diff --git a/.eslintrc b/.eslintrc
deleted file mode 100644
index fcb231522..000000000
--- a/.eslintrc
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "rules": {
-        "curly": [2, "multi-line"],
-        "eol-last": [2],
-        "indent": [2, 4],
-        "quotes": [2, "single"],
-        "linebreak-style": [2, "unix"],
-        "max-len": [2, 80, 4],
-        "semi": [2, "always"],
-        "strict": [2, "never"],
-        "no-console": [2, {"allow": ["log", "warn", "error", "groupCollapsed", "groupEnd", "time", "timeEnd"]}],
-        "valid-jsdoc": ["error", {"requireReturn": false}]
-    },
-    "env": {
-        "node": true,
-        "browser": true,
-        "worker": true
-    },
-    "extends": "eslint:recommended"
-}
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 000000000..36ff570d9
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+    extends: ['scratch', 'scratch/node']
+};
diff --git a/package.json b/package.json
index 0f528e374..130845bad 100644
--- a/package.json
+++ b/package.json
@@ -24,8 +24,10 @@
     "version": "./node_modules/.bin/json -f package.json -I -e \"this.repository.sha = '$(git log -n1 --pretty=format:%H)'\""
   },
   "devDependencies": {
+    "babel-eslint": "7.0.0",
     "copy-webpack-plugin": "3.0.1",
-    "eslint": "2.7.0",
+    "eslint": "3.8.1",
+    "eslint-config-scratch": "^2.0.0",
     "expose-loader": "0.7.1",
     "gh-pages": "0.11.0",
     "highlightjs": "8.7.0",
@@ -33,6 +35,7 @@
     "json": "9.0.4",
     "json-loader": "0.5.4",
     "lodash.defaultsdeep": "4.6.0",
+    "minilog": "3.0.1",
     "promise": "7.1.1",
     "scratch-blocks": "latest",
     "scratch-render": "latest",
diff --git a/src/.eslintrc.js b/src/.eslintrc.js
new file mode 100644
index 000000000..425bb3ff2
--- /dev/null
+++ b/src/.eslintrc.js
@@ -0,0 +1,10 @@
+module.exports = {
+    root: true,
+    extends: 'scratch',
+    env: {
+        browser: true
+    },
+    globals: {
+        Promise: true
+    }
+};
diff --git a/src/blocks/scratch3_control.js b/src/blocks/scratch3_control.js
index 571b1478f..cbfe61a24 100644
--- a/src/blocks/scratch3_control.js
+++ b/src/blocks/scratch3_control.js
@@ -1,45 +1,45 @@
 var Cast = require('../util/cast');
 var Timer = require('../util/timer');
 
-function Scratch3ControlBlocks(runtime) {
+var Scratch3ControlBlocks = function (runtime) {
     /**
      * The runtime instantiating this block package.
      * @type {Runtime}
      */
     this.runtime = runtime;
-}
+};
 
 /**
  * Retrieve the block primitives implemented by this package.
  * @return {Object.<string, Function>} Mapping of opcode to Function.
  */
-Scratch3ControlBlocks.prototype.getPrimitives = function() {
+Scratch3ControlBlocks.prototype.getPrimitives = function () {
     return {
-        'control_repeat': this.repeat,
-        'control_repeat_until': this.repeatUntil,
-        'control_forever': this.forever,
-        'control_wait': this.wait,
-        'control_wait_until': this.waitUntil,
-        'control_if': this.if,
-        'control_if_else': this.ifElse,
-        'control_stop': this.stop,
-        'control_create_clone_of': this.createClone,
-        'control_delete_this_clone': this.deleteClone
+        control_repeat: this.repeat,
+        control_repeat_until: this.repeatUntil,
+        control_forever: this.forever,
+        control_wait: this.wait,
+        control_wait_until: this.waitUntil,
+        control_if: this.if,
+        control_if_else: this.ifElse,
+        control_stop: this.stop,
+        control_create_clone_of: this.createClone,
+        control_delete_this_clone: this.deleteClone
     };
 };
 
 Scratch3ControlBlocks.prototype.getHats = function () {
     return {
-        'control_start_as_clone': {
+        control_start_as_clone: {
             restartExistingThreads: false
         }
     };
 };
 
-Scratch3ControlBlocks.prototype.repeat = function(args, util) {
+Scratch3ControlBlocks.prototype.repeat = function (args, util) {
     var times = Math.floor(Cast.toNumber(args.TIMES));
     // Initialize loop
-    if (util.stackFrame.loopCounter === undefined) {
+    if (typeof util.stackFrame.loopCounter === 'undefined') {
         util.stackFrame.loopCounter = times;
     }
     // Only execute once per frame.
@@ -53,7 +53,7 @@ Scratch3ControlBlocks.prototype.repeat = function(args, util) {
     }
 };
 
-Scratch3ControlBlocks.prototype.repeatUntil = function(args, util) {
+Scratch3ControlBlocks.prototype.repeatUntil = function (args, util) {
     var condition = Cast.toBoolean(args.CONDITION);
     // If the condition is true, start the branch.
     if (!condition) {
@@ -61,18 +61,18 @@ Scratch3ControlBlocks.prototype.repeatUntil = function(args, util) {
     }
 };
 
-Scratch3ControlBlocks.prototype.waitUntil = function(args, util) {
+Scratch3ControlBlocks.prototype.waitUntil = function (args, util) {
     var condition = Cast.toBoolean(args.CONDITION);
     if (!condition) {
         util.yield();
     }
 };
 
-Scratch3ControlBlocks.prototype.forever = function(args, util) {
+Scratch3ControlBlocks.prototype.forever = function (args, util) {
     util.startBranch(1, true);
 };
 
-Scratch3ControlBlocks.prototype.wait = function(args, util) {
+Scratch3ControlBlocks.prototype.wait = function (args, util) {
     if (!util.stackFrame.timer) {
         util.stackFrame.timer = new Timer();
         util.stackFrame.timer.start();
@@ -86,14 +86,14 @@ Scratch3ControlBlocks.prototype.wait = function(args, util) {
     }
 };
 
-Scratch3ControlBlocks.prototype.if = function(args, util) {
+Scratch3ControlBlocks.prototype.if = function (args, util) {
     var condition = Cast.toBoolean(args.CONDITION);
     if (condition) {
         util.startBranch(1, false);
     }
 };
 
-Scratch3ControlBlocks.prototype.ifElse = function(args, util) {
+Scratch3ControlBlocks.prototype.ifElse = function (args, util) {
     var condition = Cast.toBoolean(args.CONDITION);
     if (condition) {
         util.startBranch(1, false);
@@ -102,21 +102,21 @@ Scratch3ControlBlocks.prototype.ifElse = function(args, util) {
     }
 };
 
-Scratch3ControlBlocks.prototype.stop = function(args, util) {
+Scratch3ControlBlocks.prototype.stop = function (args, util) {
     var option = args.STOP_OPTION;
-    if (option == 'all') {
+    if (option === 'all') {
         util.stopAll();
-    } else if (option == 'other scripts in sprite' ||
-        option == 'other scripts in stage') {
+    } else if (option === 'other scripts in sprite' ||
+        option === 'other scripts in stage') {
         util.stopOtherTargetThreads();
-    } else if (option == 'this script') {
+    } else if (option === 'this script') {
         util.stopThread();
     }
 };
 
 Scratch3ControlBlocks.prototype.createClone = function (args, util) {
     var cloneTarget;
-    if (args.CLONE_OPTION == '_myself_') {
+    if (args.CLONE_OPTION === '_myself_') {
         cloneTarget = util.target;
     } else {
         cloneTarget = this.runtime.getSpriteTargetByName(args.CLONE_OPTION);
diff --git a/src/blocks/scratch3_data.js b/src/blocks/scratch3_data.js
index a40172427..55a6b8bb7 100644
--- a/src/blocks/scratch3_data.js
+++ b/src/blocks/scratch3_data.js
@@ -1,12 +1,12 @@
 var Cast = require('../util/cast');
 
-function Scratch3DataBlocks(runtime) {
+var Scratch3DataBlocks = function (runtime) {
     /**
      * The runtime instantiating this block package.
      * @type {Runtime}
      */
     this.runtime = runtime;
-}
+};
 
 /**
  * Retrieve the block primitives implemented by this package.
@@ -14,17 +14,17 @@ function Scratch3DataBlocks(runtime) {
  */
 Scratch3DataBlocks.prototype.getPrimitives = function () {
     return {
-        'data_variable': this.getVariable,
-        'data_setvariableto': this.setVariableTo,
-        'data_changevariableby': this.changeVariableBy,
-        'data_listcontents': this.getListContents,
-        'data_addtolist': this.addToList,
-        'data_deleteoflist': this.deleteOfList,
-        'data_insertatlist': this.insertAtList,
-        'data_replaceitemoflist': this.replaceItemOfList,
-        'data_itemoflist': this.getItemOfList,
-        'data_lengthoflist': this.lengthOfList,
-        'data_listcontainsitem': this.listContainsItem
+        data_variable: this.getVariable,
+        data_setvariableto: this.setVariableTo,
+        data_changevariableby: this.changeVariableBy,
+        data_listcontents: this.getListContents,
+        data_addtolist: this.addToList,
+        data_deleteoflist: this.deleteOfList,
+        data_insertatlist: this.insertAtList,
+        data_replaceitemoflist: this.replaceItemOfList,
+        data_itemoflist: this.getItemOfList,
+        data_lengthoflist: this.lengthOfList,
+        data_listcontainsitem: this.listContainsItem
     };
 };
 
@@ -54,7 +54,7 @@ Scratch3DataBlocks.prototype.getListContents = function (args, util) {
     for (var i = 0; i < list.contents.length; i++) {
         var listItem = list.contents[i];
         if (!((typeof listItem === 'string') &&
-              (listItem.length == 1))) {
+              (listItem.length === 1))) {
             allSingleLetters = false;
             break;
         }
@@ -126,7 +126,7 @@ Scratch3DataBlocks.prototype.listContainsItem = function (args, util) {
     // Try using Scratch comparison operator on each item.
     // (Scratch considers the string '123' equal to the number 123).
     for (var i = 0; i < list.contents.length; i++) {
-        if (Cast.compare(list.contents[i], item) == 0) {
+        if (Cast.compare(list.contents[i], item) === 0) {
             return true;
         }
     }
diff --git a/src/blocks/scratch3_event.js b/src/blocks/scratch3_event.js
index 7f56e3baf..8bfef42c2 100644
--- a/src/blocks/scratch3_event.js
+++ b/src/blocks/scratch3_event.js
@@ -1,44 +1,44 @@
 var Cast = require('../util/cast');
 
-function Scratch3EventBlocks(runtime) {
+var Scratch3EventBlocks = function (runtime) {
     /**
      * The runtime instantiating this block package.
      * @type {Runtime}
      */
     this.runtime = runtime;
-}
+};
 
 /**
  * Retrieve the block primitives implemented by this package.
  * @return {Object.<string, Function>} Mapping of opcode to Function.
  */
-Scratch3EventBlocks.prototype.getPrimitives = function() {
+Scratch3EventBlocks.prototype.getPrimitives = function () {
     return {
-        'event_broadcast': this.broadcast,
-        'event_broadcastandwait': this.broadcastAndWait,
-        'event_whengreaterthan': this.hatGreaterThanPredicate
+        event_broadcast: this.broadcast,
+        event_broadcastandwait: this.broadcastAndWait,
+        event_whengreaterthan: this.hatGreaterThanPredicate
     };
 };
 
 Scratch3EventBlocks.prototype.getHats = function () {
     return {
-        'event_whenflagclicked': {
+        event_whenflagclicked: {
             restartExistingThreads: true
         },
-        'event_whenkeypressed': {
+        event_whenkeypressed: {
             restartExistingThreads: false
         },
-        'event_whenthisspriteclicked': {
+        event_whenthisspriteclicked: {
             restartExistingThreads: true
         },
-        'event_whenbackdropswitchesto': {
+        event_whenbackdropswitchesto: {
             restartExistingThreads: true
         },
-        'event_whengreaterthan': {
+        event_whengreaterthan: {
             restartExistingThreads: false,
             edgeActivated: true
         },
-        'event_whenbroadcastreceived': {
+        event_whenbroadcastreceived: {
             restartExistingThreads: true
         }
     };
@@ -48,16 +48,16 @@ Scratch3EventBlocks.prototype.hatGreaterThanPredicate = function (args, util) {
     var option = Cast.toString(args.WHENGREATERTHANMENU).toLowerCase();
     var value = Cast.toNumber(args.VALUE);
     // @todo: Other cases :)
-    if (option == 'timer') {
+    if (option === 'timer') {
         return util.ioQuery('clock', 'projectTimer') > value;
     }
     return false;
 };
 
-Scratch3EventBlocks.prototype.broadcast = function(args, util) {
+Scratch3EventBlocks.prototype.broadcast = function (args, util) {
     var broadcastOption = Cast.toString(args.BROADCAST_OPTION);
     util.startHats('event_whenbroadcastreceived', {
-        'BROADCAST_OPTION': broadcastOption
+        BROADCAST_OPTION: broadcastOption
     });
 };
 
@@ -68,17 +68,17 @@ Scratch3EventBlocks.prototype.broadcastAndWait = function (args, util) {
         // No - start hats for this broadcast.
         util.stackFrame.startedThreads = util.startHats(
             'event_whenbroadcastreceived', {
-                'BROADCAST_OPTION': broadcastOption
+                BROADCAST_OPTION: broadcastOption
             }
         );
-        if (util.stackFrame.startedThreads.length == 0) {
+        if (util.stackFrame.startedThreads.length === 0) {
             // Nothing was started.
             return;
         }
     }
     // We've run before; check if the wait is still going on.
     var instance = this;
-    var waiting = util.stackFrame.startedThreads.some(function(thread) {
+    var waiting = util.stackFrame.startedThreads.some(function (thread) {
         return instance.runtime.isActiveThread(thread);
     });
     if (waiting) {
diff --git a/src/blocks/scratch3_looks.js b/src/blocks/scratch3_looks.js
index a1d433e94..f37e9a8fd 100644
--- a/src/blocks/scratch3_looks.js
+++ b/src/blocks/scratch3_looks.js
@@ -1,41 +1,41 @@
 var Cast = require('../util/cast');
 
-function Scratch3LooksBlocks(runtime) {
+var Scratch3LooksBlocks = function (runtime) {
     /**
      * The runtime instantiating this block package.
      * @type {Runtime}
      */
     this.runtime = runtime;
-}
+};
 
 /**
  * Retrieve the block primitives implemented by this package.
  * @return {Object.<string, Function>} Mapping of opcode to Function.
  */
-Scratch3LooksBlocks.prototype.getPrimitives = function() {
+Scratch3LooksBlocks.prototype.getPrimitives = function () {
     return {
-        'looks_say': this.say,
-        'looks_sayforsecs': this.sayforsecs,
-        'looks_think': this.think,
-        'looks_thinkforsecs': this.sayforsecs,
-        'looks_show': this.show,
-        'looks_hide': this.hide,
-        'looks_switchcostumeto': this.switchCostume,
-        'looks_switchbackdropto': this.switchBackdrop,
-        'looks_switchbackdroptoandwait': this.switchBackdropAndWait,
-        'looks_nextcostume': this.nextCostume,
-        'looks_nextbackdrop': this.nextBackdrop,
-        'looks_changeeffectby': this.changeEffect,
-        'looks_seteffectto': this.setEffect,
-        'looks_cleargraphiceffects': this.clearEffects,
-        'looks_changesizeby': this.changeSize,
-        'looks_setsizeto': this.setSize,
-        'looks_gotofront': this.goToFront,
-        'looks_gobacklayers': this.goBackLayers,
-        'looks_size': this.getSize,
-        'looks_costumeorder': this.getCostumeIndex,
-        'looks_backdroporder': this.getBackdropIndex,
-        'looks_backdropname': this.getBackdropName
+        looks_say: this.say,
+        looks_sayforsecs: this.sayforsecs,
+        looks_think: this.think,
+        looks_thinkforsecs: this.sayforsecs,
+        looks_show: this.show,
+        looks_hide: this.hide,
+        looks_switchcostumeto: this.switchCostume,
+        looks_switchbackdropto: this.switchBackdrop,
+        looks_switchbackdroptoandwait: this.switchBackdropAndWait,
+        looks_nextcostume: this.nextCostume,
+        looks_nextbackdrop: this.nextBackdrop,
+        looks_changeeffectby: this.changeEffect,
+        looks_seteffectto: this.setEffect,
+        looks_cleargraphiceffects: this.clearEffects,
+        looks_changesizeby: this.changeSize,
+        looks_setsizeto: this.setSize,
+        looks_gotofront: this.goToFront,
+        looks_gobacklayers: this.goBackLayers,
+        looks_size: this.getSize,
+        looks_costumeorder: this.getCostumeIndex,
+        looks_backdroporder: this.getBackdropIndex,
+        looks_backdropname: this.getBackdropName
     };
 };
 
@@ -45,8 +45,8 @@ Scratch3LooksBlocks.prototype.say = function (args, util) {
 
 Scratch3LooksBlocks.prototype.sayforsecs = function (args, util) {
     util.target.setSay('say', args.MESSAGE);
-    return new Promise(function(resolve) {
-        setTimeout(function() {
+    return new Promise(function (resolve) {
+        setTimeout(function () {
             // Clear say bubble and proceed.
             util.target.setSay();
             resolve();
@@ -60,8 +60,8 @@ Scratch3LooksBlocks.prototype.think = function (args, util) {
 
 Scratch3LooksBlocks.prototype.thinkforsecs = function (args, util) {
     util.target.setSay('think', args.MESSAGE);
-    return new Promise(function(resolve) {
-        setTimeout(function() {
+    return new Promise(function (resolve) {
+        setTimeout(function () {
             // Clear say bubble and proceed.
             util.target.setSay();
             resolve();
@@ -82,37 +82,37 @@ Scratch3LooksBlocks.prototype.hide = function (args, util) {
  * Matches the behavior of Scratch 2.0 for different types of arguments.
  * @param {!Target} target Target to set costume/backdrop to.
  * @param {Any} requestedCostume Costume requested, e.g., 0, 'name', etc.
- * @param {boolean=} opt_zeroIndex Set to zero-index the requestedCostume.
+ * @param {boolean=} optZeroIndex Set to zero-index the requestedCostume.
  * @return {Array.<!Thread>} Any threads started by this switch.
  */
 Scratch3LooksBlocks.prototype._setCostumeOrBackdrop = function (target,
-        requestedCostume, opt_zeroIndex) {
+        requestedCostume, optZeroIndex) {
     if (typeof requestedCostume === 'number') {
-        target.setCostume(opt_zeroIndex ?
+        target.setCostume(optZeroIndex ?
             requestedCostume : requestedCostume - 1);
     } else {
         var costumeIndex = target.getCostumeIndexByName(requestedCostume);
         if (costumeIndex > -1) {
             target.setCostume(costumeIndex);
-        } else if (costumeIndex == 'previous costume' ||
-                   costumeIndex == 'previous backdrop') {
+        } else if (costumeIndex === 'previous costume' ||
+                   costumeIndex === 'previous backdrop') {
             target.setCostume(target.currentCostume - 1);
-        } else if (costumeIndex == 'next costume' ||
-                   costumeIndex == 'next backdrop') {
+        } else if (costumeIndex === 'next costume' ||
+                   costumeIndex === 'next backdrop') {
             target.setCostume(target.currentCostume + 1);
         } else {
             var forcedNumber = Cast.toNumber(requestedCostume);
             if (!isNaN(forcedNumber)) {
-                target.setCostume(opt_zeroIndex ?
+                target.setCostume(optZeroIndex ?
                     forcedNumber : forcedNumber - 1);
             }
         }
     }
-    if (target == this.runtime.getTargetForStage()) {
+    if (target === this.runtime.getTargetForStage()) {
         // Target is the stage - start hats.
         var newName = target.sprite.costumes[target.currentCostume].name;
         return this.runtime.startHats('event_whenbackdropswitchesto', {
-            'BACKDROP': newName
+            BACKDROP: newName
         });
     }
     return [];
@@ -142,14 +142,14 @@ Scratch3LooksBlocks.prototype.switchBackdropAndWait = function (args, util) {
                 args.BACKDROP
             )
         );
-        if (util.stackFrame.startedThreads.length == 0) {
+        if (util.stackFrame.startedThreads.length === 0) {
             // Nothing was started.
             return;
         }
     }
     // We've run before; check if the wait is still going on.
     var instance = this;
-    var waiting = util.stackFrame.startedThreads.some(function(thread) {
+    var waiting = util.stackFrame.startedThreads.some(function (thread) {
         return instance.runtime.isActiveThread(thread);
     });
     if (waiting) {
diff --git a/src/blocks/scratch3_motion.js b/src/blocks/scratch3_motion.js
index 68078578b..be96e9cd8 100644
--- a/src/blocks/scratch3_motion.js
+++ b/src/blocks/scratch3_motion.js
@@ -2,37 +2,37 @@ var Cast = require('../util/cast');
 var MathUtil = require('../util/math-util');
 var Timer = require('../util/timer');
 
-function Scratch3MotionBlocks(runtime) {
+var Scratch3MotionBlocks = function (runtime) {
     /**
      * The runtime instantiating this block package.
      * @type {Runtime}
      */
     this.runtime = runtime;
-}
+};
 
 /**
  * Retrieve the block primitives implemented by this package.
  * @return {Object.<string, Function>} Mapping of opcode to Function.
  */
-Scratch3MotionBlocks.prototype.getPrimitives = function() {
+Scratch3MotionBlocks.prototype.getPrimitives = function () {
     return {
-        'motion_movesteps': this.moveSteps,
-        'motion_gotoxy': this.goToXY,
-        'motion_goto': this.goTo,
-        'motion_turnright': this.turnRight,
-        'motion_turnleft': this.turnLeft,
-        'motion_pointindirection': this.pointInDirection,
-        'motion_pointtowards': this.pointTowards,
-        'motion_glidesecstoxy': this.glide,
-        'motion_ifonedgebounce': this.ifOnEdgeBounce,
-        'motion_setrotationstyle': this.setRotationStyle,
-        'motion_changexby': this.changeX,
-        'motion_setx': this.setX,
-        'motion_changeyby': this.changeY,
-        'motion_sety': this.setY,
-        'motion_xposition': this.getX,
-        'motion_yposition': this.getY,
-        'motion_direction': this.getDirection
+        motion_movesteps: this.moveSteps,
+        motion_gotoxy: this.goToXY,
+        motion_goto: this.goTo,
+        motion_turnright: this.turnRight,
+        motion_turnleft: this.turnLeft,
+        motion_pointindirection: this.pointInDirection,
+        motion_pointtowards: this.pointTowards,
+        motion_glidesecstoxy: this.glide,
+        motion_ifonedgebounce: this.ifOnEdgeBounce,
+        motion_setrotationstyle: this.setRotationStyle,
+        motion_changexby: this.changeX,
+        motion_setx: this.setX,
+        motion_changeyby: this.changeY,
+        motion_sety: this.setY,
+        motion_xposition: this.getX,
+        motion_yposition: this.getY,
+        motion_direction: this.getDirection
     };
 };
 
@@ -149,10 +149,10 @@ Scratch3MotionBlocks.prototype.ifOnEdgeBounce = function (args, util) {
     // and clamped to zero when the sprite is beyond.
     var stageWidth = this.runtime.constructor.STAGE_WIDTH;
     var stageHeight = this.runtime.constructor.STAGE_HEIGHT;
-    var distLeft = Math.max(0, stageWidth / 2 + bounds.left);
-    var distTop = Math.max(0, stageHeight / 2 - bounds.top);
-    var distRight = Math.max(0, stageWidth / 2 - bounds.right);
-    var distBottom = Math.max(0, stageHeight / 2 + bounds.bottom);
+    var distLeft = Math.max(0, (stageWidth / 2) + bounds.left);
+    var distTop = Math.max(0, (stageHeight / 2) - bounds.top);
+    var distRight = Math.max(0, (stageWidth / 2) - bounds.right);
+    var distBottom = Math.max(0, (stageHeight / 2) + bounds.bottom);
     // Find the nearest edge.
     var nearestEdge = '';
     var minDist = Infinity;
@@ -179,13 +179,13 @@ Scratch3MotionBlocks.prototype.ifOnEdgeBounce = function (args, util) {
     var radians = MathUtil.degToRad(90 - util.target.direction);
     var dx = Math.cos(radians);
     var dy = -Math.sin(radians);
-    if (nearestEdge == 'left') {
+    if (nearestEdge === 'left') {
         dx = Math.max(0.2, Math.abs(dx));
-    } else if (nearestEdge == 'top') {
+    } else if (nearestEdge === 'top') {
         dy = Math.max(0.2, Math.abs(dy));
-    } else if (nearestEdge == 'right') {
+    } else if (nearestEdge === 'right') {
         dx = 0 - Math.max(0.2, Math.abs(dx));
-    } else if (nearestEdge == 'bottom') {
+    } else if (nearestEdge === 'bottom') {
         dy = 0 - Math.max(0.2, Math.abs(dy));
     }
     var newDirection = MathUtil.radToDeg(Math.atan2(dy, dx)) + 90;
diff --git a/src/blocks/scratch3_operators.js b/src/blocks/scratch3_operators.js
index 0d5531778..eb2a98135 100644
--- a/src/blocks/scratch3_operators.js
+++ b/src/blocks/scratch3_operators.js
@@ -1,36 +1,36 @@
 var Cast = require('../util/cast.js');
 
-function Scratch3OperatorsBlocks(runtime) {
+var Scratch3OperatorsBlocks = function (runtime) {
     /**
      * The runtime instantiating this block package.
      * @type {Runtime}
      */
     this.runtime = runtime;
-}
+};
 
 /**
  * Retrieve the block primitives implemented by this package.
  * @return {Object.<string, Function>} Mapping of opcode to Function.
  */
-Scratch3OperatorsBlocks.prototype.getPrimitives = function() {
+Scratch3OperatorsBlocks.prototype.getPrimitives = function () {
     return {
-        'operator_add': this.add,
-        'operator_subtract': this.subtract,
-        'operator_multiply': this.multiply,
-        'operator_divide': this.divide,
-        'operator_lt': this.lt,
-        'operator_equals': this.equals,
-        'operator_gt': this.gt,
-        'operator_and': this.and,
-        'operator_or': this.or,
-        'operator_not': this.not,
-        'operator_random': this.random,
-        'operator_join': this.join,
-        'operator_letter_of': this.letterOf,
-        'operator_length': this.length,
-        'operator_mod': this.mod,
-        'operator_round': this.round,
-        'operator_mathop': this.mathop
+        operator_add: this.add,
+        operator_subtract: this.subtract,
+        operator_multiply: this.multiply,
+        operator_divide: this.divide,
+        operator_lt: this.lt,
+        operator_equals: this.equals,
+        operator_gt: this.gt,
+        operator_and: this.and,
+        operator_or: this.or,
+        operator_not: this.not,
+        operator_random: this.random,
+        operator_join: this.join,
+        operator_letter_of: this.letterOf,
+        operator_length: this.length,
+        operator_mod: this.mod,
+        operator_round: this.round,
+        operator_mathop: this.mathop
     };
 };
 
@@ -55,7 +55,7 @@ Scratch3OperatorsBlocks.prototype.lt = function (args) {
 };
 
 Scratch3OperatorsBlocks.prototype.equals = function (args) {
-    return Cast.compare(args.OPERAND1, args.OPERAND2) == 0;
+    return Cast.compare(args.OPERAND1, args.OPERAND2) === 0;
 };
 
 Scratch3OperatorsBlocks.prototype.gt = function (args) {
@@ -79,10 +79,10 @@ Scratch3OperatorsBlocks.prototype.random = function (args) {
     var nTo = Cast.toNumber(args.TO);
     var low = nFrom <= nTo ? nFrom : nTo;
     var high = nFrom <= nTo ? nTo : nFrom;
-    if (low == high) return low;
+    if (low === high) return low;
     // If both arguments are ints, truncate the result to an int.
     if (Cast.isInt(args.FROM) && Cast.isInt(args.TO)) {
-        return low + parseInt(Math.random() * ((high + 1) - low));
+        return low + parseInt(Math.random() * ((high + 1) - low), 10);
     }
     return (Math.random() * (high - low)) + low;
 };
diff --git a/src/blocks/scratch3_procedures.js b/src/blocks/scratch3_procedures.js
index 19a6df370..62c7b8dbe 100644
--- a/src/blocks/scratch3_procedures.js
+++ b/src/blocks/scratch3_procedures.js
@@ -1,20 +1,20 @@
-function Scratch3ProcedureBlocks(runtime) {
+var Scratch3ProcedureBlocks = function (runtime) {
     /**
      * The runtime instantiating this block package.
      * @type {Runtime}
      */
     this.runtime = runtime;
-}
+};
 
 /**
  * Retrieve the block primitives implemented by this package.
  * @return {Object.<string, Function>} Mapping of opcode to Function.
  */
-Scratch3ProcedureBlocks.prototype.getPrimitives = function() {
+Scratch3ProcedureBlocks.prototype.getPrimitives = function () {
     return {
-        'procedures_defnoreturn': this.defNoReturn,
-        'procedures_callnoreturn': this.callNoReturn,
-        'procedures_param': this.param
+        procedures_defnoreturn: this.defNoReturn,
+        procedures_callnoreturn: this.callNoReturn,
+        procedures_param: this.param
     };
 };
 
diff --git a/src/blocks/scratch3_sensing.js b/src/blocks/scratch3_sensing.js
index 293273936..be83d99c2 100644
--- a/src/blocks/scratch3_sensing.js
+++ b/src/blocks/scratch3_sensing.js
@@ -1,41 +1,41 @@
 var Cast = require('../util/cast');
 
-function Scratch3SensingBlocks(runtime) {
+var Scratch3SensingBlocks = function (runtime) {
     /**
      * The runtime instantiating this block package.
      * @type {Runtime}
      */
     this.runtime = runtime;
-}
+};
 
 /**
  * Retrieve the block primitives implemented by this package.
  * @return {Object.<string, Function>} Mapping of opcode to Function.
  */
-Scratch3SensingBlocks.prototype.getPrimitives = function() {
+Scratch3SensingBlocks.prototype.getPrimitives = function () {
     return {
-        'sensing_touchingobject': this.touchingObject,
-        'sensing_touchingcolor': this.touchingColor,
-        'sensing_coloristouchingcolor': this.colorTouchingColor,
-        'sensing_distanceto': this.distanceTo,
-        'sensing_timer': this.getTimer,
-        'sensing_resettimer': this.resetTimer,
-        'sensing_mousex': this.getMouseX,
-        'sensing_mousey': this.getMouseY,
-        'sensing_mousedown': this.getMouseDown,
-        'sensing_keypressed': this.getKeyPressed,
-        'sensing_current': this.current,
-        'sensing_dayssince2000': this.daysSince2000
+        sensing_touchingobject: this.touchingObject,
+        sensing_touchingcolor: this.touchingColor,
+        sensing_coloristouchingcolor: this.colorTouchingColor,
+        sensing_distanceto: this.distanceTo,
+        sensing_timer: this.getTimer,
+        sensing_resettimer: this.resetTimer,
+        sensing_mousex: this.getMouseX,
+        sensing_mousey: this.getMouseY,
+        sensing_mousedown: this.getMouseDown,
+        sensing_keypressed: this.getKeyPressed,
+        sensing_current: this.current,
+        sensing_dayssince2000: this.daysSince2000
     };
 };
 
 Scratch3SensingBlocks.prototype.touchingObject = function (args, util) {
     var requestedObject = args.TOUCHINGOBJECTMENU;
-    if (requestedObject == '_mouse_') {
+    if (requestedObject === '_mouse_') {
         var mouseX = util.ioQuery('mouse', 'getX');
         var mouseY = util.ioQuery('mouse', 'getY');
         return util.target.isTouchingPoint(mouseX, mouseY);
-    } else if (requestedObject == '_edge_') {
+    } else if (requestedObject === '_edge_') {
         return util.target.isTouchingEdge();
     } else {
         return util.target.isTouchingSprite(requestedObject);
@@ -114,11 +114,10 @@ Scratch3SensingBlocks.prototype.getKeyPressed = function (args, util) {
     return util.ioQuery('keyboard', 'getKeyIsDown', args.KEY_OPTION);
 };
 
-Scratch3SensingBlocks.prototype.daysSince2000 = function()
-{
+Scratch3SensingBlocks.prototype.daysSince2000 = function () {
     var msPerDay = 24 * 60 * 60 * 1000;
-    var start = new Date(2000, 1-1, 1); 
-    var today = new Date(); 
+    var start = new Date(2000, 1 - 1, 1);
+    var today = new Date();
     var dstAdjust = today.getTimezoneOffset() - start.getTimezoneOffset();
     var mSecsSinceStart = today.valueOf() - start.valueOf();
     mSecsSinceStart += ((today.getTimezoneOffset() - dstAdjust) * 60 * 1000);
diff --git a/src/engine/adapter.js b/src/engine/adapter.js
index 327aae5e3..e68cd3ea5 100644
--- a/src/engine/adapter.js
+++ b/src/engine/adapter.js
@@ -1,20 +1,6 @@
 var mutationAdapter = require('./mutation-adapter');
 var html = require('htmlparser2');
 
-/**
- * Adapter between block creation events and block representation which can be
- * used by the Scratch runtime.
- * @param {Object} e `Blockly.events.create`
- * @return {Array.<Object>} List of blocks from this CREATE event.
- */
-module.exports = function (e) {
-    // Validate input
-    if (typeof e !== 'object') return;
-    if (typeof e.xml !== 'object') return;
-
-    return domToBlocks(html.parseDOM(e.xml.outerHTML));
-};
-
 /**
  * Convert outer blocks DOM from a Blockly CREATE event
  * to a usable form for the Scratch runtime.
@@ -22,7 +8,7 @@ module.exports = function (e) {
  * @param {Element} blocksDOM DOM tree for this event.
  * @return {Array.<Object>} Usable list of blocks from this CREATE event.
  */
-function domToBlocks (blocksDOM) {
+var domToBlocks = function (blocksDOM) {
     // At this level, there could be multiple blocks adjacent in the DOM tree.
     var blocks = {};
     for (var i = 0; i < blocksDOM.length; i++) {
@@ -31,7 +17,7 @@ function domToBlocks (blocksDOM) {
             continue;
         }
         var tagName = block.name.toLowerCase();
-        if (tagName == 'block' || tagName == 'shadow') {
+        if (tagName === 'block' || tagName === 'shadow') {
             domToBlock(block, blocks, true, null);
         }
     }
@@ -41,7 +27,21 @@ function domToBlocks (blocksDOM) {
         blocksList.push(blocks[b]);
     }
     return blocksList;
-}
+};
+
+/**
+ * Adapter between block creation events and block representation which can be
+ * used by the Scratch runtime.
+ * @param {Object} e `Blockly.events.create`
+ * @return {Array.<Object>} List of blocks from this CREATE event.
+ */
+var adapter = function (e) {
+    // Validate input
+    if (typeof e !== 'object') return;
+    if (typeof e.xml !== 'object') return;
+
+    return domToBlocks(html.parseDOM(e.xml.outerHTML));
+};
 
 /**
  * Convert and an individual block DOM to the representation tree.
@@ -50,8 +50,9 @@ function domToBlocks (blocksDOM) {
  * @param {Object} blocks Collection of blocks to add to.
  * @param {Boolean} isTopBlock Whether blocks at this level are "top blocks."
  * @param {?string} parent Parent block ID.
+ * @return {undefined}
  */
-function domToBlock (blockDOM, blocks, isTopBlock, parent) {
+var domToBlock = function (blockDOM, blocks, isTopBlock, parent) {
     // Block skeleton.
     var block = {
         id: blockDOM.attribs.id, // Block ID
@@ -61,7 +62,7 @@ function domToBlock (blockDOM, blocks, isTopBlock, parent) {
         next: null, // Next block in the stack, if one exists.
         topLevel: isTopBlock, // If this block starts a stack.
         parent: parent, // Parent block ID, if available.
-        shadow: blockDOM.name == 'shadow', // If this represents a shadow/slot.
+        shadow: blockDOM.name === 'shadow', // If this represents a shadow/slot.
         x: blockDOM.attribs.x, // X position of script, if top-level.
         y: blockDOM.attribs.y // Y position of script, if top-level.
     };
@@ -82,9 +83,9 @@ function domToBlock (blockDOM, blocks, isTopBlock, parent) {
                 continue;
             }
             var grandChildNodeName = grandChildNode.name.toLowerCase();
-            if (grandChildNodeName == 'block') {
+            if (grandChildNodeName === 'block') {
                 childBlockNode = grandChildNode;
-            } else if (grandChildNodeName == 'shadow') {
+            } else if (grandChildNodeName === 'shadow') {
                 childShadowNode = grandChildNode;
             }
         }
@@ -117,7 +118,7 @@ function domToBlock (blockDOM, blocks, isTopBlock, parent) {
         case 'statement':
             // Recursively generate block structure for input block.
             domToBlock(childBlockNode, blocks, false, block.id);
-            if (childShadowNode && childBlockNode != childShadowNode) {
+            if (childShadowNode && childBlockNode !== childShadowNode) {
                 // Also generate the shadow block.
                 domToBlock(childShadowNode, blocks, false, block.id);
             }
@@ -144,4 +145,6 @@ function domToBlock (blockDOM, blocks, isTopBlock, parent) {
             break;
         }
     }
-}
+};
+
+module.exports = adapter;
diff --git a/src/engine/blocks.js b/src/engine/blocks.js
index 0e89025e9..84d09a6f9 100644
--- a/src/engine/blocks.js
+++ b/src/engine/blocks.js
@@ -8,7 +8,7 @@ var xmlEscape = require('../util/xml-escape');
  * and handle updates from Scratch Blocks events.
  */
 
-function Blocks () {
+var Blocks = function () {
     /**
      * All blocks in the workspace.
      * Keys are block IDs, values are metadata about the block.
@@ -22,7 +22,7 @@ function Blocks () {
      * @type {Array.<String>}
      */
     this._scripts = [];
-}
+};
 
 /**
  * Blockly inputs that represent statements/branch.
@@ -109,8 +109,8 @@ Blocks.prototype.getInputs = function (id) {
     var inputs = {};
     for (var input in this._blocks[id].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] = this._blocks[id].inputs[input];
         }
     }
@@ -149,9 +149,9 @@ Blocks.prototype.getTopLevelScript = function (id) {
 Blocks.prototype.getProcedureDefinition = function (name) {
     for (var id in this._blocks) {
         var block = this._blocks[id];
-        if ((block.opcode == 'procedures_defnoreturn' ||
-            block.opcode == 'procedures_defreturn') &&
-            block.mutation.proccode == name) {
+        if ((block.opcode === 'procedures_defnoreturn' ||
+            block.opcode === 'procedures_defreturn') &&
+            block.mutation.proccode === name) {
             return id;
         }
     }
@@ -166,9 +166,9 @@ Blocks.prototype.getProcedureDefinition = function (name) {
 Blocks.prototype.getProcedureParamNames = function (name) {
     for (var id in this._blocks) {
         var block = this._blocks[id];
-        if ((block.opcode == 'procedures_defnoreturn' ||
-            block.opcode == 'procedures_defreturn') &&
-            block.mutation.proccode == name) {
+        if ((block.opcode === 'procedures_defnoreturn' ||
+            block.opcode === 'procedures_defreturn') &&
+            block.mutation.proccode === name) {
             return JSON.parse(block.mutation.argumentnames);
         }
     }
@@ -181,18 +181,18 @@ Blocks.prototype.getProcedureParamNames = function (name) {
  * Create event listener for blocks. Handles validation and serves as a generic
  * adapter between the blocks and the runtime interface.
  * @param {Object} e Blockly "block" event
- * @param {?Runtime} opt_runtime Optional runtime to forward click events to.
+ * @param {?Runtime} optRuntime Optional runtime to forward click events to.
  */
 
-Blocks.prototype.blocklyListen = function (e, opt_runtime) {
+Blocks.prototype.blocklyListen = function (e, optRuntime) {
     // Validate event
     if (typeof e !== 'object') return;
     if (typeof e.blockId !== 'string') return;
 
     // UI event: clicked scripts toggle in the runtime.
     if (e.element === 'stackclick') {
-        if (opt_runtime) {
-            opt_runtime.toggleScript(e.blockId);
+        if (optRuntime) {
+            optRuntime.toggleScript(e.blockId);
         }
         return;
     }
@@ -232,8 +232,8 @@ Blocks.prototype.blocklyListen = function (e, opt_runtime) {
             return;
         }
         // Inform any runtime to forget about glows on this script.
-        if (opt_runtime && this._blocks[e.blockId].topLevel) {
-            opt_runtime.quietGlow(e.blockId);
+        if (optRuntime && this._blocks[e.blockId].topLevel) {
+            optRuntime.quietGlow(e.blockId);
         }
         this.deleteBlock({
             id: e.blockId
@@ -273,11 +273,11 @@ Blocks.prototype.changeBlock = function (args) {
     if (args.element !== 'field' && args.element !== 'mutation') return;
     if (typeof this._blocks[args.id] === 'undefined') return;
 
-    if (args.element == 'field') {
+    if (args.element === 'field') {
         // Update block value
         if (!this._blocks[args.id].fields[args.name]) return;
         this._blocks[args.id].fields[args.name].value = args.value;
-    } else if (args.element == 'mutation') {
+    } else if (args.element === 'mutation') {
         this._blocks[args.id].mutation = mutationAdapter(args.value);
     }
 };
@@ -298,9 +298,9 @@ Blocks.prototype.moveBlock = function (e) {
     }
 
     // Remove from any old parent.
-    if (e.oldParent !== undefined) {
+    if (typeof e.oldParent !== 'undefined') {
         var oldParent = this._blocks[e.oldParent];
-        if (e.oldInput !== undefined &&
+        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;
@@ -312,13 +312,16 @@ Blocks.prototype.moveBlock = function (e) {
     }
 
     // Has the block become a top-level block?
-    if (e.newParent === undefined) {
+    if (typeof e.newParent === 'undefined') {
         this._addScript(e.id);
     } else {
         // Remove script, if one exists.
         this._deleteScript(e.id);
         // Otherwise, try to connect it in its new place.
-        if (e.newInput !== undefined) {
+        if (typeof e.newInput === 'undefined') {
+            // Moved to the new parent's next connection.
+            this._blocks[e.newParent].next = e.id;
+        } else {
             // Moved to the new parent's input.
             // Don't obscure the shadow block.
             var oldShadow = null;
@@ -330,9 +333,6 @@ Blocks.prototype.moveBlock = function (e) {
                 block: e.id,
                 shadow: oldShadow
             };
-        } else {
-            // Moved to the new parent's next connection.
-            this._blocks[e.newParent].next = e.id;
         }
         this._blocks[e.id].parent = e.newParent;
     }
@@ -399,7 +399,7 @@ Blocks.prototype.blockToXML = function (blockId) {
     // Encode properties of this block.
     var tagName = (block.shadow) ? 'shadow' : 'block';
     var xy = (block.topLevel) ?
-        ' x="' + block.x +'"' + ' y="' + block.y +'"' :
+        ' x="' + block.x + '" y="' + block.y + '"' :
         '';
     var xmlString = '';
     xmlString += '<' + tagName +
@@ -420,7 +420,7 @@ Blocks.prototype.blockToXML = function (blockId) {
             if (blockInput.block) {
                 xmlString += this.blockToXML(blockInput.block);
             }
-            if (blockInput.shadow && blockInput.shadow != blockInput.block) {
+            if (blockInput.shadow && blockInput.shadow !== blockInput.block) {
                 // Obscured shadow.
                 xmlString += this.blockToXML(blockInput.shadow);
             }
@@ -453,7 +453,7 @@ Blocks.prototype.blockToXML = function (blockId) {
 Blocks.prototype.mutationToXML = function (mutation) {
     var mutationString = '<' + mutation.tagName;
     for (var prop in mutation) {
-        if (prop == 'children' || prop == 'tagName') continue;
+        if (prop === 'children' || prop === 'tagName') continue;
         var mutationValue = (typeof mutation[prop] === 'string') ?
             xmlEscape(mutation[prop]) : mutation[prop];
         mutationString += ' ' + prop + '="' + mutationValue + '"';
diff --git a/src/engine/execute.js b/src/engine/execute.js
index 6ef0599de..a8967eb1f 100644
--- a/src/engine/execute.js
+++ b/src/engine/execute.js
@@ -1,3 +1,4 @@
+var log = require('../util/log');
 var Thread = require('./thread');
 
 /**
@@ -52,7 +53,7 @@ var execute = function (sequencer, thread) {
 
 
     if (!opcode) {
-        console.warn('Could not get opcode for block: ' + currentBlockId);
+        log.warn('Could not get opcode for block: ' + currentBlockId);
         return;
     }
 
@@ -105,14 +106,14 @@ var execute = function (sequencer, thread) {
             // Skip through the block (hat with no predicate).
             return;
         } else {
-            if (Object.keys(fields).length == 1 &&
-                Object.keys(inputs).length == 0) {
+            if (Object.keys(fields).length === 1 &&
+                Object.keys(inputs).length === 0) {
                 // One field and no inputs - treat as arg.
                 for (var fieldKey in fields) { // One iteration.
                     handleReport(fields[fieldKey].value);
                 }
             } else {
-                console.warn('Could not get implementation for opcode: ' +
+                log.warn('Could not get implementation for opcode: ' +
                     opcode);
             }
             thread.requestScriptGlowInFrame = true;
@@ -133,8 +134,8 @@ var execute = function (sequencer, thread) {
         var input = inputs[inputName];
         var inputBlockId = input.block;
         // Is there no value for this input waiting in the stack frame?
-        if (typeof currentStackFrame.reported[inputName] === 'undefined'
-            && inputBlockId) {
+        if (typeof currentStackFrame.reported[inputName] === 'undefined' &&
+            inputBlockId) {
             // If there's not, we need to evaluate the block.
             // Push to the stack to evaluate the reporter block.
             thread.pushStack(inputBlockId);
@@ -170,7 +171,7 @@ var execute = function (sequencer, thread) {
     primitiveReportedValue = blockFunction(argValues, {
         stackFrame: currentStackFrame.executionContext,
         target: target,
-        yield: function() {
+        yield: function () {
             thread.status = Thread.STATUS_YIELD;
         },
         startBranch: function (branchNum, isLoop) {
@@ -179,10 +180,10 @@ var execute = function (sequencer, thread) {
         stopAll: function () {
             runtime.stopAll();
         },
-        stopOtherTargetThreads: function() {
+        stopOtherTargetThreads: function () {
             runtime.stopForTarget(target, thread);
         },
-        stopThread: function() {
+        stopThread: function () {
             sequencer.retireThread(thread);
         },
         startProcedure: function (procedureCode) {
@@ -197,15 +198,20 @@ var execute = function (sequencer, thread) {
         getParam: function (paramName) {
             return thread.getParam(paramName);
         },
-        startHats: function(requestedHat, opt_matchFields, opt_target) {
+        startHats: function (requestedHat, optMatchFields, optTarget) {
             return (
-                runtime.startHats(requestedHat, opt_matchFields, opt_target)
+                runtime.startHats(requestedHat, optMatchFields, optTarget)
             );
         },
         ioQuery: function (device, func, args) {
             // Find the I/O device and execute the query/function call.
             if (runtime.ioDevices[device] && runtime.ioDevices[device][func]) {
                 var devObject = runtime.ioDevices[device];
+                // @todo Figure out why eslint complains about no-useless-call
+                // no-useless-call can't tell if the call is useless for dynamic
+                // expressions... or something. Not exactly sure why it
+                // complains here.
+                // eslint-disable-next-line no-useless-call
                 return devObject[func].call(devObject, args);
             }
         }
@@ -224,19 +230,19 @@ var execute = function (sequencer, thread) {
             thread.status = Thread.STATUS_PROMISE_WAIT;
         }
         // Promise handlers
-        primitiveReportedValue.then(function(resolvedValue) {
+        primitiveReportedValue.then(function (resolvedValue) {
             handleReport(resolvedValue);
-            if (typeof resolvedValue !== 'undefined') {
-                thread.popStack();
-            } else {
+            if (typeof resolvedValue === 'undefined') {
                 var popped = thread.popStack();
                 var nextBlockId = thread.target.blocks.getNextBlock(popped);
                 thread.pushStack(nextBlockId);
+            } else {
+                thread.popStack();
             }
-        }, function(rejectionReason) {
+        }, function (rejectionReason) {
             // Promise rejected: the primitive had some error.
             // Log it and proceed.
-            console.warn('Primitive rejected promise: ', rejectionReason);
+            log.warn('Primitive rejected promise: ', rejectionReason);
             thread.status = Thread.STATUS_RUNNING;
             thread.popStack();
         });
diff --git a/src/engine/list.js b/src/engine/list.js
index 8ef082cde..d8be65a33 100644
--- a/src/engine/list.js
+++ b/src/engine/list.js
@@ -8,9 +8,9 @@
   * @param {Array} contents Contents of the list, as an array.
   * @constructor
   */
-function List (name, contents) {
+var List = function (name, contents) {
     this.name = name;
     this.contents = contents;
-}
+};
 
 module.exports = List;
diff --git a/src/engine/mutation-adapter.js b/src/engine/mutation-adapter.js
index 12dc123e1..9277cc150 100644
--- a/src/engine/mutation-adapter.js
+++ b/src/engine/mutation-adapter.js
@@ -1,12 +1,33 @@
 var html = require('htmlparser2');
 
+/**
+ * Convert a part of a mutation DOM to a mutation VM object, recursively.
+ * @param {Object} dom DOM object for mutation tag.
+ * @return {Object} Object representing useful parts of this mutation.
+ */
+var mutatorTagToObject = function (dom) {
+    var obj = Object.create(null);
+    obj.tagName = dom.name;
+    obj.children = [];
+    for (var prop in dom.attribs) {
+        if (prop === 'xmlns') continue;
+        obj[prop] = dom.attribs[prop];
+    }
+    for (var i = 0; i < dom.children.length; i++) {
+        obj.children.push(
+            mutatorTagToObject(dom.children[i])
+        );
+    }
+    return obj;
+};
+
 /**
  * Adapter between mutator XML or DOM and block representation which can be
  * used by the Scratch runtime.
  * @param {(Object|string)} mutation Mutation XML string or DOM.
  * @return {Object} Object representing the mutation.
  */
-module.exports = function (mutation) {
+var mutationAdpater = function (mutation) {
     var mutationParsed;
     // Check if the mutation is already parsed; if not, parse it.
     if (typeof mutation === 'object') {
@@ -17,23 +38,4 @@ module.exports = function (mutation) {
     return mutatorTagToObject(mutationParsed);
 };
 
-/**
- * Convert a part of a mutation DOM to a mutation VM object, recursively.
- * @param {Object} dom DOM object for mutation tag.
- * @return {Object} Object representing useful parts of this mutation.
- */
-function mutatorTagToObject (dom) {
-    var obj = Object.create(null);
-    obj.tagName = dom.name;
-    obj.children = [];
-    for (var prop in dom.attribs) {
-        if (prop == 'xmlns') continue;
-        obj[prop] = dom.attribs[prop];
-    }
-    for (var i = 0; i < dom.children.length; i++) {
-        obj.children.push(
-            mutatorTagToObject(dom.children[i])
-        );
-    }
-    return obj;
-}
+module.exports = mutationAdpater;
diff --git a/src/engine/runtime.js b/src/engine/runtime.js
index 6b5bffbeb..0a8930a1d 100644
--- a/src/engine/runtime.js
+++ b/src/engine/runtime.js
@@ -10,20 +10,20 @@ var Keyboard = require('../io/keyboard');
 var Mouse = require('../io/mouse');
 
 var defaultBlockPackages = {
-    'scratch3_control': require('../blocks/scratch3_control'),
-    'scratch3_event': require('../blocks/scratch3_event'),
-    'scratch3_looks': require('../blocks/scratch3_looks'),
-    'scratch3_motion': require('../blocks/scratch3_motion'),
-    'scratch3_operators': require('../blocks/scratch3_operators'),
-    'scratch3_sensing': require('../blocks/scratch3_sensing'),
-    'scratch3_data': require('../blocks/scratch3_data'),
-    'scratch3_procedures': require('../blocks/scratch3_procedures')
+    scratch3_control: require('../blocks/scratch3_control'),
+    scratch3_event: require('../blocks/scratch3_event'),
+    scratch3_looks: require('../blocks/scratch3_looks'),
+    scratch3_motion: require('../blocks/scratch3_motion'),
+    scratch3_operators: require('../blocks/scratch3_operators'),
+    scratch3_sensing: require('../blocks/scratch3_sensing'),
+    scratch3_data: require('../blocks/scratch3_data'),
+    scratch3_procedures: require('../blocks/scratch3_procedures')
 };
 
 /**
  * Manages targets, scripts, and the sequencer.
  */
-function Runtime () {
+var Runtime = function () {
     // Bind event emitter
     EventEmitter.call(this);
 
@@ -139,11 +139,11 @@ function Runtime () {
     // I/O related data.
     /** @type {Object.<string, Object>} */
     this.ioDevices = {
-        'clock': new Clock(),
-        'keyboard': new Keyboard(this),
-        'mouse': new Mouse(this)
+        clock: new Clock(),
+        keyboard: new Keyboard(this),
+        mouse: new Mouse(this)
     };
-}
+};
 
 /**
  * Inherit from EventEmitter
@@ -346,7 +346,7 @@ Runtime.prototype.isActiveThread = function (thread) {
 Runtime.prototype.toggleScript = function (topBlockId) {
     // Remove any existing thread.
     for (var i = 0; i < this.threads.length; i++) {
-        if (this.threads[i].topBlock == topBlockId) {
+        if (this.threads[i].topBlock === topBlockId) {
             this._removeThread(this.threads[i]);
             return;
         }
@@ -361,12 +361,12 @@ Runtime.prototype.toggleScript = function (topBlockId) {
  *  - the top block ID of the script.
  *  - the target that owns the script.
  * @param {!Function} f Function to call for each script.
- * @param {Target=} opt_target Optionally, a target to restrict to.
+ * @param {Target=} optTarget Optionally, a target to restrict to.
  */
-Runtime.prototype.allScriptsDo = function (f, opt_target) {
+Runtime.prototype.allScriptsDo = function (f, optTarget) {
     var targets = this.targets;
-    if (opt_target) {
-        targets = [opt_target];
+    if (optTarget) {
+        targets = [optTarget];
     }
     for (var t = 0; t < targets.length; t++) {
         var target = targets[t];
@@ -381,12 +381,12 @@ Runtime.prototype.allScriptsDo = function (f, opt_target) {
 /**
  * Start all relevant hats.
  * @param {!string} requestedHatOpcode Opcode of hats to start.
- * @param {Object=} opt_matchFields Optionally, fields to match on the hat.
- * @param {Target=} opt_target Optionally, a target to restrict to.
+ * @param {Object=} optMatchFields Optionally, fields to match on the hat.
+ * @param {Target=} optTarget Optionally, a target to restrict to.
  * @return {Array.<Thread>} List of threads started by this function.
  */
 Runtime.prototype.startHats = function (requestedHatOpcode,
-    opt_matchFields, opt_target) {
+    optMatchFields, optTarget) {
     if (!this._hats.hasOwnProperty(requestedHatOpcode)) {
         // No known hat with this opcode.
         return;
@@ -394,7 +394,7 @@ Runtime.prototype.startHats = function (requestedHatOpcode,
     var instance = this;
     var newThreads = [];
     // Consider all scripts, looking for hats with opcode `requestedHatOpcode`.
-    this.allScriptsDo(function(topBlockId, target) {
+    this.allScriptsDo(function (topBlockId, target) {
         var potentialHatOpcode = target.blocks.getBlock(topBlockId).opcode;
         if (potentialHatOpcode !== requestedHatOpcode) {
             // Not the right hat.
@@ -406,10 +406,10 @@ Runtime.prototype.startHats = function (requestedHatOpcode,
         // (i.e., before the predicate can be run) because "broadcast and wait"
         // needs to have a precise collection of started threads.
         var hatFields = target.blocks.getFields(topBlockId);
-        if (opt_matchFields) {
-            for (var matchField in opt_matchFields) {
+        if (optMatchFields) {
+            for (var matchField in optMatchFields) {
                 if (hatFields[matchField].value !==
-                    opt_matchFields[matchField]) {
+                    optMatchFields[matchField]) {
                     // Field mismatch.
                     return;
                 }
@@ -422,7 +422,7 @@ Runtime.prototype.startHats = function (requestedHatOpcode,
             // any existing threads starting with the top block.
             for (var i = 0; i < instance.threads.length; i++) {
                 if (instance.threads[i].topBlock === topBlockId &&
-                    instance.threads[i].target == target) {
+                    instance.threads[i].target === target) {
                     instance._removeThread(instance.threads[i]);
                 }
             }
@@ -431,7 +431,7 @@ Runtime.prototype.startHats = function (requestedHatOpcode,
             // give up if any threads with the top block are running.
             for (var j = 0; j < instance.threads.length; j++) {
                 if (instance.threads[j].topBlock === topBlockId &&
-                    instance.threads[j].target == target) {
+                    instance.threads[j].target === target) {
                     // Some thread is already running.
                     return;
                 }
@@ -439,7 +439,7 @@ Runtime.prototype.startHats = function (requestedHatOpcode,
         }
         // Start the thread with this top block.
         newThreads.push(instance._pushThread(topBlockId, target));
-    }, opt_target);
+    }, optTarget);
     return newThreads;
 };
 
@@ -468,15 +468,15 @@ Runtime.prototype.disposeTarget = function (disposingTarget) {
 /**
  * Stop any threads acting on the target.
  * @param {!Target} target Target to stop threads for.
- * @param {Thread=} opt_threadException Optional thread to skip.
+ * @param {Thread=} optThreadException Optional thread to skip.
  */
-Runtime.prototype.stopForTarget = function (target, opt_threadException) {
+Runtime.prototype.stopForTarget = function (target, optThreadException) {
     // Stop any threads on the target.
     for (var i = 0; i < this.threads.length; i++) {
-        if (this.threads[i] === opt_threadException) {
+        if (this.threads[i] === optThreadException) {
             continue;
         }
-        if (this.threads[i].target == target) {
+        if (this.threads[i].target === target) {
             this._removeThread(this.threads[i]);
         }
     }
@@ -562,13 +562,13 @@ Runtime.prototype.setCompatibilityMode = function (compatibilityModeOn) {
 /**
  * Emit glows/glow clears for scripts after a single tick.
  * Looks at `this.threads` and notices which have turned on/off new glows.
- * @param {Array.<Thread>=} opt_extraThreads Optional list of inactive threads.
+ * @param {Array.<Thread>=} optExtraThreads Optional list of inactive threads.
  */
-Runtime.prototype._updateGlows = function (opt_extraThreads) {
+Runtime.prototype._updateGlows = function (optExtraThreads) {
     var searchThreads = [];
     searchThreads.push.apply(searchThreads, this.threads);
-    if (opt_extraThreads) {
-        searchThreads.push.apply(searchThreads, opt_extraThreads);
+    if (optExtraThreads) {
+        searchThreads.push.apply(searchThreads, optExtraThreads);
     }
     // Set of scripts that request a glow this frame.
     var requestedGlowsThisFrame = [];
@@ -578,7 +578,7 @@ Runtime.prototype._updateGlows = function (opt_extraThreads) {
     for (var i = 0; i < searchThreads.length; i++) {
         var thread = searchThreads[i];
         var target = thread.target;
-        if (target == this._editingTarget) {
+        if (target === this._editingTarget) {
             var blockForThread = thread.blockGlowInFrame;
             if (thread.requestScriptGlowInFrame) {
                 var script = target.blocks.getTopLevelScript(blockForThread);
@@ -672,7 +672,7 @@ Runtime.prototype.visualReport = function (blockId, value) {
 Runtime.prototype.getTargetById = function (targetId) {
     for (var i = 0; i < this.targets.length; i++) {
         var target = this.targets[i];
-        if (target.id == targetId) {
+        if (target.id === targetId) {
             return target;
         }
     }
@@ -686,7 +686,7 @@ Runtime.prototype.getTargetById = function (targetId) {
 Runtime.prototype.getSpriteTargetByName = function (spriteName) {
     for (var i = 0; i < this.targets.length; i++) {
         var target = this.targets[i];
-        if (target.sprite && target.sprite.name == spriteName) {
+        if (target.sprite && target.sprite.name === spriteName) {
             return target;
         }
     }
@@ -750,7 +750,7 @@ Runtime.prototype.start = function () {
         interval = Runtime.THREAD_STEP_INTERVAL_COMPATIBILITY;
     }
     this.currentStepTime = interval;
-    this._steppingInterval = self.setInterval(function() {
+    this._steppingInterval = self.setInterval(function () {
         this._step();
     }.bind(this), interval);
 };
diff --git a/src/engine/sequencer.js b/src/engine/sequencer.js
index 86ae29005..c777949b7 100644
--- a/src/engine/sequencer.js
+++ b/src/engine/sequencer.js
@@ -2,7 +2,7 @@ var Timer = require('../util/timer');
 var Thread = require('./thread');
 var execute = require('./execute.js');
 
-function Sequencer (runtime) {
+var Sequencer = function (runtime) {
     /**
      * A utility timer for timing thread sequencing.
      * @type {!Timer}
@@ -14,7 +14,7 @@ function Sequencer (runtime) {
      * @type {!Runtime}
      */
     this.runtime = runtime;
-}
+};
 
 /**
  * Time to run a warp-mode thread, in ms.
@@ -78,7 +78,7 @@ Sequencer.prototype.stepThreads = function () {
         ranFirstTick = true;
     }
     // Filter inactive threads from `this.runtime.threads`.
-    this.runtime.threads = this.runtime.threads.filter(function(thread) {
+    this.runtime.threads = this.runtime.threads.filter(function (thread) {
         if (inactiveThreads.indexOf(thread) > -1) {
             return false;
         }
diff --git a/src/engine/target.js b/src/engine/target.js
index d5a59b47a..f8f99f47d 100644
--- a/src/engine/target.js
+++ b/src/engine/target.js
@@ -13,7 +13,7 @@ var uid = require('../util/uid');
  * @param {?Blocks} blocks Blocks instance for the blocks owned by this target.
  * @constructor
  */
-function Target (blocks) {
+var Target = function (blocks) {
     if (!blocks) {
         blocks = new Blocks(this);
     }
@@ -39,7 +39,7 @@ function Target (blocks) {
      * @type {Object.<string,*>}
      */
     this.lists = {};
-}
+};
 
 /**
  * Called when the project receives a "green flag."
@@ -109,8 +109,6 @@ Target.prototype.lookupOrCreateList = function (name) {
  * Call to destroy a target.
  * @abstract
  */
-Target.prototype.dispose = function () {
-
-};
+Target.prototype.dispose = function () {};
 
 module.exports = Target;
diff --git a/src/engine/thread.js b/src/engine/thread.js
index 9aeb559f3..765f48b71 100644
--- a/src/engine/thread.js
+++ b/src/engine/thread.js
@@ -3,7 +3,7 @@
  * @param {?string} firstBlock First block to execute in the thread.
  * @constructor
  */
-function Thread (firstBlock) {
+var Thread = function (firstBlock) {
     /**
      * ID of top block of the thread
      * @type {!string}
@@ -53,7 +53,7 @@ function Thread (firstBlock) {
      * @type {?Timer}
      */
     this.warpTimer = null;
-}
+};
 
 /**
  * Thread status for initialized or running thread.
@@ -225,8 +225,8 @@ Thread.prototype.isRecursiveCall = function (procedureCode) {
     var sp = this.stack.length - 1;
     for (var i = sp - 1; i >= 0; i--) {
         var block = this.target.blocks.getBlock(this.stack[i]);
-        if (block.opcode == 'procedures_callnoreturn' &&
-            block.mutation.proccode == procedureCode)  {
+        if (block.opcode === 'procedures_callnoreturn' &&
+            block.mutation.proccode === procedureCode) {
             return true;
         }
         if (--callCount < 0) return false;
diff --git a/src/engine/variable.js b/src/engine/variable.js
index 4e5e5e6e3..65fc21c45 100644
--- a/src/engine/variable.js
+++ b/src/engine/variable.js
@@ -9,10 +9,10 @@
  * @param {boolean} isCloud Whether the variable is stored in the cloud.
  * @constructor
  */
-function Variable (name, value, isCloud) {
+var Variable = function (name, value, isCloud) {
     this.name = name;
     this.value = value;
     this.isCloud = isCloud;
-}
+};
 
 module.exports = Variable;
diff --git a/src/import/sb2import.js b/src/import/sb2import.js
index 927fb650d..b09c7c536 100644
--- a/src/import/sb2import.js
+++ b/src/import/sb2import.js
@@ -9,27 +9,12 @@ var Blocks = require('../engine/blocks');
 var Clone = require('../sprites/clone');
 var Sprite = require('../sprites/sprite');
 var Color = require('../util/color.js');
+var log = require('../util/log');
 var uid = require('../util/uid');
 var specMap = require('./sb2specmap');
 var Variable = require('../engine/variable');
 var List = require('../engine/list');
 
-/**
- * Top-level handler. Parse provided JSON,
- * and process the top-level object (the stage object).
- * @param {!string} json SB2-format JSON to load.
- * @param {!Runtime} runtime Runtime object to load all structures into.
- * @param {Boolean=} opt_forceSprite If set, treat as sprite (Sprite2).
- * @return {?Target} Top-level target created (stage or sprite).
- */
-function sb2import (json, runtime, opt_forceSprite) {
-    return parseScratchObject(
-        JSON.parse(json),
-        runtime,
-        !opt_forceSprite
-    );
-}
-
 /**
  * Parse a single "Scratch object" and create all its in-memory VM objects.
  * @param {!Object} object From-JSON "Scratch object:" sprite, stage, watcher.
@@ -37,7 +22,7 @@ function sb2import (json, runtime, opt_forceSprite) {
  * @param {boolean} topLevel Whether this is the top-level object (stage).
  * @return {?Target} Target created (stage or sprite).
  */
-function parseScratchObject (object, runtime, topLevel) {
+var parseScratchObject = function (object, runtime, topLevel) {
     if (!object.hasOwnProperty('objName')) {
         // Watcher/monitor - skip this object until those are implemented in VM.
         // @todo
@@ -57,8 +42,8 @@ function parseScratchObject (object, runtime, topLevel) {
             var costume = object.costumes[i];
             // @todo: Make sure all the relevant metadata is being pulled out.
             sprite.costumes.push({
-                skin: 'https://cdn.assets.scratch.mit.edu/internalapi/asset/'
-                    + costume.baseLayerMD5 + '/get/',
+                skin: 'https://cdn.assets.scratch.mit.edu/internalapi/asset/' +
+                    costume.baseLayerMD5 + '/get/',
                 name: costume.costumeName,
                 bitmapResolution: costume.bitmapResolution,
                 rotationCenterX: costume.rotationCenterX,
@@ -115,11 +100,11 @@ function parseScratchObject (object, runtime, topLevel) {
         target.currentCostume = Math.round(object.currentCostumeIndex);
     }
     if (object.hasOwnProperty('rotationStyle')) {
-        if (object.rotationStyle == 'none') {
+        if (object.rotationStyle === 'none') {
             target.rotationStyle = Clone.ROTATION_STYLE_NONE;
-        } else if (object.rotationStyle == 'leftRight') {
+        } else if (object.rotationStyle === 'leftRight') {
             target.rotationStyle = Clone.ROTATION_STYLE_LEFT_RIGHT;
-        } else if (object.rotationStyle == 'normal') {
+        } else if (object.rotationStyle === 'normal') {
             target.rotationStyle = Clone.ROTATION_STYLE_ALL_AROUND;
         }
     }
@@ -132,7 +117,23 @@ function parseScratchObject (object, runtime, topLevel) {
         }
     }
     return target;
-}
+};
+
+/**
+ * Top-level handler. Parse provided JSON,
+ * and process the top-level object (the stage object).
+ * @param {!string} json SB2-format JSON to load.
+ * @param {!Runtime} runtime Runtime object to load all structures into.
+ * @param {Boolean=} optForceSprite If set, treat as sprite (Sprite2).
+ * @return {?Target} Top-level target created (stage or sprite).
+ */
+var sb2import = function (json, runtime, optForceSprite) {
+    return parseScratchObject(
+        JSON.parse(json),
+        runtime,
+        !optForceSprite
+    );
+};
 
 /**
  * Parse a Scratch object's scripts into VM blocks.
@@ -140,7 +141,7 @@ function parseScratchObject (object, runtime, topLevel) {
  * @param {!Object} scripts Scripts object from SB2 JSON.
  * @param {!Blocks} blocks Blocks object to load parsed blocks into.
  */
-function parseScripts (scripts, blocks) {
+var parseScripts = function (scripts, blocks) {
     for (var i = 0; i < scripts.length; i++) {
         var script = scripts[i];
         var scriptX = script[0];
@@ -162,7 +163,7 @@ function parseScripts (scripts, blocks) {
             blocks.createBlock(convertedBlocks[j]);
         }
     }
-}
+};
 
 /**
  * Parse any list of blocks from SB2 JSON into a list of VM-format blocks.
@@ -172,7 +173,7 @@ function parseScripts (scripts, blocks) {
  * @param {Array.<Object>} blockList SB2 JSON-format block list.
  * @return {Array.<Object>} Scratch VM-format block list.
  */
-function parseBlockList (blockList) {
+var parseBlockList = function (blockList) {
     var resultingList = [];
     var previousBlock = null; // For setting next.
     for (var i = 0; i < blockList.length; i++) {
@@ -186,7 +187,7 @@ function parseBlockList (blockList) {
         resultingList.push(parsedBlock);
     }
     return resultingList;
-}
+};
 
 /**
  * Flatten a block tree into a block list.
@@ -194,7 +195,7 @@ function parseBlockList (blockList) {
  * @param {Array.<Object>} blocks list generated by `parseBlockList`.
  * @return {Array.<Object>} Flattened list to be passed to `blocks.createBlock`.
  */
-function flatten (blocks) {
+var flatten = function (blocks) {
     var finalBlocks = [];
     for (var i = 0; i < blocks.length; i++) {
         var block = blocks[i];
@@ -205,7 +206,7 @@ function flatten (blocks) {
         delete block.children;
     }
     return finalBlocks;
-}
+};
 
 /**
  * Convert a Scratch 2.0 procedure string (e.g., "my_procedure %s %b %n")
@@ -214,44 +215,44 @@ function flatten (blocks) {
  * @param {string} procCode Scratch 2.0 procedure string.
  * @return {Object} Argument map compatible with those in sb2specmap.
  */
-function parseProcedureArgMap (procCode) {
+var parseProcedureArgMap = function (procCode) {
     var argMap = [
         {} // First item in list is op string.
     ];
     var INPUT_PREFIX = 'input';
     var inputCount = 0;
     // Split by %n, %b, %s.
-    var parts = procCode.split(/(?=[^\\]\%[nbs])/);
+    var parts = procCode.split(/(?=[^\\]%[nbs])/);
     for (var i = 0; i < parts.length; i++) {
         var part = parts[i].trim();
-        if (part.substring(0, 1) == '%') {
+        if (part.substring(0, 1) === '%') {
             var argType = part.substring(1, 2);
             var arg = {
                 type: 'input',
                 inputName: INPUT_PREFIX + (inputCount++)
             };
-            if (argType == 'n') {
+            if (argType === 'n') {
                 arg.inputOp = 'math_number';
-            } else if (argType == 's') {
+            } else if (argType === 's') {
                 arg.inputOp = 'text';
             }
             argMap.push(arg);
         }
     }
     return argMap;
-}
+};
 
 /**
  * Parse a single SB2 JSON-formatted block and its children.
  * @param {!Object} sb2block SB2 JSON-formatted block.
  * @return {Object} Scratch VM format block.
  */
-function parseBlock (sb2block) {
+var parseBlock = function (sb2block) {
     // First item in block object is the old opcode (e.g., 'forward:').
     var oldOpcode = sb2block[0];
     // Convert the block using the specMap. See sb2specmap.js.
     if (!oldOpcode || !specMap[oldOpcode]) {
-        console.warn('Couldn\'t find SB2 block: ', oldOpcode);
+        log.warn('Couldn\'t find SB2 block: ', oldOpcode);
         return;
     }
     var blockMetadata = specMap[oldOpcode];
@@ -266,7 +267,7 @@ function parseBlock (sb2block) {
         children: [] // Store any generated children, flattened in `flatten`.
     };
     // For a procedure call, generate argument map from proc string.
-    if (oldOpcode == 'call') {
+    if (oldOpcode === 'call') {
         blockMetadata.argMap = parseProcedureArgMap(sb2block[1]);
     }
     // Look at the expected arguments in `blockMetadata.argMap.`
@@ -278,7 +279,7 @@ function parseBlock (sb2block) {
         // Whether the input is obscuring a shadow.
         var shadowObscured = false;
         // Positional argument is an input.
-        if (expectedArg.type == 'input') {
+        if (expectedArg.type === 'input') {
             // Create a new block and input metadata.
             var inputUid = uid();
             activeBlock.inputs[expectedArg.inputName] = {
@@ -286,10 +287,10 @@ function parseBlock (sb2block) {
                 block: null,
                 shadow: null
             };
-            if (typeof providedArg == 'object' && providedArg) {
+            if (typeof providedArg === 'object' && providedArg) {
                 // Block or block list occupies the input.
                 var innerBlocks;
-                if (typeof providedArg[0] == 'object' && providedArg[0]) {
+                if (typeof providedArg[0] === 'object' && providedArg[0]) {
                     // Block list occupies the input.
                     innerBlocks = parseBlockList(providedArg);
                 } else {
@@ -298,7 +299,7 @@ function parseBlock (sb2block) {
                 }
                 var previousBlock = null;
                 for (var j = 0; j < innerBlocks.length; j++) {
-                    if (j == 0) {
+                    if (j === 0) {
                         innerBlocks[j].parent = activeBlock.id;
                     } else {
                         innerBlocks[j].parent = previousBlock;
@@ -324,22 +325,22 @@ function parseBlock (sb2block) {
             var fieldValue = providedArg;
             // Shadows' field names match the input name, except for these:
             var fieldName = expectedArg.inputName;
-            if (expectedArg.inputOp == 'math_number' ||
-                expectedArg.inputOp == 'math_whole_number' ||
-                expectedArg.inputOp == 'math_positive_number' ||
-                expectedArg.inputOp == 'math_integer' ||
-                expectedArg.inputOp == 'math_angle') {
+            if (expectedArg.inputOp === 'math_number' ||
+                expectedArg.inputOp === 'math_whole_number' ||
+                expectedArg.inputOp === 'math_positive_number' ||
+                expectedArg.inputOp === 'math_integer' ||
+                expectedArg.inputOp === 'math_angle') {
                 fieldName = 'NUM';
                 // Fields are given Scratch 2.0 default values if obscured.
                 if (shadowObscured) {
                     fieldValue = 10;
                 }
-            } else if (expectedArg.inputOp == 'text') {
+            } else if (expectedArg.inputOp === 'text') {
                 fieldName = 'TEXT';
                 if (shadowObscured) {
                     fieldValue = '';
                 }
-            } else if (expectedArg.inputOp == 'colour_picker') {
+            } else if (expectedArg.inputOp === 'colour_picker') {
                 // Convert SB2 color to hex.
                 fieldValue = Color.decimalToHex(providedArg);
                 fieldName = 'COLOUR';
@@ -367,7 +368,7 @@ function parseBlock (sb2block) {
             if (!activeBlock.inputs[expectedArg.inputName].block) {
                 activeBlock.inputs[expectedArg.inputName].block = inputUid;
             }
-        } else if (expectedArg.type == 'field') {
+        } else if (expectedArg.type === 'field') {
             // Add as a field on this block.
             activeBlock.fields[expectedArg.fieldName] = {
                 name: expectedArg.fieldName,
@@ -376,18 +377,18 @@ function parseBlock (sb2block) {
         }
     }
     // Special cases to generate mutations.
-    if (oldOpcode == 'stopScripts') {
+    if (oldOpcode === 'stopScripts') {
         // Mutation for stop block: if the argument is 'other scripts',
         // the block needs a next connection.
-        if (sb2block[1] == 'other scripts in sprite' ||
-            sb2block[1] == 'other scripts in stage') {
+        if (sb2block[1] === 'other scripts in sprite' ||
+            sb2block[1] === 'other scripts in stage') {
             activeBlock.mutation = {
                 tagName: 'mutation',
                 hasnext: 'true',
                 children: []
             };
         }
-    } else if (oldOpcode == 'procDef') {
+    } else if (oldOpcode === 'procDef') {
         // Mutation for procedure definition:
         // store all 2.0 proc data.
         var procData = sb2block.slice(1);
@@ -399,7 +400,7 @@ function parseBlock (sb2block) {
             warp: procData[3], // Warp mode, e.g., true/false.
             children: []
         };
-    } else if (oldOpcode == 'call') {
+    } else if (oldOpcode === 'call') {
         // Mutation for procedure call:
         // string for proc code (e.g., "abc %n %b %s").
         activeBlock.mutation = {
@@ -407,7 +408,7 @@ function parseBlock (sb2block) {
             children: [],
             proccode: sb2block[1]
         };
-    } else if (oldOpcode == 'getParam') {
+    } else if (oldOpcode === 'getParam') {
         // Mutation for procedure parameter.
         activeBlock.mutation = {
             tagName: 'mutation',
@@ -417,6 +418,6 @@ function parseBlock (sb2block) {
         };
     }
     return activeBlock;
-}
+};
 
 module.exports = sb2import;
diff --git a/src/import/sb2specmap.js b/src/import/sb2specmap.js
index 1cf0620fc..9dceaa052 100644
--- a/src/import/sb2specmap.js
+++ b/src/import/sb2specmap.js
@@ -22,1367 +22,1367 @@
  * Finally, I filled in the expected arguments as below.
  */
 var specMap = {
-    'forward:':{
-        'opcode':'motion_movesteps',
-        'argMap':[
+    'forward:': {
+        opcode: 'motion_movesteps',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'STEPS'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'STEPS'
             }
         ]
     },
-    'turnRight:':{
-        'opcode':'motion_turnright',
-        'argMap':[
+    'turnRight:': {
+        opcode: 'motion_turnright',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'DEGREES'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'DEGREES'
             }
         ]
     },
-    'turnLeft:':{
-        'opcode':'motion_turnleft',
-        'argMap':[
+    'turnLeft:': {
+        opcode: 'motion_turnleft',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'DEGREES'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'DEGREES'
             }
         ]
     },
-    'heading:':{
-        'opcode':'motion_pointindirection',
-        'argMap':[
+    'heading:': {
+        opcode: 'motion_pointindirection',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_angle',
-                'inputName':'DIRECTION'
+                type: 'input',
+                inputOp: 'math_angle',
+                inputName: 'DIRECTION'
             }
         ]
     },
-    'pointTowards:':{
-        'opcode':'motion_pointtowards',
-        'argMap':[
+    'pointTowards:': {
+        opcode: 'motion_pointtowards',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'motion_pointtowards_menu',
-                'inputName':'TOWARDS'
+                type: 'input',
+                inputOp: 'motion_pointtowards_menu',
+                inputName: 'TOWARDS'
             }
         ]
     },
-    'gotoX:y:':{
-        'opcode':'motion_gotoxy',
-        'argMap':[
+    'gotoX:y:': {
+        opcode: 'motion_gotoxy',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'X'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'X'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'Y'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'Y'
             }
         ]
     },
-    'gotoSpriteOrMouse:':{
-        'opcode':'motion_goto',
-        'argMap':[
+    'gotoSpriteOrMouse:': {
+        opcode: 'motion_goto',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'motion_goto_menu',
-                'inputName':'TO'
+                type: 'input',
+                inputOp: 'motion_goto_menu',
+                inputName: 'TO'
             }
         ]
     },
-    'glideSecs:toX:y:elapsed:from:':{
-        'opcode':'motion_glidesecstoxy',
-        'argMap':[
+    'glideSecs:toX:y:elapsed:from:': {
+        opcode: 'motion_glidesecstoxy',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'SECS'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'SECS'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'X'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'X'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'Y'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'Y'
             }
         ]
     },
-    'changeXposBy:':{
-        'opcode':'motion_changexby',
-        'argMap':[
+    'changeXposBy:': {
+        opcode: 'motion_changexby',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'DX'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'DX'
             }
         ]
     },
-    'xpos:':{
-        'opcode':'motion_setx',
-        'argMap':[
+    'xpos:': {
+        opcode: 'motion_setx',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'X'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'X'
             }
         ]
     },
-    'changeYposBy:':{
-        'opcode':'motion_changeyby',
-        'argMap':[
+    'changeYposBy:': {
+        opcode: 'motion_changeyby',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'DY'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'DY'
             }
         ]
     },
-    'ypos:':{
-        'opcode':'motion_sety',
-        'argMap':[
+    'ypos:': {
+        opcode: 'motion_sety',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'Y'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'Y'
             }
         ]
     },
-    'bounceOffEdge':{
-        'opcode':'motion_ifonedgebounce',
-        'argMap':[
+    'bounceOffEdge': {
+        opcode: 'motion_ifonedgebounce',
+        argMap: [
         ]
     },
-    'setRotationStyle':{
-        'opcode':'motion_setrotationstyle',
-        'argMap':[
+    'setRotationStyle': {
+        opcode: 'motion_setrotationstyle',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'motion_setrotationstyle_menu',
-                'inputName':'STYLE'
+                type: 'input',
+                inputOp: 'motion_setrotationstyle_menu',
+                inputName: 'STYLE'
             }
         ]
     },
-    'xpos':{
-        'opcode':'motion_xposition',
-        'argMap':[
+    'xpos': {
+        opcode: 'motion_xposition',
+        argMap: [
         ]
     },
-    'ypos':{
-        'opcode':'motion_yposition',
-        'argMap':[
+    'ypos': {
+        opcode: 'motion_yposition',
+        argMap: [
         ]
     },
-    'heading':{
-        'opcode':'motion_direction',
-        'argMap':[
+    'heading': {
+        opcode: 'motion_direction',
+        argMap: [
         ]
     },
-    'say:duration:elapsed:from:':{
-        'opcode':'looks_sayforsecs',
-        'argMap':[
+    'say:duration:elapsed:from:': {
+        opcode: 'looks_sayforsecs',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'MESSAGE'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'MESSAGE'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'SECS'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'SECS'
             }
         ]
     },
-    'say:':{
-        'opcode':'looks_say',
-        'argMap':[
+    'say:': {
+        opcode: 'looks_say',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'MESSAGE'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'MESSAGE'
             }
         ]
     },
-    'think:duration:elapsed:from:':{
-        'opcode':'looks_thinkforsecs',
-        'argMap':[
+    'think:duration:elapsed:from:': {
+        opcode: 'looks_thinkforsecs',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'MESSAGE'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'MESSAGE'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'SECS'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'SECS'
             }
         ]
     },
-    'think:':{
-        'opcode':'looks_think',
-        'argMap':[
+    'think:': {
+        opcode: 'looks_think',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'MESSAGE'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'MESSAGE'
             }
         ]
     },
-    'show':{
-        'opcode':'looks_show',
-        'argMap':[
+    'show': {
+        opcode: 'looks_show',
+        argMap: [
         ]
     },
-    'hide':{
-        'opcode':'looks_hide',
-        'argMap':[
+    'hide': {
+        opcode: 'looks_hide',
+        argMap: [
         ]
     },
-    'lookLike:':{
-        'opcode':'looks_switchcostumeto',
-        'argMap':[
+    'lookLike:': {
+        opcode: 'looks_switchcostumeto',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'looks_costume',
-                'inputName':'COSTUME'
+                type: 'input',
+                inputOp: 'looks_costume',
+                inputName: 'COSTUME'
             }
         ]
     },
-    'nextCostume':{
-        'opcode':'looks_nextcostume',
-        'argMap':[
+    'nextCostume': {
+        opcode: 'looks_nextcostume',
+        argMap: [
         ]
     },
-    'startScene':{
-        'opcode':'looks_switchbackdropto',
-        'argMap':[
+    'startScene': {
+        opcode: 'looks_switchbackdropto',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'looks_backdrops',
-                'inputName':'BACKDROP'
+                type: 'input',
+                inputOp: 'looks_backdrops',
+                inputName: 'BACKDROP'
             }
         ]
     },
-    'changeGraphicEffect:by:':{
-        'opcode':'looks_changeeffectby',
-        'argMap':[
+    'changeGraphicEffect:by:': {
+        opcode: 'looks_changeeffectby',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'looks_effectmenu',
-                'inputName':'EFFECT'
+                type: 'input',
+                inputOp: 'looks_effectmenu',
+                inputName: 'EFFECT'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'CHANGE'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'CHANGE'
             }
         ]
     },
-    'setGraphicEffect:to:':{
-        'opcode':'looks_seteffectto',
-        'argMap':[
+    'setGraphicEffect:to:': {
+        opcode: 'looks_seteffectto',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'looks_effectmenu',
-                'inputName':'EFFECT'
+                type: 'input',
+                inputOp: 'looks_effectmenu',
+                inputName: 'EFFECT'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'VALUE'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'VALUE'
             }
         ]
     },
-    'filterReset':{
-        'opcode':'looks_cleargraphiceffects',
-        'argMap':[
+    'filterReset': {
+        opcode: 'looks_cleargraphiceffects',
+        argMap: [
         ]
     },
-    'changeSizeBy:':{
-        'opcode':'looks_changesizeby',
-        'argMap':[
+    'changeSizeBy:': {
+        opcode: 'looks_changesizeby',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'CHANGE'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'CHANGE'
             }
         ]
     },
-    'setSizeTo:':{
-        'opcode':'looks_setsizeto',
-        'argMap':[
+    'setSizeTo:': {
+        opcode: 'looks_setsizeto',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'SIZE'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'SIZE'
             }
         ]
     },
-    'comeToFront':{
-        'opcode':'looks_gotofront',
-        'argMap':[
+    'comeToFront': {
+        opcode: 'looks_gotofront',
+        argMap: [
         ]
     },
-    'goBackByLayers:':{
-        'opcode':'looks_gobacklayers',
-        'argMap':[
+    'goBackByLayers:': {
+        opcode: 'looks_gobacklayers',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_integer',
-                'inputName':'NUM'
+                type: 'input',
+                inputOp: 'math_integer',
+                inputName: 'NUM'
             }
         ]
     },
-    'costumeIndex':{
-        'opcode':'looks_costumeorder',
-        'argMap':[
+    'costumeIndex': {
+        opcode: 'looks_costumeorder',
+        argMap: [
         ]
     },
-    'sceneName':{
-        'opcode':'looks_backdropname',
-        'argMap':[
+    'sceneName': {
+        opcode: 'looks_backdropname',
+        argMap: [
         ]
     },
-    'scale':{
-        'opcode':'looks_size',
-        'argMap':[
+    'scale': {
+        opcode: 'looks_size',
+        argMap: [
         ]
     },
-    'startSceneAndWait':{
-        'opcode':'looks_switchbackdroptoandwait',
-        'argMap':[
+    'startSceneAndWait': {
+        opcode: 'looks_switchbackdroptoandwait',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'looks_backdrops',
-                'inputName':'BACKDROP'
+                type: 'input',
+                inputOp: 'looks_backdrops',
+                inputName: 'BACKDROP'
             }
         ]
     },
-    'nextScene':{
-        'opcode':'looks_nextbackdrop',
-        'argMap':[
+    'nextScene': {
+        opcode: 'looks_nextbackdrop',
+        argMap: [
         ]
     },
-    'backgroundIndex':{
-        'opcode':'looks_backdroporder',
-        'argMap':[
+    'backgroundIndex': {
+        opcode: 'looks_backdroporder',
+        argMap: [
         ]
     },
-    'playSound:':{
-        'opcode':'sound_play',
-        'argMap':[
+    'playSound:': {
+        opcode: 'sound_play',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'sound_sounds_option',
-                'inputName':'SOUND_MENU'
+                type: 'input',
+                inputOp: 'sound_sounds_option',
+                inputName: 'SOUND_MENU'
             }
         ]
     },
-    'doPlaySoundAndWait':{
-        'opcode':'sound_playuntildone',
-        'argMap':[
+    'doPlaySoundAndWait': {
+        opcode: 'sound_playuntildone',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'sound_sounds_option',
-                'inputName':'SOUND_MENU'
+                type: 'input',
+                inputOp: 'sound_sounds_option',
+                inputName: 'SOUND_MENU'
             }
         ]
     },
-    'stopAllSounds':{
-        'opcode':'sound_stopallsounds',
-        'argMap':[
+    'stopAllSounds': {
+        opcode: 'sound_stopallsounds',
+        argMap: [
         ]
     },
-    'playDrum':{
-        'opcode':'sound_playdrumforbeats',
-        'argMap':[
+    'playDrum': {
+        opcode: 'sound_playdrumforbeats',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'DRUMTYPE'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'DRUMTYPE'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'BEATS'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'BEATS'
             }
         ]
     },
-    'rest:elapsed:from:':{
-        'opcode':'sound_restforbeats',
-        'argMap':[
+    'rest:elapsed:from:': {
+        opcode: 'sound_restforbeats',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'BEATS'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'BEATS'
             }
         ]
     },
-    'noteOn:duration:elapsed:from:':{
-        'opcode':'sound_playnoteforbeats',
-        'argMap':[
+    'noteOn:duration:elapsed:from:': {
+        opcode: 'sound_playnoteforbeats',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'NOTE'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'NOTE'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'BEATS'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'BEATS'
             }
         ]
     },
-    'instrument:':{
-        'opcode':'sound_setinstrumentto',
-        'argMap':[
+    'instrument:': {
+        opcode: 'sound_setinstrumentto',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'INSTRUMENT'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'INSTRUMENT'
             }
         ]
     },
-    'changeVolumeBy:':{
-        'opcode':'sound_changevolumeby',
-        'argMap':[
+    'changeVolumeBy:': {
+        opcode: 'sound_changevolumeby',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'VOLUME'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'VOLUME'
             }
         ]
     },
-    'setVolumeTo:':{
-        'opcode':'sound_setvolumeto',
-        'argMap':[
+    'setVolumeTo:': {
+        opcode: 'sound_setvolumeto',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'VOLUME'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'VOLUME'
             }
         ]
     },
-    'volume':{
-        'opcode':'sound_volume',
-        'argMap':[
+    'volume': {
+        opcode: 'sound_volume',
+        argMap: [
         ]
     },
-    'changeTempoBy:':{
-        'opcode':'sound_changetempoby',
-        'argMap':[
+    'changeTempoBy:': {
+        opcode: 'sound_changetempoby',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'TEMPO'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'TEMPO'
             }
         ]
     },
-    'setTempoTo:':{
-        'opcode':'sound_settempotobpm',
-        'argMap':[
+    'setTempoTo:': {
+        opcode: 'sound_settempotobpm',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'TEMPO'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'TEMPO'
             }
         ]
     },
-    'tempo':{
-        'opcode':'sound_tempo',
-        'argMap':[
+    'tempo': {
+        opcode: 'sound_tempo',
+        argMap: [
         ]
     },
-    'clearPenTrails':{
-        'opcode':'pen_clear',
-        'argMap':[
+    'clearPenTrails': {
+        opcode: 'pen_clear',
+        argMap: [
         ]
     },
-    'stampCostume':{
-        'opcode':'pen_stamp',
-        'argMap':[
+    'stampCostume': {
+        opcode: 'pen_stamp',
+        argMap: [
         ]
     },
-    'putPenDown':{
-        'opcode':'pen_pendown',
-        'argMap':[
+    'putPenDown': {
+        opcode: 'pen_pendown',
+        argMap: [
         ]
     },
-    'putPenUp':{
-        'opcode':'pen_penup',
-        'argMap':[
+    'putPenUp': {
+        opcode: 'pen_penup',
+        argMap: [
         ]
     },
-    'penColor:':{
-        'opcode':'pen_setpencolortocolor',
-        'argMap':[
+    'penColor:': {
+        opcode: 'pen_setpencolortocolor',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'colour_picker',
-                'inputName':'COLOR'
+                type: 'input',
+                inputOp: 'colour_picker',
+                inputName: 'COLOR'
             }
         ]
     },
-    'changePenHueBy:':{
-        'opcode':'pen_changepencolorby',
-        'argMap':[
+    'changePenHueBy:': {
+        opcode: 'pen_changepencolorby',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'COLOR'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'COLOR'
             }
         ]
     },
-    'setPenHueTo:':{
-        'opcode':'pen_setpencolortonum',
-        'argMap':[
+    'setPenHueTo:': {
+        opcode: 'pen_setpencolortonum',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'COLOR'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'COLOR'
             }
         ]
     },
-    'changePenShadeBy:':{
-        'opcode':'pen_changepenshadeby',
-        'argMap':[
+    'changePenShadeBy:': {
+        opcode: 'pen_changepenshadeby',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'SHADE'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'SHADE'
             }
         ]
     },
-    'setPenShadeTo:':{
-        'opcode':'pen_changepenshadeby',
-        'argMap':[
+    'setPenShadeTo:': {
+        opcode: 'pen_changepenshadeby',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'SHADE'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'SHADE'
             }
         ]
     },
-    'changePenSizeBy:':{
-        'opcode':'pen_changepensizeby',
-        'argMap':[
+    'changePenSizeBy:': {
+        opcode: 'pen_changepensizeby',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'SIZE'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'SIZE'
             }
         ]
     },
-    'penSize:':{
-        'opcode':'pen_setpensizeto',
-        'argMap':[
+    'penSize:': {
+        opcode: 'pen_setpensizeto',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'SIZE'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'SIZE'
             }
         ]
     },
-    'whenGreenFlag':{
-        'opcode':'event_whenflagclicked',
-        'argMap':[
+    'whenGreenFlag': {
+        opcode: 'event_whenflagclicked',
+        argMap: [
         ]
     },
-    'whenKeyPressed':{
-        'opcode':'event_whenkeypressed',
-        'argMap':[
+    'whenKeyPressed': {
+        opcode: 'event_whenkeypressed',
+        argMap: [
             {
-                'type':'field',
-                'fieldName':'KEY_OPTION'
+                type: 'field',
+                fieldName: 'KEY_OPTION'
             }
         ]
     },
-    'whenClicked':{
-        'opcode':'event_whenthisspriteclicked',
-        'argMap':[
+    'whenClicked': {
+        opcode: 'event_whenthisspriteclicked',
+        argMap: [
         ]
     },
-    'whenSceneStarts':{
-        'opcode':'event_whenbackdropswitchesto',
-        'argMap':[
+    'whenSceneStarts': {
+        opcode: 'event_whenbackdropswitchesto',
+        argMap: [
             {
-                'type':'field',
-                'fieldName':'BACKDROP'
+                type: 'field',
+                fieldName: 'BACKDROP'
             }
         ]
     },
-    'whenSensorGreaterThan':{
-        'opcode':'event_whengreaterthan',
-        'argMap':[
+    'whenSensorGreaterThan': {
+        opcode: 'event_whengreaterthan',
+        argMap: [
             {
-                'type':'field',
-                'fieldName':'WHENGREATERTHANMENU'
+                type: 'field',
+                fieldName: 'WHENGREATERTHANMENU'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'VALUE'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'VALUE'
             }
         ]
     },
-    'whenIReceive':{
-        'opcode':'event_whenbroadcastreceived',
-        'argMap':[
+    'whenIReceive': {
+        opcode: 'event_whenbroadcastreceived',
+        argMap: [
             {
-                'type':'field',
-                'fieldName':'BROADCAST_OPTION'
+                type: 'field',
+                fieldName: 'BROADCAST_OPTION'
             }
         ]
     },
-    'broadcast:':{
-        'opcode':'event_broadcast',
-        'argMap':[
+    'broadcast:': {
+        opcode: 'event_broadcast',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'event_broadcast_menu',
-                'inputName':'BROADCAST_OPTION'
+                type: 'input',
+                inputOp: 'event_broadcast_menu',
+                inputName: 'BROADCAST_OPTION'
             }
         ]
     },
-    'doBroadcastAndWait':{
-        'opcode':'event_broadcastandwait',
-        'argMap':[
+    'doBroadcastAndWait': {
+        opcode: 'event_broadcastandwait',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'event_broadcast_menu',
-                'inputName':'BROADCAST_OPTION'
+                type: 'input',
+                inputOp: 'event_broadcast_menu',
+                inputName: 'BROADCAST_OPTION'
             }
         ]
     },
-    'wait:elapsed:from:':{
-        'opcode':'control_wait',
-        'argMap':[
+    'wait:elapsed:from:': {
+        opcode: 'control_wait',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_positive_number',
-                'inputName':'DURATION'
+                type: 'input',
+                inputOp: 'math_positive_number',
+                inputName: 'DURATION'
             }
         ]
     },
-    'doRepeat':{
-        'opcode':'control_repeat',
-        'argMap':[
+    'doRepeat': {
+        opcode: 'control_repeat',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_whole_number',
-                'inputName':'TIMES'
+                type: 'input',
+                inputOp: 'math_whole_number',
+                inputName: 'TIMES'
             },
             {
-                'type':'input',
-                'inputName': 'SUBSTACK'
+                type: 'input',
+                inputName: 'SUBSTACK'
             }
         ]
     },
-    'doForever':{
-        'opcode':'control_forever',
-        'argMap':[
+    'doForever': {
+        opcode: 'control_forever',
+        argMap: [
             {
-                'type':'input',
-                'inputName':'SUBSTACK'
+                type: 'input',
+                inputName: 'SUBSTACK'
             }
         ]
     },
-    'doIf':{
-        'opcode':'control_if',
-        'argMap':[
+    'doIf': {
+        opcode: 'control_if',
+        argMap: [
             {
-                'type':'input',
-                'inputName':'CONDITION'
+                type: 'input',
+                inputName: 'CONDITION'
             },
             {
-                'type':'input',
-                'inputName':'SUBSTACK'
+                type: 'input',
+                inputName: 'SUBSTACK'
             }
         ]
     },
-    'doIfElse':{
-        'opcode':'control_if_else',
-        'argMap':[
+    'doIfElse': {
+        opcode: 'control_if_else',
+        argMap: [
             {
-                'type':'input',
-                'inputName':'CONDITION'
+                type: 'input',
+                inputName: 'CONDITION'
             },
             {
-                'type':'input',
-                'inputName':'SUBSTACK'
+                type: 'input',
+                inputName: 'SUBSTACK'
             },
             {
-                'type':'input',
-                'inputName':'SUBSTACK2'
+                type: 'input',
+                inputName: 'SUBSTACK2'
             }
         ]
     },
-    'doWaitUntil':{
-        'opcode':'control_wait_until',
-        'argMap':[
+    'doWaitUntil': {
+        opcode: 'control_wait_until',
+        argMap: [
             {
-                'type':'input',
-                'inputName':'CONDITION'
+                type: 'input',
+                inputName: 'CONDITION'
             }
         ]
     },
-    'doUntil':{
-        'opcode':'control_repeat_until',
-        'argMap':[
+    'doUntil': {
+        opcode: 'control_repeat_until',
+        argMap: [
             {
-                'type':'input',
-                'inputName':'CONDITION'
+                type: 'input',
+                inputName: 'CONDITION'
             },
             {
-                'type':'input',
-                'inputName':'SUBSTACK'
+                type: 'input',
+                inputName: 'SUBSTACK'
             }
         ]
     },
-    'stopScripts':{
-        'opcode':'control_stop',
-        'argMap':[
+    'stopScripts': {
+        opcode: 'control_stop',
+        argMap: [
             {
-                'type':'field',
-                'fieldName':'STOP_OPTION'
+                type: 'field',
+                fieldName: 'STOP_OPTION'
             }
         ]
     },
-    'whenCloned':{
-        'opcode':'control_start_as_clone',
-        'argMap':[
+    'whenCloned': {
+        opcode: 'control_start_as_clone',
+        argMap: [
         ]
     },
-    'createCloneOf':{
-        'opcode':'control_create_clone_of',
-        'argMap':[
+    'createCloneOf': {
+        opcode: 'control_create_clone_of',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'control_create_clone_of_menu',
-                'inputName':'CLONE_OPTION'
+                type: 'input',
+                inputOp: 'control_create_clone_of_menu',
+                inputName: 'CLONE_OPTION'
             }
         ]
     },
-    'deleteClone':{
-        'opcode':'control_delete_this_clone',
-        'argMap':[
+    'deleteClone': {
+        opcode: 'control_delete_this_clone',
+        argMap: [
         ]
     },
-    'touching:':{
-        'opcode':'sensing_touchingobject',
-        'argMap':[
+    'touching:': {
+        opcode: 'sensing_touchingobject',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'sensing_touchingobjectmenu',
-                'inputName':'TOUCHINGOBJECTMENU'
+                type: 'input',
+                inputOp: 'sensing_touchingobjectmenu',
+                inputName: 'TOUCHINGOBJECTMENU'
             }
         ]
     },
-    'touchingColor:':{
-        'opcode':'sensing_touchingcolor',
-        'argMap':[
+    'touchingColor:': {
+        opcode: 'sensing_touchingcolor',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'colour_picker',
-                'inputName':'COLOR'
+                type: 'input',
+                inputOp: 'colour_picker',
+                inputName: 'COLOR'
             }
         ]
     },
-    'color:sees:':{
-        'opcode':'sensing_coloristouchingcolor',
-        'argMap':[
+    'color:sees:': {
+        opcode: 'sensing_coloristouchingcolor',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'colour_picker',
-                'inputName':'COLOR'
+                type: 'input',
+                inputOp: 'colour_picker',
+                inputName: 'COLOR'
             },
             {
-                'type':'input',
-                'inputOp':'colour_picker',
-                'inputName':'COLOR2'
+                type: 'input',
+                inputOp: 'colour_picker',
+                inputName: 'COLOR2'
             }
         ]
     },
-    'distanceTo:':{
-        'opcode':'sensing_distanceto',
-        'argMap':[
+    'distanceTo:': {
+        opcode: 'sensing_distanceto',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'sensing_distancetomenu',
-                'inputName':'DISTANCETOMENU'
+                type: 'input',
+                inputOp: 'sensing_distancetomenu',
+                inputName: 'DISTANCETOMENU'
             }
         ]
     },
-    'doAsk':{
-        'opcode':'sensing_askandwait',
-        'argMap':[
+    'doAsk': {
+        opcode: 'sensing_askandwait',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'QUESTION'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'QUESTION'
             }
         ]
     },
-    'answer':{
-        'opcode':'sensing_answer',
-        'argMap':[
+    'answer': {
+        opcode: 'sensing_answer',
+        argMap: [
         ]
     },
-    'keyPressed:':{
-        'opcode':'sensing_keypressed',
-        'argMap':[
+    'keyPressed:': {
+        opcode: 'sensing_keypressed',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'sensing_keyoptions',
-                'inputName':'KEY_OPTION'
+                type: 'input',
+                inputOp: 'sensing_keyoptions',
+                inputName: 'KEY_OPTION'
             }
         ]
     },
-    'mousePressed':{
-        'opcode':'sensing_mousedown',
-        'argMap':[
+    'mousePressed': {
+        opcode: 'sensing_mousedown',
+        argMap: [
         ]
     },
-    'mouseX':{
-        'opcode':'sensing_mousex',
-        'argMap':[
+    'mouseX': {
+        opcode: 'sensing_mousex',
+        argMap: [
         ]
     },
-    'mouseY':{
-        'opcode':'sensing_mousey',
-        'argMap':[
+    'mouseY': {
+        opcode: 'sensing_mousey',
+        argMap: [
         ]
     },
-    'soundLevel':{
-        'opcode':'sensing_loudness',
-        'argMap':[
+    'soundLevel': {
+        opcode: 'sensing_loudness',
+        argMap: [
         ]
     },
-    'senseVideoMotion':{
-        'opcode':'sensing_videoon',
-        'argMap':[
+    'senseVideoMotion': {
+        opcode: 'sensing_videoon',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'sensing_videoonmenuone',
-                'inputName':'VIDEOONMENU1'
+                type: 'input',
+                inputOp: 'sensing_videoonmenuone',
+                inputName: 'VIDEOONMENU1'
             },
             {
-                'type':'input',
-                'inputOp':'sensing_videoonmenutwo',
-                'inputName':'VIDEOONMENU2'
+                type: 'input',
+                inputOp: 'sensing_videoonmenutwo',
+                inputName: 'VIDEOONMENU2'
             }
         ]
     },
-    'setVideoState':{
-        'opcode':'sensing_videotoggle',
-        'argMap':[
+    'setVideoState': {
+        opcode: 'sensing_videotoggle',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'sensing_videotogglemenu',
-                'inputName':'VIDEOTOGGLEMENU'
+                type: 'input',
+                inputOp: 'sensing_videotogglemenu',
+                inputName: 'VIDEOTOGGLEMENU'
             }
         ]
     },
-    'setVideoTransparency':{
-        'opcode':'sensing_setvideotransparency',
-        'argMap':[
+    'setVideoTransparency': {
+        opcode: 'sensing_setvideotransparency',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'TRANSPARENCY'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'TRANSPARENCY'
             }
         ]
     },
-    'timer':{
-        'opcode':'sensing_timer',
-        'argMap':[
+    'timer': {
+        opcode: 'sensing_timer',
+        argMap: [
         ]
     },
-    'timerReset':{
-        'opcode':'sensing_resettimer',
-        'argMap':[
+    'timerReset': {
+        opcode: 'sensing_resettimer',
+        argMap: [
         ]
     },
-    'getAttribute:of:':{
-        'opcode':'sensing_of',
-        'argMap':[
+    'getAttribute:of:': {
+        opcode: 'sensing_of',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'sensing_of_property_menu',
-                'inputName':'PROPERTY'
+                type: 'input',
+                inputOp: 'sensing_of_property_menu',
+                inputName: 'PROPERTY'
             },
             {
-                'type':'input',
-                'inputOp':'sensing_of_object_menu',
-                'inputName':'OBJECT'
+                type: 'input',
+                inputOp: 'sensing_of_object_menu',
+                inputName: 'OBJECT'
             }
         ]
     },
-    'timeAndDate':{
-        'opcode':'sensing_current',
-        'argMap':[
+    'timeAndDate': {
+        opcode: 'sensing_current',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'sensing_currentmenu',
-                'inputName':'CURRENTMENU'
+                type: 'input',
+                inputOp: 'sensing_currentmenu',
+                inputName: 'CURRENTMENU'
             }
         ]
     },
-    'timestamp':{
-        'opcode':'sensing_dayssince2000',
-        'argMap':[
+    'timestamp': {
+        opcode: 'sensing_dayssince2000',
+        argMap: [
         ]
     },
-    'getUserName':{
-        'opcode':'sensing_username',
-        'argMap':[
+    'getUserName': {
+        opcode: 'sensing_username',
+        argMap: [
         ]
     },
-    '+':{
-        'opcode':'operator_add',
-        'argMap':[
+    '+': {
+        opcode: 'operator_add',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'NUM1'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'NUM1'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'NUM2'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'NUM2'
             }
         ]
     },
-    '-':{
-        'opcode':'operator_subtract',
-        'argMap':[
+    '-': {
+        opcode: 'operator_subtract',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'NUM1'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'NUM1'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'NUM2'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'NUM2'
             }
         ]
     },
-    '*':{
-        'opcode':'operator_multiply',
-        'argMap':[
+    '*': {
+        opcode: 'operator_multiply',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'NUM1'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'NUM1'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'NUM2'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'NUM2'
             }
         ]
     },
-    '/':{
-        'opcode':'operator_divide',
-        'argMap':[
+    '/': {
+        opcode: 'operator_divide',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'NUM1'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'NUM1'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'NUM2'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'NUM2'
             }
         ]
     },
-    'randomFrom:to:':{
-        'opcode':'operator_random',
-        'argMap':[
+    'randomFrom:to:': {
+        opcode: 'operator_random',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'FROM'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'FROM'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'TO'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'TO'
             }
         ]
     },
-    '<':{
-        'opcode':'operator_lt',
-        'argMap':[
+    '<': {
+        opcode: 'operator_lt',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'OPERAND1'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'OPERAND1'
             },
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'OPERAND2'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'OPERAND2'
             }
         ]
     },
-    '=':{
-        'opcode':'operator_equals',
-        'argMap':[
+    '=': {
+        opcode: 'operator_equals',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'OPERAND1'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'OPERAND1'
             },
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'OPERAND2'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'OPERAND2'
             }
         ]
     },
-    '>':{
-        'opcode':'operator_gt',
-        'argMap':[
+    '>': {
+        opcode: 'operator_gt',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'OPERAND1'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'OPERAND1'
             },
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'OPERAND2'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'OPERAND2'
             }
         ]
     },
-    '&':{
-        'opcode':'operator_and',
-        'argMap':[
+    '&': {
+        opcode: 'operator_and',
+        argMap: [
             {
-                'type':'input',
-                'inputName':'OPERAND1'
+                type: 'input',
+                inputName: 'OPERAND1'
             },
             {
-                'type':'input',
-                'inputName':'OPERAND2'
+                type: 'input',
+                inputName: 'OPERAND2'
             }
         ]
     },
-    '|':{
-        'opcode':'operator_or',
-        'argMap':[
+    '|': {
+        opcode: 'operator_or',
+        argMap: [
             {
-                'type':'input',
-                'inputName':'OPERAND1'
+                type: 'input',
+                inputName: 'OPERAND1'
             },
             {
-                'type':'input',
-                'inputName':'OPERAND2'
+                type: 'input',
+                inputName: 'OPERAND2'
             }
         ]
     },
-    'not':{
-        'opcode':'operator_not',
-        'argMap':[
+    'not': {
+        opcode: 'operator_not',
+        argMap: [
             {
-                'type':'input',
-                'inputName':'OPERAND'
+                type: 'input',
+                inputName: 'OPERAND'
             }
         ]
     },
-    'concatenate:with:':{
-        'opcode':'operator_join',
-        'argMap':[
+    'concatenate:with:': {
+        opcode: 'operator_join',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'STRING1'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'STRING1'
             },
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'STRING2'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'STRING2'
             }
         ]
     },
-    'letter:of:':{
-        'opcode':'operator_letter_of',
-        'argMap':[
+    'letter:of:': {
+        opcode: 'operator_letter_of',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_whole_number',
-                'inputName':'LETTER'
+                type: 'input',
+                inputOp: 'math_whole_number',
+                inputName: 'LETTER'
             },
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'STRING'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'STRING'
             }
         ]
     },
-    'stringLength:':{
-        'opcode':'operator_length',
-        'argMap':[
+    'stringLength:': {
+        opcode: 'operator_length',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'STRING'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'STRING'
             }
         ]
     },
-    '%':{
-        'opcode':'operator_mod',
-        'argMap':[
+    '%': {
+        opcode: 'operator_mod',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'NUM1'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'NUM1'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'NUM2'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'NUM2'
             }
         ]
     },
-    'rounded':{
-        'opcode':'operator_round',
-        'argMap':[
+    'rounded': {
+        opcode: 'operator_round',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'NUM'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'NUM'
             }
         ]
     },
-    'computeFunction:of:':{
-        'opcode':'operator_mathop',
-        'argMap':[
+    'computeFunction:of:': {
+        opcode: 'operator_mathop',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'operator_mathop_menu',
-                'inputName':'OPERATOR'
+                type: 'input',
+                inputOp: 'operator_mathop_menu',
+                inputName: 'OPERATOR'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'NUM'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'NUM'
             }
         ]
     },
-    'readVariable':{
-        'opcode':'data_variable',
-        'argMap':[
+    'readVariable': {
+        opcode: 'data_variable',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'data_variablemenu',
-                'inputName':'VARIABLE'
+                type: 'input',
+                inputOp: 'data_variablemenu',
+                inputName: 'VARIABLE'
             }
         ]
     },
-    'setVar:to:':{
-        'opcode':'data_setvariableto',
-        'argMap':[
+    'setVar:to:': {
+        opcode: 'data_setvariableto',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'data_variablemenu',
-                'inputName':'VARIABLE'
+                type: 'input',
+                inputOp: 'data_variablemenu',
+                inputName: 'VARIABLE'
             },
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'VALUE'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'VALUE'
             }
         ]
     },
-    'changeVar:by:':{
-        'opcode':'data_changevariableby',
-        'argMap':[
+    'changeVar:by:': {
+        opcode: 'data_changevariableby',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'data_variablemenu',
-                'inputName':'VARIABLE'
+                type: 'input',
+                inputOp: 'data_variablemenu',
+                inputName: 'VARIABLE'
             },
             {
-                'type':'input',
-                'inputOp':'math_number',
-                'inputName':'VALUE'
+                type: 'input',
+                inputOp: 'math_number',
+                inputName: 'VALUE'
             }
         ]
     },
-    'showVariable:':{
-        'opcode':'data_showvariable',
-        'argMap':[
+    'showVariable:': {
+        opcode: 'data_showvariable',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'data_variablemenu',
-                'inputName':'VARIABLE'
+                type: 'input',
+                inputOp: 'data_variablemenu',
+                inputName: 'VARIABLE'
             }
         ]
     },
-    'hideVariable:':{
-        'opcode':'data_hidevariable',
-        'argMap':[
+    'hideVariable:': {
+        opcode: 'data_hidevariable',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'data_variablemenu',
-                'inputName':'VARIABLE'
+                type: 'input',
+                inputOp: 'data_variablemenu',
+                inputName: 'VARIABLE'
             }
         ]
     },
-    'contentsOfList:':{
-        'opcode':'data_list',
-        'argMap':[
+    'contentsOfList:': {
+        opcode: 'data_list',
+        argMap: [
             {
-                'type':'field',
-                'fieldName':'LIST'
+                type: 'field',
+                fieldName: 'LIST'
             }
         ]
     },
-    'append:toList:':{
-        'opcode':'data_addtolist',
-        'argMap':[
+    'append:toList:': {
+        opcode: 'data_addtolist',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'ITEM'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'ITEM'
             },
             {
-                'type':'field',
-                'fieldName':'LIST'
+                type: 'field',
+                fieldName: 'LIST'
             }
         ]
     },
-    'deleteLine:ofList:':{
-        'opcode':'data_deleteoflist',
-        'argMap':[
+    'deleteLine:ofList:': {
+        opcode: 'data_deleteoflist',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_integer',
-                'inputName':'INDEX'
+                type: 'input',
+                inputOp: 'math_integer',
+                inputName: 'INDEX'
             },
             {
-                'type':'field',
-                'fieldName':'LIST'
+                type: 'field',
+                fieldName: 'LIST'
             }
         ]
     },
-    'insert:at:ofList:':{
-        'opcode':'data_insertatlist',
-        'argMap':[
+    'insert:at:ofList:': {
+        opcode: 'data_insertatlist',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'ITEM'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'ITEM'
             },
             {
-                'type':'input',
-                'inputOp':'math_integer',
-                'inputName':'INDEX'
+                type: 'input',
+                inputOp: 'math_integer',
+                inputName: 'INDEX'
             },
             {
-                'type':'field',
-                'fieldName':'LIST'
+                type: 'field',
+                fieldName: 'LIST'
             }
         ]
     },
-    'setLine:ofList:to:':{
-        'opcode':'data_replaceitemoflist',
-        'argMap':[
+    'setLine:ofList:to:': {
+        opcode: 'data_replaceitemoflist',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_integer',
-                'inputName':'INDEX'
+                type: 'input',
+                inputOp: 'math_integer',
+                inputName: 'INDEX'
             },
             {
-                'type':'field',
-                'fieldName':'LIST'
+                type: 'field',
+                fieldName: 'LIST'
             },
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'ITEM'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'ITEM'
             }
         ]
     },
-    'getLine:ofList:':{
-        'opcode':'data_itemoflist',
-        'argMap':[
+    'getLine:ofList:': {
+        opcode: 'data_itemoflist',
+        argMap: [
             {
-                'type':'input',
-                'inputOp':'math_integer',
-                'inputName':'INDEX'
+                type: 'input',
+                inputOp: 'math_integer',
+                inputName: 'INDEX'
             },
             {
-                'type':'field',
-                'fieldName':'LIST'
+                type: 'field',
+                fieldName: 'LIST'
             }
         ]
     },
-    'lineCountOfList:':{
-        'opcode':'data_lengthoflist',
-        'argMap':[
+    'lineCountOfList:': {
+        opcode: 'data_lengthoflist',
+        argMap: [
             {
-                'type':'field',
-                'fieldName':'LIST'
+                type: 'field',
+                fieldName: 'LIST'
             }
         ]
     },
-    'list:contains:':{
-        'opcode':'data_listcontainsitem',
-        'argMap':[
+    'list:contains:': {
+        opcode: 'data_listcontainsitem',
+        argMap: [
             {
-                'type':'field',
-                'fieldName':'LIST'
+                type: 'field',
+                fieldName: 'LIST'
             },
             {
-                'type':'input',
-                'inputOp':'text',
-                'inputName':'ITEM'
+                type: 'input',
+                inputOp: 'text',
+                inputName: 'ITEM'
             }
         ]
     },
-    'showList:':{
-        'opcode':'data_showlist',
-        'argMap':[
+    'showList:': {
+        opcode: 'data_showlist',
+        argMap: [
             {
-                'type':'field',
-                'fieldName':'LIST'
+                type: 'field',
+                fieldName: 'LIST'
             }
         ]
     },
-    'hideList:':{
-        'opcode':'data_hidelist',
-        'argMap':[
+    'hideList:': {
+        opcode: 'data_hidelist',
+        argMap: [
             {
-                'type':'field',
-                'fieldName':'LIST'
+                type: 'field',
+                fieldName: 'LIST'
             }
         ]
     },
-    'procDef':{
-        'opcode':'procedures_defnoreturn',
-        'argMap':[]
+    'procDef': {
+        opcode: 'procedures_defnoreturn',
+        argMap: []
     },
-    'getParam':{
-        'opcode':'procedures_param',
-        'argMap':[]
+    'getParam': {
+        opcode: 'procedures_param',
+        argMap: []
     },
-    'call':{
-        'opcode':'procedures_callnoreturn',
-        'argMap':[]
+    'call': {
+        opcode: 'procedures_callnoreturn',
+        argMap: []
     }
 };
 module.exports = specMap;
diff --git a/src/index.js b/src/index.js
index 7ef892b85..1480b1bdf 100644
--- a/src/index.js
+++ b/src/index.js
@@ -11,7 +11,7 @@ var Blocks = require('./engine/blocks');
  *
  * @author Andrew Sliwinski <ascii@media.mit.edu>
  */
-function VirtualMachine () {
+var VirtualMachine = function () {
     var instance = this;
     // Bind event emitter and runtime to VM instance
     EventEmitter.call(instance);
@@ -45,7 +45,7 @@ function VirtualMachine () {
 
     this.blockListener = this.blockListener.bind(this);
     this.flyoutBlockListener = this.flyoutBlockListener.bind(this);
-}
+};
 
 /**
  * Inherit from EventEmitter
@@ -106,12 +106,12 @@ VirtualMachine.prototype.clear = function () {
 VirtualMachine.prototype.getPlaygroundData = function () {
     var instance = this;
     // Only send back thread data for the current editingTarget.
-    var threadData = this.runtime.threads.filter(function(thread) {
-        return thread.target == instance.editingTarget;
+    var threadData = this.runtime.threads.filter(function (thread) {
+        return thread.target === instance.editingTarget;
     });
     // Remove the target key, since it's a circular reference.
-    var filteredThreadData = JSON.stringify(threadData, function(key, value) {
-        if (key == 'target') return undefined;
+    var filteredThreadData = JSON.stringify(threadData, function (key, value) {
+        if (key === 'target') return;
         return value;
     }, 2);
     this.emit('playgroundData', {
@@ -273,7 +273,7 @@ VirtualMachine.prototype.flyoutBlockListener = function (e) {
  */
 VirtualMachine.prototype.setEditingTarget = function (targetId) {
     // Has the target id changed? If not, exit.
-    if (targetId == this.editingTarget.id) {
+    if (targetId === this.editingTarget.id) {
         return;
     }
     var target = this.runtime.getTargetById(targetId);
@@ -297,7 +297,7 @@ VirtualMachine.prototype.emitTargetsUpdate = function () {
         targetList: this.runtime.targets.filter(function (target) {
             // Don't report clones.
             return !target.hasOwnProperty('isOriginal') || target.isOriginal;
-        }).map(function(target) {
+        }).map(function (target) {
             return [target.id, target.getName()];
         }),
         // Currently editing target id.
@@ -311,7 +311,7 @@ VirtualMachine.prototype.emitTargetsUpdate = function () {
  */
 VirtualMachine.prototype.emitWorkspaceUpdate = function () {
     this.emit('workspaceUpdate', {
-        'xml': this.editingTarget.blocks.toXML()
+        xml: this.editingTarget.blocks.toXML()
     });
 };
 
diff --git a/src/io/clock.js b/src/io/clock.js
index ce4c8f553..aaefa9d5a 100644
--- a/src/io/clock.js
+++ b/src/io/clock.js
@@ -1,6 +1,6 @@
 var Timer = require('../util/timer');
 
-function Clock (runtime) {
+var Clock = function (runtime) {
     this._projectTimer = new Timer();
     this._projectTimer.start();
     this._pausedTime = null;
@@ -10,7 +10,7 @@ function Clock (runtime) {
      * @type{!Runtime}
      */
     this.runtime = runtime;
-}
+};
 
 Clock.prototype.projectTimer = function () {
     if (this._paused) {
diff --git a/src/io/keyboard.js b/src/io/keyboard.js
index 86a634374..da0e41625 100644
--- a/src/io/keyboard.js
+++ b/src/io/keyboard.js
@@ -1,6 +1,6 @@
 var Cast = require('../util/cast');
 
-function Keyboard (runtime) {
+var Keyboard = function (runtime) {
     /**
      * List of currently pressed keys.
      * @type{Array.<number>}
@@ -12,7 +12,7 @@ function Keyboard (runtime) {
      * @type{!Runtime}
      */
     this.runtime = runtime;
-}
+};
 
 /**
  * Convert a Scratch key name to a DOM keyCode.
@@ -21,7 +21,7 @@ function Keyboard (runtime) {
  * @private
  */
 Keyboard.prototype._scratchKeyToKeyCode = function (keyName) {
-    if (typeof keyName == 'number') {
+    if (typeof keyName === 'number') {
         // Key codes placed in with number blocks.
         return keyName;
     }
@@ -73,10 +73,10 @@ Keyboard.prototype.postData = function (data) {
             }
             // Always trigger hats, even if it was already pressed.
             this.runtime.startHats('event_whenkeypressed', {
-                'KEY_OPTION': this._keyCodeToScratchKey(data.keyCode)
+                KEY_OPTION: this._keyCodeToScratchKey(data.keyCode)
             });
             this.runtime.startHats('event_whenkeypressed', {
-                'KEY_OPTION': 'any'
+                KEY_OPTION: 'any'
             });
         } else if (index > -1) {
             // If already present, remove from the list.
@@ -91,7 +91,7 @@ Keyboard.prototype.postData = function (data) {
  * @return {boolean} Is the specified key down?
  */
 Keyboard.prototype.getKeyIsDown = function (key) {
-    if (key == 'any') {
+    if (key === 'any') {
         return this._keysPressed.length > 0;
     }
     var keyCode = this._scratchKeyToKeyCode(key);
diff --git a/src/io/mouse.js b/src/io/mouse.js
index 3ca389c06..bcd19087e 100644
--- a/src/io/mouse.js
+++ b/src/io/mouse.js
@@ -1,6 +1,6 @@
 var MathUtil = require('../util/math-util');
 
-function Mouse (runtime) {
+var Mouse = function (runtime) {
     this._x = 0;
     this._y = 0;
     this._isDown = false;
@@ -10,7 +10,7 @@ function Mouse (runtime) {
      * @type{!Runtime}
      */
     this.runtime = runtime;
-}
+};
 
 /**
  * Activate "event_whenthisspriteclicked" hats if needed.
@@ -24,7 +24,7 @@ Mouse.prototype._activateClickHats = function (x, y) {
         for (var i = 0; i < this.runtime.targets.length; i++) {
             var target = this.runtime.targets[i];
             if (target.hasOwnProperty('drawableID') &&
-                target.drawableID == drawableID) {
+                target.drawableID === drawableID) {
                 this.runtime.startHats('event_whenthisspriteclicked',
                     null, target);
                 return;
@@ -37,7 +37,7 @@ Mouse.prototype._activateClickHats = function (x, y) {
  * Mouse DOM event handler.
  * @param  {object} data Data from DOM event.
  */
-Mouse.prototype.postData = function(data) {
+Mouse.prototype.postData = function (data) {
     if (data.x) {
         this._x = data.x - data.canvasWidth / 2;
     }
diff --git a/src/sprites/clone.js b/src/sprites/clone.js
index bef0fb1a5..c5567cd03 100644
--- a/src/sprites/clone.js
+++ b/src/sprites/clone.js
@@ -1,4 +1,6 @@
 var util = require('util');
+
+var log = require('../util/log');
 var MathUtil = require('../util/math-util');
 var Target = require('../engine/target');
 
@@ -8,7 +10,7 @@ var Target = require('../engine/target');
  * @param {Runtime} runtime Reference to the runtime.
  * @constructor
  */
-function Clone(sprite, runtime) {
+var Clone = function (sprite, runtime) {
     Target.call(this, sprite.blocks);
     this.runtime = runtime;
     /**
@@ -35,15 +37,15 @@ function Clone(sprite, runtime) {
      * @type {!Object.<string, number>}
      */
     this.effects = {
-        'color': 0,
-        'fisheye': 0,
-        'whirl': 0,
-        'pixelate': 0,
-        'mosaic': 0,
-        'brightness': 0,
-        'ghost': 0
+        color: 0,
+        fisheye: 0,
+        whirl: 0,
+        pixelate: 0,
+        mosaic: 0,
+        brightness: 0,
+        ghost: 0
     };
-}
+};
 util.inherits(Clone, Target);
 
 /**
@@ -166,7 +168,7 @@ Clone.prototype._getRenderedDirectionAndScale = function () {
     // Default: no changes to `this.direction` or `this.scale`.
     var finalDirection = this.direction;
     var finalScale = [this.size, this.size];
-    if (this.rotationStyle == Clone.ROTATION_STYLE_NONE) {
+    if (this.rotationStyle === Clone.ROTATION_STYLE_NONE) {
         // Force rendered direction to be 90.
         finalDirection = 90;
     } else if (this.rotationStyle === Clone.ROTATION_STYLE_LEFT_RIGHT) {
@@ -211,10 +213,10 @@ Clone.prototype.setSay = function (type, message) {
     }
     // @todo: Render to stage.
     if (!type || !message) {
-        console.log('Clearing say bubble');
+        log.info('Clearing say bubble');
         return;
     }
-    console.log('Setting say bubble:', type, message);
+    log.info('Setting say bubble:', type, message);
 };
 
 /**
@@ -319,11 +321,11 @@ Clone.prototype.setCostume = function (index) {
  * @param {!string} rotationStyle New rotation style.
  */
 Clone.prototype.setRotationStyle = function (rotationStyle) {
-    if (rotationStyle == Clone.ROTATION_STYLE_NONE) {
+    if (rotationStyle === Clone.ROTATION_STYLE_NONE) {
         this.rotationStyle = Clone.ROTATION_STYLE_NONE;
-    } else if (rotationStyle == Clone.ROTATION_STYLE_ALL_AROUND) {
+    } else if (rotationStyle === Clone.ROTATION_STYLE_ALL_AROUND) {
         this.rotationStyle = Clone.ROTATION_STYLE_ALL_AROUND;
-    } else if (rotationStyle == Clone.ROTATION_STYLE_LEFT_RIGHT) {
+    } else if (rotationStyle === Clone.ROTATION_STYLE_LEFT_RIGHT) {
         this.rotationStyle = Clone.ROTATION_STYLE_LEFT_RIGHT;
     }
     if (this.renderer) {
@@ -345,7 +347,7 @@ Clone.prototype.setRotationStyle = function (rotationStyle) {
  */
 Clone.prototype.getCostumeIndexByName = function (costumeName) {
     for (var i = 0; i < this.sprite.costumes.length; i++) {
-        if (this.sprite.costumes[i].name == costumeName) {
+        if (this.sprite.costumes[i].name === costumeName) {
             return i;
         }
     }
@@ -408,8 +410,8 @@ Clone.prototype.isTouchingPoint = function (x, y) {
         // Limits test to this Drawable, so this will return true
         // even if the clone is obscured by another Drawable.
         var pickResult = this.runtime.renderer.pick(
-            x + this.runtime.constructor.STAGE_WIDTH / 2,
-            -y + this.runtime.constructor.STAGE_HEIGHT / 2,
+            x + (this.runtime.constructor.STAGE_WIDTH / 2),
+            -y + (this.runtime.constructor.STAGE_HEIGHT / 2),
             null, null,
             [this.drawableID]
         );
@@ -447,7 +449,7 @@ Clone.prototype.isTouchingSprite = function (spriteName) {
     if (!firstClone || !this.renderer) {
         return false;
     }
-    var drawableCandidates = firstClone.sprite.clones.map(function(clone) {
+    var drawableCandidates = firstClone.sprite.clones.map(function (clone) {
         return clone.drawableID;
     });
     return this.renderer.isTouchingDrawables(
@@ -506,11 +508,11 @@ Clone.prototype.goBackLayers = function (nLayers) {
  * Keep a desired position within a fence.
  * @param {number} newX New desired X position.
  * @param {number} newY New desired Y position.
- * @param {Object=} opt_fence Optional fence with left, right, top bottom.
+ * @param {Object=} optFence Optional fence with left, right, top bottom.
  * @return {Array.<number>} Fenced X and Y coordinates.
  */
-Clone.prototype.keepInFence = function (newX, newY, opt_fence) {
-    var fence = opt_fence;
+Clone.prototype.keepInFence = function (newX, newY, optFence) {
+    var fence = optFence;
     if (!fence) {
         fence = {
             left: -this.runtime.constructor.STAGE_WIDTH / 2,
diff --git a/src/sprites/sprite.js b/src/sprites/sprite.js
index 2afb25e5e..351d40a3f 100644
--- a/src/sprites/sprite.js
+++ b/src/sprites/sprite.js
@@ -8,7 +8,7 @@ var Blocks = require('../engine/blocks');
  * @param {Runtime} runtime Reference to the runtime.
  * @constructor
  */
-function Sprite (blocks, runtime) {
+var Sprite = function (blocks, runtime) {
     this.runtime = runtime;
     if (!blocks) {
         // Shared set of blocks for all clones.
@@ -38,7 +38,7 @@ function Sprite (blocks, runtime) {
      * @type {Array.<!Clone>}
      */
     this.clones = [];
-}
+};
 
 /**
  * Create a clone of this sprite.
@@ -46,7 +46,7 @@ function Sprite (blocks, runtime) {
  */
 Sprite.prototype.createClone = function () {
     var newClone = new Clone(this, this.runtime);
-    newClone.isOriginal = this.clones.length == 0;
+    newClone.isOriginal = this.clones.length === 0;
     this.clones.push(newClone);
     if (newClone.isOriginal) {
         newClone.initDrawable();
diff --git a/src/util/cast.js b/src/util/cast.js
index dda55bf8e..f14e97df5 100644
--- a/src/util/cast.js
+++ b/src/util/cast.js
@@ -1,6 +1,6 @@
 var Color = require('../util/color');
 
-function Cast () {}
+var Cast = function () {};
 
 /**
  * @fileoverview
@@ -44,9 +44,9 @@ Cast.toBoolean = function (value) {
     }
     if (typeof value === 'string') {
         // These specific strings are treated as false in Scratch.
-        if ((value == '') ||
-            (value == '0') ||
-            (value.toLowerCase() == 'false')) {
+        if ((value === '') ||
+            (value === '0') ||
+            (value.toLowerCase() === 'false')) {
             return false;
         }
         // All other strings treated as true.
@@ -72,7 +72,7 @@ Cast.toString = function (value) {
  */
 Cast.toRgbColorList = function (value) {
     var color;
-    if (typeof value == 'string' && value.substring(0, 1) == '#') {
+    if (typeof value === 'string' && value.substring(0, 1) === '#') {
         color = Color.hexToRgb(value);
     } else {
         color = Color.decimalToRgb(Cast.toNumber(value));
@@ -114,7 +114,7 @@ Cast.isInt = function (val) {
             return true;
         }
         // True if it's "round" (e.g., 2.0 and 2).
-        return val == parseInt(val);
+        return val === parseInt(val, 10);
     } else if (typeof val === 'boolean') {
         // `True` and `false` always represent integer after Scratch cast.
         return true;
@@ -138,15 +138,15 @@ Cast.LIST_ALL = 'ALL';
  */
 Cast.toListIndex = function (index, length) {
     if (typeof index !== 'number') {
-        if (index == 'all') {
+        if (index === 'all') {
             return Cast.LIST_ALL;
         }
-        if (index == 'last') {
+        if (index === 'last') {
             if (length > 0) {
                 return length;
             }
             return Cast.LIST_INVALID;
-        } else if (index == 'random' || index == 'any') {
+        } else if (index === 'random' || index === 'any') {
             if (length > 0) {
                 return 1 + Math.floor(Math.random() * length);
             }
diff --git a/src/util/color.js b/src/util/color.js
index 2635c1b6c..3e5054652 100644
--- a/src/util/color.js
+++ b/src/util/color.js
@@ -1,4 +1,4 @@
-function Color () {}
+var Color = function () {};
 
 /**
  * Convert a Scratch decimal color to a hex string, #RRGGBB.
@@ -35,7 +35,7 @@ Color.decimalToRgb = function (decimal) {
  */
 Color.hexToRgb = function (hex) {
     var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
-    hex = hex.replace(shorthandRegex, function(m, r, g, b) {
+    hex = hex.replace(shorthandRegex, function (m, r, g, b) {
         return r + r + g + g + b + b;
     });
     var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
diff --git a/src/util/log.js b/src/util/log.js
new file mode 100644
index 000000000..28e596a12
--- /dev/null
+++ b/src/util/log.js
@@ -0,0 +1,4 @@
+var minilog = require('minilog');
+minilog.enable();
+
+module.exports = minilog('vm');
diff --git a/src/util/math-util.js b/src/util/math-util.js
index 14ebb450e..c27e730bb 100644
--- a/src/util/math-util.js
+++ b/src/util/math-util.js
@@ -1,4 +1,4 @@
-function MathUtil () {}
+var MathUtil = function () {};
 
 /**
  * Convert a value from degrees to radians.
@@ -42,7 +42,7 @@ MathUtil.clamp = function (n, min, max) {
  */
 MathUtil.wrapClamp = function (n, min, max) {
     var range = (max - min) + 1;
-    return n - Math.floor((n - min) / range) * range;
+    return n - (Math.floor((n - min) / range) * range);
 };
 
 module.exports = MathUtil;
diff --git a/src/util/timer.js b/src/util/timer.js
index 48dd223d5..17c66a567 100644
--- a/src/util/timer.js
+++ b/src/util/timer.js
@@ -15,7 +15,7 @@
 /**
  * @constructor
  */
-function Timer () {}
+var Timer = function () {};
 
 /**
  * Used to store the start time of a timer action.
diff --git a/test/.eslintrc.js b/test/.eslintrc.js
new file mode 100644
index 000000000..666194097
--- /dev/null
+++ b/test/.eslintrc.js
@@ -0,0 +1,5 @@
+module.exports = {
+    rules: {
+        'no-undefined': [0]
+    }
+};
diff --git a/test/unit/blocks_operators.js b/test/unit/blocks_operators.js
index f7befa063..b88ff0f77 100644
--- a/test/unit/blocks_operators.js
+++ b/test/unit/blocks_operators.js
@@ -9,75 +9,75 @@ test('getPrimitives', function (t) {
 });
 
 test('add', function (t) {
-    t.strictEqual(blocks.add({NUM1:'1', NUM2:'1'}), 2);
-    t.strictEqual(blocks.add({NUM1:'foo', NUM2:'bar'}), 0);
+    t.strictEqual(blocks.add({NUM1: '1', NUM2: '1'}), 2);
+    t.strictEqual(blocks.add({NUM1: 'foo', NUM2: 'bar'}), 0);
     t.end();
 });
 
 test('subtract', function (t) {
-    t.strictEqual(blocks.subtract({NUM1:'1', NUM2:'1'}), 0);
-    t.strictEqual(blocks.subtract({NUM1:'foo', NUM2:'bar'}), 0);
+    t.strictEqual(blocks.subtract({NUM1: '1', NUM2: '1'}), 0);
+    t.strictEqual(blocks.subtract({NUM1: 'foo', NUM2: 'bar'}), 0);
     t.end();
 });
 
 test('multiply', function (t) {
-    t.strictEqual(blocks.multiply({NUM1:'2', NUM2:'2'}), 4);
-    t.strictEqual(blocks.multiply({NUM1:'foo', NUM2:'bar'}), 0);
+    t.strictEqual(blocks.multiply({NUM1: '2', NUM2: '2'}), 4);
+    t.strictEqual(blocks.multiply({NUM1: 'foo', NUM2: 'bar'}), 0);
     t.end();
 });
 
 test('divide', function (t) {
-    t.strictEqual(blocks.divide({NUM1:'2', NUM2:'2'}), 1);
-    t.strictEqual(blocks.divide({NUM1:'1', NUM2:'0'}), Infinity);   // @todo
-    t.ok(isNaN(blocks.divide({NUM1:'foo', NUM2:'bar'})));           // @todo
+    t.strictEqual(blocks.divide({NUM1: '2', NUM2: '2'}), 1);
+    t.strictEqual(blocks.divide({NUM1: '1', NUM2: '0'}), Infinity);   // @todo
+    t.ok(isNaN(blocks.divide({NUM1: 'foo', NUM2: 'bar'})));           // @todo
     t.end();
 });
 
 test('lt', function (t) {
-    t.strictEqual(blocks.lt({OPERAND1:'1', OPERAND2:'2'}), true);
-    t.strictEqual(blocks.lt({OPERAND1:'2', OPERAND2:'1'}), false);
-    t.strictEqual(blocks.lt({OPERAND1:'1', OPERAND2:'1'}), false);
+    t.strictEqual(blocks.lt({OPERAND1: '1', OPERAND2: '2'}), true);
+    t.strictEqual(blocks.lt({OPERAND1: '2', OPERAND2: '1'}), false);
+    t.strictEqual(blocks.lt({OPERAND1: '1', OPERAND2: '1'}), false);
     t.end();
 });
 
 test('equals', function (t) {
-    t.strictEqual(blocks.equals({OPERAND1:'1', OPERAND2:'2'}), false);
-    t.strictEqual(blocks.equals({OPERAND1:'2', OPERAND2:'1'}), false);
-    t.strictEqual(blocks.equals({OPERAND1:'1', OPERAND2:'1'}), true);
+    t.strictEqual(blocks.equals({OPERAND1: '1', OPERAND2: '2'}), false);
+    t.strictEqual(blocks.equals({OPERAND1: '2', OPERAND2: '1'}), false);
+    t.strictEqual(blocks.equals({OPERAND1: '1', OPERAND2: '1'}), true);
     t.end();
 });
 
 test('gt', function (t) {
-    t.strictEqual(blocks.gt({OPERAND1:'1', OPERAND2:'2'}), false);
-    t.strictEqual(blocks.gt({OPERAND1:'2', OPERAND2:'1'}), true);
-    t.strictEqual(blocks.gt({OPERAND1:'1', OPERAND2:'1'}), false);
+    t.strictEqual(blocks.gt({OPERAND1: '1', OPERAND2: '2'}), false);
+    t.strictEqual(blocks.gt({OPERAND1: '2', OPERAND2: '1'}), true);
+    t.strictEqual(blocks.gt({OPERAND1: '1', OPERAND2: '1'}), false);
     t.end();
 });
 
 test('and', function (t) {
-    t.strictEqual(blocks.and({OPERAND1:true, OPERAND2:true}), true);
-    t.strictEqual(blocks.and({OPERAND1:true, OPERAND2:false}), false);
-    t.strictEqual(blocks.and({OPERAND1:false, OPERAND2:false}), false);
+    t.strictEqual(blocks.and({OPERAND1: true, OPERAND2: true}), true);
+    t.strictEqual(blocks.and({OPERAND1: true, OPERAND2: false}), false);
+    t.strictEqual(blocks.and({OPERAND1: false, OPERAND2: false}), false);
     t.end();
 });
 
 test('or', function (t) {
-    t.strictEqual(blocks.or({OPERAND1:true, OPERAND2:true}), true);
-    t.strictEqual(blocks.or({OPERAND1:true, OPERAND2:false}), true);
-    t.strictEqual(blocks.or({OPERAND1:false, OPERAND2:false}), false);
+    t.strictEqual(blocks.or({OPERAND1: true, OPERAND2: true}), true);
+    t.strictEqual(blocks.or({OPERAND1: true, OPERAND2: false}), true);
+    t.strictEqual(blocks.or({OPERAND1: false, OPERAND2: false}), false);
     t.end();
 });
 
 test('not', function (t) {
-    t.strictEqual(blocks.not({OPERAND:true}), false);
-    t.strictEqual(blocks.not({OPERAND:false}), true);
+    t.strictEqual(blocks.not({OPERAND: true}), false);
+    t.strictEqual(blocks.not({OPERAND: false}), true);
     t.end();
 });
 
 test('random', function (t) {
     var min = 0;
     var max = 100;
-    var result = blocks.random({FROM:min, TO:max});
+    var result = blocks.random({FROM: min, TO: max});
     t.ok(result >= min);
     t.ok(result <= max);
     t.end();
@@ -86,14 +86,14 @@ test('random', function (t) {
 test('random - equal', function (t) {
     var min = 1;
     var max = 1;
-    t.strictEqual(blocks.random({FROM:min, TO:max}), min);
+    t.strictEqual(blocks.random({FROM: min, TO: max}), min);
     t.end();
 });
 
 test('random - decimal', function (t) {
     var min = 0.1;
     var max = 10;
-    var result = blocks.random({FROM:min, TO:max});
+    var result = blocks.random({FROM: min, TO: max});
     t.ok(result >= min);
     t.ok(result <= max);
     t.end();
@@ -102,7 +102,7 @@ test('random - decimal', function (t) {
 test('random - int', function (t) {
     var min = 0;
     var max = 10;
-    var result = blocks.random({FROM:min, TO:max});
+    var result = blocks.random({FROM: min, TO: max});
     t.ok(result >= min);
     t.ok(result <= max);
     t.end();
@@ -111,65 +111,65 @@ test('random - int', function (t) {
 test('random - reverse', function (t) {
     var min = 0;
     var max = 10;
-    var result = blocks.random({FROM:max, TO:min});
+    var result = blocks.random({FROM: max, TO: min});
     t.ok(result >= min);
     t.ok(result <= max);
     t.end();
 });
 
 test('join', function (t) {
-    t.strictEqual(blocks.join({STRING1:'foo', STRING2:'bar'}), 'foobar');
-    t.strictEqual(blocks.join({STRING1:'1', STRING2:'2'}), '12');
+    t.strictEqual(blocks.join({STRING1: 'foo', STRING2: 'bar'}), 'foobar');
+    t.strictEqual(blocks.join({STRING1: '1', STRING2: '2'}), '12');
     t.end();
 });
 
 test('letterOf', function (t) {
-    t.strictEqual(blocks.letterOf({STRING:'foo', LETTER:0}), '');
-    t.strictEqual(blocks.letterOf({STRING:'foo', LETTER:1}), 'f');
-    t.strictEqual(blocks.letterOf({STRING:'foo', LETTER:2}), 'o');
-    t.strictEqual(blocks.letterOf({STRING:'foo', LETTER:3}), 'o');
-    t.strictEqual(blocks.letterOf({STRING:'foo', LETTER:4}), '');
-    t.strictEqual(blocks.letterOf({STRING:'foo', LETTER:'bar'}), '');
+    t.strictEqual(blocks.letterOf({STRING: 'foo', LETTER: 0}), '');
+    t.strictEqual(blocks.letterOf({STRING: 'foo', LETTER: 1}), 'f');
+    t.strictEqual(blocks.letterOf({STRING: 'foo', LETTER: 2}), 'o');
+    t.strictEqual(blocks.letterOf({STRING: 'foo', LETTER: 3}), 'o');
+    t.strictEqual(blocks.letterOf({STRING: 'foo', LETTER: 4}), '');
+    t.strictEqual(blocks.letterOf({STRING: 'foo', LETTER: 'bar'}), '');
     t.end();
 });
 
 test('length', function (t) {
-    t.strictEqual(blocks.length({STRING:''}), 0);
-    t.strictEqual(blocks.length({STRING:'foo'}), 3);
-    t.strictEqual(blocks.length({STRING:'1'}), 1);
-    t.strictEqual(blocks.length({STRING:'100'}), 3);
+    t.strictEqual(blocks.length({STRING: ''}), 0);
+    t.strictEqual(blocks.length({STRING: 'foo'}), 3);
+    t.strictEqual(blocks.length({STRING: '1'}), 1);
+    t.strictEqual(blocks.length({STRING: '100'}), 3);
     t.end();
 });
 
 test('mod', function (t) {
-    t.strictEqual(blocks.mod({NUM1:1, NUM2:1}), 0);
-    t.strictEqual(blocks.mod({NUM1:3, NUM2:6}), 3);
-    t.strictEqual(blocks.mod({NUM1:-3, NUM2:6}), 3);
+    t.strictEqual(blocks.mod({NUM1: 1, NUM2: 1}), 0);
+    t.strictEqual(blocks.mod({NUM1: 3, NUM2: 6}), 3);
+    t.strictEqual(blocks.mod({NUM1: -3, NUM2: 6}), 3);
     t.end();
 });
 
 test('round', function (t) {
-    t.strictEqual(blocks.round({NUM:1}), 1);
-    t.strictEqual(blocks.round({NUM:1.1}), 1);
-    t.strictEqual(blocks.round({NUM:1.5}), 2);
+    t.strictEqual(blocks.round({NUM: 1}), 1);
+    t.strictEqual(blocks.round({NUM: 1.1}), 1);
+    t.strictEqual(blocks.round({NUM: 1.5}), 2);
     t.end();
 });
 
 test('mathop', function (t) {
-    t.strictEqual(blocks.mathop({OPERATOR:'abs', NUM:-1}), 1);
-    t.strictEqual(blocks.mathop({OPERATOR:'floor', NUM:1.5}), 1);
-    t.strictEqual(blocks.mathop({OPERATOR:'ceiling', NUM:0.1}), 1);
-    t.strictEqual(blocks.mathop({OPERATOR:'sqrt', NUM:1}), 1);
-    t.strictEqual(blocks.mathop({OPERATOR:'sin', NUM:1}), 0.01745240643728351);
-    t.strictEqual(blocks.mathop({OPERATOR:'cos', NUM:1}), 0.9998476951563913);
-    t.strictEqual(blocks.mathop({OPERATOR:'tan', NUM:1}), 0.017455064928217585);
-    t.strictEqual(blocks.mathop({OPERATOR:'asin', NUM:1}), 90);
-    t.strictEqual(blocks.mathop({OPERATOR:'acos', NUM:1}), 0);
-    t.strictEqual(blocks.mathop({OPERATOR:'atan', NUM:1}), 45);
-    t.strictEqual(blocks.mathop({OPERATOR:'ln', NUM:1}), 0);
-    t.strictEqual(blocks.mathop({OPERATOR:'log', NUM:1}), 0);
-    t.strictEqual(blocks.mathop({OPERATOR:'e ^', NUM:1}), 2.718281828459045);
-    t.strictEqual(blocks.mathop({OPERATOR:'10 ^', NUM:1}), 10);
-    t.strictEqual(blocks.mathop({OPERATOR:'undefined', NUM:1}), 0);
+    t.strictEqual(blocks.mathop({OPERATOR: 'abs', NUM: -1}), 1);
+    t.strictEqual(blocks.mathop({OPERATOR: 'floor', NUM: 1.5}), 1);
+    t.strictEqual(blocks.mathop({OPERATOR: 'ceiling', NUM: 0.1}), 1);
+    t.strictEqual(blocks.mathop({OPERATOR: 'sqrt', NUM: 1}), 1);
+    t.strictEqual(blocks.mathop({OPERATOR: 'sin', NUM: 1}), 0.01745240643728351);
+    t.strictEqual(blocks.mathop({OPERATOR: 'cos', NUM: 1}), 0.9998476951563913);
+    t.strictEqual(blocks.mathop({OPERATOR: 'tan', NUM: 1}), 0.017455064928217585);
+    t.strictEqual(blocks.mathop({OPERATOR: 'asin', NUM: 1}), 90);
+    t.strictEqual(blocks.mathop({OPERATOR: 'acos', NUM: 1}), 0);
+    t.strictEqual(blocks.mathop({OPERATOR: 'atan', NUM: 1}), 45);
+    t.strictEqual(blocks.mathop({OPERATOR: 'ln', NUM: 1}), 0);
+    t.strictEqual(blocks.mathop({OPERATOR: 'log', NUM: 1}), 0);
+    t.strictEqual(blocks.mathop({OPERATOR: 'e ^', NUM: 1}), 2.718281828459045);
+    t.strictEqual(blocks.mathop({OPERATOR: '10 ^', NUM: 1}), 10);
+    t.strictEqual(blocks.mathop({OPERATOR: 'undefined', NUM: 1}), 0);
     t.end();
 });
diff --git a/test/unit/engine_adapter.js b/test/unit/engine_adapter.js
index 19289dacd..7c6cd2da1 100644
--- a/test/unit/engine_adapter.js
+++ b/test/unit/engine_adapter.js
@@ -7,10 +7,10 @@ test('spec', function (t) {
     t.end();
 });
 
-test('invalid inputs', function(t) {
+test('invalid inputs', function (t) {
     var nothing = adapter('not an object');
     t.type(nothing, 'undefined');
-    nothing = adapter({noxmlproperty:true});
+    nothing = adapter({noxmlproperty: true});
     t.type(nothing, 'undefined');
     t.end();
 });
@@ -26,7 +26,7 @@ test('create event', function (t) {
     t.type(result[0].opcode, 'string');
     t.type(result[0].fields, 'object');
     t.type(result[0].inputs, 'object');
-    t.type(result[0].inputs['DURATION'], 'object');
+    t.type(result[0].inputs.DURATION, 'object');
     t.type(result[0].topLevel, 'boolean');
     t.equal(result[0].topLevel, true);
 
@@ -35,8 +35,8 @@ test('create event', function (t) {
     t.type(result[1].opcode, 'string');
     t.type(result[1].fields, 'object');
     t.type(result[1].inputs, 'object');
-    t.type(result[1].fields['NUM'], 'object');
-    t.type(result[1].fields['NUM'].value, '10');
+    t.type(result[1].fields.NUM, 'object');
+    t.type(result[1].fields.NUM.value, '10');
     t.type(result[1].topLevel, 'boolean');
     t.equal(result[1].topLevel, false);
 
@@ -50,18 +50,18 @@ test('create with branch', function (t) {
     t.type(result[0].opcode, 'string');
     t.type(result[0].fields, 'object');
     t.type(result[0].inputs, 'object');
-    t.type(result[0].inputs['SUBSTACK'], 'object');
+    t.type(result[0].inputs.SUBSTACK, 'object');
     t.type(result[0].topLevel, 'boolean');
     t.equal(result[0].topLevel, true);
     // In branch
-    var branchBlockId = result[0].inputs['SUBSTACK']['block'];
-    var branchShadowId = result[0].inputs['SUBSTACK']['shadow'];
+    var branchBlockId = result[0].inputs.SUBSTACK.block;
+    var branchShadowId = result[0].inputs.SUBSTACK.shadow;
     t.type(branchBlockId, 'string');
     t.equal(branchShadowId, null);
     // Find actual branch block
     var branchBlock = null;
     for (var i = 0; i < result.length; i++) {
-        if (result[i].id == branchBlockId) {
+        if (result[i].id === branchBlockId) {
             branchBlock = result[i];
         }
     }
@@ -76,27 +76,27 @@ test('create with two branches', function (t) {
     t.type(result[0].opcode, 'string');
     t.type(result[0].fields, 'object');
     t.type(result[0].inputs, 'object');
-    t.type(result[0].inputs['SUBSTACK'], 'object');
-    t.type(result[0].inputs['SUBSTACK2'], 'object');
+    t.type(result[0].inputs.SUBSTACK, 'object');
+    t.type(result[0].inputs.SUBSTACK2, 'object');
     t.type(result[0].topLevel, 'boolean');
     t.equal(result[0].topLevel, true);
     // In branchs
-    var firstBranchBlockId = result[0].inputs['SUBSTACK']['block'];
-    var secondBranchBlockId = result[0].inputs['SUBSTACK2']['block'];
+    var firstBranchBlockId = result[0].inputs.SUBSTACK.block;
+    var secondBranchBlockId = result[0].inputs.SUBSTACK2.block;
     t.type(firstBranchBlockId, 'string');
     t.type(secondBranchBlockId, 'string');
-    var firstBranchShadowBlockId = result[0].inputs['SUBSTACK']['shadow'];
-    var secondBranchShadowBlockId = result[0].inputs['SUBSTACK2']['shadow'];
+    var firstBranchShadowBlockId = result[0].inputs.SUBSTACK.shadow;
+    var secondBranchShadowBlockId = result[0].inputs.SUBSTACK2.shadow;
     t.equal(firstBranchShadowBlockId, null);
     t.equal(secondBranchShadowBlockId, null);
     // Find actual branch blocks
     var firstBranchBlock = null;
     var secondBranchBlock = null;
     for (var i = 0; i < result.length; i++) {
-        if (result[i].id == firstBranchBlockId) {
+        if (result[i].id === firstBranchBlockId) {
             firstBranchBlock = result[i];
         }
-        if (result[i].id == secondBranchBlockId) {
+        if (result[i].id === secondBranchBlockId) {
             secondBranchBlock = result[i];
         }
     }
diff --git a/test/unit/engine_blocks.js b/test/unit/engine_blocks.js
index 2c9f8f13e..9cb3ffd4b 100644
--- a/test/unit/engine_blocks.js
+++ b/test/unit/engine_blocks.js
@@ -245,8 +245,8 @@ test('create', function (t) {
         topLevel: true
     });
 
-    t.type(b._blocks['foo'], 'object');
-    t.equal(b._blocks['foo'].opcode, 'TEST_BLOCK');
+    t.type(b._blocks.foo, 'object');
+    t.equal(b._blocks.foo.opcode, 'TEST_BLOCK');
     t.notEqual(b._scripts.indexOf('foo'), -1);
     t.end();
 });
@@ -277,7 +277,7 @@ test('move', function (t) {
     });
     t.equal(b._scripts.length, 1);
     t.equal(Object.keys(b._blocks).length, 2);
-    t.equal(b._blocks['foo'].next, 'bar');
+    t.equal(b._blocks.foo.next, 'bar');
 
     // Detach 'bar' from 'foo'
     b.moveBlock({
@@ -286,7 +286,7 @@ test('move', function (t) {
     });
     t.equal(b._scripts.length, 2);
     t.equal(Object.keys(b._blocks).length, 2);
-    t.equal(b._blocks['foo'].next, null);
+    t.equal(b._blocks.foo.next, null);
 
     t.end();
 });
@@ -314,7 +314,7 @@ test('move into empty', function (t) {
         newInput: 'fooInput',
         newParent: 'foo'
     });
-    t.equal(b._blocks['foo'].inputs['fooInput'].block, 'bar');
+    t.equal(b._blocks.foo.inputs.fooInput.block, 'bar');
     t.end();
 });
 
@@ -326,7 +326,7 @@ test('move no obscure shadow', function (t) {
         next: null,
         fields: {},
         inputs: {
-            'fooInput': {
+            fooInput: {
                 name: 'fooInput',
                 block: 'x',
                 shadow: 'y'
@@ -347,8 +347,8 @@ test('move no obscure shadow', function (t) {
         newInput: 'fooInput',
         newParent: 'foo'
     });
-    t.equal(b._blocks['foo'].inputs['fooInput'].block, 'bar');
-    t.equal(b._blocks['foo'].inputs['fooInput'].shadow, 'y');
+    t.equal(b._blocks.foo.inputs.fooInput.block, 'bar');
+    t.equal(b._blocks.foo.inputs.fooInput.shadow, 'y');
     t.end();
 });
 
@@ -369,7 +369,7 @@ test('change', function (t) {
     });
 
     // Test that the field is updated
-    t.equal(b._blocks['foo'].fields.someField.value, 'initial-value');
+    t.equal(b._blocks.foo.fields.someField.value, 'initial-value');
 
     b.changeBlock({
         element: 'field',
@@ -378,7 +378,7 @@ test('change', function (t) {
         value: 'final-value'
     });
 
-    t.equal(b._blocks['foo'].fields.someField.value, 'final-value');
+    t.equal(b._blocks.foo.fields.someField.value, 'final-value');
 
     // Invalid cases
     // No `element`
@@ -387,7 +387,7 @@ test('change', function (t) {
         name: 'someField',
         value: 'invalid-value'
     });
-    t.equal(b._blocks['foo'].fields.someField.value, 'final-value');
+    t.equal(b._blocks.foo.fields.someField.value, 'final-value');
 
     // No block ID
     b.changeBlock({
@@ -395,7 +395,7 @@ test('change', function (t) {
         name: 'someField',
         value: 'invalid-value'
     });
-    t.equal(b._blocks['foo'].fields.someField.value, 'final-value');
+    t.equal(b._blocks.foo.fields.someField.value, 'final-value');
 
     // No such field
     b.changeBlock({
@@ -404,7 +404,7 @@ test('change', function (t) {
         name: 'someWrongField',
         value: 'final-value'
     });
-    t.equal(b._blocks['foo'].fields.someField.value, 'final-value');
+    t.equal(b._blocks.foo.fields.someField.value, 'final-value');
 
     t.end();
 });
@@ -423,7 +423,7 @@ test('delete', function (t) {
         id: 'foo'
     });
 
-    t.type(b._blocks['foo'], 'undefined');
+    t.type(b._blocks.foo, 'undefined');
     t.equal(b._scripts.indexOf('foo'), -1);
     t.end();
 });
@@ -459,9 +459,9 @@ test('delete chain', function (t) {
     b.deleteBlock({
         id: 'foo'
     });
-    t.type(b._blocks['foo'], 'undefined');
-    t.type(b._blocks['foo2'], 'undefined');
-    t.type(b._blocks['foo3'], 'undefined');
+    t.type(b._blocks.foo, 'undefined');
+    t.type(b._blocks.foo2, 'undefined');
+    t.type(b._blocks.foo3, 'undefined');
     t.equal(b._scripts.indexOf('foo'), -1);
     t.equal(Object.keys(b._blocks).length, 0);
     t.equal(b._scripts.length, 0);
@@ -532,11 +532,11 @@ test('delete inputs', function (t) {
     b.deleteBlock({
         id: 'foo'
     });
-    t.type(b._blocks['foo'], 'undefined');
-    t.type(b._blocks['foo2'], 'undefined');
-    t.type(b._blocks['foo3'], 'undefined');
-    t.type(b._blocks['foo4'], 'undefined');
-    t.type(b._blocks['foo5'], 'undefined');
+    t.type(b._blocks.foo, 'undefined');
+    t.type(b._blocks.foo2, 'undefined');
+    t.type(b._blocks.foo3, 'undefined');
+    t.type(b._blocks.foo4, 'undefined');
+    t.type(b._blocks.foo5, 'undefined');
     t.equal(b._scripts.indexOf('foo'), -1);
     t.equal(Object.keys(b._blocks).length, 0);
     t.equal(b._scripts.length, 0);
diff --git a/test/unit/util_cast.js b/test/unit/util_cast.js
index 1d372213e..147ba2575 100644
--- a/test/unit/util_cast.js
+++ b/test/unit/util_cast.js
@@ -75,19 +75,19 @@ test('toString', function (t) {
 
 test('toRbgColorList', function (t) {
     // Hex (minimal, see "color" util tests)
-    t.deepEqual(cast.toRgbColorList('#000'), [0,0,0]);
-    t.deepEqual(cast.toRgbColorList('#000000'), [0,0,0]);
-    t.deepEqual(cast.toRgbColorList('#fff'), [255,255,255]);
-    t.deepEqual(cast.toRgbColorList('#ffffff'), [255,255,255]);
+    t.deepEqual(cast.toRgbColorList('#000'), [0, 0, 0]);
+    t.deepEqual(cast.toRgbColorList('#000000'), [0, 0, 0]);
+    t.deepEqual(cast.toRgbColorList('#fff'), [255, 255, 255]);
+    t.deepEqual(cast.toRgbColorList('#ffffff'), [255, 255, 255]);
 
     // Decimal (minimal, see "color" util tests)
-    t.deepEqual(cast.toRgbColorList(0), [0,0,0]);
-    t.deepEqual(cast.toRgbColorList(1), [0,0,1]);
-    t.deepEqual(cast.toRgbColorList(16777215), [255,255,255]);
+    t.deepEqual(cast.toRgbColorList(0), [0, 0, 0]);
+    t.deepEqual(cast.toRgbColorList(1), [0, 0, 1]);
+    t.deepEqual(cast.toRgbColorList(16777215), [255, 255, 255]);
 
     // Malformed
-    t.deepEqual(cast.toRgbColorList('ffffff'), [0,0,0]);
-    t.deepEqual(cast.toRgbColorList('foobar'), [0,0,0]);
+    t.deepEqual(cast.toRgbColorList('ffffff'), [0, 0, 0]);
+    t.deepEqual(cast.toRgbColorList('foobar'), [0, 0, 0]);
     t.end();
 });
 
@@ -144,7 +144,7 @@ test('isInt', function (t) {
 });
 
 test('toListIndex', function (t) {
-    var list = [0,1,2,3,4,5];
+    var list = [0, 1, 2, 3, 4, 5];
     var empty = [];
 
     // Valid
diff --git a/test/unit/util_color.js b/test/unit/util_color.js
index ba7fa059c..c0db8ee90 100644
--- a/test/unit/util_color.js
+++ b/test/unit/util_color.js
@@ -11,25 +11,25 @@ test('decimalToHex', function (t) {
 });
 
 test('decimalToRgb', function (t) {
-    t.deepEqual(color.decimalToRgb(0), {r:0,g:0,b:0});
-    t.deepEqual(color.decimalToRgb(1), {r:0,g:0,b:1});
-    t.deepEqual(color.decimalToRgb(16777215), {r:255,g:255,b:255});
-    t.deepEqual(color.decimalToRgb(-16777215), {r:0,g:0,b:1});
-    t.deepEqual(color.decimalToRgb(99999999), {r:245,g:224,b:255});
+    t.deepEqual(color.decimalToRgb(0), {r: 0, g: 0, b: 0});
+    t.deepEqual(color.decimalToRgb(1), {r: 0, g: 0, b: 1});
+    t.deepEqual(color.decimalToRgb(16777215), {r: 255, g: 255, b: 255});
+    t.deepEqual(color.decimalToRgb(-16777215), {r: 0, g: 0, b: 1});
+    t.deepEqual(color.decimalToRgb(99999999), {r: 245, g: 224, b: 255});
     t.end();
 });
 
 test('hexToRgb', function (t) {
-    t.deepEqual(color.hexToRgb('#000'), {r:0,g:0,b:0});
-    t.deepEqual(color.hexToRgb('#000000'), {r:0,g:0,b:0});
-    t.deepEqual(color.hexToRgb('#fff'), {r:255,g:255,b:255});
-    t.deepEqual(color.hexToRgb('#ffffff'), {r:255,g:255,b:255});
-    t.deepEqual(color.hexToRgb('#0fa'), {r:0,g:255,b:170});
-    t.deepEqual(color.hexToRgb('#00ffaa'), {r:0,g:255,b:170});
+    t.deepEqual(color.hexToRgb('#000'), {r: 0, g: 0, b: 0});
+    t.deepEqual(color.hexToRgb('#000000'), {r: 0, g: 0, b: 0});
+    t.deepEqual(color.hexToRgb('#fff'), {r: 255, g: 255, b: 255});
+    t.deepEqual(color.hexToRgb('#ffffff'), {r: 255, g: 255, b: 255});
+    t.deepEqual(color.hexToRgb('#0fa'), {r: 0, g: 255, b: 170});
+    t.deepEqual(color.hexToRgb('#00ffaa'), {r: 0, g: 255, b: 170});
 
-    t.deepEqual(color.hexToRgb('000'), {r:0,g:0,b:0});
-    t.deepEqual(color.hexToRgb('fff'), {r:255,g:255,b:255});
-    t.deepEqual(color.hexToRgb('00ffaa'), {r:0,g:255,b:170});
+    t.deepEqual(color.hexToRgb('000'), {r: 0, g: 0, b: 0});
+    t.deepEqual(color.hexToRgb('fff'), {r: 255, g: 255, b: 255});
+    t.deepEqual(color.hexToRgb('00ffaa'), {r: 0, g: 255, b: 170});
 
     t.deepEqual(color.hexToRgb('0'), null);
     t.deepEqual(color.hexToRgb('hello world'), null);
@@ -38,16 +38,16 @@ test('hexToRgb', function (t) {
 });
 
 test('rgbToHex', function (t) {
-    t.strictEqual(color.rgbToHex({r:0,g:0,b:0}), '#000000');
-    t.strictEqual(color.rgbToHex({r:255,g:255,b:255}), '#ffffff');
-    t.strictEqual(color.rgbToHex({r:0,g:255,b:170}), '#00ffaa');
+    t.strictEqual(color.rgbToHex({r: 0, g: 0, b: 0}), '#000000');
+    t.strictEqual(color.rgbToHex({r: 255, g: 255, b: 255}), '#ffffff');
+    t.strictEqual(color.rgbToHex({r: 0, g: 255, b: 170}), '#00ffaa');
     t.end();
 });
 
 test('rgbToDecimal', function (t) {
-    t.strictEqual(color.rgbToDecimal({r:0,g:0,b:0}), 0);
-    t.strictEqual(color.rgbToDecimal({r:255,g:255,b:255}), 16777215);
-    t.strictEqual(color.rgbToDecimal({r:0,g:255,b:170}), 65450);
+    t.strictEqual(color.rgbToDecimal({r: 0, g: 0, b: 0}), 0);
+    t.strictEqual(color.rgbToDecimal({r: 255, g: 255, b: 255}), 16777215);
+    t.strictEqual(color.rgbToDecimal({r: 0, g: 255, b: 170}), 65450);
     t.end();
 });
 
diff --git a/webpack.config.js b/webpack.config.js
index d46f55bf6..cb4b01e05 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -50,7 +50,7 @@ module.exports = [
     // Webpack-compatible
     defaultsDeep({}, base, {
         entry: {
-            'dist': './src/index.js'
+            dist: './src/index.js'
         },
 
         output: {
@@ -63,8 +63,8 @@ module.exports = [
     // Playground
     defaultsDeep({}, base, {
         entry: {
-            'vm': './src/index.js',
-            'vendor': [
+            vm: './src/index.js',
+            vendor: [
                 // FPS counter
                 'stats.js/build/stats.min.js',
                 // Syntax highlighter