{
"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": "\n\n\n\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nTRUE\nFALSE\nTRUE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nTRUE\nFALSE\nFALSE\nFALSE\nTRUE\nFALSE\nTRUE\nTRUE\nTRUE\nFALSE\n\n\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\nFALSE\n\n\n\n\n\n",
"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 \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 \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 = ([]);\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": "",
"parts/headphone.svg": "",
"parts/speaker.svg": "\n",
"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": "/// \n\ninterface Array {\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(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(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(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(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(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(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(arr: T[], value: T) : number {\n arr.insertAt(0, value);\n return arr.length;\n }\n\n function swap(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(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(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(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(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(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