UNPKG

pxt-maker

Version:
939 lines 10.7 MB
{ "id": "maker", "platformid": "codal", "nickname": "maker", "name": "MakeCode Maker (Cortex class)", "title": "MakeCode Maker - Blocks / Javascript editor", "description": "A Blocks / JavaScript code editor for MakeCode Maker Boards", "corepkg": "core", "bundleddirs": [ "libs/base", "libs/base---light", "libs/core", "libs/core---stm32", "libs/core---nrf52", "libs/core---rp2040", "libs/core---samd", "libs/core---samd51", "libs/core---esp32", "libs/core---esp32s2", "libs/screen---st7735", "libs/pulse", "libs/infrared", "libs/game", "libs/game---light", "libs/mixer", "libs/mixer---none", "libs/mixer---samd", "libs/mixer---stm32", "libs/mixer---nrf52", "libs/mixer---rp2040", "libs/pixel", "libs/buttons", "libs/touch", "libs/light", "libs/tests", "libs/gamepad", "libs/mouse", "libs/keyboard", "libs/display", "libs/servo", "libs/storage", "libs/serial", "libs/datalogger", "libs/lightsensor", "libs/thermometer", "libs/switch", "libs/accelerometer", "libs/microphone", "libs/lora", "libs/power", "libs/lcd", "libs/color", "libs/color-sensor", "libs/light-spectrum-sensor", "libs/proximity", "libs/feather", "libs/edge-connector", "libs/esp32", "libs/net", "libs/net-game", "libs/wifi---esp32", "libs/mqtt", "libs/azureiot", "libs/settings", "libs/settings---esp32", "libs/settings---files", "libs/radio", "libs/radio-broadcast", "libs/matrix-keypad", "libs/adafruit-feather-m0-express", "libs/adafruit-feather-m4-express", "libs/adafruit-feather-nrf52840-express", "libs/nucleo-f411re", "libs/adafruit-circuit-playground-express", "libs/adafruit-circuit-playground-bluefruit", "libs/adafruit-trinket-m0", "libs/adafruit-metro-m0-express", "libs/adafruit-metro-m4-express", "libs/adafruit-itsybitsy-m0-express", "libs/adafruit-itsybitsy-m4-express", "libs/adafruit-itsybitsy-nrf52840-express", "libs/adafruit-neotrellis-m4-express", "libs/adafruit-gemma-m0", "libs/robotics-masters-robohatmm1-m4", "libs/adafruit-grand-central-m4-express", "libs/xinabox-cc03", "libs/xinabox-cs11", "libs/arduino-zero", "libs/arduino-mkr1000", "libs/arduino-mkr1010", "libs/arduino-mkr1300", "libs/arduino-nano-33-ble-sense", "libs/electroniccats-meow-meow", "libs/electroniccats-escornabot-makech", "libs/sparkfun-samd21-dev-breakout", "libs/sparkfun-samd21-mini-breakout", "libs/sparkfun-redboard-turbo", "libs/sparkfun-lumidrive", "libs/brain-nrf52840", "libs/stitchkit", "libs/machachi", "libs/espressif-esp32-devkit-c", "libs/rpi-pico", "libs/jacdac-nrfbrain", "libs/jacdac-brain-f4", "libs/jacdac-brain-rp2040", "libs/jacdac-iot-s2" ], "serial": { "useHF2": true, "useEditor": true, "log": true, "editorTheme": { "graphBackground": "#d9d9d9", "lineColors": [ "#CC2936", "#FFC914", "#2EB7ED", "#FB48C7", "#08415C", "#C200C0" ] } }, "simulator": { "autoRun": true, "streams": false, "aspectRatio": 1, "parts": true, "partsAspectRatio": 0.69, "dynamicBoardDefinition": true, "messageSimulators": { "jacdac": { "url": "https://microsoft.github.io/jacdac-docs/tools/makecode-sim?webusb=0&parentOrigin=$PARENT_ORIGIN$", "localHostUrl": "http://localhost:8000/tools/makecode-sim?webusb=0&parentOrigin=$PARENT_ORIGIN$", "aspectRatio": 0.89, "permanent": true } } }, "cloud": { "workspace": false, "packages": true, "sharing": true, "thumbnails": true, "publishing": true, "importing": true, "preferredPackages": [], "githubPackages": true, "cloudProviders": { "github": {} } }, "runtime": { "mathBlocks": true, "loopsBlocks": true, "logicBlocks": true, "variablesBlocks": true, "textBlocks": true, "listsBlocks": true, "functionBlocks": true, "functionsOptions": { "useNewFunctions": true, "extraFunctionEditorTypes": [] }, "onStartNamespace": "loops", "onStartColor": "#40bf4a", "onStartWeight": 100, "pauseUntilBlock": {}, "breakBlock": true, "continueBlock": true, "palette": [ "#000000", "#ffffff", "#ff2121", "#ff93c4", "#ff8135", "#fff609", "#249ca3", "#78dc52", "#003fad", "#87f2ff", "#8e2ec4", "#a4839f", "#5c406c", "#e5cdc4", "#91463d", "#000000" ], "screenSize": { "width": 160, "height": 120 } }, "compile": { "isNative": true, "useUF2": true, "webUSB": true, "hasHex": true, "saveAsPNG": true, "deployDrives": ".*", "deployFileMarker": "INFO_UF2.TXT", "driveName": "DRIVE", "openocdScript": "source [find interface/cmsis-dap.cfg]; set CHIPNAME at91samd21g18; source [find target/at91samdXX.cfg]", "flashChecksumAddr": 8372, "flashCodeAlign": 256, "upgrades": [ { "type": "package", "map": { "circuit-playground": "adafruit-circuit-playground" } } ], "patches": { "0.0.0 - 0.6.8": [ { "type": "package", "map": { "arduino-mkr": "arduino-mkr1000" } } ] }, "nativeType": "thumb", "switches": {}, "jsRefCounting": false, "utf8": true }, "compileService": { "buildEngine": "codal", "codalTarget": { "name": "missing", "url": "https://github.com/microsoft/pxt-does-not-exist", "branch": "v0", "type": "git" }, "codalBinary": "CIRCUIT_PLAYGROUND", "yottaConfig": { "pxt": { "board": { "id": "BOARD_ID_CPLAY" } } }, "githubCorePackage": "lancaster-university/codal", "gittag": "v0.9.0", "serviceId": "codal2cp", "dockerImage": "pext/yotta:latest" }, "variants": { "samd51": { "compile": { "hasHex": true, "openocdScript": "source [find interface/cmsis-dap.cfg]; set CHIPNAME at91samd51g19; source [find target/atsame5x.cfg]", "openocdScriptAlt": "source [find interface/stlink-v2.cfg]; set CPUTAPID 0x2ba01477; set CHIPNAME at91samd51g19; source [find target/at91samdXX.cfg]", "ramSize": 196608, "flashEnd": 524288, "uf2Family": "0x55114460" }, "compileService": { "codalTarget": { "name": "codal-itsybitsy-m4", "url": "https://github.com/lancaster-university/codal-itsybitsy-m4", "branch": "v0.2.7", "type": "git" }, "codalBinary": "ITSYBITSY_M4", "serviceId": "codal2samd51" } }, "nrf52840": { "serial": { "useHF2": false }, "compile": { "openocdScript": "source [find interface/cmsis-dap.cfg]; source [find target/nrf52.cfg]", "flashChecksumAddr": 0, "webUSB": false, "flashEnd": 1007616, "uf2Family": "0xada52840" }, "compileService": { "codalTarget": { "name": "codal-nrf52840-dk", "url": "https://github.com/mmoskal/codal-nrf52840-dk", "branch": "v1.1.8", "type": "git" }, "codalBinary": "NRF52840_DK", "serviceId": "codal2nrf52840", "dockerImage": "pext/yotta:latest", "yottaConfig": { "pxt": { "board": { "id": "BOARD_ID_NRF52840" } } } } }, "nrf52833": { "serial": { "useHF2": true }, "compile": { "openocdScript": "source [find interface/cmsis-dap.cfg]; source [find target/nrf52.cfg]", "flashChecksumAddr": 0, "webUSB": true, "flashEnd": 475136, "uf2Family": "0xada52840" }, "compileService": { "codalTarget": { "name": "codal-makeable", "url": "https://github.com/jamesadevine/codal-makeable", "branch": "v0.0.8", "type": "git" }, "codalBinary": "NRF52", "serviceId": "codal2nrf52", "dockerImage": "pext/yotta:latest", "yottaConfig": { "pxt": { "board": { "id": "BOARD_ID_NRF52833" } } } } }, "stm32f103": { "compile": { "hasHex": true, "openocdScript": "source [find interface/stlink-v2.cfg]; source [find target/stm32f1x.cfg]", "uf2Family": "0x5ee21072", "webUSB": false, "flashChecksumAddr": 0, "utf8": true }, "compileService": { "codalTarget": { "name": "codal-jacdac-feather", "url": "https://github.com/lancaster-university/codal-jacdac-feather", "branch": "v1.1.2", "type": "git" }, "codalBinary": "STM32", "serviceId": "codal2stm32", "dockerImage": "pext/yotta:latest" } }, "stm32f401": { "compile": { "hasHex": true, "openocdScript": "source [find interface/cmsis-dap.cfg]; source [find target/stm32f4x.cfg]", "flashChecksumAddr": 0, "flashEnd": 524288, "uf2Family": "0x57755a57" }, "compileService": { "codalTarget": { "name": "codal-big-brainpad", "url": "https://github.com/lancaster-university/codal-big-brainpad", "branch": "v1.3.4", "type": "git" }, "codalBinary": "STM32", "serviceId": "codal2stm32", "dockerImage": "pext/yotta:latest" } }, "samd21": { "compile": { "hasHex": true, "openocdScript": "source [find interface/cmsis-dap.cfg]; set CHIPNAME at91samd21g18; source [find target/at91samdXX.cfg]", "openocdScriptAlt": "source [find interface/stlink-v2.cfg]; set CPUTAPID 0x0bc11477; set CHIPNAME at91samd21g18; source [find target/at91samdXX.cfg]", "flashEnd": 262144, "uf2Family": "0x68ed2b88" }, "compileService": { "codalTarget": { "name": "codal-circuit-playground", "url": "https://github.com/lancaster-university/codal-circuit-playground", "branch": "v2.0.4", "type": "git" }, "dockerImage": "pext/yotta:latest", "codalBinary": "CIRCUIT_PLAYGROUND" } }, "esp32": { "compile": { "hasHex": true, "useESP": true, "useUF2": false, "flashCodeAlign": 256, "webUSB": false, "nativeType": "vm", "stackAlign": 2 }, "compileService": { "buildEngine": "dockerespidf", "dockerImage": "pext/esp:latest", "dockerArgs": [], "serviceId": "espidf" } }, "esp32s2": { "compile": { "hasHex": true, "useESP": true, "useUF2": true, "flashCodeAlign": 256, "webUSB": false, "nativeType": "vm", "uf2Family": "0xbfdd4eee", "stackAlign": 2 }, "compileService": { "buildEngine": "dockerespidf", "dockerImage": "pext/esp:latest", "dockerArgs": [], "serviceId": "espidf" } }, "rp2040": { "compile": { "hasHex": true, "openocdScript": "???", "flashChecksumAddr": 0, "flashEnd": 2097152, "uf2Family": "0xe48bff56" }, "compileService": { "codalTarget": { "name": "codal-pi-pico", "url": "https://github.com/lancaster-university/codal-pi-pico", "branch": "v0.0.10", "type": "git" }, "codalBinary": "PI-PICO", "serviceId": "codal2pico", "dockerImage": "pext/arm:gcc9" } } }, "appTheme": { "accentColor": "#ecf0f1", "backgroundColor": "#ffffff", "logoUrl": "https://github.com/microsoft/pxt-maker", "logo": "@cdnUrl@/blob/78e4304c9678839a1c6e673528aa200003065f40/static/logo.svg", "docsLogo": "@cdnUrl@/blob/78e4304c9678839a1c6e673528aa200003065f40/static/logo.svg", "docsHeader": "Microsoft MakeCode Maker", "portraitLogo": "@cdnUrl@/blob/78e4304c9678839a1c6e673528aa200003065f40/static/logo.svg", "footerLogo": "@cdnUrl@/blob/78e4304c9678839a1c6e673528aa200003065f40/static/logo.svg", "organization": "Microsoft MakeCode", "organizationUrl": "https://makecode.com/", "organizationLogo": "@cdnUrl@/blob/e6a56b2e978a522726c938cad286bf3d15aa7b51/static/Microsoft-logo_rgb_c-gray-square.png", "organizationWideLogo": "@cdnUrl@/blob/cd1a7c2065a8aae2437d49888f9a7f35d77932d8/static/Microsoft-logo_rgb_c-gray.png", "homeUrl": "https://maker.makecode.com/", "embedUrl": "https://maker.makecode.com/", "privacyUrl": "https://go.microsoft.com/fwlink/?LinkId=521839", "termsOfUseUrl": "https://go.microsoft.com/fwlink/?LinkID=206977", "githubUrl": "https://github.com/microsoft/pxt-maker", "feedbackUrl": "https://forum.makecode.com/", "betaUrl": "https://github.com/microsoft/pxt-maker", "boardName": "board", "homeScreenHero": "@cdnUrl@/blob/4fe4d3e3fc36749019b929a071ad2015815550b9/static/hero.jpg", "debugger": true, "print": true, "chooseBoardOnNewProject": true, "lightToc": true, "instructions": true, "docMenu": [ { "name": "About", "path": "/about" }, { "name": "Forum", "path": "https://forum.makecode.com" }, { "name": "Boards", "path": "/boards" }, { "name": "Blocks", "path": "/blocks" }, { "name": "JavaScript", "path": "/javascript" }, { "name": "Reference", "path": "/reference" }, { "name": "GitHub", "path": "https://github.com/microsoft/pxt-maker" } ], "invertedMenu": false, "invertedToolbox": false, "invertedMonaco": false, "monacoToolbox": true, "highContrast": true, "greenScreen": true, "blocksCollapsing": true, "accessibleBlocks": true, "simAnimationEnter": "fly right in", "simAnimationExit": "fly right out", "hasAudio": true, "usbDocs": "/device/usb", "disableBlockIcons": true, "disableAPICache": true, "blocklyOptions": { "grid": { "spacing": 20, "length": 2, "colour": "rgba(189, 195, 199, 0.20)", "snap": true } }, "blockColors": { "loops": "#40bf4a", "logic": "#4cbfe6", "math": "#9966ff", "variables": "#FF6680", "text": "#ffab19", "advanced": "#00272B", "functions": "#005a9e", "arrays": "#8A1C7C" }, "allowPackageExtensions": true, "scriptManager": true, "simScreenshot": true, "simGif": true, "qrCode": true, "python": true, "pythonToolbox": true, "addNewTypeScriptFile": true, "alwaysGithubItemBlocks": true, "alwaysGithubItem": true, "githubBlocksDiff": true, "nameProjectFirst": true, "showProjectSettings": true, "selectLanguage": false, "githubEditor": true, "tutorialBlocksDiff": true, "tutorialExplicitHints": true, "chooseLanguageRestrictionOnNewProject": true, "openProjectNewTab": true, "errorList": true, "TOC": [ { "name": "About", "path": "/about", "subitems": [] }, { "name": "FAQ", "path": "/faq", "subitems": [] }, { "name": "Projects", "path": "/projects", "subitems": [] }, { "name": "GitHub", "path": "/github", "subitems": [] }, { "name": "Reference", "path": "/reference", "subitems": [ { "name": "music", "path": "/reference/music", "subitems": [] }, { "name": "pins", "path": "/reference/pins", "subitems": [] }, { "name": "control", "path": "/reference/control", "subitems": [] }, { "name": "serial", "path": "/reference/serial", "subitems": [] } ] }, { "name": "Blocks", "path": "/blocks", "subitems": [ { "name": "On Start", "path": "/blocks/on-start", "subitems": [] }, { "name": "Loops", "path": "/blocks/loops", "subitems": [ { "name": "repeat", "path": "/blocks/loops/repeat", "subitems": [] }, { "name": "for", "path": "/blocks/loops/for", "subitems": [] }, { "name": "while", "path": "/blocks/loops/while", "subitems": [] }, { "name": "for of", "path": "/blocks/loops/for-of", "subitems": [] } ] }, { "name": "Logic", "path": "/blocks/logic", "subitems": [ { "name": "if", "path": "/blocks/logic/if", "subitems": [] }, { "name": "Boolean", "path": "/blocks/logic/boolean", "subitems": [] } ] }, { "name": "Variables", "path": "/blocks/variables", "subitems": [ { "name": "assign", "path": "/blocks/variables/assign", "subitems": [] }, { "name": "change var", "path": "/blocks/variables/change", "subitems": [] }, { "name": "var", "path": "/blocks/variables/var", "subitems": [] } ] }, { "name": "Math", "path": "/blocks/math", "subitems": [] }, { "name": "JavaScript blocks", "path": "/blocks/javascript-blocks", "subitems": [] }, { "name": "Custom blocks", "path": "/blocks/custom", "subitems": [] } ] }, { "name": "Python", "path": "/python", "subitems": [ { "name": "Calling", "path": "/python/call", "subitems": [] }, { "name": "Sequencing", "path": "/python/sequence", "subitems": [] }, { "name": "Variables", "path": "/python/variables", "subitems": [] }, { "name": "Operators", "path": "/python/operators", "subitems": [] }, { "name": "Statements", "path": "/python/statements", "subitems": [] }, { "name": "Functions", "path": "/python/functions", "subitems": [] }, { "name": "Classes", "path": "/python/classes", "subitems": [] } ] }, { "name": "JavaScript", "path": "/javascript", "subitems": [ { "name": "Calling", "path": "/javascript/call", "subitems": [] }, { "name": "Sequencing", "path": "/javascript/sequence", "subitems": [] }, { "name": "Variables", "path": "/javascript/variables", "subitems": [] }, { "name": "Operators", "path": "/javascript/operators", "subitems": [] }, { "name": "Statements", "path": "/javascript/statements", "subitems": [] }, { "name": "Functions", "path": "/javascript/functions", "subitems": [] }, { "name": "Types", "path": "/javascript/types", "subitems": [] }, { "name": "Classes", "path": "/javascript/classes", "subitems": [] }, { "name": "Interfaces", "path": "/javascript/interfaces", "subitems": [] }, { "name": "Generics", "path": "/javascript/generics", "subitems": [] } ] }, { "name": "Types", "path": "/types", "subitems": [ { "name": "Number", "path": "/types/number", "subitems": [] }, { "name": "String", "path": "/types/string", "subitems": [] }, { "name": "Boolean", "path": "/types/boolean", "subitems": [] }, { "name": "Array", "path": "/types/array", "subitems": [] }, { "name": "Function", "path": "/types/function", "subitems": [] } ] }, { "name": "Miscellaneous", "path": "", "subitems": [ { "name": "About", "path": "/about", "subitems": [] }, { "name": "Support", "path": "/support", "subitems": [] }, { "name": "Translate", "path": "/translate", "subitems": [] }, { "name": "Sharing projects", "path": "/share", "subitems": [] }, { "name": "Offline support", "path": "/offline", "subitems": [] }, { "name": "Save", "path": "/save", "subitems": [] } ] }, { "name": "Developers", "path": "", "subitems": [ { "name": "Command Line Interface", "path": "/cli", "subitems": [] }, { "name": "Visual Studio Code support", "path": "/code", "subitems": [] }, { "name": "Blocks Embed", "path": "/blocks-embed", "subitems": [] } ] } ], "id": "maker", "title": "MakeCode Maker - Blocks / Javascript editor", "name": "MakeCode Maker (Cortex class)", "description": "A Blocks / JavaScript code editor for MakeCode Maker Boards", "htmlDocIncludes": {} }, "ignoreDocsErrors": true, "uploadDocs": false, "versions": { "branch": "v0.15.66", "tag": "v0.15.66", "commits": "https://github.com/microsoft/pxt-maker/commits/1439f19f93e7699d21b816a9b7ed60840b0d3924", "target": "0.15.66", "pxt": "8.1.1" }, "blocksprj": { "id": "blocksprj", "config": { "name": "{0}", "dependencies": { "adafruit-metro-m0-express": "*" }, "description": "", "files": [ "main.blocks", "main.ts", "README.md" ], "additionalFilePaths": [] }, "files": { "README.md": "", "main.blocks": "<xml xmlns=\"http://www.w3.org/1999/xhtml\">\n <block type=\"pxt-on-start\" x=\"0\" y=\"0\"></block>\n <block type=\"forever\" x=\"176\" y=\"0\"></block>\n</xml>", "main.ts": "\n" } }, "tsprj": { "id": "tsprj", "config": { "name": "{0}", "dependencies": { "adafruit-metro-m0-express": "*" }, "description": "", "files": [ "main.ts", "README.md" ], "additionalFilePaths": [] }, "files": { "README.md": "", "main.ts": "\n" } }, "bundledpkgs": { "base": { "README.md": "# base\n\nThe base library, shared by all C++ targets (not only Codal-based).\n\n\n", "advmath.cpp": "#include \"pxtbase.h\"\n\nusing namespace std;\n\n#define SINGLE(op) return fromDouble(::op(toDouble(x)));\n\nnamespace Math_ {\n\n//%\nTNumber log2(TNumber x){SINGLE(log2)}\n//%\nTNumber exp(TNumber x){SINGLE(exp)}\n//%\nTNumber tanh(TNumber x){SINGLE(tanh)}\n//%\nTNumber sinh(TNumber x){SINGLE(sinh)}\n//%\nTNumber cosh(TNumber x){SINGLE(cosh)}\n//%\nTNumber atanh(TNumber x){SINGLE(atanh)}\n//%\nTNumber asinh(TNumber x){SINGLE(asinh)}\n//%\nTNumber acosh(TNumber x){SINGLE(acosh)}\n\n}", "buffer.cpp": "#include \"pxtbase.h\"\n#include <limits.h>\n\nusing namespace std;\n\n//% indexerGet=BufferMethods::getByte indexerSet=BufferMethods::setByte\nnamespace BufferMethods {\n//%\nuint8_t *getBytes(Buffer buf) {\n return buf->data;\n}\n\n//%\nint getByte(Buffer buf, int off) {\n if (buf && 0 <= off && off < buf->length)\n return buf->data[off];\n return 0;\n}\n\n//%\nvoid setByte(Buffer buf, int off, int v) {\n if (buf && 0 <= off && off < buf->length)\n buf->data[off] = v;\n}\n\n/**\n * Reads an unsigned byte at a particular location\n */\n//%\nint getUint8(Buffer buf, int off) {\n return getByte(buf, off);\n}\n\n/**\n * Returns false when the buffer can be written to.\n */\n//%\nbool isReadOnly(Buffer buf) {\n return buf->isReadOnly();\n}\n\n/**\n * Writes an unsigned byte at a particular location\n */\n//%\nvoid setUint8(Buffer buf, int off, int v) {\n setByte(buf, off, v);\n}\n\nint writeBuffer(Buffer buf, int dstOffset, Buffer src, int srcOffset = 0, int length = -1) {\n if (length < 0)\n length = src->length;\n\n if (srcOffset < 0 || dstOffset < 0 || dstOffset > buf->length)\n return -1;\n\n length = pxt::min(src->length - srcOffset, buf->length - dstOffset);\n\n if (length < 0)\n return -1;\n\n if (buf == src) {\n memmove(buf->data + dstOffset, src->data + srcOffset, length);\n } else {\n memcpy(buf->data + dstOffset, src->data + srcOffset, length);\n }\n\n return 0;\n}\n\n/**\n * Write a number in specified format in the buffer.\n */\n//%\nvoid setNumber(Buffer buf, NumberFormat format, int offset, TNumber value) {\n if (offset < 0)\n return;\n setNumberCore(buf->data + offset, buf->length - offset, format, value);\n}\n\n/**\n * Read a number in specified format from the buffer.\n */\n//%\nTNumber getNumber(Buffer buf, NumberFormat format, int offset) {\n if (offset < 0)\n return fromInt(0);\n return getNumberCore(buf->data + offset, buf->length - offset, format);\n}\n\n/** Returns the length of a Buffer object. */\n//% property\nint length(Buffer s) {\n return s->length;\n}\n\n/**\n * Fill (a fragment) of the buffer with given value.\n */\n//%\nvoid fill(Buffer buf, int value, int offset = 0, int length = -1) {\n if (offset < 0 || offset > buf->length)\n return; // DEVICE_INVALID_PARAMETER;\n if (length < 0)\n length = buf->length;\n length = pxt::min(length, buf->length - offset);\n memset(buf->data + offset, value, length);\n}\n\n/**\n * Return a copy of a fragment of a buffer.\n */\n//%\nBuffer slice(Buffer buf, int offset = 0, int length = -1) {\n offset = pxt::min((int)buf->length, offset);\n if (length < 0)\n length = buf->length;\n length = pxt::min(length, buf->length - offset);\n return mkBuffer(buf->data + offset, length);\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\n * start. eg: -1\n */\n//%\nvoid shift(Buffer buf, int offset, int start = 0, int length = -1) {\n if (length < 0)\n length = buf->length - start;\n if (start < 0 || start + length > buf->length || start + length < start || length == 0 ||\n offset == 0 || offset == INT_MIN)\n return;\n if (offset <= -length || offset >= length) {\n fill(buf, 0);\n return;\n }\n\n uint8_t *data = buf->data + start;\n if (offset < 0) {\n offset = -offset;\n memmove(data + offset, data, length - offset);\n memset(data, 0, offset);\n } else {\n length = length - offset;\n memmove(data, data + offset, length);\n memset(data + length, 0, offset);\n }\n}\n\n/**\n * Convert a buffer to string assuming UTF8 encoding\n */\n//%\nString toString(Buffer buf) {\n return mkString((char *)buf->data, buf->length);\n}\n\n/**\n * Convert a buffer to its hexadecimal representation.\n */\n//%\nString toHex(Buffer buf) {\n const char *hex = \"0123456789abcdef\";\n auto res = mkStringCore(NULL, buf->length * 2);\n for (int i = 0; i < buf->length; ++i) {\n res->ascii.data[i << 1] = hex[buf->data[i] >> 4];\n res->ascii.data[(i << 1) + 1] = hex[buf->data[i] & 0xf];\n }\n return res;\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\n * start. eg: -1\n */\n//%\nvoid rotate(Buffer buf, int offset, int start = 0, int length = -1) {\n if (length < 0)\n length = buf->length - start;\n if (start < 0 || start + length > buf->length || start + length < start || length == 0 ||\n offset == 0 || offset == INT_MIN)\n return;\n\n if (offset < 0)\n offset += length << 8; // try to make it positive\n offset %= length;\n if (offset < 0)\n offset += length;\n\n uint8_t *data = buf->data + 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 + length;\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\n/**\n * Write contents of `src` at `dstOffset` in current buffer.\n */\n//%\nvoid write(Buffer buf, int dstOffset, Buffer src) {\n // srcOff and length not supported, we only do up to 4 args :/\n writeBuffer(buf, dstOffset, src, 0, -1);\n}\n\n/**\n * Compute k-bit FNV-1 non-cryptographic hash of the buffer.\n */\n//%\nuint32_t hash(Buffer buf, int bits) {\n if (bits < 1)\n return 0;\n uint32_t h = hash_fnv1(buf->data, buf->length);\n if (bits >= 32)\n return h;\n else\n return ((h ^ (h >> bits)) & ((1 << bits) - 1));\n}\n\n} // namespace BufferMethods\n\nbool BoxedBuffer::isInstance(TValue v) {\n return getAnyVTable(v) == &buffer_vt;\n}\n\n// The functions below are deprecated in control namespace, but they are referenced\n// in Buffer namespaces via explicit shim=...\nnamespace control {\n/**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n//% deprecated=1\nBuffer createBuffer(int size) {\n return mkBuffer(NULL, size);\n}\n\n/**\n * Create a new buffer with UTF8-encoded string\n * @param str the string to put in the buffer\n */\n//% deprecated=1\nBuffer createBufferFromUTF8(String str) {\n#if PXT_UTF8\n auto sz = toRealUTF8(str, NULL);\n auto r = mkBuffer(NULL, sz);\n toRealUTF8(str, r->data);\n return r;\n#else\n return mkBuffer((const uint8_t *)str->getUTF8Data(), str->getUTF8Size());\n#endif\n}\n} // namespace control\n\nnamespace pxt {\nstatic int writeBytes(uint8_t *dst, uint8_t *src, int length, bool swapBytes, int szLeft) {\n if (szLeft < length) {\n return -1;\n }\n\n if (swapBytes) {\n uint8_t *p = dst + length;\n for (int i = 0; i < length; ++i)\n *--p = src[i];\n } else {\n if (length == 4 && ((uintptr_t)dst & 3) == 0)\n *(uint32_t *)dst = *(uint32_t *)src;\n else if (length == 2 && ((uintptr_t)dst & 1) == 0)\n *(uint16_t *)dst = *(uint16_t *)src;\n else\n memcpy(dst, src, length);\n }\n\n return 0;\n}\n\nstatic int readBytes(uint8_t *src, uint8_t *dst, int length, bool swapBytes, int szLeft) {\n if (szLeft < length) {\n memset(dst, 0, length);\n return -1;\n }\n\n if (swapBytes) {\n uint8_t *p = src + length;\n for (int i = 0; i < length; ++i)\n dst[i] = *--p;\n } else {\n if (length == 4 && ((uintptr_t)src & 3) == 0)\n *(uint32_t *)dst = *(uint32_t *)src;\n else if (length == 2 && ((uintptr_t)src & 1) == 0)\n *(uint16_t *)dst = *(uint16_t *)src;\n else\n memcpy(dst, src, length);\n }\n\n return 0;\n}\n\nvoid setNumberCore(uint8_t *buf, int szLeft, NumberFormat format, TNumber value) {\n int8_t i8;\n uint8_t u8;\n int16_t i16;\n uint16_t u16;\n int32_t i32;\n uint32_t u32;\n float f32;\n double f64;\n\n// Assume little endian\n#define WRITEBYTES(isz, swap, toInt) \\\n isz = toInt(value); \\\n writeBytes(buf, (uint8_t *)&isz, sizeof(isz), swap, szLeft); \\\n break\n\n switch (format) {\n case NumberFormat::Int8LE:\n WRITEBYTES(i8, false, toInt);\n case NumberFormat::UInt8LE:\n WRITEBYTES(u8, false, toInt);\n case NumberFormat::Int16LE:\n WRITEBYTES(i16, false, toInt);\n case NumberFormat::UInt16LE:\n WRITEBYTES(u16, false, toInt);\n case NumberFormat::Int32LE:\n WRITEBYTES(i32, false, toInt);\n case NumberFormat::UInt32LE:\n WRITEBYTES(u32, false, toUInt);\n\n case NumberFormat::Int8BE:\n WRITEBYTES(i8, true, toInt);\n case NumberFormat::UInt8BE:\n WRITEBYTES(u8, true, toInt);\n case NumberFormat::Int16BE:\n WRITEBYTES(i16, true, toInt);\n case NumberFormat::UInt16BE:\n WRITEBYTES(u16, true, toInt);\n case NumberFormat::Int32BE:\n WRITEBYTES(i32, true, toInt);\n case NumberFormat::UInt32BE:\n WRITEBYTES(u32, true, toUInt);\n\n case NumberFormat::Float32LE:\n WRITEBYTES(f32, false, toFloat);\n case NumberFormat::Float32BE:\n WRITEBYTES(f32, true, toFloat);\n case NumberFormat::Float64LE:\n WRITEBYTES(f64, false, toDouble);\n case NumberFormat::Float64BE:\n WRITEBYTES(f64, true, toDouble);\n }\n}\n\nTNumber getNumberCore(uint8_t *buf, int szLeft, NumberFormat format) {\n int8_t i8;\n uint8_t u8;\n int16_t i16;\n uint16_t u16;\n int32_t i32;\n uint32_t u32;\n float f32;\n double f64;\n\n// Assume little endian\n#define READBYTES(isz, swap, conv) \\\n readBytes(buf, (uint8_t *)&isz, sizeof(isz), swap, szLeft); \\\n return conv(isz)\n\n switch (format) {\n case NumberFormat::Int8LE:\n READBYTES(i8, false, fromInt);\n case NumberFormat::UInt8LE:\n READBYTES(u8, false, fromInt);\n case NumberFormat::Int16LE:\n READBYTES(i16, false, fromInt);\n case NumberFormat::UInt16LE:\n READBYTES(u16, false, fromInt);\n case NumberFormat::Int32LE:\n READBYTES(i32, false, fromInt);\n case NumberFormat::UInt32LE:\n READBYTES(u32, false, fromUInt);\n\n case NumberFormat::Int8BE:\n READBYTES(i8, true, fromInt);\n case NumberFormat::UInt8BE:\n READBYTES(u8, true, fromInt);\n case NumberFormat::Int16BE:\n READBYTES(i16, true, fromInt);\n case NumberFormat::UInt16BE:\n READBYTES(u16, true, fromInt);\n case NumberFormat::Int32BE:\n READBYTES(i32, true, fromInt);\n case NumberFormat::UInt32BE:\n READBYTES(u32, true, fromUInt);\n\n case NumberFormat::Float32LE:\n READBYTES(f32, false, fromFloat);\n case NumberFormat::Float32BE:\n READBYTES(f32, true, fromFloat);\n case NumberFormat::Float64LE:\n READBYTES(f64, false, fromDouble);\n case NumberFormat::Float64BE:\n READBYTES(f64, true, fromDouble);\n }\n\n return 0;\n}\n} // namespace pxt\n", "buffer.ts": "namespace pins {\n //% deprecated=1\n export function sizeOf(format: NumberFormat) {\n return Buffer.sizeOfNumberFormat(format)\n }\n\n //% deprecated=1\n export function createBufferFromArray(bytes: number[]) {\n return Buffer.fromArray(bytes)\n }\n\n //% deprecated=1\n export function packedSize(format: string) {\n return Buffer.packedSize(format)\n }\n\n //% deprecated=1\n export function packBuffer(format: string, nums: number[]) {\n return Buffer.pack(format, nums)\n }\n\n //% deprecated=1\n export function packIntoBuffer(format: string, buf: Buffer, offset: number, nums: number[]) {\n buf.packAt(offset, format, nums)\n }\n\n //% deprecated=1\n export function unpackBuffer(format: string, buf: Buffer, offset = 0) {\n return buf.unpack(format, offset)\n }\n\n //% deprecated=1\n export function concatBuffers(bufs: Buffer[]) {\n return Buffer.concat(bufs)\n }\n}\n\n// see http://msgpack.org/ for the spec\n// it currently only implements numbers and their sequances\n// once we handle any type and typeof expressions we can do more\n\nnamespace msgpack {\n function tagFormat(tag: number) {\n switch (tag) {\n case 0xCB: return NumberFormat.Float64BE\n case 0xCC: return NumberFormat.UInt8BE\n case 0xCD: return NumberFormat.UInt16BE\n case 0xCE: return NumberFormat.UInt32BE\n case 0xD0: return NumberFormat.Int8BE\n case 0xD1: return NumberFormat.Int16BE\n case 0xD2: return NumberFormat.Int32BE\n default:\n return null\n }\n }\n\n function packNumberCore(buf: Buffer, offset: number, num: number) {\n let tag = 0xCB\n if (num == (num << 0) || num == (num >>> 0)) {\n if (-31 <= num && num <= 127) {\n if (buf) buf[offset] = num\n return 1\n } else if (0 <= num) {\n if (num <= 0xff) {\n tag = 0xCC\n } else if (num <= 0xffff) {\n tag = 0xCD\n } else {\n tag = 0xCE\n }\n } else {\n if (-0x7f <= num) {\n tag = 0xD0\n } else if (-0x7fff <= num) {\n tag = 0xD1\n } else {\n tag = 0xD2\n }\n }\n }\n let fmt = tagFormat(tag)\n if (buf) {\n buf[offset] = tag\n buf.setNumber(fmt, offset + 1, num)\n }\n return pins.sizeOf(fmt) + 1\n }\n\n /**\n * Unpacks a buffer into a number array.\n */\n export function unpackNumberArray(buf: Buffer, offset = 0): number[] {\n let res: number[] = []\n\n while (offset < buf.length) {\n let fmt = tagFormat(buf[offset++])\n if (fmt === null) {\n let v = buf.getNumber(NumberFormat.Int8BE, offset - 1)\n if (-31 <= v && v <= 127)\n res.push(v)\n else\n return null\n } else {\n res.push(buf.getNumber(fmt, offset))\n offset += pins.sizeOf(fmt)\n }\n // padding at the end\n while (buf[offset] === 0xc1) offset++;\n }\n\n return res\n }\n\n /**\n * Pack a number array into a buffer.\n * @param nums the numbers to be packed\n */\n export function packNumberArray(nums: number[]): Buffer {\n let off = 0\n for (let n of nums) {\n off += packNumberCore(null, off, n)\n }\n let buf = Buffer.create(off)\n off = 0\n for (let n of nums) {\n off += packNumberCore(buf, off, n)\n }\n return buf\n }\n}\n\nnamespace helpers {\n export function bufferConcat(a: Buffer, b: Buffer) {\n const r = Buffer.create(a.length + b.length)\n r.write(0, a)\n r.write(a.length, b)\n return r\n }\n\n export function bufferEquals(l: Buffer, r: Buffer) {\n if (!l || !r) return !!l == !!r;\n if (l.length != r.length) return false;\n for (let i = 0; i < l.length; ++i) {\n if (l[i] != r[i])\n return false;\n }\n return true;\n }\n\n export function bufferIndexOf(a: Buffer, b: Buffer) {\n for (let i = 0; i <= a.length - b.length; ++i) {\n if (a[i] == b[0]) {\n let j = 0\n while (j < b.length) {\n if (a[i + j] != b[j])\n break\n j++\n }\n if (j >= b.length)\n return i\n }\n }\n return -1\n }\n\n export function bufferUnpack(buf: Buffer, format: string, offset?: number) {\n if (!offset) offset = 0\n let res: number[] = []\n Buffer.__packUnpackCore(format, res, buf, false, offset)\n return res\n }\n\n export function bufferPackAt(buf: Buffer, offset: number, format: string, nums: number[]) {\n Buffer.__packUnpackCore(format, nums, buf, true, offset)\n }\n\n export function bufferChunked(buf: Buffer, maxBytes: number) {\n if (buf.length <= maxBytes) return [buf]\n else {\n const r: Buffer[] = []\n for (let i = 0; i < buf.length; i += maxBytes)\n r.push(buf.slice(i, maxBytes))\n return r\n }\n }\n\n export function bufferToArray(buf: Buffer, format: NumberFormat) {\n const sz = Buffer.sizeOfNumberFormat(format)\n const len = buf.length - sz\n const r: number[] = []\n for (let i = 0; i <= len; i += sz)\n r.push(buf.g