fetch pxt-microbit v2.2.30 (#102)

* undo buttonEvent

* fetch microbit v2.2.30

Co-authored-by: Amerlander <gitkraken@juriwolf.de>
This commit is contained in:
Amerlander 2020-05-08 18:35:38 +02:00 committed by GitHub
parent 53fae2fac5
commit 64471a53f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 544 additions and 1442 deletions

8
.github/lock.yml vendored
View File

@ -30,13 +30,7 @@ lockLabel: false
# Comment to post before locking. Set to `false` to disable
lockComment: >
This thread has been automatically locked since there has not been
any recent activity after it was closed. Please open a new issue for
related bugs.
lockComment: false

3
.gitignore vendored
View File

@ -33,4 +33,5 @@ crowdinstats.csv
*.iml
.vscode/.BROWSE.VC.DB-shm
.vscode/.BROWSE.VC.DB-wal
package-lock.json
package-lock.json
.DS_Store

View File

@ -4,6 +4,6 @@ Generate a random coordinate and display it on the LED screen.
```blocks
basic.forever(() => {
led.toggle(Math.randomRange(0, 5), Math.randomRange(0, 5))
led.toggle(Math.randomRange(0, 4), Math.randomRange(0, 4))
})
```

View File

@ -3,7 +3,6 @@
## Introduction @unplugged
Make a love meter, how sweet! The @boardname@ is feeling the love, then sometimes not so much!
Tell everyone who you are. Show you name on the LEDs.
![Love meter banner message](/calliope/tutorials/05_love_meter_animation.gif)

View File

@ -8,13 +8,19 @@ Snap the dot is a game of skill where the player has to press **A** exactly when
This tutorial shows how to use the game engine.
## Create a sprite @fullscreen
## Make a sprite variable @fullscreen
Drag a ``||game:create sprite||`` block onto the workspace. A sprite is a single pixel that can move on the screen. It has an ``x`` and ``y`` position along with a direction of motion.
Create a new variable called `sprite`. Drag a ``||variables:set sprite to||`` into the ``||basic:on start||`` on the workspace.
```blocks
let sprite: game.LedSprite = null
sprite = game.createSprite(2, 2)
let sprite = 0
```
## Create a sprite @fullscreen
Pull out a ``||game:create sprite||`` block and put it in ``||variables:set sprite to||`` replacing the `0`. A sprite is a single pixel that can move on the screen. It has an ``x`` and ``y`` position along with a direction of motion.
```blocks
let sprite = game.createSprite(2, 2)
```
## Move the dot @fullscreen
@ -22,8 +28,7 @@ sprite = game.createSprite(2, 2)
The sprite starts in the center facing right. Put a ``||game:move||`` block into the ``||basic:forever||`` to make it move. Notice how it moves to the right but does not bounce back.
```blocks
let sprite: game.LedSprite = null
sprite = game.createSprite(2, 2)
let sprite = game.createSprite(2, 2)
basic.forever(function () {
sprite.move(1)
})
@ -34,8 +39,7 @@ basic.forever(function () {
Grab a ``||game:if on edge, bounce||`` block to make the sprite bounce on the side of the screen. Also, add a ``||basic:pause||`` block to slow down the sprite.
```blocks
let sprite: game.LedSprite = null
sprite = game.createSprite(2, 2)
let sprite = game.createSprite(2, 2)
basic.forever(function () {
sprite.move(1)
sprite.ifOnEdgeBounce()
@ -54,13 +58,12 @@ When **A** is pressed, we test if the sprite is in the center or not.
Use a ``||input:on button pressed||`` block to handle the **A** button. Put in a ``||logic:if||`` block and test if ``||game:x||`` is equal to `2`.
```blocks
let sprite: game.LedSprite = null
let sprite = game.createSprite(2, 2)
input.onButtonPressed(Button.A, function () {
if (sprite.get(LedSpriteProperty.X) == 2) {
} else {
}
})
sprite = game.createSprite(2, 2)
basic.forever(function () {
sprite.move(1)
basic.pause(100)
@ -73,7 +76,7 @@ basic.forever(function () {
Finally, pull out an ``||game:add score||`` and a ``||game:game over||`` block to handle both success (sprite in the center) and failure (sprite not in the center).
```blocks
let sprite: game.LedSprite = null
let sprite = game.createSprite(2, 2)
input.onButtonPressed(Button.A, function () {
if (sprite.get(LedSpriteProperty.X) == 2) {
game.addScore(1)
@ -81,7 +84,6 @@ input.onButtonPressed(Button.A, function () {
game.gameOver()
}
})
sprite = game.createSprite(2, 2)
basic.forever(function () {
sprite.move(1)
basic.pause(100)

View File

@ -17,6 +17,15 @@ A bar graph is a kind of chart that shows numbers as lines with different length
* **high**: a [number](/types/number) that is the highest
possible number (maximum) that the **value** parameter can be. The lines in the bar graph will reach their highest point when **value** reaches this number. If **high** is `0`, then the largest value recently plotted is used as the maximum.
### ~hint
#### Serial Output
The ``||led:plot bar graph||`` block also writes the number from **value** to the [serial](/reference/serial) port as a way to help you record
values.
### ~
## Example: chart acceleration
Show a bar graph of the [acceleration](/reference/input/acceleration)

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -89,8 +89,8 @@
"Gesture.FreeFall": "Raised when the board is falling!",
"Gesture.LogoDown": "Raised when the logo is downward and the screen is vertical",
"Gesture.LogoUp": "Raised when the logo is upward and the screen is vertical",
"Gesture.ScreenDown": "Raised when the screen is pointing up and the board is horizontal",
"Gesture.ScreenUp": "Raised when the screen is pointing down and the board is horizontal",
"Gesture.ScreenDown": "Raised when the screen is pointing down and the board is horizontal",
"Gesture.ScreenUp": "Raised when the screen is pointing up and the board is horizontal",
"Gesture.Shake": "Raised when shaken",
"Gesture.SixG": "Raised when a 6G shock is detected",
"Gesture.ThreeG": "Raised when a 3G shock is detected",
@ -273,6 +273,8 @@
"control.eventValue": "Gets the value of the last event executed on the bus",
"control.eventValueId": "Returns the value of a C++ runtime constant",
"control.inBackground": "Schedules code that run in the background.",
"control.micros": "Gets current time in microseconds. Overflows every ~18 minutes.",
"control.millis": "Gets the number of milliseconds elapsed since power on.",
"control.onEvent": "Registers an event handler.",
"control.panic": "Display specified error code and stop the program.",
"control.raiseEvent": "Raises an event in the event bus.",
@ -281,6 +283,7 @@
"control.raiseEvent|param|value": "Component specific code indicating the cause of the event.",
"control.reset": "Resets the BBC micro:bit.",
"control.runtimeWarning": "Display warning in the simulator.",
"control.waitForEvent": "Blocks the calling thread until the specified event is raised.",
"control.waitMicros": "Blocks the current fiber for the given microseconds",
"control.waitMicros|param|micros": "number of micro-seconds to wait. eg: 4",
"convertToText": "Convert any value to text",
@ -467,9 +470,13 @@
"music.builtInMelody": "Gets the melody array of a built-in melody.",
"music.changeTempoBy": "Change the tempo by the specified amount",
"music.changeTempoBy|param|bpm": "The change in beats per minute to the tempo, eg: 20",
"music.melodyEditor": "Create a melody with the melody editor.",
"music.noteFrequency": "Get the frequency of a note.",
"music.noteFrequency|param|name": "the note name, eg: Note.C",
"music.onEvent": "Registers code to run on various melody events",
"music.playMelody": "Play a melody from the melody editor.",
"music.playMelody|param|melody": "- string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces, which will be played one at a time, ex: \"E D G F B A C5 B \"",
"music.playMelody|param|tempo": "- number in beats per minute (bpm), dictating how long each note will play for",
"music.playTone": "Plays a tone through pin ``P0`` for the given duration.",
"music.playTone|param|frequency": "pitch of the tone to play in Hertz (Hz), eg: Note.C",
"music.playTone|param|ms": "tone duration in milliseconds (ms)",

View File

@ -79,9 +79,9 @@
"Gesture.LogoDown|block": "logo down",
"Gesture.LogoUp": "Raised when the logo is upward and the screen is vertical",
"Gesture.LogoUp|block": "logo up",
"Gesture.ScreenDown": "Raised when the screen is pointing up and the board is horizontal",
"Gesture.ScreenDown": "Raised when the screen is pointing down and the board is horizontal",
"Gesture.ScreenDown|block": "screen down",
"Gesture.ScreenUp": "Raised when the screen is pointing down and the board is horizontal",
"Gesture.ScreenUp": "Raised when the screen is pointing up and the board is horizontal",
"Gesture.ScreenUp|block": "screen up",
"Gesture.Shake": "Raised when shaken",
"Gesture.Shake|block": "shake",
@ -262,9 +262,11 @@
"control.eventValueId|block": "%id",
"control.eventValue|block": "event value",
"control.inBackground|block": "run in background",
"control.millis|block": "millis (ms)",
"control.onEvent|block": "on event|from %src=control_event_source_id|with value %value=control_event_value_id",
"control.raiseEvent|block": "raise event|from source %src=control_event_source_id|with value %value=control_event_value_id",
"control.reset|block": "reset",
"control.waitForEvent|block": "wait for event|from %src|with value %value",
"control.waitMicros|block": "wait (µs)%micros",
"control|block": "control",
"convertToText|block": "convert $value=math_number to text",
@ -338,8 +340,10 @@
"music.beginMelody|block": "start melody %melody=device_builtin_melody| repeating %options",
"music.builtInMelody|block": "%melody",
"music.changeTempoBy|block": "change tempo by (bpm)|%value",
"music.melodyEditor|block": "$melody",
"music.noteFrequency|block": "%name",
"music.onEvent|block": "music on %value",
"music.playMelody|block": "play melody $melody at tempo $tempo|(bpm)",
"music.playTone|block": "play|tone %note=device_note|for %duration=device_beat",
"music.rest|block": "rest(ms)|%duration=device_beat",
"music.ringTone|block": "ring tone (Hz)|%note=device_note",

View File

@ -223,6 +223,23 @@ namespace control {
release_fiber();
}
/**
* Gets the number of milliseconds elapsed since power on.
*/
//% help=control/millis weight=50
//% blockId=control_running_time block="millis (ms)"
int millis() {
return system_timer_current_time();
}
/**
* Gets current time in microseconds. Overflows every ~18 minutes.
*/
//%
int micros() {
return system_timer_current_time_us() & 0x3fffffff;
}
/**
* Schedules code that run in the background.
*/
@ -232,6 +249,15 @@ namespace control {
runInParallel(a);
}
/**
* Blocks the calling thread until the specified event is raised.
*/
//% help=control/wait-for-event async
//% blockId=control_wait_for_event block="wait for event|from %src|with value %value"
void waitForEvent(int src, int value) {
pxt::waitForEvent(src, value);
}
/**
* Resets the BBC micro:bit.
*/

View File

@ -111,13 +111,13 @@ declare namespace basic {
//% jres=gestures.tiltbackwards
LogoDown = 2, // MICROBIT_ACCELEROMETER_EVT_TILT_DOWN
/**
* Raised when the screen is pointing down and the board is horizontal
* Raised when the screen is pointing up and the board is horizontal
*/
//% block="screen up"
//% jres=gestures.frontsideup
ScreenUp = 5, // MICROBIT_ACCELEROMETER_EVT_FACE_UP
/**
* Raised when the screen is pointing up and the board is horizontal
* Raised when the screen is pointing down and the board is horizontal
*/
//% block="screen down"
//% jres=gestures.backsideup

View File

@ -75,13 +75,13 @@ enum class Gesture {
//% jres=gestures.tiltbackwards
LogoDown = MICROBIT_ACCELEROMETER_EVT_TILT_DOWN,
/**
* Raised when the screen is pointing down and the board is horizontal
* Raised when the screen is pointing up and the board is horizontal
*/
//% block="screen up"
//% jres=gestures.frontsideup
ScreenUp = MICROBIT_ACCELEROMETER_EVT_FACE_UP,
/**
* Raised when the screen is pointing up and the board is horizontal
* Raised when the screen is pointing down and the board is horizontal
*/
//% block="screen down"
//% jres=gestures.backsideup
@ -363,26 +363,6 @@ namespace input {
return 0;
}
/**
* Gets the number of milliseconds elapsed since power on.
*/
//% help=input/running-time weight=50 blockGap=8
//% blockId=device_get_running_time block="running time (ms)"
//% advanced=true
int runningTime() {
return system_timer_current_time();
}
/**
* Gets the number of microseconds elapsed since power on.
*/
//% help=input/running-time-micros weight=49
//% blockId=device_get_running_time_micros block="running time (micros)"
//% advanced=true
int runningTimeMicros() {
return system_timer_current_time_us();
}
/**
* Obsolete, compass calibration is automatic.
*/

View File

@ -55,4 +55,25 @@ namespace input {
export function calibrate() {
input.calibrateCompass();
}
/**
* Gets the number of milliseconds elapsed since power on.
*/
//% help=input/running-time weight=50 blockGap=8
//% blockId=device_get_running_time block="running time (ms)"
//% advanced=true
export function runningTime() {
return control.millis();
}
/**
* Gets the number of microseconds elapsed since power on.
*/
//% help=input/running-time-micros weight=49
//% blockId=device_get_running_time_micros block="running time (micros)"
//% advanced=true
export function runningTimeMicros() {
return control.micros();
}
}

View File

@ -174,6 +174,8 @@ enum MusicEvent {
*/
//% color=#DF4600 weight=98 icon="\uf025"
namespace music {
const INTERNAL_MELODY_ENDED = 5;
let beatsPerMinute: number = 120;
//% whenUsed
const freqs = hex`
@ -358,14 +360,69 @@ namespace music {
currentBackgroundMelody = null;
control.raiseEvent(MICROBIT_MELODY_ID, MusicEvent.MelodyEnded);
control.raiseEvent(MICROBIT_MELODY_ID, MusicEvent.BackgroundMelodyResumed);
control.raiseEvent(MICROBIT_MELODY_ID, INTERNAL_MELODY_ENDED);
}
}
control.raiseEvent(MICROBIT_MELODY_ID, currentMelody.background ? MusicEvent.BackgroundMelodyEnded : MusicEvent.MelodyEnded);
if (!currentMelody.background)
control.raiseEvent(MICROBIT_MELODY_ID, INTERNAL_MELODY_ENDED);
currentMelody = null;
})
}
}
/**
* Play a melody from the melody editor.
* @param melody - string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces, which will be played one at a time, ex: "E D G F B A C5 B "
* @param tempo - number in beats per minute (bpm), dictating how long each note will play for
*/
//% block="play melody $melody at tempo $tempo|(bpm)" blockId=playMelody
//% weight=85 blockGap=8 help=music/play-melody
//% melody.shadow="melody_editor"
//% tempo.min=40 tempo.max=500
//% tempo.defl=120
//% parts=headphone
export function playMelody(melody: string, tempo: number) {
melody = melody || "";
setTempo(tempo);
let notes: string[] = melody.split(" ").filter(n => !!n);
let newOctave = false;
// build melody string, replace '-' with 'R' and add tempo
// creates format like "C5-174 B4 A G F E D C "
for (let i = 0; i < notes.length; i++) {
if (notes[i] === "-") {
notes[i] = "R";
} else if (notes[i] === "C5") {
newOctave = true;
} else if (newOctave) { // change the octave if necesary
notes[i] += "4";
newOctave = false;
}
}
music.beginMelody(notes, MelodyOptions.Once)
control.waitForEvent(MICROBIT_MELODY_ID, INTERNAL_MELODY_ENDED);
}
/**
* Create a melody with the melody editor.
* @param melody
*/
//% block="$melody" blockId=melody_editor
//% blockHidden = true
//% weight=85 blockGap=8
//% duplicateShadowOnDrag
//% melody.fieldEditor="melody"
//% melody.fieldOptions.decompileLiterals=true
//% melody.fieldOptions.decompileIndirectFixedInstances="true"
//% melody.fieldOptions.onParentBlock="true"
//% shim=TD_ID
export function melodyEditor(melody: string): string {
return melody;
}
/**
* Stops the melodies
* @param options which melody to stop

36
libs/core/shims.d.ts vendored
View File

@ -346,22 +346,6 @@ declare namespace input {
//% advanced=true shim=input::magneticForce
function magneticForce(dimension: Dimension): int32;
/**
* Gets the number of milliseconds elapsed since power on.
*/
//% help=input/running-time weight=50 blockGap=8
//% blockId=device_get_running_time block="running time (ms)"
//% advanced=true shim=input::runningTime
function runningTime(): int32;
/**
* Gets the number of microseconds elapsed since power on.
*/
//% help=input/running-time-micros weight=49
//% blockId=device_get_running_time_micros block="running time (micros)"
//% advanced=true shim=input::runningTimeMicros
function runningTimeMicros(): int32;
/**
* Obsolete, compass calibration is automatic.
*/
@ -388,6 +372,19 @@ declare namespace input {
//% advanced=true
declare namespace control {
/**
* Gets the number of milliseconds elapsed since power on.
*/
//% help=control/millis weight=50
//% blockId=control_running_time block="millis (ms)" shim=control::millis
function millis(): int32;
/**
* Gets current time in microseconds. Overflows every ~18 minutes.
*/
//% shim=control::micros
function micros(): int32;
/**
* Schedules code that run in the background.
*/
@ -395,6 +392,13 @@ declare namespace control {
//% blockId="control_in_background" block="run in background" blockGap=8 shim=control::inBackground
function inBackground(a: () => void): void;
/**
* Blocks the calling thread until the specified event is raised.
*/
//% help=control/wait-for-event async
//% blockId=control_wait_for_event block="wait for event|from %src|with value %value" shim=control::waitForEvent
function waitForEvent(src: int32, value: int32): void;
/**
* Resets the BBC micro:bit.
*/

View File

@ -1,12 +1,3 @@
{
"name": "radio-broadcast",
"description": "Adds new blocks for message communication in the radio category",
"files": [
"pxt.json",
"radio-broadcast.ts"
],
"dependencies": {
"core": "file:../core",
"radio": "file:../radio"
}
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/radio-broadcast"
}

View File

@ -1,39 +0,0 @@
namespace radio {
/**
* Gets the message code
*/
//% blockHidden=1 shim=ENUM_GET
//% blockId=radioMessageCode block="$msg" enumInitialMembers="message1"
//% enumName=RadioMessage enumMemberName=msg enumPromptHint="e.g. Start, Stop, Jump..."
//% enumIsHash=1
export function __message(msg: number): number {
return msg;
}
/**
* Broadcasts a message over radio
* @param msg
*/
//% blockId=radioBroadcastMessage block="radio send $msg"
//% msg.shadow=radioMessageCode draggableParameters
//% weight=200
//% blockGap=8
//% help=radio/send-message
export function sendMessage(msg: number): void {
// 0 is MICROBIT_EVT_ANY, shifting by 1
radio.raiseEvent(DAL.MES_BROADCAST_GENERAL_ID, msg + 1);
}
/**
* Registers code to run for a particular message
* @param msg
* @param handler
*/
//% blockId=radioOnMessageReceived block="on radio $msg received"
//% msg.shadow=radioMessageCode draggableParameters
//% weight=199
//% help=radio/on-received-message
export function onReceivedMessage(msg: number, handler: () => void) {
control.onEvent(DAL.MES_BROADCAST_GENERAL_ID, msg + 1, handler);
}
}

View File

@ -1,4 +0,0 @@
# radio
The radio library.

View File

@ -9,7 +9,7 @@
"radio._packetProperty": "Gets a packet property.",
"radio._packetProperty|param|type": "the packet property type, eg: PacketProperty.time",
"radio.onDataPacketReceived": "Deprecated. Use onDataReceived() instead\nRegisters code to run when the radio receives a packet. Also takes the\nreceived packet from the radio queue.",
"radio.onDataReceived": "Registers code to run when a packet is received over radio.",
"radio.onDataReceived": "Used internally by the library.",
"radio.onReceivedBuffer": "Registers code to run when the radio receives a buffer.",
"radio.onReceivedBufferDeprecated": "Registers code to run when the radio receives a buffer. Deprecated, use\nonReceivedBuffer instead.",
"radio.onReceivedNumber": "Registers code to run when the radio receives a number.",

View File

@ -1,19 +1,5 @@
{
"name": "radio",
"description": "The radio services",
"files": [
"README.md",
"shims.d.ts",
"enums.d.ts",
"radio.cpp",
"radio.ts",
"deprecated.ts"
],
"icon": "./static/packages/radio/icon.png",
"public": true,
"dependencies": {
"core": "file:../core"
},
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/radio",
"yotta": {
"config": {
"microbit-dal": {
@ -22,6 +8,5 @@
}
}
}
},
"installedVersion": "rlfgis"
}
}

View File

@ -1,126 +0,0 @@
#include "pxt.h"
using namespace pxt;
//% color=#E3008C weight=96 icon="\uf012"
namespace radio {
bool radioEnabled = false;
int radioEnable() {
int r = uBit.radio.enable();
if (r != MICROBIT_OK) {
uBit.panic(43);
return r;
}
if (!radioEnabled) {
uBit.radio.setGroup(pxt::programHash());
uBit.radio.setTransmitPower(6); // start with high power by default
radioEnabled = true;
}
return r;
}
/**
* Sends an event over radio to neigboring devices
*/
//% blockId=radioRaiseEvent block="radio raise event|from source %src=control_event_source_id|with value %value=control_event_value_id"
//% blockExternalInputs=1
//% advanced=true
//% weight=1
//% help=radio/raise-event
void raiseEvent(int src, int value) {
if (radioEnable() != MICROBIT_OK) return;
uBit.radio.event.eventReceived(MicroBitEvent(src, value, CREATE_ONLY));
}
/**
* Internal use only. Takes the next packet from the radio queue and returns its contents + RSSI in a Buffer
*/
//%
Buffer readRawPacket() {
if (radioEnable() != MICROBIT_OK) return mkBuffer(NULL, 0);
PacketBuffer p = uBit.radio.datagram.recv();
if (p == PacketBuffer::EmptyPacket)
return mkBuffer(NULL, 0);
int rssi = p.getRSSI();
uint8_t buf[MICROBIT_RADIO_MAX_PACKET_SIZE + sizeof(int)]; // packet length + rssi
memset(buf, 0, sizeof(buf));
memcpy(buf, p.getBytes(), p.length()); // data
memcpy(buf + MICROBIT_RADIO_MAX_PACKET_SIZE, &rssi, sizeof(int)); // RSSi - assumes Int32LE layout
return mkBuffer(buf, sizeof(buf));
}
/**
* Internal use only. Sends a raw packet through the radio (assumes RSSI appened to packet)
*/
//% async
void sendRawPacket(Buffer msg) {
if (radioEnable() != MICROBIT_OK || NULL == msg) return;
// don't send RSSI data; and make sure no buffer underflow
int len = msg->length - sizeof(int);
if (len > 0)
uBit.radio.datagram.send(msg->data, len);
}
/**
* Registers code to run when a packet is received over radio.
*/
//% help=radio/on-data-received
//% weight=50
//% blockId=radio_datagram_received_event block="radio on data received" blockGap=8
//% deprecated=true
void onDataReceived(Action body) {
if (radioEnable() != MICROBIT_OK) return;
registerWithDal(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, body);
uBit.radio.datagram.recv(); // wake up read code
}
/**
* Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time.
* @param id the group id between ``0`` and ``255``, eg: 1
*/
//% help=radio/set-group
//% weight=100
//% blockId=radio_set_group block="radio set group %ID"
//% id.min=0 id.max=255
void setGroup(int id) {
if (radioEnable() != MICROBIT_OK) return;
uBit.radio.setGroup(id);
}
/**
* Change the output power level of the transmitter to the given value.
* @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7
*/
//% help=radio/set-transmit-power
//% weight=9 blockGap=8
//% blockId=radio_set_transmit_power block="radio set transmit power %power"
//% power.min=0 power.max=7
//% advanced=true
void setTransmitPower(int power) {
if (radioEnable() != MICROBIT_OK) return;
uBit.radio.setTransmitPower(power);
}
/**
* Change the transmission and reception band of the radio to the given channel
* @param band a frequency band in the range 0 - 83. Each step is 1MHz wide, based at 2400MHz.
**/
//% help=radio/set-frequency-band
//% weight=8 blockGap=8
//% blockId=radio_set_frequency_band block="radio set frequency band %band"
//% band.min=0 band.max=83
//% advanced=true
void setFrequencyBand(int band) {
if (radioEnable() != MICROBIT_OK) return;
uBit.radio.setFrequencyBand(band);
}
}

View File

@ -1,444 +0,0 @@
enum RadioPacketProperty {
//% blockIdentity=radio._packetProperty
//% block="signal strength"
SignalStrength = 2,
//% blockIdentity=radio._packetProperty
//% block="time"
Time = 0,
//% block="serial number"
//% blockIdentity=radio._packetProperty
SerialNumber = 1
}
/**
* Communicate data using radio packets
*/
//% color=#E3008C weight=96 icon="\uf012"
namespace radio {
const MAX_FIELD_DOUBLE_NAME_LENGTH = 8;
const MAX_PAYLOAD_LENGTH = 20;
const PACKET_PREFIX_LENGTH = 9;
const VALUE_PACKET_NAME_LEN_OFFSET = 13;
const DOUBLE_VALUE_PACKET_NAME_LEN_OFFSET = 17;
// Packet Spec:
// | 0 | 1 ... 4 | 5 ... 8 | 9 ... 28
// ----------------------------------------------------------------
// | packet type | system time | serial number | payload
//
// Serial number defaults to 0 unless enabled by user
// payload: number (9 ... 12)
const PACKET_TYPE_NUMBER = 0;
// payload: number (9 ... 12), name length (13), name (14 ... 26)
const PACKET_TYPE_VALUE = 1;
// payload: string length (9), string (10 ... 28)
const PACKET_TYPE_STRING = 2;
// payload: buffer length (9), buffer (10 ... 28)
const PACKET_TYPE_BUFFER = 3;
// payload: number (9 ... 16)
const PACKET_TYPE_DOUBLE = 4;
// payload: number (9 ... 16), name length (17), name (18 ... 26)
const PACKET_TYPE_DOUBLE_VALUE = 5;
let transmittingSerial: boolean;
let initialized = false;
export let lastPacket: RadioPacket;
let onReceivedNumberHandler: (receivedNumber: number) => void;
let onReceivedValueHandler: (name: string, value: number) => void;
let onReceivedStringHandler: (receivedString: string) => void;
let onReceivedBufferHandler: (receivedBuffer: Buffer) => void;
function init() {
if (initialized) return;
initialized = true;
onDataReceived(handleDataReceived);
}
function handleDataReceived() {
let buffer: Buffer = readRawPacket();
while (buffer && buffer.length) {
lastPacket = RadioPacket.getPacket(buffer);
switch (lastPacket.packetType) {
case PACKET_TYPE_NUMBER:
case PACKET_TYPE_DOUBLE:
if (onReceivedNumberHandler)
onReceivedNumberHandler(lastPacket.numberPayload);
break;
case PACKET_TYPE_VALUE:
case PACKET_TYPE_DOUBLE_VALUE:
if (onReceivedValueHandler)
onReceivedValueHandler(lastPacket.stringPayload, lastPacket.numberPayload);
break;
case PACKET_TYPE_BUFFER:
if (onReceivedBufferHandler)
onReceivedBufferHandler(lastPacket.bufferPayload);
break;
case PACKET_TYPE_STRING:
if (onReceivedStringHandler)
onReceivedStringHandler(lastPacket.stringPayload);
break;
}
// read next packet if any
buffer = readRawPacket();
}
}
/**
* Registers code to run when the radio receives a number.
*/
//% help=radio/on-received-number
//% blockId=radio_on_number_drag block="on radio received" blockGap=16
//% useLoc="radio.onDataPacketReceived" draggableParameters=reporter
export function onReceivedNumber(cb: (receivedNumber: number) => void) {
init();
onReceivedNumberHandler = cb;
}
/**
* Registers code to run when the radio receives a key value pair.
*/
//% help=radio/on-received-value
//% blockId=radio_on_value_drag block="on radio received" blockGap=16
//% useLoc="radio.onDataPacketReceived" draggableParameters=reporter
export function onReceivedValue(cb: (name: string, value: number) => void) {
init();
onReceivedValueHandler = cb;
}
/**
* Registers code to run when the radio receives a string.
*/
//% help=radio/on-received-string
//% blockId=radio_on_string_drag block="on radio received" blockGap=16
//% useLoc="radio.onDataPacketReceived" draggableParameters=reporter
export function onReceivedString(cb: (receivedString: string) => void) {
init();
onReceivedStringHandler = cb;
}
/**
* Registers code to run when the radio receives a buffer.
*/
//% help=radio/on-received-buffer blockHidden=1
//% blockId=radio_on_buffer_drag block="on radio received" blockGap=16
//% useLoc="radio.onDataPacketReceived" draggableParameters=reporter
export function onReceivedBuffer(cb: (receivedBuffer: Buffer) => void) {
init();
onReceivedBufferHandler = cb;
}
/**
* Returns properties of the last radio packet received.
* @param type the type of property to retrieve from the last packet
*/
//% help=radio/received-packet
//% weight=11 blockGap=8
//% blockId=radio_received_packet block="received packet %type=radio_packet_property" blockGap=16
export function receivedPacket(type: number) {
if (lastPacket) {
switch (type) {
case RadioPacketProperty.Time: return lastPacket.time;
case RadioPacketProperty.SerialNumber: return lastPacket.serial;
case RadioPacketProperty.SignalStrength: return lastPacket.signal;
}
}
return 0;
}
/**
* Gets a packet property.
* @param type the packet property type, eg: PacketProperty.time
*/
//% blockId=radio_packet_property block="%note"
//% shim=TD_ID blockHidden=1
export function _packetProperty(type: RadioPacketProperty): number {
return type;
}
export class RadioPacket {
public static getPacket(data: Buffer) {
// last 4 bytes is RSSi
return new RadioPacket(data);
}
public static mkPacket(packetType: number) {
const res = new RadioPacket();
res.data[0] = packetType;
return res;
}
private constructor(public readonly data?: Buffer) {
if (!data) this.data = control.createBuffer(DAL.MICROBIT_RADIO_MAX_PACKET_SIZE + 4);
}
get signal() {
return this.data.getNumber(NumberFormat.Int32LE, this.data.length - 4);
}
get packetType() {
return this.data[0];
}
get time() {
return this.data.getNumber(NumberFormat.Int32LE, 1);
}
set time(val: number) {
this.data.setNumber(NumberFormat.Int32LE, 1, val);
}
get serial() {
return this.data.getNumber(NumberFormat.Int32LE, 5);
}
set serial(val: number) {
this.data.setNumber(NumberFormat.Int32LE, 5, val);
}
get stringPayload() {
const offset = getStringOffset(this.packetType) as number;
return offset ? this.data.slice(offset + 1, this.data[offset]).toString() : undefined;
}
set stringPayload(val: string) {
const offset = getStringOffset(this.packetType) as number;
if (offset) {
const buf = control.createBufferFromUTF8(truncateString(val, getMaxStringLength(this.packetType)));
this.data[offset] = buf.length;
this.data.write(offset + 1, buf);
}
}
get numberPayload() {
switch (this.packetType) {
case PACKET_TYPE_NUMBER:
case PACKET_TYPE_VALUE:
return this.data.getNumber(NumberFormat.Int32LE, PACKET_PREFIX_LENGTH);
case PACKET_TYPE_DOUBLE:
case PACKET_TYPE_DOUBLE_VALUE:
return this.data.getNumber(NumberFormat.Float64LE, PACKET_PREFIX_LENGTH);
}
return undefined;
}
set numberPayload(val: number) {
switch (this.packetType) {
case PACKET_TYPE_NUMBER:
case PACKET_TYPE_VALUE:
this.data.setNumber(NumberFormat.Int32LE, PACKET_PREFIX_LENGTH, val);
break;
case PACKET_TYPE_DOUBLE:
case PACKET_TYPE_DOUBLE_VALUE:
this.data.setNumber(NumberFormat.Float64LE, PACKET_PREFIX_LENGTH, val);
break;
}
}
get bufferPayload() {
const len = this.data[PACKET_PREFIX_LENGTH];
return this.data.slice(PACKET_PREFIX_LENGTH + 1, len);
}
set bufferPayload(b: Buffer) {
const len = Math.min(b.length, MAX_PAYLOAD_LENGTH - 1);
this.data[PACKET_PREFIX_LENGTH] = len;
this.data.write(PACKET_PREFIX_LENGTH + 1, b.slice(0, len));
}
hasString() {
return this.packetType === PACKET_TYPE_STRING ||
this.packetType === PACKET_TYPE_VALUE ||
this.packetType === PACKET_TYPE_DOUBLE_VALUE;
}
hasNumber() {
return this.packetType === PACKET_TYPE_NUMBER ||
this.packetType === PACKET_TYPE_DOUBLE ||
this.packetType === PACKET_TYPE_VALUE ||
this.packetType === PACKET_TYPE_DOUBLE_VALUE;
}
}
/**
* Broadcasts a number over radio to any connected micro:bit in the group.
*/
//% help=radio/send-number
//% weight=60
//% blockId=radio_datagram_send block="radio send number %value" blockGap=8
export function sendNumber(value: number) {
let packet: RadioPacket;
if (value === (value | 0)) {
packet = RadioPacket.mkPacket(PACKET_TYPE_NUMBER);
}
else {
packet = RadioPacket.mkPacket(PACKET_TYPE_DOUBLE);
}
packet.numberPayload = value;
sendPacket(packet);
}
/**
* Broadcasts a name / value pair along with the device serial number
* and running time to any connected micro:bit in the group. The name can
* include no more than 8 characters.
* @param name the field name (max 8 characters), eg: "name"
* @param value the numeric value
*/
//% help=radio/send-value
//% weight=59
//% blockId=radio_datagram_send_value block="radio send|value %name|= %value" blockGap=8
export function sendValue(name: string, value: number) {
let packet: RadioPacket;
if (value === (value | 0)) {
packet = RadioPacket.mkPacket(PACKET_TYPE_VALUE);
}
else {
packet = RadioPacket.mkPacket(PACKET_TYPE_DOUBLE_VALUE);
}
packet.numberPayload = value;
packet.stringPayload = name;
sendPacket(packet);
}
/**
* Broadcasts a string along with the device serial number
* and running time to any connected micro:bit in the group.
*/
//% help=radio/send-string
//% weight=58
//% blockId=radio_datagram_send_string block="radio send string %msg"
//% msg.shadowOptions.toString=true
export function sendString(value: string) {
const packet = RadioPacket.mkPacket(PACKET_TYPE_STRING);
packet.stringPayload = value;
sendPacket(packet);
}
/**
* Broadcasts a buffer (up to 19 bytes long) along with the device serial number
* and running time to any connected micro:bit in the group.
*/
//% help=radio/send-buffer
//% weight=57
//% advanced=true
export function sendBuffer(msg: Buffer) {
const packet = RadioPacket.mkPacket(PACKET_TYPE_BUFFER);
packet.bufferPayload = msg;
sendPacket(packet);
}
/**
* Writes the last received packet to serial as JSON. This should be called
* within an ``onDataPacketReceived`` callback.
*/
//% help=radio/write-received-packet-to-serial
//% weight=3
//% blockId=radio_write_packet_serial block="radio write received packet to serial"
//% advanced=true
export function writeReceivedPacketToSerial() {
if (lastPacket) writeToSerial(lastPacket)
}
/**
* Set the radio to transmit the serial number in each message.
* @param transmit value indicating if the serial number is transmitted, eg: true
*/
//% help=radio/set-transmit-serial-number
//% weight=8 blockGap=8
//% blockId=radio_set_transmit_serial_number block="radio set transmit serial number %transmit"
//% advanced=true
export function setTransmitSerialNumber(transmit: boolean) {
transmittingSerial = transmit;
}
/**
* Gets the received signal strength indicator (RSSI) from the last packet taken
* from the radio queue (via ``receiveNumber``, ``receiveString``, etc). Not supported in simulator.
*/
//% help=radio/received-signal-strength
//% weight=40
//% blockId=radio_datagram_rssi block="radio received signal strength"
//% deprecated=true blockHidden=true
export function receivedSignalStrength(): number {
return lastPacket ? lastPacket.signal : 0;
}
export function writeToSerial(packet: RadioPacket) {
serial.writeString("{");
serial.writeString("\"t\":");
serial.writeString("" + packet.time);
serial.writeString(",\"s\":");
serial.writeString("" + packet.serial);
if (packet.hasString()) {
serial.writeString(",\"n\":\"");
serial.writeString(packet.stringPayload);
serial.writeString("\"");
}
if (packet.packetType == PACKET_TYPE_BUFFER) {
serial.writeString(",\"b\":\"");
// TODO: proper base64 encoding
serial.writeString(packet.bufferPayload.toString());
serial.writeString("\"");
}
if (packet.hasNumber()) {
serial.writeString(",\"v\":");
serial.writeString("" + packet.numberPayload);
}
serial.writeString("}\r\n");
}
function sendPacket(packet: RadioPacket) {
packet.time = input.runningTime();
packet.serial = transmittingSerial ? control.deviceSerialNumber() : 0;
radio.sendRawPacket(packet.data);
}
function truncateString(str: string, bytes: number) {
str = str.substr(0, bytes);
let buff = control.createBufferFromUTF8(str);
while (buff.length > bytes) {
str = str.substr(0, str.length - 1);
buff = control.createBufferFromUTF8(str);
}
return str;
}
function getStringOffset(packetType: number) {
switch (packetType) {
case PACKET_TYPE_STRING:
return PACKET_PREFIX_LENGTH;
case PACKET_TYPE_VALUE:
return VALUE_PACKET_NAME_LEN_OFFSET;
case PACKET_TYPE_DOUBLE_VALUE:
return DOUBLE_VALUE_PACKET_NAME_LEN_OFFSET;
default:
return undefined;
}
}
function getMaxStringLength(packetType: number) {
switch (packetType) {
case PACKET_TYPE_STRING:
return MAX_PAYLOAD_LENGTH - 2;
case PACKET_TYPE_VALUE:
case PACKET_TYPE_DOUBLE_VALUE:
return MAX_FIELD_DOUBLE_NAME_LENGTH;
default:
return undefined;
}
}
}

View File

@ -28,12 +28,12 @@ declare namespace radio {
function sendRawPacket(msg: Buffer): void;
/**
* Registers code to run when a packet is received over radio.
* Used internally by the library.
*/
//% help=radio/on-data-received
//% weight=50
//% weight=0
//% blockId=radio_datagram_received_event block="radio on data received" blockGap=8
//% deprecated=true shim=radio::onDataReceived
//% deprecated=true blockHidden=1 shim=radio::onDataReceived
function onDataReceived(body: () => void): void;
/**

View File

@ -97,19 +97,6 @@ namespace radio {
onReceivedBuffer(cb);
}
/**
* Reads the next packet from the radio queue and and writes it to serial
* as JSON.
*/
//% help=radio/write-value-to-serial
//% weight=3
//% blockId=radio_write_value_serial block="radio write value to serial"
//% deprecated=true
export function writeValueToSerial() {
const p = RadioPacket.getPacket(radio.readRawPacket());
writeToSerial(p);
}
/**
* Returns the number payload from the last packet taken from the radio queue
* (via ``receiveNumber``, ``receiveString``, etc) or 0 if that packet did not
@ -185,4 +172,67 @@ namespace radio {
lastPacket = RadioPacket.getPacket(readRawPacket());
return receivedString();
}
/**
* Gets the received signal strength indicator (RSSI) from the last packet taken
* from the radio queue (via ``receiveNumber``, ``receiveString``, etc). Not supported in simulator.
*/
//% help=radio/received-signal-strength
//% weight=40
//% blockId=radio_datagram_rssi block="radio received signal strength"
//% deprecated=true blockHidden=true
export function receivedSignalStrength(): number {
return lastPacket ? lastPacket.signal : 0;
}
/**
* Reads the next packet from the radio queue and and writes it to serial
* as JSON.
*/
//% help=radio/write-value-to-serial
//% weight=3
//% blockId=radio_write_value_serial block="radio write value to serial"
//% deprecated=true
export function writeValueToSerial() {
const p = RadioPacket.getPacket(radio.readRawPacket());
writeToSerial(p);
}
/**
* Writes the last received packet to serial as JSON. This should be called
* within an ``onDataPacketReceived`` callback.
*/
//% help=radio/write-received-packet-to-serial
//% weight=3
//% blockId=radio_write_packet_serial block="radio write received packet to serial"
//% advanced=true deprecated=true
export function writeReceivedPacketToSerial() {
if (lastPacket) writeToSerial(lastPacket)
}
function writeToSerial(packet: RadioPacket) {
serial.writeString("{");
serial.writeString("\"t\":");
serial.writeString("" + packet.time);
serial.writeString(",\"s\":");
serial.writeString("" + packet.serial);
if (packet.hasString()) {
serial.writeString(",\"n\":\"");
serial.writeString(packet.stringPayload);
serial.writeString("\"");
}
if (packet.packetType == PACKET_TYPE_BUFFER) {
serial.writeString(",\"b\":\"");
// TODO: proper base64 encoding
serial.writeString(packet.bufferPayload.toString());
serial.writeString("\"");
}
if (packet.hasNumber()) {
serial.writeString(",\"v\":");
serial.writeString("" + packet.numberPayload);
}
serial.writeString("}\r\n");
}
}

View File

@ -1,349 +0,0 @@
/**
* Tests for the radio. Press A on mbit 1 and B on mbit 2 to run the tests.
* Sends random ints, doubles, strings, and buffers and checks them on
* the other side
*/
class FastRandom {
private lfsr: number;
public seed: number;
constructor(seed?: number) {
if (seed === undefined) seed = Math.randomRange(0x0001, 0xFFFF);
this.seed = seed;
this.lfsr = seed;
}
next(): number {
return this.lfsr = (this.lfsr >> 1) ^ ((-(this.lfsr & 1)) & 0xb400);
}
randomRange(min: number, max: number): number {
return min + (max > min ? this.next() % (max - min + 1) : 0);
}
reset() {
this.lfsr = this.seed;
}
}
enum TestStage {
Integer,
String,
Double,
IntValue,
DblValue,
Buffer
}
const TEST_COUNT = 30;
radio.setGroup(78)
const rand = new FastRandom(1234);
let stage = TestStage.Integer;
function initSender() {
let lastReceived: number;
let lastString: string;
let testIndex = 0;
let lastBuf: Buffer;
let lastAck = -1;
rand.reset();
basic.clearScreen();
// Send loop
control.inBackground(function () {
while (true) {
for (let i = 0; i < TEST_COUNT; i++) {
toggle(testIndex);
if (stage === TestStage.Integer) {
lastReceived = getNextInt();
}
else if (stage === TestStage.Double) {
lastReceived = getNextDouble();
}
else if (stage === TestStage.IntValue) {
lastString = getNextName();
console.log(truncateString(lastString, 8))
lastReceived = getNextInt();
}
else if (stage === TestStage.DblValue) {
lastString = getNextName();
lastReceived = getNextDouble();
}
else if (stage === TestStage.String) {
lastString = getNextString();
console.log(truncateString(lastString, 19))
}
else if (stage === TestStage.Buffer) {
lastBuf = getNextBuffer();
}
while (lastAck !== testIndex) {
if (stage === TestStage.Integer || stage === TestStage.Double) {
radio.sendNumber(lastReceived)
}
else if (stage === TestStage.IntValue || stage === TestStage.DblValue) {
radio.sendValue(lastString, lastReceived)
}
else if (stage === TestStage.String) {
radio.sendString(lastString);
}
else if (stage === TestStage.Buffer) {
radio.sendBuffer(lastBuf);
}
basic.pause(10);
}
testIndex++;
}
stage++;
if (stage > TestStage.Buffer) {
basic.showIcon(IconNames.Yes);
return;
}
}
})
radio.onReceivedNumber(function (receivedNumber: number) {
if (receivedNumber > lastAck) {
lastAck = receivedNumber;
}
});
}
let lastReceived: number;
let lastString: string;
let testIndex = -1;
let running = true;
let lastBuf: Buffer;
let lastPacket = new radio.Packet();
let currentPacket = new radio.Packet();
function truncateString(str: string, bytes: number) {
str = str.substr(0, bytes);
let buff = control.createBufferFromUTF8(str);
while (buff.length > bytes) {
str = str.substr(0, str.length - 1);
buff = control.createBufferFromUTF8(str);
}
return str;
}
function initReceiver() {
rand.reset();
basic.clearScreen();
radio.onDataReceived(function () {
radio.receiveNumber();
currentPacket.receivedNumber = radio.receivedNumber();
currentPacket.receivedString = radio.receivedString();
currentPacket.receivedBuffer = radio.receivedBuffer();
if (currentPacket.receivedNumber === lastPacket.receivedNumber &&
currentPacket.receivedString === lastPacket.receivedString &&
checkBufferEqual(currentPacket.receivedBuffer, lastPacket.receivedBuffer)) {
return;
}
lastPacket.receivedNumber = currentPacket.receivedNumber
lastPacket.receivedString = currentPacket.receivedString
lastPacket.receivedBuffer = currentPacket.receivedBuffer
switch (stage) {
case TestStage.Integer:
verifyInt(radio.receivedNumber());
break;
case TestStage.Double:
verifyDouble(radio.receivedNumber());
break;
case TestStage.IntValue:
verifyIntValue(radio.receivedString(), radio.receivedNumber());
break;
case TestStage.DblValue:
verifyDblValue(radio.receivedString(), radio.receivedNumber());
break;
case TestStage.String:
verifyString(radio.receivedString());
break;
case TestStage.Buffer:
verifyBuffer(radio.receivedBuffer());
break;
}
})
control.inBackground(function () {
while (running) {
radio.sendNumber(testIndex);
basic.pause(10)
}
})
}
function nextTest() {
testIndex++;
toggle(testIndex);
console.log(`test ${testIndex}`)
if (((testIndex + 1) % TEST_COUNT) === 0) {
stage++;
if (stage > TestStage.Buffer) {
basic.showIcon(IconNames.Yes)
running = false;
}
}
}
function verifyInt(int: number) {
if (int === lastReceived) return;
lastReceived = int;
if (lastReceived != getNextInt()) fail();
nextTest()
}
function verifyDouble(dbl: number) {
if (dbl === lastReceived) return;
lastReceived = dbl;
if (lastReceived != getNextDouble()) fail();
nextTest()
}
function verifyIntValue(name: string, val: number) {
if (val === lastReceived) return;
lastReceived = val;
if (name != truncateString(getNextName(), 8) || lastReceived != getNextInt()) fail();
nextTest()
}
function verifyDblValue(name: string, val: number) {
if (val === lastReceived) return;
lastReceived = val;
if (name != truncateString(getNextName(), 8) || lastReceived != getNextDouble()) fail();
nextTest()
}
function verifyString(str: string) {
if (!str || str === lastString) return;
lastString = str;
let next = truncateString(getNextString(), 19);
if (lastString !== next) {
console.log(`got ${control.createBufferFromUTF8(lastString).toHex()} expected ${control.createBufferFromUTF8(next).toHex()}`)
}
nextTest()
}
function verifyBuffer(buf: Buffer) {
if (checkBufferEqual(lastBuf, buf)) return;
lastBuf = buf;
if (!checkBufferEqual(lastBuf, getNextBuffer())) {
fail();
}
nextTest()
}
function fail() {
control.panic(testIndex);
}
let _lastInt: number;
let _lastDbl: number;
let _lastStr: string;
let _lastBuf: Buffer;
let _lastNam: string;
function getNextInt(): number {
let res = rand.next();
if (!res || res === _lastInt) return getNextInt();
_lastInt = res;
return res;
}
function getNextDouble(): number {
let res = rand.next() / rand.next();
if (res === _lastDbl) return getNextDouble();
_lastDbl = res;
return res;
}
function getNextString(): string {
let len = rand.randomRange(1, 19);
let res = "";
for (let i = 0; i < len; i++) {
res += String.fromCharCode(rand.next() & 0xbfff);
}
if (res === _lastStr) return getNextString();
_lastStr = res;
return res;
}
function getNextName(): string {
let len = rand.randomRange(1, 8);
let res = "";
for (let i = 0; i < len; i++) {
res += String.fromCharCode(rand.next() & 0xbfff);
}
if (res === _lastNam) return getNextName();
_lastNam = res;
return res;
}
function getNextBuffer(): Buffer {
let len = rand.randomRange(0, 8);
let res = control.createBuffer(len);
for (let i = 0; i < len; i++) {
res[i] = rand.next() & 0xff;
}
if (checkBufferEqual(_lastBuf, res)) return getNextBuffer();
_lastBuf = res;
return res;
}
function checkBufferEqual(a: Buffer, b: Buffer) {
if (a === b) return true;
if ((!a && b) || (a && !b)) return false;
if (a.length != b.length) return false;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) return false;
}
return true;
}
input.onButtonPressed(Button.A, function () {
basic.showString("S");
initSender();
})
input.onButtonPressed(Button.B, function () {
basic.showString("R");
initReceiver();
})
function toggle(index: number) {
const x = index % 5;
const y = Math.idiv(index, 5) % 5;
led.toggle(x, y);
}

408
package-lock.json generated
View File

@ -215,6 +215,13 @@
"bn.js": "^4.0.0",
"inherits": "^2.0.1",
"minimalistic-assert": "^1.0.0"
},
"dependencies": {
"bn.js": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
}
}
},
"assert": {
@ -368,9 +375,9 @@
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
},
"bn.js": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz",
"integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA=="
},
"body-parser": {
"version": "1.19.0",
@ -554,20 +561,40 @@
"requires": {
"bn.js": "^4.1.0",
"randombytes": "^2.0.1"
},
"dependencies": {
"bn.js": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
}
}
},
"browserify-sign": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
"integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz",
"integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==",
"requires": {
"bn.js": "^4.1.1",
"browserify-rsa": "^4.0.0",
"create-hash": "^1.1.0",
"create-hmac": "^1.1.2",
"elliptic": "^6.0.0",
"inherits": "^2.0.1",
"parse-asn1": "^5.0.0"
"bn.js": "^5.1.1",
"browserify-rsa": "^4.0.1",
"create-hash": "^1.2.0",
"create-hmac": "^1.1.7",
"elliptic": "^6.5.2",
"inherits": "^2.0.4",
"parse-asn1": "^5.1.5",
"readable-stream": "^3.6.0"
},
"dependencies": {
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"browserify-zlib": {
@ -579,12 +606,12 @@
}
},
"browserslist": {
"version": "4.11.1",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.11.1.tgz",
"integrity": "sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g==",
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz",
"integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==",
"requires": {
"caniuse-lite": "^1.0.30001038",
"electron-to-chromium": "^1.3.390",
"caniuse-lite": "^1.0.30001043",
"electron-to-chromium": "^1.3.413",
"node-releases": "^1.1.53",
"pkg-up": "^2.0.0"
}
@ -692,9 +719,9 @@
}
},
"caniuse-lite": {
"version": "1.0.30001043",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001043.tgz",
"integrity": "sha512-MrBDRPJPDBYwACtSQvxg9+fkna5jPXhJlKmuxenl/ml9uf8LHKlDmLpElu+zTW/bEz7lC1m0wTDD7jiIB+hgFg=="
"version": "1.0.30001051",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001051.tgz",
"integrity": "sha512-sw8UUnTlRevawTMZKN7vpfwSjCBVoiMPlYd8oT2VwNylyPCBdMAUmLGUApnYYTtIm5JXsQegUAY7GPHqgfDzjw=="
},
"caseless": {
"version": "0.12.0",
@ -732,9 +759,9 @@
}
},
"chokidar": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz",
"integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==",
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
"integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
"requires": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
@ -743,7 +770,7 @@
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.3.0"
"readdirp": "~3.4.0"
}
},
"chownr": {
@ -936,6 +963,13 @@
"requires": {
"bn.js": "^4.1.0",
"elliptic": "^6.0.0"
},
"dependencies": {
"bn.js": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
}
}
},
"create-hash": {
@ -1005,9 +1039,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -1075,9 +1109,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -1129,9 +1163,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -1164,9 +1198,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -1361,6 +1395,13 @@
"bn.js": "^4.1.0",
"miller-rabin": "^4.0.0",
"randombytes": "^2.0.0"
},
"dependencies": {
"bn.js": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
}
}
},
"dom-serialize": {
@ -1460,9 +1501,9 @@
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"electron-to-chromium": {
"version": "1.3.413",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.413.tgz",
"integrity": "sha512-Jm1Rrd3siqYHO3jftZwDljL2LYQafj3Kki5r+udqE58d0i91SkjItVJ5RwlJn9yko8i7MOcoidVKjQlgSdd1hg=="
"version": "1.3.428",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.428.tgz",
"integrity": "sha512-u3+5jEfgLKq/hGO96YfAoOAM1tgFnRDTCD5mLuev44tttcXix+INtVegAkmGzUcfDsnzkPt51XXurXZLLwXt0w=="
},
"elliptic": {
"version": "6.5.2",
@ -1476,6 +1517,13 @@
"inherits": "^2.0.1",
"minimalistic-assert": "^1.0.0",
"minimalistic-crypto-utils": "^1.0.0"
},
"dependencies": {
"bn.js": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
}
}
},
"encodeurl": {
@ -1831,9 +1879,9 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fsevents": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz",
"integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
"integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
"optional": true
},
"function-bind": {
@ -1993,12 +2041,30 @@
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
},
"hash-base": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
"integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
"integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
"requires": {
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
"inherits": "^2.0.4",
"readable-stream": "^3.6.0",
"safe-buffer": "^5.2.0"
},
"dependencies": {
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"safe-buffer": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
}
}
},
"hash.js": {
@ -2761,12 +2827,19 @@
"requires": {
"bn.js": "^4.0.0",
"brorand": "^1.0.1"
},
"dependencies": {
"bn.js": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
}
}
},
"mime": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
"integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA=="
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.5.tgz",
"integrity": "sha512-3hQhEUF027BuxZjQA3s7rIv/7VCQPa27hN9u9g87sEkWaKwQPuXOkVKtOeiyUrnWqTDiOs8Ed2rwg733mB0R5w=="
},
"mime-db": {
"version": "1.42.0",
@ -2825,9 +2898,9 @@
}
},
"mkdirp-classic": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.2.tgz",
"integrity": "sha512-ejdnDQcR75gwknmMw/tx02AuRs8jCtqFoFqDZMjiNxsu85sRIJVXDKHuLYvUUPRBUtV2FpSZa9bL1BUa3BdR2g=="
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
},
"mocha": {
"version": "5.1.0",
@ -2926,17 +2999,17 @@
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
},
"node-abi": {
"version": "2.15.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.15.0.tgz",
"integrity": "sha512-FeLpTS0F39U7hHZU1srAK4Vx+5AHNVOTP+hxBNQknR/54laTHSFIJkDWDqiquY1LeLUgTfPN7sLPhMubx0PLAg==",
"version": "2.16.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.16.0.tgz",
"integrity": "sha512-+sa0XNlWDA6T+bDLmkCUYn6W5k5W6BPRL6mqzSCs6H/xUgtl4D5x2fORKDzopKiU6wsyn/+wXlRXwXeSp+mtoA==",
"requires": {
"semver": "^5.4.1"
}
},
"node-releases": {
"version": "1.1.53",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.53.tgz",
"integrity": "sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ=="
"version": "1.1.55",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.55.tgz",
"integrity": "sha512-H3R3YR/8TjT5WPin/wOoHOUPHgvj8leuU/Keta/rwelEQN9pA/S2Dx8/se4pZ2LBxSd0nAGzsNzhqwa77v7F1w=="
},
"noop-logger": {
"version": "0.1.1",
@ -3254,9 +3327,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3283,9 +3356,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3314,9 +3387,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3344,9 +3417,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3369,9 +3442,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3394,9 +3467,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3419,9 +3492,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3447,9 +3520,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3482,9 +3555,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3518,9 +3591,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3551,9 +3624,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3586,9 +3659,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3619,9 +3692,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3654,9 +3727,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3681,9 +3754,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3714,9 +3787,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3747,9 +3820,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3779,9 +3852,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3811,9 +3884,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3843,9 +3916,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3876,9 +3949,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3907,9 +3980,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3939,9 +4012,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -3972,9 +4045,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -4000,9 +4073,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -4043,9 +4116,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -4075,9 +4148,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -4092,9 +4165,9 @@
}
},
"postcss-value-parser": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz",
"integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg=="
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
"integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ=="
},
"prebuild-install": {
"version": "5.3.3",
@ -4185,6 +4258,13 @@
"parse-asn1": "^5.0.0",
"randombytes": "^2.0.1",
"safe-buffer": "^5.1.2"
},
"dependencies": {
"bn.js": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
}
}
},
"pump": {
@ -4250,18 +4330,18 @@
}
},
"pxt-common-packages": {
"version": "6.21.9",
"resolved": "https://registry.npmjs.org/pxt-common-packages/-/pxt-common-packages-6.21.9.tgz",
"integrity": "sha512-vbUtA4GDE+N4YCaWdC9mBVr0B1xHMj5Ad4NtxFRxbpkeuceZDd0OvGfZvFYHn624t9jUcfuwl4dmhZrXUAPclg==",
"version": "6.21.10",
"resolved": "https://registry.npmjs.org/pxt-common-packages/-/pxt-common-packages-6.21.10.tgz",
"integrity": "sha512-GsNfjTe0YWQX4nn5lMiXST79yeb8OGCZbeJAP6I0dFfahoCM1H2tQqY/hMEPAznY1QZEgHkYvpw8SEWJvbK6Vw==",
"requires": {
"@jacdac/jacdac-ts": "^0.0.9",
"pxt-core": "^5.34.1"
"pxt-core": "^5.36.2"
}
},
"pxt-core": {
"version": "5.36.1",
"resolved": "https://registry.npmjs.org/pxt-core/-/pxt-core-5.36.1.tgz",
"integrity": "sha512-tls8in91gUL1IVG+iLnAsJqEwWsva645snPNvuzM/fzxmna6kA1ZwlHFDAPcpFukZ32cIORyRxRq8ZsplaKVTw==",
"version": "5.36.9",
"resolved": "https://registry.npmjs.org/pxt-core/-/pxt-core-5.36.9.tgz",
"integrity": "sha512-2rrKF+dSrYRwc0GjhPKNR4onzrN4njaWoXQrb9fBvOxsDvpRdrcNnzOi3X7aMv4ocoBYG6wEkCZnk+Ti+AOEFw==",
"requires": {
"applicationinsights-js": "^1.0.20",
"bluebird": "3.5.1",
@ -4399,11 +4479,11 @@
}
},
"readdirp": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz",
"integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==",
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
"integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
"requires": {
"picomatch": "^2.0.7"
"picomatch": "^2.2.1"
}
},
"request": {
@ -4504,9 +4584,9 @@
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"resolve": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.1.tgz",
"integrity": "sha512-rmAglCSqWWMrrBv/XM6sW0NuRFiKViw/W4d9EbC4pt+49H8JwHy+mcGmALTEg504AUDcLTvb1T2q3E9AnmY+ig==",
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
"requires": {
"path-parse": "^1.0.6"
}
@ -4588,9 +4668,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
@ -5001,9 +5081,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.27",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
"integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
"version": "7.0.29",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.29.tgz",
"integrity": "sha512-ba0ApvR3LxGvRMMiUa9n0WR4HjzcYm7tS+ht4/2Nd0NLtHpPIH77fuB9Xh1/yJVz9O/E/95Y/dn8ygWsyffXtw==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",

View File

@ -45,7 +45,7 @@
"typescript": "^3.7.5"
},
"dependencies": {
"pxt-common-packages": "6.21.9",
"pxt-core": "5.36.1"
"pxt-common-packages": "6.21.10",
"pxt-core": "5.36.9"
}
}

View File

@ -302,14 +302,11 @@
"experiments": [
"allowPackageExtensions",
"instructions",
"debugger",
"debugExtensionCode",
"bluetoothUartConsole",
"bluetoothPartialFlashing",
"simScreenshot",
"simGif",
"qrCode",
"githubBlocksDiff"
"simGif"
],
"bluetoothUartFilters": [
{
@ -325,14 +322,6 @@
"name": "Reference",
"path": "/reference"
},
{
"name": "Blocks",
"path": "/blocks"
},
{
"name": "JavaScript",
"path": "/javascript"
},
{
"name": "Hardware",
"path": "/device"
@ -347,6 +336,12 @@
"coloredToolbox": true,
"monacoToolbox": true,
"hasAudio": true,
"socialOptions": {
"orgTwitterHandle": "MSMakeCode",
"hashtags": "MakeCode",
"discourse": "https://forum.makecode.com/",
"discourseCategory": "micro:bit"
},
"blocklyOptions": {
"grid": {
"spacing": 45,
@ -373,6 +368,7 @@
},
"highContrast": true,
"greenScreen": true,
"accessibleBlocks": true,
"print": true,
"selectLanguage": true,
"availableLocales": [
@ -391,7 +387,7 @@
"ja",
"ko",
"nl",
"no",
"nb",
"pl",
"pt-BR",
"pt-PT",
@ -416,6 +412,7 @@
},
"showProjectSettings": true,
"scriptManager": true,
"debugger": true,
"simGifTransparent": "rgba(0,0,0,0)",
"simGifMaxFrames": 44,
"simScreenshotMaxUriLength": 300000,

View File

@ -1,7 +1,8 @@
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
namespace pxsim {
export class DalBoard extends CoreBoard {
export class DalBoard extends CoreBoard
implements RadioBoard {
// state & update logic for component services
ledMatrixState: LedMatrixState;
edgeConnectorState: EdgeConnectorState;
@ -67,7 +68,10 @@ namespace pxsim {
"P3": DAL.MICROBIT_ID_IO_P16
}
});
this.builtinParts["radio"] = this.radioState = new RadioState(runtime);
this.builtinParts["radio"] = this.radioState = new RadioState(runtime, {
ID_RADIO: DAL.MICROBIT_ID_RADIO,
RADIO_EVT_DATAGRAM: DAL.MICROBIT_RADIO_EVT_DATAGRAM
});
this.builtinParts["accelerometer"] = this.accelerometerState = new AccelerometerState(runtime);
this.builtinParts["serial"] = this.serialState = new SerialState();
this.builtinParts["thermometer"] = this.thermometerState = new ThermometerState();
@ -173,7 +177,7 @@ namespace pxsim {
pxsim.initCurrentRuntime = initRuntimeWithDalBoard;
}
export function board() {
export function board(): DalBoard {
return runtime.board as DalBoard;
}
}

View File

@ -32,6 +32,11 @@ namespace pxsim {
setPull(pull: number) {
this.pull = pull;
switch(pull) {
case PinPullMode.PullDown: this.value = 0; break;
case PinPullMode.PullUp: this.value = 1023; break;
default: this.value = Math_.randomRange(0, 1023); break;
}
}
analogReadPin(): number {

View File

@ -47,6 +47,19 @@ namespace pxsim.control {
export function waitMicros(micros: number) {
// TODO
}
export function waitForEvent(id: number, evid: number) {
const cb = getResume();
board().bus.wait(id, evid, cb);
}
export function millis(): number {
return runtime.runningTime();
}
export function micros(): number {
return runtime.runningTimeUs();
}
export function deviceName(): string {
let b = board();
@ -94,14 +107,6 @@ namespace pxsim.pxtcore {
}
namespace pxsim.input {
export function runningTime(): number {
return runtime.runningTime();
}
export function runningTimeMicros(): number {
return runtime.runningTimeUs();
}
export function calibrateCompass() {
// device calibrates...
}

View File

@ -1,147 +0,0 @@
namespace pxsim {
export interface PacketBuffer {
payload: SimulatorRadioPacketPayload;
rssi: number;
serial: number;
time: number;
}
// Extends interface in pxt-core
export interface SimulatorRadioPacketPayload {
bufferData?: Uint8Array;
}
export class RadioDatagram {
datagram: PacketBuffer[] = [];
lastReceived: PacketBuffer = RadioDatagram.defaultPacket();
constructor(private runtime: Runtime) {
}
queue(packet: PacketBuffer) {
if (this.datagram.length < 4) {
this.datagram.push(packet);
}
(<DalBoard>runtime.board).bus.queue(DAL.MICROBIT_ID_RADIO, DAL.MICROBIT_RADIO_EVT_DATAGRAM);
}
send(payload: SimulatorRadioPacketPayload) {
const b = board();
Runtime.postMessage(<SimulatorRadioPacketMessage>{
type: "radiopacket",
broadcast: true,
rssi: -42, // -42 is the strongest signal
serial: b.radioState.transmitSerialNumber ? pxsim.control.deviceSerialNumber() : 0,
time: new Date().getTime(),
payload
})
}
recv(): PacketBuffer {
let r = this.datagram.shift();
if (!r) r = RadioDatagram.defaultPacket();
return this.lastReceived = r;
}
private static defaultPacket(): PacketBuffer {
return {
rssi: -1,
serial: 0,
time: 0,
payload: { type: -1, groupId: 0, bufferData: new Uint8Array(0) }
};
}
}
export class RadioState {
power = 0;
transmitSerialNumber = false;
datagram: RadioDatagram;
groupId: number;
band: number;
constructor(runtime: Runtime) {
this.datagram = new RadioDatagram(runtime);
this.power = 6; // default value
this.groupId = 0;
this.band = 7; // https://github.com/lancaster-university/microbit-dal/blob/master/inc/core/MicroBitConfig.h#L320
}
public setGroup(id: number) {
this.groupId = id & 0xff; // byte only
}
setTransmitPower(power: number) {
power = power | 0;
this.power = Math.max(0, Math.min(7, power));
}
setTransmitSerialNumber(sn: boolean) {
this.transmitSerialNumber = !!sn;
}
setFrequencyBand(band: number) {
band = band | 0;
if (band < 0 || band > 83) return;
this.band = band;
}
raiseEvent(id: number, eventid: number) {
Runtime.postMessage(<SimulatorEventBusMessage>{
type: "eventbus",
broadcast: true,
id,
eventid,
power: this.power,
group: this.groupId
})
}
receivePacket(packet: SimulatorRadioPacketMessage) {
if (this.groupId == packet.payload.groupId)
this.datagram.queue(packet)
}
}
}
namespace pxsim.radio {
export function raiseEvent(id: number, eventid: number): void {
board().radioState.raiseEvent(id, eventid);
}
export function setGroup(id: number): void {
board().radioState.setGroup(id);
}
export function setTransmitPower(power: number): void {
board().radioState.setTransmitPower(power);
}
export function setFrequencyBand(band: number) {
board().radioState.setFrequencyBand(band);
}
export function sendRawPacket(buf: RefBuffer) {
let cb = getResume();
board().radioState.datagram.send({
type: 0,
groupId: board().radioState.groupId,
bufferData: buf.data
});
setTimeout(cb, 1);
}
export function readRawPacket() {
const packet = board().radioState.datagram.recv();
return new RefBuffer(packet.payload.bufferData)
}
export function receivedSignalStrength(): number {
return board().radioState.datagram.lastReceived.rssi;
}
export function onDataReceived(handler: RefAction): void {
pxtcore.registerWithDal(DAL.MICROBIT_ID_RADIO, DAL.MICROBIT_RADIO_EVT_DATAGRAM, handler);
readRawPacket();
}
}

View File

@ -11,5 +11,11 @@
"lib": ["dom", "dom.iterable", "scripthost", "es6"],
"types": ["bluebird"],
"typeRoots": ["../node_modules/@types"]
}
},
"include": [
"*.ts",
"state/*.ts",
"visuals/*.ts",
"../node_modules/pxt-common-packages/libs/radio/sim/*.ts"
]
}

View File

@ -1106,10 +1106,10 @@ namespace pxsim.visuals {
}
else if (pin.mode & PinFlags.Touch) {
v = pin.touched ? "0%" : "100%";
if (text) text.textContent = "";
if (text) text.textContent = "TOUCHED";
} else {
v = "100%";
if (text) text.textContent = "";
if (text) text.textContent = "unused";
}
if (v) svg.setGradientValue(this.pinGradients[index], v);
}
@ -1558,4 +1558,4 @@ namespace pxsim.visuals {
})
}
}
}
}

View File

@ -185,7 +185,18 @@
"EBOTICS/pxt-eboticsMIBO",
"KitronikLtd/pxt-kitronik-halohd",
"dugbraden/pxt-climate-action-kit",
"alsrobot-microbit-makecode-packages/MiniCruise"
"alsrobot-microbit-makecode-packages/MiniCruise",
"4tronix/ServoBit",
"DFRobot/pxt-maqueen",
"DFRobot/pxt-DFRobot-microIoT",
"mu-opensource/pxt-muvision",
"KitronikLtd/pxt-kitronik-clip-detector",
"DFRobot/pxt-DFRobot-NaturalScience",
"strawbees/pxt-robotic-inventions",
"daferdur/pxt-myHX711",
"CytronTechnologies/pxt-edubit",
"MakeAndLearn/pxt-microshield",
"elecfreaks/pxt-TPBot"
],
"preferredRepos": [
"Microsoft/pxt-neopixel",
@ -199,33 +210,6 @@
"MKleinSB/pxt-foldio"
]
},
"languages": [
"en",
"ar",
"cs",
"da",
"de",
"el",
"es-ES",
"fi",
"fr",
"hu",
"it",
"ja",
"ko",
"nl",
"no",
"pt-BR",
"pt-PT",
"ru",
"si-LK",
"sk",
"sv-SE",
"tr",
"uk",
"zh-CN",
"zh-TW"
],
"galleries": {
"First Steps": "calliope/firststeps",
"Tutorials": "calliope/tutorials",

View File

@ -1,3 +1,3 @@
/*******************************
Site Overrides
*******************************/
*******************************/

0
theme/site/globals/site.variables Normal file → Executable file
View File