pxt-maker
Version:
Microsoft MakeCode Maker Boards
1 lines • 11.1 MB
JavaScript
var pxtTargetBundle = {"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},"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},"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":"Reset","path":"/reset","subitems":[]},{"name":"Beta version","path":"/beta","subitems":[]},{"name":"Home page content","path":"/homepage-content","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":"master","tag":"v0.15.70","commits":"https://github.com/microsoft/pxt-maker/commits/7a8134c1e4746eea9f5d705c4e1efb465b8f2bd1","target":"0.15.70","pxt":"12.2.8"},"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"}},"colorThemeMap":{"pxt-high-contrast":{"id":"pxt-high-contrast","name":"High Contrast","weight":100,"monacoBaseTheme":"hc-black","colors":{"pxt-header-background":"#000000","pxt-header-foreground":"#FFFFFF","pxt-header-background-hover":"#000000","pxt-header-foreground-hover":"#FFFFFF","pxt-header-stencil":"#FFFFFF","pxt-primary-background":"#000000","pxt-primary-foreground":"#FFFFFF","pxt-primary-background-hover":"#000000","pxt-primary-foreground-hover":"#FFFFFF","pxt-primary-accent":"#000000","pxt-secondary-background":"#000000","pxt-secondary-foreground":"#FFFFFF","pxt-secondary-background-hover":"#000000","pxt-secondary-foreground-hover":"#FFFFFF","pxt-secondary-accent":"#000000","pxt-tertiary-background":"#000000","pxt-tertiary-foreground":"#FFFFFF","pxt-tertiary-background-hover":"#000000","pxt-tertiary-foreground-hover":"#FFFFFF","pxt-tertiary-accent":"#000000","pxt-target-background1":"#000000","pxt-target-foreground1":"#FFFFFF","pxt-target-background1-hover":"#000000","pxt-target-foreground1-hover":"#cccccc","pxt-target-stencil1":"#FFFFFF","pxt-target-background2":"#000000","pxt-target-foreground2":"#FFFFFF","pxt-target-background2-hover":"#000000","pxt-target-foreground2-hover":"#cccccc","pxt-target-stencil2":"#FFFFFF","pxt-target-background3":"#000000","pxt-target-foreground3":"#FFFFFF","pxt-target-background3-hover":"#000000","pxt-target-foreground3-hover":"#cccccc","pxt-target-stencil3":"#FFFFFF","pxt-neutral-background1":"#000000","pxt-neutral-foreground1":"#FFFFFF","pxt-neutral-background1-hover":"#000000","pxt-neutral-foreground1-hover":"#FFFFFF","pxt-neutral-stencil1":"#FFFFFF","pxt-neutral-background2":"#000000","pxt-neutral-foreground2":"#FFFFFF","pxt-neutral-background2-hover":"#000000","pxt-neutral-foreground2-hover":"#FFFFFF","pxt-neutral-stencil2":"#FFFFFF","pxt-neutral-background3":"#000000","pxt-neutral-foreground3":"#FFFFFF","pxt-neutral-background3-hover":"#000000","pxt-neutral-foreground3-hover":"#FFFFFF","pxt-neutral-stencil3":"#FFFFFF","pxt-neutral-background3-alpha90":"#000000E5","pxt-neutral-base":"rgba(255, 255, 255, 1)","pxt-neutral-alpha0":"rgba(255, 255, 255, 0)","pxt-neutral-alpha10":"rgba(255, 255, 255, 0.1)","pxt-neutral-alpha20":"rgba(255, 255, 255, 0.2)","pxt-neutral-alpha50":"rgba(255, 255, 255, 0.5)","pxt-neutral-alpha80":"rgba(255, 255, 255, 0.8)","pxt-link":"#807FFF","pxt-link-hover":"#BBBBFF","pxt-focus-border":"#FFFF00","pxt-success":"#00FF00","pxt-success-foreground":"#000000","pxt-success-hover":"#00FF00","pxt-success-alpha10":"#00FF0019","pxt-warning":"#00FFFF","pxt-warning-foreground":"#FFFFFF","pxt-warning-hover":"#00FFFF","pxt-warning-alpha10":"#00FFFF19","pxt-error":"#880000","pxt-error-foreground":"#FFFFFF","pxt-error-hover":"#880000","pxt-error-alpha10":"#88000019","pxt-colors-purple-background":"#FF00FF","pxt-colors-purple-foreground":"#000000","pxt-colors-purple-hover":"#FF00FF","pxt-colors-purple-alpha10":"#FF00FF19","pxt-colors-orange-background":"#FF7F00","pxt-colors-orange-foreground":"#000000","pxt-colors-orange-hover":"#FF7F00","pxt-colors-orange-alpha10":"#FF7F0019","pxt-colors-brown-background":"#d1b7a3","pxt-colors-brown-foreground":"#FFFFFF","pxt-colors-brown-hover":"#d1b7a3","pxt-colors-brown-alpha10":"#d1b7a319","pxt-colors-blue-background":"#0078D7","pxt-colors-blue-foreground":"#FFFFFF","pxt-colors-blue-hover":"#0086F1","pxt-colors-blue-alpha10":"#0078D719","pxt-colors-green-background":"#00FF00","pxt-colors-green-foreground":"#000000","pxt-colors-green-hover":"#00FF00","pxt-colors-green-alpha10":"#00FF0019","pxt-colors-red-background":"#880000","pxt-colors-red-foreground":"#FFFFFF","pxt-colors-red-hover":"#880000","pxt-colors-red-alpha10":"#88000019","pxt-colors-teal-background":"#5BE0FF","pxt-colors-teal-foreground":"#000000","pxt-colors-teal-hover":"#5BE0FF","pxt-colors-teal-alpha10":"#5BE0FF19","pxt-colors-yellow-background":"#FFFF00","pxt-colors-yellow-foreground":"#000000","pxt-colors-yellow-hover":"#FFFF00","pxt-colors-yellow-alpha10":"#FFFF0019"},"overrideCss":".common-button {\n color: var(--pxt-neutral-foreground2) !important;\n background-color: var(--pxt-neutral-background2) !important;\n border-color: var(--pxt-neutral-foreground2) !important;\n}\n\n.common-button:hover, .common-button:focus {\n outline: 2px solid var(--pxt-colors-yellow-background) !important;\n z-index: 1;\n}\n\n/*\nOverride default button background for the area menu, which requires transparency,\nbut still use a fairly opaque one to keep focus/visibility on the main buttons.\n*/\n.area-menu-container .area-button {\n background-color: var(--pxt-neutral-alpha80) !important;\n}\n\n/* \n * \"User-provided content\" header in the import modal.\n */\n.ui.violet.message .header {\n color: var(--pxt-colors-purple-background) !important;\n}\n\n/* \n * Checkbox styles\n * In HC the neutral and primary colors are the same, so we need to differentiate with\n * a different background color when checked.\n */\n.common-checkbox.toggle input:checked~label:before,\ndiv.field .ui.toggle.checkbox input:checked~label:before {\n background-color: var(--pxt-colors-purple-background) !important;\n}\n\n.common-checkbox-icon.checked {\n background-color: var(--pxt-colors-purple-background);\n color: var(--pxt-colors-purple-foreground);\n border-color: var(--pxt-colors-purple-hover);\n}\n\n.common-checkbox-icon.checked i.fas.fa-check {\n color: var(--pxt-colors-purple-foreground);\n}\n\n/*\n * Make toggle \"handle\" more visible for HC\n */\n.common-checkbox.toggle label:after {\n background-color: var(--pxt-neutral-foreground1) !important;\n}\n\n/*\n * Selection highlights\n */\n\n.blocklyContextMenu {\n border: 3px solid var(--pxt-colors-yellow-background) !important;\n}\n\n.blocklyWidgetDiv .blocklyMenu.blocklyContextMenu .blocklyMenuItem.blocklyMenuItemHighlight {\n border: 3px solid var(--pxt-colors-yellow-background) !important;\n}\n\n/*\n * Toolbox\n */\n.blocklyTreeRow:hover {\n outline: 3px solid var(--pxt-colors-yellow-background) !important;\n}\n\n#blocklySearchInput i {\n color: var(--pxt-neutral-foreground1);\n opacity: 1;\n}\n\n/* \n * Inverted image colors\n */\n.barcharticon,\n.blockly-ws-search-next-btn,\n.blockly-ws-search-previous-btn,\n.blockly-ws-search-close-btn {\n filter: invert(1);\n}\n\n/* Sim toolbar */\n#simulator .editor-sidebar .simtoolbar .debug-button.active,\n#simulator .editor-sidebar .simtoolbar .debug-button.active:hover,\n#simulator .editor-sidebar .simtoolbar .debug-button.active:hover i {\n /* Make active state more apparent by inverting the colors */\n background: var(--pxt-neutral-foreground2) !important;\n color: var(--pxt-neutral-background2) !important;\n}\n\n/* Image Editor */\n.image-editor-topbar, .image-editor-bottombar, .image-editor-sidebar {\n background: var(--pxt-neutral-background1) !important;\n}\n.image-editor-tool-buttons {\n background: none !important;\n}\n.image-editor-button,\n.image-editor-input,\n.image-editor-confirm {\n border: 1px solid var(--pxt-neutral-foreground1);\n}\n.image-editor-canvas, .image-editor-canvas:hover, .image-editor-canvas:focus {\n outline: none !important;\n}\n.cursor-button {\n /* remove margin since we now have a border around the cursor buttons and it looks better centered */\n margin-right: 0;\n}\n\n/* Toolbox */\n.pxtToolbox:not(.invertedToolbox) span.blocklyTreeLabel {\n color: var(--pxt-target-foreground3);\n}\n\n.pxtToolbox:not(.invertedToolbox) .blocklyTreeSelected span.blocklyTreeLabel,\n.pxtToolbox:not(.invertedToolbox) .blocklyTreeSelected span.blocklyTreeIcon {\n color: var(--pxt-target-foreground3);\n}\n\n.pxtToolbox:not(.invertedToolbox) .blocklyTreeRow:not(.blocklyTreeSelected) .blocklyTreeLabel {\n color: var(--pxt-target-foreground3);\n}\n\n.pxtToolbox:not(.invertedToolbox) .blocklyTreeRow:not(.blocklyTreeSelected):hover,\n.pxtToolbox:not(.invertedToolbox) .blocklyTreeRow:not(.blocklyTreeSelected):focus {\n background-color: #404040;\n}\n\n.blocksEditorOuter #blocklyTrashIcon {\n color: var(--pxt-primary-foreground);\n}\n\n/*\n * Teaching Bubbles\n */\n.teaching-bubble,\n.teaching-bubble .teaching-bubble-navigation-buttons > .common-button {\n background: var(--pxt-neutral-background1) !important;\n color: var(--pxt-neutral-foreground1) !important;\n border: solid var(--pxt-neutral-foreground1) !important;\n}\n\n.teaching-bubble-cutout {\n border: 0.25rem solid var(--pxt-neutral-alpha20);\n}\n\n.teaching-bubble .ai-footer {\n opacity: 1 !important;\n}\n\n.teaching-bubble-arrow,\n.teaching-bubble .ai-footer-text,\n.teaching-bubble .feedback-button,\n.teaching-bubble .feedback-button.disabled,\n.teaching-bubble .teaching-bubble-steps {\n color: var(--pxt-neutral-foreground1) !important;\n}\n\n/*\n * Side Docs\n */\n\n#sidedocs {\n background-color: var(--pxt-neutral-foreground1);\n}\n\n#sidedocsbar a i,\n#sidedocsbar a span {\n color: var(--pxt-neutral-background1) !important;\n}\n\n#sidedocsbar a:hover,\n#sidedocsbar a:focus {\n /* Yellow does not contrast well against white background */\n outline: 3px solid var(--pxt-neutral-background1) !important;\n}\n\n#sidedocsbar a:hover i,\n#sidedocsbar a:focus i,\n#sidedocsbar a:hover span,\n#sidedocsbar a:focus span {\n color: var(--pxt-link-hover) !important;\n}\n\n/*\n * Editor Toggle\n */\n#editortoggle .selected.item {\n transition: none;\n &:focus {\n box-shadow: inset 0 0 0 6px #000000 !important;\n }\n >.icon {\n color: #000000 !important;\n }\n}\n\n#editordropdown.ui.button.active > .icon {\n color: #000000 !important;\n}\n\n/*\n * Dropdown Menu\n */\n.common-menu-dropdown-item:hover,\n.common-menu-dropdown > .menu-button.expanded {\n outline: var(--pxt-focus-border) solid 3px !important;\n outline-offset: -4px;\n z-index: 1;\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.getNumber(format, i))\n return r\n }\n\n export const _b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"\n export function bufferToBase64(buf: Buffer) {\n const len = buf.length\n let r = \"\"\n for (let i = 0; i < len; i += 3) {\n const x0 = buf[i]\n r += _b64[x0 >> 2]\n if (i + 1 >= len) {\n r += _b64[(x0 & 3) << 4] + \"==\"\n } else {\n const x1 = buf[i + 1]\n r += _b64[(x0 & 3) << 4 | (x1 >> 4)]\n if (i + 2 >= len) {\n r += _b64[(x1 & 15) << 2] + \"=\"\n } else {\n const x2 = buf[i + 2]\n r += _b64[(x1 & 15) << 2 | (x2 >> 6)]\n r += _b64[x2 & 63]\n }\n }\n }\n return r\n }\n}\n\ninterface Buffer {\n [index: number]: number;\n\n /**\n * Return concatenation of current buffer and the given buffer\n */\n //% helper=bufferConcat\n concat(other: Buffer): Buffer;\n\n /**\n * Return position of other buffer in current buffer\n */\n //% helper=bufferIndexOf\n indexOf(other: Buffer): number;\n\n /**\n * Reads numbers from the buffer according to the format\n */\n //% helper=bufferUnpack\n unpack(format: string, offset?: number): number[];\n\n /**\n * Writes numbers to the buffer according to the format\n */\n //% helper=bufferPackAt\n packAt(offset: number, format: string, nums: number[]): void;\n\n /**\n * Returns true if this and the other buffer hold the same data\n */\n //% helper=bufferEquals\n equals(other: Buffer): boolean;\n\n /**\n * Splits buffer into parts no larger than specified\n */\n //% helper=bufferChunked\n chunked(maxSize: number): Buffer[];\n\n /**\n * Read contents of buffer as an array in specified format\n */\n //% helper=bufferToArray\n toArray(format: NumberFormat): number[];\n\n /**\n * Convert buffer to ASCII base64 encoding.\n */\n //% helper=bufferToBase64\n toBase64(): string;\n\n // rest defined in buffer.cpp\n}\n\nnamespace Buffer {\n /**\n * Allocate a new buffer.\n * @param size number of bytes in the buffer\n */\n //% shim=control::createBuffer\n export declare function create(size: number): Buffer;\n\n /**\n * Create a new buffer, decoding a hex string\n */\n export function fromHex(hex: string) {\n const hexStr = \"0123456789abcdef\"\n const res = Buffer.create(hex.length >> 1)\n hex = hex.toLowerCase()\n for (let i = 0; i < hex.length; i += 2) {\n const p0 = hexStr.indexOf(hex.charAt(i))\n const p1 = hexStr.indexOf(hex.charAt(i + 1))\n if (p0 < 0 || p1 < 0)\n throw \"Invalid hex\"\n res[i >> 1] = (p0 << 4) | p1\n }\n return res\n }\n\n function b64Idx(c: string) {\n if (c === undefined || c == \"=\") return -1\n\n // handle base64url\n if (c == \"-\") return 62\n if (c == \"_\") return 63\n\n const r = helpers._b64.indexOf(c)\n if (r < 0)\n throw \"Invalid Base64\"\n return r\n }\n\n function fromBase64Core(trg: Buffer, b64: string) {\n const len = b64.length\n let dp = 0\n for (let i = 0; i < len; i += 4) {\n const x0 = b64Idx(b64[i])\n const x1 = b64Idx(b64[i + 1])\n const x2 = b64Idx(b64[i + 2])\n const x3 = b64Idx(b64[i + 3])\n if (x0 < 0 || x1 < 0) throw \"Invalid Base64\"\n if (trg)\n trg[dp] = (x0 << 2) | (x1 >> 4)\n dp++\n if (x2 >= 0) {\n if (trg)\n trg[dp] = (x1 << 4) | (x2 >> 2)\n dp++\n if (x3 >= 0) {\n if (trg)\n trg[dp] = (x2 << 6) | x3\n dp++\n }\n } else {\n if (x3 >= 0 || i + 4 < len)\n throw \"Invalid Base64\"\n }\n }\n return dp\n }\n\n /**\n * Create a new buffer, decoding a Base64 string\n */\n export function fromBase64(b64: string) {\n const sz = fromBase64Core(null, b64)\n const res = create(sz)\n fromBase64Core(res, b64)\n return res\n }\n\n /**\n * Create a new buffer from an UTF8-encoded string\n * @param str the string to put in the buffer\n */\n //% shim=control::createBufferFromUTF8\n export declare function fromUTF8(str: string): Buffer;\n\n function chunkLen(s: string, off: number, maxlen: number) {\n let L = Math.idiv(maxlen, 3)\n let R = maxlen\n\n if (fromUTF8(s.slice(off, off + R)).length <= maxlen)\n return R\n\n while (L < R) {\n const m = (L + R) >> 1\n if (m == L)\n break\n const ll = fromUTF8(s.slice(off, off + m)).length\n if (ll <= maxlen)\n L = m\n else\n R = m\n }\n\n return L\n }\n\n export function chunkedFromUTF8(str: string, maxBytes: number) {\n if (maxBytes < 3)\n throw \"Oops\"\n const chunks: Buffer[] = []\n let pos = 0\n while (pos < str.length) {\n const len = chunkLen(str, pos, maxBytes)\n chunks.push(fromUTF8(str.slice(pos, pos + len)))\n pos += len\n }\n return chunks\n }\n\n /**\n * Create a new buffer initialized to bytes from given array.\n * @param bytes data to initialize with\n */\n export function fromArray(bytes: number[]) {\n let buf = Buffer.create(bytes.length)\n for (let i = 0; i < bytes.length; ++i)\n buf[i] = bytes[i]\n return buf\