pxt-calliope/target.json
Matthias L. Jugel b028b1df5b Auto-push
2017-08-19 17:16:35 +02:00

402 lines
455 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"id": "calliope",
"name": " calliope",
"nickname": "mini",
"title": "calliope mini - Blocks / Javascript editor",
"description": "A Blocks / JavaScript code editor for the calliope mini.",
"corepkg": "core",
"bundleddirs": [
"libs/core",
"libs/radio",
"libs/devices",
"libs/bluetooth",
"libs/pxt-calliope-bc95",
"libs/pxt-calliope-bunt"
],
"cloud": {
"workspace": false,
"packages": true,
"sharing": true,
"publishing": true,
"preferredPackages": [],
"githubPackages": true
},
"compile": {
"isNative": true,
"hasHex": true,
"deployDrives": "MINI",
"driveName": "MINI",
"hexMimeType": "application/x-calliope-hex",
"upgrades": [
{
"type": "package",
"map": {
"microbit": "core",
"microbit-bluetooth": "bluetooth",
"microbit-radio": "radio",
"microbit-devices": "devices",
"microbit-led": "",
"microbit-music": "",
"microbit-game": "",
"microbit-pins": "",
"microbit-serial": ""
}
},
{
"type": "api",
"map": {
"bluetooth\\.uartRead\\((.*?)\\)": "bluetooth.uartReadUntil($1)",
"bluetooth\\.uartWrite\\((.*?)\\)": "bluetooth.uartWriteUntil($1)"
}
}
],
"jsRefCounting": true
},
"runtime": {
"mathBlocks": true,
"loopsBlocks": true,
"logicBlocks": true,
"variablesBlocks": true,
"textBlocks": true,
"onStartColor": "#54C9C9",
"onStartNamespace": "basic"
},
"simulator": {
"autoRun": true,
"streams": true,
"aspectRatio": 1.13,
"parts": false,
"partsAspectRatio": 0.69,
"boardDefinition": {
"visual": "calliope",
"gpioPinBlocks": [
[
"EDGE_P0"
],
[
"EDGE_P1"
],
[
"EDGE_P2"
],
[
"EDGE_P3"
],
[
"C_P4",
"C_P5",
"C_P6",
"C_P7"
],
[
"C_P8",
"C_P9",
"C_P10",
"C_P11",
"C_P12"
],
[
"C_P16"
]
],
"gpioPinMap": {
"P0": "EDGE_P0",
"P1": "EDGE_P1",
"P2": "EDGE_P2",
"P3": "EDGE_P3",
"C4": "C_P4",
"C5": "C_P5",
"C6": "C_P6",
"C7": "C_P7",
"C8": "C_P8",
"C9": "C_P9",
"C10": "C_P10",
"C11": "C_P11",
"C12": "C_P12",
"C13": "C_P13",
"C14": "C_P14",
"C15": "C_P15",
"C19": "C_P19",
"C20": "C_P20",
"EXT_PWR": "EXT_PWR",
"SPKR": "SPKR",
"BTN_A": "BTN_A",
"BTN_B": "BTN_B",
"MOTOR1": "M_OUT1",
"MOTOR2": "M_OUT2"
},
"spiPins": {
"MOSI": "C_P15",
"MISO": "C_P14",
"SCK": "C_P13"
},
"i2cPins": {
"SDA": "C_P20",
"SCL": "C_P19"
},
"analogInPins": [
"P1",
"P2",
"C4",
"C5",
"C6"
],
"groundPins": [
"EDGE_GND"
],
"threeVoltPins": [
"EDGE_VCC"
],
"attachPowerOnRight": true,
"onboardComponents": [
"accelerometer",
"buttonpair",
"ledmatrix",
"speaker",
"bluetooth",
"thermometer",
"compass",
"speaker",
"microphone",
"rgbled"
],
"useCrocClips": true,
"marginWhenBreadboarding": [
0,
0,
80,
0
]
}
},
"compileService": {
"yottaTarget": "calliope-mini-classic-gcc",
"yottaCorePackage": "microbit",
"githubCorePackage": "calliope-mini/microbit",
"gittag": "v2.0.0-rc8-calliope-1.0.3",
"serviceId": "calliope",
"yottaBinary": "pxt-microbit-app-combined.hex"
},
"serial": {
"manufacturerFilter": "^mbed$",
"nameFilter": "^mbed Serial Port",
"log": true
},
"appTheme": {
"accentColor": "#249899",
"defaultLocale": "de",
"logoUrl": "/pxt-calliope/",
"logo": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTc5LjkiIGhlaWdodD0iMzIuNCIgdmlld0JveD0iMCAwIDE3OS45IDMyLjQiPgogIDxwYXRoIGZpbGw9IiM0OTUyNjAiIGQ9Ik0zMy4xIDExLjJoLTguNVY1LjhjMC0yLjMgMS45LTQuMiA0LjItNC4yIDIuMyAwIDQuMiAxLjkgNC4yIDQuMnY1LjR6Ii8+CiAgPHBhdGggZmlsbD0iIzdGOTZBMSIgZD0iTTI1LjggMy42SDMydjcuNmgtNi4yeiIvPgogIDxwYXRoIGZpbGw9IiM4NDVCMzIiIGQ9Ik0xMi4yIDcuMlYxOGgxMi41VjcuMmMwLTMuNC0yLjgtNi4yLTYuMi02LjJzLTYuMyAyLjgtNi4zIDYuMnoiLz4KICA8cGF0aCBmaWxsPSIjMjZBN0FBIiBkPSJNMjguOSAzMS40SDguN2MtNi4zIDAtOS04LTQtMTEuOEwxNiAxMS4yaDE3LjF2MTZjMCAyLjMtMS45IDQuMi00LjIgNC4yeiIvPgogIDxwYXRoIGZpbGw9IiM0M0M5QzkiIGQ9Ik0xNS4yIDE3LjdsLTguOC43IDEwLjctOCIvPgogIDxwYXRoIGZpbGw9IiNGNkY0RTciIGQ9Ik0xNC44IDE1LjFsMi4zLTQuNyAxLjUgNC43bTAgMGwxLjQtNC43IDIuMyA0LjciLz4KICA8cGF0aCBmaWxsPSIjQkREMUNGIiBkPSJNMjEuOSAxNy43aC02LjdsLS40LTIuNmg3LjUiLz4KICA8cGF0aCBmaWxsPSIjRjZGNEU3IiBkPSJNMjYuOCAzMS40Yy0uNi00LjYtMS45LTEwLjItNC44LTEzLjdoLTYuOGMtMyAzLjUtNC4yIDkuMS00LjggMTMuN2gxNi40eiIvPgogIDxwYXRoIGZpbGw9IiNGRkNEOUEiIGQ9Ik0xOC42IDEwLjVjLTEuNCAwLTIuNi0xLjItMi42LTIuNlY1aDUuMXYyLjljMCAxLjUtMS4xIDIuNi0yLjUgMi42eiIvPgogIDxwYXRoIGZpbGw9IiNCREQxQ0YiIGQ9Ik0xNS40IDMxLjRWMTcuN2MyLjIgNS4xIDQuOSAxMS4zIDguMiAxMy43aC04LjJ6Ii8+CiAgPHBhdGggZmlsbD0iI0ZGQ0Q5QSIgZD0iTTE3LjEgMTAuNGwxLjUgNC43IDEuNC00LjciLz4KICA8cGF0aCBmaWxsPSIjNDNDOUM5IiBkPSJNMjUuOCAxMS4yaDcuM3Y5LjQiLz4KICA8cGF0aCBmaWxsPSIjQkNEMUNGIiBkPSJNNTIuMyAxNS4xaC0xLjZsLS4yLTEuNGMtLjItLjItLjUtLjQtLjgtLjVzLS43LS4yLTEuMi0uMmMtLjkgMC0xLjcuMy0yLjIgMXMtLjggMS42LS44IDIuN3YuNGMwIDEuMS4zIDIgLjggMi43LjUuNyAxLjIgMSAyLjEgMSAuNCAwIC44LS4xIDEuMi0uMi40LS4xLjYtLjMuOC0uNWwuMi0xLjRoMS42djIuMWMtLjQuNS0xIC45LTEuNyAxLjItLjcuMy0xLjQuNS0yLjMuNS0xLjUgMC0yLjYtLjUtMy42LTEuNXMtMS40LTIuMy0xLjQtMy45di0uNGMwLTEuNi41LTIuOSAxLjQtMy45czIuMS0xLjUgMy42LTEuNWMuOCAwIDEuNi4yIDIuMy41LjcuMyAxLjIuNyAxLjcgMS4ydjIuMXptMS41IDUuOWwuOC0uMSAzLjMtOS40aDIuMmwzLjMgOS40LjguMXYxLjNoLTMuN1YyMWwuOC0uMS0uNS0xLjVoLTMuNWwtLjUgMS41LjguMXYxLjNoLTMuN1YyMXptMy45LTMuMmgyLjVMNTkgMTRsLTEuMyAzLjh6bTcuOCA0LjVWMjFsMS4yLS4yVjEzbC0xLjItLjJ2LTEuM0g3MHYxLjNsLTEuMi4ydjcuNmgzLjFsLjEtMS40aDEuN3YzaC04LjJ6bTkuNSAwVjIxbDEuMi0uMlYxM2wtMS4yLS4ydi0xLjNoNC42djEuM2wtMS4zLjJ2Ny42aDMuMWwuMS0xLjRoMS43djNINzV6bTkuNS05LjV2LTEuM0g4OXYxLjNsLTEuMS4ydjcuOGwxLjEuMnYxLjNoLTQuNVYyMWwxLjItLjJWMTNsLTEuMi0uMnptMTUuOSA0LjJjMCAxLjYtLjUgMi45LTEuNCAzLjktLjkgMS0yLjEgMS42LTMuNiAxLjZzLTIuNi0uNS0zLjUtMS42LTEuNC0yLjMtMS40LTMuOXYtLjJjMC0xLjYuNC0yLjkgMS4zLTMuOXMyLjEtMS42IDMuNS0xLjZjMS41IDAgMi43LjUgMy42IDEuNnMxLjQgMi40IDEuNCAzLjl2LjJ6bS0yLjItLjJjMC0xLjEtLjItMi0uNy0yLjdzLTEuMi0xLTIuMS0xLTEuNi4zLTIgMS0uNyAxLjYtLjcgMi43di4yYzAgMS4xLjIgMi4xLjcgMi44LjUuNyAxLjEgMSAyIDEgLjkgMCAxLjYtLjMgMi4xLTFzLjctMS42LjctMi44di0uMnptOC44LTUuM2MxLjIgMCAyLjIuMyAyLjkgMVMxMTEgMTQgMTExIDE1cy0uNCAxLjktMS4xIDIuNWMtLjcuNi0xLjcuOS0yLjkuOWgtMS44djIuNGwxLjIuMnYxLjNoLTQuNVYyMWwxLjItLjJWMTNsLTEuMi0uMnYtMS4zaDUuMXptLTEuOCA1LjJoMS44Yy42IDAgMS4xLS4yIDEuNC0uNXMuNS0uOC41LTEuMy0uMi0xLS41LTEuM2MtLjMtLjMtLjgtLjUtMS40LS41aC0xLjh2My42em0xNC4xLjloLTMuN3YzLjFoMy41bC4xLTEuM2gxLjd2M2gtOC42VjIxbDEuMi0uMlYxM2wtMS4yLS4ydi0xLjNoOC42djNoLTEuN2wtLjEtMS4zaC0zLjV2Mi43aDMuN3YxLjd6Ii8+CiAgPHBhdGggZmlsbD0iI0ZGRiIgZD0iTTEzNC4zIDExLjZsLjEgMS4xYy4yLS40LjUtLjcuOS0xIC40LS4yLjgtLjQgMS4zLS40cy44LjEgMS4xLjNjLjMuMi41LjUuNy44LjItLjMuNS0uNi44LS44LjMtLjIuNy0uMyAxLjItLjMuNCAwIC43LjEgMSAuMi4zLjEuNS4zLjguNi4yLjMuNC42LjUgMSAuMS40LjIuOS4yIDEuNHY3LjhoLTIuMnYtNy45YzAtLjQtLjEtLjctLjMtLjktLjItLjItLjQtLjItLjctLjItLjMgMC0uNS4xLS42LjJzLS4zLjMtLjMuNXY4LjNoLTIuMnYtNy45YzAtLjQtLjEtLjctLjMtLjktLjItLjItLjQtLjMtLjctLjMtLjMgMC0uNS4xLS43LjItLjIuMS0uMy4zLS40LjV2OC4zaC0yLjJWMTEuNmgyem0xMS4zIDBoNS43djguOGgzLjJ2MmgtOC45di0yaDMuM3YtNi44aC0zLjN2LTJ6bTMuMS0yLjhjMC0uNC4xLS43LjQtLjkuMi0uMi42LS40IDEtLjRzLjguMSAxIC40Yy4yLjIuNC41LjQuOXMtLjEuNy0uNC45Yy0uMi4yLS42LjQtMSAuNHMtLjgtLjEtMS0uNGMtLjItLjItLjQtLjUtLjQtLjl6bTEwLjcgMi44bC4xIDEuNWMuNC0uNS45LTEgMS40LTEuMi42LS4zIDEuMi0uNCAxLjgtLjQuNSAwIDEgLjEgMS41LjIuNS4yLjguNCAxLjIuNy4zLjMuNi44LjggMS4zLjIuNS4zIDEuMi4zIDEuOXY2LjdoLTIuNHYtNi43YzAtLjQtLjEtLjgtLjItMS4xLS4xLS4zLS4yLS41LS40LS43LS4yLS4yLS40LS4zLS43LS40LS4zLS4xLS42LS4xLS45LS4xLS41IDAtMSAuMS0xLjQuMy0uNC4yLS43LjUtLjkuOXY3LjdoLTIuNFYxMS42aDIuMnptMTAuNiAwaDUuN3Y4LjhoMy4ydjJIMTcwdi0yaDMuM3YtNi44SDE3MHYtMnptMy4xLTIuOGMwLS40LjEtLjcuNC0uOS4yLS4yLjYtLjQgMS0uNHMuOC4xIDEgLjRjLjIuMi40LjUuNC45cy0uMS43LS40LjljLS4yLjItLjYuNC0xIC40cy0uOC0uMS0xLS40Yy0uMy0uMi0uNC0uNS0uNC0uOXoiLz4KPC9zdmc+",
"docsLogo": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOC4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4KCjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiCiAgIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIKICAgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiCiAgIHZlcnNpb249IjEuMSIKICAgaWQ9IkViZW5lXzEiCiAgIHg9IjBweCIKICAgeT0iMHB4IgogICB2aWV3Qm94PSIwIDAgMTc1LjQ5OTk5IDE3Mi40IgogICBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4NDEuOSA1OTUuMyIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMC45MSByMTM3MjUiCiAgIHNvZGlwb2RpOmRvY25hbWU9IkxvZ29fQ2FsbGlvcGVfV29tYW4uc3ZnIgogICB3aWR0aD0iMTc1LjUiCiAgIGhlaWdodD0iMTcyLjM5OTk5Ij48bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE1MDExIj48cmRmOlJERj48Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+PGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+PGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPjxkYzp0aXRsZT48L2RjOnRpdGxlPjwvY2M6V29yaz48L3JkZjpSREY+PC9tZXRhZGF0YT48ZGVmcwogICAgIGlkPSJkZWZzNTAwOSIgLz48c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEiCiAgICAgb2JqZWN0dG9sZXJhbmNlPSIxMCIKICAgICBncmlkdG9sZXJhbmNlPSIxMCIKICAgICBndWlkZXRvbGVyYW5jZT0iMTAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAiCiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjE5MjAiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMTEzNyIKICAgICBpZD0ibmFtZWR2aWV3NTAwNyIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgaW5rc2NhcGU6em9vbT0iMC4zNDIwODMzNyIKICAgICBpbmtzY2FwZTpjeD0iNDIwLjk1MDAxIgogICAgIGlua3NjYXBlOmN5PSIyOTcuNjQ5OTkiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9Ii04IgogICAgIGlua3NjYXBlOndpbmRvdy15PSIxNTYiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJFYmVuZV8xIiAvPjxnCiAgICAgaWQ9Imc0OTU1IgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yNjAuOTAwMjUsLTIwNC4xKSI+PGcKICAgICAgIGlkPSJnNDk1NyI+PGRlZnMKICAgICAgICAgaWQ9ImRlZnM0OTU5Ij48cmVjdAogICAgICAgICAgIGlkPSJTVkdJRF83XyIKICAgICAgICAgICB4PSIxOTMuMTAwMDEiCiAgICAgICAgICAgeT0iMjA0LjEwMDAxIgogICAgICAgICAgIHdpZHRoPSIzMTguMjk5OTkiCiAgICAgICAgICAgaGVpZ2h0PSIyNTYuMjk5OTkiIC8+PC9kZWZzPjxjbGlwUGF0aAogICAgICAgICBpZD0iU1ZHSURfMV8iPjx1c2UKICAgICAgICAgICB4bGluazpocmVmPSIjU1ZHSURfN18iCiAgICAgICAgICAgb3ZlcmZsb3c9InZpc2libGUiCiAgICAgICAgICAgaWQ9InVzZTQ5NjMiCiAgICAgICAgICAgc3R5bGU9Im92ZXJmbG93OnZpc2libGUiCiAgICAgICAgICAgeD0iMCIKICAgICAgICAgICB5PSIwIgogICAgICAgICAgIHdpZHRoPSIxMDAlIgogICAgICAgICAgIGhlaWdodD0iMTAwJSIgLz48L2NsaXBQYXRoPjwvZz48ZwogICAgICAgaWQ9Imc0OTY1Ij48ZGVmcwogICAgICAgICBpZD0iZGVmczQ5NjciPjxyZWN0CiAgICAgICAgICAgaWQ9IlNWR0lEXzlfIgogICAgICAgICAgIHg9IjE5My4xMDAwMSIKICAgICAgICAgICB5PSIyMDQuMTAwMDEiCiAgICAgICAgICAgd2lkdGg9IjMxOC4yOTk5OSIKICAgICAgICAgICBoZWlnaHQ9IjI1Ni4yOTk5OSIgLz48L2RlZnM+PGNsaXBQYXRoCiAgICAgICAgIGlkPSJTVkdJRF8yXyI+PHVzZQogICAgICAgICAgIHhsaW5rOmhyZWY9IiNTVkdJRF85XyIKICAgICAgICAgICBvdmVyZmxvdz0idmlzaWJsZSIKICAgICAgICAgICBpZD0idXNlNDk3MSIKICAgICAgICAgICBzdHlsZT0ib3ZlcmZsb3c6dmlzaWJsZSIKICAgICAgICAgICB4PSIwIgogICAgICAgICAgIHk9IjAiCiAgICAgICAgICAgd2lkdGg9IjEwMCUiCiAgICAgICAgICAgaGVpZ2h0PSIxMDAlIiAvPjwvY2xpcFBhdGg+PC9nPjxnCiAgICAgICBpZD0iZzQ5NzMiPjxkZWZzCiAgICAgICAgIGlkPSJkZWZzNDk3NSI+PHJlY3QKICAgICAgICAgICBpZD0iU1ZHSURfMTFfIgogICAgICAgICAgIHg9IjE5My4xMDAwMSIKICAgICAgICAgICB5PSIyMDQuMTAwMDEiCiAgICAgICAgICAgd2lkdGg9IjMxOC4yOTk5OSIKICAgICAgICAgICBoZWlnaHQ9IjI1Ni4yOTk5OSIgLz48L2RlZnM+PGNsaXBQYXRoCiAgICAgICAgIGlkPSJTVkdJRF8zXyI+PHVzZQogICAgICAgICAgIHhsaW5rOmhyZWY9IiNTVkdJRF8xMV8iCiAgICAgICAgICAgb3ZlcmZsb3c9InZpc2libGUiCiAgICAgICAgICAgaWQ9InVzZTQ5NzkiCiAgICAgICAgICAgc3R5bGU9Im92ZXJmbG93OnZpc2libGUiCiAgICAgICAgICAgeD0iMCIKICAgICAgICAgICB5PSIwIgogICAgICAgICAgIHdpZHRoPSIxMDAlIgogICAgICAgICAgIGhlaWdodD0iMTAwJSIgLz48L2NsaXBQYXRoPjxwYXRoCiAgICAgICAgIGNsaXAtcGF0aD0idXJsKCNTVkdJRF8zXykiCiAgICAgICAgIGQ9Im0gNDM2LjQsMjYyIC00Ny45LDAgMCwtNDYgYyAwLC00LjcgMy44LC04LjQgOC40LC04LjQgbCAzMSwwIGMgNC43LDAgOC40LDMuOCA4LjQsOC40IGwgMCw0NiB6IgogICAgICAgICBpZD0icGF0aDQ5ODEiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgIHN0eWxlPSJmaWxsOiM0YTUyNjEiIC8+PC9nPjxyZWN0CiAgICAgICB4PSIzOTQuNzk5OTkiCiAgICAgICB5PSIyMTguNyIKICAgICAgIHdpZHRoPSIzNS4wOTk5OTgiCiAgICAgICBoZWlnaHQ9IjQzLjIwMDAwMSIKICAgICAgIGlkPSJyZWN0NDk4MyIKICAgICAgIHN0eWxlPSJmaWxsOiM4MDk2YTEiIC8+PHBhdGgKICAgICAgIGQ9Im0gMzE3LjYsMjM5LjUgMCw2MSA3MSwwLjIgYyAwLDAgMCwtNTcuMyAwLC02MSAwLC0xOS41IC0xNi4xLC0zNS42IC0zNS42LC0zNS42IC0xOS42LDAgLTM1LjQsMTUuOCAtMzUuNCwzNS40IgogICAgICAgaWQ9InBhdGg0OTg1IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgIHN0eWxlPSJmaWxsOiM4NTVjMzMiIC8+PHBhdGgKICAgICAgIGQ9Im0gNDEyLjQsMzc2LjUgLTExNC4yLDAgYyAtMzUuNiwwIC01MC45LC00NS4yIC0yMi42LC02Ni44IGwgNjMuOCwtNDcuOCA5Ni45LDAgMCw5MC43IGMgMC4xLDEzLjIgLTEwLjYsMjMuOSAtMjMuOSwyMy45IgogICAgICAgaWQ9InBhdGg0OTg3IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgIHN0eWxlPSJmaWxsOiMyNmE2YWIiIC8+PHBvbHlnb24KICAgICAgIHBvaW50cz0iMzQ1LjcsMjU3LjMgMzM0LjgsMjk4LjggMjg1LjEsMzAyLjUgIgogICAgICAgaWQ9InBvbHlnb240OTg5IgogICAgICAgc3R5bGU9ImZpbGw6IzQyYzljOSIgLz48cG9seWdvbgogICAgICAgcG9pbnRzPSIzNTQsMjgzLjggMzMyLjUsMjgzLjggMzQ1LjcsMjU3LjMgIgogICAgICAgaWQ9InBvbHlnb240OTkxIgogICAgICAgc3R5bGU9ImZpbGw6I2Y3ZjVlOCIgLz48cG9seWdvbgogICAgICAgcG9pbnRzPSIzNzUuNCwyODMuOCAzNTQsMjgzLjggMzYyLjIsMjU3LjMgIgogICAgICAgaWQ9InBvbHlnb240OTkzIgogICAgICAgc3R5bGU9ImZpbGw6I2Y3ZjVlOCIgLz48cG9seWdvbgogICAgICAgcG9pbnRzPSIzNzMuMSwyOTguOCAzMzQuOCwyOTguOCAzMzIuNSwyODMuOCAzNzUuNCwyODMuOCAiCiAgICAgICBpZD0icG9seWdvbjQ5OTUiCiAgICAgICBzdHlsZT0iZmlsbDojYmRkMWNmIiAvPjxwYXRoCiAgICAgICBkPSJtIDQwMC42LDM3Ni41IGMgLTMuNSwtMjYuMiAtMTAuNiwtNTggLTI3LjMsLTc3LjcgbCAtMC4yLDAgLTE5LDAgLTE5LDAgLTAuMiwwIGMgLTE2LjcsMTkuOCAtMjMuOCw1MS41IC0yNy4zLDc3LjcgbCA5MywwIHoiCiAgICAgICBpZD0icGF0aDQ5OTciCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgc3R5bGU9ImZpbGw6I2Y3ZjVlOCIgLz48cGF0aAogICAgICAgZD0ibSAzNTcsMjU4IC02LjEsMCBjIC02LjQsMCAtMTEuNSwtNS4yIC0xMS41LC0xMS41IGwgMCwtMTkuNyAyOS4yLDAgMCwxOS43IGMgLTAuMSw2LjMgLTUuMywxMS41IC0xMS42LDExLjUiCiAgICAgICBpZD0icGF0aDQ5OTkiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgc3R5bGU9ImZpbGw6I2ZmY2M5OSIgLz48cGF0aAogICAgICAgZD0ibSAzMzUuOCwzNzYuNSAwLC03Ny43IGMgMTIuNCwyOS4xIDI3LjcsNjQuMyA0Ni41LDc3LjcgbCAtNDYuNSwwIHoiCiAgICAgICBpZD0icGF0aDUwMDEiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgc3R5bGU9ImZpbGw6I2JkZDFjZiIgLz48cG9seWdvbgogICAgICAgcG9pbnRzPSIzNjIuMiwyNTcuMyAzNDUuNywyNTcuMyAzNTQsMjgzLjggIgogICAgICAgaWQ9InBvbHlnb241MDAzIgogICAgICAgc3R5bGU9ImZpbGw6I2ZmY2M5OSIgLz48cG9seWdvbgogICAgICAgcG9pbnRzPSI0MzYuNCwzMTUuMyAzOTQuOCwyNjIgNDM2LjQsMjYyICIKICAgICAgIGlkPSJwb2x5Z29uNTAwNSIKICAgICAgIHN0eWxlPSJmaWxsOiM0MmM5YzkiIC8+PC9nPjwvc3ZnPg==",
"portraitLogo": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOC4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4KCjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiCiAgIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIKICAgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiCiAgIHZlcnNpb249IjEuMSIKICAgaWQ9IkViZW5lXzEiCiAgIHg9IjBweCIKICAgeT0iMHB4IgogICB2aWV3Qm94PSIwIDAgMTc1LjQ5OTk5IDE3Mi40IgogICBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4NDEuOSA1OTUuMyIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMC45MSByMTM3MjUiCiAgIHNvZGlwb2RpOmRvY25hbWU9IkxvZ29fQ2FsbGlvcGVfV29tYW4uc3ZnIgogICB3aWR0aD0iMTc1LjUiCiAgIGhlaWdodD0iMTcyLjM5OTk5Ij48bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE1MDExIj48cmRmOlJERj48Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+PGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+PGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPjxkYzp0aXRsZT48L2RjOnRpdGxlPjwvY2M6V29yaz48L3JkZjpSREY+PC9tZXRhZGF0YT48ZGVmcwogICAgIGlkPSJkZWZzNTAwOSIgLz48c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEiCiAgICAgb2JqZWN0dG9sZXJhbmNlPSIxMCIKICAgICBncmlkdG9sZXJhbmNlPSIxMCIKICAgICBndWlkZXRvbGVyYW5jZT0iMTAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAiCiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjE5MjAiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMTEzNyIKICAgICBpZD0ibmFtZWR2aWV3NTAwNyIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgaW5rc2NhcGU6em9vbT0iMC4zNDIwODMzNyIKICAgICBpbmtzY2FwZTpjeD0iNDIwLjk1MDAxIgogICAgIGlua3NjYXBlOmN5PSIyOTcuNjQ5OTkiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9Ii04IgogICAgIGlua3NjYXBlOndpbmRvdy15PSIxNTYiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJFYmVuZV8xIiAvPjxnCiAgICAgaWQ9Imc0OTU1IgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yNjAuOTAwMjUsLTIwNC4xKSI+PGcKICAgICAgIGlkPSJnNDk1NyI+PGRlZnMKICAgICAgICAgaWQ9ImRlZnM0OTU5Ij48cmVjdAogICAgICAgICAgIGlkPSJTVkdJRF83XyIKICAgICAgICAgICB4PSIxOTMuMTAwMDEiCiAgICAgICAgICAgeT0iMjA0LjEwMDAxIgogICAgICAgICAgIHdpZHRoPSIzMTguMjk5OTkiCiAgICAgICAgICAgaGVpZ2h0PSIyNTYuMjk5OTkiIC8+PC9kZWZzPjxjbGlwUGF0aAogICAgICAgICBpZD0iU1ZHSURfMV8iPjx1c2UKICAgICAgICAgICB4bGluazpocmVmPSIjU1ZHSURfN18iCiAgICAgICAgICAgb3ZlcmZsb3c9InZpc2libGUiCiAgICAgICAgICAgaWQ9InVzZTQ5NjMiCiAgICAgICAgICAgc3R5bGU9Im92ZXJmbG93OnZpc2libGUiCiAgICAgICAgICAgeD0iMCIKICAgICAgICAgICB5PSIwIgogICAgICAgICAgIHdpZHRoPSIxMDAlIgogICAgICAgICAgIGhlaWdodD0iMTAwJSIgLz48L2NsaXBQYXRoPjwvZz48ZwogICAgICAgaWQ9Imc0OTY1Ij48ZGVmcwogICAgICAgICBpZD0iZGVmczQ5NjciPjxyZWN0CiAgICAgICAgICAgaWQ9IlNWR0lEXzlfIgogICAgICAgICAgIHg9IjE5My4xMDAwMSIKICAgICAgICAgICB5PSIyMDQuMTAwMDEiCiAgICAgICAgICAgd2lkdGg9IjMxOC4yOTk5OSIKICAgICAgICAgICBoZWlnaHQ9IjI1Ni4yOTk5OSIgLz48L2RlZnM+PGNsaXBQYXRoCiAgICAgICAgIGlkPSJTVkdJRF8yXyI+PHVzZQogICAgICAgICAgIHhsaW5rOmhyZWY9IiNTVkdJRF85XyIKICAgICAgICAgICBvdmVyZmxvdz0idmlzaWJsZSIKICAgICAgICAgICBpZD0idXNlNDk3MSIKICAgICAgICAgICBzdHlsZT0ib3ZlcmZsb3c6dmlzaWJsZSIKICAgICAgICAgICB4PSIwIgogICAgICAgICAgIHk9IjAiCiAgICAgICAgICAgd2lkdGg9IjEwMCUiCiAgICAgICAgICAgaGVpZ2h0PSIxMDAlIiAvPjwvY2xpcFBhdGg+PC9nPjxnCiAgICAgICBpZD0iZzQ5NzMiPjxkZWZzCiAgICAgICAgIGlkPSJkZWZzNDk3NSI+PHJlY3QKICAgICAgICAgICBpZD0iU1ZHSURfMTFfIgogICAgICAgICAgIHg9IjE5My4xMDAwMSIKICAgICAgICAgICB5PSIyMDQuMTAwMDEiCiAgICAgICAgICAgd2lkdGg9IjMxOC4yOTk5OSIKICAgICAgICAgICBoZWlnaHQ9IjI1Ni4yOTk5OSIgLz48L2RlZnM+PGNsaXBQYXRoCiAgICAgICAgIGlkPSJTVkdJRF8zXyI+PHVzZQogICAgICAgICAgIHhsaW5rOmhyZWY9IiNTVkdJRF8xMV8iCiAgICAgICAgICAgb3ZlcmZsb3c9InZpc2libGUiCiAgICAgICAgICAgaWQ9InVzZTQ5NzkiCiAgICAgICAgICAgc3R5bGU9Im92ZXJmbG93OnZpc2libGUiCiAgICAgICAgICAgeD0iMCIKICAgICAgICAgICB5PSIwIgogICAgICAgICAgIHdpZHRoPSIxMDAlIgogICAgICAgICAgIGhlaWdodD0iMTAwJSIgLz48L2NsaXBQYXRoPjxwYXRoCiAgICAgICAgIGNsaXAtcGF0aD0idXJsKCNTVkdJRF8zXykiCiAgICAgICAgIGQ9Im0gNDM2LjQsMjYyIC00Ny45LDAgMCwtNDYgYyAwLC00LjcgMy44LC04LjQgOC40LC04LjQgbCAzMSwwIGMgNC43LDAgOC40LDMuOCA4LjQsOC40IGwgMCw0NiB6IgogICAgICAgICBpZD0icGF0aDQ5ODEiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgIHN0eWxlPSJmaWxsOiM0YTUyNjEiIC8+PC9nPjxyZWN0CiAgICAgICB4PSIzOTQuNzk5OTkiCiAgICAgICB5PSIyMTguNyIKICAgICAgIHdpZHRoPSIzNS4wOTk5OTgiCiAgICAgICBoZWlnaHQ9IjQzLjIwMDAwMSIKICAgICAgIGlkPSJyZWN0NDk4MyIKICAgICAgIHN0eWxlPSJmaWxsOiM4MDk2YTEiIC8+PHBhdGgKICAgICAgIGQ9Im0gMzE3LjYsMjM5LjUgMCw2MSA3MSwwLjIgYyAwLDAgMCwtNTcuMyAwLC02MSAwLC0xOS41IC0xNi4xLC0zNS42IC0zNS42LC0zNS42IC0xOS42LDAgLTM1LjQsMTUuOCAtMzUuNCwzNS40IgogICAgICAgaWQ9InBhdGg0OTg1IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgIHN0eWxlPSJmaWxsOiM4NTVjMzMiIC8+PHBhdGgKICAgICAgIGQ9Im0gNDEyLjQsMzc2LjUgLTExNC4yLDAgYyAtMzUuNiwwIC01MC45LC00NS4yIC0yMi42LC02Ni44IGwgNjMuOCwtNDcuOCA5Ni45LDAgMCw5MC43IGMgMC4xLDEzLjIgLTEwLjYsMjMuOSAtMjMuOSwyMy45IgogICAgICAgaWQ9InBhdGg0OTg3IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgIHN0eWxlPSJmaWxsOiMyNmE2YWIiIC8+PHBvbHlnb24KICAgICAgIHBvaW50cz0iMzQ1LjcsMjU3LjMgMzM0LjgsMjk4LjggMjg1LjEsMzAyLjUgIgogICAgICAgaWQ9InBvbHlnb240OTg5IgogICAgICAgc3R5bGU9ImZpbGw6IzQyYzljOSIgLz48cG9seWdvbgogICAgICAgcG9pbnRzPSIzNTQsMjgzLjggMzMyLjUsMjgzLjggMzQ1LjcsMjU3LjMgIgogICAgICAgaWQ9InBvbHlnb240OTkxIgogICAgICAgc3R5bGU9ImZpbGw6I2Y3ZjVlOCIgLz48cG9seWdvbgogICAgICAgcG9pbnRzPSIzNzUuNCwyODMuOCAzNTQsMjgzLjggMzYyLjIsMjU3LjMgIgogICAgICAgaWQ9InBvbHlnb240OTkzIgogICAgICAgc3R5bGU9ImZpbGw6I2Y3ZjVlOCIgLz48cG9seWdvbgogICAgICAgcG9pbnRzPSIzNzMuMSwyOTguOCAzMzQuOCwyOTguOCAzMzIuNSwyODMuOCAzNzUuNCwyODMuOCAiCiAgICAgICBpZD0icG9seWdvbjQ5OTUiCiAgICAgICBzdHlsZT0iZmlsbDojYmRkMWNmIiAvPjxwYXRoCiAgICAgICBkPSJtIDQwMC42LDM3Ni41IGMgLTMuNSwtMjYuMiAtMTAuNiwtNTggLTI3LjMsLTc3LjcgbCAtMC4yLDAgLTE5LDAgLTE5LDAgLTAuMiwwIGMgLTE2LjcsMTkuOCAtMjMuOCw1MS41IC0yNy4zLDc3LjcgbCA5MywwIHoiCiAgICAgICBpZD0icGF0aDQ5OTciCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgc3R5bGU9ImZpbGw6I2Y3ZjVlOCIgLz48cGF0aAogICAgICAgZD0ibSAzNTcsMjU4IC02LjEsMCBjIC02LjQsMCAtMTEuNSwtNS4yIC0xMS41LC0xMS41IGwgMCwtMTkuNyAyOS4yLDAgMCwxOS43IGMgLTAuMSw2LjMgLTUuMywxMS41IC0xMS42LDExLjUiCiAgICAgICBpZD0icGF0aDQ5OTkiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgc3R5bGU9ImZpbGw6I2ZmY2M5OSIgLz48cGF0aAogICAgICAgZD0ibSAzMzUuOCwzNzYuNSAwLC03Ny43IGMgMTIuNCwyOS4xIDI3LjcsNjQuMyA0Ni41LDc3LjcgbCAtNDYuNSwwIHoiCiAgICAgICBpZD0icGF0aDUwMDEiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgc3R5bGU9ImZpbGw6I2JkZDFjZiIgLz48cG9seWdvbgogICAgICAgcG9pbnRzPSIzNjIuMiwyNTcuMyAzNDUuNywyNTcuMyAzNTQsMjgzLjggIgogICAgICAgaWQ9InBvbHlnb241MDAzIgogICAgICAgc3R5bGU9ImZpbGw6I2ZmY2M5OSIgLz48cG9seWdvbgogICAgICAgcG9pbnRzPSI0MzYuNCwzMTUuMyAzOTQuOCwyNjIgNDM2LjQsMjYyICIKICAgICAgIGlkPSJwb2x5Z29uNTAwNSIKICAgICAgIHN0eWxlPSJmaWxsOiM0MmM5YzkiIC8+PC9nPjwvc3ZnPg==",
"footerLogo": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTc5LjkiIGhlaWdodD0iMzIuNCIgdmlld0JveD0iMCAwIDE3OS45IDMyLjQiPgogIDxwYXRoIGZpbGw9IiM0OTUyNjAiIGQ9Ik0zMy4xIDExLjJoLTguNVY1LjhjMC0yLjMgMS45LTQuMiA0LjItNC4yIDIuMyAwIDQuMiAxLjkgNC4yIDQuMnY1LjR6Ii8+CiAgPHBhdGggZmlsbD0iIzdGOTZBMSIgZD0iTTI1LjggMy42SDMydjcuNmgtNi4yeiIvPgogIDxwYXRoIGZpbGw9IiM4NDVCMzIiIGQ9Ik0xMi4yIDcuMlYxOGgxMi41VjcuMmMwLTMuNC0yLjgtNi4yLTYuMi02LjJzLTYuMyAyLjgtNi4zIDYuMnoiLz4KICA8cGF0aCBmaWxsPSIjMjZBN0FBIiBkPSJNMjguOSAzMS40SDguN2MtNi4zIDAtOS04LTQtMTEuOEwxNiAxMS4yaDE3LjF2MTZjMCAyLjMtMS45IDQuMi00LjIgNC4yeiIvPgogIDxwYXRoIGZpbGw9IiM0M0M5QzkiIGQ9Ik0xNS4yIDE3LjdsLTguOC43IDEwLjctOCIvPgogIDxwYXRoIGZpbGw9IiNGNkY0RTciIGQ9Ik0xNC44IDE1LjFsMi4zLTQuNyAxLjUgNC43bTAgMGwxLjQtNC43IDIuMyA0LjciLz4KICA8cGF0aCBmaWxsPSIjQkREMUNGIiBkPSJNMjEuOSAxNy43aC02LjdsLS40LTIuNmg3LjUiLz4KICA8cGF0aCBmaWxsPSIjRjZGNEU3IiBkPSJNMjYuOCAzMS40Yy0uNi00LjYtMS45LTEwLjItNC44LTEzLjdoLTYuOGMtMyAzLjUtNC4yIDkuMS00LjggMTMuN2gxNi40eiIvPgogIDxwYXRoIGZpbGw9IiNGRkNEOUEiIGQ9Ik0xOC42IDEwLjVjLTEuNCAwLTIuNi0xLjItMi42LTIuNlY1aDUuMXYyLjljMCAxLjUtMS4xIDIuNi0yLjUgMi42eiIvPgogIDxwYXRoIGZpbGw9IiNCREQxQ0YiIGQ9Ik0xNS40IDMxLjRWMTcuN2MyLjIgNS4xIDQuOSAxMS4zIDguMiAxMy43aC04LjJ6Ii8+CiAgPHBhdGggZmlsbD0iI0ZGQ0Q5QSIgZD0iTTE3LjEgMTAuNGwxLjUgNC43IDEuNC00LjciLz4KICA8cGF0aCBmaWxsPSIjNDNDOUM5IiBkPSJNMjUuOCAxMS4yaDcuM3Y5LjQiLz4KICA8cGF0aCBmaWxsPSIjQkNEMUNGIiBkPSJNNTIuMyAxNS4xaC0xLjZsLS4yLTEuNGMtLjItLjItLjUtLjQtLjgtLjVzLS43LS4yLTEuMi0uMmMtLjkgMC0xLjcuMy0yLjIgMXMtLjggMS42LS44IDIuN3YuNGMwIDEuMS4zIDIgLjggMi43LjUuNyAxLjIgMSAyLjEgMSAuNCAwIC44LS4xIDEuMi0uMi40LS4xLjYtLjMuOC0uNWwuMi0xLjRoMS42djIuMWMtLjQuNS0xIC45LTEuNyAxLjItLjcuMy0xLjQuNS0yLjMuNS0xLjUgMC0yLjYtLjUtMy42LTEuNXMtMS40LTIuMy0xLjQtMy45di0uNGMwLTEuNi41LTIuOSAxLjQtMy45czIuMS0xLjUgMy42LTEuNWMuOCAwIDEuNi4yIDIuMy41LjcuMyAxLjIuNyAxLjcgMS4ydjIuMXptMS41IDUuOWwuOC0uMSAzLjMtOS40aDIuMmwzLjMgOS40LjguMXYxLjNoLTMuN1YyMWwuOC0uMS0uNS0xLjVoLTMuNWwtLjUgMS41LjguMXYxLjNoLTMuN1YyMXptMy45LTMuMmgyLjVMNTkgMTRsLTEuMyAzLjh6bTcuOCA0LjVWMjFsMS4yLS4yVjEzbC0xLjItLjJ2LTEuM0g3MHYxLjNsLTEuMi4ydjcuNmgzLjFsLjEtMS40aDEuN3YzaC04LjJ6bTkuNSAwVjIxbDEuMi0uMlYxM2wtMS4yLS4ydi0xLjNoNC42djEuM2wtMS4zLjJ2Ny42aDMuMWwuMS0xLjRoMS43djNINzV6bTkuNS05LjV2LTEuM0g4OXYxLjNsLTEuMS4ydjcuOGwxLjEuMnYxLjNoLTQuNVYyMWwxLjItLjJWMTNsLTEuMi0uMnptMTUuOSA0LjJjMCAxLjYtLjUgMi45LTEuNCAzLjktLjkgMS0yLjEgMS42LTMuNiAxLjZzLTIuNi0uNS0zLjUtMS42LTEuNC0yLjMtMS40LTMuOXYtLjJjMC0xLjYuNC0yLjkgMS4zLTMuOXMyLjEtMS42IDMuNS0xLjZjMS41IDAgMi43LjUgMy42IDEuNnMxLjQgMi40IDEuNCAzLjl2LjJ6bS0yLjItLjJjMC0xLjEtLjItMi0uNy0yLjdzLTEuMi0xLTIuMS0xLTEuNi4zLTIgMS0uNyAxLjYtLjcgMi43di4yYzAgMS4xLjIgMi4xLjcgMi44LjUuNyAxLjEgMSAyIDEgLjkgMCAxLjYtLjMgMi4xLTFzLjctMS42LjctMi44di0uMnptOC44LTUuM2MxLjIgMCAyLjIuMyAyLjkgMVMxMTEgMTQgMTExIDE1cy0uNCAxLjktMS4xIDIuNWMtLjcuNi0xLjcuOS0yLjkuOWgtMS44djIuNGwxLjIuMnYxLjNoLTQuNVYyMWwxLjItLjJWMTNsLTEuMi0uMnYtMS4zaDUuMXptLTEuOCA1LjJoMS44Yy42IDAgMS4xLS4yIDEuNC0uNXMuNS0uOC41LTEuMy0uMi0xLS41LTEuM2MtLjMtLjMtLjgtLjUtMS40LS41aC0xLjh2My42em0xNC4xLjloLTMuN3YzLjFoMy41bC4xLTEuM2gxLjd2M2gtOC42VjIxbDEuMi0uMlYxM2wtMS4yLS4ydi0xLjNoOC42djNoLTEuN2wtLjEtMS4zaC0zLjV2Mi43aDMuN3YxLjd6Ii8+CiAgPHBhdGggZmlsbD0iI0ZGRiIgZD0iTTEzNC4zIDExLjZsLjEgMS4xYy4yLS40LjUtLjcuOS0xIC40LS4yLjgtLjQgMS4zLS40cy44LjEgMS4xLjNjLjMuMi41LjUuNy44LjItLjMuNS0uNi44LS44LjMtLjIuNy0uMyAxLjItLjMuNCAwIC43LjEgMSAuMi4zLjEuNS4zLjguNi4yLjMuNC42LjUgMSAuMS40LjIuOS4yIDEuNHY3LjhoLTIuMnYtNy45YzAtLjQtLjEtLjctLjMtLjktLjItLjItLjQtLjItLjctLjItLjMgMC0uNS4xLS42LjJzLS4zLjMtLjMuNXY4LjNoLTIuMnYtNy45YzAtLjQtLjEtLjctLjMtLjktLjItLjItLjQtLjMtLjctLjMtLjMgMC0uNS4xLS43LjItLjIuMS0uMy4zLS40LjV2OC4zaC0yLjJWMTEuNmgyem0xMS4zIDBoNS43djguOGgzLjJ2MmgtOC45di0yaDMuM3YtNi44aC0zLjN2LTJ6bTMuMS0yLjhjMC0uNC4xLS43LjQtLjkuMi0uMi42LS40IDEtLjRzLjguMSAxIC40Yy4yLjIuNC41LjQuOXMtLjEuNy0uNC45Yy0uMi4yLS42LjQtMSAuNHMtLjgtLjEtMS0uNGMtLjItLjItLjQtLjUtLjQtLjl6bTEwLjcgMi44bC4xIDEuNWMuNC0uNS45LTEgMS40LTEuMi42LS4zIDEuMi0uNCAxLjgtLjQuNSAwIDEgLjEgMS41LjIuNS4yLjguNCAxLjIuNy4zLjMuNi44LjggMS4zLjIuNS4zIDEuMi4zIDEuOXY2LjdoLTIuNHYtNi43YzAtLjQtLjEtLjgtLjItMS4xLS4xLS4zLS4yLS41LS40LS43LS4yLS4yLS40LS4zLS43LS40LS4zLS4xLS42LS4xLS45LS4xLS41IDAtMSAuMS0xLjQuMy0uNC4yLS43LjUtLjkuOXY3LjdoLTIuNFYxMS42aDIuMnptMTAuNiAwaDUuN3Y4LjhoMy4ydjJIMTcwdi0yaDMuM3YtNi44SDE3MHYtMnptMy4xLTIuOGMwLS40LjEtLjcuNC0uOS4yLS4yLjYtLjQgMS0uNHMuOC4xIDEgLjRjLjIuMi40LjUuNC45cy0uMS43LS40LjljLS4yLjItLjYuNC0xIC40cy0uOC0uMS0xLS40Yy0uMy0uMi0uNC0uNS0uNC0uOXoiLz4KPC9zdmc+",
"cardLogo": "data:image/png;base64,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",
"appLogo": "data:image/png;base64,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",
"homeUrl": "/pxt-calliope/",
"embedUrl": "https://mini.pxt.io/",
"privacyUrl": "https://go.microsoft.com/fwlink/?LinkId=521839",
"termsOfUseUrl": "https://go.microsoft.com/fwlink/?LinkID=206977",
"githubUrl": "https://github.com/Microsoft/pxt-calliope",
"crowdinProject": "kindscript",
"organization": "Microsoft MakeCode",
"organizationUrl": "https://makecode.com/",
"organizationLogo": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAS0AAAEtCAMAAABqPcbcAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAf7oAAKTvP7ryb8v18lAi9XtYnss/tthv/7kA/8o//9dv95yCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApRt6LQAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAALiEAAC4hAQdb/P8AAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMTJDBGvsAAACn0lEQVR4Xu3QsVUDMRQAQYHB5gz9tyuSX8BtpmCmgn27Nvet/X2U53SN18dR3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq1n4e5W82jZ/XUdZkcYdbhVuFW4VbhVuFW4VbhVuFW4VbhVuFW4VbxdqPo3xN1/h9H2Xtz6M8ZtN4X0dxq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcKtwq3CrcOu+6/oHGlSc5B6nYrEAAAAASUVORK5CYII=",
"organizationWideLogo": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABmcAAAFeCAMAAABHKDtZAAAAdVBMVEUAAADyUCKAugGAugHyUCLyUCKAugGAugGAugH///////////////////////////////////////////////////////////+AugHyUCICpO8CpO8CpO8CpO//uQL/uQL/uQL/uQLyUCKAugH///8CpO//uQLk57r3AAAAInRSTlMAv4BAj4Cfr78wQFCAcBAgYL/fz6/vj58gQL+An2BAgL8wO9ga1QAAAAFiS0dECfHZpewAAAAJcEhZcwAAAJYAAACWAHFG/vAAAC7SSURBVHja7Z2Ldus8kl6dnkwmkiiJkigp6U7mFifv/4iR7WP/upDEV0ABIOm915pevaaPSZACsYFCAXj7z1nwX96e+Nv/mQX/9AYA8NupbRA8AwCwbGobBM8AACyb2gbBMwAAy6a2QfAMAMCyqW0QPAMAsGxqG0Tjvz4XG88AAMyE2gbR+OfnYuMZAICZUNsgeAYAYNnUNgieAQBYNrUNgmcAAJZNbYPgGQCAZVPbIHgGAGDZ1DYIngEAWDa1DYJnAACWTW2D4BkAgGVT2yB4BgBg2dQ2CJ4BAFg2tQ2CZwAAlk1tg+AZAIBlU9sgeAYAYNnUNgieAQBYNrUNgmcAAJZNbYPgGQCAZVPbIHgGAGDZ1DYIngEAWDa1DYJnAACWTW2D4BkAgGVT2yB4BgBg2dQ2CJ4BAFg2tQ0S6Zn/VtsgeAYAQKO2QSI9w3gGAGAm1DYIngEAWDa1DYJnAACWTW2D4BkAgGVT2yCRniEPAABgJtQ2SKRn/qW2QfAMAIBGbYNEeua/1zYIngEA0KhtEDwDALBsahsEzwAALJvaBsEzAADLprZB8AwAwLKpbRA8AwCwbGobBM8AACyb2gbBMwAAy6a2QfAMAMCyqW0QPAMAsGxqGwTPAAAsm9oGwTMAAMumtkHwDADAsqltEDwDALBsahsEzwAALJvaBsEzAADLprZB8AwAwLKpbRA8AwBQkNV60/zFdr3eZb9lbYPgGQCAIuzb5nB87+F0aDarjDeubRA8AwCQnf22O7+Pcj4060w3r20QPAMAkJf95fSukef+tQ2CZwAAMrJrVcngmUfwDABAmP31rFsGzzyAZwAAQuyvFsngmUfwDADAODurZfDMA3gGAGCUrSlihmfw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",
"browserSupport": [
{
"name": "unsupported",
"os": "*",
"path": "/browsers"
},
{
"name": "unsupported",
"os": "mac",
"path": "/browsers/mac"
},
{
"name": "unsupported",
"os": "linux",
"path": "browsers/linux"
},
{
"name": "unsupported",
"os": "rpi",
"path": "/raspberry-pi"
},
{
"name": "unsupported",
"os": "windows",
"path": "/browsers/windows"
}
],
"boardName": "Calliope mini",
"hideSideDocs": true,
"invertedMenu": true,
"invertedToolbox": true,
"monacoToolbox": false,
"hasAudio": true,
"simAnimationEnter": "rotate in",
"simAnimationExit": "rotate out",
"blocklyOptions": {
"grid": {
"spacing": 45,
"length": 7,
"colour": "rgba(189, 195, 199, 0.30)",
"snap": false
}
},
"docMenu": [],
"id": "calliope",
"title": "calliope mini - Blocks / Javascript editor",
"name": " calliope",
"description": "A Blocks / JavaScript code editor for the calliope mini.",
"htmlDocIncludes": {},
"locales": {}
},
"blocksprj": {
"id": "blocksprj",
"config": {
"name": "{0} block",
"dependencies": {
"core": "*",
"radio": "*"
},
"description": "",
"files": [
"main.blocks",
"main.ts",
"README.md"
]
},
"files": {
"README.md": "",
"main.blocks": "<xml xmlns=\"http://www.w3.org/1999/xhtml\">\n<block type=\"device_forever\">\n<statement name=\"HANDLER\">\n<block type=\"device_show_leds\">\n<field name=\"LED00\">FALSE</field>\n<field name=\"LED10\">FALSE</field>\n<field name=\"LED20\">FALSE</field>\n<field name=\"LED30\">FALSE</field>\n<field name=\"LED40\">FALSE</field>\n<field name=\"LED01\">FALSE</field>\n<field name=\"LED11\">TRUE</field>\n<field name=\"LED21\">FALSE</field>\n<field name=\"LED31\">TRUE</field>\n<field name=\"LED41\">FALSE</field>\n<field name=\"LED02\">FALSE</field>\n<field name=\"LED12\">FALSE</field>\n<field name=\"LED22\">FALSE</field>\n<field name=\"LED32\">FALSE</field>\n<field name=\"LED42\">FALSE</field>\n<field name=\"LED03\">TRUE</field>\n<field name=\"LED13\">FALSE</field>\n<field name=\"LED23\">FALSE</field>\n<field name=\"LED33\">FALSE</field>\n<field name=\"LED43\">TRUE</field>\n<field name=\"LED04\">FALSE</field>\n<field name=\"LED14\">TRUE</field>\n<field name=\"LED24\">TRUE</field>\n<field name=\"LED34\">TRUE</field>\n<field name=\"LED44\">FALSE</field>\n<next>\n<block type=\"device_show_leds\">\n<field name=\"LED00\">FALSE</field>\n<field name=\"LED10\">FALSE</field>\n<field name=\"LED20\">FALSE</field>\n<field name=\"LED30\">FALSE</field>\n<field name=\"LED40\">FALSE</field>\n<field name=\"LED01\">FALSE</field>\n<field name=\"LED11\">FALSE</field>\n<field name=\"LED21\">FALSE</field>\n<field name=\"LED31\">FALSE</field>\n<field name=\"LED41\">FALSE</field>\n<field name=\"LED02\">FALSE</field>\n<field name=\"LED12\">FALSE</field>\n<field name=\"LED22\">FALSE</field>\n<field name=\"LED32\">FALSE</field>\n<field name=\"LED42\">FALSE</field>\n<field name=\"LED03\">FALSE</field>\n<field name=\"LED13\">FALSE</field>\n<field name=\"LED23\">FALSE</field>\n<field name=\"LED33\">FALSE</field>\n<field name=\"LED43\">FALSE</field>\n<field name=\"LED04\">FALSE</field>\n<field name=\"LED14\">FALSE</field>\n<field name=\"LED24\">FALSE</field>\n<field name=\"LED34\">FALSE</field>\n<field name=\"LED44\">FALSE</field>\n</block>\n</next>\n</block>\n</statement>\n</block>\n</xml>",
"main.ts": "basic.forever(() => {\n basic.showLeds(`\n . # . # .\n # . # . #\n # . . . #\n . # . # .\n . . # . .\n `)\n basic.showLeds(`\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n `)\n})"
}
},
"tsprj": {
"id": "tsprj",
"config": {
"name": "{0} bit",
"dependencies": {
"core": "*",
"radio": "*"
},
"description": "",
"files": [
"main.ts",
"README.md"
]
},
"files": {
"README.md": "",
"main.ts": "basic.showLeds(`\n . . . . .\n . # . # .\n . . . . .\n # . . . #\n . # # # .\n `);"
}
},
"bundledpkgs": {
"core": {
"ManagedBuffer.cpp": "#include \"MicroBit.h\"\n#include \"ManagedBuffer.h\"\n#include <limits.h>\n\nstatic const char empty[] __attribute__ ((aligned (4))) = \"\\xff\\xff\\0\\0\\0\";\n\n/**\n * Internal constructor helper.\n * Configures this ManagedBuffer to refer to the static empty buffer.\n */\nvoid ManagedBuffer::initEmpty()\n{\n ptr = (BufferData*)(void*)empty;\n}\n\n/**\n * Default Constructor. \n * Creates an empty ManagedBuffer. \n *\n * Example:\n * @code\n * ManagedBuffer p(); \n * @endcode\n */\nManagedBuffer::ManagedBuffer()\n{\n initEmpty();\n}\n\n/**\n * Constructor. \n * Creates an empty ManagedBuffer of the given size. \n *\n * @param length The length of the buffer to create.\n *\n * Example:\n * @code\n * ManagedBuffer p(16); // Creates a ManagedBuffer 16 bytes long.\n * @endcode\n */\nManagedBuffer::ManagedBuffer(int length)\n{\n this->init(NULL, length);\n}\n\n/**\n * Constructor. \n * Creates a new ManagedBuffer of the given size,\n * and fills it with the data provided.\n *\n * @param data The data with which to fill the buffer.\n * @param length The length of the buffer to create.\n * \n * Example:\n * @code\n * uint8_t buf = {13,5,2};\n * ManagedBuffer p(buf, 3); // Creates a ManagedBuffer 3 bytes long.\n * @endcode\n */\nManagedBuffer::ManagedBuffer(uint8_t *data, int length)\n{\n this->init(data, length);\n}\n\n/**\n * Copy Constructor. \n * Add ourselves as a reference to an existing ManagedBuffer.\n * \n * @param buffer The ManagedBuffer to reference.\n *\n * Example:\n * @code\n * ManagedBuffer p();\n * ManagedBuffer p2(i); // Refers to the same buffer as p. \n * @endcode\n */\nManagedBuffer::ManagedBuffer(const ManagedBuffer &buffer)\n{\n ptr = buffer.ptr;\n ptr->incr();\n}\n\n/**\n * Constructor. \n * Create a buffer from a raw BufferData pointer. It will ptr->incr(). This is to be used by specialized runtimes.\n *\n * @param p The pointer to use.\n */ \nManagedBuffer::ManagedBuffer(BufferData *p)\n{\n ptr = p;\n ptr->incr();\n}\n\n/**\n * Internal constructor-initialiser.\n *\n * @param data The data with which to fill the buffer.\n * @param length The length of the buffer to create.\n * \n */\nvoid ManagedBuffer::init(uint8_t *data, int length)\n{\n if (length <= 0) {\n initEmpty();\n return;\n }\n\n ptr = (BufferData *) malloc(sizeof(BufferData) + length);\n ptr->init();\n\n ptr->length = length;\n\n // Copy in the data buffer, if provided.\n if (data)\n memcpy(ptr->payload, data, length);\n else\n memset(ptr->payload, 0, length);\n}\n\n/**\n * Destructor. \n * Removes buffer resources held by the instance.\n */\nManagedBuffer::~ManagedBuffer()\n{\n ptr->decr();\n}\n\n/**\n * Copy assign operation. \n *\n * Called when one ManagedBuffer is assigned the value of another using the '=' operator.\n * Decrements our reference count and free up the buffer as necessary.\n * Then, update our buffer to refer to that of the supplied ManagedBuffer,\n * and increase its reference count.\n *\n * @param p The ManagedBuffer to reference.\n * \n * Example:\n * @code\n * uint8_t buf = {13,5,2};\n * ManagedBuffer p1(16); \n * ManagedBuffer p2(buf, 3); \n *\n * p1 = p2; \n * @endcode\n */\nManagedBuffer& ManagedBuffer::operator = (const ManagedBuffer &p)\n{\n if(ptr == p.ptr)\n return *this;\n\n ptr->decr();\n ptr = p.ptr;\n ptr->incr();\n\n return *this;\n}\n\n/**\n * Equality operation.\n *\n * Called when one ManagedBuffer is tested to be equal to another using the '==' operator.\n *\n * @param p The ManagedBuffer to test ourselves against.\n * @return true if this ManagedBuffer is identical to the one supplied, false otherwise.\n * \n * Example:\n * @code\n *\n * uint8_t buf = {13,5,2};\n * ManagedBuffer p1(16); \n * ManagedBuffer p2(buf, 3); \n *\n * if(p1 == p2) // will be true\n * uBit.display.scroll(\"same!\");\n * @endcode\n */\nbool ManagedBuffer::operator== (const ManagedBuffer& p)\n{\n if (ptr == p.ptr)\n return true;\n else\n return (ptr->length == p.ptr->length && (memcmp(ptr->payload, p.ptr->payload, ptr->length)==0)); \n}\n\n/**\n * Sets the byte at the given index to value provided.\n * @param position The index of the byte to change.\n * @param value The new value of the byte (0-255).\n * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.\n *\n * Example:\n * @code\n * ManagedBuffer p1(16); \n * p1.setByte(0,255); // Sets the firts byte in the buffer to the value 255.\n * @endcode\n */\nint ManagedBuffer::setByte(int position, uint8_t value)\n{\n if (0 <= position && position < ptr->length)\n {\n ptr->payload[position] = value;\n return MICROBIT_OK;\n }\n else\n {\n return MICROBIT_INVALID_PARAMETER;\n }\n}\n\n/**\n * Determines the value of the given byte in the buffer.\n *\n * @param position The index of the byte to read.\n * @return The value of the byte at the given position, or MICROBIT_INVALID_PARAMETER.\n *\n * Example:\n * @code\n * ManagedBuffer p1(16); \n * p1.setByte(0,255); // Sets the firts byte in the buffer to the value 255.\n * p1.getByte(0); // Returns 255.\n * @endcode\n */\nint ManagedBuffer::getByte(int position)\n{\n if (0 <= position && position < ptr->length)\n return ptr->payload[position];\n else\n return MICROBIT_INVALID_PARAMETER;\n} \n\n/**\n * Get current ptr, do not decr() it, and set the current instance to an empty buffer.\n * This is to be used by specialized runtimes which pass BufferData around.\n */\nBufferData *ManagedBuffer::leakData()\n{\n BufferData* res = ptr;\n initEmpty();\n return res;\n}\n\n\nint ManagedBuffer::fill(uint8_t value, int offset, int length)\n{\n if (offset < 0 || offset > ptr->length)\n return MICROBIT_INVALID_PARAMETER;\n if (length < 0)\n length = ptr->length;\n length = min(length, ptr->length - offset);\n\n memset(ptr->payload + offset, value, length);\n\n return MICROBIT_OK;\n}\n\nManagedBuffer ManagedBuffer::slice(int offset, int length) const\n{\n offset = min(ptr->length, offset);\n if (length < 0)\n length = ptr->length;\n length = min(length, ptr->length - offset);\n return ManagedBuffer(ptr->payload + offset, length);\n}\n\nvoid ManagedBuffer::shift(int offset, int start, int len)\n{\n if (len < 0) len = ptr->length - start; \n if (start < 0 || start + len > ptr->length || start + len < start\n || len == 0 || offset == 0 || offset == INT_MIN) return;\n if (offset <= -len || offset >= len) {\n fill(0);\n return;\n }\n \n uint8_t *data = ptr->payload + start;\n if (offset < 0) {\n offset = -offset;\n memmove(data + offset, data, len - offset);\n memset(data, 0, offset);\n } else {\n len = len - offset;\n memmove(data, data + offset, len);\n memset(data + len, 0, offset);\n }\n}\n\nvoid ManagedBuffer::rotate(int offset, int start, int len)\n{\n if (len < 0) len = ptr->length - start;\n if (start < 0 || start + len > ptr-> length || start + len < start\n || len == 0 || offset == 0 || offset == INT_MIN) return;\n\n if (offset < 0)\n offset += len << 8; // try to make it positive\n offset %= len;\n if (offset < 0)\n offset += len;\n\n uint8_t *data = ptr->payload + start;\n\n uint8_t *n_first = data + offset;\n uint8_t *first = data;\n uint8_t *next = n_first;\n uint8_t *last = data + len;\n\n while (first != next) {\n uint8_t tmp = *first;\n *first++ = *next;\n *next++ = tmp;\n if (next == last) {\n next = n_first;\n } else if (first == n_first) {\n n_first = next;\n }\n }\n}\n\nint ManagedBuffer::writeBuffer(int dstOffset, const ManagedBuffer &src, int srcOffset, int length)\n{\n if (length < 0)\n length = src.length();\n\n if (srcOffset < 0 || dstOffset < 0 || dstOffset > ptr->length)\n return MICROBIT_INVALID_PARAMETER;\n\n length = min(src.length() - srcOffset, ptr->length - dstOffset);\n\n if (length < 0)\n return MICROBIT_INVALID_PARAMETER;\n\n if (ptr == src.ptr) {\n memmove(getBytes() + dstOffset, src.ptr->payload + srcOffset, length);\n } else {\n memcpy(getBytes() + dstOffset, src.ptr->payload + srcOffset, length);\n }\n\n return MICROBIT_OK;\n}\n\nint ManagedBuffer::writeBytes(int offset, uint8_t *src, int length, bool swapBytes)\n{\n if (offset < 0 || length < 0 || offset + length > ptr->length)\n return MICROBIT_INVALID_PARAMETER;\n\n if (swapBytes) {\n uint8_t *p = ptr->payload + offset + length;\n for (int i = 0; i < length; ++i)\n *--p = src[i];\n } else {\n memcpy(ptr->payload + offset, src, length);\n }\n\n return MICROBIT_OK;\n}\n\nint ManagedBuffer::readBytes(uint8_t *dst, int offset, int length, bool swapBytes) const\n{\n if (offset < 0 || length < 0 || offset + length > ptr->length)\n return MICROBIT_INVALID_PARAMETER;\n\n if (swapBytes) {\n uint8_t *p = ptr->payload + offset + length;\n for (int i = 0; i < length; ++i)\n dst[i] = *--p;\n } else {\n memcpy(dst, ptr->payload + offset, length);\n }\n\n return MICROBIT_OK;\n}\n",
"ManagedBuffer.h": "#ifndef MICROBIT_MANAGED_BUFFER_H\n#define MICROBIT_MANAGED_BUFFER_H\n\n#include \"mbed.h\"\n#include \"RefCounted.h\"\n\nstruct BufferData : RefCounted\n{\n uint16_t length; // The length of the payload in bytes\n uint8_t payload[0]; // ManagedBuffer data\n};\n\n/**\n * Class definition for a ManagedBuffer.\n * A ManagedBuffer holds a series of bytes, used with MicroBitRadio channels and in other places.\n * n.b. This is a mutable, managed type.\n */\nclass ManagedBuffer\n{\n BufferData *ptr; // Pointer to payload data\n \n public:\n\n /**\n * Default Constructor. \n * Creates an empty ManagedBuffer. The 'ptr' field in all empty buffers is shared.\n *\n * Example:\n * @code\n * ManagedBuffer p(); \n * @endcode\n */\n ManagedBuffer();\n\n /**\n * Constructor. \n * Creates a new ManagedBuffer of the given size. \n *\n * @param length The length of the buffer to create.\n *\n * Example:\n * @code\n * ManagedBuffer p(16); // Creates a ManagedBuffer 16 bytes long.\n * @endcode\n */\n ManagedBuffer(int length);\n\n /**\n * Constructor. \n * Creates an empty ManagedBuffer of the given size,\n * and fills it with the data provided.\n *\n * @param data The data with which to fill the buffer.\n * @param length The length of the buffer to create.\n * \n * Example:\n * @code\n * uint8_t buf[] = {13,5,2};\n * ManagedBuffer p(buf, 3); // Creates a ManagedBuffer 3 bytes long.\n * @endcode\n */\n ManagedBuffer(uint8_t *data, int length);\n\n /**\n * Copy Constructor. \n * Add ourselves as a reference to an existing ManagedBuffer.\n * \n * @param buffer The ManagedBuffer to reference.\n *\n * Example:\n * @code\n * ManagedBuffer p();\n * ManagedBuffer p2(i); // Refers to the same buffer as p. \n * @endcode\n */\n ManagedBuffer(const ManagedBuffer &buffer);\n\n /**\n * Constructor. \n * Create a buffer from a raw BufferData pointer. It will ptr->incr(). This is to be used by specialized runtimes.\n *\n * @param p The pointer to use.\n */ \n ManagedBuffer(BufferData *p);\n\n /**\n * Internal constructor helper.\n * Configures this ManagedBuffer to refer to the static empty buffer.\n */\n void initEmpty();\n\n /**\n * Internal constructor-initialiser.\n *\n * @param data The data with which to fill the buffer.\n * @param length The length of the buffer to create.\n * \n */\n void init(uint8_t *data, int length);\n\n /**\n * Destructor. \n * Removes buffer resources held by the instance.\n */\n ~ManagedBuffer();\n\n /**\n * Provide an array containing the buffer data.\n * @return The contents of this buffer, as an array of bytes.\n */\n uint8_t *getBytes()\n {\n return ptr->payload;\n }\n\n /**\n * Get current ptr, do not decr() it, and set the current instance to an empty buffer.\n * This is to be used by specialized runtimes which pass BufferData around.\n */\n BufferData *leakData();\n\n /**\n * Copy assign operation. \n *\n * Called when one ManagedBuffer is assigned the value of another using the '=' operator.\n * Decrements our reference count and free up the buffer as necessary.\n * Then, update our buffer to refer to that of the supplied ManagedBuffer,\n * and increase its reference count.\n *\n * @param p The ManagedBuffer to reference.\n * \n * Example:\n * @code\n * uint8_t buf = {13,5,2};\n * ManagedBuffer p1(16); \n * ManagedBuffer p2(buf, 3); \n *\n * p1 = p2; \n * @endcode\n */\n ManagedBuffer& operator = (const ManagedBuffer& p);\n\n /**\n * Array access operation (read). \n *\n * Called when a ManagedBuffer is dereferenced with a [] operation.\n * Transparently map this through to the underlying payload for elegance of programming.\n *\n * Example:\n * @code\n * ManagedBuffer p1(16); \n * uint8_t data = p1[0];\n * @endcode\n */\n uint8_t operator [] (int i) const\n {\n return ptr->payload[i];\n }\n\n /**\n * Array access operation (modify). \n *\n * Called when a ManagedBuffer is dereferenced with a [] operation.\n * Transparently map this through to the underlying payload for elegance of programming.\n *\n * Example:\n * @code\n * ManagedBuffer p1(16); \n * p1[0] = 42;\n * @endcode\n */\n uint8_t& operator [] (int i)\n {\n return ptr->payload[i];\n }\n\n /**\n * Equality operation.\n *\n * Called when one ManagedBuffer is tested to be equal to another using the '==' operator.\n *\n * @param p The ManagedBuffer to test ourselves against.\n * @return true if this ManagedBuffer is identical to the one supplied, false otherwise.\n * \n * Example:\n * @code\n *\n * uint8_t buf = {13,5,2};\n * ManagedBuffer p1(16); \n * ManagedBuffer p2(buf, 3); \n *\n * if(p1 == p2) // will be true\n * uBit.display.scroll(\"same!\");\n * @endcode\n */\n bool operator== (const ManagedBuffer& p);\n \n /**\n * Sets the byte at the given index to value provided.\n * @param position The index of the byte to change.\n * @param value The new value of the byte (0-255).\n * @return MICROBIT_OK, or MICROBIT_INVALID_PARAMETER.\n *\n * Example:\n * @code\n * ManagedBuffer p1(16); \n * p1.setByte(0,255); // Sets the first byte in the buffer to the value 255.\n * @endcode\n */\n int setByte(int position, uint8_t value);\n\n /**\n * Determines the value of the given byte in the buffer.\n *\n * @param position The index of the byte to read.\n * @return The value of the byte at the given position, or MICROBIT_INVALID_PARAMETER.\n *\n * Example:\n * @code\n * ManagedBuffer p1(16); \n * p1.setByte(0,255); // Sets the first byte in the buffer to the value 255.\n * p1.getByte(0); // Returns 255.\n * @endcode\n */\n int getByte(int position);\n\n /**\n * Gets number of bytes in this buffer \n * @return The size of the buffer in bytes.\n * \n * Example:\n * @code\n * ManagedBuffer p1(16); \n * p1.length(); // Returns 16.\n * @endcode\n */\n int length() const { return ptr->length; }\n\n int fill(uint8_t value, int offset = 0, int length = -1);\n\n ManagedBuffer slice(int offset = 0, int length = -1) const;\n\n void shift(int offset, int start = 0, int length = -1);\n\n void rotate(int offset, int start = 0, int length = -1);\n\n int readBytes(uint8_t *dst, int offset, int length, bool swapBytes = false) const;\n\n int writeBytes(int dstOffset, uint8_t *src, int length, bool swapBytes = false);\n\n int writeBuffer(int dstOffset, const ManagedBuffer &src, int srcOffset = 0, int length = -1);\n\n bool isReadOnly() const { return ptr->isReadOnly(); }\n};\n\n#endif\n\n",
"README.md": "# core\n\nThe core library.\n\n",
"_locales/de/core-jsdoc-strings.json": "{\n \"Math.abs\": \"Gibt den absoluten Wert einer Zahl aus (den Wert unabhängig davon, ob er positiv oder negativ ist).\\nDer absolute Wert von -5 ist zum Beispiel der gleiche wie der von 5.\",\n \"Math.abs|param|x\": \"Ein numerischer Ausdruck, für den der absolute Wert benötigt wird.\",\n \"Math.max\": \"Gibt den größeren von zwei vorhandenen numerischen Ausdrücken aus.\",\n \"Math.min\": \"Gibt den niedrigeren von zwei vorhandenen numerischen Ausdrücken aus.\",\n \"Math.pow\": \"Gibt den Wert eines grundlegenden Ausdrucks bis zu einer bestimmten Stärke aus.\",\n \"Math.pow|param|x\": \"Der Basiswert des Ausdrucks.\",\n \"Math.pow|param|y\": \"Der exponentielle Wert des Ausdrucks.\",\n \"Math.random\": \"Gibt eine pseudozufüllige Zahl zwischen 0 und `max`aus.\",\n \"Math.randomBoolean\": \"Erzeugt zufällig einen \\\"wahr\\\" oder \\\"falsch\\\"-Wert, wie bei einem Münzwurf.\",\n \"Math.sign\": \"Gibt das Vorzeichen von x aus und zeigt an, ob dieses positiv, negativ oder null ist.\",\n \"Math.sign|param|x\": \"Der numerische Ausdruck, der getestet werden soll\",\n \"Math.sqrt\": \"Gibt die Quadratwurzel einer Zahl aus.\",\n \"Math.sqrt|param|x\": \"Ein numerischer Ausdruck.\",\n \"String.charAt\": \"Gibt den Buchstaben beim angegebenen Index aus.\",\n \"String.charAt|param|index\": \"Der null-basierte index des gewünschten Zeichens.\",\n \"String.charCodeAt\": \"Gibt den Unicode-Wert des Zeichens am vorgegebenen Ort aus.\",\n \"String.charCodeAt|param|index\": \"Der null-basierte Index des gewünschten Zeichens. Wenn kein Zeichen am angegeben Index vorhanden ist, wird NaN ausgegeben.\",\n \"String.compare\": \"Bestimmt die relative Reihenfolge zweier Strings (in ASCII).\",\n \"String.compare|param|that\": \"Zeichenfolge, die mit der Zielzeichenfolge verglichen werden soll\",\n \"String.concat\": \"Gibt eine Zeichenfolge aus, die die Verkettung von zwei oder mehr Zeichenfolgen ist.\",\n \"String.concat|param|other\": \"Die Zeichenfolge, die an das Ende einer Zeichenfolge angehängt werden soll.\",\n \"String.fromCharCode\": \"Erstelle Sie eine Zeichenfolge aus dem angegebenen ASCII-Zeichencode.\",\n \"String.isEmpty\": \"Gibt einen Wert aus, der anzeigt, ob die Zeichenfolge leer ist\",\n \"String.length\": \"Gibt die Länge einer Zeichenfolge aus.\",\n \"String.substr\": \"Gibt eine Teilzeichenfolge der aktuellen Zeichenfolge aus.\",\n \"String.substr|param|length\": \"Anzahl der zu extrahierenden Zeichen\",\n \"String.substr|param|start\": \"Erster Zeichenindex, kann beim zählen vom Ende negativ sein, zum Beispiel: 0\",\n \"basic\": \"Bietet Zugriff auf grundlegende mini-Funktionalität.\",\n \"basic.clearScreen\": \"Schalte alle LEDs aus\",\n \"basic.color\": \"Konvertiert den Farbnamen in eine Nummer\",\n \"basic.forever\": \"Wiederholt immer wieder den Code im Hintergrund. Bei jeder Iteration ist es möglich, anderen Code auszuführen.\",\n \"basic.pause\": \"Pausiere für die angegebene Zeit in Millisekunden\",\n \"basic.pause|param|ms\": \"wie lange pausieren, z.B.: 100, 200, 500, 1000, 2000\",\n \"basic.plotLeds\": \"Zeichnet ein Bild auf dem LED-Bildschirm.\",\n \"basic.plotLeds|param|leds\": \"Muster der LEDs, die ein-/ und ausgeschaltet werden\",\n \"basic.rgbw\": \"Konvertiert Rot-, Grün- und Blau-Kanäle in eine RGB-Farbe\",\n \"basic.rgbw|param|blue\": \"Blauwert zwischen 0 und 255, z.B. 255\",\n \"basic.rgbw|param|green\": \"Grünwert zwischen 0 und 255, z.B. 255\",\n \"basic.rgbw|param|red\": \"Rotwert zwischen 0 und 255, z.B. 255\",\n \"basic.rgbw|param|white\": \"Weißwert zwischen 0 und 255, z.B. 0\",\n \"basic.setLedColor\": \"Legt die Farbe der eingebauten LED fest. Setze auf 0, um diese abzuschalten.\",\n \"basic.showAnimation\": \"Zeigt eine Abfolge von LED-Anzeigen als Animation.\",\n \"basic.showAnimation|param|interval\": \"Zeit in Millisekunden zwischen jedem Neuzeichnen\",\n \"basic.showAnimation|param|leds\": \"Muster der LEDs, die ein-/ und ausgeschaltet werden\",\n \"basic.showLeds\": \"Zeichnet ein Bild auf dem LED-Bildschirm.\",\n \"basic.showLeds|param|interval\": \"Zeit in Millisekunden, die nach der Zeichnung gewartet wird\",\n \"basic.showLeds|param|leds\": \"Muster der LEDs, die ein- und ausgeschaltet werden\",\n \"basic.showNumber\": \"Zeige eine Nummer auf dem Display. Wenn die Nummer auf das Display passt (es sich also um eine einstellige Zahl handelt), scrolle nicht weiter.\",\n \"basic.showNumber|param|interval\": \"Scroll-Geschwindigkeit; z.B. 150, 100, 200,-100\",\n \"basic.showString\": \"Zeige Text auf dem Display an, Buchstabe für Buchstabe. Wenn die Zeichenfolge in das Display passt (also wenn es sich um einen einzelnen Buchstaben handelt), scrolle nicht weiter.\",\n \"basic.showString|param|interval\": \"Wie schnell die Zeichen geändert werden; z.B. 150, 100, 200,-100\",\n \"basic.showString|param|text\": \"Text auf dem Bildschirm dargestellt werden soll, z.B.: \\\"Hallo!\\\"\",\n \"control\": \"Laufzeit- und Event-Dienstprogramme.\",\n \"control.assert\": \"Wenn die Bedingung falsch ist, zeige eine Nachricht auf der seriellen Konsole und gebe Panic-Code 098 aus\",\n \"control.deviceName\": \"Erzeugt einen Namen für das Gerät, basierend auf der Seriennummer\",\n \"control.eventSourceId\": \"Gibt den Wert einer C++-Laufzeitkonstanten aus\",\n \"control.eventTimestamp\": \"Holt den Zeitstempel des letzten Events auf dem Bus\",\n \"control.eventValue\": \"Holt den Wert des letzten ausgeführten Events auf dem Bus\",\n \"control.eventValueId\": \"Gibt den Wert einer C++-Laufzeitkonstanten aus\",\n \"control.inBackground\": \"Plant Code, der im Hintergrund wiedergegeben wird.\",\n \"control.onEvent\": \"Startet ein Event auf dem Event-Bus.\",\n \"control.panic\": \"Zeigt einen spezifizierten Fehlercode und hält das Programm an.\",\n \"control.raiseEvent\": \"Startet ein Event auf dem Event-Bus.\",\n \"control.raiseEvent|param|mode\": \"optionale Definition davon, wie ein Event nach dem Erstellen ausgeführt wird (Standard ist \\\"CREATE_AND_FIRE).\",\n \"control.raiseEvent|param|src\": \"ID der Calliope mini-Komponente, die das Event generiert hat, zum Beispiel CALLIOPE_ID_BUTTON_A.\",\n \"control.raiseEvent|param|value\": \"Komponentenspezifischer Code, der den Grund des Events angibt.\",\n \"control.reset\": \"Seit den mini zurück.\",\n \"control.runtimeWarning\": \"Zeige Warnmeldung im Simulator.\",\n \"control.waitMicros\": \"Sperrt die aktuelle Leitung für die Dauer der angegebenen Mikrosekunden\",\n \"control.waitMicros|param|micros\": \"Anzahl der Mikrosekunden, die gewartet werden soll, z.B.: 4\",\n \"game\": \"Eine Einzel-LED-Sprite-Spielumgebung\",\n \"game.addLife\": \"Fügt Leben zum aktuellen Spielstand hinzu\",\n \"game.addScore\": \"Fügt zum aktuellen Spielstand Punkte hinzu\",\n \"game.addScore|param|points\": \"Anzahl von zu verändernden Punkten, z.B.: 1\",\n \"game.createSprite\": \"Erzeugt einen neuen LED-Sprite, der nach rechts zeigt.\",\n \"game.createSprite|param|x\": \"horizontale Koordinate des Sprites, z.B. 2\",\n \"game.createSprite|param|y\": \"vertikale Koordinate des Sprites, z.B. 2\",\n \"game.currentTime\": \"Ruft die verbliebene Zeit (seit `starte Countdown`) oder die aktuelle Zeit (seit das Gerät gestartet wurde oder eine Stoppuhr aktiviert wurde) an.\",\n \"game.gameOver\": \"Gibt über eine Animation ein Spiel wieder.\",\n \"game.invalidSprite\": \"Ruft einen invaliden Sprite ab; wird genutzt, um Locale zu initialisieren.\",\n \"game.isGameOver\": \"Zeigt an, ob das Spil die \\\"Game Over\\\"-Sequenz angezeigt hat.\",\n \"game.isRunning\": \"Holt einen Wert, der anzeigt, ob das Spiel noch läuft. Gibt `falsch`aus, wenn das Spiel zu Ende ist.\",\n \"game.level\": \"Ruft das aktuelle Level ab\",\n \"game.levelUp\": \"Erhöht das Level und zeigt eine Nachricht an.\",\n \"game.life\": \"Ruft das aktuelle Leben ab\",\n \"game.removeLife\": \"Entfernt ein Leben\",\n \"game.score\": \"Ruft den aktuellen Punktestand ab\",\n \"game.setLife\": \"Setzt den aktuellen Wert der Leben\",\n \"game.setScore\": \"Setzt den aktuellen Wert des Spielstands\",\n \"game.showScore\": \"Zeigt den Spielstand auf dem Display.\",\n \"game.startCountdown\": \"Startet einen Spiel-Countdown\",\n \"game.startCountdown|param|ms\": \"Countdown-Dauer in Millisekunden, z.B.: 10000\",\n \"game.startStopwatch\": \"Startet eine Stoppuhr.`aktuelle Zeit`gibt die vergangene Zeit an.\",\n \"images\": \"Erstellung, Bearbeitung und Anzeige von LED-Bildern.\",\n \"images.createBigImage\": \"Erstellt ein Bild mit zwei Einzelbildern.\",\n \"images.createImage\": \"Erstellt ein Bild, das auf den LED-Bildschirm passt.\",\n \"input\": \"Ereignisse und Daten der Sensoren\",\n \"input.acceleration\": \"Holt den Beschleunigungswert in Milli-Erdanziehung (wenn das Board flach mit dem Display nach oben liegt, X = 0, y = 0 und Z =-1024)\",\n \"input.buttonIsPressed\": \"Erhalte den Sie den Tastenstatus (gepresst oder nicht) für ``A`` und ``B``.\",\n \"input.calibrate\": \"Veraltet, Kompasskalibrierung erfolgt automatisch.\",\n \"input.compassHeading\": \"Holt die aktuelle Kompassrichtung in Grad.\",\n \"input.lightLevel\": \"Liest die Lichtintensität auf dem LED-Bildschirm im Bereich von ``0`` (dunkel) und `` 255`` (hell).\",\n \"input.magneticForce\": \"Ruft den Wert der Magnetkraft in ``Mikro-Tesla`` (``µT``) ab. Diese Funktion wird im Simulator nicht unterstützt.\",\n \"input.onButtonPressed\": \"Tue etwas, wenn eine Taste (``A``, ``B`` oder ``A + B``) gedrückt wird\",\n \"input.onGesture\": \"Mache etwas, wenn eine Geste gemacht wird (wie den mini zu schütteln).\",\n \"input.onLogoDown\": \"Fügt Code hinzu, der ausgeführt wird, wenn das Logo nach unten zeigt und das Board vertikal ausgerichtet ist.\",\n \"input.onLogoUp\": \"Fügt Code hinzu, der ausgeführt wird, wenn das Logo nach oben zeigt und das Board vertikal ausgerichtet ist.\",\n \"input.onPinPressed\": \"Mache etwas, wenn eine Pin gehalten wird.\",\n \"input.onPinPressed|param|body\": \"Code, der ausführt wird, wenn ein Pin gehalten wird\",\n \"input.onPinReleased\": \"Mache etwas, wenn der Pin losgelassen wird.\",\n \"input.onPinReleased|param|body\": \"Code, der ausgeführt werden soll, wenn der Pin losgelassen wird\",\n \"input.onScreenDown\": \"Hängt Code an, der ausgeführt wird, wenn der Bildschirm nach unten zeigt.\",\n \"input.onScreenUp\": \"Hängt Code an, der ausgeführt wird, wenn der Bildschirm nach oben zeigt.\",\n \"input.onShake\": \"Hängt Code an, der ausgeführt wird, wenn der mini geschüttelt wird.\",\n \"input.pinIsPressed\": \"Ruft den Pin-Zustand (gehalten oder nicht) ab. Die Erdung muss gehalten werden, um den Stromkreis zu schließen.\",\n \"input.rotation\": \"Die Neigung und Drehung des mini Drehung auf ``X-Achse``oder ``Y-Achse``, in Grad.\",\n \"input.runningTime\": \"Ruft die Anzahl der Millisekunden auf, die seit dem Einschalten vergangen sind.\",\n \"input.setAccelerometerRange\": \"Legt die Stichprobenbereich des Beschleunigungssensors in Schwerkraft fest.\",\n \"input.setAccelerometerRange|param|range\": \"Ein Wert, der die maximale Stärke der gemessenen Beschleunigung beschreibt\",\n \"input.temperature\": \"Ruft die aktuelle Temperatur in Grad Celsius (°C) ab.\",\n \"led\": \"Steuerung des LED-Bildschirms.\",\n \"led.brightness\": \"Ruft die Helligkeit des Bildschirms ab, von 0 (aus) bis 255 (volle Helligkeit).\",\n \"led.enable\": \"Schaltet das Display an und aus\",\n \"led.fadeIn\": \"Blendet die Bildschirmanzeige ein.\",\n \"led.fadeOut\": \"Blendet die Bildschirmhelligkeit aus.\",\n \"led.plot\": \"Schalte die angegebene LED mit Hilfe von X- und Y-Koordinaten ein (X ist horizontal, Y ist vertikal). (0,0) ist die obere linke Ecke.\",\n \"led.plotAll\": \"Schaltet alle LEDs an\",\n \"led.plotBarGraph\": \"Zeigt ein vertikales Balkendiagramm an, basierend auf dem `Wert`und dem `Hoch`-Wert. Wenn `Hoch`0 ist, wird das Diagramm automatisch angepasst.\",\n \"led.plotBarGraph|param|high\": \"maximalen Wert. Wenn dieser 0 ist, wird der Maximalwert automatisch angepasst, z.B.: 0\",\n \"led.plotBarGraph|param|value\": \"aktueller Wert zum Darstellen\",\n \"led.point\": \"Ruft den An/Aus-Status einer vorgegebenen LED mittels X-/Y-Koordinaten ab. (0,0) ist oben links.\",\n \"led.screenshot\": \"Macht einen Screenshot vom LED-Bildschirm und gibt ein Bild aus.\",\n \"led.setBrightness\": \"Lege die Helligkeit des Bildschirms fest, von 0 (aus) bis 255 (volle Helligkeit).\",\n \"led.setBrightness|param|value\": \"Helligkeitswert, z.B.: 255, 127, 0\",\n \"led.setDisplayMode\": \"Legt den Anzeigemodus von Wiedergabe-LEDs zwischen Schwarz und Weiß und Graustufen fest.\",\n \"led.setDisplayMode|param|mode\": \"TODO\",\n \"led.stopAnimation\": \"Bricht die aktuelle Animation ab und löscht andere ausstehende Animationen.\",\n \"led.toggle\": \"Schaltet ein bestimmtes Pixel ein\",\n \"led.toggleAll\": \"Invertiert die aktuelle LED-Anzeige\",\n \"led.unplot\": \"Schalte die angegebene LED mit x-und y-Koordinaten ab (X ist horizontal, y ist vertikal). (0,0) ist oben links.\",\n \"motors\": \"Blöcke, die genutzt werden, um Onboard-Motoren zu steuern\",\n \"motors.dualMotorPower\": \"Steuert zwei an das Board angeschlossene Motoren. Schaltet auf Dual-Motor-Modus um!\",\n \"motors.motorCommand\": \"Schicke Anhalten, Ausrollen oder Anhalten-Befehle an den Motor. Hat im Dual-Motor-Modus keinen Effekt.\",\n \"motors.motorPower\": \"Schaltet den Motor bei einer bestimmten Prozentzahl der Kraft an. Schaltet um auf den Single-Motor-Modus!\",\n \"motors.motorPower|param|power\": \"%percent der Kraft, die an den Motor geschickt wird. Negative Werte laufen rückwärts, z.B. 50\",\n \"music\": \"Generierung von von Musik durch Pin ``P0``.\",\n \"music.beat\": \"Gibt die Dauer eines Taktes in Milli-Sekunden aus\",\n \"music.changeTempoBy\": \"Ändere die Geschwindigkeit um den angegebenen Betrag\",\n \"music.changeTempoBy|param|bpm\": \"Die Änderung in Schlägen pro Minute auf das Tempo, z.B.: 20\",\n \"music.noteFrequency\": \"Ruft die Frequenz einer Note ab.\",\n \"music.playTone\": \"Spielt einen Ton für den angegebenen Zeitraum auf dem Lautsprecher ab.\",\n \"music.playTone|param|ms\": \"Tondauer in Millisekunden (ms)\",\n \"music.rest\": \"Ruht (spielt nichts) für eine bestimmte Zeit auf Pin ``P0``.\",\n \"music.rest|param|ms\": \"Restdauer in Millisekunden (ms)\",\n \"music.ringTone\": \"Spielt einen Ton durch den Lautsprecher ab.\",\n \"music.ringTone|param|frequency\": \"Tonhöhe des abzuspielenden Tones in Hertz (Hz)\",\n \"music.setTempo\": \"Legt die Geschwindigkeit auf den angegebenen Wert fest.\",\n \"music.setTempo|param|bpm\": \"Die neue Geschwindigkeit in Schlägen pro Minute, z.B.: 120\",\n \"music.tempo\": \"Gibt die Geschwindigkeit in Schlägen pro Minute aus. Die Geschwindigkeit ist Schnelligkeit (Bpm = Beats pro Minute), in der Töne abgespielt werden. Je größer der Wert, desto schneller werden die Töne abgespielt.\",\n \"pins\": \"Steuere die Stromstärke über die Pins für analoge/digitale Signale, Servos, I2C,...\",\n \"pins.analogPitch\": \"Gibt ein Pulsweiten Modulation (PWM)-Signal über den aktuellen Pitch-Pin. Benutze `analog set pitch pin`, um den Pitch-Pin festzulegen.\",\n \"pins.analogReadPin\": \"Lese den Anschlusswert als Analog aus, d. h. als einen Wert zwischen 0 und 1023.\",\n \"pins.analogSetPeriod\": \"Stellt die Pulsweite Modulation (PWM) des Analogausganges auf den angegebenen Wert in ** Mikrosekunden ** oder `1/1000` Millisekunden ein.\\nWenn dieser Pin nicht als einen Analogausgang (mit `analog write pin`) konfiguriert ist, hat der Vorgang keine Auswirkungen.\",\n \"pins.analogSetPeriod|param|micros\": \"Zeit in Mikrosekunden. z.B.: 20000\",\n \"pins.analogWritePin\": \"Legt den Wert des Verbinders auf analog fest. Der Wert muss zwischen 0 und 1023 liegen.\",\n \"pins.analogWritePin|param|value\": \"Wert, der auf den Pin geschrieben werden soll, zwischen ``0`` und ``1023`` z.B.: 1023,0\",\n \"pins.createBuffer\": \"Erstellt einen Null-initialisierten Zwischenspeicher.\",\n \"pins.createBuffer|param|size\": \"Anzahl der Bytes im Zwischenspeicher\",\n \"pins.digitalReadPin\": \"Lese den angegebene Pin oder Verbinder als 0 oder 1\",\n \"pins.digitalWritePin\": \"Setzt einen Pin- oder Verbinder-Wert auf 0 oder 1.\",\n \"pins.digitalWritePin|param|value\": \"Wert, der auf dem Pin 1 gesetzt werden soll, z.B. 0\",\n \"pins.i2cReadBuffer\": \"Lese `Größe`bytes aus einer 7-bit I2C-Adresse.\",\n \"pins.i2cReadNumber\": \"Lese eine Nummer aus einer 7-bit I2C-Adresse.\",\n \"pins.i2cWriteBuffer\": \"Schreibt Bytes in eine 7-bit I2C-Adresse.\",\n \"pins.i2cWriteNumber\": \"Schreibe eine Nummer in eine 7-bit I2C-Adresse.\",\n \"pins.map\": \"Definiert eine Nummer von einer Auswahl zu einer anderen um. Ein Wert ``von niedrig``wird so auf ``zu niedrig``umgeändert, ein Wert ``von hoch`` zu ``zu hoch`` etc.\",\n \"pins.map|param|fromHigh\": \"die obere Grenze des aktuellen Wertebereichs, z.B.: 1023\",\n \"pins.map|param|fromLow\": \"die untere Grenze des aktuellen Wertebereichs\",\n \"pins.map|param|toHigh\": \"die Obergrenze des Wertezielbereichs, z.B.: 4\",\n \"pins.map|param|toLow\": \"die Untergrenze des Wertezielbereichs\",\n \"pins.map|param|value\": \"Wert in Bereichen zuordnen\",\n \"pins.onPulsed\": \"Stellt diesen Pin als einen Digitaleingang ein und generiert Ereignisse, deren Zeitstempel die Dauer darstellt, in der der Pin entweder ``hoch``oder ``niedrig``war.\",\n \"pins.pulseDuration\": \"Ruft die Dauer des letzten Impulses in Mikrosendungen ab. Diese Funktion soll von einem `onPulsed`-Handler aufgerufen werden.\",\n \"pins.pulseIn\": \"Gibt die Dauer eines Pulses in Mikrosekunden an\",\n \"pins.pulseIn|param|name\": \"der Pin, der den Puls misst\",\n \"pins.pulseIn|param|value\": \"der Wert des Pulses (Standard hoch)\",\n \"pins.servoSetPulse\": \"Konfiguriert diesen IO-Pin als einen analogen/PWM-Ausgang, stellt den Zeitraum auf 20 ms ein und setzt die Pulsweite fest, basieren auf dem angegeben Wert **Mikrosekunden** oder `1/1000`Millisekunden.\",\n \"pins.servoSetPulse|param|micros\": \"Impulsdauer in Mikrosekunden, z.B.: 1500\",\n \"pins.servoSetPulse|param|name\": \"PIN-Name\",\n \"pins.servoWritePin\": \"Schreibt einen Wert in den Servo, der die Welle entsprechend kontroliert. Auf einem Standard-Servo wird so der Winkel der Welle (in Grad) eingestellt, sodass sich die Welle entsprechend anpasst. Auf einem kontinuierlich drehenden Servo wird dadurch die Geschwindigkeit des Servos festgelegt, wobei ``0``die volle Geschwindigkeit in eine Richtung darstellt, ``180``die volle Geschwindigkeit in die andere, und ein Wert von ``90`` einen Stillstand erzeugt.\",\n \"pins.servoWritePin|param|value\": \"Winkel oder Rotationsbeschleunigung, z.B.: 180,90,0\",\n \"pins.setPull\": \"Stellt die Anziehungskraft des Pins ein.\",\n \"pins.sizeOf\": \"Ruft die Bytegröße im spezifierten Nummernformat ab.\",\n \"pins.spiWrite\": \"Schreibe in den SPI-Slave und gebe die Antwort aus\",\n \"pins.spiWrite|param|value\": \"Daten, die an den SPI-Slave geschickt werden sollen\",\n \"serial\": \"Lesen und Schreiben von Daten über eine serielle Verbindung.\",\n \"serial.delimiters\": \"Gibt die mit dem Begrenzer korrespondierende Zeichenfolge aus.\",\n \"serial.onLineReceived\": \"Registriert ein Event, das ausgeführt wird, wenn eine Zeile empfangen wurde\",\n \"serial.readLine\": \"Liest eine Textzeile aus der seriellen Schnittstelle.\",\n \"serial.readUntil\": \"Liest aus eine Textzeile aus dem seriellen Anschluss und gibt den Puffer aus, wenn die Begrenzung erreicht wurde.\",\n \"serial.readUntil|param|delimiter\": \"Text-Begrenzung, die die Textblöcke voneinander trennt\",\n \"serial.redirect\": \"Konfiguriert dynamisch die serielle Instanz, damit sie andere Pins als USBTX und USBRX benutzt.\",\n \"serial.writeLine\": \"Gibt eine Zeile des Textes an die serielle\",\n \"serial.writeNumber\": \"Gibt einen numerischen Wert an die serielle\",\n \"serial.writeString\": \"Sendet ein Stück Text über serielle Verbindung.\",\n \"serial.writeValue\": \"Schreibt ein ``Namen: Wert`` Wertepaar auf die serielle Schnittstelle.\",\n \"serial.writeValue|param|name\": \"Name des Wertestreams, z.B.: x\",\n \"serial.writeValue|param|value\": \"Schreiben\"\n}",
"_locales/de/core-strings.json": "{\n \"AcceleratorRange.EightG\": \"Der Bewegungssensor misst Kräfte bis 8g\",\n \"AcceleratorRange.EightG|block\": \"8g\",\n \"AcceleratorRange.FourG\": \"Der Bewegungssensor misst Kräfte bis 4g\",\n \"AcceleratorRange.FourG|block\": \"4g\",\n \"AcceleratorRange.OneG\": \"Der Bewegungssensor misst Kräfte bis 1g\",\n \"AcceleratorRange.OneG|block\": \"1g\",\n \"AcceleratorRange.TwoG\": \"Der Bewegungssensor misst Kräfte bis 2g\",\n \"AcceleratorRange.TwoG|block\": \"2g\",\n \"BaudRate.BaudRate115200|block\": \"115200\",\n \"BaudRate.BaudRate9600|block\": \"9600\",\n \"BeatFraction.Eighth|block\": \"1/8\",\n \"BeatFraction.Half|block\": \"1/2\",\n \"BeatFraction.Quarter|block\": \"1/4\",\n \"BeatFraction.Sixteenth|block\": \"1/16\",\n \"BeatFraction.Whole|block\": \"1\",\n \"Button.AB|block\": \"A+B\",\n \"Colors.Blue|block\": \"Blau\",\n \"Colors.Green|block\": \"Grün\",\n \"Colors.Indigo|block\": \"Indigo\",\n \"Colors.Orange|block\": \"Orange\",\n \"Colors.Purple|block\": \"Violett\",\n \"Colors.Red|block\": \"Rot\",\n \"Colors.Violet|block\": \"Veilchenblau\",\n \"Colors.White|block\": \"Weiß\",\n \"Colors.Yellow|block\": \"Gelb\",\n \"Delimiters.Dollar|block\": \"$\",\n \"Delimiters.Hash|block\": \"#\",\n \"Delimiters.NewLine|block\": \"Neue Zeile\",\n \"Dimension.Strength|block\": \"Stärke\",\n \"Dimension.X|block\": \"x\",\n \"Dimension.Y|block\": \"y\",\n \"Dimension.Z|block\": \"z\",\n \"Direction.Left|block\": \"links\",\n \"Direction.Right|block\": \"rechts\",\n \"DisplayMode.BackAndWhite|block\": \"Schwarz-Weiß\",\n \"DisplayMode.Greyscale|block\": \"Graustufen\",\n \"EventCreationMode.CreateAndFire\": \"Calliope mini-Event wurde initialisiert, seine Event-Handler werden unverzüglich ausgeführt (nicht geeignet für die Nutzung bei Unterbrechungen!).\",\n \"EventCreationMode.CreateOnly\": \"Calliope mini-Event wurde initialisiert, es wird keine weitere Verarbeitung vorgenommen.\",\n \"Gesture.FreeFall\": \"Wird ausgeführt, wenn das Board fällt!\",\n \"Gesture.FreeFall|block\": \"freier Fall\",\n \"Gesture.LogoDown\": \"Wird ausgeführt, wenn das Logo nach unten zeigt und das Display vertikal ist.\",\n \"Gesture.LogoDown|block\": \"Logo nach unten\",\n \"Gesture.LogoUp\": \"Wird ausgeführt, wenn das Logo nach oben zeigt und das Display vertikal ist.\",\n \"Gesture.LogoUp|block\": \"Logo oben\",\n \"Gesture.ScreenDown\": \"Wird ausgeführt, wenn das Display nach oben zeigt und das Board horizontal ist.\",\n \"Gesture.ScreenDown|block\": \"Display nach unten\",\n \"Gesture.ScreenUp\": \"Wird ausgeführt, wenn das Display nach unten zeigt und das Board horizontal ist.\",\n \"Gesture.ScreenUp|block\": \"Display nach oben\",\n \"Gesture.Shake\": \"Wird erhöht, wenn geschüttelt\",\n \"Gesture.Shake|block\": \"geschüttelt\",\n \"Gesture.SixG\": \"Wird ausgeführt, ein 6g starker Stoß erkannt wird\",\n \"Gesture.SixG|block\": \"6g\",\n \"Gesture.ThreeG\": \"Wird ausgeführt, ein 3g starker Stoß erkannt wird\",\n \"Gesture.ThreeG|block\": \"3g\",\n \"Gesture.TiltLeft\": \"Wird ausgeführt, wenn das Display nach links zeigt\",\n \"Gesture.TiltLeft|block\": \"nach links neigen\",\n \"Gesture.TiltRight\": \"Wird ausgeführt, wenn das Display nach rechts zeigt\",\n \"Gesture.TiltRight|block\": \"nach rechts neigen\",\n \"LedSpriteProperty.Blink|block\": \"blinken\",\n \"LedSpriteProperty.Brightness|block\": \"Helligkeit\",\n \"LedSpriteProperty.Direction|block\": \"Richtung\",\n \"LedSpriteProperty.X|block\": \"x\",\n \"LedSpriteProperty.Y|block\": \"y\",\n \"Math.randomBoolean|block\": \"wähle zufälligen Wahr- oder Falsch-Wert\",\n \"Math|block\": \"Mathematik\",\n \"Motor.AB|block\": \"A und B\",\n \"MotorCommand.Break|block\": \"Pause\",\n \"MotorCommand.Coast|block\": \"auslaufen\",\n \"MotorCommand.Sleep|block\": \"schlafen\",\n \"Note.CSharp3|block\": \"C#3\",\n \"Note.CSharp4|block\": \"C#4\",\n \"Note.CSharp5|block\": \"C#5\",\n \"Note.CSharp|block\": \"C#\",\n \"Note.FSharp3|block\": \"F#3\",\n \"Note.FSharp4|block\": \"F#4\",\n \"Note.FSharp5|block\": \"F#5\",\n \"Note.FSharp|block\": \"F#\",\n \"Note.GSharp3|block\": \"G#3\",\n \"Note.GSharp4|block\": \"G#4\",\n \"Note.GSharp5|block\": \"G#5\",\n \"Note.GSharp|block\": \"G#\",\n \"PinPullMode.PullDown|block\": \"nach unten\",\n \"PinPullMode.PullUp|block\": \"nach oben\",\n \"Rotation.Pitch|block\": \"Winkel\",\n \"Rotation.Roll|block\": \"rollen\",\n \"String.charAt|block\": \"Zeichen an Position %pos aus|%this\",\n \"String.compare|block\": \"vergleiche %this| mit %that\",\n \"String.concat|block\": \"hänge %this| mit %other aneinander\",\n \"String.fromCharCode|block\": \"Text aus ASCII-Code %code\",\n \"String.isEmpty|block\": \"%this| ist leer\",\n \"String.length|block\": \"Länge von %VALUE\",\n \"String.substr|block\": \"extrahiere aus %this|beginnend mit %start|%length Zeichen\",\n \"String|block\": \"Zeichenfolge\",\n \"basic.clearScreen|block\": \"Bildschirminhalt löschen\",\n \"basic.color|block\": \"%c\",\n \"basic.forever|block\": \"dauerhaft\",\n \"basic.pause|block\": \"pausiere (ms) %pause\",\n \"basic.rgbw|block\": \"Rot %red|Grün %green|Blau %blue|Weiß %white\",\n \"basic.setLedColor|block\": \"setze LED-Farbe auf %color=color_id\",\n \"basic.showLeds|block\": \"zeige LEDs\",\n \"basic.showNumber|block\": \"zeige|Nummer %number\",\n \"basic.showString|block\": \"zeige|Zeichenfolge %text\",\n \"basic|block\": \"Grundlagen\",\n \"control.deviceName|block\": \"Gerätename\",\n \"control.deviceSerialNumber|block\": \"Seriennnummer\",\n \"control.eventSourceId|block\": \"%id\",\n \"control.eventTimestamp|block\": \"Ereigniszeitstempel\",\n \"control.eventValueId|block\": \"%id\",\n \"control.eventValue|block\": \"Ereigniswert\",\n \"control.inBackground|block\": \"im Hintergrund ausführen\",\n \"control.onEvent|block\": \"wenn Ereignis|von Quelle %src=control_event_source_id|mit Wert %value=control_event_value_id\",\n \"control.raiseEvent|block\": \"Ereignis auslösen|von Quelle %src=control_event_source_id|mit Wert %value=control_event_value_id\",\n \"control.reset|block\": \"zurücksetzen\",\n \"control.waitMicros|block\": \"Warte (µs)%micros\",\n \"control|block\": \"Steuerung\",\n \"game.addScore|block\": \"Ändere Spielstand um|%points\",\n \"game.createSprite|block\": \"erzeuge Sprite an Position|x: %x|y:%y\",\n \"game.gameOver|block\": \"Spiel beendet\",\n \"game.score|block\": \"Spielstand\",\n \"game.startCountdown|block\": \"Countdown| starten (ms) %duration\",\n \"game|block\": \"Spiel\",\n \"images.createBigImage|block\": \"erstelle großes Bild\",\n \"images.createImage|block\": \"erstelle Bild\",\n \"images|block\": \"Bilder\",\n \"input.acceleration|block\": \"Beschleunigung (mg) |%NAME\",\n \"input.buttonIsPressed|block\": \"Button|%NAME|ist gedrückt\",\n \"input.compassHeading|block\": \"Kompassausrichtung (°)\",\n \"input.lightLevel|block\": \"Lichtstärke\",\n \"input.magneticForce|block\": \"Magnetkraft (µT) |%NAME\",\n \"input.onButtonPressed|block\": \"wenn Knopf|%NAME|gedrückt\",\n \"input.onGesture|block\": \"wenn |%NAME\",\n \"input.onPinPressed|block\": \"wenn Pin %NAME|gedrückt\",\n \"input.onPinReleased|block\": \"wenn Pin %NAME|losgelassen\",\n \"input.pinIsPressed|block\": \"Pin %NAME|ist gedrückt\",\n \"input.rotation|block\": \"Rotation (°)|%NAME\",\n \"input.runningTime|block\": \"Laufzeit (ms)\",\n \"input.setAccelerometerRange|block\": \"setze Bewegungsmesser auf|%range\",\n \"input.temperature|block\": \"Temperatur (°C)\",\n \"input|block\": \"Eingabe\",\n \"led.brightness|block\": \"Helligkeit\",\n \"led.plotBarGraph|block\": \"zeichne Balkendiagramm von %value|bis %high\",\n \"led.plot|block\": \"Zeichne|x %x|y %y\",\n \"led.point|block\": \"Punkt|x %x|y %y\",\n \"led.setBrightness|block\": \"setze Helligkeit auf %value\",\n \"led.stopAnimation|block\": \"halte Animation an\",\n \"led.toggle|block\": \"Schalte zwischen|x %x|y %y\",\n \"led.unplot|block\": \"schalte Pixel|x %x|y %y aus\",\n \"led|block\": \"LED\",\n \"motors.dualMotorPower|block\": \"Motor %motor an|mit %percent\",\n \"motors.motorCommand|block\": \"Motor %command\",\n \"motors.motorPower|block\": \"Motor an mit %percent\",\n \"motors|block\": \"Motoren\",\n \"music.beat|block\": \"%fraction|Takt\",\n \"music.changeTempoBy|block\": \"ändere die Geschwindigkeit (bpm)|%value\",\n \"music.noteFrequency|block\": \"%note\",\n \"music.playTone|block\": \"spiele|Note %note=device_note|für %duration=device_beat\",\n \"music.rest|block\": \"pausiere (ms)|%duration=device_beat\",\n \"music.ringTone|block\": \"Klingelton (Hz) |%note = Device_note\",\n \"music.setTempo|block\": \"ändere Geschwindigkeit auf (bpm)|%value\",\n \"music.tempo|block\": \"Geschwindkeit (bpm)\",\n \"music|block\": \"Musik\",\n \"pins.analogReadPin|block\": \"lese analoge Werte von|Pin %name\",\n \"pins.analogSetPeriod|block\": \"setze Zeitraum für analogen|Pin %pin|auf (µs)%micros\",\n \"pins.analogWritePin|block\": \"schreibe analogen|Pin %name|auf %value\",\n \"pins.digitalReadPin|block\": \"lese digitale Werte von|Pin %name\",\n \"pins.digitalWritePin|block\": \"schreibe digitalen Wert von|pin %name|auf %value\",\n \"pins.i2cReadNumber|block\": \"lese Nummer aus I2C|auf Adresse %address|im Format %format=i2c_sizeof\",\n \"pins.i2cWriteNumber|block\": \"schreibe Nummer aus I2C|auf Adresse %address|mit Wert %value|im Format %format=i2c_sizeof\",\n \"pins.map|block\": \"verteile %value|von niedrig %fromLow|von hoch %fromHigh| bis niedrig %toLow|bis hoch %toHigh\",\n \"pins.onPulsed|block\": \"wenn|Pin %pin|gepulst %pulse\",\n \"pins.pulseDuration|block\": \"Impulsdauer (µs)\",\n \"pins.pulseIn|block\": \"Impuls in (µs)|Pin %name|mit %value\",\n \"pins.servoSetPulse|block\": \"setze den Puls von Servo an|Pin %value|auf (µs) %micros\",\n \"pins.servoWritePin|block\": \"schreibe Servo an|Pin %name|auf %value\",\n \"pins.setPull|block\": \"setze Anziehungskraft von|Pin %pin|auf %pull\",\n \"pins.spiWrite|block\": \"schreibe %value in SPI\",\n \"pins|block\": \"Pins\",\n \"serial.delimiters|block\": \"%del\",\n \"serial.readLine|block\": \"serial|read line\",\n \"serial.readUntil|block\": \"serial|read until %delimiter=serial_delimiter_conv\",\n \"serial.redirect|block\": \"serial|redirect to|TX %tx|RX %rx|at baud rate %rate\",\n \"serial.writeLine|block\": \"serial|write line %text\",\n \"serial.writeNumber|block\": \"serial|write number %value\",\n \"serial.writeString|block\": \"serial|write string %text\",\n \"serial.writeValue|block\": \"serial|write value %name|= %value\",\n \"serial|block\": \"Konsole\",\n \"{id:category}Basic\": \"Grundlagen\",\n \"{id:category}Control\": \"Steuerung\",\n \"{id:category}Game\": \"Spiel\",\n \"{id:category}Images\": \"Bilder\",\n \"{id:category}Input\": \"Eingabe\",\n \"{id:category}Led\": \"LED\",\n \"{id:category}Math\": \"Mathematik\",\n \"{id:category}Motors\": \"Motoren\",\n \"{id:category}Music\": \"Musik\",\n \"{id:category}Pins\": \"Pins\",\n \"{id:category}Serial\": \"Konsole\",\n \"{id:category}String\": \"Zeichenfolge\",\n \"{id:category}Text\": \"Text\"\n}",
"basic.cpp": "#include \"pxt.h\"\n\n\n/**\n * Provides access to basic micro:bit functionality.\n */\n//% color=#54C9C9 weight=100 icon=\"\\uf00a\"\nnamespace basic {\n /**\n * Sets the color on the build-in LED. Set to 0 to turn off.\n */\n //% blockId=device_set_led_color block=\"set led to %color=color_id\"\n //% weight=50\n void setLedColor(int color) {\n if (!color) {\n uBit.rgb.off();\n return;\n }\n\n int w = (color >> 24) & 0xFF;\n int r = (color >> 16) & 0xFF;\n int g = (color >> 8) & 0xFF;\n int b = (color) & 0xFF;\n \n uBit.rgb.setColour(r,g,b,w);\n }\n\n /**\n * Scroll a number on the screen. If the number fits on the screen (i.e. is a single digit), do not scroll.\n * @param interval speed of scroll; eg: 150, 100, 200, -100\n */\n //% help=basic/show-number\n //% weight=96\n //% blockId=device_show_number block=\"show|number %number\" blockGap=8\n //% async\n //% parts=\"ledmatrix\"\n void showNumber(int value, int interval = 150) { \n if (interval < 0)\n return;\n\n ManagedString t(value);\n if (value < 0 || value >= 10) {\n uBit.display.scroll(t, interval);\n } else {\n uBit.display.printChar(t.charAt(0), interval * 5);\n }\n }\n\n /**\n * Draws an image on the LED screen.\n * @param leds the pattern of LED to turn on/off\n * @param interval time in milliseconds to pause after drawing\n */\n //% help=basic/show-leds \n //% weight=95 blockGap=8\n //% imageLiteral=1 async\n //% blockId=device_show_leds\n //% block=\"show leds\"\n //% parts=\"ledmatrix\"\n void showLeds(ImageLiteral leds, int interval = 400) {\n uBit.display.print(MicroBitImage(imageBytes(leds)), 0, 0, 0, interval);\n }\n\n /**\n * Display text on the display, one character at a time. If the string fits on the screen (i.e. is one letter), does not scroll.\n * @param text the text to scroll on the screen, eg: \"Hello!\"\n * @param interval how fast to shift characters; eg: 150, 100, 200, -100\n */\n //% help=basic/show-string \n //% weight=87 blockGap=8\n //% block=\"show|string %text\" \n //% async\n //% blockId=device_print_message\n //% parts=\"ledmatrix\"\n void showString(StringData *text, int interval = 150) {\n if (interval < 0)\n return;\n ManagedString s(text);\n int l = s.length();\n if (l == 0) {\n uBit.display.clear();\n fiber_sleep(interval * 5);\n } else if (l > 1) {\n uBit.display.scroll(s, interval);\n } else {\n uBit.display.print(s.charAt(0), interval * 5);\n }\n }\n\n /**\n * Turn off all LEDs\n */\n //% help=basic/clear-screen weight=79\n //% blockId=device_clear_display block=\"clear screen\"\n //% parts=\"ledmatrix\"\n void clearScreen() {\n uBit.display.image.clear();\n }\n\n /**\n * Shows a sequence of LED screens as an animation.\n * @param leds pattern of LEDs to turn on/off\n * @param interval time in milliseconds between each redraw\n */\n //% help=basic/show-animation imageLiteral=1 async\n //% parts=\"ledmatrix\"\n void showAnimation(ImageLiteral leds, int interval = 400) {\n uBit.display.animate(MicroBitImage(imageBytes(leds)), interval, 5, 0);\n }\n\n /**\n * Draws an image on the LED screen.\n * @param leds pattern of LEDs to turn on/off\n */\n //% help=basic/plot-leds weight=80\n //% parts=\"ledmatrix\"\n void plotLeds(ImageLiteral leds) {\n MicroBitImage i(imageBytes(leds));\n uBit.display.print(i, 0, 0, 0, 0);\n }\n\n void forever_stub(void *a) {\n while (true) {\n runAction0((Action)a);\n fiber_sleep(20);\n }\n }\n\n /**\n * Repeats the code forever in the background. On each iteration, allows other codes to run.\n * @param body code to execute\n */\n //% help=basic/forever weight=55 blockGap=8\n //% blockId=device_forever block=\"forever\"\n void forever(Action a) {\n if (a != 0) {\n incr(a);\n create_fiber(forever_stub, (void*)a);\n }\n }\n\n /**\n * Pause for the specified time in milliseconds\n * @param ms how long to pause for, eg: 100, 200, 500, 1000, 2000\n */\n //% help=basic/pause weight=54\n //% async block=\"pause (ms) %pause\"\n //% blockId=device_pause\n void pause(int ms) {\n fiber_sleep(ms);\n }\n}\n",
"basic.ts": "/**\n Well known colors\n*/\nenum Colors {\n //% blockIdentity=basic.color\n //% block=red\n Red = 0x00FF0000,\n //% blockIdentity=basic.color\n //% block=orange\n Orange = 0x00FFA500,\n //% blockIdentity=basic.color\n //% block=yellow\n Yellow = 0x00FFFF00,\n //% blockIdentity=basic.color\n //% block=green\n Green = 0x0000FF00,\n //% blockIdentity=basic.color\n //% block=blue\n Blue = 0x000000FF,\n //% blockIdentity=basic.color\n //% block=indigo\n Indigo = 0x004b0082,\n //% blockIdentity=basic.color\n //% block=violet\n Violet = 0x008a2be2,\n //% blockIdentity=basic.color\n //% block=purple\n Purple = 0x00FF00FF,\n //% blockIdentity=basic.color\n //% block=white\n White = 0xFF00000\n}\n\n/**\n * Provides access to basic micro:bit functionality.\n */\n//% color=#54C9C9 weight=100\nnamespace basic {\n /**\n * Converts the color name to a number\n */\n //% blockId=color_id block=\"%c\" shim=TD_ID\n export function color(c: Colors): number {\n return c;\n }\n\n /**\n * Converts red, green, blue channels into a RGB color\n * @param red value of the red channel between 0 and 255. eg: 255\n * @param green value of the green channel between 0 and 255. eg: 255\n * @param blue value of the blue channel between 0 and 255. eg: 255\n * @param white value of the white channel between 0 and 255. eg: 0\n */\n //% weight=1\n //% blockId=\"core_rgb\" block=\"red %red|green %green|blue %blue|white %white\"\n export function rgbw(red: number, green: number, blue: number, white:number): number {\n return ((white & 0xFF) << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);\n }\n}",
"buffer.cpp": "#include \"pxt.h\"\n\n// keep in sync with github/pxt/pxtsim/libgeneric.ts\nenum class NumberFormat {\n Int8LE = 1,\n UInt8LE,\n Int16LE,\n UInt16LE,\n Int32LE,\n Int8BE,\n UInt8BE,\n Int16BE,\n UInt16BE,\n Int32BE,\n // UInt32,\n};\n\n//% indexerGet=BufferMethods::getByte indexerSet=BufferMethods::setByte\nnamespace BufferMethods {\n //%\n int getByte(Buffer buf, int off) {\n return max(ManagedBuffer(buf).getByte(off), 0);\n }\n\n //%\n void setByte(Buffer buf, int off, int v) {\n ManagedBuffer(buf).setByte(off, v);\n }\n\n //%\n uint8_t *getBytes(Buffer buf) {\n return buf->payload;\n }\n\n /**\n * Write a number in specified format in the buffer.\n */\n //%\n void setNumber(Buffer buf, NumberFormat format, int offset, int value)\n {\n int8_t i8;\n uint8_t u8;\n int16_t i16;\n uint16_t u16;\n int32_t i32;\n\n ManagedBuffer b(buf);\n\n // Assume little endian\n #define WRITEBYTES(isz, swap) isz = value; b.writeBytes(offset, (uint8_t*)&isz, sizeof(isz), swap); break\n\n switch (format) {\n case NumberFormat::Int8LE: WRITEBYTES(i8, false);\n case NumberFormat::UInt8LE: WRITEBYTES(u8, false);\n case NumberFormat::Int16LE: WRITEBYTES(i16, false);\n case NumberFormat::UInt16LE: WRITEBYTES(u16, false);\n case NumberFormat::Int32LE: WRITEBYTES(i32, false);\n case NumberFormat::Int8BE: WRITEBYTES(i8, true);\n case NumberFormat::UInt8BE: WRITEBYTES(u8, true);\n case NumberFormat::Int16BE: WRITEBYTES(i16, true);\n case NumberFormat::UInt16BE: WRITEBYTES(u16, true);\n case NumberFormat::Int32BE: WRITEBYTES(i32, true);\n }\n }\n\n /**\n * Read a number in specified format from the buffer.\n */\n //%\n int getNumber(Buffer buf, NumberFormat format, int offset)\n {\n int8_t i8;\n uint8_t u8;\n int16_t i16;\n uint16_t u16;\n int32_t i32;\n\n ManagedBuffer b(buf);\n\n // Assume little endian\n #define READBYTES(isz, swap) b.readBytes((uint8_t*)&isz, offset, sizeof(isz), swap); return isz\n\n switch (format) {\n case NumberFormat::Int8LE: READBYTES(i8, false);\n case NumberFormat::UInt8LE: READBYTES(u8, false);\n case NumberFormat::Int16LE: READBYTES(i16, false);\n case NumberFormat::UInt16LE: READBYTES(u16, false);\n case NumberFormat::Int32LE: READBYTES(i32, false);\n case NumberFormat::Int8BE: READBYTES(i8, true);\n case NumberFormat::UInt8BE: READBYTES(u8, true);\n case NumberFormat::Int16BE: READBYTES(i16, true);\n case NumberFormat::UInt16BE: READBYTES(u16, true);\n case NumberFormat::Int32BE: READBYTES(i32, true);\n }\n\n return 0;\n }\n\n /** Returns the length of a Buffer object. */\n //% property\n int length(Buffer s) {\n return s->length;\n }\n\n /**\n * Fill (a fragment) of the buffer with given value.\n */\n //%\n void fill(Buffer buf, int value, int offset = 0, int length = -1)\n {\n ManagedBuffer(buf).fill(value, offset, length);\n }\n\n /**\n * Return a copy of a fragment of a buffer.\n */\n //%\n Buffer slice(Buffer buf, int offset = 0, int length = -1)\n {\n return ManagedBuffer(buf).slice(offset, length).leakData();\n }\n\n /**\n * Shift buffer left in place, with zero padding.\n * @param offset number of bytes to shift; use negative value to shift right\n * @param start start offset in buffer. Default is 0.\n * @param length number of elements in buffer. If negative, length is set as the buffer length minus start. eg: -1\n */\n //%\n void shift(Buffer buf, int offset, int start = 0, int length = -1)\n {\n ManagedBuffer(buf).shift(offset, start, length);\n }\n\n /**\n * Rotate buffer left in place.\n * @param offset number of bytes to shift; use negative value to shift right\n * @param start start offset in buffer. Default is 0.\n * @param length number of elements in buffer. If negative, length is set as the buffer length minus start. eg: -1\n */\n //%\n void rotate(Buffer buf, int offset, int start = 0, int length = -1)\n {\n ManagedBuffer(buf).rotate(offset, start, length);\n }\n\n // int readBytes(uint8_t *dst, int offset, int length, bool swapBytes = false) const;\n // int writeBytes(int dstOffset, uint8_t *src, int length, bool swapBytes = false);\n\n /**\n * Write contents of `src` at `dstOffset` in current buffer.\n */\n //%\n void write(Buffer buf, int dstOffset, Buffer src)\n {\n //Not supported, we only do up to 4 args :/\n //void write(Buffer buf, int dstOffset, Buffer src, int srcOffset = 0, int length = -1)\n ManagedBuffer(buf).writeBuffer(dstOffset, ManagedBuffer(src), 0, -1);\n }\n}\n",
"control.cpp": "#include \"pxt.h\"\n\n/**\n * How to create the event.\n */\nenum class EventCreationMode {\n /**\n * MicroBitEvent is initialised, and no further processing takes place.\n */\n CreateOnly = CREATE_ONLY,\n /**\n * MicroBitEvent is initialised, and its event handlers are immediately fired (not suitable for use in interrupts!).\n */\n CreateAndFire = CREATE_AND_FIRE,\n};\n\n// note the trailing '_' in names - otherwise we get conflict with the pre-processor\n// this trailing underscore is removed by enums.d.ts generation process\n\n// TODO shouldn't these be renamed to something more sensible anyways?\n\nenum EventBusSource {\n MICROBIT_ID_BUTTON_A_ = MICROBIT_ID_BUTTON_A,\n MICROBIT_ID_BUTTON_B_ = MICROBIT_ID_BUTTON_B,\n MICROBIT_ID_BUTTON_AB_ = MICROBIT_ID_BUTTON_AB,\n MICROBIT_ID_RADIO_ = MICROBIT_ID_RADIO,\n MICROBIT_ID_GESTURE_ = MICROBIT_ID_GESTURE,\n MICROBIT_ID_ACCELEROMETER_ = MICROBIT_ID_ACCELEROMETER,\n MICROBIT_ID_IO_P0_ = MICROBIT_ID_IO_P0,\n MICROBIT_ID_IO_P1_ = MICROBIT_ID_IO_P1,\n MICROBIT_ID_IO_P2_ = MICROBIT_ID_IO_P2,\n MICROBIT_ID_IO_P3_ = MICROBIT_ID_IO_P3,\n MICROBIT_ID_IO_P4_ = MICROBIT_ID_IO_P4,\n MICROBIT_ID_IO_P5_ = MICROBIT_ID_IO_P5,\n MICROBIT_ID_IO_P6_ = MICROBIT_ID_IO_P6,\n MICROBIT_ID_IO_P7_ = MICROBIT_ID_IO_P7,\n MICROBIT_ID_IO_P8_ = MICROBIT_ID_IO_P8,\n MICROBIT_ID_IO_P9_ = MICROBIT_ID_IO_P9,\n MICROBIT_ID_IO_P10_ = MICROBIT_ID_IO_P10,\n MICROBIT_ID_IO_P11_ = MICROBIT_ID_IO_P11,\n MICROBIT_ID_IO_P12_ = MICROBIT_ID_IO_P12,\n MICROBIT_ID_IO_P13_ = MICROBIT_ID_IO_P13,\n MICROBIT_ID_IO_P14_ = MICROBIT_ID_IO_P14,\n MICROBIT_ID_IO_P15_ = MICROBIT_ID_IO_P15,\n MICROBIT_ID_IO_P16_ = MICROBIT_ID_IO_P16,\n MICROBIT_ID_IO_P19_ = MICROBIT_ID_IO_P19,\n MICROBIT_ID_IO_P20_ = MICROBIT_ID_IO_P20,\n MICROBIT_ID_IO_P21_ = MICROBIT_ID_IO_P21,\n MES_DEVICE_INFO_ID_ = MES_DEVICE_INFO_ID,\n MES_SIGNAL_STRENGTH_ID_ = MES_SIGNAL_STRENGTH_ID,\n MES_DPAD_CONTROLLER_ID_ = MES_DPAD_CONTROLLER_ID,\n MES_BROADCAST_GENERAL_ID_ = MES_BROADCAST_GENERAL_ID,\n};\n\nenum EventBusValue {\n MICROBIT_EVT_ANY_ = MICROBIT_EVT_ANY,\n MICROBIT_BUTTON_EVT_CLICK_ = MICROBIT_BUTTON_EVT_CLICK,\n MICROBIT_RADIO_EVT_DATAGRAM_ = MICROBIT_RADIO_EVT_DATAGRAM,\n MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE_ = MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE,\n MICROBIT_PIN_EVT_RISE_ = MICROBIT_PIN_EVT_RISE,\n MICROBIT_PIN_EVT_FALL_ = MICROBIT_PIN_EVT_FALL,\n MICROBIT_PIN_EVT_PULSE_HI_ = MICROBIT_PIN_EVT_PULSE_HI,\n MICROBIT_PIN_EVT_PULSE_LO_ = MICROBIT_PIN_EVT_PULSE_LO,\n MES_ALERT_EVT_ALARM1_ = MES_ALERT_EVT_ALARM1,\n MES_ALERT_EVT_ALARM2_ = MES_ALERT_EVT_ALARM2,\n MES_ALERT_EVT_ALARM3_ = MES_ALERT_EVT_ALARM3,\n MES_ALERT_EVT_ALARM4_ = MES_ALERT_EVT_ALARM4,\n MES_ALERT_EVT_ALARM5_ = MES_ALERT_EVT_ALARM5,\n MES_ALERT_EVT_ALARM6_ = MES_ALERT_EVT_ALARM6,\n MES_ALERT_EVT_DISPLAY_TOAST_ = MES_ALERT_EVT_DISPLAY_TOAST,\n MES_ALERT_EVT_FIND_MY_PHONE_ = MES_ALERT_EVT_FIND_MY_PHONE,\n MES_ALERT_EVT_PLAY_RINGTONE_ = MES_ALERT_EVT_PLAY_RINGTONE,\n MES_ALERT_EVT_PLAY_SOUND_ = MES_ALERT_EVT_PLAY_SOUND,\n MES_ALERT_EVT_VIBRATE_ = MES_ALERT_EVT_VIBRATE,\n MES_CAMERA_EVT_LAUNCH_PHOTO_MODE_ = MES_CAMERA_EVT_LAUNCH_PHOTO_MODE,\n MES_CAMERA_EVT_LAUNCH_VIDEO_MODE_ = MES_CAMERA_EVT_LAUNCH_VIDEO_MODE,\n MES_CAMERA_EVT_START_VIDEO_CAPTURE_ = MES_CAMERA_EVT_START_VIDEO_CAPTURE,\n MES_CAMERA_EVT_STOP_PHOTO_MODE_ = MES_CAMERA_EVT_STOP_PHOTO_MODE,\n MES_CAMERA_EVT_STOP_VIDEO_CAPTURE_ = MES_CAMERA_EVT_STOP_VIDEO_CAPTURE,\n MES_CAMERA_EVT_STOP_VIDEO_MODE_ = MES_CAMERA_EVT_STOP_VIDEO_MODE,\n MES_CAMERA_EVT_TAKE_PHOTO_ = MES_CAMERA_EVT_TAKE_PHOTO,\n MES_CAMERA_EVT_TOGGLE_FRONT_REAR_ = MES_CAMERA_EVT_TOGGLE_FRONT_REAR,\n MES_DEVICE_DISPLAY_OFF_ = MES_DEVICE_DISPLAY_OFF,\n MES_DEVICE_DISPLAY_ON_ = MES_DEVICE_DISPLAY_ON,\n MES_DEVICE_GESTURE_DEVICE_SHAKEN_ = MES_DEVICE_GESTURE_DEVICE_SHAKEN,\n MES_DEVICE_INCOMING_CALL_ = MES_DEVICE_INCOMING_CALL,\n MES_DEVICE_INCOMING_MESSAGE_ = MES_DEVICE_INCOMING_MESSAGE,\n MES_DEVICE_ORIENTATION_LANDSCAPE_ = MES_DEVICE_ORIENTATION_LANDSCAPE,\n MES_DEVICE_ORIENTATION_PORTRAIT_ = MES_DEVICE_ORIENTATION_PORTRAIT,\n MES_DPAD_BUTTON_1_DOWN_ = MES_DPAD_BUTTON_1_DOWN,\n MES_DPAD_BUTTON_1_UP_ = MES_DPAD_BUTTON_1_UP,\n MES_DPAD_BUTTON_2_DOWN_ = MES_DPAD_BUTTON_2_DOWN,\n MES_DPAD_BUTTON_2_UP_ = MES_DPAD_BUTTON_2_UP,\n MES_DPAD_BUTTON_3_DOWN_ = MES_DPAD_BUTTON_3_DOWN,\n MES_DPAD_BUTTON_3_UP_ = MES_DPAD_BUTTON_3_UP,\n MES_DPAD_BUTTON_4_DOWN_ = MES_DPAD_BUTTON_4_DOWN,\n MES_DPAD_BUTTON_4_UP_ = MES_DPAD_BUTTON_4_UP,\n MES_DPAD_BUTTON_A_DOWN_ = MES_DPAD_BUTTON_A_DOWN,\n MES_DPAD_BUTTON_A_UP_ = MES_DPAD_BUTTON_A_UP,\n MES_DPAD_BUTTON_B_DOWN_ = MES_DPAD_BUTTON_B_DOWN,\n MES_DPAD_BUTTON_B_UP_ = MES_DPAD_BUTTON_B_UP,\n MES_DPAD_BUTTON_C_DOWN_ = MES_DPAD_BUTTON_C_DOWN,\n MES_DPAD_BUTTON_C_UP_ = MES_DPAD_BUTTON_C_UP,\n MES_DPAD_BUTTON_D_DOWN_ = MES_DPAD_BUTTON_D_DOWN,\n MES_DPAD_BUTTON_D_UP_ = MES_DPAD_BUTTON_D_UP,\n MES_REMOTE_CONTROL_EVT_FORWARD_ = MES_REMOTE_CONTROL_EVT_FORWARD,\n MES_REMOTE_CONTROL_EVT_NEXTTRACK_ = MES_REMOTE_CONTROL_EVT_NEXTTRACK,\n MES_REMOTE_CONTROL_EVT_PAUSE_ = MES_REMOTE_CONTROL_EVT_PAUSE,\n MES_REMOTE_CONTROL_EVT_PLAY_ = MES_REMOTE_CONTROL_EVT_PLAY,\n MES_REMOTE_CONTROL_EVT_PREVTRACK_ = MES_REMOTE_CONTROL_EVT_PREVTRACK,\n MES_REMOTE_CONTROL_EVT_REWIND_ = MES_REMOTE_CONTROL_EVT_REWIND,\n MES_REMOTE_CONTROL_EVT_STOP_ = MES_REMOTE_CONTROL_EVT_STOP,\n MES_REMOTE_CONTROL_EVT_VOLUMEDOWN_ = MES_REMOTE_CONTROL_EVT_VOLUMEDOWN,\n MES_REMOTE_CONTROL_EVT_VOLUMEUP_ = MES_REMOTE_CONTROL_EVT_VOLUMEUP,\n};\n\n//% weight=1 color=\"#333333\"\n//% advanced=true\nnamespace control {\n void fiberDone(void *a)\n {\n decr((Action)a);\n release_fiber();\n }\n\n /**\n * Schedules code that run in the background.\n */\n //% help=control/in-background\n //% blockId=\"control_in_background\" block=\"run in background\" blockGap=8\n void inBackground(Action a) {\n runInBackground(a);\n }\n\n /**\n * Resets the BBC micro:bit.\n */\n //% weight=30 async help=control/reset blockGap=8\n //% blockId=\"control_reset\" block=\"reset\"\n void reset() {\n microbit_reset();\n }\n\n /**\n * Blocks the current fiber for the given microseconds\n * @param micros number of micro-seconds to wait. eg: 4\n */\n //% help=control/wait-micros weight=29\n //% blockId=\"control_wait_us\" block=\"wait (µs)%micros\"\n void waitMicros(int micros) {\n wait_us(micros);\n }\n\n /**\n * Raises an event in the event bus.\n * @param src ID of the MicroBit Component that generated the event e.g. MICROBIT_ID_BUTTON_A.\n * @param value Component specific code indicating the cause of the event.\n * @param mode optional definition of how the event should be processed after construction (default is CREATE_AND_FIRE).\n */\n //% weight=21 blockGap=12 blockId=\"control_raise_event\" block=\"raise event|from source %src=control_event_source_id|with value %value=control_event_value_id\" blockExternalInputs=1\n //% mode.defl=CREATE_AND_FIRE\n void raiseEvent(int src, int value, EventCreationMode mode) {\n MicroBitEvent evt(src, value, (MicroBitEventLaunchMode)mode);\n }\n\n /**\n * Raises an event in the event bus.\n */\n //% weight=20 blockGap=8 blockId=\"control_on_event\" block=\"on event|from %src=control_event_source_id|with value %value=control_event_value_id\"\n //% blockExternalInputs=1\n void onEvent(int src, int value, Action handler) {\n registerWithDal(src, value, handler);\n }\n\n /**\n * Gets the value of the last event executed on the bus\n */\n //% blockId=control_event_value\" block=\"event value\"\n //% weight=18\n int eventValue() {\n return pxt::lastEvent.value;\n }\n\n /**\n * Gets the timestamp of the last event executed on the bus\n */\n //% blockId=control_event_timestamp\" block=\"event timestamp\"\n //% weight=19 blockGap=8\n int eventTimestamp() {\n return pxt::lastEvent.timestamp;\n }\n\n /**\n * Gets a friendly name for the device derived from the its serial number\n */\n //% blockId=\"control_device_name\" block=\"device name\" weight=10 blockGap=8\n StringData* deviceName() {\n return ManagedString(microbit_friendly_name()).leakData();\n }\n\n /**\n * Derive a unique, consistent serial number of this device from internal data.\n */\n //% blockId=\"control_device_serial_number\" block=\"device serial number\" weight=9\n int deviceSerialNumber() {\n return microbit_serial_number();\n }\n}\n",
"control.ts": "/**\n* Runtime and event utilities.\n*/\n//% weight=1 color=\"#42495F\" icon=\"\\uf233\"\n//% advanced=true\nnamespace control {\n\n /**\n * Returns the value of a C++ runtime constant\n */\n //% weight=2 weight=19 blockId=\"control_event_source_id\" block=\"%id\" blockGap=8\n //% shim=TD_ID\n export function eventSourceId(id: EventBusSource): number {\n return id;\n }\n /**\n * Returns the value of a C++ runtime constant\n */\n //% weight=1 weight=19 blockId=\"control_event_value_id\" block=\"%id\"\n //% shim=TD_ID\n export function eventValueId(id: EventBusValue): number {\n return id;\n }\n\n /**\n * Display specified error code and stop the program.\n */\n //% shim=pxtrt::panic\n export function panic(code: number) { }\n\n /**\n * If the condition is false, display msg on serial console, and panic with code 098.\n */\n export function assert(condition: boolean, msg ?: string) {\n if (!condition) {\n console.log(\"ASSERTION FAILED\")\n if (msg != null) {\n console.log(msg)\n }\n panic(98)\n }\n }\n\n /**\n * Display warning in the simulator.\n */\n //% shim=pxtrt::runtimeWarning\n export function runtimeWarning(message: string) { }\n}\n",
"core.cpp": "#include \"pxt.h\"\n#include <limits.h>\n\n\nnamespace String_ {\n //%\n StringData *charAt(StringData *s, int pos) {\n return ManagedString((char)ManagedString(s).charAt(pos)).leakData();\n }\n\n //%\n int charCodeAt(StringData *s, int index) {\n return ManagedString(s).charAt(index);\n }\n\n //%\n StringData *concat(StringData *s, StringData *other) {\n ManagedString a(s), b(other);\n return (a + b).leakData();\n }\n\n //%\n int compare(StringData *s, StringData *that) {\n int compareResult = strcmp(s->data, that->data);\n if (compareResult < 0)\n return -1;\n else if (compareResult > 0)\n return 1;\n return 0;\n }\n\n //%\n int length(StringData *s) { return s->len; }\n\n //%\n StringData *fromCharCode(int code)\n {\n return ManagedString((char)code).leakData();\n }\n\n //%\n int toNumber(StringData *s) {\n return atoi(s->data);\n }\n\n //%\n StringData *mkEmpty()\n {\n return ManagedString::EmptyString.leakData();\n }\n\n //%\n StringData *substr(StringData *s, int start, int length)\n {\n if (length <= 0)\n return mkEmpty();\n if (start < 0)\n start = max(s->len + start, 0);\n length = min(length, s->len - start);\n ManagedString x(s);\n return x.substring(start, length).leakData();\n }\n}\n\n\nnamespace Boolean_ {\n // Cache the string literals \"true\" and \"false\" when used.\n // Note that the representation of booleans stays the usual C-one.\n \n static const char sTrue[] __attribute__ ((aligned (4))) = \"\\xff\\xff\\x04\\x00\" \"true\\0\";\n static const char sFalse[] __attribute__ ((aligned (4))) = \"\\xff\\xff\\x05\\x00\" \"false\\0\";\n\n //%\n StringData* toString(bool v)\n {\n if (v) {\n return (StringData*)(void*)sTrue;\n } else {\n return (StringData*)(void*)sFalse;\n } \n }\n\n //%\n bool bang(int v) { return v == 0; }\n}\n\nnamespace Number_ {\n //%\n StringData* toString(int n)\n {\n return ManagedString(n).leakData();\n }\n\n // +, - and friends are handled directly by assembly instructions\n // The comparisons are here as they are more code-size efficient\n \n //%\n bool lt(int x, int y) { return x < y; }\n //%\n bool le(int x, int y) { return x <= y; }\n //%\n bool neq(int x, int y) { return x != y; }\n //%\n bool eq(int x, int y) { return x == y; }\n //%\n bool gt(int x, int y) { return x > y; }\n //%\n bool ge(int x, int y) { return x >= y; }\n\n // These in fact call into C runtime on Cortex-M0 \n //%\n int div(int x, int y) { return x / y; }\n //%\n int mod(int x, int y) { return x % y; }\n}\n\nnamespace Math_ {\n //%\n int pow(int x, int y)\n {\n if (y < 0)\n return 0;\n int r = 1;\n while (y) {\n if (y & 1)\n r *= x;\n y >>= 1;\n x *= x;\n }\n return r;\n }\n \n //%\n int random(int max) {\n if (max == INT_MIN)\n return -microbit_random(INT_MAX);\n else if (max < 0)\n return -microbit_random(-max);\n else if (max == 0)\n return 0;\n else\n return microbit_random(max);\n }\n \n //%\n int sqrt(int x)\n {\n return ::sqrt(x);\n }\n}\n\nnamespace Array_ {\n //%\n RefCollection *mk(uint32_t flags)\n {\n return new RefCollection(flags);\n }\n //%\n int length(RefCollection *c) { return c->length(); }\n //%\n void setLength(RefCollection *c, int newLength) { c->setLength(newLength); } \n //%\n void push(RefCollection *c, uint32_t x) { c->push(x); }\n //%\n uint32_t pop(RefCollection *c) { return c->pop(); } \n //%\n uint32_t getAt(RefCollection *c, int x) { return c->getAt(x); }\n //%\n void setAt(RefCollection *c, int x, uint32_t y) { c->setAt(x, y); } \n //%\n uint32_t removeAt(RefCollection *c, int x) { return c->removeAt(x); }\n //%\n void insertAt(RefCollection *c, int x, uint32_t value) { c->insertAt(x, value); } \n //%\n int indexOf(RefCollection *c, uint32_t x, int start) { return c->indexOf(x, start); }\n //%\n int removeElement(RefCollection *c, uint32_t x) { return c->removeElement(x); }\n}\n\n\n// Import some stuff directly\nnamespace pxt {\n //%\n void registerWithDal(int id, int event, Action a);\n //%\n uint32_t runAction3(Action a, int arg0, int arg1, int arg2);\n //%\n uint32_t runAction2(Action a, int arg0, int arg1);\n //%\n uint32_t runAction1(Action a, int arg0);\n //%\n uint32_t runAction0(Action a);\n //%\n Action mkAction(int reflen, int totallen, int startptr);\n //%\n RefRecord* mkClassInstance(int offset);\n //%\n void RefRecord_destroy(RefRecord *r);\n //%\n void RefRecord_print(RefRecord *r);\n //%\n void debugMemLeaks();\n //%\n int incr(uint32_t e);\n //%\n void decr(uint32_t e);\n //%\n uint32_t *allocate(uint16_t sz);\n //%\n int templateHash();\n //%\n int programHash();\n //%\n void *ptrOfLiteral(int offset);\n //%\n int getNumGlobals();\n\n //%\n uint32_t programSize() {\n return bytecode[17] * 2;\n }\n\n#ifndef PAGE_SIZE\n\n#define PAGE_SIZE 1\n\n#endif\n\n //%\n uint32_t afterProgramPage() {\n uint32_t ptr = (uint32_t)&bytecode[0];\n ptr += programSize();\n ptr = (ptr + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);\n return ptr;\n }\n}\n\nnamespace pxtrt {\n //%\n uint32_t ldloc(RefLocal *r) {\n return r->v;\n }\n\n //%\n uint32_t ldlocRef(RefRefLocal *r) {\n uint32_t tmp = r->v;\n incr(tmp);\n return tmp;\n }\n\n //%\n void stloc(RefLocal *r, uint32_t v) {\n r->v = v;\n }\n\n //%\n void stlocRef(RefRefLocal *r, uint32_t v) {\n decr(r->v);\n r->v = v;\n }\n\n //%\n RefLocal *mkloc() {\n return new RefLocal();\n }\n\n //%\n RefRefLocal *mklocRef() {\n return new RefRefLocal();\n }\n\n // All of the functions below unref() self. This is for performance reasons -\n // the code emitter will not emit the unrefs for them.\n \n //%\n uint32_t ldfld(RefRecord *r, int idx) {\n auto tmp = r->ld(idx);\n r->unref();\n return tmp;\n }\n\n //%\n uint32_t ldfldRef(RefRecord *r, int idx) {\n auto tmp = r->ldref(idx);\n r->unref();\n return tmp;\n }\n\n //%\n void stfld(RefRecord *r, int idx, uint32_t val) {\n r->st(idx, val);\n r->unref();\n }\n\n //%\n void stfldRef(RefRecord *r, int idx, uint32_t val) {\n r->stref(idx, val);\n r->unref();\n }\n\n // Store a captured local in a closure. It returns the action, so it can be chained.\n //%\n RefAction *stclo(RefAction *a, int idx, uint32_t v)\n {\n //DBG(\"STCLO \"); a->print(); DBG(\"@%d = %p\\n\", idx, (void*)v);\n a->stCore(idx, v);\n return a;\n }\n\n //%\n void panic(int code)\n {\n microbit_panic(code);\n }\n\n //%\n int stringToBool(StringData *s) {\n if (s == NULL) return 0;\n if (s->len == 0) {\n s->decr();\n return 0;\n }\n s->decr();\n return 1;\n }\n\n //%\n StringData* emptyToNull(StringData *s) {\n if (!s || s->len == 0)\n return NULL;\n return s;\n }\n\n //%\n int ptrToBool(uint32_t p) {\n if (p) {\n decr(p);\n return 1;\n } else {\n return 0;\n }\n }\n\n //%\n RefMap *mkMap() {\n return new RefMap();\n }\n\n //%\n uint32_t mapGet(RefMap *map, uint32_t key) {\n int i = map->findIdx(key);\n if (i < 0) {\n map->unref();\n return 0;\n }\n uint32_t r = map->data[i].val;\n map->unref();\n return r;\n }\n\n //%\n uint32_t mapGetRef(RefMap *map, uint32_t key) {\n int i = map->findIdx(key);\n if (i < 0) {\n map->unref();\n return 0;\n }\n uint32_t r = incr(map->data[i].val);\n map->unref();\n return r;\n }\n\n //%\n void mapSet(RefMap *map, uint32_t key, uint32_t val) {\n int i = map->findIdx(key);\n if (i < 0) {\n map->data.push_back({\n key << 1,\n val\n });\n } else {\n if (map->data[i].key & 1) {\n decr(map->data[i].val);\n map->data[i].key = key << 1;\n }\n map->data[i].val = val;\n }\n map->unref();\n }\n\n //%\n void mapSetRef(RefMap *map, uint32_t key, uint32_t val) {\n int i = map->findIdx(key);\n if (i < 0) {\n map->data.push_back({\n (key << 1) | 1,\n val\n });\n } else {\n if (map->data[i].key & 1) {\n decr(map->data[i].val);\n } else {\n map->data[i].key = (key << 1) | 1;\n }\n map->data[i].val = val;\n }\n map->unref(); \n }\n\n //\n // Debugger\n //\n\n //%\n void* getGlobalsPtr() {\n return globals;\n }\n\n //%\n void runtimeWarning(StringData *s) {\n // noop for now\n }\n}\n",
"dal.d.ts": "// Auto-generated. Do not edit.\ndeclare const enum DAL {\n // built/yt/yotta_modules/microbit-dal/inc/bluetooth/ExternalEvents.h\n MICROBIT_ID_BLE = 1000,\n MICROBIT_ID_BLE_UART = 1200,\n MICROBIT_BLE_EVT_CONNECTED = 1,\n MICROBIT_BLE_EVT_DISCONNECTED = 2,\n // built/yt/yotta_modules/microbit-dal/inc/bluetooth/MESEvents.h\n MES_REMOTE_CONTROL_ID = 1001,\n MES_REMOTE_CONTROL_EVT_PLAY = 1,\n MES_REMOTE_CONTROL_EVT_PAUSE = 2,\n MES_REMOTE_CONTROL_EVT_STOP = 3,\n MES_REMOTE_CONTROL_EVT_NEXTTRACK = 4,\n MES_REMOTE_CONTROL_EVT_PREVTRACK = 5,\n MES_REMOTE_CONTROL_EVT_FORWARD = 6,\n MES_REMOTE_CONTROL_EVT_REWIND = 7,\n MES_REMOTE_CONTROL_EVT_VOLUMEUP = 8,\n MES_REMOTE_CONTROL_EVT_VOLUMEDOWN = 9,\n MES_CAMERA_ID = 1002,\n MES_CAMERA_EVT_LAUNCH_PHOTO_MODE = 1,\n MES_CAMERA_EVT_LAUNCH_VIDEO_MODE = 2,\n MES_CAMERA_EVT_TAKE_PHOTO = 3,\n MES_CAMERA_EVT_START_VIDEO_CAPTURE = 4,\n MES_CAMERA_EVT_STOP_VIDEO_CAPTURE = 5,\n MES_CAMERA_EVT_STOP_PHOTO_MODE = 6,\n MES_CAMERA_EVT_STOP_VIDEO_MODE = 7,\n MES_CAMERA_EVT_TOGGLE_FRONT_REAR = 8,\n MES_ALERTS_ID = 1004,\n MES_ALERT_EVT_DISPLAY_TOAST = 1,\n MES_ALERT_EVT_VIBRATE = 2,\n MES_ALERT_EVT_PLAY_SOUND = 3,\n MES_ALERT_EVT_PLAY_RINGTONE = 4,\n MES_ALERT_EVT_FIND_MY_PHONE = 5,\n MES_ALERT_EVT_ALARM1 = 6,\n MES_ALERT_EVT_ALARM2 = 7,\n MES_ALERT_EVT_ALARM3 = 8,\n MES_ALERT_EVT_ALARM4 = 9,\n MES_ALERT_EVT_ALARM5 = 10,\n MES_ALERT_EVT_ALARM6 = 11,\n MES_SIGNAL_STRENGTH_ID = 1101,\n MES_SIGNAL_STRENGTH_EVT_NO_BAR = 1,\n MES_SIGNAL_STRENGTH_EVT_ONE_BAR = 2,\n MES_SIGNAL_STRENGTH_EVT_TWO_BAR = 3,\n MES_SIGNAL_STRENGTH_EVT_THREE_BAR = 4,\n MES_SIGNAL_STRENGTH_EVT_FOUR_BAR = 5,\n MES_DEVICE_INFO_ID = 1103,\n MES_DEVICE_ORIENTATION_LANDSCAPE = 1,\n MES_DEVICE_ORIENTATION_PORTRAIT = 2,\n MES_DEVICE_GESTURE_NONE = 3,\n MES_DEVICE_GESTURE_DEVICE_SHAKEN = 4,\n MES_DEVICE_DISPLAY_OFF = 5,\n MES_DEVICE_DISPLAY_ON = 6,\n MES_DEVICE_INCOMING_CALL = 7,\n MES_DEVICE_INCOMING_MESSAGE = 8,\n MES_DPAD_CONTROLLER_ID = 1104,\n MES_DPAD_BUTTON_A_DOWN = 1,\n MES_DPAD_BUTTON_A_UP = 2,\n MES_DPAD_BUTTON_B_DOWN = 3,\n MES_DPAD_BUTTON_B_UP = 4,\n MES_DPAD_BUTTON_C_DOWN = 5,\n MES_DPAD_BUTTON_C_UP = 6,\n MES_DPAD_BUTTON_D_DOWN = 7,\n MES_DPAD_BUTTON_D_UP = 8,\n MES_DPAD_BUTTON_1_DOWN = 9,\n MES_DPAD_BUTTON_1_UP = 10,\n MES_DPAD_BUTTON_2_DOWN = 11,\n MES_DPAD_BUTTON_2_UP = 12,\n MES_DPAD_BUTTON_3_DOWN = 13,\n MES_DPAD_BUTTON_3_UP = 14,\n MES_DPAD_BUTTON_4_DOWN = 15,\n MES_DPAD_BUTTON_4_UP = 16,\n MES_BROADCAST_GENERAL_ID = 2000,\n // built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitAccelerometerService.h\n // built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitBLEManager.h\n MICROBIT_BLE_PAIR_REQUEST = 0x01,\n MICROBIT_BLE_PAIR_COMPLETE = 0x02,\n MICROBIT_BLE_PAIR_PASSCODE = 0x04,\n MICROBIT_BLE_PAIR_SUCCESSFUL = 0x08,\n MICROBIT_BLE_PAIRING_TIMEOUT = 90,\n MICROBIT_BLE_POWER_LEVELS = 8,\n MICROBIT_BLE_MAXIMUM_BONDS = 4,\n MICROBIT_BLE_EDDYSTONE_ADV_INTERVAL = 400,\n MICROBIT_BLE_EDDYSTONE_DEFAULT_POWER = 0xF0,\n MICROBIT_BLE_STATUS_STORE_SYSATTR = 0x02,\n MICROBIT_BLE_STATUS_DISCONNECT = 0x04,\n MICROBIT_BLE_DISCONNECT_AFTER_PAIRING_DELAY = 500,\n // built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitButtonService.h\n // built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitDFUService.h\n MICROBIT_DFU_OPCODE_START_DFU = 1,\n MICROBIT_DFU_HISTOGRAM_WIDTH = 5,\n MICROBIT_DFU_HISTOGRAM_HEIGHT = 5,\n // built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitEddystone.h\n // built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitEventService.h\n // built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitIOPinService.h\n MICROBIT_IO_PIN_SERVICE_PINCOUNT = 19,\n MICROBIT_IO_PIN_SERVICE_DATA_SIZE = 10,\n MICROBIT_PWM_PIN_SERVICE_DATA_SIZE = 2,\n // built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitLEDService.h\n MICROBIT_BLE_MAXIMUM_SCROLLTEXT = 20,\n // built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitMagnetometerService.h\n // built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitTemperatureService.h\n // built/yt/yotta_modules/microbit-dal/inc/bluetooth/MicroBitUARTService.h\n MICROBIT_UART_S_DEFAULT_BUF_SIZE = 20,\n MICROBIT_UART_S_EVT_DELIM_MATCH = 1,\n MICROBIT_UART_S_EVT_HEAD_MATCH = 2,\n MICROBIT_UART_S_EVT_RX_FULL = 3,\n // built/yt/yotta_modules/microbit-dal/inc/core/ErrorNo.h\n MICROBIT_OK = 0,\n MICROBIT_INVALID_PARAMETER = -1001,\n MICROBIT_NOT_SUPPORTED = -1002,\n MICROBIT_CALIBRATION_IN_PROGRESS = -1003,\n MICROBIT_CALIBRATION_REQUIRED = -1004,\n MICROBIT_NO_RESOURCES = -1005,\n MICROBIT_BUSY = -1006,\n MICROBIT_CANCELLED = -1007,\n MICROBIT_I2C_ERROR = -1010,\n MICROBIT_SERIAL_IN_USE = -1011,\n MICROBIT_NO_DATA = -1012,\n MICROBIT_OOM = 20,\n MICROBIT_HEAP_ERROR = 30,\n MICROBIT_NULL_DEREFERENCE = 40,\n // built/yt/yotta_modules/microbit-dal/inc/core/EventModel.h\n // built/yt/yotta_modules/microbit-dal/inc/core/MemberFunctionCallback.h\n // built/yt/yotta_modules/microbit-dal/inc/core/MicroBitCompat.h\n // built/yt/yotta_modules/microbit-dal/inc/core/MicroBitComponent.h\n MICROBIT_ID_BUTTON_A = 1,\n MICROBIT_ID_BUTTON_B = 2,\n MICROBIT_ID_BUTTON_RESET = 3,\n MICROBIT_ID_ACCELEROMETER = 4,\n MICROBIT_ID_COMPASS = 5,\n MICROBIT_ID_DISPLAY = 6,\n MICROBIT_ID_IO_P0 = 7,\n MICROBIT_ID_IO_P1 = 8,\n MICROBIT_ID_IO_P2 = 9,\n MICROBIT_ID_IO_P3 = 10,\n MICROBIT_ID_IO_P4 = 11,\n MICROBIT_ID_IO_P5 = 12,\n MICROBIT_ID_IO_P6 = 13,\n MICROBIT_ID_IO_P7 = 14,\n MICROBIT_ID_IO_P8 = 15,\n MICROBIT_ID_IO_P9 = 16,\n MICROBIT_ID_IO_P10 = 17,\n MICROBIT_ID_IO_P11 = 18,\n MICROBIT_ID_IO_P12 = 19,\n MICROBIT_ID_IO_P13 = 20,\n MICROBIT_ID_IO_P14 = 21,\n MICROBIT_ID_IO_P15 = 22,\n MICROBIT_ID_IO_P16 = 23,\n MICROBIT_ID_IO_P19 = 24,\n MICROBIT_ID_IO_P20 = 25,\n MICROBIT_ID_IO_P21 = 50,\n MICROBIT_ID_BUTTON_AB = 26,\n MICROBIT_ID_GESTURE = 27,\n MICROBIT_ID_THERMOMETER = 28,\n MICROBIT_ID_RADIO = 29,\n MICROBIT_ID_RADIO_DATA_READY = 30,\n MICROBIT_ID_MULTIBUTTON_ATTACH = 31,\n MICROBIT_ID_SERIAL = 32,\n MICROBIT_ID_MESSAGE_BUS_LISTENER = 1021,\n MICROBIT_ID_NOTIFY_ONE = 1022,\n MICROBIT_ID_NOTIFY = 1023,\n MICROBIT_COMPONENT_RUNNING = 0x01,\n // built/yt/yotta_modules/microbit-dal/inc/core/MicroBitDevice.h\n MICROBIT_NAME_LENGTH = 5,\n MICROBIT_NAME_CODE_LETTERS = 5,\n MICROBIT_PANIC_ERROR_CHARS = 4,\n // built/yt/yotta_modules/microbit-dal/inc/core/MicroBitFiber.h\n MICROBIT_SCHEDULER_RUNNING = 0x01,\n MICROBIT_FIBER_FLAG_FOB = 0x01,\n MICROBIT_FIBER_FLAG_PARENT = 0x02,\n MICROBIT_FIBER_FLAG_CHILD = 0x04,\n MICROBIT_FIBER_FLAG_DO_NOT_PAGE = 0x08,\n // built/yt/yotta_modules/microbit-dal/inc/core/MicroBitFont.h\n MICROBIT_FONT_WIDTH = 5,\n MICROBIT_FONT_HEIGHT = 5,\n MICROBIT_FONT_ASCII_START = 32,\n MICROBIT_FONT_ASCII_END = 126,\n // built/yt/yotta_modules/microbit-dal/inc/core/MicroBitHeapAllocator.h\n MICROBIT_MAXIMUM_HEAPS = 2,\n MICROBIT_HEAP_BLOCK_FREE = 0x80000000,\n // built/yt/yotta_modules/microbit-dal/inc/core/MicroBitListener.h\n MESSAGE_BUS_LISTENER_PARAMETERISED = 0x0001,\n MESSAGE_BUS_LISTENER_METHOD = 0x0002,\n MESSAGE_BUS_LISTENER_BUSY = 0x0004,\n MESSAGE_BUS_LISTENER_REENTRANT = 0x0008,\n MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY = 0x0010,\n MESSAGE_BUS_LISTENER_DROP_IF_BUSY = 0x0020,\n MESSAGE_BUS_LISTENER_NONBLOCKING = 0x0040,\n MESSAGE_BUS_LISTENER_URGENT = 0x0080,\n MESSAGE_BUS_LISTENER_DELETING = 0x8000,\n // built/yt/yotta_modules/microbit-dal/inc/core/MicroBitSystemTimer.h\n // built/yt/yotta_modules/microbit-dal/inc/core/NotifyEvents.h\n MICROBIT_DISPLAY_EVT_FREE = 1,\n MICROBIT_SERIAL_EVT_TX_EMPTY = 2,\n MICROBIT_UART_S_EVT_TX_EMPTY = 3,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/CalliopeRGB.h\n RGB_LED_MAX_INTENSITY = 40,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/CalliopeSoundMotor.h\n CALLIOPE_SM_DEFAULT_DUTY_M = 50,\n CALLIOPE_SM_DEFAULT_DUTY_S = 100,\n CALLIOPE_SM_DEFAULT_FREQUENCY_S = 4000,\n CALLIOPE_SM_DEFAULT_SILENT_MODE = 1,\n CALLIOPE_SM_PRESCALER_M = 2,\n CALLIOPE_SM_PRESCALER_S = 0,\n CALLIOPE_SM_PRESCALER_S_LF = 4,\n CALLIOPE_SM_PERIOD_M = 100,\n CALLIOPE_MIN_FREQUENCY_HZ_S_NP = 245,\n CALLIOPE_MIN_FREQUENCY_HZ_S = 20,\n CALLIOPE_MAX_FREQUENCY_HZ_S = 20000,\n CALLIOPE_BOARD_FREQUENCY = 16000000,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/DynamicPwm.h\n MICROBIT_DEFAULT_PWM_PERIOD = 20000,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitAccelerometer-bmx.h\n BMX055_ACC_WHOAMI = 0x00,\n BMX055_ACC_D_X_LSB = 0x02,\n BMX055_ACC_D_X_MSB = 0x03,\n BMX055_ACC_D_Y_LSB = 0x04,\n BMX055_ACC_D_Y_MSB = 0x05,\n BMX055_ACC_D_Z_LSB = 0x06,\n BMX055_ACC_D_Z_MSB = 0x07,\n BMX055_ACC_D_TEMP = 0x08,\n BMX055_ACC_INT_STATUS_0 = 0x09,\n BMX055_ACC_INT_STATUS_1 = 0x0A,\n BMX055_ACC_INT_STATUS_2 = 0x0B,\n BMX055_ACC_INT_STATUS_3 = 0x0C,\n BMX055_ACC_FIFO_STATUS = 0x0E,\n BMX055_ACC_PMU_RANGE = 0x0F,\n BMX055_ACC_PMU_BW = 0x10,\n BMX055_ACC_PMU_LPW = 0x11,\n BMX055_ACC_PMU_LOW_POWER = 0x12,\n BMX055_ACC_D_HBW = 0x13,\n BMX055_ACC_BGW_SOFTRESET = 0x14,\n BMX055_ACC_INT_EN_0 = 0x16,\n BMX055_ACC_INT_EN_1 = 0x17,\n BMX055_ACC_INT_EN_2 = 0x18,\n BMX055_ACC_INT_MAP_0 = 0x19,\n BMX055_ACC_INT_MAP_1 = 0x1A,\n BMX055_ACC_INT_MAP_2 = 0x1B,\n BMX055_ACC_INT_SRC = 0x1E,\n BMX055_ACC_INT_OUT_CTRL = 0x20,\n BMX055_ACC_INT_RST_LATCH = 0x21,\n BMX055_ACC_INT_0 = 0x22,\n BMX055_ACC_INT_1 = 0x23,\n BMX055_ACC_INT_2 = 0x24,\n BMX055_ACC_INT_3 = 0x25,\n BMX055_ACC_INT_4 = 0x26,\n BMX055_ACC_INT_5 = 0x27,\n BMX055_ACC_INT_6 = 0x28,\n BMX055_ACC_INT_7 = 0x29,\n BMX055_ACC_INT_8 = 0x2A,\n BMX055_ACC_INT_9 = 0x2B,\n BMX055_ACC_INT_A = 0x2C,\n BMX055_ACC_INT_B = 0x2D,\n BMX055_ACC_INT_C = 0x2E,\n BMX055_ACC_INT_D = 0x2F,\n BMX055_ACC_FIFO_CONFIG_0 = 0x30,\n BMX055_ACC_PMU_SELF_TEST = 0x32,\n BMX055_ACC_TRIM_NVM_CTRL = 0x33,\n BMX055_ACC_BGW_SPI3_WDT = 0x34,\n BMX055_ACC_OFC_CTRL = 0x36,\n BMX055_ACC_OFC_SETTING = 0x37,\n BMX055_ACC_OFC_OFFSET_X = 0x38,\n BMX055_ACC_OFC_OFFSET_Y = 0x39,\n BMX055_ACC_OFC_OFFSET_Z = 0x3A,\n BMX055_ACC_TRIM_GPO = 0x3B,\n BMX055_ACC_TRIM_GP1 = 0x3C,\n BMX055_ACC_FIFO_CONFIG_1 = 0x3E,\n BMX055_ACC_FIFO_DATA = 0x3F,\n BMX055_GYRO_WHOAMI = 0x00,\n BMX055_GYRO_RATE_X_LSB = 0x02,\n BMX055_GYRO_RATE_X_MSB = 0x03,\n BMX055_GYRO_RATE_Y_LSB = 0x04,\n BMX055_GYRO_RATE_Y_MSB = 0x05,\n BMX055_GYRO_RATE_Z_LSB = 0x06,\n BMX055_GYRO_RATE_Z_MSB = 0x07,\n BMX055_GYRO_INT_STATUS_0 = 0x09,\n BMX055_GYRO_INT_STATUS_1 = 0x0A,\n BMX055_GYRO_INT_STATUS_2 = 0x0B,\n BMX055_GYRO_INT_STATUS_3 = 0x0C,\n BMX055_GYRO_FIFO_STATUS = 0x0E,\n BMX055_GYRO_RANGE = 0x0F,\n BMX055_GYRO_BW = 0x10,\n BMX055_GYRO_LPM1 = 0x11,\n BMX055_GYRO_LPM2 = 0x12,\n BMX055_GYRO_RATE_HBW = 0x13,\n BMX055_GYRO_BGW_SOFTRESET = 0x14,\n BMX055_GYRO_INT_EN_0 = 0x15,\n BMX055_GYRO_INT_EN_1 = 0x16,\n BMX055_GYRO_INT_MAP_0 = 0x17,\n BMX055_GYRO_INT_MAP_1 = 0x18,\n BMX055_GYRO_INT_MAP_2 = 0x19,\n BMX055_GYRO_INT_SRC_1 = 0x1A,\n BMX055_GYRO_INT_SRC_2 = 0x1B,\n BMX055_GYRO_INT_SRC_3 = 0x1C,\n BMX055_GYRO_FIFO_EN = 0x1E,\n BMX055_GYRO_INT_RST_LATCH = 0x21,\n BMX055_GYRO_HIGH_TH_X = 0x22,\n BMX055_GYRO_HIGH_DUR_X = 0x23,\n BMX055_GYRO_HIGH_TH_Y = 0x24,\n BMX055_GYRO_HIGH_DUR_Y = 0x25,\n BMX055_GYRO_HIGH_TH_Z = 0x26,\n BMX055_GYRO_HIGH_DUR_Z = 0x27,\n BMX055_GYRO_SOC = 0x31,\n BMX055_GYRO_A_FOC = 0x32,\n BMX055_GYRO_TRIM_NVM_CTRL = 0x33,\n BMX055_GYRO_BGW_SPI3_WDT = 0x34,\n BMX055_GYRO_OFC1 = 0x36,\n BMX055_GYRO_OFC2 = 0x37,\n BMX055_GYRO_OFC3 = 0x38,\n BMX055_GYRO_OFC4 = 0x39,\n BMX055_GYRO_TRIM_GP0 = 0x3A,\n BMX055_GYRO_TRIM_GP1 = 0x3B,\n BMX055_GYRO_BIST = 0x3C,\n BMX055_GYRO_FIFO_CONFIG_0 = 0x3D,\n BMX055_GYRO_FIFO_CONFIG_1 = 0x3E,\n BMX055_MAG_WHOAMI = 0x40,\n BMX055_MAG_Reserved = 0x41,\n BMX055_MAG_XOUT_LSB = 0x42,\n BMX055_MAG_XOUT_MSB = 0x43,\n BMX055_MAG_YOUT_LSB = 0x44,\n BMX055_MAG_YOUT_MSB = 0x45,\n BMX055_MAG_ZOUT_LSB = 0x46,\n BMX055_MAG_ZOUT_MSB = 0x47,\n BMX055_MAG_ROUT_LSB = 0x48,\n BMX055_MAG_ROUT_MSB = 0x49,\n BMX055_MAG_INT_STATUS = 0x4A,\n BMX055_MAG_PWR_CNTL1 = 0x4B,\n BMX055_MAG_PWR_CNTL2 = 0x4C,\n BMX055_MAG_INT_EN_1 = 0x4D,\n BMX055_MAG_INT_EN_2 = 0x4E,\n BMX055_MAG_LOW_THS = 0x4F,\n BMX055_MAG_HIGH_THS = 0x50,\n BMX055_MAG_REP_XY = 0x51,\n BMX055_MAG_REP_Z = 0x52,\n BMM050_DIG_X1 = 0x5D,\n BMM050_DIG_Y1 = 0x5E,\n BMM050_DIG_Z4_LSB = 0x62,\n BMM050_DIG_Z4_MSB = 0x63,\n BMM050_DIG_X2 = 0x64,\n BMM050_DIG_Y2 = 0x65,\n BMM050_DIG_Z2_LSB = 0x68,\n BMM050_DIG_Z2_MSB = 0x69,\n BMM050_DIG_Z1_LSB = 0x6A,\n BMM050_DIG_Z1_MSB = 0x6B,\n BMM050_DIG_XYZ1_LSB = 0x6C,\n BMM050_DIG_XYZ1_MSB = 0x6D,\n BMM050_DIG_Z3_LSB = 0x6E,\n BMM050_DIG_Z3_MSB = 0x6F,\n BMM050_DIG_XY2 = 0x70,\n BMM050_DIG_XY1 = 0x71,\n BMX055_ACC_ADDRESS = 0x18,\n BMX055_GYRO_ADDRESS = 0x68,\n BMX055_MAG_ADDRESS = 0x10,\n MS5637_ADDRESS = 0x76,\n AFS_2G = 0x03,\n AFS_4G = 0x05,\n AFS_8G = 0x08,\n AFS_16G = 0x0C,\n ABW_8Hz = 0,\n ABW_16Hz = 1,\n ABW_31Hz = 2,\n ABW_63Hz = 3,\n ABW_125Hz = 4,\n ABW_250Hz = 5,\n ABW_500Hz = 6,\n ABW_100Hz = 7,\n GFS_2000DPS = 0,\n GFS_1000DPS = 1,\n GFS_500DPS = 2,\n GFS_250DPS = 3,\n GFS_125DPS = 4,\n G_2000Hz523Hz = 0,\n G_2000Hz230Hz = 1,\n G_1000Hz116Hz = 2,\n G_400Hz47Hz = 3,\n G_200Hz23Hz = 4,\n G_100Hz12Hz = 5,\n G_200Hz64Hz = 6,\n G_100Hz32Hz = 7,\n MODR_10Hz = 0,\n MODR_2Hz = 1,\n MODR_6Hz = 2,\n MODR_8Hz = 3,\n MODR_15Hz = 4,\n MODR_20Hz = 5,\n MODR_25Hz = 6,\n MODR_30Hz = 7,\n lowPower = 0,\n Regular = 1,\n enhancedRegular = 2,\n highAccuracy = 3,\n ADC_256 = 0x00,\n ADC_512 = 0x02,\n ADC_1024 = 0x04,\n ADC_2048 = 0x06,\n ADC_4096 = 0x08,\n ADC_8192 = 0x0A,\n ADC_D1 = 0x40,\n ADC_D2 = 0x50,\n MICROBIT_ACCEL_PITCH_ROLL_VALID = 0x02,\n MICROBIT_ACCEL_ADDED_TO_IDLE = 0x04,\n MMA8653_STATUS = 0x00,\n MMA8653_OUT_X_MSB = 0x01,\n MMA8653_WHOAMI = 0x0D,\n MMA8653_XYZ_DATA_CFG = 0x0E,\n MMA8653_CTRL_REG1 = 0x2A,\n MMA8653_CTRL_REG2 = 0x2B,\n MMA8653_CTRL_REG3 = 0x2C,\n MMA8653_CTRL_REG4 = 0x2D,\n MMA8653_CTRL_REG5 = 0x2E,\n MMA8653_WHOAMI_VAL = 0x5A,\n MMA8653_SAMPLE_RANGES = 3,\n MMA8653_SAMPLE_RATES = 8,\n MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE = 1,\n MICROBIT_ACCELEROMETER_EVT_NONE = 0,\n MICROBIT_ACCELEROMETER_EVT_TILT_UP = 1,\n MICROBIT_ACCELEROMETER_EVT_TILT_DOWN = 2,\n MICROBIT_ACCELEROMETER_EVT_TILT_LEFT = 3,\n MICROBIT_ACCELEROMETER_EVT_TILT_RIGHT = 4,\n MICROBIT_ACCELEROMETER_EVT_FACE_UP = 5,\n MICROBIT_ACCELEROMETER_EVT_FACE_DOWN = 6,\n MICROBIT_ACCELEROMETER_EVT_FREEFALL = 7,\n MICROBIT_ACCELEROMETER_EVT_2G = 8,\n MICROBIT_ACCELEROMETER_EVT_3G = 9,\n MICROBIT_ACCELEROMETER_EVT_6G = 10,\n MICROBIT_ACCELEROMETER_EVT_8G = 11,\n MICROBIT_ACCELEROMETER_EVT_SHAKE = 12,\n MICROBIT_ACCELEROMETER_REST_TOLERANCE = 200,\n MICROBIT_ACCELEROMETER_TILT_TOLERANCE = 200,\n MICROBIT_ACCELEROMETER_FREEFALL_TOLERANCE = 400,\n MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE = 400,\n MICROBIT_ACCELEROMETER_2G_TOLERANCE = 2048,\n MICROBIT_ACCELEROMETER_3G_TOLERANCE = 3072,\n MICROBIT_ACCELEROMETER_6G_TOLERANCE = 6144,\n MICROBIT_ACCELEROMETER_8G_TOLERANCE = 8192,\n MICROBIT_ACCELEROMETER_GESTURE_DAMPING = 5,\n MICROBIT_ACCELEROMETER_SHAKE_DAMPING = 10,\n MICROBIT_ACCELEROMETER_SHAKE_RTX = 30,\n MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD = 4,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitAccelerometer.h\n MMA8653_DEFAULT_ADDR = 0x3A,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitButton.h\n MICROBIT_BUTTON_EVT_DOWN = 1,\n MICROBIT_BUTTON_EVT_UP = 2,\n MICROBIT_BUTTON_EVT_CLICK = 3,\n MICROBIT_BUTTON_EVT_LONG_CLICK = 4,\n MICROBIT_BUTTON_EVT_HOLD = 5,\n MICROBIT_BUTTON_EVT_DOUBLE_CLICK = 6,\n MICROBIT_BUTTON_LONG_CLICK_TIME = 1000,\n MICROBIT_BUTTON_HOLD_TIME = 1500,\n MICROBIT_BUTTON_STATE = 1,\n MICROBIT_BUTTON_STATE_HOLD_TRIGGERED = 2,\n MICROBIT_BUTTON_STATE_CLICK = 4,\n MICROBIT_BUTTON_STATE_LONG_CLICK = 8,\n MICROBIT_BUTTON_SIGMA_MIN = 0,\n MICROBIT_BUTTON_SIGMA_MAX = 12,\n MICROBIT_BUTTON_SIGMA_THRESH_HI = 8,\n MICROBIT_BUTTON_SIGMA_THRESH_LO = 2,\n MICROBIT_BUTTON_DOUBLE_CLICK_THRESH = 50,\n MICROBIT_BUTTON_SIMPLE_EVENTS = 0,\n MICROBIT_BUTTON_ALL_EVENTS = 1,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitCompass-bmx.h\n MAG3110_DEFAULT_ADDR = 0x1D,\n MAG_DR_STATUS = 0x00,\n MAG_OUT_X_MSB = 0x01,\n MAG_OUT_X_LSB = 0x02,\n MAG_OUT_Y_MSB = 0x03,\n MAG_OUT_Y_LSB = 0x04,\n MAG_OUT_Z_MSB = 0x05,\n MAG_OUT_Z_LSB = 0x06,\n MAG_WHOAMI = 0x07,\n MAG_SYSMOD = 0x08,\n MAG_OFF_X_MSB = 0x09,\n MAG_OFF_X_LSB = 0x0A,\n MAG_OFF_Y_MSB = 0x0B,\n MAG_OFF_Y_LSB = 0x0C,\n MAG_OFF_Z_MSB = 0x0D,\n MAG_OFF_Z_LSB = 0x0E,\n MAG_DIE_TEMP = 0x0F,\n MAG_CTRL_REG1 = 0x10,\n MAG_CTRL_REG2 = 0x11,\n MAG3110_SAMPLE_RATES = 11,\n MICROBIT_COMPASS_EVT_CAL_REQUIRED = 1,\n MICROBIT_COMPASS_EVT_CAL_START = 2,\n MICROBIT_COMPASS_EVT_CAL_END = 3,\n MICROBIT_COMPASS_EVT_DATA_UPDATE = 4,\n MICROBIT_COMPASS_EVT_CONFIG_NEEDED = 5,\n MICROBIT_COMPASS_EVT_CALIBRATE = 6,\n MICROBIT_COMPASS_STATUS_CALIBRATED = 2,\n MICROBIT_COMPASS_STATUS_CALIBRATING = 4,\n MICROBIT_COMPASS_STATUS_ADDED_TO_IDLE = 8,\n MAG3110_WHOAMI_VAL = 0xC4,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitCompass.h\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitCompassCalibrator.h\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitDisplay.h\n MICROBIT_DISPLAY_EVT_ANIMATION_COMPLETE = 1,\n MICROBIT_DISPLAY_EVT_LIGHT_SENSE = 2,\n MICROBIT_DISPLAY_DEFAULT_AUTOCLEAR = 1,\n MICROBIT_DISPLAY_SPACING = 1,\n MICROBIT_DISPLAY_GREYSCALE_BIT_DEPTH = 8,\n MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS = -255,\n ANIMATION_MODE_NONE = 0,\n ANIMATION_MODE_STOPPED = 1,\n ANIMATION_MODE_SCROLL_TEXT = 2,\n ANIMATION_MODE_PRINT_TEXT = 3,\n ANIMATION_MODE_SCROLL_IMAGE = 4,\n ANIMATION_MODE_ANIMATE_IMAGE = 5,\n ANIMATION_MODE_ANIMATE_IMAGE_WITH_CLEAR = 6,\n ANIMATION_MODE_PRINT_CHARACTER = 7,\n DISPLAY_MODE_BLACK_AND_WHITE = 0,\n DISPLAY_MODE_GREYSCALE = 1,\n DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE = 2,\n MICROBIT_DISPLAY_ROTATION_0 = 0,\n MICROBIT_DISPLAY_ROTATION_90 = 1,\n MICROBIT_DISPLAY_ROTATION_180 = 2,\n MICROBIT_DISPLAY_ROTATION_270 = 3,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitFile.h\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitFileSystem.h\n MBFS_FILENAME_LENGTH = 16,\n MB_READ = 0x01,\n MB_WRITE = 0x02,\n MB_CREAT = 0x04,\n MB_APPEND = 0x08,\n MB_SEEK_SET = 0x01,\n MB_SEEK_END = 0x02,\n MB_SEEK_CUR = 0x04,\n MBFS_STATUS_INITIALISED = 0x01,\n MBFS_UNUSED = 0xFFFF,\n MBFS_EOF = 0xEFFF,\n MBFS_DELETED = 0x0000,\n MBFS_DIRECTORY_ENTRY_FREE = 0x8000,\n MBFS_DIRECTORY_ENTRY_VALID = 0x4000,\n MBFS_DIRECTORY_ENTRY_DIRECTORY = 0x2000,\n MBFS_DIRECTORY_ENTRY_NEW = 0xffff,\n MBFS_DIRECTORY_ENTRY_DELETED = 0x0000,\n MBFS_BLOCK_TYPE_FILE = 1,\n MBFS_BLOCK_TYPE_DIRECTORY = 2,\n MBFS_BLOCK_TYPE_FILETABLE = 3,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitFlash.h\n PAGE_SIZE = 1024,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitI2C.h\n MICROBIT_I2C_MAX_RETRIES = 9,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitIO.h\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitLightSensor.h\n MICROBIT_LIGHT_SENSOR_CHAN_NUM = 3,\n MICROBIT_LIGHT_SENSOR_AN_SET_TIME = 4000,\n MICROBIT_LIGHT_SENSOR_TICK_PERIOD = 5,\n MICROBIT_LIGHT_SENSOR_MAX_VALUE = 338,\n MICROBIT_LIGHT_SENSOR_MIN_VALUE = 75,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitMatrixMaps.h\n NO_CONN = 0,\n MICROBIT_DISPLAY_WIDTH = 5,\n MICROBIT_DISPLAY_HEIGHT = 5,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitMessageBus.h\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitMultiButton.h\n MICROBIT_MULTI_BUTTON_STATE_1 = 0x01,\n MICROBIT_MULTI_BUTTON_STATE_2 = 0x02,\n MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_1 = 0x04,\n MICROBIT_MULTI_BUTTON_HOLD_TRIGGERED_2 = 0x08,\n MICROBIT_MULTI_BUTTON_SUPRESSED_1 = 0X10,\n MICROBIT_MULTI_BUTTON_SUPRESSED_2 = 0x20,\n MICROBIT_MULTI_BUTTON_ATTACHED = 0x40,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitPin.h\n IO_STATUS_DIGITAL_IN = 0x01,\n IO_STATUS_DIGITAL_OUT = 0x02,\n IO_STATUS_ANALOG_IN = 0x04,\n IO_STATUS_ANALOG_OUT = 0x08,\n IO_STATUS_TOUCH_IN = 0x10,\n IO_STATUS_EVENT_ON_EDGE = 0x20,\n IO_STATUS_EVENT_PULSE_ON_EDGE = 0x40,\n IO_STATUS_EVENTBUS_ENABLED = 0x80,\n MICROBIT_PIN_MAX_OUTPUT = 1023,\n MICROBIT_PIN_MAX_SERVO_RANGE = 180,\n MICROBIT_PIN_DEFAULT_SERVO_RANGE = 2000,\n MICROBIT_PIN_DEFAULT_SERVO_CENTER = 1500,\n MICROBIT_PIN_EVENT_NONE = 0,\n MICROBIT_PIN_EVENT_ON_EDGE = 1,\n MICROBIT_PIN_EVENT_ON_PULSE = 2,\n MICROBIT_PIN_EVENT_ON_TOUCH = 3,\n MICROBIT_PIN_EVT_RISE = 2,\n MICROBIT_PIN_EVT_FALL = 3,\n MICROBIT_PIN_EVT_PULSE_HI = 4,\n MICROBIT_PIN_EVT_PULSE_LO = 5,\n PIN_CAPABILITY_DIGITAL_IN = 0x01,\n PIN_CAPABILITY_DIGITAL_OUT = 0x02,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitQuadratureDecoder.h\n QDEC_USE_SYSTEM_TICK = 0x01,\n QDEC_USE_DEBOUNCE = 0x02,\n QDEC_LED_ACTIVE_LOW = 0x04,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitRadio.h\n MICROBIT_RADIO_STATUS_INITIALISED = 0x0001,\n MICROBIT_RADIO_BASE_ADDRESS = 0x75626974,\n MICROBIT_RADIO_DEFAULT_GROUP = 0,\n MICROBIT_RADIO_DEFAULT_TX_POWER = 6,\n MICROBIT_RADIO_DEFAULT_FREQUENCY = 7,\n MICROBIT_RADIO_MAX_PACKET_SIZE = 32,\n MICROBIT_RADIO_HEADER_SIZE = 4,\n MICROBIT_RADIO_MAXIMUM_RX_BUFFERS = 4,\n MICROBIT_RADIO_PROTOCOL_DATAGRAM = 1,\n MICROBIT_RADIO_PROTOCOL_EVENTBUS = 2,\n MICROBIT_RADIO_EVT_DATAGRAM = 1,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitRadioDatagram.h\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitRadioEvent.h\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitSerial.h\n MICROBIT_SERIAL_DEFAULT_BAUD_RATE = 115200,\n MICROBIT_SERIAL_DEFAULT_BUFFER_SIZE = 20,\n MICROBIT_SERIAL_EVT_DELIM_MATCH = 1,\n MICROBIT_SERIAL_EVT_HEAD_MATCH = 2,\n MICROBIT_SERIAL_EVT_RX_FULL = 3,\n MICROBIT_SERIAL_RX_IN_USE = 1,\n MICROBIT_SERIAL_TX_IN_USE = 2,\n MICROBIT_SERIAL_RX_BUFF_INIT = 4,\n MICROBIT_SERIAL_TX_BUFF_INIT = 8,\n ASYNC = 0,\n SYNC_SPINWAIT = 1,\n SYNC_SLEEP = 2,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitStorage.h\n MICROBIT_STORAGE_MAGIC = 0xCAFE,\n MICROBIT_STORAGE_BLOCK_SIZE = 48,\n MICROBIT_STORAGE_KEY_SIZE = 16,\n MICROBIT_STORAGE_STORE_PAGE_OFFSET = 17,\n MICROBIT_STORAGE_SCRATCH_PAGE_OFFSET = 19,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/MicroBitThermometer.h\n MICROBIT_THERMOMETER_PERIOD = 1000,\n MICROBIT_THERMOMETER_EVT_UPDATE = 1,\n MICROBIT_THERMOMETER_ADDED_TO_IDLE = 2,\n // built/yt/yotta_modules/microbit-dal/inc/drivers/TimedInterruptIn.h\n // built/yt/yotta_modules/microbit-dal/inc/platform/yotta_cfg_mappings.h\n // built/yt/yotta_modules/microbit-dal/inc/types/ManagedString.h\n // built/yt/yotta_modules/microbit-dal/inc/types/ManagedType.h\n // built/yt/yotta_modules/microbit-dal/inc/types/Matrix4.h\n // built/yt/yotta_modules/microbit-dal/inc/types/MicroBitCoordinateSystem.h\n RAW = 0,\n SIMPLE_CARTESIAN = 1,\n NORTH_EAST_DOWN = 2,\n // built/yt/yotta_modules/microbit-dal/inc/types/MicroBitEvent.h\n MICROBIT_ID_ANY = 0,\n MICROBIT_EVT_ANY = 0,\n CREATE_ONLY = 0,\n CREATE_AND_FIRE = 1,\n // built/yt/yotta_modules/microbit-dal/inc/types/MicroBitImage.h\n // built/yt/yotta_modules/microbit-dal/inc/types/PacketBuffer.h\n // built/yt/yotta_modules/microbit-dal/inc/types/RefCounted.h\n}\n",
"enums.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace images {\n}\ndeclare namespace basic {\n}\n\n\n declare enum Button {\n A = 1, // MICROBIT_ID_BUTTON_A\n B = 2, // MICROBIT_ID_BUTTON_B\n //% block=\"A+B\"\n AB = 26, // MICROBIT_ID_BUTTON_AB\n }\n\n\n declare enum Dimension {\n //% block=x\n X = 0,\n //% block=y\n Y = 1,\n //% block=z\n Z = 2,\n //% block=strength\n Strength = 3,\n }\n\n\n declare enum Rotation {\n //% block=pitch\n Pitch = 0,\n //% block=roll\n Roll = 1,\n }\n\n\n declare enum TouchPin {\n P0 = 19, // MICROBIT_ID_IO_P12\n P1 = 7, // MICROBIT_ID_IO_P0\n P2 = 8, // MICROBIT_ID_IO_P1\n P3 = 23, // MICROBIT_ID_IO_P16\n }\n\n\n declare enum AcceleratorRange {\n /**\n * The accelerator measures forces up to 1 gravity\n */\n //% block=\"1g\"\n OneG = 1,\n /**\n * The accelerator measures forces up to 2 gravity\n */\n //% block=\"2g\"\n TwoG = 2,\n /**\n * The accelerator measures forces up to 4 gravity\n */\n //% block=\"4g\"\n FourG = 4,\n /**\n * The accelerator measures forces up to 8 gravity\n */\n //% block=\"8g\"\n EightG = 8,\n }\n\n\n declare enum Gesture {\n /**\n * Raised when shaken\n */\n //% block=shake\n Shake = 12, // MICROBIT_ACCELEROMETER_EVT_SHAKE\n /**\n * Raised when the logo is upward and the screen is vertical\n */\n //% block=\"logo up\"\n LogoUp = 1, // MICROBIT_ACCELEROMETER_EVT_TILT_UP\n /**\n * Raised when the logo is downward and the screen is vertical\n */\n //% block=\"logo down\"\n LogoDown = 2, // MICROBIT_ACCELEROMETER_EVT_TILT_DOWN\n /**\n * Raised when the screen is pointing down and the board is horizontal\n */\n //% block=\"screen up\"\n ScreenUp = 5, // MICROBIT_ACCELEROMETER_EVT_FACE_UP\n /**\n * Raised when the screen is pointing up and the board is horizontal\n */\n //% block=\"screen down\"\n ScreenDown = 6, // MICROBIT_ACCELEROMETER_EVT_FACE_DOWN\n /**\n * Raised when the screen is pointing left\n */\n //% block=\"tilt left\"\n TiltLeft = 3, // MICROBIT_ACCELEROMETER_EVT_TILT_LEFT\n /**\n * Raised when the screen is pointing right\n */\n //% block=\"tilt right\"\n TiltRight = 4, // MICROBIT_ACCELEROMETER_EVT_TILT_RIGHT\n /**\n * Raised when the board is falling!\n */\n //% block=\"free fall\"\n FreeFall = 7, // MICROBIT_ACCELEROMETER_EVT_FREEFALL\n /**\n * Raised when a 3G shock is detected\n */\n //% block=\"3g\"\n ThreeG = 9, // MICROBIT_ACCELEROMETER_EVT_3G\n /**\n * Raised when a 6G shock is detected\n */\n //% block=\"6g\"\n SixG = 10, // MICROBIT_ACCELEROMETER_EVT_6G\n }\ndeclare namespace input {\n}\n\n\n /**\n * How to create the event.\n */\n\n declare enum EventCreationMode {\n /**\n * MicroBitEvent is initialised, and no further processing takes place.\n */\n CreateOnly = 0, // CREATE_ONLY\n /**\n * MicroBitEvent is initialised, and its event handlers are immediately fired (not suitable for use in interrupts!).\n */\n CreateAndFire = 1, // CREATE_AND_FIRE\n }\n\n\n declare enum EventBusSource {\n MICROBIT_ID_BUTTON_A = 1, // MICROBIT_ID_BUTTON_A\n MICROBIT_ID_BUTTON_B = 2, // MICROBIT_ID_BUTTON_B\n MICROBIT_ID_BUTTON_AB = 26, // MICROBIT_ID_BUTTON_AB\n MICROBIT_ID_RADIO = 29, // MICROBIT_ID_RADIO\n MICROBIT_ID_GESTURE = 27, // MICROBIT_ID_GESTURE\n MICROBIT_ID_ACCELEROMETER = 4, // MICROBIT_ID_ACCELEROMETER\n MICROBIT_ID_IO_P0 = 7, // MICROBIT_ID_IO_P0\n MICROBIT_ID_IO_P1 = 8, // MICROBIT_ID_IO_P1\n MICROBIT_ID_IO_P2 = 9, // MICROBIT_ID_IO_P2\n MICROBIT_ID_IO_P3 = 10, // MICROBIT_ID_IO_P3\n MICROBIT_ID_IO_P4 = 11, // MICROBIT_ID_IO_P4\n MICROBIT_ID_IO_P5 = 12, // MICROBIT_ID_IO_P5\n MICROBIT_ID_IO_P6 = 13, // MICROBIT_ID_IO_P6\n MICROBIT_ID_IO_P7 = 14, // MICROBIT_ID_IO_P7\n MICROBIT_ID_IO_P8 = 15, // MICROBIT_ID_IO_P8\n MICROBIT_ID_IO_P9 = 16, // MICROBIT_ID_IO_P9\n MICROBIT_ID_IO_P10 = 17, // MICROBIT_ID_IO_P10\n MICROBIT_ID_IO_P11 = 18, // MICROBIT_ID_IO_P11\n MICROBIT_ID_IO_P12 = 19, // MICROBIT_ID_IO_P12\n MICROBIT_ID_IO_P13 = 20, // MICROBIT_ID_IO_P13\n MICROBIT_ID_IO_P14 = 21, // MICROBIT_ID_IO_P14\n MICROBIT_ID_IO_P15 = 22, // MICROBIT_ID_IO_P15\n MICROBIT_ID_IO_P16 = 23, // MICROBIT_ID_IO_P16\n MICROBIT_ID_IO_P19 = 24, // MICROBIT_ID_IO_P19\n MICROBIT_ID_IO_P20 = 25, // MICROBIT_ID_IO_P20\n MICROBIT_ID_IO_P21 = 50, // MICROBIT_ID_IO_P21\n MES_DEVICE_INFO_ID = 1103, // MES_DEVICE_INFO_ID\n MES_SIGNAL_STRENGTH_ID = 1101, // MES_SIGNAL_STRENGTH_ID\n MES_DPAD_CONTROLLER_ID = 1104, // MES_DPAD_CONTROLLER_ID\n MES_BROADCAST_GENERAL_ID = 2000, // MES_BROADCAST_GENERAL_ID\n }\n\n\n declare enum EventBusValue {\n MICROBIT_EVT_ANY = 0, // MICROBIT_EVT_ANY\n MICROBIT_BUTTON_EVT_CLICK = 3, // MICROBIT_BUTTON_EVT_CLICK\n MICROBIT_RADIO_EVT_DATAGRAM = 1, // MICROBIT_RADIO_EVT_DATAGRAM\n MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE = 1, // MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE\n MICROBIT_PIN_EVT_RISE = 2, // MICROBIT_PIN_EVT_RISE\n MICROBIT_PIN_EVT_FALL = 3, // MICROBIT_PIN_EVT_FALL\n MICROBIT_PIN_EVT_PULSE_HI = 4, // MICROBIT_PIN_EVT_PULSE_HI\n MICROBIT_PIN_EVT_PULSE_LO = 5, // MICROBIT_PIN_EVT_PULSE_LO\n MES_ALERT_EVT_ALARM1 = 6, // MES_ALERT_EVT_ALARM1\n MES_ALERT_EVT_ALARM2 = 7, // MES_ALERT_EVT_ALARM2\n MES_ALERT_EVT_ALARM3 = 8, // MES_ALERT_EVT_ALARM3\n MES_ALERT_EVT_ALARM4 = 9, // MES_ALERT_EVT_ALARM4\n MES_ALERT_EVT_ALARM5 = 10, // MES_ALERT_EVT_ALARM5\n MES_ALERT_EVT_ALARM6 = 11, // MES_ALERT_EVT_ALARM6\n MES_ALERT_EVT_DISPLAY_TOAST = 1, // MES_ALERT_EVT_DISPLAY_TOAST\n MES_ALERT_EVT_FIND_MY_PHONE = 5, // MES_ALERT_EVT_FIND_MY_PHONE\n MES_ALERT_EVT_PLAY_RINGTONE = 4, // MES_ALERT_EVT_PLAY_RINGTONE\n MES_ALERT_EVT_PLAY_SOUND = 3, // MES_ALERT_EVT_PLAY_SOUND\n MES_ALERT_EVT_VIBRATE = 2, // MES_ALERT_EVT_VIBRATE\n MES_CAMERA_EVT_LAUNCH_PHOTO_MODE = 1, // MES_CAMERA_EVT_LAUNCH_PHOTO_MODE\n MES_CAMERA_EVT_LAUNCH_VIDEO_MODE = 2, // MES_CAMERA_EVT_LAUNCH_VIDEO_MODE\n MES_CAMERA_EVT_START_VIDEO_CAPTURE = 4, // MES_CAMERA_EVT_START_VIDEO_CAPTURE\n MES_CAMERA_EVT_STOP_PHOTO_MODE = 6, // MES_CAMERA_EVT_STOP_PHOTO_MODE\n MES_CAMERA_EVT_STOP_VIDEO_CAPTURE = 5, // MES_CAMERA_EVT_STOP_VIDEO_CAPTURE\n MES_CAMERA_EVT_STOP_VIDEO_MODE = 7, // MES_CAMERA_EVT_STOP_VIDEO_MODE\n MES_CAMERA_EVT_TAKE_PHOTO = 3, // MES_CAMERA_EVT_TAKE_PHOTO\n MES_CAMERA_EVT_TOGGLE_FRONT_REAR = 8, // MES_CAMERA_EVT_TOGGLE_FRONT_REAR\n MES_DEVICE_DISPLAY_OFF = 5, // MES_DEVICE_DISPLAY_OFF\n MES_DEVICE_DISPLAY_ON = 6, // MES_DEVICE_DISPLAY_ON\n MES_DEVICE_GESTURE_DEVICE_SHAKEN = 4, // MES_DEVICE_GESTURE_DEVICE_SHAKEN\n MES_DEVICE_INCOMING_CALL = 7, // MES_DEVICE_INCOMING_CALL\n MES_DEVICE_INCOMING_MESSAGE = 8, // MES_DEVICE_INCOMING_MESSAGE\n MES_DEVICE_ORIENTATION_LANDSCAPE = 1, // MES_DEVICE_ORIENTATION_LANDSCAPE\n MES_DEVICE_ORIENTATION_PORTRAIT = 2, // MES_DEVICE_ORIENTATION_PORTRAIT\n MES_DPAD_BUTTON_1_DOWN = 9, // MES_DPAD_BUTTON_1_DOWN\n MES_DPAD_BUTTON_1_UP = 10, // MES_DPAD_BUTTON_1_UP\n MES_DPAD_BUTTON_2_DOWN = 11, // MES_DPAD_BUTTON_2_DOWN\n MES_DPAD_BUTTON_2_UP = 12, // MES_DPAD_BUTTON_2_UP\n MES_DPAD_BUTTON_3_DOWN = 13, // MES_DPAD_BUTTON_3_DOWN\n MES_DPAD_BUTTON_3_UP = 14, // MES_DPAD_BUTTON_3_UP\n MES_DPAD_BUTTON_4_DOWN = 15, // MES_DPAD_BUTTON_4_DOWN\n MES_DPAD_BUTTON_4_UP = 16, // MES_DPAD_BUTTON_4_UP\n MES_DPAD_BUTTON_A_DOWN = 1, // MES_DPAD_BUTTON_A_DOWN\n MES_DPAD_BUTTON_A_UP = 2, // MES_DPAD_BUTTON_A_UP\n MES_DPAD_BUTTON_B_DOWN = 3, // MES_DPAD_BUTTON_B_DOWN\n MES_DPAD_BUTTON_B_UP = 4, // MES_DPAD_BUTTON_B_UP\n MES_DPAD_BUTTON_C_DOWN = 5, // MES_DPAD_BUTTON_C_DOWN\n MES_DPAD_BUTTON_C_UP = 6, // MES_DPAD_BUTTON_C_UP\n MES_DPAD_BUTTON_D_DOWN = 7, // MES_DPAD_BUTTON_D_DOWN\n MES_DPAD_BUTTON_D_UP = 8, // MES_DPAD_BUTTON_D_UP\n MES_REMOTE_CONTROL_EVT_FORWARD = 6, // MES_REMOTE_CONTROL_EVT_FORWARD\n MES_REMOTE_CONTROL_EVT_NEXTTRACK = 4, // MES_REMOTE_CONTROL_EVT_NEXTTRACK\n MES_REMOTE_CONTROL_EVT_PAUSE = 2, // MES_REMOTE_CONTROL_EVT_PAUSE\n MES_REMOTE_CONTROL_EVT_PLAY = 1, // MES_REMOTE_CONTROL_EVT_PLAY\n MES_REMOTE_CONTROL_EVT_PREVTRACK = 5, // MES_REMOTE_CONTROL_EVT_PREVTRACK\n MES_REMOTE_CONTROL_EVT_REWIND = 7, // MES_REMOTE_CONTROL_EVT_REWIND\n MES_REMOTE_CONTROL_EVT_STOP = 3, // MES_REMOTE_CONTROL_EVT_STOP\n MES_REMOTE_CONTROL_EVT_VOLUMEDOWN = 9, // MES_REMOTE_CONTROL_EVT_VOLUMEDOWN\n MES_REMOTE_CONTROL_EVT_VOLUMEUP = 8, // MES_REMOTE_CONTROL_EVT_VOLUMEUP\n }\ndeclare namespace control {\n}\n\n\n declare enum DisplayMode {\n //% block=\"black and white\"\n BackAndWhite = 0, // DISPLAY_MODE_BLACK_AND_WHITE\n //% block=\"greyscale\"\n Greyscale = 1, // DISPLAY_MODE_GREYSCALE\n // TODO DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE\n }\ndeclare namespace led {\n}\n\n\n declare enum MotorCommand {\n //% block=coast\n Coast = 0,\n //% block=break\n Break = 1,\n //% block=sleep\n Sleep = 2,\n }\n\n\n declare enum Motor {\n A = 0,\n B = 1,\n //% block=\"A and B\"\n AB = 2,\n }\ndeclare namespace motors {\n}\n\n\n declare enum DigitalPin {\n P0 = 19, // MICROBIT_ID_IO_P12\n P1 = 7, // MICROBIT_ID_IO_P0\n P2 = 8, // MICROBIT_ID_IO_P1\n P3 = 23, // MICROBIT_ID_IO_P16\n C4 = 10, // MICROBIT_ID_IO_P3\n C5 = 11, // MICROBIT_ID_IO_P4\n C6 = 17, // MICROBIT_ID_IO_P10\n C7 = 20, // MICROBIT_ID_IO_P13\n C8 = 21, // MICROBIT_ID_IO_P14\n C9 = 22, // MICROBIT_ID_IO_P15\n C10 = 16, // MICROBIT_ID_IO_P9\n C11 = 14, // MICROBIT_ID_IO_P7\n C12 = 13, // MICROBIT_ID_IO_P6\n C16 = 9, // MICROBIT_ID_IO_P2\n C17 = 15, // MICROBIT_ID_IO_P8\n C18 = 25, // MICROBIT_ID_IO_P20\n C19 = 24, // MICROBIT_ID_IO_P19\n }\n\n\n declare enum AnalogPin {\n P1 = 7, // MICROBIT_ID_IO_P0\n P2 = 8, // MICROBIT_ID_IO_P1\n C4 = 10, // MICROBIT_ID_IO_P3\n C5 = 11, // MICROBIT_ID_IO_P4\n C6 = 17, // MICROBIT_ID_IO_P10\n C16 = 9, // MICROBIT_ID_IO_P2\n C17 = 15, // MICROBIT_ID_IO_P8\n MIC = 50, // MICROBIT_ID_IO_P21\n }\n\n\n declare enum PulseValue {\n High = 4, // MICROBIT_PIN_EVT_PULSE_HI\n Low = 5, // MICROBIT_PIN_EVT_PULSE_LO\n }\n\n\n declare enum PinPullMode {\n //% block=\"down\"\n PullDown = 0,\n //% block=\"up\"\n PullUp = 1,\n //% block=\"none\"\n PullNone = 2,\n }\n\n\n declare enum PinEventType {\n //% block=\"edge\"\n Edge = 1, // MICROBIT_PIN_EVENT_ON_EDGE\n //% block=\"pulse\"\n Pulse = 2, // MICROBIT_PIN_EVENT_ON_PULSE\n //% block=\"touch\"\n Touch = 3, // MICROBIT_PIN_EVENT_ON_TOUCH\n //% block=\"none\"\n None = 0, // MICROBIT_PIN_EVENT_NONE\n }\n\n\n declare enum SerialPin {\n C16 = 9, // MICROBIT_ID_IO_P2\n C17 = 15, // MICROBIT_ID_IO_P8\n P0 = 19, // MICROBIT_ID_IO_P12\n P1 = 7, // MICROBIT_ID_IO_P0\n P2 = 8, // MICROBIT_ID_IO_P1\n P3 = 23, // MICROBIT_ID_IO_P16\n }\n\n\n declare enum BaudRate {\n //% block=115200\n BaudRate115200 = 115200,\n //% block=57600\n BaudRate56700 = 57600,\n //% block=9600\n BaudRate9600 = 9600,\n }\n\n\n declare enum Delimiters {\n //% block=\"new line\"\n NewLine = 1,\n //% block=\",\"\n Comma = 2,\n //% block=\"$\"\n Dollar = 3,\n //% block=\":\"\n Colon = 4,\n //% block=\".\"\n Fullstop = 5,\n //% block=\"#\"\n Hash = 6,\n }\ndeclare namespace serial {\n}\n\n\n declare enum NumberFormat {\n Int8LE = 1,\n UInt8LE = 2,\n Int16LE = 3,\n UInt16LE = 4,\n Int32LE = 5,\n Int8BE = 6,\n UInt8BE = 7,\n Int16BE = 8,\n UInt16BE = 9,\n Int32BE = 10,\n // UInt32,\n }\n\n// Auto-generated. Do not edit. Really.\n",
"game.ts": "enum Direction {\n //% block=right\n Right,\n //% block=left\n Left\n}\n\nenum LedSpriteProperty {\n //% block=x\n X,\n //% block=y\n Y,\n //% block=direction\n Direction,\n //% block=brightness\n Brightness,\n //% block=blink\n Blink\n}\n\n/**\n * A single-LED sprite game engine\n */\n//% color=#008272 weight=32 icon=\"\\uf11b\"\n//% advanced=true\nnamespace game {\n let _score: number = 0;\n let _life: number = 3;\n let _startTime: number = 0;\n let _endTime: number = 0;\n let _isGameOver: boolean = false;\n let _countdownPause: number = 0;\n let _level: number = 1;\n let _gameId: number = 0;\n let img: Image;\n let sprites: LedSprite[];\n\n /**\n * Creates a new LED sprite pointing to the right.\n * @param x sprite horizontal coordinate, eg: 2\n * @param y sprite vertical coordinate, eg: 2\n */\n //% weight=60\n //% blockId=game_create_sprite block=\"create sprite at|x: %x|y: %y\"\n //% parts=\"ledmatrix\"\n export function createSprite(x: number, y: number): LedSprite {\n init();\n let p = new LedSprite(x, y);\n sprites.push(p);\n plot();\n return p;\n }\n\n /**\n * Gets the current score\n */\n //% weight=9 help=game/score\n //% blockId=game_score block=\"score\" blockGap=8\n export function score(): number {\n return _score;\n }\n\n /**\n * Adds points to the current score\n * @param points amount of points to change, eg: 1\n */\n //% weight=10 help=game/add-score\n //% blockId=game_add_score block=\"change score by|%points\" blockGap=8\n //% parts=\"ledmatrix\"\n export function addScore(points: number): void {\n setScore(_score + points);\n control.inBackground(() => {\n led.stopAnimation();\n basic.showAnimation(`0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0\n0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0\n0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0\n0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0`, 20);\n });\n }\n\n /**\n * Starts a game countdown timer\n * @param ms countdown duration in milliseconds, eg: 10000\n */\n //% weight=9 help=game/start-countdown\n //% blockId=game_start_countdown block=\"start countdown|(ms) %duration\" blockGap=8\n //% parts=\"ledmatrix\"\n export function startCountdown(ms: number): void {\n if (checkStart()) {\n basic.showAnimation(`1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0\n0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0\n1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0\n0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0\n1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0`, 400);\n _countdownPause = Math.max(500, ms);\n _startTime = -1;\n _endTime = input.runningTime() + _countdownPause;\n control.inBackground(() => {\n basic.pause(_countdownPause);\n gameOver();\n });\n }\n }\n\n /**\n * Displays a game over animation.\n */\n //% weight=8 help=game/game-over\n //% blockId=game_game_over block=\"game over\"\n //% parts=\"ledmatrix\"\n export function gameOver(): void {\n if (!_isGameOver) {\n _isGameOver = true;\n unplugEvents();\n led.stopAnimation();\n led.setBrightness(255);\n led.setDisplayMode(DisplayMode.BackAndWhite);\n while (true) {\n for (let i = 0; i < 8; i++) {\n basic.clearScreen();\n basic.pause(100);\n basic.showLeds(`1 1 1 1 1\n1 1 1 1 1\n1 1 1 1 1\n1 1 1 1 1\n1 1 1 1 1`, 300);\n }\n basic.showAnimation(`1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0\n1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n1 1 0 1 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0`, 100);\n for (let j = 0; j < 3; j++) {\n basic.showString(\" GAMEOVER \", 100);\n showScore();\n }\n }\n } else {\n // already in game over mode in another fiber\n while (true) {\n basic.pause(10000);\n }\n }\n }\n\n /**\n * Sets the current score value\n * @param value TODO\n */\n //% weight=10 help=game/set-score\n export function setScore(value: number): void {\n _score = Math.max(0, value);\n }\n\n /**\n * Gets the current life\n */\n //% weight=10\n export function life(): number {\n return _life;\n }\n\n /**\n * Sets the current life value\n * @param value TODO\n */\n //% weight=10\n export function setLife(value: number): void {\n _life = Math.max(0, value);\n if (_life <= 0) {\n gameOver();\n }\n }\n\n /**\n * Adds life points to the current life\n * @param lives TODO\n */\n //% weight=10\n export function addLife(lives: number): void {\n setLife(_life + lives);\n }\n\n /**\n * Gets the remaining time (since `start countdown`) or current time (since the device started or `start stopwatch`) in milliseconds.\n */\n //% weight=10\n export function currentTime(): number {\n if (_endTime > 0) {\n return Math.max(0, _endTime - input.runningTime());\n } else {\n return input.runningTime() - _startTime;\n }\n }\n\n /**\n * Removes some life\n * @param life TODO\n */\n //% weight=10\n //% parts=\"ledmatrix\"\n export function removeLife(life: number): void {\n setLife(_life - life);\n control.inBackground(() => {\n led.stopAnimation();\n basic.showAnimation(`1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0\n0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0\n0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0\n0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0\n1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0`, 40);\n });\n }\n\n /**\n * Increments the level and display a message.\n */\n //% weight=10\n //% parts=\"ledmatrix\"\n export function levelUp(): void {\n _level = _level + 1;\n basic.showString(\"LEVEL:\", 150);\n basic.showNumber(_level, 150);\n }\n\n /**\n * Gets the current level\n */\n //% weight=10\n export function level(): number {\n return _level;\n }\n\n /**\n * Starts a stopwatch timer. `current time` will return the elapsed time.\n */\n //% weight=10\n export function startStopwatch(): void {\n _startTime = input.runningTime();\n _endTime = -1;\n }\n\n /**\n * Gets a value indicating if the game is still running. Returns `false` if game over.\n */\n //% weight=10\n export function isRunning(): boolean {\n let running: boolean;\n return !_isGameOver;\n }\n\n /**\n * Displays the score on the screen.\n */\n //% weight=60\n //% parts=\"ledmatrix\"\n export function showScore(): void {\n basic.showString(\" SCORE \", 100);\n basic.showNumber(_score, 150);\n basic.showString(\" \", 150);\n }\n\n /**\n * Indicates if the game is display the game over sequence.\n */\n export function isGameOver(): boolean {\n let over: boolean;\n return _isGameOver;\n }\n\n /**\n * returns false if game can't start\n */\n function checkStart(): boolean {\n if (_countdownPause > 0 || _startTime > 0) {\n return false;\n } else {\n return true;\n }\n }\n\n function unplugEvents(): void {\n input.onButtonPressed(Button.A, () => { });\n input.onButtonPressed(Button.B, () => { });\n input.onButtonPressed(Button.AB, () => {\n control.reset();\n });\n }\n\n export class LedSprite {\n private _x: number;\n private _y: number;\n private _dir: number;\n private _brightness: number;\n private _blink: number;\n\n constructor(x: number, y: number) {\n this._x = Math.clamp(0, 4, x);\n this._y = Math.clamp(0, 4, y);\n this._dir = 90;\n this._brightness = 255;\n init();\n sprites.push(this);\n plot();\n }\n\n /**\n * Move a certain number of LEDs\n * @param this the sprite to move\n * @param leds number of leds to move, eg: 1, -1\n */\n //% weight=50\n //% blockId=game_move_sprite block=\"%sprite|move by %leds\" blockGap=8\n //% parts=\"ledmatrix\"\n public move(leds: number): void {\n if (this._dir == 0) {\n this._y = this._y - leds;\n } else if (this._dir == 45) {\n this._x = this._x + leds;\n this._y = this._y - leds;\n } else if (this._dir == 90) {\n this._x = this._x + leds;\n } else if (this._dir == 135) {\n this._x = this._x + leds;\n this._y = this._y + leds;\n } else if (this._dir == 180) {\n this._y = this._y + leds;\n } else if (this._dir == -45) {\n this._x = this._x - leds;\n this._y = this._y - leds;\n } else if (this._dir == -90) {\n this._x = this._x - leds;\n } else {\n this._x = this._x - leds;\n this._y = this._y + leds;\n }\n this._x = Math.clamp(0, 4, this._x);\n this._y = Math.clamp(0, 4, this._y);\n plot();\n }\n\n /**\n * Go to this position on the screen\n * @param this TODO\n * @param x TODO\n * @param y TODO\n */\n //% parts=\"ledmatrix\"\n public goTo(x: number, y: number): void {\n this._x = x;\n this._y = y;\n this._x = Math.clamp(0, 4, this._x);\n this._y = Math.clamp(0, 4, this._y);\n plot();\n }\n\n /**\n * If touching the edge of the stage, then bounce away.\n * @param this TODO\n */\n //% weight=18\n //% blockId=game_sprite_bounce block=\"%sprite|if on edge, bounce\"\n //% parts=\"ledmatrix\"\n public ifOnEdgeBounce(): void {\n if (this._dir == 0 && this._y == 0) {\n this._dir = 180;\n } else if (this._dir == 45 && (this._x == 4 || this._y == 0)) {\n if (this._x == 0 && this._y == 0) {\n this._dir = -135;\n } else if (this._y == 0) {\n this._dir = 135;\n } else {\n this._dir = -45;\n }\n } else if (this._dir == 90 && this._x == 4) {\n this._dir = -90;\n } else if (this._dir == 135 && (this._x == 4 || this._y == 4)) {\n if (this.x() == 4 && this.y() == 4) {\n this._dir = -45;\n } else if (this._y == 4) {\n this._dir = 45;\n } else {\n this._dir = -135;\n }\n } else if (this._dir == 180 && this._y == 4) {\n this._dir = 0;\n } else if (this._dir == -45 && (this._x == 0 || this._y == 0)) {\n if (this.x() == 0 && this.y() == 0) {\n this._dir = 135;\n } else if (this._y == 0) {\n this._dir = -135;\n } else {\n this._dir = 45;\n }\n } else if (this._dir == -90 && this._x == 0) {\n this._dir = 90;\n } else if (this._dir == -135 && (this._x == 0 || this._y == 4)) {\n if (this._x == 0 && this._y == 4) {\n this._dir = 45;\n } else if (this._y == 4) {\n this._dir = -45;\n } else {\n this._dir = 135;\n }\n }\n plot();\n }\n\n /**\n * Turn the sprite\n * @param this TODO\n * @param direction left or right\n * @param degrees angle in degrees to turn, eg: 45, 90, 180, 135\n */\n //% weight=49\n //% blockId=game_turn_sprite block=\"%sprite|turn %direction|by (°) %degrees\"\n public turn(direction: Direction, degrees: number) {\n if (direction == Direction.Right)\n this.setDirection(this._dir + degrees);\n else\n this.setDirection(this._dir - degrees);\n }\n\n /**\n * Turn to the right (clockwise)\n * @param this TODO\n * @param degrees TODO\n */\n public turnRight(degrees: number): void {\n this.turn(Direction.Right, degrees);\n }\n\n /**\n * Turn to the left (counter-clockwise)\n * @param this TODO\n * @param degrees TODO\n */\n public turnLeft(degrees: number): void {\n this.turn(Direction.Left, degrees);\n }\n\n /**\n * Sets a property of the sprite\n * @param property the name of the property to change\n * @param the updated value\n */\n //% weight=29\n //% blockId=game_sprite_set_property block=\"%sprite|set %property|to %value\" blockGap=8\n public set(property: LedSpriteProperty, value: number) {\n switch (property) {\n case LedSpriteProperty.X: this.setX(value); break;\n case LedSpriteProperty.Y: this.setY(value); break;\n case LedSpriteProperty.Direction: this.setDirection(value); break;\n case LedSpriteProperty.Brightness: this.setBrightness(value); break;\n case LedSpriteProperty.Blink: this.setBlink(value); break;\n }\n }\n\n /**\n * Changes a property of the sprite\n * @param property the name of the property to change\n * @param value amount of change, eg: 1\n */\n //% weight=30\n //% blockId=game_sprite_change_xy block=\"%sprite|change %property|by %value\" blockGap=8\n public change(property: LedSpriteProperty, value: number) {\n switch (property) {\n case LedSpriteProperty.X: this.changeXBy(value); break;\n case LedSpriteProperty.Y: this.changeYBy(value); break;\n case LedSpriteProperty.Direction: this.changeDirectionBy(value); break;\n case LedSpriteProperty.Brightness: this.changeBrightnessBy(value); break;\n case LedSpriteProperty.Blink: this.changeBlinkBy(value); break;\n }\n }\n\n /**\n * Gets a property of the sprite\n * @param property the name of the property to change\n */\n //% weight=28\n //% blockId=game_sprite_property block=\"%sprite|%property\"\n public get(property: LedSpriteProperty) {\n switch (property) {\n case LedSpriteProperty.X: return this.x();\n case LedSpriteProperty.Y: return this.y();\n case LedSpriteProperty.Direction: return this.direction()\n case LedSpriteProperty.Brightness: return this.brightness();\n case LedSpriteProperty.Blink: return this.blink();\n default: return 0;\n }\n }\n\n /**\n * Set the direction of the current sprite, rounded to the nearest multiple of 45\n * @param this TODO\n * @param degrees TODO\n */\n //% parts=\"ledmatrix\"\n public setDirection(degrees: number): void {\n this._dir = ((degrees / 45) % 8) * 45;\n if (this._dir <= -180) {\n this._dir = this._dir + 360;\n } else if (this._dir > 180) {\n this._dir = this._dir - 360;\n }\n plot();\n }\n\n /**\n * Reports the ``x`` position of a sprite on the LED screen\n * @param this TODO\n */\n public x(): number {\n return this._x;\n }\n\n /**\n * Reports the ``y`` position of a sprite on the LED screen\n * @param this TODO\n */\n public y(): number {\n return this._y;\n }\n\n /**\n * Reports the current direction of a sprite\n * @param this TODO\n */\n public direction(): number {\n return this._dir;\n }\n\n /**\n * Set the ``x`` position of a sprite\n * @param this TODO\n * @param x TODO\n */\n public setX(x: number): void {\n this.goTo(x, this._y);\n }\n\n /**\n * Set the ``y`` position of a sprite\n * @param this TODO\n * @param y TODO\n */\n public setY(y: number): void {\n this.goTo(this._x, y);\n }\n\n /**\n * Changes the ``y`` position by the given amount\n * @param this TODO\n * @param y TODO\n */\n public changeYBy(y: number): void {\n this.goTo(this._x, this._y + y);\n }\n\n /**\n * Changes the ``x`` position by the given amount\n * @param this TODO\n * @param x TODO\n */\n public changeXBy(x: number): void {\n this.goTo(this._x + x, this._y);\n }\n\n /**\n * Reports true if sprite is touching specified sprite\n * @param this TODO\n * @param other TODO\n */\n //% weight=20\n //% blockId=game_sprite_touching_sprite block=\"%sprite|touching %other|?\" blockGap=8\n public isTouching(other: LedSprite): boolean {\n return this._x == other._x && this._y == other._y;\n }\n\n /**\n * Reports true if sprite is touching an edge\n * @param this TODO\n */\n //% weight=19\n //% blockId=game_sprite_touching_edge block=\"%sprite|touching edge?\" blockGap=8\n public isTouchingEdge(): boolean {\n return this._x == 0 || this._x == 4 || this._y == 0 || this._y == 4;\n }\n\n /**\n * Turns on the sprite (on by default)\n * @param this TODO\n */\n public on(): void {\n this.setBrightness(255);\n }\n\n /**\n * Turns off the sprite (on by default)\n * @param this TODO\n */\n public off(): void {\n this.setBrightness(0);\n }\n\n /**\n * Set the ``brightness`` of a sprite\n * @param this TODO\n * @param brightness TODO\n */\n //% parts=\"ledmatrix\"\n public setBrightness(brightness: number): void {\n this._brightness = Math.clamp(0, 255, brightness);\n plot();\n }\n\n /**\n * Reports the ``brightness` of a sprite on the LED screen\n * @param this TODO\n */\n public brightness(): number {\n let r: number;\n return this._brightness;\n }\n\n /**\n * Changes the ``y`` position by the given amount\n * @param this TODO\n * @param value TODO\n */\n public changeBrightnessBy(value: number): void {\n this.setBrightness(this._brightness + value);\n }\n\n /**\n * Changes the ``direction`` position by the given amount by turning right\n * @param this TODO\n * @param angle TODO\n */\n public changeDirectionBy(angle: number): void {\n this.turnRight(angle);\n }\n\n /**\n * Deletes the sprite from the game engine. All further operation of the sprite will not have any effect.\n * @param sprite TODO\n */\n public delete(sprite: LedSprite): void {\n sprites.removeElement(sprite);\n }\n\n /**\n * Sets the blink duration interval in millisecond.\n * @param sprite TODO\n * @param ms TODO\n */\n public setBlink(ms: number): void {\n this._blink = Math.clamp(0, 10000, ms);\n }\n\n /**\n * Changes the ``blink`` duration by the given amount of millisecons\n * @param this TODO\n * @param ms TODO\n */\n public changeBlinkBy(ms: number): void {\n this.setBlink(this._blink + ms);\n }\n\n /**\n * Reports the ``blink`` duration of a sprite\n * @param this TODO\n */\n public blink(): number {\n let r: number;\n return this._blink;\n }\n\n //% weight=-1\n //% parts=\"ledmatrix\"\n public _plot(now: number) {\n let ps = this\n if (ps._brightness > 0) {\n let r = 0;\n if (ps._blink > 0) {\n r = (now / ps._blink) % 2;\n }\n if (r == 0) {\n img.setPixelBrightness(ps._x, ps._y, img.pixelBrightness(ps._x, ps._y) + ps._brightness);\n }\n }\n }\n }\n\n function init(): void {\n if (img == null) {\n img = images.createImage(\n `0 0 0 0 0\n0 0 0 0 0\n0 0 0 0 0\n0 0 0 0 0\n0 0 0 0 0`);\n sprites = (<LedSprite[]>[]);\n led.setDisplayMode(DisplayMode.Greyscale);\n basic.forever(() => {\n basic.pause(30);\n plot();\n if (game.isGameOver()) {\n basic.pause(600);\n }\n });\n }\n }\n\n /**\n * Plots the current sprites on the screen\n */\n //% parts=\"ledmatrix\"\n function plot(): void {\n if (game.isGameOver()) {\n return;\n }\n let now = input.runningTime();\n img.clear();\n for (let i = 0; i < sprites.length; i++) {\n sprites[i]._plot(now);\n }\n img.plotImage(0);\n }\n\n /**\n * Gets an invalid sprite; used to initialize locals.\n */\n //% weight=0\n export function invalidSprite(): LedSprite {\n return null;\n }\n\n}\n\n",
"helpers.ts": "namespace console {\n export function log(msg: string) {\n serial.writeString(msg);\n serial.writeString(\"\\r\\n\");\n }\n}\n\nnamespace Math {\n /**\n * Generates a `true` or `false` value randomly, just like flipping a coin.\n */\n //% blockId=logic_random block=\"pick random true or false\"\n //% help=math/random-boolean color=230\n export function randomBoolean(): boolean {\n return Math.random(2) == 0;\n }\n}",
"icons.ts": "/*\nThe MIT License (MIT)\n\nCopyright (c) 2013-2016 The MicroPython-on-micro:bit Developers, as listed\nin the accompanying AUTHORS file\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n*/\n\n// Images from file microbitconstimage.cpp https://github.com/bbcmicrobit/micropython\n\nenum IconNames {\n //% block=\"heart\"\n Heart = 0,\n //% block=\"small heart\"\n SmallHeart,\n //% block=\"yes\"\n Yes,\n //% block=\"no\"\n No,\n //% block=\"happy\"\n Happy,\n //% block=\"sad\"\n Sad,\n //% block=\"confused\"\n Confused,\n //% block=\"angry\"\n Angry,\n //% block=\"asleep\"\n Asleep,\n //% block=\"surprised\"\n Surprised,\n //% block=\"silly\"\n Silly,\n //% block=\"fabulous\"\n Fabulous,\n //% block=\"meh\"\n Meh,\n //% block=\"t-shirt\"\n TShirt,\n //% block=\"roller skate\"\n Rollerskate,\n //% block=\"duck\"\n Duck,\n //% block=\"house\"\n House,\n //% block=\"tortoise\"\n Tortoise,\n //% block=\"butterfly\"\n Butterfly,\n //% block=\"stick figure\"\n StickFigure,\n //% block=\"ghost\"\n Ghost,\n //% block=\"sword\"\n Sword,\n //% block=\"giraffe\"\n Giraffe,\n //% block=\"skull\"\n Skull,\n //% block=\"umbrella\"\n Umbrella,\n //% block=\"snake\"\n Snake,\n //% block=\"rabbit\"\n Rabbit,\n //% block=\"cow\"\n Cow,\n //% block=\"quarter note\"\n QuarterNote,\n //% block=\"eigth note\"\n EigthNote,\n //% block=\"pitchfork\"\n Pitchfork,\n //% block=\"pac man\"\n Pacman,\n //% block=\"target\"\n Target,\n //% block=\"triangle\"\n Triangle,\n //% block=\"left triangle\"\n LeftTriangle,\n //% block=\"chess board\"\n Chessboard,\n //% block=\"diamond\"\n Diamond,\n //% block=\"small diamond\"\n SmallDiamond,\n //% block=\"square\"\n Square,\n //% block=\"small square\"\n SmallSquare, \n}\n\nenum ArrowNames {\n //% blockIdentity=images.arrowNumber\n North = 0,\n //% blockIdentity=images.arrowNumber\n NorthEast,\n //% blockIdentity=images.arrowNumber\n East,\n //% blockIdentity=images.arrowNumber\n SouthEast,\n //% blockIdentity=images.arrowNumber\n South,\n //% blockIdentity=images.arrowNumber \n SouthWest,\n //% blockIdentity=images.arrowNumber\n West,\n //% blockIdentity=images.arrowNumber\n NorthWest,\n}\n\nnamespace basic {\n\n /**\n * Draws the selected icon on the LED screen\n */\n //% weight=90 blockGap=8\n //% blockId=basic_show_icon \n //% block=\"show icon %i\" icon=\"\\uf00a\"\n //% parts=\"ledmatrix\"\n //% help=basic/show-icon\n export function showIcon(icon: IconNames) {\n let res = images.iconImage(icon)\n res.showImage(0)\n }\n\n //% weight=50 blockGap=8\n //% blockId=basic_show_arrow \n //% block=\"show arrow %i=device_arrow\"\n //% parts=\"ledmatrix\"\n //% advanced=true\n //% help=basic/show-arrow\n export function showArrow(i: number) {\n let res = images.arrowImage(i)\n res.showImage(0)\n }\n}\n\n\nnamespace images {\n\n function getArrow(i : ArrowNames): string {\n switch(i) {\n // compass directions\n case ArrowNames.North: return ` \n . . # . .\n . # # # .\n # . # . #\n . . # . .\n . . # . .`;\n case ArrowNames.NorthEast: return ` \n . . # # #\n . . . # #\n . . # . #\n . # . . .\n # . . . .`;\n case ArrowNames.East: return ` \n . . # . .\n . . . # .\n # # # # #\n . . . # .\n . . # . .`;\n case ArrowNames.SouthEast: return ` \n # . . . .\n . # . . .\n . . # . #\n . . . # #\n . . # # #`;\n case ArrowNames.South: return ` \n . . # . .\n . . # . .\n # . # . #\n . # # # .\n . . # . .`;\n case ArrowNames.SouthWest: return ` \n . . . . #\n . . . # .\n # . # . .\n # # . . .\n # # # . .`;\n case ArrowNames.West: return ` \n . . # . .\n . # . . .\n # # # # #\n . # . . .\n . . # . .`;\n case ArrowNames.NorthWest: return ` \n # # # . .\n # # . . .\n # . # . .\n . . . # .\n . . . . #`;\n default: return `\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n `;\n }\n }\n \n function getIcon(i: IconNames): string {\n\n switch (i) {\n case IconNames.Heart : return `\n . # . # .\n # # # # #\n # # # # #\n . # # # .\n . . # . .`;\n\n case IconNames.SmallHeart : return `\n . . . . .\n . # . # .\n . # # # .\n . . # . .\n . . . . .`;\n //faces\n case IconNames.Happy: return `\n . . . . .\n . # . # .\n . . . . .\n # . . . #\n . # # # .`;\n case IconNames.Sad: return `\n . . . . .\n . # . # .\n . . . . .\n . # # # .\n # . . . #`;\n case IconNames.Confused: return `\n . . . . .\n . # . # .\n . . . . .\n . # . # .\n # . # . #`;\n case IconNames.Angry: return `\n # . . . #\n . # . # .\n . . . . .\n # # # # #\n # . # . #`;\n case IconNames.Asleep: return `\n . . . . .\n # # . # #\n . . . . .\n . # # # .\n . . . . .`;\n case IconNames.Surprised: return `\n . # . # .\n . . . . .\n . . # . .\n . # . # .\n . . # . .`;\n case IconNames.Silly: return `\n # . . . #\n . . . . .\n # # # # #\n . . . # #\n . . . # #`;\n case IconNames.Fabulous: return `\n # # # # #\n # # . # #\n . . . . .\n . # . # .\n . # # # .`;\n case IconNames.Meh: return `\n # # . # #\n . . . . .\n . . . # .\n . . # . .\n . # . . .`;\n case IconNames.Yes: return `\n . . . . .\n . . . . #\n . . . # .\n # . # . .\n . # . . .`;\n case IconNames.No: return `\n # . . . #\n . # . # .\n . . # . .\n . # . # .\n # . . . #`;\n case IconNames.Triangle: return `\n . . . . .\n . . # . .\n . # . # .\n # # # # #\n . . . . .`;\n case IconNames.LeftTriangle: return `\n # . . . .\n # # . . .\n # . # . .\n # . . # .\n # # # # #`;\n case IconNames.Chessboard: return `\n . # . # .\n # . # . #\n . # . # .\n # . # . #\n . # . # .`;\n case IconNames.Diamond: return `\n . . # . .\n . # . # .\n # . . . #\n . # . # .\n . . # . .`;\n case IconNames.SmallDiamond: return `\n . . . . .\n . . # . .\n . # . # .\n . . # . .\n . . . . .`;\n case IconNames.Square: return `\n # # # # #\n # . . . #\n # . . . #\n # . . . #\n # # # # #`;\n case IconNames.SmallSquare: return `\n . . . . .\n . # # # .\n . # . # .\n . # # # .\n . . . . .`;\n // The following images were designed by Abbie Brooks.\n case IconNames.TShirt: return `\n # # . # #\n # # # # #\n . # # # .\n . # # # .\n . # # # .`;\n case IconNames.Rollerskate: return `\n . . . # #\n . . . # #\n # # # # #\n # # # # #\n . # . # .`;\n case IconNames.Duck: return `\n . # # . .\n # # # . .\n . # # # #\n . # # # .\n . .. . .`;\n case IconNames.House: return `\n . . # . .\n . # # # .\n # # # # #\n . # # # .\n . # . # .`;\n case IconNames.Tortoise: return `\n . . . . .\n . # # # .\n # # # # #\n . # . # .\n . . . . .`;\n case IconNames.Butterfly: return `\n # # . # #\n # # # # #\n . . # . .\n # # # # #\n # # . # #`;\n case IconNames.StickFigure: return `\n . . # . .\n # # # # #\n . . # . .\n . # . # .\n # . . . #`;\n case IconNames.Ghost: return `\n . # # # .\n # . # . #\n # # # # #\n # # # # #\n # . # . #`;\n case IconNames.Sword: return `\n . . # . .\n . . # . .\n . . # . .\n . # # # .\n . . # . .`;\n case IconNames.Giraffe: return `\n # # . . .\n . # . . .\n . # . . .\n . # # # .\n . # . # .`;\n case IconNames.Skull: return `\n . # # # .\n # . # . #\n # # # # #\n . # # # .\n . # # # .`;\n case IconNames.Umbrella: return `\n . # # # .\n # # # # #\n . . # . .\n # . # . .\n # # # . .`;\n case IconNames.Snake: return `\n # # . . .\n # # . # #\n . # . # .\n . # # # .\n . . . . .`;\n // animals \n case IconNames.Rabbit: return `\n # . # . .\n # . # . .\n # # # # .\n # # . # .\n # # # # .`;\n case IconNames.Cow: return `\n # . . . #\n # . . . #\n # # # # #\n . # # # .\n . . # . .`;\n // musical notes\n case IconNames.QuarterNote: return `\n . . # . .\n . . # . .\n . . # . .\n # # # . .\n # # # . .`;\n case IconNames.EigthNote: return `\n . . # . .\n . . # # .\n . . # . #\n # # # . .\n # # # . .`;\n // other icons\n case IconNames.Pitchfork: return `\n # . # . #\n # . # . #\n # # # # #\n . . # . .\n . . # . .`;\n case IconNames.Pacman: return `\n . # # # #\n # # # # .\n # # # . .\n # # # # .\n . # # # #`;\n case IconNames.Target: return `\n . . # . .\n . # # # .\n # # . # #\n . # # # .\n . . # . .`;\n default: return `\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n `;\n }\n }\n\n //% weight=50 blockGap=8\n //% blockId=device_arrow block=\"%arrow\"\n //% shim=TD_ID\n export function arrowNumber(arrow: ArrowNames): number {\n return arrow;\n }\n\n //% weight=50 blockGap=8\n //% blockId=builtin_arrow_image block=\"arrow image %i=device_arrow\"\n export function arrowImage(i: ArrowNames): Image {\n let res = images.createImage(`\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n `)\n return set(res, getArrow(i));\n }\n\n //% weight=50 blockGap=8\n //% blockId=builtin_image block=\"icon image %i\"\n export function iconImage(i: IconNames): Image {\n let res = images.createImage(`\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n `)\n return set(res, getIcon(i));\n }\n\n function set(res: Image, s: string) {\n let j = 0;\n for (let x of s) {\n if (x == \".\" || x == \"#\") {\n res.setPixel(j % 5, j / 5, x == \"#\")\n j++\n }\n }\n return res\n }\n}\n",
"images.cpp": "#include \"pxt.h\"\n\n/**\n* Creation, manipulation and display of LED images.\n*/\n//% color=#5C2D91 weight=31 icon=\"\\uf03e\"\n//% advanced=true\nnamespace images {\n /**\n * Creates an image that fits on the LED screen.\n */\n //% weight=75 help=images/create-image\n //% blockId=device_build_image block=\"create image\"\n //% parts=\"ledmatrix\"\n Image createImage(ImageLiteral leds) {\n return MicroBitImage(imageBytes(leds)).clone().leakData();\n }\n\n /**\n * Creates an image with 2 frames.\n */\n //% weight=74 help=images/create-big-image\n //% blockId=device_build_big_image block=\"create big image\" imageLiteral=2\n //% parts=\"ledmatrix\"\n Image createBigImage(ImageLiteral leds) {\n return createImage(leds);\n }\n}\n\nnamespace ImageMethods {\n /**\n * Plots the image at a given column to the screen\n */\n //% help=images/plot-image\n //% parts=\"ledmatrix\"\n void plotImage(Image i, int xOffset = 0) {\n uBit.display.print(MicroBitImage(i), -xOffset, 0, 0, 0);\n }\n\n /**\n * Shows an frame from the image at offset ``x offset``.\n * @param xOffset column index to start displaying the image\n */\n //% help=images/show-image weight=80 blockNamespace=images\n //% blockId=device_show_image_offset block=\"show image %sprite|at offset %offset\" blockGap=8\n //% parts=\"ledmatrix\" async\n void showImage(Image sprite, int xOffset, int interval = 400) {\n uBit.display.print(MicroBitImage(sprite), -xOffset, 0, 0, interval);\n }\n\n /**\n * Draws the ``index``-th frame of the image on the screen.\n * @param xOffset column index to start displaying the image\n */\n //% help=images/plot-frame weight=80\n //% parts=\"ledmatrix\"\n void plotFrame(Image i, int xOffset) {\n // TODO showImage() used in original implementation\n plotImage(i, xOffset * 5);\n }\n\n /**\n * Scrolls an image .\n * @param frameOffset x offset moved on each animation step, eg: 1, 2, 5\n * @param interval time between each animation step in milli seconds, eg: 200\n */\n //% help=images/show-image weight=79 async blockNamespace=images\n //% blockId=device_scroll_image block=\"scroll image %sprite|with offset %frameoffset|and interval (ms) %delay\" blockGap=8\n //% parts=\"ledmatrix\"\n void scrollImage(Image id, int frameOffset, int interval) {\n MicroBitImage i(id);\n uBit.display.animate(i, interval, frameOffset, MICROBIT_DISPLAY_WIDTH - 1);\n }\n\n\n /**\n * Sets all pixels off.\n */\n //% help=images/clear\n //% parts=\"ledmatrix\"\n void clear(Image i) {\n MicroBitImage(i).clear();\n }\n\n /**\n * Sets a specific pixel brightness at a given position\n */\n //%\n //% parts=\"ledmatrix\"\n void setPixelBrightness(Image i, int x, int y, int value) {\n MicroBitImage(i).setPixelValue(x, y, value);\n }\n\n\n /**\n * Gets the pixel brightness ([0..255]) at a given position\n */\n //%\n //% parts=\"ledmatrix\"\n int pixelBrightness(Image i, int x, int y) {\n int pix = MicroBitImage(i).getPixelValue(x, y);\n if (pix < 0) return 0;\n return pix;\n }\n\n\n /**\n * Gets the width in columns\n */\n //% help=functions/width\n int width(Image i) {\n return i->width;\n }\n\n /**\n * Gets the height in rows (always 5)\n */\n //%\n int height(Image i) {\n return i->height;\n }\n\n /**\n * Set a pixel state at position ``(x,y)``\n * @param x TODO\n * @param y TODO\n * @param value TODO\n */\n //% help=images/set-pixel\n //% parts=\"ledmatrix\"\n void setPixel(Image i, int x, int y, bool value) {\n setPixelBrightness(i, x, y, value ? 255 : 0);\n }\n\n /**\n * Get the pixel state at position ``(x,y)``\n * @param x TODO\n * @param y TODO\n */\n //% help=images/pixel\n //% parts=\"ledmatrix\"\n bool pixel(Image i, int x, int y) {\n return pixelBrightness(i, x, y) > 0;\n }\n\n\n /**\n * Shows a particular frame of the image strip.\n * @param frame TODO\n */\n //% weight=70 help=images/show-frame\n //% parts=\"ledmatrix\"\n void showFrame(Image i, int frame, int interval = 400) {\n showImage(i, frame * 5, interval);\n }\n}\n",
"input.cpp": "#include \"pxt.h\"\n\nenum class Button {\n A = MICROBIT_ID_BUTTON_A,\n B = MICROBIT_ID_BUTTON_B,\n //% block=\"A+B\"\n AB = MICROBIT_ID_BUTTON_AB,\n};\n\nenum class Dimension {\n //% block=x\n X = 0,\n //% block=y\n Y = 1,\n //% block=z\n Z = 2,\n //% block=strength\n Strength = 3,\n};\n\nenum class Rotation {\n //% block=pitch\n Pitch = 0,\n //% block=roll\n Roll = 1,\n};\n\nenum class TouchPin {\n P0 = MICROBIT_ID_IO_P12,\n P1 = MICROBIT_ID_IO_P0,\n P2 = MICROBIT_ID_IO_P1,\n P3 = MICROBIT_ID_IO_P16\n};\n\nenum class AcceleratorRange {\n /**\n * The accelerator measures forces up to 1 gravity\n */\n //% block=\"1g\"\n OneG = 1,\n /**\n * The accelerator measures forces up to 2 gravity\n */\n //% block=\"2g\"\n TwoG = 2,\n /**\n * The accelerator measures forces up to 4 gravity\n */\n //% block=\"4g\"\n FourG = 4,\n /**\n * The accelerator measures forces up to 8 gravity\n */\n //% block=\"8g\"\n EightG = 8\n};\n\nenum class Gesture {\n /**\n * Raised when shaken\n */\n //% block=shake\n Shake = MICROBIT_ACCELEROMETER_EVT_SHAKE,\n /**\n * Raised when the logo is upward and the screen is vertical\n */\n //% block=\"logo up\"\n LogoUp = MICROBIT_ACCELEROMETER_EVT_TILT_UP,\n /**\n * Raised when the logo is downward and the screen is vertical\n */\n //% block=\"logo down\"\n LogoDown = MICROBIT_ACCELEROMETER_EVT_TILT_DOWN,\n /**\n * Raised when the screen is pointing down and the board is horizontal\n */\n //% block=\"screen up\"\n ScreenUp = MICROBIT_ACCELEROMETER_EVT_FACE_UP,\n /**\n * Raised when the screen is pointing up and the board is horizontal\n */\n //% block=\"screen down\"\n ScreenDown = MICROBIT_ACCELEROMETER_EVT_FACE_DOWN,\n /**\n * Raised when the screen is pointing left\n */\n //% block=\"tilt left\"\n TiltLeft = MICROBIT_ACCELEROMETER_EVT_TILT_LEFT,\n /**\n * Raised when the screen is pointing right\n */\n //% block=\"tilt right\"\n TiltRight = MICROBIT_ACCELEROMETER_EVT_TILT_RIGHT,\n /**\n * Raised when the board is falling!\n */\n //% block=\"free fall\"\n FreeFall = MICROBIT_ACCELEROMETER_EVT_FREEFALL,\n /**\n * Raised when a 3G shock is detected\n */\n //% block=\"3g\"\n ThreeG = MICROBIT_ACCELEROMETER_EVT_3G,\n /**\n * Raised when a 6G shock is detected\n */\n //% block=\"6g\"\n SixG = MICROBIT_ACCELEROMETER_EVT_6G\n};\n\n//% color=#C90072 weight=99 icon=\"\\uf192\"\nnamespace input {\n /**\n * Do something when a button (``A``, ``B`` or both ``A+B``) is pressed\n * @param button TODO\n * @param body TODO\n */\n //% help=input/on-button-pressed weight=85 blockGap=8\n //% blockId=device_button_event block=\"on button|%NAME|pressed\"\n //% parts=\"buttonpair\"\n void onButtonPressed(Button button, Action body) {\n registerWithDal((int)button, MICROBIT_BUTTON_EVT_CLICK, body);\n }\n\n /**\n * Do something when when a gesture is done (like shaking the micro:bit).\n * @param body TODO\n */\n //% help=input/on-gesture weight=84 blockGap=8\n //% blockId=device_gesture_event block=\"on |%NAME\"\n //% parts=\"accelerometer\"\n void onGesture(Gesture gesture, Action body) {\n if ((int)gesture == MICROBIT_ACCELEROMETER_EVT_3G && uBit.accelerometer.getRange() < 3)\n uBit.accelerometer.setRange(6);\n else if ((int)gesture == MICROBIT_ACCELEROMETER_EVT_6G && uBit.accelerometer.getRange() < 6)\n uBit.accelerometer.setRange(8);\n registerWithDal(MICROBIT_ID_GESTURE, (int)gesture, body);\n }\n\n /**\n * Do something when a pin is pressed.\n * @param name the pin that needs to be pressed\n * @param body the code to run when the pin is pressed\n */\n //% help=input/on-pin-pressed weight=83\n //% blockId=device_pin_event block=\"on pin %NAME|pressed\"\n void onPinPressed(TouchPin name, Action body) {\n auto pin = getPin((int)name);\n if (!pin) return;\n\n // Forces the PIN to switch to makey-makey style detection.\n pin->isTouched();\n registerWithDal((int)name, MICROBIT_BUTTON_EVT_CLICK, body);\n }\n\n /**\n * Do something when a pin is released.\n * @param name the pin that needs to be released\n * @param body the code to run when the pin is released\n */\n //% help=input/on-pin-released weight=6 blockGap=8\n //% blockId=device_pin_released block=\"on pin %NAME|released\"\n //% advanced=true\n void onPinReleased(TouchPin name, Action body) {\n auto pin = getPin((int)name);\n if (!pin) return;\n\n // Forces the PIN to switch to makey-makey style detection.\n pin->isTouched();\n registerWithDal((int)name, MICROBIT_BUTTON_EVT_UP, body);\n }\n\n /**\n * Get the button state (pressed or not) for ``A`` and ``B``.\n */\n //% help=input/button-is-pressed weight=60\n //% block=\"button|%NAME|is pressed\"\n //% blockId=device_get_button2\n //% blockGap=8\n //% parts=\"buttonpair\"\n bool buttonIsPressed(Button button) {\n if (button == Button::A)\n return uBit.buttonA.isPressed();\n else if (button == Button::B)\n return uBit.buttonB.isPressed();\n else if (button == Button::AB)\n return uBit.buttonAB.isPressed();\n return false;\n }\n\n /**\n * Get the pin state (pressed or not). Requires to hold the ground to close the circuit.\n * @param name pin used to detect the touch\n */\n //% help=input/pin-is-pressed weight=58\n //% blockId=\"device_pin_is_pressed\" block=\"pin %NAME|is pressed\"\n //% blockGap=8\n bool pinIsPressed(TouchPin name) {\n auto pin = getPin((int)name);\n return pin && pin->isTouched();\n }\n\n int getAccelerationStrength() {\n double x = uBit.accelerometer.getX();\n double y = uBit.accelerometer.getY();\n double z = uBit.accelerometer.getZ();\n return (int)sqrt(x*x+y*y+z*z);\n } \n\n /**\n * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up, x=0, y=0 and z=-1024)\n * @param dimension TODO\n */\n //% help=input/acceleration weight=58\n //% blockId=device_acceleration block=\"acceleration (mg)|%NAME\" blockGap=8\n //% parts=\"accelerometer\"\n int acceleration(Dimension dimension) {\n switch (dimension) {\n case Dimension::X: return uBit.accelerometer.getX();\n case Dimension::Y: return uBit.accelerometer.getY();\n case Dimension::Z: return uBit.accelerometer.getZ();\n case Dimension::Strength: return getAccelerationStrength();\n }\n return 0;\n }\n\n /**\n * Reads the light level applied to the LED screen in a range from ``0`` (dark) to ``255`` bright.\n */\n //% help=input/light-level weight=57\n //% blockId=device_get_light_level block=\"light level\" blockGap=8\n //% parts=\"ledmatrix\"\n int lightLevel() {\n return uBit.display.readLightLevel();\n }\n\n /**\n * Get the current compass heading in degrees.\n */\n //% help=input/compass-heading\n //% weight=56\n //% blockId=device_heading block=\"compass heading (°)\" blockGap=8\n //% parts=\"compass\"\n int compassHeading() {\n return uBit.compass.heading();\n }\n\n\n /**\n * Gets the temperature in Celsius degrees (°C).\n */\n //% weight=55\n //% help=input/temperature\n //% blockId=device_temperature block=\"temperature (°C)\" blockGap=8\n //% parts=\"thermometer\"\n int temperature() {\n return uBit.thermometer.getTemperature();\n }\n\n /**\n * The pitch or roll of the device, rotation along the ``x-axis`` or ``y-axis``, in degrees.\n * @param kind TODO\n */\n //% help=input/rotation weight=52\n //% blockId=device_get_rotation block=\"rotation (°)|%NAME\" blockGap=8\n //% parts=\"accelerometer\" advanced=true\n int rotation(Rotation kind) {\n switch (kind) {\n case Rotation::Pitch: return uBit.accelerometer.getPitch();\n case Rotation::Roll: return uBit.accelerometer.getRoll();\n }\n return 0;\n }\n\n /**\n * Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the simulator.\n * @param dimension TODO\n */\n //% help=input/magnetic-force weight=51\n //% blockId=device_get_magnetic_force block=\"magnetic force (µT)|%NAME\" blockGap=8\n //% parts=\"compass\"\n //% advanced=true\n int magneticForce(Dimension dimension) {\n if (!uBit.compass.isCalibrated())\n uBit.compass.calibrate();\n\n switch (dimension) {\n case Dimension::X: return uBit.compass.getX() / 1000;\n case Dimension::Y: return uBit.compass.getY() / 1000;\n case Dimension::Z: return uBit.compass.getZ() / 1000;\n case Dimension::Strength: return uBit.compass.getFieldStrength() / 1000;\n }\n return 0;\n }\n\n /**\n * Gets the number of milliseconds elapsed since power on.\n */\n //% help=input/running-time weight=50\n //% blockId=device_get_running_time block=\"running time (ms)\"\n //% advanced=true\n int runningTime() {\n return system_timer_current_time();\n }\n\n /**\n * Obsolete, compass calibration is automatic.\n */\n //% help=input/calibrate weight=0\n void calibrate() { }\n\n /**\n * Sets the accelerometer sample range in gravities.\n * @param range a value describe the maximum strengh of acceleration measured\n */\n //% help=input/set-accelerometer-range\n //% blockId=device_set_accelerometer_range block=\"set accelerometer|range %range\"\n //% weight=5\n //% parts=\"accelerometer\"\n //% advanced=true\n void setAccelerometerRange(AcceleratorRange range) {\n uBit.accelerometer.setRange((int)range);\n }\n}\n",
"input.ts": "/**\n * Events and data from sensors\n */\n//% color=#C90072 weight=99\nnamespace input {\n /**\n * Attaches code to run when the screen is facing up.\n * @param body TODO\n */\n //% help=input/on-screen-up\n export function onScreenUp(body: Action): void {\n onGesture(Gesture.ScreenUp, body);\n }\n\n /**\n * Attaches code to run when the screen is facing down.\n * @param body TODO\n */\n //% help=input/on-screen-down\n export function onScreenDown(body: Action): void {\n onGesture(Gesture.ScreenDown, body);\n }\n\n /**\n * Attaches code to run when the device is shaken.\n * @param body TODO\n */\n //% help=input/on-shake\n export function onShake(body: Action): void {\n onGesture(Gesture.Shake, body);\n }\n\n /**\n * Attaches code to run when the logo is oriented upwards and the board is vertical.\n * @param body TODO\n */\n //% help=input/on-logo-up\n export function onLogoUp(body: Action): void {\n onGesture(Gesture.LogoUp, body);\n }\n\n /**\n * Attaches code to run when the logo is oriented downwards and the board is vertical.\n * @param body TODO\n */\n //% help=input/on-logo-down\n export function onLogoDown(body: Action): void {\n onGesture(Gesture.LogoDown, body);\n }\n}\n",
"led.cpp": "#include \"pxt.h\"\n\nenum class DisplayMode_ {\n //% block=\"black and white\"\n BackAndWhite = DISPLAY_MODE_BLACK_AND_WHITE,\n //% block=\"greyscale\"\n Greyscale = DISPLAY_MODE_GREYSCALE,\n // TODO DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE\n};\n\n//% color=#8169E6 weight=35 icon=\"\\uf205\"\nnamespace led {\n\n /**\n * Turn on the specified LED using x, y coordinates (x is horizontal, y is vertical). (0,0) is upper left.\n * @param x TODO\n * @param y TODO\n */\n //% help=led/plot weight=78\n //% blockId=device_plot block=\"plot|x %x|y %y\" blockGap=8\n //% parts=\"ledmatrix\"\n void plot(int x, int y) {\n uBit.display.image.setPixelValue(x, y, 1);\n }\n\n /**\n * Turn off the specified LED using x, y coordinates (x is horizontal, y is vertical). (0,0) is upper left.\n * @param x TODO\n * @param y TODO\n */\n //% help=led/unplot weight=77\n //% blockId=device_unplot block=\"unplot|x %x|y %y\" blockGap=8\n //% parts=\"ledmatrix\"\n void unplot(int x, int y) {\n uBit.display.image.setPixelValue(x, y, 0);\n }\n\n /**\n * Get the on/off state of the specified LED using x, y coordinates. (0,0) is upper left.\n * @param x TODO\n * @param y TODO\n */\n //% help=led/point weight=76\n //% blockId=device_point block=\"point|x %x|y %y\"\n //% parts=\"ledmatrix\"\n bool point(int x, int y) {\n int pix = uBit.display.image.getPixelValue(x, y);\n return pix > 0;\n }\n\n /**\n * Get the screen brightness from 0 (off) to 255 (full bright).\n */\n //% help=led/brightness weight=60\n //% blockId=device_get_brightness block=\"brightness\" blockGap=8\n //% parts=\"ledmatrix\"\n //% advanced=true\n int brightness() {\n return uBit.display.getBrightness();\n }\n\n /**\n * Set the screen brightness from 0 (off) to 255 (full bright).\n * @param value the brightness value, eg:255, 127, 0\n */\n //% help=led/set-brightness weight=59\n //% blockId=device_set_brightness block=\"set brightness %value\"\n //% parts=\"ledmatrix\"\n //% advanced=true\n void setBrightness(int value) {\n uBit.display.setBrightness(value);\n }\n\n /**\n * Cancels the current animation and clears other pending animations.\n */\n //% weight=50 help=led/stop-animation\n //% blockId=device_stop_animation block=\"stop animation\"\n //% parts=\"ledmatrix\"\n //% advanced=true\n void stopAnimation() {\n uBit.display.stopAnimation();\n }\n\n /**\n * Sets the display mode between black and white and greyscale for rendering LEDs.\n * @param mode mode the display mode in which the screen operates\n */\n //% weight=1 help=led/set-display-mode\n //% parts=\"ledmatrix\" advanced=true\n void setDisplayMode(DisplayMode_ mode) {\n uBit.display.setDisplayMode((DisplayMode)mode);\n }\n\n /**\n * Turns on or off the display \n */\n //% help=led/enable blockId=device_led_enable\n //% advanced=true parts=\"ledmatrix\"\n void enable(bool on) {\n if (on) uBit.display.enable();\n else uBit.display.disable();\n }\n\n /**\n * Takes a screenshot of the LED screen and returns an image.\n */\n //% help=led/screenshot\n //% parts=\"ledmatrix\"\n Image screenshot() {\n return uBit.display.screenShot().leakData();\n /*\n let Image img;\n img = image.createImage(\"\");\n for (let i = 0; i < 5; i++) {\n for (let j = 0; j < 5; j++) {\n if (led.point(i, j)) {\n img.setPixel(i, j, true);\n }\n }\n }\n return img;\n */\n }\n}\n",
"led.ts": "/**\n * Control of the LED screen.\n */\n//% color=#8169E6 weight=97\n namespace led {\n\n // what's the current high value\n let barGraphHigh = 0;\n // when was the current high value recorded\n let barGraphHighLast = 0;\n\n /**\n * Displays a vertical bar graph based on the `value` and `high` value.\n * If `high` is 0, the chart gets adjusted automatically.\n * @param value current value to plot\n * @param high maximum value. If 0, maximum value adjusted automatically, eg: 0\n */\n //% help=led/plot-bar-graph weight=20\n //% blockId=device_plot_bar_graph block=\"plot bar graph of %value |up to %high\" icon=\"\\uf080\" blockExternalInputs=true\n //% parts=\"ledmatrix\"\n export function plotBarGraph(value: number, high: number): void {\n let now = input.runningTime();\n serial.writeString(value.toString() + \"\\r\\n\");\n value = Math.abs(value);\n\n if (high != 0) barGraphHigh = high;\n else if (value > barGraphHigh || now - barGraphHighLast > 10000) {\n barGraphHigh = value;\n barGraphHighLast = now;\n }\n\n barGraphHigh = Math.max(barGraphHigh, 16);\n\n let v = (value * 15) / barGraphHigh;\n let k = 0;\n for (let y = 4; y >= 0; --y) {\n for (let x = 0; x < 3; ++x) {\n if (k > v) {\n unplot(2 - x, y);\n unplot(2 + x, y);\n } else {\n plot(2 - x, y);\n plot(2 + x, y);\n }\n ++k;\n }\n }\n }\n\n /**\n * Toggles a particular pixel\n * @param x TODO\n * @param y TODO\n */\n //% help=led/toggle weight=77\n //% blockId=device_led_toggle block=\"toggle|x %x|y %y\" icon=\"\\uf204\" blockGap=8\n //% parts=\"ledmatrix\"\n export function toggle(x: number, y: number): void {\n if (led.point(x, y)) {\n led.unplot(x, y);\n } else {\n led.plot(x, y);\n }\n }\n\n /**\n * Turns all LEDS on\n */\n //% help=led/plot-all\n //% parts=\"ledmatrix\"\n export function plotAll(): void {\n for (let i = 0; i < 5; i++) {\n for (let j = 0; j < 5; j++) {\n led.plot(i, j);\n }\n }\n }\n\n /**\n * Inverts the current LED display\n */\n //% help=led/toggle-all\n //% parts=\"ledmatrix\"\n export function toggleAll(): void {\n for (let i = 0; i < 5; i++) {\n for (let j = 0; j < 5; j++) {\n led.toggle(i, j);\n }\n }\n }\n\n /**\n * Fades in the screen display.\n * @param ms TODO\n */\n //% help=led/fade-in\n //% parts=\"ledmatrix\"\n export function fadeIn(ms: number = 700): void {\n if (ms < 20) {\n led.setBrightness(255);\n return;\n }\n let dt = 50;\n let brightness = led.brightness();\n let start = input.runningTime();\n let elapsed = 0;\n while (elapsed < ms) {\n led.setBrightness(brightness + ((255 - brightness) * elapsed) / ms);\n basic.pause(dt);\n elapsed = input.runningTime() - start;\n }\n led.setBrightness(255);\n }\n\n /**\n * Fades out the screen brightness.\n * @param ms TODO\n */\n //% help=led/fade-out\n //% parts=\"ledmatrix\"\n export function fadeOut(ms: number = 700): void {\n if (ms < 20) {\n led.setBrightness(0);\n return;\n }\n let brightness = led.brightness();\n let dt = 50;\n let start = input.runningTime();\n let elapsed = 0;\n while (elapsed < ms) {\n led.setBrightness(brightness - (brightness * elapsed) / ms);\n basic.pause(dt);\n elapsed = input.runningTime() - start;\n }\n led.setBrightness(0);\n }\n\n\n}\n",
"motors.cpp": "#include \"pxt.h\"\n\nenum MotorCommand {\n //% block=coast\n Coast,\n //% block=break\n Break,\n //% block=sleep\n Sleep\n};\n\nenum Motor {\n A,\n B,\n //% block=\"A and B\"\n AB\n};\n\n/**\n* Blocks to control the onboard motors\n*/\n//% color=#008272 weight=30 icon=\"\\uf1b9\"\nnamespace motors {\n /**\n * Turns on the motor at a certain percent of power. Switches to single motor mode!\n * @param power %percent of power sent to the motor. Negative power goes backward. eg: 50\n */\n //% blockId=motor_on block=\"motor on at %percent\"\n //% parts=dcmotor weight=90 blockGap=8\n void motorPower(int power) {\n uBit.soundmotor.motorOn(power);\n }\n\n /**\n * Send break, coast or sleep commands to the motor. Has no effect in dual-motor mode.\n */\n //% blockId=motor_command block=\"motor %command\"\n //% parts=dcmotor weight=85\n void motorCommand(MotorCommand command) {\n switch(command) {\n case MotorCommand::Coast: uBit.soundmotor.motorCoast();break;\n case MotorCommand::Break: uBit.soundmotor.motorBreak();break;\n case MotorCommand::Sleep: uBit.soundmotor.motorSleep();break;\n }\n }\n\n /**\n * Controls two motors attached to the board. Switches to dual-motor mode!\n */\n //% blockId=block_dual_motor block=\"motor %motor|at %percent\"\n //% weight=80\n void dualMotorPower(Motor motor, int duty_percent) {\n switch(motor) {\n case Motor::A: if (duty_percent <= 0) uBit.soundmotor.motorAOff();\n else uBit.soundmotor.motorAOn(duty_percent); break;\n case Motor::B: if (duty_percent <= 0) uBit.soundmotor.motorBOff();\n else uBit.soundmotor.motorBOn(duty_percent); break;\n case Motor::AB: if (duty_percent <= 0) {\n uBit.soundmotor.motorAOff();\n uBit.soundmotor.motorBOff();\n } else {\n uBit.soundmotor.motorAOn(duty_percent);\n uBit.soundmotor.motorBOn(duty_percent);\n }\n break;\n }\n }\n}",
"music.cpp": "#include \"pxt.h\"\n\nnamespace music {\n /**\n * Plays a tone through ``speaker`` for the given duration.\n * @param frequency pitch of the tone to play in Hertz (Hz)\n * @param ms tone duration in milliseconds (ms)\n */\n //% help=music/play-tone weight=90\n //% blockId=device_play_note block=\"play|tone %note=device_note|for %duration=device_beat\" icon=\"\\uf025\" blockGap=8\n //% parts=\"speaker\" async useEnumVal=1\n void playTone(int frequency, int ms) {\n if(frequency > 0) uBit.soundmotor.soundOn(frequency);\n else uBit.soundmotor.soundOff();\n if(ms > 0) {\n uBit.sleep(ms);\n uBit.soundmotor.soundOff();\n }\n\n }\n}\n",
"music.ts": "enum Note {\n //% blockIdentity=music.noteFrequency enumval=262\n C = 262,\n //% block=C#\n //% blockIdentity=music.noteFrequency enumval=277\n CSharp = 277,\n //% blockIdentity=music.noteFrequency enumval=294\n D = 294,\n //% blockIdentity=music.noteFrequency enumval=311\n Eb = 311,\n //% blockIdentity=music.noteFrequency enumval=330\n E = 330,\n //% blockIdentity=music.noteFrequency enumval=349\n F = 349,\n //% block=F#\n //% blockIdentity=music.noteFrequency enumval=370\n FSharp = 370,\n //% blockIdentity=music.noteFrequency enumval=392\n G = 392,\n //% block=G#\n //% blockIdentity=music.noteFrequency enumval=415\n GSharp = 415,\n //% blockIdentity=music.noteFrequency enumval=440\n A = 440,\n //% blockIdentity=music.noteFrequency enumval=466\n Bb = 466,\n //% blockIdentity=music.noteFrequency enumval=494\n B = 494,\n //% blockIdentity=music.noteFrequency enumval=131\n C3 = 131,\n //% block=C#3\n //% blockIdentity=music.noteFrequency enumval=139\n CSharp3 = 139,\n //% blockIdentity=music.noteFrequency enumval=147\n D3 = 147,\n //% blockIdentity=music.noteFrequency enumval=156\n Eb3 = 156,\n //% blockIdentity=music.noteFrequency enumval=165\n E3 = 165,\n //% blockIdentity=music.noteFrequency enumval=175\n F3 = 175,\n //% block=F#3\n //% blockIdentity=music.noteFrequency enumval=185\n FSharp3 = 185,\n //% blockIdentity=music.noteFrequency enumval=196\n G3 = 196,\n //% block=G#3\n //% blockIdentity=music.noteFrequency enumval=208\n GSharp3 = 208,\n //% blockIdentity=music.noteFrequency enumval=220\n A3 = 220,\n //% blockIdentity=music.noteFrequency enumval=233\n Bb3 = 233,\n //% blockIdentity=music.noteFrequency enumval=247\n B3 = 247,\n //% blockIdentity=music.noteFrequency enumval=262\n C4 = 262,\n //% block=C#4\n //% blockIdentity=music.noteFrequency enumval=277\n CSharp4 = 277,\n //% blockIdentity=music.noteFrequency enumval=294\n D4 = 294,\n //% blockIdentity=music.noteFrequency enumval=311\n Eb4 = 311,\n //% blockIdentity=music.noteFrequency enumval=330\n E4 = 330,\n //% blockIdentity=music.noteFrequency enumval=349\n F4 = 349,\n //% block=F#4\n //% blockIdentity=music.noteFrequency enumval=370\n FSharp4 = 370,\n //% blockIdentity=music.noteFrequency enumval=392\n G4 = 392,\n //% block=G#4\n //% blockIdentity=music.noteFrequency enumval=415\n GSharp4 = 415,\n //% blockIdentity=music.noteFrequency enumval=440\n A4 = 440,\n //% blockIdentity=music.noteFrequency enumval=466\n Bb4 = 466,\n //% blockIdentity=music.noteFrequency enumval=494\n B4 = 494,\n //% blockIdentity=music.noteFrequency enumval=523\n C5 = 523,\n //% block=C#5\n //% blockIdentity=music.noteFrequency enumval=555\n CSharp5 = 555,\n //% blockIdentity=music.noteFrequency enumval=587\n D5 = 587,\n //% blockIdentity=music.noteFrequency enumval=622\n Eb5 = 622,\n //% blockIdentity=music.noteFrequency enumval=659\n E5 = 659,\n //% blockIdentity=music.noteFrequency enumval=698\n F5 = 698,\n //% block=F#5\n //% blockIdentity=music.noteFrequency enumval=740\n FSharp5 = 740,\n //% blockIdentity=music.noteFrequency enumval=784\n G5 = 784,\n //% block=G#5\n //% blockIdentity=music.noteFrequency enumval=831\n GSharp5 = 831,\n //% blockIdentity=music.noteFrequency enumval=880\n A5 = 880,\n //% blockIdentity=music.noteFrequency enumval=932\n Bb5 = 932,\n //% blockIdentity=music.noteFrequency enumval=988\n B5 = 988,\n}\n\nenum BeatFraction {\n //% block=1\n Whole = 1,\n //% block=\"1/2\"\n Half = 2,\n //% block=\"1/4\"\n Quarter = 4,\n //% block=\"1/8\"\n Eighth = 8,\n //% block=\"1/16\"\n Sixteenth = 16\n}\n\n/**\n * Generation of music tones through pin ``P0``.\n */\n//% color=#DF4600 weight=98 icon=\"\\uf025\"\nnamespace music {\n let beatsPerMinute: number = 120;\n\n /**\n * Rests (plays nothing) for a specified time through pin ``P0``.\n * @param ms rest duration in milliseconds (ms)\n */\n //% help=music/rest weight=79\n //% blockId=device_rest block=\"rest(ms)|%duration=device_beat\"\n //% parts=\"speaker\"\n export function rest(ms: number): void {\n playTone(0, ms);\n }\n\n /**\n * Plays a tone through ``speaker``.\n * @param frequency pitch of the tone to play in Hertz (Hz)\n */\n //% help=music/ring-tone weight=80\n //% blockId=device_ring block=\"ring tone (Hz)|%note=device_note\" blockGap=8\n //% parts=\"speaker\" async\n //% useEnumVal=1\n export function ringTone(frequency: number) {\n playTone(frequency, 0);\n }\n\n /**\n * Gets the frequency of a note.\n * @param name the note name\n */\n //% weight=50 help=music/note-frequency\n //% blockId=device_note block=\"%note\"\n //% shim=TD_ID blockHidden=true\n //% blockFieldEditor=\"note_editor\"\n //% useEnumVal = 1\n export function noteFrequency(name: Note): number {\n return name;\n }\n\n function init() {\n if (beatsPerMinute <= 0) beatsPerMinute = 120;\n }\n\n /**\n * Returns the duration of a beat in milli-seconds\n */\n //% help=music/beat weight=49\n //% blockId=device_beat block=\"%fraction|beat\"\n export function beat(fraction?: BeatFraction): number {\n init();\n if (fraction == null) fraction = BeatFraction.Whole;\n let beat = 60000 / beatsPerMinute;\n if (fraction == BeatFraction.Whole) return beat;\n else if (fraction == BeatFraction.Half) return beat / 2;\n else if (fraction == BeatFraction.Quarter) return beat / 4;\n else if (fraction == BeatFraction.Eighth) return beat / 8;\n else return beat / 16;\n }\n\n /**\n * Returns the tempo in beats per minute. Tempo is the speed (bpm = beats per minute) at which notes play. The larger the tempo value, the faster the notes will play.\n */\n //% help=music/tempo weight=40\n //% blockId=device_tempo block=\"tempo (bpm)\" blockGap=8\n export function tempo(): number {\n init();\n return beatsPerMinute;\n }\n\n /**\n * Change the tempo by the specified amount\n * @param bpm The change in beats per minute to the tempo, eg: 20\n */\n //% help=music/change-tempo-by weight=39\n //% blockId=device_change_tempo block=\"change tempo by (bpm)|%value\" blockGap=8\n export function changeTempoBy(bpm: number): void {\n init();\n setTempo(beatsPerMinute + bpm);\n }\n\n /**\n * Sets the tempo to the specified amount\n * @param bpm The new tempo in beats per minute, eg: 120\n */\n //% help=music/set-tempo weight=38\n //% blockId=device_set_tempo block=\"set tempo to (bpm)|%value\"\n export function setTempo(bpm: number): void {\n init();\n if (bpm > 0) {\n beatsPerMinute = Math.max(1, bpm);\n }\n }\n}\n",
"parts/dcmotor.svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"488\" height=\"836\" viewBox=\"0 0 488 836\">\n <g transform=\"translate(0 -216.362)\">\n <rect width=\"34.286\" height=\"122.532\" x=\"226.365\" y=\"929.711\" fill=\"#ccc\" ry=\"16.162\"/>\n <path fill=\"gray\" d=\"M23.23 359.456A23.233 23.233 0 0 0 0 382.686v511.428a23.233 23.233 0 0 0 23.23 23.23h38.2v24.117a23.233 23.233 0 0 0 23.23 23.234h317.143a23.233 23.233 0 0 0 23.23-23.23v-24.118h38.197a23.233 23.233 0 0 0 23.23-23.23v-511.43a23.233 23.233 0 0 0-23.23-23.23h-440z\"/>\n <path fill=\"#333\" d=\"M23.23 357.82C10.4 357.82.002 368.22 0 381.05v511.427c.002 12.83 10.4 23.23 23.23 23.23h38.2v24.118c2.08 25.815 20.27 23.748 33.1 23.75 0 0-11.976-16.96-12.05-40.988-.057-17.923-9.03-12.008-8.176-39.76 2.743-237.84-2.423-390.158.37-522.93z\"/>\n <path fill=\"#fd5\" d=\"M23.508 286.934A23.51 18.415 0 0 0 0 305.347v69.375a23.51 18.415 0 0 0 23.508 18.413h440a23.51 18.415 0 0 0 23.508-18.413v-69.375a23.51 18.415 0 0 0-23.508-18.413h-440z\"/>\n <path fill=\"#c87137\" d=\"M77.156 216.362c-5.698 0-10.283 4.588-10.283 10.286v94.03c0 5.7 4.585 10.286 10.283 10.286h24.98c5.697 0 10.284-4.587 10.284-10.285v-94.034c0-5.698-4.587-10.286-10.285-10.286h-24.98zm10.18 10.37h4.018c5.095 0 9.197 4.103 9.197 9.2v28.032c0 5.096-4.1 9.197-9.194 9.197h-4.018c-5.096 0-9.2-4.1-9.2-9.194V235.93c0-5.095 4.104-9.197 9.2-9.197zm288.814-10.37c-5.697 0-10.283 4.588-10.283 10.286v94.03c0 5.7 4.586 10.286 10.283 10.286h24.98c5.697 0 10.284-4.587 10.284-10.285v-94.034c0-5.698-4.587-10.286-10.285-10.286h-24.98zm11.045 11.885h4.02c5.095 0 9.197 4.102 9.197 9.197v28.032c0 5.095-4.102 9.2-9.197 9.2h-4.02c-5.095 0-9.197-4.105-9.197-9.2v-28.032c0-5.095 4.102-9.197 9.197-9.197z\"/>\n <path fill=\"#fc0\" d=\"M170.587 306.637a17.633 17.633 0 0 0-17.63 17.63v67.587a17.633 17.633 0 0 0 17.63 17.63h34.852v20.57c0 15.162 12.756 27.915 27.913 27.915h24.976c15.157 0 27.916-12.756 27.916-27.917v-20.57h38.612a17.633 17.633 0 0 0 17.63-17.63v-67.587a17.633 17.633 0 0 0-17.63-17.63H170.585z\"/>\n <rect width=\"126.356\" height=\"29.385\" x=\"272.569\" y=\"914.707\" fill=\"#b3b3b3\" ry=\"14.693\"/>\n <rect width=\"169.991\" height=\"457.913\" x=\"300.928\" y=\"430.348\" fill=\"#b3b3b3\" ry=\"27.415\"/>\n </g>\n</svg>",
"parts/headphone.svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"142\" height=\"180\" viewBox=\"0 0 142 180\"><rect ry=\".3\" rx=\"1\" y=\"58.615\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><rect ry=\".3\" rx=\"1\" y=\"32.043\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><path d=\"M.346 7.296c-.394.39-.31 4.797-.18 4.898l13.404 10.18c.117.12.337 4.76.73 4.368l5.506-5.56.01.01 6.51-6.444c.39-.392-4.25-.614-4.366-.73L11.777.612c-.1-.132-4.51-.215-4.898.18L4.087 3.636l-.01-.01-3.73 3.67z\" fill=\"#b3b3b3\"/><rect ry=\"6.85\" rx=\"4.571\" y=\"84.758\" x=\"-20.128\" height=\"75.571\" width=\"39.643\" transform=\"rotate(-45)\"/><rect ry=\".374\" rx=\"1.038\" y=\"29.442\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"55.939\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"82.392\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\"2.317\" rx=\"2.183\" y=\"158.876\" x=\"-9.774\" height=\"25.568\" width=\"18.935\" transform=\"rotate(-45)\"/><path d=\"M128.588 128.82s14.97 11.165 7.547 26.35c-8.426 17.24-25.57 20.653-25.57 20.653\" fill=\"none\" stroke=\"#000\" stroke-width=\"6.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>",
"parts/speaker.svg": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<svg viewBox=\"0 0 500 500\" xmlns=\"http://www.w3.org/2000/svg\">\n <g transform=\"matrix(1, 0, 0, 1, -0.00023, -58.230297)\">\n <ellipse style=\"fill: rgb(70, 70, 70);\" cx=\"250.58\" cy=\"308.81\" rx=\"215\" ry=\"215\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" transform=\"matrix(1, 0, 0, 1.000001, -232.069031, 248.780606)\" cx=\"482.069\" cy=\"198.188\" rx=\"23.028\" ry=\"23.028\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" transform=\"matrix(1, 0, 0, 0.999999, -232.067871, 110.041956)\" cx=\"482.067\" cy=\"198.188\" rx=\"23.028\" ry=\"23.028\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" cx=\"389.12\" cy=\"308.23\" rx=\"23.028\" ry=\"23.028\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" cx=\"110.88\" cy=\"308.23\" rx=\"23.028\" ry=\"23.028\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" cx=\"250\" cy=\"169.393\" rx=\"23.028\" ry=\"23.028\"/>\n <g transform=\"matrix(1, 0, 0, 1, -0.000009, 0.000015)\">\n <ellipse style=\"fill: rgb(0, 0, 0);\" cx=\"250\" cy=\"238.513\" rx=\"23.028\" ry=\"23.028\" transform=\"matrix(1.000001, 0, 0, 0.999999, 69.996739, 69.71816)\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" transform=\"matrix(1, 0, 0, 0.999999, -302.064453, 110.043115)\" cx=\"482.064\" cy=\"198.188\" rx=\"23.028\" ry=\"23.028\"/>\n </g>\n <g transform=\"matrix(0.866026, 0.5, -0.5, 0.866026, 7.386552, -105.261086)\">\n <ellipse style=\"fill: rgb(0, 0, 0);\" transform=\"matrix(0.999999, 0, 0, 0.999999, -65.212313, 177.387415)\" cx=\"482.068\" cy=\"198.188\" rx=\"23.028\" ry=\"23.028\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" cx=\"555.975\" cy=\"236.836\" rx=\"23.028\" ry=\"23.028\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" cx=\"277.735\" cy=\"236.836\" rx=\"23.028\" ry=\"23.028\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" cx=\"416.855\" cy=\"97.999\" rx=\"23.028\" ry=\"23.028\"/>\n </g>\n <g transform=\"matrix(0.5, 0.866026, -0.866026, 0.5, 246.635941, -171.170502)\">\n <ellipse style=\"fill: rgb(0, 0, 0);\" transform=\"matrix(0.999999, 0, 0, 0.999999, -65.212313, 177.387415)\" cx=\"482.068\" cy=\"198.188\" rx=\"23.028\" ry=\"23.028\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" cx=\"555.975\" cy=\"236.836\" rx=\"23.028\" ry=\"23.028\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" cx=\"277.735\" cy=\"236.836\" rx=\"23.028\" ry=\"23.028\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" cx=\"416.855\" cy=\"97.999\" rx=\"23.028\" ry=\"23.028\"/>\n </g>\n <g transform=\"matrix(-0.5, 0.866026, -0.866026, -0.5, 641.934998, 245.84082)\">\n <ellipse style=\"fill: rgb(0, 0, 0);\" cx=\"250\" cy=\"238.513\" rx=\"23.028\" ry=\"23.028\" transform=\"matrix(1.000001, 0, 0, 0.999999, 69.996739, 69.71816)\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" transform=\"matrix(1, 0, 0, 0.999999, -302.064453, 110.043115)\" cx=\"482.064\" cy=\"198.188\" rx=\"23.028\" ry=\"23.028\"/>\n </g>\n <g transform=\"matrix(-0.500001, -0.866026, 0.866026, -0.500001, 108.063393, 678.85083)\">\n <ellipse style=\"fill: rgb(0, 0, 0);\" cx=\"250\" cy=\"238.513\" rx=\"23.028\" ry=\"23.028\" transform=\"matrix(1.000001, 0, 0, 0.999999, 69.996739, 69.71816)\"/>\n <ellipse style=\"fill: rgb(0, 0, 0);\" transform=\"matrix(1, 0, 0, 0.999999, -302.064453, 110.043115)\" cx=\"482.064\" cy=\"198.188\" rx=\"23.028\" ry=\"23.028\"/>\n </g>\n </g>\n</svg>",
"pins.cpp": "#include \"pxt.h\"\n\nenum class DigitalPin {\n P0 = MICROBIT_ID_IO_P12, // edge connector 0\n P1 = MICROBIT_ID_IO_P0, // edge connector 1\n P2 = MICROBIT_ID_IO_P1, // edge connector 2\n P3 = MICROBIT_ID_IO_P16, // edge connector 3\n C4 = MICROBIT_ID_IO_P3, // LED matrix C1\n C5 = MICROBIT_ID_IO_P4, // LED matrix C2\n C6 = MICROBIT_ID_IO_P10, // LED matrix C3\n C7 = MICROBIT_ID_IO_P13, // LED matrix C4\n C8 = MICROBIT_ID_IO_P14, // LED matrix C5\n C9 = MICROBIT_ID_IO_P15, // LED matrix C6\n C10 = MICROBIT_ID_IO_P9, // LED matrix C7\n C11 = MICROBIT_ID_IO_P7, // LED matrix C8\n C12 = MICROBIT_ID_IO_P6, // LED matrix C9\n C16 = MICROBIT_ID_IO_P2, // RX\n C17 = MICROBIT_ID_IO_P8, // TX\n C18 = MICROBIT_ID_IO_P20, // SDA\n C19 = MICROBIT_ID_IO_P19 // SCL\n};\n\nenum class AnalogPin {\n P1 = MICROBIT_ID_IO_P0, // edge connector 1\n P2 = MICROBIT_ID_IO_P1, // edge connector 2\n C4 = MICROBIT_ID_IO_P3, // LED matrix C1\n C5 = MICROBIT_ID_IO_P4, // LED matrix C2\n C6 = MICROBIT_ID_IO_P10, // LED matrix C3\n C16 = MICROBIT_ID_IO_P2, // RX\n C17 = MICROBIT_ID_IO_P8, // TX\n MIC = MICROBIT_ID_IO_P21 // microphone\n};\n\nenum class PulseValue {\n High = MICROBIT_PIN_EVT_PULSE_HI,\n Low = MICROBIT_PIN_EVT_PULSE_LO\n};\n\nenum class PinPullMode {\n //% block=\"down\"\n PullDown = 0,\n //% block=\"up\"\n PullUp = 1,\n //% block=\"none\"\n PullNone = 2\n};\n\nenum class PinEventType {\n //% block=\"edge\"\n Edge = MICROBIT_PIN_EVENT_ON_EDGE,\n //% block=\"pulse\"\n Pulse = MICROBIT_PIN_EVENT_ON_PULSE,\n //% block=\"touch\"\n Touch = MICROBIT_PIN_EVENT_ON_TOUCH,\n //% block=\"none\"\n None = MICROBIT_PIN_EVENT_NONE\n};\n\nMicroBitPin *getPin(int id) {\n switch (id) {\n case MICROBIT_ID_IO_P0: return &uBit.io.P0;\n case MICROBIT_ID_IO_P1: return &uBit.io.P1;\n case MICROBIT_ID_IO_P2: return &uBit.io.P2;\n case MICROBIT_ID_IO_P3: return &uBit.io.P3;\n case MICROBIT_ID_IO_P4: return &uBit.io.P4;\n case MICROBIT_ID_IO_P5: return &uBit.io.P5;\n case MICROBIT_ID_IO_P6: return &uBit.io.P6;\n case MICROBIT_ID_IO_P7: return &uBit.io.P7;\n case MICROBIT_ID_IO_P8: return &uBit.io.P8;\n case MICROBIT_ID_IO_P9: return &uBit.io.P9;\n case MICROBIT_ID_IO_P10: return &uBit.io.P10;\n case MICROBIT_ID_IO_P11: return &uBit.io.P11;\n case MICROBIT_ID_IO_P12: return &uBit.io.P12;\n case MICROBIT_ID_IO_P13: return &uBit.io.P13;\n case MICROBIT_ID_IO_P14: return &uBit.io.P14;\n case MICROBIT_ID_IO_P15: return &uBit.io.P15;\n case MICROBIT_ID_IO_P16: return &uBit.io.P16;\n case MICROBIT_ID_IO_P19: return &uBit.io.P19;\n case MICROBIT_ID_IO_P20: return &uBit.io.P20;\n case MICROBIT_ID_IO_P21: return &uBit.io.P21;\n default: return NULL;\n }\n}\n\n\nnamespace pins {\n #define PINOP(op) \\\n MicroBitPin *pin = getPin((int)name); \\\n if (!pin) return; \\\n pin->op\n\n #define PINREAD(op) \\\n MicroBitPin *pin = getPin((int)name); \\\n if (!pin) return 0; \\\n return pin->op\n\n\n //%\n MicroBitPin *getPinAddress(int id) {\n return getPin(id);\n }\n\n /**\n * Read the specified pin or connector as either 0 or 1\n * @param name pin to read from\n */\n //% help=pins/digital-read-pin weight=30\n //% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n int digitalReadPin(DigitalPin name) {\n PINREAD(getDigitalValue());\n }\n\n /**\n * Set a pin or connector value to either 0 or 1.\n * @param name pin to write to\n * @param value value to set on the pin, 1 eg,0\n */\n //% help=pins/digital-write-pin weight=29\n //% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value\"\n void digitalWritePin(DigitalPin name, int value) {\n PINOP(setDigitalValue(value));\n }\n\n /**\n * Read the connector value as analog, that is, as a value comprised between 0 and 1023.\n * @param name pin to write to\n */\n //% help=pins/analog-read-pin weight=25\n //% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n int analogReadPin(AnalogPin name) {\n PINREAD(getAnalogValue());\n }\n\n /**\n * Set the connector value as analog. Value must be comprised between 0 and 1023.\n * @param name pin name to write to\n * @param value value to write to the pin between ``0`` and ``1023``. eg:1023,0\n */\n //% help=pins/analog-write-pin weight=24\n //% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n void analogWritePin(AnalogPin name, int value) {\n PINOP(setAnalogValue(value));\n }\n\n /**\n * Configures the Pulse-width modulation (PWM) of the analog output to the given value in **microseconds** or `1/1000` milliseconds.\n * If this pin is not configured as an analog output (using `analog write pin`), the operation has no effect.\n * @param name analog pin to set period to\n * @param micros period in micro seconds. eg:20000\n */\n //% help=pins/analog-set-period weight=23 blockGap=8\n //% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%micros\"\n void analogSetPeriod(AnalogPin name, int micros) {\n PINOP(setAnalogPeriodUs(micros));\n }\n\n /**\n * Configures this pin to a digital input, and generates events where the timestamp is the duration that this pin was either ``high`` or ``low``.\n */\n //% help=pins/on-pulsed weight=22 blockGap=8\n //% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n void onPulsed(DigitalPin name, PulseValue pulse, Action body) {\n MicroBitPin* pin = getPin((int)name);\n if (!pin) return;\n\n pin->eventOn(MICROBIT_PIN_EVENT_ON_PULSE);\n registerWithDal((int)name, (int)pulse, body);\n }\n\n /**\n * Gets the duration of the last pulse in micro-seconds. This function should be called from a ``onPulsed`` handler.\n */\n //% help=pins/pulse-duration\n //% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n //% weight=21 blockGap=8\n int pulseDuration() {\n return pxt::lastEvent.timestamp;\n }\n\n /**\n * Returns the duration of a pulse in microseconds\n * @param name the pin which measures the pulse\n * @param value the value of the pulse (default high)\n * @param maximum duration in micro-seconds\n */\n //% blockId=\"pins_pulse_in\" block=\"pulse in (µs)|pin %name|pulsed %value\"\n //% weight=20\n int pulseIn(DigitalPin name, PulseValue value, int maxDuration = 2000000) {\n MicroBitPin* pin = getPin((int)name);\n if (!pin) return 0;\n\n int pulse = value == PulseValue::High ? 1 : 0;\n uint64_t tick = system_timer_current_time_us();\n uint64_t maxd = (uint64_t)maxDuration;\n while(pin->getDigitalValue() != pulse) {\n if(system_timer_current_time_us() - tick > maxd)\n return 0;\n }\n\n uint64_t start = system_timer_current_time_us();\n while(pin->getDigitalValue() == pulse) {\n if(system_timer_current_time_us() - tick > maxd)\n return 0;\n }\n uint64_t end = system_timer_current_time_us();\n return end - start;\n }\n\n /**\n * Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one direction, ``180`` being full speed in the other, and a value near ``90`` being no movement).\n * @param name pin to write to\n * @param value angle or rotation speed, eg:180,90,0\n */\n //% help=pins/servo-write-pin weight=20\n //% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value\" blockGap=8\n //% parts=microservo trackArgs=0\n void servoWritePin(AnalogPin name, int value) {\n PINOP(setServoValue(value));\n }\n\n /**\n * Configures this IO pin as an analog/pwm output, configures the period to be 20 ms, and sets the pulse width, based on the value it is given **microseconds** or `1/1000` milliseconds.\n * @param name pin name\n * @param micros pulse duration in micro seconds, eg:1500\n */\n //% help=pins/servo-set-pulse weight=19\n //% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %micros\"\n void servoSetPulse(AnalogPin name, int micros) {\n PINOP(setServoPulseUs(micros));\n }\n\n\n MicroBitPin* pitchPin = NULL;\n\n /**\n * Sets the pin used when using `pins->analog pitch`.\n * @param name TODO\n */\n //% blockId=device_analog_set_pitch_pin block=\"analog set pitch pin %name\"\n //% help=pins/analog-set-pitch weight=3 advanced=true\n void analogSetPitchPin(AnalogPin name) {\n pitchPin = getPin((int)name);\n }\n\n /**\n * Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin.\n * @param frequency TODO\n * @param ms TODO\n */\n //% blockId=device_analog_pitch block=\"analog pitch %frequency|for (ms) %ms\"\n //% help=pins/analog-pitch weight=4 async advanced=true blockGap=8\n void analogPitch(int frequency, int ms) {\n if (pitchPin == NULL)\n analogSetPitchPin(AnalogPin::P1);\n if (frequency <= 0) {\n pitchPin->setAnalogValue(0);\n } else {\n pitchPin->setAnalogValue(512);\n pitchPin->setAnalogPeriodUs(1000000/frequency);\n }\n\n if (ms > 0) {\n fiber_sleep(ms);\n pitchPin->setAnalogValue(0);\n // TODO why do we use wait_ms() here? it's a busy wait I think\n wait_ms(5);\n }\n }\n\n\n /**\n * Configures the pull of this pin.\n * @param name pin to set the pull mode on\n * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone \n */\n //% help=pins/set-pull weight=3\n //% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n void setPull(DigitalPin name, PinPullMode pull) {\n PinMode m = pull == PinPullMode::PullDown\n ? PinMode::PullDown\n : pull == PinPullMode::PullUp ? PinMode::PullUp\n : PinMode::PullNone;\n PINOP(setPull(m));\n }\n\n /**\n * Configures the events emitted by this pin. Events can be subscribed to\n * using ``control.onEvent()``.\n * @param name pin to set the event mode on, eg: DigitalPin.P0\n * @param type the type of events for this pin to emit, eg: PinEventType.Edge\n */\n //% help=pins/set-events weight=4 advanced=true\n //% blockId=device_set_pin_events block=\"set pin %pin|to emit %type|events\"\n void setEvents(DigitalPin name, PinEventType type) {\n getPin((int)name)->eventOn((int)type);\n }\n\n /**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n //%\n Buffer createBuffer(int size)\n {\n return ManagedBuffer(size).leakData();\n }\n\n /**\n * Read `size` bytes from a 7-bit I2C `address`.\n */\n //%\n Buffer i2cReadBuffer(int address, int size, bool repeat = false)\n {\n Buffer buf = createBuffer(size);\n uBit.i2c.read(address << 1, (char*)buf->payload, size, repeat);\n return buf;\n }\n\n /**\n * Write bytes to a 7-bit I2C `address`.\n */\n //%\n void i2cWriteBuffer(int address, Buffer buf, bool repeat = false)\n {\n uBit.i2c.write(address << 1, (char*)buf->payload, buf->length, repeat);\n }\n\n SPI* spi = NULL;\n SPI* allocSPI() {\n if (spi == NULL)\n spi = new SPI(MOSI, MISO, SCK);\n return spi;\n }\n\n /**\n * Write to the SPI slave and return the response\n * @param value Data to be sent to the SPI slave\n */\n //% help=pins/spi-write weight=5\n //% blockId=spi_write block=\"spi write %value\"\n int spiWrite(int value) {\n auto p = allocSPI();\n return p->write(value);\n }\n\n}\n",
"pins.ts": "/**\n * Control currents in Pins for analog/digital signals, servos, i2c, ...\n */\n//% color=#A80000 weight=30 icon=\"\\uf140\"\n//% advanced=true\nnamespace pins {\n /**\n * Re-maps a number from one range to another. That is, a value of ``from low`` would get mapped to ``to low``, a value of ``from high`` to ``to high``, values in-between to values in-between, etc.\n * @param value value to map in ranges\n * @param fromLow the lower bound of the value's current range\n * @param fromHigh the upper bound of the value's current range, eg: 1023\n * @param toLow the lower bound of the value's target range\n * @param toHigh the upper bound of the value's target range, eg: 4\n */\n //% help=pins/map weight=23\n //% blockId=math_map block=\"map %value|from low %fromLow|from high %fromHigh|to low %toLow|to high %toHigh\"\n export function map(value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number): number {\n return ((value - fromLow) * (toHigh - toLow)) / (fromHigh - fromLow) + toLow;\n }\n\n /**\n * Read one number from 7-bit I2C address.\n */\n //% help=pins/i2c-read-number blockGap=8\n //% blockId=pins_i2c_readnumber block=\"i2c read number|at address %address|of format %format=i2c_sizeof|repeat %repeat\" weight=7\n export function i2cReadNumber(address: number, format: NumberFormat, repeat?: boolean): number {\n let buf = pins.i2cReadBuffer(address, pins.sizeOf(format), repeat)\n return buf.getNumber(format, 0)\n }\n\n /**\n * Write one number to a 7-bit I2C address.\n */\n //% help=pins/i2c-write-number blockGap=8\n //% blockId=i2c_writenumber block=\"i2c write number|at address %address|with value %value|of format %format=i2c_sizeof|repeat %repeat\" weight=6\n export function i2cWriteNumber(address: number, value: number, format: NumberFormat, repeat?: boolean): void {\n let buf = createBuffer(pins.sizeOf(format))\n buf.setNumber(format, 0, value)\n pins.i2cWriteBuffer(address, buf, repeat)\n }\n\n /**\n * Get the size in bytes of specified number format.\n */\n //%\n export function sizeOf(format: NumberFormat) {\n switch (format) {\n case NumberFormat.Int8LE:\n case NumberFormat.UInt8LE:\n case NumberFormat.Int8BE:\n case NumberFormat.UInt8BE:\n return 1;\n case NumberFormat.Int16LE:\n case NumberFormat.UInt16LE:\n case NumberFormat.Int16BE:\n case NumberFormat.UInt16BE:\n return 2;\n case NumberFormat.Int32LE:\n case NumberFormat.Int32BE:\n return 4;\n }\n return 0;\n }\n}\n\n\ninterface Buffer {\n [index: number]: number;\n // rest defined in buffer.cpp\n}\n",
"pxt-core.d.ts": "/// <reference no-default-lib=\"true\"/>\n\ninterface Array<T> {\n /**\n * Gets or sets the length of the array. This is a number one higher than the highest element defined in an array.\n */\n //% shim=Array_::length weight=84\n //% blockId=\"lists_length\" block=\"length of %VALUE\" blockBuiltin=true blockNamespace=\"lists\"\n length: number;\n\n /**\n * Appends new elements to an array.\n * @param items New elements of the Array.\n */\n //% shim=Array_::push weight=75\n //% blockId=\"array_push\" block=\"push into %this|with last item %item\" blockNamespace=\"lists\"\n push(item: T): void;\n\n /**\n * Removes the last element from an array and returns it.\n */\n //% shim=Array_::pop weight=74\n //% blockId=\"array_pop\" block=\"pop last item from %this\" blockNamespace=\"lists\"\n pop(): T;\n\n /**\n * Reverses the elements in an Array. The first array element becomes the last, and the last array element becomes the first.\n */\n //% helper=arrayReverse weight=10\n //% blockId=\"array_reverse\" block=\"reverse %this\" blockNamespace=\"lists\"\n reverse(): void;\n\n /**\n * Removes the first element from an array and returns that element. This method changes the length of the array.\n */\n //% helper=arrayShift weight=70\n //% blockId=\"array_shift\" block=\"shift first item from %this\" blockNamespace=\"lists\"\n shift(): T;\n\n /**\n * Adds one element to the beginning of an array and returns the new length of the array.\n * @param element to insert at the start of the Array.\n */\n //% helper=arrayUnshift weight=69\n //% blockId=\"array_unshift\" block=\"unshift into %this|with first item %item\" blockNamespace=\"lists\"\n //unshift(...values:T[]): number; //rest is not supported in our compiler yet.\n unshift(value:T): number;\n\n /**\n * Returns a section of an array.\n * @param start The beginning of the specified portion of the array. eg: 0\n * @param end The end of the specified portion of the array. eg: 0\n */\n //% helper=arraySlice weight=41\n //% blockId=\"array_slice\" block=\"slice %this|from %start|to %end\" blockNamespace=\"lists\"\n slice(start: number, end: number): T[];\n\n /**\n * Removes elements from an array.\n * @param start The zero-based location in the array from which to start removing elements. eg: 0\n * @param deleteCount The number of elements to remove. eg: 0\n */\n //% helper=arraySplice weight=40\n splice(start: number, deleteCount: number): void;\n\n /**\n * Sorts the elements of an array in place and returns the array. The sort is not necessarily stable.\n * @param specifies a function that defines the sort order. If omitted, the array is sorted according to the prmitive type\n */\n //% helper=arraySort weight=40\n sort(callbackfn?: (value1: T, value2: T) => number): T[];\n\n /**\n * Calls a defined callback function on each element of an array, and returns an array that contains the results.\n * @param callbackfn A function that accepts up to two arguments. The map method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayMap weight=40\n map<U>(callbackfn: (value: T, index: number) => U): U[];\n\n /**\n * Returns the elements of an array that meet the condition specified in a callback function.\n * @param callbackfn A function that accepts up to two arguments. The filter method calls the callbackfn function one time for each element in the array.\n */\n //% helper=arrayFilter weight=40\n filter(callbackfn: (value: T, index: number) => boolean): T[];\n\n /**\n * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\n * @param callbackfn A function that accepts up to three arguments. The reduce method calls the callbackfn function one time for each element in the array.\n * @param initialValue Initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\n */\n //% helper=arrayReduce weight=40\n reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U;\n\n\n /** Removes the first occurence of an object. Returns true if removed. */\n //% shim=Array_::removeElement weight=48\n removeElement(element:T) : boolean;\n\n /** Removes the object at position index. */\n //% shim=Array_::removeAt weight=49\n //% blockId=\"array_removeat\" block=\"remove from %this|at %index\" blockNamespace=\"lists\"\n removeAt(index:number) : T;\n\n /**\n * Insert the value at a particular index, increases length by 1\n * @param index the zero-based position in the list to insert the value, eg: 0\n * @param the value to insert, eg: 0\n */\n //% shim=Array_::insertAt weight=84\n //% blockId=\"array_insertAt\" block=\"insert in %this|at %index|with value %value\" blockNamespace=\"lists\"\n insertAt(index:number, value: T) : void;\n\n /**\n * Returns the index of the first occurrence of a value in an array.\n * @param item The value to locate in the array.\n * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.\n */\n //% shim=Array_::indexOf weight=50\n //% blockId=\"array_indexof\" block=\"index in %this|of %item\" blockNamespace=\"lists\"\n indexOf(item: T, fromIndex?: number): number;\n\n /**\n * Gets the value at a particular index\n * @param index the zero-based position in the list of the item, eg: 0\n */\n //% shim=Array_::getAt weight=85\n //% blockId=\"array_get\" block=\"get from %this|at %index\" blockNamespace=\"lists\"\n get(index: number): T;\n\n /**\n * Stores the value at a particular index\n * @param index the zero-based position in the list to store the value, eg: 0\n * @param the value to insert, eg: 0\n */\n //% shim=Array_::setAt weight=84\n //% blockId=\"array_set\" block=\"set in %this|at %index|with value %value\" blockNamespace=\"lists\"\n set(index: number, value : T) : void;\n\n [n: number]: T;\n}\n\ndeclare interface String {\n // This block is currently disabled in favor of the built-in Blockly \"Create text with\" block, which compiles to \"\" + \"\"\n // Add % sign back to the block annotation to re-enable\n /**\n * Returns a string that contains the concatenation of two or more strings.\n * @param other The string to append to the end of the string.\n */\n //% shim=String_::concat weight=80\n //% blockId=\"string_concat\" blockNamespace=\"text\"\n // block=\"join %this=text|%other\"\n concat(other: string): string;\n\n /**\n * Returns the character at the specified index.\n * @param index The zero-based index of the desired character.\n */\n //% shim=String_::charAt weight=77\n //% blockId=\"string_get\" block=\"char from %this=text|at %pos\" blockNamespace=\"text\"\n charAt(index: number): string;\n\n /** Returns the length of a String object. */\n //% property shim=String_::length weight=75\n //% blockId=\"text_length\" block=\"length of %VALUE\" blockBuiltin=true blockNamespace=\"text\"\n length: number;\n\n /**\n * Returns the Unicode value of the character at the specified location.\n * @param index The zero-based index of the desired character. If there is no character at the specified index, NaN is returned.\n */\n //% shim=String_::charCodeAt\n charCodeAt(index: number): number;\n\n /**\n * Determines whether relative order of two strings (in ASCII encoding).\n * @param that String to compare to target string\n */\n //% shim=String_::compare\n //% blockId=\"string_compare\" block=\"compare %this=text| to %that\" blockNamespace=\"text\"\n compare(that: string): number;\n\n /**\n * Return substring of the current string.\n * @param start first character index; can be negative from counting from the end, eg:0\n * @param length number of characters to extract\n */\n //% shim=String_::substr length.defl=1000000\n //% blockId=\"string_substr\" block=\"substring of %this=text|from %start|of length %length\" blockNamespace=\"text\"\n substr(start:number, length?:number): string;\n\n // This block is currently disabled, as it does not compile in some targets\n // Add % sign back to the block annotation to re-enable\n /** Returns a value indicating if the string is empty */\n //% shim=String_::isEmpty\n //% blockId=\"string_isempty\" blockNamespace=\"text\"\n // block=\"%this=text| is empty\"\n isEmpty() : boolean;\n\n [index: number]: string;\n}\n\n/**\n * Converts A string to an integer.\n * @param s A string to convert into a number.\n */\n//% shim=String_::toNumber\n//% blockId=\"string_parseint\" block=\"parse to integer %text\" blockNamespace=\"text\"\ndeclare function parseInt(text: string): number;\n\ninterface Object {}\ninterface Function {}\ninterface IArguments {}\ninterface RegExp {}\n\ntype uint8 = number;\ntype uint16 = number;\n//type uint32 = number;\ntype int8 = number;\ntype int16 = number;\ntype int32 = number;\n\n\ndeclare interface Boolean {\n /**\n * Returns a string representation of an object.\n */\n //% shim=Boolean_::toString\n toString(): string;\n}\n\ndeclare namespace String {\n\n /**\n * Make a string from the given ASCII character code.\n */\n //% help=math/string-from-char-code\n //% shim=String_::fromCharCode\n //% advanced=true\n //% blockNamespace=\"Math\" blockId=\"stringFromCharCode\" block=\"text from char code %code\" weight=1\n function fromCharCode(code: number): string;\n}\n\n\ndeclare interface Number {\n /**\n * Returns a string representation of a number.\n */\n //% shim=Number_::toString\n toString(): string;\n}\n\ndeclare namespace Math {\n\n /**\n * Returns the value of a base expression taken to a specified power.\n * @param x The base value of the expression.\n * @param y The exponent value of the expression.\n */\n //% shim=Math_::pow\n function pow(x: number, y: number): number;\n\n /**\n * Returns a pseudorandom number between 0 and `max`.\n */\n //% shim=Math_::random\n function random(max: number): number;\n\n /**\n * Returns the square root of a number.\n * @param x A numeric expression.\n */\n //% shim=Math_::sqrt\n function sqrt(x: number): number;\n}\n",
"pxt-helpers.ts": "type Action = () => void;\n\nnamespace helpers {\n export function arraySplice<T>(arr: T[], start: number, len: number) {\n if (start < 0) {\n return;\n }\n for (let i = 0; i < len; ++i) {\n arr.removeAt(start)\n }\n }\n \n export function arrayReverse<T>(arr: T[]) : void {\n let len = arr.length;\n for (let i = 0; i < len/2; i++)\n {\n swap(arr, i, len - i - 1);\n }\n }\n\n export function arrayShift<T>(arr: T[]) : T {\n return arr.removeAt(0);\n }\n\n/*TODO: Enable this multiple value unshift, after rest is enabled in our compiler.\n export function arrayUnshift<T>(arr: T[], ...values: T[]) : number {\n for(let i = values.length; i > 0; --i) {\n arr.insertAt(0, values[i - 1]);\n }\n return arr.length;\n } \n*/\n export function arrayUnshift<T>(arr: T[], value: T) : number {\n arr.insertAt(0, value);\n return arr.length;\n }\n\n function swap<T>(arr: T[], i : number, j: number) : void {\n let temp : T = arr[i];\n arr[i] = arr[j];\n arr[j] = temp;\n }\n\n function sortHelper<T>(arr: T[], callbackfn ?: (value1: T, value2: T) => number) : T[] {\n if (arr.length <= 0 || !callbackfn) {\n return arr;\n } \n let len = arr.length; \n // simple selection sort. \n for (let i = 0; i < len - 1; ++i) {\n for (let j = i + 1; j < len; ++j)\n {\n if (callbackfn(arr[i], arr[j]) > 0) {\n swap(arr, i, j);\n }\n }\n }\n return arr;\n }\n\n export function arraySort<T>(arr: T[], callbackfn?: (value1: T, value2: T) => number): T[] {\n if (!callbackfn) {\n //TODO: support native strings and number sorting\n /* callbackfn = function (value1: string, value2: string) : number {\n return value1.compare(value2);\n }*/\n }\n return sortHelper(arr, callbackfn);\n }\n\n export function arrayMap<T, U>(arr: T[], callbackfn: (value: T, index: number) => U): U[] {\n let res: U[] = []\n let len = arr.length // caching this seems to match V8\n for (let i = 0; i < len; ++i) {\n res.push(callbackfn(arr[i], i))\n }\n return res\n }\n\n export function arrayFilter<T>(arr: T[], callbackfn: (value: T, index: number) => boolean): T[] {\n let res: T[] = []\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n let v = arr[i] // need to cache\n if (callbackfn(v, i)) res.push(v)\n }\n return res\n }\n\n export function arrayReduce<T, U>(arr: T[], callbackfn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U {\n let len = arr.length\n for (let i = 0; i < len; ++i) {\n initialValue = callbackfn(initialValue, arr[i], i)\n }\n return initialValue\n }\n}\n\nnamespace Math {\n export function clamp(min: number, max: number, value: number): number {\n return Math.min(max, Math.max(min, value));\n }\n\n /**\n * Returns the absolute value of a number (the value without regard to whether it is positive or negative). \n * For example, the absolute value of -5 is the same as the absolute value of 5.\n * @param x A numeric expression for which the absolute value is needed.\n */\n export function abs(x: number): number {\n return x < 0 ? -x : x;\n }\n\n /**\n * Returns the sign of the x, indicating whether x is positive, negative or zero.\n * @param x The numeric expression to test\n */\n export function sign(x: number): number {\n if (x == 0) return 0;\n if (x > 0) return 1;\n return -1;\n }\n\n /**\n * Returns the larger of two supplied numeric expressions. \n */\n export function max(a: number, b: number): number {\n if (a >= b) return a;\n return b;\n }\n\n /**\n * Returns the smaller of two supplied numeric expressions. \n */\n export function min(a: number, b: number): number {\n if (a <= b) return a;\n return b;\n }\n}\n",
"pxt.cpp": "#include \"pxt.h\"\n#include <map>\n\nMicroBit uBit;\n\nnamespace pxt {\n int incr(uint32_t e)\n {\n if (e) {\n if (hasVTable(e))\n ((RefObject*)e)->ref();\n else\n ((RefCounted*)e)->incr();\n }\n return e;\n }\n\n void decr(uint32_t e)\n {\n if (e) {\n if (hasVTable(e))\n ((RefObject*)e)->unref();\n else\n ((RefCounted*)e)->decr();\n }\n }\n\n Action mkAction(int reflen, int totallen, int startptr)\n {\n check(0 <= reflen && reflen <= totallen, ERR_SIZE, 1);\n check(reflen <= totallen && totallen <= 255, ERR_SIZE, 2);\n check(bytecode[startptr] == 0xffff, ERR_INVALID_BINARY_HEADER, 3);\n check(bytecode[startptr + 1] == 0, ERR_INVALID_BINARY_HEADER, 4);\n\n uint32_t tmp = (uint32_t)&bytecode[startptr];\n\n if (totallen == 0) {\n return tmp; // no closure needed\n }\n\n void *ptr = ::operator new(sizeof(RefAction) + totallen * sizeof(uint32_t));\n RefAction *r = new (ptr) RefAction();\n r->len = totallen;\n r->reflen = reflen;\n r->func = (ActionCB)((tmp + 4) | 1);\n memset(r->fields, 0, r->len * sizeof(uint32_t));\n\n return (Action)r;\n }\n\n uint32_t runAction3(Action a, int arg0, int arg1, int arg2)\n {\n if (hasVTable(a))\n return ((RefAction*)a)->runCore(arg0, arg1, arg2);\n else {\n check(*(uint16_t*)a == 0xffff, ERR_INVALID_BINARY_HEADER, 4);\n return ((ActionCB)((a + 4) | 1))(NULL, arg0, arg1, arg2);\n }\n }\n\n uint32_t runAction2(Action a, int arg0, int arg1)\n {\n return runAction3(a, arg0, arg1, 0);\n }\n\n uint32_t runAction1(Action a, int arg0)\n {\n return runAction3(a, arg0, 0, 0);\n }\n\n uint32_t runAction0(Action a)\n {\n return runAction3(a, 0, 0, 0);\n }\n\n RefRecord* mkClassInstance(int vtableOffset)\n {\n VTable *vtable = (VTable*)&bytecode[vtableOffset];\n\n intcheck(vtable->methods[0] == &RefRecord_destroy, ERR_SIZE, 3);\n intcheck(vtable->methods[1] == &RefRecord_print, ERR_SIZE, 4);\n\n void *ptr = ::operator new(vtable->numbytes);\n RefRecord *r = new (ptr) RefRecord(PXT_VTABLE_TO_INT(vtable));\n memset(r->fields, 0, vtable->numbytes - sizeof(RefRecord));\n return r;\n }\n\n uint32_t RefRecord::ld(int idx)\n {\n //intcheck((reflen == 255 ? 0 : reflen) <= idx && idx < len, ERR_OUT_OF_BOUNDS, 1);\n return fields[idx];\n }\n\n uint32_t RefRecord::ldref(int idx)\n {\n //printf(\"LD %p len=%d reflen=%d idx=%d\\n\", this, len, reflen, idx);\n //intcheck(0 <= idx && idx < reflen, ERR_OUT_OF_BOUNDS, 2);\n uint32_t tmp = fields[idx];\n incr(tmp);\n return tmp;\n }\n\n void RefRecord::st(int idx, uint32_t v)\n {\n //intcheck((reflen == 255 ? 0 : reflen) <= idx && idx < len, ERR_OUT_OF_BOUNDS, 3);\n fields[idx] = v;\n }\n\n void RefRecord::stref(int idx, uint32_t v)\n {\n //printf(\"ST %p len=%d reflen=%d idx=%d\\n\", this, len, reflen, idx);\n //intcheck(0 <= idx && idx < reflen, ERR_OUT_OF_BOUNDS, 4);\n decr(fields[idx]);\n fields[idx] = v;\n }\n\n void RefObject::destroy() {\n ((RefObjectMethod)getVTable()->methods[0])(this);\n }\n\n void RefObject::print() {\n ((RefObjectMethod)getVTable()->methods[1])(this);\n }\n\n void RefRecord_destroy(RefRecord *r) {\n auto tbl = r->getVTable();\n uint8_t *refmask = (uint8_t*)&tbl->methods[tbl->userdata & 0xff];\n int len = (tbl->numbytes >> 2) - 1;\n for (int i = 0; i < len; ++i) {\n if (refmask[i]) decr(r->fields[i]);\n r->fields[i] = 0;\n }\n //RefRecord is allocated using placement new\n r->~RefRecord();\n ::operator delete(r);\n }\n\n void RefRecord_print(RefRecord *r)\n {\n printf(\"RefRecord %p r=%d size=%d bytes\\n\", r, r->refcnt, r->getVTable()->numbytes);\n }\n\n uint32_t Segment::get(uint32_t i)\n {\n#ifdef DEBUG_BUILD\n printf(\"In Segment::get index:%u\\n\", i);\n this->print();\n#endif \n \n if (i < length)\n {\n return data[i]; \n }\n return Segment::DefaultValue;\n }\n\n void Segment::set(uint32_t i, uint32_t value) \n {\n if (i < size)\n {\n data[i] = value;\n }\n else if (i < Segment::MaxSize)\n {\n growByMin(i + 1);\n data[i] = value;\n }\n if (length <= i)\n {\n length = i + 1; \n } \n\n#ifdef DEBUG_BUILD\n printf(\"In Segment::set\\n\");\n this->print();\n#endif \n \n return;\n } \n\n uint16_t Segment::growthFactor(uint16_t size)\n {\n if (size == 0)\n {\n return 4;\n }\n if (size < 64)\n {\n return size * 2; // Double\n }\n if (size < 512)\n {\n return size * 5/3; //Grow by 1.66 rate\n }\n return size + 256; //Grow by constant rate\n }\n\n void Segment::growByMin(uint16_t minSize)\n {\n growBy(max(minSize, growthFactor(size)));\n }\n\n void Segment::growBy(uint16_t newSize) \n {\n#ifdef DEBUG_BUILD\n printf(\"growBy: %d\\n\", newSize);\n this->print();\n#endif \n if (size < newSize)\n {\n //this will throw if unable to allocate\n uint32_t *tmp = (uint32_t*)(::operator new(newSize * sizeof(uint32_t)));\n\n //Copy existing data\n if (size)\n {\n memcpy(tmp, data, size * sizeof(uint32_t));\n }\n //fill the rest with default value\n memset(tmp + size, Segment::DefaultValue, (newSize - size) * sizeof(uint32_t));\n\n //free older segment;\n ::operator delete(data); \n\n data = tmp; \n size = newSize;\n\n#ifdef DEBUG_BUILD\n printf(\"growBy - after reallocation\\n\");\n this->print();\n#endif \n \n }\n //else { no shrinking yet; }\n return;\n }\n\n void Segment::ensure(uint16_t newSize)\n {\n if (newSize < size)\n {\n return;\n }\n growByMin(newSize);\n }\n\n void Segment::setLength(uint32_t newLength)\n {\n if (newLength > size)\n {\n ensure(length); \n }\n length = newLength;\n return;\n }\n\n void Segment::push(uint32_t value) \n { \n this->set(length, value);\n }\n \n uint32_t Segment::pop() \n {\n#ifdef DEBUG_BUILD\n printf(\"In Segment::pop\\n\");\n this->print();\n#endif \n \n if (length > 0)\n {\n uint32_t value = data[length];\n data[length] = Segment::DefaultValue;\n --length;\n return value;\n }\n return Segment::DefaultValue;\n }\n\n //this function removes an element at index i and shifts the rest of the elements to\n //left to fill the gap \n uint32_t Segment::remove(uint32_t i) \n {\n#ifdef DEBUG_BUILD\n printf(\"In Segment::remove index:%u\\n\", i);\n this->print();\n#endif \n if (i < length)\n {\n //value to return\n uint32_t ret = data[i];\n if (i + 1 < length)\n {\n //Move the rest of the elements to fill in the gap.\n memmove(data + i, data + i + 1, (length - i - 1) * sizeof(uint32_t));\n }\n length--; \n data[length] = Segment::DefaultValue; \n#ifdef DEBUG_BUILD\n printf(\"After Segment::remove index:%u\\n\", i);\n this->print();\n#endif \n return ret;\n }\n return Segment::DefaultValue;\n }\n\n //this function inserts element value at index i by shifting the rest of the elements right. \n void Segment::insert(uint32_t i, uint32_t value) \n {\n#ifdef DEBUG_BUILD\n printf(\"In Segment::insert index:%u value:%u\\n\", i, value);\n this->print();\n#endif \n\n if (i < length)\n {\n ensure(length + 1);\n if (i + 1 < length)\n {\n //Move the rest of the elements to fill in the gap.\n memmove(data + i + 1, data + i, (length - i) * sizeof(uint32_t));\n }\n\n data[i] = value; \n length++;\n }\n else\n {\n //This is insert beyond the length, just call set which will adjust the length\n set(i, value);\n }\n#ifdef DEBUG_BUILD\n printf(\"After Segment::insert index:%u\\n\", i);\n this->print();\n#endif \n }\n\n void Segment::print()\n {\n printf(\"Segment: %x, length: %u, size: %u\\n\", data, (uint32_t)length, (uint32_t)size);\n for(uint32_t i = 0; i < size; i++)\n {\n printf(\"%d \",(uint32_t)data[i]);\n }\n printf(\"\\n\");\n }\n\n bool Segment::isValidIndex(uint32_t i)\n {\n if (i > length)\n {\n return false;\n }\n return true;\n }\n\n void Segment::destroy()\n {\n#ifdef DEBUG_BUILD\n printf(\"In Segment::destroy\\n\");\n this->print();\n#endif \n length = size = 0;\n ::operator delete(data);\n data = nullptr;\n }\n\n void RefCollection::push(uint32_t x) \n {\n if (isRef()) incr(x);\n head.push(x);\n }\n\n uint32_t RefCollection::pop() \n {\n uint32_t ret = head.pop();\n if (isRef())\n {\n incr(ret); \n } \n return ret;\n }\n\n uint32_t RefCollection::getAt(int i) \n {\n uint32_t tmp = head.get(i);\n if (isRef())\n {\n incr(tmp);\n }\n return tmp;\n }\n\n uint32_t RefCollection::removeAt(int i) \n {\n if (isRef())\n {\n decr(head.get(i));\n } \n return head.remove(i);\n }\n\n void RefCollection::insertAt(int i, uint32_t value) \n {\n head.insert(i, value);\n if (isRef())\n {\n incr(value);\n } \n }\n\n void RefCollection::setAt(int i, uint32_t value) \n {\n if (isRef()) \n {\n if (head.isValidIndex((uint32_t)i))\n {\n decr(head.get(i));\n }\n incr(value);\n }\n head.set(i, value);\n }\n\n int RefCollection::indexOf(uint32_t x, int start) \n {\n if (isString()) \n {\n StringData *xx = (StringData*)x;\n uint32_t i = start;\n while(head.isValidIndex(i))\n {\n StringData *ee = (StringData*)head.get(i);\n if (ee == xx)\n {\n //handles ee being null\n return (int) i;\n }\n if (ee && xx->len == ee->len && memcmp(xx->data, ee->data, xx->len) == 0)\n {\n return (int)i;\n }\n i++;\n }\n } \n else \n {\n uint32_t i = start;\n while(head.isValidIndex(i))\n {\n if (head.get(i) == x)\n {\n return (int)i;\n }\n i++;\n }\n }\n\n return -1;\n }\n\n int RefCollection::removeElement(uint32_t x) \n {\n int idx = indexOf(x, 0);\n if (idx >= 0) {\n removeAt(idx);\n return 1;\n }\n return 0;\n }\n\n namespace Coll0 {\n PXT_VTABLE_BEGIN(RefCollection, 0, 0)\n PXT_VTABLE_END\n }\n namespace Coll1 {\n PXT_VTABLE_BEGIN(RefCollection, 1, 0)\n PXT_VTABLE_END\n }\n namespace Coll3 {\n PXT_VTABLE_BEGIN(RefCollection, 3, 0)\n PXT_VTABLE_END\n }\n\n RefCollection::RefCollection(uint16_t flags) : RefObject(0) {\n switch (flags) {\n case 0:\n vtable = PXT_VTABLE_TO_INT(&Coll0::RefCollection_vtable);\n break;\n case 1:\n vtable = PXT_VTABLE_TO_INT(&Coll1::RefCollection_vtable);\n break;\n case 3:\n vtable = PXT_VTABLE_TO_INT(&Coll3::RefCollection_vtable);\n break;\n default:\n error(ERR_SIZE);\n break;\n }\n }\n\n void RefCollection::destroy()\n {\n if (this->isRef())\n {\n for(uint32_t i = 0; i < this->head.getLength(); i++)\n {\n decr(this->head.get(i));\n }\n }\n this->head.destroy();\n delete this;\n }\n\n void RefCollection::print()\n {\n printf(\"RefCollection %p r=%d flags=%d size=%d\\n\", this, refcnt, getFlags(), head.getLength());\n head.print();\n }\n\n PXT_VTABLE_CTOR(RefAction) {}\n\n // fields[] contain captured locals\n void RefAction::destroy()\n {\n for (int i = 0; i < this->reflen; ++i) {\n decr(fields[i]);\n fields[i] = 0;\n }\n //RefAction is allocated using placement new\n this->~RefAction();\n ::operator delete(this);\n }\n\n void RefAction::print()\n {\n printf(\"RefAction %p r=%d pc=0x%lx size=%d (%d refs)\\n\", this, refcnt, (const uint8_t*)func - (const uint8_t*)bytecode, len, reflen);\n }\n\n void RefLocal::print()\n {\n printf(\"RefLocal %p r=%d v=%d\\n\", this, refcnt, v);\n }\n\n void RefLocal::destroy()\n {\n delete this;\n }\n\n PXT_VTABLE_CTOR(RefLocal) {\n v = 0;\n }\n\n PXT_VTABLE_CTOR(RefRefLocal) {\n v = 0;\n }\n\n void RefRefLocal::print()\n {\n printf(\"RefRefLocal %p r=%d v=%p\\n\", this, refcnt, (void*)v);\n }\n\n void RefRefLocal::destroy()\n {\n decr(v);\n delete this;\n }\n\n PXT_VTABLE_BEGIN(RefMap, 0, RefMapMarker)\n PXT_VTABLE_END\n RefMap::RefMap() : PXT_VTABLE_INIT(RefMap) {}\n\n void RefMap::destroy() {\n for (unsigned i = 0; i < data.size(); ++i) {\n if (data[i].key & 1) {\n decr(data[i].val);\n }\n data[i].val = 0;\n }\n data.resize(0);\n delete this;\n }\n\n int RefMap::findIdx(uint32_t key) {\n for (unsigned i = 0; i < data.size(); ++i) {\n if (data[i].key >> 1 == key)\n return i;\n }\n return -1;\n }\n\n void RefMap::print()\n {\n printf(\"RefMap %p r=%d size=%d\\n\", this, refcnt, data.size());\n }\n\n\n#ifdef DEBUG_MEMLEAKS\n std::set<RefObject*> allptrs;\n void debugMemLeaks()\n {\n printf(\"LIVE POINTERS:\\n\");\n for(std::set<RefObject*>::iterator itr = allptrs.begin();itr!=allptrs.end();itr++)\n {\n (*itr)->print();\n }\n printf(\"\\n\");\n }\n#else\n void debugMemLeaks() {}\n#endif\n\n\n // ---------------------------------------------------------------------------\n // An adapter for the API expected by the run-time.\n // ---------------------------------------------------------------------------\n\n map<pair<int, int>, Action> handlersMap;\n\n MicroBitEvent lastEvent;\n\n // We have the invariant that if [dispatchEvent] is registered against the DAL\n // for a given event, then [handlersMap] contains a valid entry for that\n // event.\n void dispatchEvent(MicroBitEvent e) {\n\n lastEvent = e;\n\n Action curr = handlersMap[{ e.source, e.value }];\n if (curr)\n runAction1(curr, e.value);\n\n curr = handlersMap[{ e.source, MICROBIT_EVT_ANY }];\n if (curr)\n runAction1(curr, e.value);\n }\n\n void registerWithDal(int id, int event, Action a) {\n Action prev = handlersMap[{ id, event }];\n if (prev)\n decr(prev);\n else\n uBit.messageBus.listen(id, event, dispatchEvent);\n incr(a);\n handlersMap[{ id, event }] = a;\n }\n\n void fiberDone(void *a)\n {\n decr((Action)a);\n release_fiber();\n }\n\n\n void runInBackground(Action a) {\n if (a != 0) {\n incr(a);\n create_fiber((void(*)(void*))runAction0, (void*)a, fiberDone);\n }\n }\n\n\n void error(ERROR code, int subcode)\n {\n printf(\"Error: %d [%d]\\n\", code, subcode);\n uBit.panic(42);\n }\n\n uint16_t *bytecode;\n uint32_t *globals;\n int numGlobals;\n\n uint32_t *allocate(uint16_t sz)\n {\n uint32_t *arr = new uint32_t[sz];\n memset(arr, 0, sz * 4);\n return arr;\n }\n\n void checkStr(bool cond, const char *msg)\n {\n if (!cond) {\n while (true) {\n uBit.display.scroll(msg, 100);\n uBit.sleep(100);\n }\n }\n }\n\n int templateHash()\n {\n return ((int*)bytecode)[4];\n }\n\n int programHash()\n {\n return ((int*)bytecode)[6];\n }\n\n int getNumGlobals()\n {\n return bytecode[16];\n }\n\n void exec_binary(int32_t *pc)\n {\n // XXX re-enable once the calibration code is fixed and [editor/embedded.ts]\n // properly prepends a call to [internal_main].\n // ::touch_develop::internal_main();\n\n // unique group for radio based on source hash\n // ::touch_develop::micro_bit::radioDefaultGroup = programHash();\n\n // repeat error 4 times and restart as needed\n microbit_panic_timeout(4);\n\n int32_t ver = *pc++;\n checkStr(ver == 0x4209, \":( Bad runtime version\");\n\n bytecode = *((uint16_t**)pc++); // the actual bytecode is here\n globals = allocate(getNumGlobals());\n\n // just compare the first word\n checkStr(((uint32_t*)bytecode)[0] == 0x923B8E70 &&\n templateHash() == *pc,\n \":( Failed partial flash\");\n\n uint32_t startptr = (uint32_t)bytecode;\n startptr += 48; // header\n startptr |= 1; // Thumb state\n\n ((uint32_t (*)())startptr)();\n\n#ifdef DEBUG_MEMLEAKS\n pxt::debugMemLeaks();\n#endif\n\n return;\n }\n\n void start()\n {\n exec_binary((int32_t*)functionsAndBytecode);\n }\n}\n\n// vim: ts=2 sw=2 expandtab",
"pxt.h": "#ifndef __PXT_H\n#define __PXT_H\n\n//#define DEBUG_MEMLEAKS 1\n\n#pragma GCC diagnostic ignored \"-Wunused-parameter\"\n\n#include \"MicroBit.h\"\n#include \"MicroBitImage.h\"\n#include \"ManagedString.h\"\n#include \"ManagedType.h\"\n#include \"ManagedBuffer.h\"\n\n#define printf(...) uBit.serial.printf(__VA_ARGS__)\n// #define printf(...)\n\n#define intcheck(...) check(__VA_ARGS__)\n//#define intcheck(...) do {} while (0)\n\n#include <stdio.h>\n#include <string.h>\n#include <vector>\n#include <stdint.h>\n\n#ifdef DEBUG_MEMLEAKS\n#include <set>\n#endif\n\nextern MicroBit uBit;\n\nnamespace pxt {\n typedef uint32_t Action;\n typedef uint32_t ImageLiteral;\n\n\n typedef enum {\n ERR_INVALID_BINARY_HEADER = 5,\n ERR_OUT_OF_BOUNDS = 8,\n ERR_REF_DELETED = 7,\n ERR_SIZE = 9,\n } ERROR;\n\n extern const uint32_t functionsAndBytecode[];\n extern uint32_t *globals;\n extern uint16_t *bytecode;\n class RefRecord;\n\n // Utility functions\n extern MicroBitEvent lastEvent;\n void registerWithDal(int id, int event, Action a);\n void runInBackground(Action a);\n uint32_t runAction3(Action a, int arg0, int arg1, int arg2);\n uint32_t runAction2(Action a, int arg0, int arg1);\n uint32_t runAction1(Action a, int arg0);\n uint32_t runAction0(Action a);\n Action mkAction(int reflen, int totallen, int startptr);\n void error(ERROR code, int subcode = 0);\n void exec_binary(uint16_t *pc);\n void start();\n void debugMemLeaks();\n // allocate [sz] words and clear them\n uint32_t *allocate(uint16_t sz);\n int templateHash();\n int programHash();\n uint32_t programSize();\n uint32_t afterProgramPage(); \n int getNumGlobals();\n RefRecord* mkClassInstance(int vtableOffset);\n\n // The standard calling convention is:\n // - when a pointer is loaded from a local/global/field etc, and incr()ed\n // (in other words, its presence on stack counts as a reference)\n // - after a function call, all pointers are popped off the stack and decr()ed\n // This does not apply to the RefRecord and st/ld(ref) methods - they unref()\n // the RefRecord* this.\n int incr(uint32_t e);\n void decr(uint32_t e);\n\n inline void *ptrOfLiteral(int offset)\n {\n return &bytecode[offset];\n }\n\n inline ImageData* imageBytes(int offset)\n {\n return (ImageData*)(void*)&bytecode[offset];\n }\n\n // Checks if object has a VTable, or if its RefCounted* from the runtime.\n inline bool hasVTable(uint32_t e)\n {\n return (*((uint32_t*)e) & 1) == 0;\n }\n\n inline void check(int cond, ERROR code, int subcode = 0)\n {\n if (!cond) error(code, subcode);\n }\n\n\n class RefObject;\n#ifdef DEBUG_MEMLEAKS\n extern std::set<RefObject*> allptrs;\n#endif\n\n typedef void (*RefObjectMethod)(RefObject *self);\n typedef void *PVoid;\n typedef void **PPVoid;\n\n const PPVoid RefMapMarker = (PPVoid)(void*)43;\n\n struct VTable {\n uint16_t numbytes; // in the entire object, including the vtable pointer\n uint16_t userdata;\n PVoid *ifaceTable;\n PVoid methods[2]; // we only use up to two methods here; pxt will generate more\n // refmask sits at &methods[nummethods]\n };\n\n const int vtableShift = 2;\n\n // A base abstract class for ref-counted objects.\n class RefObject\n {\n public:\n uint16_t refcnt;\n uint16_t vtable;\n\n RefObject(uint16_t vt)\n {\n refcnt = 2;\n vtable = vt;\n#ifdef DEBUG_MEMLEAKS\n allptrs.insert(this);\n#endif\n }\n\n inline VTable *getVTable() {\n return (VTable*)(vtable << vtableShift);\n }\n\n void destroy();\n void print();\n\n // Call to disable pointer tracking on the current instance (in destructor or some other hack)\n inline void untrack() {\n#ifdef DEBUG_MEMLEAKS\n allptrs.erase(this);\n#endif\n }\n\n // Increment/decrement the ref-count. Decrementing to zero deletes the current object.\n inline void ref()\n {\n check(refcnt > 0, ERR_REF_DELETED);\n //printf(\"INCR \"); this->print();\n refcnt += 2;\n }\n\n inline void unref()\n {\n //printf(\"DECR \"); this->print();\n refcnt -= 2;\n if (refcnt == 0) {\n destroy();\n }\n }\n };\n\n class Segment {\n private: \n uint32_t* data;\n uint16_t length;\n uint16_t size;\n\n static const uint16_t MaxSize = 0xFFFF;\n static const uint32_t DefaultValue = 0x0;\n\n static uint16_t growthFactor(uint16_t size); \n void growByMin(uint16_t minSize);\n void growBy(uint16_t newSize);\n void ensure(uint16_t newSize);\n\n public:\n Segment() : data (nullptr), length(0), size(0) {};\n\n uint32_t get(uint32_t i);\n void set(uint32_t i, uint32_t value); \n\n uint32_t getLength() { return length;};\n void setLength(uint32_t newLength);\n\n void push(uint32_t value);\n uint32_t pop();\n\n uint32_t remove(uint32_t i);\n void insert(uint32_t i, uint32_t value);\n\n bool isValidIndex(uint32_t i);\n\n void destroy();\n\n void print();\n };\n\n // A ref-counted collection of either primitive or ref-counted objects (String, Image,\n // user-defined record, another collection)\n class RefCollection\n : public RefObject\n {\n private:\n Segment head;\n public:\n // 1 - collection of refs (need decr)\n // 2 - collection of strings (in fact we always have 3, never 2 alone)\n inline uint32_t getFlags() { return getVTable()->userdata; }\n inline bool isRef() { return getFlags() & 1; }\n inline bool isString() { return getFlags() & 2; }\n\n RefCollection(uint16_t f);\n\n void destroy();\n void print();\n\n uint32_t length() { return head.getLength();}\n void setLength(uint32_t newLength) { head.setLength(newLength); }\n\n void push(uint32_t x);\n uint32_t pop();\n uint32_t getAt(int i);\n void setAt(int i, uint32_t x);\n //removes the element at index i and shifts the other elements left\n uint32_t removeAt(int i);\n //inserts the element at index i and moves the other elements right.\n void insertAt(int i, uint32_t x); \n\n int indexOf(uint32_t x, int start);\n int removeElement(uint32_t x);\n };\n\n struct MapEntry {\n uint32_t key;\n uint32_t val;\n };\n\n class RefMap\n : public RefObject\n {\n public:\n std::vector<MapEntry> data;\n\n RefMap();\n void destroy();\n void print();\n int findIdx(uint32_t key);\n };\n\n // A ref-counted, user-defined JS object.\n class RefRecord\n : public RefObject\n {\n public:\n // The object is allocated, so that there is space at the end for the fields.\n uint32_t fields[];\n\n RefRecord(uint16_t v) : RefObject(v) {}\n\n uint32_t ld(int idx);\n uint32_t ldref(int idx);\n void st(int idx, uint32_t v);\n void stref(int idx, uint32_t v);\n };\n\n // these are needed when constructing vtables for user-defined classes\n void RefRecord_destroy(RefRecord *r);\n void RefRecord_print(RefRecord *r);\n\n class RefAction;\n typedef uint32_t (*ActionCB)(uint32_t *captured, uint32_t arg0, uint32_t arg1, uint32_t arg2);\n\n // Ref-counted function pointer. It's currently always a ()=>void procedure pointer.\n class RefAction\n : public RefObject\n {\n public:\n // This is the same as for RefRecord.\n uint8_t len;\n uint8_t reflen;\n ActionCB func; // The function pointer\n // fields[] contain captured locals\n uint32_t fields[];\n\n void destroy();\n void print();\n\n RefAction();\n\n inline void stCore(int idx, uint32_t v)\n {\n //printf(\"ST [%d] = %d \", idx, v); this->print();\n intcheck(0 <= idx && idx < len, ERR_OUT_OF_BOUNDS, 10);\n intcheck(fields[idx] == 0, ERR_OUT_OF_BOUNDS, 11); // only one assignment permitted\n fields[idx] = v;\n }\n\n inline uint32_t runCore(int arg0, int arg1, int arg2) // internal; use runAction*() functions\n {\n this->ref();\n uint32_t r = this->func(&this->fields[0], arg0, arg1, arg2);\n this->unref();\n return r;\n }\n };\n\n // These two are used to represent locals written from inside inline functions\n class RefLocal\n : public RefObject\n {\n public:\n uint32_t v;\n void destroy();\n void print();\n RefLocal();\n };\n\n class RefRefLocal\n : public RefObject\n {\n public:\n uint32_t v;\n void destroy();\n void print();\n RefRefLocal();\n };\n}\n\nusing namespace pxt;\nMicroBitPin *getPin(int id);\ntypedef ImageData* Image;\ntypedef BufferData* Buffer;\n\n// The ARM Thumb generator in the JavaScript code is parsing\n// the hex file and looks for the magic numbers as present here.\n//\n// Then it fetches function pointer addresses from there.\n \n#define PXT_SHIMS_BEGIN \\\nnamespace pxt { \\\n const uint32_t functionsAndBytecode[] __attribute__((aligned(0x20))) = { \\\n 0x08010801, 0x42424242, 0x08010801, 0x8de9d83e,\n\n#define PXT_SHIMS_END }; }\n\n#pragma GCC diagnostic ignored \"-Wpmf-conversions\"\n\n#define PXT_VTABLE_TO_INT(vt) ((uint32_t)(vt) >> vtableShift)\n#define PXT_VTABLE_BEGIN(classname, flags, iface) \\\nconst VTable classname ## _vtable \\\n __attribute__((aligned(1 << vtableShift))) \\\n = { \\\n sizeof(classname), \\\n flags, \\\n iface, \\\n { \\\n (void*)&classname::destroy, \\\n (void*)&classname::print,\n\n#define PXT_VTABLE_END } };\n\n#define PXT_VTABLE_INIT(classname) \\\n RefObject(PXT_VTABLE_TO_INT(&classname ## _vtable))\n\n#define PXT_VTABLE_CTOR(classname) \\\n PXT_VTABLE_BEGIN(classname, 0, 0) PXT_VTABLE_END \\\n classname::classname() : PXT_VTABLE_INIT(classname)\n\n#endif\n\n// vim: ts=2 sw=2 expandtab\n",
"pxt.json": "{\n \"name\": \"core\",\n \"description\": \"The microbit core library\",\n \"files\": [\n \"README.md\",\n \"ManagedBuffer.cpp\",\n \"ManagedBuffer.h\",\n \"pxt.cpp\",\n \"pxt.h\",\n \"dal.d.ts\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"pxt-core.d.ts\",\n \"core.cpp\",\n \"pxt-helpers.ts\",\n \"helpers.ts\",\n \"images.cpp\",\n \"basic.cpp\",\n \"basic.ts\",\n \"input.cpp\",\n \"input.ts\",\n \"control.ts\",\n \"control.cpp\",\n \"game.ts\",\n \"led.cpp\",\n \"led.ts\",\n \"motors.cpp\",\n \"music.cpp\",\n \"music.ts\",\n \"pins.cpp\",\n \"pins.ts\",\n \"serial.cpp\",\n \"serial.ts\",\n \"icons.ts\",\n \"buffer.cpp\",\n \"pxtparts.json\",\n \"parts/speaker.svg\",\n \"parts/headphone.svg\",\n \"parts/dcmotor.svg\",\n \"_locales/de/core-jsdoc-strings.json\",\n \"_locales/de/core-strings.json\"\n ],\n \"public\": true,\n \"dependencies\": {},\n \"yotta\": {\n \"optionalConfig\": {\n \"microbit-dal\": {\n \"bluetooth\": {\n \"enabled\": 0\n }\n }\n }\n }\n}",
"pxtparts.json": "{ \n \"buttonpair\": {\n \"simulationBehavior\": \"buttonpair\",\n \"visual\": {\n \"builtIn\": \"buttonpair\",\n \"width\": 75,\n \"height\": 45,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\"x\": 0, \"y\": 0},\n {\"x\": 30, \"y\": 45},\n {\"x\": 45, \"y\": 0},\n {\"x\": 75, \"y\": 45}\n ]\n },\n \"numberOfPins\": 4,\n \"pinDefinitions\": [\n {\"target\": \"P14\", \"style\": \"male\", \"orientation\": \"-Z\"},\n {\"target\": \"ground\", \"style\": \"male\", \"orientation\": \"-Z\"},\n {\"target\": \"P15\", \"style\": \"male\", \"orientation\": \"-Z\"},\n {\"target\": \"ground\", \"style\": \"male\", \"orientation\": \"-Z\"}\n ],\n \"instantiation\": {\n \"kind\": \"singleton\"\n },\n \"assembly\": [\n {\"part\": true},\n {\"pinIndices\": [0, 1]},\n {\"pinIndices\": [2, 3]}\n ]\n },\n \"microservo\": {\n \"simulationBehavior\": \"microservo\",\n \"visual\": {\n \"builtIn\": \"microservo\",\n \"width\": 74.85,\n \"height\": 200,\n \"pinDistance\": 10,\n \"pinLocations\": [\n {\"x\": 30, \"y\": 5},\n {\"x\": 37, \"y\": 5},\n {\"x\": 45, \"y\": 5}\n ]\n },\n \"numberOfPins\": 3,\n \"pinDefinitions\": [\n {\"target\": {\"pinInstantiationIdx\": 0}, \"style\": \"croc\", \"orientation\": \"+Z\"},\n {\"target\": \"threeVolt\", \"style\": \"croc\", \"orientation\": \"+Z\"},\n {\"target\": \"ground\", \"style\": \"croc\", \"orientation\": \"+Z\"}\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"pins.servoWritePin\",\n \"argumentRoles\": [\n {\"pinInstantiationIdx\": 0, \"partParameter\": \"name\"}\n ]\n },\n \"assembly\": [\n {\"part\": true, \"pinIndices\": [2]},\n {\"pinIndices\": [0, 1]}\n ]\n },\n \"neopixel\": {\n \"simulationBehavior\": \"neopixel\",\n \"visual\": {\n \"builtIn\": \"neopixel\",\n \"width\": 58,\n \"height\": 113,\n \"pinDistance\": 9,\n \"pinLocations\": [\n {\"x\": 10, \"y\": 0},\n {\"x\": 19, \"y\": 0},\n {\"x\": 28, \"y\": 0}\n ]\n },\n \"numberOfPins\": 3,\n \"pinDefinitions\": [\n {\"target\": {\"pinInstantiationIdx\": 0}, \"style\": \"solder\", \"orientation\": \"+Z\"},\n {\"target\": \"threeVolt\", \"style\": \"solder\", \"orientation\": \"+Z\"},\n {\"target\": \"ground\", \"style\": \"solder\", \"orientation\": \"+Z\"}\n ],\n \"instantiation\": {\n \"kind\": \"function\",\n \"fullyQualifiedName\": \"neopixel.create\",\n \"argumentRoles\": [\n {\"pinInstantiationIdx\": 0, \"partParameter\": \"pin\"},\n {\"partParameter\": \"mode\"}\n ]\n },\n \"assembly\": [\n {\"part\": true, \"pinIndices\": [2]},\n {\"pinIndices\": [0, 1]}\n ]\n },\n \"ledmatrix\": {\n \"visual\": {\n \"builtIn\": \"ledmatrix\",\n \"width\": 105,\n \"height\": 105,\n \"pinDistance\": 15,\n \"pinLocations\": [\n {\"x\": 0, \"y\": 0},\n {\"x\": 15, \"y\": 0},\n {\"x\": 30, \"y\": 0},\n {\"x\": 45, \"y\": 0},\n {\"x\": 105, \"y\": 105},\n {\"x\": 0, \"y\": 105},\n {\"x\": 15, \"y\": 105},\n {\"x\": 30, \"y\": 105},\n {\"x\": 45, \"y\": 105},\n {\"x\": 60, \"y\": 0}\n ]\n },\n \"simulationBehavior\": \"ledmatrix\",\n \"numberOfPins\": 10,\n \"instantiation\": {\"kind\": \"singleton\"},\n \"pinDefinitions\": [\n {\"target\": \"P6\", \"style\": \"male\", \"orientation\": \"-Z\", \"colorGroup\": 0},\n {\"target\": \"P7\", \"style\": \"male\", \"orientation\": \"-Z\", \"colorGroup\": 0},\n {\"target\": \"P8\", \"style\": \"male\", \"orientation\": \"-Z\", \"colorGroup\": 0},\n {\"target\": \"P9\", \"style\": \"male\", \"orientation\": \"-Z\", \"colorGroup\": 0},\n {\"target\": \"P10\", \"style\": \"male\", \"orientation\": \"-Z\", \"colorGroup\": 0},\n {\"target\": \"P12\", \"style\": \"male\", \"orientation\": \"-Z\", \"colorGroup\": 1},\n {\"target\": \"P13\", \"style\": \"male\", \"orientation\": \"-Z\", \"colorGroup\": 1},\n {\"target\": \"P16\", \"style\": \"male\", \"orientation\": \"-Z\", \"colorGroup\": 1},\n {\"target\": \"P19\", \"style\": \"male\", \"orientation\": \"-Z\", \"colorGroup\": 1},\n {\"target\": \"P20\", \"style\": \"male\", \"orientation\": \"-Z\", \"colorGroup\": 1}\n ],\n \"assembly\": [\n {\"part\": true},\n {\"pinIndices\": [0, 1, 2, 3, 4]},\n {\"pinIndices\": [5, 6, 7, 8, 9]}\n ]\n },\n \"headphone\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"image\": \"parts/headphone.svg\",\n \"width\": 142,\n \"height\": 180,\n \"pinDistance\": 20,\n \"pinLocations\": [\n {\"x\": 17, \"y\": 11},\n {\"x\": 55, \"y\": 50}\n ]\n },\n \"pinDefinitions\": [\n {\"target\": \"P0\", \"style\": \"croc\", \"orientation\": \"Y\"},\n {\"target\": \"ground\", \"style\": \"croc\", \"orientation\": \"Y\"}\n ],\n \"instantiation\": {\"kind\": \"singleton\"},\n \"assembly\": [\n {\"part\": true, \"pinIndices\": [0]},\n {\"pinIndices\": [1]}\n ]\n },\n \"speaker\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"image\": \"parts/speaker.svg\",\n \"width\": 500,\n \"height\": 500,\n \"pinDistance\": 70,\n \"pinLocations\": [\n {\"x\": 180, \"y\": 135},\n {\"x\": 320, \"y\": 135}\n ]\n },\n \"pinDefinitions\": [\n {\"target\": \"P0\", \"style\": \"male\", \"orientation\": \"-Z\"},\n {\"target\": \"ground\", \"style\": \"male\", \"orientation\": \"-Z\"}\n ],\n \"instantiation\": {\"kind\": \"singleton\"},\n \"assembly\": [\n {\"part\": true, \"pinIndices\": [0]},\n {\"pinIndices\": [1]}\n ]\n },\n \"dcmotor\": {\n \"numberOfPins\": 2,\n \"visual\": {\n \"image\": \"parts/dcmotor.svg\",\n \"width\": 488,\n \"height\": 836,\n \"pinDistance\": 65,\n \"pinLocations\": [\n {\"x\": 89, \"y\": 48},\n {\"x\": 393, \"y\": 48} ]\n },\n \"pinDefinitions\": [\n { \"target\": \"M_OUT1\", \"style\": \"croc\", \"orientation\": \"-Z\"},\n { \"target\": \"M_OUT2\", \"style\": \"croc\", \"orientation\": \"-Z\"}\n ],\n \"instantiation\": {\"kind\": \"singleton\"},\n \"assembly\": [\n {\"part\": true, \"pinIndices\": [0]},\n {\"pinIndices\": [1]}\n ]\n } \n}",
"serial.cpp": "#include \"pxt.h\"\n\nenum SerialPin {\n C16 = MICROBIT_ID_IO_P2,\n C17 = MICROBIT_ID_IO_P8,\n P0 = MICROBIT_ID_IO_P12,\n P1 = MICROBIT_ID_IO_P0,\n P2 = MICROBIT_ID_IO_P1,\n P3 = MICROBIT_ID_IO_P16,\n};\n\nenum BaudRate {\n //% block=115200\n BaudRate115200 = 115200,\n //% block=57600\n BaudRate56700 = 57600,\n //% block=9600\n BaudRate9600 = 9600\n};\n\nenum Delimiters {\n //% block=\"new line\"\n NewLine = 1,\n //% block=\",\"\n Comma = 2,\n //% block=\"$\"\n Dollar = 3,\n //% block=\":\"\n Colon = 4,\n //% block=\".\"\n Fullstop = 5,\n //% block=\"#\"\n Hash = 6,\n};\n\n//% weight=2 color=30\n//% advanced=true\nnamespace serial {\n // note that at least one // followed by % is needed per declaration!\n\n /**\n * Reads a line of text from the serial port and returns the buffer when the delimiter is met.\n * @param delimiter text delimiter that separates each text chunk\n */\n //% help=serial/read-until\n //% blockId=serial_read_until block=\"serial|read until %delimiter=serial_delimiter_conv\"\n //% weight=19\n StringData* readUntil(StringData* delimiter) {\n return uBit.serial.readUntil(ManagedString(delimiter)).leakData();\n }\n\n /**\n * Reads the buffered received data as a string\n */\n //% blockId=serial_read_buffer block=\"serial|read string\"\n //% weight=18\n StringData* readString() {\n int n = uBit.serial.getRxBufferSize();\n if (n == 0) return ManagedString(\"\").leakData();\n return ManagedString(uBit.serial.read(n, MicroBitSerialMode::ASYNC)).leakData();\n }\n\n /**\n * Registers an event to be fired when one of the delimiter is matched.\n * @param delimiters the characters to match received characters against.\n */\n //% help=serial/on-data-received\n //% weight=18 blockId=serial_on_data_received block=\"serial|on data received %delimiters=serial_delimiter_conv\"\n void onDataReceived(StringData* delimiters, Action body) {\n uBit.serial.eventOn(ManagedString(delimiters));\n registerWithDal(MICROBIT_ID_SERIAL, MICROBIT_SERIAL_EVT_DELIM_MATCH, body);\n // lazy initialization of serial buffers\n uBit.serial.read(MicroBitSerialMode::ASYNC);\n }\n\n /**\n * Sends a piece of text through Serial connection.\n */\n //% help=serial/write-string\n //% weight=87\n //% blockId=serial_writestring block=\"serial|write string %text\"\n void writeString(StringData *text) {\n uBit.serial.send(ManagedString(text));\n }\n\n /**\n * Dynamically configuring the serial instance to use pins other than USBTX and USBRX.\n * @param tx the new transmission pins, eg: SerialPin.P0\n * @param rx the new reception pin, eg: SerialPin.P1\n * @param rate the new baud rate. eg: 115200\n */\n //% weight=10\n //% help=serial/redirect-to\n //% blockId=serial_redirect block=\"serial|redirect to|TX %tx|RX %rx|at baud rate %rate\"\n //% blockExternalInputs=1\n void redirect(SerialPin tx, SerialPin rx, BaudRate rate) {\n MicroBitPin* txp = getPin(tx); if (!tx) return;\n MicroBitPin* rxp = getPin(rx); if (!rx) return;\n\n uBit.serial.redirect(txp->name, rxp->name);\n uBit.serial.baud((int)rate);\n }\n}\n",
"serial.ts": "/**\n * Reading and writing data over a serial connection.\n */\n//% weight=2 color=#002050 icon=\"\\uf287\"\n//% advanced=true\nnamespace serial {\n /**\n * Prints a line of text to the serial\n * @param value to send over serial\n */\n //% weight=90\n //% help=serial/write-line blockGap=8\n //% blockId=serial_writeline block=\"serial|write line %text\"\n export function writeLine(text: string): void {\n writeString(text + \"\\r\\n\");\n }\n\n /**\n * Prints a numeric value to the serial\n */\n //% help=serial/write-number\n //% weight=89 blockGap=8\n //% blockId=serial_writenumber block=\"serial|write number %value\"\n export function writeNumber(value: number): void {\n writeString(value.toString());\n }\n\n /**\n * Writes a ``name: value`` pair line to the serial.\n * @param name name of the value stream, eg: x\n * @param value to write\n */\n //% weight=88 blockGap=8\n //% help=serial/write-value\n //% blockId=serial_writevalue block=\"serial|write value %name|= %value\"\n export function writeValue(name: string, value: number): void {\n writeString(name + \":\" + value + \"\\r\\n\");\n }\n\n /**\n * Reads a line of text from the serial port.\n */\n //% help=serial/read-line\n //% blockId=serial_read_line block=\"serial|read line\"\n //% weight=20 blockGap=8\n export function readLine(): string {\n return serial.readUntil(delimiters(Delimiters.NewLine));\n }\n\n /**\n * Returns the delimiter corresponding string\n */\n //% blockId=\"serial_delimiter_conv\" block=\"%del\"\n //% weight=1 blockHidden=true\n export function delimiters(del: Delimiters): string {\n // even though it might not look like, this is more\n // (memory) efficient than the C++ implementation, because the\n // strings are statically allocated and take no RAM \n switch (del) {\n case Delimiters.NewLine: return \"\\n\"\n case Delimiters.Comma: return \",\"\n case Delimiters.Dollar: return \"$\"\n case Delimiters.Colon: return \":\"\n case Delimiters.Fullstop: return \".\"\n case Delimiters.Hash: return \"#\"\n default: return \"\\n\"\n }\n }\n}\n",
"shims.d.ts": "// Auto-generated. Do not edit.\n\n\n /**\n * Creation, manipulation and display of LED images.\n */\n //% color=#5C2D91 weight=31 icon=\"\\uf03e\"\n //% advanced=true\ndeclare namespace images {\n\n /**\n * Creates an image that fits on the LED screen.\n */\n //% weight=75 help=images/create-image\n //% blockId=device_build_image block=\"create image\"\n //% parts=\"ledmatrix\" imageLiteral=1 shim=images::createImage\n function createImage(leds: string): Image;\n\n /**\n * Creates an image with 2 frames.\n */\n //% weight=74 help=images/create-big-image\n //% blockId=device_build_big_image block=\"create big image\" imageLiteral=2\n //% parts=\"ledmatrix\" shim=images::createBigImage\n function createBigImage(leds: string): Image;\n}\n\n\ndeclare interface Image {\n /**\n * Plots the image at a given column to the screen\n */\n //% help=images/plot-image\n //% parts=\"ledmatrix\" xOffset.defl=0 shim=ImageMethods::plotImage\n plotImage(xOffset?: number): void;\n\n /**\n * Shows an frame from the image at offset ``x offset``.\n * @param xOffset column index to start displaying the image\n */\n //% help=images/show-image weight=80 blockNamespace=images\n //% blockId=device_show_image_offset block=\"show image %sprite|at offset %offset\" blockGap=8\n //% parts=\"ledmatrix\" async interval.defl=400 shim=ImageMethods::showImage\n showImage(xOffset: number, interval?: number): void;\n\n /**\n * Draws the ``index``-th frame of the image on the screen.\n * @param xOffset column index to start displaying the image\n */\n //% help=images/plot-frame weight=80\n //% parts=\"ledmatrix\" shim=ImageMethods::plotFrame\n plotFrame(xOffset: number): void;\n\n /**\n * Scrolls an image .\n * @param frameOffset x offset moved on each animation step, eg: 1, 2, 5\n * @param interval time between each animation step in milli seconds, eg: 200\n */\n //% help=images/show-image weight=79 async blockNamespace=images\n //% blockId=device_scroll_image block=\"scroll image %sprite|with offset %frameoffset|and interval (ms) %delay\" blockGap=8\n //% parts=\"ledmatrix\" shim=ImageMethods::scrollImage\n scrollImage(frameOffset: number, interval: number): void;\n\n /**\n * Sets all pixels off.\n */\n //% help=images/clear\n //% parts=\"ledmatrix\" shim=ImageMethods::clear\n clear(): void;\n\n /**\n * Sets a specific pixel brightness at a given position\n */\n //%\n //% parts=\"ledmatrix\" shim=ImageMethods::setPixelBrightness\n setPixelBrightness(x: number, y: number, value: number): void;\n\n /**\n * Gets the pixel brightness ([0..255]) at a given position\n */\n //%\n //% parts=\"ledmatrix\" shim=ImageMethods::pixelBrightness\n pixelBrightness(x: number, y: number): number;\n\n /**\n * Gets the width in columns\n */\n //% help=functions/width shim=ImageMethods::width\n width(): number;\n\n /**\n * Gets the height in rows (always 5)\n */\n //% shim=ImageMethods::height\n height(): number;\n\n /**\n * Set a pixel state at position ``(x,y)``\n * @param x TODO\n * @param y TODO\n * @param value TODO\n */\n //% help=images/set-pixel\n //% parts=\"ledmatrix\" shim=ImageMethods::setPixel\n setPixel(x: number, y: number, value: boolean): void;\n\n /**\n * Get the pixel state at position ``(x,y)``\n * @param x TODO\n * @param y TODO\n */\n //% help=images/pixel\n //% parts=\"ledmatrix\" shim=ImageMethods::pixel\n pixel(x: number, y: number): boolean;\n\n /**\n * Shows a particular frame of the image strip.\n * @param frame TODO\n */\n //% weight=70 help=images/show-frame\n //% parts=\"ledmatrix\" interval.defl=400 shim=ImageMethods::showFrame\n showFrame(frame: number, interval?: number): void;\n}\n\n\n /**\n * Provides access to basic micro:bit functionality.\n */\n //% color=#54C9C9 weight=100 icon=\"\\uf00a\"\ndeclare namespace basic {\n\n /**\n * Sets the color on the build-in LED. Set to 0 to turn off.\n */\n //% blockId=device_set_led_color block=\"set led to %color=color_id\"\n //% weight=50 shim=basic::setLedColor\n function setLedColor(color: number): void;\n\n /**\n * Scroll a number on the screen. If the number fits on the screen (i.e. is a single digit), do not scroll.\n * @param interval speed of scroll; eg: 150, 100, 200, -100\n */\n //% help=basic/show-number\n //% weight=96\n //% blockId=device_show_number block=\"show|number %number\" blockGap=8\n //% async\n //% parts=\"ledmatrix\" interval.defl=150 shim=basic::showNumber\n function showNumber(value: number, interval?: number): void;\n\n /**\n * Draws an image on the LED screen.\n * @param leds the pattern of LED to turn on/off\n * @param interval time in milliseconds to pause after drawing\n */\n //% help=basic/show-leds \n //% weight=95 blockGap=8\n //% imageLiteral=1 async\n //% blockId=device_show_leds\n //% block=\"show leds\"\n //% parts=\"ledmatrix\" interval.defl=400 shim=basic::showLeds\n function showLeds(leds: string, interval?: number): void;\n\n /**\n * Display text on the display, one character at a time. If the string fits on the screen (i.e. is one letter), does not scroll.\n * @param text the text to scroll on the screen, eg: \"Hello!\"\n * @param interval how fast to shift characters; eg: 150, 100, 200, -100\n */\n //% help=basic/show-string \n //% weight=87 blockGap=8\n //% block=\"show|string %text\" \n //% async\n //% blockId=device_print_message\n //% parts=\"ledmatrix\" interval.defl=150 shim=basic::showString\n function showString(text: string, interval?: number): void;\n\n /**\n * Turn off all LEDs\n */\n //% help=basic/clear-screen weight=79\n //% blockId=device_clear_display block=\"clear screen\"\n //% parts=\"ledmatrix\" shim=basic::clearScreen\n function clearScreen(): void;\n\n /**\n * Shows a sequence of LED screens as an animation.\n * @param leds pattern of LEDs to turn on/off\n * @param interval time in milliseconds between each redraw\n */\n //% help=basic/show-animation imageLiteral=1 async\n //% parts=\"ledmatrix\" interval.defl=400 shim=basic::showAnimation\n function showAnimation(leds: string, interval?: number): void;\n\n /**\n * Draws an image on the LED screen.\n * @param leds pattern of LEDs to turn on/off\n */\n //% help=basic/plot-leds weight=80\n //% parts=\"ledmatrix\" imageLiteral=1 shim=basic::plotLeds\n function plotLeds(leds: string): void;\n\n /**\n * Repeats the code forever in the background. On each iteration, allows other codes to run.\n * @param body code to execute\n */\n //% help=basic/forever weight=55 blockGap=8\n //% blockId=device_forever block=\"forever\" shim=basic::forever\n function forever(a: () => void): void;\n\n /**\n * Pause for the specified time in milliseconds\n * @param ms how long to pause for, eg: 100, 200, 500, 1000, 2000\n */\n //% help=basic/pause weight=54\n //% async block=\"pause (ms) %pause\"\n //% blockId=device_pause shim=basic::pause\n function pause(ms: number): void;\n}\n\n\n\n //% color=#C90072 weight=99 icon=\"\\uf192\"\ndeclare namespace input {\n\n /**\n * Do something when a button (``A``, ``B`` or both ``A+B``) is pressed\n * @param button TODO\n * @param body TODO\n */\n //% help=input/on-button-pressed weight=85 blockGap=8\n //% blockId=device_button_event block=\"on button|%NAME|pressed\"\n //% parts=\"buttonpair\" shim=input::onButtonPressed\n function onButtonPressed(button: Button, body: () => void): void;\n\n /**\n * Do something when when a gesture is done (like shaking the micro:bit).\n * @param body TODO\n */\n //% help=input/on-gesture weight=84 blockGap=8\n //% blockId=device_gesture_event block=\"on |%NAME\"\n //% parts=\"accelerometer\" shim=input::onGesture\n function onGesture(gesture: Gesture, body: () => void): void;\n\n /**\n * Do something when a pin is pressed.\n * @param name the pin that needs to be pressed\n * @param body the code to run when the pin is pressed\n */\n //% help=input/on-pin-pressed weight=83\n //% blockId=device_pin_event block=\"on pin %NAME|pressed\" shim=input::onPinPressed\n function onPinPressed(name: TouchPin, body: () => void): void;\n\n /**\n * Do something when a pin is released.\n * @param name the pin that needs to be released\n * @param body the code to run when the pin is released\n */\n //% help=input/on-pin-released weight=6 blockGap=8\n //% blockId=device_pin_released block=\"on pin %NAME|released\"\n //% advanced=true shim=input::onPinReleased\n function onPinReleased(name: TouchPin, body: () => void): void;\n\n /**\n * Get the button state (pressed or not) for ``A`` and ``B``.\n */\n //% help=input/button-is-pressed weight=60\n //% block=\"button|%NAME|is pressed\"\n //% blockId=device_get_button2\n //% blockGap=8\n //% parts=\"buttonpair\" shim=input::buttonIsPressed\n function buttonIsPressed(button: Button): boolean;\n\n /**\n * Get the pin state (pressed or not). Requires to hold the ground to close the circuit.\n * @param name pin used to detect the touch\n */\n //% help=input/pin-is-pressed weight=58\n //% blockId=\"device_pin_is_pressed\" block=\"pin %NAME|is pressed\"\n //% blockGap=8 shim=input::pinIsPressed\n function pinIsPressed(name: TouchPin): boolean;\n\n /**\n * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up, x=0, y=0 and z=-1024)\n * @param dimension TODO\n */\n //% help=input/acceleration weight=58\n //% blockId=device_acceleration block=\"acceleration (mg)|%NAME\" blockGap=8\n //% parts=\"accelerometer\" shim=input::acceleration\n function acceleration(dimension: Dimension): number;\n\n /**\n * Reads the light level applied to the LED screen in a range from ``0`` (dark) to ``255`` bright.\n */\n //% help=input/light-level weight=57\n //% blockId=device_get_light_level block=\"light level\" blockGap=8\n //% parts=\"ledmatrix\" shim=input::lightLevel\n function lightLevel(): number;\n\n /**\n * Get the current compass heading in degrees.\n */\n //% help=input/compass-heading\n //% weight=56\n //% blockId=device_heading block=\"compass heading (°)\" blockGap=8\n //% parts=\"compass\" shim=input::compassHeading\n function compassHeading(): number;\n\n /**\n * Gets the temperature in Celsius degrees (°C).\n */\n //% weight=55\n //% help=input/temperature\n //% blockId=device_temperature block=\"temperature (°C)\" blockGap=8\n //% parts=\"thermometer\" shim=input::temperature\n function temperature(): number;\n\n /**\n * The pitch or roll of the device, rotation along the ``x-axis`` or ``y-axis``, in degrees.\n * @param kind TODO\n */\n //% help=input/rotation weight=52\n //% blockId=device_get_rotation block=\"rotation (°)|%NAME\" blockGap=8\n //% parts=\"accelerometer\" advanced=true shim=input::rotation\n function rotation(kind: Rotation): number;\n\n /**\n * Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the simulator.\n * @param dimension TODO\n */\n //% help=input/magnetic-force weight=51\n //% blockId=device_get_magnetic_force block=\"magnetic force (µT)|%NAME\" blockGap=8\n //% parts=\"compass\"\n //% advanced=true shim=input::magneticForce\n function magneticForce(dimension: Dimension): number;\n\n /**\n * Gets the number of milliseconds elapsed since power on.\n */\n //% help=input/running-time weight=50\n //% blockId=device_get_running_time block=\"running time (ms)\"\n //% advanced=true shim=input::runningTime\n function runningTime(): number;\n\n /**\n * Obsolete, compass calibration is automatic.\n */\n //% help=input/calibrate weight=0 shim=input::calibrate\n function calibrate(): void;\n\n /**\n * Sets the accelerometer sample range in gravities.\n * @param range a value describe the maximum strengh of acceleration measured\n */\n //% help=input/set-accelerometer-range\n //% blockId=device_set_accelerometer_range block=\"set accelerometer|range %range\"\n //% weight=5\n //% parts=\"accelerometer\"\n //% advanced=true shim=input::setAccelerometerRange\n function setAccelerometerRange(range: AcceleratorRange): void;\n}\n\n\n\n //% weight=1 color=\"#333333\"\n //% advanced=true\ndeclare namespace control {\n\n /**\n * Schedules code that run in the background.\n */\n //% help=control/in-background\n //% blockId=\"control_in_background\" block=\"run in background\" blockGap=8 shim=control::inBackground\n function inBackground(a: () => void): void;\n\n /**\n * Resets the BBC micro:bit.\n */\n //% weight=30 async help=control/reset blockGap=8\n //% blockId=\"control_reset\" block=\"reset\" shim=control::reset\n function reset(): void;\n\n /**\n * Blocks the current fiber for the given microseconds\n * @param micros number of micro-seconds to wait. eg: 4\n */\n //% help=control/wait-micros weight=29\n //% blockId=\"control_wait_us\" block=\"wait (µs)%micros\" shim=control::waitMicros\n function waitMicros(micros: number): void;\n\n /**\n * Raises an event in the event bus.\n * @param src ID of the MicroBit Component that generated the event e.g. MICROBIT_ID_BUTTON_A.\n * @param value Component specific code indicating the cause of the event.\n * @param mode optional definition of how the event should be processed after construction (default is CREATE_AND_FIRE).\n */\n //% weight=21 blockGap=12 blockId=\"control_raise_event\" block=\"raise event|from source %src=control_event_source_id|with value %value=control_event_value_id\" blockExternalInputs=1\n //% mode.defl=1 shim=control::raiseEvent\n function raiseEvent(src: number, value: number, mode?: EventCreationMode): void;\n\n /**\n * Raises an event in the event bus.\n */\n //% weight=20 blockGap=8 blockId=\"control_on_event\" block=\"on event|from %src=control_event_source_id|with value %value=control_event_value_id\"\n //% blockExternalInputs=1 shim=control::onEvent\n function onEvent(src: number, value: number, handler: () => void): void;\n\n /**\n * Gets the value of the last event executed on the bus\n */\n //% blockId=control_event_value\" block=\"event value\"\n //% weight=18 shim=control::eventValue\n function eventValue(): number;\n\n /**\n * Gets the timestamp of the last event executed on the bus\n */\n //% blockId=control_event_timestamp\" block=\"event timestamp\"\n //% weight=19 blockGap=8 shim=control::eventTimestamp\n function eventTimestamp(): number;\n\n /**\n * Gets a friendly name for the device derived from the its serial number\n */\n //% blockId=\"control_device_name\" block=\"device name\" weight=10 blockGap=8 shim=control::deviceName\n function deviceName(): string;\n\n /**\n * Derive a unique, consistent serial number of this device from internal data.\n */\n //% blockId=\"control_device_serial_number\" block=\"device serial number\" weight=9 shim=control::deviceSerialNumber\n function deviceSerialNumber(): number;\n}\n\n\n\n //% color=#8169E6 weight=35 icon=\"\\uf205\"\ndeclare namespace led {\n\n /**\n * Turn on the specified LED using x, y coordinates (x is horizontal, y is vertical). (0,0) is upper left.\n * @param x TODO\n * @param y TODO\n */\n //% help=led/plot weight=78\n //% blockId=device_plot block=\"plot|x %x|y %y\" blockGap=8\n //% parts=\"ledmatrix\" shim=led::plot\n function plot(x: number, y: number): void;\n\n /**\n * Turn off the specified LED using x, y coordinates (x is horizontal, y is vertical). (0,0) is upper left.\n * @param x TODO\n * @param y TODO\n */\n //% help=led/unplot weight=77\n //% blockId=device_unplot block=\"unplot|x %x|y %y\" blockGap=8\n //% parts=\"ledmatrix\" shim=led::unplot\n function unplot(x: number, y: number): void;\n\n /**\n * Get the on/off state of the specified LED using x, y coordinates. (0,0) is upper left.\n * @param x TODO\n * @param y TODO\n */\n //% help=led/point weight=76\n //% blockId=device_point block=\"point|x %x|y %y\"\n //% parts=\"ledmatrix\" shim=led::point\n function point(x: number, y: number): boolean;\n\n /**\n * Get the screen brightness from 0 (off) to 255 (full bright).\n */\n //% help=led/brightness weight=60\n //% blockId=device_get_brightness block=\"brightness\" blockGap=8\n //% parts=\"ledmatrix\"\n //% advanced=true shim=led::brightness\n function brightness(): number;\n\n /**\n * Set the screen brightness from 0 (off) to 255 (full bright).\n * @param value the brightness value, eg:255, 127, 0\n */\n //% help=led/set-brightness weight=59\n //% blockId=device_set_brightness block=\"set brightness %value\"\n //% parts=\"ledmatrix\"\n //% advanced=true shim=led::setBrightness\n function setBrightness(value: number): void;\n\n /**\n * Cancels the current animation and clears other pending animations.\n */\n //% weight=50 help=led/stop-animation\n //% blockId=device_stop_animation block=\"stop animation\"\n //% parts=\"ledmatrix\"\n //% advanced=true shim=led::stopAnimation\n function stopAnimation(): void;\n\n /**\n * Sets the display mode between black and white and greyscale for rendering LEDs.\n * @param mode mode the display mode in which the screen operates\n */\n //% weight=1 help=led/set-display-mode\n //% parts=\"ledmatrix\" advanced=true shim=led::setDisplayMode\n function setDisplayMode(mode: DisplayMode): void;\n\n /**\n * Turns on or off the display \n */\n //% help=led/enable blockId=device_led_enable\n //% advanced=true parts=\"ledmatrix\" shim=led::enable\n function enable(on: boolean): void;\n\n /**\n * Takes a screenshot of the LED screen and returns an image.\n */\n //% help=led/screenshot\n //% parts=\"ledmatrix\" shim=led::screenshot\n function screenshot(): Image;\n}\n\n\n /**\n * Blocks to control the onboard motors\n */\n //% color=#008272 weight=30 icon=\"\\uf1b9\"\ndeclare namespace motors {\n\n /**\n * Turns on the motor at a certain percent of power. Switches to single motor mode!\n * @param power %percent of power sent to the motor. Negative power goes backward. eg: 50\n */\n //% blockId=motor_on block=\"motor on at %percent\"\n //% parts=dcmotor weight=90 blockGap=8 shim=motors::motorPower\n function motorPower(power: number): void;\n\n /**\n * Send break, coast or sleep commands to the motor. Has no effect in dual-motor mode.\n */\n //% blockId=motor_command block=\"motor %command\"\n //% parts=dcmotor weight=85 shim=motors::motorCommand\n function motorCommand(command: MotorCommand): void;\n\n /**\n * Controls two motors attached to the board. Switches to dual-motor mode!\n */\n //% blockId=block_dual_motor block=\"motor %motor|at %percent\"\n //% weight=80 shim=motors::dualMotorPower\n function dualMotorPower(motor: Motor, duty_percent: number): void;\n}\ndeclare namespace music {\n\n /**\n * Plays a tone through ``speaker`` for the given duration.\n * @param frequency pitch of the tone to play in Hertz (Hz)\n * @param ms tone duration in milliseconds (ms)\n */\n //% help=music/play-tone weight=90\n //% blockId=device_play_note block=\"play|tone %note=device_note|for %duration=device_beat\" icon=\"\\uf025\" blockGap=8\n //% parts=\"speaker\" async useEnumVal=1 shim=music::playTone\n function playTone(frequency: number, ms: number): void;\n}\ndeclare namespace pins {\n\n /**\n * Read the specified pin or connector as either 0 or 1\n * @param name pin to read from\n */\n //% help=pins/digital-read-pin weight=30\n //% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8 shim=pins::digitalReadPin\n function digitalReadPin(name: DigitalPin): number;\n\n /**\n * Set a pin or connector value to either 0 or 1.\n * @param name pin to write to\n * @param value value to set on the pin, 1 eg,0\n */\n //% help=pins/digital-write-pin weight=29\n //% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value\" shim=pins::digitalWritePin\n function digitalWritePin(name: DigitalPin, value: number): void;\n\n /**\n * Read the connector value as analog, that is, as a value comprised between 0 and 1023.\n * @param name pin to write to\n */\n //% help=pins/analog-read-pin weight=25\n //% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\" shim=pins::analogReadPin\n function analogReadPin(name: AnalogPin): number;\n\n /**\n * Set the connector value as analog. Value must be comprised between 0 and 1023.\n * @param name pin name to write to\n * @param value value to write to the pin between ``0`` and ``1023``. eg:1023,0\n */\n //% help=pins/analog-write-pin weight=24\n //% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8 shim=pins::analogWritePin\n function analogWritePin(name: AnalogPin, value: number): void;\n\n /**\n * Configures the Pulse-width modulation (PWM) of the analog output to the given value in **microseconds** or `1/1000` milliseconds.\n * If this pin is not configured as an analog output (using `analog write pin`), the operation has no effect.\n * @param name analog pin to set period to\n * @param micros period in micro seconds. eg:20000\n */\n //% help=pins/analog-set-period weight=23 blockGap=8\n //% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%micros\" shim=pins::analogSetPeriod\n function analogSetPeriod(name: AnalogPin, micros: number): void;\n\n /**\n * Configures this pin to a digital input, and generates events where the timestamp is the duration that this pin was either ``high`` or ``low``.\n */\n //% help=pins/on-pulsed weight=22 blockGap=8\n //% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\" shim=pins::onPulsed\n function onPulsed(name: DigitalPin, pulse: PulseValue, body: () => void): void;\n\n /**\n * Gets the duration of the last pulse in micro-seconds. This function should be called from a ``onPulsed`` handler.\n */\n //% help=pins/pulse-duration\n //% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n //% weight=21 blockGap=8 shim=pins::pulseDuration\n function pulseDuration(): number;\n\n /**\n * Returns the duration of a pulse in microseconds\n * @param name the pin which measures the pulse\n * @param value the value of the pulse (default high)\n * @param maximum duration in micro-seconds\n */\n //% blockId=\"pins_pulse_in\" block=\"pulse in (µs)|pin %name|pulsed %value\"\n //% weight=20 maxDuration.defl=2000000 shim=pins::pulseIn\n function pulseIn(name: DigitalPin, value: PulseValue, maxDuration?: number): number;\n\n /**\n * Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one direction, ``180`` being full speed in the other, and a value near ``90`` being no movement).\n * @param name pin to write to\n * @param value angle or rotation speed, eg:180,90,0\n */\n //% help=pins/servo-write-pin weight=20\n //% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value\" blockGap=8\n //% parts=microservo trackArgs=0 shim=pins::servoWritePin\n function servoWritePin(name: AnalogPin, value: number): void;\n\n /**\n * Configures this IO pin as an analog/pwm output, configures the period to be 20 ms, and sets the pulse width, based on the value it is given **microseconds** or `1/1000` milliseconds.\n * @param name pin name\n * @param micros pulse duration in micro seconds, eg:1500\n */\n //% help=pins/servo-set-pulse weight=19\n //% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %micros\" shim=pins::servoSetPulse\n function servoSetPulse(name: AnalogPin, micros: number): void;\n\n /**\n * Sets the pin used when using `pins->analog pitch`.\n * @param name TODO\n */\n //% blockId=device_analog_set_pitch_pin block=\"analog set pitch pin %name\"\n //% help=pins/analog-set-pitch weight=3 advanced=true shim=pins::analogSetPitchPin\n function analogSetPitchPin(name: AnalogPin): void;\n\n /**\n * Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin.\n * @param frequency TODO\n * @param ms TODO\n */\n //% blockId=device_analog_pitch block=\"analog pitch %frequency|for (ms) %ms\"\n //% help=pins/analog-pitch weight=4 async advanced=true blockGap=8 shim=pins::analogPitch\n function analogPitch(frequency: number, ms: number): void;\n\n /**\n * Configures the pull of this pin.\n * @param name pin to set the pull mode on\n * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone \n */\n //% help=pins/set-pull weight=3\n //% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\" shim=pins::setPull\n function setPull(name: DigitalPin, pull: PinPullMode): void;\n\n /**\n * Configures the events emitted by this pin. Events can be subscribed to\n * using ``control.onEvent()``.\n * @param name pin to set the event mode on, eg: DigitalPin.P0\n * @param type the type of events for this pin to emit, eg: PinEventType.Edge\n */\n //% help=pins/set-events weight=4 advanced=true\n //% blockId=device_set_pin_events block=\"set pin %pin|to emit %type|events\" shim=pins::setEvents\n function setEvents(name: DigitalPin, type: PinEventType): void;\n\n /**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n //% shim=pins::createBuffer\n function createBuffer(size: number): Buffer;\n\n /**\n * Read `size` bytes from a 7-bit I2C `address`.\n */\n //% repeat.defl=0 shim=pins::i2cReadBuffer\n function i2cReadBuffer(address: number, size: number, repeat?: boolean): Buffer;\n\n /**\n * Write bytes to a 7-bit I2C `address`.\n */\n //% repeat.defl=0 shim=pins::i2cWriteBuffer\n function i2cWriteBuffer(address: number, buf: Buffer, repeat?: boolean): void;\n\n /**\n * Write to the SPI slave and return the response\n * @param value Data to be sent to the SPI slave\n */\n //% help=pins/spi-write weight=5\n //% blockId=spi_write block=\"spi write %value\" shim=pins::spiWrite\n function spiWrite(value: number): number;\n}\n\n\n\n //% weight=2 color=30\n //% advanced=true\ndeclare namespace serial {\n\n /**\n * Reads a line of text from the serial port and returns the buffer when the delimiter is met.\n * @param delimiter text delimiter that separates each text chunk\n */\n //% help=serial/read-until\n //% blockId=serial_read_until block=\"serial|read until %delimiter=serial_delimiter_conv\"\n //% weight=19 shim=serial::readUntil\n function readUntil(delimiter: string): string;\n\n /**\n * Reads the buffered received data as a string\n */\n //% blockId=serial_read_buffer block=\"serial|read string\"\n //% weight=18 shim=serial::readString\n function readString(): string;\n\n /**\n * Registers an event to be fired when one of the delimiter is matched.\n * @param delimiters the characters to match received characters against.\n */\n //% help=serial/on-data-received\n //% weight=18 blockId=serial_on_data_received block=\"serial|on data received %delimiters=serial_delimiter_conv\" shim=serial::onDataReceived\n function onDataReceived(delimiters: string, body: () => void): void;\n\n /**\n * Sends a piece of text through Serial connection.\n */\n //% help=serial/write-string\n //% weight=87\n //% blockId=serial_writestring block=\"serial|write string %text\" shim=serial::writeString\n function writeString(text: string): void;\n\n /**\n * Dynamically configuring the serial instance to use pins other than USBTX and USBRX.\n * @param tx the new transmission pins, eg: SerialPin.P0\n * @param rx the new reception pin, eg: SerialPin.P1\n * @param rate the new baud rate. eg: 115200\n */\n //% weight=10\n //% help=serial/redirect-to\n //% blockId=serial_redirect block=\"serial|redirect to|TX %tx|RX %rx|at baud rate %rate\"\n //% blockExternalInputs=1 shim=serial::redirect\n function redirect(tx: SerialPin, rx: SerialPin, rate: BaudRate): void;\n}\n\n\n\n //% indexerGet=BufferMethods::getByte indexerSet=BufferMethods::setByte\ndeclare interface Buffer {\n /**\n * Write a number in specified format in the buffer.\n */\n //% shim=BufferMethods::setNumber\n setNumber(format: NumberFormat, offset: number, value: number): void;\n\n /**\n * Read a number in specified format from the buffer.\n */\n //% shim=BufferMethods::getNumber\n getNumber(format: NumberFormat, offset: number): number;\n\n /** Returns the length of a Buffer object. */\n //% property shim=BufferMethods::length\n length: number;\n\n /**\n * Fill (a fragment) of the buffer with given value.\n */\n //% offset.defl=0 length.defl=-1 shim=BufferMethods::fill\n fill(value: number, offset?: number, length?: number): void;\n\n /**\n * Return a copy of a fragment of a buffer.\n */\n //% offset.defl=0 length.defl=-1 shim=BufferMethods::slice\n slice(offset?: number, length?: number): Buffer;\n\n /**\n * Shift buffer left in place, with zero padding.\n * @param offset number of bytes to shift; use negative value to shift right\n * @param start start offset in buffer. Default is 0.\n * @param length number of elements in buffer. If negative, length is set as the buffer length minus start. eg: -1\n */\n //% start.defl=0 length.defl=-1 shim=BufferMethods::shift\n shift(offset: number, start?: number, length?: number): void;\n\n /**\n * Rotate buffer left in place.\n * @param offset number of bytes to shift; use negative value to shift right\n * @param start start offset in buffer. Default is 0.\n * @param length number of elements in buffer. If negative, length is set as the buffer length minus start. eg: -1\n */\n //% start.defl=0 length.defl=-1 shim=BufferMethods::rotate\n rotate(offset: number, start?: number, length?: number): void;\n\n /**\n * Write contents of `src` at `dstOffset` in current buffer.\n */\n //% shim=BufferMethods::write\n write(dstOffset: number, src: Buffer): void;\n}\n\n// Auto-generated. Do not edit. Really.\n"
},
"radio": {
"README.md": "# radio\n\nThe radio library.\n\n",
"_locales/de/radio-jsdoc-strings.json": "{\n \"radio\": \"Daten mithilfe von Funk-Paketen übertragen\",\n \"radio.onDataPacketReceived\": \"Registriert Funktionen, die ausgeführt werden, wenn das Radio ein Datenpaket empfängt. Entnimmt das empfangene Paket aus der Warteschlange des Radios.\",\n \"radio.onDataReceived\": \"Registriert Code der ausgeführt wird, wenn ein Paket über Funk empfangen wird.\",\n \"radio.receiveNumber\": \"Liest das nächste Paket aus der Funk-Warteschlange und gibt die Paketnummer oder 0 aus, wenn das Paket keine Nummer enthält.\",\n \"radio.receiveString\": \"Liest das nächste Paket aus der Funk-Warteschlange und gibt die enthaltene Zeichenfolge oder die leere Zeichenfolge aus, wenn das Paket keine Zeichenfolge enthält.\",\n \"radio.receivedNumber\": \"Extrahiert eine Zahl aus dem Inhalt des letzten Datenpakets, welches aus der Warteschlange des Radios (via ``Zahl empfangen``, ``Zeichenkette empfangen``, etc) entnommen wurde oder eine 0, wenn das Paket keine Zahl enthält.\",\n \"radio.receivedSerial\": \"Extrahiert die Seriennummer des Calliope mini Senders aus dem Inhalt des letzten Datenpakets, welches aus der Warteschlange des Radios entnommen wurde oder eine 0, wenn der Absender keine Seriennummer gesendet hat.\",\n \"radio.receivedSignalStrength\": \"Ruft den empfangenen Signalstärkeindikator (RSSI) aus dem letzten Paket aus der Funk-Warteschlange aus (via ``receiveNumber``, ``receiveString``, etc). Wird im Simulator nicht unterstützt.\\nnamespace=radio\",\n \"radio.receivedString\": \"Extrahiert die Zeichenkette aus dem Inhalt des letzten Datenpakets, welches aus der Warteschlange des Radios (via ``Zahl empfangen``, ``Zeichenkette empfangen``, etc) entnommen wurde oder eine leere Zeichenkette, wenn das Paket keine Zeichenkette enthält.\",\n \"radio.receivedTime\": \"Extrahiert die Systemzeit des Absenders aus dem Inhalt des letzten Datenpakets, welches aus der Warteschlange des Radios (via ``Zahl empfangen``, ``Zeichenkette empfangen``, etc) entnommen wurde.\",\n \"radio.sendNumber\": \"Überträgt eine Nummer über Funk an jeden angeschlossenen mini in der Gruppe.\",\n \"radio.sendString\": \"Überträgt eine Zeichenfolge über Funk mit Seriennummer des Geräts und Laufzeit an jeden angeschlossenen mini in der Gruppe.\",\n \"radio.sendValue\": \"Sendet ein Name / Wert-Paar zusammen mit der Seriennummer des Geräts und die Laufzeit auf alle angeschlossenen minis in der Gruppe.\",\n \"radio.sendValue|param|value\": \"der numerische Wert\",\n \"radio.setGroup\": \"Setzt die Gruppen-ID für Funkverbindungen. Ein mini kann nur ein Gruppen-ID hören.\\nDie Gruppen-ID zwischen liegt zwischen 0 und 255, z.B. 1\",\n \"radio.setTransmitPower\": \"Ändere die Ausgabeleistung des Senders auf den angegebenen Wert.\",\n \"radio.setTransmitPower|param|power\": \"ein Wert im Bereich 0.. 7, wo 0 die niedrigste Leistung und 7 ist ist die höchste. z.B. 7\",\n \"radio.setTransmitSerialNumber\": \"Stelle den Dunk so ein, dass die Seriennummer in jeder Nachricht übertragen wird.\",\n \"radio.setTransmitSerialNumber|param|transmit\": \"Wert, der anzeigt, ob die Seriennummer übertragen wird, z.B. wahr\",\n \"radio.writeReceivedPacketToSerial\": \"Schreibt das letzte empfangene Paket als JSON auf Seriell. Sollte in einem ´´onDataPacketReceived``-Callback aufgerufen werden.\",\n \"radio.writeValueToSerial\": \"Liest das nächste Paket aus der Funk-Warteschlange und schreibt dieses als JSON auf Seriell.\"\n}",
"_locales/de/radio-strings.json": "{\n \"radio.onDataPacketReceived|block\": \"wenn Datenpaket empfangen\",\n \"radio.onDataReceived|block\": \"Funk auf empfangenen Daten\",\n \"radio.receiveNumber|block\": \"empfange Nummer über Funk\",\n \"radio.receiveString|block\": \"empfange Zeichenfolge über Funk\",\n \"radio.receivedSignalStrength|block\": \"über Funk empfangene Signalstärke\",\n \"radio.sendNumber|block\": \"sende Nummer %value über Funk\",\n \"radio.sendString|block\": \"sende Zeichenfolge %msg über Funk\",\n \"radio.sendValue|block\": \"schicke |Wert %name|= %value über Funk\",\n \"radio.setGroup|block\": \"setze Gruppe %ID über Funk\",\n \"radio.setTransmitPower|block\": \"setze Übertragungsstärke %power über Funk\",\n \"radio.setTransmitSerialNumber|block\": \"setze Übertragungsseriennummer %transmit über Funk\",\n \"radio.writeReceivedPacketToSerial|block\": \"schreibe das über Funk übertragene Paket auf Seriell\",\n \"radio.writeValueToSerial|block\": \"schreibe Wert über Funk auf Seriell\",\n \"radio|block\": \"Funk\",\n \"{id:category}Radio\": \"Funk\"\n}",
"enums.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace radio {\n}\n\n// Auto-generated. Do not edit. Really.\n",
"pxt.json": "{\n \"name\": \"radio\",\n \"description\": \"The radio services\",\n \"files\": [\n \"README.md\",\n \"shims.d.ts\",\n \"enums.d.ts\",\n \"radio.cpp\",\n \"radio.ts\",\n \"_locales/de/radio-jsdoc-strings.json\",\n \"_locales/de/radio-strings.json\"\n ],\n \"public\": true,\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"yotta\": {\n \"config\": {\n \"microbit-dal\": {\n \"bluetooth\": {\n \"enabled\": 0\n }\n }\n }\n }\n}",
"radio.cpp": "#include \"pxt.h\"\n\nusing namespace pxt;\n\n#define MAX_FIELD_NAME_LENGTH 12\n#define MAX_PAYLOAD_LENGTH 20\n#define PACKET_PREFIX_LENGTH 9\n#define VALUE_PACKET_NAME_LEN_OFFSET 13\n\n\n// Packet Spec:\n// | 0 | 1 ... 4 | 5 ... 8 | 9 ... 28\n// ----------------------------------------------------------------\n// | packet type | system time | serial number | payload\n//\n// Serial number defaults to 0 unless enabled by user\n\n// payload: number (9 ... 12)\n#define PACKET_TYPE_NUMBER 0\n\n// payload: number (9 ... 12), name length (13), name (14 ... 26)\n#define PACKET_TYPE_VALUE 1\n\n// payload: string length (9), string (10 ... 28)\n#define PACKET_TYPE_STRING 2\n\n//% color=270 weight=34\nnamespace radio {\n\n // -------------------------------------------------------------------------\n // Radio\n // -------------------------------------------------------------------------\n bool radioEnabled = false;\n bool transmitSerialNumber = false;\n\n PacketBuffer packet;\n\n uint8_t type;\n uint32_t time;\n uint32_t serial;\n int value;\n StringData* msg;\n\n int radioEnable() {\n int r = uBit.radio.enable();\n if (r != MICROBIT_OK) {\n uBit.panic(43);\n return r;\n }\n if (!radioEnabled) {\n uBit.radio.setGroup(pxt::programHash());\n radioEnabled = true;\n }\n return r;\n }\n\n void broadcastMessage(int message) {\n if (radioEnable() != MICROBIT_OK) return;\n uBit.radio.event.eventReceived(MicroBitEvent(MES_BROADCAST_GENERAL_ID, message, CREATE_ONLY));\n }\n\n void onBroadcastMessageReceived(int message, Action f) {\n if (radioEnable() != MICROBIT_OK) return;\n registerWithDal(MES_BROADCAST_GENERAL_ID, message, f);\n }\n\n void setPacketPrefix(uint8_t* buf, int type) {\n // prefix: type (0), time (1..4), serial (5..8)\n uint32_t t = system_timer_current_time();\n uint32_t sn = transmitSerialNumber ? microbit_serial_number() : 0;\n\n buf[0] = (uint8_t) type;\n memcpy(buf + 1, &t, 4);\n memcpy(buf + 5, &sn, 4);\n }\n\n uint8_t copyStringValue(uint8_t* buf, StringData* data, uint8_t maxLength) {\n ManagedString s(data);\n uint8_t len = min(maxLength, s.length());\n\n // One byte for length of the string\n buf[0] = len;\n\n if (len > 0) {\n memcpy(buf + 1, s.toCharArray(), len);\n }\n return len + 1;\n }\n\n StringData* getStringValue(uint8_t* buf, uint8_t maxLength) {\n // First byte is the string length\n uint8_t len = min(maxLength, buf[0]);\n\n if (len) {\n char name[maxLength + 1];\n memcpy(name, buf + 1, len);\n name[len] = 0;\n return ManagedString(name).leakData();\n }\n return ManagedString().leakData();\n }\n\n void writePacketAsJSON(uint8_t tp, int v, int s, int t, StringData* m) {\n // Convert the packet to JSON and send over serial\n uBit.serial.send(\"{\");\n uBit.serial.send(\"\\\"t\\\":\");\n uBit.serial.send(t);\n uBit.serial.send(\",\\\"s\\\":\");\n uBit.serial.send(s);\n if (tp == PACKET_TYPE_STRING || tp == PACKET_TYPE_VALUE) {\n uBit.serial.send(\",\\\"n\\\":\\\"\");\n uBit.serial.send(m);\n uBit.serial.send(\"\\\"\");\n }\n if (tp == PACKET_TYPE_NUMBER || tp == PACKET_TYPE_VALUE) {\n uBit.serial.send(\",\\\"v\\\":\");\n uBit.serial.send(v);\n }\n uBit.serial.send(\"}\\r\\n\");\n }\n\n /**\n * Takes a packet from the micro:bit radio queue.\n * @param writeToSerial if true, write the received packet to serial without updating the global packet;\n if false, update the global packet instead\n */\n void receivePacket(bool writeToSerial) {\n PacketBuffer p = uBit.radio.datagram.recv();\n\n uint8_t* buf = p.getBytes();\n uint8_t tp;\n int t;\n int s;\n int v;\n StringData* m;\n\n\n memcpy(&tp, buf, 1);\n memcpy(&t, buf + 1, 4);\n memcpy(&s, buf + 5, 4);\n\n if (tp == PACKET_TYPE_STRING) {\n v = 0;\n m = getStringValue(buf + PACKET_PREFIX_LENGTH, MAX_PAYLOAD_LENGTH - 1);\n }\n else {\n memcpy(&v, buf + 9, 4);\n if (tp == PACKET_TYPE_VALUE) {\n m = getStringValue(buf + VALUE_PACKET_NAME_LEN_OFFSET, MAX_FIELD_NAME_LENGTH);\n }\n else {\n m = ManagedString().leakData();\n }\n }\n\n if (!writeToSerial) {\n // Refresh global packet\n packet = p;\n type = tp;\n time = t;\n serial = s;\n value = v;\n msg = m;\n }\n else {\n writePacketAsJSON(tp, v, s, t, m);\n }\n }\n\n /**\n * Broadcasts a number over radio to any connected micro:bit in the group.\n */\n //% help=radio/send-number\n //% weight=60\n //% blockId=radio_datagram_send block=\"radio send number %value\" blockGap=8\n void sendNumber(int value) {\n if (radioEnable() != MICROBIT_OK) return;\n uint8_t length = PACKET_PREFIX_LENGTH + sizeof(uint32_t);\n uint8_t buf[length];\n memset(buf, 0, length);\n\n setPacketPrefix(buf, PACKET_TYPE_NUMBER);\n memcpy(buf + PACKET_PREFIX_LENGTH, &value, 4);\n\n uBit.radio.datagram.send(buf, length);\n }\n\n /**\n * Broadcasts a name / value pair along with the device serial number\n * and running time to any connected micro:bit in the group.\n * @param name the field name (max 12 characters), eg: \"name\"\n * @param value the numberic value\n */\n //% help=radio/send-value\n //% weight=59\n //% blockId=radio_datagram_send_value block=\"radio send|value %name|= %value\" blockGap=8\n void sendValue(StringData* name, int value) {\n if (radioEnable() != MICROBIT_OK) return;\n\n ManagedString n(name);\n uint8_t buf[32];\n memset(buf, 0, 32);\n\n setPacketPrefix(buf, PACKET_TYPE_VALUE);\n memcpy(buf + PACKET_PREFIX_LENGTH, &value, 4);\n\n int stringLen = copyStringValue(buf + VALUE_PACKET_NAME_LEN_OFFSET, name, MAX_FIELD_NAME_LENGTH);\n\n uBit.radio.datagram.send(buf, VALUE_PACKET_NAME_LEN_OFFSET + stringLen);\n }\n\n /**\n * Broadcasts a string along with the device serial number\n * and running time to any connected micro:bit in the group.\n */\n //% help=radio/send-string\n //% weight=58\n //% blockId=radio_datagram_send_string block=\"radio send string %msg\"\n void sendString(StringData* msg) {\n if (radioEnable() != MICROBIT_OK) return;\n\n uint8_t buf[32];\n memset(buf, 0, 32);\n\n setPacketPrefix(buf, PACKET_TYPE_STRING);\n int stringLen = copyStringValue(buf + PACKET_PREFIX_LENGTH, msg, MAX_PAYLOAD_LENGTH - 1);\n\n uBit.radio.datagram.send(buf, PACKET_PREFIX_LENGTH + stringLen);\n }\n\n /**\n * Reads the next packet from the radio queue and and writes it to serial\n * as JSON.\n */\n //% help=radio/write-value-to-serial\n //% weight=3\n //% blockId=radio_write_value_serial block=\"radio write value to serial\"\n //% deprecated=true\n void writeValueToSerial() {\n if (radioEnable() != MICROBIT_OK) return;\n receivePacket(true);\n }\n\n /**\n * Writes the last received packet to serial as JSON. This should be called\n * within an ``onDataPacketReceived`` callback.\n */\n //% help=radio/write-received-packet-to-serial\n //% weight=3\n //% blockId=radio_write_packet_serial block=\"radio write received packet to serial\"\n //% advanced=true\n void writeReceivedPacketToSerial() {\n if (radioEnable() != MICROBIT_OK) return;\n writePacketAsJSON(type, value, (int) serial, (int) time, msg);\n }\n\n /**\n * Reads the next packet from the radio queue and returns the packet's number\n * payload or 0 if the packet did not contain a number.\n */\n //% help=radio/receive-number\n //% weight=46\n //% blockId=radio_datagram_receive block=\"radio receive number\" blockGap=8\n //% deprecated=true\n int receiveNumber()\n {\n if (radioEnable() != MICROBIT_OK) return 0;\n receivePacket(false);\n return value;\n }\n\n /**\n * Registers code to run when a packet is received over radio.\n */\n //% help=radio/on-data-received\n //% weight=50\n //% blockId=radio_datagram_received_event block=\"radio on data received\" blockGap=8\n //% deprecated=true\n void onDataReceived(Action body) {\n if (radioEnable() != MICROBIT_OK) return;\n registerWithDal(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, body);\n // make sure the receive buffer has a free spot\n receiveNumber();\n }\n\n\n /**\n * Reads the next packet from the radio queue and returns the packet's string\n * payload or the empty string if the packet did not contain a string.\n */\n //% blockId=radio_datagram_receive_string block=\"radio receive string\" blockGap=8\n //% weight=44\n //% help=radio/receive-string\n //% deprecated=true\n StringData* receiveString() {\n if (radioEnable() != MICROBIT_OK) return ManagedString().leakData();\n receivePacket(false);\n return msg;\n }\n\n /**\n * Gets the received signal strength indicator (RSSI) from the last packet taken\n * from the radio queue (via ``receiveNumber``, ``receiveString``, etc). Not supported in simulator.\n * namespace=radio\n */\n //% help=radio/received-signal-strength\n //% weight=40\n //% blockId=radio_datagram_rssi block=\"radio received signal strength\"\n //% deprecated=true\n int receivedSignalStrength() {\n if (radioEnable() != MICROBIT_OK) return 0;\n return packet.getRSSI();\n }\n\n /**\n * Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time.\n * @ param id the group id between ``0`` and ``255``, 1 eg\n */\n //% help=radio/set-group\n //% weight=10 blockGap=8 advanced=true\n //% blockId=radio_set_group block=\"radio set group %ID\"\n void setGroup(int id) {\n if (radioEnable() != MICROBIT_OK) return;\n uBit.radio.setGroup(id);\n }\n\n /**\n * Change the output power level of the transmitter to the given value.\n * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7\n */\n //% help=radio/set-transmit-power\n //% weight=9 blockGap=8\n //% blockId=radio_set_transmit_power block=\"radio set transmit power %power\"\n //% advanced=true\n void setTransmitPower(int power) {\n if (radioEnable() != MICROBIT_OK) return;\n uBit.radio.setTransmitPower(power);\n }\n\n /**\n * Set the radio to transmit the serial number in each message.\n * @param transmit value indicating if the serial number is transmitted, eg: true\n */\n //% help=radio/set-transmit-serial-number\n //% weight=8 blockGap=8\n //% blockId=radio_set_transmit_serial_number block=\"radio set transmit serial number %transmit\"\n //% advanced=true\n void setTransmitSerialNumber(bool transmit) {\n if (radioEnable() != MICROBIT_OK) return;\n transmitSerialNumber = transmit;\n }\n\n /**\n * Returns the number payload from the last packet taken from the radio queue\n * (via ``receiveNumber``, ``receiveString``, etc) or 0 if that packet did not\n * contain a number.\n */\n //% help=radio/received-number\n int receivedNumber() {\n if (radioEnable() != MICROBIT_OK) return 0;\n return value;\n }\n\n /**\n * Returns the serial number of the sender micro:bit from the last packet taken\n * from the radio queue (via ``receiveNumber``, ``receiveString``, etc) or 0 if\n * that packet did not send a serial number.\n */\n //% help=radio/received-serial\n uint32_t receivedSerial() {\n if (radioEnable() != MICROBIT_OK) return 0;\n return serial;\n }\n\n /**\n * Returns the string payload from the last packet taken from the radio queue\n * (via ``receiveNumber``, ``receiveString``, etc) or the empty string if that\n * packet did not contain a string.\n */\n //% help=radio/received-string\n StringData* receivedString() {\n if (radioEnable() != MICROBIT_OK) return ManagedString().leakData();\n return msg;\n }\n\n /**\n * Returns the system time of the sender micro:bit at the moment when it sent the\n * last packet taken from the radio queue (via ``receiveNumber``,\n * ``receiveString``, etc).\n */\n //% help=radio/received-time\n uint32_t receivedTime() {\n if (radioEnable() != MICROBIT_OK) return 0;\n return time;\n }\n}\n",
"radio.ts": "/**\n * Communicate data using radio packets\n */\n//% color=#E3008C weight=34 icon=\"\\uf012\"\nnamespace radio {\n export class Packet {\n /**\n * The number payload if a number was sent in this packet (via ``sendNumber()`` or ``sendValue()``)\n * or 0 if this packet did not contain a number.\n */\n public receivedNumber: number;\n /**\n * The string payload if a string was sent in this packet (via ``sendString()`` or ``sendValue()``)\n * or the empty string if this packet did not contain a string.\n */\n public receivedString: string;\n /**\n * The system time of the sender of the packet at the time the packet was sent.\n */\n public time: number;\n /**\n * The serial number of the sender of the packet or 0 if the sender did not sent their serial number.\n */\n public serial: number;\n /**\n * The received signal strength indicator (RSSI) of the packet.\n */\n public signal: number;\n }\n\n /**\n * Registers code to run when the radio receives a packet. Also takes the\n * received packet from the radio queue.\n */\n //% help=radio/on-data-packet-received\n //% mutate=objectdestructuring\n //% mutateText=Packet\n //% mutateDefaults=\"receivedNumber;receivedString:name,receivedNumber:value;receivedString\"\n //% blockId=radio_on_packet block=\"on radio received\" blockGap=8\n export function onDataPacketReceived(cb: (packet: Packet) => void) {\n onDataReceived(() => {\n receiveNumber();\n const packet = new Packet();\n packet.receivedNumber = receivedNumber();\n packet.time = receivedTime();\n packet.serial = receivedSerial();\n packet.receivedString = receivedString();\n packet.signal = receivedSignalStrength();\n cb(packet)\n });\n }\n}\n",
"shims.d.ts": "// Auto-generated. Do not edit.\n\n\n\n //% color=270 weight=34\ndeclare namespace radio {\n\n /**\n * Broadcasts a number over radio to any connected micro:bit in the group.\n */\n //% help=radio/send-number\n //% weight=60\n //% blockId=radio_datagram_send block=\"radio send number %value\" blockGap=8 shim=radio::sendNumber\n function sendNumber(value: number): void;\n\n /**\n * Broadcasts a name / value pair along with the device serial number\n * and running time to any connected micro:bit in the group.\n * @param name the field name (max 12 characters), eg: \"name\"\n * @param value the numberic value\n */\n //% help=radio/send-value\n //% weight=59\n //% blockId=radio_datagram_send_value block=\"radio send|value %name|= %value\" blockGap=8 shim=radio::sendValue\n function sendValue(name: string, value: number): void;\n\n /**\n * Broadcasts a string along with the device serial number\n * and running time to any connected micro:bit in the group.\n */\n //% help=radio/send-string\n //% weight=58\n //% blockId=radio_datagram_send_string block=\"radio send string %msg\" shim=radio::sendString\n function sendString(msg: string): void;\n\n /**\n * Reads the next packet from the radio queue and and writes it to serial\n * as JSON.\n */\n //% help=radio/write-value-to-serial\n //% weight=3\n //% blockId=radio_write_value_serial block=\"radio write value to serial\"\n //% deprecated=true shim=radio::writeValueToSerial\n function writeValueToSerial(): void;\n\n /**\n * Writes the last received packet to serial as JSON. This should be called\n * within an ``onDataPacketReceived`` callback.\n */\n //% help=radio/write-received-packet-to-serial\n //% weight=3\n //% blockId=radio_write_packet_serial block=\"radio write received packet to serial\"\n //% advanced=true shim=radio::writeReceivedPacketToSerial\n function writeReceivedPacketToSerial(): void;\n\n /**\n * Reads the next packet from the radio queue and returns the packet's number\n * payload or 0 if the packet did not contain a number.\n */\n //% help=radio/receive-number\n //% weight=46\n //% blockId=radio_datagram_receive block=\"radio receive number\" blockGap=8\n //% deprecated=true shim=radio::receiveNumber\n function receiveNumber(): number;\n\n /**\n * Registers code to run when a packet is received over radio.\n */\n //% help=radio/on-data-received\n //% weight=50\n //% blockId=radio_datagram_received_event block=\"radio on data received\" blockGap=8\n //% deprecated=true shim=radio::onDataReceived\n function onDataReceived(body: () => void): void;\n\n /**\n * Reads the next packet from the radio queue and returns the packet's string\n * payload or the empty string if the packet did not contain a string.\n */\n //% blockId=radio_datagram_receive_string block=\"radio receive string\" blockGap=8\n //% weight=44\n //% help=radio/receive-string\n //% deprecated=true shim=radio::receiveString\n function receiveString(): string;\n\n /**\n * Gets the received signal strength indicator (RSSI) from the last packet taken\n * from the radio queue (via ``receiveNumber``, ``receiveString``, etc). Not supported in simulator.\n * namespace=radio\n */\n //% help=radio/received-signal-strength\n //% weight=40\n //% blockId=radio_datagram_rssi block=\"radio received signal strength\"\n //% deprecated=true shim=radio::receivedSignalStrength\n function receivedSignalStrength(): number;\n\n /**\n * Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time.\n * @ param id the group id between ``0`` and ``255``, 1 eg\n */\n //% help=radio/set-group\n //% weight=10 blockGap=8 advanced=true\n //% blockId=radio_set_group block=\"radio set group %ID\" shim=radio::setGroup\n function setGroup(id: number): void;\n\n /**\n * Change the output power level of the transmitter to the given value.\n * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7\n */\n //% help=radio/set-transmit-power\n //% weight=9 blockGap=8\n //% blockId=radio_set_transmit_power block=\"radio set transmit power %power\"\n //% advanced=true shim=radio::setTransmitPower\n function setTransmitPower(power: number): void;\n\n /**\n * Set the radio to transmit the serial number in each message.\n * @param transmit value indicating if the serial number is transmitted, eg: true\n */\n //% help=radio/set-transmit-serial-number\n //% weight=8 blockGap=8\n //% blockId=radio_set_transmit_serial_number block=\"radio set transmit serial number %transmit\"\n //% advanced=true shim=radio::setTransmitSerialNumber\n function setTransmitSerialNumber(transmit: boolean): void;\n\n /**\n * Returns the number payload from the last packet taken from the radio queue\n * (via ``receiveNumber``, ``receiveString``, etc) or 0 if that packet did not\n * contain a number.\n */\n //% help=radio/received-number shim=radio::receivedNumber\n function receivedNumber(): number;\n\n /**\n * Returns the serial number of the sender micro:bit from the last packet taken\n * from the radio queue (via ``receiveNumber``, ``receiveString``, etc) or 0 if\n * that packet did not send a serial number.\n */\n //% help=radio/received-serial shim=radio::receivedSerial\n function receivedSerial(): number;\n\n /**\n * Returns the string payload from the last packet taken from the radio queue\n * (via ``receiveNumber``, ``receiveString``, etc) or the empty string if that\n * packet did not contain a string.\n */\n //% help=radio/received-string shim=radio::receivedString\n function receivedString(): string;\n\n /**\n * Returns the system time of the sender micro:bit at the moment when it sent the\n * last packet taken from the radio queue (via ``receiveNumber``,\n * ``receiveString``, etc).\n */\n //% help=radio/received-time shim=radio::receivedTime\n function receivedTime(): number;\n}\n\n// Auto-generated. Do not edit. Really.\n"
},
"devices": {
"README.md": "# devices\n",
"devices.cpp": "#include \"pxt.h\"\n#include \"MESEvents.h\"\n\nusing namespace pxt;\n\nenum class MesCameraEvent {\n //% block=\"take photo\"\n TakePhoto = MES_CAMERA_EVT_TAKE_PHOTO,\n //% block=\"start video capture\"\n StartVideoCapture = MES_CAMERA_EVT_START_VIDEO_CAPTURE,\n //% block=\"stop video capture\"\n StopVideoCapture = MES_CAMERA_EVT_STOP_VIDEO_CAPTURE,\n //% block=\"toggle front-rear\"\n ToggleFrontRear = MES_CAMERA_EVT_TOGGLE_FRONT_REAR,\n //% block=\"launch photo mode\"\n LaunchPhotoMode = MES_CAMERA_EVT_LAUNCH_PHOTO_MODE,\n //% block=\"launch video mode\"\n LaunchVideoMode = MES_CAMERA_EVT_LAUNCH_VIDEO_MODE,\n //% block=\"stop photo mode\"\n StopPhotoMode = MES_CAMERA_EVT_STOP_PHOTO_MODE,\n //% block=\"stop video mode\"\n StopVideoMode = MES_CAMERA_EVT_STOP_VIDEO_MODE,\n};\n\nenum class MesAlertEvent {\n //% block=\"display toast\"\n DisplayToast = MES_ALERT_EVT_DISPLAY_TOAST,\n //% block=\"vibrate\"\n Vibrate = MES_ALERT_EVT_VIBRATE,\n //% block=\"play sound\"\n PlaySound = MES_ALERT_EVT_PLAY_SOUND,\n //% block=\"play ring tone\"\n PlayRingtone = MES_ALERT_EVT_PLAY_RINGTONE,\n //% block=\"find my phone\"\n FindMyPhone = MES_ALERT_EVT_FIND_MY_PHONE,\n //% block=\"ring alarm\"\n RingAlarm = MES_ALERT_EVT_ALARM1,\n //% block=\"ring alarm 2\"\n RingAlarm2 = MES_ALERT_EVT_ALARM2,\n //% block=\"ring alarm 3\"\n RingAlarm3 = MES_ALERT_EVT_ALARM3,\n //% block=\"ring alarm 4\"\n RingAlarm4 = MES_ALERT_EVT_ALARM4,\n //% block=\"ring alarm 5\"\n RingAlarm5 = MES_ALERT_EVT_ALARM5,\n //% block=\"ring alarm 6\"\n RingAlarm6 = MES_ALERT_EVT_ALARM6,\n};\n\nenum class MesDeviceInfo {\n //% block=\"incoming call\"\n IncomingCall = MES_DEVICE_INCOMING_CALL,\n //% block=\"incoming message\"\n IncomingMessage = MES_DEVICE_INCOMING_MESSAGE,\n //% block=\"orientation landscape\"\n OrientationLandscape = MES_DEVICE_ORIENTATION_LANDSCAPE,\n //% block=\"orientation portrait\"\n OrientationPortrait = MES_DEVICE_ORIENTATION_PORTRAIT,\n //% block=\"shaken\"\n Shaken = MES_DEVICE_GESTURE_DEVICE_SHAKEN,\n //% block=\"display off\"\n DisplayOff = MES_DEVICE_DISPLAY_OFF,\n //% block=\"display on\"\n DisplayOn = MES_DEVICE_DISPLAY_ON,\n};\n\nenum class MesRemoteControlEvent {\n //% block=\"play\"\n play = MES_REMOTE_CONTROL_EVT_PLAY,\n //% block=\"pause\"\n pause = MES_REMOTE_CONTROL_EVT_PAUSE,\n //% block=\"stop\"\n stop = MES_REMOTE_CONTROL_EVT_STOP,\n //% block=\"next track\"\n nextTrack = MES_REMOTE_CONTROL_EVT_NEXTTRACK,\n //% block=\"previous track\"\n previousTrack = MES_REMOTE_CONTROL_EVT_PREVTRACK,\n //% block=\"forward\"\n forward = MES_REMOTE_CONTROL_EVT_FORWARD,\n //% block=\"rewind\"\n rewind = MES_REMOTE_CONTROL_EVT_REWIND,\n //% block=\"volume up\"\n volumeUp = MES_REMOTE_CONTROL_EVT_VOLUMEUP,\n //% block=\"volume down\"\n volumeDown = MES_REMOTE_CONTROL_EVT_VOLUMEDOWN,\n};\n\nenum class MesDpadButtonInfo {\n //% block=\"A down\"\n ADown = MES_DPAD_BUTTON_A_DOWN,\n //% block=\"A up\"\n AUp = MES_DPAD_BUTTON_A_UP,\n //% block=\"B down\"\n BDown = MES_DPAD_BUTTON_B_DOWN,\n //% block=\"B up\"\n BUp = MES_DPAD_BUTTON_B_UP,\n //% block=\"C down\"\n CDown = MES_DPAD_BUTTON_C_DOWN,\n //% block=\"C up\"\n CUp = MES_DPAD_BUTTON_C_UP,\n //% block=\"D down\"\n DDown = MES_DPAD_BUTTON_D_DOWN,\n //% block=\"D up\"\n DUp = MES_DPAD_BUTTON_D_UP,\n //% block=\"1 down\"\n _1Down = MES_DPAD_BUTTON_1_UP,\n //% block=\"1 up\"\n _1Up = MES_DPAD_BUTTON_1_DOWN,\n //% block=\"2 down\"\n _2Down = MES_DPAD_BUTTON_2_DOWN,\n //% block=\"2 up\"\n _2Up = MES_DPAD_BUTTON_2_UP,\n //% block=\"3 down\"\n _3Down = MES_DPAD_BUTTON_3_DOWN,\n //% block=\"3 up\"\n _3Up = MES_DPAD_BUTTON_3_UP,\n //% block=\"4 down\"\n _4Down = MES_DPAD_BUTTON_4_DOWN,\n //% block=\"4 up\"\n _4Up = MES_DPAD_BUTTON_4_UP,\n};\n\n/**\n * Control a phone with the BBC micro:bit via Bluetooth.\n */\n//% color=156 weight=80\nnamespace devices {\n static void genEvent(int id, int event) {\n MicroBitEvent e(id, event);\n }\n\n /**\n * Sends a ``camera`` command to the parent device.\n * @param event event description\n */\n //% weight=30 help=devices/tell-camera-to\n //% blockId=devices_camera icon=\"\\uf030\" block=\"tell camera to|%property\" blockGap=8\n void tellCameraTo(MesCameraEvent event) { \n genEvent(MES_CAMERA_ID, (int)event);\n }\n\n /**\n * Sends a ``remote control`` command to the parent device.\n * @param event event description\n */\n //% weight=29 help=devices/tell-remote-control-to\n //% blockId=devices_remote_control block=\"tell remote control to|%property\" blockGap=14 icon=\"\\uf144\"\n void tellRemoteControlTo(MesRemoteControlEvent event) { \n genEvent(MES_REMOTE_CONTROL_ID, (int)event);\n }\n\n /**\n * Sends an ``alert`` command to the parent device.\n * @param event event description\n */\n //% weight=27 help=devices/raise-alert-to\n //% blockId=devices_alert block=\"raise alert to|%property\" icon=\"\\uf0f3\"\n void raiseAlertTo(MesAlertEvent event) { \n genEvent(MES_ALERTS_ID, (int)event);\n }\n\n /**\n * Registers code to run when the device notifies about a particular event.\n * @param event event description\n * @param body code handler when event is triggered\n */\n //% help=devices/on-notified weight=26\n //% blockId=devices_device_info_event block=\"on notified|%event\" icon=\"\\uf10a\"\n void onNotified(MesDeviceInfo event, Action body) {\n registerWithDal(MES_DEVICE_INFO_ID, (int)event, body);\n }\n\n /**\n * Register code to run when the micro:bit receives a command from the paired gamepad.\n * @param name button name\n * @param body code to run when button is pressed\n */\n //% help=devices/on-gamepad-button weight=40\n //% weight=25\n //% blockId=devices_gamepad_event block=\"on gamepad button|%NAME\" icon=\"\\uf11b\"\n void onGamepadButton(MesDpadButtonInfo name, Action body) {\n registerWithDal(MES_DPAD_CONTROLLER_ID, (int)name, body);\n }\n\n static int _signalStrength = -1;\n static void signalStrengthHandler(MicroBitEvent ev) { \n // keep in sync with MESEvents.h\n _signalStrength = ev.value - 1; \n }\n static void initSignalStrength() {\n if (_signalStrength < 0) {\n _signalStrength = 0;\n uBit.messageBus.listen(MES_SIGNAL_STRENGTH_ID, MICROBIT_EVT_ANY, signalStrengthHandler);\n } \n }\n \n /**\n * Returns the last signal strength reported by the paired device.\n */\n //% help=devices/signal-strength weight=24\n //% blockId=devices_signal_strength block=\"signal strength\" blockGap=14 icon=\"\\uf012\" blockGap=14\n int signalStrength() {\n initSignalStrength();\n return _signalStrength;\n }\n\n /**\n * Registers code to run when the device notifies about a change of signal strength.\n * @param body Code run when the signal strength changes.\n */\n //% weight=23 help=devices/on-signal-strength-changed\n //% blockId=devices_signal_strength_changed_event block=\"on signal strength changed\" icon=\"\\uf012\"\n void onSignalStrengthChanged(Action body) {\n initSignalStrength(); \n registerWithDal(MES_SIGNAL_STRENGTH_ID, MICROBIT_EVT_ANY, body);\n }\n}\n",
"enums.d.ts": "// Auto-generated. Do not edit.\n\n\n declare enum MesCameraEvent {\n //% block=\"take photo\"\n TakePhoto = 3, // MES_CAMERA_EVT_TAKE_PHOTO\n //% block=\"start video capture\"\n StartVideoCapture = 4, // MES_CAMERA_EVT_START_VIDEO_CAPTURE\n //% block=\"stop video capture\"\n StopVideoCapture = 5, // MES_CAMERA_EVT_STOP_VIDEO_CAPTURE\n //% block=\"toggle front-rear\"\n ToggleFrontRear = 8, // MES_CAMERA_EVT_TOGGLE_FRONT_REAR\n //% block=\"launch photo mode\"\n LaunchPhotoMode = 1, // MES_CAMERA_EVT_LAUNCH_PHOTO_MODE\n //% block=\"launch video mode\"\n LaunchVideoMode = 2, // MES_CAMERA_EVT_LAUNCH_VIDEO_MODE\n //% block=\"stop photo mode\"\n StopPhotoMode = 6, // MES_CAMERA_EVT_STOP_PHOTO_MODE\n //% block=\"stop video mode\"\n StopVideoMode = 7, // MES_CAMERA_EVT_STOP_VIDEO_MODE\n }\n\n\n declare enum MesAlertEvent {\n //% block=\"display toast\"\n DisplayToast = 1, // MES_ALERT_EVT_DISPLAY_TOAST\n //% block=\"vibrate\"\n Vibrate = 2, // MES_ALERT_EVT_VIBRATE\n //% block=\"play sound\"\n PlaySound = 3, // MES_ALERT_EVT_PLAY_SOUND\n //% block=\"play ring tone\"\n PlayRingtone = 4, // MES_ALERT_EVT_PLAY_RINGTONE\n //% block=\"find my phone\"\n FindMyPhone = 5, // MES_ALERT_EVT_FIND_MY_PHONE\n //% block=\"ring alarm\"\n RingAlarm = 6, // MES_ALERT_EVT_ALARM1\n //% block=\"ring alarm 2\"\n RingAlarm2 = 7, // MES_ALERT_EVT_ALARM2\n //% block=\"ring alarm 3\"\n RingAlarm3 = 8, // MES_ALERT_EVT_ALARM3\n //% block=\"ring alarm 4\"\n RingAlarm4 = 9, // MES_ALERT_EVT_ALARM4\n //% block=\"ring alarm 5\"\n RingAlarm5 = 10, // MES_ALERT_EVT_ALARM5\n //% block=\"ring alarm 6\"\n RingAlarm6 = 11, // MES_ALERT_EVT_ALARM6\n }\n\n\n declare enum MesDeviceInfo {\n //% block=\"incoming call\"\n IncomingCall = 7, // MES_DEVICE_INCOMING_CALL\n //% block=\"incoming message\"\n IncomingMessage = 8, // MES_DEVICE_INCOMING_MESSAGE\n //% block=\"orientation landscape\"\n OrientationLandscape = 1, // MES_DEVICE_ORIENTATION_LANDSCAPE\n //% block=\"orientation portrait\"\n OrientationPortrait = 2, // MES_DEVICE_ORIENTATION_PORTRAIT\n //% block=\"shaken\"\n Shaken = 4, // MES_DEVICE_GESTURE_DEVICE_SHAKEN\n //% block=\"display off\"\n DisplayOff = 5, // MES_DEVICE_DISPLAY_OFF\n //% block=\"display on\"\n DisplayOn = 6, // MES_DEVICE_DISPLAY_ON\n }\n\n\n declare enum MesRemoteControlEvent {\n //% block=\"play\"\n play = 1, // MES_REMOTE_CONTROL_EVT_PLAY\n //% block=\"pause\"\n pause = 2, // MES_REMOTE_CONTROL_EVT_PAUSE\n //% block=\"stop\"\n stop = 3, // MES_REMOTE_CONTROL_EVT_STOP\n //% block=\"next track\"\n nextTrack = 4, // MES_REMOTE_CONTROL_EVT_NEXTTRACK\n //% block=\"previous track\"\n previousTrack = 5, // MES_REMOTE_CONTROL_EVT_PREVTRACK\n //% block=\"forward\"\n forward = 6, // MES_REMOTE_CONTROL_EVT_FORWARD\n //% block=\"rewind\"\n rewind = 7, // MES_REMOTE_CONTROL_EVT_REWIND\n //% block=\"volume up\"\n volumeUp = 8, // MES_REMOTE_CONTROL_EVT_VOLUMEUP\n //% block=\"volume down\"\n volumeDown = 9, // MES_REMOTE_CONTROL_EVT_VOLUMEDOWN\n }\n\n\n declare enum MesDpadButtonInfo {\n //% block=\"A down\"\n ADown = 1, // MES_DPAD_BUTTON_A_DOWN\n //% block=\"A up\"\n AUp = 2, // MES_DPAD_BUTTON_A_UP\n //% block=\"B down\"\n BDown = 3, // MES_DPAD_BUTTON_B_DOWN\n //% block=\"B up\"\n BUp = 4, // MES_DPAD_BUTTON_B_UP\n //% block=\"C down\"\n CDown = 5, // MES_DPAD_BUTTON_C_DOWN\n //% block=\"C up\"\n CUp = 6, // MES_DPAD_BUTTON_C_UP\n //% block=\"D down\"\n DDown = 7, // MES_DPAD_BUTTON_D_DOWN\n //% block=\"D up\"\n DUp = 8, // MES_DPAD_BUTTON_D_UP\n //% block=\"1 down\"\n _1Down = 10, // MES_DPAD_BUTTON_1_UP\n //% block=\"1 up\"\n _1Up = 9, // MES_DPAD_BUTTON_1_DOWN\n //% block=\"2 down\"\n _2Down = 11, // MES_DPAD_BUTTON_2_DOWN\n //% block=\"2 up\"\n _2Up = 12, // MES_DPAD_BUTTON_2_UP\n //% block=\"3 down\"\n _3Down = 13, // MES_DPAD_BUTTON_3_DOWN\n //% block=\"3 up\"\n _3Up = 14, // MES_DPAD_BUTTON_3_UP\n //% block=\"4 down\"\n _4Down = 15, // MES_DPAD_BUTTON_4_DOWN\n //% block=\"4 up\"\n _4Up = 16, // MES_DPAD_BUTTON_4_UP\n }\ndeclare namespace devices {\n}\n\n// Auto-generated. Do not edit. Really.\n",
"pxt.json": "{\n \"name\": \"devices\",\n \"description\": \"The BLE specific services\",\n \"files\": [\n \"README.md\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"devices.cpp\"\n ],\n \"public\": true,\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"yotta\": {\n \"config\": {\n \"microbit-dal\": {\n \"bluetooth\": {\n \"enabled\": 1\n }\n }\n }\n }\n}",
"shims.d.ts": "// Auto-generated. Do not edit.\n\n\n /**\n * Control a phone with the BBC micro:bit via Bluetooth.\n */\n //% color=156 weight=80\ndeclare namespace devices {\n\n /**\n * Sends a ``camera`` command to the parent device.\n * @param event event description\n */\n //% weight=30 help=devices/tell-camera-to\n //% blockId=devices_camera icon=\"\\uf030\" block=\"tell camera to|%property\" blockGap=8 shim=devices::tellCameraTo\n function tellCameraTo(event: MesCameraEvent): void;\n\n /**\n * Sends a ``remote control`` command to the parent device.\n * @param event event description\n */\n //% weight=29 help=devices/tell-remote-control-to\n //% blockId=devices_remote_control block=\"tell remote control to|%property\" blockGap=14 icon=\"\\uf144\" shim=devices::tellRemoteControlTo\n function tellRemoteControlTo(event: MesRemoteControlEvent): void;\n\n /**\n * Sends an ``alert`` command to the parent device.\n * @param event event description\n */\n //% weight=27 help=devices/raise-alert-to\n //% blockId=devices_alert block=\"raise alert to|%property\" icon=\"\\uf0f3\" shim=devices::raiseAlertTo\n function raiseAlertTo(event: MesAlertEvent): void;\n\n /**\n * Registers code to run when the device notifies about a particular event.\n * @param event event description\n * @param body code handler when event is triggered\n */\n //% help=devices/on-notified weight=26\n //% blockId=devices_device_info_event block=\"on notified|%event\" icon=\"\\uf10a\" shim=devices::onNotified\n function onNotified(event: MesDeviceInfo, body: () => void): void;\n\n /**\n * Register code to run when the micro:bit receives a command from the paired gamepad.\n * @param name button name\n * @param body code to run when button is pressed\n */\n //% help=devices/on-gamepad-button weight=40\n //% weight=25\n //% blockId=devices_gamepad_event block=\"on gamepad button|%NAME\" icon=\"\\uf11b\" shim=devices::onGamepadButton\n function onGamepadButton(name: MesDpadButtonInfo, body: () => void): void;\n\n /**\n * Returns the last signal strength reported by the paired device.\n */\n //% help=devices/signal-strength weight=24\n //% blockId=devices_signal_strength block=\"signal strength\" blockGap=14 icon=\"\\uf012\" blockGap=14 shim=devices::signalStrength\n function signalStrength(): number;\n\n /**\n * Registers code to run when the device notifies about a change of signal strength.\n * @param body Code run when the signal strength changes.\n */\n //% weight=23 help=devices/on-signal-strength-changed\n //% blockId=devices_signal_strength_changed_event block=\"on signal strength changed\" icon=\"\\uf012\" shim=devices::onSignalStrengthChanged\n function onSignalStrengthChanged(body: () => void): void;\n}\n\n// Auto-generated. Do not edit. Really.\n"
},
"bluetooth": {
"README.md": "# Bluetooth services\n",
"_locales/de/bluetooth-jsdoc-strings.json": "{\n \"bluetooth\": \"Unterstützung für zusätzliche Bluetooth-Dienste.\",\n \"bluetooth.onBluetoothConnected|param|body\": \"Code, der ausgeführt wird, wenn eine Bluetooth-Verbindung aufgebaut wurde\",\n \"bluetooth.uartWriteNumber\": \"Gibt einen numerischen Wert an die serielle\",\n \"bluetooth.uartWriteValue\": \"Schreibt ein ``Namen: Wert`` Wertepaar auf die serielle Schnittstelle.\",\n \"bluetooth.uartWriteValue|param|name\": \"Name des Wertestreams, z.B.: x\",\n \"bluetooth.uartWriteValue|param|value\": \"Schreiben\"\n}",
"bluetooth.cpp": "#include \"pxt.h\"\n#include \"MESEvents.h\"\n#include \"MicroBitUARTService.h\"\n\nusing namespace pxt;\n\n/**\n * Support for additional Bluetooth services.\n */\n//% color=#0082FB weight=20\nnamespace bluetooth {\n MicroBitUARTService *uart = NULL;\n\n\n /**\n * Starts the Bluetooth accelerometer service\n */\n //% help=bluetooth/start-accelerometer-service\n //% blockId=bluetooth_start_accelerometer_service block=\"bluetooth accelerometer service\"\n //% parts=\"bluetooth\" weight=90 blockGap=8\n void startAccelerometerService() {\n new MicroBitAccelerometerService(*uBit.ble, uBit.accelerometer); \n } \n\n /**\n * Starts the Bluetooth button service\n */\n //% help=bluetooth/start-button-service\n //% blockId=bluetooth_start_button_service block=\"bluetooth button service\" blockGap=8\n //% parts=\"bluetooth\" weight=89\n void startButtonService() {\n new MicroBitButtonService(*uBit.ble); \n }\n\n /**\n * Starts the Bluetooth IO pin service.\n */\n //% help=bluetooth/start-io-pin-service\n //% blockId=bluetooth_start_io_pin_service block=\"bluetooth io pin service\" blockGap=8\n //% parts=\"bluetooth\" weight=88\n void startIOPinService() {\n new MicroBitIOPinService(*uBit.ble, uBit.io);\n }\n\n /**\n * Starts the Bluetooth LED service\n */\n //% help=bluetooth/start-led-service\n //% blockId=bluetooth_start_led_service block=\"bluetooth led service\" blockGap=8\n //% parts=\"bluetooth\" weight=87\n void startLEDService() {\n new MicroBitLEDService(*uBit.ble, uBit.display);\n }\n\n /**\n * Starts the Bluetooth temperature service\n */\n //% help=bluetooth/start-temperature-service\n //% blockId=bluetooth_start_temperature_service block=\"bluetooth temperature service\" blockGap=8\n //% parts=\"bluetooth\" weight=86\n void startTemperatureService() { \n new MicroBitTemperatureService(*uBit.ble, uBit.thermometer); \n }\n\n /**\n * Starts the Bluetooth magnetometer service\n */\n //% help=bluetooth/start-magnetometer-service\n //% blockId=bluetooth_start_magnetometer_service block=\"bluetooth magnetometer service\"\n //% parts=\"bluetooth\" weight=85\n void startMagnetometerService() { \n new MicroBitMagnetometerService(*uBit.ble, uBit.compass); \n }\n\n\n /**\n * Starts the Bluetooth UART service\n */\n //% help=bluetooth/start-uart-service\n //% blockId=bluetooth_start_uart_service block=\"bluetooth uart service\"\n //% parts=\"bluetooth\" advanced=true\n void startUartService() {\n if (uart) return;\n // 61 octet buffer size is 3 x (MTU - 3) + 1\n // MTU on nRF51822 is 23 octets. 3 are used by Attribute Protocol header data leaving 20 octets for payload\n // So we allow a RX buffer that can contain 3 x max length messages plus one octet for a terminator character\n uart = new MicroBitUARTService(*uBit.ble, 61, 60);\n }\n \n //%\n void uartWriteString(StringData *data) {\n startUartService();\n \tuart->send(ManagedString(data));\n } \n\n //%\n StringData* uartReadUntil(StringData *del) {\n startUartService();\n return uart->readUntil(ManagedString(del)).leakData();\n } \n\n /**\n * Register code to run when the micro:bit is connected to over Bluetooth\n * @param body Code to run when a Bluetooth connection is established\n */\n //% help=bluetooth/on-bluetooth-connected weight=20\n //% blockId=bluetooth_on_connected block=\"on bluetooth connected\" blockGap=8\n //% parts=\"bluetooth\"\n void onBluetoothConnected(Action body) {\n registerWithDal(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_CONNECTED, body);\n } \n\n /**\n * Register code to run when a bluetooth connection to the micro:bit is lost\n * @param body Code to run when a Bluetooth connection is lost\n */\n //% help=bluetooth/on-bluetooth-disconnected weight=19\n //% blockId=bluetooth_on_disconnected block=\"on bluetooth disconnected\"\n //% parts=\"bluetooth\"\n void onBluetoothDisconnected(Action body) {\n registerWithDal(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_DISCONNECTED, body);\n } \n}",
"bluetooth.ts": "/**\n * Support for additional Bluetooth services.\n */\n//% color=#0082FB weight=20 icon=\"\\uf294\"\nnamespace bluetooth {\n /**\n * Writes to the Bluetooth UART service buffer. From there the data is transmitted over Bluetooth to a connected device.\n */\n //% help=bluetooth/uart-write-string weight=80\n //% blockId=bluetooth_uart_write block=\"bluetooth uart|write string %data\" blockGap=8\n //% parts=\"bluetooth\" shim=bluetooth::uartWriteString advanced=true\n export function uartWriteString(data: string): void {\n // dummy implementation for simulator\n console.log(\"UART Write: \" + data)\n }\n\n /**\n * Prints a numeric value to the serial\n */\n //% help=bluetooth/uart-write-number weight=79\n //% weight=89 blockGap=8 advanced=true\n //% blockId=bluetooth_uart_writenumber block=\"bluetooth uart|write number %value\"\n export function uartWriteNumber(value: number): void {\n uartWriteString(value.toString());\n }\n\n /**\n * Writes a ``name: value`` pair line to the serial.\n * @param name name of the value stream, eg: x\n * @param value to write\n */\n //% weight=88 weight=78\n //% help=bluetooth/uart-write-value advanced=true\n //% blockId=bluetooth_uart_writevalue block=\"bluetooth uart|write value %name|= %value\"\n export function uartWriteValue(name: string, value: number): void {\n uartWriteString(name + \":\" + value + \"\\r\\n\");\n }\n\n /**\n * Reads from the Bluetooth UART service buffer, returning its contents when the specified delimiter character is encountered.\n */\n //% help=bluetooth/uart-read-until weight=75\n //% blockId=bluetooth_uart_read block=\"bluetooth uart|read until %del=serial_delimiter_conv\"\n //% parts=\"bluetooth\" shim=bluetooth::uartReadUntil advanced=true\n export function uartReadUntil(del: string): string {\n // dummy implementation for simulator\n return \"???\"\n }\n}\n",
"enums.d.ts": "// Auto-generated. Do not edit.\ndeclare namespace bluetooth {\n}\n\n// Auto-generated. Do not edit. Really.\n",
"pxt.json": "{\n \"name\": \"bluetooth\",\n \"description\": \"Bluetooth services\",\n \"files\": [\n \"README.md\",\n \"enums.d.ts\",\n \"shims.d.ts\",\n \"bluetooth.ts\",\n \"bluetooth.cpp\",\n \"_locales/de/bluetooth-jsdoc-strings.json\"\n ],\n \"public\": true,\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"yotta\": {\n \"config\": {\n \"microbit-dal\": {\n \"bluetooth\": {\n \"enabled\": 1,\n \"pairing_mode\": 1,\n \"private_addressing\": 0,\n \"open\": 0,\n \"whitelist\": 1,\n \"advertising_timeout\": 0,\n \"tx_power\": 6,\n \"dfu_service\": 1,\n \"event_service\": 1,\n \"device_info_service\": 1\n },\n \"gatt_table_size\": \"0x700\"\n }\n }\n }\n}",
"shims.d.ts": "// Auto-generated. Do not edit.\n\n\n /**\n * Support for additional Bluetooth services.\n */\n //% color=#0082FB weight=20\ndeclare namespace bluetooth {\n\n /**\n * Starts the Bluetooth accelerometer service\n */\n //% help=bluetooth/start-accelerometer-service\n //% blockId=bluetooth_start_accelerometer_service block=\"bluetooth accelerometer service\"\n //% parts=\"bluetooth\" weight=90 blockGap=8 shim=bluetooth::startAccelerometerService\n function startAccelerometerService(): void;\n\n /**\n * Starts the Bluetooth button service\n */\n //% help=bluetooth/start-button-service\n //% blockId=bluetooth_start_button_service block=\"bluetooth button service\" blockGap=8\n //% parts=\"bluetooth\" weight=89 shim=bluetooth::startButtonService\n function startButtonService(): void;\n\n /**\n * Starts the Bluetooth IO pin service.\n */\n //% help=bluetooth/start-io-pin-service\n //% blockId=bluetooth_start_io_pin_service block=\"bluetooth io pin service\" blockGap=8\n //% parts=\"bluetooth\" weight=88 shim=bluetooth::startIOPinService\n function startIOPinService(): void;\n\n /**\n * Starts the Bluetooth LED service\n */\n //% help=bluetooth/start-led-service\n //% blockId=bluetooth_start_led_service block=\"bluetooth led service\" blockGap=8\n //% parts=\"bluetooth\" weight=87 shim=bluetooth::startLEDService\n function startLEDService(): void;\n\n /**\n * Starts the Bluetooth temperature service\n */\n //% help=bluetooth/start-temperature-service\n //% blockId=bluetooth_start_temperature_service block=\"bluetooth temperature service\" blockGap=8\n //% parts=\"bluetooth\" weight=86 shim=bluetooth::startTemperatureService\n function startTemperatureService(): void;\n\n /**\n * Starts the Bluetooth magnetometer service\n */\n //% help=bluetooth/start-magnetometer-service\n //% blockId=bluetooth_start_magnetometer_service block=\"bluetooth magnetometer service\"\n //% parts=\"bluetooth\" weight=85 shim=bluetooth::startMagnetometerService\n function startMagnetometerService(): void;\n\n /**\n * Starts the Bluetooth UART service\n */\n //% help=bluetooth/start-uart-service\n //% blockId=bluetooth_start_uart_service block=\"bluetooth uart service\"\n //% parts=\"bluetooth\" advanced=true shim=bluetooth::startUartService\n function startUartService(): void;\n\n /**\n * Register code to run when the micro:bit is connected to over Bluetooth\n * @param body Code to run when a Bluetooth connection is established\n */\n //% help=bluetooth/on-bluetooth-connected weight=20\n //% blockId=bluetooth_on_connected block=\"on bluetooth connected\" blockGap=8\n //% parts=\"bluetooth\" shim=bluetooth::onBluetoothConnected\n function onBluetoothConnected(body: () => void): void;\n\n /**\n * Register code to run when a bluetooth connection to the micro:bit is lost\n * @param body Code to run when a Bluetooth connection is lost\n */\n //% help=bluetooth/on-bluetooth-disconnected weight=19\n //% blockId=bluetooth_on_disconnected block=\"on bluetooth disconnected\"\n //% parts=\"bluetooth\" shim=bluetooth::onBluetoothDisconnected\n function onBluetoothDisconnected(body: () => void): void;\n}\n\n// Auto-generated. Do not edit. Really.\n"
},
"pxt-calliope-bc95": {
"README.md": "# Calliope mini BC95 NB-IoT module\n\nThis is a package for controlling an NB-IoT module to send messages from the Calliope mini.\nIt can be used by the [PXT Calliope mini editor](https://pxt.calliope.cc/). Should also work\nwith PXT for Micro:bit.\n\nMore information on the module can be found on the [Quectel website](http://www.quectel.com/product/bc95.htm).\nIt is used in conjunction with an [evaluation kit](http://www.quectel.com/product/gsmevb.htm).\n\nThe code may be used as a starting point for similar AT based systems.\n\n## Testing\n\n- Modify `tests.ts` to send packages to your own server.\n- Execute a little server: `nc -vv -ul -p 5883` (Linux, also echos the messages) \n- Compile the test `pxt test` and copy `built/binary.hex` to the Calliope mini.\n\nOn the USB console window you will see this:\n\n```\nSTART TEST\nTEST: modem working: OK\nTEST: enable all functionality: OK\nTEST: check IMSI: OK\nTEST: connect to network: OK\nTEST: check signal quality: OK\nTEST: check network stats: OK\nTEST: check PDP context: OK\nTEST: check address: OK\nTEST: check band: OK\nTEST: ping external server: OK\nTEST: expect ping reply: OK\nTEST: sending number: OK\nTEST: sending string: OK\nTEST FINISHED OK\n``` \n\n> You can follow the AT flow on the USB serial console by enabling debug in `tests.ts`\n\nThe server should show something like this:\n\n```\nconnect to [46.23.86.61] from tmo-121-137.customers.d1-online.com [80.187.121.137] 25519\n {\"id\":\"bc9ab239\",\"p\":{\"test\":123}}{\"id\":\"bc9ab239\",\"p\":{\"test\":\"value 123\"}}\n```\n\n## Example\n\n### Blocks\n![Example Code](example.png)\n\n### Javascript\n\n```typescript\ninput.onButtonPressed(Button.A, () => {\n bc95.sendString(\n \"Hallo\",\n \"Calliope mini\"\n )\n if (bc95.sendOk()) {\n basic.showIcon(IconNames.Yes)\n } else {\n basic.showIcon(IconNames.No)\n }\n basic.pause(1000)\n basic.clearScreen()\n})\ninput.onButtonPressed(Button.B, () => {\n bc95.sendNumber(\n \"t\",\n input.temperature()\n )\n if (bc95.sendOk()) {\n basic.showIcon(IconNames.Yes)\n } else {\n basic.showIcon(IconNames.No)\n }\n basic.pause(1000)\n basic.clearScreen()\n})\nbc95.init(\n SerialPin.C17,\n SerialPin.C16,\n BaudRate.BaudRate9600\n)\nbc95.attach()\nbc95.setServer(\"46.23.86.61\", 5883)\n```\n\n```\n$ listening on [any] 5883 ...\n connect to [46.23.86.61] from tmo-121-137.customers.d1-online.com [80.187.121.137] 24189\n {\"id\":\"bc9ab239\",\"p\":{\"t\":29}}{\"id\":\"bc9ab239\",\"p\":{\"Hallo\":\"Calliope mini\"}}\n\n```\n\n## TODO\n\n- extract AT response parsing into its own module, to make it usable for other devices\n- handle incoming messages\n\n## Meta\n\n- PXT/calliope\n- PXT/microbit\n\nAuthor: Matthias L. Jugel ([@thinkberg](https://twitter.com/thinkberg))\n\n## License\n\nMIT",
"_locales/de/pxt-calliope-bc95-jsdoc-strings.json": "{\n \"bc95\": \"Funktionen für das NB-IoT Modul BC95\",\n \"bc95.attach\": \"Verbinde NB-IoT Netzwerk.\",\n \"bc95.enableDebug\": \"Starte AT-Kommando Debugausgabe.\",\n \"bc95.expectAT\": \"Sende ein AT Kommando an das Modul. Nur den Befehl, ohne den AT Prefix, z.B. AT(\\\"+CIMI\\\"). Gibt die erste Zeile der Antwort des Modules zurück.\",\n \"bc95.expectAT|param|command\": \"AT Kommando ohne Prefix\",\n \"bc95.expectOK\": \"Sende ein AT Kommando an das Modul und erwarte OK. Nur den Befehl ohne AT Prefix, z.B. AT(\\\"+CGMI=?\\\"). Gibt Erfolg zurück.\",\n \"bc95.expectOK|param|command\": \"AT Kommando ohne Prefix\",\n \"bc95.init\": \"Intialisiere das BC95 Modul mit dem Seriellen Port.\",\n \"bc95.init|param|rate\": \"die Baud Rate, z.B. BaudRate.BaudRate9600\",\n \"bc95.init|param|rx\": \"der Empfangs-Pin, z.B. SerialPin.C16\",\n \"bc95.init|param|tx\": \"der Sende-Pin, z.B. SerialPin.C17\",\n \"bc95.pushAT\": \"Sende eine AT Kommando an das Modul. Nur den Befehl, ohne den AT Prefix, z.B. AT(\\\"+CIMI\\\"). Ignoriert das Ergebnis.\",\n \"bc95.pushAT|param|command\": \"AT Kommando ohne Prefix\",\n \"bc95.sendNumber\": \"Sende eine Nummer zum Server.\",\n \"bc95.sendOk\": \"Prüft, ob die letzte Sendeoperation erfolgreich war.\\nSetzt den Status zurück.\",\n \"bc95.sendString\": \"Sende Text zum Server.\",\n \"bc95.setAPN\": \"Konfiguriert den APN Zugangspunkt inkl. Nutzernamen und Passwort.\",\n \"bc95.setAPN|param|apn\": \"Zugangspunkt, z.B. internet.nbiot.telekom.de\",\n \"bc95.setAPN|param|password\": \"Passwort\",\n \"bc95.setAPN|param|user\": \"Benutzername\",\n \"bc95.setServer\": \"Konfiguriert die IP Adresse des UDP Empfangsservers.\",\n \"bc95.setServer|param|host\": \"IP Adresse des Empfangsservers\",\n \"bc95.setServer|param|port\": \"Portadresse des Empfangsservers, z.B. 5883\",\n \"serial\": \"Reading and writing data over a serial connection.\",\n \"serial.resetSerial\": \"Setze seriellen Port zurück auf USBTX/USBRX.\",\n \"serial.setReceiveBufferSize\": \"Setze Empfangspuffergröße.\"\n}",
"_locales/de/pxt-calliope-bc95-strings.json": "{\n \"bc95.attach|block\": \"verbinde mit NB-IoT Netzwerk\",\n \"bc95.enableDebug|block\": \"debugge AT %debug\",\n \"bc95.expectAT|block\": \"sende AT %command und empfange\",\n \"bc95.expectOK|block\": \"prüfe AT %command|Resultat OK?\",\n \"bc95.init|block\": \"initialisiere BC95|TX %tx|RX %rx|mit Baudrate %rate\",\n \"bc95.pushAT|block\": \"sende AT %command\",\n \"bc95.sendNumber|block\": \"sende Zahlennachricht|Name %key|Wert %n\",\n \"bc95.sendOk|block\": \"senden erfolgreich?\",\n \"bc95.sendString|block\": \"sende Textnachricht|Name %key|Wert %n\",\n \"bc95.setAPN|block\": \"setze APN %apn|Benutzer %user|Passwort %password\",\n \"bc95.setServer|block\": \"setze Server Adresse %host|Port %port\",\n \"bc95|block\": \"BC95\",\n \"serial.resetSerial|block\": \"seriellen Port zurücksetzen\",\n \"serial.setReceiveBufferSize|block\": \"setze Empfangspuffergrösse %size\",\n \"serial|block\": \"seriell\",\n \"{id:category}Bc95\": \"BC95\",\n \"{id:category}Serial\": \"Seriell\"\n}",
"bc95.cpp": "#include \"pxt.h\"\n\nnamespace bc95 {\n //%\n StringData *getSerialNumber() {\n char tmp[9];\n snprintf(tmp, 9, \"%8lx\", microbit_serial_number());\n return ManagedString(tmp).leakData();\n }\n}\n\nnamespace serial {\n //%\n void setReceiveBufferSize(int size) {\n uBit.serial.setRxBufferSize(size);\n }\n\n //%\n void resetSerial() {\n uBit.serial.redirect(USBTX, USBRX);\n uBit.serial.baud(MICROBIT_SERIAL_DEFAULT_BAUD_RATE);\n }\n\n //%\n StringData *readLine_() {\n return uBit.serial.readUntil(ManagedString(\"\\n\")).leakData();\n }\n\n}\n",
"bc95.ts": "/**\n * Functions for the NB-IoT module bc95\n */\n\n//% weight=2 color=#A8BCBC icon=\"\\uf1d9\"\n//% parts=\"bc95 \nnamespace bc95 {\n // enabling DEBUG allows to follow the AT flow on the USB serial port\n // this switches the serial back and forth and introduces delays\n let DEBUG = false;\n\n let TX = SerialPin.C17;\n let RX = SerialPin.C16;\n let BAUD = BaudRate.BaudRate9600;\n\n let SERVER = \"\";\n let PORT = 44567;\n let APN = \"internet.nbiot.telekom.de\";\n let USER = \"\";\n let PASS = \"\";\n let ERROR = false;\n\n /**\n * Initialize bc95 module serial port.\n * @param tx the new transmission pins, eg: SerialPin.C17\n * @param rx the new reception pin, eg: SerialPin.C16\n * @param rate the new baud rate, eg: BaudRate.BaudRate9600\n */\n //% weight=210\n //% blockId=bc95_init block=\"initialize BC95|TX %tx|RX %rx|at baud rate %rate\"\n //% blockExternalInputs=1\n //% parts=\"bc95\"\n export function init(tx: SerialPin, rx: SerialPin, rate: BaudRate): void {\n TX = tx;\n RX = rx;\n BAUD = rate;\n serial.redirect(TX, RX, BAUD);\n serial.setReceiveBufferSize(100);\n }\n\n /**\n * Attach to the mobile network. May take up to 30s.\n */\n //% weight=209\n //% blockId=bc95_attach block=\"attach NB-IoT network\"\n //% parts=\"bc95\"\n export function attach(): void {\n expectOK(\"+CFUN=1\");\n expectOK(\"+COPS=1,2,\\\"26201\\\"\");\n for (let i = 0; i < 6; i++) {\n if (bc95.sendAT(\"+CGATT?\")[0] == \"+CGATT:1\") break;\n basic.pause(1000);\n }\n }\n\n /**\n * Configure the UDP server to use for the NB-IoT messaging.\n * @param host the IP address of a server to send messages to\n * @param port the port to send messages to, eg: 5883\n */\n //% weight=208\n //% blockId=bc95_setserver block=\"set server |address %host|port %port\"\n //% parts=\"bc95\"\n export function setServer(host: string, port: number): void {\n SERVER = host;\n PORT = port;\n }\n\n /**\n * Configure the APN to use for the NB-IoT messaging.\n * @param apn the access point name, eg: internet.nbiot.telekom.de\n * @param user a user name to access the APN\n * @param password a password to access the APN\n */\n //% weight=100\n //% blockId=bc95_setapn block=\"set APN %apn|user %user|password %password\"\n //% blockExternalInputs=1\n //% parts=\"bc95\"\n export function setAPN(apn: string, user: string = null, password: string = null) {\n APN = apn;\n if (user != null && user.length > 0) USER = user;\n if (password != null && password.length > 0) PASS = password;\n }\n\n /**\n * Send an AT command to the bc95 module. Just provide the actual\n * command, not the AT prefix, like this AT(\"+CGMI?\"). Ignores the\n * AT command response completely\n * @param command the command to be sent without AT prefix\n */\n //% weight=20\n //% blockId=bc95_pushat block=\"send AT %command\"\n //% parts=\"bc95\"\n //% advanced=true\n export function pushAT(command: string): void {\n sendAT(command);\n }\n\n /**\n * Send an AT command to the bc95 module. Just provide the actual\n * command, not the AT prefix, like this AT(\"+CIMI\"). Returns the\n * first line of the response from this AT command.\n * @param command the command to be sent without AT prefix\n */\n //% weight=22\n //% blockId=bc95_sendat block=\"send AT %command and receive\"\n //% parts=\"bc95\"\n //% advanced=true\n export function expectAT(command: string): string {\n let r = sendAT(command);\n if (r.length == 0) return \"\";\n return r[0];\n }\n\n export function sendAT(command: string): Array<string> {\n basic.pause(100);\n if (DEBUG) log(\"+++\", \"AT\" + command);\n serial.writeString(\"\\r\\nAT\" + command + \"\\r\\n\");\n return receiveResponse((line: string) => {\n return line == \"OK\\r\" || line == \"ERROR\\r\";\n });\n }\n\n export function receiveResponse(cond: (line: string) => boolean): Array<string> {\n let line = \"\";\n let received: Array<string> = [];\n do {\n line = serial.readLine_();\n if (line.length > 1) received.push(line.substr(0, line.length - 1));\n } while (!cond(line));\n if (DEBUG) logArray(\"---\", received);\n return received;\n }\n\n /**\n * Send an AT command to the bc95 module and expect OK. Just provide the actual\n * command, not the AT prefix, like this AT(\"+CGMI?\"). This function\n * only returns whether the command was executed successful or not.\n * @param command the command to be sent without AT prefix\n */\n //% weight=21\n //% blockId=bc95_expectok block=\"check AT %command|response OK?\"\n //% parts=\"bc95\"\n //% advanced=true\n export function expectOK(command: string): boolean {\n let response = sendAT(command);\n return response[response.length - 1] == \"OK\";\n }\n\n /**\n * Send a number to the backend server.\n */\n //% weight=110\n //% blockId=bc95_sendNumber block=\"UDP|send number message|key %key|value %n\"\n //% blockExternalInputs=1\n //% parts=\"bc95\"\n export function sendNumber(key: string, value: number): void {\n ERROR = !sendUDP(\"{\\\"\" + key + \"\\\":\" + value + \"}\");\n }\n\n /**\n * Send a string to the backend server.\n */\n //% weight=120\n //% blockId=bc95_sendString block=\"UDP|send string message|key %key|value %n\"\n //% blockExternalInputs=1\n //% parts=\"bc95\"\n export function sendString(key: string, value: string): void {\n ERROR = !sendUDP(\"{\\\"\" + key + \"\\\":\\\"\" + value + \"\\\"}\");\n }\n\n /**\n * Send the actual message, encoded.\n */\n function sendUDP(message: string, receivePort: number = 44567): boolean {\n let sendok = false;\n // open the socket and remember the socket number\n let response = sendAT(\"+NSOCR=DGRAM,17,\" + receivePort + \",1\");\n if (response[response.length - 1] == \"OK\") {\n let socket = response[0];\n message = \"{\\\"id\\\":\\\"\" + getSerialNumber() + \"\\\",\\\"p\\\":\" + message + \"}\";\n // send UDP packet\n sendok = expectOK(\"+NSOST=\" + socket + \",\" + SERVER + \",\" + PORT + \",\" + message.length + \",\" + stringToHex(message));\n // close socket\n expectOK(\"+NSOCL=\" + socket);\n }\n return sendok;\n }\n\n /**\n * Check if the last send operation was successful.\n * Also reset the status.\n */\n //% weight=99\n //% blockId=bc95_sendOk block=\"UDP send success?\"\n //% parts=\"bc95\"\n export function sendOk(): boolean {\n if (ERROR) {\n ERROR = false;\n return false;\n } else return true;\n }\n\n const l = \"0123456789ABCDEF\";\n\n // helper function to convert a string into a hex representation usable by the bc95 module\n export function stringToHex(s: string): string {\n let r = \"\";\n for (let i = 0; i < s.length; i++) {\n let c = s.charCodeAt(i);\n r = r + l.substr((c >> 4), 1) + l.substr((c & 0x0f), 1);\n }\n return r;\n }\n\n // debug functions\n\n /**\n * Enable AT command debug.\n */\n //% weight=1\n //% blockId=bc95_setDEBUG block=\"enable DEBUG %debug\"\n //% parts=\"bc95\"\n //% advanced=true\n export function enableDebug(debug: boolean = false): void {\n DEBUG = debug;\n }\n\n export function log(prefix: string, message: string): void {\n basic.pause(100);\n serial.resetSerial();\n serial.writeLine(prefix + \" \" + message);\n basic.pause(100);\n serial.redirect(TX, RX, BAUD);\n basic.pause(100);\n }\n\n export function logArray(prefix: string, lines: Array<string>): void {\n basic.pause(100);\n serial.resetSerial();\n if (lines.length > 1) console.log(prefix + \" (\" + lines.length + \" lines)\");\n for (let i = 0; i < lines.length; i++) {\n serial.writeLine(prefix + \" \" + lines[i]);\n }\n basic.pause(100);\n serial.redirect(TX, RX, BAUD);\n basic.pause(100);\n }\n\n //% shim=bc95::getSerialNumber\n export function getSerialNumber(): string {\n // nothing here\n return \"FEDCBA00\";\n }\n\n}\n\nnamespace serial {\n /**\n * Set serial receive buffer size.\n */\n //% blockId=serial_buffersize block=\"serial receive buffer size %size\"\n //% shim=serial::setReceiveBufferSize\n export function setReceiveBufferSize(size: number): void {\n return;\n }\n\n /**\n * Reset serial back to USBTX/USBRX.\n */\n //% blockId=serial_resetserial block=\"serial reset\"\n //% shim=serial::resetSerial\n export function resetSerial(): void {\n return;\n }\n\n //% shim=serial::readLine_\n export function readLine_(): string {\n return \"OK\\r\";\n }\n}\n",
"pxt.json": "{\n \"name\": \"pxt-calliope-bc95\",\n \"version\": \"0.0.1\",\n \"description\": \"NB-IoT BC95 Module\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"bc95.cpp\",\n \"bc95.ts\",\n \"_locales/de/pxt-calliope-bc95-jsdoc-strings.json\",\n \"_locales/de/pxt-calliope-bc95-strings.json\"\n ],\n \"testFiles\": [\n \"tests.ts\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/calliope-mini/pxt-calliope-bc95.git\"\n },\n \"public\": true\n}",
"tests.ts": "// this test runs on the device, connect and it will send the output on serial\n// after everything is done\n\n//% shim=pxtrt::panic\nfunction panic(code2: number): void {\n}\n\nfunction assert(msg: string, cond: boolean) {\n if (!cond) {\n bc95.log(\"ASSERT:\", msg + \" failed\");\n panic(45);\n } else {\n bc95.log(\"TEST:\", msg +\": OK\");\n }\n}\n\nconsole.log(\"START TEST\");\n\nbc95.init(SerialPin.C17, SerialPin.C16, BaudRate.BaudRate9600);\n// bc95.enableDebug(true);\n\nassert(\"modem working\",\n bc95.expectOK(\"\"));\nassert(\"enable all functionality\",\n bc95.expectOK(\"+CFUN=1\"));\nassert(\"check IMSI\",\n bc95.sendAT(\"+CIMI\")[0] == \"901405800006425\");\nassert(\"connect to network\",\n bc95.expectOK(\"+COPS=1,2,\\\"26201\\\"\"));\n// try to wait for attachment max. approx. 30s\nfor (let i = 0; i < 6; i++) {\n let response = bc95.sendAT(\"+CGATT?\");\n if (response[0] == \"+CGATT:1\") break;\n basic.pause(5000);\n}\n\nassert(\"check signal quality\",\n bc95.sendAT(\"+CSQ\")[0] != \"+CSQ:99,99\");\nassert(\"check network stats\",\n bc95.expectOK(\"+NUESTATS\"));\n\n// assert(\"set APN\",\n// bc95.expectOK(\"+CGDCONT=1,\\\"IP\\\",\\\"internet.nbiot.telekom.de\\\"\"));\nassert(\"check PDP context\",\n bc95.sendAT(\"+CGDCONT?\")[0] == \"+CGDCONT:0,\\\"IP\\\",\\\"internet.nbiot.telekom.de.MNC040.MCC901.GPRS\\\",,0,0\");\nassert(\"check address\",\n bc95.sendAT(\"+CGPADDR\")[0].substr(0,9) == \"+CGPADDR:\");\nassert(\"check band\",\n bc95.sendAT(\"+NBAND?\")[0] == \"+NBAND:8\");\nassert(\"ping external server\",\n bc95.expectOK(\"+NPING=85.214.66.173\"));\nassert(\"expect ping reply\", bc95.receiveResponse((line: string) => {\n return line.length > 7 && line.substr(0,7) == \"+NPING:\";\n})[0].length != 0);\n\nbc95.setServer(\"46.23.86.61\", 5883);\nbc95.sendNumber(\"test\", 123);\nassert(\"sending number\", bc95.sendOk());\nbc95.sendString(\"test\", \"value 123\");\nassert(\"sending string\", bc95.sendOk());\n\nserial.resetSerial();\nconsole.log(\"TEST FINISHED OK\");\n"
},
"pxt-calliope-bunt": {
"README.md": "# Calliope mini RGB Sensor (bunt)\n\nThis is a sensor package for the [PXT Calliope mini Editor](https://pxt.calliope.cc/).\n\n## Meta\n\n- PXT/calliope\n- PXT/microbit\n\n## License\n\nMIT",
"_locales/de/pxt-calliope-bunt-jsdoc-strings.json": "{\n \"sensors\": \"Lichtfarbe vom Calliope mini bunt Sensor lesen.\",\n \"sensors.calliopeBuntBlue\": \"Blauanteil aus dem Calliope mini bunt Sensor lesen.\",\n \"sensors.calliopeBuntColor\": \"Lichtfarbe vom Calliope mini bunt Sensor lesen.\",\n \"sensors.calliopeBuntGreen\": \"Grünanteil aus dem Calliope mini bunt Sensor lesen.\",\n \"sensors.calliopeBuntRed\": \"Rotanteil aus dem Calliope mini bunt Sensor lesen.\",\n \"sensors.calliopeBuntSetSensitivity\": \"Lichtempfindlichkeit des Calliope mini Farbsensors einstellen.\",\n \"sensors.calliopeBuntWhite\": \"Get RGBW values from Calliope mini RGB sensor.\",\n \"sensors.sensitivity\": \"Wandelt den Namen der Lichtempfindlichkeit in eine Zahl um.\"\n}",
"_locales/de/pxt-calliope-bunt-strings.json": "{\n \"Sensitivity.S0|block\": \"515 Lux (Nacht, extrem langsam)\",\n \"Sensitivity.S1|block\": \"1031 Lux (Abend, recht langsam)\",\n \"Sensitivity.S2|block\": \"2062 Lux (Dämmerung, langsam)\",\n \"Sensitivity.S4|block\": \"4124 Lux (Bewölkt, recht schnell)\",\n \"Sensitivity.S8|block\": \"8248 Lux (Tageslicht, schnell)\",\n \"Sensitivity.S16|block\": \"16496 Lux (Sonnenschein, sehr schnell)\",\n \"sensors.calliopeBuntColor|block\": \"Lichtfarbe\",\n \"sensors.calliopeBuntBlue|block\": \"erkannter Blauanteil\",\n \"sensors.calliopeBuntGreen|block\": \"erkannter Grünanteil\",\n \"sensors.calliopeBuntRed|block\": \"erkannter Rotanteil\",\n \"sensors.calliopeBuntWhite|block\": \"erkannte Helligkeit\",\n \"sensors.calliopeBuntSetSensitivity|block\": \"setze Lichtempfindlichkeit auf %sensitivity=sensitivity_id\",\n \"sensors.sensitivity|block\": \"%c\",\n \"sensors|block\": \"Sensoren\",\n \"{id:category}Sensors\": \"Sensoren\"\n}",
"main.ts": "enum Sensitivity {\n //% blockIdentity=calliopeBunt.sensitivity\n //% block=\"16496 Lux - 40ms\"\n S16 = 0b000,\n //% blockIdentity=calliopeBunt.sensitivity\n //% block=\"8248 Lux - 80ms\"\n S8 = 0b001,\n //% blockIdentity=calliopeBunt.sensitivity\n //% block=\"4124 Lux - 160ms\"\n S4 = 0b010,\n //% blockIdentity=calliopeBunt.sensitivity\n //% block=\"2062 Lux - 320ms\"\n S2 = 0b011,\n //% blockIdentity=calliopeBunt.sensitivity\n //% block=\"1031 Lux - 640ms\"\n S1 = 0b100,\n //% blockIdentity=calliopeBunt.sensitivity\n //% block=\"515 Lux - 1280ms\"\n S0 = 0b101,\n}\n\n/**\n * Read data from an Calliope mini RGB sensor.\n */\n//% color=#A80000\nnamespace sensors {\n const ADDRESS = 0x10;\n let colorSensitivity = Sensitivity.S4;\n\n /**\n * Converts the sensitivity name to a number.\n */\n //% blockId=sensitivity_id block=\"%c\" shim=TD_ID\n export function sensitivity(c: Sensitivity): number {\n return c;\n }\n\n /**\n * Set sensivity for the Calliope mini RGB sensor.\n */\n //% blockId=calliopeBunt_sensitivity block=\"set light sensitivity to %sensitivity=sensitivity_id\"\n //% parts=\"calliope-bunt\"\n //% trackArgs=0\n export function calliopeBuntSetSensitivity(sensitivity: number): void {\n colorSensitivity = sensitivity > Sensitivity.S0 ? Sensitivity.S0 : sensitivity;\n }\n\n /**\n * Get RGBW values from Calliope mini RGB sensor.\n */\n //% blockId=calliopeBunt_rgb block=\"read light color\"\n //% parts=\"calliope-bunt\"\n //% trackArgs=0\n export function calliopeBuntColor(): number {\n // enable the sensor, writing to the register\n pins.i2cWriteNumber(ADDRESS, (0x00 << 8) | (colorSensitivity << 4), NumberFormat.UInt16BE);\n\n // red\n pins.i2cWriteNumber(ADDRESS, 0x08, NumberFormat.Int8LE, true);\n let red = pins.map(pins.i2cReadNumber(ADDRESS, NumberFormat.UInt16LE), 0, 65535, 0, 255);\n\n // green\n pins.i2cWriteNumber(ADDRESS, 0x09, NumberFormat.Int8LE, true);\n let green = pins.map(pins.i2cReadNumber(ADDRESS, NumberFormat.UInt16LE), 0, 65535, 0, 255);\n\n // blue\n pins.i2cWriteNumber(ADDRESS, 0x0A, NumberFormat.Int8LE, true);\n let blue = pins.map(pins.i2cReadNumber(ADDRESS, NumberFormat.UInt16LE), 0, 65535, 0, 255);\n\n // white\n pins.i2cWriteNumber(ADDRESS, 0x0B, NumberFormat.Int8LE, true);\n let white = pins.map(pins.i2cReadNumber(ADDRESS, NumberFormat.UInt16LE), 0, 65535, 0, 255);\n\n // -- enable for debugging\n // serial.writeString(\"RGB[\");\n // serial.writeNumber(red);\n // serial.writeString(\",\");\n // serial.writeNumber(green);\n // serial.writeString(\",\");\n // serial.writeNumber(blue);\n // serial.writeString(\"](\");\n // serial.writeNumber(white);\n // serial.writeString(\")\\r\\n\");\n\n // shift colors down (only need the high byte)\n return basic.rgbw(red, green, blue, white);\n }\n\n /**\n * Get RGBW values from Calliope mini RGB sensor.\n */\n //% blockId=calliopeBunt_green block=\"erkannte Grün Farbe\"\n //% parts=\"calliope-bunt\"\n //% trackArgs=0\n export function calliopeBuntGreen(): number {\n // green\n pins.i2cWriteNumber(ADDRESS, 0x09, NumberFormat.Int8LE, true);\n let green = pins.map(pins.i2cReadNumber(ADDRESS, NumberFormat.UInt16LE), 0, 65535, 0, 255);\n // -- enable for debugging\n // serial.writeString(\"G[\");\n // serial.writeNumber(green);\n // serial.writeString(\"]\\r\\n\");\n return green;\n\n }\n\n /**\n * Get RGBW values from Calliope mini RGB sensor.\n */\n //% blockId=calliopeBunt_red block=\"erkannte Rot Farbe\"\n //% parts=\"calliope-bunt\"\n //% trackArgs=0\n export function calliopeBuntRed(): number {\n // red\n pins.i2cWriteNumber(ADDRESS, 0x08, NumberFormat.Int8LE, true);\n let red = pins.map(pins.i2cReadNumber(ADDRESS, NumberFormat.UInt16LE), 0, 65535, 0, 255);\n // -- enable for debugging\n // serial.writeString(\"R[\");\n // serial.writeNumber(red);\n // serial.writeString(\"]\\r\\n\");\n return red;\n }\n\n /**\n * Get RGBW values from Calliope mini RGB sensor.\n */\n //% blockId=calliopeBunt_blue block=\"erkannte Blau Farbe\"\n //% parts=\"calliope-bunt\"\n //% trackArgs=0\n export function calliopeBuntBlue(): number {\n // blue\n pins.i2cWriteNumber(ADDRESS, 0x0A, NumberFormat.Int8LE, true);\n let blue = pins.map(pins.i2cReadNumber(ADDRESS, NumberFormat.UInt16LE), 0, 65535, 0, 255);\n // -- enable for debugging\n // serial.writeString(\"B[\");\n // serial.writeNumber(blue);\n // serial.writeString(\"]\\r\\n\");\n return blue;\n }\n\n /**\n * Get RGBW values from Calliope mini RGB sensor.\n */\n //% blockId=calliopeBunt_white block=\"erkannte Helligkeit\"\n //% parts=\"calliope-bunt\"\n //% trackArgs=0\n export function calliopeBuntWhite(): number {\n // white\n pins.i2cWriteNumber(ADDRESS, 0x0B, NumberFormat.Int8LE, true);\n let white = pins.map(pins.i2cReadNumber(ADDRESS, NumberFormat.UInt16LE), 0, 65535, 0, 255);\n // -- enable for debugging\n // serial.writeString(\"W[\");\n // serial.writeNumber(white);\n // serial.writeString(\"]\\r\\n\");\n return white;\n }\n\n}\n",
"pxt.json": "{\n \"name\": \"pxt-calliope-bunt\",\n \"version\": \"0.0.1\",\n \"description\": \"Calliope Bunt Sensor\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"files\": [\n \"README.md\",\n \"main.ts\",\n \"_locales/de/pxt-calliope-bunt-jsdoc-strings.json\",\n \"_locales/de/pxt-calliope-bunt-strings.json\"\n ],\n \"testFiles\": [\n \"tests.ts\"\n ],\n \"public\": true\n}",
"tests.ts": "sensors.calliopeBuntSetSensitivity(Sensitivity.S0);\n// read color\nbasic.forever(() => {\n let color = sensors.calliopeBuntColor();\n basic.setLedColor(color);\n});\n"
},
"blocksprj": {
"README.md": "",
"main.blocks": "<xml xmlns=\"http://www.w3.org/1999/xhtml\">\n<block type=\"device_forever\">\n<statement name=\"HANDLER\">\n<block type=\"device_show_leds\">\n<field name=\"LED00\">FALSE</field>\n<field name=\"LED10\">FALSE</field>\n<field name=\"LED20\">FALSE</field>\n<field name=\"LED30\">FALSE</field>\n<field name=\"LED40\">FALSE</field>\n<field name=\"LED01\">FALSE</field>\n<field name=\"LED11\">TRUE</field>\n<field name=\"LED21\">FALSE</field>\n<field name=\"LED31\">TRUE</field>\n<field name=\"LED41\">FALSE</field>\n<field name=\"LED02\">FALSE</field>\n<field name=\"LED12\">FALSE</field>\n<field name=\"LED22\">FALSE</field>\n<field name=\"LED32\">FALSE</field>\n<field name=\"LED42\">FALSE</field>\n<field name=\"LED03\">TRUE</field>\n<field name=\"LED13\">FALSE</field>\n<field name=\"LED23\">FALSE</field>\n<field name=\"LED33\">FALSE</field>\n<field name=\"LED43\">TRUE</field>\n<field name=\"LED04\">FALSE</field>\n<field name=\"LED14\">TRUE</field>\n<field name=\"LED24\">TRUE</field>\n<field name=\"LED34\">TRUE</field>\n<field name=\"LED44\">FALSE</field>\n<next>\n<block type=\"device_show_leds\">\n<field name=\"LED00\">FALSE</field>\n<field name=\"LED10\">FALSE</field>\n<field name=\"LED20\">FALSE</field>\n<field name=\"LED30\">FALSE</field>\n<field name=\"LED40\">FALSE</field>\n<field name=\"LED01\">FALSE</field>\n<field name=\"LED11\">FALSE</field>\n<field name=\"LED21\">FALSE</field>\n<field name=\"LED31\">FALSE</field>\n<field name=\"LED41\">FALSE</field>\n<field name=\"LED02\">FALSE</field>\n<field name=\"LED12\">FALSE</field>\n<field name=\"LED22\">FALSE</field>\n<field name=\"LED32\">FALSE</field>\n<field name=\"LED42\">FALSE</field>\n<field name=\"LED03\">FALSE</field>\n<field name=\"LED13\">FALSE</field>\n<field name=\"LED23\">FALSE</field>\n<field name=\"LED33\">FALSE</field>\n<field name=\"LED43\">FALSE</field>\n<field name=\"LED04\">FALSE</field>\n<field name=\"LED14\">FALSE</field>\n<field name=\"LED24\">FALSE</field>\n<field name=\"LED34\">FALSE</field>\n<field name=\"LED44\">FALSE</field>\n</block>\n</next>\n</block>\n</statement>\n</block>\n</xml>",
"main.ts": "basic.forever(() => {\n basic.showLeds(`\n . # . # .\n # . # . #\n # . . . #\n . # . # .\n . . # . .\n `)\n basic.showLeds(`\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n `)\n})",
"pxt.json": "{\n \"name\": \"{0} block\",\n \"dependencies\": {\n \"core\": \"*\",\n \"radio\": \"*\"\n },\n \"description\": \"\",\n \"files\": [\n \"main.blocks\",\n \"main.ts\",\n \"README.md\"\n ]\n}"
},
"bluetoothprj": {
"README.md": "",
"main.blocks": "<xml xmlns=\"http://www.w3.org/1999/xhtml\">\n<block type=\"device_forever\">\n<statement name=\"HANDLER\">\n<block type=\"device_show_leds\">\n<field name=\"LED00\">FALSE</field>\n<field name=\"LED10\">FALSE</field>\n<field name=\"LED20\">FALSE</field>\n<field name=\"LED30\">FALSE</field>\n<field name=\"LED40\">FALSE</field>\n<field name=\"LED01\">FALSE</field>\n<field name=\"LED11\">TRUE</field>\n<field name=\"LED21\">FALSE</field>\n<field name=\"LED31\">TRUE</field>\n<field name=\"LED41\">FALSE</field>\n<field name=\"LED02\">FALSE</field>\n<field name=\"LED12\">FALSE</field>\n<field name=\"LED22\">FALSE</field>\n<field name=\"LED32\">FALSE</field>\n<field name=\"LED42\">FALSE</field>\n<field name=\"LED03\">TRUE</field>\n<field name=\"LED13\">FALSE</field>\n<field name=\"LED23\">FALSE</field>\n<field name=\"LED33\">FALSE</field>\n<field name=\"LED43\">TRUE</field>\n<field name=\"LED04\">FALSE</field>\n<field name=\"LED14\">TRUE</field>\n<field name=\"LED24\">TRUE</field>\n<field name=\"LED34\">TRUE</field>\n<field name=\"LED44\">FALSE</field>\n<next>\n<block type=\"device_show_leds\">\n<field name=\"LED00\">FALSE</field>\n<field name=\"LED10\">FALSE</field>\n<field name=\"LED20\">FALSE</field>\n<field name=\"LED30\">FALSE</field>\n<field name=\"LED40\">FALSE</field>\n<field name=\"LED01\">FALSE</field>\n<field name=\"LED11\">FALSE</field>\n<field name=\"LED21\">FALSE</field>\n<field name=\"LED31\">FALSE</field>\n<field name=\"LED41\">FALSE</field>\n<field name=\"LED02\">FALSE</field>\n<field name=\"LED12\">FALSE</field>\n<field name=\"LED22\">FALSE</field>\n<field name=\"LED32\">FALSE</field>\n<field name=\"LED42\">FALSE</field>\n<field name=\"LED03\">FALSE</field>\n<field name=\"LED13\">FALSE</field>\n<field name=\"LED23\">FALSE</field>\n<field name=\"LED33\">FALSE</field>\n<field name=\"LED43\">FALSE</field>\n<field name=\"LED04\">FALSE</field>\n<field name=\"LED14\">FALSE</field>\n<field name=\"LED24\">FALSE</field>\n<field name=\"LED34\">FALSE</field>\n<field name=\"LED44\">FALSE</field>\n</block>\n</next>\n</block>\n</statement>\n</block>\n</xml>",
"main.ts": "basic.forever(() => {\n basic.showLeds(`\n . # . # .\n # . # . #\n # . . . #\n . # . # .\n . . # . .\n `)\n basic.showLeds(`\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n . . . . .\n `)\n})",
"pxt.json": "{\n \"name\": \"{0} block\",\n \"dependencies\": {\n \"core\": \"*\",\n \"bluetooth\": \"*\"\n },\n \"description\": \"\",\n \"files\": [\n \"main.blocks\",\n \"main.ts\",\n \"README.md\"\n ]\n}"
},
"tsprj": {
"README.md": "",
"main.ts": "basic.showLeds(`\n . . . . .\n . # . # .\n . . . . .\n # . . . #\n . # # # .\n `);",
"pxt.json": "{\n \"name\": \"{0} bit\",\n \"dependencies\": {\n \"core\": \"*\",\n \"radio\": \"*\"\n },\n \"description\": \"\",\n \"files\": [\n \"main.ts\",\n \"README.md\"\n ]\n}"
}
},
"versions": {
"target": "1.0.11",
"pxt": "1.0.20"
}
}