From eb931fd99bf0a32e694e2ac67d495ddd7799ebfd Mon Sep 17 00:00:00 2001
From: Christopher Willis-Ford <cwillisf@media.mit.edu>
Date: Wed, 24 May 2017 15:30:29 -0700
Subject: [PATCH 01/11] Specify dataFormat when loading asset for import

When importing a project we know the file extension for each asset to be
loaded. This change provides that information to the storage system so
that we can load assets which don't use the default. For example, this
allows loading JPG-format backdrops.

In support of this change, there's a new function on `StringUtil` called
`splitFirst`, which splits a string on the first instance of a separator
character. This change includes unit tests for this new function.
---
 src/import/load-costume.js           |  9 +++++----
 src/import/load-sound.js             |  6 ++++--
 src/playground/playground.js         |  2 +-
 src/serialization/sb3.js             |  2 +-
 src/util/string-util.js              | 24 ++++++++++++++++++++++++
 test/fixtures/attach-test-storage.js |  2 +-
 test/unit/util_string.js             |  8 ++++++++
 7 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/src/import/load-costume.js b/src/import/load-costume.js
index a9323398d..54962ea1f 100644
--- a/src/import/load-costume.js
+++ b/src/import/load-costume.js
@@ -1,3 +1,4 @@
+const StringUtil = require('../util/string-util');
 const log = require('../util/log');
 
 /**
@@ -19,17 +20,17 @@ const loadCostume = function (md5ext, costume, runtime) {
     }
 
     const AssetType = runtime.storage.AssetType;
-    const idParts = md5ext.split('.');
+    const idParts = StringUtil.splitFirst(md5ext, '.');
     const md5 = idParts[0];
-    const ext = idParts[1].toUpperCase();
-    const assetType = (ext === 'SVG') ? AssetType.ImageVector : AssetType.ImageBitmap;
+    const ext = idParts[1].toLowerCase();
+    const assetType = (ext === 'svg') ? AssetType.ImageVector : AssetType.ImageBitmap;
 
     const rotationCenter = [
         costume.rotationCenterX / costume.bitmapResolution,
         costume.rotationCenterY / costume.bitmapResolution
     ];
 
-    let promise = runtime.storage.load(assetType, md5).then(costumeAsset => {
+    let promise = runtime.storage.load(assetType, md5, ext).then(costumeAsset => {
         costume.assetId = costumeAsset.assetId;
         costume.assetType = assetType;
         return costumeAsset;
diff --git a/src/import/load-sound.js b/src/import/load-sound.js
index a308e1516..80b595987 100644
--- a/src/import/load-sound.js
+++ b/src/import/load-sound.js
@@ -1,3 +1,4 @@
+const StringUtil = require('../util/string-util');
 const log = require('../util/log');
 
 /**
@@ -17,9 +18,10 @@ const loadSound = function (sound, runtime) {
         log.error('No audio engine present; cannot load sound asset: ', sound.md5);
         return Promise.resolve(sound);
     }
-    const idParts = sound.md5.split('.');
+    const idParts = StringUtil.splitFirst(sound.md5, '.');
     const md5 = idParts[0];
-    return runtime.storage.load(runtime.storage.AssetType.Sound, md5)
+    const ext = idParts[1].toLowerCase();
+    return runtime.storage.load(runtime.storage.AssetType.Sound, md5, ext)
         .then(soundAsset => {
             sound.assetId = soundAsset.assetId;
             sound.assetType = runtime.storage.AssetType.Sound;
diff --git a/src/playground/playground.js b/src/playground/playground.js
index c1b655a58..814bfb628 100644
--- a/src/playground/playground.js
+++ b/src/playground/playground.js
@@ -34,7 +34,7 @@ const getAssetUrl = function (asset) {
         'internalapi/asset/',
         asset.assetId,
         '.',
-        asset.assetType.runtimeFormat,
+        asset.dataFormat,
         '/get/'
     ];
     return assetUrlParts.join('');
diff --git a/src/serialization/sb3.js b/src/serialization/sb3.js
index 4477a7b51..9708b9195 100644
--- a/src/serialization/sb3.js
+++ b/src/serialization/sb3.js
@@ -75,7 +75,7 @@ const parseScratchObject = function (object, runtime) {
             rotationCenterX: costumeSource.rotationCenterX,
             rotationCenterY: costumeSource.rotationCenterY
         };
-        const costumeMd5 = `${costumeSource.assetId}.${costumeSource.assetType.runtimeFormat}`;
+        const costumeMd5 = `${costumeSource.assetId}.${costumeSource.dataFormat}`;
         return loadCostume(costumeMd5, costume, runtime);
     });
     // Sounds from JSON
diff --git a/src/util/string-util.js b/src/util/string-util.js
index 0ee712548..48dde0277 100644
--- a/src/util/string-util.js
+++ b/src/util/string-util.js
@@ -12,6 +12,30 @@ class StringUtil {
         while (existingNames.indexOf(name + i) >= 0) i++;
         return name + i;
     }
+
+    /**
+     * Split a string on the first occurrence of a split character.
+     * @param {string} text - the string to split.
+     * @param {string} separator - split the text on this character.
+     * @returns {[string, string]} - the two parts of the split string, or [text, null] if no split character found.
+     * @example
+     * // returns ['foo', 'tar.gz']
+     * splitFirst('foo.tar.gz', '.');
+     * @example
+     * // returns ['foo', null]
+     * splitFirst('foo', '.');
+     * @example
+     * // returns ['foo', '']
+     * splitFirst('foo.', '.');
+     */
+    static splitFirst (text, separator) {
+        const index = text.indexOf(separator);
+        if (index >= 0) {
+            return [text.substring(0, index), text.substring(index + 1)];
+        } else {
+            return [text, null];
+        }
+    }
 }
 
 module.exports = StringUtil;
diff --git a/test/fixtures/attach-test-storage.js b/test/fixtures/attach-test-storage.js
index 3e75f5967..bb0cc3a08 100644
--- a/test/fixtures/attach-test-storage.js
+++ b/test/fixtures/attach-test-storage.js
@@ -26,7 +26,7 @@ const getAssetUrl = function (asset) {
         'internalapi/asset/',
         asset.assetId,
         '.',
-        asset.assetType.runtimeFormat,
+        asset.dataFormat,
         '/get/'
     ];
     return assetUrlParts.join('');
diff --git a/test/unit/util_string.js b/test/unit/util_string.js
index 741336258..aca20f9a4 100644
--- a/test/unit/util_string.js
+++ b/test/unit/util_string.js
@@ -1,6 +1,14 @@
 const test = require('tap').test;
 const StringUtil = require('../../src/util/string-util');
 
+test('splitFirst', t => {
+    t.deepEqual(StringUtil.splitFirst('asdf.1234', '.'), ['asdf', '1234']);
+    t.deepEqual(StringUtil.splitFirst('asdf.', '.'), ['asdf', '']);
+    t.deepEqual(StringUtil.splitFirst('.1234', '.'), ['', '1234']);
+    t.deepEqual(StringUtil.splitFirst('foo', '.'), ['foo', null]);
+    t.end();
+});
+
 test('withoutTrailingDigits', t => {
     t.strictEqual(StringUtil.withoutTrailingDigits('boeing747'), 'boeing');
     t.strictEqual(StringUtil.withoutTrailingDigits('boeing747 '), 'boeing747 ');

From 2625529ebe2a921eb3f912b69f96948a616a83ea Mon Sep 17 00:00:00 2001
From: Christopher Willis-Ford <cwillisf@media.mit.edu>
Date: Wed, 3 May 2017 16:39:31 -0700
Subject: [PATCH 02/11] Create WeDo 2.0 device communication classes

---
 src/blocks/scratch3_wedo2.js | 387 +++++++++++++++++++++++++++++++++++
 src/engine/runtime.js        |   3 +-
 2 files changed, 389 insertions(+), 1 deletion(-)
 create mode 100644 src/blocks/scratch3_wedo2.js

diff --git a/src/blocks/scratch3_wedo2.js b/src/blocks/scratch3_wedo2.js
new file mode 100644
index 000000000..ac945ef84
--- /dev/null
+++ b/src/blocks/scratch3_wedo2.js
@@ -0,0 +1,387 @@
+const log = require('../util/log');
+
+/**
+ * Manage power, direction, and timers for one WeDo 2.0 motor.
+ */
+class WeDo2Motor {
+    /**
+     * Construct a WeDo2Motor instance.
+     * @param {WeDo2} parent - the WeDo 2.0 device which owns this motor.
+     * @param {int} index - the zero-based index of this motor on its parent device.
+     */
+    constructor (parent, index) {
+        /**
+         * The WeDo 2.0 device which owns this motor.
+         * @type {WeDo2}
+         * @private
+         */
+        this._parent = parent;
+
+        /**
+         * The zero-based index of this motor on its parent device.
+         * @type {int}
+         * @private
+         */
+        this._index = index;
+
+        /**
+         * This motor's current direction: 1 for "this way" or -1 for "that way"
+         * @type {number}
+         * @private
+         */
+        this._direction = 1;
+
+        /**
+         * This motor's current power level, in the range [0,100].
+         * @type {number}
+         * @private
+         */
+        this._power = 100;
+
+        /**
+         * Is this motor currently moving?
+         * @type {boolean}
+         * @private
+         */
+        this._isOn = false;
+
+        /**
+         * If the motor has been turned on or is actively braking for a specific duration, this is the timeout ID for
+         * the end-of-action handler. Cancel this when changing plans.
+         * @type {Object}
+         * @private
+         */
+        this._pendingTimeoutId = null;
+
+        this.startBraking = this.startBraking.bind(this);
+        this.setMotorOff = this.setMotorOff.bind(this);
+    }
+
+    /**
+     * @return {number} - the duration of active braking after a call to startBraking(). Afterward, turn the motor off.
+     * @constructor
+     */
+    static get BRAKE_TIME_MS () {
+        return 1000;
+    }
+
+    /**
+     * @return {int} - this motor's current direction: 1 for "this way" or -1 for "that way"
+     */
+    get direction () {
+        return this._direction;
+    }
+
+    /**
+     * @param {int} value - this motor's new direction: 1 for "this way" or -1 for "that way"
+     */
+    set direction (value) {
+        if (value < 0) {
+            this._direction = -1;
+        } else {
+            this._direction = 1;
+        }
+    }
+
+    /**
+     * @return {int} - this motor's current power level, in the range [0,100].
+     */
+    get power () {
+        return this._power;
+    }
+
+    /**
+     * @param {int} value - this motor's new power level, in the range [0,100].
+     */
+    set power (value) {
+        this._power = Math.max(0, Math.min(value, 100));
+    }
+
+    /**
+     * @return {boolean} - true if this motor is currently moving, false if this motor is off or braking.
+     */
+    get isOn () {
+        return this._isOn;
+    }
+
+    /**
+     * Turn this motor on indefinitely.
+     */
+    setMotorOn () {
+        this._parent._send('motorOn', {motorIndex: this._index, power: this._direction * this._power});
+        this._isOn = true;
+        this._clearTimeout();
+    }
+
+    /**
+     * Turn this motor on for a specific duration.
+     * @param {number} milliseconds - run the motor for this long.
+     */
+    setMotorOnFor (milliseconds) {
+        milliseconds = Math.max(0, milliseconds);
+        this.setMotorOn();
+        this._setNewTimeout(this.startBraking, milliseconds);
+    }
+
+    /**
+     * Start active braking on this motor. After a short time, the motor will turn off.
+     */
+    startBraking () {
+        this._parent._send('motorBrake', {motorIndex: this._index});
+        this._isOn = false;
+        this._setNewTimeout(this.setMotorOff, WeDo2Motor.BRAKE_TIME_MS);
+    }
+
+    /**
+     * Turn this motor off.
+     */
+    setMotorOff () {
+        this._parent._send('motorOff', {motorIndex: this._index});
+        this._isOn = false;
+    }
+
+    /**
+     * Clear the motor action timeout, if any. Safe to call even when there is no pending timeout.
+     * @private
+     */
+    _clearTimeout () {
+        if (this._pendingTimeoutId !== null) {
+            clearTimeout(this._pendingTimeoutId);
+            this._pendingTimeoutId = null;
+        }
+    }
+
+    /**
+     * Set a new motor action timeout, after clearing an existing one if necessary.
+     * @param {Function} callback - to be called at the end of the timeout.
+     * @param {int} delay - wait this many milliseconds before calling the callback.
+     * @private
+     */
+    _setNewTimeout (callback, delay) {
+        this._clearTimeout();
+        const timeoutID = setTimeout(() => {
+            if (this._pendingTimeoutId === timeoutID) {
+                this._pendingTimeoutId = null;
+            }
+            callback();
+        }, delay);
+        this._pendingTimeoutId = timeoutID;
+    }
+}
+
+/**
+ * Manage communication with a WeDo 2.0 device over a Device Manager client socket.
+ */
+class WeDo2 {
+
+    /**
+     * @return {string} - the type of Device Manager device socket that this class will handle.
+     */
+    static get DEVICE_TYPE () {
+        return 'wedo2';
+    }
+
+    /**
+     * Construct a WeDo2 communication object.
+     * @param {Socket} socket - the socket for a WeDo 2.0 device, as provided by a Device Manager client.
+     */
+    constructor (socket) {
+        /**
+         * The socket-IO socket used to communicate with the Device Manager about this device.
+         * @type {Socket}
+         * @private
+         */
+        this._socket = socket;
+
+        /**
+         * The motors which this WeDo 2.0 could possibly have.
+         * @type {[WeDo2Motor]}
+         * @private
+         */
+        this._motors = [new WeDo2Motor(this, 0), new WeDo2Motor(this, 1)];
+
+        /**
+         * The most recently received value for each sensor.
+         * @type {Object.<string, number>}
+         * @private
+         */
+        this._sensors = {
+            tiltX: 0,
+            tiltY: 0,
+            distance: 0
+        };
+
+        this._onSensorChanged = this._onSensorChanged.bind(this);
+        this._onDisconnect = this._onDisconnect.bind(this);
+
+        this._connectEvents();
+    }
+
+    /**
+     * Manually dispose of this object.
+     */
+    dispose () {
+        this._disconnectEvents();
+    }
+
+    /**
+     * @return {number} - the latest value received for the tilt sensor's tilt about the X axis.
+     */
+    get tiltX () {
+        return this._sensors.tiltX;
+    }
+
+    /**
+     * @return {number} - the latest value received for the tilt sensor's tilt about the Y axis.
+     */
+    get tiltY () {
+        return this._sensors.tiltY;
+    }
+
+    /**
+     * @return {number} - the latest value received from the distance sensor.
+     */
+    get distance () {
+        return this._sensors.distance;
+    }
+
+    /**
+     * Access a particular motor on this device.
+     * @param {int} index - the zero-based index of the desired motor.
+     * @return {WeDo2Motor} - the WeDo2Motor instance, if any, at that index.
+     */
+    motor (index) {
+        return this._motors[index];
+    }
+
+    /**
+     * Set the WeDo 2.0 hub's LED to a specific color.
+     * @param {int} rgb - a 24-bit RGB color in 0xRRGGBB format.
+     */
+    setLED (rgb) {
+        this._send('setLED', {rgb});
+    }
+
+    /**
+     * Play a tone from the WeDo 2.0 hub for a specific amount of time.
+     * @param {int} tone - the pitch of the tone, in Hz.
+     * @param {int} milliseconds - the duration of the note, in milliseconds.
+     */
+    playTone (tone, milliseconds) {
+        this._send('playTone', {tone, ms: milliseconds});
+    }
+
+    /**
+     * Stop the tone playing from the WeDo 2.0 hub, if any.
+     */
+    stopTone () {
+        this._send('stopTone');
+    }
+
+    /**
+     * Attach event handlers to the device socket.
+     * @private
+     */
+    _connectEvents () {
+        this._socket.on('sensorChanged', this._onSensorChanged);
+        this._socket.on('deviceWasClosed', this._onDisconnect);
+        this._socket.on('disconnect', this._onDisconnect);
+    }
+
+    /**
+     * Detach event handlers from the device socket.
+     * @private
+     */
+    _disconnectEvents () {
+        this._socket.off('sensorChanged', this._onSensorChanged);
+        this._socket.off('deviceWasClosed', this._onDisconnect);
+        this._socket.off('disconnect', this._onDisconnect);
+    }
+
+    /**
+     * Store the sensor value from an incoming 'sensorChanged' event.
+     * @param {object} event - the 'sensorChanged' event.
+     * @property {string} sensorName - the name of the sensor which changed.
+     * @property {number} sensorValue - the new value of the sensor.
+     * @private
+     */
+    _onSensorChanged (event) {
+        this._sensors[event.sensorName] = event.sensorValue;
+    }
+
+    /**
+     * React to device disconnection. May be called more than once.
+     * @private
+     */
+    _onDisconnect () {
+        this._disconnectEvents();
+    }
+
+    /**
+     * Send a message to the device socket.
+     * @param {string} message - the name of the message, such as 'playTone'.
+     * @param {object} [details] - optional additional details for the message, such as tone duration and pitch.
+     * @private
+     */
+    _send (message, details) {
+        this._socket.emit(message, details);
+    }
+}
+
+/**
+ * Scratch 3.0 blocks to interact with a LEGO WeDo 2.0 device.
+ */
+class Scratch3WeDo2Blocks {
+
+    /**
+     * @return {string} - the name of this extension.
+     */
+    static get EXTENSION_NAME () {
+        return 'wedo2';
+    }
+
+    /**
+     * Construct a set of WeDo 2.0 blocks.
+     * @param {Runtime} runtime - the Scratch 3.0 runtime.
+     */
+    constructor (runtime) {
+        /**
+         * The Scratch 3.0 runtime.
+         * @type {Runtime}
+         */
+        this.runtime = runtime;
+
+        this.runtime.HACK_WeDo2Blocks = this;
+    }
+
+    /**
+     * Use the Device Manager client to attempt to connect to a WeDo 2.0 device.
+     */
+    connect () {
+        if (this._device || this._finder) {
+            return;
+        }
+        const deviceManager = this.runtime.ioDevices.deviceManager;
+        const finder = this._finder =
+            deviceManager.searchAndConnect(Scratch3WeDo2Blocks.EXTENSION_NAME, WeDo2.DEVICE_TYPE);
+        this._finder.promise.then(
+            socket => {
+                if (this._finder === finder) {
+                    this._finder = null;
+                    this._device = new WeDo2(socket);
+                } else {
+                    log.warn('Ignoring success from stale WeDo 2.0 connection attempt');
+                }
+            },
+            reason => {
+                if (this._finder === finder) {
+                    this._finder = null;
+                    log.warn(`WeDo 2.0 connection failed: ${reason}`);
+                } else {
+                    log.warn('Ignoring failure from stale WeDo 2.0 connection attempt');
+                }
+            });
+    }
+}
+
+module.exports = Scratch3WeDo2Blocks;
diff --git a/src/engine/runtime.js b/src/engine/runtime.js
index c938c37ed..dd037c57d 100644
--- a/src/engine/runtime.js
+++ b/src/engine/runtime.js
@@ -19,7 +19,8 @@ const defaultBlockPackages = {
     scratch3_sound: require('../blocks/scratch3_sound'),
     scratch3_sensing: require('../blocks/scratch3_sensing'),
     scratch3_data: require('../blocks/scratch3_data'),
-    scratch3_procedures: require('../blocks/scratch3_procedures')
+    scratch3_procedures: require('../blocks/scratch3_procedures'),
+    scratch3_wedo2: require('../blocks/scratch3_wedo2')
 };
 
 /**

From 06fe701624d3954bf67aefddbd6d5fd2fa0268ac Mon Sep 17 00:00:00 2001
From: Christopher Willis-Ford <cwillisf@media.mit.edu>
Date: Fri, 5 May 2017 15:05:21 -0700
Subject: [PATCH 03/11] Implement WeDo 2.0 blocks

---
 src/blocks/scratch3_wedo2.js | 312 +++++++++++++++++++++++++++++++++++
 1 file changed, 312 insertions(+)

diff --git a/src/blocks/scratch3_wedo2.js b/src/blocks/scratch3_wedo2.js
index ac945ef84..bd9e6c119 100644
--- a/src/blocks/scratch3_wedo2.js
+++ b/src/blocks/scratch3_wedo2.js
@@ -1,3 +1,4 @@
+const color = require('../util/color');
 const log = require('../util/log');
 
 /**
@@ -328,6 +329,42 @@ class WeDo2 {
     }
 }
 
+/**
+ * Enum for motor specification.
+ * @readonly
+ * @enum {string}
+ */
+const MotorID = {
+    DEFAULT: 'motor',
+    A: 'motor A',
+    B: 'motor B',
+    ALL: 'all motors'
+};
+
+/**
+ * Enum for motor direction specification.
+ * @readonly
+ * @enum {string}
+ */
+const MotorDirection = {
+    FORWARD: 'this way',
+    BACKWARD: 'that way',
+    REVERSE: 'reverse'
+};
+
+/**
+ * Enum for tilt sensor direction.
+ * @readonly
+ * @enum {string}
+ */
+const TiltDirection = {
+    UP: 'up',
+    DOWN: 'down',
+    LEFT: 'left',
+    RIGHT: 'right',
+    ANY: 'any'
+};
+
 /**
  * Scratch 3.0 blocks to interact with a LEGO WeDo 2.0 device.
  */
@@ -340,6 +377,13 @@ class Scratch3WeDo2Blocks {
         return 'wedo2';
     }
 
+    /**
+     * @return {number} - the tilt sensor counts as "tilted" if its tilt angle meets or exceeds this threshold.
+     */
+    static get TILT_THRESHOLD () {
+        return 15;
+    }
+
     /**
      * Construct a set of WeDo 2.0 blocks.
      * @param {Runtime} runtime - the Scratch 3.0 runtime.
@@ -382,6 +426,274 @@ class Scratch3WeDo2Blocks {
                 }
             });
     }
+
+    /**
+     * Retrieve the block primitives implemented by this package.
+     * @return {object.<string, Function>} Mapping of opcode to Function.
+     */
+    getPrimitives () {
+        return {
+            wedo2_motorOnFor: this.motorOnFor,
+            wedo2_motorOn: this.motorOn,
+            wedo2_motorOff: this.motorOff,
+            wedo2_startMotorPower: this.startMotorPower,
+            wedo2_setMotorDirection: this.setMotorDirection,
+            wedo2_setLightHue: this.setLightHue,
+            wedo2_playNoteFor: this.playNoteFor,
+            wedo2_whenDistance: this.whenDistance,
+            wedo2_whenTilted: this.whenTilted,
+            wedo2_getDistance: this.getDistance,
+            wedo2_isTilted: this.isTilted,
+            wedo2_getTiltAngle: this.getTiltAngle
+        };
+    }
+
+    /**
+     * Turn specified motor(s) on for a specified duration.
+     * @param {object} args - the block's arguments.
+     * @property {MotorID} MOTOR_ID - the motor(s) to activate.
+     * @property {int} DURATION - the amount of time to run the motors.
+     * @return {Promise} - a promise which will resolve at the end of the duration.
+     */
+    motorOnFor (args) {
+        return new Promise(resolve => {
+            this._forEachMotor(args.MOTOR_ID, motorIndex => {
+                this._device.motor(motorIndex).setMotorOnFor(args.DURATION);
+            });
+
+            // Ensure this block runs for a fixed amount of time even when no device is connected.
+            setTimeout(resolve, args.DURATION);
+        });
+    }
+
+    /**
+     * Turn specified motor(s) on indefinitely.
+     * @param {object} args - the block's arguments.
+     * @property {MotorID} MOTOR_ID - the motor(s) to activate.
+     */
+    motorOn (args) {
+        this._forEachMotor(args.MOTOR_ID, motorIndex => {
+            this._device.motor(motorIndex).setMotorOn();
+        });
+    }
+
+    /**
+     * Turn specified motor(s) off.
+     * @param {object} args - the block's arguments.
+     * @property {MotorID} MOTOR_ID - the motor(s) to deactivate.
+     */
+    motorOff (args) {
+        this._forEachMotor(args.MOTOR_ID, motorIndex => {
+            this._device.motor(motorIndex).setMotorOff();
+        });
+    }
+
+    /**
+     * Turn specified motor(s) off.
+     * @param {object} args - the block's arguments.
+     * @property {MotorID} MOTOR_ID - the motor(s) to be affected.
+     * @property {int} POWER - the new power level for the motor(s).
+     */
+    startMotorPower (args) {
+        this._forEachMotor(args.MOTOR_ID, motorIndex => {
+            const motor = this._device.motor(motorIndex);
+            motor.power = args.POWER;
+            motor.setMotorOn();
+        });
+    }
+
+    /**
+     * Set the direction of rotation for specified motor(s).
+     * If the direction is 'reverse' the motor(s) will be reversed individually.
+     * @param {object} args - the block's arguments.
+     * @property {MotorID} MOTOR_ID - the motor(s) to be affected.
+     * @property {MotorDirection} DIRECTION - the new direction for the motor(s).
+     */
+    setMotorDirection (args) {
+        this._forEachMotor(args.MOTOR_ID, motorIndex => {
+            const motor = this._device.motor(motorIndex);
+            switch (args.DIRECTION) {
+            case MotorDirection.FORWARD:
+                motor.direction = 1;
+                break;
+            case MotorDirection.BACKWARD:
+                motor.direction = -1;
+                break;
+            case MotorDirection.REVERSE:
+                motor.direction = -motor.direction;
+                break;
+            default:
+                log.warn(`Unknown motor direction in setMotorDirection: ${args.DIRECTION}`);
+                break;
+            }
+        });
+    }
+
+    /**
+     * Set the LED's hue.
+     * @param {object} args - the block's arguments.
+     * @property {number} HUE - the hue to set, in the range [0,100].
+     */
+    setLightHue (args) {
+        // Convert from [0,100] to [0,360]
+        const hue = args.HUE * 360 / 100;
+
+        const rgbObject = color.hsvToRgb({h: hue, s: 1, v: 1});
+
+        const rgbDecimal = color.rgbToDecimal(rgbObject);
+
+        this._device.setLED(rgbDecimal);
+    }
+
+    /**
+     * Make the WeDo 2.0 hub play a MIDI note for the specified duration.
+     * @param {object} args - the block's arguments.
+     * @property {number} NOTE - the MIDI note to play.
+     * @property {number} DURATION - the duration of the note, in seconds.
+     * @return {Promise} - a promise which will resolve at the end of the duration.
+     */
+    playNoteFor (args) {
+        return new Promise(resolve => {
+            const durationMS = args.DURATION * 1000;
+            const tone = this._noteToTone(args.NOTE);
+            this._device.playTone(tone, durationMS);
+
+            // Ensure this block runs for a fixed amount of time even when no device is connected.
+            setTimeout(resolve, durationMS);
+        });
+    }
+
+    /**
+     * Compare the distance sensor's value to a reference.
+     * @param {object} args - the block's arguments.
+     * @property {string} OP - the comparison operation: '<' or '>'.
+     * @property {number} REFERENCE - the value to compare against.
+     * @return {boolean} - the result of the comparison, or false on error.
+     */
+    whenDistance (args) {
+        switch (args.OP) {
+        case '<':
+            return this._device.distance < args.REFERENCE;
+        case '>':
+            return this._device.distance > args.REFERENCE;
+        default:
+            log.warn(`Unknown comparison operator in whenDistance: ${args.OP}`);
+            return false;
+        }
+    }
+
+    /**
+     * Test whether the tilt sensor is currently tilted.
+     * @param {object} args - the block's arguments.
+     * @property {TiltDirection} DIRECTION - the tilt direction to test (up, down, left, right, or any).
+     * @return {boolean} - true if the tilt sensor is tilted past a threshold in the specified direction.
+     */
+    whenTilted (args) {
+        return this._isTilted(args.DIRECTION);
+    }
+
+    /**
+     * @return {number} - the distance sensor's value, scaled to the [0,100] range.
+     */
+    getDistance () {
+        return this._device.distance * 10;
+    }
+
+    /**
+     * Test whether the tilt sensor is currently tilted.
+     * @param {object} args - the block's arguments.
+     * @property {TiltDirection} DIRECTION - the tilt direction to test (up, down, left, right, or any).
+     * @return {boolean} - true if the tilt sensor is tilted past a threshold in the specified direction.
+     */
+    isTilted (args) {
+        return this._isTilted(args.DIRECTION);
+    }
+
+    /**
+     * @param {object} args - the block's arguments.
+     * @property {TiltDirection} DIRECTION - the direction (up, down, left, right) to check.
+     * @return {number} - the tilt sensor's angle in the specified direction.
+     * Note that getTiltAngle(up) = -getTiltAngle(down) and getTiltAngle(left) = -getTiltAngle(right).
+     */
+    getTiltAngle (args) {
+        return this._getTiltAngle(args.DIRECTION);
+    }
+
+    /**
+     * Test whether the tilt sensor is currently tilted.
+     * @param {TiltDirection} direction - the tilt direction to test (up, down, left, right, or any).
+     * @return {boolean} - true if the tilt sensor is tilted past a threshold in the specified direction.
+     * @private
+     */
+    _isTilted (direction) {
+        switch (direction) {
+        case TiltDirection.ANY:
+            return (Math.abs(this._device.tiltX) >= Scratch3WeDo2Blocks.TILT_THRESHOLD) ||
+                (Math.abs(this._device.tiltY) >= Scratch3WeDo2Blocks.TILT_THRESHOLD);
+        default:
+            return this._getTiltAngle(direction) >= Scratch3WeDo2Blocks.TILT_THRESHOLD;
+        }
+    }
+
+    /**
+     * @param {TiltDirection} direction - the direction (up, down, left, right) to check.
+     * @return {number} - the tilt sensor's angle in the specified direction.
+     * Note that getTiltAngle(up) = -getTiltAngle(down) and getTiltAngle(left) = -getTiltAngle(right).
+     * @private
+     */
+    _getTiltAngle (direction) {
+        switch (direction) {
+        case TiltDirection.UP:
+            return -this._device.tiltY;
+        case TiltDirection.DOWN:
+            return this._device.tiltY;
+        case TiltDirection.LEFT:
+            return -this._device.tiltX;
+        case TiltDirection.RIGHT:
+            return this._device.tiltX;
+        default:
+            log.warn(`Unknown tilt direction in _getTiltAngle: ${direction}`);
+        }
+    }
+
+    /**
+     * Call a callback for each motor indexed by the provided motor ID.
+     * @param {MotorID} motorID - the ID specifier.
+     * @param {Function} callback - the function to call with the numeric motor index for each motor.
+     * @private
+     */
+    _forEachMotor (motorID, callback) {
+        let motors;
+        switch (motorID) {
+        case MotorID.A:
+            motors = [0];
+            break;
+        case MotorID.B:
+            motors = [1];
+            break;
+        case MotorID.ALL:
+        case MotorID.DEFAULT:
+            motors = [0, 1];
+            break;
+        default:
+            log.warn(`Invalid motor ID: ${motorID}`);
+            motors = [];
+            break;
+        }
+        for (const index of motors) {
+            callback(index);
+        }
+    }
+
+    /**
+     * @param {number} midiNote - the MIDI note value to convert.
+     * @return {number} - the frequency, in Hz, corresponding to that MIDI note value.
+     * @private
+     */
+    _noteToTone (midiNote) {
+        // Note that MIDI note 69 is A4, 440 Hz
+        return 440 * Math.pow(2, (midiNote - 69) / 12);
+    }
 }
 
 module.exports = Scratch3WeDo2Blocks;

From cbfbc5d600bfa2e1f57a925bfde831be8a21c1cf Mon Sep 17 00:00:00 2001
From: Christopher Willis-Ford <cwillisf@media.mit.edu>
Date: Thu, 11 May 2017 22:39:24 -0700
Subject: [PATCH 04/11] Convert motor duration: seconds -> milliseconds

The block takes seconds, whereas the device takes milliseconds. Turning
on a motor for 1 millisecond isn't very dramatic.
---
 src/blocks/scratch3_wedo2.js | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/blocks/scratch3_wedo2.js b/src/blocks/scratch3_wedo2.js
index bd9e6c119..d79ef9096 100644
--- a/src/blocks/scratch3_wedo2.js
+++ b/src/blocks/scratch3_wedo2.js
@@ -456,13 +456,14 @@ class Scratch3WeDo2Blocks {
      * @return {Promise} - a promise which will resolve at the end of the duration.
      */
     motorOnFor (args) {
+        const durationMS = args.DURATION * 1000;
         return new Promise(resolve => {
             this._forEachMotor(args.MOTOR_ID, motorIndex => {
-                this._device.motor(motorIndex).setMotorOnFor(args.DURATION);
+                this._device.motor(motorIndex).setMotorOnFor(durationMS);
             });
 
             // Ensure this block runs for a fixed amount of time even when no device is connected.
-            setTimeout(resolve, args.DURATION);
+            setTimeout(resolve, durationMS);
         });
     }
 

From 467b747283afdd610cc1ac8b8bf8e31f074fa2ad Mon Sep 17 00:00:00 2001
From: Ray Schamp <ray@scratch.mit.edu>
Date: Fri, 2 Jun 2017 08:57:21 -0400
Subject: [PATCH 05/11] Bump scratch-storage version

Now 0.2.0 is the lowest compatible version.
---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 0308aa6f7..11fb66efe 100644
--- a/package.json
+++ b/package.json
@@ -43,7 +43,7 @@
     "scratch-audio": "^0.1.0-prerelease.0",
     "scratch-blocks": "^0.1.0-prerelease.0",
     "scratch-render": "^0.1.0-prerelease.0",
-    "scratch-storage": "^0.1.0",
+    "scratch-storage": "^0.2.0",
     "script-loader": "0.7.0",
     "stats.js": "^0.17.0",
     "tap": "^10.2.0",

From ab0cef52eb759bad7e7aad3d637fa31a19b1c18c Mon Sep 17 00:00:00 2001
From: DD Liu <liudi@media.mit.edu>
Date: Mon, 5 Jun 2017 16:55:15 -0400
Subject: [PATCH 06/11] Change wait to use a promise instead of being called
 every frame

---
 src/blocks/scratch3_control.js | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/src/blocks/scratch3_control.js b/src/blocks/scratch3_control.js
index f3b53baa2..f460399e1 100644
--- a/src/blocks/scratch3_control.js
+++ b/src/blocks/scratch3_control.js
@@ -73,18 +73,13 @@ class Scratch3ControlBlocks {
         util.startBranch(1, true);
     }
 
-    wait (args, util) {
-        if (!util.stackFrame.timer) {
-            util.stackFrame.timer = new Timer();
-            util.stackFrame.timer.start();
-            util.yield();
-            this.runtime.requestRedraw();
-        } else {
-            const duration = Math.max(0, 1000 * Cast.toNumber(args.DURATION));
-            if (util.stackFrame.timer.timeElapsed() < duration) {
-                util.yield();
-            }
-        }
+    wait (args) {
+        const duration = Math.max(0, 1000 * Cast.toNumber(args.DURATION));
+        return new Promise(resolve => {
+            setTimeout(() => {
+                resolve();
+            }, duration);
+        });
     }
 
     if (args, util) {

From e237d2484611298d2c8faf494f20b1ec431ea270 Mon Sep 17 00:00:00 2001
From: DD Liu <liudi@media.mit.edu>
Date: Tue, 6 Jun 2017 10:21:27 -0400
Subject: [PATCH 07/11] fix lint

---
 src/blocks/scratch3_control.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/blocks/scratch3_control.js b/src/blocks/scratch3_control.js
index f460399e1..975dfeb81 100644
--- a/src/blocks/scratch3_control.js
+++ b/src/blocks/scratch3_control.js
@@ -1,5 +1,4 @@
 const Cast = require('../util/cast');
-const Timer = require('../util/timer');
 
 class Scratch3ControlBlocks {
     constructor (runtime) {

From 40345384aa47e267115b9a201ab1e93bd6e1535f Mon Sep 17 00:00:00 2001
From: Paul Kaplan <pkaplan@media.mit.edu>
Date: Wed, 7 Jun 2017 09:06:46 -0400
Subject: [PATCH 08/11] Select the last target instead of the first

---
 src/virtual-machine.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/virtual-machine.js b/src/virtual-machine.js
index 19a4a8dd4..436ff60e8 100644
--- a/src/virtual-machine.js
+++ b/src/virtual-machine.js
@@ -379,7 +379,8 @@ class VirtualMachine extends EventEmitter {
                 this.runtime.disposeTarget(sprite.clones[i]);
                 // Ensure editing target is switched if we are deleting it.
                 if (clone === currentEditingTarget) {
-                    this.setEditingTarget(this.runtime.targets[0].id);
+                    const lastTargetIndex = this.runtime.targets.length - 1;
+                    this.setEditingTarget(this.runtime.targets[lastTargetIndex].id);
                 }
             }
             // Sprite object should be deleted by GC.

From 454082b569e6cb1969ede222ba5fb771a4288e9c Mon Sep 17 00:00:00 2001
From: Christopher Willis-Ford <cwillisf@media.mit.edu>
Date: Wed, 7 Jun 2017 17:05:24 -0700
Subject: [PATCH 09/11] Improve cleanup on clone disposal

The `dispose()` method on `RenderedTarget` now:
- informs the runtime that it should end any threads corresponding the
  target being disposed, and
- removes the clone from its sprite.
---
 src/sprites/rendered-target.js |  2 ++
 src/sprites/sprite.js          | 12 ++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/src/sprites/rendered-target.js b/src/sprites/rendered-target.js
index 0bc5cff6e..2fb0ddf9e 100644
--- a/src/sprites/rendered-target.js
+++ b/src/sprites/rendered-target.js
@@ -832,6 +832,8 @@ class RenderedTarget extends Target {
      */
     dispose () {
         this.runtime.changeCloneCounter(-1);
+        this.runtime.stopForTarget(this);
+        this.sprite.removeClone(this);
         if (this.renderer && this.drawableID !== null) {
             this.renderer.destroyDrawable(this.drawableID);
             if (this.visible) {
diff --git a/src/sprites/sprite.js b/src/sprites/sprite.js
index 3a0402a16..293a1f265 100644
--- a/src/sprites/sprite.js
+++ b/src/sprites/sprite.js
@@ -58,6 +58,18 @@ class Sprite {
         }
         return newClone;
     }
+
+    /**
+     * Disconnect a clone from this sprite. The clone is unmodified.
+     * In particular, the clone's dispose() method is not called.
+     * @param {!RenderedTarget} clone - the clone to be removed.
+     */
+    removeClone (clone) {
+        const cloneIndex = this.clones.indexOf(clone);
+        if (cloneIndex >= 0) {
+            this.clones.splice(cloneIndex, 1);
+        }
+    }
 }
 
 module.exports = Sprite;

From 6320fd72c311a65547adeb89e37c80c585f1c2b8 Mon Sep 17 00:00:00 2001
From: Christopher Willis-Ford <cwillisf@media.mit.edu>
Date: Thu, 8 Jun 2017 11:16:29 -0700
Subject: [PATCH 10/11] Add test for clone cleanup

This new test verifies that clones and their associated threads are
cleaned up properly by the `delete this clone` block. The clones run two
stacks each: one which waits and then deletes the clone, and another
which includes a `forever` loop: this is to verify that the thread
running the `forever` loop is ended when the clone itself is deleted.
The project does this with two batches of clones to ensure there are no
problems with reusing array indices previously occupied by now-removed
threads or clones.
---
 test/fixtures/clone-cleanup.sb2   | Bin 0 -> 54947 bytes
 test/integration/clone-cleanup.js |  96 ++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+)
 create mode 100644 test/fixtures/clone-cleanup.sb2
 create mode 100644 test/integration/clone-cleanup.js

diff --git a/test/fixtures/clone-cleanup.sb2 b/test/fixtures/clone-cleanup.sb2
new file mode 100644
index 0000000000000000000000000000000000000000..61baeb7f2def6182f3372a4d89edcee7bf23db88
GIT binary patch
literal 54947
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
M4;o(Z)~9d(55ztL+yDRo

literal 0
HcmV?d00001

diff --git a/test/integration/clone-cleanup.js b/test/integration/clone-cleanup.js
new file mode 100644
index 000000000..bfecd6d77
--- /dev/null
+++ b/test/integration/clone-cleanup.js
@@ -0,0 +1,96 @@
+const path = require('path');
+const test = require('tap').test;
+const attachTestStorage = require('../fixtures/attach-test-storage');
+const extract = require('../fixtures/extract');
+const VirtualMachine = require('../../src/index');
+
+const projectUri = path.resolve(__dirname, '../fixtures/clone-cleanup.sb2');
+const project = extract(projectUri);
+
+test('clone-cleanup', t => {
+    const vm = new VirtualMachine();
+    attachTestStorage(vm);
+
+    /**
+     * Track which step of the project is currently under test.
+     * @type {number}
+     */
+    let testStep = -1;
+
+    /**
+     * We test using setInterval; track the interval ID here so we can cancel it.
+     * @type {object}
+     */
+    let testInterval = null;
+
+    const verifyCounts = (expectedClones, extraThreads) => {
+        // stage plus one sprite, plus clones
+        t.strictEqual(vm.runtime.targets.length, 2 + expectedClones,
+            `target count at step ${testStep}`);
+
+        // the stage should never have any clones
+        t.strictEqual(vm.runtime.targets[0].sprite.clones.length, 1,
+            `stage clone count at step ${testStep}`);
+
+        // check sprite clone count (+1 for original)
+        t.strictEqual(vm.runtime.targets[1].sprite.clones.length, 1 + expectedClones,
+            `sprite clone count at step ${testStep}`);
+
+        // thread count isn't directly tied to clone count since threads can end
+        t.strictEqual(vm.runtime.threads.length, extraThreads + (2 * expectedClones),
+            `thread count at step ${testStep}`);
+    };
+
+    const testNextStep = () => {
+        ++testStep;
+        switch (testStep) {
+        case 0:
+            // Project has started, main thread running, no clones yet
+            verifyCounts(0, 1);
+            break;
+
+        case 1:
+            // 10 clones have been created, main thread still running
+            verifyCounts(10, 1);
+            break;
+
+        case 2:
+            // The first batch of clones has deleted themselves; main thread still running
+            verifyCounts(0, 1);
+            break;
+
+        case 3:
+            // The second batch of clones has been created and the main thread has ended
+            verifyCounts(10, 0);
+            break;
+
+        case 4:
+            // The second batch of clones has deleted themselves; everything is finished
+            verifyCounts(0, 0);
+
+            clearInterval(testInterval);
+            t.end();
+            process.nextTick(process.exit);
+            break;
+        }
+    };
+
+    // Start VM, load project, and run
+    t.doesNotThrow(() => {
+        vm.start();
+        vm.clear();
+        vm.setCompatibilityMode(false);
+        vm.setTurboMode(false);
+        vm.loadProject(project).then(() => {
+
+            // Verify initial state: no clones, nothing running ("step -1")
+            verifyCounts(0, 0);
+
+            vm.greenFlag();
+
+            // Every second, advance the testing step
+            testInterval = setInterval(testNextStep, 1000);
+        });
+    });
+
+});

From 9c5d43e9d3f6da2c75cccc851756b7b355244cb4 Mon Sep 17 00:00:00 2001
From: Paul Kaplan <pkaplan@media.mit.edu>
Date: Mon, 12 Jun 2017 08:35:27 -0400
Subject: [PATCH 11/11] Enhance sprite delete behavior

---
 src/virtual-machine.js | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/virtual-machine.js b/src/virtual-machine.js
index 436ff60e8..12e6e7a77 100644
--- a/src/virtual-machine.js
+++ b/src/virtual-machine.js
@@ -364,6 +364,8 @@ class VirtualMachine extends EventEmitter {
      */
     deleteSprite (targetId) {
         const target = this.runtime.getTargetById(targetId);
+        const targetIndexBeforeDelete = this.runtime.targets.map(t => t.id).indexOf(target.id);
+
         if (target) {
             if (!target.isSprite()) {
                 throw new Error('Cannot delete non-sprite targets.');
@@ -379,8 +381,8 @@ class VirtualMachine extends EventEmitter {
                 this.runtime.disposeTarget(sprite.clones[i]);
                 // Ensure editing target is switched if we are deleting it.
                 if (clone === currentEditingTarget) {
-                    const lastTargetIndex = this.runtime.targets.length - 1;
-                    this.setEditingTarget(this.runtime.targets[lastTargetIndex].id);
+                    const nextTargetIndex = Math.min(this.runtime.targets.length - 1, targetIndexBeforeDelete);
+                    this.setEditingTarget(this.runtime.targets[nextTargetIndex].id);
                 }
             }
             // Sprite object should be deleted by GC.