{"id":"arcade","name":"arcade","nickname":"arcade","thumbnailName":"MakeCode Arcade","title":"Microsoft MakeCode Arcade","description":"Develop your programming skills by quickly creating and modding retro arcade games with Blocks and JavaScript in the MakeCode editor","corepkg":"device","cloud":{"workspace":false,"sharing":true,"thumbnails":true,"importing":true,"packages":true,"publishing":true,"githubPackages":true,"showBadges":true,"cloudProviders":{"github":{"id":"github","name":"GitHub","icon":"@cdnUrl@/blob/ea6ff545a246caa64074ba809bbc86fcb8589071/static/providers/github-mark.png","identity":false,"order":4},"microsoft":{"id":"microsoft","name":"Microsoft","icon":"@cdnUrl@/blob/5334aa7ca6864819631aad2993cc42f68d72a6e3/static/providers/microsoft-logo.svg","identity":true,"redirect":true,"order":1},"google":{"id":"google","name":"Google","icon":"@cdnUrl@/blob/c06982fbad6b6825d8efb8497291a533747480df/static/providers/google-logo.svg","identity":true,"redirect":true,"order":2},"clever":{"id":"clever","name":"Clever","icon":"@cdnUrl@/blob/3494ce63ad28b4528664f74f1fdac22242269125/static/providers/clever-logo.png","identity":true,"redirect":true,"order":3}}},"bundleddirs":["libs/animation","libs/accelerometer","libs/azureiot","libs/base","libs/buttons","libs/color","libs/color-coded-tilemap","libs/controller","libs/controller---none","libs/core","libs/core---linux","libs/core---nrf52","libs/core---samd","libs/core---stm32","libs/core---rp2040","libs/core---vm","libs/corgio","libs/d5prj","libs/darts","libs/device","libs/edge-connector","libs/esp32","libs/f4prj","libs/feather","libs/game","libs/game---light","libs/hw","libs/hw---n3","libs/hw---n4","libs/hw---rpi","libs/hw---samd51","libs/hw---stm32f401","libs/hw---rp2040","libs/hw---vm","libs/keyboard","libs/light","libs/lightsensor","libs/microphone","libs/mixer","libs/mixer---ext","libs/mixer---linux","libs/mixer---none","libs/mixer---nrf52","libs/mixer---samd","libs/mixer---stm32","libs/mixer---rp2040","libs/mouse","libs/mqtt","libs/multiplayer","libs/net","libs/net-game","libs/palette","libs/power","libs/radio","libs/radio-broadcast","libs/rotary-encoder","libs/rpiprj","libs/screen","libs/screen---ext","libs/screen---linux","libs/screen---st7735","libs/serial","libs/serial---linux","libs/servo","libs/settings","libs/settings---files","libs/sevenseg","libs/shader","libs/sprite-scaling","libs/storyboard","libs/template","libs/thermometer","libs/browser-events"],"staticpkgdirs":{"base":["libs/hw","libs/hw---n3","libs/hw---n4","libs/hw---samd51","libs/hw---stm32f401","libs/hw---rp2040"],"extensions":["libs/accelerometer","libs/color","libs/edge-connector","libs/esp32","libs/feather","libs/light","libs/lightsensor","libs/mqtt","libs/net","libs/net-game","libs/palette","libs/radio","libs/radio-broadcast","libs/serial","libs/servo","libs/settings","libs/sevenseg","libs/shader","libs/thermometer"]},"cacheusedblocksdirs":["skillmap/space","skillmap/platformer"],"compile":{"useUF2":true,"deployDrives":"(ARCADE|PY|FTHR840BOOT|ARCD|RPI-RP2)","deployFileMarker":"INFO_UF2.TXT","driveName":"ARCADE","floatingPoint":true,"taggedInts":true,"nativeType":"thumb","gc":true,"upgrades":[],"webUSB":true,"saveAsPNG":true,"patches":{"0.0.0 - *":[{"type":"missingPackage","map":{"(DigitalPin|AnalogPin|pins)\\.P\\d\\d?":"edge-connector","serial\\.":"serial"}}],"0.0.0 - 0.1.1":[{"type":"api","map":{"controller\\.controlSprite":"controller.moveSprite","controller\\.controlPlayer":"controller.movePlayer"}}],"0.0.0 - 0.3.23":[{"type":"package","map":{"local-multiplayer":""}}],"0.0.0 - 0.3.24":[{"type":"api","map":{"sprites\\.createEmptySprite\\(([^)]+)\\)":"sprites.create(img`.`, $1)"}},{"type":"blockId","map":{"keysdx":"keydx","keysdy":"keydy"}}],"0.0.0 - 0.11.20":[{"type":"api","map":{"SpriteKind":"SpriteKindLegacy"}}],"0.0.0 - 0.14.57":[{"type":"missingPackage","map":{"scene\\.setTileMap":"color-coded-tilemap","scene\\.setTile":"color-coded-tilemap","scene\\.getTile":"color-coded-tilemap","scene\\.getTilesByType":"color-coded-tilemap","scene\\.placeOnRandomTile":"color-coded-tilemap","scene\\.setTileAt":"color-coded-tilemap","scene\\.onHitTile":"color-coded-tilemap","\\.tileHitFrom":"color-coded-tilemap"}}],"0.0.0 - 0.18.9":[{"type":"api","map":{"tilemap\\s*\\.\\s*createTileSprite":"tiles.createTileSprite","tilemap\\s*\\.\\s*coverAllTiles":"tiles.coverAllTiles","tilemap\\s*\\.\\s*createSpritesOnTiles":"tiles.createSpritesOnTiles","tilemap\\s*\\.\\s*destorySpritesOfKind":"tiles.destroySpritesOfKind","tilemap\\s*\\.\\s*tileIs":"tiles.tileIs","tilemap\\s*\\.\\s*tileIsWall":"tiles.tileIsWall","tilemap\\s*\\.\\s*forEachTileOfKind":"tiles.forEachTileOfKind","tilemap\\s*\\.\\s*forEachTileOfMap":"tiles.forEachTileOfMap","tilemap\\s*\\.\\s*replaceAllTiles":"tiles.replaceAllTiles","tilemap\\s*\\.\\s*columnInDirection":"tiles.columnInDirection","tilemap\\s*\\.\\s*rowInDirection":"tiles.rowInDirection","tilemap\\s*\\.\\s*forEachDirection":"tiles.forEachDirection","tilemap\\s*\\.\\s*centerCameraOnTile":"tiles.centerCameraOnTile","tilemap\\s*\\.\\s*locationOfSprite":"tiles.locationOfSprite","tilemap\\s*\\.\\s*RowCol":"tiles.RowCol","tilemap\\s*\\.\\s*spriteRowCol":"tiles.spriteRowCol","tilemap\\s*\\.\\s*locationColumn":"tiles.locationColumn","tilemap\\s*\\.\\s*locationRow":"tiles.locationRow","tilemap\\s*\\.\\s*XY":"tiles.XY","tilemap\\s*\\.\\s*locationXY":"tiles.locationXY","tilemap\\s*\\.\\s*locationInDirection":"tiles.locationInDirection","tilemap\\s*\\.\\s*_directionEditor":"tiles._directionEditor","tilemap\\s*\\.\\s*tileWidth":"tiles.tileWidth","tilemap\\s*\\.\\s*tilemapColumns":"tiles.tilemapColumns","tilemap\\s*\\.\\s*tilemapRows":"tiles.tilemapRows","tilemap\\s*\\.\\s*screenCoordinateToTile":"tiles.screenCoordinateToTile","tilemap\\s*\\.\\s*tileCoordinateToScreen":"tiles.tileCoordinateToScreen","tilemap\\s*\\.\\s*centeredTileCoordinateToScreen":"tiles.centeredTileCoordinateToScreen","tilemap\\s*\\.\\s*OVERWORLD_MAP_ID":"tiles.OVERWORLD_MAP_ID","tilemap\\s*\\.\\s*MAP_LOADED_EVENT":"tiles.MAP_LOADED_EVENT","tilemap\\s*\\.\\s*WorldMap":"tiles.WorldMap","tilemap\\s*\\.\\s*WorldMapConnection":"tiles.WorldMapConnection","tilemap\\s*\\.\\s*createMap":"tiles.createMap","tilemap\\s*\\.\\s*copyMap":"tiles.copyMap","tilemap\\s*\\.\\s*loadMap":"tiles.loadMap","tilemap\\s*\\.\\s*getLoadedMap":"tiles.getLoadedMap","tilemap\\s*\\.\\s*onMapLoaded":"tiles.onMapLoaded","tilemap\\s*\\.\\s*onMapUnloaded":"tiles.onMapUnloaded","tilemap\\s*\\.\\s*connectMapById":"tiles.connectMapById","tilemap\\s*\\.\\s*loadConnectedMap":"tiles.loadConnectedMap","tilemap\\s*\\.\\s*getConnectedMap":"tiles.getConnectedMap","tilemap\\s*\\.\\s*setWorldLocationToMap":"tiles.setWorldLocationToMap","tilemap\\s*\\.\\s*loadMapAt":"tiles.loadMapAt","tilemap\\s*\\.\\s*getMapAtWorldLocation":"tiles.getMapAtWorldLocation","tilemap\\s*\\.\\s*loadMapInDirection":"tiles.loadMapInDirection","tilemap\\s*\\.\\s*loadedWorldColumn":"tiles.loadedWorldColumn","tilemap\\s*\\.\\s*loadedWorldRow":"tiles.loadedWorldRow"}}],"0.0.0 - 1.9.0":[{"type":"api","map":{"myCorg\\s*\\.\\s*follow":"myCorg.cameraFollow"}}]},"switches":{},"jsRefCounting":false,"utf8":true},"compileService":{"buildEngine":"codal","githubCorePackage":"lancaster-university/codal","gittag":"v0.8.0","dockerImage":"pext/yotta:latest","codalTarget":{"branches":{}}},"variants":{"stm32f401":{"compile":{"hasHex":true,"openocdScript":"source [find interface/stlink-v2.cfg]; source [find target/stm32f4x.cfg]","flashEnd":524288,"uf2Family":"0x57755a57"},"compileService":{"codalTarget":{"name":"codal-big-brainpad","url":"https://github.com/lancaster-university/codal-big-brainpad","branch":"v1.3.1","type":"git"},"codalBinary":"STM32","serviceId":"codal2stm32","dockerImage":"pext/yotta:latest"}},"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","dockerImage":"pext/yotta:latest"}},"nrf52840":{"compile":{"hasHex":true,"openocdScript":"source [find interface/cmsis-dap.cfg]; source [find target/nrf52.cfg]","webUSB":false,"flashEnd":1007616,"uf2Family":"0xada52840"},"compileService":{"codalTarget":{"name":"codal-nrf52840-dk","url":"https://github.com/mmoskal/codal-nrf52840-dk","branch":"v1.1.7","type":"git"},"codalBinary":"NRF52840_DK","serviceId":"codal2nrf52840","dockerImage":"pext/yotta:latest","yottaConfig":{"pxt":{"board":{"id":"BOARD_ID_NRF52840"}}}}},"nrf52833":{"compile":{"hasHex":true,"openocdScript":"source [find interface/cmsis-dap.cfg]; source [find target/nrf52.cfg]","webUSB":false,"useUF2":false,"flashEnd":524288,"deployDrives":".*","deployFileMarker":"DETAILS.TXT"},"compileService":{"codalTarget":{"name":"codal-nrf52833-dk","url":"https://github.com/mmoskal/codal-nrf52833-dk","branch":"v2.0.2","type":"git"},"codalBinary":"NRF52840_DK","serviceId":"codal2nrf52840","dockerImage":"pext/yotta:latest","yottaConfig":{"pxt":{"board":{"id":"BOARD_ID_NRF52833"}}}}},"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.13","type":"git"},"gittag":"v0.9.0","codalBinary":"PI-PICO","serviceId":"codal2pico","dockerImage":"pext/arm:gcc9"}},"rpi":{"compile":{"hasHex":true,"useELF":true,"runtimeIsARM":true,"flashCodeAlign":256,"webUSB":false,"stackAlign":2},"compileService":{"buildEngine":"dockermake","dockerImage":"pext/rpi:alsa","serviceId":"rpi"}},"vm":{"compile":{"hasHex":true,"useELF":true,"flashCodeAlign":256,"webUSB":false,"nativeType":"vm","stackAlign":2},"compileService":{"buildEngine":"dockercross","dockerImage":"pext/crossbuild","serviceId":"crossbuild","skipCloudBuild":true}}},"serial":{"useEditor":true,"log":true,"editorTheme":{"graphBackground":"#d9d9d9","lineColors":["#009DDC","#FB48C7","#40bf4a","#8073E5","#d25b33"]}},"runtime":{"mathBlocks":true,"loopsBlocks":true,"logicBlocks":true,"variablesBlocks":true,"textBlocks":true,"functionBlocks":true,"breakBlock":true,"continueBlock":true,"pauseUntilBlock":{"category":"loops"},"functionsOptions":{"useNewFunctions":true,"extraFunctionEditorTypes":[{"typeName":"Sprite","icon":"send","defaultName":"mySprite"},{"typeName":"Image","icon":"image outline","defaultName":"myImage"},{"label":"Location","typeName":"tiles.Location","icon":"tree","defaultName":"myLocation"}]},"listsBlocks":true,"tilesetFieldEditorIdentity":"images._tile","bannedCategories":["pins","control","input","serial","power"]},"simulator":{"autoRun":true,"autoRunLight":false,"emptyRunCode":"pxsim.pxtcore.updateScreen(new pxsim.RefImage(160, 120, 4))","aspectRatio":0.85,"dynamicBoardDefinition":true,"keymap":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}}},"appTheme":{"logoUrl":"https://makecode.com/org","logo":"@cdnUrl@/blob/dd2273dd4e5972576a2cc228b8a4d18f0819fcc3/static/logo.svg","docsLogo":"@cdnUrl@/blob/dd2273dd4e5972576a2cc228b8a4d18f0819fcc3/static/logo.svg","cardLogo":"@cdnUrl@/blob/9ab4abfcdff3405e5cca8a3c38e129aec2b363e3/static/logo.png","appLogo":"@cdnUrl@/blob/bfe873eb228f98720fe0ed18c638daa13906958f/static/icons/favicon.ico","portraitLogo":"@cdnUrl@/blob/dd2273dd4e5972576a2cc228b8a4d18f0819fcc3/static/logo.svg","footerLogo":"@cdnUrl@/blob/dd2273dd4e5972576a2cc228b8a4d18f0819fcc3/static/logo.svg","organization":"Microsoft MakeCode","organizationText":"MakeCode Arcade","organizationShortText":"MakeCode","organizationUrl":"https://makecode.com/org","organizationLogo":"@cdnUrl@/blob/106597ae039a275897661651b96856220c9b0fad/static/Micorsoft_logo_rgb_W-white_D-square.png","organizationWideLogo":"@cdnUrl@/blob/d6139e3d0af51f02aa5f8765ecb0985acbd98551/static/Micorsoft_logo_rgb_W-white_D.png","homeUrl":"https://arcade.makecode.com/","embedUrl":"https://arcade.makecode.com/","privacyUrl":"https://go.microsoft.com/fwlink/?LinkId=521839","termsOfUseUrl":"https://go.microsoft.com/fwlink/?LinkID=206977","githubUrl":"https://github.com/microsoft/pxt-arcade","boardName":"Arcade","addNewTypeScriptFile":true,"docMenu":[{"name":"Docs","path":"/docs","popout":true},{"name":"Hardware","path":"/hardware","popout":true},{"name":"Forum","path":"https://forum.makecode.com"}],"coloredToolbox":true,"monacoToolbox":true,"selectLanguage":true,"availableLocales":["en","ar","de","es-ES","es-MX","fr","ga-IE","it","ja","ko","ru","zh-CN","zh-TW","nl"],"invertedMenu":true,"showHomeScreen":true,"useTextLogo":true,"highContrast":true,"greenScreen":true,"print":true,"hasAudio":true,"allowPackageExtensions":true,"homeScreenHero":{"imageUrl":"@cdnUrl@/blob/afd694fa1145b394625777a2c18cf33ae57e76e1/static/hero-gallery/multiplayer-banner.png","name":"Multiplayer Games!","url":"/--multiplayer","buttonLabel":"Try Now","description":"Multiplayer Games!","cardType":"link"},"homeScreenHeroGallery":"/hero-banner","socialOptions":{"orgTwitterHandle":"MSMakeCode","hashtags":"MakeCode","discourse":"https://forum.makecode.com/","discourseCategory":"Arcade"},"blocklyOptions":{"grid":{"spacing":30,"length":1,"colour":"rgb(189, 195, 199)","snap":false}},"blockColors":{"loops":"#20BF6B","logic":"#45AAF2","math":"#A55EEA","variables":"#EC3B59","text":"#F5D547","arrays":"#FF8F08","functions":"#1446A0"},"defaultColorTheme":"arcade-orange","highContrastColorTheme":"pxt-high-contrast","simAnimationEnter":"fly right in","simAnimationExit":"fly right out","crowdinProject":"makecode","monacoColors":{"editor.background":"#F8FAFC"},"monacoFieldEditors":["image-editor","tilemap-editor","soundeffect-editor","music-editor"],"scriptManager":true,"saveInMenu":false,"debugger":true,"importExtensionFiles":true,"experiments":["debugExtensionCode","snippetBuilder","experimentalHw","recipes","tutorialBlocksDiff","blocksErrorList","identity","accessibleBlocks","palettePicker"],"blocksCollapsing":true,"errorList":true,"workspaceSearch":true,"extendEditor":true,"simScreenshot":true,"simScreenshotKey":"P","simScreenshotMaxUriLength":300000,"simGif":true,"simGifKey":"R","qrCode":true,"shareFinishedTutorials":true,"nameProjectFirst":true,"githubEditor":true,"githubCompiledJs":true,"chooseLanguageRestrictionOnNewProject":true,"openProjectNewTab":true,"hasReferenceDocs":true,"python":true,"assetEditor":true,"immersiveReader":true,"tutorialCodeValidation":true,"multiplayer":true,"songEditor":true,"shareToKiosk":true,"tours":{"editor":"/tours/editor-tour"},"showOpenInVscode":true,"hideReplaceMyCode":true,"timeMachine":true,"timeMachineDiffInterval":600000,"timeMachineSnapshotInterval":1800000,"feedbackEnabled":true,"ocvAppId":50315,"ocvFrameUrl":"https://admin-ignite.microsoft.com","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":"sprites","path":"/reference/sprites","subitems":[]},{"name":"controller","path":"/reference/controller","subitems":[]},{"name":"game","path":"/reference/game","subitems":[]},{"name":"music","path":"/reference/music","subitems":[]},{"name":"scene","path":"/reference/scene","subitems":[]},{"name":"info","path":"/reference/info","subitems":[]},{"name":"images","path":"/reference/images","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":"Image","path":"/types/image","subitems":[]},{"name":"Sprite","path":"/types/sprite","subitems":[]}]},{"name":"Blocks Gallery","path":"/block-gallery","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":"Multiplayer","path":"/multiplayer","subitems":[]},{"name":"Offline support","path":"/offline","subitems":[]},{"name":"Save","path":"/save","subitems":[]},{"name":"Sign In","path":"/identity/sign-in","subitems":[]},{"name":"Cloud Sync","path":"/identity/cloud-sync","subitems":[]},{"name":"VS Code","path":"/vscode","subitems":[]}]},{"name":"Hardware","path":"/hardware","subitems":[{"name":"Errors","path":"/hardware/errors","subitems":[]},{"name":"Adding New Board","path":"/hardware/adding","subitems":[]},{"name":"Raspberry Pi","path":"/hardware/raspberry-pi","subitems":[]},{"name":"Makey Makey","path":"/hardware/makey-makey","subitems":[]},{"name":"Shoebox Controller","path":"/hardware/shoebox-controller","subitems":[]},{"name":"Dev","path":"/hardware/dev","subitems":[]},{"name":"Debug connector","path":"/hardware/dbg","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":[]},{"name":"Art, images, colors","path":"/developer/images","subitems":[]},{"name":"Sounds","path":"/developer/sound","subitems":[]}]},{"name":"Lessons","path":"/lessons","subitems":[{"name":"Cherry Pickr","path":"/lessons/cherry-pickr","subitems":[]},{"name":"Barrel Dodger","path":"/lessons/barrel-dodger","subitems":[]},{"name":"Dance Party","path":"/lessons/dance-party","subitems":[]},{"name":"BlockOut","path":"/lessons/block-out","subitems":[]}]},{"name":"Courses","path":"/courses","subitems":[{"name":"CS Intro 1","path":"/courses/csintro1","subitems":[]},{"name":"CS Intro 2","path":"/courses/csintro2","subitems":[]},{"name":"CS Intro 3","path":"/courses/csintro3","subitems":[]}]}],"id":"arcade","title":"Microsoft MakeCode Arcade","name":"arcade","description":"Develop your programming skills by quickly creating and modding retro arcade games with Blocks and JavaScript in the MakeCode editor","htmlDocIncludes":{}},"queryVariants":{"skillmap=1":{"appTheme":{"embeddedTutorial":true,"allowParentController":true,"shareFinishedTutorials":false,"hideReplaceMyCode":false}},"teachertool=1":{"appTheme":{"hideMenuBar":true,"workspaceSearch":true}},"ninja=1":{"appTheme":{"embeddedTutorial":true,"allowParentController":true,"shareFinishedTutorials":false,"hideReplaceMyCode":false}}},"unsupportedBrowsers":[{"id":"ie"}],"uploadDocs":true,"noSimShims":true,"defaultBadges":[{"id":"skillmap-completion-save the forest","type":"skillmap-completion","image":"@cdnUrl@/blob/146f698eaa0c80a63e5bb79ad20a6536edc947c8/static/badges/badge-forest.png","lockedImage":"@cdnUrl@/blob/181bf6f9f258825d81ebbdcde6ad675d2cf48a68/static/badges/badge-forest-locked.png","sourceURL":"https://www.makecode.com/api/md/arcade/skillmap/forest","title":"Save the Forest"},{"id":"skillmap-completion-zookeeper","type":"skillmap-completion","image":"@cdnUrl@/blob/489378a1db6e001928923a31d69d164dbf52ce2b/static/badges/badge-zoo.png","lockedImage":"@cdnUrl@/blob/0ff375c7b2fb6b5961256575402be6d67ba0b925/static/badges/badge-zoo-locked.png","sourceURL":"https://www.makecode.com/api/md/arcade/skillmap/zoo","title":"Zookeeper"},{"id":"skillmap-completion-rockstar","image":"@cdnUrl@/blob/bd7d64424b8c6339ecdfb58e5caadd1b155c68c7/static/badges/badge-rockstar.png","lockedImage":"@cdnUrl@/blob/59f7cfc52f99704e276433e06bdf758a2e263a95/static/badges/badge-rockstar-locked.png","sourceURL":"https://www.makecode.com/api/md/arcade/skillmap/rockstar","type":"skillmap-completion","title":"80's Rockstar"},{"id":"skillmap-completion-build a platformer game!","image":"@cdnUrl@/blob/7d005bbde6f56777de2b8b53706fc03897955119/static/badges/badge-jungle.png","lockedImage":"@cdnUrl@/blob/cf3aa1d48cfdb42099d230118373ef746b397cb0/static/badges/badge-jungle-locked.png","sourceURL":"https://www.makecode.com/api/md/arcade/skillmap/jungle","type":"skillmap-completion","title":"Jungle Jump"},{"id":"skillmap-completion-space","image":"@cdnUrl@/blob/59e0eef309206e56b143d2b79f1ff5117afcf37c/static/badges/badge-space.png","lockedImage":"@cdnUrl@/blob/e10e46d04dc2e4d066c2c6ec92baefc5bd9cec8a/static/badges/badge-space-locked.png","sourceURL":"https://www.makecode.com/api/md/arcade/skillmap/space","type":"skillmap-completion","title":"Space Explorer"},{"id":"skillmap-completion-shark","image":"@cdnUrl@/blob/723902a101777d73e7787ba43e6c635be825b35c/static/badges/badge-shark.png","lockedImage":"@cdnUrl@/blob/2f3e865d14dcf81dc0dfbba048323b9904b458fc/static/badges/badge-shark-locked.png","sourceURL":"https://www.makecode.com/api/md/arcade/skillmap/shark","type":"skillmap-completion","title":"Shark Splash"}],"versions":{"branch":"v2.0.56","tag":"v2.0.56","commits":"https://github.com/microsoft/pxt-arcade/commits/2e47d3464cf6ea715ec6e630834bbe15bc2f6feb","target":"2.0.56","pxt":"11.3.59"},"blocksprj":{"id":"blocksprj","config":{"name":"{0}","dependencies":{"device":"*"},"description":"","files":["main.blocks","main.ts","README.md","assets.json"],"additionalFilePaths":[]},"files":{"README.md":" ","assets.json":"","main.blocks":"<xml xmlns=\"http://www.w3.org/1999/xhtml\">\n  <variables></variables>\n  <block type=\"pxt-on-start\" x=\"0\" y=\"0\"></block>\n</xml>","main.ts":" "}},"tsprj":{"id":"tsprj","config":{"name":"{0}","dependencies":{"device":"*"},"description":"","files":["main.ts","README.md","assets.json"],"additionalFilePaths":[]},"files":{"README.md":" ","assets.json":"","main.ts":" "}},"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":"#1b19ff","pxt-focus-border":"#FFFF00","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":"#8C8CFF","pxt-colors-blue-foreground":"#000000","pxt-colors-blue-hover":"#8C8CFF","pxt-colors-blue-alpha10":"#8C8CFF19","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":"#00FFFF","pxt-colors-yellow-foreground":"#000000","pxt-colors-yellow-hover":"#00FFFF","pxt-colors-yellow-alpha10":"#00FFFF19"},"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/* \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) !important;\n}\n\n.pxtToolbox:not(.invertedToolbox) .blocklyTreeRow:not(.blocklyTreeSelected):hover,\n.pxtToolbox:not(.invertedToolbox) .blocklyTreeRow:not(.blocklyTreeSelected):focus {\n    background-color: #404040 !important;\n}\n"},"arcade-dark":{"id":"arcade-dark","name":"Dark","weight":60,"monacoBaseTheme":"vs-dark","colors":{"pxt-header-background":"#181818","pxt-header-foreground":"#ffffff","pxt-header-background-hover":"#252525","pxt-header-foreground-hover":"#ffffff","pxt-header-stencil":"#323232","pxt-primary-background":"#0078D4","pxt-primary-foreground":"#ffffff","pxt-primary-background-hover":"#026EC1","pxt-primary-foreground-hover":"#ffffff","pxt-primary-accent":"#005ba1","pxt-secondary-background":"#63276d","pxt-secondary-foreground":"#f3f2f1","pxt-secondary-background-hover":"#742e80","pxt-secondary-foreground-hover":"#f3f2f1","pxt-secondary-accent":"#411a47","pxt-tertiary-background":"#0078d4","pxt-tertiary-foreground":"#ffffff","pxt-tertiary-background-hover":"#026EC1","pxt-tertiary-foreground-hover":"#ffffff","pxt-tertiary-accent":"#0894ff","pxt-target-background1":"#1F1F1F","pxt-target-foreground1":"#f3f2f1","pxt-target-background1-hover":"#2c2c2c","pxt-target-foreground1-hover":"#ffffff","pxt-target-stencil1":"#3b3a39","pxt-target-background2":"#181818","pxt-target-foreground2":"#ffffff","pxt-target-background2-hover":"#252525","pxt-target-foreground2-hover":"#ffffff","pxt-target-stencil2":"#323232","pxt-target-background3":"#181818","pxt-target-foreground3":"#ffffff","pxt-target-background3-hover":"#252525","pxt-target-foreground3-hover":"#ffffff","pxt-target-stencil3":"#323232","pxt-neutral-background1":"#1F1F1F","pxt-neutral-foreground1":"#f3f2f1","pxt-neutral-background1-hover":"#2c2c2c","pxt-neutral-foreground1-hover":"#ffffff","pxt-neutral-stencil1":"#3b3a39","pxt-neutral-background2":"#181818","pxt-neutral-foreground2":"#ffffff","pxt-neutral-background2-hover":"#252525","pxt-neutral-foreground2-hover":"#ffffff","pxt-neutral-stencil2":"#3b3a39","pxt-neutral-background3":"#2d2d2d","pxt-neutral-foreground3":"#f3f2f1","pxt-neutral-background3-hover":"#202020","pxt-neutral-foreground3-hover":"#ffffff","pxt-neutral-stencil3":"#070707","pxt-neutral-background3-alpha90":"#2d2d2de6","pxt-neutral-base":"rgba(180, 180, 180, 1)","pxt-neutral-alpha0":"rgba(180, 180, 180, 0)","pxt-neutral-alpha10":"rgba(180, 180, 180, 0.1)","pxt-neutral-alpha20":"rgba(180, 180, 180, 0.2)","pxt-neutral-alpha50":"rgba(180, 180, 180, 0.5)","pxt-neutral-alpha80":"rgba(180, 180, 180, 0.8)","pxt-link":"#479ef5","pxt-link-hover":"#62abf5","pxt-focus-border":"#5caae5","pxt-colors-purple-background":"#63276d","pxt-colors-purple-foreground":"#f3f2f1","pxt-colors-purple-hover":"#742e80","pxt-colors-purple-alpha10":"#63276d19","pxt-colors-orange-background":"#7a2101","pxt-colors-orange-foreground":"#ffffff","pxt-colors-orange-hover":"#932801","pxt-colors-orange-alpha10":"#7a210119","pxt-colors-brown-background":"#50301a","pxt-colors-brown-foreground":"#ffffff","pxt-colors-brown-hover":"#633c20","pxt-colors-brown-alpha10":"#50301a19","pxt-colors-blue-background":"#0078D4","pxt-colors-blue-foreground":"#ffffff","pxt-colors-blue-hover":"#026EC1","pxt-colors-blue-alpha10":"#0078D419","pxt-colors-green-background":"#27ae60","pxt-colors-green-foreground":"#ffffff","pxt-colors-green-hover":"#1e8449","pxt-colors-green-alpha10":"#27ae6019","pxt-colors-red-background":"#e74c3c","pxt-colors-red-foreground":"#ffffff","pxt-colors-red-hover":"#c0392b","pxt-colors-red-alpha10":"#e74c3c19","pxt-colors-teal-background":"#1abc9c","pxt-colors-teal-foreground":"#ffffff","pxt-colors-teal-hover":"#16a085","pxt-colors-teal-alpha10":"#1abc9c19","pxt-colors-yellow-background":"#fde300","pxt-colors-yellow-foreground":"#000000","pxt-colors-yellow-hover":"#e4cc00","pxt-colors-yellow-alpha10":"#fde30019"},"overrideCss":".image-editor-change-name .image-editor-input {\n    /* The textbox background matches the footer of the image editor, so add a border */\n    border: 1px solid var(--pxt-neutral-stencil2);\n}\n\n#langmodal #availablelocales .langoption .header {\n    /* Better contrast than default, which is purple */\n    color: var(--pxt-neutral-foreground1);\n}\n\n.pxtToolbox span.blocklyTreeLabel,\n.pxtToolbox .blocklyTreeSelected span.blocklyTreeLabel,\n.pxtToolbox .blocklyTreeSelected .blocklyTreeIcon {\n    /* Better contrast in toolbox */\n    color: var(--pxt-target-foreground3);\n}\n\n.pxtToolbox .blocklyTreeIcon,\n.tutorial-container span.docs.inlineblock {\n    /* Better contrast in toolbox & tutorial block colors, but try to preserve some of the icon color */\n    filter: brightness(1.2) saturate(2);\n}\n\n#mainmenu {\n    /* Some parts of the app use the same color as a background. This keeps the menu from blending in */\n    border-bottom: 1px solid var(--pxt-header-stencil);\n}\n\n.projectsdialog .ui.card:hover {\n    /* Neutral and target colors are the same in dark theme, so it helps to have a clearer border when hovering over cards. */\n    border-color: var(--pxt-focus-border) !important;\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.modals .ui.button.immersive-reader-button,\n#mainmenu .immersive-reader-button.ui.item,\n#simulator .editor-sidebar .immersive-reader-button.ui.item {\n    background-image: url(\"/static/icons/immersive-reader-light.svg\") !important;\n}\n\n.carouselarrow {\n    /* Better contrast, especially against images in carousels */\n    opacity: 0.9;\n}\n\n/* For inverted buttons, it almost always looks better to have the background be dark instead of light (even though non-inverted has a light foreground) */\nbutton.ui.button.inverted:not(.teaching-bubble-button),\nbutton.common-button.inverted:not(.teaching-bubble-button) {\n    background-color: var(--pxt-neutral-background2) !important;\n}\n\nbutton.ui.button.inverted:hover:not(.teaching-bubble-button),\nbutton.common-button.inverted:hover:not(.teaching-bubble-button) {\n    background-color: var(--pxt-neutral-background2-hover) !important;\n}\n"},"arcade-light":{"id":"arcade-light","name":"Light","weight":40,"colors":{"pxt-header-background":"#116E79","pxt-header-foreground":"#FFFFFF","pxt-header-background-hover":"#041d20","pxt-header-foreground-hover":"#FFFFFF","pxt-header-stencil":"#0b454c","pxt-primary-background":"#5D4FBA","pxt-primary-foreground":"#FFFFFF","pxt-primary-background-hover":"#4d3eb1","pxt-primary-foreground-hover":"#FFFFFF","pxt-primary-accent":"#403587","pxt-secondary-background":"#5D4FBA","pxt-secondary-foreground":"#F8FAFC","pxt-secondary-background-hover":"#483c9a","pxt-secondary-foreground-hover":"#F8FAFC","pxt-secondary-accent":"#403587","pxt-tertiary-background":"#116E79","pxt-tertiary-foreground":"#FFFFFF","pxt-tertiary-background-hover":"#0b454c","pxt-tertiary-foreground-hover":"#FFFFFF","pxt-tertiary-accent":"#041d20","pxt-target-background1":"#F8FAFC","pxt-target-foreground1":"#000000","pxt-target-background1-hover":"#d4e0ed","pxt-target-foreground1-hover":"#000000","pxt-target-stencil1":"#e1e1e1","pxt-target-background2":"#F8FAFC","pxt-target-foreground2":"#000000","pxt-target-background2-hover":"#d4e0ed","pxt-target-foreground2-hover":"#000000","pxt-target-stencil2":"#e1e1e1","pxt-target-background3":"#F8FAFC","pxt-target-foreground3":"#000000","pxt-target-background3-hover":"#d4e0ed","pxt-target-foreground3-hover":"#000000","pxt-target-stencil3":"#e1e1e1","pxt-neutral-background1":"#FFFFFF","pxt-neutral-foreground1":"rgba(0,0,0,.85)","pxt-neutral-background1-hover":"#f2f2f2","pxt-neutral-foreground1-hover":"rgba(0,0,0,.85)","pxt-neutral-stencil1":"rgba(34, 74, 114, 0.15)","pxt-neutral-background2":"#F8F8F8","pxt-neutral-foreground2":"rgba(0,0,0,.85)","pxt-neutral-background2-hover":"#ebebeb","pxt-neutral-foreground2-hover":"rgba(0,0,0,.85)","pxt-neutral-stencil2":"#e9eef2","pxt-neutral-background3":"#4e5758","pxt-neutral-foreground3":"#FFFFFF","pxt-neutral-background3-hover":"#424a4a","pxt-neutral-foreground3-hover":"#FFFFFF","pxt-neutral-stencil3":"#FFFFFF","pxt-neutral-background3-alpha90":"#4E5758E5","pxt-neutral-base":"rgba(0, 0, 0, 1)","pxt-neutral-alpha0":"rgba(0, 0, 0, 0)","pxt-neutral-alpha10":"rgba(0, 0, 0, 0.1)","pxt-neutral-alpha20":"rgba(0, 0, 0, 0.2)","pxt-neutral-alpha50":"rgba(0, 0, 0, 0.5)","pxt-neutral-alpha80":"rgba(0, 0, 0, 0.8)","pxt-link":"#3977B4","pxt-link-hover":"#204467","pxt-focus-border":"#0078D4","pxt-colors-purple-background":"#6B4F76","pxt-colors-purple-foreground":"#FFFFFF","pxt-colors-purple-hover":"#483c9a","pxt-colors-purple-alpha10":"#6b4f7619","pxt-colors-orange-background":"#F76820","pxt-colors-orange-foreground":"#FFFFFF","pxt-colors-orange-hover":"#dc4f08","pxt-colors-orange-alpha10":"#F7682019","pxt-colors-brown-background":"#663905","pxt-colors-brown-foreground":"#FFFFFF","pxt-colors-brown-hover":"#351e03","pxt-colors-brown-alpha10":"#66390519","pxt-colors-blue-background":"#116e79","pxt-colors-blue-foreground":"#FFFFFF","pxt-colors-blue-hover":"#0b454c","pxt-colors-blue-alpha10":"#116e7919","pxt-colors-green-background":"#2ecc71","pxt-colors-green-foreground":"#FFFFFF","pxt-colors-green-hover":"#22be64","pxt-colors-green-alpha10":"#2ecc7119","pxt-colors-red-background":"#a80000","pxt-colors-red-foreground":"#FFFFFF","pxt-colors-red-hover":"#8f0000","pxt-colors-red-alpha10":"#a8000019","pxt-colors-teal-background":"#116e79","pxt-colors-teal-foreground":"#FFFFFF","pxt-colors-teal-hover":"#0b454c","pxt-colors-teal-alpha10":"#116e7919","pxt-colors-yellow-background":"#f1c40f","pxt-colors-yellow-foreground":"#000000","pxt-colors-yellow-hover":"#c29d0b","pxt-colors-yellow-alpha10":"#f1c40f19"},"overrideCss":".gallerysegment .ui.card.link.cloudprojectscard {\n    /* Differentiate from New Project button */\n    background-color: var(--pxt-colors-teal-background) !important;\n    color: var(--pxt-colors-teal-foreground) !important;\n}\n"},"arcade-orange":{"id":"arcade-orange","name":"Orange","weight":20,"colors":{"pxt-header-background":"#F76820","pxt-header-foreground":"#FFFFFF","pxt-header-background-hover":"#ab3d06","pxt-header-foreground-hover":"#FFFFFF","pxt-header-stencil":"#dc4f08","pxt-primary-background":"#F76820","pxt-primary-foreground":"#FFFFFF","pxt-primary-background-hover":"#dc4f08","pxt-primary-foreground-hover":"#FFFFFF","pxt-primary-accent":"#C5561F","pxt-secondary-background":"#028B9B","pxt-secondary-background-hover":"#015e69","pxt-secondary-foreground":"#FFFFFF","pxt-secondary-foreground-hover":"#FFFFFF","pxt-secondary-accent":"#015964","pxt-tertiary-background":"#028B9B","pxt-tertiary-foreground":"#FFFFFF","pxt-tertiary-background-hover":"#015e69","pxt-tertiary-foreground-hover":"#FFFFFF","pxt-tertiary-accent":"#013136","pxt-target-background1":"#FEF3E0","pxt-target-foreground1":"#000000","pxt-target-background1-hover":"#fce0af","pxt-target-foreground1-hover":"#000000","pxt-target-stencil1":"#e4d9c7","pxt-target-background2":"#B1E1DA","pxt-target-foreground2":"#000000","pxt-target-background2-hover":"#8cd3c9","pxt-target-foreground2-hover":"#000000","pxt-target-stencil2":"#b0b0b0","pxt-target-background3":"#FEF3E0","pxt-target-foreground3":"#000000","pxt-target-background3-hover":"#E4E4E4","pxt-target-foreground3-hover":"#000000","pxt-target-stencil3":"#e4d9c7","pxt-neutral-background1":"#FFFFFF","pxt-neutral-foreground1":"rgba(0,0,0,.85)","pxt-neutral-background1-hover":"#f2f2f2","pxt-neutral-foreground1-hover":"rgba(0,0,0,.85)","pxt-neutral-stencil1":"rgba(34, 36, 38, .15)","pxt-neutral-background2":"#F8F8F8","pxt-neutral-foreground2":"rgba(0,0,0,.85)","pxt-neutral-background2-hover":"#ebebeb","pxt-neutral-foreground2-hover":"rgba(0,0,0,.85)","pxt-neutral-stencil2":"#e9eef2","pxt-neutral-background3":"#4e5758","pxt-neutral-foreground3":"#FFFFFF","pxt-neutral-background3-hover":"#424a4a","pxt-neutral-foreground3-hover":"#FFFFFF","pxt-neutral-stencil3":"#FFFFFF","pxt-neutral-background3-alpha90":"#4E5758E5","pxt-neutral-base":"rgba(0, 0, 0, 1)","pxt-neutral-alpha0":"rgba(0, 0, 0, 0)","pxt-neutral-alpha10":"rgba(0, 0, 0, 0.1)","pxt-neutral-alpha20":"rgba(0, 0, 0, 0.2)","pxt-neutral-alpha50":"rgba(0, 0, 0, 0.5)","pxt-neutral-alpha80":"rgba(0, 0, 0, 0.8)","pxt-link":"#3977B4","pxt-link-hover":"#204467","pxt-focus-border":"#0078D4","pxt-colors-purple-background":"#6B4F76","pxt-colors-purple-foreground":"#FFFFFF","pxt-colors-purple-hover":"#4f3b57","pxt-colors-purple-alpha10":"#6b4f7619","pxt-colors-orange-background":"#ff7f50","pxt-colors-orange-foreground":"#FFFFFF","pxt-colors-orange-hover":"#ff5a1d","pxt-colors-orange-alpha10":"#ff7f5019","pxt-colors-brown-background":"#663905","pxt-colors-brown-foreground":"#FFFFFF","pxt-colors-brown-hover":"#351e03","pxt-colors-brown-alpha10":"#66390519","pxt-colors-blue-background":"#028b9b","pxt-colors-blue-foreground":"#FFFFFF","pxt-colors-blue-hover":"#015e69","pxt-colors-blue-alpha10":"#028b9b19","pxt-colors-green-background":"#2ecc71","pxt-colors-green-foreground":"#FFFFFF","pxt-colors-green-hover":"#22be64","pxt-colors-green-alpha10":"#2ecc7119","pxt-colors-red-background":"#a80000","pxt-colors-red-foreground":"#FFFFFF","pxt-colors-red-hover":"#8f0000","pxt-colors-red-alpha10":"#a8000019","pxt-colors-teal-background":"#028B9B","pxt-colors-teal-foreground":"#FFFFFF","pxt-colors-teal-hover":"#015e69","pxt-colors-teal-alpha10":"#028b9b19","pxt-colors-yellow-background":"#c0a000","pxt-colors-yellow-foreground":"#FFFFFF","pxt-colors-yellow-hover":"rgb(153, 132, 0)","pxt-colors-yellow-alpha10":"#c0a00019"}}},"bundledpkgs":{"animation":{"README.md":"# Animations\n\nA small animation library.","legacy.ts":"/*\n    Animation library for sprites\n*/\nnamespace animation {\n    //Handles all the updates\n    let animations: Animation[];\n\n    let animationStateStack: {\n        state: Animation[],\n        scene: scene.Scene\n    }[];\n\n    game.addScenePushHandler(oldScene => {\n        if (animations) {\n            if (!animationStateStack) animationStateStack = [];\n            animationStateStack.push({\n                state: animations,\n                scene: oldScene\n            });\n            animations = undefined;\n        }\n    });\n\n    game.addScenePopHandler(() => {\n        const scene = game.currentScene();\n        animations = undefined;\n        if (animationStateStack && animationStateStack.length) {\n            const nextState = animationStateStack.pop();\n            if (nextState.scene == scene) {\n                animations = nextState.state;\n            } else {\n                animationStateStack.push(nextState);\n            }\n        }\n    });\n\n    export class Animation {\n\n        sprites: Sprite[];\n        frames: Image[];\n        index: number;\n        interval: number;\n        action: number;\n        lastTime: number;\n\n        constructor(action: number, interval: number) {\n            this.interval = interval;\n            this.index = -1;\n            this.action = action;\n            this.frames = [];\n            this.sprites = [];\n            this.lastTime = control.millis();\n\n            this._init();\n        }\n\n        _init() {\n            if (!animations) {\n                animations = [];\n                game.eventContext().registerFrameHandler(scene.ANIMATION_UPDATE_PRIORITY, () => {\n                    animations.forEach(anim => anim.update());\n                });\n            }\n            animations.push(this);\n        }\n\n        update() {\n            let currentTime = control.millis();\n            let dt = currentTime - this.lastTime;\n            if (dt >= this.interval && this.frames.length) {\n                this.index = (this.index + 1) % this.frames.length;\n                this.lastTime = currentTime;\n            }\n\n            this.sprites = this.sprites.filter(sprite => !(sprite.flags & sprites.Flag.Destroyed));\n\n            this.sprites.forEach(sprite => {\n                if (sprite._action === this.action) {\n                    let newImage = this.getImage();\n                    //Update only if the image has changed\n                    if (sprite.image !== newImage) {\n                        sprite.setImage(newImage);\n                    }\n                }\n            });\n        }\n\n        getImage() {\n            return this.frames[this.index];\n        }\n\n        getAction() {\n            return this.action;\n        }\n\n        getInterval() {\n            return this.interval;\n        }\n\n        setInterval(interval: number) {\n            this.interval = interval;\n        }\n\n        /**\n        * Add an image frame to an animation\n        */\n        //% blockId=addAnimationFrame\n        //% block=\"add frame $frame=screen_image_picker to $this=variables_get(anim)\"\n        //% group=\"Advanced\"\n        //% weight=40\n        //% help=animation/add-animation-frame\n        addAnimationFrame(frame: Image) {\n            this.frames[++this.index] = frame;\n        }\n\n        registerSprite(sprite: Sprite) {\n            if (this.sprites.indexOf(sprite) === -1) {\n                this.sprites.push(sprite);\n            }\n        }\n\n    }\n\n    //% shim=ENUM_GET\n    //% blockId=action_enum_shim\n    //% block=\"%arg\"\n    //% group=\"Advanced\"\n    //% enumName=\"ActionKind\"\n    //% enumMemberName=\"action\"\n    //% enumPromptHint=\"e.g. Walking, Idle, Jumping, ...\"\n    //% enumInitialMembers=\"Walking, Idle, Jumping\"\n    //% weight=10\n    export function _actionEnumShim(arg: number) {\n        // This function should do nothing, but must take in a single\n        // argument of type number and return a number value.\n        return arg;\n    }\n\n    /**\n     * Create an animation\n     */\n    //% blockId=createAnimation\n    //% block=\"create animation of $action=action_enum_shim with interval $interval ms\"\n    //% group=\"Advanced\"\n    //% interval.defl=1000\n    //% blockSetVariable=\"anim\"\n    //% weight=50\n    //% help=animation/create-animation\n    export function createAnimation(action: number, interval: number) {\n        return new Animation(action, interval);\n    }\n\n    /**\n     * Attach an animation to a sprite\n     */\n    //% blockId=attachAnimation\n    //% block=\"attach animation $set=variables_get(anim) to sprite $sprite=variables_get(mySprite)\"\n    //% group=\"Advanced\"\n    //% weight=30\n    //% help=animation/attach-animation\n    export function attachAnimation(sprite: Sprite, set: Animation) {\n        set.registerSprite(sprite);\n    }\n\n    /**\n     * Set an animation action to a sprite\n     */\n    //% blockId=setAction\n    //% block=\"activate animation $action=action_enum_shim on $sprite=variables_get(mySprite)\"\n    //% group=\"Advanced\"\n    //% weight=20\n    //% help=animation/set-action\n    export function setAction(sprite: Sprite, action: number) {\n        sprite._action = action;\n    }\n\n}","pxt.json":"{\n    \"name\": \"animation\",\n    \"description\": \"Advanced state based animations for sprites\",\n    \"dependencies\": {\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"legacy.ts\",\n        \"targetoverrides.ts\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"weight\": 80,\n    \"icon\": \"/static/libs/animation.png\"\n}\n","targetoverrides.ts":"// TODO any platform specific overrides","test.ts":"let mySprite: Sprite = sprites.create(img`\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    `, SpriteKind.Player);\nanimation.runImageAnimation(\n    mySprite,\n    [img`\n    1 . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    `,\n    img`\n    2 . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    `],\n    500\n)\nanimation.runMovementAnimation(\n    mySprite,\n    animation.animationPresets(animation.flyToCenter),\n    500\n)\nanimation.runImageAnimation(\n    mySprite,\n    [img`\n    1 . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    `,\n    img`\n    2 . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . .\n    . . . . . . . . . . . . . . . .\n    `],\n    500,\n    true\n)\nanimation.runMovementAnimation(\n    mySprite,\n    animation.animationPresets(animation.flyToCenter),\n    500\n)"},"accelerometer":{"README.md":"# accelerometer\n\nThe accelerometer library.\n\n","accelerometer.cpp":"#include \"pxt.h\"\n#include \"axis.h\"\n#include \"Pin.h\"\n#include \"I2C.h\"\n#include \"CoordinateSystem.h\"\n#include \"Accelerometer.h\"\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 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 = ACCELEROMETER_EVT_SHAKE,\n    /**\n     * Raised when the device tilts up\n     */\n    //% block=\"tilt up\"\n    TiltUp = ACCELEROMETER_EVT_TILT_UP,\n    /**\n     * Raised when the device tilts down\n     */\n    //% block=\"tilt down\"\n    TiltDown = ACCELEROMETER_EVT_TILT_DOWN,\n    /**\n     * Raised when the screen is pointing left\n     */\n    //% block=\"tilt left\"\n    TiltLeft = ACCELEROMETER_EVT_TILT_LEFT,\n    /**\n     * Raised when the screen is pointing right\n     */\n    //% block=\"tilt right\"\n    TiltRight = ACCELEROMETER_EVT_TILT_RIGHT,\n    /**\n     * Raised when the screen faces up\n     */\n    //% block=\"face up\"\n    FaceUp = ACCELEROMETER_EVT_FACE_UP,\n    /**\n     * Raised when the screen is pointing up and the board is horizontal\n     */\n    //% block=\"face down\"\n    FaceDown = ACCELEROMETER_EVT_FACE_DOWN,\n    /**\n     * Raised when the board is falling!\n     */\n    //% block=\"free fall\"\n    FreeFall = ACCELEROMETER_EVT_FREEFALL,\n    /**\n     * Raised when a 2G shock is detected\n     */\n    //% block=\"2g (step)\"\n    TwoG = ACCELEROMETER_EVT_2G,\n    /**\n     * Raised when a 3G shock is detected\n     */\n    //% block=\"3g\"\n    ThreeG = ACCELEROMETER_EVT_3G,\n    /**\n     * Raised when a 6G shock is detected\n     */\n    //% block=\"6g\"\n    SixG = ACCELEROMETER_EVT_6G,\n    /**\n     * Raised when a 8G shock is detected\n     */\n    //% block=\"8g\"\n    EightG = ACCELEROMETER_EVT_8G\n};\n\n// defined in accelhw.cpp\nnamespace pxt {\ncodal::Accelerometer *getAccelerometer();\n\nvoid initAccelRandom() {\n    auto acc = getAccelerometer();\n    if (!acc) return;\n\n    for (int i = 0; i < 10; ++i) {\n        acc->requestUpdate();\n        if (acc->getY())\n            break;\n        fiber_sleep(5);\n    }\n    int x = acc->getX(), y = acc->getY(), z = acc->getZ();\n    DMESG(\"random seed from accel %d,%d,%d\", x, y, z);\n    seedAddRandom(x);\n    seedAddRandom(y);\n    seedAddRandom(z);\n}\n\n} // namespace pxt\n\nnamespace input {\n/**\n * Do something when a gesture happens (like shaking the board).\n * @param gesture the type of gesture to track, eg: Gesture.Shake\n * @param body code to run when gesture is raised\n */\n//% help=input/on-gesture\n//% blockId=device_gesture_event block=\"on |%NAME\"\n//% parts=\"accelerometer\"\n//% gesture.fieldEditor=\"gridpicker\"\n//% gesture.fieldOptions.width=220\n//% gesture.fieldOptions.columns=3\n//% weight=92 blockGap=12\nvoid onGesture(Gesture gesture, Action body) {\n    auto acc = getAccelerometer();\n    if (!acc) return;\n\n    acc->requestUpdate();\n    int gi = (int)gesture;\n    if (gi == ACCELEROMETER_EVT_3G && acc->getRange() < 3)\n        acc->setRange(4);\n    else if ((gi == ACCELEROMETER_EVT_6G || gi == ACCELEROMETER_EVT_8G) && acc->getRange() < 6)\n        acc->setRange(8);\n    registerWithDal(DEVICE_ID_GESTURE, gi, body);\n}\n\n/**\n * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\n * x=0, y=0 and z=-1023)\n * @param dimension TODO\n */\n//% help=input/acceleration\n//% blockId=device_acceleration block=\"acceleration (mg)|%NAME\"\n//% parts=\"accelerometer\"\n//% dimension.fieldEditor=\"gridpicker\"\n//% dimension.fieldOptions.width=180\n//% dimension.fieldOptions.columns=2\n//% weight=42 blockGap=8\nint acceleration(Dimension dimension) {\n    auto acc = getAccelerometer();\n    if (!acc) return 0;\n\n    acc->requestUpdate();\n    switch (dimension) {\n    case Dimension::X:\n        return acc->getX();\n    case Dimension::Y:\n        return acc->getY();\n    case Dimension::Z:\n        return acc->getZ();\n    case Dimension::Strength:\n        float x = acc->getX();\n        float y = acc->getY();\n        float z = acc->getZ();\n        return (int)sqrtf(x * x + y * y + z * z);\n    }\n    return 0;\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\n//% blockId=device_get_rotation block=\"rotation (°)|%NAME\"\n//% parts=\"accelerometer\"\n//% group=\"More\" weight=38\nint rotation(Rotation kind) {\n    auto acc = getAccelerometer();\n    if (!acc) return 0;\n\n    acc->requestUpdate();\n    switch (kind) {\n    case Rotation::Pitch:\n        return acc->getPitch();\n    case Rotation::Roll:\n        return acc->getRoll();\n    }\n    return 0;\n}\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//% group=\"More\" weight=15 blockGap=8\nvoid setAccelerometerRange(AcceleratorRange range) {\n    auto acc = getAccelerometer();\n    if (!acc) return;\n\n    acc->setRange((int)range);\n}\n\n} // namespace input\n","accelhw.cpp":"// This supports a few different accelerometers.\n// If desired, overrides PXT_SUPPORT_* in platform.h (note that only LIS3DH is on by default).\n// Then accelerometer can be changed with config.ACCELEROMETER_TYPE in TypeScript.\n// This file can be overridden alltogether by a target if a different accelerometer is desired.\n\n#include \"pxt.h\"\n#include \"axis.h\"\n#include \"Pin.h\"\n#include \"I2C.h\"\n#include \"CoordinateSystem.h\"\n#include \"CodalDmesg.h\"\n\n#ifndef PXT_DEFAULT_ACCELEROMETER\n#define PXT_DEFAULT_ACCELEROMETER -1\n#endif\n\n#ifndef PXT_SUPPORT_LIS3DH\n#define PXT_SUPPORT_LIS3DH 1\n#endif\n#if PXT_SUPPORT_LIS3DH\n#include \"LIS3DH.h\"\n#endif\n\n#ifndef PXT_SUPPORT_MMA8653\n#define PXT_SUPPORT_MMA8653 0\n#endif\n#if PXT_SUPPORT_MMA8653\n#include \"MMA8653.h\"\n#endif\n\n#ifndef PXT_SUPPORT_MMA8453\n#define PXT_SUPPORT_MMA8453 0\n#endif\n#if PXT_SUPPORT_MMA8453\n#include \"MMA8453.h\"\n#endif\n\n#ifndef PXT_SUPPORT_FXOS8700\n#define PXT_SUPPORT_FXOS8700 0\n#endif\n#if PXT_SUPPORT_FXOS8700\n#include \"FXOS8700Accelerometer.h\"\n#endif\n\n#ifndef PXT_SUPPORT_MSA300\n#define PXT_SUPPORT_MSA300 0\n#endif\n#if PXT_SUPPORT_MSA300\n#include \"MSA300.h\"\n#endif\n\n#ifndef PXT_SUPPORT_MPU6050\n#define PXT_SUPPORT_MPU6050 0\n#endif\n#if PXT_SUPPORT_MPU6050\n#include \"MPU6050.h\"\n#endif\n\n#if defined(CODAL_ACCELEROMETER)\n#error \"please define PXT_SUPPORT_*\"\n#endif\n\nnamespace pxt {\n\n    /*\nRAW,                            0x000000\nSIMPLE_CARTESIAN,               0x000001\nNORTH_EAST_DOWN,                0x000002\nNORTH_EAST_UP                   0x000003\n\nCOORDINATE_SPACE_ROTATED_0      0x000000\nCOORDINATE_SPACE_ROTATED_90     0x000010\nCOORDINATE_SPACE_ROTATED_180    0x000020\nCOORDINATE_SPACE_ROTATED_270    0x000030\n\nNOT_UPSIDE_DOWN                 0x000000\nUPSIDE_DOWN                     0x000100\n    */\n\nstatic CoordinateSpace boardCoordinateSpace() {\n    int defaultSpace = ((int)ACC_SYSTEM) | ((int)ACC_ROTATION << 4) | (ACC_UPSIDEDOWN ? 0x100 : 0x000);\n#if defined(STM32F4) && PXT_SUPPORT_MPU6050\n    // meowbit\n    if (getConfig(CFG_ACCELEROMETER_TYPE, -1) == ACCELEROMETER_TYPE_MPU6050)\n        defaultSpace = 0x33;\n#endif\n    int space = getConfig(CFG_ACCELEROMETER_SPACE, defaultSpace);\n    DMESG(\"coordinate space: %d / %d, %s\", space & 0xf, (space >> 4) & 0xf, space & 0x100 ? \"upside\" : \"normal\");\n    return CoordinateSpace((CoordinateSystem)(space & 0xf), !!(space & 0x100), (space >> 4) & 0xf);\n}\n\n// Wrapper classes\nclass WAccel {\n    CoordinateSpace space;\n\t\t\n  public:\n    Accelerometer *acc;\n    WAccel() \n    : space(boardCoordinateSpace())\n    , acc(NULL) {\n        DMESG(\"acc: mounting\");\n        auto sda = LOOKUP_PIN(ACCELEROMETER_SDA);\n        auto scl = LOOKUP_PIN(ACCELEROMETER_SCL);\n        if (NULL == sda || NULL == scl) { // use default i2c instead\n            DMESG(\"acc: using SDA, SCL\");\n            sda = LOOKUP_PIN(SDA);\n            scl = LOOKUP_PIN(SCL);\n        }\n        codal::I2C* i2c = pxt::getI2C(sda, scl);\n        if (NULL == i2c) {\n            DMESG(\"acc: no i2c available\");\n            return;\n        }\n\t\t\n        int accType = getConfig(CFG_ACCELEROMETER_TYPE, PXT_DEFAULT_ACCELEROMETER);\n        acc = instantiateAccelerometer(accType, i2c);\n        if (NULL == acc) {\n            int accDetect = detectAccelerometer(i2c);\n            if (accDetect < 0) {\n                DMESG(\"acc: not detected\");\n            } else {\n                DMESG(\"acc: detected %d\", accDetect);\n                acc = instantiateAccelerometer(accDetect, i2c);\n            }\n        }\n\n        if (NULL == acc) {\n            // the accelerometer might be damaged or incorrectly configured,\n            // in doubt, we just ignore it            \n            if (LOOKUP_PIN(ACCELEROMETER_SDA))\n                DMESG(\"acc: damaged accelereomter or invalid ACCELEROMETER_TYPE\");\n            else\n                DMESG(\"acc: invalid ACCELEROMETER_TYPE\");\n            // acc is already NULL, do nothing\n        }\n        else {\n            // acc->init(); - doesn't do anything\n            acc->configure();\n            acc->requestUpdate();\n            DMESG(\"acc: mounted\");\n        }\n    }\n\nprivate:\n\n\tint detectAccelerometer(codal::I2C* i2c){\n\t\tuint8_t data;\n\t\tint result;\n\n#if PXT_SUPPORT_LIS3DH\n\t\tresult = i2c->readRegister(ACCELEROMETER_TYPE_LIS3DH, LIS3DH_WHOAMI, &data, 1);\n\t\tif (result ==0)\n\t\t\treturn ACCELEROMETER_TYPE_LIS3DH;\n\t\tresult = i2c->readRegister(ACCELEROMETER_TYPE_LIS3DH_ALT, LIS3DH_WHOAMI, &data, 1);\n\t\tif (result ==0)\n\t\t\treturn ACCELEROMETER_TYPE_LIS3DH_ALT;\n#endif\n\t\t\t\n#if PXT_SUPPORT_MMA8453\n\t\tresult = i2c->readRegister(ACCELEROMETER_TYPE_MMA8453, MMA8653_WHOAMI/*MMA8453 is similar to MMA8653*/ , &data, 1);\n\t\tif (result ==0)\n\t\t\treturn ACCELEROMETER_TYPE_MMA8453;\n#endif\n\n#if PXT_SUPPORT_FXOS8700\n\t\tresult = i2c->readRegister(ACCELEROMETER_TYPE_FXOS8700, FXOS8700_WHO_AM_I, &data, 1);\n\t\tif (result ==0)\n\t\t\treturn ACCELEROMETER_TYPE_FXOS8700;\n#endif\n\t\t\n#if PXT_SUPPORT_MMA8653\n\t\tresult = i2c->readRegister(ACCELEROMETER_TYPE_MMA8653,  MMA8653_WHOAMI, &data, 1);\n\t\tif (result ==0)\n\t\t\treturn ACCELEROMETER_TYPE_MMA8653;\t\n#endif\n\t\t\n#if PXT_SUPPORT_MSA300\n\t\tresult = i2c->readRegister(ACCELEROMETER_TYPE_MSA300, MSA300_WHOAMI, &data, 1);\n\t\tif (result ==0)\n\t\t\treturn ACCELEROMETER_TYPE_MSA300;\t\n#endif\n\t\t\t\n#if PXT_SUPPORT_MPU6050\n\t\tresult = i2c->readRegister(ACCELEROMETER_TYPE_MPU6050, MPU6050_WHOAMI, &data, 1);\n\t\tif (result ==0)\n\t\t\treturn ACCELEROMETER_TYPE_MPU6050;\t\n#endif \n\n\t\treturn -1;\n\t}\n\n    codal::Accelerometer* instantiateAccelerometer(int accType, codal::I2C* i2c) {\n        switch (accType) {\n#if PXT_SUPPORT_LIS3DH\n        case ACCELEROMETER_TYPE_LIS3DH:\n        case ACCELEROMETER_TYPE_LIS3DH_ALT:\n            return new LIS3DH(*i2c, *LOOKUP_PIN(ACCELEROMETER_INT), space, accType);\n#endif\n#if PXT_SUPPORT_MSA300\n        case ACCELEROMETER_TYPE_MSA300:\n            return new MSA300(*i2c, *LOOKUP_PIN(ACCELEROMETER_INT), space);\n#endif\n#if PXT_SUPPORT_FXOS8700\n        case ACCELEROMETER_TYPE_FXOS8700: {\n            // TODO: singleton when exposing gyro\n            auto fox = new FXOS8700(*i2c, *LOOKUP_PIN(ACCELEROMETER_INT));\n            return new FXOS8700Accelerometer(*fox, space);\n        }\n#endif\n#if PXT_SUPPORT_MMA8653\n        case ACCELEROMETER_TYPE_MMA8653:\n            return new MMA8653(*i2c, *LOOKUP_PIN(ACCELEROMETER_INT), space);\n#endif\n#if PXT_SUPPORT_MMA8453\n        case ACCELEROMETER_TYPE_MMA8453:\n            return new MMA8453(*i2c, *LOOKUP_PIN(ACCELEROMETER_INT), space);\n#endif\n#if PXT_SUPPORT_MPU6050\n        case ACCELEROMETER_TYPE_MPU6050:\n            return new MPU6050(*i2c, *LOOKUP_PIN(ACCELEROMETER_INT), space);\n#endif\n        default:\n            return NULL;\n        }\n    }\n\n};\n\nstatic WAccel *instAcc;\ncodal::Accelerometer *getAccelerometer() {\n    if (instAcc)\n        return instAcc->acc;\n    if (LOOKUP_PIN(ACCELEROMETER_INT) || LOOKUP_PIN(ACCELEROMETER_SDA)) {\n        instAcc = new WAccel();\n        return instAcc->acc;\n    }\n    return NULL;\n}\n\n} // namespace pxt\n","axis.h":"// Override in target to change inversion of axis\n\n#define ACC_SYSTEM NORTH_EAST_UP\n#define ACC_UPSIDEDOWN false\n#define ACC_ROTATION COORDINATE_SPACE_ROTATED_0\n","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const 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 const enum Rotation {\n    //% block=pitch\n    Pitch = 0,\n    //% block=roll\n    Roll = 1,\n    }\n\n\n    declare const 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 const enum Gesture {\n    /**\n     * Raised when shaken\n     */\n    //% block=shake\n    Shake = 11,  // ACCELEROMETER_EVT_SHAKE\n    /**\n     * Raised when the device tilts up\n     */\n    //% block=\"tilt up\"\n    TiltUp = 1,  // ACCELEROMETER_EVT_TILT_UP\n    /**\n     * Raised when the device tilts down\n     */\n    //% block=\"tilt down\"\n    TiltDown = 2,  // ACCELEROMETER_EVT_TILT_DOWN\n    /**\n     * Raised when the screen is pointing left\n     */\n    //% block=\"tilt left\"\n    TiltLeft = 3,  // ACCELEROMETER_EVT_TILT_LEFT\n    /**\n     * Raised when the screen is pointing right\n     */\n    //% block=\"tilt right\"\n    TiltRight = 4,  // ACCELEROMETER_EVT_TILT_RIGHT\n    /**\n     * Raised when the screen faces up\n     */\n    //% block=\"face up\"\n    FaceUp = 5,  // ACCELEROMETER_EVT_FACE_UP\n    /**\n     * Raised when the screen is pointing up and the board is horizontal\n     */\n    //% block=\"face down\"\n    FaceDown = 6,  // ACCELEROMETER_EVT_FACE_DOWN\n    /**\n     * Raised when the board is falling!\n     */\n    //% block=\"free fall\"\n    FreeFall = 7,  // ACCELEROMETER_EVT_FREEFALL\n    /**\n     * Raised when a 2G shock is detected\n     */\n    //% block=\"2g (step)\"\n    TwoG = 12,  // ACCELEROMETER_EVT_2G\n    /**\n     * Raised when a 3G shock is detected\n     */\n    //% block=\"3g\"\n    ThreeG = 8,  // ACCELEROMETER_EVT_3G\n    /**\n     * Raised when a 6G shock is detected\n     */\n    //% block=\"6g\"\n    SixG = 9,  // ACCELEROMETER_EVT_6G\n    /**\n     * Raised when a 8G shock is detected\n     */\n    //% block=\"8g\"\n    EightG = 10,  // ACCELEROMETER_EVT_8G\n    }\n\n// Auto-generated. Do not edit. Really.\n","gesture.ts":"namespace input {\n    /**\n     * Registers a custom gesture recognizer\n     * @param id \n     * @param update true if gesture detected\n     * @param handler \n     */\n    export function onCustomGesture(\n        id: number, \n        update: () => boolean, \n        handler: () => void) {\n        if (!update || !handler) return;\n\n        input.acceleration(Dimension.X); // turn on accelerometer\n        const evid = DAL.ACCELEROMETER_EVT_2G + 1 + (id | 0);\n        control.onEvent(DAL.DEVICE_ID_GESTURE, evid, handler);\n        let sigma = 0;\n        control.onIdle(function() {\n            if (sigma > 0) {\n                sigma--;\n            } else if(update()) {\n                sigma = 6;\n                control.raiseEvent(DAL.DEVICE_ID_GESTURE, evid);\n            }\n        })\n    }\n}","ns.ts":"\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\nnamespace input {\n}","part.svg":"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<svg\n   xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n   xmlns:cc=\"http://creativecommons.org/ns#\"\n   xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n   xmlns:svg=\"http://www.w3.org/2000/svg\"\n   xmlns=\"http://www.w3.org/2000/svg\"\n   xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"\n   xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"\n   width=\"92.834999\"\n   height=\"48.351559\"\n   y=\"0\"\n   x=\"0\"\n   viewBox=\"0 0 92.834999 48.351559\"\n   id=\"svg4493\"\n   version=\"1.1\"\n   sodipodi:docname=\"part.svg\"\n   inkscape:version=\"0.92.1 r15371\">\n  <metadata\n     id=\"metadata4514\">\n    <rdf:RDF>\n      <cc:Work\n         rdf:about=\"\">\n        <dc:format>image/svg+xml</dc:format>\n        <dc:type\n           rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\n        <dc:title />\n      </cc:Work>\n    </rdf:RDF>\n  </metadata>\n  <defs\n     id=\"defs4512\" />\n  <sodipodi:namedview\n     pagecolor=\"#ffffff\"\n     bordercolor=\"#666666\"\n     borderopacity=\"1\"\n     objecttolerance=\"10\"\n     gridtolerance=\"10\"\n     guidetolerance=\"10\"\n     inkscape:pageopacity=\"0\"\n     inkscape:pageshadow=\"2\"\n     inkscape:window-width=\"1600\"\n     inkscape:window-height=\"837\"\n     id=\"namedview4510\"\n     showgrid=\"false\"\n     inkscape:zoom=\"8.2495794\"\n     inkscape:cx=\"42.339269\"\n     inkscape:cy=\"33.871495\"\n     inkscape:window-x=\"-8\"\n     inkscape:window-y=\"-8\"\n     inkscape:window-maximized=\"1\"\n     inkscape:current-layer=\"svg4493\"\n     fit-margin-top=\"0\"\n     fit-margin-left=\"0\"\n     fit-margin-right=\"0\"\n     fit-margin-bottom=\"0\"\n     units=\"px\"\n     inkscape:measure-start=\"-5.21239,56.8514\"\n     inkscape:measure-end=\"23.6376,42.184\" />\n  <rect\n     rx=\"1.1604376\"\n     y=\"0.048351564\"\n     height=\"48.254856\"\n     width=\"92.738297\"\n     id=\"rect5038\"\n     x=\"0.048351564\"\n     style=\"fill:#5a86c2;stroke:#8e8e8e;stroke-width:0.09670313\" />\n  <text\n     id=\"text5094\"\n     y=\"40.50362\"\n     x=\"4.5252295\"\n     style=\"font-weight:400;font-size:13.53218174px;line-height:1.25;font-family:consolas;-inkscape-font-specification:consolas;letter-spacing:0;word-spacing:0;fill:#ffffff;stroke-width:0.37589398\"\n     font-weight=\"400\"\n     font-size=\"14.4\"\n     letter-spacing=\"0\"\n     word-spacing=\"0\"\n     transform=\"scale(0.99296988,1.0070799)\">\n    <tspan\n       y=\"40.50362\"\n       x=\"4.5252295\"\n       id=\"tspan5092\"\n       style=\"font-size:10.02383709px;stroke-width:0.37589398\">ACCELEROMETER</tspan>\n  </text>\n  <rect\n     rx=\"0.78499681\"\n     y=\"32.338985\"\n     x=\"77.394577\"\n     height=\"10.968015\"\n     width=\"11.303953\"\n     id=\"rect5096\"\n     style=\"stroke:#000000;stroke-width:0.3893353\" />\n  <ellipse\n     style=\"fill:#ffffff;stroke:#000000;stroke-width:0.32272443\"\n     cy=\"-5.9231954\"\n     cx=\"-9.2452202\"\n     id=\"ACCELEROMETER_INT\"\n     transform=\"scale(-1)\"\n     rx=\"3.23646\"\n     ry=\"3.218055\"\n     inkscape:label=\"#path5042-7-6\" />\n  <text\n     transform=\"matrix(0,1.0070833,-0.99296652,0,0,0)\"\n     id=\"text5100-8-5\"\n     y=\"-7.1094813\"\n     x=\"10.925499\"\n     style=\"font-weight:400;font-size:6.13176918px;line-height:1.25;font-family:consolas;-inkscape-font-specification:consolas;letter-spacing:0;word-spacing:0;fill:#ffffff;stroke-width:0.32272473\"\n     font-weight=\"400\"\n     font-size=\"1.9\"\n     letter-spacing=\"0\"\n     word-spacing=\"0\">\n    <tspan\n       y=\"-7.1094813\"\n       x=\"10.925499\"\n       id=\"tspan5098-2-4\"\n       style=\"stroke-width:0.32272473\">INT</tspan>\n  </text>\n  <ellipse\n     style=\"fill:#ffffff;stroke:#000000;stroke-width:0.32272443\"\n     cy=\"-5.9231954\"\n     cx=\"-39.334583\"\n     id=\"SDA\"\n     transform=\"scale(-1)\"\n     rx=\"3.23646\"\n     ry=\"3.218055\"\n     inkscape:label=\"#path5042-7-3\" />\n  <text\n     transform=\"matrix(0,1.0070833,-0.99296652,0,0,0)\"\n     id=\"text5100-8-5-4\"\n     y=\"-37.301361\"\n     x=\"11.108133\"\n     style=\"font-weight:400;font-size:6.13176918px;line-height:1.25;font-family:consolas;-inkscape-font-specification:consolas;letter-spacing:0;word-spacing:0;fill:#ffffff;stroke-width:0.32272473\"\n     font-weight=\"400\"\n     font-size=\"1.9\"\n     letter-spacing=\"0\"\n     word-spacing=\"0\">\n    <tspan\n       id=\"tspan5156\"\n       y=\"-37.301361\"\n       x=\"11.108133\"\n       style=\"stroke-width:0.32272473\">SDA</tspan>\n  </text>\n  <ellipse\n     style=\"fill:#ffffff;stroke:#000000;stroke-width:0.32272443\"\n     cy=\"-5.9231954\"\n     cx=\"-70.055618\"\n     id=\"VCC\"\n     transform=\"scale(-1)\"\n     rx=\"3.23646\"\n     ry=\"3.218055\"\n     inkscape:label=\"#path5042-7-1\" />\n  <text\n     transform=\"matrix(0,1.0070833,-0.99296652,0,0,0)\"\n     id=\"text5100-8-5-4-9\"\n     y=\"-68.672005\"\n     x=\"11.428495\"\n     style=\"font-weight:400;font-size:6.13176918px;line-height:1.25;font-family:consolas;-inkscape-font-specification:consolas;letter-spacing:0;word-spacing:0;fill:#ffffff;stroke-width:0.32272473\"\n     font-weight=\"400\"\n     font-size=\"1.9\"\n     letter-spacing=\"0\"\n     word-spacing=\"0\">\n    <tspan\n       id=\"tspan5156-5\"\n       y=\"-68.672005\"\n       x=\"11.428495\"\n       style=\"stroke-width:0.32272473\">VCC</tspan>\n  </text>\n  <ellipse\n     style=\"fill:#ffffff;stroke:#000000;stroke-width:0.32272443\"\n     cy=\"-5.9231954\"\n     cx=\"-85.100304\"\n     id=\"GND\"\n     transform=\"scale(-1)\"\n     rx=\"3.23646\"\n     ry=\"3.218055\"\n     inkscape:label=\"#path5042-7-0\" />\n  <text\n     transform=\"matrix(0,1.0070833,-0.99296652,0,0,0)\"\n     id=\"text5100-8-5-4-9-3\"\n     y=\"-83.929306\"\n     x=\"11.242865\"\n     style=\"font-weight:400;font-size:6.13176918px;line-height:1.25;font-family:consolas;-inkscape-font-specification:consolas;letter-spacing:0;word-spacing:0;fill:#ffffff;stroke-width:0.32272473\"\n     font-weight=\"400\"\n     font-size=\"1.9\"\n     letter-spacing=\"0\"\n     word-spacing=\"0\">\n    <tspan\n       id=\"tspan5156-5-7\"\n       y=\"-83.929306\"\n       x=\"11.242865\"\n       style=\"stroke-width:0.32272473\">GND</tspan>\n  </text>\n  <ellipse\n     style=\"fill:#ffffff;stroke:#000000;stroke-width:0.32272443\"\n     cy=\"-5.9231954\"\n     cx=\"-24.289902\"\n     id=\"SCL\"\n     transform=\"scale(-1)\"\n     rx=\"3.23646\"\n     ry=\"3.218055\"\n     inkscape:label=\"#path5042-7-6-2\" />\n  <text\n     transform=\"matrix(0,1.0070833,-0.99296652,0,0,0)\"\n     id=\"text5100-8-5-47\"\n     y=\"-22.366781\"\n     x=\"11.108133\"\n     style=\"font-weight:400;font-size:6.13176918px;line-height:1.25;font-family:consolas;-inkscape-font-specification:consolas;letter-spacing:0;word-spacing:0;fill:#ffffff;stroke-width:0.32272473\"\n     font-weight=\"400\"\n     font-size=\"1.9\"\n     letter-spacing=\"0\"\n     word-spacing=\"0\">\n    <tspan\n       y=\"-22.366781\"\n       x=\"11.108133\"\n       id=\"tspan5098-2-4-5\"\n       style=\"stroke-width:0.32272473\">SCL</tspan>\n  </text>\n  <ellipse\n     style=\"fill:#ffffff;stroke:#000000;stroke-width:0.32272443\"\n     cy=\"-5.5968285\"\n     cx=\"-54.547421\"\n     id=\"SDO\"\n     transform=\"scale(-1)\"\n     rx=\"3.23646\"\n     ry=\"3.218055\"\n     inkscape:label=\"#path5042-7-3\" />\n  <text\n     transform=\"matrix(0,1.0070833,-0.99296652,0,0,0)\"\n     id=\"text5100-8-5-4-4\"\n     y=\"-52.621964\"\n     x=\"10.784061\"\n     style=\"font-weight:400;font-size:6.13176918px;line-height:1.25;font-family:consolas;-inkscape-font-specification:consolas;letter-spacing:0;word-spacing:0;fill:#ffffff;stroke-width:0.32272473\"\n     font-weight=\"400\"\n     font-size=\"1.9\"\n     letter-spacing=\"0\"\n     word-spacing=\"0\">\n    <tspan\n       id=\"tspan5156-4\"\n       y=\"-52.621964\"\n       x=\"10.784061\"\n       style=\"stroke-width:0.32272473\">SDO</tspan>\n  </text>\n</svg>\n","pxt.json":"{\n    \"name\": \"accelerometer\",\n    \"description\": \"The accelerometer library\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"accelerometer.cpp\",\n        \"accelhw.cpp\",\n        \"axis.h\",\n        \"gesture.ts\",\n        \"shims.d.ts\",\n        \"enums.d.ts\",\n        \"ns.ts\",\n        \"pxtparts.json\",\n        \"part.svg\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"yotta\": {\n        \"config\": {\n            \"PXT_SUPPORT_LIS3DH\": 1,\n            \"PXT_SUPPORT_MMA8453\": 1,\n            \"PXT_SUPPORT_MPU6050\": 1\n        }\n    },\n    \"hidden\": true\n}\n","pxtparts.json":"{\n  \"accelerometer\": {\n    \"visual\": {\n      \"image\": \"part.svg\",\n      \"width\": 92.83499908447266,\n      \"height\": 48.351558685302734,\n      \"pinDistance\": 15,\n      \"pinLocations\": [\n        {\n          \"x\": 6.009125520265597,\n          \"y\": 2.705139350474586\n        },\n        {\n          \"x\": 36.0982164424424,\n          \"y\": 2.705139350474586\n        },\n        {\n          \"x\": 66.81896669097237,\n          \"y\": 2.705139350474586\n        },\n        {\n          \"x\": 81.86351733614008,\n          \"y\": 2.705139350474586\n        },\n        {\n          \"x\": 21.053670981354,\n          \"y\": 2.705139350474586\n        },\n        {\n          \"x\": 51.31091788377569,\n          \"y\": 2.378772674719472\n        }\n      ]\n    },\n    \"numberOfPins\": 6,\n    \"instantiation\": {\n      \"kind\": \"singleton\"\n    },\n    \"pinDefinitions\": [\n      {\n        \"target\": \"ACCELEROMETER_INT\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"SDA\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"threeVolt\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"ground\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"SCL\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"threeVolt\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      }\n    ],\n    \"assembly\": [\n      {\n        \"pinIndices\": [\n          0,\n          1,\n          2,\n          3,\n          4,\n          5\n        ]\n      }\n    ]\n  }\n}","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace input {\n\n    /**\n     * Do something when a gesture happens (like shaking the board).\n     * @param gesture the type of gesture to track, eg: Gesture.Shake\n     * @param body code to run when gesture is raised\n     */\n    //% help=input/on-gesture\n    //% blockId=device_gesture_event block=\"on |%NAME\"\n    //% parts=\"accelerometer\"\n    //% gesture.fieldEditor=\"gridpicker\"\n    //% gesture.fieldOptions.width=220\n    //% gesture.fieldOptions.columns=3\n    //% weight=92 blockGap=12 shim=input::onGesture\n    function onGesture(gesture: Gesture, body: () => void): void;\n\n    /**\n     * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\n     * x=0, y=0 and z=-1023)\n     * @param dimension TODO\n     */\n    //% help=input/acceleration\n    //% blockId=device_acceleration block=\"acceleration (mg)|%NAME\"\n    //% parts=\"accelerometer\"\n    //% dimension.fieldEditor=\"gridpicker\"\n    //% dimension.fieldOptions.width=180\n    //% dimension.fieldOptions.columns=2\n    //% weight=42 blockGap=8 shim=input::acceleration\n    function acceleration(dimension: Dimension): int32;\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\n    //% blockId=device_get_rotation block=\"rotation (°)|%NAME\"\n    //% parts=\"accelerometer\"\n    //% group=\"More\" weight=38 shim=input::rotation\n    function rotation(kind: Rotation): int32;\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    //% group=\"More\" weight=15 blockGap=8 shim=input::setAccelerometerRange\n    function setAccelerometerRange(range: AcceleratorRange): void;\n}\n\n// Auto-generated. Do not edit. Really.\n","test.ts":""},"azureiot":{"README.md":"# Azure IoT support - beta\n\nAzure MQTT communication layer. \nA port of https://github.com/rovale/micro-mqtt for MakeCode.\n\n## Settings\n\nThe connection string should be stored in the \"azureiot\" secret in the settings.","azureiot.ts":"const enum AzureIotEvent {\n    Connected = 1,\n    Disconnected = 2,\n    Error = 3,\n    GotTwinResponse = 100,\n}\n\nnamespace azureiot {\n    export const SECRETS_KEY = \"azureiot\"\n\n    export let logPriority = ConsolePriority.Debug;\n\n    type SMap<T> = { [s: string]: T; }\n    export type Json = any;\n\n    let _mqttClient: mqtt.Client;\n    let _messageBusId: number;\n    let _receiveHandler: (msg: Json, sysProps: SMap<string>) => void;\n    let _methodHandlers: SMap<(msg: Json) => Json>;\n    let twinRespHandlers: SMap<(status: number, body: any) => void>\n\n    function log(msg: string) {\n        console.add(logPriority, \"azureiot: \" + msg);\n    }\n\n    export function mqttClient(skipCreate?: boolean): mqtt.Client {\n        if (!_mqttClient && !skipCreate) {\n            log(\"creating mqtt client\")\n            _mqttClient = createMQTTClient();\n        }\n        return _mqttClient;\n    }\n\n    function generateSasToken(resourceUri: string, signingKey: string, expiresEpoch: number) {\n        const key = Buffer.fromBase64(signingKey)\n        resourceUri = net.urlencode(resourceUri)\n        const toSign = resourceUri + \"\\n\" + expiresEpoch\n        const sig = net.urlencode(crypto.sha256Hmac(key, Buffer.fromUTF8(toSign)).toBase64())\n        const token = `sr=${resourceUri}&se=${expiresEpoch}&sig=${sig}`\n        return token\n    }\n\n    export function hubName() {\n        return connectionStringPart(\"HostName\")\n    }\n\n    export function hubDeviceId() {\n        return connectionStringPart(\"DeviceId\")\n    }\n\n    function messageBusId() {\n        if (!_messageBusId)\n            _messageBusId = control.allocateEventSource();\n        return _messageBusId\n    }\n\n    function createMQTTClient() {\n        messageBusId()\n        const iotHubHostName = hubName()\n        const deviceId = hubDeviceId()\n        if (!iotHubHostName || !deviceId)\n            throw \"invalid connection string\"\n\n        const connStringParts = parseConnectionString();\n        let sasToken = connStringParts[\"SharedAccessSignature\"];\n        if (!sasToken)\n            // token valid until year 2255; in future we may try something more short-lived\n            sasToken = generateSasToken(`${iotHubHostName}/devices/${deviceId}`, connStringParts[\"SharedAccessKey\"], 9000000000)\n\n        const opts: mqtt.IConnectionOptions = {\n            host: iotHubHostName,\n            /* port: 8883, overriden based on platform */\n            username: `${iotHubHostName}/${deviceId}/?api-version=2018-06-30`,\n            password: \"SharedAccessSignature \" + sasToken,\n            clientId: deviceId\n        }\n        const c = new mqtt.Client(opts);\n        const evid = messageBusId()\n        c.on('connected', () => {\n            log(\"connected\")\n            control.raiseEvent(evid, AzureIotEvent.Connected)\n        });\n        c.on('disconnected', () => {\n            log(\"disconnected\")\n            control.raiseEvent(evid, AzureIotEvent.Disconnected)\n        });\n        c.on('error', (msg) => {\n            log(\"error: \" + msg)\n            control.raiseEvent(evid, AzureIotEvent.Error)\n        });\n        c.on('receive', (packet: mqtt.IMessage) => {\n            log(\"unhandled msg: \" + packet.topic + \" / \" + packet.content.toString())\n        });\n        c.connect();\n        return c;\n    }\n\n    function splitPair(kv: string): string[] {\n        const i = kv.indexOf('=');\n        if (i < 0)\n            return [kv, \"\"];\n        else\n            return [kv.slice(0, i), kv.slice(i + 1)];\n    }\n\n    function parsePropertyBag(msg: string, separator?: string): SMap<string> {\n        const r: SMap<string> = {};\n        if (msg && typeof msg === \"string\")\n            msg.split(separator || \"&\")\n                .map(kv => splitPair(kv))\n                .filter(parts => !!parts[1].length)\n                .forEach(parts => r[net.urldecode(parts[0])] = net.urldecode(parts[1]));\n        return r;\n    }\n\n    function parseConnectionString() {\n        try {\n            const connString = settings.programSecrets.readSecret(SECRETS_KEY);\n            const connStringParts = parsePropertyBag(connString, \";\");\n            return connStringParts\n        } catch {\n            console.debug(`clearing invalid azure iot connection string`)\n            settings.programSecrets.setSecret(SECRETS_KEY, \"\")\n            return {}\n        }\n    }\n\n    function connectionStringPart(name: string) {\n        const connStringParts = parseConnectionString()\n        const value = connStringParts[name];\n        return value || \"\"\n    }\n\n    function encodeQuery(props: SMap<string>): string {\n        const keys = Object.keys(props)\n        if (keys.length == 0)\n            return \"\"\n        return \"?\" + keys\n            .map(k => `${net.urlencode(k)}=${net.urlencode(props[k])}`)\n            .join('&');\n    }\n\n    export function setConnectionString(connectionString: string) {\n        disconnect()\n        settings.programSecrets.setSecret(SECRETS_KEY, connectionString)\n        parseConnectionString()\n    }\n\n    /**\n     * Disconnects the hub if any\n     */\n    export function disconnect() {\n        const c = mqttClient(true)\n        if (c) {\n            try {\n                c.disconnect()\n            }\n            catch {\n                // just ignore errors disconnecting\n            }\n        }\n    }\n\n    /**\n     * Connects to the IoT hub\n     */\n    export function connect() {\n        const c = mqttClient();\n        if (!c.connected) {\n            c.connect() // start connect if not started yet\n            // busy wait for connection\n            const start = control.millis()\n            const timeout = 30000\n            while (!c.connected && control.millis() - start < timeout) {\n                pause(1000)\n            }\n            if (!c.connected)\n                throw \"connection failed\"\n        }\n    }\n\n    /**\n     * Registers code when the MQTT client gets connected or disconnected\n     * @param event \n     * @param handler \n     */\n    export function onEvent(event: AzureIotEvent, handler: () => void) {\n        const evid = messageBusId()\n        control.onEvent(evid, event, handler);\n        try {\n            const c = mqttClient(true);\n            if (c && c.connected) // raise connected event by default\n                control.raiseEvent(evid, AzureIotEvent.Connected);\n        } catch { }\n    }\n\n    /**\n     * Indicates if the MQTT client is connected\n     */\n    //%\n    export function isConnected(): boolean {\n        try {\n            const c = mqttClient(true);\n            return !!c && !!c.connected;\n        }\n        catch {\n            return false\n        }\n    }\n\n    /**\n     * Send a message via mqtt\n     * @param msg \n     */\n    //%\n    export function publishMessageJSON(msg: Json, sysProps?: SMap<string>) {\n        const c = mqttClient();\n        let topic = `devices/${c.opt.clientId}/messages/events/`;\n        if (sysProps)\n            topic += encodeQuery(sysProps);\n        const m = JSON.stringify(msg)\n        msg = null\n        // qos, retained are not supported\n        c.publish(topic, m);\n    }\n\n    /**\n     * Send a message via mqtt\n     * @param msg \n     */\n    //%\n    export function publishMessageBuffer(msg: Buffer, sysProps?: SMap<string>) {\n        const c = mqttClient();\n        let topic = `devices/${c.opt.clientId}/messages/events/`;\n        if (sysProps)\n            topic += encodeQuery(sysProps);\n        // qos, retained are not supported\n        c.publish(topic, msg);\n    }\n\n    /**\n     * Send a message via mqtt\n     * @param msg \n     */\n    //%\n    export function publishMessageHex(msg: Buffer, len?: number, sysProps?: SMap<string>) {\n        const c = mqttClient();\n        let topic = `devices/${c.opt.clientId}/messages/events/`;\n        if (sysProps)\n            topic += encodeQuery(sysProps);\n        if (len == null)\n            len = msg.length\n        if (len > msg.length) {\n            log(`len too long: ${len}/${msg.length}`)\n            len = msg.length\n        }\n        // qos, retained are not supported\n        if (c.startPublish(topic, len * 2)) {\n            const chunk = 128\n            for (let ptr = 0; ptr < len; ptr += chunk)\n                c.continuePublish(Buffer.fromUTF8(msg.slice(ptr, Math.min(chunk, len - ptr)).toHex()))\n            c.finishPublish()\n        }\n    }\n\n    /**\n     * Registers code to run when a message is received\n     * @param handler \n     */\n    //%\n    export function onMessageReceived(handler: (body: Json, sysProps: SMap<string>) => void) {\n        const c = mqttClient();\n        if (!_receiveHandler) {\n            c.subscribe(`devices/${c.opt.clientId}/messages/devicebound/#`, handleDeviceBound);\n\n            /*\n            c.subscribe('$iothub/twin/PATCH/properties/desired/#')\n            */\n        }\n        _receiveHandler = handler;\n    }\n\n    function parseTopicArgs(topic: string) {\n        const qidx = topic.indexOf(\"?\")\n        if (qidx >= 0)\n            return parsePropertyBag(topic.slice(qidx + 1))\n        return {}\n    }\n\n    function handleDeviceBound(packet: mqtt.IMessage) {\n        if (!_receiveHandler) return; // nobody's listening\n        // TODO this needs some testing\n        const sysProps = parseTopicArgs(packet.topic)\n        _receiveHandler(JSON.parse(packet.content.toString()), sysProps);\n    }\n\n    function handleMethod(msg: mqtt.IMessage) {\n        const props = parseTopicArgs(msg.topic)\n        const qidx = msg.topic.indexOf(\"/?\")\n        const methodName = msg.topic.slice(21, qidx)\n        log(\"method: '\" + methodName + \"'; \" + JSON.stringify(props))\n        let status = 200\n        let resp: any = {}\n        if (!_methodHandlers[methodName]) {\n            log(\"method not found: '\" + methodName + \"'\")\n            status = 404\n        } else {\n            const h = _methodHandlers[methodName]\n            const resp2 = h(JSON.parse(msg.content.toString()))\n            if (resp2)\n                resp = resp2\n            if (resp[\"_status\"] != null) {\n                status = resp[\"_status\"]\n                resp[\"_status\"] = undefined\n            }\n            log(\"method: '\" + methodName + \"' status=\" + status)\n        }\n\n        const c = mqttClient();\n        c.publish('$iothub/methods/res/' + status + \"/?$rid=\" + props[\"$rid\"], JSON.stringify(resp))\n    }\n\n    // $iothub/twin/res/{status}/?$rid={request id}\n    function twinResponse(msg: mqtt.IMessage) {\n        const args = parseTopicArgs(msg.topic)\n        const h = twinRespHandlers[args[\"$rid\"]]\n        const status = parseInt(msg.topic.slice(17))\n        // log(`twin resp: ${status} ${msg.content.toHex()} ${msg.content.toString()}`)\n        if (h) {\n            delete twinRespHandlers[args[\"$rid\"]]\n            h(status, JSON.parse(msg.content.toString() || \"{}\"))\n        }\n    }\n\n    export class ValueAwaiter {\n        private evid: number\n        private value: any\n        constructor() {\n            this.evid = control.allocateNotifyEvent()\n        }\n        setValue(v: any) {\n            this.value = v\n            control.raiseEvent(DAL.DEVICE_ID_NOTIFY, this.evid)\n            this.evid = -1\n        }\n        wait() {\n            if (this.evid < 0) return this.value\n            control.waitForEvent(DAL.DEVICE_ID_NOTIFY, this.evid)\n            return this.value\n        }\n    }\n\n    function twinReq(path: string, msg?: string): Json {\n        const c = mqttClient();\n        if (!twinRespHandlers) {\n            twinRespHandlers = {}\n            c.subscribe(\"$iothub/twin/res/#\", twinResponse)\n        }\n        const rid = Math.randomRange(100000000, 900000000) + \"\"\n        const va = new ValueAwaiter()\n        twinRespHandlers[rid] = (status, body) => {\n            if (status == 204 || status == 200) {\n                va.setValue(body)\n            } else {\n                log(`twin error -> ${status} ${JSON.stringify(body)}`)\n                va.setValue(null)\n            }\n        }\n        c.publish(`$iothub/twin/${path}/?$rid=${rid}`, msg)\n        return va.wait()\n    }\n\n    export function getTwin(): Json {\n        return twinReq(\"GET\")\n    }\n\n    export function patchTwin(patch: Json) {\n        const p = JSON.stringify(patch)\n        if (p == \"{}\")\n            log(\"skipping empty twin patch\")\n        else {\n            log(`twin patch: ${JSON.stringify(patch)}`)\n            twinReq(\"PATCH/properties/reported\", p)\n        }\n    }\n\n    export function computePatch(curr: Json, target: Json) {\n        const patch: Json = {}\n        for (const k of Object.keys(curr)) {\n            const vt = target[k]\n            if (k[0] == \"$\")\n                continue\n            if (vt === undefined) {\n                patch[k] = null\n            } else {\n                const vc = curr[k]\n                if (typeof vt == \"object\")\n                    if (typeof vc == \"object\") {\n                        const p0 = computePatch(vc, vt)\n                        if (Object.keys(p0).length > 0)\n                            patch[k] = p0\n                    } else {\n                        patch[k] = vt\n                    }\n                else if (vc != vt)\n                    patch[k] = vt\n            }\n        }\n        for (const k of Object.keys(target)) {\n            if (curr[k] === undefined && k[0] != \"$\")\n                patch[k] = target[k]\n        }\n        return patch\n    }\n\n    export function applyPatch(trg: Json, patch: Json) {\n        for (const k of Object.keys(patch)) {\n            const v = patch[k]\n            if (v === null) {\n                delete trg[k]\n            } else if (typeof v == \"object\") {\n                if (!trg[k]) trg[k] = {}\n                applyPatch(trg[k], v)\n            } else {\n                trg[k] = v\n            }\n        }\n    }\n\n    export function onTwinUpdate(handler: (twin: Json, patch: Json) => void) {\n        const c = mqttClient()\n        let currTwin: Json = null\n        let lastVersion: number\n        c.subscribe(\"$iothub/twin/PATCH/properties/desired/#\", msg => {\n            if (!currTwin)\n                return\n            const sysProps = parseTopicArgs(msg.topic)\n            const ver = parseInt(sysProps[\"$version\"])\n            if (ver <= lastVersion) {\n                log(`skipping twin update: ${ver}`)\n                return\n            }\n            const update = JSON.parse(msg.content.toString())\n            applyPatch(currTwin[\"desired\"], update)\n            handler(currTwin, update)\n        })\n        currTwin = getTwin()\n        lastVersion = currTwin[\"desired\"][\"$version\"]\n        handler(currTwin, currTwin[\"desired\"])\n    }\n\n    export function onMethod(methodName: string, handler: (msg: Json) => Json) {\n        const c = mqttClient();\n        if (!_methodHandlers) {\n            if (!c.connected)\n                throw \"azure iot hub not connected\"\n            _methodHandlers = {}\n            c.subscribe('$iothub/methods/POST/#', handleMethod)\n        }\n        _methodHandlers[methodName] = handler\n    }\n}\n","pxt.json":"{\n    \"name\": \"azureiot\",\n    \"description\": \"Azure IoT - beta\",\n    \"dependencies\": {\n        \"mqtt\": \"*\",\n        \"settings\": \"*\"\n    },\n    \"files\": [\n        \"azureiot.ts\",\n        \"README.md\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"testDependencies\": {\n        \"esp32\": \"file:../esp32\"\n    },\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true\n}\n","test.ts":"function test() {\n\n    const log = console.log;\n    const esp = net.instance().controller();\n\n    if (!esp.connect()) {\n        log(\"can't connect\")\n        return\n    }\n\n    log(\"ping: \" + esp.ping(\"bing.com\"))\n\n    azureiot.connect()\n    log(\"mqtt connected\")\n\n    azureiot.onMessageReceived((msg) => {\n        log(\"MSG:\" + JSON.stringify(msg))\n    })\n\n    azureiot.onMethod(\"echo\", msg => {\n        log(\"ECHO \" + msg.displayedValue)\n        msg.type = \"echo\"\n        return {}\n    })\n}\n\ntest();"},"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\n    }\n\n    /**\n     * Concatenates all buffers in the list\n     */\n    export function concat(buffers: Buffer[]) {\n        let len = 0\n        for (let b of buffers)\n            len += b.length\n        const r = Buffer.create(len)\n        len = 0\n        for (let b of buffers) {\n            r.write(len, b)\n            len += b.length\n        }\n        return r\n    }\n\n    // Python-like packing, see https://docs.python.org/3/library/struct.html\n\n    export function packedSize(format: string) {\n        return __packUnpackCore(format, null, null, true)\n    }\n\n    export function pack(format: string, nums: number[]) {\n        let buf = Buffer.create(packedSize(format))\n        __packUnpackCore(format, nums, buf, true)\n        return buf\n    }\n\n    function getFormat(pychar: string, isBig: boolean) {\n        switch (pychar) {\n            case 'B':\n                return NumberFormat.UInt8LE\n            case 'b':\n                return NumberFormat.Int8LE\n            case 'H':\n                return isBig ? NumberFormat.UInt16BE : NumberFormat.UInt16LE\n            case 'h':\n                return isBig ? NumberFormat.Int16BE : NumberFormat.Int16LE\n            case 'I':\n            case 'L':\n                return isBig ? NumberFormat.UInt32BE : NumberFormat.UInt32LE\n            case 'i':\n            case 'l':\n                return isBig ? NumberFormat.Int32BE : NumberFormat.Int32LE\n            case 'f':\n                return isBig ? NumberFormat.Float32BE : NumberFormat.Float32LE\n            case 'd':\n                return isBig ? NumberFormat.Float64BE : NumberFormat.Float64LE\n            default:\n                return null as NumberFormat\n        }\n    }\n\n    function isDigit(ch: string) {\n        const code = ch.charCodeAt(0)\n        return 0x30 <= code && code <= 0x39\n    }\n\n    export function __packUnpackCore(format: string, nums: number[], buf: Buffer, isPack: boolean, off = 0) {\n        let isBig = false\n        let idx = 0\n        for (let i = 0; i < format.length; ++i) {\n            switch (format[i]) {\n                case ' ':\n                case '<':\n                case '=':\n                    isBig = false\n                    break\n                case '>':\n                case '!':\n                    isBig = true\n                    break\n                default:\n                    const i0 = i\n                    while (isDigit(format[i])) i++\n                    let reps = 1\n                    if (i0 != i)\n                        reps = parseInt(format.slice(i0, i))\n                    if (format[i] == 'x')\n                        off += reps\n                    else\n                        while (reps--) {\n                            let fmt = getFormat(format[i], isBig)\n                            if (fmt === null) {\n                                control.fail(\"Unsupported format character: \" + format[i])\n                            } else {\n                                if (buf) {\n                                    if (isPack)\n                                        buf.setNumber(fmt, off, nums[idx++])\n                                    else\n                                        nums.push(buf.getNumber(fmt, off))\n                                }\n\n                                off += sizeOfNumberFormat(fmt)\n                            }\n                        }\n                    break\n            }\n        }\n        return off\n    }\n\n    /**\n     * Get the size in bytes of specified number format.\n     */\n    export function sizeOfNumberFormat(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            case NumberFormat.UInt32BE:\n            case NumberFormat.UInt32LE:\n            case NumberFormat.Float32BE:\n            case NumberFormat.Float32LE:\n                return 4;\n            case NumberFormat.Float64BE:\n            case NumberFormat.Float64LE:\n                return 8;\n        }\n        return 0;\n    }\n}\n","configkeys.h":"#ifndef __PXT_CONFIGKEYS_H\n#define __PXT_CONFIGKEYS_H\n\n// used by pins.cpp to mask off the pin name from any config\n// lower 16 pins of value are the pin name\n#define CFG_PIN_NAME_MSK 0x0000ffff\n// upper 16 bits of value is any configuration of the pin.\n#define CFG_PIN_CONFIG_MSK 0xffff0000\n\n// begin optional pin configurations\n#define CFG_PIN_CONFIG_ACTIVE_LO 0x10000\n\n\n#define CFG_MAGIC0 0x1e9e10f1\n#define CFG_MAGIC1 0x20227a79\n\n// these define keys for getConfig() function\n#define CFG_PIN_ACCELEROMETER_INT 1\n#define CFG_PIN_ACCELEROMETER_SCL 2\n#define CFG_PIN_ACCELEROMETER_SDA 3\n#define CFG_PIN_BTN_A 4\n#define CFG_PIN_BTN_B 5\n#define CFG_PIN_BTN_SLIDE 6\n#define CFG_PIN_DOTSTAR_CLOCK 7\n#define CFG_PIN_DOTSTAR_DATA 8\n#define CFG_PIN_FLASH_CS 9\n#define CFG_PIN_FLASH_MISO 10\n#define CFG_PIN_FLASH_MOSI 11\n#define CFG_PIN_FLASH_SCK 12\n#define CFG_PIN_LED 13\n#define CFG_PIN_LIGHT 14\n#define CFG_PIN_MICROPHONE 15\n#define CFG_PIN_MIC_CLOCK 16\n#define CFG_PIN_MIC_DATA 17\n#define CFG_PIN_MISO 18\n#define CFG_PIN_MOSI 19\n// the preferred pin to drive an external neopixel strip\n#define CFG_PIN_NEOPIXEL 20\n#define CFG_PIN_RX 21\n#define CFG_PIN_RXLED 22\n#define CFG_PIN_SCK 23\n#define CFG_PIN_SCL 24\n#define CFG_PIN_SDA 25\n#define CFG_PIN_SPEAKER_AMP 26\n#define CFG_PIN_TEMPERATURE 27\n#define CFG_PIN_TX 28\n#define CFG_PIN_TXLED 29\n#define CFG_PIN_IR_OUT 30\n#define CFG_PIN_IR_IN 31\n#define CFG_PIN_DISPLAY_SCK 32\n#define CFG_PIN_DISPLAY_MISO 33\n#define CFG_PIN_DISPLAY_MOSI 34\n#define CFG_PIN_DISPLAY_CS 35\n#define CFG_PIN_DISPLAY_DC 36\n#define CFG_DISPLAY_WIDTH 37\n#define CFG_DISPLAY_HEIGHT 38\n#define CFG_DISPLAY_CFG0 39\n#define CFG_DISPLAY_CFG1 40\n#define CFG_DISPLAY_CFG2 41\n#define CFG_DISPLAY_CFG3 42\n#define CFG_PIN_DISPLAY_RST 43\n#define CFG_PIN_DISPLAY_BL 44\n#define CFG_PIN_SERVO_1 45\n#define CFG_PIN_SERVO_2 46\n#define CFG_PIN_BTN_LEFT 47\n#define CFG_PIN_BTN_RIGHT 48\n#define CFG_PIN_BTN_UP 49\n#define CFG_PIN_BTN_DOWN 50\n#define CFG_PIN_BTN_MENU 51\n#define CFG_PIN_LED_R 52\n#define CFG_PIN_LED_G 53\n#define CFG_PIN_LED_B 54\n#define CFG_PIN_LED1 55\n#define CFG_PIN_LED2 56\n#define CFG_PIN_LED3 57\n#define CFG_PIN_LED4 58\n#define CFG_SPEAKER_VOLUME 59\n\n#define CFG_PIN_JACK_TX 60\n#define CFG_PIN_JACK_SENSE 61\n#define CFG_PIN_JACK_HPEN 62\n#define CFG_PIN_JACK_BZEN 63\n#define CFG_PIN_JACK_PWREN 64\n#define CFG_PIN_JACK_SND 65\n#define CFG_PIN_JACK_BUSLED 66\n#define CFG_PIN_JACK_COMMLED 67\n\n#define CFG_PIN_BTN_SOFT_RESET 69\n#define CFG_ACCELEROMETER_TYPE 70\n#define CFG_PIN_BTNMX_LATCH 71\n#define CFG_PIN_BTNMX_CLOCK 72\n#define CFG_PIN_BTNMX_DATA 73\n#define CFG_PIN_BTN_MENU2 74\n#define CFG_PIN_BATTSENSE 75\n#define CFG_PIN_VIBRATION 76\n#define CFG_PIN_PWREN 77\n#define CFG_DISPLAY_TYPE 78\n\n#define CFG_PIN_ROTARY_ENCODER_A 79\n#define CFG_PIN_ROTARY_ENCODER_B 80\n\n#define CFG_ACCELEROMETER_SPACE 81\n\n#define CFG_PIN_WIFI_MOSI 82\n#define CFG_PIN_WIFI_MISO 83\n#define CFG_PIN_WIFI_SCK 84\n#define CFG_PIN_WIFI_TX 85\n#define CFG_PIN_WIFI_RX 86\n#define CFG_PIN_WIFI_CS 87\n#define CFG_PIN_WIFI_BUSY 88\n#define CFG_PIN_WIFI_RESET 89\n#define CFG_PIN_WIFI_GPIO0 90\n#define CFG_PIN_WIFI_AT_TX 91\n#define CFG_PIN_WIFI_AT_RX 92\n\n#define CFG_PIN_USB_POWER 93\n#define CFG_DISPLAY_DELAY 94\n\n// default I2C address\n#define ACCELEROMETER_TYPE_LIS3DH 0x32\n#define ACCELEROMETER_TYPE_LIS3DH_ALT 0x30\n#define ACCELEROMETER_TYPE_MMA8453 0x38\n#define ACCELEROMETER_TYPE_FXOS8700 0x3C\n#define ACCELEROMETER_TYPE_MMA8653 0x3A\n#define ACCELEROMETER_TYPE_MSA300 0x4C\n#define ACCELEROMETER_TYPE_MPU6050 0x68\n\n#define DISPLAY_TYPE_ST7735 7735\n#define DISPLAY_TYPE_ILI9341 9341\n#define DISPLAY_TYPE_SMART 4242\n\n#define CFG_PIN_A0 100\n#define CFG_PIN_A1 101\n#define CFG_PIN_A2 102\n#define CFG_PIN_A3 103\n#define CFG_PIN_A4 104\n#define CFG_PIN_A5 105\n#define CFG_PIN_A6 106\n#define CFG_PIN_A7 107\n#define CFG_PIN_A8 108\n#define CFG_PIN_A9 109\n#define CFG_PIN_A10 110\n#define CFG_PIN_A11 111\n#define CFG_PIN_A12 112\n#define CFG_PIN_A13 113\n#define CFG_PIN_A14 114\n#define CFG_PIN_A15 115\n#define CFG_PIN_A16 116\n#define CFG_PIN_A17 117\n#define CFG_PIN_A18 118\n#define CFG_PIN_A19 119\n#define CFG_PIN_A20 120\n#define CFG_PIN_A21 121\n#define CFG_PIN_A22 122\n#define CFG_PIN_A23 123\n#define CFG_PIN_A24 124\n#define CFG_PIN_A25 125\n#define CFG_PIN_A26 126\n#define CFG_PIN_A27 127\n#define CFG_PIN_A28 128\n#define CFG_PIN_A29 129\n#define CFG_PIN_A30 130\n#define CFG_PIN_A31 131\n\n#define CFG_PIN_D0 150\n#define CFG_PIN_D1 151\n#define CFG_PIN_D2 152\n#define CFG_PIN_D3 153\n#define CFG_PIN_D4 154\n#define CFG_PIN_D5 155\n#define CFG_PIN_D6 156\n#define CFG_PIN_D7 157\n#define CFG_PIN_D8 158\n#define CFG_PIN_D9 159\n#define CFG_PIN_D10 160\n#define CFG_PIN_D11 161\n#define CFG_PIN_D12 162\n#define CFG_PIN_D13 163\n#define CFG_PIN_D14 164\n#define CFG_PIN_D15 165\n#define CFG_PIN_D16 166\n#define CFG_PIN_D17 167\n#define CFG_PIN_D18 168\n#define CFG_PIN_D19 169\n#define CFG_PIN_D20 170\n#define CFG_PIN_D21 171\n#define CFG_PIN_D22 172\n#define CFG_PIN_D23 173\n#define CFG_PIN_D24 174\n#define CFG_PIN_D25 175\n#define CFG_PIN_D26 176\n#define CFG_PIN_D27 177\n#define CFG_PIN_D28 178\n#define CFG_PIN_D29 179\n#define CFG_PIN_D30 180\n#define CFG_PIN_D31 181\n\n#define CFG_NUM_NEOPIXELS 200\n#define CFG_NUM_DOTSTARS 201\n#define CFG_DEFAULT_BUTTON_MODE 202\n#define CFG_SWD_ENABLED 203\n#define CFG_FLASH_BYTES 204\n#define CFG_RAM_BYTES 205\n#define CFG_SYSTEM_HEAP_BYTES 206\n#define CFG_LOW_MEM_SIMULATION_KB 207\n#define CFG_BOOTLOADER_BOARD_ID 208\n#define CFG_UF2_FAMILY 209\n#define CFG_PINS_PORT_SIZE 210\n#define CFG_BOOTLOADER_PROTECTION 211\n#define CFG_POWER_DEEPSLEEP_TIMEOUT 212\n#define CFG_ANALOG_BUTTON_THRESHOLD 213\n#define CFG_CPU_MHZ 214\n#define CFG_CONTROLLER_LIGHT_MAX_BRIGHTNESS 215\n#define CFG_ANALOG_JOYSTICK_MIN 216\n#define CFG_ANALOG_JOYSTICK_MAX 217\n#define CFG_TIMERS_TO_USE 218\n// configs to specify the onboard (built-in) dotstar or neopixel strips\n// some boards have a combination of dotstar, neopixel strips like neotrellis\n#define CFG_PIN_ONBOARD_DOTSTAR_CLOCK 219\n#define CFG_PIN_ONBOARD_DOTSTAR_DATA 220\n#define CFG_NUM_ONBOARD_DOTSTARS 221\n#define CFG_PIN_ONBOARD_NEOPIXEL 222\n#define CFG_NUM_ONBOARD_NEOPIXELS 223\n\n#define CFG_MATRIX_KEYPAD_MESSAGE_ID 239\n#define CFG_NUM_MATRIX_KEYPAD_ROWS 240\n#define CFG_PIN_MATRIX_KEYPAD_ROW0 241\n#define CFG_PIN_MATRIX_KEYPAD_ROW1 242\n#define CFG_PIN_MATRIX_KEYPAD_ROW2 243\n#define CFG_PIN_MATRIX_KEYPAD_ROW3 244\n#define CFG_PIN_MATRIX_KEYPAD_ROW4 245\n#define CFG_PIN_MATRIX_KEYPAD_ROW5 246\n#define CFG_PIN_MATRIX_KEYPAD_ROW6 247\n#define CFG_PIN_MATRIX_KEYPAD_ROW7 248\n#define CFG_NUM_MATRIX_KEYPAD_COLS 250\n#define CFG_PIN_MATRIX_KEYPAD_COL0 251\n#define CFG_PIN_MATRIX_KEYPAD_COL1 252\n#define CFG_PIN_MATRIX_KEYPAD_COL2 253\n#define CFG_PIN_MATRIX_KEYPAD_COL3 254\n#define CFG_PIN_MATRIX_KEYPAD_COL4 255\n#define CFG_PIN_MATRIX_KEYPAD_COL5 256\n#define CFG_PIN_MATRIX_KEYPAD_COL6 257\n#define CFG_PIN_MATRIX_KEYPAD_COL7 258\n\n#define CFG_PIN_B0 300\n#define CFG_PIN_B1 301\n#define CFG_PIN_B2 302\n#define CFG_PIN_B3 303\n#define CFG_PIN_B4 304\n#define CFG_PIN_B5 305\n#define CFG_PIN_B6 306\n#define CFG_PIN_B7 307\n#define CFG_PIN_B8 308\n#define CFG_PIN_B9 309\n#define CFG_PIN_B10 310\n#define CFG_PIN_B11 311\n#define CFG_PIN_B12 312\n#define CFG_PIN_B13 313\n#define CFG_PIN_B14 314\n#define CFG_PIN_B15 315\n#define CFG_PIN_B16 316\n#define CFG_PIN_B17 317\n#define CFG_PIN_B18 318\n#define CFG_PIN_B19 319\n#define CFG_PIN_B20 320\n#define CFG_PIN_B21 321\n#define CFG_PIN_B22 322\n#define CFG_PIN_B23 323\n#define CFG_PIN_B24 324\n#define CFG_PIN_B25 325\n#define CFG_PIN_B26 326\n#define CFG_PIN_B27 327\n#define CFG_PIN_B28 328\n#define CFG_PIN_B29 329\n#define CFG_PIN_B30 330\n#define CFG_PIN_B31 331\n\n#define CFG_PIN_C0 350\n#define CFG_PIN_C1 351\n#define CFG_PIN_C2 352\n#define CFG_PIN_C3 353\n#define CFG_PIN_C4 354\n#define CFG_PIN_C5 355\n#define CFG_PIN_C6 356\n#define CFG_PIN_C7 357\n#define CFG_PIN_C8 358\n#define CFG_PIN_C9 359\n#define CFG_PIN_C10 360\n#define CFG_PIN_C11 361\n#define CFG_PIN_C12 362\n#define CFG_PIN_C13 363\n#define CFG_PIN_C14 364\n#define CFG_PIN_C15 365\n#define CFG_PIN_C16 366\n#define CFG_PIN_C17 367\n#define CFG_PIN_C18 368\n#define CFG_PIN_C19 369\n#define CFG_PIN_C20 370\n#define CFG_PIN_C21 371\n#define CFG_PIN_C22 372\n#define CFG_PIN_C23 373\n#define CFG_PIN_C24 374\n#define CFG_PIN_C25 375\n#define CFG_PIN_C26 376\n#define CFG_PIN_C27 377\n#define CFG_PIN_C28 378\n#define CFG_PIN_C29 379\n#define CFG_PIN_C30 380\n#define CFG_PIN_C31 381\n\n#define CFG_PIN_P0 400\n#define CFG_PIN_P1 401\n#define CFG_PIN_P2 402\n#define CFG_PIN_P3 403\n#define CFG_PIN_P4 404\n#define CFG_PIN_P5 405\n#define CFG_PIN_P6 406\n#define CFG_PIN_P7 407\n#define CFG_PIN_P8 408\n#define CFG_PIN_P9 409\n#define CFG_PIN_P10 410\n#define CFG_PIN_P11 411\n#define CFG_PIN_P12 412\n#define CFG_PIN_P13 413\n#define CFG_PIN_P14 414\n#define CFG_PIN_P15 415\n#define CFG_PIN_P16 416\n#define CFG_PIN_P17 417\n#define CFG_PIN_P18 418\n#define CFG_PIN_P19 419\n#define CFG_PIN_P20 420\n#define CFG_PIN_P21 421\n#define CFG_PIN_P22 422\n#define CFG_PIN_P23 423\n#define CFG_PIN_P24 424\n#define CFG_PIN_P25 425\n#define CFG_PIN_P26 426\n#define CFG_PIN_P27 427\n#define CFG_PIN_P28 428\n#define CFG_PIN_P29 429\n#define CFG_PIN_P30 430\n#define CFG_PIN_P31 431\n#define CFG_PIN_P32 432\n#define CFG_PIN_P33 433\n#define CFG_PIN_P34 434\n#define CFG_PIN_P35 435\n#define CFG_PIN_P36 436\n#define CFG_PIN_P37 437\n#define CFG_PIN_P38 438\n#define CFG_PIN_P39 439\n#define CFG_PIN_P40 440\n#define CFG_PIN_P41 441\n#define CFG_PIN_P42 442\n#define CFG_PIN_P43 443\n#define CFG_PIN_P44 444\n#define CFG_PIN_P45 445\n#define CFG_PIN_P46 446\n#define CFG_PIN_P47 447\n#define CFG_PIN_P48 448\n#define CFG_PIN_P49 449\n#define CFG_PIN_P50 450\n#define CFG_PIN_P51 451\n#define CFG_PIN_P52 452\n#define CFG_PIN_P53 453\n#define CFG_PIN_P54 454\n#define CFG_PIN_P55 455\n#define CFG_PIN_P56 456\n#define CFG_PIN_P57 457\n#define CFG_PIN_P58 458\n#define CFG_PIN_P59 459\n#define CFG_PIN_P60 460\n#define CFG_PIN_P61 461\n#define CFG_PIN_P62 462\n#define CFG_PIN_P63 463\n\n#define CFG_PIN_LORA_MISO 1001\n#define CFG_PIN_LORA_MOSI 1002\n#define CFG_PIN_LORA_SCK 1003\n#define CFG_PIN_LORA_CS 1004\n#define CFG_PIN_LORA_BOOT 1005\n#define CFG_PIN_LORA_RESET 1006\n#define CFG_PIN_IRRXLED 1007\n#define CFG_PIN_IRTXLED 1008\n#define CFG_PIN_LCD_RESET 1009\n#define CFG_PIN_LCD_ENABLE 1010\n#define CFG_PIN_LCD_DATALINE4 1011\n#define CFG_PIN_LCD_DATALINE5 1012\n#define CFG_PIN_LCD_DATALINE6 1013\n#define CFG_PIN_LCD_DATALINE7 1014\n#define CFG_NUM_LCD_COLUMNS 1015\n#define CFG_NUM_LCD_ROWS 1016\n\n//RoboHAT MM1 pinout\n#define CFG_PIN_RCC0 1017\n#define CFG_PIN_RCC1 1018\n#define CFG_PIN_RCC2 1019\n#define CFG_PIN_RCC3 1020\n#define CFG_PIN_RCC4 1021\n#define CFG_PIN_RCC5 1022\n#define CFG_PIN_RCC6 1023\n#define CFG_PIN_RCC7 1024\n#define CFG_PIN_SERVO0 1025\n#define CFG_PIN_SERVO1 1026\n#define CFG_PIN_SERVO2 1027\n#define CFG_PIN_SERVO3 1028\n#define CFG_PIN_SERVO4 1029\n#define CFG_PIN_SERVO5 1030\n#define CFG_PIN_SERVO6 1031\n#define CFG_PIN_SERVO7 1032\n#define CFG_PIN_SERVO8 1033\n#define CFG_PIN_PI_TX 1034\n#define CFG_PIN_PI_RX 1035\n#define CFG_PIN_GPS_SDA 1036\n#define CFG_PIN_GPS_SCL 1037\n#define CFG_PIN_GPS_TX 1038\n#define CFG_PIN_GPS_RX 1039\n#define CFG_PIN_GROVE0 1040\n#define CFG_PIN_GROVE1 1041\n#define CFG_PIN_SS 1042\n\n// Adafruit Grand Central M4\n#define CFG_PIN_D33 183\n#define CFG_PIN_D34 184\n#define CFG_PIN_D35 185\n#define CFG_PIN_D36 186\n#define CFG_PIN_D37 187\n#define CFG_PIN_D38 188\n#define CFG_PIN_D39 189\n#define CFG_PIN_D40 190\n#define CFG_PIN_D41 191\n#define CFG_PIN_D42 192\n#define CFG_PIN_D43 193\n#define CFG_PIN_D44 194\n#define CFG_PIN_D45 195\n#define CFG_PIN_D46 196\n#define CFG_PIN_D47 197\n#define CFG_PIN_D48 198\n#define CFG_PIN_D49 199\n#define CFG_PIN_D50 259\n#define CFG_PIN_D51 260\n#define CFG_PIN_D52 261\n#define CFG_PIN_D53 262\n\n#define CFG_PIN_TX1 263\n#define CFG_PIN_TX2 264\n#define CFG_PIN_TX3 265\n#define CFG_PIN_RX1 266\n#define CFG_PIN_RX2 267\n#define CFG_PIN_RX3 268\n#define CFG_PIN_SCL1 269\n#define CFG_PIN_SDA1 270\n#define CFG_PIN_PCC_D0 271\n#define CFG_PIN_PCC_D1 272\n#define CFG_PIN_PCC_D2 273\n#define CFG_PIN_PCC_D3 274\n#define CFG_PIN_PCC_D4 275\n#define CFG_PIN_PCC_D5 276\n#define CFG_PIN_PCC_D6 277\n#define CFG_PIN_PCC_D7 278\n#define CFG_PIN_PCC_D8 279\n#define CFG_PIN_PCC_D9 280\n#define CFG_PIN_PCC_D10 281\n#define CFG_PIN_PCC_D11 282\n#define CFG_PIN_PCC_D12 283\n#define CFG_PIN_PCC_D13 284\n#define CFG_PIN_CC_DEN1 285\n#define CFG_PIN_CC_DEN2 286\n#define CFG_PIN_CC_CLK 287\n#define CFG_PIN_XCC_CLK 288\n\n\n#define CFG_PIN_JDPWR_PRE_SENSE 1100\n#define CFG_PIN_JDPWR_GND_SENSE 1101\n#define CFG_PIN_JDPWR_PULSE 1102\n#define CFG_PIN_JDPWR_OVERLOAD_LED 1103\n#define CFG_PIN_JDPWR_ENABLE 1104\n#define CFG_PIN_JDPWR_FAULT 1105\n\n#define CFG_USER_CFG_0 2000\n#define CFG_USER_CFG_1 2001\n#define CFG_USER_CFG_2 2002\n#define CFG_USER_CFG_3 2003\n#define CFG_USER_CFG_4 2004\n#define CFG_USER_CFG_5 2005\n#define CFG_USER_CFG_6 2006\n#define CFG_USER_CFG_7 2007\n#define CFG_USER_CFG_8 2008\n#define CFG_USER_CFG_9 2009\n\n#define CFG_ARCADE_CFG_0 2100\n#define CFG_ARCADE_CFG_1 2101\n#define CFG_ARCADE_SCREEN_WIDTH 2102\n#define CFG_ARCADE_SCREEN_HEIGHT 2103\n\n#endif\n","console.ts":"/// <reference no-default-lib=\"true\"/>\n\nenum ConsolePriority {\n    Debug = 0,\n    Log = 1,\n    Warning = 2,\n    Error = 3,\n    Silent = 4\n}\n\n/**\n * Reading and writing data to the console output.\n */\n//% weight=12 color=#002050 icon=\"\\uf120\"\n//% advanced=true\nnamespace console {\n    type Listener = (priority: ConsolePriority, text: string) => void;\n\n    /**\n     * Minimum priority to send messages to listeners\n     */\n    export let minPriority = ConsolePriority.Log;\n\n    //% whenUsed\n    const listeners: Listener[] = [\n        function (priority: ConsolePriority, text: string) { control.__log(priority, text); }\n    ];\n\n    export function add(priority: ConsolePriority, message: any) {\n        if (priority < minPriority) return;\n        let text = inspect(message);\n        // add new line\n        text += \"\\n\";\n        // send to listeners\n        for (let i = 0; i < listeners.length; ++i)\n            listeners[i](priority, text);\n    }\n\n    export function debug(text: any) {\n        add(ConsolePriority.Debug, text);\n    }\n\n    export function warn(text: any) {\n        add(ConsolePriority.Warning, text);\n    }\n\n    export function error(text: any) {\n        add(ConsolePriority.Error, text);\n    }\n\n    /**\n     * Write a line of text to the console output.\n     * @param value to send\n     */\n    //% weight=90\n    //% help=console/log blockGap=8\n    //% blockId=console_log block=\"console log $value\"\n    //% value.shadow=text\n    export function log(value: any): void {\n        add(ConsolePriority.Log, value);\n    }\n\n    /**\n     * Write a name:value pair as a line of text to the console output.\n     * @param name name of the value stream, eg: \"x\"\n     * @param value to write\n     */\n    //% weight=88 blockGap=8\n    //% help=console/log-value\n    //% blockId=console_log_value block=\"console|log value %name|= %value\"\n    //% name.shadow=text\n    //% value.shadow=math_number\n    export function logValue(name: any, value: any): void {\n        log(name ? `${inspect(name)}: ${inspect(value)}` : `${inspect(value)}`)\n    }\n\n    /**\n     * Convert any object or value to a string representation\n     * @param obj value to be converted to a string\n     * @param maxElements [optional] max number values in an object to include in output\n     */\n    export function inspect(obj: any, maxElements = 20): string {\n        if (typeof obj == \"string\") {\n            return obj;\n        } else if (typeof obj == \"number\") {\n            return \"\" + obj;\n        } else if (Array.isArray(obj)) {\n            const asArr = (obj as Array<string>);\n            if (asArr.length <= maxElements) {\n                return asArr.join(\",\");\n            } else {\n                return `${asArr.slice(0, maxElements).join(\",\")}...`;\n            }\n        } else {\n            const asString = obj + \"\";\n            if (asString != \"[object Object]\"\n                && asString != \"[Object]\") { // on arcade at least, default toString is [Object] on hardware instead of standard\n                return asString;\n            }\n\n            let keys = Object.keys(obj);\n            const snipped = keys.length > maxElements;\n            if (snipped) {\n                keys = keys.slice(0, maxElements);\n            }\n\n            return `{${\n                keys.reduce(\n                    (prev, currKey) => prev + `\\n    ${currKey}: ${obj[currKey]}`,\n                    \"\"\n                ) + (snipped ? \"\\n    ...\" : \"\")\n            }\n}`;\n        }\n    }\n\n    /**\n     * Adds a listener for the log messages\n     * @param listener\n     */\n    //%\n    export function addListener(listener: (priority: ConsolePriority, text: string) => void) {\n        if (!listener || listeners.indexOf(listener) > -1) return;\n        listeners.push(listener);\n    }\n\n    /**\n     * Removes a listener\n     * @param listener\n     */\n    //%\n    export function removeListener(listener: (priority: ConsolePriority, text: string) => void) {\n        if (!listener) return;\n        const i = listeners.indexOf(listener);\n        if (i > -1)\n            listeners.splice(i, 1);\n    }\n}","control.cpp":"#include \"pxtbase.h\"\n\n\nnamespace control {\n    /**\n    * Gets the number of milliseconds elapsed since power on.\n    */\n    //% help=control/millis weight=50\n    //% blockId=control_running_time block=\"millis (ms)\"\n    int millis() {\n        return current_time_ms();\n    }\n\n    /**\n    * Gets current time in microseconds. Overflows every ~18 minutes.\n    */\n    //%\n    int micros() {\n        return current_time_us() & 0x3fffffff;\n    }\n\n    /**\n    * Used internally\n    */\n    //%\n    void internalOnEvent(int src, int value, Action handler, int flags = 16) {\n        registerWithDal(src, value, handler, flags);\n    }\n\n    /**\n     * Reset the device.\n     */\n    //% weight=30 async help=control/reset blockGap=8\n    //% blockId=\"control_reset\" block=\"reset\"\n    void reset() {\n        target_reset();\n    }\n\n    /**\n    * Block 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 async\n    //% blockId=\"control_wait_us\" block=\"wait (µs)%micros\"\n    void waitMicros(int micros) {\n        sleep_us(micros);\n    }\n\n    /**\n     * Run other code in the parallel.\n     */\n    //% help=control/run-in-parallel handlerStatement=1\n    //% blockId=\"control_run_in_parallel\" block=\"run in parallel\" blockGap=8\n    void runInParallel(Action a) {\n        pxt::runInParallel(a);\n    }\n\n    /**\n    * Blocks the calling thread until the specified event is raised.\n    */\n    //% help=control/wait-for-event async\n    //% blockId=control_wait_for_event block=\"wait for event|from %src|with value %value\"\n    void waitForEvent(int src, int value) {\n        pxt::waitForEvent(src, value);\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    //% help=control/device-serial-number\n    int deviceSerialNumber() {\n        uint64_t serial_num = pxt::getLongSerialNumber();\n        return hash_fnv1(&serial_num, sizeof(serial_num)) & 0x3fffffff;\n    }\n\n    /**\n    * Derive a unique, consistent 64-bit serial number of this device from internal data.\n    */\n    //% blockId=\"control_device_long_serial_number\" block=\"device long serial number\" weight=9\n    //% help=control/device-long-serial-number\n    Buffer deviceLongSerialNumber() {\n        uint64_t serial_num = pxt::getLongSerialNumber();\n        return mkBuffer((uint8_t*)&serial_num, sizeof(uint64_t));\n    }\n\n    /**\n    *\n    */\n    //%\n    void __log(int prority, String text) {\n        if (NULL == text) return;\n        pxt::sendSerial(text->getUTF8Data(), text->getUTF8Size());\n    }\n\n    /**\n     * Dump internal information about a value.\n     */\n    //%\n    void dmesgValue(TValue v) {\n        anyPrint(v);\n    }\n}\n","control.ts":"/**\n* Program controls and events.\n*/\n//% weight=90 color=\"#FF5722\" icon=\"\\uf110\" advanced=true\nnamespace control {\n    /**\n     * Deprecated, use ``control.runInParallel`` instead.\n     */\n    //% deprecated=1 hidden=1 help=control/run-in-background blockAllowMultiple=1 afterOnStart=true\n    //% blockId=\"control_run_in_background\" block=\"run in background\" blockGap=8 weight=0\n    export function runInBackground(a: () => void) {\n        control.runInParallel(a);\n    }\n\n    export const enum PXT_PANIC {\n        CODAL_OOM = 20,\n        GC_OOM = 21,\n        GC_TOO_BIG_ALLOCATION = 22,\n        CODAL_HEAP_ERROR = 30,\n        CODAL_NULL_DEREFERENCE = 40,\n        CODAL_USB_ERROR = 50,\n        CODAL_HARDWARE_CONFIGURATION_ERROR = 90,\n\n        INVALID_BINARY_HEADER = 901,\n        OUT_OF_BOUNDS = 902,\n        REF_DELETED = 903,\n        SIZE = 904,\n        INVALID_VTABLE = 905,\n        INTERNAL_ERROR = 906,\n        NO_SUCH_CONFIG = 907,\n        NO_SUCH_PIN = 908,\n        INVALID_ARGUMENT = 909,\n        MEMORY_LIMIT_EXCEEDED = 910,\n        SCREEN_ERROR = 911,\n        MISSING_PROPERTY = 912,\n        INVALID_IMAGE = 913,\n        CALLED_FROM_ISR = 914,\n        HEAP_DUMPED = 915,\n        STACK_OVERFLOW = 916,\n        BLOCKING_TO_STRING = 917,\n        VM_ERROR = 918,\n        SETTINGS_CLEARED = 920,\n        SETTINGS_OVERLOAD = 921,\n        SETTINGS_SECRET_MISSING = 922,\n        DELETE_ON_CLASS = 923,\n\n        CAST_FIRST = 980,\n        CAST_FROM_UNDEFINED = 980,\n        CAST_FROM_BOOLEAN = 981,\n        CAST_FROM_NUMBER = 982,\n        CAST_FROM_STRING = 983,\n        CAST_FROM_OBJECT = 984,\n        CAST_FROM_FUNCTION = 985,\n        CAST_FROM_NULL = 989,\n\n        UNHANDLED_EXCEPTION = 999,\n    }\n    /**\n     * Display an error code and stop the program.\n     * @param code an error number to display. eg: 5\n     */\n    //% help=control/panic weight=29\n    //% blockId=\"control_panic\" block=\"panic %code\"\n    //% shim=pxtrt::panic\n    export function panic(code: number) { }\n\n    /**\n     * Display an error code and stop the program when the assertion is `false`.\n     */\n    //% help=control/assert weight=30\n    //% blockId=\"control_assert\" block=\"assert %cond|with value %code\"\n    export function assert(cond: boolean, code: number) {\n        if (!cond) {\n            fail(\"Assertion failed, code=\" + code)\n        }\n    }\n\n    export function fail(message: string) {\n        console.log(\"Fatal failure: \")\n        console.log(message)\n        dmesg(message)\n        panic(108)\n    }\n\n    let _evSource = 0x8000\n    export function allocateEventSource() {\n        return ++_evSource\n    }\n\n    export class AnimationQueue {\n        running: boolean;\n        eventID: number;\n        public interval: number;\n\n        constructor() {\n            this.running = false;\n            this.eventID = control.allocateNotifyEvent();\n            this.interval = 1;\n        }\n\n        /**\n         * Runs 'render' in a loop until it returns false or the 'stop' function is called\n         */\n        runUntilDone(render: () => boolean) {\n            const evid = this.eventID;\n\n            // if other animation, wait for turn\n            if (this.running)\n                control.waitForEvent(DAL.DEVICE_ID_NOTIFY, evid);\n\n            // check if the animation hasn't been cancelled since we've waiting\n            if (this.isCancelled(evid))\n                return;\n\n            // run animation\n            this.running = true;\n            while (this.running\n                && !this.isCancelled(evid)\n                && render()) {\n                pause(this.interval);\n            }\n\n            // check if the animation hasn't been cancelled since we've been waiting\n            if (this.isCancelled(evid))\n                return;\n\n            // we're done\n            this.running = false;\n            // unblock 1 fiber\n            control.raiseEvent(DAL.DEVICE_ID_NOTIFY_ONE, this.eventID);\n        }\n\n        isCancelled(evid: number) {\n            return this.eventID !== evid;\n        }\n\n        /**\n         * Cancels the current running animation and clears the queue\n         */\n        cancel() {\n            if (this.running) {\n                this.running = false;\n                const evid = this.eventID;\n                this.eventID = control.allocateNotifyEvent();\n                // unblock fibers\n                control.raiseEvent(DAL.DEVICE_ID_NOTIFY, evid);\n            }\n        }\n    }\n\n    //% shim=pxt::getConfig\n    export declare function getConfigValue(key: int32, defl: int32): number;\n\n    //% shim=pxt::programHash\n    export declare function programHash(): number;\n\n    //% shim=pxt::programName\n    export declare function programName(): string;\n\n    //% shim=control::_ramSize\n    function _ramSize() {\n        return 32 * 1024 * 1024;\n    }\n\n    /** Returns estimated size of memory in bytes. */\n    export function ramSize() {\n        return getConfigValue(DAL.CFG_RAM_BYTES, 0) || _ramSize();\n    }\n\n    /** Runs the function and returns run time in microseconds. */\n    export function benchmark(f: () => void) {\n        const t0 = micros()\n        f()\n        let t = micros() - t0\n        if (t < 0)\n            t += 0x3fffffff\n        return t\n    }\n}\n\n/**\n * Convert any value to text\n * @param value value to be converted to text\n */\n//% help=text/convert-to-text weight=1\n//% block=\"convert $value=math_number to text\"\n//% blockId=variable_to_text blockNamespace=\"text\"\nfunction convertToText(value: any): string {\n    return \"\" + value;\n}\n","controlgc.cpp":"#include \"pxtbase.h\"\n\n\nnamespace control {\n    /**\n     * Force GC and dump basic information about heap.\n     */\n    //%\n    void gc() {\n        pxt::gc(1);\n    }\n\n    /**\n     * Force GC and halt waiting for debugger to do a full heap dump.\n     */\n    //%\n    void heapDump() {\n        pxt::gc(2);\n        soft_panic(PANIC_HEAP_DUMPED);\n    }\n\n\n    /**\n     * Set flags used when connecting an external debugger.\n     */\n    //%\n    void setDebugFlags(int flags) {\n        debugFlags = flags;\n    }\n\n    /**\n     * Record a heap snapshot to debug memory leaks.\n     */\n    //%\n    void heapSnapshot() {\n        // only in JS backend for now\n    }\n\n    /**\n     * Return true if profiling is enabled in the current build.\n     */\n    //%\n    bool profilingEnabled() {\n#ifdef PXT_PROFILE\n        return true;\n#else\n        return false;\n#endif\n    }\n}\n","controlmessage.ts":"namespace control.simmessages {\n    // these events are raised by JS simulator when messages come in\n    export const CONTROL_MESSAGE_EVT_ID = 2999;\n    export const CONTROL_MESSAGE_RECEIVED = 1;\n\n    //% shim=pxt::sendMessage\n    export declare function send(channel: string, message: Buffer, parentOnly?: boolean) : void;\n\n    //% shim=pxt::peekMessageChannel\n    declare function peekMessageChannel(): string;\n\n    //% shim=pxt::readMessageData\n    declare function readMessageData(): Buffer;\n\n    let handlers: { [channel: string] : (msg: Buffer) => void}\n    function consumeMessages() {\n        while(true) {\n            // peek channel of next message\n            const channel = peekMessageChannel();\n            if (!channel) break;\n            // read next message\n            const msg = readMessageData();\n            // send to handler\n            const handler = handlers && handlers[channel];\n            if (handler)\n                handler(msg);\n        }\n    }\n\n    /**\n     * Registers the handler for a message on a given channel\n     **/\n    export function onReceived(channel: string, handler: (msg: Buffer) => void) {\n        if (!channel) return;\n\n        if (!handlers)\n            handlers = {};\n        handlers[channel] = handler;\n        control.onEvent(CONTROL_MESSAGE_EVT_ID, CONTROL_MESSAGE_RECEIVED, consumeMessages);\n    }\n}","core.cpp":"#include \"pxtbase.h\"\n#include <limits.h>\n#include <stdlib.h>\n\nusing namespace std;\n\n#define p10(v) __builtin_powi(10, v)\n\n// try not to create cons-strings shorter than this\n#define SHORT_CONCAT_STRING 50\n\nnamespace pxt {\n\nPXT_DEF_STRING(emptyString, \"\")\n\nstatic HandlerBinding *handlerBindings;\n\nHandlerBinding *nextBinding(HandlerBinding *curr, int source, int value) {\n    for (auto p = curr; p; p = p->next) {\n        // DEVICE_ID_ANY == DEVICE_EXT_ANY == 0\n        if ((p->source == source || p->source == 0) &&\n            (value == -1 || p->value == value || p->value == 0)) {\n            return p;\n        }\n    }\n    return 0;\n}\n\nHandlerBinding *findBinding(int source, int value) {\n    return nextBinding(handlerBindings, source, value);\n}\n\nvoid setBinding(int source, int value, Action act) {\n    HandlerBinding *curr = NULL;\n    for (auto p = handlerBindings; p; p = p->next) {\n        if ((p->source == source) && (p->value == value)) {\n            curr = p;\n            break;\n        }\n    }\n    if (curr) {\n        curr->action = act;\n        return;\n    }\n    curr = new (app_alloc(sizeof(HandlerBinding))) HandlerBinding();\n    curr->next = handlerBindings;\n    curr->source = source;\n    curr->value = value;\n    curr->action = act;\n    registerGC(&curr->action);\n    handlerBindings = curr;\n}\n\nvoid coreReset() {\n    // these are allocated on GC heap, so they will go away together with the reset\n    handlerBindings = NULL;\n}\n\nstruct EmptyBufferLayout {\n    const void *vtable;\n    // data needs to be word-aligned, so we use 32 bits for length\n    int length;\n    uint8_t data[1];\n};\n\nstatic const EmptyBufferLayout emptyBuffer[1] = {{&pxt::buffer_vt, 0, {0}}};\n\n#if PXT_UTF8\nint utf8Len(const char *data, int size) {\n    int len = 0;\n    for (int i = 0; i < size; ++i) {\n        char c = data[i];\n        len++;\n        if ((c & 0x80) == 0x00) {\n            // skip\n        } else if ((c & 0xe0) == 0xc0) {\n            i++;\n        } else if ((c & 0xf0) == 0xe0) {\n            i += 2;\n        } else {\n            // error; just skip\n        }\n    }\n    return len;\n}\n\nconst char *utf8Skip(const char *data, int size, int skip) {\n    int len = 0;\n    for (int i = 0; i <= size; ++i) {\n        char c = data[i];\n        len++;\n        if (len > skip)\n            return data + i;\n        if ((c & 0x80) == 0x00) {\n            // skip\n        } else if ((c & 0xe0) == 0xc0) {\n            i++;\n        } else if ((c & 0xf0) == 0xe0) {\n            i += 2;\n        } else {\n            // error; just skip over\n        }\n    }\n    return NULL;\n}\n\nstatic char *write3byte(char *dst, uint32_t charCode) {\n    if (dst) {\n        *dst++ = 0xe0 | (charCode >> 12);\n        *dst++ = 0x80 | (0x3f & (charCode >> 6));\n        *dst++ = 0x80 | (0x3f & (charCode >> 0));\n    }\n    return dst;\n}\n\nstatic char *write2byte(char *dst, uint32_t charCode) {\n    if (dst) {\n        *dst++ = 0xc0 | (charCode >> 6);\n        *dst++ = 0x80 | (0x3f & charCode);\n    }\n    return dst;\n}\n\nstatic int utf8canon(char *dst, const char *data, int size) {\n    int outsz = 0;\n    for (int i = 0; i < size;) {\n        uint8_t c = data[i];\n        uint32_t charCode = c;\n        if ((c & 0x80) == 0x00) {\n            charCode = c;\n            i++;\n        } else if ((c & 0xe0) == 0xc0 && i + 1 < size && (data[i + 1] & 0xc0) == 0x80) {\n            charCode = ((c & 0x1f) << 6) | (data[i + 1] & 0x3f);\n            if (charCode < 0x80)\n                goto error;\n            else\n                i += 2;\n        } else if ((c & 0xf0) == 0xe0 && i + 2 < size && (data[i + 1] & 0xc0) == 0x80 &&\n                   (data[i + 2] & 0xc0) == 0x80) {\n            charCode = ((c & 0x0f) << 12) | (data[i + 1] & 0x3f) << 6 | (data[i + 2] & 0x3f);\n            // don't exclude surrogate pairs, since we're generating them\n            if (charCode < 0x800 /*|| (0xd800 <= charCode && charCode <= 0xdfff)*/)\n                goto error;\n            else\n                i += 3;\n        } else if ((c & 0xf8) == 0xf0 && i + 3 < size && (data[i + 1] & 0xc0) == 0x80 &&\n                   (data[i + 2] & 0xc0) == 0x80 && (data[i + 3] & 0xc0) == 0x80) {\n            charCode = ((c & 0x07) << 18) | (data[i + 1] & 0x3f) << 12 | (data[i + 2] & 0x3f) << 6 |\n                       (data[i + 3] & 0x3f);\n            if (charCode < 0x10000 || charCode > 0x10ffff)\n                goto error;\n            else\n                i += 4;\n        } else {\n            goto error;\n        }\n\n        if (charCode < 0x80) {\n            outsz += 1;\n            if (dst)\n                *dst++ = charCode;\n        } else if (charCode < 0x800) {\n            outsz += 2;\n            dst = write2byte(dst, charCode);\n        } else if (charCode < 0x10000) {\n            outsz += 3;\n            dst = write3byte(dst, charCode);\n        } else {\n            outsz += 6; // a surrogate pair\n            charCode -= 0x10000;\n            dst = write3byte(dst, 0xd800 + (charCode >> 10));\n            dst = write3byte(dst, 0xdc00 + (charCode & 0x3ff));\n        }\n\n        continue;\n\n    error:\n        i++;\n        outsz += 2;\n        dst = write2byte(dst, c);\n    }\n    return outsz;\n}\n\nstatic int utf8CharCode(const char *data) {\n    unsigned char c = *data;\n    if ((c & 0x80) == 0) {\n        return c;\n    } else if ((c & 0xe0) == 0xc0) {\n        return ((c & 0x1f) << 6) | (data[1] & 0x3f);\n    } else if ((c & 0xf0) == 0xe0) {\n        return ((c & 0x0f) << 12) | (data[1] & 0x3f) << 6 | (data[2] & 0x3f);\n    } else {\n        return c; // error\n    }\n}\n\nstatic bool isUTF8(const char *data, int len) {\n    for (int i = 0; i < len; ++i) {\n        if (data[i] & 0x80)\n            return true;\n    }\n    return false;\n}\n\nstatic void setupSkipList(String r, const char *data, int packed) {\n    char *dst = (char *)(packed ? PXT_SKIP_DATA_PACK(r) : PXT_SKIP_DATA_IND(r));\n    auto len = r->skip.size;\n    if (data)\n        memcpy(dst, data, len);\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wstringop-overflow\"\n    dst[len] = 0;\n#pragma GCC diagnostic pop\n    const char *ptr = dst;\n    auto skipEntries = PXT_NUM_SKIP_ENTRIES(r);\n    auto lst = packed ? r->skip_pack.list : r->skip.list;\n    for (int i = 0; i < skipEntries; ++i) {\n        ptr = utf8Skip(ptr, (int)(len - (ptr - dst)), PXT_STRING_SKIP_INCR);\n        if (!ptr)\n            oops(80);\n        lst[i] = ptr - dst;\n    }\n}\n#endif\n\nString mkStringCore(const char *data, int len) {\n    if (len < 0)\n        len = (int)strlen(data);\n    if (len == 0)\n        return (String)emptyString;\n\n    auto vt = &string_inline_ascii_vt;\n    String r;\n\n#if PXT_UTF8\n    if (data && isUTF8(data, len)) {\n        vt = len >= PXT_STRING_MIN_SKIP ? &string_skiplist16_packed_vt : &string_inline_utf8_vt;\n    }\n    if (vt == &string_skiplist16_packed_vt) {\n        int ulen = utf8Len(data, len);\n        r = new (gcAllocate(sizeof(void *) + 2 + 2 + (ulen / PXT_STRING_SKIP_INCR) * 2 + len + 1))\n            BoxedString(vt);\n        r->skip_pack.size = len;\n        r->skip_pack.length = ulen;\n        setupSkipList(r, data, 1);\n    } else\n#endif\n    {\n        // for ASCII and UTF8 the layout is the same\n        r = new (gcAllocate(sizeof(void *) + 2 + len + 1)) BoxedString(vt);\n        r->ascii.length = len;\n        if (data)\n            memcpy(r->ascii.data, data, len);\n        r->ascii.data[len] = 0;\n    }\n\n    MEMDBG(\"mkString: len=%d => %p\", len, r);\n    return r;\n}\n\nString mkString(const char *data, int len) {\n#if PXT_UTF8\n    if (len < 0)\n        len = (int)strlen(data);\n    if (len == 0)\n        return (String)emptyString;\n\n    int sz = utf8canon(NULL, data, len);\n    if (sz == len)\n        return mkStringCore(data, len);\n    // this could be optimized, but it only kicks in when the string isn't valid utf8\n    // (or we need to introduce surrogate pairs) which is unlikely to be performance critical\n    char *tmp = (char *)app_alloc(sz);\n    utf8canon(tmp, data, len);\n    auto r = mkStringCore(tmp, sz);\n    app_free(tmp);\n    return r;\n#else\n    return mkStringCore(data, len);\n#endif\n}\n\n#if PXT_UTF8\n// This converts surrogate pairs, which are encoded as 2 characters of 3 bytes each\n// into a proper 4 byte utf-8 character.\nuint32_t toRealUTF8(String str, uint8_t *dst) {\n    auto src = str->getUTF8Data();\n    auto len = str->getUTF8Size();\n    auto dlen = 0;\n\n    for (unsigned i = 0; i < len; ++i) {\n        if ((uint8_t)src[i] == 0xED && i + 5 < len) {\n            auto c0 = utf8CharCode(src + i);\n            auto c1 = utf8CharCode(src + i + 3);\n            if (0xd800 <= c0 && c0 < 0xdc00 && 0xdc00 <= c1 && c1 < 0xe000) {\n                i += 5;\n                auto charCode = ((c0 - 0xd800) << 10) + (c1 - 0xdc00) + 0x10000;\n                if (dst) {\n                    dst[dlen] = 0xf0 | (charCode >> 18);\n                    dst[dlen + 1] = 0x80 | (0x3f & (charCode >> 12));\n                    dst[dlen + 2] = 0x80 | (0x3f & (charCode >> 6));\n                    dst[dlen + 3] = 0x80 | (0x3f & (charCode >> 0));\n                }\n                dlen += 4;\n            }\n        } else {\n            if (dst)\n                dst[dlen] = src[i];\n            dlen++;\n        }\n    }\n    return dlen;\n}\n#endif\n\nBuffer mkBuffer(const void *data, int len) {\n    if (len <= 0)\n        return (Buffer)emptyBuffer;\n    Buffer r = new (gcAllocate(sizeof(BoxedBuffer) + len)) BoxedBuffer();\n    r->length = len;\n    if (data)\n        memcpy(r->data, data, len);\n    else\n        memset(r->data, 0, len);\n    MEMDBG(\"mkBuffer: len=%d => %p\", len, r);\n    return r;\n}\n\nstatic unsigned random_value = 0xC0DA1;\n\n//%\nvoid seedRandom(unsigned seed) {\n    random_value = seed;\n}\n\n//% expose\nvoid seedAddRandom(unsigned seed) {\n    random_value ^= 0xCA2557CB * seed;\n}\n\nunsigned getRandom(unsigned max) {\n    unsigned m, result;\n\n    do {\n        m = (unsigned)max;\n        result = 0;\n\n        do {\n            // Cycle the LFSR (Linear Feedback Shift Register).\n            // We use an optimal sequence with a period of 2^32-1, as defined by Bruce Schneier here\n            // (a true legend in the field!),\n            // For those interested, it's documented in his paper:\n            // \"Pseudo-Random Sequence Generator for 32-Bit CPUs: A fast, machine-independent\n            // generator for 32-bit Microprocessors\"\n            // https://www.schneier.com/paper-pseudorandom-sequence.html\n            unsigned r = random_value;\n\n            r = ((((r >> 31) ^ (r >> 6) ^ (r >> 4) ^ (r >> 2) ^ (r >> 1) ^ r) & 1) << 31) |\n                (r >> 1);\n\n            random_value = r;\n\n            result = ((result << 1) | (r & 0x00000001));\n        } while (m >>= 1);\n    } while (result > (unsigned)max);\n\n    return result;\n}\n\nTNumber BoxedString::charCodeAt(int pos) {\n#if PXT_UTF8\n    auto ptr = this->getUTF8DataAt(pos);\n    if (!ptr)\n        return TAG_NAN;\n    auto code = utf8CharCode(ptr);\n    if (!code && ptr == this->getUTF8Data() + this->getUTF8Size())\n        return TAG_NAN;\n    return fromInt(code);\n#else\n    if (0 <= pos && pos < this->ascii.length) {\n        return fromInt(this->ascii.data[pos]);\n    } else {\n        return TAG_NAN;\n    }\n#endif\n}\n\nPXT_DEF_STRING(sTrue, \"true\")\nPXT_DEF_STRING(sFalse, \"false\")\nPXT_DEF_STRING(sUndefined, \"undefined\")\nPXT_DEF_STRING(sNull, \"null\")\nPXT_DEF_STRING(sObject, \"[Object]\")\nPXT_DEF_STRING(sFunction, \"[Function]\")\nPXT_DEF_STRING(sNaN, \"NaN\")\nPXT_DEF_STRING(sInf, \"Infinity\")\nPXT_DEF_STRING(sMInf, \"-Infinity\")\n} // namespace pxt\n\n#ifndef X86_64\n\nnamespace String_ {\n\n//%\nString mkEmpty() {\n    return (String)emptyString;\n}\n\n// TODO support var-args somehow?\n\n//%\nString fromCharCode(int code) {\n#if PXT_UTF8\n    char buf[3];\n    int len;\n    code &= 0xffff; // JS semantics\n    if (code < 0x80) {\n        buf[0] = code;\n        len = 1;\n    } else if (code < 0x800) {\n        buf[0] = 0xc0 | (code >> 6);\n        buf[1] = 0x80 | ((code >> 0) & 0x3f);\n        len = 2;\n    } else {\n        buf[0] = 0xe0 | (code >> 12);\n        buf[1] = 0x80 | ((code >> 6) & 0x3f);\n        buf[2] = 0x80 | ((code >> 0) & 0x3f);\n        len = 3;\n    }\n    return mkStringCore(buf, len);\n#else\n    char buf[] = {(char)code, 0};\n    return mkStringCore(buf, 1);\n#endif\n}\n\n//%\nTNumber charCodeAt(String s, int pos) {\n    if (!s)\n        return TAG_NAN;\n    return s->charCodeAt(pos);\n}\n\n//%\nString charAt(String s, int pos) {\n    auto v = charCodeAt(s, pos);\n    if (v == TAG_NAN)\n        return mkEmpty();\n    if (!isInt(v))\n        oops(81);\n    return fromCharCode(numValue(v));\n}\n\n#define IS_CONS(s) ((s)->vtable == &string_cons_vt)\n#define IS_EMPTY(s) ((s) == (String)emptyString)\n\n//%\nString concat(String s, String other) {\n    if (!s)\n        s = (String)sNull;\n    if (!other)\n        other = (String)sNull;\n    if (IS_EMPTY(s))\n        return other;\n    if (IS_EMPTY(other))\n        return s;\n\n    uint32_t lenA, lenB;\n\n#if PXT_UTF8\n    if (IS_CONS(s)) {\n        // (s->cons.left + s->cons.right) + other = s->cons.left + (s->cons.right + other)\n        if (IS_CONS(other) || IS_CONS(s->cons.right))\n            goto mkCons;\n        auto lenAR = s->cons.right->getUTF8Size();\n        lenB = other->getUTF8Size(); // de-consify other\n        if (lenAR + lenB > SHORT_CONCAT_STRING)\n            goto mkCons;\n        // if (s->cons.right + other) is short enough, use associativity\n        // to construct a shallower tree; this should keep the live set reasonable\n        // when someone decides to construct a long string by concatenating\n        // single characters\n\n        // allocate [r] first, and keep it alive\n        String r = new (gcAllocate(3 * sizeof(void *))) BoxedString(&string_cons_vt);\n        registerGCObj(r);\n        r->cons.left = s->cons.left;\n        // this concat() might trigger GC\n        r->cons.right = concat(s->cons.right, other);\n        unregisterGCObj(r);\n        return r;\n    }\n#endif\n\n    lenA = s->getUTF8Size();\n    lenB = other->getUTF8Size();\n#if PXT_UTF8\n    if (lenA + lenB > SHORT_CONCAT_STRING)\n        goto mkCons;\n#endif\n    String r;\n    {\n        auto dataA = s->getUTF8Data();\n        auto dataB = other->getUTF8Data();\n        r = mkStringCore(NULL, lenA + lenB);\n        auto dst = (char *)r->getUTF8Data();\n        memcpy(dst, dataA, lenA);\n        memcpy(dst + lenA, dataB, lenB);\n#if PXT_UTF8\n        if (isUTF8(dst, lenA + lenB))\n            r->vtable = &string_inline_utf8_vt;\n#endif\n        return r;\n    }\n\n#if PXT_UTF8\nmkCons:\n    r = new (gcAllocate(3 * sizeof(void *))) BoxedString(&string_cons_vt);\n    r->cons.left = s;\n    r->cons.right = other;\n    return r;\n#endif\n}\n\nint compare(String a, String b) {\n    if (a == b)\n        return 0;\n\n    auto lenA = a->getUTF8Size();\n    auto lenB = b->getUTF8Size();\n    auto dataA = a->getUTF8Data();\n    auto dataB = b->getUTF8Data();\n    auto len = lenA < lenB ? lenA : lenB;\n\n    // this also works for UTF8, provided canonical encoding\n    // which is guaranteed by the constructor\n    for (unsigned i = 0; i <= len; ++i) {\n        unsigned char cA = dataA[i];\n        unsigned char cB = dataB[i];\n        if (cA == cB)\n            continue;\n        return cA < cB ? -1 : 1;\n    }\n    return 0;\n}\n\n//%\nint length(String s) {\n    return s->getLength();\n}\n\n#define isspace(c) ((c) == ' ')\n#define iswhitespace(c)                                                                            \\\n    ((c) == 0x09 || (c) == 0x0B || (c) == 0x0C || (c) == 0x20 || (uint8_t)(c) == 0xA0 ||           \\\n     (c) == 0x0A || (c) == 0x0D)\n\nNUMBER mystrtod(const char *p, char **endp) {\n    while (iswhitespace(*p))\n        p++;\n    NUMBER m = 1;\n    NUMBER v = 0;\n    int dot = 0;\n    int hasDigit = 0;\n    if (*p == '+')\n        p++;\n    if (*p == '-') {\n        m = -1;\n        p++;\n    }\n\n    while (*p) {\n        int c = *p - '0';\n        if (0 <= c && c <= 9) {\n            v *= 10;\n            v += c;\n            if (dot)\n                m /= 10;\n            hasDigit = 1;\n        } else if (!dot && *p == '.') {\n            dot = 1;\n        } else if (!hasDigit) {\n            return NAN;\n        } else {\n            break;\n        }\n        p++;\n    }\n\n    v *= m;\n\n    if (*p == 'e' || *p == 'E') {\n        p++;\n        int pw = (int)strtol(p, endp, 10);\n        v *= p10(pw);\n    } else {\n        *endp = (char *)p;\n    }\n\n    return v;\n}\n\n//%\nTNumber toNumber(String s) {\n    // JSCHECK\n    char *endptr;\n    auto data = s->getUTF8Data();\n    NUMBER v = mystrtod(data, &endptr);\n    if (v == 0.0 || v == -0.0) {\n        // nothing\n    } else if (!isnormal(v))\n        v = NAN;\n    return fromDouble(v);\n}\n\n//%\nString substr(String s, int start, int length) {\n    if (length <= 0)\n        return mkEmpty();\n    auto slen = (int)s->getLength();\n    if (start < 0)\n        start = pxt::max(slen + start, 0);\n    length = pxt::min(length, slen - start);\n    if (length <= 0)\n        return mkEmpty();\n    auto p = s->getUTF8DataAt(start);\n#if PXT_UTF8\n    auto ep = s->getUTF8DataAt(start + length);\n    if (ep == NULL)\n        oops(82);\n    return mkStringCore(p, (int)(ep - p));\n#else\n    return mkStringCore(p, length);\n#endif\n}\n\n//%\nint indexOf(String s, String searchString, int start) {\n    if (!s || !searchString)\n        return -1;\n\n    if (start < 0)\n        start = 0;\n\n    auto dataA0 = s->getUTF8Data();\n    auto dataA = s->getUTF8DataAt(start);\n    auto offset = dataA - dataA0;\n    auto lenA = s->getUTF8Size() - offset;\n    auto lenB = searchString->getUTF8Size();\n\n    if (dataA == NULL || lenB > lenA)\n        return -1;\n\n    auto dataB = searchString->getUTF8Data();\n    auto firstB = dataB[0];\n    while (lenA >= lenB) {\n        if (*dataA == firstB && !memcmp(dataA, dataB, lenB))\n#if PXT_UTF8\n            return utf8Len(dataA0, (int)(dataA - dataA0));\n#else\n            return dataA - dataA0;\n#endif\n        dataA++;\n        lenA--;\n    }\n    return -1;\n}\n\n//%\nint includes(String s, String searchString, int start) {\n    return -1 != indexOf(s, searchString, start);\n}\n\n} // namespace String_\n\nnamespace Boolean_ {\n//%\nbool bang(bool v) {\n    return v == 0;\n}\n} // namespace Boolean_\n\nnamespace pxt {\n\n// ES5 9.5, 9.6\nunsigned toUInt(TNumber v) {\n    if (isInt(v))\n        return numValue(v);\n    if (isSpecial(v)) {\n        if ((intptr_t)v >> 6)\n            return 1;\n        else\n            return 0;\n    }\n    if (!v)\n        return 0;\n\n    NUMBER num = toDouble(v);\n    if (!isnormal(num))\n        return 0;\n#ifdef PXT_USE_FLOAT\n    float rem = fmodf(truncf(num), 4294967296.0);\n#else\n    double rem = fmod(trunc(num), 4294967296.0);\n#endif\n    if (rem < 0.0)\n        rem += 4294967296.0;\n    return (unsigned)rem;\n}\nint toInt(TNumber v) {\n    return (int)toUInt(v);\n}\n\nNUMBER toDouble(TNumber v) {\n    if (v == TAG_NAN || v == TAG_UNDEFINED)\n        return NAN;\n    if (isTagged(v))\n        return toInt(v);\n\n#ifdef PXT64\n    if (isDouble(v))\n        return doubleVal(v);\n#endif\n\n    ValType t = valType(v);\n\n#ifndef PXT64\n    if (t == ValType::Number) {\n        BoxedNumber *p = (BoxedNumber *)v;\n        return p->num;\n    }\n#endif\n\n    if (t == ValType::String) {\n        // TODO avoid allocation\n        auto tmp = String_::toNumber((String)v);\n        auto r = toDouble(tmp);\n        return r;\n    } else {\n        return NAN;\n    }\n}\n\nfloat toFloat(TNumber v) {\n    if (v == TAG_NAN || v == TAG_UNDEFINED)\n        return NAN;\n    // optimize for the int case - this will avoid software conversion when FPU is present\n    if (isTagged(v))\n        return toInt(v);\n    return (float)toDouble(v);\n}\n\n#if !defined(PXT_HARD_FLOAT) && !defined(PXT_USE_FLOAT)\nunion NumberConv {\n    double v;\n    struct {\n        uint32_t word0;\n        uint32_t word1;\n    };\n};\n\nstatic inline TValue doubleToInt(double x) {\n    NumberConv cnv;\n    cnv.v = x;\n\n    if (cnv.word1 == 0 && cnv.word0 == 0)\n        return TAG_NUMBER(0);\n\n    auto ex = (int)((cnv.word1 << 1) >> 21) - 1023;\n\n    // DMESG(\"v=%d/1000 %p %p %d\", (int)(x * 1000), cnv.word0, cnv.word1, ex);\n\n    if (ex < 0 || ex > 29) {\n        // the 'MININT' case\n        if (ex == 30 && cnv.word0 == 0 && cnv.word1 == 0xC1D00000)\n            return (TValue)(0x80000001);\n        return NULL;\n    }\n\n    int32_t r;\n\n    if (ex <= 20) {\n        if (cnv.word0)\n            return TAG_UNDEFINED;\n        if (cnv.word1 << (ex + 12))\n            return TAG_UNDEFINED;\n        r = ((cnv.word1 << 11) | 0x80000000) >> (20 - ex + 11);\n    } else {\n        if (cnv.word0 << (ex - 20))\n            return TAG_UNDEFINED;\n        r = ((cnv.word1 << 11) | 0x80000000) >> (20 - ex + 11);\n        r |= cnv.word0 >> (32 - (ex - 20));\n    }\n\n    if (cnv.word1 >> 31)\n        return TAG_NUMBER(-r);\n    else\n        return TAG_NUMBER(r);\n}\n#else\nstatic inline TValue doubleToInt(NUMBER r) {\n#ifdef PXT64\n    if ((int)r == r)\n        return TAG_NUMBER((int)r);\n#else\n    int ri = ((int)r) << 1;\n    if ((ri >> 1) == r)\n        return (TNumber)(uintptr_t)(ri | 1);\n#endif\n    return TAG_UNDEFINED;\n}\n#endif\n\nTNumber fromDouble(NUMBER r) {\n#ifndef PXT_BOX_DEBUG\n    auto i = doubleToInt(r);\n    if (i)\n        return i;\n#endif\n    if (isnan(r))\n        return TAG_NAN;\n#ifdef PXT64\n    return tvalueFromDouble(r);\n#else\n    BoxedNumber *p = NEW_GC(BoxedNumber);\n    p->num = r;\n    MEMDBG(\"mkNum: %d/1000 => %p\", (int)(r * 1000), p);\n    return (TNumber)p;\n#endif\n}\n\nTNumber fromFloat(float r) {\n    // TODO optimize\n    return fromDouble(r);\n}\n\nTNumber fromInt(int v) {\n    if (canBeTagged(v))\n        return TAG_NUMBER(v);\n    return fromDouble(v);\n}\n\nTNumber fromUInt(unsigned v) {\n#ifndef PXT_BOX_DEBUG\n    if (v <= 0x3fffffff)\n        return TAG_NUMBER(v);\n#endif\n    return fromDouble(v);\n}\n\nTValue fromBool(bool v) {\n    if (v)\n        return TAG_TRUE;\n    else\n        return TAG_FALSE;\n}\n\nTNumber eqFixup(TNumber v) {\n    if (v == TAG_NULL)\n        return TAG_UNDEFINED;\n    if (v == TAG_TRUE)\n        return TAG_NUMBER(1);\n    if (v == TAG_FALSE)\n        return TAG_NUMBER(0);\n    return v;\n}\n\nstatic inline bool eq_core(TValue a, TValue b, ValType ta) {\n#ifndef PXT_BOX_DEBUG\n    auto aa = (intptr_t)a;\n    auto bb = (intptr_t)b;\n\n    // if at least one of the values is tagged, they are not equal\n    if ((aa | bb) & 3)\n        return false;\n#endif\n\n    if (ta == ValType::String)\n        return String_::compare((String)a, (String)b) == 0;\n    else if (ta == ValType::Number)\n        return toDouble(a) == toDouble(b);\n    else\n        return a == b;\n}\n\nbool eqq_bool(TValue a, TValue b) {\n    if (a == TAG_NAN || b == TAG_NAN)\n        return false;\n\n    if (a == b)\n        return true;\n\n    if (bothNumbers(a, b))\n        return false;\n\n    ValType ta = valType(a);\n    ValType tb = valType(b);\n\n    if (ta != tb)\n        return false;\n\n    return eq_core(a, b, ta);\n}\n\nbool eq_bool(TValue a, TValue b) {\n    if (a == TAG_NAN || b == TAG_NAN)\n        return false;\n\n    if (eqFixup(a) == eqFixup(b))\n        return true;\n\n    if (bothNumbers(a, b))\n        return false;\n\n    ValType ta = valType(a);\n    ValType tb = valType(b);\n\n    if ((ta == ValType::String && tb == ValType::Number) ||\n        (tb == ValType::String && ta == ValType::Number))\n        return toDouble(a) == toDouble(b);\n\n    if (ta == ValType::Boolean) {\n        a = eqFixup(a);\n        ta = ValType::Number;\n    }\n    if (tb == ValType::Boolean) {\n        b = eqFixup(b);\n        tb = ValType::Number;\n    }\n\n    if (ta != tb)\n        return false;\n\n    return eq_core(a, b, ta);\n}\n\n// TODO move to assembly\n//%\nbool switch_eq(TValue a, TValue b) {\n    if (eq_bool(a, b)) {\n        return true;\n    }\n    return false;\n}\n\n} // namespace pxt\n\n#define NUMOP(op) return fromDouble(toDouble(a) op toDouble(b));\n#define BITOP(op) return fromInt(toInt(a) op toInt(b));\nnamespace numops {\n\nint toBool(TValue v) {\n    if (isTagged(v)) {\n        if (v == TAG_FALSE || v == TAG_UNDEFINED || v == TAG_NAN || v == TAG_NULL ||\n            v == TAG_NUMBER(0))\n            return 0;\n        else\n            return 1;\n    }\n\n    ValType t = valType(v);\n    if (t == ValType::String) {\n        String s = (String)v;\n        if (IS_EMPTY(s))\n            return 0;\n    } else if (t == ValType::Number) {\n        auto x = toDouble(v);\n        if (isnan(x) || x == 0.0 || x == -0.0)\n            return 0;\n        else\n            return 1;\n    }\n\n    return 1;\n}\n\nint toBoolDecr(TValue v) {\n    if (v == TAG_TRUE)\n        return 1;\n    if (v == TAG_FALSE)\n        return 0;\n    return toBool(v);\n}\n\n// The integer, non-overflow case for add/sub/bit opts is handled in assembly\n\n#ifdef PXT_VM\n#define NUMOP2(op)                                                                                 \\\n    if (bothNumbers(a, b)) {                                                                       \\\n        auto tmp = (int64_t)numValue(a) op(int64_t) numValue(b);                                   \\\n        if ((int)tmp == tmp)                                                                       \\\n            return TAG_NUMBER((int)tmp);                                                           \\\n    }                                                                                              \\\n    NUMOP(op)\n#else\n#define NUMOP2(op) NUMOP(op)\n#endif\n\n//%\nTNumber adds(TNumber a, TNumber b){NUMOP2(+)}\n\n//%\nTNumber subs(TNumber a, TNumber b){NUMOP2(-)}\n\n//%\nTNumber muls(TNumber a, TNumber b) {\n    if (bothNumbers(a, b)) {\n#ifdef PXT64\n        auto tmp = (int64_t)numValue(a) * (int64_t)numValue(b);\n        if ((int)tmp == tmp)\n            return TAG_NUMBER((int)tmp);\n#else\n        int aa = (int)a;\n        int bb = (int)b;\n        // if both operands fit 15 bits, the result will not overflow int\n        if ((aa >> 15 == 0 || aa >> 15 == -1) && (bb >> 15 == 0 || bb >> 15 == -1)) {\n            // it may overflow 31 bit int though - use fromInt to convert properly\n            return fromInt((aa >> 1) * (bb >> 1));\n        }\n#endif\n    }\n    NUMOP(*)\n}\n\n//%\nTNumber div(TNumber a, TNumber b) {\n    if (b == TAG_NUMBER(1))\n        return a;\n    NUMOP(/)\n}\n\n//%\nTNumber mod(TNumber a, TNumber b) {\n    if (isInt(a) && isInt(b) && numValue(b))\n        BITOP(%)\n    return fromDouble(fmod(toDouble(a), toDouble(b)));\n}\n\n//%\nTNumber lsls(TNumber a, TNumber b) {\n    return fromInt(toInt(a) << (toInt(b) & 0x1f));\n}\n\n//%\nTNumber lsrs(TNumber a, TNumber b) {\n    return fromUInt(toUInt(a) >> (toUInt(b) & 0x1f));\n}\n\n//%\nTNumber asrs(TNumber a, TNumber b) {\n    return fromInt(toInt(a) >> (toInt(b) & 0x1f));\n}\n\n//%\nTNumber eors(TNumber a, TNumber b){BITOP(^)}\n\n//%\nTNumber orrs(TNumber a, TNumber b){BITOP(|)}\n\n//%\nTNumber bnot(TNumber a) {\n    return fromInt(~toInt(a));\n}\n\n//%\nTNumber ands(TNumber a, TNumber b) {\n    BITOP(&)\n}\n\n#ifdef PXT64\n#define CMPOP_RAW(op, t, f)                                                                        \\\n    if (bothNumbers(a, b))                                                                         \\\n        return numValue(a) op numValue(b) ? t : f;                                                 \\\n    int cmp = valCompare(a, b);                                                                    \\\n    return cmp != -2 && cmp op 0 ? t : f;\n#else\n#define CMPOP_RAW(op, t, f)                                                                        \\\n    if (bothNumbers(a, b))                                                                         \\\n        return (intptr_t)a op((intptr_t)b) ? t : f;                                                \\\n    int cmp = valCompare(a, b);                                                                    \\\n    return cmp != -2 && cmp op 0 ? t : f;\n#endif\n\n#define CMPOP(op) CMPOP_RAW(op, TAG_TRUE, TAG_FALSE)\n\n// 7.2.13 Abstract Relational Comparison\nstatic int valCompare(TValue a, TValue b) {\n    if (a == TAG_NAN || b == TAG_NAN)\n        return -2;\n\n    ValType ta = valType(a);\n    ValType tb = valType(b);\n\n    if (ta == ValType::String && tb == ValType::String)\n        return String_::compare((String)a, (String)b);\n\n    if (a == b)\n        return 0;\n\n    auto da = toDouble(a);\n    auto db = toDouble(b);\n\n    if (isnan(da) || isnan(db))\n        return -2;\n\n    if (da < db)\n        return -1;\n    else if (da > db)\n        return 1;\n    else\n        return 0;\n}\n\n//%\nbool lt_bool(TNumber a, TNumber b){CMPOP_RAW(<, true, false)}\n\n//%\nTNumber le(TNumber a, TNumber b){CMPOP(<=)}\n\n//%\nTNumber lt(TNumber a, TNumber b){CMPOP(<)}\n\n//%\nTNumber ge(TNumber a, TNumber b){CMPOP(>=)}\n\n//%\nTNumber gt(TNumber a, TNumber b){CMPOP(>)}\n\n//%\nTNumber eq(TNumber a, TNumber b) {\n    return pxt::eq_bool(a, b) ? TAG_TRUE : TAG_FALSE;\n}\n\n//%\nTNumber neq(TNumber a, TNumber b) {\n    return !pxt::eq_bool(a, b) ? TAG_TRUE : TAG_FALSE;\n}\n\n//%\nTNumber eqq(TNumber a, TNumber b) {\n    return pxt::eqq_bool(a, b) ? TAG_TRUE : TAG_FALSE;\n}\n\n//%\nTNumber neqq(TNumber a, TNumber b) {\n    return !pxt::eqq_bool(a, b) ? TAG_TRUE : TAG_FALSE;\n}\n\n// How many significant digits mycvt() should output.\n// This cannot be more than 15, as this is the most that can be accurately represented\n// in 64 bit double. Otherwise this code may crash.\n#define DIGITS 15\n\nstatic const uint64_t pows[] = {\n    1LL,           10LL,           100LL,           1000LL,           10000LL,\n    100000LL,      1000000LL,      10000000LL,      100000000LL,      1000000000LL,\n    10000000000LL, 100000000000LL, 1000000000000LL, 10000000000000LL, 100000000000000LL,\n};\n\n// The basic idea is we convert d to a 64 bit integer with DIGITS\n// digits, and then print it out, putting dot in the right place.\n\nvoid mycvt(NUMBER d, char *buf) {\n    if (d < 0) {\n        *buf++ = '-';\n        d = -d;\n    }\n\n    if (!d) {\n        *buf++ = '0';\n        *buf++ = 0;\n        return;\n    }\n\n    int pw = (int)log10(d);\n    int e = 1;\n\n    // if outside 1e-6 -- 1e21 range, we use the e-notation\n    if (d < 1e-6 || d > 1e21) {\n        // normalize number to 1.XYZ, save e, and reset pw\n        if (pw < 0)\n            d *= p10(-pw);\n        else\n            d /= p10(pw);\n        e = pw;\n        pw = 0;\n    }\n\n    int trailingZ = 0;\n    int dotAfter = pw + 1; // at which position the dot should be in the number\n\n    uint64_t dd;\n\n    // normalize number to be integer with exactly DIGITS digits\n    if (pw >= DIGITS) {\n        // if the number is larger than DIGITS, we need trailing zeroes\n        trailingZ = pw - DIGITS + 1;\n        dd = (uint64_t)(d / p10(trailingZ) + 0.5);\n    } else {\n        dd = (uint64_t)(d * p10(DIGITS - pw - 1) + 0.5);\n    }\n\n    // if number is less than 1, we need 0.00...00 at the beginning\n    if (dotAfter < 1) {\n        *buf++ = '0';\n        *buf++ = '.';\n        int n = -dotAfter;\n        while (n--)\n            *buf++ = '0';\n    }\n\n    // now print out the actual number\n    for (int i = DIGITS - 1; i >= 0; i--) {\n        uint64_t q = pows[i];\n        // this may be faster than fp-division and fmod(); or maybe not\n        // anyways, it works\n        int k = '0';\n        while (dd >= q) {\n            dd -= q;\n            k++;\n        }\n        *buf++ = k;\n        // if we're after dot, and what's left is zeroes, stop\n        if (dd == 0 && (DIGITS - i) >= dotAfter)\n            break;\n        // print the dot, if we arrived at it\n        if ((DIGITS - i) == dotAfter)\n            *buf++ = '.';\n    }\n\n    // print out remaining trailing zeroes if any\n    while (trailingZ-- > 0)\n        *buf++ = '0';\n\n    // if we used e-notation, handle that\n    if (e != 1) {\n        *buf++ = 'e';\n        if (e > 0)\n            *buf++ = '+';\n        itoa(e, buf);\n    } else {\n        *buf = 0;\n    }\n}\n\n#if 0\n//%\nTValue floatAsInt(TValue x) {\n    return doubleToInt(toDouble(x));\n}\n\n//% shim=numops::floatAsInt\nfunction floatAsInt(v: number): number { return 0 }\n\nfunction testInt(i: number) {\n    if (floatAsInt(i) != i)\n        control.panic(101)\n    if (floatAsInt(i + 0.5) != null)\n        control.panic(102)\n    if (floatAsInt(i + 0.00001) != null)\n        control.panic(103)\n}\n\nfunction testFloat(i: number) {\n    if (floatAsInt(i) != null)\n        control.panic(104)\n}\n\nfunction testFloatAsInt() {\n    for (let i = 0; i < 0xffff; ++i) {\n        testInt(i)\n        testInt(-i)\n        testInt(i * 10000)\n        testInt(i << 12)\n        testInt(i + 0x3fff0001)\n        testInt(-i - 0x3fff0002)\n        testFloat(i + 0x3fffffff + 1)\n        testFloat((i + 10000) * 1000000)\n    }\n}\n#endif\n\nString toString(TValue v) {\n    ValType t = valType(v);\n\n    if (t == ValType::String) {\n        return (String)v;\n    } else if (t == ValType::Number) {\n        char buf[64];\n\n        if (isInt(v)) {\n            itoa(numValue(v), buf);\n            return mkStringCore(buf);\n        }\n\n        if (v == TAG_NAN)\n            return (String)(void *)sNaN;\n\n        auto x = toDouble(v);\n\n#ifdef PXT_BOX_DEBUG\n        if (x == (int)x) {\n            itoa((int)x, buf);\n            return mkStringCore(buf);\n        }\n#endif\n\n        if (isinf(x)) {\n            if (x < 0)\n                return (String)(void *)sMInf;\n            else\n                return (String)(void *)sInf;\n        } else if (isnan(x)) {\n            return (String)(void *)sNaN;\n        }\n        mycvt(x, buf);\n\n        return mkStringCore(buf);\n    } else if (t == ValType::Function) {\n        return (String)(void *)sFunction;\n    } else {\n        if (v == TAG_UNDEFINED)\n            return (String)(void *)sUndefined;\n        else if (v == TAG_FALSE)\n            return (String)(void *)sFalse;\n        else if (v == TAG_NAN)\n            return (String)(void *)sNaN;\n        else if (v == TAG_TRUE)\n            return (String)(void *)sTrue;\n        else if (v == TAG_NULL)\n            return (String)(void *)sNull;\n        return (String)(void *)sObject;\n    }\n}\n\n} // namespace numops\n\nnamespace Math_ {\n//%\nTNumber pow(TNumber x, TNumber y) {\n#ifdef PXT_POWI\n    // regular pow() from math.h is 4k of code, but it can\n    // also be expressed as exp(y * log(x)) which is less\n    // performant than pow() but doesn't increase code size\n    double dx = toDouble(x);\n    double dy = toDouble(y);\n\n    // shortcut to integer pow if y is an integer\n    if (::floor(dy) == dy) {\n        return fromDouble(__builtin_powi(dx, dy));\n    }\n    if (dx > 0) {\n        return fromDouble(::exp(dy * ::log(dx)));\n    }\n    if (dx == 0) {\n        if (dy < 0) {\n            // positive infinity\n            return fromDouble(HUGE_VAL);\n        }\n        return x;\n    }\n    return fromDouble(::log(dx));\n#else\n    return fromDouble(::pow(toDouble(x), toDouble(y)));\n#endif\n}\n\nNUMBER randomDouble() {\n    return getRandom(UINT_MAX) / ((NUMBER)UINT_MAX + 1) +\n           getRandom(0xffffff) / ((NUMBER)UINT_MAX * 0xffffff);\n}\n\n//%\nTNumber random() {\n    return fromDouble(randomDouble());\n}\n\n//%\nTNumber randomRange(TNumber min, TNumber max) {\n    if (isInt(min) && isInt(max)) {\n        int mini = numValue(min);\n        int maxi = numValue(max);\n        if (mini > maxi) {\n            int temp = mini;\n            mini = maxi;\n            maxi = temp;\n        }\n        if (maxi == mini)\n            return fromInt(mini);\n        else\n            return fromInt(mini + getRandom(maxi - mini));\n    } else {\n        auto mind = toDouble(min);\n        auto maxd = toDouble(max);\n        if (mind > maxd) {\n            auto temp = mind;\n            mind = maxd;\n            maxd = temp;\n        }\n        if (maxd == mind)\n            return fromDouble(mind);\n        else {\n            return fromDouble(mind + randomDouble() * (maxd - mind));\n        }\n    }\n}\n\n#define SINGLE(op) return fromDouble(::op(toDouble(x)));\n\n//%\nTNumber log(TNumber x){SINGLE(log)}\n\n//%\nTNumber log10(TNumber x){SINGLE(log10)}\n\n//%\nTNumber floor(TNumber x){SINGLE(floor)}\n\n//%\nTNumber ceil(TNumber x){SINGLE(ceil)}\n\n//%\nTNumber trunc(TNumber x){SINGLE(trunc)}\n\n//%\nTNumber round(TNumber x) {\n    // In C++, round(-1.5) == -2, while in JS, round(-1.5) == -1. Align to the JS convention for\n    // consistency between simulator and device. The following does rounding with ties (x.5) going\n    // towards positive infinity.\n    return fromDouble(::floor(toDouble(x) + 0.5));\n}\n\n//%\nint imul(int x, int y) {\n    return x * y;\n}\n\n//%\nint idiv(int x, int y) {\n    return x / y;\n}\n} // namespace Math_\n\nnamespace Array_ {\nRefCollection *mk() {\n    auto r = NEW_GC(RefCollection);\n    MEMDBG(\"mkColl: => %p\", r);\n    return r;\n}\nint length(RefCollection *c) {\n    return c->length();\n}\nvoid setLength(RefCollection *c, int newLength) {\n    c->setLength(newLength);\n}\nvoid push(RefCollection *c, TValue x) {\n    c->head.push(x);\n}\nTValue pop(RefCollection *c) {\n    return c->head.pop();\n}\nTValue getAt(RefCollection *c, int x) {\n    return c->head.get(x);\n}\nvoid setAt(RefCollection *c, int x, TValue y) {\n    c->head.set(x, y);\n}\nTValue removeAt(RefCollection *c, int x) {\n    return c->head.remove(x);\n}\nvoid insertAt(RefCollection *c, int x, TValue value) {\n    c->head.insert(x, value);\n}\nint indexOf(RefCollection *c, TValue x, int start) {\n    auto data = c->head.getData();\n    auto len = c->head.getLength();\n    for (unsigned i = 0; i < len; i++) {\n        if (pxt::eq_bool(data[i], x)) {\n            return (int)i;\n        }\n    }\n    return -1;\n}\nbool removeElement(RefCollection *c, TValue x) {\n    int idx = indexOf(c, x, 0);\n    if (idx >= 0) {\n        decr(removeAt(c, idx));\n        return 1;\n    }\n    return 0;\n}\n} // namespace Array_\n\nnamespace pxt {\nint debugFlags;\n\n//%\nvoid *ptrOfLiteral(int offset);\n\n#ifdef PXT_VM\nunsigned programSize() {\n    return 0;\n}\n#else\n//%\nunsigned programSize() {\n    return bytecode[17] * 8;\n}\n#endif\n\nvoid deepSleep() __attribute__((weak));\n//%\nvoid deepSleep() {}\n\nint *getBootloaderConfigData() __attribute__((weak));\nint *getBootloaderConfigData() {\n    return NULL;\n}\n\n//%\nint getConfig(int key, int defl) {\n#ifdef PXT_VM\n    if (!vmImg)\n        return defl;\n    int *cfgData = vmImg->configData;\n#else\n    int *cfgData = NULL;\n    if (bytecode) {\n        cfgData = *(int **)&bytecode[18];\n    } else {\n        // This happens when getConfig() is called before the TypeScript\n        // program starts (exec_binary()). One example is overriding heap size with:\n        // namespace userconfig { export const SYSTEM_HEAP_BYTES = 10000 }\n        unsigned *pc = (unsigned *)functionsAndBytecode;\n        if (*pc++ == 0x4210) {\n            uint16_t *bcode = *((uint16_t **)pc++);\n            cfgData = *(int **)&bcode[18];\n        }\n    }\n#endif\n\n    if (cfgData) {\n        for (int i = 0;; i += 2) {\n            if (cfgData[i] == key)\n                return cfgData[i + 1];\n            if (cfgData[i] == 0)\n                break;\n        }\n    }\n\n    cfgData = getBootloaderConfigData();\n\n    if (cfgData) {\n        for (int i = 0;; i += 2) {\n            if (cfgData[i] == key)\n                return cfgData[i + 1];\n            if (cfgData[i] == 0)\n                break;\n        }\n    }\n\n    return defl;\n}\n\n} // namespace pxt\n\nnamespace pxtrt {\n//%\nTValue ldlocRef(RefRefLocal *r) {\n    return r->v;\n}\n\n//%\nvoid stlocRef(RefRefLocal *r, TValue v) {\n    r->v = v;\n}\n\n//%\nRefRefLocal *mklocRef() {\n    auto r = NEW_GC(RefRefLocal);\n    MEMDBG(\"mklocRef: => %p\", r);\n    return r;\n}\n\n// Store a captured local in a closure. It returns the action, so it can be chained.\n//%\nRefAction *stclo(RefAction *a, int idx, TValue v) {\n    // DBG(\"STCLO \"); a->print(); DBG(\"@%d = %p\\n\", idx, (void*)v);\n    a->stCore(idx, v);\n    return a;\n}\n\n//%\nvoid panic(int code) {\n    soft_panic(code);\n}\n\n//%\nString emptyToNull(String s) {\n    if (!s || IS_EMPTY(s))\n        return NULL;\n    return s;\n}\n\n//%\nint ptrToBool(TValue p) {\n    if (p) {\n        decr(p);\n        return 1;\n    } else {\n        return 0;\n    }\n}\n\nRefMap *mkMap() {\n    auto r = NEW_GC(RefMap);\n    MEMDBG(\"mkMap: => %p\", r);\n    return r;\n}\n\nTValue mapGetByString(RefMap *map, String key) {\n    int i = map->findIdx(key);\n    if (i < 0) {\n        return 0;\n    }\n    return map->values.get(i);\n}\n\n#ifdef PXT_VM\n#define IFACE_MEMBER_NAMES vmImg->ifaceMemberNames\n#else\n#define IFACE_MEMBER_NAMES *(uintptr_t **)&bytecode[22]\n#endif\n\nint lookupMapKey(String key) {\n    auto arr = IFACE_MEMBER_NAMES;\n    auto len = *arr++;\n    int l = 1U; // skip index 0 - it's invalid\n    int r = (int)len - 1;\n    auto ikey = (uintptr_t)key;\n    if (arr[l] <= ikey && ikey <= arr[r]) {\n        while (l <= r) {\n            auto m = (l + r) >> 1;\n            if (arr[m] == ikey)\n                return m;\n            else if (arr[m] < ikey)\n                l = m + 1;\n            else\n                r = m - 1;\n        }\n    } else {\n        while (l <= r) {\n            int m = (l + r) >> 1;\n            auto cmp = String_::compare((String)arr[m], key);\n            if (cmp == 0)\n                return m;\n            else if (cmp < 0)\n                l = m + 1;\n            else\n                r = m - 1;\n        }\n    }\n    return 0;\n}\n\nTValue mapGet(RefMap *map, unsigned key) {\n    auto arr = (String *)IFACE_MEMBER_NAMES;\n    auto r = mapGetByString(map, arr[key + 1]);\n    map->unref();\n    return r;\n}\n\nvoid mapSetByString(RefMap *map, String key, TValue val) {\n    int i = map->findIdx(key);\n    if (i < 0) {\n        map->keys.push((TValue)key);\n        map->values.push(val);\n    } else {\n        map->values.set(i, val);\n    }\n}\n\nvoid mapSet(RefMap *map, unsigned key, TValue val) {\n    auto arr = (String *)IFACE_MEMBER_NAMES;\n    mapSetByString(map, arr[key + 1], val);\n    decr(val);\n    map->unref();\n}\n\n//\n// Debugger\n//\n\n// This is only to be called once at the beginning of lambda function\n//%\nvoid *getGlobalsPtr() {\n#ifdef DEVICE_GROUP_ID_USER\n    fiber_set_group(DEVICE_GROUP_ID_USER);\n#endif\n\n    return globals;\n}\n\n//%\nvoid runtimeWarning(String s) {\n    // noop for now\n}\n} // namespace pxtrt\n#endif\n\nnamespace pxt {\n\nvoid doNothing() {}\n\n//%\nValType valType(TValue v) {\n    if (isTagged(v)) {\n        if (!v)\n            return ValType::Undefined;\n\n        if (isInt(v) || v == TAG_NAN)\n            return ValType::Number;\n        if (v == TAG_TRUE || v == TAG_FALSE)\n            return ValType::Boolean;\n        else if (v == TAG_NULL)\n            return ValType::Object;\n        else {\n            oops(1);\n            return ValType::Object;\n        }\n#ifdef PXT64\n    } else if (isDouble(v)) {\n        return ValType::Number;\n#endif\n    } else {\n        auto vt = getVTable((RefObject *)v);\n        if (vt->magic == VTABLE_MAGIC)\n            return vt->objectType;\n        else\n            return ValType::Object;\n    }\n}\n\nPXT_DEF_STRING(sObjectTp, \"object\")\nPXT_DEF_STRING(sBooleanTp, \"boolean\")\nPXT_DEF_STRING(sStringTp, \"string\")\nPXT_DEF_STRING(sNumberTp, \"number\")\nPXT_DEF_STRING(sFunctionTp, \"function\")\nPXT_DEF_STRING(sUndefinedTp, \"undefined\")\n\n//% expose\nString typeOf(TValue v) {\n    switch (valType(v)) {\n    case ValType::Undefined:\n        return (String)sUndefinedTp;\n    case ValType::Boolean:\n        return (String)sBooleanTp;\n    case ValType::Number:\n        return (String)sNumberTp;\n    case ValType::String:\n        return (String)sStringTp;\n    case ValType::Object:\n        return (String)sObjectTp;\n    case ValType::Function:\n        return (String)sFunctionTp;\n    default:\n        oops(2);\n        return 0;\n    }\n}\n\n// Maybe in future we will want separate print methods; for now ignore\nvoid anyPrint(TValue v) {\n    if (valType(v) == ValType::Object) {\n        if (isRefCounted(v)) {\n            auto o = (RefObject *)v;\n            auto vt = getVTable(o);\n            auto meth = ((RefObjectMethod)vt->methods[1]);\n            if ((void *)meth == (void *)&anyPrint)\n                DMESG(\"[RefObject vt=%p cl=%d sz=%d]\", o->vtable, vt->classNo, vt->numbytes);\n            else\n                meth(o);\n        } else {\n            DMESG(\"[Native %p]\", v);\n        }\n    } else {\n#ifndef X86_64\n        String s = numops::toString(v);\n        DMESG(\"[%s %p = %s]\", pxt::typeOf(v)->getUTF8Data(), v, s->getUTF8Data());\n        decr((TValue)s);\n#endif\n    }\n}\n\nstatic void dtorDoNothing() {}\n\n#define PRIM_VTABLE(name, objectTp, tp, szexpr)                                                    \\\n    static uint32_t name##_size(tp *p) {                                                           \\\n        return TOWORDS(sizeof(tp) + szexpr);                                                       \\\n    }                                                                                              \\\n    DEF_VTABLE(name##_vt, tp, objectTp, (void *)&dtorDoNothing, (void *)&anyPrint, 0,              \\\n               (void *)&name##_size)\n\n#define NOOP ((void)0)\n\n#define STRING_VT(name, fix, scan, gcsize, data, utfsize, length, dataAt)                          \\\n    static uint32_t name##_gcsize(BoxedString *p) {                                                \\\n        return TOWORDS(sizeof(void *) + (gcsize));                                                 \\\n    }                                                                                              \\\n    static void name##_gcscan(BoxedString *p) {                                                    \\\n        scan;                                                                                      \\\n    }                                                                                              \\\n    static const char *name##_data(BoxedString *p) {                                               \\\n        fix;                                                                                       \\\n        return data;                                                                               \\\n    }                                                                                              \\\n    static uint32_t name##_utfsize(BoxedString *p) {                                               \\\n        fix;                                                                                       \\\n        return utfsize;                                                                            \\\n    }                                                                                              \\\n    static uint32_t name##_length(BoxedString *p) {                                                \\\n        fix;                                                                                       \\\n        return length;                                                                             \\\n    }                                                                                              \\\n    static const char *name##_dataAt(BoxedString *p, uint32_t idx) {                               \\\n        fix;                                                                                       \\\n        return dataAt;                                                                             \\\n    }                                                                                              \\\n    DEF_VTABLE(name##_vt, BoxedString, ValType::String, (void *)&dtorDoNothing, (void *)&anyPrint, \\\n               (void *)&name##_gcscan, (void *)&name##_gcsize, (void *)&name##_data,               \\\n               (void *)&name##_utfsize, (void *)&name##_length, (void *)&name##_dataAt)\n\nvoid gcMarkArray(void *data);\nvoid gcScan(TValue v);\n\n#if PXT_UTF8\nstatic const char *skipLookup(BoxedString *p, uint32_t idx, int packed) {\n    if (idx > p->skip.length)\n        return NULL;\n    auto ent = idx / PXT_STRING_SKIP_INCR;\n    auto data = packed ? PXT_SKIP_DATA_PACK(p) : PXT_SKIP_DATA_IND(p);\n    auto size = p->skip.size;\n    if (ent) {\n        auto off = packed ? p->skip_pack.list[ent - 1] : p->skip.list[ent - 1];\n        data += off;\n        size -= off;\n        idx &= PXT_STRING_SKIP_INCR - 1;\n    }\n    return utf8Skip(data, size, idx);\n}\n\nextern LLSegment workQueue;\n\nstatic uint32_t fixSize(BoxedString *p, uint32_t *len) {\n    uint32_t tlen = 0;\n    uint32_t sz = 0;\n    if (workQueue.getLength())\n        oops(81);\n    workQueue.push((TValue)p);\n    while (workQueue.getLength()) {\n        p = (BoxedString *)workQueue.pop();\n        if (IS_CONS(p)) {\n            workQueue.push((TValue)p->cons.right);\n            workQueue.push((TValue)p->cons.left);\n        } else {\n            tlen += p->getLength();\n            sz += p->getUTF8Size();\n        }\n    }\n    *len = tlen;\n    return sz;\n}\n\nstatic void fixCopy(BoxedString *p, char *dst) {\n    if (workQueue.getLength())\n        oops(81);\n\n    workQueue.push((TValue)p);\n    while (workQueue.getLength()) {\n        p = (BoxedString *)workQueue.pop();\n        if (IS_CONS(p)) {\n            workQueue.push((TValue)p->cons.right);\n            workQueue.push((TValue)p->cons.left);\n        } else {\n            auto sz = p->getUTF8Size();\n            memcpy(dst, p->getUTF8Data(), sz);\n            dst += sz;\n        }\n    }\n}\n\n// switches CONS representation into skip list representation\n// does not switch representation of CONS' children\nstatic void fixCons(BoxedString *r) {\n    uint32_t length = 0;\n    auto sz = fixSize(r, &length);\n    auto numSkips = length / PXT_STRING_SKIP_INCR;\n    // allocate first, while [r] still holds references to its children\n    // because allocation might trigger GC\n    auto data = (uint16_t *)gcAllocateArray(numSkips * 2 + sz + 1);\n    // copy, while [r] is still cons\n    fixCopy(r, (char *)(data + numSkips));\n    // now, set [r] up properly\n    r->vtable = &string_skiplist16_vt;\n    r->skip.size = sz;\n    r->skip.length = length;\n    r->skip.list = data;\n    setupSkipList(r, NULL, 0);\n}\n#endif\n\nSTRING_VT(string_inline_ascii, NOOP, NOOP, 2 + p->ascii.length + 1, p->ascii.data, p->ascii.length,\n          p->ascii.length, idx <= p->ascii.length ? p->ascii.data + idx : NULL)\n#if PXT_UTF8\nSTRING_VT(string_inline_utf8, NOOP, NOOP, 2 + p->utf8.size + 1, p->utf8.data, p->utf8.size,\n          utf8Len(p->utf8.data, p->utf8.size), utf8Skip(p->utf8.data, p->utf8.size, idx))\nSTRING_VT(string_skiplist16, NOOP, if (p->skip.list) gcMarkArray(p->skip.list), 2 * sizeof(void *),\n          PXT_SKIP_DATA_IND(p), p->skip.size, p->skip.length, skipLookup(p, idx, 0))\nSTRING_VT(string_skiplist16_packed, NOOP, NOOP,\n          2 + 2 + PXT_NUM_SKIP_ENTRIES(p) * 2 + p->skip.size + 1, PXT_SKIP_DATA_PACK(p),\n          p->skip.size, p->skip.length, skipLookup(p, idx, 1))\nSTRING_VT(string_cons, fixCons(p), (gcScan((TValue)p->cons.left), gcScan((TValue)p->cons.right)),\n          2 * sizeof(void *), PXT_SKIP_DATA_IND(p), p->skip.size, p->skip.length,\n          skipLookup(p, idx, 0))\n#endif\n\nPRIM_VTABLE(number, ValType::Number, BoxedNumber, 0)\nPRIM_VTABLE(buffer, ValType::Object, BoxedBuffer, p->length)\n// PRIM_VTABLE(action, ValType::Function, RefAction, )\n\nvoid failedCast(TValue v, void *addr) {\n    DMESG(\"failed type check for %p @%p\", v, addr);\n    auto vt = getAnyVTable(v);\n    if (vt) {\n        DMESG(\"VT %p - objtype %d classNo %d\", vt, vt->objectType, vt->classNo);\n    }\n\n    int code;\n    if (v == TAG_NULL)\n        code = PANIC_CAST_FROM_NULL;\n    else\n        code = PANIC_CAST_FIRST + (int)valType(v);\n    soft_panic(code);\n}\n\nvoid missingProperty(TValue v) {\n    DMESG(\"missing property on %p\", v);\n    soft_panic(PANIC_MISSING_PROPERTY);\n}\n\n#ifdef PXT_PROFILE\nstruct PerfCounter *perfCounters;\n\nstruct PerfCounterInfo {\n    uint32_t numPerfCounters;\n    char *perfCounterNames[0];\n};\n\n#define PERF_INFO ((PerfCounterInfo *)(((uintptr_t *)bytecode)[13]))\n\nvoid initPerfCounters() {\n    auto n = PERF_INFO->numPerfCounters;\n    perfCounters = new PerfCounter[n];\n    memset(perfCounters, 0, n * sizeof(PerfCounter));\n}\n\nvoid dumpPerfCounters() {\n    auto info = PERF_INFO;\n    DMESG(\"calls,us,name\");\n    for (uint32_t i = 0; i < info->numPerfCounters; ++i) {\n        auto c = &perfCounters[i];\n        DMESG(\"%d,%d,%s\", c->numstops, c->value, info->perfCounterNames[i]);\n        c->value = 0;\n        c->numstops = 0;\n    }\n}\n\nvoid startPerfCounter(PerfCounters n) {\n    if (!perfCounters)\n        return;\n    auto c = &perfCounters[(uint32_t)n];\n    if (c->start)\n        oops(50);\n    c->start = PERF_NOW();\n}\n\nvoid stopPerfCounter(PerfCounters n) {\n    if (!perfCounters)\n        return;\n    auto c = &perfCounters[(uint32_t)n];\n    if (!c->start)\n        oops(51);\n    c->value += ((PERF_NOW() - c->start) & PERF_NOW_MASK) / PERF_NOW_SCALE;\n    c->start = 0;\n    c->numstops++;\n}\n#endif\n\n// Exceptions\n\n#ifndef PXT_EXN_CTX\n#define PXT_EXN_CTX() getThreadContext()\n#endif\n\ntypedef void (*RestoreStateType)(TryFrame *, ThreadContext *);\n#ifndef pxt_restore_exception_state\n#define pxt_restore_exception_state ((RestoreStateType)(((uintptr_t *)bytecode)[14]))\n#endif\n\n//%\nTryFrame *beginTry() {\n    auto ctx = PXT_EXN_CTX();\n    auto frame = (TryFrame *)app_alloc(sizeof(TryFrame));\n    frame->parent = ctx->tryFrame;\n    ctx->tryFrame = frame;\n    return frame;\n}\n\n//% expose\nvoid endTry() {\n    auto ctx = PXT_EXN_CTX();\n    auto f = ctx->tryFrame;\n    if (!f)\n        oops(51);\n    ctx->tryFrame = f->parent;\n    app_free(f);\n}\n\n//% expose\nvoid throwValue(TValue v) {\n    auto ctx = PXT_EXN_CTX();\n    auto f = ctx->tryFrame;\n    if (!f) {\n        DMESG(\"unhandled exception, value:\");\n        anyPrint(v);\n        soft_panic(PANIC_UNHANDLED_EXCEPTION);\n    }\n    ctx->tryFrame = f->parent;\n    TryFrame copy = *f;\n    app_free(f);\n    ctx->thrownValue = v;\n    pxt_restore_exception_state(&copy, ctx);\n}\n\n//% expose\nTValue getThrownValue() {\n    auto ctx = PXT_EXN_CTX();\n    auto v = ctx->thrownValue;\n    ctx->thrownValue = TAG_NON_VALUE;\n    if (v == TAG_NON_VALUE)\n        oops(51);\n    return v;\n}\n\n//% expose\nvoid endFinally() {\n    auto ctx = PXT_EXN_CTX();\n    if (ctx->thrownValue == TAG_NON_VALUE)\n        return;\n    throwValue(getThrownValue());\n}\n\n// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function\nuint32_t hash_fnv1(const void *data, unsigned len) {\n    const uint8_t *d = (const uint8_t *)data;\n    uint32_t h = 0x811c9dc5;\n    while (len--)\n        h = (h * 0x1000193) ^ *d++;\n    return h;\n}\n\n// redefined in melody.cpp\n__attribute__((weak)) int redirectSamples(int16_t *dst, int numsamples, int samplerate) {\n    return 0;\n}\n\n} // namespace pxt\n","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const 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\n    UInt32LE = 11,\n    UInt32BE = 12,\n    Float32LE = 13,\n    Float64LE = 14,\n    Float32BE = 15,\n    Float64BE = 16,\n    }\n\n\n    declare const enum PerfCounters {\n    GC = 0,\n    }\n\n// Auto-generated. Do not edit. Really.\n","eventcontext.ts":"namespace control {\n    /**\n     * Run code when a registered event happens.\n     * @param id the event compoent id\n     * @param value the event value to match\n     */\n    //% weight=20 blockGap=8 blockId=\"control_on_event\" block=\"on event|from %src|with value %value\"\n    //% blockExternalInputs=1\n    //% help=\"control/on-event\"\n    export function onEvent(src: number, value: number, handler: () => void, flags = 16) { // EVENT_LISTENER_DEFAULT_FLAGS\n        const ctx = control.eventContext();\n        if (!ctx)\n            control.internalOnEvent(src, value, handler, flags);\n        else\n            ctx.registerHandler(src, value, handler, flags);\n    }\n\n    export class FrameCallback {\n        order: number\n        handler: () => void\n    }\n\n    class EventHandler {\n        constructor(\n            public src: number,\n            public value: number,\n            public handler: () => void,\n            public flags: number\n        ) { }\n\n        register() {\n            control.internalOnEvent(this.src, this.value, () => {\n                if (this.handler) this.handler();\n            }, this.flags)\n        }\n\n        unregister() {\n            control.internalOnEvent(this.src, this.value, doNothing, this.flags);\n        }\n    }\n\n    function doNothing() { }\n\n\n\n    export class EventContext {\n        private handlers: EventHandler[];\n        private frameCallbacks: FrameCallback[];\n        private frameWorker: number;\n        private framesInSample: number;\n        private timeInSample: number;\n        private lastPerfDump: number;\n        public deltaTimeMillis: number;\n        private prevTimeMillis: number;\n        private idleCallbacks: (() => void)[];\n\n        static lastStats: string;\n        static onStats: (stats: string) => void;\n\n        constructor() {\n            this.handlers = [];\n            this.framesInSample = 0;\n            this.timeInSample = 0;\n            this.deltaTimeMillis = 0;\n            this.frameWorker = 0;\n            this.idleCallbacks = undefined;\n            if (!EventContext.lastStats) {\n                EventContext.lastStats = \"\";\n            }\n        }\n\n        get deltaTime() {\n            return this.deltaTimeMillis / 1000;\n        }\n\n        private runCallbacks() {\n            control.enablePerfCounter(\"all frame callbacks\")\n\n            let loopStart = control.millis()\n            this.deltaTimeMillis = loopStart - this.prevTimeMillis;\n            this.prevTimeMillis = loopStart;\n            for (let f of this.frameCallbacks) {\n                f.handler()\n            }\n            const now = control.millis()\n            let runtime = now - loopStart\n            this.timeInSample += runtime\n            this.framesInSample++\n            if (this.timeInSample > 1000 || this.framesInSample > 30) {\n                const realTimeInSample = now - this.lastPerfDump\n                this.lastPerfDump = now\n                const fps = this.framesInSample / (this.timeInSample / 1000);\n                EventContext.lastStats = `fps:${Math.round(fps)}`;\n                if (fps < 99)\n                    EventContext.lastStats += \".\" + (Math.round(fps * 10) % 10)\n                if (control.profilingEnabled()) {\n                    control.dmesg(`${(fps * 100) | 0}/100 fps - ${this.framesInSample} frames (${this.timeInSample}ms/${realTimeInSample}ms)`)\n                    control.gc()\n                    control.dmesgPerfCounters()\n                }\n                this.timeInSample = 0\n                this.framesInSample = 0\n            }\n            let delay = Math.max(1, 20 - runtime)\n\n            return delay\n        }\n\n        private runningCallbacks: boolean;\n        private registerFrameCallbacks() {\n            if (!this.frameCallbacks) return;\n\n            const worker = this.frameWorker;\n            control.runInParallel(() => {\n                if (this.runningCallbacks) {\n                    // this context is still running in a different fiber;\n                    // delay until the other fiber doing so has ceased.\n                    pauseUntil(() => !this.runningCallbacks);\n                }\n                this.runningCallbacks = true;\n\n                this.framesInSample = 0;\n                this.timeInSample = 0;\n                this.deltaTimeMillis = 0;\n                this.prevTimeMillis = control.millis();\n\n                while (worker == this.frameWorker) {\n                    let delay = this.runCallbacks()\n                    pause(delay)\n                }\n\n                this.runningCallbacks = false;\n            })\n        }\n\n        register() {\n            for (const h of this.handlers)\n                h.register();\n            this.registerFrameCallbacks();\n        }\n\n        unregister() {\n            for (const h of this.handlers)\n                h.unregister();\n            this.frameWorker++;\n        }\n\n        registerFrameHandler(order: number, handler: () => void): FrameCallback {\n            if (!this.frameCallbacks) {\n                this.frameCallbacks = [];\n                this.registerFrameCallbacks();\n            }\n\n            const fn = new FrameCallback()\n            fn.order = order\n            fn.handler = handler\n            for (let i = 0; i < this.frameCallbacks.length; ++i) {\n                if (this.frameCallbacks[i].order > order) {\n                    this.frameCallbacks.insertAt(i, fn)\n                    return fn;\n                }\n            }\n            this.frameCallbacks.push(fn);\n            return fn;\n        }\n\n        unregisterFrameHandler(fn: FrameCallback) {\n            if (!fn || !this.frameCallbacks) return;\n            const i = this.frameCallbacks.indexOf(fn);\n            if (i > -1)\n                this.frameCallbacks.splice(i, 1);\n        }\n\n        registerHandler(src: number, value: number, handler: () => void, flags: number) {\n            // already there?\n            for (const h of this.handlers) {\n                if (h.src == src && h.value == value) {\n                    h.flags = flags;\n                    h.handler = handler;\n                    return;\n                }\n            }\n            // register and push\n            const hn = new EventHandler(src, value, handler, flags);\n            this.handlers.push(hn);\n            hn.register();\n        }\n\n        addIdleHandler(handler: () => void) {\n            if (!this.idleCallbacks) {\n                this.idleCallbacks = [];\n                this.registerHandler(15/*DAL.DEVICE_ID_SCHEDULER*/, 2/*DAL.DEVICE_SCHEDULER_EVT_IDLE*/, () => this.runIdleHandler(), 16);\n            }\n            this.idleCallbacks.push(handler);\n        }\n\n        removeIdleHandler(handler: () => void) {\n            if (handler && this.idleCallbacks)\n                this.idleCallbacks.removeElement(handler);\n        }\n\n        private runIdleHandler() {\n            if (this.idleCallbacks) {\n                const ics = this.idleCallbacks.slice(0);\n                ics.forEach(ic => ic());\n            }\n        }\n    }\n    let eventContexts: EventContext[];\n\n    /**\n     * Gets the current event context if any\n     */\n    export function eventContext(): EventContext {\n        return eventContexts ? eventContexts[eventContexts.length - 1] : undefined;\n    }\n\n    /**\n     * Pushes a new event context and clears all handlers\n     */\n    export function pushEventContext(): EventContext {\n        if (!eventContexts)\n            eventContexts = [];\n\n        // unregister previous context\n        const ctx = eventContext();\n        if (ctx) ctx.unregister();\n        // register again\n        const n = new EventContext();\n        eventContexts.push(n);\n        return n;\n    }\n\n    /**\n     * Pops the current event context and restore handlers if any previous context\n     */\n    export function popEventContext() {\n        if (!eventContexts) return;\n\n        // clear current context\n        const ctx = eventContexts.pop();\n        if (!ctx) return;\n        ctx.unregister();\n\n        // register old context again\n        const context = eventContexts[eventContexts.length - 1];\n        if (context)\n            context.register();\n        else\n            eventContexts = undefined;\n    }\n\n    let _idleCallbacks: (() => void)[];\n    /**\n     * Registers a function to run when the device is idling\n     * @param handler\n    */\n    export function onIdle(handler: () => void) {\n        if (!handler) return;\n\n        const ctx = eventContext();\n        if (ctx) ctx.addIdleHandler(handler);\n        else {\n            if (!_idleCallbacks) {\n                _idleCallbacks = [];\n                control.runInBackground(function () {\n                    while (_idleCallbacks) {\n                        _idleCallbacks.slice(0).forEach(cb => cb());\n                        pause(20);\n                    }\n                })\n                /*\n                control.internalOnEvent(\n                    15. // DAL.DEVICE_ID_SCHEDULER\n                    2, // DAL.DEVICE_SCHEDULER_EVT_IDLE\n                    function() {\n                        pins.LED.digitalWrite(on = !on);\n                        if (_idleCallbacks)\n                            _idleCallbacks.slice(0).forEach(cb => cb());\n                    }, 192); // MESSAGE_BUS_LISTENER_IMMEDIATE\n                */\n            }\n            _idleCallbacks.push(handler);\n        }\n    }\n\n    export function removeIdleHandler(handler: () => void) {\n        if (!handler) return;\n        const ctx = eventContext();\n        if (ctx) ctx.removeIdleHandler(handler);\n        else if (_idleCallbacks) _idleCallbacks.removeElement(handler);\n    }\n}","fixed.ts":"interface Fx8 {\n    _dummyFx8: string;\n}\n\nfunction Fx8(v: number) {\n    return ((v * 256) | 0) as any as Fx8\n}\n\nnamespace Fx {\n    export const zeroFx8 = 0 as any as Fx8\n    export const oneHalfFx8 = 128 as any as Fx8\n    export const oneFx8 = 256 as any as Fx8\n    export const twoFx8 = 512 as any as Fx8\n\n    export function neg(a: Fx8) {\n        return (-(a as any as number)) as any as Fx8\n    }\n    export function toIntShifted(a: Fx8, n: number) {\n        return (a as any as number) >> (n + 8)\n    }\n    export function add(a: Fx8, b: Fx8) {\n        return ((a as any as number) + (b as any as number)) as any as Fx8\n    }\n    export function iadd(a: number, b: Fx8) {\n        return ((a << 8) + (b as any as number)) as any as Fx8\n    }\n    export function sub(a: Fx8, b: Fx8) {\n        return ((a as any as number) - (b as any as number)) as any as Fx8\n    }\n    export function mul(a: Fx8, b: Fx8) {\n        return (Math.imul((a as any as number), (b as any as number)) >> 8) as any as Fx8\n    }\n    export function imul(a: Fx8, b: number) {\n        return Math.imul((a as any as number), (b as any as number)) as any as Fx8\n    }\n    export function div(a: Fx8, b: Fx8) {\n        return Math.idiv((a as any as number) << 8, b as any as number) as any as Fx8\n    }\n    export function idiv(a: Fx8, b: number) {\n        return Math.idiv((a as any as number), b) as any as Fx8\n    }\n    export function compare(a: Fx8, b: Fx8) {\n        return (a as any as number) - (b as any as number)\n    }\n    export function abs(a: Fx8) {\n        if ((a as any as number) < 0)\n            return (-(a as any as number)) as any as Fx8\n        else\n            return a\n    }\n    export function min(a: Fx8, b: Fx8) {\n        if (a < b)\n            return a\n        else\n            return b\n    }\n    export function max(a: Fx8, b: Fx8) {\n        if (a > b)\n            return a\n        else\n            return b\n    }\n    export function floor(v: Fx8): Fx8 {\n        return ((v as any as number) & ~0xff) as any as Fx8;\n    }\n    export function ceil(v: Fx8): Fx8 {\n        return (v as any as number) & 0xff ? Fx.floor(Fx.add(v, Fx.oneFx8)) : v;\n    }\n    export function leftShift(a: Fx8, n: number) {\n        return (a as any as number << n) as any as Fx8\n    }\n    export function rightShift(a: Fx8, n: number) {\n        return (a as any as number >> n) as any as Fx8\n    }\n    export function toInt(v: Fx8) {\n        return ((v as any as number) + 128) >> 8\n    }\n    export function toFloat(v: Fx8) {\n        return (v as any as number) / 256\n    }\n}","forever.ts":"// implemented in game","gc.cpp":"#include \"pxtbase.h\"\n\n#ifndef GC_BLOCK_SIZE\n#define GC_BLOCK_SIZE (1024 * 16)\n#endif\n\n#ifndef GC_MAX_ALLOC_SIZE\n#define GC_MAX_ALLOC_SIZE (GC_BLOCK_SIZE - 16)\n#endif\n\n#ifndef GC_ALLOC_BLOCK\n#define GC_ALLOC_BLOCK xmalloc\n#endif\n\n#ifdef PXT64\n#define HIGH_SHIFT 48\n#define BYTES_TO_WORDS(x) ((x) >> 3)\n#define WORDS_TO_BYTES(x) ((x) << 3)\n#define ALIGN_TO_WORD(x) (((x) + 7) & (~7ULL))\n#define VAR_BLOCK_WORDS(vt) ((uint32_t)(uint64_t)(vt) >> 2)\n#else\n#define HIGH_SHIFT 28\n#define BYTES_TO_WORDS(x) ((x) >> 2)\n#define WORDS_TO_BYTES(x) ((x) << 2)\n#define ALIGN_TO_WORD(x) (((x) + 3) & (~3U))\n#define VAR_BLOCK_WORDS(vt) (((uint32_t)(vt) << 4) >> (4 + 2))\n#endif\n\n#define FREE_MASK (1ULL << (HIGH_SHIFT + 3))\n#define ARRAY_MASK (1ULL << (HIGH_SHIFT + 2))\n#define PERMA_MASK (1ULL << (HIGH_SHIFT + 1))\n#define MARKED_MASK 0x1\n#define ANY_MARKED_MASK 0x3\n\n// the bit operations should be faster than loading large constants\n#define IS_FREE(vt) ((uintptr_t)(vt) >> (HIGH_SHIFT + 3))\n#define IS_ARRAY(vt) (((uintptr_t)(vt) >> (HIGH_SHIFT + 2)) & 1)\n#define IS_PERMA(vt) (((uintptr_t)(vt) >> (HIGH_SHIFT + 1)) & 1)\n#define IS_VAR_BLOCK(vt) ((uintptr_t)(vt) >> (HIGH_SHIFT + 2))\n#define IS_MARKED(vt) ((uintptr_t)(vt)&MARKED_MASK)\n#define IS_LIVE(vt) (IS_MARKED(vt) || (((uintptr_t)(vt) >> (HIGH_SHIFT)) == 0x6))\n\n//#define PXT_GC_DEBUG 1\n#ifndef PXT_GC_CHECKS\n#define PXT_GC_CHECKS 1\n#endif\n//#define PXT_GC_STRESS 1\n\n//#define PXT_GC_CHECKS 1\n\n#define MARK(v)                                                                                    \\\n    do {                                                                                           \\\n        GC_CHECK(inGCArea(v), 42);                                                                 \\\n        *(uintptr_t *)(v) |= MARKED_MASK;                                                          \\\n    } while (0)\n\n#ifdef PXT_GC_DEBUG\n#define LOG DMESG\n#define VLOG DMESG\n#define VVLOG DMESG\n#else\n#define LOG NOLOG\n#define VLOG NOLOG\n#define VVLOG NOLOG\n#endif\n\n#ifdef PXT_GC_CHECKS\n#define GC_CHECK(cond, code)                                                                       \\\n    if (!(cond))                                                                                   \\\n    oops(code)\n#else\n#define GC_CHECK(cond, code) ((void)0)\n#endif\n\nnamespace pxt {\n\n// keep in sync with base/control.ts, function gcStats()\nstruct GCStats {\n    uint32_t numGC;\n    uint32_t numBlocks;\n    uint32_t totalBytes;\n    uint32_t lastFreeBytes;\n    uint32_t lastMaxBlockBytes;\n    uint32_t minFreeBytes;\n};\n\nstatic GCStats gcStats;\n\n//% expose\nBuffer getGCStats() {\n    return mkBuffer((uint8_t *)&gcStats, sizeof(gcStats));\n}\n\n//%\nvoid popThreadContext(ThreadContext *ctx);\n//%\nThreadContext *pushThreadContext(void *sp, void *endSP);\n\nunsigned RefRecord_gcsize(RefRecord *r) {\n    VTable *tbl = getVTable(r);\n    return BYTES_TO_WORDS(tbl->numbytes);\n}\n\n#ifdef PXT_GC_THREAD_LIST\nThreadContext *threadContexts;\n#endif\n\n#define IN_GC_ALLOC 1\n#define IN_GC_COLLECT 2\n#define IN_GC_FREEZE 4\n#define IN_GC_PREALLOC 8\n\n#ifndef PXT_VM\nstatic TValue *tempRoot;\nstatic uint8_t tempRootLen;\n#endif\n\nuint8_t inGC;\n\nvoid popThreadContext(ThreadContext *ctx) {\n#ifndef PXT_VM\n    VLOG(\"pop: %p\", ctx);\n\n    if (!ctx)\n        return;\n\n    auto n = ctx->stack.next;\n    if (n) {\n        VLOG(\"seg %p\", n);\n        ctx->stack.top = n->top;\n        ctx->stack.bottom = n->bottom;\n        ctx->stack.next = n->next;\n        app_free(n);\n    } else {\n#ifdef PXT_GC_THREAD_LIST\n        if (ctx->next)\n            ctx->next->prev = ctx->prev;\n        if (ctx->prev)\n            ctx->prev->next = ctx->next;\n        else {\n            if (threadContexts != ctx)\n                oops(41);\n            threadContexts = ctx->next;\n            if (threadContexts)\n                threadContexts->prev = NULL;\n        }\n#endif\n        app_free(ctx);\n        setThreadContext(NULL);\n    }\n#endif\n}\n\n#define ALLOC(tp) (tp *)app_alloc(sizeof(tp))\n\nThreadContext *pushThreadContext(void *sp, void *endSP) {\n#ifdef PXT_VM\n    return NULL;\n#else\n    if (PXT_IN_ISR())\n        target_panic(PANIC_CALLED_FROM_ISR);\n\n    auto curr = getThreadContext();\n    tempRoot = (TValue *)endSP;\n    tempRootLen = (uintptr_t *)sp - (uintptr_t *)endSP;\n    if (curr) {\n#ifdef PXT_GC_THREAD_LIST\n#ifdef PXT_GC_DEBUG\n        auto ok = false;\n        for (auto p = threadContexts; p; p = p->next)\n            if (p == curr) {\n                ok = true;\n                break;\n            }\n        if (!ok)\n            oops(49);\n#endif\n#endif\n        auto seg = ALLOC(StackSegment);\n        VLOG(\"stack %p / %p\", seg, curr);\n        seg->top = curr->stack.top;\n        seg->bottom = curr->stack.bottom;\n        seg->next = curr->stack.next;\n        curr->stack.next = seg;\n    } else {\n        curr = ALLOC(ThreadContext);\n        LOG(\"push: %p\", curr);\n        curr->globals = globals;\n        curr->stack.next = NULL;\n        curr->thrownValue = TAG_NON_VALUE;\n        curr->tryFrame = NULL;\n\n#ifdef PXT_GC_THREAD_LIST\n        curr->next = threadContexts;\n        curr->prev = NULL;\n        if (curr->next)\n            curr->next->prev = curr;\n        threadContexts = curr;\n#endif\n        setThreadContext(curr);\n    }\n    tempRootLen = 0;\n    curr->stack.bottom = sp;\n    curr->stack.top = NULL;\n    return curr;\n#endif\n}\n\nclass RefBlock : public RefObject {\n  public:\n    RefBlock *nextFree;\n};\n\nstruct GCBlock {\n    GCBlock *next;\n    uint32_t blockSize;\n    RefObject data[0];\n};\n\nstruct PendingArray {\n    PendingArray *next;\n    TValue *data;\n    unsigned len;\n};\n\n#define PENDING_ARRAY_THR 100\n\nstatic PendingArray *pendingArrays;\nstatic LLSegment gcRoots;\nLLSegment workQueue; // (ab)used by consString making\nstatic GCBlock *firstBlock;\nstatic RefBlock *firstFree;\nstatic uint8_t *midPtr;\n\nstatic bool inGCArea(void *ptr) {\n    for (auto block = firstBlock; block; block = block->next) {\n        if ((void *)block->data <= ptr && ptr < (void *)((uint8_t *)block->data + block->blockSize))\n            return true;\n    }\n    return false;\n}\n\n#define NO_MAGIC(vt) ((VTable *)vt)->magic != VTABLE_MAGIC\n#define VT(p) (*(uintptr_t *)(p))\n#define SKIP_PROCESSING(p)                                                                         \\\n    (isReadOnly(p) || (VT(p) & (ANY_MARKED_MASK | ARRAY_MASK)) || NO_MAGIC(VT(p)))\n\nvoid gcMarkArray(void *data) {\n    auto segBl = (uintptr_t *)data - 1;\n    GC_CHECK(!IS_MARKED(VT(segBl)), 47);\n    MARK(segBl);\n}\n\nvoid gcScan(TValue v) {\n    if (SKIP_PROCESSING(v))\n        return;\n    MARK(v);\n    workQueue.push(v);\n}\n\nvoid gcScanMany(TValue *data, unsigned len) {\n    // VLOG(\"scan: %p %d\", data, len);\n    for (unsigned i = 0; i < len; ++i) {\n        auto v = data[i];\n        // VLOG(\"psh: %p %d %d\", v, isReadOnly(v), (*(uint32_t *)v & 1));\n        if (SKIP_PROCESSING(v))\n            continue;\n        MARK(v);\n        workQueue.push(v);\n        if (workQueue.getLength() > PENDING_ARRAY_THR) {\n            i++;\n            // store rest of the work for later, when we have cleared the queue\n            auto pa = (PendingArray *)xmalloc(sizeof(PendingArray));\n            pa->next = pendingArrays;\n            pa->data = data + i;\n            pa->len = len - i;\n            pendingArrays = pa;\n            break;\n        }\n    }\n}\n\nvoid gcScanSegment(Segment &seg) {\n    auto data = seg.getData();\n    if (!data)\n        return;\n    VVLOG(\"seg %p %d\", data, seg.getLength());\n    gcMarkArray(data);\n    gcScanMany(data, seg.getLength());\n}\n\n#define getScanMethod(vt) ((RefObjectMethod)(((VTable *)(vt))->methods[2]))\n#define getSizeMethod(vt) ((RefObjectSizeMethod)(((VTable *)(vt))->methods[3]))\n\nvoid gcProcess(TValue v) {\n    if (SKIP_PROCESSING(v))\n        return;\n    VVLOG(\"gcProcess: %p\", v);\n    MARK(v);\n    auto scan = getScanMethod(VT(v) & ~ANY_MARKED_MASK);\n    if (scan)\n        scan((RefObject *)v);\n    for (;;) {\n        while (workQueue.getLength()) {\n            auto curr = (RefObject *)workQueue.pop();\n            VVLOG(\" - %p\", curr);\n            scan = getScanMethod(curr->vt() & ~ANY_MARKED_MASK);\n            if (scan)\n                scan(curr);\n        }\n        if (pendingArrays) {\n            auto pa = pendingArrays;\n            pendingArrays = pa->next;\n            auto data = pa->data;\n            auto len = pa->len;\n            xfree(pa);\n            gcScanMany(data, len);\n        } else {\n            break;\n        }\n    }\n}\n\nstatic void mark(int flags) {\n#ifdef PXT_GC_DEBUG\n    flags |= 2;\n#endif\n    auto data = gcRoots.getData();\n    auto len = gcRoots.getLength();\n    if (flags & 2) {\n        DMESG(\"--MARK\");\n        DMESG(\"RP:%p/%d\", data, len);\n    }\n    for (unsigned i = 0; i < len; ++i) {\n        auto d = data[i];\n        if ((uintptr_t)d & 1) {\n            d = *(TValue *)((uintptr_t)d & ~1);\n        }\n        gcProcess(d);\n    }\n\n#ifdef PXT_GC_THREAD_LIST\n    for (auto ctx = threadContexts; ctx; ctx = ctx->next) {\n        gcProcess(ctx->thrownValue);\n        for (auto seg = &ctx->stack; seg; seg = seg->next) {\n            auto ptr = (TValue *)threadAddressFor(ctx, seg->top);\n            auto end = (TValue *)threadAddressFor(ctx, seg->bottom);\n            VLOG(\"mark: %p - %p\", ptr, end);\n            while (ptr < end) {\n                gcProcess(*ptr++);\n            }\n        }\n    }\n#else\n    gcProcessStacks(flags);\n#endif\n\n    if (globals) {\n#ifdef PXT_VM\n        auto nonPtrs = vmImg->infoHeader->nonPointerGlobals;\n#else\n        auto nonPtrs = bytecode[21];\n#endif\n        len = getNumGlobals() - nonPtrs;\n        data = globals + nonPtrs;\n        if (flags & 2)\n            DMESG(\"RG:%p/%d\", data, len);\n        VLOG(\"globals: %p %d\", data, len);\n        for (unsigned i = 0; i < len; ++i) {\n            gcProcess(*data++);\n        }\n    }\n\n#ifndef PXT_VM\n    data = tempRoot;\n    len = tempRootLen;\n    for (unsigned i = 0; i < len; ++i) {\n        gcProcess(*data++);\n    }\n#endif\n}\n\nstatic uint32_t getObjectSize(RefObject *o) {\n    auto vt = o->vt() & ~ANY_MARKED_MASK;\n    uint32_t r;\n    GC_CHECK(vt != 0, 49);\n    if (IS_VAR_BLOCK(vt)) {\n        r = VAR_BLOCK_WORDS(vt);\n    } else {\n        auto sz = getSizeMethod(vt);\n        // GC_CHECK(0x2000 <= (intptr_t)sz && (intptr_t)sz <= 0x100000, 47);\n        r = sz(o);\n    }\n    GC_CHECK(1 <= r && (r <= BYTES_TO_WORDS(GC_MAX_ALLOC_SIZE) || IS_FREE(vt)), 41);\n    return r;\n}\n\nstatic void setupFreeBlock(GCBlock *curr) {\n    gcStats.numBlocks++;\n    gcStats.totalBytes += curr->blockSize;\n    curr->data[0].setVT(FREE_MASK | (TOWORDS(curr->blockSize) << 2));\n    ((RefBlock *)curr->data)[0].nextFree = firstFree;\n    firstFree = (RefBlock *)curr->data;\n    midPtr = (uint8_t *)curr->data + curr->blockSize / 4;\n}\n\nstatic void linkFreeBlock(GCBlock *curr) {\n    // blocks need to be sorted by address for midPtr to work\n    if (!firstBlock || curr < firstBlock) {\n        curr->next = firstBlock;\n        firstBlock = curr;\n    } else {\n        for (auto p = firstBlock; p; p = p->next) {\n            if (!p->next || curr < p->next) {\n                curr->next = p->next;\n                p->next = curr;\n                break;\n            }\n        }\n    }\n}\n\nvoid gcPreAllocateBlock(uint32_t sz) {\n    auto curr = (GCBlock *)GC_ALLOC_BLOCK(sz);\n    curr->blockSize = sz - sizeof(GCBlock);\n    LOG(\"GC pre-alloc: %p\", curr);\n    GC_CHECK((curr->blockSize & 3) == 0, 40);\n    setupFreeBlock(curr);\n    linkFreeBlock(curr);\n}\n\nstatic GCBlock *allocateBlockCore() {\n    int sz = GC_BLOCK_SIZE;\n    void *dummy = NULL;\n#ifdef GC_GET_HEAP_SIZE\n    if (firstBlock) {\n#ifdef GC_STACK_BASE\n        if (!firstBlock->next) {\n            int memSize = getConfig(CFG_RAM_BYTES, 0);\n            int codalEnd = GC_STACK_BASE;\n            // round up to 1k - there is sometimes a few bytes below the stack\n            codalEnd = (codalEnd + 1024) & ~1023;\n            int codalSize = codalEnd & 0xffffff;\n            sz = memSize - codalSize - 4;\n            if (sz > 0) {\n                auto curr = (GCBlock *)codalEnd;\n                curr->blockSize = sz - sizeof(GCBlock);\n                return curr;\n            }\n        }\n#endif\n        gc(2); // dump roots\n        soft_panic(PANIC_GC_OOM);\n    }\n    auto lowMem = getConfig(CFG_LOW_MEM_SIMULATION_KB, 0);\n    auto sysHeapSize = getConfig(CFG_SYSTEM_HEAP_BYTES, 4 * 1024);\n    auto heapSize = GC_GET_HEAP_SIZE();\n    DMESG(\"heap: %d (minus %d sys bytes)\", heapSize, sysHeapSize);\n    sz = heapSize - sysHeapSize;\n    if (lowMem) {\n        auto memIncrement = 32 * 1024;\n        // get the memory size - assume it's increment of 32k,\n        // and we don't statically allocate more than 32k\n        auto memSize = ((heapSize + memIncrement - 1) / memIncrement) * memIncrement;\n        int fillerSize = memSize - lowMem * 1024;\n        if (fillerSize > 0) {\n            dummy = GC_ALLOC_BLOCK(fillerSize);\n            sz -= fillerSize;\n        }\n    }\n#endif\n    auto curr = (GCBlock *)GC_ALLOC_BLOCK(sz);\n    curr->blockSize = sz - sizeof(GCBlock);\n    // make sure reference to allocated block is stored somewhere, otherwise\n    // GCC optimizes out the call to GC_ALLOC_BLOCK\n    curr->data[4].setVT((uintptr_t)dummy);\n    return curr;\n}\n\n__attribute__((noinline)) static void allocateBlock() {\n    auto curr = allocateBlockCore();\n    DMESG(\"GC block %db @ %p\", curr->blockSize, curr);\n    GC_CHECK((curr->blockSize & 3) == 0, 40);\n    setupFreeBlock(curr);\n    linkFreeBlock(curr);\n}\n\nstatic void sweep(int flags) {\n    RefBlock *prevFreePtr = NULL;\n    uint32_t freeSize = 0;\n    uint32_t totalSize = 0;\n    uint32_t maxFreeBlock = 0;\n    firstFree = NULL;\n\n    gcStats.numGC++;\n\n    for (auto h = firstBlock; h; h = h->next) {\n        auto d = h->data;\n        auto words = BYTES_TO_WORDS(h->blockSize);\n        auto end = d + words;\n        totalSize += words;\n        VLOG(\"sweep: %p - %p\", d, end);\n        while (d < end) {\n            if (IS_LIVE(d->vtable)) {\n                VVLOG(\"Live %p\", d);\n                d->setVT(d->vt() & ~MARKED_MASK);\n                d += getObjectSize(d);\n            } else {\n                auto start = (RefBlock *)d;\n                while (d < end) {\n                    if (IS_FREE(d->vtable)) {\n                        VVLOG(\"Free %p\", d);\n                    } else if (IS_LIVE(d->vtable)) {\n                        break;\n                    } else if (IS_ARRAY(d->vtable)) {\n                        VVLOG(\"Dead Arr %p\", d);\n                    } else {\n                        VVLOG(\"Dead Obj %p\", d);\n                        GC_CHECK(d->vtable->magic == VTABLE_MAGIC, 41);\n                        d->destroyVT();\n                        VVLOG(\"destroyed\");\n                    }\n                    d += getObjectSize(d);\n                }\n                auto sz = d - (RefObject *)start;\n                freeSize += sz;\n                if (sz > (int)maxFreeBlock)\n                    maxFreeBlock = sz;\n#ifdef PXT_GC_CHECKS\n                memset((void *)start, 0xff, WORDS_TO_BYTES(sz));\n#endif\n                start->setVT((sz << 2) | FREE_MASK);\n                if (sz > 1) {\n                    start->nextFree = NULL;\n                    if (!prevFreePtr) {\n                        firstFree = start;\n                    } else {\n                        prevFreePtr->nextFree = start;\n                    }\n                    prevFreePtr = start;\n                }\n            }\n        }\n    }\n\n    if (midPtr) {\n        uint32_t currFree = 0;\n#ifdef PXT_ESP32\n        auto limit = freeSize * 1 / 4;\n#else\n        auto limit = freeSize * 1 / 2;\n#endif\n        for (auto p = firstFree; p; p = p->nextFree) {\n            auto len = VAR_BLOCK_WORDS(p->vtable);\n            currFree += len;\n            if (currFree > limit) {\n                midPtr = (uint8_t *)p + ((limit - currFree + len) << 2);\n                break;\n            }\n        }\n    }\n\n    freeSize = WORDS_TO_BYTES(freeSize);\n    totalSize = WORDS_TO_BYTES(totalSize);\n    maxFreeBlock = WORDS_TO_BYTES(maxFreeBlock);\n\n    gcStats.lastFreeBytes = freeSize;\n    gcStats.lastMaxBlockBytes = maxFreeBlock;\n\n    if (gcStats.minFreeBytes == 0 || gcStats.minFreeBytes > freeSize)\n        gcStats.minFreeBytes = freeSize;\n\n    if (flags & 1)\n        DMESG(\"GC %d/%d free; %d maxBlock\", freeSize, totalSize, maxFreeBlock);\n    else\n        LOG(\"GC %d/%d free; %d maxBlock\", freeSize, totalSize, maxFreeBlock);\n\n#ifndef GC_GET_HEAP_SIZE\n    // if the heap is 90% full, allocate a new block\n    if (freeSize * 10 <= totalSize) {\n        allocateBlock();\n    }\n#endif\n}\n\nvoid gc(int flags) {\n    startPerfCounter(PerfCounters::GC);\n    GC_CHECK(!(inGC & IN_GC_COLLECT), 40);\n    inGC |= IN_GC_COLLECT;\n    VLOG(\"GC mark\");\n    mark(flags);\n    VLOG(\"GC sweep\");\n    sweep(flags);\n    VLOG(\"GC done\");\n    stopPerfCounter(PerfCounters::GC);\n    inGC &= ~IN_GC_COLLECT;\n}\n\n#ifdef GC_GET_HEAP_SIZE\nextern \"C\" void free(void *ptr) {\n    if (!ptr)\n        return;\n    if (inGCArea(ptr))\n        app_free(ptr);\n    else\n        xfree(ptr);\n}\n\nextern \"C\" void *malloc(size_t sz) {\n    if (PXT_IN_ISR() || inGC)\n        return xmalloc(sz);\n    else\n        return app_alloc(sz);\n}\n\nextern \"C\" void *realloc(void *ptr, size_t size) {\n    if (inGCArea(ptr)) {\n        void *mem = malloc(size);\n\n        if (ptr != NULL && mem != NULL) {\n            auto r = (uintptr_t *)ptr;\n            GC_CHECK((r[-1] >> (HIGH_SHIFT + 1)) == 3, 41);\n            size_t blockSize = VAR_BLOCK_WORDS(r[-1]);\n            memcpy(mem, ptr, min(blockSize * sizeof(void *), size));\n            free(ptr);\n        }\n\n        return mem;\n    } else {\n        return device_realloc(ptr, size);\n    }\n}\n#endif\n\nvoid *gcAllocateArray(int numbytes) {\n    numbytes = ALIGN_TO_WORD(numbytes);\n    numbytes += sizeof(void *);\n    auto r = (uintptr_t *)gcAllocate(numbytes);\n    *r = ARRAY_MASK | (TOWORDS(numbytes) << 2);\n    return r + 1;\n}\n\nstatic void *gcAllocAt(void *hint, int numbytes) {\n    gc(0);\n    size_t numwords = BYTES_TO_WORDS(ALIGN_TO_WORD(numbytes));\n\n    for (auto p = firstFree; p; p = p->nextFree) {\n        GC_CHECK(!isReadOnly((TValue)p), 49);\n        auto vt = p->vtable;\n        GC_CHECK(IS_FREE(vt), 43);\n        int offset = BYTES_TO_WORDS((uint8_t *)hint - (uint8_t *)p);\n        int left = (int)(VAR_BLOCK_WORDS(vt) - numwords - offset);\n        // we give ourselves some space here, so we don't get some strange overlaps\n        if (offset >= 8 && left >= 8) {\n            auto nf = (RefBlock *)((void **)p + numwords + offset);\n            nf->setVT((left << 2) | FREE_MASK);\n            nf->nextFree = p->nextFree;\n            p->nextFree = nf;\n            p->setVT((offset << 2) | FREE_MASK);\n            p = (RefBlock *)((void **)p + offset);\n            p->setVT(0);\n            return p;\n        }\n    }\n\n    return NULL;\n}\n\nvoid *app_alloc_at(void *at, int numbytes) {\n    if (numbytes < 8)\n        return NULL;\n    if (!at)\n        return NULL;\n\n    numbytes = ALIGN_TO_WORD(numbytes) + sizeof(void *);\n    auto r = (uintptr_t *)gcAllocAt((uintptr_t *)at - 1, numbytes);\n    if (!r)\n        return NULL;\n    *r = ARRAY_MASK | PERMA_MASK | (TOWORDS(numbytes) << 2);\n    gc(0);\n    return r + 1;\n}\n\nvoid *app_alloc(int numbytes) {\n    if (!numbytes)\n        return NULL;\n\n    // gc(0);\n    auto r = (uintptr_t *)gcAllocateArray(numbytes);\n    r[-1] |= PERMA_MASK;\n    return r;\n}\n\nvoid *app_free(void *ptr) {\n    auto r = (uintptr_t *)ptr;\n    GC_CHECK((r[-1] >> (HIGH_SHIFT + 1)) == 3, 41);\n    r[-1] |= FREE_MASK;\n    return r;\n}\n\nvoid gcFreeze() {\n    inGC |= IN_GC_FREEZE;\n}\n\nvoid gcReset() {\n    inGC &= ~IN_GC_FREEZE;\n\n    gcRoots.setLength(0);\n\n    if (inGC)\n        oops(41);\n\n    if (workQueue.getLength())\n        oops(41);\n\n    memset(&gcStats, 0, sizeof(gcStats));\n    firstFree = NULL;\n    for (auto h = firstBlock; h; h = h->next) {\n        setupFreeBlock(h);\n    }\n}\n\n#ifdef PXT_VM\nvoid gcPreStartup() {\n    inGC |= IN_GC_PREALLOC;\n}\n\nvoid gcStartup() {\n    inGC &= ~IN_GC_PREALLOC;\n}\n#endif\n\nvoid *gcAllocate(int numbytes) {\n    size_t numwords = BYTES_TO_WORDS(ALIGN_TO_WORD(numbytes));\n    // VVLOG(\"alloc %d bytes %d words\", numbytes, numwords);\n\n    if (numbytes > GC_MAX_ALLOC_SIZE)\n        soft_panic(PANIC_GC_TOO_BIG_ALLOCATION);\n\n    if (PXT_IN_ISR() || (inGC & (IN_GC_PREALLOC | IN_GC_ALLOC | IN_GC_COLLECT | IN_GC_FREEZE)))\n        target_panic(PANIC_CALLED_FROM_ISR);\n\n    inGC |= IN_GC_ALLOC;\n\n#if defined(PXT_GC_CHECKS) && !defined(PXT_VM)\n    {\n        auto curr = getThreadContext();\n        if (curr && !curr->stack.top)\n            oops(46);\n    }\n#endif\n\n#ifdef PXT_GC_STRESS\n    gc(0);\n#endif\n\n    for (int i = 0;; ++i) {\n        RefBlock *prev = NULL;\n        for (auto p = firstFree; p; p = p->nextFree) {\n            VVLOG(\"p=%p\", p);\n            if (i == 0 && (uint8_t *)p > midPtr) {\n                VLOG(\"past midptr %p; gc\", midPtr);\n                break;\n            }\n            GC_CHECK(!isReadOnly((TValue)p), 49);\n            auto vt = p->vtable;\n            if (!IS_FREE(vt))\n                oops(43);\n            int left = (int)(VAR_BLOCK_WORDS(vt) - numwords);\n            VVLOG(\"%p %d - %d = %d\", (void *)vt, (int)VAR_BLOCK_WORDS(vt), (int)numwords, left);\n            if (left >= 0) {\n                auto nf = (RefBlock *)((void **)p + numwords);\n                auto nextFree = p->nextFree; // p and nf can overlap when allocating 4 bytes\n                // VVLOG(\"nf=%p nef=%p\", nf, nextFree);\n                if (left)\n                    nf->setVT((left << 2) | FREE_MASK);\n                if (left >= 2) {\n                    nf->nextFree = nextFree;\n                } else {\n                    nf = nextFree;\n                }\n                if (prev)\n                    prev->nextFree = nf;\n                else\n                    firstFree = nf;\n                p->setVT(0);\n                VVLOG(\"GC=>%p %d %p -> %p,%p\", p, numwords, nf, nf ? nf->nextFree : 0,\n                      nf ? (void *)nf->vtable : 0);\n                GC_CHECK(!nf || !nf->nextFree || !isReadOnly((TValue)nf->nextFree), 48);\n                inGC &= ~IN_GC_ALLOC;\n                return p;\n            }\n            prev = p;\n        }\n\n        // we didn't find anything, try GC\n        if (i == 0)\n            gc(0);\n        // GC didn't help, try new block\n        else if (i == 1) {\n            DMESG(\"gcAlloc(%d) (%d/%d free; %d max block) -> new block\", numbytes,\n                  gcStats.lastFreeBytes, gcStats.totalBytes, gcStats.lastMaxBlockBytes);\n            allocateBlock();\n        } else\n            // the block allocated was apparently too small\n            soft_panic(PANIC_GC_OOM);\n    }\n}\n\nstatic void removePtr(TValue v) {\n    int len = gcRoots.getLength();\n    auto data = gcRoots.getData();\n    // scan from the back, as this is often used as a stack\n    for (int i = len - 1; i >= 0; --i) {\n        if (data[i] == v) {\n            if (i == len - 1) {\n                gcRoots.pop();\n            } else {\n                data[i] = gcRoots.pop();\n            }\n            return;\n        }\n    }\n    oops(40);\n}\n\nvoid registerGC(TValue *root, int numwords) {\n    if (!numwords)\n        return;\n\n    if (numwords > 1) {\n        while (numwords-- > 0) {\n            registerGC(root++, 1);\n        }\n        return;\n    }\n\n    gcRoots.push((TValue)((uintptr_t)root | 1));\n}\n\nvoid unregisterGC(TValue *root, int numwords) {\n    if (!numwords)\n        return;\n    if (numwords > 1) {\n        while (numwords-- > 0) {\n            unregisterGC(root++, 1);\n        }\n        return;\n    }\n\n    removePtr((TValue)((uintptr_t)root | 1));\n}\n\nvoid registerGCPtr(TValue ptr) {\n    if (isReadOnly(ptr))\n        return;\n    gcRoots.push(ptr);\n}\n\nvoid unregisterGCPtr(TValue ptr) {\n    if (isReadOnly(ptr))\n        return;\n    removePtr(ptr);\n}\n\nvoid RefImage::scan(RefImage *t) {\n    gcScan((TValue)t->buffer);\n}\n\nvoid RefCollection::scan(RefCollection *t) {\n    gcScanSegment(t->head);\n}\n\nvoid RefAction::scan(RefAction *t) {\n    gcScanMany(t->fields, t->len);\n}\n\nvoid RefRefLocal::scan(RefRefLocal *t) {\n    gcScan(t->v);\n}\n\nvoid RefMap::scan(RefMap *t) {\n    gcScanSegment(t->keys);\n    gcScanSegment(t->values);\n}\n\nvoid RefRecord_scan(RefRecord *r) {\n    VTable *tbl = getVTable(r);\n    gcScanMany(r->fields, BYTES_TO_WORDS(tbl->numbytes - sizeof(RefRecord)));\n}\n\n#define SIZE(off) TOWORDS(sizeof(*t) + (off))\n\nunsigned RefImage::gcsize(RefImage *t) {\n    return SIZE(0);\n}\n\nunsigned RefCollection::gcsize(RefCollection *t) {\n    return SIZE(0);\n}\n\nunsigned RefAction::gcsize(RefAction *t) {\n    return SIZE(WORDS_TO_BYTES(t->len));\n}\n\nunsigned RefRefLocal::gcsize(RefRefLocal *t) {\n    return SIZE(0);\n}\n\nunsigned RefMap::gcsize(RefMap *t) {\n    return SIZE(0);\n}\n\n} // namespace pxt\n","gcstats.ts":"namespace control {\n    //% shim=pxt::getGCStats\n    function getGCStats(): Buffer {\n        return null\n    }\n\n    export interface GCStats {\n        numGC: number;\n        numBlocks: number;\n        totalBytes: number;\n        lastFreeBytes: number;\n        lastMaxBlockBytes: number;\n        minFreeBytes: number;\n    }\n\n    /**\n     * Get various statistics about the garbage collector (GC)\n     */\n    export function gcStats(): GCStats {\n        const buf = getGCStats()\n        if (!buf)\n            return null\n        let off = 0\n        const res: any = {}\n\n        addField(\"numGC\")\n        addField(\"numBlocks\")\n        addField(\"totalBytes\")\n        addField(\"lastFreeBytes\")\n        addField(\"lastMaxBlockBytes\")\n        addField(\"minFreeBytes\")\n\n        return res\n\n        function addField(name: string) {\n            res[name] = buf.getNumber(NumberFormat.UInt32LE, off)\n            off += 4\n        }\n    }    \n}","interval.ts":"namespace control {\n    export enum IntervalMode {\n        Interval,\n        Timeout,\n        Immediate\n    }\n\n    let _intervals: Interval[] = undefined;\n    class Interval {\n\n        id: number;\n        func: () => void;\n        delay: number;\n        mode: IntervalMode;\n\n        constructor(func: () => void, delay: number, mode: IntervalMode) {\n            this.id = _intervals.length == 0\n                ? 1 : _intervals[_intervals.length - 1].id + 1;\n            this.func = func;\n            this.delay = delay;\n            this.mode = mode;\n            _intervals.push(this);\n\n            control.runInParallel(() => this.work());\n        }\n\n        work() {\n            // execute\n            switch (this.mode) {\n                case IntervalMode.Immediate:\n                case IntervalMode.Timeout:\n                    if (this.delay > 0)\n                        pause(this.delay); // timeout\n                    if (this.delay >= 0) // immediate, timeout\n                        this.func();\n                    break;\n                case IntervalMode.Interval:\n                    while (this.delay > 0) {\n                        pause(this.delay);\n                        // might have been cancelled during this duration\n                        if (this.delay > 0)\n                            this.func();\n                    }\n                    break;\n            }\n            // remove from interval array\n            _intervals.removeElement(this);\n        }\n\n        cancel() {\n            this.delay = -1;\n        }\n    }\n\n    export function setInterval(func: () => void, delay: number, mode: IntervalMode): number {\n        if (!func || delay < 0) return 0;\n        if (!_intervals) _intervals = [];\n        const interval = new Interval(func, delay, mode);\n        return interval.id;\n    }\n\n    export function clearInterval(intervalId: number, mode: IntervalMode): void {\n        if (!_intervals) return;\n        for (let i = 0; i < _intervals.length; ++i) {\n            const it = _intervals[i];\n            if (it.id == intervalId && it.mode == mode) {\n                it.cancel();\n                break;\n            }\n        }\n    }\n}","json.ts":"namespace JSON {\n    export function parseIntRadix(s: string, base?: number) {\n        if (base == null || base == 10) {\n            return parseFloat(s) | 0\n        }\n\n        let m = false\n        let r = 0\n        for (let i = 0; i < s.length; ++i) {\n            let c = s.charCodeAt(i)\n            if (c == 0x20 || c == 10 || c == 13 || c == 9)\n                continue\n            if (r == 0 && !m && c == 0x2d) {\n                m = true\n                continue\n            }\n\n            let v = -1\n            if (0x30 <= c && c <= 0x39)\n                v = c - 0x30\n            else {\n                c |= 0x20\n                if (0x61 <= c && c <= 0x7a)\n                    v = c - 0x61 + 10\n            }\n\n            if (0 <= v && v < base) {\n                r *= base\n                r += v\n            } else {\n                return undefined\n            }\n        }\n\n        return m ? -r : r\n    }\n\n\n    class Parser {\n        ptr: number\n        s: string\n        errorMsg: string\n\n        error(msg: string) {\n            if (!this.errorMsg) {\n                this.errorMsg = msg + \" at position \" + this.ptr\n                this.ptr = this.s.length\n            }\n        }\n\n        skipWS() {\n            for (; ;) {\n                const c = this.nextChar()\n                if (c == 0x20 || c == 0x0a || c == 0x0d || c == 0x09) {\n                    // OK\n                } else {\n                    this.ptr--\n                    return c\n                }\n            }\n        }\n\n        nextChar() {\n            if (this.ptr < this.s.length)\n                return this.s.charCodeAt(this.ptr++)\n            return 0\n        }\n\n        doString() {\n            let r = \"\"\n            this.ptr++\n            for (; ;) {\n                const c = this.s.charAt(this.ptr++)\n                if (c == \"\\\"\")\n                    return r\n                if (c == \"\\\\\") {\n                    let q = this.s.charAt(this.ptr++)\n                    if (q == \"b\") q = \"\\b\"\n                    else if (q == \"n\") q = \"\\n\"\n                    else if (q == \"r\") q = \"\\r\"\n                    else if (q == \"t\") q = \"\\t\"\n                    else if (q == \"u\") {\n                        q = String.fromCharCode(parseIntRadix(this.s.slice(this.ptr, this.ptr + 4), 16))\n                        this.ptr += 4\n                    }\n                    r += q\n                } else {\n                    r += c\n                }\n            }\n        }\n\n        doArray(): any[] {\n            const r = []\n            this.ptr++\n            for (; ;) {\n                let c = this.skipWS()\n                if (c == 0x5d) {\n                    this.ptr++\n                    return r\n                }\n                const v = this.value()\n                if (this.errorMsg)\n                    return null\n                r.push(v)\n                c = this.skipWS()\n                if (c == 0x2c) {\n                    this.ptr++\n                    continue\n                }\n                if (c == 0x5d)\n                    continue\n                this.error(\"expecting comma\")\n            }\n        }\n\n        doObject() {\n            const r: any = {}\n            this.ptr++\n            for (; ;) {\n                let c = this.skipWS()\n                if (c == 0x7d) {\n                    this.ptr++\n                    return r\n                }\n                if (c != 0x22) {\n                    this.error(\"expecting key\")\n                    return r\n                }\n                const k = this.doString()\n                c = this.skipWS()\n                if (c != 0x3a) {\n                    this.error(\"expecting colon\")\n                    return r\n                }\n                this.ptr++\n                const v = this.value()\n                if (this.errorMsg)\n                    return null\n                r[k] = v\n                c = this.skipWS()\n                if (c == 0x2c) {\n                    this.ptr++\n                    continue\n                }\n                if (c == 0x7d)\n                    continue\n                this.error(\"expecting comma, got \" + String.fromCharCode(c))\n            }\n        }\n\n        doNumber() {\n            const beg = this.ptr\n            for (; ;) {\n                const c = this.nextChar()\n                if ((0x30 <= c && c <= 0x39) || c == 0x2b || c == 0x2d || c == 0x2e || c == 0x45 || c == 0x65) {\n                    // one more\n                } else {\n                    this.ptr--\n                    break\n                }\n            }\n            const ss = this.s.slice(beg, this.ptr)\n            if (ss.length == 0) {\n                this.error(\"expecting number\")\n                return 0\n            }\n            return parseFloat(ss)\n        }\n\n        checkKw(k: string) {\n            if (this.s.slice(this.ptr, this.ptr + k.length) == k) {\n                this.ptr += k.length\n                return true\n            }\n            return false\n        }\n\n        value() {\n            if (this.errorMsg)\n                return null\n\n            const c = this.skipWS()\n            if (c == 0x7b)\n                return this.doObject()\n            else if (c == 0x5b)\n                return this.doArray()\n            else if ((0x30 <= c && c <= 0x39) || c == 0x2d)\n                return this.doNumber()\n            else if (c == 0x22)\n                return this.doString()\n            else if (c == 0x74 && this.checkKw(\"true\"))\n                return true\n            else if (c == 0x66 && this.checkKw(\"false\"))\n                return false\n            else if (c == 0x6e && this.checkKw(\"null\"))\n                return null\n\n            this.error(\"unexpected token\")\n            return null\n        }\n    }\n\n    class Stringifier {\n        currIndent: string\n        indentStep: string\n        indent: number\n\n        doString(s: string) {\n            let r = \"\\\"\"\n            for (let i = 0; i < s.length; ++i) {\n                let c = s[i]\n                if (c == \"\\n\") c = \"\\\\n\"\n                else if (c == \"\\r\") c = \"\\\\r\"\n                else if (c == \"\\t\") c = \"\\\\t\"\n                else if (c == \"\\b\") c = \"\\\\b\"\n                else if (c == \"\\\\\") c = \"\\\\\\\\\"\n                else if (c == \"\\\"\") c = \"\\\\\\\"\"\n                r += c\n            }\n            return r + \"\\\"\"\n        }\n\n        go(v: any) {\n            const t = typeof v\n            if (t == \"string\")\n                return this.doString(v)\n            else if (t == \"boolean\" || t == \"number\" || v == null)\n                return \"\" + v\n            else if (Array.isArray(v)) {\n                const arr = v as any[]\n                if (arr.length == 0)\n                    return \"[]\"\n                else {\n                    let r = \"[\"\n                    if (this.indent) {\n                        this.currIndent += this.indentStep\n                        r += \"\\n\"\n                    }\n                    for (let i = 0; i < arr.length; ++i) {\n                        r += this.currIndent + this.go(arr[i])\n                        if (i != arr.length - 1)\n                            r += \",\"\n                        if (this.indent)\n                            r += \"\\n\"\n                    }\n                    if (this.indent)\n                        this.currIndent = this.currIndent.slice(this.indent)\n                    r += this.currIndent + \"]\"\n                    return r\n                }\n            } else {\n                const keys = Object.keys(v)\n                if (keys.length == 0)\n                    return \"{}\"\n\n                let r = \"{\"\n                if (this.indent) {\n                    this.currIndent += this.indentStep\n                    r += \"\\n\"\n                }\n                for (let i = 0; i < keys.length; ++i) {\n                    const k = keys[i]\n                    r += this.currIndent + this.doString(k)\n                    if (this.indent)\n                        r += \": \"\n                    else\n                        r += \":\"\n                    r += this.go(v[k])\n                    if (i != keys.length - 1)\n                        r += \",\"\n                    if (this.indent)\n                        r += \"\\n\"\n                }\n                if (this.indent)\n                    this.currIndent = this.currIndent.slice(this.indent)\n                r += this.currIndent + \"}\"\n                return r\n            }\n        }\n    }\n\n    /**\n     * Converts a JavaScript value to a JavaScript Object Notation (JSON) string.\n     * @param value A JavaScript value, usually an object or array, to be converted.\n     * @param replacer Not supported; use null.\n     * @param indent Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.\n     */\n    export function stringify(value: any, replacer: any = null, indent: number = 0) {\n        const ss = new Stringifier()\n        ss.currIndent = \"\"\n        indent |= 0\n        if (indent < 0) indent = 0\n        if (indent > 10) indent = 10\n        ss.indentStep = \"\"\n        ss.currIndent = \"\"\n        ss.indent = indent\n        while (indent-- > 0)\n            ss.indentStep += \" \"\n        return ss.go(value)\n    }\n\n\n    /**\n     * Converts a JavaScript Object Notation (JSON) string into an object.\n     * @param text A valid JSON string.\n     */\n    export function parse(s: string) {\n        const p = new Parser()\n        p.ptr = 0\n        p.s = s\n        const r = p.value()\n        if (p.skipWS()) {\n            p.error(\"excessive input\")\n        }\n        if (p.errorMsg) {\n            control.dmesg(\"Invalid JSON: \" + p.errorMsg)\n            return undefined\n        }\n        return r\n    }\n}\n","loops.cpp":"#include \"pxtbase.h\"\n\nnamespace loops {\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=loops/forever weight=100 afterOnStart=true deprecated=true\n//% blockId=forever_deprecated block=\"forever\" blockAllowMultiple=1\nvoid forever(Action a) {\n    runForever(a);\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=loops/pause weight=99 deprecated=true\n//% async block=\"pause %pause=timePicker|ms\"\n//% blockId=device_pause_deprecated\nvoid pause(int ms) {\n    if (ms < 0) return;\n    sleep_ms(ms);\n}\n\n}","math.ts":"namespace Math {\n\n    export const E = 2.718281828459045;\n    export const LN2 = 0.6931471805599453;\n    export const LN10 = 2.302585092994046;\n    export const LOG2E = 1.4426950408889634;\n    export const LOG10E = 0.4342944819032518;\n    export const PI = 3.141592653589793;\n    export const SQRT1_2 = 0.7071067811865476;\n    export const SQRT2 = 1.4142135623730951;\n\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=math/map weight=10 blockGap=8\n    //% blockId=math_map block=\"map %value|from low %fromLow|high %fromHigh|to low %toLow|high %toHigh\"\n    //% inlineInputMode=inline\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     * Constrains a number to be within a range\n     * @param x the number to constrain, all data types\n     * @param y the lower end of the range, all data types\n     * @param z the upper end of the range, all data types\n     */\n    //% help=math/constrain weight=11 blockGap=8\n    //% blockId=\"math_constrain_value\" block=\"constrain %value|between %low|and %high\"\n    export function constrain(value: number, low: number, high: number): number {\n        return value < low ? low : value > high ? high : value;\n    }\n\n    const b_m16: number[] = [0, 49, 49, 41, 90, 27, 117, 10]\n    /**\n     * Returns the sine of an input angle. This is an 8-bit approximation.\n     * @param theta input angle from 0-255\n     */\n    //% help=math/isin weight=11 advanced=true blockGap=8\n    export function isin(theta: number) {\n        //reference: based on FASTLed's sin approximation method: [https://github.com/FastLED/FastLED](MIT)\n        let offset = theta;\n        if( theta & 0x40 ) {\n            offset = 255 - offset;\n        }\n        offset &= 0x3F; // 0..63\n\n        let secoffset  = offset & 0x0F; // 0..15\n        if( theta & 0x40) secoffset++;\n\n        let section = offset >> 4; // 0..3\n        let s2 = section * 2;\n\n        let b = b_m16[s2];\n        let m16 = b_m16[s2+1];\n        let mx = (m16 * secoffset) >> 4;\n        \n        let y = mx + b;\n        if( theta & 0x80 ) y = -y;\n\n        y += 128;\n\n        return y;\n    }\n\n    /**\n     * Returns the cosine of an input angle. This is an 8-bit approximation. \n     * @param theta input angle from 0-255\n     */\n    //% help=math/icos weight=10 advanced=true blockGap=8\n    export function icos(theta: number) {\n        return isin(theta + 16384);\n    }\n}\n\nnamespace Number {\n    export const EPSILON = 2.220446049250313e-16;\n}","ns.ts":"\n/**\n * Respond to and read data from buttons and sensors.\n */\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\nnamespace input {\n}\n","pause.ts":"/**\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=loops/pause weight=99\n//% async block=\"pause %pause=timePicker|ms\"\n//% blockId=device_pause blockNamespace=\"loops\"\nfunction pause(ms: number): void {\n    loops.pause(ms);\n}\n\n// micro:bit compatibility\n// these functions allow some level of reuse\n// between micro:bit and other maker-style editors\nnamespace basic {\n    export function pause(millis: number) {\n        loops.pause(millis);\n    }\n}","perfcounters.ts":"namespace control {\n    /**\n     * Enable profiling for current function.\n     */\n    //% shim=TD_NOOP shimArgument=perfCounter\n    export function enablePerfCounter(name?: string) { }\n\n    /**\n     * Dump values of profiling performance counters.\n     */\n    //% shim=pxt::dumpPerfCounters\n    export function dmesgPerfCounters() { }\n}\n","poll.ts":"namespace control {\n    class PollEvent {\n        public eid: number;\n        public vid: number;\n        public start: number;\n        public timeOut: number;\n        public condition: () => boolean;\n        public once: boolean;\n        constructor(eid: number, vid: number, start: number, timeOut: number, condition: () => boolean, once: boolean) {\n            this.eid = eid;\n            this.vid = vid;\n            this.start = start;\n            this.timeOut = timeOut;\n            this.condition = condition;\n            this.once = once;\n        }\n    }\n\n    let _pollEventQueue: PollEvent[] = undefined;\n\n    function pollEvents() {\n        while (_pollEventQueue.length > 0) {\n            const now = control.millis();\n            for (let i = 0; i < _pollEventQueue.length; ++i) {\n                const ev = _pollEventQueue[i];\n                if (ev.condition() || (ev.timeOut > 0 && now - ev.start > ev.timeOut)) {\n                    control.raiseEvent(ev.eid, ev.vid);\n                    if (ev.once) {\n                        _pollEventQueue.splice(i, 1);\n                        --i;\n                    }\n                }\n            }\n            pause(50);\n        }\n        // release fiber\n        _pollEventQueue = undefined;\n    }\n\n    export function __queuePollEvent(timeOut: number, condition: () => boolean, handler: () => void) {\n        const ev = new PollEvent(\n            DAL.DEVICE_ID_NOTIFY,\n            control.allocateNotifyEvent(),\n            control.millis(),\n            timeOut,\n            condition,\n            !handler\n        );\n\n        // start polling fiber if needed\n        if (!_pollEventQueue) {\n            _pollEventQueue = [ev];\n            control.runInParallel(pollEvents);\n        }\n        else {\n            // add to the queue\n            _pollEventQueue.push(ev)\n        }\n\n        // register event\n        if (handler)\n            control.onEvent(ev.eid, ev.vid, handler);\n        else // or wait\n            control.waitForEvent(ev.eid, ev.vid);\n    }    \n}\n\n/**\n * Busy wait for a condition to be true\n * @param condition condition to test for\n * @param timeOut if positive, maximum duration to wait for in milliseconds\n */\n//% blockId=\"pxt_pause_until\"\nfunction pauseUntil(condition: () => boolean, timeOut?: number): void {\n    if (!condition || condition()) return; // optimistic path\n    if (!timeOut) timeOut = 0;\n    control.__queuePollEvent(timeOut, condition, undefined);\n}\n","pxt-core.d.ts":"/// <reference no-default-lib=\"true\"/>\n\ninterface Array<T> {\n    /**\n      * Get or set the length of an array. This number is one more than the index of the last element the array.\n      */\n    //% shim=Array_::length weight=84\n    //% blockId=\"lists_length\" block=\"length of %VALUE\" blockBuiltin=true blockNamespace=\"arrays\"\n    length: number;\n\n    /**\n      * Append a new element to an array.\n      * @param items New elements of the Array.\n      */\n    //% help=arrays/push\n    //% shim=Array_::push weight=50\n    //% blockId=\"array_push\" block=\"%list| add value %value| to end\" blockNamespace=\"arrays\"\n    //% group=\"Modify\"\n    push(item: T): void;\n\n    /**\n      * Concatenates the values with another array.\n      * @param arr The other array that is being concatenated with\n      */\n    //% helper=arrayConcat weight=40\n    concat(arr: T[]): T[];\n\n    /**\n      * Remove the last element from an array and return it.\n      */\n    //% help=arrays/pop\n    //% shim=Array_::pop weight=45\n    //% blockId=\"array_pop\" block=\"get and remove last value from %list\" blockNamespace=\"arrays\"\n    //% group=\"Read\"\n    pop(): T;\n\n    /**\n      * Reverse the elements in an array. The first array element becomes the last, and the last array element becomes the first.\n      */\n    //% help=arrays/reverse\n    //% helper=arrayReverse weight=10\n    //% blockId=\"array_reverse\" block=\"reverse %list\" blockNamespace=\"arrays\"\n    //% group=\"Operations\"\n    reverse(): void;\n\n    /**\n      * Remove the first element from an array and return it. This method changes the length of the array.\n      */\n    //% help=arrays/shift\n    //% helper=arrayShift weight=30\n    //% blockId=\"array_shift\" block=\"get and remove first value from %list\" blockNamespace=\"arrays\"\n    //% group=\"Read\"\n    shift(): T;\n\n    /**\n      * Add one element to the beginning of an array and return the new length of the array.\n      * @param element to insert at the start of the Array.\n      */\n    //% help=arrays/unshift\n    //% helper=arrayUnshift weight=25\n    //% blockId=\"array_unshift\" block=\"%list| insert %value| at beginning\" blockNamespace=\"arrays\"\n    //% group=\"Modify\"\n    //unshift(...values:T[]): number; //rest is not supported in our compiler yet.\n    unshift(value: T): number;\n\n    /**\n      * Return 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    //% help=arrays/slice\n    //% helper=arraySlice weight=41 blockNamespace=\"arrays\"\n    slice(start?: number, end?: number): T[];\n\n    /**\n      * Remove 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      * joins all elements of an array into a string and returns this string.\n      * @param sep the string separator\n      */\n    //% helper=arrayJoin weight=40\n    join(sep?: string): string;\n\n    /**\n      * Tests whether at least one element in the array passes the test implemented by the provided function.\n      * @param callbackfn A function that accepts up to two arguments. The some method calls the callbackfn function one time for each element in the array.\n      */\n    //% helper=arraySome weight=40\n    some(callbackfn: (value: T, index: number) => boolean): boolean;\n\n    /**\n      * Tests whether all elements in the array pass the test implemented by the provided function.\n      * @param callbackfn A function that accepts up to two arguments. The every method calls the callbackfn function one time for each element in the array.\n      */\n    //% helper=arrayEvery weight=40\n    every(callbackfn: (value: T, index: number) => boolean): boolean;\n\n    /**\n      * Sort 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      * Call a defined callback function on each element of an array, and return an array containing the results.\n      * @param callbackfn A function that accepts up to two arguments. The map method calls the callbackfn function one time for each element in the array.\n      */\n    //% helper=arrayMap weight=40\n    map<U>(callbackfn: (value: T, index: number) => U): U[];\n\n    /**\n      * Call a defined callback function on each element of an array.\n      * @param callbackfn A function that accepts up to two arguments. The forEach method calls the callbackfn function one time for each element in the array.\n      */\n    //% helper=arrayForEach weight=40\n    forEach(callbackfn: (value: T, index: number) => void): void;\n\n    /**\n      * Return 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      * Fills all the elements of an array from a start index to an end index with a static value. The end index is not included.\n      */\n    //% helper=arrayFill weight=39\n    fill(value: T, start?: number, end?: number): T[];\n\n    /**\n     * Returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.\n     * @param callbackfn\n     */\n    //% helper=arrayFind weight=40\n    find(callbackfn: (value: T, index: number) => boolean): T;\n\n    /**\n      * Call the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\n      * @param callbackfn A function that accepts up to three arguments. The reduce method calls the callbackfn function one time for each element in the array.\n      * @param initialValue Initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\n      */\n    //% helper=arrayReduce weight=40\n    reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U;\n\n\n    /** Remove the first occurence of an object. Returns true if removed. */\n    //% shim=Array_::removeElement weight=48\n    removeElement(element: T): boolean;\n\n    /** Remove and return the element at a certain index. */\n    //% help=arrays/remove-at\n    //% shim=Array_::removeAt weight=47\n    //% blockId=\"array_removeat\" block=\"%list| get and remove value at %index\" blockNamespace=\"arrays\"\n    //% group=\"Read\"\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    //% help=arrays/insert-at\n    //% shim=Array_::insertAt weight=20\n    //% blockId=\"array_insertAt\" block=\"%list| insert at %index| value %value\" blockNamespace=\"arrays\"\n    //% group=\"Modify\"\n    insertAt(index: number, value: T): void;\n\n    /**\n      * Return 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    //% help=arrays/index-of\n    //% shim=Array_::indexOf weight=40\n    //% blockId=\"array_indexof\" block=\"%list| find index of %value\" blockNamespace=\"arrays\"\n    //% group=\"Operations\"\n    indexOf(item: T, fromIndex?: number): number;\n\n    /**\n     * Get the value at a particular index\n     * @param index the zero-based position in the list of the item, eg: 0\n     */\n    //% help=arrays/get\n    //% shim=Array_::getAt weight=85\n    get(index: number): T;\n\n    /**\n     * Store a value at a particular index\n     * @param index the zero-based position in the list to store the value, eg: 0\n     * @param value the value to insert, eg: 0\n     */\n    //% help=arrays/set\n    //% shim=Array_::setAt weight=84\n    set(index: number, value: T): void;\n\n    /**\n     * Return a random value from the array\n     */\n    //% help=arrays/pick-random\n    //% helper=arrayPickRandom weight=25\n    //% blockId=\"array_pickRandom\" block=\"get random value from %list\"\n    //% blockNamespace=\"arrays\"\n    //% group=\"Read\"\n    _pickRandom(): T;\n\n    [n: number]: T;\n\n    /**\n      * Add one element to the beginning of an array and return the new length of the array.\n      * @param element to insert at the start of the Array.\n      */\n    //% help=arrays/unshift\n    //% helper=arrayUnshift weight=24\n    //% blockId=\"array_unshift_statement\" block=\"%list| insert %value| at beginning\" blockNamespace=\"arrays\"\n    //% blockAliasFor=\"Array.unshift\"\n    //% group=\"Modify\"\n    _unshiftStatement(value: T): void;\n\n    /**\n      * Remove the last element from an array and return it.\n      */\n    //% help=arrays/pop\n    //% shim=Array_::pop weight=44\n    //% blockId=\"array_pop_statement\" block=\"remove last value from %list\" blockNamespace=\"arrays\"\n    //% blockAliasFor=\"Array.pop\"\n    //% group=\"Modify\"\n    _popStatement(): void;\n\n    /**\n      * Remove the first element from an array and return it. This method changes the length of the array.\n      */\n    //% help=arrays/shift\n    //% helper=arrayShift weight=29\n    //% blockId=\"array_shift_statement\" block=\"remove first value from %list\" blockNamespace=\"arrays\"\n    //% blockAliasFor=\"Array.shift\"\n    //% group=\"Modify\"\n    _shiftStatement(): void;\n\n    /** Remove the element at a certain index. */\n    //% help=arrays/remove-at-statement\n    //% shim=Array_::removeAt weight=14\n    //% blockId=\"array_removeat_statement\" block=\"%list| remove value at %index\" blockNamespace=\"arrays\"\n    //% blockAliasFor=\"Array.removeAt\"\n    //% group=\"Modify\"\n    _removeAtStatement(index: number): void;\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=49\n    //% blockId=\"string_concat\" blockNamespace=\"text\"\n    // block=\"join %list=text|%other\"\n    concat(other: string): string;\n\n    /**\n     * Return the character at the specified index.\n     * @param index The zero-based index of the desired character.\n     */\n    //% shim=String_::charAt weight=48\n    //% help=text/char-at\n    //% blockId=\"string_get\" block=\"char from %this=text|at %pos\" blockNamespace=\"text\"\n    //% this.defl=\"this\"\n    charAt(index: number): string;\n\n    /** Returns the length of a String object. */\n    //% property shim=String_::length weight=47\n    //% blockId=\"text_length\" block=\"length of %VALUE\" blockBuiltin=true blockNamespace=\"text\"\n    length: number;\n\n    /**\n     * Return 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 weight=46\n    //% help=text/char-code-at\n    //% blockId=\"string_charcode_at\" block=\"char code from $this=text|at $index\" blockNamespace=\"text\"\n    //% this.defl=\"this\"\n    charCodeAt(index: number): number;\n\n    /**\n     * See how the order of characters in two strings is different (in ASCII encoding).\n     * @param that String to compare to target string\n     */\n    //% shim=String_::compare\n    //% help=text/compare\n    //% blockId=\"string_compare\" block=\"compare %this=text| to %that\" blockNamespace=\"text\"\n    //% this.defl=\"this\"\n    compare(that: string): number;\n\n    /**\n     * Return a 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, eg: 10\n     */\n    //% helper=stringSubstr\n    //% help=text/substr\n    //% blockId=\"string_substr\" block=\"substring of %this=text|from %start|of length %length\" blockNamespace=\"text\"\n    //% this.defl=\"this\"\n    substr(start: number, length?: number): string;\n\n    /**\n     * Return the current string with the first occurence of toReplace\n     * replaced with the replacer\n     * @param toReplace the substring to replace in the current string\n     * @param replacer either the string that replaces toReplace in the current string,\n     *                or a function that accepts the substring and returns the replacement string.\n     */\n    //% helper=stringReplace\n    replace(toReplace: string, replacer: string | ((sub: string) => string)): string;\n\n    /**\n     * Return the current string with each occurence of toReplace\n     * replaced with the replacer\n     * @param toReplace the substring to replace in the current string\n     * @param replacer either the string that replaces toReplace in the current string,\n     *                or a function that accepts the substring and returns the replacement string.\n     */\n    //% helper=stringReplaceAll\n    replaceAll(toReplace: string, replacer: string | ((sub: string) => string)): string;\n\n    /**\n     * Return a substring of the current string.\n     * @param start first character index; can be negative from counting from the end, eg:0\n     * @param end one-past-last character index\n     */\n    //% helper=stringSlice\n    slice(start: number, end?: number): string;\n\n    /** Returns a value indicating if the string is empty */\n    //% helper=stringEmpty\n    //% help=text/is-empty\n    //% blockId=\"string_isempty\" blockNamespace=\"text\"\n    //% block=\"%this=text| is empty\"\n    //% this.defl=\"this\"\n    isEmpty(): boolean;\n\n    /**\n     * Returns the position of the first occurrence of a specified value in a string.\n     * @param searchValue the text to find\n     * @param start optional start index for the search\n     */\n    //% shim=String_::indexOf\n    //% help=text/index-of\n    //% blockId=\"string_indexof\" blockNamespace=\"text\"\n    //% block=\"%this=text|find index of %searchValue\"\n    //% this.defl=\"this\"\n    indexOf(searchValue: string, start?: number): number;\n\n    /**\n     * Determines whether a string contains the characters of a specified string.\n     * @param searchValue the text to find\n     * @param start optional start index for the search\n     */\n    //% shim=String_::includes\n    //% help=text/includes\n    //% blockId=\"string_includes\" blockNamespace=\"text\"\n    //% block=\"%this=text|includes %searchValue\"\n    //% this.defl=\"this\"\n    includes(searchValue: string, start?: number): boolean;\n\n    /**\n     * Splits the string according to the separators\n     * @param separator\n     * @param limit\n     */\n    //% helper=stringSplit\n    //% help=text/split\n    //% blockId=\"string_split\" blockNamespace=\"text\"\n    //% block=\"split %this=text|at %separator\"\n    //% this.defl=\"this\"\n    split(separator?: string, limit?: number): string[];\n\n    /**\n     * Return a substring of the current string with whitespace removed from both ends\n     */\n    //% helper=stringTrim\n    trim(): string;\n\n    /**\n     * Converts the string to upper case characters.\n     */\n    //% helper=stringToUpperCase\n    //% help=text/to-upper-case\n    toUpperCase(): string;\n\n    /**\n     * Converts the string to lower case characters.\n     */\n    //% helper=stringToLowerCase\n    //% help=text/to-lower-case\n    toLowerCase(): string;\n\n    [index: number]: string;\n}\n\n/**\n  * Convert a string to a number.\n  * @param s A string to convert into a number. eg: 123\n  */\n//% shim=String_::toNumber\n//% help=text/parse-float\n//% blockId=\"string_parsefloat\" block=\"parse to number %text\" blockNamespace=\"text\"\n//% text.defl=\"123\"\ndeclare function parseFloat(text: string): number;\n\n/**\n * Returns a pseudorandom number between min and max included.\n * If both numbers are integral, the result is integral.\n * @param min the lower inclusive bound, eg: 0\n * @param max the upper inclusive bound, eg: 10\n */\n//% blockId=\"device_random\" block=\"pick random %min|to %limit\"\n//% blockNamespace=\"Math\"\n//% help=math/randint\n//% shim=Math_::randomRange\ndeclare function randint(min: number, max: number): number;\n\ninterface Object { }\ninterface Function {\n  __assignableToFunction: Function;\n}\ninterface IArguments {\n  __assignableToIArguments: IArguments;\n}\ninterface RegExp {\n  __assignableToRegExp: RegExp;\n}\ntype TemplateStringsArray = Array<string>;\n\ntype uint8 = number;\ntype uint16 = number;\ntype 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=numops::toString\n    toString(): string;\n}\n\n/**\n * Combine, split, and search text strings.\n*/\n//% blockNamespace=\"text\"\ndeclare namespace String {\n\n    /**\n     * Make a string from the given ASCII character code.\n     */\n    //% help=math/from-char-code\n    //% shim=String_::fromCharCode weight=1\n    //% blockNamespace=\"text\" blockId=\"stringFromCharCode\" block=\"text from char code %code\"\n    function fromCharCode(code: number): string;\n}\n\ndeclare interface Number {\n    /**\n     * Returns a string representation of a number.\n     */\n    //% shim=numops::toString\n    toString(): string;\n}\n\n/**\n * Add, remove, and replace items in lists.\n*/\n//% blockNamespace=\"Arrays\"\ndeclare namespace Array {\n    /**\n     * Check if a given object is an array.\n     */\n    //% shim=Array_::isArray\n    function isArray(obj: any): boolean;\n}\n\ndeclare namespace Object {\n    /**\n     * Return the field names in an object.\n     */\n    //% shim=pxtrt::keysOf\n    function keys(obj: any): string[];\n}\n\n/**\n * More complex operations with numbers.\n*/\ndeclare namespace Math {\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 1.\n     */\n    //% shim=Math_::random\n    //% help=math/random\n    function random(): number;\n\n    /**\n     * Returns a pseudorandom number between min and max included.\n     * If both numbers are integral, the result is integral.\n     * @param min the lower inclusive bound, eg: 0\n     * @param max the upper inclusive bound, eg: 10\n     */\n    //% blockId=\"device_random_deprecated\" block=\"pick random %min|to %limit\"\n    //% help=math/random-range deprecated\n    //% shim=Math_::randomRange\n    function randomRange(min: number, max: number): number;\n\n    /**\n     * Returns the natural logarithm (base e) of a number.\n     * @param x A number\n     */\n    //% shim=Math_::log\n    //% help=math\n    function log(x: number): number;\n\n    /**\n     * Returns returns ``e^x``.\n     * @param x A number\n     */\n    //% shim=Math_::exp\n    //% help=math\n    function exp(x: number): number;\n\n    /**\n     * Returns the sine of a number.\n     * @param x An angle in radians\n     */\n    //% shim=Math_::sin\n    //% help=math/trigonometry\n    function sin(x: number): number;\n\n    /**\n     * Returns the cosine of a number.\n     * @param x An angle in radians\n     */\n    //% shim=Math_::cos\n    //% help=math/trigonometry\n    function cos(x: number): number;\n\n    /**\n     * Returns the tangent of a number.\n     * @param x An angle in radians\n     */\n    //% shim=Math_::tan\n    //% help=math/trigonometry\n    function tan(x: number): number;\n\n    /**\n     * Returns the arcsine (in radians) of a number\n     * @param x A number\n     */\n    //% shim=Math_::asin\n    //% help=math/trigonometry\n    function asin(x: number): number;\n\n    /**\n     * Returns the arccosine (in radians) of a number\n     * @param x A number\n     */\n    //% shim=Math_::acos\n    //% help=math/trigonometry\n    function acos(x: number): number;\n\n    /**\n     * Returns the arctangent (in radians) of a number\n     * @param x A number\n     */\n    //% shim=Math_::atan\n    //% help=math/trigonometry\n    function atan(x: number): number;\n\n    /**\n     * Returns the arctangent of the quotient of its arguments.\n     * @param y A number\n     * @param x A number\n     */\n    //% shim=Math_::atan2\n    //% help=math/trigonometry\n    function atan2(y: number, x: number): number;\n\n    /**\n     * Returns the square root of a number.\n     * @param x A numeric expression.\n     */\n    //% shim=Math_::sqrt\n    //% help=math\n    function sqrt(x: number): number;\n\n    /**\n     * Returns the smallest number greater than or equal to its numeric argument.\n     * @param x A numeric expression.\n     */\n    //% shim=Math_::ceil\n      //% help=math\n    function ceil(x: number): number;\n\n    /**\n      * Returns the greatest number less than or equal to its numeric argument.\n      * @param x A numeric expression.\n      */\n    //% shim=Math_::floor\n      //% help=math\n    function floor(x: number): number;\n\n    /**\n      * Returns the number with the decimal part truncated.\n      * @param x A numeric expression.\n      */\n    //% shim=Math_::trunc\n    //% help=math\n    function trunc(x: number): number;\n\n    /**\n      * Returns a supplied numeric expression rounded to the nearest number.\n      * @param x The value to be rounded to the nearest number.\n      */\n    //% shim=Math_::round\n    //% help=math\n    function round(x: number): number;\n\n    /**\n     * Returns the value of integer signed 32 bit multiplication of two numbers.\n     * @param x The first number\n     * @param y The second number\n     */\n    //% shim=Math_::imul\n    //% help=math\n    function imul(x: number, y: number): number;\n\n    /**\n     * Returns the value of integer signed 32 bit division of two numbers.\n     * @param x The first number\n     * @param y The second number\n     */\n    //% shim=Math_::idiv\n    //% help=math\n    function idiv(x: number, y: number): number;\n}\n\ndeclare namespace control {\n    //% shim=_control::_onCodeStart\n    export function _onCodeStart(arg: any): void;\n\n    //% shim=_control::_onCodeStop\n    export function _onCodeStop(arg: any): void;\n}","pxt-helpers.ts":"type Action = () => void;\n\n/**\n * Constant representing Not-A-Number.\n */\nconst NaN = 0 / 0\n\n/**\n * Constant representing positive infinity.\n */\nconst Infinity = 1 / 0\n\nfunction isNaN(x: number) {\n    x = +x // convert to number\n    return x !== x\n}\n\nnamespace Number {\n    /**\n     * Check if a given value is of type Number and it is a NaN.\n     */\n    export function isNaN(x: any): boolean {\n        return typeof x == \"number\" && x !== x\n    }\n}\n\n/**\n * A dictionary from string key to string values\n */\ninterface StringMap {\n    [index: string]: string;\n}\n\n/**\n  * Convert a string to an integer.\n  * @param text A string to convert into an integral number. eg: \"123\"\n  * @param radix optional A value between 2 and 36 that specifies the base of the number in text.\n  * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.\n  * All other strings are considered decimal.\n  */\n//% help=text/parse-int\n//% blockId=\"string_parseint\" block=\"parse to integer %text\" blockNamespace=\"text\"\n//% text.defl=\"123\"\n//% blockHidden=1\nfunction parseInt(text: string, radix?: number): number {\n    // roughly based on https://www.ecma-international.org/ecma-262/5.1/#sec-15.1.2.2\n    // with some consideration for avoiding unnecessary slices where easy\n    if (!text || (radix != null && (radix < 2 || radix > 36)))\n        return NaN;\n\n    let start = 0;\n    while (start < text.length && helpers.isWhitespace(text.charCodeAt(start)))\n        ++start;\n\n    if (start === text.length)\n        return NaN;\n\n    const numberOffset = 48; // 0\n    const numCount = 10;\n    const letterOffset = 97; // a\n    const letterCount = 26;\n    const lowerCaseMask = 0x20;\n\n    let sign = 1;\n    switch (text.charAt(start)) {\n        case \"-\":\n            sign = -1;\n            // fallthrough\n        case \"+\":\n            ++start;\n    }\n\n    if ((!radix || radix == 16)\n            && \"0\" === text[start]\n            && (\"x\" === text[start + 1] || \"X\" === text[start + 1])) {\n        radix = 16;\n        start += 2;\n    } else if (!radix) {\n        radix = 10;\n    }\n\n    let output = 0;\n    let hasDigit = false;\n    for (let i = start; i < text.length; ++i) {\n        const code = text.charCodeAt(i) | lowerCaseMask;\n        let val: number = undefined;\n\n        if (code >= numberOffset && code < numberOffset + numCount)\n            val = code - numberOffset;\n        else if (code >= letterOffset && code < letterOffset + letterCount)\n            val = numCount + code - letterOffset;\n\n        if (val == undefined || val >= radix) {\n            if (!hasDigit) {\n                return NaN;\n            }\n            break;\n        }\n        hasDigit = true;\n        output = output * radix + val;\n    }\n\n    return sign * output;\n}\n\nnamespace helpers {\n    export function arrayFill<T>(O: T[], value: T, start?: number, end?: number) {\n        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill\n        // Steps 3-5.\n        const len = O.length >>> 0;\n\n        // Steps 6-7.\n        const relativeStart = start === undefined ? 0 : start >> 0;\n\n        // Step 8.\n        let k = relativeStart < 0 ?\n            Math.max(len + relativeStart, 0) :\n            Math.min(relativeStart, len);\n\n        // Steps 9-10.\n        const relativeEnd = end === undefined ? len : end >> 0;\n\n        // Step 11.\n        const final = relativeEnd < 0 ?\n            Math.max(len + relativeEnd, 0) :\n            Math.min(relativeEnd, len);\n\n        // Step 12.\n        while (k < final) {\n            O[k] = value;\n            k++;\n        }\n\n        // Step 13.\n        return O;\n    }\n\n    export function arraySplice<T>(arr: T[], start: number, len: number) {\n        if (start < 0) {\n            return;\n        }\n        for (let i = 0; i < len; ++i) {\n            arr.removeAt(start)\n        }\n    }\n\n    export function arrayReverse<T>(arr: T[]): void {\n        let len = arr.length;\n        for (let i = 0; i < len / 2; i++) {\n            swap(arr, i, len - i - 1);\n        }\n    }\n\n    export function arrayShift<T>(arr: T[]): T {\n        return arr.removeAt(0);\n    }\n\n    export function arrayJoin<T>(arr: T[], sep?: string): string {\n        if (sep === undefined || sep === null) {\n            sep = \",\";\n        }\n\n        let r = \"\";\n        let len = arr.length // caching this seems to match V8\n        for (let i = 0; i < len; ++i) {\n            if (i > 0 && sep)\n                r += sep;\n            r += (arr[i] === undefined || arr[i] === null) ? \"\" : arr[i];\n        }\n        return r;\n    }\n\n    /*TODO: Enable this multiple value unshift, after rest is enabled in our compiler.\n        export function arrayUnshift<T>(arr: T[], ...values: T[]) : number {\n            for(let i = values.length; i > 0; --i) {\n                arr.insertAt(0, values[i - 1]);\n            }\n            return arr.length;\n        }\n    */\n    export function arrayUnshift<T>(arr: T[], value: T): number {\n        arr.insertAt(0, value);\n        return arr.length;\n    }\n\n    function swap<T>(arr: T[], i: number, j: number): void {\n        let temp: T = arr[i];\n        arr[i] = arr[j];\n        arr[j] = temp;\n    }\n\n    function sortHelper<T>(arr: T[], callbackfn?: (value1: T, value2: T) => number): T[] {\n        if (arr.length <= 0 || !callbackfn) {\n            return arr;\n        }\n        let len = arr.length;\n        // simple selection sort.\n        for (let i = 0; i < len - 1; ++i) {\n            for (let j = i + 1; j < len; ++j) {\n                if (callbackfn(arr[i], arr[j]) > 0) {\n                    swap(arr, i, j);\n                }\n            }\n        }\n        return arr;\n    }\n\n    export function arraySort<T>(arr: T[], callbackfn?: (value1: T, value2: T) => number): T[] {\n        if (!callbackfn && arr.length > 1) {\n            callbackfn = (a, b) => {\n                // default is sort as if the element were a string, with null < undefined\n                const aIsUndef = a === undefined;\n                const bIsUndef = b === undefined;\n                if (aIsUndef && bIsUndef) return 0;\n                else if (aIsUndef) return 1;\n                else if (bIsUndef) return -1;\n\n                const aIsNull = a === null;\n                const bIsNull = b === null;\n                if (aIsNull && bIsNull) return 0;\n                else if (aIsNull) return 1;\n                else if (bIsNull) return -1;\n\n                return (a + \"\").compare(b + \"\");\n            }\n        }\n        return sortHelper(arr, callbackfn);\n    }\n\n    export function arrayMap<T, U>(arr: T[], callbackfn: (value: T, index: number) => U): U[] {\n        let res: U[] = []\n        let len = arr.length // caching this seems to match V8\n        for (let i = 0; i < len; ++i) {\n            res.push(callbackfn(arr[i], i))\n        }\n        return res\n    }\n\n    export function arraySome<T>(arr: T[], callbackfn: (value: T, index: number) => boolean): boolean {\n        let len = arr.length // caching this seems to match V8\n        for (let i = 0; i < len; ++i)\n            if (callbackfn(arr[i], i))\n                return true;\n        return false;\n    }\n\n    export function arrayEvery<T>(arr: T[], callbackfn: (value: T, index: number) => boolean): boolean {\n        let len = arr.length // caching this seems to match V8\n        for (let i = 0; i < len; ++i)\n            if (!callbackfn(arr[i], i))\n                return false;\n        return true;\n    }\n\n    export function arrayForEach<T>(arr: T[], callbackfn: (value: T, index: number) => void): void {\n        let len = arr.length // caching this seems to match V8\n        for (let i = 0; i < len; ++i) {\n            callbackfn(arr[i], i);\n        }\n    }\n\n    export function arrayFilter<T>(arr: T[], callbackfn: (value: T, index: number) => boolean): T[] {\n        let res: T[] = []\n        let len = arr.length\n        for (let i = 0; i < len; ++i) {\n            let v = arr[i] // need to cache\n            if (callbackfn(v, i)) res.push(v)\n        }\n        return res\n    }\n\n    export function arrayFind<T>(arr: T[], callbackfn: (value: T, index: number) => boolean): 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)) return v;\n        }\n        return undefined;\n    }\n\n    export function arrayReduce<T, U>(arr: T[], callbackfn: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue: U): U {\n        let len = arr.length\n        for (let i = 0; i < len; ++i) {\n            initialValue = callbackfn(initialValue, arr[i], i)\n        }\n        return initialValue\n    }\n\n    export function arrayConcat<T>(arr: T[], otherArr: T[]): T[] {\n        let out: T[] = [];\n        for (let value of arr) {\n            out.push(value);\n        }\n        for (let value of otherArr) {\n            out.push(value);\n        }\n        return out;\n    }\n\n    export function arrayPickRandom<T>(arr: T[]): T {\n        return arr[Math.randomRange(0, arr.length - 1)];\n    }\n\n    export function arraySlice<T>(arr: T[], start?: number, end?: number): T[] {\n        // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\n        const res: T[] = [];\n        const len = arr.length;\n\n        if (start === undefined)\n            start = 0;\n        else if (start < 0)\n            start = Math.max(len + start, 0);\n\n        if (start > len)\n            return res;\n\n        if (end === undefined)\n            end = len;\n        else if (end < 0)\n            end = len + end;\n\n        if (end > len)\n            end = len;\n\n        for (let i = start; i < end; ++i) {\n            res.push(arr[i]);\n        }\n        return res;\n    }\n\n    export function stringReplace(s: string, toReplace: string, replacer: string | ((sub: string) => string)) {\n        toReplace = toReplace + \"\";\n        const ind = s.indexOf(toReplace);\n        if (ind == -1)\n            return s;\n\n        const begin = s.slice(0, ind);\n        const end = s.slice(ind + toReplace.length);\n\n        if (typeof replacer == \"string\" || !replacer) {\n            return begin + replacer + end;\n        } else {\n            return begin + replacer(toReplace) + end;\n        }\n    }\n\n    export function stringReplaceAll(s: string, toReplace: string, replacer: string | ((sub: string) => string)) {\n        toReplace = toReplace + \"\";\n        const split = s.split(toReplace);\n        const empty = toReplace.isEmpty();\n\n        let output = (empty ? applyReplace(toReplace, replacer) : \"\");\n\n        if (split.length) {\n            output += split[0];\n        }\n\n        for (let i = 1; i < split.length; ++i) {\n            output += applyReplace(toReplace, replacer) + split[i];\n        }\n\n        if (!s.isEmpty() && empty) {\n            output += applyReplace(toReplace, replacer);\n        }\n\n        return output;\n\n        function applyReplace(r: string, replacer: string | ((sub: string) => string)): string {\n            if (typeof replacer == \"string\" || !replacer) {\n                return replacer as string;\n            } else {\n                return replacer(r);\n            }\n        }\n    }\n\n    //% shim=String_::substr\n    declare function stringSubstrHelper(s: string, start: number, length?: number): string;\n\n    export function stringSubstr(s: string, start: number, length?: number): string {\n        length = length === undefined ? s.length : length || 0;\n        return stringSubstrHelper(s, start, length);\n    }\n\n    export function stringSlice(s: string, start: number, end?: number): string {\n        const len = s.length;\n\n        if (start < 0) {\n            start = Math.max(len + start, 0);\n        }\n\n        if (end === undefined) {\n            end = len;\n        } else if (end === null) {\n            end = 0;\n        }\n\n        if (end < 0) {\n            end = len + end;\n        }\n\n        return stringSubstrHelper(s, start, end - start);\n    }\n\n    // also note this doesn't handle unicode, but neither does JS (there's toLocaleUpperCase())\n    export function stringToUpperCase(s: string): string {\n        let r = \"\"\n        let prev = 0\n        for (let i = 0; i < s.length; i++) {\n            const c = s.charCodeAt(i)\n            if (97 <= c && c <= 122) {\n                r += s.slice(prev, i) + String.fromCharCode(c - 32)\n                prev = i + 1\n            }\n        }\n        r += s.slice(prev)\n        return r\n    }\n\n    // also note this doesn't handle unicode, but neither does JS (there's toLocaleLowerCase())\n    export function stringToLowerCase(s: string): string {\n        let r = \"\"\n        let prev = 0\n        for (let i = 0; i < s.length; i++) {\n            const c = s.charCodeAt(i)\n            if (65 <= c && c <= 90) {\n                r += s.slice(prev, i) + String.fromCharCode(c + 32)\n                prev = i + 1\n            }\n        }\n        r += s.slice(prev)\n        return r\n    }\n\n    export function stringSplit(S: string, separator?: string, limit?: number): string[] {\n        // https://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.split\n        const A: string[] = [];\n        let lim = 0;\n        if (limit === undefined)\n            lim = (1 << 29) - 1; // spec says 1 << 53, leaving it at 29 for constant folding\n        else if (limit < 0)\n            lim = 0;\n        else\n            lim = limit | 0;\n        const s = S.length;\n        let p = 0;\n        const R = separator;\n        if (lim == 0)\n            return A;\n        if (separator === undefined) {\n            A[0] = S;\n            return A;\n        }\n        if (s == 0) {\n            let z = splitMatch(S, 0, R);\n            if (z > -1) return A;\n            A[0] = S;\n            return A;\n        }\n        let T: string;\n        let q = p;\n        while (q != s) {\n            let e = splitMatch(S, q, R);\n            if (e < 0) q++;\n            else {\n                if (e == p) q++;\n                else {\n                    T = stringSlice(S, p, q);\n                    A.push(T);\n                    if (A.length == lim) return A;\n                    p = e;\n                    q = p;\n                }\n            }\n        }\n        T = stringSlice(S, p, q);\n        A.push(T);\n        return A;\n    }\n\n    function splitMatch(S: string, q: number, R: string): number {\n        const r = R.length;\n        const s = S.length;\n        if (q + r > s) return -1;\n        for (let i = 0; i < r; ++i) {\n            if (S[q + i] != R[i])\n                return -1;\n        }\n        return q + r;\n    }\n\n    export function stringTrim(s: string): string {\n        let start = 0;\n        let end = s.length - 1;\n\n        while (start <= end && isWhitespace(s.charCodeAt(start)))\n            ++start;\n\n        while (end > start && isWhitespace(s.charCodeAt(end)))\n            --end;\n        return s.slice(start, end + 1);\n    }\n\n    export function isWhitespace(c: number): boolean {\n        // https://www.ecma-international.org/ecma-262/6.0/#sec-white-space\n        switch (c) {\n            case 0x0009:  // character tab\n            case 0x000B:  // line tab\n            case 0x000C:  // form feed\n            case 0x0020:  // space\n            case 0x00A0:  // no-break space\n            case 0xFEFF:  // zero width no break space\n            case 0x000A:  // line feed\n            case 0x000D:  // carriage return\n            case 0x2028:  // line separator\n            case 0x2029:  // paragraph separator\n                return true;\n            default:\n                return false;\n        }\n    }\n\n    export function stringEmpty(S: string): boolean {\n        return !S;\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    //% blockId=math_op3\n    //% help=math/abs\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    //% blockId=math_op2\n    //% help=math/max\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    //% blockId=math_op2\n    //% help=math/min\n    export function min(a: number, b: number): number {\n        if (a <= b) return a;\n        return b;\n    }\n\n    /**\n     * Rounds ``x`` to a number with the given number of ``digits``\n     * @param x the number to round\n     * @param digits the number of resulting digits\n     */\n    //%\n    export function roundWithPrecision(x: number, digits: number): number {\n        digits = digits | 0;\n        // invalid digits input\n        if (digits <= 0) return Math.round(x);\n        if (x == 0) return 0;\n        let r = 0;\n        do {\n            const d = Math.pow(10, digits);\n            r = Math.round(x * d) / d;\n            digits++;\n        } while (r == 0 && digits < 21);\n        return r;\n    }\n}\n\n\n//% blockHidden=1\nnamespace __internal {\n    /**\n     * A shim to render a boolean as a down/up toggle\n     */\n    //% shim=TD_ID blockHidden=1\n    //% blockId=toggleDownUp block=\"%down\"\n    //% down.fieldEditor=toggledownup\n    //% down.fieldOptions.decompileLiterals=true\n    export function __downUp(down: boolean): boolean {\n        return down;\n    }\n\n    /**\n     * A shim to render a boolean as a up/down toggle\n     */\n    //% shim=TD_ID blockHidden=1\n    //% blockId=toggleUpDown block=\"%up\"\n    //% up.fieldEditor=toggleupdown\n    //% up.fieldOptions.decompileLiterals=true\n    export function __upDown(up: boolean): boolean {\n        return up;\n    }\n\n    /**\n     * A shim to render a boolean as a high/low toggle\n     */\n    //% shim=TD_ID blockHidden=1\n    //% blockId=toggleHighLow block=\"%high\"\n    //% high.fieldEditor=togglehighlow\n    //% high.fieldOptions.decompileLiterals=true\n    export function __highLow(high: boolean): boolean {\n        return high;\n    }\n\n    /**\n     * A shim to render a boolean as a on/off toggle\n     */\n    //% shim=TD_ID blockHidden=1\n    //% blockId=toggleOnOff block=\"%on\"\n    //% on.fieldEditor=toggleonoff\n    //% on.fieldOptions.decompileLiterals=true\n    export function __onOff(on: boolean): boolean {\n        return on;\n    }\n\n    /**\n     * A shim to render a boolean as a yes/no toggle\n     */\n    //% shim=TD_ID blockHidden=1\n    //% blockId=toggleYesNo block=\"%yes\"\n    //% yes.fieldEditor=toggleyesno\n    //% yes.fieldOptions.decompileLiterals=true\n    export function __yesNo(yes: boolean): boolean {\n        return yes;\n    }\n\n    /**\n     * A shim to render a boolean as a win/lose toggle\n     */\n    //% shim=TD_ID blockHidden=1\n    //% blockId=toggleWinLose block=\"%win\"\n    //% win.fieldEditor=togglewinlose\n    //% win.fieldOptions.decompileLiterals=true\n    export function __winLose(win: boolean): boolean {\n        return win;\n    }\n\n    /**\n     * Get the color wheel field editor\n     * @param color color\n     */\n    //% blockId=colorNumberPicker block=\"%value\"\n    //% blockHidden=true\n    //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n    //% value.fieldEditor=\"colornumber\" value.fieldOptions.decompileLiterals=true\n    //% value.defl='0xff0000'\n    //% value.fieldOptions.colours='[\"#ff0000\",\"#ff8000\",\"#ffff00\",\"#ff9da5\",\"#00ff00\",\"#b09eff\",\"#00ffff\",\"#007fff\",\"#65471f\",\"#0000ff\",\"#7f00ff\",\"#ff0080\",\"#ff00ff\",\"#ffffff\",\"#999999\",\"#000000\"]'\n    //% value.fieldOptions.columns=4 value.fieldOptions.className='rgbColorPicker'\n    export function __colorNumberPicker(value: number) {\n        return value;\n    }\n\n    /**\n     * Get the color wheel field editor\n     * @param value value between 0 to 255 to get a color value, eg: 10\n     */\n    //% blockId=colorWheelPicker block=\"%value\"\n    //% blockHidden=true\n    //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n    //% value.fieldEditor=\"colorwheel\" value.fieldOptions.decompileLiterals=true\n    //% value.fieldOptions.sliderWidth='200'\n    //% value.fieldOptions.min=0 value.fieldOptions.max=255\n    export function __colorWheelPicker(value: number) {\n        return value;\n    }\n\n    /**\n    * Get the color wheel field editor using HSV values\n    * @param value value between 0 to 255 to get a color value, eg: 10\n    */\n    //% blockId=colorWheelHsvPicker block=\"%value\"\n    //% blockHidden=true\n    //% shim=TD_ID colorSecondary=\"#FFFFFF\"\n    //% value.fieldEditor=\"colorwheel\" value.fieldOptions.decompileLiterals=true\n    //% value.fieldOptions.sliderWidth='200'\n    //% value.fieldOptions.min=0 value.fieldOptions.max=255\n    //% value.fieldOptions.channel=hsvfast\n    export function __colorWheelHsvPicker(value: number) {\n        return value;\n    }\n\n    /**\n     * A speed picker\n     * @param speed the speed, eg: 50\n     */\n    //% blockId=speedPicker block=\"%speed\" shim=TD_ID\n    //% speed.fieldEditor=\"speed\" colorSecondary=\"#FFFFFF\"\n    //% weight=0 blockHidden=1 speed.fieldOptions.decompileLiterals=1\n    export function __speedPicker(speed: number): number {\n        return speed;\n    }\n\n    /**\n     * A turn ratio picker\n     * @param turnratio the turn ratio, eg: 0\n     */\n    //% blockId=turnRatioPicker block=\"%turnratio\" shim=TD_ID\n    //% turnratio.fieldEditor=\"turnratio\" colorSecondary=\"#FFFFFF\"\n    //% weight=0 blockHidden=1 turnRatio.fieldOptions.decompileLiterals=1\n    export function __turnRatioPicker(turnratio: number): number {\n        return turnratio;\n    }\n\n    /**\n     * A field editor that displays a protractor\n     */\n    //% blockId=protractorPicker block=\"%angle\"\n    //% shim=TD_ID\n    //% angle.fieldEditor=protractor\n    //% angle.fieldOptions.decompileLiterals=1\n    //% colorSecondary=\"#FFFFFF\"\n    //% blockHidden=1\n    export function __protractor(angle: number) {\n        return angle;\n    }\n\n    /**\n      * Get the time field editor\n      * @param ms time duration in milliseconds, eg: 500, 1000\n      */\n    //% blockId=timePicker block=\"%ms\"\n    //% blockHidden=true shim=TD_ID\n    //% colorSecondary=\"#FFFFFF\"\n    //% ms.fieldEditor=\"numberdropdown\" ms.fieldOptions.decompileLiterals=true\n    //% ms.fieldOptions.data='[[\"100 ms\", 100], [\"200 ms\", 200], [\"500 ms\", 500], [\"1 second\", 1000], [\"2 seconds\", 2000], [\"5 seconds\", 5000]]'\n    export function __timePicker(ms: number): number {\n        return ms;\n    }\n}\n","pxt.cpp":"#include \"pxtbase.h\"\n\nusing namespace std;\n\nnamespace pxt {\n\nAction mkAction(int totallen, RefAction *act) {\n    check(getVTable(act)->classNo == BuiltInType::RefAction, PANIC_INVALID_BINARY_HEADER, 1);\n#ifdef PXT_VM\n    check(act->initialLen <= totallen, PANIC_INVALID_BINARY_HEADER, 13);\n#endif\n\n    if (totallen == 0) {\n        return (TValue)act; // no closure needed\n    }\n\n    void *ptr = gcAllocate(sizeof(RefAction) + totallen * sizeof(void *));\n    RefAction *r = new (ptr) RefAction();\n    r->len = totallen;\n#ifdef PXT_VM\n    r->numArgs = act->numArgs;\n    r->initialLen = act->initialLen;\n    r->flags = 0;\n#endif\n    r->func = act->func;\n    memset(r->fields, 0, r->len * sizeof(void *));\n\n    MEMDBG(\"mkAction: start=%p => %p\", act, r);\n\n    return (Action)r;\n}\n\nRefRecord *mkClassInstance(VTable *vtable) {\n    intcheck(vtable->methods[0] == &RefRecord_destroy, PANIC_SIZE, 3);\n    // intcheck(vtable->methods[1] == &RefRecord_print, PANIC_SIZE, 4);\n\n    void *ptr = gcAllocate(vtable->numbytes);\n    RefRecord *r = new (ptr) RefRecord(vtable);\n    memset(r->fields, 0, vtable->numbytes - sizeof(RefRecord));\n    MEMDBG(\"mkClass: vt=%p => %p\", vtable, r);\n    return r;\n}\n\nTValue RefRecord::ld(int idx) {\n    // intcheck((reflen == 255 ? 0 : reflen) <= idx && idx < len, PANIC_OUT_OF_BOUNDS, 1);\n    return fields[idx];\n}\n\nTValue RefRecord::ldref(int idx) {\n    // DMESG(\"LD %p len=%d reflen=%d idx=%d\", this, len, reflen, idx);\n    // intcheck(0 <= idx && idx < reflen, PANIC_OUT_OF_BOUNDS, 2);\n    return fields[idx];\n}\n\nvoid RefRecord::st(int idx, TValue v) {\n    // intcheck((reflen == 255 ? 0 : reflen) <= idx && idx < len, PANIC_OUT_OF_BOUNDS, 3);\n    fields[idx] = v;\n}\n\nvoid RefRecord::stref(int idx, TValue v) {\n    // DMESG(\"ST %p len=%d reflen=%d idx=%d\", this, len, reflen, idx);\n    // intcheck(0 <= idx && idx < reflen, PANIC_OUT_OF_BOUNDS, 4);\n    fields[idx] = v;\n}\n\nvoid RefObject::destroyVT() {\n    ((RefObjectMethod)getVTable(this)->methods[0])(this);\n}\n\n//%\nvoid deleteRefObject(RefObject *obj) {\n    obj->destroyVT();\n}\n\nvoid RefObject::printVT() {\n    ((RefObjectMethod)getVTable(this)->methods[1])(this);\n}\n\nvoid RefRecord_destroy(RefRecord *) {}\n\nvoid RefRecord_print(RefRecord *r) {\n    DMESG(\"RefRecord %p size=%d bytes\", r, getVTable(r)->numbytes);\n}\n\nvoid Segment::set(unsigned i, TValue value) {\n    if (i < size) {\n        data[i] = value;\n    } else if (i < Segment::MaxSize) {\n        growByMin(i + 1);\n        data[i] = value;\n    } else {\n        return;\n    }\n    if (length <= i) {\n        length = i + 1;\n    }\n\n#ifdef DEBUG_BUILD\n    DMESG(\"In Segment::set\");\n    this->print();\n#endif\n\n    return;\n}\n\nstatic inline int growthFactor(int size) {\n    if (size == 0) {\n        return 4;\n    }\n    if (size < 64) {\n        return size * 2; // Double\n    }\n    if (size < 512) {\n        return size * 5 / 3; // Grow by 1.66 rate\n    }\n    // Grow by constant rate\n    if ((unsigned)size + 256 < Segment::MaxSize)\n        return size + 256;\n    else\n        return Segment::MaxSize;\n}\n\nvoid LLSegment::setLength(unsigned newLen) {\n    if (newLen > Segment::MaxSize)\n        return;\n\n    if (newLen > size) {\n        int newSize = growthFactor(size);\n        if (newSize < (int)newLen)\n            newSize = newLen;\n\n        // this will throw if unable to allocate\n        TValue *tmp = (TValue *)(xmalloc(newSize * sizeof(TValue)));\n\n        // Copy existing data\n        if (size) {\n            memcpy(tmp, data, size * sizeof(TValue));\n        }\n        // fill the rest with default value\n        memset(tmp + size, 0, (newSize - size) * sizeof(TValue));\n\n        // free older segment;\n        xfree(data);\n\n        data = tmp;\n        size = newSize;\n    } else if (newLen < length) {\n        memset(data + newLen, 0, (length - newLen) * sizeof(TValue));\n    }\n\n    length = newLen;\n}\n\nvoid LLSegment::set(unsigned idx, TValue v) {\n    if (idx >= Segment::MaxSize)\n        return;\n    if (idx >= length)\n        setLength(idx + 1);\n    data[idx] = v;\n}\n\nTValue LLSegment::pop() {\n    if (length > 0) {\n        --length;\n        TValue value = data[length];\n        data[length] = 0;\n        return value;\n    }\n    return 0;\n}\n\nvoid LLSegment::destroy() {\n    length = size = 0;\n    xfree(data);\n    data = nullptr;\n}\n\nvoid Segment::growByMin(ramint_t minSize) {\n    ramint_t newSize = max(minSize, (ramint_t)growthFactor(size));\n\n    if (size < newSize) {\n        // this will throw if unable to allocate\n        TValue *tmp = (TValue *)(gcAllocateArray(newSize * sizeof(TValue)));\n\n        // Copy existing data\n        if (size)\n            memcpy(tmp, data, size * sizeof(TValue));\n        // fill the rest with default value\n        memset(tmp + size, 0, (newSize - size) * sizeof(TValue));\n\n        data = tmp;\n        size = newSize;\n\n#ifdef DEBUG_BUILD\n        DMESG(\"growBy - after reallocation\");\n        this->print();\n#endif\n    }\n    // else { no shrinking yet; }\n    return;\n}\n\nvoid Segment::ensure(ramint_t newSize) {\n    if (newSize < size) {\n        return;\n    }\n    growByMin(newSize);\n}\n\nvoid Segment::setLength(unsigned newLength) {\n    if (newLength > size) {\n        ensure(newLength);\n    }\n    length = newLength;\n    return;\n}\n\nTValue Segment::pop() {\n#ifdef DEBUG_BUILD\n    DMESG(\"In Segment::pop\");\n    this->print();\n#endif\n\n    if (length > 0) {\n        --length;\n        TValue value = data[length];\n        data[length] = Segment::DefaultValue;\n        return value;\n    }\n    return Segment::DefaultValue;\n}\n\n// this function removes an element at index i and shifts the rest of the elements to\n// left to fill the gap\nTValue Segment::remove(unsigned i) {\n#ifdef DEBUG_BUILD\n    DMESG(\"In Segment::remove index:%d\", i);\n    this->print();\n#endif\n    if (i < length) {\n        // value to return\n        TValue ret = data[i];\n        if (i + 1 < length) {\n            // Move the rest of the elements to fill in the gap.\n            memmove(data + i, data + i + 1, (length - i - 1) * sizeof(void *));\n        }\n        length--;\n        data[length] = Segment::DefaultValue;\n#ifdef DEBUG_BUILD\n        DMESG(\"After Segment::remove index:%d\", i);\n        this->print();\n#endif\n        return ret;\n    }\n    return Segment::DefaultValue;\n}\n\n// this function inserts element value at index i by shifting the rest of the elements right.\nvoid Segment::insert(unsigned i, TValue value) {\n#ifdef DEBUG_BUILD\n    DMESG(\"In Segment::insert index:%d value:%d\", i, value);\n    this->print();\n#endif\n\n    if (i < length) {\n        ensure(length + 1);\n\n        // Move the rest of the elements to fill in the gap.\n        memmove(data + i + 1, data + i, (length - i) * sizeof(void *));\n\n        data[i] = value;\n        length++;\n    } else {\n        // This is insert beyond the length, just call set which will adjust the length\n        set(i, value);\n    }\n#ifdef DEBUG_BUILD\n    DMESG(\"After Segment::insert index:%d\", i);\n    this->print();\n#endif\n}\n\nvoid Segment::print() {\n    DMESG(\"Segment: %p, length: %d, size: %d\", data, (unsigned)length, (unsigned)size);\n    for (unsigned i = 0; i < size; i++) {\n        DMESG(\"-> %d\", (unsigned)(uintptr_t)data[i]);\n    }\n}\n\nvoid Segment::destroy() {\n#ifdef DEBUG_BUILD\n    DMESG(\"In Segment::destroy\");\n    this->print();\n#endif\n    length = size = 0;\n    data = nullptr;\n}\n\nPXT_VTABLE_CTOR(RefCollection) {}\n\nvoid RefCollection::destroy(RefCollection *t) {\n    t->head.destroy();\n}\n\nvoid RefCollection::print(RefCollection *t) {\n    DMESG(\"RefCollection %p size=%d\", t, t->head.getLength());\n    t->head.print();\n}\n\nPXT_VTABLE(RefAction, ValType::Function)\nRefAction::RefAction() : PXT_VTABLE_INIT(RefAction) {}\n\n// fields[] contain captured locals\nvoid RefAction::destroy(RefAction *t) {}\n\nvoid RefAction::print(RefAction *t) {\n#ifdef PXT_VM\n    DMESG(\"RefAction %p pc=%X size=%d\", t, (uint32_t)t->func, t->len);\n#else\n    DMESG(\"RefAction %p pc=%X size=%d\", t, (const uint8_t *)t->func - (const uint8_t *)bytecode,\n          t->len);\n#endif\n}\n\nPXT_VTABLE_CTOR(RefRefLocal) {\n    v = 0;\n}\n\nvoid RefRefLocal::print(RefRefLocal *t) {\n    DMESG(\"RefRefLocal %p v=%p\", t, (void *)t->v);\n}\n\nvoid RefRefLocal::destroy(RefRefLocal *t) {\n    decr(t->v);\n}\n\nPXT_VTABLE_CTOR(RefMap) {}\n\nvoid RefMap::destroy(RefMap *t) {\n    t->keys.destroy();\n    t->values.destroy();\n}\n\nint RefMap::findIdx(String key) {\n    auto len = keys.getLength();\n    auto data = (String *)keys.getData();\n\n    // fast path\n    for (unsigned i = 0; i < len; ++i) {\n        if (data[i] == key)\n            return i;\n    }\n\n    // slow path\n    auto keylen = key->getUTF8Size();\n    auto keydata = key->getUTF8Data();\n    for (unsigned i = 0; i < len; ++i) {\n        auto s = data[i];\n        if (s->getUTF8Size() == keylen && memcmp(keydata, s->getUTF8Data(), keylen) == 0)\n            return i;\n    }\n\n    return -1;\n}\n\nvoid RefMap::print(RefMap *t) {\n    DMESG(\"RefMap %p size=%d\", t, t->keys.getLength());\n}\n\nvoid debugMemLeaks() {}\n\nvoid error(PXT_PANIC code, int subcode) {\n    DMESG(\"Error: %d [%d]\", code, subcode);\n    target_panic(code);\n}\n\n#ifndef PXT_VM\nuint16_t *bytecode;\n#endif\nTValue *globals;\n\nvoid checkStr(bool cond, const char *msg) {\n    if (!cond) {\n        while (true) {\n            // uBit.display.scroll(msg, 100);\n            // uBit.sleep(100);\n        }\n    }\n}\n\n#ifdef PXT_VM\nint templateHash() {\n    return *(int*)&vmImg->infoHeader->hexHash;\n}\n\nint programHash() {\n    return *(int*)&vmImg->infoHeader->programHash;\n}\n\nint getNumGlobals() {\n    return (int)vmImg->infoHeader->allocGlobals;\n}\n\nString programName() {\n    return mkString((char *)vmImg->infoHeader->name);\n}\n#else\nint templateHash() {\n    return ((int *)bytecode)[4];\n}\n\nint programHash() {\n    return ((int *)bytecode)[6];\n}\n\nint getNumGlobals() {\n    return bytecode[16];\n}\n\nString programName() {\n    return ((String *)bytecode)[15];\n}\n#endif\n\n#ifndef PXT_VM\nvoid variantNotSupported(const char *v) {\n    DMESG(\"variant not supported: %s\", v);\n    target_panic(PANIC_VARIANT_NOT_SUPPORTED);\n}\n\nvoid exec_binary(unsigned *pc) {\n    // XXX re-enable once the calibration code is fixed and [editor/embedded.ts]\n    // properly prepends a call to [internal_main].\n    // ::touch_develop::internal_main();\n\n    // unique group for radio based on source hash\n    // ::touch_develop::micro_bit::radioDefaultGroup = programHash();\n\n    unsigned ver = *pc++;\n    checkStr(ver == 0x4210, \":( Bad runtime version\");\n\n    bytecode = *((uint16_t **)pc++); // the actual bytecode is here\n\n    if (((uint32_t *)bytecode)[0] == 0x923B8E71) {\n        variantNotSupported((const char *)bytecode + 16);\n        return;\n    }\n\n    globals = (TValue *)app_alloc(sizeof(TValue) * getNumGlobals());\n    memset(globals, 0, sizeof(TValue) * getNumGlobals());\n\n    // can be any valid address, best in RAM for speed\n    globals[0] = (TValue)&globals;\n\n    // just compare the first word\n    // TODO\n    checkStr(((uint32_t *)bytecode)[0] == 0x923B8E70 && (unsigned)templateHash() == *pc,\n             \":( Failed partial flash\");\n\n    uintptr_t startptr = (uintptr_t)bytecode;\n\n    startptr += 64; // header\n\n    initPerfCounters();\n\n    initRuntime();\n\n    runAction0((Action)startptr);\n\n    pxt::releaseFiber();\n}\n\nvoid start() {\n    exec_binary((unsigned *)functionsAndBytecode);\n}\n#endif\n\n} // namespace pxt\n\nnamespace Array_ {\n//%\nbool isArray(TValue arr) {\n    auto vt = getAnyVTable(arr);\n    return vt && vt->classNo == BuiltInType::RefCollection;\n}\n} // namespace Array_\n\nnamespace pxtrt {\n//% expose\nRefCollection *keysOf(TValue v) {\n    auto r = NEW_GC(RefCollection);\n    MEMDBG(\"mkColl[keys]: => %p\", r);\n    if (getAnyVTable(v) != &RefMap_vtable)\n        return r;\n    auto rm = (RefMap *)v;\n    auto len = rm->keys.getLength();\n    if (!len)\n        return r;\n    registerGCObj(r);\n    r->setLength(len);\n    auto dst = r->getData();\n    memcpy(dst, rm->keys.getData(), len * sizeof(TValue));\n    unregisterGCObj(r);\n    return r;\n}\n//% expose\nTValue mapDeleteByString(RefMap *map, String key) {\n    if (getAnyVTable((TValue)map) != &RefMap_vtable)\n        soft_panic(PANIC_DELETE_ON_CLASS);\n    int i = map->findIdx(key);\n    if (i >= 0) {\n        map->keys.remove(i);\n        map->values.remove(i);\n    }\n    return TAG_TRUE;\n}\n\n} // namespace pxtrt\n","pxt.json":"{\n    \"name\": \"base\",\n    \"description\": \"The base library\",\n    \"dependencies\": {},\n    \"files\": [\n        \"README.md\",\n        \"pxt-core.d.ts\",\n        \"pxt.cpp\",\n        \"gc.cpp\",\n        \"configkeys.h\",\n        \"pxtbase.h\",\n        \"core.cpp\",\n        \"advmath.cpp\",\n        \"trig.cpp\",\n        \"pxt-helpers.ts\",\n        \"fixed.ts\",\n        \"buffer.cpp\",\n        \"buffer.ts\",\n        \"shims.d.ts\",\n        \"enums.d.ts\",\n        \"loops.cpp\",\n        \"math.ts\",\n        \"ns.ts\",\n        \"control.cpp\",\n        \"controlgc.cpp\",\n        \"control.ts\",\n        \"interval.ts\",\n        \"gcstats.ts\",\n        \"poll.ts\",\n        \"console.ts\",\n        \"json.ts\",\n        \"templates.ts\",\n        \"eventcontext.ts\",\n        \"pause.ts\",\n        \"forever.ts\",\n        \"utfdecoder.ts\",\n        \"scheduling.ts\",\n        \"controlmessage.ts\",\n        \"perfcounters.ts\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"partial\": true,\n    \"yotta\": {\n        \"optionalConfig\": {\n            \"PXT_GC_CHECKS\": 0\n        },\n        \"userConfigs\": [\n            {\n                \"description\": \"(Diagnostics) Garbage Collection checks.\",\n                \"config\": {\n                    \"PXT_GC_CHECKS\": 1\n                }\n            }\n        ]\n    }\n}\n","pxtbase.h":"#ifndef __PXTBASE_H\n#define __PXTBASE_H\n\n#pragma GCC diagnostic ignored \"-Wunused-parameter\"\n#pragma GCC diagnostic ignored \"-Wformat\"\n#pragma GCC diagnostic ignored \"-Warray-bounds\"\n\n// needed for gcc6; not sure why\n#undef min\n#undef max\n\n#define NOLOG(...)                                                                                 \\\n    do {                                                                                           \\\n    } while (0)\n\n#define MEMDBG NOLOG\n//#define MEMDBG DMESG\n#define MEMDBG2 NOLOG\n\n#include \"pxtconfig.h\"\n#include \"configkeys.h\"\n\n#ifndef PXT_UTF8\n#define PXT_UTF8 0\n#endif\n\n#if defined(PXT_VM)\n#include <stdint.h>\n#if UINTPTR_MAX == 0xffffffff\n#define PXT32 1\n#elif UINTPTR_MAX == 0xffffffffffffffff\n#define PXT64 1\n#else\n#error \"UINTPTR_MAX has invalid value\"\n#endif\n#endif\n\n#define intcheck(...) check(__VA_ARGS__)\n//#define intcheck(...) do {} while (0)\n\n#ifdef PXT_USE_FLOAT\n#define NUMBER float\n#else\n#define NUMBER double\n#endif\n\n#include <string.h>\n#include <stdint.h>\n#include <math.h>\n\n#ifdef POKY\nvoid *operator new(size_t size, void *ptr);\nvoid *operator new(size_t size);\n#else\n#include <new>\n#endif\n\n#include \"platform.h\"\n#include \"pxtcore.h\"\n\n#ifndef PXT_REGISTER_RESET\n#define PXT_REGISTER_RESET(fn) ((void)0)\n#endif\n\n#define PXT_REFCNT_FLASH 0xfffe\n\n#define CONCAT_1(a, b) a##b\n#define CONCAT_0(a, b) CONCAT_1(a, b)\n// already provided in some platforms, like mbedos\n#ifndef STATIC_ASSERT\n#define STATIC_ASSERT(e) enum { CONCAT_0(_static_assert_, __LINE__) = 1 / ((e) ? 1 : 0) };\n#endif\n\n#ifndef ramint_t\n// this type limits size of arrays\n#if defined(__linux__) || defined(PXT_VM)\n// TODO fix the inline array accesses to take note of this!\n#define ramint_t uint32_t\n#else\n#define ramint_t uint16_t\n#endif\n#endif\n\n#ifndef PXT_IN_ISR\n#define PXT_IN_ISR() (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk)\n#endif\n\n#ifdef POKY\ninline void *operator new(size_t, void *p) {\n    return p;\n}\ninline void *operator new[](size_t, void *p) {\n    return p;\n}\n#endif\n\nnamespace pxt {\n\ntemplate <typename T> inline const T &max(const T &a, const T &b) {\n    if (a < b)\n        return b;\n    return a;\n}\n\ntemplate <typename T> inline const T &min(const T &a, const T &b) {\n    if (a < b)\n        return a;\n    return b;\n}\n\ntemplate <typename T> inline void swap(T &a, T &b) {\n    T tmp = a;\n    a = b;\n    b = tmp;\n}\n\n//\n// Tagged values (assume 4 bytes for now, Cortex-M0)\n//\nstruct TValueStruct {};\ntypedef TValueStruct *TValue;\n\ntypedef TValue TNumber;\ntypedef TValue Action;\ntypedef TValue ImageLiteral;\n\n// To be implemented by the target\nextern \"C\" void target_panic(int error_code);\nextern \"C\" void target_reset();\nvoid sleep_ms(unsigned ms);\nvoid sleep_us(uint64_t us);\nvoid releaseFiber();\nuint64_t current_time_us();\nint current_time_ms();\nvoid initRuntime();\nvoid initSystemTimer();\nvoid sendSerial(const char *data, int len);\nvoid setSendToUART(void (*f)(const char *, int));\nuint64_t getLongSerialNumber();\nvoid registerWithDal(int id, int event, Action a, int flags = 16); // EVENT_LISTENER_DEFAULT_FLAGS\nvoid runInParallel(Action a);\nvoid runForever(Action a);\nvoid waitForEvent(int id, int event);\n//%\nunsigned afterProgramPage();\n//%\nvoid dumpDmesg();\nuint32_t hash_fnv1(const void *data, unsigned len);\n\n// also defined DMESG macro\n// end\n\n#define TAGGED_SPECIAL(n) (TValue)(void *)((n << 2) | 2)\n#define TAG_FALSE TAGGED_SPECIAL(2) // 10\n#define TAG_TRUE TAGGED_SPECIAL(16) // 66\n#define TAG_UNDEFINED (TValue)0\n#define TAG_NULL TAGGED_SPECIAL(1) // 6\n#define TAG_NAN TAGGED_SPECIAL(3)  // 14\n#define TAG_NUMBER(n) (TNumber)(void *)(((uintptr_t)(uint32_t)(n) << 1) | 1)\n#define TAG_NON_VALUE TAGGED_SPECIAL(4) // 18; doesn't represent any JS value\n\n#ifdef PXT_VM\ninline bool isEncodedDouble(uint64_t v) {\n    return (v >> 48) != 0;\n}\n#endif\n\ninline bool isDouble(TValue v) {\n#ifdef PXT64\n    return ((uintptr_t)v >> 48) != 0;\n#else\n    (void)v;\n    return false;\n#endif\n}\n\ninline bool isPointer(TValue v) {\n    return !isDouble(v) && v != 0 && ((intptr_t)v & 3) == 0;\n}\n\ninline bool isTagged(TValue v) {\n    return (!isDouble(v) && ((intptr_t)v & 3)) || !v;\n}\n\ninline bool isInt(TValue v) {\n    return !isDouble(v) && ((intptr_t)v & 1);\n}\n\ninline bool isSpecial(TValue v) {\n    return !isDouble(v) && ((intptr_t)v & 2);\n}\n\ninline bool bothNumbers(TValue a, TValue b) {\n    return !isDouble(a) && !isDouble(b) && ((intptr_t)a & (intptr_t)b & 1);\n}\n\ninline int numValue(TValue n) {\n    return (int)((intptr_t)n >> 1);\n}\n\ninline bool canBeTagged(int v) {\n    (void)v;\n#ifdef PXT_BOX_DEBUG\n    return false;\n#elif defined(PXT64)\n    return true;\n#else\n    return (v << 1) >> 1 == v;\n#endif\n}\n\n// see https://anniecherkaev.com/the-secret-life-of-nan\n\n#define NanBoxingOffset 0x1000000000000LL\n\ntemplate <typename TO, typename FROM> TO bitwise_cast(FROM in) {\n    STATIC_ASSERT(sizeof(TO) == sizeof(FROM));\n    union {\n        FROM from;\n        TO to;\n    } u;\n    u.from = in;\n    return u.to;\n}\n\ninline double decodeDouble(uint64_t v) {\n    return bitwise_cast<double>(v - NanBoxingOffset);\n}\n\n#ifdef PXT64\nSTATIC_ASSERT(sizeof(void *) == 8);\ninline double doubleVal(TValue v) {\n    return bitwise_cast<double>((uint64_t)v - NanBoxingOffset);\n}\n\ninline TValue tvalueFromDouble(double d) {\n    return (TValue)(bitwise_cast<uint64_t>(d) + NanBoxingOffset);\n}\n#else\nSTATIC_ASSERT(sizeof(void *) == 4);\n#endif\n\n// keep in sym with sim/control.ts\ntypedef enum {\n    PANIC_CODAL_OOM = 20,\n    PANIC_GC_OOM = 21,\n    PANIC_GC_TOO_BIG_ALLOCATION = 22,\n    PANIC_CODAL_HEAP_ERROR = 30,\n    PANIC_CODAL_NULL_DEREFERENCE = 40,\n    PANIC_CODAL_USB_ERROR = 50,\n    PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR = 90,\n\n    PANIC_INVALID_BINARY_HEADER = 901,\n    PANIC_OUT_OF_BOUNDS = 902,\n    PANIC_REF_DELETED = 903,\n    PANIC_SIZE = 904,\n    PANIC_INVALID_VTABLE = 905,\n    PANIC_INTERNAL_ERROR = 906,\n    PANIC_NO_SUCH_CONFIG = 907,\n    PANIC_NO_SUCH_PIN = 908,\n    PANIC_INVALID_ARGUMENT = 909,\n    PANIC_MEMORY_LIMIT_EXCEEDED = 910,\n    PANIC_SCREEN_ERROR = 911,\n    PANIC_MISSING_PROPERTY = 912,\n    PANIC_INVALID_IMAGE = 913,\n    PANIC_CALLED_FROM_ISR = 914,\n    PANIC_HEAP_DUMPED = 915,\n    PANIC_STACK_OVERFLOW = 916,\n    PANIC_BLOCKING_TO_STRING = 917,\n    PANIC_VM_ERROR = 918,\n    PANIC_SETTINGS_CLEARED = 920,\n    PANIC_SETTINGS_OVERLOAD = 921,\n    PANIC_SETTINGS_SECRET_MISSING = 922,\n    PANIC_DELETE_ON_CLASS = 923,\n    PANIC_OUT_OF_TIMERS = 924,\n    PANIC_JACDAC = 925,\n    PANIC_MICROPHONE_MISSING = 926,\n    PANIC_VARIANT_NOT_SUPPORTED = 927,\n\n    PANIC_CAST_FIRST = 980,\n    PANIC_CAST_FROM_UNDEFINED = 980,\n    PANIC_CAST_FROM_BOOLEAN = 981,\n    PANIC_CAST_FROM_NUMBER = 982,\n    PANIC_CAST_FROM_STRING = 983,\n    PANIC_CAST_FROM_OBJECT = 984,\n    PANIC_CAST_FROM_FUNCTION = 985,\n    PANIC_CAST_FROM_NULL = 989,\n\n    PANIC_UNHANDLED_EXCEPTION = 999,\n\n} PXT_PANIC;\n\nextern const uintptr_t functionsAndBytecode[];\nextern TValue *globals;\nextern uint16_t *bytecode;\nclass RefRecord;\n\n// Utility functions\n\ntypedef TValue (*RunActionType)(Action a, TValue arg0, TValue arg1, TValue arg2);\n\n#define asmRunAction3 ((RunActionType)(((uintptr_t *)bytecode)[12]))\n\nstatic inline TValue runAction3(Action a, TValue arg0, TValue arg1, TValue arg2) {\n    return asmRunAction3(a, arg0, arg1, 0);\n}\nstatic inline TValue runAction2(Action a, TValue arg0, TValue arg1) {\n    return asmRunAction3(a, arg0, arg1, 0);\n}\nstatic inline TValue runAction1(Action a, TValue arg0) {\n    return asmRunAction3(a, arg0, 0, 0);\n}\nstatic inline TValue runAction0(Action a) {\n    return asmRunAction3(a, 0, 0, 0);\n}\n\nclass RefAction;\nclass BoxedString;\nstruct VTable;\n\n//%\nAction mkAction(int totallen, RefAction *act);\n//% expose\nint templateHash();\n//% expose\nint programHash();\n//% expose\nBoxedString *programName();\n//% expose\nunsigned programSize();\n//%\nint getNumGlobals();\n//%\nRefRecord *mkClassInstance(VTable *vt);\n//%\nvoid debugMemLeaks();\n//%\nvoid anyPrint(TValue v);\n\n//%\nint getConfig(int key, int defl = -1);\n\n//%\nint toInt(TNumber v);\n//%\nunsigned toUInt(TNumber v);\n//%\nNUMBER toDouble(TNumber v);\n//%\nfloat toFloat(TNumber v);\n//%\nTNumber fromDouble(NUMBER r);\n//%\nTNumber fromFloat(float r);\n\n//%\nTNumber fromInt(int v);\n//%\nTNumber fromUInt(unsigned v);\n//%\nTValue fromBool(bool v);\n//%\nbool eq_bool(TValue a, TValue b);\n//%\nbool eqq_bool(TValue a, TValue b);\n\n//%\nvoid failedCast(TValue v, void *addr = NULL);\n//%\nvoid missingProperty(TValue v);\n\nvoid error(PXT_PANIC code, int subcode = 0);\nvoid exec_binary(unsigned *pc);\nvoid start();\n\nstruct HandlerBinding {\n    HandlerBinding *next;\n    int source;\n    int value;\n    Action action;\n#ifndef PXT_CODAL\n    uint32_t flags;\n    struct Event *pending;\n#endif\n};\nHandlerBinding *findBinding(int source, int value);\nHandlerBinding *nextBinding(HandlerBinding *curr, int source, int value);\nvoid setBinding(int source, int value, Action act);\n\n// Legacy stuff; should no longer be used\n//%\nTValue incr(TValue e);\n//%\nvoid decr(TValue e);\n\ninline TValue incr(TValue e) {\n    return e;\n}\ninline void decr(TValue e) {}\n\nclass RefObject;\n\nstatic inline RefObject *incrRC(RefObject *r) {\n    return r;\n}\nstatic inline void decrRC(RefObject *) {}\n\ninline void *ptrOfLiteral(int offset) {\n    return &bytecode[offset];\n}\n\n// Checks if object is ref-counted, and has a custom PXT vtable in front\n// TODO\ninline bool isRefCounted(TValue e) {\n    return isPointer(e);\n}\n\ninline void check(int cond, PXT_PANIC code, int subcode = 0) {\n    if (!cond)\n        error(code, subcode);\n}\n\ninline void oops(int subcode = 0) {\n    target_panic(800 + subcode);\n}\n\nclass RefObject;\n\ntypedef void (*RefObjectMethod)(RefObject *self);\ntypedef unsigned (*RefObjectSizeMethod)(RefObject *self);\ntypedef void *PVoid;\ntypedef void **PPVoid;\n\ntypedef void *Object_;\n\n#define VTABLE_MAGIC 0xF9\n#define VTABLE_MAGIC2 0xF8\n\nenum class ValType : uint8_t {\n    Undefined,\n    Boolean,\n    Number,\n    String,\n    Object,\n    Function,\n};\n\n// keep in sync with pxt-core (search for the type name)\nenum class BuiltInType : uint16_t {\n    BoxedString = 1,\n    BoxedNumber = 2,\n    BoxedBuffer = 3,\n    RefAction = 4,\n    RefImage = 5,\n    RefCollection = 6,\n    RefRefLocal = 7,\n    RefMap = 8,\n    RefMImage = 9,             // microbit-specific\n    MMap = 10,                 // linux, mostly ev3\n    BoxedString_SkipList = 11, // used by VM bytecode representation only\n    BoxedString_ASCII = 12,    // ditto\n    ZPin = 13,\n    User0 = 16,\n};\n\nstruct VTable {\n    uint16_t numbytes;\n    ValType objectType;\n    uint8_t magic;\n#ifdef PXT_VM\n    uint16_t ifaceHashEntries;\n    BuiltInType lastClassNo;\n#else\n    PVoid *ifaceTable;\n#endif\n    BuiltInType classNo;\n    uint16_t reserved;\n    uint32_t ifaceHashMult;\n\n    // we only use the first few methods here; pxt will generate more\n    PVoid methods[8];\n};\n\n//%\nextern const VTable string_inline_ascii_vt;\n#if PXT_UTF8\n//%\nextern const VTable string_inline_utf8_vt;\n//%\nextern const VTable string_cons_vt;\n//%\nextern const VTable string_skiplist16_vt;\n//%\nextern const VTable string_skiplist16_packed_vt;\n#endif\n//%\nextern const VTable buffer_vt;\n//%\nextern const VTable number_vt;\n//%\nextern const VTable RefAction_vtable;\n\n#ifndef PXT_IS_READONLY\n// assume ARM - ram addresses are 0x2000_0000+; flash is either 0x0+ or 0x0800_0000+\n#define PXT_IS_READONLY(v) (isTagged(v) || !((uintptr_t)v >> 28))\n#endif\n\ninline bool isReadOnly(TValue v) {\n    return PXT_IS_READONLY(v);\n}\n\n// A base abstract class for ref-counted objects.\nclass RefObject {\n  public:\n    const VTable *vtable;\n\n    RefObject(const VTable *vt) {\n#if defined(PXT32) && defined(PXT_VM) && !defined(PXT_ESP32)\n        if ((uint32_t)vt & 0xf0000000)\n            target_panic(PANIC_INVALID_VTABLE);\n#endif\n        vtable = vt;\n    }\n\n    void destroyVT();\n    void printVT();\n\n    inline uintptr_t vt() { return (uintptr_t)vtable; }\n    inline void setVT(uintptr_t v) { vtable = (const VTable *)v; }\n\n    inline void ref() {}\n    inline void unref() {}\n    inline bool isReadOnly() { return pxt::isReadOnly((TValue)this); }\n};\n\nclass Segment {\n  private:\n    TValue *data;\n    ramint_t length;\n    ramint_t size;\n\n    // this just gives max value of ramint_t\n    void growByMin(ramint_t minSize);\n    void ensure(ramint_t newSize);\n\n  public:\n    static constexpr ramint_t MaxSize = (((1U << (8 * sizeof(ramint_t) - 1)) - 1) << 1) + 1;\n    static constexpr TValue DefaultValue = TAG_UNDEFINED; // == NULL\n\n    Segment() : data(nullptr), length(0), size(0) {}\n\n    TValue get(unsigned i) { return i < length ? data[i] : NULL; }\n    void set(unsigned i, TValue value);\n\n    unsigned getLength() { return length; };\n    void setLength(unsigned newLength);\n\n    void push(TValue value) { set(length, value); }\n    TValue pop();\n\n    TValue remove(unsigned i);\n    void insert(unsigned i, TValue value);\n\n    void destroy();\n\n    void print();\n\n    TValue *getData() { return data; }\n};\n\n// Low-Level segment using system malloc\nclass LLSegment {\n  private:\n    TValue *data;\n    ramint_t length;\n    ramint_t size;\n\n  public:\n    LLSegment() : data(nullptr), length(0), size(0) {}\n\n    void set(unsigned idx, TValue v);\n    void push(TValue value) { set(length, value); }\n    TValue pop();\n    void destroy();\n    void setLength(unsigned newLen);\n\n    TValue get(unsigned i) { return i < length ? data[i] : NULL; }\n    unsigned getLength() { return length; };\n    TValue *getData() { return data; }\n};\n\n// A ref-counted collection of either primitive or ref-counted objects (String, Image,\n// user-defined record, another collection)\nclass RefCollection : public RefObject {\n  public:\n    Segment head;\n\n    RefCollection();\n\n    static void destroy(RefCollection *coll);\n    static void scan(RefCollection *coll);\n    static unsigned gcsize(RefCollection *coll);\n    static void print(RefCollection *coll);\n\n    unsigned length() { return head.getLength(); }\n    void setLength(unsigned newLength) { head.setLength(newLength); }\n    TValue getAt(int i) { return head.get(i); }\n    TValue *getData() { return head.getData(); }\n};\n\nclass RefMap : public RefObject {\n  public:\n    Segment keys;\n    Segment values;\n\n    RefMap();\n    static void destroy(RefMap *map);\n    static void scan(RefMap *map);\n    static unsigned gcsize(RefMap *coll);\n    static void print(RefMap *map);\n    int findIdx(BoxedString *key);\n};\n\n// A ref-counted, user-defined JS object.\nclass RefRecord : public RefObject {\n  public:\n    // The object is allocated, so that there is space at the end for the fields.\n    TValue fields[];\n\n    RefRecord(VTable *v) : RefObject(v) {}\n\n    TValue ld(int idx);\n    TValue ldref(int idx);\n    void st(int idx, TValue v);\n    void stref(int idx, TValue v);\n};\n\nstatic inline VTable *getVTable(RefObject *r) {\n    return (VTable *)(r->vt() & ~1);\n}\n\nstatic inline VTable *getAnyVTable(TValue v) {\n    if (!isRefCounted(v))\n        return NULL;\n    auto vt = getVTable((RefObject *)v);\n    if (vt->magic == VTABLE_MAGIC)\n        return vt;\n    return NULL;\n}\n\n// these are needed when constructing vtables for user-defined classes\n//%\nvoid RefRecord_destroy(RefRecord *r);\n//%\nvoid RefRecord_print(RefRecord *r);\n//%\nvoid RefRecord_scan(RefRecord *r);\n//%\nunsigned RefRecord_gcsize(RefRecord *r);\n\ntypedef TValue (*ActionCB)(TValue *captured, TValue arg0, TValue arg1, TValue arg2);\n\n// Ref-counted function pointer.\nclass RefAction : public RefObject {\n  public:\n    uint16_t len;\n    uint16_t numArgs;\n#ifdef PXT_VM\n    uint16_t initialLen;\n    uint16_t flags;\n    uintptr_t func;\n#else\n    ActionCB func; // The function pointer\n#endif\n    // fields[] contain captured locals\n    TValue fields[];\n\n    static void destroy(RefAction *act);\n    static void scan(RefAction *act);\n    static unsigned gcsize(RefAction *coll);\n    static void print(RefAction *act);\n\n    RefAction();\n\n    inline void stCore(int idx, TValue v) {\n        // DMESG(\"ST [%d] = %d \", idx, v); this->print();\n        intcheck(0 <= idx && idx < len, PANIC_OUT_OF_BOUNDS, 10);\n        intcheck(fields[idx] == 0, PANIC_OUT_OF_BOUNDS, 11); // only one assignment permitted\n        fields[idx] = v;\n    }\n};\n\n// These two are used to represent locals written from inside inline functions\nclass RefRefLocal : public RefObject {\n  public:\n    TValue v;\n    static void destroy(RefRefLocal *l);\n    static void scan(RefRefLocal *l);\n    static unsigned gcsize(RefRefLocal *l);\n    static void print(RefRefLocal *l);\n    RefRefLocal();\n};\n\ntypedef int color;\n\n// note: this is hardcoded in PXT (hexfile.ts)\n\nclass BoxedNumber : public RefObject {\n  public:\n    NUMBER num;\n    BoxedNumber() : RefObject(&number_vt) {}\n} __attribute__((packed));\n\nclass BoxedString : public RefObject {\n  public:\n    union {\n        struct {\n            uint16_t length; // ==size\n            char data[0];\n        } ascii;\n#if PXT_UTF8\n        struct {\n            uint16_t size;\n            char data[0];\n        } utf8;\n        struct {\n            BoxedString *left;\n            BoxedString *right;\n        } cons;\n        struct {\n            uint16_t size;   // in bytes\n            uint16_t length; // in characters\n            uint16_t *list;\n        } skip;\n        struct {\n            uint16_t size;   // in bytes\n            uint16_t length; // in characters\n            uint16_t list[0];\n        } skip_pack;\n#endif\n    };\n\n#if PXT_UTF8\n    uintptr_t runMethod(int idx) {\n        return ((uintptr_t(*)(BoxedString *))vtable->methods[idx])(this);\n    }\n    const char *getUTF8Data() { return (const char *)runMethod(4); }\n    uint32_t getUTF8Size() { return (uint32_t)runMethod(5); }\n    // in characters\n    uint32_t getLength() { return (uint32_t)runMethod(6); }\n    const char *getUTF8DataAt(uint32_t pos) {\n        auto meth = ((const char *(*)(BoxedString *, uint32_t))vtable->methods[7]);\n        return meth(this, pos);\n    }\n#else\n    const char *getUTF8Data() { return ascii.data; }\n    uint32_t getUTF8Size() { return ascii.length; }\n    uint32_t getLength() { return ascii.length; }\n    const char *getUTF8DataAt(uint32_t pos) { return pos < ascii.length ? ascii.data + pos : NULL; }\n#endif\n\n    TNumber charCodeAt(int pos);\n\n    BoxedString(const VTable *vt) : RefObject(vt) {}\n};\n\n// cross version compatible way of accessing string data\n#ifndef PXT_STRING_DATA\n#define PXT_STRING_DATA(str) str->getUTF8Data()\n#endif\n\n// cross version compatible way of accessing string length\n#ifndef PXT_STRING_DATA_LENGTH\n#define PXT_STRING_DATA_LENGTH(str) str->getUTF8Size()\n#endif\n\nclass BoxedBuffer : public RefObject {\n  public:\n    // data needs to be word-aligned, so we use 32 bits for length\n    int length;\n    uint8_t data[0];\n    BoxedBuffer() : RefObject(&buffer_vt) {}\n\n    static bool isInstance(TValue v);\n};\n\n// cross version compatible way of access data field\n#ifndef PXT_BUFFER_DATA\n#define PXT_BUFFER_DATA(buffer) buffer->data\n#endif\n\n// cross version compatible way of access data length\n#ifndef PXT_BUFFER_LENGTH\n#define PXT_BUFFER_LENGTH(buffer) buffer->length\n#endif\n\n#ifndef PXT_CREATE_BUFFER\n#define PXT_CREATE_BUFFER(data, len) pxt::mkBuffer(data, len)\n#endif\n\n// Legacy format:\n// the first byte of data indicates the format - currently 0xE1 or 0xE4 to 1 or 4 bit bitmaps\n// second byte indicates width in pixels\n// third byte indicates the height (which should also match the size of the buffer)\n// just like ordinary buffers, these can be layed out in flash\n\n// Current format:\n// 87 BB WW WW HH HH 00 00 DATA\n// that is: 0x87, 0x01 or 0x04 - bpp, width in little endian, height, 0x00, 0x00 followed by data\n// for 4 bpp images, rows are word-aligned (as in legacy)\n\n#define IMAGE_HEADER_MAGIC 0x87\n\nstruct ImageHeader {\n    uint8_t magic;\n    uint8_t bpp;\n    uint16_t width;\n    uint16_t height;\n    uint16_t padding;\n    uint8_t pixels[0];\n};\n\nclass RefImage : public RefObject {\n  public:\n    BoxedBuffer *buffer;\n    uint32_t revision;\n\n    RefImage(BoxedBuffer *buf);\n    RefImage(uint32_t sz);\n\n    void setBuffer(BoxedBuffer *b);\n\n    uint8_t *data() { return buffer->data; }\n    int length() { return (int)buffer->length; }\n\n    ImageHeader *header() { return (ImageHeader *)buffer->data; }\n    int pixLength() { return length() - sizeof(ImageHeader); }\n\n    int width() { return header()->width; }\n    int height() { return header()->height; }\n    int wordHeight();\n    int bpp() { return header()->bpp; }\n\n    bool hasPadding() { return (height() & 0x7) != 0; }\n\n    uint8_t *pix() { return header()->pixels; }\n\n    int byteHeight() {\n        if (bpp() == 1)\n            return (height() + 7) >> 3;\n        else if (bpp() == 4)\n            return ((height() * 4 + 31) >> 5) << 2;\n        else {\n            oops(21);\n            return -1;\n        }\n    }\n\n    uint8_t *pix(int x, int y) {\n        uint8_t *d = &pix()[byteHeight() * x];\n        if (y) {\n            if (bpp() == 1)\n                d += y >> 3;\n            else if (bpp() == 4)\n                d += y >> 1;\n        }\n        return d;\n    }\n\n    uint8_t fillMask(color c);\n    bool inRange(int x, int y);\n    void clamp(int *x, int *y);\n    void makeWritable();\n\n    static void destroy(RefImage *t);\n    static void scan(RefImage *t);\n    static unsigned gcsize(RefImage *t);\n    static void print(RefImage *t);\n};\n\nRefImage *mkImage(int w, int h, int bpp);\n\ntypedef BoxedBuffer *Buffer;\ntypedef BoxedString *String;\ntypedef RefImage *Image_;\n\nuint32_t toRealUTF8(String str, uint8_t *dst);\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\n    UInt32LE,\n    UInt32BE,\n    Float32LE,\n    Float64LE,\n    Float32BE,\n    Float64BE,\n};\n\n// this will, unlike mkStringCore, UTF8-canonicalize the data\nString mkString(const char *data, int len = -1);\n// data can be NULL in both cases\nBuffer mkBuffer(const void *data, int len);\nString mkStringCore(const char *data, int len = -1);\n\nTNumber getNumberCore(uint8_t *buf, int size, NumberFormat format);\nvoid setNumberCore(uint8_t *buf, int size, NumberFormat format, TNumber value);\n\nvoid seedRandom(unsigned seed);\nvoid seedAddRandom(unsigned seed);\n// max is inclusive\nunsigned getRandom(unsigned max);\n\nValType valType(TValue v);\n\n// this is equivalent to JS `throw v`; it will leave\n// the current function(s), all the way until the nearest try block and\n// ignore all destructors (think longjmp())\nvoid throwValue(TValue v);\n\nvoid registerGC(TValue *root, int numwords = 1);\nvoid unregisterGC(TValue *root, int numwords = 1);\nvoid registerGCPtr(TValue ptr);\nvoid unregisterGCPtr(TValue ptr);\nstatic inline void registerGCObj(RefObject *ptr) {\n    registerGCPtr((TValue)ptr);\n}\nstatic inline void unregisterGCObj(RefObject *ptr) {\n    unregisterGCPtr((TValue)ptr);\n}\nvoid gc(int flags);\n\nstruct StackSegment {\n    void *top;\n    void *bottom;\n    StackSegment *next;\n};\n\n#define NUM_TRY_FRAME_REGS 3\nstruct TryFrame {\n    TryFrame *parent;\n    uintptr_t registers[NUM_TRY_FRAME_REGS];\n};\n\nstruct ThreadContext {\n    TValue *globals;\n    StackSegment stack;\n    TryFrame *tryFrame;\n    TValue thrownValue;\n#ifdef PXT_GC_THREAD_LIST\n    ThreadContext *next;\n    ThreadContext *prev;\n#endif\n};\n\n#ifdef PXT_GC_THREAD_LIST\nextern ThreadContext *threadContexts;\nvoid *threadAddressFor(ThreadContext *, void *sp);\n#endif\n\nvoid releaseThreadContext(ThreadContext *ctx);\nThreadContext *getThreadContext();\nvoid setThreadContext(ThreadContext *ctx);\n\n#ifndef PXT_GC_THREAD_LIST\nvoid gcProcessStacks(int flags);\n#endif\n\nvoid gcProcess(TValue v);\nvoid gcFreeze();\n\n#ifdef PXT_VM\nvoid gcStartup();\nvoid gcPreStartup();\n#endif\n\nvoid coreReset();\nvoid gcReset();\nvoid systemReset();\n\nvoid doNothing();\n\nvoid *gcAllocate(int numbytes);\nvoid *gcAllocateArray(int numbytes);\nextern \"C\" void *app_alloc(int numbytes);\nextern \"C\" void *app_free(void *ptr);\nextern \"C\" void *app_alloc_at(void *at, int numbytes);\nvoid gcPreAllocateBlock(uint32_t sz);\n\nint redirectSamples(int16_t *dst, int numsamples, int samplerate);\n\n#ifdef PXT64\n#define TOWORDS(bytes) (((bytes) + 7) >> 3)\n#else\n#define TOWORDS(bytes) (((bytes) + 3) >> 2)\n#endif\n\n#ifndef PXT_VM\n#define soft_panic target_panic\n#endif\n\nextern int debugFlags;\n\nenum class PerfCounters {\n    GC,\n};\n\n#ifdef PXT_PROFILE\n#ifndef PERF_NOW\n#error \"missing platform timer support\"\n#endif\n\n#ifndef PERF_NOW_MASK\n#define PERF_NOW_MASK 0xffffffff\n#endif\n\n#ifndef PERF_NOW_SCALE\n#define PERF_NOW_SCALE 1\n#endif\n\nstruct PerfCounter {\n    uint32_t value;\n    uint32_t numstops;\n    uint32_t start;\n};\n\nextern struct PerfCounter *perfCounters;\n\nvoid initPerfCounters();\n//%\nvoid dumpPerfCounters();\n//%\nvoid startPerfCounter(PerfCounters n);\n//%\nvoid stopPerfCounter(PerfCounters n);\n#else\ninline void startPerfCounter(PerfCounters n) {}\ninline void stopPerfCounter(PerfCounters n) {}\ninline void initPerfCounters() {}\ninline void dumpPerfCounters() {}\n#endif\n\n// Handling of built-in string literals (like \"[Object]\", \"true\" etc.).\n\n// This has the same layout as BoxedString, but has statically allocated buffer\ntemplate <size_t N> struct BoxedStringLayout {\n    const void *vtable;\n    uint16_t size;\n    const char data[N];\n};\n\ntemplate <size_t N> constexpr size_t _boxedStringLen(char const (&)[N]) {\n    return N;\n}\n\n// strings defined here as used as (String)name\n#define PXT_DEF_STRING(name, val)                                                                  \\\n    const BoxedStringLayout<_boxedStringLen(val)> name[1] = {                                      \\\n        {&pxt::string_inline_ascii_vt, _boxedStringLen(val) - 1, val}};\n\n// bigger value - less memory, but slower\n// 16/20 keeps s.length and s.charCodeAt(i) at about 200 cycles (for actual unicode strings),\n// which is similar to amortized allocation time\n#define PXT_STRING_SKIP_INCR 16 // needs to be power of 2; needs to be kept in sync with compiler\n#define PXT_STRING_MIN_SKIP                                                                        \\\n    20 // min. size of string to use skip list; static code has its own limit\n\n#define PXT_NUM_SKIP_ENTRIES(p) ((p)->skip.length / PXT_STRING_SKIP_INCR)\n#define PXT_SKIP_DATA_IND(p) ((const char *)(p->skip.list + PXT_NUM_SKIP_ENTRIES(p)))\n#define PXT_SKIP_DATA_PACK(p) ((const char *)(p->skip_pack.list + PXT_NUM_SKIP_ENTRIES(p)))\n\n} // namespace pxt\n\nusing namespace pxt;\n\nnamespace numops {\n//%\nString toString(TValue v);\n//%\nint toBool(TValue v);\n//%\nint toBoolDecr(TValue v);\n} // namespace numops\n\nnamespace pxt {\ninline bool toBoolQuick(TValue v) {\n    if (v == TAG_TRUE)\n        return true;\n    if (v == TAG_FALSE || v == TAG_UNDEFINED || v == TAG_NULL)\n        return false;\n    return numops::toBool(v);\n}\n} // namespace pxt\n\nnamespace pxtrt {\n//%\nRefMap *mkMap();\n//%\nTValue mapGetByString(RefMap *map, String key);\n//%\nint lookupMapKey(String key);\n//%\nTValue mapGet(RefMap *map, unsigned key);\n//% expose\nvoid mapSetByString(RefMap *map, String key, TValue val);\n//%\nvoid mapSet(RefMap *map, unsigned key, TValue val);\n} // namespace pxtrt\n\nnamespace pins {\nBuffer createBuffer(int size);\n}\n\nnamespace String_ {\n//%\nint compare(String a, String b);\n} // namespace String_\n\nnamespace Array_ {\n//%\nRefCollection *mk();\n//%\nint length(RefCollection *c);\n//%\nvoid setLength(RefCollection *c, int newLength);\n//%\nvoid push(RefCollection *c, TValue x);\n//%\nTValue pop(RefCollection *c);\n//%\nTValue getAt(RefCollection *c, int x);\n//%\nvoid setAt(RefCollection *c, int x, TValue y);\n//%\nTValue removeAt(RefCollection *c, int x);\n//%\nvoid insertAt(RefCollection *c, int x, TValue value);\n//%\nint indexOf(RefCollection *c, TValue x, int start);\n//%\nbool removeElement(RefCollection *c, TValue x);\n} // namespace Array_\n\n#define NEW_GC(T, ...) new (gcAllocate(sizeof(T))) T(__VA_ARGS__)\n\n// The ARM Thumb generator in the JavaScript code is parsing\n// the hex file and looks for the magic numbers as present here.\n//\n// Then it fetches function pointer addresses from there.\n//\n// The vtable pointers are there, so that the ::emptyData for various types\n// can be patched with the right vtable.\n//\n#define PXT_SHIMS_BEGIN                                                                            \\\n    namespace pxt {                                                                                \\\n    const uintptr_t functionsAndBytecode[]                                                         \\\n        __attribute__((aligned(0x20))) = {0x08010801, 0x42424242, 0x08010801, 0x8de9d83e,\n\n#define PXT_SHIMS_END                                                                              \\\n    }                                                                                              \\\n    ;                                                                                              \\\n    }\n\n#if !defined(X86_64) && !defined(PXT_VM)\n#pragma GCC diagnostic ignored \"-Wpmf-conversions\"\n#endif\n\n#ifdef PXT_VM\n#define DEF_VTABLE(name, tp, valtype, ...)                                                         \\\n    const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC, 0, BuiltInType::tp, BuiltInType::tp,   \\\n                         0,          0,       {__VA_ARGS__}};\n#define DEF_VTABLE_EXT(name, tp, valtype, ...)                                                     \\\n    const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC2, 0, BuiltInType::tp, BuiltInType::tp,  \\\n                         0,          0,       {__VA_ARGS__}};\n#else\n#define DEF_VTABLE(name, tp, valtype, ...)                                                         \\\n    const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC, 0, BuiltInType::tp,                    \\\n                         0,          0,       {__VA_ARGS__}};\n#define DEF_VTABLE_EXT(name, tp, valtype, ...)                                                     \\\n    const VTable name = {sizeof(tp), valtype, VTABLE_MAGIC2, 0, BuiltInType::tp,                   \\\n                         0,          0,       {__VA_ARGS__}};\n#endif\n\n#define PXT_VTABLE(classname, valtp)                                                               \\\n    DEF_VTABLE(classname##_vtable, classname, valtp, (void *)&classname::destroy,                  \\\n               (void *)&classname::print, (void *)&classname::scan, (void *)&classname::gcsize)\n\n#define PXT_EXT_VTABLE(classname)                                                                  \\\n    static int classname##_gcsize() { return sizeof(classname); }                                  \\\n    DEF_VTABLE_EXT(classname##_vtable, classname, ValType::Object, (void *)&pxt::doNothing,        \\\n                   (void *)&pxt::anyPrint, (void *)&pxt::doNothing, (void *)&classname##_gcsize)\n\n#define PXT_VTABLE_INIT(classname) RefObject(&classname##_vtable)\n\n#define PXT_VTABLE_CTOR(classname)                                                                 \\\n    PXT_VTABLE(classname, ValType::Object)                                                         \\\n    classname::classname() : PXT_VTABLE_INIT(classname)\n\n#define PXT_MAIN                                                                                   \\\n    int main() {                                                                                   \\\n        pxt::start();                                                                              \\\n        return 0;                                                                                  \\\n    }\n\n#define PXT_FNPTR(x) (uintptr_t)(void *)(x)\n\n#define PXT_ABI(...)\n\n#define JOIN(a, b) a##b\n/// Defines getClassName() function to fetch the singleton\n#define SINGLETON(ClassName)                                                                       \\\n    static ClassName *JOIN(inst, ClassName);                                                       \\\n    ClassName *JOIN(get, ClassName)() {                                                            \\\n        if (!JOIN(inst, ClassName))                                                                \\\n            JOIN(inst, ClassName) = new ClassName();                                               \\\n        return JOIN(inst, ClassName);                                                              \\\n    }\n\n/// Defines getClassName() function to fetch the singleton if PIN present\n#define SINGLETON_IF_PIN(ClassName, pin)                                                           \\\n    static ClassName *JOIN(inst, ClassName);                                                       \\\n    ClassName *JOIN(get, ClassName)() {                                                            \\\n        if (!JOIN(inst, ClassName) && LOOKUP_PIN(pin))                                             \\\n            JOIN(inst, ClassName) = new ClassName();                                               \\\n        return JOIN(inst, ClassName);                                                              \\\n    }\n\n#ifdef PXT_VM\n#include \"vm.h\"\n#endif\n\n#endif\n","scheduling.ts":"/**\n * Calls a function with a fixed time delay between each call to that function.\n * @param func \n * @param delay \n */\n//%\nfunction setInterval(func: () => void, delay: number): number {\n    delay = Math.max(10, delay | 0);\n    return control.setInterval(func, delay, control.IntervalMode.Interval);\n}\n\n/**\n * Cancels repeated action which was set up using setInterval().\n * @param intervalId \n */\n//%\nfunction clearInterval(intervalId: number) {\n    control.clearInterval(intervalId, control.IntervalMode.Interval);\n}\n\n/**\n * Calls a function after specified delay.\n * @param func \n * @param delay \n */\n//%\nfunction setTimeout(func: () => void, delay: number): number {\n    return control.setInterval(func, delay, control.IntervalMode.Timeout);\n}\n\n/**\n * Clears the delay set by setTimeout().\n * @param intervalId \n */\n//%\nfunction clearTimeout(intervalId: number) {\n    control.clearInterval(intervalId, control.IntervalMode.Timeout);\n}\n\n/**\n * Calls a function as soon as possible.\n * @param func \n */\n//%\nfunction setImmediate(func: () => void): number {\n    return control.setInterval(func, 0, control.IntervalMode.Immediate);\n}\n\n/**\n * Cancels the immediate actions.\n * @param intervalId \n */\n//%\nfunction clearImmediate(intervalId: number) {\n    control.clearInterval(intervalId, control.IntervalMode.Immediate);\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\n\n\n\n    //% indexerGet=BufferMethods::getByte indexerSet=BufferMethods::setByte\ndeclare interface Buffer {\n    /**\n     * Reads an unsigned byte at a particular location\n     */\n    //% shim=BufferMethods::getUint8\n    getUint8(off: int32): int32;\n\n    /**\n     * Returns false when the buffer can be written to.\n     */\n    //% shim=BufferMethods::isReadOnly\n    isReadOnly(): boolean;\n\n    /**\n     * Writes an unsigned byte at a particular location\n     */\n    //% shim=BufferMethods::setUint8\n    setUint8(off: int32, v: int32): void;\n\n    /**\n     * Write a number in specified format in the buffer.\n     */\n    //% shim=BufferMethods::setNumber\n    setNumber(format: NumberFormat, offset: int32, value: number): void;\n\n    /**\n     * Read a number in specified format from the buffer.\n     */\n    //% shim=BufferMethods::getNumber\n    getNumber(format: NumberFormat, offset: int32): number;\n\n    /** Returns the length of a Buffer object. */\n    //% property shim=BufferMethods::length\n    length: int32;\n\n    /**\n     * Fill (a fragment) of the buffer with given value.\n     */\n    //% offset.defl=0 length.defl=-1 shim=BufferMethods::fill\n    fill(value: int32, offset?: int32, length?: int32): void;\n\n    /**\n     * Return a copy of a fragment of a buffer.\n     */\n    //% offset.defl=0 length.defl=-1 shim=BufferMethods::slice\n    slice(offset?: int32, length?: int32): Buffer;\n\n    /**\n     * Shift buffer left in place, with zero padding.\n     * @param offset number of bytes to shift; use negative value to shift right\n     * @param start start offset in buffer. Default is 0.\n     * @param length number of elements in buffer. If negative, length is set as the buffer length minus\n     * start. eg: -1\n     */\n    //% start.defl=0 length.defl=-1 shim=BufferMethods::shift\n    shift(offset: int32, start?: int32, length?: int32): void;\n\n    /**\n     * Convert a buffer to string assuming UTF8 encoding\n     */\n    //% shim=BufferMethods::toString\n    toString(): string;\n\n    /**\n     * Convert a buffer to its hexadecimal representation.\n     */\n    //% shim=BufferMethods::toHex\n    toHex(): string;\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    //% start.defl=0 length.defl=-1 shim=BufferMethods::rotate\n    rotate(offset: int32, start?: int32, length?: int32): void;\n\n    /**\n     * Write contents of `src` at `dstOffset` in current buffer.\n     */\n    //% shim=BufferMethods::write\n    write(dstOffset: int32, src: Buffer): void;\n\n    /**\n     * Compute k-bit FNV-1 non-cryptographic hash of the buffer.\n     */\n    //% shim=BufferMethods::hash\n    hash(bits: int32): uint32;\n}\ndeclare namespace control {\n\n    /**\n     * Create a new zero-initialized buffer.\n     * @param size number of bytes in the buffer\n     */\n    //% deprecated=1 shim=control::createBuffer\n    function createBuffer(size: int32): Buffer;\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 shim=control::createBufferFromUTF8\n    function createBufferFromUTF8(str: string): Buffer;\n}\ndeclare namespace loops {\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=loops/forever weight=100 afterOnStart=true deprecated=true\n    //% blockId=forever_deprecated block=\"forever\" blockAllowMultiple=1 shim=loops::forever\n    function forever(a: () => void): void;\n\n    /**\n     * Pause for the specified time in milliseconds\n     * @param ms how long to pause for, eg: 100, 200, 500, 1000, 2000\n     */\n    //% help=loops/pause weight=99 deprecated=true\n    //% async block=\"pause %pause=timePicker|ms\"\n    //% blockId=device_pause_deprecated shim=loops::pause\n    function pause(ms: int32): void;\n}\ndeclare namespace control {\n\n    /**\n     * Gets the number of milliseconds elapsed since power on.\n     */\n    //% help=control/millis weight=50\n    //% blockId=control_running_time block=\"millis (ms)\" shim=control::millis\n    function millis(): int32;\n\n    /**\n     * Gets current time in microseconds. Overflows every ~18 minutes.\n     */\n    //% shim=control::micros\n    function micros(): int32;\n\n    /**\n     * Used internally\n     */\n    //% flags.defl=16 shim=control::internalOnEvent\n    function internalOnEvent(src: int32, value: int32, handler: () => void, flags?: int32): void;\n\n    /**\n     * Reset the device.\n     */\n    //% weight=30 async help=control/reset blockGap=8\n    //% blockId=\"control_reset\" block=\"reset\" shim=control::reset\n    function reset(): void;\n\n    /**\n     * Block 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 async\n    //% blockId=\"control_wait_us\" block=\"wait (µs)%micros\" shim=control::waitMicros\n    function waitMicros(micros: int32): void;\n\n    /**\n     * Run other code in the parallel.\n     */\n    //% help=control/run-in-parallel handlerStatement=1\n    //% blockId=\"control_run_in_parallel\" block=\"run in parallel\" blockGap=8 shim=control::runInParallel\n    function runInParallel(a: () => void): void;\n\n    /**\n     * Blocks the calling thread until the specified event is raised.\n     */\n    //% help=control/wait-for-event async\n    //% blockId=control_wait_for_event block=\"wait for event|from %src|with value %value\" shim=control::waitForEvent\n    function waitForEvent(src: int32, value: int32): void;\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    //% help=control/device-serial-number shim=control::deviceSerialNumber\n    function deviceSerialNumber(): int32;\n\n    /**\n     * Derive a unique, consistent 64-bit serial number of this device from internal data.\n     */\n    //% blockId=\"control_device_long_serial_number\" block=\"device long serial number\" weight=9\n    //% help=control/device-long-serial-number shim=control::deviceLongSerialNumber\n    function deviceLongSerialNumber(): Buffer;\n\n    /**\n     *\n     */\n    //% shim=control::__log\n    function __log(prority: int32, text: string): void;\n\n    /**\n     * Dump internal information about a value.\n     */\n    //% shim=control::dmesgValue\n    function dmesgValue(v: any): void;\n}\ndeclare namespace control {\n\n    /**\n     * Force GC and dump basic information about heap.\n     */\n    //% shim=control::gc\n    function gc(): void;\n\n    /**\n     * Force GC and halt waiting for debugger to do a full heap dump.\n     */\n    //% shim=control::heapDump\n    function heapDump(): void;\n\n    /**\n     * Set flags used when connecting an external debugger.\n     */\n    //% shim=control::setDebugFlags\n    function setDebugFlags(flags: int32): void;\n\n    /**\n     * Record a heap snapshot to debug memory leaks.\n     */\n    //% shim=control::heapSnapshot\n    function heapSnapshot(): void;\n\n    /**\n     * Return true if profiling is enabled in the current build.\n     */\n    //% shim=control::profilingEnabled\n    function profilingEnabled(): boolean;\n}\n\n// Auto-generated. Do not edit. Really.\n","templates.ts":"/**\n * Tagged hex literal converter\n */\n//% shim=@hex\nfunction hex(lits: any, ...args: any[]): Buffer { return null }\n","test.ts":"let i = 1\nlet f = 0.5\nlet plus = i + f\nlet minus = i - f\n\nlet r = Math.random()\nlet ri = Math.randomRange(5, 10)\n\n\nfunction check(cond:boolean) { control.assert(cond, 108) }\n\ncheck(Buffer.pack(\"<2h\", [0x3412, 0x7856]).toHex() == \"12345678\")\ncheck(Buffer.pack(\">hh\", [0x3412, 0x7856]).toHex() == \"34127856\")\ncheck(Buffer.fromHex(\"F00d\").toHex() == \"f00d\")","trig.cpp":"#include \"pxtbase.h\"\n#include <limits.h>\n#include <stdlib.h>\n\nusing namespace std;\n\nnamespace Math_ {\n\n#define SINGLE(op) return fromDouble(::op(toDouble(x)));\n\n//%\nTNumber atan2(TNumber y, TNumber x) {\n    return fromDouble(::atan2(toDouble(y), toDouble(x)));\n}\n\n//%\nTNumber tan(TNumber x){SINGLE(tan)}\n\n//%\nTNumber sin(TNumber x){SINGLE(sin)}\n\n//%\nTNumber cos(TNumber x){SINGLE(cos)}\n\n//%\nTNumber atan(TNumber x){SINGLE(atan)}\n\n//%\nTNumber asin(TNumber x){SINGLE(asin)}\n\n//%\nTNumber acos(TNumber x){SINGLE(acos)}\n\n//%\nTNumber sqrt(TNumber x){SINGLE(sqrt)}\n\n}","utfdecoder.ts":"class UTF8Decoder {\n    private buf: Buffer;\n\n    constructor() {\n        this.buf = undefined;\n    }\n\n    add(buf: Buffer) {\n        if (!buf || !buf.length) return;\n\n        if (!this.buf)\n            this.buf = buf;\n        else {\n            const b = control.createBuffer(this.buf.length + buf.length);\n            b.write(0, this.buf);\n            b.write(this.buf.length, buf);\n            this.buf = b;\n        }\n    }\n\n    decodeUntil(delimiter: number): string {\n        if (!this.buf) return undefined;\n        delimiter = delimiter | 0;\n        let i = 0;\n        for (; i < this.buf.length; ++i) {\n            const c = this.buf[i];\n            // skip multi-chars\n            if ((c & 0xe0) == 0xc0)\n                i += 1;\n            else if ((c & 0xf0) == 0xe0)\n                i += 2;\n            else if (c == delimiter) {\n                // found it\n                break;\n            }\n        }\n\n        if (i >= this.buf.length)\n            return undefined;\n        else {\n            const s = this.buf.slice(0, i).toString();\n            if (i + 1 == this.buf.length)\n                this.buf = undefined;\n            else\n                this.buf = this.buf.slice(i + 1);\n            return s;\n        }\n    }\n\n    decode(): string {\n        if (!this.buf) return \"\";\n\n        // scan the end of the buffer for partial characters\n        let length = 0;\n        for (let i = this.buf.length - 1; i >= 0; i--) {\n            const c = this.buf[i];\n            if ((c & 0x80) == 0) {\n                length = i + 1;\n                break;\n            }\n            else if ((c & 0xe0) == 0xc0) {\n                length = i + 2;\n                break;\n            }\n            else if ((c & 0xf0) == 0xe0) {\n                length = i + 3;\n                break;\n            }\n        }\n        // is last beyond the end?\n        if (length == this.buf.length) {\n            const s = this.buf.toString();\n            this.buf = undefined;\n            return s;\n        } else if (length == 0) { // data yet\n            return \"\";\n        } else {\n            const s = this.buf.slice(0, length).toString();\n            this.buf = this.buf.slice(length);\n            return s;\n        }\n    }\n}"},"buttons":{"README.md":"# buttons\n\nA library to handle 2 buttons A and B.\n","buttons.cpp":"#include \"pxt.h\"\n\n/*\n\nThese button events need CODAL work.\n\n    // % block=\"double click\"\n    DoubleClick = DEVICE_BUTTON_EVT_DOUBLE_CLICK,\n\n    // % block=\"hold\"\n    Hold = DEVICE_BUTTON_EVT_HOLD\n\n*/\n\n/**\n * User interaction on buttons\n */\nenum class ButtonEvent {\n    //% block=\"click\"\n    Click = DEVICE_BUTTON_EVT_CLICK,\n    //% block=\"long click\"\n    LongClick = DEVICE_BUTTON_EVT_LONG_CLICK,\n    //% block=\"up\"\n    Up = DEVICE_BUTTON_EVT_UP,\n    //% block=\"down\"\n    Down = DEVICE_BUTTON_EVT_DOWN\n};\n\nnamespace pxt {\n//%\nButton *getButtonByPin(int pin, int flags) {\n    unsigned highflags = (unsigned)pin >> 16;\n    if (highflags & 0xff)\n        flags = highflags & 0xff;\n\n    pin &= 0xffff;\n\n    auto cpid = DEVICE_ID_FIRST_BUTTON + pin;\n    auto btn = (Button *)lookupComponent(cpid);\n    if (btn == NULL) {\n        auto pull = PullMode::None;\n        if ((flags & 0xf0) == 0x10)\n            pull = PullMode::Down;\n        else if ((flags & 0xf0) == 0x20)\n            pull = PullMode::Up;\n        else if ((flags & 0xf0) == 0x30)\n            pull = PullMode::None;\n        else\n            oops(3);\n        // GCTODO\n        btn = new Button(*lookupPin(pin), cpid, DEVICE_BUTTON_ALL_EVENTS,\n                                 (ButtonPolarity)(flags & 0xf), pull);\n    }\n    return btn;\n}\n\n//%\nButton *getButtonByPinCfg(int key, int flags) {\n    int pin = getConfig(key);\n    if (pin == -1)\n        soft_panic(PANIC_NO_SUCH_CONFIG);\n    return getButtonByPin(pin, flags);\n}\n\nMultiButton *getMultiButton(int id, int pinA, int pinB, int flags) {\n    auto btn = (MultiButton *)lookupComponent(id);\n    if (btn == NULL) {\n        auto bA = getButtonByPin(pinA, flags);\n        auto bB = getButtonByPin(pinB, flags);\n        // GCTODO\n        btn = new MultiButton(bA->id, bB->id, id);\n\n        // A user has registered to receive events from the buttonAB multibutton.\n        // Disable click events from being generated by ButtonA and ButtonB, and defer the\n        // control of this to the multibutton handler.\n        //\n        // This way, buttons look independent unless a buttonAB is requested, at which\n        // point button A+B clicks can be correclty handled without breaking\n        // causal ordering.\n        bA->setEventConfiguration(DEVICE_BUTTON_SIMPLE_EVENTS);\n        bB->setEventConfiguration(DEVICE_BUTTON_SIMPLE_EVENTS);\n        btn->setEventConfiguration(DEVICE_BUTTON_ALL_EVENTS);\n    }\n    return btn;\n}\n\n// This is for A, B, and AB\n//%\nAbstractButton *getButton(int id) {\n    int pa = getConfig(CFG_PIN_BTN_A);\n    int pb = getConfig(CFG_PIN_BTN_B);\n    int flags = getConfig(CFG_DEFAULT_BUTTON_MODE, BUTTON_ACTIVE_LOW_PULL_UP);\n    if (id == 0)\n        return getButtonByPin(pa, flags);\n    else if (id == 1)\n        return getButtonByPin(pb, flags);\n    else if (id == 2)\n        return getMultiButton(DEVICE_ID_BUTTON_AB, pa, pb, flags);\n    else {\n        soft_panic(PANIC_INVALID_ARGUMENT);\n        return NULL;\n    }\n}\n\n} // namespace pxt\n\nnamespace DigitalInOutPinMethods {\n\n/**\n * Get the push button (connected to GND) for given pin\n */\n//%\nButton_ pushButton(DigitalInOutPin pin) {\n    return pxt::getButtonByPin(pin->name, BUTTON_ACTIVE_LOW_PULL_UP);\n}\n\n} // namespace DigitalInOutPinMethods\n\n//% noRefCounting fixedInstances\nnamespace ButtonMethods {\n/**\n * Do something when a button (`A`, `B` or both `A` + `B`) is clicked, double clicked, etc...\n * @param button the button that needs to be clicked or used\n * @param event the kind of button gesture that needs to be detected\n * @param body code to run when the event is raised\n */\n//% help=input/button/on-event\n//% blockId=buttonEvent block=\"on %button|%event\"\n//% blockNamespace=input\n//% button.fieldEditor=\"gridpicker\"\n//% button.fieldOptions.width=220\n//% button.fieldOptions.columns=3\n//% weight=96 blockGap=12\n//% trackArgs=0\nvoid onEvent(Button_ button, ButtonEvent ev, Action body) {\n    registerWithDal(button->id, (int)ev, body);\n}\n\n/**\n * Check if a button is pressed or not.\n * @param button the button to query the request\n */\n//% help=input/button/is-pressed\n//% block=\"%button|is pressed\"\n//% blockId=buttonIsPressed\n//% blockNamespace=input\n//% button.fieldEditor=\"gridpicker\"\n//% button.fieldOptions.width=220\n//% button.fieldOptions.columns=3\n//% weight=50 blockGap=8\n//% trackArgs=0\nbool isPressed(Button_ button) {\n    return button->isPressed();\n}\n\n/**\n * See if the button was pressed again since the last time you checked.\n * @param button the button to query the request\n */\n//% help=input/button/was-pressed\n//% block=\"%button|was pressed\"\n//% blockId=buttonWasPressed\n//% blockNamespace=input\n//% button.fieldEditor=\"gridpicker\"\n//% button.fieldOptions.width=220\n//% button.fieldOptions.columns=3\n//% group=\"More\" weight=46 blockGap=8\n//% trackArgs=0\nbool wasPressed(Button_ button) {\n    return button->wasPressed();\n}\n\n/**\n * Gets the component identifier for the button\n */\n//%\nint id(Button_ button) {\n    return button->id;\n}\n\n} // namespace ButtonMethods\n","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    /**\n     * User interaction on buttons\n     */\n\n    declare const enum ButtonEvent {\n    //% block=\"click\"\n    Click = 3,  // DEVICE_BUTTON_EVT_CLICK\n    //% block=\"long click\"\n    LongClick = 4,  // DEVICE_BUTTON_EVT_LONG_CLICK\n    //% block=\"up\"\n    Up = 2,  // DEVICE_BUTTON_EVT_UP\n    //% block=\"down\"\n    Down = 1,  // DEVICE_BUTTON_EVT_DOWN\n    }\n\n// Auto-generated. Do not edit. Really.\n","pxt.json":"{\n    \"name\": \"buttons\",\n    \"description\": \"Button A and B drivers\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"buttons.cpp\",\n        \"shims.d.ts\",\n        \"enums.d.ts\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\n\n\ndeclare interface DigitalInOutPin {\n    /**\n     * Get the push button (connected to GND) for given pin\n     */\n    //% shim=DigitalInOutPinMethods::pushButton\n    pushButton(): Button;\n}\n\n\n\n    //% noRefCounting fixedInstances\ndeclare interface Button {\n    /**\n     * Do something when a button (`A`, `B` or both `A` + `B`) is clicked, double clicked, etc...\n     * @param button the button that needs to be clicked or used\n     * @param event the kind of button gesture that needs to be detected\n     * @param body code to run when the event is raised\n     */\n    //% help=input/button/on-event\n    //% blockId=buttonEvent block=\"on %button|%event\"\n    //% blockNamespace=input\n    //% button.fieldEditor=\"gridpicker\"\n    //% button.fieldOptions.width=220\n    //% button.fieldOptions.columns=3\n    //% weight=96 blockGap=12\n    //% trackArgs=0 shim=ButtonMethods::onEvent\n    onEvent(ev: ButtonEvent, body: () => void): void;\n\n    /**\n     * Check if a button is pressed or not.\n     * @param button the button to query the request\n     */\n    //% help=input/button/is-pressed\n    //% block=\"%button|is pressed\"\n    //% blockId=buttonIsPressed\n    //% blockNamespace=input\n    //% button.fieldEditor=\"gridpicker\"\n    //% button.fieldOptions.width=220\n    //% button.fieldOptions.columns=3\n    //% weight=50 blockGap=8\n    //% trackArgs=0 shim=ButtonMethods::isPressed\n    isPressed(): boolean;\n\n    /**\n     * See if the button was pressed again since the last time you checked.\n     * @param button the button to query the request\n     */\n    //% help=input/button/was-pressed\n    //% block=\"%button|was pressed\"\n    //% blockId=buttonWasPressed\n    //% blockNamespace=input\n    //% button.fieldEditor=\"gridpicker\"\n    //% button.fieldOptions.width=220\n    //% button.fieldOptions.columns=3\n    //% group=\"More\" weight=46 blockGap=8\n    //% trackArgs=0 shim=ButtonMethods::wasPressed\n    wasPressed(): boolean;\n\n    /**\n     * Gets the component identifier for the button\n     */\n    //% shim=ButtonMethods::id\n    id(): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n","test.ts":""},"color":{"README.md":"# Colors\n\nColor manipulation","colorbuffer.ts":"namespace color {\n    export enum ColorBufferLayout {\n        /**\n         * 24bit RGB color\n         */\n        RGB,\n        /**\n         * 32bit RGB color with alpha\n         */\n        ARGB\n    }\n\n    /**\n     * A buffer of colors\n     */\n    export class ColorBuffer {\n        layout: ColorBufferLayout;\n        buf: Buffer;\n\n        constructor(length: number, layout?: ColorBufferLayout) {\n            this.layout = layout || ColorBufferLayout.RGB;\n            this.buf = control.createBuffer((length | 0) * this.stride);\n        }\n\n        static fromBuffer(buffer: Buffer, layout: ColorBufferLayout) {\n            const b = new ColorBuffer(0, layout);\n            b.buf = buffer.slice();\n            return b;\n        }\n\n        get stride() {\n            return this.layout == ColorBufferLayout.RGB ? 3 : 4;\n        }\n\n        get length() {\n            return Math.idiv(this.buf.length, this.stride);\n        }\n\n        color(index: number): number {\n            index = index | 0;\n            if (index < 0 || index >= this.length)\n                return -1;\n\n            const s = this.stride;\n            const start = index * s;\n            let c = 0;\n            for (let i = 0; i < s; ++i)\n                c = (c << 8) | (this.buf[start + i] & 0xff);\n            return c;\n        }\n\n        setColor(index: number, color: number) {\n            index = index | 0;\n            if (index < 0 || index >= this.length) return;\n\n            const s = this.stride;\n            const start = index * s;\n            for (let i = s - 1; i >= 0; --i) {\n                this.buf[start + i] = color & 0xff;\n                color = color >> 8;\n            }\n        }\n\n        slice(start?: number, length?: number): ColorBuffer {\n            start = start | 0;\n            if (start < 0)\n                start = this.length - start;\n\n            if (length == undefined)\n                length = this.length;\n            length = Math.min(length, this.length - start);\n\n            const output = new ColorBuffer(length, this.layout);\n            for (let i = 0; i < length; ++i) {\n                output.setColor(i, this.color(start + i));\n            }\n\n            return output;\n        }\n\n        /**\n         * Writes the content of the src color buffer starting at the start dstOffset in the current buffer\n         * @param dstOffset\n         * @param src\n         */\n        write(dstOffset: number, src: ColorBuffer): void {\n            if (this.layout == src.layout) {\n                const d = (dstOffset | 0) * this.stride;\n                this.buf.write(d, src.buf);\n            } else {\n                // different color layout\n                const n = Math.min(src.length, this.length - dstOffset);\n                for (let i = 0; i < n; ++i)\n                    this.setColor(dstOffset + i, src.color(i));\n            }\n        }\n    }\n\n    /**\n     * Converts an array of colors into a color buffer\n     */\n    export function createBuffer(colors: number[], layout?: ColorBufferLayout): color.ColorBuffer {\n        const p = new ColorBuffer(colors.length, layout);\n        const n = colors.length;\n        for (let i = 0; i < n; i++) {\n            p.setColor(i, colors[i]);\n        }\n        return p;\n    }\n}","colors.ts":"/**\n * Well known colors\n */\nconst enum Colors {\n    //% block=red\n    //% blockIdentity=color.wellKnown\n    Red = 0xFF0000,\n    //% block=orange\n    //% blockIdentity=color.wellKnown\n    Orange = 0xFF7F00,\n    //% block=yellow\n    //% blockIdentity=color.wellKnown\n    Yellow = 0xFFFF00,\n    //% block=green\n    //% blockIdentity=color.wellKnown\n    Green = 0x00FF00,\n    //% block=blue\n    //% blockIdentity=color.wellKnown\n    Blue = 0x0000FF,\n    //% block=indigo\n    //% blockIdentity=color.wellKnown\n    Indigo = 0x4b0082,\n    //% block=violet\n    //% blockIdentity=color.wellKnown\n    Violet = 0x8a2be2,\n    //% block=purple\n    //% blockIdentity=color.wellKnown\n    Purple = 0xA033E5,\n    //% block=pink\n    //% blockIdentity=color.wellKnown\n    Pink = 0xFF007F,\n    //% block=white\n    //% blockIdentity=color.wellKnown\n    White = 0xFFFFFF,\n    //% block=black\n    //% blockIdentity=color.wellKnown\n    Black = 0x000000\n}\n\n/**\n * Well known color hues\n */\nconst enum ColorHues {\n    //% block=red\n    Red = 0,\n    //% block=orange\n    Orange = 29,\n    //% block=yellow\n    Yellow = 43,\n    //% block=green\n    Green = 86,\n    //% block=aqua\n    Aqua = 125,\n    //% block=blue\n    Blue = 170,\n    //% block=purple\n    Purple = 191,\n    //% block=magenta\n    Magenta = 213,\n    //% block=pink\n    Pink = 234\n}\n\n/**\n * Color manipulation\n */\n//% advanced=1\nnamespace color {\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     */\n    //% blockId=\"colorsrgb\" block=\"red %red|green %green|blue %blue\"\n    //% red.min=0 red.max=255 green.min=0 green.max=255 blue.min=0 blue.max=255\n    //% help=\"colors/rgb\"\n    //% weight=19 blockGap=8\n    //% blockHidden=true\n    export function rgb(red: number, green: number, blue: number): number {\n        return ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);\n    }\n\n    export function argb(alpha: number, red: number, green: number, blue: number): number {\n        return ((alpha & 0xFF) << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | (blue & 0xFF);\n    }\n\n    /**\n    * Get the RGB value of a known color\n    */\n    //% blockId=colorscolors block=\"%color\"\n    //% help=\"colors/well-known\"\n    //% shim=TD_ID\n    //% weight=20 blockGap=8\n    //% blockHidden=true\n    export function wellKnown(color: Colors): number {\n        return color;\n    }\n\n    /**\n     * Convert an HSV (hue, saturation, value) color to RGB\n     * @param hue value of the hue channel between 0 and 255. eg: 255\n     * @param sat value of the saturation channel between 0 and 255. eg: 255\n     * @param val value of the value channel between 0 and 255. eg: 255\n     */\n\n    //% blockId=\"colorshsv\" block=\"hue %hue|sat %sat|val %val\"\n    //% hue.min=0 hue.max=255 sat.min=0 sat.max=255 val.min=0 val.max=255\n    //% help=\"colors/hsv\"\n    //% weight=17\n    //% blockHidden=true\n    export function hsv(hue: number, sat: number = 255, val: number = 255): number {\n        let h = (hue % 255) >> 0;\n        if (h < 0) h += 255;\n        // scale down to 0..192\n        h = (h * 192 / 255) >> 0;\n\n        //reference: based on FastLED's hsv2rgb rainbow algorithm [https://github.com/FastLED/FastLED](MIT)\n        const invsat = 255 - sat;\n        const brightness_floor = ((val * invsat) / 255) >> 0;\n        const color_amplitude = val - brightness_floor;\n        const section = (h / 0x40) >> 0; // [0..2]\n        const offset = (h % 0x40) >> 0; // [0..63]\n\n        const rampup = offset;\n        const rampdown = (0x40 - 1) - offset;\n\n        const rampup_amp_adj = ((rampup * color_amplitude) / (255 / 4)) >> 0;\n        const rampdown_amp_adj = ((rampdown * color_amplitude) / (255 / 4)) >> 0;\n\n        const rampup_adj_with_floor = (rampup_amp_adj + brightness_floor);\n        const rampdown_adj_with_floor = (rampdown_amp_adj + brightness_floor);\n\n        let r: number;\n        let g: number;\n        let b: number;\n        if (section) {\n            if (section == 1) {\n                // section 1: 0x40..0x7F\n                r = brightness_floor;\n                g = rampdown_adj_with_floor;\n                b = rampup_adj_with_floor;\n            } else {\n                // section 2; 0x80..0xBF\n                r = rampup_adj_with_floor;\n                g = brightness_floor;\n                b = rampdown_adj_with_floor;\n            }\n        } else {\n            // section 0: 0x00..0x3F\n            r = rampdown_adj_with_floor;\n            g = rampup_adj_with_floor;\n            b = brightness_floor;\n        }\n        return rgb(r, g, b);\n    }\n\n    /**\n     * Fade the color by the brightness\n     * @param color color to fade\n     * @param brightness the amount of brightness to apply to the color, eg: 128\n     */\n    //% blockId=\"colorsfade\" block=\"fade %color=neopixel_colors|by %brightness\"\n    //% brightness.min=0 brightness.max=255\n    //% help=\"light/fade\"\n    //% group=\"Color\" weight=18 blockGap=8\n    //% blockHidden=true\n    export function fade(color: number, brightness: number): number {\n        brightness = Math.max(0, Math.min(255, brightness >> 0));\n        if (brightness < 255) {\n            let red = unpackR(color);\n            let green = unpackG(color);\n            let blue = unpackB(color);\n\n            red = (red * brightness) >> 8;\n            green = (green * brightness) >> 8;\n            blue = (blue * brightness) >> 8;\n\n            color = rgb(red, green, blue);\n        }\n        return color;\n    }\n\n    export function blend(color: number, alpha: number, otherColor: number) {\n        alpha = Math.max(0, Math.min(0xff, alpha | 0));\n        const malpha = 0xff - alpha;\n        const r = (unpackR(color) * malpha + unpackR(otherColor) * alpha) >> 8;\n        const g = (unpackG(color) * malpha + unpackG(otherColor) * alpha) >> 8;\n        const b = (unpackB(color) * malpha + unpackB(otherColor) * alpha) >> 8;\n        return rgb(r, g, b);\n    }\n\n    export function gradient(startColor: number, endColor: number, steps: number): ColorBuffer {\n        steps = Math.max(2, steps | 0);\n        const b = new ColorBuffer(steps);\n        b.setColor(0, startColor);\n        b.setColor(b.length - 1, endColor);\n        for (let i = 1; i < steps - 1; ++i) {\n            const alpha = Math.idiv(0xff * i, steps);\n            const c = blend(startColor, alpha, endColor);\n            b.setColor(i, c);\n        }\n        return b;\n    }\n\n    export function unpackR(rgb: number): number {\n        return (rgb >> 16) & 0xFF;\n    }\n    export function unpackG(rgb: number): number {\n        return (rgb >> 8) & 0xFF;\n    }\n    export function unpackB(rgb: number): number {\n        return (rgb >> 0) & 0xFF;\n    }\n\n    export function parseColor(color: string): number {\n        switch (color) {\n            case \"RED\":\n            case \"red\":\n                return Colors.Red;\n            case \"GREEN\":\n            case \"green\":\n                return Colors.Green;\n            case \"BLUE\":\n            case \"blue\":\n                return Colors.Blue;\n            case \"WHITE\":\n            case \"white\":\n                return Colors.White;\n            case \"ORANGE\":\n            case \"orange\":\n                return Colors.Orange;\n            case \"PURPLE\":\n            case \"purple\":\n                return Colors.Purple;\n            case \"YELLOW\":\n            case \"yellow\":\n                return Colors.Yellow;\n            case \"PINK\":\n            case \"pink\":\n                return Colors.Pink;\n            default:\n                return parseInt(color) || 0;\n        }\n    }\n}","pxt.json":"{\n    \"name\": \"color\",\n    \"description\": \"Color manipulation\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"colors.ts\",\n        \"colorbuffer.ts\",\n        \"README.md\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"searchOnly\": true,\n    \"weight\": 1,\n    \"icon\": \"/static/libs/color.png\"\n}\n"},"color-coded-tilemap":{"README.md":"# Color-coded Tilemap\n\nBlocks for the color-coded tilemap.","pxt.json":"{\n    \"name\": \"color-coded-tilemap\",\n    \"description\": \"Blocks for the color-coded tilemap\",\n    \"dependencies\": {\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"tilemap.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"weight\": 10,\n    \"icon\": \"/static/libs/color-coded-tilemap.png\"\n}\n","tilemap.ts":"//% blockGap=8\nnamespace scene {\n    /**\n     *  Package for color-coded tilemap blocks, to support existing curriculum.\n     */\n\n    /**\n     * Set the map for placing tiles in the scene\n     * @param map\n     * @param scale\n     */\n    //% blockId=gamesettilemap block=\"set tile map to %map=tilemap_image_picker || with %scale pixel tiles\"\n    //% scale.defl=TileScale.Sixteen\n    //% group=\"Color-coded Tilemap\"\n    //% help=color-coded-tilemap/set-tile-map\n    export function setTileMap(map: Image, scale = TileScale.Sixteen) {\n        const scene = game.currentScene();\n        if (!scene.tileMap || !(scene.tileMap as tiles.legacy.LegacyTilemap).isLegacy) {\n            scene.tileMap = new tiles.legacy.LegacyTilemap();\n        }\n        (scene.tileMap as tiles.legacy.LegacyTilemap).setMap(map);\n        scene.tileMap.scale = scale;\n    }\n\n    /**\n     * Set an image as a tile at the given index. Tiles should be a 16x16 image\n     * @param index\n     * @param img\n     */\n    //% blockId=gamesettile block=\"set tile %index=colorindexpicker to %img=tile_image_picker with wall %wall=toggleOnOff\"\n    //% group=\"Color-coded Tilemap\"\n    //% help=color-coded-tilemap/set-tile\n    export function setTile(index: number, img: Image, wall?: boolean) {\n        const scene = game.currentScene();\n        if (!scene.tileMap || !(scene.tileMap as tiles.legacy.LegacyTilemap).isLegacy) {\n            scene.tileMap = new tiles.legacy.LegacyTilemap();\n        }\n        (scene.tileMap as tiles.legacy.LegacyTilemap).setTile(index, img, !!wall);\n    }\n\n    /**\n     * Get the tile at a position in the tile map\n     * @param col\n     * @param row\n     */\n    //% blockId=gamegettile block=\"tile col %col row %row\"\n    //% group=\"Color-coded Tilemap\" blockSetVariable=\"myTile\"\n    //% help=color-coded-tilemap/get-tile\n    export function getTile(col: number, row: number): tiles.Tile {\n        const scene = game.currentScene();\n        if (!scene.tileMap || !(scene.tileMap as tiles.legacy.LegacyTilemap).isLegacy) {\n            scene.tileMap = new tiles.legacy.LegacyTilemap();\n        }\n        return (scene.tileMap as tiles.legacy.LegacyTilemap).getTileLegacy(col, row);\n    }\n\n    /**\n     * Get all tiles in the tile map with the given index.\n     * @param index\n     */\n    //% blockId=gamegettilestype block=\"array of all %index=colorindexpicker tiles\"\n    //% group=\"Color-coded Tilemap\" blockSetVariable=\"tile list\"\n    //% help=color-coded-tilemap/get-tiles-by-type\n    export function getTilesByType(index: number): tiles.Tile[] {\n        const scene = game.currentScene();\n        if (!scene.tileMap || !(scene.tileMap as tiles.legacy.LegacyTilemap).isLegacy) {\n            scene.tileMap = new tiles.legacy.LegacyTilemap();\n        }\n        return (scene.tileMap as tiles.legacy.LegacyTilemap).getTilesByTypeLegacy(index);\n    }\n\n    /**\n     * Center the given sprite on a random tile that is the given color\n     * @param sprite\n     * @param color\n     */\n    //% blockId=gameplaceonrandomtile block=\"place %sprite=variables_get(mySprite) on top of random $color tile\"\n    //% group=\"Color-coded Tilemap\"\n    //% color.shadow=\"colorindexpicker\"\n    //% help=color-coded-tilemap/place-on-random-tile\n    export function placeOnRandomTile(sprite: Sprite, color: number): void {\n        if (!sprite || !game.currentScene().tileMap) return;\n        const tiles = getTilesByType(color);\n        if (tiles.length > 0)\n            Math.pickRandom(tiles).place(sprite);\n    }\n\n    /**\n     * Set a tile at the given index\n     * @param tile\n     * @param index\n     */\n    //% blockId=gamesettileat block=\"set %tile=gamegettile to %index=colorindexpicker\"\n    //% group=\"Color-coded Tilemap\"\n    //% help=color-coded-tilemap/set-tile-at\n    export function setTileAt(tile: tiles.Tile, index: number) {\n        const scene = game.currentScene();\n        if (!scene.tileMap || !(scene.tileMap as tiles.legacy.LegacyTilemap).isLegacy) {\n            scene.tileMap = new tiles.legacy.LegacyTilemap();\n        }\n\n        const tm: tiles.legacy.LegacyTilemap = scene.tileMap as tiles.legacy.LegacyTilemap;\n        const scale = tm.scale;\n        tm.setTileAt(tile.x >> scale, tile.y >> scale, index);\n    }\n\n    /**\n     * Center the given sprite on this tile\n     * @param sprite\n     */\n    //% blockId=legacyplaceontile block=\"on top of %tile=variables_get(myTile) place %sprite=variables_get(mySprite)\"\n    //% group=\"Color-coded Tilemap\"\n    //% help=tiles/place\n    export function place(tile: tiles.Tile, mySprite: Sprite): void {\n        if (!tile) return;\n        tile.place(mySprite);\n    }\n\n    /**\n     * Run code when a certain kind of sprite hits a tile\n     * @param direction\n     * @param tile\n     * @param handler\n     */\n    //% group=\"Color-coded Tilemap\"\n    //% draggableParameters=\"reporter\"\n    //% blockId=spritesollisions block=\"on $sprite of kind $kind=spritekind hits wall $tile=colorindexpicker\"\n    //% help=color-coded-tilemap/on-hit-tile\n    export function onHitTile(kind: number, tile: number, handler: (sprite: Sprite) => void) {\n        if (kind == undefined || tile < 0 || tile > 0xF || !handler) return;\n\n        const collisionHandlers = game.currentScene().collisionHandlers;\n        if (!collisionHandlers[tile]) {\n            collisionHandlers[tile] = [];\n        }\n\n        collisionHandlers[tile].push(\n            new scene.SpriteHandler(\n                kind,\n                handler\n            )\n        );\n    }\n\n    /**\n     * Get the obstacle sprite in a given direction if any\n     * @param direction\n     */\n    //% blockId=legacyspriteobstacle block=\"%sprite=variables_get(mySprite) wall hit on %direction\"\n    //% group=\"Color-coded Tilemap\"\n    //% help=sprites/sprite/tile-hit-from\n    export function tileHitFrom(sprite: Sprite, direction: CollisionDirection): number {\n        if (!sprite) return 0;\n        return sprite.tileHitFrom(direction);\n    }\n}\n\nnamespace tiles.legacy {\n    class TileSet {\n        obstacle: boolean;\n        private map: TileMap;\n        private originalImage: Image;\n        private cachedImage: Image;\n\n        constructor(image: Image, collisions: boolean, map: tiles.TileMap) {\n            this.originalImage = image;\n            this.obstacle = collisions;\n            this.map = map;\n        }\n\n        get image(): Image {\n            const size = 1 << this.map.scale;\n            if (!this.cachedImage || this.cachedImage.width != size || this.cachedImage.height != size) {\n                if (this.originalImage.width == size && this.originalImage.height == size) {\n                    this.cachedImage = this.originalImage;\n                } else {\n                    this.cachedImage = image.create(size, size);\n                    this.cachedImage.drawImage(this.originalImage, 0, 0);\n                }\n            }\n            return this.cachedImage;\n        }\n    }\n\n    export class LegacyTilemap extends tiles.TileMap {\n        private _mapImage: Image;\n        private _tileSets: TileSet[];\n\n        public isLegacy: boolean;\n\n        constructor(scale: TileScale = TileScale.Sixteen) {\n            super(scale);\n            this._tileSets = [];\n            this.isLegacy = true;\n        }\n\n        get data(): TileMapData {\n            return null;\n        }\n\n        get image(): Image {\n            return this._mapImage;\n        }\n\n        offsetX(value: number) {\n            return Math.clamp(0, Math.max(this.areaWidth() - screen.width, 0), value);\n        }\n\n        offsetY(value: number) {\n            return Math.clamp(0, Math.max(this.areaHeight() - screen.height, 0), value);\n        }\n\n        areaWidth() {\n            return this._mapImage ? (this._mapImage.width << this.scale) : 0;\n        }\n\n        areaHeight() {\n            return this._mapImage ? (this._mapImage.height << this.scale) : 0;\n        }\n\n        get layer(): number {\n            return this._layer;\n        }\n\n        set layer(value: number) {\n            if (this._layer != value) {\n                this._layer = value;\n            }\n        }\n\n        get enabled(): boolean {\n            return !!this._mapImage;\n        }\n\n        setTile(index: number, img: Image, collisions?: boolean) {\n            if (this.isInvalidIndex(index)) return;\n            this._tileSets[index] = new TileSet(img, collisions, this);\n        }\n\n        setMap(map: Image) {\n            this._mapImage = map;\n        }\n\n        public getTileLegacy(col: number, row: number): Tile {\n            return new Tile(col, row, this);\n        }\n\n        public getTile(col: number, row: number): Location {\n            return new Location(col, row, this);\n        }\n\n        public setTileAt(col: number, row: number, index: number): void {\n            if (!this.isOutsideMap(col, row) && !this.isInvalidIndex(index))\n                this._mapImage.setPixel(col, row, index);\n        }\n\n        public getTilesByType(index: number): Location[] {\n            if (this.isInvalidIndex(index) || !this.enabled) return [];\n\n            let output: Location[] = [];\n            for (let col = 0; col < this._mapImage.width; ++col) {\n                for (let row = 0; row < this._mapImage.height; ++row) {\n                    let currTile = this._mapImage.getPixel(col, row);\n                    if (currTile === index) {\n                        output.push(new Location(col, row, this));\n                    }\n                }\n            }\n            return output;\n        }\n\n        public getTilesByTypeLegacy(index: number): Tile[] {\n            if (this.isInvalidIndex(index) || !this.enabled) return [];\n\n            let output: Tile[] = [];\n            for (let col = 0; col < this._mapImage.width; ++col) {\n                for (let row = 0; row < this._mapImage.height; ++row) {\n                    let currTile = this._mapImage.getPixel(col, row);\n                    if (currTile === index) {\n                        output.push(new Tile(col, row, this));\n                    }\n                }\n            }\n            return output;\n        }\n\n        private generateTile(index: number): TileSet {\n            const size = 1 << this.scale\n\n            const i = image.create(size, size);\n            i.fill(index);\n            return this._tileSets[index] = new TileSet(i, false, this);\n        }\n\n        private isOutsideMap(col: number, row: number): boolean {\n            return !this.enabled || col < 0 || col >= this._mapImage.width\n                || row < 0 || row >= this._mapImage.height;\n        }\n\n        protected isInvalidIndex(index: number): boolean {\n            return index < 0 || index > 0xf;\n        }\n\n        protected draw(target: Image, camera: scene.Camera) {\n            if (!this.enabled) return;\n\n            // render tile map\n            const bitmask = (0x1 << this.scale) - 1;\n            const offsetX = camera.drawOffsetX & bitmask;\n            const offsetY = camera.drawOffsetY & bitmask;\n\n            const x0 = Math.max(0, camera.drawOffsetX >> this.scale);\n            const xn = Math.min(this._mapImage.width, ((camera.drawOffsetX + target.width) >> this.scale) + 1);\n            const y0 = Math.max(0, camera.drawOffsetY >> this.scale);\n            const yn = Math.min(this._mapImage.height, ((camera.drawOffsetY + target.height) >> this.scale) + 1);\n\n            for (let x = x0; x <= xn; ++x) {\n                for (let y = y0; y <= yn; ++y) {\n                    const index = this._mapImage.getPixel(x, y);\n                    const tile = this._tileSets[index] || this.generateTile(index);\n                    if (tile) {\n                        target.drawTransparentImage(\n                            tile.image,\n                            ((x - x0) << this.scale) - offsetX,\n                            ((y - y0) << this.scale) - offsetY\n                        );\n                    }\n                }\n            }\n\n            if (game.debug) {\n                // render debug grid overlay\n                for (let x = x0; x <= xn; ++x) {\n                    const xLine = ((x - x0) << this.scale) - offsetX;\n                    if (xLine >= 0 && xLine <= screen.width) {\n                        target.drawLine(\n                            xLine,\n                            0,\n                            xLine,\n                            target.height,\n                            1\n                        );\n                    }\n                }\n\n                for (let y = y0; y <= yn; ++y) {\n                    const yLine = ((y - y0) << this.scale) - offsetY;\n                    if (yLine >= 0 && yLine <= screen.height) {\n                        target.drawLine(\n                            0,\n                            yLine,\n                            target.width,\n                            yLine,\n                            1\n                        );\n                    }\n                }\n            }\n        }\n\n        public isObstacle(col: number, row: number) {\n            if (!this.enabled) return false;\n            if (this.isOutsideMap(col, row)) return true;\n\n            let t = this._tileSets[this._mapImage.getPixel(col, row)];\n            return t && t.obstacle;\n        }\n\n        public getObstacle(col: number, row: number) {\n            const index = this.isOutsideMap(col, row) ? 0 : this._mapImage.getPixel(col, row);\n            const tile = this._tileSets[index] || this.generateTile(index);\n            return new sprites.StaticObstacle(\n                tile.image,\n                row << this.scale,\n                col << this.scale,\n                this.layer,\n                index\n            );\n        }\n\n        public isOnWall(s: Sprite) {\n            if (!s.isStatic()) s.setHitbox();\n            const hbox = s._hitbox\n\n            const left = Fx.toIntShifted(hbox.left, this.scale);\n            const right = Fx.toIntShifted(hbox.right, this.scale);\n            const top = Fx.toIntShifted(hbox.top, this.scale);\n            const bottom = Fx.toIntShifted(hbox.bottom, this.scale);\n\n            for (let col = left; col <= right; ++col) {\n                for (let row = top; row <= bottom; ++row) {\n                    if (this.isObstacle(col, row)) {\n                        return true;\n                    }\n                }\n            }\n\n            return false;\n        }\n\n        public getTileIndex(col: number, row: number) {\n            return this._mapImage.getPixel(col, row);\n        }\n\n        public getTileImage(index: number) {\n            if (!this._tileSets[index]) this.generateTile(index);\n            return this._tileSets[index].image;\n        }\n    }\n}"},"controller":{"README.md":"# Controller\n\nExtra features for Aracde controllers\n","accelerometer.ts":"enum ControllerGesture {\n    /**\n     * Shake gesture\n     */\n    //% block=\"shake\"\n    Shake = 11,  // ACCELEROMETER_EVT_SHAKE\n    /**\n     * Raised when the device tilts up\n     */\n    //% block=\"tilt up\"\n    TiltUp = 1,  // ACCELEROMETER_EVT_TILT_UP\n    /**\n     * Raised when the device tilts down\n     */\n    //% block=\"tilt down\"\n    TiltDown = 2,  // ACCELEROMETER_EVT_TILT_DOWN\n    /**\n     * Raised when the screen is pointing left\n     */\n    //% block=\"tilt left\"\n    TiltLeft = 3,  // ACCELEROMETER_EVT_TILT_LEFT\n    /**\n     * Raised when the screen is pointing right\n     */\n    //% block=\"tilt right\"\n    TiltRight = 4,  // ACCELEROMETER_EVT_TILT_RIGHT\n    /**\n     * Raised when the screen faces up\n     */\n    //% block=\"screen up\"\n    ScreenUp = 5,  // 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,  // ACCELEROMETER_EVT_FACE_DOWN\n    /**\n     * Raised when a 2G shock is detected\n     */\n    //% block=\"2g (step)\"\n    TwoG = 12,  // ACCELEROMETER_EVT_2G\n    /**\n     * Raised when a 3G shock is detected\n     */\n    //% block=\"3g\"\n    ThreeG = 8,  // ACCELEROMETER_EVT_3G\n    /**\n     * Raised when a 6G shock is detected\n     */\n    //% block=\"6g\"\n    SixG = 9,  // ACCELEROMETER_EVT_6G\n    /**\n     * Raised when a 8G shock is detected\n     */\n    //% block=\"8g\"\n    EightG = 10,  // ACCELEROMETER_EVT_8G\n}\n\nenum ControllerDimension {\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\nnamespace controller {\n    /**\n     * Do something when a gesture happens (like shaking the board).\n     * @param gesture the type of gesture to track\n     * @param body code to run when gesture is raised\n     */\n    //% blockId=ctrlongesture block=\"on |%NAME\"\n    //% parts=\"accelerometer\"\n    //% gesture.fieldEditor=\"gridpicker\"\n    //% gesture.fieldOptions.width=220\n    //% gesture.fieldOptions.columns=3\n    //% group=\"Extras\"\n    export function onGesture(gesture: ControllerGesture, handler: () => void) {\n        controller.__internal.onGesture(gesture, handler);\n    }\n\n    /**\n     * Register a custom gesture for the controller\n     * @param id \n     * @param update\n     * @param handler\n     */\n    export function onCustomGesture(id: number, update: () => boolean, handler: () => void) {\n        controller.__internal.onCustomGesture(id, update, handler);\n    }\n\n    /**\n     * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\n     * x=0, y=0 and z=-1023)\n     * @param dimension the axis along which the acceleration if measured\n     */\n    //% blockId=ctrlaccelerationvalue block=\"acceleration (mg)|%NAME\"\n    //% parts=\"accelerometer\"\n    //% dimension.fieldEditor=\"gridpicker\"\n    //% dimension.fieldOptions.width=180\n    //% dimension.fieldOptions.columns=2\n    //% group=\"Extras\"\n    export function acceleration(dimension: ControllerDimension): number {\n        return controller.__internal.acceleration(dimension);\n    }\n}","controller.ts":"namespace controller {\n    /**\n     * Configures the timing of the on button repeat event for all of the controller buttons\n     * @param delay number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500\n     * @param interval minimum number of milliseconds between calls to the button repeat event, eg: 30\n     */\n    //% blockId=repeatDefaultDelayInterval block=\"set button repeat delay $delay ms interval $interval ms\"\n    //% weight=10\n    //% group=\"Single Player\"\n    export function configureRepeatEventDefaults(delay: number, interval: number) {\n        controller.setRepeatDefault(delay, interval);\n    }\n}","controllerimpl.ts":"namespace controller.__internal {\n    export function onGesture(gesture: ControllerGesture, handler: () => void) {\n        const state = sceneState();\n        if (!state.gestureHandlers) state.gestureHandlers = {};\n        state.gestureHandlers[gesture] = handler;\n\n        input.onGesture(<Gesture><number>gesture, function () {\n            const st = sceneState();\n            st.lastGesture = gesture;\n        })\n    }\n\n    export function onCustomGesture(id: number, update: () => boolean, handler: () => void) {\n        const state = sceneState();\n        if (!state.customGestureHandlers) state.customGestureHandlers = {};\n        state.customGestureHandlers[id] = <CustomGestureHandler>{ update, handler };\n\n        input.onCustomGesture(id,\n            function () {\n                const st = sceneState();\n                const h = st.customGestureHandlers && st.customGestureHandlers[id];\n                return h && h.update();\n            }, function () {\n                const st = sceneState();\n                st.lastCustomGesture = id;\n            })\n    }\n\n    export function acceleration(dimension: ControllerDimension): number {\n        return input.acceleration(<Dimension><number>dimension);\n    }\n}\n\nnamespace controller {\n    /**\n     * Configures the pins used by the crank\n     * @param pinA \n     * @param pinB \n     */\n    //% blockId=controller_crank_setpins block=\"set crank pinA $pinA pin B $pinB\"\n    //% weight=28 blockGap=8\n    //% group=\"Extras\"\n    export function setCrankPins(pinA: DigitalInOutPin, pinB: DigitalInOutPin) {\n        controller.__internal.setCrankPins(pinA, pinB);\n    }\n}\n\nnamespace controller.__internal {\n    let crankEncoder: RotaryEncoder;\n    export function crankPosition(): number {\n        const crank = crankEncoder || encoders.defaultEncoder;\n        return crank ? crank.position() : 0;\n    }\n\n    export function setCrankPins(pinA: DigitalInOutPin, pinB: DigitalInOutPin) {\n        crankEncoder = encoders.createRotaryEncoder(pinA, pinB);\n    }\n}\n\nnamespace controller {\n    /**\n     * Shows an animation on the controller lights\n     * @param animation \n     * @param duration \n     */\n    //% blockId=controller_show_animation block=\"start light animation %animation=light_animation_picker|for %duration=timePicker|ms\"\n    //% weight=30 blockGap=8\n    //% group=\"Extras\"\n    export function startLightAnimation(animation: light.NeoPixelAnimation, duration: number) {\n        controller.__internal.startLightAnimation(animation, duration);\n    }\n}\n\nnamespace controller.__internal {\n    const ANIM_KEY = \"ctrllightanim\";\n    const ANIM_TIME_KEY = \"ctrllightanimend\";\n\n    export function startLightAnimation(animation: light.NeoPixelAnimation, duration: number) {\n        if (duration <= 0) return;\n\n        const strip = light.onboardStrip();\n        if (!strip || !strip.length()) return;\n\n        const scene = game.currentScene();\n        let anim = scene.data[ANIM_KEY] as light.NeoPixelAnimation;\n        // schedule animation\n        if (anim === undefined) { // undefined means the game.update hasn't been registered\n            strip.setBuffered(true);\n            game.onUpdateInterval(50, renderLightFrame);\n        }\n\n        // don't blind users\n        strip.stopBrightnessTransition();\n        const brightess = control.getConfigValue(DAL.CFG_CONTROLLER_LIGHT_MAX_BRIGHTNESS, 32);\n        strip.setBrightness(brightess);\n        // record data for animation\n        scene.data[ANIM_KEY] = animation;\n        scene.data[ANIM_TIME_KEY] = game.runtime() + duration;\n    }\n\n    export function startLightPulse(rgb: number, duration: number) {\n        if (duration <= 0) return;\n\n        const strip = light.onboardStrip();\n        if (!strip || !strip.length()) return;\n\n        const scene = game.currentScene();\n        let anim = scene.data[ANIM_KEY] as light.NeoPixelAnimation;\n        if (anim)\n            scene.data[ANIM_KEY] = null; // stop any running animation\n\n        // start a brightness transition\n        const brightess = control.getConfigValue(DAL.CFG_CONTROLLER_LIGHT_MAX_BRIGHTNESS, 8);\n        strip.setBrightness(0);\n        strip.setAll(rgb);\n        strip.startBrightnessTransition(0, brightess, duration, 2, true);\n    }\n\n    function renderLightFrame() {\n        const scene = game.currentScene();\n        if (!scene) return;\n\n        // anything to animate?\n        let anim = scene.data[ANIM_KEY] as light.NeoPixelAnimation;\n        if (!anim) return;\n\n        // expired?\n        let animend = scene.data[ANIM_TIME_KEY] || 0;\n        if (game.runtime() > animend) { // invalidate key\n            anim = scene.data[ANIM_KEY] = null; // make sure to use null\n        }\n\n        const strip = light.onboardStrip();\n        if (anim)\n            strip.showAnimationFrame(anim);\n        else\n            strip.clear();\n        strip.show();\n    }\n}\n\nnamespace controller.__internal {\n    export function lightLevel(): number {\n        return input.lightLevel();\n    }\n\n\n    export function onLightConditionChanged(condition: ControllerLightCondition, handler: () => void): void {\n        const state = sceneState();\n        if (!state.lightHandlers) state.lightHandlers = {};\n        state.lightHandlers[condition] = handler;\n        input.onLightConditionChanged(<LightCondition><number>condition, function () {\n            const st = sceneState();\n            st.lastLightCondition = condition;\n        })\n    }\n}\n\nnamespace controller.__internal {\n    export function temperature(unit: ControllerTemperatureUnit): number {\n        return input.temperature(<TemperatureUnit><number>unit);\n    }\n}\n\nnamespace controller.__internal {\n    let vibrationPin: DigitalInOutPin;\n    let vibrationEnd: number;\n\n    function updateVibration() {\n        // turn off vibration if needed\n        if (vibrationEnd > 0 && vibrationEnd < control.millis()) {\n            if (vibrationPin)\n                vibrationPin.digitalWrite(false);\n            vibrationEnd = -1;\n        }\n    }\n\n    function initVibration(s: scene.Scene) {\n        if (!vibrationPin)\n            vibrationPin = pins.pinByCfg(DAL.CFG_PIN_VIBRATION);\n        vibrationEnd = -1;\n        s.eventContext.registerFrameHandler(scene.UPDATE_PRIORITY, updateVibration);\n    }\n\n    export function vibrate(millis: number) {\n        const off = vibrationEnd <= 0;\n        vibrationEnd = millis <= 0 ? -1 : (control.millis() + Math.min(3000, millis));\n        if (off) {\n            if (vibrationPin)\n                vibrationPin.digitalWrite(true);\n        }\n    }\n\n    scene.Scene.initializers.push(initVibration);\n}","crank.ts":"namespace controller {\n    /**\n     * Gets the current position of the crank.\n     */\n    //% blockId=controller_crank_position block=\"crank position\"\n    //% weight=29 blockGap=8\n    //% group=\"Extras\"\n    export function crankPosition(): number {\n        return controller.__internal.crankPosition();\n    }\n}\n","light.ts":"namespace controller {\n    /**\n     * Shows a color pulse\n     * @param rgb RGB color of the LED\n     */\n    //% blockId=\"ctrllightpulse\" block=\"start light pulse %rgb=colorNumberPicker|for %duration=timePicker|ms\"\n    //% weight=80 blockGap=8\n    //% group=\"Extras\"\n    export function startLightPulse(rgb: number, duration: number) {\n        controller.__internal.startLightPulse(rgb, duration);\n    }\n}\n\n//% advanced=true\nnamespace light {\n\n}","lightsensor.ts":"enum ControllerLightCondition {\n    //% block=\"dark\"\n    Dark = 1,  // SENSOR_THRESHOLD_LOW\n    //% block=\"bright\"\n    Bright = 2,  // SENSOR_THRESHOLD_HIGH\n}\n\nnamespace controller {\n    /**\n     * Read the light level applied to the LED screen in a range from 0 (dark) to 255 (bright).\n     */\n    //% blockId=ctrllightlevel block=\"light level\"\n    //% parts=\"lightsensor\"\n    //% weight=30 blockGap=8\n    //% group=\"Extras\"\n    export function lightLevel(): number {\n        return controller.__internal.lightLevel();\n    }\n\n\n    /**\n     * Register an event that runs when light conditions (darker or brighter) change.\n     * @param condition the condition that event triggers on\n     */\n    //% blockId=ctrlonlightcondition block=\"on light %condition\"\n    //% parts=\"lightsensor\"\n    //% weight=84 blockGap=12\n    //% group=\"Extras\"\n    export function onLightConditionChanged(condition: ControllerLightCondition, handler: () => void): void {\n        controller.__internal.onLightConditionChanged(condition, handler);\n    } \n}","pxt.json":"{\n    \"name\": \"controller\",\n    \"description\": \"Extra game controller functionalities\",\n    \"dependencies\": {\n        \"core\": \"*\",\n        \"accelerometer\": \"*\",\n        \"lightsensor\": \"*\",\n        \"thermometer\": \"*\",\n        \"game\": \"*\",\n        \"light\": \"*\",\n        \"rotary-encoder\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"state.ts\",\n        \"vibration.ts\",\n        \"accelerometer.ts\",\n        \"lightsensor.ts\",\n        \"thermometer.ts\",\n        \"controller.ts\",\n        \"light.ts\",\n        \"crank.ts\",\n        \"controllerimpl.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"weight\": 99,\n    \"icon\": \"/static/libs/controller.png\"\n}\n","state.ts":"namespace controller {\n    export interface ControllerSceneState {\n        lastGesture?: ControllerGesture;\n        gestureHandlers?: any;\n        lastCustomGesture?: number;\n        customGestureHandlers?: any;\n        lastLightCondition?: ControllerLightCondition;\n        lightHandlers?: any;\n    }\n\n    export interface CustomGestureHandler {\n        update: () => boolean;\n        handler: () => void;\n    }\n\n    export function sceneState(): ControllerSceneState {\n        const sc = game.currentScene();\n        let state = sc.data[\"controller.state\"];\n        if (!state) {\n            state = sc.data[\"controller.state\"] = <ControllerSceneState>{\n            };\n        }\n        return state;\n    }\n\n\n    function updateController() {\n        const state = sceneState();\n        // accelerometer\n        if (state.lastGesture !== undefined) {\n            const handler = state.gestureHandlers && state.gestureHandlers[state.lastGesture];\n            if (handler) {\n                state.lastGesture = undefined;\n                handler();\n            }\n        }\n        if (state.lastCustomGesture !== undefined) {\n            const customHandler = state.customGestureHandlers && state.customGestureHandlers[state.lastCustomGesture] as CustomGestureHandler;\n            if (customHandler) {\n                state.lastCustomGesture = undefined;\n                customHandler.handler();\n            }\n        }\n\n        // light sensor\n        if (state.lightHandlers\n            && state.lastLightCondition !== undefined\n            && state.lightHandlers[state.lastLightCondition]) {\n            const handler = state.lightHandlers[state.lastLightCondition];\n            state.lastLightCondition = undefined;\n            handler();\n        }\n    }\n\n    function initController(s: scene.Scene) {\n        s.eventContext.registerFrameHandler(scene.UPDATE_CONTROLLER_PRIORITY, updateController);\n    }\n\n    scene.Scene.initializers.push(initController);\n}","thermometer.ts":"const enum ControllerTemperatureUnit {\n    //% block=\"°C\"\n    Celsius = 0,\n    //% block=\"°F\"\n    Fahrenheit = 1,\n}\n\n\nnamespace controller {\n    /**\n     * Get the temperature in Celsius or Fahrenheit degrees.\n     */\n    //% blockId=ctrltemperature block=\"temperature in %unit\"\n    //% parts=\"thermometer\"\n    //% weight=26\n    //% group=\"Extras\"\n    export function temperature(unit: ControllerTemperatureUnit): number {\n        return controller.__internal.temperature(unit);\n    }\n}","vibration.ts":"namespace controller {\n    /**\n     * Vibrates the controller for the given duration (in milli seconds)\n     * @param millis \n     */\n    //% blockId=ctrlvibrate block=\"vibrate $millis ms\"\n    //% millis.shadow=timePicker\n    //% group=\"Extras\"\n    export function vibrate(millis: number) {\n        controller.__internal.vibrate(millis);\n    }\n}"},"controller---none":{"README.md":"# Controller\n\nExtra features for Aracde controllers\n","accelerometer.ts":"enum ControllerGesture {\n    /**\n     * Shake gesture\n     */\n    //% block=\"shake\"\n    Shake = 11,  // ACCELEROMETER_EVT_SHAKE\n    /**\n     * Raised when the device tilts up\n     */\n    //% block=\"tilt up\"\n    TiltUp = 1,  // ACCELEROMETER_EVT_TILT_UP\n    /**\n     * Raised when the device tilts down\n     */\n    //% block=\"tilt down\"\n    TiltDown = 2,  // ACCELEROMETER_EVT_TILT_DOWN\n    /**\n     * Raised when the screen is pointing left\n     */\n    //% block=\"tilt left\"\n    TiltLeft = 3,  // ACCELEROMETER_EVT_TILT_LEFT\n    /**\n     * Raised when the screen is pointing right\n     */\n    //% block=\"tilt right\"\n    TiltRight = 4,  // ACCELEROMETER_EVT_TILT_RIGHT\n    /**\n     * Raised when the screen faces up\n     */\n    //% block=\"screen up\"\n    ScreenUp = 5,  // 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,  // ACCELEROMETER_EVT_FACE_DOWN\n    /**\n     * Raised when a 2G shock is detected\n     */\n    //% block=\"2g (step)\"\n    TwoG = 12,  // ACCELEROMETER_EVT_2G\n    /**\n     * Raised when a 3G shock is detected\n     */\n    //% block=\"3g\"\n    ThreeG = 8,  // ACCELEROMETER_EVT_3G\n    /**\n     * Raised when a 6G shock is detected\n     */\n    //% block=\"6g\"\n    SixG = 9,  // ACCELEROMETER_EVT_6G\n    /**\n     * Raised when a 8G shock is detected\n     */\n    //% block=\"8g\"\n    EightG = 10,  // ACCELEROMETER_EVT_8G\n}\n\nenum ControllerDimension {\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\nnamespace controller {\n    /**\n     * Do something when a gesture happens (like shaking the board).\n     * @param gesture the type of gesture to track\n     * @param body code to run when gesture is raised\n     */\n    //% blockId=ctrlongesture block=\"on |%NAME\"\n    //% parts=\"accelerometer\"\n    //% gesture.fieldEditor=\"gridpicker\"\n    //% gesture.fieldOptions.width=220\n    //% gesture.fieldOptions.columns=3\n    //% group=\"Extras\"\n    export function onGesture(gesture: ControllerGesture, handler: () => void) {\n        controller.__internal.onGesture(gesture, handler);\n    }\n\n    /**\n     * Register a custom gesture for the controller\n     * @param id \n     * @param update\n     * @param handler\n     */\n    export function onCustomGesture(id: number, update: () => boolean, handler: () => void) {\n        controller.__internal.onCustomGesture(id, update, handler);\n    }\n\n    /**\n     * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\n     * x=0, y=0 and z=-1023)\n     * @param dimension the axis along which the acceleration if measured\n     */\n    //% blockId=ctrlaccelerationvalue block=\"acceleration (mg)|%NAME\"\n    //% parts=\"accelerometer\"\n    //% dimension.fieldEditor=\"gridpicker\"\n    //% dimension.fieldOptions.width=180\n    //% dimension.fieldOptions.columns=2\n    //% group=\"Extras\"\n    export function acceleration(dimension: ControllerDimension): number {\n        return controller.__internal.acceleration(dimension);\n    }\n}","controller.ts":"namespace controller {\n    /**\n     * Configures the timing of the on button repeat event for all of the controller buttons\n     * @param delay number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500\n     * @param interval minimum number of milliseconds between calls to the button repeat event, eg: 30\n     */\n    //% blockId=repeatDefaultDelayInterval block=\"set button repeat delay $delay ms interval $interval ms\"\n    //% weight=10\n    //% group=\"Single Player\"\n    export function configureRepeatEventDefaults(delay: number, interval: number) {\n        controller.setRepeatDefault(delay, interval);\n    }\n}","controllerimpl.ts":"namespace controller.__internal {\n    export function onGesture(gesture: ControllerGesture, handler: () => void) {\n    }\n\n    export function onCustomGesture(id: number, update: () => boolean, handler: () => void) {\n    }\n\n    export function acceleration(dimension: ControllerDimension): number {\n        return 0;\n    }\n}\n\nnamespace controller.__internal {\n    export function crankPosition(): number {\n        return 0;\n    }\n\n    //export function setCrankPins(pinA: DigitalInOutPin, pinB: DigitalInOutPin) {\n    //}\n}\n\nnamespace controller.__internal {\n    //export function startLightAnimation(animation: light.NeoPixelAnimation, duration: number) {\n    //}\n\n    export function startLightPulse(rgb: number, duration: number) {\n    }\n}\n\nnamespace controller.__internal {\n    export function lightLevel(): number {\n        return 0;\n    }\n\n\n    export function onLightConditionChanged(condition: ControllerLightCondition, handler: () => void): void {\n    }\n}\n\nnamespace controller.__internal {\n    export function temperature(unit: ControllerTemperatureUnit): number {\n        return 0;\n    }\n}\n\nnamespace controller.__internal {\n    export function vibrate(millis: number) {\n    }\n}","crank.ts":"namespace controller {\n    /**\n     * Gets the current position of the crank.\n     */\n    //% blockId=controller_crank_position block=\"crank position\"\n    //% weight=29 blockGap=8\n    //% group=\"Extras\"\n    export function crankPosition(): number {\n        return controller.__internal.crankPosition();\n    }\n}\n","light.ts":"namespace controller {\n    /**\n     * Shows a color pulse\n     * @param rgb RGB color of the LED\n     */\n    //% blockId=\"ctrllightpulse\" block=\"start light pulse %rgb=colorNumberPicker|for %duration=timePicker|ms\"\n    //% weight=80 blockGap=8\n    //% group=\"Extras\"\n    export function startLightPulse(rgb: number, duration: number) {\n        controller.__internal.startLightPulse(rgb, duration);\n    }\n}\n\n//% advanced=true\nnamespace light {\n\n}","lightsensor.ts":"enum ControllerLightCondition {\n    //% block=\"dark\"\n    Dark = 1,  // SENSOR_THRESHOLD_LOW\n    //% block=\"bright\"\n    Bright = 2,  // SENSOR_THRESHOLD_HIGH\n}\n\nnamespace controller {\n    /**\n     * Read the light level applied to the LED screen in a range from 0 (dark) to 255 (bright).\n     */\n    //% blockId=ctrllightlevel block=\"light level\"\n    //% parts=\"lightsensor\"\n    //% weight=30 blockGap=8\n    //% group=\"Extras\"\n    export function lightLevel(): number {\n        return controller.__internal.lightLevel();\n    }\n\n\n    /**\n     * Register an event that runs when light conditions (darker or brighter) change.\n     * @param condition the condition that event triggers on\n     */\n    //% blockId=ctrlonlightcondition block=\"on light %condition\"\n    //% parts=\"lightsensor\"\n    //% weight=84 blockGap=12\n    //% group=\"Extras\"\n    export function onLightConditionChanged(condition: ControllerLightCondition, handler: () => void): void {\n        controller.__internal.onLightConditionChanged(condition, handler);\n    } \n}","pxt.json":"{\n    \"name\": \"controller---none\",\n    \"description\": \"Extra game controller functionalities\",\n    \"dependencies\": {\n        \"core\": \"*\",\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"state.ts\",\n        \"vibration.ts\",\n        \"accelerometer.ts\",\n        \"lightsensor.ts\",\n        \"thermometer.ts\",\n        \"controller.ts\",\n        \"light.ts\",\n        \"crank.ts\",\n        \"controllerimpl.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","state.ts":"namespace controller {\n    export interface ControllerSceneState {\n        lastGesture?: ControllerGesture;\n        gestureHandlers?: any;\n        lastCustomGesture?: number;\n        customGestureHandlers?: any;\n        lastLightCondition?: ControllerLightCondition;\n        lightHandlers?: any;\n    }\n\n    export interface CustomGestureHandler {\n        update: () => boolean;\n        handler: () => void;\n    }\n\n    export function sceneState(): ControllerSceneState {\n        const sc = game.currentScene();\n        let state = sc.data[\"controller.state\"];\n        if (!state) {\n            state = sc.data[\"controller.state\"] = <ControllerSceneState>{\n            };\n        }\n        return state;\n    }\n\n\n    function updateController() {\n        const state = sceneState();\n        // accelerometer\n        if (state.lastGesture !== undefined) {\n            const handler = state.gestureHandlers && state.gestureHandlers[state.lastGesture];\n            if (handler) {\n                state.lastGesture = undefined;\n                handler();\n            }\n        }\n        if (state.lastCustomGesture !== undefined) {\n            const customHandler = state.customGestureHandlers && state.customGestureHandlers[state.lastCustomGesture] as CustomGestureHandler;\n            if (customHandler) {\n                state.lastCustomGesture = undefined;\n                customHandler.handler();\n            }\n        }\n\n        // light sensor\n        if (state.lightHandlers\n            && state.lastLightCondition !== undefined\n            && state.lightHandlers[state.lastLightCondition]) {\n            const handler = state.lightHandlers[state.lastLightCondition];\n            state.lastLightCondition = undefined;\n            handler();\n        }\n    }\n\n    function initController(s: scene.Scene) {\n        s.eventContext.registerFrameHandler(scene.UPDATE_CONTROLLER_PRIORITY, updateController);\n    }\n\n    scene.Scene.initializers.push(initController);\n}","thermometer.ts":"const enum ControllerTemperatureUnit {\n    //% block=\"°C\"\n    Celsius = 0,\n    //% block=\"°F\"\n    Fahrenheit = 1,\n}\n\n\nnamespace controller {\n    /**\n     * Get the temperature in Celsius or Fahrenheit degrees.\n     */\n    //% blockId=ctrltemperature block=\"temperature in %unit\"\n    //% parts=\"thermometer\"\n    //% weight=26\n    //% group=\"Extras\"\n    export function temperature(unit: ControllerTemperatureUnit): number {\n        return controller.__internal.temperature(unit);\n    }\n}","vibration.ts":"namespace controller {\n    /**\n     * Vibrates the controller for the given duration (in milli seconds)\n     * @param millis \n     */\n    //% blockId=ctrlvibrate block=\"vibrate $millis ms\"\n    //% millis.shadow=timePicker\n    //% group=\"Extras\"\n    export function vibrate(millis: number) {\n        controller.__internal.vibrate(millis);\n    }\n}"},"core":{"README.md":"# core\n\nThe core library for Codal-based targets.\n\n","codal.cpp":"#include \"pxt.h\"\n#include \"LowLevelTimer.h\"\nusing namespace codal;\n\nvoid cpu_clock_init(void);\n\nPXT_ABI(__aeabi_dadd)\nPXT_ABI(__aeabi_dcmplt)\nPXT_ABI(__aeabi_dcmpgt)\nPXT_ABI(__aeabi_dsub)\nPXT_ABI(__aeabi_ddiv)\nPXT_ABI(__aeabi_dmul)\n\n#ifdef DEVICE_GET_FIBER_LIST_AVAILABLE\n// newer codal-core has get_fiber_list() but not list_fibers()\nnamespace codal {\n/*\n * Return all current fibers.\n *\n * @param dest If non-null, it points to an array of pointers to fibers to store results in.\n *\n * @return the number of fibers (potentially) stored\n */\nint list_fibers(Fiber **dest) {\n    int i = 0;\n    for (Fiber *fib = codal::get_fiber_list(); fib; fib = fib->next) {\n        if (dest)\n            dest[i] = fib;\n        i++;\n    }\n    return i;\n}\n\n} // namespace codal\n#endif\n\nnamespace pxt {\n\nvoid platform_init();\nvoid usb_init();\n\n// The first two word are used to tell the bootloader that a single reset should start the\n// bootloader and the MSD device, not us.\n// The rest is reserved for partial flashing checksums.\n__attribute__((section(\".binmeta\"))) __attribute__((used)) const uint32_t pxt_binmeta[] = {\n    0x87eeb07c, 0x87eeb07c, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,\n    0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,\n};\n\nEvent lastEvent;\nMessageBus devMessageBus;\ncodal::CodalDevice device;\n\nstruct FreeList {\n    FreeList *next;\n};\n\nstatic void commInit() {\n    int commSize = bytecode[20];\n    if (!commSize)\n        return;\n\n    void *r = app_alloc_at((void *)PXT_COMM_BASE, commSize);\n    DMESG(\"comm %d -> %p\", commSize, r);\n    if (!r)\n        target_panic(20);\n}\n\nstatic void initCodal() {\n    cpu_clock_init();\n\n    commInit();\n\n    // Bring up fiber scheduler.\n    scheduler_init(devMessageBus);\n\n    // We probably don't need that - components are initialized when one obtains\n    // the reference to it.\n    // devMessageBus.listen(DEVICE_ID_MESSAGE_BUS_LISTENER, DEVICE_EVT_ANY, this,\n    // &CircuitPlayground::onListenerRegisteredEvent);\n\n    for (int i = 0; i < DEVICE_COMPONENT_COUNT; i++) {\n        if (CodalComponent::components[i])\n            CodalComponent::components[i]->init();\n    }\n\n    usb_init();\n\n    auto led = LOOKUP_PIN(LED);\n    if (led) {\n        led->setDigitalValue(0);\n    }\n}\n\n// ---------------------------------------------------------------------------\n// An adapter for the API expected by the run-time.\n// ---------------------------------------------------------------------------\n\n// We have the invariant that if [dispatchEvent] is registered against the DAL\n// for a given event, then [handlersMap] contains a valid entry for that\n// event.\nvoid dispatchEvent(Event e) {\n    lastEvent = e;\n\n    auto curr = findBinding(e.source, e.value);\n    auto value = fromInt(e.value);\n    while (curr) {\n        runAction1(curr->action, value);\n        curr = nextBinding(curr->next, e.source, e.value);\n    }\n}\n\nvoid registerWithDal(int id, int event, Action a, int flags) {\n    // first time?\n    if (!findBinding(id, event)) {\n        devMessageBus.listen(id, event, dispatchEvent, flags);\n        if (event == 0) {\n            // we're registering for all events on given ID\n            // need to remove old listeners for specific events\n            auto curr = findBinding(id, -1);\n            while (curr) {\n                devMessageBus.ignore(id, curr->value, dispatchEvent);\n                curr = nextBinding(curr->next, id, -1);\n            }\n        }\n    }\n    setBinding(id, event, a);\n}\n\nvoid fiberDone(void *a) {\n    unregisterGCPtr((Action)a);\n    release_fiber();\n}\n\nvoid releaseFiber() {\n    release_fiber();\n}\n\nvoid sleep_ms(unsigned ms) {\n    fiber_sleep(ms);\n}\n\nvoid sleep_us(uint64_t us) {\n    target_wait_us(us);\n}\n\nvoid forever_stub(void *a) {\n    while (true) {\n        runAction0((Action)a);\n        fiber_sleep(20);\n    }\n}\n\nvoid runForever(Action a) {\n    if (a != 0) {\n        registerGCPtr(a);\n        create_fiber(forever_stub, (void *)a);\n    }\n}\n\nvoid runInParallel(Action a) {\n    if (a != 0) {\n        registerGCPtr(a);\n        create_fiber((void (*)(void *))(void*)runAction0, (void *)a, fiberDone);\n    }\n}\n\nvoid waitForEvent(int id, int event) {\n    fiber_wait_for_event(id, event);\n}\n\nvoid initRuntime() {\n    initSystemTimer();\n    initCodal();\n    platform_init();\n}\n\n//%\nunsigned afterProgramPage() {\n    unsigned ptr = (unsigned)&bytecode[0];\n    ptr += programSize();\n    ptr = (ptr + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);\n    return ptr;\n}\n\nuint64_t getLongSerialNumber() {\n    return device.getSerialNumber();\n}\n\nint current_time_ms() {\n    return system_timer_current_time();\n}\n\nuint64_t current_time_us() {\n    return system_timer_current_time_us();\n}\n\nThreadContext *getThreadContext() {\n    if (!currentFiber)\n        return NULL;\n    return (ThreadContext *)currentFiber->user_data;\n}\n\nvoid setThreadContext(ThreadContext *ctx) {\n    currentFiber->user_data = ctx;\n}\n\nstatic void *threadAddressFor(codal::Fiber *fib, void *sp) {\n    if (fib == currentFiber)\n        return sp;\n    return (uint8_t *)sp + ((uint8_t *)fib->stack_top - (uint8_t *)tcb_get_stack_base(fib->tcb));\n}\n\nvoid gcProcessStacks(int flags) {\n    // check scheduler is initialized\n    if (!currentFiber) {\n        // make sure we allocate something to at least initalize the memory allocator\n        void *volatile p = xmalloc(1);\n        xfree(p);\n        return;\n    }\n\n    int numFibers = codal::list_fibers(NULL);\n    codal::Fiber **fibers = (codal::Fiber **)xmalloc(sizeof(codal::Fiber *) * numFibers);\n    int num2 = codal::list_fibers(fibers);\n    if (numFibers != num2)\n        oops(12);\n    int cnt = 0;\n\n    for (int i = 0; i < numFibers; ++i) {\n        auto fib = fibers[i];\n        auto ctx = (ThreadContext *)fib->user_data;\n        if (!ctx)\n            continue;\n        gcProcess(ctx->thrownValue);\n        for (auto seg = &ctx->stack; seg; seg = seg->next) {\n            auto ptr = (TValue *)threadAddressFor(fib, seg->top);\n            auto end = (TValue *)threadAddressFor(fib, seg->bottom);\n            if (flags & 2)\n                DMESG(\"RS%d:%p/%d\", cnt++, ptr, end - ptr);\n            // VLOG(\"mark: %p - %p\", ptr, end);\n            while (ptr < end) {\n                gcProcess(*ptr++);\n            }\n        }\n    }\n    xfree(fibers);\n}\n\nLowLevelTimer *getJACDACTimer() {\n    static LowLevelTimer *jacdacTimer;\n    if (!jacdacTimer) {\n        jacdacTimer = allocateTimer();\n        jacdacTimer->setIRQPriority(1);\n    }\n    return jacdacTimer;\n}\nvoid initSystemTimer() {\n    new CODAL_TIMER(*allocateTimer());\n}\n\n} // namespace pxt\n","control.cpp":"#include \"pxt.h\"\n\n#if defined(NRF52_SERIES) || defined(PICO_BOARD)\n#define _estack __StackTop \n#endif\nextern uint32_t _estack;\n\nnamespace control {\n\n/**\n * Announce that an event happened to registered handlers.\n * @param src ID of the MicroBit Component that generated the event\n * @param value Component specific code indicating the cause of the event.\n */\n//% weight=21 blockGap=12 blockId=\"control_raise_event\"\n//% help=control/raise-event\n//% block=\"raise event|from %src|with value %value\" blockExternalInputs=1\nvoid raiseEvent(int src, int value) {\n    Event evt(src, value);\n}\n\n/**\n* Determine the version of system software currently running.\n*/\n//% blockId=\"control_device_dal_version\" block=\"device dal version\"\n//% help=control/device-dal-version\nString deviceDalVersion() {\n    return mkString(device.getVersion());\n}\n\n/**\n* Allocates the next user notification event\n*/\n//% help=control/allocate-notify-event\nint allocateNotifyEvent() {\n    return ::allocateNotifyEvent();\n}\n\n/** Write a message to DMESG debugging buffer. */\n//%\nvoid dmesg(String s) {\n    DMESG(\"# %s\", s->getUTF8Data());\n}\n\n/** Write a message and value (pointer) to DMESG debugging buffer. */\n//%\nvoid dmesgPtr(String str, Object_ ptr) {\n    DMESG(\"# %s: %p\", str->getUTF8Data(), ptr);\n}\n\n//%\nuint32_t _ramSize()\n{\n    return (uint32_t)&_estack & 0x1fffffff;\n}\n\n}\n","dal.d.ts":"// Auto-generated. Do not edit.\ndeclare const enum DAL {\n    // /libraries/codal-core/inc/JACDAC/JDPhysicalLayer.h\n    Receiving = 0,\n    Transmitting = 1,\n    Error = 2,\n    Unknown = 3,\n    ListeningForPulse = 0,\n    ErrorRecovery = 1,\n    Off = 2,\n    Continuation = 0,\n    // /libraries/codal-core/inc/JACDAC/JDServiceClasses.h\n    STATIC_CLASS_START = 0,\n    STATIC_CLASS_END = 16777215,\n    DYNAMIC_CLASS_END = 4294967295,\n    // /libraries/codal-core/inc/core/CodalComponent.h\n    DEVICE_ID_BUTTON_A = 1,\n    DEVICE_ID_BUTTON_B = 2,\n    DEVICE_ID_BUTTON_AB = 3,\n    DEVICE_ID_BUTTON_RESET = 4,\n    DEVICE_ID_ACCELEROMETER = 5,\n    DEVICE_ID_COMPASS = 6,\n    DEVICE_ID_DISPLAY = 7,\n    DEVICE_ID_THERMOMETER = 8,\n    DEVICE_ID_RADIO = 9,\n    DEVICE_ID_RADIO_DATA_READY = 10,\n    DEVICE_ID_MULTIBUTTON_ATTACH = 11,\n    DEVICE_ID_SERIAL = 12,\n    DEVICE_ID_GESTURE = 13,\n    DEVICE_ID_SYSTEM_TIMER = 14,\n    DEVICE_ID_SCHEDULER = 15,\n    DEVICE_ID_COMPONENT = 16,\n    DEVICE_ID_LIGHT_SENSOR = 17,\n    DEVICE_ID_TOUCH_SENSOR = 18,\n    DEVICE_ID_SYSTEM_DAC = 19,\n    DEVICE_ID_SYSTEM_MICROPHONE = 20,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR = 21,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR_SPL = 22,\n    DEVICE_ID_MSC = 23,\n    DEVICE_ID_SPI = 24,\n    DEVICE_ID_DISTANCE = 25,\n    DEVICE_ID_GYROSCOPE = 26,\n    DEVICE_ID_HUMIDITY = 27,\n    DEVICE_ID_PRESSURE = 28,\n    DEVICE_ID_SINGLE_WIRE_SERIAL = 29,\n    DEVICE_ID_JACDAC = 30,\n    DEVICE_ID_JACDAC_PHYS = 31,\n    DEVICE_ID_JACDAC_CONTROL_SERVICE = 32,\n    DEVICE_ID_JACDAC_CONFIGURATION_SERVICE = 33,\n    DEVICE_ID_IO_P0 = 100,\n    DEVICE_ID_MESSAGE_BUS_LISTENER = 1021,\n    DEVICE_ID_NOTIFY_ONE = 1022,\n    DEVICE_ID_NOTIFY = 1023,\n    DEVICE_ID_BUTTON_UP = 2000,\n    DEVICE_ID_BUTTON_DOWN = 2001,\n    DEVICE_ID_BUTTON_LEFT = 2002,\n    DEVICE_ID_BUTTON_RIGHT = 2003,\n    DEVICE_ID_JD_DYNAMIC_ID = 3000,\n    DEVICE_COMPONENT_RUNNING = 4096,\n    DEVICE_COMPONENT_STATUS_SYSTEM_TICK = 8192,\n    DEVICE_COMPONENT_STATUS_IDLE_TICK = 16384,\n    DEVICE_COMPONENT_LISTENERS_CONFIGURED = 1,\n    DEVICE_COMPONENT_EVT_SYSTEM_TICK = 1,\n    // /libraries/codal-core/inc/core/CodalFiber.h\n    DEVICE_SCHEDULER_RUNNING = 1,\n    DEVICE_SCHEDULER_IDLE = 2,\n    DEVICE_FIBER_FLAG_FOB = 1,\n    DEVICE_FIBER_FLAG_PARENT = 2,\n    DEVICE_FIBER_FLAG_CHILD = 4,\n    DEVICE_FIBER_FLAG_DO_NOT_PAGE = 8,\n    DEVICE_SCHEDULER_EVT_TICK = 1,\n    DEVICE_SCHEDULER_EVT_IDLE = 2,\n    // /libraries/codal-core/inc/core/CodalListener.h\n    MESSAGE_BUS_LISTENER_PARAMETERISED = 1,\n    MESSAGE_BUS_LISTENER_METHOD = 2,\n    MESSAGE_BUS_LISTENER_BUSY = 4,\n    MESSAGE_BUS_LISTENER_REENTRANT = 8,\n    MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY = 16,\n    MESSAGE_BUS_LISTENER_DROP_IF_BUSY = 32,\n    MESSAGE_BUS_LISTENER_NONBLOCKING = 64,\n    MESSAGE_BUS_LISTENER_URGENT = 128,\n    MESSAGE_BUS_LISTENER_DELETING = 32768,\n    MESSAGE_BUS_LISTENER_IMMEDIATE = 192,\n    // /libraries/codal-core/inc/core/ErrorNo.h\n    DEVICE_OK = 0,\n    DEVICE_INVALID_PARAMETER = -1001,\n    DEVICE_NOT_SUPPORTED = -1002,\n    DEVICE_CALIBRATION_IN_PROGRESS = -1003,\n    DEVICE_CALIBRATION_REQUIRED = -1004,\n    DEVICE_NO_RESOURCES = -1005,\n    DEVICE_BUSY = -1006,\n    DEVICE_CANCELLED = -1007,\n    DEVICE_I2C_ERROR = -1010,\n    DEVICE_SERIAL_IN_USE = -1011,\n    DEVICE_NO_DATA = -1012,\n    DEVICE_NOT_IMPLEMENTED = -1013,\n    DEVICE_SPI_ERROR = -1014,\n    DEVICE_INVALID_STATE = -1015,\n    DEVICE_OOM = 20,\n    DEVICE_HEAP_ERROR = 30,\n    DEVICE_NULL_DEREFERENCE = 40,\n    DEVICE_USB_ERROR = 50,\n    DEVICE_JACDAC_ERROR = 60,\n    DEVICE_HARDWARE_CONFIGURATION_ERROR = 90,\n    // /libraries/codal-core/inc/core/NotifyEvents.h\n    DISPLAY_EVT_FREE = 1,\n    CODAL_SERIAL_EVT_TX_EMPTY = 2,\n    BLE_EVT_SERIAL_TX_EMPTY = 3,\n    ARCADE_PLAYER_JOIN_RESULT = 4,\n    DEVICE_NOTIFY_USER_EVENT_BASE = 1024,\n    // /libraries/codal-core/inc/driver-models/AbstractButton.h\n    DEVICE_BUTTON_EVT_DOWN = 1,\n    DEVICE_BUTTON_EVT_UP = 2,\n    DEVICE_BUTTON_EVT_CLICK = 3,\n    DEVICE_BUTTON_EVT_LONG_CLICK = 4,\n    DEVICE_BUTTON_EVT_HOLD = 5,\n    DEVICE_BUTTON_EVT_DOUBLE_CLICK = 6,\n    DEVICE_BUTTON_LONG_CLICK_TIME = 1000,\n    DEVICE_BUTTON_HOLD_TIME = 1500,\n    DEVICE_BUTTON_STATE = 1,\n    DEVICE_BUTTON_STATE_HOLD_TRIGGERED = 2,\n    DEVICE_BUTTON_STATE_CLICK = 4,\n    DEVICE_BUTTON_STATE_LONG_CLICK = 8,\n    DEVICE_BUTTON_SIGMA_MIN = 0,\n    DEVICE_BUTTON_SIGMA_MAX = 12,\n    DEVICE_BUTTON_SIGMA_THRESH_HI = 8,\n    DEVICE_BUTTON_SIGMA_THRESH_LO = 2,\n    DEVICE_BUTTON_DOUBLE_CLICK_THRESH = 50,\n    DEVICE_BUTTON_SIMPLE_EVENTS = 0,\n    DEVICE_BUTTON_ALL_EVENTS = 1,\n    ACTIVE_LOW = 0,\n    ACTIVE_HIGH = 1,\n    // /libraries/codal-core/inc/driver-models/Accelerometer.h\n    ACCELEROMETER_IMU_DATA_VALID = 2,\n    ACCELEROMETER_EVT_DATA_UPDATE = 1,\n    ACCELEROMETER_EVT_NONE = 0,\n    ACCELEROMETER_EVT_TILT_UP = 1,\n    ACCELEROMETER_EVT_TILT_DOWN = 2,\n    ACCELEROMETER_EVT_TILT_LEFT = 3,\n    ACCELEROMETER_EVT_TILT_RIGHT = 4,\n    ACCELEROMETER_EVT_FACE_UP = 5,\n    ACCELEROMETER_EVT_FACE_DOWN = 6,\n    ACCELEROMETER_EVT_FREEFALL = 7,\n    ACCELEROMETER_EVT_3G = 8,\n    ACCELEROMETER_EVT_6G = 9,\n    ACCELEROMETER_EVT_8G = 10,\n    ACCELEROMETER_EVT_SHAKE = 11,\n    ACCELEROMETER_EVT_2G = 12,\n    ACCELEROMETER_REST_TOLERANCE = 200,\n    ACCELEROMETER_TILT_TOLERANCE = 200,\n    ACCELEROMETER_FREEFALL_TOLERANCE = 400,\n    ACCELEROMETER_SHAKE_TOLERANCE = 400,\n    ACCELEROMETER_2G_TOLERANCE = 2048,\n    ACCELEROMETER_3G_TOLERANCE = 3072,\n    ACCELEROMETER_6G_TOLERANCE = 6144,\n    ACCELEROMETER_8G_TOLERANCE = 8192,\n    ACCELEROMETER_GESTURE_DAMPING = 5,\n    ACCELEROMETER_SHAKE_DAMPING = 10,\n    ACCELEROMETER_SHAKE_RTX = 30,\n    ACCELEROMETER_SHAKE_COUNT_THRESHOLD = 4,\n    // /libraries/codal-core/inc/driver-models/Compass.h\n    COMPASS_STATUS_RUNNING = 1,\n    COMPASS_STATUS_CALIBRATED = 2,\n    COMPASS_STATUS_CALIBRATING = 4,\n    COMPASS_STATUS_ADDED_TO_IDLE = 8,\n    COMPASS_EVT_DATA_UPDATE = 1,\n    COMPASS_EVT_CONFIG_NEEDED = 2,\n    COMPASS_EVT_CALIBRATE = 3,\n    COMPASS_EVT_CALIBRATION_NEEDED = 4,\n    // /libraries/codal-core/inc/driver-models/Gyroscope.h\n    GYROSCOPE_IMU_DATA_VALID = 2,\n    GYROSCOPE_EVT_DATA_UPDATE = 1,\n    // /libraries/codal-core/inc/driver-models/LowLevelTimer.h\n    TimerModeTimer = 0,\n    TimerModeCounter = 1,\n    TimerModeAlternateFunction = 2,\n    BitMode8 = 0,\n    BitMode16 = 1,\n    BitMode24 = 2,\n    BitMode32 = 3,\n    // /libraries/codal-core/inc/driver-models/Pin.h\n    IO_STATUS_DIGITAL_IN = 1,\n    IO_STATUS_DIGITAL_OUT = 2,\n    IO_STATUS_ANALOG_IN = 4,\n    IO_STATUS_ANALOG_OUT = 8,\n    IO_STATUS_TOUCH_IN = 16,\n    IO_STATUS_EVENT_ON_EDGE = 32,\n    IO_STATUS_EVENT_PULSE_ON_EDGE = 64,\n    IO_STATUS_INTERRUPT_ON_EDGE = 128,\n    DEVICE_PIN_MAX_OUTPUT = 1023,\n    DEVICE_PIN_MAX_SERVO_RANGE = 180,\n    DEVICE_PIN_DEFAULT_SERVO_RANGE = 2000,\n    DEVICE_PIN_DEFAULT_SERVO_CENTER = 1500,\n    DEVICE_PIN_EVENT_NONE = 0,\n    DEVICE_PIN_INTERRUPT_ON_EDGE = 1,\n    DEVICE_PIN_EVENT_ON_EDGE = 2,\n    DEVICE_PIN_EVENT_ON_PULSE = 3,\n    DEVICE_PIN_EVENT_ON_TOUCH = 4,\n    DEVICE_PIN_EVT_RISE = 2,\n    DEVICE_PIN_EVT_FALL = 3,\n    DEVICE_PIN_EVT_PULSE_HI = 4,\n    DEVICE_PIN_EVT_PULSE_LO = 5,\n    PIN_CAPABILITY_DIGITAL = 1,\n    PIN_CAPABILITY_ANALOG = 2,\n    PIN_CAPABILITY_AD = 3,\n    PIN_CAPABILITY_ALL = 3,\n    None = 0,\n    Down = 1,\n    Up = 2,\n    // /libraries/codal-core/inc/driver-models/Radio.h\n    RADIO_EVT_DATA_READY = 2,\n    // /libraries/codal-core/inc/driver-models/SPIFlash.h\n    SPIFLASH_PAGE_SIZE = 256,\n    SPIFLASH_SMALL_ROW_PAGES = 16,\n    SPIFLASH_BIG_ROW_PAGES = 256,\n    // /libraries/codal-core/inc/driver-models/Sensor.h\n    SENSOR_THRESHOLD_LOW = 1,\n    SENSOR_THRESHOLD_HIGH = 2,\n    SENSOR_UPDATE_NEEDED = 3,\n    SENSOR_INITIALISED = 1,\n    SENSOR_HIGH_THRESHOLD_PASSED = 2,\n    SENSOR_LOW_THRESHOLD_PASSED = 4,\n    SENSOR_LOW_THRESHOLD_ENABLED = 8,\n    SENSOR_HIGH_THRESHOLD_ENABLED = 16,\n    SENSOR_DEFAULT_SENSITIVITY = 868,\n    SENSOR_DEFAULT_SAMPLE_PERIOD = 500,\n    // /libraries/codal-core/inc/driver-models/Serial.h\n    CODAL_SERIAL_DEFAULT_BAUD_RATE = 115200,\n    CODAL_SERIAL_DEFAULT_BUFFER_SIZE = 20,\n    CODAL_SERIAL_EVT_DELIM_MATCH = 1,\n    CODAL_SERIAL_EVT_HEAD_MATCH = 2,\n    CODAL_SERIAL_EVT_RX_FULL = 3,\n    CODAL_SERIAL_EVT_DATA_RECEIVED = 4,\n    CODAL_SERIAL_STATUS_RX_IN_USE = 1,\n    CODAL_SERIAL_STATUS_TX_IN_USE = 2,\n    CODAL_SERIAL_STATUS_RX_BUFF_INIT = 4,\n    CODAL_SERIAL_STATUS_TX_BUFF_INIT = 8,\n    CODAL_SERIAL_STATUS_RXD = 16,\n    ASYNC = 0,\n    SYNC_SPINWAIT = 1,\n    SYNC_SLEEP = 2,\n    RxInterrupt = 0,\n    TxInterrupt = 1,\n    // /libraries/codal-core/inc/driver-models/SingleWireSerial.h\n    SWS_EVT_DATA_RECEIVED = 1,\n    SWS_EVT_DATA_SENT = 2,\n    SWS_EVT_ERROR = 3,\n    SWS_EVT_DATA_DROPPED = 4,\n    SingleWireRx = 0,\n    SingleWireTx = 1,\n    SingleWireDisconnected = 2,\n    // /libraries/codal-core/inc/driver-models/Timer.h\n    CODAL_TIMER_DEFAULT_EVENT_LIST_SIZE = 10,\n    // /libraries/codal-core/inc/drivers/AnalogSensor.h\n    ANALOG_THRESHOLD_LOW = 1,\n    ANALOG_THRESHOLD_HIGH = 2,\n    ANALOG_SENSOR_UPDATE_NEEDED = 3,\n    ANALOG_SENSOR_INITIALISED = 1,\n    ANALOG_SENSOR_HIGH_THRESHOLD_PASSED = 2,\n    ANALOG_SENSOR_LOW_THRESHOLD_PASSED = 4,\n    ANALOG_SENSOR_LOW_THRESHOLD_ENABLED = 8,\n    ANALOG_SENSOR_HIGH_THRESHOLD_ENABLED = 16,\n    // /libraries/codal-core/inc/drivers/AnimatedDisplay.h\n    DISPLAY_EVT_ANIMATION_COMPLETE = 1,\n    DISPLAY_DEFAULT_AUTOCLEAR = 1,\n    DISPLAY_SPACING = 1,\n    DISPLAY_ANIMATE_DEFAULT_POS = -255,\n    DISPLAY_DEFAULT_SCROLL_SPEED = 120,\n    DISPLAY_DEFAULT_SCROLL_STRIDE = -1,\n    DISPLAY_DEFAULT_PRINT_SPEED = 400,\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    // /libraries/codal-core/inc/drivers/FAT.h\n    FAT_RESERVED_SECTORS = 1,\n    FAT_ROOT_DIR_SECTORS = 4,\n    // /libraries/codal-core/inc/drivers/HID.h\n    HID_REQUEST_GET_REPORT = 1,\n    HID_REQUEST_GET_IDLE = 2,\n    HID_REQUEST_GET_PROTOCOL = 3,\n    HID_REQUEST_SET_REPORT = 9,\n    HID_REQUEST_SET_IDLE = 10,\n    HID_REQUEST_SET_PROTOCOL = 11,\n    // /libraries/codal-core/inc/drivers/HIDKeyboard.h\n    HID_KEYBOARD_NUM_REPORTS = 3,\n    HID_KEYBOARD_REPORT_GENERIC = 1,\n    HID_KEYBOARD_REPORT_CONSUMER = 2,\n    HID_KEYBOARD_KEYSTATE_SIZE_GENERIC = 8,\n    HID_KEYBOARD_KEYSTATE_SIZE_CONSUMER = 2,\n    HID_KEYBOARD_MODIFIER_OFFSET = 2,\n    HID_KEYBOARD_DELAY_DEFAULT = 10,\n    PressKey = 0,\n    ReleaseKey = 1,\n    // /libraries/codal-core/inc/drivers/KeyMap.h\n    KEYMAP_ALL_KEYS_UP_Val = 1,\n    KEYMAP_ALL_KEYS_UP_POS = 28,\n    KEYMAP_NORMAL_KEY_Val = 0,\n    KEYMAP_MODIFIER_KEY_Val = 1,\n    KEYMAP_MODIFIER_POS = 29,\n    KEYMAP_MEDIA_KEY_Val = 1,\n    KEYMAP_MEDIA_POS = 30,\n    KEYMAP_KEY_UP_Val = 0,\n    KEYMAP_KEY_DOWN_Val = 1,\n    KEYMAP_KEY_DOWN_POS = 31,\n    // /libraries/codal-core/inc/drivers/KeyValueStorage.h\n    DEVICE_KEY_VALUE_STORE_OFFSET = 4,\n    KEY_VALUE_STORAGE_MAGIC = 49370,\n    KEY_VALUE_STORAGE_BLOCK_SIZE = 48,\n    KEY_VALUE_STORAGE_KEY_SIZE = 16,\n    KEY_VALUE_STORAGE_SCRATCH_WORD_SIZE = 64,\n    KEY_VALUE_STORAGE_MAX_PAIRS = 5,\n    // /libraries/codal-core/inc/drivers/LEDMatrix.h\n    LED_MATRIX_GREYSCALE_BIT_DEPTH = 8,\n    LED_MATRIX_EVT_LIGHT_SENSE = 2,\n    LED_MATRIX_EVT_FRAME_TIMEOUT = 3,\n    LED_MATRIX_MINIMUM_BRIGHTNESS = 1,\n    LED_MATRIX_MAXIMUM_BRIGHTNESS = 255,\n    LED_MATRIX_DEFAULT_BRIGHTNESS = 255,\n    DISPLAY_MODE_BLACK_AND_WHITE = 0,\n    DISPLAY_MODE_GREYSCALE = 1,\n    DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE = 2,\n    MATRIX_DISPLAY_ROTATION_0 = 0,\n    MATRIX_DISPLAY_ROTATION_90 = 1,\n    MATRIX_DISPLAY_ROTATION_180 = 2,\n    MATRIX_DISPLAY_ROTATION_270 = 3,\n    NO_CONN = 0,\n    // /libraries/codal-core/inc/drivers/MMA8653.h\n    MICROBIT_ACCEL_PITCH_ROLL_VALID = 2,\n    MICROBIT_ACCEL_ADDED_TO_IDLE = 4,\n    // /libraries/codal-core/inc/drivers/MultiButton.h\n    MULTI_BUTTON_STATE_1 = 1,\n    MULTI_BUTTON_STATE_2 = 2,\n    MULTI_BUTTON_HOLD_TRIGGERED_1 = 4,\n    MULTI_BUTTON_HOLD_TRIGGERED_2 = 8,\n    MULTI_BUTTON_SUPRESSED_1 = 16,\n    MULTI_BUTTON_SUPRESSED_2 = 32,\n    MULTI_BUTTON_ATTACHED = 64,\n    // /libraries/codal-core/inc/drivers/TouchButton.h\n    TOUCH_BUTTON_CALIBRATION_PERIOD = 10,\n    TOUCH_BUTTON_CALIBRATION_LINEAR_OFFSET = 2,\n    TOUCH_BUTTON_CALIBRATION_PERCENTAGE_OFFSET = 5,\n    TOUCH_BUTTON_CALIBRATING = 16,\n    // /libraries/codal-core/inc/drivers/TouchSensor.h\n    TOUCH_SENSOR_MAX_BUTTONS = 10,\n    TOUCH_SENSOR_SAMPLE_PERIOD = 50,\n    TOUCH_SENSE_SAMPLE_MAX = 1000,\n    TOUCH_SENSOR_UPDATE_NEEDED = 1,\n    // /libraries/codal-core/inc/drivers/USBJACDAC.h\n    JACDAC_USB_STATUS_CLEAR_TO_SEND = 2,\n    // /libraries/codal-core/inc/drivers/USB_HID_Keys.h\n    KEY_MOD_LCTRL = 1,\n    KEY_MOD_LSHIFT = 2,\n    KEY_MOD_LALT = 4,\n    KEY_MOD_LMETA = 8,\n    KEY_MOD_RCTRL = 16,\n    KEY_MOD_RSHIFT = 32,\n    KEY_MOD_RALT = 64,\n    KEY_MOD_RMETA = 128,\n    KEY_NONE = 0,\n    KEY_ERR_OVF = 1,\n    KEY_A = 4,\n    KEY_B = 5,\n    KEY_C = 6,\n    KEY_D = 7,\n    KEY_E = 8,\n    KEY_F = 9,\n    KEY_G = 10,\n    KEY_H = 11,\n    KEY_I = 12,\n    KEY_J = 13,\n    KEY_K = 14,\n    KEY_L = 15,\n    KEY_M = 16,\n    KEY_N = 17,\n    KEY_O = 18,\n    KEY_P = 19,\n    KEY_Q = 20,\n    KEY_R = 21,\n    KEY_S = 22,\n    KEY_T = 23,\n    KEY_U = 24,\n    KEY_V = 25,\n    KEY_W = 26,\n    KEY_X = 27,\n    KEY_Y = 28,\n    KEY_Z = 29,\n    KEY_1 = 30,\n    KEY_2 = 31,\n    KEY_3 = 32,\n    KEY_4 = 33,\n    KEY_5 = 34,\n    KEY_6 = 35,\n    KEY_7 = 36,\n    KEY_8 = 37,\n    KEY_9 = 38,\n    KEY_0 = 39,\n    KEY_ENTER = 40,\n    KEY_ESC = 41,\n    KEY_BACKSPACE = 42,\n    KEY_TAB = 43,\n    KEY_SPACE = 44,\n    KEY_MINUS = 45,\n    KEY_EQUAL = 46,\n    KEY_LEFTBRACE = 47,\n    KEY_RIGHTBRACE = 48,\n    KEY_BACKSLASH = 49,\n    KEY_HASHTILDE = 50,\n    KEY_SEMICOLON = 51,\n    KEY_APOSTROPHE = 52,\n    KEY_GRAVE = 53,\n    KEY_COMMA = 54,\n    KEY_DOT = 55,\n    KEY_SLASH = 56,\n    KEY_CAPSLOCK = 57,\n    KEY_F1 = 58,\n    KEY_F2 = 59,\n    KEY_F3 = 60,\n    KEY_F4 = 61,\n    KEY_F5 = 62,\n    KEY_F6 = 63,\n    KEY_F7 = 64,\n    KEY_F8 = 65,\n    KEY_F9 = 66,\n    KEY_F10 = 67,\n    KEY_F11 = 68,\n    KEY_F12 = 69,\n    KEY_SYSRQ = 70,\n    KEY_SCROLLLOCK = 71,\n    KEY_PAUSE = 72,\n    KEY_INSERT = 73,\n    KEY_HOME = 74,\n    KEY_PAGEUP = 75,\n    KEY_DELETE = 76,\n    KEY_END = 77,\n    KEY_PAGEDOWN = 78,\n    KEY_RIGHT = 79,\n    KEY_LEFT = 80,\n    KEY_DOWN = 81,\n    KEY_UP = 82,\n    KEY_NUMLOCK = 83,\n    KEY_KPSLASH = 84,\n    KEY_KPASTERISK = 85,\n    KEY_KPMINUS = 86,\n    KEY_KPPLUS = 87,\n    KEY_KPENTER = 88,\n    KEY_KP1 = 89,\n    KEY_KP2 = 90,\n    KEY_KP3 = 91,\n    KEY_KP4 = 92,\n    KEY_KP5 = 93,\n    KEY_KP6 = 94,\n    KEY_KP7 = 95,\n    KEY_KP8 = 96,\n    KEY_KP9 = 97,\n    KEY_KP0 = 98,\n    KEY_KPDOT = 99,\n    KEY_102ND = 100,\n    KEY_COMPOSE = 101,\n    KEY_POWER = 102,\n    KEY_KPEQUAL = 103,\n    KEY_F13 = 104,\n    KEY_F14 = 105,\n    KEY_F15 = 106,\n    KEY_F16 = 107,\n    KEY_F17 = 108,\n    KEY_F18 = 109,\n    KEY_F19 = 110,\n    KEY_F20 = 111,\n    KEY_F21 = 112,\n    KEY_F22 = 113,\n    KEY_F23 = 114,\n    KEY_F24 = 115,\n    KEY_OPEN = 116,\n    KEY_HELP = 117,\n    KEY_PROPS = 118,\n    KEY_FRONT = 119,\n    KEY_STOP = 120,\n    KEY_AGAIN = 121,\n    KEY_UNDO = 122,\n    KEY_CUT = 123,\n    KEY_COPY = 124,\n    KEY_PASTE = 125,\n    KEY_FIND = 126,\n    KEY_MUTE = 127,\n    KEY_VOLUMEUP = 128,\n    KEY_VOLUMEDOWN = 129,\n    KEY_KPCOMMA = 133,\n    KEY_RO = 135,\n    KEY_KATAKANAHIRAGANA = 136,\n    KEY_YEN = 137,\n    KEY_HENKAN = 138,\n    KEY_MUHENKAN = 139,\n    KEY_KPJPCOMMA = 140,\n    KEY_HANGEUL = 144,\n    KEY_HANJA = 145,\n    KEY_KATAKANA = 146,\n    KEY_HIRAGANA = 147,\n    KEY_ZENKAKUHANKAKU = 148,\n    KEY_KPLEFTPAREN = 182,\n    KEY_KPRIGHTPAREN = 183,\n    KEY_LEFTCTRL = 224,\n    KEY_LEFTSHIFT = 225,\n    KEY_LEFTALT = 226,\n    KEY_LEFTMETA = 227,\n    KEY_RIGHTCTRL = 228,\n    KEY_RIGHTSHIFT = 229,\n    KEY_RIGHTALT = 230,\n    KEY_RIGHTMETA = 231,\n    KEY_MEDIA_PLAYPAUSE = 232,\n    KEY_MEDIA_STOPCD = 233,\n    KEY_MEDIA_PREVIOUSSONG = 234,\n    KEY_MEDIA_NEXTSONG = 235,\n    KEY_MEDIA_EJECTCD = 236,\n    KEY_MEDIA_VOLUMEUP = 237,\n    KEY_MEDIA_VOLUMEDOWN = 238,\n    KEY_MEDIA_MUTE = 239,\n    KEY_MEDIA_WWW = 240,\n    KEY_MEDIA_BACK = 241,\n    KEY_MEDIA_FORWARD = 242,\n    KEY_MEDIA_STOP = 243,\n    KEY_MEDIA_FIND = 244,\n    KEY_MEDIA_SCROLLUP = 245,\n    KEY_MEDIA_SCROLLDOWN = 246,\n    KEY_MEDIA_EDIT = 247,\n    KEY_MEDIA_SLEEP = 248,\n    KEY_MEDIA_COFFEE = 249,\n    KEY_MEDIA_REFRESH = 250,\n    KEY_MEDIA_CALC = 251,\n    // /libraries/codal-core/inc/drivers/uf2format.h\n    UF2FORMAT_H = 1,\n    APP_START_ADDRESS = 8192,\n    UF2_FLAG_NOFLASH = 1,\n    // /libraries/codal-core/inc/streams/DataStream.h\n    DATASTREAM_MAXIMUM_BUFFERS = 1,\n    // /libraries/codal-core/inc/streams/LevelDetector.h\n    LEVEL_THRESHOLD_LOW = 1,\n    LEVEL_THRESHOLD_HIGH = 2,\n    LEVEL_DETECTOR_INITIALISED = 1,\n    LEVEL_DETECTOR_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_DEFAULT_WINDOW_SIZE = 128,\n    // /libraries/codal-core/inc/streams/LevelDetectorSPL.h\n    LEVEL_DETECTOR_SPL_INITIALISED = 1,\n    LEVEL_DETECTOR_SPL_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_SPL_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_SPL_DEFAULT_WINDOW_SIZE = 128,\n    // /libraries/codal-core/inc/streams/Synthesizer.h\n    SYNTHESIZER_SAMPLE_RATE = 44100,\n    TONE_WIDTH = 1024,\n    // /libraries/codal-core/inc/types/BitmapFont.h\n    BITMAP_FONT_WIDTH = 5,\n    BITMAP_FONT_HEIGHT = 5,\n    BITMAP_FONT_ASCII_START = 32,\n    BITMAP_FONT_ASCII_END = 126,\n    // /libraries/codal-core/inc/types/CoordinateSystem.h\n    COORDINATE_SPACE_ROTATED_0 = 0,\n    COORDINATE_SPACE_ROTATED_90 = 1,\n    COORDINATE_SPACE_ROTATED_180 = 2,\n    COORDINATE_SPACE_ROTATED_270 = 3,\n    RAW = 0,\n    SIMPLE_CARTESIAN = 1,\n    NORTH_EAST_DOWN = 2,\n    NORTH_EAST_UP = 3,\n    // /libraries/codal-core/inc/types/Event.h\n    DEVICE_ID_ANY = 0,\n    DEVICE_EVT_ANY = 0,\n    CREATE_ONLY = 0,\n    CREATE_AND_FIRE = 1,\n    DEVICE_EVENT_DEFAULT_LAUNCH_MODE = 1,\n    // /libraries/codal-core/inc/types/RefCounted.h\n    REF_TAG_STRING = 1,\n    REF_TAG_BUFFER = 2,\n    REF_TAG_IMAGE = 3,\n    REF_TAG_USER = 32,\n    // /pxtapp/accelerometer/axis.h\n    ACC_SYSTEM = 3,\n    ACC_ROTATION = 0,\n    // /pxtapp/configkeys.h\n    CFG_PIN_NAME_MSK = 65535,\n    CFG_PIN_CONFIG_MSK = 4294901760,\n    CFG_PIN_CONFIG_ACTIVE_LO = 65536,\n    CFG_MAGIC0 = 513675505,\n    CFG_MAGIC1 = 539130489,\n    CFG_PIN_ACCELEROMETER_INT = 1,\n    CFG_PIN_ACCELEROMETER_SCL = 2,\n    CFG_PIN_ACCELEROMETER_SDA = 3,\n    CFG_PIN_BTN_A = 4,\n    CFG_PIN_BTN_B = 5,\n    CFG_PIN_BTN_SLIDE = 6,\n    CFG_PIN_DOTSTAR_CLOCK = 7,\n    CFG_PIN_DOTSTAR_DATA = 8,\n    CFG_PIN_FLASH_CS = 9,\n    CFG_PIN_FLASH_MISO = 10,\n    CFG_PIN_FLASH_MOSI = 11,\n    CFG_PIN_FLASH_SCK = 12,\n    CFG_PIN_LED = 13,\n    CFG_PIN_LIGHT = 14,\n    CFG_PIN_MICROPHONE = 15,\n    CFG_PIN_MIC_CLOCK = 16,\n    CFG_PIN_MIC_DATA = 17,\n    CFG_PIN_MISO = 18,\n    CFG_PIN_MOSI = 19,\n    CFG_PIN_NEOPIXEL = 20,\n    CFG_PIN_RX = 21,\n    CFG_PIN_RXLED = 22,\n    CFG_PIN_SCK = 23,\n    CFG_PIN_SCL = 24,\n    CFG_PIN_SDA = 25,\n    CFG_PIN_SPEAKER_AMP = 26,\n    CFG_PIN_TEMPERATURE = 27,\n    CFG_PIN_TX = 28,\n    CFG_PIN_TXLED = 29,\n    CFG_PIN_IR_OUT = 30,\n    CFG_PIN_IR_IN = 31,\n    CFG_PIN_DISPLAY_SCK = 32,\n    CFG_PIN_DISPLAY_MISO = 33,\n    CFG_PIN_DISPLAY_MOSI = 34,\n    CFG_PIN_DISPLAY_CS = 35,\n    CFG_PIN_DISPLAY_DC = 36,\n    CFG_DISPLAY_WIDTH = 37,\n    CFG_DISPLAY_HEIGHT = 38,\n    CFG_DISPLAY_CFG0 = 39,\n    CFG_DISPLAY_CFG1 = 40,\n    CFG_DISPLAY_CFG2 = 41,\n    CFG_DISPLAY_CFG3 = 42,\n    CFG_PIN_DISPLAY_RST = 43,\n    CFG_PIN_DISPLAY_BL = 44,\n    CFG_PIN_SERVO_1 = 45,\n    CFG_PIN_SERVO_2 = 46,\n    CFG_PIN_BTN_LEFT = 47,\n    CFG_PIN_BTN_RIGHT = 48,\n    CFG_PIN_BTN_UP = 49,\n    CFG_PIN_BTN_DOWN = 50,\n    CFG_PIN_BTN_MENU = 51,\n    CFG_PIN_LED_R = 52,\n    CFG_PIN_LED_G = 53,\n    CFG_PIN_LED_B = 54,\n    CFG_PIN_LED1 = 55,\n    CFG_PIN_LED2 = 56,\n    CFG_PIN_LED3 = 57,\n    CFG_PIN_LED4 = 58,\n    CFG_SPEAKER_VOLUME = 59,\n    CFG_PIN_JACK_TX = 60,\n    CFG_PIN_JACK_SENSE = 61,\n    CFG_PIN_JACK_HPEN = 62,\n    CFG_PIN_JACK_BZEN = 63,\n    CFG_PIN_JACK_PWREN = 64,\n    CFG_PIN_JACK_SND = 65,\n    CFG_PIN_JACK_BUSLED = 66,\n    CFG_PIN_JACK_COMMLED = 67,\n    CFG_PIN_BTN_SOFT_RESET = 69,\n    CFG_ACCELEROMETER_TYPE = 70,\n    CFG_PIN_BTNMX_LATCH = 71,\n    CFG_PIN_BTNMX_CLOCK = 72,\n    CFG_PIN_BTNMX_DATA = 73,\n    CFG_PIN_BTN_MENU2 = 74,\n    CFG_PIN_BATTSENSE = 75,\n    CFG_PIN_VIBRATION = 76,\n    CFG_PIN_PWREN = 77,\n    CFG_DISPLAY_TYPE = 78,\n    CFG_PIN_ROTARY_ENCODER_A = 79,\n    CFG_PIN_ROTARY_ENCODER_B = 80,\n    CFG_ACCELEROMETER_SPACE = 81,\n    CFG_PIN_WIFI_MOSI = 82,\n    CFG_PIN_WIFI_MISO = 83,\n    CFG_PIN_WIFI_SCK = 84,\n    CFG_PIN_WIFI_TX = 85,\n    CFG_PIN_WIFI_RX = 86,\n    CFG_PIN_WIFI_CS = 87,\n    CFG_PIN_WIFI_BUSY = 88,\n    CFG_PIN_WIFI_RESET = 89,\n    CFG_PIN_WIFI_GPIO0 = 90,\n    CFG_PIN_WIFI_AT_TX = 91,\n    CFG_PIN_WIFI_AT_RX = 92,\n    CFG_PIN_USB_POWER = 93,\n    CFG_DISPLAY_DELAY = 94,\n    ACCELEROMETER_TYPE_LIS3DH = 50,\n    ACCELEROMETER_TYPE_LIS3DH_ALT = 48,\n    ACCELEROMETER_TYPE_MMA8453 = 56,\n    ACCELEROMETER_TYPE_FXOS8700 = 60,\n    ACCELEROMETER_TYPE_MMA8653 = 58,\n    ACCELEROMETER_TYPE_MSA300 = 76,\n    ACCELEROMETER_TYPE_MPU6050 = 104,\n    DISPLAY_TYPE_ST7735 = 7735,\n    DISPLAY_TYPE_ILI9341 = 9341,\n    DISPLAY_TYPE_SMART = 4242,\n    CFG_PIN_A0 = 100,\n    CFG_PIN_A1 = 101,\n    CFG_PIN_A2 = 102,\n    CFG_PIN_A3 = 103,\n    CFG_PIN_A4 = 104,\n    CFG_PIN_A5 = 105,\n    CFG_PIN_A6 = 106,\n    CFG_PIN_A7 = 107,\n    CFG_PIN_A8 = 108,\n    CFG_PIN_A9 = 109,\n    CFG_PIN_A10 = 110,\n    CFG_PIN_A11 = 111,\n    CFG_PIN_A12 = 112,\n    CFG_PIN_A13 = 113,\n    CFG_PIN_A14 = 114,\n    CFG_PIN_A15 = 115,\n    CFG_PIN_A16 = 116,\n    CFG_PIN_A17 = 117,\n    CFG_PIN_A18 = 118,\n    CFG_PIN_A19 = 119,\n    CFG_PIN_A20 = 120,\n    CFG_PIN_A21 = 121,\n    CFG_PIN_A22 = 122,\n    CFG_PIN_A23 = 123,\n    CFG_PIN_A24 = 124,\n    CFG_PIN_A25 = 125,\n    CFG_PIN_A26 = 126,\n    CFG_PIN_A27 = 127,\n    CFG_PIN_A28 = 128,\n    CFG_PIN_A29 = 129,\n    CFG_PIN_A30 = 130,\n    CFG_PIN_A31 = 131,\n    CFG_PIN_D0 = 150,\n    CFG_PIN_D1 = 151,\n    CFG_PIN_D2 = 152,\n    CFG_PIN_D3 = 153,\n    CFG_PIN_D4 = 154,\n    CFG_PIN_D5 = 155,\n    CFG_PIN_D6 = 156,\n    CFG_PIN_D7 = 157,\n    CFG_PIN_D8 = 158,\n    CFG_PIN_D9 = 159,\n    CFG_PIN_D10 = 160,\n    CFG_PIN_D11 = 161,\n    CFG_PIN_D12 = 162,\n    CFG_PIN_D13 = 163,\n    CFG_PIN_D14 = 164,\n    CFG_PIN_D15 = 165,\n    CFG_PIN_D16 = 166,\n    CFG_PIN_D17 = 167,\n    CFG_PIN_D18 = 168,\n    CFG_PIN_D19 = 169,\n    CFG_PIN_D20 = 170,\n    CFG_PIN_D21 = 171,\n    CFG_PIN_D22 = 172,\n    CFG_PIN_D23 = 173,\n    CFG_PIN_D24 = 174,\n    CFG_PIN_D25 = 175,\n    CFG_PIN_D26 = 176,\n    CFG_PIN_D27 = 177,\n    CFG_PIN_D28 = 178,\n    CFG_PIN_D29 = 179,\n    CFG_PIN_D30 = 180,\n    CFG_PIN_D31 = 181,\n    CFG_NUM_NEOPIXELS = 200,\n    CFG_NUM_DOTSTARS = 201,\n    CFG_DEFAULT_BUTTON_MODE = 202,\n    CFG_SWD_ENABLED = 203,\n    CFG_FLASH_BYTES = 204,\n    CFG_RAM_BYTES = 205,\n    CFG_SYSTEM_HEAP_BYTES = 206,\n    CFG_LOW_MEM_SIMULATION_KB = 207,\n    CFG_BOOTLOADER_BOARD_ID = 208,\n    CFG_UF2_FAMILY = 209,\n    CFG_PINS_PORT_SIZE = 210,\n    CFG_BOOTLOADER_PROTECTION = 211,\n    CFG_POWER_DEEPSLEEP_TIMEOUT = 212,\n    CFG_ANALOG_BUTTON_THRESHOLD = 213,\n    CFG_CPU_MHZ = 214,\n    CFG_CONTROLLER_LIGHT_MAX_BRIGHTNESS = 215,\n    CFG_ANALOG_JOYSTICK_MIN = 216,\n    CFG_ANALOG_JOYSTICK_MAX = 217,\n    CFG_TIMERS_TO_USE = 218,\n    CFG_PIN_ONBOARD_DOTSTAR_CLOCK = 219,\n    CFG_PIN_ONBOARD_DOTSTAR_DATA = 220,\n    CFG_NUM_ONBOARD_DOTSTARS = 221,\n    CFG_PIN_ONBOARD_NEOPIXEL = 222,\n    CFG_NUM_ONBOARD_NEOPIXELS = 223,\n    CFG_MATRIX_KEYPAD_MESSAGE_ID = 239,\n    CFG_NUM_MATRIX_KEYPAD_ROWS = 240,\n    CFG_PIN_MATRIX_KEYPAD_ROW0 = 241,\n    CFG_PIN_MATRIX_KEYPAD_ROW1 = 242,\n    CFG_PIN_MATRIX_KEYPAD_ROW2 = 243,\n    CFG_PIN_MATRIX_KEYPAD_ROW3 = 244,\n    CFG_PIN_MATRIX_KEYPAD_ROW4 = 245,\n    CFG_PIN_MATRIX_KEYPAD_ROW5 = 246,\n    CFG_PIN_MATRIX_KEYPAD_ROW6 = 247,\n    CFG_PIN_MATRIX_KEYPAD_ROW7 = 248,\n    CFG_NUM_MATRIX_KEYPAD_COLS = 250,\n    CFG_PIN_MATRIX_KEYPAD_COL0 = 251,\n    CFG_PIN_MATRIX_KEYPAD_COL1 = 252,\n    CFG_PIN_MATRIX_KEYPAD_COL2 = 253,\n    CFG_PIN_MATRIX_KEYPAD_COL3 = 254,\n    CFG_PIN_MATRIX_KEYPAD_COL4 = 255,\n    CFG_PIN_MATRIX_KEYPAD_COL5 = 256,\n    CFG_PIN_MATRIX_KEYPAD_COL6 = 257,\n    CFG_PIN_MATRIX_KEYPAD_COL7 = 258,\n    CFG_PIN_B0 = 300,\n    CFG_PIN_B1 = 301,\n    CFG_PIN_B2 = 302,\n    CFG_PIN_B3 = 303,\n    CFG_PIN_B4 = 304,\n    CFG_PIN_B5 = 305,\n    CFG_PIN_B6 = 306,\n    CFG_PIN_B7 = 307,\n    CFG_PIN_B8 = 308,\n    CFG_PIN_B9 = 309,\n    CFG_PIN_B10 = 310,\n    CFG_PIN_B11 = 311,\n    CFG_PIN_B12 = 312,\n    CFG_PIN_B13 = 313,\n    CFG_PIN_B14 = 314,\n    CFG_PIN_B15 = 315,\n    CFG_PIN_B16 = 316,\n    CFG_PIN_B17 = 317,\n    CFG_PIN_B18 = 318,\n    CFG_PIN_B19 = 319,\n    CFG_PIN_B20 = 320,\n    CFG_PIN_B21 = 321,\n    CFG_PIN_B22 = 322,\n    CFG_PIN_B23 = 323,\n    CFG_PIN_B24 = 324,\n    CFG_PIN_B25 = 325,\n    CFG_PIN_B26 = 326,\n    CFG_PIN_B27 = 327,\n    CFG_PIN_B28 = 328,\n    CFG_PIN_B29 = 329,\n    CFG_PIN_B30 = 330,\n    CFG_PIN_B31 = 331,\n    CFG_PIN_C0 = 350,\n    CFG_PIN_C1 = 351,\n    CFG_PIN_C2 = 352,\n    CFG_PIN_C3 = 353,\n    CFG_PIN_C4 = 354,\n    CFG_PIN_C5 = 355,\n    CFG_PIN_C6 = 356,\n    CFG_PIN_C7 = 357,\n    CFG_PIN_C8 = 358,\n    CFG_PIN_C9 = 359,\n    CFG_PIN_C10 = 360,\n    CFG_PIN_C11 = 361,\n    CFG_PIN_C12 = 362,\n    CFG_PIN_C13 = 363,\n    CFG_PIN_C14 = 364,\n    CFG_PIN_C15 = 365,\n    CFG_PIN_C16 = 366,\n    CFG_PIN_C17 = 367,\n    CFG_PIN_C18 = 368,\n    CFG_PIN_C19 = 369,\n    CFG_PIN_C20 = 370,\n    CFG_PIN_C21 = 371,\n    CFG_PIN_C22 = 372,\n    CFG_PIN_C23 = 373,\n    CFG_PIN_C24 = 374,\n    CFG_PIN_C25 = 375,\n    CFG_PIN_C26 = 376,\n    CFG_PIN_C27 = 377,\n    CFG_PIN_C28 = 378,\n    CFG_PIN_C29 = 379,\n    CFG_PIN_C30 = 380,\n    CFG_PIN_C31 = 381,\n    CFG_PIN_P0 = 400,\n    CFG_PIN_P1 = 401,\n    CFG_PIN_P2 = 402,\n    CFG_PIN_P3 = 403,\n    CFG_PIN_P4 = 404,\n    CFG_PIN_P5 = 405,\n    CFG_PIN_P6 = 406,\n    CFG_PIN_P7 = 407,\n    CFG_PIN_P8 = 408,\n    CFG_PIN_P9 = 409,\n    CFG_PIN_P10 = 410,\n    CFG_PIN_P11 = 411,\n    CFG_PIN_P12 = 412,\n    CFG_PIN_P13 = 413,\n    CFG_PIN_P14 = 414,\n    CFG_PIN_P15 = 415,\n    CFG_PIN_P16 = 416,\n    CFG_PIN_P17 = 417,\n    CFG_PIN_P18 = 418,\n    CFG_PIN_P19 = 419,\n    CFG_PIN_P20 = 420,\n    CFG_PIN_P21 = 421,\n    CFG_PIN_P22 = 422,\n    CFG_PIN_P23 = 423,\n    CFG_PIN_P24 = 424,\n    CFG_PIN_P25 = 425,\n    CFG_PIN_P26 = 426,\n    CFG_PIN_P27 = 427,\n    CFG_PIN_P28 = 428,\n    CFG_PIN_P29 = 429,\n    CFG_PIN_P30 = 430,\n    CFG_PIN_P31 = 431,\n    CFG_PIN_LORA_MISO = 1001,\n    CFG_PIN_LORA_MOSI = 1002,\n    CFG_PIN_LORA_SCK = 1003,\n    CFG_PIN_LORA_CS = 1004,\n    CFG_PIN_LORA_BOOT = 1005,\n    CFG_PIN_LORA_RESET = 1006,\n    CFG_PIN_IRRXLED = 1007,\n    CFG_PIN_IRTXLED = 1008,\n    CFG_PIN_LCD_RESET = 1009,\n    CFG_PIN_LCD_ENABLE = 1010,\n    CFG_PIN_LCD_DATALINE4 = 1011,\n    CFG_PIN_LCD_DATALINE5 = 1012,\n    CFG_PIN_LCD_DATALINE6 = 1013,\n    CFG_PIN_LCD_DATALINE7 = 1014,\n    CFG_NUM_LCD_COLUMNS = 1015,\n    CFG_NUM_LCD_ROWS = 1016,\n    CFG_PIN_RCC0 = 1017,\n    CFG_PIN_RCC1 = 1018,\n    CFG_PIN_RCC2 = 1019,\n    CFG_PIN_RCC3 = 1020,\n    CFG_PIN_RCC4 = 1021,\n    CFG_PIN_RCC5 = 1022,\n    CFG_PIN_RCC6 = 1023,\n    CFG_PIN_RCC7 = 1024,\n    CFG_PIN_SERVO0 = 1025,\n    CFG_PIN_SERVO1 = 1026,\n    CFG_PIN_SERVO2 = 1027,\n    CFG_PIN_SERVO3 = 1028,\n    CFG_PIN_SERVO4 = 1029,\n    CFG_PIN_SERVO5 = 1030,\n    CFG_PIN_SERVO6 = 1031,\n    CFG_PIN_SERVO7 = 1032,\n    CFG_PIN_SERVO8 = 1033,\n    CFG_PIN_PI_TX = 1034,\n    CFG_PIN_PI_RX = 1035,\n    CFG_PIN_GPS_SDA = 1036,\n    CFG_PIN_GPS_SCL = 1037,\n    CFG_PIN_GPS_TX = 1038,\n    CFG_PIN_GPS_RX = 1039,\n    CFG_PIN_GROVE0 = 1040,\n    CFG_PIN_GROVE1 = 1041,\n    CFG_PIN_SS = 1042,\n    CFG_USER_CFG_0 = 2000,\n    CFG_USER_CFG_1 = 2001,\n    CFG_USER_CFG_2 = 2002,\n    CFG_USER_CFG_3 = 2003,\n    CFG_USER_CFG_4 = 2004,\n    CFG_USER_CFG_5 = 2005,\n    CFG_USER_CFG_6 = 2006,\n    CFG_USER_CFG_7 = 2007,\n    CFG_USER_CFG_8 = 2008,\n    CFG_USER_CFG_9 = 2009,\n    CFG_ARCADE_CFG_0 = 2100,\n    CFG_ARCADE_CFG_1 = 2101,\n    CFG_ARCADE_SCREEN_WIDTH = 2102,\n    CFG_ARCADE_SCREEN_HEIGHT = 2103,\n    // /pxtapp/hf2dbg.h\n    HF2DBG_H = 1,\n    // /pxtapp/jacdac/jdprotocol.h\n    JDSPI_MAGIC = 31437,\n    JDSPI_MAGIC_NOOP = 46029,\n    // /pxtapp/mixer---samd/melody.h\n    SW_TRIANGLE = 1,\n    SW_SAWTOOTH = 2,\n    SW_SINE = 3,\n    SW_NOISE = 5,\n    SW_SQUARE_10 = 11,\n    SW_SQUARE_50 = 15,\n    CODAL = 1,\n    MAX_SOUNDS = 5,\n    Waiting = 0,\n    Playing = 1,\n    Done = 2,\n    // /pxtapp/pins.h\n    BUTTON_ACTIVE_HIGH_PULL_DOWN = 17,\n    BUTTON_ACTIVE_HIGH_PULL_UP = 33,\n    BUTTON_ACTIVE_HIGH_PULL_NONE = 49,\n    BUTTON_ACTIVE_LOW_PULL_DOWN = 16,\n    BUTTON_ACTIVE_LOW_PULL_UP = 32,\n    BUTTON_ACTIVE_LOW_PULL_NONE = 48,\n    // /pxtapp/platform.h\n    PAGE_SIZE = 512,\n    BOOTLOADER_START = 0,\n    DEV_NUM_PINS = 64,\n    PXT_74HC165 = 1,\n    IMAGE_BITS = 4,\n    PA00 = 0,\n    PA01 = 1,\n    PA02 = 2,\n    PA03 = 3,\n    PA04 = 4,\n    PA05 = 5,\n    PA06 = 6,\n    PA07 = 7,\n    PA08 = 8,\n    PA09 = 9,\n    PA10 = 10,\n    PA11 = 11,\n    PA12 = 12,\n    PA13 = 13,\n    PA14 = 14,\n    PA15 = 15,\n    PA16 = 16,\n    PA17 = 17,\n    PA18 = 18,\n    PA19 = 19,\n    PA20 = 20,\n    PA21 = 21,\n    PA22 = 22,\n    PA23 = 23,\n    PA24 = 24,\n    PA25 = 25,\n    PA26 = 26,\n    PA27 = 27,\n    PA28 = 28,\n    PA29 = 29,\n    PA30 = 30,\n    PA31 = 31,\n    PB00 = 32,\n    PB01 = 33,\n    PB02 = 34,\n    PB03 = 35,\n    PB04 = 36,\n    PB05 = 37,\n    PB06 = 38,\n    PB07 = 39,\n    PB08 = 40,\n    PB09 = 41,\n    PB10 = 42,\n    PB11 = 43,\n    PB12 = 44,\n    PB13 = 45,\n    PB14 = 46,\n    PB15 = 47,\n    PB16 = 48,\n    PB17 = 49,\n    PB18 = 50,\n    PB19 = 51,\n    PB20 = 52,\n    PB21 = 53,\n    PB22 = 54,\n    PB23 = 55,\n    PB24 = 56,\n    PB25 = 57,\n    PB26 = 58,\n    PB27 = 59,\n    PB28 = 60,\n    PB29 = 61,\n    PB30 = 62,\n    PB31 = 63,\n    // /pxtapp/pxt.h\n    DEVICE_ID_BUTTON_SLIDE = 3000,\n    DEVICE_ID_MICROPHONE = 3001,\n    DEVICE_ID_FIRST_BUTTON = 4000,\n    DEVICE_ID_FIRST_TOUCHBUTTON = 4100,\n    PXT_INTERNAL_KEY_UP = 2050,\n    PXT_INTERNAL_KEY_DOWN = 2051,\n    // /pxtapp/pxtbase.h\n    PXT32 = 1,\n    PXT64 = 1,\n    PXT_REFCNT_FLASH = 65534,\n    VTABLE_MAGIC = 249,\n    Undefined = 0,\n    Boolean = 1,\n    Number = 2,\n    String = 3,\n    Object = 4,\n    Function = 5,\n    BoxedString = 1,\n    BoxedNumber = 2,\n    BoxedBuffer = 3,\n    RefAction = 4,\n    RefImage = 5,\n    RefCollection = 6,\n    RefRefLocal = 7,\n    RefMap = 8,\n    RefMImage = 9,\n    MMap = 10,\n    User0 = 16,\n    PXT_IOS_HEAP_ALLOC_BITS = 20,\n    IMAGE_HEADER_MAGIC = 135,\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    UInt32LE = 11,\n    UInt32BE = 12,\n    Float32LE = 13,\n    Float64LE = 14,\n    Float32BE = 15,\n    Float64BE = 16,\n    NUM_TRY_FRAME_REGS = 3,\n    GC = 0,\n    // /pxtapp/pxtconfig.h\n    PXT_UF2_FAMILY = 1427194976,\n    // /pxtapp/settings/Flash.h\n    DEVICE_FLASH_ERROR = 922,\n    // /pxtapp/settings/RAFFS.h\n    RAFFS_FOLLOWING_MASK = 32768,\n    RAFFS_FLASH_BUFFER_SIZE = 64,\n    // /pxtapp/uf2hid.h\n    UF2_HID_H = 1,\n}\n","dmac.cpp":"#include \"dmac.h\"\n\nnamespace pxt {\n\n#ifdef CODAL_DMAC\nSINGLETON(WDMAC);\n#endif\n\n}","dmac.h":"#ifndef __DMAC_H\n#define __DMAC_H\n\n#include \"pxt.h\"\n\nnamespace pxt {\n\n#ifdef CODAL_DMAC\nclass WDMAC {\n  public:\n    CODAL_DMAC dmac;\n\n    WDMAC() {}\n};\n\nWDMAC* getWDMAC();\n#endif\n\n}\n\n#endif","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum PulseValue {\n    //% block=high\n    High = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=low\n    Low = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    }\n\n\n    declare const enum PinEvent {\n    //% block=\"pulse high\"\n    PulseHigh = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=\"pulse low\"\n    PulseLow = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    //% block=\"rise\"\n    Rise = 2,  // DEVICE_PIN_EVT_RISE\n    //% block=\"fall\"\n    Fall = 3,  // DEVICE_PIN_EVT_FALL\n    }\n\n\n    declare const enum PinPullMode {\n    //% block=\"down\"\n    PullDown = 0,\n    //% block=\"up\"\n    PullUp = 1,\n    //% block=\"none\"\n    PullNone = 2,\n    }\n\n// Auto-generated. Do not edit. Really.\n","hf2.cpp":"#include \"pxt.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#ifndef USB_HANDOVER\n#define USB_HANDOVER 1\n#endif\n\n#if USB_HANDOVER\n#define UF2_DEFINE_HANDOVER 1\n#endif\n\n#include \"uf2format.h\"\n\nstatic void *stackCopy;\nstatic uint32_t stackSize;\n\n//#define LOG DMESG\n#define LOG(...) ((void)0)\n\nstatic volatile bool resume = false;\n\nusing namespace codal;\n\n#ifdef HF2_HID\nstatic const char hidDescriptor[] = {\n    0x06, 0x97, 0xFF, // usage page vendor 0x97 (usage 0xff97 0x0001)\n    0x09, 0x01,       // usage 1\n    0xA1, 0x01,       // collection - application\n    0x15, 0x00,       // logical min 0\n    0x26, 0xFF, 0x00, // logical max 255\n    0x75, 8,          // report size 8\n    0x95, 64,         // report count 64\n    0x09, 0x01,       // usage 1\n    0x81, 0x02,       // input: data, variable, absolute\n    0x95, 64,         // report count 64\n    0x09, 0x01,       // usage 1\n    0x91, 0x02,       // output: data, variable, absolute\n    0x95, 1,          // report count 1\n    0x09, 0x01,       // usage 1\n    0xB1, 0x02,       // feature: data, variable, absolute\n    0xC0,             // end\n};\n\nstatic const HIDReportDescriptor reportDesc = {\n    9,\n    0x21,                  // HID\n    0x100,                 // hidbcd 1.00\n    0x00,                  // country code\n    0x01,                  // num desc\n    0x22,                  // report desc type\n    sizeof(hidDescriptor), // size of 0x22\n};\n\nstatic const InterfaceInfo ifaceInfoHID = {\n    &reportDesc,\n    sizeof(reportDesc),\n    1,\n    {\n        2,    // numEndpoints\n        0x03, /// class code - HID\n        0x00, // subclass\n        0x00, // protocol\n        0x02, // string\n        0x00, // alt\n    },\n    {USB_EP_TYPE_INTERRUPT, 1},\n    {USB_EP_TYPE_INTERRUPT, 1},\n};\n#endif\n\nstatic const InterfaceInfo ifaceInfoEP = {\n    NULL,\n    0,\n    2,\n    {\n        2,    // numEndpoints\n        0xff, /// class code - vendor-specific\n        42,   // subclass\n        1,    // protocol\n        0x02, // string\n        0x00, // alt\n    },\n    {USB_EP_TYPE_BULK, 0},\n    {USB_EP_TYPE_BULK, 0},\n};\n\nint HF2::stdRequest(UsbEndpointIn &ctrl, USBSetup &setup) {\n#ifdef HF2_HID\n    if (!useHID)\n        return DEVICE_NOT_SUPPORTED;\n    if (setup.bRequest == USB_REQ_GET_DESCRIPTOR) {\n        if (setup.wValueH == 0x21) {\n            InterfaceDescriptor tmp;\n            fillInterfaceInfo(&tmp);\n            return ctrl.write(&tmp, sizeof(tmp));\n        } else if (setup.wValueH == 0x22) {\n            return ctrl.write(hidDescriptor, sizeof(hidDescriptor));\n        }\n    }\n#endif\n    return DEVICE_NOT_SUPPORTED;\n}\n\n#define HF2_FLAG_EVENT 0x01\n\nREAL_TIME_FUNC\nvoid HF2::sendBuffer(uint8_t flag, const void *data, unsigned size, uint32_t prepend) {\n    if (!CodalUSB::usbInstance->isInitialised())\n        return;\n\n#ifdef USB_EP_FLAG_ASYNC\n    // drop non-responses if too much stuff queued up\n    if (flag != HF2_FLAG_CMDPKT_LAST && pendingWriteSize > 1000)\n        return;\n#endif\n\n    if (flag == HF2_FLAG_EVENT)\n        flag = HF2_FLAG_CMDPKT_LAST;\n\n    if (prepend + 1)\n        size += 4;\n\n#ifdef USB_EP_FLAG_ASYNC\n    HF2_PendingWrite *e = (HF2_PendingWrite *)malloc(sizeof(HF2_PendingWrite) + size);\n    e->size = size;\n    e->flag = flag;\n    e->next = NULL;\n    uint8_t *dst = e->data;\n    if (prepend + 1) {\n        memcpy(dst, &prepend, 4);\n        dst += 4;\n        size -= 4;\n    }\n    memcpy(dst, data, size);\n\n    target_disable_irq();\n    auto p = this->pendingWrite;\n    if (!p)\n        this->pendingWrite = e;\n    else {\n        while (p->next)\n            p = p->next;\n        p->next = e;\n    }\n    this->pendingWriteSize += 16 + e->size;\n    target_enable_irq();\n\n    pokeSend();\n#else\n    uint32_t buf[64 / 4]; // aligned\n\n    target_disable_irq();\n    while (size > 0) {\n        memset(buf + 1, 0, 60);\n        int s = 63;\n        if (size <= 63) {\n            s = size;\n            buf[0] = flag;\n        } else {\n            buf[0] = flag == HF2_FLAG_CMDPKT_LAST ? HF2_FLAG_CMDPKT_BODY : flag;\n        }\n        buf[0] |= s;\n        uint8_t *dst = (uint8_t *)buf;\n        dst++;\n        if (prepend + 1) {\n            memcpy(dst, &prepend, 4);\n            prepend = -1;\n            dst += 4;\n            s -= 4;\n            size -= 4;\n        }\n        memcpy(dst, data, s);\n        data = (const uint8_t *)data + s;\n        size -= s;\n\n        in->write(buf, sizeof(buf));\n    }\n    target_enable_irq();\n#endif\n}\n\nconst InterfaceInfo *HF2::getInterfaceInfo() {\n#ifdef HF2_HID\n    if (useHID)\n        return &ifaceInfoHID;\n#endif\n    return &ifaceInfoEP;\n}\n\nint HF2::sendEvent(uint32_t evId, const void *data, int size) {\n    sendBuffer(HF2_FLAG_EVENT, data, size, evId);\n    return 0;\n}\n\nint HF2::sendSerial(const void *data, int size, int isError) {\n    if (!gotSomePacket)\n        return DEVICE_OK;\n\n    sendBuffer(isError ? HF2_FLAG_SERIAL_ERR : HF2_FLAG_SERIAL_OUT, data, size);\n\n    return 0;\n}\n\n// Receive HF2 message\n// Does not block. Will store intermediate data in pkt.\n// `serial` flag is cleared if we got a command message.\nint HF2::recv() {\n    uint8_t buf[64];\n\n    int len = out->read(buf, sizeof(buf));\n    // DMESG(\"HF2 read: %d\", len);\n\n    if (len <= 0)\n        return len;\n\n    uint8_t tag = buf[0];\n    // serial packets not allowed when in middle of command packet\n    usb_assert(pkt.size == 0 || !(tag & HF2_FLAG_SERIAL_OUT));\n    int size = tag & HF2_SIZE_MASK;\n    usb_assert(pkt.size + size <= (int)sizeof(pkt.buf));\n    memcpy(pkt.buf + pkt.size, buf + 1, size);\n    pkt.size += size;\n    tag &= HF2_FLAG_MASK;\n    if (tag != HF2_FLAG_CMDPKT_BODY) {\n        if (tag == HF2_FLAG_CMDPKT_LAST)\n            pkt.serial = 0;\n        else if (tag == HF2_FLAG_SERIAL_OUT)\n            pkt.serial = 1;\n        else\n            pkt.serial = 2;\n        int sz = pkt.size;\n        pkt.size = 0;\n        return sz;\n    }\n    return 0;\n}\n\nint HF2::sendResponse(int size) {\n    sendBuffer(HF2_FLAG_CMDPKT_LAST, pkt.buf, 4 + size);\n    return 0;\n}\n\nint HF2::sendResponseWithData(const void *data, int size) {\n    if (size <= (int)sizeof(pkt.buf) - 4) {\n        memcpy(pkt.resp.data8, data, size);\n        return sendResponse(size);\n    } else {\n        sendBuffer(HF2_FLAG_CMDPKT_LAST, data, size, pkt.resp.eventId);\n        return 0;\n    }\n}\n\nstatic void copy_words(void *dst0, const void *src0, uint32_t n_words) {\n    uint32_t *dst = (uint32_t *)dst0;\n    const uint32_t *src = (const uint32_t *)src0;\n    while (n_words--)\n        *dst++ = *src++;\n}\n\n#ifndef QUICK_BOOT\n#ifdef SAMD21\n#define DBL_TAP_PTR ((volatile uint32_t *)(HMCRAMC0_ADDR + HMCRAMC0_SIZE - 4))\n#endif\n#ifdef SAMD51\n#define DBL_TAP_PTR ((volatile uint32_t *)(HSRAM_ADDR + HSRAM_SIZE - 4))\n#endif\n#if defined(NRF52840) || defined(NRF52833)\n#define DBL_TAP_PTR ((volatile uint32_t *)0x20007F7C)\n#endif\n#ifdef DBL_TAP_PTR\n#define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef\n#define QUICK_BOOT(v) *DBL_TAP_PTR = v ? DBL_TAP_MAGIC_QUICK_BOOT : 0\n#endif\n#endif\n\nstatic HF2 *jdLogger;\nstatic void jdLog(const uint8_t *frame) {\n    jdLogger->sendEvent(HF2_EV_JDS_PACKET, frame, frame[2] + 12);\n}\n\nvoid HF2::pokeSend() {\n#ifdef USB_EP_FLAG_ASYNC\n    target_disable_irq();\n    while (pendingWrite && in->canWrite()) {\n        in->flags |= USB_EP_FLAG_ASYNC;\n\n        int size = pendingWrite->size - pendingWritePtr;\n        usb_assert(size > 0);\n        uint32_t buf[64 / 4] = {0};\n\n        int s = 63;\n        if (size <= 63) {\n            s = size;\n            buf[0] = pendingWrite->flag;\n        } else {\n            buf[0] = pendingWrite->flag == HF2_FLAG_CMDPKT_LAST ? HF2_FLAG_CMDPKT_BODY\n                                                                : pendingWrite->flag;\n        }\n        buf[0] |= s;\n        uint8_t *dst = (uint8_t *)buf;\n        dst++;\n        memcpy(dst, pendingWrite->data + pendingWritePtr, s);\n\n        int r = in->write(buf, sizeof(buf));\n        if (r == 0) {\n            if (s == size) {\n                pendingWritePtr = 0;\n                pendingWriteSize -= 16 + pendingWrite->size;\n                HF2_PendingWrite *n = pendingWrite->next;\n                free(pendingWrite);\n                pendingWrite = n;\n            } else {\n                pendingWritePtr += s;\n            }\n        }\n    }\n    target_enable_irq();\n#endif\n}\n\nint HF2::endpointRequest() {\n#ifdef USB_EP_FLAG_ASYNC\n    pokeSend();\n#endif\n\n    int sz = recv();\n\n    if (!sz)\n        return 0;\n\n    uint32_t tmp;\n\n    if (pkt.serial) {\n        // TODO raise some event?\n        return 0;\n    }\n\n    LOG(\"HF2 sz=%d CMD=%x\", sz, pkt.buf32[0]);\n\n    // one has to be careful dealing with these, as they share memory\n    HF2_Command *cmd = &pkt.cmd;\n    HF2_Response *resp = &pkt.resp;\n\n    uint32_t cmdId = cmd->command_id;\n    resp->tag = cmd->tag;\n    resp->status16 = HF2_STATUS_OK;\n\n#define checkDataSize(str, add) usb_assert(sz == 8 + (int)sizeof(cmd->str) + (int)(add))\n\n    lastExchange = current_time_ms();\n    gotSomePacket = true;\n\n    switch (cmdId) {\n    case HF2_CMD_INFO:\n        return sendResponseWithData(uf2_info(), strlen(uf2_info()));\n\n    case HF2_CMD_BININFO:\n        resp->bininfo.mode = HF2_MODE_USERSPACE;\n        resp->bininfo.flash_page_size = 0;\n        resp->bininfo.flash_num_pages = 0;\n        resp->bininfo.max_message_size = sizeof(pkt.buf);\n        resp->bininfo.uf2_family = PXT_UF2_FAMILY;\n        return sendResponse(sizeof(resp->bininfo));\n\n    case HF2_DBG_RESTART:\n        *HF2_DBG_MAGIC_PTR = HF2_DBG_MAGIC_START;\n        target_reset();\n        break;\n\n#ifdef QUICK_BOOT\n    case HF2_CMD_RESET_INTO_APP:\n        QUICK_BOOT(1);\n        NVIC_SystemReset();\n        break;\n    case HF2_CMD_RESET_INTO_BOOTLOADER:\n        QUICK_BOOT(0);\n        NVIC_SystemReset();\n        break;\n#else\n    case HF2_CMD_RESET_INTO_APP:\n        NVIC_SystemReset();\n        break;\n    // reset into bootloader not supported\n#endif\n\n#if USB_HANDOVER\n    case HF2_CMD_START_FLASH:\n        sendResponse(0);\n        hf2_handover(in->ep);\n        usb_assert(0); // should not be reached\n        break;\n#endif\n\n    case HF2_CMD_WRITE_WORDS:\n        checkDataSize(write_words, cmd->write_words.num_words << 2);\n        copy_words((void *)cmd->write_words.target_addr, cmd->write_words.words,\n                   cmd->write_words.num_words);\n        break;\n\n    case HF2_CMD_READ_WORDS:\n        checkDataSize(read_words, 0);\n        tmp = cmd->read_words.num_words;\n        usb_assert(tmp <= sizeof(pkt.buf) / 4 - 1);\n        copy_words(resp->data32, (void *)cmd->read_words.target_addr, tmp);\n        return sendResponse(tmp << 2);\n\n    case HF2_CMD_DMESG:\n#if DEVICE_DMESG_BUFFER_SIZE > 0\n        return sendResponseWithData(codalLogStore.buffer, codalLogStore.ptr);\n#else\n        break;\n#endif\n\n    case HF2_DBG_GET_GLOBAL_STATE: {\n        HF2_GLOBAL_STATE_Result gstate = {\n            .num_globals = (uint32_t)getNumGlobals(), //\n            .globals_addr = (uint32_t)globals,\n        };\n        return sendResponseWithData(&gstate, sizeof(gstate));\n    }\n\n    case HF2_DBG_RESUME:\n        globals[0] = (TValue)cmd->data32[0];\n        resume = true;\n        return sendResponse(0);\n\n    case HF2_DBG_GET_STACK:\n        return sendResponseWithData(stackCopy, stackSize);\n\n    case HF2_CMD_JDS_CONFIG:\n        if (cmd->data8[0]) {\n            jdLogger = this;\n            pxt::logJDFrame = jdLog;\n        } else {\n            pxt::logJDFrame = NULL;\n        }\n        return sendResponse(0);\n\n    case HF2_CMD_JDS_SEND:\n        if (pxt::sendJDFrame) {\n            pxt::sendJDFrame(cmd->data8);\n            return sendResponse(0);\n        } else {\n            resp->status16 = HF2_STATUS_INVALID_STATE;\n            return sendResponse(0);\n        }\n\n    default:\n        // command not understood\n        resp->status16 = HF2_STATUS_INVALID_CMD;\n        break;\n    }\n\n    return sendResponse(0);\n}\n\nHF2::HF2(HF2_Buffer &p) : gotSomePacket(false), ctrlWaiting(false), pkt(p), useHID(false) {\n    lastExchange = 0;\n#ifdef USB_EP_FLAG_ASYNC\n    pendingWrite = NULL;\n    pendingWriteSize = 0;\n    pendingWritePtr = 0;\n#endif\n}\n\nstatic const InterfaceInfo dummyIfaceInfo = {\n    NULL,\n    0,\n    0,\n    {\n        0,    // numEndpoints\n        0xff, /// class code - vendor-specific\n        0xff, // subclass\n        0xff, // protocol\n        0x00, // string\n        0x00, // alt\n    },\n    {0, 0},\n    {0, 0},\n};\n\nconst InterfaceInfo *DummyIface::getInterfaceInfo() {\n    return &dummyIfaceInfo;\n}\n\n//\n//\n// Debugger\n//\n//\n\nstruct ExceptionContext {\n    uint32_t excReturn; // 0xFFFFFFF9\n    uint32_t r0;\n    uint32_t r1;\n    uint32_t r2;\n    uint32_t r3;\n    uint32_t r12;\n    uint32_t lr;\n    uint32_t faultInstrAddr;\n    uint32_t psr;\n};\n\nstruct Paused_Data {\n    uint32_t pc;\n};\nstatic Paused_Data pausedData;\n\nvoid bkptPaused() {\n\n// waiting for https://github.com/lancaster-university/codal/pull/14\n#ifdef DEVICE_GROUP_ID_USER\n    // the loop below counts as \"system\" task, and we don't want to pause ourselves\n    fiber_set_group(DEVICE_GROUP_ID_SYSTEM);\n    // pause everyone else\n    fiber_pause_group(DEVICE_GROUP_ID_USER);\n#endif\n\n    while (!resume) {\n        // DMESG(\"BKPT\");\n        hf2.pkt.resp.eventId = HF2_EV_DBG_PAUSED;\n        hf2.sendResponseWithData(&pausedData, sizeof(pausedData));\n        // TODO use an event\n        for (int i = 0; i < 20; ++i) {\n            if (resume)\n                break;\n            fiber_sleep(50);\n        }\n    }\n\n    if (stackCopy) {\n        xfree(stackCopy);\n        stackCopy = NULL;\n    }\n\n#ifdef DEVICE_GROUP_ID_USER\n    fiber_resume_group(DEVICE_GROUP_ID_USER);\n    // go back to user mode\n    fiber_set_group(DEVICE_GROUP_ID_USER);\n#endif\n\n    resume = false;\n}\n\nextern \"C\" void handleHardFault(ExceptionContext *ectx) {\n    auto instr = (uint16_t *)ectx->faultInstrAddr;\n\n    DMESG(\"FLT %p\", instr);\n\n    if (ectx->faultInstrAddr & 0x80000000) {\n        ectx->faultInstrAddr &= ~0x80000000;\n        // switch to step-over mode\n        globals[0] = (TValue)3;\n        return;\n    }\n\n    DMESG(\"BB %p %p %p lr=%p r0=%p\", instr[-1], instr[0], instr[1], ectx->lr, ectx->r0);\n\n    if (instr[0] == 0x6840) {\n        // ldr r0, [r0, #4] -- entry breakpoint\n        ectx->faultInstrAddr += 2;\n        // we're being ask for step-over mode\n        if (ectx->r0 == 3) {\n            // switch to debugger-attached-no-stepping mode\n            globals[0] = (TValue)0;\n            ectx->lr |= 0x80000000;\n        }\n        return;\n    }\n\n    if (instr[0] == 0x6800) {\n        // ldr r0, [r0, #0]\n        ectx->lr = ectx->faultInstrAddr + 3; // next instruction + thumb mode\n        pausedData.pc = ectx->faultInstrAddr + 2;\n        void *ssp = (void *)(ectx + 1);\n        stackSize = DEVICE_STACK_BASE - (uint32_t)ssp;\n        if (stackCopy)\n            xfree(stackCopy);\n        stackCopy = xmalloc(stackSize);\n        memcpy(stackCopy, ssp, stackSize);\n        ectx->faultInstrAddr = ((uint32_t)(&bkptPaused) & (~1U));\n        return;\n    }\n\n    while (1) {\n    }\n}\n\nextern \"C\" void HardFault_Handler(void) {\n    asm(\"push {lr}; mov r0, sp; bl handleHardFault; pop {pc}\");\n}\n\n#endif","hf2.h":"#ifndef DEVICE_HF2_H\n#define DEVICE_HF2_H\n\n#if CONFIG_ENABLED(DEVICE_USB)\n\n#include \"HID.h\"\n#include \"uf2hid.h\"\n\n// 260 bytes needed for biggest JD packets (with overheads)\n#define HF2_BUF_SIZE 260\n\ntypedef struct {\n    uint16_t size;\n    uint8_t serial;\n    union {\n        uint8_t buf[HF2_BUF_SIZE];\n        uint32_t buf32[HF2_BUF_SIZE / 4];\n        uint16_t buf16[HF2_BUF_SIZE / 2];\n        HF2_Command cmd;\n        HF2_Response resp;\n    };\n} HF2_Buffer;\n\nstruct HF2_PendingWrite {\n    HF2_PendingWrite *next;\n    uint16_t size;\n    uint8_t flag;\n    uint8_t _reserved;\n    uint8_t data[0];\n};\n\nclass HF2 : public CodalUSBInterface {\n    bool gotSomePacket;\n    bool ctrlWaiting;\n    uint32_t lastExchange;\n\n#ifdef USB_EP_FLAG_ASYNC\n    HF2_PendingWrite *pendingWrite;\n    int pendingWriteSize;\n    int pendingWritePtr;\n#endif\n\n  public:\n    HF2_Buffer &pkt;\n\n    bool useHID;\n\n    int sendResponse(int size);\n    int recv();\n    int sendResponseWithData(const void *data, int size);\n    int sendEvent(uint32_t evId, const void *data, int size);\n    void sendBuffer(uint8_t flag, const void *data, unsigned size, uint32_t prepend = -1);\n    void pokeSend();\n\n    HF2(HF2_Buffer &pkt);\n    virtual int endpointRequest();\n    virtual int stdRequest(UsbEndpointIn &ctrl, USBSetup &setup);\n    virtual const InterfaceInfo *getInterfaceInfo();\n    int sendSerial(const void *data, int size, int isError = 0);\n\n    virtual bool enableWebUSB() { return !useHID; }\n};\n\nclass DummyIface : public CodalUSBInterface {\n  public:\n    virtual const InterfaceInfo *getInterfaceInfo();\n};\n\n#endif\n\n#endif\n","hf2dbg.h":"#ifndef HF2DBG_H\n#define HF2DBG_H 1\n\n// we use a location at the top of the stack to store a magic value\n// which causes us to stop at the very first break point in the program\n#define HF2_DBG_MAGIC_PTR ((uint32_t *)(DEVICE_STACK_BASE - (DEVICE_STACK_SIZE - 4)))\n#define HF2_DBG_MAGIC_START 0xf0ebac7f\n\n#define HF2_DBG_GET_GLOBAL_STATE 0x53fc66e0\nstruct HF2_GLOBAL_STATE_Result {\n    uint32_t num_globals;\n    uint32_t globals_addr;\n};\n\n#define HF2_DBG_RESTART 0x1120bd93\n#define HF2_DBG_RESUME 0x27a55931\n#define HF2_EV_DBG_PAUSED 0x3692f9fd\n#define HF2_DBG_GET_STACK 0x70901510\n\n#endif\n","i2c.cpp":"#include \"pxt.h\"\n#include \"ErrorNo.h\"\n#include \"CodalDmesg.h\"\n#include \"configkeys.h\"\n\n#ifdef CODAL_I2C\n\nnamespace pins {\n\nclass CodalI2CProxy {\nprivate:\n  DevicePin* sda;\n  DevicePin* scl;\n  CODAL_I2C i2c;\npublic:\n  CodalI2CProxy* next;\npublic:\n  CodalI2CProxy(DevicePin* _sda, DevicePin* _scl)\n    : sda(_sda)\n    , scl(_scl)\n    , i2c(*_sda, *_scl) \n    , next(NULL)\n  {\n\n  }\n\n  CODAL_I2C* getI2C() {\n    return &(this->i2c);\n  }\n  \n  bool matchPins(DevicePin* sda, DevicePin* scl) {\n      return this->sda == sda && this->scl == scl;\n  }\n\n  Buffer readBuffer(int address, int size, bool repeat = false)\n  {\n    Buffer buf = mkBuffer(NULL, size);\n    registerGCObj(buf);\n    int status = this->i2c.read(address << 1, buf->data, size, repeat);\n    unregisterGCObj(buf);\n    if (status != ErrorCode::DEVICE_OK) {\n      buf = 0;\n    }\n    return buf;\n  }\n\n  int writeBuffer(int address, Buffer buf, bool repeat = false)\n  {\n    return this->i2c.write(address << 1, buf->data, buf->length, repeat);\n  }\n};\n\n}\n\nnamespace I2CMethods {\n/**\n  * Read `size` bytes from a 7-bit I2C `address`.\n  */\n//%\nBuffer readBuffer(I2C_ i2c, int address, int size, bool repeat = false)\n{\n  return i2c->readBuffer(address, size, repeat);\n}\n\n/**\n  * Write bytes to a 7-bit I2C `address`.\n  */\n//%\nint writeBuffer(I2C_ i2c, int address, Buffer buf, bool repeat = false)\n{\n  return i2c->writeBuffer(address, buf, repeat);\n}\n\n}\n\nnamespace pins {\n\nstatic I2C_ i2cs(NULL);\n/**\n* Opens a Serial communication driver\n*/\n//% help=pins/create-i2c\n//% parts=i2c\nI2C_ createI2C(DigitalInOutPin sda, DigitalInOutPin scl) {\n  // pick up defaults\n  if (!sda || !scl) {\n    DMESG(\"i2c: lookup default pins\");\n    sda = LOOKUP_PIN(SDA);\n    scl = LOOKUP_PIN(SCL);\n  }\n\n  // lookup existing devices\n  auto dev = i2cs;\n  while(dev) {\n    if (dev->matchPins(sda, scl)) {\n      DMESG(\"i2c: found existing i2c\");\n      return dev;\n    }\n    dev = dev->next;\n  }\n\n  // allocate new one\n  DMESG(\"i2c: mounting on new device\");\n  auto ser = new CodalI2CProxy(sda, scl);\n  // push in list\n  ser->next = i2cs;\n  i2cs = ser;\n  return ser;\n}\n\n}\n\nnamespace pxt {\n  CODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl) {\n    auto i2c = pins::createI2C(sda, scl);\n    return i2c->getI2C();\n  }\n}\n\n#endif","i2c.ts":"namespace pins {\n    /**\n     * Read one number from an I2C address.\n     */\n    //% help=pins/i2c-read-number weight=5 group=\"i2c\" inlineInputMode=\"external\"\n    //% blockId=pins_i2c_readnumber block=\"i2c read number at address %address|of format %format|repeated %repeated\"\n    export function i2cReadNumber(address: number, format: NumberFormat, repeated?: boolean): number {\n        const buf = pins.i2cReadBuffer(address, pins.sizeOf(format), repeated)\n        if (!buf)\n            return undefined\n        return buf.getNumber(format, 0)\n    }\n\n    /**\n     * Write one number to an I2C address.\n     */\n    //% help=pins/i2c-write-number weight=4 group=\"i2c\"\n    //% blockId=i2c_writenumber block=\"i2c write number|at address %address|with value %value|of format %format|repeated %repeated\"\n    export function i2cWriteNumber(address: number, value: number, format?: NumberFormat, repeated?: boolean): void {\n        if (format == undefined)\n            format = NumberFormat.UInt8LE;\n        const buf = control.createBuffer(pins.sizeOf(format))\n        buf.setNumber(format, 0, value)\n        pins.i2cWriteBuffer(address, buf, repeated)\n    }\n\n    /**\n     * Write a value in a I2C register.\n     * @param address I2c address of the device\n     * @param register register index\n     * @param value value to write\n     * @param valueFormat format of the value, default is UInt8LE\n     */\n    //% weight=3 group=\"i2c\"\n    //% help=pins/i2c-write-register\n    //% blockId=i2c_writereg block=\"i2c write register|at address $address|at register $register|value $value\"\n    export function i2cWriteRegister(address: number, register: number, value: number, valueFormat?: NumberFormat): void {\n        if (valueFormat === undefined)\n            valueFormat = NumberFormat.UInt8LE;\n        const valueSize = pins.sizeOf(valueFormat);\n        const buf = control.createBuffer(1 + valueSize);\n        buf.setNumber(NumberFormat.UInt8LE, 0, register);\n        buf.setNumber(valueFormat, 1, value);\n        pins.i2cWriteBuffer(address, buf);\n    }\n\n    /**\n     * Read the value from a I2C register.\n     * @param address I2c address of the device\n     * @param register register index\n     * @param valueFormat format of the value, default is UInt8LE\n     */\n    //% weight=3 group=\"i2c\"\n    //% help=pins/i2c-read-register\n    //% blockId=i2c_readreg block=\"i2c read register|at address $address|at register $register\"\n    export function i2cReadRegister(address: number, register: number, valueFormat?: NumberFormat): number {\n        if (valueFormat === undefined)\n            valueFormat = NumberFormat.UInt8LE;\n        pins.i2cWriteNumber(address, register, NumberFormat.UInt8LE);\n        return pins.i2cReadNumber(address, valueFormat);\n    }\n\n    /**\n     * Read `size` bytes from a 7-bit I2C `address`.\n     */\n    //%\n    export function i2cReadBuffer(address: number, size: number, repeat: boolean = false): Buffer {\n        return pins.i2c().readBuffer(address, size, repeat);\n    }\n\n    /**\n     * Write bytes to a 7-bit I2C `address`.\n     */\n    //%\n    export function i2cWriteBuffer(address: number, buf: Buffer, repeat: boolean = false): number {\n        return pins.i2c().writeBuffer(address, buf, repeat);\n    }\n\n    let _i2c: I2C;\n    /**\n     * Gets the default I2C bus\n     */\n    //%\n    export function i2c(): I2C {\n        if (!_i2c) {\n            const sda = pins.pinByCfg(DAL.CFG_PIN_SDA);\n            const scl = pins.pinByCfg(DAL.CFG_PIN_SCL);\n            _i2c = pins.createI2C(sda, scl);    \n        }\n        return _i2c;        \n    }\n\n    export class I2CDevice {\n        public address: number;\n        public bus: I2C;\n        private _hasError: boolean;\n        constructor(address: number, bus?: I2C) {\n            this.address = address;\n            this.bus = bus || i2c();\n        }\n        public readInto(buf: Buffer, repeat = false, start = 0, end: number = null) {\n            if (end === null)\n                end = buf.length\n            if (start >= end)\n                return\n            let res = this.bus.readBuffer(this.address, end - start, repeat)\n            if (!res) {\n                this._hasError = true\n                return\n            }\n            buf.write(start, res)\n        }\n        public write(buf: Buffer, repeat = false) {\n            let res = this.bus.writeBuffer(this.address, buf, repeat)\n            if (res) {\n                this._hasError = true\n            }\n        }\n        public begin(): I2CDevice {\n            this._hasError = false;\n            return this;\n        }\n        public end() {\n        }\n        public ok() {\n            return !this._hasError\n        }\n\n        public transfer(command: Buffer, response: Buffer, responseStart?: number, responseEnd?: number) {\n            this.begin();\n            if (command)\n                this.write(command);\n            if (response)\n                this.readInto(response, false, responseStart, responseEnd);\n            this.end();\n        }    \n    }\n}\n","keyvaluestorage.cpp":"#include \"pxt.h\"\n#include \"KeyValueStorage.h\"\n\nnamespace pxt {\n\nclass WKeyValueStorage {\n#ifdef CODAL_NVMCONTROLLER\n    CODAL_NVMCONTROLLER controller;\n#else\n    NVMController controller;\n#endif\n    KeyValueStorage storage;\n  public:\n\n    WKeyValueStorage()\n    : controller()\n    , storage(controller) {\n    }\n\n    bool isSupported() {\n#ifdef CODAL_NVMCONTROLLER\n      return true;\n#else\n      return false;\n#endif\n    }\n\n    int put(String key, Buffer data) {\n#ifdef CODAL_NVMCONTROLLER\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        return storage.put(mkey, data->data, data->length);\n#else\n        return -1;\n#endif\n    }\n\n    Buffer get(String key) {\n#ifdef CODAL_NVMCONTROLLER\n        Buffer buf = NULL;\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        auto entry = storage.get(mkey);\n        if (entry) {\n          buf = mkBuffer(entry->value, sizeof(entry->value));\n          free(entry);\n        }\n        return buf;\n#else\n        return NULL;\n#endif\n    }\n\n    void remove(String key) {\n#ifdef CODAL_NVMCONTROLLER\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        storage.remove(mkey);\n#endif\n    }\n\n    void clear() {\n#ifdef CODAL_NVMCONTROLLER\n        storage.wipe();\n#endif\n    }\n};\nSINGLETON(WKeyValueStorage);\n\n}\n\nnamespace configStorage {\n  /**\n  * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n  * @param key the identifier (max 16 characters)\n  * @param value the data (max 32 characters)\n  */\n  //%\n  void setBuffer(String key, Buffer value) {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->put(key, value);\n  }\n\n  /**\n  * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n  * @param key the identifier (max 16 characters)\n  */\n  //%\n  Buffer getBuffer(String key) {\n    auto kvm = pxt::getWKeyValueStorage();\n    return kvm->get(key);\n  }\n\n  /**\n  * Removes the key from local storage\n  * @param key the identifier (max 16 characters)\n  */\n  //%\n  void removeItem(String key) {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->remove(key);\n  }\n\n  /**\n  * Clears the local storage\n  */\n  //%\n  void clear() {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->clear();\n  }\n}\n","keyvaluestorage.ts":"namespace configStorage {\n    /**\n     * Stores the value at the key entry\n     * @param key identifier of the key (max 16 characters)\n     * @param value identifier of the value (max 32 characters)\n     */\n    export function setItem(key: string, value: string) {\n        if (value == null)\n            configStorage.removeItem(key);\n        else\n        {\n            let idx = 0;\n            let buf = control.createBuffer(value.length + 1);\n            buf[idx++] = value.length;\n            let valBuf = control.createBufferFromUTF8(value);\n\n            for (let i = 0; i < valBuf.length; i++)\n                buf[idx++] = valBuf[i];\n\n            configStorage.setBuffer(key, buf);\n        }\n    }\n\n    /**\n     * Retrieves the value at the key entry\n     * @param key identifier of the key (max 16 characters)\n     */\n    export function getItem(key: string): string {\n        const buf = configStorage.getBuffer(key);\n\n        if (!buf)\n            return undefined;\n\n        let idx = 0;\n        let count = buf[idx++];\n        const retBuf = control.createBuffer(count);\n\n        for (let i = 0; i < count; i++)\n            retBuf[i] = buf[idx++];\n\n        return retBuf.toString();\n    }\n}\n","leveldetector.ts":"namespace pins {\n    export class LevelDetector {\n        public id: number;\n        public min: number;\n        public max: number;\n        public lowThreshold: number;\n        public highThreshold: number;\n        private transition: number;\n        private transitionMs: number;\n        private _level: number;\n        private _state: number;\n        public onHigh: () => void;\n        public onLow: () => void;\n        public onNeutral: () => void;\n        public transitionWindow: number;\n        // minimum duration (ms) between events\n        public transitionInterval: number;\n\n        static LEVEL_THRESHOLD_NEUTRAL = 0;\n\n        constructor(id: number,\n            min: number, max: number,\n            lowThreshold: number, highThreshold: number) {\n            this.id = id;\n            this.min = min;\n            this.max = max;\n            this.lowThreshold = lowThreshold;\n            this.highThreshold = highThreshold;\n            this.transitionWindow = 4;\n            this.transitionInterval = 0;\n\n            this.onHigh = () => control.raiseEvent(this.id, DAL.LEVEL_THRESHOLD_HIGH);\n            this.onLow = () => control.raiseEvent(this.id, DAL.LEVEL_THRESHOLD_LOW);\n            this.onNeutral = undefined;\n\n            this.reset();\n        }\n\n        reset() {\n            this.transition = 0;\n            this.transitionMs = 0;\n            this._level = Math.ceil((this.highThreshold - this.lowThreshold) / 2);\n            this._state = LevelDetector.LEVEL_THRESHOLD_NEUTRAL;\n        }\n\n        get level(): number {\n            return this._level;\n        }\n\n        set level(level: number) {\n            this._level = this.clampValue(level);\n\n            if (this._level >= this.highThreshold) {\n                this.setState(DAL.LEVEL_THRESHOLD_HIGH);\n            }\n            else if (this._level <= this.lowThreshold) {\n                this.setState(DAL.LEVEL_THRESHOLD_LOW);\n            }\n            else {\n                this.setState(LevelDetector.LEVEL_THRESHOLD_NEUTRAL);\n            }\n        }\n\n        public setLowThreshold(value: number) {\n            this.lowThreshold = this.clampValue(value);\n            this.reset();\n        }\n\n        public setHighThreshold(value: number) {\n            this.highThreshold = this.clampValue(value);\n            this.reset();\n        }\n\n        private clampValue(value: number) {\n            if (value < this.min) {\n                return this.min;\n            }\n            else if (value > this.max) {\n                return this.max;\n            }\n            return value;\n        }\n\n        private setState(state: number) {\n            // not enough samples to change\n            if (this._state === state \n                || (this.transition++ < this.transitionWindow)\n                || (control.millis() - this.transitionMs) < this.transitionInterval) {\n                return;\n            }\n\n            this.transition = 0;\n            this.transitionMs = control.millis();\n            this._state = state;\n            switch (state) {\n                case DAL.LEVEL_THRESHOLD_HIGH:\n                    if (this.onHigh) this.onHigh();\n                    break;\n                case DAL.LEVEL_THRESHOLD_LOW:\n                    if (this.onLow) this.onLow();\n                    break;\n                case LevelDetector.LEVEL_THRESHOLD_NEUTRAL:\n                    if (this.onNeutral) this.onNeutral();\n                    break;\n            }\n        }\n    }\n}","light.cpp":"#include \"light.h\"\n\n// WS2812B timings, datasheet v1\n// 0 - 0.25-0.55us hi 0.70-1.00us low\n// 1 - 0.65-0.95us hi 0.30-0.60us low\n// datasheet v5\n// 0 - 0.22-0.38us hi 0.58-1.00us low 1-3\n// 1 - 0.58-1.00us hi 0.58-1.00us low 3-2\n\n#define SPI_SUPPORTED 1\n\n#if defined(NRF52_SERIES)\n#define BIT_EXPANSION 5\n#define SPI_FREQ 4000000\n#else\n#define BIT_EXPANSION 3\n#define SPI_FREQ 2400000\n#endif\n\n#if defined(SAMD21) || defined(SAMD51) || defined(STM32F4) || defined(NRF52_SERIES)\n#include \"neopixel.h\"\n#define BITBANG_SUPPORTED 1\n#else\n#define BITBANG_SUPPORTED 0\n#endif\n\n#define NEOPIXEL_MIN_LENGTH_FOR_SPI 24\n#define DOTSTAR_MIN_LENGTH_FOR_SPI 24\n\n#define LIGHTMODE_RGB 1\n#define LIGHTMODE_RGBW 2\n#define LIGHTMODE_RGB_RGB 3\n#define LIGHTMODE_DOTSTAR 4\n\nnamespace light {\nbool isValidMOSIPin(DigitalInOutPin pin) {\n    if (!pin)\n        return false;\n\n#if SAMD51\n    return ZSPI::isValidMOSIPin(*pin);\n#elif defined(NRF52_SERIES)\n    return true;\n#else\n    // TODO: support for SPI neopixels\n    // default SPI pins supported for now\n    return pin == LOOKUP_PIN(MOSI);\n#endif\n}\n\n// SPI\nvoid spiNeopixelSendBuffer(DevicePin *pin, const uint8_t *data, unsigned size) {\n    int32_t iptr = 0, optr = 120;\n    uint32_t len = optr + size * BIT_EXPANSION + 120;\n    uint8_t *expBuf = new uint8_t[len];\n    memset(expBuf, 0, len);\n    uint8_t imask = 0x80;\n    uint8_t omask = 0x80;\n\n#define WR(k)                                                                                      \\\n    if (k)                                                                                         \\\n        expBuf[optr] |= omask;                                                                     \\\n    omask >>= 1;                                                                                   \\\n    if (!omask) {                                                                                  \\\n        omask = 0x80;                                                                              \\\n        optr++;                                                                                    \\\n    }\n\n    while (iptr < (int)size) {\n#if BIT_EXPANSION == 3\n        WR(1);\n        WR(data[iptr] & imask);\n        WR(0);\n#elif BIT_EXPANSION == 5\n        WR(1);\n        if (data[iptr] & imask) {\n            WR(1);\n            WR(1);\n        } else {\n            WR(0);\n        }\n        WR(0);\n        WR(0);\n#else\n#error \"invalid BIT_EXPANSION\"\n#endif\n\n        imask >>= 1;\n        if (!imask) {\n            imask = 0x80;\n            iptr++;\n        }\n    }\n\n    auto spi = pxt::getSPI(pin, NULL, NULL);\n    spi->setFrequency(SPI_FREQ);\n    spi->transfer(expBuf, len, NULL, 0);\n    delete expBuf;\n}\n\nvoid neopixelSendData(DevicePin *pin, int mode, const uint8_t *data, unsigned length) {\n    if (!pin || !length)\n        return;\n\n#if BITBANG_SUPPORTED\n    if (SPI_SUPPORTED && length > NEOPIXEL_MIN_LENGTH_FOR_SPI && isValidMOSIPin(pin))\n        spiNeopixelSendBuffer(pin, data, length);\n    else\n        neopixel_send_buffer(*pin, data, length);\n#else\n    if (isValidMOSIPin(pin)) {\n        spiNeopixelSendBuffer(pin, data, length);\n    }\n#endif\n}\n\nvoid bitBangDotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                            unsigned length) {\n    // first frame of zeroes\n    data->setDigitalValue(0);\n    for (unsigned i = 0; i < 32; ++i) {\n        clk->setDigitalValue(1);\n        clk->setDigitalValue(0);\n    }\n\n    // data stream\n    for (unsigned i = 0; i < length; ++i) {\n        auto x = buf[i];\n        for (uint8_t j = 0x80; j != 0; j >>= 1) {\n            data->setDigitalValue(x & j ? 1 : 0);\n            clk->setDigitalValue(1);\n            clk->setDigitalValue(0);\n        }\n    }\n    // https://cpldcpu.wordpress.com/2016/12/13/sk9822-a-clone-of-the-apa102/\n    // reset frame\n    // data->setDigitalValue(0);\n    // for (unsigned i = 0; i < 32 ; ++i) {\n    //    clk->setDigitalValue(1);\n    //    clk->setDigitalValue(0);\n    //}\n\n    // https://cpldcpu.wordpress.com/2014/11/30/understanding-the-apa102-superled/\n    data->setDigitalValue(1);\n    unsigned n = 32;\n    for (unsigned i = 0; i < n; ++i) {\n        clk->setDigitalValue(1);\n        clk->setDigitalValue(0);\n    }\n}\n\nstatic uint8_t ZERO_FRAME[4];\nstatic uint8_t ONE_FRAME[] = {1, 1, 1, 1};\nvoid spiDotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                        unsigned length) {\n    auto spi = pxt::getSPI(data, NULL, clk);\n\n    spi->transfer(ZERO_FRAME, sizeof(ZERO_FRAME), NULL, 0); // initial frame\n    spi->transfer(buf, length, NULL, 0);\n    spi->transfer(ZERO_FRAME, sizeof(ZERO_FRAME), NULL, 0); // reset frame\n    for (unsigned i = 0; i < (length >> 3); i += 32)\n        spi->transfer(ONE_FRAME, sizeof(ONE_FRAME), NULL, 0); // final frame\n}\n\nvoid dotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                     unsigned length) {\n    if (!data || !clk || !buf || !length)\n        return;\n\n    if (length > DOTSTAR_MIN_LENGTH_FOR_SPI && isValidMOSIPin(data))\n        spiDotStarSendData(data, clk, mode, buf, length);\n    else\n        bitBangDotStarSendData(data, clk, mode, buf, length);\n}\n\nvoid sendBuffer(DevicePin *data, DevicePin *clk, int mode, Buffer buf) {\n    if (!data || !buf || !buf->length)\n        return;\n\n    if (mode == LIGHTMODE_DOTSTAR)\n        light::dotStarSendData(data, clk, mode, buf->data, buf->length);\n    else\n        light::neopixelSendData(data, mode, buf->data, buf->length);\n}\n\nvoid clear() {\n    auto neopix = LOOKUP_PIN(NEOPIXEL);\n    auto neonum = getConfig(CFG_NUM_NEOPIXELS, 0);\n    if (neopix && neonum >= 0) {\n        auto n = 3 * neonum;\n        uint8_t off[n];\n        memset(off, 0, sizeof(off));\n        light::neopixelSendData(neopix, 0x100, off, sizeof(off));\n    }\n\n    auto data = LOOKUP_PIN(DOTSTAR_DATA);\n    auto clk = LOOKUP_PIN(DOTSTAR_CLOCK);\n    auto dsnum = getConfig(CFG_NUM_DOTSTARS, 0);\n    if (data && clk && dsnum > 0) {\n        auto n = 4 * dsnum;\n        uint8_t off[n];\n        memset(off, 0, sizeof(off));\n        for (int i = 0; i < n; i += 4)\n            off[i] = 0xe0;\n        bitBangDotStarSendData(data, clk, 0x100, off, sizeof(off));\n    }\n}\n\n} // namespace light\n","light.h":"#ifndef __PXT_LIGHT_H\n#define __PXT_LIGHT_H\n\n#include \"pxt.h\"\n\nnamespace light {\n    /**\n    * Clear onboard neopixels\n    */\n    void clear();\n\n    /**\n    * Send a programmable light buffer to the specified digital pin\n    * @param data The pin that the lights are connected to\n    * @param clk the clock line if any\n    * @param mode the color encoding mode\n    * @param buf The buffer to send to the pin\n    */\n    //%\n    void sendBuffer(DigitalInOutPin data, DigitalInOutPin clk, int mode, Buffer buf);\n\n    void neopixelSendData(DevicePin* pin, int mode, const uint8_t* data, unsigned length);\n}\n\n#endif","ns.ts":"/**\n * Events and data from sensors.\n */\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\n//% groups='[\"other\", \"More\"]'\nnamespace input {\n}\n\n/**\n * Servos\n */\n//% color=\"#03AA74\" weight=88 icon=\"\\uf021\"\nnamespace servos {\n\n}\n\n/**\n * A Joint Asynchronous Communications, Device Agnostic Control.\n */\n//% color=\"#E79251\" weight=1 icon=\"\\uf185\"\n//% groups='[\"Broadcast\", \"Console\", \"Control\"]'\n//% blockGap=8\nnamespace jacdac {\n\n}","pins.cpp":"#include \"pxt.h\"\n\nnamespace pxt {\nstatic DevicePin **pinPtrs;\nstatic uint8_t numPinPtrs;\nstatic uint8_t pinPos[DEV_NUM_PINS];\n\n//%\nDevicePin *getPin(int id) {\n\n    id &= CFG_PIN_NAME_MSK;\n\n    if (id >= DEV_NUM_PINS)\n        soft_panic(PANIC_NO_SUCH_PIN);\n\n    // we could use lookupComponent() here - it would be slightly slower\n\n    int ptr = pinPos[id];\n    if (ptr == 0) {\n        pinPtrs = (DevicePin **)realloc(pinPtrs, (numPinPtrs + 1) * sizeof(void *));\n        bool isAnalog = IS_ANALOG_PIN(id);\n        // GCTODO\n        pinPtrs[numPinPtrs++] =\n            new DevicePin(DEVICE_ID_IO_P0 + id, (PinName)id,\n                          isAnalog ? PIN_CAPABILITY_AD : PIN_CAPABILITY_DIGITAL);\n        ptr = numPinPtrs;\n        pinPos[id] = ptr;\n    }\n    return pinPtrs[ptr - 1];\n}\n\n//%\nDevicePin *getPinCfg(int key) {\n    int p = getConfig(key, -1);\n    if (p == -1)\n        DMESG(\"no pin cfg: %d\", key);\n    return getPin(p);\n}\n\nvoid linkPin(int from, int to) {\n    if (from < 0 || from >= DEV_NUM_PINS)\n        soft_panic(PANIC_NO_SUCH_PIN);\n    getPin(to);\n    pinPos[from] = pinPos[to];\n}\n\n//%\nDevicePin *lookupPin(int pinName) {\n    if (pinName < 0 || pinName == 0xff)\n        return NULL;\n    pinName &= CFG_PIN_NAME_MSK;\n    return getPin(pinName);\n}\n\n//%\nDevicePin *lookupPinCfg(int key) {\n    return lookupPin(getConfig(key));\n}\n\nCodalComponent *lookupComponent(int id) {\n    for (int i = 0; i < DEVICE_COMPONENT_COUNT; ++i) {\n        if (CodalComponent::components[i] && CodalComponent::components[i]->id == id)\n            return CodalComponent::components[i];\n    }\n    return NULL;\n}\n\n} // namespace pxt\n\nnamespace pins {\n/**\n* Get a pin by configuration id (DAL.CFG_PIN...)\n*/\n//%\nDigitalInOutPin pinByCfg(int key) {\n    return pxt::lookupPinCfg(key);\n}\n\n/**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n//%\nBuffer createBuffer(int size) {\n    return mkBuffer(NULL, size);\n}\n\n/**\n * Get the duration of the last pulse in microseconds. This function should be called from a\n * ``onPulsed`` handler.\n */\n//% help=pins/pulse-duration blockGap=8\n//% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n//% weight=19\nint pulseDuration() {\n    return pxt::lastEvent.timestamp;\n}\n} // namespace pins\n","pins.h":"#ifndef __PXT_PINS_H\n#define __PXT_PINS_H\n\n#define BUTTON_ACTIVE_HIGH_PULL_DOWN (ACTIVE_HIGH | 0x10)\n#define BUTTON_ACTIVE_HIGH_PULL_UP (ACTIVE_HIGH | 0x20)\n#define BUTTON_ACTIVE_HIGH_PULL_NONE (ACTIVE_HIGH | 0x30)\n#define BUTTON_ACTIVE_LOW_PULL_DOWN (ACTIVE_LOW | 0x10)\n#define BUTTON_ACTIVE_LOW_PULL_UP (ACTIVE_LOW | 0x20)\n#define BUTTON_ACTIVE_LOW_PULL_NONE (ACTIVE_LOW | 0x30)\n\n#define PIN(name) ((PinName)pxt::getConfig(CFG_PIN_##name, -1))\n#define LOOKUP_PIN(name) pxt::lookupPin(PIN(name))\n\n// these can be overridden in platform.h\n#ifndef CODAL_PIN\n#define CODAL_PIN CODAL_MBED::Pin\n#endif\n\n#ifndef CODAL_TIMER\n#define CODAL_TIMER CODAL_MBED::Timer\n#endif\n\n#ifndef CODAL_SPI\n#define CODAL_SPI CODAL_MBED::SPI\n#endif\n\n#ifndef CODAL_SERIAL\n#define CODAL_SERIAL CODAL_MBED::Serial\n#endif\n\n#ifndef IS_ANALOG_PIN\n#define IS_ANALOG_PIN(id) ((DEV_ANALOG_PINS >> (id)) & 1)\n#endif\n\ntypedef CODAL_PIN DevicePin;\n\ntypedef DevicePin *DigitalInOutPin;\ntypedef DevicePin *AnalogInOutPin;\ntypedef DevicePin *AnalogInPin;\ntypedef DevicePin *AnalogOutPin;\ntypedef DevicePin *PwmPin;\ntypedef DevicePin *PwmOnlyPin;\ntypedef Button *Button_;\n\nnamespace pxt {\nDevicePin *getPin(int id);\nDevicePin *getPinCfg(int key);\nDevicePin *lookupPin(int pinName);\nDevicePin *lookupPinCfg(int key);\nvoid linkPin(int from, int to);\nCodalComponent *lookupComponent(int id);\n}\n\n#define PINOP(op) name->op\n\n#endif\n","pins.ts":"//% noRefCounting fixedInstances\ninterface DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogInPin extends DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogOutPin extends DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogInOutPin extends AnalogInPin, AnalogOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface PwmOnlyPin extends DigitalInOutPin, AnalogOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface PwmPin extends PwmOnlyPin, AnalogInOutPin {\n}\n\n/**\n * Control currents in Pins for analog/digital signals, servos, i2c, ...\n */\n//% color=#A80000 weight=85 icon=\"\\uf140\" advanced=true\n//% groups='[\"other\", \"Servo\", \"i2c\"]'\nnamespace pins {\n}","pinsAnalog.cpp":"#include \"pxt.h\"\n\nnamespace AnalogInPinMethods {\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 weight=53\n//% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nint analogRead(AnalogInPin name) {\n    return PINOP(getAnalogValue());\n}\n}\n\nnamespace AnalogOutPinMethods {\nvoid analogWrite(AnalogOutPin name, int value) __attribute__ ((weak));\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 weight=52\n//% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\n//% value.min=0 value.max=1023\nvoid analogWrite(AnalogOutPin name, int value) {\n    PINOP(setAnalogValue(value));\n}\n}","pinsDigital.cpp":"#include \"pxt.h\"\n\nenum class PulseValue {\n    //% block=high\n    High = DEVICE_PIN_EVT_PULSE_HI,\n    //% block=low\n    Low = DEVICE_PIN_EVT_PULSE_LO\n};\n\nenum class PinEvent {\n    //% block=\"pulse high\"\n    PulseHigh = DEVICE_PIN_EVT_PULSE_HI,\n    //% block=\"pulse low\"\n    PulseLow = DEVICE_PIN_EVT_PULSE_LO,\n    //% block=\"rise\"\n    Rise = DEVICE_PIN_EVT_RISE,\n    //% block=\"fall\"\n    Fall = DEVICE_PIN_EVT_FALL,\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\nnamespace DigitalInOutPinMethods {\n/**\n * Read a pin or connector as either 0 or 1\n * @param name pin to read from\n */\n//% help=pins/digital-read weight=61\n//% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nbool digitalRead(DigitalInOutPin name) {\n    return PINOP(getDigitalValue()) != 0;\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\n    */\n//% help=pins/digital-write weight=60\n//% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid digitalWrite(DigitalInOutPin name, bool value) {\n    PINOP(setDigitalValue(value));\n}\n\n/**\n* Make this pin a digital input, and create events where the timestamp is the duration\n* that this pin was either ``high`` or ``low``.\n*/\n//% help=pins/on-pulsed weight=16 blockGap=8\n//% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\n//% deprecated=1 hidden=1\nvoid onPulsed(DigitalInOutPin pin, PulseValue pulse, Action body) {\n    pin->eventOn(DEVICE_PIN_EVENT_ON_PULSE);\n    registerWithDal(pin->id, (int)pulse, body);\n}\n\n/**\n* Register code to run when a pin event occurs. \n*/\n//% help=pins/on-event weight=20 blockGap=8\n//% blockId=pinsonevent block=\"on|pin %pin|%event\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\nvoid onEvent(DigitalInOutPin pin, PinEvent event, Action body) {\n    switch(event) {\n        case PinEvent::PulseHigh:\n        case PinEvent::PulseLow:\n            pin->eventOn(DEVICE_PIN_EVENT_ON_PULSE);\n            registerWithDal(pin->id, (int)event, body);\n            break;\n        case PinEvent::Rise:\n        case PinEvent::Fall:\n            pin->eventOn(DEVICE_PIN_EVENT_ON_EDGE);\n            registerWithDal(pin->id, (int)event, body);\n            break;    \n    }    \n}\n\n/**\n* Return 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 %high||timeout %maxDuration (µs)\"\n//% weight=18 blockGap=8\n//% help=\"pins/pulse-in\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\nint pulseIn(DigitalInOutPin pin, PulseValue value, int maxDuration = 2000000) {\n    int pulse = PulseValue::High == value ? 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* Set the pull direction 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=17 blockGap=8\n//% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid setPull(DigitalInOutPin name, PinPullMode pull) {\n    PullMode m = pull == PinPullMode::PullDown ? PullMode::Down : pull == PinPullMode::PullUp\n                                                                        ? PullMode::Up\n                                                                        : PullMode::None;\n    PINOP(setPull(m));\n}\n\n}\n\n#ifdef PXT_CODAL\n\nnamespace pxt {\n\nstatic void waitABit() {\n    // for (int i = 0; i < 10; ++i)\n    //    asm volatile(\"nop\");\n}\n\nclass ButtonMultiplexer : public CodalComponent {\n  public:\n    Pin &latch;\n    Pin &clock;\n    Pin &data;\n    uint32_t state;\n    uint32_t invMask;\n    uint16_t buttonIdPerBit[8];\n    bool enabled;\n\n    ButtonMultiplexer(uint16_t id)\n        : latch(*LOOKUP_PIN(BTNMX_LATCH)), clock(*LOOKUP_PIN(BTNMX_CLOCK)),\n          data(*LOOKUP_PIN(BTNMX_DATA)) {\n        this->id = id;\n        this->status |= DEVICE_COMPONENT_STATUS_SYSTEM_TICK;\n\n        state = 0;\n        invMask = 0;\n        enabled = true;\n\n        memset(buttonIdPerBit, 0, sizeof(buttonIdPerBit));\n\n        data.getDigitalValue(PullMode::Down);\n        latch.setDigitalValue(1);\n        clock.setDigitalValue(1);\n    }\n\n    void disable() {\n        data.getDigitalValue(PullMode::None);\n        latch.getDigitalValue(PullMode::None);\n        clock.getDigitalValue(PullMode::None);\n        enabled = false;\n    }\n\n    bool isButtonPressed(int id) {\n        for (int i = 0; i < 8; ++i) {\n            if (buttonIdPerBit[i] == id)\n                return (state & (1 << i)) != 0;\n        }\n        return false;\n    }\n\n    uint32_t readBits(int bits) {\n        latch.setDigitalValue(0);\n        waitABit();\n        latch.setDigitalValue(1);\n        waitABit();\n\n        uint32_t state = 0;\n        for (int i = 0; i < bits; i++) {\n            state <<= 1;\n            if (data.getDigitalValue(PullMode::Down))\n                state |= 1;\n\n            clock.setDigitalValue(0);\n            waitABit();\n            clock.setDigitalValue(1);\n            waitABit();\n        }\n\n        return state;\n    }\n\n    virtual void periodicCallback() override {\n        if (!enabled)\n            return;\n\n        uint32_t newState = readBits(8);\n        newState ^= invMask;\n        if (newState == state)\n            return;\n\n        for (int i = 0; i < 8; ++i) {\n            uint32_t mask = 1 << i;\n            if (!buttonIdPerBit[i])\n                continue;\n            int ev = 0;\n            if (!(state & mask) && (newState & mask))\n                ev = PXT_INTERNAL_KEY_DOWN;\n            else if ((state & mask) && !(newState & mask))\n                ev = PXT_INTERNAL_KEY_UP;\n            if (ev) {\n                Event(ev, buttonIdPerBit[i]);\n                Event(ev, 0); // any key\n            }\n        }\n\n        state = newState;\n    }\n};\n\nstatic ButtonMultiplexer *btnMultiplexer;\nButtonMultiplexer *getMultiplexer() {\n    if (!btnMultiplexer)\n        btnMultiplexer = new ButtonMultiplexer(DEVICE_ID_FIRST_BUTTON);\n    return btnMultiplexer;\n}\n\nint registerMultiplexedButton(int pin, int buttonId) {\n    if (1050 <= pin && pin < 1058) {\n        pin -= 50;\n        getMultiplexer()->invMask |= 1 << (pin - 1000);\n    }\n    if (1000 <= pin && pin < 1008) {\n        getMultiplexer()->buttonIdPerBit[pin - 1000] = buttonId;\n        return 1;\n    }\n    return 0;\n}\n\nint multiplexedButtonIsPressed(int btnId) {\n    if (btnMultiplexer)\n        return btnMultiplexer->isButtonPressed(btnId) ? 512 : 0;\n    return 0;\n}\n\n//% expose\nuint32_t readButtonMultiplexer(int bits) {\n    if (!LOOKUP_PIN(BTNMX_CLOCK))\n        return 0;\n    return getMultiplexer()->readBits(bits);\n}\n\nvoid disableButtonMultiplexer() {\n    if (LOOKUP_PIN(BTNMX_CLOCK)) {\n        getMultiplexer()->disable();\n    }\n}\n\n}\n\n#endif\n","pinsPWM.cpp":"#include \"pxt.h\"\n\nnamespace PwmPinMethods {\n}\n\nnamespace PwmOnlyPinMethods {\n\n/**\n * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n * **microseconds** or `1/1000` milliseconds.\n * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n * 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=51\n//% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid analogSetPeriod(PwmOnlyPin name, int period) {\n    PINOP(setAnalogPeriodUs(period));\n}\n\n/**\n * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n * 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\n */\n//% help=pins/servo-write weight=41 group=\"Servo\"\n//% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n//% parts=microservo trackArgs=0\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\n//% value.defl=90\nvoid servoWrite(PwmOnlyPin name, int value) {\n    PINOP(setServoValue(value));\n}\n\n/**\n * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n * @param name pin name\n * @param duration pulse duration in micro seconds, eg:1500\n */\n//% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n//% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n//% parts=microservo blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid servoSetPulse(PwmOnlyPin name, int duration) {\n    PINOP(setServoPulseUs(duration));\n}\n\n/**\n* Indicates if the servo is running continuously\n*/\n//% blockHidden=1\nvoid servoSetContinuous(PwmOnlyPin name, bool continuous) {\n    // used by simulator\n}\n\n}","pinscompat.ts":"// filled in by microbit","platform.cpp":"#include \"pxt.h\"\n#include \"light.h\"\n\nnamespace pxt {\n\nCODAL_TIMER devTimer;\n\nstatic void initRandomSeed() {\n    int seed = 0xC0DA1;\n    auto pinTemp = LOOKUP_PIN(TEMPERATURE);\n    if (pinTemp)\n        seed *= pinTemp->getAnalogValue();\n    auto pinLight = LOOKUP_PIN(LIGHT);\n    if (pinLight)\n        seed *= pinLight->getAnalogValue();\n    seedRandom(seed);\n}\n\nstatic void remapSwdPin(int pinCfg, int fallback) {\n    int pinName = getConfig(pinCfg);\n    if (pinName == PA30 || pinName == PA31) {\n        if (getConfig(CFG_SWD_ENABLED, 0)) {\n            linkPin(pinName, fallback);\n        } else {\n            PORT->Group[pinName / 32].PINCFG[pinName % 32].reg = (uint8_t)PORT_PINCFG_INEN;\n        }\n    }\n}\n\nstatic void initSwdPins() {\n    remapSwdPin(CFG_PIN_NEOPIXEL, PIN(D0));\n    remapSwdPin(CFG_PIN_RXLED, PIN(D1));\n    remapSwdPin(CFG_PIN_SPEAKER_AMP, PIN(D2));\n}\n\nvoid platform_init() {\n    initSwdPins();\n    initRandomSeed();\n    light::clear();\n\n    if (*HF2_DBG_MAGIC_PTR == HF2_DBG_MAGIC_START) {\n        *HF2_DBG_MAGIC_PTR = 0;\n        // this will cause alignment fault at the first breakpoint\n        globals[0] = (TValue)1;\n    }\n}\n\n} // namespace pxt\n","platform.h":"#ifndef __PXT_PLATFORM_H\n#define __PXT_PLATFORM_H\n\n// This is specific for SAMD21, to be replaced in other Codal targets.\n\n#include \"CapTouchButton.h\"\n#include \"Image.h\"\n#include \"MbedTimer.h\"\n#include \"MbedI2C.h\"\n#include \"MbedPin.h\"\n#include \"MbedSPI.h\"\n#include \"MbedSerial.h\"\n#include \"MultiButton.h\"\n#include \"CPlayI2C.h\"\n\n#include \"SAMD21DMAC.h\"\n\n// Analog Pins, all SAMD21: PA02-PA11 PB00-PB09 (some pins not connected)\n// 2 ports times 32 pins in each\n#define DEV_NUM_PINS 64\n// pins marked with AIN and PTC in the data sheet\n#define DEV_ANALOG_PINS 0x3ff00000ffcULL\n\n#define PAGE_SIZE 256\n\n#define CODAL_DMAC SAMD21DMAC\n\n// this is codal::_mbed for both mbed and mbedos now\n#define CODAL_MBED codal::_mbed\n\n#define CODAL_I2C codal::CPlayI2C\n\n#ifndef IMAGE_BITS\n#define IMAGE_BITS 1\n#endif\n\n#ifdef JUST_FOR_DAL_D_TS_CPP_WILL_IGNORE\n#define PA00 0\n#define PA01 1\n#define PA02 2\n#define PA03 3\n#define PA04 4\n#define PA05 5\n#define PA06 6\n#define PA07 7\n#define PA08 8\n#define PA09 9\n#define PA10 10\n#define PA11 11\n#define PA12 12\n#define PA13 13\n#define PA14 14\n#define PA15 15\n#define PA16 16\n#define PA17 17\n#define PA18 18\n#define PA19 19\n#define PA20 20\n#define PA21 21\n#define PA22 22\n#define PA23 23\n#define PA24 24\n#define PA25 25\n#define PA26 26\n#define PA27 27\n#define PA28 28\n#define PA29 29\n#define PA30 30\n#define PA31 31\n#define PB00 32\n#define PB01 33\n#define PB02 34\n#define PB03 35\n#define PB04 36\n#define PB05 37\n#define PB06 38\n#define PB07 39\n#define PB08 40\n#define PB09 41\n#define PB10 42\n#define PB11 43\n#define PB12 44\n#define PB13 45\n#define PB14 46\n#define PB15 47\n#define PB16 48\n#define PB17 49\n#define PB18 50\n#define PB19 51\n#define PB20 52\n#define PB21 53\n#define PB22 54\n#define PB23 55\n#define PB24 56\n#define PB25 57\n#define PB26 58\n#define PB27 59\n#define PB28 60\n#define PB29 61\n#define PB30 62\n#define PB31 63\n#endif\n\n#endif\n","pxt.h":"#ifndef __PXT_H\n#define __PXT_H\n\n#include \"pxtbase.h\"\n\n#include \"CodalConfig.h\"\n#include \"CodalHeapAllocator.h\"\n#include \"CodalDevice.h\"\n#include \"CodalDmesg.h\"\n#include \"ErrorNo.h\"\n#include \"Timer.h\"\n#include \"Matrix4.h\"\n#include \"CodalCompat.h\"\n#include \"CodalComponent.h\"\n#include \"ManagedType.h\"\n#include \"Event.h\"\n#include \"NotifyEvents.h\"\n#include \"Button.h\"\n#include \"CodalFiber.h\"\n#include \"MessageBus.h\"\n#include \"MultiButton.h\"\n\nusing namespace codal;\n\n// codal::ManagedString compat\n#define MSTR(s) codal::ManagedString((s)->data, (s)->length)\n#define PSTR(s) mkString((s).toCharArray(), (s).length())\n\n#include \"pins.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"hf2.h\"\n#include \"hf2dbg.h\"\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n#include \"HIDMouse.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n#include \"HIDKeyboard.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n#include \"HIDJoystick.h\"\n#endif\n#endif\n\n#define PXT_COMM_BASE 0x20002000 // 8k in\n\n// old codal compat\n#ifndef REAL_TIME_FUNC\n#define REAL_TIME_FUNC /* */\n#endif\n\nnamespace pxt {\n\n#if CONFIG_ENABLED(DEVICE_USB)\nextern CodalUSB usb;\nextern HF2 hf2;\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nextern USBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nextern USBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nextern USBHIDJoystick joystick;\n#endif\n#endif\n\n// Utility functions\nextern Event lastEvent;\nextern CODAL_TIMER devTimer;\nextern MessageBus devMessageBus;\nextern codal::CodalDevice device;\n\nvoid set_usb_strings(const char *uf2_info);\nextern void (*logJDFrame)(const uint8_t *data);\nextern void (*sendJDFrame)(const uint8_t *data);\n\nstatic inline void raiseEvent(int src, int val) {\n    Event(src, val);\n}\n\n} // namespace pxt\n\nnamespace pins {\nclass CodalSPIProxy;\nclass CodalI2CProxy;\n} // namespace pins\n\ntypedef pins::CodalI2CProxy* I2C_;\ntypedef pins::CodalSPIProxy* SPI_;\n\nnamespace pxt {\ncodal::LowLevelTimer *allocateTimer();\n\n#ifdef CODAL_I2C\nCODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl);\n#endif\nCODAL_SPI* getSPI(DigitalInOutPin mosi, DigitalInOutPin miso, DigitalInOutPin sck);\n#ifdef CODAL_JACDAC_WIRE_SERIAL\nLowLevelTimer* getJACDACTimer();\n#endif\nclass PressureButton;\nuint32_t readButtonMultiplexer(int bits);\nvoid disableButtonMultiplexer();\n}\n\nnamespace serial {\nclass CodalSerialDeviceProxy;\n}\n\ntypedef serial::CodalSerialDeviceProxy* SerialDevice;\n\nnamespace jacdac {\nclass JDProxyDriver;\n} // namespace network\n\ntypedef jacdac::JDProxyDriver* JacDacDriverStatus;\n\n#define DEVICE_ID_BUTTON_SLIDE 3000\n#define DEVICE_ID_MICROPHONE 3001\n#define DEVICE_ID_FIRST_BUTTON 4000\n#define DEVICE_ID_FIRST_TOUCHBUTTON 4100\n\n#define PXT_INTERNAL_KEY_UP 2050\n#define PXT_INTERNAL_KEY_DOWN 2051\n\n#endif\n","pxt.json":"{\n    \"name\": \"core\",\n    \"description\": \"The core library for Codal-based targets\",\n    \"dependencies\": {\n        \"base\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"dal.d.ts\",\n        \"codal.cpp\",\n        \"usb.cpp\",\n        \"pxt.h\",\n        \"platform.h\",\n        \"platform.cpp\",\n        \"pxtcore.h\",\n        \"pins.h\",\n        \"pins.cpp\",\n        \"pinsAnalog.cpp\",\n        \"pinsDigital.cpp\",\n        \"pinsPWM.cpp\",\n        \"pins.ts\",\n        \"pinscompat.ts\",\n        \"control.cpp\",\n        \"i2c.cpp\",\n        \"i2c.ts\",\n        \"spi.cpp\",\n        \"spi.ts\",\n        \"shims.d.ts\",\n        \"enums.d.ts\",\n        \"hf2.cpp\",\n        \"hf2.h\",\n        \"hf2dbg.h\",\n        \"uf2format.h\",\n        \"uf2hid.h\",\n        \"ns.ts\",\n        \"dmac.cpp\",\n        \"dmac.h\",\n        \"timer.ts\",\n        \"light.cpp\",\n        \"light.h\",\n        \"keyvaluestorage.cpp\",\n        \"keyvaluestorage.ts\",\n        \"leveldetector.ts\",\n        \"pxtparts.json\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"yotta\": {\n        \"config\": {\n            \"codal\": {\n                \"component_count\": 64,\n                \"dmesg_buffer_size\": 1024\n            }\n        }\n    },\n    \"dalDTS\": {\n        \"includeDirs\": [\n            \"libraries/codal-core/inc\",\n            \"pxtapp\"\n        ],\n        \"excludePrefix\": [\n            \"JD_\",\n            \"USB_\",\n            \"REQUEST_\",\n            \"LIS3DH_\",\n            \"FXOS8700_\",\n            \"HF2_\",\n            \"PXT_REF_TAG_\",\n            \"MS_\",\n            \"SCSI_\",\n            \"MAG_\",\n            \"MAG3\",\n            \"MPU6\",\n            \"MADCTL\",\n            \"MMA8\"\n        ]\n    }\n}\n","pxtcore.h":"#ifndef __PXTCORE_H\n#define __PXTCORE_H\n\n#include \"CodalDmesg.h\"\n#include \"CodalHeapAllocator.h\"\n\n#define PXT_CODAL 1\n\n#define itoa(a, b) codal::itoa(a, b)\n\n#define GC_GET_HEAP_SIZE() device_heap_size(0)\n#define GC_STACK_BASE DEVICE_STACK_BASE\n#define xmalloc device_malloc\n#define xfree device_free\n\n// on most devices we allocate the entire heap at once, so large allocs should work\n// if they don't you just get the regular out of memory instead of alloc too large\n#define GC_MAX_ALLOC_SIZE (128 * 1024)\n\n#endif\n","pxtparts.json":"{\n    \"neopixel\": {\n        \"simulationBehavior\": \"neopixel\",\n        \"visual\": {\n            \"builtIn\": \"neopixel\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 19,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 28,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createStrip,light.createNeoPixelStrip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"dotstar\": {\n        \"simulationBehavior\": \"dotstar\",\n        \"visual\": {\n            \"builtIn\": \"dotstar\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 1\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createAPA102Strip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"dataPin\"\n                },\n                {\n                    \"pinInstantiationIdx\": 1,\n                    \"partParameter\": \"clkPin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },\n    \"pixels\": {\n        \"simulationBehavior\": \"pixels\",\n        \"visual\": { \n            \"builtIn\": \"pixels\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"MOSI\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"SCK\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },    \n    \"buttons\": {\n        \"simulationBehavior\": \"buttons\",\n        \"visual\": {\n            \"builtIn\": \"buttons\",\n            \"width\": 75,\n            \"height\": 45,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 30,\n                    \"y\": 45\n                }\n            ]\n        },\n        \"numberOfPins\": 2,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"Button.onEvent,Button.isPressed,Button.wasPressed\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"button\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"slideswitch\": {\n        \"numberOfPins\": 3,\n        \"simulationBehavior\": \"slideswitch\",\n        \"visual\": {\n            \"builtIn\": \"slideswitch\",\n            \"width\": 100,\n            \"height\": 100,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalRead,DigitalInOutPin.onPulsed,DigitalInOutPin.onEvent\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"microservo\": {\n        \"simulationBehavior\": \"microservo\",\n        \"visual\": {\n            \"builtIn\": \"microservo\",\n            \"width\": 74.85,\n            \"height\": 200,\n            \"pinDistance\": 10,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 37,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 5\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"PwmOnlyPin.servoWrite,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"led\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"analogled\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogOutPin.analogWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"photocell\": {\n        \"numberOfPins\": 3,\n        \"visual\": {\n            \"builtIn\": \"photocell\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 15,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"photocell\",\n        \"pinDefinitions\": [\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogInPin.analogRead\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace light {\n\n    /**\n     * Send a programmable light buffer to the specified digital pin\n     * @param data The pin that the lights are connected to\n     * @param clk the clock line if any\n     * @param mode the color encoding mode\n     * @param buf The buffer to send to the pin\n     */\n    //% shim=light::sendBuffer\n    function sendBuffer(data: DigitalInOutPin, clk: DigitalInOutPin, mode: int32, buf: Buffer): void;\n}\ndeclare namespace control {\n\n    /**\n     * Determines if the USB has been enumerated.\n     */\n    //% shim=control::isUSBInitialized\n    function isUSBInitialized(): boolean;\n}\ndeclare namespace pins {\n\n    /**\n     * Get a pin by configuration id (DAL.CFG_PIN...)\n     */\n    //% shim=pins::pinByCfg\n    function pinByCfg(key: int32): DigitalInOutPin;\n\n    /**\n     * Create a new zero-initialized buffer.\n     * @param size number of bytes in the buffer\n     */\n    //% shim=pins::createBuffer\n    function createBuffer(size: int32): Buffer;\n\n    /**\n     * Get the duration of the last pulse in microseconds. This function should be called from a\n     * ``onPulsed`` handler.\n     */\n    //% help=pins/pulse-duration blockGap=8\n    //% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n    //% weight=19 shim=pins::pulseDuration\n    function pulseDuration(): int32;\n}\n\n\ndeclare interface AnalogInPin {\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 weight=53\n    //% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=AnalogInPinMethods::analogRead\n    analogRead(): int32;\n}\n\n\ndeclare interface AnalogOutPin {\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 weight=52\n    //% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4\n    //% value.min=0 value.max=1023 shim=AnalogOutPinMethods::analogWrite\n    analogWrite(value: int32): void;\n}\n\n\ndeclare interface DigitalInOutPin {\n    /**\n     * Read a pin or connector as either 0 or 1\n     * @param name pin to read from\n     */\n    //% help=pins/digital-read weight=61\n    //% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::digitalRead\n    digitalRead(): boolean;\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\n     */\n    //% help=pins/digital-write weight=60\n    //% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::digitalWrite\n    digitalWrite(value: boolean): void;\n\n    /**\n     * Make this pin a digital input, and create events where the timestamp is the duration\n     * that this pin was either ``high`` or ``low``.\n     */\n    //% help=pins/on-pulsed weight=16 blockGap=8\n    //% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4\n    //% deprecated=1 hidden=1 shim=DigitalInOutPinMethods::onPulsed\n    onPulsed(pulse: PulseValue, body: () => void): void;\n\n    /**\n     * Register code to run when a pin event occurs. \n     */\n    //% help=pins/on-event weight=20 blockGap=8\n    //% blockId=pinsonevent block=\"on|pin %pin|%event\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4 shim=DigitalInOutPinMethods::onEvent\n    onEvent(event: PinEvent, body: () => void): void;\n\n    /**\n     * Return 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 %high||timeout %maxDuration (µs)\"\n    //% weight=18 blockGap=8\n    //% help=\"pins/pulse-in\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4 maxDuration.defl=2000000 shim=DigitalInOutPinMethods::pulseIn\n    pulseIn(value: PulseValue, maxDuration?: int32): int32;\n\n    /**\n     * Set the pull direction 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=17 blockGap=8\n    //% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::setPull\n    setPull(pull: PinPullMode): void;\n}\n\n\ndeclare interface PwmPin {}\n\n\ndeclare interface PwmOnlyPin {\n    /**\n     * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n     * **microseconds** or `1/1000` milliseconds.\n     * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n     * 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=51\n    //% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::analogSetPeriod\n    analogSetPeriod(period: int32): void;\n\n    /**\n     * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n     * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n     * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n     * 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\n     */\n    //% help=pins/servo-write weight=41 group=\"Servo\"\n    //% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n    //% parts=microservo trackArgs=0\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4\n    //% value.defl=90 shim=PwmOnlyPinMethods::servoWrite\n    servoWrite(value?: int32): void;\n\n    /**\n     * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n     * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n     * @param name pin name\n     * @param duration pulse duration in micro seconds, eg:1500\n     */\n    //% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n    //% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n    //% parts=microservo blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::servoSetPulse\n    servoSetPulse(duration: int32): void;\n\n    /**\n     * Indicates if the servo is running continuously\n     */\n    //% blockHidden=1 shim=PwmOnlyPinMethods::servoSetContinuous\n    servoSetContinuous(continuous: boolean): void;\n}\ndeclare namespace control {\n\n    /**\n     * Announce that an event happened to registered handlers.\n     * @param src ID of the MicroBit Component that generated the event\n     * @param value Component specific code indicating the cause of the event.\n     */\n    //% weight=21 blockGap=12 blockId=\"control_raise_event\"\n    //% help=control/raise-event\n    //% block=\"raise event|from %src|with value %value\" blockExternalInputs=1 shim=control::raiseEvent\n    function raiseEvent(src: int32, value: int32): void;\n\n    /**\n     * Determine the version of system software currently running.\n     */\n    //% blockId=\"control_device_dal_version\" block=\"device dal version\"\n    //% help=control/device-dal-version shim=control::deviceDalVersion\n    function deviceDalVersion(): string;\n\n    /**\n     * Allocates the next user notification event\n     */\n    //% help=control/allocate-notify-event shim=control::allocateNotifyEvent\n    function allocateNotifyEvent(): int32;\n\n    /** Write a message to DMESG debugging buffer. */\n    //% shim=control::dmesg\n    function dmesg(s: string): void;\n\n    /** Write a message and value (pointer) to DMESG debugging buffer. */\n    //% shim=control::dmesgPtr\n    function dmesgPtr(str: string, ptr: Object): void;\n}\n\n\ndeclare interface I2C {\n    /**\n     * Read `size` bytes from a 7-bit I2C `address`.\n     */\n    //% repeat.defl=0 shim=I2CMethods::readBuffer\n    readBuffer(address: int32, size: int32, repeat?: boolean): Buffer;\n\n    /**\n     * Write bytes to a 7-bit I2C `address`.\n     */\n    //% repeat.defl=0 shim=I2CMethods::writeBuffer\n    writeBuffer(address: int32, buf: Buffer, repeat?: boolean): int32;\n}\ndeclare namespace pins {\n\n    /**\n     * Opens a Serial communication driver\n     */\n    //% help=pins/create-i2c\n    //% parts=i2c shim=pins::createI2C\n    function createI2C(sda: DigitalInOutPin, scl: DigitalInOutPin): I2C;\n}\ndeclare namespace pins {\n\n    /**\n     * Opens a SPI driver\n     */\n    //% help=pins/create-spi\n    //% parts=spi shim=pins::createSPI\n    function createSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin): SPI;\n\n    /**\n     * Opens a slave SPI driver\n     */\n    //% parts=spi shim=pins::createSlaveSPI\n    function createSlaveSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin, csPin: DigitalInOutPin): SPI;\n}\n\n\ndeclare interface SPI {\n    /**\n     * Write to the SPI bus\n     */\n    //% shim=SPIMethods::write\n    write(value: int32): int32;\n\n    /**\n     * Transfer buffers over the SPI bus\n     */\n    //% argsNullable shim=SPIMethods::transfer\n    transfer(command: Buffer, response: Buffer): void;\n\n    /**\n     * Sets the SPI clock frequency\n     */\n    //% shim=SPIMethods::setFrequency\n    setFrequency(frequency: int32): void;\n\n    /**\n     * Sets the SPI bus mode\n     */\n    //% shim=SPIMethods::setMode\n    setMode(mode: int32): void;\n}\ndeclare namespace configStorage {\n\n    /**\n     * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n     * @param key the identifier (max 16 characters)\n     * @param value the data (max 32 characters)\n     */\n    //% shim=configStorage::setBuffer\n    function setBuffer(key: string, value: Buffer): void;\n\n    /**\n     * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n     * @param key the identifier (max 16 characters)\n     */\n    //% shim=configStorage::getBuffer\n    function getBuffer(key: string): Buffer;\n\n    /**\n     * Removes the key from local storage\n     * @param key the identifier (max 16 characters)\n     */\n    //% shim=configStorage::removeItem\n    function removeItem(key: string): void;\n\n    /**\n     * Clears the local storage\n     */\n    //% shim=configStorage::clear\n    function clear(): void;\n}\n\n// Auto-generated. Do not edit. Really.\n","spi.cpp":"#include \"pxt.h\"\n#include \"ErrorNo.h\"\n\nnamespace pins {\n\nclass CodalSPIProxy {\nprivate:\n    DevicePin* mosi; \n    DevicePin* miso; \n    DevicePin* sck;\n    CODAL_SPI spi;\npublic:\n    CodalSPIProxy* next;\n\npublic:\n    CodalSPIProxy(DevicePin* _mosi, DevicePin* _miso, DevicePin* _sck)\n        : mosi(_mosi)\n        , miso(_miso)\n        , sck(_sck)\n        , spi(*_mosi, *_miso, *_sck) \n        , next(NULL)\n    {\n    }\n\n#ifdef CODAL_SPI_SLAVE_SUPPORTED\n    CodalSPIProxy(DevicePin* _mosi, DevicePin* _miso, DevicePin* _sck, DevicePin* _cs)\n        : mosi(_mosi)\n        , miso(_miso)\n        , sck(_sck)\n        , spi(*_mosi, *_miso, *_sck, _cs) \n        , next(NULL)\n    {\n    }\n#endif\n\n    CODAL_SPI* getSPI() {\n        return &spi;\n    }\n\n    bool matchPins(DevicePin* mosi, DevicePin* miso, DevicePin* sck) {\n        return this->mosi == mosi && this->miso == miso && this->sck == sck;\n    }\n\n    int write(int value) {\n        return spi.write(value);\n    }\n\n    void transfer(Buffer command, Buffer response) {\n        auto cdata = NULL == command ? NULL : command->data;\n        auto clength = NULL == command ? 0 : command->length;\n        auto rdata = NULL == response ? NULL : response->data;\n        auto rlength = NULL == response ? 0 : response->length;\n        spi.transfer(cdata, clength, rdata, rlength);\n    }\n\n    void setFrequency(int frequency) {\n        spi.setFrequency(frequency);\n    }\n\n    void setMode(int mode) {\n        spi.setMode(mode);\n    }\n};\n\nSPI_ spis(NULL);\n\n/**\n* Opens a SPI driver\n*/\n//% help=pins/create-spi\n//% parts=spi\nSPI_ createSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin) {\n  auto dev = spis;\n  while(dev) {\n    if (dev->matchPins(mosiPin, misoPin, sckPin))\n      return dev;\n    dev = dev->next;\n  }\n\n  auto ser = new CodalSPIProxy(mosiPin, misoPin, sckPin);\n  ser->next = spis;\n  spis = ser;\n  return ser;\n}\n\n/**\n* Opens a slave SPI driver\n*/\n//% parts=spi\nSPI_ createSlaveSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin, DigitalInOutPin csPin) {\n#ifdef CODAL_SPI_SLAVE_SUPPORTED\n  auto dev = spis;\n  if (!csPin)\n    soft_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n  while(dev) {\n    if (dev->matchPins(mosiPin, misoPin, sckPin))\n      return dev;\n    dev = dev->next;\n  }\n\n  auto ser = new CodalSPIProxy(mosiPin, misoPin, sckPin, csPin);\n  ser->next = spis;\n  spis = ser;\n  return ser;\n#else\n  soft_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n  return NULL;\n#endif\n}\n\n}\n\nnamespace pxt {\n\nCODAL_SPI* getSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin) {\n    auto spi = pins::createSPI(mosiPin, misoPin, sckPin);\n    return spi->getSPI();\n}\n\n}\n\nnamespace SPIMethods {\n\n/**\n* Write to the SPI bus\n*/\n//%\nint write(SPI_ device, int value) {\n    return device->write(value);\n}\n\n/**\n* Transfer buffers over the SPI bus\n*/\n//% argsNullable\nvoid transfer(SPI_ device, Buffer command, Buffer response) {\n    if (!device)\n        soft_panic(PANIC_CAST_FROM_NULL);\n    if (!command && !response)\n        return;\n    device->transfer(command, response);\n}\n\n/**\n* Sets the SPI clock frequency\n*/\n//%\nvoid setFrequency(SPI_ device, int frequency) {\n    device->setFrequency(frequency);\n}\n\n/**\n* Sets the SPI bus mode\n*/\n//%\nvoid setMode(SPI_ device, int mode) {\n    device->setMode(mode);\n}\n\n}\n","spi.ts":"namespace pins {\n\n    let _spi: SPI;\n    /**\n    * Gets the default SPI driver\n    */\n    //%\n    export function spi() {\n        if (!_spi) {\n            const mosi = pins.pinByCfg(DAL.CFG_PIN_MOSI);\n            const miso = pins.pinByCfg(DAL.CFG_PIN_MISO);\n            const sck = pins.pinByCfg(DAL.CFG_PIN_SCK);\n            _spi = pins.createSPI(mosi, miso, sck);\n        }\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 advanced=true\n    //% blockId=spi_write block=\"spi write %value\"\n    export function spiWrite(value: number) {\n        return spi().write(value);\n    }\n\n    /**\n     * Write a given command to SPI bus, and at the same time read the response.\n     */\n    //% help=pins/spi-transfer weight=4 advanced=true\n    //% blockId=spi_transfer block=\"spi transfer %command into %response\"\n    export function spiTransfer(command: Buffer, response: Buffer) {\n        spi().transfer(command, response);\n    }\n\n    /**\n     * Set the SPI frequency\n     * @param frequency the clock frequency, eg: 1000000\n     */\n    //% help=pins/spi-frequency weight=4 advanced=true\n    //% blockId=spi_frequency block=\"spi frequency %frequency\"\n    export function spiFrequency(frequency: number) {\n        spi().setFrequency(frequency);\n    }\n\n    /**\n     * Set the SPI signal mode\n     * @param mode the mode, eg: 3\n     */\n    //% help=pins/spi-mode weight=3 advanced=true\n    //% blockId=spi_mode block=\"spi mode %mode\"\n    export function spiMode(mode: number) {\n        spi().setMode(mode);\n    }\n}","test.ts":"let i = 1\nlet f = 0.5\nlet plus = i + f\nlet minus = i - f\n\nlet r = Math.random()\nlet ri = Math.randomRange(5, 10)\n\n","timer.ts":"namespace control {\n    /**\n     * A timer\n     */\n    //% fixedInstances\n    export class Timer {\n        start: number;\n\n        constructor() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Gets the elapsed time in millis since the last reset\n         */\n        //% blockId=timerMillis block=\"%timer|millis\"\n        millis(): number {\n            return control.millis() - this.start;\n        }\n\n        /**\n         * Gets the elapsed time in seconds since the last reset\n         */\n        //% blockId=timerSeconds block=\"%timer|seconds\"\n        seconds(): number {\n            return this.millis() / 1000;\n        }\n\n        /**\n         * Resets the timer\n         */\n        //% blockId=timerRest block=\"%timer|reset\"\n        reset() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Pauses until the timer reaches the given amount of milliseconds\n         * @param ms how long to pause for, eg: 5, 100, 200, 500, 1000, 2000\n         */\n        //% blockId=timerPauseUntil block=\"%timer|pause until (ms) %ms\"\n        pauseUntil(ms: number) {\n            const remaining = this.millis() - ms;\n            pause(Math.max(0, remaining));\n        }\n    }\n\n    //% whenUsed fixedInstance block=\"timer 1\"\n    export const timer1 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 2\"\n    export const timer2 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 3\"\n    export const timer3 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 4\"\n    export const timer4 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 5\"\n    export const timer5 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 6\"\n    export const timer6 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 7\"\n    export const timer7 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 8\"\n    export const timer8 = new Timer();\n}","uf2format.h":"#ifndef UF2FORMAT_H\n#define UF2FORMAT_H 1\n\n#include <stdint.h>\n#include <stdbool.h>\n\n// All entries are little endian.\n\n#ifndef BOOTLOADER_START\n#define BOOTLOADER_START 0x0\n#endif\n\n#ifndef BOOTLOADER_END\n#define BOOTLOADER_END 0x2000\n#endif\n\n#ifndef UF2_BINFO\n#define UF2_BINFO ((UF2_BInfo *)(BOOTLOADER_END - sizeof(UF2_BInfo)))\n#endif\n\n#ifndef UF2_INFO_TXT\n#define UF2_INFO_TXT UF2_BINFO->info_uf2\n#endif\n\n\n#define UF2_MAGIC_START0 0x0A324655UL // \"UF2\\n\"\n#define UF2_MAGIC_START1 0x9E5D5157UL // Randomly selected\n#define UF2_MAGIC_END 0x0AB16F30UL    // Ditto\n\n// If set, the block is \"comment\" and should not be flashed to the device\n#define UF2_FLAG_NOFLASH 0x00000001\n\ntypedef struct {\n    // 32 byte header\n    uint32_t magicStart0;\n    uint32_t magicStart1;\n    uint32_t flags;\n    uint32_t targetAddr;\n    uint32_t payloadSize;\n    uint32_t blockNo;\n    uint32_t numBlocks;\n    uint32_t reserved;\n\n    // raw data;\n    uint8_t data[476];\n\n    // store magic also at the end to limit damage from partial block reads\n    uint32_t magicEnd;\n} UF2_Block;\n\ntypedef struct {\n    uint8_t version;\n    uint8_t ep_in;\n    uint8_t ep_out;\n    uint8_t reserved0;\n    uint32_t cbw_tag;\n    uint32_t blocks_remaining;\n    uint8_t *buffer;\n} UF2_HandoverArgs;\n\ntypedef void (*UF2_MSC_Handover_Handler)(UF2_HandoverArgs *handover);\ntypedef void (*UF2_HID_Handover_Handler)(int ep);\n\n// this is required to be exactly 16 bytes long by the linker script\ntypedef struct {\n    void *reserved0;\n    UF2_HID_Handover_Handler handoverHID;\n    UF2_MSC_Handover_Handler handoverMSC;\n    const char *info_uf2;\n} UF2_BInfo;\n\nstatic inline bool is_uf2_block(void *data) {\n    UF2_Block *bl = (UF2_Block *)data;\n    return bl->magicStart0 == UF2_MAGIC_START0 && bl->magicStart1 == UF2_MAGIC_START1 &&\n           bl->magicEnd == UF2_MAGIC_END;\n}\n\nstatic inline bool in_uf2_bootloader_space(const void *addr) {\n    return (BOOTLOADER_START + 0x100) <= (uint32_t)addr && (uint32_t)addr < (BOOTLOADER_END);\n}\n\nstatic inline const char *uf2_info(void) {\n    if (in_uf2_bootloader_space(UF2_INFO_TXT))\n        return UF2_INFO_TXT;\n    return \"N/A\";\n}\n\n#ifdef UF2_DEFINE_HANDOVER\nstatic inline void hf2_handover(uint8_t ep) {\n    const char *board_info = UF2_BINFO->info_uf2;\n    UF2_HID_Handover_Handler fn = UF2_BINFO->handoverHID;\n\n    if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&\n        ((uint32_t)fn & 1)) {\n        // Pass control to bootloader; never returns\n        fn(ep & 0xf);\n    }\n}\n\nstatic inline void check_uf2_handover(uint8_t *buffer, uint32_t blocks_remaining, uint8_t ep_in,\n                                      uint8_t ep_out, uint32_t cbw_tag) {\n    if (!is_uf2_block(buffer))\n        return;\n\n    const char *board_info = UF2_BINFO->info_uf2;\n    UF2_MSC_Handover_Handler fn = UF2_BINFO->handoverMSC;\n\n    if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&\n        ((uint32_t)fn & 1)) {\n        UF2_HandoverArgs hand = {\n            1, ep_in, ep_out, 0, cbw_tag, blocks_remaining, buffer,\n        };\n        // Pass control to bootloader; never returns\n        fn(&hand);\n    }\n}\n#endif\n\n#endif\n","uf2hid.h":"#ifndef UF2_HID_H\n#define UF2_HID_H 1\n\n#define HF2_CMD_BININFO 0x0001\n// no arguments\n#define HF2_MODE_BOOTLOADER 0x01\n#define HF2_MODE_USERSPACE 0x02\nstruct HF2_BININFO_Result {\n    uint32_t mode;\n    uint32_t flash_page_size;\n    uint32_t flash_num_pages;\n    uint32_t max_message_size;\n    uint32_t uf2_family;\n};\n\n#define HF2_CMD_INFO 0x0002\n// no arguments\n// results is utf8 character array\n\n#define HF2_CMD_RESET_INTO_APP 0x0003\n// no arguments, no result\n\n#define HF2_CMD_RESET_INTO_BOOTLOADER 0x0004\n// no arguments, no result\n\n#define HF2_CMD_START_FLASH 0x0005\n// no arguments, no result\n\n#define HF2_CMD_WRITE_FLASH_PAGE 0x0006\nstruct HF2_WRITE_FLASH_PAGE_Command {\n    uint32_t target_addr;\n    uint32_t data[0];\n};\n// no result\n\n#define HF2_CMD_CHKSUM_PAGES 0x0007\nstruct HF2_CHKSUM_PAGES_Command {\n    uint32_t target_addr;\n    uint32_t num_pages;\n};\nstruct HF2_CHKSUM_PAGES_Result {\n    uint16_t chksums[0 /* num_pages */];\n};\n\n#define HF2_CMD_READ_WORDS 0x0008\nstruct HF2_READ_WORDS_Command {\n    uint32_t target_addr;\n    uint32_t num_words;\n};\nstruct HF2_READ_WORDS_Result {\n    uint32_t words[0 /* num_words */];\n};\n\n#define HF2_CMD_WRITE_WORDS 0x0009\nstruct HF2_WRITE_WORDS_Command {\n    uint32_t target_addr;\n    uint32_t num_words;\n    uint32_t words[0 /* num_words */];\n};\n// no result\n\n#define HF2_CMD_DMESG 0x0010\n// no arguments\n// results is utf8 character array\n\n#define HF2_EV_MASK 0x800000\n\n#define HF2_CMD_JDS_CONFIG 0x0020\n#define HF2_CMD_JDS_SEND 0x0021\n#define HF2_EV_JDS_PACKET 0x800020\n\ntypedef struct {\n    uint32_t command_id;\n    uint16_t tag;\n    uint8_t reserved0;\n    uint8_t reserved1;\n\n    union {\n        struct HF2_WRITE_FLASH_PAGE_Command write_flash_page;\n        struct HF2_WRITE_WORDS_Command write_words;\n        struct HF2_READ_WORDS_Command read_words;\n        struct HF2_CHKSUM_PAGES_Command chksum_pages;\n        uint8_t data8[0];\n        uint16_t data16[0];\n        uint32_t data32[0];\n    };\n} HF2_Command;\n\ntypedef struct {\n    union {\n        uint32_t eventId;\n        struct {\n            uint16_t tag;\n            union {\n                struct {\n                    uint8_t status;\n                    uint8_t status_info;\n                };\n                uint16_t status16;\n            };\n        };\n    };\n    union {\n        struct HF2_BININFO_Result bininfo;\n        uint8_t data8[0];\n        uint16_t data16[0];\n        uint32_t data32[0];\n    };\n} HF2_Response;\n\n#define HF2_FLAG_SERIAL_OUT 0x80\n#define HF2_FLAG_SERIAL_ERR 0xC0\n#define HF2_FLAG_CMDPKT_LAST 0x40\n#define HF2_FLAG_CMDPKT_BODY 0x00\n#define HF2_FLAG_MASK 0xC0\n#define HF2_SIZE_MASK 63\n\n#define HF2_STATUS_OK 0x00\n#define HF2_STATUS_INVALID_CMD 0x01\n#define HF2_STATUS_INVALID_STATE 0x02\n\n#endif\n","usb.cpp":"#include \"pxt.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"uf2format.h\"\n\nnamespace pxt {\nCodalUSB usb;\n\n// share the buffer; we will crash anyway if someone talks to us over both at the same time\nHF2_Buffer hf2buf;\nHF2 hf2(hf2buf);\n#ifdef HF2_HID\nHF2 hf2hid(hf2buf);\n#endif\nDummyIface dummyIface;\n\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nUSBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nUSBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nUSBHIDJoystick joystick;\n#endif\n\nstatic const DeviceDescriptor device_desc = {\n    0x12,   // bLength\n    0x01,   // bDescriptorType\n    0x0210, // bcdUSBL\n\n    // Class etc specified per-interface\n    0x00, 0x00, 0x00,\n\n    0x40, // bMaxPacketSize0\n    USB_DEFAULT_VID, USB_DEFAULT_PID,\n    0x4202, // bcdDevice - leave unchanged for the HF2 to work\n    0x01,   // iManufacturer\n    0x02,   // iProduct\n    0x03,   // SerialNumber\n    0x01    // bNumConfigs\n};\n\nstatic void start_usb() {\n    // start USB with a delay, so that user code can add new interfaces if needed\n    // (eg USB HID keyboard, or MSC)\n    fiber_sleep(500);\n    usb.start();\n}\n\nvoid platform_usb_init() __attribute__((weak));\nvoid platform_usb_init() {}\n\nvoid set_usb_strings(const char *uf2_info) {\n    static const char *string_descriptors[3];\n    static char serial[12];\n    itoa(target_get_serial() & 0x7fffffff, serial);\n\n    auto model = strstr(uf2_info, \"Model: \");\n    if (model) {\n        model += 7;\n        auto end = model;\n        while (*end && *end != '\\n' && *end != '\\r')\n            end++;\n        auto len = end - model;\n        auto dev = (char *)app_alloc(len + 10);\n        memcpy(dev, model, len);\n        strcpy(dev + len, \" (app)\");\n        // try to split into manufacturer and\n        auto sep = strstr(dev, \" / \");\n        if (sep) {\n            *sep = '\\0';\n            string_descriptors[0] = dev;\n            string_descriptors[1] = sep + 3;\n        } else {\n            string_descriptors[0] = dev;\n            string_descriptors[1] = dev;\n        }\n    } else {\n        string_descriptors[0] = \"Unknown Corp.\";\n        string_descriptors[1] = \"PXT Device (app)\";\n    }\n\n    string_descriptors[2] = serial;\n    usb.stringDescriptors = string_descriptors;\n}\n\nvoid usb_init() {\n    usb.deviceDescriptor = &device_desc;\n    set_usb_strings(UF2_INFO_TXT);\n\n    platform_usb_init();\n\n    usb.add(hf2);\n\n#ifdef HF2_HID\n    hf2hid.useHID = true;\n    usb.add(hf2hid);\n#else\n    // the WINUSB descriptors don't seem to work if there's only one interface\n    // so we add a dummy interface\n    usb.add(dummyIface);\n#endif\n\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n    usb.add(mouse);\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n    usb.add(keyboard);\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n    usb.add(joystick);\n#endif\n\n    create_fiber(start_usb);\n}\n\n} // namespace pxt\n\n#else\nnamespace pxt {\nvoid usb_init() {}\n} // namespace pxt\n#endif\n\nnamespace control {\n/**\n * Determines if the USB has been enumerated.\n */\n//%\nbool isUSBInitialized() {\n#if CONFIG_ENABLED(DEVICE_USB)\n    return pxt::usb.isInitialised();\n#else\n    return false;\n#endif\n}\n} // namespace control\n\nnamespace pxt {\nstatic void (*pSendToUART)(const char *data, int len) = NULL;\nvoid setSendToUART(void (*f)(const char *, int)) {\n    pSendToUART = f;\n}\n\nvoid sendSerial(const char *data, int len) {\n#if CONFIG_ENABLED(DEVICE_USB)\n    hf2.sendSerial(data, len);\n#if HF2_HID\n    hf2hid.sendSerial(data, len);\n#endif\n#endif\n    if (pSendToUART)\n        pSendToUART(data, len);\n}\n\nvoid dumpDmesg() {\n    sendSerial(\"\\nDMESG:\\n\", 8);\n    sendSerial(codalLogStore.buffer, codalLogStore.ptr);\n    sendSerial(\"\\n\\n\", 2);\n}\n\nvoid (*logJDFrame)(const uint8_t *data);\nvoid (*sendJDFrame)(const uint8_t *data);\n\n} // namespace pxt\n"},"core---linux":{"Makefile":"include Makefile.inc\n\n\nCOMMON_FLAGS = -W -Wall -Wno-unused-parameter -Ipxtapp \\\n\t-fwrapv -fno-threadsafe-statics -ffunction-sections -O3 \\\n\t$(NPM_INCLUDES) -g\nLIBS = -lwiringPi -lm -lpthread -lrt -lasound\nCFLAGS = $(COMMON_FLAGS) -std=c99\nCXXFLAGS = $(COMMON_FLAGS) -std=c++11 -fno-rtti -fno-exceptions -fno-unwind-tables\nLDFLAGS = -Wl,--gc-sections -Wl,--sort-common -Wl,--sort-section=alignment -g -lwiringPi\nPREF = arm-linux-gnueabihf-\nCC = $(PREF)gcc\nLD = $(PREF)gcc\n#LIBSTDCPP = /usr/lib/gcc/arm-linux-gnueabi/4.9/libstdc++.a\nLIBSTDCPP = \nNPM_LIBS = $(wildcard node_modules/*/lib/*.a)\nNPM_INCLUDES = $(addprefix -I, $(wildcard node_modules/*/include))\n\nEXE = bld/pxt-app.elf\nHEX = $(EXE:.elf=.hex)\n\nDEPS = $(PXT_HEADERS) package.json Makefile Makefile.inc\n\nall: $(EXE)\n\n$(EXE): $(PXT_OBJS)\n\t$(LD) -o $(EXE) $(LDFLAGS) -Wl,-Map,$(EXE:.elf=.map) $(PXT_OBJS) $(LIBSTDCPP) $(LIBS) $(NPM_LIBS)\n\tcp $(EXE) $(EXE:.elf=.full)\n\t$(PREF)strip $(EXE)\n\tnode -p 'require(\"fs\").readFileSync(\"$(EXE)\").toString(\"hex\")' > $(HEX)\n\t@ls -l $(EXE)\n\nclean:\n\trm -rf bld\n\nbld/%.o: %.cpp $(DEPS)\n\t@mkdir -p $(dir $@)\n\t$(CC) $(CXXFLAGS) -c $< -o $@\n\nbld/%.o: %.s $(DEPS)\n\t@mkdir -p $(dir $@)\n\t$(CC) $(CFLAGS) -c $< -o $@\n\nbld/%.o: %.c $(DEPS)\n\t@mkdir -p $(dir $@)\n\t$(CC) $(CFLAGS) -c $< -o $@\n","README.md":"# core\n\nThe core library for Codal-based targets.\n\n","codalemu.cpp":"#include \"pxt.h\"\n#include <pthread.h>\n\nnamespace pxt {\n\nstatic pthread_mutex_t irqMutex;\nvoid target_disable_irq() {\n    pthread_mutex_lock(&irqMutex);\n}\nvoid target_enable_irq() {\n    pthread_mutex_unlock(&irqMutex);\n}\n\n} // namespace pxt\n\n","config.cpp":"#include \"pxt.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <ctype.h>\n\nnamespace pxt {\n\nstruct EnvConfig {\n    const char *name;\n    const char *value;\n    EnvConfig *next;\n};\n\nstatic EnvConfig *readEnvConfig(const char *name) {\n    FILE *f = fopen(name, \"r\");\n    DMESG(\"read config: %s %s\", name, !f ? \"missing!\" : \"\");\n    if (!f)\n        return NULL;\n    EnvConfig *res = NULL;\n    EnvConfig *endres = NULL;\n    for (;;) {\n        char *line = NULL;\n        size_t len = 0;\n        int llen = getline(&line, &len, f);\n        if (llen <= 0)\n            break;\n        char *p = line;\n        while (isspace(*p))\n            p++;\n        if (!*p || *p == '#') {\n            free(line);\n            continue;\n        }\n\n        auto name = p;\n        while (isalnum(*p) || strchr(\"-_.\", *p))\n            p++;\n        auto endName = p;\n        while (isspace(*p))\n            p++;\n        if (*p == '=' || *p == ':') {\n            p++;\n        } else {\n            free(line);\n            continue;\n        }\n        *endName = 0;\n        while (isspace(*p))\n            p++;\n\n        auto e = new EnvConfig;\n        e->name = name;\n        e->value = p;\n        e->next = endres;\n\n        if (*p) {\n            auto ep = p + strlen(p) - 1;\n            while (ep > p && isspace(*ep))\n                ep--;\n            ep++;\n            *ep = 0;\n        }\n\n        DMESG(\"%s=%s\", e->name, e->value);\n\n        if (endres == NULL) {\n            res = e;\n        } else {\n            endres->next = e;\n        }\n        e->next = NULL;\n        endres = e;\n    }\n    fclose(f);\n\n    return res;\n}\n\nstatic int gotConfig;\nstatic EnvConfig *envConfig;\nstatic void readConfig() {\n    if (gotConfig)\n        return;\n    gotConfig = 1;\n    envConfig = readEnvConfig(\"/sd/arcade.cfg\");\n    DMESG(\"config done\");\n}\nconst char *getConfigString(const char *name) {\n    readConfig();\n    for (auto p = envConfig; p; p = p->next) {\n        if (strcmp(p->name, name) == 0)\n            return p->value;\n    }\n    return NULL;\n}\nint getConfigInt(const char *name, int defl) {\n    auto v = getConfigString(name);\n    if (!v)\n        return defl;\n    sscanf(v, \"%d\", &defl);\n    return defl;\n}\n\nconst int *getConfigInts(const char *name) {\n    static int buf[30];\n\n    buf[0] = ENDMARK;\n\n    auto v = getConfigString(name);\n\n    if (!v)\n        return buf;\n\n    int bp = 0;\n\n    while (bp < 25) {\n        while (isspace(*v))\n            v++;\n        if (!*v)\n            break;\n        if (sscanf(v, \"%i\", &buf[bp]) != 1)\n            break;\n        while (*v && !isspace(*v) && *v != ',')\n            v++;\n        while (isspace(*v))\n            v++;\n        if (*v == ',')\n            v++;\n        bp++;\n    }\n    buf[bp] = ENDMARK;\n\n    // if (gotConfig++ < 20)\n    //    DMESG(\"%s - %d %d %d len=%d\", name, buf[0], buf[1], buf[2], bp);\n\n    return buf;\n}\n\n} // namespace pxt","control.cpp":"#include \"pxt.h\"\n\nnamespace control {\n\n/**\n * Announce that an event happened to registered handlers.\n * @param src ID of the Component that generated the event\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.\n */\n//% weight=21 blockGap=12 blockId=\"control_raise_event\"\n//% block=\"raise event|from %src|with value %value\" blockExternalInputs=1\n//% help=control/raise-event\nvoid raiseEvent(int src, int value) {\n    pxt::raiseEvent(src, value);\n}\n\n/**\n* Allocates the next user notification event\n*/\n//% help=control/allocate-notify-event\nint allocateNotifyEvent() {\n    return pxt::allocateNotifyEvent();\n}\n\n/**\n* Determine the version of system software currently running.\n*/\n//% blockId=\"control_device_dal_version\" block=\"device dal version\"\n//% help=control/device-dal-version\nString deviceDalVersion() {\n#ifdef PXT_VM\n    return mkString(\"vm\");\n#else\n    return mkString(\"linux\");\n#endif\n}\n\n\n/** Write data to DMESG debugging buffer. */\n//%\nvoid dmesg(String s) {\n    DMESG(\"# %s\", s->getUTF8Data());\n}\n\n//%\nuint32_t _ramSize()\n{\n#ifdef POKY\n    return 128 * 1024;\n#else\n    // a lot! doesn't really matter how much\n    return 16 * 1024 * 1024;\n#endif\n}\n\n/**\n * Determines if the USB has been enumerated.\n */\n//%\nbool isUSBInitialized() {\n    return false;\n}\n\n}\n\nnamespace serial {\n    /** Send DMESG debug buffer over serial. */\n    //%\n    void writeDmesg() {\n        pxt::dumpDmesg();\n    }\n}","dal.d.ts":"// Auto-generated. Do not edit.\ndeclare const enum DAL {\n    // /libraries/codal-core/inc/JACDAC/JACDAC.h\n    JD_VERSION = 5,\n    JD_SERIAL_MAX_BUFFERS = 10,\n    JD_SERIAL_RECEIVING = 2,\n    JD_SERIAL_TRANSMITTING = 4,\n    JD_SERIAL_TX_DRAIN_ENABLE = 8,\n    JD_SERIAL_BUS_RISE = 16,\n    JD_SERIAL_EVT_DATA_READY = 1,\n    JD_SERIAL_EVT_BUS_ERROR = 2,\n    JD_SERIAL_EVT_DRAIN = 3,\n    JD_SERIAL_EVT_RX_TIMEOUT = 4,\n    JD_SERIAL_EVT_BUS_CONNECTED = 5,\n    JD_SERIAL_EVT_BUS_DISCONNECTED = 6,\n    JD_SERIAL_HEADER_SIZE = 4,\n    JD_SERIAL_DATA_SIZE = 32,\n    JD_SERIAL_PACKET_SIZE = 36,\n    JD_SERIAL_MAXIMUM_BUFFERS = 10,\n    JD_SERIAL_DMA_TIMEOUT = 2,\n    JD_SERIAL_MAX_BAUD = 1000000,\n    JD_SERIAL_TX_MAX_BACKOFF = 4000,\n    JD_SERIAL_TX_MIN_BACKOFF = 1000,\n    Receiving = 0,\n    Transmitting = 1,\n    High = 2,\n    Low = 3,\n    Baud1M = 1,\n    Baud500K = 2,\n    Baud250K = 4,\n    Baud125K = 8,\n    // /libraries/codal-core/inc/JACDAC/JDAccelerometerDriver.h\n    JD_ACCEL_EVT_SEND_DATA = 1,\n    // /libraries/codal-core/inc/JACDAC/JDBridgeDriver.h\n    JD_BRIDGE_HISTORY_SIZE = 8,\n    // /libraries/codal-core/inc/JACDAC/JDClasses.h\n    STATIC_CLASS_START = 0,\n    STATIC_CLASS_END = 16777215,\n    DYNAMIC_CLASS_END = 4294967295,\n    JD_DRIVER_CLASS_CODAL_START = 0,\n    JD_DRIVER_CLASS_CODAL_END = 2000,\n    JD_DRIVER_CLASS_MAKECODE_START = 2000,\n    JD_DRIVER_CLASS_MAKECODE_END = 4000,\n    JD_DRIVER_CLASS_CONTROL = 0,\n    JD_DRIVER_CLASS_JOYSTICK = 1,\n    JD_DRIVER_CLASS_MESSAGE_BUS = 2,\n    JD_DRIVER_CLASS_BRIDGE = 3,\n    JD_DRIVER_CLASS_BUTTON = 4,\n    JD_DRIVER_CLASS_PIN = 5,\n    JD_DRIVER_CLASS_RELIABILITY_TESTER = 6,\n    JD_DRIVER_CLASS_ACCELEROMETER = 7,\n    JD_DRIVER_CLASS_CAPTOUCH_BUTTON = 8,\n    // /libraries/codal-core/inc/JACDAC/JDMessageBusDriver.h\n    JD_MESSAGEBUS_TYPE_EVENT = 1,\n    JD_MESSAGEBUS_TYPE_LISTEN = 2,\n    // /libraries/codal-core/inc/JACDAC/JDPinDriver.h\n    SetDigital = 0,\n    SetAnalog = 1,\n    SetServo = 2,\n    // /libraries/codal-core/inc/JACDAC/JDProtocol.h\n    JD_DRIVER_EVT_CONNECTED = 65520,\n    JD_DRIVER_EVT_DISCONNECTED = 65521,\n    JD_DRIVER_EVT_PAIRED = 65522,\n    JD_DRIVER_EVT_UNPAIRED = 65523,\n    JD_DRIVER_EVT_PAIR_REJECTED = 65524,\n    JD_DRIVER_EVT_PAIRING_RESPONSE = 65525,\n    JD_DRIVER_EVT_ERROR = 65526,\n    JD_DEVICE_FLAGS_LOCAL = 32768,\n    JD_DEVICE_FLAGS_REMOTE = 16384,\n    JD_DEVICE_FLAGS_BROADCAST = 8192,\n    JD_DEVICE_FLAGS_PAIR = 4096,\n    JD_DEVICE_DRIVER_MODE_MSK = 61440,\n    JD_DEVICE_FLAGS_PAIRABLE = 2048,\n    JD_DEVICE_FLAGS_PAIRED = 1024,\n    JD_DEVICE_FLAGS_PAIRING = 512,\n    JD_DEVICE_FLAGS_INITIALISED = 128,\n    JD_DEVICE_FLAGS_INITIALISING = 64,\n    JD_DEVICE_FLAGS_CP_SEEN = 32,\n    JD_DEVICE_ERROR_MSK = 15,\n    JD_LOGIC_DRIVER_MAX_FILTERS = 20,\n    JD_LOGIC_DRIVER_TIMEOUT = 254,\n    JD_LOGIC_ADDRESS_ALLOC_TIME = 254,\n    JD_LOGIC_DRIVER_CTRLPACKET_TIME = 112,\n    JD_LOGIC_DRIVER_EVT_CHANGED = 2,\n    CONTROL_JD_FLAGS_RESERVED = 32768,\n    CONTROL_JD_FLAGS_PAIRING_MODE = 16384,\n    CONTROL_JD_FLAGS_PAIRABLE = 8192,\n    CONTROL_JD_FLAGS_PAIRED = 4096,\n    CONTROL_JD_FLAGS_CONFLICT = 2048,\n    CONTROL_JD_FLAGS_UNCERTAIN = 1024,\n    CONTROL_JD_FLAGS_NACK = 512,\n    CONTROL_JD_FLAGS_ACK = 256,\n    CONTROL_JD_TYPE_HELLO = 1,\n    CONTROL_JD_TYPE_PAIRING_REQUEST = 2,\n    CONTROL_JD_TYPE_ERROR = 3,\n    CONTROL_JD_TYPE_PANIC = 255,\n    JD_PROTOCOL_EVT_SEND_CONTROL = 1,\n    JD_PROTOCOL_DRIVER_ARRAY_SIZE = 20,\n    CONTROL_PACKET_ERROR_NAME_LENGTH = 6,\n    VirtualDriver = 16384,\n    PairedDriver = 12288,\n    HostDriver = 32768,\n    PairableHostDriver = 34816,\n    BroadcastDriver = 40960,\n    SnifferDriver = 24576,\n    DRIVER_OK = 0,\n    DRIVER_CALIBRATION_IN_PROGRESS = 1,\n    DRIVER_CALIBRATION_REQUIRED = 2,\n    DRIVER_NO_RESOURCES = 3,\n    DRIVER_BUSY = 4,\n    DRIVER_COMMS_ERROR = 5,\n    DRIVER_INVALID_STATE = 6,\n    DRIVER_PERIPHERAL_MALFUNCTION = 7,\n    // /libraries/codal-core/inc/JACDAC/JDReliabilityTester.h\n    RELIABILITY_TEST_FINISHED = 7,\n    RELIABILITY_STATUS_TEST_IN_PROGRESS = 2,\n    RELIABILITY_STATUS_TEST_READY = 4,\n    RELIABILITY_STATUS_TEST_FINISHED = 8,\n    // /libraries/codal-core/inc/core/CodalComponent.h\n    DEVICE_ID_BUTTON_A = 1,\n    DEVICE_ID_BUTTON_B = 2,\n    DEVICE_ID_BUTTON_AB = 3,\n    DEVICE_ID_BUTTON_RESET = 4,\n    DEVICE_ID_ACCELEROMETER = 5,\n    DEVICE_ID_COMPASS = 6,\n    DEVICE_ID_DISPLAY = 7,\n    DEVICE_ID_THERMOMETER = 8,\n    DEVICE_ID_RADIO = 9,\n    DEVICE_ID_RADIO_DATA_READY = 10,\n    DEVICE_ID_MULTIBUTTON_ATTACH = 11,\n    DEVICE_ID_SERIAL = 12,\n    DEVICE_ID_GESTURE = 13,\n    DEVICE_ID_SYSTEM_TIMER = 14,\n    DEVICE_ID_SCHEDULER = 15,\n    DEVICE_ID_COMPONENT = 16,\n    DEVICE_ID_LIGHT_SENSOR = 17,\n    DEVICE_ID_TOUCH_SENSOR = 18,\n    DEVICE_ID_SYSTEM_DAC = 19,\n    DEVICE_ID_SYSTEM_MICROPHONE = 20,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR = 21,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR_SPL = 22,\n    DEVICE_ID_MSC = 23,\n    DEVICE_ID_SPI = 24,\n    DEVICE_ID_DISTANCE = 25,\n    DEVICE_ID_GYROSCOPE = 26,\n    DEVICE_ID_HUMIDITY = 27,\n    DEVICE_ID_PRESSURE = 28,\n    DEVICE_ID_JACDAC0 = 29,\n    DEVICE_ID_JACDAC1 = 30,\n    DEVICE_ID_JACDAC_PROTOCOL = 31,\n    DEVICE_ID_JACKROUTER = 32,\n    DEVICE_ID_GAME_ENGINE = 33,\n    DEVICE_ID_GAME_STATE_MANAGER = 34,\n    DEVICE_ID_SPRITE = 35,\n    DEVICE_ID_SINGLE_WIRE_SERIAL = 36,\n    DEVICE_ID_IO_P0 = 100,\n    DEVICE_ID_MESSAGE_BUS_LISTENER = 1021,\n    DEVICE_ID_NOTIFY_ONE = 1022,\n    DEVICE_ID_NOTIFY = 1023,\n    DEVICE_ID_BUTTON_UP = 2000,\n    DEVICE_ID_BUTTON_DOWN = 2001,\n    DEVICE_ID_BUTTON_LEFT = 2002,\n    DEVICE_ID_BUTTON_RIGHT = 2003,\n    DEVICE_ID_JD_DYNAMIC_ID = 3000,\n    DEVICE_COMPONENT_RUNNING = 4096,\n    DEVICE_COMPONENT_STATUS_SYSTEM_TICK = 8192,\n    DEVICE_COMPONENT_STATUS_IDLE_TICK = 16384,\n    DEVICE_COMPONENT_LISTENERS_CONFIGURED = 1,\n    DEVICE_COMPONENT_EVT_SYSTEM_TICK = 1,\n    // /libraries/codal-core/inc/core/CodalFiber.h\n    DEVICE_SCHEDULER_RUNNING = 1,\n    DEVICE_SCHEDULER_IDLE = 2,\n    DEVICE_FIBER_FLAG_FOB = 1,\n    DEVICE_FIBER_FLAG_PARENT = 2,\n    DEVICE_FIBER_FLAG_CHILD = 4,\n    DEVICE_FIBER_FLAG_DO_NOT_PAGE = 8,\n    DEVICE_SCHEDULER_EVT_TICK = 1,\n    DEVICE_SCHEDULER_EVT_IDLE = 2,\n    // /libraries/codal-core/inc/core/CodalListener.h\n    MESSAGE_BUS_LISTENER_PARAMETERISED = 1,\n    MESSAGE_BUS_LISTENER_METHOD = 2,\n    MESSAGE_BUS_LISTENER_BUSY = 4,\n    MESSAGE_BUS_LISTENER_REENTRANT = 8,\n    MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY = 16,\n    MESSAGE_BUS_LISTENER_DROP_IF_BUSY = 32,\n    MESSAGE_BUS_LISTENER_NONBLOCKING = 64,\n    MESSAGE_BUS_LISTENER_URGENT = 128,\n    MESSAGE_BUS_LISTENER_DELETING = 32768,\n    MESSAGE_BUS_LISTENER_IMMEDIATE = 192,\n    // /libraries/codal-core/inc/core/ErrorNo.h\n    DEVICE_OK = 0,\n    DEVICE_INVALID_PARAMETER = -1001,\n    DEVICE_NOT_SUPPORTED = -1002,\n    DEVICE_CALIBRATION_IN_PROGRESS = -1003,\n    DEVICE_CALIBRATION_REQUIRED = -1004,\n    DEVICE_NO_RESOURCES = -1005,\n    DEVICE_BUSY = -1006,\n    DEVICE_CANCELLED = -1007,\n    DEVICE_I2C_ERROR = -1010,\n    DEVICE_SERIAL_IN_USE = -1011,\n    DEVICE_NO_DATA = -1012,\n    DEVICE_NOT_IMPLEMENTED = -1013,\n    DEVICE_SPI_ERROR = -1014,\n    DEVICE_INVALID_STATE = -1015,\n    DEVICE_OOM = 20,\n    DEVICE_HEAP_ERROR = 30,\n    DEVICE_NULL_DEREFERENCE = 40,\n    DEVICE_USB_ERROR = 50,\n    DEVICE_HARDWARE_CONFIGURATION_ERROR = 90,\n    // /libraries/codal-core/inc/core/NotifyEvents.h\n    DISPLAY_EVT_FREE = 1,\n    CODAL_SERIAL_EVT_TX_EMPTY = 2,\n    BLE_EVT_SERIAL_TX_EMPTY = 3,\n    ARCADE_PLAYER_JOIN_RESULT = 4,\n    DEVICE_NOTIFY_USER_EVENT_BASE = 1024,\n    // /libraries/codal-core/inc/driver-models/AbstractButton.h\n    DEVICE_BUTTON_EVT_DOWN = 1,\n    DEVICE_BUTTON_EVT_UP = 2,\n    DEVICE_BUTTON_EVT_CLICK = 3,\n    DEVICE_BUTTON_EVT_LONG_CLICK = 4,\n    DEVICE_BUTTON_EVT_HOLD = 5,\n    DEVICE_BUTTON_EVT_DOUBLE_CLICK = 6,\n    DEVICE_BUTTON_LONG_CLICK_TIME = 1000,\n    DEVICE_BUTTON_HOLD_TIME = 1500,\n    DEVICE_BUTTON_STATE = 1,\n    DEVICE_BUTTON_STATE_HOLD_TRIGGERED = 2,\n    DEVICE_BUTTON_STATE_CLICK = 4,\n    DEVICE_BUTTON_STATE_LONG_CLICK = 8,\n    DEVICE_BUTTON_SIGMA_MIN = 0,\n    DEVICE_BUTTON_SIGMA_MAX = 12,\n    DEVICE_BUTTON_SIGMA_THRESH_HI = 8,\n    DEVICE_BUTTON_SIGMA_THRESH_LO = 2,\n    DEVICE_BUTTON_DOUBLE_CLICK_THRESH = 50,\n    DEVICE_BUTTON_SIMPLE_EVENTS = 0,\n    DEVICE_BUTTON_ALL_EVENTS = 1,\n    ACTIVE_LOW = 0,\n    ACTIVE_HIGH = 1,\n    // /libraries/codal-core/inc/driver-models/Accelerometer.h\n    ACCELEROMETER_IMU_DATA_VALID = 2,\n    ACCELEROMETER_EVT_DATA_UPDATE = 1,\n    ACCELEROMETER_EVT_NONE = 0,\n    ACCELEROMETER_EVT_TILT_UP = 1,\n    ACCELEROMETER_EVT_TILT_DOWN = 2,\n    ACCELEROMETER_EVT_TILT_LEFT = 3,\n    ACCELEROMETER_EVT_TILT_RIGHT = 4,\n    ACCELEROMETER_EVT_FACE_UP = 5,\n    ACCELEROMETER_EVT_FACE_DOWN = 6,\n    ACCELEROMETER_EVT_FREEFALL = 7,\n    ACCELEROMETER_EVT_3G = 8,\n    ACCELEROMETER_EVT_6G = 9,\n    ACCELEROMETER_EVT_8G = 10,\n    ACCELEROMETER_EVT_SHAKE = 11,\n    ACCELEROMETER_EVT_2G = 12,\n    ACCELEROMETER_REST_TOLERANCE = 200,\n    ACCELEROMETER_TILT_TOLERANCE = 200,\n    ACCELEROMETER_FREEFALL_TOLERANCE = 400,\n    ACCELEROMETER_SHAKE_TOLERANCE = 400,\n    ACCELEROMETER_2G_TOLERANCE = 2048,\n    ACCELEROMETER_3G_TOLERANCE = 3072,\n    ACCELEROMETER_6G_TOLERANCE = 6144,\n    ACCELEROMETER_8G_TOLERANCE = 8192,\n    ACCELEROMETER_GESTURE_DAMPING = 5,\n    ACCELEROMETER_SHAKE_DAMPING = 10,\n    ACCELEROMETER_SHAKE_RTX = 30,\n    ACCELEROMETER_SHAKE_COUNT_THRESHOLD = 4,\n    // /libraries/codal-core/inc/driver-models/Compass.h\n    COMPASS_STATUS_RUNNING = 1,\n    COMPASS_STATUS_CALIBRATED = 2,\n    COMPASS_STATUS_CALIBRATING = 4,\n    COMPASS_STATUS_ADDED_TO_IDLE = 8,\n    COMPASS_EVT_DATA_UPDATE = 1,\n    COMPASS_EVT_CONFIG_NEEDED = 2,\n    COMPASS_EVT_CALIBRATE = 3,\n    COMPASS_EVT_CALIBRATION_NEEDED = 4,\n    // /libraries/codal-core/inc/driver-models/Gyroscope.h\n    GYROSCOPE_IMU_DATA_VALID = 2,\n    GYROSCOPE_EVT_DATA_UPDATE = 1,\n    // /libraries/codal-core/inc/driver-models/LowLevelTimer.h\n    TimerModeTimer = 0,\n    TimerModeCounter = 1,\n    TimerModeAlternateFunction = 2,\n    BitMode8 = 0,\n    BitMode16 = 1,\n    BitMode24 = 2,\n    BitMode32 = 3,\n    // /libraries/codal-core/inc/driver-models/Pin.h\n    IO_STATUS_DIGITAL_IN = 1,\n    IO_STATUS_DIGITAL_OUT = 2,\n    IO_STATUS_ANALOG_IN = 4,\n    IO_STATUS_ANALOG_OUT = 8,\n    IO_STATUS_TOUCH_IN = 16,\n    IO_STATUS_EVENT_ON_EDGE = 32,\n    IO_STATUS_EVENT_PULSE_ON_EDGE = 64,\n    DEVICE_PIN_MAX_OUTPUT = 1023,\n    DEVICE_PIN_MAX_SERVO_RANGE = 180,\n    DEVICE_PIN_DEFAULT_SERVO_RANGE = 2000,\n    DEVICE_PIN_DEFAULT_SERVO_CENTER = 1500,\n    DEVICE_PIN_EVENT_NONE = 0,\n    DEVICE_PIN_EVENT_ON_EDGE = 1,\n    DEVICE_PIN_EVENT_ON_PULSE = 2,\n    DEVICE_PIN_EVENT_ON_TOUCH = 3,\n    DEVICE_PIN_EVT_RISE = 2,\n    DEVICE_PIN_EVT_FALL = 3,\n    DEVICE_PIN_EVT_PULSE_HI = 4,\n    DEVICE_PIN_EVT_PULSE_LO = 5,\n    PIN_CAPABILITY_DIGITAL = 1,\n    PIN_CAPABILITY_ANALOG = 2,\n    PIN_CAPABILITY_AD = 3,\n    PIN_CAPABILITY_ALL = 3,\n    None = 0,\n    Down = 1,\n    Up = 2,\n    // /libraries/codal-core/inc/driver-models/Radio.h\n    RADIO_EVT_DATA_READY = 2,\n    // /libraries/codal-core/inc/driver-models/SPIFlash.h\n    SPIFLASH_PAGE_SIZE = 256,\n    SPIFLASH_SMALL_ROW_PAGES = 16,\n    SPIFLASH_BIG_ROW_PAGES = 256,\n    // /libraries/codal-core/inc/driver-models/Sensor.h\n    SENSOR_THRESHOLD_LOW = 1,\n    SENSOR_THRESHOLD_HIGH = 2,\n    SENSOR_UPDATE_NEEDED = 3,\n    SENSOR_INITIALISED = 1,\n    SENSOR_HIGH_THRESHOLD_PASSED = 2,\n    SENSOR_LOW_THRESHOLD_PASSED = 4,\n    SENSOR_LOW_THRESHOLD_ENABLED = 8,\n    SENSOR_HIGH_THRESHOLD_ENABLED = 16,\n    SENSOR_DEFAULT_SENSITIVITY = 868,\n    SENSOR_DEFAULT_SAMPLE_PERIOD = 500,\n    // /libraries/codal-core/inc/driver-models/Serial.h\n    CODAL_SERIAL_DEFAULT_BAUD_RATE = 115200,\n    CODAL_SERIAL_DEFAULT_BUFFER_SIZE = 20,\n    CODAL_SERIAL_EVT_DELIM_MATCH = 1,\n    CODAL_SERIAL_EVT_HEAD_MATCH = 2,\n    CODAL_SERIAL_EVT_RX_FULL = 3,\n    CODAL_SERIAL_EVT_DATA_RECEIVED = 4,\n    CODAL_SERIAL_STATUS_RX_IN_USE = 1,\n    CODAL_SERIAL_STATUS_TX_IN_USE = 2,\n    CODAL_SERIAL_STATUS_RX_BUFF_INIT = 4,\n    CODAL_SERIAL_STATUS_TX_BUFF_INIT = 8,\n    CODAL_SERIAL_STATUS_RXD = 16,\n    ASYNC = 0,\n    SYNC_SPINWAIT = 1,\n    SYNC_SLEEP = 2,\n    RxInterrupt = 0,\n    TxInterrupt = 1,\n    // /libraries/codal-core/inc/driver-models/SingleWireSerial.h\n    SWS_EVT_DATA_RECEIVED = 1,\n    SWS_EVT_DATA_SENT = 2,\n    SWS_EVT_ERROR = 3,\n    SWS_EVT_DATA_DROPPED = 4,\n    SingleWireRx = 0,\n    SingleWireTx = 1,\n    SingleWireDisconnected = 2,\n    // /libraries/codal-core/inc/driver-models/Timer.h\n    CODAL_TIMER_DEFAULT_EVENT_LIST_SIZE = 10,\n    // /libraries/codal-core/inc/drivers/AnalogSensor.h\n    ANALOG_THRESHOLD_LOW = 1,\n    ANALOG_THRESHOLD_HIGH = 2,\n    ANALOG_SENSOR_UPDATE_NEEDED = 3,\n    ANALOG_SENSOR_INITIALISED = 1,\n    ANALOG_SENSOR_HIGH_THRESHOLD_PASSED = 2,\n    ANALOG_SENSOR_LOW_THRESHOLD_PASSED = 4,\n    ANALOG_SENSOR_LOW_THRESHOLD_ENABLED = 8,\n    ANALOG_SENSOR_HIGH_THRESHOLD_ENABLED = 16,\n    // /libraries/codal-core/inc/drivers/AnimatedDisplay.h\n    DISPLAY_EVT_ANIMATION_COMPLETE = 1,\n    DISPLAY_DEFAULT_AUTOCLEAR = 1,\n    DISPLAY_SPACING = 1,\n    DISPLAY_ANIMATE_DEFAULT_POS = -255,\n    DISPLAY_DEFAULT_SCROLL_SPEED = 120,\n    DISPLAY_DEFAULT_SCROLL_STRIDE = -1,\n    DISPLAY_DEFAULT_PRINT_SPEED = 400,\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    // /libraries/codal-core/inc/drivers/FAT.h\n    FAT_RESERVED_SECTORS = 1,\n    FAT_ROOT_DIR_SECTORS = 4,\n    // /libraries/codal-core/inc/drivers/HID.h\n    HID_REQUEST_GET_REPORT = 1,\n    HID_REQUEST_GET_IDLE = 2,\n    HID_REQUEST_GET_PROTOCOL = 3,\n    HID_REQUEST_SET_REPORT = 9,\n    HID_REQUEST_SET_IDLE = 10,\n    HID_REQUEST_SET_PROTOCOL = 11,\n    // /libraries/codal-core/inc/drivers/HIDKeyboard.h\n    HID_KEYBOARD_NUM_REPORTS = 3,\n    HID_KEYBOARD_REPORT_GENERIC = 1,\n    HID_KEYBOARD_REPORT_CONSUMER = 2,\n    HID_KEYBOARD_KEYSTATE_SIZE_GENERIC = 8,\n    HID_KEYBOARD_KEYSTATE_SIZE_CONSUMER = 2,\n    HID_KEYBOARD_MODIFIER_OFFSET = 2,\n    HID_KEYBOARD_DELAY_DEFAULT = 10,\n    PressKey = 0,\n    ReleaseKey = 1,\n    // /libraries/codal-core/inc/drivers/JackRouter.h\n    AllDown = 1,\n    HeadPhones = 2,\n    Buzzer = 3,\n    BuzzerAndSerial = 4,\n    // /libraries/codal-core/inc/drivers/KeyMap.h\n    KEYMAP_ALL_KEYS_UP_Val = 1,\n    KEYMAP_ALL_KEYS_UP_POS = 28,\n    KEYMAP_NORMAL_KEY_Val = 0,\n    KEYMAP_MODIFIER_KEY_Val = 1,\n    KEYMAP_MODIFIER_POS = 29,\n    KEYMAP_MEDIA_KEY_Val = 1,\n    KEYMAP_MEDIA_POS = 30,\n    KEYMAP_KEY_UP_Val = 0,\n    KEYMAP_KEY_DOWN_Val = 1,\n    KEYMAP_KEY_DOWN_POS = 31,\n    // /libraries/codal-core/inc/drivers/LEDMatrix.h\n    LED_MATRIX_GREYSCALE_BIT_DEPTH = 8,\n    LED_MATRIX_EVT_LIGHT_SENSE = 2,\n    LED_MATRIX_EVT_FRAME_TIMEOUT = 3,\n    LED_MATRIX_MINIMUM_BRIGHTNESS = 1,\n    LED_MATRIX_MAXIMUM_BRIGHTNESS = 255,\n    LED_MATRIX_DEFAULT_BRIGHTNESS = 255,\n    DISPLAY_MODE_BLACK_AND_WHITE = 0,\n    DISPLAY_MODE_GREYSCALE = 1,\n    DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE = 2,\n    MATRIX_DISPLAY_ROTATION_0 = 0,\n    MATRIX_DISPLAY_ROTATION_90 = 1,\n    MATRIX_DISPLAY_ROTATION_180 = 2,\n    MATRIX_DISPLAY_ROTATION_270 = 3,\n    NO_CONN = 0,\n    // /libraries/codal-core/inc/drivers/MAG3110.h\n    MAG3110_DEFAULT_ADDR = 29,\n    MAG_DR_STATUS = 0,\n    MAG_OUT_X_MSB = 1,\n    MAG_OUT_X_LSB = 2,\n    MAG_OUT_Y_MSB = 3,\n    MAG_OUT_Y_LSB = 4,\n    MAG_OUT_Z_MSB = 5,\n    MAG_OUT_Z_LSB = 6,\n    MAG_WHOAMI = 7,\n    MAG_SYSMOD = 8,\n    MAG_OFF_X_MSB = 9,\n    MAG_OFF_X_LSB = 10,\n    MAG_OFF_Y_MSB = 11,\n    MAG_OFF_Y_LSB = 12,\n    MAG_OFF_Z_MSB = 13,\n    MAG_OFF_Z_LSB = 14,\n    MAG_DIE_TEMP = 15,\n    MAG_CTRL_REG1 = 16,\n    MAG_CTRL_REG2 = 17,\n    MAG3110_SAMPLE_RATES = 11,\n    MAG3110_WHOAMI_VAL = 196,\n    // /libraries/codal-core/inc/drivers/MMA8453.h\n    MMA8453_DEFAULT_ADDR = 56,\n    MMA8453_WHOAMI_VAL = 58,\n    // /libraries/codal-core/inc/drivers/MMA8653.h\n    MICROBIT_ACCEL_PITCH_ROLL_VALID = 2,\n    MICROBIT_ACCEL_ADDED_TO_IDLE = 4,\n    MMA8653_DEFAULT_ADDR = 58,\n    MMA8653_STATUS = 0,\n    MMA8653_OUT_X_MSB = 1,\n    MMA8653_WHOAMI = 13,\n    MMA8653_XYZ_DATA_CFG = 14,\n    MMA8653_CTRL_REG1 = 42,\n    MMA8653_CTRL_REG2 = 43,\n    MMA8653_CTRL_REG3 = 44,\n    MMA8653_CTRL_REG4 = 45,\n    MMA8653_CTRL_REG5 = 46,\n    MMA8653_WHOAMI_VAL = 90,\n    MMA8653_SAMPLE_RANGES = 3,\n    MMA8653_SAMPLE_RATES = 8,\n    // /libraries/codal-core/inc/drivers/MPU6050.h\n    MPU6050_DEFAULT_ADDR = 104,\n    MPU6050_WHOAMI = 117,\n    MPU6050_WHOAMI_VAL = 52,\n    // /libraries/codal-core/inc/drivers/MultiButton.h\n    MULTI_BUTTON_STATE_1 = 1,\n    MULTI_BUTTON_STATE_2 = 2,\n    MULTI_BUTTON_HOLD_TRIGGERED_1 = 4,\n    MULTI_BUTTON_HOLD_TRIGGERED_2 = 8,\n    MULTI_BUTTON_SUPRESSED_1 = 16,\n    MULTI_BUTTON_SUPRESSED_2 = 32,\n    MULTI_BUTTON_ATTACHED = 64,\n    // /libraries/codal-core/inc/drivers/ST7735.h\n    MADCTL_MY = 128,\n    MADCTL_MX = 64,\n    MADCTL_MV = 32,\n    MADCTL_ML = 16,\n    MADCTL_RGB = 0,\n    MADCTL_BGR = 8,\n    MADCTL_MH = 4,\n    // /libraries/codal-core/inc/drivers/TouchButton.h\n    TOUCH_BUTTON_CALIBRATION_PERIOD = 10,\n    TOUCH_BUTTON_CALIBRATION_LINEAR_OFFSET = 2,\n    TOUCH_BUTTON_CALIBRATION_PERCENTAGE_OFFSET = 5,\n    TOUCH_BUTTON_CALIBRATING = 16,\n    // /libraries/codal-core/inc/drivers/TouchSensor.h\n    TOUCH_SENSOR_MAX_BUTTONS = 10,\n    TOUCH_SENSOR_SAMPLE_PERIOD = 50,\n    TOUCH_SENSE_SAMPLE_MAX = 1000,\n    TOUCH_SENSOR_UPDATE_NEEDED = 1,\n    // /libraries/codal-core/inc/drivers/USB_HID_Keys.h\n    KEY_MOD_LCTRL = 1,\n    KEY_MOD_LSHIFT = 2,\n    KEY_MOD_LALT = 4,\n    KEY_MOD_LMETA = 8,\n    KEY_MOD_RCTRL = 16,\n    KEY_MOD_RSHIFT = 32,\n    KEY_MOD_RALT = 64,\n    KEY_MOD_RMETA = 128,\n    KEY_NONE = 0,\n    KEY_ERR_OVF = 1,\n    KEY_A = 4,\n    KEY_B = 5,\n    KEY_C = 6,\n    KEY_D = 7,\n    KEY_E = 8,\n    KEY_F = 9,\n    KEY_G = 10,\n    KEY_H = 11,\n    KEY_I = 12,\n    KEY_J = 13,\n    KEY_K = 14,\n    KEY_L = 15,\n    KEY_M = 16,\n    KEY_N = 17,\n    KEY_O = 18,\n    KEY_P = 19,\n    KEY_Q = 20,\n    KEY_R = 21,\n    KEY_S = 22,\n    KEY_T = 23,\n    KEY_U = 24,\n    KEY_V = 25,\n    KEY_W = 26,\n    KEY_X = 27,\n    KEY_Y = 28,\n    KEY_Z = 29,\n    KEY_1 = 30,\n    KEY_2 = 31,\n    KEY_3 = 32,\n    KEY_4 = 33,\n    KEY_5 = 34,\n    KEY_6 = 35,\n    KEY_7 = 36,\n    KEY_8 = 37,\n    KEY_9 = 38,\n    KEY_0 = 39,\n    KEY_ENTER = 40,\n    KEY_ESC = 41,\n    KEY_BACKSPACE = 42,\n    KEY_TAB = 43,\n    KEY_SPACE = 44,\n    KEY_MINUS = 45,\n    KEY_EQUAL = 46,\n    KEY_LEFTBRACE = 47,\n    KEY_RIGHTBRACE = 48,\n    KEY_BACKSLASH = 49,\n    KEY_HASHTILDE = 50,\n    KEY_SEMICOLON = 51,\n    KEY_APOSTROPHE = 52,\n    KEY_GRAVE = 53,\n    KEY_COMMA = 54,\n    KEY_DOT = 55,\n    KEY_SLASH = 56,\n    KEY_CAPSLOCK = 57,\n    KEY_F1 = 58,\n    KEY_F2 = 59,\n    KEY_F3 = 60,\n    KEY_F4 = 61,\n    KEY_F5 = 62,\n    KEY_F6 = 63,\n    KEY_F7 = 64,\n    KEY_F8 = 65,\n    KEY_F9 = 66,\n    KEY_F10 = 67,\n    KEY_F11 = 68,\n    KEY_F12 = 69,\n    KEY_SYSRQ = 70,\n    KEY_SCROLLLOCK = 71,\n    KEY_PAUSE = 72,\n    KEY_INSERT = 73,\n    KEY_HOME = 74,\n    KEY_PAGEUP = 75,\n    KEY_DELETE = 76,\n    KEY_END = 77,\n    KEY_PAGEDOWN = 78,\n    KEY_RIGHT = 79,\n    KEY_LEFT = 80,\n    KEY_DOWN = 81,\n    KEY_UP = 82,\n    KEY_NUMLOCK = 83,\n    KEY_KPSLASH = 84,\n    KEY_KPASTERISK = 85,\n    KEY_KPMINUS = 86,\n    KEY_KPPLUS = 87,\n    KEY_KPENTER = 88,\n    KEY_KP1 = 89,\n    KEY_KP2 = 90,\n    KEY_KP3 = 91,\n    KEY_KP4 = 92,\n    KEY_KP5 = 93,\n    KEY_KP6 = 94,\n    KEY_KP7 = 95,\n    KEY_KP8 = 96,\n    KEY_KP9 = 97,\n    KEY_KP0 = 98,\n    KEY_KPDOT = 99,\n    KEY_102ND = 100,\n    KEY_COMPOSE = 101,\n    KEY_POWER = 102,\n    KEY_KPEQUAL = 103,\n    KEY_F13 = 104,\n    KEY_F14 = 105,\n    KEY_F15 = 106,\n    KEY_F16 = 107,\n    KEY_F17 = 108,\n    KEY_F18 = 109,\n    KEY_F19 = 110,\n    KEY_F20 = 111,\n    KEY_F21 = 112,\n    KEY_F22 = 113,\n    KEY_F23 = 114,\n    KEY_F24 = 115,\n    KEY_OPEN = 116,\n    KEY_HELP = 117,\n    KEY_PROPS = 118,\n    KEY_FRONT = 119,\n    KEY_STOP = 120,\n    KEY_AGAIN = 121,\n    KEY_UNDO = 122,\n    KEY_CUT = 123,\n    KEY_COPY = 124,\n    KEY_PASTE = 125,\n    KEY_FIND = 126,\n    KEY_MUTE = 127,\n    KEY_VOLUMEUP = 128,\n    KEY_VOLUMEDOWN = 129,\n    KEY_KPCOMMA = 133,\n    KEY_RO = 135,\n    KEY_KATAKANAHIRAGANA = 136,\n    KEY_YEN = 137,\n    KEY_HENKAN = 138,\n    KEY_MUHENKAN = 139,\n    KEY_KPJPCOMMA = 140,\n    KEY_HANGEUL = 144,\n    KEY_HANJA = 145,\n    KEY_KATAKANA = 146,\n    KEY_HIRAGANA = 147,\n    KEY_ZENKAKUHANKAKU = 148,\n    KEY_KPLEFTPAREN = 182,\n    KEY_KPRIGHTPAREN = 183,\n    KEY_LEFTCTRL = 224,\n    KEY_LEFTSHIFT = 225,\n    KEY_LEFTALT = 226,\n    KEY_LEFTMETA = 227,\n    KEY_RIGHTCTRL = 228,\n    KEY_RIGHTSHIFT = 229,\n    KEY_RIGHTALT = 230,\n    KEY_RIGHTMETA = 231,\n    KEY_MEDIA_PLAYPAUSE = 232,\n    KEY_MEDIA_STOPCD = 233,\n    KEY_MEDIA_PREVIOUSSONG = 234,\n    KEY_MEDIA_NEXTSONG = 235,\n    KEY_MEDIA_EJECTCD = 236,\n    KEY_MEDIA_VOLUMEUP = 237,\n    KEY_MEDIA_VOLUMEDOWN = 238,\n    KEY_MEDIA_MUTE = 239,\n    KEY_MEDIA_WWW = 240,\n    KEY_MEDIA_BACK = 241,\n    KEY_MEDIA_FORWARD = 242,\n    KEY_MEDIA_STOP = 243,\n    KEY_MEDIA_FIND = 244,\n    KEY_MEDIA_SCROLLUP = 245,\n    KEY_MEDIA_SCROLLDOWN = 246,\n    KEY_MEDIA_EDIT = 247,\n    KEY_MEDIA_SLEEP = 248,\n    KEY_MEDIA_COFFEE = 249,\n    KEY_MEDIA_REFRESH = 250,\n    KEY_MEDIA_CALC = 251,\n    // /libraries/codal-core/inc/drivers/uf2format.h\n    UF2FORMAT_H = 1,\n    APP_START_ADDRESS = 8192,\n    UF2_FLAG_NOFLASH = 1,\n    // /libraries/codal-core/inc/streams/DataStream.h\n    DATASTREAM_MAXIMUM_BUFFERS = 1,\n    // /libraries/codal-core/inc/streams/LevelDetector.h\n    LEVEL_THRESHOLD_LOW = 1,\n    LEVEL_THRESHOLD_HIGH = 2,\n    LEVEL_DETECTOR_INITIALISED = 1,\n    LEVEL_DETECTOR_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_DEFAULT_WINDOW_SIZE = 128,\n    // /libraries/codal-core/inc/streams/LevelDetectorSPL.h\n    LEVEL_DETECTOR_SPL_INITIALISED = 1,\n    LEVEL_DETECTOR_SPL_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_SPL_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_SPL_DEFAULT_WINDOW_SIZE = 128,\n    // /libraries/codal-core/inc/streams/Synthesizer.h\n    SYNTHESIZER_SAMPLE_RATE = 44100,\n    TONE_WIDTH = 1024,\n    // /libraries/codal-core/inc/types/BitmapFont.h\n    BITMAP_FONT_WIDTH = 5,\n    BITMAP_FONT_HEIGHT = 5,\n    BITMAP_FONT_ASCII_START = 32,\n    BITMAP_FONT_ASCII_END = 126,\n    // /libraries/codal-core/inc/types/CoordinateSystem.h\n    COORDINATE_SPACE_ROTATED_0 = 0,\n    COORDINATE_SPACE_ROTATED_90 = 1,\n    COORDINATE_SPACE_ROTATED_180 = 2,\n    COORDINATE_SPACE_ROTATED_270 = 3,\n    RAW = 0,\n    SIMPLE_CARTESIAN = 1,\n    NORTH_EAST_DOWN = 2,\n    NORTH_EAST_UP = 3,\n    // /libraries/codal-core/inc/types/Event.h\n    DEVICE_ID_ANY = 0,\n    DEVICE_EVT_ANY = 0,\n    CREATE_ONLY = 0,\n    CREATE_AND_FIRE = 1,\n    DEVICE_EVENT_DEFAULT_LAUNCH_MODE = 1,\n    // /libraries/codal-core/inc/types/RefCounted.h\n    REF_TAG_STRING = 1,\n    REF_TAG_BUFFER = 2,\n    REF_TAG_IMAGE = 3,\n    REF_TAG_USER = 32,\n    // /pxtapp/configkeys.h\n    CFG_PIN_NAME_MSK = 65535,\n    CFG_PIN_CONFIG_MSK = 4294901760,\n    CFG_PIN_CONFIG_ACTIVE_LO = 65536,\n    CFG_MAGIC0 = 513675505,\n    CFG_MAGIC1 = 539130489,\n    CFG_PIN_ACCELEROMETER_INT = 1,\n    CFG_PIN_ACCELEROMETER_SCL = 2,\n    CFG_PIN_ACCELEROMETER_SDA = 3,\n    CFG_PIN_BTN_A = 4,\n    CFG_PIN_BTN_B = 5,\n    CFG_PIN_BTN_SLIDE = 6,\n    CFG_PIN_DOTSTAR_CLOCK = 7,\n    CFG_PIN_DOTSTAR_DATA = 8,\n    CFG_PIN_FLASH_CS = 9,\n    CFG_PIN_FLASH_MISO = 10,\n    CFG_PIN_FLASH_MOSI = 11,\n    CFG_PIN_FLASH_SCK = 12,\n    CFG_PIN_LED = 13,\n    CFG_PIN_LIGHT = 14,\n    CFG_PIN_MICROPHONE = 15,\n    CFG_PIN_MIC_CLOCK = 16,\n    CFG_PIN_MIC_DATA = 17,\n    CFG_PIN_MISO = 18,\n    CFG_PIN_MOSI = 19,\n    CFG_PIN_NEOPIXEL = 20,\n    CFG_PIN_RX = 21,\n    CFG_PIN_RXLED = 22,\n    CFG_PIN_SCK = 23,\n    CFG_PIN_SCL = 24,\n    CFG_PIN_SDA = 25,\n    CFG_PIN_SPEAKER_AMP = 26,\n    CFG_PIN_TEMPERATURE = 27,\n    CFG_PIN_TX = 28,\n    CFG_PIN_TXLED = 29,\n    CFG_PIN_IR_OUT = 30,\n    CFG_PIN_IR_IN = 31,\n    CFG_PIN_DISPLAY_SCK = 32,\n    CFG_PIN_DISPLAY_MISO = 33,\n    CFG_PIN_DISPLAY_MOSI = 34,\n    CFG_PIN_DISPLAY_CS = 35,\n    CFG_PIN_DISPLAY_DC = 36,\n    CFG_DISPLAY_WIDTH = 37,\n    CFG_DISPLAY_HEIGHT = 38,\n    CFG_DISPLAY_CFG0 = 39,\n    CFG_DISPLAY_CFG1 = 40,\n    CFG_DISPLAY_CFG2 = 41,\n    CFG_DISPLAY_CFG3 = 42,\n    CFG_PIN_DISPLAY_RST = 43,\n    CFG_PIN_DISPLAY_BL = 44,\n    CFG_PIN_SERVO_1 = 45,\n    CFG_PIN_SERVO_2 = 46,\n    CFG_PIN_BTN_LEFT = 47,\n    CFG_PIN_BTN_RIGHT = 48,\n    CFG_PIN_BTN_UP = 49,\n    CFG_PIN_BTN_DOWN = 50,\n    CFG_PIN_BTN_MENU = 51,\n    CFG_PIN_LED_R = 52,\n    CFG_PIN_LED_G = 53,\n    CFG_PIN_LED_B = 54,\n    CFG_PIN_LED1 = 55,\n    CFG_PIN_LED2 = 56,\n    CFG_PIN_LED3 = 57,\n    CFG_PIN_LED4 = 58,\n    CFG_SPEAKER_VOLUME = 59,\n    CFG_PIN_JACK_TX = 60,\n    CFG_PIN_JACK_SENSE = 61,\n    CFG_PIN_JACK_HPEN = 62,\n    CFG_PIN_JACK_BZEN = 63,\n    CFG_PIN_JACK_PWREN = 64,\n    CFG_PIN_JACK_SND = 65,\n    CFG_PIN_JACK_BUSLED = 66,\n    CFG_PIN_JACK_COMMLED = 67,\n    CFG_PIN_BTN_SOFT_RESET = 69,\n    CFG_ACCELEROMETER_TYPE = 70,\n    CFG_PIN_BTNMX_LATCH = 71,\n    CFG_PIN_BTNMX_CLOCK = 72,\n    CFG_PIN_BTNMX_DATA = 73,\n    CFG_PIN_BTN_MENU2 = 74,\n    CFG_PIN_BATTSENSE = 75,\n    CFG_PIN_VIBRATION = 76,\n    CFG_PIN_PWREN = 77,\n    CFG_PIN_ROTARY_ENCODER_A = 79,\n    CFG_PIN_ROTARY_ENCODER_B = 80,\n    CFG_PIN_WIFI_MOSI = 82,\n    CFG_PIN_WIFI_MISO = 83,\n    CFG_PIN_WIFI_SCK = 84,\n    CFG_PIN_WIFI_TX = 85,\n    CFG_PIN_WIFI_RX = 86,\n    CFG_PIN_WIFI_CS = 87,\n    CFG_PIN_WIFI_BUSY = 88,\n    CFG_PIN_WIFI_RESET = 89,\n    CFG_PIN_WIFI_GPIO0 = 90,\n    ACCELEROMETER_TYPE_LIS3DH = 50,\n    ACCELEROMETER_TYPE_MMA8453 = 56,\n    ACCELEROMETER_TYPE_FXOS8700 = 60,\n    ACCELEROMETER_TYPE_MMA8653 = 58,\n    ACCELEROMETER_TYPE_MSA300 = 76,\n    ACCELEROMETER_TYPE_MPU6050 = 104,\n    CFG_PIN_A0 = 100,\n    CFG_PIN_A1 = 101,\n    CFG_PIN_A2 = 102,\n    CFG_PIN_A3 = 103,\n    CFG_PIN_A4 = 104,\n    CFG_PIN_A5 = 105,\n    CFG_PIN_A6 = 106,\n    CFG_PIN_A7 = 107,\n    CFG_PIN_A8 = 108,\n    CFG_PIN_A9 = 109,\n    CFG_PIN_A10 = 110,\n    CFG_PIN_A11 = 111,\n    CFG_PIN_A12 = 112,\n    CFG_PIN_A13 = 113,\n    CFG_PIN_A14 = 114,\n    CFG_PIN_A15 = 115,\n    CFG_PIN_A16 = 116,\n    CFG_PIN_A17 = 117,\n    CFG_PIN_A18 = 118,\n    CFG_PIN_A19 = 119,\n    CFG_PIN_A20 = 120,\n    CFG_PIN_A21 = 121,\n    CFG_PIN_A22 = 122,\n    CFG_PIN_A23 = 123,\n    CFG_PIN_A24 = 124,\n    CFG_PIN_A25 = 125,\n    CFG_PIN_A26 = 126,\n    CFG_PIN_A27 = 127,\n    CFG_PIN_A28 = 128,\n    CFG_PIN_A29 = 129,\n    CFG_PIN_A30 = 130,\n    CFG_PIN_A31 = 131,\n    CFG_PIN_D0 = 150,\n    CFG_PIN_D1 = 151,\n    CFG_PIN_D2 = 152,\n    CFG_PIN_D3 = 153,\n    CFG_PIN_D4 = 154,\n    CFG_PIN_D5 = 155,\n    CFG_PIN_D6 = 156,\n    CFG_PIN_D7 = 157,\n    CFG_PIN_D8 = 158,\n    CFG_PIN_D9 = 159,\n    CFG_PIN_D10 = 160,\n    CFG_PIN_D11 = 161,\n    CFG_PIN_D12 = 162,\n    CFG_PIN_D13 = 163,\n    CFG_PIN_D14 = 164,\n    CFG_PIN_D15 = 165,\n    CFG_PIN_D16 = 166,\n    CFG_PIN_D17 = 167,\n    CFG_PIN_D18 = 168,\n    CFG_PIN_D19 = 169,\n    CFG_PIN_D20 = 170,\n    CFG_PIN_D21 = 171,\n    CFG_PIN_D22 = 172,\n    CFG_PIN_D23 = 173,\n    CFG_PIN_D24 = 174,\n    CFG_PIN_D25 = 175,\n    CFG_PIN_D26 = 176,\n    CFG_PIN_D27 = 177,\n    CFG_PIN_D28 = 178,\n    CFG_PIN_D29 = 179,\n    CFG_PIN_D30 = 180,\n    CFG_PIN_D31 = 181,\n    CFG_NUM_NEOPIXELS = 200,\n    CFG_NUM_DOTSTARS = 201,\n    CFG_DEFAULT_BUTTON_MODE = 202,\n    CFG_SWD_ENABLED = 203,\n    CFG_FLASH_BYTES = 204,\n    CFG_RAM_BYTES = 205,\n    CFG_SYSTEM_HEAP_BYTES = 206,\n    CFG_LOW_MEM_SIMULATION_KB = 207,\n    CFG_BOOTLOADER_BOARD_ID = 208,\n    CFG_UF2_FAMILY = 209,\n    CFG_PINS_PORT_SIZE = 210,\n    CFG_BOOTLOADER_PROTECTION = 211,\n    CFG_POWER_DEEPSLEEP_TIMEOUT = 212,\n    CFG_ANALOG_BUTTON_THRESHOLD = 213,\n    CFG_CONTROLLER_LIGHT_MAX_BRIGHTNESS = 215,\n    CFG_PIN_B0 = 300,\n    CFG_PIN_B1 = 301,\n    CFG_PIN_B2 = 302,\n    CFG_PIN_B3 = 303,\n    CFG_PIN_B4 = 304,\n    CFG_PIN_B5 = 305,\n    CFG_PIN_B6 = 306,\n    CFG_PIN_B7 = 307,\n    CFG_PIN_B8 = 308,\n    CFG_PIN_B9 = 309,\n    CFG_PIN_B10 = 310,\n    CFG_PIN_B11 = 311,\n    CFG_PIN_B12 = 312,\n    CFG_PIN_B13 = 313,\n    CFG_PIN_B14 = 314,\n    CFG_PIN_B15 = 315,\n    CFG_PIN_B16 = 316,\n    CFG_PIN_B17 = 317,\n    CFG_PIN_B18 = 318,\n    CFG_PIN_B19 = 319,\n    CFG_PIN_B20 = 320,\n    CFG_PIN_B21 = 321,\n    CFG_PIN_B22 = 322,\n    CFG_PIN_B23 = 323,\n    CFG_PIN_B24 = 324,\n    CFG_PIN_B25 = 325,\n    CFG_PIN_B26 = 326,\n    CFG_PIN_B27 = 327,\n    CFG_PIN_B28 = 328,\n    CFG_PIN_B29 = 329,\n    CFG_PIN_B30 = 330,\n    CFG_PIN_B31 = 331,\n    CFG_PIN_C0 = 350,\n    CFG_PIN_C1 = 351,\n    CFG_PIN_C2 = 352,\n    CFG_PIN_C3 = 353,\n    CFG_PIN_C4 = 354,\n    CFG_PIN_C5 = 355,\n    CFG_PIN_C6 = 356,\n    CFG_PIN_C7 = 357,\n    CFG_PIN_C8 = 358,\n    CFG_PIN_C9 = 359,\n    CFG_PIN_C10 = 360,\n    CFG_PIN_C11 = 361,\n    CFG_PIN_C12 = 362,\n    CFG_PIN_C13 = 363,\n    CFG_PIN_C14 = 364,\n    CFG_PIN_C15 = 365,\n    CFG_PIN_C16 = 366,\n    CFG_PIN_C17 = 367,\n    CFG_PIN_C18 = 368,\n    CFG_PIN_C19 = 369,\n    CFG_PIN_C20 = 370,\n    CFG_PIN_C21 = 371,\n    CFG_PIN_C22 = 372,\n    CFG_PIN_C23 = 373,\n    CFG_PIN_C24 = 374,\n    CFG_PIN_C25 = 375,\n    CFG_PIN_C26 = 376,\n    CFG_PIN_C27 = 377,\n    CFG_PIN_C28 = 378,\n    CFG_PIN_C29 = 379,\n    CFG_PIN_C30 = 380,\n    CFG_PIN_C31 = 381,\n    CFG_PIN_P0 = 400,\n    CFG_PIN_P1 = 401,\n    CFG_PIN_P2 = 402,\n    CFG_PIN_P3 = 403,\n    CFG_PIN_P4 = 404,\n    CFG_PIN_P5 = 405,\n    CFG_PIN_P6 = 406,\n    CFG_PIN_P7 = 407,\n    CFG_PIN_P8 = 408,\n    CFG_PIN_P9 = 409,\n    CFG_PIN_P10 = 410,\n    CFG_PIN_P11 = 411,\n    CFG_PIN_P12 = 412,\n    CFG_PIN_P13 = 413,\n    CFG_PIN_P14 = 414,\n    CFG_PIN_P15 = 415,\n    CFG_PIN_P16 = 416,\n    CFG_PIN_P17 = 417,\n    CFG_PIN_P18 = 418,\n    CFG_PIN_P19 = 419,\n    CFG_PIN_P20 = 420,\n    CFG_PIN_LORA_MISO = 1001,\n    CFG_PIN_LORA_MOSI = 1002,\n    CFG_PIN_LORA_SCK = 1003,\n    CFG_PIN_LORA_CS = 1004,\n    CFG_PIN_LORA_BOOT = 1005,\n    CFG_PIN_LORA_RESET = 1006,\n    CFG_PIN_IRRXLED = 1007,\n    CFG_PIN_IRTXLED = 1008,\n    CFG_PIN_LCD_RESET = 1009,\n    CFG_PIN_LCD_ENABLE = 1010,\n    CFG_PIN_LCD_DATALINE4 = 1011,\n    CFG_PIN_LCD_DATALINE5 = 1012,\n    CFG_PIN_LCD_DATALINE6 = 1013,\n    CFG_PIN_LCD_DATALINE7 = 1014,\n    CFG_NUM_LCD_COLUMNS = 1015,\n    CFG_NUM_LCD_ROWS = 1016,\n\n    CFG_USER_CFG_0 = 2000,\n    CFG_USER_CFG_1 = 2001,\n    CFG_USER_CFG_2 = 2002,\n    CFG_USER_CFG_3 = 2003,\n    CFG_USER_CFG_4 = 2004,\n    CFG_USER_CFG_5 = 2005,\n    CFG_USER_CFG_6 = 2006,\n    CFG_USER_CFG_7 = 2007,\n    CFG_USER_CFG_8 = 2008,\n    CFG_USER_CFG_9 = 2009,\n    CFG_ARCADE_CFG_0 = 2100,\n    CFG_ARCADE_CFG_1 = 2101,\n    CFG_ARCADE_SCREEN_WIDTH = 2102,\n    CFG_ARCADE_SCREEN_HEIGHT = 2103,\n\n    // /pxtapp/hf2dbg.h\n    HF2DBG_H = 1,\n    // /pxtapp/pins.h\n    BUTTON_ACTIVE_HIGH_PULL_DOWN = 17,\n    BUTTON_ACTIVE_HIGH_PULL_UP = 33,\n    BUTTON_ACTIVE_HIGH_PULL_NONE = 49,\n    BUTTON_ACTIVE_LOW_PULL_DOWN = 16,\n    BUTTON_ACTIVE_LOW_PULL_UP = 32,\n    BUTTON_ACTIVE_LOW_PULL_NONE = 48,\n    // /pxtapp/platform.h\n    SETTINGS_MAGIC_0 = 273114691,\n    SETTINGS_MAGIC_1 = 781864998,\n    BOOT_RTC_SIGNATURE = 1906448503,\n    APP_RTC_SIGNATURE = 614608146,\n    PAGE_SIZE = 1024,\n    DEV_NUM_PINS = 64,\n    IMAGE_BITS = 4,\n    PA_0 = 0,\n    PA_1 = 1,\n    PA_2 = 2,\n    PA_3 = 3,\n    PA_4 = 4,\n    PA_5 = 5,\n    PA_6 = 6,\n    PA_7 = 7,\n    PA_8 = 8,\n    PA_9 = 9,\n    PA_10 = 10,\n    PA_11 = 11,\n    PA_12 = 12,\n    PA_13 = 13,\n    PA_14 = 14,\n    PA_15 = 15,\n    PB_0 = 16,\n    PB_1 = 17,\n    PB_2 = 18,\n    PB_3 = 19,\n    PB_4 = 20,\n    PB_5 = 21,\n    PB_6 = 22,\n    PB_7 = 23,\n    PB_8 = 24,\n    PB_9 = 25,\n    PB_10 = 26,\n    PB_11 = 27,\n    PB_12 = 28,\n    PB_13 = 29,\n    PB_14 = 30,\n    PB_15 = 31,\n    PC_0 = 32,\n    PC_1 = 33,\n    PC_2 = 34,\n    PC_3 = 35,\n    PC_4 = 36,\n    PC_5 = 37,\n    PC_6 = 38,\n    PC_7 = 39,\n    PC_8 = 40,\n    PC_9 = 41,\n    PC_10 = 42,\n    PC_11 = 43,\n    PC_12 = 44,\n    PC_13 = 45,\n    PC_14 = 46,\n    PC_15 = 47,\n    PD_0 = 48,\n    PD_1 = 49,\n    PD_2 = 50,\n    PD_3 = 51,\n    PD_4 = 52,\n    PD_5 = 53,\n    PD_6 = 54,\n    PD_7 = 55,\n    PD_8 = 56,\n    PD_9 = 57,\n    PD_10 = 58,\n    PD_11 = 59,\n    PD_12 = 60,\n    PD_13 = 61,\n    PD_14 = 62,\n    PD_15 = 63,\n    // /pxtapp/pxt.h\n    DEVICE_ID_BUTTON_SLIDE = 3000,\n    DEVICE_ID_MICROPHONE = 3001,\n    DEVICE_ID_FIRST_BUTTON = 4000,\n    DEVICE_ID_FIRST_TOUCHBUTTON = 4100,\n    // /pxtapp/pxtbase.h\n    PXT_REFCNT_FLASH = 65534,\n    VTABLE_MAGIC = 249,\n    Undefined = 0,\n    Boolean = 1,\n    Number = 2,\n    String = 3,\n    Object = 4,\n    Function = 5,\n    BoxedString = 1,\n    BoxedNumber = 2,\n    BoxedBuffer = 3,\n    RefAction = 4,\n    RefImage = 5,\n    RefCollection = 6,\n    RefRefLocal = 7,\n    RefMap = 8,\n    RefMImage = 9,\n    User0 = 16,\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    UInt32LE = 11,\n    UInt32BE = 12,\n    Float32LE = 13,\n    Float64LE = 14,\n    Float32BE = 15,\n    Float64BE = 16,\n    GC = 0,\n    // /pxtapp/pxtconfig.h\n    PXT_GC = 1,\n    PXT_UF2_FAMILY = 1591873650,\n    // /pxtapp/uf2hid.h\n    UF2_HID_H = 1,\n}\n","dmesg.cpp":"#include \"pxt.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <signal.h>\n#include <stdarg.h>\n#include <fcntl.h>\n\nstatic FILE *dmesgFile;\n\nstatic int dmesgPtr;\nstatic int dmesgSerialPtr;\nstatic char dmesgBuf[4096];\n\nvoid pxt::dumpDmesg() {\n    auto len = dmesgPtr - dmesgSerialPtr;\n    if (len == 0)\n        return;\n    sendSerial(dmesgBuf + dmesgSerialPtr, len);\n    dmesgSerialPtr = dmesgPtr;\n}\n\n\nstatic void dmesgRaw(const char *buf, uint32_t len) {\n    if (!dmesgFile) {\n        dmesgFile = fopen(\"/tmp/dmesg.txt\", \"w\");\n        if (!dmesgFile)\n            dmesgFile = stderr;\n    }\n\n    if (len > sizeof(dmesgBuf) / 2)\n        return;\n    if (dmesgPtr + len > sizeof(dmesgBuf)) {\n        dmesgPtr = 0;\n        dmesgSerialPtr = 0;\n    }\n    memcpy(dmesgBuf + dmesgPtr, buf, len);\n    dmesgPtr += len;\n    fwrite(buf, 1, len, dmesgFile);\n\n    fwrite(buf, 1, len, stderr);\n}\n\nstatic void dmesgFlushRaw() {\n    fflush(dmesgFile);\n\n#ifdef __linux__\n    // we only really care on RPi, so it may reboot/crash and we would like to see this file\n    fdatasync(fileno(dmesgFile));\n#else\n    //fsync(fileno(dmesgFile));\n#endif\n}\n\nextern \"C\" void vdmesg(const char *format, va_list arg) {\n    char buf[500];\n\n    snprintf(buf, sizeof(buf), \"[%8d] \", current_time_ms());\n    dmesgRaw(buf, strlen(buf));\n    vsnprintf(buf, sizeof(buf), format, arg);\n    dmesgRaw(buf, strlen(buf));\n    dmesgRaw(\"\\n\", 1);\n\n    dmesgFlushRaw();\n}\n\nextern \"C\" void dmesg(const char *format, ...) {\n    va_list arg;\n    va_start(arg, format);\n    vdmesg(format, arg);\n    va_end(arg);\n}\n\n","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum PulseValue {\n    //% block=high\n    High = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=low\n    Low = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    }\n\n\n    declare const enum PinEvent {\n    //% block=\"pulse high\"\n    PulseHigh = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=\"pulse low\"\n    PulseLow = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    //% block=\"rise\"\n    Rise = 2,  // DEVICE_PIN_EVT_RISE\n    //% block=\"fall\"\n    Fall = 3,  // DEVICE_PIN_EVT_FALL\n    }\n\n\n    declare const enum PinPullMode {\n    //% block=\"down\"\n    PullDown = 0,\n    //% block=\"up\"\n    PullUp = 1,\n    //% block=\"none\"\n    PullNone = 2,\n    }\n\n// Auto-generated. Do not edit. Really.\n","linux.cpp":"#include \"pxt.h\"\n\n#include <stdlib.h>\n#include <stdio.h>\n#include <sys/time.h>\n#include <time.h>\n#include <pthread.h>\n#include <unistd.h>\n#include <signal.h>\n#include <sys/types.h>\n#include <sys/mman.h>\n#include <errno.h>\n\n#if defined(__linux__) && !defined(POKY)\n#include <malloc.h>\n#define MALLOC_STATS\n#endif\n\n// should this be something like CXX11 or whatever?\n#ifdef PXT_VM\n#define THROW throw()\n#else\n#define THROW /* nothing */\n#endif\n\n#define THREAD_DBG(...)\n\n#define MALLOC_LIMIT (8 * 1024 * 1024)\n#define MALLOC_CHECK_PERIOD (1024 * 1024)\n\nvoid *xmalloc(size_t sz) {\n#ifdef MALLOC_STATS\n    static size_t allocBytes = 0;\n    allocBytes += sz;\n    if (allocBytes >= MALLOC_CHECK_PERIOD) {\n        allocBytes = 0;\n        auto info = mallinfo();\n        // DMESG(\"malloc used: %d kb\", info.uordblks / 1024);\n        if (info.uordblks > MALLOC_LIMIT) {\n            soft_panic(PANIC_MEMORY_LIMIT_EXCEEDED);\n        }\n    }\n#endif\n    auto r = malloc(sz);\n    if (r == NULL)\n        oops(50); // shouldn't happen\n    return r;\n}\n\nvoid *operator new(size_t size) {\n    return xmalloc(size);\n}\nvoid *operator new[](size_t size) {\n    return xmalloc(size);\n}\n\nvoid operator delete(void *p) THROW {\n    xfree(p);\n}\nvoid operator delete[](void *p) THROW {\n    xfree(p);\n}\n\nnamespace pxt {\n\nstatic uint64_t startTime;\nstatic pthread_mutex_t execMutex;\nstatic pthread_mutex_t eventMutex;\nstatic pthread_cond_t newEventBroadcast;\n\nstruct Thread {\n    struct Thread *next;\n    Action act;\n    TValue arg0;\n    TValue data0;\n    TValue data1;\n    pthread_t pid;\n    pthread_cond_t waitCond;\n    int waitSource;\n    int waitValue;\n};\n\nstatic struct Thread *allThreads;\nstatic struct Event *eventHead, *eventTail;\n\nstruct Event {\n    struct Event *next;\n    int source;\n    int value;\n};\n\nEvent lastEvent;\n\nEvent *mkEvent(int source, int value) {\n    auto res = new Event();\n    memset(res, 0, sizeof(Event));\n    res->source = source;\n    res->value = value;\n    return res;\n}\n\nvolatile bool paniced;\nextern \"C\" void drawPanic(int code);\n\nint tryLockUser() {\n    return pthread_mutex_trylock(&execMutex);\n}\n\nextern \"C\" void target_panic(int error_code) {\n    char buf[50];\n    int prevErr = errno;\n\n    paniced = true;\n    tryLockUser();\n\n    snprintf(buf, sizeof(buf), \"\\nPANIC %d\\n\", error_code);\n\n    drawPanic(error_code);\n    DMESG(\"PANIC %d\", error_code);\n    DMESG(\"errno=%d %s\", prevErr, strerror(prevErr));\n\n    for (int i = 0; i < 10; ++i) {\n        sendSerial(buf, strlen(buf));\n        sleep_core_us(500 * 1000);\n    }\n\n    target_exit();\n}\n\nvoid startUser() {\n    pthread_mutex_lock(&execMutex);\n}\n\nvoid stopUser() {\n    pthread_mutex_unlock(&execMutex);\n}\n\nvoid sleep_core_us(uint64_t us) {\n    struct timespec ts;\n    ts.tv_sec = us / 1000000;\n    ts.tv_nsec = (us % 1000000) * 1000;\n    while (nanosleep(&ts, &ts))\n        ;\n}\n\nvoid sleep_ms(uint32_t ms) {\n    stopUser();\n    sleep_core_us(ms * 1000);\n    startUser();\n}\n\nvoid sleep_us(uint64_t us) {\n    if (us > 50000) {\n        sleep_ms(us / 1000);\n    } else {\n        sleep_core_us(us);\n    }\n}\n\nuint64_t currTime() {\n    struct timeval tv;\n    gettimeofday(&tv, NULL);\n    return tv.tv_sec * 1000000LL + tv.tv_usec;\n}\n\nuint64_t current_time_us() {\n    return currTime() - startTime;\n}\n\nint current_time_ms() {\n    return current_time_us() / 1000;\n}\n\nvoid disposeThread(Thread *t) {\n    if (allThreads == t) {\n        allThreads = t->next;\n    } else {\n        for (auto tt = allThreads; tt; tt = tt->next) {\n            if (tt->next == t) {\n                tt->next = t->next;\n                break;\n            }\n        }\n    }\n    unregisterGC(&t->act, 4);\n    pthread_cond_destroy(&t->waitCond);\n    delete t;\n}\n\nstatic void runAct(Thread *thr) {\n    startUser();\n    pxt::runAction1(thr->act, thr->arg0);\n    stopUser();\n    disposeThread(thr);\n}\n\nstatic void mainThread(Thread *) {}\n\nvoid setupThread(Action a, TValue arg = 0, void (*runner)(Thread *) = NULL, TValue d0 = 0,\n                 TValue d1 = 0) {\n    if (runner == NULL)\n        runner = runAct;\n    auto thr = new Thread();\n    memset(thr, 0, sizeof(Thread));\n    thr->next = allThreads;\n    allThreads = thr;\n    registerGC(&thr->act, 4);\n    thr->act = a;\n    thr->arg0 = arg;\n    thr->data0 = d0;\n    thr->data1 = d1;\n    pthread_cond_init(&thr->waitCond, NULL);\n    if (runner == mainThread) {\n        thr->pid = pthread_self();\n    } else {\n        pthread_create(&thr->pid, NULL, (void *(*)(void *))runner, thr);\n        THREAD_DBG(\"setup thread: %p (pid %p)\", thr, thr->pid);\n        pthread_detach(thr->pid);\n    }\n}\n\nvoid releaseFiber() {\n    stopUser();\n    pthread_exit(NULL);\n}\n\nvoid runInParallel(Action a) {\n    setupThread(a);\n}\n\nstatic void runFor(Thread *t) {\n    startUser();\n    while (true) {\n        pxt::runAction0(t->act);\n        sleep_ms(20);\n    }\n}\n\nvoid runForever(Action a) {\n    setupThread(a, 0, runFor);\n}\n\nvoid waitForEvent(int source, int value) {\n    THREAD_DBG(\"waitForEv: %d %d\", source, value);\n    auto self = pthread_self();\n    for (auto t = allThreads; t; t = t->next) {\n        THREAD_DBG(\"t: %p\", t);\n        if (t->pid == self) {\n            pthread_mutex_lock(&eventMutex);\n            t->waitSource = source;\n            t->waitValue = value;\n            stopUser();\n            // spourious wake ups may occur they say\n            while (t->waitSource) {\n                pthread_cond_wait(&t->waitCond, &eventMutex);\n            }\n            pthread_mutex_unlock(&eventMutex);\n            startUser();\n            return;\n        }\n    }\n    DMESG(\"current thread not registered!\");\n    oops(52);\n}\n\nstatic void dispatchEvent(Event &e) {\n    lastEvent = e;\n\n    auto curr = findBinding(e.source, e.value);\n    while(curr) {\n        setupThread(curr->action, fromInt(e.value));\n        curr = nextBinding(curr->next, e.source, e.value);\n    }\n}\n\nstatic void *evtDispatcher(void *dummy) {\n    pthread_mutex_lock(&eventMutex);\n    while (true) {\n        pthread_cond_wait(&newEventBroadcast, &eventMutex);\n        while (eventHead != NULL) {\n            if (paniced)\n                return 0;\n            Event *ev = eventHead;\n            eventHead = ev->next;\n            if (eventHead == NULL)\n                eventTail = NULL;\n\n            for (auto thr = allThreads; thr; thr = thr->next) {\n                if (paniced)\n                    return 0;\n                if (thr->waitSource == 0)\n                    continue;\n                if (thr->waitValue != ev->value && thr->waitValue != DEVICE_EVT_ANY)\n                    continue;\n                if (thr->waitSource == ev->source) {\n                    thr->waitSource = 0; // once!\n                    pthread_cond_broadcast(&thr->waitCond);\n                } else if (thr->waitSource == DEVICE_ID_NOTIFY &&\n                           ev->source == DEVICE_ID_NOTIFY_ONE) {\n                    thr->waitSource = 0; // once!\n                    pthread_cond_broadcast(&thr->waitCond);\n                    break; // do not wake up any other threads\n                }\n            }\n\n            dispatchEvent(*ev);\n            delete ev;\n        }\n    }\n}\n\nint allocateNotifyEvent() {\n    static volatile int notifyId;\n    pthread_mutex_lock(&eventMutex);\n    int res = ++notifyId;\n    pthread_mutex_unlock(&eventMutex);\n    return res;\n}\n\nvoid raiseEvent(int id, int event) {\n    auto e = mkEvent(id, event);\n    pthread_mutex_lock(&eventMutex);\n    if (eventTail == NULL) {\n        if (eventHead != NULL)\n            oops(51);\n        eventHead = eventTail = e;\n    } else {\n        eventTail->next = e;\n        eventTail = e;\n    }\n    pthread_cond_broadcast(&newEventBroadcast);\n    pthread_mutex_unlock(&eventMutex);\n}\n\nvoid registerWithDal(int id, int event, Action a, int flags) {\n    // TODO support flags\n    setBinding(id, event, a);\n}\n\nuint32_t afterProgramPage() {\n    return 0;\n}\n\nchar **initialArgv;\n\nvoid screen_init();\nvoid initKeys();\nvoid target_startup();\n\nvoid initRuntime() {\n    // daemon(1, 1);\n    startTime = currTime();\n\n    target_startup();\n\n    pthread_t disp;\n    pthread_create(&disp, NULL, evtDispatcher, NULL);\n    pthread_detach(disp);\n    setupThread(0, 0, mainThread);\n    target_init();\n    screen_init();\n    initKeys();\n    startUser();\n}\n\n#define GC_BASE 0x20000000\n#define GC_PAGE_SIZE 4096\nvoid *gcAllocBlock(size_t sz) {\n    static uint8_t *currPtr = (uint8_t *)GC_BASE;\n    sz = (sz + GC_PAGE_SIZE - 1) & ~(GC_PAGE_SIZE - 1);\n    void *r = mmap(currPtr, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);\n    if (r == MAP_FAILED) {\n        DMESG(\"mmap %p failed; err=%d\", currPtr, errno);\n        target_panic(PANIC_INTERNAL_ERROR);\n    }\n    currPtr = (uint8_t *)r + sz;\n    if (isReadOnly((TValue)r)) {\n        DMESG(\"mmap returned read-only address: %p\", r);\n        target_panic(PANIC_INTERNAL_ERROR);\n    }\n    return r;\n}\n\nstatic __thread ThreadContext *threadCtx;\n\nThreadContext *getThreadContext() {\n    return threadCtx;\n}\n\nvoid setThreadContext(ThreadContext *ctx) {\n    threadCtx = ctx;\n}\n\nvoid *threadAddressFor(ThreadContext *, void *sp) {\n    return sp;\n}\n\n} // namespace pxt\n","ns.ts":"/**\n * Events and data from sensors.\n */\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\n//% groups='[\"other\", \"More\"]'\nnamespace input {\n}\n\n/**\n * Servos\n */\n//% color=\"#03AA74\" weight=88 icon=\"\\uf021\"\nnamespace servos {\n\n}\n\n/**\n * A Joint Asynchronous Communications, Device Agnostic Control.\n */\n//% color=\"#E79251\" weight=1 icon=\"\\uf185\"\n//% groups='[\"Broadcast\", \"Console\", \"Control\"]'\n//% blockGap=8\nnamespace jacdac {\n\n}","pins.h":"#ifndef __PXT_PINS_H\n#define __PXT_PINS_H\n\n#define BUTTON_ACTIVE_HIGH_PULL_DOWN (ACTIVE_HIGH | 0x10)\n#define BUTTON_ACTIVE_HIGH_PULL_UP (ACTIVE_HIGH | 0x20)\n#define BUTTON_ACTIVE_HIGH_PULL_NONE (ACTIVE_HIGH | 0x30)\n#define BUTTON_ACTIVE_LOW_PULL_DOWN (ACTIVE_LOW | 0x10)\n#define BUTTON_ACTIVE_LOW_PULL_UP (ACTIVE_LOW | 0x20)\n#define BUTTON_ACTIVE_LOW_PULL_NONE (ACTIVE_LOW | 0x30)\n\n#define PIN(name) ((PinName)pxt::getConfig(CFG_PIN_##name, -1))\n#define LOOKUP_PIN(name) pxt::lookupPin(PIN(name))\n\n// these can be overridden in platform.h\n#ifndef CODAL_PIN\n#define CODAL_PIN CODAL_MBED::Pin\n#endif\n\n#ifndef CODAL_TIMER\n#define CODAL_TIMER CODAL_MBED::Timer\n#endif\n\n#ifndef CODAL_SPI\n#define CODAL_SPI CODAL_MBED::SPI\n#endif\n\n#ifndef CODAL_SERIAL\n#define CODAL_SERIAL CODAL_MBED::Serial\n#endif\n\n#ifndef IS_ANALOG_PIN\n#define IS_ANALOG_PIN(id) ((DEV_ANALOG_PINS >> (id)) & 1)\n#endif\n\ntypedef CODAL_PIN DevicePin;\n\ntypedef DevicePin *DigitalInOutPin;\ntypedef DevicePin *AnalogInOutPin;\ntypedef DevicePin *AnalogInPin;\ntypedef DevicePin *AnalogOutPin;\ntypedef DevicePin *PwmPin;\ntypedef DevicePin *PwmOnlyPin;\ntypedef Button *Button_;\n\nnamespace pxt {\nDevicePin *getPin(int id);\nDevicePin *getPinCfg(int key);\nDevicePin *lookupPin(int pinName);\nDevicePin *lookupPinCfg(int key);\nvoid linkPin(int from, int to);\nCodalComponent *lookupComponent(int id);\n}\n\n#define PINOP(op) name->op\n\n#endif\n","platform.cpp":"#include \"pxt.h\"\n\n#include <unistd.h>\n#include <stdio.h>\n#include <fcntl.h>\n\nnamespace pxt {\n\nstatic void initRandomSeed() {\n    int seed = 0xC0DA1;\n    int fd = open(\"/dev/urandom\", O_RDONLY);\n    read(fd, &seed, sizeof(seed));\n    close(fd);\n    seedRandom(seed);\n}\n\nvoid sendSerial(const char *data, int len) {\n    /*\n    if (!serial) {\n        serial = new codal::_mbed::Serial(USBTX, NC);\n        serial->baud(9600);\n    }\n    serial->send((uint8_t*)data, len);\n    */\n}\n\nextern \"C\" void drawPanic(int code)\n{\n    // TODO\n}\n\n\nextern \"C\" void target_init()\n{\n    initRandomSeed();\n}\n\nvoid updateScreen(Image_ img);\n\nvoid screen_init() {\n    updateScreen(NULL);\n}\n\n}\n\n","platform.h":"#ifndef __PXT_PLATFORM_H\n#define __PXT_PLATFORM_H\n\n#define OUTPUT_BITS 12\n\n#define PAGE_SIZE 1024 // not really\n\n#define DEV_NUM_PINS 28\n\n#define DEV_PWM_PINS 0xffffffffULL\n#define DEV_AIN_PINS 0ULL\n\n\n// Codal doesn't yet distinguish between PWM and AIN\n#define DEV_ANALOG_PINS (DEV_PWM_PINS | DEV_AIN_PINS)\n\n#define CODAL_PIN ZPin\n#define CODAL_TIMER ZTimer\n#define CODAL_SPI ZSPI\n#define CODAL_I2C ZI2C\n\n\nnamespace pxt\n{\n\n    class ZPin;\n    class AbstractButton;\n    class MultiButton;\n    class CodalComponent;\n    \n    \n} // pxt\n\n#define IMAGE_BITS 4\n#define PXT_GC_THREAD_LIST 1\n\n#define PXT_IN_ISR() false\n\n#define PROGDIR \"/sd/prj\"\n#undef SETTINGSDIR\n\n// #define SETTINGSDIR \"/sd/cfg\"\n\n#endif\n","platform_includes.h":"#include <unistd.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n#include <sys/types.h>\n\n#define PROCESSOR_WORD_TYPE uintptr_t\n","pxt.h":"#ifndef __PXT_H\n#define __PXT_H\n\n#include \"pxtbase.h\"\n\n#define OUTPUT_BITS 12\n\n#define DEVICE_EVT_ANY 0\n#define DEVICE_ID_NOTIFY_ONE 1022\n#define DEVICE_ID_NOTIFY 1023\n\nnamespace serial {\nclass LinuxSerialDevice;\n}\n\ntypedef serial::LinuxSerialDevice *SerialDevice;\n\nnamespace pxt {\nvoid raiseEvent(int id, int event);\nint allocateNotifyEvent();\nvoid sleep_core_us(uint64_t us);\nvoid startUser();\nvoid stopUser();\nint tryLockUser();\n\nvoid target_disable_irq();\nvoid target_enable_irq();\n\nconst char *getConfigString(const char *name);\nint getConfigInt(const char *name, int defl);\n#define ENDMARK -0x7fff0123\nconst int *getConfigInts(const char *name);\n\nclass Button;\ntypedef Button *Button_;\n\nextern \"C\" void target_init();\n\nextern volatile bool paniced;\nextern char **initialArgv;\nvoid target_exit();\n\n// Buffer, Sound, and Image share representation.\ntypedef Buffer Sound;\n\n// extern Event lastEvent;\n} // namespace pxt\n\n#undef PXT_MAIN\n#define PXT_MAIN                                                                                   \\\n    int main(int argc, char **argv) {                                                              \\\n        pxt::initialArgv = argv;                                                                   \\\n        pxt::start();                                                                              \\\n        return 0;                                                                                  \\\n    }\n\n#endif\n","pxt.json":"{\n    \"name\": \"core---linux\",\n    \"description\": \"The core library for Codal-based targets\",\n    \"dependencies\": {\n        \"base\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"Makefile\",\n        \"dal.d.ts\",\n        \"linux.cpp\",\n        \"config.cpp\",\n        \"target.cpp\",\n        \"pxt.h\",\n        \"platform.h\",\n        \"platform.cpp\",\n        \"pxtcore.h\",\n        \"pins.h\",\n        \"control.cpp\",\n        \"dmesg.cpp\",\n        \"shims.d.ts\",\n        \"enums.d.ts\",\n        \"ns.ts\",\n        \"timer.ts\",\n        \"platform_includes.h\",\n        \"codalemu.cpp\",\n        \"pxtparts.json\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"yotta\": {\n        \"config\": {\n            \"codal\": {\n                \"component_count\": 64,\n                \"dmesg_buffer_size\": 1024\n            }\n        }\n    },\n    \"dalDTS\": {\n        \"includeDirs\": [\n            \"libraries/codal-core/inc\",\n            \"pxtapp\"\n        ],\n        \"excludePrefix\": [\n            \"JD_\",\n            \"USB_\",\n            \"REQUEST_\",\n            \"LIS3DH_\",\n            \"FXOS8700_\",\n            \"HF2_\",\n            \"PXT_REF_TAG_\",\n            \"MS_\",\n            \"SCSI_\",\n            \"MAG_\",\n            \"MAG3\",\n            \"MPU6\",\n            \"MADCTL\",\n            \"MMA8\"\n        ]\n    }\n}\n","pxtcore.h":"#ifndef __PXTCORE_H\n#define __PXTCORE_H\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdarg.h>\n\nnamespace pxt {\nvoid *gcAllocBlock(size_t sz);\nvoid vm_stack_trace();\n}\n\nextern \"C\" void dmesg(const char *fmt, ...);\nextern \"C\" void vdmesg(const char *format, va_list arg);\n#define DMESG ::dmesg\n\nstatic inline void itoa(int v, char *dst) {\n    snprintf(dst, 30, \"%d\", v);\n}\n\nextern \"C\" void *xmalloc(size_t sz);\n#define xfree free\n\n#define GC_ALLOC_BLOCK gcAllocBlock\n\n#ifndef POKY\n// This seems to degrade performance - probably due to cache size\n//#define GC_BLOCK_SIZE (1024 * 64)\n#endif\n\n#define PXT_HARD_FLOAT 1\n\n#endif\n","pxtparts.json":"{\n    \"neopixel\": {\n        \"simulationBehavior\": \"neopixel\",\n        \"visual\": {\n            \"builtIn\": \"neopixel\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 19,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 28,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createStrip,light.createNeoPixelStrip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"dotstar\": {\n        \"simulationBehavior\": \"dotstar\",\n        \"visual\": {\n            \"builtIn\": \"dotstar\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 1\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createAPA102Strip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"dataPin\"\n                },\n                {\n                    \"pinInstantiationIdx\": 1,\n                    \"partParameter\": \"clkPin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },\n    \"pixels\": {\n        \"simulationBehavior\": \"pixels\",\n        \"visual\": { \n            \"builtIn\": \"pixels\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"MOSI\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"SCK\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },    \n    \"buttons\": {\n        \"simulationBehavior\": \"buttons\",\n        \"visual\": {\n            \"builtIn\": \"buttons\",\n            \"width\": 75,\n            \"height\": 45,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 30,\n                    \"y\": 45\n                }\n            ]\n        },\n        \"numberOfPins\": 2,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"Button.onEvent,Button.isPressed,Button.wasPressed\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"button\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"slideswitch\": {\n        \"numberOfPins\": 3,\n        \"simulationBehavior\": \"slideswitch\",\n        \"visual\": {\n            \"builtIn\": \"slideswitch\",\n            \"width\": 100,\n            \"height\": 100,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalRead,DigitalInOutPin.onPulsed,DigitalInOutPin.onEvent\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"microservo\": {\n        \"simulationBehavior\": \"microservo\",\n        \"visual\": {\n            \"builtIn\": \"microservo\",\n            \"width\": 74.85,\n            \"height\": 200,\n            \"pinDistance\": 10,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 37,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 5\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"PwmOnlyPin.servoWrite,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"led\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"analogled\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogOutPin.analogWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"photocell\": {\n        \"numberOfPins\": 3,\n        \"visual\": {\n            \"builtIn\": \"photocell\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 15,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"photocell\",\n        \"pinDefinitions\": [\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogInPin.analogRead\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace control {\n\n    /**\n     * Announce that an event happened to registered handlers.\n     * @param src ID of the Component that generated the event\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.\n     */\n    //% weight=21 blockGap=12 blockId=\"control_raise_event\"\n    //% block=\"raise event|from %src|with value %value\" blockExternalInputs=1\n    //% help=control/raise-event shim=control::raiseEvent\n    function raiseEvent(src: int32, value: int32): void;\n\n    /**\n     * Allocates the next user notification event\n     */\n    //% help=control/allocate-notify-event shim=control::allocateNotifyEvent\n    function allocateNotifyEvent(): int32;\n\n    /**\n     * Determine the version of system software currently running.\n     */\n    //% blockId=\"control_device_dal_version\" block=\"device dal version\"\n    //% help=control/device-dal-version shim=control::deviceDalVersion\n    function deviceDalVersion(): string;\n\n    /** Write data to DMESG debugging buffer. */\n    //% shim=control::dmesg\n    function dmesg(s: string): void;\n\n    /**\n     * Determines if the USB has been enumerated.\n     */\n    //% shim=control::isUSBInitialized\n    function isUSBInitialized(): boolean;\n}\ndeclare namespace serial {\n\n    /** Send DMESG debug buffer over serial. */\n    //% shim=serial::writeDmesg\n    function writeDmesg(): void;\n}\n\n// Auto-generated. Do not edit. Really.\n","target.cpp":"#include \"pxt.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <signal.h>\n#include <stdarg.h>\n#include <fcntl.h>\n\nnamespace pxt {\n\nvoid target_exit() {\n    kill(getpid(), SIGTERM);\n}\n\nextern \"C\" void target_reset() {\n    for (int i = 3; i < 1000; ++i)\n        close(i);\n    if (!fork()) {\n        execv(initialArgv[0], initialArgv);\n        exit(127);\n    } else {\n        target_exit();\n    }\n}\n\nvoid target_startup() {\n    int pid = getpid();\n    DMESG(\"runtime starting, pid=%d...\", pid);\n\n    FILE *pf = fopen(\"/tmp/pxt-pid\", \"r\");\n    if (pf) {\n        int p2 = 0;\n        fscanf(pf, \"%d\", &p2);\n        if (p2)\n            kill(p2, SIGTERM);\n        fclose(pf);\n    }\n    pf = fopen(\"/tmp/pxt-pid\", \"w\");\n    fprintf(pf, \"%d\", pid);\n    fclose(pf);\n}\n\nuint64_t readSerialNumber() {\n    static uint64_t bigSerialNumber;\n\n    if (bigSerialNumber)\n        return bigSerialNumber;\n\n    char buf[1024];\n    int fd = open(\"/proc/cpuinfo\", O_RDONLY);\n    int len = read(fd, buf, sizeof(buf) - 1);\n    close(fd);\n\n    if (len < 0)\n        len = 0;\n    buf[len] = 0;\n    auto p = strstr(buf, \"Serial\\t\");\n    if (p) {\n        p += 6;\n        while (*p && strchr(\" \\t:\", *p))\n            p++;\n        uint64_t s = 0;\n        sscanf(p, \"%llu\", &s);\n        bigSerialNumber = s;\n    }\n\n    if (!bigSerialNumber)\n        bigSerialNumber = 0xf00d0042f00d0042;\n\n    return bigSerialNumber;\n}\n\nuint64_t getLongSerialNumber() {\n    static uint64_t serial;\n    if (serial == 0)\n        serial = readSerialNumber();\n    return serial;\n}\n\n} // namespace pxt\n","test.ts":"let i = 1\nlet f = 0.5\nlet plus = i + f\nlet minus = i - f\n\nlet r = Math.random()\nlet ri = Math.randomRange(5, 10)\n\n","timer.ts":"namespace control {\n    /**\n     * A timer\n     */\n    //% fixedInstances\n    export class Timer {\n        start: number;\n\n        constructor() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Gets the elapsed time in millis since the last reset\n         */\n        //% blockId=timerMillis block=\"%timer|millis\"\n        millis(): number {\n            return control.millis() - this.start;\n        }\n\n        /**\n         * Gets the elapsed time in seconds since the last reset\n         */\n        //% blockId=timerSeconds block=\"%timer|seconds\"\n        seconds(): number {\n            return this.millis() / 1000;\n        }\n\n        /**\n         * Resets the timer\n         */\n        //% blockId=timerRest block=\"%timer|reset\"\n        reset() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Pauses until the timer reaches the given amount of milliseconds\n         * @param ms how long to pause for, eg: 5, 100, 200, 500, 1000, 2000\n         */\n        //% blockId=timerPauseUntil block=\"%timer|pause until (ms) %ms\"\n        pauseUntil(ms: number) {\n            const remaining = this.millis() - ms;\n            pause(Math.max(0, remaining));\n        }\n    }\n\n    //% whenUsed fixedInstance block=\"timer 1\"\n    export const timer1 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 2\"\n    export const timer2 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 3\"\n    export const timer3 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 4\"\n    export const timer4 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 5\"\n    export const timer5 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 6\"\n    export const timer6 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 7\"\n    export const timer7 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 8\"\n    export const timer8 = new Timer();\n}"},"core---nrf52":{"README.md":"# core\n\nThe core library for Codal-based targets.\n\n","codal.cpp":"#include \"pxt.h\"\n#include \"LowLevelTimer.h\"\nusing namespace codal;\n\nvoid cpu_clock_init(void);\n\nPXT_ABI(__aeabi_dadd)\nPXT_ABI(__aeabi_dcmplt)\nPXT_ABI(__aeabi_dcmpgt)\nPXT_ABI(__aeabi_dsub)\nPXT_ABI(__aeabi_ddiv)\nPXT_ABI(__aeabi_dmul)\n\n#ifdef DEVICE_GET_FIBER_LIST_AVAILABLE\n// newer codal-core has get_fiber_list() but not list_fibers()\nnamespace codal {\n/*\n * Return all current fibers.\n *\n * @param dest If non-null, it points to an array of pointers to fibers to store results in.\n *\n * @return the number of fibers (potentially) stored\n */\nint list_fibers(Fiber **dest) {\n    int i = 0;\n    for (Fiber *fib = codal::get_fiber_list(); fib; fib = fib->next) {\n        if (dest)\n            dest[i] = fib;\n        i++;\n    }\n    return i;\n}\n\n} // namespace codal\n#endif\n\nnamespace pxt {\n\nvoid platform_init();\nvoid usb_init();\n\n// The first two word are used to tell the bootloader that a single reset should start the\n// bootloader and the MSD device, not us.\n// The rest is reserved for partial flashing checksums.\n__attribute__((section(\".binmeta\"))) __attribute__((used)) const uint32_t pxt_binmeta[] = {\n    0x87eeb07c, 0x87eeb07c, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,\n    0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,\n};\n\nEvent lastEvent;\nMessageBus devMessageBus;\ncodal::CodalDevice device;\n\nstruct FreeList {\n    FreeList *next;\n};\n\nstatic void commInit() {\n    int commSize = bytecode[20];\n    if (!commSize)\n        return;\n\n    void *r = app_alloc_at((void *)PXT_COMM_BASE, commSize);\n    DMESG(\"comm %d -> %p\", commSize, r);\n    if (!r)\n        target_panic(20);\n}\n\nstatic void initCodal() {\n    cpu_clock_init();\n\n    commInit();\n\n    // Bring up fiber scheduler.\n    scheduler_init(devMessageBus);\n\n    // We probably don't need that - components are initialized when one obtains\n    // the reference to it.\n    // devMessageBus.listen(DEVICE_ID_MESSAGE_BUS_LISTENER, DEVICE_EVT_ANY, this,\n    // &CircuitPlayground::onListenerRegisteredEvent);\n\n    for (int i = 0; i < DEVICE_COMPONENT_COUNT; i++) {\n        if (CodalComponent::components[i])\n            CodalComponent::components[i]->init();\n    }\n\n    usb_init();\n\n    auto led = LOOKUP_PIN(LED);\n    if (led) {\n        led->setDigitalValue(0);\n    }\n}\n\n// ---------------------------------------------------------------------------\n// An adapter for the API expected by the run-time.\n// ---------------------------------------------------------------------------\n\n// We have the invariant that if [dispatchEvent] is registered against the DAL\n// for a given event, then [handlersMap] contains a valid entry for that\n// event.\nvoid dispatchEvent(Event e) {\n    lastEvent = e;\n\n    auto curr = findBinding(e.source, e.value);\n    auto value = fromInt(e.value);\n    while (curr) {\n        runAction1(curr->action, value);\n        curr = nextBinding(curr->next, e.source, e.value);\n    }\n}\n\nvoid registerWithDal(int id, int event, Action a, int flags) {\n    // first time?\n    if (!findBinding(id, event)) {\n        devMessageBus.listen(id, event, dispatchEvent, flags);\n        if (event == 0) {\n            // we're registering for all events on given ID\n            // need to remove old listeners for specific events\n            auto curr = findBinding(id, -1);\n            while (curr) {\n                devMessageBus.ignore(id, curr->value, dispatchEvent);\n                curr = nextBinding(curr->next, id, -1);\n            }\n        }\n    }\n    setBinding(id, event, a);\n}\n\nvoid fiberDone(void *a) {\n    unregisterGCPtr((Action)a);\n    release_fiber();\n}\n\nvoid releaseFiber() {\n    release_fiber();\n}\n\nvoid sleep_ms(unsigned ms) {\n    fiber_sleep(ms);\n}\n\nvoid sleep_us(uint64_t us) {\n    target_wait_us(us);\n}\n\nvoid forever_stub(void *a) {\n    while (true) {\n        runAction0((Action)a);\n        fiber_sleep(20);\n    }\n}\n\nvoid runForever(Action a) {\n    if (a != 0) {\n        registerGCPtr(a);\n        create_fiber(forever_stub, (void *)a);\n    }\n}\n\nvoid runInParallel(Action a) {\n    if (a != 0) {\n        registerGCPtr(a);\n        create_fiber((void (*)(void *))(void*)runAction0, (void *)a, fiberDone);\n    }\n}\n\nvoid waitForEvent(int id, int event) {\n    fiber_wait_for_event(id, event);\n}\n\nvoid initRuntime() {\n    initSystemTimer();\n    initCodal();\n    platform_init();\n}\n\n//%\nunsigned afterProgramPage() {\n    unsigned ptr = (unsigned)&bytecode[0];\n    ptr += programSize();\n    ptr = (ptr + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);\n    return ptr;\n}\n\nuint64_t getLongSerialNumber() {\n    return device.getSerialNumber();\n}\n\nint current_time_ms() {\n    return system_timer_current_time();\n}\n\nuint64_t current_time_us() {\n    return system_timer_current_time_us();\n}\n\nThreadContext *getThreadContext() {\n    if (!currentFiber)\n        return NULL;\n    return (ThreadContext *)currentFiber->user_data;\n}\n\nvoid setThreadContext(ThreadContext *ctx) {\n    currentFiber->user_data = ctx;\n}\n\nstatic void *threadAddressFor(codal::Fiber *fib, void *sp) {\n    if (fib == currentFiber)\n        return sp;\n    return (uint8_t *)sp + ((uint8_t *)fib->stack_top - (uint8_t *)tcb_get_stack_base(fib->tcb));\n}\n\nvoid gcProcessStacks(int flags) {\n    // check scheduler is initialized\n    if (!currentFiber) {\n        // make sure we allocate something to at least initalize the memory allocator\n        void *volatile p = xmalloc(1);\n        xfree(p);\n        return;\n    }\n\n    int numFibers = codal::list_fibers(NULL);\n    codal::Fiber **fibers = (codal::Fiber **)xmalloc(sizeof(codal::Fiber *) * numFibers);\n    int num2 = codal::list_fibers(fibers);\n    if (numFibers != num2)\n        oops(12);\n    int cnt = 0;\n\n    for (int i = 0; i < numFibers; ++i) {\n        auto fib = fibers[i];\n        auto ctx = (ThreadContext *)fib->user_data;\n        if (!ctx)\n            continue;\n        gcProcess(ctx->thrownValue);\n        for (auto seg = &ctx->stack; seg; seg = seg->next) {\n            auto ptr = (TValue *)threadAddressFor(fib, seg->top);\n            auto end = (TValue *)threadAddressFor(fib, seg->bottom);\n            if (flags & 2)\n                DMESG(\"RS%d:%p/%d\", cnt++, ptr, end - ptr);\n            // VLOG(\"mark: %p - %p\", ptr, end);\n            while (ptr < end) {\n                gcProcess(*ptr++);\n            }\n        }\n    }\n    xfree(fibers);\n}\n\nLowLevelTimer *getJACDACTimer() {\n    static LowLevelTimer *jacdacTimer;\n    if (!jacdacTimer) {\n        jacdacTimer = allocateTimer();\n        jacdacTimer->setIRQPriority(1);\n    }\n    return jacdacTimer;\n}\nvoid initSystemTimer() {\n    new CODAL_TIMER(*allocateTimer());\n}\n\n} // namespace pxt\n","control.cpp":"#include \"pxt.h\"\n\n#if defined(NRF52_SERIES) || defined(PICO_BOARD)\n#define _estack __StackTop \n#endif\nextern uint32_t _estack;\n\nnamespace control {\n\n/**\n * Announce that an event happened to registered handlers.\n * @param src ID of the MicroBit Component that generated the event\n * @param value Component specific code indicating the cause of the event.\n */\n//% weight=21 blockGap=12 blockId=\"control_raise_event\"\n//% help=control/raise-event\n//% block=\"raise event|from %src|with value %value\" blockExternalInputs=1\nvoid raiseEvent(int src, int value) {\n    Event evt(src, value);\n}\n\n/**\n* Determine the version of system software currently running.\n*/\n//% blockId=\"control_device_dal_version\" block=\"device dal version\"\n//% help=control/device-dal-version\nString deviceDalVersion() {\n    return mkString(device.getVersion());\n}\n\n/**\n* Allocates the next user notification event\n*/\n//% help=control/allocate-notify-event\nint allocateNotifyEvent() {\n    return ::allocateNotifyEvent();\n}\n\n/** Write a message to DMESG debugging buffer. */\n//%\nvoid dmesg(String s) {\n    DMESG(\"# %s\", s->getUTF8Data());\n}\n\n/** Write a message and value (pointer) to DMESG debugging buffer. */\n//%\nvoid dmesgPtr(String str, Object_ ptr) {\n    DMESG(\"# %s: %p\", str->getUTF8Data(), ptr);\n}\n\n//%\nuint32_t _ramSize()\n{\n    return (uint32_t)&_estack & 0x1fffffff;\n}\n\n}\n","dal.d.ts":"// Auto-generated. Do not edit.\ndeclare const enum DAL {\n    // /libraries/codal-core/inc/JACDAC/JDPhysicalLayer.h\n    Receiving = 0,\n    Transmitting = 1,\n    Error = 2,\n    Unknown = 3,\n    ListeningForPulse = 0,\n    ErrorRecovery = 1,\n    Off = 2,\n    Continuation = 0,\n    // /libraries/codal-core/inc/JACDAC/JDServiceClasses.h\n    STATIC_CLASS_START = 0,\n    STATIC_CLASS_END = 16777215,\n    DYNAMIC_CLASS_END = 4294967295,\n    // /libraries/codal-core/inc/core/CodalComponent.h\n    DEVICE_ID_BUTTON_A = 1,\n    DEVICE_ID_BUTTON_B = 2,\n    DEVICE_ID_BUTTON_AB = 3,\n    DEVICE_ID_BUTTON_RESET = 4,\n    DEVICE_ID_ACCELEROMETER = 5,\n    DEVICE_ID_COMPASS = 6,\n    DEVICE_ID_DISPLAY = 7,\n    DEVICE_ID_THERMOMETER = 8,\n    DEVICE_ID_RADIO = 9,\n    DEVICE_ID_RADIO_DATA_READY = 10,\n    DEVICE_ID_MULTIBUTTON_ATTACH = 11,\n    DEVICE_ID_SERIAL = 12,\n    DEVICE_ID_GESTURE = 13,\n    DEVICE_ID_SYSTEM_TIMER = 14,\n    DEVICE_ID_SCHEDULER = 15,\n    DEVICE_ID_COMPONENT = 16,\n    DEVICE_ID_LIGHT_SENSOR = 17,\n    DEVICE_ID_TOUCH_SENSOR = 18,\n    DEVICE_ID_SYSTEM_DAC = 19,\n    DEVICE_ID_SYSTEM_MICROPHONE = 20,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR = 21,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR_SPL = 22,\n    DEVICE_ID_MSC = 23,\n    DEVICE_ID_SPI = 24,\n    DEVICE_ID_DISTANCE = 25,\n    DEVICE_ID_GYROSCOPE = 26,\n    DEVICE_ID_HUMIDITY = 27,\n    DEVICE_ID_PRESSURE = 28,\n    DEVICE_ID_SINGLE_WIRE_SERIAL = 29,\n    DEVICE_ID_JACDAC = 30,\n    DEVICE_ID_JACDAC_PHYS = 31,\n    DEVICE_ID_JACDAC_CONTROL_SERVICE = 32,\n    DEVICE_ID_JACDAC_CONFIGURATION_SERVICE = 33,\n    DEVICE_ID_IO_P0 = 100,\n    DEVICE_ID_MESSAGE_BUS_LISTENER = 1021,\n    DEVICE_ID_NOTIFY_ONE = 1022,\n    DEVICE_ID_NOTIFY = 1023,\n    DEVICE_ID_BUTTON_UP = 2000,\n    DEVICE_ID_BUTTON_DOWN = 2001,\n    DEVICE_ID_BUTTON_LEFT = 2002,\n    DEVICE_ID_BUTTON_RIGHT = 2003,\n    DEVICE_ID_JD_DYNAMIC_ID = 3000,\n    DEVICE_COMPONENT_RUNNING = 4096,\n    DEVICE_COMPONENT_STATUS_SYSTEM_TICK = 8192,\n    DEVICE_COMPONENT_STATUS_IDLE_TICK = 16384,\n    DEVICE_COMPONENT_LISTENERS_CONFIGURED = 1,\n    DEVICE_COMPONENT_EVT_SYSTEM_TICK = 1,\n    // /libraries/codal-core/inc/core/CodalFiber.h\n    DEVICE_SCHEDULER_RUNNING = 1,\n    DEVICE_SCHEDULER_IDLE = 2,\n    DEVICE_FIBER_FLAG_FOB = 1,\n    DEVICE_FIBER_FLAG_PARENT = 2,\n    DEVICE_FIBER_FLAG_CHILD = 4,\n    DEVICE_FIBER_FLAG_DO_NOT_PAGE = 8,\n    DEVICE_SCHEDULER_EVT_TICK = 1,\n    DEVICE_SCHEDULER_EVT_IDLE = 2,\n    // /libraries/codal-core/inc/core/CodalListener.h\n    MESSAGE_BUS_LISTENER_PARAMETERISED = 1,\n    MESSAGE_BUS_LISTENER_METHOD = 2,\n    MESSAGE_BUS_LISTENER_BUSY = 4,\n    MESSAGE_BUS_LISTENER_REENTRANT = 8,\n    MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY = 16,\n    MESSAGE_BUS_LISTENER_DROP_IF_BUSY = 32,\n    MESSAGE_BUS_LISTENER_NONBLOCKING = 64,\n    MESSAGE_BUS_LISTENER_URGENT = 128,\n    MESSAGE_BUS_LISTENER_DELETING = 32768,\n    MESSAGE_BUS_LISTENER_IMMEDIATE = 192,\n    // /libraries/codal-core/inc/core/ErrorNo.h\n    DEVICE_OK = 0,\n    DEVICE_INVALID_PARAMETER = -1001,\n    DEVICE_NOT_SUPPORTED = -1002,\n    DEVICE_CALIBRATION_IN_PROGRESS = -1003,\n    DEVICE_CALIBRATION_REQUIRED = -1004,\n    DEVICE_NO_RESOURCES = -1005,\n    DEVICE_BUSY = -1006,\n    DEVICE_CANCELLED = -1007,\n    DEVICE_I2C_ERROR = -1010,\n    DEVICE_SERIAL_IN_USE = -1011,\n    DEVICE_NO_DATA = -1012,\n    DEVICE_NOT_IMPLEMENTED = -1013,\n    DEVICE_SPI_ERROR = -1014,\n    DEVICE_INVALID_STATE = -1015,\n    DEVICE_OOM = 20,\n    DEVICE_HEAP_ERROR = 30,\n    DEVICE_NULL_DEREFERENCE = 40,\n    DEVICE_USB_ERROR = 50,\n    DEVICE_JACDAC_ERROR = 60,\n    DEVICE_HARDWARE_CONFIGURATION_ERROR = 90,\n    // /libraries/codal-core/inc/core/NotifyEvents.h\n    DISPLAY_EVT_FREE = 1,\n    CODAL_SERIAL_EVT_TX_EMPTY = 2,\n    BLE_EVT_SERIAL_TX_EMPTY = 3,\n    ARCADE_PLAYER_JOIN_RESULT = 4,\n    DEVICE_NOTIFY_USER_EVENT_BASE = 1024,\n    // /libraries/codal-core/inc/driver-models/AbstractButton.h\n    DEVICE_BUTTON_EVT_DOWN = 1,\n    DEVICE_BUTTON_EVT_UP = 2,\n    DEVICE_BUTTON_EVT_CLICK = 3,\n    DEVICE_BUTTON_EVT_LONG_CLICK = 4,\n    DEVICE_BUTTON_EVT_HOLD = 5,\n    DEVICE_BUTTON_EVT_DOUBLE_CLICK = 6,\n    DEVICE_BUTTON_LONG_CLICK_TIME = 1000,\n    DEVICE_BUTTON_HOLD_TIME = 1500,\n    DEVICE_BUTTON_STATE = 1,\n    DEVICE_BUTTON_STATE_HOLD_TRIGGERED = 2,\n    DEVICE_BUTTON_STATE_CLICK = 4,\n    DEVICE_BUTTON_STATE_LONG_CLICK = 8,\n    DEVICE_BUTTON_SIGMA_MIN = 0,\n    DEVICE_BUTTON_SIGMA_MAX = 12,\n    DEVICE_BUTTON_SIGMA_THRESH_HI = 8,\n    DEVICE_BUTTON_SIGMA_THRESH_LO = 2,\n    DEVICE_BUTTON_DOUBLE_CLICK_THRESH = 50,\n    DEVICE_BUTTON_SIMPLE_EVENTS = 0,\n    DEVICE_BUTTON_ALL_EVENTS = 1,\n    ACTIVE_LOW = 0,\n    ACTIVE_HIGH = 1,\n    // /libraries/codal-core/inc/driver-models/Accelerometer.h\n    ACCELEROMETER_IMU_DATA_VALID = 2,\n    ACCELEROMETER_EVT_DATA_UPDATE = 1,\n    ACCELEROMETER_EVT_NONE = 0,\n    ACCELEROMETER_EVT_TILT_UP = 1,\n    ACCELEROMETER_EVT_TILT_DOWN = 2,\n    ACCELEROMETER_EVT_TILT_LEFT = 3,\n    ACCELEROMETER_EVT_TILT_RIGHT = 4,\n    ACCELEROMETER_EVT_FACE_UP = 5,\n    ACCELEROMETER_EVT_FACE_DOWN = 6,\n    ACCELEROMETER_EVT_FREEFALL = 7,\n    ACCELEROMETER_EVT_3G = 8,\n    ACCELEROMETER_EVT_6G = 9,\n    ACCELEROMETER_EVT_8G = 10,\n    ACCELEROMETER_EVT_SHAKE = 11,\n    ACCELEROMETER_EVT_2G = 12,\n    ACCELEROMETER_REST_TOLERANCE = 200,\n    ACCELEROMETER_TILT_TOLERANCE = 200,\n    ACCELEROMETER_FREEFALL_TOLERANCE = 400,\n    ACCELEROMETER_SHAKE_TOLERANCE = 400,\n    ACCELEROMETER_2G_TOLERANCE = 2048,\n    ACCELEROMETER_3G_TOLERANCE = 3072,\n    ACCELEROMETER_6G_TOLERANCE = 6144,\n    ACCELEROMETER_8G_TOLERANCE = 8192,\n    ACCELEROMETER_GESTURE_DAMPING = 5,\n    ACCELEROMETER_SHAKE_DAMPING = 10,\n    ACCELEROMETER_SHAKE_RTX = 30,\n    ACCELEROMETER_SHAKE_COUNT_THRESHOLD = 4,\n    // /libraries/codal-core/inc/driver-models/Compass.h\n    COMPASS_STATUS_RUNNING = 1,\n    COMPASS_STATUS_CALIBRATED = 2,\n    COMPASS_STATUS_CALIBRATING = 4,\n    COMPASS_STATUS_ADDED_TO_IDLE = 8,\n    COMPASS_EVT_DATA_UPDATE = 1,\n    COMPASS_EVT_CONFIG_NEEDED = 2,\n    COMPASS_EVT_CALIBRATE = 3,\n    COMPASS_EVT_CALIBRATION_NEEDED = 4,\n    // /libraries/codal-core/inc/driver-models/Gyroscope.h\n    GYROSCOPE_IMU_DATA_VALID = 2,\n    GYROSCOPE_EVT_DATA_UPDATE = 1,\n    // /libraries/codal-core/inc/driver-models/LowLevelTimer.h\n    TimerModeTimer = 0,\n    TimerModeCounter = 1,\n    TimerModeAlternateFunction = 2,\n    BitMode8 = 0,\n    BitMode16 = 1,\n    BitMode24 = 2,\n    BitMode32 = 3,\n    // /libraries/codal-core/inc/driver-models/Pin.h\n    IO_STATUS_DIGITAL_IN = 1,\n    IO_STATUS_DIGITAL_OUT = 2,\n    IO_STATUS_ANALOG_IN = 4,\n    IO_STATUS_ANALOG_OUT = 8,\n    IO_STATUS_TOUCH_IN = 16,\n    IO_STATUS_EVENT_ON_EDGE = 32,\n    IO_STATUS_EVENT_PULSE_ON_EDGE = 64,\n    IO_STATUS_INTERRUPT_ON_EDGE = 128,\n    DEVICE_PIN_MAX_OUTPUT = 1023,\n    DEVICE_PIN_MAX_SERVO_RANGE = 180,\n    DEVICE_PIN_DEFAULT_SERVO_RANGE = 2000,\n    DEVICE_PIN_DEFAULT_SERVO_CENTER = 1500,\n    DEVICE_PIN_EVENT_NONE = 0,\n    DEVICE_PIN_INTERRUPT_ON_EDGE = 1,\n    DEVICE_PIN_EVENT_ON_EDGE = 2,\n    DEVICE_PIN_EVENT_ON_PULSE = 3,\n    DEVICE_PIN_EVENT_ON_TOUCH = 4,\n    DEVICE_PIN_EVT_RISE = 2,\n    DEVICE_PIN_EVT_FALL = 3,\n    DEVICE_PIN_EVT_PULSE_HI = 4,\n    DEVICE_PIN_EVT_PULSE_LO = 5,\n    PIN_CAPABILITY_DIGITAL = 1,\n    PIN_CAPABILITY_ANALOG = 2,\n    PIN_CAPABILITY_AD = 3,\n    PIN_CAPABILITY_ALL = 3,\n    None = 0,\n    Down = 1,\n    Up = 2,\n    // /libraries/codal-core/inc/driver-models/Radio.h\n    RADIO_EVT_DATA_READY = 2,\n    // /libraries/codal-core/inc/driver-models/SPIFlash.h\n    SPIFLASH_PAGE_SIZE = 256,\n    SPIFLASH_SMALL_ROW_PAGES = 16,\n    SPIFLASH_BIG_ROW_PAGES = 256,\n    // /libraries/codal-core/inc/driver-models/Sensor.h\n    SENSOR_THRESHOLD_LOW = 1,\n    SENSOR_THRESHOLD_HIGH = 2,\n    SENSOR_UPDATE_NEEDED = 3,\n    SENSOR_INITIALISED = 1,\n    SENSOR_HIGH_THRESHOLD_PASSED = 2,\n    SENSOR_LOW_THRESHOLD_PASSED = 4,\n    SENSOR_LOW_THRESHOLD_ENABLED = 8,\n    SENSOR_HIGH_THRESHOLD_ENABLED = 16,\n    SENSOR_DEFAULT_SENSITIVITY = 868,\n    SENSOR_DEFAULT_SAMPLE_PERIOD = 500,\n    // /libraries/codal-core/inc/driver-models/Serial.h\n    CODAL_SERIAL_DEFAULT_BAUD_RATE = 115200,\n    CODAL_SERIAL_DEFAULT_BUFFER_SIZE = 20,\n    CODAL_SERIAL_EVT_DELIM_MATCH = 1,\n    CODAL_SERIAL_EVT_HEAD_MATCH = 2,\n    CODAL_SERIAL_EVT_RX_FULL = 3,\n    CODAL_SERIAL_EVT_DATA_RECEIVED = 4,\n    CODAL_SERIAL_STATUS_RX_IN_USE = 1,\n    CODAL_SERIAL_STATUS_TX_IN_USE = 2,\n    CODAL_SERIAL_STATUS_RX_BUFF_INIT = 4,\n    CODAL_SERIAL_STATUS_TX_BUFF_INIT = 8,\n    CODAL_SERIAL_STATUS_RXD = 16,\n    ASYNC = 0,\n    SYNC_SPINWAIT = 1,\n    SYNC_SLEEP = 2,\n    RxInterrupt = 0,\n    TxInterrupt = 1,\n    // /libraries/codal-core/inc/driver-models/SingleWireSerial.h\n    SWS_EVT_DATA_RECEIVED = 1,\n    SWS_EVT_DATA_SENT = 2,\n    SWS_EVT_ERROR = 3,\n    SWS_EVT_DATA_DROPPED = 4,\n    SingleWireRx = 0,\n    SingleWireTx = 1,\n    SingleWireDisconnected = 2,\n    // /libraries/codal-core/inc/driver-models/Timer.h\n    CODAL_TIMER_DEFAULT_EVENT_LIST_SIZE = 10,\n    // /libraries/codal-core/inc/drivers/AnalogSensor.h\n    ANALOG_THRESHOLD_LOW = 1,\n    ANALOG_THRESHOLD_HIGH = 2,\n    ANALOG_SENSOR_UPDATE_NEEDED = 3,\n    ANALOG_SENSOR_INITIALISED = 1,\n    ANALOG_SENSOR_HIGH_THRESHOLD_PASSED = 2,\n    ANALOG_SENSOR_LOW_THRESHOLD_PASSED = 4,\n    ANALOG_SENSOR_LOW_THRESHOLD_ENABLED = 8,\n    ANALOG_SENSOR_HIGH_THRESHOLD_ENABLED = 16,\n    // /libraries/codal-core/inc/drivers/AnimatedDisplay.h\n    DISPLAY_EVT_ANIMATION_COMPLETE = 1,\n    DISPLAY_DEFAULT_AUTOCLEAR = 1,\n    DISPLAY_SPACING = 1,\n    DISPLAY_ANIMATE_DEFAULT_POS = -255,\n    DISPLAY_DEFAULT_SCROLL_SPEED = 120,\n    DISPLAY_DEFAULT_SCROLL_STRIDE = -1,\n    DISPLAY_DEFAULT_PRINT_SPEED = 400,\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    // /libraries/codal-core/inc/drivers/FAT.h\n    FAT_RESERVED_SECTORS = 1,\n    FAT_ROOT_DIR_SECTORS = 4,\n    // /libraries/codal-core/inc/drivers/HID.h\n    HID_REQUEST_GET_REPORT = 1,\n    HID_REQUEST_GET_IDLE = 2,\n    HID_REQUEST_GET_PROTOCOL = 3,\n    HID_REQUEST_SET_REPORT = 9,\n    HID_REQUEST_SET_IDLE = 10,\n    HID_REQUEST_SET_PROTOCOL = 11,\n    // /libraries/codal-core/inc/drivers/HIDKeyboard.h\n    HID_KEYBOARD_NUM_REPORTS = 3,\n    HID_KEYBOARD_REPORT_GENERIC = 1,\n    HID_KEYBOARD_REPORT_CONSUMER = 2,\n    HID_KEYBOARD_KEYSTATE_SIZE_GENERIC = 8,\n    HID_KEYBOARD_KEYSTATE_SIZE_CONSUMER = 2,\n    HID_KEYBOARD_MODIFIER_OFFSET = 2,\n    HID_KEYBOARD_DELAY_DEFAULT = 10,\n    PressKey = 0,\n    ReleaseKey = 1,\n    // /libraries/codal-core/inc/drivers/KeyMap.h\n    KEYMAP_ALL_KEYS_UP_Val = 1,\n    KEYMAP_ALL_KEYS_UP_POS = 28,\n    KEYMAP_NORMAL_KEY_Val = 0,\n    KEYMAP_MODIFIER_KEY_Val = 1,\n    KEYMAP_MODIFIER_POS = 29,\n    KEYMAP_MEDIA_KEY_Val = 1,\n    KEYMAP_MEDIA_POS = 30,\n    KEYMAP_KEY_UP_Val = 0,\n    KEYMAP_KEY_DOWN_Val = 1,\n    KEYMAP_KEY_DOWN_POS = 31,\n    // /libraries/codal-core/inc/drivers/KeyValueStorage.h\n    DEVICE_KEY_VALUE_STORE_OFFSET = 4,\n    KEY_VALUE_STORAGE_MAGIC = 49370,\n    KEY_VALUE_STORAGE_BLOCK_SIZE = 48,\n    KEY_VALUE_STORAGE_KEY_SIZE = 16,\n    KEY_VALUE_STORAGE_SCRATCH_WORD_SIZE = 64,\n    KEY_VALUE_STORAGE_MAX_PAIRS = 5,\n    // /libraries/codal-core/inc/drivers/LEDMatrix.h\n    LED_MATRIX_GREYSCALE_BIT_DEPTH = 8,\n    LED_MATRIX_EVT_LIGHT_SENSE = 2,\n    LED_MATRIX_EVT_FRAME_TIMEOUT = 3,\n    LED_MATRIX_MINIMUM_BRIGHTNESS = 1,\n    LED_MATRIX_MAXIMUM_BRIGHTNESS = 255,\n    LED_MATRIX_DEFAULT_BRIGHTNESS = 255,\n    DISPLAY_MODE_BLACK_AND_WHITE = 0,\n    DISPLAY_MODE_GREYSCALE = 1,\n    DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE = 2,\n    MATRIX_DISPLAY_ROTATION_0 = 0,\n    MATRIX_DISPLAY_ROTATION_90 = 1,\n    MATRIX_DISPLAY_ROTATION_180 = 2,\n    MATRIX_DISPLAY_ROTATION_270 = 3,\n    NO_CONN = 0,\n    // /libraries/codal-core/inc/drivers/MMA8653.h\n    MICROBIT_ACCEL_PITCH_ROLL_VALID = 2,\n    MICROBIT_ACCEL_ADDED_TO_IDLE = 4,\n    // /libraries/codal-core/inc/drivers/MultiButton.h\n    MULTI_BUTTON_STATE_1 = 1,\n    MULTI_BUTTON_STATE_2 = 2,\n    MULTI_BUTTON_HOLD_TRIGGERED_1 = 4,\n    MULTI_BUTTON_HOLD_TRIGGERED_2 = 8,\n    MULTI_BUTTON_SUPRESSED_1 = 16,\n    MULTI_BUTTON_SUPRESSED_2 = 32,\n    MULTI_BUTTON_ATTACHED = 64,\n    // /libraries/codal-core/inc/drivers/TouchButton.h\n    TOUCH_BUTTON_CALIBRATION_PERIOD = 10,\n    TOUCH_BUTTON_CALIBRATION_LINEAR_OFFSET = 2,\n    TOUCH_BUTTON_CALIBRATION_PERCENTAGE_OFFSET = 5,\n    TOUCH_BUTTON_CALIBRATING = 16,\n    // /libraries/codal-core/inc/drivers/TouchSensor.h\n    TOUCH_SENSOR_MAX_BUTTONS = 10,\n    TOUCH_SENSOR_SAMPLE_PERIOD = 50,\n    TOUCH_SENSE_SAMPLE_MAX = 1000,\n    TOUCH_SENSOR_UPDATE_NEEDED = 1,\n    // /libraries/codal-core/inc/drivers/USBJACDAC.h\n    JACDAC_USB_STATUS_CLEAR_TO_SEND = 2,\n    // /libraries/codal-core/inc/drivers/USB_HID_Keys.h\n    KEY_MOD_LCTRL = 1,\n    KEY_MOD_LSHIFT = 2,\n    KEY_MOD_LALT = 4,\n    KEY_MOD_LMETA = 8,\n    KEY_MOD_RCTRL = 16,\n    KEY_MOD_RSHIFT = 32,\n    KEY_MOD_RALT = 64,\n    KEY_MOD_RMETA = 128,\n    KEY_NONE = 0,\n    KEY_ERR_OVF = 1,\n    KEY_A = 4,\n    KEY_B = 5,\n    KEY_C = 6,\n    KEY_D = 7,\n    KEY_E = 8,\n    KEY_F = 9,\n    KEY_G = 10,\n    KEY_H = 11,\n    KEY_I = 12,\n    KEY_J = 13,\n    KEY_K = 14,\n    KEY_L = 15,\n    KEY_M = 16,\n    KEY_N = 17,\n    KEY_O = 18,\n    KEY_P = 19,\n    KEY_Q = 20,\n    KEY_R = 21,\n    KEY_S = 22,\n    KEY_T = 23,\n    KEY_U = 24,\n    KEY_V = 25,\n    KEY_W = 26,\n    KEY_X = 27,\n    KEY_Y = 28,\n    KEY_Z = 29,\n    KEY_1 = 30,\n    KEY_2 = 31,\n    KEY_3 = 32,\n    KEY_4 = 33,\n    KEY_5 = 34,\n    KEY_6 = 35,\n    KEY_7 = 36,\n    KEY_8 = 37,\n    KEY_9 = 38,\n    KEY_0 = 39,\n    KEY_ENTER = 40,\n    KEY_ESC = 41,\n    KEY_BACKSPACE = 42,\n    KEY_TAB = 43,\n    KEY_SPACE = 44,\n    KEY_MINUS = 45,\n    KEY_EQUAL = 46,\n    KEY_LEFTBRACE = 47,\n    KEY_RIGHTBRACE = 48,\n    KEY_BACKSLASH = 49,\n    KEY_HASHTILDE = 50,\n    KEY_SEMICOLON = 51,\n    KEY_APOSTROPHE = 52,\n    KEY_GRAVE = 53,\n    KEY_COMMA = 54,\n    KEY_DOT = 55,\n    KEY_SLASH = 56,\n    KEY_CAPSLOCK = 57,\n    KEY_F1 = 58,\n    KEY_F2 = 59,\n    KEY_F3 = 60,\n    KEY_F4 = 61,\n    KEY_F5 = 62,\n    KEY_F6 = 63,\n    KEY_F7 = 64,\n    KEY_F8 = 65,\n    KEY_F9 = 66,\n    KEY_F10 = 67,\n    KEY_F11 = 68,\n    KEY_F12 = 69,\n    KEY_SYSRQ = 70,\n    KEY_SCROLLLOCK = 71,\n    KEY_PAUSE = 72,\n    KEY_INSERT = 73,\n    KEY_HOME = 74,\n    KEY_PAGEUP = 75,\n    KEY_DELETE = 76,\n    KEY_END = 77,\n    KEY_PAGEDOWN = 78,\n    KEY_RIGHT = 79,\n    KEY_LEFT = 80,\n    KEY_DOWN = 81,\n    KEY_UP = 82,\n    KEY_NUMLOCK = 83,\n    KEY_KPSLASH = 84,\n    KEY_KPASTERISK = 85,\n    KEY_KPMINUS = 86,\n    KEY_KPPLUS = 87,\n    KEY_KPENTER = 88,\n    KEY_KP1 = 89,\n    KEY_KP2 = 90,\n    KEY_KP3 = 91,\n    KEY_KP4 = 92,\n    KEY_KP5 = 93,\n    KEY_KP6 = 94,\n    KEY_KP7 = 95,\n    KEY_KP8 = 96,\n    KEY_KP9 = 97,\n    KEY_KP0 = 98,\n    KEY_KPDOT = 99,\n    KEY_102ND = 100,\n    KEY_COMPOSE = 101,\n    KEY_POWER = 102,\n    KEY_KPEQUAL = 103,\n    KEY_F13 = 104,\n    KEY_F14 = 105,\n    KEY_F15 = 106,\n    KEY_F16 = 107,\n    KEY_F17 = 108,\n    KEY_F18 = 109,\n    KEY_F19 = 110,\n    KEY_F20 = 111,\n    KEY_F21 = 112,\n    KEY_F22 = 113,\n    KEY_F23 = 114,\n    KEY_F24 = 115,\n    KEY_OPEN = 116,\n    KEY_HELP = 117,\n    KEY_PROPS = 118,\n    KEY_FRONT = 119,\n    KEY_STOP = 120,\n    KEY_AGAIN = 121,\n    KEY_UNDO = 122,\n    KEY_CUT = 123,\n    KEY_COPY = 124,\n    KEY_PASTE = 125,\n    KEY_FIND = 126,\n    KEY_MUTE = 127,\n    KEY_VOLUMEUP = 128,\n    KEY_VOLUMEDOWN = 129,\n    KEY_KPCOMMA = 133,\n    KEY_RO = 135,\n    KEY_KATAKANAHIRAGANA = 136,\n    KEY_YEN = 137,\n    KEY_HENKAN = 138,\n    KEY_MUHENKAN = 139,\n    KEY_KPJPCOMMA = 140,\n    KEY_HANGEUL = 144,\n    KEY_HANJA = 145,\n    KEY_KATAKANA = 146,\n    KEY_HIRAGANA = 147,\n    KEY_ZENKAKUHANKAKU = 148,\n    KEY_KPLEFTPAREN = 182,\n    KEY_KPRIGHTPAREN = 183,\n    KEY_LEFTCTRL = 224,\n    KEY_LEFTSHIFT = 225,\n    KEY_LEFTALT = 226,\n    KEY_LEFTMETA = 227,\n    KEY_RIGHTCTRL = 228,\n    KEY_RIGHTSHIFT = 229,\n    KEY_RIGHTALT = 230,\n    KEY_RIGHTMETA = 231,\n    KEY_MEDIA_PLAYPAUSE = 232,\n    KEY_MEDIA_STOPCD = 233,\n    KEY_MEDIA_PREVIOUSSONG = 234,\n    KEY_MEDIA_NEXTSONG = 235,\n    KEY_MEDIA_EJECTCD = 236,\n    KEY_MEDIA_VOLUMEUP = 237,\n    KEY_MEDIA_VOLUMEDOWN = 238,\n    KEY_MEDIA_MUTE = 239,\n    KEY_MEDIA_WWW = 240,\n    KEY_MEDIA_BACK = 241,\n    KEY_MEDIA_FORWARD = 242,\n    KEY_MEDIA_STOP = 243,\n    KEY_MEDIA_FIND = 244,\n    KEY_MEDIA_SCROLLUP = 245,\n    KEY_MEDIA_SCROLLDOWN = 246,\n    KEY_MEDIA_EDIT = 247,\n    KEY_MEDIA_SLEEP = 248,\n    KEY_MEDIA_COFFEE = 249,\n    KEY_MEDIA_REFRESH = 250,\n    KEY_MEDIA_CALC = 251,\n    // /libraries/codal-core/inc/drivers/uf2format.h\n    UF2FORMAT_H = 1,\n    APP_START_ADDRESS = 8192,\n    UF2_FLAG_NOFLASH = 1,\n    // /libraries/codal-core/inc/streams/DataStream.h\n    DATASTREAM_MAXIMUM_BUFFERS = 1,\n    // /libraries/codal-core/inc/streams/LevelDetector.h\n    LEVEL_THRESHOLD_LOW = 1,\n    LEVEL_THRESHOLD_HIGH = 2,\n    LEVEL_DETECTOR_INITIALISED = 1,\n    LEVEL_DETECTOR_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_DEFAULT_WINDOW_SIZE = 128,\n    // /libraries/codal-core/inc/streams/LevelDetectorSPL.h\n    LEVEL_DETECTOR_SPL_INITIALISED = 1,\n    LEVEL_DETECTOR_SPL_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_SPL_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_SPL_DEFAULT_WINDOW_SIZE = 128,\n    // /libraries/codal-core/inc/streams/MemorySource.h\n    MEMORY_SOURCE_MAX_BUFFER = 256,\n    // /libraries/codal-core/inc/streams/Synthesizer.h\n    SYNTHESIZER_SAMPLE_RATE = 44100,\n    TONE_WIDTH = 1024,\n    // /libraries/codal-core/inc/types/BitmapFont.h\n    BITMAP_FONT_WIDTH = 5,\n    BITMAP_FONT_HEIGHT = 5,\n    BITMAP_FONT_ASCII_START = 32,\n    BITMAP_FONT_ASCII_END = 126,\n    // /libraries/codal-core/inc/types/CoordinateSystem.h\n    COORDINATE_SPACE_ROTATED_0 = 0,\n    COORDINATE_SPACE_ROTATED_90 = 1,\n    COORDINATE_SPACE_ROTATED_180 = 2,\n    COORDINATE_SPACE_ROTATED_270 = 3,\n    RAW = 0,\n    SIMPLE_CARTESIAN = 1,\n    NORTH_EAST_DOWN = 2,\n    NORTH_EAST_UP = 3,\n    // /libraries/codal-core/inc/types/Event.h\n    DEVICE_ID_ANY = 0,\n    DEVICE_EVT_ANY = 0,\n    CREATE_ONLY = 0,\n    CREATE_AND_FIRE = 1,\n    DEVICE_EVENT_DEFAULT_LAUNCH_MODE = 1,\n    // /libraries/codal-core/inc/types/RefCounted.h\n    REF_TAG_STRING = 1,\n    REF_TAG_BUFFER = 2,\n    REF_TAG_IMAGE = 3,\n    REF_TAG_USER = 32,\n    // /pxtapp/accelerometer/axis.h\n    ACC_SYSTEM = 3,\n    ACC_ROTATION = 0,\n    // /pxtapp/configkeys.h\n    CFG_PIN_NAME_MSK = 65535,\n    CFG_PIN_CONFIG_MSK = 4294901760,\n    CFG_PIN_CONFIG_ACTIVE_LO = 65536,\n    CFG_MAGIC0 = 513675505,\n    CFG_MAGIC1 = 539130489,\n    CFG_PIN_ACCELEROMETER_INT = 1,\n    CFG_PIN_ACCELEROMETER_SCL = 2,\n    CFG_PIN_ACCELEROMETER_SDA = 3,\n    CFG_PIN_BTN_A = 4,\n    CFG_PIN_BTN_B = 5,\n    CFG_PIN_BTN_SLIDE = 6,\n    CFG_PIN_DOTSTAR_CLOCK = 7,\n    CFG_PIN_DOTSTAR_DATA = 8,\n    CFG_PIN_FLASH_CS = 9,\n    CFG_PIN_FLASH_MISO = 10,\n    CFG_PIN_FLASH_MOSI = 11,\n    CFG_PIN_FLASH_SCK = 12,\n    CFG_PIN_LED = 13,\n    CFG_PIN_LIGHT = 14,\n    CFG_PIN_MICROPHONE = 15,\n    CFG_PIN_MIC_CLOCK = 16,\n    CFG_PIN_MIC_DATA = 17,\n    CFG_PIN_MISO = 18,\n    CFG_PIN_MOSI = 19,\n    CFG_PIN_NEOPIXEL = 20,\n    CFG_PIN_RX = 21,\n    CFG_PIN_RXLED = 22,\n    CFG_PIN_SCK = 23,\n    CFG_PIN_SCL = 24,\n    CFG_PIN_SDA = 25,\n    CFG_PIN_SPEAKER_AMP = 26,\n    CFG_PIN_TEMPERATURE = 27,\n    CFG_PIN_TX = 28,\n    CFG_PIN_TXLED = 29,\n    CFG_PIN_IR_OUT = 30,\n    CFG_PIN_IR_IN = 31,\n    CFG_PIN_DISPLAY_SCK = 32,\n    CFG_PIN_DISPLAY_MISO = 33,\n    CFG_PIN_DISPLAY_MOSI = 34,\n    CFG_PIN_DISPLAY_CS = 35,\n    CFG_PIN_DISPLAY_DC = 36,\n    CFG_DISPLAY_WIDTH = 37,\n    CFG_DISPLAY_HEIGHT = 38,\n    CFG_DISPLAY_CFG0 = 39,\n    CFG_DISPLAY_CFG1 = 40,\n    CFG_DISPLAY_CFG2 = 41,\n    CFG_DISPLAY_CFG3 = 42,\n    CFG_PIN_DISPLAY_RST = 43,\n    CFG_PIN_DISPLAY_BL = 44,\n    CFG_PIN_SERVO_1 = 45,\n    CFG_PIN_SERVO_2 = 46,\n    CFG_PIN_BTN_LEFT = 47,\n    CFG_PIN_BTN_RIGHT = 48,\n    CFG_PIN_BTN_UP = 49,\n    CFG_PIN_BTN_DOWN = 50,\n    CFG_PIN_BTN_MENU = 51,\n    CFG_PIN_LED_R = 52,\n    CFG_PIN_LED_G = 53,\n    CFG_PIN_LED_B = 54,\n    CFG_PIN_LED1 = 55,\n    CFG_PIN_LED2 = 56,\n    CFG_PIN_LED3 = 57,\n    CFG_PIN_LED4 = 58,\n    CFG_SPEAKER_VOLUME = 59,\n    CFG_PIN_JACK_TX = 60,\n    CFG_PIN_JACK_SENSE = 61,\n    CFG_PIN_JACK_HPEN = 62,\n    CFG_PIN_JACK_BZEN = 63,\n    CFG_PIN_JACK_PWREN = 64,\n    CFG_PIN_JACK_SND = 65,\n    CFG_PIN_JACK_BUSLED = 66,\n    CFG_PIN_JACK_COMMLED = 67,\n    CFG_PIN_BTN_SOFT_RESET = 69,\n    CFG_ACCELEROMETER_TYPE = 70,\n    CFG_PIN_BTNMX_LATCH = 71,\n    CFG_PIN_BTNMX_CLOCK = 72,\n    CFG_PIN_BTNMX_DATA = 73,\n    CFG_PIN_BTN_MENU2 = 74,\n    CFG_PIN_BATTSENSE = 75,\n    CFG_PIN_VIBRATION = 76,\n    CFG_PIN_PWREN = 77,\n    CFG_DISPLAY_TYPE = 78,\n    CFG_PIN_ROTARY_ENCODER_A = 79,\n    CFG_PIN_ROTARY_ENCODER_B = 80,\n    CFG_ACCELEROMETER_SPACE = 81,\n    CFG_PIN_WIFI_MOSI = 82,\n    CFG_PIN_WIFI_MISO = 83,\n    CFG_PIN_WIFI_SCK = 84,\n    CFG_PIN_WIFI_TX = 85,\n    CFG_PIN_WIFI_RX = 86,\n    CFG_PIN_WIFI_CS = 87,\n    CFG_PIN_WIFI_BUSY = 88,\n    CFG_PIN_WIFI_RESET = 89,\n    CFG_PIN_WIFI_GPIO0 = 90,\n    CFG_PIN_WIFI_AT_TX = 91,\n    CFG_PIN_WIFI_AT_RX = 92,\n    CFG_PIN_USB_POWER = 93,\n    CFG_DISPLAY_DELAY = 94,\n    ACCELEROMETER_TYPE_LIS3DH = 50,\n    ACCELEROMETER_TYPE_LIS3DH_ALT = 48,\n    ACCELEROMETER_TYPE_MMA8453 = 56,\n    ACCELEROMETER_TYPE_FXOS8700 = 60,\n    ACCELEROMETER_TYPE_MMA8653 = 58,\n    ACCELEROMETER_TYPE_MSA300 = 76,\n    ACCELEROMETER_TYPE_MPU6050 = 104,\n    DISPLAY_TYPE_ST7735 = 7735,\n    DISPLAY_TYPE_ILI9341 = 9341,\n    DISPLAY_TYPE_SMART = 4242,\n    CFG_PIN_A0 = 100,\n    CFG_PIN_A1 = 101,\n    CFG_PIN_A2 = 102,\n    CFG_PIN_A3 = 103,\n    CFG_PIN_A4 = 104,\n    CFG_PIN_A5 = 105,\n    CFG_PIN_A6 = 106,\n    CFG_PIN_A7 = 107,\n    CFG_PIN_A8 = 108,\n    CFG_PIN_A9 = 109,\n    CFG_PIN_A10 = 110,\n    CFG_PIN_A11 = 111,\n    CFG_PIN_A12 = 112,\n    CFG_PIN_A13 = 113,\n    CFG_PIN_A14 = 114,\n    CFG_PIN_A15 = 115,\n    CFG_PIN_A16 = 116,\n    CFG_PIN_A17 = 117,\n    CFG_PIN_A18 = 118,\n    CFG_PIN_A19 = 119,\n    CFG_PIN_A20 = 120,\n    CFG_PIN_A21 = 121,\n    CFG_PIN_A22 = 122,\n    CFG_PIN_A23 = 123,\n    CFG_PIN_A24 = 124,\n    CFG_PIN_A25 = 125,\n    CFG_PIN_A26 = 126,\n    CFG_PIN_A27 = 127,\n    CFG_PIN_A28 = 128,\n    CFG_PIN_A29 = 129,\n    CFG_PIN_A30 = 130,\n    CFG_PIN_A31 = 131,\n    CFG_PIN_D0 = 150,\n    CFG_PIN_D1 = 151,\n    CFG_PIN_D2 = 152,\n    CFG_PIN_D3 = 153,\n    CFG_PIN_D4 = 154,\n    CFG_PIN_D5 = 155,\n    CFG_PIN_D6 = 156,\n    CFG_PIN_D7 = 157,\n    CFG_PIN_D8 = 158,\n    CFG_PIN_D9 = 159,\n    CFG_PIN_D10 = 160,\n    CFG_PIN_D11 = 161,\n    CFG_PIN_D12 = 162,\n    CFG_PIN_D13 = 163,\n    CFG_PIN_D14 = 164,\n    CFG_PIN_D15 = 165,\n    CFG_PIN_D16 = 166,\n    CFG_PIN_D17 = 167,\n    CFG_PIN_D18 = 168,\n    CFG_PIN_D19 = 169,\n    CFG_PIN_D20 = 170,\n    CFG_PIN_D21 = 171,\n    CFG_PIN_D22 = 172,\n    CFG_PIN_D23 = 173,\n    CFG_PIN_D24 = 174,\n    CFG_PIN_D25 = 175,\n    CFG_PIN_D26 = 176,\n    CFG_PIN_D27 = 177,\n    CFG_PIN_D28 = 178,\n    CFG_PIN_D29 = 179,\n    CFG_PIN_D30 = 180,\n    CFG_PIN_D31 = 181,\n    CFG_NUM_NEOPIXELS = 200,\n    CFG_NUM_DOTSTARS = 201,\n    CFG_DEFAULT_BUTTON_MODE = 202,\n    CFG_SWD_ENABLED = 203,\n    CFG_FLASH_BYTES = 204,\n    CFG_RAM_BYTES = 205,\n    CFG_SYSTEM_HEAP_BYTES = 206,\n    CFG_LOW_MEM_SIMULATION_KB = 207,\n    CFG_BOOTLOADER_BOARD_ID = 208,\n    CFG_UF2_FAMILY = 209,\n    CFG_PINS_PORT_SIZE = 210,\n    CFG_BOOTLOADER_PROTECTION = 211,\n    CFG_POWER_DEEPSLEEP_TIMEOUT = 212,\n    CFG_ANALOG_BUTTON_THRESHOLD = 213,\n    CFG_CPU_MHZ = 214,\n    CFG_CONTROLLER_LIGHT_MAX_BRIGHTNESS = 215,\n    CFG_ANALOG_JOYSTICK_MIN = 216,\n    CFG_ANALOG_JOYSTICK_MAX = 217,\n    CFG_TIMERS_TO_USE = 218,\n    CFG_PIN_ONBOARD_DOTSTAR_CLOCK = 219,\n    CFG_PIN_ONBOARD_DOTSTAR_DATA = 220,\n    CFG_NUM_ONBOARD_DOTSTARS = 221,\n    CFG_PIN_ONBOARD_NEOPIXEL = 222,\n    CFG_NUM_ONBOARD_NEOPIXELS = 223,\n    CFG_MATRIX_KEYPAD_MESSAGE_ID = 239,\n    CFG_NUM_MATRIX_KEYPAD_ROWS = 240,\n    CFG_PIN_MATRIX_KEYPAD_ROW0 = 241,\n    CFG_PIN_MATRIX_KEYPAD_ROW1 = 242,\n    CFG_PIN_MATRIX_KEYPAD_ROW2 = 243,\n    CFG_PIN_MATRIX_KEYPAD_ROW3 = 244,\n    CFG_PIN_MATRIX_KEYPAD_ROW4 = 245,\n    CFG_PIN_MATRIX_KEYPAD_ROW5 = 246,\n    CFG_PIN_MATRIX_KEYPAD_ROW6 = 247,\n    CFG_PIN_MATRIX_KEYPAD_ROW7 = 248,\n    CFG_NUM_MATRIX_KEYPAD_COLS = 250,\n    CFG_PIN_MATRIX_KEYPAD_COL0 = 251,\n    CFG_PIN_MATRIX_KEYPAD_COL1 = 252,\n    CFG_PIN_MATRIX_KEYPAD_COL2 = 253,\n    CFG_PIN_MATRIX_KEYPAD_COL3 = 254,\n    CFG_PIN_MATRIX_KEYPAD_COL4 = 255,\n    CFG_PIN_MATRIX_KEYPAD_COL5 = 256,\n    CFG_PIN_MATRIX_KEYPAD_COL6 = 257,\n    CFG_PIN_MATRIX_KEYPAD_COL7 = 258,\n    CFG_PIN_B0 = 300,\n    CFG_PIN_B1 = 301,\n    CFG_PIN_B2 = 302,\n    CFG_PIN_B3 = 303,\n    CFG_PIN_B4 = 304,\n    CFG_PIN_B5 = 305,\n    CFG_PIN_B6 = 306,\n    CFG_PIN_B7 = 307,\n    CFG_PIN_B8 = 308,\n    CFG_PIN_B9 = 309,\n    CFG_PIN_B10 = 310,\n    CFG_PIN_B11 = 311,\n    CFG_PIN_B12 = 312,\n    CFG_PIN_B13 = 313,\n    CFG_PIN_B14 = 314,\n    CFG_PIN_B15 = 315,\n    CFG_PIN_B16 = 316,\n    CFG_PIN_B17 = 317,\n    CFG_PIN_B18 = 318,\n    CFG_PIN_B19 = 319,\n    CFG_PIN_B20 = 320,\n    CFG_PIN_B21 = 321,\n    CFG_PIN_B22 = 322,\n    CFG_PIN_B23 = 323,\n    CFG_PIN_B24 = 324,\n    CFG_PIN_B25 = 325,\n    CFG_PIN_B26 = 326,\n    CFG_PIN_B27 = 327,\n    CFG_PIN_B28 = 328,\n    CFG_PIN_B29 = 329,\n    CFG_PIN_B30 = 330,\n    CFG_PIN_B31 = 331,\n    CFG_PIN_C0 = 350,\n    CFG_PIN_C1 = 351,\n    CFG_PIN_C2 = 352,\n    CFG_PIN_C3 = 353,\n    CFG_PIN_C4 = 354,\n    CFG_PIN_C5 = 355,\n    CFG_PIN_C6 = 356,\n    CFG_PIN_C7 = 357,\n    CFG_PIN_C8 = 358,\n    CFG_PIN_C9 = 359,\n    CFG_PIN_C10 = 360,\n    CFG_PIN_C11 = 361,\n    CFG_PIN_C12 = 362,\n    CFG_PIN_C13 = 363,\n    CFG_PIN_C14 = 364,\n    CFG_PIN_C15 = 365,\n    CFG_PIN_C16 = 366,\n    CFG_PIN_C17 = 367,\n    CFG_PIN_C18 = 368,\n    CFG_PIN_C19 = 369,\n    CFG_PIN_C20 = 370,\n    CFG_PIN_C21 = 371,\n    CFG_PIN_C22 = 372,\n    CFG_PIN_C23 = 373,\n    CFG_PIN_C24 = 374,\n    CFG_PIN_C25 = 375,\n    CFG_PIN_C26 = 376,\n    CFG_PIN_C27 = 377,\n    CFG_PIN_C28 = 378,\n    CFG_PIN_C29 = 379,\n    CFG_PIN_C30 = 380,\n    CFG_PIN_C31 = 381,\n    CFG_PIN_P0 = 400,\n    CFG_PIN_P1 = 401,\n    CFG_PIN_P2 = 402,\n    CFG_PIN_P3 = 403,\n    CFG_PIN_P4 = 404,\n    CFG_PIN_P5 = 405,\n    CFG_PIN_P6 = 406,\n    CFG_PIN_P7 = 407,\n    CFG_PIN_P8 = 408,\n    CFG_PIN_P9 = 409,\n    CFG_PIN_P10 = 410,\n    CFG_PIN_P11 = 411,\n    CFG_PIN_P12 = 412,\n    CFG_PIN_P13 = 413,\n    CFG_PIN_P14 = 414,\n    CFG_PIN_P15 = 415,\n    CFG_PIN_P16 = 416,\n    CFG_PIN_P17 = 417,\n    CFG_PIN_P18 = 418,\n    CFG_PIN_P19 = 419,\n    CFG_PIN_P20 = 420,\n    CFG_PIN_P21 = 421,\n    CFG_PIN_P22 = 422,\n    CFG_PIN_P23 = 423,\n    CFG_PIN_P24 = 424,\n    CFG_PIN_P25 = 425,\n    CFG_PIN_P26 = 426,\n    CFG_PIN_P27 = 427,\n    CFG_PIN_P28 = 428,\n    CFG_PIN_P29 = 429,\n    CFG_PIN_P30 = 430,\n    CFG_PIN_P31 = 431,\n    CFG_PIN_LORA_MISO = 1001,\n    CFG_PIN_LORA_MOSI = 1002,\n    CFG_PIN_LORA_SCK = 1003,\n    CFG_PIN_LORA_CS = 1004,\n    CFG_PIN_LORA_BOOT = 1005,\n    CFG_PIN_LORA_RESET = 1006,\n    CFG_PIN_IRRXLED = 1007,\n    CFG_PIN_IRTXLED = 1008,\n    CFG_PIN_LCD_RESET = 1009,\n    CFG_PIN_LCD_ENABLE = 1010,\n    CFG_PIN_LCD_DATALINE4 = 1011,\n    CFG_PIN_LCD_DATALINE5 = 1012,\n    CFG_PIN_LCD_DATALINE6 = 1013,\n    CFG_PIN_LCD_DATALINE7 = 1014,\n    CFG_NUM_LCD_COLUMNS = 1015,\n    CFG_NUM_LCD_ROWS = 1016,\n    CFG_PIN_RCC0 = 1017,\n    CFG_PIN_RCC1 = 1018,\n    CFG_PIN_RCC2 = 1019,\n    CFG_PIN_RCC3 = 1020,\n    CFG_PIN_RCC4 = 1021,\n    CFG_PIN_RCC5 = 1022,\n    CFG_PIN_RCC6 = 1023,\n    CFG_PIN_RCC7 = 1024,\n    CFG_PIN_SERVO0 = 1025,\n    CFG_PIN_SERVO1 = 1026,\n    CFG_PIN_SERVO2 = 1027,\n    CFG_PIN_SERVO3 = 1028,\n    CFG_PIN_SERVO4 = 1029,\n    CFG_PIN_SERVO5 = 1030,\n    CFG_PIN_SERVO6 = 1031,\n    CFG_PIN_SERVO7 = 1032,\n    CFG_PIN_SERVO8 = 1033,\n    CFG_PIN_PI_TX = 1034,\n    CFG_PIN_PI_RX = 1035,\n    CFG_PIN_GPS_SDA = 1036,\n    CFG_PIN_GPS_SCL = 1037,\n    CFG_PIN_GPS_TX = 1038,\n    CFG_PIN_GPS_RX = 1039,\n    CFG_PIN_GROVE0 = 1040,\n    CFG_PIN_GROVE1 = 1041,\n    CFG_PIN_SS = 1042,\n    CFG_USER_CFG_0 = 2000,\n    CFG_USER_CFG_1 = 2001,\n    CFG_USER_CFG_2 = 2002,\n    CFG_USER_CFG_3 = 2003,\n    CFG_USER_CFG_4 = 2004,\n    CFG_USER_CFG_5 = 2005,\n    CFG_USER_CFG_6 = 2006,\n    CFG_USER_CFG_7 = 2007,\n    CFG_USER_CFG_8 = 2008,\n    CFG_USER_CFG_9 = 2009,\n    CFG_ARCADE_CFG_0 = 2100,\n    CFG_ARCADE_CFG_1 = 2101,\n    CFG_ARCADE_SCREEN_WIDTH = 2102,\n    CFG_ARCADE_SCREEN_HEIGHT = 2103,\n\n    // /pxtapp/hf2dbg.h\n    HF2DBG_H = 1,\n    // /pxtapp/jacdac/jdprotocol.h\n    JDSPI_MAGIC = 31437,\n    JDSPI_MAGIC_NOOP = 46029,\n    // /pxtapp/pins.h\n    BUTTON_ACTIVE_HIGH_PULL_DOWN = 17,\n    BUTTON_ACTIVE_HIGH_PULL_UP = 33,\n    BUTTON_ACTIVE_HIGH_PULL_NONE = 49,\n    BUTTON_ACTIVE_LOW_PULL_DOWN = 16,\n    BUTTON_ACTIVE_LOW_PULL_UP = 32,\n    BUTTON_ACTIVE_LOW_PULL_NONE = 48,\n    // /pxtapp/platform.h\n    PAGE_SIZE = 4096,\n    IMAGE_BITS = 4,\n    DEFAULT_NEOPIXEL_PIN = 0,\n    TEMPERATURE_NOMINAL_VALUE = 25,\n    TEMPERATURE_NOMINAL_READING = 10000,\n    TEMPERATURE_BETA = 3380,\n    TEMPERATURE_SERIES_RESISTOR = 10000,\n    LIGHTSENSOR_SENSITIVITY = 868,\n    LIGHTSENSOR_LOW_THRESHOLD = 128,\n    LIGHTSENSOR_HIGH_THRESHOLD = 896,\n    P0_0 = 0,\n    P0_1 = 1,\n    P0_2 = 2,\n    P0_3 = 3,\n    P0_4 = 4,\n    P0_5 = 5,\n    P0_6 = 6,\n    P0_7 = 7,\n    P0_8 = 8,\n    P0_9 = 9,\n    P0_10 = 10,\n    P0_11 = 11,\n    P0_12 = 12,\n    P0_13 = 13,\n    P0_14 = 14,\n    P0_15 = 15,\n    P0_16 = 16,\n    P0_17 = 17,\n    P0_18 = 18,\n    P0_19 = 19,\n    P0_20 = 20,\n    P0_21 = 21,\n    P0_22 = 22,\n    P0_23 = 23,\n    P0_24 = 24,\n    P0_25 = 25,\n    P0_26 = 26,\n    P0_27 = 27,\n    P0_28 = 28,\n    P0_29 = 29,\n    P0_30 = 30,\n    P0_31 = 31,\n    P1_0 = 32,\n    P1_1 = 33,\n    P1_2 = 34,\n    P1_3 = 35,\n    P1_4 = 36,\n    P1_5 = 37,\n    P1_6 = 38,\n    P1_7 = 39,\n    P1_8 = 40,\n    P1_9 = 41,\n    P1_10 = 42,\n    P1_11 = 43,\n    P1_12 = 44,\n    P1_13 = 45,\n    P1_14 = 46,\n    P1_15 = 47,\n    P1_16 = 48,\n    P1_17 = 49,\n    P1_18 = 50,\n    P1_19 = 51,\n    P1_20 = 52,\n    P1_21 = 53,\n    P1_22 = 54,\n    P1_23 = 55,\n    P1_24 = 56,\n    P1_25 = 57,\n    P1_26 = 58,\n    P1_27 = 59,\n    P1_28 = 60,\n    P1_29 = 61,\n    P1_30 = 62,\n    P1_31 = 63,\n    // /pxtapp/pxt.h\n    DEVICE_ID_BUTTON_SLIDE = 3000,\n    DEVICE_ID_MICROPHONE = 3001,\n    DEVICE_ID_FIRST_BUTTON = 4000,\n    DEVICE_ID_FIRST_TOUCHBUTTON = 4100,\n    PXT_INTERNAL_KEY_UP = 2050,\n    PXT_INTERNAL_KEY_DOWN = 2051,\n    // /pxtapp/pxtbase.h\n    PXT32 = 1,\n    PXT64 = 1,\n    PXT_REFCNT_FLASH = 65534,\n    VTABLE_MAGIC = 249,\n    Undefined = 0,\n    Boolean = 1,\n    Number = 2,\n    String = 3,\n    Object = 4,\n    Function = 5,\n    BoxedString = 1,\n    BoxedNumber = 2,\n    BoxedBuffer = 3,\n    RefAction = 4,\n    RefImage = 5,\n    RefCollection = 6,\n    RefRefLocal = 7,\n    RefMap = 8,\n    RefMImage = 9,\n    MMap = 10,\n    User0 = 16,\n    PXT_IOS_HEAP_ALLOC_BITS = 20,\n    IMAGE_HEADER_MAGIC = 135,\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    UInt32LE = 11,\n    UInt32BE = 12,\n    Float32LE = 13,\n    Float64LE = 14,\n    Float32BE = 15,\n    Float64BE = 16,\n    NUM_TRY_FRAME_REGS = 3,\n    GC = 0,\n    // /pxtapp/pxtconfig.h\n    PXT_UF2_FAMILY = 2913282112,\n    // /pxtapp/settings/Flash.h\n    DEVICE_FLASH_ERROR = 922,\n    // /pxtapp/settings/RAFFS.h\n    RAFFS_FOLLOWING_MASK = 32768,\n    RAFFS_FLASH_BUFFER_SIZE = 64,\n    // /pxtapp/uf2format.h\n    BOOTLOADER_START = 0,\n    BOOTLOADER_END = 8192,\n    // /pxtapp/uf2hid.h\n    UF2_HID_H = 1,\n}\n","dmac.cpp":"#include \"dmac.h\"\n\nnamespace pxt {\n\n#ifdef CODAL_DMAC\nSINGLETON(WDMAC);\n#endif\n\n}","dmac.h":"#ifndef __DMAC_H\n#define __DMAC_H\n\n#include \"pxt.h\"\n\nnamespace pxt {\n\n#ifdef CODAL_DMAC\nclass WDMAC {\n  public:\n    CODAL_DMAC dmac;\n\n    WDMAC() {}\n};\n\nWDMAC* getWDMAC();\n#endif\n\n}\n\n#endif","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum PulseValue {\n    //% block=high\n    High = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=low\n    Low = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    }\n\n\n    declare const enum PinEvent {\n    //% block=\"pulse high\"\n    PulseHigh = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=\"pulse low\"\n    PulseLow = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    //% block=\"rise\"\n    Rise = 2,  // DEVICE_PIN_EVT_RISE\n    //% block=\"fall\"\n    Fall = 3,  // DEVICE_PIN_EVT_FALL\n    }\n\n\n    declare const enum PinPullMode {\n    //% block=\"down\"\n    PullDown = 0,\n    //% block=\"up\"\n    PullUp = 1,\n    //% block=\"none\"\n    PullNone = 2,\n    }\n\n// Auto-generated. Do not edit. Really.\n","hf2.cpp":"#include \"pxt.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#ifndef USB_HANDOVER\n#define USB_HANDOVER 1\n#endif\n\n#if USB_HANDOVER\n#define UF2_DEFINE_HANDOVER 1\n#endif\n\n#include \"uf2format.h\"\n\nstatic void *stackCopy;\nstatic uint32_t stackSize;\n\n//#define LOG DMESG\n#define LOG(...) ((void)0)\n\nstatic volatile bool resume = false;\n\nusing namespace codal;\n\n#ifdef HF2_HID\nstatic const char hidDescriptor[] = {\n    0x06, 0x97, 0xFF, // usage page vendor 0x97 (usage 0xff97 0x0001)\n    0x09, 0x01,       // usage 1\n    0xA1, 0x01,       // collection - application\n    0x15, 0x00,       // logical min 0\n    0x26, 0xFF, 0x00, // logical max 255\n    0x75, 8,          // report size 8\n    0x95, 64,         // report count 64\n    0x09, 0x01,       // usage 1\n    0x81, 0x02,       // input: data, variable, absolute\n    0x95, 64,         // report count 64\n    0x09, 0x01,       // usage 1\n    0x91, 0x02,       // output: data, variable, absolute\n    0x95, 1,          // report count 1\n    0x09, 0x01,       // usage 1\n    0xB1, 0x02,       // feature: data, variable, absolute\n    0xC0,             // end\n};\n\nstatic const HIDReportDescriptor reportDesc = {\n    9,\n    0x21,                  // HID\n    0x100,                 // hidbcd 1.00\n    0x00,                  // country code\n    0x01,                  // num desc\n    0x22,                  // report desc type\n    sizeof(hidDescriptor), // size of 0x22\n};\n\nstatic const InterfaceInfo ifaceInfoHID = {\n    &reportDesc,\n    sizeof(reportDesc),\n    1,\n    {\n        2,    // numEndpoints\n        0x03, /// class code - HID\n        0x00, // subclass\n        0x00, // protocol\n        0x02, // string\n        0x00, // alt\n    },\n    {USB_EP_TYPE_INTERRUPT, 1},\n    {USB_EP_TYPE_INTERRUPT, 1},\n};\n#endif\n\nstatic const InterfaceInfo ifaceInfoEP = {\n    NULL,\n    0,\n    2,\n    {\n        2,    // numEndpoints\n        0xff, /// class code - vendor-specific\n        42,   // subclass\n        1,    // protocol\n        0x02, // string\n        0x00, // alt\n    },\n    {USB_EP_TYPE_BULK, 0},\n    {USB_EP_TYPE_BULK, 0},\n};\n\nint HF2::stdRequest(UsbEndpointIn &ctrl, USBSetup &setup) {\n#ifdef HF2_HID\n    if (!useHID)\n        return DEVICE_NOT_SUPPORTED;\n    if (setup.bRequest == USB_REQ_GET_DESCRIPTOR) {\n        if (setup.wValueH == 0x21) {\n            InterfaceDescriptor tmp;\n            fillInterfaceInfo(&tmp);\n            return ctrl.write(&tmp, sizeof(tmp));\n        } else if (setup.wValueH == 0x22) {\n            return ctrl.write(hidDescriptor, sizeof(hidDescriptor));\n        }\n    }\n#endif\n    return DEVICE_NOT_SUPPORTED;\n}\n\n#define HF2_FLAG_EVENT 0x01\n\nREAL_TIME_FUNC\nvoid HF2::sendBuffer(uint8_t flag, const void *data, unsigned size, uint32_t prepend) {\n    if (!CodalUSB::usbInstance->isInitialised())\n        return;\n\n#ifdef USB_EP_FLAG_ASYNC\n    // drop non-responses if too much stuff queued up\n    if (flag != HF2_FLAG_CMDPKT_LAST && pendingWriteSize > 1000)\n        return;\n#endif\n\n    if (flag == HF2_FLAG_EVENT)\n        flag = HF2_FLAG_CMDPKT_LAST;\n\n    if (prepend + 1)\n        size += 4;\n\n#ifdef USB_EP_FLAG_ASYNC\n    HF2_PendingWrite *e = (HF2_PendingWrite *)malloc(sizeof(HF2_PendingWrite) + size);\n    e->size = size;\n    e->flag = flag;\n    e->next = NULL;\n    uint8_t *dst = e->data;\n    if (prepend + 1) {\n        memcpy(dst, &prepend, 4);\n        dst += 4;\n        size -= 4;\n    }\n    memcpy(dst, data, size);\n\n    target_disable_irq();\n    auto p = this->pendingWrite;\n    if (!p)\n        this->pendingWrite = e;\n    else {\n        while (p->next)\n            p = p->next;\n        p->next = e;\n    }\n    this->pendingWriteSize += 16 + e->size;\n    target_enable_irq();\n\n    pokeSend();\n#else\n    uint32_t buf[64 / 4]; // aligned\n\n    target_disable_irq();\n    while (size > 0) {\n        memset(buf + 1, 0, 60);\n        int s = 63;\n        if (size <= 63) {\n            s = size;\n            buf[0] = flag;\n        } else {\n            buf[0] = flag == HF2_FLAG_CMDPKT_LAST ? HF2_FLAG_CMDPKT_BODY : flag;\n        }\n        buf[0] |= s;\n        uint8_t *dst = (uint8_t *)buf;\n        dst++;\n        if (prepend + 1) {\n            memcpy(dst, &prepend, 4);\n            prepend = -1;\n            dst += 4;\n            s -= 4;\n            size -= 4;\n        }\n        memcpy(dst, data, s);\n        data = (const uint8_t *)data + s;\n        size -= s;\n\n        in->write(buf, sizeof(buf));\n    }\n    target_enable_irq();\n#endif\n}\n\nconst InterfaceInfo *HF2::getInterfaceInfo() {\n#ifdef HF2_HID\n    if (useHID)\n        return &ifaceInfoHID;\n#endif\n    return &ifaceInfoEP;\n}\n\nint HF2::sendEvent(uint32_t evId, const void *data, int size) {\n    sendBuffer(HF2_FLAG_EVENT, data, size, evId);\n    return 0;\n}\n\nint HF2::sendSerial(const void *data, int size, int isError) {\n    if (!gotSomePacket)\n        return DEVICE_OK;\n\n    sendBuffer(isError ? HF2_FLAG_SERIAL_ERR : HF2_FLAG_SERIAL_OUT, data, size);\n\n    return 0;\n}\n\n// Receive HF2 message\n// Does not block. Will store intermediate data in pkt.\n// `serial` flag is cleared if we got a command message.\nint HF2::recv() {\n    uint8_t buf[64];\n\n    int len = out->read(buf, sizeof(buf));\n    // DMESG(\"HF2 read: %d\", len);\n\n    if (len <= 0)\n        return len;\n\n    uint8_t tag = buf[0];\n    // serial packets not allowed when in middle of command packet\n    usb_assert(pkt.size == 0 || !(tag & HF2_FLAG_SERIAL_OUT));\n    int size = tag & HF2_SIZE_MASK;\n    usb_assert(pkt.size + size <= (int)sizeof(pkt.buf));\n    memcpy(pkt.buf + pkt.size, buf + 1, size);\n    pkt.size += size;\n    tag &= HF2_FLAG_MASK;\n    if (tag != HF2_FLAG_CMDPKT_BODY) {\n        if (tag == HF2_FLAG_CMDPKT_LAST)\n            pkt.serial = 0;\n        else if (tag == HF2_FLAG_SERIAL_OUT)\n            pkt.serial = 1;\n        else\n            pkt.serial = 2;\n        int sz = pkt.size;\n        pkt.size = 0;\n        return sz;\n    }\n    return 0;\n}\n\nint HF2::sendResponse(int size) {\n    sendBuffer(HF2_FLAG_CMDPKT_LAST, pkt.buf, 4 + size);\n    return 0;\n}\n\nint HF2::sendResponseWithData(const void *data, int size) {\n    if (size <= (int)sizeof(pkt.buf) - 4) {\n        memcpy(pkt.resp.data8, data, size);\n        return sendResponse(size);\n    } else {\n        sendBuffer(HF2_FLAG_CMDPKT_LAST, data, size, pkt.resp.eventId);\n        return 0;\n    }\n}\n\nstatic void copy_words(void *dst0, const void *src0, uint32_t n_words) {\n    uint32_t *dst = (uint32_t *)dst0;\n    const uint32_t *src = (const uint32_t *)src0;\n    while (n_words--)\n        *dst++ = *src++;\n}\n\n#ifndef QUICK_BOOT\n#ifdef SAMD21\n#define DBL_TAP_PTR ((volatile uint32_t *)(HMCRAMC0_ADDR + HMCRAMC0_SIZE - 4))\n#endif\n#ifdef SAMD51\n#define DBL_TAP_PTR ((volatile uint32_t *)(HSRAM_ADDR + HSRAM_SIZE - 4))\n#endif\n#if defined(NRF52840) || defined(NRF52833)\n#define DBL_TAP_PTR ((volatile uint32_t *)0x20007F7C)\n#endif\n#ifdef DBL_TAP_PTR\n#define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef\n#define QUICK_BOOT(v) *DBL_TAP_PTR = v ? DBL_TAP_MAGIC_QUICK_BOOT : 0\n#endif\n#endif\n\nstatic HF2 *jdLogger;\nstatic void jdLog(const uint8_t *frame) {\n    jdLogger->sendEvent(HF2_EV_JDS_PACKET, frame, frame[2] + 12);\n}\n\nvoid HF2::pokeSend() {\n#ifdef USB_EP_FLAG_ASYNC\n    target_disable_irq();\n    while (pendingWrite && in->canWrite()) {\n        in->flags |= USB_EP_FLAG_ASYNC;\n\n        int size = pendingWrite->size - pendingWritePtr;\n        usb_assert(size > 0);\n        uint32_t buf[64 / 4] = {0};\n\n        int s = 63;\n        if (size <= 63) {\n            s = size;\n            buf[0] = pendingWrite->flag;\n        } else {\n            buf[0] = pendingWrite->flag == HF2_FLAG_CMDPKT_LAST ? HF2_FLAG_CMDPKT_BODY\n                                                                : pendingWrite->flag;\n        }\n        buf[0] |= s;\n        uint8_t *dst = (uint8_t *)buf;\n        dst++;\n        memcpy(dst, pendingWrite->data + pendingWritePtr, s);\n\n        int r = in->write(buf, sizeof(buf));\n        if (r == 0) {\n            if (s == size) {\n                pendingWritePtr = 0;\n                pendingWriteSize -= 16 + pendingWrite->size;\n                HF2_PendingWrite *n = pendingWrite->next;\n                free(pendingWrite);\n                pendingWrite = n;\n            } else {\n                pendingWritePtr += s;\n            }\n        }\n    }\n    target_enable_irq();\n#endif\n}\n\nint HF2::endpointRequest() {\n#ifdef USB_EP_FLAG_ASYNC\n    pokeSend();\n#endif\n\n    int sz = recv();\n\n    if (!sz)\n        return 0;\n\n    uint32_t tmp;\n\n    if (pkt.serial) {\n        // TODO raise some event?\n        return 0;\n    }\n\n    LOG(\"HF2 sz=%d CMD=%x\", sz, pkt.buf32[0]);\n\n    // one has to be careful dealing with these, as they share memory\n    HF2_Command *cmd = &pkt.cmd;\n    HF2_Response *resp = &pkt.resp;\n\n    uint32_t cmdId = cmd->command_id;\n    resp->tag = cmd->tag;\n    resp->status16 = HF2_STATUS_OK;\n\n#define checkDataSize(str, add) usb_assert(sz == 8 + (int)sizeof(cmd->str) + (int)(add))\n\n    lastExchange = current_time_ms();\n    gotSomePacket = true;\n\n    switch (cmdId) {\n    case HF2_CMD_INFO:\n        return sendResponseWithData(uf2_info(), strlen(uf2_info()));\n\n    case HF2_CMD_BININFO:\n        resp->bininfo.mode = HF2_MODE_USERSPACE;\n        resp->bininfo.flash_page_size = 0;\n        resp->bininfo.flash_num_pages = 0;\n        resp->bininfo.max_message_size = sizeof(pkt.buf);\n        resp->bininfo.uf2_family = PXT_UF2_FAMILY;\n        return sendResponse(sizeof(resp->bininfo));\n\n    case HF2_DBG_RESTART:\n        *HF2_DBG_MAGIC_PTR = HF2_DBG_MAGIC_START;\n        target_reset();\n        break;\n\n#ifdef QUICK_BOOT\n    case HF2_CMD_RESET_INTO_APP:\n        QUICK_BOOT(1);\n        NVIC_SystemReset();\n        break;\n    case HF2_CMD_RESET_INTO_BOOTLOADER:\n        QUICK_BOOT(0);\n        NVIC_SystemReset();\n        break;\n#else\n    case HF2_CMD_RESET_INTO_APP:\n        NVIC_SystemReset();\n        break;\n    // reset into bootloader not supported\n#endif\n\n#if USB_HANDOVER\n    case HF2_CMD_START_FLASH:\n        sendResponse(0);\n        hf2_handover(in->ep);\n        usb_assert(0); // should not be reached\n        break;\n#endif\n\n    case HF2_CMD_WRITE_WORDS:\n        checkDataSize(write_words, cmd->write_words.num_words << 2);\n        copy_words((void *)cmd->write_words.target_addr, cmd->write_words.words,\n                   cmd->write_words.num_words);\n        break;\n\n    case HF2_CMD_READ_WORDS:\n        checkDataSize(read_words, 0);\n        tmp = cmd->read_words.num_words;\n        usb_assert(tmp <= sizeof(pkt.buf) / 4 - 1);\n        copy_words(resp->data32, (void *)cmd->read_words.target_addr, tmp);\n        return sendResponse(tmp << 2);\n\n    case HF2_CMD_DMESG:\n#if DEVICE_DMESG_BUFFER_SIZE > 0\n        return sendResponseWithData(codalLogStore.buffer, codalLogStore.ptr);\n#else\n        break;\n#endif\n\n    case HF2_DBG_GET_GLOBAL_STATE: {\n        HF2_GLOBAL_STATE_Result gstate = {\n            .num_globals = (uint32_t)getNumGlobals(), //\n            .globals_addr = (uint32_t)globals,\n        };\n        return sendResponseWithData(&gstate, sizeof(gstate));\n    }\n\n    case HF2_DBG_RESUME:\n        globals[0] = (TValue)cmd->data32[0];\n        resume = true;\n        return sendResponse(0);\n\n    case HF2_DBG_GET_STACK:\n        return sendResponseWithData(stackCopy, stackSize);\n\n    case HF2_CMD_JDS_CONFIG:\n        if (cmd->data8[0]) {\n            jdLogger = this;\n            pxt::logJDFrame = jdLog;\n        } else {\n            pxt::logJDFrame = NULL;\n        }\n        return sendResponse(0);\n\n    case HF2_CMD_JDS_SEND:\n        if (pxt::sendJDFrame) {\n            pxt::sendJDFrame(cmd->data8);\n            return sendResponse(0);\n        } else {\n            resp->status16 = HF2_STATUS_INVALID_STATE;\n            return sendResponse(0);\n        }\n\n    default:\n        // command not understood\n        resp->status16 = HF2_STATUS_INVALID_CMD;\n        break;\n    }\n\n    return sendResponse(0);\n}\n\nHF2::HF2(HF2_Buffer &p) : gotSomePacket(false), ctrlWaiting(false), pkt(p), useHID(false) {\n    lastExchange = 0;\n#ifdef USB_EP_FLAG_ASYNC\n    pendingWrite = NULL;\n    pendingWriteSize = 0;\n    pendingWritePtr = 0;\n#endif\n}\n\nstatic const InterfaceInfo dummyIfaceInfo = {\n    NULL,\n    0,\n    0,\n    {\n        0,    // numEndpoints\n        0xff, /// class code - vendor-specific\n        0xff, // subclass\n        0xff, // protocol\n        0x00, // string\n        0x00, // alt\n    },\n    {0, 0},\n    {0, 0},\n};\n\nconst InterfaceInfo *DummyIface::getInterfaceInfo() {\n    return &dummyIfaceInfo;\n}\n\n//\n//\n// Debugger\n//\n//\n\nstruct ExceptionContext {\n    uint32_t excReturn; // 0xFFFFFFF9\n    uint32_t r0;\n    uint32_t r1;\n    uint32_t r2;\n    uint32_t r3;\n    uint32_t r12;\n    uint32_t lr;\n    uint32_t faultInstrAddr;\n    uint32_t psr;\n};\n\nstruct Paused_Data {\n    uint32_t pc;\n};\nstatic Paused_Data pausedData;\n\nvoid bkptPaused() {\n\n// waiting for https://github.com/lancaster-university/codal/pull/14\n#ifdef DEVICE_GROUP_ID_USER\n    // the loop below counts as \"system\" task, and we don't want to pause ourselves\n    fiber_set_group(DEVICE_GROUP_ID_SYSTEM);\n    // pause everyone else\n    fiber_pause_group(DEVICE_GROUP_ID_USER);\n#endif\n\n    while (!resume) {\n        // DMESG(\"BKPT\");\n        hf2.pkt.resp.eventId = HF2_EV_DBG_PAUSED;\n        hf2.sendResponseWithData(&pausedData, sizeof(pausedData));\n        // TODO use an event\n        for (int i = 0; i < 20; ++i) {\n            if (resume)\n                break;\n            fiber_sleep(50);\n        }\n    }\n\n    if (stackCopy) {\n        xfree(stackCopy);\n        stackCopy = NULL;\n    }\n\n#ifdef DEVICE_GROUP_ID_USER\n    fiber_resume_group(DEVICE_GROUP_ID_USER);\n    // go back to user mode\n    fiber_set_group(DEVICE_GROUP_ID_USER);\n#endif\n\n    resume = false;\n}\n\nextern \"C\" void handleHardFault(ExceptionContext *ectx) {\n    auto instr = (uint16_t *)ectx->faultInstrAddr;\n\n    DMESG(\"FLT %p\", instr);\n\n    if (ectx->faultInstrAddr & 0x80000000) {\n        ectx->faultInstrAddr &= ~0x80000000;\n        // switch to step-over mode\n        globals[0] = (TValue)3;\n        return;\n    }\n\n    DMESG(\"BB %p %p %p lr=%p r0=%p\", instr[-1], instr[0], instr[1], ectx->lr, ectx->r0);\n\n    if (instr[0] == 0x6840) {\n        // ldr r0, [r0, #4] -- entry breakpoint\n        ectx->faultInstrAddr += 2;\n        // we're being ask for step-over mode\n        if (ectx->r0 == 3) {\n            // switch to debugger-attached-no-stepping mode\n            globals[0] = (TValue)0;\n            ectx->lr |= 0x80000000;\n        }\n        return;\n    }\n\n    if (instr[0] == 0x6800) {\n        // ldr r0, [r0, #0]\n        ectx->lr = ectx->faultInstrAddr + 3; // next instruction + thumb mode\n        pausedData.pc = ectx->faultInstrAddr + 2;\n        void *ssp = (void *)(ectx + 1);\n        stackSize = DEVICE_STACK_BASE - (uint32_t)ssp;\n        if (stackCopy)\n            xfree(stackCopy);\n        stackCopy = xmalloc(stackSize);\n        memcpy(stackCopy, ssp, stackSize);\n        ectx->faultInstrAddr = ((uint32_t)(&bkptPaused) & (~1U));\n        return;\n    }\n\n    while (1) {\n    }\n}\n\nextern \"C\" void HardFault_Handler(void) {\n    asm(\"push {lr}; mov r0, sp; bl handleHardFault; pop {pc}\");\n}\n\n#endif","hf2.h":"#ifndef DEVICE_HF2_H\n#define DEVICE_HF2_H\n\n#if CONFIG_ENABLED(DEVICE_USB)\n\n#include \"HID.h\"\n#include \"uf2hid.h\"\n\n// 260 bytes needed for biggest JD packets (with overheads)\n#define HF2_BUF_SIZE 260\n\ntypedef struct {\n    uint16_t size;\n    uint8_t serial;\n    union {\n        uint8_t buf[HF2_BUF_SIZE];\n        uint32_t buf32[HF2_BUF_SIZE / 4];\n        uint16_t buf16[HF2_BUF_SIZE / 2];\n        HF2_Command cmd;\n        HF2_Response resp;\n    };\n} HF2_Buffer;\n\nstruct HF2_PendingWrite {\n    HF2_PendingWrite *next;\n    uint16_t size;\n    uint8_t flag;\n    uint8_t _reserved;\n    uint8_t data[0];\n};\n\nclass HF2 : public CodalUSBInterface {\n    bool gotSomePacket;\n    bool ctrlWaiting;\n    uint32_t lastExchange;\n\n#ifdef USB_EP_FLAG_ASYNC\n    HF2_PendingWrite *pendingWrite;\n    int pendingWriteSize;\n    int pendingWritePtr;\n#endif\n\n  public:\n    HF2_Buffer &pkt;\n\n    bool useHID;\n\n    int sendResponse(int size);\n    int recv();\n    int sendResponseWithData(const void *data, int size);\n    int sendEvent(uint32_t evId, const void *data, int size);\n    void sendBuffer(uint8_t flag, const void *data, unsigned size, uint32_t prepend = -1);\n    void pokeSend();\n\n    HF2(HF2_Buffer &pkt);\n    virtual int endpointRequest();\n    virtual int stdRequest(UsbEndpointIn &ctrl, USBSetup &setup);\n    virtual const InterfaceInfo *getInterfaceInfo();\n    int sendSerial(const void *data, int size, int isError = 0);\n\n    virtual bool enableWebUSB() { return !useHID; }\n};\n\nclass DummyIface : public CodalUSBInterface {\n  public:\n    virtual const InterfaceInfo *getInterfaceInfo();\n};\n\n#endif\n\n#endif\n","hf2dbg.h":"#ifndef HF2DBG_H\n#define HF2DBG_H 1\n\n// we use a location at the top of the stack to store a magic value\n// which causes us to stop at the very first break point in the program\n#define HF2_DBG_MAGIC_PTR ((uint32_t *)(DEVICE_STACK_BASE - (DEVICE_STACK_SIZE - 4)))\n#define HF2_DBG_MAGIC_START 0xf0ebac7f\n\n#define HF2_DBG_GET_GLOBAL_STATE 0x53fc66e0\nstruct HF2_GLOBAL_STATE_Result {\n    uint32_t num_globals;\n    uint32_t globals_addr;\n};\n\n#define HF2_DBG_RESTART 0x1120bd93\n#define HF2_DBG_RESUME 0x27a55931\n#define HF2_EV_DBG_PAUSED 0x3692f9fd\n#define HF2_DBG_GET_STACK 0x70901510\n\n#endif\n","i2c.cpp":"#include \"pxt.h\"\n#include \"ErrorNo.h\"\n#include \"CodalDmesg.h\"\n#include \"configkeys.h\"\n\n#ifdef CODAL_I2C\n\nnamespace pins {\n\nclass CodalI2CProxy {\nprivate:\n  DevicePin* sda;\n  DevicePin* scl;\n  CODAL_I2C i2c;\npublic:\n  CodalI2CProxy* next;\npublic:\n  CodalI2CProxy(DevicePin* _sda, DevicePin* _scl)\n    : sda(_sda)\n    , scl(_scl)\n    , i2c(*_sda, *_scl) \n    , next(NULL)\n  {\n\n  }\n\n  CODAL_I2C* getI2C() {\n    return &(this->i2c);\n  }\n  \n  bool matchPins(DevicePin* sda, DevicePin* scl) {\n      return this->sda == sda && this->scl == scl;\n  }\n\n  Buffer readBuffer(int address, int size, bool repeat = false)\n  {\n    Buffer buf = mkBuffer(NULL, size);\n    registerGCObj(buf);\n    int status = this->i2c.read(address << 1, buf->data, size, repeat);\n    unregisterGCObj(buf);\n    if (status != ErrorCode::DEVICE_OK) {\n      buf = 0;\n    }\n    return buf;\n  }\n\n  int writeBuffer(int address, Buffer buf, bool repeat = false)\n  {\n    return this->i2c.write(address << 1, buf->data, buf->length, repeat);\n  }\n};\n\n}\n\nnamespace I2CMethods {\n/**\n  * Read `size` bytes from a 7-bit I2C `address`.\n  */\n//%\nBuffer readBuffer(I2C_ i2c, int address, int size, bool repeat = false)\n{\n  return i2c->readBuffer(address, size, repeat);\n}\n\n/**\n  * Write bytes to a 7-bit I2C `address`.\n  */\n//%\nint writeBuffer(I2C_ i2c, int address, Buffer buf, bool repeat = false)\n{\n  return i2c->writeBuffer(address, buf, repeat);\n}\n\n}\n\nnamespace pins {\n\nstatic I2C_ i2cs(NULL);\n/**\n* Opens a Serial communication driver\n*/\n//% help=pins/create-i2c\n//% parts=i2c\nI2C_ createI2C(DigitalInOutPin sda, DigitalInOutPin scl) {\n  // pick up defaults\n  if (!sda || !scl) {\n    DMESG(\"i2c: lookup default pins\");\n    sda = LOOKUP_PIN(SDA);\n    scl = LOOKUP_PIN(SCL);\n  }\n\n  // lookup existing devices\n  auto dev = i2cs;\n  while(dev) {\n    if (dev->matchPins(sda, scl)) {\n      DMESG(\"i2c: found existing i2c\");\n      return dev;\n    }\n    dev = dev->next;\n  }\n\n  // allocate new one\n  DMESG(\"i2c: mounting on new device\");\n  auto ser = new CodalI2CProxy(sda, scl);\n  // push in list\n  ser->next = i2cs;\n  i2cs = ser;\n  return ser;\n}\n\n}\n\nnamespace pxt {\n  CODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl) {\n    auto i2c = pins::createI2C(sda, scl);\n    return i2c->getI2C();\n  }\n}\n\n#endif","i2c.ts":"namespace pins {\n    /**\n     * Read one number from an I2C address.\n     */\n    //% help=pins/i2c-read-number weight=5 group=\"i2c\" inlineInputMode=\"external\"\n    //% blockId=pins_i2c_readnumber block=\"i2c read number at address %address|of format %format|repeated %repeated\"\n    export function i2cReadNumber(address: number, format: NumberFormat, repeated?: boolean): number {\n        const buf = pins.i2cReadBuffer(address, pins.sizeOf(format), repeated)\n        if (!buf)\n            return undefined\n        return buf.getNumber(format, 0)\n    }\n\n    /**\n     * Write one number to an I2C address.\n     */\n    //% help=pins/i2c-write-number weight=4 group=\"i2c\"\n    //% blockId=i2c_writenumber block=\"i2c write number|at address %address|with value %value|of format %format|repeated %repeated\"\n    export function i2cWriteNumber(address: number, value: number, format?: NumberFormat, repeated?: boolean): void {\n        if (format == undefined)\n            format = NumberFormat.UInt8LE;\n        const buf = control.createBuffer(pins.sizeOf(format))\n        buf.setNumber(format, 0, value)\n        pins.i2cWriteBuffer(address, buf, repeated)\n    }\n\n    /**\n     * Write a value in a I2C register.\n     * @param address I2c address of the device\n     * @param register register index\n     * @param value value to write\n     * @param valueFormat format of the value, default is UInt8LE\n     */\n    //% weight=3 group=\"i2c\"\n    //% help=pins/i2c-write-register\n    //% blockId=i2c_writereg block=\"i2c write register|at address $address|at register $register|value $value\"\n    export function i2cWriteRegister(address: number, register: number, value: number, valueFormat?: NumberFormat): void {\n        if (valueFormat === undefined)\n            valueFormat = NumberFormat.UInt8LE;\n        const valueSize = pins.sizeOf(valueFormat);\n        const buf = control.createBuffer(1 + valueSize);\n        buf.setNumber(NumberFormat.UInt8LE, 0, register);\n        buf.setNumber(valueFormat, 1, value);\n        pins.i2cWriteBuffer(address, buf);\n    }\n\n    /**\n     * Read the value from a I2C register.\n     * @param address I2c address of the device\n     * @param register register index\n     * @param valueFormat format of the value, default is UInt8LE\n     */\n    //% weight=3 group=\"i2c\"\n    //% help=pins/i2c-read-register\n    //% blockId=i2c_readreg block=\"i2c read register|at address $address|at register $register\"\n    export function i2cReadRegister(address: number, register: number, valueFormat?: NumberFormat): number {\n        if (valueFormat === undefined)\n            valueFormat = NumberFormat.UInt8LE;\n        pins.i2cWriteNumber(address, register, NumberFormat.UInt8LE);\n        return pins.i2cReadNumber(address, valueFormat);\n    }\n\n    /**\n     * Read `size` bytes from a 7-bit I2C `address`.\n     */\n    //%\n    export function i2cReadBuffer(address: number, size: number, repeat: boolean = false): Buffer {\n        return pins.i2c().readBuffer(address, size, repeat);\n    }\n\n    /**\n     * Write bytes to a 7-bit I2C `address`.\n     */\n    //%\n    export function i2cWriteBuffer(address: number, buf: Buffer, repeat: boolean = false): number {\n        return pins.i2c().writeBuffer(address, buf, repeat);\n    }\n\n    let _i2c: I2C;\n    /**\n     * Gets the default I2C bus\n     */\n    //%\n    export function i2c(): I2C {\n        if (!_i2c) {\n            const sda = pins.pinByCfg(DAL.CFG_PIN_SDA);\n            const scl = pins.pinByCfg(DAL.CFG_PIN_SCL);\n            _i2c = pins.createI2C(sda, scl);    \n        }\n        return _i2c;        \n    }\n\n    export class I2CDevice {\n        public address: number;\n        public bus: I2C;\n        private _hasError: boolean;\n        constructor(address: number, bus?: I2C) {\n            this.address = address;\n            this.bus = bus || i2c();\n        }\n        public readInto(buf: Buffer, repeat = false, start = 0, end: number = null) {\n            if (end === null)\n                end = buf.length\n            if (start >= end)\n                return\n            let res = this.bus.readBuffer(this.address, end - start, repeat)\n            if (!res) {\n                this._hasError = true\n                return\n            }\n            buf.write(start, res)\n        }\n        public write(buf: Buffer, repeat = false) {\n            let res = this.bus.writeBuffer(this.address, buf, repeat)\n            if (res) {\n                this._hasError = true\n            }\n        }\n        public begin(): I2CDevice {\n            this._hasError = false;\n            return this;\n        }\n        public end() {\n        }\n        public ok() {\n            return !this._hasError\n        }\n\n        public transfer(command: Buffer, response: Buffer, responseStart?: number, responseEnd?: number) {\n            this.begin();\n            if (command)\n                this.write(command);\n            if (response)\n                this.readInto(response, false, responseStart, responseEnd);\n            this.end();\n        }    \n    }\n}\n","keyvaluestorage.cpp":"#include \"pxt.h\"\n#include \"KeyValueStorage.h\"\n\nnamespace pxt {\n\nclass WKeyValueStorage {\n#ifdef CODAL_NVMCONTROLLER\n    CODAL_NVMCONTROLLER controller;\n#else\n    NVMController controller;\n#endif\n    KeyValueStorage storage;\n  public:\n\n    WKeyValueStorage()\n    : controller()\n    , storage(controller) {\n    }\n\n    bool isSupported() {\n#ifdef CODAL_NVMCONTROLLER\n      return true;\n#else\n      return false;\n#endif\n    }\n\n    int put(String key, Buffer data) {\n#ifdef CODAL_NVMCONTROLLER\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        return storage.put(mkey, data->data, data->length);\n#else\n        return -1;\n#endif\n    }\n\n    Buffer get(String key) {\n#ifdef CODAL_NVMCONTROLLER\n        Buffer buf = NULL;\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        auto entry = storage.get(mkey);\n        if (entry) {\n          buf = mkBuffer(entry->value, sizeof(entry->value));\n          free(entry);\n        }\n        return buf;\n#else\n        return NULL;\n#endif\n    }\n\n    void remove(String key) {\n#ifdef CODAL_NVMCONTROLLER\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        storage.remove(mkey);\n#endif\n    }\n\n    void clear() {\n#ifdef CODAL_NVMCONTROLLER\n        storage.wipe();\n#endif\n    }\n};\nSINGLETON(WKeyValueStorage);\n\n}\n\nnamespace configStorage {\n  /**\n  * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n  * @param key the identifier (max 16 characters)\n  * @param value the data (max 32 characters)\n  */\n  //%\n  void setBuffer(String key, Buffer value) {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->put(key, value);\n  }\n\n  /**\n  * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n  * @param key the identifier (max 16 characters)\n  */\n  //%\n  Buffer getBuffer(String key) {\n    auto kvm = pxt::getWKeyValueStorage();\n    return kvm->get(key);\n  }\n\n  /**\n  * Removes the key from local storage\n  * @param key the identifier (max 16 characters)\n  */\n  //%\n  void removeItem(String key) {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->remove(key);\n  }\n\n  /**\n  * Clears the local storage\n  */\n  //%\n  void clear() {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->clear();\n  }\n}\n","keyvaluestorage.ts":"namespace configStorage {\n    /**\n     * Stores the value at the key entry\n     * @param key identifier of the key (max 16 characters)\n     * @param value identifier of the value (max 32 characters)\n     */\n    export function setItem(key: string, value: string) {\n        if (value == null)\n            configStorage.removeItem(key);\n        else\n        {\n            let idx = 0;\n            let buf = control.createBuffer(value.length + 1);\n            buf[idx++] = value.length;\n            let valBuf = control.createBufferFromUTF8(value);\n\n            for (let i = 0; i < valBuf.length; i++)\n                buf[idx++] = valBuf[i];\n\n            configStorage.setBuffer(key, buf);\n        }\n    }\n\n    /**\n     * Retrieves the value at the key entry\n     * @param key identifier of the key (max 16 characters)\n     */\n    export function getItem(key: string): string {\n        const buf = configStorage.getBuffer(key);\n\n        if (!buf)\n            return undefined;\n\n        let idx = 0;\n        let count = buf[idx++];\n        const retBuf = control.createBuffer(count);\n\n        for (let i = 0; i < count; i++)\n            retBuf[i] = buf[idx++];\n\n        return retBuf.toString();\n    }\n}\n","leveldetector.ts":"namespace pins {\n    export class LevelDetector {\n        public id: number;\n        public min: number;\n        public max: number;\n        public lowThreshold: number;\n        public highThreshold: number;\n        private transition: number;\n        private transitionMs: number;\n        private _level: number;\n        private _state: number;\n        public onHigh: () => void;\n        public onLow: () => void;\n        public onNeutral: () => void;\n        public transitionWindow: number;\n        // minimum duration (ms) between events\n        public transitionInterval: number;\n\n        static LEVEL_THRESHOLD_NEUTRAL = 0;\n\n        constructor(id: number,\n            min: number, max: number,\n            lowThreshold: number, highThreshold: number) {\n            this.id = id;\n            this.min = min;\n            this.max = max;\n            this.lowThreshold = lowThreshold;\n            this.highThreshold = highThreshold;\n            this.transitionWindow = 4;\n            this.transitionInterval = 0;\n\n            this.onHigh = () => control.raiseEvent(this.id, DAL.LEVEL_THRESHOLD_HIGH);\n            this.onLow = () => control.raiseEvent(this.id, DAL.LEVEL_THRESHOLD_LOW);\n            this.onNeutral = undefined;\n\n            this.reset();\n        }\n\n        reset() {\n            this.transition = 0;\n            this.transitionMs = 0;\n            this._level = Math.ceil((this.highThreshold - this.lowThreshold) / 2);\n            this._state = LevelDetector.LEVEL_THRESHOLD_NEUTRAL;\n        }\n\n        get level(): number {\n            return this._level;\n        }\n\n        set level(level: number) {\n            this._level = this.clampValue(level);\n\n            if (this._level >= this.highThreshold) {\n                this.setState(DAL.LEVEL_THRESHOLD_HIGH);\n            }\n            else if (this._level <= this.lowThreshold) {\n                this.setState(DAL.LEVEL_THRESHOLD_LOW);\n            }\n            else {\n                this.setState(LevelDetector.LEVEL_THRESHOLD_NEUTRAL);\n            }\n        }\n\n        public setLowThreshold(value: number) {\n            this.lowThreshold = this.clampValue(value);\n            this.reset();\n        }\n\n        public setHighThreshold(value: number) {\n            this.highThreshold = this.clampValue(value);\n            this.reset();\n        }\n\n        private clampValue(value: number) {\n            if (value < this.min) {\n                return this.min;\n            }\n            else if (value > this.max) {\n                return this.max;\n            }\n            return value;\n        }\n\n        private setState(state: number) {\n            // not enough samples to change\n            if (this._state === state \n                || (this.transition++ < this.transitionWindow)\n                || (control.millis() - this.transitionMs) < this.transitionInterval) {\n                return;\n            }\n\n            this.transition = 0;\n            this.transitionMs = control.millis();\n            this._state = state;\n            switch (state) {\n                case DAL.LEVEL_THRESHOLD_HIGH:\n                    if (this.onHigh) this.onHigh();\n                    break;\n                case DAL.LEVEL_THRESHOLD_LOW:\n                    if (this.onLow) this.onLow();\n                    break;\n                case LevelDetector.LEVEL_THRESHOLD_NEUTRAL:\n                    if (this.onNeutral) this.onNeutral();\n                    break;\n            }\n        }\n    }\n}","light.cpp":"#include \"light.h\"\n\n// WS2812B timings, datasheet v1\n// 0 - 0.25-0.55us hi 0.70-1.00us low\n// 1 - 0.65-0.95us hi 0.30-0.60us low\n// datasheet v5\n// 0 - 0.22-0.38us hi 0.58-1.00us low 1-3\n// 1 - 0.58-1.00us hi 0.58-1.00us low 3-2\n\n#define SPI_SUPPORTED 1\n\n#if defined(NRF52_SERIES)\n#define BIT_EXPANSION 5\n#define SPI_FREQ 4000000\n#else\n#define BIT_EXPANSION 3\n#define SPI_FREQ 2400000\n#endif\n\n#if defined(SAMD21) || defined(SAMD51) || defined(STM32F4) || defined(NRF52_SERIES)\n#include \"neopixel.h\"\n#define BITBANG_SUPPORTED 1\n#else\n#define BITBANG_SUPPORTED 0\n#endif\n\n#define NEOPIXEL_MIN_LENGTH_FOR_SPI 24\n#define DOTSTAR_MIN_LENGTH_FOR_SPI 24\n\n#define LIGHTMODE_RGB 1\n#define LIGHTMODE_RGBW 2\n#define LIGHTMODE_RGB_RGB 3\n#define LIGHTMODE_DOTSTAR 4\n\nnamespace light {\nbool isValidMOSIPin(DigitalInOutPin pin) {\n    if (!pin)\n        return false;\n\n#if SAMD51\n    return ZSPI::isValidMOSIPin(*pin);\n#elif defined(NRF52_SERIES)\n    return true;\n#else\n    // TODO: support for SPI neopixels\n    // default SPI pins supported for now\n    return pin == LOOKUP_PIN(MOSI);\n#endif\n}\n\n// SPI\nvoid spiNeopixelSendBuffer(DevicePin *pin, const uint8_t *data, unsigned size) {\n    int32_t iptr = 0, optr = 120;\n    uint32_t len = optr + size * BIT_EXPANSION + 120;\n    uint8_t *expBuf = new uint8_t[len];\n    memset(expBuf, 0, len);\n    uint8_t imask = 0x80;\n    uint8_t omask = 0x80;\n\n#define WR(k)                                                                                      \\\n    if (k)                                                                                         \\\n        expBuf[optr] |= omask;                                                                     \\\n    omask >>= 1;                                                                                   \\\n    if (!omask) {                                                                                  \\\n        omask = 0x80;                                                                              \\\n        optr++;                                                                                    \\\n    }\n\n    while (iptr < (int)size) {\n#if BIT_EXPANSION == 3\n        WR(1);\n        WR(data[iptr] & imask);\n        WR(0);\n#elif BIT_EXPANSION == 5\n        WR(1);\n        if (data[iptr] & imask) {\n            WR(1);\n            WR(1);\n        } else {\n            WR(0);\n        }\n        WR(0);\n        WR(0);\n#else\n#error \"invalid BIT_EXPANSION\"\n#endif\n\n        imask >>= 1;\n        if (!imask) {\n            imask = 0x80;\n            iptr++;\n        }\n    }\n\n    auto spi = pxt::getSPI(pin, NULL, NULL);\n    spi->setFrequency(SPI_FREQ);\n    spi->transfer(expBuf, len, NULL, 0);\n    delete expBuf;\n}\n\nvoid neopixelSendData(DevicePin *pin, int mode, const uint8_t *data, unsigned length) {\n    if (!pin || !length)\n        return;\n\n#if BITBANG_SUPPORTED\n    if (SPI_SUPPORTED && length > NEOPIXEL_MIN_LENGTH_FOR_SPI && isValidMOSIPin(pin))\n        spiNeopixelSendBuffer(pin, data, length);\n    else\n        neopixel_send_buffer(*pin, data, length);\n#else\n    if (isValidMOSIPin(pin)) {\n        spiNeopixelSendBuffer(pin, data, length);\n    }\n#endif\n}\n\nvoid bitBangDotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                            unsigned length) {\n    // first frame of zeroes\n    data->setDigitalValue(0);\n    for (unsigned i = 0; i < 32; ++i) {\n        clk->setDigitalValue(1);\n        clk->setDigitalValue(0);\n    }\n\n    // data stream\n    for (unsigned i = 0; i < length; ++i) {\n        auto x = buf[i];\n        for (uint8_t j = 0x80; j != 0; j >>= 1) {\n            data->setDigitalValue(x & j ? 1 : 0);\n            clk->setDigitalValue(1);\n            clk->setDigitalValue(0);\n        }\n    }\n    // https://cpldcpu.wordpress.com/2016/12/13/sk9822-a-clone-of-the-apa102/\n    // reset frame\n    // data->setDigitalValue(0);\n    // for (unsigned i = 0; i < 32 ; ++i) {\n    //    clk->setDigitalValue(1);\n    //    clk->setDigitalValue(0);\n    //}\n\n    // https://cpldcpu.wordpress.com/2014/11/30/understanding-the-apa102-superled/\n    data->setDigitalValue(1);\n    unsigned n = 32;\n    for (unsigned i = 0; i < n; ++i) {\n        clk->setDigitalValue(1);\n        clk->setDigitalValue(0);\n    }\n}\n\nstatic uint8_t ZERO_FRAME[4];\nstatic uint8_t ONE_FRAME[] = {1, 1, 1, 1};\nvoid spiDotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                        unsigned length) {\n    auto spi = pxt::getSPI(data, NULL, clk);\n\n    spi->transfer(ZERO_FRAME, sizeof(ZERO_FRAME), NULL, 0); // initial frame\n    spi->transfer(buf, length, NULL, 0);\n    spi->transfer(ZERO_FRAME, sizeof(ZERO_FRAME), NULL, 0); // reset frame\n    for (unsigned i = 0; i < (length >> 3); i += 32)\n        spi->transfer(ONE_FRAME, sizeof(ONE_FRAME), NULL, 0); // final frame\n}\n\nvoid dotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                     unsigned length) {\n    if (!data || !clk || !buf || !length)\n        return;\n\n    if (length > DOTSTAR_MIN_LENGTH_FOR_SPI && isValidMOSIPin(data))\n        spiDotStarSendData(data, clk, mode, buf, length);\n    else\n        bitBangDotStarSendData(data, clk, mode, buf, length);\n}\n\nvoid sendBuffer(DevicePin *data, DevicePin *clk, int mode, Buffer buf) {\n    if (!data || !buf || !buf->length)\n        return;\n\n    if (mode == LIGHTMODE_DOTSTAR)\n        light::dotStarSendData(data, clk, mode, buf->data, buf->length);\n    else\n        light::neopixelSendData(data, mode, buf->data, buf->length);\n}\n\nvoid clear() {\n    auto neopix = LOOKUP_PIN(NEOPIXEL);\n    auto neonum = getConfig(CFG_NUM_NEOPIXELS, 0);\n    if (neopix && neonum >= 0) {\n        auto n = 3 * neonum;\n        uint8_t off[n];\n        memset(off, 0, sizeof(off));\n        light::neopixelSendData(neopix, 0x100, off, sizeof(off));\n    }\n\n    auto data = LOOKUP_PIN(DOTSTAR_DATA);\n    auto clk = LOOKUP_PIN(DOTSTAR_CLOCK);\n    auto dsnum = getConfig(CFG_NUM_DOTSTARS, 0);\n    if (data && clk && dsnum > 0) {\n        auto n = 4 * dsnum;\n        uint8_t off[n];\n        memset(off, 0, sizeof(off));\n        for (int i = 0; i < n; i += 4)\n            off[i] = 0xe0;\n        bitBangDotStarSendData(data, clk, 0x100, off, sizeof(off));\n    }\n}\n\n} // namespace light\n","light.h":"#ifndef __PXT_LIGHT_H\n#define __PXT_LIGHT_H\n\n#include \"pxt.h\"\n\nnamespace light {\n    /**\n    * Clear onboard neopixels\n    */\n    void clear();\n\n    /**\n    * Send a programmable light buffer to the specified digital pin\n    * @param data The pin that the lights are connected to\n    * @param clk the clock line if any\n    * @param mode the color encoding mode\n    * @param buf The buffer to send to the pin\n    */\n    //%\n    void sendBuffer(DigitalInOutPin data, DigitalInOutPin clk, int mode, Buffer buf);\n\n    void neopixelSendData(DevicePin* pin, int mode, const uint8_t* data, unsigned length);\n}\n\n#endif","ns.ts":"/**\n * Events and data from sensors.\n */\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\n//% groups='[\"other\", \"More\"]'\nnamespace input {\n}\n\n/**\n * Servos\n */\n//% color=\"#03AA74\" weight=88 icon=\"\\uf021\"\nnamespace servos {\n\n}\n\n/**\n * A Joint Asynchronous Communications, Device Agnostic Control.\n */\n//% color=\"#E79251\" weight=1 icon=\"\\uf185\"\n//% groups='[\"Broadcast\", \"Console\", \"Control\"]'\n//% blockGap=8\nnamespace jacdac {\n\n}","pins.cpp":"#include \"pxt.h\"\n\nnamespace pxt {\nstatic DevicePin **pinPtrs;\nstatic uint8_t numPinPtrs;\nstatic uint8_t pinPos[DEV_NUM_PINS];\n\n//%\nDevicePin *getPin(int id) {\n\n    id &= CFG_PIN_NAME_MSK;\n\n    if (id >= DEV_NUM_PINS)\n        soft_panic(PANIC_NO_SUCH_PIN);\n\n    // we could use lookupComponent() here - it would be slightly slower\n\n    int ptr = pinPos[id];\n    if (ptr == 0) {\n        pinPtrs = (DevicePin **)realloc(pinPtrs, (numPinPtrs + 1) * sizeof(void *));\n        bool isAnalog = IS_ANALOG_PIN(id);\n        // GCTODO\n        pinPtrs[numPinPtrs++] =\n            new DevicePin(DEVICE_ID_IO_P0 + id, (PinName)id,\n                          isAnalog ? PIN_CAPABILITY_AD : PIN_CAPABILITY_DIGITAL);\n        ptr = numPinPtrs;\n        pinPos[id] = ptr;\n    }\n    return pinPtrs[ptr - 1];\n}\n\n//%\nDevicePin *getPinCfg(int key) {\n    int p = getConfig(key, -1);\n    if (p == -1)\n        DMESG(\"no pin cfg: %d\", key);\n    return getPin(p);\n}\n\nvoid linkPin(int from, int to) {\n    if (from < 0 || from >= DEV_NUM_PINS)\n        soft_panic(PANIC_NO_SUCH_PIN);\n    getPin(to);\n    pinPos[from] = pinPos[to];\n}\n\n//%\nDevicePin *lookupPin(int pinName) {\n    if (pinName < 0 || pinName == 0xff)\n        return NULL;\n    pinName &= CFG_PIN_NAME_MSK;\n    return getPin(pinName);\n}\n\n//%\nDevicePin *lookupPinCfg(int key) {\n    return lookupPin(getConfig(key));\n}\n\nCodalComponent *lookupComponent(int id) {\n    for (int i = 0; i < DEVICE_COMPONENT_COUNT; ++i) {\n        if (CodalComponent::components[i] && CodalComponent::components[i]->id == id)\n            return CodalComponent::components[i];\n    }\n    return NULL;\n}\n\n} // namespace pxt\n\nnamespace pins {\n/**\n* Get a pin by configuration id (DAL.CFG_PIN...)\n*/\n//%\nDigitalInOutPin pinByCfg(int key) {\n    return pxt::lookupPinCfg(key);\n}\n\n/**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n//%\nBuffer createBuffer(int size) {\n    return mkBuffer(NULL, size);\n}\n\n/**\n * Get the duration of the last pulse in microseconds. This function should be called from a\n * ``onPulsed`` handler.\n */\n//% help=pins/pulse-duration blockGap=8\n//% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n//% weight=19\nint pulseDuration() {\n    return pxt::lastEvent.timestamp;\n}\n} // namespace pins\n","pins.h":"#ifndef __PXT_PINS_H\n#define __PXT_PINS_H\n\n#define BUTTON_ACTIVE_HIGH_PULL_DOWN (ACTIVE_HIGH | 0x10)\n#define BUTTON_ACTIVE_HIGH_PULL_UP (ACTIVE_HIGH | 0x20)\n#define BUTTON_ACTIVE_HIGH_PULL_NONE (ACTIVE_HIGH | 0x30)\n#define BUTTON_ACTIVE_LOW_PULL_DOWN (ACTIVE_LOW | 0x10)\n#define BUTTON_ACTIVE_LOW_PULL_UP (ACTIVE_LOW | 0x20)\n#define BUTTON_ACTIVE_LOW_PULL_NONE (ACTIVE_LOW | 0x30)\n\n#define PIN(name) ((PinName)pxt::getConfig(CFG_PIN_##name, -1))\n#define LOOKUP_PIN(name) pxt::lookupPin(PIN(name))\n\n// these can be overridden in platform.h\n#ifndef CODAL_PIN\n#define CODAL_PIN CODAL_MBED::Pin\n#endif\n\n#ifndef CODAL_TIMER\n#define CODAL_TIMER CODAL_MBED::Timer\n#endif\n\n#ifndef CODAL_SPI\n#define CODAL_SPI CODAL_MBED::SPI\n#endif\n\n#ifndef CODAL_SERIAL\n#define CODAL_SERIAL CODAL_MBED::Serial\n#endif\n\n#ifndef IS_ANALOG_PIN\n#define IS_ANALOG_PIN(id) ((DEV_ANALOG_PINS >> (id)) & 1)\n#endif\n\ntypedef CODAL_PIN DevicePin;\n\ntypedef DevicePin *DigitalInOutPin;\ntypedef DevicePin *AnalogInOutPin;\ntypedef DevicePin *AnalogInPin;\ntypedef DevicePin *AnalogOutPin;\ntypedef DevicePin *PwmPin;\ntypedef DevicePin *PwmOnlyPin;\ntypedef Button *Button_;\n\nnamespace pxt {\nDevicePin *getPin(int id);\nDevicePin *getPinCfg(int key);\nDevicePin *lookupPin(int pinName);\nDevicePin *lookupPinCfg(int key);\nvoid linkPin(int from, int to);\nCodalComponent *lookupComponent(int id);\n}\n\n#define PINOP(op) name->op\n\n#endif\n","pins.ts":"//% noRefCounting fixedInstances\ninterface DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogInPin extends DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogOutPin extends DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogInOutPin extends AnalogInPin, AnalogOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface PwmOnlyPin extends DigitalInOutPin, AnalogOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface PwmPin extends PwmOnlyPin, AnalogInOutPin {\n}\n\n/**\n * Control currents in Pins for analog/digital signals, servos, i2c, ...\n */\n//% color=#A80000 weight=85 icon=\"\\uf140\" advanced=true\n//% groups='[\"other\", \"Servo\", \"i2c\"]'\nnamespace pins {\n}","pinsAnalog.cpp":"#include \"pxt.h\"\n\nnamespace AnalogInPinMethods {\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 weight=53\n//% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nint analogRead(AnalogInPin name) {\n    return PINOP(getAnalogValue());\n}\n}\n\nnamespace AnalogOutPinMethods {\nvoid analogWrite(AnalogOutPin name, int value) __attribute__ ((weak));\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 weight=52\n//% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\n//% value.min=0 value.max=1023\nvoid analogWrite(AnalogOutPin name, int value) {\n    PINOP(setAnalogValue(value));\n}\n}","pinsDigital.cpp":"#include \"pxt.h\"\n\nenum class PulseValue {\n    //% block=high\n    High = DEVICE_PIN_EVT_PULSE_HI,\n    //% block=low\n    Low = DEVICE_PIN_EVT_PULSE_LO\n};\n\nenum class PinEvent {\n    //% block=\"pulse high\"\n    PulseHigh = DEVICE_PIN_EVT_PULSE_HI,\n    //% block=\"pulse low\"\n    PulseLow = DEVICE_PIN_EVT_PULSE_LO,\n    //% block=\"rise\"\n    Rise = DEVICE_PIN_EVT_RISE,\n    //% block=\"fall\"\n    Fall = DEVICE_PIN_EVT_FALL,\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\nnamespace DigitalInOutPinMethods {\n/**\n * Read a pin or connector as either 0 or 1\n * @param name pin to read from\n */\n//% help=pins/digital-read weight=61\n//% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nbool digitalRead(DigitalInOutPin name) {\n    return PINOP(getDigitalValue()) != 0;\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\n    */\n//% help=pins/digital-write weight=60\n//% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid digitalWrite(DigitalInOutPin name, bool value) {\n    PINOP(setDigitalValue(value));\n}\n\n/**\n* Make this pin a digital input, and create events where the timestamp is the duration\n* that this pin was either ``high`` or ``low``.\n*/\n//% help=pins/on-pulsed weight=16 blockGap=8\n//% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\n//% deprecated=1 hidden=1\nvoid onPulsed(DigitalInOutPin pin, PulseValue pulse, Action body) {\n    pin->eventOn(DEVICE_PIN_EVENT_ON_PULSE);\n    registerWithDal(pin->id, (int)pulse, body);\n}\n\n/**\n* Register code to run when a pin event occurs. \n*/\n//% help=pins/on-event weight=20 blockGap=8\n//% blockId=pinsonevent block=\"on|pin %pin|%event\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\nvoid onEvent(DigitalInOutPin pin, PinEvent event, Action body) {\n    switch(event) {\n        case PinEvent::PulseHigh:\n        case PinEvent::PulseLow:\n            pin->eventOn(DEVICE_PIN_EVENT_ON_PULSE);\n            registerWithDal(pin->id, (int)event, body);\n            break;\n        case PinEvent::Rise:\n        case PinEvent::Fall:\n            pin->eventOn(DEVICE_PIN_EVENT_ON_EDGE);\n            registerWithDal(pin->id, (int)event, body);\n            break;    \n    }    \n}\n\n/**\n* Return 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 %high||timeout %maxDuration (µs)\"\n//% weight=18 blockGap=8\n//% help=\"pins/pulse-in\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\nint pulseIn(DigitalInOutPin pin, PulseValue value, int maxDuration = 2000000) {\n    int pulse = PulseValue::High == value ? 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* Set the pull direction 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=17 blockGap=8\n//% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid setPull(DigitalInOutPin name, PinPullMode pull) {\n    PullMode m = pull == PinPullMode::PullDown ? PullMode::Down : pull == PinPullMode::PullUp\n                                                                        ? PullMode::Up\n                                                                        : PullMode::None;\n    PINOP(setPull(m));\n}\n\n}\n\n#ifdef PXT_CODAL\n\nnamespace pxt {\n\nstatic void waitABit() {\n    // for (int i = 0; i < 10; ++i)\n    //    asm volatile(\"nop\");\n}\n\nclass ButtonMultiplexer : public CodalComponent {\n  public:\n    Pin &latch;\n    Pin &clock;\n    Pin &data;\n    uint32_t state;\n    uint32_t invMask;\n    uint16_t buttonIdPerBit[8];\n    bool enabled;\n\n    ButtonMultiplexer(uint16_t id)\n        : latch(*LOOKUP_PIN(BTNMX_LATCH)), clock(*LOOKUP_PIN(BTNMX_CLOCK)),\n          data(*LOOKUP_PIN(BTNMX_DATA)) {\n        this->id = id;\n        this->status |= DEVICE_COMPONENT_STATUS_SYSTEM_TICK;\n\n        state = 0;\n        invMask = 0;\n        enabled = true;\n\n        memset(buttonIdPerBit, 0, sizeof(buttonIdPerBit));\n\n        data.getDigitalValue(PullMode::Down);\n        latch.setDigitalValue(1);\n        clock.setDigitalValue(1);\n    }\n\n    void disable() {\n        data.getDigitalValue(PullMode::None);\n        latch.getDigitalValue(PullMode::None);\n        clock.getDigitalValue(PullMode::None);\n        enabled = false;\n    }\n\n    bool isButtonPressed(int id) {\n        for (int i = 0; i < 8; ++i) {\n            if (buttonIdPerBit[i] == id)\n                return (state & (1 << i)) != 0;\n        }\n        return false;\n    }\n\n    uint32_t readBits(int bits) {\n        latch.setDigitalValue(0);\n        waitABit();\n        latch.setDigitalValue(1);\n        waitABit();\n\n        uint32_t state = 0;\n        for (int i = 0; i < bits; i++) {\n            state <<= 1;\n            if (data.getDigitalValue(PullMode::Down))\n                state |= 1;\n\n            clock.setDigitalValue(0);\n            waitABit();\n            clock.setDigitalValue(1);\n            waitABit();\n        }\n\n        return state;\n    }\n\n    virtual void periodicCallback() override {\n        if (!enabled)\n            return;\n\n        uint32_t newState = readBits(8);\n        newState ^= invMask;\n        if (newState == state)\n            return;\n\n        for (int i = 0; i < 8; ++i) {\n            uint32_t mask = 1 << i;\n            if (!buttonIdPerBit[i])\n                continue;\n            int ev = 0;\n            if (!(state & mask) && (newState & mask))\n                ev = PXT_INTERNAL_KEY_DOWN;\n            else if ((state & mask) && !(newState & mask))\n                ev = PXT_INTERNAL_KEY_UP;\n            if (ev) {\n                Event(ev, buttonIdPerBit[i]);\n                Event(ev, 0); // any key\n            }\n        }\n\n        state = newState;\n    }\n};\n\nstatic ButtonMultiplexer *btnMultiplexer;\nButtonMultiplexer *getMultiplexer() {\n    if (!btnMultiplexer)\n        btnMultiplexer = new ButtonMultiplexer(DEVICE_ID_FIRST_BUTTON);\n    return btnMultiplexer;\n}\n\nint registerMultiplexedButton(int pin, int buttonId) {\n    if (1050 <= pin && pin < 1058) {\n        pin -= 50;\n        getMultiplexer()->invMask |= 1 << (pin - 1000);\n    }\n    if (1000 <= pin && pin < 1008) {\n        getMultiplexer()->buttonIdPerBit[pin - 1000] = buttonId;\n        return 1;\n    }\n    return 0;\n}\n\nint multiplexedButtonIsPressed(int btnId) {\n    if (btnMultiplexer)\n        return btnMultiplexer->isButtonPressed(btnId) ? 512 : 0;\n    return 0;\n}\n\n//% expose\nuint32_t readButtonMultiplexer(int bits) {\n    if (!LOOKUP_PIN(BTNMX_CLOCK))\n        return 0;\n    return getMultiplexer()->readBits(bits);\n}\n\nvoid disableButtonMultiplexer() {\n    if (LOOKUP_PIN(BTNMX_CLOCK)) {\n        getMultiplexer()->disable();\n    }\n}\n\n}\n\n#endif\n","pinsPWM.cpp":"#include \"pxt.h\"\n\nnamespace PwmPinMethods {\n}\n\nnamespace PwmOnlyPinMethods {\n\n/**\n * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n * **microseconds** or `1/1000` milliseconds.\n * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n * 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=51\n//% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid analogSetPeriod(PwmOnlyPin name, int period) {\n    PINOP(setAnalogPeriodUs(period));\n}\n\n/**\n * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n * 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\n */\n//% help=pins/servo-write weight=41 group=\"Servo\"\n//% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n//% parts=microservo trackArgs=0\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\n//% value.defl=90\nvoid servoWrite(PwmOnlyPin name, int value) {\n    PINOP(setServoValue(value));\n}\n\n/**\n * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n * @param name pin name\n * @param duration pulse duration in micro seconds, eg:1500\n */\n//% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n//% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n//% parts=microservo blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid servoSetPulse(PwmOnlyPin name, int duration) {\n    PINOP(setServoPulseUs(duration));\n}\n\n/**\n* Indicates if the servo is running continuously\n*/\n//% blockHidden=1\nvoid servoSetContinuous(PwmOnlyPin name, bool continuous) {\n    // used by simulator\n}\n\n}","pinscompat.ts":"// filled in by microbit","platform.cpp":"#include \"pxt.h\"\n\n#include \"NRFLowLevelTimer.h\"\n\nnamespace pxt {\n\nstruct TimerConfig {\n    uint8_t id;\n    IRQn_Type irqn;\n    NRF_TIMER_Type *addr;\n};\n\n#define DEF_TIM(n)                                                                                 \\\n    { 0x10 + n, TIMER##n##_IRQn, NRF_TIMER##n }\n\nstatic const TimerConfig timers[] = {\n#ifdef NRF_TIMER0\n    DEF_TIM(0),\n#endif\n#ifdef NRF_TIMER1\n    DEF_TIM(1),\n#endif\n#ifdef NRF_TIMER2\n    DEF_TIM(2),\n#endif\n#ifdef NRF_TIMER3\n    DEF_TIM(3),\n#endif\n#ifdef NRF_TIMER4\n    DEF_TIM(4),\n#endif\n#ifdef NRF_TIMER5\n    DEF_TIM(5),\n#endif\n#ifdef NRF_TIMER6\n    DEF_TIM(6),\n#endif\n    {0, (IRQn_Type)0, 0}};\n\n#define DEF_TIMERS 0x11121013 // TIMER1 TIMER2 TIMER0 TIMER3\n\nstatic uint32_t usedTimers;\nstatic int timerIdx(uint8_t id) {\n    for (unsigned i = 0; timers[i].id; i++) {\n        if (id == timers[i].id)\n            return i;\n    }\n    return -1;\n}\nLowLevelTimer *allocateTimer() {\n    uint32_t timersToUse = getConfig(CFG_TIMERS_TO_USE, DEF_TIMERS);\n    for (int shift = 24; shift >= 0; shift -= 8) {\n        uint8_t tcId = (timersToUse >> shift) & 0xff;\n        int idx = timerIdx(tcId);\n        if (idx < 0 || (usedTimers & (1 << idx)))\n            continue;\n        auto dev = timers[idx].addr;\n        if (dev->INTENSET) // any irqs enabled?\n            continue;      // then we won't allocate it\n        usedTimers |= 1 << idx;\n        DMESG(\"allocate TIMER%d\", tcId - 0x10);\n        return new NRFLowLevelTimer(dev, timers[idx].irqn);\n    }\n\n    soft_panic(PANIC_OUT_OF_TIMERS);\n    return NULL;\n}\n\nstatic void initRandomSeed() {\n    int seed = 0xC0DA1;\n    /*\n    auto pinTemp = LOOKUP_PIN(TEMPERATURE);\n    if (pinTemp)\n        seed *= pinTemp->getAnalogValue();\n    auto pinLight = LOOKUP_PIN(LIGHT);\n    if (pinLight)\n        seed *= pinLight->getAnalogValue();\n    */\n    seedRandom(seed);\n}\n\n#if defined(NRF52840) || defined(NRF52833)\n#define IS_3_3_V() ((NRF_UICR->REGOUT0 & 7) == 5)\n#else\n#define IS_3_3_V() 1\n#endif\n\nstatic void disableNFConPins() {\n    // Ensure NFC pins are configured as GPIO. If not, update the non-volatile UICR.\n    if (NRF_UICR->NFCPINS || !IS_3_3_V()) {\n        DMESG(\"RESET UICR\\n\");\n        // Enable Flash Writes\n        NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);\n        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)\n            ;\n\n        // Configure PINS for GPIO use.\n        if (NRF_UICR->NFCPINS)\n            NRF_UICR->NFCPINS = 0;\n\n#if defined(NRF52840) || defined(NRF52833)\n        // Set VDD to 3.3V\n        if ((NRF_UICR->REGOUT0 & 7) != 5)\n            NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~7) | 5;\n#endif\n\n        // Disable Flash Writes\n        NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);\n        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)\n            ;\n\n        // Reset, so the changes can take effect.\n        NVIC_SystemReset();\n    }\n}\n\nvoid deepSleep() {\n    NRF_POWER->SYSTEMOFF = 1;\n}\n\nvoid platform_init() {\n#ifdef PXT_PROFILE\n    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;\n    DWT->CYCCNT = 0;\n    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;\n#endif\n\n    initRandomSeed();\n\n    disableNFConPins(); // this is needed when P0_9 and P0_10 are to be used as regular pins\n\n    /*\n        if (*HF2_DBG_MAGIC_PTR == HF2_DBG_MAGIC_START) {\n            *HF2_DBG_MAGIC_PTR = 0;\n            // this will cause alignment fault at the first breakpoint\n            globals[0] = (TValue)1;\n        }\n    */\n}\n\nint *getBootloaderConfigData() {\n#ifdef NRF52840\n    auto p = (volatile uint32_t *)0x000fd800;\n    if (p[0] == CFG_MAGIC0 && p[1] == CFG_MAGIC1)\n        return (int *)p + 4;\n#endif\n\n    return NULL;\n}\n\n} // namespace pxt\n\nvoid cpu_clock_init() {\n    // missing in Codal\n}\n","platform.h":"#ifndef __PXT_PLATFORM_H\n#define __PXT_PLATFORM_H\n\n#include \"Image.h\"\n#include \"NRF52SPI.h\"\n#include \"NRF52I2C.h\"\n#include \"NRF52Pin.h\"\n#include \"NRF52PWM.h\"\n#include \"NRF52Serial.h\"\n#include \"NRF52PDM.h\"\n#include \"Timer.h\"\n#include \"MultiButton.h\"\n\n#define PAGE_SIZE 4096\n#define MIC_DEVICE NRF52PDM\n\n#if defined(NRF52840) || defined(NRF52833)\n#define DEV_NUM_PINS 48\n#else\n#define DEV_NUM_PINS 32\n#endif\n\n#define DEV_PWM_PINS 0x0000ffffffffULL // all pins are PWM pins it seems\n#define DEV_AIN_PINS 0x0000f000001fULL\n\n// Codal doesn't yet distinguish between PWM and AIN\n#define DEV_ANALOG_PINS (DEV_PWM_PINS | DEV_AIN_PINS)\n\n#define CODAL_PIN NRF52Pin\n#define CODAL_SPI NRF52SPI\n#define CODAL_I2C NRF52I2C\n#define CODAL_TIMER Timer\n#define CODAL_SERIAL NRF52Serial\n\n#define IMAGE_BITS 4\n\ntypedef uint8_t PinName;\n\n#define DEFAULT_NEOPIXEL_PIN P0_0\n\n#define PERF_NOW() (DWT->CYCCNT)\n#define PERF_NOW_SCALE 64\n\n// The parameters below needs tuning!\n\n/*\n * @param nominalValue The value (in SI units) of a nominal position.\n * @param nominalReading The raw reading from the sensor at the nominal position.\n * @param beta The Steinhart-Hart Beta constant for the device\n * @param seriesResistor The value (in ohms) of the resistor in series with the sensor.\n * @param zeroOffset Optional zero offset applied to all SI units (e.g. 273.15 for temperature\n * sensing in C vs Kelvin).\n */\n\n#define TEMPERATURE_NOMINAL_VALUE 25\n#define TEMPERATURE_NOMINAL_READING 10000\n#define TEMPERATURE_BETA 3380\n#define TEMPERATURE_SERIES_RESISTOR 10000\n#define TEMPERATURE_ZERO_OFFSET 273.5\n\n#define LIGHTSENSOR_SENSITIVITY 868 // codal has 912 now\n#define LIGHTSENSOR_LOW_THRESHOLD 128\n#define LIGHTSENSOR_HIGH_THRESHOLD 896\n\n\n#define P0_0 0\n#define P0_1 1\n#define P0_2 2\n#define P0_3 3\n#define P0_4 4\n#define P0_5 5\n#define P0_6 6\n#define P0_7 7\n#define P0_8 8\n#define P0_9 9\n#define P0_10 10\n#define P0_11 11\n#define P0_12 12\n#define P0_13 13\n#define P0_14 14\n#define P0_15 15\n#define P0_16 16\n#define P0_17 17\n#define P0_18 18\n#define P0_19 19\n#define P0_20 20\n#define P0_21 21\n#define P0_22 22\n#define P0_23 23\n#define P0_24 24\n#define P0_25 25\n#define P0_26 26\n#define P0_27 27\n#define P0_28 28\n#define P0_29 29\n#define P0_30 30\n#define P0_31 31\n#define P1_0 32\n#define P1_1 33\n#define P1_2 34\n#define P1_3 35\n#define P1_4 36\n#define P1_5 37\n#define P1_6 38\n#define P1_7 39\n#define P1_8 40\n#define P1_9 41\n#define P1_10 42\n#define P1_11 43\n#define P1_12 44\n#define P1_13 45\n#define P1_14 46\n#define P1_15 47\n#define P1_16 48\n#define P1_17 49\n#define P1_18 50\n#define P1_19 51\n#define P1_20 52\n#define P1_21 53\n#define P1_22 54\n#define P1_23 55\n#define P1_24 56\n#define P1_25 57\n#define P1_26 58\n#define P1_27 59\n#define P1_28 60\n#define P1_29 61\n#define P1_30 62\n#define P1_31 63\n\n#endif\n","pxt.h":"#ifndef __PXT_H\n#define __PXT_H\n\n#include \"pxtbase.h\"\n\n#include \"CodalConfig.h\"\n#include \"CodalHeapAllocator.h\"\n#include \"CodalDevice.h\"\n#include \"CodalDmesg.h\"\n#include \"ErrorNo.h\"\n#include \"Timer.h\"\n#include \"Matrix4.h\"\n#include \"CodalCompat.h\"\n#include \"CodalComponent.h\"\n#include \"ManagedType.h\"\n#include \"Event.h\"\n#include \"NotifyEvents.h\"\n#include \"Button.h\"\n#include \"CodalFiber.h\"\n#include \"MessageBus.h\"\n#include \"MultiButton.h\"\n\nusing namespace codal;\n\n// codal::ManagedString compat\n#define MSTR(s) codal::ManagedString((s)->data, (s)->length)\n#define PSTR(s) mkString((s).toCharArray(), (s).length())\n\n#include \"pins.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"hf2.h\"\n#include \"hf2dbg.h\"\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n#include \"HIDMouse.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n#include \"HIDKeyboard.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n#include \"HIDJoystick.h\"\n#endif\n#endif\n\n#define PXT_COMM_BASE 0x20002000 // 8k in\n\n// old codal compat\n#ifndef REAL_TIME_FUNC\n#define REAL_TIME_FUNC /* */\n#endif\n\nnamespace pxt {\n\n#if CONFIG_ENABLED(DEVICE_USB)\nextern CodalUSB usb;\nextern HF2 hf2;\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nextern USBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nextern USBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nextern USBHIDJoystick joystick;\n#endif\n#endif\n\n// Utility functions\nextern Event lastEvent;\nextern CODAL_TIMER devTimer;\nextern MessageBus devMessageBus;\nextern codal::CodalDevice device;\n\nvoid set_usb_strings(const char *uf2_info);\nextern void (*logJDFrame)(const uint8_t *data);\nextern void (*sendJDFrame)(const uint8_t *data);\n\nstatic inline void raiseEvent(int src, int val) {\n    Event(src, val);\n}\n\n} // namespace pxt\n\nnamespace pins {\nclass CodalSPIProxy;\nclass CodalI2CProxy;\n} // namespace pins\n\ntypedef pins::CodalI2CProxy* I2C_;\ntypedef pins::CodalSPIProxy* SPI_;\n\nnamespace pxt {\ncodal::LowLevelTimer *allocateTimer();\n\n#ifdef CODAL_I2C\nCODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl);\n#endif\nCODAL_SPI* getSPI(DigitalInOutPin mosi, DigitalInOutPin miso, DigitalInOutPin sck);\n#ifdef CODAL_JACDAC_WIRE_SERIAL\nLowLevelTimer* getJACDACTimer();\n#endif\nclass PressureButton;\nuint32_t readButtonMultiplexer(int bits);\nvoid disableButtonMultiplexer();\n}\n\nnamespace serial {\nclass CodalSerialDeviceProxy;\n}\n\ntypedef serial::CodalSerialDeviceProxy* SerialDevice;\n\nnamespace jacdac {\nclass JDProxyDriver;\n} // namespace network\n\ntypedef jacdac::JDProxyDriver* JacDacDriverStatus;\n\n#define DEVICE_ID_BUTTON_SLIDE 3000\n#define DEVICE_ID_MICROPHONE 3001\n#define DEVICE_ID_FIRST_BUTTON 4000\n#define DEVICE_ID_FIRST_TOUCHBUTTON 4100\n\n#define PXT_INTERNAL_KEY_UP 2050\n#define PXT_INTERNAL_KEY_DOWN 2051\n\n#endif\n","pxt.json":"{\n    \"name\": \"core---nrf52\",\n    \"description\": \"The core library for Codal-based targets\",\n    \"dependencies\": {\n        \"base\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"dal.d.ts\",\n        \"codal.cpp\",\n        \"usb.cpp\",\n        \"pxt.h\",\n        \"platform.h\",\n        \"platform.cpp\",\n        \"pxtcore.h\",\n        \"pins.h\",\n        \"pins.cpp\",\n        \"pinsAnalog.cpp\",\n        \"pinsDigital.cpp\",\n        \"pinsPWM.cpp\",\n        \"pins.ts\",\n        \"pinscompat.ts\",\n        \"control.cpp\",\n        \"i2c.cpp\",\n        \"i2c.ts\",\n        \"spi.cpp\",\n        \"spi.ts\",\n        \"shims.d.ts\",\n        \"enums.d.ts\",\n        \"hf2.cpp\",\n        \"hf2.h\",\n        \"hf2dbg.h\",\n        \"uf2format.h\",\n        \"uf2hid.h\",\n        \"ns.ts\",\n        \"dmac.cpp\",\n        \"dmac.h\",\n        \"timer.ts\",\n        \"light.cpp\",\n        \"light.h\",\n        \"keyvaluestorage.cpp\",\n        \"keyvaluestorage.ts\",\n        \"leveldetector.ts\",\n        \"pxtparts.json\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"yotta\": {\n        \"config\": {\n            \"codal\": {\n                \"component_count\": 64,\n                \"dmesg_buffer_size\": 1024\n            }\n        }\n    },\n    \"dalDTS\": {\n        \"includeDirs\": [\n            \"libraries/codal-core/inc\",\n            \"pxtapp\"\n        ],\n        \"excludePrefix\": [\n            \"JD_\",\n            \"USB_\",\n            \"REQUEST_\",\n            \"LIS3DH_\",\n            \"FXOS8700_\",\n            \"HF2_\",\n            \"PXT_REF_TAG_\",\n            \"MS_\",\n            \"SCSI_\",\n            \"MAG_\",\n            \"MAG3\",\n            \"MPU6\",\n            \"MADCTL\",\n            \"MMA8\"\n        ]\n    }\n}\n","pxtcore.h":"#ifndef __PXTCORE_H\n#define __PXTCORE_H\n\n#include \"CodalDmesg.h\"\n#include \"CodalHeapAllocator.h\"\n\n#define PXT_CODAL 1\n\n#define itoa(a, b) codal::itoa(a, b)\n\n#define GC_GET_HEAP_SIZE() device_heap_size(0)\n#define GC_STACK_BASE DEVICE_STACK_BASE\n#define xmalloc device_malloc\n#define xfree device_free\n\n// on most devices we allocate the entire heap at once, so large allocs should work\n// if they don't you just get the regular out of memory instead of alloc too large\n#define GC_MAX_ALLOC_SIZE (128 * 1024)\n\n#endif\n","pxtparts.json":"{\n    \"neopixel\": {\n        \"simulationBehavior\": \"neopixel\",\n        \"visual\": {\n            \"builtIn\": \"neopixel\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 19,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 28,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createStrip,light.createNeoPixelStrip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"dotstar\": {\n        \"simulationBehavior\": \"dotstar\",\n        \"visual\": {\n            \"builtIn\": \"dotstar\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 1\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createAPA102Strip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"dataPin\"\n                },\n                {\n                    \"pinInstantiationIdx\": 1,\n                    \"partParameter\": \"clkPin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },\n    \"pixels\": {\n        \"simulationBehavior\": \"pixels\",\n        \"visual\": { \n            \"builtIn\": \"pixels\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"MOSI\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"SCK\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },    \n    \"buttons\": {\n        \"simulationBehavior\": \"buttons\",\n        \"visual\": {\n            \"builtIn\": \"buttons\",\n            \"width\": 75,\n            \"height\": 45,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 30,\n                    \"y\": 45\n                }\n            ]\n        },\n        \"numberOfPins\": 2,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"Button.onEvent,Button.isPressed,Button.wasPressed\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"button\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"slideswitch\": {\n        \"numberOfPins\": 3,\n        \"simulationBehavior\": \"slideswitch\",\n        \"visual\": {\n            \"builtIn\": \"slideswitch\",\n            \"width\": 100,\n            \"height\": 100,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalRead,DigitalInOutPin.onPulsed,DigitalInOutPin.onEvent\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"microservo\": {\n        \"simulationBehavior\": \"microservo\",\n        \"visual\": {\n            \"builtIn\": \"microservo\",\n            \"width\": 74.85,\n            \"height\": 200,\n            \"pinDistance\": 10,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 37,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 5\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"PwmOnlyPin.servoWrite,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"led\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"analogled\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogOutPin.analogWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"photocell\": {\n        \"numberOfPins\": 3,\n        \"visual\": {\n            \"builtIn\": \"photocell\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 15,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"photocell\",\n        \"pinDefinitions\": [\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogInPin.analogRead\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace light {\n\n    /**\n     * Send a programmable light buffer to the specified digital pin\n     * @param data The pin that the lights are connected to\n     * @param clk the clock line if any\n     * @param mode the color encoding mode\n     * @param buf The buffer to send to the pin\n     */\n    //% shim=light::sendBuffer\n    function sendBuffer(data: DigitalInOutPin, clk: DigitalInOutPin, mode: int32, buf: Buffer): void;\n}\ndeclare namespace control {\n\n    /**\n     * Determines if the USB has been enumerated.\n     */\n    //% shim=control::isUSBInitialized\n    function isUSBInitialized(): boolean;\n}\ndeclare namespace pins {\n\n    /**\n     * Get a pin by configuration id (DAL.CFG_PIN...)\n     */\n    //% shim=pins::pinByCfg\n    function pinByCfg(key: int32): DigitalInOutPin;\n\n    /**\n     * Create a new zero-initialized buffer.\n     * @param size number of bytes in the buffer\n     */\n    //% shim=pins::createBuffer\n    function createBuffer(size: int32): Buffer;\n\n    /**\n     * Get the duration of the last pulse in microseconds. This function should be called from a\n     * ``onPulsed`` handler.\n     */\n    //% help=pins/pulse-duration blockGap=8\n    //% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n    //% weight=19 shim=pins::pulseDuration\n    function pulseDuration(): int32;\n}\n\n\ndeclare interface AnalogInPin {\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 weight=53\n    //% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=AnalogInPinMethods::analogRead\n    analogRead(): int32;\n}\n\n\ndeclare interface AnalogOutPin {\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 weight=52\n    //% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4\n    //% value.min=0 value.max=1023 shim=AnalogOutPinMethods::analogWrite\n    analogWrite(value: int32): void;\n}\n\n\ndeclare interface DigitalInOutPin {\n    /**\n     * Read a pin or connector as either 0 or 1\n     * @param name pin to read from\n     */\n    //% help=pins/digital-read weight=61\n    //% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::digitalRead\n    digitalRead(): boolean;\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\n     */\n    //% help=pins/digital-write weight=60\n    //% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::digitalWrite\n    digitalWrite(value: boolean): void;\n\n    /**\n     * Make this pin a digital input, and create events where the timestamp is the duration\n     * that this pin was either ``high`` or ``low``.\n     */\n    //% help=pins/on-pulsed weight=16 blockGap=8\n    //% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4\n    //% deprecated=1 hidden=1 shim=DigitalInOutPinMethods::onPulsed\n    onPulsed(pulse: PulseValue, body: () => void): void;\n\n    /**\n     * Register code to run when a pin event occurs. \n     */\n    //% help=pins/on-event weight=20 blockGap=8\n    //% blockId=pinsonevent block=\"on|pin %pin|%event\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4 shim=DigitalInOutPinMethods::onEvent\n    onEvent(event: PinEvent, body: () => void): void;\n\n    /**\n     * Return 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 %high||timeout %maxDuration (µs)\"\n    //% weight=18 blockGap=8\n    //% help=\"pins/pulse-in\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4 maxDuration.defl=2000000 shim=DigitalInOutPinMethods::pulseIn\n    pulseIn(value: PulseValue, maxDuration?: int32): int32;\n\n    /**\n     * Set the pull direction 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=17 blockGap=8\n    //% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::setPull\n    setPull(pull: PinPullMode): void;\n}\n\n\ndeclare interface PwmPin {}\n\n\ndeclare interface PwmOnlyPin {\n    /**\n     * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n     * **microseconds** or `1/1000` milliseconds.\n     * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n     * 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=51\n    //% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::analogSetPeriod\n    analogSetPeriod(period: int32): void;\n\n    /**\n     * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n     * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n     * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n     * 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\n     */\n    //% help=pins/servo-write weight=41 group=\"Servo\"\n    //% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n    //% parts=microservo trackArgs=0\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4\n    //% value.defl=90 shim=PwmOnlyPinMethods::servoWrite\n    servoWrite(value?: int32): void;\n\n    /**\n     * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n     * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n     * @param name pin name\n     * @param duration pulse duration in micro seconds, eg:1500\n     */\n    //% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n    //% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n    //% parts=microservo blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::servoSetPulse\n    servoSetPulse(duration: int32): void;\n\n    /**\n     * Indicates if the servo is running continuously\n     */\n    //% blockHidden=1 shim=PwmOnlyPinMethods::servoSetContinuous\n    servoSetContinuous(continuous: boolean): void;\n}\ndeclare namespace control {\n\n    /**\n     * Announce that an event happened to registered handlers.\n     * @param src ID of the MicroBit Component that generated the event\n     * @param value Component specific code indicating the cause of the event.\n     */\n    //% weight=21 blockGap=12 blockId=\"control_raise_event\"\n    //% help=control/raise-event\n    //% block=\"raise event|from %src|with value %value\" blockExternalInputs=1 shim=control::raiseEvent\n    function raiseEvent(src: int32, value: int32): void;\n\n    /**\n     * Determine the version of system software currently running.\n     */\n    //% blockId=\"control_device_dal_version\" block=\"device dal version\"\n    //% help=control/device-dal-version shim=control::deviceDalVersion\n    function deviceDalVersion(): string;\n\n    /**\n     * Allocates the next user notification event\n     */\n    //% help=control/allocate-notify-event shim=control::allocateNotifyEvent\n    function allocateNotifyEvent(): int32;\n\n    /** Write a message to DMESG debugging buffer. */\n    //% shim=control::dmesg\n    function dmesg(s: string): void;\n\n    /** Write a message and value (pointer) to DMESG debugging buffer. */\n    //% shim=control::dmesgPtr\n    function dmesgPtr(str: string, ptr: Object): void;\n}\n\n\ndeclare interface I2C {\n    /**\n     * Read `size` bytes from a 7-bit I2C `address`.\n     */\n    //% repeat.defl=0 shim=I2CMethods::readBuffer\n    readBuffer(address: int32, size: int32, repeat?: boolean): Buffer;\n\n    /**\n     * Write bytes to a 7-bit I2C `address`.\n     */\n    //% repeat.defl=0 shim=I2CMethods::writeBuffer\n    writeBuffer(address: int32, buf: Buffer, repeat?: boolean): int32;\n}\ndeclare namespace pins {\n\n    /**\n     * Opens a Serial communication driver\n     */\n    //% help=pins/create-i2c\n    //% parts=i2c shim=pins::createI2C\n    function createI2C(sda: DigitalInOutPin, scl: DigitalInOutPin): I2C;\n}\ndeclare namespace pins {\n\n    /**\n     * Opens a SPI driver\n     */\n    //% help=pins/create-spi\n    //% parts=spi shim=pins::createSPI\n    function createSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin): SPI;\n\n    /**\n     * Opens a slave SPI driver\n     */\n    //% parts=spi shim=pins::createSlaveSPI\n    function createSlaveSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin, csPin: DigitalInOutPin): SPI;\n}\n\n\ndeclare interface SPI {\n    /**\n     * Write to the SPI bus\n     */\n    //% shim=SPIMethods::write\n    write(value: int32): int32;\n\n    /**\n     * Transfer buffers over the SPI bus\n     */\n    //% argsNullable shim=SPIMethods::transfer\n    transfer(command: Buffer, response: Buffer): void;\n\n    /**\n     * Sets the SPI clock frequency\n     */\n    //% shim=SPIMethods::setFrequency\n    setFrequency(frequency: int32): void;\n\n    /**\n     * Sets the SPI bus mode\n     */\n    //% shim=SPIMethods::setMode\n    setMode(mode: int32): void;\n}\ndeclare namespace configStorage {\n\n    /**\n     * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n     * @param key the identifier (max 16 characters)\n     * @param value the data (max 32 characters)\n     */\n    //% shim=configStorage::setBuffer\n    function setBuffer(key: string, value: Buffer): void;\n\n    /**\n     * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n     * @param key the identifier (max 16 characters)\n     */\n    //% shim=configStorage::getBuffer\n    function getBuffer(key: string): Buffer;\n\n    /**\n     * Removes the key from local storage\n     * @param key the identifier (max 16 characters)\n     */\n    //% shim=configStorage::removeItem\n    function removeItem(key: string): void;\n\n    /**\n     * Clears the local storage\n     */\n    //% shim=configStorage::clear\n    function clear(): void;\n}\n\n// Auto-generated. Do not edit. Really.\n","spi.cpp":"#include \"pxt.h\"\n#include \"ErrorNo.h\"\n\nnamespace pins {\n\nclass CodalSPIProxy {\nprivate:\n    DevicePin* mosi; \n    DevicePin* miso; \n    DevicePin* sck;\n    CODAL_SPI spi;\npublic:\n    CodalSPIProxy* next;\n\npublic:\n    CodalSPIProxy(DevicePin* _mosi, DevicePin* _miso, DevicePin* _sck)\n        : mosi(_mosi)\n        , miso(_miso)\n        , sck(_sck)\n        , spi(*_mosi, *_miso, *_sck) \n        , next(NULL)\n    {\n    }\n\n#ifdef CODAL_SPI_SLAVE_SUPPORTED\n    CodalSPIProxy(DevicePin* _mosi, DevicePin* _miso, DevicePin* _sck, DevicePin* _cs)\n        : mosi(_mosi)\n        , miso(_miso)\n        , sck(_sck)\n        , spi(*_mosi, *_miso, *_sck, _cs) \n        , next(NULL)\n    {\n    }\n#endif\n\n    CODAL_SPI* getSPI() {\n        return &spi;\n    }\n\n    bool matchPins(DevicePin* mosi, DevicePin* miso, DevicePin* sck) {\n        return this->mosi == mosi && this->miso == miso && this->sck == sck;\n    }\n\n    int write(int value) {\n        return spi.write(value);\n    }\n\n    void transfer(Buffer command, Buffer response) {\n        auto cdata = NULL == command ? NULL : command->data;\n        auto clength = NULL == command ? 0 : command->length;\n        auto rdata = NULL == response ? NULL : response->data;\n        auto rlength = NULL == response ? 0 : response->length;\n        spi.transfer(cdata, clength, rdata, rlength);\n    }\n\n    void setFrequency(int frequency) {\n        spi.setFrequency(frequency);\n    }\n\n    void setMode(int mode) {\n        spi.setMode(mode);\n    }\n};\n\nSPI_ spis(NULL);\n\n/**\n* Opens a SPI driver\n*/\n//% help=pins/create-spi\n//% parts=spi\nSPI_ createSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin) {\n  auto dev = spis;\n  while(dev) {\n    if (dev->matchPins(mosiPin, misoPin, sckPin))\n      return dev;\n    dev = dev->next;\n  }\n\n  auto ser = new CodalSPIProxy(mosiPin, misoPin, sckPin);\n  ser->next = spis;\n  spis = ser;\n  return ser;\n}\n\n/**\n* Opens a slave SPI driver\n*/\n//% parts=spi\nSPI_ createSlaveSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin, DigitalInOutPin csPin) {\n#ifdef CODAL_SPI_SLAVE_SUPPORTED\n  auto dev = spis;\n  if (!csPin)\n    soft_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n  while(dev) {\n    if (dev->matchPins(mosiPin, misoPin, sckPin))\n      return dev;\n    dev = dev->next;\n  }\n\n  auto ser = new CodalSPIProxy(mosiPin, misoPin, sckPin, csPin);\n  ser->next = spis;\n  spis = ser;\n  return ser;\n#else\n  soft_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n  return NULL;\n#endif\n}\n\n}\n\nnamespace pxt {\n\nCODAL_SPI* getSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin) {\n    auto spi = pins::createSPI(mosiPin, misoPin, sckPin);\n    return spi->getSPI();\n}\n\n}\n\nnamespace SPIMethods {\n\n/**\n* Write to the SPI bus\n*/\n//%\nint write(SPI_ device, int value) {\n    return device->write(value);\n}\n\n/**\n* Transfer buffers over the SPI bus\n*/\n//% argsNullable\nvoid transfer(SPI_ device, Buffer command, Buffer response) {\n    if (!device)\n        soft_panic(PANIC_CAST_FROM_NULL);\n    if (!command && !response)\n        return;\n    device->transfer(command, response);\n}\n\n/**\n* Sets the SPI clock frequency\n*/\n//%\nvoid setFrequency(SPI_ device, int frequency) {\n    device->setFrequency(frequency);\n}\n\n/**\n* Sets the SPI bus mode\n*/\n//%\nvoid setMode(SPI_ device, int mode) {\n    device->setMode(mode);\n}\n\n}\n","spi.ts":"namespace pins {\n\n    let _spi: SPI;\n    /**\n    * Gets the default SPI driver\n    */\n    //%\n    export function spi() {\n        if (!_spi) {\n            const mosi = pins.pinByCfg(DAL.CFG_PIN_MOSI);\n            const miso = pins.pinByCfg(DAL.CFG_PIN_MISO);\n            const sck = pins.pinByCfg(DAL.CFG_PIN_SCK);\n            _spi = pins.createSPI(mosi, miso, sck);\n        }\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 advanced=true\n    //% blockId=spi_write block=\"spi write %value\"\n    export function spiWrite(value: number) {\n        return spi().write(value);\n    }\n\n    /**\n     * Write a given command to SPI bus, and at the same time read the response.\n     */\n    //% help=pins/spi-transfer weight=4 advanced=true\n    //% blockId=spi_transfer block=\"spi transfer %command into %response\"\n    export function spiTransfer(command: Buffer, response: Buffer) {\n        spi().transfer(command, response);\n    }\n\n    /**\n     * Set the SPI frequency\n     * @param frequency the clock frequency, eg: 1000000\n     */\n    //% help=pins/spi-frequency weight=4 advanced=true\n    //% blockId=spi_frequency block=\"spi frequency %frequency\"\n    export function spiFrequency(frequency: number) {\n        spi().setFrequency(frequency);\n    }\n\n    /**\n     * Set the SPI signal mode\n     * @param mode the mode, eg: 3\n     */\n    //% help=pins/spi-mode weight=3 advanced=true\n    //% blockId=spi_mode block=\"spi mode %mode\"\n    export function spiMode(mode: number) {\n        spi().setMode(mode);\n    }\n}","test.ts":"let i = 1\nlet f = 0.5\nlet plus = i + f\nlet minus = i - f\n\nlet r = Math.random()\nlet ri = Math.randomRange(5, 10)\n\n","timer.ts":"namespace control {\n    /**\n     * A timer\n     */\n    //% fixedInstances\n    export class Timer {\n        start: number;\n\n        constructor() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Gets the elapsed time in millis since the last reset\n         */\n        //% blockId=timerMillis block=\"%timer|millis\"\n        millis(): number {\n            return control.millis() - this.start;\n        }\n\n        /**\n         * Gets the elapsed time in seconds since the last reset\n         */\n        //% blockId=timerSeconds block=\"%timer|seconds\"\n        seconds(): number {\n            return this.millis() / 1000;\n        }\n\n        /**\n         * Resets the timer\n         */\n        //% blockId=timerRest block=\"%timer|reset\"\n        reset() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Pauses until the timer reaches the given amount of milliseconds\n         * @param ms how long to pause for, eg: 5, 100, 200, 500, 1000, 2000\n         */\n        //% blockId=timerPauseUntil block=\"%timer|pause until (ms) %ms\"\n        pauseUntil(ms: number) {\n            const remaining = this.millis() - ms;\n            pause(Math.max(0, remaining));\n        }\n    }\n\n    //% whenUsed fixedInstance block=\"timer 1\"\n    export const timer1 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 2\"\n    export const timer2 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 3\"\n    export const timer3 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 4\"\n    export const timer4 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 5\"\n    export const timer5 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 6\"\n    export const timer6 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 7\"\n    export const timer7 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 8\"\n    export const timer8 = new Timer();\n}","uf2format.h":"#ifndef UF2FORMAT_H\n#define UF2FORMAT_H 1\n\n#include <stdint.h>\n#include <stdbool.h>\n\n// All entries are little endian.\n\n#ifndef BOOTLOADER_START\n#define BOOTLOADER_START 0x0\n#endif\n\n#ifndef BOOTLOADER_END\n#define BOOTLOADER_END 0x2000\n#endif\n\n#ifndef UF2_BINFO\n#define UF2_BINFO ((UF2_BInfo *)(BOOTLOADER_END - sizeof(UF2_BInfo)))\n#endif\n\n#ifndef UF2_INFO_TXT\n#define UF2_INFO_TXT UF2_BINFO->info_uf2\n#endif\n\n\n#define UF2_MAGIC_START0 0x0A324655UL // \"UF2\\n\"\n#define UF2_MAGIC_START1 0x9E5D5157UL // Randomly selected\n#define UF2_MAGIC_END 0x0AB16F30UL    // Ditto\n\n// If set, the block is \"comment\" and should not be flashed to the device\n#define UF2_FLAG_NOFLASH 0x00000001\n\ntypedef struct {\n    // 32 byte header\n    uint32_t magicStart0;\n    uint32_t magicStart1;\n    uint32_t flags;\n    uint32_t targetAddr;\n    uint32_t payloadSize;\n    uint32_t blockNo;\n    uint32_t numBlocks;\n    uint32_t reserved;\n\n    // raw data;\n    uint8_t data[476];\n\n    // store magic also at the end to limit damage from partial block reads\n    uint32_t magicEnd;\n} UF2_Block;\n\ntypedef struct {\n    uint8_t version;\n    uint8_t ep_in;\n    uint8_t ep_out;\n    uint8_t reserved0;\n    uint32_t cbw_tag;\n    uint32_t blocks_remaining;\n    uint8_t *buffer;\n} UF2_HandoverArgs;\n\ntypedef void (*UF2_MSC_Handover_Handler)(UF2_HandoverArgs *handover);\ntypedef void (*UF2_HID_Handover_Handler)(int ep);\n\n// this is required to be exactly 16 bytes long by the linker script\ntypedef struct {\n    void *reserved0;\n    UF2_HID_Handover_Handler handoverHID;\n    UF2_MSC_Handover_Handler handoverMSC;\n    const char *info_uf2;\n} UF2_BInfo;\n\nstatic inline bool is_uf2_block(void *data) {\n    UF2_Block *bl = (UF2_Block *)data;\n    return bl->magicStart0 == UF2_MAGIC_START0 && bl->magicStart1 == UF2_MAGIC_START1 &&\n           bl->magicEnd == UF2_MAGIC_END;\n}\n\nstatic inline bool in_uf2_bootloader_space(const void *addr) {\n    return (BOOTLOADER_START + 0x100) <= (uint32_t)addr && (uint32_t)addr < (BOOTLOADER_END);\n}\n\nstatic inline const char *uf2_info(void) {\n    if (in_uf2_bootloader_space(UF2_INFO_TXT))\n        return UF2_INFO_TXT;\n    return \"N/A\";\n}\n\n#ifdef UF2_DEFINE_HANDOVER\nstatic inline void hf2_handover(uint8_t ep) {\n    const char *board_info = UF2_BINFO->info_uf2;\n    UF2_HID_Handover_Handler fn = UF2_BINFO->handoverHID;\n\n    if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&\n        ((uint32_t)fn & 1)) {\n        // Pass control to bootloader; never returns\n        fn(ep & 0xf);\n    }\n}\n\nstatic inline void check_uf2_handover(uint8_t *buffer, uint32_t blocks_remaining, uint8_t ep_in,\n                                      uint8_t ep_out, uint32_t cbw_tag) {\n    if (!is_uf2_block(buffer))\n        return;\n\n    const char *board_info = UF2_BINFO->info_uf2;\n    UF2_MSC_Handover_Handler fn = UF2_BINFO->handoverMSC;\n\n    if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&\n        ((uint32_t)fn & 1)) {\n        UF2_HandoverArgs hand = {\n            1, ep_in, ep_out, 0, cbw_tag, blocks_remaining, buffer,\n        };\n        // Pass control to bootloader; never returns\n        fn(&hand);\n    }\n}\n#endif\n\n#endif\n","uf2hid.h":"#ifndef UF2_HID_H\n#define UF2_HID_H 1\n\n#define HF2_CMD_BININFO 0x0001\n// no arguments\n#define HF2_MODE_BOOTLOADER 0x01\n#define HF2_MODE_USERSPACE 0x02\nstruct HF2_BININFO_Result {\n    uint32_t mode;\n    uint32_t flash_page_size;\n    uint32_t flash_num_pages;\n    uint32_t max_message_size;\n    uint32_t uf2_family;\n};\n\n#define HF2_CMD_INFO 0x0002\n// no arguments\n// results is utf8 character array\n\n#define HF2_CMD_RESET_INTO_APP 0x0003\n// no arguments, no result\n\n#define HF2_CMD_RESET_INTO_BOOTLOADER 0x0004\n// no arguments, no result\n\n#define HF2_CMD_START_FLASH 0x0005\n// no arguments, no result\n\n#define HF2_CMD_WRITE_FLASH_PAGE 0x0006\nstruct HF2_WRITE_FLASH_PAGE_Command {\n    uint32_t target_addr;\n    uint32_t data[0];\n};\n// no result\n\n#define HF2_CMD_CHKSUM_PAGES 0x0007\nstruct HF2_CHKSUM_PAGES_Command {\n    uint32_t target_addr;\n    uint32_t num_pages;\n};\nstruct HF2_CHKSUM_PAGES_Result {\n    uint16_t chksums[0 /* num_pages */];\n};\n\n#define HF2_CMD_READ_WORDS 0x0008\nstruct HF2_READ_WORDS_Command {\n    uint32_t target_addr;\n    uint32_t num_words;\n};\nstruct HF2_READ_WORDS_Result {\n    uint32_t words[0 /* num_words */];\n};\n\n#define HF2_CMD_WRITE_WORDS 0x0009\nstruct HF2_WRITE_WORDS_Command {\n    uint32_t target_addr;\n    uint32_t num_words;\n    uint32_t words[0 /* num_words */];\n};\n// no result\n\n#define HF2_CMD_DMESG 0x0010\n// no arguments\n// results is utf8 character array\n\n#define HF2_EV_MASK 0x800000\n\n#define HF2_CMD_JDS_CONFIG 0x0020\n#define HF2_CMD_JDS_SEND 0x0021\n#define HF2_EV_JDS_PACKET 0x800020\n\ntypedef struct {\n    uint32_t command_id;\n    uint16_t tag;\n    uint8_t reserved0;\n    uint8_t reserved1;\n\n    union {\n        struct HF2_WRITE_FLASH_PAGE_Command write_flash_page;\n        struct HF2_WRITE_WORDS_Command write_words;\n        struct HF2_READ_WORDS_Command read_words;\n        struct HF2_CHKSUM_PAGES_Command chksum_pages;\n        uint8_t data8[0];\n        uint16_t data16[0];\n        uint32_t data32[0];\n    };\n} HF2_Command;\n\ntypedef struct {\n    union {\n        uint32_t eventId;\n        struct {\n            uint16_t tag;\n            union {\n                struct {\n                    uint8_t status;\n                    uint8_t status_info;\n                };\n                uint16_t status16;\n            };\n        };\n    };\n    union {\n        struct HF2_BININFO_Result bininfo;\n        uint8_t data8[0];\n        uint16_t data16[0];\n        uint32_t data32[0];\n    };\n} HF2_Response;\n\n#define HF2_FLAG_SERIAL_OUT 0x80\n#define HF2_FLAG_SERIAL_ERR 0xC0\n#define HF2_FLAG_CMDPKT_LAST 0x40\n#define HF2_FLAG_CMDPKT_BODY 0x00\n#define HF2_FLAG_MASK 0xC0\n#define HF2_SIZE_MASK 63\n\n#define HF2_STATUS_OK 0x00\n#define HF2_STATUS_INVALID_CMD 0x01\n#define HF2_STATUS_INVALID_STATE 0x02\n\n#endif\n","usb.cpp":"#include \"pxt.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"uf2format.h\"\n\nnamespace pxt {\nCodalUSB usb;\n\n// share the buffer; we will crash anyway if someone talks to us over both at the same time\nHF2_Buffer hf2buf;\nHF2 hf2(hf2buf);\n#ifdef HF2_HID\nHF2 hf2hid(hf2buf);\n#endif\nDummyIface dummyIface;\n\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nUSBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nUSBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nUSBHIDJoystick joystick;\n#endif\n\nstatic const DeviceDescriptor device_desc = {\n    0x12,   // bLength\n    0x01,   // bDescriptorType\n    0x0210, // bcdUSBL\n\n    // Class etc specified per-interface\n    0x00, 0x00, 0x00,\n\n    0x40, // bMaxPacketSize0\n    USB_DEFAULT_VID, USB_DEFAULT_PID,\n    0x4202, // bcdDevice - leave unchanged for the HF2 to work\n    0x01,   // iManufacturer\n    0x02,   // iProduct\n    0x03,   // SerialNumber\n    0x01    // bNumConfigs\n};\n\nstatic void start_usb() {\n    // start USB with a delay, so that user code can add new interfaces if needed\n    // (eg USB HID keyboard, or MSC)\n    fiber_sleep(500);\n    usb.start();\n}\n\nvoid platform_usb_init() __attribute__((weak));\nvoid platform_usb_init() {}\n\nvoid set_usb_strings(const char *uf2_info) {\n    static const char *string_descriptors[3];\n    static char serial[12];\n    itoa(target_get_serial() & 0x7fffffff, serial);\n\n    auto model = strstr(uf2_info, \"Model: \");\n    if (model) {\n        model += 7;\n        auto end = model;\n        while (*end && *end != '\\n' && *end != '\\r')\n            end++;\n        auto len = end - model;\n        auto dev = (char *)app_alloc(len + 10);\n        memcpy(dev, model, len);\n        strcpy(dev + len, \" (app)\");\n        // try to split into manufacturer and\n        auto sep = strstr(dev, \" / \");\n        if (sep) {\n            *sep = '\\0';\n            string_descriptors[0] = dev;\n            string_descriptors[1] = sep + 3;\n        } else {\n            string_descriptors[0] = dev;\n            string_descriptors[1] = dev;\n        }\n    } else {\n        string_descriptors[0] = \"Unknown Corp.\";\n        string_descriptors[1] = \"PXT Device (app)\";\n    }\n\n    string_descriptors[2] = serial;\n    usb.stringDescriptors = string_descriptors;\n}\n\nvoid usb_init() {\n    usb.deviceDescriptor = &device_desc;\n    set_usb_strings(UF2_INFO_TXT);\n\n    platform_usb_init();\n\n    usb.add(hf2);\n\n#ifdef HF2_HID\n    hf2hid.useHID = true;\n    usb.add(hf2hid);\n#else\n    // the WINUSB descriptors don't seem to work if there's only one interface\n    // so we add a dummy interface\n    usb.add(dummyIface);\n#endif\n\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n    usb.add(mouse);\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n    usb.add(keyboard);\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n    usb.add(joystick);\n#endif\n\n    create_fiber(start_usb);\n}\n\n} // namespace pxt\n\n#else\nnamespace pxt {\nvoid usb_init() {}\n} // namespace pxt\n#endif\n\nnamespace control {\n/**\n * Determines if the USB has been enumerated.\n */\n//%\nbool isUSBInitialized() {\n#if CONFIG_ENABLED(DEVICE_USB)\n    return pxt::usb.isInitialised();\n#else\n    return false;\n#endif\n}\n} // namespace control\n\nnamespace pxt {\nstatic void (*pSendToUART)(const char *data, int len) = NULL;\nvoid setSendToUART(void (*f)(const char *, int)) {\n    pSendToUART = f;\n}\n\nvoid sendSerial(const char *data, int len) {\n#if CONFIG_ENABLED(DEVICE_USB)\n    hf2.sendSerial(data, len);\n#if HF2_HID\n    hf2hid.sendSerial(data, len);\n#endif\n#endif\n    if (pSendToUART)\n        pSendToUART(data, len);\n}\n\nvoid dumpDmesg() {\n    sendSerial(\"\\nDMESG:\\n\", 8);\n    sendSerial(codalLogStore.buffer, codalLogStore.ptr);\n    sendSerial(\"\\n\\n\", 2);\n}\n\nvoid (*logJDFrame)(const uint8_t *data);\nvoid (*sendJDFrame)(const uint8_t *data);\n\n} // namespace pxt\n"},"core---samd":{"README.md":"# core\n\nThe core library for Codal-based targets.\n\n","codal.cpp":"#include \"pxt.h\"\n#include \"LowLevelTimer.h\"\nusing namespace codal;\n\nvoid cpu_clock_init(void);\n\nPXT_ABI(__aeabi_dadd)\nPXT_ABI(__aeabi_dcmplt)\nPXT_ABI(__aeabi_dcmpgt)\nPXT_ABI(__aeabi_dsub)\nPXT_ABI(__aeabi_ddiv)\nPXT_ABI(__aeabi_dmul)\n\n#ifdef DEVICE_GET_FIBER_LIST_AVAILABLE\n// newer codal-core has get_fiber_list() but not list_fibers()\nnamespace codal {\n/*\n * Return all current fibers.\n *\n * @param dest If non-null, it points to an array of pointers to fibers to store results in.\n *\n * @return the number of fibers (potentially) stored\n */\nint list_fibers(Fiber **dest) {\n    int i = 0;\n    for (Fiber *fib = codal::get_fiber_list(); fib; fib = fib->next) {\n        if (dest)\n            dest[i] = fib;\n        i++;\n    }\n    return i;\n}\n\n} // namespace codal\n#endif\n\nnamespace pxt {\n\nvoid platform_init();\nvoid usb_init();\n\n// The first two word are used to tell the bootloader that a single reset should start the\n// bootloader and the MSD device, not us.\n// The rest is reserved for partial flashing checksums.\n__attribute__((section(\".binmeta\"))) __attribute__((used)) const uint32_t pxt_binmeta[] = {\n    0x87eeb07c, 0x87eeb07c, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,\n    0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,\n};\n\nEvent lastEvent;\nMessageBus devMessageBus;\ncodal::CodalDevice device;\n\nstruct FreeList {\n    FreeList *next;\n};\n\nstatic void commInit() {\n    int commSize = bytecode[20];\n    if (!commSize)\n        return;\n\n    void *r = app_alloc_at((void *)PXT_COMM_BASE, commSize);\n    DMESG(\"comm %d -> %p\", commSize, r);\n    if (!r)\n        target_panic(20);\n}\n\nstatic void initCodal() {\n    cpu_clock_init();\n\n    commInit();\n\n    // Bring up fiber scheduler.\n    scheduler_init(devMessageBus);\n\n    // We probably don't need that - components are initialized when one obtains\n    // the reference to it.\n    // devMessageBus.listen(DEVICE_ID_MESSAGE_BUS_LISTENER, DEVICE_EVT_ANY, this,\n    // &CircuitPlayground::onListenerRegisteredEvent);\n\n    for (int i = 0; i < DEVICE_COMPONENT_COUNT; i++) {\n        if (CodalComponent::components[i])\n            CodalComponent::components[i]->init();\n    }\n\n    usb_init();\n\n    auto led = LOOKUP_PIN(LED);\n    if (led) {\n        led->setDigitalValue(0);\n    }\n}\n\n// ---------------------------------------------------------------------------\n// An adapter for the API expected by the run-time.\n// ---------------------------------------------------------------------------\n\n// We have the invariant that if [dispatchEvent] is registered against the DAL\n// for a given event, then [handlersMap] contains a valid entry for that\n// event.\nvoid dispatchEvent(Event e) {\n    lastEvent = e;\n\n    auto curr = findBinding(e.source, e.value);\n    auto value = fromInt(e.value);\n    while (curr) {\n        runAction1(curr->action, value);\n        curr = nextBinding(curr->next, e.source, e.value);\n    }\n}\n\nvoid registerWithDal(int id, int event, Action a, int flags) {\n    // first time?\n    if (!findBinding(id, event)) {\n        devMessageBus.listen(id, event, dispatchEvent, flags);\n        if (event == 0) {\n            // we're registering for all events on given ID\n            // need to remove old listeners for specific events\n            auto curr = findBinding(id, -1);\n            while (curr) {\n                devMessageBus.ignore(id, curr->value, dispatchEvent);\n                curr = nextBinding(curr->next, id, -1);\n            }\n        }\n    }\n    setBinding(id, event, a);\n}\n\nvoid fiberDone(void *a) {\n    unregisterGCPtr((Action)a);\n    release_fiber();\n}\n\nvoid releaseFiber() {\n    release_fiber();\n}\n\nvoid sleep_ms(unsigned ms) {\n    fiber_sleep(ms);\n}\n\nvoid sleep_us(uint64_t us) {\n    target_wait_us(us);\n}\n\nvoid forever_stub(void *a) {\n    while (true) {\n        runAction0((Action)a);\n        fiber_sleep(20);\n    }\n}\n\nvoid runForever(Action a) {\n    if (a != 0) {\n        registerGCPtr(a);\n        create_fiber(forever_stub, (void *)a);\n    }\n}\n\nvoid runInParallel(Action a) {\n    if (a != 0) {\n        registerGCPtr(a);\n        create_fiber((void (*)(void *))(void*)runAction0, (void *)a, fiberDone);\n    }\n}\n\nvoid waitForEvent(int id, int event) {\n    fiber_wait_for_event(id, event);\n}\n\nvoid initRuntime() {\n    initSystemTimer();\n    initCodal();\n    platform_init();\n}\n\n//%\nunsigned afterProgramPage() {\n    unsigned ptr = (unsigned)&bytecode[0];\n    ptr += programSize();\n    ptr = (ptr + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);\n    return ptr;\n}\n\nuint64_t getLongSerialNumber() {\n    return device.getSerialNumber();\n}\n\nint current_time_ms() {\n    return system_timer_current_time();\n}\n\nuint64_t current_time_us() {\n    return system_timer_current_time_us();\n}\n\nThreadContext *getThreadContext() {\n    if (!currentFiber)\n        return NULL;\n    return (ThreadContext *)currentFiber->user_data;\n}\n\nvoid setThreadContext(ThreadContext *ctx) {\n    currentFiber->user_data = ctx;\n}\n\nstatic void *threadAddressFor(codal::Fiber *fib, void *sp) {\n    if (fib == currentFiber)\n        return sp;\n    return (uint8_t *)sp + ((uint8_t *)fib->stack_top - (uint8_t *)tcb_get_stack_base(fib->tcb));\n}\n\nvoid gcProcessStacks(int flags) {\n    // check scheduler is initialized\n    if (!currentFiber) {\n        // make sure we allocate something to at least initalize the memory allocator\n        void *volatile p = xmalloc(1);\n        xfree(p);\n        return;\n    }\n\n    int numFibers = codal::list_fibers(NULL);\n    codal::Fiber **fibers = (codal::Fiber **)xmalloc(sizeof(codal::Fiber *) * numFibers);\n    int num2 = codal::list_fibers(fibers);\n    if (numFibers != num2)\n        oops(12);\n    int cnt = 0;\n\n    for (int i = 0; i < numFibers; ++i) {\n        auto fib = fibers[i];\n        auto ctx = (ThreadContext *)fib->user_data;\n        if (!ctx)\n            continue;\n        gcProcess(ctx->thrownValue);\n        for (auto seg = &ctx->stack; seg; seg = seg->next) {\n            auto ptr = (TValue *)threadAddressFor(fib, seg->top);\n            auto end = (TValue *)threadAddressFor(fib, seg->bottom);\n            if (flags & 2)\n                DMESG(\"RS%d:%p/%d\", cnt++, ptr, end - ptr);\n            // VLOG(\"mark: %p - %p\", ptr, end);\n            while (ptr < end) {\n                gcProcess(*ptr++);\n            }\n        }\n    }\n    xfree(fibers);\n}\n\nLowLevelTimer *getJACDACTimer() {\n    static LowLevelTimer *jacdacTimer;\n    if (!jacdacTimer) {\n        jacdacTimer = allocateTimer();\n        jacdacTimer->setIRQPriority(1);\n    }\n    return jacdacTimer;\n}\nvoid initSystemTimer() {\n    new CODAL_TIMER(*allocateTimer());\n}\n\n} // namespace pxt\n","control.cpp":"#include \"pxt.h\"\n\n#if defined(NRF52_SERIES) || defined(PICO_BOARD)\n#define _estack __StackTop \n#endif\nextern uint32_t _estack;\n\nnamespace control {\n\n/**\n * Announce that an event happened to registered handlers.\n * @param src ID of the MicroBit Component that generated the event\n * @param value Component specific code indicating the cause of the event.\n */\n//% weight=21 blockGap=12 blockId=\"control_raise_event\"\n//% help=control/raise-event\n//% block=\"raise event|from %src|with value %value\" blockExternalInputs=1\nvoid raiseEvent(int src, int value) {\n    Event evt(src, value);\n}\n\n/**\n* Determine the version of system software currently running.\n*/\n//% blockId=\"control_device_dal_version\" block=\"device dal version\"\n//% help=control/device-dal-version\nString deviceDalVersion() {\n    return mkString(device.getVersion());\n}\n\n/**\n* Allocates the next user notification event\n*/\n//% help=control/allocate-notify-event\nint allocateNotifyEvent() {\n    return ::allocateNotifyEvent();\n}\n\n/** Write a message to DMESG debugging buffer. */\n//%\nvoid dmesg(String s) {\n    DMESG(\"# %s\", s->getUTF8Data());\n}\n\n/** Write a message and value (pointer) to DMESG debugging buffer. */\n//%\nvoid dmesgPtr(String str, Object_ ptr) {\n    DMESG(\"# %s: %p\", str->getUTF8Data(), ptr);\n}\n\n//%\nuint32_t _ramSize()\n{\n    return (uint32_t)&_estack & 0x1fffffff;\n}\n\n}\n","dal.d.ts":"// Auto-generated. Do not edit.\ndeclare const enum DAL {\n    // /libraries/codal-core/inc/JACDAC/JDPhysicalLayer.h\n    Receiving = 0,\n    Transmitting = 1,\n    Error = 2,\n    Unknown = 3,\n    ListeningForPulse = 0,\n    ErrorRecovery = 1,\n    Off = 2,\n    Continuation = 0,\n    // /libraries/codal-core/inc/JACDAC/JDServiceClasses.h\n    STATIC_CLASS_START = 0,\n    STATIC_CLASS_END = 16777215,\n    DYNAMIC_CLASS_END = 4294967295,\n    // /libraries/codal-core/inc/core/CodalComponent.h\n    DEVICE_ID_BUTTON_A = 1,\n    DEVICE_ID_BUTTON_B = 2,\n    DEVICE_ID_BUTTON_AB = 3,\n    DEVICE_ID_BUTTON_RESET = 4,\n    DEVICE_ID_ACCELEROMETER = 5,\n    DEVICE_ID_COMPASS = 6,\n    DEVICE_ID_DISPLAY = 7,\n    DEVICE_ID_THERMOMETER = 8,\n    DEVICE_ID_RADIO = 9,\n    DEVICE_ID_RADIO_DATA_READY = 10,\n    DEVICE_ID_MULTIBUTTON_ATTACH = 11,\n    DEVICE_ID_SERIAL = 12,\n    DEVICE_ID_GESTURE = 13,\n    DEVICE_ID_SYSTEM_TIMER = 14,\n    DEVICE_ID_SCHEDULER = 15,\n    DEVICE_ID_COMPONENT = 16,\n    DEVICE_ID_LIGHT_SENSOR = 17,\n    DEVICE_ID_TOUCH_SENSOR = 18,\n    DEVICE_ID_SYSTEM_DAC = 19,\n    DEVICE_ID_SYSTEM_MICROPHONE = 20,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR = 21,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR_SPL = 22,\n    DEVICE_ID_MSC = 23,\n    DEVICE_ID_SPI = 24,\n    DEVICE_ID_DISTANCE = 25,\n    DEVICE_ID_GYROSCOPE = 26,\n    DEVICE_ID_HUMIDITY = 27,\n    DEVICE_ID_PRESSURE = 28,\n    DEVICE_ID_SINGLE_WIRE_SERIAL = 29,\n    DEVICE_ID_JACDAC = 30,\n    DEVICE_ID_JACDAC_PHYS = 31,\n    DEVICE_ID_JACDAC_CONTROL_SERVICE = 32,\n    DEVICE_ID_JACDAC_CONFIGURATION_SERVICE = 33,\n    DEVICE_ID_IO_P0 = 100,\n    DEVICE_ID_MESSAGE_BUS_LISTENER = 1021,\n    DEVICE_ID_NOTIFY_ONE = 1022,\n    DEVICE_ID_NOTIFY = 1023,\n    DEVICE_ID_BUTTON_UP = 2000,\n    DEVICE_ID_BUTTON_DOWN = 2001,\n    DEVICE_ID_BUTTON_LEFT = 2002,\n    DEVICE_ID_BUTTON_RIGHT = 2003,\n    DEVICE_ID_JD_DYNAMIC_ID = 3000,\n    DEVICE_COMPONENT_RUNNING = 4096,\n    DEVICE_COMPONENT_STATUS_SYSTEM_TICK = 8192,\n    DEVICE_COMPONENT_STATUS_IDLE_TICK = 16384,\n    DEVICE_COMPONENT_LISTENERS_CONFIGURED = 1,\n    DEVICE_COMPONENT_EVT_SYSTEM_TICK = 1,\n    // /libraries/codal-core/inc/core/CodalFiber.h\n    DEVICE_SCHEDULER_RUNNING = 1,\n    DEVICE_SCHEDULER_IDLE = 2,\n    DEVICE_FIBER_FLAG_FOB = 1,\n    DEVICE_FIBER_FLAG_PARENT = 2,\n    DEVICE_FIBER_FLAG_CHILD = 4,\n    DEVICE_FIBER_FLAG_DO_NOT_PAGE = 8,\n    DEVICE_SCHEDULER_EVT_TICK = 1,\n    DEVICE_SCHEDULER_EVT_IDLE = 2,\n    // /libraries/codal-core/inc/core/CodalListener.h\n    MESSAGE_BUS_LISTENER_PARAMETERISED = 1,\n    MESSAGE_BUS_LISTENER_METHOD = 2,\n    MESSAGE_BUS_LISTENER_BUSY = 4,\n    MESSAGE_BUS_LISTENER_REENTRANT = 8,\n    MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY = 16,\n    MESSAGE_BUS_LISTENER_DROP_IF_BUSY = 32,\n    MESSAGE_BUS_LISTENER_NONBLOCKING = 64,\n    MESSAGE_BUS_LISTENER_URGENT = 128,\n    MESSAGE_BUS_LISTENER_DELETING = 32768,\n    MESSAGE_BUS_LISTENER_IMMEDIATE = 192,\n    // /libraries/codal-core/inc/core/ErrorNo.h\n    DEVICE_OK = 0,\n    DEVICE_INVALID_PARAMETER = -1001,\n    DEVICE_NOT_SUPPORTED = -1002,\n    DEVICE_CALIBRATION_IN_PROGRESS = -1003,\n    DEVICE_CALIBRATION_REQUIRED = -1004,\n    DEVICE_NO_RESOURCES = -1005,\n    DEVICE_BUSY = -1006,\n    DEVICE_CANCELLED = -1007,\n    DEVICE_I2C_ERROR = -1010,\n    DEVICE_SERIAL_IN_USE = -1011,\n    DEVICE_NO_DATA = -1012,\n    DEVICE_NOT_IMPLEMENTED = -1013,\n    DEVICE_SPI_ERROR = -1014,\n    DEVICE_INVALID_STATE = -1015,\n    DEVICE_OOM = 20,\n    DEVICE_HEAP_ERROR = 30,\n    DEVICE_NULL_DEREFERENCE = 40,\n    DEVICE_USB_ERROR = 50,\n    DEVICE_JACDAC_ERROR = 60,\n    DEVICE_HARDWARE_CONFIGURATION_ERROR = 90,\n    // /libraries/codal-core/inc/core/NotifyEvents.h\n    DISPLAY_EVT_FREE = 1,\n    CODAL_SERIAL_EVT_TX_EMPTY = 2,\n    BLE_EVT_SERIAL_TX_EMPTY = 3,\n    ARCADE_PLAYER_JOIN_RESULT = 4,\n    DEVICE_NOTIFY_USER_EVENT_BASE = 1024,\n    // /libraries/codal-core/inc/driver-models/AbstractButton.h\n    DEVICE_BUTTON_EVT_DOWN = 1,\n    DEVICE_BUTTON_EVT_UP = 2,\n    DEVICE_BUTTON_EVT_CLICK = 3,\n    DEVICE_BUTTON_EVT_LONG_CLICK = 4,\n    DEVICE_BUTTON_EVT_HOLD = 5,\n    DEVICE_BUTTON_EVT_DOUBLE_CLICK = 6,\n    DEVICE_BUTTON_LONG_CLICK_TIME = 1000,\n    DEVICE_BUTTON_HOLD_TIME = 1500,\n    DEVICE_BUTTON_STATE = 1,\n    DEVICE_BUTTON_STATE_HOLD_TRIGGERED = 2,\n    DEVICE_BUTTON_STATE_CLICK = 4,\n    DEVICE_BUTTON_STATE_LONG_CLICK = 8,\n    DEVICE_BUTTON_SIGMA_MIN = 0,\n    DEVICE_BUTTON_SIGMA_MAX = 12,\n    DEVICE_BUTTON_SIGMA_THRESH_HI = 8,\n    DEVICE_BUTTON_SIGMA_THRESH_LO = 2,\n    DEVICE_BUTTON_DOUBLE_CLICK_THRESH = 50,\n    DEVICE_BUTTON_SIMPLE_EVENTS = 0,\n    DEVICE_BUTTON_ALL_EVENTS = 1,\n    ACTIVE_LOW = 0,\n    ACTIVE_HIGH = 1,\n    // /libraries/codal-core/inc/driver-models/Accelerometer.h\n    ACCELEROMETER_IMU_DATA_VALID = 2,\n    ACCELEROMETER_EVT_DATA_UPDATE = 1,\n    ACCELEROMETER_EVT_NONE = 0,\n    ACCELEROMETER_EVT_TILT_UP = 1,\n    ACCELEROMETER_EVT_TILT_DOWN = 2,\n    ACCELEROMETER_EVT_TILT_LEFT = 3,\n    ACCELEROMETER_EVT_TILT_RIGHT = 4,\n    ACCELEROMETER_EVT_FACE_UP = 5,\n    ACCELEROMETER_EVT_FACE_DOWN = 6,\n    ACCELEROMETER_EVT_FREEFALL = 7,\n    ACCELEROMETER_EVT_3G = 8,\n    ACCELEROMETER_EVT_6G = 9,\n    ACCELEROMETER_EVT_8G = 10,\n    ACCELEROMETER_EVT_SHAKE = 11,\n    ACCELEROMETER_EVT_2G = 12,\n    ACCELEROMETER_REST_TOLERANCE = 200,\n    ACCELEROMETER_TILT_TOLERANCE = 200,\n    ACCELEROMETER_FREEFALL_TOLERANCE = 400,\n    ACCELEROMETER_SHAKE_TOLERANCE = 400,\n    ACCELEROMETER_2G_TOLERANCE = 2048,\n    ACCELEROMETER_3G_TOLERANCE = 3072,\n    ACCELEROMETER_6G_TOLERANCE = 6144,\n    ACCELEROMETER_8G_TOLERANCE = 8192,\n    ACCELEROMETER_GESTURE_DAMPING = 5,\n    ACCELEROMETER_SHAKE_DAMPING = 10,\n    ACCELEROMETER_SHAKE_RTX = 30,\n    ACCELEROMETER_SHAKE_COUNT_THRESHOLD = 4,\n    // /libraries/codal-core/inc/driver-models/Compass.h\n    COMPASS_STATUS_RUNNING = 1,\n    COMPASS_STATUS_CALIBRATED = 2,\n    COMPASS_STATUS_CALIBRATING = 4,\n    COMPASS_STATUS_ADDED_TO_IDLE = 8,\n    COMPASS_EVT_DATA_UPDATE = 1,\n    COMPASS_EVT_CONFIG_NEEDED = 2,\n    COMPASS_EVT_CALIBRATE = 3,\n    COMPASS_EVT_CALIBRATION_NEEDED = 4,\n    // /libraries/codal-core/inc/driver-models/Gyroscope.h\n    GYROSCOPE_IMU_DATA_VALID = 2,\n    GYROSCOPE_EVT_DATA_UPDATE = 1,\n    // /libraries/codal-core/inc/driver-models/LowLevelTimer.h\n    TimerModeTimer = 0,\n    TimerModeCounter = 1,\n    TimerModeAlternateFunction = 2,\n    BitMode8 = 0,\n    BitMode16 = 1,\n    BitMode24 = 2,\n    BitMode32 = 3,\n    // /libraries/codal-core/inc/driver-models/Pin.h\n    IO_STATUS_DIGITAL_IN = 1,\n    IO_STATUS_DIGITAL_OUT = 2,\n    IO_STATUS_ANALOG_IN = 4,\n    IO_STATUS_ANALOG_OUT = 8,\n    IO_STATUS_TOUCH_IN = 16,\n    IO_STATUS_EVENT_ON_EDGE = 32,\n    IO_STATUS_EVENT_PULSE_ON_EDGE = 64,\n    IO_STATUS_INTERRUPT_ON_EDGE = 128,\n    DEVICE_PIN_MAX_OUTPUT = 1023,\n    DEVICE_PIN_MAX_SERVO_RANGE = 180,\n    DEVICE_PIN_DEFAULT_SERVO_RANGE = 2000,\n    DEVICE_PIN_DEFAULT_SERVO_CENTER = 1500,\n    DEVICE_PIN_EVENT_NONE = 0,\n    DEVICE_PIN_INTERRUPT_ON_EDGE = 1,\n    DEVICE_PIN_EVENT_ON_EDGE = 2,\n    DEVICE_PIN_EVENT_ON_PULSE = 3,\n    DEVICE_PIN_EVENT_ON_TOUCH = 4,\n    DEVICE_PIN_EVT_RISE = 2,\n    DEVICE_PIN_EVT_FALL = 3,\n    DEVICE_PIN_EVT_PULSE_HI = 4,\n    DEVICE_PIN_EVT_PULSE_LO = 5,\n    PIN_CAPABILITY_DIGITAL = 1,\n    PIN_CAPABILITY_ANALOG = 2,\n    PIN_CAPABILITY_AD = 3,\n    PIN_CAPABILITY_ALL = 3,\n    None = 0,\n    Down = 1,\n    Up = 2,\n    // /libraries/codal-core/inc/driver-models/Radio.h\n    RADIO_EVT_DATA_READY = 2,\n    // /libraries/codal-core/inc/driver-models/SPIFlash.h\n    SPIFLASH_PAGE_SIZE = 256,\n    SPIFLASH_SMALL_ROW_PAGES = 16,\n    SPIFLASH_BIG_ROW_PAGES = 256,\n    // /libraries/codal-core/inc/driver-models/Sensor.h\n    SENSOR_THRESHOLD_LOW = 1,\n    SENSOR_THRESHOLD_HIGH = 2,\n    SENSOR_UPDATE_NEEDED = 3,\n    SENSOR_INITIALISED = 1,\n    SENSOR_HIGH_THRESHOLD_PASSED = 2,\n    SENSOR_LOW_THRESHOLD_PASSED = 4,\n    SENSOR_LOW_THRESHOLD_ENABLED = 8,\n    SENSOR_HIGH_THRESHOLD_ENABLED = 16,\n    SENSOR_DEFAULT_SENSITIVITY = 868,\n    SENSOR_DEFAULT_SAMPLE_PERIOD = 500,\n    // /libraries/codal-core/inc/driver-models/Serial.h\n    CODAL_SERIAL_DEFAULT_BAUD_RATE = 115200,\n    CODAL_SERIAL_DEFAULT_BUFFER_SIZE = 20,\n    CODAL_SERIAL_EVT_DELIM_MATCH = 1,\n    CODAL_SERIAL_EVT_HEAD_MATCH = 2,\n    CODAL_SERIAL_EVT_RX_FULL = 3,\n    CODAL_SERIAL_EVT_DATA_RECEIVED = 4,\n    CODAL_SERIAL_STATUS_RX_IN_USE = 1,\n    CODAL_SERIAL_STATUS_TX_IN_USE = 2,\n    CODAL_SERIAL_STATUS_RX_BUFF_INIT = 4,\n    CODAL_SERIAL_STATUS_TX_BUFF_INIT = 8,\n    CODAL_SERIAL_STATUS_RXD = 16,\n    ASYNC = 0,\n    SYNC_SPINWAIT = 1,\n    SYNC_SLEEP = 2,\n    RxInterrupt = 0,\n    TxInterrupt = 1,\n    // /libraries/codal-core/inc/driver-models/SingleWireSerial.h\n    SWS_EVT_DATA_RECEIVED = 1,\n    SWS_EVT_DATA_SENT = 2,\n    SWS_EVT_ERROR = 3,\n    SWS_EVT_DATA_DROPPED = 4,\n    SingleWireRx = 0,\n    SingleWireTx = 1,\n    SingleWireDisconnected = 2,\n    // /libraries/codal-core/inc/driver-models/Timer.h\n    CODAL_TIMER_DEFAULT_EVENT_LIST_SIZE = 10,\n    // /libraries/codal-core/inc/drivers/AnalogSensor.h\n    ANALOG_THRESHOLD_LOW = 1,\n    ANALOG_THRESHOLD_HIGH = 2,\n    ANALOG_SENSOR_UPDATE_NEEDED = 3,\n    ANALOG_SENSOR_INITIALISED = 1,\n    ANALOG_SENSOR_HIGH_THRESHOLD_PASSED = 2,\n    ANALOG_SENSOR_LOW_THRESHOLD_PASSED = 4,\n    ANALOG_SENSOR_LOW_THRESHOLD_ENABLED = 8,\n    ANALOG_SENSOR_HIGH_THRESHOLD_ENABLED = 16,\n    // /libraries/codal-core/inc/drivers/AnimatedDisplay.h\n    DISPLAY_EVT_ANIMATION_COMPLETE = 1,\n    DISPLAY_DEFAULT_AUTOCLEAR = 1,\n    DISPLAY_SPACING = 1,\n    DISPLAY_ANIMATE_DEFAULT_POS = -255,\n    DISPLAY_DEFAULT_SCROLL_SPEED = 120,\n    DISPLAY_DEFAULT_SCROLL_STRIDE = -1,\n    DISPLAY_DEFAULT_PRINT_SPEED = 400,\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    // /libraries/codal-core/inc/drivers/FAT.h\n    FAT_RESERVED_SECTORS = 1,\n    FAT_ROOT_DIR_SECTORS = 4,\n    // /libraries/codal-core/inc/drivers/HID.h\n    HID_REQUEST_GET_REPORT = 1,\n    HID_REQUEST_GET_IDLE = 2,\n    HID_REQUEST_GET_PROTOCOL = 3,\n    HID_REQUEST_SET_REPORT = 9,\n    HID_REQUEST_SET_IDLE = 10,\n    HID_REQUEST_SET_PROTOCOL = 11,\n    // /libraries/codal-core/inc/drivers/HIDKeyboard.h\n    HID_KEYBOARD_NUM_REPORTS = 3,\n    HID_KEYBOARD_REPORT_GENERIC = 1,\n    HID_KEYBOARD_REPORT_CONSUMER = 2,\n    HID_KEYBOARD_KEYSTATE_SIZE_GENERIC = 8,\n    HID_KEYBOARD_KEYSTATE_SIZE_CONSUMER = 2,\n    HID_KEYBOARD_MODIFIER_OFFSET = 2,\n    HID_KEYBOARD_DELAY_DEFAULT = 10,\n    PressKey = 0,\n    ReleaseKey = 1,\n    // /libraries/codal-core/inc/drivers/KeyMap.h\n    KEYMAP_ALL_KEYS_UP_Val = 1,\n    KEYMAP_ALL_KEYS_UP_POS = 28,\n    KEYMAP_NORMAL_KEY_Val = 0,\n    KEYMAP_MODIFIER_KEY_Val = 1,\n    KEYMAP_MODIFIER_POS = 29,\n    KEYMAP_MEDIA_KEY_Val = 1,\n    KEYMAP_MEDIA_POS = 30,\n    KEYMAP_KEY_UP_Val = 0,\n    KEYMAP_KEY_DOWN_Val = 1,\n    KEYMAP_KEY_DOWN_POS = 31,\n    // /libraries/codal-core/inc/drivers/KeyValueStorage.h\n    DEVICE_KEY_VALUE_STORE_OFFSET = 4,\n    KEY_VALUE_STORAGE_MAGIC = 49370,\n    KEY_VALUE_STORAGE_BLOCK_SIZE = 48,\n    KEY_VALUE_STORAGE_KEY_SIZE = 16,\n    KEY_VALUE_STORAGE_SCRATCH_WORD_SIZE = 64,\n    KEY_VALUE_STORAGE_MAX_PAIRS = 5,\n    // /libraries/codal-core/inc/drivers/LEDMatrix.h\n    LED_MATRIX_GREYSCALE_BIT_DEPTH = 8,\n    LED_MATRIX_EVT_LIGHT_SENSE = 2,\n    LED_MATRIX_EVT_FRAME_TIMEOUT = 3,\n    LED_MATRIX_MINIMUM_BRIGHTNESS = 1,\n    LED_MATRIX_MAXIMUM_BRIGHTNESS = 255,\n    LED_MATRIX_DEFAULT_BRIGHTNESS = 255,\n    DISPLAY_MODE_BLACK_AND_WHITE = 0,\n    DISPLAY_MODE_GREYSCALE = 1,\n    DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE = 2,\n    MATRIX_DISPLAY_ROTATION_0 = 0,\n    MATRIX_DISPLAY_ROTATION_90 = 1,\n    MATRIX_DISPLAY_ROTATION_180 = 2,\n    MATRIX_DISPLAY_ROTATION_270 = 3,\n    NO_CONN = 0,\n    // /libraries/codal-core/inc/drivers/MMA8653.h\n    MICROBIT_ACCEL_PITCH_ROLL_VALID = 2,\n    MICROBIT_ACCEL_ADDED_TO_IDLE = 4,\n    // /libraries/codal-core/inc/drivers/MultiButton.h\n    MULTI_BUTTON_STATE_1 = 1,\n    MULTI_BUTTON_STATE_2 = 2,\n    MULTI_BUTTON_HOLD_TRIGGERED_1 = 4,\n    MULTI_BUTTON_HOLD_TRIGGERED_2 = 8,\n    MULTI_BUTTON_SUPRESSED_1 = 16,\n    MULTI_BUTTON_SUPRESSED_2 = 32,\n    MULTI_BUTTON_ATTACHED = 64,\n    // /libraries/codal-core/inc/drivers/TouchButton.h\n    TOUCH_BUTTON_CALIBRATION_PERIOD = 10,\n    TOUCH_BUTTON_CALIBRATION_LINEAR_OFFSET = 2,\n    TOUCH_BUTTON_CALIBRATION_PERCENTAGE_OFFSET = 5,\n    TOUCH_BUTTON_CALIBRATING = 16,\n    // /libraries/codal-core/inc/drivers/TouchSensor.h\n    TOUCH_SENSOR_MAX_BUTTONS = 10,\n    TOUCH_SENSOR_SAMPLE_PERIOD = 50,\n    TOUCH_SENSE_SAMPLE_MAX = 1000,\n    TOUCH_SENSOR_UPDATE_NEEDED = 1,\n    // /libraries/codal-core/inc/drivers/USBJACDAC.h\n    JACDAC_USB_STATUS_CLEAR_TO_SEND = 2,\n    // /libraries/codal-core/inc/drivers/USB_HID_Keys.h\n    KEY_MOD_LCTRL = 1,\n    KEY_MOD_LSHIFT = 2,\n    KEY_MOD_LALT = 4,\n    KEY_MOD_LMETA = 8,\n    KEY_MOD_RCTRL = 16,\n    KEY_MOD_RSHIFT = 32,\n    KEY_MOD_RALT = 64,\n    KEY_MOD_RMETA = 128,\n    KEY_NONE = 0,\n    KEY_ERR_OVF = 1,\n    KEY_A = 4,\n    KEY_B = 5,\n    KEY_C = 6,\n    KEY_D = 7,\n    KEY_E = 8,\n    KEY_F = 9,\n    KEY_G = 10,\n    KEY_H = 11,\n    KEY_I = 12,\n    KEY_J = 13,\n    KEY_K = 14,\n    KEY_L = 15,\n    KEY_M = 16,\n    KEY_N = 17,\n    KEY_O = 18,\n    KEY_P = 19,\n    KEY_Q = 20,\n    KEY_R = 21,\n    KEY_S = 22,\n    KEY_T = 23,\n    KEY_U = 24,\n    KEY_V = 25,\n    KEY_W = 26,\n    KEY_X = 27,\n    KEY_Y = 28,\n    KEY_Z = 29,\n    KEY_1 = 30,\n    KEY_2 = 31,\n    KEY_3 = 32,\n    KEY_4 = 33,\n    KEY_5 = 34,\n    KEY_6 = 35,\n    KEY_7 = 36,\n    KEY_8 = 37,\n    KEY_9 = 38,\n    KEY_0 = 39,\n    KEY_ENTER = 40,\n    KEY_ESC = 41,\n    KEY_BACKSPACE = 42,\n    KEY_TAB = 43,\n    KEY_SPACE = 44,\n    KEY_MINUS = 45,\n    KEY_EQUAL = 46,\n    KEY_LEFTBRACE = 47,\n    KEY_RIGHTBRACE = 48,\n    KEY_BACKSLASH = 49,\n    KEY_HASHTILDE = 50,\n    KEY_SEMICOLON = 51,\n    KEY_APOSTROPHE = 52,\n    KEY_GRAVE = 53,\n    KEY_COMMA = 54,\n    KEY_DOT = 55,\n    KEY_SLASH = 56,\n    KEY_CAPSLOCK = 57,\n    KEY_F1 = 58,\n    KEY_F2 = 59,\n    KEY_F3 = 60,\n    KEY_F4 = 61,\n    KEY_F5 = 62,\n    KEY_F6 = 63,\n    KEY_F7 = 64,\n    KEY_F8 = 65,\n    KEY_F9 = 66,\n    KEY_F10 = 67,\n    KEY_F11 = 68,\n    KEY_F12 = 69,\n    KEY_SYSRQ = 70,\n    KEY_SCROLLLOCK = 71,\n    KEY_PAUSE = 72,\n    KEY_INSERT = 73,\n    KEY_HOME = 74,\n    KEY_PAGEUP = 75,\n    KEY_DELETE = 76,\n    KEY_END = 77,\n    KEY_PAGEDOWN = 78,\n    KEY_RIGHT = 79,\n    KEY_LEFT = 80,\n    KEY_DOWN = 81,\n    KEY_UP = 82,\n    KEY_NUMLOCK = 83,\n    KEY_KPSLASH = 84,\n    KEY_KPASTERISK = 85,\n    KEY_KPMINUS = 86,\n    KEY_KPPLUS = 87,\n    KEY_KPENTER = 88,\n    KEY_KP1 = 89,\n    KEY_KP2 = 90,\n    KEY_KP3 = 91,\n    KEY_KP4 = 92,\n    KEY_KP5 = 93,\n    KEY_KP6 = 94,\n    KEY_KP7 = 95,\n    KEY_KP8 = 96,\n    KEY_KP9 = 97,\n    KEY_KP0 = 98,\n    KEY_KPDOT = 99,\n    KEY_102ND = 100,\n    KEY_COMPOSE = 101,\n    KEY_POWER = 102,\n    KEY_KPEQUAL = 103,\n    KEY_F13 = 104,\n    KEY_F14 = 105,\n    KEY_F15 = 106,\n    KEY_F16 = 107,\n    KEY_F17 = 108,\n    KEY_F18 = 109,\n    KEY_F19 = 110,\n    KEY_F20 = 111,\n    KEY_F21 = 112,\n    KEY_F22 = 113,\n    KEY_F23 = 114,\n    KEY_F24 = 115,\n    KEY_OPEN = 116,\n    KEY_HELP = 117,\n    KEY_PROPS = 118,\n    KEY_FRONT = 119,\n    KEY_STOP = 120,\n    KEY_AGAIN = 121,\n    KEY_UNDO = 122,\n    KEY_CUT = 123,\n    KEY_COPY = 124,\n    KEY_PASTE = 125,\n    KEY_FIND = 126,\n    KEY_MUTE = 127,\n    KEY_VOLUMEUP = 128,\n    KEY_VOLUMEDOWN = 129,\n    KEY_KPCOMMA = 133,\n    KEY_RO = 135,\n    KEY_KATAKANAHIRAGANA = 136,\n    KEY_YEN = 137,\n    KEY_HENKAN = 138,\n    KEY_MUHENKAN = 139,\n    KEY_KPJPCOMMA = 140,\n    KEY_HANGEUL = 144,\n    KEY_HANJA = 145,\n    KEY_KATAKANA = 146,\n    KEY_HIRAGANA = 147,\n    KEY_ZENKAKUHANKAKU = 148,\n    KEY_KPLEFTPAREN = 182,\n    KEY_KPRIGHTPAREN = 183,\n    KEY_LEFTCTRL = 224,\n    KEY_LEFTSHIFT = 225,\n    KEY_LEFTALT = 226,\n    KEY_LEFTMETA = 227,\n    KEY_RIGHTCTRL = 228,\n    KEY_RIGHTSHIFT = 229,\n    KEY_RIGHTALT = 230,\n    KEY_RIGHTMETA = 231,\n    KEY_MEDIA_PLAYPAUSE = 232,\n    KEY_MEDIA_STOPCD = 233,\n    KEY_MEDIA_PREVIOUSSONG = 234,\n    KEY_MEDIA_NEXTSONG = 235,\n    KEY_MEDIA_EJECTCD = 236,\n    KEY_MEDIA_VOLUMEUP = 237,\n    KEY_MEDIA_VOLUMEDOWN = 238,\n    KEY_MEDIA_MUTE = 239,\n    KEY_MEDIA_WWW = 240,\n    KEY_MEDIA_BACK = 241,\n    KEY_MEDIA_FORWARD = 242,\n    KEY_MEDIA_STOP = 243,\n    KEY_MEDIA_FIND = 244,\n    KEY_MEDIA_SCROLLUP = 245,\n    KEY_MEDIA_SCROLLDOWN = 246,\n    KEY_MEDIA_EDIT = 247,\n    KEY_MEDIA_SLEEP = 248,\n    KEY_MEDIA_COFFEE = 249,\n    KEY_MEDIA_REFRESH = 250,\n    KEY_MEDIA_CALC = 251,\n    // /libraries/codal-core/inc/drivers/uf2format.h\n    UF2FORMAT_H = 1,\n    APP_START_ADDRESS = 8192,\n    UF2_FLAG_NOFLASH = 1,\n    // /libraries/codal-core/inc/streams/DataStream.h\n    DATASTREAM_MAXIMUM_BUFFERS = 1,\n    // /libraries/codal-core/inc/streams/LevelDetector.h\n    LEVEL_THRESHOLD_LOW = 1,\n    LEVEL_THRESHOLD_HIGH = 2,\n    LEVEL_DETECTOR_INITIALISED = 1,\n    LEVEL_DETECTOR_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_DEFAULT_WINDOW_SIZE = 128,\n    // /libraries/codal-core/inc/streams/LevelDetectorSPL.h\n    LEVEL_DETECTOR_SPL_INITIALISED = 1,\n    LEVEL_DETECTOR_SPL_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_SPL_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_SPL_DEFAULT_WINDOW_SIZE = 128,\n    // /libraries/codal-core/inc/streams/Synthesizer.h\n    SYNTHESIZER_SAMPLE_RATE = 44100,\n    TONE_WIDTH = 1024,\n    // /libraries/codal-core/inc/types/BitmapFont.h\n    BITMAP_FONT_WIDTH = 5,\n    BITMAP_FONT_HEIGHT = 5,\n    BITMAP_FONT_ASCII_START = 32,\n    BITMAP_FONT_ASCII_END = 126,\n    // /libraries/codal-core/inc/types/CoordinateSystem.h\n    COORDINATE_SPACE_ROTATED_0 = 0,\n    COORDINATE_SPACE_ROTATED_90 = 1,\n    COORDINATE_SPACE_ROTATED_180 = 2,\n    COORDINATE_SPACE_ROTATED_270 = 3,\n    RAW = 0,\n    SIMPLE_CARTESIAN = 1,\n    NORTH_EAST_DOWN = 2,\n    NORTH_EAST_UP = 3,\n    // /libraries/codal-core/inc/types/Event.h\n    DEVICE_ID_ANY = 0,\n    DEVICE_EVT_ANY = 0,\n    CREATE_ONLY = 0,\n    CREATE_AND_FIRE = 1,\n    DEVICE_EVENT_DEFAULT_LAUNCH_MODE = 1,\n    // /libraries/codal-core/inc/types/RefCounted.h\n    REF_TAG_STRING = 1,\n    REF_TAG_BUFFER = 2,\n    REF_TAG_IMAGE = 3,\n    REF_TAG_USER = 32,\n    // /pxtapp/accelerometer/axis.h\n    ACC_SYSTEM = 3,\n    ACC_ROTATION = 0,\n    // /pxtapp/configkeys.h\n    CFG_PIN_NAME_MSK = 65535,\n    CFG_PIN_CONFIG_MSK = 4294901760,\n    CFG_PIN_CONFIG_ACTIVE_LO = 65536,\n    CFG_MAGIC0 = 513675505,\n    CFG_MAGIC1 = 539130489,\n    CFG_PIN_ACCELEROMETER_INT = 1,\n    CFG_PIN_ACCELEROMETER_SCL = 2,\n    CFG_PIN_ACCELEROMETER_SDA = 3,\n    CFG_PIN_BTN_A = 4,\n    CFG_PIN_BTN_B = 5,\n    CFG_PIN_BTN_SLIDE = 6,\n    CFG_PIN_DOTSTAR_CLOCK = 7,\n    CFG_PIN_DOTSTAR_DATA = 8,\n    CFG_PIN_FLASH_CS = 9,\n    CFG_PIN_FLASH_MISO = 10,\n    CFG_PIN_FLASH_MOSI = 11,\n    CFG_PIN_FLASH_SCK = 12,\n    CFG_PIN_LED = 13,\n    CFG_PIN_LIGHT = 14,\n    CFG_PIN_MICROPHONE = 15,\n    CFG_PIN_MIC_CLOCK = 16,\n    CFG_PIN_MIC_DATA = 17,\n    CFG_PIN_MISO = 18,\n    CFG_PIN_MOSI = 19,\n    CFG_PIN_NEOPIXEL = 20,\n    CFG_PIN_RX = 21,\n    CFG_PIN_RXLED = 22,\n    CFG_PIN_SCK = 23,\n    CFG_PIN_SCL = 24,\n    CFG_PIN_SDA = 25,\n    CFG_PIN_SPEAKER_AMP = 26,\n    CFG_PIN_TEMPERATURE = 27,\n    CFG_PIN_TX = 28,\n    CFG_PIN_TXLED = 29,\n    CFG_PIN_IR_OUT = 30,\n    CFG_PIN_IR_IN = 31,\n    CFG_PIN_DISPLAY_SCK = 32,\n    CFG_PIN_DISPLAY_MISO = 33,\n    CFG_PIN_DISPLAY_MOSI = 34,\n    CFG_PIN_DISPLAY_CS = 35,\n    CFG_PIN_DISPLAY_DC = 36,\n    CFG_DISPLAY_WIDTH = 37,\n    CFG_DISPLAY_HEIGHT = 38,\n    CFG_DISPLAY_CFG0 = 39,\n    CFG_DISPLAY_CFG1 = 40,\n    CFG_DISPLAY_CFG2 = 41,\n    CFG_DISPLAY_CFG3 = 42,\n    CFG_PIN_DISPLAY_RST = 43,\n    CFG_PIN_DISPLAY_BL = 44,\n    CFG_PIN_SERVO_1 = 45,\n    CFG_PIN_SERVO_2 = 46,\n    CFG_PIN_BTN_LEFT = 47,\n    CFG_PIN_BTN_RIGHT = 48,\n    CFG_PIN_BTN_UP = 49,\n    CFG_PIN_BTN_DOWN = 50,\n    CFG_PIN_BTN_MENU = 51,\n    CFG_PIN_LED_R = 52,\n    CFG_PIN_LED_G = 53,\n    CFG_PIN_LED_B = 54,\n    CFG_PIN_LED1 = 55,\n    CFG_PIN_LED2 = 56,\n    CFG_PIN_LED3 = 57,\n    CFG_PIN_LED4 = 58,\n    CFG_SPEAKER_VOLUME = 59,\n    CFG_PIN_JACK_TX = 60,\n    CFG_PIN_JACK_SENSE = 61,\n    CFG_PIN_JACK_HPEN = 62,\n    CFG_PIN_JACK_BZEN = 63,\n    CFG_PIN_JACK_PWREN = 64,\n    CFG_PIN_JACK_SND = 65,\n    CFG_PIN_JACK_BUSLED = 66,\n    CFG_PIN_JACK_COMMLED = 67,\n    CFG_PIN_BTN_SOFT_RESET = 69,\n    CFG_ACCELEROMETER_TYPE = 70,\n    CFG_PIN_BTNMX_LATCH = 71,\n    CFG_PIN_BTNMX_CLOCK = 72,\n    CFG_PIN_BTNMX_DATA = 73,\n    CFG_PIN_BTN_MENU2 = 74,\n    CFG_PIN_BATTSENSE = 75,\n    CFG_PIN_VIBRATION = 76,\n    CFG_PIN_PWREN = 77,\n    CFG_DISPLAY_TYPE = 78,\n    CFG_PIN_ROTARY_ENCODER_A = 79,\n    CFG_PIN_ROTARY_ENCODER_B = 80,\n    CFG_ACCELEROMETER_SPACE = 81,\n    CFG_PIN_WIFI_MOSI = 82,\n    CFG_PIN_WIFI_MISO = 83,\n    CFG_PIN_WIFI_SCK = 84,\n    CFG_PIN_WIFI_TX = 85,\n    CFG_PIN_WIFI_RX = 86,\n    CFG_PIN_WIFI_CS = 87,\n    CFG_PIN_WIFI_BUSY = 88,\n    CFG_PIN_WIFI_RESET = 89,\n    CFG_PIN_WIFI_GPIO0 = 90,\n    CFG_PIN_WIFI_AT_TX = 91,\n    CFG_PIN_WIFI_AT_RX = 92,\n    CFG_PIN_USB_POWER = 93,\n    CFG_DISPLAY_DELAY = 94,\n    ACCELEROMETER_TYPE_LIS3DH = 50,\n    ACCELEROMETER_TYPE_LIS3DH_ALT = 48,\n    ACCELEROMETER_TYPE_MMA8453 = 56,\n    ACCELEROMETER_TYPE_FXOS8700 = 60,\n    ACCELEROMETER_TYPE_MMA8653 = 58,\n    ACCELEROMETER_TYPE_MSA300 = 76,\n    ACCELEROMETER_TYPE_MPU6050 = 104,\n    DISPLAY_TYPE_ST7735 = 7735,\n    DISPLAY_TYPE_ILI9341 = 9341,\n    DISPLAY_TYPE_SMART = 4242,\n    CFG_PIN_A0 = 100,\n    CFG_PIN_A1 = 101,\n    CFG_PIN_A2 = 102,\n    CFG_PIN_A3 = 103,\n    CFG_PIN_A4 = 104,\n    CFG_PIN_A5 = 105,\n    CFG_PIN_A6 = 106,\n    CFG_PIN_A7 = 107,\n    CFG_PIN_A8 = 108,\n    CFG_PIN_A9 = 109,\n    CFG_PIN_A10 = 110,\n    CFG_PIN_A11 = 111,\n    CFG_PIN_A12 = 112,\n    CFG_PIN_A13 = 113,\n    CFG_PIN_A14 = 114,\n    CFG_PIN_A15 = 115,\n    CFG_PIN_A16 = 116,\n    CFG_PIN_A17 = 117,\n    CFG_PIN_A18 = 118,\n    CFG_PIN_A19 = 119,\n    CFG_PIN_A20 = 120,\n    CFG_PIN_A21 = 121,\n    CFG_PIN_A22 = 122,\n    CFG_PIN_A23 = 123,\n    CFG_PIN_A24 = 124,\n    CFG_PIN_A25 = 125,\n    CFG_PIN_A26 = 126,\n    CFG_PIN_A27 = 127,\n    CFG_PIN_A28 = 128,\n    CFG_PIN_A29 = 129,\n    CFG_PIN_A30 = 130,\n    CFG_PIN_A31 = 131,\n    CFG_PIN_D0 = 150,\n    CFG_PIN_D1 = 151,\n    CFG_PIN_D2 = 152,\n    CFG_PIN_D3 = 153,\n    CFG_PIN_D4 = 154,\n    CFG_PIN_D5 = 155,\n    CFG_PIN_D6 = 156,\n    CFG_PIN_D7 = 157,\n    CFG_PIN_D8 = 158,\n    CFG_PIN_D9 = 159,\n    CFG_PIN_D10 = 160,\n    CFG_PIN_D11 = 161,\n    CFG_PIN_D12 = 162,\n    CFG_PIN_D13 = 163,\n    CFG_PIN_D14 = 164,\n    CFG_PIN_D15 = 165,\n    CFG_PIN_D16 = 166,\n    CFG_PIN_D17 = 167,\n    CFG_PIN_D18 = 168,\n    CFG_PIN_D19 = 169,\n    CFG_PIN_D20 = 170,\n    CFG_PIN_D21 = 171,\n    CFG_PIN_D22 = 172,\n    CFG_PIN_D23 = 173,\n    CFG_PIN_D24 = 174,\n    CFG_PIN_D25 = 175,\n    CFG_PIN_D26 = 176,\n    CFG_PIN_D27 = 177,\n    CFG_PIN_D28 = 178,\n    CFG_PIN_D29 = 179,\n    CFG_PIN_D30 = 180,\n    CFG_PIN_D31 = 181,\n    CFG_NUM_NEOPIXELS = 200,\n    CFG_NUM_DOTSTARS = 201,\n    CFG_DEFAULT_BUTTON_MODE = 202,\n    CFG_SWD_ENABLED = 203,\n    CFG_FLASH_BYTES = 204,\n    CFG_RAM_BYTES = 205,\n    CFG_SYSTEM_HEAP_BYTES = 206,\n    CFG_LOW_MEM_SIMULATION_KB = 207,\n    CFG_BOOTLOADER_BOARD_ID = 208,\n    CFG_UF2_FAMILY = 209,\n    CFG_PINS_PORT_SIZE = 210,\n    CFG_BOOTLOADER_PROTECTION = 211,\n    CFG_POWER_DEEPSLEEP_TIMEOUT = 212,\n    CFG_ANALOG_BUTTON_THRESHOLD = 213,\n    CFG_CPU_MHZ = 214,\n    CFG_CONTROLLER_LIGHT_MAX_BRIGHTNESS = 215,\n    CFG_ANALOG_JOYSTICK_MIN = 216,\n    CFG_ANALOG_JOYSTICK_MAX = 217,\n    CFG_TIMERS_TO_USE = 218,\n    CFG_PIN_ONBOARD_DOTSTAR_CLOCK = 219,\n    CFG_PIN_ONBOARD_DOTSTAR_DATA = 220,\n    CFG_NUM_ONBOARD_DOTSTARS = 221,\n    CFG_PIN_ONBOARD_NEOPIXEL = 222,\n    CFG_NUM_ONBOARD_NEOPIXELS = 223,\n    CFG_MATRIX_KEYPAD_MESSAGE_ID = 239,\n    CFG_NUM_MATRIX_KEYPAD_ROWS = 240,\n    CFG_PIN_MATRIX_KEYPAD_ROW0 = 241,\n    CFG_PIN_MATRIX_KEYPAD_ROW1 = 242,\n    CFG_PIN_MATRIX_KEYPAD_ROW2 = 243,\n    CFG_PIN_MATRIX_KEYPAD_ROW3 = 244,\n    CFG_PIN_MATRIX_KEYPAD_ROW4 = 245,\n    CFG_PIN_MATRIX_KEYPAD_ROW5 = 246,\n    CFG_PIN_MATRIX_KEYPAD_ROW6 = 247,\n    CFG_PIN_MATRIX_KEYPAD_ROW7 = 248,\n    CFG_NUM_MATRIX_KEYPAD_COLS = 250,\n    CFG_PIN_MATRIX_KEYPAD_COL0 = 251,\n    CFG_PIN_MATRIX_KEYPAD_COL1 = 252,\n    CFG_PIN_MATRIX_KEYPAD_COL2 = 253,\n    CFG_PIN_MATRIX_KEYPAD_COL3 = 254,\n    CFG_PIN_MATRIX_KEYPAD_COL4 = 255,\n    CFG_PIN_MATRIX_KEYPAD_COL5 = 256,\n    CFG_PIN_MATRIX_KEYPAD_COL6 = 257,\n    CFG_PIN_MATRIX_KEYPAD_COL7 = 258,\n    CFG_PIN_B0 = 300,\n    CFG_PIN_B1 = 301,\n    CFG_PIN_B2 = 302,\n    CFG_PIN_B3 = 303,\n    CFG_PIN_B4 = 304,\n    CFG_PIN_B5 = 305,\n    CFG_PIN_B6 = 306,\n    CFG_PIN_B7 = 307,\n    CFG_PIN_B8 = 308,\n    CFG_PIN_B9 = 309,\n    CFG_PIN_B10 = 310,\n    CFG_PIN_B11 = 311,\n    CFG_PIN_B12 = 312,\n    CFG_PIN_B13 = 313,\n    CFG_PIN_B14 = 314,\n    CFG_PIN_B15 = 315,\n    CFG_PIN_B16 = 316,\n    CFG_PIN_B17 = 317,\n    CFG_PIN_B18 = 318,\n    CFG_PIN_B19 = 319,\n    CFG_PIN_B20 = 320,\n    CFG_PIN_B21 = 321,\n    CFG_PIN_B22 = 322,\n    CFG_PIN_B23 = 323,\n    CFG_PIN_B24 = 324,\n    CFG_PIN_B25 = 325,\n    CFG_PIN_B26 = 326,\n    CFG_PIN_B27 = 327,\n    CFG_PIN_B28 = 328,\n    CFG_PIN_B29 = 329,\n    CFG_PIN_B30 = 330,\n    CFG_PIN_B31 = 331,\n    CFG_PIN_C0 = 350,\n    CFG_PIN_C1 = 351,\n    CFG_PIN_C2 = 352,\n    CFG_PIN_C3 = 353,\n    CFG_PIN_C4 = 354,\n    CFG_PIN_C5 = 355,\n    CFG_PIN_C6 = 356,\n    CFG_PIN_C7 = 357,\n    CFG_PIN_C8 = 358,\n    CFG_PIN_C9 = 359,\n    CFG_PIN_C10 = 360,\n    CFG_PIN_C11 = 361,\n    CFG_PIN_C12 = 362,\n    CFG_PIN_C13 = 363,\n    CFG_PIN_C14 = 364,\n    CFG_PIN_C15 = 365,\n    CFG_PIN_C16 = 366,\n    CFG_PIN_C17 = 367,\n    CFG_PIN_C18 = 368,\n    CFG_PIN_C19 = 369,\n    CFG_PIN_C20 = 370,\n    CFG_PIN_C21 = 371,\n    CFG_PIN_C22 = 372,\n    CFG_PIN_C23 = 373,\n    CFG_PIN_C24 = 374,\n    CFG_PIN_C25 = 375,\n    CFG_PIN_C26 = 376,\n    CFG_PIN_C27 = 377,\n    CFG_PIN_C28 = 378,\n    CFG_PIN_C29 = 379,\n    CFG_PIN_C30 = 380,\n    CFG_PIN_C31 = 381,\n    CFG_PIN_P0 = 400,\n    CFG_PIN_P1 = 401,\n    CFG_PIN_P2 = 402,\n    CFG_PIN_P3 = 403,\n    CFG_PIN_P4 = 404,\n    CFG_PIN_P5 = 405,\n    CFG_PIN_P6 = 406,\n    CFG_PIN_P7 = 407,\n    CFG_PIN_P8 = 408,\n    CFG_PIN_P9 = 409,\n    CFG_PIN_P10 = 410,\n    CFG_PIN_P11 = 411,\n    CFG_PIN_P12 = 412,\n    CFG_PIN_P13 = 413,\n    CFG_PIN_P14 = 414,\n    CFG_PIN_P15 = 415,\n    CFG_PIN_P16 = 416,\n    CFG_PIN_P17 = 417,\n    CFG_PIN_P18 = 418,\n    CFG_PIN_P19 = 419,\n    CFG_PIN_P20 = 420,\n    CFG_PIN_P21 = 421,\n    CFG_PIN_P22 = 422,\n    CFG_PIN_P23 = 423,\n    CFG_PIN_P24 = 424,\n    CFG_PIN_P25 = 425,\n    CFG_PIN_P26 = 426,\n    CFG_PIN_P27 = 427,\n    CFG_PIN_P28 = 428,\n    CFG_PIN_P29 = 429,\n    CFG_PIN_P30 = 430,\n    CFG_PIN_P31 = 431,\n    CFG_PIN_LORA_MISO = 1001,\n    CFG_PIN_LORA_MOSI = 1002,\n    CFG_PIN_LORA_SCK = 1003,\n    CFG_PIN_LORA_CS = 1004,\n    CFG_PIN_LORA_BOOT = 1005,\n    CFG_PIN_LORA_RESET = 1006,\n    CFG_PIN_IRRXLED = 1007,\n    CFG_PIN_IRTXLED = 1008,\n    CFG_PIN_LCD_RESET = 1009,\n    CFG_PIN_LCD_ENABLE = 1010,\n    CFG_PIN_LCD_DATALINE4 = 1011,\n    CFG_PIN_LCD_DATALINE5 = 1012,\n    CFG_PIN_LCD_DATALINE6 = 1013,\n    CFG_PIN_LCD_DATALINE7 = 1014,\n    CFG_NUM_LCD_COLUMNS = 1015,\n    CFG_NUM_LCD_ROWS = 1016,\n    CFG_PIN_RCC0 = 1017,\n    CFG_PIN_RCC1 = 1018,\n    CFG_PIN_RCC2 = 1019,\n    CFG_PIN_RCC3 = 1020,\n    CFG_PIN_RCC4 = 1021,\n    CFG_PIN_RCC5 = 1022,\n    CFG_PIN_RCC6 = 1023,\n    CFG_PIN_RCC7 = 1024,\n    CFG_PIN_SERVO0 = 1025,\n    CFG_PIN_SERVO1 = 1026,\n    CFG_PIN_SERVO2 = 1027,\n    CFG_PIN_SERVO3 = 1028,\n    CFG_PIN_SERVO4 = 1029,\n    CFG_PIN_SERVO5 = 1030,\n    CFG_PIN_SERVO6 = 1031,\n    CFG_PIN_SERVO7 = 1032,\n    CFG_PIN_SERVO8 = 1033,\n    CFG_PIN_PI_TX = 1034,\n    CFG_PIN_PI_RX = 1035,\n    CFG_PIN_GPS_SDA = 1036,\n    CFG_PIN_GPS_SCL = 1037,\n    CFG_PIN_GPS_TX = 1038,\n    CFG_PIN_GPS_RX = 1039,\n    CFG_PIN_GROVE0 = 1040,\n    CFG_PIN_GROVE1 = 1041,\n    CFG_PIN_SS = 1042,\n    CFG_USER_CFG_0 = 2000,\n    CFG_USER_CFG_1 = 2001,\n    CFG_USER_CFG_2 = 2002,\n    CFG_USER_CFG_3 = 2003,\n    CFG_USER_CFG_4 = 2004,\n    CFG_USER_CFG_5 = 2005,\n    CFG_USER_CFG_6 = 2006,\n    CFG_USER_CFG_7 = 2007,\n    CFG_USER_CFG_8 = 2008,\n    CFG_USER_CFG_9 = 2009,\n    CFG_ARCADE_CFG_0 = 2100,\n    CFG_ARCADE_CFG_1 = 2101,\n    CFG_ARCADE_SCREEN_WIDTH = 2102,\n    CFG_ARCADE_SCREEN_HEIGHT = 2103,\n    // /pxtapp/hf2dbg.h\n    HF2DBG_H = 1,\n    // /pxtapp/jacdac/jdprotocol.h\n    JDSPI_MAGIC = 31437,\n    JDSPI_MAGIC_NOOP = 46029,\n    // /pxtapp/mixer---samd/melody.h\n    SW_TRIANGLE = 1,\n    SW_SAWTOOTH = 2,\n    SW_SINE = 3,\n    SW_NOISE = 5,\n    SW_SQUARE_10 = 11,\n    SW_SQUARE_50 = 15,\n    CODAL = 1,\n    MAX_SOUNDS = 5,\n    Waiting = 0,\n    Playing = 1,\n    Done = 2,\n    // /pxtapp/pins.h\n    BUTTON_ACTIVE_HIGH_PULL_DOWN = 17,\n    BUTTON_ACTIVE_HIGH_PULL_UP = 33,\n    BUTTON_ACTIVE_HIGH_PULL_NONE = 49,\n    BUTTON_ACTIVE_LOW_PULL_DOWN = 16,\n    BUTTON_ACTIVE_LOW_PULL_UP = 32,\n    BUTTON_ACTIVE_LOW_PULL_NONE = 48,\n    // /pxtapp/platform.h\n    PAGE_SIZE = 512,\n    BOOTLOADER_START = 0,\n    DEV_NUM_PINS = 64,\n    PXT_74HC165 = 1,\n    IMAGE_BITS = 4,\n    PA00 = 0,\n    PA01 = 1,\n    PA02 = 2,\n    PA03 = 3,\n    PA04 = 4,\n    PA05 = 5,\n    PA06 = 6,\n    PA07 = 7,\n    PA08 = 8,\n    PA09 = 9,\n    PA10 = 10,\n    PA11 = 11,\n    PA12 = 12,\n    PA13 = 13,\n    PA14 = 14,\n    PA15 = 15,\n    PA16 = 16,\n    PA17 = 17,\n    PA18 = 18,\n    PA19 = 19,\n    PA20 = 20,\n    PA21 = 21,\n    PA22 = 22,\n    PA23 = 23,\n    PA24 = 24,\n    PA25 = 25,\n    PA26 = 26,\n    PA27 = 27,\n    PA28 = 28,\n    PA29 = 29,\n    PA30 = 30,\n    PA31 = 31,\n    PB00 = 32,\n    PB01 = 33,\n    PB02 = 34,\n    PB03 = 35,\n    PB04 = 36,\n    PB05 = 37,\n    PB06 = 38,\n    PB07 = 39,\n    PB08 = 40,\n    PB09 = 41,\n    PB10 = 42,\n    PB11 = 43,\n    PB12 = 44,\n    PB13 = 45,\n    PB14 = 46,\n    PB15 = 47,\n    PB16 = 48,\n    PB17 = 49,\n    PB18 = 50,\n    PB19 = 51,\n    PB20 = 52,\n    PB21 = 53,\n    PB22 = 54,\n    PB23 = 55,\n    PB24 = 56,\n    PB25 = 57,\n    PB26 = 58,\n    PB27 = 59,\n    PB28 = 60,\n    PB29 = 61,\n    PB30 = 62,\n    PB31 = 63,\n    // /pxtapp/pxt.h\n    DEVICE_ID_BUTTON_SLIDE = 3000,\n    DEVICE_ID_MICROPHONE = 3001,\n    DEVICE_ID_FIRST_BUTTON = 4000,\n    DEVICE_ID_FIRST_TOUCHBUTTON = 4100,\n    PXT_INTERNAL_KEY_UP = 2050,\n    PXT_INTERNAL_KEY_DOWN = 2051,\n    // /pxtapp/pxtbase.h\n    PXT32 = 1,\n    PXT64 = 1,\n    PXT_REFCNT_FLASH = 65534,\n    VTABLE_MAGIC = 249,\n    Undefined = 0,\n    Boolean = 1,\n    Number = 2,\n    String = 3,\n    Object = 4,\n    Function = 5,\n    BoxedString = 1,\n    BoxedNumber = 2,\n    BoxedBuffer = 3,\n    RefAction = 4,\n    RefImage = 5,\n    RefCollection = 6,\n    RefRefLocal = 7,\n    RefMap = 8,\n    RefMImage = 9,\n    MMap = 10,\n    User0 = 16,\n    PXT_IOS_HEAP_ALLOC_BITS = 20,\n    IMAGE_HEADER_MAGIC = 135,\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    UInt32LE = 11,\n    UInt32BE = 12,\n    Float32LE = 13,\n    Float64LE = 14,\n    Float32BE = 15,\n    Float64BE = 16,\n    NUM_TRY_FRAME_REGS = 3,\n    GC = 0,\n    // /pxtapp/pxtconfig.h\n    PXT_UF2_FAMILY = 1427194976,\n    // /pxtapp/settings/Flash.h\n    DEVICE_FLASH_ERROR = 922,\n    // /pxtapp/settings/RAFFS.h\n    RAFFS_FOLLOWING_MASK = 32768,\n    RAFFS_FLASH_BUFFER_SIZE = 64,\n    // /pxtapp/uf2hid.h\n    UF2_HID_H = 1,\n}\n","dmac.cpp":"#include \"dmac.h\"\n\nnamespace pxt {\n\n#ifdef CODAL_DMAC\nSINGLETON(WDMAC);\n#endif\n\n}","dmac.h":"#ifndef __DMAC_H\n#define __DMAC_H\n\n#include \"pxt.h\"\n\nnamespace pxt {\n\n#ifdef CODAL_DMAC\nclass WDMAC {\n  public:\n    CODAL_DMAC dmac;\n\n    WDMAC() {}\n};\n\nWDMAC* getWDMAC();\n#endif\n\n}\n\n#endif","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum PulseValue {\n    //% block=high\n    High = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=low\n    Low = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    }\n\n\n    declare const enum PinEvent {\n    //% block=\"pulse high\"\n    PulseHigh = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=\"pulse low\"\n    PulseLow = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    //% block=\"rise\"\n    Rise = 2,  // DEVICE_PIN_EVT_RISE\n    //% block=\"fall\"\n    Fall = 3,  // DEVICE_PIN_EVT_FALL\n    }\n\n\n    declare const enum PinPullMode {\n    //% block=\"down\"\n    PullDown = 0,\n    //% block=\"up\"\n    PullUp = 1,\n    //% block=\"none\"\n    PullNone = 2,\n    }\n\n// Auto-generated. Do not edit. Really.\n","hf2.cpp":"#include \"pxt.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#ifndef USB_HANDOVER\n#define USB_HANDOVER 1\n#endif\n\n#if USB_HANDOVER\n#define UF2_DEFINE_HANDOVER 1\n#endif\n\n#include \"uf2format.h\"\n\nstatic void *stackCopy;\nstatic uint32_t stackSize;\n\n//#define LOG DMESG\n#define LOG(...) ((void)0)\n\nstatic volatile bool resume = false;\n\nusing namespace codal;\n\n#ifdef HF2_HID\nstatic const char hidDescriptor[] = {\n    0x06, 0x97, 0xFF, // usage page vendor 0x97 (usage 0xff97 0x0001)\n    0x09, 0x01,       // usage 1\n    0xA1, 0x01,       // collection - application\n    0x15, 0x00,       // logical min 0\n    0x26, 0xFF, 0x00, // logical max 255\n    0x75, 8,          // report size 8\n    0x95, 64,         // report count 64\n    0x09, 0x01,       // usage 1\n    0x81, 0x02,       // input: data, variable, absolute\n    0x95, 64,         // report count 64\n    0x09, 0x01,       // usage 1\n    0x91, 0x02,       // output: data, variable, absolute\n    0x95, 1,          // report count 1\n    0x09, 0x01,       // usage 1\n    0xB1, 0x02,       // feature: data, variable, absolute\n    0xC0,             // end\n};\n\nstatic const HIDReportDescriptor reportDesc = {\n    9,\n    0x21,                  // HID\n    0x100,                 // hidbcd 1.00\n    0x00,                  // country code\n    0x01,                  // num desc\n    0x22,                  // report desc type\n    sizeof(hidDescriptor), // size of 0x22\n};\n\nstatic const InterfaceInfo ifaceInfoHID = {\n    &reportDesc,\n    sizeof(reportDesc),\n    1,\n    {\n        2,    // numEndpoints\n        0x03, /// class code - HID\n        0x00, // subclass\n        0x00, // protocol\n        0x02, // string\n        0x00, // alt\n    },\n    {USB_EP_TYPE_INTERRUPT, 1},\n    {USB_EP_TYPE_INTERRUPT, 1},\n};\n#endif\n\nstatic const InterfaceInfo ifaceInfoEP = {\n    NULL,\n    0,\n    2,\n    {\n        2,    // numEndpoints\n        0xff, /// class code - vendor-specific\n        42,   // subclass\n        1,    // protocol\n        0x02, // string\n        0x00, // alt\n    },\n    {USB_EP_TYPE_BULK, 0},\n    {USB_EP_TYPE_BULK, 0},\n};\n\nint HF2::stdRequest(UsbEndpointIn &ctrl, USBSetup &setup) {\n#ifdef HF2_HID\n    if (!useHID)\n        return DEVICE_NOT_SUPPORTED;\n    if (setup.bRequest == USB_REQ_GET_DESCRIPTOR) {\n        if (setup.wValueH == 0x21) {\n            InterfaceDescriptor tmp;\n            fillInterfaceInfo(&tmp);\n            return ctrl.write(&tmp, sizeof(tmp));\n        } else if (setup.wValueH == 0x22) {\n            return ctrl.write(hidDescriptor, sizeof(hidDescriptor));\n        }\n    }\n#endif\n    return DEVICE_NOT_SUPPORTED;\n}\n\n#define HF2_FLAG_EVENT 0x01\n\nREAL_TIME_FUNC\nvoid HF2::sendBuffer(uint8_t flag, const void *data, unsigned size, uint32_t prepend) {\n    if (!CodalUSB::usbInstance->isInitialised())\n        return;\n\n#ifdef USB_EP_FLAG_ASYNC\n    // drop non-responses if too much stuff queued up\n    if (flag != HF2_FLAG_CMDPKT_LAST && pendingWriteSize > 1000)\n        return;\n#endif\n\n    if (flag == HF2_FLAG_EVENT)\n        flag = HF2_FLAG_CMDPKT_LAST;\n\n    if (prepend + 1)\n        size += 4;\n\n#ifdef USB_EP_FLAG_ASYNC\n    HF2_PendingWrite *e = (HF2_PendingWrite *)malloc(sizeof(HF2_PendingWrite) + size);\n    e->size = size;\n    e->flag = flag;\n    e->next = NULL;\n    uint8_t *dst = e->data;\n    if (prepend + 1) {\n        memcpy(dst, &prepend, 4);\n        dst += 4;\n        size -= 4;\n    }\n    memcpy(dst, data, size);\n\n    target_disable_irq();\n    auto p = this->pendingWrite;\n    if (!p)\n        this->pendingWrite = e;\n    else {\n        while (p->next)\n            p = p->next;\n        p->next = e;\n    }\n    this->pendingWriteSize += 16 + e->size;\n    target_enable_irq();\n\n    pokeSend();\n#else\n    uint32_t buf[64 / 4]; // aligned\n\n    target_disable_irq();\n    while (size > 0) {\n        memset(buf + 1, 0, 60);\n        int s = 63;\n        if (size <= 63) {\n            s = size;\n            buf[0] = flag;\n        } else {\n            buf[0] = flag == HF2_FLAG_CMDPKT_LAST ? HF2_FLAG_CMDPKT_BODY : flag;\n        }\n        buf[0] |= s;\n        uint8_t *dst = (uint8_t *)buf;\n        dst++;\n        if (prepend + 1) {\n            memcpy(dst, &prepend, 4);\n            prepend = -1;\n            dst += 4;\n            s -= 4;\n            size -= 4;\n        }\n        memcpy(dst, data, s);\n        data = (const uint8_t *)data + s;\n        size -= s;\n\n        in->write(buf, sizeof(buf));\n    }\n    target_enable_irq();\n#endif\n}\n\nconst InterfaceInfo *HF2::getInterfaceInfo() {\n#ifdef HF2_HID\n    if (useHID)\n        return &ifaceInfoHID;\n#endif\n    return &ifaceInfoEP;\n}\n\nint HF2::sendEvent(uint32_t evId, const void *data, int size) {\n    sendBuffer(HF2_FLAG_EVENT, data, size, evId);\n    return 0;\n}\n\nint HF2::sendSerial(const void *data, int size, int isError) {\n    if (!gotSomePacket)\n        return DEVICE_OK;\n\n    sendBuffer(isError ? HF2_FLAG_SERIAL_ERR : HF2_FLAG_SERIAL_OUT, data, size);\n\n    return 0;\n}\n\n// Receive HF2 message\n// Does not block. Will store intermediate data in pkt.\n// `serial` flag is cleared if we got a command message.\nint HF2::recv() {\n    uint8_t buf[64];\n\n    int len = out->read(buf, sizeof(buf));\n    // DMESG(\"HF2 read: %d\", len);\n\n    if (len <= 0)\n        return len;\n\n    uint8_t tag = buf[0];\n    // serial packets not allowed when in middle of command packet\n    usb_assert(pkt.size == 0 || !(tag & HF2_FLAG_SERIAL_OUT));\n    int size = tag & HF2_SIZE_MASK;\n    usb_assert(pkt.size + size <= (int)sizeof(pkt.buf));\n    memcpy(pkt.buf + pkt.size, buf + 1, size);\n    pkt.size += size;\n    tag &= HF2_FLAG_MASK;\n    if (tag != HF2_FLAG_CMDPKT_BODY) {\n        if (tag == HF2_FLAG_CMDPKT_LAST)\n            pkt.serial = 0;\n        else if (tag == HF2_FLAG_SERIAL_OUT)\n            pkt.serial = 1;\n        else\n            pkt.serial = 2;\n        int sz = pkt.size;\n        pkt.size = 0;\n        return sz;\n    }\n    return 0;\n}\n\nint HF2::sendResponse(int size) {\n    sendBuffer(HF2_FLAG_CMDPKT_LAST, pkt.buf, 4 + size);\n    return 0;\n}\n\nint HF2::sendResponseWithData(const void *data, int size) {\n    if (size <= (int)sizeof(pkt.buf) - 4) {\n        memcpy(pkt.resp.data8, data, size);\n        return sendResponse(size);\n    } else {\n        sendBuffer(HF2_FLAG_CMDPKT_LAST, data, size, pkt.resp.eventId);\n        return 0;\n    }\n}\n\nstatic void copy_words(void *dst0, const void *src0, uint32_t n_words) {\n    uint32_t *dst = (uint32_t *)dst0;\n    const uint32_t *src = (const uint32_t *)src0;\n    while (n_words--)\n        *dst++ = *src++;\n}\n\n#ifndef QUICK_BOOT\n#ifdef SAMD21\n#define DBL_TAP_PTR ((volatile uint32_t *)(HMCRAMC0_ADDR + HMCRAMC0_SIZE - 4))\n#endif\n#ifdef SAMD51\n#define DBL_TAP_PTR ((volatile uint32_t *)(HSRAM_ADDR + HSRAM_SIZE - 4))\n#endif\n#if defined(NRF52840) || defined(NRF52833)\n#define DBL_TAP_PTR ((volatile uint32_t *)0x20007F7C)\n#endif\n#ifdef DBL_TAP_PTR\n#define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef\n#define QUICK_BOOT(v) *DBL_TAP_PTR = v ? DBL_TAP_MAGIC_QUICK_BOOT : 0\n#endif\n#endif\n\nstatic HF2 *jdLogger;\nstatic void jdLog(const uint8_t *frame) {\n    jdLogger->sendEvent(HF2_EV_JDS_PACKET, frame, frame[2] + 12);\n}\n\nvoid HF2::pokeSend() {\n#ifdef USB_EP_FLAG_ASYNC\n    target_disable_irq();\n    while (pendingWrite && in->canWrite()) {\n        in->flags |= USB_EP_FLAG_ASYNC;\n\n        int size = pendingWrite->size - pendingWritePtr;\n        usb_assert(size > 0);\n        uint32_t buf[64 / 4] = {0};\n\n        int s = 63;\n        if (size <= 63) {\n            s = size;\n            buf[0] = pendingWrite->flag;\n        } else {\n            buf[0] = pendingWrite->flag == HF2_FLAG_CMDPKT_LAST ? HF2_FLAG_CMDPKT_BODY\n                                                                : pendingWrite->flag;\n        }\n        buf[0] |= s;\n        uint8_t *dst = (uint8_t *)buf;\n        dst++;\n        memcpy(dst, pendingWrite->data + pendingWritePtr, s);\n\n        int r = in->write(buf, sizeof(buf));\n        if (r == 0) {\n            if (s == size) {\n                pendingWritePtr = 0;\n                pendingWriteSize -= 16 + pendingWrite->size;\n                HF2_PendingWrite *n = pendingWrite->next;\n                free(pendingWrite);\n                pendingWrite = n;\n            } else {\n                pendingWritePtr += s;\n            }\n        }\n    }\n    target_enable_irq();\n#endif\n}\n\nint HF2::endpointRequest() {\n#ifdef USB_EP_FLAG_ASYNC\n    pokeSend();\n#endif\n\n    int sz = recv();\n\n    if (!sz)\n        return 0;\n\n    uint32_t tmp;\n\n    if (pkt.serial) {\n        // TODO raise some event?\n        return 0;\n    }\n\n    LOG(\"HF2 sz=%d CMD=%x\", sz, pkt.buf32[0]);\n\n    // one has to be careful dealing with these, as they share memory\n    HF2_Command *cmd = &pkt.cmd;\n    HF2_Response *resp = &pkt.resp;\n\n    uint32_t cmdId = cmd->command_id;\n    resp->tag = cmd->tag;\n    resp->status16 = HF2_STATUS_OK;\n\n#define checkDataSize(str, add) usb_assert(sz == 8 + (int)sizeof(cmd->str) + (int)(add))\n\n    lastExchange = current_time_ms();\n    gotSomePacket = true;\n\n    switch (cmdId) {\n    case HF2_CMD_INFO:\n        return sendResponseWithData(uf2_info(), strlen(uf2_info()));\n\n    case HF2_CMD_BININFO:\n        resp->bininfo.mode = HF2_MODE_USERSPACE;\n        resp->bininfo.flash_page_size = 0;\n        resp->bininfo.flash_num_pages = 0;\n        resp->bininfo.max_message_size = sizeof(pkt.buf);\n        resp->bininfo.uf2_family = PXT_UF2_FAMILY;\n        return sendResponse(sizeof(resp->bininfo));\n\n    case HF2_DBG_RESTART:\n        *HF2_DBG_MAGIC_PTR = HF2_DBG_MAGIC_START;\n        target_reset();\n        break;\n\n#ifdef QUICK_BOOT\n    case HF2_CMD_RESET_INTO_APP:\n        QUICK_BOOT(1);\n        NVIC_SystemReset();\n        break;\n    case HF2_CMD_RESET_INTO_BOOTLOADER:\n        QUICK_BOOT(0);\n        NVIC_SystemReset();\n        break;\n#else\n    case HF2_CMD_RESET_INTO_APP:\n        NVIC_SystemReset();\n        break;\n    // reset into bootloader not supported\n#endif\n\n#if USB_HANDOVER\n    case HF2_CMD_START_FLASH:\n        sendResponse(0);\n        hf2_handover(in->ep);\n        usb_assert(0); // should not be reached\n        break;\n#endif\n\n    case HF2_CMD_WRITE_WORDS:\n        checkDataSize(write_words, cmd->write_words.num_words << 2);\n        copy_words((void *)cmd->write_words.target_addr, cmd->write_words.words,\n                   cmd->write_words.num_words);\n        break;\n\n    case HF2_CMD_READ_WORDS:\n        checkDataSize(read_words, 0);\n        tmp = cmd->read_words.num_words;\n        usb_assert(tmp <= sizeof(pkt.buf) / 4 - 1);\n        copy_words(resp->data32, (void *)cmd->read_words.target_addr, tmp);\n        return sendResponse(tmp << 2);\n\n    case HF2_CMD_DMESG:\n#if DEVICE_DMESG_BUFFER_SIZE > 0\n        return sendResponseWithData(codalLogStore.buffer, codalLogStore.ptr);\n#else\n        break;\n#endif\n\n    case HF2_DBG_GET_GLOBAL_STATE: {\n        HF2_GLOBAL_STATE_Result gstate = {\n            .num_globals = (uint32_t)getNumGlobals(), //\n            .globals_addr = (uint32_t)globals,\n        };\n        return sendResponseWithData(&gstate, sizeof(gstate));\n    }\n\n    case HF2_DBG_RESUME:\n        globals[0] = (TValue)cmd->data32[0];\n        resume = true;\n        return sendResponse(0);\n\n    case HF2_DBG_GET_STACK:\n        return sendResponseWithData(stackCopy, stackSize);\n\n    case HF2_CMD_JDS_CONFIG:\n        if (cmd->data8[0]) {\n            jdLogger = this;\n            pxt::logJDFrame = jdLog;\n        } else {\n            pxt::logJDFrame = NULL;\n        }\n        return sendResponse(0);\n\n    case HF2_CMD_JDS_SEND:\n        if (pxt::sendJDFrame) {\n            pxt::sendJDFrame(cmd->data8);\n            return sendResponse(0);\n        } else {\n            resp->status16 = HF2_STATUS_INVALID_STATE;\n            return sendResponse(0);\n        }\n\n    default:\n        // command not understood\n        resp->status16 = HF2_STATUS_INVALID_CMD;\n        break;\n    }\n\n    return sendResponse(0);\n}\n\nHF2::HF2(HF2_Buffer &p) : gotSomePacket(false), ctrlWaiting(false), pkt(p), useHID(false) {\n    lastExchange = 0;\n#ifdef USB_EP_FLAG_ASYNC\n    pendingWrite = NULL;\n    pendingWriteSize = 0;\n    pendingWritePtr = 0;\n#endif\n}\n\nstatic const InterfaceInfo dummyIfaceInfo = {\n    NULL,\n    0,\n    0,\n    {\n        0,    // numEndpoints\n        0xff, /// class code - vendor-specific\n        0xff, // subclass\n        0xff, // protocol\n        0x00, // string\n        0x00, // alt\n    },\n    {0, 0},\n    {0, 0},\n};\n\nconst InterfaceInfo *DummyIface::getInterfaceInfo() {\n    return &dummyIfaceInfo;\n}\n\n//\n//\n// Debugger\n//\n//\n\nstruct ExceptionContext {\n    uint32_t excReturn; // 0xFFFFFFF9\n    uint32_t r0;\n    uint32_t r1;\n    uint32_t r2;\n    uint32_t r3;\n    uint32_t r12;\n    uint32_t lr;\n    uint32_t faultInstrAddr;\n    uint32_t psr;\n};\n\nstruct Paused_Data {\n    uint32_t pc;\n};\nstatic Paused_Data pausedData;\n\nvoid bkptPaused() {\n\n// waiting for https://github.com/lancaster-university/codal/pull/14\n#ifdef DEVICE_GROUP_ID_USER\n    // the loop below counts as \"system\" task, and we don't want to pause ourselves\n    fiber_set_group(DEVICE_GROUP_ID_SYSTEM);\n    // pause everyone else\n    fiber_pause_group(DEVICE_GROUP_ID_USER);\n#endif\n\n    while (!resume) {\n        // DMESG(\"BKPT\");\n        hf2.pkt.resp.eventId = HF2_EV_DBG_PAUSED;\n        hf2.sendResponseWithData(&pausedData, sizeof(pausedData));\n        // TODO use an event\n        for (int i = 0; i < 20; ++i) {\n            if (resume)\n                break;\n            fiber_sleep(50);\n        }\n    }\n\n    if (stackCopy) {\n        xfree(stackCopy);\n        stackCopy = NULL;\n    }\n\n#ifdef DEVICE_GROUP_ID_USER\n    fiber_resume_group(DEVICE_GROUP_ID_USER);\n    // go back to user mode\n    fiber_set_group(DEVICE_GROUP_ID_USER);\n#endif\n\n    resume = false;\n}\n\nextern \"C\" void handleHardFault(ExceptionContext *ectx) {\n    auto instr = (uint16_t *)ectx->faultInstrAddr;\n\n    DMESG(\"FLT %p\", instr);\n\n    if (ectx->faultInstrAddr & 0x80000000) {\n        ectx->faultInstrAddr &= ~0x80000000;\n        // switch to step-over mode\n        globals[0] = (TValue)3;\n        return;\n    }\n\n    DMESG(\"BB %p %p %p lr=%p r0=%p\", instr[-1], instr[0], instr[1], ectx->lr, ectx->r0);\n\n    if (instr[0] == 0x6840) {\n        // ldr r0, [r0, #4] -- entry breakpoint\n        ectx->faultInstrAddr += 2;\n        // we're being ask for step-over mode\n        if (ectx->r0 == 3) {\n            // switch to debugger-attached-no-stepping mode\n            globals[0] = (TValue)0;\n            ectx->lr |= 0x80000000;\n        }\n        return;\n    }\n\n    if (instr[0] == 0x6800) {\n        // ldr r0, [r0, #0]\n        ectx->lr = ectx->faultInstrAddr + 3; // next instruction + thumb mode\n        pausedData.pc = ectx->faultInstrAddr + 2;\n        void *ssp = (void *)(ectx + 1);\n        stackSize = DEVICE_STACK_BASE - (uint32_t)ssp;\n        if (stackCopy)\n            xfree(stackCopy);\n        stackCopy = xmalloc(stackSize);\n        memcpy(stackCopy, ssp, stackSize);\n        ectx->faultInstrAddr = ((uint32_t)(&bkptPaused) & (~1U));\n        return;\n    }\n\n    while (1) {\n    }\n}\n\nextern \"C\" void HardFault_Handler(void) {\n    asm(\"push {lr}; mov r0, sp; bl handleHardFault; pop {pc}\");\n}\n\n#endif","hf2.h":"#ifndef DEVICE_HF2_H\n#define DEVICE_HF2_H\n\n#if CONFIG_ENABLED(DEVICE_USB)\n\n#include \"HID.h\"\n#include \"uf2hid.h\"\n\n// 260 bytes needed for biggest JD packets (with overheads)\n#define HF2_BUF_SIZE 260\n\ntypedef struct {\n    uint16_t size;\n    uint8_t serial;\n    union {\n        uint8_t buf[HF2_BUF_SIZE];\n        uint32_t buf32[HF2_BUF_SIZE / 4];\n        uint16_t buf16[HF2_BUF_SIZE / 2];\n        HF2_Command cmd;\n        HF2_Response resp;\n    };\n} HF2_Buffer;\n\nstruct HF2_PendingWrite {\n    HF2_PendingWrite *next;\n    uint16_t size;\n    uint8_t flag;\n    uint8_t _reserved;\n    uint8_t data[0];\n};\n\nclass HF2 : public CodalUSBInterface {\n    bool gotSomePacket;\n    bool ctrlWaiting;\n    uint32_t lastExchange;\n\n#ifdef USB_EP_FLAG_ASYNC\n    HF2_PendingWrite *pendingWrite;\n    int pendingWriteSize;\n    int pendingWritePtr;\n#endif\n\n  public:\n    HF2_Buffer &pkt;\n\n    bool useHID;\n\n    int sendResponse(int size);\n    int recv();\n    int sendResponseWithData(const void *data, int size);\n    int sendEvent(uint32_t evId, const void *data, int size);\n    void sendBuffer(uint8_t flag, const void *data, unsigned size, uint32_t prepend = -1);\n    void pokeSend();\n\n    HF2(HF2_Buffer &pkt);\n    virtual int endpointRequest();\n    virtual int stdRequest(UsbEndpointIn &ctrl, USBSetup &setup);\n    virtual const InterfaceInfo *getInterfaceInfo();\n    int sendSerial(const void *data, int size, int isError = 0);\n\n    virtual bool enableWebUSB() { return !useHID; }\n};\n\nclass DummyIface : public CodalUSBInterface {\n  public:\n    virtual const InterfaceInfo *getInterfaceInfo();\n};\n\n#endif\n\n#endif\n","hf2dbg.h":"#ifndef HF2DBG_H\n#define HF2DBG_H 1\n\n// we use a location at the top of the stack to store a magic value\n// which causes us to stop at the very first break point in the program\n#define HF2_DBG_MAGIC_PTR ((uint32_t *)(DEVICE_STACK_BASE - (DEVICE_STACK_SIZE - 4)))\n#define HF2_DBG_MAGIC_START 0xf0ebac7f\n\n#define HF2_DBG_GET_GLOBAL_STATE 0x53fc66e0\nstruct HF2_GLOBAL_STATE_Result {\n    uint32_t num_globals;\n    uint32_t globals_addr;\n};\n\n#define HF2_DBG_RESTART 0x1120bd93\n#define HF2_DBG_RESUME 0x27a55931\n#define HF2_EV_DBG_PAUSED 0x3692f9fd\n#define HF2_DBG_GET_STACK 0x70901510\n\n#endif\n","i2c.cpp":"#include \"pxt.h\"\n#include \"ErrorNo.h\"\n#include \"CodalDmesg.h\"\n#include \"configkeys.h\"\n\n#ifdef CODAL_I2C\n\nnamespace pins {\n\nclass CodalI2CProxy {\nprivate:\n  DevicePin* sda;\n  DevicePin* scl;\n  CODAL_I2C i2c;\npublic:\n  CodalI2CProxy* next;\npublic:\n  CodalI2CProxy(DevicePin* _sda, DevicePin* _scl)\n    : sda(_sda)\n    , scl(_scl)\n    , i2c(*_sda, *_scl) \n    , next(NULL)\n  {\n\n  }\n\n  CODAL_I2C* getI2C() {\n    return &(this->i2c);\n  }\n  \n  bool matchPins(DevicePin* sda, DevicePin* scl) {\n      return this->sda == sda && this->scl == scl;\n  }\n\n  Buffer readBuffer(int address, int size, bool repeat = false)\n  {\n    Buffer buf = mkBuffer(NULL, size);\n    registerGCObj(buf);\n    int status = this->i2c.read(address << 1, buf->data, size, repeat);\n    unregisterGCObj(buf);\n    if (status != ErrorCode::DEVICE_OK) {\n      buf = 0;\n    }\n    return buf;\n  }\n\n  int writeBuffer(int address, Buffer buf, bool repeat = false)\n  {\n    return this->i2c.write(address << 1, buf->data, buf->length, repeat);\n  }\n};\n\n}\n\nnamespace I2CMethods {\n/**\n  * Read `size` bytes from a 7-bit I2C `address`.\n  */\n//%\nBuffer readBuffer(I2C_ i2c, int address, int size, bool repeat = false)\n{\n  return i2c->readBuffer(address, size, repeat);\n}\n\n/**\n  * Write bytes to a 7-bit I2C `address`.\n  */\n//%\nint writeBuffer(I2C_ i2c, int address, Buffer buf, bool repeat = false)\n{\n  return i2c->writeBuffer(address, buf, repeat);\n}\n\n}\n\nnamespace pins {\n\nstatic I2C_ i2cs(NULL);\n/**\n* Opens a Serial communication driver\n*/\n//% help=pins/create-i2c\n//% parts=i2c\nI2C_ createI2C(DigitalInOutPin sda, DigitalInOutPin scl) {\n  // pick up defaults\n  if (!sda || !scl) {\n    DMESG(\"i2c: lookup default pins\");\n    sda = LOOKUP_PIN(SDA);\n    scl = LOOKUP_PIN(SCL);\n  }\n\n  // lookup existing devices\n  auto dev = i2cs;\n  while(dev) {\n    if (dev->matchPins(sda, scl)) {\n      DMESG(\"i2c: found existing i2c\");\n      return dev;\n    }\n    dev = dev->next;\n  }\n\n  // allocate new one\n  DMESG(\"i2c: mounting on new device\");\n  auto ser = new CodalI2CProxy(sda, scl);\n  // push in list\n  ser->next = i2cs;\n  i2cs = ser;\n  return ser;\n}\n\n}\n\nnamespace pxt {\n  CODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl) {\n    auto i2c = pins::createI2C(sda, scl);\n    return i2c->getI2C();\n  }\n}\n\n#endif","i2c.ts":"namespace pins {\n    /**\n     * Read one number from an I2C address.\n     */\n    //% help=pins/i2c-read-number weight=5 group=\"i2c\" inlineInputMode=\"external\"\n    //% blockId=pins_i2c_readnumber block=\"i2c read number at address %address|of format %format|repeated %repeated\"\n    export function i2cReadNumber(address: number, format: NumberFormat, repeated?: boolean): number {\n        const buf = pins.i2cReadBuffer(address, pins.sizeOf(format), repeated)\n        if (!buf)\n            return undefined\n        return buf.getNumber(format, 0)\n    }\n\n    /**\n     * Write one number to an I2C address.\n     */\n    //% help=pins/i2c-write-number weight=4 group=\"i2c\"\n    //% blockId=i2c_writenumber block=\"i2c write number|at address %address|with value %value|of format %format|repeated %repeated\"\n    export function i2cWriteNumber(address: number, value: number, format?: NumberFormat, repeated?: boolean): void {\n        if (format == undefined)\n            format = NumberFormat.UInt8LE;\n        const buf = control.createBuffer(pins.sizeOf(format))\n        buf.setNumber(format, 0, value)\n        pins.i2cWriteBuffer(address, buf, repeated)\n    }\n\n    /**\n     * Write a value in a I2C register.\n     * @param address I2c address of the device\n     * @param register register index\n     * @param value value to write\n     * @param valueFormat format of the value, default is UInt8LE\n     */\n    //% weight=3 group=\"i2c\"\n    //% help=pins/i2c-write-register\n    //% blockId=i2c_writereg block=\"i2c write register|at address $address|at register $register|value $value\"\n    export function i2cWriteRegister(address: number, register: number, value: number, valueFormat?: NumberFormat): void {\n        if (valueFormat === undefined)\n            valueFormat = NumberFormat.UInt8LE;\n        const valueSize = pins.sizeOf(valueFormat);\n        const buf = control.createBuffer(1 + valueSize);\n        buf.setNumber(NumberFormat.UInt8LE, 0, register);\n        buf.setNumber(valueFormat, 1, value);\n        pins.i2cWriteBuffer(address, buf);\n    }\n\n    /**\n     * Read the value from a I2C register.\n     * @param address I2c address of the device\n     * @param register register index\n     * @param valueFormat format of the value, default is UInt8LE\n     */\n    //% weight=3 group=\"i2c\"\n    //% help=pins/i2c-read-register\n    //% blockId=i2c_readreg block=\"i2c read register|at address $address|at register $register\"\n    export function i2cReadRegister(address: number, register: number, valueFormat?: NumberFormat): number {\n        if (valueFormat === undefined)\n            valueFormat = NumberFormat.UInt8LE;\n        pins.i2cWriteNumber(address, register, NumberFormat.UInt8LE);\n        return pins.i2cReadNumber(address, valueFormat);\n    }\n\n    /**\n     * Read `size` bytes from a 7-bit I2C `address`.\n     */\n    //%\n    export function i2cReadBuffer(address: number, size: number, repeat: boolean = false): Buffer {\n        return pins.i2c().readBuffer(address, size, repeat);\n    }\n\n    /**\n     * Write bytes to a 7-bit I2C `address`.\n     */\n    //%\n    export function i2cWriteBuffer(address: number, buf: Buffer, repeat: boolean = false): number {\n        return pins.i2c().writeBuffer(address, buf, repeat);\n    }\n\n    let _i2c: I2C;\n    /**\n     * Gets the default I2C bus\n     */\n    //%\n    export function i2c(): I2C {\n        if (!_i2c) {\n            const sda = pins.pinByCfg(DAL.CFG_PIN_SDA);\n            const scl = pins.pinByCfg(DAL.CFG_PIN_SCL);\n            _i2c = pins.createI2C(sda, scl);    \n        }\n        return _i2c;        \n    }\n\n    export class I2CDevice {\n        public address: number;\n        public bus: I2C;\n        private _hasError: boolean;\n        constructor(address: number, bus?: I2C) {\n            this.address = address;\n            this.bus = bus || i2c();\n        }\n        public readInto(buf: Buffer, repeat = false, start = 0, end: number = null) {\n            if (end === null)\n                end = buf.length\n            if (start >= end)\n                return\n            let res = this.bus.readBuffer(this.address, end - start, repeat)\n            if (!res) {\n                this._hasError = true\n                return\n            }\n            buf.write(start, res)\n        }\n        public write(buf: Buffer, repeat = false) {\n            let res = this.bus.writeBuffer(this.address, buf, repeat)\n            if (res) {\n                this._hasError = true\n            }\n        }\n        public begin(): I2CDevice {\n            this._hasError = false;\n            return this;\n        }\n        public end() {\n        }\n        public ok() {\n            return !this._hasError\n        }\n\n        public transfer(command: Buffer, response: Buffer, responseStart?: number, responseEnd?: number) {\n            this.begin();\n            if (command)\n                this.write(command);\n            if (response)\n                this.readInto(response, false, responseStart, responseEnd);\n            this.end();\n        }    \n    }\n}\n","keyvaluestorage.cpp":"#include \"pxt.h\"\n#include \"KeyValueStorage.h\"\n\nnamespace pxt {\n\nclass WKeyValueStorage {\n#ifdef CODAL_NVMCONTROLLER\n    CODAL_NVMCONTROLLER controller;\n#else\n    NVMController controller;\n#endif\n    KeyValueStorage storage;\n  public:\n\n    WKeyValueStorage()\n    : controller()\n    , storage(controller) {\n    }\n\n    bool isSupported() {\n#ifdef CODAL_NVMCONTROLLER\n      return true;\n#else\n      return false;\n#endif\n    }\n\n    int put(String key, Buffer data) {\n#ifdef CODAL_NVMCONTROLLER\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        return storage.put(mkey, data->data, data->length);\n#else\n        return -1;\n#endif\n    }\n\n    Buffer get(String key) {\n#ifdef CODAL_NVMCONTROLLER\n        Buffer buf = NULL;\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        auto entry = storage.get(mkey);\n        if (entry) {\n          buf = mkBuffer(entry->value, sizeof(entry->value));\n          free(entry);\n        }\n        return buf;\n#else\n        return NULL;\n#endif\n    }\n\n    void remove(String key) {\n#ifdef CODAL_NVMCONTROLLER\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        storage.remove(mkey);\n#endif\n    }\n\n    void clear() {\n#ifdef CODAL_NVMCONTROLLER\n        storage.wipe();\n#endif\n    }\n};\nSINGLETON(WKeyValueStorage);\n\n}\n\nnamespace configStorage {\n  /**\n  * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n  * @param key the identifier (max 16 characters)\n  * @param value the data (max 32 characters)\n  */\n  //%\n  void setBuffer(String key, Buffer value) {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->put(key, value);\n  }\n\n  /**\n  * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n  * @param key the identifier (max 16 characters)\n  */\n  //%\n  Buffer getBuffer(String key) {\n    auto kvm = pxt::getWKeyValueStorage();\n    return kvm->get(key);\n  }\n\n  /**\n  * Removes the key from local storage\n  * @param key the identifier (max 16 characters)\n  */\n  //%\n  void removeItem(String key) {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->remove(key);\n  }\n\n  /**\n  * Clears the local storage\n  */\n  //%\n  void clear() {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->clear();\n  }\n}\n","keyvaluestorage.ts":"namespace configStorage {\n    /**\n     * Stores the value at the key entry\n     * @param key identifier of the key (max 16 characters)\n     * @param value identifier of the value (max 32 characters)\n     */\n    export function setItem(key: string, value: string) {\n        if (value == null)\n            configStorage.removeItem(key);\n        else\n        {\n            let idx = 0;\n            let buf = control.createBuffer(value.length + 1);\n            buf[idx++] = value.length;\n            let valBuf = control.createBufferFromUTF8(value);\n\n            for (let i = 0; i < valBuf.length; i++)\n                buf[idx++] = valBuf[i];\n\n            configStorage.setBuffer(key, buf);\n        }\n    }\n\n    /**\n     * Retrieves the value at the key entry\n     * @param key identifier of the key (max 16 characters)\n     */\n    export function getItem(key: string): string {\n        const buf = configStorage.getBuffer(key);\n\n        if (!buf)\n            return undefined;\n\n        let idx = 0;\n        let count = buf[idx++];\n        const retBuf = control.createBuffer(count);\n\n        for (let i = 0; i < count; i++)\n            retBuf[i] = buf[idx++];\n\n        return retBuf.toString();\n    }\n}\n","leveldetector.ts":"namespace pins {\n    export class LevelDetector {\n        public id: number;\n        public min: number;\n        public max: number;\n        public lowThreshold: number;\n        public highThreshold: number;\n        private transition: number;\n        private transitionMs: number;\n        private _level: number;\n        private _state: number;\n        public onHigh: () => void;\n        public onLow: () => void;\n        public onNeutral: () => void;\n        public transitionWindow: number;\n        // minimum duration (ms) between events\n        public transitionInterval: number;\n\n        static LEVEL_THRESHOLD_NEUTRAL = 0;\n\n        constructor(id: number,\n            min: number, max: number,\n            lowThreshold: number, highThreshold: number) {\n            this.id = id;\n            this.min = min;\n            this.max = max;\n            this.lowThreshold = lowThreshold;\n            this.highThreshold = highThreshold;\n            this.transitionWindow = 4;\n            this.transitionInterval = 0;\n\n            this.onHigh = () => control.raiseEvent(this.id, DAL.LEVEL_THRESHOLD_HIGH);\n            this.onLow = () => control.raiseEvent(this.id, DAL.LEVEL_THRESHOLD_LOW);\n            this.onNeutral = undefined;\n\n            this.reset();\n        }\n\n        reset() {\n            this.transition = 0;\n            this.transitionMs = 0;\n            this._level = Math.ceil((this.highThreshold - this.lowThreshold) / 2);\n            this._state = LevelDetector.LEVEL_THRESHOLD_NEUTRAL;\n        }\n\n        get level(): number {\n            return this._level;\n        }\n\n        set level(level: number) {\n            this._level = this.clampValue(level);\n\n            if (this._level >= this.highThreshold) {\n                this.setState(DAL.LEVEL_THRESHOLD_HIGH);\n            }\n            else if (this._level <= this.lowThreshold) {\n                this.setState(DAL.LEVEL_THRESHOLD_LOW);\n            }\n            else {\n                this.setState(LevelDetector.LEVEL_THRESHOLD_NEUTRAL);\n            }\n        }\n\n        public setLowThreshold(value: number) {\n            this.lowThreshold = this.clampValue(value);\n            this.reset();\n        }\n\n        public setHighThreshold(value: number) {\n            this.highThreshold = this.clampValue(value);\n            this.reset();\n        }\n\n        private clampValue(value: number) {\n            if (value < this.min) {\n                return this.min;\n            }\n            else if (value > this.max) {\n                return this.max;\n            }\n            return value;\n        }\n\n        private setState(state: number) {\n            // not enough samples to change\n            if (this._state === state \n                || (this.transition++ < this.transitionWindow)\n                || (control.millis() - this.transitionMs) < this.transitionInterval) {\n                return;\n            }\n\n            this.transition = 0;\n            this.transitionMs = control.millis();\n            this._state = state;\n            switch (state) {\n                case DAL.LEVEL_THRESHOLD_HIGH:\n                    if (this.onHigh) this.onHigh();\n                    break;\n                case DAL.LEVEL_THRESHOLD_LOW:\n                    if (this.onLow) this.onLow();\n                    break;\n                case LevelDetector.LEVEL_THRESHOLD_NEUTRAL:\n                    if (this.onNeutral) this.onNeutral();\n                    break;\n            }\n        }\n    }\n}","light.cpp":"#include \"light.h\"\n\n// WS2812B timings, datasheet v1\n// 0 - 0.25-0.55us hi 0.70-1.00us low\n// 1 - 0.65-0.95us hi 0.30-0.60us low\n// datasheet v5\n// 0 - 0.22-0.38us hi 0.58-1.00us low 1-3\n// 1 - 0.58-1.00us hi 0.58-1.00us low 3-2\n\n#define SPI_SUPPORTED 1\n\n#if defined(NRF52_SERIES)\n#define BIT_EXPANSION 5\n#define SPI_FREQ 4000000\n#else\n#define BIT_EXPANSION 3\n#define SPI_FREQ 2400000\n#endif\n\n#if defined(SAMD21) || defined(SAMD51) || defined(STM32F4) || defined(NRF52_SERIES)\n#include \"neopixel.h\"\n#define BITBANG_SUPPORTED 1\n#else\n#define BITBANG_SUPPORTED 0\n#endif\n\n#define NEOPIXEL_MIN_LENGTH_FOR_SPI 24\n#define DOTSTAR_MIN_LENGTH_FOR_SPI 24\n\n#define LIGHTMODE_RGB 1\n#define LIGHTMODE_RGBW 2\n#define LIGHTMODE_RGB_RGB 3\n#define LIGHTMODE_DOTSTAR 4\n\nnamespace light {\nbool isValidMOSIPin(DigitalInOutPin pin) {\n    if (!pin)\n        return false;\n\n#if SAMD51\n    return ZSPI::isValidMOSIPin(*pin);\n#elif defined(NRF52_SERIES)\n    return true;\n#else\n    // TODO: support for SPI neopixels\n    // default SPI pins supported for now\n    return pin == LOOKUP_PIN(MOSI);\n#endif\n}\n\n// SPI\nvoid spiNeopixelSendBuffer(DevicePin *pin, const uint8_t *data, unsigned size) {\n    int32_t iptr = 0, optr = 120;\n    uint32_t len = optr + size * BIT_EXPANSION + 120;\n    uint8_t *expBuf = new uint8_t[len];\n    memset(expBuf, 0, len);\n    uint8_t imask = 0x80;\n    uint8_t omask = 0x80;\n\n#define WR(k)                                                                                      \\\n    if (k)                                                                                         \\\n        expBuf[optr] |= omask;                                                                     \\\n    omask >>= 1;                                                                                   \\\n    if (!omask) {                                                                                  \\\n        omask = 0x80;                                                                              \\\n        optr++;                                                                                    \\\n    }\n\n    while (iptr < (int)size) {\n#if BIT_EXPANSION == 3\n        WR(1);\n        WR(data[iptr] & imask);\n        WR(0);\n#elif BIT_EXPANSION == 5\n        WR(1);\n        if (data[iptr] & imask) {\n            WR(1);\n            WR(1);\n        } else {\n            WR(0);\n        }\n        WR(0);\n        WR(0);\n#else\n#error \"invalid BIT_EXPANSION\"\n#endif\n\n        imask >>= 1;\n        if (!imask) {\n            imask = 0x80;\n            iptr++;\n        }\n    }\n\n    auto spi = pxt::getSPI(pin, NULL, NULL);\n    spi->setFrequency(SPI_FREQ);\n    spi->transfer(expBuf, len, NULL, 0);\n    delete expBuf;\n}\n\nvoid neopixelSendData(DevicePin *pin, int mode, const uint8_t *data, unsigned length) {\n    if (!pin || !length)\n        return;\n\n#if BITBANG_SUPPORTED\n    if (SPI_SUPPORTED && length > NEOPIXEL_MIN_LENGTH_FOR_SPI && isValidMOSIPin(pin))\n        spiNeopixelSendBuffer(pin, data, length);\n    else\n        neopixel_send_buffer(*pin, data, length);\n#else\n    if (isValidMOSIPin(pin)) {\n        spiNeopixelSendBuffer(pin, data, length);\n    }\n#endif\n}\n\nvoid bitBangDotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                            unsigned length) {\n    // first frame of zeroes\n    data->setDigitalValue(0);\n    for (unsigned i = 0; i < 32; ++i) {\n        clk->setDigitalValue(1);\n        clk->setDigitalValue(0);\n    }\n\n    // data stream\n    for (unsigned i = 0; i < length; ++i) {\n        auto x = buf[i];\n        for (uint8_t j = 0x80; j != 0; j >>= 1) {\n            data->setDigitalValue(x & j ? 1 : 0);\n            clk->setDigitalValue(1);\n            clk->setDigitalValue(0);\n        }\n    }\n    // https://cpldcpu.wordpress.com/2016/12/13/sk9822-a-clone-of-the-apa102/\n    // reset frame\n    // data->setDigitalValue(0);\n    // for (unsigned i = 0; i < 32 ; ++i) {\n    //    clk->setDigitalValue(1);\n    //    clk->setDigitalValue(0);\n    //}\n\n    // https://cpldcpu.wordpress.com/2014/11/30/understanding-the-apa102-superled/\n    data->setDigitalValue(1);\n    unsigned n = 32;\n    for (unsigned i = 0; i < n; ++i) {\n        clk->setDigitalValue(1);\n        clk->setDigitalValue(0);\n    }\n}\n\nstatic uint8_t ZERO_FRAME[4];\nstatic uint8_t ONE_FRAME[] = {1, 1, 1, 1};\nvoid spiDotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                        unsigned length) {\n    auto spi = pxt::getSPI(data, NULL, clk);\n\n    spi->transfer(ZERO_FRAME, sizeof(ZERO_FRAME), NULL, 0); // initial frame\n    spi->transfer(buf, length, NULL, 0);\n    spi->transfer(ZERO_FRAME, sizeof(ZERO_FRAME), NULL, 0); // reset frame\n    for (unsigned i = 0; i < (length >> 3); i += 32)\n        spi->transfer(ONE_FRAME, sizeof(ONE_FRAME), NULL, 0); // final frame\n}\n\nvoid dotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                     unsigned length) {\n    if (!data || !clk || !buf || !length)\n        return;\n\n    if (length > DOTSTAR_MIN_LENGTH_FOR_SPI && isValidMOSIPin(data))\n        spiDotStarSendData(data, clk, mode, buf, length);\n    else\n        bitBangDotStarSendData(data, clk, mode, buf, length);\n}\n\nvoid sendBuffer(DevicePin *data, DevicePin *clk, int mode, Buffer buf) {\n    if (!data || !buf || !buf->length)\n        return;\n\n    if (mode == LIGHTMODE_DOTSTAR)\n        light::dotStarSendData(data, clk, mode, buf->data, buf->length);\n    else\n        light::neopixelSendData(data, mode, buf->data, buf->length);\n}\n\nvoid clear() {\n    auto neopix = LOOKUP_PIN(NEOPIXEL);\n    auto neonum = getConfig(CFG_NUM_NEOPIXELS, 0);\n    if (neopix && neonum >= 0) {\n        auto n = 3 * neonum;\n        uint8_t off[n];\n        memset(off, 0, sizeof(off));\n        light::neopixelSendData(neopix, 0x100, off, sizeof(off));\n    }\n\n    auto data = LOOKUP_PIN(DOTSTAR_DATA);\n    auto clk = LOOKUP_PIN(DOTSTAR_CLOCK);\n    auto dsnum = getConfig(CFG_NUM_DOTSTARS, 0);\n    if (data && clk && dsnum > 0) {\n        auto n = 4 * dsnum;\n        uint8_t off[n];\n        memset(off, 0, sizeof(off));\n        for (int i = 0; i < n; i += 4)\n            off[i] = 0xe0;\n        bitBangDotStarSendData(data, clk, 0x100, off, sizeof(off));\n    }\n}\n\n} // namespace light\n","light.h":"#ifndef __PXT_LIGHT_H\n#define __PXT_LIGHT_H\n\n#include \"pxt.h\"\n\nnamespace light {\n    /**\n    * Clear onboard neopixels\n    */\n    void clear();\n\n    /**\n    * Send a programmable light buffer to the specified digital pin\n    * @param data The pin that the lights are connected to\n    * @param clk the clock line if any\n    * @param mode the color encoding mode\n    * @param buf The buffer to send to the pin\n    */\n    //%\n    void sendBuffer(DigitalInOutPin data, DigitalInOutPin clk, int mode, Buffer buf);\n\n    void neopixelSendData(DevicePin* pin, int mode, const uint8_t* data, unsigned length);\n}\n\n#endif","ns.ts":"/**\n * Events and data from sensors.\n */\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\n//% groups='[\"other\", \"More\"]'\nnamespace input {\n}\n\n/**\n * Servos\n */\n//% color=\"#03AA74\" weight=88 icon=\"\\uf021\"\nnamespace servos {\n\n}\n\n/**\n * A Joint Asynchronous Communications, Device Agnostic Control.\n */\n//% color=\"#E79251\" weight=1 icon=\"\\uf185\"\n//% groups='[\"Broadcast\", \"Console\", \"Control\"]'\n//% blockGap=8\nnamespace jacdac {\n\n}","pins.cpp":"#include \"pxt.h\"\n\nnamespace pxt {\nstatic DevicePin **pinPtrs;\nstatic uint8_t numPinPtrs;\nstatic uint8_t pinPos[DEV_NUM_PINS];\n\n//%\nDevicePin *getPin(int id) {\n\n    id &= CFG_PIN_NAME_MSK;\n\n    if (id >= DEV_NUM_PINS)\n        soft_panic(PANIC_NO_SUCH_PIN);\n\n    // we could use lookupComponent() here - it would be slightly slower\n\n    int ptr = pinPos[id];\n    if (ptr == 0) {\n        pinPtrs = (DevicePin **)realloc(pinPtrs, (numPinPtrs + 1) * sizeof(void *));\n        bool isAnalog = IS_ANALOG_PIN(id);\n        // GCTODO\n        pinPtrs[numPinPtrs++] =\n            new DevicePin(DEVICE_ID_IO_P0 + id, (PinName)id,\n                          isAnalog ? PIN_CAPABILITY_AD : PIN_CAPABILITY_DIGITAL);\n        ptr = numPinPtrs;\n        pinPos[id] = ptr;\n    }\n    return pinPtrs[ptr - 1];\n}\n\n//%\nDevicePin *getPinCfg(int key) {\n    int p = getConfig(key, -1);\n    if (p == -1)\n        DMESG(\"no pin cfg: %d\", key);\n    return getPin(p);\n}\n\nvoid linkPin(int from, int to) {\n    if (from < 0 || from >= DEV_NUM_PINS)\n        soft_panic(PANIC_NO_SUCH_PIN);\n    getPin(to);\n    pinPos[from] = pinPos[to];\n}\n\n//%\nDevicePin *lookupPin(int pinName) {\n    if (pinName < 0 || pinName == 0xff)\n        return NULL;\n    pinName &= CFG_PIN_NAME_MSK;\n    return getPin(pinName);\n}\n\n//%\nDevicePin *lookupPinCfg(int key) {\n    return lookupPin(getConfig(key));\n}\n\nCodalComponent *lookupComponent(int id) {\n    for (int i = 0; i < DEVICE_COMPONENT_COUNT; ++i) {\n        if (CodalComponent::components[i] && CodalComponent::components[i]->id == id)\n            return CodalComponent::components[i];\n    }\n    return NULL;\n}\n\n} // namespace pxt\n\nnamespace pins {\n/**\n* Get a pin by configuration id (DAL.CFG_PIN...)\n*/\n//%\nDigitalInOutPin pinByCfg(int key) {\n    return pxt::lookupPinCfg(key);\n}\n\n/**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n//%\nBuffer createBuffer(int size) {\n    return mkBuffer(NULL, size);\n}\n\n/**\n * Get the duration of the last pulse in microseconds. This function should be called from a\n * ``onPulsed`` handler.\n */\n//% help=pins/pulse-duration blockGap=8\n//% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n//% weight=19\nint pulseDuration() {\n    return pxt::lastEvent.timestamp;\n}\n} // namespace pins\n","pins.h":"#ifndef __PXT_PINS_H\n#define __PXT_PINS_H\n\n#define BUTTON_ACTIVE_HIGH_PULL_DOWN (ACTIVE_HIGH | 0x10)\n#define BUTTON_ACTIVE_HIGH_PULL_UP (ACTIVE_HIGH | 0x20)\n#define BUTTON_ACTIVE_HIGH_PULL_NONE (ACTIVE_HIGH | 0x30)\n#define BUTTON_ACTIVE_LOW_PULL_DOWN (ACTIVE_LOW | 0x10)\n#define BUTTON_ACTIVE_LOW_PULL_UP (ACTIVE_LOW | 0x20)\n#define BUTTON_ACTIVE_LOW_PULL_NONE (ACTIVE_LOW | 0x30)\n\n#define PIN(name) ((PinName)pxt::getConfig(CFG_PIN_##name, -1))\n#define LOOKUP_PIN(name) pxt::lookupPin(PIN(name))\n\n// these can be overridden in platform.h\n#ifndef CODAL_PIN\n#define CODAL_PIN CODAL_MBED::Pin\n#endif\n\n#ifndef CODAL_TIMER\n#define CODAL_TIMER CODAL_MBED::Timer\n#endif\n\n#ifndef CODAL_SPI\n#define CODAL_SPI CODAL_MBED::SPI\n#endif\n\n#ifndef CODAL_SERIAL\n#define CODAL_SERIAL CODAL_MBED::Serial\n#endif\n\n#ifndef IS_ANALOG_PIN\n#define IS_ANALOG_PIN(id) ((DEV_ANALOG_PINS >> (id)) & 1)\n#endif\n\ntypedef CODAL_PIN DevicePin;\n\ntypedef DevicePin *DigitalInOutPin;\ntypedef DevicePin *AnalogInOutPin;\ntypedef DevicePin *AnalogInPin;\ntypedef DevicePin *AnalogOutPin;\ntypedef DevicePin *PwmPin;\ntypedef DevicePin *PwmOnlyPin;\ntypedef Button *Button_;\n\nnamespace pxt {\nDevicePin *getPin(int id);\nDevicePin *getPinCfg(int key);\nDevicePin *lookupPin(int pinName);\nDevicePin *lookupPinCfg(int key);\nvoid linkPin(int from, int to);\nCodalComponent *lookupComponent(int id);\n}\n\n#define PINOP(op) name->op\n\n#endif\n","pins.ts":"//% noRefCounting fixedInstances\ninterface DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogInPin extends DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogOutPin extends DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogInOutPin extends AnalogInPin, AnalogOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface PwmOnlyPin extends DigitalInOutPin, AnalogOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface PwmPin extends PwmOnlyPin, AnalogInOutPin {\n}\n\n/**\n * Control currents in Pins for analog/digital signals, servos, i2c, ...\n */\n//% color=#A80000 weight=85 icon=\"\\uf140\" advanced=true\n//% groups='[\"other\", \"Servo\", \"i2c\"]'\nnamespace pins {\n}","pinsAnalog.cpp":"#include \"pxt.h\"\n\nnamespace AnalogInPinMethods {\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 weight=53\n//% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nint analogRead(AnalogInPin name) {\n    return PINOP(getAnalogValue());\n}\n}\n\nnamespace AnalogOutPinMethods {\nvoid analogWrite(AnalogOutPin name, int value) __attribute__ ((weak));\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 weight=52\n//% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\n//% value.min=0 value.max=1023\nvoid analogWrite(AnalogOutPin name, int value) {\n    PINOP(setAnalogValue(value));\n}\n}","pinsDigital.cpp":"#include \"pxt.h\"\n\nenum class PulseValue {\n    //% block=high\n    High = DEVICE_PIN_EVT_PULSE_HI,\n    //% block=low\n    Low = DEVICE_PIN_EVT_PULSE_LO\n};\n\nenum class PinEvent {\n    //% block=\"pulse high\"\n    PulseHigh = DEVICE_PIN_EVT_PULSE_HI,\n    //% block=\"pulse low\"\n    PulseLow = DEVICE_PIN_EVT_PULSE_LO,\n    //% block=\"rise\"\n    Rise = DEVICE_PIN_EVT_RISE,\n    //% block=\"fall\"\n    Fall = DEVICE_PIN_EVT_FALL,\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\nnamespace DigitalInOutPinMethods {\n/**\n * Read a pin or connector as either 0 or 1\n * @param name pin to read from\n */\n//% help=pins/digital-read weight=61\n//% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nbool digitalRead(DigitalInOutPin name) {\n    return PINOP(getDigitalValue()) != 0;\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\n    */\n//% help=pins/digital-write weight=60\n//% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid digitalWrite(DigitalInOutPin name, bool value) {\n    PINOP(setDigitalValue(value));\n}\n\n/**\n* Make this pin a digital input, and create events where the timestamp is the duration\n* that this pin was either ``high`` or ``low``.\n*/\n//% help=pins/on-pulsed weight=16 blockGap=8\n//% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\n//% deprecated=1 hidden=1\nvoid onPulsed(DigitalInOutPin pin, PulseValue pulse, Action body) {\n    pin->eventOn(DEVICE_PIN_EVENT_ON_PULSE);\n    registerWithDal(pin->id, (int)pulse, body);\n}\n\n/**\n* Register code to run when a pin event occurs. \n*/\n//% help=pins/on-event weight=20 blockGap=8\n//% blockId=pinsonevent block=\"on|pin %pin|%event\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\nvoid onEvent(DigitalInOutPin pin, PinEvent event, Action body) {\n    switch(event) {\n        case PinEvent::PulseHigh:\n        case PinEvent::PulseLow:\n            pin->eventOn(DEVICE_PIN_EVENT_ON_PULSE);\n            registerWithDal(pin->id, (int)event, body);\n            break;\n        case PinEvent::Rise:\n        case PinEvent::Fall:\n            pin->eventOn(DEVICE_PIN_EVENT_ON_EDGE);\n            registerWithDal(pin->id, (int)event, body);\n            break;    \n    }    \n}\n\n/**\n* Return 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 %high||timeout %maxDuration (µs)\"\n//% weight=18 blockGap=8\n//% help=\"pins/pulse-in\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\nint pulseIn(DigitalInOutPin pin, PulseValue value, int maxDuration = 2000000) {\n    int pulse = PulseValue::High == value ? 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* Set the pull direction 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=17 blockGap=8\n//% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid setPull(DigitalInOutPin name, PinPullMode pull) {\n    PullMode m = pull == PinPullMode::PullDown ? PullMode::Down : pull == PinPullMode::PullUp\n                                                                        ? PullMode::Up\n                                                                        : PullMode::None;\n    PINOP(setPull(m));\n}\n\n}\n\n#ifdef PXT_CODAL\n\nnamespace pxt {\n\nstatic void waitABit() {\n    // for (int i = 0; i < 10; ++i)\n    //    asm volatile(\"nop\");\n}\n\nclass ButtonMultiplexer : public CodalComponent {\n  public:\n    Pin &latch;\n    Pin &clock;\n    Pin &data;\n    uint32_t state;\n    uint32_t invMask;\n    uint16_t buttonIdPerBit[8];\n    bool enabled;\n\n    ButtonMultiplexer(uint16_t id)\n        : latch(*LOOKUP_PIN(BTNMX_LATCH)), clock(*LOOKUP_PIN(BTNMX_CLOCK)),\n          data(*LOOKUP_PIN(BTNMX_DATA)) {\n        this->id = id;\n        this->status |= DEVICE_COMPONENT_STATUS_SYSTEM_TICK;\n\n        state = 0;\n        invMask = 0;\n        enabled = true;\n\n        memset(buttonIdPerBit, 0, sizeof(buttonIdPerBit));\n\n        data.getDigitalValue(PullMode::Down);\n        latch.setDigitalValue(1);\n        clock.setDigitalValue(1);\n    }\n\n    void disable() {\n        data.getDigitalValue(PullMode::None);\n        latch.getDigitalValue(PullMode::None);\n        clock.getDigitalValue(PullMode::None);\n        enabled = false;\n    }\n\n    bool isButtonPressed(int id) {\n        for (int i = 0; i < 8; ++i) {\n            if (buttonIdPerBit[i] == id)\n                return (state & (1 << i)) != 0;\n        }\n        return false;\n    }\n\n    uint32_t readBits(int bits) {\n        latch.setDigitalValue(0);\n        waitABit();\n        latch.setDigitalValue(1);\n        waitABit();\n\n        uint32_t state = 0;\n        for (int i = 0; i < bits; i++) {\n            state <<= 1;\n            if (data.getDigitalValue(PullMode::Down))\n                state |= 1;\n\n            clock.setDigitalValue(0);\n            waitABit();\n            clock.setDigitalValue(1);\n            waitABit();\n        }\n\n        return state;\n    }\n\n    virtual void periodicCallback() override {\n        if (!enabled)\n            return;\n\n        uint32_t newState = readBits(8);\n        newState ^= invMask;\n        if (newState == state)\n            return;\n\n        for (int i = 0; i < 8; ++i) {\n            uint32_t mask = 1 << i;\n            if (!buttonIdPerBit[i])\n                continue;\n            int ev = 0;\n            if (!(state & mask) && (newState & mask))\n                ev = PXT_INTERNAL_KEY_DOWN;\n            else if ((state & mask) && !(newState & mask))\n                ev = PXT_INTERNAL_KEY_UP;\n            if (ev) {\n                Event(ev, buttonIdPerBit[i]);\n                Event(ev, 0); // any key\n            }\n        }\n\n        state = newState;\n    }\n};\n\nstatic ButtonMultiplexer *btnMultiplexer;\nButtonMultiplexer *getMultiplexer() {\n    if (!btnMultiplexer)\n        btnMultiplexer = new ButtonMultiplexer(DEVICE_ID_FIRST_BUTTON);\n    return btnMultiplexer;\n}\n\nint registerMultiplexedButton(int pin, int buttonId) {\n    if (1050 <= pin && pin < 1058) {\n        pin -= 50;\n        getMultiplexer()->invMask |= 1 << (pin - 1000);\n    }\n    if (1000 <= pin && pin < 1008) {\n        getMultiplexer()->buttonIdPerBit[pin - 1000] = buttonId;\n        return 1;\n    }\n    return 0;\n}\n\nint multiplexedButtonIsPressed(int btnId) {\n    if (btnMultiplexer)\n        return btnMultiplexer->isButtonPressed(btnId) ? 512 : 0;\n    return 0;\n}\n\n//% expose\nuint32_t readButtonMultiplexer(int bits) {\n    if (!LOOKUP_PIN(BTNMX_CLOCK))\n        return 0;\n    return getMultiplexer()->readBits(bits);\n}\n\nvoid disableButtonMultiplexer() {\n    if (LOOKUP_PIN(BTNMX_CLOCK)) {\n        getMultiplexer()->disable();\n    }\n}\n\n}\n\n#endif\n","pinsPWM.cpp":"#include \"pxt.h\"\n\nnamespace PwmPinMethods {\n}\n\nnamespace PwmOnlyPinMethods {\n\n/**\n * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n * **microseconds** or `1/1000` milliseconds.\n * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n * 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=51\n//% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid analogSetPeriod(PwmOnlyPin name, int period) {\n    PINOP(setAnalogPeriodUs(period));\n}\n\n/**\n * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n * 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\n */\n//% help=pins/servo-write weight=41 group=\"Servo\"\n//% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n//% parts=microservo trackArgs=0\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\n//% value.defl=90\nvoid servoWrite(PwmOnlyPin name, int value) {\n    PINOP(setServoValue(value));\n}\n\n/**\n * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n * @param name pin name\n * @param duration pulse duration in micro seconds, eg:1500\n */\n//% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n//% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n//% parts=microservo blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid servoSetPulse(PwmOnlyPin name, int duration) {\n    PINOP(setServoPulseUs(duration));\n}\n\n/**\n* Indicates if the servo is running continuously\n*/\n//% blockHidden=1\nvoid servoSetContinuous(PwmOnlyPin name, bool continuous) {\n    // used by simulator\n}\n\n}","pinscompat.ts":"// filled in by microbit","platform.cpp":"#include \"pxt.h\"\n\n#include \"SAMDTCTimer.h\"\n#include \"SAMDTCCTimer.h\"\n#include \"light.h\"\n\nnamespace pxt {\n\nstruct TimerConfig {\n    uint8_t id;\n    uint8_t irq;\n    uint8_t dmaovf;\n    uint32_t addr;\n};\n\n#define DEF_TC(n)                                                                                  \\\n    { 0x10 + n, TC##n##_IRQn, TC##n##_DMAC_ID_OVF, (uint32_t)TC##n }\n#ifdef SAMD21\n#define DEF_TCC(n)                                                                                 \\\n    { 0x20 + n, TCC##n##_IRQn, TCC##n##_DMAC_ID_OVF, (uint32_t)TCC##n }\n#else\n#define DEF_TCC(n)                                                                                 \\\n    { 0x20 + n, TCC##n##_0_IRQn, TCC##n##_DMAC_ID_OVF, (uint32_t)TCC##n }\n#endif\n\nstatic const TimerConfig timers[] = {\n#ifdef TC0\n    DEF_TC(0),\n#endif\n#ifdef TC1\n    DEF_TC(1),\n#endif\n#ifdef TC2\n    DEF_TC(2),\n#endif\n#ifdef TC3\n    DEF_TC(3),\n#endif\n#ifdef TC4\n    DEF_TC(4),\n#endif\n#ifdef TC5\n    DEF_TC(5),\n#endif\n\n#ifdef TCC0\n    DEF_TCC(0),\n#endif\n#ifdef TCC1\n    DEF_TCC(1),\n#endif\n#ifdef TCC2\n    DEF_TCC(2),\n#endif\n\n    {0, 0, 0, 0}};\n\n// Backlight:\n// Kitronik: PA6 TC1 (ch 0)\n// Adafruit: PA1 TC2 (ch 1)\n\n// TC3 is used by DAC on both D21 and D51\n// TCC0 and TC4 is used by IR\n// TCC0, TCC1, TC4 is used by PWM on CPX\n\n#ifdef SAMD21\n#define DEF_TIMERS 0x15222021 // TC5 TCC2 TCC0 TCC1\n#else\n#define DEF_TIMERS 0x10111200 // TC0 TC1 TC2\n#endif\n\nstatic uint32_t usedTimers;\nstatic int timerIdx(uint8_t id) {\n    for (unsigned i = 0; timers[i].id; i++) {\n        if (id == timers[i].id)\n            return i;\n    }\n    return -1;\n}\nLowLevelTimer *allocateTimer() {\n    uint32_t timersToUse = getConfig(CFG_TIMERS_TO_USE, DEF_TIMERS);\n    uint8_t blTC = 0;\n    // DAC hard-wired to TC3 right now\n    uint8_t dacTC = 0x13;\n\n    // if BL is on a known pin, don't use its PWM TC\n    // this is a hack for legacy boards that don't have CFG_TIMERS_TO_USE\n    auto blPin = PIN(DISPLAY_BL);\n    if (blPin == PA01)\n        blTC = 0x12;\n\n    for (int shift = 24; shift >= 0; shift -= 8) {\n        uint8_t tcId = (timersToUse >> shift) & 0xff;\n        if (tcId == 0 || tcId == blTC || tcId == dacTC)\n            continue;\n        int idx = timerIdx(tcId);\n        if (idx < 0 || (usedTimers & (1 << idx)))\n            continue;\n        LowLevelTimer *res;\n        if (idx < 0x20) {\n            Tc *tc = (Tc *)timers[idx].addr;\n            if (tc->COUNT16.CTRLA.bit.ENABLE)\n                continue;\n            DMESG(\"allocate TC%d\", tcId & 0xf);\n            res = new SAMDTCTimer(tc, timers[idx].irq);\n        } else {\n            Tcc *tcc = (Tcc *)timers[idx].addr;\n            if (tcc->CTRLA.bit.ENABLE)\n                continue;\n            DMESG(\"allocate TCC%d\", tcId & 0xf);\n            res = new SAMDTCCTimer(tcc, timers[idx].irq);\n        }\n        usedTimers |= 1 << idx;\n        return res;\n    }\n\n    soft_panic(PANIC_OUT_OF_TIMERS);\n    return NULL;\n}\n\nstatic void initRandomSeed() {\n    int seed = 0xC0DA1;\n    // TODO use TRNG\n    seedRandom(seed);\n}\n\nvoid platformSendSerial(const char *data, int len) {}\n\n#ifdef SAMD21\nstatic void remapSwdPin(int pinCfg, int fallback) {\n    int pinName = getConfig(pinCfg);\n    if (pinName == PA30 || pinName == PA31) {\n        if (getConfig(CFG_SWD_ENABLED, 0)) {\n            linkPin(pinName, fallback);\n        } else {\n            PORT->Group[pinName / 32].PINCFG[pinName % 32].reg = (uint8_t)PORT_PINCFG_INEN;\n        }\n    }\n}\n\nstatic void initSwdPins() {\n    remapSwdPin(CFG_PIN_NEOPIXEL, PIN(D0));\n    remapSwdPin(CFG_PIN_RXLED, PIN(D1));\n    remapSwdPin(CFG_PIN_SPEAKER_AMP, PIN(A2));\n}\n#else\nstatic void initSwdPins() {}\n#endif\n\nvoid platform_init() {\n    initSwdPins();\n    initRandomSeed();\n    setSendToUART(platformSendSerial);\n    light::clear();\n\n    /*\n        if (*HF2_DBG_MAGIC_PTR == HF2_DBG_MAGIC_START) {\n            *HF2_DBG_MAGIC_PTR = 0;\n            // this will cause alignment fault at the first breakpoint\n            globals[0] = (TValue)1;\n        }\n    */\n}\n\nint *getBootloaderConfigData() {\n#ifdef SAMD51\n    auto config_data = *(uint32_t *)(BOOTLOADER_END - 4 * 4);\n    if (config_data && (config_data & 3) == 0 && config_data < BOOTLOADER_END) {\n        auto p = (uint32_t *)config_data;\n        if (p[0] == CFG_MAGIC0 && p[1] == CFG_MAGIC1)\n            return (int *)p + 4;\n    }\n#endif\n    return NULL;\n}\n\n} // namespace pxt\n\nvoid cpu_clock_init() {}\n","platform.h":"#ifndef __PXT_PLATFORM_H\n#define __PXT_PLATFORM_H\n\n#include \"Image.h\"\n#include \"MultiButton.h\"\n#include \"ZPin.h\"\n#include \"Timer.h\"\n#include \"SAMDDAC.h\"\n#include \"ZSPI.h\"\n#include \"ZI2C.h\"\n#include \"ZSingleWireSerial.h\"\n#include \"SAMDNVM.h\"\n#include \"SAMDPDM.h\"\n#include \"SAMDSerial.h\"\n\n// cap touch not available on 51 yet\n#ifdef SAMD21\n#include \"CapTouchButton.h\"\n#endif\n\n#define MIC_DEVICE SAMD21PDM\n\n#ifdef SAMD21\n#define OUTPUT_BITS 10\n#else\n#define OUTPUT_BITS 12\n#endif\n\n#include \"pinmap.h\"\n\n#undef min\n#undef max\n\ntypedef int PinName;\n\n#define PAGE_SIZE 512\n\n#define BOOTLOADER_START 0x0\n\n#ifdef SAMD21\n#define BOOTLOADER_END 0x2000\n#endif\n\n#ifdef SAMD51\n#define BOOTLOADER_END 0x4000\n#endif\n\n#define USB_HANDOVER 0\n\n// if we ever want to support 100+ pin packages, need to add PC,PD ports and increase this to 128\n#ifdef SAMD51\n#define DEV_NUM_PINS 128\n#else\n#define DEV_NUM_PINS 64\n#endif\n\n#define IS_ANALOG_PIN(id) 1\n\n#define CODAL_PIN ZPin\n#define CODAL_TIMER Timer\n#define CODAL_SPI ZSPI\n#define CODAL_I2C ZI2C\n#define CODAL_JACDAC_WIRE_SERIAL codal::ZSingleWireSerial\n#define CODAL_SERIAL codal::SAMDSerial\n#define CODAL_DAC SAMDDAC\n\n#ifdef SAMD21\n#define CODAL_NVMCONTROLLER codal::SAMDNVM\n#endif\n\n#define PXT_74HC165 1\n\n#define IMAGE_BITS 4\n\n// The parameters below needs tuning!\n\n#define PA00 0\n#define PA01 1\n#define PA02 2\n#define PA03 3\n#define PA04 4\n#define PA05 5\n#define PA06 6\n#define PA07 7\n#define PA08 8\n#define PA09 9\n#define PA10 10\n#define PA11 11\n#define PA12 12\n#define PA13 13\n#define PA14 14\n#define PA15 15\n#define PA16 16\n#define PA17 17\n#define PA18 18\n#define PA19 19\n#define PA20 20\n#define PA21 21\n#define PA22 22\n#define PA23 23\n#define PA24 24\n#define PA25 25\n#define PA26 26\n#define PA27 27\n#define PA28 28\n#define PA29 29\n#define PA30 30\n#define PA31 31\n#define PB00 32\n#define PB01 33\n#define PB02 34\n#define PB03 35\n#define PB04 36\n#define PB05 37\n#define PB06 38\n#define PB07 39\n#define PB08 40\n#define PB09 41\n#define PB10 42\n#define PB11 43\n#define PB12 44\n#define PB13 45\n#define PB14 46\n#define PB15 47\n#define PB16 48\n#define PB17 49\n#define PB18 50\n#define PB19 51\n#define PB20 52\n#define PB21 53\n#define PB22 54\n#define PB23 55\n#define PB24 56\n#define PB25 57\n#define PB26 58\n#define PB27 59\n#define PB28 60\n#define PB29 61\n#define PB30 62\n#define PB31 63\n#define PC00  64\n#define PC01  65\n#define PC02  66\n#define PC03  67\n#define PC04  68\n#define PC05  69\n#define PC06  70\n#define PC07  71\n#define PC08  72\n#define PC09  73\n#define PC10  74\n#define PC11  75\n#define PC12  76\n#define PC13  77\n#define PC14  78\n#define PC15  79\n#define PC16  80\n#define PC17  81\n#define PC18  82\n#define PC19  83\n#define PC20  84\n#define PC21  85\n#define PC22  86\n#define PC23  87\n#define PC24  88\n#define PC25  89\n#define PC26  90\n#define PC27  91\n#define PC28  92\n#define PC29  93\n#define PC30  94\n#define PC31  95\n#define PD00  96\n#define PD01  97\n#define PD02  98\n#define PD03  99\n#define PD04  100\n#define PD05  101\n#define PD06  102\n#define PD07  103\n#define PD08  104\n#define PD09  105\n#define PD10  106\n#define PD11  107\n#define PD12  108\n#define PD13  109\n#define PD14  110\n#define PD15  111\n#define PD16  112\n#define PD17  113\n#define PD18  114\n#define PD19  115\n#define PD20  116\n#define PD21  117\n#define PD22  118\n#define PD23  119\n#define PD24  120\n#define PD25  121\n#define PD26  122\n#define PD27  123\n#define PD28  124\n#define PD29  125\n#define PD30  126\n#define PD31  127\n#endif\n","pxt.h":"#ifndef __PXT_H\n#define __PXT_H\n\n#include \"pxtbase.h\"\n\n#include \"CodalConfig.h\"\n#include \"CodalHeapAllocator.h\"\n#include \"CodalDevice.h\"\n#include \"CodalDmesg.h\"\n#include \"ErrorNo.h\"\n#include \"Timer.h\"\n#include \"Matrix4.h\"\n#include \"CodalCompat.h\"\n#include \"CodalComponent.h\"\n#include \"ManagedType.h\"\n#include \"Event.h\"\n#include \"NotifyEvents.h\"\n#include \"Button.h\"\n#include \"CodalFiber.h\"\n#include \"MessageBus.h\"\n#include \"MultiButton.h\"\n\nusing namespace codal;\n\n// codal::ManagedString compat\n#define MSTR(s) codal::ManagedString((s)->data, (s)->length)\n#define PSTR(s) mkString((s).toCharArray(), (s).length())\n\n#include \"pins.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"hf2.h\"\n#include \"hf2dbg.h\"\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n#include \"HIDMouse.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n#include \"HIDKeyboard.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n#include \"HIDJoystick.h\"\n#endif\n#endif\n\n#define PXT_COMM_BASE 0x20002000 // 8k in\n\n// old codal compat\n#ifndef REAL_TIME_FUNC\n#define REAL_TIME_FUNC /* */\n#endif\n\nnamespace pxt {\n\n#if CONFIG_ENABLED(DEVICE_USB)\nextern CodalUSB usb;\nextern HF2 hf2;\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nextern USBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nextern USBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nextern USBHIDJoystick joystick;\n#endif\n#endif\n\n// Utility functions\nextern Event lastEvent;\nextern CODAL_TIMER devTimer;\nextern MessageBus devMessageBus;\nextern codal::CodalDevice device;\n\nvoid set_usb_strings(const char *uf2_info);\nextern void (*logJDFrame)(const uint8_t *data);\nextern void (*sendJDFrame)(const uint8_t *data);\n\nstatic inline void raiseEvent(int src, int val) {\n    Event(src, val);\n}\n\n} // namespace pxt\n\nnamespace pins {\nclass CodalSPIProxy;\nclass CodalI2CProxy;\n} // namespace pins\n\ntypedef pins::CodalI2CProxy* I2C_;\ntypedef pins::CodalSPIProxy* SPI_;\n\nnamespace pxt {\ncodal::LowLevelTimer *allocateTimer();\n\n#ifdef CODAL_I2C\nCODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl);\n#endif\nCODAL_SPI* getSPI(DigitalInOutPin mosi, DigitalInOutPin miso, DigitalInOutPin sck);\n#ifdef CODAL_JACDAC_WIRE_SERIAL\nLowLevelTimer* getJACDACTimer();\n#endif\nclass PressureButton;\nuint32_t readButtonMultiplexer(int bits);\nvoid disableButtonMultiplexer();\n}\n\nnamespace serial {\nclass CodalSerialDeviceProxy;\n}\n\ntypedef serial::CodalSerialDeviceProxy* SerialDevice;\n\nnamespace jacdac {\nclass JDProxyDriver;\n} // namespace network\n\ntypedef jacdac::JDProxyDriver* JacDacDriverStatus;\n\n#define DEVICE_ID_BUTTON_SLIDE 3000\n#define DEVICE_ID_MICROPHONE 3001\n#define DEVICE_ID_FIRST_BUTTON 4000\n#define DEVICE_ID_FIRST_TOUCHBUTTON 4100\n\n#define PXT_INTERNAL_KEY_UP 2050\n#define PXT_INTERNAL_KEY_DOWN 2051\n\n#endif\n","pxt.json":"{\n    \"name\": \"core---samd\",\n    \"description\": \"The core library for Codal-based targets\",\n    \"dependencies\": {\n        \"base\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"dal.d.ts\",\n        \"codal.cpp\",\n        \"usb.cpp\",\n        \"pxt.h\",\n        \"platform.h\",\n        \"platform.cpp\",\n        \"pxtcore.h\",\n        \"pins.h\",\n        \"pins.cpp\",\n        \"pinsAnalog.cpp\",\n        \"pinsDigital.cpp\",\n        \"pinsPWM.cpp\",\n        \"pins.ts\",\n        \"pinscompat.ts\",\n        \"control.cpp\",\n        \"i2c.cpp\",\n        \"i2c.ts\",\n        \"spi.cpp\",\n        \"spi.ts\",\n        \"shims.d.ts\",\n        \"enums.d.ts\",\n        \"hf2.cpp\",\n        \"hf2.h\",\n        \"hf2dbg.h\",\n        \"uf2format.h\",\n        \"uf2hid.h\",\n        \"ns.ts\",\n        \"dmac.cpp\",\n        \"dmac.h\",\n        \"timer.ts\",\n        \"light.cpp\",\n        \"light.h\",\n        \"keyvaluestorage.cpp\",\n        \"keyvaluestorage.ts\",\n        \"leveldetector.ts\",\n        \"pxtparts.json\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"yotta\": {\n        \"config\": {\n            \"codal\": {\n                \"component_count\": 64,\n                \"dmesg_buffer_size\": 1024\n            }\n        }\n    },\n    \"dalDTS\": {\n        \"includeDirs\": [\n            \"libraries/codal-core/inc\",\n            \"pxtapp\"\n        ],\n        \"excludePrefix\": [\n            \"JD_\",\n            \"USB_\",\n            \"REQUEST_\",\n            \"LIS3DH_\",\n            \"FXOS8700_\",\n            \"HF2_\",\n            \"PXT_REF_TAG_\",\n            \"MS_\",\n            \"SCSI_\",\n            \"MAG_\",\n            \"MAG3\",\n            \"MPU6\",\n            \"MADCTL\",\n            \"MMA8\"\n        ]\n    }\n}\n","pxtcore.h":"#ifndef __PXTCORE_H\n#define __PXTCORE_H\n\n#include \"CodalDmesg.h\"\n#include \"CodalHeapAllocator.h\"\n\n#define PXT_CODAL 1\n\n#define itoa(a, b) codal::itoa(a, b)\n\n#define GC_GET_HEAP_SIZE() device_heap_size(0)\n#define GC_STACK_BASE DEVICE_STACK_BASE\n#define xmalloc device_malloc\n#define xfree device_free\n\n// on most devices we allocate the entire heap at once, so large allocs should work\n// if they don't you just get the regular out of memory instead of alloc too large\n#define GC_MAX_ALLOC_SIZE (128 * 1024)\n\n#endif\n","pxtparts.json":"{\n    \"neopixel\": {\n        \"simulationBehavior\": \"neopixel\",\n        \"visual\": {\n            \"builtIn\": \"neopixel\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 19,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 28,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createStrip,light.createNeoPixelStrip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"dotstar\": {\n        \"simulationBehavior\": \"dotstar\",\n        \"visual\": {\n            \"builtIn\": \"dotstar\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 1\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createAPA102Strip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"dataPin\"\n                },\n                {\n                    \"pinInstantiationIdx\": 1,\n                    \"partParameter\": \"clkPin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },\n    \"pixels\": {\n        \"simulationBehavior\": \"pixels\",\n        \"visual\": { \n            \"builtIn\": \"pixels\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"MOSI\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"SCK\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },    \n    \"buttons\": {\n        \"simulationBehavior\": \"buttons\",\n        \"visual\": {\n            \"builtIn\": \"buttons\",\n            \"width\": 75,\n            \"height\": 45,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 30,\n                    \"y\": 45\n                }\n            ]\n        },\n        \"numberOfPins\": 2,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"Button.onEvent,Button.isPressed,Button.wasPressed\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"button\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"slideswitch\": {\n        \"numberOfPins\": 3,\n        \"simulationBehavior\": \"slideswitch\",\n        \"visual\": {\n            \"builtIn\": \"slideswitch\",\n            \"width\": 100,\n            \"height\": 100,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalRead,DigitalInOutPin.onPulsed,DigitalInOutPin.onEvent\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"microservo\": {\n        \"simulationBehavior\": \"microservo\",\n        \"visual\": {\n            \"builtIn\": \"microservo\",\n            \"width\": 74.85,\n            \"height\": 200,\n            \"pinDistance\": 10,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 37,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 5\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"PwmOnlyPin.servoWrite,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"led\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"analogled\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogOutPin.analogWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"photocell\": {\n        \"numberOfPins\": 3,\n        \"visual\": {\n            \"builtIn\": \"photocell\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 15,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"photocell\",\n        \"pinDefinitions\": [\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogInPin.analogRead\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace light {\n\n    /**\n     * Send a programmable light buffer to the specified digital pin\n     * @param data The pin that the lights are connected to\n     * @param clk the clock line if any\n     * @param mode the color encoding mode\n     * @param buf The buffer to send to the pin\n     */\n    //% shim=light::sendBuffer\n    function sendBuffer(data: DigitalInOutPin, clk: DigitalInOutPin, mode: int32, buf: Buffer): void;\n}\ndeclare namespace control {\n\n    /**\n     * Determines if the USB has been enumerated.\n     */\n    //% shim=control::isUSBInitialized\n    function isUSBInitialized(): boolean;\n}\ndeclare namespace pins {\n\n    /**\n     * Get a pin by configuration id (DAL.CFG_PIN...)\n     */\n    //% shim=pins::pinByCfg\n    function pinByCfg(key: int32): DigitalInOutPin;\n\n    /**\n     * Create a new zero-initialized buffer.\n     * @param size number of bytes in the buffer\n     */\n    //% shim=pins::createBuffer\n    function createBuffer(size: int32): Buffer;\n\n    /**\n     * Get the duration of the last pulse in microseconds. This function should be called from a\n     * ``onPulsed`` handler.\n     */\n    //% help=pins/pulse-duration blockGap=8\n    //% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n    //% weight=19 shim=pins::pulseDuration\n    function pulseDuration(): int32;\n}\n\n\ndeclare interface AnalogInPin {\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 weight=53\n    //% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=AnalogInPinMethods::analogRead\n    analogRead(): int32;\n}\n\n\ndeclare interface AnalogOutPin {\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 weight=52\n    //% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4\n    //% value.min=0 value.max=1023 shim=AnalogOutPinMethods::analogWrite\n    analogWrite(value: int32): void;\n}\n\n\ndeclare interface DigitalInOutPin {\n    /**\n     * Read a pin or connector as either 0 or 1\n     * @param name pin to read from\n     */\n    //% help=pins/digital-read weight=61\n    //% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::digitalRead\n    digitalRead(): boolean;\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\n     */\n    //% help=pins/digital-write weight=60\n    //% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::digitalWrite\n    digitalWrite(value: boolean): void;\n\n    /**\n     * Make this pin a digital input, and create events where the timestamp is the duration\n     * that this pin was either ``high`` or ``low``.\n     */\n    //% help=pins/on-pulsed weight=16 blockGap=8\n    //% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4\n    //% deprecated=1 hidden=1 shim=DigitalInOutPinMethods::onPulsed\n    onPulsed(pulse: PulseValue, body: () => void): void;\n\n    /**\n     * Register code to run when a pin event occurs. \n     */\n    //% help=pins/on-event weight=20 blockGap=8\n    //% blockId=pinsonevent block=\"on|pin %pin|%event\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4 shim=DigitalInOutPinMethods::onEvent\n    onEvent(event: PinEvent, body: () => void): void;\n\n    /**\n     * Return 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 %high||timeout %maxDuration (µs)\"\n    //% weight=18 blockGap=8\n    //% help=\"pins/pulse-in\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4 maxDuration.defl=2000000 shim=DigitalInOutPinMethods::pulseIn\n    pulseIn(value: PulseValue, maxDuration?: int32): int32;\n\n    /**\n     * Set the pull direction 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=17 blockGap=8\n    //% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::setPull\n    setPull(pull: PinPullMode): void;\n}\n\n\ndeclare interface PwmPin {}\n\n\ndeclare interface PwmOnlyPin {\n    /**\n     * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n     * **microseconds** or `1/1000` milliseconds.\n     * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n     * 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=51\n    //% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::analogSetPeriod\n    analogSetPeriod(period: int32): void;\n\n    /**\n     * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n     * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n     * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n     * 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\n     */\n    //% help=pins/servo-write weight=41 group=\"Servo\"\n    //% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n    //% parts=microservo trackArgs=0\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4\n    //% value.defl=90 shim=PwmOnlyPinMethods::servoWrite\n    servoWrite(value?: int32): void;\n\n    /**\n     * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n     * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n     * @param name pin name\n     * @param duration pulse duration in micro seconds, eg:1500\n     */\n    //% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n    //% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n    //% parts=microservo blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::servoSetPulse\n    servoSetPulse(duration: int32): void;\n\n    /**\n     * Indicates if the servo is running continuously\n     */\n    //% blockHidden=1 shim=PwmOnlyPinMethods::servoSetContinuous\n    servoSetContinuous(continuous: boolean): void;\n}\ndeclare namespace control {\n\n    /**\n     * Announce that an event happened to registered handlers.\n     * @param src ID of the MicroBit Component that generated the event\n     * @param value Component specific code indicating the cause of the event.\n     */\n    //% weight=21 blockGap=12 blockId=\"control_raise_event\"\n    //% help=control/raise-event\n    //% block=\"raise event|from %src|with value %value\" blockExternalInputs=1 shim=control::raiseEvent\n    function raiseEvent(src: int32, value: int32): void;\n\n    /**\n     * Determine the version of system software currently running.\n     */\n    //% blockId=\"control_device_dal_version\" block=\"device dal version\"\n    //% help=control/device-dal-version shim=control::deviceDalVersion\n    function deviceDalVersion(): string;\n\n    /**\n     * Allocates the next user notification event\n     */\n    //% help=control/allocate-notify-event shim=control::allocateNotifyEvent\n    function allocateNotifyEvent(): int32;\n\n    /** Write a message to DMESG debugging buffer. */\n    //% shim=control::dmesg\n    function dmesg(s: string): void;\n\n    /** Write a message and value (pointer) to DMESG debugging buffer. */\n    //% shim=control::dmesgPtr\n    function dmesgPtr(str: string, ptr: Object): void;\n}\n\n\ndeclare interface I2C {\n    /**\n     * Read `size` bytes from a 7-bit I2C `address`.\n     */\n    //% repeat.defl=0 shim=I2CMethods::readBuffer\n    readBuffer(address: int32, size: int32, repeat?: boolean): Buffer;\n\n    /**\n     * Write bytes to a 7-bit I2C `address`.\n     */\n    //% repeat.defl=0 shim=I2CMethods::writeBuffer\n    writeBuffer(address: int32, buf: Buffer, repeat?: boolean): int32;\n}\ndeclare namespace pins {\n\n    /**\n     * Opens a Serial communication driver\n     */\n    //% help=pins/create-i2c\n    //% parts=i2c shim=pins::createI2C\n    function createI2C(sda: DigitalInOutPin, scl: DigitalInOutPin): I2C;\n}\ndeclare namespace pins {\n\n    /**\n     * Opens a SPI driver\n     */\n    //% help=pins/create-spi\n    //% parts=spi shim=pins::createSPI\n    function createSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin): SPI;\n\n    /**\n     * Opens a slave SPI driver\n     */\n    //% parts=spi shim=pins::createSlaveSPI\n    function createSlaveSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin, csPin: DigitalInOutPin): SPI;\n}\n\n\ndeclare interface SPI {\n    /**\n     * Write to the SPI bus\n     */\n    //% shim=SPIMethods::write\n    write(value: int32): int32;\n\n    /**\n     * Transfer buffers over the SPI bus\n     */\n    //% argsNullable shim=SPIMethods::transfer\n    transfer(command: Buffer, response: Buffer): void;\n\n    /**\n     * Sets the SPI clock frequency\n     */\n    //% shim=SPIMethods::setFrequency\n    setFrequency(frequency: int32): void;\n\n    /**\n     * Sets the SPI bus mode\n     */\n    //% shim=SPIMethods::setMode\n    setMode(mode: int32): void;\n}\ndeclare namespace configStorage {\n\n    /**\n     * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n     * @param key the identifier (max 16 characters)\n     * @param value the data (max 32 characters)\n     */\n    //% shim=configStorage::setBuffer\n    function setBuffer(key: string, value: Buffer): void;\n\n    /**\n     * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n     * @param key the identifier (max 16 characters)\n     */\n    //% shim=configStorage::getBuffer\n    function getBuffer(key: string): Buffer;\n\n    /**\n     * Removes the key from local storage\n     * @param key the identifier (max 16 characters)\n     */\n    //% shim=configStorage::removeItem\n    function removeItem(key: string): void;\n\n    /**\n     * Clears the local storage\n     */\n    //% shim=configStorage::clear\n    function clear(): void;\n}\n\n// Auto-generated. Do not edit. Really.\n","spi.cpp":"#include \"pxt.h\"\n#include \"ErrorNo.h\"\n\nnamespace pins {\n\nclass CodalSPIProxy {\nprivate:\n    DevicePin* mosi; \n    DevicePin* miso; \n    DevicePin* sck;\n    CODAL_SPI spi;\npublic:\n    CodalSPIProxy* next;\n\npublic:\n    CodalSPIProxy(DevicePin* _mosi, DevicePin* _miso, DevicePin* _sck)\n        : mosi(_mosi)\n        , miso(_miso)\n        , sck(_sck)\n        , spi(*_mosi, *_miso, *_sck) \n        , next(NULL)\n    {\n    }\n\n#ifdef CODAL_SPI_SLAVE_SUPPORTED\n    CodalSPIProxy(DevicePin* _mosi, DevicePin* _miso, DevicePin* _sck, DevicePin* _cs)\n        : mosi(_mosi)\n        , miso(_miso)\n        , sck(_sck)\n        , spi(*_mosi, *_miso, *_sck, _cs) \n        , next(NULL)\n    {\n    }\n#endif\n\n    CODAL_SPI* getSPI() {\n        return &spi;\n    }\n\n    bool matchPins(DevicePin* mosi, DevicePin* miso, DevicePin* sck) {\n        return this->mosi == mosi && this->miso == miso && this->sck == sck;\n    }\n\n    int write(int value) {\n        return spi.write(value);\n    }\n\n    void transfer(Buffer command, Buffer response) {\n        auto cdata = NULL == command ? NULL : command->data;\n        auto clength = NULL == command ? 0 : command->length;\n        auto rdata = NULL == response ? NULL : response->data;\n        auto rlength = NULL == response ? 0 : response->length;\n        spi.transfer(cdata, clength, rdata, rlength);\n    }\n\n    void setFrequency(int frequency) {\n        spi.setFrequency(frequency);\n    }\n\n    void setMode(int mode) {\n        spi.setMode(mode);\n    }\n};\n\nSPI_ spis(NULL);\n\n/**\n* Opens a SPI driver\n*/\n//% help=pins/create-spi\n//% parts=spi\nSPI_ createSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin) {\n  auto dev = spis;\n  while(dev) {\n    if (dev->matchPins(mosiPin, misoPin, sckPin))\n      return dev;\n    dev = dev->next;\n  }\n\n  auto ser = new CodalSPIProxy(mosiPin, misoPin, sckPin);\n  ser->next = spis;\n  spis = ser;\n  return ser;\n}\n\n/**\n* Opens a slave SPI driver\n*/\n//% parts=spi\nSPI_ createSlaveSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin, DigitalInOutPin csPin) {\n#ifdef CODAL_SPI_SLAVE_SUPPORTED\n  auto dev = spis;\n  if (!csPin)\n    soft_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n  while(dev) {\n    if (dev->matchPins(mosiPin, misoPin, sckPin))\n      return dev;\n    dev = dev->next;\n  }\n\n  auto ser = new CodalSPIProxy(mosiPin, misoPin, sckPin, csPin);\n  ser->next = spis;\n  spis = ser;\n  return ser;\n#else\n  soft_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n  return NULL;\n#endif\n}\n\n}\n\nnamespace pxt {\n\nCODAL_SPI* getSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin) {\n    auto spi = pins::createSPI(mosiPin, misoPin, sckPin);\n    return spi->getSPI();\n}\n\n}\n\nnamespace SPIMethods {\n\n/**\n* Write to the SPI bus\n*/\n//%\nint write(SPI_ device, int value) {\n    return device->write(value);\n}\n\n/**\n* Transfer buffers over the SPI bus\n*/\n//% argsNullable\nvoid transfer(SPI_ device, Buffer command, Buffer response) {\n    if (!device)\n        soft_panic(PANIC_CAST_FROM_NULL);\n    if (!command && !response)\n        return;\n    device->transfer(command, response);\n}\n\n/**\n* Sets the SPI clock frequency\n*/\n//%\nvoid setFrequency(SPI_ device, int frequency) {\n    device->setFrequency(frequency);\n}\n\n/**\n* Sets the SPI bus mode\n*/\n//%\nvoid setMode(SPI_ device, int mode) {\n    device->setMode(mode);\n}\n\n}\n","spi.ts":"namespace pins {\n\n    let _spi: SPI;\n    /**\n    * Gets the default SPI driver\n    */\n    //%\n    export function spi() {\n        if (!_spi) {\n            const mosi = pins.pinByCfg(DAL.CFG_PIN_MOSI);\n            const miso = pins.pinByCfg(DAL.CFG_PIN_MISO);\n            const sck = pins.pinByCfg(DAL.CFG_PIN_SCK);\n            _spi = pins.createSPI(mosi, miso, sck);\n        }\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 advanced=true\n    //% blockId=spi_write block=\"spi write %value\"\n    export function spiWrite(value: number) {\n        return spi().write(value);\n    }\n\n    /**\n     * Write a given command to SPI bus, and at the same time read the response.\n     */\n    //% help=pins/spi-transfer weight=4 advanced=true\n    //% blockId=spi_transfer block=\"spi transfer %command into %response\"\n    export function spiTransfer(command: Buffer, response: Buffer) {\n        spi().transfer(command, response);\n    }\n\n    /**\n     * Set the SPI frequency\n     * @param frequency the clock frequency, eg: 1000000\n     */\n    //% help=pins/spi-frequency weight=4 advanced=true\n    //% blockId=spi_frequency block=\"spi frequency %frequency\"\n    export function spiFrequency(frequency: number) {\n        spi().setFrequency(frequency);\n    }\n\n    /**\n     * Set the SPI signal mode\n     * @param mode the mode, eg: 3\n     */\n    //% help=pins/spi-mode weight=3 advanced=true\n    //% blockId=spi_mode block=\"spi mode %mode\"\n    export function spiMode(mode: number) {\n        spi().setMode(mode);\n    }\n}","test.ts":"let i = 1\nlet f = 0.5\nlet plus = i + f\nlet minus = i - f\n\nlet r = Math.random()\nlet ri = Math.randomRange(5, 10)\n\n","timer.ts":"namespace control {\n    /**\n     * A timer\n     */\n    //% fixedInstances\n    export class Timer {\n        start: number;\n\n        constructor() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Gets the elapsed time in millis since the last reset\n         */\n        //% blockId=timerMillis block=\"%timer|millis\"\n        millis(): number {\n            return control.millis() - this.start;\n        }\n\n        /**\n         * Gets the elapsed time in seconds since the last reset\n         */\n        //% blockId=timerSeconds block=\"%timer|seconds\"\n        seconds(): number {\n            return this.millis() / 1000;\n        }\n\n        /**\n         * Resets the timer\n         */\n        //% blockId=timerRest block=\"%timer|reset\"\n        reset() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Pauses until the timer reaches the given amount of milliseconds\n         * @param ms how long to pause for, eg: 5, 100, 200, 500, 1000, 2000\n         */\n        //% blockId=timerPauseUntil block=\"%timer|pause until (ms) %ms\"\n        pauseUntil(ms: number) {\n            const remaining = this.millis() - ms;\n            pause(Math.max(0, remaining));\n        }\n    }\n\n    //% whenUsed fixedInstance block=\"timer 1\"\n    export const timer1 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 2\"\n    export const timer2 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 3\"\n    export const timer3 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 4\"\n    export const timer4 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 5\"\n    export const timer5 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 6\"\n    export const timer6 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 7\"\n    export const timer7 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 8\"\n    export const timer8 = new Timer();\n}","uf2format.h":"#ifndef UF2FORMAT_H\n#define UF2FORMAT_H 1\n\n#include <stdint.h>\n#include <stdbool.h>\n\n// All entries are little endian.\n\n#ifndef BOOTLOADER_START\n#define BOOTLOADER_START 0x0\n#endif\n\n#ifndef BOOTLOADER_END\n#define BOOTLOADER_END 0x2000\n#endif\n\n#ifndef UF2_BINFO\n#define UF2_BINFO ((UF2_BInfo *)(BOOTLOADER_END - sizeof(UF2_BInfo)))\n#endif\n\n#ifndef UF2_INFO_TXT\n#define UF2_INFO_TXT UF2_BINFO->info_uf2\n#endif\n\n\n#define UF2_MAGIC_START0 0x0A324655UL // \"UF2\\n\"\n#define UF2_MAGIC_START1 0x9E5D5157UL // Randomly selected\n#define UF2_MAGIC_END 0x0AB16F30UL    // Ditto\n\n// If set, the block is \"comment\" and should not be flashed to the device\n#define UF2_FLAG_NOFLASH 0x00000001\n\ntypedef struct {\n    // 32 byte header\n    uint32_t magicStart0;\n    uint32_t magicStart1;\n    uint32_t flags;\n    uint32_t targetAddr;\n    uint32_t payloadSize;\n    uint32_t blockNo;\n    uint32_t numBlocks;\n    uint32_t reserved;\n\n    // raw data;\n    uint8_t data[476];\n\n    // store magic also at the end to limit damage from partial block reads\n    uint32_t magicEnd;\n} UF2_Block;\n\ntypedef struct {\n    uint8_t version;\n    uint8_t ep_in;\n    uint8_t ep_out;\n    uint8_t reserved0;\n    uint32_t cbw_tag;\n    uint32_t blocks_remaining;\n    uint8_t *buffer;\n} UF2_HandoverArgs;\n\ntypedef void (*UF2_MSC_Handover_Handler)(UF2_HandoverArgs *handover);\ntypedef void (*UF2_HID_Handover_Handler)(int ep);\n\n// this is required to be exactly 16 bytes long by the linker script\ntypedef struct {\n    void *reserved0;\n    UF2_HID_Handover_Handler handoverHID;\n    UF2_MSC_Handover_Handler handoverMSC;\n    const char *info_uf2;\n} UF2_BInfo;\n\nstatic inline bool is_uf2_block(void *data) {\n    UF2_Block *bl = (UF2_Block *)data;\n    return bl->magicStart0 == UF2_MAGIC_START0 && bl->magicStart1 == UF2_MAGIC_START1 &&\n           bl->magicEnd == UF2_MAGIC_END;\n}\n\nstatic inline bool in_uf2_bootloader_space(const void *addr) {\n    return (BOOTLOADER_START + 0x100) <= (uint32_t)addr && (uint32_t)addr < (BOOTLOADER_END);\n}\n\nstatic inline const char *uf2_info(void) {\n    if (in_uf2_bootloader_space(UF2_INFO_TXT))\n        return UF2_INFO_TXT;\n    return \"N/A\";\n}\n\n#ifdef UF2_DEFINE_HANDOVER\nstatic inline void hf2_handover(uint8_t ep) {\n    const char *board_info = UF2_BINFO->info_uf2;\n    UF2_HID_Handover_Handler fn = UF2_BINFO->handoverHID;\n\n    if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&\n        ((uint32_t)fn & 1)) {\n        // Pass control to bootloader; never returns\n        fn(ep & 0xf);\n    }\n}\n\nstatic inline void check_uf2_handover(uint8_t *buffer, uint32_t blocks_remaining, uint8_t ep_in,\n                                      uint8_t ep_out, uint32_t cbw_tag) {\n    if (!is_uf2_block(buffer))\n        return;\n\n    const char *board_info = UF2_BINFO->info_uf2;\n    UF2_MSC_Handover_Handler fn = UF2_BINFO->handoverMSC;\n\n    if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&\n        ((uint32_t)fn & 1)) {\n        UF2_HandoverArgs hand = {\n            1, ep_in, ep_out, 0, cbw_tag, blocks_remaining, buffer,\n        };\n        // Pass control to bootloader; never returns\n        fn(&hand);\n    }\n}\n#endif\n\n#endif\n","uf2hid.h":"#ifndef UF2_HID_H\n#define UF2_HID_H 1\n\n#define HF2_CMD_BININFO 0x0001\n// no arguments\n#define HF2_MODE_BOOTLOADER 0x01\n#define HF2_MODE_USERSPACE 0x02\nstruct HF2_BININFO_Result {\n    uint32_t mode;\n    uint32_t flash_page_size;\n    uint32_t flash_num_pages;\n    uint32_t max_message_size;\n    uint32_t uf2_family;\n};\n\n#define HF2_CMD_INFO 0x0002\n// no arguments\n// results is utf8 character array\n\n#define HF2_CMD_RESET_INTO_APP 0x0003\n// no arguments, no result\n\n#define HF2_CMD_RESET_INTO_BOOTLOADER 0x0004\n// no arguments, no result\n\n#define HF2_CMD_START_FLASH 0x0005\n// no arguments, no result\n\n#define HF2_CMD_WRITE_FLASH_PAGE 0x0006\nstruct HF2_WRITE_FLASH_PAGE_Command {\n    uint32_t target_addr;\n    uint32_t data[0];\n};\n// no result\n\n#define HF2_CMD_CHKSUM_PAGES 0x0007\nstruct HF2_CHKSUM_PAGES_Command {\n    uint32_t target_addr;\n    uint32_t num_pages;\n};\nstruct HF2_CHKSUM_PAGES_Result {\n    uint16_t chksums[0 /* num_pages */];\n};\n\n#define HF2_CMD_READ_WORDS 0x0008\nstruct HF2_READ_WORDS_Command {\n    uint32_t target_addr;\n    uint32_t num_words;\n};\nstruct HF2_READ_WORDS_Result {\n    uint32_t words[0 /* num_words */];\n};\n\n#define HF2_CMD_WRITE_WORDS 0x0009\nstruct HF2_WRITE_WORDS_Command {\n    uint32_t target_addr;\n    uint32_t num_words;\n    uint32_t words[0 /* num_words */];\n};\n// no result\n\n#define HF2_CMD_DMESG 0x0010\n// no arguments\n// results is utf8 character array\n\n#define HF2_EV_MASK 0x800000\n\n#define HF2_CMD_JDS_CONFIG 0x0020\n#define HF2_CMD_JDS_SEND 0x0021\n#define HF2_EV_JDS_PACKET 0x800020\n\ntypedef struct {\n    uint32_t command_id;\n    uint16_t tag;\n    uint8_t reserved0;\n    uint8_t reserved1;\n\n    union {\n        struct HF2_WRITE_FLASH_PAGE_Command write_flash_page;\n        struct HF2_WRITE_WORDS_Command write_words;\n        struct HF2_READ_WORDS_Command read_words;\n        struct HF2_CHKSUM_PAGES_Command chksum_pages;\n        uint8_t data8[0];\n        uint16_t data16[0];\n        uint32_t data32[0];\n    };\n} HF2_Command;\n\ntypedef struct {\n    union {\n        uint32_t eventId;\n        struct {\n            uint16_t tag;\n            union {\n                struct {\n                    uint8_t status;\n                    uint8_t status_info;\n                };\n                uint16_t status16;\n            };\n        };\n    };\n    union {\n        struct HF2_BININFO_Result bininfo;\n        uint8_t data8[0];\n        uint16_t data16[0];\n        uint32_t data32[0];\n    };\n} HF2_Response;\n\n#define HF2_FLAG_SERIAL_OUT 0x80\n#define HF2_FLAG_SERIAL_ERR 0xC0\n#define HF2_FLAG_CMDPKT_LAST 0x40\n#define HF2_FLAG_CMDPKT_BODY 0x00\n#define HF2_FLAG_MASK 0xC0\n#define HF2_SIZE_MASK 63\n\n#define HF2_STATUS_OK 0x00\n#define HF2_STATUS_INVALID_CMD 0x01\n#define HF2_STATUS_INVALID_STATE 0x02\n\n#endif\n","usb.cpp":"#include \"pxt.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"uf2format.h\"\n\nnamespace pxt {\nCodalUSB usb;\n\n// share the buffer; we will crash anyway if someone talks to us over both at the same time\nHF2_Buffer hf2buf;\nHF2 hf2(hf2buf);\n#ifdef HF2_HID\nHF2 hf2hid(hf2buf);\n#endif\nDummyIface dummyIface;\n\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nUSBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nUSBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nUSBHIDJoystick joystick;\n#endif\n\nstatic const DeviceDescriptor device_desc = {\n    0x12,   // bLength\n    0x01,   // bDescriptorType\n    0x0210, // bcdUSBL\n\n    // Class etc specified per-interface\n    0x00, 0x00, 0x00,\n\n    0x40, // bMaxPacketSize0\n    USB_DEFAULT_VID, USB_DEFAULT_PID,\n    0x4202, // bcdDevice - leave unchanged for the HF2 to work\n    0x01,   // iManufacturer\n    0x02,   // iProduct\n    0x03,   // SerialNumber\n    0x01    // bNumConfigs\n};\n\nstatic void start_usb() {\n    // start USB with a delay, so that user code can add new interfaces if needed\n    // (eg USB HID keyboard, or MSC)\n    fiber_sleep(500);\n    usb.start();\n}\n\nvoid platform_usb_init() __attribute__((weak));\nvoid platform_usb_init() {}\n\nvoid set_usb_strings(const char *uf2_info) {\n    static const char *string_descriptors[3];\n    static char serial[12];\n    itoa(target_get_serial() & 0x7fffffff, serial);\n\n    auto model = strstr(uf2_info, \"Model: \");\n    if (model) {\n        model += 7;\n        auto end = model;\n        while (*end && *end != '\\n' && *end != '\\r')\n            end++;\n        auto len = end - model;\n        auto dev = (char *)app_alloc(len + 10);\n        memcpy(dev, model, len);\n        strcpy(dev + len, \" (app)\");\n        // try to split into manufacturer and\n        auto sep = strstr(dev, \" / \");\n        if (sep) {\n            *sep = '\\0';\n            string_descriptors[0] = dev;\n            string_descriptors[1] = sep + 3;\n        } else {\n            string_descriptors[0] = dev;\n            string_descriptors[1] = dev;\n        }\n    } else {\n        string_descriptors[0] = \"Unknown Corp.\";\n        string_descriptors[1] = \"PXT Device (app)\";\n    }\n\n    string_descriptors[2] = serial;\n    usb.stringDescriptors = string_descriptors;\n}\n\nvoid usb_init() {\n    usb.deviceDescriptor = &device_desc;\n    set_usb_strings(UF2_INFO_TXT);\n\n    platform_usb_init();\n\n    usb.add(hf2);\n\n#ifdef HF2_HID\n    hf2hid.useHID = true;\n    usb.add(hf2hid);\n#else\n    // the WINUSB descriptors don't seem to work if there's only one interface\n    // so we add a dummy interface\n    usb.add(dummyIface);\n#endif\n\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n    usb.add(mouse);\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n    usb.add(keyboard);\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n    usb.add(joystick);\n#endif\n\n    create_fiber(start_usb);\n}\n\n} // namespace pxt\n\n#else\nnamespace pxt {\nvoid usb_init() {}\n} // namespace pxt\n#endif\n\nnamespace control {\n/**\n * Determines if the USB has been enumerated.\n */\n//%\nbool isUSBInitialized() {\n#if CONFIG_ENABLED(DEVICE_USB)\n    return pxt::usb.isInitialised();\n#else\n    return false;\n#endif\n}\n} // namespace control\n\nnamespace pxt {\nstatic void (*pSendToUART)(const char *data, int len) = NULL;\nvoid setSendToUART(void (*f)(const char *, int)) {\n    pSendToUART = f;\n}\n\nvoid sendSerial(const char *data, int len) {\n#if CONFIG_ENABLED(DEVICE_USB)\n    hf2.sendSerial(data, len);\n#if HF2_HID\n    hf2hid.sendSerial(data, len);\n#endif\n#endif\n    if (pSendToUART)\n        pSendToUART(data, len);\n}\n\nvoid dumpDmesg() {\n    sendSerial(\"\\nDMESG:\\n\", 8);\n    sendSerial(codalLogStore.buffer, codalLogStore.ptr);\n    sendSerial(\"\\n\\n\", 2);\n}\n\nvoid (*logJDFrame)(const uint8_t *data);\nvoid (*sendJDFrame)(const uint8_t *data);\n\n} // namespace pxt\n"},"core---stm32":{"README.md":"# core\n\nThe core library for Codal-based targets.\n\n","codal.cpp":"#include \"pxt.h\"\n#include \"LowLevelTimer.h\"\nusing namespace codal;\n\nvoid cpu_clock_init(void);\n\nPXT_ABI(__aeabi_dadd)\nPXT_ABI(__aeabi_dcmplt)\nPXT_ABI(__aeabi_dcmpgt)\nPXT_ABI(__aeabi_dsub)\nPXT_ABI(__aeabi_ddiv)\nPXT_ABI(__aeabi_dmul)\n\n#ifdef DEVICE_GET_FIBER_LIST_AVAILABLE\n// newer codal-core has get_fiber_list() but not list_fibers()\nnamespace codal {\n/*\n * Return all current fibers.\n *\n * @param dest If non-null, it points to an array of pointers to fibers to store results in.\n *\n * @return the number of fibers (potentially) stored\n */\nint list_fibers(Fiber **dest) {\n    int i = 0;\n    for (Fiber *fib = codal::get_fiber_list(); fib; fib = fib->next) {\n        if (dest)\n            dest[i] = fib;\n        i++;\n    }\n    return i;\n}\n\n} // namespace codal\n#endif\n\nnamespace pxt {\n\nvoid platform_init();\nvoid usb_init();\n\n// The first two word are used to tell the bootloader that a single reset should start the\n// bootloader and the MSD device, not us.\n// The rest is reserved for partial flashing checksums.\n__attribute__((section(\".binmeta\"))) __attribute__((used)) const uint32_t pxt_binmeta[] = {\n    0x87eeb07c, 0x87eeb07c, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,\n    0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,\n};\n\nEvent lastEvent;\nMessageBus devMessageBus;\ncodal::CodalDevice device;\n\nstruct FreeList {\n    FreeList *next;\n};\n\nstatic void commInit() {\n    int commSize = bytecode[20];\n    if (!commSize)\n        return;\n\n    void *r = app_alloc_at((void *)PXT_COMM_BASE, commSize);\n    DMESG(\"comm %d -> %p\", commSize, r);\n    if (!r)\n        target_panic(20);\n}\n\nstatic void initCodal() {\n    cpu_clock_init();\n\n    commInit();\n\n    // Bring up fiber scheduler.\n    scheduler_init(devMessageBus);\n\n    // We probably don't need that - components are initialized when one obtains\n    // the reference to it.\n    // devMessageBus.listen(DEVICE_ID_MESSAGE_BUS_LISTENER, DEVICE_EVT_ANY, this,\n    // &CircuitPlayground::onListenerRegisteredEvent);\n\n    for (int i = 0; i < DEVICE_COMPONENT_COUNT; i++) {\n        if (CodalComponent::components[i])\n            CodalComponent::components[i]->init();\n    }\n\n    usb_init();\n\n    auto led = LOOKUP_PIN(LED);\n    if (led) {\n        led->setDigitalValue(0);\n    }\n}\n\n// ---------------------------------------------------------------------------\n// An adapter for the API expected by the run-time.\n// ---------------------------------------------------------------------------\n\n// We have the invariant that if [dispatchEvent] is registered against the DAL\n// for a given event, then [handlersMap] contains a valid entry for that\n// event.\nvoid dispatchEvent(Event e) {\n    lastEvent = e;\n\n    auto curr = findBinding(e.source, e.value);\n    auto value = fromInt(e.value);\n    while (curr) {\n        runAction1(curr->action, value);\n        curr = nextBinding(curr->next, e.source, e.value);\n    }\n}\n\nvoid registerWithDal(int id, int event, Action a, int flags) {\n    // first time?\n    if (!findBinding(id, event)) {\n        devMessageBus.listen(id, event, dispatchEvent, flags);\n        if (event == 0) {\n            // we're registering for all events on given ID\n            // need to remove old listeners for specific events\n            auto curr = findBinding(id, -1);\n            while (curr) {\n                devMessageBus.ignore(id, curr->value, dispatchEvent);\n                curr = nextBinding(curr->next, id, -1);\n            }\n        }\n    }\n    setBinding(id, event, a);\n}\n\nvoid fiberDone(void *a) {\n    unregisterGCPtr((Action)a);\n    release_fiber();\n}\n\nvoid releaseFiber() {\n    release_fiber();\n}\n\nvoid sleep_ms(unsigned ms) {\n    fiber_sleep(ms);\n}\n\nvoid sleep_us(uint64_t us) {\n    target_wait_us(us);\n}\n\nvoid forever_stub(void *a) {\n    while (true) {\n        runAction0((Action)a);\n        fiber_sleep(20);\n    }\n}\n\nvoid runForever(Action a) {\n    if (a != 0) {\n        registerGCPtr(a);\n        create_fiber(forever_stub, (void *)a);\n    }\n}\n\nvoid runInParallel(Action a) {\n    if (a != 0) {\n        registerGCPtr(a);\n        create_fiber((void (*)(void *))(void*)runAction0, (void *)a, fiberDone);\n    }\n}\n\nvoid waitForEvent(int id, int event) {\n    fiber_wait_for_event(id, event);\n}\n\nvoid initRuntime() {\n    initSystemTimer();\n    initCodal();\n    platform_init();\n}\n\n//%\nunsigned afterProgramPage() {\n    unsigned ptr = (unsigned)&bytecode[0];\n    ptr += programSize();\n    ptr = (ptr + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);\n    return ptr;\n}\n\nuint64_t getLongSerialNumber() {\n    return device.getSerialNumber();\n}\n\nint current_time_ms() {\n    return system_timer_current_time();\n}\n\nuint64_t current_time_us() {\n    return system_timer_current_time_us();\n}\n\nThreadContext *getThreadContext() {\n    if (!currentFiber)\n        return NULL;\n    return (ThreadContext *)currentFiber->user_data;\n}\n\nvoid setThreadContext(ThreadContext *ctx) {\n    currentFiber->user_data = ctx;\n}\n\nstatic void *threadAddressFor(codal::Fiber *fib, void *sp) {\n    if (fib == currentFiber)\n        return sp;\n    return (uint8_t *)sp + ((uint8_t *)fib->stack_top - (uint8_t *)tcb_get_stack_base(fib->tcb));\n}\n\nvoid gcProcessStacks(int flags) {\n    // check scheduler is initialized\n    if (!currentFiber) {\n        // make sure we allocate something to at least initalize the memory allocator\n        void *volatile p = xmalloc(1);\n        xfree(p);\n        return;\n    }\n\n    int numFibers = codal::list_fibers(NULL);\n    codal::Fiber **fibers = (codal::Fiber **)xmalloc(sizeof(codal::Fiber *) * numFibers);\n    int num2 = codal::list_fibers(fibers);\n    if (numFibers != num2)\n        oops(12);\n    int cnt = 0;\n\n    for (int i = 0; i < numFibers; ++i) {\n        auto fib = fibers[i];\n        auto ctx = (ThreadContext *)fib->user_data;\n        if (!ctx)\n            continue;\n        gcProcess(ctx->thrownValue);\n        for (auto seg = &ctx->stack; seg; seg = seg->next) {\n            auto ptr = (TValue *)threadAddressFor(fib, seg->top);\n            auto end = (TValue *)threadAddressFor(fib, seg->bottom);\n            if (flags & 2)\n                DMESG(\"RS%d:%p/%d\", cnt++, ptr, end - ptr);\n            // VLOG(\"mark: %p - %p\", ptr, end);\n            while (ptr < end) {\n                gcProcess(*ptr++);\n            }\n        }\n    }\n    xfree(fibers);\n}\n\nLowLevelTimer *getJACDACTimer() {\n    static LowLevelTimer *jacdacTimer;\n    if (!jacdacTimer) {\n        jacdacTimer = allocateTimer();\n        jacdacTimer->setIRQPriority(1);\n    }\n    return jacdacTimer;\n}\nvoid initSystemTimer() {\n    new CODAL_TIMER(*allocateTimer());\n}\n\n} // namespace pxt\n","control.cpp":"#include \"pxt.h\"\n\n#if defined(NRF52_SERIES) || defined(PICO_BOARD)\n#define _estack __StackTop \n#endif\nextern uint32_t _estack;\n\nnamespace control {\n\n/**\n * Announce that an event happened to registered handlers.\n * @param src ID of the MicroBit Component that generated the event\n * @param value Component specific code indicating the cause of the event.\n */\n//% weight=21 blockGap=12 blockId=\"control_raise_event\"\n//% help=control/raise-event\n//% block=\"raise event|from %src|with value %value\" blockExternalInputs=1\nvoid raiseEvent(int src, int value) {\n    Event evt(src, value);\n}\n\n/**\n* Determine the version of system software currently running.\n*/\n//% blockId=\"control_device_dal_version\" block=\"device dal version\"\n//% help=control/device-dal-version\nString deviceDalVersion() {\n    return mkString(device.getVersion());\n}\n\n/**\n* Allocates the next user notification event\n*/\n//% help=control/allocate-notify-event\nint allocateNotifyEvent() {\n    return ::allocateNotifyEvent();\n}\n\n/** Write a message to DMESG debugging buffer. */\n//%\nvoid dmesg(String s) {\n    DMESG(\"# %s\", s->getUTF8Data());\n}\n\n/** Write a message and value (pointer) to DMESG debugging buffer. */\n//%\nvoid dmesgPtr(String str, Object_ ptr) {\n    DMESG(\"# %s: %p\", str->getUTF8Data(), ptr);\n}\n\n//%\nuint32_t _ramSize()\n{\n    return (uint32_t)&_estack & 0x1fffffff;\n}\n\n}\n","dal.d.ts":"// Auto-generated. Do not edit.\ndeclare const enum DAL {\n    // /libraries/codal-core/inc/JACDAC/JDPhysicalLayer.h\n    Receiving = 0,\n    Transmitting = 1,\n    Error = 2,\n    Unknown = 3,\n    ListeningForPulse = 0,\n    ErrorRecovery = 1,\n    Off = 2,\n    Continuation = 0,\n    // /libraries/codal-core/inc/JACDAC/JDServiceClasses.h\n    STATIC_CLASS_START = 0,\n    STATIC_CLASS_END = 16777215,\n    DYNAMIC_CLASS_END = 4294967295,\n    // /libraries/codal-core/inc/core/CodalComponent.h\n    DEVICE_ID_BUTTON_A = 1,\n    DEVICE_ID_BUTTON_B = 2,\n    DEVICE_ID_BUTTON_AB = 3,\n    DEVICE_ID_BUTTON_RESET = 4,\n    DEVICE_ID_ACCELEROMETER = 5,\n    DEVICE_ID_COMPASS = 6,\n    DEVICE_ID_DISPLAY = 7,\n    DEVICE_ID_THERMOMETER = 8,\n    DEVICE_ID_RADIO = 9,\n    DEVICE_ID_RADIO_DATA_READY = 10,\n    DEVICE_ID_MULTIBUTTON_ATTACH = 11,\n    DEVICE_ID_SERIAL = 12,\n    DEVICE_ID_GESTURE = 13,\n    DEVICE_ID_SYSTEM_TIMER = 14,\n    DEVICE_ID_SCHEDULER = 15,\n    DEVICE_ID_COMPONENT = 16,\n    DEVICE_ID_LIGHT_SENSOR = 17,\n    DEVICE_ID_TOUCH_SENSOR = 18,\n    DEVICE_ID_SYSTEM_DAC = 19,\n    DEVICE_ID_SYSTEM_MICROPHONE = 20,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR = 21,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR_SPL = 22,\n    DEVICE_ID_MSC = 23,\n    DEVICE_ID_SPI = 24,\n    DEVICE_ID_DISTANCE = 25,\n    DEVICE_ID_GYROSCOPE = 26,\n    DEVICE_ID_HUMIDITY = 27,\n    DEVICE_ID_PRESSURE = 28,\n    DEVICE_ID_SINGLE_WIRE_SERIAL = 29,\n    DEVICE_ID_JACDAC = 30,\n    DEVICE_ID_JACDAC_PHYS = 31,\n    DEVICE_ID_JACDAC_CONTROL_SERVICE = 32,\n    DEVICE_ID_JACDAC_CONFIGURATION_SERVICE = 33,\n    DEVICE_ID_IO_P0 = 100,\n    DEVICE_ID_MESSAGE_BUS_LISTENER = 1021,\n    DEVICE_ID_NOTIFY_ONE = 1022,\n    DEVICE_ID_NOTIFY = 1023,\n    DEVICE_ID_BUTTON_UP = 2000,\n    DEVICE_ID_BUTTON_DOWN = 2001,\n    DEVICE_ID_BUTTON_LEFT = 2002,\n    DEVICE_ID_BUTTON_RIGHT = 2003,\n    DEVICE_ID_JD_DYNAMIC_ID = 3000,\n    DEVICE_COMPONENT_RUNNING = 4096,\n    DEVICE_COMPONENT_STATUS_SYSTEM_TICK = 8192,\n    DEVICE_COMPONENT_STATUS_IDLE_TICK = 16384,\n    DEVICE_COMPONENT_LISTENERS_CONFIGURED = 1,\n    DEVICE_COMPONENT_EVT_SYSTEM_TICK = 1,\n    // /libraries/codal-core/inc/core/CodalFiber.h\n    DEVICE_SCHEDULER_RUNNING = 1,\n    DEVICE_SCHEDULER_IDLE = 2,\n    DEVICE_FIBER_FLAG_FOB = 1,\n    DEVICE_FIBER_FLAG_PARENT = 2,\n    DEVICE_FIBER_FLAG_CHILD = 4,\n    DEVICE_FIBER_FLAG_DO_NOT_PAGE = 8,\n    DEVICE_SCHEDULER_EVT_TICK = 1,\n    DEVICE_SCHEDULER_EVT_IDLE = 2,\n    // /libraries/codal-core/inc/core/CodalListener.h\n    MESSAGE_BUS_LISTENER_PARAMETERISED = 1,\n    MESSAGE_BUS_LISTENER_METHOD = 2,\n    MESSAGE_BUS_LISTENER_BUSY = 4,\n    MESSAGE_BUS_LISTENER_REENTRANT = 8,\n    MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY = 16,\n    MESSAGE_BUS_LISTENER_DROP_IF_BUSY = 32,\n    MESSAGE_BUS_LISTENER_NONBLOCKING = 64,\n    MESSAGE_BUS_LISTENER_URGENT = 128,\n    MESSAGE_BUS_LISTENER_DELETING = 32768,\n    MESSAGE_BUS_LISTENER_IMMEDIATE = 192,\n    // /libraries/codal-core/inc/core/ErrorNo.h\n    DEVICE_OK = 0,\n    DEVICE_INVALID_PARAMETER = -1001,\n    DEVICE_NOT_SUPPORTED = -1002,\n    DEVICE_CALIBRATION_IN_PROGRESS = -1003,\n    DEVICE_CALIBRATION_REQUIRED = -1004,\n    DEVICE_NO_RESOURCES = -1005,\n    DEVICE_BUSY = -1006,\n    DEVICE_CANCELLED = -1007,\n    DEVICE_I2C_ERROR = -1010,\n    DEVICE_SERIAL_IN_USE = -1011,\n    DEVICE_NO_DATA = -1012,\n    DEVICE_NOT_IMPLEMENTED = -1013,\n    DEVICE_SPI_ERROR = -1014,\n    DEVICE_INVALID_STATE = -1015,\n    DEVICE_OOM = 20,\n    DEVICE_HEAP_ERROR = 30,\n    DEVICE_NULL_DEREFERENCE = 40,\n    DEVICE_USB_ERROR = 50,\n    DEVICE_JACDAC_ERROR = 60,\n    DEVICE_HARDWARE_CONFIGURATION_ERROR = 90,\n    // /libraries/codal-core/inc/core/NotifyEvents.h\n    DISPLAY_EVT_FREE = 1,\n    CODAL_SERIAL_EVT_TX_EMPTY = 2,\n    BLE_EVT_SERIAL_TX_EMPTY = 3,\n    ARCADE_PLAYER_JOIN_RESULT = 4,\n    DEVICE_NOTIFY_USER_EVENT_BASE = 1024,\n    // /libraries/codal-core/inc/driver-models/AbstractButton.h\n    DEVICE_BUTTON_EVT_DOWN = 1,\n    DEVICE_BUTTON_EVT_UP = 2,\n    DEVICE_BUTTON_EVT_CLICK = 3,\n    DEVICE_BUTTON_EVT_LONG_CLICK = 4,\n    DEVICE_BUTTON_EVT_HOLD = 5,\n    DEVICE_BUTTON_EVT_DOUBLE_CLICK = 6,\n    DEVICE_BUTTON_LONG_CLICK_TIME = 1000,\n    DEVICE_BUTTON_HOLD_TIME = 1500,\n    DEVICE_BUTTON_STATE = 1,\n    DEVICE_BUTTON_STATE_HOLD_TRIGGERED = 2,\n    DEVICE_BUTTON_STATE_CLICK = 4,\n    DEVICE_BUTTON_STATE_LONG_CLICK = 8,\n    DEVICE_BUTTON_SIGMA_MIN = 0,\n    DEVICE_BUTTON_SIGMA_MAX = 12,\n    DEVICE_BUTTON_SIGMA_THRESH_HI = 8,\n    DEVICE_BUTTON_SIGMA_THRESH_LO = 2,\n    DEVICE_BUTTON_DOUBLE_CLICK_THRESH = 50,\n    DEVICE_BUTTON_SIMPLE_EVENTS = 0,\n    DEVICE_BUTTON_ALL_EVENTS = 1,\n    ACTIVE_LOW = 0,\n    ACTIVE_HIGH = 1,\n    // /libraries/codal-core/inc/driver-models/Accelerometer.h\n    ACCELEROMETER_IMU_DATA_VALID = 2,\n    ACCELEROMETER_EVT_DATA_UPDATE = 1,\n    ACCELEROMETER_EVT_NONE = 0,\n    ACCELEROMETER_EVT_TILT_UP = 1,\n    ACCELEROMETER_EVT_TILT_DOWN = 2,\n    ACCELEROMETER_EVT_TILT_LEFT = 3,\n    ACCELEROMETER_EVT_TILT_RIGHT = 4,\n    ACCELEROMETER_EVT_FACE_UP = 5,\n    ACCELEROMETER_EVT_FACE_DOWN = 6,\n    ACCELEROMETER_EVT_FREEFALL = 7,\n    ACCELEROMETER_EVT_3G = 8,\n    ACCELEROMETER_EVT_6G = 9,\n    ACCELEROMETER_EVT_8G = 10,\n    ACCELEROMETER_EVT_SHAKE = 11,\n    ACCELEROMETER_EVT_2G = 12,\n    ACCELEROMETER_REST_TOLERANCE = 200,\n    ACCELEROMETER_TILT_TOLERANCE = 200,\n    ACCELEROMETER_FREEFALL_TOLERANCE = 400,\n    ACCELEROMETER_SHAKE_TOLERANCE = 400,\n    ACCELEROMETER_2G_TOLERANCE = 2048,\n    ACCELEROMETER_3G_TOLERANCE = 3072,\n    ACCELEROMETER_6G_TOLERANCE = 6144,\n    ACCELEROMETER_8G_TOLERANCE = 8192,\n    ACCELEROMETER_GESTURE_DAMPING = 5,\n    ACCELEROMETER_SHAKE_DAMPING = 10,\n    ACCELEROMETER_SHAKE_RTX = 30,\n    ACCELEROMETER_SHAKE_COUNT_THRESHOLD = 4,\n    // /libraries/codal-core/inc/driver-models/Compass.h\n    COMPASS_STATUS_RUNNING = 1,\n    COMPASS_STATUS_CALIBRATED = 2,\n    COMPASS_STATUS_CALIBRATING = 4,\n    COMPASS_STATUS_ADDED_TO_IDLE = 8,\n    COMPASS_EVT_DATA_UPDATE = 1,\n    COMPASS_EVT_CONFIG_NEEDED = 2,\n    COMPASS_EVT_CALIBRATE = 3,\n    COMPASS_EVT_CALIBRATION_NEEDED = 4,\n    // /libraries/codal-core/inc/driver-models/Gyroscope.h\n    GYROSCOPE_IMU_DATA_VALID = 2,\n    GYROSCOPE_EVT_DATA_UPDATE = 1,\n    // /libraries/codal-core/inc/driver-models/LowLevelTimer.h\n    TimerModeTimer = 0,\n    TimerModeCounter = 1,\n    TimerModeAlternateFunction = 2,\n    BitMode8 = 0,\n    BitMode16 = 1,\n    BitMode24 = 2,\n    BitMode32 = 3,\n    // /libraries/codal-core/inc/driver-models/Pin.h\n    IO_STATUS_DIGITAL_IN = 1,\n    IO_STATUS_DIGITAL_OUT = 2,\n    IO_STATUS_ANALOG_IN = 4,\n    IO_STATUS_ANALOG_OUT = 8,\n    IO_STATUS_TOUCH_IN = 16,\n    IO_STATUS_EVENT_ON_EDGE = 32,\n    IO_STATUS_EVENT_PULSE_ON_EDGE = 64,\n    IO_STATUS_INTERRUPT_ON_EDGE = 128,\n    DEVICE_PIN_MAX_OUTPUT = 1023,\n    DEVICE_PIN_MAX_SERVO_RANGE = 180,\n    DEVICE_PIN_DEFAULT_SERVO_RANGE = 2000,\n    DEVICE_PIN_DEFAULT_SERVO_CENTER = 1500,\n    DEVICE_PIN_EVENT_NONE = 0,\n    DEVICE_PIN_INTERRUPT_ON_EDGE = 1,\n    DEVICE_PIN_EVENT_ON_EDGE = 2,\n    DEVICE_PIN_EVENT_ON_PULSE = 3,\n    DEVICE_PIN_EVENT_ON_TOUCH = 4,\n    DEVICE_PIN_EVT_RISE = 2,\n    DEVICE_PIN_EVT_FALL = 3,\n    DEVICE_PIN_EVT_PULSE_HI = 4,\n    DEVICE_PIN_EVT_PULSE_LO = 5,\n    PIN_CAPABILITY_DIGITAL = 1,\n    PIN_CAPABILITY_ANALOG = 2,\n    PIN_CAPABILITY_AD = 3,\n    PIN_CAPABILITY_ALL = 3,\n    None = 0,\n    Down = 1,\n    Up = 2,\n    // /libraries/codal-core/inc/driver-models/Radio.h\n    RADIO_EVT_DATA_READY = 2,\n    // /libraries/codal-core/inc/driver-models/SPIFlash.h\n    SPIFLASH_PAGE_SIZE = 256,\n    SPIFLASH_SMALL_ROW_PAGES = 16,\n    SPIFLASH_BIG_ROW_PAGES = 256,\n    // /libraries/codal-core/inc/driver-models/Sensor.h\n    SENSOR_THRESHOLD_LOW = 1,\n    SENSOR_THRESHOLD_HIGH = 2,\n    SENSOR_UPDATE_NEEDED = 3,\n    SENSOR_INITIALISED = 1,\n    SENSOR_HIGH_THRESHOLD_PASSED = 2,\n    SENSOR_LOW_THRESHOLD_PASSED = 4,\n    SENSOR_LOW_THRESHOLD_ENABLED = 8,\n    SENSOR_HIGH_THRESHOLD_ENABLED = 16,\n    SENSOR_DEFAULT_SENSITIVITY = 868,\n    SENSOR_DEFAULT_SAMPLE_PERIOD = 500,\n    // /libraries/codal-core/inc/driver-models/Serial.h\n    CODAL_SERIAL_DEFAULT_BAUD_RATE = 115200,\n    CODAL_SERIAL_DEFAULT_BUFFER_SIZE = 20,\n    CODAL_SERIAL_EVT_DELIM_MATCH = 1,\n    CODAL_SERIAL_EVT_HEAD_MATCH = 2,\n    CODAL_SERIAL_EVT_RX_FULL = 3,\n    CODAL_SERIAL_EVT_DATA_RECEIVED = 4,\n    CODAL_SERIAL_STATUS_RX_IN_USE = 1,\n    CODAL_SERIAL_STATUS_TX_IN_USE = 2,\n    CODAL_SERIAL_STATUS_RX_BUFF_INIT = 4,\n    CODAL_SERIAL_STATUS_TX_BUFF_INIT = 8,\n    CODAL_SERIAL_STATUS_RXD = 16,\n    ASYNC = 0,\n    SYNC_SPINWAIT = 1,\n    SYNC_SLEEP = 2,\n    RxInterrupt = 0,\n    TxInterrupt = 1,\n    // /libraries/codal-core/inc/driver-models/SingleWireSerial.h\n    SWS_EVT_DATA_RECEIVED = 1,\n    SWS_EVT_DATA_SENT = 2,\n    SWS_EVT_ERROR = 3,\n    SWS_EVT_DATA_DROPPED = 4,\n    SingleWireRx = 0,\n    SingleWireTx = 1,\n    SingleWireDisconnected = 2,\n    // /libraries/codal-core/inc/driver-models/Timer.h\n    CODAL_TIMER_DEFAULT_EVENT_LIST_SIZE = 10,\n    // /libraries/codal-core/inc/drivers/AnalogSensor.h\n    ANALOG_THRESHOLD_LOW = 1,\n    ANALOG_THRESHOLD_HIGH = 2,\n    ANALOG_SENSOR_UPDATE_NEEDED = 3,\n    ANALOG_SENSOR_INITIALISED = 1,\n    ANALOG_SENSOR_HIGH_THRESHOLD_PASSED = 2,\n    ANALOG_SENSOR_LOW_THRESHOLD_PASSED = 4,\n    ANALOG_SENSOR_LOW_THRESHOLD_ENABLED = 8,\n    ANALOG_SENSOR_HIGH_THRESHOLD_ENABLED = 16,\n    // /libraries/codal-core/inc/drivers/AnimatedDisplay.h\n    DISPLAY_EVT_ANIMATION_COMPLETE = 1,\n    DISPLAY_DEFAULT_AUTOCLEAR = 1,\n    DISPLAY_SPACING = 1,\n    DISPLAY_ANIMATE_DEFAULT_POS = -255,\n    DISPLAY_DEFAULT_SCROLL_SPEED = 120,\n    DISPLAY_DEFAULT_SCROLL_STRIDE = -1,\n    DISPLAY_DEFAULT_PRINT_SPEED = 400,\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    // /libraries/codal-core/inc/drivers/FAT.h\n    FAT_RESERVED_SECTORS = 1,\n    FAT_ROOT_DIR_SECTORS = 4,\n    // /libraries/codal-core/inc/drivers/HID.h\n    HID_REQUEST_GET_REPORT = 1,\n    HID_REQUEST_GET_IDLE = 2,\n    HID_REQUEST_GET_PROTOCOL = 3,\n    HID_REQUEST_SET_REPORT = 9,\n    HID_REQUEST_SET_IDLE = 10,\n    HID_REQUEST_SET_PROTOCOL = 11,\n    // /libraries/codal-core/inc/drivers/HIDKeyboard.h\n    HID_KEYBOARD_NUM_REPORTS = 3,\n    HID_KEYBOARD_REPORT_GENERIC = 1,\n    HID_KEYBOARD_REPORT_CONSUMER = 2,\n    HID_KEYBOARD_KEYSTATE_SIZE_GENERIC = 8,\n    HID_KEYBOARD_KEYSTATE_SIZE_CONSUMER = 2,\n    HID_KEYBOARD_MODIFIER_OFFSET = 2,\n    HID_KEYBOARD_DELAY_DEFAULT = 10,\n    PressKey = 0,\n    ReleaseKey = 1,\n    // /libraries/codal-core/inc/drivers/KeyMap.h\n    KEYMAP_ALL_KEYS_UP_Val = 1,\n    KEYMAP_ALL_KEYS_UP_POS = 28,\n    KEYMAP_NORMAL_KEY_Val = 0,\n    KEYMAP_MODIFIER_KEY_Val = 1,\n    KEYMAP_MODIFIER_POS = 29,\n    KEYMAP_MEDIA_KEY_Val = 1,\n    KEYMAP_MEDIA_POS = 30,\n    KEYMAP_KEY_UP_Val = 0,\n    KEYMAP_KEY_DOWN_Val = 1,\n    KEYMAP_KEY_DOWN_POS = 31,\n    // /libraries/codal-core/inc/drivers/KeyValueStorage.h\n    DEVICE_KEY_VALUE_STORE_OFFSET = 4,\n    KEY_VALUE_STORAGE_MAGIC = 49370,\n    KEY_VALUE_STORAGE_BLOCK_SIZE = 48,\n    KEY_VALUE_STORAGE_KEY_SIZE = 16,\n    KEY_VALUE_STORAGE_SCRATCH_WORD_SIZE = 64,\n    KEY_VALUE_STORAGE_MAX_PAIRS = 5,\n    // /libraries/codal-core/inc/drivers/LEDMatrix.h\n    LED_MATRIX_GREYSCALE_BIT_DEPTH = 8,\n    LED_MATRIX_EVT_LIGHT_SENSE = 2,\n    LED_MATRIX_EVT_FRAME_TIMEOUT = 3,\n    LED_MATRIX_MINIMUM_BRIGHTNESS = 1,\n    LED_MATRIX_MAXIMUM_BRIGHTNESS = 255,\n    LED_MATRIX_DEFAULT_BRIGHTNESS = 255,\n    DISPLAY_MODE_BLACK_AND_WHITE = 0,\n    DISPLAY_MODE_GREYSCALE = 1,\n    DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE = 2,\n    MATRIX_DISPLAY_ROTATION_0 = 0,\n    MATRIX_DISPLAY_ROTATION_90 = 1,\n    MATRIX_DISPLAY_ROTATION_180 = 2,\n    MATRIX_DISPLAY_ROTATION_270 = 3,\n    NO_CONN = 0,\n    // /libraries/codal-core/inc/drivers/MMA8653.h\n    MICROBIT_ACCEL_PITCH_ROLL_VALID = 2,\n    MICROBIT_ACCEL_ADDED_TO_IDLE = 4,\n    // /libraries/codal-core/inc/drivers/MultiButton.h\n    MULTI_BUTTON_STATE_1 = 1,\n    MULTI_BUTTON_STATE_2 = 2,\n    MULTI_BUTTON_HOLD_TRIGGERED_1 = 4,\n    MULTI_BUTTON_HOLD_TRIGGERED_2 = 8,\n    MULTI_BUTTON_SUPRESSED_1 = 16,\n    MULTI_BUTTON_SUPRESSED_2 = 32,\n    MULTI_BUTTON_ATTACHED = 64,\n    // /libraries/codal-core/inc/drivers/TouchButton.h\n    TOUCH_BUTTON_CALIBRATION_PERIOD = 10,\n    TOUCH_BUTTON_CALIBRATION_LINEAR_OFFSET = 2,\n    TOUCH_BUTTON_CALIBRATION_PERCENTAGE_OFFSET = 5,\n    TOUCH_BUTTON_CALIBRATING = 16,\n    // /libraries/codal-core/inc/drivers/TouchSensor.h\n    TOUCH_SENSOR_MAX_BUTTONS = 10,\n    TOUCH_SENSOR_SAMPLE_PERIOD = 50,\n    TOUCH_SENSE_SAMPLE_MAX = 1000,\n    TOUCH_SENSOR_UPDATE_NEEDED = 1,\n    // /libraries/codal-core/inc/drivers/USBJACDAC.h\n    JACDAC_USB_STATUS_CLEAR_TO_SEND = 2,\n    // /libraries/codal-core/inc/drivers/USB_HID_Keys.h\n    KEY_MOD_LCTRL = 1,\n    KEY_MOD_LSHIFT = 2,\n    KEY_MOD_LALT = 4,\n    KEY_MOD_LMETA = 8,\n    KEY_MOD_RCTRL = 16,\n    KEY_MOD_RSHIFT = 32,\n    KEY_MOD_RALT = 64,\n    KEY_MOD_RMETA = 128,\n    KEY_NONE = 0,\n    KEY_ERR_OVF = 1,\n    KEY_A = 4,\n    KEY_B = 5,\n    KEY_C = 6,\n    KEY_D = 7,\n    KEY_E = 8,\n    KEY_F = 9,\n    KEY_G = 10,\n    KEY_H = 11,\n    KEY_I = 12,\n    KEY_J = 13,\n    KEY_K = 14,\n    KEY_L = 15,\n    KEY_M = 16,\n    KEY_N = 17,\n    KEY_O = 18,\n    KEY_P = 19,\n    KEY_Q = 20,\n    KEY_R = 21,\n    KEY_S = 22,\n    KEY_T = 23,\n    KEY_U = 24,\n    KEY_V = 25,\n    KEY_W = 26,\n    KEY_X = 27,\n    KEY_Y = 28,\n    KEY_Z = 29,\n    KEY_1 = 30,\n    KEY_2 = 31,\n    KEY_3 = 32,\n    KEY_4 = 33,\n    KEY_5 = 34,\n    KEY_6 = 35,\n    KEY_7 = 36,\n    KEY_8 = 37,\n    KEY_9 = 38,\n    KEY_0 = 39,\n    KEY_ENTER = 40,\n    KEY_ESC = 41,\n    KEY_BACKSPACE = 42,\n    KEY_TAB = 43,\n    KEY_SPACE = 44,\n    KEY_MINUS = 45,\n    KEY_EQUAL = 46,\n    KEY_LEFTBRACE = 47,\n    KEY_RIGHTBRACE = 48,\n    KEY_BACKSLASH = 49,\n    KEY_HASHTILDE = 50,\n    KEY_SEMICOLON = 51,\n    KEY_APOSTROPHE = 52,\n    KEY_GRAVE = 53,\n    KEY_COMMA = 54,\n    KEY_DOT = 55,\n    KEY_SLASH = 56,\n    KEY_CAPSLOCK = 57,\n    KEY_F1 = 58,\n    KEY_F2 = 59,\n    KEY_F3 = 60,\n    KEY_F4 = 61,\n    KEY_F5 = 62,\n    KEY_F6 = 63,\n    KEY_F7 = 64,\n    KEY_F8 = 65,\n    KEY_F9 = 66,\n    KEY_F10 = 67,\n    KEY_F11 = 68,\n    KEY_F12 = 69,\n    KEY_SYSRQ = 70,\n    KEY_SCROLLLOCK = 71,\n    KEY_PAUSE = 72,\n    KEY_INSERT = 73,\n    KEY_HOME = 74,\n    KEY_PAGEUP = 75,\n    KEY_DELETE = 76,\n    KEY_END = 77,\n    KEY_PAGEDOWN = 78,\n    KEY_RIGHT = 79,\n    KEY_LEFT = 80,\n    KEY_DOWN = 81,\n    KEY_UP = 82,\n    KEY_NUMLOCK = 83,\n    KEY_KPSLASH = 84,\n    KEY_KPASTERISK = 85,\n    KEY_KPMINUS = 86,\n    KEY_KPPLUS = 87,\n    KEY_KPENTER = 88,\n    KEY_KP1 = 89,\n    KEY_KP2 = 90,\n    KEY_KP3 = 91,\n    KEY_KP4 = 92,\n    KEY_KP5 = 93,\n    KEY_KP6 = 94,\n    KEY_KP7 = 95,\n    KEY_KP8 = 96,\n    KEY_KP9 = 97,\n    KEY_KP0 = 98,\n    KEY_KPDOT = 99,\n    KEY_102ND = 100,\n    KEY_COMPOSE = 101,\n    KEY_POWER = 102,\n    KEY_KPEQUAL = 103,\n    KEY_F13 = 104,\n    KEY_F14 = 105,\n    KEY_F15 = 106,\n    KEY_F16 = 107,\n    KEY_F17 = 108,\n    KEY_F18 = 109,\n    KEY_F19 = 110,\n    KEY_F20 = 111,\n    KEY_F21 = 112,\n    KEY_F22 = 113,\n    KEY_F23 = 114,\n    KEY_F24 = 115,\n    KEY_OPEN = 116,\n    KEY_HELP = 117,\n    KEY_PROPS = 118,\n    KEY_FRONT = 119,\n    KEY_STOP = 120,\n    KEY_AGAIN = 121,\n    KEY_UNDO = 122,\n    KEY_CUT = 123,\n    KEY_COPY = 124,\n    KEY_PASTE = 125,\n    KEY_FIND = 126,\n    KEY_MUTE = 127,\n    KEY_VOLUMEUP = 128,\n    KEY_VOLUMEDOWN = 129,\n    KEY_KPCOMMA = 133,\n    KEY_RO = 135,\n    KEY_KATAKANAHIRAGANA = 136,\n    KEY_YEN = 137,\n    KEY_HENKAN = 138,\n    KEY_MUHENKAN = 139,\n    KEY_KPJPCOMMA = 140,\n    KEY_HANGEUL = 144,\n    KEY_HANJA = 145,\n    KEY_KATAKANA = 146,\n    KEY_HIRAGANA = 147,\n    KEY_ZENKAKUHANKAKU = 148,\n    KEY_KPLEFTPAREN = 182,\n    KEY_KPRIGHTPAREN = 183,\n    KEY_LEFTCTRL = 224,\n    KEY_LEFTSHIFT = 225,\n    KEY_LEFTALT = 226,\n    KEY_LEFTMETA = 227,\n    KEY_RIGHTCTRL = 228,\n    KEY_RIGHTSHIFT = 229,\n    KEY_RIGHTALT = 230,\n    KEY_RIGHTMETA = 231,\n    KEY_MEDIA_PLAYPAUSE = 232,\n    KEY_MEDIA_STOPCD = 233,\n    KEY_MEDIA_PREVIOUSSONG = 234,\n    KEY_MEDIA_NEXTSONG = 235,\n    KEY_MEDIA_EJECTCD = 236,\n    KEY_MEDIA_VOLUMEUP = 237,\n    KEY_MEDIA_VOLUMEDOWN = 238,\n    KEY_MEDIA_MUTE = 239,\n    KEY_MEDIA_WWW = 240,\n    KEY_MEDIA_BACK = 241,\n    KEY_MEDIA_FORWARD = 242,\n    KEY_MEDIA_STOP = 243,\n    KEY_MEDIA_FIND = 244,\n    KEY_MEDIA_SCROLLUP = 245,\n    KEY_MEDIA_SCROLLDOWN = 246,\n    KEY_MEDIA_EDIT = 247,\n    KEY_MEDIA_SLEEP = 248,\n    KEY_MEDIA_COFFEE = 249,\n    KEY_MEDIA_REFRESH = 250,\n    KEY_MEDIA_CALC = 251,\n    // /libraries/codal-core/inc/drivers/uf2format.h\n    UF2FORMAT_H = 1,\n    APP_START_ADDRESS = 8192,\n    UF2_FLAG_NOFLASH = 1,\n    // /libraries/codal-core/inc/streams/DataStream.h\n    DATASTREAM_MAXIMUM_BUFFERS = 1,\n    // /libraries/codal-core/inc/streams/LevelDetector.h\n    LEVEL_THRESHOLD_LOW = 1,\n    LEVEL_THRESHOLD_HIGH = 2,\n    LEVEL_DETECTOR_INITIALISED = 1,\n    LEVEL_DETECTOR_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_DEFAULT_WINDOW_SIZE = 128,\n    // /libraries/codal-core/inc/streams/LevelDetectorSPL.h\n    LEVEL_DETECTOR_SPL_INITIALISED = 1,\n    LEVEL_DETECTOR_SPL_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_SPL_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_SPL_DEFAULT_WINDOW_SIZE = 128,\n    // /libraries/codal-core/inc/streams/MemorySource.h\n    MEMORY_SOURCE_MAX_BUFFER = 256,\n    // /libraries/codal-core/inc/streams/Synthesizer.h\n    SYNTHESIZER_SAMPLE_RATE = 44100,\n    TONE_WIDTH = 1024,\n    // /libraries/codal-core/inc/types/BitmapFont.h\n    BITMAP_FONT_WIDTH = 5,\n    BITMAP_FONT_HEIGHT = 5,\n    BITMAP_FONT_ASCII_START = 32,\n    BITMAP_FONT_ASCII_END = 126,\n    // /libraries/codal-core/inc/types/CoordinateSystem.h\n    COORDINATE_SPACE_ROTATED_0 = 0,\n    COORDINATE_SPACE_ROTATED_90 = 1,\n    COORDINATE_SPACE_ROTATED_180 = 2,\n    COORDINATE_SPACE_ROTATED_270 = 3,\n    RAW = 0,\n    SIMPLE_CARTESIAN = 1,\n    NORTH_EAST_DOWN = 2,\n    NORTH_EAST_UP = 3,\n    // /libraries/codal-core/inc/types/Event.h\n    DEVICE_ID_ANY = 0,\n    DEVICE_EVT_ANY = 0,\n    CREATE_ONLY = 0,\n    CREATE_AND_FIRE = 1,\n    DEVICE_EVENT_DEFAULT_LAUNCH_MODE = 1,\n    // /libraries/codal-core/inc/types/RefCounted.h\n    REF_TAG_STRING = 1,\n    REF_TAG_BUFFER = 2,\n    REF_TAG_IMAGE = 3,\n    REF_TAG_USER = 32,\n    // /pxtapp/accelerometer/axis.h\n    ACC_SYSTEM = 3,\n    ACC_ROTATION = 0,\n    // /pxtapp/configkeys.h\n    CFG_PIN_NAME_MSK = 65535,\n    CFG_PIN_CONFIG_MSK = 4294901760,\n    CFG_PIN_CONFIG_ACTIVE_LO = 65536,\n    CFG_MAGIC0 = 513675505,\n    CFG_MAGIC1 = 539130489,\n    CFG_PIN_ACCELEROMETER_INT = 1,\n    CFG_PIN_ACCELEROMETER_SCL = 2,\n    CFG_PIN_ACCELEROMETER_SDA = 3,\n    CFG_PIN_BTN_A = 4,\n    CFG_PIN_BTN_B = 5,\n    CFG_PIN_BTN_SLIDE = 6,\n    CFG_PIN_DOTSTAR_CLOCK = 7,\n    CFG_PIN_DOTSTAR_DATA = 8,\n    CFG_PIN_FLASH_CS = 9,\n    CFG_PIN_FLASH_MISO = 10,\n    CFG_PIN_FLASH_MOSI = 11,\n    CFG_PIN_FLASH_SCK = 12,\n    CFG_PIN_LED = 13,\n    CFG_PIN_LIGHT = 14,\n    CFG_PIN_MICROPHONE = 15,\n    CFG_PIN_MIC_CLOCK = 16,\n    CFG_PIN_MIC_DATA = 17,\n    CFG_PIN_MISO = 18,\n    CFG_PIN_MOSI = 19,\n    CFG_PIN_NEOPIXEL = 20,\n    CFG_PIN_RX = 21,\n    CFG_PIN_RXLED = 22,\n    CFG_PIN_SCK = 23,\n    CFG_PIN_SCL = 24,\n    CFG_PIN_SDA = 25,\n    CFG_PIN_SPEAKER_AMP = 26,\n    CFG_PIN_TEMPERATURE = 27,\n    CFG_PIN_TX = 28,\n    CFG_PIN_TXLED = 29,\n    CFG_PIN_IR_OUT = 30,\n    CFG_PIN_IR_IN = 31,\n    CFG_PIN_DISPLAY_SCK = 32,\n    CFG_PIN_DISPLAY_MISO = 33,\n    CFG_PIN_DISPLAY_MOSI = 34,\n    CFG_PIN_DISPLAY_CS = 35,\n    CFG_PIN_DISPLAY_DC = 36,\n    CFG_DISPLAY_WIDTH = 37,\n    CFG_DISPLAY_HEIGHT = 38,\n    CFG_DISPLAY_CFG0 = 39,\n    CFG_DISPLAY_CFG1 = 40,\n    CFG_DISPLAY_CFG2 = 41,\n    CFG_DISPLAY_CFG3 = 42,\n    CFG_PIN_DISPLAY_RST = 43,\n    CFG_PIN_DISPLAY_BL = 44,\n    CFG_PIN_SERVO_1 = 45,\n    CFG_PIN_SERVO_2 = 46,\n    CFG_PIN_BTN_LEFT = 47,\n    CFG_PIN_BTN_RIGHT = 48,\n    CFG_PIN_BTN_UP = 49,\n    CFG_PIN_BTN_DOWN = 50,\n    CFG_PIN_BTN_MENU = 51,\n    CFG_PIN_LED_R = 52,\n    CFG_PIN_LED_G = 53,\n    CFG_PIN_LED_B = 54,\n    CFG_PIN_LED1 = 55,\n    CFG_PIN_LED2 = 56,\n    CFG_PIN_LED3 = 57,\n    CFG_PIN_LED4 = 58,\n    CFG_SPEAKER_VOLUME = 59,\n    CFG_PIN_JACK_TX = 60,\n    CFG_PIN_JACK_SENSE = 61,\n    CFG_PIN_JACK_HPEN = 62,\n    CFG_PIN_JACK_BZEN = 63,\n    CFG_PIN_JACK_PWREN = 64,\n    CFG_PIN_JACK_SND = 65,\n    CFG_PIN_JACK_BUSLED = 66,\n    CFG_PIN_JACK_COMMLED = 67,\n    CFG_PIN_BTN_SOFT_RESET = 69,\n    CFG_ACCELEROMETER_TYPE = 70,\n    CFG_PIN_BTNMX_LATCH = 71,\n    CFG_PIN_BTNMX_CLOCK = 72,\n    CFG_PIN_BTNMX_DATA = 73,\n    CFG_PIN_BTN_MENU2 = 74,\n    CFG_PIN_BATTSENSE = 75,\n    CFG_PIN_VIBRATION = 76,\n    CFG_PIN_PWREN = 77,\n    CFG_DISPLAY_TYPE = 78,\n    CFG_PIN_ROTARY_ENCODER_A = 79,\n    CFG_PIN_ROTARY_ENCODER_B = 80,\n    CFG_ACCELEROMETER_SPACE = 81,\n    CFG_PIN_WIFI_MOSI = 82,\n    CFG_PIN_WIFI_MISO = 83,\n    CFG_PIN_WIFI_SCK = 84,\n    CFG_PIN_WIFI_TX = 85,\n    CFG_PIN_WIFI_RX = 86,\n    CFG_PIN_WIFI_CS = 87,\n    CFG_PIN_WIFI_BUSY = 88,\n    CFG_PIN_WIFI_RESET = 89,\n    CFG_PIN_WIFI_GPIO0 = 90,\n    CFG_PIN_WIFI_AT_TX = 91,\n    CFG_PIN_WIFI_AT_RX = 92,\n    CFG_PIN_USB_POWER = 93,\n    CFG_DISPLAY_DELAY = 94,\n    ACCELEROMETER_TYPE_LIS3DH = 50,\n    ACCELEROMETER_TYPE_LIS3DH_ALT = 48,\n    ACCELEROMETER_TYPE_MMA8453 = 56,\n    ACCELEROMETER_TYPE_FXOS8700 = 60,\n    ACCELEROMETER_TYPE_MMA8653 = 58,\n    ACCELEROMETER_TYPE_MSA300 = 76,\n    ACCELEROMETER_TYPE_MPU6050 = 104,\n    DISPLAY_TYPE_ST7735 = 7735,\n    DISPLAY_TYPE_ILI9341 = 9341,\n    DISPLAY_TYPE_SMART = 4242,\n    CFG_PIN_A0 = 100,\n    CFG_PIN_A1 = 101,\n    CFG_PIN_A2 = 102,\n    CFG_PIN_A3 = 103,\n    CFG_PIN_A4 = 104,\n    CFG_PIN_A5 = 105,\n    CFG_PIN_A6 = 106,\n    CFG_PIN_A7 = 107,\n    CFG_PIN_A8 = 108,\n    CFG_PIN_A9 = 109,\n    CFG_PIN_A10 = 110,\n    CFG_PIN_A11 = 111,\n    CFG_PIN_A12 = 112,\n    CFG_PIN_A13 = 113,\n    CFG_PIN_A14 = 114,\n    CFG_PIN_A15 = 115,\n    CFG_PIN_A16 = 116,\n    CFG_PIN_A17 = 117,\n    CFG_PIN_A18 = 118,\n    CFG_PIN_A19 = 119,\n    CFG_PIN_A20 = 120,\n    CFG_PIN_A21 = 121,\n    CFG_PIN_A22 = 122,\n    CFG_PIN_A23 = 123,\n    CFG_PIN_A24 = 124,\n    CFG_PIN_A25 = 125,\n    CFG_PIN_A26 = 126,\n    CFG_PIN_A27 = 127,\n    CFG_PIN_A28 = 128,\n    CFG_PIN_A29 = 129,\n    CFG_PIN_A30 = 130,\n    CFG_PIN_A31 = 131,\n    CFG_PIN_D0 = 150,\n    CFG_PIN_D1 = 151,\n    CFG_PIN_D2 = 152,\n    CFG_PIN_D3 = 153,\n    CFG_PIN_D4 = 154,\n    CFG_PIN_D5 = 155,\n    CFG_PIN_D6 = 156,\n    CFG_PIN_D7 = 157,\n    CFG_PIN_D8 = 158,\n    CFG_PIN_D9 = 159,\n    CFG_PIN_D10 = 160,\n    CFG_PIN_D11 = 161,\n    CFG_PIN_D12 = 162,\n    CFG_PIN_D13 = 163,\n    CFG_PIN_D14 = 164,\n    CFG_PIN_D15 = 165,\n    CFG_PIN_D16 = 166,\n    CFG_PIN_D17 = 167,\n    CFG_PIN_D18 = 168,\n    CFG_PIN_D19 = 169,\n    CFG_PIN_D20 = 170,\n    CFG_PIN_D21 = 171,\n    CFG_PIN_D22 = 172,\n    CFG_PIN_D23 = 173,\n    CFG_PIN_D24 = 174,\n    CFG_PIN_D25 = 175,\n    CFG_PIN_D26 = 176,\n    CFG_PIN_D27 = 177,\n    CFG_PIN_D28 = 178,\n    CFG_PIN_D29 = 179,\n    CFG_PIN_D30 = 180,\n    CFG_PIN_D31 = 181,\n    CFG_NUM_NEOPIXELS = 200,\n    CFG_NUM_DOTSTARS = 201,\n    CFG_DEFAULT_BUTTON_MODE = 202,\n    CFG_SWD_ENABLED = 203,\n    CFG_FLASH_BYTES = 204,\n    CFG_RAM_BYTES = 205,\n    CFG_SYSTEM_HEAP_BYTES = 206,\n    CFG_LOW_MEM_SIMULATION_KB = 207,\n    CFG_BOOTLOADER_BOARD_ID = 208,\n    CFG_UF2_FAMILY = 209,\n    CFG_PINS_PORT_SIZE = 210,\n    CFG_BOOTLOADER_PROTECTION = 211,\n    CFG_POWER_DEEPSLEEP_TIMEOUT = 212,\n    CFG_ANALOG_BUTTON_THRESHOLD = 213,\n    CFG_CPU_MHZ = 214,\n    CFG_CONTROLLER_LIGHT_MAX_BRIGHTNESS = 215,\n    CFG_ANALOG_JOYSTICK_MIN = 216,\n    CFG_ANALOG_JOYSTICK_MAX = 217,\n    CFG_TIMERS_TO_USE = 218,\n    CFG_PIN_ONBOARD_DOTSTAR_CLOCK = 219,\n    CFG_PIN_ONBOARD_DOTSTAR_DATA = 220,\n    CFG_NUM_ONBOARD_DOTSTARS = 221,\n    CFG_PIN_ONBOARD_NEOPIXEL = 222,\n    CFG_NUM_ONBOARD_NEOPIXELS = 223,\n    CFG_MATRIX_KEYPAD_MESSAGE_ID = 239,\n    CFG_NUM_MATRIX_KEYPAD_ROWS = 240,\n    CFG_PIN_MATRIX_KEYPAD_ROW0 = 241,\n    CFG_PIN_MATRIX_KEYPAD_ROW1 = 242,\n    CFG_PIN_MATRIX_KEYPAD_ROW2 = 243,\n    CFG_PIN_MATRIX_KEYPAD_ROW3 = 244,\n    CFG_PIN_MATRIX_KEYPAD_ROW4 = 245,\n    CFG_PIN_MATRIX_KEYPAD_ROW5 = 246,\n    CFG_PIN_MATRIX_KEYPAD_ROW6 = 247,\n    CFG_PIN_MATRIX_KEYPAD_ROW7 = 248,\n    CFG_NUM_MATRIX_KEYPAD_COLS = 250,\n    CFG_PIN_MATRIX_KEYPAD_COL0 = 251,\n    CFG_PIN_MATRIX_KEYPAD_COL1 = 252,\n    CFG_PIN_MATRIX_KEYPAD_COL2 = 253,\n    CFG_PIN_MATRIX_KEYPAD_COL3 = 254,\n    CFG_PIN_MATRIX_KEYPAD_COL4 = 255,\n    CFG_PIN_MATRIX_KEYPAD_COL5 = 256,\n    CFG_PIN_MATRIX_KEYPAD_COL6 = 257,\n    CFG_PIN_MATRIX_KEYPAD_COL7 = 258,\n    CFG_PIN_B0 = 300,\n    CFG_PIN_B1 = 301,\n    CFG_PIN_B2 = 302,\n    CFG_PIN_B3 = 303,\n    CFG_PIN_B4 = 304,\n    CFG_PIN_B5 = 305,\n    CFG_PIN_B6 = 306,\n    CFG_PIN_B7 = 307,\n    CFG_PIN_B8 = 308,\n    CFG_PIN_B9 = 309,\n    CFG_PIN_B10 = 310,\n    CFG_PIN_B11 = 311,\n    CFG_PIN_B12 = 312,\n    CFG_PIN_B13 = 313,\n    CFG_PIN_B14 = 314,\n    CFG_PIN_B15 = 315,\n    CFG_PIN_B16 = 316,\n    CFG_PIN_B17 = 317,\n    CFG_PIN_B18 = 318,\n    CFG_PIN_B19 = 319,\n    CFG_PIN_B20 = 320,\n    CFG_PIN_B21 = 321,\n    CFG_PIN_B22 = 322,\n    CFG_PIN_B23 = 323,\n    CFG_PIN_B24 = 324,\n    CFG_PIN_B25 = 325,\n    CFG_PIN_B26 = 326,\n    CFG_PIN_B27 = 327,\n    CFG_PIN_B28 = 328,\n    CFG_PIN_B29 = 329,\n    CFG_PIN_B30 = 330,\n    CFG_PIN_B31 = 331,\n    CFG_PIN_C0 = 350,\n    CFG_PIN_C1 = 351,\n    CFG_PIN_C2 = 352,\n    CFG_PIN_C3 = 353,\n    CFG_PIN_C4 = 354,\n    CFG_PIN_C5 = 355,\n    CFG_PIN_C6 = 356,\n    CFG_PIN_C7 = 357,\n    CFG_PIN_C8 = 358,\n    CFG_PIN_C9 = 359,\n    CFG_PIN_C10 = 360,\n    CFG_PIN_C11 = 361,\n    CFG_PIN_C12 = 362,\n    CFG_PIN_C13 = 363,\n    CFG_PIN_C14 = 364,\n    CFG_PIN_C15 = 365,\n    CFG_PIN_C16 = 366,\n    CFG_PIN_C17 = 367,\n    CFG_PIN_C18 = 368,\n    CFG_PIN_C19 = 369,\n    CFG_PIN_C20 = 370,\n    CFG_PIN_C21 = 371,\n    CFG_PIN_C22 = 372,\n    CFG_PIN_C23 = 373,\n    CFG_PIN_C24 = 374,\n    CFG_PIN_C25 = 375,\n    CFG_PIN_C26 = 376,\n    CFG_PIN_C27 = 377,\n    CFG_PIN_C28 = 378,\n    CFG_PIN_C29 = 379,\n    CFG_PIN_C30 = 380,\n    CFG_PIN_C31 = 381,\n    CFG_PIN_P0 = 400,\n    CFG_PIN_P1 = 401,\n    CFG_PIN_P2 = 402,\n    CFG_PIN_P3 = 403,\n    CFG_PIN_P4 = 404,\n    CFG_PIN_P5 = 405,\n    CFG_PIN_P6 = 406,\n    CFG_PIN_P7 = 407,\n    CFG_PIN_P8 = 408,\n    CFG_PIN_P9 = 409,\n    CFG_PIN_P10 = 410,\n    CFG_PIN_P11 = 411,\n    CFG_PIN_P12 = 412,\n    CFG_PIN_P13 = 413,\n    CFG_PIN_P14 = 414,\n    CFG_PIN_P15 = 415,\n    CFG_PIN_P16 = 416,\n    CFG_PIN_P17 = 417,\n    CFG_PIN_P18 = 418,\n    CFG_PIN_P19 = 419,\n    CFG_PIN_P20 = 420,\n    CFG_PIN_P21 = 421,\n    CFG_PIN_P22 = 422,\n    CFG_PIN_P23 = 423,\n    CFG_PIN_P24 = 424,\n    CFG_PIN_P25 = 425,\n    CFG_PIN_P26 = 426,\n    CFG_PIN_P27 = 427,\n    CFG_PIN_P28 = 428,\n    CFG_PIN_P29 = 429,\n    CFG_PIN_P30 = 430,\n    CFG_PIN_P31 = 431,\n    CFG_PIN_LORA_MISO = 1001,\n    CFG_PIN_LORA_MOSI = 1002,\n    CFG_PIN_LORA_SCK = 1003,\n    CFG_PIN_LORA_CS = 1004,\n    CFG_PIN_LORA_BOOT = 1005,\n    CFG_PIN_LORA_RESET = 1006,\n    CFG_PIN_IRRXLED = 1007,\n    CFG_PIN_IRTXLED = 1008,\n    CFG_PIN_LCD_RESET = 1009,\n    CFG_PIN_LCD_ENABLE = 1010,\n    CFG_PIN_LCD_DATALINE4 = 1011,\n    CFG_PIN_LCD_DATALINE5 = 1012,\n    CFG_PIN_LCD_DATALINE6 = 1013,\n    CFG_PIN_LCD_DATALINE7 = 1014,\n    CFG_NUM_LCD_COLUMNS = 1015,\n    CFG_NUM_LCD_ROWS = 1016,\n    CFG_PIN_RCC0 = 1017,\n    CFG_PIN_RCC1 = 1018,\n    CFG_PIN_RCC2 = 1019,\n    CFG_PIN_RCC3 = 1020,\n    CFG_PIN_RCC4 = 1021,\n    CFG_PIN_RCC5 = 1022,\n    CFG_PIN_RCC6 = 1023,\n    CFG_PIN_RCC7 = 1024,\n    CFG_PIN_SERVO0 = 1025,\n    CFG_PIN_SERVO1 = 1026,\n    CFG_PIN_SERVO2 = 1027,\n    CFG_PIN_SERVO3 = 1028,\n    CFG_PIN_SERVO4 = 1029,\n    CFG_PIN_SERVO5 = 1030,\n    CFG_PIN_SERVO6 = 1031,\n    CFG_PIN_SERVO7 = 1032,\n    CFG_PIN_SERVO8 = 1033,\n    CFG_PIN_PI_TX = 1034,\n    CFG_PIN_PI_RX = 1035,\n    CFG_PIN_GPS_SDA = 1036,\n    CFG_PIN_GPS_SCL = 1037,\n    CFG_PIN_GPS_TX = 1038,\n    CFG_PIN_GPS_RX = 1039,\n    CFG_PIN_GROVE0 = 1040,\n    CFG_PIN_GROVE1 = 1041,\n    CFG_PIN_SS = 1042,\n    CFG_USER_CFG_0 = 2000,\n    CFG_USER_CFG_1 = 2001,\n    CFG_USER_CFG_2 = 2002,\n    CFG_USER_CFG_3 = 2003,\n    CFG_USER_CFG_4 = 2004,\n    CFG_USER_CFG_5 = 2005,\n    CFG_USER_CFG_6 = 2006,\n    CFG_USER_CFG_7 = 2007,\n    CFG_USER_CFG_8 = 2008,\n    CFG_USER_CFG_9 = 2009,\n    CFG_ARCADE_CFG_0 = 2100,\n    CFG_ARCADE_CFG_1 = 2101,\n    CFG_ARCADE_SCREEN_WIDTH = 2102,\n    CFG_ARCADE_SCREEN_HEIGHT = 2103,\n    // /pxtapp/hf2dbg.h\n    HF2DBG_H = 1,\n    // /pxtapp/jacdac/jdprotocol.h\n    JDSPI_MAGIC = 31437,\n    JDSPI_MAGIC_NOOP = 46029,\n    // /pxtapp/mixer---stm32/melody.h\n    OUTPUT_BITS = 10,\n    SW_TRIANGLE = 1,\n    SW_SAWTOOTH = 2,\n    SW_SINE = 3,\n    SW_NOISE = 5,\n    SW_SQUARE_10 = 11,\n    SW_SQUARE_50 = 15,\n    CODAL = 1,\n    MAX_SOUNDS = 5,\n    Waiting = 0,\n    Playing = 1,\n    Done = 2,\n    // /pxtapp/pins.h\n    BUTTON_ACTIVE_HIGH_PULL_DOWN = 17,\n    BUTTON_ACTIVE_HIGH_PULL_UP = 33,\n    BUTTON_ACTIVE_HIGH_PULL_NONE = 49,\n    BUTTON_ACTIVE_LOW_PULL_DOWN = 16,\n    BUTTON_ACTIVE_LOW_PULL_UP = 32,\n    BUTTON_ACTIVE_LOW_PULL_NONE = 48,\n    // /pxtapp/platform.h\n    SETTINGS_MAGIC_0 = 273114691,\n    SETTINGS_MAGIC_1 = 781864998,\n    BOOT_RTC_SIGNATURE = 1906448503,\n    APP_RTC_SIGNATURE = 614608146,\n    PAGE_SIZE = 1024,\n    DEV_NUM_PINS = 64,\n    IMAGE_BITS = 4,\n    PA_0 = 0,\n    PA_1 = 1,\n    PA_2 = 2,\n    PA_3 = 3,\n    PA_4 = 4,\n    PA_5 = 5,\n    PA_6 = 6,\n    PA_7 = 7,\n    PA_8 = 8,\n    PA_9 = 9,\n    PA_10 = 10,\n    PA_11 = 11,\n    PA_12 = 12,\n    PA_13 = 13,\n    PA_14 = 14,\n    PA_15 = 15,\n    PB_0 = 16,\n    PB_1 = 17,\n    PB_2 = 18,\n    PB_3 = 19,\n    PB_4 = 20,\n    PB_5 = 21,\n    PB_6 = 22,\n    PB_7 = 23,\n    PB_8 = 24,\n    PB_9 = 25,\n    PB_10 = 26,\n    PB_11 = 27,\n    PB_12 = 28,\n    PB_13 = 29,\n    PB_14 = 30,\n    PB_15 = 31,\n    PC_0 = 32,\n    PC_1 = 33,\n    PC_2 = 34,\n    PC_3 = 35,\n    PC_4 = 36,\n    PC_5 = 37,\n    PC_6 = 38,\n    PC_7 = 39,\n    PC_8 = 40,\n    PC_9 = 41,\n    PC_10 = 42,\n    PC_11 = 43,\n    PC_12 = 44,\n    PC_13 = 45,\n    PC_14 = 46,\n    PC_15 = 47,\n    PD_0 = 48,\n    PD_1 = 49,\n    PD_2 = 50,\n    PD_3 = 51,\n    PD_4 = 52,\n    PD_5 = 53,\n    PD_6 = 54,\n    PD_7 = 55,\n    PD_8 = 56,\n    PD_9 = 57,\n    PD_10 = 58,\n    PD_11 = 59,\n    PD_12 = 60,\n    PD_13 = 61,\n    PD_14 = 62,\n    PD_15 = 63,\n    // /pxtapp/pxt.h\n    DEVICE_ID_BUTTON_SLIDE = 3000,\n    DEVICE_ID_MICROPHONE = 3001,\n    DEVICE_ID_FIRST_BUTTON = 4000,\n    DEVICE_ID_FIRST_TOUCHBUTTON = 4100,\n    PXT_INTERNAL_KEY_UP = 2050,\n    PXT_INTERNAL_KEY_DOWN = 2051,\n    // /pxtapp/pxtbase.h\n    PXT32 = 1,\n    PXT64 = 1,\n    PXT_REFCNT_FLASH = 65534,\n    VTABLE_MAGIC = 249,\n    Undefined = 0,\n    Boolean = 1,\n    Number = 2,\n    String = 3,\n    Object = 4,\n    Function = 5,\n    BoxedString = 1,\n    BoxedNumber = 2,\n    BoxedBuffer = 3,\n    RefAction = 4,\n    RefImage = 5,\n    RefCollection = 6,\n    RefRefLocal = 7,\n    RefMap = 8,\n    RefMImage = 9,\n    MMap = 10,\n    User0 = 16,\n    PXT_IOS_HEAP_ALLOC_BITS = 20,\n    IMAGE_HEADER_MAGIC = 135,\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    UInt32LE = 11,\n    UInt32BE = 12,\n    Float32LE = 13,\n    Float64LE = 14,\n    Float32BE = 15,\n    Float64BE = 16,\n    NUM_TRY_FRAME_REGS = 3,\n    GC = 0,\n    // /pxtapp/pxtconfig.h\n    PXT_UF2_FAMILY = 1467308631,\n    // /pxtapp/settings/Flash.h\n    DEVICE_FLASH_ERROR = 922,\n    // /pxtapp/settings/RAFFS.h\n    RAFFS_FOLLOWING_MASK = 32768,\n    RAFFS_FLASH_BUFFER_SIZE = 64,\n    // /pxtapp/uf2hid.h\n    UF2_HID_H = 1,\n}\n","dmac.cpp":"#include \"dmac.h\"\n\nnamespace pxt {\n\n#ifdef CODAL_DMAC\nSINGLETON(WDMAC);\n#endif\n\n}","dmac.h":"#ifndef __DMAC_H\n#define __DMAC_H\n\n#include \"pxt.h\"\n\nnamespace pxt {\n\n#ifdef CODAL_DMAC\nclass WDMAC {\n  public:\n    CODAL_DMAC dmac;\n\n    WDMAC() {}\n};\n\nWDMAC* getWDMAC();\n#endif\n\n}\n\n#endif","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum PulseValue {\n    //% block=high\n    High = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=low\n    Low = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    }\n\n\n    declare const enum PinEvent {\n    //% block=\"pulse high\"\n    PulseHigh = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=\"pulse low\"\n    PulseLow = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    //% block=\"rise\"\n    Rise = 2,  // DEVICE_PIN_EVT_RISE\n    //% block=\"fall\"\n    Fall = 3,  // DEVICE_PIN_EVT_FALL\n    }\n\n\n    declare const enum PinPullMode {\n    //% block=\"down\"\n    PullDown = 0,\n    //% block=\"up\"\n    PullUp = 1,\n    //% block=\"none\"\n    PullNone = 2,\n    }\n\n// Auto-generated. Do not edit. Really.\n","hf2.cpp":"#include \"pxt.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#ifndef USB_HANDOVER\n#define USB_HANDOVER 1\n#endif\n\n#if USB_HANDOVER\n#define UF2_DEFINE_HANDOVER 1\n#endif\n\n#include \"uf2format.h\"\n\nstatic void *stackCopy;\nstatic uint32_t stackSize;\n\n//#define LOG DMESG\n#define LOG(...) ((void)0)\n\nstatic volatile bool resume = false;\n\nusing namespace codal;\n\n#ifdef HF2_HID\nstatic const char hidDescriptor[] = {\n    0x06, 0x97, 0xFF, // usage page vendor 0x97 (usage 0xff97 0x0001)\n    0x09, 0x01,       // usage 1\n    0xA1, 0x01,       // collection - application\n    0x15, 0x00,       // logical min 0\n    0x26, 0xFF, 0x00, // logical max 255\n    0x75, 8,          // report size 8\n    0x95, 64,         // report count 64\n    0x09, 0x01,       // usage 1\n    0x81, 0x02,       // input: data, variable, absolute\n    0x95, 64,         // report count 64\n    0x09, 0x01,       // usage 1\n    0x91, 0x02,       // output: data, variable, absolute\n    0x95, 1,          // report count 1\n    0x09, 0x01,       // usage 1\n    0xB1, 0x02,       // feature: data, variable, absolute\n    0xC0,             // end\n};\n\nstatic const HIDReportDescriptor reportDesc = {\n    9,\n    0x21,                  // HID\n    0x100,                 // hidbcd 1.00\n    0x00,                  // country code\n    0x01,                  // num desc\n    0x22,                  // report desc type\n    sizeof(hidDescriptor), // size of 0x22\n};\n\nstatic const InterfaceInfo ifaceInfoHID = {\n    &reportDesc,\n    sizeof(reportDesc),\n    1,\n    {\n        2,    // numEndpoints\n        0x03, /// class code - HID\n        0x00, // subclass\n        0x00, // protocol\n        0x02, // string\n        0x00, // alt\n    },\n    {USB_EP_TYPE_INTERRUPT, 1},\n    {USB_EP_TYPE_INTERRUPT, 1},\n};\n#endif\n\nstatic const InterfaceInfo ifaceInfoEP = {\n    NULL,\n    0,\n    2,\n    {\n        2,    // numEndpoints\n        0xff, /// class code - vendor-specific\n        42,   // subclass\n        1,    // protocol\n        0x02, // string\n        0x00, // alt\n    },\n    {USB_EP_TYPE_BULK, 0},\n    {USB_EP_TYPE_BULK, 0},\n};\n\nint HF2::stdRequest(UsbEndpointIn &ctrl, USBSetup &setup) {\n#ifdef HF2_HID\n    if (!useHID)\n        return DEVICE_NOT_SUPPORTED;\n    if (setup.bRequest == USB_REQ_GET_DESCRIPTOR) {\n        if (setup.wValueH == 0x21) {\n            InterfaceDescriptor tmp;\n            fillInterfaceInfo(&tmp);\n            return ctrl.write(&tmp, sizeof(tmp));\n        } else if (setup.wValueH == 0x22) {\n            return ctrl.write(hidDescriptor, sizeof(hidDescriptor));\n        }\n    }\n#endif\n    return DEVICE_NOT_SUPPORTED;\n}\n\n#define HF2_FLAG_EVENT 0x01\n\nREAL_TIME_FUNC\nvoid HF2::sendBuffer(uint8_t flag, const void *data, unsigned size, uint32_t prepend) {\n    if (!CodalUSB::usbInstance->isInitialised())\n        return;\n\n#ifdef USB_EP_FLAG_ASYNC\n    // drop non-responses if too much stuff queued up\n    if (flag != HF2_FLAG_CMDPKT_LAST && pendingWriteSize > 1000)\n        return;\n#endif\n\n    if (flag == HF2_FLAG_EVENT)\n        flag = HF2_FLAG_CMDPKT_LAST;\n\n    if (prepend + 1)\n        size += 4;\n\n#ifdef USB_EP_FLAG_ASYNC\n    HF2_PendingWrite *e = (HF2_PendingWrite *)malloc(sizeof(HF2_PendingWrite) + size);\n    e->size = size;\n    e->flag = flag;\n    e->next = NULL;\n    uint8_t *dst = e->data;\n    if (prepend + 1) {\n        memcpy(dst, &prepend, 4);\n        dst += 4;\n        size -= 4;\n    }\n    memcpy(dst, data, size);\n\n    target_disable_irq();\n    auto p = this->pendingWrite;\n    if (!p)\n        this->pendingWrite = e;\n    else {\n        while (p->next)\n            p = p->next;\n        p->next = e;\n    }\n    this->pendingWriteSize += 16 + e->size;\n    target_enable_irq();\n\n    pokeSend();\n#else\n    uint32_t buf[64 / 4]; // aligned\n\n    target_disable_irq();\n    while (size > 0) {\n        memset(buf + 1, 0, 60);\n        int s = 63;\n        if (size <= 63) {\n            s = size;\n            buf[0] = flag;\n        } else {\n            buf[0] = flag == HF2_FLAG_CMDPKT_LAST ? HF2_FLAG_CMDPKT_BODY : flag;\n        }\n        buf[0] |= s;\n        uint8_t *dst = (uint8_t *)buf;\n        dst++;\n        if (prepend + 1) {\n            memcpy(dst, &prepend, 4);\n            prepend = -1;\n            dst += 4;\n            s -= 4;\n            size -= 4;\n        }\n        memcpy(dst, data, s);\n        data = (const uint8_t *)data + s;\n        size -= s;\n\n        in->write(buf, sizeof(buf));\n    }\n    target_enable_irq();\n#endif\n}\n\nconst InterfaceInfo *HF2::getInterfaceInfo() {\n#ifdef HF2_HID\n    if (useHID)\n        return &ifaceInfoHID;\n#endif\n    return &ifaceInfoEP;\n}\n\nint HF2::sendEvent(uint32_t evId, const void *data, int size) {\n    sendBuffer(HF2_FLAG_EVENT, data, size, evId);\n    return 0;\n}\n\nint HF2::sendSerial(const void *data, int size, int isError) {\n    if (!gotSomePacket)\n        return DEVICE_OK;\n\n    sendBuffer(isError ? HF2_FLAG_SERIAL_ERR : HF2_FLAG_SERIAL_OUT, data, size);\n\n    return 0;\n}\n\n// Receive HF2 message\n// Does not block. Will store intermediate data in pkt.\n// `serial` flag is cleared if we got a command message.\nint HF2::recv() {\n    uint8_t buf[64];\n\n    int len = out->read(buf, sizeof(buf));\n    // DMESG(\"HF2 read: %d\", len);\n\n    if (len <= 0)\n        return len;\n\n    uint8_t tag = buf[0];\n    // serial packets not allowed when in middle of command packet\n    usb_assert(pkt.size == 0 || !(tag & HF2_FLAG_SERIAL_OUT));\n    int size = tag & HF2_SIZE_MASK;\n    usb_assert(pkt.size + size <= (int)sizeof(pkt.buf));\n    memcpy(pkt.buf + pkt.size, buf + 1, size);\n    pkt.size += size;\n    tag &= HF2_FLAG_MASK;\n    if (tag != HF2_FLAG_CMDPKT_BODY) {\n        if (tag == HF2_FLAG_CMDPKT_LAST)\n            pkt.serial = 0;\n        else if (tag == HF2_FLAG_SERIAL_OUT)\n            pkt.serial = 1;\n        else\n            pkt.serial = 2;\n        int sz = pkt.size;\n        pkt.size = 0;\n        return sz;\n    }\n    return 0;\n}\n\nint HF2::sendResponse(int size) {\n    sendBuffer(HF2_FLAG_CMDPKT_LAST, pkt.buf, 4 + size);\n    return 0;\n}\n\nint HF2::sendResponseWithData(const void *data, int size) {\n    if (size <= (int)sizeof(pkt.buf) - 4) {\n        memcpy(pkt.resp.data8, data, size);\n        return sendResponse(size);\n    } else {\n        sendBuffer(HF2_FLAG_CMDPKT_LAST, data, size, pkt.resp.eventId);\n        return 0;\n    }\n}\n\nstatic void copy_words(void *dst0, const void *src0, uint32_t n_words) {\n    uint32_t *dst = (uint32_t *)dst0;\n    const uint32_t *src = (const uint32_t *)src0;\n    while (n_words--)\n        *dst++ = *src++;\n}\n\n#ifndef QUICK_BOOT\n#ifdef SAMD21\n#define DBL_TAP_PTR ((volatile uint32_t *)(HMCRAMC0_ADDR + HMCRAMC0_SIZE - 4))\n#endif\n#ifdef SAMD51\n#define DBL_TAP_PTR ((volatile uint32_t *)(HSRAM_ADDR + HSRAM_SIZE - 4))\n#endif\n#if defined(NRF52840) || defined(NRF52833)\n#define DBL_TAP_PTR ((volatile uint32_t *)0x20007F7C)\n#endif\n#ifdef DBL_TAP_PTR\n#define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef\n#define QUICK_BOOT(v) *DBL_TAP_PTR = v ? DBL_TAP_MAGIC_QUICK_BOOT : 0\n#endif\n#endif\n\nstatic HF2 *jdLogger;\nstatic void jdLog(const uint8_t *frame) {\n    jdLogger->sendEvent(HF2_EV_JDS_PACKET, frame, frame[2] + 12);\n}\n\nvoid HF2::pokeSend() {\n#ifdef USB_EP_FLAG_ASYNC\n    target_disable_irq();\n    while (pendingWrite && in->canWrite()) {\n        in->flags |= USB_EP_FLAG_ASYNC;\n\n        int size = pendingWrite->size - pendingWritePtr;\n        usb_assert(size > 0);\n        uint32_t buf[64 / 4] = {0};\n\n        int s = 63;\n        if (size <= 63) {\n            s = size;\n            buf[0] = pendingWrite->flag;\n        } else {\n            buf[0] = pendingWrite->flag == HF2_FLAG_CMDPKT_LAST ? HF2_FLAG_CMDPKT_BODY\n                                                                : pendingWrite->flag;\n        }\n        buf[0] |= s;\n        uint8_t *dst = (uint8_t *)buf;\n        dst++;\n        memcpy(dst, pendingWrite->data + pendingWritePtr, s);\n\n        int r = in->write(buf, sizeof(buf));\n        if (r == 0) {\n            if (s == size) {\n                pendingWritePtr = 0;\n                pendingWriteSize -= 16 + pendingWrite->size;\n                HF2_PendingWrite *n = pendingWrite->next;\n                free(pendingWrite);\n                pendingWrite = n;\n            } else {\n                pendingWritePtr += s;\n            }\n        }\n    }\n    target_enable_irq();\n#endif\n}\n\nint HF2::endpointRequest() {\n#ifdef USB_EP_FLAG_ASYNC\n    pokeSend();\n#endif\n\n    int sz = recv();\n\n    if (!sz)\n        return 0;\n\n    uint32_t tmp;\n\n    if (pkt.serial) {\n        // TODO raise some event?\n        return 0;\n    }\n\n    LOG(\"HF2 sz=%d CMD=%x\", sz, pkt.buf32[0]);\n\n    // one has to be careful dealing with these, as they share memory\n    HF2_Command *cmd = &pkt.cmd;\n    HF2_Response *resp = &pkt.resp;\n\n    uint32_t cmdId = cmd->command_id;\n    resp->tag = cmd->tag;\n    resp->status16 = HF2_STATUS_OK;\n\n#define checkDataSize(str, add) usb_assert(sz == 8 + (int)sizeof(cmd->str) + (int)(add))\n\n    lastExchange = current_time_ms();\n    gotSomePacket = true;\n\n    switch (cmdId) {\n    case HF2_CMD_INFO:\n        return sendResponseWithData(uf2_info(), strlen(uf2_info()));\n\n    case HF2_CMD_BININFO:\n        resp->bininfo.mode = HF2_MODE_USERSPACE;\n        resp->bininfo.flash_page_size = 0;\n        resp->bininfo.flash_num_pages = 0;\n        resp->bininfo.max_message_size = sizeof(pkt.buf);\n        resp->bininfo.uf2_family = PXT_UF2_FAMILY;\n        return sendResponse(sizeof(resp->bininfo));\n\n    case HF2_DBG_RESTART:\n        *HF2_DBG_MAGIC_PTR = HF2_DBG_MAGIC_START;\n        target_reset();\n        break;\n\n#ifdef QUICK_BOOT\n    case HF2_CMD_RESET_INTO_APP:\n        QUICK_BOOT(1);\n        NVIC_SystemReset();\n        break;\n    case HF2_CMD_RESET_INTO_BOOTLOADER:\n        QUICK_BOOT(0);\n        NVIC_SystemReset();\n        break;\n#else\n    case HF2_CMD_RESET_INTO_APP:\n        NVIC_SystemReset();\n        break;\n    // reset into bootloader not supported\n#endif\n\n#if USB_HANDOVER\n    case HF2_CMD_START_FLASH:\n        sendResponse(0);\n        hf2_handover(in->ep);\n        usb_assert(0); // should not be reached\n        break;\n#endif\n\n    case HF2_CMD_WRITE_WORDS:\n        checkDataSize(write_words, cmd->write_words.num_words << 2);\n        copy_words((void *)cmd->write_words.target_addr, cmd->write_words.words,\n                   cmd->write_words.num_words);\n        break;\n\n    case HF2_CMD_READ_WORDS:\n        checkDataSize(read_words, 0);\n        tmp = cmd->read_words.num_words;\n        usb_assert(tmp <= sizeof(pkt.buf) / 4 - 1);\n        copy_words(resp->data32, (void *)cmd->read_words.target_addr, tmp);\n        return sendResponse(tmp << 2);\n\n    case HF2_CMD_DMESG:\n#if DEVICE_DMESG_BUFFER_SIZE > 0\n        return sendResponseWithData(codalLogStore.buffer, codalLogStore.ptr);\n#else\n        break;\n#endif\n\n    case HF2_DBG_GET_GLOBAL_STATE: {\n        HF2_GLOBAL_STATE_Result gstate = {\n            .num_globals = (uint32_t)getNumGlobals(), //\n            .globals_addr = (uint32_t)globals,\n        };\n        return sendResponseWithData(&gstate, sizeof(gstate));\n    }\n\n    case HF2_DBG_RESUME:\n        globals[0] = (TValue)cmd->data32[0];\n        resume = true;\n        return sendResponse(0);\n\n    case HF2_DBG_GET_STACK:\n        return sendResponseWithData(stackCopy, stackSize);\n\n    case HF2_CMD_JDS_CONFIG:\n        if (cmd->data8[0]) {\n            jdLogger = this;\n            pxt::logJDFrame = jdLog;\n        } else {\n            pxt::logJDFrame = NULL;\n        }\n        return sendResponse(0);\n\n    case HF2_CMD_JDS_SEND:\n        if (pxt::sendJDFrame) {\n            pxt::sendJDFrame(cmd->data8);\n            return sendResponse(0);\n        } else {\n            resp->status16 = HF2_STATUS_INVALID_STATE;\n            return sendResponse(0);\n        }\n\n    default:\n        // command not understood\n        resp->status16 = HF2_STATUS_INVALID_CMD;\n        break;\n    }\n\n    return sendResponse(0);\n}\n\nHF2::HF2(HF2_Buffer &p) : gotSomePacket(false), ctrlWaiting(false), pkt(p), useHID(false) {\n    lastExchange = 0;\n#ifdef USB_EP_FLAG_ASYNC\n    pendingWrite = NULL;\n    pendingWriteSize = 0;\n    pendingWritePtr = 0;\n#endif\n}\n\nstatic const InterfaceInfo dummyIfaceInfo = {\n    NULL,\n    0,\n    0,\n    {\n        0,    // numEndpoints\n        0xff, /// class code - vendor-specific\n        0xff, // subclass\n        0xff, // protocol\n        0x00, // string\n        0x00, // alt\n    },\n    {0, 0},\n    {0, 0},\n};\n\nconst InterfaceInfo *DummyIface::getInterfaceInfo() {\n    return &dummyIfaceInfo;\n}\n\n//\n//\n// Debugger\n//\n//\n\nstruct ExceptionContext {\n    uint32_t excReturn; // 0xFFFFFFF9\n    uint32_t r0;\n    uint32_t r1;\n    uint32_t r2;\n    uint32_t r3;\n    uint32_t r12;\n    uint32_t lr;\n    uint32_t faultInstrAddr;\n    uint32_t psr;\n};\n\nstruct Paused_Data {\n    uint32_t pc;\n};\nstatic Paused_Data pausedData;\n\nvoid bkptPaused() {\n\n// waiting for https://github.com/lancaster-university/codal/pull/14\n#ifdef DEVICE_GROUP_ID_USER\n    // the loop below counts as \"system\" task, and we don't want to pause ourselves\n    fiber_set_group(DEVICE_GROUP_ID_SYSTEM);\n    // pause everyone else\n    fiber_pause_group(DEVICE_GROUP_ID_USER);\n#endif\n\n    while (!resume) {\n        // DMESG(\"BKPT\");\n        hf2.pkt.resp.eventId = HF2_EV_DBG_PAUSED;\n        hf2.sendResponseWithData(&pausedData, sizeof(pausedData));\n        // TODO use an event\n        for (int i = 0; i < 20; ++i) {\n            if (resume)\n                break;\n            fiber_sleep(50);\n        }\n    }\n\n    if (stackCopy) {\n        xfree(stackCopy);\n        stackCopy = NULL;\n    }\n\n#ifdef DEVICE_GROUP_ID_USER\n    fiber_resume_group(DEVICE_GROUP_ID_USER);\n    // go back to user mode\n    fiber_set_group(DEVICE_GROUP_ID_USER);\n#endif\n\n    resume = false;\n}\n\nextern \"C\" void handleHardFault(ExceptionContext *ectx) {\n    auto instr = (uint16_t *)ectx->faultInstrAddr;\n\n    DMESG(\"FLT %p\", instr);\n\n    if (ectx->faultInstrAddr & 0x80000000) {\n        ectx->faultInstrAddr &= ~0x80000000;\n        // switch to step-over mode\n        globals[0] = (TValue)3;\n        return;\n    }\n\n    DMESG(\"BB %p %p %p lr=%p r0=%p\", instr[-1], instr[0], instr[1], ectx->lr, ectx->r0);\n\n    if (instr[0] == 0x6840) {\n        // ldr r0, [r0, #4] -- entry breakpoint\n        ectx->faultInstrAddr += 2;\n        // we're being ask for step-over mode\n        if (ectx->r0 == 3) {\n            // switch to debugger-attached-no-stepping mode\n            globals[0] = (TValue)0;\n            ectx->lr |= 0x80000000;\n        }\n        return;\n    }\n\n    if (instr[0] == 0x6800) {\n        // ldr r0, [r0, #0]\n        ectx->lr = ectx->faultInstrAddr + 3; // next instruction + thumb mode\n        pausedData.pc = ectx->faultInstrAddr + 2;\n        void *ssp = (void *)(ectx + 1);\n        stackSize = DEVICE_STACK_BASE - (uint32_t)ssp;\n        if (stackCopy)\n            xfree(stackCopy);\n        stackCopy = xmalloc(stackSize);\n        memcpy(stackCopy, ssp, stackSize);\n        ectx->faultInstrAddr = ((uint32_t)(&bkptPaused) & (~1U));\n        return;\n    }\n\n    while (1) {\n    }\n}\n\nextern \"C\" void HardFault_Handler(void) {\n    asm(\"push {lr}; mov r0, sp; bl handleHardFault; pop {pc}\");\n}\n\n#endif","hf2.h":"#ifndef DEVICE_HF2_H\n#define DEVICE_HF2_H\n\n#if CONFIG_ENABLED(DEVICE_USB)\n\n#include \"HID.h\"\n#include \"uf2hid.h\"\n\n// 260 bytes needed for biggest JD packets (with overheads)\n#define HF2_BUF_SIZE 260\n\ntypedef struct {\n    uint16_t size;\n    uint8_t serial;\n    union {\n        uint8_t buf[HF2_BUF_SIZE];\n        uint32_t buf32[HF2_BUF_SIZE / 4];\n        uint16_t buf16[HF2_BUF_SIZE / 2];\n        HF2_Command cmd;\n        HF2_Response resp;\n    };\n} HF2_Buffer;\n\nstruct HF2_PendingWrite {\n    HF2_PendingWrite *next;\n    uint16_t size;\n    uint8_t flag;\n    uint8_t _reserved;\n    uint8_t data[0];\n};\n\nclass HF2 : public CodalUSBInterface {\n    bool gotSomePacket;\n    bool ctrlWaiting;\n    uint32_t lastExchange;\n\n#ifdef USB_EP_FLAG_ASYNC\n    HF2_PendingWrite *pendingWrite;\n    int pendingWriteSize;\n    int pendingWritePtr;\n#endif\n\n  public:\n    HF2_Buffer &pkt;\n\n    bool useHID;\n\n    int sendResponse(int size);\n    int recv();\n    int sendResponseWithData(const void *data, int size);\n    int sendEvent(uint32_t evId, const void *data, int size);\n    void sendBuffer(uint8_t flag, const void *data, unsigned size, uint32_t prepend = -1);\n    void pokeSend();\n\n    HF2(HF2_Buffer &pkt);\n    virtual int endpointRequest();\n    virtual int stdRequest(UsbEndpointIn &ctrl, USBSetup &setup);\n    virtual const InterfaceInfo *getInterfaceInfo();\n    int sendSerial(const void *data, int size, int isError = 0);\n\n    virtual bool enableWebUSB() { return !useHID; }\n};\n\nclass DummyIface : public CodalUSBInterface {\n  public:\n    virtual const InterfaceInfo *getInterfaceInfo();\n};\n\n#endif\n\n#endif\n","hf2dbg.h":"#ifndef HF2DBG_H\n#define HF2DBG_H 1\n\n// we use a location at the top of the stack to store a magic value\n// which causes us to stop at the very first break point in the program\n#define HF2_DBG_MAGIC_PTR ((uint32_t *)(DEVICE_STACK_BASE - (DEVICE_STACK_SIZE - 4)))\n#define HF2_DBG_MAGIC_START 0xf0ebac7f\n\n#define HF2_DBG_GET_GLOBAL_STATE 0x53fc66e0\nstruct HF2_GLOBAL_STATE_Result {\n    uint32_t num_globals;\n    uint32_t globals_addr;\n};\n\n#define HF2_DBG_RESTART 0x1120bd93\n#define HF2_DBG_RESUME 0x27a55931\n#define HF2_EV_DBG_PAUSED 0x3692f9fd\n#define HF2_DBG_GET_STACK 0x70901510\n\n#endif\n","i2c.cpp":"#include \"pxt.h\"\n#include \"ErrorNo.h\"\n#include \"CodalDmesg.h\"\n#include \"configkeys.h\"\n\n#ifdef CODAL_I2C\n\nnamespace pins {\n\nclass CodalI2CProxy {\nprivate:\n  DevicePin* sda;\n  DevicePin* scl;\n  CODAL_I2C i2c;\npublic:\n  CodalI2CProxy* next;\npublic:\n  CodalI2CProxy(DevicePin* _sda, DevicePin* _scl)\n    : sda(_sda)\n    , scl(_scl)\n    , i2c(*_sda, *_scl) \n    , next(NULL)\n  {\n\n  }\n\n  CODAL_I2C* getI2C() {\n    return &(this->i2c);\n  }\n  \n  bool matchPins(DevicePin* sda, DevicePin* scl) {\n      return this->sda == sda && this->scl == scl;\n  }\n\n  Buffer readBuffer(int address, int size, bool repeat = false)\n  {\n    Buffer buf = mkBuffer(NULL, size);\n    registerGCObj(buf);\n    int status = this->i2c.read(address << 1, buf->data, size, repeat);\n    unregisterGCObj(buf);\n    if (status != ErrorCode::DEVICE_OK) {\n      buf = 0;\n    }\n    return buf;\n  }\n\n  int writeBuffer(int address, Buffer buf, bool repeat = false)\n  {\n    return this->i2c.write(address << 1, buf->data, buf->length, repeat);\n  }\n};\n\n}\n\nnamespace I2CMethods {\n/**\n  * Read `size` bytes from a 7-bit I2C `address`.\n  */\n//%\nBuffer readBuffer(I2C_ i2c, int address, int size, bool repeat = false)\n{\n  return i2c->readBuffer(address, size, repeat);\n}\n\n/**\n  * Write bytes to a 7-bit I2C `address`.\n  */\n//%\nint writeBuffer(I2C_ i2c, int address, Buffer buf, bool repeat = false)\n{\n  return i2c->writeBuffer(address, buf, repeat);\n}\n\n}\n\nnamespace pins {\n\nstatic I2C_ i2cs(NULL);\n/**\n* Opens a Serial communication driver\n*/\n//% help=pins/create-i2c\n//% parts=i2c\nI2C_ createI2C(DigitalInOutPin sda, DigitalInOutPin scl) {\n  // pick up defaults\n  if (!sda || !scl) {\n    DMESG(\"i2c: lookup default pins\");\n    sda = LOOKUP_PIN(SDA);\n    scl = LOOKUP_PIN(SCL);\n  }\n\n  // lookup existing devices\n  auto dev = i2cs;\n  while(dev) {\n    if (dev->matchPins(sda, scl)) {\n      DMESG(\"i2c: found existing i2c\");\n      return dev;\n    }\n    dev = dev->next;\n  }\n\n  // allocate new one\n  DMESG(\"i2c: mounting on new device\");\n  auto ser = new CodalI2CProxy(sda, scl);\n  // push in list\n  ser->next = i2cs;\n  i2cs = ser;\n  return ser;\n}\n\n}\n\nnamespace pxt {\n  CODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl) {\n    auto i2c = pins::createI2C(sda, scl);\n    return i2c->getI2C();\n  }\n}\n\n#endif","i2c.ts":"namespace pins {\n    /**\n     * Read one number from an I2C address.\n     */\n    //% help=pins/i2c-read-number weight=5 group=\"i2c\" inlineInputMode=\"external\"\n    //% blockId=pins_i2c_readnumber block=\"i2c read number at address %address|of format %format|repeated %repeated\"\n    export function i2cReadNumber(address: number, format: NumberFormat, repeated?: boolean): number {\n        const buf = pins.i2cReadBuffer(address, pins.sizeOf(format), repeated)\n        if (!buf)\n            return undefined\n        return buf.getNumber(format, 0)\n    }\n\n    /**\n     * Write one number to an I2C address.\n     */\n    //% help=pins/i2c-write-number weight=4 group=\"i2c\"\n    //% blockId=i2c_writenumber block=\"i2c write number|at address %address|with value %value|of format %format|repeated %repeated\"\n    export function i2cWriteNumber(address: number, value: number, format?: NumberFormat, repeated?: boolean): void {\n        if (format == undefined)\n            format = NumberFormat.UInt8LE;\n        const buf = control.createBuffer(pins.sizeOf(format))\n        buf.setNumber(format, 0, value)\n        pins.i2cWriteBuffer(address, buf, repeated)\n    }\n\n    /**\n     * Write a value in a I2C register.\n     * @param address I2c address of the device\n     * @param register register index\n     * @param value value to write\n     * @param valueFormat format of the value, default is UInt8LE\n     */\n    //% weight=3 group=\"i2c\"\n    //% help=pins/i2c-write-register\n    //% blockId=i2c_writereg block=\"i2c write register|at address $address|at register $register|value $value\"\n    export function i2cWriteRegister(address: number, register: number, value: number, valueFormat?: NumberFormat): void {\n        if (valueFormat === undefined)\n            valueFormat = NumberFormat.UInt8LE;\n        const valueSize = pins.sizeOf(valueFormat);\n        const buf = control.createBuffer(1 + valueSize);\n        buf.setNumber(NumberFormat.UInt8LE, 0, register);\n        buf.setNumber(valueFormat, 1, value);\n        pins.i2cWriteBuffer(address, buf);\n    }\n\n    /**\n     * Read the value from a I2C register.\n     * @param address I2c address of the device\n     * @param register register index\n     * @param valueFormat format of the value, default is UInt8LE\n     */\n    //% weight=3 group=\"i2c\"\n    //% help=pins/i2c-read-register\n    //% blockId=i2c_readreg block=\"i2c read register|at address $address|at register $register\"\n    export function i2cReadRegister(address: number, register: number, valueFormat?: NumberFormat): number {\n        if (valueFormat === undefined)\n            valueFormat = NumberFormat.UInt8LE;\n        pins.i2cWriteNumber(address, register, NumberFormat.UInt8LE);\n        return pins.i2cReadNumber(address, valueFormat);\n    }\n\n    /**\n     * Read `size` bytes from a 7-bit I2C `address`.\n     */\n    //%\n    export function i2cReadBuffer(address: number, size: number, repeat: boolean = false): Buffer {\n        return pins.i2c().readBuffer(address, size, repeat);\n    }\n\n    /**\n     * Write bytes to a 7-bit I2C `address`.\n     */\n    //%\n    export function i2cWriteBuffer(address: number, buf: Buffer, repeat: boolean = false): number {\n        return pins.i2c().writeBuffer(address, buf, repeat);\n    }\n\n    let _i2c: I2C;\n    /**\n     * Gets the default I2C bus\n     */\n    //%\n    export function i2c(): I2C {\n        if (!_i2c) {\n            const sda = pins.pinByCfg(DAL.CFG_PIN_SDA);\n            const scl = pins.pinByCfg(DAL.CFG_PIN_SCL);\n            _i2c = pins.createI2C(sda, scl);    \n        }\n        return _i2c;        \n    }\n\n    export class I2CDevice {\n        public address: number;\n        public bus: I2C;\n        private _hasError: boolean;\n        constructor(address: number, bus?: I2C) {\n            this.address = address;\n            this.bus = bus || i2c();\n        }\n        public readInto(buf: Buffer, repeat = false, start = 0, end: number = null) {\n            if (end === null)\n                end = buf.length\n            if (start >= end)\n                return\n            let res = this.bus.readBuffer(this.address, end - start, repeat)\n            if (!res) {\n                this._hasError = true\n                return\n            }\n            buf.write(start, res)\n        }\n        public write(buf: Buffer, repeat = false) {\n            let res = this.bus.writeBuffer(this.address, buf, repeat)\n            if (res) {\n                this._hasError = true\n            }\n        }\n        public begin(): I2CDevice {\n            this._hasError = false;\n            return this;\n        }\n        public end() {\n        }\n        public ok() {\n            return !this._hasError\n        }\n\n        public transfer(command: Buffer, response: Buffer, responseStart?: number, responseEnd?: number) {\n            this.begin();\n            if (command)\n                this.write(command);\n            if (response)\n                this.readInto(response, false, responseStart, responseEnd);\n            this.end();\n        }    \n    }\n}\n","keyvaluestorage.cpp":"#include \"pxt.h\"\n#include \"KeyValueStorage.h\"\n\nnamespace pxt {\n\nclass WKeyValueStorage {\n#ifdef CODAL_NVMCONTROLLER\n    CODAL_NVMCONTROLLER controller;\n#else\n    NVMController controller;\n#endif\n    KeyValueStorage storage;\n  public:\n\n    WKeyValueStorage()\n    : controller()\n    , storage(controller) {\n    }\n\n    bool isSupported() {\n#ifdef CODAL_NVMCONTROLLER\n      return true;\n#else\n      return false;\n#endif\n    }\n\n    int put(String key, Buffer data) {\n#ifdef CODAL_NVMCONTROLLER\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        return storage.put(mkey, data->data, data->length);\n#else\n        return -1;\n#endif\n    }\n\n    Buffer get(String key) {\n#ifdef CODAL_NVMCONTROLLER\n        Buffer buf = NULL;\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        auto entry = storage.get(mkey);\n        if (entry) {\n          buf = mkBuffer(entry->value, sizeof(entry->value));\n          free(entry);\n        }\n        return buf;\n#else\n        return NULL;\n#endif\n    }\n\n    void remove(String key) {\n#ifdef CODAL_NVMCONTROLLER\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        storage.remove(mkey);\n#endif\n    }\n\n    void clear() {\n#ifdef CODAL_NVMCONTROLLER\n        storage.wipe();\n#endif\n    }\n};\nSINGLETON(WKeyValueStorage);\n\n}\n\nnamespace configStorage {\n  /**\n  * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n  * @param key the identifier (max 16 characters)\n  * @param value the data (max 32 characters)\n  */\n  //%\n  void setBuffer(String key, Buffer value) {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->put(key, value);\n  }\n\n  /**\n  * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n  * @param key the identifier (max 16 characters)\n  */\n  //%\n  Buffer getBuffer(String key) {\n    auto kvm = pxt::getWKeyValueStorage();\n    return kvm->get(key);\n  }\n\n  /**\n  * Removes the key from local storage\n  * @param key the identifier (max 16 characters)\n  */\n  //%\n  void removeItem(String key) {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->remove(key);\n  }\n\n  /**\n  * Clears the local storage\n  */\n  //%\n  void clear() {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->clear();\n  }\n}\n","keyvaluestorage.ts":"namespace configStorage {\n    /**\n     * Stores the value at the key entry\n     * @param key identifier of the key (max 16 characters)\n     * @param value identifier of the value (max 32 characters)\n     */\n    export function setItem(key: string, value: string) {\n        if (value == null)\n            configStorage.removeItem(key);\n        else\n        {\n            let idx = 0;\n            let buf = control.createBuffer(value.length + 1);\n            buf[idx++] = value.length;\n            let valBuf = control.createBufferFromUTF8(value);\n\n            for (let i = 0; i < valBuf.length; i++)\n                buf[idx++] = valBuf[i];\n\n            configStorage.setBuffer(key, buf);\n        }\n    }\n\n    /**\n     * Retrieves the value at the key entry\n     * @param key identifier of the key (max 16 characters)\n     */\n    export function getItem(key: string): string {\n        const buf = configStorage.getBuffer(key);\n\n        if (!buf)\n            return undefined;\n\n        let idx = 0;\n        let count = buf[idx++];\n        const retBuf = control.createBuffer(count);\n\n        for (let i = 0; i < count; i++)\n            retBuf[i] = buf[idx++];\n\n        return retBuf.toString();\n    }\n}\n","leveldetector.ts":"namespace pins {\n    export class LevelDetector {\n        public id: number;\n        public min: number;\n        public max: number;\n        public lowThreshold: number;\n        public highThreshold: number;\n        private transition: number;\n        private transitionMs: number;\n        private _level: number;\n        private _state: number;\n        public onHigh: () => void;\n        public onLow: () => void;\n        public onNeutral: () => void;\n        public transitionWindow: number;\n        // minimum duration (ms) between events\n        public transitionInterval: number;\n\n        static LEVEL_THRESHOLD_NEUTRAL = 0;\n\n        constructor(id: number,\n            min: number, max: number,\n            lowThreshold: number, highThreshold: number) {\n            this.id = id;\n            this.min = min;\n            this.max = max;\n            this.lowThreshold = lowThreshold;\n            this.highThreshold = highThreshold;\n            this.transitionWindow = 4;\n            this.transitionInterval = 0;\n\n            this.onHigh = () => control.raiseEvent(this.id, DAL.LEVEL_THRESHOLD_HIGH);\n            this.onLow = () => control.raiseEvent(this.id, DAL.LEVEL_THRESHOLD_LOW);\n            this.onNeutral = undefined;\n\n            this.reset();\n        }\n\n        reset() {\n            this.transition = 0;\n            this.transitionMs = 0;\n            this._level = Math.ceil((this.highThreshold - this.lowThreshold) / 2);\n            this._state = LevelDetector.LEVEL_THRESHOLD_NEUTRAL;\n        }\n\n        get level(): number {\n            return this._level;\n        }\n\n        set level(level: number) {\n            this._level = this.clampValue(level);\n\n            if (this._level >= this.highThreshold) {\n                this.setState(DAL.LEVEL_THRESHOLD_HIGH);\n            }\n            else if (this._level <= this.lowThreshold) {\n                this.setState(DAL.LEVEL_THRESHOLD_LOW);\n            }\n            else {\n                this.setState(LevelDetector.LEVEL_THRESHOLD_NEUTRAL);\n            }\n        }\n\n        public setLowThreshold(value: number) {\n            this.lowThreshold = this.clampValue(value);\n            this.reset();\n        }\n\n        public setHighThreshold(value: number) {\n            this.highThreshold = this.clampValue(value);\n            this.reset();\n        }\n\n        private clampValue(value: number) {\n            if (value < this.min) {\n                return this.min;\n            }\n            else if (value > this.max) {\n                return this.max;\n            }\n            return value;\n        }\n\n        private setState(state: number) {\n            // not enough samples to change\n            if (this._state === state \n                || (this.transition++ < this.transitionWindow)\n                || (control.millis() - this.transitionMs) < this.transitionInterval) {\n                return;\n            }\n\n            this.transition = 0;\n            this.transitionMs = control.millis();\n            this._state = state;\n            switch (state) {\n                case DAL.LEVEL_THRESHOLD_HIGH:\n                    if (this.onHigh) this.onHigh();\n                    break;\n                case DAL.LEVEL_THRESHOLD_LOW:\n                    if (this.onLow) this.onLow();\n                    break;\n                case LevelDetector.LEVEL_THRESHOLD_NEUTRAL:\n                    if (this.onNeutral) this.onNeutral();\n                    break;\n            }\n        }\n    }\n}","light.cpp":"#include \"light.h\"\n\n// WS2812B timings, datasheet v1\n// 0 - 0.25-0.55us hi 0.70-1.00us low\n// 1 - 0.65-0.95us hi 0.30-0.60us low\n// datasheet v5\n// 0 - 0.22-0.38us hi 0.58-1.00us low 1-3\n// 1 - 0.58-1.00us hi 0.58-1.00us low 3-2\n\n#define SPI_SUPPORTED 1\n\n#if defined(NRF52_SERIES)\n#define BIT_EXPANSION 5\n#define SPI_FREQ 4000000\n#else\n#define BIT_EXPANSION 3\n#define SPI_FREQ 2400000\n#endif\n\n#if defined(SAMD21) || defined(SAMD51) || defined(STM32F4) || defined(NRF52_SERIES)\n#include \"neopixel.h\"\n#define BITBANG_SUPPORTED 1\n#else\n#define BITBANG_SUPPORTED 0\n#endif\n\n#define NEOPIXEL_MIN_LENGTH_FOR_SPI 24\n#define DOTSTAR_MIN_LENGTH_FOR_SPI 24\n\n#define LIGHTMODE_RGB 1\n#define LIGHTMODE_RGBW 2\n#define LIGHTMODE_RGB_RGB 3\n#define LIGHTMODE_DOTSTAR 4\n\nnamespace light {\nbool isValidMOSIPin(DigitalInOutPin pin) {\n    if (!pin)\n        return false;\n\n#if SAMD51\n    return ZSPI::isValidMOSIPin(*pin);\n#elif defined(NRF52_SERIES)\n    return true;\n#else\n    // TODO: support for SPI neopixels\n    // default SPI pins supported for now\n    return pin == LOOKUP_PIN(MOSI);\n#endif\n}\n\n// SPI\nvoid spiNeopixelSendBuffer(DevicePin *pin, const uint8_t *data, unsigned size) {\n    int32_t iptr = 0, optr = 120;\n    uint32_t len = optr + size * BIT_EXPANSION + 120;\n    uint8_t *expBuf = new uint8_t[len];\n    memset(expBuf, 0, len);\n    uint8_t imask = 0x80;\n    uint8_t omask = 0x80;\n\n#define WR(k)                                                                                      \\\n    if (k)                                                                                         \\\n        expBuf[optr] |= omask;                                                                     \\\n    omask >>= 1;                                                                                   \\\n    if (!omask) {                                                                                  \\\n        omask = 0x80;                                                                              \\\n        optr++;                                                                                    \\\n    }\n\n    while (iptr < (int)size) {\n#if BIT_EXPANSION == 3\n        WR(1);\n        WR(data[iptr] & imask);\n        WR(0);\n#elif BIT_EXPANSION == 5\n        WR(1);\n        if (data[iptr] & imask) {\n            WR(1);\n            WR(1);\n        } else {\n            WR(0);\n        }\n        WR(0);\n        WR(0);\n#else\n#error \"invalid BIT_EXPANSION\"\n#endif\n\n        imask >>= 1;\n        if (!imask) {\n            imask = 0x80;\n            iptr++;\n        }\n    }\n\n    auto spi = pxt::getSPI(pin, NULL, NULL);\n    spi->setFrequency(SPI_FREQ);\n    spi->transfer(expBuf, len, NULL, 0);\n    delete expBuf;\n}\n\nvoid neopixelSendData(DevicePin *pin, int mode, const uint8_t *data, unsigned length) {\n    if (!pin || !length)\n        return;\n\n#if BITBANG_SUPPORTED\n    if (SPI_SUPPORTED && length > NEOPIXEL_MIN_LENGTH_FOR_SPI && isValidMOSIPin(pin))\n        spiNeopixelSendBuffer(pin, data, length);\n    else\n        neopixel_send_buffer(*pin, data, length);\n#else\n    if (isValidMOSIPin(pin)) {\n        spiNeopixelSendBuffer(pin, data, length);\n    }\n#endif\n}\n\nvoid bitBangDotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                            unsigned length) {\n    // first frame of zeroes\n    data->setDigitalValue(0);\n    for (unsigned i = 0; i < 32; ++i) {\n        clk->setDigitalValue(1);\n        clk->setDigitalValue(0);\n    }\n\n    // data stream\n    for (unsigned i = 0; i < length; ++i) {\n        auto x = buf[i];\n        for (uint8_t j = 0x80; j != 0; j >>= 1) {\n            data->setDigitalValue(x & j ? 1 : 0);\n            clk->setDigitalValue(1);\n            clk->setDigitalValue(0);\n        }\n    }\n    // https://cpldcpu.wordpress.com/2016/12/13/sk9822-a-clone-of-the-apa102/\n    // reset frame\n    // data->setDigitalValue(0);\n    // for (unsigned i = 0; i < 32 ; ++i) {\n    //    clk->setDigitalValue(1);\n    //    clk->setDigitalValue(0);\n    //}\n\n    // https://cpldcpu.wordpress.com/2014/11/30/understanding-the-apa102-superled/\n    data->setDigitalValue(1);\n    unsigned n = 32;\n    for (unsigned i = 0; i < n; ++i) {\n        clk->setDigitalValue(1);\n        clk->setDigitalValue(0);\n    }\n}\n\nstatic uint8_t ZERO_FRAME[4];\nstatic uint8_t ONE_FRAME[] = {1, 1, 1, 1};\nvoid spiDotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                        unsigned length) {\n    auto spi = pxt::getSPI(data, NULL, clk);\n\n    spi->transfer(ZERO_FRAME, sizeof(ZERO_FRAME), NULL, 0); // initial frame\n    spi->transfer(buf, length, NULL, 0);\n    spi->transfer(ZERO_FRAME, sizeof(ZERO_FRAME), NULL, 0); // reset frame\n    for (unsigned i = 0; i < (length >> 3); i += 32)\n        spi->transfer(ONE_FRAME, sizeof(ONE_FRAME), NULL, 0); // final frame\n}\n\nvoid dotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                     unsigned length) {\n    if (!data || !clk || !buf || !length)\n        return;\n\n    if (length > DOTSTAR_MIN_LENGTH_FOR_SPI && isValidMOSIPin(data))\n        spiDotStarSendData(data, clk, mode, buf, length);\n    else\n        bitBangDotStarSendData(data, clk, mode, buf, length);\n}\n\nvoid sendBuffer(DevicePin *data, DevicePin *clk, int mode, Buffer buf) {\n    if (!data || !buf || !buf->length)\n        return;\n\n    if (mode == LIGHTMODE_DOTSTAR)\n        light::dotStarSendData(data, clk, mode, buf->data, buf->length);\n    else\n        light::neopixelSendData(data, mode, buf->data, buf->length);\n}\n\nvoid clear() {\n    auto neopix = LOOKUP_PIN(NEOPIXEL);\n    auto neonum = getConfig(CFG_NUM_NEOPIXELS, 0);\n    if (neopix && neonum >= 0) {\n        auto n = 3 * neonum;\n        uint8_t off[n];\n        memset(off, 0, sizeof(off));\n        light::neopixelSendData(neopix, 0x100, off, sizeof(off));\n    }\n\n    auto data = LOOKUP_PIN(DOTSTAR_DATA);\n    auto clk = LOOKUP_PIN(DOTSTAR_CLOCK);\n    auto dsnum = getConfig(CFG_NUM_DOTSTARS, 0);\n    if (data && clk && dsnum > 0) {\n        auto n = 4 * dsnum;\n        uint8_t off[n];\n        memset(off, 0, sizeof(off));\n        for (int i = 0; i < n; i += 4)\n            off[i] = 0xe0;\n        bitBangDotStarSendData(data, clk, 0x100, off, sizeof(off));\n    }\n}\n\n} // namespace light\n","light.h":"#ifndef __PXT_LIGHT_H\n#define __PXT_LIGHT_H\n\n#include \"pxt.h\"\n\nnamespace light {\n    /**\n    * Clear onboard neopixels\n    */\n    void clear();\n\n    /**\n    * Send a programmable light buffer to the specified digital pin\n    * @param data The pin that the lights are connected to\n    * @param clk the clock line if any\n    * @param mode the color encoding mode\n    * @param buf The buffer to send to the pin\n    */\n    //%\n    void sendBuffer(DigitalInOutPin data, DigitalInOutPin clk, int mode, Buffer buf);\n\n    void neopixelSendData(DevicePin* pin, int mode, const uint8_t* data, unsigned length);\n}\n\n#endif","ns.ts":"/**\n * Events and data from sensors.\n */\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\n//% groups='[\"other\", \"More\"]'\nnamespace input {\n}\n\n/**\n * Servos\n */\n//% color=\"#03AA74\" weight=88 icon=\"\\uf021\"\nnamespace servos {\n\n}\n\n/**\n * A Joint Asynchronous Communications, Device Agnostic Control.\n */\n//% color=\"#E79251\" weight=1 icon=\"\\uf185\"\n//% groups='[\"Broadcast\", \"Console\", \"Control\"]'\n//% blockGap=8\nnamespace jacdac {\n\n}","pins.cpp":"#include \"pxt.h\"\n\nnamespace pxt {\nstatic DevicePin **pinPtrs;\nstatic uint8_t numPinPtrs;\nstatic uint8_t pinPos[DEV_NUM_PINS];\n\n//%\nDevicePin *getPin(int id) {\n\n    id &= CFG_PIN_NAME_MSK;\n\n    if (id >= DEV_NUM_PINS)\n        soft_panic(PANIC_NO_SUCH_PIN);\n\n    // we could use lookupComponent() here - it would be slightly slower\n\n    int ptr = pinPos[id];\n    if (ptr == 0) {\n        pinPtrs = (DevicePin **)realloc(pinPtrs, (numPinPtrs + 1) * sizeof(void *));\n        bool isAnalog = IS_ANALOG_PIN(id);\n        // GCTODO\n        pinPtrs[numPinPtrs++] =\n            new DevicePin(DEVICE_ID_IO_P0 + id, (PinName)id,\n                          isAnalog ? PIN_CAPABILITY_AD : PIN_CAPABILITY_DIGITAL);\n        ptr = numPinPtrs;\n        pinPos[id] = ptr;\n    }\n    return pinPtrs[ptr - 1];\n}\n\n//%\nDevicePin *getPinCfg(int key) {\n    int p = getConfig(key, -1);\n    if (p == -1)\n        DMESG(\"no pin cfg: %d\", key);\n    return getPin(p);\n}\n\nvoid linkPin(int from, int to) {\n    if (from < 0 || from >= DEV_NUM_PINS)\n        soft_panic(PANIC_NO_SUCH_PIN);\n    getPin(to);\n    pinPos[from] = pinPos[to];\n}\n\n//%\nDevicePin *lookupPin(int pinName) {\n    if (pinName < 0 || pinName == 0xff)\n        return NULL;\n    pinName &= CFG_PIN_NAME_MSK;\n    return getPin(pinName);\n}\n\n//%\nDevicePin *lookupPinCfg(int key) {\n    return lookupPin(getConfig(key));\n}\n\nCodalComponent *lookupComponent(int id) {\n    for (int i = 0; i < DEVICE_COMPONENT_COUNT; ++i) {\n        if (CodalComponent::components[i] && CodalComponent::components[i]->id == id)\n            return CodalComponent::components[i];\n    }\n    return NULL;\n}\n\n} // namespace pxt\n\nnamespace pins {\n/**\n* Get a pin by configuration id (DAL.CFG_PIN...)\n*/\n//%\nDigitalInOutPin pinByCfg(int key) {\n    return pxt::lookupPinCfg(key);\n}\n\n/**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n//%\nBuffer createBuffer(int size) {\n    return mkBuffer(NULL, size);\n}\n\n/**\n * Get the duration of the last pulse in microseconds. This function should be called from a\n * ``onPulsed`` handler.\n */\n//% help=pins/pulse-duration blockGap=8\n//% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n//% weight=19\nint pulseDuration() {\n    return pxt::lastEvent.timestamp;\n}\n} // namespace pins\n","pins.h":"#ifndef __PXT_PINS_H\n#define __PXT_PINS_H\n\n#define BUTTON_ACTIVE_HIGH_PULL_DOWN (ACTIVE_HIGH | 0x10)\n#define BUTTON_ACTIVE_HIGH_PULL_UP (ACTIVE_HIGH | 0x20)\n#define BUTTON_ACTIVE_HIGH_PULL_NONE (ACTIVE_HIGH | 0x30)\n#define BUTTON_ACTIVE_LOW_PULL_DOWN (ACTIVE_LOW | 0x10)\n#define BUTTON_ACTIVE_LOW_PULL_UP (ACTIVE_LOW | 0x20)\n#define BUTTON_ACTIVE_LOW_PULL_NONE (ACTIVE_LOW | 0x30)\n\n#define PIN(name) ((PinName)pxt::getConfig(CFG_PIN_##name, -1))\n#define LOOKUP_PIN(name) pxt::lookupPin(PIN(name))\n\n// these can be overridden in platform.h\n#ifndef CODAL_PIN\n#define CODAL_PIN CODAL_MBED::Pin\n#endif\n\n#ifndef CODAL_TIMER\n#define CODAL_TIMER CODAL_MBED::Timer\n#endif\n\n#ifndef CODAL_SPI\n#define CODAL_SPI CODAL_MBED::SPI\n#endif\n\n#ifndef CODAL_SERIAL\n#define CODAL_SERIAL CODAL_MBED::Serial\n#endif\n\n#ifndef IS_ANALOG_PIN\n#define IS_ANALOG_PIN(id) ((DEV_ANALOG_PINS >> (id)) & 1)\n#endif\n\ntypedef CODAL_PIN DevicePin;\n\ntypedef DevicePin *DigitalInOutPin;\ntypedef DevicePin *AnalogInOutPin;\ntypedef DevicePin *AnalogInPin;\ntypedef DevicePin *AnalogOutPin;\ntypedef DevicePin *PwmPin;\ntypedef DevicePin *PwmOnlyPin;\ntypedef Button *Button_;\n\nnamespace pxt {\nDevicePin *getPin(int id);\nDevicePin *getPinCfg(int key);\nDevicePin *lookupPin(int pinName);\nDevicePin *lookupPinCfg(int key);\nvoid linkPin(int from, int to);\nCodalComponent *lookupComponent(int id);\n}\n\n#define PINOP(op) name->op\n\n#endif\n","pins.ts":"//% noRefCounting fixedInstances\ninterface DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogInPin extends DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogOutPin extends DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogInOutPin extends AnalogInPin, AnalogOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface PwmOnlyPin extends DigitalInOutPin, AnalogOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface PwmPin extends PwmOnlyPin, AnalogInOutPin {\n}\n\n/**\n * Control currents in Pins for analog/digital signals, servos, i2c, ...\n */\n//% color=#A80000 weight=85 icon=\"\\uf140\" advanced=true\n//% groups='[\"other\", \"Servo\", \"i2c\"]'\nnamespace pins {\n}","pinsAnalog.cpp":"#include \"pxt.h\"\n\nnamespace AnalogInPinMethods {\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 weight=53\n//% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nint analogRead(AnalogInPin name) {\n    return PINOP(getAnalogValue());\n}\n}\n\nnamespace AnalogOutPinMethods {\nvoid analogWrite(AnalogOutPin name, int value) __attribute__ ((weak));\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 weight=52\n//% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\n//% value.min=0 value.max=1023\nvoid analogWrite(AnalogOutPin name, int value) {\n    PINOP(setAnalogValue(value));\n}\n}","pinsDigital.cpp":"#include \"pxt.h\"\n\nenum class PulseValue {\n    //% block=high\n    High = DEVICE_PIN_EVT_PULSE_HI,\n    //% block=low\n    Low = DEVICE_PIN_EVT_PULSE_LO\n};\n\nenum class PinEvent {\n    //% block=\"pulse high\"\n    PulseHigh = DEVICE_PIN_EVT_PULSE_HI,\n    //% block=\"pulse low\"\n    PulseLow = DEVICE_PIN_EVT_PULSE_LO,\n    //% block=\"rise\"\n    Rise = DEVICE_PIN_EVT_RISE,\n    //% block=\"fall\"\n    Fall = DEVICE_PIN_EVT_FALL,\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\nnamespace DigitalInOutPinMethods {\n/**\n * Read a pin or connector as either 0 or 1\n * @param name pin to read from\n */\n//% help=pins/digital-read weight=61\n//% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nbool digitalRead(DigitalInOutPin name) {\n    return PINOP(getDigitalValue()) != 0;\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\n    */\n//% help=pins/digital-write weight=60\n//% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid digitalWrite(DigitalInOutPin name, bool value) {\n    PINOP(setDigitalValue(value));\n}\n\n/**\n* Make this pin a digital input, and create events where the timestamp is the duration\n* that this pin was either ``high`` or ``low``.\n*/\n//% help=pins/on-pulsed weight=16 blockGap=8\n//% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\n//% deprecated=1 hidden=1\nvoid onPulsed(DigitalInOutPin pin, PulseValue pulse, Action body) {\n    pin->eventOn(DEVICE_PIN_EVENT_ON_PULSE);\n    registerWithDal(pin->id, (int)pulse, body);\n}\n\n/**\n* Register code to run when a pin event occurs. \n*/\n//% help=pins/on-event weight=20 blockGap=8\n//% blockId=pinsonevent block=\"on|pin %pin|%event\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\nvoid onEvent(DigitalInOutPin pin, PinEvent event, Action body) {\n    switch(event) {\n        case PinEvent::PulseHigh:\n        case PinEvent::PulseLow:\n            pin->eventOn(DEVICE_PIN_EVENT_ON_PULSE);\n            registerWithDal(pin->id, (int)event, body);\n            break;\n        case PinEvent::Rise:\n        case PinEvent::Fall:\n            pin->eventOn(DEVICE_PIN_EVENT_ON_EDGE);\n            registerWithDal(pin->id, (int)event, body);\n            break;    \n    }    \n}\n\n/**\n* Return 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 %high||timeout %maxDuration (µs)\"\n//% weight=18 blockGap=8\n//% help=\"pins/pulse-in\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\nint pulseIn(DigitalInOutPin pin, PulseValue value, int maxDuration = 2000000) {\n    int pulse = PulseValue::High == value ? 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* Set the pull direction 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=17 blockGap=8\n//% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid setPull(DigitalInOutPin name, PinPullMode pull) {\n    PullMode m = pull == PinPullMode::PullDown ? PullMode::Down : pull == PinPullMode::PullUp\n                                                                        ? PullMode::Up\n                                                                        : PullMode::None;\n    PINOP(setPull(m));\n}\n\n}\n\n#ifdef PXT_CODAL\n\nnamespace pxt {\n\nstatic void waitABit() {\n    // for (int i = 0; i < 10; ++i)\n    //    asm volatile(\"nop\");\n}\n\nclass ButtonMultiplexer : public CodalComponent {\n  public:\n    Pin &latch;\n    Pin &clock;\n    Pin &data;\n    uint32_t state;\n    uint32_t invMask;\n    uint16_t buttonIdPerBit[8];\n    bool enabled;\n\n    ButtonMultiplexer(uint16_t id)\n        : latch(*LOOKUP_PIN(BTNMX_LATCH)), clock(*LOOKUP_PIN(BTNMX_CLOCK)),\n          data(*LOOKUP_PIN(BTNMX_DATA)) {\n        this->id = id;\n        this->status |= DEVICE_COMPONENT_STATUS_SYSTEM_TICK;\n\n        state = 0;\n        invMask = 0;\n        enabled = true;\n\n        memset(buttonIdPerBit, 0, sizeof(buttonIdPerBit));\n\n        data.getDigitalValue(PullMode::Down);\n        latch.setDigitalValue(1);\n        clock.setDigitalValue(1);\n    }\n\n    void disable() {\n        data.getDigitalValue(PullMode::None);\n        latch.getDigitalValue(PullMode::None);\n        clock.getDigitalValue(PullMode::None);\n        enabled = false;\n    }\n\n    bool isButtonPressed(int id) {\n        for (int i = 0; i < 8; ++i) {\n            if (buttonIdPerBit[i] == id)\n                return (state & (1 << i)) != 0;\n        }\n        return false;\n    }\n\n    uint32_t readBits(int bits) {\n        latch.setDigitalValue(0);\n        waitABit();\n        latch.setDigitalValue(1);\n        waitABit();\n\n        uint32_t state = 0;\n        for (int i = 0; i < bits; i++) {\n            state <<= 1;\n            if (data.getDigitalValue(PullMode::Down))\n                state |= 1;\n\n            clock.setDigitalValue(0);\n            waitABit();\n            clock.setDigitalValue(1);\n            waitABit();\n        }\n\n        return state;\n    }\n\n    virtual void periodicCallback() override {\n        if (!enabled)\n            return;\n\n        uint32_t newState = readBits(8);\n        newState ^= invMask;\n        if (newState == state)\n            return;\n\n        for (int i = 0; i < 8; ++i) {\n            uint32_t mask = 1 << i;\n            if (!buttonIdPerBit[i])\n                continue;\n            int ev = 0;\n            if (!(state & mask) && (newState & mask))\n                ev = PXT_INTERNAL_KEY_DOWN;\n            else if ((state & mask) && !(newState & mask))\n                ev = PXT_INTERNAL_KEY_UP;\n            if (ev) {\n                Event(ev, buttonIdPerBit[i]);\n                Event(ev, 0); // any key\n            }\n        }\n\n        state = newState;\n    }\n};\n\nstatic ButtonMultiplexer *btnMultiplexer;\nButtonMultiplexer *getMultiplexer() {\n    if (!btnMultiplexer)\n        btnMultiplexer = new ButtonMultiplexer(DEVICE_ID_FIRST_BUTTON);\n    return btnMultiplexer;\n}\n\nint registerMultiplexedButton(int pin, int buttonId) {\n    if (1050 <= pin && pin < 1058) {\n        pin -= 50;\n        getMultiplexer()->invMask |= 1 << (pin - 1000);\n    }\n    if (1000 <= pin && pin < 1008) {\n        getMultiplexer()->buttonIdPerBit[pin - 1000] = buttonId;\n        return 1;\n    }\n    return 0;\n}\n\nint multiplexedButtonIsPressed(int btnId) {\n    if (btnMultiplexer)\n        return btnMultiplexer->isButtonPressed(btnId) ? 512 : 0;\n    return 0;\n}\n\n//% expose\nuint32_t readButtonMultiplexer(int bits) {\n    if (!LOOKUP_PIN(BTNMX_CLOCK))\n        return 0;\n    return getMultiplexer()->readBits(bits);\n}\n\nvoid disableButtonMultiplexer() {\n    if (LOOKUP_PIN(BTNMX_CLOCK)) {\n        getMultiplexer()->disable();\n    }\n}\n\n}\n\n#endif\n","pinsPWM.cpp":"#include \"pxt.h\"\n\nnamespace PwmPinMethods {\n}\n\nnamespace PwmOnlyPinMethods {\n\n/**\n * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n * **microseconds** or `1/1000` milliseconds.\n * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n * 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=51\n//% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid analogSetPeriod(PwmOnlyPin name, int period) {\n    PINOP(setAnalogPeriodUs(period));\n}\n\n/**\n * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n * 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\n */\n//% help=pins/servo-write weight=41 group=\"Servo\"\n//% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n//% parts=microservo trackArgs=0\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\n//% value.defl=90\nvoid servoWrite(PwmOnlyPin name, int value) {\n    PINOP(setServoValue(value));\n}\n\n/**\n * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n * @param name pin name\n * @param duration pulse duration in micro seconds, eg:1500\n */\n//% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n//% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n//% parts=microservo blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid servoSetPulse(PwmOnlyPin name, int duration) {\n    PINOP(setServoPulseUs(duration));\n}\n\n/**\n* Indicates if the servo is running continuously\n*/\n//% blockHidden=1\nvoid servoSetContinuous(PwmOnlyPin name, bool continuous) {\n    // used by simulator\n}\n\n}","pinscompat.ts":"// filled in by microbit","platform.cpp":"#include \"pxt.h\"\n#include \"STMLowLevelTimer.h\"\n#include \"Accelerometer.h\"\n#include \"light.h\"\n\nnamespace pxt {\n\nstruct TimerConfig {\n    uint8_t id;\n    uint8_t irqn;\n    TIM_TypeDef *addr;\n};\n\n#define TIM1_IRQn TIM1_CC_IRQn\n#ifdef STM32F4\n#define TIM9_IRQn TIM1_BRK_TIM9_IRQn\n#define TIM10_IRQn TIM1_UP_TIM10_IRQn\n#define TIM11_IRQn TIM1_TRG_COM_TIM11_IRQn\n#endif\n\n#define DEF_TIM(n)                                                                                 \\\n    { 0x10 + n, TIM##n##_IRQn, TIM##n }\n\nstatic const TimerConfig timers[] = {\n#ifdef TIM1\n    DEF_TIM(1),\n#endif\n#ifdef TIM2\n    DEF_TIM(2),\n#endif\n#ifdef TIM3\n    DEF_TIM(3),\n#endif\n#ifdef TIM4\n    DEF_TIM(4),\n#endif\n#ifdef TIM5\n    DEF_TIM(5),\n#endif\n#ifdef TIM6\n    DEF_TIM(6),\n#endif\n#ifdef TIM7\n    DEF_TIM(7),\n#endif\n#ifdef TIM8\n    DEF_TIM(8),\n#endif\n#ifdef TIM9\n    DEF_TIM(9),\n#endif\n#ifdef TIM10\n    DEF_TIM(10),\n#endif\n#ifdef TIM11\n    DEF_TIM(11),\n#endif\n#ifdef TIM12\n    DEF_TIM(12),\n#endif\n#ifdef TIM13\n    DEF_TIM(13),\n#endif\n#ifdef TIM14\n    DEF_TIM(14),\n#endif\n#ifdef TIM15\n    DEF_TIM(15),\n#endif\n{0,0,0}\n};\n\n#ifdef STM32F1\n#define DEF_TIMERS 0x14120000 // TIM4 TIM2\n#else\n#define DEF_TIMERS 0x15120000 // TIM5 TIM2\n#endif\n\nstatic uint32_t usedTimers;\nstatic int timerIdx(uint8_t id) {\n    for (unsigned i = 0; timers[i].id; i++) {\n        if (id == timers[i].id)\n            return i;\n    }\n    return -1;\n}\nLowLevelTimer *allocateTimer() {\n    uint32_t timersToUse = getConfig(CFG_TIMERS_TO_USE, DEF_TIMERS);\n    for (int shift = 24; shift >= 0; shift -= 8) {\n        uint8_t tcId = (timersToUse >> shift) & 0xff;\n        int idx = timerIdx(tcId);\n        if (idx < 0 || (usedTimers & (1 << idx)))\n            continue;\n        auto dev = timers[idx].addr;\n        if (dev->CR1 & TIM_CR1_CEN)\n            continue;\n        usedTimers |= 1 << idx;\n        DMESG(\"allocate TIM%d\", tcId - 0x10);\n        return new STMLowLevelTimer(dev, timers[idx].irqn);\n    }\n\n    soft_panic(PANIC_OUT_OF_TIMERS);\n    return NULL;\n}\n\n\nvoid initAccelRandom();\n#ifdef STM32F4\nextern \"C\" void apply_clock_init(RCC_OscInitTypeDef *oscInit, RCC_ClkInitTypeDef *clkConfig,\n                                 uint32_t flashLatency) {\n\n    int mhz = getConfig(CFG_CPU_MHZ, 84);\n\n    if (mhz >= 216) {\n        oscInit->PLL.PLLN = 432;\n        oscInit->PLL.PLLP = RCC_PLLP_DIV2;\n        oscInit->PLL.PLLQ = 9;\n        flashLatency = FLASH_LATENCY_6;\n    } else if (mhz >= 192) {\n        oscInit->PLL.PLLN = 384;\n        oscInit->PLL.PLLP = RCC_PLLP_DIV2;\n        oscInit->PLL.PLLQ = 8;\n        flashLatency = FLASH_LATENCY_6;\n    } else if (mhz >= 168) {\n        oscInit->PLL.PLLN = 336;\n        oscInit->PLL.PLLP = RCC_PLLP_DIV2;\n        oscInit->PLL.PLLQ = 7;\n        flashLatency = FLASH_LATENCY_5;\n    } else if (mhz >= 144) {\n        oscInit->PLL.PLLN = 288;\n        oscInit->PLL.PLLP = RCC_PLLP_DIV2;\n        oscInit->PLL.PLLQ = 6;\n        flashLatency = FLASH_LATENCY_5;\n    } else if (mhz >= 108) {\n        oscInit->PLL.PLLN = 432;\n        oscInit->PLL.PLLP = RCC_PLLP_DIV4;\n        oscInit->PLL.PLLQ = 9;\n        flashLatency = FLASH_LATENCY_4;\n    } else if (mhz >= 96) {\n        oscInit->PLL.PLLN = 384;\n        oscInit->PLL.PLLP = RCC_PLLP_DIV4;\n        oscInit->PLL.PLLQ = 8;\n        flashLatency = FLASH_LATENCY_3;\n    } else if (mhz >= 84) {\n        // this is the default from codal\n        oscInit->PLL.PLLN = 336;\n        oscInit->PLL.PLLP = RCC_PLLP_DIV4;\n        oscInit->PLL.PLLQ = 7;\n        flashLatency = FLASH_LATENCY_2;\n    } else {\n        soft_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n    }\n\n    DMESG(\"CPU clock: %dMHz -> %dMHz\", mhz,\n          oscInit->PLL.PLLN / (oscInit->PLL.PLLP == RCC_PLLP_DIV4 ? 4 : 2));\n\n    if (mhz > 108) {\n        clkConfig->APB1CLKDivider = RCC_HCLK_DIV4;\n        clkConfig->APB2CLKDivider = RCC_HCLK_DIV2;\n    } else {\n        clkConfig->APB1CLKDivider = RCC_HCLK_DIV2;\n        clkConfig->APB2CLKDivider = RCC_HCLK_DIV1;\n    }\n\n    HAL_RCC_OscConfig(oscInit);\n    HAL_RCC_ClockConfig(clkConfig, flashLatency);\n}\n#endif\n\n// Disable seeding random from accelerometer. We now store random\n// seed in internal flash, so it's different on every reset, and\n// accelerometer sometimes have bugs, so better not enable them unless\n// requested.\nstatic void initRandomSeed() {\n#if 0\n    if (getConfig(CFG_ACCELEROMETER_TYPE, -1) != -1) {\n        initAccelRandom();\n    }\n#endif\n}\n\nstatic void set_if_present(int cfg, int val) {\n    auto snd = pxt::lookupPinCfg(cfg);\n    if (snd)\n        snd->setDigitalValue(val);\n}\n\n//%\nvoid deepSleep() {\n    // this in particular puts accelerometer to sleep, which the bootloader\n    // doesn't do\n    CodalComponent::setAllSleep(true);\n\n#ifdef STM32F4\n    // ask bootloader to do the deep sleeping\n    QUICK_BOOT(1);\n    RTC->BKP1R = 0x10b37889;\n    NVIC_SystemReset();\n#endif\n}\n\nvoid platformSendSerial(const char *data, int len) {\n    /*\n    if (!serial) {\n        serial = new codal::_mbed::Serial(USBTX, NC);\n        serial->baud(9600);\n    }\n    serial->send((uint8_t*)data, len);\n    */\n}\n\nvoid platform_init() {\n    initRandomSeed();\n    setSendToUART(platformSendSerial);\n    light::clear();\n\n    // make sure sound doesn't draw power before enabled\n    set_if_present(CFG_PIN_JACK_SND, 0);\n    set_if_present(CFG_PIN_JACK_HPEN, 0);\n    set_if_present(CFG_PIN_JACK_BZEN, 1);\n\n    /*\n        if (*HF2_DBG_MAGIC_PTR == HF2_DBG_MAGIC_START) {\n            *HF2_DBG_MAGIC_PTR = 0;\n            // this will cause alignment fault at the first breakpoint\n            globals[0] = (TValue)1;\n        }\n    */\n}\n\nint *getBootloaderConfigData() {\n#ifdef STM32F4\n    auto config_data = (uint32_t)(UF2_BINFO->configValues);\n    if (config_data && (config_data & 3) == 0) {\n        auto p = (uint32_t *)config_data - 4;\n        if (p[0] == CFG_MAGIC0 && p[1] == CFG_MAGIC1)\n            return (int *)p + 4;\n    }\n#endif\n\n    return NULL;\n}\n\n#define STM32_UUID ((uint32_t *)0x1FFF7A10)\n\nstatic void writeHex(char *buf, uint32_t n) {\n    int i = 0;\n    int sh = 28;\n    while (sh >= 0) {\n        int d = (n >> sh) & 0xf;\n        buf[i++] = d > 9 ? 'A' + d - 10 : '0' + d;\n        sh -= 4;\n    }\n    buf[i] = 0;\n}\n\nvoid platform_usb_init() {\n#if CONFIG_ENABLED(DEVICE_USB)\n    static char serial_number[25];\n\n    writeHex(serial_number, STM32_UUID[0]);\n    writeHex(serial_number + 8, STM32_UUID[1]);\n    writeHex(serial_number + 16, STM32_UUID[2]);\n\n    usb.stringDescriptors[2] = serial_number;\n#endif\n}\n\n} // namespace pxt\n\nvoid cpu_clock_init() {}\n","platform.h":"#ifndef __PXT_PLATFORM_H\n#define __PXT_PLATFORM_H\n\n#include \"Image.h\"\n#include \"MultiButton.h\"\n#include \"ZPin.h\"\n#include \"Timer.h\"\n#include \"ZSPI.h\"\n#include \"ZI2C.h\"\n#include \"ZSingleWireSerial.h\"\n\n#include \"pinmap.h\"\n\n#define BOOTLOADER_START 0x08000000\n#define BOOTLOADER_END 0x08008000\n\n#ifdef STM32F4\n#define SETTINGS_MAGIC_0 0x10476643\n#define SETTINGS_MAGIC_1 0x2e9a5026\n\nstruct F4_Settings {\n    uint32_t magic0;\n    uint32_t magic1;\n    int *configValues;\n    uint32_t hseValue;\n    const char *info_uf2;\n    const char *manufacturer;\n    const char *device;\n    uint32_t reserved[16 - 7];\n};\n\n#define UF2_BINFO ((F4_Settings *)(BOOTLOADER_END - sizeof(F4_Settings)))\n#define UF2_INFO_TXT UF2_BINFO->info_uf2\n#define USB_HANDOVER 0\n\n#define BOOT_RTC_SIGNATURE 0x71a21877\n#define APP_RTC_SIGNATURE 0x24a22d12\n#define HF2_RTC_SIGNATURE 0x39a63a78\n#define QUICK_BOOT(v)                                                                              \\\n    do {                                                                                           \\\n        RTC->BKP0R = v ? APP_RTC_SIGNATURE : HF2_RTC_SIGNATURE;                                    \\\n    } while (0)\n#endif\n\n#define PAGE_SIZE 1024 // not really\n\n#define DEV_NUM_PINS 64\n\n#ifdef STM32F1\n#define DEV_PWM_PINS 0b111100000011101100001110111000111111001110LL\n#else\n#define DEV_PWM_PINS 0b111100000011100111111110111000111111101111LL\n#endif\n\n//               CCCCCCCCCCCCCCCCBBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAA\n//               fedcba9876543210fedcba9876543210fedcba9876543210\n#define DEV_AIN_PINS 0b000011111100000000000000110000000011111111LL\n\n// Codal doesn't yet distinguish between PWM and AIN\n#define DEV_ANALOG_PINS (DEV_PWM_PINS | DEV_AIN_PINS)\n\n#define CODAL_PIN ZPin\n#define CODAL_TIMER Timer\n#define CODAL_SPI ZSPI\n#define CODAL_I2C ZI2C\n#define CODAL_JACDAC_WIRE_SERIAL codal::ZSingleWireSerial\n\n#define PERF_NOW() (TIM5->CNT)\n\n#define IMAGE_BITS 4\n\n\n// The parameters below needs tuning!\n\n#ifdef JUST_FOR_DAL_D_TS_CPP_WILL_IGNORE\n#define PA_0 0x00\n#define PA_1 0x01\n#define PA_2 0x02\n#define PA_3 0x03\n#define PA_4 0x04\n#define PA_5 0x05\n#define PA_6 0x06\n#define PA_7 0x07\n#define PA_8 0x08\n#define PA_9 0x09\n#define PA_10 0x0A\n#define PA_11 0x0B\n#define PA_12 0x0C\n#define PA_13 0x0D\n#define PA_14 0x0E\n#define PA_15 0x0F\n\n#define PB_0 0x10\n#define PB_1 0x11\n#define PB_2 0x12\n#define PB_3 0x13\n#define PB_4 0x14\n#define PB_5 0x15\n#define PB_6 0x16\n#define PB_7 0x17\n#define PB_8 0x18\n#define PB_9 0x19\n#define PB_10 0x1A\n#define PB_11 0x1B\n#define PB_12 0x1C\n#define PB_13 0x1D\n#define PB_14 0x1E\n#define PB_15 0x1F\n\n#define PC_0 0x20\n#define PC_1 0x21\n#define PC_2 0x22\n#define PC_3 0x23\n#define PC_4 0x24\n#define PC_5 0x25\n#define PC_6 0x26\n#define PC_7 0x27\n#define PC_8 0x28\n#define PC_9 0x29\n#define PC_10 0x2A\n#define PC_11 0x2B\n#define PC_12 0x2C\n#define PC_13 0x2D\n#define PC_14 0x2E\n#define PC_15 0x2F\n\n#define PD_0 0x30\n#define PD_1 0x31\n#define PD_2 0x32\n#define PD_3 0x33\n#define PD_4 0x34\n#define PD_5 0x35\n#define PD_6 0x36\n#define PD_7 0x37\n#define PD_8 0x38\n#define PD_9 0x39\n#define PD_10 0x3A\n#define PD_11 0x3B\n#define PD_12 0x3C\n#define PD_13 0x3D\n#define PD_14 0x3E\n#define PD_15 0x3F\n#endif\n\n#endif","pxt.h":"#ifndef __PXT_H\n#define __PXT_H\n\n#include \"pxtbase.h\"\n\n#include \"CodalConfig.h\"\n#include \"CodalHeapAllocator.h\"\n#include \"CodalDevice.h\"\n#include \"CodalDmesg.h\"\n#include \"ErrorNo.h\"\n#include \"Timer.h\"\n#include \"Matrix4.h\"\n#include \"CodalCompat.h\"\n#include \"CodalComponent.h\"\n#include \"ManagedType.h\"\n#include \"Event.h\"\n#include \"NotifyEvents.h\"\n#include \"Button.h\"\n#include \"CodalFiber.h\"\n#include \"MessageBus.h\"\n#include \"MultiButton.h\"\n\nusing namespace codal;\n\n// codal::ManagedString compat\n#define MSTR(s) codal::ManagedString((s)->data, (s)->length)\n#define PSTR(s) mkString((s).toCharArray(), (s).length())\n\n#include \"pins.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"hf2.h\"\n#include \"hf2dbg.h\"\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n#include \"HIDMouse.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n#include \"HIDKeyboard.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n#include \"HIDJoystick.h\"\n#endif\n#endif\n\n#define PXT_COMM_BASE 0x20002000 // 8k in\n\n// old codal compat\n#ifndef REAL_TIME_FUNC\n#define REAL_TIME_FUNC /* */\n#endif\n\nnamespace pxt {\n\n#if CONFIG_ENABLED(DEVICE_USB)\nextern CodalUSB usb;\nextern HF2 hf2;\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nextern USBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nextern USBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nextern USBHIDJoystick joystick;\n#endif\n#endif\n\n// Utility functions\nextern Event lastEvent;\nextern CODAL_TIMER devTimer;\nextern MessageBus devMessageBus;\nextern codal::CodalDevice device;\n\nvoid set_usb_strings(const char *uf2_info);\nextern void (*logJDFrame)(const uint8_t *data);\nextern void (*sendJDFrame)(const uint8_t *data);\n\nstatic inline void raiseEvent(int src, int val) {\n    Event(src, val);\n}\n\n} // namespace pxt\n\nnamespace pins {\nclass CodalSPIProxy;\nclass CodalI2CProxy;\n} // namespace pins\n\ntypedef pins::CodalI2CProxy* I2C_;\ntypedef pins::CodalSPIProxy* SPI_;\n\nnamespace pxt {\ncodal::LowLevelTimer *allocateTimer();\n\n#ifdef CODAL_I2C\nCODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl);\n#endif\nCODAL_SPI* getSPI(DigitalInOutPin mosi, DigitalInOutPin miso, DigitalInOutPin sck);\n#ifdef CODAL_JACDAC_WIRE_SERIAL\nLowLevelTimer* getJACDACTimer();\n#endif\nclass PressureButton;\nuint32_t readButtonMultiplexer(int bits);\nvoid disableButtonMultiplexer();\n}\n\nnamespace serial {\nclass CodalSerialDeviceProxy;\n}\n\ntypedef serial::CodalSerialDeviceProxy* SerialDevice;\n\nnamespace jacdac {\nclass JDProxyDriver;\n} // namespace network\n\ntypedef jacdac::JDProxyDriver* JacDacDriverStatus;\n\n#define DEVICE_ID_BUTTON_SLIDE 3000\n#define DEVICE_ID_MICROPHONE 3001\n#define DEVICE_ID_FIRST_BUTTON 4000\n#define DEVICE_ID_FIRST_TOUCHBUTTON 4100\n\n#define PXT_INTERNAL_KEY_UP 2050\n#define PXT_INTERNAL_KEY_DOWN 2051\n\n#endif\n","pxt.json":"{\n    \"name\": \"core---stm32\",\n    \"description\": \"The core library for Codal-based targets\",\n    \"dependencies\": {\n        \"base\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"dal.d.ts\",\n        \"codal.cpp\",\n        \"usb.cpp\",\n        \"pxt.h\",\n        \"platform.h\",\n        \"platform.cpp\",\n        \"pxtcore.h\",\n        \"pins.h\",\n        \"pins.cpp\",\n        \"pinsAnalog.cpp\",\n        \"pinsDigital.cpp\",\n        \"pinsPWM.cpp\",\n        \"pins.ts\",\n        \"pinscompat.ts\",\n        \"control.cpp\",\n        \"i2c.cpp\",\n        \"i2c.ts\",\n        \"spi.cpp\",\n        \"spi.ts\",\n        \"shims.d.ts\",\n        \"enums.d.ts\",\n        \"hf2.cpp\",\n        \"hf2.h\",\n        \"hf2dbg.h\",\n        \"uf2format.h\",\n        \"uf2hid.h\",\n        \"ns.ts\",\n        \"dmac.cpp\",\n        \"dmac.h\",\n        \"timer.ts\",\n        \"light.cpp\",\n        \"light.h\",\n        \"keyvaluestorage.cpp\",\n        \"keyvaluestorage.ts\",\n        \"leveldetector.ts\",\n        \"pxtparts.json\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"yotta\": {\n        \"config\": {\n            \"codal\": {\n                \"component_count\": 64,\n                \"dmesg_buffer_size\": 1024\n            }\n        }\n    },\n    \"dalDTS\": {\n        \"includeDirs\": [\n            \"libraries/codal-core/inc\",\n            \"pxtapp\"\n        ],\n        \"excludePrefix\": [\n            \"JD_\",\n            \"USB_\",\n            \"REQUEST_\",\n            \"LIS3DH_\",\n            \"FXOS8700_\",\n            \"HF2_\",\n            \"PXT_REF_TAG_\",\n            \"MS_\",\n            \"SCSI_\",\n            \"MAG_\",\n            \"MAG3\",\n            \"MPU6\",\n            \"MADCTL\",\n            \"MMA8\"\n        ]\n    }\n}\n","pxtcore.h":"#ifndef __PXTCORE_H\n#define __PXTCORE_H\n\n#include \"CodalDmesg.h\"\n#include \"CodalHeapAllocator.h\"\n\n#define PXT_CODAL 1\n\n#define itoa(a, b) codal::itoa(a, b)\n\n#define GC_GET_HEAP_SIZE() device_heap_size(0)\n#define GC_STACK_BASE DEVICE_STACK_BASE\n#define xmalloc device_malloc\n#define xfree device_free\n\n// on most devices we allocate the entire heap at once, so large allocs should work\n// if they don't you just get the regular out of memory instead of alloc too large\n#define GC_MAX_ALLOC_SIZE (128 * 1024)\n\n#endif\n","pxtparts.json":"{\n    \"neopixel\": {\n        \"simulationBehavior\": \"neopixel\",\n        \"visual\": {\n            \"builtIn\": \"neopixel\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 19,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 28,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createStrip,light.createNeoPixelStrip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"dotstar\": {\n        \"simulationBehavior\": \"dotstar\",\n        \"visual\": {\n            \"builtIn\": \"dotstar\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 1\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createAPA102Strip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"dataPin\"\n                },\n                {\n                    \"pinInstantiationIdx\": 1,\n                    \"partParameter\": \"clkPin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },\n    \"pixels\": {\n        \"simulationBehavior\": \"pixels\",\n        \"visual\": { \n            \"builtIn\": \"pixels\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"MOSI\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"SCK\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },    \n    \"buttons\": {\n        \"simulationBehavior\": \"buttons\",\n        \"visual\": {\n            \"builtIn\": \"buttons\",\n            \"width\": 75,\n            \"height\": 45,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 30,\n                    \"y\": 45\n                }\n            ]\n        },\n        \"numberOfPins\": 2,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"Button.onEvent,Button.isPressed,Button.wasPressed\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"button\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"slideswitch\": {\n        \"numberOfPins\": 3,\n        \"simulationBehavior\": \"slideswitch\",\n        \"visual\": {\n            \"builtIn\": \"slideswitch\",\n            \"width\": 100,\n            \"height\": 100,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalRead,DigitalInOutPin.onPulsed,DigitalInOutPin.onEvent\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"microservo\": {\n        \"simulationBehavior\": \"microservo\",\n        \"visual\": {\n            \"builtIn\": \"microservo\",\n            \"width\": 74.85,\n            \"height\": 200,\n            \"pinDistance\": 10,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 37,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 5\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"PwmOnlyPin.servoWrite,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"led\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"analogled\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogOutPin.analogWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"photocell\": {\n        \"numberOfPins\": 3,\n        \"visual\": {\n            \"builtIn\": \"photocell\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 15,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"photocell\",\n        \"pinDefinitions\": [\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogInPin.analogRead\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace light {\n\n    /**\n     * Send a programmable light buffer to the specified digital pin\n     * @param data The pin that the lights are connected to\n     * @param clk the clock line if any\n     * @param mode the color encoding mode\n     * @param buf The buffer to send to the pin\n     */\n    //% shim=light::sendBuffer\n    function sendBuffer(data: DigitalInOutPin, clk: DigitalInOutPin, mode: int32, buf: Buffer): void;\n}\ndeclare namespace control {\n\n    /**\n     * Determines if the USB has been enumerated.\n     */\n    //% shim=control::isUSBInitialized\n    function isUSBInitialized(): boolean;\n}\ndeclare namespace pins {\n\n    /**\n     * Get a pin by configuration id (DAL.CFG_PIN...)\n     */\n    //% shim=pins::pinByCfg\n    function pinByCfg(key: int32): DigitalInOutPin;\n\n    /**\n     * Create a new zero-initialized buffer.\n     * @param size number of bytes in the buffer\n     */\n    //% shim=pins::createBuffer\n    function createBuffer(size: int32): Buffer;\n\n    /**\n     * Get the duration of the last pulse in microseconds. This function should be called from a\n     * ``onPulsed`` handler.\n     */\n    //% help=pins/pulse-duration blockGap=8\n    //% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n    //% weight=19 shim=pins::pulseDuration\n    function pulseDuration(): int32;\n}\n\n\ndeclare interface AnalogInPin {\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 weight=53\n    //% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=AnalogInPinMethods::analogRead\n    analogRead(): int32;\n}\n\n\ndeclare interface AnalogOutPin {\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 weight=52\n    //% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4\n    //% value.min=0 value.max=1023 shim=AnalogOutPinMethods::analogWrite\n    analogWrite(value: int32): void;\n}\n\n\ndeclare interface DigitalInOutPin {\n    /**\n     * Read a pin or connector as either 0 or 1\n     * @param name pin to read from\n     */\n    //% help=pins/digital-read weight=61\n    //% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::digitalRead\n    digitalRead(): boolean;\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\n     */\n    //% help=pins/digital-write weight=60\n    //% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::digitalWrite\n    digitalWrite(value: boolean): void;\n\n    /**\n     * Make this pin a digital input, and create events where the timestamp is the duration\n     * that this pin was either ``high`` or ``low``.\n     */\n    //% help=pins/on-pulsed weight=16 blockGap=8\n    //% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4\n    //% deprecated=1 hidden=1 shim=DigitalInOutPinMethods::onPulsed\n    onPulsed(pulse: PulseValue, body: () => void): void;\n\n    /**\n     * Register code to run when a pin event occurs. \n     */\n    //% help=pins/on-event weight=20 blockGap=8\n    //% blockId=pinsonevent block=\"on|pin %pin|%event\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4 shim=DigitalInOutPinMethods::onEvent\n    onEvent(event: PinEvent, body: () => void): void;\n\n    /**\n     * Return 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 %high||timeout %maxDuration (µs)\"\n    //% weight=18 blockGap=8\n    //% help=\"pins/pulse-in\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4 maxDuration.defl=2000000 shim=DigitalInOutPinMethods::pulseIn\n    pulseIn(value: PulseValue, maxDuration?: int32): int32;\n\n    /**\n     * Set the pull direction 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=17 blockGap=8\n    //% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::setPull\n    setPull(pull: PinPullMode): void;\n}\n\n\ndeclare interface PwmPin {}\n\n\ndeclare interface PwmOnlyPin {\n    /**\n     * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n     * **microseconds** or `1/1000` milliseconds.\n     * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n     * 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=51\n    //% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::analogSetPeriod\n    analogSetPeriod(period: int32): void;\n\n    /**\n     * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n     * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n     * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n     * 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\n     */\n    //% help=pins/servo-write weight=41 group=\"Servo\"\n    //% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n    //% parts=microservo trackArgs=0\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4\n    //% value.defl=90 shim=PwmOnlyPinMethods::servoWrite\n    servoWrite(value?: int32): void;\n\n    /**\n     * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n     * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n     * @param name pin name\n     * @param duration pulse duration in micro seconds, eg:1500\n     */\n    //% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n    //% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n    //% parts=microservo blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::servoSetPulse\n    servoSetPulse(duration: int32): void;\n\n    /**\n     * Indicates if the servo is running continuously\n     */\n    //% blockHidden=1 shim=PwmOnlyPinMethods::servoSetContinuous\n    servoSetContinuous(continuous: boolean): void;\n}\ndeclare namespace control {\n\n    /**\n     * Announce that an event happened to registered handlers.\n     * @param src ID of the MicroBit Component that generated the event\n     * @param value Component specific code indicating the cause of the event.\n     */\n    //% weight=21 blockGap=12 blockId=\"control_raise_event\"\n    //% help=control/raise-event\n    //% block=\"raise event|from %src|with value %value\" blockExternalInputs=1 shim=control::raiseEvent\n    function raiseEvent(src: int32, value: int32): void;\n\n    /**\n     * Determine the version of system software currently running.\n     */\n    //% blockId=\"control_device_dal_version\" block=\"device dal version\"\n    //% help=control/device-dal-version shim=control::deviceDalVersion\n    function deviceDalVersion(): string;\n\n    /**\n     * Allocates the next user notification event\n     */\n    //% help=control/allocate-notify-event shim=control::allocateNotifyEvent\n    function allocateNotifyEvent(): int32;\n\n    /** Write a message to DMESG debugging buffer. */\n    //% shim=control::dmesg\n    function dmesg(s: string): void;\n\n    /** Write a message and value (pointer) to DMESG debugging buffer. */\n    //% shim=control::dmesgPtr\n    function dmesgPtr(str: string, ptr: Object): void;\n}\n\n\ndeclare interface I2C {\n    /**\n     * Read `size` bytes from a 7-bit I2C `address`.\n     */\n    //% repeat.defl=0 shim=I2CMethods::readBuffer\n    readBuffer(address: int32, size: int32, repeat?: boolean): Buffer;\n\n    /**\n     * Write bytes to a 7-bit I2C `address`.\n     */\n    //% repeat.defl=0 shim=I2CMethods::writeBuffer\n    writeBuffer(address: int32, buf: Buffer, repeat?: boolean): int32;\n}\ndeclare namespace pins {\n\n    /**\n     * Opens a Serial communication driver\n     */\n    //% help=pins/create-i2c\n    //% parts=i2c shim=pins::createI2C\n    function createI2C(sda: DigitalInOutPin, scl: DigitalInOutPin): I2C;\n}\ndeclare namespace pins {\n\n    /**\n     * Opens a SPI driver\n     */\n    //% help=pins/create-spi\n    //% parts=spi shim=pins::createSPI\n    function createSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin): SPI;\n\n    /**\n     * Opens a slave SPI driver\n     */\n    //% parts=spi shim=pins::createSlaveSPI\n    function createSlaveSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin, csPin: DigitalInOutPin): SPI;\n}\n\n\ndeclare interface SPI {\n    /**\n     * Write to the SPI bus\n     */\n    //% shim=SPIMethods::write\n    write(value: int32): int32;\n\n    /**\n     * Transfer buffers over the SPI bus\n     */\n    //% argsNullable shim=SPIMethods::transfer\n    transfer(command: Buffer, response: Buffer): void;\n\n    /**\n     * Sets the SPI clock frequency\n     */\n    //% shim=SPIMethods::setFrequency\n    setFrequency(frequency: int32): void;\n\n    /**\n     * Sets the SPI bus mode\n     */\n    //% shim=SPIMethods::setMode\n    setMode(mode: int32): void;\n}\ndeclare namespace configStorage {\n\n    /**\n     * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n     * @param key the identifier (max 16 characters)\n     * @param value the data (max 32 characters)\n     */\n    //% shim=configStorage::setBuffer\n    function setBuffer(key: string, value: Buffer): void;\n\n    /**\n     * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n     * @param key the identifier (max 16 characters)\n     */\n    //% shim=configStorage::getBuffer\n    function getBuffer(key: string): Buffer;\n\n    /**\n     * Removes the key from local storage\n     * @param key the identifier (max 16 characters)\n     */\n    //% shim=configStorage::removeItem\n    function removeItem(key: string): void;\n\n    /**\n     * Clears the local storage\n     */\n    //% shim=configStorage::clear\n    function clear(): void;\n}\n\n// Auto-generated. Do not edit. Really.\n","spi.cpp":"#include \"pxt.h\"\n#include \"ErrorNo.h\"\n\nnamespace pins {\n\nclass CodalSPIProxy {\nprivate:\n    DevicePin* mosi; \n    DevicePin* miso; \n    DevicePin* sck;\n    CODAL_SPI spi;\npublic:\n    CodalSPIProxy* next;\n\npublic:\n    CodalSPIProxy(DevicePin* _mosi, DevicePin* _miso, DevicePin* _sck)\n        : mosi(_mosi)\n        , miso(_miso)\n        , sck(_sck)\n        , spi(*_mosi, *_miso, *_sck) \n        , next(NULL)\n    {\n    }\n\n#ifdef CODAL_SPI_SLAVE_SUPPORTED\n    CodalSPIProxy(DevicePin* _mosi, DevicePin* _miso, DevicePin* _sck, DevicePin* _cs)\n        : mosi(_mosi)\n        , miso(_miso)\n        , sck(_sck)\n        , spi(*_mosi, *_miso, *_sck, _cs) \n        , next(NULL)\n    {\n    }\n#endif\n\n    CODAL_SPI* getSPI() {\n        return &spi;\n    }\n\n    bool matchPins(DevicePin* mosi, DevicePin* miso, DevicePin* sck) {\n        return this->mosi == mosi && this->miso == miso && this->sck == sck;\n    }\n\n    int write(int value) {\n        return spi.write(value);\n    }\n\n    void transfer(Buffer command, Buffer response) {\n        auto cdata = NULL == command ? NULL : command->data;\n        auto clength = NULL == command ? 0 : command->length;\n        auto rdata = NULL == response ? NULL : response->data;\n        auto rlength = NULL == response ? 0 : response->length;\n        spi.transfer(cdata, clength, rdata, rlength);\n    }\n\n    void setFrequency(int frequency) {\n        spi.setFrequency(frequency);\n    }\n\n    void setMode(int mode) {\n        spi.setMode(mode);\n    }\n};\n\nSPI_ spis(NULL);\n\n/**\n* Opens a SPI driver\n*/\n//% help=pins/create-spi\n//% parts=spi\nSPI_ createSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin) {\n  auto dev = spis;\n  while(dev) {\n    if (dev->matchPins(mosiPin, misoPin, sckPin))\n      return dev;\n    dev = dev->next;\n  }\n\n  auto ser = new CodalSPIProxy(mosiPin, misoPin, sckPin);\n  ser->next = spis;\n  spis = ser;\n  return ser;\n}\n\n/**\n* Opens a slave SPI driver\n*/\n//% parts=spi\nSPI_ createSlaveSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin, DigitalInOutPin csPin) {\n#ifdef CODAL_SPI_SLAVE_SUPPORTED\n  auto dev = spis;\n  if (!csPin)\n    soft_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n  while(dev) {\n    if (dev->matchPins(mosiPin, misoPin, sckPin))\n      return dev;\n    dev = dev->next;\n  }\n\n  auto ser = new CodalSPIProxy(mosiPin, misoPin, sckPin, csPin);\n  ser->next = spis;\n  spis = ser;\n  return ser;\n#else\n  soft_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n  return NULL;\n#endif\n}\n\n}\n\nnamespace pxt {\n\nCODAL_SPI* getSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin) {\n    auto spi = pins::createSPI(mosiPin, misoPin, sckPin);\n    return spi->getSPI();\n}\n\n}\n\nnamespace SPIMethods {\n\n/**\n* Write to the SPI bus\n*/\n//%\nint write(SPI_ device, int value) {\n    return device->write(value);\n}\n\n/**\n* Transfer buffers over the SPI bus\n*/\n//% argsNullable\nvoid transfer(SPI_ device, Buffer command, Buffer response) {\n    if (!device)\n        soft_panic(PANIC_CAST_FROM_NULL);\n    if (!command && !response)\n        return;\n    device->transfer(command, response);\n}\n\n/**\n* Sets the SPI clock frequency\n*/\n//%\nvoid setFrequency(SPI_ device, int frequency) {\n    device->setFrequency(frequency);\n}\n\n/**\n* Sets the SPI bus mode\n*/\n//%\nvoid setMode(SPI_ device, int mode) {\n    device->setMode(mode);\n}\n\n}\n","spi.ts":"namespace pins {\n\n    let _spi: SPI;\n    /**\n    * Gets the default SPI driver\n    */\n    //%\n    export function spi() {\n        if (!_spi) {\n            const mosi = pins.pinByCfg(DAL.CFG_PIN_MOSI);\n            const miso = pins.pinByCfg(DAL.CFG_PIN_MISO);\n            const sck = pins.pinByCfg(DAL.CFG_PIN_SCK);\n            _spi = pins.createSPI(mosi, miso, sck);\n        }\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 advanced=true\n    //% blockId=spi_write block=\"spi write %value\"\n    export function spiWrite(value: number) {\n        return spi().write(value);\n    }\n\n    /**\n     * Write a given command to SPI bus, and at the same time read the response.\n     */\n    //% help=pins/spi-transfer weight=4 advanced=true\n    //% blockId=spi_transfer block=\"spi transfer %command into %response\"\n    export function spiTransfer(command: Buffer, response: Buffer) {\n        spi().transfer(command, response);\n    }\n\n    /**\n     * Set the SPI frequency\n     * @param frequency the clock frequency, eg: 1000000\n     */\n    //% help=pins/spi-frequency weight=4 advanced=true\n    //% blockId=spi_frequency block=\"spi frequency %frequency\"\n    export function spiFrequency(frequency: number) {\n        spi().setFrequency(frequency);\n    }\n\n    /**\n     * Set the SPI signal mode\n     * @param mode the mode, eg: 3\n     */\n    //% help=pins/spi-mode weight=3 advanced=true\n    //% blockId=spi_mode block=\"spi mode %mode\"\n    export function spiMode(mode: number) {\n        spi().setMode(mode);\n    }\n}","test.ts":"let i = 1\nlet f = 0.5\nlet plus = i + f\nlet minus = i - f\n\nlet r = Math.random()\nlet ri = Math.randomRange(5, 10)\n\n","timer.ts":"namespace control {\n    /**\n     * A timer\n     */\n    //% fixedInstances\n    export class Timer {\n        start: number;\n\n        constructor() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Gets the elapsed time in millis since the last reset\n         */\n        //% blockId=timerMillis block=\"%timer|millis\"\n        millis(): number {\n            return control.millis() - this.start;\n        }\n\n        /**\n         * Gets the elapsed time in seconds since the last reset\n         */\n        //% blockId=timerSeconds block=\"%timer|seconds\"\n        seconds(): number {\n            return this.millis() / 1000;\n        }\n\n        /**\n         * Resets the timer\n         */\n        //% blockId=timerRest block=\"%timer|reset\"\n        reset() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Pauses until the timer reaches the given amount of milliseconds\n         * @param ms how long to pause for, eg: 5, 100, 200, 500, 1000, 2000\n         */\n        //% blockId=timerPauseUntil block=\"%timer|pause until (ms) %ms\"\n        pauseUntil(ms: number) {\n            const remaining = this.millis() - ms;\n            pause(Math.max(0, remaining));\n        }\n    }\n\n    //% whenUsed fixedInstance block=\"timer 1\"\n    export const timer1 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 2\"\n    export const timer2 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 3\"\n    export const timer3 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 4\"\n    export const timer4 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 5\"\n    export const timer5 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 6\"\n    export const timer6 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 7\"\n    export const timer7 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 8\"\n    export const timer8 = new Timer();\n}","uf2format.h":"#ifndef UF2FORMAT_H\n#define UF2FORMAT_H 1\n\n#include <stdint.h>\n#include <stdbool.h>\n\n// All entries are little endian.\n\n#ifndef BOOTLOADER_START\n#define BOOTLOADER_START 0x0\n#endif\n\n#ifndef BOOTLOADER_END\n#define BOOTLOADER_END 0x2000\n#endif\n\n#ifndef UF2_BINFO\n#define UF2_BINFO ((UF2_BInfo *)(BOOTLOADER_END - sizeof(UF2_BInfo)))\n#endif\n\n#ifndef UF2_INFO_TXT\n#define UF2_INFO_TXT UF2_BINFO->info_uf2\n#endif\n\n\n#define UF2_MAGIC_START0 0x0A324655UL // \"UF2\\n\"\n#define UF2_MAGIC_START1 0x9E5D5157UL // Randomly selected\n#define UF2_MAGIC_END 0x0AB16F30UL    // Ditto\n\n// If set, the block is \"comment\" and should not be flashed to the device\n#define UF2_FLAG_NOFLASH 0x00000001\n\ntypedef struct {\n    // 32 byte header\n    uint32_t magicStart0;\n    uint32_t magicStart1;\n    uint32_t flags;\n    uint32_t targetAddr;\n    uint32_t payloadSize;\n    uint32_t blockNo;\n    uint32_t numBlocks;\n    uint32_t reserved;\n\n    // raw data;\n    uint8_t data[476];\n\n    // store magic also at the end to limit damage from partial block reads\n    uint32_t magicEnd;\n} UF2_Block;\n\ntypedef struct {\n    uint8_t version;\n    uint8_t ep_in;\n    uint8_t ep_out;\n    uint8_t reserved0;\n    uint32_t cbw_tag;\n    uint32_t blocks_remaining;\n    uint8_t *buffer;\n} UF2_HandoverArgs;\n\ntypedef void (*UF2_MSC_Handover_Handler)(UF2_HandoverArgs *handover);\ntypedef void (*UF2_HID_Handover_Handler)(int ep);\n\n// this is required to be exactly 16 bytes long by the linker script\ntypedef struct {\n    void *reserved0;\n    UF2_HID_Handover_Handler handoverHID;\n    UF2_MSC_Handover_Handler handoverMSC;\n    const char *info_uf2;\n} UF2_BInfo;\n\nstatic inline bool is_uf2_block(void *data) {\n    UF2_Block *bl = (UF2_Block *)data;\n    return bl->magicStart0 == UF2_MAGIC_START0 && bl->magicStart1 == UF2_MAGIC_START1 &&\n           bl->magicEnd == UF2_MAGIC_END;\n}\n\nstatic inline bool in_uf2_bootloader_space(const void *addr) {\n    return (BOOTLOADER_START + 0x100) <= (uint32_t)addr && (uint32_t)addr < (BOOTLOADER_END);\n}\n\nstatic inline const char *uf2_info(void) {\n    if (in_uf2_bootloader_space(UF2_INFO_TXT))\n        return UF2_INFO_TXT;\n    return \"N/A\";\n}\n\n#ifdef UF2_DEFINE_HANDOVER\nstatic inline void hf2_handover(uint8_t ep) {\n    const char *board_info = UF2_BINFO->info_uf2;\n    UF2_HID_Handover_Handler fn = UF2_BINFO->handoverHID;\n\n    if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&\n        ((uint32_t)fn & 1)) {\n        // Pass control to bootloader; never returns\n        fn(ep & 0xf);\n    }\n}\n\nstatic inline void check_uf2_handover(uint8_t *buffer, uint32_t blocks_remaining, uint8_t ep_in,\n                                      uint8_t ep_out, uint32_t cbw_tag) {\n    if (!is_uf2_block(buffer))\n        return;\n\n    const char *board_info = UF2_BINFO->info_uf2;\n    UF2_MSC_Handover_Handler fn = UF2_BINFO->handoverMSC;\n\n    if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&\n        ((uint32_t)fn & 1)) {\n        UF2_HandoverArgs hand = {\n            1, ep_in, ep_out, 0, cbw_tag, blocks_remaining, buffer,\n        };\n        // Pass control to bootloader; never returns\n        fn(&hand);\n    }\n}\n#endif\n\n#endif\n","uf2hid.h":"#ifndef UF2_HID_H\n#define UF2_HID_H 1\n\n#define HF2_CMD_BININFO 0x0001\n// no arguments\n#define HF2_MODE_BOOTLOADER 0x01\n#define HF2_MODE_USERSPACE 0x02\nstruct HF2_BININFO_Result {\n    uint32_t mode;\n    uint32_t flash_page_size;\n    uint32_t flash_num_pages;\n    uint32_t max_message_size;\n    uint32_t uf2_family;\n};\n\n#define HF2_CMD_INFO 0x0002\n// no arguments\n// results is utf8 character array\n\n#define HF2_CMD_RESET_INTO_APP 0x0003\n// no arguments, no result\n\n#define HF2_CMD_RESET_INTO_BOOTLOADER 0x0004\n// no arguments, no result\n\n#define HF2_CMD_START_FLASH 0x0005\n// no arguments, no result\n\n#define HF2_CMD_WRITE_FLASH_PAGE 0x0006\nstruct HF2_WRITE_FLASH_PAGE_Command {\n    uint32_t target_addr;\n    uint32_t data[0];\n};\n// no result\n\n#define HF2_CMD_CHKSUM_PAGES 0x0007\nstruct HF2_CHKSUM_PAGES_Command {\n    uint32_t target_addr;\n    uint32_t num_pages;\n};\nstruct HF2_CHKSUM_PAGES_Result {\n    uint16_t chksums[0 /* num_pages */];\n};\n\n#define HF2_CMD_READ_WORDS 0x0008\nstruct HF2_READ_WORDS_Command {\n    uint32_t target_addr;\n    uint32_t num_words;\n};\nstruct HF2_READ_WORDS_Result {\n    uint32_t words[0 /* num_words */];\n};\n\n#define HF2_CMD_WRITE_WORDS 0x0009\nstruct HF2_WRITE_WORDS_Command {\n    uint32_t target_addr;\n    uint32_t num_words;\n    uint32_t words[0 /* num_words */];\n};\n// no result\n\n#define HF2_CMD_DMESG 0x0010\n// no arguments\n// results is utf8 character array\n\n#define HF2_EV_MASK 0x800000\n\n#define HF2_CMD_JDS_CONFIG 0x0020\n#define HF2_CMD_JDS_SEND 0x0021\n#define HF2_EV_JDS_PACKET 0x800020\n\ntypedef struct {\n    uint32_t command_id;\n    uint16_t tag;\n    uint8_t reserved0;\n    uint8_t reserved1;\n\n    union {\n        struct HF2_WRITE_FLASH_PAGE_Command write_flash_page;\n        struct HF2_WRITE_WORDS_Command write_words;\n        struct HF2_READ_WORDS_Command read_words;\n        struct HF2_CHKSUM_PAGES_Command chksum_pages;\n        uint8_t data8[0];\n        uint16_t data16[0];\n        uint32_t data32[0];\n    };\n} HF2_Command;\n\ntypedef struct {\n    union {\n        uint32_t eventId;\n        struct {\n            uint16_t tag;\n            union {\n                struct {\n                    uint8_t status;\n                    uint8_t status_info;\n                };\n                uint16_t status16;\n            };\n        };\n    };\n    union {\n        struct HF2_BININFO_Result bininfo;\n        uint8_t data8[0];\n        uint16_t data16[0];\n        uint32_t data32[0];\n    };\n} HF2_Response;\n\n#define HF2_FLAG_SERIAL_OUT 0x80\n#define HF2_FLAG_SERIAL_ERR 0xC0\n#define HF2_FLAG_CMDPKT_LAST 0x40\n#define HF2_FLAG_CMDPKT_BODY 0x00\n#define HF2_FLAG_MASK 0xC0\n#define HF2_SIZE_MASK 63\n\n#define HF2_STATUS_OK 0x00\n#define HF2_STATUS_INVALID_CMD 0x01\n#define HF2_STATUS_INVALID_STATE 0x02\n\n#endif\n","usb.cpp":"#include \"pxt.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"uf2format.h\"\n\nnamespace pxt {\nCodalUSB usb;\n\n// share the buffer; we will crash anyway if someone talks to us over both at the same time\nHF2_Buffer hf2buf;\nHF2 hf2(hf2buf);\n#ifdef HF2_HID\nHF2 hf2hid(hf2buf);\n#endif\nDummyIface dummyIface;\n\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nUSBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nUSBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nUSBHIDJoystick joystick;\n#endif\n\nstatic const DeviceDescriptor device_desc = {\n    0x12,   // bLength\n    0x01,   // bDescriptorType\n    0x0210, // bcdUSBL\n\n    // Class etc specified per-interface\n    0x00, 0x00, 0x00,\n\n    0x40, // bMaxPacketSize0\n    USB_DEFAULT_VID, USB_DEFAULT_PID,\n    0x4202, // bcdDevice - leave unchanged for the HF2 to work\n    0x01,   // iManufacturer\n    0x02,   // iProduct\n    0x03,   // SerialNumber\n    0x01    // bNumConfigs\n};\n\nstatic void start_usb() {\n    // start USB with a delay, so that user code can add new interfaces if needed\n    // (eg USB HID keyboard, or MSC)\n    fiber_sleep(500);\n    usb.start();\n}\n\nvoid platform_usb_init() __attribute__((weak));\nvoid platform_usb_init() {}\n\nvoid set_usb_strings(const char *uf2_info) {\n    static const char *string_descriptors[3];\n    static char serial[12];\n    itoa(target_get_serial() & 0x7fffffff, serial);\n\n    auto model = strstr(uf2_info, \"Model: \");\n    if (model) {\n        model += 7;\n        auto end = model;\n        while (*end && *end != '\\n' && *end != '\\r')\n            end++;\n        auto len = end - model;\n        auto dev = (char *)app_alloc(len + 10);\n        memcpy(dev, model, len);\n        strcpy(dev + len, \" (app)\");\n        // try to split into manufacturer and\n        auto sep = strstr(dev, \" / \");\n        if (sep) {\n            *sep = '\\0';\n            string_descriptors[0] = dev;\n            string_descriptors[1] = sep + 3;\n        } else {\n            string_descriptors[0] = dev;\n            string_descriptors[1] = dev;\n        }\n    } else {\n        string_descriptors[0] = \"Unknown Corp.\";\n        string_descriptors[1] = \"PXT Device (app)\";\n    }\n\n    string_descriptors[2] = serial;\n    usb.stringDescriptors = string_descriptors;\n}\n\nvoid usb_init() {\n    usb.deviceDescriptor = &device_desc;\n    set_usb_strings(UF2_INFO_TXT);\n\n    platform_usb_init();\n\n    usb.add(hf2);\n\n#ifdef HF2_HID\n    hf2hid.useHID = true;\n    usb.add(hf2hid);\n#else\n    // the WINUSB descriptors don't seem to work if there's only one interface\n    // so we add a dummy interface\n    usb.add(dummyIface);\n#endif\n\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n    usb.add(mouse);\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n    usb.add(keyboard);\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n    usb.add(joystick);\n#endif\n\n    create_fiber(start_usb);\n}\n\n} // namespace pxt\n\n#else\nnamespace pxt {\nvoid usb_init() {}\n} // namespace pxt\n#endif\n\nnamespace control {\n/**\n * Determines if the USB has been enumerated.\n */\n//%\nbool isUSBInitialized() {\n#if CONFIG_ENABLED(DEVICE_USB)\n    return pxt::usb.isInitialised();\n#else\n    return false;\n#endif\n}\n} // namespace control\n\nnamespace pxt {\nstatic void (*pSendToUART)(const char *data, int len) = NULL;\nvoid setSendToUART(void (*f)(const char *, int)) {\n    pSendToUART = f;\n}\n\nvoid sendSerial(const char *data, int len) {\n#if CONFIG_ENABLED(DEVICE_USB)\n    hf2.sendSerial(data, len);\n#if HF2_HID\n    hf2hid.sendSerial(data, len);\n#endif\n#endif\n    if (pSendToUART)\n        pSendToUART(data, len);\n}\n\nvoid dumpDmesg() {\n    sendSerial(\"\\nDMESG:\\n\", 8);\n    sendSerial(codalLogStore.buffer, codalLogStore.ptr);\n    sendSerial(\"\\n\\n\", 2);\n}\n\nvoid (*logJDFrame)(const uint8_t *data);\nvoid (*sendJDFrame)(const uint8_t *data);\n\n} // namespace pxt\n"},"core---rp2040":{"README.md":"# core\n\nThe core library for Codal-based targets.\n\n","codal.cpp":"#include \"pxt.h\"\n#include \"LowLevelTimer.h\"\nusing namespace codal;\n\nvoid cpu_clock_init(void);\n\nPXT_ABI(__aeabi_dadd)\nPXT_ABI(__aeabi_dcmplt)\nPXT_ABI(__aeabi_dcmpgt)\nPXT_ABI(__aeabi_dsub)\nPXT_ABI(__aeabi_ddiv)\nPXT_ABI(__aeabi_dmul)\n\n#ifdef DEVICE_GET_FIBER_LIST_AVAILABLE\n// newer codal-core has get_fiber_list() but not list_fibers()\nnamespace codal {\n/*\n * Return all current fibers.\n *\n * @param dest If non-null, it points to an array of pointers to fibers to store results in.\n *\n * @return the number of fibers (potentially) stored\n */\nint list_fibers(Fiber **dest) {\n    int i = 0;\n    for (Fiber *fib = codal::get_fiber_list(); fib; fib = fib->next) {\n        if (dest)\n            dest[i] = fib;\n        i++;\n    }\n    return i;\n}\n\n} // namespace codal\n#endif\n\nnamespace pxt {\n\nvoid platform_init();\nvoid usb_init();\n\n// The first two word are used to tell the bootloader that a single reset should start the\n// bootloader and the MSD device, not us.\n// The rest is reserved for partial flashing checksums.\n__attribute__((section(\".binmeta\"))) __attribute__((used)) const uint32_t pxt_binmeta[] = {\n    0x87eeb07c, 0x87eeb07c, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,\n    0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,\n};\n\nEvent lastEvent;\nMessageBus devMessageBus;\ncodal::CodalDevice device;\n\nstruct FreeList {\n    FreeList *next;\n};\n\nstatic void commInit() {\n    int commSize = bytecode[20];\n    if (!commSize)\n        return;\n\n    void *r = app_alloc_at((void *)PXT_COMM_BASE, commSize);\n    DMESG(\"comm %d -> %p\", commSize, r);\n    if (!r)\n        target_panic(20);\n}\n\nstatic void initCodal() {\n    cpu_clock_init();\n\n    commInit();\n\n    // Bring up fiber scheduler.\n    scheduler_init(devMessageBus);\n\n    // We probably don't need that - components are initialized when one obtains\n    // the reference to it.\n    // devMessageBus.listen(DEVICE_ID_MESSAGE_BUS_LISTENER, DEVICE_EVT_ANY, this,\n    // &CircuitPlayground::onListenerRegisteredEvent);\n\n    for (int i = 0; i < DEVICE_COMPONENT_COUNT; i++) {\n        if (CodalComponent::components[i])\n            CodalComponent::components[i]->init();\n    }\n\n    usb_init();\n\n    auto led = LOOKUP_PIN(LED);\n    if (led) {\n        led->setDigitalValue(0);\n    }\n}\n\n// ---------------------------------------------------------------------------\n// An adapter for the API expected by the run-time.\n// ---------------------------------------------------------------------------\n\n// We have the invariant that if [dispatchEvent] is registered against the DAL\n// for a given event, then [handlersMap] contains a valid entry for that\n// event.\nvoid dispatchEvent(Event e) {\n    lastEvent = e;\n\n    auto curr = findBinding(e.source, e.value);\n    auto value = fromInt(e.value);\n    while (curr) {\n        runAction1(curr->action, value);\n        curr = nextBinding(curr->next, e.source, e.value);\n    }\n}\n\nvoid registerWithDal(int id, int event, Action a, int flags) {\n    // first time?\n    if (!findBinding(id, event)) {\n        devMessageBus.listen(id, event, dispatchEvent, flags);\n        if (event == 0) {\n            // we're registering for all events on given ID\n            // need to remove old listeners for specific events\n            auto curr = findBinding(id, -1);\n            while (curr) {\n                devMessageBus.ignore(id, curr->value, dispatchEvent);\n                curr = nextBinding(curr->next, id, -1);\n            }\n        }\n    }\n    setBinding(id, event, a);\n}\n\nvoid fiberDone(void *a) {\n    unregisterGCPtr((Action)a);\n    release_fiber();\n}\n\nvoid releaseFiber() {\n    release_fiber();\n}\n\nvoid sleep_ms(unsigned ms) {\n    fiber_sleep(ms);\n}\n\nvoid sleep_us(uint64_t us) {\n    target_wait_us(us);\n}\n\nvoid forever_stub(void *a) {\n    while (true) {\n        runAction0((Action)a);\n        fiber_sleep(20);\n    }\n}\n\nvoid runForever(Action a) {\n    if (a != 0) {\n        registerGCPtr(a);\n        create_fiber(forever_stub, (void *)a);\n    }\n}\n\nvoid runInParallel(Action a) {\n    if (a != 0) {\n        registerGCPtr(a);\n        create_fiber((void (*)(void *))(void*)runAction0, (void *)a, fiberDone);\n    }\n}\n\nvoid waitForEvent(int id, int event) {\n    fiber_wait_for_event(id, event);\n}\n\nvoid initRuntime() {\n    initSystemTimer();\n    initCodal();\n    platform_init();\n}\n\n//%\nunsigned afterProgramPage() {\n    unsigned ptr = (unsigned)&bytecode[0];\n    ptr += programSize();\n    ptr = (ptr + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);\n    return ptr;\n}\n\nuint64_t getLongSerialNumber() {\n    return device.getSerialNumber();\n}\n\nint current_time_ms() {\n    return system_timer_current_time();\n}\n\nuint64_t current_time_us() {\n    return system_timer_current_time_us();\n}\n\nThreadContext *getThreadContext() {\n    if (!currentFiber)\n        return NULL;\n    return (ThreadContext *)currentFiber->user_data;\n}\n\nvoid setThreadContext(ThreadContext *ctx) {\n    currentFiber->user_data = ctx;\n}\n\nstatic void *threadAddressFor(codal::Fiber *fib, void *sp) {\n    if (fib == currentFiber)\n        return sp;\n    return (uint8_t *)sp + ((uint8_t *)fib->stack_top - (uint8_t *)tcb_get_stack_base(fib->tcb));\n}\n\nvoid gcProcessStacks(int flags) {\n    // check scheduler is initialized\n    if (!currentFiber) {\n        // make sure we allocate something to at least initalize the memory allocator\n        void *volatile p = xmalloc(1);\n        xfree(p);\n        return;\n    }\n\n    int numFibers = codal::list_fibers(NULL);\n    codal::Fiber **fibers = (codal::Fiber **)xmalloc(sizeof(codal::Fiber *) * numFibers);\n    int num2 = codal::list_fibers(fibers);\n    if (numFibers != num2)\n        oops(12);\n    int cnt = 0;\n\n    for (int i = 0; i < numFibers; ++i) {\n        auto fib = fibers[i];\n        auto ctx = (ThreadContext *)fib->user_data;\n        if (!ctx)\n            continue;\n        gcProcess(ctx->thrownValue);\n        for (auto seg = &ctx->stack; seg; seg = seg->next) {\n            auto ptr = (TValue *)threadAddressFor(fib, seg->top);\n            auto end = (TValue *)threadAddressFor(fib, seg->bottom);\n            if (flags & 2)\n                DMESG(\"RS%d:%p/%d\", cnt++, ptr, end - ptr);\n            // VLOG(\"mark: %p - %p\", ptr, end);\n            while (ptr < end) {\n                gcProcess(*ptr++);\n            }\n        }\n    }\n    xfree(fibers);\n}\n\nLowLevelTimer *getJACDACTimer() {\n    static LowLevelTimer *jacdacTimer;\n    if (!jacdacTimer) {\n        jacdacTimer = allocateTimer();\n        jacdacTimer->setIRQPriority(1);\n    }\n    return jacdacTimer;\n}\nvoid initSystemTimer() {\n    new CODAL_TIMER(*allocateTimer());\n}\n\n} // namespace pxt\n","control.cpp":"#include \"pxt.h\"\n\n#if defined(NRF52_SERIES) || defined(PICO_BOARD)\n#define _estack __StackTop \n#endif\nextern uint32_t _estack;\n\nnamespace control {\n\n/**\n * Announce that an event happened to registered handlers.\n * @param src ID of the MicroBit Component that generated the event\n * @param value Component specific code indicating the cause of the event.\n */\n//% weight=21 blockGap=12 blockId=\"control_raise_event\"\n//% help=control/raise-event\n//% block=\"raise event|from %src|with value %value\" blockExternalInputs=1\nvoid raiseEvent(int src, int value) {\n    Event evt(src, value);\n}\n\n/**\n* Determine the version of system software currently running.\n*/\n//% blockId=\"control_device_dal_version\" block=\"device dal version\"\n//% help=control/device-dal-version\nString deviceDalVersion() {\n    return mkString(device.getVersion());\n}\n\n/**\n* Allocates the next user notification event\n*/\n//% help=control/allocate-notify-event\nint allocateNotifyEvent() {\n    return ::allocateNotifyEvent();\n}\n\n/** Write a message to DMESG debugging buffer. */\n//%\nvoid dmesg(String s) {\n    DMESG(\"# %s\", s->getUTF8Data());\n}\n\n/** Write a message and value (pointer) to DMESG debugging buffer. */\n//%\nvoid dmesgPtr(String str, Object_ ptr) {\n    DMESG(\"# %s: %p\", str->getUTF8Data(), ptr);\n}\n\n//%\nuint32_t _ramSize()\n{\n    return (uint32_t)&_estack & 0x1fffffff;\n}\n\n}\n","dal.d.ts":"// Auto-generated. Do not edit.\ndeclare const enum DAL {\n    // /libraries/codal-core/inc/core/CodalComponent.h\n    DEVICE_ID_BUTTON_A = 1,\n    DEVICE_ID_BUTTON_B = 2,\n    DEVICE_ID_BUTTON_AB = 3,\n    DEVICE_ID_BUTTON_RESET = 4,\n    DEVICE_ID_ACCELEROMETER = 5,\n    DEVICE_ID_COMPASS = 6,\n    DEVICE_ID_DISPLAY = 7,\n    DEVICE_ID_THERMOMETER = 8,\n    DEVICE_ID_RADIO = 9,\n    DEVICE_ID_RADIO_DATA_READY = 10,\n    DEVICE_ID_MULTIBUTTON_ATTACH = 11,\n    DEVICE_ID_SERIAL = 12,\n    DEVICE_ID_GESTURE = 13,\n    DEVICE_ID_SYSTEM_TIMER = 14,\n    DEVICE_ID_SCHEDULER = 15,\n    DEVICE_ID_COMPONENT = 16,\n    DEVICE_ID_LIGHT_SENSOR = 17,\n    DEVICE_ID_TOUCH_SENSOR = 18,\n    DEVICE_ID_SYSTEM_DAC = 19,\n    DEVICE_ID_SYSTEM_MICROPHONE = 20,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR = 21,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR_SPL = 22,\n    DEVICE_ID_MSC = 23,\n    DEVICE_ID_SPI = 24,\n    DEVICE_ID_DISTANCE = 25,\n    DEVICE_ID_GYROSCOPE = 26,\n    DEVICE_ID_HUMIDITY = 27,\n    DEVICE_ID_PRESSURE = 28,\n    DEVICE_ID_SINGLE_WIRE_SERIAL = 29,\n    DEVICE_ID_JACDAC = 30,\n    DEVICE_ID_JACDAC_PHYS = 31,\n    DEVICE_ID_JACDAC_CONTROL_SERVICE = 32,\n    DEVICE_ID_JACDAC_CONFIGURATION_SERVICE = 33,\n    DEVICE_ID_SYSTEM_ADC = 34,\n    DEVICE_ID_PULSE_IN = 35,\n    DEVICE_ID_USB = 36,\n    DEVICE_ID_IO_P0 = 100,\n    DEVICE_ID_MESSAGE_BUS_LISTENER = 1021,\n    DEVICE_ID_NOTIFY_ONE = 1022,\n    DEVICE_ID_NOTIFY = 1023,\n    DEVICE_ID_BUTTON_UP = 2000,\n    DEVICE_ID_BUTTON_DOWN = 2001,\n    DEVICE_ID_BUTTON_LEFT = 2002,\n    DEVICE_ID_BUTTON_RIGHT = 2003,\n    DEVICE_ID_JD_DYNAMIC_ID = 3000,\n    DEVICE_COMPONENT_RUNNING = 4096,\n    DEVICE_COMPONENT_STATUS_SYSTEM_TICK = 8192,\n    DEVICE_COMPONENT_STATUS_IDLE_TICK = 16384,\n    DEVICE_COMPONENT_LISTENERS_CONFIGURED = 1,\n    DEVICE_COMPONENT_EVT_SYSTEM_TICK = 1,\n    // /libraries/codal-core/inc/core/CodalFiber.h\n    DEVICE_SCHEDULER_RUNNING = 1,\n    DEVICE_SCHEDULER_IDLE = 2,\n    DEVICE_SCHEDULER_DEEPSLEEP = 4,\n    DEVICE_FIBER_FLAG_FOB = 1,\n    DEVICE_FIBER_FLAG_PARENT = 2,\n    DEVICE_FIBER_FLAG_CHILD = 4,\n    DEVICE_FIBER_FLAG_DO_NOT_PAGE = 8,\n    DEVICE_SCHEDULER_EVT_TICK = 1,\n    DEVICE_SCHEDULER_EVT_IDLE = 2,\n    DEVICE_GET_FIBER_LIST_AVAILABLE = 1,\n    // /libraries/codal-core/inc/core/CodalListener.h\n    MESSAGE_BUS_LISTENER_PARAMETERISED = 1,\n    MESSAGE_BUS_LISTENER_METHOD = 2,\n    MESSAGE_BUS_LISTENER_BUSY = 4,\n    MESSAGE_BUS_LISTENER_REENTRANT = 8,\n    MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY = 16,\n    MESSAGE_BUS_LISTENER_DROP_IF_BUSY = 32,\n    MESSAGE_BUS_LISTENER_NONBLOCKING = 64,\n    MESSAGE_BUS_LISTENER_URGENT = 128,\n    MESSAGE_BUS_LISTENER_DELETING = 32768,\n    MESSAGE_BUS_LISTENER_IMMEDIATE = 192,\n    // /libraries/codal-core/inc/core/ErrorNo.h\n    DEVICE_OK = 0,\n    DEVICE_INVALID_PARAMETER = -1001,\n    DEVICE_NOT_SUPPORTED = -1002,\n    DEVICE_CALIBRATION_IN_PROGRESS = -1003,\n    DEVICE_CALIBRATION_REQUIRED = -1004,\n    DEVICE_NO_RESOURCES = -1005,\n    DEVICE_BUSY = -1006,\n    DEVICE_CANCELLED = -1007,\n    DEVICE_I2C_ERROR = -1010,\n    DEVICE_SERIAL_IN_USE = -1011,\n    DEVICE_NO_DATA = -1012,\n    DEVICE_NOT_IMPLEMENTED = -1013,\n    DEVICE_SPI_ERROR = -1014,\n    DEVICE_INVALID_STATE = -1015,\n    DEVICE_OOM = 20,\n    DEVICE_HEAP_ERROR = 30,\n    DEVICE_NULL_DEREFERENCE = 40,\n    DEVICE_USB_ERROR = 50,\n    DEVICE_JACDAC_ERROR = 60,\n    DEVICE_CPU_SDK = 70,\n    DEVICE_HARDWARE_CONFIGURATION_ERROR = 90,\n    // /libraries/codal-core/inc/core/NotifyEvents.h\n    DISPLAY_EVT_FREE = 1,\n    CODAL_SERIAL_EVT_TX_EMPTY = 2,\n    BLE_EVT_SERIAL_TX_EMPTY = 3,\n    ARCADE_PLAYER_JOIN_RESULT = 4,\n    POWER_EVT_CANCEL_DEEPSLEEP = 5,\n    DEVICE_NOTIFY_USER_EVENT_BASE = 1024,\n    // /libraries/codal-core/inc/driver-models/AbstractButton.h\n    DEVICE_BUTTON_EVT_DOWN = 1,\n    DEVICE_BUTTON_EVT_UP = 2,\n    DEVICE_BUTTON_EVT_CLICK = 3,\n    DEVICE_BUTTON_EVT_LONG_CLICK = 4,\n    DEVICE_BUTTON_EVT_HOLD = 5,\n    DEVICE_BUTTON_EVT_DOUBLE_CLICK = 6,\n    DEVICE_BUTTON_LONG_CLICK_TIME = 1000,\n    DEVICE_BUTTON_HOLD_TIME = 1500,\n    DEVICE_BUTTON_STATE = 1,\n    DEVICE_BUTTON_STATE_HOLD_TRIGGERED = 2,\n    DEVICE_BUTTON_STATE_CLICK = 4,\n    DEVICE_BUTTON_STATE_LONG_CLICK = 8,\n    DEVICE_BUTTON_SIGMA_MIN = 0,\n    DEVICE_BUTTON_SIGMA_MAX = 12,\n    DEVICE_BUTTON_SIGMA_THRESH_HI = 8,\n    DEVICE_BUTTON_SIGMA_THRESH_LO = 2,\n    DEVICE_BUTTON_DOUBLE_CLICK_THRESH = 50,\n    DEVICE_BUTTON_SIMPLE_EVENTS = 0,\n    DEVICE_BUTTON_ALL_EVENTS = 1,\n    ACTIVE_LOW = 0,\n    ACTIVE_HIGH = 1,\n    // /libraries/codal-core/inc/driver-models/Accelerometer.h\n    ACCELEROMETER_IMU_DATA_VALID = 2,\n    ACCELEROMETER_EVT_DATA_UPDATE = 1,\n    ACCELEROMETER_EVT_NONE = 0,\n    ACCELEROMETER_EVT_TILT_UP = 1,\n    ACCELEROMETER_EVT_TILT_DOWN = 2,\n    ACCELEROMETER_EVT_TILT_LEFT = 3,\n    ACCELEROMETER_EVT_TILT_RIGHT = 4,\n    ACCELEROMETER_EVT_FACE_UP = 5,\n    ACCELEROMETER_EVT_FACE_DOWN = 6,\n    ACCELEROMETER_EVT_FREEFALL = 7,\n    ACCELEROMETER_EVT_3G = 8,\n    ACCELEROMETER_EVT_6G = 9,\n    ACCELEROMETER_EVT_8G = 10,\n    ACCELEROMETER_EVT_SHAKE = 11,\n    ACCELEROMETER_EVT_2G = 12,\n    ACCELEROMETER_REST_TOLERANCE = 200,\n    ACCELEROMETER_TILT_TOLERANCE = 200,\n    ACCELEROMETER_FREEFALL_TOLERANCE = 400,\n    ACCELEROMETER_SHAKE_TOLERANCE = 400,\n    ACCELEROMETER_2G_TOLERANCE = 2048,\n    ACCELEROMETER_3G_TOLERANCE = 3072,\n    ACCELEROMETER_6G_TOLERANCE = 6144,\n    ACCELEROMETER_8G_TOLERANCE = 8192,\n    ACCELEROMETER_GESTURE_DAMPING = 5,\n    ACCELEROMETER_SHAKE_DAMPING = 10,\n    ACCELEROMETER_SHAKE_RTX = 30,\n    ACCELEROMETER_SHAKE_COUNT_THRESHOLD = 4,\n    // /libraries/codal-core/inc/driver-models/Compass.h\n    COMPASS_STATUS_RUNNING = 1,\n    COMPASS_STATUS_CALIBRATED = 2,\n    COMPASS_STATUS_CALIBRATING = 4,\n    COMPASS_STATUS_ADDED_TO_IDLE = 8,\n    COMPASS_EVT_DATA_UPDATE = 1,\n    COMPASS_EVT_CONFIG_NEEDED = 2,\n    COMPASS_EVT_CALIBRATE = 3,\n    COMPASS_EVT_CALIBRATION_NEEDED = 4,\n    // /libraries/codal-core/inc/driver-models/Gyroscope.h\n    GYROSCOPE_IMU_DATA_VALID = 2,\n    GYROSCOPE_EVT_DATA_UPDATE = 1,\n    // /libraries/codal-core/inc/driver-models/LowLevelTimer.h\n    CODAL_LOWLEVELTIMER_STATUS_SLEEP_IRQENABLE = 1,\n    TimerModeTimer = 0,\n    TimerModeCounter = 1,\n    TimerModeAlternateFunction = 2,\n    BitMode8 = 0,\n    BitMode16 = 1,\n    BitMode24 = 2,\n    BitMode32 = 3,\n    // /libraries/codal-core/inc/driver-models/Pin.h\n    IO_STATUS_DIGITAL_IN = 1,\n    IO_STATUS_DIGITAL_OUT = 2,\n    IO_STATUS_ANALOG_IN = 4,\n    IO_STATUS_ANALOG_OUT = 8,\n    IO_STATUS_TOUCH_IN = 16,\n    IO_STATUS_EVENT_ON_EDGE = 32,\n    IO_STATUS_EVENT_PULSE_ON_EDGE = 64,\n    IO_STATUS_INTERRUPT_ON_EDGE = 128,\n    IO_STATUS_ACTIVE_HI = 256,\n    IO_STATUS_WAKE_ON_ACTIVE = 512,\n    DEVICE_PIN_MAX_OUTPUT = 1023,\n    DEVICE_PIN_MAX_SERVO_RANGE = 180,\n    DEVICE_PIN_DEFAULT_SERVO_RANGE = 2000,\n    DEVICE_PIN_DEFAULT_SERVO_CENTER = 1500,\n    DEVICE_PIN_EVENT_NONE = 0,\n    DEVICE_PIN_INTERRUPT_ON_EDGE = 1,\n    DEVICE_PIN_EVENT_ON_EDGE = 2,\n    DEVICE_PIN_EVENT_ON_PULSE = 3,\n    DEVICE_PIN_EVENT_ON_TOUCH = 4,\n    DEVICE_PIN_EVT_RISE = 2,\n    DEVICE_PIN_EVT_FALL = 3,\n    DEVICE_PIN_EVT_PULSE_HI = 4,\n    DEVICE_PIN_EVT_PULSE_LO = 5,\n    PIN_CAPABILITY_DIGITAL = 1,\n    PIN_CAPABILITY_ANALOG = 2,\n    PIN_CAPABILITY_AD = 3,\n    PIN_CAPABILITY_ALL = 3,\n    None = 0,\n    Down = 1,\n    Up = 2,\n    // /libraries/codal-core/inc/driver-models/Radio.h\n    RADIO_EVT_DATA_READY = 2,\n    // /libraries/codal-core/inc/driver-models/SPIFlash.h\n    SPIFLASH_PAGE_SIZE = 256,\n    SPIFLASH_SMALL_ROW_PAGES = 16,\n    SPIFLASH_BIG_ROW_PAGES = 256,\n    // /libraries/codal-core/inc/driver-models/Sensor.h\n    SENSOR_THRESHOLD_LOW = 1,\n    SENSOR_THRESHOLD_HIGH = 2,\n    SENSOR_UPDATE_NEEDED = 3,\n    SENSOR_INITIALISED = 1,\n    SENSOR_HIGH_THRESHOLD_PASSED = 2,\n    SENSOR_LOW_THRESHOLD_PASSED = 4,\n    SENSOR_LOW_THRESHOLD_ENABLED = 8,\n    SENSOR_HIGH_THRESHOLD_ENABLED = 16,\n    SENSOR_DEFAULT_SENSITIVITY = 868,\n    SENSOR_DEFAULT_SAMPLE_PERIOD = 500,\n    // /libraries/codal-core/inc/driver-models/Serial.h\n    CODAL_SERIAL_DEFAULT_BAUD_RATE = 115200,\n    CODAL_SERIAL_DEFAULT_BUFFER_SIZE = 20,\n    CODAL_SERIAL_EVT_DELIM_MATCH = 1,\n    CODAL_SERIAL_EVT_HEAD_MATCH = 2,\n    CODAL_SERIAL_EVT_RX_FULL = 3,\n    CODAL_SERIAL_EVT_DATA_RECEIVED = 4,\n    CODAL_SERIAL_STATUS_RX_IN_USE = 1,\n    CODAL_SERIAL_STATUS_TX_IN_USE = 2,\n    CODAL_SERIAL_STATUS_RX_BUFF_INIT = 4,\n    CODAL_SERIAL_STATUS_TX_BUFF_INIT = 8,\n    CODAL_SERIAL_STATUS_RXD = 16,\n    CODAL_SERIAL_STATUS_DEEPSLEEP = 32,\n    ASYNC = 0,\n    SYNC_SPINWAIT = 1,\n    SYNC_SLEEP = 2,\n    RxInterrupt = 0,\n    TxInterrupt = 1,\n    // /libraries/codal-core/inc/driver-models/SingleWireSerial.h\n    SWS_EVT_DATA_RECEIVED = 1,\n    SWS_EVT_DATA_SENT = 2,\n    SWS_EVT_ERROR = 3,\n    SWS_EVT_DATA_DROPPED = 4,\n    SingleWireRx = 0,\n    SingleWireTx = 1,\n    SingleWireDisconnected = 2,\n    // /libraries/codal-core/inc/driver-models/Timer.h\n    CODAL_TIMER_DEFAULT_EVENT_LIST_SIZE = 10,\n    CODAL_TIMER_EVENT_FLAGS_NONE = 0,\n    CODAL_TIMER_EVENT_FLAGS_WAKEUP = 1,\n    // /libraries/codal-core/inc/drivers/AnalogSensor.h\n    ANALOG_THRESHOLD_LOW = 1,\n    ANALOG_THRESHOLD_HIGH = 2,\n    ANALOG_SENSOR_UPDATE_NEEDED = 3,\n    ANALOG_SENSOR_INITIALISED = 1,\n    ANALOG_SENSOR_HIGH_THRESHOLD_PASSED = 2,\n    ANALOG_SENSOR_LOW_THRESHOLD_PASSED = 4,\n    ANALOG_SENSOR_LOW_THRESHOLD_ENABLED = 8,\n    ANALOG_SENSOR_HIGH_THRESHOLD_ENABLED = 16,\n    // /libraries/codal-core/inc/drivers/AnimatedDisplay.h\n    DISPLAY_EVT_ANIMATION_COMPLETE = 1,\n    DISPLAY_DEFAULT_AUTOCLEAR = 1,\n    DISPLAY_SPACING = 1,\n    DISPLAY_ANIMATE_DEFAULT_POS = -255,\n    DISPLAY_DEFAULT_SCROLL_SPEED = 120,\n    DISPLAY_DEFAULT_SCROLL_STRIDE = -1,\n    DISPLAY_DEFAULT_PRINT_SPEED = 400,\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    // /libraries/codal-core/inc/drivers/FAT.h\n    FAT_RESERVED_SECTORS = 1,\n    FAT_ROOT_DIR_SECTORS = 4,\n    // /libraries/codal-core/inc/drivers/HID.h\n    HID_REQUEST_GET_REPORT = 1,\n    HID_REQUEST_GET_IDLE = 2,\n    HID_REQUEST_GET_PROTOCOL = 3,\n    HID_REQUEST_SET_REPORT = 9,\n    HID_REQUEST_SET_IDLE = 10,\n    HID_REQUEST_SET_PROTOCOL = 11,\n    // /libraries/codal-core/inc/drivers/HIDKeyboard.h\n    HID_KEYBOARD_NUM_REPORTS = 3,\n    HID_KEYBOARD_REPORT_GENERIC = 1,\n    HID_KEYBOARD_REPORT_CONSUMER = 2,\n    HID_KEYBOARD_KEYSTATE_SIZE_GENERIC = 8,\n    HID_KEYBOARD_KEYSTATE_SIZE_CONSUMER = 2,\n    HID_KEYBOARD_MODIFIER_OFFSET = 2,\n    HID_KEYBOARD_DELAY_DEFAULT = 10,\n    PressKey = 0,\n    ReleaseKey = 1,\n    // /libraries/codal-core/inc/drivers/KeyMap.h\n    KEYMAP_ALL_KEYS_UP_Val = 1,\n    KEYMAP_ALL_KEYS_UP_POS = 28,\n    KEYMAP_NORMAL_KEY_Val = 0,\n    KEYMAP_MODIFIER_KEY_Val = 1,\n    KEYMAP_MODIFIER_POS = 29,\n    KEYMAP_MEDIA_KEY_Val = 1,\n    KEYMAP_MEDIA_POS = 30,\n    KEYMAP_KEY_UP_Val = 0,\n    KEYMAP_KEY_DOWN_Val = 1,\n    KEYMAP_KEY_DOWN_POS = 31,\n    // /libraries/codal-core/inc/drivers/KeyValueStorage.h\n    DEVICE_KEY_VALUE_STORE_OFFSET = -4,\n    KEY_VALUE_STORAGE_MAGIC = 789921,\n    KEY_VALUE_STORAGE_BLOCK_SIZE = 48,\n    KEY_VALUE_STORAGE_KEY_SIZE = 16,\n    KEY_VALUE_STORAGE_SCRATCH_WORD_SIZE = 64,\n    KEY_VALUE_STORAGE_MAX_PAIRS = 5,\n    // /libraries/codal-core/inc/drivers/LEDMatrix.h\n    LED_MATRIX_GREYSCALE_BIT_DEPTH = 8,\n    LED_MATRIX_EVT_LIGHT_SENSE = 2,\n    LED_MATRIX_EVT_FRAME_TIMEOUT = 3,\n    LED_MATRIX_MINIMUM_BRIGHTNESS = 1,\n    LED_MATRIX_MAXIMUM_BRIGHTNESS = 255,\n    LED_MATRIX_DEFAULT_BRIGHTNESS = 255,\n    DISPLAY_MODE_BLACK_AND_WHITE = 0,\n    DISPLAY_MODE_GREYSCALE = 1,\n    DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE = 2,\n    DISPLAY_MODE_GREYSCALE_LIGHT_SENSE = 3,\n    MATRIX_DISPLAY_ROTATION_0 = 0,\n    MATRIX_DISPLAY_ROTATION_90 = 1,\n    MATRIX_DISPLAY_ROTATION_180 = 2,\n    MATRIX_DISPLAY_ROTATION_270 = 3,\n    NO_CONN = 0,\n    // /libraries/codal-core/inc/drivers/LSM303Accelerometer.h\n    LSM303_A_DEFAULT_ADDR = 50,\n    LSM303_STATUS_REG_AUX_A = 7,\n    LSM303_OUT_TEMP_L_A = 12,\n    LSM303_OUT_TEMP_H_A = 13,\n    LSM303_INT_COUNTER_REG_A = 14,\n    LSM303_WHO_AM_I_A = 15,\n    LSM303_TEMP_CFG_REG_A = 31,\n    LSM303_CTRL_REG1_A = 32,\n    LSM303_CTRL_REG2_A = 33,\n    LSM303_CTRL_REG3_A = 34,\n    LSM303_CTRL_REG4_A = 35,\n    LSM303_CTRL_REG5_A = 36,\n    LSM303_CTRL_REG6_A = 37,\n    LSM303_DATACAPTURE_A = 38,\n    LSM303_STATUS_REG_A = 39,\n    LSM303_OUT_X_L_A = 40,\n    LSM303_OUT_X_H_A = 41,\n    LSM303_OUT_Y_L_A = 42,\n    LSM303_OUT_Y_H_A = 43,\n    LSM303_OUT_Z_L_A = 44,\n    LSM303_OUT_Z_H_A = 45,\n    LSM303_FIFO_CTRL_REG_A = 46,\n    LSM303_FIFO_SRC_REG_A = 47,\n    LSM303_INT1_CFG_A = 48,\n    LSM303_INT1_SRC_A = 49,\n    LSM303_INT1_THS_A = 50,\n    LSM303_INT1_DURATION_A = 51,\n    LSM303_INT2_CFG_A = 52,\n    LSM303_INT2_SRC_A = 53,\n    LSM303_INT2_THS_A = 54,\n    LSM303_INT2_DURATION_A = 55,\n    LSM303_CLICK_CFG_A = 56,\n    LSM303_CLICK_SRC_A = 57,\n    LSM303_CLICK_THS_A = 58,\n    LSM303_TIME_LIMIT_A = 59,\n    LSM303_TIME_LATENCY_A = 60,\n    LSM303_TIME_WINDOW_A = 61,\n    LSM303_ACT_THS_A = 62,\n    LSM303_ACT_DUR_A = 63,\n    LSM303_A_WHOAMI_VAL = 51,\n    LSM303_A_STATUS_DATA_READY = 8,\n    LSM303_A_STATUS_ENABLED = 256,\n    LSM303_A_STATUS_SLEEPING = 512,\n    // /libraries/codal-core/inc/drivers/LSM303Magnetometer.h\n    LSM303_M_WHOAMI_VAL = 64,\n    LSM303_M_DEFAULT_ADDR = 60,\n    LSM303_OFFSET_X_REG_L_M = 69,\n    LSM303_OFFSET_X_REG_H_M = 70,\n    LSM303_OFFSET_Y_REG_L_M = 71,\n    LSM303_OFFSET_Y_REG_H_M = 72,\n    LSM303_OFFSET_Z_REG_L_M = 73,\n    LSM303_OFFSET_Z_REG_H_M = 74,\n    LSM303_WHO_AM_I_M = 79,\n    LSM303_CFG_REG_A_M = 96,\n    LSM303_CFG_REG_B_M = 97,\n    LSM303_CFG_REG_C_M = 98,\n    LSM303_INT_CRTL_REG_M = 99,\n    LSM303_INT_SOURCE_REG_M = 100,\n    LSM303_INT_THS_L_REG_M = 101,\n    LSM303_INT_THS_H_REG_M = 102,\n    LSM303_STATUS_REG_M = 103,\n    LSM303_OUTX_L_REG_M = 104,\n    LSM303_OUTX_H_REG_M = 105,\n    LSM303_OUTY_L_REG_M = 106,\n    LSM303_OUTY_H_REG_M = 107,\n    LSM303_OUTZ_L_REG_M = 108,\n    LSM303_OUTZ_H_REG_M = 109,\n    LSM303_M_STATUS_DATA_READY = 8,\n    LSM303_M_STATUS_ENABLED = 256,\n    LSM303_M_STATUS_SLEEPING = 512,\n    // /libraries/codal-core/inc/drivers/MultiButton.h\n    MULTI_BUTTON_STATE_1 = 1,\n    MULTI_BUTTON_STATE_2 = 2,\n    MULTI_BUTTON_HOLD_TRIGGERED_1 = 4,\n    MULTI_BUTTON_HOLD_TRIGGERED_2 = 8,\n    MULTI_BUTTON_SUPRESSED_1 = 16,\n    MULTI_BUTTON_SUPRESSED_2 = 32,\n    MULTI_BUTTON_ATTACHED = 64,\n    // /libraries/codal-core/inc/drivers/PulseIn.h\n    DEVICE_EVT_PULSE_IN_TIMEOUT = 10000,\n    // /libraries/codal-core/inc/drivers/TouchButton.h\n    TOUCH_BUTTON_CALIBRATION_LINEAR_OFFSET = 2,\n    TOUCH_BUTTON_CALIBRATION_PERCENTAGE_OFFSET = 5,\n    TOUCH_BUTTON_SENSITIVITY = 10,\n    TOUCH_BUTTON_CALIBRATION_PERIOD = 10,\n    TOUCH_BUTTON_CALIBRATING = 16,\n    // /libraries/codal-core/inc/drivers/TouchSensor.h\n    TOUCH_SENSOR_MAX_BUTTONS = 10,\n    TOUCH_SENSOR_SAMPLE_PERIOD = 50,\n    TOUCH_SENSE_SAMPLE_MAX = 1000,\n    TOUCH_SENSOR_UPDATE_NEEDED = 1,\n    // /libraries/codal-core/inc/drivers/USB_HID_Keys.h\n    KEY_MOD_LCTRL = 1,\n    KEY_MOD_LSHIFT = 2,\n    KEY_MOD_LALT = 4,\n    KEY_MOD_LMETA = 8,\n    KEY_MOD_RCTRL = 16,\n    KEY_MOD_RSHIFT = 32,\n    KEY_MOD_RALT = 64,\n    KEY_MOD_RMETA = 128,\n    KEY_NONE = 0,\n    KEY_ERR_OVF = 1,\n    KEY_A = 4,\n    KEY_B = 5,\n    KEY_C = 6,\n    KEY_D = 7,\n    KEY_E = 8,\n    KEY_F = 9,\n    KEY_G = 10,\n    KEY_H = 11,\n    KEY_I = 12,\n    KEY_J = 13,\n    KEY_K = 14,\n    KEY_L = 15,\n    KEY_M = 16,\n    KEY_N = 17,\n    KEY_O = 18,\n    KEY_P = 19,\n    KEY_Q = 20,\n    KEY_R = 21,\n    KEY_S = 22,\n    KEY_T = 23,\n    KEY_U = 24,\n    KEY_V = 25,\n    KEY_W = 26,\n    KEY_X = 27,\n    KEY_Y = 28,\n    KEY_Z = 29,\n    KEY_1 = 30,\n    KEY_2 = 31,\n    KEY_3 = 32,\n    KEY_4 = 33,\n    KEY_5 = 34,\n    KEY_6 = 35,\n    KEY_7 = 36,\n    KEY_8 = 37,\n    KEY_9 = 38,\n    KEY_0 = 39,\n    KEY_ENTER = 40,\n    KEY_ESC = 41,\n    KEY_BACKSPACE = 42,\n    KEY_TAB = 43,\n    KEY_SPACE = 44,\n    KEY_MINUS = 45,\n    KEY_EQUAL = 46,\n    KEY_LEFTBRACE = 47,\n    KEY_RIGHTBRACE = 48,\n    KEY_BACKSLASH = 49,\n    KEY_HASHTILDE = 50,\n    KEY_SEMICOLON = 51,\n    KEY_APOSTROPHE = 52,\n    KEY_GRAVE = 53,\n    KEY_COMMA = 54,\n    KEY_DOT = 55,\n    KEY_SLASH = 56,\n    KEY_CAPSLOCK = 57,\n    KEY_F1 = 58,\n    KEY_F2 = 59,\n    KEY_F3 = 60,\n    KEY_F4 = 61,\n    KEY_F5 = 62,\n    KEY_F6 = 63,\n    KEY_F7 = 64,\n    KEY_F8 = 65,\n    KEY_F9 = 66,\n    KEY_F10 = 67,\n    KEY_F11 = 68,\n    KEY_F12 = 69,\n    KEY_SYSRQ = 70,\n    KEY_SCROLLLOCK = 71,\n    KEY_PAUSE = 72,\n    KEY_INSERT = 73,\n    KEY_HOME = 74,\n    KEY_PAGEUP = 75,\n    KEY_DELETE = 76,\n    KEY_END = 77,\n    KEY_PAGEDOWN = 78,\n    KEY_RIGHT = 79,\n    KEY_LEFT = 80,\n    KEY_DOWN = 81,\n    KEY_UP = 82,\n    KEY_NUMLOCK = 83,\n    KEY_KPSLASH = 84,\n    KEY_KPASTERISK = 85,\n    KEY_KPMINUS = 86,\n    KEY_KPPLUS = 87,\n    KEY_KPENTER = 88,\n    KEY_KP1 = 89,\n    KEY_KP2 = 90,\n    KEY_KP3 = 91,\n    KEY_KP4 = 92,\n    KEY_KP5 = 93,\n    KEY_KP6 = 94,\n    KEY_KP7 = 95,\n    KEY_KP8 = 96,\n    KEY_KP9 = 97,\n    KEY_KP0 = 98,\n    KEY_KPDOT = 99,\n    KEY_102ND = 100,\n    KEY_COMPOSE = 101,\n    KEY_POWER = 102,\n    KEY_KPEQUAL = 103,\n    KEY_F13 = 104,\n    KEY_F14 = 105,\n    KEY_F15 = 106,\n    KEY_F16 = 107,\n    KEY_F17 = 108,\n    KEY_F18 = 109,\n    KEY_F19 = 110,\n    KEY_F20 = 111,\n    KEY_F21 = 112,\n    KEY_F22 = 113,\n    KEY_F23 = 114,\n    KEY_F24 = 115,\n    KEY_OPEN = 116,\n    KEY_HELP = 117,\n    KEY_PROPS = 118,\n    KEY_FRONT = 119,\n    KEY_STOP = 120,\n    KEY_AGAIN = 121,\n    KEY_UNDO = 122,\n    KEY_CUT = 123,\n    KEY_COPY = 124,\n    KEY_PASTE = 125,\n    KEY_FIND = 126,\n    KEY_MUTE = 127,\n    KEY_VOLUMEUP = 128,\n    KEY_VOLUMEDOWN = 129,\n    KEY_KPCOMMA = 133,\n    KEY_RO = 135,\n    KEY_KATAKANAHIRAGANA = 136,\n    KEY_YEN = 137,\n    KEY_HENKAN = 138,\n    KEY_MUHENKAN = 139,\n    KEY_KPJPCOMMA = 140,\n    KEY_HANGEUL = 144,\n    KEY_HANJA = 145,\n    KEY_KATAKANA = 146,\n    KEY_HIRAGANA = 147,\n    KEY_ZENKAKUHANKAKU = 148,\n    KEY_KPLEFTPAREN = 182,\n    KEY_KPRIGHTPAREN = 183,\n    KEY_LEFTCTRL = 224,\n    KEY_LEFTSHIFT = 225,\n    KEY_LEFTALT = 226,\n    KEY_LEFTMETA = 227,\n    KEY_RIGHTCTRL = 228,\n    KEY_RIGHTSHIFT = 229,\n    KEY_RIGHTALT = 230,\n    KEY_RIGHTMETA = 231,\n    KEY_MEDIA_PLAYPAUSE = 232,\n    KEY_MEDIA_STOPCD = 233,\n    KEY_MEDIA_PREVIOUSSONG = 234,\n    KEY_MEDIA_NEXTSONG = 235,\n    KEY_MEDIA_EJECTCD = 236,\n    KEY_MEDIA_VOLUMEUP = 237,\n    KEY_MEDIA_VOLUMEDOWN = 238,\n    KEY_MEDIA_MUTE = 239,\n    KEY_MEDIA_WWW = 240,\n    KEY_MEDIA_BACK = 241,\n    KEY_MEDIA_FORWARD = 242,\n    KEY_MEDIA_STOP = 243,\n    KEY_MEDIA_FIND = 244,\n    KEY_MEDIA_SCROLLUP = 245,\n    KEY_MEDIA_SCROLLDOWN = 246,\n    KEY_MEDIA_EDIT = 247,\n    KEY_MEDIA_SLEEP = 248,\n    KEY_MEDIA_COFFEE = 249,\n    KEY_MEDIA_REFRESH = 250,\n    KEY_MEDIA_CALC = 251,\n    // /libraries/codal-core/inc/drivers/uf2format.h\n    UF2FORMAT_H = 1,\n    APP_START_ADDRESS = 8192,\n    UF2_FLAG_NOFLASH = 1,\n    // /libraries/codal-core/inc/streams/DataStream.h\n    DATASTREAM_MAXIMUM_BUFFERS = 1,\n    DATASTREAM_FORMAT_UNKNOWN = 0,\n    DATASTREAM_FORMAT_8BIT_UNSIGNED = 1,\n    DATASTREAM_FORMAT_8BIT_SIGNED = 2,\n    DATASTREAM_FORMAT_16BIT_UNSIGNED = 3,\n    DATASTREAM_FORMAT_16BIT_SIGNED = 4,\n    DATASTREAM_FORMAT_24BIT_UNSIGNED = 5,\n    DATASTREAM_FORMAT_24BIT_SIGNED = 6,\n    DATASTREAM_FORMAT_32BIT_UNSIGNED = 7,\n    DATASTREAM_FORMAT_32BIT_SIGNED = 8,\n    // /libraries/codal-core/inc/streams/LevelDetector.h\n    LEVEL_THRESHOLD_LOW = 1,\n    LEVEL_THRESHOLD_HIGH = 2,\n    LEVEL_DETECTOR_INITIALISED = 1,\n    LEVEL_DETECTOR_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_DEFAULT_WINDOW_SIZE = 128,\n    // /libraries/codal-core/inc/streams/LevelDetectorSPL.h\n    LEVEL_DETECTOR_SPL_INITIALISED = 1,\n    LEVEL_DETECTOR_SPL_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_SPL_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_SPL_DEFAULT_WINDOW_SIZE = 128,\n    // /libraries/codal-core/inc/streams/MemorySource.h\n    MEMORY_SOURCE_DEFAULT_MAX_BUFFER = 256,\n    // /libraries/codal-core/inc/streams/Synthesizer.h\n    SYNTHESIZER_SAMPLE_RATE = 44100,\n    TONE_WIDTH = 1024,\n    // /libraries/codal-core/inc/types/BitmapFont.h\n    BITMAP_FONT_WIDTH = 5,\n    BITMAP_FONT_HEIGHT = 5,\n    BITMAP_FONT_ASCII_START = 32,\n    BITMAP_FONT_ASCII_END = 126,\n    // /libraries/codal-core/inc/types/CoordinateSystem.h\n    COORDINATE_SPACE_ROTATED_0 = 0,\n    COORDINATE_SPACE_ROTATED_90 = 1,\n    COORDINATE_SPACE_ROTATED_180 = 2,\n    COORDINATE_SPACE_ROTATED_270 = 3,\n    RAW = 0,\n    SIMPLE_CARTESIAN = 1,\n    NORTH_EAST_DOWN = 2,\n    EAST_NORTH_UP = 3,\n    NORTH_EAST_UP = 3,\n    // /libraries/codal-core/inc/types/Event.h\n    DEVICE_ID_ANY = 0,\n    DEVICE_EVT_ANY = 0,\n    CREATE_ONLY = 0,\n    CREATE_AND_FIRE = 1,\n    DEVICE_EVENT_DEFAULT_LAUNCH_MODE = 1,\n    // /libraries/codal-core/inc/types/ManagedBuffer.h\n    Zero = 1,\n    // /libraries/codal-core/inc/types/RefCounted.h\n    REF_TAG_STRING = 1,\n    REF_TAG_BUFFER = 2,\n    REF_TAG_IMAGE = 3,\n    REF_TAG_USER = 32,\n    // /pxtapp/accelerometer/axis.h\n    ACC_SYSTEM = 3,\n    ACC_ROTATION = 0,\n    // /pxtapp/configkeys.h\n    CFG_PIN_NAME_MSK = 65535,\n    CFG_PIN_CONFIG_MSK = 4294901760,\n    CFG_PIN_CONFIG_ACTIVE_LO = 65536,\n    CFG_MAGIC0 = 513675505,\n    CFG_MAGIC1 = 539130489,\n    CFG_PIN_ACCELEROMETER_INT = 1,\n    CFG_PIN_ACCELEROMETER_SCL = 2,\n    CFG_PIN_ACCELEROMETER_SDA = 3,\n    CFG_PIN_BTN_A = 4,\n    CFG_PIN_BTN_B = 5,\n    CFG_PIN_BTN_SLIDE = 6,\n    CFG_PIN_DOTSTAR_CLOCK = 7,\n    CFG_PIN_DOTSTAR_DATA = 8,\n    CFG_PIN_FLASH_CS = 9,\n    CFG_PIN_FLASH_MISO = 10,\n    CFG_PIN_FLASH_MOSI = 11,\n    CFG_PIN_FLASH_SCK = 12,\n    CFG_PIN_LED = 13,\n    CFG_PIN_LIGHT = 14,\n    CFG_PIN_MICROPHONE = 15,\n    CFG_PIN_MIC_CLOCK = 16,\n    CFG_PIN_MIC_DATA = 17,\n    CFG_PIN_MISO = 18,\n    CFG_PIN_MOSI = 19,\n    CFG_PIN_NEOPIXEL = 20,\n    CFG_PIN_RX = 21,\n    CFG_PIN_RXLED = 22,\n    CFG_PIN_SCK = 23,\n    CFG_PIN_SCL = 24,\n    CFG_PIN_SDA = 25,\n    CFG_PIN_SPEAKER_AMP = 26,\n    CFG_PIN_TEMPERATURE = 27,\n    CFG_PIN_TX = 28,\n    CFG_PIN_TXLED = 29,\n    CFG_PIN_IR_OUT = 30,\n    CFG_PIN_IR_IN = 31,\n    CFG_PIN_DISPLAY_SCK = 32,\n    CFG_PIN_DISPLAY_MISO = 33,\n    CFG_PIN_DISPLAY_MOSI = 34,\n    CFG_PIN_DISPLAY_CS = 35,\n    CFG_PIN_DISPLAY_DC = 36,\n    CFG_DISPLAY_WIDTH = 37,\n    CFG_DISPLAY_HEIGHT = 38,\n    CFG_DISPLAY_CFG0 = 39,\n    CFG_DISPLAY_CFG1 = 40,\n    CFG_DISPLAY_CFG2 = 41,\n    CFG_DISPLAY_CFG3 = 42,\n    CFG_PIN_DISPLAY_RST = 43,\n    CFG_PIN_DISPLAY_BL = 44,\n    CFG_PIN_SERVO_1 = 45,\n    CFG_PIN_SERVO_2 = 46,\n    CFG_PIN_BTN_LEFT = 47,\n    CFG_PIN_BTN_RIGHT = 48,\n    CFG_PIN_BTN_UP = 49,\n    CFG_PIN_BTN_DOWN = 50,\n    CFG_PIN_BTN_MENU = 51,\n    CFG_PIN_LED_R = 52,\n    CFG_PIN_LED_G = 53,\n    CFG_PIN_LED_B = 54,\n    CFG_PIN_LED1 = 55,\n    CFG_PIN_LED2 = 56,\n    CFG_PIN_LED3 = 57,\n    CFG_PIN_LED4 = 58,\n    CFG_SPEAKER_VOLUME = 59,\n    CFG_PIN_JACK_TX = 60,\n    CFG_PIN_JACK_SENSE = 61,\n    CFG_PIN_JACK_HPEN = 62,\n    CFG_PIN_JACK_BZEN = 63,\n    CFG_PIN_JACK_PWREN = 64,\n    CFG_PIN_JACK_SND = 65,\n    CFG_PIN_JACK_BUSLED = 66,\n    CFG_PIN_JACK_COMMLED = 67,\n    CFG_PIN_BTN_SOFT_RESET = 69,\n    CFG_ACCELEROMETER_TYPE = 70,\n    CFG_PIN_BTNMX_LATCH = 71,\n    CFG_PIN_BTNMX_CLOCK = 72,\n    CFG_PIN_BTNMX_DATA = 73,\n    CFG_PIN_BTN_MENU2 = 74,\n    CFG_PIN_BATTSENSE = 75,\n    CFG_PIN_VIBRATION = 76,\n    CFG_PIN_PWREN = 77,\n    CFG_DISPLAY_TYPE = 78,\n    CFG_PIN_ROTARY_ENCODER_A = 79,\n    CFG_PIN_ROTARY_ENCODER_B = 80,\n    CFG_ACCELEROMETER_SPACE = 81,\n    CFG_PIN_WIFI_MOSI = 82,\n    CFG_PIN_WIFI_MISO = 83,\n    CFG_PIN_WIFI_SCK = 84,\n    CFG_PIN_WIFI_TX = 85,\n    CFG_PIN_WIFI_RX = 86,\n    CFG_PIN_WIFI_CS = 87,\n    CFG_PIN_WIFI_BUSY = 88,\n    CFG_PIN_WIFI_RESET = 89,\n    CFG_PIN_WIFI_GPIO0 = 90,\n    CFG_PIN_WIFI_AT_TX = 91,\n    CFG_PIN_WIFI_AT_RX = 92,\n    CFG_PIN_USB_POWER = 93,\n    CFG_DISPLAY_DELAY = 94,\n    ACCELEROMETER_TYPE_LIS3DH = 50,\n    ACCELEROMETER_TYPE_LIS3DH_ALT = 48,\n    ACCELEROMETER_TYPE_MMA8453 = 56,\n    ACCELEROMETER_TYPE_FXOS8700 = 60,\n    ACCELEROMETER_TYPE_MMA8653 = 58,\n    ACCELEROMETER_TYPE_MSA300 = 76,\n    ACCELEROMETER_TYPE_MPU6050 = 104,\n    DISPLAY_TYPE_ST7735 = 7735,\n    DISPLAY_TYPE_ILI9341 = 9341,\n    DISPLAY_TYPE_SMART = 4242,\n    CFG_PIN_A0 = 100,\n    CFG_PIN_A1 = 101,\n    CFG_PIN_A2 = 102,\n    CFG_PIN_A3 = 103,\n    CFG_PIN_A4 = 104,\n    CFG_PIN_A5 = 105,\n    CFG_PIN_A6 = 106,\n    CFG_PIN_A7 = 107,\n    CFG_PIN_A8 = 108,\n    CFG_PIN_A9 = 109,\n    CFG_PIN_A10 = 110,\n    CFG_PIN_A11 = 111,\n    CFG_PIN_A12 = 112,\n    CFG_PIN_A13 = 113,\n    CFG_PIN_A14 = 114,\n    CFG_PIN_A15 = 115,\n    CFG_PIN_A16 = 116,\n    CFG_PIN_A17 = 117,\n    CFG_PIN_A18 = 118,\n    CFG_PIN_A19 = 119,\n    CFG_PIN_A20 = 120,\n    CFG_PIN_A21 = 121,\n    CFG_PIN_A22 = 122,\n    CFG_PIN_A23 = 123,\n    CFG_PIN_A24 = 124,\n    CFG_PIN_A25 = 125,\n    CFG_PIN_A26 = 126,\n    CFG_PIN_A27 = 127,\n    CFG_PIN_A28 = 128,\n    CFG_PIN_A29 = 129,\n    CFG_PIN_A30 = 130,\n    CFG_PIN_A31 = 131,\n    CFG_PIN_D0 = 150,\n    CFG_PIN_D1 = 151,\n    CFG_PIN_D2 = 152,\n    CFG_PIN_D3 = 153,\n    CFG_PIN_D4 = 154,\n    CFG_PIN_D5 = 155,\n    CFG_PIN_D6 = 156,\n    CFG_PIN_D7 = 157,\n    CFG_PIN_D8 = 158,\n    CFG_PIN_D9 = 159,\n    CFG_PIN_D10 = 160,\n    CFG_PIN_D11 = 161,\n    CFG_PIN_D12 = 162,\n    CFG_PIN_D13 = 163,\n    CFG_PIN_D14 = 164,\n    CFG_PIN_D15 = 165,\n    CFG_PIN_D16 = 166,\n    CFG_PIN_D17 = 167,\n    CFG_PIN_D18 = 168,\n    CFG_PIN_D19 = 169,\n    CFG_PIN_D20 = 170,\n    CFG_PIN_D21 = 171,\n    CFG_PIN_D22 = 172,\n    CFG_PIN_D23 = 173,\n    CFG_PIN_D24 = 174,\n    CFG_PIN_D25 = 175,\n    CFG_PIN_D26 = 176,\n    CFG_PIN_D27 = 177,\n    CFG_PIN_D28 = 178,\n    CFG_PIN_D29 = 179,\n    CFG_PIN_D30 = 180,\n    CFG_PIN_D31 = 181,\n    CFG_NUM_NEOPIXELS = 200,\n    CFG_NUM_DOTSTARS = 201,\n    CFG_DEFAULT_BUTTON_MODE = 202,\n    CFG_SWD_ENABLED = 203,\n    CFG_FLASH_BYTES = 204,\n    CFG_RAM_BYTES = 205,\n    CFG_SYSTEM_HEAP_BYTES = 206,\n    CFG_LOW_MEM_SIMULATION_KB = 207,\n    CFG_BOOTLOADER_BOARD_ID = 208,\n    CFG_UF2_FAMILY = 209,\n    CFG_PINS_PORT_SIZE = 210,\n    CFG_BOOTLOADER_PROTECTION = 211,\n    CFG_POWER_DEEPSLEEP_TIMEOUT = 212,\n    CFG_ANALOG_BUTTON_THRESHOLD = 213,\n    CFG_CPU_MHZ = 214,\n    CFG_CONTROLLER_LIGHT_MAX_BRIGHTNESS = 215,\n    CFG_ANALOG_JOYSTICK_MIN = 216,\n    CFG_ANALOG_JOYSTICK_MAX = 217,\n    CFG_TIMERS_TO_USE = 218,\n    CFG_PIN_ONBOARD_DOTSTAR_CLOCK = 219,\n    CFG_PIN_ONBOARD_DOTSTAR_DATA = 220,\n    CFG_NUM_ONBOARD_DOTSTARS = 221,\n    CFG_PIN_ONBOARD_NEOPIXEL = 222,\n    CFG_NUM_ONBOARD_NEOPIXELS = 223,\n    CFG_MATRIX_KEYPAD_MESSAGE_ID = 239,\n    CFG_NUM_MATRIX_KEYPAD_ROWS = 240,\n    CFG_PIN_MATRIX_KEYPAD_ROW0 = 241,\n    CFG_PIN_MATRIX_KEYPAD_ROW1 = 242,\n    CFG_PIN_MATRIX_KEYPAD_ROW2 = 243,\n    CFG_PIN_MATRIX_KEYPAD_ROW3 = 244,\n    CFG_PIN_MATRIX_KEYPAD_ROW4 = 245,\n    CFG_PIN_MATRIX_KEYPAD_ROW5 = 246,\n    CFG_PIN_MATRIX_KEYPAD_ROW6 = 247,\n    CFG_PIN_MATRIX_KEYPAD_ROW7 = 248,\n    CFG_NUM_MATRIX_KEYPAD_COLS = 250,\n    CFG_PIN_MATRIX_KEYPAD_COL0 = 251,\n    CFG_PIN_MATRIX_KEYPAD_COL1 = 252,\n    CFG_PIN_MATRIX_KEYPAD_COL2 = 253,\n    CFG_PIN_MATRIX_KEYPAD_COL3 = 254,\n    CFG_PIN_MATRIX_KEYPAD_COL4 = 255,\n    CFG_PIN_MATRIX_KEYPAD_COL5 = 256,\n    CFG_PIN_MATRIX_KEYPAD_COL6 = 257,\n    CFG_PIN_MATRIX_KEYPAD_COL7 = 258,\n    CFG_PIN_B0 = 300,\n    CFG_PIN_B1 = 301,\n    CFG_PIN_B2 = 302,\n    CFG_PIN_B3 = 303,\n    CFG_PIN_B4 = 304,\n    CFG_PIN_B5 = 305,\n    CFG_PIN_B6 = 306,\n    CFG_PIN_B7 = 307,\n    CFG_PIN_B8 = 308,\n    CFG_PIN_B9 = 309,\n    CFG_PIN_B10 = 310,\n    CFG_PIN_B11 = 311,\n    CFG_PIN_B12 = 312,\n    CFG_PIN_B13 = 313,\n    CFG_PIN_B14 = 314,\n    CFG_PIN_B15 = 315,\n    CFG_PIN_B16 = 316,\n    CFG_PIN_B17 = 317,\n    CFG_PIN_B18 = 318,\n    CFG_PIN_B19 = 319,\n    CFG_PIN_B20 = 320,\n    CFG_PIN_B21 = 321,\n    CFG_PIN_B22 = 322,\n    CFG_PIN_B23 = 323,\n    CFG_PIN_B24 = 324,\n    CFG_PIN_B25 = 325,\n    CFG_PIN_B26 = 326,\n    CFG_PIN_B27 = 327,\n    CFG_PIN_B28 = 328,\n    CFG_PIN_B29 = 329,\n    CFG_PIN_B30 = 330,\n    CFG_PIN_B31 = 331,\n    CFG_PIN_C0 = 350,\n    CFG_PIN_C1 = 351,\n    CFG_PIN_C2 = 352,\n    CFG_PIN_C3 = 353,\n    CFG_PIN_C4 = 354,\n    CFG_PIN_C5 = 355,\n    CFG_PIN_C6 = 356,\n    CFG_PIN_C7 = 357,\n    CFG_PIN_C8 = 358,\n    CFG_PIN_C9 = 359,\n    CFG_PIN_C10 = 360,\n    CFG_PIN_C11 = 361,\n    CFG_PIN_C12 = 362,\n    CFG_PIN_C13 = 363,\n    CFG_PIN_C14 = 364,\n    CFG_PIN_C15 = 365,\n    CFG_PIN_C16 = 366,\n    CFG_PIN_C17 = 367,\n    CFG_PIN_C18 = 368,\n    CFG_PIN_C19 = 369,\n    CFG_PIN_C20 = 370,\n    CFG_PIN_C21 = 371,\n    CFG_PIN_C22 = 372,\n    CFG_PIN_C23 = 373,\n    CFG_PIN_C24 = 374,\n    CFG_PIN_C25 = 375,\n    CFG_PIN_C26 = 376,\n    CFG_PIN_C27 = 377,\n    CFG_PIN_C28 = 378,\n    CFG_PIN_C29 = 379,\n    CFG_PIN_C30 = 380,\n    CFG_PIN_C31 = 381,\n    CFG_PIN_P0 = 400,\n    CFG_PIN_P1 = 401,\n    CFG_PIN_P2 = 402,\n    CFG_PIN_P3 = 403,\n    CFG_PIN_P4 = 404,\n    CFG_PIN_P5 = 405,\n    CFG_PIN_P6 = 406,\n    CFG_PIN_P7 = 407,\n    CFG_PIN_P8 = 408,\n    CFG_PIN_P9 = 409,\n    CFG_PIN_P10 = 410,\n    CFG_PIN_P11 = 411,\n    CFG_PIN_P12 = 412,\n    CFG_PIN_P13 = 413,\n    CFG_PIN_P14 = 414,\n    CFG_PIN_P15 = 415,\n    CFG_PIN_P16 = 416,\n    CFG_PIN_P17 = 417,\n    CFG_PIN_P18 = 418,\n    CFG_PIN_P19 = 419,\n    CFG_PIN_P20 = 420,\n    CFG_PIN_P21 = 421,\n    CFG_PIN_P22 = 422,\n    CFG_PIN_P23 = 423,\n    CFG_PIN_P24 = 424,\n    CFG_PIN_P25 = 425,\n    CFG_PIN_P26 = 426,\n    CFG_PIN_P27 = 427,\n    CFG_PIN_P28 = 428,\n    CFG_PIN_P29 = 429,\n    CFG_PIN_P30 = 430,\n    CFG_PIN_P31 = 431,\n    CFG_PIN_P32 = 432,\n    CFG_PIN_P33 = 433,\n    CFG_PIN_P34 = 434,\n    CFG_PIN_P35 = 435,\n    CFG_PIN_P36 = 436,\n    CFG_PIN_P37 = 437,\n    CFG_PIN_P38 = 438,\n    CFG_PIN_P39 = 439,\n    CFG_PIN_P40 = 440,\n    CFG_PIN_P41 = 441,\n    CFG_PIN_P42 = 442,\n    CFG_PIN_P43 = 443,\n    CFG_PIN_P44 = 444,\n    CFG_PIN_P45 = 445,\n    CFG_PIN_P46 = 446,\n    CFG_PIN_P47 = 447,\n    CFG_PIN_P48 = 448,\n    CFG_PIN_P49 = 449,\n    CFG_PIN_P50 = 450,\n    CFG_PIN_P51 = 451,\n    CFG_PIN_P52 = 452,\n    CFG_PIN_P53 = 453,\n    CFG_PIN_P54 = 454,\n    CFG_PIN_P55 = 455,\n    CFG_PIN_P56 = 456,\n    CFG_PIN_P57 = 457,\n    CFG_PIN_P58 = 458,\n    CFG_PIN_P59 = 459,\n    CFG_PIN_P60 = 460,\n    CFG_PIN_P61 = 461,\n    CFG_PIN_P62 = 462,\n    CFG_PIN_P63 = 463,\n    CFG_PIN_LORA_MISO = 1001,\n    CFG_PIN_LORA_MOSI = 1002,\n    CFG_PIN_LORA_SCK = 1003,\n    CFG_PIN_LORA_CS = 1004,\n    CFG_PIN_LORA_BOOT = 1005,\n    CFG_PIN_LORA_RESET = 1006,\n    CFG_PIN_IRRXLED = 1007,\n    CFG_PIN_IRTXLED = 1008,\n    CFG_PIN_LCD_RESET = 1009,\n    CFG_PIN_LCD_ENABLE = 1010,\n    CFG_PIN_LCD_DATALINE4 = 1011,\n    CFG_PIN_LCD_DATALINE5 = 1012,\n    CFG_PIN_LCD_DATALINE6 = 1013,\n    CFG_PIN_LCD_DATALINE7 = 1014,\n    CFG_NUM_LCD_COLUMNS = 1015,\n    CFG_NUM_LCD_ROWS = 1016,\n    CFG_PIN_RCC0 = 1017,\n    CFG_PIN_RCC1 = 1018,\n    CFG_PIN_RCC2 = 1019,\n    CFG_PIN_RCC3 = 1020,\n    CFG_PIN_RCC4 = 1021,\n    CFG_PIN_RCC5 = 1022,\n    CFG_PIN_RCC6 = 1023,\n    CFG_PIN_RCC7 = 1024,\n    CFG_PIN_SERVO0 = 1025,\n    CFG_PIN_SERVO1 = 1026,\n    CFG_PIN_SERVO2 = 1027,\n    CFG_PIN_SERVO3 = 1028,\n    CFG_PIN_SERVO4 = 1029,\n    CFG_PIN_SERVO5 = 1030,\n    CFG_PIN_SERVO6 = 1031,\n    CFG_PIN_SERVO7 = 1032,\n    CFG_PIN_SERVO8 = 1033,\n    CFG_PIN_PI_TX = 1034,\n    CFG_PIN_PI_RX = 1035,\n    CFG_PIN_GPS_SDA = 1036,\n    CFG_PIN_GPS_SCL = 1037,\n    CFG_PIN_GPS_TX = 1038,\n    CFG_PIN_GPS_RX = 1039,\n    CFG_PIN_GROVE0 = 1040,\n    CFG_PIN_GROVE1 = 1041,\n    CFG_PIN_SS = 1042,\n    CFG_PIN_D33 = 183,\n    CFG_PIN_D34 = 184,\n    CFG_PIN_D35 = 185,\n    CFG_PIN_D36 = 186,\n    CFG_PIN_D37 = 187,\n    CFG_PIN_D38 = 188,\n    CFG_PIN_D39 = 189,\n    CFG_PIN_D40 = 190,\n    CFG_PIN_D41 = 191,\n    CFG_PIN_D42 = 192,\n    CFG_PIN_D43 = 193,\n    CFG_PIN_D44 = 194,\n    CFG_PIN_D45 = 195,\n    CFG_PIN_D46 = 196,\n    CFG_PIN_D47 = 197,\n    CFG_PIN_D48 = 198,\n    CFG_PIN_D49 = 199,\n    CFG_PIN_D50 = 259,\n    CFG_PIN_D51 = 260,\n    CFG_PIN_D52 = 261,\n    CFG_PIN_D53 = 262,\n    CFG_PIN_TX1 = 263,\n    CFG_PIN_TX2 = 264,\n    CFG_PIN_TX3 = 265,\n    CFG_PIN_RX1 = 266,\n    CFG_PIN_RX2 = 267,\n    CFG_PIN_RX3 = 268,\n    CFG_PIN_SCL1 = 269,\n    CFG_PIN_SDA1 = 270,\n    CFG_PIN_PCC_D0 = 271,\n    CFG_PIN_PCC_D1 = 272,\n    CFG_PIN_PCC_D2 = 273,\n    CFG_PIN_PCC_D3 = 274,\n    CFG_PIN_PCC_D4 = 275,\n    CFG_PIN_PCC_D5 = 276,\n    CFG_PIN_PCC_D6 = 277,\n    CFG_PIN_PCC_D7 = 278,\n    CFG_PIN_PCC_D8 = 279,\n    CFG_PIN_PCC_D9 = 280,\n    CFG_PIN_PCC_D10 = 281,\n    CFG_PIN_PCC_D11 = 282,\n    CFG_PIN_PCC_D12 = 283,\n    CFG_PIN_PCC_D13 = 284,\n    CFG_PIN_CC_DEN1 = 285,\n    CFG_PIN_CC_DEN2 = 286,\n    CFG_PIN_CC_CLK = 287,\n    CFG_PIN_XCC_CLK = 288,\n    CFG_PIN_JDPWR_PRE_SENSE = 1100,\n    CFG_PIN_JDPWR_GND_SENSE = 1101,\n    CFG_PIN_JDPWR_PULSE = 1102,\n    CFG_PIN_JDPWR_OVERLOAD_LED = 1103,\n    CFG_PIN_JDPWR_ENABLE = 1104,\n    CFG_PIN_JDPWR_FAULT = 1105,\n    CFG_USER_CFG_0 = 2000,\n    CFG_USER_CFG_1 = 2001,\n    CFG_USER_CFG_2 = 2002,\n    CFG_USER_CFG_3 = 2003,\n    CFG_USER_CFG_4 = 2004,\n    CFG_USER_CFG_5 = 2005,\n    CFG_USER_CFG_6 = 2006,\n    CFG_USER_CFG_7 = 2007,\n    CFG_USER_CFG_8 = 2008,\n    CFG_USER_CFG_9 = 2009,\n    CFG_ARCADE_CFG_0 = 2100,\n    CFG_ARCADE_CFG_1 = 2101,\n    CFG_ARCADE_SCREEN_WIDTH = 2102,\n    CFG_ARCADE_SCREEN_HEIGHT = 2103,\n\n    // /pxtapp/hf2dbg.h\n    HF2DBG_H = 1,\n    // /pxtapp/mixer---rp2040/melody.h\n    OUTPUT_BITS = 10,\n    SW_TRIANGLE = 1,\n    SW_SAWTOOTH = 2,\n    SW_SINE = 3,\n    SW_TUNEDNOISE = 4,\n    SW_NOISE = 5,\n    SW_SQUARE_10 = 11,\n    SW_SQUARE_50 = 15,\n    SW_SQUARE_CYCLE_16 = 16,\n    SW_SQUARE_CYCLE_32 = 17,\n    SW_SQUARE_CYCLE_64 = 18,\n    CODAL = 1,\n    MAX_SOUNDS = 5,\n    Waiting = 0,\n    Playing = 1,\n    Done = 2,\n    // /pxtapp/pins.h\n    BUTTON_ACTIVE_HIGH_PULL_DOWN = 17,\n    BUTTON_ACTIVE_HIGH_PULL_UP = 33,\n    BUTTON_ACTIVE_HIGH_PULL_NONE = 49,\n    BUTTON_ACTIVE_LOW_PULL_DOWN = 16,\n    BUTTON_ACTIVE_LOW_PULL_UP = 32,\n    BUTTON_ACTIVE_LOW_PULL_NONE = 48,\n    // /pxtapp/platform.h\n    IMAGE_BITS = 4,\n    PAGE_SIZE = 256,\n    DEV_NUM_PINS = 30,\n    DEV_PWM_PINS = 1073741823,\n    DEV_AIN_PINS = 1006632960,\n    DEV_ANALOG_PINS = 1073741823,\n    P0 = 0,\n    P1 = 1,\n    P2 = 2,\n    P3 = 3,\n    P4 = 4,\n    P5 = 5,\n    P6 = 6,\n    P7 = 7,\n    P8 = 8,\n    P9 = 9,\n    P10 = 10,\n    P11 = 11,\n    P12 = 12,\n    P13 = 13,\n    P14 = 14,\n    P15 = 15,\n    P16 = 16,\n    P17 = 17,\n    P18 = 18,\n    P19 = 19,\n    P20 = 20,\n    P21 = 21,\n    P22 = 22,\n    P23 = 23,\n    P24 = 24,\n    P25 = 25,\n    P26 = 26,\n    P27 = 27,\n    P28 = 28,\n    P29 = 29,\n    P30 = 30,\n    // /pxtapp/pxt.h\n    PXT_COMM_BASE = 536879104,\n    DEVICE_ID_BUTTON_SLIDE = 3000,\n    DEVICE_ID_MICROPHONE = 3001,\n    DEVICE_ID_FIRST_BUTTON = 4000,\n    DEVICE_ID_FIRST_TOUCHBUTTON = 4100,\n    PXT_INTERNAL_KEY_UP = 2050,\n    PXT_INTERNAL_KEY_DOWN = 2051,\n    // /pxtapp/pxtbase.h\n    PXT32 = 1,\n    PXT64 = 1,\n    PXT_REFCNT_FLASH = 65534,\n    VTABLE_MAGIC = 249,\n    VTABLE_MAGIC2 = 248,\n    Undefined = 0,\n    Boolean = 1,\n    Number = 2,\n    String = 3,\n    Object = 4,\n    Function = 5,\n    BoxedString = 1,\n    BoxedNumber = 2,\n    BoxedBuffer = 3,\n    RefAction = 4,\n    RefImage = 5,\n    RefCollection = 6,\n    RefRefLocal = 7,\n    RefMap = 8,\n    RefMImage = 9,\n    MMap = 10,\n    BoxedString_SkipList = 11,\n    BoxedString_ASCII = 12,\n    ZPin = 13,\n    User0 = 16,\n    IMAGE_HEADER_MAGIC = 135,\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    UInt32LE = 11,\n    UInt32BE = 12,\n    Float32LE = 13,\n    Float64LE = 14,\n    Float32BE = 15,\n    Float64BE = 16,\n    NUM_TRY_FRAME_REGS = 3,\n    GC = 0,\n    PXT_STRING_SKIP_INCR = 16,\n    // /pxtapp/pxtconfig.h\n    PXT_UF2_FAMILY = 3834380118,\n    // /pxtapp/pxtcore.h\n    PXT_CODAL = 1,\n    // /pxtapp/screen---st7735/arcadegamepad.h\n    _JACDAC_SPEC_ARCADE_GAMEPAD_H = 1,\n    // /pxtapp/screen---st7735/arcadesound.h\n    _JACDAC_SPEC_ARCADE_SOUND_H = 1,\n    // /pxtapp/screen---st7735/indexedscreen.h\n    _JACDAC_SPEC_INDEXED_SCREEN_H = 1,\n    // /pxtapp/screen---st7735/jdprotocol.h\n    JDSPI_MAGIC = 31437,\n    JDSPI_MAGIC_NOOP = 46029,\n    // /pxtapp/settings/Flash.h\n    DEVICE_FLASH_ERROR = 922,\n    // /pxtapp/settings/RAFFS.h\n    RAFFS_FOLLOWING_MASK = 32768,\n    // /pxtapp/thermometer/target_temperature.h\n    TEMPERATURE_NOMINAL_VALUE = 25,\n    TEMPERATURE_NOMINAL_READING = 10000,\n    TEMPERATURE_BETA = 3380,\n    TEMPERATURE_SERIES_RESISTOR = 10000,\n    // /pxtapp/uf2format.h\n    BOOTLOADER_START = 0,\n    BOOTLOADER_END = 8192,\n    // /pxtapp/uf2hid.h\n    UF2_HID_H = 1,\n}\n","dmac.cpp":"#include \"dmac.h\"\n\nnamespace pxt {\n\n#ifdef CODAL_DMAC\nSINGLETON(WDMAC);\n#endif\n\n}","dmac.h":"#ifndef __DMAC_H\n#define __DMAC_H\n\n#include \"pxt.h\"\n\nnamespace pxt {\n\n#ifdef CODAL_DMAC\nclass WDMAC {\n  public:\n    CODAL_DMAC dmac;\n\n    WDMAC() {}\n};\n\nWDMAC* getWDMAC();\n#endif\n\n}\n\n#endif","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum PulseValue {\n    //% block=high\n    High = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=low\n    Low = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    }\n\n\n    declare const enum PinEvent {\n    //% block=\"pulse high\"\n    PulseHigh = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=\"pulse low\"\n    PulseLow = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    //% block=\"rise\"\n    Rise = 2,  // DEVICE_PIN_EVT_RISE\n    //% block=\"fall\"\n    Fall = 3,  // DEVICE_PIN_EVT_FALL\n    }\n\n\n    declare const enum PinPullMode {\n    //% block=\"down\"\n    PullDown = 0,\n    //% block=\"up\"\n    PullUp = 1,\n    //% block=\"none\"\n    PullNone = 2,\n    }\n\n// Auto-generated. Do not edit. Really.\n","hf2.cpp":"#include \"pxt.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#ifndef USB_HANDOVER\n#define USB_HANDOVER 1\n#endif\n\n#if USB_HANDOVER\n#define UF2_DEFINE_HANDOVER 1\n#endif\n\n#include \"uf2format.h\"\n\nstatic void *stackCopy;\nstatic uint32_t stackSize;\n\n//#define LOG DMESG\n#define LOG(...) ((void)0)\n\nstatic volatile bool resume = false;\n\nusing namespace codal;\n\n#ifdef HF2_HID\nstatic const char hidDescriptor[] = {\n    0x06, 0x97, 0xFF, // usage page vendor 0x97 (usage 0xff97 0x0001)\n    0x09, 0x01,       // usage 1\n    0xA1, 0x01,       // collection - application\n    0x15, 0x00,       // logical min 0\n    0x26, 0xFF, 0x00, // logical max 255\n    0x75, 8,          // report size 8\n    0x95, 64,         // report count 64\n    0x09, 0x01,       // usage 1\n    0x81, 0x02,       // input: data, variable, absolute\n    0x95, 64,         // report count 64\n    0x09, 0x01,       // usage 1\n    0x91, 0x02,       // output: data, variable, absolute\n    0x95, 1,          // report count 1\n    0x09, 0x01,       // usage 1\n    0xB1, 0x02,       // feature: data, variable, absolute\n    0xC0,             // end\n};\n\nstatic const HIDReportDescriptor reportDesc = {\n    9,\n    0x21,                  // HID\n    0x100,                 // hidbcd 1.00\n    0x00,                  // country code\n    0x01,                  // num desc\n    0x22,                  // report desc type\n    sizeof(hidDescriptor), // size of 0x22\n};\n\nstatic const InterfaceInfo ifaceInfoHID = {\n    &reportDesc,\n    sizeof(reportDesc),\n    1,\n    {\n        2,    // numEndpoints\n        0x03, /// class code - HID\n        0x00, // subclass\n        0x00, // protocol\n        0x02, // string\n        0x00, // alt\n    },\n    {USB_EP_TYPE_INTERRUPT, 1},\n    {USB_EP_TYPE_INTERRUPT, 1},\n};\n#endif\n\nstatic const InterfaceInfo ifaceInfoEP = {\n    NULL,\n    0,\n    2,\n    {\n        2,    // numEndpoints\n        0xff, /// class code - vendor-specific\n        42,   // subclass\n        1,    // protocol\n        0x02, // string\n        0x00, // alt\n    },\n    {USB_EP_TYPE_BULK, 0},\n    {USB_EP_TYPE_BULK, 0},\n};\n\nint HF2::stdRequest(UsbEndpointIn &ctrl, USBSetup &setup) {\n#ifdef HF2_HID\n    if (!useHID)\n        return DEVICE_NOT_SUPPORTED;\n    if (setup.bRequest == USB_REQ_GET_DESCRIPTOR) {\n        if (setup.wValueH == 0x21) {\n            InterfaceDescriptor tmp;\n            fillInterfaceInfo(&tmp);\n            return ctrl.write(&tmp, sizeof(tmp));\n        } else if (setup.wValueH == 0x22) {\n            return ctrl.write(hidDescriptor, sizeof(hidDescriptor));\n        }\n    }\n#endif\n    return DEVICE_NOT_SUPPORTED;\n}\n\n#define HF2_FLAG_EVENT 0x01\n\nREAL_TIME_FUNC\nvoid HF2::sendBuffer(uint8_t flag, const void *data, unsigned size, uint32_t prepend) {\n    if (!CodalUSB::usbInstance->isInitialised())\n        return;\n\n#ifdef USB_EP_FLAG_ASYNC\n    // drop non-responses if too much stuff queued up\n    if (flag != HF2_FLAG_CMDPKT_LAST && pendingWriteSize > 1000)\n        return;\n#endif\n\n    if (flag == HF2_FLAG_EVENT)\n        flag = HF2_FLAG_CMDPKT_LAST;\n\n    if (prepend + 1)\n        size += 4;\n\n#ifdef USB_EP_FLAG_ASYNC\n    HF2_PendingWrite *e = (HF2_PendingWrite *)malloc(sizeof(HF2_PendingWrite) + size);\n    e->size = size;\n    e->flag = flag;\n    e->next = NULL;\n    uint8_t *dst = e->data;\n    if (prepend + 1) {\n        memcpy(dst, &prepend, 4);\n        dst += 4;\n        size -= 4;\n    }\n    memcpy(dst, data, size);\n\n    target_disable_irq();\n    auto p = this->pendingWrite;\n    if (!p)\n        this->pendingWrite = e;\n    else {\n        while (p->next)\n            p = p->next;\n        p->next = e;\n    }\n    this->pendingWriteSize += 16 + e->size;\n    target_enable_irq();\n\n    pokeSend();\n#else\n    uint32_t buf[64 / 4]; // aligned\n\n    target_disable_irq();\n    while (size > 0) {\n        memset(buf + 1, 0, 60);\n        int s = 63;\n        if (size <= 63) {\n            s = size;\n            buf[0] = flag;\n        } else {\n            buf[0] = flag == HF2_FLAG_CMDPKT_LAST ? HF2_FLAG_CMDPKT_BODY : flag;\n        }\n        buf[0] |= s;\n        uint8_t *dst = (uint8_t *)buf;\n        dst++;\n        if (prepend + 1) {\n            memcpy(dst, &prepend, 4);\n            prepend = -1;\n            dst += 4;\n            s -= 4;\n            size -= 4;\n        }\n        memcpy(dst, data, s);\n        data = (const uint8_t *)data + s;\n        size -= s;\n\n        in->write(buf, sizeof(buf));\n    }\n    target_enable_irq();\n#endif\n}\n\nconst InterfaceInfo *HF2::getInterfaceInfo() {\n#ifdef HF2_HID\n    if (useHID)\n        return &ifaceInfoHID;\n#endif\n    return &ifaceInfoEP;\n}\n\nint HF2::sendEvent(uint32_t evId, const void *data, int size) {\n    sendBuffer(HF2_FLAG_EVENT, data, size, evId);\n    return 0;\n}\n\nint HF2::sendSerial(const void *data, int size, int isError) {\n    if (!gotSomePacket)\n        return DEVICE_OK;\n\n    sendBuffer(isError ? HF2_FLAG_SERIAL_ERR : HF2_FLAG_SERIAL_OUT, data, size);\n\n    return 0;\n}\n\n// Receive HF2 message\n// Does not block. Will store intermediate data in pkt.\n// `serial` flag is cleared if we got a command message.\nint HF2::recv() {\n    uint8_t buf[64];\n\n    int len = out->read(buf, sizeof(buf));\n    // DMESG(\"HF2 read: %d\", len);\n\n    if (len <= 0)\n        return len;\n\n    uint8_t tag = buf[0];\n    // serial packets not allowed when in middle of command packet\n    usb_assert(pkt.size == 0 || !(tag & HF2_FLAG_SERIAL_OUT));\n    int size = tag & HF2_SIZE_MASK;\n    usb_assert(pkt.size + size <= (int)sizeof(pkt.buf));\n    memcpy(pkt.buf + pkt.size, buf + 1, size);\n    pkt.size += size;\n    tag &= HF2_FLAG_MASK;\n    if (tag != HF2_FLAG_CMDPKT_BODY) {\n        if (tag == HF2_FLAG_CMDPKT_LAST)\n            pkt.serial = 0;\n        else if (tag == HF2_FLAG_SERIAL_OUT)\n            pkt.serial = 1;\n        else\n            pkt.serial = 2;\n        int sz = pkt.size;\n        pkt.size = 0;\n        return sz;\n    }\n    return 0;\n}\n\nint HF2::sendResponse(int size) {\n    sendBuffer(HF2_FLAG_CMDPKT_LAST, pkt.buf, 4 + size);\n    return 0;\n}\n\nint HF2::sendResponseWithData(const void *data, int size) {\n    if (size <= (int)sizeof(pkt.buf) - 4) {\n        memcpy(pkt.resp.data8, data, size);\n        return sendResponse(size);\n    } else {\n        sendBuffer(HF2_FLAG_CMDPKT_LAST, data, size, pkt.resp.eventId);\n        return 0;\n    }\n}\n\nstatic void copy_words(void *dst0, const void *src0, uint32_t n_words) {\n    uint32_t *dst = (uint32_t *)dst0;\n    const uint32_t *src = (const uint32_t *)src0;\n    while (n_words--)\n        *dst++ = *src++;\n}\n\n#ifndef QUICK_BOOT\n#ifdef SAMD21\n#define DBL_TAP_PTR ((volatile uint32_t *)(HMCRAMC0_ADDR + HMCRAMC0_SIZE - 4))\n#endif\n#ifdef SAMD51\n#define DBL_TAP_PTR ((volatile uint32_t *)(HSRAM_ADDR + HSRAM_SIZE - 4))\n#endif\n#if defined(NRF52840) || defined(NRF52833)\n#define DBL_TAP_PTR ((volatile uint32_t *)0x20007F7C)\n#endif\n#ifdef DBL_TAP_PTR\n#define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef\n#define QUICK_BOOT(v) *DBL_TAP_PTR = v ? DBL_TAP_MAGIC_QUICK_BOOT : 0\n#endif\n#endif\n\nstatic HF2 *jdLogger;\nstatic void jdLog(const uint8_t *frame) {\n    jdLogger->sendEvent(HF2_EV_JDS_PACKET, frame, frame[2] + 12);\n}\n\nvoid HF2::pokeSend() {\n#ifdef USB_EP_FLAG_ASYNC\n    target_disable_irq();\n    while (pendingWrite && in->canWrite()) {\n        in->flags |= USB_EP_FLAG_ASYNC;\n\n        int size = pendingWrite->size - pendingWritePtr;\n        usb_assert(size > 0);\n        uint32_t buf[64 / 4] = {0};\n\n        int s = 63;\n        if (size <= 63) {\n            s = size;\n            buf[0] = pendingWrite->flag;\n        } else {\n            buf[0] = pendingWrite->flag == HF2_FLAG_CMDPKT_LAST ? HF2_FLAG_CMDPKT_BODY\n                                                                : pendingWrite->flag;\n        }\n        buf[0] |= s;\n        uint8_t *dst = (uint8_t *)buf;\n        dst++;\n        memcpy(dst, pendingWrite->data + pendingWritePtr, s);\n\n        int r = in->write(buf, sizeof(buf));\n        if (r == 0) {\n            if (s == size) {\n                pendingWritePtr = 0;\n                pendingWriteSize -= 16 + pendingWrite->size;\n                HF2_PendingWrite *n = pendingWrite->next;\n                free(pendingWrite);\n                pendingWrite = n;\n            } else {\n                pendingWritePtr += s;\n            }\n        }\n    }\n    target_enable_irq();\n#endif\n}\n\nint HF2::endpointRequest() {\n#ifdef USB_EP_FLAG_ASYNC\n    pokeSend();\n#endif\n\n    int sz = recv();\n\n    if (!sz)\n        return 0;\n\n    uint32_t tmp;\n\n    if (pkt.serial) {\n        // TODO raise some event?\n        return 0;\n    }\n\n    LOG(\"HF2 sz=%d CMD=%x\", sz, pkt.buf32[0]);\n\n    // one has to be careful dealing with these, as they share memory\n    HF2_Command *cmd = &pkt.cmd;\n    HF2_Response *resp = &pkt.resp;\n\n    uint32_t cmdId = cmd->command_id;\n    resp->tag = cmd->tag;\n    resp->status16 = HF2_STATUS_OK;\n\n#define checkDataSize(str, add) usb_assert(sz == 8 + (int)sizeof(cmd->str) + (int)(add))\n\n    lastExchange = current_time_ms();\n    gotSomePacket = true;\n\n    switch (cmdId) {\n    case HF2_CMD_INFO:\n        return sendResponseWithData(uf2_info(), strlen(uf2_info()));\n\n    case HF2_CMD_BININFO:\n        resp->bininfo.mode = HF2_MODE_USERSPACE;\n        resp->bininfo.flash_page_size = 0;\n        resp->bininfo.flash_num_pages = 0;\n        resp->bininfo.max_message_size = sizeof(pkt.buf);\n        resp->bininfo.uf2_family = PXT_UF2_FAMILY;\n        return sendResponse(sizeof(resp->bininfo));\n\n    case HF2_DBG_RESTART:\n        *HF2_DBG_MAGIC_PTR = HF2_DBG_MAGIC_START;\n        target_reset();\n        break;\n\n#ifdef QUICK_BOOT\n    case HF2_CMD_RESET_INTO_APP:\n        QUICK_BOOT(1);\n        NVIC_SystemReset();\n        break;\n    case HF2_CMD_RESET_INTO_BOOTLOADER:\n        QUICK_BOOT(0);\n        NVIC_SystemReset();\n        break;\n#else\n    case HF2_CMD_RESET_INTO_APP:\n        NVIC_SystemReset();\n        break;\n    // reset into bootloader not supported\n#endif\n\n#if USB_HANDOVER\n    case HF2_CMD_START_FLASH:\n        sendResponse(0);\n        hf2_handover(in->ep);\n        usb_assert(0); // should not be reached\n        break;\n#endif\n\n    case HF2_CMD_WRITE_WORDS:\n        checkDataSize(write_words, cmd->write_words.num_words << 2);\n        copy_words((void *)cmd->write_words.target_addr, cmd->write_words.words,\n                   cmd->write_words.num_words);\n        break;\n\n    case HF2_CMD_READ_WORDS:\n        checkDataSize(read_words, 0);\n        tmp = cmd->read_words.num_words;\n        usb_assert(tmp <= sizeof(pkt.buf) / 4 - 1);\n        copy_words(resp->data32, (void *)cmd->read_words.target_addr, tmp);\n        return sendResponse(tmp << 2);\n\n    case HF2_CMD_DMESG:\n#if DEVICE_DMESG_BUFFER_SIZE > 0\n        return sendResponseWithData(codalLogStore.buffer, codalLogStore.ptr);\n#else\n        break;\n#endif\n\n    case HF2_DBG_GET_GLOBAL_STATE: {\n        HF2_GLOBAL_STATE_Result gstate = {\n            .num_globals = (uint32_t)getNumGlobals(), //\n            .globals_addr = (uint32_t)globals,\n        };\n        return sendResponseWithData(&gstate, sizeof(gstate));\n    }\n\n    case HF2_DBG_RESUME:\n        globals[0] = (TValue)cmd->data32[0];\n        resume = true;\n        return sendResponse(0);\n\n    case HF2_DBG_GET_STACK:\n        return sendResponseWithData(stackCopy, stackSize);\n\n    case HF2_CMD_JDS_CONFIG:\n        if (cmd->data8[0]) {\n            jdLogger = this;\n            pxt::logJDFrame = jdLog;\n        } else {\n            pxt::logJDFrame = NULL;\n        }\n        return sendResponse(0);\n\n    case HF2_CMD_JDS_SEND:\n        if (pxt::sendJDFrame) {\n            pxt::sendJDFrame(cmd->data8);\n            return sendResponse(0);\n        } else {\n            resp->status16 = HF2_STATUS_INVALID_STATE;\n            return sendResponse(0);\n        }\n\n    default:\n        // command not understood\n        resp->status16 = HF2_STATUS_INVALID_CMD;\n        break;\n    }\n\n    return sendResponse(0);\n}\n\nHF2::HF2(HF2_Buffer &p) : gotSomePacket(false), ctrlWaiting(false), pkt(p), useHID(false) {\n    lastExchange = 0;\n#ifdef USB_EP_FLAG_ASYNC\n    pendingWrite = NULL;\n    pendingWriteSize = 0;\n    pendingWritePtr = 0;\n#endif\n}\n\nstatic const InterfaceInfo dummyIfaceInfo = {\n    NULL,\n    0,\n    0,\n    {\n        0,    // numEndpoints\n        0xff, /// class code - vendor-specific\n        0xff, // subclass\n        0xff, // protocol\n        0x00, // string\n        0x00, // alt\n    },\n    {0, 0},\n    {0, 0},\n};\n\nconst InterfaceInfo *DummyIface::getInterfaceInfo() {\n    return &dummyIfaceInfo;\n}\n\n//\n//\n// Debugger\n//\n//\n\nstruct ExceptionContext {\n    uint32_t excReturn; // 0xFFFFFFF9\n    uint32_t r0;\n    uint32_t r1;\n    uint32_t r2;\n    uint32_t r3;\n    uint32_t r12;\n    uint32_t lr;\n    uint32_t faultInstrAddr;\n    uint32_t psr;\n};\n\nstruct Paused_Data {\n    uint32_t pc;\n};\nstatic Paused_Data pausedData;\n\nvoid bkptPaused() {\n\n// waiting for https://github.com/lancaster-university/codal/pull/14\n#ifdef DEVICE_GROUP_ID_USER\n    // the loop below counts as \"system\" task, and we don't want to pause ourselves\n    fiber_set_group(DEVICE_GROUP_ID_SYSTEM);\n    // pause everyone else\n    fiber_pause_group(DEVICE_GROUP_ID_USER);\n#endif\n\n    while (!resume) {\n        // DMESG(\"BKPT\");\n        hf2.pkt.resp.eventId = HF2_EV_DBG_PAUSED;\n        hf2.sendResponseWithData(&pausedData, sizeof(pausedData));\n        // TODO use an event\n        for (int i = 0; i < 20; ++i) {\n            if (resume)\n                break;\n            fiber_sleep(50);\n        }\n    }\n\n    if (stackCopy) {\n        xfree(stackCopy);\n        stackCopy = NULL;\n    }\n\n#ifdef DEVICE_GROUP_ID_USER\n    fiber_resume_group(DEVICE_GROUP_ID_USER);\n    // go back to user mode\n    fiber_set_group(DEVICE_GROUP_ID_USER);\n#endif\n\n    resume = false;\n}\n\nextern \"C\" void handleHardFault(ExceptionContext *ectx) {\n    auto instr = (uint16_t *)ectx->faultInstrAddr;\n\n    DMESG(\"FLT %p\", instr);\n\n    if (ectx->faultInstrAddr & 0x80000000) {\n        ectx->faultInstrAddr &= ~0x80000000;\n        // switch to step-over mode\n        globals[0] = (TValue)3;\n        return;\n    }\n\n    DMESG(\"BB %p %p %p lr=%p r0=%p\", instr[-1], instr[0], instr[1], ectx->lr, ectx->r0);\n\n    if (instr[0] == 0x6840) {\n        // ldr r0, [r0, #4] -- entry breakpoint\n        ectx->faultInstrAddr += 2;\n        // we're being ask for step-over mode\n        if (ectx->r0 == 3) {\n            // switch to debugger-attached-no-stepping mode\n            globals[0] = (TValue)0;\n            ectx->lr |= 0x80000000;\n        }\n        return;\n    }\n\n    if (instr[0] == 0x6800) {\n        // ldr r0, [r0, #0]\n        ectx->lr = ectx->faultInstrAddr + 3; // next instruction + thumb mode\n        pausedData.pc = ectx->faultInstrAddr + 2;\n        void *ssp = (void *)(ectx + 1);\n        stackSize = DEVICE_STACK_BASE - (uint32_t)ssp;\n        if (stackCopy)\n            xfree(stackCopy);\n        stackCopy = xmalloc(stackSize);\n        memcpy(stackCopy, ssp, stackSize);\n        ectx->faultInstrAddr = ((uint32_t)(&bkptPaused) & (~1U));\n        return;\n    }\n\n    while (1) {\n    }\n}\n\nextern \"C\" void HardFault_Handler(void) {\n    asm(\"push {lr}; mov r0, sp; bl handleHardFault; pop {pc}\");\n}\n\n#endif","hf2.h":"#ifndef DEVICE_HF2_H\n#define DEVICE_HF2_H\n\n#if CONFIG_ENABLED(DEVICE_USB)\n\n#include \"HID.h\"\n#include \"uf2hid.h\"\n\n// 260 bytes needed for biggest JD packets (with overheads)\n#define HF2_BUF_SIZE 260\n\ntypedef struct {\n    uint16_t size;\n    uint8_t serial;\n    union {\n        uint8_t buf[HF2_BUF_SIZE];\n        uint32_t buf32[HF2_BUF_SIZE / 4];\n        uint16_t buf16[HF2_BUF_SIZE / 2];\n        HF2_Command cmd;\n        HF2_Response resp;\n    };\n} HF2_Buffer;\n\nstruct HF2_PendingWrite {\n    HF2_PendingWrite *next;\n    uint16_t size;\n    uint8_t flag;\n    uint8_t _reserved;\n    uint8_t data[0];\n};\n\nclass HF2 : public CodalUSBInterface {\n    bool gotSomePacket;\n    bool ctrlWaiting;\n    uint32_t lastExchange;\n\n#ifdef USB_EP_FLAG_ASYNC\n    HF2_PendingWrite *pendingWrite;\n    int pendingWriteSize;\n    int pendingWritePtr;\n#endif\n\n  public:\n    HF2_Buffer &pkt;\n\n    bool useHID;\n\n    int sendResponse(int size);\n    int recv();\n    int sendResponseWithData(const void *data, int size);\n    int sendEvent(uint32_t evId, const void *data, int size);\n    void sendBuffer(uint8_t flag, const void *data, unsigned size, uint32_t prepend = -1);\n    void pokeSend();\n\n    HF2(HF2_Buffer &pkt);\n    virtual int endpointRequest();\n    virtual int stdRequest(UsbEndpointIn &ctrl, USBSetup &setup);\n    virtual const InterfaceInfo *getInterfaceInfo();\n    int sendSerial(const void *data, int size, int isError = 0);\n\n    virtual bool enableWebUSB() { return !useHID; }\n};\n\nclass DummyIface : public CodalUSBInterface {\n  public:\n    virtual const InterfaceInfo *getInterfaceInfo();\n};\n\n#endif\n\n#endif\n","hf2dbg.h":"#ifndef HF2DBG_H\n#define HF2DBG_H 1\n\n// we use a location at the top of the stack to store a magic value\n// which causes us to stop at the very first break point in the program\n#define HF2_DBG_MAGIC_PTR ((uint32_t *)(DEVICE_STACK_BASE - (DEVICE_STACK_SIZE - 4)))\n#define HF2_DBG_MAGIC_START 0xf0ebac7f\n\n#define HF2_DBG_GET_GLOBAL_STATE 0x53fc66e0\nstruct HF2_GLOBAL_STATE_Result {\n    uint32_t num_globals;\n    uint32_t globals_addr;\n};\n\n#define HF2_DBG_RESTART 0x1120bd93\n#define HF2_DBG_RESUME 0x27a55931\n#define HF2_EV_DBG_PAUSED 0x3692f9fd\n#define HF2_DBG_GET_STACK 0x70901510\n\n#endif\n","i2c.cpp":"#include \"pxt.h\"\n#include \"ErrorNo.h\"\n#include \"CodalDmesg.h\"\n#include \"configkeys.h\"\n\n#ifdef CODAL_I2C\n\nnamespace pins {\n\nclass CodalI2CProxy {\nprivate:\n  DevicePin* sda;\n  DevicePin* scl;\n  CODAL_I2C i2c;\npublic:\n  CodalI2CProxy* next;\npublic:\n  CodalI2CProxy(DevicePin* _sda, DevicePin* _scl)\n    : sda(_sda)\n    , scl(_scl)\n    , i2c(*_sda, *_scl) \n    , next(NULL)\n  {\n\n  }\n\n  CODAL_I2C* getI2C() {\n    return &(this->i2c);\n  }\n  \n  bool matchPins(DevicePin* sda, DevicePin* scl) {\n      return this->sda == sda && this->scl == scl;\n  }\n\n  Buffer readBuffer(int address, int size, bool repeat = false)\n  {\n    Buffer buf = mkBuffer(NULL, size);\n    registerGCObj(buf);\n    int status = this->i2c.read(address << 1, buf->data, size, repeat);\n    unregisterGCObj(buf);\n    if (status != ErrorCode::DEVICE_OK) {\n      buf = 0;\n    }\n    return buf;\n  }\n\n  int writeBuffer(int address, Buffer buf, bool repeat = false)\n  {\n    return this->i2c.write(address << 1, buf->data, buf->length, repeat);\n  }\n};\n\n}\n\nnamespace I2CMethods {\n/**\n  * Read `size` bytes from a 7-bit I2C `address`.\n  */\n//%\nBuffer readBuffer(I2C_ i2c, int address, int size, bool repeat = false)\n{\n  return i2c->readBuffer(address, size, repeat);\n}\n\n/**\n  * Write bytes to a 7-bit I2C `address`.\n  */\n//%\nint writeBuffer(I2C_ i2c, int address, Buffer buf, bool repeat = false)\n{\n  return i2c->writeBuffer(address, buf, repeat);\n}\n\n}\n\nnamespace pins {\n\nstatic I2C_ i2cs(NULL);\n/**\n* Opens a Serial communication driver\n*/\n//% help=pins/create-i2c\n//% parts=i2c\nI2C_ createI2C(DigitalInOutPin sda, DigitalInOutPin scl) {\n  // pick up defaults\n  if (!sda || !scl) {\n    DMESG(\"i2c: lookup default pins\");\n    sda = LOOKUP_PIN(SDA);\n    scl = LOOKUP_PIN(SCL);\n  }\n\n  // lookup existing devices\n  auto dev = i2cs;\n  while(dev) {\n    if (dev->matchPins(sda, scl)) {\n      DMESG(\"i2c: found existing i2c\");\n      return dev;\n    }\n    dev = dev->next;\n  }\n\n  // allocate new one\n  DMESG(\"i2c: mounting on new device\");\n  auto ser = new CodalI2CProxy(sda, scl);\n  // push in list\n  ser->next = i2cs;\n  i2cs = ser;\n  return ser;\n}\n\n}\n\nnamespace pxt {\n  CODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl) {\n    auto i2c = pins::createI2C(sda, scl);\n    return i2c->getI2C();\n  }\n}\n\n#endif","i2c.ts":"namespace pins {\n    /**\n     * Read one number from an I2C address.\n     */\n    //% help=pins/i2c-read-number weight=5 group=\"i2c\" inlineInputMode=\"external\"\n    //% blockId=pins_i2c_readnumber block=\"i2c read number at address %address|of format %format|repeated %repeated\"\n    export function i2cReadNumber(address: number, format: NumberFormat, repeated?: boolean): number {\n        const buf = pins.i2cReadBuffer(address, pins.sizeOf(format), repeated)\n        if (!buf)\n            return undefined\n        return buf.getNumber(format, 0)\n    }\n\n    /**\n     * Write one number to an I2C address.\n     */\n    //% help=pins/i2c-write-number weight=4 group=\"i2c\"\n    //% blockId=i2c_writenumber block=\"i2c write number|at address %address|with value %value|of format %format|repeated %repeated\"\n    export function i2cWriteNumber(address: number, value: number, format?: NumberFormat, repeated?: boolean): void {\n        if (format == undefined)\n            format = NumberFormat.UInt8LE;\n        const buf = control.createBuffer(pins.sizeOf(format))\n        buf.setNumber(format, 0, value)\n        pins.i2cWriteBuffer(address, buf, repeated)\n    }\n\n    /**\n     * Write a value in a I2C register.\n     * @param address I2c address of the device\n     * @param register register index\n     * @param value value to write\n     * @param valueFormat format of the value, default is UInt8LE\n     */\n    //% weight=3 group=\"i2c\"\n    //% help=pins/i2c-write-register\n    //% blockId=i2c_writereg block=\"i2c write register|at address $address|at register $register|value $value\"\n    export function i2cWriteRegister(address: number, register: number, value: number, valueFormat?: NumberFormat): void {\n        if (valueFormat === undefined)\n            valueFormat = NumberFormat.UInt8LE;\n        const valueSize = pins.sizeOf(valueFormat);\n        const buf = control.createBuffer(1 + valueSize);\n        buf.setNumber(NumberFormat.UInt8LE, 0, register);\n        buf.setNumber(valueFormat, 1, value);\n        pins.i2cWriteBuffer(address, buf);\n    }\n\n    /**\n     * Read the value from a I2C register.\n     * @param address I2c address of the device\n     * @param register register index\n     * @param valueFormat format of the value, default is UInt8LE\n     */\n    //% weight=3 group=\"i2c\"\n    //% help=pins/i2c-read-register\n    //% blockId=i2c_readreg block=\"i2c read register|at address $address|at register $register\"\n    export function i2cReadRegister(address: number, register: number, valueFormat?: NumberFormat): number {\n        if (valueFormat === undefined)\n            valueFormat = NumberFormat.UInt8LE;\n        pins.i2cWriteNumber(address, register, NumberFormat.UInt8LE);\n        return pins.i2cReadNumber(address, valueFormat);\n    }\n\n    /**\n     * Read `size` bytes from a 7-bit I2C `address`.\n     */\n    //%\n    export function i2cReadBuffer(address: number, size: number, repeat: boolean = false): Buffer {\n        return pins.i2c().readBuffer(address, size, repeat);\n    }\n\n    /**\n     * Write bytes to a 7-bit I2C `address`.\n     */\n    //%\n    export function i2cWriteBuffer(address: number, buf: Buffer, repeat: boolean = false): number {\n        return pins.i2c().writeBuffer(address, buf, repeat);\n    }\n\n    let _i2c: I2C;\n    /**\n     * Gets the default I2C bus\n     */\n    //%\n    export function i2c(): I2C {\n        if (!_i2c) {\n            const sda = pins.pinByCfg(DAL.CFG_PIN_SDA);\n            const scl = pins.pinByCfg(DAL.CFG_PIN_SCL);\n            _i2c = pins.createI2C(sda, scl);    \n        }\n        return _i2c;        \n    }\n\n    export class I2CDevice {\n        public address: number;\n        public bus: I2C;\n        private _hasError: boolean;\n        constructor(address: number, bus?: I2C) {\n            this.address = address;\n            this.bus = bus || i2c();\n        }\n        public readInto(buf: Buffer, repeat = false, start = 0, end: number = null) {\n            if (end === null)\n                end = buf.length\n            if (start >= end)\n                return\n            let res = this.bus.readBuffer(this.address, end - start, repeat)\n            if (!res) {\n                this._hasError = true\n                return\n            }\n            buf.write(start, res)\n        }\n        public write(buf: Buffer, repeat = false) {\n            let res = this.bus.writeBuffer(this.address, buf, repeat)\n            if (res) {\n                this._hasError = true\n            }\n        }\n        public begin(): I2CDevice {\n            this._hasError = false;\n            return this;\n        }\n        public end() {\n        }\n        public ok() {\n            return !this._hasError\n        }\n\n        public transfer(command: Buffer, response: Buffer, responseStart?: number, responseEnd?: number) {\n            this.begin();\n            if (command)\n                this.write(command);\n            if (response)\n                this.readInto(response, false, responseStart, responseEnd);\n            this.end();\n        }    \n    }\n}\n","keyvaluestorage.cpp":"#include \"pxt.h\"\n#include \"KeyValueStorage.h\"\n\nnamespace pxt {\n\nclass WKeyValueStorage {\n#ifdef CODAL_NVMCONTROLLER\n    CODAL_NVMCONTROLLER controller;\n#else\n    NVMController controller;\n#endif\n    KeyValueStorage storage;\n  public:\n\n    WKeyValueStorage()\n    : controller()\n    , storage(controller) {\n    }\n\n    bool isSupported() {\n#ifdef CODAL_NVMCONTROLLER\n      return true;\n#else\n      return false;\n#endif\n    }\n\n    int put(String key, Buffer data) {\n#ifdef CODAL_NVMCONTROLLER\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        return storage.put(mkey, data->data, data->length);\n#else\n        return -1;\n#endif\n    }\n\n    Buffer get(String key) {\n#ifdef CODAL_NVMCONTROLLER\n        Buffer buf = NULL;\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        auto entry = storage.get(mkey);\n        if (entry) {\n          buf = mkBuffer(entry->value, sizeof(entry->value));\n          free(entry);\n        }\n        return buf;\n#else\n        return NULL;\n#endif\n    }\n\n    void remove(String key) {\n#ifdef CODAL_NVMCONTROLLER\n        ManagedString mkey(key->getUTF8Data(), key->getUTF8Size());\n        storage.remove(mkey);\n#endif\n    }\n\n    void clear() {\n#ifdef CODAL_NVMCONTROLLER\n        storage.wipe();\n#endif\n    }\n};\nSINGLETON(WKeyValueStorage);\n\n}\n\nnamespace configStorage {\n  /**\n  * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n  * @param key the identifier (max 16 characters)\n  * @param value the data (max 32 characters)\n  */\n  //%\n  void setBuffer(String key, Buffer value) {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->put(key, value);\n  }\n\n  /**\n  * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n  * @param key the identifier (max 16 characters)\n  */\n  //%\n  Buffer getBuffer(String key) {\n    auto kvm = pxt::getWKeyValueStorage();\n    return kvm->get(key);\n  }\n\n  /**\n  * Removes the key from local storage\n  * @param key the identifier (max 16 characters)\n  */\n  //%\n  void removeItem(String key) {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->remove(key);\n  }\n\n  /**\n  * Clears the local storage\n  */\n  //%\n  void clear() {\n    auto kvm = pxt::getWKeyValueStorage();\n    kvm->clear();\n  }\n}\n","keyvaluestorage.ts":"namespace configStorage {\n    /**\n     * Stores the value at the key entry\n     * @param key identifier of the key (max 16 characters)\n     * @param value identifier of the value (max 32 characters)\n     */\n    export function setItem(key: string, value: string) {\n        if (value == null)\n            configStorage.removeItem(key);\n        else\n        {\n            let idx = 0;\n            let buf = control.createBuffer(value.length + 1);\n            buf[idx++] = value.length;\n            let valBuf = control.createBufferFromUTF8(value);\n\n            for (let i = 0; i < valBuf.length; i++)\n                buf[idx++] = valBuf[i];\n\n            configStorage.setBuffer(key, buf);\n        }\n    }\n\n    /**\n     * Retrieves the value at the key entry\n     * @param key identifier of the key (max 16 characters)\n     */\n    export function getItem(key: string): string {\n        const buf = configStorage.getBuffer(key);\n\n        if (!buf)\n            return undefined;\n\n        let idx = 0;\n        let count = buf[idx++];\n        const retBuf = control.createBuffer(count);\n\n        for (let i = 0; i < count; i++)\n            retBuf[i] = buf[idx++];\n\n        return retBuf.toString();\n    }\n}\n","leveldetector.ts":"namespace pins {\n    export class LevelDetector {\n        public id: number;\n        public min: number;\n        public max: number;\n        public lowThreshold: number;\n        public highThreshold: number;\n        private transition: number;\n        private transitionMs: number;\n        private _level: number;\n        private _state: number;\n        public onHigh: () => void;\n        public onLow: () => void;\n        public onNeutral: () => void;\n        public transitionWindow: number;\n        // minimum duration (ms) between events\n        public transitionInterval: number;\n\n        static LEVEL_THRESHOLD_NEUTRAL = 0;\n\n        constructor(id: number,\n            min: number, max: number,\n            lowThreshold: number, highThreshold: number) {\n            this.id = id;\n            this.min = min;\n            this.max = max;\n            this.lowThreshold = lowThreshold;\n            this.highThreshold = highThreshold;\n            this.transitionWindow = 4;\n            this.transitionInterval = 0;\n\n            this.onHigh = () => control.raiseEvent(this.id, DAL.LEVEL_THRESHOLD_HIGH);\n            this.onLow = () => control.raiseEvent(this.id, DAL.LEVEL_THRESHOLD_LOW);\n            this.onNeutral = undefined;\n\n            this.reset();\n        }\n\n        reset() {\n            this.transition = 0;\n            this.transitionMs = 0;\n            this._level = Math.ceil((this.highThreshold - this.lowThreshold) / 2);\n            this._state = LevelDetector.LEVEL_THRESHOLD_NEUTRAL;\n        }\n\n        get level(): number {\n            return this._level;\n        }\n\n        set level(level: number) {\n            this._level = this.clampValue(level);\n\n            if (this._level >= this.highThreshold) {\n                this.setState(DAL.LEVEL_THRESHOLD_HIGH);\n            }\n            else if (this._level <= this.lowThreshold) {\n                this.setState(DAL.LEVEL_THRESHOLD_LOW);\n            }\n            else {\n                this.setState(LevelDetector.LEVEL_THRESHOLD_NEUTRAL);\n            }\n        }\n\n        public setLowThreshold(value: number) {\n            this.lowThreshold = this.clampValue(value);\n            this.reset();\n        }\n\n        public setHighThreshold(value: number) {\n            this.highThreshold = this.clampValue(value);\n            this.reset();\n        }\n\n        private clampValue(value: number) {\n            if (value < this.min) {\n                return this.min;\n            }\n            else if (value > this.max) {\n                return this.max;\n            }\n            return value;\n        }\n\n        private setState(state: number) {\n            // not enough samples to change\n            if (this._state === state \n                || (this.transition++ < this.transitionWindow)\n                || (control.millis() - this.transitionMs) < this.transitionInterval) {\n                return;\n            }\n\n            this.transition = 0;\n            this.transitionMs = control.millis();\n            this._state = state;\n            switch (state) {\n                case DAL.LEVEL_THRESHOLD_HIGH:\n                    if (this.onHigh) this.onHigh();\n                    break;\n                case DAL.LEVEL_THRESHOLD_LOW:\n                    if (this.onLow) this.onLow();\n                    break;\n                case LevelDetector.LEVEL_THRESHOLD_NEUTRAL:\n                    if (this.onNeutral) this.onNeutral();\n                    break;\n            }\n        }\n    }\n}","light.cpp":"#include \"light.h\"\n\n// WS2812B timings, datasheet v1\n// 0 - 0.25-0.55us hi 0.70-1.00us low\n// 1 - 0.65-0.95us hi 0.30-0.60us low\n// datasheet v5\n// 0 - 0.22-0.38us hi 0.58-1.00us low 1-3\n// 1 - 0.58-1.00us hi 0.58-1.00us low 3-2\n\n#define SPI_SUPPORTED 1\n\n#if defined(NRF52_SERIES)\n#define BIT_EXPANSION 5\n#define SPI_FREQ 4000000\n#else\n#define BIT_EXPANSION 3\n#define SPI_FREQ 2400000\n#endif\n\n#if defined(SAMD21) || defined(SAMD51) || defined(STM32F4) || defined(NRF52_SERIES)\n#include \"neopixel.h\"\n#define BITBANG_SUPPORTED 1\n#else\n#define BITBANG_SUPPORTED 0\n#endif\n\n#define NEOPIXEL_MIN_LENGTH_FOR_SPI 24\n#define DOTSTAR_MIN_LENGTH_FOR_SPI 24\n\n#define LIGHTMODE_RGB 1\n#define LIGHTMODE_RGBW 2\n#define LIGHTMODE_RGB_RGB 3\n#define LIGHTMODE_DOTSTAR 4\n\nnamespace light {\nbool isValidMOSIPin(DigitalInOutPin pin) {\n    if (!pin)\n        return false;\n\n#if SAMD51\n    return ZSPI::isValidMOSIPin(*pin);\n#elif defined(NRF52_SERIES)\n    return true;\n#else\n    // TODO: support for SPI neopixels\n    // default SPI pins supported for now\n    return pin == LOOKUP_PIN(MOSI);\n#endif\n}\n\n// SPI\nvoid spiNeopixelSendBuffer(DevicePin *pin, const uint8_t *data, unsigned size) {\n    int32_t iptr = 0, optr = 120;\n    uint32_t len = optr + size * BIT_EXPANSION + 120;\n    uint8_t *expBuf = new uint8_t[len];\n    memset(expBuf, 0, len);\n    uint8_t imask = 0x80;\n    uint8_t omask = 0x80;\n\n#define WR(k)                                                                                      \\\n    if (k)                                                                                         \\\n        expBuf[optr] |= omask;                                                                     \\\n    omask >>= 1;                                                                                   \\\n    if (!omask) {                                                                                  \\\n        omask = 0x80;                                                                              \\\n        optr++;                                                                                    \\\n    }\n\n    while (iptr < (int)size) {\n#if BIT_EXPANSION == 3\n        WR(1);\n        WR(data[iptr] & imask);\n        WR(0);\n#elif BIT_EXPANSION == 5\n        WR(1);\n        if (data[iptr] & imask) {\n            WR(1);\n            WR(1);\n        } else {\n            WR(0);\n        }\n        WR(0);\n        WR(0);\n#else\n#error \"invalid BIT_EXPANSION\"\n#endif\n\n        imask >>= 1;\n        if (!imask) {\n            imask = 0x80;\n            iptr++;\n        }\n    }\n\n    auto spi = pxt::getSPI(pin, NULL, NULL);\n    spi->setFrequency(SPI_FREQ);\n    spi->transfer(expBuf, len, NULL, 0);\n    delete expBuf;\n}\n\nvoid neopixelSendData(DevicePin *pin, int mode, const uint8_t *data, unsigned length) {\n    if (!pin || !length)\n        return;\n\n#if BITBANG_SUPPORTED\n    if (SPI_SUPPORTED && length > NEOPIXEL_MIN_LENGTH_FOR_SPI && isValidMOSIPin(pin))\n        spiNeopixelSendBuffer(pin, data, length);\n    else\n        neopixel_send_buffer(*pin, data, length);\n#else\n    if (isValidMOSIPin(pin)) {\n        spiNeopixelSendBuffer(pin, data, length);\n    }\n#endif\n}\n\nvoid bitBangDotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                            unsigned length) {\n    // first frame of zeroes\n    data->setDigitalValue(0);\n    for (unsigned i = 0; i < 32; ++i) {\n        clk->setDigitalValue(1);\n        clk->setDigitalValue(0);\n    }\n\n    // data stream\n    for (unsigned i = 0; i < length; ++i) {\n        auto x = buf[i];\n        for (uint8_t j = 0x80; j != 0; j >>= 1) {\n            data->setDigitalValue(x & j ? 1 : 0);\n            clk->setDigitalValue(1);\n            clk->setDigitalValue(0);\n        }\n    }\n    // https://cpldcpu.wordpress.com/2016/12/13/sk9822-a-clone-of-the-apa102/\n    // reset frame\n    // data->setDigitalValue(0);\n    // for (unsigned i = 0; i < 32 ; ++i) {\n    //    clk->setDigitalValue(1);\n    //    clk->setDigitalValue(0);\n    //}\n\n    // https://cpldcpu.wordpress.com/2014/11/30/understanding-the-apa102-superled/\n    data->setDigitalValue(1);\n    unsigned n = 32;\n    for (unsigned i = 0; i < n; ++i) {\n        clk->setDigitalValue(1);\n        clk->setDigitalValue(0);\n    }\n}\n\nstatic uint8_t ZERO_FRAME[4];\nstatic uint8_t ONE_FRAME[] = {1, 1, 1, 1};\nvoid spiDotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                        unsigned length) {\n    auto spi = pxt::getSPI(data, NULL, clk);\n\n    spi->transfer(ZERO_FRAME, sizeof(ZERO_FRAME), NULL, 0); // initial frame\n    spi->transfer(buf, length, NULL, 0);\n    spi->transfer(ZERO_FRAME, sizeof(ZERO_FRAME), NULL, 0); // reset frame\n    for (unsigned i = 0; i < (length >> 3); i += 32)\n        spi->transfer(ONE_FRAME, sizeof(ONE_FRAME), NULL, 0); // final frame\n}\n\nvoid dotStarSendData(DevicePin *data, DevicePin *clk, int mode, const uint8_t *buf,\n                     unsigned length) {\n    if (!data || !clk || !buf || !length)\n        return;\n\n    if (length > DOTSTAR_MIN_LENGTH_FOR_SPI && isValidMOSIPin(data))\n        spiDotStarSendData(data, clk, mode, buf, length);\n    else\n        bitBangDotStarSendData(data, clk, mode, buf, length);\n}\n\nvoid sendBuffer(DevicePin *data, DevicePin *clk, int mode, Buffer buf) {\n    if (!data || !buf || !buf->length)\n        return;\n\n    if (mode == LIGHTMODE_DOTSTAR)\n        light::dotStarSendData(data, clk, mode, buf->data, buf->length);\n    else\n        light::neopixelSendData(data, mode, buf->data, buf->length);\n}\n\nvoid clear() {\n    auto neopix = LOOKUP_PIN(NEOPIXEL);\n    auto neonum = getConfig(CFG_NUM_NEOPIXELS, 0);\n    if (neopix && neonum >= 0) {\n        auto n = 3 * neonum;\n        uint8_t off[n];\n        memset(off, 0, sizeof(off));\n        light::neopixelSendData(neopix, 0x100, off, sizeof(off));\n    }\n\n    auto data = LOOKUP_PIN(DOTSTAR_DATA);\n    auto clk = LOOKUP_PIN(DOTSTAR_CLOCK);\n    auto dsnum = getConfig(CFG_NUM_DOTSTARS, 0);\n    if (data && clk && dsnum > 0) {\n        auto n = 4 * dsnum;\n        uint8_t off[n];\n        memset(off, 0, sizeof(off));\n        for (int i = 0; i < n; i += 4)\n            off[i] = 0xe0;\n        bitBangDotStarSendData(data, clk, 0x100, off, sizeof(off));\n    }\n}\n\n} // namespace light\n","light.h":"#ifndef __PXT_LIGHT_H\n#define __PXT_LIGHT_H\n\n#include \"pxt.h\"\n\nnamespace light {\n    /**\n    * Clear onboard neopixels\n    */\n    void clear();\n\n    /**\n    * Send a programmable light buffer to the specified digital pin\n    * @param data The pin that the lights are connected to\n    * @param clk the clock line if any\n    * @param mode the color encoding mode\n    * @param buf The buffer to send to the pin\n    */\n    //%\n    void sendBuffer(DigitalInOutPin data, DigitalInOutPin clk, int mode, Buffer buf);\n\n    void neopixelSendData(DevicePin* pin, int mode, const uint8_t* data, unsigned length);\n}\n\n#endif","ns.ts":"/**\n * Events and data from sensors.\n */\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\n//% groups='[\"other\", \"More\"]'\nnamespace input {\n}\n\n/**\n * Servos\n */\n//% color=\"#03AA74\" weight=88 icon=\"\\uf021\"\nnamespace servos {\n\n}\n\n/**\n * A Joint Asynchronous Communications, Device Agnostic Control.\n */\n//% color=\"#E79251\" weight=1 icon=\"\\uf185\"\n//% groups='[\"Broadcast\", \"Console\", \"Control\"]'\n//% blockGap=8\nnamespace jacdac {\n\n}","pins.cpp":"#include \"pxt.h\"\n\nnamespace pxt {\nstatic DevicePin **pinPtrs;\nstatic uint8_t numPinPtrs;\nstatic uint8_t pinPos[DEV_NUM_PINS];\n\n//%\nDevicePin *getPin(int id) {\n\n    id &= CFG_PIN_NAME_MSK;\n\n    if (id >= DEV_NUM_PINS)\n        soft_panic(PANIC_NO_SUCH_PIN);\n\n    // we could use lookupComponent() here - it would be slightly slower\n\n    int ptr = pinPos[id];\n    if (ptr == 0) {\n        pinPtrs = (DevicePin **)realloc(pinPtrs, (numPinPtrs + 1) * sizeof(void *));\n        bool isAnalog = IS_ANALOG_PIN(id);\n        // GCTODO\n        pinPtrs[numPinPtrs++] =\n            new DevicePin(DEVICE_ID_IO_P0 + id, (PinName)id,\n                          isAnalog ? PIN_CAPABILITY_AD : PIN_CAPABILITY_DIGITAL);\n        ptr = numPinPtrs;\n        pinPos[id] = ptr;\n    }\n    return pinPtrs[ptr - 1];\n}\n\n//%\nDevicePin *getPinCfg(int key) {\n    int p = getConfig(key, -1);\n    if (p == -1)\n        DMESG(\"no pin cfg: %d\", key);\n    return getPin(p);\n}\n\nvoid linkPin(int from, int to) {\n    if (from < 0 || from >= DEV_NUM_PINS)\n        soft_panic(PANIC_NO_SUCH_PIN);\n    getPin(to);\n    pinPos[from] = pinPos[to];\n}\n\n//%\nDevicePin *lookupPin(int pinName) {\n    if (pinName < 0 || pinName == 0xff)\n        return NULL;\n    pinName &= CFG_PIN_NAME_MSK;\n    return getPin(pinName);\n}\n\n//%\nDevicePin *lookupPinCfg(int key) {\n    return lookupPin(getConfig(key));\n}\n\nCodalComponent *lookupComponent(int id) {\n    for (int i = 0; i < DEVICE_COMPONENT_COUNT; ++i) {\n        if (CodalComponent::components[i] && CodalComponent::components[i]->id == id)\n            return CodalComponent::components[i];\n    }\n    return NULL;\n}\n\n} // namespace pxt\n\nnamespace pins {\n/**\n* Get a pin by configuration id (DAL.CFG_PIN...)\n*/\n//%\nDigitalInOutPin pinByCfg(int key) {\n    return pxt::lookupPinCfg(key);\n}\n\n/**\n * Create a new zero-initialized buffer.\n * @param size number of bytes in the buffer\n */\n//%\nBuffer createBuffer(int size) {\n    return mkBuffer(NULL, size);\n}\n\n/**\n * Get the duration of the last pulse in microseconds. This function should be called from a\n * ``onPulsed`` handler.\n */\n//% help=pins/pulse-duration blockGap=8\n//% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n//% weight=19\nint pulseDuration() {\n    return pxt::lastEvent.timestamp;\n}\n} // namespace pins\n","pins.h":"#ifndef __PXT_PINS_H\n#define __PXT_PINS_H\n\n#define BUTTON_ACTIVE_HIGH_PULL_DOWN (ACTIVE_HIGH | 0x10)\n#define BUTTON_ACTIVE_HIGH_PULL_UP (ACTIVE_HIGH | 0x20)\n#define BUTTON_ACTIVE_HIGH_PULL_NONE (ACTIVE_HIGH | 0x30)\n#define BUTTON_ACTIVE_LOW_PULL_DOWN (ACTIVE_LOW | 0x10)\n#define BUTTON_ACTIVE_LOW_PULL_UP (ACTIVE_LOW | 0x20)\n#define BUTTON_ACTIVE_LOW_PULL_NONE (ACTIVE_LOW | 0x30)\n\n#define PIN(name) ((PinName)pxt::getConfig(CFG_PIN_##name, -1))\n#define LOOKUP_PIN(name) pxt::lookupPin(PIN(name))\n\n// these can be overridden in platform.h\n#ifndef CODAL_PIN\n#define CODAL_PIN CODAL_MBED::Pin\n#endif\n\n#ifndef CODAL_TIMER\n#define CODAL_TIMER CODAL_MBED::Timer\n#endif\n\n#ifndef CODAL_SPI\n#define CODAL_SPI CODAL_MBED::SPI\n#endif\n\n#ifndef CODAL_SERIAL\n#define CODAL_SERIAL CODAL_MBED::Serial\n#endif\n\n#ifndef IS_ANALOG_PIN\n#define IS_ANALOG_PIN(id) ((DEV_ANALOG_PINS >> (id)) & 1)\n#endif\n\ntypedef CODAL_PIN DevicePin;\n\ntypedef DevicePin *DigitalInOutPin;\ntypedef DevicePin *AnalogInOutPin;\ntypedef DevicePin *AnalogInPin;\ntypedef DevicePin *AnalogOutPin;\ntypedef DevicePin *PwmPin;\ntypedef DevicePin *PwmOnlyPin;\ntypedef Button *Button_;\n\nnamespace pxt {\nDevicePin *getPin(int id);\nDevicePin *getPinCfg(int key);\nDevicePin *lookupPin(int pinName);\nDevicePin *lookupPinCfg(int key);\nvoid linkPin(int from, int to);\nCodalComponent *lookupComponent(int id);\n}\n\n#define PINOP(op) name->op\n\n#endif\n","pins.ts":"//% noRefCounting fixedInstances\ninterface DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogInPin extends DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogOutPin extends DigitalInOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface AnalogInOutPin extends AnalogInPin, AnalogOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface PwmOnlyPin extends DigitalInOutPin, AnalogOutPin {\n    // methods filled from C++\n}\n\n//% noRefCounting fixedInstances\ninterface PwmPin extends PwmOnlyPin, AnalogInOutPin {\n}\n\n/**\n * Control currents in Pins for analog/digital signals, servos, i2c, ...\n */\n//% color=#A80000 weight=85 icon=\"\\uf140\" advanced=true\n//% groups='[\"other\", \"Servo\", \"i2c\"]'\nnamespace pins {\n}","pinsAnalog.cpp":"#include \"pxt.h\"\n\nnamespace AnalogInPinMethods {\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 weight=53\n//% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nint analogRead(AnalogInPin name) {\n    return PINOP(getAnalogValue());\n}\n}\n\nnamespace AnalogOutPinMethods {\nvoid analogWrite(AnalogOutPin name, int value) __attribute__ ((weak));\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 weight=52\n//% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\n//% value.min=0 value.max=1023\nvoid analogWrite(AnalogOutPin name, int value) {\n    PINOP(setAnalogValue(value));\n}\n}","pinsDigital.cpp":"#include \"pxt.h\"\n\nenum class PulseValue {\n    //% block=high\n    High = DEVICE_PIN_EVT_PULSE_HI,\n    //% block=low\n    Low = DEVICE_PIN_EVT_PULSE_LO\n};\n\nenum class PinEvent {\n    //% block=\"pulse high\"\n    PulseHigh = DEVICE_PIN_EVT_PULSE_HI,\n    //% block=\"pulse low\"\n    PulseLow = DEVICE_PIN_EVT_PULSE_LO,\n    //% block=\"rise\"\n    Rise = DEVICE_PIN_EVT_RISE,\n    //% block=\"fall\"\n    Fall = DEVICE_PIN_EVT_FALL,\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\nnamespace DigitalInOutPinMethods {\n/**\n * Read a pin or connector as either 0 or 1\n * @param name pin to read from\n */\n//% help=pins/digital-read weight=61\n//% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nbool digitalRead(DigitalInOutPin name) {\n    return PINOP(getDigitalValue()) != 0;\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\n    */\n//% help=pins/digital-write weight=60\n//% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid digitalWrite(DigitalInOutPin name, bool value) {\n    PINOP(setDigitalValue(value));\n}\n\n/**\n* Make this pin a digital input, and create events where the timestamp is the duration\n* that this pin was either ``high`` or ``low``.\n*/\n//% help=pins/on-pulsed weight=16 blockGap=8\n//% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\n//% deprecated=1 hidden=1\nvoid onPulsed(DigitalInOutPin pin, PulseValue pulse, Action body) {\n    pin->eventOn(DEVICE_PIN_EVENT_ON_PULSE);\n    registerWithDal(pin->id, (int)pulse, body);\n}\n\n/**\n* Register code to run when a pin event occurs. \n*/\n//% help=pins/on-event weight=20 blockGap=8\n//% blockId=pinsonevent block=\"on|pin %pin|%event\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\nvoid onEvent(DigitalInOutPin pin, PinEvent event, Action body) {\n    switch(event) {\n        case PinEvent::PulseHigh:\n        case PinEvent::PulseLow:\n            pin->eventOn(DEVICE_PIN_EVENT_ON_PULSE);\n            registerWithDal(pin->id, (int)event, body);\n            break;\n        case PinEvent::Rise:\n        case PinEvent::Fall:\n            pin->eventOn(DEVICE_PIN_EVENT_ON_EDGE);\n            registerWithDal(pin->id, (int)event, body);\n            break;    \n    }    \n}\n\n/**\n* Return 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 %high||timeout %maxDuration (µs)\"\n//% weight=18 blockGap=8\n//% help=\"pins/pulse-in\"\n//% blockNamespace=pins\n//% pin.fieldEditor=\"gridpicker\"\n//% pin.fieldOptions.width=220\n//% pin.fieldOptions.columns=4\nint pulseIn(DigitalInOutPin pin, PulseValue value, int maxDuration = 2000000) {\n    int pulse = PulseValue::High == value ? 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* Set the pull direction 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=17 blockGap=8\n//% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid setPull(DigitalInOutPin name, PinPullMode pull) {\n    PullMode m = pull == PinPullMode::PullDown ? PullMode::Down : pull == PinPullMode::PullUp\n                                                                        ? PullMode::Up\n                                                                        : PullMode::None;\n    PINOP(setPull(m));\n}\n\n}\n\n#ifdef PXT_CODAL\n\nnamespace pxt {\n\nstatic void waitABit() {\n    // for (int i = 0; i < 10; ++i)\n    //    asm volatile(\"nop\");\n}\n\nclass ButtonMultiplexer : public CodalComponent {\n  public:\n    Pin &latch;\n    Pin &clock;\n    Pin &data;\n    uint32_t state;\n    uint32_t invMask;\n    uint16_t buttonIdPerBit[8];\n    bool enabled;\n\n    ButtonMultiplexer(uint16_t id)\n        : latch(*LOOKUP_PIN(BTNMX_LATCH)), clock(*LOOKUP_PIN(BTNMX_CLOCK)),\n          data(*LOOKUP_PIN(BTNMX_DATA)) {\n        this->id = id;\n        this->status |= DEVICE_COMPONENT_STATUS_SYSTEM_TICK;\n\n        state = 0;\n        invMask = 0;\n        enabled = true;\n\n        memset(buttonIdPerBit, 0, sizeof(buttonIdPerBit));\n\n        data.getDigitalValue(PullMode::Down);\n        latch.setDigitalValue(1);\n        clock.setDigitalValue(1);\n    }\n\n    void disable() {\n        data.getDigitalValue(PullMode::None);\n        latch.getDigitalValue(PullMode::None);\n        clock.getDigitalValue(PullMode::None);\n        enabled = false;\n    }\n\n    bool isButtonPressed(int id) {\n        for (int i = 0; i < 8; ++i) {\n            if (buttonIdPerBit[i] == id)\n                return (state & (1 << i)) != 0;\n        }\n        return false;\n    }\n\n    uint32_t readBits(int bits) {\n        latch.setDigitalValue(0);\n        waitABit();\n        latch.setDigitalValue(1);\n        waitABit();\n\n        uint32_t state = 0;\n        for (int i = 0; i < bits; i++) {\n            state <<= 1;\n            if (data.getDigitalValue(PullMode::Down))\n                state |= 1;\n\n            clock.setDigitalValue(0);\n            waitABit();\n            clock.setDigitalValue(1);\n            waitABit();\n        }\n\n        return state;\n    }\n\n    virtual void periodicCallback() override {\n        if (!enabled)\n            return;\n\n        uint32_t newState = readBits(8);\n        newState ^= invMask;\n        if (newState == state)\n            return;\n\n        for (int i = 0; i < 8; ++i) {\n            uint32_t mask = 1 << i;\n            if (!buttonIdPerBit[i])\n                continue;\n            int ev = 0;\n            if (!(state & mask) && (newState & mask))\n                ev = PXT_INTERNAL_KEY_DOWN;\n            else if ((state & mask) && !(newState & mask))\n                ev = PXT_INTERNAL_KEY_UP;\n            if (ev) {\n                Event(ev, buttonIdPerBit[i]);\n                Event(ev, 0); // any key\n            }\n        }\n\n        state = newState;\n    }\n};\n\nstatic ButtonMultiplexer *btnMultiplexer;\nButtonMultiplexer *getMultiplexer() {\n    if (!btnMultiplexer)\n        btnMultiplexer = new ButtonMultiplexer(DEVICE_ID_FIRST_BUTTON);\n    return btnMultiplexer;\n}\n\nint registerMultiplexedButton(int pin, int buttonId) {\n    if (1050 <= pin && pin < 1058) {\n        pin -= 50;\n        getMultiplexer()->invMask |= 1 << (pin - 1000);\n    }\n    if (1000 <= pin && pin < 1008) {\n        getMultiplexer()->buttonIdPerBit[pin - 1000] = buttonId;\n        return 1;\n    }\n    return 0;\n}\n\nint multiplexedButtonIsPressed(int btnId) {\n    if (btnMultiplexer)\n        return btnMultiplexer->isButtonPressed(btnId) ? 512 : 0;\n    return 0;\n}\n\n//% expose\nuint32_t readButtonMultiplexer(int bits) {\n    if (!LOOKUP_PIN(BTNMX_CLOCK))\n        return 0;\n    return getMultiplexer()->readBits(bits);\n}\n\nvoid disableButtonMultiplexer() {\n    if (LOOKUP_PIN(BTNMX_CLOCK)) {\n        getMultiplexer()->disable();\n    }\n}\n\n}\n\n#endif\n","pinsPWM.cpp":"#include \"pxt.h\"\n\nnamespace PwmPinMethods {\n}\n\nnamespace PwmOnlyPinMethods {\n\n/**\n * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n * **microseconds** or `1/1000` milliseconds.\n * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n * 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=51\n//% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid analogSetPeriod(PwmOnlyPin name, int period) {\n    PINOP(setAnalogPeriodUs(period));\n}\n\n/**\n * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n * 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\n */\n//% help=pins/servo-write weight=41 group=\"Servo\"\n//% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n//% parts=microservo trackArgs=0\n//% blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\n//% value.defl=90\nvoid servoWrite(PwmOnlyPin name, int value) {\n    PINOP(setServoValue(value));\n}\n\n/**\n * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n * @param name pin name\n * @param duration pulse duration in micro seconds, eg:1500\n */\n//% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n//% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n//% parts=microservo blockNamespace=pins\n//% name.fieldEditor=\"gridpicker\"\n//% name.fieldOptions.width=220\n//% name.fieldOptions.columns=4\nvoid servoSetPulse(PwmOnlyPin name, int duration) {\n    PINOP(setServoPulseUs(duration));\n}\n\n/**\n* Indicates if the servo is running continuously\n*/\n//% blockHidden=1\nvoid servoSetContinuous(PwmOnlyPin name, bool continuous) {\n    // used by simulator\n}\n\n}","pinscompat.ts":"// filled in by microbit","platform.cpp":"#include \"pxt.h\"\n\n#include \"RP2040LowLevelTimer.h\"\n\n#include \"hardware/pll.h\"\n#include \"hardware/clocks.h\"\n#include \"hardware/structs/rosc.h\"\n\nnamespace pxt {\n\nLowLevelTimer *allocateTimer() {\n    // TODO: add config to low level timer\n    return new RP2040LowLevelTimer();\n}\n\nstatic uint32_t hw_random(void) {\n    uint8_t buf[16];\n    for (unsigned i = 0; i < sizeof(buf); ++i) {\n        buf[i] = 0;\n        for (int j = 0; j < 8; ++j) {\n            buf[i] <<= 1;\n            if (rosc_hw->randombit)\n                buf[i] |= 1;\n        }\n    }\n    return hash_fnv1(buf, sizeof(buf));\n}\n\nstatic void initRandomSeed() {\n    seedRandom(hw_random());\n}\n\nvoid deepSleep() {}\n\nvoid platform_init() {\n    initRandomSeed();\n}\n\nint *getBootloaderConfigData() {\n    static bool inited;\n    static int *cached;\n\n    if (!inited) {\n        inited = 1;\n        for (int i = 1; i <= 64; i *= 2) {\n            uint32_t *p = (uint32_t *)(XIP_BASE + i * 1024 * 1024 - 4096);\n            if (p[0] == CFG_MAGIC0 && p[1] == CFG_MAGIC1) {\n                cached = (int *)p;\n                break;\n            }\n        }\n    }\n\n    return cached;\n}\n\n} // namespace pxt\n\nvoid cpu_clock_init() {\n    // missing in Codal\n}\n","platform.h":"#ifndef __PXT_PLATFORM_H\n#define __PXT_PLATFORM_H\n\n#include \"Image.h\"\n#include \"Timer.h\"\n\n#include \"RP2040.h\"\n#include \"RP2040Pin.h\"\n#include \"RP2040Spi.h\"\n#include \"RP2040I2C.h\"\n#include \"RP2040PWM.h\"\n\n#define IMAGE_BITS 4\n\n#define PAGE_SIZE 256\n#define DEV_NUM_PINS 30\n\n// all pins with pwm output\n#define DEV_PWM_PINS 0x3FFFFFFF\n// 26~29 has adc input\n#define DEV_AIN_PINS 0x3C000000\n\n// Codal doesn't yet distinguish between PWM and AIN\n#define DEV_ANALOG_PINS (DEV_PWM_PINS | DEV_AIN_PINS)\n\n#define CODAL_PIN RP2040Pin\n#define CODAL_SPI RP2040SPI\n#define CODAL_I2C RP2040I2C\n#define CODAL_TIMER Timer\n\n#define UF2_INFO_TXT \"UF2 Bootloader v1.0\\nModel: Raspberry Pi RP2\\nBoard-ID: RPI-RP2\"\n\ntypedef uint8_t PinName;\n\n// XIP range in 0x1000_0000 ~ 0x1100_0000\n#define PXT_IS_READONLY(v) (isTagged(v) || ((uintptr_t)v & 0x10000000))\n\n#define P0 0\n#define P1 1\n#define P2 2\n#define P3 3\n#define P4 4\n#define P5 5\n#define P6 6\n#define P7 7\n#define P8 8\n#define P9 9\n#define P10 10\n#define P11 11\n#define P12 12\n#define P13 13\n#define P14 14\n#define P15 15\n#define P16 16\n#define P17 17\n#define P18 18\n#define P19 19\n#define P20 20\n#define P21 21\n#define P22 22\n#define P23 23\n#define P24 24\n#define P25 25\n#define P26 26\n#define P27 27\n#define P28 28\n#define P29 29\n#define P30 30\n\n#endif","pxt.h":"#ifndef __PXT_H\n#define __PXT_H\n\n#include \"pxtbase.h\"\n\n#include \"CodalConfig.h\"\n#include \"CodalHeapAllocator.h\"\n#include \"CodalDevice.h\"\n#include \"CodalDmesg.h\"\n#include \"ErrorNo.h\"\n#include \"Timer.h\"\n#include \"Matrix4.h\"\n#include \"CodalCompat.h\"\n#include \"CodalComponent.h\"\n#include \"ManagedType.h\"\n#include \"Event.h\"\n#include \"NotifyEvents.h\"\n#include \"Button.h\"\n#include \"CodalFiber.h\"\n#include \"MessageBus.h\"\n#include \"MultiButton.h\"\n\nusing namespace codal;\n\n// codal::ManagedString compat\n#define MSTR(s) codal::ManagedString((s)->data, (s)->length)\n#define PSTR(s) mkString((s).toCharArray(), (s).length())\n\n#include \"pins.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"hf2.h\"\n#include \"hf2dbg.h\"\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n#include \"HIDMouse.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n#include \"HIDKeyboard.h\"\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n#include \"HIDJoystick.h\"\n#endif\n#endif\n\n#define PXT_COMM_BASE 0x20002000 // 8k in\n\n// old codal compat\n#ifndef REAL_TIME_FUNC\n#define REAL_TIME_FUNC /* */\n#endif\n\nnamespace pxt {\n\n#if CONFIG_ENABLED(DEVICE_USB)\nextern CodalUSB usb;\nextern HF2 hf2;\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nextern USBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nextern USBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nextern USBHIDJoystick joystick;\n#endif\n#endif\n\n// Utility functions\nextern Event lastEvent;\nextern CODAL_TIMER devTimer;\nextern MessageBus devMessageBus;\nextern codal::CodalDevice device;\n\nvoid set_usb_strings(const char *uf2_info);\nextern void (*logJDFrame)(const uint8_t *data);\nextern void (*sendJDFrame)(const uint8_t *data);\n\nstatic inline void raiseEvent(int src, int val) {\n    Event(src, val);\n}\n\n} // namespace pxt\n\nnamespace pins {\nclass CodalSPIProxy;\nclass CodalI2CProxy;\n} // namespace pins\n\ntypedef pins::CodalI2CProxy* I2C_;\ntypedef pins::CodalSPIProxy* SPI_;\n\nnamespace pxt {\ncodal::LowLevelTimer *allocateTimer();\n\n#ifdef CODAL_I2C\nCODAL_I2C* getI2C(DigitalInOutPin sda, DigitalInOutPin scl);\n#endif\nCODAL_SPI* getSPI(DigitalInOutPin mosi, DigitalInOutPin miso, DigitalInOutPin sck);\n#ifdef CODAL_JACDAC_WIRE_SERIAL\nLowLevelTimer* getJACDACTimer();\n#endif\nclass PressureButton;\nuint32_t readButtonMultiplexer(int bits);\nvoid disableButtonMultiplexer();\n}\n\nnamespace serial {\nclass CodalSerialDeviceProxy;\n}\n\ntypedef serial::CodalSerialDeviceProxy* SerialDevice;\n\nnamespace jacdac {\nclass JDProxyDriver;\n} // namespace network\n\ntypedef jacdac::JDProxyDriver* JacDacDriverStatus;\n\n#define DEVICE_ID_BUTTON_SLIDE 3000\n#define DEVICE_ID_MICROPHONE 3001\n#define DEVICE_ID_FIRST_BUTTON 4000\n#define DEVICE_ID_FIRST_TOUCHBUTTON 4100\n\n#define PXT_INTERNAL_KEY_UP 2050\n#define PXT_INTERNAL_KEY_DOWN 2051\n\n#endif\n","pxt.json":"{\n    \"name\": \"core---rp2040\",\n    \"description\": \"The core library for Codal-based targets\",\n    \"dependencies\": {\n        \"base\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"dal.d.ts\",\n        \"codal.cpp\",\n        \"usb.cpp\",\n        \"pxt.h\",\n        \"platform.h\",\n        \"platform.cpp\",\n        \"pxtcore.h\",\n        \"pins.h\",\n        \"pins.cpp\",\n        \"pinsAnalog.cpp\",\n        \"pinsDigital.cpp\",\n        \"pinsPWM.cpp\",\n        \"pins.ts\",\n        \"pinscompat.ts\",\n        \"control.cpp\",\n        \"i2c.cpp\",\n        \"i2c.ts\",\n        \"spi.cpp\",\n        \"spi.ts\",\n        \"shims.d.ts\",\n        \"enums.d.ts\",\n        \"hf2.cpp\",\n        \"hf2.h\",\n        \"hf2dbg.h\",\n        \"uf2format.h\",\n        \"uf2hid.h\",\n        \"ns.ts\",\n        \"dmac.cpp\",\n        \"dmac.h\",\n        \"timer.ts\",\n        \"light.cpp\",\n        \"light.h\",\n        \"keyvaluestorage.cpp\",\n        \"keyvaluestorage.ts\",\n        \"leveldetector.ts\",\n        \"pxtparts.json\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"yotta\": {\n        \"config\": {\n            \"codal\": {\n                \"component_count\": 64,\n                \"dmesg_buffer_size\": 1024\n            }\n        }\n    },\n    \"dalDTS\": {\n        \"includeDirs\": [\n            \"libraries/codal-core/inc\",\n            \"pxtapp\"\n        ],\n        \"excludePrefix\": [\n            \"JD_\",\n            \"USB_\",\n            \"REQUEST_\",\n            \"LIS3DH_\",\n            \"FXOS8700_\",\n            \"HF2_\",\n            \"PXT_REF_TAG_\",\n            \"MS_\",\n            \"SCSI_\",\n            \"MAG_\",\n            \"MAG3\",\n            \"MPU6\",\n            \"MADCTL\",\n            \"MMA8\"\n        ]\n    }\n}\n","pxtcore.h":"#ifndef __PXTCORE_H\n#define __PXTCORE_H\n\n#include \"CodalDmesg.h\"\n#include \"CodalHeapAllocator.h\"\n\n#define PXT_CODAL 1\n\n#define itoa(a, b) codal::itoa(a, b)\n\n#define GC_GET_HEAP_SIZE() device_heap_size(0)\n#define GC_STACK_BASE DEVICE_STACK_BASE\n#define xmalloc device_malloc\n#define xfree device_free\n\n// on most devices we allocate the entire heap at once, so large allocs should work\n// if they don't you just get the regular out of memory instead of alloc too large\n#define GC_MAX_ALLOC_SIZE (128 * 1024)\n\n#endif\n","pxtparts.json":"{\n    \"neopixel\": {\n        \"simulationBehavior\": \"neopixel\",\n        \"visual\": {\n            \"builtIn\": \"neopixel\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 19,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 28,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createStrip,light.createNeoPixelStrip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"dotstar\": {\n        \"simulationBehavior\": \"dotstar\",\n        \"visual\": {\n            \"builtIn\": \"dotstar\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 1\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createAPA102Strip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"dataPin\"\n                },\n                {\n                    \"pinInstantiationIdx\": 1,\n                    \"partParameter\": \"clkPin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },\n    \"pixels\": {\n        \"simulationBehavior\": \"pixels\",\n        \"visual\": { \n            \"builtIn\": \"pixels\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"MOSI\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"SCK\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },    \n    \"buttons\": {\n        \"simulationBehavior\": \"buttons\",\n        \"visual\": {\n            \"builtIn\": \"buttons\",\n            \"width\": 75,\n            \"height\": 45,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 30,\n                    \"y\": 45\n                }\n            ]\n        },\n        \"numberOfPins\": 2,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"Button.onEvent,Button.isPressed,Button.wasPressed\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"button\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"slideswitch\": {\n        \"numberOfPins\": 3,\n        \"simulationBehavior\": \"slideswitch\",\n        \"visual\": {\n            \"builtIn\": \"slideswitch\",\n            \"width\": 100,\n            \"height\": 100,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalRead,DigitalInOutPin.onPulsed,DigitalInOutPin.onEvent\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"microservo\": {\n        \"simulationBehavior\": \"microservo\",\n        \"visual\": {\n            \"builtIn\": \"microservo\",\n            \"width\": 74.85,\n            \"height\": 200,\n            \"pinDistance\": 10,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 37,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 5\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"PwmOnlyPin.servoWrite,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"led\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"analogled\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogOutPin.analogWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"photocell\": {\n        \"numberOfPins\": 3,\n        \"visual\": {\n            \"builtIn\": \"photocell\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 15,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"photocell\",\n        \"pinDefinitions\": [\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogInPin.analogRead\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace light {\n\n    /**\n     * Send a programmable light buffer to the specified digital pin\n     * @param data The pin that the lights are connected to\n     * @param clk the clock line if any\n     * @param mode the color encoding mode\n     * @param buf The buffer to send to the pin\n     */\n    //% shim=light::sendBuffer\n    function sendBuffer(data: DigitalInOutPin, clk: DigitalInOutPin, mode: int32, buf: Buffer): void;\n}\ndeclare namespace control {\n\n    /**\n     * Determines if the USB has been enumerated.\n     */\n    //% shim=control::isUSBInitialized\n    function isUSBInitialized(): boolean;\n}\ndeclare namespace pins {\n\n    /**\n     * Get a pin by configuration id (DAL.CFG_PIN...)\n     */\n    //% shim=pins::pinByCfg\n    function pinByCfg(key: int32): DigitalInOutPin;\n\n    /**\n     * Create a new zero-initialized buffer.\n     * @param size number of bytes in the buffer\n     */\n    //% shim=pins::createBuffer\n    function createBuffer(size: int32): Buffer;\n\n    /**\n     * Get the duration of the last pulse in microseconds. This function should be called from a\n     * ``onPulsed`` handler.\n     */\n    //% help=pins/pulse-duration blockGap=8\n    //% blockId=pins_pulse_duration block=\"pulse duration (µs)\"\n    //% weight=19 shim=pins::pulseDuration\n    function pulseDuration(): int32;\n}\n\n\ndeclare interface AnalogInPin {\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 weight=53\n    //% blockId=device_get_analog_pin block=\"analog read|pin %name\" blockGap=\"8\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=AnalogInPinMethods::analogRead\n    analogRead(): int32;\n}\n\n\ndeclare interface AnalogOutPin {\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 weight=52\n    //% blockId=device_set_analog_pin block=\"analog write|pin %name|to %value\" blockGap=8\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4\n    //% value.min=0 value.max=1023 shim=AnalogOutPinMethods::analogWrite\n    analogWrite(value: int32): void;\n}\n\n\ndeclare interface DigitalInOutPin {\n    /**\n     * Read a pin or connector as either 0 or 1\n     * @param name pin to read from\n     */\n    //% help=pins/digital-read weight=61\n    //% blockId=device_get_digital_pin block=\"digital read|pin %name\" blockGap=8\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::digitalRead\n    digitalRead(): boolean;\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\n     */\n    //% help=pins/digital-write weight=60\n    //% blockId=device_set_digital_pin block=\"digital write|pin %name|to %value=toggleHighLow\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::digitalWrite\n    digitalWrite(value: boolean): void;\n\n    /**\n     * Make this pin a digital input, and create events where the timestamp is the duration\n     * that this pin was either ``high`` or ``low``.\n     */\n    //% help=pins/on-pulsed weight=16 blockGap=8\n    //% blockId=pins_on_pulsed block=\"on|pin %pin|pulsed %pulse\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4\n    //% deprecated=1 hidden=1 shim=DigitalInOutPinMethods::onPulsed\n    onPulsed(pulse: PulseValue, body: () => void): void;\n\n    /**\n     * Register code to run when a pin event occurs. \n     */\n    //% help=pins/on-event weight=20 blockGap=8\n    //% blockId=pinsonevent block=\"on|pin %pin|%event\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4 shim=DigitalInOutPinMethods::onEvent\n    onEvent(event: PinEvent, body: () => void): void;\n\n    /**\n     * Return 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 %high||timeout %maxDuration (µs)\"\n    //% weight=18 blockGap=8\n    //% help=\"pins/pulse-in\"\n    //% blockNamespace=pins\n    //% pin.fieldEditor=\"gridpicker\"\n    //% pin.fieldOptions.width=220\n    //% pin.fieldOptions.columns=4 maxDuration.defl=2000000 shim=DigitalInOutPinMethods::pulseIn\n    pulseIn(value: PulseValue, maxDuration?: int32): int32;\n\n    /**\n     * Set the pull direction 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=17 blockGap=8\n    //% blockId=device_set_pull block=\"set pull|pin %pin|to %pull\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=DigitalInOutPinMethods::setPull\n    setPull(pull: PinPullMode): void;\n}\n\n\ndeclare interface PwmPin {}\n\n\ndeclare interface PwmOnlyPin {\n    /**\n     * Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n     * **microseconds** or `1/1000` milliseconds.\n     * If this pin is not configured as an analog output (using `analog write pin`), the operation has\n     * 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=51\n    //% blockId=device_set_analog_period block=\"analog set period|pin %pin|to (µs)%period\"\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::analogSetPeriod\n    analogSetPeriod(period: int32): void;\n\n    /**\n     * Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\n     * set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\n     * rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\n     * 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\n     */\n    //% help=pins/servo-write weight=41 group=\"Servo\"\n    //% blockId=device_set_servo_pin block=\"servo write|pin %name|to %value=protractorPicker\" blockGap=8\n    //% parts=microservo trackArgs=0\n    //% blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4\n    //% value.defl=90 shim=PwmOnlyPinMethods::servoWrite\n    servoWrite(value?: int32): void;\n\n    /**\n     * Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\n     * The pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.\n     * @param name pin name\n     * @param duration pulse duration in micro seconds, eg:1500\n     */\n    //% help=pins/servo-set-pulse weight=40 group=\"Servo\" blockGap=8\n    //% blockId=device_set_servo_pulse block=\"servo set pulse|pin %value|to (µs) %duration\"\n    //% parts=microservo blockNamespace=pins\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=220\n    //% name.fieldOptions.columns=4 shim=PwmOnlyPinMethods::servoSetPulse\n    servoSetPulse(duration: int32): void;\n\n    /**\n     * Indicates if the servo is running continuously\n     */\n    //% blockHidden=1 shim=PwmOnlyPinMethods::servoSetContinuous\n    servoSetContinuous(continuous: boolean): void;\n}\ndeclare namespace control {\n\n    /**\n     * Announce that an event happened to registered handlers.\n     * @param src ID of the MicroBit Component that generated the event\n     * @param value Component specific code indicating the cause of the event.\n     */\n    //% weight=21 blockGap=12 blockId=\"control_raise_event\"\n    //% help=control/raise-event\n    //% block=\"raise event|from %src|with value %value\" blockExternalInputs=1 shim=control::raiseEvent\n    function raiseEvent(src: int32, value: int32): void;\n\n    /**\n     * Determine the version of system software currently running.\n     */\n    //% blockId=\"control_device_dal_version\" block=\"device dal version\"\n    //% help=control/device-dal-version shim=control::deviceDalVersion\n    function deviceDalVersion(): string;\n\n    /**\n     * Allocates the next user notification event\n     */\n    //% help=control/allocate-notify-event shim=control::allocateNotifyEvent\n    function allocateNotifyEvent(): int32;\n\n    /** Write a message to DMESG debugging buffer. */\n    //% shim=control::dmesg\n    function dmesg(s: string): void;\n\n    /** Write a message and value (pointer) to DMESG debugging buffer. */\n    //% shim=control::dmesgPtr\n    function dmesgPtr(str: string, ptr: Object): void;\n}\n\n\ndeclare interface I2C {\n    /**\n     * Read `size` bytes from a 7-bit I2C `address`.\n     */\n    //% repeat.defl=0 shim=I2CMethods::readBuffer\n    readBuffer(address: int32, size: int32, repeat?: boolean): Buffer;\n\n    /**\n     * Write bytes to a 7-bit I2C `address`.\n     */\n    //% repeat.defl=0 shim=I2CMethods::writeBuffer\n    writeBuffer(address: int32, buf: Buffer, repeat?: boolean): int32;\n}\ndeclare namespace pins {\n\n    /**\n     * Opens a Serial communication driver\n     */\n    //% help=pins/create-i2c\n    //% parts=i2c shim=pins::createI2C\n    function createI2C(sda: DigitalInOutPin, scl: DigitalInOutPin): I2C;\n}\ndeclare namespace pins {\n\n    /**\n     * Opens a SPI driver\n     */\n    //% help=pins/create-spi\n    //% parts=spi shim=pins::createSPI\n    function createSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin): SPI;\n\n    /**\n     * Opens a slave SPI driver\n     */\n    //% parts=spi shim=pins::createSlaveSPI\n    function createSlaveSPI(mosiPin: DigitalInOutPin, misoPin: DigitalInOutPin, sckPin: DigitalInOutPin, csPin: DigitalInOutPin): SPI;\n}\n\n\ndeclare interface SPI {\n    /**\n     * Write to the SPI bus\n     */\n    //% shim=SPIMethods::write\n    write(value: int32): int32;\n\n    /**\n     * Transfer buffers over the SPI bus\n     */\n    //% argsNullable shim=SPIMethods::transfer\n    transfer(command: Buffer, response: Buffer): void;\n\n    /**\n     * Sets the SPI clock frequency\n     */\n    //% shim=SPIMethods::setFrequency\n    setFrequency(frequency: int32): void;\n\n    /**\n     * Sets the SPI bus mode\n     */\n    //% shim=SPIMethods::setMode\n    setMode(mode: int32): void;\n}\ndeclare namespace configStorage {\n\n    /**\n     * Puts an entry in the device storage. Key may have up to 16 characters (bytes).\n     * @param key the identifier (max 16 characters)\n     * @param value the data (max 32 characters)\n     */\n    //% shim=configStorage::setBuffer\n    function setBuffer(key: string, value: Buffer): void;\n\n    /**\n     * Gets an entry from the device storage. Key may have up to 16 characters (bytes).\n     * @param key the identifier (max 16 characters)\n     */\n    //% shim=configStorage::getBuffer\n    function getBuffer(key: string): Buffer;\n\n    /**\n     * Removes the key from local storage\n     * @param key the identifier (max 16 characters)\n     */\n    //% shim=configStorage::removeItem\n    function removeItem(key: string): void;\n\n    /**\n     * Clears the local storage\n     */\n    //% shim=configStorage::clear\n    function clear(): void;\n}\n\n// Auto-generated. Do not edit. Really.\n","spi.cpp":"#include \"pxt.h\"\n#include \"ErrorNo.h\"\n\nnamespace pins {\n\nclass CodalSPIProxy {\nprivate:\n    DevicePin* mosi; \n    DevicePin* miso; \n    DevicePin* sck;\n    CODAL_SPI spi;\npublic:\n    CodalSPIProxy* next;\n\npublic:\n    CodalSPIProxy(DevicePin* _mosi, DevicePin* _miso, DevicePin* _sck)\n        : mosi(_mosi)\n        , miso(_miso)\n        , sck(_sck)\n        , spi(*_mosi, *_miso, *_sck) \n        , next(NULL)\n    {\n    }\n\n#ifdef CODAL_SPI_SLAVE_SUPPORTED\n    CodalSPIProxy(DevicePin* _mosi, DevicePin* _miso, DevicePin* _sck, DevicePin* _cs)\n        : mosi(_mosi)\n        , miso(_miso)\n        , sck(_sck)\n        , spi(*_mosi, *_miso, *_sck, _cs) \n        , next(NULL)\n    {\n    }\n#endif\n\n    CODAL_SPI* getSPI() {\n        return &spi;\n    }\n\n    bool matchPins(DevicePin* mosi, DevicePin* miso, DevicePin* sck) {\n        return this->mosi == mosi && this->miso == miso && this->sck == sck;\n    }\n\n    int write(int value) {\n        return spi.write(value);\n    }\n\n    void transfer(Buffer command, Buffer response) {\n        auto cdata = NULL == command ? NULL : command->data;\n        auto clength = NULL == command ? 0 : command->length;\n        auto rdata = NULL == response ? NULL : response->data;\n        auto rlength = NULL == response ? 0 : response->length;\n        spi.transfer(cdata, clength, rdata, rlength);\n    }\n\n    void setFrequency(int frequency) {\n        spi.setFrequency(frequency);\n    }\n\n    void setMode(int mode) {\n        spi.setMode(mode);\n    }\n};\n\nSPI_ spis(NULL);\n\n/**\n* Opens a SPI driver\n*/\n//% help=pins/create-spi\n//% parts=spi\nSPI_ createSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin) {\n  auto dev = spis;\n  while(dev) {\n    if (dev->matchPins(mosiPin, misoPin, sckPin))\n      return dev;\n    dev = dev->next;\n  }\n\n  auto ser = new CodalSPIProxy(mosiPin, misoPin, sckPin);\n  ser->next = spis;\n  spis = ser;\n  return ser;\n}\n\n/**\n* Opens a slave SPI driver\n*/\n//% parts=spi\nSPI_ createSlaveSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin, DigitalInOutPin csPin) {\n#ifdef CODAL_SPI_SLAVE_SUPPORTED\n  auto dev = spis;\n  if (!csPin)\n    soft_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n  while(dev) {\n    if (dev->matchPins(mosiPin, misoPin, sckPin))\n      return dev;\n    dev = dev->next;\n  }\n\n  auto ser = new CodalSPIProxy(mosiPin, misoPin, sckPin, csPin);\n  ser->next = spis;\n  spis = ser;\n  return ser;\n#else\n  soft_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n  return NULL;\n#endif\n}\n\n}\n\nnamespace pxt {\n\nCODAL_SPI* getSPI(DigitalInOutPin mosiPin, DigitalInOutPin misoPin, DigitalInOutPin sckPin) {\n    auto spi = pins::createSPI(mosiPin, misoPin, sckPin);\n    return spi->getSPI();\n}\n\n}\n\nnamespace SPIMethods {\n\n/**\n* Write to the SPI bus\n*/\n//%\nint write(SPI_ device, int value) {\n    return device->write(value);\n}\n\n/**\n* Transfer buffers over the SPI bus\n*/\n//% argsNullable\nvoid transfer(SPI_ device, Buffer command, Buffer response) {\n    if (!device)\n        soft_panic(PANIC_CAST_FROM_NULL);\n    if (!command && !response)\n        return;\n    device->transfer(command, response);\n}\n\n/**\n* Sets the SPI clock frequency\n*/\n//%\nvoid setFrequency(SPI_ device, int frequency) {\n    device->setFrequency(frequency);\n}\n\n/**\n* Sets the SPI bus mode\n*/\n//%\nvoid setMode(SPI_ device, int mode) {\n    device->setMode(mode);\n}\n\n}\n","spi.ts":"namespace pins {\n\n    let _spi: SPI;\n    /**\n    * Gets the default SPI driver\n    */\n    //%\n    export function spi() {\n        if (!_spi) {\n            const mosi = pins.pinByCfg(DAL.CFG_PIN_MOSI);\n            const miso = pins.pinByCfg(DAL.CFG_PIN_MISO);\n            const sck = pins.pinByCfg(DAL.CFG_PIN_SCK);\n            _spi = pins.createSPI(mosi, miso, sck);\n        }\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 advanced=true\n    //% blockId=spi_write block=\"spi write %value\"\n    export function spiWrite(value: number) {\n        return spi().write(value);\n    }\n\n    /**\n     * Write a given command to SPI bus, and at the same time read the response.\n     */\n    //% help=pins/spi-transfer weight=4 advanced=true\n    //% blockId=spi_transfer block=\"spi transfer %command into %response\"\n    export function spiTransfer(command: Buffer, response: Buffer) {\n        spi().transfer(command, response);\n    }\n\n    /**\n     * Set the SPI frequency\n     * @param frequency the clock frequency, eg: 1000000\n     */\n    //% help=pins/spi-frequency weight=4 advanced=true\n    //% blockId=spi_frequency block=\"spi frequency %frequency\"\n    export function spiFrequency(frequency: number) {\n        spi().setFrequency(frequency);\n    }\n\n    /**\n     * Set the SPI signal mode\n     * @param mode the mode, eg: 3\n     */\n    //% help=pins/spi-mode weight=3 advanced=true\n    //% blockId=spi_mode block=\"spi mode %mode\"\n    export function spiMode(mode: number) {\n        spi().setMode(mode);\n    }\n}","test.ts":"let i = 1\nlet f = 0.5\nlet plus = i + f\nlet minus = i - f\n\nlet r = Math.random()\nlet ri = Math.randomRange(5, 10)\n\n","timer.ts":"namespace control {\n    /**\n     * A timer\n     */\n    //% fixedInstances\n    export class Timer {\n        start: number;\n\n        constructor() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Gets the elapsed time in millis since the last reset\n         */\n        //% blockId=timerMillis block=\"%timer|millis\"\n        millis(): number {\n            return control.millis() - this.start;\n        }\n\n        /**\n         * Gets the elapsed time in seconds since the last reset\n         */\n        //% blockId=timerSeconds block=\"%timer|seconds\"\n        seconds(): number {\n            return this.millis() / 1000;\n        }\n\n        /**\n         * Resets the timer\n         */\n        //% blockId=timerRest block=\"%timer|reset\"\n        reset() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Pauses until the timer reaches the given amount of milliseconds\n         * @param ms how long to pause for, eg: 5, 100, 200, 500, 1000, 2000\n         */\n        //% blockId=timerPauseUntil block=\"%timer|pause until (ms) %ms\"\n        pauseUntil(ms: number) {\n            const remaining = this.millis() - ms;\n            pause(Math.max(0, remaining));\n        }\n    }\n\n    //% whenUsed fixedInstance block=\"timer 1\"\n    export const timer1 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 2\"\n    export const timer2 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 3\"\n    export const timer3 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 4\"\n    export const timer4 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 5\"\n    export const timer5 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 6\"\n    export const timer6 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 7\"\n    export const timer7 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 8\"\n    export const timer8 = new Timer();\n}","uf2format.h":"#ifndef UF2FORMAT_H\n#define UF2FORMAT_H 1\n\n#include <stdint.h>\n#include <stdbool.h>\n\n// All entries are little endian.\n\n#ifndef BOOTLOADER_START\n#define BOOTLOADER_START 0x0\n#endif\n\n#ifndef BOOTLOADER_END\n#define BOOTLOADER_END 0x2000\n#endif\n\n#ifndef UF2_BINFO\n#define UF2_BINFO ((UF2_BInfo *)(BOOTLOADER_END - sizeof(UF2_BInfo)))\n#endif\n\n#ifndef UF2_INFO_TXT\n#define UF2_INFO_TXT UF2_BINFO->info_uf2\n#endif\n\n\n#define UF2_MAGIC_START0 0x0A324655UL // \"UF2\\n\"\n#define UF2_MAGIC_START1 0x9E5D5157UL // Randomly selected\n#define UF2_MAGIC_END 0x0AB16F30UL    // Ditto\n\n// If set, the block is \"comment\" and should not be flashed to the device\n#define UF2_FLAG_NOFLASH 0x00000001\n\ntypedef struct {\n    // 32 byte header\n    uint32_t magicStart0;\n    uint32_t magicStart1;\n    uint32_t flags;\n    uint32_t targetAddr;\n    uint32_t payloadSize;\n    uint32_t blockNo;\n    uint32_t numBlocks;\n    uint32_t reserved;\n\n    // raw data;\n    uint8_t data[476];\n\n    // store magic also at the end to limit damage from partial block reads\n    uint32_t magicEnd;\n} UF2_Block;\n\ntypedef struct {\n    uint8_t version;\n    uint8_t ep_in;\n    uint8_t ep_out;\n    uint8_t reserved0;\n    uint32_t cbw_tag;\n    uint32_t blocks_remaining;\n    uint8_t *buffer;\n} UF2_HandoverArgs;\n\ntypedef void (*UF2_MSC_Handover_Handler)(UF2_HandoverArgs *handover);\ntypedef void (*UF2_HID_Handover_Handler)(int ep);\n\n// this is required to be exactly 16 bytes long by the linker script\ntypedef struct {\n    void *reserved0;\n    UF2_HID_Handover_Handler handoverHID;\n    UF2_MSC_Handover_Handler handoverMSC;\n    const char *info_uf2;\n} UF2_BInfo;\n\nstatic inline bool is_uf2_block(void *data) {\n    UF2_Block *bl = (UF2_Block *)data;\n    return bl->magicStart0 == UF2_MAGIC_START0 && bl->magicStart1 == UF2_MAGIC_START1 &&\n           bl->magicEnd == UF2_MAGIC_END;\n}\n\nstatic inline bool in_uf2_bootloader_space(const void *addr) {\n    return (BOOTLOADER_START + 0x100) <= (uint32_t)addr && (uint32_t)addr < (BOOTLOADER_END);\n}\n\nstatic inline const char *uf2_info(void) {\n    if (in_uf2_bootloader_space(UF2_INFO_TXT))\n        return UF2_INFO_TXT;\n    return \"N/A\";\n}\n\n#ifdef UF2_DEFINE_HANDOVER\nstatic inline void hf2_handover(uint8_t ep) {\n    const char *board_info = UF2_BINFO->info_uf2;\n    UF2_HID_Handover_Handler fn = UF2_BINFO->handoverHID;\n\n    if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&\n        ((uint32_t)fn & 1)) {\n        // Pass control to bootloader; never returns\n        fn(ep & 0xf);\n    }\n}\n\nstatic inline void check_uf2_handover(uint8_t *buffer, uint32_t blocks_remaining, uint8_t ep_in,\n                                      uint8_t ep_out, uint32_t cbw_tag) {\n    if (!is_uf2_block(buffer))\n        return;\n\n    const char *board_info = UF2_BINFO->info_uf2;\n    UF2_MSC_Handover_Handler fn = UF2_BINFO->handoverMSC;\n\n    if (in_uf2_bootloader_space(board_info) && in_uf2_bootloader_space((const void *)fn) &&\n        ((uint32_t)fn & 1)) {\n        UF2_HandoverArgs hand = {\n            1, ep_in, ep_out, 0, cbw_tag, blocks_remaining, buffer,\n        };\n        // Pass control to bootloader; never returns\n        fn(&hand);\n    }\n}\n#endif\n\n#endif\n","uf2hid.h":"#ifndef UF2_HID_H\n#define UF2_HID_H 1\n\n#define HF2_CMD_BININFO 0x0001\n// no arguments\n#define HF2_MODE_BOOTLOADER 0x01\n#define HF2_MODE_USERSPACE 0x02\nstruct HF2_BININFO_Result {\n    uint32_t mode;\n    uint32_t flash_page_size;\n    uint32_t flash_num_pages;\n    uint32_t max_message_size;\n    uint32_t uf2_family;\n};\n\n#define HF2_CMD_INFO 0x0002\n// no arguments\n// results is utf8 character array\n\n#define HF2_CMD_RESET_INTO_APP 0x0003\n// no arguments, no result\n\n#define HF2_CMD_RESET_INTO_BOOTLOADER 0x0004\n// no arguments, no result\n\n#define HF2_CMD_START_FLASH 0x0005\n// no arguments, no result\n\n#define HF2_CMD_WRITE_FLASH_PAGE 0x0006\nstruct HF2_WRITE_FLASH_PAGE_Command {\n    uint32_t target_addr;\n    uint32_t data[0];\n};\n// no result\n\n#define HF2_CMD_CHKSUM_PAGES 0x0007\nstruct HF2_CHKSUM_PAGES_Command {\n    uint32_t target_addr;\n    uint32_t num_pages;\n};\nstruct HF2_CHKSUM_PAGES_Result {\n    uint16_t chksums[0 /* num_pages */];\n};\n\n#define HF2_CMD_READ_WORDS 0x0008\nstruct HF2_READ_WORDS_Command {\n    uint32_t target_addr;\n    uint32_t num_words;\n};\nstruct HF2_READ_WORDS_Result {\n    uint32_t words[0 /* num_words */];\n};\n\n#define HF2_CMD_WRITE_WORDS 0x0009\nstruct HF2_WRITE_WORDS_Command {\n    uint32_t target_addr;\n    uint32_t num_words;\n    uint32_t words[0 /* num_words */];\n};\n// no result\n\n#define HF2_CMD_DMESG 0x0010\n// no arguments\n// results is utf8 character array\n\n#define HF2_EV_MASK 0x800000\n\n#define HF2_CMD_JDS_CONFIG 0x0020\n#define HF2_CMD_JDS_SEND 0x0021\n#define HF2_EV_JDS_PACKET 0x800020\n\ntypedef struct {\n    uint32_t command_id;\n    uint16_t tag;\n    uint8_t reserved0;\n    uint8_t reserved1;\n\n    union {\n        struct HF2_WRITE_FLASH_PAGE_Command write_flash_page;\n        struct HF2_WRITE_WORDS_Command write_words;\n        struct HF2_READ_WORDS_Command read_words;\n        struct HF2_CHKSUM_PAGES_Command chksum_pages;\n        uint8_t data8[0];\n        uint16_t data16[0];\n        uint32_t data32[0];\n    };\n} HF2_Command;\n\ntypedef struct {\n    union {\n        uint32_t eventId;\n        struct {\n            uint16_t tag;\n            union {\n                struct {\n                    uint8_t status;\n                    uint8_t status_info;\n                };\n                uint16_t status16;\n            };\n        };\n    };\n    union {\n        struct HF2_BININFO_Result bininfo;\n        uint8_t data8[0];\n        uint16_t data16[0];\n        uint32_t data32[0];\n    };\n} HF2_Response;\n\n#define HF2_FLAG_SERIAL_OUT 0x80\n#define HF2_FLAG_SERIAL_ERR 0xC0\n#define HF2_FLAG_CMDPKT_LAST 0x40\n#define HF2_FLAG_CMDPKT_BODY 0x00\n#define HF2_FLAG_MASK 0xC0\n#define HF2_SIZE_MASK 63\n\n#define HF2_STATUS_OK 0x00\n#define HF2_STATUS_INVALID_CMD 0x01\n#define HF2_STATUS_INVALID_STATE 0x02\n\n#endif\n","usb.cpp":"#include \"pxt.h\"\n\n#if CONFIG_ENABLED(DEVICE_USB)\n#include \"uf2format.h\"\n\nnamespace pxt {\nCodalUSB usb;\n\n// share the buffer; we will crash anyway if someone talks to us over both at the same time\nHF2_Buffer hf2buf;\nHF2 hf2(hf2buf);\n#ifdef HF2_HID\nHF2 hf2hid(hf2buf);\n#endif\nDummyIface dummyIface;\n\n#if CONFIG_ENABLED(DEVICE_MOUSE)\nUSBHIDMouse mouse;\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\nUSBHIDKeyboard keyboard;\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\nUSBHIDJoystick joystick;\n#endif\n\nstatic const DeviceDescriptor device_desc = {\n    0x12,   // bLength\n    0x01,   // bDescriptorType\n    0x0210, // bcdUSBL\n\n    // Class etc specified per-interface\n    0x00, 0x00, 0x00,\n\n    0x40, // bMaxPacketSize0\n    USB_DEFAULT_VID, USB_DEFAULT_PID,\n    0x4202, // bcdDevice - leave unchanged for the HF2 to work\n    0x01,   // iManufacturer\n    0x02,   // iProduct\n    0x03,   // SerialNumber\n    0x01    // bNumConfigs\n};\n\nstatic void start_usb() {\n    // start USB with a delay, so that user code can add new interfaces if needed\n    // (eg USB HID keyboard, or MSC)\n    fiber_sleep(500);\n    usb.start();\n}\n\nvoid platform_usb_init() __attribute__((weak));\nvoid platform_usb_init() {}\n\nvoid set_usb_strings(const char *uf2_info) {\n    static const char *string_descriptors[3];\n    static char serial[12];\n    itoa(target_get_serial() & 0x7fffffff, serial);\n\n    auto model = strstr(uf2_info, \"Model: \");\n    if (model) {\n        model += 7;\n        auto end = model;\n        while (*end && *end != '\\n' && *end != '\\r')\n            end++;\n        auto len = end - model;\n        auto dev = (char *)app_alloc(len + 10);\n        memcpy(dev, model, len);\n        strcpy(dev + len, \" (app)\");\n        // try to split into manufacturer and\n        auto sep = strstr(dev, \" / \");\n        if (sep) {\n            *sep = '\\0';\n            string_descriptors[0] = dev;\n            string_descriptors[1] = sep + 3;\n        } else {\n            string_descriptors[0] = dev;\n            string_descriptors[1] = dev;\n        }\n    } else {\n        string_descriptors[0] = \"Unknown Corp.\";\n        string_descriptors[1] = \"PXT Device (app)\";\n    }\n\n    string_descriptors[2] = serial;\n    usb.stringDescriptors = string_descriptors;\n}\n\nvoid usb_init() {\n    usb.deviceDescriptor = &device_desc;\n    set_usb_strings(UF2_INFO_TXT);\n\n    platform_usb_init();\n\n    usb.add(hf2);\n\n#ifdef HF2_HID\n    hf2hid.useHID = true;\n    usb.add(hf2hid);\n#else\n    // the WINUSB descriptors don't seem to work if there's only one interface\n    // so we add a dummy interface\n    usb.add(dummyIface);\n#endif\n\n#if CONFIG_ENABLED(DEVICE_MOUSE)\n    usb.add(mouse);\n#endif\n#if CONFIG_ENABLED(DEVICE_KEYBOARD)\n    usb.add(keyboard);\n#endif\n#if CONFIG_ENABLED(DEVICE_JOYSTICK)\n    usb.add(joystick);\n#endif\n\n    create_fiber(start_usb);\n}\n\n} // namespace pxt\n\n#else\nnamespace pxt {\nvoid usb_init() {}\n} // namespace pxt\n#endif\n\nnamespace control {\n/**\n * Determines if the USB has been enumerated.\n */\n//%\nbool isUSBInitialized() {\n#if CONFIG_ENABLED(DEVICE_USB)\n    return pxt::usb.isInitialised();\n#else\n    return false;\n#endif\n}\n} // namespace control\n\nnamespace pxt {\nstatic void (*pSendToUART)(const char *data, int len) = NULL;\nvoid setSendToUART(void (*f)(const char *, int)) {\n    pSendToUART = f;\n}\n\nvoid sendSerial(const char *data, int len) {\n#if CONFIG_ENABLED(DEVICE_USB)\n    hf2.sendSerial(data, len);\n#if HF2_HID\n    hf2hid.sendSerial(data, len);\n#endif\n#endif\n    if (pSendToUART)\n        pSendToUART(data, len);\n}\n\nvoid dumpDmesg() {\n    sendSerial(\"\\nDMESG:\\n\", 8);\n    sendSerial(codalLogStore.buffer, codalLogStore.ptr);\n    sendSerial(\"\\n\\n\", 2);\n}\n\nvoid (*logJDFrame)(const uint8_t *data);\nvoid (*sendJDFrame)(const uint8_t *data);\n\n} // namespace pxt\n"},"core---vm":{"Makefile":"include Makefile.inc\n\nBUILD := bld-$(CROSS_TRIPLE)\nSDL_OBJ := $(BUILD)/pxtapp/hw---vm/sdlmain.o\nPXT_OBJS := $(PXT_OBJS:bld/%=$(BUILD)/%)\nPXT_OBJS := $(PXT_OBJS:$(SDL_OBJ)=)\n\nCOMMON_FLAGS = -W -Wall -Wno-unused-parameter -Wno-unused-private-field -Ipxtapp \\\n\t-fwrapv -fno-threadsafe-statics -ffunction-sections -fno-strict-aliasing -O2 \\\n\t$(NPM_INCLUDES) -g\nLIBS = -lm -lpthread\nCFLAGS = $(COMMON_FLAGS) -std=c99\nCXXFLAGS = $(COMMON_FLAGS) -std=c++11 -fno-rtti -fno-exceptions -fno-unwind-tables\nLDFLAGS = -g\n\nCC = $(PREF)gcc\nLD = $(PREF)gcc\nLIBSTDCPP = \nNPM_LIBS = $(wildcard node_modules/*/lib/*.a)\nNPM_INCLUDES = $(addprefix -I, $(wildcard node_modules/*/include))\nSTRIP = strip\n\nifeq (i386,$(findstring i386,$(CROSS_TRIPLE)))\nX32 = -32\nendif\nifeq (i686,$(findstring i686,$(CROSS_TRIPLE)))\nX32 = -32\nendif\n\nifeq (darwin,$(findstring darwin,$(CROSS_TRIPLE)))\nSOFLAGS := -dynamiclib\nSONAME := libpxt$(X32).dylib\nEXE := $(BUILD)/pxt-vm-cli$(X32)\nSDL_EXE = $(BUILD)/pxt-vm-sdl$(X32)\nSTRIP = strip -S\nelse\nifeq (linux,$(findstring linux,$(CROSS_TRIPLE)))\nSOFLAGS := -shared\nSONAME := libpxt$(X32).so\nEXE := $(BUILD)/pxt-vm-cli-linux$(X32)\nCOMMON_FLAGS += -fPIC\nSDL_EXE = skip\nelse\nSOFLAGS := -shared\nLDFLAGS += -static\nSONAME := pxt$(X32).dll\nEXE := $(BUILD)/pxt-vm-cli$(X32).exe\nSDL_EXE = $(BUILD)/pxt-vm-sdl$(X32).exe\nifeq ($(X32),-32)\nLDFLAGS += -Wl,--image-base,0x08000000\nendif\nendif\nendif\n\nDEPS = $(PXT_HEADERS) package.json Makefile Makefile.inc\n\nall:\n\tCROSS_TRIPLE=win64 crossbuild make -j8 build-one\n\tCROSS_TRIPLE=linux crossbuild make -j8 build-one\n\tCROSS_TRIPLE=osx crossbuild make -j8 build-one\n\tCROSS_TRIPLE=win32 crossbuild make -j8 build-one\n\t#CROSS_TRIPLE=osx32 crossbuild make -j8 build-one\n\trm -f bld/*.tgz bld/*.b64\n\ttar zcf bld/all.tgz bld/*\n\tbase64 < bld/all.tgz > bld/all.tgz.b64\n\t@ls -l bld/\n\t@echo Build OK\n\ncreate-dir:\n\tmkdir -p $(BUILD) bld\n\nbuild-one: create-dir $(EXE)\nifneq ($(SDL_EXE),skip)\n\t$(MAKE) CXXFLAGS=\"$(CXXFLAGS) $(shell sdl2-config --cflags)\" $(SDL_EXE)\nendif\n\n$(EXE) $(BUILD)/$(SONAME): $(PXT_OBJS)\n\t$(LD) -o $(EXE) $(LDFLAGS) $(PXT_OBJS) $(LIBSTDCPP) $(LIBS) $(NPM_LIBS)\n\t$(LD) -o $(BUILD)/$(SONAME) $(SOFLAGS) $(LDFLAGS) $(PXT_OBJS) $(LIBSTDCPP) $(LIBS) $(NPM_LIBS)\n\t$(STRIP) -o bld/$(shell basename $(EXE)) $(EXE)\n\t$(STRIP) -o bld/$(SONAME) $(BUILD)/$(SONAME)\n\n$(SDL_EXE): $(SDL_OBJ)\n\t$(LD) -o $(SDL_EXE) $(LDFLAGS) $(SDL_OBJ) $(LIBSTDCPP) $(LIBS) $(shell sdl2-config --static-libs)\n\t$(STRIP) -o bld/$(shell basename $(SDL_EXE)) $(SDL_EXE)\n\nclean:\n\trm -rf bld bld-*\n\n$(BUILD)/%.o: %.cpp $(DEPS)\n\t@mkdir -p $(dir $@)\n\t$(CC) $(CXXFLAGS) -c $< -o $@\n\n$(BUILD)/%.o: %.s $(DEPS)\n\t@mkdir -p $(dir $@)\n\t$(CC) $(CFLAGS) -c $< -o $@\n\n$(BUILD)/%.o: %.c $(DEPS)\n\t@mkdir -p $(dir $@)\n\t$(CC) $(CFLAGS) -c $< -o $@\n","README.md":"# core\n\nThe core library for Codal-based targets.\n\n","codalemu.cpp":"#include \"pxt.h\"\n#include <pthread.h>\n\nnamespace pxt {\n\nstatic pthread_mutex_t irqMutex;\nvoid target_disable_irq() {\n    pthread_mutex_lock(&irqMutex);\n}\nvoid target_enable_irq() {\n    pthread_mutex_unlock(&irqMutex);\n}\n\n} // namespace pxt\n\n","config.cpp":"\n","control.cpp":"#include \"pxt.h\"\n\nnamespace control {\n\n/**\n * Announce that an event happened to registered handlers.\n * @param src ID of the Component that generated the event\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.\n */\n//% weight=21 blockGap=12 blockId=\"control_raise_event\"\n//% block=\"raise event|from %src|with value %value\" blockExternalInputs=1\n//% help=control/raise-event\nvoid raiseEvent(int src, int value) {\n    pxt::raiseEvent(src, value);\n}\n\n/**\n* Allocates the next user notification event\n*/\n//% help=control/allocate-notify-event\nint allocateNotifyEvent() {\n    return pxt::allocateNotifyEvent();\n}\n\n/**\n* Determine the version of system software currently running.\n*/\n//% blockId=\"control_device_dal_version\" block=\"device dal version\"\n//% help=control/device-dal-version\nString deviceDalVersion() {\n#ifdef PXT_VM\n    return mkString(\"vm\");\n#else\n    return mkString(\"linux\");\n#endif\n}\n\n\n/** Write data to DMESG debugging buffer. */\n//%\nvoid dmesg(String s) {\n    DMESG(\"# %s\", s->getUTF8Data());\n}\n\n//%\nuint32_t _ramSize()\n{\n#ifdef POKY\n    return 128 * 1024;\n#else\n    // a lot! doesn't really matter how much\n    return 16 * 1024 * 1024;\n#endif\n}\n\n/**\n * Determines if the USB has been enumerated.\n */\n//%\nbool isUSBInitialized() {\n    return false;\n}\n\n}\n\nnamespace serial {\n    /** Send DMESG debug buffer over serial. */\n    //%\n    void writeDmesg() {\n        pxt::dumpDmesg();\n    }\n}","dal.d.ts":"// Auto-generated. Do not edit.\ndeclare const enum DAL {\n    // built/codal/libraries/codal-core/inc/core/CodalComponent.h\n    DEVICE_ID_BUTTON_A = 1,\n    DEVICE_ID_BUTTON_B = 2,\n    DEVICE_ID_BUTTON_AB = 3,\n    DEVICE_ID_BUTTON_RESET = 4,\n    DEVICE_ID_ACCELEROMETER = 5,\n    DEVICE_ID_COMPASS = 6,\n    DEVICE_ID_DISPLAY = 7,\n    DEVICE_ID_THERMOMETER = 8,\n    DEVICE_ID_RADIO = 9,\n    DEVICE_ID_RADIO_DATA_READY = 10,\n    DEVICE_ID_MULTIBUTTON_ATTACH = 11,\n    DEVICE_ID_SERIAL = 12,\n    DEVICE_ID_GESTURE = 13,\n    DEVICE_ID_SYSTEM_TIMER = 14,\n    DEVICE_ID_SCHEDULER = 15,\n    DEVICE_ID_COMPONENT = 16,\n    DEVICE_ID_LIGHT_SENSOR = 17,\n    DEVICE_ID_TOUCH_SENSOR = 18,\n    DEVICE_ID_SYSTEM_DAC = 19,\n    DEVICE_ID_SYSTEM_MICROPHONE = 20,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR = 21,\n    DEVICE_ID_SYSTEM_LEVEL_DETECTOR_SPL = 22,\n    DEVICE_ID_MSC = 23,\n    DEVICE_ID_SPI = 24,\n    DEVICE_ID_IO_P0 = 100,\n    DEVICE_ID_MESSAGE_BUS_LISTENER = 1021,\n    DEVICE_ID_NOTIFY_ONE = 1022,\n    DEVICE_ID_NOTIFY = 1023,\n    DEVICE_COMPONENT_RUNNING = 4096,\n    DEVICE_COMPONENT_STATUS_SYSTEM_TICK = 8192,\n    DEVICE_COMPONENT_STATUS_IDLE_TICK = 16384,\n    DEVICE_COMPONENT_LISTENERS_CONFIGURED = 1,\n    DEVICE_COMPONENT_EVT_SYSTEM_TICK = 1,\n    // built/codal/libraries/codal-core/inc/core/CodalFiber.h\n    DEVICE_SCHEDULER_RUNNING = 1,\n    DEVICE_SCHEDULER_IDLE = 2,\n    DEVICE_FIBER_FLAG_FOB = 1,\n    DEVICE_FIBER_FLAG_PARENT = 2,\n    DEVICE_FIBER_FLAG_CHILD = 4,\n    DEVICE_FIBER_FLAG_DO_NOT_PAGE = 8,\n    DEVICE_SCHEDULER_EVT_TICK = 1,\n    DEVICE_SCHEDULER_EVT_IDLE = 2,\n    // built/codal/libraries/codal-core/inc/core/CodalListener.h\n    MESSAGE_BUS_LISTENER_PARAMETERISED = 1,\n    MESSAGE_BUS_LISTENER_METHOD = 2,\n    MESSAGE_BUS_LISTENER_BUSY = 4,\n    MESSAGE_BUS_LISTENER_REENTRANT = 8,\n    MESSAGE_BUS_LISTENER_QUEUE_IF_BUSY = 16,\n    MESSAGE_BUS_LISTENER_DROP_IF_BUSY = 32,\n    MESSAGE_BUS_LISTENER_NONBLOCKING = 64,\n    MESSAGE_BUS_LISTENER_URGENT = 128,\n    MESSAGE_BUS_LISTENER_DELETING = 32768,\n    MESSAGE_BUS_LISTENER_IMMEDIATE = 192,\n    // built/codal/libraries/codal-core/inc/core/ErrorNo.h\n    DEVICE_OK = 0,\n    DEVICE_INVALID_PARAMETER = -1001,\n    DEVICE_NOT_SUPPORTED = -1002,\n    DEVICE_CALIBRATION_IN_PROGRESS = -1003,\n    DEVICE_CALIBRATION_REQUIRED = -1004,\n    DEVICE_NO_RESOURCES = -1005,\n    DEVICE_BUSY = -1006,\n    DEVICE_CANCELLED = -1007,\n    DEVICE_I2C_ERROR = -1010,\n    DEVICE_SERIAL_IN_USE = -1011,\n    DEVICE_NO_DATA = -1012,\n    DEVICE_NOT_IMPLEMENTED = -1013,\n    DEVICE_SPI_ERROR = -1014,\n    DEVICE_OOM = 20,\n    DEVICE_HEAP_ERROR = 30,\n    DEVICE_NULL_DEREFERENCE = 40,\n    DEVICE_USB_ERROR = 50,\n    // built/codal/libraries/codal-core/inc/core/NotifyEvents.h\n    DISPLAY_EVT_FREE = 1,\n    CODAL_SERIAL_EVT_TX_EMPTY = 2,\n    BLE_EVT_SERIAL_TX_EMPTY = 3,\n    DEVICE_NOTIFY_USER_EVENT_BASE = 1024,\n    // built/codal/libraries/codal-core/inc/driver-models/AbstractButton.h\n    DEVICE_BUTTON_EVT_DOWN = 1,\n    DEVICE_BUTTON_EVT_UP = 2,\n    DEVICE_BUTTON_EVT_CLICK = 3,\n    DEVICE_BUTTON_EVT_LONG_CLICK = 4,\n    DEVICE_BUTTON_EVT_HOLD = 5,\n    DEVICE_BUTTON_EVT_DOUBLE_CLICK = 6,\n    DEVICE_BUTTON_LONG_CLICK_TIME = 1000,\n    DEVICE_BUTTON_HOLD_TIME = 1500,\n    DEVICE_BUTTON_STATE = 1,\n    DEVICE_BUTTON_STATE_HOLD_TRIGGERED = 2,\n    DEVICE_BUTTON_STATE_CLICK = 4,\n    DEVICE_BUTTON_STATE_LONG_CLICK = 8,\n    DEVICE_BUTTON_SIGMA_MIN = 0,\n    DEVICE_BUTTON_SIGMA_MAX = 12,\n    DEVICE_BUTTON_SIGMA_THRESH_HI = 8,\n    DEVICE_BUTTON_SIGMA_THRESH_LO = 2,\n    DEVICE_BUTTON_DOUBLE_CLICK_THRESH = 50,\n    DEVICE_BUTTON_SIMPLE_EVENTS = 0,\n    DEVICE_BUTTON_ALL_EVENTS = 1,\n    ACTIVE_LOW = 0,\n    ACTIVE_HIGH = 1,\n    // built/codal/libraries/codal-core/inc/driver-models/Accelerometer.h\n    ACCELEROMETER_IMU_DATA_VALID = 2,\n    ACCELEROMETER_EVT_DATA_UPDATE = 1,\n    ACCELEROMETER_EVT_NONE = 0,\n    ACCELEROMETER_EVT_TILT_UP = 1,\n    ACCELEROMETER_EVT_TILT_DOWN = 2,\n    ACCELEROMETER_EVT_TILT_LEFT = 3,\n    ACCELEROMETER_EVT_TILT_RIGHT = 4,\n    ACCELEROMETER_EVT_FACE_UP = 5,\n    ACCELEROMETER_EVT_FACE_DOWN = 6,\n    ACCELEROMETER_EVT_FREEFALL = 7,\n    ACCELEROMETER_EVT_3G = 8,\n    ACCELEROMETER_EVT_6G = 9,\n    ACCELEROMETER_EVT_8G = 10,\n    ACCELEROMETER_EVT_SHAKE = 11,\n    ACCELEROMETER_REST_TOLERANCE = 200,\n    ACCELEROMETER_TILT_TOLERANCE = 200,\n    ACCELEROMETER_FREEFALL_TOLERANCE = 400,\n    ACCELEROMETER_SHAKE_TOLERANCE = 400,\n    ACCELEROMETER_3G_TOLERANCE = 3072,\n    ACCELEROMETER_6G_TOLERANCE = 6144,\n    ACCELEROMETER_8G_TOLERANCE = 8192,\n    ACCELEROMETER_GESTURE_DAMPING = 5,\n    ACCELEROMETER_SHAKE_DAMPING = 10,\n    ACCELEROMETER_SHAKE_RTX = 30,\n    ACCELEROMETER_SHAKE_COUNT_THRESHOLD = 4,\n    // built/codal/libraries/codal-core/inc/driver-models/Compass.h\n    COMPASS_STATUS_RUNNING = 1,\n    COMPASS_STATUS_CALIBRATED = 2,\n    COMPASS_STATUS_CALIBRATING = 4,\n    COMPASS_STATUS_ADDED_TO_IDLE = 8,\n    COMPASS_EVT_DATA_UPDATE = 1,\n    COMPASS_EVT_CONFIG_NEEDED = 2,\n    COMPASS_EVT_CALIBRATE = 3,\n    COMPASS_EVT_CALIBRATION_NEEDED = 4,\n    // built/codal/libraries/codal-core/inc/driver-models/Pin.h\n    IO_STATUS_DIGITAL_IN = 1,\n    IO_STATUS_DIGITAL_OUT = 2,\n    IO_STATUS_ANALOG_IN = 4,\n    IO_STATUS_ANALOG_OUT = 8,\n    IO_STATUS_TOUCH_IN = 16,\n    IO_STATUS_EVENT_ON_EDGE = 32,\n    IO_STATUS_EVENT_PULSE_ON_EDGE = 64,\n    DEVICE_PIN_MAX_OUTPUT = 1023,\n    DEVICE_PIN_MAX_SERVO_RANGE = 180,\n    DEVICE_PIN_DEFAULT_SERVO_RANGE = 2000,\n    DEVICE_PIN_DEFAULT_SERVO_CENTER = 1500,\n    DEVICE_PIN_EVENT_NONE = 0,\n    DEVICE_PIN_EVENT_ON_EDGE = 1,\n    DEVICE_PIN_EVENT_ON_PULSE = 2,\n    DEVICE_PIN_EVENT_ON_TOUCH = 3,\n    DEVICE_PIN_EVT_RISE = 2,\n    DEVICE_PIN_EVT_FALL = 3,\n    DEVICE_PIN_EVT_PULSE_HI = 4,\n    DEVICE_PIN_EVT_PULSE_LO = 5,\n    PIN_CAPABILITY_DIGITAL = 1,\n    PIN_CAPABILITY_ANALOG = 2,\n    PIN_CAPABILITY_AD = 3,\n    PIN_CAPABILITY_ALL = 3,\n    None = 0,\n    Down = 1,\n    Up = 2,\n    // built/codal/libraries/codal-core/inc/driver-models/SPIFlash.h\n    SPIFLASH_PAGE_SIZE = 256,\n    SPIFLASH_SMALL_ROW_PAGES = 16,\n    SPIFLASH_BIG_ROW_PAGES = 256,\n    // /libraries/codal-core/inc/driver-models/Serial.h\n    CODAL_SERIAL_DEFAULT_BAUD_RATE = 115200,\n    CODAL_SERIAL_DEFAULT_BUFFER_SIZE = 20,\n    CODAL_SERIAL_EVT_DELIM_MATCH = 1,\n    CODAL_SERIAL_EVT_HEAD_MATCH = 2,\n    CODAL_SERIAL_EVT_RX_FULL = 3,\n    CODAL_SERIAL_EVT_DATA_RECEIVED = 4,\n    CODAL_SERIAL_STATUS_RX_IN_USE = 1,\n    CODAL_SERIAL_STATUS_TX_IN_USE = 2,\n    CODAL_SERIAL_STATUS_RX_BUFF_INIT = 4,\n    CODAL_SERIAL_STATUS_TX_BUFF_INIT = 8,\n    CODAL_SERIAL_STATUS_RXD = 16,\n    ASYNC = 0,\n    SYNC_SPINWAIT = 1,\n    SYNC_SLEEP = 2,\n    RxInterrupt = 0,\n    TxInterrupt = 1,\n    // built/codal/libraries/codal-core/inc/driver-models/Timer.h\n    CODAL_TIMER_DEFAULT_EVENT_LIST_SIZE = 10,\n    // built/codal/libraries/codal-core/inc/drivers/AnalogSensor.h\n    ANALOG_THRESHOLD_LOW = 1,\n    ANALOG_THRESHOLD_HIGH = 2,\n    ANALOG_SENSOR_UPDATE_NEEDED = 3,\n    ANALOG_SENSOR_INITIALISED = 1,\n    ANALOG_SENSOR_HIGH_THRESHOLD_PASSED = 2,\n    ANALOG_SENSOR_LOW_THRESHOLD_PASSED = 4,\n    ANALOG_SENSOR_LOW_THRESHOLD_ENABLED = 8,\n    ANALOG_SENSOR_HIGH_THRESHOLD_ENABLED = 16,\n    // built/codal/libraries/codal-core/inc/drivers/AnimatedDisplay.h\n    DISPLAY_EVT_ANIMATION_COMPLETE = 1,\n    DISPLAY_DEFAULT_AUTOCLEAR = 1,\n    DISPLAY_SPACING = 1,\n    DISPLAY_ANIMATE_DEFAULT_POS = -255,\n    DISPLAY_DEFAULT_SCROLL_SPEED = 120,\n    DISPLAY_DEFAULT_SCROLL_STRIDE = -1,\n    DISPLAY_DEFAULT_PRINT_SPEED = 400,\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    // built/codal/libraries/codal-core/inc/drivers/FAT.h\n    FAT_RESERVED_SECTORS = 1,\n    FAT_ROOT_DIR_SECTORS = 4,\n    // built/codal/libraries/codal-core/inc/drivers/HID.h\n    HID_REQUEST_GET_REPORT = 1,\n    HID_REQUEST_GET_IDLE = 2,\n    HID_REQUEST_GET_PROTOCOL = 3,\n    HID_REQUEST_SET_REPORT = 9,\n    HID_REQUEST_SET_IDLE = 10,\n    HID_REQUEST_SET_PROTOCOL = 11,\n    // built/codal/libraries/codal-core/inc/drivers/HIDKeyboard.h\n    HID_KEYBOARD_NUM_REPORTS = 3,\n    HID_KEYBOARD_REPORT_GENERIC = 1,\n    HID_KEYBOARD_REPORT_CONSUMER = 2,\n    HID_KEYBOARD_KEYSTATE_SIZE_GENERIC = 8,\n    HID_KEYBOARD_KEYSTATE_SIZE_CONSUMER = 2,\n    HID_KEYBOARD_MODIFIER_OFFSET = 2,\n    HID_KEYBOARD_DELAY_DEFAULT = 10,\n    PressKey = 0,\n    ReleaseKey = 1,\n    // built/codal/libraries/codal-core/inc/drivers/KeyMap.h\n    KEYMAP_ALL_KEYS_UP_Val = 1,\n    KEYMAP_ALL_KEYS_UP_POS = 28,\n    KEYMAP_NORMAL_KEY_Val = 0,\n    KEYMAP_MODIFIER_KEY_Val = 1,\n    KEYMAP_MODIFIER_POS = 29,\n    KEYMAP_MEDIA_KEY_Val = 1,\n    KEYMAP_MEDIA_POS = 30,\n    KEYMAP_KEY_UP_Val = 0,\n    KEYMAP_KEY_DOWN_Val = 1,\n    KEYMAP_KEY_DOWN_POS = 31,\n    // built/codal/libraries/codal-core/inc/drivers/LEDMatrix.h\n    LED_MATRIX_GREYSCALE_BIT_DEPTH = 8,\n    LED_MATRIX_EVT_LIGHT_SENSE = 2,\n    LED_MATRIX_EVT_FRAME_TIMEOUT = 3,\n    LED_MATRIX_MINIMUM_BRIGHTNESS = 1,\n    LED_MATRIX_MAXIMUM_BRIGHTNESS = 255,\n    LED_MATRIX_DEFAULT_BRIGHTNESS = 255,\n    DISPLAY_MODE_BLACK_AND_WHITE = 0,\n    DISPLAY_MODE_GREYSCALE = 1,\n    DISPLAY_MODE_BLACK_AND_WHITE_LIGHT_SENSE = 2,\n    MATRIX_DISPLAY_ROTATION_0 = 0,\n    MATRIX_DISPLAY_ROTATION_90 = 1,\n    MATRIX_DISPLAY_ROTATION_180 = 2,\n    MATRIX_DISPLAY_ROTATION_270 = 3,\n    NO_CONN = 0,\n    // built/codal/libraries/codal-core/inc/drivers/MultiButton.h\n    MULTI_BUTTON_STATE_1 = 1,\n    MULTI_BUTTON_STATE_2 = 2,\n    MULTI_BUTTON_HOLD_TRIGGERED_1 = 4,\n    MULTI_BUTTON_HOLD_TRIGGERED_2 = 8,\n    MULTI_BUTTON_SUPRESSED_1 = 16,\n    MULTI_BUTTON_SUPRESSED_2 = 32,\n    MULTI_BUTTON_ATTACHED = 64,\n    // built/codal/libraries/codal-core/inc/drivers/ST7735.h\n    MADCTL_MY = 128,\n    MADCTL_MX = 64,\n    MADCTL_MV = 32,\n    MADCTL_ML = 16,\n    MADCTL_RGB = 0,\n    MADCTL_BGR = 8,\n    MADCTL_MH = 4,\n    // built/codal/libraries/codal-core/inc/drivers/TouchButton.h\n    TOUCH_BUTTON_CALIBRATION_PERIOD = 10,\n    TOUCH_BUTTON_CALIBRATION_LINEAR_OFFSET = 2,\n    TOUCH_BUTTON_CALIBRATION_PERCENTAGE_OFFSET = 5,\n    TOUCH_BUTTON_CALIBRATING = 16,\n    // built/codal/libraries/codal-core/inc/drivers/TouchSensor.h\n    TOUCH_SENSOR_MAX_BUTTONS = 10,\n    TOUCH_SENSOR_SAMPLE_PERIOD = 50,\n    TOUCH_SENSE_SAMPLE_MAX = 1000,\n    TOUCH_SENSOR_UPDATE_NEEDED = 1,\n    // built/codal/libraries/codal-core/inc/drivers/USB_HID_Keys.h\n    KEY_MOD_LCTRL = 1,\n    KEY_MOD_LSHIFT = 2,\n    KEY_MOD_LALT = 4,\n    KEY_MOD_LMETA = 8,\n    KEY_MOD_RCTRL = 16,\n    KEY_MOD_RSHIFT = 32,\n    KEY_MOD_RALT = 64,\n    KEY_MOD_RMETA = 128,\n    KEY_NONE = 0,\n    KEY_ERR_OVF = 1,\n    KEY_A = 4,\n    KEY_B = 5,\n    KEY_C = 6,\n    KEY_D = 7,\n    KEY_E = 8,\n    KEY_F = 9,\n    KEY_G = 10,\n    KEY_H = 11,\n    KEY_I = 12,\n    KEY_J = 13,\n    KEY_K = 14,\n    KEY_L = 15,\n    KEY_M = 16,\n    KEY_N = 17,\n    KEY_O = 18,\n    KEY_P = 19,\n    KEY_Q = 20,\n    KEY_R = 21,\n    KEY_S = 22,\n    KEY_T = 23,\n    KEY_U = 24,\n    KEY_V = 25,\n    KEY_W = 26,\n    KEY_X = 27,\n    KEY_Y = 28,\n    KEY_Z = 29,\n    KEY_1 = 30,\n    KEY_2 = 31,\n    KEY_3 = 32,\n    KEY_4 = 33,\n    KEY_5 = 34,\n    KEY_6 = 35,\n    KEY_7 = 36,\n    KEY_8 = 37,\n    KEY_9 = 38,\n    KEY_0 = 39,\n    KEY_ENTER = 40,\n    KEY_ESC = 41,\n    KEY_BACKSPACE = 42,\n    KEY_TAB = 43,\n    KEY_SPACE = 44,\n    KEY_MINUS = 45,\n    KEY_EQUAL = 46,\n    KEY_LEFTBRACE = 47,\n    KEY_RIGHTBRACE = 48,\n    KEY_BACKSLASH = 49,\n    KEY_HASHTILDE = 50,\n    KEY_SEMICOLON = 51,\n    KEY_APOSTROPHE = 52,\n    KEY_GRAVE = 53,\n    KEY_COMMA = 54,\n    KEY_DOT = 55,\n    KEY_SLASH = 56,\n    KEY_CAPSLOCK = 57,\n    KEY_F1 = 58,\n    KEY_F2 = 59,\n    KEY_F3 = 60,\n    KEY_F4 = 61,\n    KEY_F5 = 62,\n    KEY_F6 = 63,\n    KEY_F7 = 64,\n    KEY_F8 = 65,\n    KEY_F9 = 66,\n    KEY_F10 = 67,\n    KEY_F11 = 68,\n    KEY_F12 = 69,\n    KEY_SYSRQ = 70,\n    KEY_SCROLLLOCK = 71,\n    KEY_PAUSE = 72,\n    KEY_INSERT = 73,\n    KEY_HOME = 74,\n    KEY_PAGEUP = 75,\n    KEY_DELETE = 76,\n    KEY_END = 77,\n    KEY_PAGEDOWN = 78,\n    KEY_RIGHT = 79,\n    KEY_LEFT = 80,\n    KEY_DOWN = 81,\n    KEY_UP = 82,\n    KEY_NUMLOCK = 83,\n    KEY_KPSLASH = 84,\n    KEY_KPASTERISK = 85,\n    KEY_KPMINUS = 86,\n    KEY_KPPLUS = 87,\n    KEY_KPENTER = 88,\n    KEY_KP1 = 89,\n    KEY_KP2 = 90,\n    KEY_KP3 = 91,\n    KEY_KP4 = 92,\n    KEY_KP5 = 93,\n    KEY_KP6 = 94,\n    KEY_KP7 = 95,\n    KEY_KP8 = 96,\n    KEY_KP9 = 97,\n    KEY_KP0 = 98,\n    KEY_KPDOT = 99,\n    KEY_102ND = 100,\n    KEY_COMPOSE = 101,\n    KEY_POWER = 102,\n    KEY_KPEQUAL = 103,\n    KEY_F13 = 104,\n    KEY_F14 = 105,\n    KEY_F15 = 106,\n    KEY_F16 = 107,\n    KEY_F17 = 108,\n    KEY_F18 = 109,\n    KEY_F19 = 110,\n    KEY_F20 = 111,\n    KEY_F21 = 112,\n    KEY_F22 = 113,\n    KEY_F23 = 114,\n    KEY_F24 = 115,\n    KEY_OPEN = 116,\n    KEY_HELP = 117,\n    KEY_PROPS = 118,\n    KEY_FRONT = 119,\n    KEY_STOP = 120,\n    KEY_AGAIN = 121,\n    KEY_UNDO = 122,\n    KEY_CUT = 123,\n    KEY_COPY = 124,\n    KEY_PASTE = 125,\n    KEY_FIND = 126,\n    KEY_MUTE = 127,\n    KEY_VOLUMEUP = 128,\n    KEY_VOLUMEDOWN = 129,\n    KEY_KPCOMMA = 133,\n    KEY_RO = 135,\n    KEY_KATAKANAHIRAGANA = 136,\n    KEY_YEN = 137,\n    KEY_HENKAN = 138,\n    KEY_MUHENKAN = 139,\n    KEY_KPJPCOMMA = 140,\n    KEY_HANGEUL = 144,\n    KEY_HANJA = 145,\n    KEY_KATAKANA = 146,\n    KEY_HIRAGANA = 147,\n    KEY_ZENKAKUHANKAKU = 148,\n    KEY_KPLEFTPAREN = 182,\n    KEY_KPRIGHTPAREN = 183,\n    KEY_LEFTCTRL = 224,\n    KEY_LEFTSHIFT = 225,\n    KEY_LEFTALT = 226,\n    KEY_LEFTMETA = 227,\n    KEY_RIGHTCTRL = 228,\n    KEY_RIGHTSHIFT = 229,\n    KEY_RIGHTALT = 230,\n    KEY_RIGHTMETA = 231,\n    KEY_MEDIA_PLAYPAUSE = 232,\n    KEY_MEDIA_STOPCD = 233,\n    KEY_MEDIA_PREVIOUSSONG = 234,\n    KEY_MEDIA_NEXTSONG = 235,\n    KEY_MEDIA_EJECTCD = 236,\n    KEY_MEDIA_VOLUMEUP = 237,\n    KEY_MEDIA_VOLUMEDOWN = 238,\n    KEY_MEDIA_MUTE = 239,\n    KEY_MEDIA_WWW = 240,\n    KEY_MEDIA_BACK = 241,\n    KEY_MEDIA_FORWARD = 242,\n    KEY_MEDIA_STOP = 243,\n    KEY_MEDIA_FIND = 244,\n    KEY_MEDIA_SCROLLUP = 245,\n    KEY_MEDIA_SCROLLDOWN = 246,\n    KEY_MEDIA_EDIT = 247,\n    KEY_MEDIA_SLEEP = 248,\n    KEY_MEDIA_COFFEE = 249,\n    KEY_MEDIA_REFRESH = 250,\n    KEY_MEDIA_CALC = 251,\n    // built/codal/libraries/codal-core/inc/drivers/uf2format.h\n    UF2FORMAT_H = 1,\n    APP_START_ADDRESS = 8192,\n    UF2_FLAG_NOFLASH = 1,\n    // built/codal/libraries/codal-core/inc/streams/DataStream.h\n    DATASTREAM_MAXIMUM_BUFFERS = 1,\n    // built/codal/libraries/codal-core/inc/streams/LevelDetector.h\n    LEVEL_THRESHOLD_LOW = 1,\n    LEVEL_THRESHOLD_HIGH = 2,\n    LEVEL_DETECTOR_INITIALISED = 1,\n    LEVEL_DETECTOR_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_DEFAULT_WINDOW_SIZE = 128,\n    // built/codal/libraries/codal-core/inc/streams/LevelDetectorSPL.h\n    LEVEL_DETECTOR_SPL_INITIALISED = 1,\n    LEVEL_DETECTOR_SPL_HIGH_THRESHOLD_PASSED = 2,\n    LEVEL_DETECTOR_SPL_LOW_THRESHOLD_PASSED = 4,\n    LEVEL_DETECTOR_SPL_DEFAULT_WINDOW_SIZE = 128,\n    // built/codal/libraries/codal-core/inc/streams/Synthesizer.h\n    SYNTHESIZER_SAMPLE_RATE = 44100,\n    TONE_WIDTH = 1024,\n    // built/codal/libraries/codal-core/inc/types/BitmapFont.h\n    BITMAP_FONT_WIDTH = 5,\n    BITMAP_FONT_HEIGHT = 5,\n    BITMAP_FONT_ASCII_START = 32,\n    BITMAP_FONT_ASCII_END = 126,\n    // built/codal/libraries/codal-core/inc/types/CoordinateSystem.h\n    COORDINATE_SPACE_ROTATED_0 = 0,\n    COORDINATE_SPACE_ROTATED_90 = 1,\n    COORDINATE_SPACE_ROTATED_180 = 2,\n    COORDINATE_SPACE_ROTATED_270 = 3,\n    RAW = 0,\n    SIMPLE_CARTESIAN = 1,\n    NORTH_EAST_DOWN = 2,\n    NORTH_EAST_UP = 3,\n    // built/codal/libraries/codal-core/inc/types/Event.h\n    DEVICE_ID_ANY = 0,\n    DEVICE_EVT_ANY = 0,\n    CREATE_ONLY = 0,\n    CREATE_AND_FIRE = 1,\n    DEVICE_EVENT_DEFAULT_LAUNCH_MODE = 1,\n    // built/codal/libraries/codal-core/inc/types/RefCounted.h\n    REF_TAG_STRING = 1,\n    REF_TAG_BUFFER = 2,\n    REF_TAG_IMAGE = 3,\n    REF_TAG_USER = 32,\n    // built/codal/pxtapp/core---stm32f401re/hf2dbg.h\n    HF2DBG_H = 1,\n    // built/codal/pxtapp/core---stm32f401re/pins.h\n    CFG_PIN_ACCELEROMETER_INT = 1,\n    CFG_PIN_ACCELEROMETER_SCL = 2,\n    CFG_PIN_ACCELEROMETER_SDA = 3,\n    CFG_PIN_BTN_A = 4,\n    CFG_PIN_BTN_B = 5,\n    CFG_PIN_BTN_SLIDE = 6,\n    CFG_PIN_DOTSTAR_CLOCK = 7,\n    CFG_PIN_DOTSTAR_DATA = 8,\n    CFG_PIN_FLASH_CS = 9,\n    CFG_PIN_FLASH_MISO = 10,\n    CFG_PIN_FLASH_MOSI = 11,\n    CFG_PIN_FLASH_SCK = 12,\n    CFG_PIN_LED = 13,\n    CFG_PIN_LIGHT = 14,\n    CFG_PIN_MICROPHONE = 15,\n    CFG_PIN_MIC_CLOCK = 16,\n    CFG_PIN_MIC_DATA = 17,\n    CFG_PIN_MISO = 18,\n    CFG_PIN_MOSI = 19,\n    CFG_PIN_NEOPIXEL = 20,\n    CFG_PIN_RX = 21,\n    CFG_PIN_RXLED = 22,\n    CFG_PIN_SCK = 23,\n    CFG_PIN_SCL = 24,\n    CFG_PIN_SDA = 25,\n    CFG_PIN_SPEAKER_AMP = 26,\n    CFG_PIN_TEMPERATURE = 27,\n    CFG_PIN_TX = 28,\n    CFG_PIN_TXLED = 29,\n    CFG_PIN_IR_OUT = 30,\n    CFG_PIN_IR_IN = 31,\n    CFG_PIN_DISPLAY_SCK = 32,\n    CFG_PIN_DISPLAY_MISO = 33,\n    CFG_PIN_DISPLAY_MOSI = 34,\n    CFG_PIN_DISPLAY_CS = 35,\n    CFG_PIN_DISPLAY_DC = 36,\n    CFG_DISPLAY_WIDTH = 37,\n    CFG_DISPLAY_HEIGHT = 38,\n    CFG_DISPLAY_CFG0 = 39,\n    CFG_DISPLAY_CFG1 = 40,\n    CFG_DISPLAY_CFG2 = 41,\n    CFG_DISPLAY_CFG3 = 42,\n    CFG_PIN_DISPLAY_RST = 43,\n    CFG_PIN_DISPLAY_BL = 44,\n    CFG_PIN_SERVO_1 = 45,\n    CFG_PIN_SERVO_2 = 46,\n    CFG_PIN_BTN_LEFT = 47,\n    CFG_PIN_BTN_RIGHT = 48,\n    CFG_PIN_BTN_UP = 49,\n    CFG_PIN_BTN_DOWN = 50,\n    CFG_PIN_BTN_MENU = 51,\n    CFG_PIN_LED_R = 52,\n    CFG_PIN_LED_G = 53,\n    CFG_PIN_LED_B = 54,\n    CFG_PIN_LED1 = 55,\n    CFG_PIN_LED2 = 56,\n    CFG_PIN_LED3 = 57,\n    CFG_PIN_LED4 = 58,\n    CFG_SPEAKER_VOLUME = 59,\n    CFG_PIN_A0 = 100,\n    CFG_PIN_A1 = 101,\n    CFG_PIN_A2 = 102,\n    CFG_PIN_A3 = 103,\n    CFG_PIN_A4 = 104,\n    CFG_PIN_A5 = 105,\n    CFG_PIN_A6 = 106,\n    CFG_PIN_A7 = 107,\n    CFG_PIN_A8 = 108,\n    CFG_PIN_A9 = 109,\n    CFG_PIN_A10 = 110,\n    CFG_PIN_A11 = 111,\n    CFG_PIN_A12 = 112,\n    CFG_PIN_A13 = 113,\n    CFG_PIN_A14 = 114,\n    CFG_PIN_A15 = 115,\n    CFG_PIN_D0 = 150,\n    CFG_PIN_D1 = 151,\n    CFG_PIN_D2 = 152,\n    CFG_PIN_D3 = 153,\n    CFG_PIN_D4 = 154,\n    CFG_PIN_D5 = 155,\n    CFG_PIN_D6 = 156,\n    CFG_PIN_D7 = 157,\n    CFG_PIN_D8 = 158,\n    CFG_PIN_D9 = 159,\n    CFG_PIN_D10 = 160,\n    CFG_PIN_D11 = 161,\n    CFG_PIN_D12 = 162,\n    CFG_PIN_D13 = 163,\n    CFG_PIN_D14 = 164,\n    CFG_PIN_D15 = 165,\n    CFG_NUM_NEOPIXELS = 200,\n    CFG_NUM_DOTSTARS = 201,\n    CFG_DEFAULT_BUTTON_MODE = 202,\n    CFG_SWD_ENABLED = 203,\n    CFG_FLASH_BYTES = 204,\n    CFG_RAM_BYTES = 205,\n    CFG_POWER_DEEPSLEEP_TIMEOUT = 212,\n    CFG_USER_CFG_0 = 2000,\n    CFG_USER_CFG_1 = 2001,\n    CFG_USER_CFG_2 = 2002,\n    CFG_USER_CFG_3 = 2003,\n    CFG_USER_CFG_4 = 2004,\n    CFG_USER_CFG_5 = 2005,\n    CFG_USER_CFG_6 = 2006,\n    CFG_USER_CFG_7 = 2007,\n    CFG_USER_CFG_8 = 2008,\n    CFG_USER_CFG_9 = 2009,\n    CFG_ARCADE_CFG_0 = 2100,\n    CFG_ARCADE_CFG_1 = 2101,\n    CFG_ARCADE_SCREEN_WIDTH = 2102,\n    CFG_ARCADE_SCREEN_HEIGHT = 2103,\n    BUTTON_ACTIVE_HIGH_PULL_DOWN = 17,\n    BUTTON_ACTIVE_HIGH_PULL_UP = 33,\n    BUTTON_ACTIVE_HIGH_PULL_NONE = 49,\n    BUTTON_ACTIVE_LOW_PULL_DOWN = 16,\n    BUTTON_ACTIVE_LOW_PULL_UP = 32,\n    BUTTON_ACTIVE_LOW_PULL_NONE = 48,\n    // built/codal/pxtapp/core---stm32f401re/platform.h\n    PXT_BOOTLOADER_CFG_ADDR = 134234056,\n    PAGE_SIZE = 1024,\n    DEV_NUM_PINS = 64,\n    IMAGE_BITS = 4,\n    PA_0 = 0,\n    PA_1 = 1,\n    PA_2 = 2,\n    PA_3 = 3,\n    PA_4 = 4,\n    PA_5 = 5,\n    PA_6 = 6,\n    PA_7 = 7,\n    PA_8 = 8,\n    PA_9 = 9,\n    PA_10 = 10,\n    PA_11 = 11,\n    PA_12 = 12,\n    PA_13 = 13,\n    PA_14 = 14,\n    PA_15 = 15,\n    PB_0 = 16,\n    PB_1 = 17,\n    PB_2 = 18,\n    PB_3 = 19,\n    PB_4 = 20,\n    PB_5 = 21,\n    PB_6 = 22,\n    PB_7 = 23,\n    PB_8 = 24,\n    PB_9 = 25,\n    PB_10 = 26,\n    PB_11 = 27,\n    PB_12 = 28,\n    PB_13 = 29,\n    PB_14 = 30,\n    PB_15 = 31,\n    PC_0 = 32,\n    PC_1 = 33,\n    PC_2 = 34,\n    PC_3 = 35,\n    PC_4 = 36,\n    PC_5 = 37,\n    PC_6 = 38,\n    PC_7 = 39,\n    PC_8 = 40,\n    PC_9 = 41,\n    PC_10 = 42,\n    PC_11 = 43,\n    PC_12 = 44,\n    PC_13 = 45,\n    PC_14 = 46,\n    PC_15 = 47,\n    // built/codal/pxtapp/core---stm32f401re/pxt.h\n    DEVICE_ID_BUTTON_SLIDE = 3000,\n    DEVICE_ID_MICROPHONE = 3001,\n    DEVICE_ID_FIRST_BUTTON = 4000,\n    DEVICE_ID_FIRST_TOUCHBUTTON = 4100,\n    // built/codal/pxtapp/core---stm32f401re/uf2hid.h\n    UF2_HID_H = 1,\n    // built/codal/pxtapp/pxtbase.h\n    MEMDBG_ENABLED = 0,\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    UInt32LE = 11,\n    UInt32BE = 12,\n    Float32LE = 13,\n    Float64LE = 14,\n    Float32BE = 15,\n    Float64BE = 16,\n    Undefined = 0,\n    Boolean = 1,\n    Number = 2,\n    String = 3,\n    Object = 4,\n    Function = 5,\n    // built/codal/pxtapp/pxtconfig.h\n    PXT_VM = 0,\n}\n","dmesg.cpp":"#include \"pxt.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <signal.h>\n#include <stdarg.h>\n#include <fcntl.h>\n\nstatic FILE *dmesgFile;\n\nstatic int dmesgPtr;\nstatic int dmesgSerialPtr;\nstatic char dmesgBuf[4096];\n\nvoid pxt::dumpDmesg() {\n    auto len = dmesgPtr - dmesgSerialPtr;\n    if (len == 0)\n        return;\n    sendSerial(dmesgBuf + dmesgSerialPtr, len);\n    dmesgSerialPtr = dmesgPtr;\n}\n\n\nstatic void dmesgRaw(const char *buf, uint32_t len) {\n    if (!dmesgFile) {\n        dmesgFile = fopen(\"/tmp/dmesg.txt\", \"w\");\n        if (!dmesgFile)\n            dmesgFile = stderr;\n    }\n\n    if (len > sizeof(dmesgBuf) / 2)\n        return;\n    if (dmesgPtr + len > sizeof(dmesgBuf)) {\n        dmesgPtr = 0;\n        dmesgSerialPtr = 0;\n    }\n    memcpy(dmesgBuf + dmesgPtr, buf, len);\n    dmesgPtr += len;\n    fwrite(buf, 1, len, dmesgFile);\n\n    fwrite(buf, 1, len, stderr);\n}\n\nstatic void dmesgFlushRaw() {\n    fflush(dmesgFile);\n\n#ifdef __linux__\n    // we only really care on RPi, so it may reboot/crash and we would like to see this file\n    fdatasync(fileno(dmesgFile));\n#else\n    //fsync(fileno(dmesgFile));\n#endif\n}\n\nextern \"C\" void vdmesg(const char *format, va_list arg) {\n    char buf[500];\n\n    snprintf(buf, sizeof(buf), \"[%8d] \", current_time_ms());\n    dmesgRaw(buf, strlen(buf));\n    vsnprintf(buf, sizeof(buf), format, arg);\n    dmesgRaw(buf, strlen(buf));\n    dmesgRaw(\"\\n\", 1);\n\n    dmesgFlushRaw();\n}\n\nextern \"C\" void dmesg(const char *format, ...) {\n    va_list arg;\n    va_start(arg, format);\n    vdmesg(format, arg);\n    va_end(arg);\n}\n\n","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum PulseValue {\n    //% block=high\n    High = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=low\n    Low = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    }\n\n\n    declare const enum PinEvent {\n    //% block=\"pulse high\"\n    PulseHigh = 4,  // DEVICE_PIN_EVT_PULSE_HI\n    //% block=\"pulse low\"\n    PulseLow = 5,  // DEVICE_PIN_EVT_PULSE_LO\n    //% block=\"rise\"\n    Rise = 2,  // DEVICE_PIN_EVT_RISE\n    //% block=\"fall\"\n    Fall = 3,  // DEVICE_PIN_EVT_FALL\n    }\n\n\n    declare const enum PinPullMode {\n    //% block=\"down\"\n    PullDown = 0,\n    //% block=\"up\"\n    PullUp = 1,\n    //% block=\"none\"\n    PullNone = 2,\n    }\n\n// Auto-generated. Do not edit. Really.\n","keys.cpp":"#include \"pxt.h\"\n\nnamespace pxt {\nvoid initKeys() {}\n\n//% expose\nint pressureLevelByButtonId(int btnId, int codalId) {\n    return 0; // TODO\n}\n\n//% expose\nvoid setupButton(int buttonId, int key) {\n    (void)buttonId;\n    (void)key;\n    // not needed on RPi\n}\n\n} // namespace pxt","ns.ts":"/**\n * Events and data from sensors.\n */\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\n//% groups='[\"other\", \"More\"]'\nnamespace input {\n}\n\n/**\n * Servos\n */\n//% color=\"#03AA74\" weight=88 icon=\"\\uf021\"\nnamespace servos {\n\n}\n\n/**\n * A Joint Asynchronous Communications, Device Agnostic Control.\n */\n//% color=\"#E79251\" weight=1 icon=\"\\uf185\"\n//% groups='[\"Broadcast\", \"Console\", \"Control\"]'\n//% blockGap=8\nnamespace jacdac {\n\n}","pins.h":"#ifndef __PXT_PINS_H\n#define __PXT_PINS_H\n\n#define BUTTON_ACTIVE_HIGH_PULL_DOWN (ACTIVE_HIGH | 0x10)\n#define BUTTON_ACTIVE_HIGH_PULL_UP (ACTIVE_HIGH | 0x20)\n#define BUTTON_ACTIVE_HIGH_PULL_NONE (ACTIVE_HIGH | 0x30)\n#define BUTTON_ACTIVE_LOW_PULL_DOWN (ACTIVE_LOW | 0x10)\n#define BUTTON_ACTIVE_LOW_PULL_UP (ACTIVE_LOW | 0x20)\n#define BUTTON_ACTIVE_LOW_PULL_NONE (ACTIVE_LOW | 0x30)\n\n#define PIN(name) ((PinName)pxt::getConfig(CFG_PIN_##name, -1))\n#define LOOKUP_PIN(name) pxt::lookupPin(PIN(name))\n\n// these can be overridden in platform.h\n#ifndef CODAL_PIN\n#define CODAL_PIN CODAL_MBED::Pin\n#endif\n\n#ifndef CODAL_TIMER\n#define CODAL_TIMER CODAL_MBED::Timer\n#endif\n\n#ifndef CODAL_SPI\n#define CODAL_SPI CODAL_MBED::SPI\n#endif\n\n#ifndef CODAL_SERIAL\n#define CODAL_SERIAL CODAL_MBED::Serial\n#endif\n\n#ifndef IS_ANALOG_PIN\n#define IS_ANALOG_PIN(id) ((DEV_ANALOG_PINS >> (id)) & 1)\n#endif\n\ntypedef CODAL_PIN DevicePin;\n\ntypedef DevicePin *DigitalInOutPin;\ntypedef DevicePin *AnalogInOutPin;\ntypedef DevicePin *AnalogInPin;\ntypedef DevicePin *AnalogOutPin;\ntypedef DevicePin *PwmPin;\ntypedef DevicePin *PwmOnlyPin;\ntypedef Button *Button_;\n\nnamespace pxt {\nDevicePin *getPin(int id);\nDevicePin *getPinCfg(int key);\nDevicePin *lookupPin(int pinName);\nDevicePin *lookupPinCfg(int key);\nvoid linkPin(int from, int to);\nCodalComponent *lookupComponent(int id);\n}\n\n#define PINOP(op) name->op\n\n#endif\n","platform.cpp":"#include \"pxt.h\"\n\n#include <unistd.h>\n#include <stdio.h>\n#include <fcntl.h>\n\nnamespace pxt {\n\nstatic void initRandomSeed() {\n    int seed = 0xC0DA1;\n    int fd = open(\"/dev/urandom\", O_RDONLY);\n    read(fd, &seed, sizeof(seed));\n    close(fd);\n    seedRandom(seed);\n}\n\nvoid sendSerial(const char *data, int len) {\n    /*\n    if (!serial) {\n        serial = new codal::_mbed::Serial(USBTX, NC);\n        serial->baud(9600);\n    }\n    serial->send((uint8_t*)data, len);\n    */\n}\n\nextern \"C\" void drawPanic(int code)\n{\n    // TODO\n}\n\n\nextern \"C\" void target_init()\n{\n    initRandomSeed();\n}\n\nvoid updateScreen(Image_ img);\n\nvoid screen_init() {\n    updateScreen(NULL);\n}\n\n}\n\n","platform.h":"#ifndef __PXT_PLATFORM_H\n#define __PXT_PLATFORM_H\n\n#define PAGE_SIZE 1024 // not really\n\n#define DEV_NUM_PINS 28\n\n#define DEV_PWM_PINS 0xffffffffULL\n#define DEV_AIN_PINS 0ULL\n\n// Codal doesn't yet distinguish between PWM and AIN\n#define DEV_ANALOG_PINS (DEV_PWM_PINS | DEV_AIN_PINS)\n\n#define CODAL_PIN ZPin\n#define CODAL_TIMER ZTimer\n#define CODAL_SPI ZSPI\n#define CODAL_I2C ZI2C\n\nconst char *vm_settings_dir(void);\n#define SETTINGSDIR vm_settings_dir()\n\nnamespace pxt {\n\nclass ZPin;\nclass AbstractButton;\nclass MultiButton;\nclass CodalComponent;\n\ntypedef void (*reset_fn_t)();\nvoid registerResetFunction(reset_fn_t fn);\nvoid soft_panic(int errorCode);\n} // namespace pxt\n\n#define IMAGE_BITS 4\n\n#define PXT_IN_ISR() false\n\n#define GC_BLOCK_SIZE (1024 * 64)\n\n#define PXT_REGISTER_RESET(fn) pxt::registerResetFunction(fn)\n\n#ifdef __APPLE__\n#include \"TargetConditionals.h\"\n#if TARGET_OS_IPHONE\n#define PXT_IOS 1\n#endif\n#endif\n\n#if defined(PXT64) || defined(__MINGW32__)\n#define GC_BASE 0x2000000000\n#define GC_PAGE_SIZE (64 * 1024)\n\n// always allocate 1M of heap\n#define PXT_VM_HEAP_ALLOC_BITS 20\nextern uint8_t *gcBase;\n#define PXT_IS_READONLY(v)                                                                         \\\n    (!isPointer(v) || (((uintptr_t)v - (uintptr_t)gcBase) >> PXT_VM_HEAP_ALLOC_BITS) != 0)\n\n#else // PXT32\n#define GC_BASE 0x20000000\n#define GC_PAGE_SIZE 4096\n\n#endif // PXT32 vs 64\n\n#endif\n","platform_includes.h":"#include <unistd.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n#include <sys/types.h>\n\n#define PROCESSOR_WORD_TYPE uintptr_t\n","pxt.h":"#ifndef __PXT_H\n#define __PXT_H\n\n#include \"pxtbase.h\"\n\n#include \"vm.h\"\n\n#define OUTPUT_BITS 12\n\n#define DEVICE_EVT_ANY 0\n#define DEVICE_ID_NOTIFY_ONE 1022\n#define DEVICE_ID_NOTIFY 1023\n\nnamespace pxt {\nvoid raiseEvent(int id, int event);\nint allocateNotifyEvent();\nvoid sleep_core_us(uint64_t us);\n\nvoid target_disable_irq();\nvoid target_enable_irq();\n\nclass Button;\ntypedef Button *Button_;\n\nextern \"C\" void target_init();\n\nextern volatile bool paniced;\nextern char **initialArgv;\nvoid target_exit();\nextern volatile int panicCode;\n\n// Buffer, Sound, and Image share representation.\ntypedef Buffer Sound;\n\n} // namespace pxt\n\n#undef PXT_MAIN\n#define PXT_MAIN                                                                                   \\\n    int main(int argc, char **argv) {                                                              \\\n        pxt::initialArgv = argv;                                                                   \\\n        pxt::vmStart();                                                                            \\\n        return 0;                                                                                  \\\n    }\n\n#undef PXT_SHIMS_BEGIN\n#define PXT_SHIMS_BEGIN                                                                            \\\n    namespace pxt {                                                                                \\\n    const OpcodeDesc staticOpcodes[] __attribute__((aligned(0x20))) = {\n\n#undef PXT_SHIMS_END\n#define PXT_SHIMS_END                                                                              \\\n    { 0, 0, 0 }                                                                                    \\\n    }                                                                                              \\\n    ;                                                                                              \\\n    }\n\n#endif\n","pxt.json":"{\n    \"name\": \"core---vm\",\n    \"description\": \"The core library for Codal-based targets\",\n    \"dependencies\": {\n        \"base\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"Makefile\",\n        \"dal.d.ts\",\n        \"scheduler.cpp\",\n        \"config.cpp\",\n        \"target.cpp\",\n        \"pxt.h\",\n        \"platform.h\",\n        \"platform.cpp\",\n        \"pxtcore.h\",\n        \"pins.h\",\n        \"control.cpp\",\n        \"shims.d.ts\",\n        \"enums.d.ts\",\n        \"ns.ts\",\n        \"timer.ts\",\n        \"platform_includes.h\",\n        \"codalemu.cpp\",\n        \"dmesg.cpp\",\n        \"keys.cpp\",\n        \"vm.cpp\",\n        \"vmload.cpp\",\n        \"vm.h\",\n        \"vmcache.cpp\",\n        \"verify.cpp\",\n        \"pxtparts.json\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"yotta\": {\n        \"config\": {\n            \"codal\": {\n                \"component_count\": 64,\n                \"dmesg_buffer_size\": 1024\n            }\n        }\n    },\n    \"dalDTS\": {\n        \"includeDirs\": [\n            \"libraries/codal-core/inc\",\n            \"pxtapp\"\n        ],\n        \"excludePrefix\": [\n            \"JD_\",\n            \"USB_\",\n            \"REQUEST_\",\n            \"LIS3DH_\",\n            \"FXOS8700_\",\n            \"HF2_\",\n            \"PXT_REF_TAG_\",\n            \"MS_\",\n            \"SCSI_\",\n            \"MAG_\",\n            \"MAG3\",\n            \"MPU6\",\n            \"MADCTL\",\n            \"MMA8\"\n        ]\n    }\n}\n","pxtcore.h":"#ifndef __PXTCORE_H\n#define __PXTCORE_H\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdarg.h>\n\nnamespace pxt {\nvoid *gcAllocBlock(size_t sz);\nvoid vm_stack_trace();\n}\n\nextern \"C\" void dmesg(const char *fmt, ...);\nextern \"C\" void vdmesg(const char *format, va_list arg);\n#define DMESG ::dmesg\n\nstatic inline void itoa(int v, char *dst) {\n    snprintf(dst, 30, \"%d\", v);\n}\n\nextern \"C\" void *xmalloc(size_t sz);\n#define xfree free\n\n#define GC_ALLOC_BLOCK gcAllocBlock\n\n#ifndef POKY\n// This seems to degrade performance - probably due to cache size\n//#define GC_BLOCK_SIZE (1024 * 64)\n#endif\n\n#define PXT_HARD_FLOAT 1\n\n#endif\n","pxtparts.json":"{\n    \"neopixel\": {\n        \"simulationBehavior\": \"neopixel\",\n        \"visual\": {\n            \"builtIn\": \"neopixel\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 19,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 28,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createStrip,light.createNeoPixelStrip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"dotstar\": {\n        \"simulationBehavior\": \"dotstar\",\n        \"visual\": {\n            \"builtIn\": \"dotstar\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 1\n                },\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"light.createAPA102Strip\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"dataPin\"\n                },\n                {\n                    \"pinInstantiationIdx\": 1,\n                    \"partParameter\": \"clkPin\"\n                },\n                {\n                    \"partParameter\": \"mode\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },\n    \"pixels\": {\n        \"simulationBehavior\": \"pixels\",\n        \"visual\": { \n            \"builtIn\": \"pixels\",\n            \"width\": 58,\n            \"height\": 113,\n            \"pinDistance\": 9,\n            \"pinLocations\": [\n                {\n                    \"x\": 10,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 17,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 24,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 31,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"numberOfPins\": 4,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"MOSI\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"SCK\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"solder\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1, 2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    3\n                ]\n            }\n        ]\n    },    \n    \"buttons\": {\n        \"simulationBehavior\": \"buttons\",\n        \"visual\": {\n            \"builtIn\": \"buttons\",\n            \"width\": 75,\n            \"height\": 45,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 30,\n                    \"y\": 45\n                }\n            ]\n        },\n        \"numberOfPins\": 2,\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"Button.onEvent,Button.isPressed,Button.wasPressed\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"button\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"slideswitch\": {\n        \"numberOfPins\": 3,\n        \"simulationBehavior\": \"slideswitch\",\n        \"visual\": {\n            \"builtIn\": \"slideswitch\",\n            \"width\": 100,\n            \"height\": 100,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalRead,DigitalInOutPin.onPulsed,DigitalInOutPin.onEvent\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"pin\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"microservo\": {\n        \"simulationBehavior\": \"microservo\",\n        \"visual\": {\n            \"builtIn\": \"microservo\",\n            \"width\": 74.85,\n            \"height\": 200,\n            \"pinDistance\": 10,\n            \"pinLocations\": [\n                {\n                    \"x\": 30,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 37,\n                    \"y\": 5\n                },\n                {\n                    \"x\": 45,\n                    \"y\": 5\n                }\n            ]\n        },\n        \"numberOfPins\": 3,\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"+Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"PwmOnlyPin.servoWrite,servos.Servo.setAngle,servos.Servo.run,servos.Servo.setPulse\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    2\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    0,\n                    1\n                ]\n            }\n        ]\n    },\n    \"led\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"DigitalInOutPin.digitalWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"analogled\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"builtIn\": \"led\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"led\",\n        \"pinDefinitions\": [\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogOutPin.analogWrite\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    },\n    \"photocell\": {\n        \"numberOfPins\": 3,\n        \"visual\": {\n            \"builtIn\": \"photocell\",\n            \"width\": 68,\n            \"height\": 180,\n            \"pinDistance\": 15,\n            \"pinLocations\": [\n                {\n                    \"x\": 0,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 15,\n                    \"y\": 0\n                },\n                {\n                    \"x\": 60,\n                    \"y\": 0\n                }\n            ]\n        },\n        \"simulationBehavior\": \"photocell\",\n        \"pinDefinitions\": [\n            {\n                \"target\": \"threeVolt\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": {\n                    \"pinInstantiationIdx\": 0\n                },\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"male\",\n                \"orientation\": \"-Z\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"function\",\n            \"fullyQualifiedName\": \"AnalogInPin.analogRead\",\n            \"argumentRoles\": [\n                {\n                    \"pinInstantiationIdx\": 0,\n                    \"partParameter\": \"name\"\n                }\n            ]\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","scheduler.cpp":"#include \"pxt.h\"\n\n#include <stdlib.h>\n#include <stdio.h>\n#include <sys/time.h>\n#include <time.h>\n#include <unistd.h>\n#include <signal.h>\n#include <sys/types.h>\n#include <errno.h>\n\n#ifndef PXT_ESP32\n// __MINGW32__ is defined on both mingw32 and mingw64\n#ifdef __MINGW32__\n#include <windows.h>\n#else\n#include <sys/mman.h>\n#endif\n#endif\n\n#define HANDLER_RUNNING 0x0001\n\n// should this be something like CXX11 or whatever?\n#define THROW throw()\n#define THREAD_DBG(...)\n\nstatic uint8_t in_xmalloc_panic;\n\nvoid *xmalloc(size_t sz) {\n    auto r = malloc(sz);\n    if (r == NULL) {\n        DMESG(\"failed to allocate %d bytes\", sz);\n        if (in_xmalloc_panic) {\n            target_panic(PANIC_GC_OOM);\n        } else {\n            in_xmalloc_panic = 1;\n            soft_panic(PANIC_GC_OOM); // this can happen on esp32 etc; shouldn't on linux/ios etc\n        }\n    }\n    return r;\n}\n\nvoid *operator new(size_t size) {\n    return xmalloc(size);\n}\nvoid *operator new[](size_t size) {\n    return xmalloc(size);\n}\n\nvoid operator delete(void *p)THROW {\n    xfree(p);\n}\nvoid operator delete[](void *p) THROW {\n    xfree(p);\n}\n\nuint8_t *gcBase;\n\nnamespace pxt {\n\n#ifndef PXT_ESP32\nstatic uint64_t startTime;\n#endif\n\nFiberContext *allFibers;\nFiberContext *currentFiber;\nstatic pthread_mutex_t eventMutex;\nstatic pthread_cond_t newEventBroadcast;\n\nstatic struct Event *eventHead, *eventTail;\n\nstruct Event {\n    struct Event *next;\n    int source;\n    int value;\n};\n\nEvent lastEvent;\n\nEvent *mkEvent(int source, int value) {\n    auto res = new Event();\n    memset(res, 0, sizeof(Event));\n    res->source = source;\n    res->value = value;\n    return res;\n}\n\nvolatile int panicCode;\nextern \"C\" void drawPanic(int code);\n\nvoid schedule() {\n    auto f = currentFiber;\n    if (!f->wakeTime && !f->waitSource)\n        oops(55);\n    f->resumePC = f->pc;\n    f->pc = NULL; // this will break the exec_loop()\n}\n\nvoid dmesg_flush();\n\nstatic void panic_core(int error_code) {\n    int prevErr = errno;\n\n    panicCode = error_code;\n\n    drawPanic(error_code);\n\n    DMESG(\"PANIC %d\", error_code % 1000);\n    DMESG(\"errno=%d %s\", prevErr, strerror(prevErr));\n\n    dmesg_flush();\n}\n\nextern \"C\" void target_panic(int error_code) {\n    panic_core(error_code);\n\n#if defined(PXT_ESP32)\n    // sleep_core_us(5 * 1000 * 1000);\n    abort();\n#elif defined(PXT_VM)\n    systemReset();\n#else\n    while (1)\n        sleep_core_us(10000);\n#endif\n}\n\nDLLEXPORT int pxt_get_panic_code() {\n    return panicCode;\n}\n\nvoid ets_log_dmesg();\nvoid soft_panic(int errorCode) {\n    if (errorCode >= 999)\n        errorCode = 999;\n    if (errorCode <= 0)\n        errorCode = 1;\n    vm_stack_trace();\n    panic_core(1000 + errorCode);\n#if defined(PXT_ESP32)\n    ets_log_dmesg();\n    sleep_core_us(4000000);\n    abort();\n#else\n    systemReset();\n#endif\n}\n\nvoid sleep_core_us(uint64_t us) {\n#ifdef PXT_ESP32\n    uint64_t endp = esp_timer_get_time() + us;\n    while (esp_timer_get_time() < endp)\n        ;\n#else\n    struct timespec ts;\n    ts.tv_sec = us / 1000000;\n    ts.tv_nsec = (us % 1000000) * 1000;\n    while (nanosleep(&ts, &ts))\n        ;\n#endif\n}\n\nvoid target_yield() {\n#ifdef PXT_ESP32\n    vTaskDelay(1);\n#else\n    sleep_core_us(1000);\n#endif\n}\n\nvoid sleep_ms(uint32_t ms) {\n    currentFiber->wakeTime = current_time_ms() + ms;\n    schedule();\n}\n\nvoid sleep_us(uint64_t us) {\n    if (us > 20000) {\n        sleep_ms((uint32_t)(us / 1000));\n    } else {\n        sleep_core_us(us);\n    }\n}\n\n#ifndef PXT_ESP32\nstatic uint64_t currTime() {\n    struct timeval tv;\n    gettimeofday(&tv, NULL);\n    return tv.tv_sec * 1000000LL + tv.tv_usec;\n}\n\nuint64_t current_time_us() {\n    if (!startTime)\n        startTime = currTime();\n    return currTime() - startTime;\n}\n#endif\n\nint current_time_ms() {\n    return (int)(current_time_us() / 1000);\n}\n\nvoid disposeFiber(FiberContext *t) {\n    if (allFibers == t) {\n        allFibers = t->next;\n    } else {\n        for (auto tt = allFibers; tt; tt = tt->next) {\n            if (tt->next == t) {\n                tt->next = t->next;\n                break;\n            }\n        }\n    }\n\n    // DMESG(\"free: %p %p\", t, t->stackCopy);\n\n    xfree(t->stackCopy);\n    xfree(t);\n\n    if (currentFiber == t)\n        currentFiber = NULL;\n}\n\n#define INITIAL_STACK_COPY_SIZE 16\n\nFiberContext *setupThread(Action a, TValue arg = 0, HandlerBinding *hb = NULL) {\n#if 0\n    int numThreads = 0;\n    for (auto p = allFibers; p; p = p->next)\n        numThreads++;\n    DMESG(\"setup thread: %p #%d\", a, numThreads);\n    //if (numThreads > 10)\n    //    abort();\n#endif\n    auto t = (FiberContext *)xmalloc(sizeof(FiberContext));\n    memset(t, 0, sizeof(*t));\n    if (!vmImg->stackBase) {\n        vmImg->stackBase = (TValue *)xmalloc(VM_STACK_SIZE * sizeof(TValue));\n        vmImg->stackTop = vmImg->stackBase + VM_STACK_SIZE;\n        vmImg->stackLimit = vmImg->stackBase + VM_MAX_FUNCTION_STACK + 5;\n    }\n    t->stackCopy = (TValue *)xmalloc(sizeof(TValue) * INITIAL_STACK_COPY_SIZE);\n    t->stackCopySize = INITIAL_STACK_COPY_SIZE;\n    t->sp = vmImg->stackTop - 8;\n\n    // DMESG(\"thr: %p %p\", t, t->stackCopy);\n\n    auto ptr = t->stackCopy;\n    *ptr++ = TAG_STACK_BOTTOM;\n    *ptr++ = 0;\n    *ptr++ = arg;\n    *ptr++ = 0;\n    *ptr++ = 0;\n    *ptr++ = 0;\n    *ptr++ = 0;\n    *ptr++ = (TValue)0xf00df00df00df00d;\n\n    t->handlerBinding = hb;\n    auto ra = (RefAction *)a;\n    // we only pass 1 argument, but can in fact handle up to 4\n    if (ra->numArgs > 2)\n        target_panic(PANIC_INVALID_IMAGE);\n    t->currAction = ra;\n    t->resumePC = actionPC(ra);\n\n    t->img = vmImg;\n    t->imgbase = (uint16_t *)vmImg->dataStart;\n\n    // add at the end\n    if (allFibers)\n        for (auto p = allFibers; p; p = p->next) {\n            if (!p->next) {\n                p->next = t;\n                break;\n            }\n        }\n    else\n        allFibers = t;\n\n    return t;\n}\n\nvoid runInParallel(Action a) {\n    setupThread(a);\n}\n\nvoid runForever(Action a) {\n    auto f = setupThread(a);\n    f->foreverPC = f->resumePC;\n}\n\nvoid waitForEvent(int source, int value) {\n    currentFiber->waitSource = source;\n    currentFiber->waitValue = value;\n    schedule();\n}\n\nFiberContext *suspendFiber() {\n    currentFiber->waitSource = PXT_WAIT_SOURCE_PROMISE;\n    schedule();\n    return currentFiber;\n}\n\nvoid resumeFiberWithFn(FiberContext *ctx, fiber_resume_t fn, void *arg) {\n    if (ctx->waitSource != PXT_WAIT_SOURCE_PROMISE)\n        oops(52);\n    ctx->waitSource = 0;\n    ctx->wakeFn = fn;\n    ctx->wakeFnArg = arg;\n}\n\nvoid resumeFiber(FiberContext *ctx, TValue v) {\n    if (ctx->waitSource != PXT_WAIT_SOURCE_PROMISE)\n        oops(52);\n    ctx->waitSource = 0;\n    ctx->r0 = v;\n}\n\nstatic void startHandler(HandlerBinding *hb, Event &e) {\n    if (!hb)\n        return;\n    lastEvent = e; // this is quite racy\n    if (hb->flags & HANDLER_RUNNING) {\n        auto tmp = mkEvent(e.source, e.value);\n        if (hb->pending == NULL) {\n            hb->pending = tmp;\n        } else {\n            int numev = 0;\n            auto p = hb->pending;\n            for (; p->next; p = p->next)\n                numev++;\n            if (numev >= 10) {\n                xfree(tmp);\n                return;\n            }\n            p->next = tmp;\n        }\n    } else {\n        hb->flags |= HANDLER_RUNNING;\n        setupThread(hb->action, fromInt(e.value), hb);\n    }\n}\n\nstatic void dispatchEvent(Event &e) {\n    startHandler(findBinding(e.source, e.value), e);\n    startHandler(findBinding(e.source, DEVICE_EVT_ANY), e);\n}\n\nstatic void wakeFibers() {\n    for (;;) {\n        pthread_mutex_lock(&eventMutex);\n        if (eventHead == NULL) {\n            pthread_mutex_unlock(&eventMutex);\n            return;\n        }\n        Event *ev = eventHead;\n        eventHead = ev->next;\n        if (eventHead == NULL)\n            eventTail = NULL;\n        pthread_mutex_unlock(&eventMutex);\n\n        for (auto thr = allFibers; thr; thr = thr->next) {\n            if (thr->waitSource == 0)\n                continue;\n            if (thr->waitValue != ev->value && thr->waitValue != DEVICE_EVT_ANY)\n                continue;\n            if (thr->waitSource == ev->source) {\n                thr->waitSource = 0;\n            } else if (thr->waitSource == DEVICE_ID_NOTIFY && ev->source == DEVICE_ID_NOTIFY_ONE) {\n                thr->waitSource = 0;\n                break; // do not wake up any other threads\n            }\n        }\n\n        dispatchEvent(*ev);\n        delete ev;\n    }\n}\n\nstatic void saveStack() {\n    auto f = currentFiber;\n    if (!f)\n        return;\n    int sizeNeeded = vmImg->stackTop - f->sp;\n    // DMESG(\"save %d %p\", sizeNeeded, f);\n    if (!f->stackCopy || sizeNeeded > f->stackCopySize) {\n        xfree(f->stackCopy);\n        f->stackCopySize = sizeNeeded + 10;\n        f->stackCopy = (TValue *)xmalloc(f->stackCopySize * sizeof(TValue));\n        // DMESG(\" -> %p\", f->stackCopy);\n    }\n    memcpy(f->stackCopy, f->sp, sizeNeeded * sizeof(TValue));\n}\n\nstatic void restoreStack() {\n    auto f = currentFiber;\n    memcpy(f->sp, f->stackCopy, (uint8_t *)vmImg->stackTop - (uint8_t *)f->sp);\n}\n\nstatic void mainRunLoop() {\n    FiberContext *f = NULL;\n    for (;;) {\n        if (panicCode)\n            return;\n        wakeFibers();\n        auto now = current_time_ms();\n        auto fromBeg = false;\n        if (!f) {\n            f = allFibers;\n            fromBeg = true;\n        }\n        while (f) {\n            if (f->wakeTime && now >= (int)f->wakeTime)\n                f->wakeTime = 0;\n            if (!f->wakeTime && !f->waitSource)\n                break;\n            f = f->next;\n        }\n        if (f) {\n            if (currentFiber != f) {\n                saveStack();\n                currentFiber = f;\n                restoreStack();\n            }\n            f->pc = f->resumePC;\n            f->resumePC = NULL;\n            if (f->wakeFn) {\n                auto fn = f->wakeFn;\n                f->wakeFn = NULL;\n                f->r0 = fn(f->wakeFnArg);\n                if (f->wakeTime || f->waitSource)\n                    continue; // we got suspended again\n            }\n            exec_loop(f);\n            if (panicCode)\n                return;\n            auto n = f->next;\n            if (f->resumePC == NULL) {\n                if (f->foreverPC) {\n                    f->resumePC = f->foreverPC;\n                    f->wakeTime = current_time_ms() + 20;\n                    // restore stack, as setupThread() does it\n                    for (int i = 0; i < 5; ++i) {\n                        if (*--f->sp == TAG_STACK_BOTTOM)\n                            break;\n                    }\n                    if (*f->sp != TAG_STACK_BOTTOM)\n                        target_panic(PANIC_INVALID_IMAGE);\n                } else {\n                    auto hb = f->handlerBinding;\n                    if (hb) {\n                        auto pev = hb->pending;\n                        if (pev) {\n                            hb->pending = pev->next;\n                            setupThread(hb->action, fromInt(pev->value), hb);\n                            xfree(pev);\n                        } else {\n                            f->handlerBinding->flags &= ~HANDLER_RUNNING;\n                        }\n                    }\n                    disposeFiber(f);\n                }\n            }\n            f = n;\n        } else if (fromBeg) {\n            target_yield();\n        }\n    }\n}\n\nint allocateNotifyEvent() {\n    static volatile int notifyId;\n    return ++notifyId;\n}\n\nvoid raiseEvent(int id, int event) {\n    auto e = mkEvent(id, event);\n    pthread_mutex_lock(&eventMutex);\n    if (eventTail == NULL) {\n        if (eventHead != NULL)\n            oops(51);\n        eventHead = eventTail = e;\n    } else {\n        eventTail->next = e;\n        eventTail = e;\n    }\n    pthread_cond_broadcast(&newEventBroadcast);\n    pthread_mutex_unlock(&eventMutex);\n}\n\nDLLEXPORT void pxt_raise_event(int id, int event) {\n    raiseEvent(id, event);\n}\n\nvoid registerWithDal(int id, int event, Action a, int flags) {\n    // TODO support flags\n    setBinding(id, event, a);\n}\n\nuint32_t afterProgramPage() {\n    return 0;\n}\n\nchar **initialArgv;\n\nvoid screen_init();\nvoid initKeys();\nvoid target_startup();\n\nvoid initRuntime() {\n    current_time_ms();\n    target_startup();\n\n    setupThread((TValue)vmImg->entryPoint);\n\n    target_init();\n    screen_init();\n    initKeys();\n\n    DMESG(\"start main loop\");\n\n    mainRunLoop();\n    systemReset();\n}\n\nvoid *gcAllocBlock(size_t sz) {\n#ifdef PXT_ESP32\n    void *r = xmalloc(sz);\n#else\n    static uint8_t *currPtr = (uint8_t *)GC_BASE;\n    sz = (sz + GC_PAGE_SIZE - 1) & ~(GC_PAGE_SIZE - 1);\n#if defined(PXT64) || defined(__MINGW32__)\n    if (!gcBase) {\n        gcBase = (uint8_t *)xmalloc(1 << PXT_VM_HEAP_ALLOC_BITS);\n        currPtr = gcBase;\n    }\n    void *r = currPtr;\n    if ((uint8_t *)currPtr - gcBase > (1 << PXT_VM_HEAP_ALLOC_BITS) - (int)sz)\n        soft_panic(20);\n#else\n    void *r = mmap(currPtr, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);\n    if (r == MAP_FAILED) {\n        DMESG(\"mmap %p failed; err=%d\", currPtr, errno);\n        target_panic(PANIC_INTERNAL_ERROR);\n    }\n#endif\n    currPtr = (uint8_t *)r + sz;\n#endif\n\n    if (isReadOnly((TValue)r)) {\n        DMESG(\"mmap returned read-only address: %p\", r);\n        target_panic(PANIC_INTERNAL_ERROR);\n    }\n    return r;\n}\n\nvoid gcProcessStacks(int flags) {\n    int cnt = 0;\n    for (auto f = allFibers; f; f = f->next) {\n        TValue *end, *ptr;\n        if (f == currentFiber) {\n            end = vmImg->stackTop;\n            ptr = f->sp;\n        } else {\n            end = f->stackCopy + (vmImg->stackTop - f->sp);\n            ptr = f->stackCopy;\n        }\n        gcProcess((TValue)f->currAction);\n        gcProcess((TValue)f->r0);\n        if (flags & 2)\n            DMESG(\"RS%d:%p/%d\", cnt++, ptr, end - ptr);\n        // VLOG(\"mark: %p - %p\", ptr, end);\n        while (ptr < end) {\n            gcProcess(*ptr++);\n        }\n    }\n}\n\n#define MAX_RESET_FN 32\nstatic reset_fn_t resetFunctions[MAX_RESET_FN];\n\nvoid registerResetFunction(reset_fn_t fn) {\n    for (int i = 0; i < MAX_RESET_FN; ++i) {\n        if (!resetFunctions[i]) {\n            resetFunctions[i] = fn;\n            return;\n        }\n    }\n\n    target_panic(PANIC_INTERNAL_ERROR);\n}\n\nvoid systemReset() {\n#ifdef PXT_ESP32\n    esp_restart();\n#else\n    if (!panicCode)\n        panicCode = -1;\n\n    dmesg(\"TARGET RESET\");\n\n    gcFreeze();\n\n    for (int i = 0; i < MAX_RESET_FN; ++i) {\n        auto fn = resetFunctions[i];\n        if (fn)\n            fn();\n    }\n\n    coreReset(); // clears handler bindings\n\n    currentFiber = NULL;\n    while (allFibers) {\n        disposeFiber(allFibers);\n    }\n\n    // this will consume all events, but won't dispatch anything, since all listener maps are empty\n    wakeFibers();\n\n    // mark all GC memory as free\n    gcReset();\n\n    pthread_exit(NULL);\n#endif\n}\n\n} // namespace pxt\n","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace control {\n\n    /**\n     * Announce that an event happened to registered handlers.\n     * @param src ID of the Component that generated the event\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.\n     */\n    //% weight=21 blockGap=12 blockId=\"control_raise_event\"\n    //% block=\"raise event|from %src|with value %value\" blockExternalInputs=1\n    //% help=control/raise-event shim=control::raiseEvent\n    function raiseEvent(src: int32, value: int32): void;\n\n    /**\n     * Allocates the next user notification event\n     */\n    //% help=control/allocate-notify-event shim=control::allocateNotifyEvent\n    function allocateNotifyEvent(): int32;\n\n    /**\n     * Determine the version of system software currently running.\n     */\n    //% blockId=\"control_device_dal_version\" block=\"device dal version\"\n    //% help=control/device-dal-version shim=control::deviceDalVersion\n    function deviceDalVersion(): string;\n\n    /** Write data to DMESG debugging buffer. */\n    //% shim=control::dmesg\n    function dmesg(s: string): void;\n\n    /**\n     * Determines if the USB has been enumerated.\n     */\n    //% shim=control::isUSBInitialized\n    function isUSBInitialized(): boolean;\n}\ndeclare namespace serial {\n\n    /** Send DMESG debug buffer over serial. */\n    //% shim=serial::writeDmesg\n    function writeDmesg(): void;\n}\n\n// Auto-generated. Do not edit. Really.\n","target.cpp":"#include \"pxt.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <signal.h>\n#include <stdarg.h>\n#include <fcntl.h>\n\n//#define LOG_TO_STDERR 1\n//#define LOG_TO_FILE 1\n\nnamespace pxt {\n\nvoid target_exit() {\n    systemReset();\n}\n\nextern \"C\" void target_reset() {\n    vmStartFromUser(NULL);\n}\n\nvoid target_startup() {}\n\n#ifdef LOG_TO_FILE\nstatic FILE *dmesgFile;\n#endif\n\n#define LOG_QUEUE_SIZE (128 * 1024)\nclass LogQueue {\n    void writeCore(const char *buf, int len);\n\n  public:\n    int ptr;\n    char buffer[LOG_QUEUE_SIZE];\n    int rdPtr;\n    int numWrap;\n    LogQueue();\n    int write(const char *buf, int len);\n    int read(char *buf, int len);\n};\n\nLogQueue::LogQueue() {\n    ptr = 0;\n    rdPtr = 0;\n    numWrap = 0;\n    memset(buffer, 0, sizeof(buffer));\n}\n\nvoid LogQueue::writeCore(const char *buf, int len) {\n    memcpy(buffer + ptr, buf, len);\n    // did we pass it?\n    if (ptr < rdPtr && rdPtr <= ptr + len)\n        rdPtr = -1;\n    ptr += len;\n}\n\nint LogQueue::read(char *buf, int len) {\n    if (rdPtr < 0) {\n        if (numWrap == 0) {\n            rdPtr = 0;\n        } else {\n            rdPtr = ptr + 1;\n        }\n    }\n\n    if (rdPtr <= ptr) {\n        int av = ptr - rdPtr;\n        if (len > av)\n            len = av;\n        memcpy(buf, buffer + rdPtr, len);\n        rdPtr += len;\n    } else {\n        int latter = sizeof(buffer) - rdPtr;\n\n        if (latter >= len) {\n            memcpy(buf, buffer + rdPtr, len);\n            rdPtr += len;\n        } else {\n            memcpy(buf, buffer + rdPtr, latter);\n            buf += latter;\n            int len2 = len - latter;\n            if (len2 > ptr)\n                len2 = ptr;\n            memcpy(buf, buffer, len2);\n            rdPtr = len2;\n            len = latter + len2;\n        }\n    }\n\n    if (rdPtr >= (int)sizeof(buffer))\n        rdPtr = 0;\n\n    return len;\n}\n\nint LogQueue::write(const char *buf, int len) {\n    if (len > (int)sizeof(buffer) / 2)\n        return -1;\n\n    int left = sizeof(buffer) - ptr;\n\n    if (left < len + 1) {\n        writeCore(buf, left);\n        buf += left;\n        len -= left;\n        ptr = 0;\n        numWrap++;\n        if (rdPtr == 0)\n            rdPtr = -1;\n    }\n\n    writeCore(buf, len);\n    buffer[ptr] = 0;\n\n    return 0;\n}\n\n} // namespace pxt\n\nLogQueue codalLogStore;\n\nDLLEXPORT int pxt_get_logs(int logtype, char *dst, int maxSize) {\n    if (logtype != 0)\n        return 0;\n    target_disable_irq();\n    int r = codalLogStore.read(dst, maxSize);\n    target_enable_irq();\n    return r;\n}\n\nnamespace pxt {\nstatic void dmesgRaw(const char *buf, uint32_t len) {\n#ifdef LOG_TO_FILE\n    if (!dmesgFile) {\n        dmesgFile = fopen(\"dmesg.txt\", \"w\");\n        if (!dmesgFile)\n            dmesgFile = stderr;\n    }\n#endif\n\n    if (codalLogStore.write(buf, len) != 0)\n        return; // if message too long, skip\n\n#ifdef LOG_TO_FILE\n    fwrite(buf, 1, len, dmesgFile);\n#endif\n#ifdef LOG_TO_STDERR\n    fwrite(buf, 1, len, stderr);\n#endif\n}\n\nvoid deepSleep() {\n    // nothing to do\n}\n\nvoid dmesg_flush() {\n#ifdef LOG_TO_FILE\n    fflush(dmesgFile);\n#endif\n}\n\nstatic void dmesgFlushRaw() {\n    dmesg_flush();\n}\n\nvoid vdmesg(const char *format, va_list arg) {\n    char buf[500];\n\n    target_disable_irq();\n\n    snprintf(buf, sizeof(buf), \"[%8d] \", current_time_ms());\n    dmesgRaw(buf, (uint32_t)strlen(buf));\n    vsnprintf(buf, sizeof(buf), format, arg);\n    dmesgRaw(buf, (uint32_t)strlen(buf));\n    dmesgRaw(\"\\n\", 1);\n\n    target_enable_irq();\n\n    dmesgFlushRaw();\n}\n\nvoid dmesg(const char *format, ...) {\n    va_list arg;\n    va_start(arg, format);\n    vdmesg(format, arg);\n    va_end(arg);\n}\n\nuint64_t getLongSerialNumber() {\n    return 0;\n}\n\n} // namespace pxt\n","test.ts":"let i = 1\nlet f = 0.5\nlet plus = i + f\nlet minus = i - f\n\nlet r = Math.random()\nlet ri = Math.randomRange(5, 10)\n\n","timer.ts":"namespace control {\n    /**\n     * A timer\n     */\n    //% fixedInstances\n    export class Timer {\n        start: number;\n\n        constructor() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Gets the elapsed time in millis since the last reset\n         */\n        //% blockId=timerMillis block=\"%timer|millis\"\n        millis(): number {\n            return control.millis() - this.start;\n        }\n\n        /**\n         * Gets the elapsed time in seconds since the last reset\n         */\n        //% blockId=timerSeconds block=\"%timer|seconds\"\n        seconds(): number {\n            return this.millis() / 1000;\n        }\n\n        /**\n         * Resets the timer\n         */\n        //% blockId=timerRest block=\"%timer|reset\"\n        reset() {\n            this.start = control.millis();\n        }\n\n        /**\n         * Pauses until the timer reaches the given amount of milliseconds\n         * @param ms how long to pause for, eg: 5, 100, 200, 500, 1000, 2000\n         */\n        //% blockId=timerPauseUntil block=\"%timer|pause until (ms) %ms\"\n        pauseUntil(ms: number) {\n            const remaining = this.millis() - ms;\n            pause(Math.max(0, remaining));\n        }\n    }\n\n    //% whenUsed fixedInstance block=\"timer 1\"\n    export const timer1 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 2\"\n    export const timer2 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 3\"\n    export const timer3 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 4\"\n    export const timer4 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 5\"\n    export const timer5 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 6\"\n    export const timer6 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 7\"\n    export const timer7 = new Timer();\n    //% whenUsed fixedInstance block=\"timer 8\"\n    export const timer8 = new Timer();\n}","verify.cpp":"#include \"pxt.h\"\n\nnamespace pxt {\n\nVMImage *setVMImgError(VMImage *img, int code, void *pos) {\n    img->errorOffset = pos ? (int)((uint8_t *)pos - (uint8_t *)img->dataStart) : 0;\n    img->errorCode = code;\n    return img;\n}\n\n// next free error 1066\n#define ERROR(code, pos) return setVMImgError(img, code, pos)\n#define CHECK(cond, code)                                                                          \\\n    do {                                                                                           \\\n        if (!(cond))                                                                               \\\n            ERROR(code, sect);                                                                     \\\n    } while (0)\n#define CHECK_AT(cond, code, pos)                                                                  \\\n    do {                                                                                           \\\n        if (!(cond))                                                                               \\\n            ERROR(code, pos);                                                                      \\\n    } while (0)\n#define ALIGNED(sz) (((sz)&7) == 0)\n\n#define FOR_SECTIONS()                                                                             \\\n    VMImageSection *sect, *next;                                                                   \\\n    for (sect = (VMImageSection *)img->dataStart;                                                  \\\n         (next = vmNextSection(sect), (uint64_t *)sect < img->dataEnd); sect = next)\n\n#define ALLOC_ARRAY(tp, sz) (tp *)xmalloc(sz == 0 ? 1 : sizeof(tp) * sz)\n\n#define VM_MAX_PATCH 7\n\nstruct VMPatchState {\n    uint32_t offset;\n    uint32_t bytesLeftInSect;\n    uint8_t patchOff;\n    const char *error;\n    uint64_t patch[VM_MAX_PATCH];\n};\n\nstatic const VTable *vtFor(VMImageSection *sect) {\n    if (sect->type == SectionType::Function)\n        return &pxt::RefAction_vtable;\n    else if (sect->type == SectionType::Literal)\n        switch ((BuiltInType)sect->aux) {\n        case BuiltInType::BoxedString_ASCII:\n            return &pxt::string_inline_ascii_vt;\n        case BuiltInType::BoxedString_SkipList:\n            return &pxt::string_skiplist16_packed_vt;\n        case BuiltInType::BoxedString:\n            return &pxt::string_inline_utf8_vt;\n        case BuiltInType::BoxedBuffer:\n            return &pxt::buffer_vt;\n        default:\n            return NULL;\n        }\n    return NULL;\n}\n\nstatic bool isStringSection(VMImageSection *sect) {\n    if (sect->type == SectionType::Literal)\n        switch ((BuiltInType)sect->aux) {\n        case BuiltInType::BoxedString_ASCII:\n        case BuiltInType::BoxedString_SkipList:\n        case BuiltInType::BoxedString:\n            return true;\n        default:\n            return false;\n        }\n    return false;\n}\n\nVMPatchState *vm_alloc_patch_state() {\n    return (VMPatchState *)calloc(sizeof(VMPatchState), 1);\n}\n\nvoid vm_finish_patch(VMPatchState *state) {\n    free(state);\n}\n\nconst char *vm_patch_image(VMPatchState *state, uint8_t *data, uint32_t len) {\n    if (state->error)\n        return state->error;\n\n    if (len <= 8 || !ALIGNED(len))\n        return (state->error = \"invalid chunk size\");\n\n    while (len > 0) {\n        if (state->bytesLeftInSect == 0) {\n            VMImageSection sect;\n            memcpy(&sect, data, sizeof(sect));\n\n            if (!ALIGNED(sect.size) || !sect.size)\n                return (state->error = \"invalid section\");\n\n            state->bytesLeftInSect = sect.size;\n\n            memset(state->patch, 0, sizeof(state->patch));\n            state->patchOff = 1;\n\n            const VTable *vt = NULL;\n#ifdef PXT32\n            if (sect.type == SectionType::NumberBoxes) {\n                return (state->error = \"TODO: NumberBoxes\");\n            }\n#endif\n            if (sect.type == SectionType::Literal || sect.type == SectionType::Function) {\n                vt = vtFor(&sect);\n                if (!vt)\n                    return (state->error = \"unknown literal vt\");\n#ifdef PXT64\n                state->patch[0] = (uint64_t)vt;\n#else\n                state->patch[0] = (uint64_t)(uint32_t)vt << 32;\n#endif\n            } else if (sect.type == SectionType::VTable) {\n                auto dest = (void **)((uint32_t *)state->patch + 4);\n                dest[0] = (void *)pxt::RefRecord_destroy;\n                dest[1] = (void *)pxt::RefRecord_print;\n                dest[2] = (void *)pxt::RefRecord_scan;\n                dest[3] = (void *)pxt::RefRecord_gcsize;\n            }\n        } else if (state->patchOff != 0) {\n            uint64_t p = state->patch[state->patchOff - 1];\n            if (p)\n                memcpy(data, &p, sizeof(p));\n            if (state->patchOff == VM_MAX_PATCH) {\n                state->patchOff = 0;\n            } else {\n                state->patchOff++;\n            }\n        }\n\n        state->bytesLeftInSect -= 8;\n        data += 8;\n        len -= 8;\n    }\n\n    return NULL;\n}\n\nstatic VMImage *countSections(VMImage *img) {\n    auto p = img->dataStart;\n    while (p < img->dataEnd) {\n        auto sect = (VMImageSection *)p;\n        CHECK(ALIGNED(sect->size), 1002);\n        CHECK(sect->size > 0, 1002);\n        img->numSections++;\n        p += sect->size >> 3;\n    }\n    CHECK_AT(p == img->dataEnd, 1003, p);\n    img->pointerLiterals = ALLOC_ARRAY(TValue, img->numSections);\n    img->sections = ALLOC_ARRAY(VMImageSection *, img->numSections);\n\n    return NULL;\n}\n\nstatic VMImage *loadSections(VMImage *img) {\n    auto idx = 0;\n    VMImageSection *numberBoxes = NULL;\n\n    FOR_SECTIONS() {\n        CHECK(sect->size < 32000, 1014);\n        CHECK(sect->size >= 16, 1048);\n\n        if (sect->type == SectionType::InfoHeader) {\n            CHECK(sect->size >= sizeof(VMImageHeader), 1008);\n            auto hd = (VMImageHeader *)sect->data;\n            CHECK(hd->magic0 == VM_MAGIC0, 1009);\n            CHECK(hd->magic1 == VM_MAGIC1, 1010);\n            CHECK(hd->allocGlobals >= hd->nonPointerGlobals, 1011);\n            CHECK(hd->allocGlobals < 10000, 1012);\n            CHECK(idx == 0, 1013);\n            img->infoHeader = hd;\n        }\n\n        if (sect->type == SectionType::OpCodeMap) {\n            CHECK(img->opcodes == NULL, 1015);\n            auto curr = sect->data;\n            auto endp = sect->data + sect->size - 8;\n            CHECK(endp[-1] == 0, 1017);\n\n            while (curr < endp) {\n                if (*curr == 0)\n                    img->numOpcodes++;\n                curr++;\n            }\n            CHECK(img->numOpcodes >= VM_FIRST_RTCALL, 1016);\n\n            img->opcodes = ALLOC_ARRAY(OpFun, img->numOpcodes);\n            img->opcodeDescs = ALLOC_ARRAY(const OpcodeDesc *, img->numOpcodes);\n\n            int i = 0;\n            curr = sect->data;\n            while (curr < endp) {\n                img->opcodeDescs[i] = NULL;\n                img->opcodes[i] = NULL;\n                if (*curr) {\n                    for (auto st = staticOpcodes; st->name; st++) {\n                        if (strcmp(st->name, (const char *)curr) == 0) {\n                            img->opcodeDescs[i] = st;\n                            break;\n                        }\n                    }\n                    if (img->opcodeDescs[i] == NULL) {\n                        DMESG(\"missing opcode: %s\", (const char *)curr);\n                        setVMImgError(img, 1018, curr);\n                    } else {\n                        img->opcodes[i] = img->opcodeDescs[i]->fn;\n                    }\n                }\n                while (*curr)\n                    curr++;\n                curr++;\n                i++;\n            }\n            if (img->errorCode)\n                return img;\n        }\n\n        if (sect->type == SectionType::NumberBoxes) {\n            CHECK(!numberBoxes, 1061);\n            numberBoxes = sect;\n        }\n\n        if (sect->type == SectionType::NumberLiterals) {\n            CHECK(!!numberBoxes, 1062);\n            CHECK(!img->numberLiterals, 1004);\n            img->numNumberLiterals = (sect->size >> 3) - 1;\n            uint64_t *values = (uint64_t *)sect->data;\n\n            int numBoxed = 0;\n\n            for (unsigned i = 0; i < img->numNumberLiterals; ++i) {\n                auto ptr = &values[i];\n                uint64_t v = *ptr;\n                if (isEncodedDouble(v)) {\n                    CHECK_AT(!isnan(decodeDouble(v)), 1005, ptr);\n                    numBoxed++;\n                } else if (v & 1) {\n                    CHECK_AT((v >> 1) <= 0xffffffff, 1006, ptr);\n                    if (!canBeTagged(v >> 1))\n                        numBoxed++;\n                } else if (v == 0) {\n                    // OK - padding probably\n                } else {\n                    CHECK_AT(false, 1007, ptr);\n                }\n            }\n\n            CHECK(numberBoxes->size >= sizeof(VMImageSection) + (numBoxed + 1) * 12, 1063);\n            CHECK(numberBoxes->size <= 4 + sizeof(VMImageSection) + (numBoxed + 1) * 12, 1063);\n\n            img->numberLiterals = ALLOC_ARRAY(TValue, img->numNumberLiterals);\n#ifdef PXT32\n            img->boxedNumbers = (BoxedNumber *)numberBoxes->data;\n            int boxedPtr = 0;\n#endif\n\n            for (unsigned i = 0; i < img->numNumberLiterals; ++i) {\n                uint64_t v = values[i];\n#ifdef PXT32\n                if (!isEncodedDouble(v) && canBeTagged(v >> 1)) {\n                    img->numberLiterals[i] = (TValue)v;\n                } else {\n                    CHECK(boxedPtr < numBoxed, 1060); // should never happen\n                    double x = isEncodedDouble(v) ? decodeDouble(v) : (int32_t)(v >> 1);\n                    CHECK(img->boxedNumbers[boxedPtr].vtable == &number_vt, 1064);\n                    CHECK(img->boxedNumbers[boxedPtr].num == x, 1065);\n                    img->numberLiterals[i] = (TValue)&img->boxedNumbers[boxedPtr];\n                    boxedPtr++;\n                }\n#else\n                img->numberLiterals[i] = (TValue)v;\n#endif\n            }\n        }\n\n        if (sect->type == SectionType::ConfigData) {\n            img->numConfigDataEntries = (sect->size - 8) >> 3;\n            img->configData = (int32_t *)sect->data;\n            CHECK(img->configData[(img->numConfigDataEntries - 1) * 2] == 0, 1045);\n        }\n\n        img->sections[idx] = sect;\n\n        if (sect->type == SectionType::Literal) {\n            CHECK(sect->size >= 20, 1066);\n            switch ((BuiltInType)sect->aux) {\n            case BuiltInType::BoxedString_ASCII:\n            case BuiltInType::BoxedString: {\n                auto p = (BoxedString *)vmLiteralVal(sect);\n                CHECK(sect->size >= 16 + 2 + (uint32_t)p->ascii.length + 1, 1067);\n                CHECK(p->ascii.data[p->ascii.length] == 0, 1068);\n                break;\n            }\n            case BuiltInType::BoxedString_SkipList: {\n                auto p = (BoxedString *)vmLiteralVal(sect);\n                CHECK(sect->size >= 16 + 4 + PXT_NUM_SKIP_ENTRIES(p) * 2 + (uint32_t)p->skip_pack.size + 1,\n                      1069);\n                CHECK(PXT_SKIP_DATA_PACK(p)[p->skip_pack.size] == 0, 1070);\n                for (int i = 0; i < PXT_NUM_SKIP_ENTRIES(p); ++i) {\n                    CHECK(p->skip_pack.list[i] <= p->skip_pack.size, 1071);\n                }\n                break;\n            }\n            case BuiltInType::BoxedBuffer: {\n                auto p = (BoxedBuffer *)vmLiteralVal(sect);\n                CHECK(sect->size >= 16 + 4 + (uint32_t)p->length, 1072);\n                break;\n            }\n            default:\n                CHECK(false, 1050);\n            }\n            img->pointerLiterals[idx] = vmLiteralVal(sect);\n            // TODO validate size/length of boxed string/buffer; check utf8 encoding?; 1042 error\n        } else if (sect->type == SectionType::Function) {\n            img->pointerLiterals[idx] = vmLiteralVal(sect);\n            if (!img->entryPoint)\n                img->entryPoint = (RefAction *)img->pointerLiterals[idx];\n        } else if (sect->type == SectionType::VTable) {\n            img->pointerLiterals[idx] = (TValue)(sect->data);\n        } else {\n            img->pointerLiterals[idx] = nullptr;\n        }\n\n        idx++;\n    }\n\n    CHECK_AT(img->infoHeader != NULL, 1019, 0);\n    CHECK_AT(img->opcodes != NULL, 1020, 0);\n    CHECK_AT(img->numberLiterals != NULL, 1021, 0);\n    CHECK_AT(img->configData != NULL, 1022, 0);\n    CHECK_AT(img->entryPoint != NULL, 1059, 0);\n\n    return NULL;\n}\n\nstatic VMImage *loadIfaceNames(VMImage *img) {\n    FOR_SECTIONS() {\n        if (sect->type == SectionType::IfaceMemberNames) {\n            uint32_t *ptrs = (uint32_t *)sect->data;\n            auto len = *ptrs++;\n            CHECK(len < 0x40000, 1047);\n            uintptr_t *dst = ALLOC_ARRAY(uintptr_t, len + 1);\n            img->ifaceMemberNames = dst;\n            img->numIfaceMemberNames = len;\n            *dst++ = len;\n            CHECK(sect->size >= 12 + len * 4, 1047);\n            for (unsigned i = 0; i < len; ++i) {\n                CHECK(ptrs[i] < img->numSections, 1051);\n                auto ss = img->sections[ptrs[i]];\n                CHECK(isStringSection(ss), 1052);\n                dst[i] = (uintptr_t)img->pointerLiterals[ptrs[i]];\n                // pointers have to be sorted\n                CHECK(i == 0 || dst[i - 1] < dst[i], 1053);\n                // and so strings\n                CHECK(i == 0 || String_::compare((String)dst[i - 1], (String)dst[i]) < 0, 1054);\n            }\n        }\n    }\n\n    return NULL;\n}\n\nvoid validateFunction(VMImage *img, VMImageSection *sect, int debug);\n\nstatic VMImage *validateFunctions(VMImage *img) {\n    FOR_SECTIONS() {\n        if (sect->type == SectionType::VTable) {\n            uint8_t *endp = sect->data + sect->size - 8;\n            auto vt = (VTable *)sect->data;\n            auto multBase = (uint16_t *)&vt->methods[VM_NUM_CPP_METHODS];\n            CHECK((uint8_t *)multBase < endp,\n                  1023); // basic size check, before dereferencing anything\n\n            auto maxMult = 0xffffffffU >> (vt->ifaceHashMult & 0xff);\n\n            CHECK(vt->numbytes < 1024, 1024);\n            CHECK((vt->numbytes & 7) == 0, 1025);\n            CHECK(vt->objectType == ValType::Object, 1026);\n            CHECK(vt->magic == VTABLE_MAGIC, 1027);\n            CHECK(vt->ifaceHashEntries > maxMult + 3, 1028);\n            CHECK((uint8_t *)(multBase + vt->ifaceHashEntries) < endp, 1029);\n            CHECK(vt->reserved == 0, 1030);\n            CHECK(vt->ifaceHashMult != 0, 1031);\n            CHECK((vt->ifaceHashEntries & 3) == 0, 1032);\n            CHECK((int)vt->classNo >= (int)BuiltInType::User0, 1055);\n            CHECK((int)vt->lastClassNo >= (int)vt->classNo, 1056);\n\n            uint32_t maxOff = 0;\n            uint32_t minOff = 0xfffffff;\n            for (unsigned i = 0; i < vt->ifaceHashEntries; ++i) {\n                uint32_t off2 = multBase[i];\n                if (off2 > maxOff)\n                    maxOff = off2;\n                if (off2 < minOff)\n                    minOff = off2;\n                auto ent = (IfaceEntry *)multBase + off2;\n                CHECK((uint8_t *)(ent + 1) <= endp, 1033);\n            }\n\n            CHECK(minOff * sizeof(IfaceEntry) == vt->ifaceHashEntries * 2, 1034);\n\n            auto last1 = (IfaceEntry *)multBase + maxOff + 1;\n            if (last1->memberId != 0)\n                maxOff++;\n\n            for (unsigned i = minOff; i <= maxOff; ++i) {\n                auto ent = (IfaceEntry *)multBase + i;\n                if (ent->memberId == 0)\n                    continue;\n                if (ent->aux == 0) {\n                    CHECK(ent->method < (unsigned)(vt->numbytes >> 3), 1035);\n                } else {\n                    CHECK(ent->method < img->numSections, 1037);\n                    auto fn = img->sections[ent->method];\n                    CHECK(fn->type == SectionType::Function, 1039);\n                }\n            }\n\n            auto p = (uint8_t *)((IfaceEntry *)multBase + maxOff + 1);\n            while (p < endp)\n                CHECK(*p++ == 0, 1040);\n        }\n\n        if (sect->type == SectionType::Function) {\n            validateFunction(img, sect, 0);\n            if (img->errorCode) {\n                // try again with debug\n                validateFunction(img, sect, 1);\n                return img;\n            }\n        }\n    }\n    return NULL;\n}\n\nstatic VMImage *checkVTables(VMImage *img) {\n    FOR_SECTIONS() {\n        auto vt = vtFor(sect);\n        if (vt) {\n            CHECK(((RefObject *)vmLiteralVal(sect))->vtable == vt, 1057);\n        }\n        if (sect->type == SectionType::Literal) {\n            CHECK(vt != NULL, 1043);\n        } else if (sect->type == SectionType::VTable) {\n            auto vt = (VTable *)sect->data;\n            CHECK(vt->methods[0] == (void *)pxt::RefRecord_destroy, 1058);\n            CHECK(vt->methods[1] == (void *)pxt::RefRecord_print, 1058);\n            CHECK(vt->methods[2] == (void *)pxt::RefRecord_scan, 1058);\n            CHECK(vt->methods[3] == (void *)pxt::RefRecord_gcsize, 1058);\n        }\n    }\n    return NULL;\n}\n\nVMImage *loadVMImage(void *data, unsigned length) {\n    auto img = new VMImage();\n    memset(img, 0, sizeof(*img));\n\n    DMESG(\"loading image at %p (%d bytes)\", data, length);\n\n    CHECK_AT(ALIGNED((uintptr_t)data), 1000, 0);\n    CHECK_AT(ALIGNED(length), 1001, 0);\n\n    img->dataStart = (uint64_t *)data;\n    img->dataEnd = (uint64_t *)((uint8_t *)data + length);\n\n    if (countSections(img) || checkVTables(img) || loadSections(img) || loadIfaceNames(img) ||\n        validateFunctions(img)) {\n        // error!\n        return img;\n    }\n\n    DMESG(\"image loaded\");\n\n    return img;\n}\n\nvoid unloadVMImage(VMImage *img) {\n    if (!img)\n        return;\n\n    free(img->pointerLiterals);\n    free(img->sections);\n    free(img->opcodes);\n    free(img->opcodeDescs);\n    free(img->numberLiterals);\n    free(img->ifaceMemberNames);\n\n    free(img->dataStart);\n    memset(img, 0, sizeof(*img));\n    delete img;\n}\n\n} // namespace pxt\n","vm.cpp":"#include \"pxt.h\"\n\n// TODO look for patterns in output for combined instructions\n// TODO check for backjumps (how many)\n// TODO getConfig() should have a callback into host\n\n#define BOUND_ACTION 1\n\n#define SPLIT_ARG(arg0, arg1) unsigned arg0 = arg & 31, arg1 = arg >> 6\n#define SPLIT_ARG2(arg0, arg1) unsigned arg0 = arg & 255, arg1 = arg >> 8\n\n#define PUSH(v) *--ctx->sp = (v)\n#define POPVAL() *ctx->sp++\n#define POP(n) ctx->sp += (n)\n\n//#define TRACE DMESG\n#define TRACE NOLOG\n\nnamespace pxt {\n\n//%\nvoid op_stloc(FiberContext *ctx, unsigned arg) {\n    ctx->sp[arg] = ctx->r0;\n}\n\n//%\nvoid op_ldloc(FiberContext *ctx, unsigned arg) {\n    ctx->r0 = ctx->sp[arg];\n}\n\n//%\nvoid op_ldcap(FiberContext *ctx, unsigned arg) {\n    ctx->r0 = ctx->currAction->fields[arg];\n}\n\n//%\nvoid op_bitconv(FiberContext *ctx, unsigned arg) {\n    int shift = 32 - ((arg & 0xf) * 8);\n    if (arg & 0x10) {\n        int v = toInt(ctx->r0);\n        ctx->r0 = fromInt((v << shift) >> shift);\n    } else {\n        unsigned v = toUInt(ctx->r0);\n        ctx->r0 = fromUInt((v << shift) >> shift);\n    }\n}\n\n//%\nvoid op_stglb(FiberContext *ctx, unsigned arg) {\n    globals[arg] = ctx->r0;\n}\n\n//%\nvoid op_ldglb(FiberContext *ctx, unsigned arg) {\n    ctx->r0 = globals[arg];\n}\n\n//%\nvoid op_ldlit(FiberContext *ctx, unsigned arg) {\n    ctx->r0 = ctx->img->pointerLiterals[arg];\n}\n\n//%\nvoid op_ldnumber(FiberContext *ctx, unsigned arg) {\n    ctx->r0 = (TValue)ctx->img->numberLiterals[arg];\n}\n\n//%\nvoid op_jmp(FiberContext *ctx, unsigned arg) {\n    ctx->pc += (int)arg;\n}\n\n//%\nvoid op_jmpz(FiberContext *ctx, unsigned arg) {\n    if (!toBoolQuick(ctx->r0))\n        ctx->pc += (int)arg;\n}\n\n//%\nvoid op_jmpnz(FiberContext *ctx, unsigned arg) {\n    if (toBoolQuick(ctx->r0))\n        ctx->pc += (int)arg;\n}\n\nstatic inline VTable *getStaticVTable(VMImage *img, unsigned classId) {\n    return (VTable *)(img->pointerLiterals[classId]);\n}\n\n//%\nvoid op_newobj(FiberContext *ctx, unsigned arg) {\n    ctx->r0 = (TValue)pxt::mkClassInstance(getStaticVTable(ctx->img, arg));\n}\n\nstatic inline void shiftArg(FiberContext *ctx, unsigned numArgs) {\n    for (unsigned i = numArgs - 1; i > 0; i--)\n        ctx->sp[i] = ctx->sp[i - 1];\n    POP(1);\n}\n\nstatic inline void checkClass(FiberContext *ctx, TValue obj, unsigned classId, unsigned fldId) {\n    TRACE(\"check class: %p cl=%d f=%d\", obj, classId, fldId);\n    if (!isPointer(obj))\n        failedCast(obj);\n    auto vt = getVTable((RefObject *)obj);\n    auto vt2 = getStaticVTable(ctx->img, classId);\n    if (vt == vt2)\n        return;\n    if ((int)vt2->classNo <= (int)vt->classNo && (int)vt->classNo <= (int)vt2->lastClassNo) {\n        // double check field range - we don't really check class sequence numbers\n        if (8 + fldId * 8 >= vt->numbytes)\n            failedCast(obj);\n    }\n}\n\n//%\nvoid op_ldfld(FiberContext *ctx, unsigned arg) {\n    SPLIT_ARG2(fldId, classId);\n    auto obj = ctx->r0;\n    checkClass(ctx, obj, classId, fldId);\n    ctx->r0 = ((RefRecord *)obj)->fields[fldId];\n}\n\n//%\nvoid op_stfld(FiberContext *ctx, unsigned arg) {\n    SPLIT_ARG2(fldId, classId);\n    auto obj = POPVAL();\n    checkClass(ctx, obj, classId, fldId);\n    ((RefRecord *)obj)->fields[fldId] = ctx->r0;\n}\n\nstatic RefAction *bindAction(FiberContext *ctx, RefAction *ra, TValue obj) {\n    if (ra->initialLen != 0)\n        target_panic(PANIC_INVALID_VTABLE);\n    auto act = (RefAction *)mkAction(1, ra);\n    act->flags = BOUND_ACTION;\n    act->fields[0] = obj;\n    return act;\n}\n\nstatic inline void runAction(FiberContext *ctx, RefAction *ra) {\n    if (ctx->sp < ctx->img->stackLimit)\n        soft_panic(PANIC_STACK_OVERFLOW);\n\n    PUSH((TValue)ctx->currAction);\n    PUSH(VM_ENCODE_PC(ctx->pc - ctx->imgbase));\n    ctx->currAction = ra;\n    ctx->pc = actionPC(ra);\n}\n\nstatic const uint8_t *find_src_map() {\n    const uint32_t *p = (const uint32_t *)((uint32_t)vmImg->dataEnd & ~0xf);\n    const uint32_t *endP = p + 128;\n    while (p < endP) {\n        if (p[0] == 0x4d435253 && p[1] == 0x2d4e1588 && p[2] == 0x719986aa)\n            return (const uint8_t *)p;\n        p += 4;\n    }\n    DMESG(\"source map not found; dataEnd=%p\", vmImg->dataEnd);\n    return NULL;\n}\n\nstatic const uint8_t *decode_num(const uint8_t *p, int *dst) {\n    auto v = *p++;\n    if (v < 0xf0) {\n        *dst = v;\n        return p;\n    }\n    auto sz = v & 0x07;\n    int r = 0;\n    for (int i = 0; i < sz; ++i) {\n        r |= *p++ << (i * 8);\n    }\n    if (v & 0x08)\n        r = -r;\n    *dst = r;\n    return p;\n}\n\nstatic const uint8_t *dump_pc_one(int addr, int off, const uint8_t *fn) {\n    if (!fn)\n        return NULL;\n    auto p = fn;\n    while (*p)\n        p++;\n    p++;\n    int prevLn = 0, prevOff = 0;\n    while (*p != 0xff) {\n        int a, b, c;\n        p = decode_num(p, &a);\n        p = decode_num(p, &b);\n        p = decode_num(p, &c);\n        prevLn += a;\n        b <<= 1;\n        prevOff += b;\n        c <<= 1;\n\n        int startA = prevOff;\n        int endA = startA + c;\n        if (startA <= addr + off && addr + off <= endA) {\n            DMESG(\" PC:%x %s(%d)\", addr, fn, prevLn);\n            return NULL;\n        }\n    }\n    return p + 1;\n}\n\nstatic void dump_pc(int addr, const uint8_t *srcmap) {\n    if (srcmap) {\n        auto p = srcmap + 16;\n        for (;;) {\n            auto a = dump_pc_one(addr, -2, p);\n            if (!a || !dump_pc_one(addr, -4, p) || !dump_pc_one(addr, 0, p))\n                return;\n            p = a;\n            if (*p == 0)\n                break;\n        }\n    }\n    DMESG(\" PC:%x\", addr);\n}\n\nvoid vm_stack_trace() {\n    auto ctx = currentFiber;\n    if (!ctx)\n        return;\n    DMESG(\"stack trace (programHash:%d):\", programHash());\n    auto end = vmImg->stackTop;\n    auto ptr = ctx->sp;\n    auto srcmap = find_src_map();\n    dump_pc((ctx->pc - ctx->imgbase) << 1, srcmap);\n    int max = 30;\n    while (ptr < end && max) {\n        auto v = (uintptr_t)*ptr++;\n        if (VM_IS_ENCODED_PC(v)) {\n            dump_pc(VM_DECODE_PC(v) << 1, srcmap);\n            max--;\n        }\n    }\n    if (max == 0)\n        DMESG(\" ...\");\n}\n\n//%\nvoid op_callproc(FiberContext *ctx, unsigned arg) {\n    runAction(ctx, (RefAction *)ctx->img->pointerLiterals[arg]);\n}\n\nstatic void callind(FiberContext *ctx, RefAction *ra, unsigned numArgs) {\n    if (ra->flags & BOUND_ACTION) {\n        PUSH(0);\n        for (unsigned i = 0; i < numArgs; i++) {\n            ctx->sp[i] = ctx->sp[i + 1];\n        }\n        ctx->sp[numArgs] = ra->fields[0];\n        numArgs++;\n    }\n\n    if (numArgs != ra->numArgs) {\n        int missing = ra->numArgs - numArgs;\n        TRACE(\"callind missing=%d\", missing);\n        if (missing < 0) {\n            // just drop the ones on top\n            POP(-missing);\n        } else {\n            // add some undefineds\n            while (missing--)\n                PUSH(TAG_UNDEFINED);\n        }\n    }\n\n    if (ra->initialLen > ra->len)\n        // trying to call function template\n        target_panic(PANIC_INVALID_VTABLE);\n\n    runAction(ctx, ra);\n}\n\n//%\nvoid op_callind(FiberContext *ctx, unsigned arg) {\n    auto fn = ctx->r0;\n    if (!isPointer(fn))\n        failedCast(fn);\n    auto vt = getVTable((RefObject *)fn);\n    if (vt->objectType != ValType::Function)\n        failedCast(fn);\n\n    callind(ctx, (RefAction *)fn, arg);\n}\n\n//%\nvoid op_ret(FiberContext *ctx, unsigned arg) {\n    SPLIT_ARG(retNumArgs, numTmps);\n\n    POP(numTmps);\n    auto retaddr = (intptr_t)POPVAL();\n    ctx->currAction = (RefAction *)POPVAL();\n    POP(retNumArgs);\n\n    // check if we're leaving a function that still has open try blocks\n    // (this results from invalid code generation)\n    if (ctx->tryFrame &&\n        ctx->tryFrame->registers[2] < (uint8_t *)ctx->sp - (uint8_t *)vmImg->stackBase) {\n        DMESG(\"try frame %p left on return %d/%d\", ctx->tryFrame, ctx->tryFrame->registers[2],\n              (uint8_t *)ctx->sp - (uint8_t *)vmImg->stackBase);\n        vm_stack_trace();\n        target_panic(PANIC_VM_ERROR);\n    }\n\n    if (retaddr == (intptr_t)TAG_STACK_BOTTOM) {\n        ctx->pc = NULL;\n    } else {\n        ctx->pc = ctx->imgbase + VM_DECODE_PC(retaddr);\n    }\n}\n\n//%\nvoid op_pop(FiberContext *ctx, unsigned) {\n    ctx->r0 = POPVAL();\n}\n\n//%\nvoid op_popmany(FiberContext *ctx, unsigned arg) {\n    POP(arg);\n}\n\n//%\nvoid op_pushmany(FiberContext *ctx, unsigned arg) {\n    while (arg--) {\n        PUSH(TAG_UNDEFINED);\n    }\n}\n\n//%\nvoid op_push(FiberContext *ctx, unsigned) {\n    PUSH(ctx->r0);\n}\n\n//%\nvoid op_ldspecial(FiberContext *ctx, unsigned arg) {\n    ctx->r0 = (TValue)(uintptr_t)arg;\n}\n\n//%\nvoid op_ldint(FiberContext *ctx, unsigned arg) {\n    ctx->r0 = TAG_NUMBER(arg);\n}\n\n//%\nvoid op_ldintneg(FiberContext *ctx, unsigned arg) {\n    ctx->r0 = TAG_NUMBER(-(int)arg);\n}\n\nTryFrame *beginTry();\n\n//%\nvoid op_try(FiberContext *ctx, unsigned arg) {\n    auto f = pxt::beginTry();\n    f->registers[0] = (uintptr_t)ctx->currAction;\n    f->registers[1] = (uintptr_t)(ctx->pc + (int)arg);\n    f->registers[2] = (uint8_t *)ctx->sp - (uint8_t *)vmImg->stackBase;\n}\n\nvoid restoreVMExceptionState(TryFrame *tf, FiberContext *ctx) {\n    // TODO verification\n    ctx->currAction = (RefAction *)tf->registers[0];\n    ctx->pc = (uint16_t *)tf->registers[1];\n    ctx->sp = (TValue *)((uint8_t *)vmImg->stackBase + tf->registers[2]);\n    longjmp(ctx->loopjmp, 1);\n}\n\nstatic TValue lookupIfaceMember(TValue obj, VTable *vt, unsigned ifaceIdx) {\n    uint32_t mult = vt->ifaceHashMult;\n    uint32_t off = (ifaceIdx * mult) >> (mult & 0xff);\n\n    unsigned n = 3;\n    auto multBase = (uint16_t *)&vt->methods[VM_NUM_CPP_METHODS];\n    while (n--) {\n        uint32_t off2 = multBase[off];\n        auto ent = (struct IfaceEntry *)multBase + off2;\n\n        if (ent->memberId == ifaceIdx) {\n            if (ent->aux != 0) {\n                return vmImg->pointerLiterals[ent->method];\n            } else {\n                return ((RefRecord *)obj)->fields[ent->method - 1];\n            }\n        }\n        off++;\n    }\n\n    return NULL;\n}\n\n/* skip .d.ts */ enum class CallType { Call = 0, Get = 1, Set = 2 };\n\nstatic inline void callifaceCore(FiberContext *ctx, unsigned numArgs, unsigned ifaceIdx,\n                                 CallType getset) {\n    auto obj = ctx->sp[numArgs - 1];\n    if (!isPointer(obj))\n        failedCast(obj);\n    auto vt = getVTable((RefObject *)obj);\n    uint32_t mult = vt->ifaceHashMult;\n\n    if (!mult) {\n        if (vt->classNo == BuiltInType::RefMap) {\n            if (getset == CallType::Set) {\n                pxtrt::mapSet((RefMap *)obj, ifaceIdx, ctx->sp[0]);\n                POP(2); // and pop arguments\n            } else {\n                ctx->r0 = pxtrt::mapGet((RefMap *)obj, ifaceIdx);\n                if (getset == CallType::Call) {\n                    shiftArg(ctx, numArgs);\n                    op_callind(ctx, numArgs - 1);\n                } else {\n                    POP(1);\n                }\n            }\n            return;\n        }\n        missingProperty(obj);\n    }\n    uint32_t off = (ifaceIdx * mult) >> (mult & 0xff);\n\n    unsigned n = 3;\n    auto multBase = (uint16_t *)&vt->methods[VM_NUM_CPP_METHODS];\n    while (n--) {\n        uint32_t off2 = multBase[off];\n        auto ent = (struct IfaceEntry *)multBase + off2;\n\n        if (ent->memberId == ifaceIdx) {\n            if (ent->aux != 0) {\n                if (getset == CallType::Set) {\n                    ent++;\n                    if (ent->memberId != ifaceIdx)\n                        missingProperty(obj);\n                }\n                auto fn = (RefAction *)ctx->img->pointerLiterals[ent->method];\n                if (getset == CallType::Get && ent->aux == 2) {\n                    ctx->r0 = (TValue)bindAction(ctx, fn, obj);\n                    POP(1);\n                    return;\n                }\n                callind(ctx, fn, numArgs);\n            } else {\n                if (getset == CallType::Set) {\n                    // store field\n                    ((RefRecord *)obj)->fields[ent->method - 1] = ctx->sp[0];\n                    POP(2); // and pop arguments\n                } else {\n                    // load field\n                    ctx->r0 = ((RefRecord *)obj)->fields[ent->method - 1];\n                    if (getset == CallType::Call) {\n                        // and call\n                        shiftArg(ctx, numArgs);\n                        op_callind(ctx, numArgs - 1);\n                    } else {\n                        // if just loading, pop the object arg\n                        POP(1);\n                    }\n                }\n            }\n\n            return;\n        }\n        off++;\n    }\n\n    if (getset == CallType::Get) {\n        ctx->sp += 1; // pop object arg\n        ctx->r0 = TAG_UNDEFINED;\n    } else {\n        missingProperty(obj);\n    }\n}\n\n//%\nvoid op_calliface(FiberContext *ctx, unsigned arg) {\n    SPLIT_ARG(numArgs, ifaceIdx);\n    callifaceCore(ctx, numArgs, ifaceIdx, CallType::Call);\n}\n\n//%\nvoid op_callget(FiberContext *ctx, unsigned arg) {\n    callifaceCore(ctx, 1, arg, CallType::Get);\n}\n\n//%\nvoid op_callset(FiberContext *ctx, unsigned arg) {\n    callifaceCore(ctx, 2, arg, CallType::Set);\n}\n\n//%\nvoid op_mapget(FiberContext *ctx, unsigned arg) {\n    auto obj = ctx->sp[0];\n    if (!isPointer(obj))\n        failedCast(obj);\n    auto vt = getVTable((RefObject *)obj);\n    auto key = numops::toString(ctx->r0);\n    if (vt->classNo == BuiltInType::RefMap) {\n        ctx->r0 = pxtrt::mapGetByString((RefMap *)obj, key);\n        POP(1);\n    } else {\n        int k = pxtrt::lookupMapKey(key);\n        if (k == 0) {\n            POP(1);\n            ctx->r0 = TAG_UNDEFINED;\n        } else {\n            callifaceCore(ctx, 1, k, CallType::Get);\n        }\n    }\n}\n\n//%\nvoid op_mapset(FiberContext *ctx, unsigned arg) {\n    auto obj = ctx->sp[1];\n    if (!isPointer(obj))\n        failedCast(obj);\n    auto vt = getVTable((RefObject *)obj);\n    auto key = numops::toString(ctx->sp[0]);\n    ctx->sp[0] = (TValue)key; // save it, so it doesn't get GCed\n    if (vt->classNo == BuiltInType::RefMap) {\n        pxtrt::mapSetByString((RefMap *)obj, key, ctx->r0);\n        POP(2);\n    } else {\n        int k = pxtrt::lookupMapKey(key);\n        if (k == 0) {\n            missingProperty(obj);\n        } else {\n            ctx->sp[0] = ctx->r0;\n            callifaceCore(ctx, 2, k, CallType::Set);\n        }\n    }\n}\n\n//%\nvoid op_checkinst(FiberContext *ctx, unsigned arg) {\n    auto obj = ctx->r0;\n    ctx->r0 = TAG_FALSE;\n\n    if (isPointer(obj)) {\n        auto vt2 = getStaticVTable(ctx->img, arg);\n        auto vt = getVTable((RefObject *)obj);\n        if (vt == vt2)\n            ctx->r0 = TAG_TRUE;\n        else if ((int)vt2->classNo <= (int)vt->classNo && (int)vt->classNo <= (int)vt2->lastClassNo)\n            ctx->r0 = TAG_TRUE;\n    }\n}\n\nstatic TValue inlineInvoke(FiberContext *ctx, RefAction *fn, int numArgs) {\n    auto prevPC = ctx->pc;\n    auto prevR0 = ctx->r0;\n    jmp_buf loopjmp;\n    memcpy(&loopjmp, &ctx->loopjmp, sizeof(loopjmp));\n    // make sure call will push TAG_STACK_BOTTOM\n    ctx->pc = (uint16_t *)ctx->imgbase + 1;\n    callind(ctx, fn, numArgs);\n    ctx->img->execLock ^= 1;\n    exec_loop(ctx);\n    if (ctx->resumePC)\n        target_panic(PANIC_BLOCKING_TO_STRING);\n    ctx->img->execLock ^= 1;\n    auto r = ctx->r0;\n    ctx->pc = prevPC;\n    ctx->r0 = prevR0;\n    memcpy(&ctx->loopjmp, &loopjmp, sizeof(loopjmp));\n    return r;\n}\n\nString convertToString(FiberContext *ctx, TValue v) {\n    if (isPointer(v)) {\n        auto vt = getVTable((RefObject *)v);\n        if ((int)vt->classNo >= (int)BuiltInType::User0) {\n            auto img = ctx->img;\n            if (!img->toStringKey) {\n                img->toStringKey = pxtrt::lookupMapKey(mkString(\"toString\"));\n                if (!img->toStringKey)\n                    img->toStringKey = -1;\n            }\n            if (img->toStringKey > 0) {\n                auto fn = lookupIfaceMember(v, vt, img->toStringKey);\n                if (fn && isPointer(fn) &&\n                    getVTable((RefObject *)fn)->objectType == ValType::Function) {\n                    PUSH(v);\n                    v = inlineInvoke(ctx, (RefAction *)fn, 1);\n                    PUSH(v); // make sure it doesn't get collected\n                }\n            }\n        }\n    }\n\n    auto rr = numops::toString(v);\n    if ((TValue)rr != v)\n        PUSH((TValue)rr); // make sure it doesn't get collected\n\n    return rr;\n}\n\nvoid exec_loop(FiberContext *ctx) {\n    if (ctx->img->execLock) {\n        DMESG(\"image locked!\");\n        target_panic(PANIC_VM_ERROR);\n    }\n    ctx->img->execLock = 1;\n    auto opcodes = ctx->img->opcodes;\n    setjmp(ctx->loopjmp);\n    while (ctx->pc) {\n        if (panicCode)\n            break;\n        uint16_t opcode = *ctx->pc++;\n        TRACE(\"0x%x: %04x %d\", (uint8_t *)ctx->pc - 2 - (uint8_t *)ctx->img->dataStart, opcode,\n              (int)(vmImg->stackTop - ctx->sp));\n        if (opcode >> 15 == 0) {\n            opcodes[opcode & VM_OPCODE_BASE_MASK](ctx, opcode >> VM_OPCODE_ARG_POS);\n            if (opcode & VM_OPCODE_PUSH_MASK)\n                PUSH(ctx->r0);\n        } else if (opcode >> 14 == 0b10) {\n            ((ApiFun)(void *)opcodes[opcode & 0x1fff])(ctx);\n            if (opcode & VM_RTCALL_PUSH_MASK)\n                PUSH(ctx->r0);\n        } else {\n            unsigned tmp = ((int32_t)opcode << (16 + 2)) >> (2 + VM_OPCODE_ARG_POS);\n            opcode = *ctx->pc++;\n            opcodes[opcode & VM_OPCODE_BASE_MASK](ctx, (opcode >> VM_OPCODE_ARG_POS) + tmp);\n            if (opcode & VM_OPCODE_PUSH_MASK)\n                PUSH(ctx->r0);\n        }\n    }\n    ctx->img->execLock = 0;\n}\n\n} // namespace pxt\n\n//\n// Verification\n//\n\nnamespace pxt {\n\n// 1255\n#define FNERR(errcode)                                                                             \\\n    do {                                                                                           \\\n        setVMImgError(img, errcode, &code[pc]);                                                    \\\n        return;                                                                                    \\\n    } while (0)\n#define FORCE_STACK(v, errcode, pc)                                                                \\\n    do {                                                                                           \\\n        if (stackDepth[pc] && stackDepth[pc] != v)                                                 \\\n            FNERR(errcode);                                                                        \\\n        stackDepth[pc] = v;                                                                        \\\n    } while (0)\n\nvoid validateFunction(VMImage *img, VMImageSection *sect, int debug) {\n    uint16_t stackDepth[sect->size / 2];\n    memset(stackDepth, 0, sizeof(stackDepth));\n    int baseStack = 1; // 1 is the return address; also zero in the array above means unknown yet\n    int currStack = baseStack;\n    unsigned pc = 0;\n    auto code = (uint16_t *)((uint8_t *)sect + VM_FUNCTION_CODE_OFFSET);\n    auto lastPC = (sect->size - VM_FUNCTION_CODE_OFFSET) >> 1;\n    auto atEnd = false;\n\n    RefAction *ra = (RefAction *)vmLiteralVal(sect);\n\n    if (ra->vtable != &pxt::RefAction_vtable)\n        FNERR(1251);\n    if ((uint8_t *)img->dataStart + ra->func != (uint8_t *)code)\n        FNERR(1252);\n\n    unsigned numArgs = ra->numArgs;\n    unsigned numCaps = ra->initialLen;\n\n    if (numCaps > 200)\n        FNERR(1239);\n\n    while (pc < lastPC) {\n        if (currStack > VM_MAX_FUNCTION_STACK)\n            FNERR(1204);\n\n        FORCE_STACK(currStack, 1201, pc);\n\n        uint16_t opcode = code[pc++];\n        if (opcode == 0 && atEnd)\n            continue; // allow padding at the end\n\n        atEnd = false;\n        OpFun fn;\n        unsigned arg;\n        unsigned opIdx;\n        bool isRtCall = false;\n        bool hasPush = false;\n\n        if (opcode >> 15 == 0) {\n            opIdx = opcode & VM_OPCODE_BASE_MASK;\n            arg = opcode >> VM_OPCODE_ARG_POS;\n            hasPush = !!(opcode & VM_OPCODE_PUSH_MASK);\n        } else if (opcode >> 14 == 0b10) {\n            opIdx = opcode & 0x1fff;\n            arg = 0;\n            isRtCall = true;\n            hasPush = !!(opcode & VM_RTCALL_PUSH_MASK);\n        } else {\n            unsigned tmp = ((int32_t)opcode << (16 + 2)) >> (2 + VM_OPCODE_ARG_POS);\n            FORCE_STACK(0xffff, 1200, pc); // cannot jump here!\n            opcode = code[pc++];\n            opIdx = opcode & VM_OPCODE_BASE_MASK;\n            arg = (opcode >> VM_OPCODE_ARG_POS) + tmp;\n            hasPush = !!(opcode & VM_OPCODE_PUSH_MASK);\n        }\n\n        if (opIdx >= img->numOpcodes)\n            FNERR(1227);\n        auto opd = img->opcodeDescs[opIdx];\n\n        if (debug)\n            DMESG(\"%4d/%d -> %04x idx=%d arg=%d st=%d %s\", pc, lastPC, opcode, opIdx, arg,\n                  currStack, opd ? opd->name : \"NA\");\n\n        if (!opd)\n            FNERR(1228);\n\n        fn = img->opcodes[opIdx];\n\n        if (isRtCall) {\n            if (opd->numArgs > 1) {\n                currStack -= opd->numArgs - 1;\n                if (currStack < baseStack)\n                    FNERR(1229);\n            }\n        } else if (fn == op_pushmany) {\n            if (currStack == 1 && baseStack == 1)\n                baseStack = currStack = arg + 1;\n            else\n                currStack += arg;\n        } else if (fn == op_popmany) {\n            currStack -= arg;\n            if (currStack < baseStack)\n                FNERR(1205);\n        } else if (fn == op_push) {\n            currStack++;\n        } else if (fn == op_pop) {\n            if (arg)\n                FNERR(1243);\n            currStack--;\n            if (currStack < baseStack)\n                FNERR(1206);\n        } else if (fn == op_mapget) {\n            if (arg)\n                FNERR(1244);\n            currStack--;\n            if (currStack < baseStack)\n                FNERR(1245);\n        } else if (fn == op_mapset) {\n            if (arg)\n                FNERR(1246);\n            currStack -= 2;\n            if (currStack < baseStack)\n                FNERR(1247);\n        } else if (fn == op_ret) {\n            SPLIT_ARG(retNumArgs, numTmps);\n            if (currStack != baseStack)\n                FNERR(1207);\n            if (numTmps + 1 != (unsigned)baseStack)\n                FNERR(1208);\n            if (retNumArgs != numArgs)\n                FNERR(1209);\n            currStack = baseStack;\n            atEnd = true;\n        } else if (fn == op_ldloc || fn == op_stloc) {\n            if (arg == (unsigned)currStack - 1 || arg == (unsigned)currStack)\n                FNERR(1210); // trying to load return address/function\n            if (arg > (unsigned)currStack + numArgs)\n                FNERR(1211);\n        } else if (fn == op_ldcap) {\n            if (arg >= numCaps)\n                FNERR(1212);\n        } else if (fn == op_ldglb || fn == op_stglb) {\n            if (arg >= img->infoHeader->allocGlobals)\n                FNERR(1213);\n            // not supported (yet?)\n            if (arg < img->infoHeader->nonPointerGlobals)\n                FNERR(1214);\n        } else if (fn == op_ldfld || fn == op_stfld) {\n            SPLIT_ARG2(fldId, classId);\n\n            if (classId >= img->numSections)\n                FNERR(1236);\n            auto fsec = img->sections[classId];\n            if (fsec->type != SectionType::VTable)\n                FNERR(1234);\n\n            auto vt = getStaticVTable(img, classId);\n            if (fldId * 8 + 8 >= vt->numbytes)\n                FNERR(1235);\n\n            if (fn == op_stfld) {\n                currStack--;\n                if (currStack < baseStack)\n                    FNERR(1232);\n            }\n        } else if (fn == op_ldlit) {\n            if (arg >= img->numSections)\n                FNERR(1215);\n            auto fsec = img->sections[arg];\n            if (fsec->type != SectionType::Literal && fsec->type != SectionType::Function)\n                FNERR(1237);\n        } else if (fn == op_newobj || fn == op_checkinst) {\n            if (arg >= img->numSections)\n                FNERR(1219);\n            auto fsec = img->sections[arg];\n            if (fsec->type != SectionType::VTable)\n                FNERR(1238);\n        } else if (fn == op_ldnumber) {\n            if (arg >= img->numNumberLiterals)\n                FNERR(1217);\n        } else if (fn == op_callproc) {\n            if (arg >= img->numSections)\n                FNERR(1218);\n            auto fsec = img->sections[arg];\n            if (fsec->type != SectionType::Function)\n                FNERR(1220);\n            auto ra = (RefAction *)img->pointerLiterals[arg];\n            unsigned calledArgs = ra->numArgs;\n            currStack -= calledArgs;\n            if (currStack < baseStack)\n                FNERR(1221);\n        } else if (fn == op_callind) {\n            currStack -= arg;\n            if (currStack < baseStack)\n                FNERR(1223);\n        } else if (fn == op_calliface) {\n            SPLIT_ARG(numArgs, ifaceIdx);\n            if (ifaceIdx == 0 || ifaceIdx >= img->numIfaceMemberNames)\n                FNERR(1240);\n            currStack -= numArgs;\n            if (currStack < baseStack)\n                FNERR(1230);\n        } else if (fn == op_callget) {\n            if (arg == 0 || arg >= img->numIfaceMemberNames)\n                FNERR(1241);\n            currStack -= 1;\n            if (currStack < baseStack)\n                FNERR(1230);\n        } else if (fn == op_callset) {\n            if (arg == 0 || arg >= img->numIfaceMemberNames)\n                FNERR(1242);\n            currStack -= 2;\n            if (currStack < baseStack)\n                FNERR(1230);\n        } else if (fn == op_ldspecial) {\n            auto a = (TValue)(uintptr_t)arg;\n            if (a != TAG_TRUE && a != TAG_FALSE && a != TAG_UNDEFINED && a != TAG_NULL &&\n                a != TAG_NAN)\n                FNERR(1224);\n        } else if (fn == op_ldint || fn == op_ldintneg) {\n            // nothing to check!\n        } else if (fn == op_bitconv) {\n            if (arg & ~0x1f)\n                FNERR(1253);\n            auto sz = arg & 0xf;\n            if (sz != 1 && sz != 2 && sz != 4)\n                FNERR(1254);\n        } else if (fn == op_jmp || fn == op_jmpnz || fn == op_jmpz) {\n            unsigned newPC = pc + arg; // will overflow for backjump, but this is fine\n            if (newPC >= lastPC)\n                FNERR(1202);\n            FORCE_STACK(currStack, 1226, newPC);\n            if (fn == op_jmp) {\n                if (currStack != baseStack)\n                    FNERR(1203);\n                atEnd = true;\n            }\n        } else if (fn == op_try) {\n            unsigned newPC = pc + arg; // will overflow for backjump, but this is fine\n            if (newPC >= lastPC)\n                FNERR(1248);\n            if (currStack != baseStack)\n                FNERR(1249);\n            FORCE_STACK(currStack, 1250, newPC);\n        } else {\n            FNERR(1225);\n        }\n\n        if (hasPush)\n            currStack++;\n    }\n\n    if (!atEnd) {\n        pc--;\n        FNERR(1210);\n    }\n}\n\n} // namespace pxt","vm.h":"#ifndef _PXT_VM_H\n#define _PXT_VM_H\n\n#include <pthread.h>\n#include <setjmp.h>\n\n#define VM_MAGIC0 0x000a34365458500aULL // \\nPXT64\\n\\0\n#define VM_MAGIC1 0x6837215e2bfe7154ULL\n\n#define VM_OPCODE_BASE_SIZE 6 // up to 63 base opcodes\n#define VM_OPCODE_PUSH_MASK (1 << VM_OPCODE_BASE_SIZE)\n#define VM_OPCODE_ARG_POS (VM_OPCODE_BASE_SIZE + 1)\n#define VM_OPCODE_BASE_MASK ((1 << VM_OPCODE_BASE_SIZE) - 1)\n#define VM_FIRST_RTCALL (VM_OPCODE_BASE_MASK + 1)\n#define VM_RTCALL_PUSH_MASK 0x2000\n\n#define VM_FUNCTION_CODE_OFFSET (8 * 4)\n\n// The binary has space for 4 64 bit pointers, so on 32 bit machines we pretend there is 8 of them\n#ifdef PXT32\n#define VM_NUM_CPP_METHODS 8\n#else\n#define VM_NUM_CPP_METHODS 4\n#endif\n\n// maximum size (in words) of stack in a single function\n#define VM_MAX_FUNCTION_STACK 200\n#define VM_STACK_SIZE 1000\n\n#define VM_ENCODE_PC(pc) ((TValue)(((pc) << 9) | 2))\n#define VM_DECODE_PC(pc) (((uintptr_t)(pc)) >> 9)\n#define VM_IS_ENCODED_PC(v) ((((uintptr_t)(v)) & ((1 << 9) - 1)) == 2)\n#define TAG_STACK_BOTTOM VM_ENCODE_PC(1)\n\n#define PXTEXT extern\n#ifdef __MINGW32__\n#define DLLEXPORT PXTEXT \"C\"\n#else\n#define DLLEXPORT PXTEXT \"C\"\n#endif\n\nnamespace pxt {\n\nstruct FiberContext;\ntypedef void (*OpFun)(FiberContext *ctx, unsigned arg);\ntypedef void (*ApiFun)(FiberContext *ctx);\n\n// keep in sync with backvm.ts\nenum class SectionType : uint8_t {\n    Invalid = 0x00,\n\n    // singular sections\n    InfoHeader = 0x01,       // VMImageHeader\n    OpCodeMap = 0x02,        // \\0-terminated names of opcodes and APIs (shims)\n    NumberLiterals = 0x03,   // array of boxed doubles and ints\n    ConfigData = 0x04,       // sorted array of pairs of int32s; zero-terminated\n    IfaceMemberNames = 0x05, // array of 32 bit offsets, that point to string literals\n    NumberBoxes = 0x06,      // numbers from NumberLiteral that need to be boxed on 32 bit hosts\n\n    // repetitive sections\n    Function = 0x20,\n    Literal = 0x21, // aux field contains literal type (string, hex, image, ...)\n    VTable = 0x22,\n};\n\nstruct VMImageSection {\n    SectionType type;\n    uint8_t flags;\n    uint16_t aux;\n    uint32_t size; // in bytes, including this header\n    uint8_t data[0];\n};\n\nstatic inline TValue vmLiteralVal(VMImageSection *sect) {\n#ifdef PXT64\n    return (TValue)sect->data;\n#else\n    return (TValue)(sect->data + 4);\n#endif\n}\n\nstatic inline VMImageSection *vmNextSection(VMImageSection *sect) {\n    return (VMImageSection *)((uint8_t *)sect + sect->size);\n}\n\nstruct VMPatchState;\nVMPatchState *vm_alloc_patch_state();\nvoid vm_finish_patch(VMPatchState *state);\nconst char *vm_patch_image(VMPatchState *state, uint8_t *data, uint32_t len);\n\nSTATIC_ASSERT(sizeof(VMImageSection) == 8);\n\n#define PXT_WAIT_SOURCE_PROMISE 0x1fff0\n\nstruct OpcodeDesc {\n    const char *name;\n    OpFun fn;\n    int numArgs;\n};\n\nstruct IfaceEntry {\n    uint16_t memberId;\n    uint16_t aux;\n    uint32_t method;\n};\n\nextern const OpcodeDesc staticOpcodes[];\n\nstruct VMImageHeader {\n    uint64_t magic0;\n    uint64_t magic1;\n    uint64_t hexHash;\n    uint64_t programHash;\n\n    uint32_t allocGlobals;\n    uint32_t nonPointerGlobals;\n\n    uint64_t lastUsageTime;\n    uint64_t installationTime;\n    uint64_t publicationTime;\n    uint32_t imageSize;\n    uint8_t reserved[60];\n    uint8_t name[128];\n};\n\nstruct VMImage {\n    TValue *numberLiterals;\n    TValue *pointerLiterals;\n    BoxedNumber *boxedNumbers;\n    OpFun *opcodes;\n    int32_t *configData;\n    uintptr_t *ifaceMemberNames;\n\n    uint64_t *dataStart, *dataEnd;\n    VMImageSection **sections;\n    VMImageHeader *infoHeader;\n    const OpcodeDesc **opcodeDescs;\n    RefAction *entryPoint;\n\n    // every fiber's sp starts at stackTop and goes towards stackBase\n    // stackTop > stackBase\n    // stackLimit is close to stackBase\n    TValue *stackBase;\n    TValue *stackTop;\n    TValue *stackLimit;\n\n    uint32_t numSections;\n    uint32_t numNumberLiterals;\n    uint32_t numConfigDataEntries;\n    uint32_t numOpcodes;\n    uint32_t numIfaceMemberNames;\n    uint32_t errorCode;\n    uint32_t errorOffset;\n    int toStringKey;\n\n    int execLock;\n};\n\ntypedef TValue (*fiber_resume_t)(void *);\n\nstruct FiberContext {\n    FiberContext *next;\n\n    uint16_t *imgbase;\n    VMImage *img;\n    uint16_t *pc;\n    uint16_t *resumePC;\n    uint16_t *foreverPC;\n    TValue *sp;\n    TValue r0;\n    RefAction *currAction;\n\n    TryFrame *tryFrame;\n    TValue thrownValue;\n    jmp_buf loopjmp;\n\n    TValue *stackCopy;\n    int stackCopySize;\n\n    // wait_for_event\n    int waitSource;\n    int waitValue;\n\n    // for sleep\n    uint64_t wakeTime;\n\n    fiber_resume_t wakeFn;\n    void *wakeFnArg;\n    HandlerBinding *handlerBinding;\n};\n\n#define PXT_EXN_CTX() currentFiber\n\nvoid restoreVMExceptionState(TryFrame *tf, FiberContext *ctx);\n#define pxt_restore_exception_state restoreVMExceptionState\n\nFiberContext *suspendFiber(); // returns currentFiber\n// this can be called from a different thread; fn(arg) will be called from user code thread\n// just before the VM resumes execution; the result value will be stored in ctx->r0\nvoid resumeFiberWithFn(FiberContext *ctx, fiber_resume_t fn, void *arg);\n// a simpler version\nvoid resumeFiber(FiberContext *ctx, TValue v);\n\nextern VMImage *vmImg;\nextern FiberContext *currentFiber;\nextern volatile int panicCode;\n\nstatic inline uint16_t *actionPC(RefAction *ra) {\n    return (uint16_t *)((uint8_t *)vmImg->dataStart + (uint32_t)ra->func);\n}\n\nvoid vmStart();\nVMImage *loadVMImage(void *data, unsigned length);\nvoid unloadVMImage(VMImage *img);\nVMImage *setVMImgError(VMImage *img, int code, void *pos);\nvoid exec_loop(FiberContext *ctx);\nvoid vmStartFromUser(const char *fn);\nvoid target_yield();\n\n#define DEF_CONVERSION(retp, tp, btp)                                                              \\\n    static inline retp tp(TValue v) {                                                              \\\n        if (!isPointer(v))                                                                         \\\n            failedCast(v);                                                                         \\\n        if (getVTable((RefObject *)v)->classNo != btp)                                             \\\n            failedCast(v);                                                                         \\\n        return (retp)v;                                                                            \\\n    }\n\nDEF_CONVERSION(RefCollection *, asRefCollection, BuiltInType::RefCollection)\nDEF_CONVERSION(RefAction *, asRefAction, BuiltInType::RefAction)\nDEF_CONVERSION(RefRefLocal *, asRefRefLocal, BuiltInType::RefRefLocal)\nDEF_CONVERSION(RefMap *, asRefMap, BuiltInType::RefMap)\n\nDEF_CONVERSION(Buffer, asBuffer, BuiltInType::BoxedBuffer)\nDEF_CONVERSION(Image_, asImage_, BuiltInType::RefImage)\n\nString convertToString(FiberContext *ctx, TValue v);\n\n} // namespace pxt\n\n#endif","vmcache.cpp":"#include \"pxt.h\"\n#include <dirent.h>\n#include <stdio.h>\n#include <ctype.h>\n#include <dirent.h>\n#include <sys/stat.h>\n#include <time.h>\n\nstatic char *settings_path;\n\nnamespace vmcache {\n\nstatic char *dataPath;\n\n#define OFFSET_OF(structName, field) ((uintptr_t)(&((structName *)NULL)->field) - (uintptr_t)NULL)\n\nstruct FullHeader {\n    VMImageSection sect;\n    VMImageHeader header;\n};\n\nstatic char *scriptPath(const char *scriptId) {\n    for (auto p = scriptId; *p; ++p)\n        if (!isalnum(*p) && *p != '-' && *p != '_') {\n            dmesg(\"invalid scriptId: %s at '%c'\", scriptId, *p);\n            return NULL;\n        }\n    auto baseLen = strlen(dataPath);\n    auto idLen = strlen(scriptId);\n    auto pathBuf = (char *)malloc(baseLen + 20 + idLen);\n    strcpy(pathBuf, dataPath);\n    strcat(pathBuf, \"/scripts-v0\");\n    if (*scriptId) {\n        strcat(pathBuf, \"/\");\n        strcat(pathBuf, scriptId);\n    }\n    return pathBuf;\n}\n\nDLLEXPORT void pxt_vm_set_data_directory(const char *path) {\n    free(dataPath);\n    dataPath = strdup(path);\n\n    char tmp[strlen(dataPath) + 100];\n    strcpy(tmp, dataPath);\n    strcat(tmp, \"/settings-v0\");\n    free(settings_path);\n    settings_path = strdup(tmp);\n#ifdef __WIN32__\n    mkdir(settings_path);\n#else\n    mkdir(settings_path, 0777);\n#endif\n\n    dmesg(\"set vm cached dir %s\", dataPath);\n}\n\nint checkCache(const char *scriptId, bool updateTimestamp = true) {\n    auto pathBuf = scriptPath(scriptId);\n    if (!pathBuf)\n        return 0;\n    auto fh = fopen(pathBuf, updateTimestamp ? \"r+b\" : \"rb\");\n    free(pathBuf);\n    dmesg(\"cache %s for %s\", fh ? \"hit\" : \"miss\", scriptId);\n    if (fh) {\n        if (updateTimestamp) {\n            fseek(fh, OFFSET_OF(FullHeader, header.lastUsageTime), SEEK_SET);\n            int64_t now = time(NULL);\n            fwrite(&now, 1, 8, fh);\n        }\n        fclose(fh);\n        return 1;\n    }\n    return 0;\n}\n\nDLLEXPORT int pxt_vm_cache_hit(const char *scriptId) {\n    return checkCache(scriptId, false);\n}\n\nstatic int isValidHeader(FullHeader *fh) {\n    auto hd = &fh->header;\n    return fh->sect.type == SectionType::InfoHeader && fh->sect.size >= sizeof(FullHeader) &&\n           hd->magic0 == VM_MAGIC0 && hd->magic1 == VM_MAGIC1;\n}\n\nstatic int readHeader(const char *filepath, FullHeader *fh) {\n    memset(fh, 0, sizeof(*fh));\n    if (!filepath)\n        return 0;\n\n    auto fp = fopen(filepath, \"rb\");\n    int sz = 0;\n    if (fp != NULL) {\n        sz = (int)fread(fh, 1, sizeof(*fh), fp);\n        fclose(fp);\n    }\n    if (sz <= (int)sizeof(*fh))\n        return 0;\n    return 1;\n}\n\nstatic const char *readEntry(DIR *dp, FullHeader *hd) {\n    if (!dp)\n        return NULL;\n\n    for (;;) {\n        struct dirent *de = readdir(dp);\n        if (!de) {\n            closedir(dp);\n            return NULL;\n        }\n\n        if (de->d_name[0] == '.')\n            continue;\n\n        auto filepath = scriptPath(de->d_name);\n        readHeader(filepath, hd);\n        free(filepath);\n\n        if (!isValidHeader(hd))\n            continue;\n\n        hd->header.name[127] = 0; // make sure it's NUL terminated\n\n        return de->d_name;\n    }\n}\n\nstatic DIR *openCacheDir() {\n    auto dirpath = scriptPath(\"\");\n    auto dp = opendir(dirpath);\n    free(dirpath);\n    return dp;\n}\n\nstatic bool nameExists(const char *name) {\n    auto dp = openCacheDir();\n    FullHeader fh;\n    for (;;) {\n        if (!readEntry(dp, &fh))\n            break;\n        if (strcmp(name, (char *)fh.header.name) == 0)\n            return true;\n    }\n    return false;\n}\n\n//%\nRefCollection *list() {\n    auto res = Array_::mk();\n    registerGCObj(res);\n\n    auto dp = openCacheDir();\n    FullHeader fh;\n    for (;;) {\n        auto id = readEntry(dp, &fh);\n        if (!id)\n            break;\n        char buf[1024];\n        for (auto p = fh.header.name; *p; p++) {\n            if (*p == '\\\"' || *p < 32)\n                *p = '_';\n        }\n        snprintf(buf, 1023,\n                 \"{ \\\"id\\\": \\\"%s\\\", \\\"pubTime\\\": %lld, \\\"installTime\\\": %lld, \\\"usageTime\\\": %lld, \"\n                 \"\\\"name\\\": \\\"%s\\\" }\",\n                 id, fh.header.publicationTime, fh.header.installationTime, fh.header.lastUsageTime,\n                 fh.header.name);\n        auto str = mkString(buf, -1);\n        registerGCObj(str);\n        Array_::push(res, (TValue)str);\n        unregisterGCObj(str);\n    }\n\n    unregisterGCObj(res);\n    return res;\n}\n\nstatic int renameImage(uint8_t *data, int len) {\n    FullHeader *fh = (FullHeader *)data;\n    if (len < (int)sizeof(FullHeader))\n        return -1;\n    if (!isValidHeader(fh))\n        return -2;\n    fh->header.installationTime = (int64_t)time(NULL);\n    auto name = (char *)fh->header.name;\n    name[101] = 0; // make sure we have space at the end\n    dmesg(\"rename image from '%s'\", name);\n    if (nameExists(name)) {\n        int namelen = (int)strlen(name);\n        for (int i = 2; i <= 99; ++i) {\n            snprintf(name + namelen, 6, \" (%d)\", i);\n            if (!nameExists(name))\n                break;\n        }\n        dmesg(\"renamed to '%s'\", name);\n    } else {\n        dmesg(\"rename not needed\");\n    }\n    return 0;\n}\n\nDLLEXPORT int pxt_vm_save_in_cache(const char *scriptId, uint8_t *data, int len) {\n    if (!dataPath || len < 256)\n        return -1;\n    auto dp = scriptPath(\"\");\n#ifdef __WIN32__\n    mkdir(dp);\n#else\n    mkdir(dp, 0777);\n#endif\n    free(dp);\n    auto pathBuf = scriptPath(scriptId);\n    if (!pathBuf)\n        return -3;\n    if (renameImage(data, len))\n        return -4;\n    auto fh = fopen(pathBuf, \"wb\");\n    dmesg(\"saving %s in cache, %d bytes\", pathBuf, len);\n    free(pathBuf);\n    if (!fh)\n        return -2;\n    fwrite(data, len, 1, fh);\n    fclose(fh);\n    dmesg(\"saved.\");\n    return 0;\n}\n\nDLLEXPORT void pxt_vm_start(const char *fn);\n\nDLLEXPORT int pxt_vm_cache_start(const char *scriptId) {\n    if (!checkCache(scriptId))\n        return -1;\n    auto pathBuf = scriptPath(scriptId);\n    dmesg(\"starting %s from cache\", pathBuf);\n    pxt_vm_start(pathBuf);\n    return 0;\n}\n\n//%\nvoid run(String name) {\n    auto scriptId = name->getUTF8Data();\n    if (!checkCache(scriptId))\n        return;\n    auto pathBuf = scriptPath(scriptId);\n    dmesg(\"starting %s from cache from VM code\", pathBuf);\n    vmStartFromUser(pathBuf);\n}\n\n//%\nvoid del(String name) {\n    auto scriptId = name->getUTF8Data();\n    auto pathBuf = scriptPath(scriptId);\n    if (!pathBuf)\n        return;\n    dmesg(\"delete %s from cache\", pathBuf);\n    remove(pathBuf);\n    free(pathBuf);\n}\n\n} // namespace vmcache\n\nconst char *vm_settings_dir(void) {\n    if (settings_path)\n        return settings_path;\n    return \"/tmp\";\n}","vmload.cpp":"#include \"pxt.h\"\n\nnamespace pxt {\n\nVMImage *vmImg;\n\nstatic void vmStartCore(uint8_t *data, unsigned len) {\n    unloadVMImage(vmImg);\n    vmImg = NULL;\n\n    gcPreStartup();\n\n    auto state = vm_alloc_patch_state();\n    vm_patch_image(state, data, len);\n    vm_finish_patch(state);\n\n    auto img = loadVMImage(data, len);\n    if (img->errorCode) {\n        dmesg(\"validation error %d at 0x%x\", img->errorCode, img->errorOffset);\n        return;\n    } else {\n        dmesg(\"Validation OK\");\n    }\n    vmImg = img;\n\n    gcStartup();\n\n    globals = (TValue *)app_alloc(sizeof(TValue) * getNumGlobals());\n    memset(globals, 0, sizeof(TValue) * getNumGlobals());\n\n    initRuntime();\n}\n\nstatic void vmStartFile(const char *fn) {\n    auto f = fopen(fn, \"rb\");\n    if (!f) {\n        dmesg(\"cannot open %s\", fn);\n        return;\n    }\n\n    fseek(f, 0, SEEK_END);\n    auto len = (unsigned)ftell(f);\n    fseek(f, 0, SEEK_SET);\n    auto data = (uint8_t *)malloc(len + 16);\n    fread(data, len, 1, f);\n    fclose(f);\n\n    vmStartCore(data, len);\n}\n\nstatic uint8_t *vm_data;\nstatic unsigned vm_len;\nstatic const char *vm_filename;\n\nstatic void *multiStart(void *) {\n    if (vm_filename)\n        vmStartFile(vm_filename);\n    else\n        vmStartCore(vm_data, vm_len);\n    return NULL;\n}\n\nvoid vmStart() {\n    auto fn = pxt::initialArgv[1];\n    vmStartFile(fn);\n}\n\npthread_t vm_thread;\nint vm_has_thread;\n\nstatic void spinThread() {\n    if (vm_has_thread) {\n        void *dummy;\n        if (!panicCode)\n            panicCode = -1;\n        pthread_join(vm_thread, &dummy);\n        vm_has_thread = 0;\n    }\n    panicCode = 0;\n    pthread_create(&vm_thread, NULL, multiStart, NULL);\n    vm_has_thread = 1;\n}\n\nstatic void *startFromUserWorker(void *fn) {\n    void *dummy;\n    pthread_join(vm_thread, &dummy);\n    vm_thread = pthread_self();\n    panicCode = 0;\n    vmStartFile((char *)fn);\n    return NULL;\n}\n\nstatic const char *lastFN;\nvoid vmStartFromUser(const char *fn) {\n    pthread_t pt;\n    if (!fn && lastFN) {\n        dmesg(\"re-starting %s\", lastFN);\n        fn = lastFN;\n    }\n    lastFN = fn;\n    if (fn)\n        pthread_create(&pt, NULL, startFromUserWorker, (void *)fn);\n    systemReset();\n}\n\nDLLEXPORT void pxt_vm_start(const char *fn) {\n    vm_filename = fn;\n    spinThread();\n}\n\nDLLEXPORT void pxt_vm_start_buffer(uint8_t *data, unsigned len) {\n    vm_filename = NULL;\n    vm_data = data;\n    vm_len = len;\n    spinThread();\n}\n\n} // namespace pxt\n"},"corgio":{"README.md":"# Corgio\n\nA small wrapper to help in creating a Corgi based platformer.","corgio.ts":"/**\n* Sprite Wrapper for a Corgi Platformer\n*/\n//% weight=100 color=#d2b48c icon=\"\\uf1b0\"\n//% groups='[\"Create\", \"Movement\", \"Speak\", \"Properties\"]'\nnamespace corgio {\n    export enum CorgiFlags {\n        None = 0,\n        HorizontalMovement = 1 << 0,\n        VerticalMovement = 1 << 1,\n        UpdateSprite = 1 << 2,\n        CameraFollow = 1 << 3,\n        All = ~(~0 << 4)\n    }\n\n    export let _corgi_still: Image[] = [\n        img`\n            . . 4 . . . 4 . .\n            . 4 f 4 d 4 f 4 .\n            . 4 f 4 4 4 f 4 .\n            . e 4 d 4 d 4 4 .\n            . 4 4 f 4 f 4 f .\n            d e 4 4 4 4 4 e d\n            d d 4 e d e 4 d d\n        `,\n        img`\n            . . 4 . . . 4 . .\n            . 4 f 4 d 4 f 4 .\n            . 4 f 4 4 4 f 4 .\n            . e 4 d 4 d 4 4 .\n            . 4 4 f e f 4 f .\n            . e 4 4 4 4 4 e .\n            d e d 4 e 4 d e d\n            d d d e d e d d d\n        `,\n        img`\n            . . 4 . . . 4 . .\n            . 4 f 4 d 4 f 4 .\n            . 4 f 4 4 4 f 4 .\n            . e 4 d 4 d 4 4 .\n            . 4 4 f 4 f 4 f .\n            . e 4 4 4 4 4 e .\n            d e d 4 a 4 d e d\n            d d d e d e d d d\n        `,\n        img`\n            . . 4 . . . 4 . .\n            . 4 f 4 d 4 f 4 .\n            . 4 f 4 4 4 f 4 .\n            . e 4 d 4 d 4 4 .\n            . 4 4 f 4 f 4 f .\n            . e 4 4 4 4 4 e .\n            d e d 4 a 4 d e d\n            d d d e a e d d d\n        `,\n        img`\n            . . 4 . . . 4 . .\n            . 4 f 4 d 4 f 4 .\n            . 4 f 4 4 4 f 4 .\n            . e 4 d 4 d 4 4 .\n            . 4 4 f 4 f 4 f .\n            . e 4 4 4 4 4 e .\n            d e d 4 a 4 d e d\n            d d d e d e d d d\n        `,\n        img`\n            . . 4 . . . 4 . .\n            . 4 f 4 d 4 f 4 .\n            . 4 f 4 4 4 f 4 .\n            . e 4 d 4 d 4 4 .\n            . 4 4 f 4 f 4 f .\n            . e 4 4 4 4 4 e .\n            d e d 4 4 4 d e d\n            d d d e d e d d d\n        `,\n    ];\n\n    export let _corgi_left: Image[] = [\n        img`\n            . . . . . . . . . . . . . . . .\n            . . 4 . . . 4 . . . . . . . . .\n            . 4 f 4 d 4 f 4 . . . . . . . .\n            . 4 f 4 4 4 f 4 . . . . . . . .\n            . 4 4 d 4 d 4 4 . . . . . . . .\n            . e 4 f 4 f 4 e . . . . e 4 f .\n            . e 4 4 4 4 4 4 d . . . e 4 f .\n            f d 4 4 4 4 4 d d e e e 4 4 4 .\n            . 4 d d d 4 f d 4 4 4 4 4 4 . .\n            . . 4 d d f f d d 4 4 4 4 4 4 .\n            . . . . . d d d 4 4 f 4 f 4 4 .\n            . . . . . . d 4 d 4 f f f 4 d d\n            . . . . . . f . . . . . . . d f\n        `,\n        img`\n            . . . . . . . . . . . . . . . .\n            . . 4 . . . 4 . . . . . . . . .\n            . 4 f 4 d 4 f 4 . . . . . . . .\n            . 4 f 4 4 4 f 4 . . . . . . . .\n            . 4 4 d 4 d 4 4 . . . . e 4 f .\n            . e 4 f 4 f 4 e . . . . e 4 f .\n            . e 4 4 4 4 4 4 d e e e 4 4 4 .\n            f d 4 4 4 4 4 d d 4 4 4 4 4 . .\n            . 4 d d d 4 f d 4 4 4 4 4 4 4 .\n            . . 4 d d f f d d 4 f 4 f 4 4 .\n            . . . . . d d d 4 d f f f 4 d d\n            . . . . . . d 4 d . . . . . d f\n            . . . . . . f . . . . . . . . .\n        `,\n        img`\n            . . 4 . . . 4 . . . . . . . . .\n            . 4 f 4 d 4 f 4 . . . . . . . .\n            . 4 f 4 4 4 f 4 . . . . . . . .\n            . 4 4 d 4 d 4 4 . . . . e 4 f .\n            . e 4 f 4 f 4 e . . . . e 4 f .\n            . e 4 4 4 4 4 4 d e e e 4 4 4 .\n            f d 4 4 4 4 4 d d 4 4 4 4 4 . .\n            . 4 d d d 4 f d 4 4 4 4 4 4 4 .\n            . . 4 d d f f d d 4 f 4 f 4 4 .\n            . . . . d d d 4 4 d f f f 4 d d\n            . . . f d 4 . . . . . . . . d f\n            . . . . f . . . . . . . . . . .\n        `,\n        img`\n            . . 4 . . . 4 . . . . . . . . .\n            . 4 f 4 d 4 f 4 . . . . . . . .\n            . 4 f 4 4 4 f 4 . . . . . . . .\n            . 4 4 d 4 d 4 4 . . . . e 4 f .\n            . e 4 f 4 f 4 e . . . . e 4 f .\n            . e 4 4 4 4 4 4 d e e e 4 4 4 .\n            f d 4 4 4 4 4 d d 4 4 4 4 4 . .\n            . 4 d d d 4 f d 4 4 4 4 4 4 . .\n            . . 4 d d f f d d 4 f 4 f 4 . .\n            . . . . d d d 4 4 d f f f 4 d .\n            . . . f d 4 . . . . . . 4 d d .\n            . . . . . . . . . . . . . f . .\n        `,\n        img`\n            . . 4 . . . 4 . . . . . . . . .\n            . 4 f 4 d 4 f 4 . . . . . . . .\n            . 4 f 4 4 4 f 4 . . . . . . . .\n            . 4 4 d 4 d 4 4 . . . . e 4 f .\n            . e 4 f 4 f 4 e . . . . e 4 f .\n            . e 4 4 4 4 4 4 d e e e 4 4 4 .\n            f d 4 4 4 4 4 d d 4 4 4 4 4 . .\n            . 4 d d d 4 f d 4 4 4 4 4 4 . .\n            . . 4 d d f f d d 4 f 4 f 4 . .\n            . . . . d 4 d 4 4 d f f f 4 d .\n            . . . . d 4 . . . . . . 4 d d .\n            . . . . . f . . . . . . . f . .\n        `\n    ];\n\n    export let _corgi_right: Image[] = reflect(_corgi_left);\n\n    /**\n     * Creates a new corgi from an image and kind\n     * @param kind the kind to make the corgi\n     * @param x optional initial x position, eg: 10\n     * @param y optional initial y position, eg: 70\n     */\n    //% blockId=corgiCreate block=\"corgi of kind %kind=spritekind || at x %x y %y\"\n    //% expandableArgumentMode=toggle\n    //% inlineInputMode=inline\n    //% blockSetVariable=myCorg\n    //% weight=100\n    //% group=\"Create\"\n    //% help=corgio/create\n    export function create(kind: number,\n                            x: number = 10,\n                            y: number = 70): Corgio {\n        return new Corgio(kind, x, y);\n    }\n\n    // Round input towards 0; 1.4 becomes 1.0, -0.4 becomes 0.0\n    export function roundTowardsZero(input: number): number {\n        return Math.floor(input) + input < 0 ? 1 : 0;\n    }\n\n    // Normalize input number to 0, 1, or -1\n    export function normalize(input: number): number {\n        return input ? input / Math.abs(input) : 0;\n    }\n\n    // Set the animation for looking right to be the opposite of looking left\n    export function reflect(input: Image[]): Image[] {\n        let output: Image[] = [];\n        for (let i: number = 0; i < input.length; i++) {\n            let nextImage = input[i].clone();\n            nextImage.flipX();\n            output.push(nextImage);\n        }\n        return output;\n    }\n}\n\n/**\n * A Corgi Platformer\n **/\n//% blockNamespace=corgio color=\"#d2b48c\" blockGap=8\nclass Corgio extends sprites.ExtendableSprite {\n    private stillAnimation: Image[];\n    private _leftAnimation: Image[];\n    private _rightAnimation: Image[];\n\n    //% group=\"Properties\" blockSetVariable=\"myCorg\"\n    //% blockCombine block=\"horizontal speed\"\n    maxMoveVelocity: number;\n    //% group=\"Properties\" blockSetVariable=\"myCorg\"\n    //% blockCombine block=\"gravity\"\n    gravity: number;\n    //% group=\"Properties\" blockSetVariable=\"myCorg\"\n    //% blockCombine block=\"jump speed\"\n    jumpVelocity: number;\n    //% group=\"Properties\" blockSetVariable=\"myCorg\"\n    //% blockCombine block=\"max jumps in a row\"\n    maxJump: number;\n    //% group=\"Properties\" blockSetVariable=\"myCorg\"\n    //% blockCombine block=\"rate horizontal movement is slowed\"\n    decelerationRate: number;\n\n    private controlFlags: number;\n    private initJump: boolean;\n    private releasedJump: boolean;\n    private count: number;\n    private touching: number;\n    private remainingJump: number;\n    private script: string[];\n\n    public constructor(kind: number, x: number, y: number) {\n        super(corgio._corgi_still[0], kind);\n        this.maxMoveVelocity = 70;\n        this.gravity = 300;\n        this.jumpVelocity = 125;\n\n        this.initJump = true;\n        this.releasedJump = true;\n        this.maxJump = 2;\n        this.count = 0;\n        this.touching = 2;\n        this.remainingJump = this.maxJump;\n        this.script = [\n            \"bark\"\n        ];\n\n        this.controlFlags = corgio.CorgiFlags.None;\n\n        this.stillAnimation = corgio._corgi_still;\n        this._leftAnimation = corgio._corgi_left;\n        this._rightAnimation = corgio._corgi_right;\n\n        this.setFlag(SpriteFlag.StayInScreen, true);\n        this.ay = this.gravity;\n        this.x = x;\n        this.y = y;\n    }\n\n    /**\n     * Get the Corgio's sprite\n     */\n    //% group=\"Properties\"\n    //% blockId=corgSprite block=\"%corgio(myCorg) sprite\"\n    //% weight=8\n    //% deprecated=true\n    get sprite(): Sprite {\n        return this;\n    }\n\n    /**\n     * Make the character move in the direction indicated by the left and right arrow keys.\n     */\n    //% group=\"Movement\"\n    //% blockId=horizontalMovement block=\"make %corgio(myCorg) move left and right with arrow keys || %on=toggleOnOff\"\n    //% weight=100 blockGap=5\n    //% help=corgio/horizontal-movement\n    horizontalMovement(on: boolean = true): void {\n        this.updateFlags(on, corgio.CorgiFlags.HorizontalMovement);\n\n        game.onUpdate(() => {\n            if (!(this.controlFlags & corgio.CorgiFlags.HorizontalMovement)) return;\n\n            let dir: number = controller.dx();\n\n            this.vx = dir ? corgio.normalize(dir) * this.maxMoveVelocity :\n                                    corgio.roundTowardsZero(this.vx * this.decelerationRate);\n        })\n    }\n\n    /**\n     * Make the character jump when the up arrow key is pressed, and grab onto the wall when falling.\n     */\n    //% group=\"Movement\"\n    //% blockId=verticalMovement block=\"make %corgio(myCorg) jump if up arrow key is pressed || %on=toggleOnOff\"\n    //% weight=100 blockGap=5\n    //% help=corgio/vertical-movement\n    verticalMovement(on: boolean = true): void {\n        this.updateFlags(on, corgio.CorgiFlags.VerticalMovement);\n\n        controller.up.onEvent(ControllerButtonEvent.Released, () => {\n            this.releasedJump = true;\n        })\n\n        game.onUpdate(() => {\n            if (!(this.controlFlags & corgio.CorgiFlags.VerticalMovement)) return;\n\n            if (controller.up.isPressed()) {\n                if (this.contactLeft() && controller.right.isPressed()\n                        || this.contactRight() && controller.left.isPressed()) {\n                    this.remainingJump = Math.max(this.remainingJump + 1, this.maxJump);\n                }\n                this.jumpImpulse();\n            }\n\n            if ((this.contactLeft() && controller.left.isPressed()\n                    || this.contactRight() && controller.right.isPressed())\n                    && this.vy > - 10) {\n                this.ay = this.gravity >> 2;\n            } else {\n                this.ay = this.gravity;\n            }\n\n            if (this.contactBelow()) {\n                if (this.initJump) {\n                    this.remainingJump = this.maxJump;\n                }\n                this.initJump = true;\n            }\n        })\n    }\n\n    /**\n     * Set camera to follow corgio horizontally, while keeping the screen centered vertically.\n     */\n    //% group=\"Movement\"\n    //% blockId=followCorgi block=\"make camera follow %corgio(myCorg) left and right || %on=toggleOnOff\"\n    //% weight=90 blockGap=5\n    //% help=corgio/camera-follow\n    cameraFollow(on: boolean = true): void {\n        this.updateFlags(on, corgio.CorgiFlags.CameraFollow);\n\n        game.onUpdate(() => {\n            if (this.controlFlags & corgio.CorgiFlags.CameraFollow) {\n                scene.centerCameraAt(this.x, screen.height >> 1);\n            }\n        })\n    }\n\n    /**\n     * Make the character change sprite images when moving.\n     */\n    //% group=\"Movement\"\n    //% blockId=updateSprite block=\"change image when %corgio(myCorg) is moving || %on=toggleOnOff\"\n    //% weight=100 blockGap=5\n    //% help=corgio/update-sprite\n    updateSprite(on: boolean = true): void {\n        this.updateFlags(on, corgio.CorgiFlags.UpdateSprite);\n        game.onUpdate(() => {\n            if (!(this.controlFlags & corgio.CorgiFlags.UpdateSprite)) return;\n\n            this.count++;\n\n            if (this.vx == 0) {\n                this.setImage(this.pickNext(this.stillAnimation, 6));\n            } else if (this.vx < 0) {\n                this.setImage(this.pickNext(this._leftAnimation));\n            } else {\n                this.setImage(this.pickNext(this._rightAnimation));\n            }\n        })\n    }\n\n    /**\n     * Add new phrase for the character to bark\n     * @param input phrase to add to script, eg: \"bark\"\n     */\n    //% group=\"Speak\"\n    //% blockId=addScript block=\"teach %corgio(myCorg) the word %input\"\n    //% weight=95 blockGap=5\n    //% help=corgio/add-to-script\n    addToScript(input: string): void {\n        this.script.push(input);\n    }\n\n    /**\n     * Have the character say one of the phrases in the script at random\n     */\n    //% group=\"Speak\"\n    //% blockId=bark block=\"make %corgio(myCorg) bark!\"\n    //% weight=95 blockGap=5\n    //% help=corgio/bark\n    bark(): void {\n        this.say(Math.pickRandom(this.script), 250);\n    }\n\n    private jumpImpulse() {\n        if (this.remainingJump > 0 && this.releasedJump) {\n            this.releasedJump = false;\n            if (this.initJump) {\n                this.vy = -1 * this.jumpVelocity;\n                this.initJump = false;\n            } else {\n                this.vy = Math.clamp(\n                    (-4 * this.jumpVelocity) / 3,\n                    -30,\n                    this.vy - this.jumpVelocity\n                );\n            }\n            this.remainingJump--;\n        }\n    }\n\n    private updateFlags(on: boolean, flag: corgio.CorgiFlags): void {\n        if (on) this.controlFlags |= flag;\n        else this.controlFlags &= corgio.CorgiFlags.All ^ flag;\n    }\n\n    private pickNext(input: Image[], state: number = 3): Image {\n        return input[(this.count / state) % input.length];\n    }\n\n    private contactLeft(): boolean {\n        let screenEdge = game.currentScene().camera.offsetX;\n        return this.left - screenEdge <= this.touching\n                || this.isHittingTile(CollisionDirection.Left);\n    }\n\n    private contactRight(): boolean {\n        let screenEdge = screen.width + game.currentScene().camera.offsetX;\n        return screenEdge - this.right <= this.touching\n                || this.isHittingTile(CollisionDirection.Right);\n    }\n\n    private contactBelow(): boolean {\n        let screenEdge = screen.height + game.currentScene().camera.offsetY;\n        return screenEdge - this.bottom <= this.touching\n                || this.isHittingTile(CollisionDirection.Bottom);\n    }\n}\n","pxt.json":"{\n    \"name\": \"corgio\",\n    \"description\": \"A Corgi platformer\",\n    \"dependencies\": {\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"corgio.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"weight\": 79,\n    \"icon\": \"/static/libs/corgio.png\"\n}\n"},"darts":{"README.md":"# Darts\n\nA small wrapper for projecting a path.","darts.ts":"/**\n* A dart with path prediction\n*/\n//% weight=100 color=#6699CC icon=\"\\uf140\"\n//% groups='[\"Create\", \"Actions\", \"Properties\"]'\nnamespace darts {\n    /**\n     * Creates a new dart from an image and kind\n     * @param img the image for the sprite\n     * @param kind the kind to make the dart\n     * @param x optional initial x position, eg: 10\n     * @param y optional initial y position, eg: 110\n     */\n    //% blockId=dartsCreate block=\"dart %img=screen_image_picker of kind %kind=spritekind || at x %x y %y\"\n    //% expandableArgumentMode=toggle\n    //% inlineInputMode=inline\n    //% blockSetVariable=myDart\n    //% weight=100\n    //% group=\"Create\"\n    //% help=darts/create\n    export function create(img: Image,\n                            kind: number,\n                            x: number = 10,\n                            y: number = 110): Dart {\n        return new Dart(img, kind, x, y);\n    }\n\n    /**\n     * Convert degrees to radians\n     * @param degree to convert\n     * @return converted value in radians\n     */\n    export function degreeToRadian(degree: number): number {\n        return degree * Math.PI / 180;\n    }\n\n    /**\n     * Evaluate the x component of a given vector\n     * @param degree angle of vector\n     * @param magnitude magnitude of vector\n     * @return x component of vector\n     */\n    export function xComponent(degree: number, magnitude: number): number {\n        return magnitude * Math.cos(degreeToRadian(degree));\n    }\n\n    /**\n     * Evaluate the y component of a given vector\n     * @param degree angle of vector\n     * @param magnitude magnitude of vector\n     * @return y component of vector\n     */\n    export function yComponent(degree: number, magnitude: number): number {\n        return -magnitude * Math.sin(degreeToRadian(degree));\n    }\n}\n\n/**\n * A dart\n **/\n//% blockNamespace=darts color=\"#6699CC\" blockGap=8\nclass Dart extends sprites.ExtendableSprite {\n    private renderable: scene.Renderable;\n\n    private controlKeys: boolean;\n    private trace: boolean;\n\n    //% group=\"Properties\" blockSetVariable=\"myDart\"\n    //% blockCombine block=\"angle\"\n    //% weight=8\n    public angle: number;\n    //% group=\"Properties\" blockSetVariable=\"myDart\"\n    //% blockCombine block=\"power\"\n    //% weight=8\n    public pow: number;\n    //% group=\"Properties\" blockSetVariable=\"myDart\"\n    //% blockCombine block=\"tracing time (seconds)\"\n    //% weight=8\n    public iter: number;\n    //% group=\"Properties\" blockSetVariable=\"myDart\"\n    //% blockCombine block=\"trace color\"\n    //% weight=8\n    public traceColor: number;\n    //% group=\"Properties\" blockSetVariable=\"myDart\"\n    //% blockCombine block=\"gravity\"\n    //% weight=8\n    public gravity: number;\n    //% group=\"Properties\" blockSetVariable=\"myDart\"\n    //% blockCombine block=\"wind\"\n    //% weight=8\n    public wind: number;\n    //% group=\"Properties\" blockSetVariable=\"myDart\"\n    //% blockCombine block=\"angle adjust rate\"\n    //% weight=8\n    public angleRate: number;\n    //% group=\"Properties\" blockSetVariable=\"myDart\"\n    //% blockCombine block=\"power adjust rate\"\n    //% weight=8\n    public powerRate: number;\n\n    public constructor(img: Image,\n                        kind: number,\n                        x: number,\n                        y: number) {\n        super(img, kind);\n        this.x = x;\n        this.y = y;\n\n        this.gravity = 20;\n        this.pow = 50;\n        this.angle = 10;\n        this.angleRate = 1;\n        this.powerRate = 1;\n        this.iter = 3;\n        this.wind = 0;\n\n        this.renderable = scene.createRenderable(-0.5, (target, camera) => {\n            let xComp = darts.xComponent(this.angle, this.pow);\n            let yComp = darts.yComponent(this.angle, this.pow);\n            let xOffset = camera.offsetX;\n            let yOffset = camera.offsetY;\n\n            for (let i: number = 0.1; i < this.iter; i += i / 5) {\n                let x = this.x + i * xComp + (i ** 2) * this.wind / 2;\n                let y = this.y + i * yComp + (i ** 2) * this.gravity / 2;\n                target.setPixel(\n                    x - xOffset,\n                    y - yOffset,\n                    this.traceColor\n                );\n            }\n        }, () => !this.ay && this.trace);\n\n        this.controlKeys = false;\n        this.trace = false;\n        this.traceColor = 1;\n    }\n\n    /**\n     * NO LONGER NECESSARY -- the dart is now a sprite by itself.\n     * Gets the dart's sprite.\n     */\n    //% group=\"Properties\"\n    //% blockId=dartSprite block=\"%dart(myDart) sprite\"\n    //% weight=8\n    //% deprecated=true\n    get sprite(): Sprite {\n        return this;\n    }\n\n    /**\n     * Set whether to show the trace for the estimated path\n     * @param on whether to turn on or off this feature, eg: true\n     */\n    //% blockId=setTrace block=\"trace %dart(myDart) path estimate || %on=toggleOnOff\"\n    //% weight=50\n    //% group=\"Actions\"\n    //% help=darts/set-trace\n    public setTrace(on: boolean = true): void {\n        this.trace = on;\n    }\n\n    /**\n     * Throw the dart with the current settings\n     */\n    //% blockId=throwDart block=\"throw %dart(myDart)\"\n    //% weight=50\n    //% group=\"Actions\"\n    //% help=darts/throw-dart\n    public throwDart(): void {\n        this.vx = darts.xComponent(this.angle, this.pow);\n        this.vy = darts.yComponent(this.angle, this.pow);\n        this.ay = this.gravity;\n        this.ax = this.wind;\n    }\n\n    /**\n     * Stop the dart at the current location\n     */\n    //% blockId=stopDart block=\"stop %dart(myDart)\"\n    //% weight=50\n    //% group=\"Actions\"\n    //% help=darts/stop-dart\n    public stopDart(): void {\n        this.ay = 0;\n        this.ax = 0;\n        this.vx = 0;\n        this.vy = 0;\n    }\n\n    /**\n     * Set whether to control the dart with the arrow keys; left and right\n     * to adjust the angle, and up and down to increase / decrease power\n     * @param on whether to turn on or off this feature, eg: true\n     */\n    //% blockId=controlKeys block=\"control %dart(myDart) with arrow keys || %on=toggleOnOff\"\n    //% weight=50\n    //% group=\"Actions\"\n    //% help=darts/control-with-arrow-keys\n    public controlWithArrowKeys(on: boolean = true): void {\n        this.controlKeys = on;\n\n        game.onUpdate(() => {\n            if (this.controlKeys) {\n                this.angle -= controller.dx() * this.angleRate / 5;\n                this.pow -= controller.dy() * this.powerRate / 5;\n            }\n        })\n    }\n\n    destroy(effect?: effects.ParticleEffect, duration?: number) {\n        super.destroy(effect, duration);\n        this.renderable.destroy();\n    }\n\n    /**\n     * NO LONGER NECESSARY as this uses renderables now to draw onto the background.\n     */\n    //% blockId=updateBackground block=\"change %dart(myDart) background to image %img=background_image_picker\"\n    //% weight=15\n    //% group=\"Properties\"\n    //% deprecated=true\n    public updateBackground(img: Image): void {\n        scene.setBackgroundImage(img);\n    }\n}","pxt.json":"{\n    \"name\": \"darts\",\n    \"description\": \"A sprite with path projection\",\n    \"dependencies\": {\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"darts.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"weight\": 78,\n    \"icon\": \"/static/libs/darts.png\"\n}\n"},"device":{"README.md":"# device\n\nThe core library for fantasy game console target.\n\n","bigFood.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.food\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"bigBurger\": \"hwQgACAAAAAAAAAAAO7/AID4//8PAAAAAAAAAO67y+94h75rxg8AAAAAAO5mZrb7dmf/vmb8AAAAAOBrtmZmuy9i+P9t9gAAAAC+tru7ZrbsYob/3WsPAADAu7tEtGtm+yJ2/t+0DwAAvERbS0S0Zvsidu7fvfsAAExEtERERGbGInf/T037AMBERERERERrtixn/+9N6wDARERERLRLZLYsh+//TbsPwERLRERbS7S2LPbu/k20D0y0tUREu0S0tiyG7/5NtA9MtEtERERERLssZu/+TbQPTERERERERES7LHbn/020D0xEREREREREuyx35/9NtA9MRERERERERLQsd+buTUQPRkREu0RERES0LHfm701EDEa7RFtLREREtCx35u9NRAxGW0u0RERERLQsd+juTUQMRrRERERERES0LGfo7k1EDEZEREREtEtEtCxm7v5NRAxgRERLRLS1RLQsZu/+TUQOYES0tUREu0S0LHb//k1EDmBEREtEREREtCx37v9N5AAARkRERERERMQiZ+5PTeQAAEZEtEtERET0Ivfu3kvkAACwRLS1REREy3L37t5EDgAAAEtEu0RERCxi/++9RA4AAABgRERERLQsZv++S+QAAAAAAOZERLT7dob/u2TuAAAAAAAA7rvL73hnvmbmDgAAAAAAAADu/wCI+P/vDgAAAA==\",\n    \"bigDrumstick\": \"hwQgACAAAAAAAAAAIiIiAgAAAAAAAAAAAAAAIru7uyICAAAAAAAAAAAAILu7u7u74gAAAAAAAAAAAEJEu0S0u+sOAAAAAAAAACBERERLRLvrDgAAAAAAAABCRERERES0u+4AAAAAAAAAQkREREREtLvuAAAAAAAAsEREREREtES77g4AAAAAALBERERERLRLu+sOAAAAAACwRERERES0u7vrDgAAAAAAS0RERERERLS76w4AAAAAAEtERERERES7tCsOAAAAAABLTUREREREu0Qr4gAAAAAAS91ERERERERLKyIAAAAAAEvdREREREREu7siDgAAAABL1E1ERERERLu7Kw4AAAAAsNRNRERERES0RLsCAAAAALBE3URERERERES06wAAAAAAS0RNRERERES7tOsAAAAAAOBLREREREREtLvrAAAAAAAAvru7RERERLS76wAAAAAAAOC+u0tEtEREu+4AAAAAAAAA4O67RLtLtLvOAAAAAAAAAAAA7u7uu7vu2wwAAAAAAAAAAAAAAO7uzt3NAAAAAAAAAAAAAAAAAADb0cvMAAAAAAAAAAAAAAAAsBERvQwAAAAAAAAAAAAAAAAbEREMAAAAAAAAAAAAAAAAG9EdDAAAAAAAAAAAAAAAANvRywAAAAAAAAAAAAAAAAC7EQwAAAAAAAAAAAAAAAAAsMwAAA==\",\n    \"bigHam\": \"hwQgACAAAAAAAAAAACAiIiLu7u4AAAAAAAAAACAy3RERERE97gAAAAAAACAyHTEzMzMz3T0OAAAAAAAyER0zMzMzMzPd4wAAAAAgEz3T0TMzMzMz0z0OAAAAMjEzM93dPTMzMzMdDgAAINMxMzMzMz0zMzMzE+0AADIdMzMzMzPdHTEzMxPhAADSMTMzMzMz3dEdMzMTvQ4g0zMzMzMzMxM93TEzHTMOINMzMzMzMzMTM9PR09EzDjIdMzMzMzMz3TETPd3TPQ4yET0zMzMz090d0Tsz09EPMhHRPTMzMz0zM7szMzPRDzLRHT3T3d0zMzMzMzMzEQ8y0dPd3TMzMzMzMzMzMzEPshMz0z0zMzMzMzMzM9OxD77TPdM9MzMzMzMzMzPd4w7uMzEzMzMzMzMzMzMz3fsO4DsTMzMzMzMzMzMz3bP+AODuO90zMzMzMzMzHT37/wAA7u473d3d3d0dET3r//4AAODu7rvTERER0bNm/+8PAAAA4E5Eu7tmZmtmu+7vDwAAAABORLRGtES0u+vu/wAAAAAA4E5ERmRGtGvm6w8AAAAAAADuRERGtERmu+sAAAAAAAAA4E5ERmRGu7sOAAAAAAAAAADgTmRGtLvuAAAAAAAAAAAAAOBOS2TmAAAAAAAAAAAAAAAAvmbmDgAAAAAAAAAAAAAAAODuDgAAAAAAAA==\",\n    \"bigPizza\": \"hwQgACAAAAAAAAAAAAAAAAAAAAAAu0REAAAAAAAAAAAAAAAAu10VQQAAAAAAAAAAAAAAS11V0eUAAAAAAAAAAAAARtRdXUHlAAAAAAAAAAAAa4dV1R1dBAAAAAAAAAAAu22HJS4dVA4AAAAAAAAAu11VViLiUlQOAAAAAAAAS+Qu1SUiIt7UTQAAAAAAuz0i4tIlIyLeTe4AAAAAQF0lIiJeJTMi3uUAAAAAsFRVJSMiXlUi4tPlAAAAAEtd1SUzIl5V5T5dBADg7k5dVdVVIuJTVVVVVAQA60vrVFXVVu0+VdVVFdQOAL5DtN5VbYfdVVXVXRVUDgC+NENLVWWHXVVV1V1BRQAAuzQzRN1VVlVVVdVWQUUAALtLM0PUVVVV7lJlh9XlAABLu0QzRF1VJSIuZYcR7QQAu7REM7RUVSIi4lUW0d1NALBLSzNDu1UyIuJV0VTkTgAAu0QzQ7vUMiPiVUFdDgAAALBLRENETi0iPlVN5QAAAAAAvkQ0tOvU7lMV1OQAAAAAAOBLRETrvt1VUdTtAAAAAAAAu0REtE7d1UXU5AAAAAAAALBLRETr1NVFTQ4AAAAAAAAAu0REu0tE1O0OAAAAAAAAAOBOtLvr1E3uAAAAAAAAAAAA7kS0u+7k7gAAAAAAAAAAAODuu+vu7g4AAAAAAAAAAAAA6+7u7u4AAAAAAA==\",\n    \"bigTaco\": \"hwQgACAAAAAAAAAAAAAAAO7u7u7uAAAAAAAAAAAA4O5UVVVVRO4AAAAAAAAA4E5V5e7/5O5UDgAAAAAAQE5VVUTu/+7+TuUAAAAAAERmVuTu5P7v7u/lAAAAAEBVdkbu7u7//v/vVA4AAABUZXdITv7+/v//714OAABAJXJ35k7+//7v/+5ODgAATjJzRIf+/+/uVFVVRQ4A4EQickV35u5UVdXd3d0OAE6GLn5FduZU1U3dVVXdDgBud3dXZGZe1V1VVdVF3Q7gdER3VnTm1V1VVVVVVe0A4HVFZ0Z3Xl1V1VVdVdXtAE5lRWdn59XVVVVUVV3VDgBeZUV3Il5dVVVVVVVVRQ4AXnZEJzNUXVVVVVVFVe0AAG53dybi1VVVVdVVVd0OAABuInfnQtVVXVVV1dVNDgAALjNyZ15dVVVVVVXd7QAAAO4ucmdUXUVV1VXV3Q4AAAAg4mJn1V1V1VVVRe0AAAAA4HZn5tVdVVVV1d3tAAAAAAB4d+bVVVXVVVXdDgAAAAAAeHfm3dVVXV3d7QAAAAAAAGB2591VVd3d3eQAAAAAAABgZ+bdVVXd1N0OAAAAAAAAgHeG3dRV3d3tAAAAAAAAAACIhtTdVdXdDgAAAAAAAAAAAIjY3V3U7QAAAAAAAAAAAAAAQNTd3Q4AAAAAAAAAAAAAAABE7u4AAAAAAAAAAA==\",\n    \"bigCake\": \"hwQgACAAAAAAAAAAALC7u7u7u7u7AAAAAAAAAACws1vVO1NVvQAAAAAAAAAA2zNbVbVT3bUAAAAAAAAAsNM9W1W1U1VdCwAAAAAAALDdPVtVNVNVVQsAAAAAAACwPT07VVXTVdULAAAAAAAAOz09u1VVO13VCwAAAAAAsNszPbNVVTtdVb0AAAAAALDTMz2zVVU7VVW9AAAAAACwPTPTs1VVM1VVtQAAAAAA2zMz071VVTVVXbUAAAAAANszM9O9VVU1U1VVCwAAALA9MzPTM1NVvVNVXQsAAACwMzMz0zNbVb1TVV0LAAAAuzMzMzM9W1W1U1VdCwAAADszMzMzPVvVNdtVVbUAALAzMzMzM91bVVXbXVW1AAC7MzMzMzPd21XVO13VtQAAOzMzMzMzPdtV1TtVVbUAADsj7jszMz3bXd07Vd3VC7AzMiK+MzM9u93VM1Xd1QuwM+4i4jMzPaNd1b1d3dULOzPuIuIzMz2jXdW93V1VCzs97iLiMzPdo91dvdvd1b070y4ivjMz06PdXb3b3VW9sDPt7jszM9Oj3d29291VvQCrO90zMzMzvdvdvdvd3a0AAKrT3d0zMz3b3T3b3V2rAAAAqjPd3d3ds93du921owAAAACqOtPdPbO7u7u7M6sAAAAAAKCqO7O7uzMzM7MKAAAAAAAAAKqqqqqqqqqqAA==\",\n    \"bigDonut\": \"hwQgACAAAAAAAAAAAAAAu6qqqgAAAAAAAAAAAACwu9Pd3bPuAAAAAAAAAACwO93dbd09uu4AAAAAAAAAO91jNnY4PavrDgAAAAAAsNMzmzh2ONO7uu4AAAAAADs9Y4kzdjjTs7q+DgAAALAzM2M4M2Y70z2r6w4AAAA7NDMzMzMzMzPdo+vrAACwQyUzMzMzMzMjM73q6wAAO0MlMzMzMzMzVDI9uusAADtDNDMzs7szM1QyPbu7DrAzMzPTs6q7MzNE06O0tA6wMzMzPTujOiMzMzNKtLQOYDYz070zqjNCPjMzSrREDmuHM9OzozozQj4zs0q7RA5rhzPTO6ozMyMzM6NEs0QOa4cz0zu6MzMzM9OrRLPkADs2MzO7OzMzM2bdSjRD5AA7MzMzuzMzM2OJPUo0S+QAOzMzMzMzMzOWOD1KNEQOADszMzMzYzgzhjOtRLNEDgCwhjNEM2OHMzPTo0RD5AAAoJY4VDIzdjjTPUo0S+QAAKBjiVQyM2M2M6NEtEQOAAAAOmYjMyMzM6tKREvkAAAAADozMzNCPqtKRLREDgAAAACgMzMzQr5KRERL5AAAAAAAoLrT3SOzRES7RA4AAAAAAACqqqq6S7S7ROQAAAAAAAAA4O5LRLTuS+QOAAAAAAAAAADg7u7uu+sOAAAAAAAAAAAAAADu7u4OAAAAAAAAAA==\",\n    \"bigIceCream\": \"hwQgACAAAAAAAAAAAAAAAAAAAABERAAAAAAAAAAAAABARERE1V0EAAAAAAAwszMA1N1EVVXdRQAAAACwE9ERS93dVVRV1V0EAAAAOx3REd27XVVFVVXdRQAAANsd0R3R3VtVVVRV1U0AADMzHREdEd2xVVVFVVVNALPd3RMR3RHdEVtVVVRVRTDbEdHREdER3R2xVVVF1UWw3RERHR0RHdEd0VtVRd0EsN0REdHREdER3RFbVdXUBDDRHRHR0R0RHRHdsVXV1AQTER0R0dHdEdERMT1b1U0AExHREREd3RMR3REzW91NABMR0R0RHd09Ed0dMdvdTQATERHdEdHR3RMR3dGz3U0A273b0R3REd3TEd0Rs90EADvbERPdER3RPRHdHb1NAACwHRE90R3dET0d0R0xBAAAMBHd3RMd0R3dE9Ed0QMAABvREdET0RHd3dPRHREDAAAbHRER3REd0d0z0R0RAwAA0xEREd0RHdHdPdEd0QMAABMR3d3dEd0R3T3RHT0AAAAT0R0R3R3REd093REzAAAAE9ET3d0d0RHdvd0xAwAAANMR093dE9HR3bM7AwAAAAAwET3TPRPRMd27AAAAAAAAMBExuzsR3T09CwAAAAAAAAATEbMAM90zuwAAAAAAAAAAMB3RCwC7uwAAAAAAAAAAAAAzuwAAAAAAAAAAAAAAAA==\",\n    \"plate\": \"hwQxABgAAAAAAAAAsLu7CwAAAAAAAACw2xERvQsAAAAAAADbEREREb0AAAAAALAdEREREdELAAAAANsRERERERG9AAAAABsRERERERGxAAAAsB0REd0dERHRCwAAsBER3dHdERERCwAA2xHREd3dHRERvQAAGxHd0d3d3RERvQAAGxEd0d3d3R0RsQCwHdEd3RER3RsR0QuwEdERHRER0dsR0QuwEdHRHREREb0REQuwER3REREREb0dEQvbER3dEREREdEbEQvbER3dEREREdEbEb0b0REdEREREREbEb0b0REdERERERHbEb0b0REdERERERG7EbEb0REdERERERG7EbEb0REdERERERG9EbEb0REdERERERG9EbEb0REdERERERG9EbEb0REdERERERG9EbEb0REdERERERG9EbEb0REdERERERG9EbEb0REdERERERG9EbEb0REdERERERHdEbEb0REdERERERHdEbEb0REdERERERHdEb0bER0dEREREREdEb3bER3dEREREdEdEb3bER3dEREREdEdEQuwER3REREREd0dEQuwEdHRHREREb0REQuwEdERHRER0b0R0QuwHdEd3RER3dsR0QsAGxEd0d3d3RsRsQAAGxHd0d3dvR0RvQAA2xHREd3d2xERvQAAsBERHdG7HRERCwAAsB0REd0dERHRCwAAABsRERERERGxAAAAANsRERERERG9AAAAALAdEREREdELAAAAAADbEREREb0AAAAAAACw2xERvQsAAAAAAAAAsLu7CwAAAAA=\"\n}","bigFood.ts":"namespace sprites.food {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const bigBurger = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const bigDrumstick = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const bigHam = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const bigPizza = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const bigTaco = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const bigCake = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const bigDonut = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const bigIceCream = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const plate = image.ofBuffer(hex``);\n}\n","ns.ts":"//% color=#8854d0\nnamespace game {\n    /**\n     * Reset the current game. This is usually equivalent to pressing\n     * the reset button to restart the current program\n     */\n    //% blockId=arcade_game_reset block=\"reset game\"\n    //% group=\"Gameplay\" weight=10\n    //% help=game/reset\n    export function reset() {\n        control.reset();\n    }\n}\n\n//% color=\"#4b6584\"\nnamespace scene {\n\n}\n\n//% color=\"#cf6a87\"\nnamespace info {\n\n}\n\n//% color=#E30FC0\nnamespace music {\n\n}\n\n//% color=#B09EFF\nnamespace player {\n\n}\n\n//% color=#FF5722 weight=90 advanced=true\nnamespace control {\n\n}\n","pxt.json":"{\n    \"name\": \"device\",\n    \"description\": \"The fantasy game console library\",\n    \"dependencies\": {\n        \"hw\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"ns.ts\",\n        \"sprites.background.ts\",\n        \"sprites.background.jres\",\n        \"smallFood.jres\",\n        \"smallFood.ts\",\n        \"bigFood.jres\",\n        \"bigFood.ts\",\n        \"sprites.duck.jres\",\n        \"sprites.duck.ts\",\n        \"sprites.castle.jres\",\n        \"sprites.castle.ts\",\n        \"sprites.builtin.jres\",\n        \"sprites.builtin.ts\",\n        \"sprites.dialog.jres\",\n        \"sprites.dialog.ts\",\n        \"sprites.dungeon.jres\",\n        \"sprites.dungeon.ts\",\n        \"sprites.space.jres\",\n        \"sprites.space.ts\",\n        \"sprites.vehicle.ts\",\n        \"sprites.vehicle.jres\",\n        \"sprites.projectile.ts\",\n        \"sprites.projectile.jres\",\n        \"sprites.kaiju.ts\",\n        \"sprites.kaiju.jres\",\n        \"sprites.swamp.ts\",\n        \"sprites.swamp.jres\",\n        \"sprites.skillmap.ts\",\n        \"sprites.skillmap.jres\",\n        \"storySprites.ts\",\n        \"storySprites.jres\",\n        \"startup.ts\",\n        \"pxtsnippets.json\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"core\": true,\n    \"palette\": [\n        \"#000000\",\n        \"#ffffff\",\n        \"#ff2121\",\n        \"#ff93c4\",\n        \"#ff8135\",\n        \"#fff609\",\n        \"#249ca3\",\n        \"#78dc52\",\n        \"#003fad\",\n        \"#87f2ff\",\n        \"#8e2ec4\",\n        \"#a4839f\",\n        \"#5c406c\",\n        \"#e5cdc4\",\n        \"#91463d\",\n        \"#000000\"\n    ],\n    \"screenSize\": {\n        \"width\": 160,\n        \"height\": 120\n    }\n}\n","pxtsnippets.json":"[\n    {\n        \"name\": \"Create a Sprite\",\n        \"namespace\": \"sprites\",\n        \"group\": \"Create\",\n        \"label\": \"Create a sprite...\",\n        \"outputType\": \"blocks\",\n        \"initialOutput\": \"let $spriteName = sprites.create($spriteImage, $spriteKind)\",\n        \"questions\": [\n            {\n                \"title\": \"Draw your sprite\",\n                \"inputs\": [\n                    {\n                        \"answerToken\": \"spriteImage\",\n                        \"type\": \"spriteEditor\",\n                        \"defaultAnswer\": \"img`\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n. . . . . . . . . . . . . . . .\\n`\"\n                    }\n                ],\n                \"hint\": \"Sprites are 2D characters and objects used in all MakeCode Arcade games. Click and drag to draw your own sprite.\",\n                \"goto\": {\n                    \"question\": 1\n                }\n            },\n            {\n                \"title\": \"Name your sprite\",\n                \"inputs\": [\n                    {\n                        \"answerToken\": \"spriteName\",\n                        \"defaultAnswer\": \"mySprite\",\n                        \"type\": \"variableName\"\n                    }\n                ],\n                \"output\": \"\",\n                \"hint\": \"Naming sprites is important because you can use the name to refer to your sprite elsewhere in your program.\",\n                \"goto\": {\n                    \"question\": 2\n                }\n            },\n            {\n                \"title\": \"What kind of sprite is this?\",\n                \"inputs\": [\n                    {\n                        \"answerToken\": \"spriteKind\",\n                        \"defaultAnswer\": \"SpriteKind.Player\",\n                        \"type\": \"dropdown\",\n                        \"options\": {\n                            \"SpriteKind.Player\": \"Player\",\n                            \"SpriteKind.Enemy\": \"Enemy\",\n                            \"SpriteKind.Food\": \"Food\"\n                        }\n                    }\n                ],\n                \"goto\": {\n                    \"question\": 3,\n                    \"parameters\": [\n                        {\n                            \"answer\": \"SpriteKind.Player\",\n                            \"token\": \"spriteKind\",\n                            \"question\": 4\n                        }\n                    ]\n                },\n                \"hint\": \"The kind of sprite is used when two sprites overlap.\\n\\nIf none of the kinds match your sprite, just select \\\"Player\\\".\"\n            },\n            {\n                \"title\": \"Where should your sprite appear?\",\n                \"inputs\": [\n                    {\n                        \"label\": \"X (horizontal):\",\n                        \"defaultAnswer\": 80,\n                        \"answerToken\": \"xLocation\",\n                        \"type\": \"number\",\n                        \"min\": 0,\n                        \"max\": 160\n                    },\n                    {\n                        \"label\": \"Y (vertical):\",\n                        \"defaultAnswer\": 60,\n                        \"answerToken\": \"yLocation\",\n                        \"type\": \"number\",\n                        \"min\": 0,\n                        \"max\": 120\n                    }\n                ],\n                \"output\": \"$spriteName.setPosition($xLocation,$yLocation)\",\n                \"hint\": \"This location is where your sprite will be when the game begins. 0 for X means the left of the screen, 0 for Y means the top of the screen.\"\n            },\n            {\n                \"title\": \"Do you want to control your player with direction buttons?\",\n                \"inputs\": [\n                    {\n                        \"type\": \"yesno\",\n                        \"defaultAnswer\": false,\n                        \"answerToken\": \"$moveWithButtons\"\n                    }\n                ],\n                \"output\": \"controller.moveSprite($spriteName)\",\n                \"outputConditionalOnAnswer\": \"true\",\n                \"goto\": {\n                    \"question\": 3\n                },\n                \"hint\": \"If you choose \\\"Yes\\\", the direction buttons or \\\"D-Pad\\\" will move your player left, right, up and down respectively.\"\n            }\n        ]\n    }\n]\n","smallFood.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.food\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"smallBurger\": \"hwQQABAAAAAAAO4OiO7uAADsu+t3xusOwExEuy5mvg7AREVE7nLoy7xERETrYsjLTERERORizMRMREVE5HLsxEtERETkcujES0VEVORy6ORLRERE5GLs5EtERETkYuzku1REROtyzOSwRFRE7mLo5LBLRLQuxr4OAOxL63bM6w4AAOwOiO7uAA==\",\n    \"smallApple\": \"hwQQABAAAAAAAMDMzAwAAADA7O7u7gIAAOzu7u7uLgAA7u4iIuLuAuDuLiIiIuIC4O4iIiIiIi7g7i4iIiIiLs7MLCIiIiLkfGcsIiIiIuR37iIiIiIi5ODiRCIiIkLi4CJVJCIiQg4ALlQkIiIkDgAuIiIiROIAAOAuIiLiDgAAAODu7g4AAA==\",\n    \"smallLemon\": \"hwQQABAAAABEC7DMzAAAAFS0S91EzAAAVFVdRdVEDABAVVVVVdXEAEBRVVVFVUQMVFVVVV1FTQxUEVVV1VVEy1QRVVVV3UTEVFFVVVVNRMRUVVVVVU1ExEAVVVVV1UTLQBVRVVVVTcsAVBFVVVVdtABAVRVVVVW1AABEVVVFXUQAAABERMtMBA==\",\n    \"smallDrumstick\": \"hwQQABAAAAAAIiIiAAAAACCyuysCAAAAskREtOsAAABCREREuw4AAEtERES7DgAAS0RERLTrAABLTUREtOQAAEtNRES05AAAS9RERLvrAACwRE1Eu+4AAAC7RLTr7gAAAAC77u6+ywwAAAAAANsRwQAAAAAAsNHLAAAAAACw0QwAAAAAAAC7AA==\",\n    \"smallHam\": \"hwQQABAAAAAAAAAiIu4OAAAAItPd3eMAACATMTPTPQ4AMtE9MzMT4yATM9MzMxPjIN0zExEz0eMyMTMxE93d4zIxMxExMx3jMj3TMzMzE+My3T0zMzMd6yDTMTMzHbHu4DITERE9u+4A7jszu7vr7gAAvkRERO4OAACwS0S07gAAAAC77u4AAA==\",\n    \"smallPizza\": \"hwQQABAAAAAAAAAAAAC7RAAAAAAAu11NAAAAALsjU00AAAC7XSJSTQAAu11XI10EALA9MlVV1QS7SyUiVVfVBEu7NTJVVUUAS7RVVSNTTQBLtFRXIlJNALBES1UjU00AAEvkVFXVBAAAsETuVd0EAAAAS+Te7QAAAACw5O5OAAAAAADu7gQAAA==\",\n    \"smallDonut\": \"hwQQABAAAAAAAAC7q6oAAAAAuzMzow4AALAzMzMz6gAA2z0zMzPqDrDdMzMzM7oOsD0zszPTug7bPTOqM9NKDtszozoz00oO2zOjMzOtRA47MzszM61EDjozMzPTSrQOOjMzM61E5ACgMzPdSkTuAKA6M6pE5A4AAKqqRETuAAAAALu77gAAAA==\",\n    \"smallCake\": \"hwQQABAAAAAAALC7u7sLAAAAsLM9MwsAAAA7s9XTCwAAADuz1VOzAACwM71VU70AALAzvVVTtQAAOzO9XTM1CwA7Mz1bPdULsO4z01s1VQvgIz7TWzVVC+siPtNaNVWzO+4z09o9Vb07MzPT2r3dvbA6M93avd2tAKA6Pdq9O6sAAKCqqqqqCg==\",\n    \"smallIceCream\": \"hwQQABAAAAAAAAAAAEREAAAAM0tEXVUEADARvdTdVUUA0xERvVVdRTDdHRHRW9VFExHRERG91QQTEREdEbHdBNsREdER0dsEM90R0RERSwDT0R0RERFLAB0RHREdEb0AHRHRER0RPQATHRERHdEDABMzG9E7MwAAMDEwMwsAAAAAMwAAAAAAAA==\",\n    \"smallStrawberry\": \"hwQQABAAAAAAAADu7u7uDgAA7iIiIu7OAOAiREQk4s4ALkJFIiLuwgAuRCIiIiLOAC4kIkIi4s6AKGJmJiIkzGbod3cmIiLOYIZ3ZyJC4gwAZncmQuLuDABgZyIiIu4MAHZ3Zy7izgBgZ2h35+4MAIAIhnZ3zAAAAACAYGYGAAAAAAAAAAAAAA==\",\n    \"smallCherries\": \"hwQQABAAAAAAAODuDAAAAAAALiLCAAAAAOBC4i4MAAAA4CXi7uIAAADgJCLiwgAAAOAiIuLCAAAAyC4iIu4AAABoLCLizswAAGjI7C4i4gxghwDgQiLuzmCHAOAlIu7CdggA4CQi4sJ2iGbIIiLiwnZ2d2YsIu7CdoiIiMgiIgyGCAAAAO7MAA==\",\n    \"smallTaco\": \"hwQQABAAAAAAAADg7u5OAAAA4E5VVVUEAABeVczsTkUA4GWGzszuRABeImfoVVXl4GQiZ1VFVeXgZYdYRVVV5E52hlVVRVUOXiJWVFRV5QBeIlRVVVXkAF5nVVRFVQ4A4EZVVVXlAADgRlVFVeQAAABORVVVDgAAAOBUVeUAAAAAAEBEBAAAAA==\"\n}","smallFood.ts":"namespace sprites.food {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const smallBurger = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const smallApple = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const smallLemon = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const smallDrumstick = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const smallHam = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const smallPizza = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const smallDonut = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const smallCake = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const smallIceCream = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const smallStrawberry = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const smallCherries = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"food\"\n    export const smallTaco = image.ofBuffer(hex``);\n}\n","sprites.background.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.background\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"autumn\": \"hwSgAHgAAADd3d3d3d3d3T3TPTMzMzMzMzMzOzNERDQzMzMzMzMzMzMz0zPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3TMzMzMzMzMzM7u7u7tEREQzMzMzMzMzMzMz093d3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzOzu7s7M0NERES7uzMzMzMzMzMzM93d3d3d3d3d3T1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzO7M7M7M0NEREQ0M7s7MzMzMzMzM9Pd3d3d3d3dPbNERERERERERERERERERETd3d3d3d3d3TMzM7O7u7s7s7szM0M0RDQzM7O7MzMzMzO7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3TMzMzMzM7szMzMzMzM0RDMzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zMzMzszszMzMzMzMzRDQzM7O7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zM9OzO0MzNDMzM0MzQ7S7u7u7u7u7uzMzs7vT3T2zu7u7u7tERERERERERERERERERETd3d3d3d3d3d0z09MzM0RDMzMzM0O0S7S7u7u7OzMzMzMzu7szM93d3bO7u7tLRERERERERERERERERETd3d3d3d3d3d3d0909MzRDMzMzM0NEQzSzMzMzMzMzMzMzuzMzM93d3d09s7tLRERERERERERERERERETd3d3d3d3d3d3d3d3d3TNEMzMzMzNEM7O7MzMzQzMzM7O7OzMz093d3d3d3T1LRERERERERERERERERETd3d3d3d3d3d3d3d3d3T1EQzQzMzNDM7MzMzNDQ7O7u7szMz0z3d3d3d3d3d1NRERERERERERERERERETd3d3d3b27u7vd3d3d3UNERDNEMzMzMzMzMzNENDMzM7szM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d3b3T3d3UNEREM0MzMzMzMzM0NENESzuzszM9MzM93d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d293T3TTUNENDMzMzMzMzMzM0NEQzQzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dPdPd2zPTQ0REQzQzMzMzMzMzMzNERDMzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3d3TPduzMzRERERDM0MzMzMzMzM0NERDMzMzMzM9M93d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dMzPdszMzRERENEM0MzMzu7s7M0NERDQzMzMzM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d09MzPTMzszREREM0MzMzMzMzO7M0NERDQzMzMz0z0zM93d3d3d3d1NRERERERERERERERERETd3d3dPdMzMzMzMzMzRERERDMzMzMzMzOzOzNERDMzMzMzMzPd3d3d3d3d3d1NRERERERERERERERERETd3d3dMzMzMzMzMzNDRERERDOzu7u7u7u7uztENDMzMzM9M9Pd3d3d3d3d3d1DRERERERERERERERERETd3d09MzMzMzMzMzNDREREQzQzMzMzMzO7u0tERDQzMzPdMzPd3d3d3d3d3d1DRERERERERERERERERETd3T09MzMzMzMzMzNDRERENDMzMzMzMzMzs7tEMzMzMzPTM9Pd3d3d3d3d3bNLRERERERERERERERERETd3T0zMzMzMzMzMzNDRERENDMzMzMzMzMzMzNENDMzMzMzM93d3d3d3d09u7tLRERERERERERERERERETd3d09M90zMzMzNDNDREQ0MzMzMzMzMzMzMzOzuzszMzOzu7u7u7u7u7u7u7tLRERERERERERERERERETd3d3dPdMzMzMzNDMzNES0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDQzM0S0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDMzQ0M0MzMzu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDNDMzQzQ0MzMzszszs7S7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDRDM7Q0QzMzOzOzMzM0QzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3d1NRLQ7M0QztLs7MzM0Q0QzMzMzM7O7OzMzu7u7u7u7u7u7u0tERERERERERERERERERETd3d3d3d3d3d1NNLvdM0MzRDMzM0M0Q0QzMzOzu7u7MzM9M93d3d3d3d09s0tERERERERERERERERERETd3d3d3d3d3d3dtNvdMzMzQzMzM0Q0RLu7u7u7uzszMzPTMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d29u9PdMzMzMzMzM0RDRDS7u7s7MzszMzPTPTPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dvbu73d3dM90zMzMzMzRDNDMzMzMzszMzMzMzMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zMzMzMzNEREMzMzOzOzMzMzMzM9M93d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d2zuzszMzNEREQzM7O7MzMzMzMzMzMz3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zM7O7MzNERDQzMzMzMzMzMzMz3TPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d0z0zMz0zMzOzMzNERDMzMzMzMzMzMzPTPTPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d093TMzMzMzMzOzOzNERDQzMzMzMzMzMzMzMzPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3T3TPTMzMzMzMzMzOzNERDQzMzMzMzMzMzMz0zPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3TMzMzMzMzMzM7u7u7tEREQzMzMzMzMzMzMz093d3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzOzu7s7M0NERES7uzMzMzMzMzMzM93d3d3d3d3d3T1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzO7M7M7M0NEREQ0M7s7MzMzMzMzM9Pd3d3d3d3dPbNERERERERERERERERERETd3d3d3d3d3TMzM7O7u7s7s7szM0M0RDQzM7O7MzMzMzO7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3TMzMzMzM7szMzMzMzM0RDMzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zMzMzszszMzMzMzMzRDQzM7O7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zM9OzO0MzNDMzM0MzQ7S7u7u7u7u7uzMzs7vT3T2zu7u7u7tERERERERERERERERERETd3d3d3d3d3d0z09MzM0RDMzMzM0O0S7S7u7u7OzMzMzMzu7szM93d3bO7u7tLRERERERERERERERERETd3d3d3d3d3d3d0909MzRDMzMzM0NEQzSzMzMzMzMzMzMzuzMzM93d3d09s7tLRERERERERERERERERETd3d3d3d3d3d3d3d3d3TNEMzMzMzNEM7O7MzMzQzMzM7O7OzMz093d3d3d3T1LRERERERERERERERERETd3d3d3d3d3d3d3d3d3T1EQzQzMzNDM7MzMzNDQ7O7u7szMz0z3d3d3d3d3d1NRERERERERERERERERETd3d3d3b27u7vd3d3d3UNERDNEMzMzMzMzMzNENDMzM7szM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d3b3T3d3UNEREM0MzMzMzMzM0NENESzuzszM9MzM93d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d293T3TTUNENDMzMzMzMzMzM0NEQzQzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dPdPd2zPTQ0REQzQzMzMzMzMzMzNERDMzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3d3TPduzMzRERERDM0MzMzMzMzM0NERDMzMzMzM9M93d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dMzPdszMzRERENEM0MzMzu7s7M0NERDQzMzMzM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d09MzPTMzszREREM0MzMzMzMzO7M0NERDQzMzMz0z0zM93d3d3d3d1NRERERERERERERERERETd3d3dPdMzMzMzMzMzRERERDMzMzMzMzOzOzNERDMzMzMzMzPd3d3d3d3d3d1NRERERERERERERERERETd3d3dMzMzMzMzMzNDRERERDOzu7u7u7u7uztENDMzMzM9M9Pd3d3d3d3d3d1DRERERERERERERERERETd3d09MzMzMzMzMzNDREREQzQzMzMzMzO7u0tERDQzMzPdMzPd3d3d3d3d3d1DRERERERERERERERERETd3T09MzMzMzMzMzNDRERENDMzMzMzMzMzs7tEMzMzMzPTM9Pd3d3d3d3d3bNLRERERERERERERERERETd3T0zMzMzMzMzMzNDRERENDMzMzMzMzMzMzNENDMzMzMzM93d3d3d3d09u7tLRERERERERERERERERETd3d09M90zMzMzNDNDREQ0MzMzMzMzMzMzMzOzuzszMzOzu7u7u7u7u7u7u7tLRERERERERERERERERETd3d3dPdMzMzMzNDMzNES0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDQzM0S0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDMzQ0M0MzMzu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDNDMzQzQ0MzMzszszs7S7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDRDM7Q0QzMzOzOzMzM0QzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3d1NRLQ7M0QztLs7MzM0Q0QzMzMzM7O7OzMzu7u7u7u7u7u7u0tERERERERERERERERERETd3d3d3d3d3d1NNLvdM0MzRDMzM0M0Q0QzMzOzu7u7MzM9M93d3d3d3d09s0tERERERERERERERERERETd3d3d3d3d3d3dtNvdMzMzQzMzM0Q0RLu7u7u7uzszMzPTMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d29u9PdMzMzMzMzM0RDRDS7u7s7MzszMzPTPTPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dvbu73d3dM90zMzMzMzRDNDMzMzMzszMzMzMzMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zMzMzMzNEREMzMzOzOzMzMzMzM9M93d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d2zuzszMzNEREQzM7O7MzMzMzMzMzMz3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zM7O7MzNERDQzMzMzMzMzMzMz3TPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d0z0zMz0zMzOzMzNERDMzMzMzMzMzMzPTPTPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d093TMzMzMzMzOzOzNERDQzMzMzMzMzMzMzMzPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3T3TPTMzMzMzMzMzOzNERDQzMzMzMzMzMzMz0zPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3TMzMzMzMzMzM7u7u7tEREQzMzMzMzMzMzMz093d3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzOzu7s7M0NERES7uzMzMzMzMzMzM93d3d3d3d3d3T1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzO7M7M7M0NEREQ0M7s7MzMzMzMzM9Pd3d3d3d3dPbNERERERERERERERERERETd3d3d3d3d3TMzM7O7u7s7s7szM0M0RDQzM7O7MzMzMzO7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3TMzMzMzM7szMzMzMzM0RDMzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zMzMzszszMzMzMzMzRDQzM7O7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zM9OzO0MzNDMzM0MzQ7S7u7u7u7u7uzMzs7vT3T2zu7u7u7tERERERERERERERERERETd3d3d3d3d3d0z09MzM0RDMzMzM0O0S7S7u7u7OzMzMzMzu7szM93d3bO7u7tLRERERERERERERERERETd3d3d3d3d3d3d0909MzRDMzMzM0NEQzSzMzMzMzMzMzMzuzMzM93d3d09s7tLRERERERERERERERERETd3d3d3d3d3d3d3d3d3TNEMzMzMzNEM7O7MzMzQzMzM7O7OzMz093d3d3d3T1LRERERERERERERERERETd3d3d3d3d3d3d3d3d3T1EQzQzMzNDM7MzMzNDQ7O7u7szMz0z3d3d3d3d3d1NRERERERERERERERERETd3d3d3b27u7vd3d3d3UNERDNEMzMzMzMzMzNENDMzM7szM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d3b3T3d3UNEREM0MzMzMzMzM0NENESzuzszM9MzM93d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d293T3TTUNENDMzMzMzMzMzM0NEQzQzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dPdPd2zPTQ0REQzQzMzMzMzMzMzNERDMzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3d3TPduzMzRERERDM0MzMzMzMzM0NERDMzMzMzM9M93d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dMzPdszMzRERENEM0MzMzu7s7M0NERDQzMzMzM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d09MzPTMzszREREM0MzMzMzMzO7M0NERDQzMzMz0z0zM93d3d3d3d1NRERERERERERERERERETd3d3dPdMzMzMzMzMzRERERDMzMzMzMzOzOzNERDMzMzMzMzPd3d3d3d3d3d1NRERERERERERERERERETd3d3dMzMzMzMzMzNDRERERDOzu7u7u7u7uztENDMzMzM9M9Pd3d3d3d3d3d1DRERERERERERERERERETd3d09MzMzMzMzMzNDREREQzQzMzMzMzO7u0tERDQzMzPdMzPd3d3d3d3d3d1DRERERERERERERERERETd3T09MzMzMzMzMzNDRERENDMzMzMzMzMzs7tEMzMzMzPTM9Pd3d3d3d3d3bNLRERERERERERERERERETd3T0zMzMzMzMzMzNDRERENDMzMzMzMzMzMzNENDMzMzMzM93d3d3d3d09u7tLRERERERERERERERERETd3d09M90zMzMzNDNDREQ0MzMzMzMzMzMzMzOzuzszMzOzu7u7u7u7u7u7u7tLRERERERERERERERERETd3d3dPdMzMzMzNDMzNES0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDQzM0S0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDMzQ0M0MzMzu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDNDMzQzQ0MzMzszszs7S7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDRDM7Q0QzMzOzOzMzM0QzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3d1NRLQ7M0QztLs7MzM0Q0QzMzMzM7O7OzMzu7u7u7u7u7u7u0tERERERERERERERERERETd3d3d3d3d3d1NNLvdM0MzRDMzM0M0Q0QzMzOzu7u7MzM9M93d3d3d3d09s0tERERERERERERERERERETd3d3d3d3d3d3dtNvdMzMzQzMzM0Q0RLu7u7u7uzszMzPTMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d29u9PdMzMzMzMzM0RDRDS7u7s7MzszMzPTPTPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dvbu73d3dM90zMzMzMzRDNDMzMzMzszMzMzMzMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zMzMzMzNEREMzMzOzOzMzMzMzM9M93d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d2zuzszMzNEREQzM7O7MzMzMzMzMzMz3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zM7O7MzNERDQzMzMzMzMzMzMz3TPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d0z0zMz0zMzOzMzNERDMzMzMzMzMzMzPTPTPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d093TMzMzMzMzOzOzNERDQzMzMzMzMzMzMzMzPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3T3TPTMzMzMzMzMzOzNERDQzMzMzMzMzMzMz0zPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3TMzMzMzMzMzM7u7u7tEREQzMzMzMzMzMzMz093d3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzOzu7s7M0NERES7uzMzMzMzMzMzM93d3d3d3d3d3T1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzO7M7M7M0NEREQ0M7s7MzMzMzMzM9Pd3d3d3d3dPbNERERERERERERERERERETd3d3d3d3d3TMzM7O7u7s7s7szM0M0RDQzM7O7MzMzMzO7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3TMzMzMzM7szMzMzMzM0RDMzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zMzMzszszMzMzMzMzRDQzM7O7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zM9OzO0MzNDMzM0MzQ7S7u7u7u7u7uzMzs7vT3T2zu7u7u7tERERERERERERERERERETd3d3d3d3d3d0z09MzM0RDMzMzM0O0S7S7u7u7OzMzMzMzu7szM93d3bO7u7tLRERERERERERERERERETd3d3d3d3d3d3d0909MzRDMzMzM0NEQzSzMzMzMzMzMzMzuzMzM93d3d09s7tLRERERERERERERERERETd3d3d3d3d3d3d3d3d3TNEMzMzMzNEM7O7MzMzQzMzM7O7OzMz093d3d3d3T1LRERERERERERERERERETd3d3d3d3d3d3d3d3d3T1EQzQzMzNDM7MzMzNDQ7O7u7szMz0z3d3d3d3d3d1NRERERERERERERERERETd3d3d3b27u7vd3d3d3UNERDNEMzMzMzMzMzNENDMzM7szM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d3b3T3d3UNEREM0MzMzMzMzM0NENESzuzszM9MzM93d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d293T3TTUNENDMzMzMzMzMzM0NEQzQzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dPdPd2zPTQ0REQzQzMzMzMzMzMzNERDMzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3d3TPduzMzRERERDM0MzMzMzMzM0NERDMzMzMzM9M93d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dMzPdszMzRERENEM0MzMzu7s7M0NERDQzMzMzM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d09MzPTMzszREREM0MzMzMzMzO7M0NERDQzMzMz0z0zM93d3d3d3d1NRERERERERERERERERETd3d3dPdMzMzMzMzMzRERERDMzMzMzMzOzOzNERDMzMzMzMzPd3d3d3d3d3d1NRERERERERERERERERETd3d3dMzMzMzMzMzNDRERERDOzu7u7u7u7uztENDMzMzM9M9Pd3d3d3d3d3d1DRERERERERERERERERETd3d09MzMzMzMzMzNDREREQzQzMzMzMzO7u0tERDQzMzPdMzPd3d3d3d3d3d1DRERERERERERERERERETd3T09MzMzMzMzMzNDRERENDMzMzMzMzMzs7tEMzMzMzPTM9Pd3d3d3d3d3bNLRERERERERERERERERETd3T0zMzMzMzMzMzNDRERENDMzMzMzMzMzMzNENDMzMzMzM93d3d3d3d09u7tLRERERERERERERERERETd3d09M90zMzMzNDNDREQ0MzMzMzMzMzMzMzOzuzszMzOzu7u7u7u7u7u7u7tLRERERERERERERERERETd3d3dPdMzMzMzNDMzNES0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDQzM0S0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDMzQ0M0MzMzu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDNDMzQzQ0MzMzszszs7S7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDRDM7Q0QzMzOzOzMzM0QzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3d1NRLQ7M0QztLs7MzM0Q0QzMzMzM7O7OzMzu7u7u7u7u7u7u0tERERERERERERERERERETd3d3d3d3d3d1NNLvdM0MzRDMzM0M0Q0QzMzOzu7u7MzM9M93d3d3d3d09s0tERERERERERERERERERETd3d3d3d3d3d3dtNvdMzMzQzMzM0Q0RLu7u7u7uzszMzPTMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d29u9PdMzMzMzMzM0RDRDS7u7s7MzszMzPTPTPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dvbu73d3dM90zMzMzMzRDNDMzMzMzszMzMzMzMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zMzMzMzNEREMzMzOzOzMzMzMzM9M93d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d2zuzszMzNEREQzM7O7MzMzMzMzMzMz3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zM7O7MzNERDQzMzMzMzMzMzMz3TPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d0z0zMz0zMzOzMzNERDMzMzMzMzMzMzPTPTPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d093TMzMzMzMzOzOzNERDQzMzMzMzMzMzMzMzPT3d3d3d3d3U1EREREREREREREREREREQ=\",\n    \"cityscape\": \"hwSgAHgAAACZmZmZmZmZmZmZmZmZERERERER3d3d3d3d3d3d3b27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmREZERERERER0d3d3d3d3d3d3bu7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERER3dHR3d3d3d3d3bu9u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERER3d3d3d3d3d3d3b29u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERERERHR3d3d3d3d3bu7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmREREREREREREREREbG7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkRERERERERERHR3b3bu7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERERERHR3b3bu7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRERERERERHRHdEd3b27u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERHR3d3d3b27u7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERHRHd0d3b27u7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERER3d3d3b27u7u7u7u7u7u7u7t7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRkRGRERERERERER3dHd3b27vdvbu7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERkRERERERERERHdHd3b27u7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERERERER3dHd3d3d3d3d3bu7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERERERER3dHd3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZkRERERERERERERER3d3d3d3d3d27u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkRERkREREREREREd3d3d3d3d3d3d3bu729u7u7u7t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREZERERERERER0d3d3d3d3d3d3d3bu729u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkRERERERERERER3d0d0d3d3d3d3d27u7u9u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkRERERERERERER3R0d3d3d3d3d3d273bu9u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZGRERERERERERERER3d3d3d3d3d3d3d27u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERER0R0d3d3d3d3d3d3dvbu7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZEREREREREREREREREREREdHd3d3d3bu7u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERERERERERER3d3dvbu7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERERERERERER3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZGRERERERERERERERERER3d3d0d3d3d3d3d27u7u92727u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkRERERERERERERERHR3d3d3d3d3d3d3b27u7vdu717d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREREREREREREREdHd3d3d3d3d3d3d3d3du7vdu727d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERERERERERHR3d3d3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERERERERERER3d3d3d3d3d3d3b27u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREREREREREREREREREdHd3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkRERERERERERERERERERHR3d3d3d3d3d3du7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZERERERERERERERERERERERERsbvbu7u9u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZEREZEREREREREREREdHd3d3dvbu7u7u7u7u7u7t3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZEZEREREREREREREREdHd3d3dvbu7u7u7u7u7vdt7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZkRERERERERERERERHd3d3dvbvbu7u9u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZkREREREREREREREdHd3d3dvbu7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmREREREREREREREREdEd3d3d3d29u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZGREREREREREREREREREd3d3d3d3d3d3du7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZGREREREREREREREREdHd3d3d3d3d3d3du7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERHd3d3d3d3d3bu7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERHd0d3d3d3d3bvb27u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZkRkZkRERHd0d3d3d3du7vbu7u7vbu7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRERERHd3d3d3d3du7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERHd3d3d3d3du7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERHd3d3d3d3d3bu7u7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRGRERHd3d3d3d3d3bu7u7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRHdHd3R0d3d3d3d3d3d3d3dvbu7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmRHd3d3d3d3d3d3d3d3d3d3dvbu7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGREREREREdHd3d3d3d3d3d3d3d3dvbt7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERERERHR3d3d3d29u7u7u7u7u7t7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERHR3d3d3d3d3d29u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmRERERHR0R0d3d29u7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmRERERHR0R0d3bu7u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZERERERHR3d29u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZERERERHRHdG9u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZERERERHR3d3du7u7u7u7u7u7u7u7u7t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZEREREREREd3d3bu7u7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmREZEREREdHd3d3d3d29u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRGZEREREd3d3d3d3d3d3d29u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERERERHR3d3d3d3du7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERERERHR3d0d3RG929u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERERERHd3d0d0R29u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRERERERERERERER0d0d0R3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkRERERERERERHR3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERERERHd3d3d3d3d3d3d3d3du7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERERERHR3d3d3d3d3d27u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERERERER0d3d3d29u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkRGREREd3d0d0d3d3d3d27u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGREREd3d3d3d3d3d3d27vbu9u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGREREd3d3d3d3d3dHd2xu7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGREREd3d0d0d3d3d3d2927u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmREREd3d3d3d3d3d3d29u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkRERER3d3d3d3d3d293bu7u7u7u7t3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkRERERERER0d3d3d2927u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkRERERERER0d3d3d29u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3dvbu7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdHd0dHd3d3d3d3dvbu7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZ0d3d0d3dHd3d3d3du7u7u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d29u729u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d29u7vbu7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZEdHd3d3d3d3d3d3du729u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmREZEdHd3d3d3d3d3d3d3d3d3bu7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGREREREREREREREREd3d3d3d3d29u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGREREREREREREREREd3d3d3d3d29u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGREREREREREREREREREREd3d3bu7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRERERERERER3d3d3d3d3d27u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkRERERERER3d3d3d3d3bu7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERER3d3d3d3d3d3d3bu7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmREREdHd3d3d3d3d3d3d3d29u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRER3d3d3d3d3d3d3d3d3d3d3bu7u7u7u7t7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRER3d3d3d3d3d3d3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRER0d3d3d3d3d3d3d3d3d3d3d3d3d3du7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRkRGREREdHd3d3d3d3d3d3d3d3d3d29u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERkRERERER3d3d3d3d3d3d3d3d3bu927u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERERERER3d3d3d3d3d3d3b27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERERERER0d3d3d3d3d3d3b29u7u7u7t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZkRERERERERERERER3dHR3d3d3d3d3bu9u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkRERkRERERERERERER3d3d3d3d3d3d3bu7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREZERERERERERERERERHR3d3d3d3d3bu7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkRERERERERERERERERERHR3b27u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREREREREREREREREREREREbG7u7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZGRERERERERERERERERERERHR3b3bu7u7u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERERERER3d3d3b27u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERERERHR3d3d3b3bu727u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERERERHRHd0d3b27u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERERERER3d3d3b27vbvbu7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZGRERERERERERERERERER3dHd3b27vdvbu7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkRERERERERERERERER3d3d3b27u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkRERERERERERERERERHdHd3b27u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERERERERERER3dHd3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERERERERERER3d3d3d3d3d27u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREREREREREREREd3d3d3d3d3d3d3bu729u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREREREREREREREd3d3d3d3d3d3d3bu729u7u7u7t3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZERERERERERER0d3d3d3d3d3d3d27u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZEREZERERERER3R0d3d3d3d3d3d273bu9u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZEZERERERERER3d3d0d3d3d3d3d27u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZkRERERERER0R0d3d3d3d3d3d27u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZkREREREREREREREdHd3d3d3bu7u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERERERERERER3d3d3bu7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZGRERERERERERERERERER3d3d3d3d3d3du7u9u727u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZGREREREREREREREREdHd3d3d3d3d3d27u7u92727d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERERERHR3d3d3d3d3d3d3d27u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmREREREREREREdHd3d3d3d3d3d3d3d3du7vdu727u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZkRkZkREREREdHd3d3d3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRERERERERER3d3d3d3d3d3d3b27u73dvbt7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGREREREREREREdHd3d3d3d3d3d27u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERERERHR3d3d3d3d3d29u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRGRERERERERERERERER0b27u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERERERER3d3dvbu7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmREREREREdEd3dHdvbu7u7u7u7u7vbt7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERERERHd3d3dvbu7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGREREREREREd3d3dvbu7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGREREREREdEd3d3d3b27u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmREREREREdHd3d3d3d29u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmREREREREdHd3d3d3d3d3d3du7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZERHd3d3d3d3d3d3d3d3d3d3du7u7u7t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZERHd3d3d3d3d3bu7u7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZERHd0d3d3d3d3bu7u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZERHd3d3d3d3du7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmREZERHd0R3d3d29u7u72729u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRGZERHd3d3d3d3d3bu7u7u7vbvbu7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERHdHd3d0d3d3bu7u7u7u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERHdHd3R0d3d3bu7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERHd3d3d3d3d3d3d3d3d3d3dvbu7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRERERHd3d3d3d3d3d3d3d3d3d3d3d27u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkRERERERERERHR3d3d3d29u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERHR3d3d3d3d3d29u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERHR0R0d3d29u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERHR0R0d3bu7u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkRGRERERHR3d29u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERHRHdG9u7u7u7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERHR3d29u7u7u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERHR3d3d3bu7u7u7u7u7u7u7u7t3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmREREdHd3d3d3d29u7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkREdHd3d3d3d29u7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkRERERERER0d0d3R29u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkRERERERHR3d0d3RG9u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkRERERERHR3d3d3d29u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3c=\",\n    \"cityscape2\": \"hwSgAHgAAACZmZmZ0d3dHBGxuxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G70bsbu7y8u7u7u7u7u7u7u7u7vLvbu7u7uZmZmZEd3RHBGxuxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7y8y7u7u7u7u7u7u7u7vLu7u7u7uZmZmZEd3RHMy8uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebvbu7zMy7u7u7u7u7u7u7u7u7vLu7u7uZmZmZ0d3dHNy9u9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7HbvbvLvMu7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0dHRHNy9uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7EbvbvLu7u8u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7EbsbvLu7u8u7u7u7u7u7u7u7u7u7u7u7uZmZkR0d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7vLu7u7u7u7u7u7u7u7u7u7u7u7uZmZnR3d3dHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZnR3d3dHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZkRERERHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZmRndHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZERHdHNy9uxu9u7u7u7u7u7u7G727u7u7u7u7u7u727Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0d3dHMy8u9u9u8u7u7u7u7u7G7G7u7u7u7u7u7u7273bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZEd3dHBGxu9u9u7y7u7u7u7u7G7G7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0R3dHBGxuxu9u9y7u7u7u7u7G7G7u7u7u7u7u7u7G70bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0d3dHMy8uxuxu9y7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZERHdHNy9u9uxu7y7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbu7u7u7u7u7u7u7uZmZmZmRkRHNy9u9u9u8u7u7u7u7u72727u7u7u7u7u7u7G7Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmZmZmRndHNy9uxu9u7u7u7u7u7u7u727u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7uZmZmZERHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0dHRHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0dHRHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0dHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHMy8uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHBGxuxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmRkR0d3dHBGxu9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmRHd3d3dHMy8u9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u8u7uZGdHd3d3dHNy9u9u9u7u7u7u7u7u7u7u7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u8u7uZGd3dHd3dHNy9u9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZGd0d3d3dHNy9uxu9u7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7vLu7uZGd3d3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7vLu7uZGdEd3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7vLvLuZmREREdHdHNy9uxuxu7u7u7u7u7u727u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7vLy7uZmZmZGRHRHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7vLzLuZmZmZERHRHNy9uxuxu7u7u7u7u7u7G727u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7vbsbu7u7u7u7vLy7uZmZmZ0d0dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7vbvbu7u7u7u7vLu7yZmZkR0d3dHMy8uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7270bsbu7u7u7u7u7vLu7vbu7u7u7u7u8u7yZmZnR3d3dHBGxuxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G70bsbu7u7u7u7vLu7u7u7u7u7u7u7u7u7uZmZkR0d3dHBGxuxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7vLvbu7u7u7u7u7u7u7u7uZmZmZ0d3dHMy8uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebvbu7u7u7u7vLvbu7u7u7u7u7u7u7u7uZmZmZEdHdHNy9u9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Hbvbu7u7u7u7vLu7u7u7u7u7u7u7u7u7uZmZmZGRHdHNy9uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7vLu7u7u7u7u7u7u7u7uZmZmZGRERHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGd0dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGd3dHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGdHdHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGd3dHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGd3RHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGdHRHNy9uxu9u7u7u7u7u7u7G727u7u7u7u7u7u727Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7sZEREREdHdHMy8u9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u7273bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7sZ3d3d3d3dHBGxu9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7sZ3dHd3d3dHBGxuxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G70bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7sZ3dHd3d3dHMy8uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7sZ3d3d3d3dHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbu7u7u7u7u7u7u7sZ3d3d3d3dHNy9u9u9u7u7u7u7u7u72727u7u7u7u7u7u7G7Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxu9u7u7u7u7u7u7u727u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZ3R3dEd3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZEREREdHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZERHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZEd3RHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZEd3RHMy8uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3RHBGxuxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0dHRHBGxu9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZmZ0d3dHMy8u9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZkREdHdHNy9u9u9u7u7u7u7u7u7u7u7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmRnR3d3dHNy9u9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmRnd3d3dHNy9uxu9u7u7u7u7u7u7u7u7u7u8u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7uZmRkRERHdHNy9uxuxu7u7u7u7u7u7u7u7u8u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZmRHdHNy9uxuxu7u7u7u7u7u7u7u7u8u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZmdHdHNy9uxuxu7u7u7u7u7u727u7u8u8u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZmRERHNy9uxuxu7u7u7u7u7u72727u7vLu7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZmRHdHNy9uxuxu7u7u7u7u7u7G727u7vLvLu7u7u7G7Ebsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZmZmdHdHNy9uxuxu7u7u7u7u7u7G7G7u7u8vLu7u7u727Ebsbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmZmZmRHdHMy8uxuxu7u7u7u7u7u7G7G7u8vLvLu7u7u7270bsbu7u7u7u7u7u7u7vbu7u7u7u7u7u7uZmRkRERERHBGxuxuxu7u7u7u7u7u7G7G7u8u8vLu7u7u7G70bsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRndHd3RHBGxuxuxu7u7u7u7u7u7G7G7u8u7vLu7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRnd3d3dHMy8uxu9u7u7u7u7u7u7G7G7u8u7y7u7u7u7G7Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRnd3d3dHNy9u9u9u7u7u7u7u7u7G7G7u7y7u7u7u7u7G7Hbvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRndHd3RHNy9uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRnd3d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRkR0d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZEdHdHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmREREdHdHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmdHd3d3dHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZEdHd0d3dHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZ0d3d0dHdHNy9uxu9u7u7u7u7u7u7G727u7u7u7u7u7u727Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZ0d3d3d3dHMy8u9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u7273bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZ0d3d3d3dHBGxu9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZEdHd3d3dHBGxuxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G70bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmdHd3d3dHMy8uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRERERERHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbu7u7u7u7u7u7u7uZmZmZmZnRHNy9u9u9u7u7u7u7u7u72727u7u7u7u7u7u7G7Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmZmZERERHNy9uxu9u7u7u7u7u7u7u727u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZkR0d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmRER3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u8u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZEdHd3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7y7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxuxu7y7u7u7u7u7u7u7u7u7u9y7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxuxu7y7u7u7u7u7u7u7u7u7u9y7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZ0d3d3d3dHNy9uxuxu7y7u7u7u7u7u7u7u7u7u7y7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZEdHd3d3dHMy8uxuxu7y7u7u7u7u7u7u7u7u7u8u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmRER3d3dHBGxuxuxu8u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZkR0d3dHBGxu9uxu8y7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZmZEd3dHMy8u9uxu7y8u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZmZ0R3dHNy9u9u9y7u7u7u7u7u7u7u7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmZmZ0d3dHNy9u9uxy7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZmZERHdHNy9uxu9y7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7uZmZmZmRndHNy9uxuxy7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZmRkRHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZERHdHNy9uxuxu7u7u7u7u7u727u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7G727u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZmZ0dHRHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmZmZ0d3dHMy8uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7270bsbu7u7u7u7u7u7u7vbu7u7u7u7u7u7uZmZmZ0d3dHBGxuxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0d3dHBGxuxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0dHdHMy8uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0d3dHNy9u9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Hbvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRkR0d3dHNy9uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRnd3d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRHd3d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZGdHd3d3dHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZGd0d3d3dHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZGd3dHd3dHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZGdEd3d3dHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmREREdHdHNy9uxu9u7u7u7u7u7u7G727u7u7u7u7u7u727Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGRHRHMy8u9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u7273bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGRHRHBGxu9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZEdHdHBGxuxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G70bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZkR0d3dHMy8uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZnR3d3dHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbu7u7u7u7u7u7u7uZmZnR3d3dHNy9u9u9u7u7u7u7u7u72727u7u7u7u7u7u7G7Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmZkR0d3dHNy9uxu9u7u7u7u7u7u7u727u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7uZmZmZEdHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGRHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZmRkRHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGRHRHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGd3RHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGdHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGdHRHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGd3RHMy8uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGd3dHBGxuxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZEREREdHdHBGxu9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7sZ3d3d3d3dHMy8u9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9u9u9u7u7u7u7u7u7u7u7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7sZ3dHd3d3dHNy9u9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxu9u7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7sZ3dEd3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7270bsbu7u8u7u7u7u7sbsbu7u7u7u7u7u7sZ3R3dHd3dHNy9uxuxu7u7u7u7u7u727u7u7u7u7u7u7u7270bsbu7u8u7u7u7u7sbsbu7u7u7u7u7u7sZ3R3dEd3dHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G70bsbu7u7y7u7u7u7sbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxuxu7u7u7u7u7u7G727u7u7u7u7u7u7G7Ebsbu7u7y7u7u7u7vbsbu7u7u7vLu7u7sZ3d3d3d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u727Ebsbu7u7y7u7u7u7vbvbu7u7vLu7u7u7sZERER0d3dHMy8u9uxu7u7u7u7u7u7G7G7u7u7u7u7u7u7273bsbu7y7y7u7u7u7u7vbu7u7vLvbu7u7s=\",\n    \"desert\": \"hwSgAHgAAAAzMzMzMzMzMxERMzMzM2N3d3d3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMx0RMzMzM2N3d3d3d3d3d3d3M93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzExERMzMzM2N3d3d3d3d3d3d3N93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTERERMzMzM2N2d3d3d3d3d3d3N9Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRERERMzMzMzNmd3d3d3d3d3d3N9Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzM9MRERERMzMzMzMzZnd3d3d3d3d3Mz3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRERERMzMzMzMzM2ZmZnd3d3d30z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRERERMzMzMzMzMzNjZmZmZmY2093T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzM9MRERERM2ZmZmZmZmZmZmZmZmY23d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRERERZnZ3d3d3d3d3d3d3d2cz3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzPTERFhdnd3d3d3d3d3d3d3dzfT3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzHRFmd3d3d3d3d3d3d3d3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzERF2d3d3d3d3d3d3d3d3dzPd3d09093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzERF2d3d3d3d3d3d3d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzExF2d3d3d3d3d3d3d3d3N9Pd3d3dM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMx1md3d3d3d3d3d3d3d3N93d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxNhdnd3d3d3d3d3d3dnNt3d3d3dPdPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERZnZ3d3d3d3d3d2dmN93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERM2ZmZmZ3Z2ZmZmZ3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERMzMzM2N3ZzMzZnd3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxMRMzMzM2N3ZzNjdnd3N93d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMTMzMzZmZ3ZzNjd3d3N9Pd3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzMzMTMzNjdnd3ZzNmd3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNTVTMzMzMTMzN2d3d3ZzN2d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzMzPTMzN2d3d3ZjN2d3d3dzPd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzNjdndnNjN2d3d3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzZmY2MzN2d3d3dzfT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzN2d3d3d3fT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzN2d3d3d3cz3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzN2d3d3d3c33T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzNmd3d3d3c33dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzNjd3d3d3c309Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzNTMzMzMzMzNjdnd3d3d309Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNTVTUzMzMzMzMzZnd3d3d3M93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNVVTMzMzMzY2ZmZmZ3d3d3M93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNTVTUzMzNjZmZmZmZmd3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzNTMzMzNmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMz0zMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzEzMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzHTMzMzMzM2NmZmZmZmZmZmZmM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTETMzMzMzM2NmZmZmZmZmZmZmNt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRETMzMzMzMzNmZmZmZmZmZmZmNtPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRETMzMzMzMzNjZmZmZmZmZmZmNtPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTETMzMzMzMzMzM2NmZmZmZmZmMz3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzPTETMzMzMzMzMzMzMzM2Z3d3dn0z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRETMzMzMzMzMzMzMzY3Z3d3c3093T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRETMzMzMzMzMzMzMzY3d3d3c33d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxERETMzMzMzMzMzMzMzY3d3d3cz3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxERETMzMzM1MzMzMzMzdnd3dzfT3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxERETMzM1NVMzMzMzMzdnd3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRETMzMzM1MzMzMzMzdnd3dzPd3d09093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMdETMzMzMzMzMzMzMzdnd3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTETMzMzMzMzMzMzMzdnd3N9Pd3d3dM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzHTMzMzMzMzMzMzMzZnd3N93d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzEzMzMzMzZmZmZmYzY3d3N93d3d3dPdPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMz0zMzMzNjd3d3d2c2Y3Z3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzNjd3d3d3dmM2Z3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzZmZmZndnM2NmNt3d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzM3ZnMzNmNt3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzM3ZnZmZmNtPd3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNmZmZmZmZmZnZ3d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzM2N2d3d3d3d3d3d3d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzM3Z3d3d3d3d3d3d3d3d3dzPd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzM3Z3d3d3d3d3d3d3d3d3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzM2Z3d3d3d3d3d3d3d3d3dzfT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNTVTUzM2Nmd3d3d3d3d3d3d3d3d3fT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNVVTMzMzNjZmZmZmZmZmZ3d2ZmZmYz3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNTVTUzMzMzMzMzMzMzM2N2d2ZmZmY23T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzMzMzMzMzMzMzM2Z2d2ZmZmY23dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzNjZnd3d2ZmZmY209Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzN2d3d3Z2ZmZmZm09Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzNmd3dmZmZmZmZmM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzNjZmZmZmZmZmZmM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzM2NmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzPTMzMzMzMzM2NmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMTMzMzMzNjZmZ3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxMRMzMzMzNmd3d3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERMzMzM2N2d3d3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERMzMzM2N3d3d3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMx0RMzMzM2N3d3d3d3d3d3d3M93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzExERMzMzM2N3d3d3d3d3d3d3N93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTERERMzMzM2N2d3d3d3d3d3d3N9Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRERERMzMzMzNmd3d3d3d3d3d3N9Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzM9MRERERMzMzMzMzZnd3d3d3d3d3Mz3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRERERMzMzMzMzM2ZmZnd3d3d30z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRERERMzMzMzMzMzNjZmZmZmY2093T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzM9MRERERM2ZmZmZmZmZmZmZmZmY23d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRERERZnZ3d3d3d3d3d3d3d2cz3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzPTERFhdnd3d3d3d3d3d3d3dzfT3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzHRFmd3d3d3d3d3d3d3d3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzERF2d3d3d3d3d3d3d3d3dzPd3d09093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzERF2d3d3d3d3d3d3d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzExF2d3d3d3d3d3d3d3d3N9Pd3d3dM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMx1md3d3d3d3d3d3d3d3N93d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxNhdnd3d3d3d3d3d3dnNt3d3d3dPdPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERZnZ3d3d3d3d3d2dmN93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERM2ZmZmZ3Z2ZmZmZ3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERMzMzM2N3ZzMzZnd3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxMRMzMzM2N3ZzNjdnd3N93d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMTMzMzZmZ3ZzNjd3d3N9Pd3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzMzMTMzNjdnd3ZzNmd3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNTVTMzMzMTMzN2d3d3ZzN2d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzMzPTMzN2d3d3ZjN2d3d3dzPd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzNjdndnNjN2d3d3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzZmY2MzN2d3d3dzfT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzN2d3d3d3fT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzN2d3d3d3cz3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzN2d3d3d3c33T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzNmd3d3d3c33dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzNjd3d3d3c309Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzNTMzMzMzMzNjdnd3d3d309Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNTVTUzMzMzMzMzZnd3d3d3M93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNVVTMzMzMzY2ZmZmZ3d3d3M93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNTVTUzMzNjZmZmZmZmd3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzNTMzMzNmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMz0zMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzEzMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzHTMzMzMzM2NmZmZmZmZmZmZmM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTETMzMzMzM2NmZmZmZmZmZmZmNt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRETMzMzMzMzNmZmZmZmZmZmZmNtPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRETMzMzMzMzNjZmZmZmZmZmZmNtPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTETMzMzMzMzMzM2NmZmZmZmZmMz3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzPTETMzMzMzMzMzMzMzM2Z3d3dn0z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRETMzMzMzMzMzMzMzY3Z3d3c3093T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRETMzMzMzMzMzMzMzY3d3d3c33d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxERETMzMzMzMzMzMzMzY3d3d3cz3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxERETMzMzM1MzMzMzMzdnd3dzfT3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxERETMzM1NVMzMzMzMzdnd3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRETMzMzM1MzMzMzMzdnd3dzPd3d09093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMdETMzMzMzMzMzMzMzdnd3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTETMzMzMzMzMzMzMzdnd3N9Pd3d3dM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzHTMzMzMzMzMzMzMzZnd3N93d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzEzMzMzMzZmZmZmYzY3d3N93d3d3dPdPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMz0zMzMzNjd3d3d2c2Y3Z3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzNjd3d3d3dmM2Z3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzZmZmZndnM2NmNt3d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzM3ZnMzNmNt3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzM3ZnZmZmNtPd3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNmZmZmZmZmZnZ3d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzM2N2d3d3d3d3d3d3d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzM3Z3d3d3d3d3d3d3d3d3dzPd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzM3Z3d3d3d3d3d3d3d3d3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzM2Z3d3d3d3d3d3d3d3d3dzfT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNTVTUzM2Nmd3d3d3d3d3d3d3d3d3fT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNVVTMzMzNjZmZmZmZmZmZ3d2ZmZmYz3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNTVTUzMzMzMzMzMzMzM2N2d2ZmZmY23T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzMzMzMzMzMzMzM2Z2d2ZmZmY23dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzNjZnd3d2ZmZmY209Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzN2d3d3Z2ZmZmZm09Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzNmd3dmZmZmZmZmM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzNjZmZmZmZmZmZmM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzM2NmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzPTMzMzMzMzM2NmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMTMzMzMzNjZmZ3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxMRMzMzMzNmd3d3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERMzMzM2N2d3d3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0=\",\n    \"forest1\": \"hwSgAHgAAAAREREREREREREREREREREREdHd3d2ZmZmZmZmZmZmZmZlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERER3d3d3d2dmZmZmZmZmZmZmZZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREdHd3d3d3d2dmZmZmZmZmZaWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3d3dmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3dnZmZmZmZaWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREdHd3d3d3d3d3d3d3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZlpmZlmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d3ZmZlmlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1plpZmZplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1pZmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbd1tZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbW1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3W1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d1m1mZmZmZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3WZm1mZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3Wbd1mmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d1tmZmWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d2dmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d3d3d3d2ZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3d3Z2ZmWZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3d3ZlpaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dnWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d2dmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREd3d3d2dmZmZmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3d2ZmZmZmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3ZmZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3ZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERHR3d3d3ZmZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHR3ZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER3ZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZmZZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3d2ZmZmZmZmZmZmZmZlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERER3d3d3d2dmZmZmZmZmZmZmZZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREdHd3d3d3d2dmZmZmZmZmZaWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3d3dmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3dnZmZmZmZaWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREdHd3d3d3d3d3d3d3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZlpmZlmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d3ZmZlmlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1plpZmZplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1pZmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbd1tZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbW1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3W1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d1m1mZmZmZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3WZm1mZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3Wbd1mmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d1tmZmWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d2dmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d3d3d3d2ZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3d3Z2ZmWZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3d3ZlpaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dnWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d2dmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREd3d3d2dmZmZmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3d2ZmZmZmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3ZmZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3ZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERHR3d3d3ZmZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHR3ZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER3ZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZmZZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3d2ZmZmZmZmZmZmZmZlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERER3d3d3d2dmZmZmZmZmZmZmZZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREdHd3d3d3d2dmZmZmZmZmZaWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3d3dmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3dnZmZmZmZaWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREdHd3d3d3d3d3d3d3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZlpmZlmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d3ZmZlmlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1plpZmZplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1pZmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbd1tZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbW1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3W1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d1m1mZmZmZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3WZm1mZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3Wbd1mmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d1tmZmWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d2dmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d3d3d3d2ZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3d3Z2ZmWZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3d3ZlpaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dnWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d2dmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREd3d3d2dmZmZmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3d2ZmZmZmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3ZmZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3ZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERHR3d3d3ZmZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHR3ZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER3ZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZmZZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3d2ZmZmZmZmZmZmZmZlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERER3d3d3d2dmZmZmZmZmZmZmZZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREdHd3d3d3d2dmZmZmZmZmZaWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3d3dmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3dnZmZmZmZaWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREdHd3d3d3d3d3d3d3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZlpmZlmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d3ZmZlmlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1plpZmZplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1pZmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbd1tZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbW1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3W1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d1m1mZmZmZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3WZm1mZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3Wbd1mmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d1tmZmWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d2dmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d3d3d3d2ZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3d3Z2ZmWZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3d3ZlpaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dnWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d2dmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREd3d3d2dmZmZmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3d2ZmZmZmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3ZmZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3ZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERHR3d3d3ZmZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHR3ZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER3ZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZmZZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmY=\",\n    \"forest2\": \"hwSgAHgAAAB3d3d3d3d3d3d3d2ZmZmZmZra7u7u7u7vbmZmZmdndmZmZ3d3d3ZmZmdnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZmu7u7u7u7m5nZ3d2ZmZnd3d3d3d2dmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmtru7u7u7u5mZmZmZmdndmZmZmZndnZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dndmZmZmZmZmZt1p2ZmZmZmZndmZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dnd2ZmZmZmZmbd3d3dnZmZmZnZ3ZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZm3W3d3d3d2dmZmZ3ZmZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmZm2d3d3d3d3d2dmZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmlpmZmdmdmd3dnZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZpmZmdmZmdnd3d3d3d2ZmZmZmZmZmZmZmZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZmaWaZmZmZ2ZmZnd3d3d3d3d3d3d3d3d3d3d3ZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmaZmZmZ3Z2ZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmbbZt3dmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZma71pmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2Z2a2m5mZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZ3ZmZmu2aZmZmZmZmZ2d2ZmZmZmZmZmd3d3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmZmu7ubmZmZmZmZ3Z2ZmZmZmZmZmZmZmd3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmtru7m5mZmZnd3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmmZm7u5mZ2d3d3ZmZmZmZmZmZmZmZmZmZmd3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2Z2ZmlpmZu7vd3d3dmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZ2ZmZt3d3bvb3ZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZnZmbWZt3d3bm725mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmbZ3Z2ZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmaZmZmZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2ZmmWaZmZm9u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3b27u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmaZmd2du5uZmZmZmZmZmZmZmZmZmZmZmbu7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZrtrZpbZ3Z2Zu7uZmZmZmZmZu7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd7a7u9ZmmZmZububmZmZmbm7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd2e7u7u7u5uZububmZmZu7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dndndmtru7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmZra7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmaWubu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmZmmZm5u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZpaZmZmZubu7u7u7u7u7u7u7u7uZmZmZmdm7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZmZmaZmZmZmZmZmZmZubu7u7uZmZmZmZmZmdndvbu7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZplpmZmZmZmZm5u7ubmZmZmZmZmZmZmdnd3d27u7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZm1t3dnZmZu7u7u5uZmZmZmZmZmZmZmdnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmZmZmmZmZ2d29u7u7m5mZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmmZmZmZm7u9ndmZmZmZmZmZmZmd3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZndmZmZmZmZmlpmZmbm7m5nZ3Z2ZmZmZmZmZ3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZmZmZpm7u7u7mZmZmd2ZmZmZmZnZ3d3dndnd3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZra7u7u7u7vbmZmZmdndmZmZ3d3d3ZmZmdnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZmu7u7u7u7m5nZ3d2ZmZnd3d3d3d2dmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmtru7u7u7u5mZmZmZmdndmZmZmZndnZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dndmZmZmZmZmZt1p2ZmZmZmZndmZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dnd2ZmZmZmZmbd3d3dnZmZmZnZ3ZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZm3W3d3d3d2dmZmZ3ZmZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmZm2d3d3d3d3d2dmZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmlpmZmdmdmd3dnZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZpmZmdmZmdnd3d3d3d2ZmZmZmZmZmZmZmZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZmaWaZmZmZ2ZmZnd3d3d3d3d3d3d3d3d3d3d3ZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmaZmZmZ3Z2ZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmabZt3dmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZma71pmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2Z2a2m5mZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZ3ZmZmu2aZmZmZmZmZ2d2ZmZmZmZmZmd3d3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmZmu7ubmZmZmZmZ3Z2ZmZmZmZmZmZmZmd3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmtru7m5mZmZnd3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmmZm7u5mZ2d3d3ZmZmZmZmZmZmZmZmZmZmd3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2Z2ZmlpmZu7vd3d3dmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZ2ZmZt3d3bvb3ZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZnZmaWZt3d3bm725mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmaZ3Z2ZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmaZmZmZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2ZmmWaZmZm9u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3b27u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmaZmd2du5uZmZmZmZmZmZmZmZmZmZmZmbu7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZrtrZpbZ3Z2Zu7uZmZmZmZmZu7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd7a7u9ZmmZmZububmZmZmbm7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd2e7u7u7u5uZububmZmZu7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dndndmtru7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmZra7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmaWubu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmZmmZm5u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZpaZmZmZubu7u7u7u7u7u7u7u7uZmZmZmdm7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZmZmaZmZmZmZmZmZmZubu7u7uZmZmZmZmZmdndvbu7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZplpmZmZmZmZm5u7ubmZmZmZmZmZmZmdnd3d27u7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZm1t3dnZmZu7u7u5uZmZmZmZmZmZmZmdnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmZmZmmZmZ2d29u7u7m5mZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmmZmZmZm7u9ndmZmZmZmZmZmZmd3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZndmZmZmZmZmlpmZmbm7m5nZ3Z2ZmZmZmZmZ3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZmZmZpm7u7u7mZmZmd2ZmZmZmZnZ3d3dndnd3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZra7u7u7u7vbmZmZmdndmZmZ3d3d3ZmZmdnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZmu7u7u7u7m5nZ3d2ZmZnd3d3d3d2dmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmtru7u7u7u5mZmZmZmdndmZmZmZndnZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dndmZmZmZmZmZt1p2ZmZmZmZndmZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dnd2ZmZmZmZmbd3d3dnZmZmZnZ3ZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZm3W3d3d3d2dmZmZ3ZmZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmZm2d3d3d3d3d2dmZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmlpmZmdmdmd3dnZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZpmZmdmZmdnd3d3d3d2ZmZmZmZmZmZmZmZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZmaWaZmZmZ2ZmZnd3d3d3d3d3d3d3d3d3d3d3ZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmaZmZmZ3Z2ZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmabZt3dmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZma71pmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2Z2a2m5mZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZ3ZmZmu2aZmZmZmZmZ2d2ZmZmZmZmZmd3d3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmZmu7ubmZmZmZmZ3Z2ZmZmZmZmZmZmZmd3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmtru7m5mZmZnd3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmmZm7u5mZ2d3d3ZmZmZmZmZmZmZmZmZmZmd3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2Z2ZmlpmZu7vd3d3dmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZ2ZmZt3d3bvb3ZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZnZmaWZt3d3bm725mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmaZ3Z2ZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmaZmZmZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2ZmmWaZmZm9u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3b27u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmaZmd2du5uZmZmZmZmZmZmZmZmZmZmZmbu7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZrtrZpbZ3Z2Zu7uZmZmZmZmZu7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd7a7u9ZmmZmZububmZmZmbm7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd2e7u7u7u5uZububmZmZu7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dndndmtru7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmZra7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmaWubu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmZmmZm5u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZpaZmZmZubu7u7u7u7u7u7u7u7uZmZmZmdm7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZmZmaZmZmZmZmZmZmZubu7u7uZmZmZmZmZmdndvbu7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZplpmZmZmZmZm5u7ubmZmZmZmZmZmZmdnd3d27u7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZm1t3dnZmZu7u7u5uZmZmZmZmZmZmZmdnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmZmZmmZmZ2d29u7u7m5mZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmmZmZmZm7u9ndmZmZmZmZmZmZmd3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZndmZmZmZmZmlpmZmbm7m5nZ3Z2ZmZmZmZmZ3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZmZmZpm7u7u7mZmZmd2ZmZmZmZnZ3d3dndnd3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZra7u7u7u7vbmZmZmdndmZmZ3d3d3ZmZmdnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZmu7u7u7u7m5nZ3d2ZmZnd3d3d3d2dmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmtru7u7u7u5mZmZmZmdndmZmZmZndnZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dndmZmZmZmZmZt1p2ZmZmZmZndmZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dnd2ZmZmZmZmbd3d3dnZmZmZnZ3ZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZm3W3d3d3d2dmZmZ3ZmZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmZm2d3d3d3d3d2dmZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmlpmZmdmdmd3dnZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZpmZmdmZmdnd3d3d3d2ZmZmZmZmZmZmZmZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZmaWaZmZmZ2ZmZnd3d3d3d3d3d3d3d3d3d3d3ZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmaZmZmZ3Z2ZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmabZt3dmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZma71pmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2Z2a2m5mZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZ3ZmZmu2aZmZmZmZmZ2d2ZmZmZmZmZmd3d3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmZmu7ubmZmZmZmZ3Z2ZmZmZmZmZmZmZmd3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmtru7m5mZmZnd3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmmZm7u5mZ2d3d3ZmZmZmZmZmZmZmZmZmZmd3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2Z2ZmlpmZu7vd3d3dmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZ2ZmZt3d3bvb3ZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZnZmaWZt3d3bm725mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmaZ3Z2ZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmaZmZmZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2ZmmWaZmZm9u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3b27u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmaZmd2du5uZmZmZmZmZmZmZmZmZmZmZmbu7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZrtrZpbZ3Z2Zu7uZmZmZmZmZu7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd7a7u9ZmmZmZububmZmZmbm7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd2e7u7u7u5uZububmZmZu7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dndndmtru7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmZra7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmaWubu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmZmmZm5u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZpaZmZmZubu7u7u7u7u7u7u7u7uZmZmZmdm7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZmZmaZmZmZmZmZmZmZubu7u7uZmZmZmZmZmdndvbu7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZplpmZmZmZmZm5u7ubmZmZmZmZmZmZmdnd3d27u7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZm1t3dnZmZu7u7u5uZmZmZmZmZmZmZmdnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmZmZmmZmZ2d29u7u7m5mZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmmZmZmZm7u9ndmZmZmZmZmZmZmd3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZndmZmZmZmZmlpmZmbm7m5nZ3Z2ZmZmZmZmZ3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZmZmZpm7u7u7mZmZmd2ZmZmZmZnZ3d3dndnd3d3d3d3dd3d3d3d3d3d3d3c=\",\n    \"fossils\": \"hwSgAHgAAACZmZmZmZmZmWlmdnd3t7u77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u//////////////+ZmZmZmZmZmWl2d2dmtrvrvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/7///////////+ZmZmZmZmZmXZ3ZmZmtr7rvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/+7/7///////////+ZmZmZmZmZaWZmZmZ3trvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZl2Z2Z2t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZlmd2dmtru+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v//////////////+ZmZmZmZmZaZmZZnd3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaZaZmWZ3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaWeZaWZmtrvr7u7u7u7u7v7/7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmXZmZmZ3t7vr7u7u7u7u7v697+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmWl3Znd3tuu77u677u7u/r/d7+7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u///u//////////+ZmZmZmZlplpl2dndmtru76+677u7u/t3d/+7u7u7u7u7u7u7u7u7u7u7u7u7+/+7u/v/u//////////+ZmZmZmZlpZ5Zpd2Zmtru7u+7u7u7u/tvd++/u7u7u7u7u7u7u7u7u/+///////f/u7v////////////+ZmZmZmZmZdmdmZ3Z3t7u7u+7u7u7u/v//3f/u7u7u7u7u7u7u7u7uv/+/v/vfvf3u7v////////////+ZmZmZmZmZaXdnZmZ3t7vrvuvu6+7u7u7+3/v/7+7u7u7u7u7u7v7/v/u7v//du/3/7/7//v////////+ZmZmZmZmZmWZ3d3d3t7vrvuvu7u7u7u7u/9297+7u7u7u7u7u7v7d//v7/////73d7/7///////////+ZmZmZmZmZmZlmZnd3tru7u+vu7u7u7u7u/t3d7+7u7u7u7u7u7v/b/fv7393/37v9//////////////+ZmZmZmZmZmZmZZnd3t7u7u+7u7u7u7u7u/t377+7u7u7u7u7u7t+7/f//u9v939u92/////////////+ZmZmZmZmZmZlmd3dmtru7u+677u7u7u7u/tvv7u7u7u7u7u7+/9+9/d/dvdv9/9+73f/u//////////+ZmZmZmZmZmWZ3Z2Z2t7u+6+677u7u7u7u/v/v7u7u7u7u7u7+3fv9//+73bv97v/f+//u//////////+ZmZmZmZmZaXdnZmZ3tru77u7u7u7u7u7u7u7u7u7u7u7u////3/v9/t29273/7u7///////////////+ZmZmZmZmZaWZmdmZntrvr7u7u7u7u7u7u7u7u7u7u7u7+393///3//7vdu/3u7u7+v93///////////+ZmZmZmZmZmWlmdmdmtrvr6+7u7u7u7u7u7u7u7u7u7u7/3d39/v/b3b3bvf3u7u7+3d3///////////+ZmZmZmZmZmWZmZndntrvu7u7u7u7u7u7u7u7u7u7u7v7f3d29////393b/f3u7u7//d/d//////////+ZmZmZmZmZmXZnZmZ3t7vu7u7u7u7u7u7u7u7u7u7u7v/d3d3d3e/u/937/f3u7u7//f/d/f////////+ZmZmZmZmZmWl3Z2Zmu7vu7u7u7u7u7u7u7u7u7u7u7t/d/93b3f3u/t///f3u7u7/3f/d3f////////+ZmZmZmZmZmZlmd3d3t7vu7u7u7u7u7u7u7u7u7u7u/t/9/9/b3f3v7t///f3u7u7/393d3f////////+ZmZmZmZmZmZlpZnd3t7vr7rvu7u7u7u7u7u7u7u7u/t3//9/b3d3v7t///f/u7u6//97d3f////////+ZmZmZmZmZmWl2d2dmtrvr7rvu7u7u7u7u7u7u7u7u/t3//9+73d3v7v///e7u7v/fu9/d/f////////+ZmZmZmZmZmXZ3ZmZ3t+u77u7u7u7u7u7u7u7u7u7u/t3//92/3d3/7u7+/+7u/9/dvf////////////+ZmZmZmZmZaXdmZnd3t7u76+7u7u7u7u7u7u7u7u7u/t393/3/3d39/v/v7u7u3939//////////////+ZmZmZmZmZaWZmdmdmtrvrvu7r7u7u7u7u7u7u7u7u/t3d3f3+3d39/t3v7u7u3/3/7////f////////+ZmZmZmZmZmZlpdmZmu7vrvu7u7u7u7u7u7u7u7u7u/t3/3f3+3d39/t3v7u7uv/v+7//f/f////////+ZmZmZmZmZZmZmZmZ3t7u7u+vu7u7u7u7u7u7u7u7u/v3/3f/+3939/tvv7u7uv/3v7v7f//////////+ZmZmZmZmZdndmZnZntru7u+u+6+7u7u7u7u7u7u7u/v3/3e/u/9397t//7u7u393/7v6/+/////////+ZmZmZmZmZaXZ3Z2Zmtru+u+u+6+7u7u7u7u7u7u7u/v3/3f/u/9397t/97u7u/9397/6//f////////+ZmZmZmZmZmWl2d3dmtru7u+vu7u7u7u7u7u7u7u7u/v3f3f3u393/7t/9/v/u/v/d7/7f/f////////+ZmZmZmWZmZmZmZnd3t7u7u+7u7u7u7u7u7u7u7u7u/93d/f/u393v7t/9//3u7v7/7//d//////////+ZmZmZmWZ3d3d3d3d3t7vru+7r7u7u7u7u7u7u7u7u393d3e/u393v7r+73/3u////7v+7//////////+ZmZmZmZlmZnZ3d3d3u7u76+7u7u7u7u7u7u7u7u7u39/d++/u393v/ru93f//3/3v/v/d//////////+ZmZmZmZmZmWlmdnd3t7u77u7u7u7u7u7u7u7u7u7u3//d/+/u/9vv/r29+//f3f/u/9/9//////////+ZmZmZmZmZmWl2d2dmtrvrvuvu7u7u7u7u7u7u7u7u3/3d3e/u393v/r3b3f/d/e/+/7v///////////+ZmZmZmZmZmXZ3ZmZmtr7rvuvu7u7u7u7u7u7u7u7u3929/+/u/9vv/t3/////////373///////////+ZmZmZmZmZaWZmZmZ3trvu7u7u7u7u7u7u7u7u7u7u393d3e/u3/3v/t/97v7////du93///////////+ZmZmZmZmZmZl2Z2Z2t7vu7u7u7u7u7u7u7u7u7u7u/t3//+/u///u7v//7v7d3bvbvf////////////+ZmZmZmZmZmZlmd2dmtru+7u7u7u7u7u7u7u7u7u7u/v/v7u7u7u7u7u7u7v7/2/3///////////////+ZmZmZmZmZaZmZZnd3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////////+ZmZmZmZmZaZaZmWZ3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaWeZaWZmtrvr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmXZmZmZ3t7vr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmWl3Znd3tuu77u677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u///u//////////+ZmZmZmZlplpl2dndmtru76+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v/u//////////+ZmZmZmZlpZ5Zpd2Zmtru7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v////////////+ZmZmZmZmZdmdmZ3Z3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v///9v9//////+ZmZmZmZmZaXdnZmZ3t7vrvuvu6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/7//t29//////+ZmZmZmZmZmWZ3d3d3t7vrvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/7//93d/f////+ZmZmZmZmZmZlmZnd3tru7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7//9vd/f////+ZmZmZmZmZmZmZZnd3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v///9vd+/////+ZmZmZmZmZmZlmd3dmtru7u+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v/u/93///////+ZmZmZmZmZmWZ3Z2Z2t7u+6+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v/v/uv93///////+ZmZmZmZmZaXdnZmZ3tru77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u////373///////+ZmZmZmZmZaWZmdmZntrvr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+////2/3///////+ZmZmZmZmZmWlmdmdmtrvr6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+/v//3fv///////+ZmZmZmZmZmWZmZndntrvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7//7+93f////////+ZmZmZmZmZmXZnZmZ3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7//9/dvf////////+ZmZmZmZmZmWl3Z2Zmu7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7//7/d3f////////+ZmZmZmZmZmZlmd3d3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7////f3f////////+ZmZmZmZmZmZlpZnd3t7vr7rvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+/+6/vf////////+ZmZmZmZmZmWl2d2dmtrvr7rvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+/+7///////////+ZmZmZmZmZmXZ3ZmZ3t+u77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u//////////////+ZmZmZmZmZaXdmZnd3t7u76+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v////////////+ZmZmZmZmZaWZmdmdmtrvrvu7r7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7//+//////////+ZmZmZmZmZmZlpdmZmu7vrvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/////////////+ZmZmZmZmZZmZmZmZ3t7u7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7///////////+ZmZmZmZmZdndmZnZntru7u+u+6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7v/v////////+ZmZmZmZmZaXZ3Z2Zmtru+u+u+6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7v7v/v////////+ZmZmZmZmZmWl2d3dmtru7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7///////////+ZmZmZmWZmZmZmZnd3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v////////////+ZmZmZmWZ3d3d3d3d3t7vru+7r7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7v/+//////////+ZmZmZmZlmZnZ3d3d3u7u76+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v////////////+ZmZmZmZmZmWlmdnd3t7u77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u//////////////+ZmZmZmZmZmWl2d2dmtrvrvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/7///////////+ZmZmZmZmZmXZ3ZmZmtr7rvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/+7/7///////////+ZmZmZmZmZaWZmZmZ3trvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZl2Z2Z2t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZlmd2dmtru+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v//////////////+ZmZmZmZmZaZmZZnd3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaZaZmWZ3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaWeZaWZmtrvr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmXZmZmZ3t7vr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmWl3Znd3tuu77u677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u///u//////////+ZmZmZmZlplpl2dndmtru76+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v/u//////////+ZmZmZmZlpZ5Zpd2Zmtru7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u///u7v////////////+ZmZmZmZmZdmdmZ3Z3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uv/3u7v////////////+ZmZmZmZmZaXdnZmZ3t7vrvuvu6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u373/7/7//v////////+ZmZmZmZmZmWZ3d3d3t7vrvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+39397/7///////////+ZmZmZmZmZmZlmZnd3tru7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7/29377v7///////////+ZmZmZmZmZmZmZZnd3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7f/f//7v////////////+ZmZmZmZmZmZlmd3dmtru7u+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v/d/+7u7v/u//////////+ZmZmZmZmZmWZ3Z2Z2t7u+6+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/t/97+7v/v/u//////////+ZmZmZmZmZaXdnZmZ3tru77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7//9v/7u7u//////////////+ZmZmZmZmZaWZmdmZntrvr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u6/3f3v7u7+//////////////+ZmZmZmZmZmWlmdmdmtrvr6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7f3f3u7u7+/v////////////+ZmZmZmZmZmWZmZndntrvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7/2/3u7u7///////////////+ZmZmZmZmZmXZnZmZ3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3/vu7u7///////////////+ZmZmZmZmZmWl3Z2Zmu7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u///u7u7///////////////+ZmZmZmZmZmZlmd3d3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZlpZnd3t7vr7rvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+/+7///////////+ZmZmZmZmZmWl2d2dmtrvr7rvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+/+7///////////+ZmZmZmZmZmXZ3ZmZ3t+u77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u//////////////+ZmZmZmZmZaXdmZnd3t7u76+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v////////////+ZmZmZmZmZaWZmdmdmtrvrvu7r7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7//+//////////+ZmZmZmZmZmZlpdmZmu7vrvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/////////////+ZmZmZmZmZZmZmZmZ3t7u7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7///////////+ZmZmZmZmZdndmZnZntru7u+u+6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7v/v////////+ZmZmZmZmZaXZ3Z2Zmtru+u+u+6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7v7v/v////////+ZmZmZmZmZmWl2d3dmtru7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7///////////+ZmZmZmWZmZmZmZnd3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v////////////+ZmZmZmWZ3d3d3d3d3t7vru+7r7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7v/+//////////+ZmZmZmZlmZnZ3d3d3u7u76+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v////////////+ZmZmZmZmZmWlmdnd3t7u77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u//////////////+ZmZmZmZmZmWl2d2dmtrvrvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/7///////////+ZmZmZmZmZmXZ3ZmZmtr7rvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/+7/7///////////+ZmZmZmZmZaWZmZmZ3trvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZl2Z2Z2t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZlmd2dmtru+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v//////////////+ZmZmZmZmZaZmZZnd3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaZaZmWZ3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaWeZaWZmtrvr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmXZmZmZ3t7vr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmWl3Znd3tuu77u677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u///u//////////+ZmZmZmZlplpl2dndmtru76+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u///v//////////+ZmZmZmZlpZ5Zpd2Zmtru7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uv73///////////+ZmZmZmZmZdmdmZ3Z3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7/393///////////+ZmZmZmZmZaXdnZmZ3t7vrvuvu6+7u7u7//+7u7u7u7u7u7u7u7u7u7u7u7u7u7u6/3d3//v////////+ZmZmZmZmZmWZ3d3d3t7vrvuvu7u7u7u7f++7u7u7u7u7u7u7u7u7u7u7u7u7u7u7f3b3///////////+ZmZmZmZmZmZlmZnd3tru7u+vu7u7u7v/b/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u6/vd3///////////+ZmZmZmZmZmZmZZnd3t7u7u+7u7u7u7t/d/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7//937//////////+ZmZmZmZmZmZlmd3dmtru7u+677u7u7r/d/e/u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/tv9//////////+ZmZmZmZmZmWZ3Z2Z2t7u+6+677u7u7v//2//u7u7u7u7u7u7u7u7u7u7u7u7u7u7v/t+9//////////+ZmZmZmZmZaXdnZmZ3tru77u7u7u7u7u7+3/3v7u7u7u7u7u7u7u7u7u7u7u7u7u7u/7/d//////////+ZmZmZmZmZaWZmdmZntrvr7u7u7u7u7u7u/93/7u7u7u7u7u7u7u7u7u7u7u7u7u7+///d//////////+ZmZmZmZmZmWlmdmdmtrvr6+7u7u7u7u7u/t/9///u7u7u7u7u7u7u7u7u7u7u7u7+/v/b3fv///////+ZmZmZmZmZmWZmZndntrvu7u7u7u7u7u7u7v/b3fvu7u7u7u7u7u7u7u7u7u7u7u7////b3f3///////+ZmZmZmZmZmXZnZmZ3t7vu7u7u7u7u7u7u7v7f3f3u7u7u7u7u7u7u7u7u7u7u7u7////d3f3///////+ZmZmZmZmZmWl3Z2Zmu7vu7u7u7u7u7u7u7u7fvf/u7u7u7u7u7u7u7u7u7u7u7u7////dvf////////+ZmZmZmZmZmZlmd3d3t7vu7u7u7u7u7u7u7u6//e7u7u7u7u7u7u7u7u7u7u7u7u7////b/f////////+ZmZmZmZmZmZlpZnd3t7vr7rvu7u7u7u7u7u7//+7u7u7u7u7u7u7u7u7u7u7u7u7+//7///////////+ZmZmZmZmZmWl2d2dmtrvr7rvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+/+7///////////+ZmZmZmZmZmXZ3ZmZ3t+u77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u//////////////+ZmZmZmZmZaXdmZnd3t7u76+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v////////////+ZmZmZmZmZaWZmdmdmtrvrvu7r7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7//+//////////+ZmZmZmZmZmZlpdmZmu7vrvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/////////////+ZmZmZmZmZZmZmZmZ3t7u7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7///////////+ZmZmZmZmZdndmZnZntru7u+u+6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7v/v////////+ZmZmZmZmZaXZ3Z2Zmtru+u+u+6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7v7v/v////////+ZmZmZmZmZmWl2d3dmtru7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7///////////+ZmZmZmWZmZmZmZnd3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v////////////+ZmZmZmWZ3d3d3d3d3t7vru+7r7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7v/+//////////+ZmZmZmZlmZnZ3d3d3t7u76+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v////////////8=\",\n    \"lanterns\": \"hwSgAHgAAACIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIVYWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIaIiIiIiIiIiIiIiIiIiIiGiIiIWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIaIaIiIiIiIiIiIiIiIiIiGhmiIiIiIiIiIiIiFiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiIiIiIZoiIiIiIiIiIiIiIiIiIiIiGiIiIiIiIiIiIiFhViIiIiIiIiIiIiIiIiIiIiIi4i4iIiIiIiIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaFWFiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhViIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFiIiIWIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiFWIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVYiIiIiIWFWIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGhVhYiIiIiIVVWIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIhohoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVYiIiIiIWFWIiIiIiIiIiIiIiIiIuIuIiIiIiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiFWIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiGaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIWIiIiIiIiIiIiIiIiIi4iIiIiIiIiIaIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIhohoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIWIiIiIiIiIiIiIWIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIVYWIiIiIiIiIiFWIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIWIiIiIiIiIiIiFVVhYiIiIiIiIiIiIiIiIiLiIiIiIiIiIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIVVVViIiIiIiIiIiIiIiIiLiIiIiIiIhmZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhVVVWFiIiIiIiIiIiIiIiIiLuIiIiIiGaGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIVVVViIiIiIiIiIiIiIiIiIuIiIiIZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFVVhYiIiIiIiIiIiIiIuLWIiGhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFWIiIiIiIiIiIiIiIiIi1W1W2WIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIWIiIiIiIiIiIiIiIi4i1VVVYWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4aFVVVYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiIiIiIiIiIiIiIhmVVVVtYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhVhYiIiIiIiFiIiIiIiIiIaGaLW1VVVYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFVVVYWIiIiIiIiIiIiIiGZmhruIiFtVVYWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhVhYiIiIiIiIiIiIhoZoiIiIuIiFi1W4WIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhVVYiIiIiIiIiIZmaGiIiIuIiIiFiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFiIiIiIiIiIiIiIiIiIiIi4iIiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi7iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIi4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYhYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVVWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhVVYWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIWFVVVYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhVVYWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVVWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYhYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiLiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4i4iIZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu4iIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIuIiIhoZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiGaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIhoZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIaGaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIuIiIiIiIhmhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLuIiIiIiIhoZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIaIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiGaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4i4iIiIiIiIhmhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIhoZoiIW4uIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIZoaIWLWLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIaGaIWLVVVVVVVVVVtYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiGaIW7WIiIiIiIi4VYWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiGhWu4W1iIiIiIiIW7WIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIhWu7VVVVVVVVVVVVWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIhVu4W1iIiIiIiIWFWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIi1VYWIiIiIiIiIWLW1W4uIiIiIiIiIiIiIiIiIiIiIiIiIiIi7u7u7u7u7u7tbu1u7tVVVVVVVVVVVVbVbVYWIiIiIiIiIWLVVW1VVVVW7u4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi7iIiIiIiIiIi1VYWIiIiIiIiIWLW1W4uIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiIhVW2W1iIiIiIiIWFWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4i4iIiIiIiIhYu7VVVVVVVVVVVVWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIhYu2W1iIiIiIiIW7WIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiIiIi4tYiIiIiIi4iIiIiIiIiIu4VmiIiIiIi4VYWIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVYhmiIiIiIiIiIiIVbuIiIiIu4iIiIiIiIiIW7VVVVVVVVVVtYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIZoiIiIiIiIiIVVtVVVVVVVVVi4iIiIiIWLVrhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGhmiIiIiIi4VYuIiIiIuIhbVYiIiIiIW4uIZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZoaIiIi1W1iLiIiIuIu4VYuIiIiIiIiIZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGhmhoi1W1tVVVVVVVVVVYWIiIiIiIiIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZla1W1iLiIiIiIuIVYWIiIiIiIiIaIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhbVYaIiIiIiIuIVVu7tYiIiIiIiIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIhVVVVVVVVVVbtVVWZmhoiIiLuIVVu1VVVVVbW7i2aIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYhYiIiIiIiIiIiIiIiFhbVYiIZmaGiLiIVVu7tYiIiIiIiGaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVVWIiIiIiIiIiIiIiFi1VViLiGhmZraIVYWIiIiIiIiIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhVVYWIiIiIiIiIiIiIiIi1W1tVVVVVVVVVVYWIiIiIiIiIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIWFVVVYiIiIiIiIiIiIiIiIi1W1iLiIiIiLi2VYuIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhVVYWIiIiIiIiIiIiIiIi4W4iIiIiIiIhbVWZmiIiIiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVVWIiIiIiIiIiIiIiIi4VVtVVVVVVVVVi4hmZoiIiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYhYiIiIiIiIiIiIiIiIiIVbuIiIiIiIiLiIhba2aGiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiIiIiIiIiIi4tYiIiIiIiIiLiIhYtWtmhoiIiIhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi7iIhYtVVVVVVVVVW1hoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIhbtYiIiGaIiLhVhYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhViIiIiIiIiIiIiIiIiIiIiIiIiIi4iFi7hbWIiGhmiIhbtYiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiIhVWFWIiIiIiIiIiIiIiIiIiIiIiIi4iFi7tVVVVVVVVVVVVYiIiIiIiIiIiIiIiIiIiIhVhYiIiIiIiFhVVYWIiIiIiIiIiIiIiIiIiIiIiIi4iFW7hbWIiIiIaIZYVYiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIWFVVVYiIiIiIiIiIiIiIiIiIiIiIiIiIiLVVhYiIiIiIiGZWtbVbi4iIiIiIiIiIiIiIiIiIiIiIiIhYVVVVhYi7u7u7u1u7W7u1VVVVVVVVVVVVtVtVhYiIiIiIiIhWtVVbVVVVVbu7iIiIiIiIiIiIiIiIiIiIWFVVVYiIiIiIiIiIiIiIiIiIiIiIiIiIi7VVhYiIiIiIiIhYtbVbi4iIiIiIiIiIiIhoiIiIiIiIiIiIiFhVVYWIiIiIiIiIiIiIiIiIiIiIiIiIi1VbhbWIiIiIiIhYVYiIiIiIiIiIiIiIiIhmZoaIiIiIiIiIiIhVWFWIiIiIiIiIiIiIiIiIiIiIiIiIi1i7tVVVVVVVVVVVVWaIiIiIiIiIiIiIiGZmZoiIiIWIiIiIiIhViIiIiIiIiIiIiIiIiIiIiIiIiIiIi1i7hbWIiIiIiIhbtWiGiIiIiIiIiIiIiGhmZoiIiFWIiIiIiIiFiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4i7hYiIiIiIiLhVhYiGiIiIiIiIiIiIiIhmZoaIiFVVhYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu4hbtVVVVVVVVVW1iIhoiIiIiIiIiIiIiIiGiIiIVVVViIiIiIiIiFiIiIiIiIiIiIiIiIiIiIiIiIiIu4hYtYuIiIiIiIiIiIiIhoiIiIiIiIiIiIiIiIhVVVWFiIiIiIiIiFWIiIiIiIiIiIiIiIiIiIiIiIiIuIhbi4iIiIiIiIiIiIiIZoiIiIiIiIiIiIiIiIiIVVVViIiIiIiIiFiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIaIaIiIiIiIiIiIiIiIiIiFVVhYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIaIiIiIiIiIiIiIiIiIiFWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIg=\",\n    \"lilypads\": \"hwSgAHgAAACZmZmZmZmZmXlmZmZ3d3d3d3d3d2bW3d19l5mZmZmZmZmZmZmZmZmZeWZmZnd3d3d3d3d3Ztbd3X2XmZmZmZmZmZmZmZlmZmZ3d3d3d3d3d2dm3d19l5mZmZmZmZmZmZmZmZmZmWZmZnd3d3d3d3d3Z2bd3X2XmZmZmZmZmZmZmZlpZnZ3d3d3d3d3d2dm3d19l5mZmZmZmZmZmZmZmZmZmWlmdnd3d3d3d3d3Z2bd3X2XmZmZmZmZmZmZmZmZZ3Z3d3d3d3d3d2dm3d19l5mZmZmZmZmZmZmZmZmZmZlndnd3d3d3d3d3Z2bd3X2XmZmZmZmZmZmZmZmZmXl3d3d3d3d3d2dm3d3dl5mZmZmZmZmZmZmZmZmZmZmZeXd3d3d3d3d3Z2bd3d2XmZmZmZmZmZmZmdndmXd3d3d3d3d3d2dm1919mZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2bX3X2ZmZmZmZmZmZmZmdkR3Xd3d3d3d3d3d2dmd92XmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2Z33ZeZmZmZmZmZmZmZmdkR0X0Rd3d9d3d3d2dmd3eZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2Z3d5mZmZmZmZmZmZmZmZkdEX0Rd9d9d3d3d2dmd5mZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2Z3mZmZmZmZmZmZ2d3d3ZkdEd0Rcd3dd3d3d2dmmZmZmZmZmZmZmZmZmZmZmZmZmZmZdnd3d3d3d3d3Z2aZmZmZmZmZmZmZ2RER0d3dEdERcd3dd3d3d2dmmZmZmZmZmZmZmZmZmZmZmZl5l5mZZmZ3d3d3d3d3Z2aZmZmZmZmZmZmZ2REREdHdHdERcd3dd3d3d2dmmZmZmZmZmZmZmZmZmZmZmdndfZeZmXlmd3d3d3d3Z2aZmZmZmZmZmZmZ2R0RERHdHdERcd13fXd3d2dmmZmZmZmZtnuZmZmZmZmZmd3d3XeZmZl5ZnZ3d3d3Z2aZmZmZmZmZmZmZmd0RERHR3REdcX0X0Xd3d2dmmZmZmZlmd7Z7mZmZmZmZ2d3d3X2XmZmZaXZ3d3d3Z2aZmZmZmWaZmZmZ2d0dERER3REd0XcR0Xd3d2dmmZmZmWlmZne7m5mZmZmZ3d3d3d13mZmZaXd3d3d3Z2aZmZmZaWaZmZmZ2d3dHRER3R0d3RcR0Xd3d2dmmZmZmWZmZna3u5mZmZmZ3d3d3d13mZmZaXd3d3d3Z2aZmZmZZmabmZnd3d3d3RHd3R0dfRERfXd3d2dmmZmZaWZmZmZ3u5uZmZnZ3d3d3d19l5mZdnd3d3d3Z2aZmZlpZmZ7mZkdERHd3R0d3d3d3RERfXd3d2Z2mZmZZmZmZmZ2tnuZmZnZ3d3d3d19l5mZdnd3d3d3ZnaZmZlmZma7mZkdERER0d0dEd3dHRHRd3d3d2aWmZmZZmZmZmZ2Z7uZmZnd3d3d3d19l5lpd3d3d3d3ZpaZmZlmZma7l5ndEREREdHdEdHdHRF9d3d3d2aWmZmZa2ZmZmZmZ7uXmZnd3d3d3d19l5lpd3d3d3d3ZpaZmZlrZma7m5nZ3R0REdHdERHd3d3dd3d3Z2aXmZmZZ2ZmZmZmZrubmZnd3d3d3d19l5l2d3d3d3dnZpeZmZlnZma7e5nZHdEdEV1VHREd3RHRfXd3Z2aZmZmZaWZmZmZmZrt7mdnd3d3d3d19l5l2d3d3d3dnZpmZmZlpZma2u5ndEREREd1VHdER3RER0Xd3ZnaZmZmZeWZmZmZmZra7mdnd3d3d3d19l2l3d3d3d3dmdpmZmZl5Zma2u5kdERER0V1V1dER0REREX13ZpaZmZmZmWtmZmZmZra7mdnd3d3d3d19l2l3d3d3191mlpmZmZmZa2a2u5nd3R0R0VVVVd0R0R0REdFnZpeZmZmZmWlmZmZmZra7mdnd3d3d3d19l3Z3d3d31xHdd3eZmZmZaWa2u5kdEREREV1V1dER0d0REdFmZpmZmbl7mblmZmZmZra7mdnd3d3d3d19l3Z3d3d31xHRfRGXuX2ZuWa2u5ndEREREd1dFdER3d3dEdFmlpmZmWm7l5lmZmZmZra7mdnd3d3d3d19l9d3d3d3Zx0RfRGX2b2XmWa2u5nZHRER0d1VEREd3d3d3W1mmZmZmWlmu5dnZmZmZra7mdnd3d3X3d19l9nd3d3dZh0R3RFx3d27l2e2u5nZ3RER3d3dERHd3XHXZ2aWmZmZmWlmtrtnZmZmZra7mdnd3d3X3d19l3nXERHR3d0R0RFx3d22u2e2u5nZ3d0R0d3dEdHdHRFnZmaZmZmZmWlmZrZrZmZmZra7mdnd3d133d19l5nXERER0d0d0RFx3d1mtmu7u5nZ3R0R0d0dEd3dHRFxZpeZmZmZmWlmZmZmZmZmZru7mdnd3d131919l5nZHREREd0d0RFx3XdtZmZ3ZnbZ3RER3d0d0R3dHRHRmZmZmZmZmWlmZmZmZmZmd3dmdtnd3d131919l5mZ3REREdHdER1xfRfRZmZ3Z2bWHRHd3RHR3R0d3RERnZmZmZmZmWlmZmZmZmZ2d3dnZtbd3d19d919l5nZ3R0RERHdER3RdxHRZmZ3d2dm3d3dHRER3REd3RERnZmZmZmZmWlmZmZmZmZ3d3d3Z2bd3d19d913mZnZ3d0dERHdHR3dFxHRZmZ3d3dm1t0dERHR3REd0RcRnZmZmZmZmWlmZmZmZnZ3d3d3d2bW3d19d9d3md3d3d3dEd3dHR19ERFtZmZ3d3dn1t0RERHdHdEd0XcRnZmZmZmZmXlmZmZmZnd3d3d3d2fW3d19d9d3mR0REd3dHR3d3d3dERFtZmZ3d3dn1h0REdHdHdER0X0XnZmZmZmZmZlmZmZmZnd3d3d3d2dm3d3dd3mXmR0RERHR3R0R3d0dEdFmZmZ3d3d31hEREd3dEdER0d3XmZmZmZmZmZlmZmZmdnd3d3d3d3dm3d3dd5mZmd0RERER0d0R0d0dEW1mZmZ3d3d31hER3d3dEd0Rcd2XmZmZmZmZmZlnZmZmdnd3d3d3d3dm1t3dd5mZmdndHRER0d0REd3d3d1mZmZ3d3d31t3d3XcdEd0Rd92XmZmZmZmZmZlpZmZmd3d3d3d3d3dm1t3dd5eZmdkd0R0RXVUdER3dEdFtZmZ3d3d3Ztbd3d0REd0Rl9eXmZmZmZmZmZl5ZmZmd3d3d3d3d3dm1t3dfZeZmd0RERER3VUd0RHdERHRZmZ3d3d3Z2bd3d0R0d1xl3eXmZmZmZmZmZmZZmZmd3d3d3d3d3dnZt3dfZeZmR0RERHRXVXV0RHRERERbWZ3d3d3Z2bd3d0R3Zl9mXmZmZmZmZmZmZmZaWZ2d3d3d3d3d3dnZt3dfZeZmd3dHRHRVVVV3RHRHRER0XZ3d3d3Z2bd3d3RnZmZmZmZmZmZmZmZmZmZmWd2d3d3d3d3d3dnZt3dfZeZmR0RERERXVXV0RHR3RER0XZ3d3d3Z2bd3d3dmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3dnZt3d3ZeZmd0RERER3V0V0RHd3d0R0Xl3d3d3Z2bX3X2ZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3dnZtfdfZmZmdkdERHR3VURER3d3d3dnXd3d3d3Z2Z33ZeZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3dnZnfdl5mZmdndERHd3d0REd3dcZeZmXd3d3d3Z2Z3d5mZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3dnZnd3mZmZmZnZ3RHR3d0R0d0dEZeZmXd3d3d3Z2Z3mZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3dnZneZmZmZmZnZHRHR3R0R3d0dEXGZmXd3d3d3Z2aZmZmZmZmZmZmZmZmZmZmZmZmZmZl2d3d3d3d3d3dnZpmZmZmZmZndERHd3R3RHd0dEdGZmXZ3d3d3Z2aZmZmZmZmZmZmZmZmZmZmZmXmXmZlmZnd3d3d3d3dnZpmZmZmZmZkdEd3dEdHdHR3dERGdmWZ3d3d3Z2aZmZmZmZmZmZmZmZmZmZmZ2d19l5mZeWZ3d3d3d3dnZpmZmZmZmZnd3d0dERHdER3dERGdmZl3d3d3Z2aZmZmZmZm2e5mZmZmZmZmZ3d3dd5mZmXlmdnd3d3dnZpmZmZmZmbZ72R0REdHdER3RFxF9mZl3d3d3Z2aZmZmZmWZ3tnuZmZmZmZnZ3d3dfZeZmZlpdnd3d3dnZpmZmZmZZne23REREd0d0R3RdxF9l5l3d3d3Z2aZmZmZaWZmd7ubmZmZmZnd3d3d3XeZmZlpd3d3d3dnZpmZmZlpZmbXHRER0d0d0RHRfRfdd5l3d3d3Z2aZmZmZZmZmdre7mZmZmZnd3d3d3XeZmZlpd3d3d3dnZpmZmZlmZmbWERER3d0R0RHR3dfdd5l3d3d3Z2aZmZlpZmZmZne7m5mZmdnd3d3d3X2XmZl2d3d3d3dnZpmZmWlmZmbWERHd3d0R3RFx3dfdfZd3d3d3ZnaZmZlmZmZmZna2e5mZmdnd3d3d3X2XmZl2d3d3d3dmdpmZmWZmZmbW3d3dmR0R3RF33dfdfZd3d3d3ZpaZmZlmZmZmZnZnu5mZmd3d3d3d3X2XmWl3d3d3d3dmlpmZmWZmZmZmdme72RER3RHX19fdfZd3d3d3ZpaZmZlrZmZmZmZnu5eZmd3d3d3d3X2XmWl3d3d3d3dmlpmZmWtmZmZmZme71xHR3XHXd9fdfZd3d3dnZpeZmZlnZmZmZmZmu5uZmd3d3d3d3X2XmXZ3d3d3d2dml5mZmWdmZmZmZma72xHd3X3dfd3dfZd3d3dnZpmZmZlpZmZmZmZmu3uZ2d3d3d3d3X2XmXZ3d3d3d2dmmZmZmWlmZmZmZma729Hd3d3d3d3dfZd3d3dmdpmZmZl5ZmZmZmZmtruZ2d3d3d3d3X2XaXd3d3d3d2Z2mZmZmXlmZmZmZma2u93Z3d3d3d3dfZd3d3dmlpmZmZmZa2ZmZmZmtruZ2d3d3d3d3X2XaXd3d3d3d2aWmZmZmZlrZmZmZma2u5nZ3d3d3d3dfZd3d2dml5mZmZmZaWZmZmZmtruZ2d3d3d3d3X2Xdnd3d3d3Z2aXmZmZmZlpZmZmZma2u5nZ3d3d3d3dfZd3d2ZmmZmZuXuZuWZmZmZmtruZ2d3d3d3d3X2Xdnd3d3d3ZmaZmZm5e5m5ZmZmZma2u5nZ3d3d3d3dfZd3Z2aWmZmZabuXmWZmZmZmtruZ2d3d3d3d3X2X13d3d3dnZpaZmZlpu5eZZmZmZma2u5nZ3d3d3d3dfZd9ZmaZmZmZaWa7l2dmZmZmtruZ2d3d3dfd3X2X2d13131mZpmZmZlpZruXZ2ZmZma2u5nZ3d3d193dfZdnZpaZmZmZaWa2u2dmZmZmtruZ2d3d3dfd3X2Xedfd3WdmlpmZmZlpZra7Z2ZmZma2u5nZ3d3d193dfZdmZpmZmZmZaWZmtmtmZmZmtruZ2d3d3Xfd3X2XmXd3Z2ZmmZmZmZlpZma2a2ZmZma2u5nZ3d3dd93dfZdml5mZmZmZaWZmZmZmZmZmu7uZ2d3d3XfX3X2XmZlmZmaXmZmZmZlpZmZmZmZmZma7u5nZ3d3dd9fdfZeZmZmZmZmZaWZmZmZmZmZ3d2Z22d3d3XfX3X2XmZmZmZmZmZmZmZlpZmZmZmZmZnd3ZnbZ3d3dd9fdfZeZmZmZmZmZaWZmZmZmZnZ3d2dm1t3d3X133X2XmZmZmZmZmZmZmZlpZmZmZmZmdnd3Z2bW3d3dfXfdfZeZmZmZmZmZaWZmZmZmZnd3d3dnZt3d3X133XeZmZmZmZmZmZmZmZlpZmZmZmZmd3d3d2dm3d3dfXfdd5mZmZmZmZmZaWZmZmZmdnd3d3d3Ztbd3X1313eZmZmZmZmZmZmZmZlpZmZmZmZ2d3d3d3dm1t3dfXfXd5mZmZmZmZmZeWZmZmZmd3d3d3d3Z9bd3X1313eZmZmZmZmZmZmZmZl5ZmZmZmZ3d3d3d3dn1t3dfXfXd5mZmZmZmZmZmWZmZmZmd3d3d3d3Z2bd3d13eZeZmZmZmZmZmZmZmZmZZmZmZmZ3d3d3d3dnZt3d3Xd5l5mZmZmZmZmZmWZmZmZ2d3d3d3d3d2bd3d13mZmZmZmZmZmZmZmZmZmZZmZmZnZ3d3d3d3d3Zt3d3XeZmZmZmZmZmZmZmWdmZmZ2d3d3d3d3d2bW3d13mZmZmZmZmZmZmZmZmZmZZ2ZmZnZ3d3d3d3d3Ztbd3XeZmZmZmZmZmZmZmWlmZmZ3d3d3d3d3d2bW3d13l5mZmZmZmZmZmZmZmZmZaWZmZnd3d3d3d3d3Ztbd3XeXmZmZmZmZmZmZmXlmZmZ3d3d3d3d3d2bW3d19l5mZmZmZmZmZmZmZmZmZeWZmZnd3d3d3d3d3Ztbd3X2XmZmZmZmZmZmZmZlmZmZ3d3d3d3d3d2dm3d19l5mZmZmZmZmZmZmZmZmZmWZmZnd3d3d3d3d3Z2bd3X2XmZmZmZmZmZmZmZlpZnZ3d3d3d3d3d2dm3d19l5mZmZmZmZmZmZmZmZmZmWlmdnd3d3d3d3d3Z2bd3X2XmZmZmZmZmZmZmZmZZ3Z3d3d3d3d3d2dm3d19l5mZmZmZmZmZmZmZmZmZmZlndnd3d3d3d3d3Z2bd3X2XmZmZmZmZmZmZmZmZmXl3d3d3d3d3d2dm3d3dl5mZmZmZmZmZmZmZmZmZmZmZeXd3d3d3d3d3Z2bd3d2XmZmZmZmZmZmZmZmZmXd3d3d3d3d3d2dm1919mZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2bX3X2ZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d2dmd92XmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2Z33ZeZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d2dmd3eZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2Z3d5mZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d2dmd5mZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2Z3mZmZmZmZmZmZmZmZmZmZmXZ3d3d3d3d3d2dmmZmZmZmZmZmZmZmZmZmZmZmZmZmZdnd3d3d3d3d3Z2aZmZmZmZmZmZmZmZmZeZeZmWZmd3d3d3d3d2dmmZmZmZmZmZmZmZmZmZmZmZl5l5mZZmZ3d3d3d3d3Z2aZmZmZmZmZmZmZmZnZ3X2XmZl5Znd3d3d3d2dmmZmZmZmZmZmZmZmZmZmZmdndfZeZmXlmd3d3d3d3Z2aZmZmZmZmZmZmZmZnd3d13mZmZeWZ2d3d3d2dmmZmZmZmZtnuZmZmZmZmZmd3d3XeZmZl5ZnZ3d3d3Z2aZmZmZmZmZmZmZmdnd3d19l5mZmWl2d3d3d2dmmZmZmZlmd7Z7mZmZmZmZ2d3d3X2XmZmZaXZ3d3d3Z2aZmZmZmWaZmZmZmd3d3d3dd5mZmWl3d3d3d2dmmZmZmWlmZne7m5mZmZmZ3d3d3d13mZmZaXd3d3d3Z2aZmZmZaWaZmZmZmd3d3d3dd5mZmWl3d3d3d2dmmZmZmWZmZna3u5mZmZmZ3d3d3d13mZmZaXd3d3d3Z2aZmZmZZmabmZmZ2d3d3d3dfZeZmXZ3d3d3d2dmmZmZaWZmZmZ3u5uZmZnZ3d3d3d19l5mZdnd3d3d3Z2aZmZlpZmZ7mZmZ2d3d3d3dfZeZmXZ3d3d3d2Z2mZmZZmZmZmZ2tnuZmZnZ3d3d3d19l5mZdnd3d3d3ZnaZmZlmZma7mZmZ3d3d3d3dfZeZaXd3d3d3d2aWmZmZZmZmZmZ2Z7uZmZnd3d3d3d19l5lpd3d3d3d3ZpaZmZlmZma7l5mZ3d3d3d3dfZeZaXd3d3d3d2aWmZmZa2ZmZmZmZ7uXmZnd3d3d3d19l5lpd3d3d3d3ZpaZmZlrZma7m5mZ3d3d3d3dfZeZdnd3d3d3Z2aXmZmZZ2ZmZmZmZrubmZnd3d3d3d19l5l2d3d3d3dnZpeZmZlnZma7e5nZ3d3d3d3dfZeZdnd3d3d3Z2aZmZmZaWZmZmZmZrt7mdnd3d3d3d19l5l2d3d3d3dnZpmZmZlpZma2u5nZ3d3d3d3dfZdpd3d3d3d3ZnaZmZmZeWZmZmZmZra7mdnd3d3d3d19l2l3d3d3d3dmdpmZmZl5Zma2u5nZ3d3d3d3dfZdpd3d3d3d3ZpaZmZmZmWtmZmZmZra7mdnd3d3d3d19l2l3d3d3d3dmlpmZmZmZa2a2u5nZ3d3d3d3dfZd2d3d3d3dnZpeZmZmZmWlmZmZmZra7mdnd3d3d3d19l3Z3d3d3d2dml5mZmZmZaWa2u5nZ3d3d3d3dfZd2d3d3d3fWbZmZmbl7mblmZmZmZra7mdnd3d3d3d19l3Z3d3d3d2ZmmZmZuXuZuWa2u5nZ3d3d3d3dfZfXd3d3d2cd3ZmZmWm7l5lmZmZmZra7mdnd3d3d3d19l9d3d3d3Z2aWmZmZabuXmWa2u5nZ3d3d193dfZfZ3XfXfWYd0Z3Zl2lnu5dnZmZmZra7mdnd3d3X3d19l9ndd9d9ZmaZmZmZaWa7l2e2u5nZ3d3d193dfZd5193dZ2YdEd0dd3l3trtnZmZmZra7mdnd3d3X3d19l3nX3d1nZpaZmZmZaWa2u2e2u5nZ3d3dd93dfZeZd3dnZmYdEdEdcXl9ZrZrZmZmZra7mdnd3d133d19l5l3d2dmZpmZmZmZaWZmtmu7u5nZ3d3dd9fdfZeZmd3d3Z3ZEdEdcdd9ZmZmZmZmZru7mdnd3d131919l5mZZmZml5mZmZmZaWZmZmZ3ZnbZ3d3dd9fdfZeZmR0R0d3dHdEdEdd9ZmZmZmZmd3dmdtnd3d131919l5mZmZmZmZmZmZmZaWZmZmZ3Z2bW3d3dfXfdfZeZmR0REdHdHREdEd19bWZmZmZ2d3dnZtbd3d19d919l5mZmZmZmZmZmZmZaWZmZmZ3d2dm3d3dfXfdd5mZmd0RERHd3REdEd130WZmZmZ3d3d3Z2bd3d19d913mZmZmZmZmZmZmZmZaWZmZmZ3d3dm1t3dfXfXd5mZmdkdERHR3RHdEX0X0WZmZnZ3d3d3d2bW3d19d9d3mZmZmZmZmZmZmZmZaWZmZmZ3d3dn1t3dfXfXd5mZmZndERER3R3REX0R0WZmZnd3d3d3d2fW3d19d9d3mZmZmZmZmZmZmZmZeWZmZmZ3d3dnZt3d3Xd5l5mZ2d3d3RER0R3R0R0R0WZmZnd3d3d3d2dm3d3dd3mXmZmZmZmZmZmZmZmZmWZmZmZ3d3d3Zt3d3XeZmZmZ2RHR3R0R3d3R0R0R0WZmdnd3d3d3d3dm3d3dd5mZmZmZmZmZmZmZmZmZmWZmZmZ3d3d3Ztbd3XeZmZmZ2R0R0d3dEd3R3RERbWZmdnd3d3d3d3dm1t3dd5mZmZmZmZmZmZmZmZmZmWdmZmZ3d3d3Ztbd3XeXmZmZmd0REd3dEdHd3RERZ2Zmd3d3d3d3d3dm1t3dd5eZmZmZmZmZmZmZmZmZmWlmZmZ3d3d3Ztbd3X2XmZmZmd0dEd3dHRHd3RFxZmZmd3d3d3d3d3dm1t3dfZeZmZmZmZmZmZmZmZmZmXlmZmZ3d3d3Z2bd3X2XmZmZ3R0R0d3dHRHR3R13ZmZmd3d3d3d3d3dnZt3dfZeZmZmZmZmZmZmZmZmZmZlmZmZ3d3d3Z2bd3X2XmZmZ3REREd1dFRHR0d3d3d12d3d3d3d3d3dnZt3dfZeZmZmZmZmZmZmZmZmZmZlpZnZ3d3d3Z2bd3X2XmZnZHREREdHdVREd0d3dHRF9d3d3d3d3d3dnZt3dfZeZmZmZmZmZmZmZmZmZmZmZZ3Z3d3d3Z2bd3d2XmZnZEREREdFVVR0dEd0dERF9d3d3d3d3d3dnZt3d3ZeZmZmZmZmZmZmZmZmZmZmZmXl3d3d3Z2bX3X2ZmZnZ3d0REV1VVdUdEd0RERF9d3d3d3d3d3dnZtfdfZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3Z2Z33ZeZmZnZEREREd1VVR0dER0REdF3d3d3d3d3d3dnZnfdl5mZmZmZmZmZmZmZmZmZmZmZmXd3d3d3Z2Z3d5mZmZnZHREREdFd1REd0R0REZ13d3d3d3d3d3dnZnd3mZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3Z2Z3mZmZmZmZ3RHdEdFV1RHR0R0R3Zl3d3d3d3d3d3dnZneZmZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3Z2aZmZmZmZmZ3d0RERHdHRHR3d3dnZl2d3d3d3d3d3dnZpmZmZmZmZmZmZmZmZmZmZmZmZmZmXZ3d3d3Z2aZmZmZmZnZHRERERHdHRHd3RHRmZlmZnd3d3d3d3dnZpmZmZmZmZmZmZmZmZmZmZmZeZeZmWZ3d3d3Z2aZmZmZmZnZEREREd3dEdHd3RERnZmZeWZ3d3d3d3dnZpmZmZmZmZmZmZmZmZmZmZnZ3X2XmZl3d3d3Z2aZmZmZmZnWERHR3d3R0d3d3R0R0ZmZmXlmdnd3d3dnZpmZmZmZmbZ7mZmZmZmZmZnd3d13mZl3d3d3Z2aZmZmZmWbX3d3d3R3R3d3R0RcR0ZeZmZlpdnd3d3dnZpmZmZmZZne2e5mZmZmZmdnd3d19l5l3d3d3Z2aZmZmZaWZmd93d3RER0d3R0X0REX2ZmZlpd3d3d3dnZpmZmZlpZmZ3u5uZmZmZmd3d3d3dd5l3d3d3Z2aZmZmZZmZmdt3dERER0R3REX0XEX2ZmZlpd3d3d3dnZpmZmZlmZmZ2t7uZmZmZmd3d3d3dd5l3d3d3Z2aZmZlpZmZmZtcdERER3R3REdd3EX2XmZl2d3d3d3dnZpmZmWlmZmZmd7ubmZmZ2d3d3d3dfZd3d3d3ZnaZmZlmZmZmZt0RERHR3REdEdd9132XmZl2d3d3d3dmdpmZmWZmZmZmdrZ7mZmZ2d3d3d3dfZd3d3d3ZpaZmZlmZmZmZh0RERHd3REdEdfd3X2XmWl3d3d3d3dmlpmZmWZmZmZmdme7mZmZ3d3d3d3dfZd3d3d3ZpaZmZlrZmZmZh0REd3dHREdEdfd3X2XmWl3d3d3d3dmlpmZmWtmZmZmZme7l5mZ3d3d3d3dfZd3d3dnZpeZmZlnZmZmZt3d3Z3ZEdEdEdfd3X2XmXZ3d3d3d2dml5mZmWdmZmZmZma7m5mZ3d3d3d3dfZd3d3dnZpmZmZlpZmZmZmZmu3vZEdEXcd3d3X2XmXZ3d3d3d2dmmZmZmWlmZmZmZma7e5nZ3d3d3d3dfZd3d3dmdpmZmZl5ZmZmZmZmtrsdEd0Xcd3d3X2XaXd3d3d3d2Z2mZmZmXlmZmZmZma2u5nZ3d3d3d3dfZd3d3dmlpmZmZmZa2ZmZmZmtrsd0d13193d3X2XaXd3d3d3d2aWmZmZmZlrZmZmZma2u5nZ3d3d3d3dfZd3d2dml5mZmZmZaWZmZmZmtrvd3d3d3d3d3X2Xdnd3d3d3Z2aXmZmZmZlpZmZmZma2u5nZ3d3d3d3dfZd3d2ZmmZmZuXuZuWZmZmZmtruZ2d3d3d3d3X2Xdnd3d3d3ZmaZmZm5e5m5ZmZmZma2u5nZ3d3d3d3dfZd3Z2aWmZmZabuXmWZmZmZmtruZ2d3d3d3d3X2X13d3d3dnZpaZmZlpu5eZZmZmZma2u5nZ3d3d3d3dfZd9ZmaZmZmZaWa7l2dmZmZmtruZ2d3d3dfd3X2X2d13131mZpmZmZlpZruXZ2ZmZma2u5nZ3d3d193dfZdnZpaZmZmZaWa2u2dmZmZmtruZ2d3d3dfd3X2Xedfd3WdmlpmZmZlpZra7Z2ZmZma2u5nZ3d3d193dfZdmZpmZmZmZaWZmtmtmZmZmtruZ2d3d3Xfd3X2XmXd3Z2ZmmZmZmZlpZma2a2ZmZma2u5nZ3d3dd93dfZdml5mZmZmZaWZmZmZmZmZmu7uZ2d3d3XfX3X2XmZlmZmaXmZmZmZlpZmZmZmZmZma7u5nZ3d3dd9fdfZeZmZmZmZmZaWZmZmZmZmZ3d2Z22d3d3XfX3X2XmZmZmZmZmZmZmZlpZmZmZmZmZnd3ZnbZ3d3dd9fdfZeZmZmZmZmZaWZmZmZmZnZ3d2dm1t3d3X133X2XmZmZmZmZmZmZmZlpZmZmZmZmdnd3Z2bW3d3dfXfdfZeZmZmZmZmZaWZmZmZmZnd3d3dnZt3d3X133XeZmZmZmZmZmZmZmZlpZmZmZmZmd3d3d2dm3d3dfXfdd5mZmZmZmZmZaWZmZmZmdnd3d3d3Ztbd3X1313eZmZmZmZmZmZmZmZlpZmZmZmZ2d3d3d3dm1t3dfXfXd5mZmZmZmZmZeWZmZmZmd3d3d3d3Z9bd3X1313eZmZmZmZmZmZmZmZl5ZmZmZmZ3d3d3d3dn1t3dfXfXd5mZmZmZmZmZmWZmZmZmd3d3d3d3Z2bd3d13eZeZmZmZmZmZmZmZmZmZZmZmZmZ3d3d3d3dnZt3d3Xd5l5mZmZmZmZmZmWZmZmZ2d3d3d3d3d2bd3d13mZmZmZmZmZmZmZmZmZmZZmZmZnZ3d3d3d3d3Zt3d3XeZmZmZmZmZmZmZmWdmZmZ2d3d3d3d3d2bW3d13mZmZmZmZmZmZmZmZmZmZZ2ZmZnZ3d3d3d3d3Ztbd3XeZmZmZmZmZmZmZmWlmZmZ3d3d3d3d3d2bW3d13l5mZmZmZmZmZmZmZmZmZaWZmZnd3d3d3d3d3Ztbd3XeXmZk=\",\n    \"lunarnewyear\": \"hwSgAHgAAADd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3aqqqqra3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dqioiIiKi2t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3NLCIiIiIiwt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1dVd3d3d3d3d3d3d3d3d3d3d3MIiJEREQkItzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dVVXdVdXd3d3d3d3d3d3d3d3d3c0sIlRVRUREJMLd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1dVVXVXdXd3d3d3d3d3d3d3d3d3cwiQlUkIiJCRMTc3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1VVVVVXVXd3d3d3d3d3d3d3d3d3SwiVCQiIiIiQkTc3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1VVd1VXVXd3d3d3d3d3d3d3d3dTSRCJCIiIiIiIkLc3d0RERERERERERHR3d3d3d3d3d3d3d3d3d3d3d1V1V1VXVXd3d3d3d3d3d3d3d3dVE1CIiIiIiIiIkIcERERERERERERERERERHd3d3d3d3d3d3d3d3d3d1V1V3VXVXd3d3d3d3d3d3d3d3dVEUiIiIiQkREJCLCEREREREREREREREREREREdHd3d3d3d3d3d3d3d1V1d3dVVXd3d3d3d3d3d3d3d3dVFUiIkJERERERCTCEREREREREREREREREREREREREd3d3d3d3d3d3d1dVd1dVVXd3d3d3d3d3d3d3d3dVFUiQkQkIiIiIkLCFBERERERERERERERERERERERERER3d3d3d3d3d3dXVVVVVXd3d3d3d3d3d3d3d1NVFUiRCIiIiIiIiLERBEREREREREREREREREREREREREREdHd3d3d3VXVXVVVVVXd3d3d3d3d3d3d3d1N1FUiIiIiIiIiIiLCREREEUFEREREREQRERERERERERERERHd3d3dVVVV3VVVVVXd3d3d3d3d3d3d3d1URFUiIiIiIiIiIiLCRNTV091dVVVVVUURERERERERERERERER3d1dVVVV3VVVVVXdTURERERERERERERUTVUiIiIiIiIiIiLERVRVQzRd1d1NREQRERERERERERERERER0d1VVVVV1VVVVVXdXVVVVVVVVVVVVVVUTVUiIiIiIiIiQkTERdTV091dVVVVVd0UERERERERERERERER0V1VVVVV1V1VVVXdTURERERERERERERURFVCVVVVVURERCTCRUREREREREREREQUERERERERERERERER0V1VVVVV1V1VVVXd3d3d3d3d3d3d3d1N1FUiIiIiIiIiIiLCTRERERERERERERERERERERERERERERER0V1V1d1V1V1VVVXd3d3d3d3d3d3d3d1NVFUiIiIiIiIiIiLCFBERERERERERERERERERERERERERERER3VVV3d1d1VVVVVXd3d3d3d3d3d3d3d3dVFUiIiIiIiIiIiLCERERERERERERERERERERERERERERERER3VXVXdVd3VVVVVXd3d3d3d3d3d3d3d3dVFUiIiIiIiIiIiLEERERERERERERERERERERERERERERERER3VXVXdVV3VVVVVXd3d3d3d3d3d3d3d3dVEUiQiQiIiIiIkTEERERERERERERERERERERERERERERERER3VVV3VXVXVVVVVXd3d3d3d3d3d3d3d3dVE0iIkREREREREQcERERERERERERERERERERERERERERERER3VVV3d3dVVXV3V3d3d3d3d3d3d3d3d3dTSRCIiJCREREJEIcERERERERERERERERERERERERERERERER3VVV1d1dVVXdVV3d3d3d3d3d3d3d3d2tqixCRSIiIiIiIkQcERERERERERERERERERERERERERERERER3VVVVVVVVVVdVd3d3d3d3d3d3d3d3a2qIswiVFUkIiIiRMIcERERERERERERERERERERERERERERERER0VVVVVVVVdVdVd3d3d3d3d3d3d3d3cwiIsIsIlRVRUREJMIRERERERERERERERERERERERERERERERER0V1VVVVVVdVdVd3d3d3d3d3d3d3dzSwiQkTMIiJCREQkIhwRERERERERERERERERERERERERERERERER0V1VVVVVVdXdVdXd3d3d3d3d3d3dzCJCRETELCIiIiIiwhEREREREREREREREREREREREREREREREREREd1VVVVVVVXdVdXd3d3d3d3d3d3NLCJEJCIiqioiIiKiGhEREREREREREREREREREREREREREREREREREdFd3d1dVVXVVdXd3d3d3d3d3d3NIkIkIiIiIqqqqqoaERERERERERERERERERERERERERERERERERERERHd3d3dVVVVVdXd3d3d3d3d3d1EIkQiIiIiIiIixBwRERERERERERERERERERERERERERERERERERERERHR3VXVXVVVVdXd3d3d3d3d3U3VJCQiIiIiIiIixBERERERERERERERERERERERERERERERERERERERERHRVVVVXVVVVdXd3d3d3d3d3U1VJCIiIiJEREQiIhwRERERERERERERERERERERERERERERERERERERERFdVVVV3VVVVdXd3d3d3d3d3U1VJSIiREREREREIhwRERERERERERERERERERERERERERERERERERERERFdVdVV3VVVVdXd3d3d3d3d3U1VJSJERCIiIiIiJEwRERERERERERERERERERERERERERERERERERERERFdVd1V3VVVVdXd3d3d3d3d3URVJUIkIiIiIiIiQkwUERERERERERERERERERERERERERERERERERERERFdVd1V3VVVVdXd3d3d3d3d3URdJSIiIiIiIiIiIkxEREREREREREREFBERERERERERERERERERERERERFdVd3dXVVVVdXd3d3d3d3dTUVUJSIiIiIiIiIiIkxEXT3d3VVVVVVVFBERERERERERERERERERERERERFdVdXdVVVVVdXdTURERERERNVUJSIiIiIiIiIiQlxEVTVE01Xd3UREFBERERERERERERERERERERERERHdVVVVVVVVVdXdXVVVVVVVRdVUJSIiIiIiIiJERFxEXT3d3VVVVVXVTRERERERERERERERERERERERERHRVVVVVVVVVdXdTUREREREREVUJUREREREREREIlxERERERERERERERBERERERERERERERERERERERERHRXVVVVVVVVdXd3d3d3d3d3URdJSIiIiIiIiIiItwUERERERERERERERERERERERERERERERERERERERHd3d1VVVVVVdXd3d3d3d3d3URVJSIiIiIiIiIiIkwRERERERERERERERERERERERERERERERERERERERHd3d1VVVVVVdXd3d3d3d3d3U1VJSIiIiIiIiIiIhwRERERERERERERERERERERERERERERERERERERERFd3V1VXVVVVdXd3d3d3d3d3U1VJSIiIiIiIiIiQhwREREREREREREREREREREREREREREREREREREREdFd3V1V1V1VVVXd3d3d3d3d3U1VJCJEIiIiIiJCRBwREREREREREREREREREREREREREREREREREREREdFV3V1VVd1VVVXd3d3d3d3d3U3VJCJCRERERERExBEREREREREREREREREREREREREREREREREREREREdFV3V1VVdVdVVXd3d3d3d3d3d1EIiQiIkREREQixBEREREREREREREREREREREREREREREREREREREREdFV3d1VVdVdVVXd3d3d3d3d3d3NIkQiIiIiIiJCxBEREREREREREREREREREREREREREREREREREREREd1V3d1dVd1VVVXd3d3d3d3d3d3NLCIkIiIiIkIkzBERERERERERERERERERERERERERERERERERERER0d1V3d3d3V1VVVXd3d3d3d3d3d1VzCJCREREREQiHBERERERERERERERERERERERERERERERERERERHR3d1V3d3d3V1VVdXd3d3d3d3d3V1VxSwiIkRERCLCERERERERERERERERERERERERERERERERERERERHd3d1V1d3d3V1VVdXd3d3d3d3d3V1VVcwiIiIiIiIcEREREREREREREREREREREREREREREREREREREdFdVdVdVd3d3V1VVdXd3d3d3d3d3V1VVaWqIiIiIqoREREREREREREREREREREREREREREREREREREREdFVVVVdVVVV1V1VVdXd3d3d3d3d3d1VVVWtqqqqqhEREREREREREREREREREREREREREREREREREREREd1VVVVdVVVV1d1dVdXd3d3d3d1dVdVdVVXdHREREREREREREREREREREREREREREREREREREREREREREV1V1V1dVVVV1d1dVdXd3d3d3d1VVVXdVVXdEREREREREREREREREREREREREREREREREREREREREREREV1V1dVdVVVV1d1dVdXd3d3d3V1V1VXdVVXdEREREREREREREREREREREREREREREREREREREREREREREV1V1d1dVVVV1d1dVdXd3d3d3V1V1VXVVVXdEREREREREREREREREREREREREREREREREREREREREREREV1VVd1VVVVV1d3dVdXd3d3d3V1V3VXdVVXdEREREREREREREREREREREREREREREREREREREREREREREV1VVVVVVVVV1d3dVdXd3d3d3V1V1d1dVVXVEREREREREREREREREREREREREREREREREREREREREREREV1VVVVVVVVV1d3dXdXd3d3d3V1VVV1VVVXVEREREREREREREREREREREREREREREREREREREREREREREV1VVVVVVVVV1d3dXdXd3d3d3V1VVVVVVVXVEREREREREREREREREREREREREREREREREREREREREREREdFV1d3dXVVV1d3dXdXd3d3d3d1VVVVVVVXVEREREREREREREREREREREREREREREREREREREREREREREdFd3VVV3VVV1d3dXdXd3d3d3d3V3VVVVVXdERERERERERERERERERERERERERERERERERERERERERERERHdXVVV1VVV1d3dXd3d3d3d3d3d3V1VVVXdERERERERERERERERERERERERERERERERERERERERERERERHRXVVV1VVV1d3dXd3d3d3d3V1VVd1VVVXdERERERERERERERERERERERERERERERERERERERERERERERERXVXV3VVV1d3dXd3d3d3d3VVVVdVVVVXdERERERERERERERERERERERERERERERERERERERERERERERER3VVVXVVV1d3dXd3d3d3dXVVVVdVVVVXdERERERERERERERERERERERERERERERERERERERERERERERER0VVVVVVV1d3dXd3d3d3dVVXVXdVdVVXVERERERERERERERERERERERERERERERERERERERERERERERER0V1VVVVV1d3d3d3d3d1dVVVdXdVdVVXVEREREREREREREREREREREREREREREREREREREREREREREREREd3dXVVV1d3d3d3d3d1dVdVdVdVdVVXVEREREREREREREREREREREREREREREREREREREREREREREREREdHdVVVV1d3d3d3d3d1dVdVVVdVdVVXVERERERERERERERERERERERERERERERERERERERERERERERERERHdVVVV1d3d3d3d3d1dVdVdVdVdVVXVERERERERERERERERERERERERERERERERERERERERERERERERERHRVVVV1d3d3d3d3d1dVVXd3d1VVVXVERERERERERERERERERERERERERERERERERERERERERERERERERHRVVVV1d3d3d3d3d1dVVXV3VVVVVXVERERERERERERERERERERERERERERERERERERERERERERERERERERXVVV1d3d3d3d3d1dVVVVVVVVVVXVERERERERERERERERERERERERERERERERERERERERERERERERERER3dVV1d3d3d3d3d1dVVVVVVVVVVXVERERERERERERERERERERERERERERERERERERERERERERERERERER3d1V1d3d3d3d3d3dVVVVVVVVVVXVERERERERERERERERERERERERERERERERERERERERERERERERERER0d1V1d3d3d3d3d3dXVVVVVVVVVXVEREREREREREREREREREREREREREREREREREREREREREREREREREREV1V1d3d3d3d3d3d3VVVVVVVVVXVEREREREREREREREREREREREREREREREREREREREREREREREREREREV1V1d3d3d3d3d3d3dXd3V1VVVXVEREREREREREREREREREREREREREREREREREREREREREREREREREREdFV1d3d3d3d3d3d3d1VVd1VVVXVEREREREREREREREREREREREREREREREREREREREREREREREREREREdFV1d3d3d3d3d3d3V1VVd1VVVXVEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd1d3d3d3d3d3d3VXVVdVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd1d3d3d3d3d3d3VXdVdVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd1d3d3d3d3d3d3dVdVdVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd1d3d3d3d3d3d3dVdVd1VVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd1d3d3d3d3d3d3VXd3V1VVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd1d3d3d3d3d3d3VVVVVVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd3d3d3d3d3d3d3VVVVVVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd3d3d3d3d3d3d3V1VVVVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd3d3d3d3d3d3d3d1VVVVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHdQ0RE3d3d3d3d3d1dVVVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdEzXVVNu+7d3d3d3d3dVVVVVVXdERERERERERERERERERERERERERERERERERERERERERERERERERERETFdVVVVNDPd3d3d3d3dXVVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREVPV3d1VTTPd3d3d3d3d3d1dVVXdEdERERERERERERERERERERERERERERERERERERERERERERERERERMVXd3d1d1dXd3d3d3d3d3d1dVVXdEdERERERERERERERERERERERERERERERERERERERERERERERERERMdVV1VVd1VXd3d3d3d3d3d3dVVXdEdERERERERERERERERERERERERERERERERERERERERERERERERERM9VV1VVd1V3d3d3d3d3d3d1dVVXdEdERERERERERERERERERERERERERERERERERERERERERERERERERU11V1VXV1d3d3d3d3d3d3d1dVVXdEd0RERERERERERERERERERERERERERERERERERERERERETFERBQRU11V1VXVVV3d3d3d3d3d3d1dVVXdEd0RERERERERERERERERERERERERERERERERERERERERMdNV1bQ7U11V3VXVVV3d3d3d3d3d3d1dVVXdEd0dERERERERERERERERERERERERERERERERERERERER01VVVUUzXd3dM1XVVV3d3d3d3d3d3d3dVVXdHd0dERERERERERERERERERERERERERERERERERERERExVd3dXdU01V01PVPdVV3d3d3d3d3d3d3dVVXdHd0dERERERERERERERERERERERERERERERERERERERFT1d3d3VU91VXV3VPdVd3d3d3d3d3d3d3dVVXdHV0dERERERERERERERERERERERERERERERERERERERFTXVVd1VU91VXV3dPdXd3d3d3d3d3d3d3d1VXdHV0dERERERERERERERERERERERERERERERERERERETFTXVVd1VU91VXd3VPVXV3d3d3d3d3d3d3d3dXd3V0dERERERERERERERERERERERERERERERERERERETHVVVVdVV091VXd3VNVXV3d3d3d3d3d3d3d3dXd3V0dERERERERERERERERERERERERERERERERERERETHVVVVdVV011VU9PVNVXV3d3d3d3d3d3d3d3dXd3V0dERERERERERERERERERERERERERERERERERERETPVVdVdVV01VV3dM11VXd3d3d3d3d3d3d3d3dXd3V3VEREREREREREREREREREREREREREREREREREREdPV3T1TVV01Xd3d3V1VXV3d3d3d3d3d3d3d3dXd3V3VEREREREREREREREREREREREREREREREREREREVPdVdMz1V3VVF1VVV1VXV3d3d3d3d3d3d3d3dXdXVXVEREREREREREREREREREREREREREREREREREREVNdVd091V3VVF1VVV3VVVXd3d3d3d3d3d3d3dXdXVXVEREREREREREREREREREREREREREREREREREREVNdVd093d3VVNVVVV3d1T3d3d3d3d3d3d3d3dXdVVXVEREREREREREREREREREREREREREREREREREREVNd1d09Vd3VNdVd1d1d1TXd3d3d3d3d3d3d3dXdVVXVEREREREREREREREREREREREREREREREREREREVNd1d09VdXVNVXd3d1VXTXd3d3d3d3d3d3d3d3dXVXVEREREREREREREREREREREREREREREREREREREVNd1dMzVdXV1dRVVVXVM7vd3d3d3d3d3d3d3d1V3VXVEREREREREREREREREREREREREREREREREREREVPV1T3TVdXVXU1UVbU7MzPd3d3d3d3d3d3d3V1V1VXVEREREREREREREREREREREREREREREREREREREdPV3d3dVdXVVd1NRLu7u7vd3d3d3d3d3d3d3VVV1V3VEREREREREREREREREREREREREREREREREREREUHVVVXVVdXVVd3j3d3d3d3d3d3d3d3d3d3dXVXV1V3VEREREREREREREREREREREREREREREREREREREUHVVVXVVV1VNURE1N3d3d3d3d3d3d3d3d3dXVXd1V3VEREREREREREREREREREREREREREREREREREREUFVXVXV1V0901XVtOve3d3d3d3d3d3d3d3dXVVd3VXVERERERERERERERERERERERERERERERERERERERFT3VXd3VXTVVVVRTPj7t3d3d3d3d3d3d3dXVXdXVXVHRERERERERERERERERERERERERERERERERERERFT1d3dXTVV3d1d1TQzRNTd3d3d3d3d3d3dXVVVVVXVHRERERERERERERERERERERERERERERERERERERFBXVVVVVPV3d3dVV3dQ9Td3d3d3d3d3d3d3VVVVVXVHRERERERERERERERERERERERERERERERERERERERRFVVu1NdVV3VVV3VTdTd3d3d3d3d3d3d3d3dXVXVHREREREREREREREREREREREREREREREREREREREREUS0O1NdVV3VVd3VvUvd3d3d3d3d3d3d3d1d3VXVHRERERERERERERERERERERERERERERERERERERERERERMdVVVV1VXd09M+vd3d3d3d3d3d3d3d1V1VXV3RERERERERERERERERERERERERERERERERERERERERERMdVVVV1VXdXV3T3d3d3d3d3d3d3d3d1V1VXV3RERERERERERERERERERERERERERERERERERERERERERM9VV1V1VXdVV3T3d3d3d3d3d3d3d3d1V1VXV3R0RERERERERERERERERERERERERERERERERERERERER09XdPVNVXdVV3d3d3d3d3d3d3d3d3d1d3VXV3d0RERERERERERERERERERERERERERERERERERERERERU91V0zPVXdU1Q7vd3d3d3d3d3d3d3d1dVVXV3d0dERERERERERERERERERERERERERERERERERERERERU11V3T3VXdXdTbTd3d3d3d3d3d3d3d3dVVXV3d3dERERERERERERERERERERERERERERERERERERERERU11V3T3d3dVd3d3d3d3d3d3d3d3d3d3dXVXV3d3dHRERERERERERERERERERERERERERERERERERERERU13V3T1V3dVV3d3d3d3d3d3d3d3d3d3d3VXV3d3d3R0RERERERERERERERERERERERERERERERERERERU13V3T1V1dVV3U3d3d3d3d3d3d3d3d3d3V3V3d3d3d0dERERERERERERERERERERERERERERERERERERU13V0zNV1dXVM0Td3d3d3d3d3d3d3d3d3V3V3d3d3d3d3RERERERERERERERERERERERERERERERERERU9XVPdNV1dVd3U3d3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d0dERERERERERERERERERERERERERERERER09Xd3d1V1dVV3U3d3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d3d3R0RERERERERERERERERERERERERERERTdVVVdVV1dVV3ePd3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d3d3d3dHRERERERERERERERERERERER0d3dTdVVVdVVXVXVPe7d3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d3d3d3d3d3d3RERERERERERERHd3d3d3d3dTVVdVdXVXd0zu97d3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3VPdVd3dVV0zs9Pd3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3VPV3d1d1VUzu93d3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3U1dVVVVPbO7O93d3d3d3d3d3d3d3d3d3d3V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1EVVW7MzOz3d3d3d3d3d3d3d3d3d3d3d3V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dRLS7u7s73d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0=\",\n    \"moon\": \"hwSgAHgAAAD/////////////////////////zLy7uzvDzLy73d3d3TPd0727293d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////P////8//////zLy7u7vDzLu73d3dPTPdMz27093d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7szzLu73d3dPTPdPd2z3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP///////////8/M/v/////////z7y7u7u7u7sz3d3dPTPdPdMz3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7u7uzsz3d3dPTPd3TPT3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP/////////////P///////////z7y7u7u7uzsz3d3dPTPd3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP//////8///////////////8z/z7y7u7u7uzsz3d3dPTPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8z/z7y7O7y7uzsz3d3d3TPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7O8y7u7vT3d3d3dPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7w8y7u7vb3d3d3d3d3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////P//////z7y7w8u8u7vb3d3d3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////Py///////zLy7w8u8u7vb3T3T3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////////8///////P//////zMy7w8u8u7vT3TOz3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP///////////////////////zPzMy7w8u8u7vT3TO7093d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8u8u7vdPdO7293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8y7M7vdPT27293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8///////////////MzMy7O8y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////8/L///////////8///MzMy8O7y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP/////////////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////MzMy8u7u7u7vdPb27O93d3TMz3d3d3TM9MzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27O93dPdOz093d3TPdMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dPd27293d3TPdPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dMz27293d3T3TPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7s7vd3dO7093d0727O93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+8/P///////8/MzMy8w7u7u7vd3TOz3d3d0727u93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+7+////////8/MzMw8w7y7u7vd3T3T3d093bO7u93d3T3T3TMzMzMzMzMzMzMzMzMzMzP///////////+8/P///8///8/MzMw7vLy7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7u7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7y7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7y7szzLvd3d3d3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7u7vDzLvTPdvd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP/////////z//////////////MzLy7uzvDzLzTM7vd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzvMy7zb07vd3d093bu7u93d3d3d3TMzMzMzMzMzMzMzMzMzMzP//////////////8/L///P///MzLy7uzu8y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLy7w7Pbvd3d093bu7u93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLzLy7Pdvd3d0907O7O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////8////////////////zLy7uzvLzLy73d3d3dPd0727O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////zLy7uzvDzLy73d3d3TPd0727293d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////P////8//////zLy7u7vDzLu73d3dPTPdMz27093d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7szzLu73d3dPTPdPd2z3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP///////////8/M/v/////////z7y7u7u7u7sz3d3dPTPdPdMz3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7u7uzsz3d3dPTPd3TPT3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP/////////////P///////////z7y7u7u7uzsz3d3dPTPd3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP//////8///////////////8z/z7y7u7u7uzsz3d3dPTPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8z/z7y7O7y7uzsz3d3d3TPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7O8y7u7vT3d3d3dPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7w8y7u7vb3d3d3d3d3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////P//////z7y7w8u8u7vb3d3d3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////Py///////zLy7w8u8u7vb3T3T3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////////8///////P//////zMy7w8u8u7vT3TOz3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP///////////////////////zPzMy7w8u8u7vT3TO7093d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8u8u7vdPdO7293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8y7M7vdPT27293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8///////////////MzMy7O8y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////8/L///////////8///MzMy8O7y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP/////////////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////MzMy8u7u7u7vdPb27O93d3TMz3d3d3TM9MzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27O93dPdOz093d3TPdMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dPd27293d3TPdPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dMz27293d3T3TPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7s7vd3dO7093d0727O93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+8/P///////8/MzMy8w7u7u7vd3TOz3d3d0727u93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+7+////////8/MzMw8w7y7u7vd3T3T3d093bO7u93d3T3T3TMzMzMzMzMzMzMzMzMzMzP///////////+8/P///8///8/MzMw7vLy7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7u7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7y7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7y7szzLvd3d3d3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7u7vDzLvTPdvd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP/////////z//////////////MzLy7uzvDzLzTM7vd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzvMy7zb07vd3d093bu7u93d3d3d3TMzMzMzMzMzMzMzMzMzMzP//////////////8/L///P///MzLy7uzu8y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLy7w7Pbvd3d093bu7u93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLzLy7Pdvd3d0907O7O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////8////////////////zLy7uzvLzLy73d3d3dPd0727O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////zLy7uzvDzLy73d3d3TPd0727293d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////P////8//////zLy7u7vDzLu73d3dPTPdMz27093d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7szzLu73d3dPTPdPd2z3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP///////////8/M/v/////////z7y7u7u7u7sz3d3dPTPdPdMz3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7u7uzsz3d3dPTPd3TPT3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP/////////////P///////////z7y7u7u7uzsz3d3dPTPd3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP//////8///////////////8z/z7y7u7u7uzsz3d3dPTPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8z/z7y7O7y7uzsz3d3d3TPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7O8y7u7vT3d3d3dPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7w8y7u7vb3d3d3d3d3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////P//////z7y7w8u8u7vb3d3d3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////Py///////zLy7w8u8u7vb3T3T3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////////8///////P//////zMy7w8u8u7vT3TOz3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP///////////////////////zPzMy7w8u8u7vT3TO7093d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8u8u7vdPdO7293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8y7M7vdPT27293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8///////////////MzMy7O8y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////8/L///////////8///MzMy8O7y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP/////////////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////MzMy8u7u7u7vdPb27O93d3TMz3d3d3TM9MzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27O93dPdOz093d3TPdMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dPd27293d3TPdPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dMz27293d3T3TPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7s7vd3dO7093d0727O93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+8/P///////8/MzMy8w7u7u7vd3TOz3d3d0727u93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+7+////////8/MzMw8w7y7u7vd3T3T3d093bO7u93d3T3T3TMzMzMzMzMzMzMzMzMzMzP///////////+8/P///8///8/MzMw7vLy7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7u7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7y7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7y7szzLvd3d3d3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7u7vDzLvTPdvd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP/////////z//////////////MzLy7uzvDzLzTM7vd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzvMy7zb07vd3d093bu7u93d3d3d3TMzMzMzMzMzMzMzMzMzMzP//////////////8/L///P///MzLy7uzu8y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLy7w7Pbvd3d093bu7u93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLzLy7Pdvd3d0907O7O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////8////////////////zLy7uzvLzLy73d3d3dPd0727O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////zLy7uzvDzLy73d3d3TPd0727293d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////P////8//////zLy7u7vDzLu73d3dPTPdMz27093d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7szzLu73d3dPTPdPd2z3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP///////////8/M/v/////////z7y7u7u7u7sz3d3dPTPdPdMz3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7u7uzsz3d3dPTPd3TPT3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP/////////////P///////////z7y7u7u7uzsz3d3dPTPd3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP//////8///////////////8z/z7y7u7u7uzsz3d3dPTPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8z/z7y7O7y7uzsz3d3d3TPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7O8y7u7vT3d3d3dPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7w8y7u7vb3d3d3d3d3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////P//////z7y7w8u8u7vb3d3d3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////Py///////zLy7w8u8u7vb3T3T3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////////8///////P//////zMy7w8u8u7vT3TOz3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP///////////////////////zPzMy7w8u8u7vT3TO7093d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8u8u7vdPdO7293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8y7M7vdPT27293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8///////////////MzMy7O8y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////8/L///////////8///MzMy8O7y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP/////////////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////MzMy8u7u7u7vdPb27O93d3TMz3d3d3TM9MzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27O93dPdOz093d3TPdMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dPd27293d3TPdPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dMz27293d3T3TPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7s7vd3dO7093d0727O93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+8/P///////8/MzMy8w7u7u7vd3TOz3d3d0727u93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+7+////////8/MzMw8w7y7u7vd3T3T3d093bO7u93d3T3T3TMzMzMzMzMzMzMzMzMzMzP///////////+8/P///8///8/MzMw7vLy7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7u7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7y7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7y7szzLvd3d3d3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7u7vDzLvTPdvd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP/////////z//////////////MzLy7uzvDzLzTM7vd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzvMy7zb07vd3d093bu7u93d3d3d3TMzMzMzMzMzMzMzMzMzMzP//////////////8/L///P///MzLy7uzu8y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLy7w7Pbvd3d093bu7u93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLzLy7Pdvd3d0907O7O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////8////////////////zLy7uzvLzLy73d3d3dPd0727O93d3d3dMzMzMzMzMzMzMzMzMzMzMzM=\",\n    \"snowynight\": \"hwSgAHgAAACIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdhmRmZmZERERERERkRkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdpmRmZmZERERERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmdpkRmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIaGZmZml5kZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIhoZmZmZmZmmZmZmZmZGRERERERERGZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIhmZmaGZ2mZmZmZmZmRERFmFhERaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIgzM4iIiIiIiGhoaGaWmZmZmZmZmRZhFmZhFmaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIiIiIaGaXmZmZmZmZZhZmZmZmFmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIiIiIiIaGaXmZmZmZmWZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGaZmZmWlmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZaWZmZmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZmWmWZmlmZmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZaZmWlmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZmZkZZmZmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlpFmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlplmlmYWYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiIiJiZmZmZmZkZkZkZkRkWEWERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI3Y2IiIiIiJiZmZmZmZkRkZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiGhpaZmZmZmZkRmZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmiGZpaZmZmZmRkRmZkZmRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZpaZmZmZmRmRmZkZGRERERGRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZpaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIhoiIiIiIiIiIiIZoaJaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZmZGZmZmZEREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZGZmZmZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZmZmZaZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZnaZmZmZGZmWlmYWERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIaIiGZnaZmWlpaZZmlmYZERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIaIiIiIiIiIiIaIaGZmaZZmZmZmZmZmYRERERERkRERERERERERERERERERERERERERGIiIhohoiIiIiIloaIiIiIiIhoaGZmZmaZkZZpZmZmZpYRERERkRERERERERERERERERERERERERERERGIiIhohoiIiIiIaIiIiIiIiGZoZmZmZmaXkZlpGWZmZhkRERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmaXkZmZmWlpZhERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIZohmZmZmaWEZmZmZlpmRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiGZoZmaWGZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZ2GZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhoiIiIiIhoZmZmmRGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmlxGZmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIhoZmZmdxmRmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdhmRmZmZERERERERkRkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdpmRmZmZERERERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmdpkRmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIaGZmZml5kZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIhoZmZmZmZmmZmZmZmZGRERERERERGZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIhmZmaGZ2mZmZmZmZmRERFmFhERaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIgzM4iIiIiIiGhoaGaWmZmZmZmZmRZhFmZhFmaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIiIiIaGaXmZmZmZmZZhZmZmZmFmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIiIiIiIaGaXmZmZmZmWZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGaZmZmWlmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZaWZmZmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZmWmWZmlmZmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZaZmWlmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZmZkZZmZmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlpFmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlplmlmYWYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiIiJiZmZmZmZkZkZkZkRkWEWERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI3Y2IiIiIiJiZmZmZmZkRkZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiGhpaZmZmZmZkRmZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmiGZpaZmZmZmRkRmZkZmRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZpaZmZmZmRmRmZkZGRERERGRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZpaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIhoiIiIiIiIiIiIZoaJaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZmZGZmZmZEREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZGZmZmZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZmZmZaZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZnaZmZmZGZmWlmYWERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIaIiGZnaZmWlpaZZmlmYZERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIaIiIiIiIiIiIaIaGZmaZZmZmZmZmZmYRERERERkRERERERERERERERERERERERERERGIiIhohoiIiIiIloaIiIiIiIhoaGZmZmaZkZZpZmZmZpYRERERkRERERERERERERERERERERERERERERGIiIhohoiIiIiIaIiIiIiIiGZoZmZmZmaXkZlpGWZmZhkRERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmaXkZmZmWlpZhERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIZohmZmZmaWEZmZmZlpmRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiGZoZmaWGZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZ2GZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhoiIiIiIhoZmZmmRGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmlxGZmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIhoZmZmdxmRmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdhmRmZmZERERERERkRkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdpmRmZmZERERERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmdpkRmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIaGZmZml5kZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIhoZmZmZmZmmZmZmZmZGRERERERERGZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIhmZmaGZ2mZmZmZmZmRERFmFhERaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIgzM4iIiIiIiGhoaGaWmZmZmZmZmRZhFmZhFmaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIiIiIaGaXmZmZmZmZZhZmZmZmFmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIiIiIiIaGaXmZmZmZmWZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGaZmZmWlmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZaWZmZmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZmWmWZmlmZmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZaZmWlmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZmZkZZmZmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlpFmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlplmlmYWYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiIiJiZmZmZmZkZkZkZkRkWEWERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI3Y2IiIiIiJiZmZmZmZkRkZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiGhpaZmZmZmZkRmZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmiGZpaZmZmZmRkRmZkZmRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZpaZmZmZmRmRmZkZGRERERGRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZpaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIhoiIiIiIiIiIiIZoaJaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZmZGZmZmZEREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZGZmZmZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZmZmZaZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZnaZmZmZGZmWlmYWERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIaIiGZnaZmWlpaZZmlmYZERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIaIiIiIiIiIiIaIaGZmaZZmZmZmZmZmYRERERERkRERERERERERERERERERERERERERGIiIhohoiIiIiIloaIiIiIiIhoaGZmZmaZkZZpZmZmZpYRERERkRERERERERERERERERERERERERERERGIiIhohoiIiIiIaIiIiIiIiGZoZmZmZmaXkZlpGWZmZhkRERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmaXkZmZmWlpZhERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIZohmZmZmaWEZmZmZlpmRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiGZoZmaWGZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZ2GZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhoiIiIiIhoZmZmmRGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmlxGZmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIhoZmZmdxmRmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdhmRmZmZERERERERkRkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdpmRmZmZERERERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmdpkRmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIaGZmZml5kZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIhoZmZmZmZmmZmZmZmZGRERERERERGZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIhmZmaGZ2mZmZmZmZmRERFmFhERaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIgzM4iIiIiIiGhoaGaWmZmZmZmZmRZhFmZhFmaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIiIiIaGaXmZmZmZmZZhZmZmZmFmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIiIiIiIaGaXmZmZmZmWZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGaZmZmWlmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZaWZmZmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZmWmWZmlmZmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZaZmWlmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZmZkZZmZmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlpFmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlplmlmYWYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiIiJiZmZmZmZkZkZkZkRkWEWERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI3Y2IiIiIiJiZmZmZmZkRkZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiGhpaZmZmZmZkRmZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmiGZpaZmZmZmRkRmZkZmRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZpaZmZmZmRmRmZkZGRERERGRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZpaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIhoiIiIiIiIiIiIZoaJaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZmZGZmZmZEREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZGZmZmZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZmZmZaZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZnaZmZmZGZmWlmYWERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIaIiGZnaZmWlpaZZmlmYZERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIaIiIiIiIiIiIaIaGZmaZZmZmZmZmZmYRERERERkRERERERERERERERERERERERERERGIiIhohoiIiIiIloaIiIiIiIhoaGZmZmaZkZZpZmZmZpYRERERkRERERERERERERERERERERERERERERGIiIhohoiIiIiIaIiIiIiIiGZoZmZmZmaXkZlpGWZmZhkRERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmaXkZmZmWlpZhERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIZohmZmZmaWEZmZmZlpmRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiGZoZmaWGZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZ2GZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhoiIiIiIhoZmZmmRGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmlxGZmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIhoZmZmdxmRmZmZERERERERkRERERERERERERERERERERERERERERE=\",\n    \"stage\": \"hwSgAHgAAAAuIu4i4u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiIiIuLuLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIuIi4u7u7u7u7u7u7u7u7u7u7u4i7u4iIiIiIiLi7u7uLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIuIi4u7u7u7u7u7u7u4u4u7u7iLu7iIiIiIiIu7uIiLiLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLuIuIy4u7u7u7u7u7u7i4i7u7uIu7uIiIiIiLi7i4iIiLiLiLu7u7u7u7u7u7uLiIiIiIiIiIiIiIiIiLuIuI+Iu7u7u7u7u7uIiLu7i4i7u4iIiIiIuIuIiIiIuLuLiIuIiIiIiIiIiLi7u7uIiIiIiIiIiIiIiLiIuIuI+7u7u7u7u4iIu7uLiLu7iIiIiIi7iIiIiIi4u7uIuLu7u7uLiIiIiIiIiIiIiIiIu7u7u4iIiLiLuIuI+7u7u7u7iIi7u4iIu7uIiIiIiIiIiIiIiIi7u4uIu7u7u7u7u7uLiIiIiIiIuLuLiIiIu7u7u7iLuIuM+7u7u7uIiLu7iIi7u4iIiIiIiIiIiIyIyLu7u4i4u7uIiIi7u7u7u7uLiIiIiIi7u7uLiIiIuIiLiIuM+7u7i4iIu4uIiLi7iIiIiIiIiIiIiIzIu7uLiLi7v/v7u4iIiIi7u7u7u4uIiIiIiLi7u4u4u4i7iIuMu7uLiLi7iIiIuIuIiIiIiIiIiIiIjMj7iLu7u7u///////u7iIiIiIiIu7u7iIiIiIiIiLu7rsi7iIuMuIuIuIiIiIi4iIiIiIiIiIiIiIiMjMiIu7u////////////7+4uIiIiIiIiIu4iIiIiIiIi4rsi7iIuMuMiIiIiIiIiIiIiIiIiIiIiIiIiMyIi4u7+///////////////v7i4iIiIiIiIiIiIiIiIi4rsi7iIuMuMiIiIiIiIiIiIiIiIiIiIiIiIzIyIi7u7//////////////////+7uIiLi7iIiIiIiIiIi7rsi4iIiMuMiIiIiIiIiIiIiIiIiIiIiIjIzIiLi7v/////////////////////r7iIiIu4uIiIiIiIivrsi4iIiMuMiIiIiIiIiIiIiIiIiIiIiIjMiMuLu/v////////////////////+76+4uIiLi7iIiIiLivrsi4iIiMuMiIiIiIiIiIiIiIiIiIiIiMyMyI+7u//////////////////////+/u7vuLiIiIu4iIuLuu7si4iIiMuMiIiIiIiIiIiIiIiIiIiIyIyIz4u7+//////////////////////+/u7u77i4iIiLu7u67u7si4iIiMuMiIiIiIiIiIiIiIiIiIiIzIjMj7v7///////////////////////+/u7u7u+4uIiIi7r67u7si4iIiMuMiIiIiIiIiIiIiIiIiIjIiPjPu7v////////////////////////+7u7u7u7vuLiIi7ru7u7si4iIiMuMiIiIiIiIiIiIi7iIiIiLiM+Pu/v////////////////////////+7u7u7u7u77u7uvru7u7si4iIiMuMiIiIiIiIiIiLiIiIiIuI+I+7+/////////////////////////7+7u7u7u7u7u+67u7u7u7si4iIiMuIiIiIiIiIiIuIuIiIi4j4z7u7///////////////////////////+7u7u7u7u7u7u7u7u7u7si4iIiMuIiIiIiIiIi4i4iIiLi7jPj7v7///////////////////////////+7u7u7u7u7u7u7u7u7u7siIiIiIuIiIiIiIiLi7iIiIiLuPjPu/v////////////////////////////+/u7u7u7u7u7u7u7u7u7siIiIiIuIiIiIiIuLuIiIiIu4+M+7u//////////////////////////////+/u7u7u7u7u7u7u7u7u7siIiIiIuIuIiIi4u4uIiIi4u4z4+7+//////////////////////////////+/u7u7u7u7u7u7u7u7u7siIiIiIuIuIiLi7i4iIiIi7j4z7v7///////////////////////////////+/u7u7u7u7u7u7u7u7u7siIiIiIuLiIiLuLiIiIiLuPjPu7v////////////////////////////////+/u7u7u7u7u7u7u7u7u7siIi4iIuLi7u7uIiIiIuLuM+Pu/v////////////////////////////////+7u7u7u7u7u7u7u7u7u7siIi4iIuLi7u4iIiIi4u4y4+7+/////////////////////////////////7+7u7u7u7u7u7u7u7u7u7si4i4iIuLi7iIiIiIi7j4j7u7//////////////////////////////////7+7u7u7u7u7u7u7u7u7u7si4i7iIu4i7iIiIiLuLiPu7v///////////////////////////////////7+7u7u7u7u7u7u7u7u7u7si4iLiIu4i7iIiIuLuIuLu/v//////////////////////////7+7u7u7///+7u7u7u7u7u7u7u7u7u7si4iLiIi4i7iIi4u4i4u7+////////////////////////7+7u7u7u/v////+7u7u7u7u7u7u7u7u7u7si7iLuIi4i7u7u7iLi7v7/////////////////////7+7u7u7u7v////////+7u7u7u7u7u7u7u7u7u7siLiIuIu4i7u/uIuLu/v///////////////////+7u7u7u7v////////////+7u7u7u7u7u7u7u7u7u7siLiIu4u4i4u8iIu7u/////////////////+7u7u7u7v////////////////+7u7u7u7u7u7u7u7u7u7viLuIu4u4i4u8i7u7//////////////+7u7u7u7v///////////////////767u7u7u9vdvbu7u7u7u7viIuIi4uIi4i/u/v///////////+7u7u7u7v/////////////////v7u7u7r67u7u7293d3b27u7u7u7vuIu4i4uIi4u/+/////////+7u7u7u/v//////////////7+7u7u7u7u7u7u67u7u73d3d3d27u7u7u7suIi4i7uIi4v///////+/u/v/////////////////u7u7u7u7u7u7u7u7u7u67u7vb3d3d3d29u7u7u7si4i4i7uIi4v//////////////////////7+7u7u7u///v7u7u7u7u7u7u7u67u7vd3d3d3d3du7u7u7si4i7iLuIi4v//////////////////7u7u7u7u/v//7u7u7u7u7u7u7u7u7u67u7vd3d3d3d3du7u7u7si7iLiLiIi4v/////////////v7u7u7u7u/v//7+7u7u7u7u7u7u7u7u7u7u67u9vd3d3d3d3dvbu7u7vi7iLiLiIi8v/////////v7u7u7u7u/v//7+7u7u7u7u7u7u7u7u7u7u7u7r67u9vd3d3d3d3dvbu7u7vuLiLuLiIi/v/////v7u7u7u7u/v//7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u67u93d3d3d3d3d3bu7u7vuLiLuLiIi/v/u7u7u7u7u///v7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uIuK+u93d3d3d3d3d3bu7u7vi7uLuLuIi/u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uLiIiIuK+293d3d3d3d3d3b27u7si7u7uLu4i7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7i4iIiIi7u67293d3d3d3d3d3b27u7si4u7uIu4i7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u4uIiIiIu7u7u67293d3d3d3d3d3b27u7siIu8uIi7i7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uLiIiIuLu7u7u7u673d3d3d3d3d3d3d27u7suIvIu4i7y7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7iIiIiLi7u7u7u7u7uK73d3d3d3d3d3d3d27u7vuIuIv4i7y7u7u7u7u7u7u7u7u7u7u7u7u7u7u7i4iIiIi7u7u7u7u7u4iIuK+3d3d3d3d3d3d3d27u7viLiLv4iL+7u7u7u7u7u7u7u7u7u7u7u7u7u4uIiIi7u7u7u7u7u7uLiIiIiLe3d3d3d3d3d3d3d29u7si7iL+7iLv7u7u7u7u7u7u7u7u7u7u7u7uIiIi7u7u7u7u7u7u7u4iIiIiIiLe3d3d3d3d3d3d3d29u7si7iLy7iLv7u7u7u7u7u7u7u7u7u7u7i7i7u7u7u7u7u7u7u7uIiIiIiIiIiLe3d3d3d3d3d3d3d29u7si4i7yL/Lu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uLiIiIiIiIiIiIuLe3d3d3d3d3d3d3d29u7si4i7iL//u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uLiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3du7siIi4i/+/u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7iIiIiIiIiIiIiIi4u7u7r7d3d3d3d3d3d3d3d3du7siIu4i/u7u7u7u7u7u7u7u7u7u7u7u7u7u7iIiIiIiIiIiIuLu7u7u7u7uIuLd3d3d3d3d3d3d3d3du7suIu4i8u7u7u7u7u7u7u7u7u7u7u7u7iIiIiIiIiIi4u7u7u7u7u4iIiIiIuLe3d3d3d3d3d3d3d3du7suIuIi8u/u7u7u7u7u7u7u7u7u7iIiIiIiIiIi7u7u7u7u7iIiIiIiIiIiIuLe3d3d3d3d3d3d3d3du7suIuIi4u/u7u7u7u7u7u7uIiIiIiIiIiLu7u7u7u7u7iIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3du7vuIuIi4u/u7u7u7u4uIiIiIiIiIuLu7u7u7u7uLiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbvuIuIuIu/u7u7uLiIiIiIi4u7u7u7u7u7uIiIiIiIiIiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3dvbviIuIuIu/u7u7u7u7u7u7u7u7u7u4iIiIiIiIiIiIiIiIiIiLi7u7u7u7u7t7d3d3d3d3d3d3d3d3dvbviLuIuIu/u7u7u7u7u7u7u7i4iIiIiIiIiIiIiIiIi4u7u7u7u7u7u7i4iIt7d3d3d3d3d3d3d3d3dvbviLuIuIu/u7u7u7i4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3dvbsiLiIuIv7u7i4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3dvbsi7iIuIv7u7i4iIiIiIiIi7u7u7u7uIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi7iIuIvLu7u7u7u7u7u7u7u4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi7iIuIvLu7u7u7i4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi7iIuIvIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsi4iIiIvLuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsi4iIiMvLuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIt7d3d3d3d3d3d3d3d3dvbsi4iIiMvLuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsi4iIiMvLuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi4iIiMvLuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi4iIjMvLuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi4iIjMvLuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7e3d3d3d3d3d3d3d3dvbsi4iIjMvLuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsi4iIjMvLuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsi4jIjMvPuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7e3d3d3d3d3d3d3d3dvbsiIjIjMvPuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsiIjIjMvPuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsiIjIjMvPuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsiIjIjMvPuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsiIjIjMvPuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIt7d3d3d3d3d3d3d3d3dvbsiIj4jMvPuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsiIj4iMvPuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsi4j4iMvPuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi4j7iMvIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi4jLiM+/u7u7u7u4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi4jPiM+/u7i4iIiLu7u7u7u7u7u7u7iIiIiIiIiIiIiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3dvbsi7jPuM+/uLiIiIiIiIiIiIiIi4u7u7u7u7u7uIiIiIiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3dvbsiLiMuI+/u7iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLu7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3dvbsiLiMu4+/u7u7u7iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLu7u7u7t7d3d3d3d3d3d3d3d3dvbviLuM+4+/u7u7u7u7u7iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3du7viIuMy8+/u7u7u7u7u7u7u7u7uIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3du7vuIu4y8u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3du7suMi4y/u7u7u7uLiIi4u7u7u7u7u7u7u7u7u7u7u7u7i4iIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3du7si4i4j/+/u7u7u7u7uIiIiIiIi4u7u7u7u7u7u7u7u7u7u7u7u7u7u7u4iIuLe3d3d3d3d3d3d3d3du7si4i7jL//u7u7u7u7u7u7uIiIiIiIiIiLi7u7u7u7u7u7u7u7u7u7u7u7u7uLd3d3d3d3d3d3d3d3du7si7iLyL/Lu7u7u7u7u7u7u7u7u7iIiIiIiIiIiIiLi7u7u7u7u7u7u7u7u7r7b3d3d3d3d3d3d3d29u7vi7iLy7iLv7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiIiIiIiIuLu7u7u7u7u7u7b3d3d3d3d3d3d3d29u7viLiL+7iLv7u7u7u7u7u7u7u7u7u7u7u7u7u7u7i4iIiIiIiIiIiLi7u7u7u7b3d3d3d3d3d3d3d29u7vuLiLv4iL+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiIiIiIiIu7b3d3d3d3d3d3d3d29u7vuIuIv4i7y7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u4u7u7u7u7u7iIiIiIiIiK+3d3d3d3d3d3d3d27u7vuIv4u4i7y7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uLiIiIu7u7u7u7u4iIiK+3d3d3d3d3d3d3d27u7suIu/uIi7i7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiLu7u7u7uK+3d3d3d3d3d3d3d27u7si4i7uIu4i7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiLi7uK7293d3d3d3d3d3b27u7si7iLiLu4i7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIuK7293d3d3d3d3d3b27u7vi7i7iLuIi/v//7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uIu67293d3d3d3d3d3b27u7vu4i7iLiIi/v//////7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u67u93d3d3d3d3d3bu7u7suIi4j7iIi/v/////////v7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u6+u93d3d3d3d3d3bu7u7siIu4y7iIi8v/////////////u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u6+u9vd3d3d3d3dvbu7u7suIu4y4iIi4v///////////+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u67u9vd3d3d3d3dvbu7u7suIuIy4uIi4v/////////////v7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7r67u7vd3d3d3d3du7u7u7suIuIy4+4i4v///////////////+/u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u67u7vd3d3d3d3du7u7u7vuIuIy4+4i4v//////////////////7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u67u7vb3d3d3d29u7u7u7vuIuIuI+4i4u/+////////////////////7u7u7u7u7u7u7u7u7u7u7u7u7u67u7u73d3d3d27u7u7u7viIuIuM+4i4i/u/v///////+/u7v//////////7u7u7u7u7u7u7u7u7u7u7u67u7u7293d3b27u7u7u7viLuIuM+4i4u8i7u7//////////+7u7u7/////////7u7u7u7u7u7u7u7u7u67u7u7u9vdvbu7u7u7u7viLuIuM+4i4u8iIj7u////////////7+7u7v7////////v7u7u7u7u7u7u7r67u7u7u7u7u7u7u7u7u7siLiIuM+4i7u/uIuIz/v/////////////v7u7u7v///////+/u7v7u7u7u7r67u7u7u7u7u7u7u7u7u7si7iIuM+4i7u7u7iLiM/7////////////////u7u7u/v///////////+7u/v+7u7u7u7u7u7u7u7u7u7si7iIuM+Ii7iIi4u4iMjP+/////////////////+/u7u7u///////////v/v+7u7u7u7u7u7u7u7u7u7si7iIuM+Ii7iIiIuLuIjPj/v//////////////////7+7u7u7///////////+7u7u7u7u7u7u7u7u7u7si7iIuM+Ii7iIiIiLuLiIz4///////////////////////7u7u7v////////+7u7u7u7u7u7u7u7u7u7si4iIiM+Li7iIiIiIi7i4yM+7////////////////////////u7u7+//////+7u7u7u7u7u7u7u7u7u7si4iIiM+Li7u4iIiIi4u4iMjP+/////////////////////////+7u/v///7+7u7u7u7u7u7u7u7u7u7si4iIiM+Li7u7uIiIiIuLuIjPj/v///////////////////////////////7+7u7u7u7u7u7u7u7u7u7si4iIiM+LiIiLuLiIiIiLuLjIz7v///////////////////////////////7+7u7u7u7u7u7u7u7u7u7si4iIiM+IuIiLi7i4iIiIi7i4yM/7///////////////////////////////+7u7u7u7u7u7u7u7u7u7si4iIiI+IuIiIi4u4uIiIi4u4iM+P+//////////////////////////////+/u7u7u7u7u7u7u7u7u7si4iIiI+IiIiIiIuLuIiIiIu4uMjPu//////////////////////////////+/u7u7u7u7u7u7u7u7u7si4iIiI+IiIiIiIiLi7iIiIiLuLjIz/v////////////////////////////+/u7u7u7u7u7u7u7u7u7si4iIiIuIiIiIiIiIi4i4iIiLi7iIz4/7///////////////////////////+/u7u7u7u7u7u7u7u7u7si4iIiIuIiIiIiIiIiIuIuIiIi4i4iM+7///////////////////////////+/u7u7u7u7u7u7u7u7u7siIiIiIuIiIiIiIiIiIiLiIiIiIuIuMuP+//////////////////////////+7u7u7u7u7u+67u7u7u7siIiIiIuIiIiIiIiIiIiIi7iIiIjPiIjLj/v////////////////////////+7u7u7u7u77u7uvru7u7siIiIiIuIiIiIiIiIiIiIiIiIiIiIzLiIz7v///////////////////////7+7u7u7u7vuLiIi7ru7u7siIiIiIuIiIiIiIiIiIiIiIiIiIiIiMyMi7v7///////////////////////+7u7u7u+4uIiIi7r67u7siIiIiIuIiIiIiIiIiIiIiIiIiIiIiIjMj4u7+//////////////////////+7u7u77i4iIiLu7u67u7siIi4iIuIiIiIiIiIiIiIiIiIiIiIiIiIzI+7u//////////////////////+/u7vuLiIiIu4iIuLuu7siIi4iIuIiIiIiIiIiIiIiIiIiIiIiIiIiM+Pu/v////////////////////+/6+4uIiLi7iIiIiLivrsi4i4iIuIiIiIiIiIiIiIiIiIiIiIiIiIiIjPj7v/////////////////////v7iIiIu4uIiIiIiIivrsi4i7iIu4iIiIiIiIiIiIiIiIiIiIiIiIiIiIz4+7//////////////////+7uIiLi7iIiIiIiIiIi7rsi4iLiIu4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiM+7+///////////////v7i4iIiIiIiIiIiIiIiIi4rsi4iLiIu4uIuIiIiIi4iIiIiIiIiIiIiIiIiIiIjPu////////////7+4uIiIiIiIiIu4iIiIiIiIi4rsi7iLuIu7uLiLi7iIiIuIuIiIiIiIiIiIiIiIi7iLu7u7u///////u7iIiIiIiIu7u7iIiIiIiIiLu7rsiLiIuIu7u7i4iIu4uIiLi7iIiIiIiIiIiIiIiIu7uLiLi7v/v7u4iIiIi7u7u7u4uIiIiIiLi7u4u4u4iLiIu4u7u7u7uIiLu7iIi7u4iIiIiIiIiIiIiIiLu7u4i4u7uIiIi7u7u7u7uLiIiIiIi7u7uLiIiIuLiLuIu4u7u7u7u7iIi7u4iIu7uIiIiIiIiIiIiIiIi7u4uIu7u7u7u7u7uLiIiIiIiIuLuLiIiIu7u7u7iIuIi4u7u7u7u7u4iIu7uLiLu7iIiIiIi7iIiIiIi4u7uIuLu7u7uLiIiIiIiIiIiIiIiIu7u7u4iIiLuIu4i4u7u7u7u7u7uIiLu7i4i7u4iIiIiIuIuIiIiIuLuLiIuIiIiIiIiIiLi7u7uIiIiIiIiIiIiIiIuIi4i7u7u7u7u7u7u7i4i7u7uIu7uIiIiIiLi7i4iIiLiLiLu7u7u7u7u7u7uLiIiIiIiIiIiIiIiIiIi4i4i7u7u7u7u7u7u7u4u4u7u7iLu7iIiIiIiIu7uIiLiLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4i7i7u7u7u7u7u7u7u7u7u7u7u4i7u4iIiIiIiLi7u7uLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi7iLi7u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiIiIuLuLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI=\",\n    \"starryclouds\": \"hwSgAHgAAAAzMzMzMzMzMxExOlWlERERERExk5mZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzExERoaU6ERERERERM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMzMzHRERMRoRERGqGqGqM5OZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMzEREREREREaFVqqpVM5M5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzMzEREREREREaFVpVpVpZMzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzPTHREREREREaFVVVVVpTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPdHREREREREaFVVVVVpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMx0R3RERkREREaFTVVVVo5qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMz0xERER0RmRkREapTVVVVM6qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzExERERERkRERoVVZVVVVVaWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzHREREREREREROlVVVVVVVVWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzERERERERERERWlVVVVVVVZkzMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERoao6VVU1M5k5k5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERERGhU1WlM5mZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzHRERERERERERERERWlWjM5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzExERERERERERERERoaWqWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREzMzMz0xERERGjEREREREREaqTWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMx0REREzGhERERkREaGZmZmZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMdERFapToRkZkRERE6mZmZmZkzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREaFTVaURERkRERGqqpOZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREVNVVTMREREREaFTM5qZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREaFTVaURERERETpVNZqZMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMxMRERFapToRERERoVpVNZqZM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREREzGhERqqqqqlVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGRGZEREREREREREREREzMzMzMzMRERGjERGhU1WjOlVVpZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZERERGREREREREREREREzMzMzMzPT3RERERGhVVVVVVVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzHRERERGhVVVVVVVVNao6M5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzERERERGhWlVVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzPTERERERERqlVVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTERERERERoTpVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTEREZERERETpVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEZGZEREREVqZVVVVVVWjk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEREZERERoVOZVVVVVaM6mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZM5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPTERERERERoVVVM1VVVZOZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzERERMRoRoVWlqlNVM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzHRERoaU6Eaqqo1o1k5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMz0xExOlWlEREREaqTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzMx2hVVUzERERETGTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzMxExOlWlERERERE5k5mZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzExERoaU6ERERETGZM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMzMzHRERMRoRERGqOqOqM5OZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMzEREREREREaFVqqpVM5M5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzMzEREREREREaFVpVpVpZMzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzPTHREREREREaFVVVVVpTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPdHREREREREaFVVVVVpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMx0R3RERkREREaFTVVVVo5qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMz0xERER0RmRkREapTVVVVM6qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzExERERERkRERoVVZVVVVVaWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzHREREREREREROlVVVVVVVVWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzERERERERERERWlVVVVVVVZkzMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERoao6VVU1M5k5k5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERERGhU1WlM5mZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzHRERERERERERERExWlWjM5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzExERERERERERERERoaWqWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREzMzMz0xERERGjEREREREREaqTWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMx0REREzGhERERkREaGZmZmZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMdERFapToRkZkRERE6mZmZmZkzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREaFTVaURERkRERGqqpOZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREVNVVTMREREREaFTM5qZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREaFTVaURERERETpVNZqZMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMxMRERFapToRERERoVpVNZqZM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREREzGhERqqqqqlVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGRGZEREREREREREREREzMzMzMzMRERGjERGhU1WjOlVVpZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZERERGREREREREREREREzMzMzMzPT3RERERGhVVVVVVVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzHRERERGhVVVVVVVVNao6M5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzERERERGhWlVVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzPTERERERERqlVVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTERERERERoTpVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTEREZERERETpVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEZGZEREREVqZVVVVVVWjk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEREZERERoVOZVVVVVaM6mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZM5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPTERERERERoVVVM1VVVZOZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzERERMRoRoVWlqlNVM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzHRERoaU6EaqqoVo1k5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMz0xExOlWlEREREaqTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzMx2hVVUzERERERGTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzMxExOlWlERERERE5k5mZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzExERoaU6ERERERGZM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMzMzHRERMRoRERGqGqGqM5OZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMzEREREREREaFVqqpVM5M5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzMzEREREREREaFVpVpVpZMzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzPTHREREREREaFVVVVVpTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPdHREREREREaFVVVVVpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMx0R3RERkREREaFTVVVVo5qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMz0xERER0RmRkREapTVVVVM6qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzExERERERkRERoVVZVVVVVaWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzHREREREREREROlVVVVVVVVWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzERERERERERERWlVVVVVVVZkzMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERoao6VVU1M5k5k5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERERGhU1WlM5mZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzHRERERERERERERExWlWjM5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzExERERERERERERERo6WqWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREzMzMz0xERERGjEREREREREaqTWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMx0REREzGhERERkREaGZmZmZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMdERFapToRkZkRERE6mZmZmZkzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREaFTVaURERkRERGqqpOZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREVNVVTMREREREaFTM5qZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREaFTVaURERERETpVNZqZMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMxMRERFapToRERERoVpVNZqZM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREREzGhERqqqqqlVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGRGZEREREREREREREREzMzMzMzMRERGjERGhU1WjOlVVpZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZERERGREREREREREREREzMzMzMzPT3RERERGhVVVVVVVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzHRERERGhVVVVVVVVNao6M5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzERERERGhWlVVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzPTERERERERqlVVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTERERERERoTpVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTEREZERERETpVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEZGZEREREVqZVVVVVVWjk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEREZERERoVOZVVVVVaM6mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZM5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPTERERERERoVVVM1VVVZOZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzERERMRoRoVWlqlNVM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzHRERoaU6EaqqoVo1k5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMz0xExOlWlEREREaqTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzMx2hVVUzERERERGTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzMxExOlWlERERERExk5mZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzExERoaU6ERERERGRM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMzMzHRERMRoRERGqGqGqM5OZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMzEREREREREaFVqqpVM5M5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzMzEREREREREaFVpVpVpZMzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzPTHREREREREaFVVVVVpTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPdHREREREREaFVVVVVpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMx0R3RERkREREaFTVVVVo5qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMz0xERER0RmRkREapTVVVVM6qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzExERERERkRERoVVZVVVVVaWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzHREREREREREROlVVVVVVVVWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzERERERERERERWlVVVVVVVZkzMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERoao6VVU1M5k5k5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERETGjU1WlM5mZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzHRERERERERERERExWlWjM5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzExERERERERERERERoaWqWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREzMzMz0xERERGjEREREREREaqTWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMx0REREzGhERERkREaGZmZmZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMdERFapToRkZkRERE6mZmZmZkzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREaFTVaURERkRERGqqpOZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREVNVVTMREREREaFTM5qZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREaFTVaURERERETpVNZqZMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMxMRERFapToRERERoVpVNZqZM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREREzGhERqqqqqlVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGRGZEREREREREREREREzMzMzMzMRERGjERGhU1WjOlVVpZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZERERGREREREREREREREzMzMzMzPT3RERERGhVVVVVVVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzHRERERGhVVVVVVVVNao6M5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzERERERGhWlVVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzPTERERERERqlVVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTERERERERoTpVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTEREZERERETpVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEZGZEREREVqZVVVVVVWjk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEREZERERoVOZVVVVVaM6mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZM5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPTERERERERoVVVM1VVVZOZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzERERMRoRoVWlqlNVM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzHRERoaU6EaqqoVo1k5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMz0xExOlWlEREREaqTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzMx2hVVUzERERERGTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRERERERERERERERERE=\"\n}","sprites.background.ts":"namespace sprites.background {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const autumn = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const cityscape = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const cityscape2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const desert = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const forest1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const forest2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const fossils = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const lanterns = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const lilypads = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const lunarnewyear = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const moon = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const snowynight = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const stage = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const starryclouds = image.ofBuffer(hex``);\n}\n","sprites.builtin.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.builtin\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"angelFish0\": \"hwQQABAAAAAAAAAAAAD/AAAAAAAAwP0AAAAAAMDM/QAAAADAzNz9AAAAzBzR3fEAAMC7EREREQ8AXLsRERwRD8BVuxsREREPwFW7u7sRsfXAVRsRERG79cBVuxGxu1v1wFW1ERERW/XAXMXMW/tf9QBcxQBbu/D/AMAMAFxVDAAAAAAAzMwMAA==\",\n    \"angelFish1\": \"hwQQABAAAAAAAAAAAPAPAAAAAAAA3A8AAAAAAMDcDwAAAADMzN3xAAAAzBHdHfEAAMAbEREREQ8AXBsRwRERDwBcuxsREREPwFW7u7sRsfXAVRsREbG79cBVuxGxu7v1wFW1ERERW/XAVcXMW/tf9QBcxQBbC/D/AMAMwFXFAAAAAADAzMwAAA==\",\n    \"angelFish2\": \"hwQQABAAAAAAAAAA/AAAAAAAAADcDwAAAAAAwNwPAAAAAMzM3fEAAADMEd0dEQ8AALwRERERDwDAtRHBERHxAMC1GxEREVEPwLW7uxsRWw9ctREREbtbD1y1GxG7u1UPXFUbERGxVQ9cVcy8tf//D8xVDLu1AAAAwMzAVcUAAAAAAMDMzAAAAA==\",\n    \"angelFish3\": \"hwQQABAAAAAAAAAAAP8AAAAAAADA/QAAAAAAAMz9AAAAAMDM3B0PAADAHNHdEQ8AALwRERER8QDAtRERHBHxAMC1uxEREfEAXLW7uxsRWw9ctREREbtbD1y1GxG7u1sPXFUbERGxVQ9cVcy8tf9VD8BVDLC1AP8PAMwAXFUMAAAAAADMzAwAAA==\",\n    \"angelFishLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.angelFish0\\\",\\\"sprites.builtin.angelFish1\\\",\\\"sprites.builtin.angelFish2\\\",\\\"sprites.builtin.angelFish3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"angelFishRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.angelFish0\\\",\\\"sprites.builtin.angelFish1\\\",\\\"sprites.builtin.angelFish2\\\",\\\"sprites.builtin.angelFish3\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"aquaticBackground\": \"hwSgAHgAAACZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3c=\",\n    \"bed0\": \"hwQQABgAAAAAAADw///////MDAAAy/xvxrvb3d29zQ+w3btrtrvd3d3bzfvbvczMvDMRERHbzfvbG83dPNMRERHdzQ/cGxvROxMREdHdzQvcGxsROxMREbHdzQvcGxsROxMREbHdzQvcGxsROxMREbHdzQvcGxsROxMREbHdzQvcGxvROxMREdHdzQsbG83dPNMRERHdzQ/bvczMvDMRERHbzfuw3btrtrvd3d3bzfsAy/xvxrvb3d29zQ8AAADw///////PDAA=\",\n    \"bed1\": \"hwQQABgAAAAAAADw///////MDAAAy/xvxrvb3d29zQ+w3bvMtrvd3d3bzfvbvbzdvDMRERHbzfvbG9vRO9MRERHdzQ/cGxsROxMREdHdzQvcGxsROxMREbHdzQvcGxsROxMREbHdzQvcGxsROxMREbHdzQvcGxsROxMREbHdzQvcGxsROxMREdHdzQsbG9vRO9MRERHdzQ/bvbzdvDMRERHbzfuw3bvMvLvd3d3bzfsAy/xvxrvb3d29zQ8AAADw///////PDAA=\",\n    \"bed2\": \"hwQQABgAAAAAAADw///////MDAAAy8xvxrvb3d3LzA+w3btrvLvd3b3dy/vbvbvMvDMREdu9zPvbu8vdPNMREdu7zA/cuxzROxMREdy7zAvcuxwROxMREdy7zAvcuxwROxMREdy7zAvcuxwROxMREdy7zAvcuxwROxMREdy7zAvcuxzROxMREdy7zAsbu8vdPNMRERu7zA/bvbvMvDMREdu9zPuw3btrvLvd3b3dy/sAy8xvxrvb3d3LzA8AAADw///////PDAA=\",\n    \"bigButtonPress0\": \"hwQgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8////DwAAAAAAAAAAAADAzIyIZvb/AAAAAABmiIiIyLu7zMxs9g8AAABmZoiIiIjMu8vMzGz/AABgdnd3mXlmxry7zMzM9gAAZnd3d3eZZ2bMu8zMzMwPAHZ3d3d3l2lmxrvLzMzMD2B2d3d3iHd5Zsa8y8zMzPxgd3eXiYh3mWZmvLvMzMz8Znd3mYZod5dnZsy9zMzM/HZ3l2mGdneXaWbM3czMzPx2d5lmiHd3l2lmzN3MzMz7dndphoh5d5dpZszdvLu7+3aXZmiIeXeXaWbM3by7u/t2l4Z3iHl3l2lmzN28u7v7dpeGd4h5d5dpZszdu7u7+3aXZmiIeXeXaWbM3bu7u/t2d2mGiHl3l2lmzN27u7v7dncZYYh3d5dpZszdu7u7+3Z3F2GGdneXaWbM3bu7u/tmd3eZhmh3l2dmzN27u7v7YHd3l4mId5lmZrzdu7u7+2B2d3d3iHdxZsYc0bu7u/sAdnd3d3cXYWbGG9Hb3d0PAGZ3d3d3GWdmzB2x3d29DwBgdnd3mXlmxrzdvbu7+wAAAGZmiIiIiMzb3czMzP8AAAAAZoiIiMi73cvMzPwPAAAAAAAAAADAzMzMzPz/AAAAAAAAAAAAAPz///8PAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"bigButtonPress1\": \"hwQgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8////DwAAAAAAAAAAAADAzIyIZvb/AAAAAAAAAICIyLu7zMxs9g8AAAAAAICIiIjMu8vMzGz/AAAAAACIZmZmyLy7zMzM9gAAAACAeGZmZobMu8zMzMwPAAAAgGdmZndmyLvLzMzMDwAAAIhnZnaHaMi8y8zMzPwAAAB4ZmZ3iGiGvLvMzMz8AACAeGZ2h4hmhsy9zMzM/AAAgGdmd4hoZobM3czMzPwAAIBndoeIaGaGzN3MzMz7AACAZ3aIiHhmhszdvLu7+wAAgGeHiIZ4ZobM3by7u/sAAIBnh3iHeGaGzN28u7v7AACAZ4d4h3hmhszdu7u7+wAAgGeHiIZ4ZobM3bu7u/sAAIBndoiIeGaGzN27u7v7AACAZ3aZiGhmhszdu7u7+wAAgGdmmYhoZobM3bu7u/sAAIB4ZnaHiGaGzN27u7v7AAAAeGZmd4hohrwRu7u7+wAAAIhnZnaHaMgcEbu7u/sAAACAZ2Zmd2bIG9Hb3d0PAAAAgHhmZmaGzN293d29DwAAAACIZ2ZmyLzdvbu7+wAAAAAAgIiIiMzb3czMzP8AAAAAAACAiMi73cvMzPwPAAAAAAAAAADAzMzMzPz/AAAAAAAAAAAAAPz///8PAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"bigButtonPress\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.bigButtonPress0\\\",\\\"sprites.builtin.bigButtonPress1\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"brick\": {\n        \"data\": \"hwQQABAAAADdHd0d3R3dHRER3R0REd0d3R3dHd0d3R3dHd0d3R3dHd0d3R3dHd0d3R0REd0dERHdHd0d3R3dHd0d3R3dHd0d3R3dHd0d3R0REd0dERHdHd0d3R3dHd0d3R3dHd0d3R3dHd0d3R3dHd0dERHdHRER3R3dHd0d3R3dHd0d3R3dHQ==\",\n        \"tilemapTile\": true\n    },\n    \"cat0\": \"hwQOAA4AAADOzO/+DwAAAN472937//8A3r3T3y3b/QDA3d39Ld0PAADf3d0r3Q8AAL/d3Svd/wDA3d39Ld39AN69098tvQ8A3jvb3bLdDwDOzO/+v9v9AAAAAADw+/8AAAAA+//9AAAAAADf3fsAAAAAAPv/DwAA\",\n    \"cat1\": \"hwQOAA4AAADgzPzu/wAAAOC9s929/w8A4N07/d3S/QAA3N3d39L7AADw3d290v0AAPDb3b3S/wAA3N3d39IPAODdO/3d0g8A4L2z3S3d/QDgzPzuv/v/AAAAALD//QAAAAAA8N37AAAAAACw/w8AAAAAAAAAAAAA\",\n    \"cat2\": \"hwQOAA4AAADgzPzu/wAAAOC9s929/wAA4N07/d3SDwAA3N3d39L9AADw3d290vsAAPDb3b3S/QAA3N3d39L/AODdO/3d0v0A4L2z3S3d/wDgzPzuv/sAAAAAAADw+wAAAAAAsP/9AAAAAADw3fsAAAAAALD/DwAA\",\n    \"catWalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.cat0\\\",\\\"sprites.builtin.cat1\\\",\\\"sprites.builtin.cat2\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"catWalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.cat0\\\",\\\"sprites.builtin.cat1\\\",\\\"sprites.builtin.cat2\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"clam0\": \"hwQQABAAAAAAAAAAAMD/AAAAAAAA3LwMAAAAAMDTPPsAAAAAwLPM+wAAAAC8O83zAAAAALwzzfMAAAAAPLO8+wAAAAC8O83zAAAAADwzzfMAAAAAPLO8+wAAAAC8M83zAAAAALw7zfMAAAAAwLPM+wAAAADA0zz7AAAAAADcvAwAAAAAAMD/AA==\",\n    \"clam1\": \"hwQQABAAAAAAAM8MAMD/AAD8PPMAPLMMwDvLvM/zPPvAw8u8y//M+/DDvMzL/7/zv8vMzPz/v/O8u8vMmIn/+zzMzMw5k7/zPMzMzBmTv/O8u8vMmIn/+7/LzMz8/7/z8MO8zMv/v/PAw8u8y//M+8A7y7zP8zz7APw88wA8swwAAM8MAMD/AA==\",\n    \"clam2\": \"hwQQABAAAAAAAM8MAMD/AAD8PPMAPLMMwDvLvM/zPPvAw8u8y//M+/DDvMzL/7/zv8vMzPz/v/O8u8vM/P//+zzMzMz8/7/zPMzMzPz/v/O8u8vM/P//+7/LzMz8/7/z8MO8zMv/v/PAw8u8y//M+8A7y7zP8zz7APw88wA8swwAAM8MAMD/AA==\",\n    \"clownFish0\": \"hwQQABAAAAAAAAAA/w8AAAAAAMBE9AAAAAAATEREDwAAAMBEREQPAAAATET0RPQAAMDcRERE/QAAzEQRERFEDwDMRETExEQPwM1ERMRETw/AzURERP9PD8DNTURERMTNwN0cTUTU3M0AzMwREf2/zQAAAMz0/8wMAADARET0AAAAAMDM//8AAA==\",\n    \"clownFish1\": \"hwQQABAAAAAAAAAAAP8AAAAAAADMRA8AAAAAwERE9AAAAABMRET0AAAAwERERPQAAADcRERP1A8AzERBRERBD8DNRBQREUQPwM1ERExMRA/AzURETPRED8DNTUT0/8QMwN0cRERE3AwAzMwREf3bDAAAAMz0/8wAAAAAwEREDwAAAADA/P8PAA==\",\n    \"clownFish2\": \"hwQQABAAAAAAAADw/wAAAAAAAExEDwAAAADARET0AAAAAExERPQAAADARERPRA8AAMxNRETUDwDATBQREUH0AMBMRBRMTPQA3ExExERM9ADcTET0/0T0ANzcRERERNwM3M3RRETN3QzAzBwR0f/bDAAAzPT/D8wAAMBERPQAAAAAwPz//wAAAA==\",\n    \"clownFish3\": \"hwQQABAAAAAAAADw/wAAAAAAAExEDwAAAADARET0AAAAAExET0QPAAAATERERP0AAMAcREQU9AAAwEQREUFEDwDMRETExEQPAMxEREzERA/AzURE/09ED8DNTURERMTNwN0cTUTU3M3A3cwREf2/zQDMzP/0D8AMAABMRPQAAAAAAPz//wAAAA==\",\n    \"clownFishLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.clownFish0\\\",\\\"sprites.builtin.clownFish1\\\",\\\"sprites.builtin.clownFish2\\\",\\\"sprites.builtin.clownFish3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"clownFishRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.clownFish0\\\",\\\"sprites.builtin.clownFish1\\\",\\\"sprites.builtin.clownFish2\\\",\\\"sprites.builtin.clownFish3\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"coin0\": \"hwQIAAgAAAAAu8wAsFXVD1s90/1bUxX9W1MV/Vsd0f2wVd0PALvMAA==\",\n    \"coin1\": \"hwQIAAgAAAAAu8wAsFVVD1s90/1bUxX9Wx3R/bBV3Q8Au8wAAAAAAA==\",\n    \"coin2\": \"hwQIAAgAAAAAAAAAALvMALBVVQ9bPRP9WxHR/bBV3Q8Au8wAAAAAAA==\",\n    \"coin3\": \"hwQIAAgAAAAAAAAAAAAAALC7ywxbUd3zW1Hd87C7ywwAAAAAAAAAAA==\",\n    \"coin4\": \"hwQIAAgAAAAAAAAAALvMALBV3Q9bEdH9Wz0T/bBVVQ8Au8wAAAAAAA==\",\n    \"coin5\": \"hwQIAAgAAAAAAAAAALvMALBV3Q9bHdH9W1MV/Vs90/2wVVUPALvMAA==\",\n    \"coin\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.coin0\\\",\\\"sprites.builtin.coin1\\\",\\\"sprites.builtin.coin2\\\",\\\"sprites.builtin.coin3\\\",\\\"sprites.builtin.coin4\\\",\\\"sprites.builtin.coin5\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"computer0\": \"hwQQABAAAAAAwMzMzMzMzAAc3d3dERHLABzNu7sb3csAHM29u9sdywAczbu7Gx3LABzNu7sb3csAHM27u9sdywAczbu7Gx3LABzNu7sb3csAHM27u9sdywAczbu7Gx3LABzNu7sb3csAHN3d3RERywDAzMzMzMzMAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"computer1\": \"hwQQABAAAAAAAAAAAMDMzAC7u7u7vBHLsNHd3d3L3csbsczMzMsdy9vBZmbGyx3L28HWZsbL3cvbwWZmxssdy9vBZmbGyx3L28FmZsbL3cvbwWZmxssdy9vBZmbGyx3LG7HMzMzL3cuw0d3d3csdywC7u7u7vBHLAAAAAADAzMwAAAAAAAAAAA==\",\n    \"console\": \"hwQKAAgAAACwy8wMGxERyxsREcsbERHLu93dzbvd3c0bERHLGxERyxsREcuwu8sM\",\n    \"coral0\": {\n        \"data\": \"hwQQABAAAAAAAADAzADMAAAAAMAzDDwMAMwAADzDPAzAMwzAbDM2xsA2xjwzMzNmADzDM2bMNjPMM2bMNsPMNjxjZsZsM8xmwMzMzDM2xmwAAGzDPDMzZsDMzDMzZmZjwDNjPMbMNjMAbDPGzDwzxsw2M2bGMzYMPDPMzMxjPAzAzAAAwAzMAA==\",\n        \"tilemapTile\": true\n    },\n    \"coral1\": {\n        \"data\": \"hwQQABAAAAAAAADAzADMAAAAAMAzDDwMAMwAADzDPAzAMwzAbDM2xsA2xjwzMzNmADzDM2bMNjPMM2bMNsPMNjxjZsZsM8xmwMzMzDM2xmwAAGzDPDMzZsDMzDMzzGbDwDNjzMw2zMwAbDM8wzzDZsw2M2YzxmNmPDPMzGwzM8bAzMxsM2PMzA==\",\n        \"tilemapTile\": true\n    },\n    \"coral2\": {\n        \"data\": \"hwQQABAAAAAAADw2w2zGzMDMPGPMPGPMwDPMM8bMM8YAPMY8M2Y2ZgDMY2wzM2ZmzDNmPMNsNsw8Y8YzPMPDzMDMbMZsM8xmAADAzDM2xmwAAGzDPDMzZsDMzDMzZmZjwDNjPMbMNjMAbDPGzDwzxsw2M2bGMzYMPDPMzMxjPAzAzAAAwAzMAA==\",\n        \"tilemapTile\": true\n    },\n    \"coral3\": {\n        \"data\": \"hwQQABAAAAAAAADAzADMAAAAAMAzDDwMAMwAADzDPAzAMwzAbDM2xsA2xjwzMzNmADzDM2bMNjPMM2bMNsPMNjxjZsZsM8xmwMzMzDM2xmwAAGzDPDMzZsDMzDMzzGbDwDNjzMw2zMwAbDM8wzzDZsw2M2YzxmNmPDPMzGwzM8bAzMxsM2PMzA==\",\n        \"tilemapTile\": true\n    },\n    \"coral4\": {\n        \"data\": \"hwQQABAAAAAAADw2w2zGzMDMPGPMPGPMwDPMM8bMM8YAPMY8M2Y2ZgDMY2wzM2ZmzDNmPMNsNsw8Y8YzPMPDzMDMbMZsM8xmAADAzDM2xmwAAGzDPDMzZsDMzDMzzGbDwDNjzMw2zMwAbDM8wzzDZsw2M2YzxmNmPDPMzGwzM8bAzMxsM2PMzA==\",\n        \"tilemapTile\": true\n    },\n    \"coral5\": {\n        \"data\": \"hwQQABAAAAAAADw2w2zGzMDMPGPMPGPMwDPMM8bMM8YAPMY8M2Y2ZgDMY2wzM2ZmzDNmPMNsNsw8Y8YzPMPDzMDMbMZsM8xmAADAzDM2xmwAAGzDPDMzZsDMzDMzZmZjwDNjPMbMNjMAbDPGzDwzxsw2M2bGMzYMPDPMzMxjPAzAzAAAwAzMAA==\",\n        \"tilemapTile\": true\n    },\n    \"couchFront0\": \"hwQYABAAAAAAAADMzMzMDADMzNvdvcwMwN3d293du8y83bvLzMy7vNy9u7zd3bu83L273N3du8zcvbvc3d27DNy9u9zd3bsM3L273N3duwzcvbvc3d27DNy9u9zd3bsM3L273N3duwzcvbvc3d27DNy9u9zd3bsM3L273N3duwzcvbvc3d27DNy9u9zd3bsM3L273N3duwzcvbvc3d27zNy9u7zd3bu8vN27y8zMu7zA3d3b3d27zADMzNvdvcwMAAAAzMzMzAw=\",\n    \"couchFront1\": \"hwQYABAAAAAAAADMzMzMDADMzFNVNcwMwFVVU1VVM8zcVTPDzMwzvFw1MzxVVTO8XDUzXFVVM8xcNTNcVVUzDFw1M1xVVTMMXDUzXFVVMwxcNTNcVVUzDFw1M1xVVTMMXDUzXFVVMwxcNTNcVVUzDFw1M1xVVTMMXDUzXFVVMwxcNTNcVVUzDFw1M1xVVTMMXDUzXFVVMwxcNTNcVVUzzFw1MzxVVTO83FUzw8zMM7zAVVVTVVUzzADMzFNVNcwMAAAAzMzMzAw=\",\n    \"couchSide0\": \"hwQPABgAAAAAzMzMzMzMzMzMzADAu7u7u7u7u7u7u8zc3d3d3d3d3bu7u7zc3d3d3d3d3bu7u7zc3d3d3d3dvbu7u8y8u7u7u7u7u7u7uwzAzMzMzMzMzMzMzAwAvL3c3d3d3by9uwwA3L3c3d3d3dy9uwwA3L3c3d3d3dy9uwwA3L3c3d3d3dy9u8wA3L283d3d3dy9u7wA3LvLu7u7u9y7u7wAwLvLzMzMzMy7u8wAAMzMAAAAAADMzAw=\",\n    \"couchSide1\": \"hwQPABgAAAAAzMzMzMzMzMzMzADAMzMzMzMzMzMzM8xcVVVVVVVVVTMzM7xcVVVVVVVVVTMzM7xcVVVVVVVVNTMzM8w8MzMzMzMzMzMzMwzAzMzMzMzMzMzMzAwAPDVcVVVVVTw1MwwAXDVcVVVVVVw1MwwAXDVcVVVVVVw1MwwAXDVcVVVVVVw1M8wAXDU8VVVVVVw1M7wAXDPDMzMzM1wzM7wAwDPDzMzMzMwzM8wAAMzMAAAAAADMzAw=\",\n    \"couchSide2\": \"hwQPABgAAAAAzMzMzMzMzMzMzADAZmZmZmZmZmZmZsx8d3d3d3d3d2ZmZrx8d3d3d3d3d2ZmZrx8d3d3d3d3Z2ZmZsxsZmZmZmZmZmZmZgzAzMzMzMzMzMzMzAwAbGd8d3d3d2xnZgwAfGd8d3d3d3xnZgwAfGd8d3d3d3xnZgwAfGd8d3d3d3xnZswAfGdsd3d3d3xnZrwAfGbGZmZmZnxmZrwAwGbGzMzMzMxmZswAAMzMAAAAAADMzAw=\",\n    \"crowd0\": {\n        \"data\": \"hwQQABAAAAC8a2bM/P/MzMz2bMb8bGZmb2Zmb/xmZmZvZmZvzGZmZs/2bMxsZmZm/2zGd2dmZmb//3xvZ2ZmZv//d3dnZmZm/8x3d2dmZmbMzHxvZ2ZmZsz8z3dnZmZmzL+9zGxmZmbMzN3LbGZmZs/8z7tsZmZm/9zdvGtmZmbPzdvNa2ZmZg==\",\n        \"tilemapTile\": true\n    },\n    \"crowd1\": {\n        \"data\": \"hwQQABAAAADf3c3ba2ZmZt/dzdtrZmZmz83bzWtmZmb/3N28a2ZmZsz/z7tsZmZmzM/d/G9mZmbMv73/b2ZmZvz///9vZmZm/7wz+2xmZmbP+zyzbGZmZr+7MzxsZmZmv7szPGxmZmbP+zyzzGZmZv+8M9v9ZmZmz/zPvfxsZmbMzL/d/f/MzA==\",\n        \"tilemapTile\": true\n    },\n    \"crowd2\": {\n        \"data\": \"hwQQABAAAADMzL/d/f/MzM/8/738bGZm/8+73/1mZmb/vM/LzGZmZv+7u89rZmZm/7u7z2tmZmb/vM+7bGZmZv/Pu8tvZmZm/3v7/29mZmb/f7f8b2ZmZv//tstvZmZmz3fHvG9mZmZ8b3e8bGZmZnd3vLdrZmZmd3e8t2tmZmZ8b3fLbGZmZg==\",\n        \"tilemapTile\": true\n    },\n    \"crowd3\": {\n        \"data\": \"hwQQABAAAADPd7edaWZmZv//3MtpZmZm///bnWlmZma8u9udaWZmZsu83MtpZmZmu7vLnWlmZma7u8v8b2ZmZsu8zPxvZmZmvGtmzGxmZmbM9mzGbGZmZm9mZm9sZmZmb2Zmb2xmZmbP9mzMzGZmZv9sxnf3ZmZm//98b/dsZmb//3d39//MzA==\",\n        \"tilemapTile\": true\n    },\n    \"crowd4\": {\n        \"data\": \"hwQQABAAAAD/zHd39//MzMzMfG/3bGZmzPzPd/dmZmbMv73MzGZmZszM3ctsZmZmz/zPu2xmZmb/3N28a2ZmZs/N281rZmZm393N22tmZmbf3c3ba2ZmZs/N281rZmZm/9zdvGtmZmbM/8+7bGZmZszP3fxvZmZmzL+9/29mZmb8////b2ZmZg==\",\n        \"tilemapTile\": true\n    },\n    \"crowd5\": {\n        \"data\": \"hwQQABAAAAD/vDP7bGZmZs/7PLNsZmZmv7szPGxmZma/uzM8bGZmZs/7PLNsZmZm/7wz221mZmbP/M+9bGZmZszMv91tZmZmzMy/3W1mZmbP/P+9bGZmZv/Pu99tZmZm/7zPy2xmZmb/u7vPy2ZmZv+7u8/7ZmZm/7zPu/xsZmb/z7vL///MzA==\",\n        \"tilemapTile\": true\n    },\n    \"crowd6\": {\n        \"data\": \"hwQQABAAAAD/e/v////MzP9/t/z/bGZm//+2y/9mZmbPd8e8z2ZmZnxvd7xsZmZmd3e8t2tmZmZ3d7y3a2ZmZnxvd8tsZmZmz3e3nWlmZmb//9zLaWZmZv//251pZmZmvLvbnWlmZmbLvNzLaWZmZru7y51pZmZmu7vL/G9mZmbLvMz8b2ZmZg==\",\n        \"tilemapTile\": true\n    },\n    \"crowd7\": {\n        \"data\": \"hwQQABAAAAC8a2bMbGZmZsz2bMZsZmZmb2Zmb2xmZmZvZmZvbGZmZs/2bMxsZmZm/2zGd2dmZmb//3xvZ2ZmZv//d3dnZmZm/8x3d2dmZmbMzHxvZ2ZmZsz8z3dnZmZmzL+9zGxmZmbMzN3LzGZmZs/8z7v8ZmZm/9zdvPtsZmbPzdvN+//MzA==\",\n        \"tilemapTile\": true\n    },\n    \"crowd8\": {\n        \"data\": \"hwQQABAAAADf3c3b+//MzN/dzdv7bGZmz83bzftmZmb/3N28y2ZmZsz/z7tsZmZmzM/d/G9mZmbMv73/b2ZmZvz///9vZmZm/7wz+2xmZmbP+zyzbGZmZr+7MzxsZmZmv7szPGxmZmbP+zyzbGZmZv+8M9ttZmZmz/zPvWxmZmbMzL/dbWZmZg==\",\n        \"tilemapTile\": true\n    },\n    \"crowd9\": {\n        \"data\": \"hwQQABAAAADMzL/dbWZmZs/8/71sZmZm/8+7321mZmb/vM/LbGZmZv+7u89rZmZm/7u7z2tmZmb/vM+7bGZmZv/Pu8tvZmZm/3v7/29mZmb/f7f8b2ZmZv//tstvZmZmz3fHvG9mZmZ8b3e8zGZmZnd3vLf7ZmZmd3e8t/tsZmZ8b3fL/P/MzA==\",\n        \"tilemapTile\": true\n    },\n    \"dog0\": \"hwQQAA4AAAAARA4AAAAAAEBV5QAAAAAAVFXk/g8AAABURVRV9P//AFRFVV9lVPUA4FVVVWVVDwAAXlVFb1UPAABeVUVvVf8A4FVVVWVV9QBURVVfZUUPAFRFVFVGVQ8AVFXk/k9U9QBAVeUA8PT/AABEDgBf9QAAAAAA8FUPAAAAAADw/wAAAA==\",\n    \"dog1\": \"hwQQAA4AAAAAQOQAAAAAAABUVQ4AAAAAQFVF7g8AAABAVURVRf//AEBVVPVVVvUAAF5VVVVW9AAA4FVV9Fb1AADgVVX0Vv8AAF5VVVVWDwBAVVT1VVYPAEBVRFVlVPUAQFVF7v/0/wAAVFUO8PQAAABA5ABf9QAAAAAAAP8PAAAAAAAAAAAAAA==\",\n    \"dog2\": \"hwQQAA4AAAAAQOQAAAAAAABUVQ4AAAAAQFVF7g8AAABAVURVRf8AAEBVVPVVVg8AAF5VVVVW9QAA4FVV9Fb0AADgVVX0VvUAAF5VVVVW/wBAVVT1VVb1AEBVRFVlVP8AQFVF7v9P/wAAVFUO8FUPAABA5ABf9QAAAAAAAP8PAAAAAAAAAAAAAA==\",\n    \"dogWalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.dog0\\\",\\\"sprites.builtin.dog1\\\",\\\"sprites.builtin.dog2\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"dogWalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.dog0\\\",\\\"sprites.builtin.dog1\\\",\\\"sprites.builtin.dog2\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"field0\": {\n        \"data\": \"hwQQABAAAAAREREREREREXd3d3d3d3d3d3d3d3d3d3d3EXF3d3d3d3d3d3d3d3d3d3d3d3d3d3d3EXF3d3d3d3d3d3d3d3d3d3d3d3d3d3d3EXF3d3d3d3d3d3d3d3d3d3d3d3d3d3d3EXF3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dw==\",\n        \"tilemapTile\": true\n    },\n    \"field1\": {\n        \"data\": \"hwQQABAAAAAREREREREREWZmZmZmZmZmZmZmZmZmZmZmEWFmZmZmZmZmZmZmZmZmZmZmZmZmZmZmEWFmZmZmZmZmZmZmZmZmZmZmZmZmZmZmEWFmZmZmZmZmZmZmZmZmZmZmZmZmZmZmEWFmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZg==\",\n        \"tilemapTile\": true\n    },\n    \"fieldGoal\": \"hwQQAEAAAAAAAAAAAAAAAAAAAACwu7u7u7u7u7u7u7u7y8wMAAAAAAAAAAAAAAAAAAAAsBsRERERERERERERERHR3c0AAAAAAAAAAAAAAAAAALDb3RERERERERERERER0d3dywAAAAAAAAAAAAAAAACw293LzMzMzLu7u7u7u7vd3csLAAAAAAAAAAAAAAAAsNvdywsAAAAAvAwAAACw293LCwAAAAAAAAAAAAAAALDb3csLAAAAAAC8DAAAsNvdywsAAAAAAAAAAAAAAACw293LCwAAAAAAALzMALDb3csLAAAAAAAAAAAAAAAAsNvdywsAAAAAAAAAwMu8293LCwAAAAAAAAAAAAAAALDb3csLAAAAAAAAAADAvNzdywsAAAAAAAAAAAAAAACw293LCwAAAAAAAAAAAMDc3csLAADMzMzMzIxoAAAAsNvdywsAAAAAAAAAAACw293LCwAAwNu9u7u7u7sGALDb3csLAAAAAAAAAAAAsNvdy7v8/////9y7u7u7u2vA3N3LCwAAAAAAAAAAAMDc3csLzLvLzMz837u7u7u7a7zLywsAAAAAAAAAAAAAvMvLCwAAzP/////cu7u7u7trvMsLAAAAAAAAAAAAAAC8ywsAAAAAAADA2727u7u7uwbADAAAAAAAAAAAAAAAAMAMAAAAAAAAAADMzMzMzIxoAA==\",\n    \"football1\": \"hwQIAAYAAAAAxgAAYBEMANa7ywBGscsARkHLAEZEzQBgHQwAAMYAAA==\",\n    \"football2\": \"hwQIAAYAAAAAxgAAYL0MABa0ywBGFMsARhTEAEZEwQBg1AwAAMYAAA==\",\n    \"football3\": \"hwQIAAYAAAAAxgAAYB0MANa0ywBGRMEARkTBAEZExABg3QwAAMYAAA==\",\n    \"football4\": \"hwQIAAYAAAAAxgAAYL0MANa0ywDWRMsARkTEAEZEzQBg3QwAAMYAAA==\",\n    \"football6\": \"hwQIAAYAAAAAxgAAYL0MANa0ywAWRMsAFkTEAEZEzQBg0QwAAMYAAA==\",\n    \"football7\": \"hwQIAAYAAAAAAAAAYMwAANa7DABGscsARkHLAEZEvQCw1LEAALsMAA==\",\n    \"footballPlayer0\": \"hwQQABAAAAAAAADgvgAAAAAAAO4eDwAAAO7uLhL/D+4gIuIu0v7/7iIiIt/t0v3uIiIi/i/S/e8iIuIiLiL+/9Ii8hvuIg7/IiL+H+z+D/AuIv8fzPAPAODu/x8M0A0AAAC8vQDQDQAAAMzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"footballPlayer1\": \"hwQQABAAAAAAAAAAAAD/DwAAAAAAAP8PAAAAAO77/wAAAADg7vEPAADg7u4i8f8AACIi7iL9/wAgIiLy3d797iAiIuL/0u3uICIiLuL+AO4gLSK/4Q4A4CAi4v/BDAAA4CLy/8EAAAAA7v7/wQAAAAAAwNsLAAAAAADAzAwAAAAAAAAAAAAAAA==\",\n    \"footballPlayer2\": \"hwQQABAAAAAAAAAAAADuDgAAAADuC+4OAAAA4O7x7wAAAADgItH9AADg7u4i3v0AACIi/t0u/gAgIiLi/yL+/yAiIiLuIv7/ICIiLuL+AP8gLSK/4f4P8CAi4v/B/A8A4CLy/8HQDQAA7v7/wdANAAAAwNsLAAAAAADAzAwAAAAAAAAAAAAAAA==\",\n    \"footballPlayer3\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO4LAAAAAADg7vEAAAAAAOAi8Q/uAODu7iL9/+4AIiL+3d797iAiIuL/0v3vICIiIu4i/v8gIiIu4i7+8CAtIr/h/g8AICLi/8HcDQDgIvL/wdANAADu/v/BAAAAAADA2wsAAAAAAMDMDAAAAA==\",\n    \"footballPlayer4\": \"hwQQABAAAAAAAADgvgAAAAAAAO4eDwAAAO7uLhL/D/8gIuIu0v7//yIiIt/t3v3/IiIi/u/e/f4iIuIizu7+7tIi8utMRAzuIiL+/xtEDOAuIv//FEQMAODu//9EtAwAAAC8vczMDQAAAMzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"footballPlayer5\": \"hwQQABAAAAAAAAAAAAD/DwAAAAAAAP8PAAAAAO77/wAAAADg7vEPAADg7u4i8f8AACIi7iL7/wAgIiLyvd797iAiIuLP3P3uICIi7kxEzO4gLSL/G0TM4CAi4v8URMwA4CLy/0S0DAAA7v7/zMwAAAAAwNsLAAAAAADAzAwAAAAAAAAAAAAAAA==\",\n    \"footballPlayer6\": \"hwQQABAAAAAAAAAAAADuDgAAAADuC+4OAAAA4O7x7wAAAADgIvH/AADg7u4i+/8AACIi/r3e/QAgIiLiz9z9/yAiIuJMRMz/ICIi/htEzP8gLSL/FETM8CAi4v9EtAwA4CLy/8zMDQAA7v7/wdANAAAAwNsLAAAAAADAzAwAAAAAAAAAAAAAAA==\",\n    \"footballPlayer7\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO4LAAAAAADg7vEAAAAAAOAi8Q/uAODu7iL9/+4AIiL+3f7/7iAiIuL//v/vICIiIu7e/f8gIiIuwtz98CAtIu9MRMwAICLi/xtEzADgIvL/FETMAADu/v9EtAwAAADA28zMAAAAAMDMDAAAAA==\",\n    \"footballPlayerRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.footballPlayer0\\\",\\\"sprites.builtin.footballPlayer1\\\",\\\"sprites.builtin.footballPlayer2\\\",\\\"sprites.builtin.footballPlayer3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"footballPlayerCarryingBallRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.footballPlayer4\\\",\\\"sprites.builtin.footballPlayer5\\\",\\\"sprites.builtin.footballPlayer6\\\",\\\"sprites.builtin.footballPlayer7\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"footballPlayerLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.footballPlayer0\\\",\\\"sprites.builtin.footballPlayer1\\\",\\\"sprites.builtin.footballPlayer2\\\",\\\"sprites.builtin.footballPlayer3\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"footballPlayerCarryingBallLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.footballPlayer4\\\",\\\"sprites.builtin.footballPlayer5\\\",\\\"sprites.builtin.footballPlayer6\\\",\\\"sprites.builtin.footballPlayer7\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"forestBackground\": \"hwSgAHgAAACZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd2ZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd2Z3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2Zmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmdmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmdmdnd3Znd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmd3Z3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmd3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmdmZ3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZ2Znd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZndmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZnZ2dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZ2dmd2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZnd2d3d2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmd3d3d3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZnd3Z3dndnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZnZmd3ZnZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmdmZnZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZndmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnZnd2Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3Z3d3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZndnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3Znd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZndnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZndnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZndmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ2dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3Z2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3Znd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2ZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2Znd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2Znd2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdmd3Znd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3ZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnZ3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdmZ2Z3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2ZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0=\",\n    \"forestBat0\": \"hwQQABAAAAAA//8PwPwPAPDP/8+8u/sA//zPu7Ecuw/PzDyzu/u7+88AzLu7+7v7AADAvLv7u/sAADyzsRy7+wAAzLu7u7v7AADAzLu7u/sAAP+/vLu7/AD/vLvMu8sP8LzLzMz//wDAy7vMDMAMAL/LvMsAAAwAv8zMDAAAAADPAAAAAAAAAA==\",\n    \"forestBat1\": \"hwQQABAAAADw/w/A/A8AAPD/z7y7+wAA/8y7G8uxDwDPPLO7u7/7AM/Au7u7v/sAAMC8u7u/+wAAPLMby7H7AADMu7u7u/sAAMDMvLu7+wAA8P+7vLv8AADwu8u8yw8AAL/LzPz/AAAAvLzLzAwAAPC7zLsMDAAA8MvMzAAAAADwDAAAAAAAAA==\",\n    \"forestBat2\": \"hwQQABAAAAAAAMDM/8AMAADAzLu7z8wAwLy7sRz7zAzAM7u7+7vPDAC8u7v7uw8MAMy7u/u7DwDAM7uxHLsPAMC8u7u7uw8AAMy7u/zPDwAAzLv8zMsMAADA///Lu8wAAAD//8u8ywAAAAD/y8zLDAAAAAAAAMwMAAAAAAAAwAwAAAAAAAAADA==\",\n    \"forestBat3\": \"hwQQABAAAADwz/wPwPwPAP/8///Mu/sAzwz/z7uxHA8PAMA8s7v7+wAAwMy7u/v7AAAAzLy7+/sAAMA8s7Ec+wAAwLy7u7v7AAD/z7u7u/sA/7+7vLu7/PC8y8zMu8sPwMu7zMz//wC/y7zLDMwAAL/MzAwAwAAAzwAAAAAAAAAAAAAAAAAAAA==\",\n    \"forestBat4\": \"hwQQABAAAAAA//8PwPwPAPDP/8+8+/8A//zPG7ERIg/PzDyzu/8i+88AzLu7/yL7AADAvLsRIvsAADwTsfy/+wAAzLu7u7v7AADAzLu7u/sAAP+/vLu7/AD/vLvMu8sP8LzLzMz//wDAy7vMDMAMAL/LvMsAAAwAv8zMDAAAAADPAAAAAAAAAA==\",\n    \"forestBat5\": \"hwQQABAAAADw///MzP8AAPD/z7z7/w8A/8y8sREv8gDPPLO7/y8iD8/Mu7v/LyIPAMC8uxEvIg8APLOx/P+yDwDMu7u7u7sPAMDMvLu7uw8A8P+7vLvLDwDwu8u8u/wAAL/LzPz/DwAAvLzLzMwAAPC7zLsMwAAA8MvMzAAAAADwDAAAAAAAAA==\",\n    \"forestBat6\": \"hwQQABAAAAAAAPDM/P8AAAAAz7z7/w8AAPC8sREv8gAAPLO7/y8iDwDMu7v/LyIPAMC8uxEvIg8APLOx/P+yDwDMu7u7u/sPAMC8u8v//A8AwLzLz7zMDwAA/P+/vMsMAADw/7/MuwwAAADwv8y8zAAAAAAAwMDMAAAAAAAAAMwAAAAAAAAAwA==\",\n    \"forestBat7\": \"hwQQABAAAADwz/wPwPwPAP/8///MsfsAzwz/z7uxHA8PAMA8s7v7+wAAwMy7u/v7AAAAzLy7+/sAAMA8s7Ec+wAAwLy7sbv7AAD/z7u7u/sA/7+7vLu7/PC8y8zMu8sPwMu7zMz//wC/y7zLDMwAAL/MzAwAwAAAzwAAAAAAAAAAAAAAAAAAAA==\",\n    \"forestBatLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.forestBat0\\\",\\\"sprites.builtin.forestBat1\\\",\\\"sprites.builtin.forestBat2\\\",\\\"sprites.builtin.forestBat3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"forestBatAttackLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.forestBat4\\\",\\\"sprites.builtin.forestBat5\\\",\\\"sprites.builtin.forestBat6\\\",\\\"sprites.builtin.forestBat7\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"forestBatRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.forestBat0\\\",\\\"sprites.builtin.forestBat1\\\",\\\"sprites.builtin.forestBat2\\\",\\\"sprites.builtin.forestBat3\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"forestBatAttackRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.forestBat4\\\",\\\"sprites.builtin.forestBat5\\\",\\\"sprites.builtin.forestBat6\\\",\\\"sprites.builtin.forestBat7\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"forestFlowers0\": \"hwQIABAAAAAAALC7zAAAAAAAG9HRDAAAAAAbMxFsZogAAD1V3XeGhwAAPVXdZniHAAAbMxEMeGcAABvR0Qx4BgAAsLvMAGYA\",\n    \"forestFlowers1\": \"hwQIABAAAAAAAMDMzAAAAAAAzDYzDAAAAMA8bDZjZogAwDY/ZnOGhwDA9jZjY3iHAABsMzMGeGcAAMDMzAB4BgAAAAAAAGYA\",\n    \"forestFlowers2\": \"hwQIABAAAAAAAACGAAAAAGCIAGaIiAAAdncIYHh3CAB3iIaAd4iGYIcAaHiHAGh4CGCIdwiIgHcAZgiIAGYIiACIAAAAYAgA\",\n    \"forestLargeMushroom0\": \"hwQgABAAAAAAAADMDAAAAAAAwLzLDAAAAADAu7sMAAAAALy7u8sAAADAu929ywAAALwT0d3LAAAAOxER3bsMALA7ERHduwwAsDMREdG7DACwMxERsbsMADszExGzuwywOzEzM7O7DLsbETMzM7u8uxsRMzMzu7zbGxEzMzO7vN0bETMzM7vc3TsxMzMRuxzROzMzExG9HBE7MzMTEb28ETszMxMRvbzbOzMzM9G7DLs7MzMzs7sMsLAzETOzuwwAsBMRMbO7DACwGxERu7sMAAAbERG7uwwAANsR0bvLAAAAsN3du8sAAAAA2727ywAAAADAu7sMAAAAAMC8ywwAAAAAAMwMAAAA\",\n    \"forestLargeMushroom1\": \"hwQgABAAAAAAAAAAwMwAAAAAAAC8ywwAAAAAwLu7zAAAAAC8u7vLAAAAwLvdvcsAAAC8E9HduwwAADsREd27DACwOxER3bsMALAzERHRuwwAsDMREbG7DAA7MxMRs7u8ADsxMzOzu7wAGxEzMzO7vAAbETMzM7vcABsRMzMzu9wAGxEzMzO73AA7MTMzEbvcADszMxMRvRwAOzMzExG9HAA7MzMTEb3cADszMzPRu7wAOzMzM7O7vACwMxEzs7sMALATETGzuwwAsBsREbu7DAAAGxERu7sMAADbEdG7uwwAALDd3bvLAAAAANu9u8sAAAAAwLu7zAAAAAAAvMsMAAAAAADAzAAA\",\n    \"forestMonkey0\": \"hwQQABAAAAAAAMDMAAAAAADA3M0PAAAAAN/tzf0AAADw/e/N/fD/D+/d3c397979793d3P3+v/3v/d/d/f7//O/e3d3u7t797+7u7u7+v/3w7u7u7+7++wD/vfvv7v77APDdzfDu7v0AAM8MAO/+/wAAAPD//w8AAAAA7+7+AAAAAAD//w8AAA==\",\n    \"forestMonkey1\": \"hwQQABAAAAAAAMDMAPD/AADA3M3/3/0AAN/tzf3f+wDw/e/N/f//AO/d3c393/0A793d3P3e+wDv/d/d/v7/AO/e3e3u7v4A7+7u7u7+/wDw7u7u7+7+DwD/37vv7v78AADf3fzu/v0AAPDMAO/u/QAAAAD/////AAAA8O7+AAAAAADw/w8AAA==\",\n    \"forestMonkey2\": \"hwQQABAAAAAAAMDMAADwDwDA3N0PAN/9AN/d3vzw3v3w3f/e/PC//O/d3d3879/9793dzf3+3v3v3f/d/u7O/e/e3e3u7v//7+7u7u7+/wDw7u7u7+7/AADfu//v7v4PAN/dDPDu/vwA8MwAAO/+/QAAAP///7/9AADw7u4P8A8AAPD//wAAAA==\",\n    \"forestMonkey3\": \"hwQQABAAAAAAAMDMAAAAAADA3N0PAAAAAN/d7f0A8A/w3f3v/QDf/e/d3d39/979793d3dz+v/zv3v3f7e7f/e/u3d3u7t797+7u7u7uzv3w7u7u7+78//C9+//v7v0P8N3NAPC+/QAAzwwAAP8PAAAA8P///w8AAADw7u4PAAAAAAD//wAAAA==\",\n    \"forestMonkey4\": \"hwQQABAAAAAAAMDMAAAAAADA3M0PAPAPAN/tzf0Av/3w/e/N/fDe/e/d3c397/7/793d3P3v3/3v/d/d/v6+/e/e3e3u7v7/7+7u7u7uv/3w7u7u7/6+/QD/vfvv7v77APDdzfDu7v4AAM8MAP///wAAAAAAAPD/AAAAAADv7v8AAAAAAP//Dw==\",\n    \"forestMonkey5\": \"hwQQABAAAAAAAMDMAAAAAADA3M0PAPAPAN/tzf0Av/3w/e/N/fDe/e/d3c397/7/793d3P3v3/3v/d/d/v6+/e/e3e3u7v7/7+7u7u7uv/3w7u7u7/6+/QD/vfvv7v77APDdzfDu7v4AAM8MAP///wAAAAAAAPD/AAAAAADv7v8AAAAAAP//Dw==\",\n    \"forestMonkey6\": \"hwQQABAAAAAAAMDMAAAAAADA3M0PAP8PAN/tzf3///3w/e/N7d/9/e/d3c3tv/3/793d3O3///7v/d/d/u/+/u/e3e3+7u/+7+7u7u7+v/3w7u7u7/6+/QD/vfvv7v77APDdzfDu7v4AAM8MAP///wAAAAAAAPD/AAAAAADv7v8AAAAAAP//Dw==\",\n    \"forestMonkey7\": \"hwQQABAAAAAAAAAAAAAAAAAAzAwAAPD/APDNzQAAv/0A/93cDPDf/fD93tz97/7/793e3P3u7v7v3d3c/e7u/u/9zd3t7v7/7/3d3e7uv/3v3t3t/u6//fDu7u7v/v/7AP/d/e/+//8A8P3/7v///wAA/9v/7+7/AADw3Q///w8AAAD/DwAAAA==\",\n    \"forestMonkey8\": \"hwQQABAAAAAAAAAAAAAAAAAAzAwAAPD/APDdzQAAv/0A383dDPDf/fD93dz97/7/7/3e3P3u7v/v3d7c/e7u/+/d3dzt7v7/7/3N3e7uv/3v/d3d/u6//fDe3e3v/v/7AP/u/u/+//8A8P3/7////wAA/7/97+7/AAAA3/3//w8AAAD//wAAAA==\",\n    \"forestMonkey9\": \"hwQQABAAAAAAAADA/P8AAAAAANzf/f//AAD/7d/9v/0A8N3t/f/f/QDv3d3t/v7/AO/d3/zu7/4A793f/e7//gDv3t397/7/AO/u7u7vvv0A8O7u7u++/QAA/73r///7AADw3f3///8AAADPDADw/wAAAAAA8O7+AAAAAADw/w8AAAAAAAAAAA==\",\n    \"forestMonkey10\": \"hwQQABAAAAAAAMDMAAAAAAAA3P3/AP//AP/t/dv/v/3w3e393e/e/e/d3f3/7/7/7/3f3O/+7v/v3d3d/+7v/u/e3d3+7v/+7+7u7v7uv/3w7u7u7u+//QD/vfvu///7APDdzf////8AAM/8AAD//wAAAAAA7+7/AAAAAAD//w8AAAAAAAAAAA==\",\n    \"forestMonkeyWalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.forestMonkey0\\\",\\\"sprites.builtin.forestMonkey1\\\",\\\"sprites.builtin.forestMonkey2\\\",\\\"sprites.builtin.forestMonkey3\\\",\\\"sprites.builtin.forestMonkey4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"forestMonkeyLaughLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.forestMonkey5\\\",\\\"sprites.builtin.forestMonkey6\\\",\\\"sprites.builtin.forestMonkey7\\\",\\\"sprites.builtin.forestMonkey8\\\",\\\"sprites.builtin.forestMonkey9\\\",\\\"sprites.builtin.forestMonkey10\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"forestMonkeyWalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.forestMonkey0\\\",\\\"sprites.builtin.forestMonkey1\\\",\\\"sprites.builtin.forestMonkey2\\\",\\\"sprites.builtin.forestMonkey3\\\",\\\"sprites.builtin.forestMonkey4\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"forestMonkeyLaughRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.forestMonkey5\\\",\\\"sprites.builtin.forestMonkey6\\\",\\\"sprites.builtin.forestMonkey7\\\",\\\"sprites.builtin.forestMonkey8\\\",\\\"sprites.builtin.forestMonkey9\\\",\\\"sprites.builtin.forestMonkey10\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"forestMushroomPatch\": \"hwQYABAAAAAAAACwzAAAAAAAALu7DAAAAACwEbvLAAAAsBsRs8sAAAA7EzGzuwwAsDMzM9G7DLuwMzMT0b28EbAzMxPRvRzRsBMxM9G73N2wExEzs7vcvQAbETO7u7y7ADsRM9u9CwAAsDOz3c0AAAAAu7vdywwAAADAu8u7DAAAAADLvN3LAAAAAAC73cu7AAAAsDO7u9wAAACwM7O73AAAALARs7u8AAAAsBHTvQwAAAAAO9O9DAAAAADAu8sAAAAAAADMDAA=\",\n    \"forestScenery0\": \"hwQQABAAAAAAAADMzMzMzAAAzLvLzMvMAMC7zLvMu8wAvLvLvMy7zMC8u7u8zLzMwNvdu7zMzMy8u9u9vMzMzLzdu728vLvM3N3d28zMvMvc3d3bzL3My9zd3du83cvL3N3du9zdzcvA3b3L3N3NywC8u8zc3b3LAMDMzLzdvMwAAAAAwLzLzA==\",\n    \"forestScenery1\": \"hwQQABAAAAAAAAAAAAD/7gDg/////+/uANu9/v/v7u6wu9vt7u7u7rDdvb3u/+7/27293e7u/v/b29vb/v7//9vb29vu7u7u29vb2+7/7v/b29vb7u/v7tu9vd3u/u/usN29ve7u7u6wu9vt7v//7gDbve7u7v//AODu/v/u/v8AAAAAAO/u/w==\",\n    \"forestScenery2\": \"hwQQABAAAAAAAMDMDAAAAAAAzLvLAAAAAMDcvbsMAAAAvBG9uwwAALA7ETG7ywAAsDMRM73LALs7MzMT3cu72zszMxPRyxHdOzMzM7HLERE7ETMzs8u7EbARMRG7y7C7sBsxEb3LAAAAvDPRvQwAAADAvNu9DAAAAADMu8sAAAAAAMDMDAAAAA==\",\n    \"forestScenery3\": \"hwQQABAAAAAAAAAAzAwAAAAAAMC7ywAAAAAAvL27DAAAAMAb0bsMAAAAuxMRs8sAAAA7EzHTy7sAsDMzM9HN2wCwMzMzEc3dALAzMzMTyxEAsBMxMzPLEQAAGxETscu7AAC7ERPRywAAAMA7E90MAAAAAMy73QwAAAAAwLvLAAAAAAAAzAwAAA==\",\n    \"forestSnake0\": \"hwQQABAAAAAAAAAAAMD/AADA/A8AHGEPAGx398AXEcbAd2x3fxcRwWx39ncsEhHBfHdmd3x3EcF8d2Z3fGcWwXx39md8/GbBfHdsx2fPbMFsd3d3x8xmxsB3d3f2ZmbGAGx3Z39nZvYAwPz/d2fGDwAAAMB3xv8AAAAAAHwMAAAAAAAAwAwAAA==\",\n    \"forestSnake1\": \"hwQQABAAAAAAwPwPAAAAAABsd/cAzMwAwHdsd88WYQxsd/Z3bBcRxnx3ZncsFxHBfHdmd3wSEcF8d/ZnfHcRwXx3bMd3ZxbBbHd3d/dsZsHAd3d3xs9mxwBsd2fPZmbGAMD8/3xnZsYAAAAAfGdmzAAAAAB8x8wMAAAAAMDHAAAAAAAAAMwAAA==\",\n    \"forestSnake2\": \"hwQQABAAAAAAAAAAAPz/AAAAAADAF2EPAMD8D3wREfYAbHf2fBER8cB3h/9/ERHBbGwXIXIXEcF89vcvcncRwXxm9y9yZ2bBfGYXIXL3ZsZ89mf/d89sxnxsd3fHzGbGbHd3d8ZmZsbAdndnf2dmDADM/P98Z8wAAAAAAMDHAAAAAAAAAMwAAA==\",\n    \"forestSnake3\": \"hwQQABAAAAAAAAAAwP//AAAAAAB8EWYPAAAAwBcREfYAwPzPFxER8QB8Z2YXERHBwHf4/3cREcH8dhEichcRwfx2/yJyZ2bGbHb/InL3ZsZsdhEics9sxvx29v/HzGbG/HZ3d8dmZsZ8d3d3f2dmDMB2d2d8Z8wAAMz8/8DHAAAAAAAAAMwAAA==\",\n    \"forestSnake4\": \"hwQQABAAAAAAAAAAwP//AAAAAAB8EWYPAAAAwBcREfYAwPzPFxER8QB8Z2YXERHBwHf4/3cREcH8dhEichcRwfx2/yJyZ2bGbHb/InL3ZsZsdhEics9sxvx29v/HzGbG/HZ3d8dmZsZ8d3d3f2dmDMB2d2d8Z8wAAMz8/8DHAAAAAAAAAMwAAA==\",\n    \"forestSnake5\": \"hwQQABAAAAAAAAAAAMz/AAAAAADAdnfMAAAAAHzHbMEAAADAdmf8zAAAAMB3Z2bPAAAAwHdnZs8AAADAd2f8wQAAAMB3x2zMAADMzHZ3d8cAwGxmfHd3xgDAd2bMdnfPAHx3ZmbM/8YAfMfMZmZmxgB8DMBmZmYMAGwMAMxmZgwAzAAAwMzMAA==\",\n    \"forestSnake6\": \"hwQQABAAAAAAAAAAwPwPAAAAAABsd/fMAAAAwHfMdsEAAABsd8Z/zAAAAHx3ZnbPAAAAfHdmds8AAAB8d8Z/wQAAAHx3zHbMAMzMbHd3d8fAbGbMd3d3xsB3ZsZsd2fPfHdmZsb8/8Z8x8xmZmZmxnwMwGxmZmYMbAwAzGxmxgzMAAAAzMwMAA==\",\n    \"forestSnake7\": \"hwQQABAAAAAAAAAAwPwPAAAAAABsd/fMAAAAwHfMdsEAAABsd8Z/zAAAAHx3ZnbPAAAAfHdmds8AAAB8d8Z/wQAAAHx3zHbMAMzMbHd3d8fAbGbMd3d3xsB3ZsZsd2fPfHdmZsb8/8Z8x8xmZmZmxnwMwGxmZmYMbAwAzGxmxgzMAAAAzMwMAA==\",\n    \"forestSnakeWalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.forestSnake0\\\",\\\"sprites.builtin.forestSnake1\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"forestSnakeAttackLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.forestSnake2\\\",\\\"sprites.builtin.forestSnake3\\\",\\\"sprites.builtin.forestSnake4\\\",\\\"sprites.builtin.forestSnake5\\\",\\\"sprites.builtin.forestSnake6\\\",\\\"sprites.builtin.forestSnake7\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"forestSnakeWalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.forestSnake0\\\",\\\"sprites.builtin.forestSnake1\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"forestSnakeAttackRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.forestSnake2\\\",\\\"sprites.builtin.forestSnake3\\\",\\\"sprites.builtin.forestSnake4\\\",\\\"sprites.builtin.forestSnake5\\\",\\\"sprites.builtin.forestSnake6\\\",\\\"sprites.builtin.forestSnake7\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"forestTiles0\": {\n        \"data\": \"hwQQABAAAAAAYGaIZogIAGB2d3aHZvgAYHdnd2aGZg92d3d3d2fm/nZ3d3d3Zuj+dnd3d2dmhv52d3d3dndmhnZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aG+HZ3d3d3Zmb/dnd3d3Znhv92d3d3Z4aI+GB3Z3dnZogPYHZ3dodm+AAAYGaIZogIAA==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles1\": {\n        \"data\": \"hwQQABAAAAAAYGaIZoiI+GB2d3aHZujuYHdnd2aGZu52d3d3d2fm7nZ3d3d3ZujuZnd3d2dmhv5mdnd3dndmhmZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3dnhu52d3d3ZoaI6GZ3d3d3ZojuZnZ3d2dm5u5md3d3d2aG/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles2\": {\n        \"data\": \"hwQQABAAAAB2d3d3d2eI+HZ3d3d2d+judnd3d2dmZu52d3d3d2fm7nZ3d3d3ZujuZnd3d2dmhv5mdnd3dndmhmZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3dnhu52d3d3ZoaI6GZ3d3d3ZojuZnZ3d2dm5u5md3d3d2aG/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles3\": {\n        \"data\": \"hwQQABAAAAB2d3d3d2eI+HZ3d3d2d+judnd3d2dmZu52d3d3d2fm7nZ3d3d3ZujuZnd3d2dmhv5mdnd3dndmhmZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3Znhu52d3d3Z4aI6GB3Z3dnZojuYHZ3dodm6O4AYGaIZoiI/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles4\": {\n        \"data\": \"hwQQABAAAAAAYGaIZoiI+GB2d3aHZujuYHdnd2aGZu5md3d3d2fm7nZ3d3d3Zujudnd3d2dmhv52d3d3dndmhnZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3Znhu5md3d3Z4aI6GB3Z3dnZojuYHZ3dodm6O4AYGaIZoiI/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles5\": {\n        \"data\": \"hwQQABAAAADv/u7/7v/v/v//7u/u/u/+/u7v7+7+/+/+7v//7v//7v////7////u/v/////////u7////////+7//////////v/////////u/v///////+/+/////////u/////////+//////////7+////////7+7////////v7v///////w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles6\": {\n        \"data\": \"hwQQABAAAADv/v///////////////////u7////////+7v///////////////////v/////////u7////////+7//////////v/////////u/v///////+/+/////////u/////////+//////////7+////////7+7////////v7v///////w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles7\": {\n        \"data\": \"hwQQABAAAADv/v///////////////////u7////////+7v///////////////////v/////////u7////////+7//////////v/////////u/u///////+/+/////////u/v/v//7/7+/+/+///u7v7u///u/+7u7+7//u7v7/7v/u/u/v///w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles8\": {\n        \"data\": \"hwQQABAAAAAAvru7u/4PAOC7u7u7vv4Avru7u7vrvg++u7u7u+6+/ru7u7u7vuv+u7u7u+u+++67u7u76+7+/ru7u7vru+7/u7u7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/++u7u7u+vr/767u7u76+4P4Lu7u7vr6wAAvru7u74PAA==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles9\": {\n        \"data\": \"hwQQABAAAADv/u7/7v/v/v//7u/u/u/+/v/v7+7+/+/+7v//7v//7v/u///////u/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles10\": {\n        \"data\": \"hwQQABAAAAD//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles11\": {\n        \"data\": \"hwQQABAAAAD//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/+////7/7/7+7////u7u//7v/u/+7u7v7/7+7v7/7u/v7v/v///w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles12\": {\n        \"data\": \"hwQQABAAAAAAvru7u777/+C7u7u7vu7/vru7u7vrvv6+u7u7u+6+/ru7u7u7vuvuu7u7u+u+++67u7u76+7+/ru7u7vru+7/u7u7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/++u7u7u+vr/767u7u76+7/4Lu7u7vr6/8Avru7u777/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles13\": {\n        \"data\": \"hwQQABAAAADv/u7/7/4PAP//7u/+//8P/v/v7/7u7w/+7v///+7////u/////+7/////////7v/////////v/v///////+/+/////////////////////v///////////////////////////////////////////////////////////////w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles14\": {\n        \"data\": \"hwQQABAAAAD///////8PAP////////8P/////////w////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8P/////////w////////8PAA==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles15\": {\n        \"data\": \"hwQQABAAAAD//////////////////////////////////////////////////////////////////////////v///////////////////v/////////v/v///////+/+/+/+///v////7+7////u/+//7v/u/+4P7v7/7+7+/w/u/v7v7v4PAA==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles16\": {\n        \"data\": \"hwQQABAAAAC+u7u7u777/7u7u3u7vu7/a7a7d7trZv57Z3u3t3Zn/mt3Zna3d+bua3d3d2dmhv5mdnd3dndmhmZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3dnhu52d3d3ZoaI6GZ3d3d3ZojuZnZ3d2dm5u5md3d3d2aG/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles17\": {\n        \"data\": \"hwQQABAAAADv/g8AAAAAAP///w8AAAAA/u7vDwAAAAD+7v//AAAAAP//7v8AAAAA/v/u/wAAAADu7+/+AAAAAO7/7/4AAAAA/v///wAAAADu/v/+AAAAAO/+//8AAAAA/u///wAAAAD+////AAAAAP7+//8AAAAA7+7//wAAAADv7v//AAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles18\": {\n        \"data\": \"hwQQABAAAADv/v//AAAAAP////8AAAAA/u7//wAAAAD+7v//AAAAAP////8AAAAA/v///wAAAADu7///AAAAAO7///8AAAAA/v///wAAAADu/v//AAAAAO/+//8AAAAA/u///wAAAAD+////AAAAAP7+//8AAAAA7+7//wAAAADv7v//AAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles19\": {\n        \"data\": \"hwQQABAAAADv/v//AAAAAP////8AAAAA/u7//wAAAAD+7v//AAAAAP////8AAAAA/v///wAAAADu7//+AAAAAO7///8AAAAA/v/+/wAAAADu/u/+AAAAAO/+7/4AAAAA/u///wAAAAD+/+7/AAAAAP7+7g8AAAAA7+7/DwAAAADv7g8AAAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles20\": {\n        \"data\": \"hwQQABAAAAB2d3d3d2eI+HZ3d3d2d+j/dnd3d2dmZv52d3d3d2eG/nZ3d3d3ZujuZnd3d2dmhu5mdnd3dndmhmZ3d3d3Z2b/dnd3d3dmiPh2d3d3Z2aGiGZ3d3d3dmf+a3d2Z3Znd/9rZ3tnZoaI+Lu7e3t2Z4j/vru7e2d36//uu7u7Z777/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles21\": {\n        \"data\": \"hwQQABAAAAAAYGaIZogIAGB2d3aHZvgAYHdnd2aGZg92d3d3d2f2/3Z3d3d3Zvj/Znd3d2dmhv9mdnd3dndm9mZ3d3d3Z2b+dnd3d3dmiOh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3dnhu52d3d3ZoaI+GZ3d3d3Zoj/ZnZ3d2dm9v9md3d3d2aG/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles22\": {\n        \"data\": \"hwQQABAAAAB2d3d3d2eI+HZ3d3d2d+judnd3d2dmZu52d3d3d2fm7nZ3d3d3ZujuZnd3d2dmhv5mdnd3dndmhmZ3d3d3Z2b/dnd3d3dmiPh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3dnhu52d3d3ZoaI6GZ3d3d3ZojuZnZ3d2dm5v5md3d3d2aG/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles23\": {\n        \"data\": \"hwQQABAAAAB2d3d3d2eI+HZ3d3d2d+judnd3d2dmZu52d3d3d2fm7nZ3d3d3ZujuZnd3d2dmhv5mdnd3dndmhmZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aG+HZ3d3d3Zmb/dnd3d3Znhv92d3d3Z4aI+GB3Z3dnZogPYHZ3dodm+AAAYGaIZogIAA==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles24\": {\n        \"data\": \"hwQQABAAAAAA4L67u777/+C+u7u7vu7/4Lu7u7vrvv6+u7u7u+6+/ru7u7u7vuvuu7u7u+u+++6+u7u76+7+/u67u7vru+7/vru7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/+7u7u7u+vr/7u7u7u76+7/vru7u7vr6//uu7u7u777/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles25\": {\n        \"data\": \"hwQQABAAAAC+u7u7u777/7u7u7u7vu7/u7u7u7vrvv67u7u7u+6+/ru7u7u7vuvuu7u7u+u+++6+u7u76+7+/u67u7vru+7/vru7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/+7u7u7u+vr/7u7u7u76+7/vru7u7vr6//uu7u7u777/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles26\": {\n        \"data\": \"hwQQABAAAAC+u7u7u777/7u7u7u7vu7/u7u7u7vrvv67u7u7u+6+/ru7u7u7vuvuu7u7u+u+++6+u7u76+7+/u67u7vru+7/vru7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/++u7u7u+vr/+C7u7u76+7/4L67u7vr6/8A4Lu7u777/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles27\": {\n        \"data\": \"hwQQABAAAAAA4L67u/4PAOC+u7u7vu4A4Lu7u7vrvg6+u7u7u+6+/ru7u7u7vuv+u7u7u+u++/6+u7u76+7+/u67u7vru+7/vru7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/+7u7u7u+vr/7u7u7u76+7/vru7u7vr6//uu7u7u777/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles28\": {\n        \"data\": \"hwQQABAAAAC+u7u7u777/7u7u7u7vu7/u7u7u7vrvv67u7u7u+6+/ru7u7u7vuvuu7u7u+u+++6+u7u76+7+/u67u7vru+7/vru7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/+7u7u7u+vr/7u7u7u76+7/vru7u7vr6//uu7u7u777/w==\",\n        \"tilemapTile\": true\n    },\n    \"forestTiles29\": {\n        \"data\": \"hwQQABAAAAC+u7u7u777/7u7u7u7vu7/u7u7u7vrvv67u7u7u+6+/ru7u7u7vuvuu7u7u+u+++6+u7u76+7+/u67u7vru+7/vru7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/++u7u7u+vr/+C7u7u76+4P4L67u7vr6wAA4Lu7u/4PAA==\",\n        \"tilemapTile\": true\n    },\n    \"forestTree0\": \"hwQYACgAAAAAAAAAAAAAAAAAAACACACIAAAAAAAAAAAAAAAAAICIAGiIiIYAAAAAAAAAAAAAAAAAaIiIZohohggAAAAAAAAAAAAAAIBmaGiGiGZmCAAAAAAAAAAAiICIaIZmhoiGZmYIAAAAAAAAgIiGaIZmZmaGaIaGZogAAAAAAABoaIZmiGZmZmiGiIiGZggAAAAAAGhmiIhohmZmZoiGaGaGCAAAAACAZmZohmiIZmaGaIZmZogIAP8AgGhmZmaIiGhmZoZmiGZmZob/7gCIZmZmhmiGiGZmiIiIiGhmiO7+gGZmZmaGZohoZmZmhoiIZobo7u6AZmZmZoaIiGZmZmaIiGZmZuju/wCIZmZmZoiIiGhmiIaIaGZmhu7+AIBoZmZohohoZmaGZoiIZmaG/+4AAIBmZoiIaIhmZmZohmZmhggA/wAAAGhmaIZohmZmhoiIaGaGCAAAAAAAaGiGZohmZmZmiGZohmYIAAAAAACAiIaIiGZmZmiGaGZmiAgAAAAAAAAAiACIaGZmhoiIaGYIAAAAAAAAAAAAAACAaGiGaIZmZggAAAAAAAAAAAAAAACAhmaIZmiGCAAAAAAAAAAAAAAAAACIaAiIiIYAAAAAAAAAAAAAAAAAAACACACACAAAAAA=\",\n    \"forestTree1\": \"hwQYACgAAAAAAAAAAAAAAAAAAACACACIAAAAAAAAAAAAAAAAAICIAGiIiIcAAAAAAAAAAAAAAAAAeGiIZmh4hwgAAAAAAAAAAAAAAIB3ZmiGiHd2CAAAAAAAAAAAiICIeHd2h4iGaHcIAAAAAAAAAICGaIZ2Z3eHaIaId4gAAAAAAABgaIZmiHd3d2aGiHiHZggAAAAAAHZmiIhohnZnZoiGeHaHCAAAAACAd3ZohmiId3eHaIZod4gIAP8AAGhnd2aIiGh3d4ZmiHZndob/7gBmd3dnhmiGiHZniIiIiGh3iO7+YHd3d3eHZohod3dmhoiId4fo7u5gd3d3d4aIiHZ3Z2aIiHZ3Z+ju/wBmd3dnZoiIiGh3iIaIeHdmhu7+AABoZ3dohohod3eHZoiIdmaG/+4AAIB3doiIaIh3d2dohnd3hwgA/wAAAHZmaIZohnZnhoiIeHaHCAAAAAAAYGiGZoh3d3dmiGZ4h2YIAAAAAAAAgIaIiHZnd2aGaGZ3iAgAAAAAAAAAiACIaHd2h4iIaHcIAAAAAAAAAAAAAAAAeGeGaIZ3dggAAAAAAAAAAAAAAACAh2aIZniHCAAAAAAAAAAAAAAAAACIaAiIiIcAAAAAAAAAAAAAAAAAAACACACACAAAAAA=\",\n    \"forestTree2\": \"hwQYACgAAAAAAAAAAAAAAAAAAADwDwD/AAAAAAAAAAAAAAAAAPD/AI////YAAAAAAAAAAAAAAAAAb4//iI9v9g8AAAAAAAAAAAAAAPBmiI/4/2ZoDwAAAAAAAAAA//D/b2Zo9v/4j2YPAAAAAAAAAPD4j/hohmb2j/j/Zv8AAAAAAACAj/iI/2ZmZoj4/2/2iA8AAAAAAGiI//+P+GiGiP/4b2j2DwAAAADwZmiP+I//Zmb2j/iPZv8PAP8AAI+GZoj//49mZviI/2iGaPj/7gCIZmaG+I/4/2iG/////49m/+7+gGZmZmb2iP+PZmaI+P//Zvbv7u6AZmZmZvj//2hmhoj//2hmhu/u/wCIZmaGiP///49m//j/b2aI+O7+AACPhmaP+P+PZmb2iP//aIj4/+4AAPBmaP//j/9mZoaP+GZm9g8A/wAAAGiIj/iP+GiG+P//b2j2DwAAAAAAgI/4iP9mZmaI/4hv9ogPAAAAAAAA8Pj//2iGZoj4j4hm/w8AAAAAAAAA/wD/j2Zo9v//j2YPAAAAAAAAAAAAAAAAaIb4j/hmaA8AAAAAAAAAAAAAAACA9oj/iG/2DwAAAAAAAAAAAAAAAAD/jw////YAAAAAAAAAAAAAAAAAAADwDwDwDwAAAAA=\",\n    \"forestTree3\": \"hwQYACgAAAAAAAAAAAAAAAAAAADwDwD/AAAAAAAAAAAAAAAAAPD/AI////gAAAAAAAAAAAAAAAAAj///iP+P+A8AAAAAAAAAAAAAAPCIj4/4/4iIDwAAAAAAAAAA//D/j/iI+P/4iIgPAAAAAAAA8P/4j/iIiIj4j/j4iP8AAAAAAACPj/iI/4iIiI/4///4iA8AAAAAAI+I//+P+IiIiP/4j4j4DwAAAADwiIiP+I//iIj4j/iIiP8PAP8A8I+IiIj//4+IiPiI/4iIiPj/7gD/iIiI+I/4/4iI/////4+I/+7+8IiIiIj4iP+PiIiI+P//iPjv7u7wiIiIiPj//4iIiIj//4iIiO/u/wD/iIiIiP///4+I//j/j4iI+O7+APCPiIiP+P+PiIj4iP//iIj4/+4AAPCIiP//j/+IiIiP+IiI+A8A/wAAAI+Ij/iP+IiI+P//j4j4DwAAAAAAj4/4iP+IiIiI/4iP+IgPAAAAAADw//j//4iIiI/4j4iI/w8AAAAAAAAA/wD/j4iI+P//j4gPAAAAAAAAAAAAAADwj4/4j/iIiA8AAAAAAAAAAAAAAADw+Ij/iI/4DwAAAAAAAAAAAAAAAAD/jw////gAAAAAAAAAAAAAAAAAAADwDwDwDwAAAAA=\",\n    \"forestTreeGroup0\": \"hwQYACgAAAAAAAAAAAAAAAAAAADwDwD/AAAAAAAAAAAAAAAAAPD/AI////gAAAAAAAAAAAAAAAAAj///iP+P+A8AAAAAAAAAAAAAAPCIj4/4/4iIDwAAAAAAAAAA//D/j/iI+P/4iIgPAAAAAAAA8P/4j/iIiIj4j/j4iP8AAAAAAACPj/iI/4iIiI/4///4iA8AAAAAAI+I//+P+IiIiP/4j4j4DwAAAADwiIiP+I//iIj4j/iIiP8PAP8A8I+IiIj//4+IiPiI/4iIiPj/7gD/iIiI+I/4/4iI/////4+I/+7+8IiIiIj4iP+PiIiI+P//iPjv7u7wiIiIiPj//4iIiIiP+IiIiO/u/wD/iIiIiP///4+I/2iIiIaI+O7+APCPiIiP+P+PaIiIZohohoj4/+4AAPCIiP//j49maGiGiGZm+A8A/wAAAI+IiIiIaIZmhoiGZmb4DwAAAAAAj4iGaIZmZmaGaIaGZogPAAAAAABoaIZmiGZmZmiGiIiGZggAAAAAAGhmiIhohmZmZoiGaGaGCAAAAACAZmZohmiIZmaGaIZmZogIAP8AgGhmZmaIiGhmZoZmiGZmZob/7gCIZmZmhmiGiGZmiIiIiGhmiO7+gGZmZmaGZohoZmZmhoiIZobo7u4=\",\n    \"forestTreeGroup1\": \"hwQYACgAAACAZmZmZoaIiGZmZmaIiGZmZuju/wCIZmZmZoiIiGhmiIaIaGZmhu7+AIBoZmZohohoZmaGZoiIZmaG/+4AAIBmZoiIaIhmZmZohmZmhggA/wAAAGhmaIZohmZmhoiIaGaGCAAAAAAAaGiGZohmZmZmiGZohmYIAAAAAACPiIaIiGZmZmiGaGZmiAgAAAAAAI+IiP+IaGZmhoiIaGb4DwAAAADwiIiP+I+PaGiGaIZmZvgPAP8A8I+IiIj//4+IhmaIZmiGiPj/7gD/iIiI+I/4/4iIaPiIiIaI/+7+8IiIiIj4iP+PiIiI+P+PiPjv7u7wiIiIiPj//4iIiIiP+IiIiO/u/wD/iIiIiP///4+I/2iIiIaI+O7+APCPiIiP+P+PaIiIZohohoj4/+4AAPCIiP//j49maGiGiGZm+A8A/wAAAI+IiIiIaIZmhoiGZmb4DwAAAAAAj4iGaIZmZmaGaIaGZogPAAAAAABoaIZmiGZmZmiGiIiGZggAAAAAAGhmiIhohmZmZoiGaGaGCAAAAACAZmZohmiIZmaGaIZmZogIAP8AgGhmZmaIiGhmZoZmiGZmZob/7gCIZmZmhmiGiGZmiIiIiGhmiO7+gGZmZmaGZohoZmZmhoiIZobo7u4=\",\n    \"forestTreeGroup2\": \"hwQYACgAAACAZmZmZoaIiGZmZmaIiGZmZuju/wCIZmZmZoiIiGhmiIaIaGZmhu7+AIBoZmZohohoZmaGZoiIZmaG/+4AAIBmZoiIaIhmZmZohmZmhggA/wAAAGhmaIZohmZmhoiIaGaGCAAAAAAAaGiGZohmZmZmiGZohmYIAAAAAACPiIaIiGZmZmiGaGZmiAgAAAAAAI+IiP+IaGZmhoiIaGb4DwAAAADwiIiP+I+PaGiGaIZmZvgPAP8A8I+IiIj//4+IhmaIZmiGiPj/7gD/iIiI+I/4/4iIaPiIiIaI/+7+8IiIiIj4iP+PiIiI+P+PiPjv7u7wiIiIiPj//4iIiIj//4iIiO/u/wD/iIiIiP///4+I//j/j4iI+O7+APCPiIiP+P+PiIj4iP//iIj4/+4AAPCIiP//j/+IiIiP+IiI+A8A/wAAAI+Ij/iP+IiI+P//j4j4DwAAAAAAj4/4iP+IiIiI/4iP+IgPAAAAAADw//j//4iIiI/4j4iI/w8AAAAAAAAA/wD/j4iI+P//j4gPAAAAAAAAAAAAAADwj4/4j/iIiA8AAAAAAAAAAAAAAADw+Ij/iI/4DwAAAAAAAAAAAAAAAAD/jw////gAAAAAAAAAAAAAAAAAAADwDwDwDwAAAAA=\",\n    \"forestTreeGroup3\": \"hwQYACgAAAAAAAAAAAAAAAAAAACACACIAAAAAAAAAAAAAAAAAICIAGiIiIYAAAAAAAAAAAAAAAAAaIiIZohohggAAAAAAAAAAAAAAIBmaGiGiGZmCAAAAAAAAAAAiICIaIZmhoiGZmYIAAAAAAAAgIiGaIZmZmaGaIaGZogAAAAAAABoaIZmiGZmZmiGiIiGZggAAAAAAGhmiIhohmZmZoiGaGaGCAAAAACAZmZohmiIZmaGaIZmZogIAP8AgGhmZmaIiGhmZoZmiGZmZob/7gCIZmZmhmiGiGZmiIiIiGhmiO7+gGZmZmaGZohoZmZmhoiIZobo7u6AZmZmZoaIiGZmZmaIiGZmZuju/wCIZmZmZoiIiGhmiIaIaGZmhu7+AIBoZmZohohoZmaGZoiIZmaG/+4AAIBmZoiIaIhmZmZohmZmhggA/wAAAGhmaIZohmZmhoiIaGaGCAAAAAAAaGiGZohmZmZmiGZohmYIAAAAAACPiIaIiGZmZmiGaGZmiAgAAAAAAI+IiP+IaGZmhoiIaGb4DwAAAADwiIiP+I+PaGiGaIZmZvgPAP8A8I+IiIj//4+IhmaIZmiGiPj/7gD/iIiI+I/4/4iIaPiIiIaI/+7+8IiIiIj4iP+PiIiI+P+PiPjv7u4=\",\n    \"forestTreeGroup4\": \"hwQYACgAAADwiIiIiPj//4iIiIiP+IiIiO/u/wD/iIiIiP///4+I/2iIiIaI+O7+APCPiIiP+P+PaIiIZohohoj4/+4AAPCIiP//j49maGiGiGZm+A8A/wAAAI+IiIiIaIZmhoiGZmb4DwAAAAAAj4iGaIZmZmaGaIaGZogPAAAAAABoaIZmiGZmZmiGiIiGZggAAAAAAGhmiIhohmZmZoiGaGaGCAAAAACAZmZohmiIZmaGaIZmZogIAP8AgGhmZmaIiGhmZoZmiGZmZob/7gCIZmZmhmiGiGZmiIiIiGhmiO7+gGZmZmaGZohoZmZmhoiIZobo7u6AZmZmZoaIiGZmZmaIiGZmZuju/wCIZmZmZoiIiGhmiIaIaGZmhu7+AIBoZmZohohoZmaGZoiIZmaG/+4AAIBmZoiIaIhmZmZohmZmhggA/wAAAGhmaIZohmZmhoiIaGaGCAAAAAAAaGiGZohmZmZmiGZohmYIAAAAAACAiIaIiGZmZmiGaGZmiAgAAAAAAAAAiACIaGZmhoiIaGYIAAAAAAAAAAAAAACAaGiGaIZmZggAAAAAAAAAAAAAAACAhmaIZmiGCAAAAAAAAAAAAAAAAACIaAiIiIYAAAAAAAAAAAAAAAAAAACACACACAAAAAA=\",\n    \"furnitureRug\": \"hwQgABgAAAAAu7u7u7u7u7u7uwAwOzs7Ozs7Ozs7OwvTPTs7Ozs7Ozs73QvbPd3d3d3d3d093bsz0z0zMzMzMzPdM7O73TMzMzMzMzPTvbszPTMzMzMzMzMzPbO7PdMzMzPTMzMzvbszPTMzMzMzMzMzPbO7PTMzMzMzMzMzvbszPTMzMzMzMzMzPbO7PTMz0zMzM9MzvbszPTMzMzMzMzMzPbO7PTMzMzMzMzMzvbszPTMzMzMzMzMzPbO7PdMzMzPTMzMzvbszPTMzMzMzMzMzPbO7PTMzMzMzMzMzvbszPTMzMzMzMzMzPbO7PTMz0zMzMzMzvbszPTMzMzMzM9MzPbO7PTMzMzMzMzMzvbszPTMzMzMzMzMzPbO7PdMzMzPTMzMzvbszPTMzMzMzMzMzPbO7PTMzMzMzMzMzvbsz3TMzMzMzMzPTPbO70z0zMzMzMzPds7vTPd3d3d3d3d093bPbPTs7Ozs7Ozs73QswOzs7Ozs7Ozs7OwsAu7u7u7u7u7u7uwA=\",\n    \"furnitureTable1\": \"hwQgABgAAAAAzMzMzMzMzMzMAACwvd293b3dvb27DADcvd293T3dvd27zAzcvd093T3dvd27vMPcPd093T3dvd27vMPc3d3d3d3dvd27zAzc3d3d3d3dvd27DADc3d3d3d3dPd27DADcPd3d3d3dPd27DADcPd093T3dPd27DADc3d293d3dPd27DADcPd293b3dPd27DADc3d093T3dPd27DADc3d093d3dPd27DADc3d3d3d3d3d27DADc3d093d3d3d27DADcPd093d3d3d27DADcPd3d3d3d3d27DADcPd3d3d3dPd27DADcPd093d3dPd27DADc3d093d3dPd27DADc3d3d3T3d3d27DADc3d3d3T3dPd27DADc3d3d3T3d3d27DADcPd093T3d3d27DADc3d093T3d3d27DADcPd093d3d3d27zAzcPd093d3dPd27vMPcPd093d3dPd27vMPcvd293T3dvd27zAywvd293b3dvb27DAAAzMzMzMzMzMzMAAA=\",\n    \"furnitureTable2\": \"hwQgABgAAAAAzMzMzMzMzMwMAACwMzMzMzMzuzvDAAA8MzMzMzMzs7vLzAw8ExERERExM7u7vMM8ETMzMzMRM7vDvMM8MTMzMzMTM7vDzAw8MTMzMzMTM7vDDAA8MTMzMzMTM7u7DAA8MTMzMzMTM7s7DAA8MTMzMzMTM7s7DAA8MTMzMzMTM7u7DAA8MTMzMzMTM7vDDAA8MTMzMzMTM7vDDAA8MTMzMzMTM7vDDAA8MTMzMzMTM7u7DAA8MTMzMzMTM7s7DAA8MTMzMzMTM7s7DAA8MTMzMzMTM7u7DAA8MTMzMzMTM7vDDAA8MTMzMzMTM7vDDAA8MTMzMzMTM7vDDAA8MTMzMzMTM7u7DAA8MTMzMzMTM7s7DAA8MTMzMzMTM7s7DAA8MTMzMzMTM7u7DAA8MTMzMzMTM7vDDAA8MTMzMzMTM7vDzAw8ETMzMzMRM7vDvMM8ExERERExM7u7vMM8MzMzMzMzs7vLzAwAMzMzMzMzuzvDAAAAzMzMzMzMzMwMAAA=\",\n    \"hermitCrabAttack0\": \"hwQYABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8zAwAAPu/wFVUxQDA9V/LRVXFAMBVVVW0VcUAAMw8VUXLxQDAZsZTRUTMAGzMPFVFy8XAxlVVVURVxcDD9V+8u1XFwDP8z8O1VcXAMzNmw1XEDGwzM2MzzEwEPDYzYzOzxMzAPDNjM7NVxQDAM8wzDMvMAADMzMwAAAA=\",\n    \"hermitCrabAttack1\": \"hwQYABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDMDAAAsPsPXFXEAADA9b/MVcUAAMBVVcVVxQAAzMxcxcVMAMBmZjzFTEQAbGbMXMXFTAA8w1VVxVXFADzD9c/LVcUAPDP8P8xVxcA2MzM2XEXMwGMzMzbDzMQAzDMzNjNbxQAAPMM8w7DMAADAzMwMAAA=\",\n    \"hermitCrabAttack2\": \"hwQYABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/M8AAAAAwMz1X8wAAABcxVVVxQwAwFVVzDxVzADAVVXFzFXFAMzFzMw8VcXAxkzEVVVVxcDDxcz1X0zEwMNVVfzPxMzAw1VVxUzEDGwzXFVFVcwMPDbDzMzMxMzAPDMzNsNVxQDAM8M8w8zMAADMzMwMAAA=\",\n    \"hermitCrabAttack3\": \"hwQYABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwz8wAAADAzPxfVcwAAFxVXFVVxQzAVVXFzDxVzMBVVcXMzFXFwMXMzMw8VcXATERcVVVVxcDFzPxfVUzEwFVV9c/MxMzAVVVVzEzEDMBcVVVUVcwMbMPMzMzMxMw8NjNjM8NVxcA8M8wzw8zMAMzMzMwMAAA=\",\n    \"hermitCrabAttack4\": \"hwQYABAAAAAAAAAAAAAAzAAAAAAAAMDFAAAAAAAAW8UAAAAAAABbzAAAAAAAAMvFAAAAAAAAW8UAAAAAwP9bxQAAAABc/1vFAAAAAFxVW8UAAAAAwMxbxQAAAMzMzEXEAADAZszMxcUAAMBmXFXFxQAAbGZc/8XFAAA8Zsb/zMQAADxjZmbDzAAAPDNmNjPMAMA2M2MzwwwAwGMzYzNDzAAAzDNjM1PFAADAM8wzw8wAAADMzMwMAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"hermitCrabAttack5\": \"hwQYABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwAAAAAAADMxQAAAAAAsFXMAAAAAACwy8UAALD7D7BVxQAAwPW/vFXFAADAVVW0VcUAAMzMU7VbxQDAZmY8RUvEAGxmzFxFXMXAZsZVVbRVzMAzxvVfzMUMwDNj/M/DzADAMzNmM8PMAGwzM2Mzw8wAPDYzYzOzxMzAPDNjM7NVxQDAM8wzDMvMAADMzMwAAAA=\",\n    \"hermitCrabAttackLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.hermitCrabAttack0\\\",\\\"sprites.builtin.hermitCrabAttack1\\\",\\\"sprites.builtin.hermitCrabAttack2\\\",\\\"sprites.builtin.hermitCrabAttack3\\\",\\\"sprites.builtin.hermitCrabAttack4\\\",\\\"sprites.builtin.hermitCrabAttack5\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"hermitCrabAttackRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.hermitCrabAttack0\\\",\\\"sprites.builtin.hermitCrabAttack1\\\",\\\"sprites.builtin.hermitCrabAttack2\\\",\\\"sprites.builtin.hermitCrabAttack3\\\",\\\"sprites.builtin.hermitCrabAttack4\\\",\\\"sprites.builtin.hermitCrabAttack5\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"hermitCrabAwaken0\": \"hwQQABAAAAAAAAAAAMwMAAAAAADAY8YAAAAAADzMbAwAAAAAPMzMxgAAAMA8zMzMAAAAbMbDzMwAAMBmZjzGzAAAbGZmxmbMAABsZmZmzMwAADwzZmZmxgAAPDNjZjbDAAA8MzNmM8MAwGYzM2MzwwDAYzMzYzPGAADMMzPMYwwAAADMzMzMAA==\",\n    \"hermitCrabAwaken1\": \"hwQQABAAAAAAAAAAAMDMDAAAAAAAbFzEAAAAAMDDXMUAAAAAwMNMxQAAAMDMw8zMAAAAbGY8zMUAAMBmZsZcxQAAwGZmxlzFAADAY2ZmTMwAAMAzZmbGxgAAwDNjZmPGAABsMzM2Y8YAADw2MzbDDAAAwDwzNsMAAAAAbDNswwAAAADAzMwMAA==\",\n    \"hermitCrabAwaken2\": \"hwQQABAAAAAAAACw/wDMDAAAAFz/y1TFAAAAXFVFVcUAAADMzEVVxQAAwDzMU8TFAABsPMxcRMwAwGbGw1PExQBsZsbMVVTFADxjXFVFVcUAPDNc/8xVxQA8M8P/w8QMwDYzMzYzTATAYzMzNjPLzADMMzM2M1vFAAA8wzzDwMwAAMDMzAwAAA==\",\n    \"hermitCrabAwaken3\": \"hwQQABAAAAAAAAAAwMvMDAD/u7tcRVXFwP9Vu1xUVcXAVVVVRVtVxQDMVVVVtMzFwGbMM1VERMzAzFVVVbTMxcBVVVVFVFXFwP9VzLtbVcUw/8wzXFtVxcAzYzZcRcwMbDMzM8PMRAQ8NjNjM7PEzMA8M2Mzs1XFAMAzzDMMy8wAAMzMzAAAAA==\",\n    \"hermitCrabAwaken4\": \"hwQQABAAAAAAAAAAAMDLDAAAAPwPXFXFAADA9b9cVMUAAMBVVUVbxQAAAMxTVcTFAADAZjxVRMwAAGzMU1XExQDAxlVVRVTFAMDD9c+7W8UAwDP8P1xbxQDAM2M2XMUMAGwzMzbDTAQAPDYzNjPLzADAPDM2M1vFAADAwzzDwMwAAADMzAwAAA==\",\n    \"hermitCrabAwaken5\": \"hwQQABAAAAAAAAAAALzMDAAA+7/AVVTFAMD1X8tFVcUAwFVVVbRVxQAAzDxVRcvFAMBmxlNFRMwAbMw8VUXLxcDGVVVVRFXFwMP1X7y7VcXAM/zPw7VVxcAzM2bDVcQMbDMzYzPMTAQ8NjNjM7PEzMA8M2Mzs1XFAMAzzDMMy8wAAMzMzAAAAA==\",\n    \"hermitCrabAwakenLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.hermitCrabAwaken0\\\",\\\"sprites.builtin.hermitCrabAwaken1\\\",\\\"sprites.builtin.hermitCrabAwaken2\\\",\\\"sprites.builtin.hermitCrabAwaken3\\\",\\\"sprites.builtin.hermitCrabAwaken4\\\",\\\"sprites.builtin.hermitCrabAwaken5\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"hermitCrabAwakenRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.hermitCrabAwaken0\\\",\\\"sprites.builtin.hermitCrabAwaken1\\\",\\\"sprites.builtin.hermitCrabAwaken2\\\",\\\"sprites.builtin.hermitCrabAwaken3\\\",\\\"sprites.builtin.hermitCrabAwaken4\\\",\\\"sprites.builtin.hermitCrabAwaken5\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"hermitCrabWalk0\": \"hwQQABAAAAAAAAAAAAAAAAAA+78AwMwMAMD1X8tcVMUAwFVVVbREzAAAzDxVRcvFAMBmxlNFVcUAbMw8VbRVxcDGVVW1u1XFwMP1X8xVxMzAM/zPw8VMBMAzM2YzzEQEbDMzYzOzRAQ8NjNjM7PEDMA8M2Mzs1UMAMAzzDMMywwAAMzMzAAAAA==\",\n    \"hermitCrabWalk1\": \"hwQQABAAAAAAALD7DwAAAAAAwPW/zMwAAADAVVVFxQAAAMDMXFVbDAAAbGY8VUTMAMBmzFxFxMUAbMZVVURbxQBsw/XPvFvFADwz/D9cVcUAPDNjNlzMzMA2MzM2w8sMwGMzMzYzWwwAzDMzNjPMDAAAPMM8wwAAAADAzMwMAAAAAAAAAAAAAA==\",\n    \"hermitCrabWalk2\": \"hwQQABAAAAAAAAAAAAAAAAAAsPsPwMwAAADA9b9MVQwAAMBVVUVVDAAAwMxcVVvMAABsZjxVRMwAwGbMXEVExABsxlVVRUTMAGzD9c+7y8UAPDP8z7VVxQA8M2PGVVXFwDYzMzbMVcXAYzMzNjPLzADMMzM2M7zMAAA8wzzDAAAAAMDMzAwAAA==\",\n    \"hermitCrabWalk3\": \"hwQQABAAAAAAAAAAALzMDAAA+7/AVVTFAMD1X8tFVcUAwFVVVbRVxQAAzDxVRcvFAMBmxlNFRMwAbMw8VUTExMDGVVVFzFwMwMP1X8xVVQzAM/zPw1VVDMAzM2YzXFUMbDMzYzOzzAw8NjNjM8PLzMA8M2Mzw1vFAMAzzDMMsMwAAMzMzAAAAA==\",\n    \"hermitCrabWalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.hermitCrabWalk0\\\",\\\"sprites.builtin.hermitCrabWalk1\\\",\\\"sprites.builtin.hermitCrabWalk2\\\",\\\"sprites.builtin.hermitCrabWalk3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"hermitCrabWalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.hermitCrabWalk0\\\",\\\"sprites.builtin.hermitCrabWalk1\\\",\\\"sprites.builtin.hermitCrabWalk2\\\",\\\"sprites.builtin.hermitCrabWalk3\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"largeOceanRock\": \"hwQYAA4AAAAAAAC7zMwAAAAAu93du8wAALDd3d29ywAA29273b3LALDbvTPd3bsAsN29M93duwA8szsz2727ADwzMzM7M7sAvD0zMzMzvAC80zMzM8u7ALw7MzPDu7sAwDMzM7y7ywDAM9MzvLvMADAzzD2zy8wAAMC7O7PdywAAAMzM2929AAAAAMDd3b0AAAAAwN3dvQAAAACw3d28AAAAAADbzbsAAAAAAMy8ywAAAAAAwLzMAAAAAAAAzMwAAAAAAADAzAA=\",\n    \"largeShelf\": \"hwQYABgAAADAzMzMzMz///////+83d29zLvb3d3d3f3c3d3d+8zM/MzMzP/c3d3d+8zM+8zMu//c3d3d+zPD+8zMu//c3d3d+zPD/WbG3f/c3d3d+8zM/czM3f/c3d3d+2bG/TPD3f/c3d3d+8zM/TPD3f/c3d3d+0TE/czM3f/c3d3d+0TE/UTM3f/c3d3d+8zM/czM3f/c3d3d+zPM/WbG3f/c3d3d+8zM/czM3f/c3d3d+3fH/UTE3f/c3d3d+8zM/UTE3f/c3d3d+2bG/czM3f/c3d3d+2bG/TPM3f/c3d3d+8zM/czM3f/c3d3d+zPD+3fHu//c3d3d+8zM+8zMu//c3d3d+8zM/MzMzP+83d29zLvb3d3d3f3AzMzMzMz///////8=\",\n    \"mediumOceanRock\": \"hwQQABAAAAAAAAAAAMDMzAAAAADMvMzMAAAAzL28y8wAAMzM28vLzADAu83cy8zMANu927zLzMyw3d3bu8u8zLDd3du7zLzL293d3My7vLvb3d3MzLy9u9vdvczdu727293N3N29zbu73cvc3b3NvLDMzNzdzc3MAADMzN3Ly8wAAADAzMzMzA==\",\n    \"oceanDepths0\": {\n        \"data\": \"hwQQABAAAADAvLu7u8vMAMy7u7u7y8wMvLu7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/7u7u7u7y8v8vLu7u7vM+//Mu7u7y7z8/w==\",\n        \"tilemapTile\": true\n    },\n    \"oceanDepths1\": {\n        \"data\": \"hwQQABAAAAC8u7u7u8vM/7u7u7u7y8z8u7u7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/7u7u7u7y8v8vLu7u7vM+//Mu7u7y7z8/w==\",\n        \"tilemapTile\": true\n    },\n    \"oceanDepths2\": {\n        \"data\": \"hwQQABAAAAC8u7u7u8vM/7u7u7u7y8z8u7u7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/Ly7u7u7y8v8zLu7u7vM+w/AvLu7y7z8AA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanDepths3\": {\n        \"data\": \"hwQQABAAAADAvLu7u8vMAMy7u7u7y8wMvLu7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/Ly7u7u7y8v8zLu7u7vM+w/MvLu7y7z8AA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanDepths4\": {\n        \"data\": \"hwQQABAAAADAvLu7u8vM/8y7u7u7y8z8vLu7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/7u7u7u7y8v8vLu7u7vM+//Mu7u7y7z8/w==\",\n        \"tilemapTile\": true\n    },\n    \"oceanDepths5\": {\n        \"data\": \"hwQQABAAAAC8u7u7u8vM/7u7u7u7y8z8u7u7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/7u7u7u7y8v8vLu7u7vM+//Mu7u7y7z8/w==\",\n        \"tilemapTile\": true\n    },\n    \"oceanDepths6\": {\n        \"data\": \"hwQQABAAAAC8u7u7u8vM/7u7u7u7y8z8u7u7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/Ly7u7u7y8v8zLu7u7vM+//AvLu7y7z8/w==\",\n        \"tilemapTile\": true\n    },\n    \"oceanDepths7\": {\n        \"data\": \"hwQQABAAAADAvLu7u8vM/8y7u7u7y8z8vLu7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/Ly7u7u7y8v8zLu7u7vM+//AvLu7y7z8/w==\",\n        \"tilemapTile\": true\n    },\n    \"oceanDepths8\": {\n        \"data\": \"hwQQABAAAAD/////AAAAAP////8PAAAA//////8AAAD//////w8AAP//////DwAA//////8PAAD//////w8AAP//////DwAA////////AAD/////////AP////////8P/////////w///////////////////////////////////////////w==\",\n        \"tilemapTile\": true\n    },\n    \"oceanDepths9\": {\n        \"data\": \"hwQQABAAAAD/////////////////////////////////////////D/////////8P/////////w//////////AP////////8A/////////wD/////////AP////////8A/////////w///////////////////////////////////////////w==\",\n        \"tilemapTile\": true\n    },\n    \"oceanDepths10\": {\n        \"data\": \"hwQQABAAAAD/////////////////////////////////////////D/////////8P/////////w//////////D/////////8A////////DwD///////8AAP//////DwAA//////8PAAD//////w8AAP//////AAAA/////w8AAAD/////AAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanDepths11\": {\n        \"data\": \"hwQQABAAAAD/////AAAAAP//////AAAA//////8PAAD///////8AAP///////w8A////////DwD///////8PAP///////w8A////////DwD///////8PAP///////w8A////////DwD///////8AAP//////DwAA//////8AAAD/////AAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand0\": {\n        \"data\": \"hwQQABAAAAAAMLO7y8zMAAAz3d0zM7sMMNPdPT3Du8yw3d09M8O7y9vd3T07w7vL293d3TM9vMw73d3TPTPDzDvd3d29083MM93dPT3TvczT3R3dMzO7y9Pd3T09w7vL293dPTPDu8uw3d09O8O7zDDT3d0zPbzMADPd0z0zwwwAMLu7y8zMAA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand1\": {\n        \"data\": \"hwQQABAAAAAAMLO7y8zMAAAz3dPLvMsMMNPdM8O7u8yw3d2zw7u7zDvd3T09vMvMO9093TPDy8w73d3d283LzDPd0dPTvbvM093d3TO8u8vT3d09Pby7y9Pd3d0zw7vM293d3bPDy8zb3d3dMz3MzDvd3dM9M8PMO93d3b3Tzcwz3d09PdO9zA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand2\": {\n        \"data\": \"hwQQABAAAADT3R3dMzO7y9Pd3T09w7vL093dPTPDu8vb3d09O8O7zNvd3d0zPbzMO93d0z0zw8w73d3dvdPNzDPdHT09083M093d3TMzu8zT3d09PcO7zNPd3T0zw7vL293dPTvDu8vb3d3dMz28zDvd3dM9M8PMO93d3b3Tzcwz3d09PdO9zA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand3\": {\n        \"data\": \"hwQQABAAAADT3R3dMzO7y9Pd3T09w7vL093dPTPDu8vb3d09O8O7zNvd3d3TPczMO93dPd0zw8w73d3d3dvNzDPd3d3T083M093d0T0zu8zT3d3d07O7zNPd3bPDu7vLO93d08O7u8uw3d093by7yzDT3b3dvLvMADPdMzPMywwAMLu7y8zMAA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand4\": {\n        \"data\": \"hwQQABAAAAAAMLO7y8zMzAAz3d0zM7u7MNPdPT3Du7uw3d09M8O7u9vd3T07w7u7293d3TM9vLs73d3TPTPDuzvd3d290827M93dPT3TvbvT3R3dMzO7u9Pd3T09w7u7293dPTPDu7uw3d09O8O7uzDT3d0zPby7ADPd0z0zw7sAMLu7y8zMuw==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand5\": {\n        \"data\": \"hwQQABAAAAAAMLO7y8zMzAAz3dPLvLu7MNPdM8O7u7uw3d2zw7u7uzvd3T09vLu7O9093TPDu7s73d3d2827uzPd0dPTvbu7093d3TOzu7vT3d09Pby7u9Pd3d0zw7u7293d3bPDu7vb3d3dMz28uzvd3dM9M8O7O93d3b3Tzbsz3d09PdO9uw==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand6\": {\n        \"data\": \"hwQQABAAAADT3R3dMzO7u9Pd3T09w7u7093dPTPDu7vb3d09O8O7u9vd3d0zPby7O93d0z0zw7s73d3dvdPNuzPdHT090727093d3TMzu7vT3d09PcO7u9Pd3T0zw7u7293dPTvDu7vb3d3dMz28uzvd3dM9M8O7O93d3b3Tzbsz3d09PdO9uw==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand7\": {\n        \"data\": \"hwQQABAAAADT3R3dMzO7u9Pd3T09w7u7093dPTPDu7vb3d09O8O7u9vd3d3TPby7O93dPd0zw7s73d3d3dvNuzPd3d3T0727093d0T0zu7vT3d3d07O7u9Pd3bPDu7u7O93d08O7u7uw3d093by7uzDT3b3dvLu7ADPdMzPMu7sAMLu7y8zMzA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand8\": {\n        \"data\": \"hwQQABAAAADMvMvMzMzMzMvMu8zMzMzMu8zMzMzMzMy8y8zMzMzMzMzLzMzMzMzMzMzLzMzMzMzLzLvMzMzMzLvMvMzMzMzMvMzMzMzMzMzMzMzMzMzMzMvLzLzMzMzMu7vMu8zMzMy7u8zLzMzMzLu8zMzMzMzMy7zMzMzMzMzMy8zMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand9\": {\n        \"data\": \"hwQQABAAAADMvMvMzMzMzMvMu8zMzMzMu8zMzMzMzMy8y8zMzMzMzMzLzMzMzMzMzMzLzMzMzMzLzLvMzMzMzLvMvMzMzMzMvMzMzMzMzMzMzMzMzMzMzMvLzLzMzMzMu7vMu8zMzMy7u8zLzMzMzLu8zMzMzMzMy7zMzMzMzMzMy8zMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand10\": {\n        \"data\": \"hwQQABAAAAC7vMvMzMzMzLvMu8zMzMzMu8zMzMzMzMy8y8zMzMzMzMzLzMzMzMzMzMzLzMzMzMzLzLvMzMzMzLvMvMzMzMzMvMzMzMzMzMzMzMzMzMzMzMvLzLzMzMzMu7vMu8zMzMy7u8zLzMzMzLu8zMzMzMzMy7zMzMzMzMzMy8zMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand11\": {\n        \"data\": \"hwQQABAAAAC7vMvMzMzMzLvMu8zMzMzMu8zMzMzMzMy8y8zMzMzMzMzLzMzMzMzMzMzLzMzMzMzLzLvMzMzMzLvMvMzMzMzMvMzMzMzMzMzMzMzMzMzMzMvLzLzMzMzMu7vMu8zMzMy7u8zLzMzMzLu8zMzMzMzMy8zMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand12\": {\n        \"data\": \"hwQQABAAAADMAAAAAAAAAMzMAAAAAAAAzMwMAAAAAADMzMwAAAAAAMzMzAwAAAAAzMzMDAAAAADMzMzMAAAAAMzMzMwAAAAAzMzMzAAAAADMzMzMAAAAAMzMzMwAAAAAzMzMDAAAAADMzMwAAAAAAMzMDAAAAAAAzAwAAAAAAADMAAAAAAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand13\": {\n        \"data\": \"hwQQABAAAADMzMzMAAAAAMzMzMwMAAAAzMzMzMwAAADMzMzMzAwAAMzMzMzMDAAAzMzMzMwMAADMzMzMzAwAAMzMzMzMDAAAzMzMzMzMAADMzMzMzMzMAMzMzMzMzMwMzMzMzMzMzAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand14\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMDMzMzMzMzMwMzMzMzMzMzAzMzMzMzMzMAMzMzMzMzMwAzMzMzMzMzADMzMzMzMzMAMzMzMzMzMwAzMzMzMzMzAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"oceanSand15\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMDMzMzMzMzMwMzMzMzMzMzAzMzMzMzMzMDMzMzMzMzMwAzMzMzMzMDADMzMzMzMwAAMzMzMzMDAAAzMzMzMwMAADMzMzMzAwAAMzMzMzMAAAAzMzMzAwAAADMzMzMAAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"pedestal\": \"hwQgACAAAAAAAAAAsMzMDAAAAAAAAAAAAAAAALsREcsAAAAAAAAAAAAAsMwcsRuxDAAAAADAzMwAANsRHLu7EQwAAAAAvBGxALDdERzbuxEMAAAAwNsRsQDb3REc3N0RDADAzMzdEbGw3d0RHLzdzQAAvB3N3RGx293dEdzBy8zMzLwb0dsRsdvd3RHcsd27u7u7uxHbEbHb3d0RHB3b3d3d3b0R2xGx293dERwdvdG7u7u7G7ERsdvd3RHc0bERu93d3RuxEbHb3d0RvNHRGxEREREbsRGx293dEbwdHRvb3d3dG7ERsdvd3RG8Gx0bu93d3RuxEbHb3d0RvBsdGxEREREbsRGx293dEbwbHRsRERERG7ERsdvd3RG8Gx0bu93d3RuxEbHb3d0RvB0dG9vd3d0bsRGx293dEbzR0RsRERERG7ERsdvd3RHc0bERu93d3RuxEbHb3d0RHB290bu7u7sbsRGx293dERwd293d3d29EdsRsdvd3RHcsd27u7u7uxHbEbHb3d0R3MHLzMzMvBvR2xGxsN3dERy83c0AALwdzd0RsQDb3REc3N0RDADAzMzdEbEAsN0RHNu7EQwAAADA2xGxAADbERy7uxEMAAAAALwRsQAAsMwcsRuxDAAAAADAzMwAAAAAuxERywAAAAAAAAAAAAAAALDMzAwAAAAAAAAAAA==\",\n    \"seaweed0\": \"hwQQADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGaIiAAAAAAAAAAAAAAAAAAAAAAAiAAAYFV3dwgAAAAAAAAAAAAAAAAAAAAAaAgAVmdmdocAAAAAAAAAAAAAAAAAAAAAgIaIZ1d3Z3YAAAAAAAAAAAAAAAAAAAAAAGhmdmWId2cAAAAAAAAAAAAAAAAAAAAAAIB2VYhoZogAAAAAAAAAAAAAAAAAAAAAAABghmZmhgAAAAAAAAAAAAAAAAAAAAAAAAAAAIiICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"seaweed1\": \"hwQQADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAiHd3iAAAAAAAAAAAAAAAAAAAAAAAAACAZmZmdwgAAAAAAAAAAAAAAIiIiAAAAABohoh2docAAAAAAAAAAAAAiFd1d4gAAIBmCABoZ2cAAAAAAAAAAACAd3dVZncIAICIAIiIZ3YAAAAAAAAAAAB4d4iId2aHAAAAgIiIdmYAAAAAAAAAAIBmiAAAiHdmCAAAaIiIeHcAAAAAAAAAAICGAAAAAGhmhoiIhohohnYAAAAAAAAAAGgIAAAAAICIaGZmiIZmiIgAAAAAAAAAAGgIAAAAAGh3Z2hmZniHZogAAAAAAAAAAIgAAAAAgHdndmWIaHd2hgAAAAAAAAAAAAAAAAAAeIZoZ1d1d2Z3CAAAAAAAAAAAAAAAAACAhwgAeHVmZneHAAAAAAAAAAAAAAAAAACACAAAgFZ1d4cIAAAAAAAAAAAAAAAAAAAAAAAAAGCGiAgAAAA=\",\n    \"seaweed2\": \"hwQQADAAAAAAAAAAAAAAAAAAAAAAgIiIiIgAAAAAAAAAAAAAAAAAAAAAAABoaGZmd3eGCAAAAAAAAAAAAAAAAAAAAGh3hoiIaGZ3hwgAAAAAAAAAAAAAAAAAgHeGaGZ2d2dmd4YAAACIAAAAAAAAAABgdmZmZoiIaHdnZncIAABoCAAAAAAAAABWZXeGiAAAiGh3ZnaHAACAhgAAAAAAAGZVdocIAACId2Z4d2Z3CAAAaIgAAACAaHdmVQYAAIh3ZmaGdmd2hwAAgGaIiIhod2ZVZgAAgHdmh4hmaHdmd4gAAIhmZnZ3d3dmAAAAeGZnCABoiHhnZncAAACIZmZmhmYAAACIZ2cIgAaAiIh3Z2YAAAAAiIiICAAAAIhohggAgGcAiHhmd4cAAAAAAAAAAAAAAAAAAAAAAHhmVWeIZoYAAAAAAAAAAAAAAAAAAAAAAIB3ZohmZggAAAAAAAAAAAAAAAAAAAAAAAB4V3VmiAAAAAAAAAAAAAAAAAAAAAAAAACAaGaIAAA=\",\n    \"shark0\": \"hwQgABAAAAAAAADw/wAAAAAAAPC7DwAAAAAAv7z7AAAAAPC7u8EPAAAA8LsbwfwAAAC/uxvBwQAAAL+7ETPDAAAAv7sRE8wAAAC/+x/MEQwAAL/7HxwRDAD8vLsREREMwMy8vBsR/AzAzczLvLu7D9y9vLy7u9v83Lu8y7u7u/2/y7y7u8u/+8//v7u7zMz7/wDPu8vMzfwAAPDMzMzdDAAA8MzMzM0AAADwzMy8zQAAAADPzNwMAAAAAM/MvAwAAAAA8M/8AAAAAADMv/wAAAAAwN27vA8AAADAu8u8+wAAALy7/8+7DwAAvPwA8L8PAADMAAAA8A8AAAAAAAAAAAAAAAAAAAAA\",\n    \"shark1\": \"hwQgABAAAAAAAAD/DwAAAAAAAL/7AAAAAADwy7sPAAAAAPC7G/wAAAAAv7sRzA8AAAC/uxEc8wAAAL+7ETPzAAAAv7sRExwMAAC/+x/MEQwAAL/7HxwRDADwvLsREREMAMy8vLsR/AzAzbzLvLu7D9y9vLy7u9v73Lu8y7y7u/2/y7y7u8u/+7//v7u7zP37/wDPu8vM3f8AAPDMzMzdDAAA8MzMzM0AAADwzMy8zQAAAADPzNwMAAAAAM/MvAwAAAAA8MzMAAAAAADwzA8AAAAAAPzLDwAAAADA3bsPAAAAANy9y/sAAAAAvLvMuw8AAMC7+/+8+wAAwMsPAP/7AADADAAAAP8A\",\n    \"shark2\": \"hwQgABAAAAAAAAD/DwAAAAAA8Lz7AAAAAADwy7sPAAAAAM+7EfwAAAAAv7sRzA8AAAC/uxEc8wAAAL+7ETPzAAAAv/sfExwMAAC/+x/MEQwAAL+7GxsRDADwvLsbEREMAMy8vLsR/AzAy7zLvLvbD8C9vLvLu7v93L28y7y7vPvfy7y7u8vM+7//v7u7zM37/w/Pu8vM3f8AAPDMzMzdDAAA8MzMzL0MAADwzMy8zQAAAADPzNzLAAAAAM/MvAwAAAAA8MzPAAAAAAD8yw8AAAAAzN27DwAAAMDdy7z7AAAAvLv/z7sPAAC8/ADwvw8AAMwAAADwDwAAAAAAAAAAAAAAAAAAAAAA\",\n    \"shark3\": \"hwQgABAAAAAAAAD/DwAAAAAAAL/7AAAAAADwy7sPAAAAAPC7G/wAAAAAv7sRzA8AAAC/uxEc8wAAAL+7ETPzAAAAv7sRExwMAAC/+x/MEQwAAL/7HxwRDADwvLsREREMAMy8vLsR/AzAzbzLvLu7D9y9vLy7u9v73Lu8y7y7u/2/y7y7u8u/+7//v7u7zP37/wDPu8vM3f8AAPDMzMzdDAAA8MzMzM0AAADwzMy8zQAAAADPzNwMAAAAAM/MvAwAAAAA8MzMAAAAAADwzA8AAAAAAPzLDwAAAADA3bsPAAAAANy9y/sAAAAAvLvMuw8AAMC7+/+8+wAAwMsPAP/7AADADAAAAP8A\",\n    \"sharkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.shark0\\\",\\\"sprites.builtin.shark1\\\",\\\"sprites.builtin.shark2\\\",\\\"sprites.builtin.shark3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"sharkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.shark0\\\",\\\"sprites.builtin.shark1\\\",\\\"sprites.builtin.shark2\\\",\\\"sprites.builtin.shark3\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"sharkAttack0\": \"hwQkABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8PAAAAAAAAv/sAAAAAAPDLuw8AAAAA8Lsb/AAAAAC/uxHMDwAAAL+7ERzzAAAAv7sRM/MAAAC/uxETHAwAAL/7H8wRDAAAv/sfHBEMAPC8uxEREQwAzLy8uxH8DMDNvMu8u7sP3L28vLu72/vcu7zLvLu7/b/LvLu7y7/7v/+/u7vM/fv/AM+7y8zd/wAA8MzMzN0MAADwzMzMzQAAAPDMzLzNAAAAAM/M3AwAAAAAz8y8DAAAAADwzMwAAAAAAPDMDwAAAAAA/MsPAAAAAMDduw8AAAAA3L3L+wAAAAC8u8y7DwAAwLv7/7z7AADAyw8A//sAAMAMAAAA/wA=\",\n    \"sharkAttack1\": \"hwQkABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwuw8AAAAAAL+8+wAAAAAAv7vBDwAAAAC/G8H8AAAA8LsbwTEPAADwuxsxMw8AAPC7GzHBwQAA8Lv/wRzBAADwu/8RHMEAAPC7uxEREQwAzLu8uxH8DMDNu8u8u7sP3L28vLu72/vcu7zLvLu7/b/LvLu7y7/7v/+/u7vM/fv/AM+7y8zd/wAA8MzMzN0MAADwzMzMzQAAAPDMzLzNAAAAAM/M3AwAAAAAz8y8DAAAAADwzMwAAAAAAPDMDwAAAAAAwMsPAAAAAADcvfsAAAAAwN27vA8AAADAu8u8+wAAAMC7/8+7DwAAwMsA8L8PAADADAAA8A8=\",\n    \"sharkAttack2\": \"hwQkABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw/wAAAAAAAL+7/wAAAAAAvxvB/wAAAAC/HMwRDwAAAL8RHBHBAAAAvxEzEREMAAC/ERMREQwAAL8bwRERwQAAv/8RERHxAAC//7sbwfwAwP27u7u7uw/czbu8u7vb+9y7vMu8u7v9v8u8vLvLv/u//7/LvMz9+/8Az7vLzN3/AADPzMzM3QwAAM/MzMzdDAAA8MzMvM0AAADwzMzczQAAAADPzLwMAAAAAPDMzwAAAAAAwMsPAAAAAADcvfsAAAAAwN27vA8AAADAu8u8+wAAAMC7/8+7DwAAwMsA8L8PAADADAAA8A8=\",\n    \"sharkAttack3\": \"hwQkABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAPC7Gw8AzAAA8LvBDMwcDADwG8HBMxEMAPAbwTwzE8EA8BvBMRMcwQDwuxE8zBHBAPD7HxEREfEA8Pu/uxvB/ADwu7u7u7u7D8C/y7u7u9v7vL+7zLu7u/28v8u7u8u/+7/7u8y7zP37v//Mu8vM3f//AM/MzMzdDAAAz8zMzN0MAADwzMy8zQAAAADPzLwMAAAAAPDMzwAAAAAAwMsPAAAAAADAvfsPAAAAANy9zPsAAAAA3MvMuw8AAAC8zP+8+wAAALwMAP/7AAAAzAAAAP8=\",\n    \"sharkAttack4\": \"hwQkABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPD//wAAAAAAv7vxDwDMDAC/G8zMzMzBAL8RHDwzE8EAvxHMMzMzEQy/ERwzM8ERDL8bwcPMHBEMv/sfEREREQ/w+7+7G8H8D/C7u7u7u7sPwLvLu7u72/u8v7vMu7u7/by/y7u7y7/7v/u7zLvM/fu//8y7y8zd//8Az8zMzN0MAADPzMzM3QwAAPDMzLzNAAAAAM/MvAwAAAAA8MzPAAAAAADAvfsPAAAAANy9zPsAAAAA3MvMuw8AAAC8zP+8+wAAALwMAP/7AAAAzAAAAP8=\",\n    \"sharkAttack5\": \"hwQkABAAAAAAAAAAAAAAAAAAAADw/wAAAAAAAL/7DwAAAADwy7sPAAAAAPC7u8EAAAAAv7sbwQAAAAC/uxvBAAAA8Lu7G8EAAADwu7sbwQwAAPC7u//BDAAA8Lu7/8EMAADwu7v/EQwAAPC7u7sRDAAAwMu8uxsMAADcu8vMuw8AwN3Lu7vb+wDAvbvMu7v9APC7u7u7vPsA8Lu7u7u8+wDw+7u7y/z7APAPvLvM3P8AAADPzMzcDAAAAM/MzLwMAAAAz8zMywAAAADwzMzLAAAAAPDMzMsAAAAAAM+8DAAAAAAAz8wMAAAAAADP/AAAAAAAALz8AAAAAADA3bsPAAAAANy9y/sAAAAAvLvM+wAAAAC8+/+8DwAAALwMAL8PAAAAzAAA8A8=\",\n    \"sharkAttackLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.sharkAttack0\\\",\\\"sprites.builtin.sharkAttack1\\\",\\\"sprites.builtin.sharkAttack2\\\",\\\"sprites.builtin.sharkAttack3\\\",\\\"sprites.builtin.sharkAttack4\\\",\\\"sprites.builtin.sharkAttack5\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"sharkAttackRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.sharkAttack0\\\",\\\"sprites.builtin.sharkAttack1\\\",\\\"sprites.builtin.sharkAttack2\\\",\\\"sprites.builtin.sharkAttack3\\\",\\\"sprites.builtin.sharkAttack4\\\",\\\"sprites.builtin.sharkAttack5\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"smallOceanRock\": \"hwQIAAgAAAAAzMzMwLvLzLy9vbzc3du73N29zdzdvc3A3bvLAMzMzA==\",\n    \"smallShelf0\": \"hwQQABgAAADAzMzMzMz///////+83d3dvbu7u7u7u/vc3d3du83MvM3MvP/c3d3du727vL27vP/c3d3du727vL27vP/c3d3du727vL27vP/c3d3du828vM28vP/c3d3du73NvL3NvP/c3d3du73NvL3NvP/c3d3du828vM28vP/c3d3du727vL27vP/c3d3du727vL27vP/c3d3du727vL27vP/c3d3du83MvM3MvP+83d3dvbu7u7u7u/vAzMzMzMz///////8=\",\n    \"smallShelf1\": \"hwQQABgAAADAzMzMzMz///////+8d3d3Z2ZmZmZmZvZ8d3d3ZsfMbMfMbP98d3d3ZmdmbGdmbP98d3d3ZmdmbGdmbP98d3d3ZmdmbGdmbP98d3d3ZsdsbMdsbP98d3d3ZmfNbGfNbP98d3d3ZmfNbGfNbP98d3d3ZsdsbMdsbP98d3d3ZmdmbGdmbP98d3d3ZmdmbGdmbP98d3d3ZmdmbGdmbP98d3d3ZsfMbMfMbP+8d3d3Z2ZmZmZmZvbAzMzMzMz///////8=\",\n    \"smallShelf2\": \"hwQQABgAAADAzMzMzMz///////+83d29zLvb3d3d3f3c3d3d+8zM/MzMzP/c3d3d+0TE+8zMu//c3d3d+0TE+0TMu//c3d3d+8zM/czM3f/c3d3d+3fH/UTE3f/c3d3d+8zM/UTE3f/c3d3d+2bG/czM3f/c3d3d+2bG/TPM3f/c3d3d+8zM/czM3f/c3d3d+zPD+3fHu//c3d3d+8zM+8zMu//c3d3d+8zM/MzMzP+83d29zLvb3d3d3f3AzMzMzMz///////8=\",\n    \"tv\": \"hwQQABYAAAAAAAAAAADw/////wAAu7u7u7vMu7u7+wCwEd3d3d3Ly8y8/wAbEc3MzNzL27u8/wAbEWxmZsbL27u8/wAbEWzRZsbL27u8/wAbEWxtZsbL27u8/wAbEWxmZsbL27u8/wAbEWxmZsbL27u8/wAbEWxmZsbL27u8/wAbEWxmZsbL27u8/wAbEWxmZsbL27u8/wAbEc3MzNzL27u8/wCwEd3d3d3L28y8/wAAu7u7u7vMu7u7+wAAAAAAAADw/////wA=\",\n    \"villager1WalkFront1\": \"hwQOABAAAADw/wAAAAAAAP////8P4EQA///D//9OTQD/z8P89P//APA7zLzRvmP/z8zM9N80Y//PzExE3TRjD8/MTETdNGMPz8zM9N80Y//wO8y80b5j///Pw/z0//wA///D//9OTQD/////D+BEAPD/AAAAAAAA\",\n    \"villager1WalkFront2\": \"hwQOABAAAAAA/w8AAAAAAPD/////8A4A8P8//P/vBADw/zzMT////wC/w8wb/Wv/8MzMTP+9Y//wzMxE1L1jD/DMzETUvWMP8MzMTP/t/g8Av8PMG9TtD/D/PMxP3u0A8P8//P9PDgDw/////+4AAAD/DwAAAAAA\",\n    \"villager1WalkFront3\": \"hwQOABAAAAAA/w8AAAAAAPD/////7gAA8P8//P9PDgDw/zzMT97tAAC/w8wb1O0P8MzMTP/t/g/wzMxE1L1jD/DMzETUvWMP8MzMTP+9a/8Av8PMG/1u//D/PMxP////8P8//P/vBADw//////AOAAD/DwAAAAAA\",\n    \"villager1WalkBack1\": \"hwQOABAAAADw/wAAAAAAAP////8P4EQA///D//9OTQD/z8P8////APA7zMz//2P/z8zMzP//Y//PzMzM//9jD8/MzMz//2MPz8zMzP//Y//wO8zM//9j///Pw/z///wA///D//9OTQD/////D+BEAPD/AAAAAAAA\",\n    \"villager1WalkBack2\": \"hwQOABAAAAAA/w8AAAAAAPD/////AAAA8P8//P/vTg7w/zzM/P///wC/w8z8/z//8MzMzPz/P//wzMzM/P8/D/DMzMz8/z8P8MzMzPz/Pw8Av8PM///vDvD/PMz//98O8P8////v1ATw/////wBOAAD/DwAAAAAA\",\n    \"villager1WalkBack3\": \"hwQOABAAAAAA/w8AAAAAAPD/////AE4A8P8////v1ATw/zzM///fDgC/w8z//+8O8MzMzPz/Pw/wzMzM/P8/D/DMzMz8/z8P8MzMzPz/P/8Av8PM/P8///D/PMz8////8P8//P/vTg7w/////wAAAAD/DwAAAAAA\",\n    \"villager1WalkLeft1\": \"hwQOABAAAAAAAAAAAAAAAAAA//8AAAAAAP/M/w8AAADwzMzu////AP/MTETdPmMPz8zMRN00Yw/PzMz83zRj/8/MzLzR5P7/z8zM/ETe7f/wO8xP/d7tD//P80/0T/4A///z//8AAAD/////AAAAAPD/AAAAAAAA\",\n    \"villager1WalkLeft2\": \"hwQOABAAAAAAAAAAAAAAAAAA8P8PAAAAAPDP/P8A8A8Az8zM//////DPzETU7WP/8MzMTNRNY//wzMzM/+3+D/DMzMwb3u0P8MzMzE/e7Q8Av8P81E/+//D/PP9E////8P8///8P8A/w////DwAAAAD/DwAAAAAA\",\n    \"villager1WalkLeft3\": \"hwQOABAAAAAAAAAAAAAAAAAA8P8PAAAAAPDP/P8A8A8Az8zMz/////DPzETU7WP/8MzMTNRNY//wzMzM/01jD/DMzMwbTWMP8MzMzE/k/g8Av8P81N/t//D/PP9E3+3/8P8///9P/g/w/////wAAAAD/DwAAAAAA\",\n    \"villager1WalkRight1\": \"hwQOABAAAAAA/w8AAAAAAPD/////AAAA8P8///9P/g/w/zz/RN/t/wC/w/zU3+3/8MzMzE/k/g/wzMzMG01jD/DMzMz/TWMP8MzMTNRNY//wz8xE1O1j/wDPzMzP////APDP/P8A8A8AAPD/DwAAAAAAAAAAAAAA\",\n    \"villager1WalkRight2\": \"hwQOABAAAAAA/w8AAAAAAPD///8PAAAA8P8///8P8A/w/zz/RP///wC/w/zUT/7/8MzMzE/e7Q/wzMzMG97tD/DMzMz/7f4P8MzMTNRNY//wz8xE1O1j/wDPzMz/////APDP/P8A8A8AAPD/DwAAAAAAAAAAAAAA\",\n    \"villager1WalkRight3\": \"hwQOABAAAADw/wAAAAAAAP////8AAAAA///z//8AAAD/z/NP9E/+APA7zE/93u0Pz8zM/ETe7f/PzMy80eT+/8/MzPzfNGP/z8zMRN00Yw//zExE3T5jD/DMzO7///8AAP/M/w8AAAAAAP//AAAAAAAAAAAAAAAA\",\n    \"villager1WalkFront\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.villager1WalkFront1\\\",\\\"sprites.builtin.villager1WalkFront2\\\",\\\"sprites.builtin.villager1WalkFront3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"villager1WalkBack\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.villager1WalkBack1\\\",\\\"sprites.builtin.villager1WalkBack2\\\",\\\"sprites.builtin.villager1WalkBack3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"villager1WalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.villager1WalkLeft1\\\",\\\"sprites.builtin.villager1WalkLeft2\\\",\\\"sprites.builtin.villager1WalkLeft3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"villager1WalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.villager1WalkRight1\\\",\\\"sprites.builtin.villager1WalkRight2\\\",\\\"sprites.builtin.villager1WalkRight3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"villager2WalkFront1\": \"hwQNABAAAAAA8M//APDuAAD/z///7+QA8P/P/+T//wDw//y/Qb9n//////9Pfmf/////7kR+Zw//z+/uRH5nD//M7/9Pfmf/8P//v0G/Z//w///85P//AAD/z/z/7+QAAMDM/wDw7gAAAAAAAAAAAA==\",\n    \"villager2WalkFront2\": \"hwQNABAAAAAAAP8AAAAAAAAA//z/8A4AAPD//P/vBAAA///8T/7//wD/z/8btGf/8P////90Z//w///vTnRnD/D//O5OdGcP8M/8/v/kbg8A////G07kDwD//89PTuQAAPD/zP9PDgAAAMz8/+4AAA==\",\n    \"villager2WalkFront3\": \"hwQNABAAAAAAAMz8/+4AAADw/8z/Tw4AAP//z09O5AAA////G07kD/DP/P7/5G4P8P/87k50Zw/w///vTnRnD/D/////dGf/AP/P/xu0Z/8A///8T/7//wDw//z/7wQAAAD//P/wDgAAAP8AAAAAAA==\",\n    \"villager2WalkBack1\": \"hwQNABAAAAAA8P//D/DuAAD/////7+QA8M/8/////wDwzPz///9n/8/M//z//2f/z8zM/P//Zw/PzMz8//9nD8/MzP///2f/8Mz8/P//Z//wz8z8///8AAD/zP//7+QAAPD//w/w7gAAAAAAAAAAAA==\",\n    \"villager2WalkBack2\": \"hwQNABAAAAAAAP8AAAAAAADwz///AAAAAPDM///vTg4A/8z////P/wDPzP///3//8Mz8zP//f//wzMzM//9/D/DMzPz//38P8MzMzP//fw8Az8zP///vDwD/zMz//08OAPDP/P//Tg4AAP///wDvAA==\",\n    \"villager2WalkBack3\": \"hwQNABAAAAAAAPAPAAAAAAAA//8PAO8AAPD//P//Tg4A/8/8//9PDgDPzPz//+8P8MzM//z/fw/wzMzM/P9/D/DMzMz//38P8MzMzP//f/8Az8z8/P9//wD/zMz//8//APDP/P/vTg4AAP///wAAAA==\",\n    \"villager2WalkLeft1\": \"hwQNABAAAAAAAP8AAAAAAAAA/w8AAAAAAP/8/wAAAADw//z/////APDP/+5Ef2cP//zv7kR+Zw//////T35n/////L9B7v7//8/8/+5O5P/////v9E7kD/D/z+/+7/4A8P/M//8AAAAA8P//AAAAAA==\",\n    \"villager2WalkLeft2\": \"hwQNABAAAAAAAPAPAAAAAAAA//8AAAAAAPDP//8A8A8A/8////////D//O9O9Gf/8M//7k7kZ//w/////+T+D/D/z/8bTuQP8P/M/+9O5A/w////Tu/+/wD///zu////AP/P/P8P8A8AAP//DwAAAA==\",\n    \"villager2WalkLeft3\": \"hwQNABAAAAAAAPAPAAAAAAAA//8PAAAAAPDP//8A8A8A/8////////D//O9O9Gf/8M//7k7kZ//w/////+RnD/D/z/8b5GcP8P/M/+/u/g/w////Tk/k/wD///zuT+T/AP/P/P9P/g8AAP///wAAAA==\",\n    \"villager2WalkRight1\": \"hwQNABAAAAAAAP///wAAAAD/z/z/T/4PAP///O5P5P/w////Tk/k//D/zP/v7v4P8P/P/xvkZw/w/////+RnD/DP/+5O5Gf/8P/87070Z/8A/8///////wDwz///APAPAAD//w8AAAAAAPAPAAAAAA==\",\n    \"villager2WalkRight2\": \"hwQNABAAAAAAAP//DwAAAAD/z/z/D/APAP///O7////w////Tu/+//D/zP/vTuQP8P/P/xtO5A/w/////+T+D/DP/+5O5Gf/8P/87070Z/8A/8///////wDwz///APAPAAD//wAAAAAAAPAPAAAAAA==\",\n    \"villager2WalkRight3\": \"hwQNABAAAAAA8P//AAAAAPD/zP//AAAA8P/P7/7v/gD////v9E7kD//P/P/uTuT////8v0Hu/v//////T35n///87+5EfmcP8M//7kR/Zw/w//z/////AAD//P8AAAAAAAD/DwAAAAAAAP8AAAAAAA==\",\n    \"villager2WalkFront\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.villager2WalkFront1\\\",\\\"sprites.builtin.villager2WalkFront2\\\",\\\"sprites.builtin.villager2WalkFront3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"villager2WalkBack\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.villager2WalkBack1\\\",\\\"sprites.builtin.villager2WalkBack2\\\",\\\"sprites.builtin.villager2WalkBack3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"villager2WalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.villager2WalkLeft1\\\",\\\"sprites.builtin.villager2WalkLeft2\\\",\\\"sprites.builtin.villager2WalkLeft3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"villager2WalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.villager2WalkRight1\\\",\\\"sprites.builtin.villager2WalkRight2\\\",\\\"sprites.builtin.villager2WalkRight3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"villager3WalkFront1\": \"hwQMABAAAAAA8P//D+BEAAD//0T+T00A8P//TuT//wDw/kT03b5h/+9ORPTdFGH/7+5ERL0UYQ/v7k5EvRRhD+/u7vTdFGH/8P7v9N2+Yf/w//9O5P//AAD//0T+T00AAPD//w/gRAA=\",\n    \"villager3WalkFront2\": \"hwQMABAAAAAA8P////AOAAD//0/k/wQAAP//70T+///w709E3+1r//DuRETfTWH/8O5ORNRLYQ/w7u5E1EthD/Du7k7fTf4P8O//Tt/U7Q8A///vRN7tAAD//0/kTw4AAPD////uAAA=\",\n    \"villager3WalkFront3\": \"hwQMABAAAAAA8P///+4AAAD//0/kTw4AAP//70Te7QDw709E39TtD/DuRETfTf4P8O5ORNRLYQ/w7u5E1EthD/Du7k7fTWH/8O//Tt/ta/8A///vRP7//wD//0/k/wQAAPD////wDgA=\",\n    \"villager3WalkBack1\": \"hwQMABAAAAAA8P//D+BEAAD/////Tk0A8O7//////wDw/u7//79t/+/u7v7/v23/7+7u/v+/bQ/v7u7+/79tD+/u7v7/v23/8O7u//+/bf/w7/7////8AAD/7v//Tk0AAPD//w/gRAA=\",\n    \"villager3WalkBack2\": \"hwQMABAAAAAAAP///wAAAADw/v//70QOAO/+/v////8A7+/u///b//Du7u7//9v/8O7u7v//2w/w7u7u///bD/Du7v7//9sPAO/u/v//7w4A/+7////eDgDw7/7/79QEAAD///8ATgA=\",\n    \"villager3WalkBack3\": \"hwQMABAAAAAAAP///wBOAADw////79QEAO/+////3g4A7+/////vDvDu7v7//9sP8O7u7v//2w/w7u7u///bD/Du7u7//9v/AO/u7v//2/8A/+7//////wDw7/7/70QOAAD///8AAAA=\",\n    \"villager3WalkLeft1\": \"hwQMABAAAAAA8P//AAAAAADv7v8PAAAA8O7u7v///wDv7kREvR5hD+/uTkS9FGEP7+7u9N0UYf/v7u703eT+/+/u70RE3u3/8P7/7/3e7Q/w//9P9E/+AAD/////AAAAAPD//wAAAAA=\",\n    \"villager3WalkLeft2\": \"hwQMABAAAAAAAP//AAAAAADw7v4PAPAPAO/u7v7////w7k5E1Oth//Du7kTUS2H/8O7uTt/t/g/w7u5O397tD/Du/k5E3u0P8O///95P/v8A////RP///wD/////D/APAPD//w8AAAA=\",\n    \"villager3WalkLeft3\": \"hwQMABAAAAAAAP//AAAAAADw7v4PAPAPAO/u7v7////w7k5E1Oth//Du7kTUS2H/8O7uTt9NYQ/w7u5O301hD/Du/k5E5P4P8O///97f7f8A////RN/t/wD/////T/4PAPD///8AAAA=\",\n    \"villager3WalkRight1\": \"hwQMABAAAAAA8P///wAAAAD/////T/4PAP///0Tf7f/w7///3t/t//Du/k5E5P4P8O7uTt9NYQ/w7u5O301hD/Du7kTUS2H/8O5ORNTrYf8A7+7u/v///wDw7v4PAPAPAAD//wAAAAA=\",\n    \"villager3WalkRight2\": \"hwQMABAAAAAA8P//DwAAAAD/////D/APAP///0T////w7///3k/+//Du/k5E3u0P8O7uTt/e7Q/w7u5O3+3+D/Du7kTUS2H/8O5ORNTrYf8A7+7u/v///wDw7v4PAPAPAAD//wAAAAA=\",\n    \"villager3WalkRight3\": \"hwQMABAAAAAA8P//AAAAAAD/////AAAA8P//T/RP/gDw/v/v/d7tD+/u70RE3u3/7+7u9N3k/v/v7u703RRh/+/uTkS9FGEP7+5ERL0eYQ/w7u7u////AADv7v8PAAAAAPD//wAAAAA=\",\n    \"villager3WalkFront\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.villager3WalkFront1\\\",\\\"sprites.builtin.villager3WalkFront2\\\",\\\"sprites.builtin.villager3WalkFront3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"villager3WalkBack\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.villager3WalkBack1\\\",\\\"sprites.builtin.villager3WalkBack2\\\",\\\"sprites.builtin.villager3WalkBack3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"villager3WalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.villager3WalkLeft1\\\",\\\"sprites.builtin.villager3WalkLeft2\\\",\\\"sprites.builtin.villager3WalkLeft3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"villager3WalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.builtin.villager3WalkRight1\\\",\\\"sprites.builtin.villager3WalkRight2\\\",\\\"sprites.builtin.villager3WalkRight3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"villager4WalkFront1\": \"hwQOABAAAAAAAPD/DwAAAADwX7X770QAAF9VtbtO/Q/wVVX89P+8D/BVtbzRbjnzX1VN9N+UuftfVUtE3ZQ5s19VS0TdlLm7X1VN9N+UOfPwVbW80W658/BVVfz0/7wPAF9VtbtO/Q8A8F+1++9EAAAA8P8PAAAA\",\n    \"villager4WalkFront2\": \"hwQOABAAAAAAAMD//wwAAAAAv1W7z+4AAPBVVbvrxAwAX1XF78+8DABfVcsbbbnD8FXVRP+dObPwVbVE1J25u/BVtUTUnbnD8FXVRP9NtMsAX1XLG9TtwwBfVcXv1O0MAPBVVbvbxAwAAL9Vu88MAAAAwP//DAAA\",\n    \"villager4WalkFront3\": \"hwQOABAAAAAAAMD//wwAAAAAv1W7zwwAAPBVVbvbxAwAX1XF79TtDABfVcsb1O3D8FXVRP9NtMvwVbVE1J25w/BVtUTUnbm78FXVRP+dObMAX1XLG225wwBfVcXvz7wMAPBVVbvrxAwAAL9Vu8/uAAAAwP//DAAA\",\n    \"villager4WalkBack1\": \"hwQOABAAAAAAAPD//w8AAADwv7u7z0QAAN9VtbvL/Q/wXVVVu7u8D/BVVVW9uz/zX1VVVbW7v/tfVVVVtbs/s19VVVW1u7+7X1VVVbW7P/PwVVVVvbu/+/BdVVW7u7wPAN9VtbvL/Q8A8L+7u89EAAAA8P//AAAA\",\n    \"villager4WalkBack2\": \"hwQOABAAAAAAAPD///8EAAAA3727y00AAPBVVbu7xAwAX1VVtbu/DABfVVW1u7/D8FVVVbW7P7PwVVVVtbu/u/BVVVW1uz/D8FVVVb27v8sAX1VVu7tPywC/Vb27u9wEAPC7u7vL1A4AAP+7u89MAAAAAP//DAAA\",\n    \"villager4WalkBack3\": \"hwQOABAAAAAAAAD//wwAAAAA/7u7z0wAAPC7u7vL1A4Av1W9u7vcBABfVVW7u0/L8FVVVb27v8vwVVVVtbs/w/BVVVW1u7+78FVVVbW7P7MAX1VVtbu/wwBfVVW1u78MAPBVVbu7xAwAAN+9u8tNAAAA8P///wQA\",\n    \"villager4WalkLeft1\": \"hwQOABAAAAAA8P//AAAAAPBfVfUPAPAP8FXV+///Pw9fVUtE3ZQ5819VTUTdlLn7X1W1xNyUObNcVVW80e6+u1xVVcxO3u3zXFVVtfve7fvwVVVVu0S+D/BVVVW7+/8PAF9VVbv7AAAAwFy1uwwAAAAA8P/MAAAA\",\n    \"villager4WalkLeft2\": \"hwQOABAAAAAAAP//AAAAAAD/VVUPAMAMAF9Vvf/MvMPwVbVE1E25y/BV1UTUTbnD8FVVS8xNubvAVVXFG+2+s8BVVcXs3u3DwFVVVbve7cMAX1VVtUu+ywBfVVW1u7wMAPBVVbW7zAAAAFxVu8sAAAAAwP/PDAAA\",\n    \"villager4WalkRight1\": \"hwQOABAAAAAAAPD/zAAAAADAXLW7DAAAAF9VVbv7AADwVVVVu/v/D/BVVVW7RL4PXFVVtfve7ftcVVXMTt7t81xVVbzR7r67X1W1xNyUObNfVU1E3ZS5+19VS0TdlDnz8FXV+///Pw/wX1X1DwDwDwDw//8AAAAA\",\n    \"villager4WalkRight2\": \"hwQOABAAAAAAAMD/zwwAAAAAXFW7ywAAAPBVVbW7zAAAX1VVtbu8DABfVVW1S77LwFVVVbve7cPAVVXF7N7tw8BVVcUb7b6z8FVVS8xNubvwVdVE1E25w/BVtUTUTbnLAF9Vvf/MvMMA/1VVDwDADAAA//8AAAAA\"\n}","sprites.builtin.ts":"namespace sprites.builtin {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic animals\"\n    export const angelFish0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic animals\"\n    export const angelFish1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic animals\"\n    export const angelFish2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic animals\"\n    export const angelFish3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const aquaticBackground = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const bed0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const bed1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const bed2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"electronics\"\n    export const bigButtonPress0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"electronics\"\n    export const bigButtonPress1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const brick = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const cat0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const cat1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const cat2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const clam0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const clam1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const clam2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const clownFish0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const clownFish1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const clownFish2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const clownFish3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const coin0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const coin1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const coin2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const coin3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const coin4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const coin5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"electronics\"\n    export const computer0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"electronics\"\n    export const computer1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"electronics\"\n    export const console = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile aquatic\"\n    export const coral0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile aquatic\"\n    export const coral1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile aquatic\"\n    export const coral2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile aquatic\"\n    export const coral3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile aquatic\"\n    export const coral4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile aquatic\"\n    export const coral5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const couchFront0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const couchFront1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const couchSide0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const couchSide1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const couchSide2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const crowd0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const crowd1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const crowd2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const crowd3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const crowd4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const crowd5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const crowd6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const crowd7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const crowd8 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const crowd9 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const dog0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const dog1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const dog2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const field0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const field1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports\"\n    export const fieldGoal = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports\"\n    export const football1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports\"\n    export const football2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports\"\n    export const football3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports\"\n    export const football4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports\"\n    export const football6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports\"\n    export const football7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports people\"\n    export const footballPlayer0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports people\"\n    export const footballPlayer1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports people\"\n    export const footballPlayer2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports people\"\n    export const footballPlayer3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports people\"\n    export const footballPlayer4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports people\"\n    export const footballPlayer5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports people\"\n    export const footballPlayer6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"sports people\"\n    export const footballPlayer7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const forestBackground = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals dungeon\"\n    export const forestBat0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals dungeon\"\n    export const forestBat1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals dungeon\"\n    export const forestBat2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals dungeon\"\n    export const forestBat3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals dungeon\"\n    export const forestBat4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals dungeon\"\n    export const forestBat5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals dungeon\"\n    export const forestBat6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals dungeon\"\n    export const forestBat7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestFlowers0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestFlowers1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestFlowers2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestLargeMushroom0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestLargeMushroom1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestMonkey0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestMonkey1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestMonkey2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestMonkey3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestMonkey4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestMonkey5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestMonkey6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestMonkey7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestMonkey8 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestMonkey9 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestMonkey10 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestMushroomPatch = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestScenery0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestScenery1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestScenery2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestScenery3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestSnake0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestSnake1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestSnake2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestSnake3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestSnake4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestSnake5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestSnake6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals forest\"\n    export const forestSnake7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles8 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles9 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles10 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles11 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles12 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles13 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles14 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles15 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles16 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles17 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles18 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles19 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles20 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles21 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles22 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles23 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles24 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles25 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles26 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles27 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles28 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const forestTiles29 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestTree0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestTree1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestTree2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestTree3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestTreeGroup0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestTreeGroup1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestTreeGroup2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestTreeGroup3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const forestTreeGroup4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const furnitureRug = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const furnitureTable1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const furnitureTable2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabAttack0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabAttack1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabAttack2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabAttack3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabAttack4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabAttack5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabAwaken0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabAwaken1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabAwaken2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabAwaken3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabAwaken4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabAwaken5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabWalk0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabWalk1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabWalk2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const hermitCrabWalk3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic\"\n    export const largeOceanRock = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const largeShelf = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic\"\n    export const mediumOceanRock = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanDepths0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanDepths1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanDepths2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanDepths3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanDepths4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanDepths5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanDepths6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanDepths7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanDepths8 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanDepths9 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanDepths10 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanDepths11 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand8 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand9 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand10 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand11 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand12 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand13 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand14 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile aquatic\"\n    export const oceanSand15 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const pedestal = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic\"\n    export const seaweed0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic\"\n    export const seaweed1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic\"\n    export const seaweed2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const shark0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const shark1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const shark2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const shark3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const sharkAttack0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const sharkAttack1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const sharkAttack2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const sharkAttack3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const sharkAttack4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals aquatic\"\n    export const sharkAttack5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic\"\n    export const smallOceanRock = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const smallShelf0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const smallShelf1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"furniture\"\n    export const smallShelf2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"electronics\"\n    export const tv = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager1WalkFront1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager1WalkFront2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager1WalkFront3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager1WalkBack1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager1WalkBack2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager1WalkBack3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager1WalkLeft1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager1WalkLeft2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager1WalkLeft3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager1WalkRight1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager1WalkRight2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager1WalkRight3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager2WalkFront1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager2WalkFront2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager2WalkFront3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager2WalkBack1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager2WalkBack2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager2WalkBack3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager2WalkLeft1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager2WalkLeft2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager2WalkLeft3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager2WalkRight1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager2WalkRight2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager2WalkRight3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager3WalkFront1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager3WalkFront2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager3WalkFront3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager3WalkBack1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager3WalkBack2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager3WalkBack3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager3WalkLeft1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager3WalkLeft2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager3WalkLeft3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager3WalkRight1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager3WalkRight2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager3WalkRight3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager4WalkFront1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager4WalkFront2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager4WalkFront3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager4WalkBack1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager4WalkBack2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager4WalkBack3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager4WalkLeft1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager4WalkLeft2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager4WalkRight1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const villager4WalkRight2 = image.ofBuffer(hex``);\n}\n","sprites.castle.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.castle\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"heroFrontAttack1\": \"hwQYABgAAAAAAAAA//D/AAAAAAAAAP//79+7DwAAAAAA8P/+7t+7/AAAAAAA/+/yT9+7/AAAAAAA/y7/G9+7/w8AAADwLy7v//3/9A8AAADwIi7v1E0i9QAAAADwIi7v1E0i9QAAAADwLy7v/00i9A8AAAAA/y7/G+0i9A8AAAAA/+/yT+7/DwAAAAAA8O/+7v7UBAAAAAAAAP//7w9OBAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"heroFrontAttack2\": \"hwQYABgAAAAAAAAAAP//AAAAAAAAAAAA/73LDwAAAAAAAP//7///DwAAAAAA8P/+7v4EAAAAAAAA/+/yT+7//8DMAAAA/y7/G+0i9N/NAADwLy7v/00i9N0MAADwIi7v1E3C3M0AAADwIi7v1E3C3QwAAADwLy7v/+3OzA8AAAAA/y7/G9Tt9A8AAAAA/+/yT97t/wAAAAAA8O/+7k8OAAAAAAAAAP//7+8AAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"heroFrontAttack3\": \"hwQYABgAAAAAAAAAAP//AAAAAAAAAAAA/73LDwAAAAAAAPD/////DwAAAAAAAP/v/u7vBAAAAAAAAP/v8k/+/wAAAAAA8C/i8hsk9A8AAAAA8CLi4v8t9A8AAAAALyLi4tQt9Q8AAAAALyLi4tQt9Q/AAAAA8CLi4v8t9A7MzMwA8C/i8hv03+0cEREAAP/v8k9O1O3MzMwAAP/v/u7v7g7AAAAAAPD///8OAAAAAAAAAADw/w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"heroFrontAttack4\": \"hwQYABgAAAAAAAAAAP//AAAAAAAAAADw/73LDwAAAAAA8P//7///DwAAAAAA/+/v7v4EAAAAAADw/y7/T+7//wAAAADw7/K/2+0i9A8AAAD/4vL+300i9A8AAAAv4vJO1E0i9QAAAAAv4vJO1E0i9QAAAAD/4vL+300i9A8AAADw7/K/2+Qi9A8AAADw/y7/T+7//wAAAAAA/+7v7k5BAAAAAAAA8P//7/9OAAAAAAAAAADw/9/tAAAAAAAAAAAAAN7tAAAAAAAAAAAAwMwOAAAAAAAAAAAAwM0AAAAAAAAAAAAA3M0AAAAAAAAAAADA3QwAAAAAAAAAAADczQAAAAAAAAAAAADcDAAAAAAAAAAAAADMAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"heroFrontAttack\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.heroFrontAttack1\\\",\\\"sprites.castle.heroFrontAttack2\\\",\\\"sprites.castle.heroFrontAttack3\\\",\\\"sprites.castle.heroFrontAttack4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"heroSideAttackLeft1\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMwAAAAAAAAAAAAAwN0MAAAAAAAAAAAAANzNAAAAAAAAAAAAAMDdzAAAAAAAAAAAAP/czQ4AAAAAAAAA/y7PzO0AAAAAAADw4uLv3u3/AAAAAAAv4vJO7URSDwAAAAD/4vJO3U5eDwAAAADv7/L+3yRC/wAAAADv/v6/0SRC/wAAAADv/i7vRC5C/wAAAADv7i9P7S5CDwAAAADw7i9P5P//AAAAAADw7+/v7g8AAAAAAAAA/////gAAAAAAAAAAAAD/DwAAAAAAAAA=\",\n    \"heroSideAttackLeft2\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAwAAAAAAAAAAAAA3AwAAAAAAAAAAAAAwM0AAAAAAAAAAAAAwN0MAAAAAAAAAAAAANzMAAAAAAAAAAAAANzNAAAAAAAAAAAAAMDMAAAAAAAAAAD//+DdDgAAAAAAAP8u7+/dDgAAAAAA8O/i7/5ODgAAAAAA8OLyTt1ODgAAAAAAL+LyTt3i/wAAAADwIuLy/t9S/wAAAADw7/7+v9tCDwAAAADw7/7+v9tCDwAAAAAA7/4u70RCDwAAAAAA7+4vT+1C/wAAAAAA7+4vT+RC/wAAAAAA8O7v7+7//wAAAAAA8O////4AAAAAAAAAAP//7w8AAAAAAAAAAADw/wAAAAAAAAA=\",\n    \"heroSideAttackLeft3\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAMANAAAAAAAAAAAAAMDNAAAAAAAAAAAAAMDNAAAAAAAAAAAAAMDNAAAAAAAAAAAAAMDNAAAAAAAAAPD/D8zMDAAAAAAA8O/y/uAOAAAAAAAA/y7+7t7tAAAAAADwLy7v1N7tAAAAAADwIi7v1O3kDwAAAAAv/y7v/+3k/wAAAAD/7u//uy3+/wAAAADw7u/yTiT0DwAAAADw7v7y1C70DwAAAADw7v7yRC70/wAAAAAA7/7+7v7//wAAAAAA//7/7w8A/wAAAAAA8P///gAAAAAAAAAAAAD/DwAAAAAAAAA=\",\n    \"heroSideAttackLeft4\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMwAAAAAAP//AAAA3M0AAAAA/y7vDwDA3QwAAADw4uLv/s/czQAAAAAv4vJO3c7dDAAAAAD/4vJO3cTMDwAAAADv7/L+3yRC/wAAAADv/v6/0SRC/wAAAADv/i7vRO5P/wAAAADv7i9P7d1ODwAAAADw7i9P5N3+AAAAAADw7+/v7v8AAAAAAAAA/////gAAAAAAAAAAAAD/DwAAAAAAAAA=\",\n    \"heroSideAttackRight4\": \"hwQYABgAAAAAAAD/DwAAAAAAAAAA/////gAAAAAAAADw7+/v7v8AAAAAAADw7i9P5N3+AAAAAADv7i9P7d1ODwAAAADv/i7vRO5P/wAAAADv/v6/0SRC/wAAAADv7/L+3yRC/wAAAAD/4vJO3cTMDwAAAAAv4vJO3c7dDAAAAADw4uLv/s/czQAAAAAA/y7vDwDA3QwAAAAAAP//AAAA3M0AAAAAAAAAAAAAwMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"heroSideAttackRight3\": \"hwQYABgAAAAAAAD/DwAAAAAAAAAA8P///gAAAAAAAAAA//7/7w8A/wAAAAAA7/7+7v7//wAAAADw7v7yRC70/wAAAADw7v7y1C70DwAAAADw7u/yTiT0DwAAAAD/7u//uy3+/wAAAAAv/y7v/+3k/wAAAADwIi7v1O3kDwAAAADwLy7v1N7tAAAAAAAA/y7+7t7tAAAAAAAA8O/y/uAOAAAAAAAAAPD/D8zMDAAAAAAAAAAAAMDNAAAAAAAAAAAAAMDNAAAAAAAAAAAAAMDNAAAAAAAAAAAAAMDNAAAAAAAAAAAAAMANAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"heroSideAttackRight2\": \"hwQYABgAAAAAAADw/wAAAAAAAAAAAP//7w8AAAAAAAAA8O////4AAAAAAAAA8O7v7+7//wAAAAAA7+4vT+RC/wAAAAAA7+4vT+1C/wAAAAAA7/4u70RCDwAAAADw7/7+v9tCDwAAAADw7/7+v9tCDwAAAADwIuLy/t9S/wAAAAAAL+LyTt3i/wAAAAAA8OLyTt1ODgAAAAAA8O/i7/5ODgAAAAAAAP8u7+/dDgAAAAAAAAD//+DdDgAAAAAAAAAAAMDMAAAAAAAAAAAAANzNAAAAAAAAAAAAANzMAAAAAAAAAAAAwN0MAAAAAAAAAAAAwM0AAAAAAAAAAAAA3AwAAAAAAAAAAAAAzAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"heroSideAttackRight1\": \"hwQYABgAAAAAAADw/wAAAAAAAAAA8P//7w8AAAAAAAAA//7+7v4AAAAAAAAA7/7yRP7/DwAAAADw7v7y1O4i9AAAAADw7u/yTuQi9A8AAADw7u//G00i9A8AAADw/i7v/00i9A8AAADwLy7v1O3k9QAAAADwIi7v1E4k9QAAAAAALy7+7t3+DwAAAAAA8O/yzNwOAAAAAAAAAPDP3ewAAAAAAAAAAADczQwAAAAAAAAAAMDdDAAAAAAAAAAAANzNAAAAAAAAAAAAAMwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"heroSideAttackLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.heroSideAttackLeft1\\\",\\\"sprites.castle.heroSideAttackLeft2\\\",\\\"sprites.castle.heroSideAttackLeft3\\\",\\\"sprites.castle.heroSideAttackLeft4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"heroSideAttackRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.heroSideAttackRight1\\\",\\\"sprites.castle.heroSideAttackRight2\\\",\\\"sprites.castle.heroSideAttackRight3\\\",\\\"sprites.castle.heroSideAttackRight4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"heroWalkFront1\": \"hwQQABAAAAAAAAAAAAAAAAAAAPAPAAAAAPD///7gRAAA/+/v7k9NAPD/Lv/k/v8A8O/yv9EuQv//4vL+3yRC/y/i8k7dJFIPL+LyTt0kUg//4vL+3yRC//Dv8r/RLkL/8P8u/+T+/wAA/+7v7k9NAADw///+4EQAAAAA8A8AAAAAAAAAAAAAAA==\",\n    \"heroWalkFront2\": \"hwQQABAAAAAAAAAAAAAAAAAAAP8AAAAAAAD////wDgAA8P/+7u8EAAD/7/JP/v//AP8u/xskQv/wLy7v/y1C//AiLu/ULVIP8CIu79QtUg/wLy7v/+3+DwD/Lv8b1O0PAP/v8k/e7QAA8O/+7k8OAAAA////7gAAAAAA/wAAAAAAAAAAAAAAAA==\",\n    \"heroWalkFront3\": \"hwQQABAAAAAAAAAAAAAAAAAAAPAPAAAAAPD///7gRAAA/+/v7k9NAPD/Lv/k/v8A8O/yv9EuQv//4vL+3yRC/y/i8k7dJFIPL+LyTt0kUg//4vL+3yRC//Dv8r/RLkL/8P8u/+T+/wAA/+7v7k9NAADw///+4EQAAAAA8A8AAAAAAAAAAAAAAA==\",\n    \"heroWalkFront4\": \"hwQQABAAAAAAAAAAAAAAAAAAAP8AAAAAAAD////uAAAA8O/+7k8OAAD/7/JP3u0AAP8u/xvU7Q/wLy7v/+3+D/AiLu/ULVIP8CIu79QtUg/wLy7v/y1C/wD/Lv8bJEL/AP/v8k/+//8A8P/+7u8EAAAA////8A4AAAAA/wAAAAAAAAAAAAAAAA==\",\n    \"heroWalkBack1\": \"hwQQABAAAAAAAAAAAAAAAAAAAPAPAAAAAPD///7gRAAA/+/v7k9NAPD+Lv/v/v8A8P7yIu/+Qv/v/i7y7v5C/+8v8u7u/kIP7y/y7u7+Qg/v/i7y7v5C//D+8iLv/kL/8P4u/+7+/wAA/+/v7k9NAADw///+4EQAAAAA8A8AAAAAAAAAAAAAAA==\",\n    \"heroWalkBack2\": \"hwQQABAAAAAAAAAAAAAAAAAAAADwDwAAAADw//8PAAAA8P/+7v5ODgDv7/Ly7v//AO8vL//uL//w7u/y7+4v//D+Iu/u7i8P8P4i7+7uLw/w7u8v8u4vDwDvLyLv7u8OAO/v/+7u3w4A8P/+7v7UBAAA8P//D04AAAAAAPAPAAAAAAAAAAAAAA==\",\n    \"heroWalkBack3\": \"hwQQABAAAAAAAAAAAAAAAAAAAPAPAAAAAPD///7gRAAA/+/v7k9NAPD+Lv/v/v8A8P7yIu/+Qv/v/i7y7v5C/+8v8u7u/kIP7y/y7u7+Qg/v/i7y7v5C//D+8iLv/kL/8P4u/+7+/wAA/+/v7k9NAADw///+4EQAAAAA8A8AAAAAAAAAAAAAAA==\",\n    \"heroWalkBack4\": \"hwQQABAAAAAAAAAAAAAAAAAAAADwDwAAAADw//8PTgAA8P/+7v7UBADv7//u7t8OAO8vIu/u7w7w7u8v8u4vD/D+Iu/u7i8P8P4i7+7uLw/w7u/y7+4v/wDvLy//7i//AO/v8vLu//8A8P/+7v5ODgAA8P//DwAAAAAAAPAPAAAAAAAAAAAAAA==\",\n    \"heroWalkFront\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.heroWalkFront1\\\",\\\"sprites.castle.heroWalkFront2\\\",\\\"sprites.castle.heroWalkFront3\\\",\\\"sprites.castle.heroWalkFront4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"heroWalkBack\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.heroWalkBack1\\\",\\\"sprites.castle.heroWalkBack2\\\",\\\"sprites.castle.heroWalkBack3\\\",\\\"sprites.castle.heroWalkBack4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"heroWalkShieldFront1\": \"hwQQABAAAAAAAAAAAAAAAAAAAPAP/w8AAPD///69+wAA/+/v/r3LD/D/Lv/0vcsP8O/yv/G9+///4vL+3/9P/y/i8k7dJFIPL+LyTt0kUg//4vL+3yRC//Dv8r/RLkL/8P8u/+T+/wAA/+7v7k9NAADw///+4EQAAAAA8A8AAAAAAAAAAAAAAA==\",\n    \"heroWalkShieldFront2\": \"hwQQABAAAAAAAAAAAP//AAAAAP/wvcsPAAD//////w8A8P/+7u8EAAD/7/JP/v//AP8u/xskQv/wLy7v/y1C//AiLu/ULVIP8CIu79QtUg/wLy7v/+3+DwD/Lv8b1O0PAP/v8k/e7QAA8O/+7k8OAAAA////7gAAAAAA/wAAAAAAAAAAAAAAAA==\",\n    \"heroWalkShieldFront3\": \"hwQQABAAAAAAAAAAAAAAAAAAAP8AAAAAAAD////+/wAA8O/+7t+7DwD/7/JP37v8AP8u/xvfu/zwLy7v/9+7D/AiLu/U/f8P8CIu79QtUg/wLy7v/y1C/wD/Lv8bJEL/AP/v8k/+//8A8P/+7u8EAAAA////8A4AAAAA/wAAAAAAAAAAAAAAAA==\",\n    \"heroWalkShieldFront4\": \"hwQQABAAAAAAAAAAAAAAAAAAAP8AAAAAAAD////uAAAA8O/+7k8OAAD/7/JP3u0AAP8u/xvU7Q/wLy7v/+3+D/AiLu/ULVIP8CIu79QtUg/wLy7v/y1C/wD/Lv8bJEL/AP/v8k/+//8A8P/+7u8EAAAA//////8PAAAA//C9yw8AAAAAAP//AA==\",\n    \"heroWalkShieldBack1\": \"hwQQABAAAAAAAAAAAAAAAAAAAPAPAAAAAPD///7gRAAA/+/v7k9NAPD+Lv/v/v8A8P7yIu/+Qv/v/i7y7v5C/+8v8u7u/kIP7y/y7u7+Qg/v/i7y7v5C//D+8iLv/kL/8P4u/+7+/wAA/+/v7k9NAADw///+4EQAAAAA8A8AAAAAAAAAAAAAAA==\",\n    \"heroWalkShieldBack2\": \"hwQQABAAAAAAAAAA8A8AAAAA8P//DwAAAPD//u7+Tg4A7+/y8u7//wDvLy//7i//8O7v8u/uL//w/iLv7u4vD/D+Iu/u7i8P8O7vL/LuLw8A7y8i7+7vDgDv7//u7t8OAPD//u7+1AQAAPD/////DwAAAADwvcsPAAAAAAD//wAAAAAAAAAAAA==\",\n    \"heroWalkShieldBack3\": \"hwQQABAAAAAAAADwDwAAAADw///+4EQAAP/v7+5PTQDw/i7/7/7/APD+8iLv/kL/7/4u8u7+Qv/vL/Lu7v5CD+8v8u7u/kIP7/4u8u7+Qv/w/vIi7/5C//D+Lv/u/v8AAP/v7+5PTQAA8P///uBEAAAAAPAPAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"heroWalkShieldBack4\": \"hwQQABAAAAAAAAAAAAAAAAAA8P////8PAPD//u7+1AQA7+//7u7fDgDvLyLv7u8O8O7vL/LuLw/w/iLv7u4vD/D+Iu/u7i8P8O7v8u/uL/8A7y8v/+4v/wDv7/Ly7v//APD//u7+Tg4AAPD//w8AAAAAAADwDwAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"heroWalkShieldFront\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.heroWalkShieldFront1\\\",\\\"sprites.castle.heroWalkShieldFront2\\\",\\\"sprites.castle.heroWalkShieldFront3\\\",\\\"sprites.castle.heroWalkShieldFront4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"heroWalkShieldBack\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.heroWalkShieldBack1\\\",\\\"sprites.castle.heroWalkShieldBack2\\\",\\\"sprites.castle.heroWalkShieldBack3\\\",\\\"sprites.castle.heroWalkShieldBack4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"heroWalkShieldSideLeft1\": \"hwQQABAAAAAAAAAAAAAAAAAA8P8PAAAAAPDv8v4A8A8ALy7+7v////AiLu/U7VL/8C8u79RNUv/w/i7v/+3+D/Du7/8b3u0P8O7v8k7e7Q/w7v7y1E7+/wDv/vJE/v//AP/+/u4O8A8A8P//7w8AAAAAAPD/AAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"heroWalkShieldSideLeft2\": \"hwQQABAAAAAAAAAAAAAAAAAAAADw/wAAAAD//9+7DwAA/y7v37v7APDi4u/+7/4AL+LyTt3e7Q//4vJO3d7tD+/v8v7fTv7/7/7+v9EkQv/v/i7vRC5C/+/uL0/tLkIP8O4vT+T//gDw7+/v7g8AAAD////+AAAAAAAA/w8AAAAAAAAAAAAAAA==\",\n    \"heroWalkShieldSideLeft3\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAADw/w8AAAAA8O/y/gDwDwAvLv7u////8CIu79TtUv/wLy7v1E1S//D+Lu//7f4P8O7v/xve7Q/w7u/yTt7tD/Du/vLUTv7/AO/+8kT+//8A//7+7g7wDwDw///vDwAAAAAA8P8AAAAAAAAAAAAAAA==\",\n    \"heroWalkShieldSideLeft4\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAA/w8AAADw//+9+wAA8O/y/r27DwAvLv7u/+7/8CIu79Tt3f7wLy7v1O3d/vD+Lu//7eQP8O7v/xtNQg/w7u/yTuRCD/Du/vLU7kL/AO/+8kT+//8A//7+7g7wDwDw///vDwAAAAAA8P8AAAAAAAAAAAAAAA==\",\n    \"heroWalkShieldSideRight4\": \"hwQQABAAAAAAAAAAAAAAAAAAAPD/AAAAAPD//+8PAAAA//7+7g7wDwDv/vJE/v//8O7+8tTuQv/w7u/yTuRCD/Du7/8bTUIP8P4u7//t5A/wLy7v1O3d/vAiLu/U7d3+AC8u/u7/7v8A8O/y/r27DwAA8P//vfsAAAAAAAD/DwAAAAAAAAAAAA==\",\n    \"heroWalkShieldSideRight3\": \"hwQQABAAAAAAAAAAAAAAAAAAAPD/AAAAAPD//+8PAAAA//7+7g7wDwDv/vJE/v//8O7+8tRO/v/w7u/yTt7tD/Du7/8b3u0P8P4u7//t/g/wLy7v1E1S//AiLu/U7VL/AC8u/u7///8A8O/y/gDwDwAA8P8PAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"heroWalkShieldSideRight2\": \"hwQQABAAAAAAAAAAAAAAAAAAAP8PAAAAAP////4AAADw7+/v7g8AAPDuL0/k//4A7+4vT+0uQg/v/i7vRC5C/+/+/r/RJEL/7+/y/t9O/v//4vJO3d7tDy/i8k7d3u0P8OLi7/7v/gAA/y7v37v7AAAA///fuw8AAAAAAPD/AAAAAAAAAAAAAA==\",\n    \"heroWalkShieldSideRight1\": \"hwQQABAAAAAAAAAAAAAAAAAAAPD/AAAAAPD//+8PAAAA//7+7g7wDwDv/vJE/v//8O7+8tRO/v/w7u/yTt7tD/Du7/8b3u0P8P4u7//t/g/wLy7v1E1S//AiLu/U7VL/AC8u/u7///8A8O/y/gDwDwAA8P8PAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"heroWalkShieldLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.heroWalkShieldSideLeft4\\\",\\\"sprites.castle.heroWalkShieldSideLeft3\\\",\\\"sprites.castle.heroWalkShieldSideLeft2\\\",\\\"sprites.castle.heroWalkShieldSideLeft1\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"heroWalkShieldRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.heroWalkShieldSideRight1\\\",\\\"sprites.castle.heroWalkShieldSideRight2\\\",\\\"sprites.castle.heroWalkShieldSideRight3\\\",\\\"sprites.castle.heroWalkShieldSideRight4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"heroWalkSideLeft1\": \"hwQQABAAAAAAAAAAAAAAAAAA//8AAAAAAP8u7w8AAADw4uLv/v//AC/i8k7dLlIP/+LyTt0kUg/v7/L+3yRC/+/+/r/R5P7/7/4u70Te7f/v7i9P7d7tD/DuL0/kT/4A8O/v7+4PAAAA/////gAAAAAAAP8PAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"heroWalkSideLeft2\": \"hwQQABAAAAAAAAAAAAAAAAAA8P8PAAAAAPDv8v4A8A8ALy7+7v////AiLu/U7VL/8C8u79RNUv/w/i7v/+3+D/Du7/8b3u0P8O7v8k7e7Q/w7v7y1E7+/wDv/vJE/v//AP/+/u4O8A8A8P//7w8AAAAAAPD/AAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"heroWalkSideLeft3\": \"hwQQABAAAAAAAAAAAAAAAAAA//8AAAAAAP8u7w8AAADw4uLv/v//AC/i8k7dLlIP/+LyTt0kUg/v7/L+3yRC/+/+/r/R5P7/7/4u70Te7f/v7i9P7d7tD/DuL0/kT/4A8O/v7+4PAAAA/////gAAAAAAAP8PAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"heroWalkSideLeft4\": \"hwQQABAAAAAAAAAAAAAAAAAA8P8PAAAAAPDv8v4A8A8ALy7+7v////AiLu/U7VL/8C8u79RNUv/w/i7v/01CD/Du7/8bTUIP8O7v8k7k/g/w7v7y1N7t/wDv/vJE3u3/AP/+/u5O/g8A8P//7w8AAAAAAPD/AAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"heroWalkSideRight4\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAA8P//7w8AAAD//v7uTv4PAO/+8kTe7f/w7v7y1N7t//Du7/JO5P4P8O7v/xtNQg/w/i7v/01CD/AvLu/UTVL/8CIu79TtUv8ALy7+7v///wDw7/L+APAPAADw/w8AAAAAAAAAAAAAAA==\",\n    \"heroWalkSideRight3\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/w8AAAAA/////gAAAPDv7+/uDwAA8O4vT+RP/gDv7i9P7d7tD+/+Lu9E3u3/7/7+v9Hk/v/v7/L+3yRC///i8k7dJFIPL+LyTt0uUg/w4uLv/v//AAD/Lu8PAAAAAAD//wAAAAAAAAAAAAAAAA==\",\n    \"heroWalkSideRight2\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAA8P//7w8AAAD//v7uDvAPAO/+8kT+///w7v7y1E7+//Du7/JO3u0P8O7v/xve7Q/w/i7v/+3+D/AvLu/UTVL/8CIu79TtUv8ALy7+7v///wDw7/L+APAPAADw/w8AAAAAAAAAAAAAAA==\",\n    \"heroWalkSideRight1\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/w8AAAAA/////gAAAPDv7+/uDwAA8O4vT+RP/gDv7i9P7d7tD+/+Lu9E3u3/7/7+v9Hk/v/v7/L+3yRC///i8k7dJFIPL+LyTt0uUg/w4uLv/v//AAD/Lu8PAAAAAAD//wAAAAAAAAAAAAAAAA==\",\n    \"heroWalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.heroWalkSideLeft1\\\",\\\"sprites.castle.heroWalkSideLeft2\\\",\\\"sprites.castle.heroWalkSideLeft3\\\",\\\"sprites.castle.heroWalkSideLeft4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"heroWalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.heroWalkSideRight1\\\",\\\"sprites.castle.heroWalkSideRight2\\\",\\\"sprites.castle.heroWalkSideRight3\\\",\\\"sprites.castle.heroWalkSideRight4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"houseRed\": \"hwQwADAAAAAAAABARkRGREZERkRGRGxmZmZmxswAAAAAAADAbMZsxmzGbMZsxkxmZmZmZsYMAAAAAADAZsZmxmbGZsZmxkxsZmZmZmbGAAAAAAAiLiLiIiIuIuIiwkzL5u7u7m5mDAAAAAAiLiLiIiIuIuIiYkzEJN7d3W1EZAAAACDu7u7u7u7u7u7ubEzEJN7P/WzkTgYAACAuIuIiIi4i4iIibEzEJN7P/WzkTmQAACAuIuIiIi4i4iIiZkzEJN7d3W3kTs4AAO7u7u7u7u7u7u7OxkbEJN7P/WxERM4AAC4i4iIiLiLiIiLOxkbEJN7P/WzkTs4AAC4i4iIiLiLiIiJuxkbEJN7d3W3kTmQA4O7u7u7u7u7u7u5sbEbE5O7u7m7kTmQAICLiIiIuIuIiIuJsTEbERERERERERGQAICLiIiIuIuIiIuJmTGbMzMzMzMzMzMwA4u7u7u7u7u7u7s5mRsbbEWFmZmZmZmYAIuIiIi4iIi4iIs7GtEwUYWZmZmZmZmYAIuIiIi4iIi4iIm7GxEth5v7/7+7+/+8g7u7u7u7u7u7u7mxmxERhTkREREREREQg4iIi4iIi4iIi4mxMZERh7u7u7u7u7u4g4iIi4iIi4iIi4mZMZERhTkT/TkRERETu7u7u7u7u7u7uzmZGZERhTuT/TkRERETiIiIuIuIiIi4izsZEZERh7v7/7u7u7u7u7u7u7u7u7u7ubsZEZERhTvT/TkREREQiIiIiIiIiIiIiYsZEZERhTvT/TkREREQiIiIiIiIiIiIiYsZEZERh7v7/7u7u7u7u7u7u7u7u7u7ubsZEZERhTvT/TkREREQiLiIuIuIiIi4izsZEZERhTvT/TkRERETu7u7u7u7u7u7uzmZGZERh7u7/7v7/7u4g4iIi4iIi4iIi4mZMZERhTkT/TuRPT0Qg4iIi4iIi4iIi4mxMZERhTkTkTuRPT0Qg7u7u7u7u7u7u7mxmxERh7u7u7u7/7u4AIuIiIi4iIi4iIm7GxEth5u7u7u7u7u4AIuIiIi4iIi4iIs7GtEwUYWZmZmZmZmYA4u7u7u7u7u7u7s5mRsbbEWFmZmZmZmYAICLiIiIuIuIiIuJmTGbMzMzMzMzMzMwAICLiIiIuIuIiIuJsTEbERERERERERGQA4O7u7u7u7u7u7u5sbEbE5O7u7m7kTmQAAC4i4iIiLiLiIiJuxkbEJN7d3W3kTmQAAC4i4iIiLiLiIiLOxkbEJN7P/WzkTs4AAO7u7u7u7u7u7u7OxkbEJN7P/WxERM4AACAuIuIiIi4i4iIiZkzEJN7d3W3kTs4AACAuIuIiIi4i4iIibEzEJN7P/WzkTmQAACDu7u7u7u7u7u7ubEzEJN7P/WzkTgYAAAAiLiLiIiIuIuIiYkzEJN7d3W1EZAAAAAAiLiLiIiIuIuIiwkzL5u7u7m5mDAAAAADAZsZmxmbGZsZmxkxsZmZmZmbGAAAAAADAbMZsxmzGbMZsxkxmZmZmZsYMAAAAAABARkRGREZERkRGRGxmZmZmxswAAAA=\",\n    \"houseBlue\": \"hwQwADAAAAAAAADQ293b3dvd293b3by7u7u7y8wAAAAAAADAvMu8y7zLvMu8y9y7u7u7u8sMAAAAAADAu8u7y7vLu8u7y9y8u7u7u7vLAAAAAACqqKqKqqqoqoqqytzLi4iIiLi7DAAAAACqqKqKqqqoqoqqutzNrTgzM7PdvQAAAKCIiIiIiIiIiIiIvNzNrTjP87y92wsAAKCoqoqqqqiqiqqqvNzNrTjP87y9270AAKCoqoqqqqiqiqqqu9zNrTgzM7O928sAAIiIiIiIiIiIiIjIy9vNrTjP87zd3csAAKiqiqqqqKqKqqrIy9vNrTjP87y928sAAKiqiqqqqKqKqqq4y9vNrTgzM7O9270AgIiIiIiIiIiIiIi8vNvNjYiIiLi9270AoKqKqqqoqoqqqoq83NvN3d3d3d3d3b0AoKqKqqqoqoqqqoq73LvMzMzMzMzMzMwAioiIiIiIiIiIiMi728vbEbG7u7u7u7sAqoqqqqiqqqiqqsjLvdwdsbu7u7u7u7sAqoqqqqiqqqiqqrjLzdux6/7/7+7+/++giIiIiIiIiIiIiLy7zd2xPjMzMzMzMzOgiqqqiqqqiqqqirzcvd2xvrvrvru7u7ugiqqqiqqqiqqqirvcvd2xPjP/PjMzMzOIiIiIiIiIiIiIyLvbvd2xPuP/PjMzMzOKqqqoqoqqqqiqyMvdvd2xvvv/vru7u7uIiIiIiIiIiIiIuMvdvd2xPvP/PjMzMzOqqqqqqqqqqqqqusvdvd2xPvP/PjMzMzOqqqqqqqqqqqqqusvdvd2xvvv/vru7u7uIiIiIiIiIiIiIuMvdvd2xPvP/PjMzMzOqqKqoqoqqqqiqyMvdvd2xPvP/PjMzMzOIiIiIiIiIiIiIyLvbvd2xvuv/vvv/u7ugiqqqiqqqiqqqirvcvd2xPjP/PuM/PzOgiqqqiqqqiqqqirzcvd2xPjPjPuM/PzOgiIiIiIiIiIiIiLy7zd2xvru7u+v/vrsAqoqqqqiqqqiqqrjLzdux6+7u7u7u7u4AqoqqqqiqqqiqqsjLvdwdsbu7u7u7u7sAioiIiIiIiIiIiMi728vbEbG7u7u7u7sAoKqKqqqoqoqqqoq73LvMzMzMzMzMzMwAoKqKqqqoqoqqqoq83NvN3d3d3d3d3b0AgIiIiIiIiIiIiIi8vNvNjYiIiLi9270AAKiqiqqqqKqKqqq4y9vNrTgzM7O9270AAKiqiqqqqKqKqqrIy9vNrTjP87y928sAAIiIiIiIiIiIiIjIy9vNrTjP87zd3csAAKCoqoqqqqiqiqqqu9zNrTgzM7O928sAAKCoqoqqqqiqiqqqvNzNrTjP87y9270AAKCIiIiIiIiIiIiIvNzNrTjP87y92wsAAACqqKqKqqqoqoqqutzNrTgzM7PdvQAAAACqqKqKqqqoqoqqytzLi4iIiLi7DAAAAADAu8u7y7vLu8u7y9y8u7u7u7vLAAAAAADAvMu8y7zLvMu8y9y7u7u7u8sMAAAAAADQ293b3dvd293b3by7u7u7y8wAAAA=\",\n    \"princessFront0\": \"hwQQABAAAAAAAAAAAAAAAAAAAADwAAAAAAAA/2//AAAA8P9mZt//DwAfZv/23T8P8GH23T/zM/9VZf8//TVT/1Bi3939UzMPVWXf3f1TMw/wYf8//TVT//AW9t0/8zP/AG9h//bdPw8A8P9mZt//DwAAAP9v/wAAAAAAAPAAAAAAAAAAAAAAAA==\",\n    \"princessFront1\": \"hwQQABAAAAAAAAAAAAAAAAAAAADwAAAAAAAA/28PAAAA8P9mZv//AAAfZv/20/0P8GH23T/zPw9VZf8//TVTD1Bi3939UzMPVWXf3f1TMw/wYf8//TVT//AW9t0/8zP/AG9h//b9Pw8A8P9mZt//DwAAAP9v/wAAAAAAAPAAAAAAAAAAAAAAAA==\",\n    \"princessFront2\": \"hwQQABAAAAAAAAAAAAAAAAAAAADwAAAAAAAA/2//AAAA8P9mZt//DwAfZv/2/T8P8GH23T/zM/9VZf8//TVT/1Bi3939UzMPVWXf3f1TMw/wYf8//TVTD/AW9t0/8z8PAG9h//bT/Q8A8P9mZv//AAAAAP9vDwAAAAAAAPAAAAAAAAAAAAAAAA==\",\n    \"princessLeft0\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P//AAAAAABv1t0P//AP8Gb2P/01Pw9VYtbd/TNT81BlZtZd8z/zVRVmZj/f/f/wZmFm///fDwBvFmZmD/AAAPD//28PAAAAAABvbw8AAAAAAPDwAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"princessLeft1\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8PAAAAAPBm3f3wD/8Ab2b/09/9/1AlZt3d3/3/AFVmZt3T/fNQVWFm9tPf8wBvFmb2/1P/APBmYWb/P/8AAP////bwAAAAAPD29gAAAAAAAA8PAAAAAAAAAAAAAA==\",\n    \"princessLeft2\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8PAAAAAPBm3f3wDw8Ab2b/01/z81AlZt3dPzPzAFVmZt0zU/NQVWFm9tP/8wBvFmb23/3/APBmYWb//QAAAP////YPAAAAAPD29gAAAAAAAA8PAAAAAAAAAAAAAA==\",\n    \"princessBack0\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAPAAAAAAAA8PbwAAAA8P//9t8PAABvZmb23f8P8BZmZj/1P/NQFmZm9jM181UWZmb2M1PzVWZmZvYzU/NQFmZm9jM18/BmZmY/9T/zAG9mZvbd/w8A8P//9t8PAAAAAPD28AAAAAAAAA8AAAAAAAAAAAAAAA==\",\n    \"princessBack1\": \"hwQQABAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAG8PAAAAAP//b/8AAADwZmZm3/8PAG9hZvbzMw8AZWFmZj8181BlYWZmP1PzUGVmZmY/Uw8AZWFmZj8/DwBvZmb21f0AAPBmZmbf/QAAAP//b/8PAAAAAABvDwAAAAAAAPAAAAAAAAAAAAAAAA==\",\n    \"princessBack2\": \"hwQQABAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAG8PAAAAAP//b/8PAADwZmZm3/0AAG9hZvbV/QAAZWFmZj8/D1BlYWZmP1MPUGVmZmY/U/MAZWFmZj818wBvZmb28zMPAPBmZmbf/w8AAP//b/8AAAAAAABvDwAAAAAAAPAAAAAAAAAAAAAAAA==\",\n    \"princessWalkFront\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.princessFront0\\\",\\\"sprites.castle.princessFront1\\\",\\\"sprites.castle.princessFront2\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"princessWalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.princessLeft0\\\",\\\"sprites.castle.princessLeft1\\\",\\\"sprites.castle.princessLeft2\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"princessWalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.princessLeft0\\\",\\\"sprites.castle.princessLeft1\\\",\\\"sprites.castle.princessLeft2\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"princessWalkBack\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.princessBack0\\\",\\\"sprites.castle.princessBack1\\\",\\\"sprites.castle.princessBack2\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"princess2Front\": \"hwQQABAAAAAAAAAA8A8AAAAA8P//+wAAAPA/s7vr7gAAvzOzu+/0D/A+4//+/7wPX+Szv0G/3fFPRTP+T969/VRF4+5E3t2xVEXj7kTevb1PRTP+T97d8V/ks79Bv7398D7j//7/vA8AvzOzu+/0DwDwP7O76+4AAADw///7AAAAAAAA8A8AAA==\",\n    \"princess2WalkFront1\": \"hwQQABAAAAAAAAAA/wAAAAAA8P+/DwAAAADvs7v7DwAA8Dszu0v+DwDvM/7vTuQP8EU++xtO5PHwVDTj/+Te/U9VNO5O1N3xT1U07k7Uvb3wVDTj/9TdsfBFPvsbtL3xAO8z/u//vA8A8Dszu+v0DwAA77O7++4AAADw/78PAAAAAAAA/wAAAA==\",\n    \"princess2WalkFront2\": \"hwQQABAAAAAAAAAA8A8AAAAA8P//+wAAAPA/s7vr7gAAvzOzu+/0D/A+4//+/7wPX+Szv0G/3fFPRTP+T969/VRF4+5E3t2xVEXj7kTevb1PRTP+T97d8V/ks79Bv7398D7j//7/vA8AvzOzu+/0DwDwP7O76+4AAADw///7AAAAAAAA8A8AAA==\",\n    \"princess2WalkFront3\": \"hwQQABAAAAAAAAAA/wAAAAAA8P+/DwAAAADvs7v77gAA8Dszu+v0DwDvM/7v/7wP8EU++xu0vfHwVDTj/9TdsU9VNO5O1L29T1U07k7U3fHwVDTj/+Te/fBFPvsbTuTxAO8z/u9O5A8A8Dszu0v+DwAA77O7+w8AAADw/78PAAAAAAAA/wAAAA==\",\n    \"princess2Back\": \"hwQQABAAAAAAAAAA8A8AAAAA8P/P+wAAAPA/u7vL7gAAvzOzu8v0D/A+MzO7u7wPXzMzM7u73/FPMzMzu7u//VQzMzO7u9+xVDMzM7u7v71PMzMzu7vf8V8zMzO7u7/98D4zM7u7vA8AvzOzu8v0DwDwP7u7y+4AAADw/8/7AAAAAAAA8A8AAA==\",\n    \"princess2WalkBack1\": \"hwQQABAAAAAAAAAA8P8AAAAAAP/P+w8AAAD/u7u7DAAA8Duzu7v8DwDvMzO7u7wP8DUzM7u7v/HwNDMzu7vfsUA1MzO7u7+9QDUzM7u73/HwNDMzu7vf/fA1MzO7u+/+AO8zM7u7Tw4A8Duzu8tODwAA/7u7/OwAAAAA//8PAAAAAAAAAAAAAA==\",\n    \"princess2WalkBack2\": \"hwQQABAAAAAAAAAA8A8AAAAA8P/P+wAAAPA/u7vL7gAAvzOzu8v0D/A+MzO7u7wPXzMzM7u73/FPMzMzu7u//VQzMzO7u9+xVDMzM7u7v71PMzMzu7vf8V8zMzO7u7/98D4zM7u7vA8AvzOzu8v0DwDwP7u7y+4AAADw/8/7AAAAAAAA8A8AAA==\",\n    \"princess2WalkBack3\": \"hwQQABAAAAAAAAAAAAAAAAAAAP//DwAAAAD/u7v87AAA8Duzu8tODwDvMzO7u08O8DUzM7u77/7wNDMzu7vf/UA1MzO7u9/xQDUzM7u7v73wNDMzu7vfsfA1MzO7u7/xAO8zM7u7vA8A8Duzu7v8DwAA/7u7uwwAAAAA/8/7DwAAAAAA8P8AAA==\",\n    \"princess2Left1\": \"hwQQABAAAAAAAAAAAAAAAAAA8P8AAAAA8P8/Mw8A8A9P5TPj/v+/D1RF4+5E3t3xVEXj7kTevf1PRTP+T97dsV/ks79B7769/z7j//5P5PG/MzOzu0/k/fAzM7O7+74P8Dszs7u7/w8AvzOzu7sPAADw////+wAAAAAAAPAPAAAAAAAAAAAAAA==\",\n    \"princess2Left2\": \"hwQQABAAAAAAAAAAAAAAAAAA8P8AAAAAAP8/Mw8A8A/wVD4z7v/f+0BVNO5O1N39QFU07k7U3fHwVDTj/9S9vfBFPvsb5L6x8O8z/u9P5P3wOzMzu0vk/QA/MzO7u7/7AL8zM7u7vw8A8Dszu7v/AAAA//+/+wAAAAAAAP8PAAAAAAAAAAAAAA==\",\n    \"princess2Right1\": \"hwQQABAAAAAAAAAAAAAAAAAAAADwDwAAAPD////7AAAAvzOzu7sPAPA7M7O7u/8P8DMzs7v7vg+/MzOzu0/k/f8+4//+T+TxX+Szv0Hvvr1PRTP+T97dsVRF4+5E3r39VEXj7kTe3fFP5TPj/v+/D/D/PzMPAPAPAADw/wAAAAAAAAAAAAAAAA==\",\n    \"princess2Right2\": \"hwQQABAAAAAAAAAAAAAAAAAAAAD/DwAAAAD//7/7AAAA8Dszu7v/AAC/MzO7u78PAD8zM7u7v/vwOzMzu0vk/fDvM/7vT+T98EU++xvkvrHwVDTj/9S9vUBVNO5O1N3xQFU07k7U3f3wVD4z7v/f+wD/PzMPAPAPAADw/wAAAAAAAAAAAAAAAA==\",\n    \"princess2WalkFront\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.princess2Front\\\",\\\"sprites.castle.princess2WalkFront1\\\",\\\"sprites.castle.princess2WalkFront2\\\",\\\"sprites.castle.princess2WalkFront3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"princess2WalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.princess2Left1\\\",\\\"sprites.castle.princess2Left2\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"princess2WalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.princess2Right1\\\",\\\"sprites.castle.princess2Right2\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"princess2WalkBack\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.princess2Back\\\",\\\"sprites.castle.princess2WalkBack1\\\",\\\"sprites.castle.princess2WalkBack2\\\",\\\"sprites.castle.princess2WalkBack3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"rock0\": {\n        \"data\": \"hwQQABAAAAAAAAAAzMwAAAAAAMzLywwAAAAA3Lu8zAAAAMzcvbzMAMDMu7zdzMwAvN27y93LzADc3d2728vMDNvd3bvby7wM293du9u7vMvb3d2929u8y7Dd3b3b27zLANvdvb3bvMsA2927vb27DACwu7u7zbsMAAAA293MywAAAACwy7wLAA==\",\n        \"tilemapTile\": true\n    },\n    \"rock1\": {\n        \"data\": \"hwQQABAAAAAAAAAAAMDMAAAAAADLvMwMAAAAsNvLywwAAAC73c3LDACwy8zdzcvMALDdzN3Nzcuw293L27vNy7Dd3bvb28vLsN3d27vdzMvb3d3b27u8y9vdvb27vLvL2727zcu8u8vbvdvLzLy7DLDbvczMu8sMAADLzLzLzAAAAAAAzMwMAA==\",\n        \"tilemapTile\": true\n    },\n    \"rock2\": {\n        \"data\": \"hwQQABAAAAAAAADADLALAMALALvM27sAuwyw3cvbzQDdDLDdy7DNANsLsN27sMsAsADL27sAvAAAsN3MDAAAuwCw3csMALC9AMu7y7wL272wzLzMwAzbzbu9zAC7zNvL293LsL3Lu8zbvcuw3cu7vNu9y7Ddu8sLsLsMALsLuwAAAAAAsAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"saplingOak\": {\n        \"data\": \"hwQQABAAAAAAAADMDAAAAAAAzMbMDAAAAMBmZszMAAAAwGZnbMYAAABsdmdm9gwAAGx3dmf8TwDAZndnZ2b8DsBnV3fGZvzuwHd3Z2fM/O7AVWdmZ/bPAGBVd2dn/AzgAHZ1Z2bG7wQAxnZWZ8YPAADAbHbG/AAAAADMZsYMAAAAAMDMzAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"saplingPine\": {\n        \"data\": \"hwQQABAAAAAAAADMAAAAAAAAYMfMDAAAAABsx3wMAAAAYGxndwwAAMDMx2ZmzAAOwMZnbGZ35g7AfHfHdsfvAGxVd2xm9u7uXFV3Zmb/7u7AfHVnd8fuAGDHZ2Z3d+wOYGbHd2fMAA4AYMx3dwwAAAAAZmd8DAAAAABgZ8YMAAAAAABmAAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"shrub\": {\n        \"data\": \"hwQQABAAAAAAAGZgZgwAAAAAZsx2xmwAAGB2bHfMZgYAYHVsd1x3ZgDMdWZnVnVmwMZVZmx3ZcZmZ3ZnzGZmDHZVZ8bMfFdmdld1xsx8V2dmZ1ZlzGZmZsDGVWdsd2UMAMx1ZmdWdcYAYHdsd1x3ZgBgdmx3zGYGAAB2xnbGbAAAAGZgZgwAAA==\",\n        \"tilemapTile\": true\n    },\n    \"skellyFront\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAAAAAAAAAAwLEAAAAAAAAA//8PH/sAAAAAAAD/3b38H7EAAAAAAPAbEd29H/sAAAAAAPAREb0czPEPAAAAAB8REfEfvf8PAAAAAB8REdER+///AAAAAB8REdERsf//AAAAAB8REfEf+///AAAAAPAREb0czbEPAAAAAPAbEd29H/sAAAAAAAD/3b38H7EAAAAAAAAA//8PH/sAAAAAAAAAAAAAz7EAAAAAAAAAAAAA8P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyWalkFront1\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAAAAAAAAAAwLEAAAAAAAAA//8PH/sAAAAAAAD/3b38H7EAAAAAAPAbEd29H/sAAAAAAPAREb0czPEPAAAAAB8REfEfvf//AAAAAB8REdER+///AAAAAB8REdERsf//AAAAAB8REfEf+/8PAAAAAPAREb0cHPsAAAAAAPAbEd39sQ8AAAAAAAD/3b38EQsAAAAAAAAA////sQ8AAAAAAAAAAADwHAsAAAAAAAAAAAAA/w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyWalkFront2\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAAAAAAAAAAwLEAAAAAAAAA//8PH/sAAAAAAAD/3b38H7EAAAAAAPAbEd29H/sAAAAAAPAREb0czPEPAAAAAB8REfEfvf8PAAAAAB8REdER+///AAAAAB8REdERsf//AAAAAB8REfEf+///AAAAAPAREb0czbEPAAAAAPAbEd29H/sAAAAAAAD/3b38H7EAAAAAAAAA//8PH/sAAAAAAAAAAAAAz7EAAAAAAAAAAAAA8P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyWalkFront3\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/w8AAAAAAAAAAADwHAsAAAAAAAAA////sQ8AAAAAAAD/3b38EQsAAAAAAPAbEd39sQ8AAAAAAPAREb0czPsAAAAAAB8REfEfvf8PAAAAAB8REdER+///AAAAAB8REdERsf//AAAAAB8REfEf+///AAAAAPAREb0czfEPAAAAAPAbEd29H/sAAAAAAAD/3b38H7EAAAAAAAAA//8PH/sAAAAAAAAAAAAAwLEAAAAAAAAAAAAA8P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyAttackFront1\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAAAAAAAAAAwLEAAAAAAAAAAAAAH/sAAAAAAAAAAAAAH7EPAAAAAAAAAADwH/vMDwAAAAAAAAC/zPHP/w8AAAAAAAAf0cux//8PAAAAAPAREfHR+///AAAAAPARERGx////DwAAAPARERER+///DwAAAPAREfGx////DwAAAAAfEc0R/c+xDwAAAAC/Ed37/x/7AAAAAADwH93LDx+xAAAAAAAA8P//AB/7AAAAAAAAAAAAAM+xAAAAAAAAAAAAAPD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyAttackFront2\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHB3dwAAAAAAAAAAAAcAd/f/AAAAAAAAAAAAcMfRDwAAAAAA8P///7/8AAAAAADw393dyx/RDwAAAAC/ERHR3b/8AAAAAAAfERHRy8vRDwAAAPARERER//3/AAAAAPARERERHfv/AAAAAPARERERHfH/AAAAAPARERER//v/AAAAAAAfERHRy/3/AAAAAAC/ERHR3f8PAAAAAADw393dyw8AAAAAAAAA8P///wwAAAAAAAAAAADwvA8AAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyAttackFront3\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAA//8AAM8PAAAAAAD/3c3/AL8PAAAAAPAbEdH7/x8LAAAAAPAREdG8/L8PAAAAAB8RERHf+88PAAAAAB8RERGx//8AAAAAAB8RERER+/8AAAAAAB8RERG///8AAAAAAPAREdHc/f8AAAAAAPAbEdH7/w8AAAAAAAD/0c3/AAAAAAAAAAAA///7AAAAAAAAAAAAAPD7AAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyAttackFront4\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAA//8AABwPAAAAAAD/3cv/8LsPAAAAAPAb0d37/xELAAAAAPAREb28/LsPAAAAAB8REfEf/RwPAAAAAB8REdER+/8AAAAAAB8REdER8f8AAAAAAB8REfEf+/8AAAAAAPAREb28/f8AAAAAAPAb0d3L/w8AAAAAAAD/3b3/+wAAAAAAAAAA//+/ywAAAAAAAAAAAADP+wAAAAAAAAAAAADwDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyWalkLeft1\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8PAAAAAAAAAAD/3d37/wAAAAAAAPAbEREdsQ8AAAAAAPAREdEd+/8AAAAAAB8REfEfwbEPAAAAAB8REb0cH/sPAAAAAB8REd0dH7H/AAAAAB8REd27H/v/AAAAAPAR0d27v///AAAAAPDb3d3L////AAAAAAD/3b38AAD/AAAAAAAA//8PAPAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyAttackLeft1\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////DwAAAAAAAAD/3RuxDwAAAAAAAPAbERH7DwAAAAAAAPARERGx//8AAAAAAB8RER/7//8PAAAAAB8R0RzN////AAAAAB8R0b3/////AAAAAB8REf/M////AAAAAL8RwbHP////AAAAAPARH/vPD/D/AAAAAPAbH7H/AAD/AAAAAAD/H/sPAAD/AAAAAAAAv/8AAPAPAAAAAAAA8A8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyAttackLeft2\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAAAAAAAAAAz9EPAAAAAADw////v/sAAAAAAPDf3d29H9EPAAAAAL8RERHRv/0AAAAAAB8REdHdvAwAAAAA8BEREdH/vA8AAAAA8BER0d3L/f8AAAAA8BER0d3dzf8AAAAA8BER0d29+/8PAAAAAB8R3d27//8PAAAAAL/d3d3L//8PAAAAAPDb3b3///8PAAAAAAD///8PAP8PAAAAAAAAAAAAAPAPAAAAAAAAAAAAAPAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyWalkLeft2\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw/wAAAAAAAAAA//+/sQ8AAAAAAAD/3R0R+w8AAAAAAPAbERERsQ//AAAAAB8REREf+w+xAAAAAB8REd0c/Q/7AAAAAB8REd29//+xAAAAAB8REd3d/P/7AAAAAB8R0d3d////AAAAAPAR3d3d////AAAAAPDb3d29////AAAAAAC/3d398P//AAAAAADw//8PAPD/AAAAAAAAAAAAAP8PAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyWalkRight1\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAP8PAAAAAADw//8PAPD/AAAAAAC/3d398P//AAAAAPDb3d29////AAAAAPAR3d3d////AAAAAB8R0d3d////AAAAAB8REd3d/P/7AAAAAB8REd29//+xAAAAAB8REd0c/Q/7AAAAAB8REREf+w+xAAAAAPAbERERsQ//AAAAAAD/3R0R+w8AAAAAAAAA//+/sQ8AAAAAAAAAAADw/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyAttackRight1\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAPAPAAAAAAD///8PAP8PAAAAAPDb3b3///8PAAAAAL/d3d3L//8PAAAAAB8R3d27//8PAAAA8BER0d29+/8PAAAA8BER0d3dzf8AAAAA8BER0d3L/f8AAAAA8BEREdH/vA8AAAAAAB8REdHdvAwAAAAAAL8RERHRv/0AAAAAAPDf3d29H9EPAAAAAADw////v/sAAAAAAAAAAAAAz9EPAAAAAAAAAAAA8P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyAttackRight2\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8A8AAAAAAAAAAAAAv/8AAPAPAAAAAAD/H/sPAAD/AAAAAPAbH7H/AAD/AAAAAPARH/vPD/D/AAAAAL8RwbHP////AAAAAB8REf/M////AAAAAB8R0b3/////AAAAAB8R0RzN////AAAAAB8RER/7//8PAAAAAPARERGx//8AAAAAAPAbERH7DwAAAAAAAAD/3RuxDwAAAAAAAAAA////DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyWalkRight2\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8PAPAPAAAAAAD/3b38AAD/AAAAAPDb3d3L////AAAAAPAR0d27v///AAAAAB8REd27H/v/AAAAAB8REd0dH7H/AAAAAB8REb0cH/sPAAAAAB8REfEfwbEPAAAAAPAREdEd+/8AAAAAAPAbEREdsQ8AAAAAAAD/3d37/wAAAAAAAAAA//8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"skellyWalkFront\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.skellyFront\\\",\\\"sprites.castle.skellyWalkFront1\\\",\\\"sprites.castle.skellyWalkFront2\\\",\\\"sprites.castle.skellyWalkFront3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"skellyAttackFront\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.skellyAttackFront1\\\",\\\"sprites.castle.skellyAttackFront2\\\",\\\"sprites.castle.skellyAttackFront3\\\",\\\"sprites.castle.skellyAttackFront4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"skellyWalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.skellyWalkLeft1\\\",\\\"sprites.castle.skellyWalkLeft2\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"skellyAttackLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.skellyAttackLeft1\\\",\\\"sprites.castle.skellyAttackLeft2\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"skellyWalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.skellyWalkRight1\\\",\\\"sprites.castle.skellyWalkRight2\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"skellyAttackRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.castle.skellyAttackRight1\\\",\\\"sprites.castle.skellyAttackRight2\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"tileGrass2\": {\n        \"data\": \"hwQQABAAAAB1d3d3d3d3d3d30XZ3F3Z3dTcRY3dxcVd3EXbRdxd2d3cRdtF3d3d3dzcRY3d3d3d3d9F2F3Z3d3d3d3dxcXd3d3d3dxd2d3d3V2V3d3d3d3d3d1d1F213d3d3VXYTMXZ3YXdnF2EXfRcXd3cXYRd9d2F3d3cTMXZ3d3d3dxdtdw==\",\n        \"tilemapTile\": true\n    },\n    \"tilePath1\": {\n        \"data\": \"hwQQABAAAAB3d3d3d3d3d3dndmd21nZmd3dm3W3dbd131t3d3d3d3Wfd3d3d3d3bd9bd3d3d3d131t29293d3WfW3b3b3d3dZ93d3d3d3d1n3d3d3d3d3XfW3d3dHdHdZ93d3dEd0d131t3d3d3d3Xfd293d3d3dZ9fd3d3R3d131t3d3d3d2w==\",\n        \"tilemapTile\": true\n    },\n    \"tilePath2\": {\n        \"data\": \"hwQQABAAAABn3d3d3d3d3WfdHdHd3d3dd9Yd0d293d1n193d3d3d3XfXHd3d3d3dZ9bd3d3d3d13Z93dvd3d3Wfd3d3d3d3RZ93d3d3d3d3X3d3d3d3d3WfXHd3d3d3dd9bd3d2929133d3d3b3b3WfW3d3d3d3dd2fd3R3d3R131t3d3d3d3Q==\",\n        \"tilemapTile\": true\n    },\n    \"tilePath3\": {\n        \"data\": \"hwQQABAAAADX3d3R3d3d3Wfd3d3d3d3dd9bd3d3d3d1n1t3dvdvd3Wfd2929293dd93d3d3d3dt31t3d3d3d3XfW3d3d3d3dZ9bd0d3d3d3X3d3d293d3WfdEd3d3dHdd9YR3d3d3d1n3d3d1t3d3XfWbd1n3Wbdd2d2ZndmZ213d3d3d3d3dw==\",\n        \"tilemapTile\": true\n    },\n    \"tileGrass1\": {\n        \"data\": \"hwQQABAAAAB3d3d3d3d3d3d2d3d3d3d3V2V3d3d3d3d3VXZ3d1V2d1V3d3d3d3d3V3V3d3d3d3d3V3V3d3d3d3dVdnd3d3d3d2V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1dld3d3d3d3d3d3d1d3d3d3d3d3d3d3d3d3d3d3dw==\",\n        \"tilemapTile\": true\n    },\n    \"tilePath4\": {\n        \"data\": \"hwQQABAAAAB3d3d3d3d3d2dnd2d21nZ2Zmdm3W3dbdbd1tbd3b3d1t3d3d3d3d3d3d3d3d3d3d0R3d3d3d3d3RHdvd3d3d3d3d3d3d0d3dvd3d3d3RHR3d3R3d3dHd3d3d3d3d3d3d3d3d3du93d3d3d3d273d3d3d3d3d3d3d3d3d3R3d3dHQ==\",\n        \"tilemapTile\": true\n    },\n    \"tilePath5\": {\n        \"data\": \"hwQQABAAAADd3d3d3R3R3d3d3d3dHdHd3d3b3d3d3d0d0d3d3d3d3R3R3d3d3d3d3d3d3dvd3d3d3d3d3d0d3d3d3d3d3d3d3d3d3d3d3d3d3bvd3d3d3d3du93d3d3d3d3d3d3d3d3d3d3d3d3b3b3d3d3d3d3d3d3d3d3d3b3d3d3d3d3d3Q==\",\n        \"tilemapTile\": true\n    },\n    \"tilePath6\": {\n        \"data\": \"hwQQABAAAADd3d3d0d3d3d0d3d3d3d3d3RHR3d3d3dHdHd3d3d3d3d3d3d29293d3d3d3b3b3d3d3d3d3d3d3d3d3d3d3d3d3b3d3d3d3d3d3d3d3d3d3d3d3d3d3dvd3d3d0d3d3d3d3d3dbd3d3d3W3WZ91m3WZmdtZ3Z2bWd3d3d3d3d3dw==\",\n        \"tilemapTile\": true\n    },\n    \"tileGrass3\": {\n        \"data\": \"hwQQABAAAAB1d3d3d3d3d3d3d3d3d3d3dXdnd1d3d1d3d1V2d3d3d3d3V2V3d3d3d1d1d3d3d3d3d1V3d3d3d3d3d1V3d3d3d3dXZXd3dXd3d1d2d3dVd3d3d3d3V1d3d3d3d3dVdnd3d3V3d2V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3VQ==\",\n        \"tilemapTile\": true\n    },\n    \"tilePath7\": {\n        \"data\": \"hwQQABAAAAB3d3d3d3d3d9Z2ZndmZ3Z33Wbddt3WbXfd3d1t3d3ddt3d3d2922133d3d3b3b3XbdHd3d3d3dfd3d3d3d3W123d3d3d3dbXfd3d3d3d1td90R3d3d3d133RHd3dvd3Xbd3d3d3d1tdt3d3d3dEW133d3d3d0R3Xbd3d3b3d3dfQ==\",\n        \"tilemapTile\": true\n    },\n    \"tilePath8\": {\n        \"data\": \"hwQQABAAAADd3d3d3d1td9Hd3dHd3XZ33d3d3d3dbXbd3d3d3dvdd93d3d3d3W133d3du93dfXbd29273d3dfd3d3d3d3d123d3d3d3d3Xbd3d3d3d12d93d3d3d3W123d3d3d3RfXfdEd3d3d19dt0R3d3d3W133d3dvd3d3Xbd3d3d3d3ddg==\",\n        \"tilemapTile\": true\n    },\n    \"tilePath9\": {\n        \"data\": \"hwQQABAAAAC93d3d3d1td93d3R3R3X123d3dHdG93Xfd3d3d3d1td93d3d3d3d123dHd3d3dbXfd3d3d3d3ddt3d3d3R3d123d3d3d3dbXbd3bvd3d1td93du93d3W133d3d3d0d3Xbd3d3d3d1td93W3dbdZnd3ZmdtZ3Zndnd3d3d3d3d3dw==\",\n        \"tilemapTile\": true\n    },\n    \"tileDarkGrass1\": {\n        \"data\": \"hwQQABAAAABnZmZmZmZmZmZmZmZmZmZmZ2aGZnZmZnZmZndoZmZmZmZmdodmZmZmZnZnZmZmZmZmZndmZmZmZmZmZndmZmZmZmZ2h2ZmZ2ZmZnZoZmZ3ZmZmZmZmdnZmZmZmZmZ3aGZmZmdmZodmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdw==\",\n        \"tilemapTile\": true\n    },\n    \"tileDarkGrass2\": {\n        \"data\": \"hwQQABAAAABnZmZmZmZmZmZm0WhmFmhmZzYRg2ZhYXZmEWjRZhZoZmYRaNFmZmZmZjYRg2ZmZmZmZtFoFmhmZmZmZmZhYWZmZmZmZhZoZmZmdodmZmZmZmZmZnZnFo1mZmZmd2gTMWhmgWaGFoEWbRYWZmYWgRZtZoFmZmYTMWhmZmZmZhaNZg==\",\n        \"tilemapTile\": true\n    },\n    \"tileDarkGrass3\": {\n        \"data\": \"hwQQABAAAABmZmZmZmZmZmZoZmZmZmZmdodmZmZmZmZmd2hmZndoZndmZmZmZmZmdmdmZmZmZmZmdmdmZmZmZmZ3aGZmZmZmZodmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnaHZmZmZmZmZmZmZnZmZmZmZmZmZmZmZmZmZmZmZg==\",\n        \"tilemapTile\": true\n    },\n    \"treePine\": \"hwQgACAAAAAAAAAAAAAAwAwAAAAAAAAAAAAAAAAAYMbGDAAAAAAAAAAAAAAAAGBnZgwAAAAAAAAAAAAAAABsZ3ZmbAAAAAAAAAAAAADAzGd3ZswAAAAAAAAAAADAbMdmd3bHAAAAAAAAAAAAfHxnxmd2xgYAAAAAAAAAAHZmZ8dmZ8wMAAAAAAAAAMx2ZnbHZsZmzAAAAAAAAGDHzGx2bMdmdswAAAAAAABsx3xsZnbHZnfHAPAAAABgbGd3bGZ3xmZmbAzwAADAzMdmZsxmZmZmZnYM7wAAwMZnbGZ3ZnZnbGZ3Z+8PAMB8d8d2x2Z3d2xmd8fu/g9sVXdsZmx3d8ZmZsZs7u7+XFV3ZmZ2d2dsZmZnZu7+D8B8dWd3Z3d3d2Z2d2fuDwBgx2dmd3d2d2dmd3dn7w8AYGbHVWdsd3fGdmZ2BuAOAABgzFd3fHd3x3Z3bAbwAAAAAGZlfHZ3dmdmd8cAAAAAAABgZ2Z2d2ZnZnbHAAAAAAAAAGZ3dnbHbHfGZgAAAAAAAAAAdnZmx2Z3dwwAAAAAAAAAAHZ2Z3ZnZncMAAAAAAAAAABgZnx3d2xnAAAAAAAAAAAAAGB2Z3fMZgAAAAAAAAAAAAAAZnd2xmwAAAAAAAAAAAAAAGBnbMYAAAAAAAAAAAAAAABgZsbGAAAAAAAAAAAAAAAAAGAGAAAAAAAAAA==\",\n    \"treeOak\": \"hwQgACAAAAAAAAAABsDMxgwAAAAAAAAAAAAAYGbMbMZsDAAAAAAAAAAAAGBmdmfGZwwAAAAAAAAAAABmZndmdmfMDAAAAAAAAAAAZndmZmfGxswMAAAAAAAAZnZ3ZnZnZsZmDAAAAAAAYHd2Z2d2dnd2x8wAAAAAAGB3ZnZnZnZnd8bMDAAAAABgZnd3Z3dmZsZszAwAAAAAZnZ3d3Z3dmdmd8YAAA4AYHd2d3d3d3d3dmfMDAAOAGB3dnd3d3d3Z2bGZswADgBgd3d3dXd3d3Z3ZmbG8P4AZld1V3V3d2Z3Z2bGzO/+AGZXVVd3d3dnd2Z3Zsbu/wB2d1V3d3d3d2ZmdmfM7v4PdndXVVV3d3dnZmbGzO7u7mB3VXdVdXd3Z3Z3Zszu7g5gV1VXd3d3ZmZmd2fG7v8AAHZ3V3V3d2d3Z8bMzP4PAGB3d1d1d3d3dndmzMzgDgBgd3d3dXdnZmZmZsYMAO4AYHd2d3d3Z3dmZ8bMDADgAGBmd3d3d2d3Z3dmzAAAAAAAYHd2d3Z3dmd2ZswMAAAAAGBndndnd2ZmZmzGDAAAAAAAZmZ2Z2Z3Z2bGzAAAAAAAAHZ2Z2dmdmdsxgwAAAAAAAB2dndmZ2ZmzMYMAAAAAAAAYGBmZnfGxswMAAAAAAAAAAAAZmB2xszMDAAAAAAAAAAAAGDAbMYMAAAAAAAAAA==\",\n    \"treeSmallPine\": \"hwQQABgAAAAAAAAAAADAzAAAAAAAAAAAwMxsxwwAAAAAAGDMbGd8d8YAAAAAAMxnfHdnd8cMAAAAzGx2xnfHd2YMAADAxmZ2x3bGdmfMAA5sZ2x2d3ZndnfG4A5cd3Z2Z3Z3dmfM7u52dXZ3Z3ZndmbG7u5mZ3Z2d3ZmdmfG4A7AZsd2Z3dndnfMAA4AbMx3Zndnd2cMAAAAAGxnfHdmd2YMAAAAAMDGbGd2d8cAAAAAAAAAwGx2ZwwAAAAAAAAAAABmxgAAAAA=\"\n}","sprites.castle.ts":"namespace sprites.castle {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroFrontAttack1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroFrontAttack2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroFrontAttack3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroFrontAttack4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroSideAttackLeft1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroSideAttackLeft2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroSideAttackLeft3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroSideAttackLeft4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroSideAttackRight4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroSideAttackRight3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroSideAttackRight2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroSideAttackRight1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkFront1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkFront2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkFront3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkFront4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkBack1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkBack2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkBack3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkBack4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldFront1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldFront2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldFront3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldFront4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldBack1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldBack2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldBack3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldBack4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldSideLeft1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldSideLeft2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldSideLeft3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldSideLeft4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldSideRight4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldSideRight3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldSideRight2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkShieldSideRight1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkSideLeft1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkSideLeft2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkSideLeft3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkSideLeft4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkSideRight4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkSideRight3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkSideRight2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const heroWalkSideRight1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"buildings\"\n    export const houseRed = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"buildings\"\n    export const houseBlue = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princessFront0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princessFront1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princessFront2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princessLeft0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princessLeft1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princessLeft2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princessBack0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princessBack1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princessBack2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princess2Front = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princess2WalkFront1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princess2WalkFront2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princess2WalkFront3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princess2Back = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princess2WalkBack1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princess2WalkBack2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princess2WalkBack3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princess2Left1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princess2Left2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princess2Right1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people\"\n    export const princess2Right2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile misc\"\n    export const rock0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile misc\"\n    export const rock1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile misc\"\n    export const rock2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile misc\"\n    export const saplingOak = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile misc\"\n    export const saplingPine = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile misc\"\n    export const shrub = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyFront = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyWalkFront1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyWalkFront2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyWalkFront3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyAttackFront1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyAttackFront2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyAttackFront3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyAttackFront4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyWalkLeft1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyAttackLeft1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyAttackLeft2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyWalkLeft2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyWalkRight1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyAttackRight1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyAttackRight2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const skellyWalkRight2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tileGrass2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tilePath1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tilePath2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tilePath3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tileGrass1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tilePath4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tilePath5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tilePath6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tileGrass3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tilePath7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tilePath8 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tilePath9 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tileDarkGrass1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tileDarkGrass2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest\"\n    export const tileDarkGrass3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const treePine = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const treeOak = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const treeSmallPine = image.ofBuffer(hex``);\n}\n","sprites.dialog.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.dialog\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"bones\": \"hwRCAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAD/DwAAAAAAAP8PAAAA8P8AAAAAAAAAAAAAAADfvQ8AAAAAAPDb+wAAAAAA8Nv7AAAAv90PAAAAAAAAAAAAAPC/3f8A/w8A///d/QAAAAD//939AADwu90PAAAAAAAAAAAAAPDd3d3/3f//273dvf/////bvd29////3d0PAAAAAAAAAAAAAPDdzNvd3d/d3b3b3d3d3d3dvdvd3d393d39AAD/DwAAAAAAAAD/3bvd+9/d3bvd3d3d3d3du93d3d3d///dD/Dd/w8AAAAAAADw3cvc/f7/273dvf/////bvd29///f3f/f/f/d2w8AAAAAAADw3d38/+7u3/3b++7u7u7f/dv77u7+/+//3d3c3Q8AAAAAAADf3d3v7u7u////7+7u7u7////v7u7u7u7+3d3cvQ8AAAAAAPDd///v7u7u7u7u7u7u7u7u7u7u7u7u7u7+3bvb/wAAAAAA/9/97+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+3bzdDwAAAADw3d3/7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+z9z9AAAAAADw3d3/7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/t39AAAAAADwu93f7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/r3dDwAAAAAAv93f7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v/dDwAAAAAA8P/d7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7/DwAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/9u9DwAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u393dDwAAAAAA/9u97+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u373dDwAAAADw293d++7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/7u7/wAAAADw3d3d/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uv93bvQ8AAADw273d++7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u393d3Q8AAAAA/7u7/+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uv93dvQ8AAAAA8N3b/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/tu9/wAAAAAA8N3d/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAA8Nu9/+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/9u9DwAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u393dDwAAAAAA/9u97+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u373dDwAAAADw293d++7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/7u7/wAAAADw3d3d/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uv93bvQ8AAADw273d++7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u393d3Q8AAAAA/7u7/+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uv93dvQ8AAAAA8N3b/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/tu9/wAAAAAA8N3d/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAA8Nu9/+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAA8P/v7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/t3/DwAAAAAA8N3/7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v3d+wAAAAAA8N3b7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v3duw8AAAAAAN/d7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v/d3Q8AAAAAAN/N/O/u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v/d3Q8AAAAA8N3L3e/u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/t/9/wAAAAAA/7273e/u7u7u7u7u7u7u7u7u7u7u7u7u7v7//90PAAAAAADw283d3e/u7u7u7v7////u7u7u/v///+7u7v7d3f0AAAAAAADw3c3d3f/+/+/u7r+93/3u7u7uv73f/e7u/8/d3Q8AAAAAAADwvd3/3/3/3f3//9vd273/////293bvf/v38283Q8AAAAAAADw/90P8N3//93d3d3du93d3d3d3d273d39v9273f8AAAAAAAAA8P8AAN/d3d/d3d29293d3d3d3b3b3d393d29zN0PAAAAAAAAAAAAAPDd3f///9vd273/////293bvf//3f/d3d0PAAAAAAAAAAAAAPDduw8AAN/d//8AAAAA393//wDw/wD/3fsPAAAAAAAAAAAAAPDd+wAAAL+9DwAAAAAAv70PAAAAAADw2/0AAAAAAAAAAAAAAAD/DwAAAPD/AAAAAAAA8P8AAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"cityscape\": \"hwQwADAAAACZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3QCZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3Q2ZmZmZmRGZmZmZERGZGRGR3R0dHR0d3d2ZGRGRGRGREZEZERGRERER0d3d3d3d3d2ZERERGRERERERERERERERERERERER3d2ZEREREREREREREREREREREREREdHd3d2ZERERERERERERERERERERERHR3d3d3d2ZERERERERERERERERERERERHd0dHR3d2ZGRERERERERERERERERERERHd3d3d3d2ZGRERERERERERERERERERERHd0dHR3d2ZmRERERERERERERERERERERHR3d3d3d2ZGREREREREREREREREREREREREdHd3d2ZEREREREREREREREREREREREREdHd3d2ZEREREREREREREREREREREdHd3d3d3d2ZGREREREREREREREREREREd3R0dHR3d2ZmREREREREREREREREREREd3R0dHR3d2ZGREREREREREREREREREREdHR0dHR3d2ZEREREREREREREREREREREdHd3d3d3d2ZERERERERERERERERERERERERERHd3d2ZERERERERERERERERERERERER3d3d3d2ZERERERERERERERERERERERER3d3d3d2ZGRERERERERERERERERERERERERHd3d2ZmRERERERERERERERERERERHd3d3d3d2ZGRERERERERERERERERERERHd0R3d0d2ZERERERERERERERERERERERHd3d3d3d2ZERERERERERERERERERERERHdHd3RHd2ZERERERERERERERERERERERHd3d3d3d2ZEREREREREREREREREREREREREdHd3d2ZGREREREREREREREREREREREREdHd3d2ZmREREREREREREREREREREdHd3d3d3d2ZmREREREREREREREREREREdHR0dHR3d2ZGREREREREREREREREREREdHR0dHR3d2ZGREREREREREREREREREREdHR0dHR3d2ZGREREREREREREREREREREdHd3d3d3d2ZmRERERERERERERERERERERER0d3d3d2ZGRERERERERERERERERERERER0d3d3d2ZERERERERERERERERERERERHd3d3d3d2ZERERERERERERERERERER3d0d3R3dHd2ZGRERERERERERERERERER3d3dHd0d3d2ZmRkREREREREREREREREREdHd3d3d3d2ZmRERERERERERERERERERERER3d3d3d2ZGRERERERERERERERERERERER3d3d3d2ZGRERERERERERERERERERERERHR0dHd2ZGREREREREREREREREREREd3dHR0dHd2ZGRERERkRkRERERkREZEZEd3dHR0dHd2ZmRERmZkRmRkRkZkREZmZEdHd3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3Q2ZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3QA=\",\n    \"desert\": \"hwRCAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzYwYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzZgcAAAAwMxMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzMzNjZjYzdgcAAAAwMzMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzMzN2d2YzdgcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzMzNmZmczdgcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzZmczZgcAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzY2ZmZmdmZgYAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzdnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzY2ZmZ2ZmZgYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzM3Z3ZzNjdgcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2ZmNjNmdwcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2dwcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N2dwcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N3dwcAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N2dwcAAAAwMxMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2dwcAAAAwMzMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzM2NmZjZmdwcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzM2N3d2ZjdgcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzMzNmdmdmZgYAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzY2Zmdnd3dwcAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzY2ZmZnZmZgYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzZndmZgYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNjd2dmdgcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNjZjZmdwcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2dwcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N2dwcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N3dwcAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N2dwcAAAAwMxMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2dwcAAAAwMzMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzM2NmZjZmdwcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzM2N3d2ZjdgcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzMzNmdmdmZgYAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzY2Zmdnd3dwcAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzY2ZmZnZmZgYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzZndmZgYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNjd2dmdgcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNjZjZmdwcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2dwcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N2dwcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N3dwcAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N2dwcAAAAwMxMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2dwcAAAAwMzMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzM2ZmNjNmdwcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzM3Z3ZzNjdgcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzY2ZmZ2ZmZgYAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzdnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzY2ZmZmdmZgYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzZmczZgcAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNmZmczdgcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2d2YzdgcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNjZjYzdgcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzZgcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzYwYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"frogs\": \"hwRCAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZmYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGBmBgAAAAAAYGZmd90GYGZmBgAAAABmZmYGAAAAAGZmBgAAYHbXbQAAAAAAhmg3c9ZtZpmZZgYAAGaWmZlmBgAAZpaZZgaIdjNn3QYAAAAAeHc3c9ZtmZmZmWYAYJaZmZmZZgBglpmZmYZ3dzNn3QYAAACAd4h3d9ZtmZmZmWlmZpmZmZmZaWZmmZmZmXiHeHdn3QYAAACAd4h3Z91tmZmZmZmZmZmZmZmZmZmZmZmZmXiHeHfW3QYAAACAd3d31t1tmZmZmZmZmZmZmZmZmZmZmZmZmXh3d2fd3QYAAAAAeHd31t1tmZmZmZmZmZmZmZmZmZmZmZmZmYl3d2fd3QYAAAAAeHd31t1tmZmZmZmZmZmZmZmZmZmZmZmZmYl3d2fd3QYAAACAd3d31t1tmZmZmZmZmZmZmZmZmZmZmZmZmXh3d2fd3QYAAACAd4h3Z91tmZmZmZmZmZmZmZmZmZmZmZmZmXiHeHfW3QYAAACAd4h3d9ZtmZmZmZmZmZmZmZmZmZmZmZmZmXiHeHdn3QYAAAAAeHc3c9ZtmZmZmZmZmZmZmZmZmZmZmZmZmYl3dzNn3QYAAAAAgGg3c9ZtmZmZmZmZmZmZmZmZmZmZmZmZmZmIdjNn3QYAAAAAZplmd92WmZmZmZmZmZmZmZmZmZmZmZmZmZmZaXbXbQAAAAAAlplpZmaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmWZmZgAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAZpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAYJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZgAAAAAAYJaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZBgAAAAAAAGaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlpBgAAAAAAAGCZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlmAAAAAAAAAGCZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkGAAAAAAAAAGCZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkGAAAAAAAAAGaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkGAAAAAAAAYJaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlmAAAAAAAAYJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlpBgAAAAAAZpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZBgAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZgAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAZpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAYJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZgAAAAAAYJaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZBgAAAAAAAGaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlpBgAAAAAAAGCZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlmAAAAAAAAAGCZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkGAAAAAAAAAGCZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkGAAAAAAAAAGaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkGAAAAAAAAYJaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlmAAAAAAAAYJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlpBgAAAAAAZpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZBgAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZgAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAlplpZmaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmWZmZgAAAAAAZplmd92WmZmZmZmZmZmZmZmZmZmZmZmZmZmZaXbXbQAAAAAAgGg3c9ZtmZmZmZmZmZmZmZmZmZmZmZmZmZmIdjNn3QYAAAAAeHc3c9ZtmZmZmZmZmZmZmZmZmZmZmZmZmYl3dzNn3QYAAACAd4h3d9ZtmZmZmZmZmZmZmZmZmZmZmZmZmXiHeHdn3QYAAACAd4h3Z91tmZmZmZmZmZmZmZmZmZmZmZmZmXiHeHfW3QYAAACAd3d31t1tmZmZmZmZmZmZmZmZmZmZmZmZmXh3d2fd3QYAAAAAeHd31t1tmZmZmZmZmZmZmZmZmZmZmZmZmYl3d2fd3QYAAAAAeHd31t1tmZmZmZmZmZmZmZmZmZmZmZmZmYl3d2fd3QYAAACAd3d31t1tmZmZmZmZmZmZmZmZmZmZmZmZmXh3d2fd3QYAAACAd4h3Z91tmZmZmZmZmZmZmZmZmZmZmZmZmXiHeHfW3QYAAACAd4h3d9ZtmZmZmWZmlpmZmZmZZmaWmZmZmXiHeHdn3QYAAAAAeHc3c9ZtmZmZaQYAZpmZmZlpBgBmmZmZmYZ3dzNn3QYAAAAAhmg3c9ZtZplpZgAAYGaZmWlmAABgZpmZZgaIdjNn3QYAAAAAYGZmd90GYGZmAAAAAGBmZmYAAAAAYGZmBgAAYHbXbQAAAAAAAABgZmYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZmBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"hugeLeaf\": \"hwQwADAAAACIiAAAiAAAiAgAgAiIAACICACACAAAiIhod4iAZwiAdoYAaIdnCIB2hgBohwCId4Z4dmeId4doZ2eId4d3h2hnZ4h3h4h2Z4d4Z3eGZ3d4Z3d4Z2dnd3hnd3hnZ2h3doeAd3hmd3Z4Z3d4dmd3dnhnd3h2Z2aHdwiAdodmdmZoZ2dodoZ2ZmhnZ2h2hmZ4ZwgAaGZoaGeIhoaIZ4hoZ4iGhmhniIZmhgAAgGaGiIiIiIiIiIiIiIiIiIiIiGiGiIiAaIaIZmZmZmZmZmZmZmZmZmZmZoh2d4d4d2eIZmZmZmZmZmZmZmZmZmZmZmh3doZoZ3eGZmZmZmZmZmZmZmZmZmZmZnhmdwiAd2aHZmZmZmZmZmZmZmZmZmZmZmh2hwAAeGeGZmZmZmZmZmZmZmZmZmZmZoiIiAAAiIiIZmZmZmZmZmZmZmZmZmZmZoh2ZwiAdmeIZmZmZmZmZmZmZmZmZmZmZmh3d4Zod3eGZmZmZmZmZmZmZmZmZmZmZohmZod4ZmaIZmZmZmZmZmZmZmZmZmZmZmh3d4Zod3eGZmZmZmZmZmZmZmZmZmZmZoh2ZwiAdmeIZmZmZmZmZmZmZmZmZmZmZoiIiAAAiIiIZmZmZmZmZmZmZmZmZmZmZmh2hwAAeGeGZmZmZmZmZmZmZmZmZmZmZnhmdwiAd2aHZmZmZmZmZmZmZmZmZmZmZmh3doZoZ3eGZmZmZmZmZmZmZmZmZmZmZoh2d4d4d2eIZmZmZmZmZmZmZmZmZmZmZohohgiAaIaIZmZmZmZmZmZmZmZmZmZmZoh2d4d4d2eIZmZmZmZmZmZmZmZmZmZmZmh3doZoZ3eGZmZmZmZmZmZmZmZmZmZmZnhmdwiAd2aHZmZmZmZmZmZmZmZmZmZmZmh2hwAAeGeGZmZmZmZmZmZmZmZmZmZmZoiIiAAAiIiIZmZmZmZmZmZmZmZmZmZmZoh2ZwiAdmeIZmZmZmZmZmZmZmZmZmZmZmh3d4Zod3eGZmZmZmZmZmZmZmZmZmZmZohmZod4ZmaIZmZmZmZmZmZmZmZmZmZmZmh3d4Zod3eGZmZmZmZmZmZmZmZmZmZmZoh2ZwiAdmeIZmZmZmZmZmZmZmZmZmZmZoiIiAAAiIiIZmZmZmZmZmZmZmZmZmZmZmh2hwAAeGeGZmZmZmZmZmZmZmZmZmZmZnhmdwiAd2aHZmZmZmZmZmZmZmZmZmZmZmh3doZoZ3eGZmZmZmZmZmZmZmZmZmZmZoh2d4d4d2eIZmZmZmZmZmZmZmZmZmZmZohohgiIiGiGiIiIiIiIiIiIiIiIiIiIiGhmCAAAaGZoiHaGaGiIdoaIdoZoaIh2hoZmhgCAdodmaGeGdnaGZmdoZ4Z2doZmZ2Z4ZwiAd3hmdmeHd3aHZ3d2Z4d3dodnd2aHdwh4Z3eGdnaHd3aHd3Z2dod3dod3dmh3dod4dmeIeHeIdnaGeHd4d4h2doZ4d4h2Z4dod4gAeIYAaGcIgHZ4hgBoZwiAdgiId4aIiAAAgAgAgIgAAIiACACAiAAAiAAAiIg=\",\n    \"largeShell\": \"hwQqACoAAAAAzMwMADMDAAAzAwAAMwMAwMzMAAAAAADAMzvDMJk5ADCZOQAwmTkAPLMzDAAAAAA8O7M7nJmZM5OZmTOTmZnGszuzwwAAAAA8szM7nBGRmZkRkZmZEZHJszM7wwAAAAC8MzuzHJkZmRmZGZkZmRnJO7MzywAAAAA8O7O7vJmZEZGZmRGRmZnLuzuzwwAAAAA8u7PbsRERmRkREZkZEREbvTu7wwAAAADAM7sdGxERERERERERERGx0bszDAAAAAAAzMyxERERERERERERERERG8zMAAAAAAAAk7kbERERERERERERERERsRuZAwAAAAAwmZEREREREREREREREREREZmROQAAAACTGZkREREREREREREREREREZmROQAAAACTGZkREREREREREREREREREZmROQAAAACTGZkRERERERERERERERERERmZAwAAAAAwmZERERERERERERERERERkZE5AAAAAAAAkxkZERERERERERERERERkZE5AAAAAAAAkxkZERERERERERERERERkZE5AAAAAAAAkxkZERERERERERERERERERmZAwAAAAAwmZEREREREREREREREREREZmROQAAAACTGZkREREREREREREREREREZmROQAAAACTGZkREREREREREREREREREZmROQAAAACTGZkRERERERERERERERERERmZAwAAAAAwmZERERERERERERERERERkZE5AAAAAAAAkxkZERERERERERERERERkZE5AAAAAAAAkxkZERERERERERERERERkZE5AAAAAAAAkxkZERERERERERERERERERmZAwAAAAAwmZEREREREREREREREREREZmROQAAAACTGZkREREREREREREREREREZmROQAAAACTGZkREREREREREREREREREZmROQAAAACTGZkRERERERERERERERERERmZAwAAAAAwmbEbERERERERERERERERsZs5AAAAAAAAzMyxERERERERERERERERG8zMAAAAAADAM7sdGxERERERERERERGx0bszDAAAAAA8u7PbsRERkZkREZGZEREbvTu7wwAAAAA8O7O7vJmZGRGZmRkRmZnLuzuzwwAAAAC8MzuznJGZkZmRmZGZkZnBO7MzywAAAAA8szM7nBkRmZkZEZmZGRHJszM7wwAAAAA8O7M7PJmZOTOZmTkzmZnJszuzwwAAAADAMzvDAJOZAwCTmQMAk5kDPLMzDAAAAAAAzMwMADAzAAAwMwAAMDMAwMzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"largeStar\": \"hwQqACoAAAAAsMsAAAAAAAAAAAAAAAAAALDLAAAAAAAAXLvMALC7uwCwu7sAsLu7AFy7zAAAAADAW1W1u7vdvbu73b27u929y1tVtQAAAABcVVW7EdvdGxHb3RsR2927XFVVuwAAAABcVVW7EbG9ERGxvRERsb3bXFVVuwAAAADAW1W1ERHdHRER3R0REd0RwVtVtQAAAAAAXLvMEdER0RHREdER0REREVy7zAAAAAAAu8sREREREREREREREREREb3LAAAAAACwvdsREREREREREREREREREd29AAAAAACw3dsRERERERERERERERERERG9AAAAAACw3d0RERERERERERERERERERGxAAAAAACw2xsdERERERERERERERERERGxAAAAAAAAuxERERERERERERERERERERG7AAAAAAAAGxERERERERERERERERER0bG9CwAAAAAAGxEREREREREREREREREREd3dCwAAAACwGxEdEREREREREREREREREb3dCwAAAACwvdERERERERERERERERERER3bCwAAAACw3dsRERERERERERERERER0RGxCwAAAACw3d0RERERERERERERERERERGxAAAAAACw2xsdERERERERERERERERERGxAAAAAAAAuxERERERERERERERERERERG7AAAAAAAAGxERERERERERERERERER0bG9CwAAAAAAGxEREREREREREREREREREd3dCwAAAACwGxEdEREREREREREREREREb3dCwAAAACwvdERERERERERERERERERER3bCwAAAACw3dsRERERERERERERERER0RGxCwAAAACw3d0RERERERERERERERERERGxAAAAAACw2xsdERERERERERERERERERGxAAAAAAAAuxERERERERERERERERERERG7AAAAAAAAGxERERERERERERERERER0bG9CwAAAAAAGxEREREREREREREREREREd3dCwAAAAAA2xEdEREREREREREREREREb3dCwAAAAAAu8sdEREREREREREREREREb3LCwAAAAAAXLvMEREREREREREREREREVy7zAAAAADAW1W1HREdER0RHREdER0RzVtVtQAAAABcVVW73d0REdHdERHR3RERXFVVuwAAAABcVVW7vdsbERHbGxER2xsRXFVVuwAAAADAW1W1u929EbHdvRGx3b0RzVtVtQAAAAAAXLvM2927u9vdu7vb3bu7u1y7zAAAAAAAsMsAsLsLALu7CwC7uwsAALDLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"mediumStar\": \"hwQhACEAAAAAsMsAAAAAAAAAAAAAsMsAAAAAAABcu8wAsLu7ALC7uwBcu8wAAAAAwFtVtbu73b27u929y1tVtQAAAABcVVW7EdvdGxHb3btcVVW7AAAAAFxVVbsRsb0REbG921xVVbsAAAAAwFtVtRER3R0REd0RwVtVtQAAAAAAXLvMEdER0RHRERERXLvMAAAAAAC7yxERERERERERERG9ywAAAAAAsL3dERERERERERERER3bCwAAAACw3dsRERERERERERHREbELAAAAALDd3RERERERERERERERsQAAAAAAsNsbHRERERERERERERGxAAAAAAAAuxEREREREREREREREbsAAAAAAAAbEREREREREREREdGxvQsAAAAAABsREREREREREREREd3dCwAAAACwGxEdERERERERERERvd0LAAAAALC90REREREREREREREd2wsAAAAAsN3bERERERERERER0RGxCwAAAACw3d0REREREREREREREbEAAAAAALDbGx0RERERERERERERsQAAAAAAALsRERERERERERERERG7AAAAAAAAGxERERERERERERHRsb0LAAAAAAAbERERERERERERERHd3QsAAAAAANsRHREREREREREREb3dCwAAAAAAu8sdERERERERERERvcsLAAAAAABcu8wRERERERERERFcu8wAAAAAwFtVtR0RHREdER0RzVtVtQAAAABcVVW70d0REdHdERFcVVW7AAAAAFxVVbsR2xsREdsbEVxVVbsAAAAAwFtVtbHdvRGx3b0RzVtVtQAAAAAAXLvM2927u9vdu7u7XLvMAAAAAACwywC7uwsAu7sLAACwywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"mediumShell\": \"hwQhACEAAAAAzMwMADMDAAAzAwDAzMwAAAAAAMAzO8MwmTkAMJk5ADyzMwwAAAAAPDuzO5yZmTOTmZnGszuzwwAAAAA8szM7nBGRmZkRkcmzMzvDAAAAALwzO7McmRmZGZkZyTuzM8sAAAAAPDuzu7yZmRGRmZnLuzuzwwAAAAA8u7PbsRERmRkRERu9O7vDAAAAAMAzux0bERERERERsdG7MwwAAAAAAMzMsRERERERERERG8zMAAAAAAAAk7kbERERERERERGxG5kDAAAAADCZkRERERERERERERGZkTkAAAAAkxmZEREREREREREREZmROQAAAACTGZkRERERERERERERmZE5AAAAAJMZmREREREREREREREZmQMAAAAAMJmRERERERERERERkZE5AAAAAAAAkxkZERERERERERGRkTkAAAAAAACTGRkREREREREREZGROQAAAAAAAJMZGRERERERERERERmZAwAAAAAwmZERERERERERERERmZE5AAAAAJMZmRERERERERERERGZkTkAAAAAkxmZEREREREREREREZmROQAAAACTGZkRERERERERERERGZkDAAAAADCZsRsREREREREREbGbOQAAAAAAAMzMsRERERERERERG8zMAAAAAADAM7sdGxEREREREbHRuzMMAAAAADy7s9uxERGRmRERG707u8MAAAAAPDuzu7yZmRkRmZnLuzuzwwAAAAC8MzuznJGZkZmRmcE7szPLAAAAADyzMzucGRGZmRkRybMzO8MAAAAAPDuzOzyZmTkzmZnJszuzwwAAAADAMzvDAJOZAwCTmQM8szMMAAAAAADMzAwAMDMAADAzAMDMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"mediumLeaf0\": \"hwQhACEAAACIiAAAiAAAiAgAgAgAAIiIAAAAAGh3iIBnCIB2hgBohwCId4YAAAAAeHZniHeHaGdniHeHiHZnhwAAAAB4Z3eGZ3d4Z3d4Z2dod3aHAAAAAIB3eGZ3dnhnd3h2Z2aHdwgAAAAAgHaHZnZmaGdnaHaGZnhnCAAAAAAAaGZoaGeIhoZoZ4iGZoYAAAAAAACAZoaIiIiIiIiIiGiGiIgAAAAAgGiGiGZmZmZmZmZmiHZ3hwAAAAB4d2eIZmZmZmZmZmZod3aGAAAAAGhnd4ZmZmZmZmZmZnhmdwgAAAAAgHdmh2ZmZmZmZmZmaHaHAAAAAAAAeGeGZmZmZmZmZmaIiIgAAAAAAACIiIhmZmZmZmZmZoh2ZwgAAAAAgHZniGZmZmZmZmZmaHd3hgAAAABod3eGZmZmZmZmZmaIZmaHAAAAAHhmZohmZmZmZmZmZmh3d4YAAAAAaHd3hmZmZmZmZmZmiHZnCAAAAACAdmeIZmZmZmZmZmaIiIgAAAAAAACIiIhmZmZmZmZmZmh2hwAAAAAAAHhnhmZmZmZmZmZmeGZ3CAAAAACAd2aHZmZmZmZmZmZod3aGAAAAAGhnd4ZmZmZmZmZmZoh2d4cAAAAAeHdniGZmZmZmZmZmiGiGCAAAAACIiGiGiIiIiIiIiIhoZggAAAAAAABoZmiIdoZoaIh2hoZmhgAAAAAAgHaHZmhnhnZ2hmZnZnhnCAAAAACAd3hmdmeHd3aHZ3dmh3cIAAAAAHhnd4Z2dod3dod3dmh3docAAAAAeHZniHh3iHZ2hnh3iHZnhwAAAABod4gAeIYAaGcIgHYIiHeGAAAAAIiIAACACACAiAAAiAAAiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"mediumLeaf1\": \"hwQhACEAAACIiAgAiIiIiIiIiIgAAIiIAAAAAHh3hoh4d3h3eHd4d4iIdocAAAAAeHd3iHZ2eHZ2dnh2hnZ3hwAAAABoZ3eGZ3Z2Zmd2dmZnd3aHAAAAAIh3doZnd3ZnZ3d2Z2dnd4YAAAAAgHZnhmdnaHdnZ2h3h3Z3CAAAAACAaIaIiIiIiIiIiIiIZoYIAAAAAIh2d4hmZmZmZmZmZoiIiIgAAAAAeGd2aGZmZmZmZmZmhndniAAAAAB4ZndoZmZmZmZmZmaGZnaHAAAAAHh3Z2hmZmZmZmZmZoZ3ZocAAAAAiGiGaGZmZmZmZmZmhnZ3hwAAAAB4d2doZmZmZmZmZmaGaIaIAAAAAHhmd2hmZmZmZmZmZoZ2d4cAAAAAeGdmaGZmZmZmZmZmhndmhwAAAACIdndoZmZmZmZmZmaGZ3aHAAAAAHhndmhmZmZmZmZmZoZ3Z4gAAAAAeGZ3aGZmZmZmZmZmhmZ2hwAAAAB4d2doZmZmZmZmZmaGd2aHAAAAAIhohmhmZmZmZmZmZoZ2d4cAAAAAeHdnaGZmZmZmZmZmhmiGiAAAAAB4ZndoZmZmZmZmZmaGdneHAAAAAHhnZmhmZmZmZmZmZoZ3ZocAAAAAgHZ3aGZmZmZmZmZmhmd2hwAAAACAiIiIZmZmZmZmZmaId2cIAAAAAIBoZoiIiIiIiIiIiIhohggAAAAAgHdneHeGdnZ3hnZ2aHZnCAAAAABod3Z2dmd3dnZnd3ZoZ3cIAAAAAHhnd3ZmZ2d2Zmdndmh3doYAAAAAeHdnaGeHZ2dnh2dniHd3hwAAAAB4Z4iId4d3h3eHd4eIaHeHAAAAAIiIAACIiIiIiIiIiACAiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"pineday\": \"hwQwADAAAAARERERERERERERERERERERERERERERmZkRkZmZmZmZmZmZmZmZmZmZmZmWaZmWZpYRmZmZmZmZmZmZmZmZmZmZmZlmaWZmZpYRmZmZmZmZmZmZmZmZmZmZaWZmZmZmZpaRmZmZmZmZmZmZmZmZmZmZmWlplmaWZpaRmZmZmZmZmZmZmZmZmZmZmZmZlmaZZpaRmZmZmZmZmZmZmZmZmZmZmZmZmZmZlpYRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZYRmZmZmZmZmZmZmZmZmZmZmZmZmZlpaZYRkZmZmZmZmZmZmZmZmZmZmZmZmZlmZpYRkZmZmZmZmZmZmZmZmZmZmZmZaWZmZpYRkZmZmZmZmZmZmZmZmZmZmZlpaWZmZpYRmZmZmZmZmZmZmZmZmZmZmWZmZmZmZpYRmZmZmZmZmZmZmZmZmZmZmWlpaWZmZpYRmZmZmZmZmZmZmZmZmZmZmZmZaZmWZpYRmZmZmZmZmZmZmZmZmZmZmZmZmZmZZpYRkZmZmZmZmZmZmZmZmZmZmZmZmZmZZpYRkZmZmZmZmZmZmZmZmZmZmZmZmZZmZpYRmZmZmZmZmZmZmZmZmZmZmZlpZmZmZpYRmZmZmZmZmZmZmZmZmZmZmZmZaWZmZpaRmZmZmZmZmZmZmZmZmZmZmZmZmZZmZpaRmZmZmZmZmZmZmZmZmZmZmZmZmZmZZpaRmZmZmZmZmZmZmZmZmZmZmZmZmZmZZpYRmZmZmZmZmZmZmZmZmZmZmZmZmZmZZpYRmZmZmZmZmZmZmZmZmZmZmZmZmZlpZpYRkZmZmZmZmZmZmZmZmZmZmZmZmZZmZpYRkZmZmZmZmZmZmZmZmZmZmZmZZmZmZpYRkZmZmZmZmZmZmZmZmZmZmZlmZmZmZpYRmZmZmZmZmZmZmZmZmZmZmZmZlpZmZpYRmZmZmZmZmZmZmZmZmZmZmZmZmZaWZpYRmZmZmZmZmZmZmZmZmZmZmZmZmZmZZpYRmZmZmZmZmZmZmZmZmZmZmZmZmZmZZpYRkZmZmZmZmZmZmZmZmZmZmZmZmZZmZpYRkZmZmZmZmZmZmZmZmZmZmZlpmWZmZpYRmZmZmZmZmZmZmZmZmZmZmWZmZmZmZpYRmZmZmZmZmZmZmZmZmZmZmZmWZmlmZpaRmZmZmZmZmZmZmZmZmZmZmZmZaZlpZpaRmZmZmZmZmZmZmZmZmZmZmZmZmZlmZpaRmZmZmZmZmZmZmZmZmZmZmZmZmZlmZpYRmZmZmZmZmZmZmZmZmZmZmZmZlmZmZpYRmZmZmZmZmZmZmZmZmZmZmZZmZmZmZpYRkZmZmZmZmZmZmZmZmZmZaWZmZmZmZpYRkZmZmZmZmZmZmZmZmZmZmZmWlmZmZpYRkZmZmZmZmZmZmZmZmZmZmZmZmWlmZpYRmZmZmZmZmZmZmZmZmZmZmZlpaWZmZpYRmZmZmZmZmZmZmZmZmZmZmWlmZmZmZpYRmZmZmZmZmZmZmZmZmZmZmZmZaWlmZpYRERERERERERERERERERERERERERGZmZk=\",\n    \"pinenight\": \"hwQwADAAAACZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiYiIiIiIiIiIiIiIiIiIiIiGaIiGZpaZiIiIiIiIiIiIiIiIiIiIiIhmaGZmZpaZiIiIiIiIiIiIiIiIiIiIaGZmZmZmZpaJiIiIiIiIiIiIiIiIiIiIiGhohmaGZpaJiIiIiIiIiIiIiIiIiIiIiIiIhmaIZpaJiIiIiIiIiIiIiIiIiIiIiIiIiIiIhpaZiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJaZiIiIiIiIiIiIiIiIiIiIiIiIiIhoaJaZiYiIiIiIiIiIiIiIiIiIiIiIiIhmZpaZiYiIiIiIiIiIiIiIiIiIiIiIaGZmZpaZiYiIiIiIiIiIiIiIiIiIiIhoaGZmZpaZiIiIiIiIiIiIiIiIiIiIiGZmZmZmZpaZiIiIiIiIiIiIiIiIiIiIiGhoaGZmZpaZiIiIiIiIiIiIiIiIiIiIiIiIaIiGZpaZiIiIiIiIiIiIiIiIiIiIiIiIiIiIZpaZiYiIiIiIiIiIiIiIiIiIiIiIiIiIZpaZiYiIiIiIiIiIiIiIiIiIiIiIiIZmZpaZiIiIiIiIiIiIiIiIiIiIiIhoZmZmZpaZiIiIiIiIiIiIiIiIiIiIiIiIaGZmZpaJiIiIiIiIiIiIiIiIiIiIiIiIiIZmZpaJiIiIiIiIiIiIiIiIiIiIiIiIiIiIZpaJiIiIiIiIiIiIiIiIiIiIiIiIiIiIZpaZiIiIiIiIiIiIiIiIiIiIiIiIiIiIZpaZiIiIiIiIiIiIiIiIiIiIiIiIiIhoZpaZiYiIiIiIiIiIiIiIiIiIiIiIiIZmZpaZiYiIiIiIiIiIiIiIiIiIiIiIZmZmZpaZiYiIiIiIiIiIiIiIiIiIiIhmZmZmZpaZiIiIiIiIiIiIiIiIiIiIiIiIhoZmZpaZiIiIiIiIiIiIiIiIiIiIiIiIiIaGZpaZiIiIiIiIiIiIiIiIiIiIiIiIiIiIZpaZiIiIiIiIiIiIiIiIiIiIiIiIiIiIZpaZiYiIiIiIiIiIiIiIiIiIiIiIiIZmZpaZiYiIiIiIiIiIiIiIiIiIiIhoiGZmZpaZiIiIiIiIiIiIiIiIiIiIiGZmZmZmZpaZiIiIiIiIiIiIiIiIiIiIiIiGZmhmZpaJiIiIiIiIiIiIiIiIiIiIiIiIaIhoZpaJiIiIiIiIiIiIiIiIiIiIiIiIiIhmZpaJiIiIiIiIiIiIiIiIiIiIiIiIiIhmZpaZiIiIiIiIiIiIiIiIiIiIiIiIhmZmZpaZiIiIiIiIiIiIiIiIiIiIiIZmZmZmZpaZiYiIiIiIiIiIiIiIiIiIaGZmZmZmZpaZiYiIiIiIiIiIiIiIiIiIiIiGhmZmZpaZiYiIiIiIiIiIiIiIiIiIiIiIiGhmZpaZiIiIiIiIiIiIiIiIiIiIiIhoaGZmZpaZiIiIiIiIiIiIiIiIiIiIiGhmZmZmZpaZiIiIiIiIiIiIiIiIiIiIiIiIaGhmZpaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZk=\",\n    \"smallIndustrial0\": \"hwQYABgAAAAzu7u7u7u7u7u7u8vTMzMzMzMzMzMzs8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTMzMzMzMzMzMzs8wzu7u7u7u7u7u7u8s=\",\n    \"smallIndustrial1\": \"hwQYABgAAAAzM7u7u7u7u7u7u7vTPTMzMzMzMzMzs7vTM7s7MzMzMzO7O7vTMz07MzMzMzM9O7vTMz07MzMzMzM9O7vTM7s7MzMzMzO7O7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTM7s7MzMzMzO7O7vTMz07MzMzMzM9O7vTMz07MzMzMzM9O7vTM7s7MzMzMzO7O7vTPTMzMzMzMzMzs7szM7u7u7u7u7u7u7s=\",\n    \"smallBlue0\": \"hwQYABgAAAAAmZmZmZmZmZmZmQCQaWZmZmZmZmZmlgmZZmZmZmZmZmZmZplpZmZmZmZmZmZmZpZpFhERERERERERYZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpFhERERERERERYZZpZmZmZmZmZmZmZpaZZmZmZmZmZmZmZpmQaWZmZmZmZmZmlgkAmZmZmZmZmZmZmQA=\",\n    \"smallBlue1\": \"hwQYABgAAAAAZmZmZmZmZmZmZgBglpmZmZmZmZmZaQZmmZmZmZmZmZmZmWaWmZmZmZmZmZmZmWmWGRERERERERERkWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWGRERERERERERkWmWmZmZmZmZmZmZmWlmmZmZmZmZmZmZmWZglpmZmZmZmZmZaQYAZmZmZmZmZmZmZgA=\",\n    \"smallDefault\": \"hwQYABgAAAAAu7u7u7u7u7u7uwCwHRERERERERERvQvb0bu7u7u7u7u70bsbvR0RERERERHRG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbvR0RERERERHRG7vb0bu7u7u7u7u70buwHRERERERERERvQsAu7u7u7u7u7u7uwA=\",\n    \"smallSwirlyWhite\": \"hwQYABgAAAAAu7u7u7u7u7u7uwCwuxG7EbsRuxG7EQsbG7EbsRuxG7Ebsbsbsbu7u7u7u7u7G7u7sRsRERERERGxG7G7uxERERERERERu7EbuxERERERERERu7sbsRERERERERERG7u7sRERERERERERG7G7uxERERERERERu7EbuxERERERERERu7sbsRERERERERERG7u7sRERERERERERG7G7uxERERERERERu7EbuxERERERERERu7sbsRERERERERERG7u7sRERERERERERG7G7uxERERERERERu7EbuxERERERERERu7sbsRsRERERERGxG7u7sbu7u7u7u7u7G7G7G7EbsRuxG7EbsbGwEbsRuxG7EbsRuwsAu7u7u7u7u7u7uwA=\",\n    \"smallSwirlyPurple\": \"hwQYABgAAAAAqrqruqu6q7qrqgCw3bu63brdut263Qrb3a3brdut263b3a3b3b2ruqu6q7rb3a263RsRERERERGx3auruxERERERERERq7vbuhERERERERERu7rarRERERERERER2qu6rRERERERERER2q2ruxERERERERERq73buhERERERERERu7rarRERERERERER2qu6rRERERERERER2q2ruxERERERERERq73buhERERERERERu7rarRERERERERER2qu6rRERERERERER2q2ruxERERERERERq727uhERERERERERu7q73RsRERERERGx3avb3b2ruqu6q7rb3a3b3b3avdq92r3a3a2w3avdq92r3au73QoAqrqruqu6q7qrqgA=\",\n    \"smallDialogLeftThin\": \"hwQYABgAAAAAAMDMzMzMzMwAAMAAwNsREREREdHLAMsA3BERERERERHRvMHAHRERERERERERHcGwEREREREREREREcvcERERERERERER0QwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQzcERERERERERER0QywERERERERERERsQDAHRERERERERERzQAA3BERERERERHRDAAAwNsREREREdHLAAAAAMDMzMzMzMwAAAA=\",\n    \"smallDialogLeftThick\": \"hwQYABgAAAAAAMDMzMzMzMwMAMwAwNsREREREb3MsM0A3BERERERERHNHM3AHRERERERERHREcywERERERERERER0czcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQzcERERERERERERzQywERERERERERERywDAHRERERERERHRzAAA3BERERERERHNDAAAwNsREREREb3MAAAAAMDMzMzMzMwAAAA=\",\n    \"smallDialogCenterThin\": \"hwQYABgAAAAAAMDMzMzMzAwAAAAAwNsREREREb0MAAAA3BERERERERHNAADAHRERERERERHRDACwERERERERERERCwDcERERERERERERzQAcERERERERERERwQAcERERERERERERwQAcERERERERERERwQAcERERERERERERzQAcERERERERERERsQwcEREREREREREREcEcERERERERERERsQwcERERERERERERzQAcERERERERERERwQAcERERERERERERwQAcERERERERERERwQAcERERERERERERwQDcERERERERERERzQCwERERERERERERCwDAHRERERERERHRDAAA3BERERERERHNAAAAwNsREREREb0MAAAAAMDMzMzMzAwAAAA=\",\n    \"smallDialogcenterThick\": \"hwQYABgAAAAAAMDMzMzMzMwAAAAAwNsREREREb3MAAAA3BERERERERHNDADAHRERERERERHRzACwERERERERERERywDcERERERERERERzQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERzQwcERERERERERERsQwcEREREREREREREcEcERERERERERERsQwcERERERERERERzQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQzcERERERERERERzQywERERERERERERywDAHRERERERERHRzAAA3BERERERERHNDAAAwNsREREREb3MAAAAAMDMzMzMzMwAAAA=\",\n    \"starryclouds\": \"hwRCAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCqAAAAAAAA3d0AAAAAAADd3QAAAAAAMAMAAAAzAAAAAAAAAFqjADAzAwDQERHd3d0NANAREd3d3Q0AMDkAADBTCgAAAAAAqlM1qjo5OdAdERHRHRHR3R0REdEdEdENk5kzqjpVCgAAAAAwVVVVVTqZOdMREREREZER3RERERERkRE9mZk5WlVVowAAAAAwU1VVpZOZmRMREREREZkZERERERERmRkxk5kzM1VVVQoAAAAAM1VVozOZORERVREREZERERFVERERkRERk5MzM1VVNQoAAAAAoFVVpTGTMxERVRERERERERFVERERERERMTMTWlVVowoAAAAAoDVTpREzExERERERERERERERERERERERERERWjVVCgAAAAAAoDqjqhERERERERERERERERERERERERERGRERqqpaCgAAAAAAMDMTERERkREREREREREREREREREREREREVEVETGjCgAAAAAAMDkzEVUREREREREREREREREREREREREREVEVETM5MwAAAAAAk5k5EVURERERERERERERERERERERERERERERMZOZOQAAAAAwmZkzERERERERERERERERERERERERERERERERMZmZMwAAAAAwk5k5ERERERERERERERERERERERERERERERERMZOZOQAAAAAAMDkTkRERERERERERERERERERERERERERERGRETM5AwAAAAAAADMREREREREREREREREREREREREREREREREREREzAAAAAAAA0B0RERERERERERERERERERERERERERERERERERHRDQAAAAAA0BERERERERERERERERERERERERERERERERERERERDQAAAAAAHZERERERERERERERERERERERERERERERERERERER0QAAAAAAHZkZEREREREREREREREREREREREREREREREREVUREQ0AAAAAHZEREREREREREREREREREREREREREREREREREVUREQ0AAAAAHREREREREREREREREREREREREREREREREREREREREQ0AAAAA3REREREREREREREREREREREREREREREREREREREREQ0AAAAA3RERERERERERERERERERERERERERERERERERERER0QAAAAAAHRERERERERERERERERERERERERERERERERERERER3QAAAADQERERERERERERERERERERERERERERERERERERERER3QAAAADQERERERERERERERERERERERERERERERERERERERER0QAAAADQERFVEREREREREREREREREREREREREREREREREREZ0QAAAADQERFVEREREREREREREREREREREREREREREREREZGZ0QAAAAAAHREREREREREREREREREREREREREREREREREREREZ0QAAAAAA0BERERERERERERERERERERERERERERERERERERERDQAAAAAA0B0RERERERERERERERERERERERERERERERERERHRDQAAAAAA0B0RERERERERERERERERERERERERERERERERERHRDQAAAAAA0BERERERERERERERERERERERERERERERERERERERDQAAAAAAHZERERERERERERERERERERERERERERERERERERER0QAAAAAAHZkZEREREREREREREREREREREREREREREREREVUREQ0AAAAAHZEREREREREREREREREREREREREREREREREREVUREQ0AAAAAHREREREREREREREREREREREREREREREREREREREREQ0AAAAA3REREREREREREREREREREREREREREREREREREREREQ0AAAAA3RERERERERERERERERERERERERERERERERERERER0QAAAAAAHRERERERERERERERERERERERERERERERERERERER3QAAAADQERERERERERERERERERERERERERERERERERERERER3QAAAADQERERERERERERERERERERERERERERERERERERERER0QAAAADQERFVEREREREREREREREREREREREREREREREREREZ0QAAAADQERFVEREREREREREREREREREREREREREREREREZGZ0QAAAAAAHREREREREREREREREREREREREREREREREREREREZ0QAAAAAA0BERERERERERERERERERERERERERERERERERERERDQAAAAAA0B0RERERERERERERERERERERERERERERERERERHRDQAAAAAAADMREREREREREREREREREREREREREREREREREREzAAAAAAAAMJMzERkRERERERERERERERERERERERERERERGTGTAwAAAAAAk5k5ExEREREREREREREREREREREREREREREREZOZOQMAAAAAM5mZExERERERERERERERERERERERERERERERETOZmQMAAAAAk5k5ExERERERERERERERERERERERERERERFVEZOZOQAAAAAAM5MzEVEVERERERERERERERERERERERERERFVETOTAwAAAAAAoDoTEVEVERERERERERERERERERERERERGRERETEzAwAAAAAAoKWqqhERkRERERERERERERERERERERERERERqjqjCgAAAAAAoFVTpRERERERERERERERERERERERERERMTMRWjVTCgAAAACgOlVVpTEzExEREREREVURERERERERVRERMzkTWlVVCgAAAACgU1VVMzM5ORERGREREVUREREZERERVRERk5kzOlVVMwAAAACgVVVVMzOZORORmREREREREZGZERERERExmZk5WlVVNQMAAAAAOlVVpZOZmdMRGRERERER3REZERERERE9k5mjVVVVVQMAAAAAoFWjqjOZOdAdEdEdERHR3R0R0R0REdENk5OjqlM1qgAAAAAAoDUDAACTAwDQ3d3dERENANDd3d0REQ0AMDMDADqlAAAAAAAAADMAAAAwAwAAAAAA3d0AAAAAAADd3QAAAAAAAKoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\"\n}","sprites.dialog.ts":"namespace sprites.dialog {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const bones = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const cityscape = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const desert = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const frogs = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const hugeLeaf = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const largeShell = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const largeStar = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const mediumStar = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const mediumShell = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const mediumLeaf0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const mediumLeaf1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const pineday = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const pinenight = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const smallIndustrial0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const smallIndustrial1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const smallBlue0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const smallBlue1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const smallDefault = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const smallSwirlyWhite = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const smallSwirlyPurple = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const smallDialogLeftThin = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const smallDialogLeftThick = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const smallDialogCenterThin = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const smallDialogcenterThick = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dialog\"\n    export const starryclouds = image.ofBuffer(hex``);\n}\n","sprites.duck.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.duck\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"duck1\": \"hwQQABAAAAAAAAAAsMsMAAAAsAuw3csAAACwvdvd3QwAALBVvdzdywAAsFtVzd3NAAC7tVXF3c0AsFtVW7XdzQCwVdXRW9XNALBVFf9VVc0Au1X1v1RVxQC1VVVFVFXFALVV1URUVbUAC1tFRFRVuwAAsPtMVNULAAAAALC0uwAAAAAAAAsAAA==\",\n    \"duck2\": \"hwQQABAAAAAAAAAAsMsMAAAAsAuw3csAAACwvdvd3QwAALBVvdzdywAAsFtVzd3NAAC7tVXF3c0AsFtVW7XdzQCwVdXRW9XNALBVFf9VVc0Au1X1v1RVxbC1VVVFVFXFULtV1URUVbWwAFtFRFRVuwAAsPtMVNULAAAAAEC7uwAAAAAAsAAAAA==\",\n    \"duck3\": \"hwQQABAAAAAAAAAAu8sMAAAAAAC93csAAAAAAN3c3QwAAAAAXcXdywAAsLtb1dzNAAC7VVtV3M0AsFtVvVXbzQCw1dFVvdXNALAV/1VVVc2wu/W/RVVVxVu8VdVEVVXFtbBV3URVVbULANtERFVVuwAA8ExEW9ULAAAAALSwuwAAAAAACwAAAA==\",\n    \"duck4\": \"hwQQABAAAAAAAAAAAMsMCwAAAACw3bsLAAAAANvdWwwAAACw3b1dzAAAu9vdW7XMALBbVdVbzc0Au1VVVdvczQBbHV1Vxd3NAFvxX1VVVc2wW/9LVVVVxVtb1URVVVXFtVvdRFVVVbULsEREVVVVuwAATLRbVdULAABAC7C7uwAAALAAAAAAAA==\",\n    \"duck5\": \"hwQQABAAAAAAAAAAsMy8AAAAAADbvbsAAAAAANu9xQAAAACw3dvFAAAAu9u9VcsMALBbVb3V3AwAu1VVtc3dzQBbHV1V3N3NAFvxX1VVVc2wW/9LVVVVxVtb1URVVVXFtVvdRFVVVbULsEREVVVVuwAATLRbVdULAABAC7C7uwAAALAAAAAAAA==\",\n    \"duck6\": \"hwQQABAAAAAAAAAAu8wAAAAAALC9vQwAAAAAsN3czQAAAACwXcW9DAAAu9tb1dwMALBbVVtV3AwAu1VVvVXbDABbHV1Vvd0MAFvxX1VV1QywW/9bVFVVDFtbVU1UVVUMtVvVTVRVVQsLsE1EVFW1CwAAz0S0Vb0AAAAAQAu7CwAAAACwAAAAAA==\",\n    \"duckRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.duck.duck1\\\",\\\"sprites.duck.duck2\\\",\\\"sprites.duck.duck3\\\",\\\"sprites.duck.duck4\\\",\\\"sprites.duck.duck5\\\",\\\"sprites.duck.duck6\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"duckLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.duck.duck1\\\",\\\"sprites.duck.duck2\\\",\\\"sprites.duck.duck3\\\",\\\"sprites.duck.duck4\\\",\\\"sprites.duck.duck5\\\",\\\"sprites.duck.duck6\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"duckHurt\": \"hwQQABAAAAAAAAAAAMsMAAAAsAuw3csAAACwvdvd3QwAALBVvdzdywAAu1tVzd3NALBbtVXF3c0Au1VVW7XdzQBbW1vVW9XNAFu8XFVVVc27W/VLVVVVxVVb1URVVVXFu1vdRFVVVbUAsEREVVVVuwAATLRbVdULAABAC7C7uwAAALAAAAAAAA==\",\n    \"log1\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAABgZwAAAAAAAAAAAAB2ZwAAALDL7O7Mz2B3hgAAANvd++7uzv936O4AsL27ve/u7s5m7u4A27u92+/u7u5udmcA29vb2/vu7u5ud+ewvb29vf3u7u7uZ+6wvb29vc3u7u7uhu6wvb29vc3u7u7uhu6wvb29vc3u7u7uZ+4A29vb28vu7u5ud+cA27u92+zu7u5ud2cAsL27vezu7u5uhu4AANvdy+7u7u5mhuwAALDL7A4AAGB3Z/4AAAAAAAAAAAB2Zw4AAAAAAAAAAABgZwAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"log2\": \"hwQYACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAABgAAAAAAAAAAAAAAAHYGAAAAAGBnAAAAAAAAAAAAAABgdwYAAAAAdmcAAAAAALvM7s78DHZnCAAAAGB3hgAAAACw3b3v7u78f4fu7u7M/3fu7gAAANu72/vu7u5s5u7u7u7uZu7uAACwvdu7/e7u7u5md+bu7u5udmcAALC9vb297+7u7nZ37u7u7m535wAA29vb29vv7u7ufubu7u7u7mfuAADb29vb2+zu7u5u6O7u7u7uh+4AANvb29vb7O7u7m7o7u7u7u6H7gAA29vb29vs7u7ufubu7u7u7mfuAACwvb29vezu7u52d+7u7u5ud+YAALC927vN7u7u7nZ35u7u7m53ZwAAANu728vu7u7uZuju7u7ubobOAAAAsN297O7u7m5myO7O/P92hu4AAAAAu8zuAAAAdnfm////bndnAAAAAAAAAAAAAABgd+YAAAAAdmcAAAAAAAAAAAAAAAB2BgAAAABgZwAAAAAAAAAAAAAAAGAAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"log3\": \"hwQYADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAABgAAAAAAAABgAAAAAAAAAAAAAAAABgZwAAAAAAdgYAAAAAYGcAAAAAAAAAAAAAAAAAdmcAAAAAYHcGAAAAAHZnAAAAAAAAsMvs7szPYHeGAAAAAHZnCAAAAGB3hgAAAAAAANvd++7uzv936O7uzvx/5+7u7u7uZ87MAAAAALC9u73v7u7OZu7u7u7ububu7u7u7mbu7gAAAADbu73b7+7u7m52Z+7u7u5md/bM7O5ud2cAAAAA29vb2/vu7u5ud+fu7u7udnfu7u7ubnfnAAAAsL29vb397u7u7mfu7u7u7n7m7u7u7u5n7gAAALC9vb29ze7u7u6G7u7u7u5+6O7u7u7uh+4AAACwvb29vc3u7u7uhu7u7u7ufuju7u7u7ofuAAAAsL29vb3N7u7u7mfu7u7u7n7m7u7u7u5n7gAAAADb29vby+7u7m535+7u7u52Z+7u7u5ud+YAAAAA27u92+zu7u5ud2fu7u7udnfm7u7ufndnAAAAALC9u73s7u7ubobu7u7u7mbozPz/zG6G7gAAAAAA293L7u7u7maG7O7M/29n6O7u7u5mhu4AAAAAALDL7A4AAGB3Z/7//+92dwYAAABgd2cAAAAAAAAAAAAAAAAAdmcOAAAAYHcGAAAAAHZnAAAAAAAAAAAAAAAAAGBnAAAAAAB2BgAAAABgZwAAAAAAAAAAAAAAAAAABgAAAAAAYAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"log4\": \"hwQYAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAGAAAAAABgAAAAAAAABgAAAAAAAAAAAAAAdgYAAAAAYGcAAAAAAHYGAAAAAGBnAAAAAAAAAAAAAGB3BgAAAAB2ZwAAAABgdwYAAAAAdmcAAAAAu8zuzvwMdmcIAAAAYHeGAAAAAHZnCAAAAGB3hgAAALDdve/u7vx/h+7u7sz/d+7u7u7ufubMzP///2fMzAAA27vb++7u7mzm7u7u7u5m7u7u7u5u5u7uzMzMZszMALC927v97u7u7mZ35u7u7m52Z8/M7u52d+bMzMx8d2cAsL29vb3v7u7udnfu7u7ubnfn7u7u7nZ37s7OzGx3xwDb29vb2+/u7u5+5u7u7u7uZ+7u7u7ufubu7u7MzGfMANvb29vb7O7u7m7o7u7u7u6H7u7u7u5+6O7u7szMh8wA29vb29vs7u7ubuju7u7u7ofu7u7u7n7o7u7MzsyHzADb29vb2+zu7u5+5u7u7u7uZ+7u7u7ufubuzszMzGfMALC9vb297O7u7nZ37u7u7m535u7u7u52Z+7u7s5sd8YAsL3bu83u7u7udnfm7u7ubndn7u7u7nd35szMznx3ZwAA27vby+7u7u5m6O7u7u5uhs7M/8/sZujuzszMbIbMAACw3b3s7u7ubmbI7s78/3aG7u7u7m5m6O7uzPxmhv8AAAC7zO4AAAB2d+b///9ud2cAAAAAdncGAAAAYHdnAAAAAAAAAAAAAGB35gAAAAB2ZwAAAABgdwYAAAAAdmcAAAAAAAAAAAAAAHYGAAAAAGBnAAAAAAB2BgAAAABgZwAAAAAAAAAAAAAAYAAAAAAAAAYAAAAAAGAAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"log5\": \"hwQYABAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAdgYAAAAAAGB3BgAAAAAAdmcIAAAAAAB+5szu7u6+AG7m7u7u7u4L7nZ37u7u7r7udnfu7u7u7u5+5u7u7u7u7n7o7u7u7u7ufuju7u7u7u5+5u7u7u7u7nZn7u7u7u7ud3fu7u7uvuxm6O7u7u4Lbmbo7u7uvgB2dwYAAAAAAGB3BgAAAAAAAHYGAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"log6\": \"hwQYACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAABgAAAAAAAAAAdgYAAAAAYGcAAAAAAAAAYHcGAAAAAHZnAAAAAAAAAHZnCAAAAGB3hgAAAAAAAAB/5+7u7u7uZ87s7u7uCwAAbubu7u7u7mbu7u7u7r4AAO5md/bM7O5ud+fu7u7uCwDudnfu7u7ubnfn7u7u7g4A7n7m7u7u7u5n7u7u7u4OAO5+6O7u7u7uh+7u7u7uDgDufuju7u7u7ofu7u7u7g4A7n7m7u7u7u5n7u7u7u4OAO52Z+7u7u5ud+bu7u7uDgDudnfm7u7ufnfn7u7u7gsA7mbozPz/zG6G7u7u7r4AAG9n6O7u7u5mhu7u7u4LAAB2dwYAAABgd2cAAAAAAAAAYHcGAAAAAHZnAAAAAAAAAAB2BgAAAABgZwAAAAAAAAAAYAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"log7\": \"hwQYADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAYAAAAAAGAAAAAAAAAAAAAAdgYAAAAAYGcAAAAAAHYGAAAAAAAAAABgdwYAAAAAdmcAAAAAYHcGAAAAAAAAAAB2ZwgAAABgd4YAAAAAdmcIAAAAAAAAAAB/5+7u7u7/d+7u7u7ufubM7u7uvgAAAABu5u7u7u7uZu7u7u7ububu7u7u7gsAAADuZnfm7u7ubnZnz8zu7nZ37u7u7r4AAADudnfu7u7ubnfn7u7u7nZ37u7u7u4AAADufubu7u7u7mfu7u7u7n7m7u7u7u4AAADufuju7u7u7ofu7u7u7n7o7u7u7u4AAADufuju7u7u7ofu7u7u7n7o7u7u7u4AAADufubu7u7u7mfu7u7u7n7m7u7u7u4AAADudmfu7u7ubnfm7u7u7nZn7u7u7u4AAADudnfm7u7ubndn7u7u7nd37u7u7r4AAADuZujs7u7ubobOzP/P7Gbo7u7u7gsAAABvZ+juzvz/dobu7u7ubmbo7u7uvgAAAAB2d+b///9ud2cAAAAAdncGAAAAAAAAAABgd+YAAAAAdmcAAAAAYHcGAAAAAAAAAAAAdgYAAAAAYGcAAAAAAHYGAAAAAAAAAAAAYAAAAAAAAAYAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"log8\": \"hwQYADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAABgAAAAAAYAAAAAAAAAYAAAAAAAAAdgYAAAAAYGcAAAAAAHYGAAAAAGBnAAAAAAAAYHcGAAAAAHZnAAAAAGB3BgAAAAB2ZwAAAAAAAHZnCAAAAGB3hgAAAAB2ZwgAAABgd4YAAAAAAAB/h+7u7sz/d+7u7u7+f+fu7u7u7mfO7O7u7gsAbObu7u7u7mbu7u7u7m7m7u7u7u5m7u7u7u6+AO5md+bu7u5udmfu7u7uZnf2zOzubnfn7u7u7gvudnfu7u7ubnfn7u7u7nZ37u7u7m535+7u7u4O7n7m7u7u7u5n7u7u7u5+5u7u7u7uZ+7u7u7uDu5u6O7u7u7uh+7u7u7ufuju7u7u7ofu7u7u7g7ubuju7u7u7ofu7u7u7n7o7u7u7u6H7u7u7u4O7n7m7u7u7u5n7u7u7u5+5u7u7u7uZ+7u7u7uDu52d+7u7u5ud+bu7u7udmfu7u7ubnfm7u7u7g7udnfm7u7ubndn7u7u7nZ35u7u7n535+7u7u4L7mbo7u7u7m6Gzu7u7u5m6Mz8/8xuhu7u7u6+AG5myO7O/P92hu7uzP9vZ+ju7u7uZobu7u7uCwB2d+b///9ud2f+///vdncGAAAAYHdnAAAAAAAAYHfmAAAAAHZnDgAAAGB3BgAAAAB2ZwAAAAAAAAB2BgAAAABgZwAAAAAAdgYAAAAAYGcAAAAAAAAAYAAAAAAAAAYAAAAAAGAAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"tree\": \"hwQkACkAAAAAAAAAAAAAAAAAgIYAAAAAAAAAAAAAAAAAAAAAAAAAAAAIgIaIBgAAAAAAAAAAAAAAAAAAAAAAAICGaIZmhgAAAAAAAAAAAAAAAAAAAAAAAICGZmhmiIgAAAAAAAAAAAAAAAAAAABgAGZmZ2aGaGYIAAAAAAAAAAAAAAAAAAB2CGh2Z2aIZoYIAAAAAAAAAAAAAAAAAIB3hmh2ZmZoZoiICAAAAAAAAAAAAAAAAIZndmdmdmZmhmhmCAAAAAAAAAAAAGAAYGdmd2dmd2dmZmaGiAAAAAAAAAAAAHYGaGdmd2Znd2ZmZmaIhgAAAAAAAAAAAHiHdmZnZ3ZnZmZmZoZohgAAAAAAAABgCGhndnZnZndnZnZmZmZmhgAAAAAAAABghnZmZnZnZndmZndnZmZmiAAAAAAAAACAZnZmZnZmZmZ2ZndmZmaIiAAAAAAAAACAhndmZmd2Z3Z3dmZmZmZmhg4AAAAAAACAeHd3ZmZ3Z3d3ZnZ3ZmZmZujM/w8AAABod3dnZnZ3ZndmZnd3ZmZmiOjuzg8AAAB2d3dmZmZmZnZ3ZmZmZmaGiO7u7gwAAACAdnd3Zndndnd3ZndnZmZmhuj/7w4AAACAaHdmZnd3d3dnZndndndmhgjA7A4AAABgeHZ2ZnZ3dnd3ZmZmdmdmhgDszgwAAAAAeIZ2Z2Z3Znd3dmdmZmZmyO7OAAAAAAAAZmhoZ2Zmd3dmdndmZmaG6AwAAAAAAAAAiGiGZ2dmd3dmZmZ2d2dmiAAAAAAAAAAAAGCIeGdmd3dmZ2Zmd2dmZggAAAAAAAAAAAAAYIdnd2dmd2ZmdmdmhgAAAAAAAAAAAAAAAIZ2dmdmd2d3ZmaGCAAAAAAAAAAAAAAAAAB4Z2d3dmd3ZmZmCAAAAAAAAAAAAAAAAABgZ2Z3ZmZ2ZmaGCAAAAAAAAAAAAAAAAAAAhmd2ZnZmZoYIAAAAAAAAAAAAAAAAAAAAgHdmZnZmZoYAAAAAAAAAAAAAAAAAAAAAAHZmZmZmZoYAAAAAAAAAAAAAAAAAAAAAAIBohmZmiAgAAAAAAAAAAAAAAAAAAAAAAACACGhmCAAAAAAAAAAAAAAAAAAAAAAAAAAAAICGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIAAAAAAAAAAAAAAA=\"\n}","sprites.duck.ts":"namespace sprites.duck {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const duck1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const duck2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const duck3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const duck4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const duck5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const duck6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const duckHurt = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const log1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const log2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const log3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const log4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const log5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const log6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const log7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const log8 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const tree = image.ofBuffer(hex``);\n}\n","sprites.dungeon.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.dungeon\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"buttonOrange\": {\n        \"data\": \"hwQQABAAAAC7u7u7u7u7u8u7u7u7u7u8u05ERN1EvLvrRERERE3Eu0tERERE1MS7S0RERETUxLtLRERERNTEu0tERERE1MS7S0RERETUxLtLRERERNTEu0tERERE1MS7S0RERETUxLvrRERERE3Eu7tORETdRLy7y7u7u7u7u7y7u7u7u7u7uw==\",\n        \"tilemapTile\": true\n    },\n    \"buttonOrangeDepressed\": {\n        \"data\": \"hwQQABAAAAC7u7u7u7u7u8u7u7u7u7u8u+tERNRNvLu7TkRERNTEu7tERERERM27u0REREREzbu7RERERETNu7tERERERM27u0REREREzbu7RERERETNu7tERERERM27u0REREREzbu7TkRERNTEu7vrRETUTby7y7u7u7u7u7y7u7u7u7u7uw==\",\n        \"tilemapTile\": true\n    },\n    \"buttonTeal\": {\n        \"data\": \"hwQQABAAAAC7u7u7u7u7u8u7u7u7u7u8u2xmZplmvLvLZmZmZmnGu2tmZmZmlsa7a2ZmZmaWxrtrZmZmZpbGu2tmZmZmlsa7a2ZmZmaWxrtrZmZmZpbGu2tmZmZmlsa7a2ZmZmaWxrvLZmZmZmnGu7tsZmaZZry7y7u7u7u7u7y7u7u7u7u7uw==\",\n        \"tilemapTile\": true\n    },\n    \"buttonTealDepressed\": {\n        \"data\": \"hwQQABAAAAC7u7u7u7u7u8u7u7u7u7u8u8tmZpZpvLu7bGZmZpbGu7tmZmZmZsm7u2ZmZmZmybu7ZmZmZmbJu7tmZmZmZsm7u2ZmZmZmybu7ZmZmZmbJu7tmZmZmZsm7u2ZmZmZmybu7bGZmZpbGu7vLZmaWaby7y7u7u7u7u7y7u7u7u7u7uw==\",\n        \"tilemapTile\": true\n    },\n    \"buttonPink\": {\n        \"data\": \"hwQQABAAAAC7u7u7u7u7u8u7u7u7u7u8uzozMxEzvLurMzMzMzHDuzszMzMzE8O7OzMzMzMTw7s7MzMzMxPDuzszMzMzE8O7OzMzMzMTw7s7MzMzMxPDuzszMzMzE8O7OzMzMzMTw7urMzMzMzHDu7s6MzMRM7y7y7u7u7u7u7y7u7u7u7u7uw==\",\n        \"tilemapTile\": true\n    },\n    \"buttonPinkDepressed\": {\n        \"data\": \"hwQQABAAAAC7u7u7u7u7u8u7u7u7u7u8u6szMxMxvLu7OjMzMxPDu7szMzMzM8G7uzMzMzMzwbu7MzMzMzPBu7szMzMzM8G7uzMzMzMzwbu7MzMzMzPBu7szMzMzM8G7uzMzMzMzwbu7OjMzMxPDu7urMzMTMby7y7u7u7u7u7y7u7u7u7u7uw==\",\n        \"tilemapTile\": true\n    },\n    \"chestClosed\": {\n        \"data\": \"hwQQABAAAAAAu7u7y7y7C7Du7u677M6760Tk7rvs7rtLRETuu+zuC0tERO677O4LS0RE7rvs7gtLRETuu8vuC0tERO7NvO4LS0RE7s287gtLRETuu8vuC0tERO677O4LS0RE7rvs7gtLRETuu+zuC+tE5O677O67sO7u7rvszrsAu7u7y7y7Cw==\",\n        \"tilemapTile\": true\n    },\n    \"chestOpen\": {\n        \"data\": \"hwQQABAAAACwuwu7u7u7C+vuu8zM6867S+S7zMzr7rtLRLvMzOvuC0tEu8zM6+4LS0S7zMzr7gtLRLvLzOvuC0tEzbzM6+4LS0TNvMzr7gtLRLvLzOvuC0tEu8zM6+4LS0S7zMzr7gtLRLvMzOvuC0vku8zM6+67S+67zMzrzruwuwu7u7u7Cw==\",\n        \"tilemapTile\": true\n    },\n    \"collectibleInsignia\": {\n        \"data\": \"hwQQABAAAABmZmZmZmZmZpaZZpmZZplplmmWyZxplmmWZplpzJlmaWaWmWacmWlmZpmZZpmZmWaWyZmWZmaZaZbMnJaZZsZplmxmmWnJzGmWmWZmaZmcaWaZmZlmmZlmZpaZyWaZaWaWZpnMlplmaZZplsmcaZZplplmmZlmmWlmZmZmZmZmZg==\",\n        \"tilemapTile\": true\n    },\n    \"collectibleRedCrystal\": {\n        \"data\": \"hwQQABAAAAAAAAAAAAAAAAAAAEREAAAAAAA0MyREAAAAMDMzMyIEAAA0MzMzI0IAADQzIyIzQgBANDMiIiIiBEBFIiJEJCIEQEUiQkREIgRARCJCREQiBABEEUJEREIAAEQRRUQkQgAAQFRVREIEAAAARERERAAAAAAAREQAAAAAAAAAAAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"collectibleBlueCrystal\": {\n        \"data\": \"hwQQABAAAAAAAAAAAAAAAAAAAGZmAAAAAAB2d4ZmAAAAcHd3d4gGAAB2d3d3h2gAAHZ3h4h3aABgdneIiIiIBmBliIhmhogGYGWIaGZmiAZgZohoZmaIBgBmEWhmZmgAAGYRZWaGaAAAYFZVZmgGAAAAZmZmZgAAAAAAZmYAAAAAAAAAAAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"darkGroundNorthWest0\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzLy7u7u7u7u7vMzMzMzMzMy8zMzMzMy8zLzMzMzMzMzMvMzMzLzMzMy8zLzMzMzMzLzMzMzMzMzLvMzMzMzMzMy8zMzMzMzMzLzMzMzMzMzMvMy8zLzMzMy8zMzMzMzMzLzMzMzMzLzMvMzMzMzMzMy8zMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"darkGroundNorth\": {\n        \"data\": \"hwQQABAAAAC8zMzMzMzMzLzMzLzMzMzMvLzMzMzMvMy8zMzMzMzMzLzMzMzMzMzMvMzMzLzMzMy8zLzMzMzMzLzMzMzMzMzLvMzMzMzMzMy8zMzMzMzMzLzMzMzMzMzMvMy8zLzMzMy8zMzMzMzMzLzMzMzMzLzMvMzMzMzMzMy8zMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"darkGroundNorthEast0\": {\n        \"data\": \"hwQQABAAAAC8zMzMzMzMzLzMzLzMzMzMvLzMzMzMvMy8zMzMzMzMzLzMzMzMzMzMvMzMzLzMzMy8zLzMzMzMzLzMzMzMzMzLvMzMzMzMzMy8zMzMzMzMzLzMzMzMzMzMvMy8zLzMzMy8zMzMzMzMzLzMzMzMzMzMvLu7u7u7u7vMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"darkGroundNorthWest1\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzLzMzMzMzMvMzMzMvMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzMzMvMzMzMzMzLvMzMzMzMzMyw==\",\n        \"tilemapTile\": true\n    },\n    \"darkGroundWest\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzLu7u7u7u7u7zMzMzMzMzMzMvMzMzMy8zMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzLzMvMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"darkGroundCenter\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzLzMzMzMzMvMzMzMvMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzLzMvMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"darkGroundEast\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzLzMzMzMzMvMzMzMvMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzMzMu7u7u7u7u7vMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"darkGroundNorthEast1\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMy8zMzLzMzMy7zMvMzMzMy8zMzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzLzMvMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"darkGroundSouthWest0\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzLu7u7u7u7vLzMzMzMzMzMvMy8zMzMzMy8zMzMzMzMzLzMzMzLzMzMvMzLzMzMzMy8zMzMzMzMzLzMzMzMzMy8u8zMzMzMzMy8zMzMzMzMzLzMy8zLzMzMvMzMzMzMzMy8zMzMzMzMzLvMzMzMzMzMvMzMzMzMzMyw==\",\n        \"tilemapTile\": true\n    },\n    \"darkGroundSouth\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMy8zMzLzMzMzLzMvMzMzMzMvMzMzMzMzMy8zMzMzMzMzLzMzMzLzMzMvMzLzMzMzMy8zMzMzMzMzLzMzMzMzMy8u8zMzMzMzMy8zMzMzMzMzLzMy8zLzMzMvMzMzMzMzMy8zMzMzMzMzLvMzMzMzMy8vMzMzMzMzMyw==\",\n        \"tilemapTile\": true\n    },\n    \"darkGroundSouthEast0\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMy8zMzLzMzMzLzMvMzMzMzMvMzMzMzMzMy8zMzMzMzMzLzMzMzLzMzMvMzLzMzMzMy8zMzMzMzMzLzMzMzMzMy8u8zMzMzMzMy8zMzMzMzMzLzMy8zLzMzMvMzMzMzMzMy8zMzMzMzMzLu7u7u7u7u8vMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"darkGroundSouthEast1\": {\n        \"data\": \"hwQQABAAAAC8zMzMzMzMzLvMzLzMzMzMzMzMzMzMvMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzLzMvMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"darkGroundSouthWest1\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzLzMzMzMzMvMzMzMvMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzLzMu8zMzMzMzMy8zMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"doorClosedWest\": {\n        \"data\": \"hwQQABAAAAC8u7u7u7u7y7y7u7u7u7vL3N3d3d3d3c3c3d3d3d3dzczMzMzMzMzMvLvP//z8u8vcvc///Pzbzdy9z//8/NvN3L3P//z8283cvc///PzbzbzLz//8/LzL3L3Pz//8283cvc/P//zbzdy9z8///NvN3L3Pz//8283KrM/P//zKrA==\",\n        \"tilemapTile\": true\n    },\n    \"doorClosedSouth\": {\n        \"data\": \"hwQQABAAAADKzMzMzMzMzNzdvd3dy9273N293d3L3bu6u8u7u8vdu///////z927zMzMzMzM3bv//////8/du8zM/P//z927///PzMzM3bv//////8/du8zMzMzMzN27///////P3bu6u8u7u8vdu9zdvd3dy9273N293d3L3bvKzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"doorClosedNorth\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMrLvdvN3d293Nu9283d3b3c273by7u7y7q7vd/P//////u93MzMzMzMy73fz//////7vdzMzM/P//u938///PzMy73fz//////7vdzMzMzMzMu938//////+73by7u7y7q7vdvN3d293Nu9283d3b3c3MzMzMzMzMrA==\",\n        \"tilemapTile\": true\n    },\n    \"doorClosedEast\": {\n        \"data\": \"hwQQABAAAADKrM///PzKrNy9z//8/NvN3L3P//z8283cvc///Pzbzdy9z//8/NvNvMvPz//8vMvcvc/P//zbzdy9z8///NvN3L3Pz//8283cvc/P//zbzby7z8///LvLzMzMzMzMzMzc3d3d3d3dzdzd3d3d3d3NvLu7u7u7u8u8u7u7u7u7yw==\",\n        \"tilemapTile\": true\n    },\n    \"doorOpenWest\": {\n        \"data\": \"hwQQABAAAAC8u7u7u7u7y7y7u7u7u7vL3N3d3d3d3c3c3d3d3d3dzczMzMzMzMzMvLv/////u8vcvf/////bzdy9/////9vN3L3/////283cvf/////bzbzL/////7zL3L3/////283cvc/8///bzdy9///M/NvN3L3M/M/M283KrMzMzMzKrA==\",\n        \"tilemapTile\": true\n    },\n    \"doorOpenSouth\": {\n        \"data\": \"hwQQABAAAADKzMzMzMzMzNzdvd3dy9273N293d3L3bu6u8u7u8vdu8z/////z927zM/////P3bvMz////8/du/z/////z927/Pz////P3bvM/P///8/du8z8////z927zP/////P3bu6u8u7u8vdu9zdvd3dy9273N293d3L3bvKzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"doorOpenNorth\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMrLvdvN3d293Nu9283d3b3c273by7u7y7q7vd/P/////Mu938////z8y73fz////PzLvd/P///8/Pu938/////8+73fz////8zLvd/P////zMu938/////8y73by7u7y7q7vdvN3d293Nu9283d3b3c3MzMzMzMzMrA==\",\n        \"tilemapTile\": true\n    },\n    \"doorOpenEast\": {\n        \"data\": \"hwQQABAAAADKrMzMzMzKrNy9zPzPzNvN3L3PzP//283cvf//z/zbzdy9/////9vNvMv/////vMvcvf/////bzdy9/////9vN3L3/////283cvf/////bzby7/////7vLzMzMzMzMzMzc3d3d3d3dzdzd3d3d3d3NvLu7u7u7u8u8u7u7u7u7yw==\",\n        \"tilemapTile\": true\n    },\n    \"doorLockedWest\": {\n        \"data\": \"hwQQABAAAAC8u7u7u7u7y7y7u7u7u7vL3N3d3d3d3c3c3d3d3d3dzczMzMzMzMzMvMu7u7u7vMvczbu7u7vczdzNtFu1S9zN3M3rtVu+3M3czetURb7czbzLtPVUS7zL3M275ES73M3czbtO5LvczdzNu+u+u9zN3M27u7u73M3KzMzMzMzMrA==\",\n        \"tilemapTile\": true\n    },\n    \"doorLockedSouth\": {\n        \"data\": \"hwQQABAAAADKzMzMzMzMzNzdvd3dy9273N293d3L3bvMzMzMzMzdu7y7S7u0y927vLu77rvL3bu861RUu8vdu7xO/rW1y927vE5EtbXL3bu861RUu8vdu7y7u+67y927vLtLu7TL3bvMzMzMzMzdu9zdvd3dy9273N293d3L3bvKzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"doorLockedNorth\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMrLvdvN3d293Nu9283d3b3c273czMzMzMzLvdvEu7tLvLu928u+67u8u73by7RUW+y7vdvFtbROTLu928W1vv5Mu73by7RUW+y7vdvLvuu7vLu928S7u0u8u73czMzMzMzLvdvN3d293Nu9283d3b3c3MzMzMzMzMrA==\",\n        \"tilemapTile\": true\n    },\n    \"doorLockedEast\": {\n        \"data\": \"hwQQABAAAADKzMzMzMzMrNzNu7u7u9zN3M2767673M3czbtO5LvczdzNu0ROu9zNvMu0RV9LvMvczetURb7czdzN67VbvtzN3M20W7VL3M3czbu7u7vczbzLu7u7u7zLzMzMzMzMzMzc3d3d3d3dzdzd3d3d3d3NvLu7u7u7u8u8u7u7u7u7yw==\",\n        \"tilemapTile\": true\n    },\n    \"floorLight0\": {\n        \"data\": \"hwQQABAAAAAdERGxHRERsdHd3b3R3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d3d0d3d3bu7u+27u7vtHRERsR0REdHR3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d290d3d3dHd3b27u7vtu7u77Q==\",\n        \"tilemapTile\": true\n    },\n    \"floorLight1\": {\n        \"data\": \"hwQQABAAAAAdERGxHRERsdHd3b3R3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d290d3dvdHdvbvR3d3d0d27u7u7u+27u7vtHRERsR0REbHR3d290d3dvdHdvbvR3d290d27u9Hd3b3RHd290d3dvdEb3b3R3d29sd3d3dHd3b27u7vtu7u77Q==\",\n        \"tilemapTile\": true\n    },\n    \"floorLight2\": {\n        \"data\": \"hwQQABAAAAAdERERERERsdHd3d3d3d290d3d3d3d3b3R3d3d3d3dvdHd3d3d3d290d3d3d3d3b3R3d3d3d3dvdHd3d3d3d290d3d3d3d3b3R3d3d3d3dvdHd3d3d3d290d3d3d3d3b3R3d3d3d3dvdHd3d3d3d290d3d3d3d3b27u7u7u7u7uw==\",\n        \"tilemapTile\": true\n    },\n    \"floorLightMoss\": {\n        \"data\": \"hwQQABAAAAAdERGxHRERsdHd3bbR3d290d3dZtHd3b3R3W290d3dvdHd3b3R3d290d3dvd3d3b3R1t1t293d3btrtr3m7rvtHRERYWa+EdHR3d29Ft3dvdHd3W3R3d290d3dvdHd3bvR3d290d27vdHd3b3R3d290d3d3dG93b27u7vtu7u77Q==\",\n        \"tilemapTile\": true\n    },\n    \"floorLight3\": {\n        \"data\": \"hwQQABAAAAAdERGxzMzMzNHd3b3MzMzM0d3dvcwcEczR3d29EdHdy9Hd3b0c3d3L0d3dvczd3cvR3d3tzMzdvbu7287MzNy9HRGxy8zMzL3R3b0cwczMy9HdvdEdwczM0d3L3N3dvczR3cvM3N29zNHdy8zM3MvM0b3MzMzMzMy7u8zMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"floorLight4\": {\n        \"data\": \"hwQQABAAAAAdERGxu7u7u9Hd3b0dERGx0d3dvdHd3b3R3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d3d0d3dvbu7u+3R3bvbHRERsbu7Ee3R3d29HdHd3dHd3b3R3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d290d3d3dHd3b27u7vtu7u77Q==\",\n        \"tilemapTile\": true\n    },\n    \"floorLight5\": {\n        \"data\": \"hwQQABAAAAAdERERERERsdHd3d3d3d290d3d3d3d3b3R3d3d3d3dvdHd3d3d3d29293d3d3d3bux293d3d27u9G9u93dvRux0d3d270b0b3R3d29G9HdvdHd3d293d290d3d3b3d3b3R3d3d3dvdvdHd3d3d29290d3d3d293b27u7u7u7u7uw==\",\n        \"tilemapTile\": true\n    },\n    \"floorMixed\": {\n        \"data\": \"hwQQABAAAADb3d3NHRERwb27u8vR3d3Nvbu7y9Hd3c29u7vL0d3dzb27u8vR3d3Nvbu7y9Hd3c29u7u70d3d3czMzKvMzMytHRERwdvd3b3R3d3Nvbu7y9Hd3c29u7vL0d3dzb27u8vR3d3Nvbu7y9Hd3c29u7vL0d3d3b27u8vMzMytzMzMqw==\",\n        \"tilemapTile\": true\n    },\n    \"floorDark0\": {\n        \"data\": \"hwQQABAAAADb3d3N293dzb27u8u9u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7u7vbu7u8zMzKvMzMyr293dzdvd3b29u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7vLvbu7u727u8vMzMyrzMzMqw==\",\n        \"tilemapTile\": true\n    },\n    \"floorDark1\": {\n        \"data\": \"hwQQABAAAADb3d3N293dzb27u8u9u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7vLvbu7y727y8y9u7u7vbvMzMzMzKvMzMyr293dzdvd3c29u7vLvbu7y727y8y9u7vLvbvMzL27u8u927vLvbu7y73cu8u9u7vLzbu7u727u8vMzMyrzMzMqw==\",\n        \"tilemapTile\": true\n    },\n    \"floorDark2\": {\n        \"data\": \"hwQQABAAAADb3d3d3d3dzb27u7u7u7vLvbu7u7u7u8u9u7u7u7u7y727u7u7u7vLvbu7u7u7u8u9u7u7u7u7y727u7u7u7vLvbu7u7u7u8u9u7u7u7u7y727u7u7u7vLvbu7u7u7u8u9u7u7u7u7y727u7u7u7vLvbu7u7u7u8vMzMzMzMzMrA==\",\n        \"tilemapTile\": true\n    },\n    \"floorDarkDiamond\": {\n        \"data\": \"hwQQABAAAADb3d3N3N3dzb27u9zNu7vLvbvLvbu8u8u9u9y7u8u7y73Lvbu7u7zLvdy7u7u7y8vNvbu7u7u7vNy7u7u7u7vL3Lu7u7u7u9zNu7u7u7vLzb28u7u7u9zLvcu7u7vLvcu9u7y7u9y7y727y7vLvbvLvbu7vNy7u8vMzMzLzczMrA==\",\n        \"tilemapTile\": true\n    },\n    \"floorDark3\": {\n        \"data\": \"hwQQABAAAADb3d3NzMzMzL27u8vMzMzMvbu7y8zc3cy9u7vL3b27zL27u8vcu7vMvbu7y8y7u8y9u7urzMy7y8zMvMrMzLzL293NzMzMzMu9u8vczczMzL27y73bzczMvbvMvLu7y8y9u8zMvLvLzL27zMzMvMzMvcvMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"floorDark4\": {\n        \"data\": \"hwQQABAAAADb3d3NzMzMzL27u8vb3d3Nvbu7y727u8u9u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7u7vbu7y8zMzKu9u8y8293dzczM3au9u7vL2727u727u8u9u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7vLvbu7u727u8vMzMyrzMzMqw==\",\n        \"tilemapTile\": true\n    },\n    \"floorDark5\": {\n        \"data\": \"hwQQABAAAADb3d3d3d3dzb27u7u7u7vLvbu7u7u7u8u9u7u7u7u7y727u7u7u7vLvLu7u7u7u8zNvLu7u7vMzL3LzLu7y9zNvbu7vMvcvcu9u7vL3L27y727u7vLu7vLvbu7u8u7u8u9u7u7u7y7y727u7u7vLvLvbu7u7vLu8vMzMzMzMzMrA==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterNorthWest\": {\n        \"data\": \"hwQQABAAAADPZmZmxmxmZvx8d3d3fHd3xsx3d3fMd3d2zGxmZsZmZnbHzMzMzMzMdmfMfHd3d8Z2Z8zMZmZmzHZnbMzMzMzMdmd8xsxmZmZ8Z3zGzGxmZnxnfMbGzMzMzGd8xmbMbGbMbHzGZszMzHbMfMZmbMxmdmdsxmZszM92Z8zGZmxs/A==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterNorth0\": {\n        \"data\": \"hwQQABAAAAB2Z8zMZsxszHZnbMxmbGzMdmd8xmZszMx8ZnzGzGzMzMzMfMbGbGzMdmd8xmZsbMx2Z3zGZmxszHZnbMZmzGzMdmfMzGbMbMx2Z2zMZmxszHZnfMZmbMzMfGd8xmZszMzMzHzGzGxszHbHfMZmbGzMdmd8xmZsbMx2Z2zGZsxszA==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterNorth1\": {\n        \"data\": \"hwQQABAAAAB2Z8zMZsxszHZnbMZmzGzMdmd8xmbMzMx8ZnzGxszMzMzMfMbMzGzMdmZ8xmzMbMx2Z2zGbMZszHZnbMxsxmzMdmfMzGbGbMx2Z2zMZsxszHZnfMZmbMzMfGd8xmZszMzMzHzGzGxszHbHfMZmbGzMdmd8xmZsbMx2Z2zGZsxszA==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterNorthEast\": {\n        \"data\": \"hwQQABAAAAB2Z8zMZmxs/HZnbMxmbGzPdmd8xmZszGx2Z3zGZszMzHbMfMZmzGxmzGx8xsbMzMx8Z3zGzGxmZnZnfMbMZmZmdmd8zMzMzMx2Z8zMZmZmZnZnzGx3d3fGdsfMzMzMzMx2zGxmZmbGZsbMd3d3d8x3/Hx3d3fHfHfPZmZmxsxsZg==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterWest0\": {\n        \"data\": \"hwQQABAAAABmxmxmZsZsZnfHd3d3x3d3d8d3d3fHdndmzGZmZsZmZszMzMzMzMzMdnd3xnZ3d8ZmZmbMZmZmzMzMzMzMzMzMZsZmZmZmbGZmxmZmZsZsZszMzMzMzMzMbGZmxmxmZsbMzMzMzMzMzGZmzGZmZsxmzMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"greenInnerNorthWest\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMzMxmZmbMZmbMzMzMzMzMzMzGZmZmZmbGzMbGzMzMzMzMxsZmZmZsZszGzHZmZmxmzMbMZsfMzMzMxsZmzGZmZszGxmZsd3dnzMbGbGx3zMzMzMbMbMfMZszMxmZsx2Z3zMbGZszGdnfMxsxmzMx2Zw==\",\n        \"tilemapTile\": true\n    },\n    \"greenInnerNorthEast\": {\n        \"data\": \"hwQQABAAAADMxsxmbMZ2Z8zGxmZsx3Z3zMbGZmzHbHfMxsbMbMdsZszMxmZsd8zMzMzGZmx3d8bMxsZmzGZmzMzGxmbHzMzMzMbGdmZmbGbMxsZmZsZsZszGxszMzMzMzMZmxmxmZsbMzMzMzMzMzMzMZmZmZsxmzMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterEast0\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMZsxmZmbMZmbMzMzMzMzMzGxmZsZsZmbGzMzMzMzMzMxmxmxmZmZsZmbGZmZmZmxmzMzMzMzMzMzMZmZmzGZmZmx3d2dsd3dnzMzMzMzMzMxmZmxmZmbMZndnfHd3d3x3d3d8d3d3fHdmxmxmZsZsZg==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterWest1\": {\n        \"data\": \"hwQQABAAAABmxmxmZsZsZnfHd3d3x3d3d8d3d3fGdndmzGZmZsZmZszMzMzMzMzMdnd3xmZ3d8ZmZmbMbGZmxszMzMzMzMzMZsZmZszMZmZmxmZmZsZsZszMzGxmzMzMbGZmzMzMzMzMzMzMzMzMzGZmzGZmZsxmzMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"greenInnerSouthWest\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMZsxmZmZmzMzMzMzMzMzMzGxmZsZsZmzMzMzMzMxsbMxmxmxmZmxszGbGZmZnbGzMzMzMfGZsbMzMZmbMZmxszGx3d8ZmbMzMzMx3xmZszMxmxnzGzGxszHfGfMZmbGzMd2d8xmZsbMx2Z2zGZsxszA==\",\n        \"tilemapTile\": true\n    },\n    \"greenInnerSouthEast\": {\n        \"data\": \"hwQQABAAAAB2Z8zMZsxszHdnbMxmbGzMd2Z8xmZszMxmzHzGzGzMzMzMd8bGbGzMdnd3xmZsbMxmZmbMZmxszMzMzHxmzGzMZsZmZmfMbMxmxmZmZmxszMzMzMzMbGzMbGZmZmZmbMzMzMzMzMzMzGZmzGZmZszMzMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterEast1\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMZsxmZmbMZmbMzMzMzMzMzMzMzMzMZmbGzMzMZsbMzMxmxmxmZmZsZmZmzMxmZmxmzMzMzMzMzMxsZmbGzGZmZmx3d2Zsd3dnzMzMzMzMzMxmZmxmZmbMZndnbHd3d3x3d3d8d3d3fHdmxmxmZsZsZg==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterSouthEast\": {\n        \"data\": \"hwQQABAAAABmxsxsZmZm/HfHfHd3d8fPd8x3d3d3zGxmbGZmZsbMZ8zMzMzMzHxnbHd3d8bMdmdmZmZmzMx2Z8zMzMzMx3ZnZmZmzGzHdmdmZsbMbMd2x8zMzGxsx8bMZsbMZmzHzGfMzMxmbMd2Z8bMxmZsx3Zn/MbGZszGdmfPxsZmzMx2Zw==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterSouth0\": {\n        \"data\": \"hwQQABAAAADMxsxmbMZ2Z8zGxmZsx3ZnzMbGZmzHfGfMxsbMbMfMzMzMxmZsx3bHzMzGZmzHdmfMxsxmzMZ2Z8zGbGbMzHZnzMZsxszGdmfMxmzGbMZ2Z8zGzMZsx2ZnzMbMzGzHzMzMzMxsbMdmx8zMzGZsx3ZnzMbMZmzGdmfMxsxmzMx2Zw==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterSouth1\": {\n        \"data\": \"hwQQABAAAADMxsxmbMZ2Z8zGxmZsx3ZnzMbGZmzHfGfMxsbMbMfMzMzMxmZsx3bHzMzGZmzHdmfMxsZmzMZ2Z8zGzGbMzHZnzMbMZmzGdmfMxsZmbMd2Z8zGxmZsx3ZnzMbGbGzHzMzMzMbMbMdmx8zMxmZsx3ZnzMbGZszGdmfMxsxmzMx2Zw==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterSouthWest\": {\n        \"data\": \"hwQQABAAAADPxsZmbMx2Z/zMxmZsxnZnZszGZmzHzGfMzMxmbMfGzGbGzGZsx3bMzMzMbGzHdsdmZsbMbMd2x2ZmZsxsx3ZnzMzMzMzGdmfMZmZmzMx2Z2x3d3fHzHZnzMzMzMzMfGdmZmxmZsbMZ3d3zHd3d8xsd3fHd3d3x89mZsZsZmZm/A==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterNorth2\": {\n        \"data\": \"hwQQABAAAAB2Z8zMZsxszHZndsxmbGzMdnd2x2dszMx8d3Znd2zMzMxmdnd3Z2zMdnd2Z3dmbMx2d3dEbGZszHZ3RBXkbGzMdndHFeRsbMx2d3dEZGZszHZ3dnd3ZszMfHd2d3dnzMzMZnZnd2ZszHbHdmdnbGzMdmd8Z2ZsbMx2Z2zGZsxszA==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterEast2\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMZsxmZmbMZmbMzMzMzMzMzGxmZmZmZmbGzMxnxmx2xsxmdnfmbndnZmZ3d0xEd3dmzGxnFEF3ZsbMd3dURXd3Z3x3d0d0d3dnbGZmR3dmZsxmd3Z3d3fGZnd3dnd3d3Z3d3d8d3d3fHdmxmxmZsZsZg==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterSouth2\": {\n        \"data\": \"hwQQABAAAADMxsxmbMZ2Z8zGxmZ2x3ZnzMbGdnZnfGfMxmZ3dmdmzMzMdnd3Z3fHzMxmd3dnd2fMxmZGRHd3Z8zGxk5RdHdnzMbGTlFEd2fMxmbGRHd3Z8zGZnd2Z3dnzMZ2d3dnZszMzMZ3dmd3x8zMxnZ8Z3dnzMbGZsxndmfMxsxmzMx2Zw==\",\n        \"tilemapTile\": true\n    },\n    \"greenOuterWest2\": {\n        \"data\": \"hwQQABAAAABmxmxmZsZsZnfHd3d3x3d3d2d3d3dnd3dmbHd3d2d3ZsxmZnd0ZmbGdnd3R3R3d8d2d3dURXd3zGxmdxRBdsbMZnd3RMR3d2ZmdnfmbndnZsxsZ8ZsdszMbGZmZmZmZsbMzMzMzMzMzGZmzGZmZsxmzMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"greenSwitchUp\": {\n        \"data\": \"hwQQABAAAAB2Z8zMZsxszHZnbMxmbGzMdmd8xmZszMx8ZnzGzGzMzMzMzMzMzGzMdmfdvbu7y8x2Z828u7vLzHZnTcTMzMvMdmdN1M3My8x2Z929u7vLzHZn3b27u8vMfGfMzMzMzMzMzHzGzGxszHbHfMZmbGzMdmd8xmZsbMx2Z2zGZsxszA==\",\n        \"tilemapTile\": true\n    },\n    \"greenSwitchDown\": {\n        \"data\": \"hwQQABAAAAB2Z8zMZsxszHZnbMxmbGzMdmd8xmZszMx8ZnzGzGzMzMzMzMzMzGzMdmfdvbu7y8x2Z929u7vMzHZn3b3M3UTMdmfdvczMRMx2Z929u7vLzHZn3b27u8vMfGfMzMzMzMzMzHzGzGxszHbHfMZmbGzMdmd8xmZsbMx2Z2zGZsxszA==\",\n        \"tilemapTile\": true\n    },\n    \"hazardWater\": {\n        \"data\": \"hwQQABAAAACMaJaWmZmZmYxolpaZmZmZjIhmlpmZmZmMhmaWmZmZmYyGZpmZmZmZjGZmmZmZmZmMaGaZmZmZmYxolpaZmZmZjGiWlpmZmZmMZpaWmZmZmYxmlpmZmZmZjIZmmZmZmZmMhmaZmZmZmYyIZpmZmZmZjIiWmZmZmZmMaJaZmZmZmQ==\",\n        \"tilemapTile\": true\n    },\n    \"hazardLava0\": {\n        \"data\": \"hwQQABAAAABVJERCRVREREUiREJVVVVVJCIiVEVFVVUiJERVRCJURCJCVEQiQiJFIkRFJCIkJEUiVEUiJEIiRUJUJCIiIkJFREUkIiIiQkVCRSJEIiRCRUJFIkQiIlJFQlVEIiJCVCRCRVVFRFRVJERVRFVVVUQiVEREVEVVJEJVRCJCRVQkQg==\",\n        \"tilemapTile\": true\n    },\n    \"hazardLava1\": {\n        \"data\": \"hwQQABAAAABFJEJCRVRFREQiIiJEQlVVREIiIkRCRFVFIiJEJCJCVUVERFQkQkJFVERUVSQiQkVUVVVVRCJURURERFVFQlREJCJCRFVEVCQiIkIkVFVVJCJERCJCVUUiIlREQkJVJCREVUUiQkVCQkRVRSJERSIkRFVEIlRFIkJURSRCVFVERA==\",\n        \"tilemapTile\": true\n    },\n    \"hazardHole\": {\n        \"data\": \"hwQQABAAAAC8z////////7zP////////vPz////////M/Pz//////8z8/P//////zPz8//////+8/////////7zP////////vM////////+8z////////8z/////////zPz////////M/Pz//////8z8/P//////zP/////////cz////////w==\",\n        \"tilemapTile\": true\n    },\n    \"hazardSpike\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzM3My7u7u7u7sRzLu7u7u7HRHMvLu7uxsREcy8u7vbERERzMy7uxERERHMzLsdEREREczMGxERERERzMwbERERERHMzLsdEREREczMu7sRERERzLy7u9sRERHMvLu7uxsREcy7u7u7ux0RzLu7u7u7uxG8u7u7u7u72w==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterNorthWest\": {\n        \"data\": \"hwQQABAAAADPqqqqyqyqqvw8MzMzPDMzyswzMzPMMzM6zKyqqsqqqjrDzMzMzMzMOqPMPDMzM8o6o8zMqqqqzDqjrMzMzMzMOqM8ysyqqqo8ozzKzKyqqjyjPMrKzMzMzKM8yqrMrKrMrDzKqszMzDrMPMqqrMyqOqOsyqqszM86o8zKqqys/A==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterNorth0\": {\n        \"data\": \"hwQQABAAAAA6o8zMqsyszDqjrMyqrKzMOqM8yqqszMw8qjzKzKzMzMzMPMrKrKzMOqM8yqqsrMw6ozzKqqyszDqjrMqqzKzMOqPMzKrMrMw6o6zMqqyszDqjPMqqrMzMPKM8yqqszMzMzDzKzKyszDrDPMqqrKzMOqM8yqqsrMw6o6zKqsyszA==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterNorth1\": {\n        \"data\": \"hwQQABAAAAA6o8zMqsyszDqjrMqqzKzMOqM8yqrMzMw8qjzKyszMzMzMPMrMzKzMOqo8yqzMrMw6o6zKrMqszDqjrMysyqzMOqPMzKrKrMw6o6zMqsyszDqjPMqqrMzMPKM8yqqszMzMzDzKzKyszDrDPMqqrKzMOqM8yqqsrMw6o6zKqsyszA==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterNorthEast\": {\n        \"data\": \"hwQQABAAAAA6o8zMqqys/DqjrMyqrKzPOqM8yqqszKw6ozzKqszMzDrMPMqqzKyqzKw8ysrMzMw8ozzKzKyqqjqjPMrMqqqqOqM8zMzMzMw6o8zMqqqqqjqjzKwzMzPKOsPMzMzMzMw6zKyqqqrKqsrMMzMzM8wz/DwzMzPDPDPPqqqqysysqg==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterWest0\": {\n        \"data\": \"hwQQABAAAACqyqyqqsqsqjPDMzMzwzMzM8MzMzPDOjOqzKqqqsqqqszMzMzMzMzMOjMzyjozM8qqqqrMqqqqzMzMzMzMzMzMqsqqqqqqrKqqyqqqqsqsqszMzMzMzMzMrKqqyqyqqsrMzMzMzMzMzKqqzKqqqsyqzMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"purpleInnerNorthWest\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMzMyqqqrMqqrMzMzMzMzMzMzKqqqqqqrKzMrKzMzMzMzMysqqqqqsqszKzDqqqqyqzMrMqsPMzMzMysqqzKqqqszKyqqsMzOjzMrKrKwzzMzMzMrMrMPMqszMyqqsw6ozzMrKqszKOjPMysyqzMw6ow==\",\n        \"tilemapTile\": true\n    },\n    \"purpleInnerNorthEast\": {\n        \"data\": \"hwQQABAAAADMysyqrMo6o8zKyqqswzozzMrKqqzDrDPMysrMrMOsqszMyqqsM8zMzMzKqqwzM8rMysqqzKqqzMzKyqrDzMzMzMrKOqqqrKrMysqqqsqsqszKyszMzMzMzMqqyqyqqsrMzMzMzMzMzMzMqqqqqsyqzMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterEast0\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMqsyqqqrMqqrMzMzMzMzMzMzMzMzMqqrKzMzMqsrMzMyqyqyqqqqsqqqqzMyqqqyqzMzMzMzMzMysqqrKzKqqqqwzM6qsMzOjzMzMzMzMzMyqqqyqqqrMqjOjrDMzMzwzMzM8MzMzPDOqyqyqqsqsqg==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterWest1\": {\n        \"data\": \"hwQQABAAAACqyqyqqsqsqjPDMzMzwzMzM8MzMzPKOjOqzKqqqsqqqszMzMzMzMzMOjMzyqozM8qqqqrMrKqqyszMzMzMzMzMqsqqqszMqqqqyqqqqsqsqszMzKyqzMzMrKqqzMzMzMzMzMzMzMzMzKqqzKqqqsyqzMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"purpleInnerSouthWest\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMqsyqqqqqzMzMzMzMzMzMzKyqqsqsqqzMzMzMzMysrMyqyqyqqqyszKrKqqqjrKzMzMzMPKqsrMzMqqrMqqyszKwzM8qqrMzMzMwzyqqszMyqyjzKzKyszDPKPMqqrKzMM6M8yqqsrMw6o6zKqsyszA==\",\n        \"tilemapTile\": true\n    },\n    \"purpleInnerSouthEast\": {\n        \"data\": \"hwQQABAAAAA6o8zMqsyszDOjrMyqrKzMM6o8yqqszMyqzDzKzKzMzMzMM8rKrKzMOjMzyqqsrMyqqqrMqqyszMzMzDyqzKzMqsqqqqPMrMyqyqqqqqyszMzMzMzMrKzMrKqqqqqqrMzMzMzMzMzMzKqqzKqqqszMzMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterEast1\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMqsyqqqrMqqrMzMzMzMzMzKyqqsqsqqrKzMzMzMzMzMyqyqyqqqqsqqrKqqqqqqyqzMzMzMzMzMzMqqqqzKqqqqwzM6OsMzOjzMzMzMzMzMyqqqyqqqrMqjOjPDMzMzwzMzM8MzMzPDOqyqyqqsqsqg==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterSouthEast\": {\n        \"data\": \"hwQQABAAAACqysysqqqq/DPDPDMzM8PPM8wzMzMzzKyqrKqqqsrMo8zMzMzMzDyjrDMzM8rMOqOqqqqqzMw6o8zMzMzMwzqjqqqqzKzDOqOqqsrMrMM6w8zMzKysw8rMqsrMqqzDzKPMzMyqrMM6o8rMyqqswzqj/MrKqszKOqPPysqqzMw6ow==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterSouth0\": {\n        \"data\": \"hwQQABAAAADMysyqrMo6o8zKyqqswzqjzMrKqqzDPKPMysrMrMPMzMzMyqqswzrDzMzKqqzDOqPMysyqzMo6o8zKrKrMzDqjzMqsyszKOqPMyqzKrMo6o8zKzMqsw6qjzMrMzKzDzMzMzMysrMOqw8zMzKqswzqjzMrMqqzKOqPMysyqzMw6ow==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterSouth1\": {\n        \"data\": \"hwQQABAAAADMysyqrMo6o8zKyqqswzqjzMrKqqzDPKPMysrMrMPMzMzMyqqswzrDzMzKqqzDOqPMysqqzMo6o8zKzKrMzDqjzMrMqqzKOqPMysqqrMM6o8zKyqqswzqjzMrKrKzDzMzMzMrMrMOqw8zMyqqswzqjzMrKqszKOqPMysyqzMw6ow==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterSouthWest\": {\n        \"data\": \"hwQQABAAAADPysqqrMw6o/zMyqqsyjqjqszKqqzDzKPMzMyqrMPKzKrKzKqswzrMzMzMrKzDOsOqqsrMrMM6w6qqqsyswzqjzMzMzMzKOqPMqqqqzMw6o6wzMzPDzDqjzMzMzMzMPKOqqqyqqsrMozMzzDMzM8ysMzPDMzMzw8+qqsqsqqqq/A==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterNorth2\": {\n        \"data\": \"hwQQABAAAAA6o8zMqsyszDqjOsyqrKzMOjM6w6OszMw8MzqjM6zMzMyqOjMzo6zMOjM6ozOqrMw6MzNErKqszDozRBXkrKzMOjNDFeSsrMw6MzNEpKqszDozOjMzqszMPDM6MzOjzMzMqjqjM6qszDrDOqOjrKzMOqM8o6qsrMw6o6zKqsyszA==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterEast2\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMqsyqqqrMqqrMzMzMzMzMzKyqqqqqqqrKzMyjyqw6ysyqOjPqrjOjqqozM0xEMzOqzKyjFEEzqsrMMzNURTMzozwzM0M0MzOjrKqqQzOqqsyqMzozMzPKqjMzOjMzMzozMzM8MzMzPDOqyqyqqsqsqg==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterSouth2\": {\n        \"data\": \"hwQQABAAAADMysyqrMo6o8zKyqo6wzqjzMrKOjqjPKPMyqozOqOqzMzMOjMzozPDzMyqMzOjM6PMyqpKRDMzo8zKyk5RNDOjzMrKTlFEM6PMyqrKRDMzo8zKqjM6ozOjzMo6MzOjqszMzMozOqMzw8zMyjo8ozOjzMrKqsyjOqPMysyqzMw6ow==\",\n        \"tilemapTile\": true\n    },\n    \"purpleOuterWest2\": {\n        \"data\": \"hwQQABAAAACqyqyqqsqsqjPDMzMzwzMzM6MzMzOjMzOqrDMzM6MzqsyqqjM0qqrKOjMzQzQzM8M6MzNURTMzzKyqMxRBOsrMqjMzRMQzM6qqOjPqrjOjqsyso8qsOszMrKqqqqqqqsrMzMzMzMzMzKqqzKqqqsyqzMzMzMzMzMzMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"purpleSwitchUp\": {\n        \"data\": \"hwQQABAAAAA6o8zMqsyszDqjrMyqrKzMOqM8yqqszMw8qjzKzKzMzMzMzMzMzKzMOqPdvbu7y8w6o828u7vLzDqjTcTMzMvMOqNN1M3My8w6o929u7vLzDqj3b27u8vMPKPMzMzMzMzMzDzKzKyszDrDPMqqrKzMOqM8yqqsrMw6o6zKqsyszA==\",\n        \"tilemapTile\": true\n    },\n    \"purpleSwitchDown\": {\n        \"data\": \"hwQQABAAAAA6o8zMqsyszDqjrMyqrKzMOqM8yqqszMw8qjzKzKzMzMzMzMzMzKzMOqPdvbu7y8w6o929u7vMzDqj3b3M3UTMOqPdvczMRMw6o929u7vLzDqj3b27u8vMPKPMzMzMzMzMzDzKzKyszDrDPMqqrKzMOqM8yqqsrMw6o6zKqsyszA==\",\n        \"tilemapTile\": true\n    },\n    \"stairWest\": {\n        \"data\": \"hwQQABAAAADdzMzMzMzM3d28u7u7u8vd3dvd3d3dvd3dzMzMzMzM3d28u7u7u8vd3dvd3d3dvd3dzMzMzMzM3d28u7u7u8vd3dvd3d3dvd3dzMzMzMzM3d28u7u7u8vd3dvd3d3dvd3dzMzMzMzM3d28u7u7u8vdu9vd3d3dvbvMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"stairSouth\": {\n        \"data\": \"hwQQABAAAAC83d3d3d3d3bzd3d3d3d3dvMzLvMzLvMzcy73cy73cy9zLvdzLvdzL3Mu93Mu93Mvcy73cy73cy9zLvdzLvdzL3Mu93Mu93Mvcy73cy73cy9zLvdzLvdzL3Mu93Mu93Mvcy73cy73cy7zMy7zMy7zMvN3d3d3d3d283d3d3d3d3Q==\",\n        \"tilemapTile\": true\n    },\n    \"stairNorth\": {\n        \"data\": \"hwQQABAAAADd3d3d3d3dy93d3d3d3d3LzMu8zMu8zMu8zdu8zdu8zbzN27zN27zNvM3bvM3bvM28zdu8zdu8zbzN27zN27zNvM3bvM3bvM28zdu8zdu8zbzN27zN27zNvM3bvM3bvM28zdu8zdu8zczLvMzLvMzL3d3d3d3d3cvd3d3d3d3dyw==\",\n        \"tilemapTile\": true\n    },\n    \"stairEast\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzLvb3d3d3b273by7u7u7y93dzMzMzMzM3d3b3d3d3b3d3by7u7u7y93dzMzMzMzM3d3b3d3d3b3d3by7u7u7y93dzMzMzMzM3d3b3d3d3b3d3by7u7u7y93dzMzMzMzM3d3b3d3d3b3d3by7u7u7y93dzMzMzMzM3Q==\",\n        \"tilemapTile\": true\n    },\n    \"stairLarge\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzMzMzMy7u7u9zMzMzLu7u73MzMzMu7u7vczMzMy7u7u9zMzMzMzMvLvMzLu7u9u7u8zMu7u727u7zMy7u7vbu7vMzLu7u9u7u8zMzMzMu7u7vLu7u9u7u7u8u7u727u7u7y7u7vbu7u7vLu7u9u7u7vMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"stairLadder\": {\n        \"data\": \"hwQQABAAAADu7u7u7u7u7kNOREREQ+7uQ+7u7u5DzuxDTj7kQ0PO7ENOPuRDQ87sQ04+5ENDzuxDTj7kQ0PO7ENOPuRDQ87sQ04+5ENDzuxDTj7kQ0PO7ENOPuRDQ87sQ04+5ENDzuxDTj7kQ0PO7EPu7u7uQ87sQ05ERERD7u7u7u7u7u7u7g==\",\n        \"tilemapTile\": true\n    },\n    \"statueLight\": \"hwQQACAAAAAAAAAAAAAAAAAAOzMzOxHLAAAAAAAAAAAAsBEREbEzswAAAAAAAAAAALARERGxM7MAAAAAAAAAEwCwMRMRETOzAAAAAAAwM7MAsBMxEREzswAAAAC7u8s8MzMzERMRs7MAETM7M8w8EREREREzEbOzEDOxEzEzERERETMzMxGzsxATETszERERMTMzMzMRs7MQEzETERMREREREREzEbOzAAAQMRsxERERERERMxGzswAAABExEQATERExMxMRM7MAAAAAAAAAAAATETMTETOzAAAAAAAAAAAAsDMTEbEzswAAAAAAAAAAALARERGxM7MAAAAAAAAAAAAAOzMzOxHL\",\n    \"statueDark\": \"hwQQACAAAAAAAAAAAAAAAAAAvLu7vN38AAAAAAAAAAAAwN3d3c27ywAAAAAAAAAAAMDd3d3Nu8sAAAAAAAAA2wDAvdvd3bvLAAAAAACwu8sAwNu93d27ywAAAADMzPy/u7u73dvdy8sA3bu8u/+/3d3d3d273cvL0LvN27273d3d3bu7u93Ly9Db3by73d3dvbu7u7vdy8vQ273b3dvd3d3d3d273cvLAADQvdy93d3d3d3du93LywAAAN293QDb3d29u9vdu8sAAAAAAAAAAADb3bvb3bvLAAAAAAAAAAAAwLvb3c27ywAAAAAAAAAAAMDd3d3Nu8sAAAAAAAAAAAAAvLu7vN38\"\n}","sprites.dungeon.ts":"namespace sprites.dungeon {\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile electronics\"\n    export const buttonOrange = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile electronics\"\n    export const buttonOrangeDepressed = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile electronics\"\n    export const buttonTeal = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile electronics\"\n    export const buttonTealDepressed = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile electronics\"\n    export const buttonPink = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile electronics\"\n    export const buttonPinkDepressed = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile dungeon\"\n    export const chestClosed = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile dungeon\"\n    export const chestOpen = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile dungeon\"\n    export const collectibleInsignia = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile dungeon\"\n    export const collectibleRedCrystal = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"?tile dungeon\"\n    export const collectibleBlueCrystal = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const darkGroundNorthWest0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const darkGroundNorth = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const darkGroundNorthEast0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const darkGroundNorthWest1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const darkGroundWest = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const darkGroundCenter = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const darkGroundEast = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const darkGroundNorthEast1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const darkGroundSouthWest0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const darkGroundSouth = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const darkGroundSouthEast0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const darkGroundSouthEast1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const darkGroundSouthWest1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const doorClosedWest = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const doorClosedSouth = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const doorClosedNorth = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const doorClosedEast = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const doorOpenWest = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const doorOpenSouth = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const doorOpenNorth = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const doorOpenEast = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const doorLockedWest = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const doorLockedSouth = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const doorLockedNorth = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const doorLockedEast = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorLight0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorLight1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorLight2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorLightMoss = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorLight3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorLight4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorLight5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorMixed = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorDark0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorDark1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorDark2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorDarkDiamond = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorDark3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorDark4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const floorDark5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterNorthWest = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterNorth0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterNorth1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterNorthEast = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterWest0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenInnerNorthWest = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenInnerNorthEast = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterEast0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterWest1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenInnerSouthWest = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenInnerSouthEast = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterEast1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterSouthEast = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterSouth0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterSouth1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterSouthWest = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterNorth2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterEast2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterSouth2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenOuterWest2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenSwitchUp = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const greenSwitchDown = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const hazardWater = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const hazardLava0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const hazardLava1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const hazardHole = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const hazardSpike = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterNorthWest = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterNorth0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterNorth1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterNorthEast = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterWest0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleInnerNorthWest = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleInnerNorthEast = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterEast0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterWest1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleInnerSouthWest = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleInnerSouthEast = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterEast1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterSouthEast = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterSouth0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterSouth1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterSouthWest = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterNorth2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterEast2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterSouth2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleOuterWest2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleSwitchUp = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const purpleSwitchDown = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const stairWest = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const stairSouth = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const stairNorth = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const stairEast = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const stairLarge = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile dungeon\"\n    export const stairLadder = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const statueLight = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"dungeon\"\n    export const statueDark = image.ofBuffer(hex``);\n}\n","sprites.kaiju.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.kaiju\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"egg\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsLvMDAAAALDbvdvLAACwGxEz290MALARETPd3csAGxETEdG7zQAbERER0bvNABszERHR3c0AGzMTEbPbzQCwMRMxs9vLALAbETG73QwAALDb3d3LAAAAALC7zAwAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"eggRolling\": \"hwQVABUAAAAAsLvMzMwAAAAAAAAAu9u7u83MDAAAAACwGzEzu9vdzAwAAAC7ETEzM7vd3cwAAAC7ETEzM7Pd3c0MAAAbEREzMxPd3d3MAAAbERERERHd3d3NDAAbERERERHR3bvLDAAbERERERHRvbu7DAAbETMRERHRvbu7DAAbETMRERHRvbu7DAC7ERERERHR3bvbDACwERERERHR3d3dDACwERERMxPR3d3dDACwGxExMzPd3d3dDAAA2xExM7Pb3d3NDAAAuxExs7vbvdvNAAAAsNvdu7vdvdvMAAAAALvd3d3d3c0MAAAAALC73d3dzcwAAAAAAACwu8vMzAAAAAA=\",\n    \"kaijuBabyLarge\": \"hwQfAB4AAAAAAAAAAAAAAADAzMwAAAAAAAAAAAAAAAAAANzNDAAAAAAAAAAAAAAAAADA3cwAAAAAAAAAAAAAAAAAwN3NAAAAAAAAAAAAAAAAAMDdzQwAAAAAAAAAAAAAAADM3d0MAAAAAAAAAAAAAAAA3N3dDAAAAAAAAMzMzMzMzN3d3QwAAAAAAMxVVdXd3d3d3d0MAAAAAFxVVVVV1d3d3b27zAwAAMBVVVVVVVXd3d273c3MAABcVVVVVVVV1d3dXVVVxQDAVbW8VVVVVVXdXVVVVcUAwFXFzFVVVVVV1V1VVVXFAFxVFby1VVVVVVVVVVVVxQBcVVVVVVtVVVVVVVVVVcUAXFVVVVVbVVVdVVVVVVXFAFxVVVVVvFVVXVVVVVW7xQBcVVVVxcNVVVtV1VXFzMUAXFVVVREzVbVbVVW92wzMAFxVVVXMM1VcVV1V3d0MAABcVVVVzDPFVVVdVd3NDAAAXFVbxcxTxVVVW1XdzQAAAMBVVcu8XcVVu1VV3cwMAADAVbvb3V3FvFtV1c3cDAAAANzd3d3dVVVVVdXM3QwAAADAzMy73VVVVdXNvL0MAAAAAMDcvbtcVVXNzNzNAAAAAADA3d3MwMzMzADcDAAAAAAAwN29DAAAAAAAzAAAAAAAAADMzAAAAAAAAAAAAAAA\",\n    \"kaijuBabyWalk0\": \"hwQQABAAAAAAAMzMDAAAAADAVcW1wAwAAFxVtVO8DMwAXFW1U7vMvMBVVRVTy8y8wFVVtVVczLzAVfFVVVXMzMBV/1VVtd3bAFxVVVW7XVUAXFVVVd1dVQDAVVXd3b27AABcVd3d3cwAAMDc3d3dDAAAAMDMzN0MAAAAAADczQAAAAAAAMAMAA==\",\n    \"kaijuBabyWalk1\": \"hwQQABAAAAAAwMzMAAAAAABcxVUMzAAAwFW1M8XLAADAVbUztcsAAFxVFTO1zAzMXFW1VcXFzLxc8VVVW8XcvFz/VVVV21u8XFVVVbXbVczAVVVV1d21DABcVdXd3bsMAMBV1d3dzQAAAMzd3d3NAAAAAMzM3M0AAAAAAADcDAAAAAAAAMwAAA==\",\n    \"kaijuBabyWalk2\": \"hwQQABAAAAAAwMzMAAAAAABcxVUMzAAAwFW1U8XLAADAVbVTtcsAAFxVFVO1zMzMXFW1VcXF3Lxc8VVVW8VbvFz/VVVV21W8XFVVVbXbtczAVVVV1d27DABcVdXd3c0MAMBV1d3dzQAAAMzd3d3NAAAAAMzM3AwAAAAAAADcDAAAAAAAAMwAAA==\",\n    \"kaijuBabyWalk3\": \"hwQQABAAAAAAwMzMAAAAAABcxVUMzAAAwFW1U8XLAADAVbVTtcsMAFxVFVO1zMwMXFW1VcXFtcxc8VVVW7VVvFz/VVVVu1u8XFVVVbXbtbzAVVVV1d21zABcVdXd3c0AAMBV1d3dzQAAAMzd3d3NAAAAAMzM3M0AAAAAAADMzQAAAAAAAMDMAA==\",\n    \"kaijuBabyWalk4\": \"hwQQABAAAAAAAMzMDAAAAADAVcy1wAwAAFxVO1O8DAAAXFU7U7vMzMBVVbFTy8zLwFVVu1VczMzAVfFVVVXM3MBV/1VVtd1bAFxVVVW7XVUAXFVVVd1dtQDAVVXd3b3LAABcVd3d3QwAAMDc3d3dDAAAAMDMzN0MAAAAAADAzQAAAAAAAMDMAA==\",\n    \"kaijuBabyWalk5\": \"hwQQABAAAAAAAMzMDAAAAADAVcW1wAwAAFxVtVO8DMwAXFW1U7vMy8BVVRVTy8zLwFVVtVVczMzAVfFVVVXMzMBV/1VVtd3cAFxVVVW7XVUAXFVVVd1dVQDAVVXd3b3LAABcVd3d3QwAAMDc3d3dDAAAAMDMzM0AAAAAAADAzQAAAAAAAMAMAA==\",\n    \"kaijuBabyWalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.kaiju.kaijuBabyWalk0\\\",\\\"sprites.kaiju.kaijuBabyWalk1\\\",\\\"sprites.kaiju.kaijuBabyWalk2\\\",\\\"sprites.kaiju.kaijuBabyWalk3\\\",\\\"sprites.kaiju.kaijuBabyWalk4\\\",\\\"sprites.kaiju.kaijuBabyWalk5\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"kaijuBabyWalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.kaiju.kaijuBabyWalk0\\\",\\\"sprites.kaiju.kaijuBabyWalk1\\\",\\\"sprites.kaiju.kaijuBabyWalk2\\\",\\\"sprites.kaiju.kaijuBabyWalk3\\\",\\\"sprites.kaiju.kaijuBabyWalk4\\\",\\\"sprites.kaiju.kaijuBabyWalk5\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"kaijuMomAttack0\": \"hwQYABgAAAAAAAAAAAAAAMAMAAAAAAAAAAAAAMDNAAAAAAAAAAAAzMDdDAAAAAAAAMAMzMzdDAAAAAAAAMAMzLzdzQAAAADADAC83d3dzQAAAADAzLvd3d3dvQwAAMwAvFXV3d3duwwAAMwMW1XV3d29y8wAAMy8VVXd3d3du80AAMBbVdXdu93V3c0AzMBVVdXdVVtV3cUAzMxVVVXdVcVV1cUAzFxVVVXdW7VV1cUAwFxVVVXVu1W8zM0AAFxVX1XVvVW8y8wAAFxV/7VVvcy73AwAAFxV8bVbvbvL3QwAAFxVVRWzxczM3AwAAMBVVTUzxc0AwAwAAMBV1bUzxQwAwAwAAABcVbVVxQAAAAAAAADAVcXMDAAAAAAAAAAAzAwAAAAAAAA=\",\n    \"kaijuMomAttack1\": \"hwQYABgAAAAAAAAAAAAAAADMAAAAAAAAAAAAAADcDAAAAAAAwAzAAMDdDAAAAMAMwMzADMzdzQAAAMDMAMzLzLzdzQAAAADMu93d3d3dzQAAzAy7VdXd3d3dvQwAzLxVVVXd3d3duwwAwFtVVd273d29y8zMwFVV1b1V293du83MXFVV1d1VtV3V3c3MXFVV3d1VVVtV3cXAVVXVVd3LVbVV1cXAVfVVVbW7XMVV1cXAVfVfVbW7y7y7zM3AVRVfVbW7u7u7y8zAVVVVXdW7u7u72wwAXFVVtV28u7u73AwAXFVdtVW8u7u73AwAwFVVtVXMu7vLzAwAAFxVtcUAzMwMwAwAAMDMzAwAAMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"kaijuMomAttack2\": \"hwQYABgAAAAAAAAAAAAAAAAAzAAAAAAAAAAAAADAzQAAAAAAwAzAAADczQAAAMAMwMzADMzbzQAAAMDMAMzLzLzdzQAAzAy7VdXd3d3dzQAAzLxVVVXd3d3dvQwAwFtVVd3d3d3duwzMwFVV1b273d29y8zMXFVV3d1V293du83MXFXVXdVVtV3V3c3AVbXVVVVVVVtV3cXAVcVVVVXLVbVV1cXAVcVVVVW7XMVV1cXAVVVcVVW7y7y7zM3AVVVVXdW7u7u7y8wAXFVV1V27u7u72wwAXFVdtVW8u7u73AwAwFVVtVW8u7u73AwAAFxVtcW8u7u7zAwAAMDMzAzAu7vLwAwAAAAAAAAAzMwMAAAAAAAAAAAAAMwAAAAAAAAAAAAAAAAAAAA=\",\n    \"kaijuMomAttack3\": \"hwQYABgAAAAAAAAAAAAAAMzMAAAAAAAAAAAAwN3NDAAAAAAAAAAAwNzdDAAAAAAAAAAMzLzdzQAAAAAAAADMzNzdzQAAAAAAzADA293dvQwAAAAAzLzb3d3dvQwAAMAMwFtV3d3duwwAAMDMsFVV3d29y8wAAMDMW1XV3d3du80AAAC8VVXd3btd3c0AwAxcVVXd3VVb3cUAwMxcVVXV3VW11cUAwMxVVVXV3Vu11cUAAMxVtVVVVbtVzM0AAMBVxVW1W7VVzMwAAMBVxVW7u1vL3AwAAMBVVVy7u7tV2wwAAMBVVVWxuzNT3AwAAABcVVU7MzNTzAwAAABcVV07MzNTDAAAAADAVVVbVVXFAAAAAAAAXFXMzMwMAAAAAAAAwMwAAAAAAAA=\",\n    \"kaijuMomAttack4\": \"hwQYABgAAAAAAAAAAAAAAMzMAAAAAAAAAAAAwN3NDAAAAAAAAAAAwNzdDAAAAAAAAAAMzLzdzQAAAAAAAADMzNzdzQAAAAAAzADA293dvQwAAAAAzLzb3d3dvQwAAMAMwFtV3d3duwwAAMDMsFVV3d29y8wAAMDMW1XV3d3du80AAAC8VVXd3btd3c0AwAxcVVXd3VVb3cUAwMxcVVXV3VW11cUAwMxVVVXV3Vu11cUAAMxVtVVVVbtVzM0AAMBVxVW1W7VVzMwAAMBVxVW7u1XL2wwAAMBVVVy7u1u12wwAAMBVVVWxOzPF3AwAAABcVVU7MzPFwAwAAABcVV07MzPFAAAAAADAVVVbVVUMAAAAAAAAXFXMzMwAAAAAAAAAwMwAAAAAAAA=\",\n    \"kaijuMomAttack5\": \"hwQYABgAAAAAAAAAAAAAAMzMAAAAAAAAAAAAwN3NDAAAAAAAAAAAwNzdDAAAAAAAAAAMzLzdzQAAAAAAAADMzNzdzQAAAAAAzADA293dvQwAAAAAzLzb3d3dvQwAAMAMwFtV3d3duwwAAMDMsFVV3d29y8wAAMDMW1XV3d3du80AAAC8VVXd3btd3c0AwAxcVVXd3VVb3cUAwMxcVVXV3VW11cUAwMxVVVXV3Vu11cUAAMxVtVVV3btVzM0AAMBVxVVVVb1VzMwAAMBVxVW7W1XL2wwAAMBVVVy7u1W73QwAAMBVVVWxM1PM3AwAAABcVVU7M1MMwAwAAABcVV07M1MMAAAAAADAVVVbVcUAAAAAAAAAXFXMzAwAAAAAAAAAwMwAAAAAAAA=\",\n    \"kaijuMomAttackRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.kaiju.kaijuMomAttack0\\\",\\\"sprites.kaiju.kaijuMomAttack1\\\",\\\"sprites.kaiju.kaijuMomAttack2\\\",\\\"sprites.kaiju.kaijuMomAttack3\\\",\\\"sprites.kaiju.kaijuMomAttack4\\\",\\\"sprites.kaiju.kaijuMomAttack5\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"kaijuMomAttackLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.kaiju.kaijuMomAttack0\\\",\\\"sprites.kaiju.kaijuMomAttack1\\\",\\\"sprites.kaiju.kaijuMomAttack2\\\",\\\"sprites.kaiju.kaijuMomAttack3\\\",\\\"sprites.kaiju.kaijuMomAttack4\\\",\\\"sprites.kaiju.kaijuMomAttack5\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"kaijuMomLarge\": \"hwRNAEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMzMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzLxb1d3NzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMzMzLtVVVXV3c0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMBVu1tVVVVVVd3dzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW1VVVVVVVVXV3c0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALtbVVVVVVVV1d3dDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu7u7VVVVVdXd3cwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu7tbVVXV3d3NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsFVV1d3dzQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALBbVdXd3d0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW1Xd3d3dDADMDAAAAAAAAAAAAAAAAAAAAAAAAADAzAAAAAAAAAAAAFvV3d3d3QzAzAwAAAAAAAAAAAAAAAAAAAAAAAAAwFUMAAAAAAAAAADb3d3d3d3MwN0MAAAAAAAAAAAAAAAAAAAAAADMDLxVywAAAAAAAAAA293d3d3dzNzdDAAAAAAAAAAAAAAAAAAAAADAVbW9VbsMAAAAAAAAsNvd3d3dzczV3QwAAAAAAAAAAAAAAAAAAAAAwFW1vVu7DAAAAAAAALDd3d3NzMxd1czMDAAAAAAAAAAAAAAAAAAAwMzbtVW7VcwAAAAAAAC73d3MzMzdXcXc3QwAAAAAAAAAAAAAAAAAAFxVu7tVVVXNzAAAAAAA3N3MXFXV3V3F3c0AAAAAAAC7zMwMAAAAAABcVbXdVVVV3c0MAAAAwNzNXFVVVd1d1d0MAAAAAAC7W1VVxQwAAAAAvLu73btVVd3dzAAAAMy7XFVVVVXdXVXNDAAAAACwW1VVVVXFDAAAAMzb3bu1VVXd3c0MAMDMu1VVVVVV3V1VzQwAAAAAu1VVVVVVVcUAAADA3N1btVXV3b27y8zMvFtVVVVVVd3dVc0MAAAAsFtVVVW1y8xVzAAAAMDdW7VV3b3b3d3du7tdVVVVVdXd3d3MDAAAALBVVbtV28zMXMUMAAAAzFVbVbtbVVXd3d27VVVVVVXV3d3d3c0AAAC7VVVVtdy9zMxVzAAAAMDM3btbVVVVVV3dvVVVVVVV3d3d3d3MAAAAW1VVVcXMzMzMXMXMzMwAwLtbVVVVVVVV1d1VVVVVVd3d3c3MzAAAAFtVVVXFzMzMzNy121W1DMC7VVVVVVVVVVXdVVVVVVXV3d3NDAAAAABbVVVVxczMzMzMVVVVVcXMVVVVVVVVVVXV3V1VVVVV1d3dzQAAAAAAW1VVVcXMzMzMzDwzEVPV291VVVVVVVVVVd3dVVXdVd3d3cwAAAAAAFtVVVXFzMzMzMwzMzMzVdvd3VVVVVVV1V1d1d3d3d3d3d3MAAAAAABbVVVVVczMzMw8MzMzE1G73d1VVVVVVdVdXdXd3d3d3d3NDAAAAAAAW1VVVVXMzMzMOzMzMzNTu93dXVVVVVVVVdXV3d3d3d3dzQAAAAAAAFtVVVVVy8zMzDMzMzMzU7vd3V1VVVVVVVXV3d3d3d3d3cwAAAAAAABbVVW7VcXMzMwzs7szE1G73d1dVVVVVVVV1d3d3d3d3c0MAAAAAAAAW1VVvVW1zMzMszszMzNTu93dXVVVVVVVVVXV3d3d3d3LDAAAAAAAAFtVVVVVFRHBzMwzMzMzVdvd3V1VVVVVVVVV1d3d3d29ywAAAAAAAABbVVVVVVURy8w8M7O7W9Xb3d1dVVVVVVXVVdXd3d3dvc0AAAAAAAAAW1VVVVVVy8zMMzMTEVW13d3dVVVVVVVV1VXV3d3d3d3NAAAAAAAAAFtVVVVVVcXMzDMzMxFV3d3dXVVVVVVVVVXV3d3d3d3dzQAAAAAAAABbVVVVVVVVu8wzMzNT1d3dXVVVVVVVVVVV1VXd3d3d3c0AAAAAAAAAW1VVVVVVVRHBOzOzVd1VVVVVVVVVVVVVVd1V3d3d3d3NAAAAAAAAALtVVVVVVVUVyzwzW9VdVVVVVVVVVVVVVVXd3d3d3d3dzQAAAAAAAAC7VVVVVVVVVczMzFXdVVVVVVVVVVVVVVVV3d3d3d3d3c0AAAAAAAAAsFVVVctdVVXMzFzVXVVVVVVVVVVVVVVdVdXd3d3d3d3NDAAAAAAAALBVVVXMXFVVzLxV3VVVVVVVVVVVVVVVVV3V3d3d3d3dzQwAAAAAAACwW1VVzFtVVcxVVVVVVVVVVVVVVVVVVVVd3d3d3d3d3b0MAAAAAAAAAFtVVRxbVVVbVVVVVVVVVVVVVVVVVVXV3d3d3d3d3d27zAAAAAAAAAC7VVXFXFW7VVVVVVVVVcxbVVVVVVVV3d3d3d3d3b27u8sAAAAAAAAAsFVVVVVVW1VVVVVVVVVcu1VVVVVV1dXd3d3d3d3d3bvLAAAAAAAAALBbVVVVVVVVVVVVVVVVXLVbVVVVVV3V3d3d3d3d3d3duwwAAAAAAAAAXFVVVVVVVVVVVVXFzMxVzFxV1dVV3d3d3d3d3d3d3d3MAAAAAAAAAMxVVVVVVVVVVVVVxbXLVVXMXF3d3d3d3d3d3d3d3d3dzQwAAAAAAMDLXFVVVVVVVVVVVcVVu9VdVczc3d3d3d3d3d3d3d3d3d0MAAAAAACwy8xVVVVVVVVVVVXFXLXd3V1VzNzd3d3d3d3d3d3d3d3dzAAAAAAAu8zMXFVVVVVVVVVVVVy1u93dVVXM3N3d3d3d3d3d3d3d3c0AAAAAAMvMzMxVVVVVVVVVVVVcu8Xdu1VVVczd3d3d3VXd3d3d3d3NAAAAAADMDADAXFVVVVVVVVVVzFvFvVtbVVXF3d3d3d1V3d3V3d3dzQAAAAAAAAAAwMxVVVVVVVVVVc1Vtb1VW9VVxdzd3V3VXVVVXd3d3c0MAAAAAAAAAMDM3FXVVVVVXdXNXbW7VdvdVVXc3d1VXVVVVVXd3d3NzAAAAAAAAADAu8zd3VXdVd3dzVtVu1XVXVVVzN3d1V1VVVVV1d3d3c0AAAAAAAAAwMvMzN3dXVXd3d28VVVVVVVVVcXd3d1VVVVVVVXd3d3NDAAAAAAAALzLzMzM3V3V3d3dzVVVVVVVVVXF3d3dVVVVVVVV3d3dzQwAAAAAAAC8zMwAwMzc3d3d3d3MVVVVVVVVxd3d3VVVVVVVVdXd3c0MAAAAAAAAzAwAAMDMzNzd3d3dzcxVVVVVVc3d3d1VVVVVVVVV3VXdzAAAAAAAAAAAAADAy8zMzN3d3d2921VVVVXN3d3bXVVVVVVVVV1V3c0AAAAAAAAAAAAAsMvMzMzMzNvd3btdVVXVzd3du11VVVVVVVVdVdzNAAAAAAAAAAAAALDMzMwAzMzMzN273VVV3c3du7vbVVVVVVVVXdXMzQAAAAAAAAAAAADAzAAAAMzMzMDcvd3d3d3MzMzMzFxVVVVVVV3VzcwAAAAAAAAAAAAAAAAAAADAzAwAzN3d3d3NzMzMAADMXFVVVdVd1d0MAAAAAAAAAAAAAAAAAAAAwMwAAADM3d3NzADMDAAAAMzMVdXdXdXdDAAAAAAAAAAAAAAAAAAAAMAMAAAAwMzMzAwAwAAAAAAAwMzMzFzF3cwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzczdzNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAzNzMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADc3QwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwN0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAwAAA==\",\n    \"kaijuMomWalk0\": \"hwQYABgAAAAAAAAAAAAAAMDMAAAAAAAAAAAAAMC9DAAAAAAAAAAAzMDdDAAAAAAAAMAMzMzdywAAAAAAAADMzLzdzQAAAADAzAC83d3dzQAAAADAzLvd3d3dvQwAAMwAvFXV3d3duwwAAMwMW1XV3d3du8wAAMC8VVXd3d3dvdsAAMBbVdXdu91V3d0AzMBVVVXdVdtV1V0AzMxVVVXdVcVdVV0AwFxVVVXdW7XbVVsAwFxVVVXVvVW8y9wAAFxVX1XVvVW8y8wAAFxV/7Vbvcy73AwAAFxV8bVbvbvL3QwAAFxVVRWzxczM2wwAAMBVVTUzxc0AvAwAAMBV1bUzxQwAzAwAAABcVbVVxQAAAAAAAADAVcXMDAAAAAAAAAAAzAwAAAAAAAA=\",\n    \"kaijuMomWalk1\": \"hwQYABgAAAAAAAAAAAAAAMAMAAAAAAAAAAAAAMDNAAAAAAAAAAAAzMDdDAAAAAAAAMAMzMzdDAAAAAAAAMAMzLzdzQAAAADADAC83d3dzQAAAADAzLvd3d3dvQwAAMwAvFXV3d3duwwAAMwMW1XV3d29y8wAAMy8VVXd3d3du80AAMBbVdXdu93V3c0AzMBVVdXdVVtV3cUAzMxVVVXdVcVV1cUAzFxVVVXdW7VV1cUAwFxVVVXVu1W8zM0AAFxVX1XVvVW8y8wAAFxV/7VVvcy73AwAAFxV8bVbvbvL3QwAAFxVVRWzxczM3AwAAMBVVTUzxc0AwAwAAMBV1bUzxQwAwAwAAABcVbVVxQAAAAAAAADAVcXMDAAAAAAAAAAAzAwAAAAAAAA=\",\n    \"kaijuMomWalk2\": \"hwQYABgAAAAAAAAAAAAAAADMAAAAAAAAAAAAAMDcDAAAAAAAAAAAAMDdDAAAAAAAAADAzLzdzQAAAAAAwMwAzNzdzQAAAADMAMy83d3dzQwAAADMvNvd3d3dvQwAAADMW1Xd3d29uwwAwMywVVXV3d29uwwAwMxbVdXd3d29uwwAwLxVVd29293du80AAFxVVd1d213V3c3AzFxVVd1dxV1V3cXAzFVVVdVdxdtV1cUAzFVVVVW9VbxdtcUAwFVfVVW9Vby7y80AwFX/tVW1Vby73AwAwFXxtbvVu7vM3AwAwFVVVTFbzMzMwAwAAFxVVTNTzFzFwAwAAFxVXTtTDFwMAAAAAMBVVVvFAMwAAAAAAABcVcwMAAAAAAAAAADAzAAAAAAAAAA=\",\n    \"kaijuMomWalk3\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMAAAAAAAAAAAAANy9DAAAAAAAAADAzMzdywAAAAAAwMwAzNzdzQAAAADMAMy83d3dzQwAAADMvNvd3d3dvQwAAADMW1Xd3d29uwwAwMywVVXV3d29uwwAwMxbVdXd3d29uwwAwLxVVd292929uwwAAFxVVd1d293duwzAzFxVVd1dxV3V3QzAzFVVVdVdxV1VXcUAzFVVVVW9VdzVVcUAwFVfVVW9VbxdVcUAwFX/tVW1VbxcVQwAwFXxtbvVu7tcxQAAwFVVVTFbzMzMAAAAAFxVVTNTzFzFAAAAAFxVXTtTDFwMAAAAAMBVVVvFAMwAAAAAAABcVcwMAAAAAAAAAADAzAAAAAAAAAA=\",\n    \"kaijuMomWalk4\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMAAAAAAAAAAAAwN29DAAAAAAAAADAzNzdywAAAAAAwMwAzLzdzQAAAADMAMy83d3dzQwAAADMvNvd3d3dvQwAAADMW1Xd3d29uwwAwMywVVXV3d29uwwAwMxbVdXd3d29uwwAwLxVVd292929uwwAAFxVVd1dxd3dvcvAzFxVVd1dxd1V1c3AzFVVVdVdVdtV1VUAzFVVVVW9Vbzd1VUAwFVfVVW9VbzbXVUAwFX/tVW1Vby7XFUAwFXxtbvVu7vLXMUAwFVVVTFbzMzMzAwAAFxVVTNTzFzFAAAAAFxVXTtTDFwMAAAAAMBVVVvFAMwAAAAAAABcVcwMAAAAAAAAAADAzAAAAAAAAAA=\",\n    \"kaijuMomWalk5\": \"hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMzMAAAAAAAAAAAAzN3LDAAAAAAAAMwAzNy9DAAAAAAAAMwMzNzdzAAAAADMAMC83d3dzQAAAADMvNvd3d3dvQwAAADAW1Xd3d3duwwAwMywVVXV3d3duwwAwMxbVdXd3d3duwwAALxVVd29291VvcsAAFxVVd1dtd1V1d3AzFxVVdVdVdxdVV3AzFVVVdW9W8XbVV0AzFVVVVXdW8W7W10AwFX1VVXdW8W7y1sAwFX1X1vVy7y7zNwAwFUVX7vVu7vMDMAAwFVVVTFbzMy8DAAAAFxVVTNTzFXMAAAAAFxVXTtTzMUAAAAAAMBVVVtVzAwAAAAAAABcVczMAAAAAAAAAADAzAAAAAAAAAA=\",\n    \"kaijuMomWalkRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.kaiju.kaijuMomWalk0\\\",\\\"sprites.kaiju.kaijuMomWalk1\\\",\\\"sprites.kaiju.kaijuMomWalk2\\\",\\\"sprites.kaiju.kaijuMomWalk3\\\",\\\"sprites.kaiju.kaijuMomWalk4\\\",\\\"sprites.kaiju.kaijuMomWalk5\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"kaijuMomWalkLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.kaiju.kaijuMomWalk0\\\",\\\"sprites.kaiju.kaijuMomWalk1\\\",\\\"sprites.kaiju.kaijuMomWalk2\\\",\\\"sprites.kaiju.kaijuMomWalk3\\\",\\\"sprites.kaiju.kaijuMomWalk4\\\",\\\"sprites.kaiju.kaijuMomWalk5\\\"],\\\"flippedHorizontal\\\":true}\"\n    }\n}","sprites.kaiju.ts":"namespace sprites.kaiju {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const egg = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const eggRolling = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuBabyLarge = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuBabyWalk0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuBabyWalk1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuBabyWalk2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuBabyWalk3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuBabyWalk4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuBabyWalk5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuMomAttack0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuMomAttack1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuMomAttack2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuMomAttack3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuMomAttack4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuMomAttack5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuMomLarge = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuMomWalk0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuMomWalk1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuMomWalk2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuMomWalk3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuMomWalk4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const kaijuMomWalk5 = image.ofBuffer(hex``);\n}\n","sprites.projectile.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.projectile\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"bubble1\": \"hwQQABAAAAAAALC7uwsAAACwm5lVtQsAALvZPTNdvQCwm92ZPTPVC7DZmZmZM1MLm5mZmZk507WbmZmZmdkztZuZmZmZmTO1m5mZmZmZM7WbmRGRmZkztZuZEZGZmVO1sJkRkZnZXQuwm5kZmd21CwC7mZnZXbsAALCbmZm5CwAAALC7uwsAAA==\",\n    \"bubble2\": \"hwQQABAAAAAAAAAAAAAAAACwuwCwuwAAAJuzAFu1AAAAG7kAG7W7AACwu7u7u1ULAACwWbW7VQsAAJs9U7tRC7C7m5lTu7sAm7kbkZ0LAAAbuRuRubu7ALALsLu7kzkLAAC7C7AZkQsAsDkLsBmRCwCwmQsAkzkLALCRCwCwuwAAALsAAAAAAA==\",\n    \"bubble3\": \"hwQQABAAAAAAAAAAAACwCwAAAAAAAFu1AAAAAAu7VbUAAACwuZldCwAAALDZPbkAAAAAsJ05swAAAACwmZmzAAAAALCZmbMAAAAAuxGZvQAAALCZEZm9AAAAsJGdmbsLAAAAu5vZm7MAAAAA272buQAAAACbuRu5AAAAABu5sAsAAAAAsAsAAA==\",\n    \"bubble4\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAAAAAAAAARAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAQAQAAAAAAABABAAAAAAAAAAAAAAAAABARAAAAAAAAEBEAEAAAAAAQEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"bubble\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.projectile.bubble1\\\",\\\"sprites.projectile.bubble2\\\",\\\"sprites.projectile.bubble3\\\",\\\"sprites.projectile.bubble4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"drop1\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAiMyMAACAiMxERMQIAEBERERERAgAgIjMRETECAAAAIDIzIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"drop2\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAgAAAAAAMBEDAAAAAAASEQEAAAAAABMRIQAAAAAAExEhAAAAAAATESEAAAAAABMRIQAAAAAAExEhAAAAAAASEQMAAAAAADARAwAAAAAAACACAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"drop3\": \"hwQQABAAAAAAAAAAAAAAAAAAAEQkAgAAAABE1VUtIAAAQF3VVUUiAgBAVRVR1SICAEQdEdHdJCQAVBVRFVEtJABUFVERUUUkAFTVVRFRRSQA1N0RVVVNJABAXREV0S0kAEBdVR3RJAIAQFRVXVUkAgBARNRdRQAAAAAARCQCAAAAAAAAAAAAAA==\",\n    \"drop4\": \"hwQQABAAAAAAACBCALsLAAAiQkSw3QsAAEJURdvdvQIgVV1F27uxIkJV3QTbu9EkQl1VBNu700RCVFUkIrIRRFLVVU1EtBFEUlXVVUS0PURCVdVVIrLRREJU1Q3bu90kQkRdBdu7ESQgVFRF27uxIiBEVEXb3b0CICJERLDdCwAAIEJEALsLAA==\",\n    \"drop5\": \"hwQQABAAAAAAAAAAALDMAAAAuwsA270MALDdC7Dd3QwA290LsMzbywDbvQCwvNvNALsLANAMsM0AAAAA0AuwzQAAAADQCwDNuwAAANALAMu7ALAL0AsAAAAAsAvQvAAMAAAAALDMuwwAALsAsM3cDACw3Quw3d0MALDdCwDbzQwAALsAALDMDA==\",\n    \"drop\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.projectile.drop1\\\",\\\"sprites.projectile.drop2\\\",\\\"sprites.projectile.drop3\\\",\\\"sprites.projectile.drop4\\\",\\\"sprites.projectile.drop5\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"explosion1\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAgAAAAAAAFQlAAAAAAAAVCUAAAAAAABAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"explosion2\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAIAAAAAAAAAJAIABAAAAABAJUIEAAAAANBVRQAAAAAAVFUEAAAAAEBVVQIAAAAARERUJAAAAAAAAEBEAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"explosion3\": \"hwQQABAAAAAAAAAAAAAAADMDAEQERAREMD1D1URVREUAU11VNVVdBAAwVRXR3U0AAEAdFVE1RAAAVBFRVVVNBABUEVFV1U0EAEAdVdXdTQQAQFURVT1EAADUFRFV3UMAANQdEd1VTQBATVRd1VVNBERERFTVRAREAAAAREQAAEAAAAAAAAAAAA==\",\n    \"explosion4\": \"hwQQABAAAAAAAAAAAAAAAAAAsAu7uwsAAAAbMRGxvQAAABvRHd3dCwCw09Gz290LABvRuwCwPQsAG7EAAAA7vQCwvQAAALC9ABu9AAAA270AG7EAAAA7vQAbvQAAsDO9ALAdu7DbvQsAABvdu929AAAAux0R07MAAAAAG9G9CwAAAACwuwsAAA==\",\n    \"firework\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.projectile.explosion1\\\",\\\"sprites.projectile.explosion2\\\",\\\"sprites.projectile.explosion3\\\",\\\"sprites.projectile.explosion4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"firework1\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwMAAAAAAAAyMwAAAAAAABIRIzIAAAAAExERMQAAADMRERExAAAwERERESMAADARERERIwAAADMREREhAAAAABMRETEAAAAAEhEjMgAAAAAyMwAAAAAAADADAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"firework2\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAIAAAAAAAATMQAAAAAAIBERAgAAAAAgERECAAAAAAATMQAAAAAAACACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"firework3\": \"hwQQABAAAAAAADADAAAAAAAAMDEAAAAAADMwMQAwAwAAEzMxABMDAAAwISEwMQAAAAATMRIDAAAzMzMRMSIzMxMRERERERExMDMTETEzMwMAIBISEwMAAAAwMRMjMQAAABMDEwITAwAAMwATAzADAAAAABMDAAAAAAAAEwMAAAAAAAAzAAAAAA==\",\n    \"firework4\": \"hwQQABAAAAAAADAzAAAzAzADExEDMBEDEzETEQISEQMTISAhAhIxACAiIAIAIgIAAAAAAAAgAgAAAAAAADIxADMjAAAgEREDExECAAASMQMwIwIAACACAAAAADAAAAAAACMCEgIiAgAwETIRMRIxADARMhExEhEDMDMAEwMwEQMAAAAzADAzAA==\",\n    \"firework5\": \"hwQQABAAAAAAAAAAADMAAAAAAAAwAwAAAAAAAAAAADMAAAAAAAAwAwAAADMAAAAAAAAwAwAAAAAAAAAAAAAAAAAAAAAAADAzAAAAMAMAAAAAAAAAAAAAAAAAMwAAAAAAAAAwAwAAAAAAAAAAMAMAAAAAAAAAMzADAAAAAAAAADMAAAAAAAAAAA==\",\n    \"explosion\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.projectile.firework1\\\",\\\"sprites.projectile.firework2\\\",\\\"sprites.projectile.firework3\\\",\\\"sprites.projectile.firework4\\\",\\\"sprites.projectile.firework5\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"flash1\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAACwvQAAAAAAAMDNAAAAAAAAwMUAAAAAAADc1QwAAACwzF1VzbwAANtdVVVV3QsAsMxdVc28AAAAANzVDAAAAAAAwMUAAAAAAADAzQAAAAAAALC9AAAAAAAAAAsAAAAAAAAAAAAAAA==\",\n    \"flash2\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsL0AAAAAAAC8vQwAAAAAu1xVvAsAAABbVVFVCwAAAFxVUVXMAAC7VRURVbULAN0VERER1Q0Au1UVEVW1CwDAXFVRVcwAAABbVVFVCwAAALtcVbwLAAAAALy9DAAAAAAAsL0AAAAAAAAAAAAAAA==\",\n    \"flash3\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAABEAEBEAEAAAERAREREAAAAAEREREQEAEBAREREREQAAEBERERERAAAREREREREBABEREREREQEAERERERERAQAQEREREREAABAREREREQAAABEREREBAAAAEBEREQAAAAAAEBEAAAEAAAAAAAAAAA==\",\n    \"flash\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.projectile.flash1\\\",\\\"sprites.projectile.flash2\\\",\\\"sprites.projectile.flash3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"heart1\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAPD//w8AAAAA/zMz/wAAAAA/MzPzDwAAAD8zMzP/AAAAPzMzs/sPAAD/MzO7u/8AAPA/M7u7+wAA/zMzu7v/AAA/EzGz+w8AAD8TMTP/AAAAPzMz8w8AAAD/MzP/AAAAAPD//w8AAAAAAAAAAAAAAA==\",\n    \"heart2\": \"hwQQABAAAAAAAAAAAAAAAAD///8PAAAA8D8zM/8AAADwMzMz8w8AAPAzMzMz/wAA8DMzM7v7DwDwMzOzu7v/APA/M7u7u/sPAP8zu7u7uw/wPzO7u7v7D/AzEbG7u/8A8DMRMbv7DwDwMxExM/8AAPAzMzPzDwAA8D8zM/8AAAAA////DwAAAA==\",\n    \"heart3\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8PAAAAAADwM/MPAAAAAPAzM/8AAAAA8DOz+w8AAAAAP7O7DwAAAPAzs/sPAAAA8BMz/wAAAADwM/MPAAAAAAD/DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"heart4\": \"hwQQABAAAAAAsMu8ywAAAADbMRMxDAAAsB0RExHNAACwEREdER0LALAR0TMdEbEAsBHBABsRMwzA080AwNEdywDcEQwA3BGxABwRDAA7EbHAM80AsDMdy7AdzQAcEd0MsBERPR0RwwCwERHRHRELAMATEdHTsQAAADwRPbMMAAAAwLvLzAAAAA==\",\n    \"heart5\": \"hwQQABAAAAAAAAAwAwAAAAAAADAxAAAAMAMAABEDAAAzMQAwMQAAABMRAzADAAAAMBExAAAwMQATEQMAAAARAzMxAAAAMDEAMAMAAAAAAAAAAAAAAAAAAAAwAwAzAwAAABMxABMxAAAAMBEDMBEDAAATMQATMQAAADADADMDAAAAAAAAAAAAAA==\",\n    \"heart\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.projectile.heart1\\\",\\\"sprites.projectile.heart2\\\",\\\"sprites.projectile.heart3\\\",\\\"sprites.projectile.heart4\\\",\\\"sprites.projectile.heart5\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"laser1\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgEzECAAAAACATMQIAAAAAIBMxAgAAAAAgEzECAAAAACATMQIAAAAAIBMxAgAAAAAgEzECAAAAACATMQIAAAAAIBMxAgAAAAAgEzECAAAAACATMQIAAAAAIBMxAgAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"laser2\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDEAAAAAAAAwMQAAAAAAADIhAAAAAAAAMiEAAAAAAAATMQIAAAAAIBMRAgAAAAAgEREDAAAAABIRESEAAAAAEhERIQAAAAASEREhAAAAABIRESEAAAAAIBERAgAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"laser3\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICEAAAAAAAAgIQAAAAAAACAhAAAAAAAQERERAAAAEDEzMzMRAAAxADAxADABAAEAMjECAAEAMwAyMQIwAwAwIzMxIzMAAAAiEREhAgAAABIRERECAAAAMxERMQMAAAAwMzMzAAAAAAAAAAAAAA==\",\n    \"laser4\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwMAAAAAAAAAADADAAAzAAAAADMAMAMAAAAAMAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzADAAAAADADADMAAAAAMwAAMAMAAAAAAAAAADAzAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"laser\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.projectile.laser1\\\",\\\"sprites.projectile.laser2\\\",\\\"sprites.projectile.laser3\\\",\\\"sprites.projectile.laser4\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"star1\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAACwuwAAAAAAALDVy8zMAAAAsNW9W8UAAAC7VV1VzQAAsFtVVdXNAABbVVVV1QwAsF1VVVW1DAAAWxVRVdUMAACwG1FV1c0AAAC7VV1VzQAAALDVvVvFAAAAsNXLzMwAAACwuwAAAAAAAAAAAAAAAA==\",\n    \"star2\": \"hwQQABAAAAAAALC7AAAAAAAAsNULAAAAAACw1b3MzAwAALBVvVtVDACwu1VVVdUMALtVVVVVvQywXVVVVVXLANtVVVVV1csA21VVVVXVywCwXRURVVXLAAC7FRFVVb0MALDbEVVV1QwAALBVvVtVDAAAsNW9zMwMAACw1QsAAAAAALC7AAAAAA==\",\n    \"star3\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7AAAAAAAAAFvLzAwAAAAAW71VDAAAALBVVd0MAAAAW1VVzQAAAABbEVXNAAAAALARVd0MAAAAAFu9VQwAAAAAW8vMDAAAAAC7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"star4\": \"hwQQABAAAAAAALC7CwAAAAAAsB2xALsAAACwERHM3bsAAMARERsRsQCw3B3RHRGxABsRzdzdEb2wERHLvNvdDNARwQzAEbEM293NDLARsQvAHRHMuxvduwAcEdsR2xG9ALDR3RHdEbEAABwRvdsRsQAAHBHNvB29AACwEcwAu7sAALC7AAAAAA==\",\n    \"star5\": \"hwQQABAAAAAAAAAAsAAAAACwAABbuwAAAFu7u1W1CwAAW1u1W7u1u7BVVQu7W1W1W1W1C7BVVbu7VVW7AFtVtbBbW7UAsLW7AFu7uwC7CwAAuwAAsLULAAAAsAC7VbUAAABbu1VVuwAAsFW1u1W1AAAAW7uwtQsAAACwAAC7AAAAAAAAAAAAAA==\",\n    \"star\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.projectile.star1\\\",\\\"sprites.projectile.star2\\\",\\\"sprites.projectile.star3\\\",\\\"sprites.projectile.star4\\\",\\\"sprites.projectile.star5\\\"],\\\"flippedHorizontal\\\":false}\"\n    }\n}","sprites.projectile.ts":"namespace sprites.projectile {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic\"\n    export const bubble1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic\"\n    export const bubble2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic\"\n    export const bubble3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"aquatic\"\n    export const bubble4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const drop1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const drop2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const drop3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const drop4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const drop5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const explosion1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const explosion2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const explosion3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const explosion4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const firework1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const firework2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const firework3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const firework4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const firework5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const flash1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const flash2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const flash3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const heart1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const heart2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const heart3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const heart4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const heart5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const laser1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const laser2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const laser3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const laser4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const star1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const star2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const star3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const star4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const star5 = image.ofBuffer(hex``);\n}\n","sprites.skillmap.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.skillmap\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"akita\": \"hwQhACgAAADLzMzMzMzMzMzMzMwAAAAAAAAAAJuZmZmZmZmZmZmZuf8AAAAAAAAAm7k7k5mZmZmZmZmZ+Q8AAAAAAAC7mbszmZmZmZmZGRER+w8AAAD/D7CbmZn5n8GcmRkRERGx+////7sPALuZmfkfEZyZERERERG7u7u7uw8AwJuZmRkRsZkREREREbu7u7v7DwDAnJkZEfGxmxERERER8f///w8AAMCcmRER/zGzERERERHxAAAAAAAAwJuZERH/MbMZEREREfEAAADw/wC7mZmZER/BnJkRERERsf///5/5sJuZmfkfEcGZmZkREZGZmZmZmfm7mbsz+Z+RnJmZmZmZmZmZmZmZzJu5O5OZmZmZmZmZmZmZmZnMzMwMm5mZmZmZubuZmZmZmZmZzAAAAAC7zMzMzMzMzJmZmZmZmckAAAAAAAAAAAAAAADAm5mZmZmZyQAAAAAAAAAAAAAAAACbmZmZmZnBAAAAAAAAAAAAAAAAAJyZmZmZGcEAAAAAAAAAAAAAAAAAnJmZmZkZwQAAAAAAAAAAAAAAAACcmZmZmRnB/wDwDwAAAAAAAADMzJyZmZmZGcG7/78PAAAAAAAAwJm5m5mZmZkZwbu7uw8AAAAAAACcmdGbmZmZmRnB/7+7DwAAAAAAsJkZ0Z2ZmZmZmcEA8P8AAAAAAACwmRG9m5mZmZmZucwAAAAAAAAAALCZEb27mZmZmZmZyQwAAAAAAAAAsJkR0buZmZmZmZmZzADAzAAAAACwmRkREZuZmZmZmZnJzJzJAAAAALCZmRGRmZmZmZmZmZmZm8kAAAAAAJuZmZmZzMzMzMycmZmZyQAAAAAAu5mZmckMAAAAAMDMzMwMAAAAAAAAu8vMDAAAAAAAAAAAAAA=\",\n    \"bridge\": \"hwQYACsAAADg7v/v7v/v7v/v7v/v7v/v7v///+8AAADu3e7u3e7u3e7u3e7u3e7u3e677u4OAADeu+3eu+3eu+3eu+3eu+3eu+2+6+4OAADeu+3eu+3eu+3eu+3eu+3eu+3+++4PAADu3e7u3e7u3e7u3e7u3e7u3e7+++4PAADg7v7/7v7v7v7v7v7v7v7v7v7//v8AAAAA4Lv+v+v/u/6/6/+7/r/r/7v+bwYAAAAA4Lvuv+v+u+6/6/677r/r/rvubwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvuv+v+u+6/6/677r/r/rvubwYAAAAA4Lv+v+v/u/6/6/+7/r/r/7v+bwYAAADg7v//7v/v7v/v7v/v7v/v7v///+8AAADu3e7u3e7u3e7u3e7u3e7u3e677u4OAADeu+3eu+3eu+3eu+3eu+3eu+2+6+4OAADeu+3eu+3eu+3eu+3eu+3eu+3+++4PAADu3e7u3e7u3e7u3e7u3e7u3e7+++4PAADg7v7v7v7v7v7v7v7v7v7v7v7//v8AAAA=\",\n    \"button\": \"hwQPABAAAAAAAAAAzMzMAABmzMzczcwMYHaXaca9vAxgd3dpxt28y3Z3iJdm3LzLdod4l2bcu8t2iHiXZty7y3Z4eJdm3LvLdoh4l2bcu8t2h3iXZty7y3Z3iJdm3LzLYHd3acbdvMtgdpdpxr28DABmzMzczcwMAAAAAMzMzAA=\",\n    \"cloud\": \"hwQYABAAAAAAAAAAwMwAAAAAALDb3cwAAAAAG9HdywAAALAREb27DAAAsBHR3b0MAACwER0R3QwAu9sRERHRzbAbEREREdHNsBERERER0c0bERERERHdyxsRERER0b3LGxERERER3csbERERERHdzbAREREREdHNsNsRERER0c0A290RERHdzQDbERER0d3NABsRERHR2wwAGxERERG9DACwEdEREc0AAAC7GxERzQAAAAAbEdEMAAAAALARzQwAAAAAAMsMAAA=\",\n    \"decoration0\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzMzMAAAAAAAAAADAPMvDDAAAAAAAAADAM8MzDHUAAAAAAADAzMw7DHBnZgYAAADMw8s7DHAGAGYAAAA8vMPMDGcAAAAAAADMw8vDdwYAAAAAAADAzDPDYAYAAAAAAAAAAMzMYAAAAAAAAAAAAAAAZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"decoration1\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcHAAcHcAYAAAAAAAcHcAd3YAZwcGAAAAx2Z3bHZmB2YHAAAAcMd2d3ZnBwAAAAAAfGd3d+duAAAAAABwx2d3ZnZ+DgAAAABwbGd2d2Zn53AGAAAAZ2x8d253ZnAAAAAAYHdnbuZm5gYAAAAAx3dndnfu7gAAAAAAZ2bHd2d37wAAAAAAcGd253Z2fwAAAAAAx3dnZ2f+Z3AHAAAAwGZ3d3cGAAYGAAAAcHx2d2Z3AAAAAAAAAHcHdwd3BgAAAAAAAAAAAAAAcAYHAAAAAAAAAAAAAGAAAAA=\",\n    \"decoration2\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAJAJAAAAAAAAAAAAAJmZAAAAAAAAAAAAAJCZCQAAAAAAAAAAAJmZAAAAAAAAAAAAAJAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQCQAAAAAAAAAAAACZmQAAAAAAAAAAAJCZmQkAAAAAAAAAAACZmZkAAAAAAAAAAACQmZkJAAAAAAAAAACQmZkJAAAAAAAAAACZmZkAAAAAkAAAAJCZmQkAAAAAmQkAAACZmQAAAAAAkJkAAACQCQAAAAAAmQkAAAAAAAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"decoration3\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAiIgIAAAAAAAAAACIiIiIAAAAAAAAAICIiIiICAAAAAAAAICIiIiIiAAAAAAAAICIiIiIiAgAAAAAAICIiIiIiIgAAAAAAACIiIiIiIgIAAAAAACAiIiIiIiICAAAAACIiIiIiIgIAAAAAICIiIiIiIgAAAAAAICIiIiIiAgAAAAAAICIiIiIiAAAAAAAAICIiIiICAAAAAAAAACIiIiIAAAAAAAAAACAiIgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"decoration4\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwuwAAAAAAAAAAAADb3QsAAAAAAAAAALDd3b0AAAAAAAAAALDd3b0LAAAAAAAAALDd3d28AAAAAAAAAADb3b3MCwAAAAAAAACw3bvMvAAAAAAAAADbvcvMCwAAAAAAALDdu8y8AAAAAAAAALC9y8wLAAAAAAAAALDMzLwAAAAAAAAAAADLzAsAAAAAAAAAAACwuwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"decoration5\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAAAAAAAAAAAAAQE4EcAAAAAAAAAAAQE50cAYAAAAAAAAAQE4EdwYAAAAAAAAAAEQAcAYAAAAAAAAAAAAAAGcAAAAAAABEAAAAAGAAAAAAAEBOBHB3d2YAAAAAAEBOdHdnBgAAAAAAAEBOBABmAAAAAAAAAABEAHAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"decoration6\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMwAAAAAAAAAAAAAzMwMAAAAAAAAAAAAzMzMAAAAAAAAAAAAwMzMDAAAAAAAAAAAAMzMzAAAAAAAAAAAwMzMDAAAAAAAAAAAzMzMAAAAAAAAAAAAzMwMAAAAAAAAAAAAwMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"decoration7\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIgAAAAAAAAAAAAAyIwIAAAAAAAAAAAAiIiIAAAAAAAAAAAAgIiICAAAAAAAAAAAAIiIiAAAAAAAAAAAgIrICAAAAAAAAAAAiIisAAAAAAAAAAAAiIgIAAAAAAAAAAAAgIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"decoration8\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwuwAAAAAAAAAAAAAbEQsAAAAAAAAAALAREbEAAAAAAAAAALARERELAAAAAAAAAAAbERGxAAAAAAAAAACwERERCwAAAAAAAAAbERGxAAAAAAAAALARERELAAAAAAAAALAREbEAAAAAAAAAAAAbEQsAAAAAAAAAAACwuwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"decoration9\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAzAAAAAAAAAAAAADMzAwAAAAAAAAAAMBMRMwAAAAAAAAAAMBERMQMAAAAAAAAAMBERETMAAAAAAAAAMBMRETEDAAAAAAAAADMREREzAAAAAAAAMBMRETEDAAAAAAAAMBERETMAAAAAAAAAMBERMQMAAAAAAAAAMBMRMwAAAAAAAAAAADMzAwAAAAAAAAAAADAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"decoration10\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3AAAAAAAAAAAADQ19BwAAAAAAAAAA0N0ABwAAAAAAAAAA3dVtd3cAAAAAAAAA0N0AcGcAAAAAAAAADQ0NdwYAAAAAAAAAAABwZwAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"decoration11\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADg7g4AAAAAAAAAAAAAPu4AAAAAAAAAAADg7s53d3cGAAAAAAAA7swAcHcGAAAAAADgzgxwd2YAAAAAAAAAAAB3ZwAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"decoration12\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsLAAAAAAAAAACwu7sMAAAAAAAAAAC7u8sAAHAAAAAAALC7vAwAAHcAAAAAALC7DABwdwAAAAAAAAC7dwB3AAAAAAAAAAAHu3sAAAAAAAAAAAC7u7u7DAAAAAAAALC7u8vLd3cAAAAAAAC7u8sHAAAAAAAAAAC3fAcAAAAAAAAAAHAAB3AHAAAAAAAAAHC7ywBwBwAAAAAAALC7uwwAcAAAAAAAAAC7u8vLAHcAAAAAAACwu7u7AAAAAAAAAAAAAACwAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"decoration13\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAHFnZwAAAAAAAAAGEB13ZwAAAAAAAABwd3F3dwcAAAAAABDHd3fGdwYAAAAAANFxdmd3dwcAAAAAYBd3d2Z3ZwcAAAAAYHd3Zxd3dwYAAAAAEHdnZ9FxdwcAAAAA0XF3Zhd3ZwYAAAAAEHd8dnbHdwYAAAAAAHd3d2d3dwYAAAAAAGYXd3ZndwcAAAAAAHbRcXd3dgYAAAAAAHAXd3cXdwcAAAAAAAB3d3fRcQYAAAAAAAAAZ3wXdwYAAAAAAAAAcHd2ZgAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"decoration14\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAmQAAAAAAAAAAAACQkXkAAAAAAAAAAAAAmQAAAAAAAAAAAAAAAAAHAAAAAAAAAJAJAAcAAAAAAAAAAJmRd3cAAAAAAAAAAJAJcAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAACZAHAAAAAAAAAAAJCReXcAAAAAAAAAAACZAHAAAAAAAAAAAAAAAAAAAAAAAAAAAACQCQAHAAAAAAAAAACZkXcAAAAAAAAAAACQCQcAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAA=\",\n    \"fans\": \"hwRTAFAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAfEfEPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ERERDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwHxEREf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/xERzBz7DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8RwRy82/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfscERvN39AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH7HLEdzd/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+xuxHM3f0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfEbsREdv9/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/xERERGxEfH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAfERERsRER//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/xERERERERHx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAfERERERER0f3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////ERERERHd/f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8RERER0d3MzBH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw/xEREdG9zBwR8Q8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPD/ERHRuxsRERH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8RuxERERER8Q8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw/xERERERERH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPD//////xER8f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/HxERERHMERH//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwHxHMvBERERy7EREREf////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/xERzLyxGxHBERERERERERH///8AAAAAAAAAAAAAAAAAAAAAAAAAAB8REREREcE7ExwREREWFhERERERAAAAAAAAAAAAAAAAAAAAAAAAAPAfERERERHBMxO8GxFhZmYRZmYWEQAAAAAAAAAAAAAAAAAAAAAAAADwERERERERwTMTwbsRERYWERYWEREAAAAAAAAAAAAAAAAAAAAAAAAA8BEREREREbsREcGxG2FmZhEWFhERAAAAAAAAAAAAAAAAAAAAAAAAAPARERERERERERHBEdsRFhYREREREQAAAAAAAAAAAAAAAAAAAAAAAADwEREREcHMGxERwRHbHREREWFmZhEAAAAAAAAAAAAAAAAAAAAAAAAA8BERERHBzBsREcER290RERFhYRERAAAAAAAAAAAAAAAAAAAAAAAAAPARERERERERERHBsdvdZhFhEWZmEQAAAAAAAAAAAAAAAAAAAAAAAADwERERERERERERwbvdbWZmZhEREREAAAAAAAAAAAAAAAAAAAAAAAAA8BwREREREREREbzb3d0dEWERZmYRAAAAAAAAAAAAAAAAAAAAAAAAAPAcERERERERERHc3d3d3RERERYREQAAAAAAAAAAAAAAAAAAAAAAAAD/zBERERERERHxzN3d3d0RERFhZhEAAAAAAAAAAADw//////8AAADw380cERERERER///f3b27u7sbERERAAAAAAAAAADw/xERERHx/wAA/93dzBwRERER/w/w/9273R0Ru7sREQAAAAAAAAAA/xEREREREfEP8L+7283MzP///w8AAP+/293dERERuxEAAAAAAAAA8B/BzBsRERER//+7EREREcz//w8AAADw/93d3REREbERAAAAAAAAAPARwcwbGxEREcG8EREREREREf///wAAAP/f3d0RERGxuwAAAAAAAAD/EREREcERERHBHBERERERERER8f///////93dERERsREAAAAAAAAAHxERERHBHBERERwRERERERERERERERGxu//cHREREbsRAAAAAAAAAB8RERERwcwcEREcERERYWEREWZmFhERsbvLzBEREREbEQAAAAAAAAAfEREREcE8MxERHBEREWZmFhEWFhEREbG7u8vMERGxGxEAAAAAAAAAHxERERHBMzMREbwbERFhYRERFhYRERGxu7u7y8wRzBERAAAAAAAAAB8RzLwRyzMTEREcsRERZmYWERERERERsbu7u7vLzMzMEQAAAADwDwAfEcy8sRsRERERHLEREWFhERFmZhYREbG7u7u7u7vLzMwAAP//H/8AHxERERERERERERyxERERERERFhYRERG7u7u7u7u7u8vMAPAfwRzxAP8REREREREREcERGxEREREREWFmFhERu7u7u7u7u7u7zAD/ERHM8QDwERERERERERHMuxERYRYRFhEREREREbu7u7u7u8zMzMzwHxERzPwA8B8RERERERHMHBEREWZmZhZhZmYRERG7u8zMzMzMzBER/xEREcz9AAD/ERERERHMHBEREREREREWYRERERGxu8zM3dzdzRwRER8RERHc/QAA8P8RERHMHBERERERERERERFmZhERsczc3d3b3cwREREfERHB3P0AAADw////vBERERERERHBzMzMzMwREcvc3d3du80cERERHxERwd39AAAAAAAA/xG7ERERERHBzBERERHBzBHMEREREb3MERERER8Ru8vd/QAAAAAA8B8REbsRERERzBERMxMREcHMHBERERHBHBEREcEfEbvL3fwPAAAAAP8RERERGxERERwRETMzERERzBERwczMzBERERHMHxHb3c0c/w8AAPAfEREREbEREcERERExMxMREcERERwRERERERHBHB8Rsd3NERH///+/ERERERHx///PERERMzMRERHBHBHMERERERHBzBH/EREREREREbu7vRsRERER////HxERETMTsRERERwRwcwcERHBzBER8P8fERERERER0d27ERER8Q8A8B8REREREREcEREcERHBHBERwREREQDw/x8RERERERHdvRsREf8AAPAfERERERERHBERHBERzMwREcEREREAAAD/HxERERER3d27EfEPAADwHxERERERERwRERwRzBHBHBHMERERAAAAAP8fEREREd3d/R//AAAA8B8RETMTEREcEREczBEREcwRHBEREQAAAAAA/x8REdHd3f//DwAAAPAfEREzMxG7ERERHBwRERHBzBwREREAAAAAAAD//xHd3f0PAAAAAADwHxERMTMTERERERzMEREREcwRERERAAAAAAAAAPD/////AAAAAAAAAP8RETMzEREREcEcwRwRERHMEREREQAAAAAAAAAAAAAAAAAAAAAAAAD/EREzExERERHBERHMERERwREREREAAAAAAAAAAAAAAAAAAAAAAAAA8B8RERERERERzBERwRwREcEcERERAAAAAAAAAAAAAAAAAAAAAAAAAAD/ERERERERwdwRwcwcERERHBEREQAAAAAAAAAAAAAAAAAAAAAAAAAA8P8RERERwczdEcwREREREcwREREAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////fvbscERERERHBERERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPD///8P37sRwczMzBERwRwREQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/dEREREcEREREcEREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3R0RERHBHBERzBERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8N8dERERERwREcEREQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3REREbEcERHB/xEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8RERG7zBEREfz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//xGx280RERHMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//u93NERERwQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///dzRwREfEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//90cERHxAA==\",\n    \"islandTile0\": {\n        \"data\": \"hwQQABAAAAAAYGZmZmZmZgBmd3d3d3d3YHZ3d3d3d3dgd3d3d3d3d2Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3dw==\",\n        \"tilemapTile\": true\n    },\n    \"islandTile1\": {\n        \"data\": \"hwQQABAAAAB2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3dw==\",\n        \"tilemapTile\": true\n    },\n    \"islandTile2\": {\n        \"data\": \"hwQQABAAAAB2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3Znd3d3d3d3dgd3d3d3d3d2B2d3d3d3d3AGZ3d3d3d3cAYGZmZmZmZg==\",\n        \"tilemapTile\": true\n    },\n    \"islandTile3\": {\n        \"data\": \"hwQQABAAAABmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dw==\",\n        \"tilemapTile\": true\n    },\n    \"islandTile4\": {\n        \"data\": \"hwQQABAAAAB3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dw==\",\n        \"tilemapTile\": true\n    },\n    \"islandTile5\": {\n        \"data\": \"hwQQABAAAAB3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZmZmZg==\",\n        \"tilemapTile\": true\n    },\n    \"islandTile6\": {\n        \"data\": \"hwQQABAAAABmzMzMvLsAAHd3Z2a2uwsAd3d3Zma9uwB3d3dnZt29AHd3d2fd3R0Ad3d3d2bdHQF3d3d3Z9bdAXd3d3dn1t0dd3d3d9bd3R13d3d3Z93dHXd3d3dn1t0dd3d3d2bW3RF3d3dnZtYdAXd3d3d31h0Bd3d3d2bWHQB3d3d3Z9YdAA==\",\n        \"tilemapTile\": true\n    },\n    \"islandTile7\": {\n        \"data\": \"hwQQABAAAAB3d3d3Z9YdAHd3d2fW3R0Bd3d3d2bdHQF3d3d3Z9bdEXd3d3dn1t0dd3d3d2fW3R13d3d3Zt3dHXd3d3dn1t0dd3d3d2fW3R13d3d3Z9bdHXd3d3dn3d0Rd3d3d9bdHQF3d3dnZtYdAXd3d3dn1h0Ad3d3d2bWHQB3d3d3Z9YdAA==\",\n        \"tilemapTile\": true\n    },\n    \"islandTile8\": {\n        \"data\": \"hwQQABAAAAB3d3d3Z9YdAHd3d3dm1h0Ad3d3d3fWHQF3d3dnZtYdAXd3d3dm1t0Rd3d3d2fW3R13d3d3Z93dHXd3d3fW3d0dd3d3d2fW3R13d3d3Z9bdAXd3d3dm3R0Bd3d3Z93dHQB3d3dnZt29AHd3d2ZmvbsAd3dnZra7CwBmzMzMvLsAAA==\",\n        \"tilemapTile\": true\n    },\n    \"kaijuIcon\": \"hwQsACgAAAAAAAAAAAAAvLu7u7vLzLwLAAAAAAAAAAAAAMDc3d3dvcy7uwsAAAAAAAAAAAAAzNy93dvNvLu7CwAAAAAAAAAAAMDM3L3d2827u7sLAAAAAAAAAAAAwMzc3d3dzby7uwsAAAAAAAAAAADAzNy93d27zLu7CwAAAAAAAAAAAMDM3L3d3bvLu7sLAAAAAAAAAAAAwMzc3d3Mu7vb3Q0AAAAAAAAAAADAzNzdzdzd3d3dDQAAAAAAzMzMzMzMzMzM3d3d3d0NAAAAAMC83d3d3d3d3d3d3d3d3Q0AAAAAzLvd273d3dvbvd3b273dDQAAAAC8u93bvd3d29u93dvbvd0NAAAAALy73d3d3d3d3d3d3d3d3Q0AAAAAvLvdvd3b29vb2927u7u7CwAAAAC8u9293dvb29vbzdvd3d0NAAAAAMy73d3d3d3d3d3M3dvb2w0AAAAAwLzd3d3d3d3dzczd3d3dDQAAAAAAzMzMzMy8u7u7zN3b29sNAAAAAAAAAMDM3N3d3d3L293d3Q0AAAAAAAAAwMzc3d3d3d27zLy7CwAAAAAAAAC8zNy92729281VxcwMAAAAAAAAALzL3N3d3d3dXFW1VcUAAAAAAAAAzLvcvdu73ctV1bUzxQwAzAwAAADA3N3d3d3dzVVVNTPFzQC8DAAAAADc3d3d3btcVVUVs8XMzNsMAAAAAMDMzLvb3VxV8bVbvbvL3QwAAAAAAADAzMy8XFX/tVu9zLvcDAAAAAAAAMDMvLtcVV9V1b1VvMvMAAAAAAAAwMy7y1xVVVXVvVW8y9wAAAAAAAAAzLvLXFVVVd1btdtVWwAAAAAAAADAvMzMVVVV3VXFXVVdAAAAAAAAAAAAzMBVVVXdVdtV1V0AAAAAAAAAAAAAwFtV1d273VXd3QAAAAAAAAAAAADAvFVV3d3d3b3bAAAAAAAAAAAAAMwMW1XV3d3du8wAAAAAAAAAAAAAzAC8VdXd3d27DAAAAAAAAAAAAAAAwMy73d3d3b0MAAAAAAAAAAAAAADAzAC83d3dzQAAAAAAAAAAAAAAAAAAAMzMvN3NAAAAAAAAAAAAAAAAAADADMzM3csAAAAAAAAAAAAAAAAAAAAAzMDdDAAAAAAAAAAAAAAAAAAAAAAAwL0MAAAAAAAAAAAAAAAAAAAAAADAzAAA\",\n    \"mailboxIcon\": \"hwQgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADADAAAAAAAAAAAAAAAAAAAvM0AAAAAAAAAAAAAAAAAwLvbDAAAAAAAAAAAAAAAALy7u80AAAAAAAAAAAAAAMC7u7vNAAAAAAAAAAAAAAC8u7u7zWa7AAAAAPD/z8zMvLu7u81n3QAAAAD/u7u7u7+7u9v9Z90AAADwv8zMzPzPu7vd/2fdAAAA8LzMzMz8/7vb/X9n3QAAALy8zMzM//+83f93t90AAAC83MzMzP//3/1/d9bdAADA29vNzPz//8//d2e23QAAwNu93cv8////f3d3Z90AALy73bvdu7u7/3d2d2fdAAC8u9vdy8zMzG93Zne33QDAu7u72929u/vMzGxn1t3g7u7uzMy7y7z7u7trd7bdICIiItzNu8y7z8zMbHe32yDiu7vbvbvMuw9gd2Z3Zt0g4ru7u7vLvPsAZnd2Z2bdIOK8u7u7y7z7YHZ3d3dn3QAAzLu7u8y7DwBgd3dmZt0AAMC8u8vMuw8AZnd3Z9bdAAAAwMzM//8AYHd3d3dm3QAAAAAAAAAAAGBmd2dmxrsAAAAAAAAAAAAAZnd3Zsy7AAAAAAAAAAAAAGB3Z8a8CwAAAAAAAAAAAAAAdmbMuwAAAAAAAAAAAAAAAGDMvAsAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"pigeon\": \"hwRDAEYAAAAAAAAAAAAAzAzAzAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3M3M3cwMAMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzN29293MwM0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwNzdu93dvN0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzdvd3dvd3NzAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDc3d3dvdvd28wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADM3N3d3dvd280MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzNzd3d3dvd3MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzdu9vdvd3NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMC8u9vd3d29zAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADM3bvd3d2928wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADA3bu92929280AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADA3b27u9293c0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADA3d3dvd3d3csAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADA3d3du93d3csMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADA3d3du93dvdsMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADA3d3du7vb3d0MAAAAAAAAAAAAu7sLAAAAAAAAAAAAAAAAAAAA3N3d3b3b3b0MAAAAAAAAALu7ERELAAAAAAAAAAAAAAAAAAAAzN3d3d3b3bsMAAAAAACwuxERERELAAAAAAAAAAAAAAAAAAAAwN3d3d3b3d3MAAAAsLsbERERERG7AAAAAAAAAAAAAAAAAAAAwN3d3b273d3LAAAAsBERERERERGxAAAAAAAAAAAAAAAAAADA////3b273b0LAAAAsN0RERERERGxAAAAAAAAAAAAAAAAAMwcsbv73d29u7sAAAAAsNHdERERERGxAAAAAAAAAAAAAAAAwLwbsbvf3d29ywwAAAAAsBHRHRERERGxAAAAAAAAAAAAAAAAwLsbEfvd3czMzMwAAAAAsBER3RERERGxAAAAAAAAAAAAAAAAvLu7G8vMzLxm1s0MAAAAsBER0d0RERGxAAAAAAAAAAAAAAAAvLu7y8y7u7trNt3MAAAAsBEREdEdERERCwAAAAAAAAAAAAAAvLu7u7u7u7trZtPNDADAzBwRERHdERERCwAAAAAAAAAAAAAAvLu7u7u7u7u7ZtPdvADMM7MRERHRHRERCwAAAAAAAAAAAAAAvLv/u7u7u7u7ZtPdvcszw8wRERERHRERCwAAAAAAAAAAAAAAvLv/u7u7u7trZtPdvcszM7MRERHRHRERCwAAAAAAAAAAAAAAvLu7u7u7u7trNtPd3cszw8wRERHdERERCwAAAAAAAAAAAAAAwLu7u7u7u7trNt3d3c0zM8MREREdERERCwAAAAAAAAAAAAAAwLy7u7u7u7tr1t3d3d08w8wREdEdERERuwAAAAAAAAAAAAAAAMy8u7u7u7tm1t3d3d3NMxsREd0RERERsQAAAAAAAAAAAAAAAADMu7u7a2Zm093d3d29zBER0R0RERERsQAAAAAAAAAAAAAAAADAvLu7a2Y23d3d3d3NzBwR3RERERERsQAAAAAAAAAAAAAAAAAAvLtmZjPd3d3d3b3MM7PRHRERERERsQAAAAAAAAAAAAAAAAAAzGZmNtPd3d3dvcszw8zdERERERERsQAAAAAAAAAAAAAAAAAAwMw7M93d3d3du80zM7MdERERERERsQAAAAAAAAAAAAAAAAAAwN29293d3d3du80zw8wRERERERERsQAAAAAAAAAAAAAAAAAA3N29293d3d3du80zM8MRERER3d3dvQAAAAAAAAAAAAAAAAAA3N27u9vd3d3du908w8wR3d3d3d27uwAAAAAAAAAAAAAAAADA3b3b3d3MzNzd3d3NM9vd3b27u7sAAAAAAAAAAAAAAAAAAADA3b3b3d0MAMDM3d3dzLu7uwsAAAAAAAAAAAAAAAAAAMzMDADM3b3du8sMAADAzN3d3b3MAAAAAAAAAAAAAAAAAAAAwN29y8zb3b3b3bsMAAAAzN3dzLsMAAAAAAAAAAAAAAAAAAAA3N3d3d3d3d3b3b0MAAAAwN3dzcwMAAAAAAAAAAAAAAAAAADA3d3d3d3d3b3b3d0MAAAAwN3du8wAAAAAAAAAAAAAAAAAAADc3d3d3d3du7vbvd0MAAAAwN3MuwwAAAAAAAAAAAAAAAAAAMDc3d3d3d3du93dvdsMAAAAwLvMzAAAAAAAAAAAAAAAAAAAAMDd3d3d3d3d293d3bsMAAAAwLwMAAAAAAAAAAAAAAAAAAAAAMzd3d3du9u929273b0MAAAAAMwMAAAAAAAAAAAAAAAAAAAAANzdu93du7u73d3d280AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwNu9u9u9293d3d3dvQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzLu73bu73d3d3d273QwAAAAAAAAAAAAAAAAAAAAAAAAAAADA3N3d3d3d3d3dvd292wwAAAAAAAAAAAAAAAAAAAAAAAAAAMDM3d3d3d3d3d3d3dvdywwAAAAAAAAAAAAAAAAAAAAAAAAAwMzd3dvd3d3d3d293b3dywAAAAAAAAAAAAAAAAAAAAAAAADAzN3dvdvd3d3d3d293b3bzAAAAAAAAAAAAAAAAAAAAAAAAADM3d3du93d3d3d3dvd273MDAAAAAAAAAAAAAAAAAAAAAAAAADMzLy73d3bvd3b3bvd28wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzc3b3dvd3b3bvdywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDMvNvd293b3bvNDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwN293c3czczMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMzMzQzczAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMzADMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"pigeonIcon\": \"hwQgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAALwPAAAAAAAAAAAAAAAAAAC8DwDAzMwAAAAAAAAAAADAvQ/wz93dzAAAAAAAAAAAwN3//2bT3c0MAAAAAAAAALzbvbtr1t3dzMwAAAAAAAC8u7u7uzbd3c0zAAAAAAAAvLu7u7s23d3NMwAAAAAAALz7v7u7Nt3dvcMAAAAAAAC8+7+7uzbd3d3LAAAAAAAAwLu7u2vW3d3dOwAAAAAAAAD/v7tms7vdzTMAAAAAAAAAAP+/Zt29283DAAAAAAAAAAAA/9Pd3bu9wwAAAAAAAAAAAPDd3d293TwAAAAAAAAAAADw3d3du937AAAAAAAAAAAAANzdvbvd+wAAAAAAAAAAAADc3bvN3f8AAAAAAAAAAAAAwL3bzb0PAAAAAAAAAAAAAADM3c29DwAAAAAAAAAAAAAAwN3N+wAAAAAAAAAAAAAAAAC8y/wAAAAAAAAAAAAAAAAAwLv8AAAAAAAAAAAAAAAAAAC8DwAAAAAAAAAAAAAAAAAAvA8AAAAAAAAAAAAAAAAAAMwPAAAAAAAAAAAAAAAAAADADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"potion0\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwuwsAAAAAAADADAC7u8sAAAAAAADL/Lu7u8sAAAAAAADL/L+7u8sAAAAAAADADAC7u8sAAAAAAAAAAACwuwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion1\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABARAAAAAAAAAAAAABERAQAAAAAAADgAEBEROQAAAAAAADkAEREROQAAAAAAADuTEREROQAAAAAAADuzEREROQAAAAAAADuAEREROQAAAAAAADgAEBEROQAAAAAAAAAAABERAQAAAAAAAAAAABARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion2\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDd3Q0AAAAAAABd0N3d3d0EAAAAAABd1N3d3d0EAAAAAABV1N3d3d0EAAAAAABV0N3d3d0EAAAAAAAAANDd3Q0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion3\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3AJmZmQkAAAAAAAB5lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3AJmZmQkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion4\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAPgAAAAAAAAACJmZmfgAAAAAAAAA+JmZmfgAAAAAAACI+JmZmfgAAAAAAACI+JmZmfgAAAAAAACI+JmZmfgAAAAAAAAA+JmZmfgAAAAAAAAACJmZmfgAAAAAAAAACAAAAPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion5\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwzAwAAAAAAADADAC7zMwAAAAAAADL/Lu7zPwAAAAAAADL/L+7zPwAAAAAAADADAC7zPwAAAAAAAAAAACwzA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion6\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA7gAAAAAAAAAAAABE7g4AAAAAAADgAEBE7u4AAAAAAADkAERE7s4AAAAAAADuTERE7s4AAAAAAADuzERE7s4AAAAAAADuAERE7s4AAAAAAADgAEBE7swAAAAAAAAAAABEzgwAAAAAAAAAAABAzgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion7\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDdVQUAAAAAAABd0N3dVVUEAAAAAABd1N3dVVUEAAAAAABV1N3dVVUEAAAAAABV0N3dVVUEAAAAAAAAANDdVQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion8\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3AJl5dwcAAAAAAAB5lpl5d3cAAAAAAAB3lpl5d2cAAAAAAAB3lpl5d2cAAAAAAAB3lpl5d2cAAAAAAAB3lpl5d2cAAAAAAAB3lpl5d2cAAAAAAAB3lpl5d2cAAAAAAAB3lpl5d2cAAAAAAAB3AJl5ZwYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion9\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAPgAAAAAAAAACJmZiPgAAAAAAAAA+JmZiPgAAAAAAACI+JmZiPgAAAAAAACI+JmZiPgAAAAAAACI+JmZiPgAAAAAAAAA+JmZiPgAAAAAAAAACJmZiPgAAAAAAAAACAAAAPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion10\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAzAwAAAAAAADADAC8y8wAAAAAAADL/My8zPwAAAAAAADL/M/MzPwAAAAAAADADADMzPwAAAAAAAAAAADAzA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion11\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADg7gAAAAAAAAAAAADu7g4AAAAAAADgAOBO7u4AAAAAAADkAO7k7s4AAAAAAADu7E7u7s4AAAAAAADuzO7u7s4AAAAAAADuAO7u7s4AAAAAAADgAODu7swAAAAAAAAAAADuzgwAAAAAAAAAAADgzgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion12\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBdVQUAAAAAAABdUNVVVVUEAAAAAABdVF1VVVUEAAAAAABVVFVVVVUEAAAAAABVUFVVVVUEAAAAAAAAAFBVVQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion13\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3AHd3dwcAAAAAAAB5dpd5d3cAAAAAAAB3dnl3d2cAAAAAAAB3dnd3d2cAAAAAAAB3dnd3d2cAAAAAAAB3dnd3d2cAAAAAAAB3dnd3d2cAAAAAAAB3dnd3d2cAAAAAAAB3dnd3d2cAAAAAAAB3AHd3ZwYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"potion14\": \"hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAPgAAAAAAAAACIiIiPgAAAAAAAAA+JiJiPgAAAAAAACI+JiIiPgAAAAAAACI+IiIiPgAAAAAAACI+IiIiPgAAAAAAAAA+IiIiPgAAAAAAAAACIiIiPgAAAAAAAAACAAAAPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n    \"seasonalTree0\": \"hwQgACAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAPAADwDwAAAAAAAAAAAAAACAAACAAAAAAAAAAA8AAAiP8AAAgAAAAAAAAAAIAA8PD4AAAIAAAAAAAAAAD4AAAAj/8ACAAAAAAAAAAADwAAAPD4APgAAAAAAAAAAA8AAAAA+A+PAAAAAAAAAPAIAAAAAPAP8AgAAAAAAACADwAAAADw+PAPAAAAAAAAgPDwCP8PAP+PDwAAAAAAAPAPAI+I+A/wjw8AAAAAAACPDwAAAP/////4AAAAAACAiA8AAAAA////iPgAAADwiP8AAPj/AAD//4+IiIiIiIgPAAAAAIgP8P//j4iIiPj//w8AAP+A+A/////////////4AP8AAP//j///////////DwAAAAAAiP///////////wAAAADwiPj/+P8PAAAA8P8PAADwiP8P8PgPAAAAAADw/wAA/wgAAP//AAAAAAAA8PAA8A8AAPD4AAAAAAAAAAD/APAAAAD/DwAAAAAAAAAADwDw8ACA+AAAAAAAAAAAAPAAD/CPj/8AAAAAAAAAAADwAA8A8P8PAAAAAAAAAAAA8AAAAADwAAAAAAAAAAAAAPAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"seasonalTree1\": \"hwQgACAAAAAAAHUAAAAAUAUAAAAAAAAAAADlUAdQVQUAAAAAAAAAAFAFUAd3V3UFVQAAAAAAAAAAAEd3d1d3d1UHAAAAAAAAUHVVZwdVB3dXAAAAAAAA4Fd3R1UGd3d3AHB1AAAAAOBVV3B3d3V3d3BwBwAAAADgUAB3V3RVfndwBwAAAAAADlB1dXd1V35wdwcAAAAAAA4AdnZ3dwd3B3cHAAAAAOAOUFV3d3Z3dncHBwAAAADgDnd3dndXV3d1d3cHAAAA4OB1dHdXdmV3d3cABwAAAEQEd2dndXd1d3cHVwAAAABEDnBgV3Z3d2Z3d1cAAABA5A5Qd1d2d3d3d1d3BgDgTu4AAGZndnd3d3dndkZERO4OAAB2d3Z2d2Z2d+fm5u7u7g51d3d3d3d3d2Z25+7u7s7sV2d3ZnZ353d3ZubuzszsDlB3Z2dWZWZmxmXnxuzOzAAAZ3d2d3d3d8dXAAAA4MwMd3ZmZXd3d2dnB2AAAADA7AB2Z3Z2d3Z2ZnYHAAAA4OwAZ2x2V3dndncHAAAAAMDucHd3d3d3dmdmBwYAAAAADHBld2d3V2Z2dgcAAAAAAMBQfmZnZ2d3d3dmAAAAAADAd3d2dnZmBmdgZwAAAAAA4Ad3d2fHBwdndmcAAAAAAOAAdwBnZmcHAGYGAAAAAAAAAABwAHdnAAYAAAAAAAAAAA==\",\n    \"seasonalTree2\": \"hwQgACAAAAAAAHkAAHAAkAkAAAAAAAAAAADpkAeQmQkAAAAAAAAAAJAJkAd3kzkDmQAAAAAAAAAAE0czN5cXc5kHAAAAAAAAkDOZEzeZN3eXAAAAAAAA4Jd3R5kGd3dzAHB5AAAAAOCZl3B3d3l3d3BwBwAAAADgkAB3l3SZfndwBwAAAAAADpB5c3dzl35wNwEAAAAAAA4ANnFzdwd3B3cDAAAAAOAOkDk3d3Z3dncHBwAAAADgDnd3NneXlzN5c3cHAAAA4OB5dHeXdmkTd3cABwAAAEQEdzdnmXd5c3cHlwkAAABEDnAQlxZzd2Z3d5cJAABA5A6Qd5d2d3d3d5d3BgDgTu4AAGZndnd3d3djdkZERO4OAAB2d3Z2d2Y2Mefm5u7u7g55d3d3F3N3d2Z25+7u7s7sl2dzZjZ353d3ZubuzszsDpA3YWeWaWZmw2nnxuzOzAAAZ3d2d3d3N8GXAAAA4MwMd3ZmaTdzd2dnA2AAAADA7AB2Z3Y2d3Z2ZnEHAAAA4OwAZ2x2F3dndncHAAAAAMDucHd3dzN3dmdmBwYAAAAADHBpd2d3l2Z2NgcAAAAAAMCQPmFnZ5N3dxdjAAAAAADAdzdzdnZhBmdgZwAAAAAA4Ad3d2fHBwdndmcAAAAAAOAAdwBnZmcHAGYGAAAAAAAAAABwAHdnAAYAAAAAAAAAAA==\",\n    \"seasonalTree3\": \"hwQgACAAAAAAAOAAAHAAAAAAAAAAAAAAAABFBABARFAFAAAAAAAAAABE1VAFRFVFRAAAAAAAAABABVAFRFRFBUUAAAAAAAAAQAAHVVRFRERVBAAAAAAA4EREVWUFRQREVAQAAAAAAOBER+VVBkTeQAB0dQAAAADgVUREVEQFRARCRAcAAAAADlBEVUVcRE4kQgQAAAAAAA5QRAVVVEXeQEQCAAAAAOAOQERWVUAFIAREIgIAAADgDlRAVQRA5SYiIiQiAAAA4ODkRVZUREQkQiJEIgIAAN0EBU5UVERlJCREAiQCAADdDkVlREUiRSTUDVQiAgDQ7Q5AQCdCJEQm3t1UAgLg3u0AUCUiIkIkIi7SRCLS3e4OAAAiAEIiQiQiZEbu7u7u7g4AIkRGJiJmTkTuLubu7s7sRSJERCIkRM5iRu7uzszsDlRiAmYmRORCRG7uzuzOzABQQgQkUmVmJuLu7g4A4MwMAO7uIiIiIiLiAg4AAADA7AAuIiIiIiLi4uDgAAAA4OzucCcmJiIm5u7u4AAAAMDuDmIsJtIiYibi7g4AAAAADC4iIiItIiZu5g4GAAAAAMDuZeJiwlJm4u7iDgAAAADAUA7mYGJiLuIuIg4AAAAA4CIiJu5y4gIiIu4OAAAAAOAC4u7uIuIO7uLuAAAAAAAAAOIA4uZuB+4uBgAAAAAAAA==\",\n    \"stageIcon\": \"hwQgACAAAAAAAAAAAAAAAAAAAADuzswAAAAA////AADuDgDuLr7LDAAA8O8i8v//4vL/LiK+y8wAAP/u7iLvLuLyIi7ivsvMAPDv7uIu7y4u4i4uIr7LzAD/7u4uLu7uIvIuLuK+y8zw7+7uLv7uLiLy/y8ivsvM/+7u7i7+LiIu/v//Lr7LzO/u7u7i/y7iIv///++7y8zv7u7u/u/uLvL//7+7u8vM7+7u7iL+L+L//++7vbvLzO/u7u4i4v///+/u2927y8zv7u7u7iL+/+/u7tvdu8vM7+7u7uIu8u/u7u7d3b3LzO/u7u4uLuLu7u7u3d29y8zv7u7uLi7i7u7u7t3dvcvM7+7u7i4u4u7u7u7d3b3LzO/u7u4uLuLu7u7u3d29y8zv7u7u4i7y7+7u7t3dvcvM7+7u7u4i/v/v7u7b3bvLzO/u7u4i4v///+/u2927y8zv7u7uIv4v4v//77u9u8vM7+7u7v7v7i7y//+/u7vLzO/u7u7i/y7iIv///++7y8z/7u7uLv4uIi7+//8uvsvM8O/u7i7+7i4i8v8vIr7LzAD/7u4uLu7uIvIuLuK+y8wA8O/u4i7vLi7iLi4ivsvMAAD/7u4i7y7i8iIu4r7LzAAA8O8i8v/v4vL/LiK+y8wAAAD///8AAO4OAO4uvssMAAAAAAAAAAAAAAAA7s7MAA==\",\n    \"writer\": \"hwQ/ADcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA293d3d3d3d0NAAAAAAAAAAAAAAAAAAAAAAAAANvd3d3d3d3dDQAAAAAAAAAAAAAAAAAAAAAAAADb3d3d3d3d3Q0AAAAAAAAAAAAAAAAAAAAAAAAA293d3d3d3d0NAAAAAAAAAAAAAAAAAAAAAAAAANvd3d3d3d3dDQAAAAAAAAAAAAAAAAAAAAAAAADb3d3d3d3d3Q0AAAAAAAAAAAAAAAAAAAAAAMzM3N3d3d3d3d0NAAAAAAAAAAAAAAAAAAAAAMzMzMzd3d3d3d3dDQAAAAAAAAAAAAAAAAAAAMAcERHB3N3d3d3d3Q0AAAAAAAAAAAAAAAAAAADMEREREdzd3d3d3d0NAAAAAAAAAAAAAAAAAADAHBGxuxHB3b273d3dDQAAAAAAAAAAAAAAAAAAzB0RsRsRwd29sd3d3Q0AAAAAAAAAAAAAAAAAwBwdEbsREcHcGxHb3d0NAAAAAAAAAAAAAAAAAMwR0REbEbG7zBsR293dDQAAAAAAAAAAAAAAAMwcERHdG7EbEcwREbHd3Q0AAAAAAAAAAAAAAMAcERER0Ru7ERHBERGx3d0NAAAAAAAAAAAAAADMERERERG7GxERERwREdvdDQAAAAAAAAAAAAAAHBERERHRvRsRERHMERHb3Q0AAAAAAAAAAAAAwBwRERER3b0bERERwRERsd0NAAAAAAAAAAAAAMAdEUFERNTdvBEREcEREbHdDQAAAADAzMzMAADM3R1BVVVFRMS7ERHBERER2w0AAADMzMzMzMzMHBHdTUREVVVVvBsRwREREdsNAADMzBERERGxuxsRERERQURERBS7EcwRERGxDQDAHBERERERERG7EREREREREREcscscERERsQ0AzBERERERERsRsRsRERERERERzMHMEREREbENwBwREREREREcERG7EREREREREcHMERERERHbDcARERERERERzBwRsRERERERERGxvRERERGx3Q3MEREREREREcwcEbEbERERERERsb0RERER290NHBERERERERHMERERGxEREREREbHdGxERsd3dDRwRERERERERERERERsRERERERGx3RsREdvd3Q0cERERERERERERsRHbHRERERERsd0bEbHd3d0NHBEREREREREREREbGx0REREREbHdvRHb3d3dDRwRERERERERERERGxvRERERERGx3b2x3d3d3Q0cERERERERERERERsb0RERERERsdu9293d3d0NHBERERERERsREREbG9ERERERERHb3d3d3d3dDRwREREREREcERGxERvRERERERER293d3d3d3Q3MERERERERzByxG7G7u7sREREREdvd3d3d3d0NwBEREREREcwcERGxuxuxGxERERHb3d3d3d3dDcAcERERERHMERERG7ERERsRERER293d3d3d3Q0AzBERERERERERzBERuxGxGxEREdvd3d3d3d0NAMAcERERERERwRwREbEREbsRERHb3d3d3d3dDQAAzBwREREREcERERGxERGxGxER293d3d3d3Q0AAADMzBwREcHMEbG7sREREbsdEdvd3d3d3d0NAAAAAMDMzMzMzBGxuxsRERGx293b3d3d3d3dDQAAAAAAAAAAAMAcEREREREREczd293d3d3d3Q0AAAAAAAAAAAAAzBEREbsRERHB3Nvd3d3d3d0NAAAAAAAAAAAAAMAcsbu7GxEREczc3d3d3d3dDQAAAAAAAAAAAAAAzLsREbsRERHB3N3d3d3d3Q0AAAAAAAAAAAAAAMwRERGxGxEREczd3d3d3d0NAAAAAAAAAAAAAAAcEREREbsRERHB3N3d3d3dDQAAAAAAAAAAAAAAzBERERGxERERwdzd3d3d3Q0AAAAAAAAAAAAAAMAcERER0RsRERHc3d3d3d0NAAAAAAAAAAAAAAAAzBEREdEdERER3N3d3d3dDQAAAAAAAAAAAAAAAMDMHBHRHREREdzd3d3d3Q0AAAAAAAAAAAAAAAAAAMwcER0REcHc3d3d3d0NAAAAAAAAAAAAAAAAAAAAzMzRERHM3d3d3d3dDQAAAAAAAAAAAAAAAAAAAADAzBzBvN3d3d3d3Q0AAAAAAAAAAAAAAAAAAAAAAMDMzLDd3d3d3d0NAAAAAAAAAAAAAAAAAAAAAAAAAACw3d3d3d3dDQAAAAAAAAAAAAAAAAAAAAAAAAAAsN3d3d3d3Q0AAAAAAAAAAAAAAAAAAAAAAAAAALDd3d3d3d0NAAAAAAAAAAAAAAAAAAAAAAAAAACw3d3d3d3dDQAAAAAAAAAAAAAAAAAAAAAAAAAAsN3d3d3d3Q0=\"\n}","sprites.skillmap.ts":"namespace sprites.skillmap {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const akita = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    export const bridge = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    export const button = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    export const cloud = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration8 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration9 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration10 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration11 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration12 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration13 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const decoration14 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    export const fans = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"tile misc\"\n    export const islandTile0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"tile misc\"\n    export const islandTile1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"tile misc\"\n    export const islandTile2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"tile misc\"\n    export const islandTile3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"tile misc\"\n    export const islandTile4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"tile misc\"\n    export const islandTile5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"tile misc\"\n    export const islandTile6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"tile misc\"\n    export const islandTile7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"tile misc\"\n    export const islandTile8 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    export const kaijuIcon = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    export const mailboxIcon = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const pigeon = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"animals\"\n    export const pigeonIcon = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion8 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion9 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion10 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion11 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion12 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion13 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const potion14 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const seasonalTree0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const seasonalTree1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const seasonalTree2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest\"\n    export const seasonalTree3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    export const stageIcon = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    export const writer = image.ofBuffer(hex``);\n}\n","sprites.space.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.space\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"spaceSmallAsteroid0\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8DAAAAAAAwLvLAAAAAAC6+68MAAAAwKurr8wAAADA+r/LDAAAAMDKv7oMAAAAAKCqvwAAAAAAwKysAAAAAAAAzAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"spaceSmallAsteroid1\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAzAAAAAAAwKq7CwAAAACguqurAAAAAKD/y68AAAAArP+qvwAAAACsy7+6AAAAAAC6vMoAAAAAAAC7DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"spaceSmallAsteroid2\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMwAAAAAAMCquwsAAAAAoLqrqwAAAACg/8uvAAAAAKz/qr8AAAAArMu/ugAAAAAAurzKAAAAAAAAuwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"spaceSmallAsteroid3\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvMsAAAAAAMD8uwsAAAAAoP/6ugAAAACguru/AAAAAKz7v8wAAAAAwKuvDAAAAAAArMoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"spaceAsteroid0\": \"hwQQABAAAAAAAMisygAAAAAAzPqoCgAAAMDMyo/MAAAAzLyrrMrMAADM/6uqussMAPj/uMqsu8yA+P+6zP+6ysD/j6vM/7/LwMyszMr6b8vMqszMrKpmzPyvysyqu6bMiP+qzPy4ygzA/6zM/8/LAMDMqPz/z8YAAMzM/I9szAAAwMzMrMoAAA==\",\n    \"spaceAsteroid1\": \"hwQQABAAAAAAwMzMAAAAAADMqrsMAAAAAKyPvAsAAAAAzPqvCwAAAADMqqqqvMsAAMysyqu7uwwAwMz6vMy6CgDMqoq/yrvGAIzPqrqqasYA/M/Mqrxmy8D8zMyqvMoMwMyqzIirAADA/6qMqAAAAMD8r8zMAAAAAMyvzAwAAAAAwMzMAAAAAA==\",\n    \"spaceSmallAsteroid4\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwKoMAAAAAADA/7sAAAAAALz7uwwAAAAAy7uqCwAAAAD6q/8LAAAAAKz6rwAAAAAAwMwMAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"spaceSmallAsteroid5\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADKAAAAAAAAvKqrAAAAAAD6z/8KAAAAwP+7/wsAAADAu7q7CwAAAADM+78MAAAAAMD6ugwAAAAAALyrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n    \"spaceRedShip\": \"hwQQABAAAAAAAAAAAAAAzAAAAAAAAMDMAAAAAAAAzMwAAAAAAADPzAAAAAAA4M/MAAAAAADs78wAAAAA7izs7szMz+8uLCzu3b0vL0QuLiIAAAAA7k4uIgAAAAAA7i8iAAAAAADgTyQAAAAAAAAuQgAAAAAAAO4iAAAAAAAA4O4AAAAAAAAA7g==\",\n    \"spaceAsteroid2\": \"hwQQABAAAAAAAADAzAwAAAAAAKyqzAAAAMDM/K/LDAAAzMz8z7oMAMD/qsz/uswMwPyvyv+6uwvA/K/MzLqsu8D6rKysu8xqzKq6u2y2zGrMqsq6Zru7xsyq/2+7q7rLzMz/vLvKugzAqv+6u8vLAACsqrqquwwAAMCqzKqqAAAAAMzMzAAAAA==\",\n    \"spaceAsteroid3\": \"hwQQABAAAAAAAADMzMwAAADMzMysqgwAwKyqrLqMqwDAuoyqy/+8DLDL/6yGz7wMsPr/zGrKvAyw/I/MzLy8DKz7yMzMrLsLzLqqqqr6v8usqrvLr/+8u6q6u/yvyrq7rLu7/7y8u8vAvLvKvMy7DACsu7vLzLoMAACqvLvLzAAAAACsygAAAA==\",\n    \"spaceAsteroid4\": \"hwQQABAAAAAAAAAAzLq7CgAArArArLqrAMC8q6rKrKYArKq7qrvMuwDKrLuqu6rLoPzMpsy6uwqs/2/6zGqrDKz6qvuvtqoAzKqqu6zKDADA+sy6qwsAAMD6z6q6ywAAAKz/rLrGAAAAwKrKrKsAAAAAzP/PywAAAADA/6oMAAAAAMDMzAAAAA==\",\n    \"spaceOrangeShip\": \"hwQQABAAAAAAAAAAAAAA7gAAAAAAAODuAAAAAAAA7u4AAAAAAADv7gAAAAAA4O/uAAAAAADsL+4AAAAA7kwsIszMz+9OTEwi3b1PT1VCQkQAAAAAIlJCRAAAAAAAIk9EAAAAAAAgX0UAAAAAAABCVAAAAAAAACJEAAAAAAAAICIAAAAAAAAAIg==\",\n    \"spacePinkShip\": \"hwQQABAAAAAAAAAAAAAAiAAAAAAAAICIAAAAAAAAiIgAAAAAAACPiAAAAAAAgI+IAAAAAACMr4gAAAAAiDysqszMz484PDyq3b0/PxE6OjMAAAAAqho6MwAAAAAAqj8zAAAAAACgHzEAAAAAAAA6EwAAAAAAAKozAAAAAAAAoKoAAAAAAAAAqg==\",\n    \"spaceBlueShip\": \"hwQQABAAAAAAAAAAAAAAiAAAAAAAAICIAAAAAAAAiIgAAAAAAACPiAAAAAAAgI+IAAAAAACMj4gAAAAAiGyMiMzMz49obGyI3b1vb5lobmYAAAAAiJhuZgAAAAAAiG9mAAAAAACAn2kAAAAAAABolgAAAAAAAIhmAAAAAAAAgIgAAAAAAAAAiA==\",\n    \"spaceGreenShip\": \"hwQQABAAAAAAAAAAAAAAiAAAAAAAAICIAAAAAAAAiIgAAAAAAACPiAAAAAAAgI+IAAAAAACMb4gAAAAAiHxsZszMz494fHxm3b1/f1V2dncAAAAAZlZ2dwAAAAAAZn93AAAAAABgX3UAAAAAAAB2VwAAAAAAAGZ3AAAAAAAAYGYAAAAAAAAAZg==\"\n}","sprites.space.ts":"namespace sprites.space {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceSmallAsteroid0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceSmallAsteroid1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceSmallAsteroid2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceSmallAsteroid3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceAsteroid0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceAsteroid1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceSmallAsteroid4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceSmallAsteroid5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceRedShip = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceAsteroid2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceAsteroid3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceAsteroid4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceOrangeShip = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spacePinkShip = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceBlueShip = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"space\"\n    export const spaceGreenShip = image.ofBuffer(hex``);\n}\n","sprites.swamp.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.swamp\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"mushroomBackLeft0\": \"hwQQABAAAAAAwPz/AAAAAADMu7vM/wAAALy7u8vdDAAAu7u7u9zN/7Abu7u7y93csBG7u7vL3dywMTO7u7vc3LAzM7O7u9z/OzMzs7u7y/s7MzMzG7HLCzszMzMbscsLOxMxM7u7ywuwGzGzu7v7AAC7y7u7u/sAAAAAvLu7/wAAAADA/P8PAA==\",\n    \"mushroomBackLeft1\": \"hwQQABAAAAAAAMz/DwAAAADAu7vL/A8AAMC7u7vczQAAsLu7u8vdDAAbsbu7y93NABuxu7u73M0AGzO7u7vczQA7MzO7u8v9sDMzM7u7y7ywMzMzEzG7vLAzMzMTMbsMsBMRM7O7uwwAuxGzu7u7DwCwu7y7u8sPAAAAwLu7/A8AAAAAzP//AA==\",\n    \"mushroomBackLeft2\": \"hwQQABAAAAAAAMz/DwAAAADAvLvL/A8AAMC7u7vczf8AsLu7u8vd/AC7sbu7u9zNABuxu7u73M0AGzOzu7vLzQA7MzO7u8v9sDMzM7u7u7ywMzMzsxG7vLAzMzOzEbu8sDMRM7O7u/wAuxEzu7u7DwCwu7y7u7sPAAAAwLu7+w8AAAAAzP//AA==\",\n    \"mushroomBackLeft3\": \"hwQQABAAAAAAwPz/AAAAAADMvLvM/wD/AMy7u7vc/N8AvLu7u8vN27Abu7u7y93csBG7u7u73LywETOzu7vc/LAzM7O7u8sPOzMzM7u7yww7MzMzOxHL/zszMzM7Ecu7OzMRM7u7y7uwGxEzu7v7vwC7y7y7u/v/AAAAzLu7/wAAAADA/P8PAA==\",\n    \"mushroomBackLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.swamp.mushroomBackLeft0\\\",\\\"sprites.swamp.mushroomBackLeft1\\\",\\\"sprites.swamp.mushroomBackLeft2\\\",\\\"sprites.swamp.mushroomBackLeft3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"mushroomBackRight0\": \"hwQQABAAAAAAAADA/P8PAAAAALy7u/8AALvLu7u7+wCwGzGzu7v7ADsTMTO7u8sLOzMzMxuxyws7MzMzG7HLCzszM7O7u8v7sDMzs7u73P+wMTO7u7vc3LARu7u7y93csBu7u7vL3dwAu7u7u9zN/wC8u7vL3QwAAMy7u8z/AAAAwPz/AAAAAA==\",\n    \"mushroomBackRight1\": \"hwQQABAAAAAAAAAAzP//AAAAAMC7u/wPALC7vLu7yw8AuxGzu7u7D7ATETOzu7sMsDMzMxMxuwywMzMzEzG7vLAzMzO7u8u8ADszM7u7y/0AGzO7u7vczQAbsbu7u9zNABuxu7vL3c0AsLu7u8vdDADAu7u73M0AAMC7u8v8DwAAAMz/DwAAAA==\",\n    \"mushroomBackRight2\": \"hwQQABAAAAAAAAAAzP//AAAAAMC7u/sPALC7vLu7uw8AuxEzu7u7D7AzETOzu7v8sDMzM7MRu7ywMzMzsxG7vLAzMzO7u7u8ADszM7u7y/0AGzOzu7vLzQAbsbu7u9zNALuxu7u73M0AsLu7u8vd/ADAu7u73M3/AMC8u8v8DwAAAMz/DwAAAA==\",\n    \"mushroomBackRight3\": \"hwQQABAAAAAAAADA/P8PAAAAAMy7u/8AALvLvLu7+/+wGxEzu7v7vzszETO7u8u7OzMzMzsRy7s7MzMzOxHL/zszMzO7u8sMsDMzs7u7yw+wETOzu7vc/LARu7u7u9y8sBu7u7vL3dwAvLu7u8vN2wDMu7u73PzfAMy8u8z/AP8AwPz/AAAAAA==\",\n    \"mushroomBackRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.swamp.mushroomBackRight0\\\",\\\"sprites.swamp.mushroomBackRight1\\\",\\\"sprites.swamp.mushroomBackRight2\\\",\\\"sprites.swamp.mushroomBackRight3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"mushroomFrontLeft0\": \"hwQQABAAAAAAwPz/AAAAAADMu7vM/wAAALyzzNvdDAAAO8O83b3N/7Abw9zMvd2/sBHD3d293buwMcPd3d3du7Azs93d3Lv/OzMz2829vfs7MzPb3f3dCzszM7Pd/dsLOxMxs8vM/wuwGzEzzMz7AAC7yzPDzPsAAAAAvDO7/wAAAADA/P8PAA==\",\n    \"mushroomFrontLeft1\": \"hwQQABAAAAAAAMz/DwAAAADAvLvL/A8AAMA8y9zdzQAAsDPM3d3bDAC7MbzN3NvNABsx3N3du/sAGzHc3d3buwA7M9vdzd+9sDMz293cv72wMzOz3d39v7AzM7Pb3c0MsDMRMbvLzAwAuxExs8y8DwCwu8wzw7wPAAAAwDuz+w8AAAAAzP//AA==\",\n    \"mushroomFrontLeft2\": \"hwQQABAAAAAAAMz/DwAAAADAvLvL/A8AAMA8y7zdzf8AsDPM29zb+wAbMczd3Nv9ABsx3N3d280AOzHc3d3dzQA7M9vdzd27sDMzs93NvduwMzOz3d393bAzMzPb3f3dsDMTMbvMzP8AuxMxw8y8DwCwu8wzzLwPAAAAwDuz+w8AAAAAzP//AA==\",\n    \"mushroomFrontLeft3\": \"hwQQABAAAAAAwPz/AAAAAADMu7vM/wD/ADyzzLzd/L8AO8PM3b39u7Abw9zMvd27sBHD29293f+wMTPb3d3d/7AzM9vd3N0MOzMz283dzQw7MzOz3d3NuzszM7Pd3bvdOxMxM8vM/N2wGzEzzMz72wC7yzPDzPv/AAAAPDO7/wAAAADA/P8PAA==\",\n    \"mushroomFrontLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.swamp.mushroomFrontLeft0\\\",\\\"sprites.swamp.mushroomFrontLeft1\\\",\\\"sprites.swamp.mushroomFrontLeft2\\\",\\\"sprites.swamp.mushroomFrontLeft3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"mushroomFrontRight0\": \"hwQQABAAAAAAAADA/P8PAAAAALwzu/8AALvLM8PM+wCwGzEzzMz7ADsTMbPLzP8LOzMzs9392ws7MzPb3f3dCzszM9vNvb37sDOz3d3cu/+wMcPd3d3du7ARw93dvd27sBvD3My93b8AO8O83b3N/wC8s8zb3QwAAMy7u8z/AAAAwPz/AAAAAA==\",\n    \"mushroomFrontRight1\": \"hwQQABAAAAAAAAAAzP//AAAAAMA7s/sPALC7zDPDvA8AuxExs8y8D7AzETG7y8wMsDMzs9vdzQywMzOz3d39v7AzM9vd3L+9ADsz293N370AGzHc3d3buwAbMdzd3bv7ALsxvM3c280AsDPM3d3bDADAPMvc3c0AAMC8u8v8DwAAAMz/DwAAAA==\",\n    \"mushroomFrontRight2\": \"hwQQABAAAAAAAAAAzP//AAAAAMA7s/sPALC7zDPMvA8AuxMxw8y8D7AzEzG7zMz/sDMzM9vd/d2wMzOz3d393bAzM7Pdzb3bADsz293N3bsAOzHc3d3dzQAbMdzd3dvNABsxzN3c2/0AsDPM29zb+wDAPMu83c3/AMC8u8v8DwAAAMz/DwAAAA==\",\n    \"mushroomFrontRight3\": \"hwQQABAAAAAAAADA/P8PAAAAADwzu/8AALvLM8PM+/+wGzEzzMz72zsTMTPLzPzdOzMzs93du907MzOz3d3NuzszM9vN3c0MsDMz293c3QywMTPb3d3d/7ARw9vdvd3/sBvD3My93bsAO8PM3b39uwA8s8y83fy/AMy7u8z/AP8AwPz/AAAAAA==\",\n    \"mushroomFrontRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.swamp.mushroomFrontRight0\\\",\\\"sprites.swamp.mushroomFrontRight1\\\",\\\"sprites.swamp.mushroomFrontRight2\\\",\\\"sprites.swamp.mushroomFrontRight3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"swampTile0\": {\n        \"data\": \"hwQQABAAAAAAAACAiAAAAAAAAIBnCAAAAAAAAHiHAACAiIiIaHeIiIB3hoiIdndmAGh3d2dmhogAgIh2d3d3ZgAAgIhohohoAICIdnd3ZmYAiHd3ZmZmZoh3d4Zod4eIiIiIiHdniIgAAABoZ4hmZgAAiHiGeGdmAABoiIh3iIgAAIBmeIdoZg==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile1\": {\n        \"data\": \"hwQQABAAAAAAAABoeIiIiAAAAIhoaGaIAAAAiIiIZoiAiIiIiHeIiIB3hoiIdndmAGh3d2dmhogAgIh2d3d3ZgAAgIhohohoAICIdnd3ZmYAiHd3ZmZmZoh3d4Zod4eIiIiIiHdniIgAAABoZ4hmZgAAiHiGeGdmAABoiIh3iIgAAIBmeIdoZg==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile2\": {\n        \"data\": \"hwQQABAAAAAAAABoeIiIiAAAAIhoaGaIAAAAiIiIZoiAiIiIiHeIiIB3hoiIdmdmAGh3d2dmhogAgIh2d3d3ZgAAgIhohohoAICIdnd3ZmYAiHd3ZmZmZoh3d4Zod4eIiIiIiHdniIgAAABoZ4hmZgAAAHiGeGdmAAAAiIh3iIgAAAAAgIgAAA==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile3\": {\n        \"data\": \"hwQQABAAAAAAAACAiAAAAAAAAIBnCAAAAAAAAHiHAACAiIiIaHeIiIB3hoiIdndmAGh3d2dmhogAgIh2d3d3ZgAAgIhohohoAICIdnd3ZmYAiHd3ZmZmZoh3d4Zod4eIiIiIiHdniIgAAABoZ4hmZgAAAHiGeIeIAAAAiIh3CAAAAAAAiIgAAA==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile4\": {\n        \"data\": \"hwQQABAAAAAAAACIqAAAAAAAiKiqqgAAAICIqqqqCgAAiKiqqqqqAACIqqqqqqoAgKiqqqqqqgqAqKqqqqqqCoioqqqqqqoKiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqg==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile5\": {\n        \"data\": \"hwQQABAAAACIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKiqqqqqqgqAqKqqqqqqCoCoqqqqqqoKAIiqqqqqqgAAiKiqqqqqAACAiKqqqgoAAACIqKqqAAAAAACIqAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile6\": {\n        \"data\": \"hwQQABAAAAAAAAAAAACqqgAAAAAAqqqqAAAAAKqqqqoAAACgqqqqqgAAAKiqqqqqAACAqqqqqqoAAIiqqqqqqgCAqKqqqqqqAICoqqqqqqoAiKqqqqqqqgCIqqqqqqqqgKiqqqqqqqqAqKqqqqqqqoCoqqqqqqqqgKiqqqqqqqqIqKqqqqqqqg==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile7\": {\n        \"data\": \"hwQQABAAAACIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqg==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile8\": {\n        \"data\": \"hwQQABAAAACIqKqqqqqqqoCoqqqqqqqqgKiqqqqqqqqAqKqqqqqqqoCoqqqqqqqqAIiqqqqqqqoAiKqqqqqqqgCAqKqqqqqqAICoqqqqqqoAAIiqqqqqqgAAgKqqqqqqAAAAqKqqqqoAAACgqqqqqgAAAACqqqqqAAAAAACqqqoAAAAAAACqqg==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile9\": {\n        \"data\": \"hwQQABAAAACqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqg==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile10\": {\n        \"data\": \"hwQQABAAAAAAAAAAAAC7uwAAAAAAu7u7AAAAALu7u7sAAACwu7u7uwAAALu7u7u7AACwu7u7u7sAALu7u7u7uwCwu7u7u7u7ALC7u7u7u7sAu7u7u7u7uwC7u7u7u7u7sLu7u7u7u7uwu7u7u7u7u7C7u7u7u7u7sLu7u7u7u7u7u7u7u7u7uw==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile11\": {\n        \"data\": \"hwQQABAAAAC7u7u7u7u7u7C7u7u7u7u7sLu7u7u7u7uwu7u7u7u7u7C7u7u7u7u7ALu7u7u7u7sAu7u7u7u7uwCwu7u7u7u7ALC7u7u7u7sAALu7u7u7uwAAsLu7u7u7AAAAu7u7u7sAAACwu7u7uwAAAAC7u7u7AAAAAAC7u7sAAAAAAAC7uw==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile12\": {\n        \"data\": \"hwQQABAAAACqqgAAAAAAAKqqqgAAAAAAqqqqqgAAAACqqqqqCgAAAKqqqqqqAAAAqqqqqqoKAACqqqqqqqoAAKqqqqqqqgoAqqqqqqqqCgCqqqqqqqqqAKqqqqqqqqoAqqqqqqqqqgqqqqqqqqqqCqqqqqqqqqoKqqqqqqqqqgqqqqqqqqqqqg==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile13\": {\n        \"data\": \"hwQQABAAAACqqqqqqqqqqqqqqqqqqqqqqqqqqqqKqKqqM6OqqoqoqjqjOqo6g4iqM6qqozqDiKoToaqjqoiIqhOhqqOqiIiqOqM6qqqIiKqqM6OqqoiIqqqqqjqjiIiqqqqqozqIiKqqqqqjOoqoqqqqqjqjiqiqqqqqqqqqqqqqqqqqqqqqqg==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile14\": {\n        \"data\": \"hwQQABAAAACqqqqqqqqqqqqqqqqqqqoKqqqqqqqqqgqqqqqqqqqqCqqqqqqqqqoKqqqqqqqqqgCqqqqqqqqqAKqqqqqqqgoAqqqqqqqqCgCqqqqqqqoAAKqqqqqqCgAAqqqqqqoAAACqqqqqCgAAAKqqqqoAAAAAqqqqAAAAAACqqgAAAAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile15\": {\n        \"data\": \"hwQQABAAAAAAAAC7uwAAAAAAu7u7uwAAALC7u7u7CwAAu7u7u7u7AAC7u7u7u7sAsLu7u7u7uwuwu7u7u7u7C7C7u7u7u7sLu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uw==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile16\": {\n        \"data\": \"hwQQABAAAAC7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uw==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile17\": {\n        \"data\": \"hwQQABAAAAC7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7sLu7u7u7uwuwu7u7u7u7C7C7u7u7u7sLALu7u7u7uwAAu7u7u7u7AACwu7u7uwsAAAC7u7u7AAAAAAC7uwAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile18\": {\n        \"data\": \"hwQQABAAAAC7uwAAAAAAALu7uwAAAAAAu7u7uwAAAAC7u7u7CwAAALu7u7u7AAAAu7u7u7sLAAC7u7u7u7sAALu7u7u7uwsAu7u7u7u7CwC7u7u7u7u7ALu7u7u7u7sAu7u7u7u7uwu7u7u7u7u7C7u7u7u7u7sLu7u7u7u7uwu7u7u7u7u7uw==\",\n        \"tilemapTile\": true\n    },\n    \"swampTile19\": {\n        \"data\": \"hwQQABAAAAC7u7u7u7u7u7u7u7u7u7sLu7u7u7u7uwu7u7u7u7u7C7u7u7u7u7sLu7u7u7u7uwC7u7u7u7u7ALu7u7u7uwsAu7u7u7u7CwC7u7u7u7sAALu7u7u7CwAAu7u7u7sAAAC7u7u7CwAAALu7u7sAAAAAu7u7AAAAAAC7uwAAAAAAAA==\",\n        \"tilemapTile\": true\n    },\n    \"swampTree1\": \"hwQQABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAMD/DwDwzwAAAAAAALy8/ADwywAAAAAAAAzAy///+wAAAMD/DwDA293d/QAAALzM/M+73d29+wAAwAzA/Nzbvbvd+w8AAAAA/73dzLvb3Q8AAAAA39vNzP+83M2wzADA3NvL3A+8zM0Au8zMvd0M3A+8y/8AwL27270A2w/A+wAAANzd3Qyw+wAA/wAAAMDMzACwDwAA8AAAAAAAAAAAAAAAAAA=\",\n    \"swampTree2\": \"hwQgACAAAAAAAAAAAADw/w8AAAAAAAAAAAAAAADAbGb2DwAAAAAAAAAAAAAAbGZm9v8AAAAAAAAAAAAAwGZmd3f/DwAAAAAAAAAAAGxmd3d3Zw8AwAwAAAAAAMDMZnd3d2f2ALwMAAAAAADMzMZsd3dm9sDMDMwAAAAAfMfMzHd3ZvbAu8zNAAAAwHdmd8x2d3dmzMy8ywAAAMB3dndndnd3Z7zL3csAAAB8d3d3Z3Z3d3c8s9v9AAAAfGd2d2Z2d3d3PN0z+wAAAHxmdndmdnd3d9zdPfMAAMBndmZ3Z3Z3d2fb3d37AADAZ3dmd3dmd3dm2929ywAAwGd3Z3d3ZndnZtvdu90MAMBnd2d3d2Z3Z2bb3ds9wwDAZ3dmd3dmd3dm293TPc0AwGd2Zndndnd3Z9vdM70MAAB8ZnZ3ZnZ3d3fc3T37AAAAfGd2d2Z2d3d3PN0z8wAAAHx3l3lndnd3dzwz2/0AAADAd5aZZ3Z3d2e8y937AAAAwHxmmcx2d3dmzMy8ywAAAAB8x8zMdndm9sy7zM0AAAAAbMzGbHd3ZvbAzAzMAAAAAMDMdpd5d2f2ALwMAAAAAAAAbHaXmXf3DwDADAAAAAAAAMBmd5l3/w8AAAAAAAAAAAAAbGZmZv8AAAAAAAAAAAAAAMBsZmYPAAAAAAAAAAAAAAAA8P//AAAAAAAAAA==\",\n    \"swampTree3\": \"hwQgACAAAAAAAAAAAADw/w8AAAAAAAAAAAAAAADwj4j4DwAAAAAAAAAAAAAAj4iI+P8AAAAAAAAAAAAA8IiIZmb/DwAAAAAAAAAAAI+IZmZmhg8A8A8AAAAAAPD/iGZmZob4AO8PAAAAAAD///iPZmaI+PD/D/8AAAAAb/b//2ZmiPjw7v/7AAAA8GaIZv9oZmaI///v/gAAAPBmaGaGaGZmhu/+u/4AAABvZmZmhmhmZmbv7r77AAAAb4ZoZohoZmZm77vu/gAAAG+IaGaIaGZmZr+76/4AAPCGaIhmhmhmZoa+u7v+AADwhmaIZmaIZmaIvrvrzgAA8IZmhmZmiGaGiL677rsMAPCGZoZmZohmhoi+u77r/gDwhmaIZmaIZmaIvru+6/sA8IZoiGaGaGZmhr677usPAABviGhmiGhmZma/u+v+AAAAb4ZoZohoZmZm77vu/gAAAG9mdmeGaGZmZu/uvvsAAADwZnh3hmhmZobv/rv+AAAA8G+Id/9oZmaI///v/gAAAABv9v//aGaI+P/u//sAAAAAj//4j2ZmiPjw/w//AAAAAPD/aHZnZob4AO8PAAAAAAAAj2h2d2b2DwDwDwAAAAAAAPCIZndm/w8AAAAAAAAAAAAAj4iIiP8AAAAAAAAAAAAAAPCPiIgPAAAAAAAAAAAAAAAA8P//AAAAAAAAAA==\",\n    \"witchBack0\": \"hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7/P8A7gAAwFv1/+/rAADMVVX/7/8MAMy7Vf//W/vMXLVb//9V9VxVVVv//1v1vFVVW///W/XAXLVb//9V9QDMu1X//1v7ALxVVf///AwAwFv1/+/rAADAu///AO4AAADMAAAAAAAAAAAAAAAAAA==\",\n    \"witchBack1\": \"hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8+/8PAAAAALxV///uAADAW1X1/7sMAMC8W/X/vv4AwFW79f/u/gBcVbX1/7/1wFVVtfX/v/XAzFW79f9f9QDAvFv1/1/1AMBcVfX/+/UAALxV///rDwAAvMv/D+4AAADADAAAAAAAAAAAAAAAAA==\",\n    \"witchBack2\": \"hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7//8A7gAAwFv1/+/rAAC8VVX/7/wMAMy7Vf//W/vAXLVb//9V9bxVVVv//1v1XFVVW///W/XMXLVb//9V9QDMu1X//1v7AMxVVf/v/wwAwFv1/+/rAADAu/z/AO4AAADMAAAAAAAAAAAAAAAAAA==\",\n    \"witchBack3\": \"hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8y/8P7gAAALxV///rDwDAXFX1//v1AMC8W/X/X/XAzFW79f9e9cBVVbX1/771AFxVtfX/vvUAwFW79f/u/gDAvFv1777+AMBbVfXvuwwAALxV///uAAAAvPv/DwAAAADADAAAAAAAAAAAAAAAAA==\",\n    \"witchBack\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.swamp.witchBack0\\\",\\\"sprites.swamp.witchBack1\\\",\\\"sprites.swamp.witchBack2\\\",\\\"sprites.swamp.witchBack3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"witchForward0\": \"hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7//8A7gAAwFv1/+/rAAC8VVX/7/wMAMy7VRv7W/vAXLVb/+tV9bxVVVu+61v1XFVVW77rW/XMXLVb/+tV9QDMu1Ub+1v7AMxVVf/v/wwAwFv1/+/rAADAu/z/AO4AAADMAAAAAAAAAAAAAAAAAA==\",\n    \"witchForward1\": \"hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8y/8P7gAAALxV///rDwDAXFX1//v1AMC8W7WxX/XAzFW79b9e9cBVVbXlu771AFxVteW7vvUAwFW79e/u/gDAvFu14bv+AMBbVfXvuwwAALxV///uAAAAvPv/DwAAAADADAAAAAAAAAAAAAAAAA==\",\n    \"witchForward2\": \"hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7/P8A7gAAwFv1/+/rAADMVVX/7/8MAMy7VRv7W/vMXLVb/+tV9VxVVVu+61v1vFVVW77rW/XAXLVb/+tV9QDMu1Ub+1v7ALxVVf/v/AwAwFv1/+/rAADAu///AO4AAADMAAAAAAAAAAAAAAAAAA==\",\n    \"witchForward3\": \"hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8+/8PAAAAALxV///uAADAW1X177sMAMC8W7Xhu/4AwFW79e/u/gBcVbXlu771wFVVteW7vvXAzFW79b9e9QDAvFu1sV/1AMBcVfX/+/UAALxV///rDwAAvMv/D+4AAADADAAAAAAAAAAAAAAAAA==\",\n    \"witchForward\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.swamp.witchForward0\\\",\\\"sprites.swamp.witchForward1\\\",\\\"sprites.swamp.witchForward2\\\",\\\"sprites.swamp.witchForward3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"witchLeft0\": \"hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7DAAAAAAAwFv1AAAAAADMVVX/D/AMAMy7Ve77X/vAVbVbvutV9VxVVVu+61v1zFVVW//rW/UAXLVbG+vu9QDMu1W++7v+ALxVVf7vuw4AwFv1/+/uAADAu///AAAAAADMAAAAAAAAAAAAAAAAAA==\",\n    \"witchLeft1\": \"hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8ywAAAAAAALxVDwAAAADAXFX1//AMAMC8W+W+X/UAXFW75bu+9cBcVbXlu771wFVVtfW/7vUAzFW7teG7/gDAvFvl67v+AMBbVeX/7g8AALxV//8PAAAAvPv/DwAAAADADAAAAAAAAAAAAAAAAA==\",\n    \"witchLeft2\": \"hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7DAAAAAAAwFv1AAAAAADMVVX/D/AMAMy7Ve77X/vAVbVbvutV9VxVVVu+61v1zFVVW//rW/UAXLVbG+vu9QDMu1W++7v+ALxVVf7vuw4AwFv1/+/uAADAu///AAAAAADMAAAAAAAAAAAAAAAAAA==\",\n    \"witchLeft3\": \"hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8ywAAAAAAALxVDwAAAADAXFX1//AMAMC8W+W+X/UAXFW75bte9cBcVbXlu771wFVVtfW/vvUAzFW7tbG+9QDAvFvlu+7+AMBbVeX/uw4AALxV//+7DgAAvPv/D+4AAADADAAAAAAAAAAAAAAAAA==\",\n    \"witchLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.swamp.witchLeft0\\\",\\\"sprites.swamp.witchLeft1\\\",\\\"sprites.swamp.witchLeft2\\\",\\\"sprites.swamp.witchLeft3\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"witchRight0\": \"hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7//8AAAAAwFv1/+/uAAC8VVX+77sOAMy7Vb77u/4AXLVbG+vu9cxVVVv/61v1XFVVW77rW/XAVbVbvutV9QDMu1Xu+1/7AMxVVf8P8AwAwFv1AAAAAADAuwwAAAAAAADMAAAAAAAAAAAAAAAAAA==\",\n    \"witchRight1\": \"hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8+/8PAAAAALxV//8PAADAW1Xl/+4PAMC8W+Xru/4AzFW7teG7/sBVVbX1v+71wFxVteW7vvUAXFW75bu+9QDAvFvlvl/1AMBcVfX/8AwAALxVDwAAAAAAvMsAAAAAAADADAAAAAAAAAAAAAAAAA==\",\n    \"witchRight2\": \"hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7//8AAAAAwFv1/+/uAAC8VVX+77sOAMy7Vb77u/4AXLVbG+vu9cxVVVv/61v1XFVVW77rW/XAVbVbvutV9QDMu1Xu+1/7AMxVVf8P8AwAwFv1AAAAAADAuwwAAAAAAADMAAAAAAAAAAAAAAAAAA==\",\n    \"witchRight3\": \"hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8+/8P7gAAALxV//+7DgDAW1Xl/7sOAMC8W+W77v4AzFW7tbG+9cBVVbX1v771wFxVteW7vvUAXFW75bte9QDAvFvlvl/1AMBcVfX/8AwAALxVDwAAAAAAvMsAAAAAAADADAAAAAAAAAAAAAAAAA==\",\n    \"witchRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.swamp.witchRight0\\\",\\\"sprites.swamp.witchRight1\\\",\\\"sprites.swamp.witchRight2\\\",\\\"sprites.swamp.witchRight3\\\"],\\\"flippedHorizontal\\\":false}\"\n    }\n}","sprites.swamp.ts":"namespace sprites.swamp {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomBackLeft0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomBackLeft1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomBackLeft2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomBackLeft3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomBackRight0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomBackRight1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomBackRight2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomBackRight3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomFrontLeft0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomFrontLeft1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomFrontLeft2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomFrontLeft3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomFrontRight0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomFrontRight1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomFrontRight2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"forest swamp\"\n    export const mushroomFrontRight3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile6 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile7 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile8 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile9 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile10 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile11 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile12 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile13 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile14 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile15 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile16 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile17 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile18 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile forest swamp\"\n    export const swampTile19 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"swamp\"\n    export const swampTree1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"swamp\"\n    export const swampTree2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"swamp\"\n    export const swampTree3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchBack0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchBack1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchBack2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchBack3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchForward0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchForward1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchForward2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchForward3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchLeft0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchLeft1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchLeft2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchLeft3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchRight0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchRight1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchRight2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"people swamp\"\n    export const witchRight3 = image.ofBuffer(hex``);\n}\n","sprites.vehicle.jres":"{\n    \"*\": {\n        \"namespace\": \"sprites.vehicle\",\n        \"mimeType\": \"image/x-mkcd-f4\",\n        \"dataEncoding\": \"base64\"\n    },\n    \"carRedLeft\": \"hwQQABAAAAAAAAAAAAAAAAAA0CIi7Q4AAAAtItLtDgAAACIi0uLuAAAgRCQi7v4PAMLMK+7u/w8gzLzu8u7/DyAi4r7i7/8PICLku+L+/gAgIuS74v7uACAi5Lvy/+4AICLk7u7u/gAgIuS74u7/DyBE5Lvi7v8PAMIsvuLu/w8AIMzi7u7/AA==\",\n    \"carRedRight\": \"hwQQABAAAAAAAAAAAAAAAAAAIiLu7g4AACDM4u7u/wAAwiy+4u7/DyBE5Lvi7v8PICLku+Lu/w8gIuTu7u7+ACAi5Lvy/+4AICLku+L+7gAgIuS74v7+ACAi4r7i7/8PIMy87vLu/w8Awswr7u7/DwAgRCQi7v4PAAAiItLi7gAAAC0i0u0OAA==\",\n    \"carRedBack\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4P//7u7/DwAiIiIi4u7/4MwiwuzuLf4uQkQkzuveDi4iIkK86+4OLCIiQrzr7g4sIiIivOvuDi4iIiK86+4OLiIiIs7r3g7gzCzC7O4t/gAiIiIi4u7/AOD//+7u/w8AAAAAAAAAAA==\",\n    \"carRedFront\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOD/7/4PAAAAIuIi7i4PAMLMzCxL3eIgQkQkskzSLSAkIiLLTCIiICQiIstMIiIgIiIiy0wiIiAiIiLLTCIiICIiIrJM0i0AwszMLEvd4gAAIuIi7i4PAADg/+/+/wAAAAAAAAAAAA==\",\n    \"carBlueLeft\": \"hwQQABAAAAAAAAAAAAAAAAAA0GZmjQgAAABtZtaNCAAAAGZm1oaIAABgmWlmiPgPAMbMa4iI/w9gzLyI9oj/D2BmhriGj/8PYGaJu4b4+ABgZom7hviIAGBmibv2/4gAYGaJiIiI+ABgZom7hoj/D2CZibuGiP8PAMZsuIaI/w8AYMyGiIj/AA==\",\n    \"carBlueRight\": \"hwQQABAAAAAAAAAAAAAAAAAAZmaIiAgAAGDMhoiI/wAAxmy4hoj/D2CZibuGiP8PYGaJu4aI/w9gZomIiIj4AGBmibv2/4gAYGaJu4b4iABgZom7hvj4AGBmhriGj/8PYMy8iPaI/w8AxsxriIj/DwBgmWlmiPgPAABmZtaGiAAAAG1m1o0IAA==\",\n    \"carBlueBack\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP//iIj/DwBmZmZmhoj/gMxmxoyIbfholplpyIvYCGhmZpa8i4gIbGZmlryLiAhsZmZmvIuICGhmZma8i4gIaGZmZsiL2AiAzGzGjIht+ABmZmZmhoj/AID//4iI/w8AAAAAAAAAAA==\",\n    \"carBlueFront\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAID/j/gPAAAAZoZmiGgPAMbMzGyb3YZglplptpzWbWBpZmbLnGZmYGlmZsucZmZgZmZmy5xmZmBmZmbLnGZmYGZmZrac1m0AxszMbJvdhgAAZoZmiGgPAACA/4/4/wAAAAAAAAAAAA==\",\n    \"carPinkLeft\": \"hwQQABAAAAAAAAAAAAAAAAAA0DMzrQoAAAA9M9OtCgAAADMz06OqAAAw3T0zqvoPAMPMO6qq/w8wzLyq86r/DzAzo7qjr/8PMDOtu6P6+gAwM627o/qqADAzrbvz/6oAMDOtqqqq+gAwM627o6r/DzDdrbujqv8PAMM8uqOq/w8AMMyjqqr/AA==\",\n    \"carPinkRight\": \"hwQQABAAAAAAAAAAAAAAAAAAMzOqqgoAADDMo6qq/wAAwzy6o6r/DzDdrbujqv8PMDOtu6Oq/w8wM62qqqr6ADAzrbvz/6oAMDOtu6P6qgAwM627o/r6ADAzo7qjr/8PMMy8qvOq/w8Aw8w7qqr/DwAw3T0zqvoPAAAzM9OjqgAAAD0z060KAA==\",\n    \"carPinkBack\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//qqr/DwAzMzMzo6r/oMwzw6yqPfo60909yqvaCjozM9O8q6oKPDMz07yrqgo8MzMzvKuqCjozMzO8q6oKOjMzM8qr2gqgzDzDrKo9+gAzMzMzo6r/AKD//6qq/w8AAAAAAAAAAA==\",\n    \"carPinkFront\": \"hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKD/r/oPAAAAM6MzqjoPAMPMzDzb3aMw0909s9zTPTA9MzPL3DMzMD0zM8vcMzMwMzMzy9wzMzAzMzPL3DMzMDMzM7Pc0z0Aw8zMPNvdowAAM6MzqjoPAACg/6/6/wAAAAAAAAAAAA==\",\n    \"car20\": \"hwQQABAAAAAAAACIiIiIAAAAgGZmOIgIAABoZoYziAgAAGhmhoOIDwCImZmJiPi7gJiZmYuI+LyAdneGuIb4/Ghmd4e7hogPaGZ2h7uGiAhoZmaHu4aICGhmZoeIiIgPaGZmh7uG+LuAdneGuIb4vAC4mZmLiPj8AICbmbmIiA8AAIiIiIiIAA==\",\n    \"car21\": \"hwQQABAAAAAAAACIiIiIAAAAgGZmOIgIAABoZoYziAgAAGhmhoOIDwCImZmJiPjPgJiZmYuI+L+AdneGuIb4u2h2d4e7hogPaHZ3h7uGiAhoZneHu4aICGhmdoeIiIgPaGZmh7uG+M+AdneGuIb4vwC4mZmLiPi7AICbmbmIiA8AAIiIiIiIAA==\",\n    \"car22\": \"hwQQABAAAAAAAACIiIiIAAAAgGZmOIgIAABoZoYziAgAAGhmhoOIDwCImZmJiPj8gJiZmYuI+PuAdneGuIb4+2hmdoe7hogPaGZmh7uGiAhoZmaHu4aICGh2Z4eIiIgPaHZ3h7uG+PyAdneGuIb4+wC4mZmLiPj7AICbmbmIiA8AAIiIiIiIAA==\",\n    \"car23\": \"hwQQABAAAAAAAACIiIiIAAAAgGZmOIgIAABoZoYziAgAAGhmhoOIDwCImZmJiPjLgJiZmYuI+PuAdneGuIb4/Ghmdoe7hogPaGZmh7uGiAhoZmaHu4aICGhmZoeIiIgPaGZmh7uG+MuAdneGuIb4+wC4mZmLiPj8AICbmbmIiA8AAIiIiIiIAA==\",\n    \"car2Left\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.vehicle.car20\\\",\\\"sprites.vehicle.car21\\\",\\\"sprites.vehicle.car22\\\",\\\"sprites.vehicle.car23\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"car2Right\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.vehicle.car20\\\",\\\"sprites.vehicle.car21\\\",\\\"sprites.vehicle.car22\\\",\\\"sprites.vehicle.car23\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"car30\": \"hwQQABAAAAAAAADu7u7uAAAA4CIiPu4OAAAuIuIz7g4AAC4i4uPuDwDumZnp7v674J6Zmevu/rzgQkTivuL+/C4iROS74u4PLiJC5Lvi7g4uIiLku+LuDi4iIuTu7u4PLiIi5Lvi/rvgQkTivuL+vAC+mZnr7v78AOCbmbnu7g8AAO7u7u7uAA==\",\n    \"car31\": \"hwQQABAAAAAAAADu7u7uAAAA4CIiPu4OAAAuIuIz7g4AAC4i4uPuDwDumZnp7v7P4J6Zmevu/r/gQkTivuL+uy5CROS74u4PLkJE5Lvi7g4uIkTku+LuDi4iQuTu7u4PLiIi5Lvi/s/gQkTivuL+vwC+mZnr7v67AOCbmbnu7g8AAO7u7u7uAA==\",\n    \"car32\": \"hwQQABAAAAAAAADu7u7uAAAA4CIiPu4OAAAuIuIz7g4AAC4i4uPuDwDumZnp7v784J6Zmevu/vvgQkTivuL++y4iQuS74u4PLiIi5Lvi7g4uIiLku+LuDi5CJOTu7u4PLkJE5Lvi/vzgQkTivuL++wC+mZnr7v77AOCbmbnu7g8AAO7u7u7uAA==\",\n    \"car33\": \"hwQQABAAAAAAAADu7u7uAAAA4CIiPu4OAAAuIuIz7g4AAC4i4uPuDwDumZnp7v7L4J6Zmevu/vvgQkTivuL+/C4iQuS74u4PLiIi5Lvi7g4uIiLku+LuDi4iIuTu7u4PLiIi5Lvi/svgQkTivuL++wC+mZnr7v78AOCbmbnu7g8AAO7u7u7uAA==\",\n    \"car3Left\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.vehicle.car30\\\",\\\"sprites.vehicle.car31\\\",\\\"sprites.vehicle.car32\\\",\\\"sprites.vehicle.car33\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"car3Right\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.vehicle.car30\\\",\\\"sprites.vehicle.car31\\\",\\\"sprites.vehicle.car32\\\",\\\"sprites.vehicle.car33\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"plane0\": \"hwQYABAAAAAAAADADwAAAAAAACzyAAAAAADAIiIPAAAAAJwrIg8AAP/Ambki8gAA/8+bGSLyAAAvL7QRIvIAAC9MJBEi8gAAz0wikSLyAADPTCKbIvL/APAsIiIi8sIPAC8iIiL8zPwALyIiQv8v8gAvIiJM9P//AMAiwiJE//8AwCLCIkL8/wDALMIiIvIPAMwswiwi8gDATCTC/CLyAMxEIswPL/IATCTywg/A/AD8/88iDwAAAAAAACwPAAAAAAAA8A8AAAA=\",\n    \"plane1\": \"hwQYABAAAAAAAADADwAAAAAAACzyAAAAAADAIiIPAAAAAJwrIg8AAP/AmSki8gAA/8+buSLyAAAvL5QRIvIAAC9MtBEi8gAAz0wikSLyAADPTCKZIvL/APAsIiIi8sIPAC8iIiL8zPwALyIiQv8v8gAvIiJM9P//AMAiwkJE//8AwCLCIkT8/wDALMIiQvIPAMwswiwi8gDATCTC/CLyAMxEIswPL/IATCTywg/A/AD8/88iDwAAAAAAACwPAAAAAAAA8A8AAAA=\",\n    \"plane2\": \"hwQYABAAAAAAAADADwAAAAAAACzyAAAAAADAIiIPAAD/AJwrIg8AAP/PmSsi8gAAL8+ZISLyAAAvLxshIvIAAM9MEiEi8gAAz0wSKSLyAADwTLIpIvL/APAsIiIi8sIPAC8iIiLMzA8ALyLCJP8iDwAvIixE//8PAMAiLEL8/w8AwCIsQvT/DwDALMwixP8AAEwszCLCAADARCLMLMIAAEwkIvwswgAATCIv8swMAAD8/yzyAAAAAAAAwPIAAAAAAAAA/wAAAAA=\",\n    \"plane3\": \"hwQYABAAAAAAAADADwAAAAAAACzyAAAAAADAIiIPAAD/AJwrIg8AAP/Pmbki8gAAL8+bGSLyAAAvL7QRIvIAAM9MJBEi8gAAz0wikSLyAAD/TCKbIvL/APAsIiIi8sIPAC8iIiL8zPwALyIiQv8v8gAvIiJM9P//AMAiwiJE//8AwCLCIkL8/wDALMIiIvIPAMwswiwi8gDATCTC/CLyAMxEIswPL/IATCTywg/A/AD8/88iDwAAAAAAACwPAAAAAAAA8A8AAAA=\",\n    \"plane4\": \"hwQYABAAAAAAAADADwAAAAAAACzyAAAAAADAIiIPAAAAAJwrIg8AAP/Ambki8gAA/8+bGSLyAAAvL0IZIfIAAC8sRBIh8gAAzywkEinyAADPLCSyKfL/APAsIiIi8sIPAC8iIiL8zMwALyIiIvT/IgAvIiLCRP//AMAiIixC9P8AwCwiLCLE/wDALCIsIiIPAMAsIswiIg8AwETC/C8iDwBMJML8/yIPwETyL/zAzA/w/88s8gAAAAAAAMzyAAAAAAAA8P8AAAA=\",\n    \"plane5\": \"hwQYABAAAAAAAADADwAAAAAAACzyAAAAAADAIiIPAAAAAJwrIg8AAP/Ambki8gAA/8+bGSLyAAAvL0IRIvIAAM8iRBIh8gAAzywkEinyAADPLCSyKfL/APAsIiIi8sIPAC8iIiL8zMwALyIiIvT/IgAvIiLCRP//AMAiIixC9P8AwCwiLCLE/wDALCIsIiIPAMAsIswiIg8AwETC/C8iDwBMJML8/yIPwETyL/zAzA/w/88s8gAAAAAAAMzyAAAAAAAA8P8AAAA=\",\n    \"planeLeft\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.vehicle.plane0\\\",\\\"sprites.vehicle.plane1\\\",\\\"sprites.vehicle.plane2\\\",\\\"sprites.vehicle.plane3\\\",\\\"sprites.vehicle.plane4\\\",\\\"sprites.vehicle.plane5\\\"],\\\"flippedHorizontal\\\":false}\"\n    },\n    \"planeRight\": {\n        \"mimeType\": \"application/mkcd-animation\",\n        \"dataEncoding\": \"json\",\n        \"data\": \"{\\\"frames\\\":[\\\"sprites.vehicle.plane0\\\",\\\"sprites.vehicle.plane1\\\",\\\"sprites.vehicle.plane2\\\",\\\"sprites.vehicle.plane3\\\",\\\"sprites.vehicle.plane4\\\",\\\"sprites.vehicle.plane5\\\"],\\\"flippedHorizontal\\\":true}\"\n    },\n    \"roadTurn1\": {\n        \"data\": \"hwQQABAAAAAAwMzMzMzMzAC8u7u7u7u7wLvd3d3d3d2827u7u7u7u7y9u7u7u7u7vL27u7u7u7u8vbu7u7u7u7y9u7u7vbu7vL27uxvRu7u8vbu7EbG7u7y9u9sRu7u7vL27u727u7u8vbu7u7u7u7y9u7u7u7vdvL27u7u727u8vbu7u7vbyw==\",\n        \"tilemapTile\": true\n    },\n    \"roadTurn2\": {\n        \"data\": \"hwQQABAAAAC8vbu7u7vby7y9u7u7u9u7vL27u7u7u928vbu7u7u7u7y9u7u9u7u7vL272xG7u7u8vbu7EbG7u7y9u7sb0bu7vL27u7u9u7u8vbu7u7u7u7y9u7u7u7u7vL27u7u7u7u827u7u7u7u8C73d3d3d3dALy7u7u7u7sAwMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"roadIntersection1\": {\n        \"data\": \"hwQQABAAAAC7vbu7u7vby9u7u7u7u9vLvbu7u7u728u7u7u7u7vby7u7u7u7u9vLu7u7u7u728u7u7u7u7vby7u7u7u7u9vLu7u7u7u728u7u7u7u7vby7u7u7u7u9vLu7u7u7u728u7u7u7u7vby727u7u7u9vL27u7u7u728u7vbu7u7vbyw==\",\n        \"tilemapTile\": true\n    },\n    \"roadIntersection2\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzLu7u7u7u7u73d3d3d3d3d27u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u727u7u7u7vb27u7u7u7u727vbu7u7vbuw==\",\n        \"tilemapTile\": true\n    },\n    \"roadTurn3\": {\n        \"data\": \"hwQQABAAAADMzMzMzMwMALu7u7u7u8sA3d3d3d3duwy7u7u7u7u9y7u7u7u7u9vLu7u7u7u728u7u7u7u7vby7u727u7u9vLu7sdsbu728u7uxsRu7vby7u7uxG9u9vLu7u727u728u7u7u7u7vby927u7u7u9vLu727u7u728u8vbu7u7vbyw==\",\n        \"tilemapTile\": true\n    },\n    \"roadTurn4\": {\n        \"data\": \"hwQQABAAAAC8vbu7u7vby7u9u7u7u9vL3bu7u7u728u7u7u7u7vby7u7u9u7u9vLu7u7Eb2728u7uxsRu7vby7u7HbG7u9vLu7vbu7u728u7u7u7u7vby7u7u7u7u9vLu7u7u7u728u7u7u7u7u9y93d3d3d3bsMu7u7u7u7ywDMzMzMzMwMAA==\",\n        \"tilemapTile\": true\n    },\n    \"roadIntersection3\": {\n        \"data\": \"hwQQABAAAAC8vbu7u7vbu7y9u7u7u7u9vL27u7u7u9u8vbu7u7u7u7y9u7u7u7u7vL27u7u7u7u8vbu7u7u7u7y9u7u7u7u7vL27u7u7u7u8vbu7u7u7u7y9u7u7u7u7vL27u7u7u7u8vbu7u7u7u7y9u7u7u7vbvL27u7u7u728vbu7u7vbuw==\",\n        \"tilemapTile\": true\n    },\n    \"roadIntersection4\": {\n        \"data\": \"hwQQABAAAAC7vbu7u7vbu9u7u7u7u7u9vbu7u7u7u9u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u93d3d3d3d3du7u7u7u7u7vMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"roadVertical\": {\n        \"data\": \"hwQQABAAAADMzMzMzMzMzLu7u7u7u7u73d3d3d3d3d27u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u9sREbvbERG7GxHRuxsR0bu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u93d3d3d3d3du7u7u7u7u7vMzMzMzMzMzA==\",\n        \"tilemapTile\": true\n    },\n    \"roadHorizontal\": {\n        \"data\": \"hwQQABAAAAC8vbu7u7vby7y9uxu9u9vLvL27G7G728u8vbsbsbvby7y9uxuxu9vLvL2727G728u8vbu7u7vby7y9u7u7u9vLvL27u7u728u8vbsbvbvby7y9uxuxu9vLvL27G7G728u8vbsbsbvby7y9u9uxu9vLvL27u7u728u8vbu7u7vbyw==\",\n        \"tilemapTile\": true\n    }\n}","sprites.vehicle.ts":"namespace sprites.vehicle {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const carRedLeft = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const carRedRight = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const carRedBack = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const carRedFront = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const carBlueLeft = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const carBlueRight = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const carBlueBack = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const carBlueFront = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const carPinkLeft = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const carPinkRight = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const carPinkBack = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const carPinkFront = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const car20 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const car21 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const car22 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const car23 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const car30 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const car31 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const car32 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const car33 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const plane0 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const plane1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const plane2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const plane3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const plane4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"transportation\"\n    export const plane5 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const roadTurn1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const roadTurn2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const roadIntersection1 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const roadIntersection2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const roadTurn3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const roadTurn4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const roadIntersection3 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const roadIntersection4 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const roadVertical = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._tile\n    //% tags=\"tile misc\"\n    export const roadHorizontal = image.ofBuffer(hex``);\n}\n","startup.ts":"// This is the last thing executed before user code\n\ngame.setWaitAnyButton(controller.pauseUntilAnyButtonIsPressed)\n// force first game engine\ngame.eventContext()","storySprites.jres":"{\n   \"*\":{\n      \"namespace\":\"storySprites\",\n      \"mimeType\":\"image/x-mkcd-f4\"\n   },\n   \"halloween\":\"hwSgAHgAAAD//////////////////////////////////////////////////////////4iYiYiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iYiYiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iYiYiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iYiYiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iYhoiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iYhoiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iYhoiIiIiIiIiIiIiIiIj/////////////////////////////////X/X//////////////////////4iWhoiIiIiIiIiIiIiIiIj/////////////////////////////////X/Vf9f///////////////////4iWhoiIiIiIiIiIiIiIiIj///////////////////////////////9fVVVV/////////////////////4ibiIiIiIiIiIiIiIiIiIj/////////////////////////////////VVX1/////////////////////4iZiIiIiIiIiIiIiIiIiIj/////////////////////////////////X1X1/////////////////////4iZiIiIiIiIiIiIiIiIiIj/////////////////////////////////Xl9V/////////////////////4iZiIiIiIiIiIiIiIiIiIj////////////////////////////////////l/////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4hoiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iIiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iIiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iIiIiIiIiIiIiIiIiIiIj///////////////////////////////////////////////////9ERERERMSIiIiIiIiIiIiIiIiIiIj/////////////////////////////////////////////////REREREREREREiIiIiIiIiIiIiIiIiIj///////////////////////////////////////////////9ERERERERERERERIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////05ERERERERERERERESIiIiIiIiIiIiIiIj/////////////////////////////////////////////T0REREREREREROTu7k6EiIiIiIiIiIiIiIj///////////////////////////////////////////9PRERERERERETu7u7u7u7ujIiIiIiIiIiIiIj///////////////////////////////////////////9ERERERERE5O7u7kREROTu7oiIiIiIiIiIiIj//////////////////////////////////////////09ERERERETu7u5ERERERERE5I6IiIiIiIiIiIj//////////////////////////////////////////0RERERERO7uTkRERERERERERISIiIiIiIiIiIj/////////////////////////////////////////T0RERERE7u5ERERERERERERERISIiIiIiIiIiIj/////////////////////////////////////////RERERETu7kRERERERERERERERESIiIiIiIiIiIj/////////////////////////////////////////RERERO7uRERERERERERERERERESEiIiIiIiIiIj///////////////////////////////////////9PRERE5O5ERERERERERERERERERESEiIiIiIiIiIj///////////////////////////////////////9ORERE7k5ERERERERERERERERERETkiIiIiIiIiIj///////////////////////////////////////9ERETkTkREREREREREREREREREREREiIiIiIiIiIj///////////////////////////////////////9ERETuREREREREREREREREREREREREiIiIiIiIiIj//////////////////////////////////////09EROROREREREREREREREREREREREREjoiIiIiIiIj//////////////////////////////////////09ERO5EREREREREREREREREREREREREhIiIiIiIiIj//////////////////////////////////////05E5E5EREREREREREREREREREREREREhI+IiIiIiIj/////////////////////////////////////7+VE7k5ERERERERERERERERERERERERE9P+IiIiIiIj/////////////////////////////////////7+Xu7kRERERERERERERERETu7u7u7u5E5P+IiIiIiIj/////////////////////////////////////70XuTkRERERERFRERERE7u7u7k7k7u7u7v+IiIiIiIj/////////////////////////////////////T+TuREREREREFFVFRO7u7lVFRERERETu7v+MiIiIiIj/////////////////////////////////////T+TuRERERETUEVXk7u5ORBFVRERERERE5P+PiIiIiIj/////////////////////////////////////T+TuREREREQRUeXu7kRERB1RRURERERE5P+PiIiIiIj/////////////////////////////////////TuTuTkRERBQRVeVORERERBRRVUVERERE5P+PiIiIiIj/////////////////////////////////////RO7kTkRERB5RVUVEREREREQRVVVERERE5P/PiIiIiIj/////////////////////////////////////RO5E7kRE7t7dVVVEREREREQdVVVFRERE5P7/iIiIiIj/////////////////////////////////////5E5E5E7u7k7dXVVNREREREQUUVVVRERE5P7/iIiIiIj////////////////////////////////////P7k5E5O7uRETU3d1NRERERETUUVVVRURE5P7PiIiIiIj////////////////////////////////////P7ERE7u5ERERE1N1NRERERERERFXVvURE5P7/iIiIiIj////////////////////////////////vVf/M7ETu7u5EREREREREREREVEVERFXV3URE5P7/iIiIiIj///////////////////////////////9fVfXMTOTuRO5EREREREREREQU0U1ERFXVRERE5P7/iIiIiIj///////////////////////////////9ex8zMzO5ORO5ERERERERERBQR3U1EVFXVRERE5P7/iIiIiIj///////////////////////////////9VzMzMzE5ERO5ERERERERERBFR1U1EVFVRRERE5P7/iIiIiIj//////////////////////////////+91zMzM7ERERO5ERERERERERBFV1U1EVFURXURE5P7/iIiIiIj//////////////////////////////1/FzMzMzERE5E5ERERERERERN1d1U1EVFURXURE5P7/iIiIiIj//////////////////////////////1/FzMzM7k5E5E5ERERERERERNTd3U1EFFXRTURE5P7/iIiIiIj//////////////////////////////1XMzMzM7O5O5E5ERERERERERETU3U1EFFXVTURE5P7/iIiIiIj//////////////////////////////3zMzMzMzO7u7kRERERENFRFRERE1E1EFFXVS0RE5P7/iIiIiIj//////////////////////////////8/MzMzM7kTu7k5EREREEVVERERERERERFXV3URE5P7/iIiIiIj//////////////////////////////8/8/8/M7E5E5O5OREQdUVVFRERERERERFXVvURE5P7/iIiIiIj//////////////////////////////8/8///P7O5E5O7u7tQRVVVFRERERERERFXdRERE5P7/iIiIiIj//////////////////////////////8z//P//zO5E5E7k7h5RVURERERERERUVd1NRERE5P//iIiIiIj//+///////////////////////////8///P//T+Tu5E5ERN5dVe5ERERERERV3d1ERERE5P//iIiIiIj//1X////////////////////////////P/Mz/70TuTk5ERETdVeTu7kRERETU3U1ERETk7v//iIiIiIj//1VU9f///////////////////////////8z//0Tk7k5ERETbXVXu7u7u7t7d7e7u7u7u7v//iIiIiIj/X1VV/v//////////////////////////////70Tk7k5ERES03V1NROTu7t297u7u7u5O7v//iIiIiIj//1VV/v///////////////////////////////0RE7u5ERERE1N1NRERE1N1ERERERERE7v//iIiIiIj//1Vf9f///////////////////////////////05E7u5ORERERNRLRERERERERERERERE/v//iIiIiIj//////////////////////////////////////+7kTuTuRERERERERERERERERERERETk/v/PiIiIiIj//////////////////////////////////////+/uTkTk7kRERERERERERERERERERETk/v/PiIiIiIj////////////////////////////////////////uRERE7u5ERERERERERERERERERETk/v+PiIiIiIj///////////////////////////////////////9ERERERO7uRERERERERERERERERETu//+PiIiIiIj///////////////////////////////////////9PRERERETu7kRERERERERERERERETu//+PiIiIiIj///////////////////////////////////////9PRERERERE7u5OREREREREREREROTu//+PiIiIiIj///////////////////////////////////////9PRERERERERO7uTkREREREREREROT+//+PiIiIiIj/////////////////////////////////////////RERERERERETk7u5ORERERERERO7+//+PiIiIiIj/////////////////////////////////////////RERERERERERE5O7u7kRERETk7u7///+PiIiIiIj/////////////////////////////////////////T0RERERERERERETk7u7u7u7u7u7///+PiIiIiIj/////////////////////////////////////////T0RERERERERERERERETu7u5O7v7///+PiIiIiIj//////////////////////////////////////////0RERERERERERERERERERETk7v////+PiIiIiIj//////////////////////////////////////////09ERERERERERERERERERETkzv////+PiIiIiIj///////////////////////////////////////////9ERERERERERERERERERETu/v////+PiIiIiIj/////////////////////////////////////////////REREREREREREREREROTu//////+PiIiIiIj/////////////////////////////////////////////70RERERERERERERE5O7+//////+MiIiIiIj//////////////////////////////////////////////+9ERERERERERETk7u7///////+IiIiIiIj///////////////////////////////////////////////9PRERERERERO7u7o7///////+IiIiIiIj/////////////////////////////////////////////////TkRERERE7u7u7oz///////+IiIiIaIn/////////////////////////////////////////////////7+7u7u7u7u7ujIj///////+IiIiImIn////////////////////////////////////////////////////v7u7u7s6IiIj4//////+IiIiImIn/////////////////////////////////////////////////////////z4iIiIj4//////+IiIiImIn/////////////////////////////////////////////////////////z4iIiIj4/////4+IiIiImIn/////////////////////////////////////////////////////////z4iIiIjI/////4+IiIiImIn/////////////////////////////////////////////////////////z4iIiIiI+P//z4iIiIiImIn/////////////////////////////////////////////////////////z4iIiIiI+P//j4iIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiPz/iIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiPiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////X/Vf////////////////////j4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////X/VV////////////////////j4iIiIiIiIiIiIiIiIiImIb/////////////////////////////////VFVV////////////////////j4iIiIiIiIiIiIiIiIiImIb///////////////////////////////9fVVX1////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////X1X1////////////////////j4iIiIiIiIiIiIiIiIiImIb/////////////////////////////////X/RV////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////T/9e////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIm4j/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImYj/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImYj/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImYj/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImYj/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIiIj/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIiIj/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIiIg=\",\n   \"mistletoe\":\"hwQbABgAAAAAAAAAAAAAzAAAAAAAAAAAAAfAzHzMDgAAAAAAcMfAzHzsDgAAAAAAcMfMzMzsDgAAAAAAd8zMzMwMAAAAAAAAfMzMzMzMAAAAAADAIs7MzMzMAAAAAAAg3SLMzO4AAAAAAAAgJCLM7A4AAAAAAAAgIuLM7A4AAAAAAAAAIsLsDgAAAAAAAAAAzNLifgfMAAAAAMwi7NMid8fMAADAx94jLiIizMzMzABwdzIkIiIizMzMzAB3xy4iwiLCzMzMzAB3zCzizOzOzMzMzAzMzMzMzOzOzMzMzAzMzMzM7M7u7szMzAwAzMzM7A7g7s7u7szAzMzM7A4AAOzu7szAzMzM7A4AAAAAAADAzMzMzM4AAAAAAAAAzMzM7M4AAAAAAAAAAMzM7A4AAAAAAAAAAADA7AAAAAAAAAAAAAAAzAAAAAAAAAA=\",\n   \"holiday\":\"hwSgAHgAAACZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmeuZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmembmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnrmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ7p7umZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme7umZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnunpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme6ZmZmZmZmZmZmZGRERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmRkREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmenumZmZmZmZGREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnumZmZmZmZERERERERERGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnrnpmZmZmZERERERERERERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn/mZmZmZmZmZmZmZnp7hEREZkZGxEREREREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn/n5mZ/J+ZmZmZmZkZ7u4REREeuxEREREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn//5mZv/uZmZmZ6e4R4R4RMe7i7hERERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmf///7/5v/uZmZmZIuIeERER7iIiuxERERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ+f+7///y//8RERGxIiLiERHhLiIishsRERERERERERGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ+f+7+/8u//8RERQhIiIiHu4uIiIisRsRERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ+f+/u/wv//8RERQRIiIi4iIiIiIishsRERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ////u/sv/x8RERQfsSIiIiIiIiISsbsRERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ//////8v/x/xTxQRESviLiIiIiIiErERERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8v/x/xTxTxEe4i4i4iIu7u7rERERERERERERGBiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8v/x8RQRQRESIiIi7i7h4REbERERERERERERFhiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8v/x8RQRTxESIiIhIREREREbEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8i/x8RERERESIiIuIe/xHxHLEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5///////y/x/xHBHxEe4iIi7u7i4dEbEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ/////y/y/x/xHxEREeLu7i4iIuLu7i4SERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSL//xEREREfESIiIiIiIiIiErEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn//xERERERISIi4iIiIiIiIiIiERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn/nxERERERIiIi7iIiIiIiIuIRERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn/mZkREZEiIiLi7e7u7u4iIrIRERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkiIiIeEREREeEuIiISERERERERERGGiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkpIh4RvhERERHh7u4RERERERERERGIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR7h4RERERGxEREREREREREYGIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ7hEREZG7HREREREREREREYiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnpnhERmZm7EREREREREREREYiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnunpmZmZmZERERERERERERgYiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnumZmZmZmZGRERERERERERiIiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmRERERERERGBiIiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmZkREREREZGJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme6ZmZmZmZmZmZmZmZmZmZmJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme6ZmZmZmZmZmZmZmZmZmZmJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZmZmZmZmZmZmZmZmZmZmJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZyZmZmZmZmZmZmZmZmZmZmJiIiImJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnp7pmZmZmZmZmZmZmZmZmZmZmJiIiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnu7pmZmZmZmZmZmZmZmZmZmZmZiIiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmemenpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmemZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZuZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiIiIiIiImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmIiIiIiIiZmZmZiIiIiIiImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmIiIiIiIiZmZmZmZmZiIiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJiJmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiYiZmZmZmZmJmYmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmZiYmZmZmZmZmZiIiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiZiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYaZiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmWmIiIiZmZmZiIiIiIiImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmIiIiIiIiYmYiZiIiImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmYmYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmZmYiZmZmZmZmZmYiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmYaZiZmZmZmZmZiYiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmIiJmZmZmZmZmZiJmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJmZmZmZmZmZmJmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiJmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiIiIiIiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmIiIiIiIiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmYmYmZmZmZmZmZmYmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmZmYiZmZmZmZmJmYmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmYmZiZmZmZmZmYmYmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmIhpmZmZmZmZmImYmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJmZmZmZmZmJiIiImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmGlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYiYmZmZmZmYmZmZiJmZmZmZmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmZmZmYmZmZiZiZmZmJyJyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJmZmYmYmZmZmYiIiIiYzMzH7JmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiIiIiIiZmZmZiZiZmXeczMzH7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJmZmZmZmZmJiJmZmXfMzMzM7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmZmZmZmZmImZmZecfMzMzMm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYaYmZmZmZmZmZmZmZmZycfMzMzMlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiJiJK+LMzMzMnJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJiJ0i3CzOyemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJiZQiLCzO6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmZiJIiLOzO6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJiJ6CLM7puZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmIiIySwt7nfJnJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmWkszj4tcnfMnJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZfOw94iIiwszMzJyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZdydDIiIiwszMzJyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d+YiIiwizMzMzJyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5x8wizsbuzMzMzLyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnJzMzMzMzuzMzMzMyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnJzMzMzO687s7MzMyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyczMzO6Z7u7s7s6cmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZy8zMzO6ZmWnu7s6cmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZzMzMzO6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZzMzMzOycmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyczMzO6cmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmbnMzO6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZzL6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZk=\",\n   \"holiday2\":\"hwSgAHgAAACZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmeuZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmembmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnrmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ7p7umZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme7umZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnunpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme6ZmZmZmZmZmZmZGRERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmRkREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmenumZmZmZmZGREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnumZmZmZmZERERERERERGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnrnpmZmZmZERERERERERERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn/mZmZmZmZmZmZmZnp7hEREZkZGxEREREREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn/n5mZ/J+ZmZmZmZkZ7u4REREeuxEREREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn//5mZv/uZmZmZ6e4R4R4RMe7i7hERERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmf///7/5v/uZmZmZIuIeERER7iIiuxERERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ+f+7///y//8RERGxIiLiERHhLiIishsRERERERERERGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ+f+7+/8u//8RERQhIiIiHu4uIiIisRsRERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ+f+/u/wv//8RERQRIiIi4iIiIiIishsRERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ////u/sv/x8RERQfsSIiIiIiIiISsbsRERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ//////8v/x/xTxQRESviLiIiIiIiErERERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8v/x/xTxTxEe4i4i4iIu7u7rERERERERERERGBiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8v/x8RQRQRESIiIi7i7h4REbERERERERERERFhiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8v/x8RQRTxESIiIhIREREREbEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8i/x8RERERESIiIuIe/xHxHLEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5///////y/x/xHBHxEe4iIi7u7i4dEbEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ/////y/y/x/xHxEREeLu7i4iIuLu7i4SERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSL//xEREREfESIiIiIiIiIiErEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn//xERERERISIi4iIiIiIiIiIiERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn/nxERERERIiIi7iIiIiIiIuIRERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn/mZkREZEiIiLi7e7u7u4iIrIRERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkiIiIeEREREeEuIiISERERERERERGGiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkpIh4RvhERERHh7u4RERERERERERGIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR7h4RERERGxEREREREREREYGIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ7hEREZG7HREREREREREREYiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnpnhERmZm7EREREREREREREYiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnunpmZmZmZERERERERERERgYiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnumZmZmZmZGRERERERERERiIiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmRERERERERGBiIiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmZkREREREZGJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme6ZmZmZmZmZmZmZmZmZmZmJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme6ZmZmZmZmZmZmZmZmZmZmJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZmZmZmZmZmZmZmZmZmZmJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZyZmZmZmZmZmZmZmZmZmZmJiIiImJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnp7pmZmZmZmZmZmZmZmZmZmZmJiIiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnu7pmZmZmZmZmZmZmZmZmZmZmZiIiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmemenpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmemZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZuZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZk=\",\n   \"birthday\":\"hwSgAHgAAAB3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIid3d3d3d3d3d3d3d3d3d3IiIiInd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiInJ3d3d3d3d3d3d3dyIiIiIiIiJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3JyIiIiIiIiJyd3d3d3d3d3d3IiIiIiIiIiJyd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3IiISESEiIiIicnd3d3d3d3cnEiEiIiIiIiIid3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIREiIiIhEiInd3d3d3d3ciESEiIiIiIiIicnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIiIiIiIhIhInJ3d3d3d3ciIiIiIiIiIiIicnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiIiIiIiIiIRIiJ3d3d3dyciIiIiIiIiIiIiInd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiIiIiIiIiIiIiJyd3d3dyciIiIiIiIiIiIiInd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIid3d3dyIhIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIid3d3dxIhIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIicnd3dyIiIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiInd3dyIiIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiInd3dyIiIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiInJ3dyIiIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiInJ3dyIiIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiIiJ3dyIiIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiIiJ3dyciIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiIiIiIiIiIiIiIiIiJ3dyciIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIiIiIiIiIiIiIiIiJyd3ciIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIiIiIiIiIiIiIiIiJyd3ciIiIiIiIiIiIiInd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3IiIiIiIiIiIiIiIiIiJyd3cnIiIiIiIiIiIiInd3d3e7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3JyIiIiIiIiIiIiIiIiJyd3d3IiIiIiIiIiIiIne3u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiJyd3d3JyIiIiIiIiIiIru7u3d3d7e7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIiIiIRESIiIiIid3d3dyIiIiIiIiIisrt3d3d3d3d3u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3JyIiIiIiESEiIiIid3d3d3ciIiIiIiIisnd3d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiIiIiIiIiIid3d3d3cnIiIiIiIicnd3d3d3d3d3d7d7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIicrd3d3d3IiIiIiIicnd3d3d3d3d3d3e7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIisrt7d3d3JyIiIiIicnd3d3d3d3d3d3e3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eyu3t3d3d3tysiIiIicnd3d3d3d3d3d3e3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7u7t3d3e7u3siIiIicnd3d3d3d3d3d3d3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7u7u7u7u7e3cnIiIicnd3d3d3d3d3d3d3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7e3e7u7t3d3d3IiIicnd3d3d3d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiIicnd3d3d3d3d3d3d3d3d3JyIucre7u3d3d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiJ3d3d3d3d3d3d3d3d3dycit7u7u7t3d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3IiISESEiIiIid3d3d3d3d3d3d3d3d3u7u7t3d7t3d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiISISIiIiIiInd3d3d3d3d3d3d3dye7e3d3d7d7d3d3d3d3d3t3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiISIiIiIiIiIiJ3d3d3d3d3d3d3dycicnd3d3d7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyciEiIiIiIiIiIiIiJyd3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyciISIiIiIiIiIiIiIicnd3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dycSIiIiIiIiIiIiIiIiInd3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiIiIiIiIiIiJ3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiIiIiIiIiIiJyd3d3d3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiIiIiIiIiIiIicncid3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiIiIiIiIiIiIiInIid3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiIiIiIiIiIiIiIrsid3d3d3d3d3d3d3d7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiIiIiIiIiIiIiIrsid3d3d3d3d3d3d7d7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiIiIiIrsid3d3d3d3d3d3d7d7d3d3d3d3d3t3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiIiIicrt3d3d3d3d3d3d3d7d7d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiIiJyd3t3d3d3d3d3d3d3d7d3d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiIiIiIiIiIiIiIiIiJ3t3t3d3d3d3d3d3d3d7t3d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIiIiIiIiIiIiIiInd3d7t3d3d3d3d3d3d3d7t3d3d3d3d3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIiIiIiIiIiIiIid3d3d7t3d3d3d3d3d3d3t3t3d3d3d3d3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3IiIiIiIiIiIiIiJ3d3d3d7d7d3d3d3d3d3d3t3t3d3d3d3d3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiInd3d3d3d3e7e3d3d3d3d3d3t3d3d3d3d3d3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIid3d3d3d3d3e3u7t3d3d3d3d3u3d3d3d3d3d3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3IiIiInd3d3d3d3d3d3d3t7u7u7t3d3d3u3d3d3d3d3e3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3u7u7u7u7u7u7u7u7d3e3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3e3d3u7u7u7u3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3e3d3d3d3t7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d3e7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d3e7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d3d7d7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d7d7d3e7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d7d7d3e3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d7d7d3d3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d7d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d3d3d3d3d3d7t3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d3d3d3d3d3d7t3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d3d3d7t3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d3d3d3t3d3d3d7d7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d3d3t3t3d3d3d7d7cXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d3d3t3u3EREREREREbt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d3d3d3d3d3txuxGxERERERu7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3txsRuxsREREREbF7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3txERsRsREREREbF7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3GxERsRsREREREbF7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3GxEREbsRERERERG7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3GxEREbsbERERERG7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3e3d3d3d3u7sREbEbERERERGxe3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3u3u3GxERu7u7EREbERERERGxe3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3t7uxuxERERG7ERG7ERERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxcRuxERERG7GxGxGxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxcRuxERERERGxGxGxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxcRsRsRERERuxERGxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0d3dxERsRsRERERuxERuxERERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0d0d9EdsRsRERERuxsRuxERERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dHRHdF3d0dERsRERERsRsRsRERERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dHVNVF3d0dEbsRERERsRsRsRERERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d9fXdxERERsRERERsRsRsRERERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxEREbsREREREbsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dERBER0bsREREREbsRERsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dEVd3d3bsREREREbsRERsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3F9Hd3bEREREREbsRERsREREREXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dHd3190REbEREREREbsREbsREREREXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dHRFXd3d0dEbEbEREREbsRERsREREREXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3RFTdF9EREbEbEREREbsRERsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3FxEREbEREREREbEREbsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3FxEREbEbEREREbEREbsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dU1d3d3bEbEREREbEREbsREREREXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dU1d3d3bEREREREbERERsREREREXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3R3R33d0dHbEREREREbERERsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3R1XV3d0dEbsREREREbsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1d1d9EdEbsREREREbsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxEREbsREREREbsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxERsRsREREREbsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxERsRsRERERsRsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxEdsRsRERERsRsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0RF3d0duxERERERuxsRsRsRERERu3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1R13dcduxERERERuxERuxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxexGxERERGxGxERuxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxexGxERERG7GxERuxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3exGxERERG7ERGxGxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3ERERG7EbERGxGxERERGxe3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3EbsRERGxGxERERGxe3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ERERERG7ERERERGxe3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3EREREbEbERERERG7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3EREREbsRERERERG7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ERERsRsREREREbF7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3FxGxuxEREREREbF7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3F7G7GxEREREREbt3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7cbERERERERsXt3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cRERERERERu3d3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3e3d3d3d3t3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3u3d3d3d3t3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3t3t3d3d3d3t3t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d7t3t7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t7d3d3d7t3t7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7e3d3d7e7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3u7t3u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3t7u7u7u7u3e3u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7u7u3d3d7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7u7u3d3d7e7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3u7t3d3e7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3e7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3e3e7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3c=\",\n   \"world\":\"hwSgAHgAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////n5mZmZm5mZn5//////////////////////////////////////////////////////////////////+ZmZmZu+u73buZmfn/////////////////////////////////////////////////////////////n5mZmbu9u7u7u7ubmZb5//////////////////////////////////////////////////////////+fmZ2Zubu7u7u7u7vbnZlpmf///////////////////////////////////////////////////////5+ZmZ2Zudu7u7u7u7u7u7uZafn/////////////////////////////////////////////////////n92dmZmZmbu7u7u7u7u7u7uZmZb5////////////////////////////////////////////////////2d2ZmZmZmbm7vMvMvLu7u7u7mZmW///////////////////////////////////////////////////fu5mZmZmZZma7vMvMvLvLvLu725Zpmf///////////////////////////////////////////////9+7u5mZZmZmZmbmu8vMu8y7vMu7u+vMafn//////////////////////////////////////////////727nZmZZmadbWZmzMzMu8y7zMu8zLvMnJb/////////////////////////////////////////////n7u725mZmZnd3ZmZxszMzMzMzMzMzLvLzGn5////////////////////////////////////////////vbu73Wlmltnd3WZmZszMzMzMzMzMzMzMy5yW///////////////////////////////////////////fu5u7bWZmZmbW3ZaZmcnMzMzMzMzMzMzMvMxs+f////////////////////////////////////////+/u9m7bZZmZpZp3WZmlsnMzMzMvMyZZsaWmczMlv////////////////////////////////////////+9m5ndZmaWmWZmZmZmlpnMzLy7zGZmZmZmaZZsafn//////////////////////////////////////9+7mZndZpaZZmZmZmZmZpnGvLtmZplmZmZpZmZmlvn//////////////////////////////////////7+bmdZtZmZmZmaWaWZmZmZmu2ZmZmaWZmaZZmlmZpb//////////////////////////////////////72badaZZmZmZmZmZmZmZmZmZmZmZrZtZmZmZpZmZmb/////////////////////////////////////392ZZtlmZmaWaWZmZmZmZmZmZmZmZrZrZmZmZmaZZpn5////////////////////////////////////351pZmZmZmZmZmZmZmZmZmZmZmZmZma7bWZmZmaZaZaW////////////////////////////////////aWlmZmZmZmZmZmZmZmZmhmhmZmZmZma7a2ZmZmZmmZaZ////////////////////////////////////mWaWZmZmZmZm3WaIaIhmhmiIaGaIaIa4u21mZpZmZplp////////////////////////////////////1m1mZmZmZmaGaGaIaIiGaIaIaGaIZoaIvWtmZmZpZmaZ+f////////////////////////////////+f1m1pZmZohmiIaGZoiIiIaIiIiIiIiIaIbdtmZmZtbWaW+f////////////////////////////////+f3WZmZoZoiGhmhoiIiIiIiIiIhoiIiIiI2L1rZtZtbWaWlv////////////////////////////////+fvWtmZohoaGaIiIiIiIiIiIiGiIiIZoaIiLa7bWbdbWZmkf/////////////////////////////////Zu9ZtZmaGiIiIZoaIaGaGiIiGiIiIiIiIiIi722bdZmZmEf/////////////////////////////////Zu71miIZohohoZmaGiIiIZoiIiIiIiIiIiIiIu92IaGZmZv////////////////////////////////+9a7uIiIiIiIiIhoiIiIiGiIiIiIiIiIiIiGZmtt2IZmZmEfn///////////////////////////////+9a22IiIiIiIi4u7u9i4iIiIiIiIiIiGaIiIiIiIiIiIaIEfn//////////////////////////////5+7ZmaGiIiIiLi73d29u4uIiIiIiIiIiIiIiIaIiIiIiIiIGPn//////////////////////////////5/dFoiGiGiIhrjb3d27u7uIiIiIiIiIiIiIiIhoiIhmZoiIFvn//////////////////////////////99tiIiIiIaIiLjdu729u7uIiIiIiIiIiIiIZohoZohoiIaIZpb//////////////////////////////59miIiIiIiIuNvdu7u9u7uLiI2IiIiIiIiIiGhoZoZoZogYEZb//////////////////////////////5+GiGiIiLuI2N3d27u7u7uL2I2IiIiIiIiIiIiIiGZoiIiIGJH//////////////////////////////7+BEYiIuLuI2N3bvdu7u7uL2I2IiIiIiIiIiIiIiIhoiIgRGJH//////////////////////////////7+GgYiIzMuI3d27vbu7u7uLiN2NiIiIiIiIiIiIiIhoiIiBEZb//////////////////////////////78YiIjIy7uI3d27u7u7u7uOiNuNiIiIiIiIiIiIiIiIiIiIgZb//////////////////////////////78bgYjMu4u43b27u7u7u7uL2LvdiIiIiIiIiIiIiIiIiIiIEZb//////////////////////////////78ciIjMjIi43bvdvbu7u7uIvbuNiIiIiIiIiIiIiIiIiIiIGJb//////////////////////////////8/MHIjMi4jYvbu7u7u7u7uIuLuNiIiIiIiIiIiIiIiIiIiIGJn////////////////////////////////MjMi8joi73du7u7u7u7uI2L2LiIiIiIiIiIiIiIiIiIiIaPn////////////////////////////////MjMi8iIi4vdu7u7u7u7uLiIiNiIiIiIiIiIiIiIiIiIiIaPn////////////////////////////////MHMi8i4jovbu7u7u7u7u7joiNiIiIiIiIiIiIiIiIiIiIZvn////////////////////////////////MjMjMi4i43b27u7u7u7u7u4yIiIiIiIiIiIiIiIiIiIiIYf/////////////////////////////////JzMjMu4i43ru7u7u7u7u7u7uIiIiIiIiIiIiIiIiIiIgYkf////////////////////////////////+/y8iMvIyIyLu7u7u7u7u7u7u7uLu7u7uMiIiIiIiIiIiIlv////////////////////////////////+fy8y8u7yIyLu7u7u7u7u7u7u7u7u7u7u8u4uIiIiIiBaB9v////////////////////////////////+fzMzMvMyIyLy7u7u7u7u7u7u7u7u7u7u7u7uLiIiIiBho+f//////////////////////////////////yczMvIiIyLy7u7u7u7u7u7u7u7u7u8u8zLy7iIiIiIho+f//////////////////////////////////uczMjIiIyLy7u7u7u7u7u7u7y8y8zMy8zLuLiIiIiIho////////////////////////////////////78zMjIiI2Ly8u7u7u8vMzLu7y8zLzMzMzMyMiIiIiIiW////////////////////////////////////n8zMjLuIiMzMzMy8zMzMzLvMzMzMzMzMzMyIiIiIiIj2/////////////////////////////////////8nMi8iMiMy8zMzMy7vMzMzMzMzMzMzMzMyIiIjYjWj5/////////////////////////////////////8nMi8iMuMvMzMzMzMzMzMzMzMzMzMzMzIiIiLjbiJb//////////////////////////////////////5/MvIuIiMjMzMy8zMzMzMzMzMzMzMzMiIiIiLiOaJb////////////////////////////////////////GzLu864vMzMzMzMzMzMzMzMzMzMyMiIiIiIiIaPn////////////////////////////////////////JzMzMvLuIzMzMzMzMzMzMzMzMzIiIiIiIiIiIlv////////////////////////////////////////+fy4jMzMuLyMzMzMzMzMzMzMzMjIiIiIiIiIho9v//////////////////////////////////////////yYyIy8y7iMjMzMzMzMzMzMzMiIiIiIiIiIhm+f//////////////////////////////////////////z2zIu8zMi4jMzMzMzMzMzIiIiIiIiIiIiGiW/////////////////////////////////////////////8yGvLzMu4iIzMzMzMyIiIiIiLi7iIiIiGb5/////////////////////////////////////////////59svLjMzIuIzMzM64iIiIiIiLvMiIiIaJb////////////////////////////////////////////////JvIvIzLuIyMzMu4iIiIjI3N3IiJholv////////////////////////////////////////////////+fzLuIzLyIiMyMiIiIiIjI3IiIiL2b+f//////////////////////////////////////////////////n7uLyMyIiIiIiIiIiIiIiIiIiGaW/////////////////////////////////////////////////////8nMiMyIiIiIiIiIiIiIiIiIZpb///////////////////////////////////////////////////////9pZoaIiIiIiIiIiIiIiIholvn/////////////////////////////////////////////////////////aWaGiIiIiIiIiIiIiGiW+f///////////////////////////////////////////////////////////5lmhoiIiIi7iIhoZpb///////////////////////////////////////////////////////////////+fmWZmZma7a2aW+f///////////////////////////////////////////////////////////////////5+ZmZmZmfn///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8=\",\n   \"field\":\"hwSgAHgAAACZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmcyZzJx5d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZzMzHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZzJnMnHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZyZmczJnHl5d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnJOckzfJd5d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmdkdkZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnMMzMzeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZGd0dEZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZM1Mzd3d3d3d3p3p3d3d3d3d3d3d3d3d3d3eZmZmZmZmZ3R0RERGZmZmZmZmZmZmZmZmZmZmZmZmZmZk5M1Uzd3d3d3d3p3p3d3d3d3d3d3d3d3d3d3eZmZmZmZkZ3REREbGbmZmZmZmZmZmZmZmZmZmZmZmZmZk5M1Mzc3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHREREbEbmZmZmZmZmZmZmZmZmZmZmZmZmZmZMzMzk5l3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZPDMzmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZPJOZzHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmczJnHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmczMfKd6d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmcmXd6d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmcmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRER3RERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZeXd3d3p3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERER0RERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmTmTd8l3d3p3d3d3d6d3d3d3d3d3d3d3d3eZmZkZERERERERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZk5MzOTd3d3d3d3d3d3d6d3d3d3d3d3d3d3d3eZmZkZEREREREREbGbmZmZmZmZmZmZmZmZmZmZmZmZmZk5MzMzmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZnZEREREREREbGbmZmZmZmZmZmZmZmZmZmZmZmZmZkzMzUzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZndEREREREREbGbmZmZmZmZmZmZmZmZmZmZmZmZmZkzU1Uzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZndEREREREREREbmZmZmZmZmZmZmZmZmZmZmZmZmTkzMzUzd5d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZnZERERERERERG7mZmZmZmZkZmZmZmZmZmZmZmZmZk5MzMzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZnZHRERERERERG7kZmZmZkREZGZmZmZmZmZmZmZmZkzMzMznHd3d3d3p3d3d3d3d3d3d3d3d3d3d3eZmZmZ3d0dERERERG7kZmZmRkRERGZmZmZmZmZmZmZmZmZOTOTmZl3d3d3p3d3d3d3d3d3d3d3d3d3d3eZmZmZmd3dERERERG7kZmZmdkREbGbmZmZmZmZmZmZmZmZOTmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERG7mZmZmdkREbGbmZmZmZmZmZmZmZmZmcmZmcx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkRERHdEbEbmZmZmdkREbGbmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdERERHd3b2bmZmZmdkRERGbmZmZmZmZmZmZmZmZmZmZmXenend3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmd0RERER3b2ZmZmZmdERERGbmZmZmZmZmZmZmZmZmZnJnJl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmd0REREREZuZmZmZGd0RERGbmZmZmZmZmZmZmZmZmczJnKZ3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmd0REREREZuZmZmZGd0REbGbmZmZmZmZmZmZmZmZmcyZqap3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdkRERERsZuZmZmZEdEREbGbmZmZmZmZmZmZmZmZmZmZqad3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdkRERERsZuZmZmZHdEREbGbmZmZmZmZmZmZmZmZmZmceXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdndERERsZuZmZnZHREREbuZmZmZmZmZmZmZmZmZmcmcmXl3d3d3p3p3d3d3d3d3d3d3d3d3d3eZmZmZmdndERERERuZmZnZHREREbuZmZmZmZmZmZmZmZmZmcmZyXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdndERERERuZmZnZHREREbuZmZmZmZmZmZmZmZmZmZmZmXx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZndEREREZuZmZnZHREREbuZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZndERERsZuZmZnZHREREbuZmZmZmZmZmZmZmZmZmZmZeXd3p3p3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZERERsZuZmZnZEREREbGZmZmZmZmZmZmZmZmZmZnJfHd3p3p3d3d3d6p3d3d3d3d3d3d3d3eZmZmZmZmZERERu5mZmZnZHREREbGZmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3p3d3d3d3d3d3d3d3eZmZmZmZmZGRERkZmZmZnZHREREbGbmZmZmZmZmZmZmZmZmZmcmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZnZHREREbGbmZmZmZmZmZmZmZmZyZyZmXd3d3d3qnd3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkZ3REREb2ZmZmZmZmZmZmZmZmZyZyZeXd3d3d3qnd3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkR3REREb2ZmZmZmZmZmZmZmZmZmZmZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkR0R0REbGZmZmZmZmZmZmZmZmZmZmZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkd0R0REbGZmZmZmZmZmZmZmZmZmZmZqXp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkdEREREbGZmZmZmZmZmZmZmZmZmZmZqnp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkdEREREbGZmZmZmZmZmZmZmZmZmZmcmXp3d6p3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkREREREbuZmZmZmZmZmZmZmZmZyZmcmXp3d3p3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkREREREbuZmZmZmZmZmZmZmZmZyZmZeXp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkREREREbuZmZmZmZmZmZmZmZmZyZmZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkdEREREbuZmZmZmZmZmZmZmZmZmZmZyXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdndEREREbuZmZmZmZmZmZmZmZmZmTMzeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdndEREREbuZmZmZmZmZmZmZmZmZmTMzk3l3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkdEREREbuZmZmZmZmZmZmZmZmZMzMzeXd3end3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REREREbuZmZmZmZmZmZmZmZk5M1Uzc3enqnd3p3p3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REREREbuZmZmZmZmZmZmZmZk5MzUzM3d3d3d3d3p3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REREREbuZmZmZmZmZmZmZmZmZMzMzc3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REREREbGZmZmZmZmZmZmZmZmZMzMzc3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0RERHdEbGZmZmZmZmZmZmZmZmZOTOZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkRERHd3b2ZmZmZmZmZmZmZmZmZmZnJeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkdERER3bGbmZmZmZmZmZmZmZmZmZmZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkdEREREbGbmZmZmZmZmZmZmZmZyZnJmXd3d3d3d3d3p3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZndEREREbGbmZmZmZmZmZmZmZmZyZnJnHl3d6d3d3d3p3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZndEREREbGbmZmZmZmZmZmZmZmZmZmZmcl3d6d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZnZHREREbGbmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZ3R0REbGbmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZEREREbGbmZmZmZmZmZmZmZmZmZnMycx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZEREREbGbmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZGREREbGbmZmZmZmZmZmZmZmZmcyZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZGREREbGbmZmZmZmZmZmZmZmZmZzJnHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmdndHZGZmZmZGREREbGbmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmd0dERGZmZmZGREREbGbmZmZmZmZmZmZmZmZmZyZyXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZ2d0RERG7mZmZ2R0REbGbmZmZmZmZmZmZmZmZmcyZzHl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZ2R0RERG7mZmZ2R0REbGbmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnR0RERERG7mZmZmR0REbGbmZmZmZmZmZmZmZmZmZmZmXd3d3d6d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdnd3R0RERG7mZmZmd0RERGbmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ2d0dER0RERG7mZmZmdkdERGZmZmZmZmZmZmZmZmZmZmZmXmnd3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ2R0RERERERG7mZmZmZndHZGZmZmZmZmZmZmZmZmZmZnMmXynd3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ3RERERERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnMmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ3RERERERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ3RERERERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZeXd3d3d3d3end3d3d3d3d3d3d3d3d3eZmZmZ3RERERERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3ene3d3d3d3d3d3d3d3d3eZmZmZ3RERERERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ3REREd0RERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZzHl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ3R0R0d0RERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmcmcmXp3d3enend3d3d3d3d3d3d3d3d3d3eZmZkZ0RER0RERERERu5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmcrKZ3d3end3d3d3d3d3d3d3d3d3d3d3eZmRkRERERERERERERu5mZmZmZmZmZmZmZmZmZmZmZmZmZmZnJrKp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmRkRERERERERERERsZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmRERERERERERERERsZuZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXd3end3d3d3d3d3d3d3d3d3d3d3d3eZmRERERERERERERERsZuZmZmZmZmZmZmZmZmZmZmZmZmZmcyZeXd3qnd3d3d3d3d3d3d3d3d3d3d3d3eZmRERERERERERERERsZuZmZmZmZmZmZmZmZmZmZmZmZmZmZnJzHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmRERERERERERERERsZuZmZmZmZmZmZmZmZmZmZmZmZmZmZnMmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmR0RERERERERERERsZuZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmd0RERERERERERERsZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmd0RERERERERERERu5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZfHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmdkdERERERERERERu5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmcfHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmdkdERERERER0d3dvZmZmZmZmZmZmZmZmZmZmZmZmZmZyZyZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZnd3RERERER0d3dm5mZmZmZmZmZmZmZmZmZmZmZmZmZyZycyXeqd3d3d3d3d3d3d3d3d3d3d3d3d3eZmZnZ3R0RERERERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmceXeqd3d3d3p3d3d3d3d3d3d3d3d3d3eZmZmZGRERERERERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3p3p3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRnRHRERERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmcyZZqZ3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZndHRERERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZnMmal3d3d6d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdkdERERERGxmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnMeXd3d3d6d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdkdERERERGxmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdkdERERERGxmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZndERER0R2RmZmZmZmZmZmZmZmZmZmZmZmZmZmZycyZyXx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZndHRHR3RGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZyZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZ3d3dnZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZeXd3d3d3d3d3p3d3d3d3d3d3d3d3d3eZmZmZmZmZ2d2dmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmceXd3d3d3d3d3p3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkREZmZmZmZmZmZmZmZmZmZmZmZmZmcyXx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REZGZmZmZmZmZmZmZmZmZmZmZmZnMyXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REbGbmZmZmZmZmZmZmZmZmZmZmZmZead6d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmR0REbGbmZmZmZmZmZmZmZmZmZmZmZmZqal6d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmR0REbGbmZmZmZmZmZmZmZmZmZmZmcmcqXp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZ2R0REbGZmZmZmZmZmZmZmZmZmZmZmcnMmaZ3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmR0REbGZmZmZmZmZmZmZmZmZmZmZmcnMyax3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmR0REbGZmZmZmZmZmZmZmZmZmZmZmcmcmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REbGZmZmZmZmZmZmZmZmZmTmTM5mZmXd3d3end3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REbGZmZmZmZmZmZmZmZmZmTkzMzl3l3l3d3end3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REbGZmZmZmZmZmZmZmZmZmTkzMzNzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGdEdEbGZmZmZmZmZmZmZmZmZmZkzVTNzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZEdEdEbGbmZmZmZmZmZmZmZmZmTlTVTNzd3l3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZnZHREREbGbmZmZmZmZmZmZmZmZmTkzNTN3l3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZndEREREbGbmZmZmZmZmZmZmZmZmTM5MzNzmXd3d3d3d3d3d3d6d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZndERERERGbmZmZmZmZmZmZmZmZmTkzMzOZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZndERERERGbmZmZmZmZmZmZmZmZmZmTM8mceXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZndERERERGbmZmZmZmZmZmZmZmZmZmZmcnMzHx3qnd3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZndEREREbGbmZmZmZmZmZmZmZmZmZmZmZmZzHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRnREREREbGbmZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRHRHREREbGbmZmZmZmZmZmZmZmZmZmZmZmZmXx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRHRHREREbGbmZmZmZmZmZmZmZmZmZmZmcmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGREREREREb2bmZmZmZmZmZmZmZmZmZmZmczMmXd3d3d3d3p3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGREREREREb2bmZmZmZmZmZmZmZmZmZmZmcnMzHl3d3d3d6p3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZ2RERERER3b2ZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZ2R0RERER3b2ZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZ2R0REREREb2ZmZmZmZmZmZmZmZmZmZmZmZmZmZx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZ2R0REREREbGZmZmZmZmZmZmZmZmZmZmZmZnJnHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmd0REREREbGZmZmZmZmZmZmZmZmZmZmZmZnJnKp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmd0dEREREbGZmZmZmZmZmZmZmZmZmZk5kzOZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmdndHREREbGZmZmZmZmZmZmZmZmZmZkzMzOTeap6d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZndHREREbGZmZmZmZmZmZmZmZmZmZkzMzOTmXp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkREREREbGbmZmZmZmZmZmZmZmZmTMzUzOTd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkREREREbGbmZmZmZmZmZmZmZmZmTMzVTVzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkREREREbGbmZmZmZmZmZmZmZmZmZmzVTOTd5d3d6d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkREREREbGZmZmZmZmZmZmZmZmZmTkzM8Mzd5x3d6d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRndEREREbuZmZmZmZmZmZmZmZmZmZk5M8ycmXx3d3d3d3d3end3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRndERER3ZGZmZmZmZmZmZmZmZmZmZmZM8mcmZl8d3d3d3d3end3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZnRERHRHZmZmZmZmZmZmZmZmZmZmZmZmcnMzMl8d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZnR3d3dEZmZmZmZmZmZmZmZmZmZmcnJzMzMzHx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZ3d0dmZmZmZmZmZmZmZmZmZmZmcnMzMycmXx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZGZmZmZmZmZmZmZmZmZmZmZmcnJyczMzJx5d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmczJzHx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmcmcmcyZmcl8d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnMmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3c=\",\n   \"valentines\":\"hwSgAHgAAAAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMx0RETEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxERERE9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRERE9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MREdEzMzMzMzMzMzMzMzMz0z0zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRETMzMzMzMzMzMzMzMzMzHTEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRMTMzMzMzMzMzMzMzMzMzETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPdMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM5kzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM5kzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz07mZOTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTMTMzk5mZMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzHT0RETEzk5mZmTMzMzMzMzMzMzMzMzMzMzMzMzMzMzPRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdERGx2xEzk5mZ2TMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRuxGxux0RkdkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM90RuxsRERERmT0zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzERERGxERERHRmTEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTEdsRERERERGR2RERPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTsdsRERERERGdGdER0TMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTsR0RERERERGZEdG7ETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMd0REREREREZHZERG7ETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMREREREREREZEZERG9ETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxHREREREREZkRERHRETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxHREREREREZkRERERETEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxPRERERERERkdkRERHRG9EzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRERERERERkRkRERERuxEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRHREREdHZnR0RERER2xEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxGxERERGZmRERERERHTEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRGxERERGRmR0REREREREzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRvRERERERnRkRERERuxEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRsR0RERERERERERERux0zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzETMzMzMzMzMzMzMzMxEREdERERERERERERERuxEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzETMzMzMzMzMzMzMzMxG7HdERERERERERERERHdEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMREREREREREREREREREREREdEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRERERERERERERERERERER3REzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxG9HRERERERERERERERERERsRs9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9G7ERERERERERERERERERERsRs9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxEbERERERERERERERERERER0REzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMx0REREREREREREREREREREREREzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzExERERERERERERERERERERERERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzEdERERERERERERERERERERERERvRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTEbsREREREREREREREREREREREbERMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPT0dsRERERkZkdEREREREREREREbERMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzEdEREREREZmZEREREREREREREbEdMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzExEREREREZmZGREREREREREREdEdMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxERERERkdmRHRERERERERERERERMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzExERERERmRkREREREREREREREbsRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzE7ERERHRmRERERERERERERHRsRvRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzE70bERGRGRERERERERERHb0bERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzExHdERGZEREREREREdG7G7EdEdEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxERHZGZERERERER0RG7HRERMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMR250ZERERERHRuxGxERMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRu5kRERERERGxuxER0TMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTkRkRERERvRsRuxEdMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTmRERu7sRuxsRETEzMzMzMzMzOTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM5mZmTMRvR0RsRHdETMzMzMzMzM5mTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM52ZOTMTERHdEREzMzMzMzMzMzOZmTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM5mZmTkzHTEz0z0zMzMzMzMzk5mZmTMzMzMzMzMzMzMzMzMTPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM5mZmTMzMzMzMzMzMzMzMzMzM5mZ2TMzMzMzMzMzMzMzMzMdMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzk5mZMzMzMzMzMzMzMzMzMzMzMzOZOTMzMzMzMzMzMzMzMzMRPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzk5kzMzMzMzMzMzMzMzMzMzMzMzOTOdM9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxERmRERPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9HRHdmd0b0RHRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTMzMzMzMzMzMzMzMzMzMzMxEREbu7m7m7ERERPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdPTMzMzMzMzMzMzMzMzMzE9HbISIi0rkiHbsbMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRMzMzMzMzMzMzMzMzMzMzE70rIiIiIpkiIiLb0RHRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzHbsiIiIiIpspIiIiERERMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdES0iIiIiIpIpIiIis7vbEd09MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRESMiIiIiIiKZIiIiIiK7HRERPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxOyIiIiIiIiKZIiIiIiIiG73b0TMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxO9KyIiIiIiIiKbKyIiIiIiIrK7ER0RMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxO9IiIiIiIiIiKSKSIiIiIiIiKyHRHdETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxO9IiIiIiIiIiKSKSIiIiIiIiIiErG7GzEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxIiIiIiIiIiKyuSIiIiIiIiIiIiK729EzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRIiIiIiIiIiIimSIiIiIiIiIiIiIiuxERMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxEtIiIiIiIiIpK7mSIiIiIiIiIiIiIiIjMdMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz07ErIiIiIiIiIpKZmZkpIiIiIiIiIiIiIiLbMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz07ErIiIiIiIiIiK725ktIiIiIiIiIiIiIiLbMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz09ErIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIdPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxG9IiIiIiIiIiIiIiIiIiIiIiIiIiIiIhLRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhI9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhsxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxO9IiIiIiIiIiIiIiIiIiIiIiIiIiIiIhs9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxKyIiIiIiIiIiIiIiIiIiIiIiIiIishEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9PRKyIiIiIiIiIiIiIiIiIiIiIiIiIiE9EzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRvSIiIiIiIiIiIiIiIiIiIiIiIiIiETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTESEiIiIiIiIiIiIiIiIiIiIiIiIiHTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzHbEiIiIiIiIiIiIiIiIiIiIiIiKyHTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzE727IiIiIiIiIiIiIiIiIiIiIiKyETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdETMzMzMzMzMzMzMzE7G7uysiIiIiIiIiIiIiIiIiIiIR0TMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRETEzMzMzMzMzMzMz0xHdHREhIiIiIiIiIiIiIiIiIjIRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMREREzMzMzMzMzMzMzMxMREREtIiIiIiIiIiIiIiIiItLRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRERExMzMzMzMzMzMzMzPTEbsiIiIiIiIiIiIiIiIiIrLRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTERERMzMzMzMzMzMzMzMTsSsiIiIiIiIiIiIiIiIiIrvRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRERERMzMzMzMzMzMzMzMTsSsiIiIiIiIiIiIiIiIiIhsxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRERExMzMzMzMzMzMzMzPT0SIiIiIiIiIiIiIiIiIi0hE9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMREREzMzMzMzMzMzMzMzMz0SIiIiIiIiIiIiIiIiIiEjEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdETMzMzMzMzMzMzMzMzMT0SIiIiIiIiIiItsrIiIi0jEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRLSIiIiIiIiKSmZmZKyIi2zEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9PRKyIiIiIiIiKSuZmyIiIi2zEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxKyIiIiIiIiIiIpkiIiIiHTEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxKyIiIiIiIiIiIpIpIiISETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRKyIiIiIiIiIiIpK5IiISMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdLSIiIiIiIiIiIiKZIiIbMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTsSIiIiIiIiIiIiKbKyIbMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTsSIiIiIiIiIiIiKSKbIbMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMduyIiIiIiIiIiIiKymdMRPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRuysiIiIiIiIiIiIimRHRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRu+0iIiIiIiIiIiIiktkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdEREiIiIiIiIiIiKym9kzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz3RErIiIiIiIiIjK7HZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxG7MyIiIiIiIh0REZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMx0RESEiIiIiuxHdPZM5M5kzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMd3bErsru7G9EzM5OZk5kzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz09G7HRHdET0zMzOZmZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxERER0R0TMzM9OZmZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRPTMzMzMzM5mZmZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzk5mZmZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzk5mZmZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM5OZmdkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz0zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MdMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMdPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTMzMzMzMzMzMzMzMzMzMzMxMRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMx0RMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxERMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMx0RMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzExERETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzHRERETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzHRERETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzExHRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM=\",\n   \"lake\":\"hwSgAHgAAABmZmZmZmZmZmZmZtEdEbG7u7u7uxHMERHMzMzMZmZmZmZmZmbmZu5uZmbuZuZu5maIiIiIiIiIiIiIiOhmZmZmZmZmZmZmZt0dEbG7u7u7EcHMERHMzMzMbGZmZmbmbmbmZm5mZmbmZmZmZoaIiIiIiIiIiIiIiOhmZmZmZmZmZmZmZt0dEbG7u7sREcHMHMHMzMzMbGZmZmZuZmZuZmZm5m5mZmZm5oaIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFt0dEbG7uxsREcEcEczMzMzMZuZmZmZmZmZmbmbmZmZmZuZmboaIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtEdERG7uxsREc0REcHMzMzMbG5mZm5mZmaIaGhoZmZmZmZmZoaIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd0dERG7uxERwRwREcHMzMzMZmZmZmZm7oiIiIhmZmZmZmbmZoiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd3dERG7uxERzBwREczMzMzMZmZmZmbmhoiIiIhm6GZuZmZuhoiIiIiIiIiIiIiIiIhmZmZmZmZmZmYWEdHdEbu7uxERwRwRwczMzMzMZm5uZm5mhoiIiIiIaGZmZmZmiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYWEdHdEbu7GxERERERzMzMzMzMZmZmZm5miIiIiIiIZmZmZmZmiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYWERHdEbu7uxERERERwcHMzMzMbG5mZmaGiIiIiIiIaGZmZuZmiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYWERHdHbG7GxERERERERHMzMzMZmZmZmaOiIiIiIiIiOhm5m6GiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYWEdHdHbG7GxERERERERHMzMzMbG5m5maIiIiIiIiIiGZmZmaGiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmbWEd3dHbG7uxEREREREcHMzMzMZm5mZuaIiIiIiIiIZmZmZmaGiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd3d3RG7uxERERERwczMzMzMZmZuZuaIiIiIiIiIiGhmZoaIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd3d3RG7uxERERERzBzMzMzMZmbuZoaIiIiIiIiIiIiIZoaIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtHd3RG7uxERERERERERzMzMZmZuZo6IiIiIiIiIiIiIZoiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtHd3R2xuxsRERERzMzMzMzMbG5mZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFhHd3R2xuxERERERwczMzMzMZmZmboaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3d0RuxERERERERHMzMzMZmZmbo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3d2xuxsRERERERHBzMzMZuZmZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3d27u7sREREREcwRzMzMbGZmZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3d29u7sRERERzMzMzMzMbGZmZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d29u7sRERERzMzMzMzMZmZm5oiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d29u7sREREREczMzMzMZmbmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d29u7sbEcEREczMzMzM7GaGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d29u7sbEREREcHMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d29u7sbERERERHMzMxsZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d27u7sbERERERHMzMxsZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZtbR3d27u7u7ERERERzBzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZtbd3d27u7u7HBEREcwRzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d27u7sbwRERHMwczMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZh3d3d27u7u7wREREcHMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZh3d3b27u7u7ERwREcHMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3b27u7u7ERzBEcHMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3b27u7u7EcwRHBHMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3R2xu7u7EcwRwRHMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3Ruxu7u7EcEcwczMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3Ruxu7u7G8HMEczMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHdvRGxu7u7y8zMEczMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm1hHdHRG7u7u7y8zMEczMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm1tHdHRG7u7u7zMzMHMHMzMzMbIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtHdGxG7u7u7wczMHMHMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtHdERERu7u7wczMHMHMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtHdEbERu7u7wczMzMHMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtG9ERGxu7u7wczMzMzMzMxs5o6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtEdERG7u7u7wczMzMzMzMzM5o6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtEdERG7u7vLwczMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm3d0dEbG7u7vLEczMzMzMzMzMbIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmHd0dEbG7u7sbEcHMzMzMzMzMbIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd0REbG7u7sbEcHMzMzMzMzMbIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd0RERG7u7sREcHMzMzMzMzMbIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd0RERG7u7sREcHMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd0REbG7u7sREcHMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm3d0REbG7uxsREczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm3R0REbu7uxsREczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm3R0REbu7uxsREczMzMzMzMzMbI6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm3R0REbu7uxsREczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmbW0R0REbu7uxsREczMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0R0REbu7uxsREczMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0REREbu7uxsREczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0REREbG7uxsREczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0RERsRG7uxsREczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0RERsbG7uxsRzMzMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0RERsbu7uxsRzMzMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0REREbu7u7sRwczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0REREbG7u7sbwczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0REREbG7u7sbwczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0R0REbG7u7u7wczMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmbZ3R0REbG7u7u7wczMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYR3R0REbG7u7u7EczMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYR3d0REbG7u7u7HMzMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYR3d0RERG7u7u7G8HMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhbR3d0RERG7u7u7G8HMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhYR0d0RERG7u7u7G8HMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhYR0d0dERG7u7u7y8HMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhYR0d0dG7G7u7u7u8HMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhYR0d0dEbG7u7u7u8HMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhYR0d0dERG7u7u7u8zMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhYR0d3dERG7u7u7u8zMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZh0R0d3dERGxu7u7u8zMzMzMzMzMbI6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZh0R0d3dHRGxu7u7u8zMzMzMzMzMbIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhER0d3dHbERu7u7u8zMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhER0d3dHRERu7u7u8vMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmFhEd0d3dHRG7u7u7u8vMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmFhER0d3d3RGxu7u7u8vMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmFhER0d3d3RGxu7u7u8vMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmFhER0d3d3Ruxu7u7u8vMzMzMzMzM5o6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmER0R0d3d3Ruxu7u7u8vMzMzMzMzM5o6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmER0R0d3d3Ruxu7u7u8zMzMzMzMxs5oaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZm0R0R0d3d3R2xu7u7u8zMzMzMzMxs5oaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZm0REREd3d3R2xu7u7u8zMzMzMzMxs5o6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYW0REREd3d3b27u7u7u8zMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYW0REREd3d3b27u7u7u8zMzMzMzMxs5oaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYWEREREd3d3d27u7u7u8zMzMzMzMzM5oaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYdEREdEdHd3d27u7u7u8zMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYREREdEdHd3d27u7u7y8zMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYRERHdEdHd3d27u7u7EczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZtYRERHdERHd3d27u7u7EczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhYRERHdERHd3d27u7u7EczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhYRERHdERHd3d29u7u7EczMzMzMzMzMZoeIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZh0RERERERHR3d29u7u7EczMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhERERER0R3R3d29u7u7EczMzMzMzMzMZu6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhERERER3R3R3d29u7u7wcHMzMzMzMzMZu6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZm1hERERER3d3R3d29u7sbwcHMzMzMzMzMZm6GiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZm1hERERHR3d0R3d29u7sbEcHMzMzMzMzMZm6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmFhERERHd3d0R3d3du7sbEcHMzMzMzMxs5maIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmFhERERHd3d0R3d3du7sbEcHMzMzMzMxs5u6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmERERERHd3d0R3d3du7sREcHMzMzMzMxs5maIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmbWERERERHd3d0d3d3du7sREczMzMzMzMxs5maIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWERERERHR3d0d0d3du7sREczMzMzMzMxs5u6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWERERERHd3d3d3d3du7sREczMzMzMzMzMZu6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWEREREdHd3d3d3d3du7sREczMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWERERERHd3d3d3d29u7sRwczMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYRERERERHd3d3d3d29u7scwczMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYdERERERHd3d3d3d29u7sczMzMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYdEREREdHd3d3d3d29u7vMzMzMzMzMzMzM5maIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYdERERERHd3d3d3d29u8vMwczMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWERERER3d3d3d3d29u8vMzMzMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWERERERHd3d3d3d29u8vMzMzMzMzMzMzM5maIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWERERERHd3d3d3d29u8vMzMzMzMzMzMzMZu6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmEREREdHd3d3d3d29u8vMzMzMzMzMzMzMZu6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmEREREdHd3d3d3d29u8vMzMzMzMzMzMzM5u6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmFhEREdHd3d3d3d27u8vMzMzMzMzMzMzM5m6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmFhEREdHd3d3d3d27u8zMzMzMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhEREdHd3d3d3d27u8zBzMzMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhEREdHd3d3d3b27uxzBzMzMzMzMzMzMZu6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhEREd3d3d3d3b27uxzBwczMzMzMzMzMZuaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhYREd3d3d3d3b27uxzBEczMzMzMzMxsZuaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhYRHdHd3d3d3b27uxEcwczMzMzMzMzMZuaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYRERHd0d3d3bu7uxERwczMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYREREdEd3d3bu7yxERwczMzMzMzMzM5uaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYRER0REd3d3bu7yxERzMzMzMzMzMzMZuaIiIiIiIiIiIiIiIhohoaIiIiIiIiIiIiIiIiIiIhmZmZmZmYRER0R0d3dvbu7yxEczMzMzMzMzMzMZuaIiIiIiIiIiIiIiGhmZo6IiIiIiIiIiIiIiIiIiIhmZmZmZmYRERER0d3dvbu7yxERzMzMzMzMzMzMbGaGiIiIiIiIiIiIiIhoaIaIiIiIiIiIiIiIiIiIiIhmZmZmZmYRERER0d3dvbu7GxERzMzMzMzMzMzM7G6IiIiIiIiIiIiIiGhmZoaIiIiIiIiIiIiIiIiIiIhmZmZmZmYREREd3d3dvbu7GxERzMHMzMzMzMxsZmaIiIiIiIiIiIiIiGZubmaIiIiIiIiIiIiIiIiIiIhmZmZmZmYREREd3d3du7u7HMHBHBHMzMzMzMzMZmaIiIiIiIiIiIiIaOZm7maIiIiIiIiIiIiIiIiIiIhmZmZmZmYd0RER3d3du7u7HBERERHBzMzMzMzMZmaIiIiIiIiIiIiIaOZmZmaIiIiIiIiIiIiIiIiIiIhmZmZmZmYW0dER3d3du7u7ERERwRHMzMzMzMzMZmaIiIiIiIiIiIiIaOZmZm6IiIiIiIiIiIiIiIiIiIhmZmZmZmYWEdER3d29u7u7ERwRERHMzMzMzMxmZmaIiIiIiIiIiIhmZmbuZm6IiIiIiIiIiIiIiIiIiIhmZmZmZmYWEdER3d29u7vLERHBEcHMzMzMzMxsZmaIiIiIiIiIiIiIZmbm7m6OiIiIiIiIiIiIiIiIiIhmZmZmZmYWEdER3d29u7sbEREcEczMzMzMzMzMZmaOiIiIiIiIiIiIZmZm5maGiIiIiIiIiIiIiIiIiIhmZmZmZmbWEdHR3d27u7sbEcERwczMzMzMzMzMZmaGiIiIiIiIiIiIaGZm5maGiIiIiIiIiIiIiIiIiIhmZmZmZmbWERHR3d27u7sRERERzMzMzMzMzMzM5maGiIiIiIiIiIiIZmZmZm6GiIiIiIiIiIiIiIiIiIhmZmZmZmbWERHR3d27u7sRERERzMzMzMzMzMzM5u5miIiIiIiIiIiIZmbuZu5miIiIiIiIiIiIiIiIiIhmZmZmZmZmHRHR3b27uxsRERHBzMzMzMzMzMzM5u5miIiIiIiIiIiI7uZmbuZmiIiIiIiIiIiIiIiIiIhmZmZmZmZm3dHd3b27uxsRERHMzMzMzMzMzMxs5m5mhoiIiIiIiIho5mZmZuZmiIiIiIiIiIiIiIiIiIhmZmZmZmZm3dHd3bG7uxERERHMHMzMzMzMzMzMZu5m5oiIiIiIiIhmZmZmZmZmiIiIiIiIiIiIiIiIiIhmZmZmZmZm3dHd3RG7uxERERHMEcHMzMzMzMzMZm5mZmaIiIiIiIhoZmbuZmZmiIiIiIiIiIiIiIiIiIhmZmZmZmZm3dHdHbG7uxEREcEcEczMzMzMzMzMZmbmZoaIiIiIiIh4ZmZmbmZuiIiIiIiIiIiIiIiIiIhmZmZmZmZm3dHdHbG7uxEREcERzMzMzMzMzMzMZmZmboaIiIiIiIhm5mZm5mbuiIiIiIiIiIiIiIiIiIhmZmZmZmZm1tHdEbG7uxERERHBzMzMzMzMzMzM5uZmZoaIiIiIiIhmZmZmZuZmiIiIiIiIiIiIiIiIiIhmZmZmZmZm1tEdEbu7uxERERHMHMHMzMzMzMzMZuZmZoaIiIiIaGZmbmZm5u5miIiIiIiIiIiIiIiIiIhmZmZmZmZm1t0REbu7GxEREcEcEcHMzMzMzMzMZm5m5maIiIiIaGZmbmZmZuZmjoiIiIiIiIiIiIiIiIhmZmZmZmZm1t0Rsbu7GxEREREREcHMzMzMzMzMZm5mZmaGiIiIiGZmbmZmbmZuhoiIiIiIiIiIiIiIiIhmZmZmZmZm1h0Rsbu7GxEREREREcHMzMzMzMzMZmZuZmZmiIiI6OZmZmZmZmZuhoiIiIiIiIiIiIiIiIhmZmZmZmZm3R0Rsbu7GxEREREREcHMzMzMzMzMbGZmbm5miIiIaObmZmZmbmZmhoiIiIiIiIiIiIiIiIhmZmZmZmZm3RERsbu7ERERHBERwczMzMzMzMzMZmZmZmZmZmbmZm5mZmZmZmZmZoiIiIiIiIiIiIiIiIhmZmZmZmZm3RERsbu7ERERERERzMzMzMzMzMzMZmZmZmZmZmZm5mZmZmZmZmZmZoiIiIiIiIiIiIiIiIhmZmZmZmZmHRERu7u7GxEREcHMzMzMzMzMzMzMZmbubuZmbmZm5mZmZmZmbmZmboaIiIiIiIiIiIiIiIg=\",\n   \"ocean\":\"hwSgAHgAAAD4////////////////j/iPiP9mZmZmZmZmZmZmZmZmZpmZmWZmZmaGZmZmZmZmZmZmZmZmZmZmZmZmZmb/////////////////iP+I/4+IZmZmZmZmZmZmZmZmlmZmmWlmxszMZmZmZmZmZmZmZmZmZmZmZmZmZsz///////////////j/+I/4/4iI+P//b2ZmZmZmZmZmZszMzGxmzMzMbGZmZmZmZmbGbGbGzGbGzMzMzMz///////////////+P+I/4/4iIiIj4/////29mZmZmxszMzMzGzMzMzGbMzMzMzMzMzMzMzMzMzMzMzMz///////////////+I+Ij/j4iIiIiI//////9mZmZmzMzMzMzMvLvMzMzMzMzMzMzMzMzMzMzMzMzMzMz//////////////4/4j/j/iIiIiIiIiP9mZv//ZmZmzMzMzMzMvLvMzMzMzMzMzMzMzMzMzMzMzMzMzMz///////////+P/4j/j/+PiIiIiIiIiGhmZvb///9mxry7u7vMzMvMzMzMzMzMzMzMzMzMzMzMzMzMzMz////////////4j4j/iP+PiIiIiIiIiIhmZvb///9vxry7u7u7u8vMzMzMzMzMzMzMzMzMzMzMzMzMzMz/////////////iPiP+P+IiIiIiIiIiIiIaP///29mZmZmvLu7u7vMzMzMzMzMzMzMzMzMzMzMzMzMzMz/////////////j/+P/4+IiIiIiIiIiIiI+P///2ZmZmZmZmZmvLvMzMzMzMzMzMbMbGbGxsxsZmbGzMz/////////////iP///4iIiIiIiIiIiIiIiP//iIhmZmZmZmbGvLvMzMzMZmZmZmZmZmZmZmZmZmbGzMz/////////////+P/4/4iIiIiIiIiIiIiIiIj/ZmaGiGhmZmbMvMvMzMxsZEZEZGZmZmZmZmZmZmbGzMz/////////+P+P/4//j4iIiIiIiIiIiIiIiIiIZmZm/4iIZmbMzMzMzMxERERERGZmZmZmZmZmZmbGzMz///////+P///4j/iPiIiIiIiIiIiIiIiIiIiIZmZm/////2/MzMzMzMxERERERGZmZmZmZmZmZmbGzMz////////4/4//j/+IiIiIiIiIiIiIiIiIiIiIiPj2//////+8y8zMzGxERCJERGZmZmZmZmZmZmZmzMz//////4////j/iI+IiIiIiIiIiIiIiIiIiIiIiIj/j29mZma2y8xmZmZERCJERGRmZmZmZmZmZmZmZmb///////j/j/iP+I+IiIiIiIiIiIiIiIiIiIiIiIj4/2ZmZmZmZmZmZmZGJEJERERmZmZmZmZmZmZmZmb/////j///iPiI/4iIiIiIiIiIiIiIiIiIiIiI/4+I+P9mZmZmZmZmZmZGRERERERVZmZmZmZmZmZmZmb///////+IiI/4j4iIiIiIiIiIiIiIiIiIiIj4//9mZvj/ZmZmZmZmVVVFRCRCRERVVWZmZmZmZmZmZmb///////+I+IiIiIiIiIiIiIiIiIiIiIiIiIiI//9mZmaI/2ZmZohVVVVVREREIkRmVVVlZmZmZlVVVWb/////////iIiIiIiIiIiIiIiIiIiIiIiIiIj4//9vZmZmhoj/9lVlZmZmRUREQlVlZlZVVVVVVVVVxsz///+P+P+IiIiIiIiIiIiIiIiIiIiIiIiIiIhvZmZmZmZmZvZvZlVmZmZmRkREVFVlZmZmVVVVZmZmxsz///+I/4+IiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmZmZmZmb2ZmZmZmZmZkREZmZmZmZmZplmZmZmzMz//4///4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIb2ZmZmZmZmaGaGZmZmZmxkzEZmZmZmZmZmZpZmbGzMz///j/j4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiP+PZmZmZmaGZmZmZmZmzMzMZmZmZmZmZmZmZmbMzMz/iP//iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiPj/j2hmZmZmZmbGzGbGvMzMZmZmZmZmZmZmZmbMzMyI//+Pj4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4j4j/b2ZmZmbMzMzMu8vMZmZmZmZmZmZmZsbMzMz4/4/4iPiPiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiPj///9mZsbMzMzMvMvMzMzMZmZmZmZmZsbMzMz///j4j/+IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiP////b8bMzMzMzMzMzMzMzMxmZmZmZsbMzMz/j4//j4+IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj/+G9mZs+8y7zLzMzMzMzMzMzMzMzMzMzMzMz///j/+I+IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4/2ZmZva8u7u7y8zMzMzMzMzMzMzMzMzMzMz/iP+P/4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI/29mZmbGy7u7u8zMzMzMzMzMzMzMzMzMzMyP+P//j4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI////b2ZmZma2u8zMzMzMzMzMzMzMzMzMzMyImf//iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiPj//29mZma8u8zMzMzMu7vMzMzMzMzMzMz4n/mPiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P9vZma8u8zMzMxsu7u7y8zMzMzMzMz//5mJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiPj/b8a8u8zMzMxsZra2u8zMvMvMzMyf+YiZiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj//8+8y8zMzMxsZmZmZszMvLvMzMz/mYmYiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj//8/MzMzMzMzMZmZmZmbMvLvMzMyPmImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj////MvLvMzMzMZmZmZmbGzLvLzMyIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4j//GvLvMzMxsZmZmZmZmzLzLzGaJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmj2ZmzMxsZmZmZmZmxry7bGaJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZlZmZmZmZmZmZmaYiIiJiIiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmZmZmZmZmZlZVVWZmZmZmZsaIiYiZiIiImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmZmZmZmZWVVVVZmZmzMyImIiYiYiIiImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiPj/b2ZmZmZmZmZmmUVEVUa0zMyZiImImYmIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P9mZmZmZmZmZmaWZkREVEREy8yZiYiImImIiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+G9mZmZmZmZmZmZmZkRERERExMyZmYiYiJmIiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI/49mZmZmZmZmZmZmZkREIkREZGaZmYmIiYmJiIiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P///2ZmZlVVZmZmZkQkRERERGaZmZmZmYmYiYiImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiPj/ZmZWVVVmZmZmZkYiIkRERGSZiJmJmJmImYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZlVVZWZmZmbMbEZEJEJERGSZiZiJiJmJmImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVVVlZmZmZszMzExEJEJERMuZmYiZiJiJiJmIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P//ZmZmZszMzMxERCRCRMyImYmYiYiZiJiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI/4iIZmZmZszMzMxMRERERMyZmJmImYiYiYiZiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4j/iIaGZmZry7zMzMzERExMyZiZmJmImImYiYiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4Zmb/ZmZmZry7u8zMzEZExsyYmZiZiJmImImImYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmb2ZmZmzMbMu8vMzGZmxsyImYmZiZiJmJmImZmJiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhvZmZmZmbMzMzMu8zMzMzMZsyImImYmYiZiJmJmJmZiIiZiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhvZmZmZmbMzMzMzMzMzMzMzMyIiJmImYmYiZiZmJmJiYiYiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZv9oZsbMzMzMzMzMzMzMzMyIiJiJmJmImYiZmZmJmIiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI/////8a8y8zMzMzMzMzMzMyJiIiZiJmJmImYmZmYiImImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P///2+8y8zMzMy8u8zMzMyYiImYiZiJiImImYmIiZiIiImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P+PiIjIu8zMzMy8u7y7y8yJiZiImYiZiJiImJmIiZiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI//+PiGhmu8zMzMzGzLy7u8yZmIiJmYmYiZiJiJmJmIiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI////j2ZmZszLzPb/Zma7u8yZiYmYmJmImYiZiJiZiImIiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI////j2ZmZry7zIb2aGZmZviZmYiYiZmJmImYiYiZiImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P/4/2Zm+MbLzGZmZmZmZmaZmYmImZiZiJmImYmYiZiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiP/4/2/2/2/MZmZmZmZmZmaZmZmImImZiZiJmImYmYiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI/4//9vZmZmZmZmZmZmZWaZmZmJmJmYiYiJmJmIiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4iI/4//9vZmZmZmZmZlVVVWaZiZmZiJmZmYiYiJmJiImYiImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4iI//X2VmZmZmZmZmZmZmZmaZmZmZiJiImYmYmZmJiJiIiZiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4iIj/X1VVVVVVVWVmZmZmZmaZmZmYiZiJmJmImZmZiIiIiJiIiImIiIiIiIiIiIiIiIiIiIiIiIiIiIj4iIj/X/VfVVVVVWVmZmb4ZmaZmWmZmYiZiJmJmJmZiYiJmJmIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4iIj//4j/ZmZmZmZmZmZmZmaZmZmZmYmYiJmZiImYiYiYmZmJiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4iIj/iIj/aGZm9mZmZmZmZmaZmZmZmJmYiZiZiImYmYiImYmIiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIj4+Ij/iIj/iG//////b2ZmZmaZmZmZmZmJiZiZiZiImYmImYmYiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIj4+Ij//4j/iI//j///j/9mZmaZmZmZmZmZmIiZmYiImZmImJmIiYiYiIiIiIiIiIiIiIiIiIiIiIiIiIiI+Ij/iIj/iI//////j///ZmaZmZmZmYmZmYiZmYiJmJmImJmImYiYiYiIiIiIiIiIiIiIiIiIiIiIiIiI+Ij/+Pj//4//////j/9v9v+ZmZmZmZmZmYmYmYmJmJmZiJmJmIiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIj/+Pj//4//////j/9vZvaZmZmZmZmZmYmYmZmZiJmZiJmJmImImYiIiIiIiIiIiIiIiIiIiIiIiIiIiIj/+Pj//4//////j///ZmaZmZmZmZmZmZmZmZmZiZiZiZiZmIiImIiIiIiIiIiIiIiIiIiIiIiIiIiI+Ij///j//4//////////ZmaZmZmZmZmZmZmZmJmZiZiZmYiZiImImImIiIiIiIiIiIiIiIiIiIiIiIiI+Ij/j/j/+Pj/////////b2aZmZmZiZmZmZmZiZmZmYiZmYiZiImIiImIiIiIiIiIiIiIiIiIiIiIiIiIiI//iPj/+Pj/////j////2aZmZmZmZmZmZmZiZiZmYiZmYmYiZiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiI//iPj4+Pj/////iP////+ZmZmZmZmJmZmZmZiZmImYmYmYiZiJiJiIiIiIiIiIiIiIiIiIiIiIiIiPiI//iPiI//j/////iP////+ZmZmZmZmZmYmZmYmZiImYmZmImZiJiIiJiIiIiIiIiIiIiIiIiIiIiIiPiI/4iPiI/2hm////iP+P//+ZmZmZmZmZmJmYmYmZiJmImZmImYiZiIiJiIiIiIiIiIiIiIiIiIiIiIiP/4+IiPiI/2b2////+P+P//+ZmZmZmZmYmZmZmYmYiZiImZmJmYiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4/4+PiIb2b2///4+P+P//+ZmZmZmZmZiZmJmZmYiZiJmJmJmYmIiIiYiIiIiIiIiIiIiIiIiIiIiIj4j4j4+P/4b2b////4+P+P//+ZmZmZmZmJmZmZmZmYmZiJmJmJmImIiIiIiIiIiIiIiIiIiIiIiIiIiIj4j4j4////Zmb///////+P//+ZmZmZmZmZmZiZmJmJmYiZmZmJmJmIiIiIiIiIiIiIiIiIiIiIiIiIiIj4j4j4//9vZvb///j/+P+P//+ZmZmZmZmZlpmZmZmJmYiZiJmZiJmIiIiIiIiIiIiIiIiIiIiIiIiIiPj4j4j4+P9mZvb///j///9vZmaZmZmZmZmZmYmZiZmZmImYiJmZiJmIiIiIiIiIiIiIiIiIiIiIiIiIiPj4/4j4+G9mZvb///j//29mZmaZmZmZmZmZmZmZiZmZmImYiZiZiZmJiIiIiIiIiIiIiIiIiIiIiIiIiPj4/4j4+GZmZvb//2b/aGZmZmaZmZmZmZmZmZmYmZiZiZmYiZiZiZiJiIiIiIiIiIiIiIiIiIiIiIiIiPj4j4j4b2ZmZvb/b2ZmZmZmZmaZmZmZmZmZmZmZmZiZiZmImYiZiZiZiIiIiIiIiIiIiIiIiIiIiIiIiPj4j4j4b2ZmZvZvZmZmZmZmZmaZmZmZmZmZmZmJmZiZiZiImYiZmZiZiIiIiIiIiIiIiIiIiIiIiIiIiPj4j4j4ZmZmVVVlZmZmZmZmZmaZmZmZmZmZmZmZmZiZiZiJmYmZmYiZiYmIiIiIiIiIiIiIiIiIiIiIiPj4j4j/ZmZmVVVVZmZmZmZmZmaZmZmZmZmZmZmZmImYiZiJmImYmZmZmYmIiIiIiIiIiIiIiIiIiIiIiPj/b2ZvZmZmZmZmZmZmZmZmZmaZmZmZmZmZmZmZmYmZmYiZmImYmZmZmYmIiImIiIiIiIiIiIiIiIiIiP9mZmZmZmZmZmZmVmVmZmZmZmaZmZmZmZmZmZmZmZmYmYiZmJmIiZiZmYmIiImIiIiIiIiIiIiIiIiIb2ZmZmZmZmZmZmZmVWVmZmZmZmaZmZmZmZmZmZmZmZmImYiZiZmIiZiZiJmIiIiIiIiIiIiIiIiIiIiIZmZmZlZVZmZmZlVmZmZmZmZmZmaZmZmZmZmZmZmZmZmJmYmYiZmJmYiZiIiIiJiIiIiIiIiIiIiIiIj4ZmZmZlVVVVVVZVVpZmZmZmZmZmaZmZmZmZmZmZmZmJmJmImYiZmJmIiZiImIiJiIiIiIiIiIiIiIiIj4ZmZmZmZVZlZllZlZVWVmZmZmZmaZmZmZmZmZmZmZiZmZmJmYmZiJmImZiYmIiIiIiIiIiIiIiIiIiIj4ZmZmZmZmZmZmZplVVWZmZmZmZmaZmZmZmZmZmZmZiZmZmJmImZiZmImYiZiIiIiIiIiIiIiIiIiIiIj4ZmZmZmZmZmZmZplpZmZmZmZmZmaZmZmZmZmZmZmZmZiZiJmJmZmZiImYiZiIiIiJiIiIiIiIiIiIiIhoZv//b8bMbGZmZplpZmZmZmZmZmaZmZmZmZmZmZmZmZiZiZmJmYmZiJmIiZiIiIiJiIiIiIiIiIiI+P//9v9vZszMzMxmlplpzMzMZmZsZmaZmZmZmZmZmZmZmZmZiJmJmYmZiZmImZiJiIiJiIiIiIiIiIiIb2Zm9m9mZszLzMxslpnGzLvLbMzMzGaZmZmZmZmZmZmZmZmZiZiZmJmZiZiJmIiJiIiYiIiIiIiIiIhoZmZmZmZmZry7zMzMZsy8u7vLzMzMzGyZmZmZmZmZmZmZmZmZiZiZmJmYiZiJmIiZiIiYiIiIiIiIiIhvZmZmZmZmZry7zMzMzMu8u7vMzMzMzMyZmZmZmZmZmZmZmZmZmYiZmZmYmZmJmJmZiIiYiIiIiIiIiPhmZv//b/ZmZsbMu8zMvLu8y8zMzMzMzMyZmZmZmZmZmZmZmZmZmYiZiZmZmZmZiJmZiIiYiIiIiIiIiPhv//+P/29mZmZmu8zMvLvMzMzMxszMzMyZmZmZmZmZmZmZmZmZmYiZmZmJmZmZiImYiYiIiIiIiIiIiIj/j4j4/2ZmZmbGzMzMzMzMbMxsZszMzMyZmZmZmZmZmZmZmZmZmYiYmZmJmZmZiYmYiYiIiIiIiIiIiIiPiPj//2ZmZmbMzMzMzMzMbGZmZmbMzMyZmZmZmZmZmZmZmZmZmYmYmZmZmZmZmYmYiYiIiIiIiIiIiIiIiP//b2ZmZma8y8zMzMzMZmZmZmbGzMyZmZmZmZmZmZmZmZmZmYiImZmZmJmZmZmYiIiIiIiIiIiIiIiI+P//aGZmZma8y8zMzGxGRGZmZmZmzMyZmZmZmZmZmZmZmZmZmYmImZmZmJmZiZmIiIiIiIiIiIiIiIj4/4//b2ZmZmbGzMzMZmZERGRmZmZmzMyZmZmZmZmZmZmZmZmZmZmIiZmZmZmZiJmIiYiIiIiIiIiIiIj//4j4j2hmZmbGzMxmZmZERERkZmZmzMyZmZmZmZmZmZmZmZmZmZmYmZmZmZmZiZiIiYiIiIiIiIiIiPj/iIj4/2ZmZmZmZmZmZiZCREREZmbGzMyZmZmZmZmZmZmZmZmZiZmYmZmZmYmZiZiJiYiIiIiIiIiIiPj/iIiIb2ZmhmZmZmb2ZiRCREJEZLa7zMyZmZmZmZmZmZmZmZmZmZmYmZmZmYmYiZiJiYiIiIiIiIiIiPj/j4j/b2ZvZmZmZmb2ZkREREJEZLu7zMyZmZmZmZmZmZmZmZmZmZmZmZmZmYmYmYiJmIiIiIiIiIiIiIj4j4j/ZmaGZmZmZmZmRiREQkREvLvLzMyZmZmZmZmZmZmZmZmZmZiZmYmZmZmImYiJmIiIiIiIiIiIiIiI/4hvZmZmZmhmZmZmJiIikkTEu7vMzMyZmZmZmZmZmZmZmZmZmZiJmZmZmZmImYiJmIiImIiIiIiIiIiI/4hmZmZmhmZmZmZmJiJCRJS8u8zMzMyZmZmZmZmZmZmZmZmZmZiJmZmZmZmImImJmIiImIiIiIiIiGZmZmZmZmZmhmZmZmZmRkQkRES8u8zMzGyZmZmZmZmZmZmZmZmZmZmJmZmZmZmJmYmYmIiIiIiIiIiIaGZmZmZmZmZmZmZmZmZmRkQkRES8y8zMzMyZmZmZmZmZmZmZmZmZmZmJmZmZmZmJmYmYiIiIiImIiIiIiGZmZmZmZmZmZmZmZmZmRkRERES8u8zMzMyZmZmZmZmZmZmZmZmZmYmJmZmZmZmJmZmYiIiIiImIiIiIiIhoZmZmZmZmZmZmZmZmZkRERGS8y8zMzMyZmZmZmZmZmZmZmZmZmYmZmZmZmZmJmZmIiIiIiImIiIiIiIiI/4+IZmZmZmZmZmZmZmZmZmbGzMzMzMyZmZmZmZmZmZmZmZmZmYmZmZiZmZmZmZmIiIiIiIiIiIiIiIiI+I9mZmZmlpmZaWZmZmZmZmhmzMzMzMyZmZmZmZmZmZmZmZmZmZmZmZiZmYmZmZmImYiIiIiIiIiIiIj4/29mb2ZmlpmZmWZmZmZmZmZmzMzMzMyZmZmZmZmZmZmZmZmZmZmZmZiZmYmZiZmJmYiIiJiIiIiIiIj//2b/ZmZmZpaZmWZmZmZmZmZozMzMzMyZmZmZmZmZmZmZmZmZmZmYmYiZmYmZiZmZmYiIiJiIiIiIiIj//2aGZmZmZmaZmWlmZmZmZoZmxszMzMyZmZmZmZmZmZmZmZmZmZmYmYiZmYmZiZmZmYiIiJiIiP//j2ZmZmb2ZmZmZmaZmWZmZmZmZmZmZszMzMyZmZmZmZmZmZmZmZmZmJmYmYiZmYmZmZmJmYiIiIiI+P9vZmZmZmb2ZmhmZmZZVWVmZmZmZmZmZsbMzMyZmZmZmZmZmZmZmZmZmZmYmYiZmYmZmZmJmIiIiIiI+P9mZmZmZmZmZmZmZlVVVVVVZmZmZmZmZmbMzMyZmZmZmZmZmZmZmZmZmZmYmYmZmYmYmYiJmYiIiIiI+PhvZvZvZmZmtrtsZlVmZmZVVWVmZmZmZmZmxsyZmZmZmZmZmZmZmZmZmZmJmYmZiYmYmYiJmYiIiIiI+P//j/9mZmZmu7vLZmZmZmZmV1VVVWVmZmZmZsyZmZmZmZmZmZmZmZmZmZmZmYmYmYmZmYiJmYiIiIiI+P////9mZmbGu8vMbGZmZmZmZmZWVWZmZmZmZsyZmZmZmZmZmZmZmZmZmZmZmYmYmYmZmYiJmYiIiIiIiP///29mZma2y8zMbGZmZmZmZmZmZmZmzGxmZsyZmZmZmZmZmZmZmZmZmZmZmYmYmYmZmYiJmYiImIiIiP///29mZma2u8zMzGZmZmZmZmZmZmbGzMxmxsyZmZmZmZmZmZmZmZmZmZmZmYmYmYmJmYiJmYiImIiIiIj/b2ZmZma2y8zMzGxmZmZmZmZmZmbGzMzMzMyZmZmZmZmZmZmZmZmZmZmZmYmYmZmJmImImYiImIiIiPj/b2ZmZmZmzMzMzMxsZmZmZmZmZpnMu8zMzMyZmZmZmZmZmZmZmZmZmZmZmYmYmZmJmImIiYiImIiI+P//aGZmZkRmZszMzMzMiGZmZmZmZpnMu8zMzMyZmZmZmZmZmZmZmZmZmZmZmYmYmZmJmImIiYiImPj///9vZmZmRERkZsbMzMzMZmZmZmZmZpa8u8zMzMyZmZmZmZmZmZmZmZmZmZmZmYmYmZmZmImIiYiImP////9mZmZmRETEzMbMzMzMZmbMzMzMzMy8u8zMzMyZmZmZmZmZmZmZmZmZmZmZmYmYmZmIiImIiYj/n////2hmZkREJCJEu7vMzMzMzMzMzMzMzMy8u8zMzMyZmZmZmZmZmZmZmZmZmZmZmYmYmZmIiImIiYj/b/j/j2ZmRkREJES0u7vMzMzMzMzMzMzMzMy7zMzMzMyZmZmZmZmZmZmZmZmZmZmJmYmYmZmIiImZiYj///9oZmZmRkQiIkRExMzMzMzMzMzMzMzMzMy7y8zMzMyZmZmZmZmZmZmZmZmZmZmImYmYmYmIiYiZifiP+GZmZmZmRkQiQkRExMzMzMzMzMzMzGZcVVW1y8zMzMyZmZmZmZmZmZmZmZmZmZmImYmYmYmIiYiZifiPZmZmZmZmZkQiIkRExMy7y8xVVVVsVlVVVVVVZsbMzMyZmZmZmZmZmZmZmZmZmZmImYmYmYmZiYiZifhmZmZmZmZmZklEQkRExFVVVVVVVVVVVVVmZmZmZmbMzMyZmZmZmZmZmZmZmZmZmZmImYmYmYmZiZiZiW9mZmZmZmZmZkREIkREzFtVVVVmzMxWZWZmZma2bGbGzMyZmZmZmZmZmZmZmZmZmZmImYmYmYmZiZiZiW9mZmZmZmZmZkREImZmtrtsZmZmZmZmZmZmZmZmxmxmzMyZmZmZmZmZmZmZmZmZmZmImZmYmYmZiZiZiW9mZmZmZmZmZkREZGZmxrvMzGxVZmZmZmZmZmZmZmZmZsyZmZmZmZmZmZmZmZmZmZmImZmYmYmZiZiZ+WZohmZmZmZmZkREZGZmZszMzFVVZmZmZmZmZrZrZmZmZsyZmZmZmZmZmZmZmZmZmZmImZmYmZmZiZiZ+WZmZmZmZmZmZkZEZmZmZsbMVlVmZmZmZmZmZsbLzMzMzMyZmZmZmZmZmZmZmZmZmZmImZmYmZmZmZiZ+WhmZoZoZmZmZmZmZmaGaGZmWGZmiGZmZmZmZsbMzMzMzIg=\",\n   \"sky\":\"hwSgAHgAAACZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR0d3d3ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRnR3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGdHdEREREd2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEd0REREREd2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZ3R0REREREd2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnR3RERERER0R2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRnRHRERERER0R2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRndEREREdHd3RGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdEdEREREdHdHRGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGdEdERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGdERERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEd0RERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEd0RERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEd0RERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEd0RERERERER0d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZER0RERERERHR3d2dmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEd0REREREdHd3RHdmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGd0REREREd0dERHdmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGd0RERER0d0RERHdmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGd0RERER3R0REdEdmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGd0RERER3REREd3RnZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdERERER3RERERHR3ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdEdERER3RERERER3Z2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdEdERER3RERERER0Z2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRndERER0R0REREREd2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRndHRER0R0REREREdFVVVVVVVVVVZSZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkR3REREd0RERFRVVVVVVVVRERUVfKdmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3REREd0REVVVVUVEREREREREJPLvmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd0dEREREdFdVVVFREREREREREREIpnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d0REREREVVVVUREREREREREREQkkpnpnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3RERERERVVVFREREREREREREREQimZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERERFVVURERERERERERERERCSSmZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZndEREREVFVRERERERERERERERERCSSmZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZndERERUVVERERERERERERERERERCKSmZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdkdERERVUVEREREREREREREREREJCKSmZmZ7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdEdERFRVUREREREREREREREREREJCKSmZmZ7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd0RERFVRUREREREREREREREREREIiKSmZmZ7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd0REVFFREREREREREREREREREREIiKSmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGd0REVVEREREREREREREREREREREIiIimZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGR0RUUVEREREREREREREREREREQkIiIimZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGR0RVUREREREREREREREREREJCIiIiIimZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGR1RVURERERERERERERERCIiIiIiIiIikpmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGR1RRUREREREREREREQkIiIiREREIiIikpmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGd1VRERERERERERERCIiIkREREREIiIikpmZ6Z6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGVFFREREREREREREIiJCREREREREIiIi4pmZ6Z6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGVFFRERERERERCQiIkREREREREREIiIi7p6ZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVEREREREREJCJCREREREREREREIiIimZ6ZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVEREREREREIkJEREREREREREREIiIimZ6ZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWUVEREREREQiQkREREREREREREREJCIimemZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWURERERERCIiREREREREREREREREJCKSmemZme6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZVUREREREJCJEREREREREREREREREJCKSmemZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZVUREREREIkJEREREREREREREREREJCKZmZmememZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZRUREREQkQkRERERERERERERERERERCKZmZmememZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZRURERCQiRERERERERERERERERERERCKZmZnpmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZRERERCJCRERERERERERERERERERERCKZmZnpmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlVREREJCJERERERERERERERERERERERCSZmZnpnumemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlVREREIkJERERERERERERERERERERERESZmZmZnpmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlVREQkIkRERERERERERERERERERERERESUmZmZnpmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVlFREQkQkRERERERERERERERERERERERESUmZmZ6ZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVlFREQiREREREREREREREREREREREREREREmZmZ6ZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVlFRCRCREREREREREREREREREREREREREREkZmZ6ZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVERCJERERERERERFRVVVVVVVVVVVVVRURElJmZ6Z7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVEJCJERERERERVVVVVVVVVRERVVVVVVVVFRJmZmZ7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVEJEJEREREVFVVVURERERERERERERERFVVRZmZme7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVEIkRERERVVVVERERERERERERERERERERERf6VmenpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVUkQkREVFVVRERERERERERERERERERERERERP/umenpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmUUkQkRUVUVERERERERERERERERERERERERE1JmZ7umenpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmUUiRFRVRUREREREREREREREREREREREREQU0Z2Z6Z7unpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWUUiVFVFREREREREREREREREREREREREREQR0Z2Zme7pnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWSVSVUVERERERERERERERERERERERERERBER0ZmZmZnunpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmUVSRUREREREREREREREREREREREREREJBER0ZmZmZnp7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVVREREREREREREREREREREREREREREJBER0ZmZmZmZ7p6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVEREREREREREREREREREREREREREREIhER3ZmZmZnu7p6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVUiREREREREREREREREREREREREREQkIhER3ZmZmeme6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVQiQkREREREREREREREREREREREREQkIhER3ZmZmZ6Z7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSQlIkREREREREREREREREREREREREQiIhER3ZmZ6ZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJFIkJEREREREREREREREREREREREQiIhIR3ZmZnpmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJVRCJEREREREREREREREREREREREQiIhIRnZnpmZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJVRCQiREREREREREREREREREREREQiIhIRnZmemZnpnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJURUQiQkRERERERERERERERERERCQiIhLRnemZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJURUREIiJERERERERERERERERERCQiIhLR7ZWZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJEVUREJCIiRERERERERERERERERCQiIiLRnpmZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJEVUREREQiIkJERERERERERERERCQiIiLunZmZmZnumZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlEVEVEREREIiIiRERERERERERERCQiIiLfnZmZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRFVERERERCQiIkJERERERERERCQiIhLRnZmZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRFVEREREREREIiIiQkRERERERCQiIhHRnZmZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRFRFREREREREREQiIiIiQkRERCQiIhHRnZmZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRERVRERERERERERERCIiIiIiQiQiIhHRnZmZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRERVRURERERERERERERERCQiIiIiIhER3ZmZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkiRERURURERERERERERERERERERCIiIhERkZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkiREREVURERERERERERERERERERCQiEhERkZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkiREREVEVEREREREREREREREREREQiEhERkZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkpQkREVFVEREREREREREREREREREQiEhEREZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkpQkRERFVFREREREREREREREREREQiEhEREZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZIkRERFRVREREREREREREREREREQiEhEREZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZIkRERERURUREREREREREREREREQkEhEREZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZKUJEREREVUREREREREREREREREQkEhEREZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJEREREVEVEREREREREREREREREIhEREZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJERERERFVFREREREREREREREREIhEREZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRERERFRVREREREREREREREREJBEREZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRERERERUVUREREREREREREREJBIREZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkiREREREREVUVEREREREREREREJBIREZGZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZktQkREREREVFVFRERERERERERERETR3d2dnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZktQkRERERERFRVRURERERERERERETUHdHdnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRIkRERERERERUVUVEREREREREREREERHtnZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRIUJEREREREREVFVVREREREREREREERHhnZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRESJERERERERERFRVVUVEREREREREFBHu3ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRES1CREREREREREREVFVVRURERERERBHu3ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREd0iREJERERERERERERVVVVFRERERBTu35mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREhIkJERERERERERERERFVVVUVERETx35mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRERHRIkIkREREREREREREREREVVVVVUUi0Z2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRERHdESIiRERERERERERERERERERVVSUi0Z2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREdEdESkiQkRERERERERERERERERERCIU0Z2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREd0dEZkpIiIiREREREREREREREREJEIR0Z2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZ0d0REZmZKSJCJCJEREJEREREREREIhQREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZ0R0REZmZmSkiIkJEJCJEREREREQkQhEREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZ3REREZmZmZkpIiIiIkQkIkREREQiFBERkZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZ3RERkZmZmZmZmSIiIiIiQiQiQiRCERERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdIiIiIiIiRCQSERGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdEREhIiIiIiIUERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdEREREREiItIREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdEREREREREd0REZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdEREREREREd0REZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdERERERERER0REZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdERHRERER0R0REZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmRndEdHdHRERER0REZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmZkREd0d3REREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmZkR0R0R3REREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRERkZmZmZmZmZkZ0R0R3REREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRERkZmZmZmZmZkZERER3REREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRERkZmZmZmZmZkZERER3REREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRERkZmZmZmZmZkZERER3REREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRERkZmZmZmZmZkZERHRHREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRnRHRERkZmZmZmZmZmZERHRHREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRnRERERkZmZmZmZmZmZERHdEREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkRERERkZmZmZmZmZmZGRHdEREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkRERERkZmZmZmZmZmZGREdEREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREd0dkZmZmZmZmZmZGdEdEREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkR0d3dkZmZmZmZmZmZmdEdEREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkR3RHdkZmZmZmZmZmZmdEdEREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRHRkZmZmZmZmZmZmdEREREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRERkZmZmZmZmZmZmdEREREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRHRERkZmZmZmZmZmZmdEREREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRHRERkZmZmZmZmZmZmd0REREREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR3RERkZmZmZmZmZmZmd0RERERERERkZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR3RERmZmZmZmZmZmZmdERERERERERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR3RERmZmZmZmZmZmZmdERERERERGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR3RGRmZmZmZmZmZmZmdERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR3RGZmZmZmZmZmZmZmdEdEREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRERGZmZmZmZmZmZmZmdkdERERkZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREZGZmZmZmZmZmZmZmZndERERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREZmZmZmZmZmZmZmZmZndHRERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZkZmZmZmZmZmZmZmZmZnZ3RGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3ZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZk=\",\n   \"castle\":\"hwSgAHgAAACZmZmZmZmZmWlpZpmZmWZmZrtLREREREREREZERO/b7//////fu7u7y828u7u7zN27u7u7zMy7vL3b3dSZmZmZmZmZmZmZmZmZmWZmZmZLRERERERERDRERP/+///////fvbu7y727u7vb3by7u7u7zMzM3L3U1N2ZmZmZmZmZmZlpmZmZmWZmZmZGS0RERERERERERP/////////Pvbu7vLu7u7u7zbu7u7u7zMzM3Ovb3d2ZmZmZmZmZmZmZmZmZmWlmZmZLRkRERERERERE5O7////////P3bvL3Lu7u8y9y7u7u7vLzMzM3OvU3d2ZmZmZmZmZmWmZmZmZmWlmZmZmS7RERERERNTd6/7////////P383L3LvMu9y8zLu7u7vLzMzM3O0z3d2ZmZmZmZmZmZmZlpmZaWZmZmZmRGRGZEZERNTt7v//////////vMvL3LvMu9u7vLu7u7vLzMzMzE3d292ZmZmZmZmZmZmZmZmZaWZmZma7u2ZmRGRERNTt7+/+////////u8vL3LzMy9u7zLu7u7vLzMzMvLTd3d2ZmZmZmZmZmZmZmZmZmWZmZma7RLRrRERERN3d/t/9////////z8vLvLzMy9u7zLvMu7vLzMzMvETU3d2ZmZmZmZmZmZmZmZmWmWZmZrtGS0RERETU3d3r7u///////////8vMu7vMy9y7y7vMy7u7zMzMvEvU3dSZmZmZmZmZmZmZmZmWaWZmZmZERERERETU3d206+7////////8/8y8u7vMy7y7u7u8u7u7zMvMvETd3d2ZmZmZmZmZmZmZmZlpmWZmZrtLS0RERETU3dPd7v7//////////8zMu7vMy7y7u7u7u7u7zMvMvERL3USZmZmZmZmZmZmZmZmZaWZmZmZrRkRERERE3d1N5P7//////////8zMu7vMy7y7u7u7u7u7zMvMu0vU3USZmZmZmZmZmZmZmZmZZpZmZrtGS0RERERE3d1N3f7/////////z8zMu7u8y7y7u8u8u7u7y7vMu0Td3USZmZmZmZmZmZmZmZmZZplmZrZERERE//9E3UQ9RP7/////////z8zMvLu8u8y7u8u7u7u7y7vMu0Td3d2ZmZmZmZmZmZmZmZmZmZlmZmZLRGRGRP//3dRN6///////////z7zLzLu8u8y7u8u7u7u7y8zMS0Td3d2ZmZmZmZmZmZmZmZlmmWlmZmZrRGRGRNTzT93tTv//////////zLzLzLu8u8y7u8u7u7u7y8zMS9Td3dSZmZmZmZmZmZmZmZlpmWZmZra2RGRGRNRL/f//////////////zLvMzLu7u8y7u8u7u7u7y8zMS9RN3d2ZmZmZmZmZaZaZmZmZZmZmZmZmS0Rk1P/////9///////////PzMzMzLu7u8y7u8u7u7u7y8y8u0RERN2ZmZmZmZmZaZmZmZmZmWlm3d29ZGZERN80REb9RP7////////PzMzMy7y7u8u7u8u7u7u7y8y8S9vd3TSZmZmZmZmZmZlpmWlplplmvcvLS0tERDQ09P/fRP/////////MzMu8u8y7u8u7u8u7u7u7y8y8uzTU3d2ZmZmZmZmZmZmZaZlplmm2vcvLzExkRkv//9/dRP///////8/MzMy8zMy7u8u7u8y7u7u7y8y8uzTU3d2ZmZmZmZmZmZmZmZlmmWmZu8u7vMxERkT/RNRERP7////Pv8vMzMy7zMu8u8u8u8y8u7u7u8y8u9Td3d2ZmZmZmZmZmZmZmZmWmZlmu8u7vMvM3d3Nu8vMzMzMzMzMzLy8u8y8y7u7u8u8vMy8u7u728y8S9tN1N2ZmZmZmZmZmZmZaZmZlpmZ+7+7vLzMvby7u7vMzMzMzMzMzLvMu8y8y7zMu8vMzMy8u7u728y8S9Td3d2ZmZmZmZmWaZmZmZmZlpmZ2fu7vLzMu8y7vLu7y7u7u8vMvLvMy8zMy7zMy8vMzMy8u7u728y7u9Td3d2ZmZmZmZlmZpmZmZmZaZmZvcvLvLvMu7u7vMy8zMu8y8zMvLvLvMvMzLy8y8zLzMy8u7u728y7u9Td3d2ZmZmZmZlmlpmZmZmZmZmWvcu7vLvMy7y7u7u7u8u8u7y7y7y7vMvMzMy8y7zLzLu8u7u727y7S9Td3d2ZmZmZmZmZmZlpmZmZmZaZ3cvLzLzMy7y7u7u7u7u7u7u7y8u8zMvMvMy8y7zMzLu7u7u7y7y7u9Td3d2ZmZmZmZmZmZmZmZmZmWmZvcvLvLzMu7vMu8zMzMy7y7y7vMvMy8vMzMy7y7zMzLu7u7u7zby7S9Pd3d2ZmZmZmZmZlpmZmZmZmWlptsvLvLvMu7vLy8zMzMy7zLy7vLu7y8vMzMy7y7zMzLvMu7u7zby7u9Td3d2ZmZmZmZmZmWmWmZmZmZmZubu7vLvMu8y7y7zMzMy7zLu7u8u8u8vMvMy8zLzMvMvMu7u7zby7u+Tb3d2ZmZmZmZmZmWmWmZmZmZmZuba7vMvMu7y7y8zMzMy7u7vMu7u8u8vMzMy8zMzMvMzMu7u7y7y7S0Td3d2ZmZmZmZmZmWmWZpmZmZmZvcvLvMzMzLzLvMzMzMy7u7vLvLu7u8vMu8u8zMzMvMy8u7u7y7y7S93U3U2ZmZmZmZmZmWmWZpmZmZmZvcvMvMzdu7vLvLu7u7vMu7vLvLu8y8zMy8zMzMzMvMy7u7u7y7zrTt3d3d2ZmZmZmZmZmZmZub2ZmZm5u8u7zEzdy8y7u7u7u7vMu8u8u8u8zMvMy8zMzMzMvMy7u7u7y7zLTt3d3d2ZmZmZmZmZmZlm3cuZmZlpubvLvPS9zMzMu7y7vLu8u8y7u8u8vMy7y8zMzLzMu8zMy7y7y7vM3N3d3d2ZmZmZmZmZmcndvMvMu7uZa0ZERP+9zETMu8zLvLy7u8u7u7u7u8y7y8zMzLzMy8zMy7u7y7vM3N3d3d2ZmZmZmZmZ2d3MvMzMu8tsS0RERE+7zMS7u7zLu7y7y8zMzMzMzLzMy8zMzMzMy7zMy7u7u7vMS93dTd2ZmZmZmZnZ3cvLvMy8zMu8uUtES2S7zMy7u7vLu7vMzMzMzMzMzLzMy8zMzLzMy7zMy7u7u7u8S93d092ZmZmZmd29y8zLvMy8u8vMzLu7zMzMzMy7u7vLu8zMzMzMzMzMzLzMy8zMzMzMy8y8y7u7u8u83d3d3d2ZmZmZ3b3Mu7zLu8y8u8zMzLu8y8zMzLvMy7zLy8y7u7u7u7u7u7vMy8zMzMzMzMy8y7u7u8vcRNTd3d2ZmZmZzczMzMzMu8y8vMzMu8u8u7u7y7u7y7y7zMzMzMzMzMzMzLzMy8y8zMzMzMy8y7u7u8u7S93d3d2ZmZmZubvMzLzLu8y8vMzMu7u7u7y7y8u8u7vLvLu7u7u7u7u7u7vMy8y7zMzMzMy8y7u7u8y73d3d3d2ZmZmZmbnMy8zLu8y8u8vMu8u7u7y7u8u8u7vLzMzMzMzMzMzMzLzMy8y7zMzMzMy8y7u7u8y73d3d3d2ZmZmZmZm5u8vLvMzMu8vMu8u7u7u7u7u7y7zMu7u7u7u7u7u7u7vMy8zLzMzMzMy8y7y7u8y7u93d3d2ZmZmZmZmZucvMvMzMu8vMy7zMzMzMy7u7y7zMzMzMzMzMzMzMzLzMy8zLzMzMzMy8y7y7u7y7S93d3d2ZmZmZmZmZmcnMvMvMu8u8z8zMzMzMzMzMy7vMu7u7u7u7u7u7u7vMy8zLzMzMzMzMy7y7y7y73d3d3d2ZmZmZmZmZmWm7vMvMu7tp27vLzERE3by7u7vLzMzMzMzMzMzMzLzMy8zMzMzMzMzMy7y7y7y7O93d3d2ZmZmZmZmZmZmZu7tmZmb227vLTERENL27u7u7zLy7u7u7u7u7u7vLu8vMzMzMzMzMzLy7y7y7u93d3d2ZmZmZmZmZmZmZtrtmZmZm3bzMRES01MzLu8y7y8zMzMzMzMzMzMzMzMy8zMzMzLzMzLy7y7u7293d1N2ZmZmZmZmZmZmZmWZmZmZmvbvM+0+03czLvMy7u8zMzMzMzMzMzMzMzMzMzMzMy8zMzLu7zMu7093d1N2ZmZmZmZmZaZlpZmZmZmZmvbvMRE9E3czMvMy7y7y7y8zMzMzMzMzMzMzMzLzMvMzMzLu7zMy7293dRN2ZmZmZmZmZlpmZZmZmZmZmvczLTETdT8y7u7u7y8y7u7u7y8u7u7vMzMzMzMzMvMzMzLu7zMy71N3d3d2ZmZmZmZmZmdnd3W1mZmZmu7vL7LT//8zLu8u8u7u7u8u7zMy8u7vLzMzMzMzMvMzMzLu7zMy71N3d3d2ZmZmZmZmZmdnLu7zLZmZmtru7zNzd/czLu8u8u7vMu8u7zMu7y8zLzMzMzMzMvMzMzLu7vMy71N3d3d2ZmZmZmZmWmdnLzMzMa2Zmtry7u7y7u8zMvMzMzLzLu7u7u7u7u7vMzMzMzMzMvMzMzLu7vMy73d3d3d2ZmZmZmZmZmdnNy7zMu93Ntsy8u7u7u8zLy8zMzMzLvLvLvLu7u7vLzMzMy8zMvMzMzLvLvLy73dTd3d2ZmZmZmZmZmdm7u7u7y8zMy8zMy8zMzMy7y7zMzMzLvLzLvLu8u7vLzMzMy8zLvMzMzLvLzLy73d3d3d2ZmZmZmZmZmZmZmcu8zMy7u7u7u8vMzLzMy8zMzMy7u8zLvMu8u8vMvMvMy8zLvMy8zLu7y7y7RN3U3d2ZmZmZmZmZmZnZ3c28y7y7vLu7vLu7y7vMu8zMzMy7u8y7u8u8u8vMvMzMy8zLvMy8zLu7y7y7RN091N2ZmZmZmZmZmWndvMy8y7y7vLu7u7u7y7y8u7u7u7u7zLu7u8u7u8vMzMzMy8zLzMy8zLu7y7y7RN3d3d2ZmZmZmZmZmZnNvLy8y7y8u8y7u8u8y8u8y7y8y8y7y7y7vLu7u8zMzMzMy8zLzMy8zLu7y7y7293d3d2ZmZmZmZmZmZnJvLu8zLzMu8zLvLu7y7u8zLy8vMy7u8y7vLu7u8zMzMzMy8zLzMy8zLu7y7u7293d3d2ZmZmZmZmZmZmZacvMzLzLu7vLvLu7u8u8u7vLvLu7zLvLvLu7zMzMzMy8zMzMzMy8zLu7y7u7293d3d2ZmZmZmZmZmZnZ3czMy8zLu7vLzMzMzMzMzMzMzMzLzLvLu7u7zMzMzMy8zMzMzMy8zLu7y7u700vd3d2ZmZmZmZmZmdndu7zMu8zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMy8zLu7zMu81N3d3d2ZmZmZmZmZmbnNvMzMu2Zmy0xERPRP1N3d3d3dTd3d/8zMzMzMzMzMzMzMzMzLzMy8zLu7u7u8RE1E3d2ZmZmZmZmZmbnLy7zLa2Zma7tERPRP1N3d1P3/Td3d/8/MzMzMzLzMzMzMzMzMzMy8zLu7u8vMS93d3d2ZmZmZmZmZmbm7y7zLZmZmZrtERET/1E3dTf//393d/f/PvMzMzMzMzMzMzMzMzMu8zLu7u8zM293d3d2ZmZmZmZmZaZlpZmZmZmZmtmZGRERP1D3d3f3d////////zMzMzMzMvMzMzMzMzMu7zLu7u8zM3d3d3d2ZmZmZmZmZmZlpZmZmZmZmtmtERERk1E1N3d3d///9////zLzMzMzMzMzMzMzMzMy7zLvLu8zL3U3d3d2ZmZmZmZmZmZmZmWaZZmZmtrRERGRmTdRN3d3d3d3d/f//zLvMzMzMzMzMvMzMzMzMvLvLu8zL293d3d2ZmZmZmZmZmZlpmWlmZmZmtrS0tkRE3d3d3d3d3d3d////z7y7zMzLzMzMzMzMzMzMu7vLu8zL293d3d2ZmZmZmZmZmZaZmWZmZmZmtrS0RkRE1N3d3d3d3d3d////z8y7y8y8zMzMzLzMzMzMu7vLu7y73N3d3d2ZmZmZmZmZmZmZmWaWZmZmtkZLRERGNN3d3d3d3U39///////MzMzLzMzMzMzMzMzMu7vLu7y7u93d3d2ZmZmZmZmZmZmZmZmWZmZmZkZLRERETfRP3d3d3f///////8/My8zMzMzMy7zMzMy8vLvLvLy7NN3d3d2ZmZmZmZmZmWmZmZaWaWZmZka0RERmS/3//////////////7/My8zMzMzMy7zMzMy7zLvLzLy7NN3d3d2ZmZmZmZmZmZaZmZaZaWZmZra7ZERENN3//////////////8/MzMzMzMzLzLzMzMy8zLvLzLy7293d3d2ZmZmZmZmZmZmZmZmZZmb2Zma2REZE9P///////////////8/MzMzMzMzLzLzMzMy8zLvLy7y7293d3d2ZmZmZmZmZmZlpmWlmlmb2/2/////////f3d3//////////8/LzMzMzMzMzLzMzMy8zLvMy7y7S9Td3d2ZmZmZmZmZmZmZaWaWZmZmZma2S0T0/9/d1N3d3d3////////MzMzMzLzMzLzLzMy8vLvMy7y7RNTd3d2ZmZmZmZmZmZmZaWaWaWZmlma2S0T0P9tN3d3d3d39///////PzMzMzMzMvLvMzMy8u7vMy7y7RN3d3d2ZmZmZmZmZmZmZmWlmmWZmZmZr9v9PRN3d3d3d3d3d///////PzMzMzMzLvMvMzMy8u8u8y7y7S9Td3d2ZmZmZmZmZmZmZmWlmZmZmZmb//09ERN3d3dTd3d3d///////PzMzMzMzMzMvMzMy8u8u8y7u720TU3d2ZmZmZmZmZmZmZmWlmZmZmZmZmtkRLRN3d3d3dTd3d/f/////My8zMzLzMzMzMzMy7u8u8y7u7003U3d2ZmZmZmZmZmZmZmZmZlmZmZmZmu0ZERP3/3d3dTdTd/f////+8y8zMzMzMzMzMzMy7u8y8y7u71N3d3d2ZmZmZmZmZmZmZmZaWZmZmZmZmu2u7tNT/393d3d1N/P////+8y8zMzMzMvMzMzMy7u8y8zLu7RN3d3d2ZmZmZmZmZmZmZmWaWZmZmZmZmu2tLtN3d///d3d3d/P/////Pz8y8zMzMzMzMzMy7u8y7y7u7RN3d3d2ZmZmZmZmZmZmZmZaZaWZmZmZmtru7a91N3f//3d27/f//////zMzLzMzMzMzMzMy7u8y7u7u7O93d3dSZmZmZmZmWmWlpmWaZaWZmZmZmtrtru9Pd3d3////////////Pu8zLzMzMzMvMzMy7u8y7u7u7RN3dTd2ZmZmZmZmZmZmZmZmWaWZmZmZmZkZr1t3d3f//////////////v8y7vMzMzMzMvMy7u8y7u7u7RNTd3d2ZmZmZmZmZmZmZmZmZZmZmZmZmZrZrSz3dTd/d3f//////////vLy7vMy8zMzMvMy7u8y7u7u7RNTd3d2ZmZmZmZmZmZmZmZmZZmZmZmZmZmZr1tvd3d3d3d39////////v7y7vMzMzMzMvMy7u8y7u7u7RN3d1N2ZmZmZmZmZmZmWmWmWmWZmZmZmZmZmlt3d3d3d3d3d/f//////z8y7zMzMzMzMvMy7u8y7u7u7RN3d3d2ZmZmZmZmZmZmZmWmWaWZmZmZmZrZmZt3d3d3d3d3d+////////7y7y8zMzMvMvMy7u7y7u7u7RN3d3d2ZmZmZmZmZmZmZmWmZaWZmZmZmZmZmZt3d3d3d3b3b/f///////8+8y8zMzMvMvMy7u7y7u7u7S93d3d2ZmZmZmZmZmZmZmZmWaWZmZmZmZma7RN3d3d3U3d3c/f///////8+8zMzMzMvMzLy7u7y7u7u7RN3d3d2ZmZmZmZmZmZmZmZaZmWZmZmZmZrb0T7vd3d3d/////////////7/MzMvMzMvMzLy7u7y7u7u769vd3d2WmZmZmZmZmZmZmZmZZmZmZmZmZmv/T93d3f3//////////////8/MzMvMvMu7zLy7y7y7u7u7Tt3d3d2WmZmZmZmZmZlpmZlpZmZmZmZm9v9vRNTU3f3f3d3d/f///////8/LvLu7y7y7zLy7y7y7u7u75NTd3d2WmZmZmZmZmZmZmWlmZmZmZmZm9rtERNTU3d3d3U3d9P///////8/LvLu7y7y7zLy7y7y7u7vLRN3d3d2WmZmZmZmZmZmZmZmZmZZmZmZm9ktkRNbU1t3d3d3d/////////8+7u7u7y7y7zLy7y7y7u7vLTt3d3d2WmZmZmZmZmZmZaZaZaWZmZmZm9r+01N3d293d3d39///////////LzLu7y7y7y7y7y7y7u7vM7NPd3d2WmZmZmZmZmZmZmZlpZmZmZmZmZv9P1N3d3d3d3d3///////////+7zLu7y7y7y7y7y7y7u7vMzN3d3d2ZmZmZmZmZmZmZmZmZlmZmZmZmZv////////////////////////+/y7y8y7y7y7y7y7y7u7vMvN3d3d2ZmZmZmZmZmZmZmZlplmZmZmZmZmb///////////////////////+8y8y8u8y7y7y7y7y7u7vMzNPd3d2ZmZmZmZmZmZmZmZmZaWZmZmZmZrZE//////////////////////+8y8y8y8u8y7y7y7y7u8vM7NTU3d2WmZmZmZmZmZmZmZmZaWZmZmZmZrb0//////////////////////+8y8y8y8u7y7y7y7y7u8vM7Nvd3d2ZmZmZmZmZmZmZmZmZaWZmZmZmZrb/T0Td//////////////////+8y8y8zMy7y7y7y7y8u8vM7DPdTd2ZmZmZmZmZmZmZaZmZmWZmZv////9vbWTd3d3d3f3///////////+8u8u7zMy7y7y7y8y8u8vLzNvd3d2ZmZmZmZmZmZmZaZmZmWZmZvZvZva2PdTd3d3d3d39///////////M28u7zLy7zLy7y8y8u8vLzNvd3d2ZmZmZmZmZmZmZmZmZmWZmZmZmZm9G201NRN3d3d3////////////Pvcu7zLy7zLy7y8y8u8vLzN3d3d2ZmZmZmZmZmZmZmZmZaWZmZmZm/2ZLS0RLRN3d///////////////Pu8y7y7zLzLy7u8y8u8vMzL3U3d2ZmZmZmZmZmZmZZpaZZmZmZmb2b2a7u0S0tN39///////////////Pu8y7y7zLzLy7u8y8u8zMvL3U3d2ZaZmZmZmZmZmZZpZplmlmZmZmZma21NtNRN3d3f3////////////Pu7y7y7vLzLy7u8y8u8zMzLxN1E2ZmZmZmZmZmZmZZplpaWZmZmZmZmZmRE3d1N3d3f//////////////zLy7zLvMzLy7u8y7u8zMzNzd3U2ZmZmZmZmZmZmZlplpZmZmZmZmZmZm1N3d3d3d3f//////////////z7y7zLvMy7y7u8y7u8zMzLzd3d2ZmZmZmZmZmZmZmZZplmZmZmZmtmZm293d3d3/////////////////zLy7u7vMy7y7u8y7u8zMzLzd3d2ZmZmZmZmZmZmZaZmZaWZmZmZmZmZmZt3d1N3d////////////////zLy7u7vMzLy7u8y7u8vMzNzd3d2ZmZmZmZmZlpmZZpaZaWZmZmZmZmZm293d3d3/////////////////zLu7u7vMzMy7u8y7u7vLzNzd3d2ZmZmZmZmZmZmZlmmZaWZmZmZmZmZm9v//3f3/////////////////z7y7u8u8zMy7u8y7u7vLzNvdTdSZmZmZmZmZmZlplpmZlmZmZmZmZmb/////////////////////////z7y7u8u8zMy7u8y7u7vLzLvd3d2ZmZmZmZmZmZlmmZmZmWZmZmZmZmZva9Td/f//////////////////vMzLu8y7zMu8u8y7u7vLzLzd3d2ZmZmZmZmZmZlpaZaZaWZmZmZmZmZmZpbW3f3////////////////Pu8zLu8y8u8u8u8y7u7vLzLzb3d2ZmZmZmZmZaZlmlmlmZmZmZmZmZmZma9bW3f3/////////////////u7vMu8y8u8u8u7u7u7vMzLzd3d2ZmZmZmZmZmZlmZpZpZmZmZmZmZma7a9nd3f/////////////////Pu7vMu8y8u7u8u7u7u7vMzLzb3d2ZmWmZmZmZmZmZmZmZaWb2ZmZmZmZG3d3d/f/////////////////Pu7vMvMzMu7u8u7u7u7vMzLzd3d2ZmZmZmZmZmZmZmZlpaWb2/2ZmZmZL+//////////////////////Mu7vMzMzMu7u8u7u7u7u7zMzd3d2ZaZmZmZmZmZmZmWmWZmZm/2ZmZru7vd39////////////////////u7vLzMzMu7vMu7u7u7u7zLzd3d2ZmZaZmZmZmZmZmZaWZmZm9m9mZkZkS/3//////////////////8/MvLu7zMzMu7vMu7u7u7u7zMzd3d2ZmZmZmZmZmZmZmZmZ////ZvZvtkZL8////////////////////8/MvMy7zMvMu7vMu7u7u7u7zMzb3d2ZmWmZmZmZmZmZmWn/b2b2/2b/v0T////////////////////////MzMy8zMzMu7u7u7u7u7u7zMzd3d2ZmZmZmZmZmZmZmWmfaWZm9m/////////////////////////PzP/MzMy8y8y7u8vMu7u7u7u7zLzb3d2ZmZmZmZmZmZmZlmlmZmZmZv/////////////////////////cvbzLzMy8y8y7u8vMu7u7u7vLzLw73d2ZmZmZmZmZmZmZmZmZZmZmZmZmZkT//////////////////8y9u7vLvMy8y8y8u8vMu7u7u7vLzLs93d2ZmZmZmZmZmZmZmZaZZmZmZmZmS/T//////////////////9y8u8y7u8u8u8y8u8vMu7u7u7vLvLtN3d2ZmZmZmZmZmZmZmZZpZmZmZmZma////////////////////7u7y7zLu8u8u8y8u8vMu7u7u7vLvLvd092ZmZmZmWmZlpmZmZZpZmb/Zma2////////////////////z7u7vLvLvMu8u8u8u8vMu7u7u7vLzLu9292ZmZmZmZmZmZmZaZZpZmb/////////////////////////z8y7zMzLvMvMu8u8u7vMvLu7u7vLzLtL3d2ZmZmZmZmZmWmZZpZmaWZmZv/2/////////////////////MzMzMzLvMvMu7vMu7vMvLu7u7vLzLvb1N2ZmZmZmZmZmZmZaZZpZmZm9m/2////////////////////zMzMzMzMvLvMu7vMu7vMvLu7u7u7zLs7Td2ZmZmZmZmZmWmZZpZpZmZmZmb////////////////////fzMzMzMzMvLvMu7vMu7vMu7u7u7u7zLvb3d2ZmZmZmZmZmZmWmWZmZmZmZvb///////////////////+/u8y7u8vMu7vLu7vLu7u8u7u7u7vLzLvbTd2ZmZmZmZmZmZlplmZmZmZmZv/////////////////////Mu7u7u7u7u7u7u7u7u7u8u7u7u7vLzLtLRN2ZmZmZmZmZmZlpmWlmZmZmZv/////////////////////MvLu7u7vLu7u7u7u7u7u8u7u7u7vLzLu73d2ZmZmZmZmZmZZpmWZmZmZm9v/////////////////////LvLu7u7vMu7u7u7u7u7vMvLu7u7vLzLu73d2ZmZmZmZmZmZZpmWZmZmZm9v///////////////////8/MvLu7u8y8u7u7u7u7u7vMvLu7u7vLzLvb3d2ZmZmZmZmZmZmZZmZmZmZm/////////////////////9+7y7u7y8y7u7u7y7u7u7vMu7u7u7vLy7tL3d2ZmZmZmZmZaZZpZmZmZmb2/////////////////////9y7y7vLzLu7y7vLzLy7u7vMu7u7u7vLy7xL1N2ZmZmZmZmZmWmWlmZmZmb2////////////////////z7+7y8zLu8u8zLzMy7y7u7vMu7u7u7vLy7y7RN2ZmZmZmWmZmZlpmWZmZmb/////////////////////z7y7y8y8zMzMvMzMu7u7u7vMu7u7u7vMy7w71ESZmZmZmZmZmZmZlmZmZvb/////////////////////38vMu8vMzMy7u8zMu7u7u7vMu7u7u7vMy7zb1N2ZmZmZmZmZlpaZZmZmZv//////////////////////v8zMvMvMzMy7u8vMy7y7u7vMu7u7y7zMy7zbRN2ZmZaZmZmZmZmZZmZm9v//////////////////////v8vMzMzLzLu7u8vMy7y7u7vMu7u7y7zMu7u7RN2ZmZaZaWZpmZlpZmZm9v//////////////////393Mu7vMzLzLzLu7u8vMzLy7u7vMu7u7zLvMu7u71N2ZaZaZmZaZmZmZZmZm///////////////////PzMzMu7u7u7u7y7y7vLvMzLu7u7vMu7u7zMy8u7vM3d2ZaWZmmZmWmZmZaWb2////////////////z8zMzMzMv7vLu7u7u8zLvLu7zLu7u7vMu7u7vMy8u7u83d2ZmWaZmZmZmZmZaWb2///////////////MzMzMzMzMvMvMvMy7u8zMvLu7y7u7u7vMu7vLzMy8u7u73d2ZmWaZmZmZZpaZaWb/////////////z8zMzMzMzMzMvMvMzMy8u7zMu7vLvLu7u7vMu7vLzMy8u7u73d2ZmZmZmWmZlmaZZmb/////////////zMzMzMzMzM/MzMvMzMzMzMy8u7vLzLy7u7vMu7vLzMy8u7u73d0=\",\n   \"castle2\":\"hwSgAHgAAAD///////////////z//////8/d3d3d3d3d3d3d3d3d27u7u9vd3b3d3dvd273MzMzMzMzMzMzM//////////zM/f/////P////////z8zd3d3d3d3d3d3d3b29u7u7u93b3d3b3d3d3b3MzMzMzMzMzMz8/P////////+//P/////P3/38/9/MvN3d3d3d3d3d3d3d3d27u7u7293d3b3d3d3d3b3My8zMzMzMzMz//////////////P//////3P///8y8u93d3d3d3d3d3d3d3d29u7u73d3b3d3d3d283d3Ly8zMzMzMzMzM/////////////P//////////z7zd3d3d3d3d3d3d3d3d3d29u7vb3d3d3d3b3d3d3d3dy8zMzMzMzMzM///////////////////b///Pu93d3d3d3d3d3d3d3d3d3d27u7vb3d3d3d3d3d3d3d3dy8zMzMzMzMzM////////z//7///P///P/M/b3d3d3d3d3d3d3d3d3d3d3d29u7vb3d293d3d3d3d3d29u8zMzMzMzMz////////M/P///9+9/8+/vcvd3d3d3d3d3d3d3d3d3d3d3du9u7vd3d3d3d3d3d3d3d3dzcvMzMzMzPz////////L/////9/939z/v9zb3d3d3d0dEd3d3d3d3d3d3du7u9vd3d3d3d3d3d3d3d3dvczMzMzMzMz////////8/9zL/c/N/M+8u93R3d3d0REREd0dEd3d3d3d3d27u9vd3d3d3b3d3d3d3d3dvczMzMzMzMz////////8/73/+//Lz9vd3R3R0REdERERERHR3d3d3d3d3b27u7vd3d3d3d3d3dzd3b3dvcvMzMzMzPz//////////9z////P3d3d3REREREREREREREREd3d3d3d3b27u7vd3d3d3d3dvd3d3d3d3bvMzMzMzPz//////////93////f3d3dEREREREREREREREREd3d3d3d3b27u7vb3d3b27vbzL3d3d3d3cvMzMzMzPz////////P/8///N/b3d0RERERERERERERERERu7vd3d3d3b27u7vb3d3dvbvb3d3d3d3d3bzMzMzMzPz/////////+////9zd3REREREREREREREREREREbu73d3d3bu7u7vb3d3bu7vb3d3d3d3d3cvMzMzMzMz/////////v/3/z9vdHREREREREREREREREREREd29293d3bu7u7vbu9u9u7vb3d3d3d3d3czMzMy8zP//////////3///3N3dERERERERERERERERERERERERsbu7u7u7u7vbu727u7vc3d3d3d3dvczMzMzMzP/////////////P3N0REREREREREREREREREREREbu7u7u9u7u7u7vbu9u7u7u83b3d3d3dy8zMzMzMzPz///////////3b3d0RERERERERERERERERERERERsRERG93b27u7u7u7u7u8vMvd3d3d3NzMzMzMzM/P///////////8zb3REREREREREREREREczMzBwRERERvbsb0b27u7u7u7u7y8y8293d3dvdzczMzMzMzP/////P//+//9zdHRERERERERERERERwczMzMwRERG7uxsdEb27u7u7u7vMzMzM29vd3d3dvczMzMzMzPz////////83d3dHRERERERERERERERwcwczMwcERG70R0R0b27u7u7u8zMzMzMzLzM3d3dzczMzMzM/8z////////f3d0dERER0RERERERERERwcwRzMzMzMzMzMzMzMzMvMzMzMzMzMzMvLvd3d3dzMzMzMzM/Nz/////3//b3d0dERERERERERERERERscvMzMzMzMzMzMzMzMzMzMzMzMzMzMzMvNvd3b3NzMzMzMzM/P/////////d3d0dEREREREREREREREREbHMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzLvd3d3NzMzMzMy8/P/////////d3R0RERERERERERERERERwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzd3dy9zMzMzMzMzP/////////d3R0RERERERERERERERERwcwcy8zMzMzMzMzMzMzMzMzMzMzMzMzMzLvd3cu7zMzMzMzby//////////d3RERERERERERERERERERwcwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzNvdvdu9zMzMzLzdvfz8///////dHRERERER0REREREREREREczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNvdu93NzMzMzLzd3cy////8///dHRERERERERERERERERERERHMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzL3b3NzMzMzLvd3f3M///8///dERERERERERERERERERERERHMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNu93d29zMzMzMvd3d38/9////8dEREREREREREREREREREREczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMvLvb2929y8zMvN3d3d3Ny/////8dERERERERERERERERERERwcwRzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNvb3d3LzMzMvN3d3d3d/P//z/8dERERERERERERERERERERwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN3b2927zMzMzLzb3d3d+////78dERERERERERERwcwRERERwczMzMy7y9HMzMzMzMzMzMzMzMzMzMzMzN3dvNu7zMzMzLvb3d3d+/////8RERERERERERERzMwRERERwczMzMG8zNHMzMzMzMzMzMzMzMzMzMzMvN29y7vMzMzMzMy73d3dzf////8RERERERERERHMzMzMzMwRERERHMvMzLHMzMzMzMzMzMzMzMzMzMzMvNu93b3LzMzMzLzb3d3d3bz///8REREREREREczMzMzMzMwcEREREcu7y83MzMzMzMzMzMzMzMzMzMzMu93b293MzMzMzLzd3d3dzf////8RERERERHMzMzMzMwcwczMEREREcG7zMHMzMzMzMzMzMzMzMzMzMzMvN3d293MzMzMzLzd3d3d/b////8RERERwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMu93d3b3MzMzMzLvb3d3d/f////8RERERzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN3d3c3MzMzMzLzb3d3d+///v78RERERzMzMzMzMzMwcwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMy8y9vd3c28zMzMzMzb293LzP////8RERERwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzc3b3d3b3LzMzMzMy73LzNu/////8REREREcHMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzd3d3Nu8vMzMzMzLy9u8y8zP3///8RERERERHBzMzMzMzczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzLvd3d3cvMzMzMzLy73Mzd/b/9//8RERERERERwczMzMwcwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNy93d293c3MzMzMzMzcvb29y8////8REREREREREcHMzMzMzMwcy8zMHBEREc3MzMzMzMzMzMzMzMzMzNu73d3d3b3MzMzMzMzc3d3du/39/P8RERERERERERHBzMzMzMwRzMzMEREREcHMzMzMzMzMzMzMzMzMzNvN3d3d3b3MzMzMzMy83d3dy7/8//8RERERERERERERzMwRERGxzLscERERER3LzMzMzMzMzMzMzMzMvN3d2929zc3MzMzMzMy83d3dzPz///8RERERERERERERzMwRERERzLscEREREdHMzMzMzMzMzMzMzMzMvL3dvd3d3bvMzMzMzMy83d3d+/////8RERERERERERERERERERERzMwcsRsREdHMzMzMzMzMzMzMzMzMu73d273cvbvMzMzMzMy827vdzf////8RERERERERERERERERERERzMwcERsREdHMzMzMzMzLzMzMzMy8y929vN3cvbvMzMzMzMzM293dy///3/8RERERERERERERERERERERzMvMERERG9HMzMzMzMzMzMzMzMy8293d3d3d3cvMzMzMzMzMy9vdvf/f/f8RERERERERERERERERERERzLvMERG7u7vMzMzMzMzMzMzMzMzM293d3d3dvbvMzMzMzMzM3N3d3fzd/P8REREREREREcHMzMzMERERwbvMHBERscvMzMzMzMzMzMzMzMy7293d3d3dvczMzMzMzMzMvN3d3cz9//8REREREREREcHMzMzMHBERwczMzMzMzMzMzMzMzMzMzMzMzMzM293d3d3dvczMzMzMzMzMzNvd3c3P//8REREREREREcHMEczMzBEREczMzMzMzMzMzMzMzMzMzMzMzMzMvdvd3c3dvczMzMzMzMzMvN3d3c3///8RERERERERERHMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMy83d3d3d3by8zMzMzMzMzM3N3d3b28/f8REREREREREREREczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMy7vdvd3dvdy8zMzMzMzMzM293d3c3//f8dEREREREREREREczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMy8zd3d3d3dy8zMzMzMzMzM293d3b3///8dERERERERERHBzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzMy73d3d3d29u8zMzMzMzMzM293d3c38//8dERERERERERHMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzb3d3d3d3Nu8zMzMzMzMzM3N3d3b38//8dERERERERERHBzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzLy93d3d3d29y8zMzMzMzMzM3d3d3d38///dEREREREREREREczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzLvby9vd3d29zMzMzMzMzMzb3d3d3d38/7/dHREREREREREREczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzc3d3N3d29y8zMzMzMzMy83d3d3d3////dHR0RERERERERzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNvd3d3d3d3dy8zMzMzMzMzd3d3d3d3//8/d3R0REREREcHMHMzMzBwREREREbHLzMzbvMsbHbEdu8vMzNvd3d293d3Mu8zMzMzMzLzd3d3d3d37///d3R0dHREREcHMHMzMHBEREREREbEbEREREbG7ERERu7vLvNvd3d3d3d29y8zMzMzMzLzd3d3d3d39///d3d0REREREcHMzMzMERERERERERG7EREdEbu7GxERsbvLzNzd3d3d3d3dvMzMzMzMzLzd3d3d3d37///d3d0REREREREREREREREREREREREbEREREbERu7u7u7u7zMvd3d3d3b3dzczMzMzMzNzd293d3d37///d3d0d0RERERERERERERERERERERERERERERERu7uxu7u7zN3d3b3b3d3du8zMzMzMzNvd3d3d3d37z8/d3d3d3RERERERERERERERERERERsRERGx3R0RERERsbu7u73d3d3d3d3du8zMzMzMzN3d3d3d3d39///d3R3d3R0REREREREREREREREREREREREREREdERERu7u7u93d3d3d3d3dvczMzMzMzNvd3d3d3d39///d3d3d3R0RERERERERERERERERERERERERERERERERu7u7u93d3d3d3d3dvczMzMzMvLvd3d3d3d39///d3d3d3R0RERERERERERERERERERERERERERERERGxu7u7vd293d3d3d3NvczMzMzMzLvd3d3d3d38///d3d3d3R0REREREREREREREREREREREbEbEREREbu7u7u7u9293d3d3du8vczMzMzMzNvb3d3d3c3P+//d3d3d3dEREREREREREREREREREREREbG7u7u7u7u7u7u72729293d3dzdu8zMzMzMzN293d3d3c39///d3d3d3d0dERERERERERERERERERERERG7u7u7u7u7u7u73b3d3d3d3d3dvczMzMzMvN3d3d3d3c3////d3d3d3d0dERERERERERGxERERERERsbu7u7u7u7u7u7u7u93d3d3d3N3dzczMzMzMvN3c3d3d3c3////d3d3d3d0dERERERERERGxuxu7u7u7u7sb0d27u7u7u7u73d3d3d3b293dy8zMzMzMvN3b3d3d3fv////d3d3d3d3dHR0RERERERERERERERGxuxsd0d3R3d27u7u73d3dvd3d3dzdvLzMzMzMvLvd3d3d3f3//P/d3d3d3d3d3dERERERERERERER0d292xHd3d3d3d29u7vb3d3d3d3c3d3dzczMzMzMvN3c3d3dvfz/+//d3d3d3d3d3d3RERERERERERERsbvb3d3d3d3d3d3du7vb3bvd3d3b3d3dvcvMzMzMvM3c3d3du/z////d3d3d3d3d3d3dERERERERER27uxvR3d3d3d3d3d3du7vb3b3d3d3d3d3dvczMzMzM283b3d3du//////d3d3d3d3d3d3d3RER3d3R3d3dHd3d3d3d3d3dHd3dvbvb3d3dvd3d3d3dvczMzMzM3N3d3d3dzP/////d3d3d3d3d3d3d3d3dHd3d3d3d3d3d3b273d3d3d3dvbvb3d3d3d3d3d3d3cvMzMzM293d3d29/P/////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d27293d3d3dvbvb293d3d3d3b3dvczMzMy83bvd3d3d/////8/d3d3d3d3d3d3d3d3d3d3d3d0d0d0R3d3du7vd3d3dvbvb3d3d3d293d3dvcvMzMzM3d3d3d3d///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3bu73d3dvbvb3d3d3d3d3d3dvcvMzMzM3d3d3d39///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d27u7u7u7vd3d3b3dvd3d3dvczMzMzM3d3d3d3L///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3bu7u7u7u7vd3d3d3dvd3d3d3czMzMy73d3d3d3M///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvd3bu7u9vd293d3dvd3d3d3cvMzMy83d3d3d3M///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d29u9vd3d3d3d3d293d3c3MzMzL293d3d3L/////P/d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvdvb3d3d3d3d3d3d3cvMzLzL293d3d27///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvd3d3d3d3d3d3d3d3bvLzMzM3N3d3d38///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvdvd3b3dvd3d3b3d3b3MzMzM293d3d3M///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvdvd3d3d3d3d3d3d3b3My8zM293d3d37///////d3d3d3d3d3d3d3d3d3d3d3d3d3d29293d3d3du7u7u9vd3d3d3d3d3d3d293MzMy8u93d3d38///////d3d3d3d3d3d3d3d3d3d3d3d3d3d27293d3b27u7u7u93d3d3d3d3d3d3d3d3MzMy8vd3d3d37///////d3d3d3d3d3d3d3d3d3d3d3d3dvbvb3d3d3b3b3d3dvdvd3d3d3b3d3d3d3d3LzMzMu93d3d37///////d3d3d3d3d3d3d3d3d3d3d3d3dvd3d3d3d3d3d3d3dvd3d3d3d3d3d3d3d3d3NzMzMvN3d3d37///////d3d3d3d3d3d3d3d3d3d3d3d3dvd3d3d3d3d3d3d3du73d3d3d3b3d3d3d3d3LzMzMvN3d3d3N///////d3d3d3d3d3d3d3d3d3d3d3d3dvdvd3d3d3d3d3d29u93b3d3d3d3d3d3d3d3NzMzMvN3d3d27/P/////d3d3d3d3d3d3d3d3d3d3d3d3d3bvb3d3d3d3d3d27u93d3d3d3d3d3d3d3d3NzMzM3N3d3d3L+//////d3d3d3d3d3d3d3d3d3d3d3d3d3bu7u7u7u7u7u7u7u9vd3d3d3d3d3d293d3NzMzM293d3d37z/z////d3d3d3d3d3d3d3d3d3d3d3d3d3d27u7u7u7u7u7u73d3d3d3d3d3d3d3d3d3LzMzM293d3d393//////d3d3d3d3d3d3d3d3d3d3d3d3d3d3du7u7u7u7u7u73d3d3d3d3d3d3d3d3d3NzMy83d3d3d37v//////d3d3d3d3d3d3d3d3d3d3d3d3d3d29u7u7u7u7u7u7293d3d3d3d3dvdzd3d3LzMy73d3d3d3P///////d3d3d3d3d3d3d3d3d3d3d3d3d3d27293du7u7u7vb293d3d3d3d3dvdzd3d3LzMy7zd3d3d3////////d3d3d3d3d3d3d3d3d3d3d3bu7u7vb3d3d3d3d3b3d3d3d3d3d3d3d3d3d3d3LzMu73dzd3b3///z////d3d3d3d3d3d3d3d3d3d3d3b3b3b3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3b3MzLzb3dzd3c3N///////d3d3d3d3d3d3d3d3d3d3d3d3d3dvd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3b3MzLvd293d3fv////////d3d3d3d3d3d3d3d3d3d3d3d3du93d3d3d3d3du93d3d3d3d3d3d3d3d3d3b3MzN3d3d3dvfz////////d3d3d3d3d3d3d3d3d3d3d3d29293d3d3d3d29u9vd3d3d3d3d3d3d3d3d3b27vN3d3d3dzP/////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cvM293d3d3d/f/////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvd3d3d3b3d3d3d3d3d3cvM293d3d3N/////f/////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cvcvL3d3d3d38///////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d27293d3d3d3dvd3d3d3d3dvcu73b3d3d3L2//////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d293dvd3d3d3d3d3d3d3dvbvb3d3d3b3////////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d27293d3d3d3d3d3d3d3d3dvbvd3d3d3c39//3/z//////d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvbu73b27u93d3d3d3d3d3d3d3d3d3d3d3d3dvfz/z93/3P/////d3d3d3d3d3d3d3d3d3d3d3d3d3d27u7u7u7u7293d3d3d3d3d3d3d3d3d3d3d3bu7zP/////P/8/////d3d3d3d3d3d3d3d3d3d3d3d3d3d3b3d3dvbu7293d3d3d3d3d3d3d3d3d3cvbu8zM///////P3//////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3b27293d3d3d3d3d3d3dvcvMzMz////P///////////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3b27293d3b3d3d3d3d3d/N3///z//////f/////////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3bu73b3d3d3d3d3d3b38//3////////8//////////////vd3d3d3d3d3d3d3d3d3d293d3d3d3d3d3dvbu7293d3d3d3d3d3fz///////3/////////v//P///////d3d3d3d3d3d3d3d3d3d29u93d3d3dvbu7u7u7293d3d3d3d29zP////////3//////f/////8///////d3d3d3d3d3d3d3d3d3d3du93d3d3d3d29u7u7293d293dvcv8z/y/zf//y//9///////////////////d3d3d3d3d3d3d3d3d3d3dvdvd3d3d3b27u7u7293d3d3dzb///////////c///////////////8/////d3d3d3d3d3d3d3d3du7u73b3b3d3dvbu7u7u7u93d3b273Nz/////////vP///////////8///8//v/vd3d3d3d3d3d3d3d272929u9272927u7u7u7u7u93d3b3d////////////////////////////////3//d3d3d3d3d3d3d3d3b3d3dvdu7u7u7u7u7u7u7u93dvbz9///////////////////////////////////d3d3d3d3d3d3d3d3d3d3d3bu7u7u7u7u7u7u7u93dy/z/3P/////////////////////////////////d3d3d3d3d3d3d3d3d3d3d3d3d3d27u7u7u7u7u929/P/c/f///8/////////////////////////7///d3d3d3d3d3d3d3d3d3d3d3d3d3b27u7u7u7u7u929/L/7z/z////////////////////P//////////3d3d3d3d3d3d3d3d3d3d3d3d3d3bu7u7u7u7u7u727/9//3/////////////////////+/2/3////////d3d3d3d3d3d3d3d3d3d273d3du7u7u7u7u7u7u73M/f+9//////////z/////////////z/3////////d3d3d3d3d3d3d3d3d3d27u7u7u7u7u7u7u7u7zM3f/f/P///////////////P////////z//////////d3d3d3d3d3d3d3d3d3d3d3bu9u7u7u7u7u8v8///////////////////P/Pv///z//////////////9zb3N3d3d3d3d3d3d3d3d3dvdu9u7u7u7u7u8z///////////////////////v///v//8///////P///93/393d3d3d3d3d3d3d3d3d3d27u7vLy8vMy//8/////////7/////////////////////////d/P///93Pz93d3d3d3d3d3d3d3d3d3b27u7vMy/z//Pz///////////////////////////////////+9//////zMzNvb3d3d3d3d3d3d3d3d3bu7u8u7/Pz////////////////////////////////////////////////d+8vN3N3b3d3d3d3d3d3d3bu7y8zL//////////////////////////////////////////////////+9///M/9zM3d3d3d3d3d3dvbvMzPv8//////////////////////z//////////////////7///////////8//z//Pzd27293d3du7vfzM/P//////////z////////////////////////////////////////////////////NvMzMvdvbvMv////////////////////////8//////////////////////////////////////////v////8+8zP/Pz//////////////////////////////////////////////////////////////////8////z/z//////////////////////////////////////////////////////P//////////3///////////z73N/P///////////////////////////////////////P//////////+/////////////3///////3////7/////////////////////////////////8/////////////////P/P///////P/8v8//////z////////////////////////////////////P/P/////////////////////////////8/////////////////////////////////////////////////c/8/8/////////////////////////8/8/////////////////////////////////////////////////////8z//////////////////////P/////7/////////////////////////////////////////////f/P/8z//////////////////////////L///////////////////////////////////////////8////////z//////////////////////////f////////////////////////////////zP/////////7/N/////////////////////////////////P///////////////8/////////////////////////////9/////////////////////////////////////////////////////////////////////////////////////8//////////z/////////////8=\"\n}","storySprites.ts":"namespace storySprites {\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"misc\"\n    export const mistletoe = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const halloween = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const holiday = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const holiday2 = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const birthday = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const world = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const field = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const valentines = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const lake = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const ocean = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const sky = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const castle = image.ofBuffer(hex``);\n    //% fixedInstance jres blockIdentity=images._image\n    //% tags=\"background\"\n    export const castle2 = image.ofBuffer(hex``);\n\n}"},"edge-connector":{"README.md":"# Edge connector\n\nSupport for 20 pin edge connector.\n\n## Config\n\nPin mapping must be specified in config key section.","device.d.ts":"declare namespace pins {\n    /**\n     * Pin P0 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P0)\n    const P0: PwmPin;\n\n    /**\n     * Pin P1 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P1)\n    const P1: PwmPin;\n\n    /**\n     * Pin P2 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P2)\n    const P2: PwmPin;\n\n    /**\n     * Pin P3 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P3)\n    const P3: AnalogInPin;\n\n    /**\n     * Pin P3 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P4)\n    const P4: AnalogInPin;\n\n    /**\n     * Pin P5 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P5)\n    const P5: DigitalInOutPin;\n\n    /**\n     * Pin P6 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P6)\n    const P6: DigitalInOutPin;\n\n    /**\n     * Pin P7 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P7)\n    const P7: DigitalInOutPin;\n\n    /**\n     * Pin P8 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P8)\n    const P8: DigitalInOutPin;\n\n    /**\n     * Pin P9 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P9)\n    const P9: DigitalInOutPin;\n\n    /**\n     * Pin P10 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P10)\n    const P10: AnalogInPin;\n\n    /**\n     * Pin P11 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P11)\n    const P11: DigitalInOutPin;\n\n    /**\n     * Pin P12 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P12)\n    const P12: DigitalInOutPin;\n\n    /**\n     * Pin P13 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P13)\n    const P13: DigitalInOutPin;\n\n    /**\n     * Pin P14 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P14)\n    const P14: DigitalInOutPin;\n\n    /**\n     * Pin P15 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P15)\n    const P15: DigitalInOutPin;\n\n    /**\n     * Pin P16 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P16)\n    const P16: PwmPin;\n\n    /**\n     * Pin P19 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P19)\n    const P19: DigitalInOutPin;\n\n    /**\n     * Pin P20 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P20)\n    const P20: DigitalInOutPin;\n\n    /**\n     * Pin P21 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P21)\n    const P21: PwmPin;\n\n    /**\n     * Pin P22 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P22)\n    const P22: PwmPin;\n\n    /**\n     * Pin P23 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P23)\n    const P23: PwmPin;\n\n    /**\n     * Pin P24 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P24)\n    const P24: PwmPin;\n\n    /**\n     * Pin P25 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P25)\n    const P25: PwmPin;\n\n    /**\n     * Pin P26 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P26)\n    const P26: PwmPin;\n\n    /**\n     * Pin P27 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P27)\n    const P27: PwmPin;\n\n    /**\n     * Pin P28 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P28)\n    const P28: PwmPin;\n\n    /**\n     * Pin P29 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P29)\n    const P29: PwmPin;\n\n    /**\n     * Pin P30 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P30)\n    const P30: PwmPin;\n\n    /**\n     * Pin P31 on the edge connector\n     */\n    //% fixedInstance shim=pxt::lookupPinCfg(CFG_PIN_P31)\n    const P31: PwmPin;\n}\n","pinscompat.ts":"// this type alias is required for backward compatibility\n// it gets overriden in microbit (DigitalPin is an enum over there)\nenum DigitalPin {\n    P0 = DAL.CFG_PIN_P0,\n    P1 = DAL.CFG_PIN_P1,\n    P2 = DAL.CFG_PIN_P2,\n    P3 = DAL.CFG_PIN_P3,\n    P4 = DAL.CFG_PIN_P4,\n    P5 = DAL.CFG_PIN_P5,\n    P6 = DAL.CFG_PIN_P6,\n    P7 = DAL.CFG_PIN_P7,\n    P8 = DAL.CFG_PIN_P8,\n    P9 = DAL.CFG_PIN_P9,\n    P10 = DAL.CFG_PIN_P10,\n    P11 = DAL.CFG_PIN_P11,\n    P12 = DAL.CFG_PIN_P12,\n    P13 = DAL.CFG_PIN_P13,\n    P14 = DAL.CFG_PIN_P14,\n    P15 = DAL.CFG_PIN_P15,\n    P16 = DAL.CFG_PIN_P16,\n    P19 = DAL.CFG_PIN_P19,\n    P20 = DAL.CFG_PIN_P20\n}\n\nenum AnalogPin {\n    P0 = DAL.CFG_PIN_P0,\n    P1 = DAL.CFG_PIN_P1,\n    P2 = DAL.CFG_PIN_P2,\n    P3 = DAL.CFG_PIN_P3,\n    P4 = DAL.CFG_PIN_P4,\n    P10 = DAL.CFG_PIN_P10,\n    P5 = DAL.CFG_PIN_P5,\n    P6 = DAL.CFG_PIN_P6,\n    P7 = DAL.CFG_PIN_P7,\n    P8 = DAL.CFG_PIN_P8,\n    P9 = DAL.CFG_PIN_P9,\n    P11 = DAL.CFG_PIN_P11,\n    P12 = DAL.CFG_PIN_P12,\n    P13 = DAL.CFG_PIN_P13,\n    P14 = DAL.CFG_PIN_P14,\n    P15 = DAL.CFG_PIN_P15,\n    P16 = DAL.CFG_PIN_P16,\n    P19 = DAL.CFG_PIN_P19,\n    P20 = DAL.CFG_PIN_P20\n}\n\nnamespace pins {\n    /**\n     * Sets the pin pull\n     * @param pin \n     * @param mode \n     */\n    //% deprecated=1\n    export function setPull(pin: DigitalPin, mode: PinPullMode) {\n        const p = pins.pinByCfg(pin);\n        if (p)\n            p.setPull(mode);\n    }\n\n    /**\n     * Sets the digital pin status\n     * @param pin\n     * @param value \n     */\n    //% deprecated=1\n    export function digitalWritePin(pin: DigitalPin, value: number) {\n        const p = pins.pinByCfg(pin);\n        if (p)\n            p.digitalWrite(!!value);\n    }\n\n    /**\n     * Reads the pin status\n     * @param pin \n     */\n    //% deprecated=1\n    export function digitalReadPin(pin: DigitalPin): number {\n        const p = pins.pinByCfg(pin);\n        return p && p.digitalRead() ? 1 : 0;\n    }\n\n    /**\n     * Sets the digital pin status\n     * @param pin \n     * @param value \n     */\n    //% deprecated=1\n    export function analogWritePin(pin: AnalogPin, value: number) {\n        const p = pins.pinByCfg(pin) as AnalogOutPin;\n        if (p)\n            p.analogWrite(value);\n    }\n\n    /**\n     * Reads the pin status\n     * @param pin \n     */\n    //% deprecated=1\n    export function analogReadPin(pin: AnalogPin): number {\n        const p = pins.pinByCfg(pin) as AnalogInPin;\n        if (p)\n            return p.analogRead();\n        else \n            return 0;\n    }\n\n    /**\n    * Make this pin a digital input, and create events where the timestamp is the duration\n    * that this pin was either ``high`` or ``low``.\n    */\n    //% deprecated=1\n    export function onPulsed(pin: DigitalPin, pulse: PulseValue, body: () => void): void {\n        const p = pins.pinByCfg(pin);\n        if (p)\n            p.onPulsed(pulse, body);\n    }\n\n    /**\n    * Register code to run when a pin event occurs. \n    */\n    //% deprecated=1\n    export function onEvent(pin: DigitalPin, event: PinEvent, body: () => void): void {\n        const p = pins.pinByCfg(pin);\n        if (p)\n            p.onEvent(event, body);\n    }\n\n    /**\n    * Return 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    //% deprecated=1\n    export function pulseIn(pin: DigitalPin, value: PulseValue, maxDuration?: number): number {\n        const p = pins.pinByCfg(pin);\n        if (p)\n            return p.pulseIn(value, maxDuration);\n        else \n            return 0;\n    }\n\n    export function map(value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number): number {\n        return Math.map(value, fromLow, fromHigh, toLow, toHigh);\n    }\n}","pxt.json":"{\n    \"name\": \"edge-connector\",\n    \"description\": \"20 pin Edge Connector\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"device.d.ts\",\n        \"pinscompat.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"requiredCategories\": [\n        \"pins\"\n    ],\n    \"icon\": \"/static/libs/edge-connector.png\"\n}\n"},"esp32":{"README.md":"# ESP32\n\nCommunication layer to a accessory ESP32 chip.\n\n> Ported from Adafruit Circuit Python \nhttps://github.com/adafruit/Adafruit_CircuitPython_ESP32SPI.\n\n## Configuration\n\n### Nina-FW over SPI\n\nThe companion firmware is https://github.com/adafruit/nina-fw over SPI.\nThe pins of the main board need to be configured either in the bootloader or using `namespace userconfig { ... }`.\nThe ESP32 pins are listed next to each key below (the number in parenthesis is the pin number on WROOM-32 module).\n\n* ``PIN_WIFI_CS``, ESP32 CS pin mapping, IO5 (29)\n* ``PIN_WIFI_BUSY``, ESP32 BUSY pin mapping, IO33 (9)\n* ``PIN_WIFI_RESET``, ESP32 RESET pin mapping, EN (3)\n* ``PIN_WIFI_GPIO0`` (optional), ESP32 GPIO0 pin mapping, IO0 (25)\n\nThe driver uses the default SPI pins. You can override this behavior by specifying these 3 keys.\n\n* ``PIN_WIFI_MOSI`` (optional), dedicated SPI MOSI pin, IO14 (13)\n* ``PIN_WIFI_MISO`` (optional), dedicated SPI MISO pin, IO23 (37)\n* ``PIN_WIFI_SCK`` (optional), dedicated SPI SCK pin, IO18 (30)\n\n### Expressif AT commands over serial\n\nNot supported yet.\n\n* ``PIN_WIFI_AT_RX``, ESP32 RX pin mapping\n* ``PIN_WIFI_AT_TX``, ESP32 TX pin mapping\n\n## Access Points and passwords\n\nThe module uses access points and password information stored in the device secrets. These secrets can be set programmatically using ``net.updateAccessPoint`` or via the menu items in Arcade (added via the ``net-game`` extension).\n\n> *Friendly reminder:* Do not share .uf2 files or programs with secrets!!\n\n## Example\n\nSee net package readme.","net.ts":"namespace esp32 {\n    let _defaultController: net.Controller;\n    function defaultController(): net.Controller {\n        // cached\n        if (_defaultController) return _defaultController;\n\n        /*\n        // look for ESP32 over serial pins\n        const rx = pins.pinByCfg(DAL.CFG_PIN_WIFI_AT_RX);\n        const tx = pins.pinByCfg(DAL.CFG_PIN_WIFI_AT_TX);\n        if (rx && tx) {\n            const dev = serial.createSerial(rx, tx);\n            return _defaultController = new ATController(dev);\n        }\n        */\n\n        // look for ESP32 over SPI pins\n        const cs = pins.pinByCfg(DAL.CFG_PIN_WIFI_CS)\n        const busy = pins.pinByCfg(DAL.CFG_PIN_WIFI_BUSY);\n        const reset = pins.pinByCfg(DAL.CFG_PIN_WIFI_RESET);\n        const gpio0 = pins.pinByCfg(DAL.CFG_PIN_WIFI_GPIO0); // optional\n        if (!!cs && !!busy && !!reset) {\n            // grab SPI pins and go\n            const mosi = pins.pinByCfg(DAL.CFG_PIN_WIFI_MOSI);\n            const miso = pins.pinByCfg(DAL.CFG_PIN_WIFI_MISO);\n            const sck = pins.pinByCfg(DAL.CFG_PIN_WIFI_SCK);\n            let spi: SPI;\n            if (!mosi && !miso && !sck) {\n                spi = pins.spi();\n            } else if (mosi && miso && sck) {\n                spi = pins.createSPI(mosi, miso, sck);\n            } else {// SPI misconfigured\n                net.log(\"esp32 spi configuration error\");\n                control.panic(control.PXT_PANIC.CODAL_HARDWARE_CONFIGURATION_ERROR);\n            }\n            if (spi)\n                return _defaultController = new NinaController(spi, cs, busy, reset, gpio0);\n        } else if (!cs && !busy && !reset) {\n            return undefined;\n            // do nothing, panic later\n        } else { // cs,busy,reset misconfigured\n            net.log(\"esp32 partially configured\");\n            control.panic(control.PXT_PANIC.CODAL_HARDWARE_CONFIGURATION_ERROR);\n        }\n\n        // no option\n        net.log(\"esp32 configuration error\");\n        control.panic(control.PXT_PANIC.CODAL_HARDWARE_CONFIGURATION_ERROR);\n        return undefined;\n    }\n\n    // initialize net\n    new net.Net(defaultController);\n}","ninacontroller.ts":"namespace esp32 {\n    // pylint: disable=bad-whitespace\n    const _SET_NET_CMD = 0x10\n    const _SET_PASSPHRASE_CMD = 0x11\n    const _SET_DEBUG_CMD = 0x1A\n    const _GET_TEMP_CMD = 0x1B\n    const _GET_CONN_STATUS_CMD = 0x20\n    const _GET_IPADDR_CMD = 0x21\n    const _GET_MACADDR_CMD = 0x22\n    const _GET_CURR_SSID_CMD = 0x23\n    const _GET_CURR_RSSI_CMD = 0x25\n    const _GET_CURR_ENCT_CMD = 0x26\n    const _SCAN_NETWORKS = 0x27\n    const _GET_SOCKET_CMD = 0x3F\n    const _GET_STATE_TCP_CMD = 0x29\n    const _DATA_SENT_TCP_CMD = 0x2A\n    const _AVAIL_DATA_TCP_CMD = 0x2B\n    const _GET_DATA_TCP_CMD = 0x2C\n    const _START_CLIENT_TCP_CMD = 0x2D\n    const _STOP_CLIENT_TCP_CMD = 0x2E\n    const _GET_CLIENT_STATE_TCP_CMD = 0x2F\n    const _DISCONNECT_CMD = 0x30\n    const _GET_IDX_RSSI_CMD = 0x32\n    const _GET_IDX_ENCT_CMD = 0x33\n    const _REQ_HOST_BY_NAME_CMD = 0x34\n    const _GET_HOST_BY_NAME_CMD = 0x35\n    const _START_SCAN_NETWORKS = 0x36\n    const _GET_FW_VERSION_CMD = 0x37\n    const _PING_CMD = 0x3E\n    const _SEND_DATA_TCP_CMD = 0x44\n    const _GET_DATABUF_TCP_CMD = 0x45\n    const _SET_ENT_IDENT_CMD = 0x4A\n    const _SET_ENT_UNAME_CMD = 0x4B\n    const _SET_ENT_PASSWD_CMD = 0x4C\n    const _SET_ENT_ENABLE_CMD = 0x4F\n    const _SET_PIN_MODE_CMD = 0x50\n    const _SET_DIGITAL_WRITE_CMD = 0x51\n    const _SET_ANALOG_WRITE_CMD = 0x52\n    const _START_CMD = 0xE0\n    const _END_CMD = 0xEE\n    const _ERR_CMD = 0xEF\n    const _REPLY_FLAG = 1 << 7\n    const _CMD_FLAG = 0\n    export const SOCKET_CLOSED = 0\n    export const SOCKET_LISTEN = 1\n    export const SOCKET_SYN_SENT = 2\n    export const SOCKET_SYN_RCVD = 3\n    export const SOCKET_ESTABLISHED = 4\n    export const SOCKET_FIN_WAIT_1 = 5\n    export const SOCKET_FIN_WAIT_2 = 6\n    export const SOCKET_CLOSE_WAIT = 7\n    export const SOCKET_CLOSING = 8\n    export const SOCKET_LAST_ACK = 9\n    export const SOCKET_TIME_WAIT = 10\n    export const WL_NO_SHIELD = 0xFF\n    export const WL_NO_MODULE = 0xFF\n    export const WL_IDLE_STATUS = 0\n    export const WL_NO_SSID_AVAIL = 1\n    export const WL_SCAN_COMPLETED = 2\n    export const WL_CONNECTED = 3\n    export const WL_CONNECT_FAILED = 4\n    export const WL_CONNECTION_LOST = 5\n    export const WL_DISCONNECTED = 6\n    export const WL_AP_LISTENING = 7\n    export const WL_AP_CONNECTED = 8\n    export const WL_AP_FAILED = 9\n\n\n    function buffer1(ch: number) {\n        const b = control.createBuffer(1)\n        b[0] = ch\n        return b\n    }\n\n    export class NinaController extends net.Controller {\n        private _socknum_ll: Buffer[];\n        private _locked: boolean;\n\n        public wasConnected: boolean;\n\n        constructor(\n            private _spi: SPI,\n            private _cs: DigitalInOutPin,\n            private _busy: DigitalInOutPin,\n            private _reset: DigitalInOutPin,\n            private _gpio0: DigitalInOutPin = null\n        ) {\n            super();\n            // if nothing connected, pretend the device is ready -\n            // we'll check for timeout waiting for response instead\n            this._busy.setPull(PinPullMode.PullDown);\n            this._busy.digitalRead();\n            this._socknum_ll = [buffer1(0)]\n            this._spi.setFrequency(8000000);\n            this.reset();\n            this._locked = false;\n        }\n\n        /** \n         * Hard reset the ESP32 using the reset pin \n        */\n        public reset(): void {\n            if (this._gpio0)\n                this._gpio0.digitalWrite(true);\n            this._cs.digitalWrite(true)\n            this._reset.digitalWrite(false)\n            // reset\n            pause(10)\n            this._reset.digitalWrite(true)\n            // wait for it to boot up\n            pause(750)\n            if (this._gpio0)\n                this._gpio0.digitalRead();\n            // make sure SPI gets initialized while the CS is up\n            this.spiTransfer(control.createBuffer(1), null)\n            net.log('reseted esp32')\n        }\n\n        private readByte(): number {\n            const r = buffer1(0)\n            this.spiTransfer(null, r)\n            return r[0]\n        }\n\n        private checkData(desired: number, msg?: string): boolean {\n            const r = this.readByte()\n            if (r != desired)\n                net.fail(`Expected ${desired} but got ${r}; ` + (msg || \"\"))\n            return false;\n        }\n\n        /** Read a byte with a time-out, and if we get it, check that its what we expect */\n        private waitSPIChar(desired: number): boolean {\n            let times = control.millis()\n            while (control.millis() - times < 100) {\n                let r = this.readByte()\n                if (r == _ERR_CMD) {\n                    net.log(\"error response to command\")\n                    return false\n                }\n\n                if (r == desired) {\n                    return true\n                }\n                //net.log(`read char ${r}, expected ${desired}`)\n            }\n            net.log(\"timed out waiting for SPI char\")\n            return false;\n        }\n\n        /**\n         * Wait until the ready pin goes low\n         */\n        private waitForReady() {\n            net.debug(`wait for ready ${this._busy.digitalRead()}`);\n            if (this._busy.digitalRead()) {\n                pauseUntil(() => !this._busy.digitalRead(), 10000);\n                net.debug(`busy = ${this._busy.digitalRead()}`);\n                // pause(1000)\n            }\n            if (this._busy.digitalRead()) {\n                net.log(\"timed out waiting for ready\")\n                return false\n            }\n\n            return true\n        }\n\n        private _sendCommand(cmd: number, params?: Buffer[], param_len_16?: boolean) {\n            params = params || [];\n\n            // compute buffer size\n            let n = 3; // START_CMD, cmd, length\n            params.forEach(param => {\n                n += 1 + (param_len_16 ? 1 : 0) + param.length;\n            })\n            n += 1; // END_CMD\n            // padding\n            while (n % 4) n++;\n\n            const packet = control.createBuffer(n);\n            let k = 0;\n            packet[k++] = _START_CMD;\n            packet[k++] = cmd & ~_REPLY_FLAG;\n            packet[k++] = params.length;\n\n            params.forEach(param => {\n                if (param_len_16)\n                    packet[k++] = (param.length >> 8) & 0xFF;\n                packet[k++] = param.length & 0xFF;\n                packet.write(k, param);\n                k += param.length;\n            })\n            packet[k++] = _END_CMD;\n            while (k < n)\n                packet[k++] = 0xff;\n\n            net.debug(`send cmd ${packet.toHex()}`)\n            if (!this.waitForReady())\n                return false\n            this._cs.digitalWrite(false)\n            this.spiTransfer(packet, null)\n            this._cs.digitalWrite(true)\n            net.debug(`send done`);\n            return true\n        }\n\n        private spiTransfer(tx: Buffer, rx: Buffer) {\n            if (!tx) tx = control.createBuffer(rx.length)\n            if (!rx) rx = control.createBuffer(tx.length)\n            this._spi.transfer(tx, rx);\n        }\n\n        private _waitResponseCmd(cmd: number, num_responses?: number, param_len_16?: boolean) {\n            net.debug(`wait response cmd`);\n            if (!this.waitForReady())\n                return null\n\n            this._cs.digitalWrite(false)\n\n            let responses: Buffer[] = []\n            if (!this.waitSPIChar(_START_CMD)) {\n                this._cs.digitalWrite(true)\n                return null\n            }\n            this.checkData(cmd | _REPLY_FLAG)\n            if (num_responses !== undefined)\n                this.checkData(num_responses, cmd + \"\")\n            else\n                num_responses = this.readByte();\n            for (let num = 0; num < num_responses; ++num) {\n                let param_len = this.readByte()\n                if (param_len_16) {\n                    param_len <<= 8\n                    param_len |= this.readByte()\n                }\n                net.debug(`\\tParameter #${num} length is ${param_len}`)\n                const response = control.createBuffer(param_len);\n                this.spiTransfer(null, response)\n                responses.push(response);\n            }\n            this.checkData(_END_CMD);\n\n            this._cs.digitalWrite(true)\n\n            net.debug(`responses ${responses.length}`);\n            return responses;\n        }\n\n        private lock() {\n            while (this._locked) {\n                pauseUntil(() => !this._locked)\n            }\n            this._locked = true\n        }\n\n        private unlock() {\n            if (!this._locked)\n                net.fail(\"not locked!\")\n            this._locked = false;\n        }\n\n        private sendCommandGetResponse(cmd: number, params?: Buffer[],\n            reply_params = 1, sent_param_len_16 = false, recv_param_len_16 = false) {\n\n            this.lock()\n            this._sendCommand(cmd, params, sent_param_len_16)\n            const resp = this._waitResponseCmd(cmd, reply_params, recv_param_len_16)\n            this.unlock();\n            return resp\n        }\n\n        get status(): number {\n            const resp = this.sendCommandGetResponse(_GET_CONN_STATUS_CMD)\n            if (!resp)\n                return WL_NO_SHIELD\n            net.debug(`status: ${resp[0][0]}`);\n            // one byte response\n            return resp[0][0];\n        }\n\n        /** A string of the firmware version on the ESP32 */\n        get firmwareVersion(): string {\n            let resp = this.sendCommandGetResponse(_GET_FW_VERSION_CMD)\n            if (!resp)\n                return \"not connected\"\n            return resp[0].toString();\n        }\n\n        /** A bytearray containing the MAC address of the ESP32 */\n        get MACaddress(): Buffer {\n            let resp = this.sendCommandGetResponse(_GET_MACADDR_CMD, [hex`ff`])\n            if (!resp)\n                return null\n            // for whatever reason, the mac adderss is backwards\n            const res = control.createBuffer(6)\n            for (let i = 0; i < 6; ++i)\n                res[i] = resp[0][5 - i]\n            return res\n        }\n\n        /** Begin a scan of visible access points. Follow up with a call\n    to 'get_scan_networks' for response\n*/\n        private startScanNetworks(): void {\n            let resp = this.sendCommandGetResponse(_START_SCAN_NETWORKS)\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to start AP scan\")\n            }\n\n        }\n\n        /** The results of the latest SSID scan. Returns a list of dictionaries with\n    'ssid', 'rssi' and 'encryption' entries, one for each AP found\n*/\n        private getScanNetworks(): net.AccessPoint[] {\n            let names = this.sendCommandGetResponse(_SCAN_NETWORKS, undefined, undefined)\n            // print(\"SSID names:\", names)\n            // pylint: disable=invalid-name\n            let APs = []\n            let i = 0\n            for (let name of names) {\n                let a_p = new net.AccessPoint(name.toString())\n                let rssi = this.sendCommandGetResponse(_GET_IDX_RSSI_CMD, [buffer1(i)])[0]\n                a_p.rssi = pins.unpackBuffer(\"<i\", rssi)[0]\n                let encr = this.sendCommandGetResponse(_GET_IDX_ENCT_CMD, [buffer1(1)])[0]\n                if (encr[0])\n                    a_p.flags |= net.WifiAPFlags.HasPassword\n                APs.push(a_p)\n                i++\n            }\n            return APs\n        }\n\n        /** Scan for visible access points, returns a list of access point details.\n     Returns a list of dictionaries with 'ssid', 'rssi' and 'encryption' entries,\n     one for each AP found\n    */\n        protected scanNetworksCore(): net.AccessPoint[] {\n            this.startScanNetworks()\n            // attempts\n            for (let _ = 0; _ < 10; ++_) {\n                pause(2000)\n                // pylint: disable=invalid-name\n                let APs = this.getScanNetworks()\n                if (APs) {\n                    for (const ap of APs)\n                        net.debug(`  ${ap.ssid} => RSSI ${ap.rssi}`)\n                    return APs\n                }\n\n            }\n            return null\n        }\n\n        /** Tells the ESP32 to set the access point to the given ssid */\n        public wifiSetNetwork(ssid: string): void {\n            const ssidbuf = control.createBufferFromUTF8(ssid);\n            let resp = this.sendCommandGetResponse(_SET_NET_CMD, [ssidbuf])\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to set network\")\n            }\n\n        }\n\n        /** Sets the desired access point ssid and passphrase */\n        public wifiSetPassphrase(ssid: string, passphrase: string): void {\n            const ssidbuf = control.createBufferFromUTF8(ssid);\n            const passphrasebuf = control.createBufferFromUTF8(passphrase);\n            let resp = this.sendCommandGetResponse(_SET_PASSPHRASE_CMD, [ssidbuf, passphrasebuf])\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to set passphrase\")\n            }\n        }\n\n        /** Sets the WPA2 Enterprise anonymous identity */\n        public wifiSetEntidentity(ident: string): void {\n            const ssidbuf = control.createBufferFromUTF8(ident);\n            let resp = this.sendCommandGetResponse(_SET_ENT_IDENT_CMD, [ssidbuf])\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to set enterprise anonymous identity\")\n            }\n\n        }\n\n        /** Sets the desired WPA2 Enterprise username */\n        public wifiSetEntusername(username: string): void {\n            const usernamebuf = control.createBufferFromUTF8(username);\n            let resp = this.sendCommandGetResponse(_SET_ENT_UNAME_CMD, [usernamebuf])\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to set enterprise username\")\n            }\n\n        }\n\n        /** Sets the desired WPA2 Enterprise password */\n        public wifiSetEntpassword(password: string): void {\n            const passwordbuf = control.createBufferFromUTF8(password);\n            let resp = this.sendCommandGetResponse(_SET_ENT_PASSWD_CMD, [passwordbuf])\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to set enterprise password\")\n            }\n\n        }\n\n        /** Enables WPA2 Enterprise mode */\n        public wifiSetEntenable(): void {\n            let resp = this.sendCommandGetResponse(_SET_ENT_ENABLE_CMD)\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to enable enterprise mode\")\n            }\n\n        }\n\n        get ssidBuffer(): Buffer {\n            let resp = this.sendCommandGetResponse(_GET_CURR_SSID_CMD, [hex`ff`])\n            return resp[0]\n        }\n\n        get ssid(): string {\n            const b = this.ssidBuffer;\n            return b ? b.toString() : \"\";\n        }\n\n        get rssi(): number {\n            let resp = this.sendCommandGetResponse(_GET_CURR_RSSI_CMD, [hex`ff`])\n            return pins.unpackBuffer(\"<i\", resp[0])[0]\n        }\n\n        get networkData(): any {\n            let resp = this.sendCommandGetResponse(_GET_IPADDR_CMD, [hex`ff`])\n            return resp[0]; //?\n        }\n\n        get ipAddress(): string {\n            return this.networkData[\"ip_addr\"]\n        }\n\n        get isConnected(): boolean {\n            return this.status == WL_CONNECTED\n        }\n\n        get isIdle(): boolean {\n            return this.status == WL_IDLE_STATUS;\n        }\n\n        /** \n         * Connect to an access point with given name and password.\n         * Will retry up to 10 times and return on success\n        */\n        connectAP(ssid: string, password: string): boolean {\n            net.log(`connect to ${ssid}`)\n            if (password) {\n                this.wifiSetPassphrase(ssid, password)\n            } else {\n                this.wifiSetNetwork(ssid)\n            }\n\n            // retries\n            let stat;\n            for (let _ = 0; _ < 10; ++_) {\n                stat = this.status\n                if (stat == WL_CONNECTED) {\n                    this.wasConnected = true;\n                    net.log(\"connected\")\n                    return true;\n                }\n                pause(1000)\n            }\n            if ([WL_CONNECT_FAILED, WL_CONNECTION_LOST, WL_DISCONNECTED].indexOf(stat) >= 0) {\n                net.log(`failed to connect to \"${ssid}\" (${stat})`)\n            }\n\n            if (stat == WL_NO_SSID_AVAIL) {\n                net.log(`no such ssid: \"${ssid}\"`)\n            }\n\n            return false;\n        }\n\n        /** \n         * Convert a hostname to a packed 4-byte IP address. Returns\n    a 4 bytearray\n    */\n        public hostbyName(hostname: string): Buffer {\n            if (!this.connect())\n                return undefined;\n\n            let resp = this.sendCommandGetResponse(_REQ_HOST_BY_NAME_CMD, [control.createBufferFromUTF8(hostname)])\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to request hostname\")\n            }\n\n            resp = this.sendCommandGetResponse(_GET_HOST_BY_NAME_CMD)\n            return resp[0];\n        }\n\n        /** Ping a destination IP address or hostname, with a max time-to-live\n    (ttl). Returns a millisecond timing value\n    */\n        public ping(dest: string, ttl: number = 250): number {\n            if (!this.connect())\n                return -1;\n\n            // convert to IP address\n            let ip = this.hostbyName(dest)\n\n            // ttl must be between 0 and 255\n            ttl = Math.max(0, Math.min(ttl | 0, 255))\n            let resp = this.sendCommandGetResponse(_PING_CMD, [ip, buffer1(ttl)])\n            return pins.unpackBuffer(\"<H\", resp[0])[0];\n        }\n\n        /** Request a socket from the ESP32, will allocate and return a number that\n    can then be passed to the other socket commands\n    */\n        public socket(): number {\n            if (!this.connect())\n                net.fail(\"can't connect\");\n\n            net.debug(\"*** Get socket\")\n            let resp0 = this.sendCommandGetResponse(_GET_SOCKET_CMD)\n            let resp = resp0[0][0]\n            if (resp == 255) {\n                net.fail(\"no sockets available\")\n            }\n            net.debug(\"Allocated socket #\" + resp)\n            return resp\n        }\n\n        /** Open a socket to a destination IP address or hostname\n    using the ESP32's internal reference number. By default we use\n    'conn_mode' TCP_MODE but can also use UDP_MODE or TLS_MODE\n    (dest must be hostname for TLS_MODE!)\n    */\n        public socketOpen(socket_num: number, dest: Buffer | string, port: number, conn_mode = net.TCP_MODE): void {\n            this._socknum_ll[0][0] = socket_num\n            net.debug(\"*** Open socket: \" + dest + \":\" + port)\n\n            let port_param = pins.packBuffer(\">H\", [port])\n            let resp: Buffer[]\n            // use the 5 arg version\n            if (typeof dest == \"string\") {\n                const dest2 = control.createBufferFromUTF8(dest)\n                resp = this.sendCommandGetResponse(_START_CLIENT_TCP_CMD, [dest2, hex`00000000`, port_param, this._socknum_ll[0], buffer1(conn_mode)])\n            } else {\n                // ip address, use 4 arg vesion\n                resp = this.sendCommandGetResponse(_START_CLIENT_TCP_CMD, [dest, port_param, this._socknum_ll[0], buffer1(conn_mode)])\n            }\n\n            if (resp[0][0] != 1) {\n                net.fail(\"could not connect to remote server\")\n            }\n\n        }\n\n        /** Get the socket connection status, can be SOCKET_CLOSED, SOCKET_LISTEN,\n    SOCKET_SYN_SENT, SOCKET_SYN_RCVD, SOCKET_ESTABLISHED, SOCKET_FIN_WAIT_1,\n    SOCKET_FIN_WAIT_2, SOCKET_CLOSE_WAIT, SOCKET_CLOSING, SOCKET_LAST_ACK, or\n    SOCKET_TIME_WAIT\n    */\n        public socketStatus(socket_num: number): number {\n            this._socknum_ll[0][0] = socket_num\n            let resp = this.sendCommandGetResponse(_GET_CLIENT_STATE_TCP_CMD, this._socknum_ll)\n            return resp[0][0]\n        }\n\n        /** Test if a socket is connected to the destination, returns boolean true/false */\n        public socket_connected(socket_num: number): boolean {\n            return this.socketStatus(socket_num) == SOCKET_ESTABLISHED\n        }\n\n        /** Write the bytearray buffer to a socket */\n        public socketWrite(socket_num: number, buffer: Buffer): void {\n            net.debug(\"Writing:\" + buffer.length)\n            this._socknum_ll[0][0] = socket_num\n            let resp = this.sendCommandGetResponse(_SEND_DATA_TCP_CMD, [this._socknum_ll[0], buffer], 1, true)\n            let sent = resp[0].getNumber(NumberFormat.UInt16LE, 0)\n            if (sent != buffer.length) {\n                net.fail(`failed to send ${buffer.length} bytes (sent ${sent})`)\n            }\n\n            resp = this.sendCommandGetResponse(_DATA_SENT_TCP_CMD, this._socknum_ll)\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to verify data sent\")\n            }\n\n        }\n\n        /** Determine how many bytes are waiting to be read on the socket */\n        public socketAvailable(socket_num: number): number {\n            this._socknum_ll[0][0] = socket_num\n            let resp = this.sendCommandGetResponse(_AVAIL_DATA_TCP_CMD, this._socknum_ll)\n            let reply = pins.unpackBuffer(\"<H\", resp[0])[0]\n            net.debug(`ESPSocket: ${reply} bytes available`)\n            return reply\n        }\n\n        /** Read up to 'size' bytes from the socket number. Returns a bytearray */\n        public socketRead(socket_num: number, size: number): Buffer {\n            net.debug(`Reading ${size} bytes from ESP socket with status ${this.socketStatus(socket_num)}`)\n            this._socknum_ll[0][0] = socket_num\n            let resp = this.sendCommandGetResponse(_GET_DATABUF_TCP_CMD,\n                [this._socknum_ll[0], pins.packBuffer(\"<H\", [size])],\n                1, true, true)\n            net.debug(`buf >>${resp[0].toString()}<<`)\n            return resp[0]\n        }\n\n        /** Open and verify we connected a socket to a destination IP address or hostname\n    using the ESP32's internal reference number. By default we use\n    'conn_mode' TCP_MODE but can also use UDP_MODE or TLS_MODE (dest must\n    be hostname for TLS_MODE!)\n    */\n        public socketConnect(socket_num: number, dest: string | Buffer, port: number, conn_mode = net.TCP_MODE): boolean {\n            net.debug(\"*** Socket connect mode \" + conn_mode)\n            this.socketOpen(socket_num, dest, port, conn_mode)\n            let times = net.monotonic()\n            // wait 3 seconds\n            while (net.monotonic() - times < 3) {\n                if (this.socket_connected(socket_num)) {\n                    return true\n                }\n\n                pause(10)\n            }\n            net.fail(\"failed to establish connection\")\n            return false\n        }\n\n        /** Close a socket using the ESP32's internal reference number */\n        public socketClose(socket_num: number): void {\n            net.debug(\"*** Closing socket #\" + socket_num)\n\n            this._socknum_ll[0][0] = socket_num\n            let resp = this.sendCommandGetResponse(_STOP_CLIENT_TCP_CMD, this._socknum_ll)\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to close socket\")\n            }\n\n        }\n\n        /** Enable/disable debug mode on the ESP32. Debug messages will be\n    written to the ESP32's UART.\n    */\n        public setESPdebug(enabled: boolean) {\n            let resp = this.sendCommandGetResponse(_SET_DEBUG_CMD, [buffer1(enabled ? 1 : 0)])\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to set debug mode\")\n            }\n        }\n\n        public getTemperature() {\n            let resp = this.sendCommandGetResponse(_GET_TEMP_CMD, [])\n            if (resp[0].length != 4) {\n                net.fail(\"failed to get temp\")\n            }\n            return resp[0].getNumber(NumberFormat.Float32LE, 0)\n        }\n\n        /** \n    Set the io mode for a GPIO pin.\n    \n    :param int pin: ESP32 GPIO pin to set.\n    :param value: direction for pin, digitalio.Direction or integer (0=input, 1=output).\n     \n    */\n        public setPinMode(pin: number, pin_mode: number): void {\n\n            let resp = this.sendCommandGetResponse(_SET_PIN_MODE_CMD, [buffer1(pin), buffer1(pin_mode)])\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to set pin mode\")\n            }\n\n        }\n\n        /** \n    Set the digital output value of pin.\n    \n    :param int pin: ESP32 GPIO pin to write to.\n    :param bool value: Value for the pin.\n     \n    */\n        public setDigitalWrite(pin: number, value: number): void {\n            let resp = this.sendCommandGetResponse(_SET_DIGITAL_WRITE_CMD, [buffer1(pin), buffer1(value)])\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to write to pin\")\n            }\n\n        }\n\n        /** \n    Set the analog output value of pin, using PWM.\n    \n    :param int pin: ESP32 GPIO pin to write to.\n    :param float value: 0=off 1.0=full on\n     \n    */\n        public setAnalogWrite(pin: number, analog_value: number) {\n            let value = Math.trunc(255 * analog_value)\n            let resp = this.sendCommandGetResponse(_SET_ANALOG_WRITE_CMD, [buffer1(pin), buffer1(value)])\n            if (resp[0][0] != 1) {\n                net.fail(\"failed to write to pin\")\n            }\n\n        }\n    }\n\n    //% shim=esp32spi::flashDevice\n    export function flashDevice() {\n        return\n    }\n}","pxt.json":"{\n    \"name\": \"esp32\",\n    \"description\": \"ESP32 over SPI - beta\",\n    \"dependencies\": {\n        \"core\": \"*\",\n        \"net\": \"*\",\n        \"settings\": \"*\"\n    },\n    \"files\": [\n        \"net.ts\",\n        \"ninacontroller.ts\",\n        \"README.md\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true\n}\n","test.ts":"function test() {\n\n    const log = console.log;\n    const esp = net.instance().controller()\n\n    if (!esp.isIdle)\n        return\n\n    log(`Firmware vers. ${esp.firmwareVersion}`)\n    log(`MAC addr: ${esp.MACaddress.toHex()}`)\n    log(\"Temp: \" + esp.getTemperature())\n\n    if (!esp.connect()) {\n        log(\"can't connect\")\n        return\n    }\n\n    log(\"ping: \" + esp.ping(\"bing.com\"))\n}\n\ntest();"},"feather":{"README.md":"# feather\n\nProvides pin definition for Adafruit Feather compatible boards.\n\n\nSee https://learn.adafruit.com/assets/78438","device.d.ts":"declare namespace pins {\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_A0)\n    const A0: PwmPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_A1)\n    const A1: PwmPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_A2)\n    const A2: PwmPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_A3)\n    const A3: PwmPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_A4)\n    const A4: PwmPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_A5)\n    const A5: PwmPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_D0)\n    const D0: PwmPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_D1)\n    const D1: PwmPin;\n\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_D4)\n    const D4: PwmPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_D5)\n    const D5: PwmPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_D6)\n    const D6: PwmPin;\n\n\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_D9)\n    const D9: PwmPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_D10)\n    const D10: PwmPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_D11)\n    const D11: PwmPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_D12)\n    const D12: PwmPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_D13)\n    const D13: PwmPin;\n\n}\n","pxt.json":"{\n    \"name\": \"feather\",\n    \"description\": \"Adafruit Feather pinout\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"device.d.ts\",\n        \"targetoverrides.d.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"requiredCategories\": [\n        \"pins\"\n    ],\n    \"weight\": 2,\n    \"icon\": \"/static/libs/feather.png\"\n}\n","targetoverrides.d.ts":"declare namespace pins {\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_D2)\n    const D2: PwmPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_D3)\n    const D3: PwmPin;\n}"},"game":{"animation.ts":"/*\n    Animation library for sprites\n*/\n//% color=\"#03AA74\" weight=100 icon=\"\\uf021\" block=\"Animation\"\n//% groups='[\"Animate\", \"Advanced\"]'\n//% weight=5\nnamespace animation {\n    const stateNamespace = \"__animation\";\n\n    interface AnimationState {\n        animations: SpriteAnimation[];\n    }\n\n    export class Point {\n        public x: number;\n        public y: number;\n\n        constructor(x: number, y: number) {\n            this.x = x;\n            this.y = y;\n        }\n    }\n\n    //% fixedInstances blockId=animation_path block=\"path %pathString\"\n    export class PathPreset {\n        constructor(public pathString: string) {\n        }\n    }\n\n    export class Path {\n        length: number;\n\n        protected args: number[];\n        protected currentCommand: string;\n        protected lastControlX: number;\n        protected lastControlY: number;\n\n        protected startX: number;\n        protected startY: number;\n\n        protected lastX: number;\n        protected lastY: number;\n\n        protected strIndex: number;\n        protected commandIndex: number;\n\n        constructor(protected path: string) {\n            this.strIndex = 0;\n\n            // Run through the path once to get the length and check for errors\n            this.length = 0;\n            while (this.strIndex < this.path.length) {\n                this.readNextCommand();\n                if (this.currentCommand) this.length++;\n            }\n\n            this.reset();\n        }\n\n        protected readNextCommand() {\n            if (this.strIndex >= this.path.length) {\n                this.currentCommand = undefined;\n                return;\n            }\n\n            this.currentCommand = this.readNextToken();\n\n            if (!this.currentCommand) return;\n\n            this.args = [];\n\n            const numArgs = Path.commandToArgCount(this.currentCommand);\n\n            if (numArgs === -1) throw \"Unknown path command '\" + this.currentCommand +\"'\";\n\n            for (let i = 0; i < numArgs; i++) {\n                this.args.push(parseFloat(this.readNextToken()))\n            }\n\n            for (const arg of this.args) {\n                if (Number.isNaN(arg)) throw \"Invalid argument for path command '\" + this.currentCommand + \"'\";\n            }\n        }\n\n        reset() {\n            this.args = undefined;\n            this.currentCommand = undefined;\n            this.lastControlX = undefined;\n            this.lastControlY = undefined;\n            this.startX = undefined;\n            this.startY = undefined;\n            this.lastX = undefined;\n            this.lastY = undefined;\n            this.strIndex = 0;\n            this.commandIndex = 0;\n        }\n\n        protected readNextToken() {\n            while (this.path.charCodeAt(this.strIndex) === 32 && this.strIndex < this.path.length) {\n                this.strIndex ++;\n            }\n\n            if (this.strIndex >= this.path.length) return undefined;\n\n            const tokenStart = this.strIndex;\n\n            while (this.path.charCodeAt(this.strIndex) !== 32 && this.strIndex < this.path.length) {\n                this.strIndex++;\n            }\n\n            return this.path.substr(tokenStart, this.strIndex - tokenStart);\n        }\n\n        private static commandToArgCount(command: string): number {\n            switch (command) {\n                case \"M\": // moveTo\n                case \"m\":\n                    return 2;\n                case \"L\": // lineTo\n                case \"l\":\n                    return 2;\n                case \"H\": // horizontalLineTo\n                case \"h\":\n                    return 1;\n                case \"V\": // verticalLineTo\n                case \"v\":\n                    return 1;\n                case \"Q\": // quadraticCurveTo\n                case \"q\":\n                    return 4;\n                case \"T\": // smoothQuadraticCurveTo\n                case \"t\":\n                    return 2;\n                case \"C\": // cubicCurveTo\n                case \"c\":\n                    return 6;\n                case \"S\": // smoothCubicCurveTo\n                case \"s\":\n                    return 4;\n                case \"A\": // arcTo\n                case \"a\":\n                    return 7;\n                case \"Z\": // closePath\n                case \"z\":\n                    return 0;\n                default:\n                    return -1;\n            }\n        }\n\n        public run(interval: number, target: Sprite, runningTime: number): boolean {\n            const nodeIndex = Math.floor(runningTime / interval); // The current node\n            const nodeTime = runningTime % interval; // The time the current node has been animating\n\n            if (this.startX === undefined) {\n                this.startX = target.x;\n                this.startY = target.y;\n                this.lastX = target.x;\n                this.lastY = target.y;\n                this.commandIndex = 0;\n                this.readNextCommand();\n            }\n\n            while (this.commandIndex < nodeIndex) {\n                if (this.currentCommand) {\n                    this.runCurrentCommand(target, interval, interval);\n                    this.lastX = target.x;\n                    this.lastY = target.y;\n                }\n                this.commandIndex++\n                this.readNextCommand();\n            }\n\n            if (nodeIndex >= this.length) {\n                return true;\n            }\n\n            this.runCurrentCommand(target, nodeTime, interval);\n            return false;\n        }\n\n        protected runCurrentCommand(target: Sprite, nodeTime: number, intervalTime: number) {\n            switch (this.currentCommand) {\n                case \"M\": // M x y\n                    this.lastControlX = undefined;\n                    this.lastControlY = undefined;\n                    moveTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.args[0],\n                        this.args[1]\n                    );\n                    break;\n                case \"m\": // m dx dy\n                    this.lastControlX = undefined;\n                    this.lastControlY = undefined;\n                    moveTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.args[0] + this.lastX,\n                        this.args[1] + this.lastY\n                    );\n                    break;\n                case \"L\": // L x y\n                    this.lastControlX = undefined;\n                    this.lastControlY = undefined;\n                    lineTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.args[0],\n                        this.args[1]\n                    );\n                    break;\n                case \"l\": // l dx dy\n                    this.lastControlX = undefined;\n                    this.lastControlY = undefined;\n                    lineTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.args[0] + this.lastX,\n                        this.args[1] + this.lastY\n                    );\n                    break;\n                case \"H\": // H x\n                    this.lastControlX = undefined;\n                    this.lastControlY = undefined;\n                    lineTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.args[0],\n                        this.lastY\n                    );\n                    break;\n                case \"h\": // h dx\n                    this.lastControlX = undefined;\n                    this.lastControlY = undefined;\n                    lineTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.args[0] + this.lastX,\n                        this.lastY\n                    );\n                    break;\n                case \"V\": // V y\n                    this.lastControlX = undefined;\n                    this.lastControlY = undefined;\n                    lineTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.lastX,\n                        this.args[0]\n                    );\n                    break;\n                case \"v\": // v dy\n                    this.lastControlX = undefined;\n                    this.lastControlY = undefined;\n                    lineTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.lastX,\n                        this.args[0] + this.lastY\n                    );\n                    break;\n                case \"Q\": // Q x1 y1 x2 y2\n                    this.lastControlX = this.args[0];\n                    this.lastControlY = this.args[1];\n                    quadraticCurveTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.args[0],\n                        this.args[1],\n                        this.args[2],\n                        this.args[3]\n                    )\n                    break;\n                case \"q\": // q dx1 dy1 dx2 dy2\n                    this.lastControlX = this.args[0] + this.lastX;\n                    this.lastControlY = this.args[1] + this.lastY;\n                    quadraticCurveTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.args[0] + this.lastX,\n                        this.args[1] + this.lastY,\n                        this.args[2] + this.lastX,\n                        this.args[3] + this.lastY\n                    );\n                    break;\n                case \"T\": // T x2 y2\n                    this.ensureControlPoint();\n                    quadraticCurveTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.lastX + this.lastX - this.lastControlX,\n                        this.lastY + this.lastY - this.lastControlY,\n                        this.args[0],\n                        this.args[1],\n                    );\n                    if (nodeTime === intervalTime) {\n                        this.lastControlX = this.lastX + this.lastX - this.lastControlX;\n                        this.lastControlY = this.lastY + this.lastY - this.lastControlY;\n                    }\n                    break;\n                case \"t\": // t dx2 dy2\n                    this.ensureControlPoint();\n                    quadraticCurveTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.lastX + this.lastX - this.lastControlX,\n                        this.lastY + this.lastY - this.lastControlY,\n                        this.args[0] + this.lastX,\n                        this.args[1] + this.lastY,\n                    );\n                    if (nodeTime === intervalTime) {\n                        this.lastControlX = this.lastX + this.lastX - this.lastControlX;\n                        this.lastControlY = this.lastY + this.lastY - this.lastControlY;\n                    }\n                    break;\n                case \"C\": // C x1 y1 x2 y2 x3 y3\n                    this.lastControlX = this.args[2];\n                    this.lastControlY = this.args[3];\n                    cubicCurveTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.args[0],\n                        this.args[1],\n                        this.args[2],\n                        this.args[3],\n                        this.args[4],\n                        this.args[5],\n                    );\n                    break;\n                case \"c\": // c dx1 dy1 dx2 dy2 dx3 dy3\n                    this.lastControlX = this.args[2] + this.lastX;\n                    this.lastControlY = this.args[3] + this.lastY;\n                    cubicCurveTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.args[0] + this.lastX,\n                        this.args[1] + this.lastY,\n                        this.args[2] + this.lastX,\n                        this.args[3] + this.lastY,\n                        this.args[4] + this.lastX,\n                        this.args[5] + this.lastY,\n                    );\n                    break;\n                case \"S\": // S x2 y2 x3 y3\n                    this.ensureControlPoint();\n                    cubicCurveTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.lastX + this.lastX - this.lastControlX,\n                        this.lastY + this.lastY - this.lastControlY,\n                        this.args[0],\n                        this.args[1],\n                        this.args[2],\n                        this.args[3]\n                    );\n                    if (nodeTime === intervalTime) {\n                        this.lastControlX = this.args[0];\n                        this.lastControlY = this.args[1];\n                    }\n                    break;\n                case \"s\": // s dx2 dy2 dx3 dy3\n                    this.ensureControlPoint();\n                    cubicCurveTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.lastX + this.lastX - this.lastControlX,\n                        this.lastY + this.lastY - this.lastControlY,\n                        this.args[0] + this.lastX,\n                        this.args[1] + this.lastY,\n                        this.args[2] + this.lastX,\n                        this.args[3] + this.lastY,\n                    );\n                    if (nodeTime === intervalTime) {\n                        this.lastControlX = this.args[0] + this.lastX;\n                        this.lastControlY = this.args[1] + this.lastY;\n                    }\n                    break;\n                case \"Z\": // Z\n                case \"z\": // z\n                    this.lastControlX = undefined;\n                    this.lastControlY = undefined;\n                    lineTo(\n                        target,\n                        nodeTime,\n                        intervalTime,\n                        this.lastX,\n                        this.lastY,\n                        this.startX,\n                        this.startY\n                    );\n                    break;\n            }\n        }\n\n        protected ensureControlPoint() {\n            if (this.lastControlX === undefined) throw \"Invalid path command. S/s and T/t must follow either Q/q or C/c\"\n        }\n    }\n\n    function moveTo(target: Sprite, nodeTime: number, interval: number, x: number, y: number) {\n        if (nodeTime >= interval) target.setPosition(x, y);\n    }\n\n    function lineTo(target: Sprite, nodeTime: number, interval: number, x0: number, y0: number, x1: number, y1: number) {\n        target.setPosition(\n            Math.round(((x1 - x0) / interval) * nodeTime) + x0,\n            Math.round(((y1 - y0) / interval) * nodeTime) + y0\n        );\n    }\n\n    function quadraticCurveTo(target: Sprite, nodeTime: number, interval: number, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number) {\n        const progress = nodeTime / interval;\n        const diff = 1 - progress;\n        const a = diff * diff;\n        const b = 2 * diff * progress;\n        const c = progress * progress;\n\n        target.setPosition(\n            Math.round(a * x0 + b * x1 + c * x2),\n            Math.round(a * y0 + b * y1 + c * y2)\n        );\n    }\n\n    function cubicCurveTo(target: Sprite, nodeTime: number, interval: number, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number) {\n        const progress = nodeTime / interval;\n        const diff = 1 - progress;\n        const a = diff * diff * diff;\n        const b = 3 * diff * diff * progress;\n        const c = 3 * diff * progress * progress;\n        const d = progress * progress * progress;\n\n        target.setPosition(\n            Math.round(a * x0 + b * x1 + c * x2 + d * x3),\n            Math.round(a * y0 + b * y1 + c * y2 + d * y3)\n        );\n    }\n\n    export abstract class SpriteAnimation {\n        protected elapsedTime: number;\n\n        constructor(public sprite: Sprite, protected loop: boolean) {\n            this.elapsedTime = 0;\n        }\n\n        public init() {\n            let state: AnimationState = game.currentScene().data[stateNamespace];\n\n            // Register animation updates to fire when frames are rendered\n            if (!state) {\n                state = game.currentScene().data[stateNamespace] = {\n                    animations: []\n                } as AnimationState;\n\n                game.eventContext().registerFrameHandler(scene.ANIMATION_UPDATE_PRIORITY, () => {\n                    state.animations = state.animations.filter((anim: SpriteAnimation) => {\n                        if (anim.sprite.flags & sprites.Flag.Destroyed)\n                            return false;\n                        return !anim.update(); // If update returns true, the animation is done and will be removed\n                    });\n                });\n            }\n\n            // Remove any other animations of this type and attached to this sprite\n            state.animations = state.animations.filter((anim: SpriteAnimation) => {\n                return !(anim.sprite === this.sprite &&\n                    ((anim instanceof ImageAnimation && this instanceof ImageAnimation) ||\n                    (anim instanceof MovementAnimation && this instanceof MovementAnimation)));\n            });\n\n            state.animations.push(this);\n        }\n\n        public update(): boolean {\n            // This should be implemented by subclasses\n            return false;\n        }\n    }\n\n    export class ImageAnimation extends SpriteAnimation {\n        private lastFrame: number;\n\n        constructor(sprite: Sprite, private frames: Image[], private frameInterval: number, loop?: boolean) {\n            super(sprite, loop);\n            this.lastFrame = -1;\n        }\n\n        public update(): boolean {\n            this.elapsedTime += game.eventContext().deltaTimeMillis;\n\n            const frameIndex = Math.floor(this.elapsedTime / this.frameInterval);\n\n            if (this.lastFrame != frameIndex && this.frames.length) {\n                if (!this.loop && frameIndex >= this.frames.length) {\n                    return true;\n                }\n                const newImage = this.frames[frameIndex % this.frames.length];\n                if (this.sprite.image !== newImage) {\n                    this.sprite.setImage(newImage);\n                }\n            }\n            this.lastFrame = frameIndex;\n            return false;\n        }\n    }\n\n    export class MovementAnimation extends SpriteAnimation {\n        protected startX: number;\n        protected startY: number;\n\n        constructor(sprite: Sprite, private path: Path, private nodeInterval: number, loop?: boolean) {\n            super(sprite, loop);\n            this.startX = sprite.x;\n            this.startY = sprite.y;\n            this.elapsedTime = 0;\n        }\n\n        public update(): boolean {\n            this.elapsedTime += game.eventContext().deltaTimeMillis;\n\n            let result = this.path.run(this.nodeInterval, this.sprite, this.elapsedTime);\n            if (result) {\n                if (!this.loop) return true;\n                this.elapsedTime = 0;\n                this.path.reset();\n                this.sprite.x = this.startX;\n                this.sprite.y = this.startY;\n            }\n            return false;\n        }\n    }\n\n    /**\n     * Create and run an image animation on a sprite\n     * @param frames the frames to animate through\n     * @param sprite the sprite to animate on\n     * @param frameInterval the time between changes, eg: 500\n     */\n    //% blockId=run_image_animation\n    //% block=\"animate $sprite=variables_get(mySprite) frames $frames=animation_editor interval (ms) $frameInterval=timePicker loop $loop=toggleOnOff\"\n    //% group=\"Animate\"\n    //% weight=100\n    //% help=animation/run-image-animation\n    export function runImageAnimation(sprite: Sprite, frames: Image[], frameInterval?: number, loop?: boolean) {\n        const anim = new ImageAnimation(sprite, frames, frameInterval || 500, !!loop);\n        anim.init();\n    }\n\n    /**\n     * Create and run a movement animation on a sprite\n     * @param sprite the sprite to move\n     * @param pathString the SVG path to animate\n     * @param duration how long the animation should play for, eg: 500\n     */\n    //% blockId=run_movement_animation\n    //% block=\"animate $sprite=variables_get(mySprite) with $pathString=animation_path for (ms) $duration=timePicker loop $loop=toggleOnOff\"\n    //% duration.defl=2000\n    //% weight=80\n    //% group=\"Animate\"\n    //% help=animation/run-movement-animation\n    export function runMovementAnimation(sprite: Sprite, pathString: string, duration?: number, loop?: boolean) {\n        const path = new Path(pathString);\n        const anim = new MovementAnimation(sprite, path, duration / path.length, !!loop);\n        anim.init();\n    }\n\n    export enum AnimationTypes {\n        //% block=\"all\"\n        All,\n        //% block=\"frame\"\n        ImageAnimation,\n        //% block=\"path\"\n        MovementAnimation\n    }\n\n    /**\n     * Stop one type or all animations (simple and looping) on a sprite\n     * @param type the animation type to stop\n     * @param sprite the sprite to filter animations by\n     */\n    //% blockId=stop_animations\n    //% block=\"stop %type animations on %sprite=variables_get(mySprite)\"\n    //% group=\"Animate\"\n    //% weight=60\n    //% help=animation/stop-animation\n    export function stopAnimation(type: AnimationTypes, sprite: Sprite) {\n        let state: AnimationState = game.currentScene().data[stateNamespace];\n        if (state && state.animations) {\n            state.animations = state.animations.filter((anim: SpriteAnimation) => {\n                if (anim.sprite === sprite) {\n                    switch (type) {\n                        case AnimationTypes.ImageAnimation:\n                            if (anim instanceof ImageAnimation) return false;\n                            break;\n                        case AnimationTypes.MovementAnimation:\n                            if (anim instanceof MovementAnimation) return false;\n                            break;\n                        case AnimationTypes.All:\n                            return false;\n                    }\n                }\n                return true;\n            });\n        }\n        if (type == AnimationTypes.All || type == AnimationTypes.ImageAnimation) {\n            //stop state based animation if any as well\n            sprite._action = -1\n        }\n    }\n\n    //% fixedInstance whenUsed block=\"fly to center\"\n    export const flyToCenter = new PathPreset(\"L 80 60\");\n\n    //% fixedInstance whenUsed block=\"shake\"\n    export const shake = new PathPreset(\"m 4 -1 m 1 2 m -6 2 m -4 -8 m 8 8 m 2 -4 m -8 0 m 6 3 m -3 -2\");\n\n    //% fixedInstance whenUsed block=\"bounce (right)\"\n    export const bounceRight = new PathPreset(\"q 7 0 15 40 q 10 -30 15 -25 q 10 5 15 25 q 5 -25 10 0 q 4 -15 8 0 q 2 -10 4 0 q 1 -5 1 0 q 0 -2 1 0\");\n\n    //% fixedInstance whenUsed block=\"bounce (left)\"\n    export const bounceLeft = new PathPreset(\"q -7 0 -15 40 q -10 -30 -15 -25 q -10 5 -15 25 q -5 -25 -10 0 q -4 -15 -8 0 q -2 -10 -4 0 q -1 -5 -1 0 q 0 -2 -1 0\");\n\n    //% fixedInstance whenUsed block=\"parachute (right)\"\n    export const parachuteRight = new PathPreset(\"q 20 10 40 5 q 2 -2 0 0 q -15 10 -30 5 q -2 -2 0 0 q 10 10 20 5 q 2 -2 0 0 q -5 5 -10 3 q -1 -1 0 0 q 2 2 5 1 l 0 2 l 0 2 l 0 2\");\n\n    //% fixedInstance whenUsed block=\"parachute (left)\"\n    export const parachuteLeft = new PathPreset(\"q -20 10 -40 5 q -2 -2 0 0 q 15 10 30 5 q 2 -2 0 0 q -10 10 -20 5 q -2 -2 0 0 q 5 5 10 3 q 1 -1 0 0 q -2 2 -5 1 l 0 2 l 0 2 l 0 2\");\n\n    //% fixedInstance whenUsed block=\"ease (right)\"\n    export const easeRight = new PathPreset(\"h 5 h 10 h 20 h 30 h 20 h 10 h 5\");\n\n    //% fixedInstance whenUsed block=\"ease (left)\"\n    export const easeLeft = new PathPreset(\"h -5 h -10 h -20 h -30 h -20 h -10 h -5\");\n\n    //% fixedInstance whenUsed block=\"ease (down)\"\n    export const easeDown = new PathPreset(\"v 5 v 10 v 20 v 30 v 20 v 10 v 5\");\n\n    //% fixedInstance whenUsed block=\"ease (up)\"\n    export const easeUp = new PathPreset(\"v -5 v -10 v -20 v -30 v -20 v -10 v -5\");\n\n    //% fixedInstance whenUsed block=\"wave (right)\"\n    export const waveRight = new PathPreset(\"c 25 -15 15 -5 20 0\");\n\n    //% fixedInstance whenUsed block=\"wave (left)\"\n    export const waveLeft = new PathPreset(\"c -25 -15 -15 -5 -20 0\");\n\n    //% fixedInstance whenUsed block=\"bobbing (in place)\"\n    export const bobbing = new PathPreset(\"c 0 -20 0 20 0 0\");\n\n    //% fixedInstance whenUsed block=\"bobbing (right)\"\n    export const bobbingRight = new PathPreset(\"c 5 -20 15 20 20 0\");\n\n    //% fixedInstance whenUsed block=\"bobbing (left)\"\n    export const bobbingLeft = new PathPreset(\"c -5 -20 -15 20 -20 0\");\n\n    /**\n     * Generates a path string for preset animation\n     * @param animationPath The preset path\n     */\n    //% blockId=animation_path\n    //% block=\"%animationPath\"\n    //% group=\"Animate\"\n    //% blockHidden=1\n    export function animationPresets(animationPath: PathPreset) {\n        return animationPath.pathString;\n    }\n\n\n    //% blockId=animation_editor block=\"%frames\"\n    //% shim=TD_ID\n    //% frames.fieldEditor=\"animation\"\n    //% frames.fieldOptions.decompileLiterals=\"true\"\n    //% frames.fieldOptions.filter=\"!tile !dialog !background\"\n    //% weight=40\n    //% group=\"Animate\" duplicateShadowOnDrag\n    //% help=animation/animation-frames\n    export function _animationFrames(frames: Image[]) {\n        return frames\n    }\n}\n","ask.ts":"namespace game {\n    /**\n     * Prompts the user for a boolean question\n     * @param title\n     * @param subtitle\n     */\n    //% weight=89 help=game/ask\n    //% blockId=gameask block=\"ask %title||%subtitle\"\n    //% title.shadow=text\n    //% subtitle.shadow=text\n    //% group=\"Prompt\"\n    export function ask(title: any, subtitle?: any): boolean {\n        controller._setUserEventsEnabled(false);\n        game.eventContext(); // initialize the game\n        control.pushEventContext();\n        title = console.inspect(title);\n        subtitle = subtitle ? console.inspect(subtitle) : subtitle;\n        game.showDialog(title, subtitle, \"A = OK, B = CANCEL\");\n        // short pause so that players don't skip through prompt\n        pause(500);\n\n        let answer: boolean = null;\n        let aNotHeld = false;\n        let bNotHeld = false;\n        pauseUntil(() => {\n            aNotHeld = aNotHeld || !controller.A.isPressed();\n            bNotHeld = bNotHeld || !controller.B.isPressed();\n\n            if (aNotHeld && controller.A.isPressed()) {\n                answer = true;\n            } else if (bNotHeld && controller.B.isPressed()) {\n                answer = false;\n            }\n            return answer !== null;\n        });\n\n        control.popEventContext();\n        controller._setUserEventsEnabled(true);\n        return answer;\n    }\n}","assetTemplates.ts":"//% helper=getTilemapByName\n//% pyConvertToTaggedTemplate\n//% blockIdentity=\"tiles._tilemapEditor\"\nfunction tilemap(lits: any, ...args: any[]): tiles.TileMapData { return null }\n\n//% helper=getTilemapByName\n//% pyConvertToTaggedTemplate\nfunction tilemap8(lits: any, ...args: any[]): tiles.TileMapData { return null }\n\n//% helper=getTilemapByName\n//% pyConvertToTaggedTemplate\nfunction tilemap16(lits: any, ...args: any[]): tiles.TileMapData { return null }\n\n//% helper=getTilemapByName\n//% pyConvertToTaggedTemplate\nfunction tilemap32(lits: any, ...args: any[]): tiles.TileMapData { return null }\n\n//% helper=getTilemapByName\n//% pyConvertToTaggedTemplate\nfunction tilemap4(lits: any, ...args: any[]): tiles.TileMapData { return null }\n\nnamespace assets {\n    //% helper=getTilemapByName\n    //% pyConvertToTaggedTemplate\n    //% blockIdentity=\"tiles._tilemapEditor\"\n    export function tilemap(lits: any, ...args: any[]): tiles.TileMapData { return null }\n\n    //% helper=getImageByName\n    //% pyConvertToTaggedTemplate\n    //% blockIdentity=\"images._spriteImage\"\n    export function image(lits: any, ...args: any[]): Image { return null }\n\n    //% helper=getTileByName\n    //% pyConvertToTaggedTemplate\n    //% blockIdentity=\"images._tile\"\n    export function tile(lits: any, ...args: any[]): Image { return null }\n\n    //% helper=getAnimationByName\n    //% pyConvertToTaggedTemplate\n    //% blockIdentity=\"animation._animationFrames\"\n    export function animation(lits: any, ...args: any[]): Image[] { return null }\n\n    //% helper=getSongByName\n    //% pyConvertToTaggedTemplate\n    //% blockIdentity=\"music._songFieldEditor\"\n    export function song(lits: any, ...args: any[]): Buffer { return null }\n}\n\nnamespace helpers {\n    export type TilemapFactory = (name: string) => tiles.TileMapData;\n    export type ImageFactory = (name: string) => Image;\n    export type TileFactory = (name: string) => Image;\n    export type AnimationFactory = (name: string) => Image[];\n    export type SongFactory = (name: string) => Buffer;\n\n    interface Factory {\n        kind: string;\n        factory: (name: string) => any;\n    }\n\n    let factories: Factory[];\n\n    export function _registerFactory(kind: string, factory: (name: string) => any) {\n        if (!factories) factories = [];\n        factories.push({\n            kind,\n            factory\n        });\n    }\n\n    export function _getFactoryInstance(kind: string, name: string) {\n        if (factories) {\n            for (const factory of factories) {\n                if (factory.kind === kind) {\n                    let data = factory.factory(name);\n                    if (data) return data;\n                }\n            }\n        }\n        return null;\n    }\n\n    // Deprecated; use helpers._registerFactory(\"tilemap\", name)\n    export function registerTilemapFactory(factory: TilemapFactory) {\n        _registerFactory(\"tilemap\", factory);\n    }\n\n    export function getTilemapByName(name: string) {\n        return _getFactoryInstance(\"tilemap\", name);\n    }\n\n    export function getImageByName(name: string) {\n        return _getFactoryInstance(\"image\", name);\n    }\n\n    export function getAnimationByName(name: string) {\n        return _getFactoryInstance(\"animation\", name);\n    }\n\n    export function getTileByName(name: string) {\n        return _getFactoryInstance(\"tile\", name);\n    }\n\n    export function getSongByName(name: string) {\n        return _getFactoryInstance(\"song\", name);\n    }\n}\n","background.ts":"enum BackgroundAlignment {\n    //% block=\"left\"\n    Left = 1,\n    //% block=\"right\"\n    Right,\n    //% block=\"top\"\n    Top,\n    //% block=\"bottom\"\n    Bottom,\n    //% block=\"center\"\n    Center\n}\n\nnamespace scene {\n    export class Background {\n        color: number;\n        _image: Image;\n        camera: Camera;\n        private _layers: BackgroundLayer[];\n\n        constructor(camera: Camera) {\n            this.color = 0;\n            this.camera = camera;\n            this._layers = [];\n        }\n\n        public addLayer(pic: Image, distance: number, alignment: BackgroundAlignment) {\n            const layer = new BackgroundLayer(distance, alignment, pic);\n            this._layers.push(layer);\n            this._layers.sort((a, b) => b.distance - a.distance);\n            return layer;\n        }\n\n        get image() {\n            if (!this._image) {\n                this._image = image.create(screen.width, screen.height);\n            }\n            return this._image;\n        }\n        \n        set image(image: Image) {\n            this._image = image;\n        }\n\n        hasBackgroundImage(): boolean {\n            return !!this._image;\n        }\n\n        draw() {\n            screen.fill(this.color);\n            if (this._image)\n                screen.drawTransparentImage(this._image, 0, 0)\n            if (this._layers) {\n                this._layers.forEach(layer => {\n                    // compute displacement based on distance\n                    const ox = Math.round(this.camera.drawOffsetX / (1 + layer.distance));\n                    const oy = Math.round(this.camera.drawOffsetY / (1 + layer.distance));\n                    layer.draw(ox, oy);\n                });\n            }\n        }\n    }\n\n\n    export class BackgroundLayer {\n        distance: number;\n        img: Image;\n        repeatX: boolean;\n        repeatY: boolean;\n        alignX: BackgroundAlignment;\n        alignY: BackgroundAlignment;\n\n        constructor(distance: number, alignment: BackgroundAlignment, img: Image) {\n            this.distance = Math.max(1, distance);\n            this.img = img;\n            switch (alignment) {\n                case BackgroundAlignment.Center:\n                    this.repeatX = true;\n                    this.repeatY = true;\n                    this.alignX = BackgroundAlignment.Center;\n                    this.alignY = BackgroundAlignment.Center;\n                    break;\n                case BackgroundAlignment.Left:\n                case BackgroundAlignment.Right:\n                    this.repeatX = false;\n                    this.repeatY = true;\n                    this.alignX = alignment;\n                    this.alignY = BackgroundAlignment.Center;\n                    break;\n                case BackgroundAlignment.Top:\n                case BackgroundAlignment.Bottom:\n                    this.repeatX = true;\n                    this.repeatY = false;\n                    this.alignX = BackgroundAlignment.Center;\n                    this.alignY = alignment;\n                    break;\n            }\n        }\n\n        draw(offsetX: number, offsetY: number) {\n            const w = screen.width;\n            const h = screen.height;\n            const pw = this.img.width;\n            const ph = this.img.height;\n\n            if (!pw || !ph) return; // empty image.\n\n            // left, top aligned\n            let rx = -offsetX;\n            let ry = -offsetY;\n\n            switch (this.alignX) {\n                case BackgroundAlignment.Right: rx -= (w + pw); break;\n                case BackgroundAlignment.Center: rx -= (w + pw) >> 1; break;\n            }\n            switch (this.alignY) {\n                case BackgroundAlignment.Bottom: ry -= (h + ph); break;\n                case BackgroundAlignment.Center: ry -= (h + ph) >> 1; break;\n            }\n\n            rx %= w; if (rx < 0) rx += w;\n            ry %= h; if (ry < 0) ry += h;\n\n            // avoid subpixel aliasing\n            rx = Math.floor(rx);\n            ry = Math.floor(ry);\n\n            let y = 0;\n            let py = 0;\n            while (y < h) {\n                py = y % ph;\n                let dh = Math.min(ph - py, h - ry);\n                let x = 0;\n                let rxl = rx;\n                while (x < w) {\n                    let px = x % pw;\n                    let dw = Math.min(pw - px, w - rxl);\n                    screen.drawImage(this.img, rxl, ry);\n                    rxl = (rxl + dw) % w;\n                    x += this.repeatX ? dw : w;\n                }\n                ry = (ry + dh) % h;\n                y += this.repeatY ? dh : h;\n            }\n        }\n    }\n}","basesprite.ts":"interface SpriteLike {\n    z: number;\n    id: number;\n    flags?: number;\n\n    __update(camera: scene.Camera, dt: number): void;\n    __draw(camera: scene.Camera): void;\n    __serialize(offset: number): Buffer;\n}\n\nnamespace sprites {\n    export class BaseSprite implements SpriteLike {\n        protected _z: number;\n        id: number;\n\n        constructor(z: number) {\n            this.z = z;\n\n            // this assigns the sprite an id as a side effect\n            game.currentScene().addSprite(this);\n        }\n\n        __visible(): boolean {\n            return true;\n        }\n\n        get z(): number {\n            return this._z;\n        }\n\n        set z(v: number) {\n            if (this._z !== v) {\n                this._z = v;\n                game.currentScene().flags |= scene.Flag.NeedsSorting;\n            }\n        }\n\n        __draw(camera: scene.Camera) {\n            if (this.__visible()) {\n                this.__drawCore(camera);\n            }\n        }\n\n        __drawCore(camera: scene.Camera) { }\n\n        __update(camera: scene.Camera, dt: number) { }\n\n        __serialize(offset: number): Buffer { return undefined }\n    }\n}","camera.ts":"namespace scene {\n    export class Camera {\n        // coordinate used for all physics computation\n        protected _offsetX: number;\n        protected _offsetY: number;\n\n        // coordinate used for draw sprites, may including shaking\n        drawOffsetX: number;\n        drawOffsetY: number;\n        sprite: Sprite;\n        protected _lastUpdatedSpriteX: number;\n        protected _lastUpdatedSpriteY: number;\n\n        protected shakeStartTime: number;\n        protected shakeDuration: number;\n        protected shakeAmplitude: number;\n\n        constructor() {\n            this._offsetX = 0;\n            this._offsetY = 0;\n\n            this.drawOffsetX = 0;\n            this.drawOffsetY = 0;\n        }\n\n        get offsetX() {\n            return this._offsetX;\n        }\n        set offsetX(v: number) {\n            const scene = game.currentScene();\n            if (scene.tileMap && scene.tileMap.enabled) {\n                this._offsetX = Math.floor(scene.tileMap.offsetX(v));\n            } else {\n                this._offsetX = Math.floor(v);\n            }\n        }\n        get offsetY() {\n            return this._offsetY;\n        }\n        set offsetY(v: number) {\n            const scene = game.currentScene();\n            if (scene.tileMap && scene.tileMap.enabled) {\n                this._offsetY = Math.floor(scene.tileMap.offsetY(v));\n            } else {\n                this._offsetY = Math.floor(v);\n            }\n        }\n\n        get x() {\n            return this.offsetX + (screen.width >> 1);\n        }\n        get y() {\n            return this.offsetY + (screen.height >> 1);\n        }\n        get left() {\n            return this.offsetX;\n        }\n        get right() {\n            return this.offsetX + screen.width;\n        }\n        get top() {\n            return this.offsetY;\n        }\n        get bottom() {\n            return this.offsetY + screen.height;\n        }\n\n        shake(amplitude: number = 4, duration: number = 1000) {\n            if (amplitude <= 0 || duration <= 0) {\n                this.shakeStartTime = undefined;\n            } else {\n                // this overrides any existing shake operation\n                this.shakeStartTime = control.millis();\n                this.shakeAmplitude = amplitude;\n                this.shakeDuration = duration;\n                // don't reset offset, will be recomputed in update\n            }\n        }\n\n        isUpdated() {\n            return !this.sprite || (this.sprite.x === this._lastUpdatedSpriteX && this.sprite.y === this._lastUpdatedSpriteY);\n        }\n\n        update() {\n            // if sprite, follow sprite\n            if (this.sprite) {\n                this._lastUpdatedSpriteX = this.sprite.x;\n                this._lastUpdatedSpriteY = this.sprite.y;\n                this.offsetX = this.sprite.left + (this.sprite.width >> 1) - (screen.width >> 1);\n                this.offsetY = this.sprite.top + (this.sprite.width >> 1) - (screen.height >> 1);\n            }\n\n            this.drawOffsetX = this.offsetX;\n            this.drawOffsetY = this.offsetY;\n\n            // apply shake if needed\n            if (this.shakeStartTime !== undefined) {\n                const elapsed = control.millis() - this.shakeStartTime;\n                if (elapsed >= this.shakeDuration) {\n                    // we are done!\n                    this.shakeStartTime = undefined;\n                } else {\n                    // compute new shake\n                    const percentComplete = elapsed / this.shakeDuration;\n                    const dampStart = 0.75;\n                    let damp = 1;\n                    if (percentComplete >= dampStart)\n                        damp = Math.max(0, 1 - percentComplete);\n                    const f = this.shakeAmplitude * damp;\n                    const x = (Math.random() * f) >> 0;\n                    const y = (Math.random() * f) >> 0;\n                    // apply to offset\n                    this.drawOffsetX += x;\n                    this.drawOffsetY += y;\n                }\n            }\n        }\n    }\n}","console.ts":"namespace game.consoleOverlay {\n    let consoleColor = 1;\n    let consoleStrings: string[];\n    let tabSize = 8;\n    const marginx = 4;\n    const marginy = 2;\n    const consoleFont = image.font5;\n    const consoleLines = Math.floor(screen.height / (consoleFont.charHeight + marginy)) - 1;\n    const consoleColumns = Math.floor((screen.width - 2 * marginx) / consoleFont.charWidth);\n    console.addListener(listener);\n\n    export function isVisible() {\n        return !!consoleStrings;\n    }\n\n    export function clear() {\n        consoleStrings = [];\n    }\n\n    export function setVisible(value: boolean, col?: number) {\n        if (value != !!consoleStrings)\n            consoleStrings = value ? [] : undefined;\n        if (col !== undefined)\n            consoleColor = col;\n    }\n\n    function listener(priority: ConsolePriority, text: string) {\n        if (!consoleStrings || !text)\n            return;\n\n        // split text into lines\n        text.split(\"\\n\")\n            .filter(line => !!line)\n            .forEach(line => {\n                for (let j = 0; j < line.length; j += consoleColumns) {\n                    consoleStrings.push(line.slice(j, j + consoleColumns));\n                }\n            });\n\n        if (consoleStrings.length > consoleLines) {\n            consoleStrings.splice(0, consoleStrings.length - consoleLines);\n        }\n    }\n\n    export function draw() {\n        if (!consoleStrings || scene.systemMenu.isVisible()) return;\n        const height = consoleFont.charHeight + marginy;\n        const top = 2 + (game.stats ? height : 0);\n        for (let i = 0; i < consoleStrings.length; ++i) {\n            if (consoleStrings[i].indexOf(\"\\t\") >= 0) {\n                const t = consoleStrings[i].split(\"\\t\");\n                let tOff = 0;\n                for (let tab of t) {\n                    let padding = tabSize - ((tOff + tab.length) % tabSize)\n                    screen.print(tab, marginx + (tOff * consoleFont.charWidth), top + i * height, consoleColor, consoleFont);\n                    tOff += tab.length + padding;\n                }\n            }\n            else\n                screen.print(consoleStrings[i], marginx, top + i * height, consoleColor, consoleFont);\n        }\n    }\n}","constants.ts":"const KEY_UP = 2048;\nconst KEY_DOWN = 2049;\nconst INTERNAL_KEY_UP = 2050;\nconst INTERNAL_KEY_DOWN = 2051;\nconst SYSTEM_KEY_UP = 2052;\nconst SYSTEM_KEY_DOWN = 2053;\nconst KEY_REPEAT = 2054;\nconst SYSTEM_KEY_REPEAT = 2055;\n","controller.ts":"enum ControllerEvent {\n    //% block=\"connected\"\n    Connected = 1,\n    //% block=\"disconnected\"\n    Disconnected = 2\n}\n\n/**\n * Access to game controls\n */\n//% weight=98 color=\"#D54322\" icon=\"\\uf11b\"\n//% groups='[\"Single Player\", \"Multiplayer\"]'\n//% blockGap=8\nnamespace controller {\n    let _players: Controller[];\n    game.addScenePopHandler(() => {\n        const stateWhenPushed = game.currentScene().controllerConnectionState;\n        if (!stateWhenPushed)\n            return;\n        for (let i = 0; i < stateWhenPushed.length; i++) {\n            const p = _players[i];\n            if (p && (!!stateWhenPushed[i] != !!p.connected)) {\n                // connection state changed while in another scene; raise the event.\n                control.raiseEvent(\n                    p.id,\n                    p.connected ? ControllerEvent.Connected : ControllerEvent.Disconnected\n                );\n            }\n        }\n\n    })\n    game.addScenePushHandler(oldScene => {\n        oldScene.controllerConnectionState = [];\n        for (let i = 0; i < _players.length; i++) {\n            if (_players[i]) {\n                oldScene.controllerConnectionState[i] = _players[i].connected;\n            }\n        }\n    })\n\n    function addController(ctrl: Controller) {\n        if (!_players) {\n            _players = [];\n        }\n        _players[ctrl.playerIndex - 1] = ctrl;\n    }\n\n    export function _player1(): Controller {\n        if (!_players || !_players[0])\n            new Controller(1, [controller.left, controller.up, controller.right, controller.down, controller.A, controller.B, controller.menu]);\n        return _players[0];\n    }\n\n    export function players(): Controller[] {\n        _player1(); // ensure player1 is present\n        return _players.filter(ctrl => !!ctrl);\n    }\n\n    export class ControlledSprite {\n        public _inputLastFrame: boolean;\n        constructor(\n            public s: Sprite,\n            public vx: number,\n            public vy: number\n        ) { }\n    }\n\n    export function _moveSprites() {\n        // todo: move to current scene\n        control.enablePerfCounter(\"controller\")\n        players().forEach(ctrl => ctrl.__preUpdate());\n    }\n\n    //% fixedInstances\n    export class Controller {\n        playerIndex: number;\n        buttons: Button[];\n        analog: boolean;\n        private _id: number;\n        private _connected: boolean;\n\n        // array of left,up,right,down,a,b,menu buttons\n        constructor(playerIndex: number, buttons: Button[]) {\n            this._id = control.allocateNotifyEvent();\n            this._connected = false;\n            this.playerIndex = playerIndex;\n            this.analog = false;\n            if (buttons)\n                this.buttons = buttons;\n            else {\n                this.buttons = [];\n                const leftId = 1 + (this.playerIndex - 1) * 7;\n                for (let i = 0; i < 7; ++i) {\n                    this.buttons.push(new Button(leftId + i, -1));\n                }\n            }\n            for (let i = 0; i < this.buttons.length; ++i)\n                this.buttons[i]._owner = this;\n            addController(this);\n        }\n\n        get _controlledSprites(): ControlledSprite[] {\n            return game.currentScene().controlledSprites[this.playerIndex];\n        }\n\n        set _controlledSprites(cps: ControlledSprite[]) {\n            game.currentScene().controlledSprites[this.playerIndex] = cps;\n        }\n\n        get id() {\n            return this._id;\n        }\n\n        dump() {\n            this.buttons.forEach(b => console.log(b.toString()));\n        }\n\n        /**\n         * Get the 'Left' button\n         */\n        //%\n        get left() {\n            return this.button(ControllerButton.Left);\n        }\n\n        /**\n         * Get the 'Right' button\n         */\n        //%\n        get right() {\n            return this.button(ControllerButton.Right);\n        }\n\n        /**\n         * Get the 'Up' button\n         */\n        //%\n        get up() {\n            return this.button(ControllerButton.Up);\n        }\n\n        /**\n         * Get the 'Down' button\n         */\n        //%\n        get down() {\n            return this.button(ControllerButton.Down);\n        }\n\n        /**\n         * Get the 'A' button\n         */\n        //%\n        get A() {\n            return this.button(ControllerButton.A);\n        }\n\n        /**\n         * Get the 'B' button\n         */\n        //%\n        get B() {\n            return this.button(ControllerButton.B);\n        }\n\n        /**\n         * Get the 'Menu' button\n         */\n        //%\n        get menu() {\n            return this.button(7);\n        }\n\n        /**\n         * Control a sprite using the direction buttons from the controller. Note that this will overwrite\n         * the current velocity of the sprite whenever a directional button is pressed. To stop controlling\n         * a sprite, pass 0 for vx and vy.\n         *\n         * @param sprite The Sprite to control\n         * @param vx The velocity used for horizontal movement when left/right is pressed\n         * @param vy The velocity used for vertical movement when up/down is pressed\n         */\n        //% blockId=\"ctrlgame_control_sprite\" block=\"%controller move $sprite=variables_get(mySprite) with buttons||vx $vx vy $vy\"\n        //% weight=100\n        //% expandableArgumentMode=\"toggle\"\n        //% vx.defl=100 vy.defl=100\n        //% help=controller/move-sprite\n        //% group=\"Multiplayer\"\n        //% vx.shadow=\"spriteSpeedPicker\"\n        //% vy.shadow=\"spriteSpeedPicker\"\n        //% parts=\"multiplayer\"\n        moveSprite(sprite: Sprite, vx: number = 100, vy: number = 100) {\n            this._moveSpriteInternal(sprite, vx, vy);\n        }\n\n        stopControllingSprite(sprite: Sprite) {\n            if (!sprite) return;\n            this._controlledSprites = this._controlledSprites.filter(s => s.s.id !== sprite.id);\n        }\n\n        // use this instead of movesprite internally to avoid adding the \"multiplayer\" part\n        // to the compiled program\n        _moveSpriteInternal(sprite: Sprite, vx: number = 100, vy: number = 100) {\n            if (!sprite) return;\n            if (!this._controlledSprites) this._controlledSprites = [];\n            let cp = this._controlledSprites.find(cp => cp.s.id == sprite.id);\n            if (!cp) {\n                cp = new ControlledSprite(sprite, vx, vy);\n                this._controlledSprites.push(cp);\n            }\n            if (cp.vx && vx == 0) {\n                cp.s.vx = 0\n            }\n            if (cp.vy && vy == 0) {\n                cp.s.vy = 0\n            }\n            cp.vx = vx;\n            cp.vy = vy;\n        }\n\n        private button(button: ControllerButton): Button {\n            return this.buttons[button - 1];\n        }\n\n        /**\n         * Run some code when a button is pressed, released, or held\n         */\n        //% weight=99 blockGap=8\n        //% blockId=ctrlonbuttonevent block=\"on %controller %button **button** %event\"\n        //% group=\"Multiplayer\"\n        //% help=controller/on-button-event\n        //% parts=\"multiplayer\"\n        onButtonEvent(btn: ControllerButton, event: ControllerButtonEvent, handler: () => void) {\n            this.button(btn).onEvent(event, handler);\n        }\n\n        /**\n         * Register code run when a controller event occurs\n         * @param event\n         * @param handler\n         */\n        //% weight=99 blockGap=8\n        //% blockId=ctrlonevent block=\"on %controller %event\"\n        //% group=\"Multiplayer\"\n        //% help=controller/on-event\n        //% parts=\"multiplayer\"\n        onEvent(event: ControllerEvent, handler: () => void) {\n            control.onEvent(this.id, event, handler);\n        }\n\n        get connected() {\n            return this._connected;\n        }\n\n        set connected(value: boolean) {\n            if (value != this._connected) {\n                this._connected = value;\n                control.raiseEvent(this.id, this._connected ? ControllerEvent.Connected : ControllerEvent.Disconnected);\n            }\n        }\n\n        /**\n         * Indicates if the button is currently pressed\n        */\n        //% weight=96 blockGap=8 help=controller/button/is-pressed\n        //% blockId=ctrlispressed block=\"is %controller %button **button** pressed\"\n        //% group=\"Multiplayer\"\n        //% parts=\"multiplayer\"\n        isPressed(btn: ControllerButton): boolean {\n            return this.button(btn).isPressed();\n        }\n\n        /**\n         * Get the horizontal movement, given the step and state of buttons\n         * @param step the distance, eg: 100\n         */\n        //% weight=50 blockGap=8 help=controller/dx\n        //% blockId=ctrldx block=\"%controller dx (left-right buttons)||scaled by %step\"\n        //% step.defl=100\n        //% group=\"Multiplayer\"\n        //% parts=\"multiplayer\"\n        dx(step: number = 100) {\n            return this._dxInternal(step);\n        }\n\n        // use this instead of dx internally to avoid adding the \"multiplayer\" part\n        // to the compiled program\n        _dxInternal(step: number = 100) {\n            const ctx = control.eventContext();\n            if (!ctx) return 0;\n\n            if (this.analog)\n                return (this.right.pressureLevel() - this.left.pressureLevel()) / 512 * ctx.deltaTime * step\n            if (this.left.isPressed()) {\n                if (this.right.isPressed()) return 0\n                else return -step * ctx.deltaTime;\n            }\n            else if (this.right.isPressed()) return step * ctx.deltaTime\n            else return 0\n        }\n\n        /**\n         * Get the vertical movement, given the step and state of buttons\n         * @param step the distance, eg: 100\n         */\n        //% weight=49 help=controller/dy\n        //% blockId=ctrldy block=\"%controller dy (up-down buttons)||scaled by %step\"\n        //% step.defl=100\n        //% group=\"Multiplayer\"\n        //% parts=\"multiplayer\"\n        dy(step: number = 100) {\n            return this._dyInternal(step);\n        }\n\n        // use this instead of dy internally to avoid adding the \"multiplayer\" part\n        // to the compiled program\n        _dyInternal(step: number = 100) {\n            const ctx = control.eventContext();\n            if (!ctx) return 0;\n\n            if (this.analog)\n                return (this.down.pressureLevel() - this.up.pressureLevel()) / 512 * ctx.deltaTime * step\n            if (this.up.isPressed()) {\n                if (this.down.isPressed()) return 0\n                else return -step * ctx.deltaTime;\n            }\n            else if (this.down.isPressed()) return step * ctx.deltaTime\n            else return 0\n        }\n\n        __preUpdate() {\n            if (!this._controlledSprites) return;\n\n            let deadSprites = false;\n\n            let svx = 0\n            let svy = 0\n\n            if (this.analog) {\n                svx = (this.right.pressureLevel() - this.left.pressureLevel()) >> 1\n                svy = (this.down.pressureLevel() - this.up.pressureLevel()) >> 1\n            } else {\n                svx = (this.right.isPressed() ? 256 : 0) - (this.left.isPressed() ? 256 : 0)\n                svy = (this.down.isPressed() ? 256 : 0) - (this.up.isPressed() ? 256 : 0)\n            }\n\n            let svxInCricle = svx\n            let svyInCircle = svy\n\n            // here svx/y are -256 to 256 range\n            const sq = svx * svx + svy * svy\n            // we want to limit svx/y to be within circle of 256 radius\n            const max = 256 * 256\n            // is it outside the circle?\n            if (sq > max) {\n                // if so, store the vector scaled down to fit in the circle\n                const scale = Math.sqrt(max / sq)\n                svxInCricle = scale * svx | 0\n                svyInCircle = scale * svy | 0\n            }\n\n            this._controlledSprites.forEach(controlledSprite => {\n                const { s, vx, vy } = controlledSprite;\n                if (s.flags & sprites.Flag.Destroyed) {\n                    deadSprites = true;\n                    return;\n                }\n\n                if (controlledSprite._inputLastFrame) {\n                    if (vx) s._vx = Fx.zeroFx8;\n                    if (vy) s._vy = Fx.zeroFx8;\n                }\n\n                if (svx || svy) {\n                    if (vx && vy) {\n                        // if moving in both vx/vy use speed vector constrained to be within circle\n                        s._vx = Fx.imul(svxInCricle as any as Fx8, vx)\n                        s._vy = Fx.imul(svyInCircle as any as Fx8, vy)\n                    } else if (vx) {\n                        // otherwise don't bother\n                        s._vx = Fx.imul(svx as any as Fx8, vx)\n                    } else if (vy) {\n                        s._vy = Fx.imul(svy as any as Fx8, vy)\n                    }\n                    controlledSprite._inputLastFrame = true;\n                }\n                else {\n                    controlledSprite._inputLastFrame = false;\n                }\n            });\n\n            if (deadSprites)\n                this._controlledSprites = this._controlledSprites\n                    .filter(s => !(s.s.flags & sprites.Flag.Destroyed));\n        }\n\n        __update(dtms: number) {\n            dtms = dtms | 0;\n            this.buttons.forEach(btn => btn.__update(dtms));\n        }\n\n        serialize(offset: number): Buffer {\n            const buf = control.createBuffer(offset + 1);\n            let b = 0;\n            for (let i = 0; this.buttons.length; ++i)\n                b |= (this.buttons[i].isPressed() ? 1 : 0) << i;\n            buf[offset] = b\n            return buf;\n        }\n    }\n\n    /**\n     * Called by the game engine to update and/or raise events\n     */\n    export function __update(dt: number) {\n        const dtms = (dt * 1000) | 0\n        players().forEach(ctrl => ctrl.__update(dtms));\n    }\n\n    export function serialize(offset: number): Buffer {\n        return _player1().serialize(offset);\n    }\n\n    /**\n     * Control a sprite using the direction buttons from the controller. Note that this\n     * control will take over the vx and vy of the sprite and overwrite any changes\n     * made unless a 0 is passed.\n     *\n     * @param sprite The Sprite to control\n     * @param vx The velocity used for horizontal movement when left/right is pressed\n     * @param vy The velocity used for vertical movement when up/down is pressed\n     */\n    //% blockId=\"game_control_sprite\" block=\"move $sprite=variables_get(mySprite) with buttons||vx $vx vy $vy\"\n    //% weight=100\n    //% expandableArgumentMode=\"toggle\"\n    //% vx.defl=100 vy.defl=100\n    //% help=controller/move-sprite\n    //% group=\"Single Player\"\n    //% vx.shadow=spriteSpeedPicker\n    //% vy.shadow=spriteSpeedPicker\n    export function moveSprite(sprite: Sprite, vx: number = 100, vy: number = 100) {\n        _player1()._moveSpriteInternal(sprite, vx, vy);\n    }\n\n    /**\n     * Get the horizontal movement, given the step and state of buttons\n     * @param step the distance, eg: 100\n     */\n    //% weight=50 blockGap=8 help=controller/dx\n    //% blockId=keydx block=\"dx (left-right buttons)||scaled by %step\"\n    //% step.defl=100\n    //% group=\"Single Player\"\n    export function dx(step: number = 100) {\n        return _player1()._dxInternal(step);\n    }\n\n    /**\n     * Get the vertical movement, given the step and state of buttons\n     * @param step the distance, eg: 100\n     */\n    //% weight=49 help=controller/dy\n    //% blockId=keydy block=\"dy (up-down buttons)||scaled by %step\"\n    //% step.defl=100\n    //% group=\"Single Player\"\n    export function dy(step: number = 100) {\n        return _player1()._dyInternal(step);\n    }\n\n    class AnyButton extends Button {\n        isPressed(): boolean {\n            const ctrl = _player1();\n\n            for (const b of ctrl.buttons) {\n                if (b.isPressed()) return true;\n            }\n            return false;\n        }\n    }\n\n    //% fixedInstance block=\"any\"\n    export const anyButton: Button = new AnyButton(0, -1);\n}\n","controllerbutton.ts":"enum ControllerButtonEvent {\n    //% block=\"pressed\"\n    Pressed = KEY_DOWN,\n    //% block=\"released\"\n    Released = KEY_UP,\n    //% block=\"repeat\"\n    Repeated = KEY_REPEAT\n}\n\nenum ControllerButton {\n    //% block=\"{id:controller}A\"\n    A = 5,\n    //% block=\"{id:controller}B\"\n    B = 6,\n    //% block=\"left\"\n    Left = 1,\n    //% block=\"up\"\n    Up = 2,\n    //% block=\"right\"\n    Right = 3,\n    //% block=\"down\"\n    Down = 4\n}\n\n/**\n * Access to game controls\n */\n//% weight=98 color=\"#D54322\" icon=\"\\uf11b\"\n//% groups='[\"Single Player\", \"Multiplayer\"]'\n//% blockGap=8\nnamespace controller {\n    let _userEventsEnabled = true;\n    let defaultRepeatDelay = 500;\n    let defaultRepeatInterval = 30;\n\n    //% shim=pxt::pressureLevelByButtonId\n    declare function pressureLevelByButtonId(btnId: number, codalId: number): number;\n\n    //% shim=pxt::setupButton\n    function setupButton(buttonId: number, key: number) {\n        return // missing in sim\n     }\n\n    export class ButtonHandler {\n        constructor(public event: number, public callback: () => void) { }\n    }\n\n    export class ButtonEventHandlerState {\n        constructor(public id: number) {};\n\n        public user: ButtonHandler[];\n        public system: ButtonHandler[];\n    }\n\n    //% fixedInstances\n    export class Button {\n        _owner: Controller;\n        public id: number;\n        //% help=controller/button/repeat-delay\n        public repeatDelay: number;\n        //% help=controller/button/repeat-interval\n        public repeatInterval: number;\n        private _pressed: boolean;\n        private _pressedElasped: number;\n        private _repeatCount: number;\n\n        protected get handlerState(): ButtonEventHandlerState {\n            for (const state of game.currentScene().buttonEventHandlers) {\n                if (state.id === this.id) return state;\n            }\n            return undefined;\n        }\n\n        toString(): string {\n            return `btn ${this.id} ${this._pressed ? \"down\" : \"up\"}`;\n        }\n\n        constructor(id: number, configKey: number) {\n            this.id = id;\n            this._pressed = false;\n            this.repeatDelay = undefined;\n            this.repeatInterval = undefined;\n            this._repeatCount = 0;\n\n            if (id > 0) {\n                // this is to deal with the \"anyButton\" hack, which creates a button that is not visible\n                // in the UI, but used in event-handler to simulate the wildcard ANY for matching. As\n                // this button can't actually be pressed, we don't want it to propagate events\n                control.internalOnEvent(INTERNAL_KEY_UP, this.id, () => this.setPressed(false), 16)\n                control.internalOnEvent(INTERNAL_KEY_DOWN, this.id, () => this.setPressed(true), 16)\n\n                if (configKey > 0)\n                    setupButton(id, configKey)\n            }\n        }\n\n        private raiseButtonUp() {\n            if (_userEventsEnabled)\n                control.raiseEvent(KEY_UP, this.id)\n            else\n                control.raiseEvent(SYSTEM_KEY_UP, this.id);\n        }\n\n        private raiseButtonDown() {\n            if (_userEventsEnabled)\n                control.raiseEvent(KEY_DOWN, this.id)\n            else\n                control.raiseEvent(SYSTEM_KEY_DOWN, this.id)\n        }\n\n        private raiseButtonRepeat() {\n            if (_userEventsEnabled)\n                control.raiseEvent(KEY_REPEAT, this.id)\n            else\n                control.raiseEvent(SYSTEM_KEY_REPEAT, this.id)\n        }\n\n        /**\n         * Run some code when a button is pressed, released, or held\n         */\n        //% weight=99 blockGap=8 help=controller/button/on-event\n        //% blockId=keyonevent block=\"on %button **button** %event\"\n        //% group=\"Single Player\"\n        onEvent(event: ControllerButtonEvent, handler: () => void) {\n            const eventHandler = this.getOrCreateHandlerForEvent(event);\n            eventHandler.callback = handler;\n        }\n\n        /**\n         * Adds an event handler that will fire whenever the specified event\n         * is triggered on this button. Handlers added using this method will\n         * not conflict with events added via onEvent. The same handler can\n         * not be added for the same event more than once.\n         *\n         * @param event     The event to subscribe to for this button\n         * @param handler   The code to run when the event triggers\n         */\n        addEventListener(event: ControllerButtonEvent, handler: () => void) {\n            this.getOrCreateHandlerForEvent(event);\n\n            const handlerState = this.handlerState;\n\n            if (!handlerState.system) handlerState.system = [];\n\n            for (const eventHandler of handlerState.system) {\n                if (eventHandler.event === event && eventHandler.callback === handler) return;\n            }\n\n            handlerState.system.push(new ButtonHandler(event, handler));\n        }\n\n        /**\n         * Removes an event handler registered with addEventListener.\n         *\n         * @param event     The event that the handler was registered for\n         * @param handler   The handler to remove\n         */\n        removeEventListener(event: ControllerButtonEvent, handler: () => void) {\n            const handlerState = this.handlerState;\n            if (!handlerState || !handlerState.system) return;\n\n            for (let i = 0; i < handlerState.system.length; i++) {\n                if (handlerState.system[i].event === event && handlerState.system[i].callback === handler) {\n                    handlerState.system.splice(i, 1)\n                    return;\n                }\n            }\n        }\n\n        /**\n         * Pauses until a button is pressed or released\n         */\n        //% weight=98 blockGap=8 help=controller/button/pause-until\n        // blockId=keypauseuntil block=\"pause until %button **button** is %event\"\n        //% group=\"Single Player\"\n        pauseUntil(event: ControllerButtonEvent) {\n            control.waitForEvent(event, this.id)\n        }\n\n        /**\n         * Indicates if the button is currently pressed\n         */\n        //% weight=96 blockGap=8 help=controller/button/is-pressed\n        //% blockId=keyispressed block=\"is %button **button** pressed\"\n        //% group=\"Single Player\"\n        isPressed() {\n            return this._pressed;\n        }\n\n        /**\n         * Indicates how hard the button is pressed, 0-512\n         */\n        pressureLevel() {\n            if (control.deviceDalVersion() == \"sim\") {\n                return this.isPressed() ? 512 : 0\n                // once implemented in sim, this could be similar to the one below\n            } else {\n                return pressureLevelByButtonId(this.id, -1);\n            }\n        }\n\n        setPressed(pressed: boolean) {\n            if (this._pressed != pressed) {\n                power.poke();\n                if (this._owner)\n                    this._owner.connected = true;\n                this._pressed = pressed;\n                if (this._pressed) {\n                    this._pressedElasped = 0;\n                    this.raiseButtonDown();\n                } else {\n                    this._repeatCount = 0;\n                    this.raiseButtonUp();\n                }\n            }\n        }\n\n        __update(dtms: number) {\n            if (!this._pressed) return;\n            this._pressedElasped += dtms;\n\n            const delay = this.repeatDelay === undefined ? defaultRepeatDelay : this.repeatDelay;\n            const interval = this.repeatInterval === undefined ? defaultRepeatInterval : this.repeatInterval;\n\n            // inital delay\n            if (this._pressedElasped < delay)\n                return;\n\n            // repeat count for this step\n            const count = Math.floor((this._pressedElasped - delay - interval) / interval);\n            if (count != this._repeatCount) {\n                this.raiseButtonRepeat();\n                this._repeatCount = count;\n            }\n        }\n\n        protected runButtonEvents(event: ControllerButtonEvent) {\n            const handlerState = this.handlerState;\n            if (!handlerState) return;\n\n            const userHandler = this.getOrCreateHandlerForEvent(event);\n            if (userHandler.callback) userHandler.callback();\n\n            if (handlerState.system) {\n                for (const eventHandler of handlerState.system) {\n                    if (eventHandler.event === event && eventHandler.callback) eventHandler.callback();\n                }\n            }\n        }\n\n        protected getOrCreateHandlerForEvent(event: ControllerButtonEvent) {\n            if (!this.handlerState) {\n                game.currentScene().buttonEventHandlers.push(new ButtonEventHandlerState(this.id));\n            }\n\n            const handlerState = this.handlerState;\n            if (!handlerState.user) handlerState.user = [];\n\n            for (const eventHandler of handlerState.user) {\n                if (eventHandler.event === event) {\n                    return eventHandler;\n                }\n            }\n\n            // Register actual handler if this hasn't been used before\n            control.onEvent(event, this.id, () => this.runButtonEvents(event));\n\n            const newHandler = new ButtonHandler(event, undefined);\n            handlerState.user.push(newHandler);\n            return newHandler;\n        }\n    }\n\n    /**\n     * Configures the timing of the on button repeat event for all of the controller buttons\n     * @param delay number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500\n     * @param interval minimum number of milliseconds between calls to the button repeat event, eg: 30\n     */\n    export function setRepeatDefault(delay: number, interval: number) {\n        defaultRepeatDelay = delay;\n        defaultRepeatInterval = interval;\n    }\n\n    /**\n     * Pause the program until a button is pressed\n     */\n    //% weight=10\n    export function pauseUntilAnyButtonIsPressed() {\n        control.waitForEvent(KEY_DOWN, 0)\n    }\n\n    export function _setUserEventsEnabled(enabled: boolean) {\n        _userEventsEnabled = enabled;\n    }\n}\n","controllerbuttons.cpp":"#include \"pxt.h\"\n\n#ifdef PXT_CODAL\n\nnamespace pxt {\n\nclass PressureButton : public codal::Button {\n  public:\n    PressureButton(Pin &pin, uint16_t id,\n                   ButtonEventConfiguration eventConfiguration = DEVICE_BUTTON_ALL_EVENTS,\n                   ButtonPolarity polarity = ACTIVE_LOW, PullMode mode = PullMode::None)\n        : Button(pin, id, eventConfiguration, polarity, mode) {}\n\n    virtual int pressureLevel() { return isPressed() ? 512 : 0; }\n};\n\nstruct AnalogCache {\n    AnalogCache *next;\n    Pin *pin;\n    uint32_t lastMeasureMS;\n    uint16_t lastMeasure;\n    AnalogCache(Pin *pin) : pin(pin) {\n        next = NULL;\n        lastMeasureMS = 0;\n        lastMeasure = pin->getAnalogValue();\n    }\n    uint16_t read();\n};\n\nuint16_t AnalogCache::read() {\n    uint32_t now = current_time_ms();\n    if (now - lastMeasureMS < 50)\n        return lastMeasure;\n    lastMeasureMS = now;\n    lastMeasure = pin->getAnalogValue();\n    return lastMeasure;\n}\n\nstatic AnalogCache *analogCache;\n\nclass AnalogButton : public PressureButton {\n  public:\n    AnalogCache *cache;\n    int16_t threshold;\n    bool state;\n\n    AnalogButton(AnalogCache *cache, uint16_t id, int threshold)\n        : PressureButton(*cache->pin, id), cache(cache), threshold(threshold), state(false) {}\n\n  protected:\n    virtual int pressureLevel() override {\n        int v = cache->read() - 512;\n        if (threshold < 0)\n            v = -v;\n        int vmin = getConfig(CFG_ANALOG_JOYSTICK_MIN, 50);\n        int vmax = getConfig(CFG_ANALOG_JOYSTICK_MAX, 500);\n        v = (v - vmin) * 512 / (vmax - vmin);\n        if (v < 0)\n            v = 0;\n        if (v > 512)\n            v = 512;\n        return v;\n    }\n\n    virtual int buttonActive() override {\n        int v = cache->read() - 512;\n        int thr = threshold;\n\n        if (thr < 0) {\n            v = -v;\n            thr = -thr;\n        }\n\n        if (v > thr)\n            state = true;\n        else if (state && v > thr * 3 / 4)\n            state = true;\n        else\n            state = false;\n\n        return state;\n    }\n};\n\nAnalogCache *lookupAnalogCache(Pin *pin) {\n    for (auto c = analogCache; c; c = c->next)\n        if (c->pin == pin)\n            return c;\n    auto c = new AnalogCache(pin);\n    c->next = analogCache;\n    analogCache = c;\n    return c;\n}\n\nint multiplexedButtonIsPressed(int btnId);\nint registerMultiplexedButton(int pin, int buttonId);\n\n//% expose\nint pressureLevelByButtonId(int btnId, int codalId) {\n    if (codalId <= 0)\n        codalId = DEVICE_ID_FIRST_BUTTON + btnId;\n    auto btn = (PressureButton *)lookupComponent(codalId);\n    if (!btn) {\n        return multiplexedButtonIsPressed(btnId) ? 512 : 0;\n    }\n    return btn->pressureLevel();\n}\n\nstatic void sendBtnDown(Event ev) {\n    Event(PXT_INTERNAL_KEY_DOWN, ev.source - DEVICE_ID_FIRST_BUTTON);\n}\n\nstatic void sendBtnUp(Event ev) {\n    Event(PXT_INTERNAL_KEY_UP, ev.source - DEVICE_ID_FIRST_BUTTON);\n}\n\n//% expose\nvoid setupButton(int buttonId, int key) {\n    int pin = getConfig(key);\n    if (pin == -1)\n        return;\n\n    unsigned highflags = (unsigned)pin >> 16;\n    int flags = BUTTON_ACTIVE_LOW_PULL_UP;\n    if (highflags & 0xff)\n        flags = highflags & 0xff;\n\n    pin &= 0xffff;\n\n    auto cpid = DEVICE_ID_FIRST_BUTTON + buttonId;\n    auto btn = (PressureButton *)lookupComponent(cpid);\n    if (btn == NULL) {\n        if (registerMultiplexedButton(pin, buttonId))\n            return;\n\n        if (1100 <= pin && pin < 1300) {\n            pin -= 1100;\n            int thr = getConfig(CFG_ANALOG_BUTTON_THRESHOLD, 300);\n            if (pin >= 100) {\n                thr = -thr;\n                pin -= 100;\n            }\n            btn = new AnalogButton(lookupAnalogCache(lookupPin(pin)), cpid, thr);\n        } else {\n            auto pull = PullMode::None;\n            if ((flags & 0xf0) == 0x10)\n                pull = PullMode::Down;\n            else if ((flags & 0xf0) == 0x20)\n                pull = PullMode::Up;\n            else if ((flags & 0xf0) == 0x30)\n                pull = PullMode::None;\n            else\n                oops(3);\n            btn = new PressureButton(*lookupPin(pin), cpid, DEVICE_BUTTON_ALL_EVENTS,\n                                     (ButtonPolarity)(flags & 0xf), pull);\n        }\n        EventModel::defaultEventBus->listen(btn->id, DEVICE_BUTTON_EVT_DOWN, sendBtnDown);\n        EventModel::defaultEventBus->listen(btn->id, DEVICE_BUTTON_EVT_UP, sendBtnUp);\n    }\n}\n\n} // namespace pxt\n\n#endif","controlleroverrides.ts":"namespace controller {\n    //% fixedInstance whenUsed block=\"{id:controller}A\"\n    export const A = new Button(ControllerButton.A, DAL.CFG_PIN_BTN_A);\n    //% fixedInstance whenUsed block=\"{id:controller}B\"\n    export const B = new Button(ControllerButton.B, DAL.CFG_PIN_BTN_B);\n    //% fixedInstance whenUsed block=\"left\"\n    export const left = new Button(ControllerButton.Left, DAL.CFG_PIN_BTN_LEFT);\n    //% fixedInstance whenUsed block=\"up\"\n    export const up = new Button(ControllerButton.Up, DAL.CFG_PIN_BTN_UP);\n    //% fixedInstance whenUsed block=\"right\"\n    export const right = new Button(ControllerButton.Right, DAL.CFG_PIN_BTN_RIGHT);\n    //% fixedInstance whenUsed block=\"down\"\n    export const down = new Button(ControllerButton.Down, DAL.CFG_PIN_BTN_DOWN);\n    //% fixedInstance whenUsed block=\"menu\"\n    export const menu = new Button(7, DAL.CFG_PIN_BTN_MENU);\n\n    //% fixedInstance whenUsed block=\"player 2\"\n    export const player2 = new Controller(2, undefined);\n    //% fixedInstance whenUsed block=\"player 3\"\n    export const player3 = new Controller(3, undefined);\n    //% fixedInstance whenUsed block=\"player 4\"\n    export const player4 = new Controller(4, undefined);\n    //% fixedInstance whenUsed block=\"player 1\"\n    export const player1 = controller._player1();\n}","effects.ts":"namespace effects {\n    //% fixedInstances\n    export class ImageEffect implements BackgroundEffect {\n\n        // If used in an animation, this should be used as the default delay between method calls\n        protected preferredDelay: number;\n        protected effect: (image: Image, fastRandom?: Math.FastRandom) => void;\n        protected fastRandom: Math.FastRandom;\n        private times: number;\n\n        constructor(defaultRate: number, effectFactory: (image: Image, fastRandom?: Math.FastRandom) => void) {\n            this.effect = effectFactory;\n            this.fastRandom = new Math.FastRandom();\n            this.preferredDelay = defaultRate;\n            this.times = undefined;\n        }\n\n        /**\n         * Apply this effect to the image of the current sprite\n         * @param sprite\n         */\n        applyTo(sprite: Sprite) {\n            if (!sprite || !sprite.image) return;\n            const clonedImage = sprite.image.clone();\n            this.change(clonedImage)\n            sprite.setImage(clonedImage);\n        }\n\n        /**\n         * Change the given image with this effect\n         * @param input \n         */\n        change(input: Image) {\n            this.effect(input, this.fastRandom);\n        }\n\n        /**\n         * Make this effect occur repeatedly on the background image\n         * @param times number of times effect should occur\n         * @param delay delay between instances of the effect\n         */\n        startScreenEffect(times?: number, delay?: number): void {\n            if (!game.currentScene().background.hasBackgroundImage()) return;\n            const wasRunning = this.times != undefined;\n            this.times = times ? times : 15;\n\n            if (!wasRunning) {\n                control.runInParallel(() => {\n                    while (this.times > 0) {\n                        this.change(scene.backgroundImage());\n                        pause(delay ? delay : this.preferredDelay);\n                        --this.times;\n                    }\n                    this.times = undefined;\n                });\n            }\n        }\n    }\n\n    //% fixedInstance whenUsed block=\"dissolve\"\n    export const dissolve = new ImageEffect(100, (input: Image, r: Math.FastRandom) => {\n        for (let i = (input.width * input.height) >> 5; i > 0; --i) {\n            const x = r.randomRange(0, input.width)\n            const y = r.randomRange(0, input.height)\n            const w = r.randomRange(1, 3);\n            const h = r.randomRange(1, 3);\n\n            input.drawRect(x, y, w, h, 0);\n        }\n    });\n\n    //% fixedInstance whenUsed block=\"melt\"\n    export const melt = new ImageEffect(125, (input: Image, r: Math.FastRandom) => {\n        const rounds = (input.width * input.height) >> 5;\n        for (let j = 0; j < rounds; ++j) {\n            let x = r.randomRange(0, input.width - 1)\n            let y = r.randomRange(0, input.height - 3)\n            let c = input.getPixel(x, y)\n            input.setPixel(x, y + 1, c)\n            input.setPixel(x, y + 2, c)\n        }\n    });\n\n    //% fixedInstance whenUsed block=\"slash\"\n    export const slash = new ImageEffect(125, (input: Image, r: Math.FastRandom) => {\n        const rounds = 12;\n        for (let j = 0; j < rounds; ++j) {\n            let horizontal = r.randomBool();\n            let length = r.randomRange(5, 50);\n            let x = r.randomRange(0, input.width - (horizontal ? length : 1));\n            let y = r.randomRange(0, input.height - (horizontal ? 3 : length));\n            input.drawLine(x, y, horizontal ? x + length : x, horizontal ? y : y + length, 1);\n        }\n    });\n\n    //% fixedInstance whenUsed block=\"splatter\"\n    export const splatter = new ImageEffect(125, (input: Image, r: Math.FastRandom) => {\n        const imgs: Image[] = [\n            img`\n            . 1 .\n            1 1 1\n            . 1 1`,\n            img`\n            . 1 1 .\n            1 1 1 1\n            . 1 1 .`,\n            img`\n            . 1 1 1 .\n            1 1 1 1 1\n            1 1 1 1 1\n            1 1 1 1 1\n            . 1 1 1 .`,\n            img`\n            . . 1 1 . .\n            . 1 1 1 1 .\n            1 1 1 1 1 1\n            1 1 1 1 1 1\n            . 1 1 1 1 .\n            . . 1 1 . .`,\n            img`\n            . . 1 1 1. .\n            . 1 1 1 1 1 .\n            1 1 1 1 1 1 1\n            1 1 1 1 1 1 1\n            1 1 1 1 1 1 1\n            . 1 1 1 1 1 .\n            . . 1 1 1. .`,\n            img`\n            . . 1 1 1 1 . .\n            . 1 1 1 1 1 1 .\n            1 1 1 1 1 1 1 1\n            1 1 1 1 1 1 1 1\n            1 1 1 1 1 1 1 1\n            1 1 1 1 1 1 1 1\n            . 1 1 1 1 1 1 .\n            . . 1 1 1 1 . .`,\n            img`\n            . . . 1 1 1 . . .\n            . . 1 1 1 1 1 . .\n            . 1 1 1 1 1 1 1 .\n            1 1 1 1 1 1 1 1 1\n            1 1 1 1 1 1 1 1 1\n            1 1 1 1 1 1 1 1 1\n            . 1 1 1 1 1 1 1 .\n            . . 1 1 1 1 1 . .\n            . . . 1 1 1 . . .`,\n        ];\n\n        const rounds = 12;\n        for (let j = 0; j < rounds; ++j) {\n            const im = imgs[r.randomRange(0, imgs.length - 1)];\n            const x = r.randomRange(0, input.width - im.width / 2);\n            const y = r.randomRange(0, input.height - im.height / 2);\n            input.drawTransparentImage(im, x, y);\n        }\n    });\n}","extendableSprite.ts":"namespace sprites {\n    /**\n     * A version of the Sprite class that is easier to extend.\n     * \n     * Unlike the normal Sprite class, this class will automatically add\n     * itself to the physics engine and run all sprite created handlers\n     * in the constructor\n     */\n    export class ExtendableSprite extends Sprite {\n        protected hasCustomDimensions: boolean;\n\n        constructor(spriteImage: Image, kind?: number) {\n            super(spriteImage);\n\n            const scene = game.currentScene();\n            this.setKind(kind);\n            scene.physicsEngine.addSprite(this);\n    \n            // run on created handlers\n            scene.createdHandlers\n                .filter(h => h.kind == kind)\n                .forEach(h => h.handler(this));\n\n            this.hasCustomDimensions = false;\n        }\n\n        /**\n         * Override to change how the sprite is drawn to the screen\n         * \n         * @param drawLeft The left position to draw the sprite at (already adjusted for camera)\n         * @param drawTop The top position to draw the sprite at (already adjusted for camera)\n         */\n        draw(drawLeft: number, drawTop: number) {\n            super.drawSprite(drawLeft, drawTop);\n        }\n\n        /**\n         * Override to add update logic for a sprite. This method runs once per frame\n         * \n         * @param deltaTimeMillis The time that has elapsed since the last frame in milliseconds\n         */\n        update(deltaTimeMillis: number) {\n        }\n\n        /**\n         * Sets the width and height of this sprite. Once set, this will also prevent\n         * this width and height from automatically changing whenever scale or the image\n         * changes\n         */\n        setDimensions(width: number, height: number) {\n            this._width = Fx8(width);\n            this._height = Fx8(height);\n            this.hasCustomDimensions = true;\n            this.resetHitbox();\n        }\n        \n        __update(camera: scene.Camera, dt: number) {\n            super.__update(camera, dt);\n            this.update(game.currentScene().eventContext.deltaTimeMillis)\n        }\n\n        setHitbox() {\n            if (this.hasCustomDimensions) {\n                this._hitbox = new game.Hitbox(this, this._width, this._height, Fx.zeroFx8, Fx.zeroFx8)\n            }\n            else {\n                super.setHitbox();\n            }\n        }\n\n        protected drawSprite(drawLeft: number, drawTop: number): void {\n            this.draw(drawLeft, drawTop);\n        }\n\n        protected recalcSize() {\n            if (this.hasCustomDimensions) return;\n            super.recalcSize();\n        }\n    }\n}","fieldeditors.ts":"namespace __internal {\n\n    /**\n     * A speed picker\n     * @param speed the speed, eg: 50\n     */\n    //% blockId=spriteSpeedPicker block=\"%speed\" shim=TD_ID\n    //% speed.fieldEditor=\"speed\" colorSecondary=\"#FFFFFF\"\n    //% weight=0 blockHidden=1 \n    //% speed.fieldOptions.decompileLiterals=1\n    //% speed.fieldOptions.format=\"{0}pix/s\"\n    export function __spriteSpeedPicker(speed: number): number {\n        return speed;\n    }\n\n    /**\n     * A sprite acceleration picker\n     * @param acceleration the acceleration in pixel/sec^2\n     */\n    //% blockId=spriteAccPicker block=\"%acceleration\" shim=TD_ID\n    //% speed.fieldEditor=\"speed\" colorSecondary=\"#FFFFFF\"\n    //% weight=0 blockHidden=1 \n    //% speed.fieldOptions.decompileLiterals=1\n    //% speed.fieldOptions.format=\"{0}pix/s²\"\n    export function __accSpeedPicker(acceleration: number): number {\n        return acceleration;\n    }\n}","game.ts":"/**\n * Game transitions and dialog\n **/\nnamespace game {\n    /**\n     * Determines if diagnostics are shown\n     */\n    export let debug = false;\n    export let stats = false;\n\n    export enum ScoringType {\n        //% block=\"high score\"\n        HighScore,\n        //% block=\"low score\"\n        LowScore,\n        //% block=\"none\"\n        None\n    }\n\n    // To stay synchronized with https://github.com/microsoft/pxt/blob/stable8.5/webapp/src/components/ImageEditor/sprite/Palette.tsx#L98.\n    /**\n     * The available colors for Arcade.\n     * NOTE: If the color palette is changed, these values will change along with it.\n     **/\n    export enum Color {\n        Transparent = 0,\n        White = 1,\n        Red = 2,\n        Pink = 3,\n        Orange = 4,\n        Yellow = 5,\n        Teal = 6,\n        Green = 7,\n        Blue = 8,\n        LightBlue = 9,\n        Purple = 0xa,\n        LightPurple = 0xb,\n        DarkPurple = 0xc,\n        Tan = 0xd,\n        Brown = 0xe,\n        Black = 0xf\n    }\n\n    export class GameOverConfig {\n        scoringType: ScoringType;\n        winEffect: effects.BackgroundEffect;\n        loseEffect: effects.BackgroundEffect;\n        loseSound: music.Playable;\n        winSound: music.Playable;\n        loseSoundLooping: boolean;\n        winSoundLooping: boolean;\n        winMessage: string;\n        winMessageMultiplayer: string;\n        loseMessage: string;\n        effectSetByUser: boolean;\n        soundSetByUser: boolean;\n        messageSetByUser: boolean;\n        scoringTypeSetByUser: boolean;\n\n        constructor() {\n            this.init();\n        }\n\n        init() {\n            this.scoringType = ScoringType.HighScore;\n            this.winEffect = effects.confetti;\n            this.loseEffect = effects.melt;\n            this.winSound = music.melodyPlayable(music.powerUp);\n            this.loseSound = music.melodyPlayable(music.wawawawaa);\n            this.winSoundLooping = false;\n            this.loseSoundLooping  = false;\n            this.winMessage = \"YOU WIN!\";\n            this.winMessageMultiplayer = \"${WINNER} WINS!\";\n            this.loseMessage = \"GAME OVER\";\n            this.effectSetByUser = false;\n            this.soundSetByUser = false;\n            this.messageSetByUser = false;\n            this.scoringTypeSetByUser = false;\n        }\n\n        setScoringType(type: ScoringType, explicit: boolean) {\n            if (!explicit && this.scoringTypeSetByUser) return;\n            this.scoringType = type;\n            if (explicit) this.scoringTypeSetByUser = true;\n        }\n\n        setEffect(win: boolean, effect: effects.BackgroundEffect, explicit: boolean) {\n            if (!explicit && this.effectSetByUser) return;\n            if (win) this.winEffect = effect;\n            else this.loseEffect = effect;\n            if (explicit) this.effectSetByUser = true;\n        }\n        getEffect(win: boolean) {\n            return win ? this.winEffect : this.loseEffect;\n        }\n\n        setSound(win: boolean, sound: music.Playable, looping: boolean, explicit: boolean) {\n            if (!explicit && this.soundSetByUser) return;\n            if (win) {\n                this.winSound = sound;\n                this.winSoundLooping = looping;\n            } else {\n                this.loseSound = sound;\n                this.loseSoundLooping = looping;\n            }\n            if (explicit) this.soundSetByUser = true;\n        }\n        getSound(win: boolean) {\n            return win ? this.winSound : this.loseSound;\n        }\n        getSoundLooping(win: boolean) {\n            return win ? this.winSoundLooping : this.loseSoundLooping;\n        }\n\n        setMessage(win: boolean, message: string, explicit: boolean) {\n            if (!explicit && this.messageSetByUser) return;\n            if (win) this.winMessage = message;\n            else this.loseMessage = message;\n            if (explicit) this.messageSetByUser = true;\n        }\n        getMessage(win: boolean, preferMultiplayer?: boolean) {\n            if (this.messageSetByUser)\n                return win ? this.winMessage : this.loseMessage;\n            else if (preferMultiplayer)\n                return win ? this.winMessageMultiplayer : this.loseMessage;\n            else\n                return win ? this.winMessage : this.loseMessage;\n        }\n    }\n\n    let _gameOverConfig: GameOverConfig;\n    export const gameOverConfig = () => {\n        if (!_gameOverConfig) _gameOverConfig = new GameOverConfig();\n        return _gameOverConfig;\n    }\n\n    let _scene: scene.Scene;\n    let _sceneStack: scene.Scene[];\n\n    let _scenePushHandlers: ((scene: scene.Scene) => void)[];\n    let _scenePopHandlers: ((scene: scene.Scene) => void)[];\n\n    export function currentScene(): scene.Scene {\n        init();\n        return _scene;\n    }\n\n    let __waitAnyButton: () => void;\n    let __gameOverHandler: (win: boolean) => void;\n    let __isOver = false;\n\n    export function setWaitAnyButton(f: () => void) {\n        __waitAnyButton = f\n    }\n\n    export function waitAnyButton() {\n        if (__waitAnyButton) __waitAnyButton()\n        else pause(3000)\n    }\n\n    export function eventContext(): control.EventContext {\n        init();\n        return _scene.eventContext;\n    }\n\n    function init(forceNewScene ?: boolean) {\n        if (!_scene || forceNewScene) {\n            _scene = new scene.Scene(control.pushEventContext(), _scene);\n        }\n        _scene.init();\n    }\n\n    export function pushScene() {\n        const oldScene = game.currentScene()\n        particles.clearAll();\n        particles.disableAll();\n        if (!_sceneStack) _sceneStack = [];\n        _sceneStack.push(_scene);\n        init(/** forceNewScene **/ true);\n\n        if (_scenePushHandlers) {\n            _scenePushHandlers.forEach(cb => cb(oldScene));\n        }\n    }\n\n    export function popScene() {\n        const oldScene = game.currentScene()\n        if (_sceneStack && _sceneStack.length) {\n            // pop scenes from the stack\n            _scene = _sceneStack.pop();\n            control.popEventContext();\n        } else if (_scene) {\n            // post last scene\n            control.popEventContext();\n            _scene = undefined;\n        }\n\n        if (_scene)\n            particles.enableAll();\n\n        if (_scenePopHandlers) {\n            _scenePopHandlers.forEach(cb => cb(oldScene));\n        }\n    }\n\n    function showDialogBackground(h: number, c: number) {\n        const top = (screen.height - h) >> 1;\n        screen.fillRect(0, top, screen.width, h, 0)\n        screen.drawLine(0, top, screen.width, top, 1)\n        screen.drawLine(0, top + h - 1, screen.width, top + h - 1, 1)\n\n        return top;\n    }\n\n    export function showDialog(title: string, subtitle: string, footer?: string) {\n        init();\n        const titleFont = image.getFontForText(title || \"\");\n        const subFont = image.getFontForText(subtitle || \"\")\n        const footerFont = image.getFontForText(footer || \"\");\n        let h = 8;\n        if (title)\n            h += titleFont.charHeight;\n        if (subtitle)\n            h += 2 + subFont.charHeight\n        h += 8;\n        const top = showDialogBackground(h, 9)\n        let y = top + 8;\n        if (title) {\n            screen.print(title, 8, y, screen.isMono ? 1 : 7, titleFont);\n            y += titleFont.charHeight + 2;\n        }\n        if (subtitle) {\n            screen.print(subtitle, 8, y, screen.isMono ? 1 : 6, subFont);\n            y += subFont.charHeight + 2;\n        }\n        if (footer) {\n            const footerTop = screen.height - footerFont.charHeight - 4;\n            screen.fillRect(0, footerTop, screen.width, footerFont.charHeight + 4, 0);\n            screen.drawLine(0, footerTop, screen.width, footerTop, 1);\n            screen.print(\n                footer,\n                screen.width - footer.length * footerFont.charWidth - 8,\n                screen.height - footerFont.charHeight - 2,\n                1,\n                footerFont\n            )\n        }\n    }\n\n    /**\n     * Set the effect that occurs when the game is over\n     * @param win whether the effect should run on a win (true) or lose (false)\n     * @param effect\n     */\n    //% blockId=game_setgameovereffect\n    //% block=\"use effect $effect for $win\"\n    //% effect.defl=effects.confetti\n    //% win.shadow=toggleWinLose\n    //% win.defl=true\n    //% group=\"Game Over\"\n    //% weight=90\n    //% blockGap=8\n    //% help=game/set-game-over-effect\n    export function setGameOverEffect(win: boolean, effect: effects.BackgroundEffect) {\n        init();\n        const goc = game.gameOverConfig();\n        goc.setEffect(win, effect, true);\n    }\n\n    /**\n     * Set the music that occurs when the game is over\n     * @param win whether the sound should play on a win (true) or lose (false)\n     * @param effect\n     */\n    //% blockId=game_setgameoverplayable\n    //% block=\"use $sound looping $looping for $win\"\n    //% sound.shadow=music_melody_playable\n    //% sound.defl=music.powerUp\n    //% looping.shadow=toggleOnOff\n    //% looping.defl=false\n    //% win.shadow=toggleWinLose\n    //% win.defl=true\n    //% group=\"Game Over\"\n    //% weight=80\n    //% blockGap=8\n    //% help=game/set-game-over-playable\n    export function setGameOverPlayable(win: boolean, sound: music.Playable, looping: boolean) {\n        init();\n        const goc = game.gameOverConfig();\n        goc.setSound(win, sound, looping, true);\n    }\n\n    // Legacy api. Older extensions may still use this.\n    export function setGameOverSound(win: boolean, sound: music.Melody) {\n        init();\n        const goc = game.gameOverConfig();\n        goc.setSound(win, music.melodyPlayable(sound), false, true);\n    }\n\n    /**\n     * Set the message that displays when the game is over\n     * @param win whether the message should show on a win (true) or lose (false)\n     * @param message \n     */\n    //% blockId=game_setgameovermessage\n    //% block=\"use message $message for $win\"\n    //% message.defl=\"GAME OVER!\"\n    //% win.shadow=toggleWinLose\n    //% win.defl=true\n    //% group=\"Game Over\"\n    //% weight=70\n    //% blockGap=8\n    //% help=game/set-game-over-message\n    export function setGameOverMessage(win: boolean, message: string) {\n        init();\n        const goc = game.gameOverConfig();\n        goc.setMessage(win, message, true);\n    }\n\n    /**\n     * Set the method of judging the best score for the game\n     * @param type the scoring type\n     */\n    //% blockId=game_setgameoverscoringtype\n    //% block=\"use $type as best score\"\n    //% type.defl=ScoringType.HighScore\n    //% group=\"Game Over\"\n    //% weight=60\n    //% blockGap=8\n    //% help=game/set-game-over-scoring-type\n    export function setGameOverScoringType(type: ScoringType) {\n        init();\n        const goc = game.gameOverConfig();\n        goc.setScoringType(type, true);\n    }\n\n    /**\n     * Set the function to call on game over. The 'win' boolean is\n     * passed to the handler.\n     * @param handler\n     */\n    export function onGameOver(handler: (win: boolean) => void) {\n        __gameOverHandler = handler;\n    }\n\n    /**\n     * Finish the game and display the score\n     */\n    //% group=\"Gameplay\"\n    //% blockId=gameOver block=\"game over %win=toggleWinLose || with %effect effect\"\n    //% weight=80 help=game/over\n    //% deprecated=true\n    export function over(win: boolean = false, effect?: effects.BackgroundEffect) {\n        // Match legacy behavior unless effect was set by user\n        const goc = game.gameOverConfig();\n        goc.setEffect(win, effect, false);\n        _gameOverImpl(win);\n    }\n\n    //% blockId=gameOver2 block=\"game over $win\"\n    //% win.shadow=toggleWinLose\n    //% win.defl=true\n    //% weight=100\n    //% blockGap=8\n    //% help=game/over\n    //% group=\"Game Over\"\n    export function gameOver(win: boolean) {\n        _gameOverImpl(win);\n    }\n\n    export function gameOverPlayerWin(player: number) {\n        _gameOverImpl(true, player);\n    }\n\n    function _mapScoreTypeToString(scoreType: ScoringType): string {\n        switch (scoreType) {\n            case ScoringType.HighScore: return \"highscore\";\n            case ScoringType.LowScore: return \"lowscore\";\n            case ScoringType.None: return \"none\";\n            default: return \"none\";\n        }\n    }\n\n    function _gameOverImpl(win: boolean, winnerOverride?: number) {\n        init();\n        if (__isOver) return;\n        __isOver = true;\n\n        if (__gameOverHandler) {\n            __gameOverHandler(win);\n        } else {\n            const goc = game.gameOverConfig();\n\n            const judged = !winnerOverride && goc.scoringType !== ScoringType.None;\n            const playersWithScores = info.playersWithScores();\n            const prevBestScore = judged && info.highScore();\n            const winner = judged && win && info.winningPlayer();\n            const scores = playersWithScores.map(player => new GameOverPlayerScore(player.number, player.impl.score(), player === winner));\n\n            // Save all scores. Dependency Note: this action triggers Kiosk to exit the simulator and show the high score screen.\n            const scoreTypeString = _mapScoreTypeToString(goc.scoringType);\n            info.saveAllScores(scoreTypeString);\n\n            // Save high score if this was a judged game and there was a winner (don't save in the LOSE case).\n            if (judged && winner) {\n                info.saveHighScore();\n            }\n\n            const preferMultiplayer = !!winnerOverride || (judged && info.multiplayerScoring());\n            const message = goc.getMessage(win, preferMultiplayer);\n            const effect = goc.getEffect(win);\n            const sound = goc.getSound(win);\n            const looping = goc.getSoundLooping(win);\n            const playbackMode = looping ? music.PlaybackMode.LoopingInBackground : music.PlaybackMode.InBackground;\n\n            // releasing memory and clear fibers. Do not add anything that releases the fiber until background is set below,\n            // or screen will be cleared on the new frame and will not appear as background in the game over screen.\n            while (_sceneStack && _sceneStack.length) {\n                _scene.destroy();\n                popScene();\n            }\n            pushScene();\n            scene.setBackgroundImage(screen.clone());\n\n            if (sound) music.play(sound, playbackMode);\n            if (effect) effect.startScreenEffect();\n\n            pause(400);\n\n            const overDialog = new GameOverDialog(win, message, judged, scores, prevBestScore, winnerOverride);\n            scene.createRenderable(scene.HUD_Z, target => {\n                overDialog.update();\n                target.drawTransparentImage(\n                    overDialog.image,\n                    0,\n                    (screen.height - overDialog.image.height) >> 1\n                );\n            });\n\n            pause(500); // wait for users to stop pressing keys\n            overDialog.displayCursor();\n            waitAnyButton();\n            control.reset();\n        }\n    }\n\n\n    // Indicates whether the fiber needs to be created\n    let foreverRunning = false;\n\n    /**\n     * Repeats the code forever in the background for this scene.\n     * On each iteration, allows other codes to run.\n     * @param body code to execute\n     */\n    export function forever(action: () => void): void {\n        if (!foreverRunning) {\n            foreverRunning = true;\n            control.runInParallel(() => {\n                while (1) {\n                    const handlers = game.currentScene().gameForeverHandlers;\n                    handlers.forEach(h => {\n                        if (!h.lock) {\n                            h.lock = true;\n                            control.runInParallel(() => {\n                                h.handler();\n                                h.lock = false;\n                            });\n                        }\n                    });\n                    pause(20);\n                }\n            });\n        }\n\n        game.currentScene().gameForeverHandlers.push(\n            new scene.GameForeverHandler(action)\n        );\n    }\n\n    /**\n     * Draw on screen before sprites, after background\n     * @param body code to execute\n     */\n    //% group=\"Gameplay\"\n    //% help=game/paint weight=10 afterOnStart=true\n    export function onPaint(a: () => void): void {\n        init();\n        if (!a) return;\n        scene.createRenderable(scene.ON_PAINT_Z, a);\n    }\n\n    /**\n     * Draw on screen after sprites\n     * @param body code to execute\n     */\n    //% group=\"Gameplay\"\n    //% help=game/shade weight=10 afterOnStart=true\n    export function onShade(a: () => void): void {\n        init();\n        if (!a) return;\n        scene.createRenderable(scene.ON_SHADE_Z, a);\n    }\n\n\n    /**\n     * Register a handler that runs whenever a scene is pushed onto the scene\n     * stack. Useful for extensions that need to store/restore state as the\n     * event context changes. The handler is run AFTER the push operation (i.e.\n     * after game.currentScene() has changed)\n     *\n     * @param handler Code to run when a scene is pushed onto the stack\n     */\n    export function addScenePushHandler(handler: (oldScene: scene.Scene) => void) {\n        if (!_scenePushHandlers) _scenePushHandlers = [];\n        if (_scenePushHandlers.indexOf(handler) < 0)\n            _scenePushHandlers.push(handler);\n    }\n\n    /**\n     * Remove a scene push handler. Useful for extensions that need to store/restore state as the\n     * event context changes.\n     *\n     * @param handler The handler to remove\n     */\n    export function removeScenePushHandler(handler: (oldScene: scene.Scene) => void) {\n        if (_scenePushHandlers) _scenePushHandlers.removeElement(handler);\n    }\n\n    /**\n     * Register a handler that runs whenever a scene is popped off of the scene\n     * stack. Useful for extensions that need to store/restore state as the\n     * event context changes. The handler is run AFTER the pop operation. (i.e.\n     * after game.currentScene() has changed)\n     *\n     * @param handler Code to run when a scene is removed from the top of the stack\n     */\n    export function addScenePopHandler(handler: (oldScene: scene.Scene) => void) {\n        if (!_scenePopHandlers) _scenePopHandlers = [];\n        if (_scenePopHandlers.indexOf(handler) < 0)\n            _scenePopHandlers.push(handler);\n    }\n\n    /**\n     * Remove a scene pop handler. Useful for extensions that need to store/restore state as the\n     * event context changes.\n     *\n     * @param handler The handler to remove\n     */\n    export function removeScenePopHandler(handler: (oldScene: scene.Scene) => void) {\n        if (_scenePopHandlers) _scenePopHandlers.removeElement(handler);\n    }\n}\n","gameoverrides.ts":"/**\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=loops/forever weight=100 afterOnStart=true blockNamespace=\"loops\"\n//% blockId=forever block=\"forever\" blockAllowMultiple=1\nfunction forever(a: () => void): void {\n    game.forever(a);\n}\n\n// micro:bit compatibility\n// these functions allow some level of reuse\n// between micro:bit and other maker-style editors\nnamespace basic {\n    export function forever(a: () => void) {\n        game.forever(a);\n    }\n}","gameutil.ts":"/**\n * Game transitions and dialog\n **/\nnamespace game {\n\n    /**\n     * Update the position and velocities of sprites\n     * @param body code to execute\n     */\n    //% group=\"Gameplay\"\n    //% help=game/on-update weight=100 afterOnStart=true\n    //% blockId=gameupdate block=\"on game update\"\n    //% blockAllowMultiple=1\n    export function onUpdate(a: () => void): void {\n        if (!a) return;\n        game.eventContext().registerFrameHandler(scene.UPDATE_PRIORITY, a);\n    }\n\n    /**\n     * Run code on an interval of time. This executes before game.onUpdate()\n     * @param body code to execute\n     */\n    //% group=\"Gameplay\"\n    //% help=game/on-update-interval weight=99 afterOnStart=true\n    //% blockId=gameinterval block=\"on game update every %period=timePicker ms\"\n    //% blockAllowMultiple=1\n    export function onUpdateInterval(period: number, a: () => void): void {\n        if (!a || period < 0) return;\n        let timer = 0;\n        game.eventContext().registerFrameHandler(scene.UPDATE_INTERVAL_PRIORITY, () => {\n            const time = game.currentScene().millis();\n            if (timer <= time) {\n                timer = time + period;\n                a();\n            }\n        });\n    }\n\n    /**\n     * Returns the time since the game started in milliseconds\n     */\n    //% blockId=arcade_game_runtime block=\"time since start (ms)\"\n    //% group=\"Gameplay\" weight=11\n    //% help=game/runtime\n    export function runtime(): number {\n        return currentScene().millis();\n    }\n}\n","hitbox.ts":"namespace game {\n    export class Hitbox {\n        hash: number;\n        parent: Sprite;\n        ox: Fx8;\n        oy: Fx8;\n        width: Fx8;\n        height: Fx8;\n\n        constructor(parent: Sprite, width: Fx8, height: Fx8, ox: Fx8, oy: Fx8) {\n            this.hash = parent.calcDimensionalHash();\n            this.parent = parent;\n            this.width = width;\n            this.height = height;\n            this.ox = ox;\n            this.oy = oy;\n        }\n\n        get left() {\n            return Fx.add(this.ox, this.parent._x);\n        }\n\n        get top() {\n            return Fx.add(this.oy, this.parent._y);\n        }\n\n        get right() {\n            return Fx.sub(\n                Fx.add(this.width, this.left),\n                Fx.oneFx8\n            );\n        }\n\n        get bottom() {\n            return Fx.sub(\n                Fx.add(this.height, this.top),\n                Fx.oneFx8\n            );\n        }\n\n        isValid() {\n            return this.hash === this.parent.calcDimensionalHash();\n        }\n\n        contains(x: Fx8, y: Fx8): boolean {\n            return (x >= this.left) && (x <= this.right) && (y >= this.top) && (y <= this.bottom);\n        }\n\n        updateIfInvalid() {\n            if (this.isValid())\n                return;\n\n            const newHitBox = game.calculateHitBox(this.parent);\n\n            const oMinX = this.ox;\n            const oMinY = this.oy;\n            const oMaxX = Fx.add(oMinX, this.width);\n            const oMaxY = Fx.add(oMinY, this.height);\n\n            const nMinX = newHitBox.ox;\n            const nMinY = newHitBox.oy;\n            const nMaxX = Fx.add(nMinX, newHitBox.width);\n            const nMaxY = Fx.add(nMinY, newHitBox.height);\n\n            // total diff in x / y corners between the two hitboxes\n            const xDiff = Fx.add(\n                Fx.abs(Fx.sub(oMinX, nMinX)),\n                Fx.abs(Fx.sub(oMaxX, nMaxX))\n            );\n            const yDiff = Fx.add(\n                Fx.abs(Fx.sub(oMinY, nMinY)),\n                Fx.abs(Fx.sub(oMaxY, nMaxY))\n            );\n\n            // If it's just a small change to the hitbox on one axis,\n            // don't change the dimensions to avoid random clipping\n            if (xDiff > Fx.twoFx8) {\n                this.ox = nMinX;\n                this.width = newHitBox.width;\n            }\n            if (yDiff > Fx.twoFx8) {\n                this.oy = nMinY;\n                this.height = newHitBox.height;\n            }\n            this.hash = newHitBox.hash;\n        }\n\n        overlapsWith(other: Hitbox): boolean {\n            this.updateIfInvalid();\n            other.updateIfInvalid();\n            if (this.contains(other.left, other.top)) return true;\n            if (this.contains(other.left, other.bottom)) return true;\n            if (this.contains(other.right, other.top)) return true;\n            if (this.contains(other.right, other.bottom)) return true;\n            if (other.contains(this.left, this.top)) return true;\n            if (other.contains(this.left, this.bottom)) return true;\n            if (other.contains(this.right, this.top)) return true;\n            if (other.contains(this.right, this.bottom)) return true;\n            return false;\n        }\n    }\n\n\n    export function calculateHitBox(s: Sprite): Hitbox {\n        if (s._hitbox && s._hitbox.isValid())\n            return s._hitbox;\n\n        const i = s.image;\n        let minX = Fx8(i.width);\n        let minY = Fx8(i.height);\n        let maxX = Fx.zeroFx8;\n        let maxY = Fx.zeroFx8;\n\n        for (let c = 0, fxc = Fx.zeroFx8; c < i.width; c++, fxc = Fx.add(fxc, Fx.oneFx8)) {\n            for (let r = 0, fxr = Fx.zeroFx8; r < i.height; r++, fxr = Fx.add(fxr, Fx.oneFx8)) {\n                if (i.getPixel(c, r)) {\n                    minX = Fx.min(minX, fxc);\n                    minY = Fx.min(minY, fxr);\n                    maxX = Fx.max(maxX, fxc);\n                    maxY = Fx.max(maxY, fxr);\n                }\n            }\n        }\n\n        minX = Fx.mul(minX, s._sx);\n        minY = Fx.mul(minY, s._sy);\n        maxX = Fx.mul(maxX, s._sx);\n        maxY = Fx.mul(maxY, s._sy);\n        const width  = Fx.add(Fx.sub(maxX, minX), s._sx);\n        const height = Fx.add(Fx.sub(maxY, minY), s._sy);\n\n        return new Hitbox(s, width, height, Fx.floor(minX), Fx.floor(minY));\n    }\n}","info.ts":"\n/**\n * Head-up display\n *\n*/\n//% color=#cf6a87 weight=80 icon=\"\\uf2bb\" blockGap=8\n//% groups='[\"Score\", \"Life\", \"Countdown\", \"Multiplayer\"]'\n//% blockGap=8\nnamespace info {\n\n    export enum Visibility {\n        None = 0,\n        Countdown = 1 << 0,\n        Score = 1 << 1,\n        Life = 1 << 2,\n        Hud = 1 << 3,\n        Multi = 1 << 4,\n        UserHeartImage = 1 << 5,\n        _ExplicitlySetScore = 1 << 6,\n        _ExplicitlySetLife = 1 << 7,\n    }\n\n    class ScoreReachedHandler {\n        public isTriggered: boolean;\n        constructor(public score: number, public handler: () => void) {\n            this.isTriggered = false;\n        }\n    }\n\n    export class PlayerState {\n        public score: number;\n        // undefined: not used\n        // null: reached 0 and callback was invoked\n        public life: number;\n        public lifeZeroHandler: () => void;\n        public scoreReachedHandlers: ScoreReachedHandler[];\n\n        public showScore?: boolean;\n        public showLife?: boolean;\n        public visibility: Visibility;\n        public showPlayer?: boolean;\n\n        constructor() {\n            this.visibility = Visibility.None;\n            this.showScore = undefined;\n            this.showLife = undefined;\n            this.showPlayer = undefined;\n            this.scoreReachedHandlers = [];\n        }\n    }\n\n    class InfoState {\n        public playerStates: PlayerState[];\n        public visibilityFlag: number;\n\n        public gameEnd: number;\n        public heartImage: Image;\n        public multiplierImage: Image;\n        public bgColor: number;\n        public borderColor: number;\n        public fontColor: number;\n        public countdownExpired: boolean;\n        public countdownEndHandler: () => void;\n\n        constructor() {\n            this.visibilityFlag = Visibility.Hud;\n            this.playerStates = [];\n            this.heartImage = defaultHeartImage();\n            this.multiplierImage = img`\n                1 . . . 1\n                . 1 . 1 .\n                . . 1 . .\n                . 1 . 1 .\n                1 . . . 1\n            `;\n            this.bgColor = screen.isMono ? 0 : 1;\n            this.borderColor = screen.isMono ? 1 : 3;\n            this.fontColor = screen.isMono ? 1 : 3;\n            this.countdownExpired = undefined;\n            this.countdownEndHandler = undefined;\n            this.gameEnd = undefined;\n            this.playerStates = [];\n        }\n    }\n\n    let infoState: InfoState = undefined;\n\n    let players: PlayerInfo[];\n\n    let infoStateStack: {\n        state: InfoState,\n        scene: scene.Scene\n    }[];\n\n    game.addScenePushHandler(oldScene => {\n        if (infoState) {\n            if (!infoStateStack) infoStateStack = [];\n            infoStateStack.push({\n                state: infoState,\n                scene: oldScene\n            });\n            infoState = undefined;\n        }\n    });\n\n    game.addScenePopHandler(() => {\n        const scene = game.currentScene();\n        infoState = undefined;\n        if (infoStateStack && infoStateStack.length) {\n            const nextState = infoStateStack.pop();\n            if (nextState.scene == scene) {\n                infoState = nextState.state;\n            } else {\n                infoStateStack.push(nextState);\n            }\n        }\n    });\n\n    function initHUD() {\n        if (infoState) return;\n\n        infoState = new InfoState();\n\n        scene.createRenderable(\n            scene.HUD_Z,\n            () => {\n                if (!infoState) return;\n                control.enablePerfCounter(\"info\")\n                // show score, lifes\n                if (infoState.visibilityFlag & Visibility.Multi) {\n                    const ps = players.filter(p => !!p);\n                    // First draw players\n                    ps.forEach(p => p.drawPlayer());\n                    // Then run life over events\n                    ps.forEach(p => p.impl.raiseLifeZero(false));\n                } else { // single player\n                    // show score\n                    const p = player1;\n                    if (p.impl.hasScore() && (infoState.visibilityFlag & Visibility.Score)) {\n                        p.drawScore();\n                    }\n                    // show life\n                    if (p.impl.hasLife() && (infoState.visibilityFlag & Visibility.Life)) {\n                        p.drawLives();\n                    }\n                    p.impl.raiseLifeZero(true);\n                }\n                // show countdown in both modes\n                if (infoState.gameEnd !== undefined && infoState.visibilityFlag & Visibility.Countdown) {\n                    const scene = game.currentScene();\n                    const elapsed = infoState.gameEnd - scene.millis();\n                    drawTimer(elapsed);\n                    let t = elapsed / 1000;\n                    if (t <= 0) {\n                        t = 0;\n                        if (!infoState.countdownExpired) {\n                            infoState.countdownExpired = true;\n                            infoState.gameEnd = undefined;\n                            if (infoState.countdownEndHandler) {\n                                infoState.countdownEndHandler();\n                            } else {\n                                // Clear effect and sound, unless set by user\n                                const goc = game.gameOverConfig();\n                                goc.setEffect(false, null, false);\n                                goc.setSound(false, null, false, false);\n                                game.gameOver(false);\n                            }\n                        }\n                    }\n                }\n            }\n        );\n    }\n\n    function initMultiHUD() {\n        if (infoState.visibilityFlag & Visibility.Multi) return;\n\n        infoState.visibilityFlag |= Visibility.Multi;\n        if (!(infoState.visibilityFlag & Visibility.UserHeartImage))\n            infoState.heartImage = defaultMultiplayerHeartImage();\n        infoState.multiplierImage = img`\n            1 . 1\n            . 1 .\n            1 . 1\n        `;\n    }\n\n    function defaultHeartImage() {\n        return screen.isMono ?\n            img`\n                . 1 1 . 1 1 . .\n                1 . . 1 . . 1 .\n                1 . . . . . 1 .\n                1 . . . . . 1 .\n                . 1 . . . 1 . .\n                . . 1 . 1 . . .\n                . . . 1 . . . .\n            `\n            :\n            img`\n                . c 2 2 . 2 2 .\n                c 2 2 2 2 2 4 2\n                c 2 2 2 2 4 2 2\n                c 2 2 2 2 2 2 2\n                . c 2 2 2 2 2 .\n                . . c 2 2 2 . .\n                . . . c 2 . . .\n            `;\n    }\n\n    function defaultMultiplayerHeartImage() {\n        return screen.isMono ?\n            img`\n                    . . 1 . 1 . .\n                    . 1 . 1 . 1 .\n                    . 1 . . . 1 .\n                    . . 1 . 1 . .\n                    . . . 1 . . .\n                `\n            :\n            img`\n                    . . 1 . 1 . .\n                    . 1 2 1 4 1 .\n                    . 1 2 4 2 1 .\n                    . . 1 2 1 . .\n                    . . . 1 . . .\n                `;\n    }\n\n    export function multiplayerScoring() {\n        const pws = playersWithScores();\n        for (const p of pws) {\n            if (p.number > 1) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    export function playersWithScores(): PlayerInfo[] {\n        return players ? players.filter(item => item.impl.hasScore()) : [];\n    }\n\n    export function saveAllScores(scoringType: string) {\n        const allScoresKey = \"all-scores\";\n        let allScores: number[];\n        const pws = playersWithScores();\n        if (pws) {\n            allScores = pws.map(item => item.impl.score());\n        }\n        else {\n            allScores = [];\n        }\n\n        const scoresObj = {\n            \"allScores\": allScores,\n            \"scoringType\": allScores.length ? scoringType : \"None\"\n        }\n\n        settings.writeJSON(allScoresKey, scoresObj);\n    }\n\n    export function winningPlayer(): PlayerInfo {\n        let winner: PlayerInfo = null;\n        const pws = playersWithScores();\n        if (pws) {\n            const goc = game.gameOverConfig();\n            let hs: number = null;\n            pws.forEach(p => {\n                const s = p.impl.score();\n                if (isBetterScore(s, hs)) {\n                    hs = s;\n                    winner = p;\n                }\n            });\n        }\n        return winner;\n    }\n\n    export function isBetterScore(newScore: number, prevScore: number): boolean {\n        const goc = game.gameOverConfig();\n        switch (goc.scoringType) {\n            case game.ScoringType.HighScore: {\n                return prevScore == null || newScore > prevScore;\n            }\n            case game.ScoringType.LowScore: {\n                return prevScore == null || newScore < prevScore;\n            }\n        }\n        return false;\n    }\n\n    export function saveHighScore() {\n        const winner = winningPlayer();\n        if (winner) {\n            let hs = winner.impl.score();\n            let curr = settings.readNumber(\"high-score\");\n            if (isBetterScore(hs, curr)) {\n                settings.writeNumber(\"high-score\", hs);\n            }\n        }\n    }\n\n    /**\n     * Get the current score if any\n     */\n    //% weight=95 blockGap=8\n    //% blockId=hudScore block=\"score\"\n    //% help=info/score\n    //% group=\"Score\"\n    export function score() {\n        return player1.impl.score();\n    }\n\n    //%\n    //% group=\"Score\"\n    export function hasScore() {\n        return player1.impl.hasScore();\n    }\n\n    /**\n     * Get the last recorded high score\n     */\n    //% weight=94\n    //% blockId=highScore block=\"high score\"\n    //% help=info/high-score\n    //% group=\"Score\"\n    export function highScore(): number {\n        return settings.readNumber(\"high-score\") || 0;\n    }\n\n    /**\n     * Set the score\n     */\n    //% weight=93 blockGap=8\n    //% blockId=hudsetScore block=\"set score to %value\"\n    //% help=info/set-score\n    //% group=\"Score\"\n    export function setScore(value: number) {\n        player1.impl.setScore(value);\n    }\n\n    /**\n     * Change the score by the given amount\n     * @param value the amount of change, eg: 1\n     */\n    //% weight=92\n    //% blockId=hudChangeScoreBy block=\"change score by %value\"\n    //% help=info/change-score-by\n    //% group=\"Score\"\n    export function changeScoreBy(value: number) {\n        player1.impl.changeScoreBy(value);\n    }\n\n    /**\n     * Get the number of lives\n     */\n    //% weight=85 blockGap=8\n    //% blockId=hudLife block=\"life\"\n    //% help=info/life\n    //% group=\"Life\"\n    export function life() {\n        return player1.impl.life();\n    }\n\n    //% group=\"Life\"\n    export function hasLife() {\n        return player1.impl.hasLife();\n    }\n\n    /**\n     * Set the number of lives\n     * @param value the number of lives, eg: 3\n     */\n    //% weight=84 blockGap=8\n    //% blockId=hudSetLife block=\"set life to %value\"\n    //% help=info/set-life\n    //% group=\"Life\"\n    export function setLife(value: number) {\n        player1.impl.setLife(value);\n    }\n\n    /**\n     * Change the lives by the given amount\n     * @param value the change of lives, eg: -1\n     */\n    //% weight=83\n    //% blockId=hudChangeLifeBy block=\"change life by %value\"\n    //% help=info/change-life-by\n    //% group=\"Life\"\n    export function changeLifeBy(value: number) {\n        player1.impl.changeLifeBy(value);\n    }\n\n    /**\n     * Run code when the player's life reaches 0. If this function\n     * is not called then game.over() is called instead\n     */\n    //% weight=82\n    //% blockId=gamelifeevent block=\"on life zero\"\n    //% help=info/on-life-zero\n    //% group=\"Life\"\n    export function onLifeZero(handler: () => void) {\n        player1.impl.onLifeZero(handler);\n    }\n\n    /**\n     * Runs code once each time the score reaches a given value. This will also\n     * run if the score \"passes\" the given value in either direction without ever\n     * having the exact value (e.g. if score is changed by more than 1)\n     *\n     * @param score the score to fire the event on\n     * @param handler code to run when the score reaches the given value\n     */\n    //% weight=10\n    //% blockId=gameonscore\n    //% block=\"on score $score\"\n    //% score.defl=100\n    //% help=info/on-score\n    //% group=\"Score\"\n    export function onScore(score: number, handler: () => void) {\n        player1.impl.onScore(score, handler);\n    }\n\n    /**\n     * Get the value of the current count down\n     */\n    //% block=\"countdown\"\n    //% blockId=gamegetcountdown\n    //% weight=79 help=info/countdown\n    //% group=\"Countdown\"\n    export function countdown(): number {\n        initHUD();\n        return infoState.gameEnd ? ((infoState.gameEnd - game.currentScene().millis()) / 1000) : 0;\n    }\n\n    /**\n     * Start a countdown of the given duration in seconds\n     * @param duration the duration of the countdown, eg: 10\n     */\n    //% blockId=gamecountdown block=\"start countdown %duration (s)\"\n    //% help=info/start-countdown weight=78 blockGap=8\n    //% group=\"Countdown\"\n    export function startCountdown(duration: number) {\n        updateFlag(Visibility.Countdown, true);\n        infoState.gameEnd = game.currentScene().millis() + duration * 1000;\n        infoState.countdownExpired = false;\n    }\n\n    /**\n     * Change the running countdown by the given number of seconds\n     * @param seconds the number of seconds the countdown should be changed by\n     */\n    //% block=\"change countdown by $seconds (s)\"\n    //% blockId=gamechangecountdown\n    //% weight=77 help=info/change-countdown-by\n    //% group=\"Countdown\"\n    export function changeCountdownBy(seconds: number) {\n        startCountdown((countdown() + seconds));\n    }\n\n    /**\n     * Stop the current countdown and hides the timer display\n     */\n    //% blockId=gamestopcountdown block=\"stop countdown\" weight=76\n    //% help=info/stop-countdown\n    //% group=\"Countdown\"\n    export function stopCountdown() {\n        updateFlag(Visibility.Countdown, false);\n        infoState.gameEnd = undefined;\n        infoState.countdownExpired = true;\n    }\n\n    /**\n     * Run code when the countdown reaches 0. If this function\n     * is not called then game.over() is called instead\n     */\n    //% blockId=gamecountdownevent block=\"on countdown end\" weight=75\n    //% help=info/on-countdown-end\n    //% group=\"Countdown\"\n    export function onCountdownEnd(handler: () => void) {\n        initHUD();\n        infoState.countdownEndHandler = handler;\n    }\n\n    /**\n     * Replaces the image used to represent the player's lives. Images\n     * should be no larger than 8x8\n     */\n    //% group=\"Life\"\n    export function setLifeImage(image: Image) {\n        updateFlag(Visibility.UserHeartImage, true);\n        infoState.heartImage = image;\n    }\n\n    /**\n     * Set whether life should be displayed\n     * @param on if true, lives are shown; otherwise, lives are hidden\n     */\n    //% group=\"Life\"\n    export function showLife(on: boolean) {\n        updateFlag(Visibility.Life, on);\n        updateFlag(Visibility._ExplicitlySetLife, true);\n    }\n\n    /**\n     * Set whether score should be displayed\n     * @param on if true, score is shown; otherwise, score is hidden\n     */\n    //% group=\"Score\"\n    export function showScore(on: boolean) {\n        updateFlag(Visibility.Score, on);\n        updateFlag(Visibility._ExplicitlySetScore, true);\n    }\n\n    /**\n     * Set whether countdown should be displayed\n     * @param on if true, countdown is shown; otherwise, countdown is hidden\n     */\n    //% group=\"Countdown\"\n    export function showCountdown(on: boolean) {\n        updateFlag(Visibility.Countdown, on);\n    }\n\n    function updateFlag(flag: Visibility, on: boolean) {\n        initHUD();\n        if (on) infoState.visibilityFlag |= flag;\n        else infoState.visibilityFlag = ~(~infoState.visibilityFlag | flag);\n    }\n\n    /**\n     * Sets the color of the borders around the score, countdown, and life\n     * elements. Defaults to 3\n     * @param color The index of the color (0-15)\n     */\n    //% group=\"Theme\"\n    export function setBorderColor(color: number) {\n        initHUD();\n        infoState.borderColor = Math.min(Math.max(color, 0), 15) | 0;\n    }\n\n    /**\n     * Sets the color of the background of the score, countdown, and life\n     * elements. Defaults to 1\n     * @param color The index of the color (0-15)\n     */\n    //% group=\"Theme\"\n    export function setBackgroundColor(color: number) {\n        initHUD();\n        infoState.bgColor = Math.min(Math.max(color, 0), 15) | 0;\n    }\n\n    /**\n     * Sets the color of the text used in the score, countdown, and life\n     * elements. Defaults to 3\n     * @param color The index of the color (0-15)\n     */\n    //% group=\"Theme\"\n    export function setFontColor(color: number) {\n        initHUD();\n        infoState.fontColor = Math.min(Math.max(color, 0), 15) | 0;\n    }\n\n    /**\n     * Get the current color of the borders around the score, countdown, and life\n     * elements\n     */\n    //% group=\"Theme\"\n    export function borderColor(): number {\n        initHUD();\n        return infoState.borderColor ? infoState.borderColor : 3;\n    }\n\n    /**\n     * Get the current color of the background of the score, countdown, and life\n     * elements\n     */\n    //% group=\"Theme\"\n    export function backgroundColor(): number {\n        initHUD();\n        return infoState.bgColor ? infoState.bgColor : 1;\n    }\n\n    /**\n     * Get the current color of the text usded in the score, countdown, and life\n     * elements\n     */\n    //% group=\"Theme\"\n    export function fontColor(): number {\n        initHUD();\n        return infoState.fontColor ? infoState.fontColor : 3;\n    }\n\n    function drawTimer(millis: number) {\n        if (millis < 0) millis = 0;\n        millis |= 0;\n\n        const font = image.font8;\n        const smallFont = image.font5;\n        const seconds = Math.idiv(millis, 1000);\n        const width = font.charWidth * 5 - 2;\n        let left = (screen.width >> 1) - (width >> 1) + 1;\n        let color1 = infoState.fontColor;\n        let color2 = infoState.bgColor;\n\n        if (seconds < 10 && (seconds & 1) && !screen.isMono) {\n            const temp = color1;\n            color1 = color2;\n            color2 = temp;\n        }\n\n        screen.fillRect(left - 3, 0, width + 6, font.charHeight + 3, infoState.borderColor)\n        screen.fillRect(left - 2, 0, width + 4, font.charHeight + 2, color2)\n\n\n        if (seconds < 60) {\n            const top = 1;\n            const remainder = Math.idiv(millis % 1000, 10);\n\n            screen.print(formatDecimal(seconds) + \".\", left, top, color1, font)\n            const decimalLeft = left + 3 * font.charWidth;\n            screen.print(formatDecimal(remainder), decimalLeft, top + 2, color1, smallFont)\n        }\n        else {\n            const minutes = Math.idiv(seconds, 60);\n            const remainder = seconds % 60;\n            screen.print(formatDecimal(minutes) + \":\" + formatDecimal(remainder), left, 1, color1, font);\n        }\n    }\n\n    /**\n     * Splits the implementation of the player info from the user-facing APIs so that\n     * we can reference this internally without causing the \"multiplayer\" part to show\n     * up in the usedParts array of the user program's compile result. Make sure to\n     * use the APIs on this class and not the PlayerInfo to avoid false-positives when\n     * we detect if a game is multiplayer or not\n     */\n    export class PlayerInfoImpl {\n        protected _player: number;\n        public bg: number; // background color\n        public border: number; // border color\n        public fc: number; // font color\n        public x?: number;\n        public y?: number;\n        public left?: boolean; // if true banner goes from x to the left, else goes rightward\n        public up?: boolean; // if true banner goes from y up, else goes downward\n\n        constructor(player: number) {\n            this._player = player;\n            this.border = 1;\n            this.fc = 1;\n            this.left = undefined;\n            this.up = undefined;\n            if (this._player === 1) {\n                // Top left, and banner is white on red\n                this.bg = screen.isMono ? 0 : 2;\n                this.x = 0;\n                this.y = 0;\n            } else if (player === 2) {\n                // Top right, and banner is white on blue\n                this.bg = screen.isMono ? 0 : 8;\n                this.x = screen.width;\n                this.y = 0;\n                this.left = true;\n            } else if (player === 3) {\n                this.bg = screen.isMono ? 0 : 4;\n                this.x = 0;\n                this.y = screen.height;\n                this.up = true;\n            } else {\n                // bottom left, banner is white on green\n                this.bg = screen.isMono ? 0 : 7;\n                this.x = screen.width;\n                this.y = screen.height;\n                this.left = true;\n                this.up = true;\n            }\n        }\n\n        private init() {\n            initHUD();\n            if (this._player > 1) initMultiHUD();\n            if (!infoState.playerStates[this._player - 1]) {\n                infoState.playerStates[this._player - 1] = new PlayerState();\n            }\n        }\n\n        getState(): PlayerState {\n            this.init();\n            return infoState.playerStates[this._player - 1];\n        }\n\n        // the id numbera of the player\n        id(): number {\n            return this._player;\n        }\n\n        score(): number {\n            const state = this.getState();\n\n            if (state.showScore === undefined) state.showScore = true;\n            if (state.showPlayer === undefined) state.showPlayer = true;\n\n            if (state.score == null)\n                state.score = 0;\n            return state.score;\n        }\n\n        setScore(value: number) {\n            const state = this.getState();\n            if (!(infoState.visibilityFlag & Visibility._ExplicitlySetScore)) {\n                updateFlag(Visibility.Score, true);\n            }\n\n            this.score(); // invoked for side effects\n\n            const oldScore = state.score || 0;\n            state.score = (value | 0);\n\n            state.scoreReachedHandlers.forEach(srh => {\n                if ((oldScore < srh.score && state.score >= srh.score) ||\n                    (oldScore > srh.score && state.score <= srh.score)) {\n                    srh.handler();\n                }\n            });\n        }\n\n        changeScoreBy(value: number): void {\n            this.setScore(this.score() + value);\n        }\n\n        hasScore() {\n            const state = this.getState();\n            return state.score !== undefined;\n        }\n\n        life(): number {\n            const state = this.getState();\n\n            if (state.showLife === undefined) state.showLife = true;\n            if (state.showPlayer === undefined) state.showPlayer = true;\n\n            if (state.life === undefined) {\n                state.life = 3;\n            }\n            return state.life || 0;\n        }\n\n        setLife(value: number): void {\n            const state = this.getState();\n            if (!(infoState.visibilityFlag & Visibility._ExplicitlySetLife)) {\n                updateFlag(Visibility.Life, true);\n            }\n\n            this.life(); // invoked for side effects\n            state.life = (value | 0);\n        }\n\n        changeLifeBy(value: number): void {\n            this.setLife(this.life() + value);\n        }\n\n        hasLife(): boolean {\n            const state = this.getState();\n            return state.life !== undefined && state.life !== null;\n        }\n\n        onLifeZero(handler: () => void) {\n            const state = this.getState();\n            state.lifeZeroHandler = handler;\n        }\n\n        onScore(score: number, handler: () => void) {\n            const state = this.getState();\n\n            for (const element of state.scoreReachedHandlers) {\n                if (element.score === score) {\n                    // Score handlers are implemented as \"last one wins.\"\n                    element.handler = handler;\n                    return;\n                }\n            }\n\n            state.scoreReachedHandlers.push(new ScoreReachedHandler(score, handler));\n        }\n\n        raiseLifeZero(gameOver: boolean) {\n            const state = this.getState();\n            if (state.life !== null && state.life <= 0) {\n                state.life = null;\n                if (state.lifeZeroHandler) {\n                    state.lifeZeroHandler();\n                } else if (gameOver) {\n                    // Clear effect and sound, unless set by user\n                    const goc = game.gameOverConfig();\n                    goc.setEffect(false, null, false);\n                    goc.setSound(false, null, false, false);\n                    game.gameOver(false);\n                }\n            }\n        }\n    }\n\n    //% fixedInstances\n    //% blockGap=8\n    export class PlayerInfo {\n        protected _player: number;\n        public impl: PlayerInfoImpl;\n\n        constructor(player: number) {\n            this._player = player;\n            this.impl = new PlayerInfoImpl(player);\n\n            if (!players) players = [];\n            players[this._player - 1] = this;\n        }\n\n        private init() {\n            initHUD();\n            if (this._player > 1) initMultiHUD();\n            if (!infoState.playerStates[this._player - 1]) {\n                infoState.playerStates[this._player - 1] = new PlayerState();\n            }\n        }\n\n        /**\n         * Returns the one-based number of the player\n         */\n        get number() {\n            return this._player;\n        }\n\n        get bg(): number {\n            return this.impl.bg;\n        }\n\n        set bg(value: number) {\n            this.impl.bg = value;\n        }\n\n        get border(): number {\n            return this.impl.border;\n        }\n\n        set border(value: number) {\n            this.impl.border = value;\n        }\n\n        get fc(): number {\n            return this.impl.fc;\n        }\n\n        set fc(value: number) {\n            this.impl.fc = value;\n        }\n\n        get showScore(): boolean {\n            return this.impl.getState().showScore;\n        }\n\n        set showScore(value: boolean) {\n            this.impl.getState().showScore = value;\n        }\n\n        get showLife(): boolean {\n            return this.impl.getState().showLife;\n        }\n\n        set showLife(value: boolean) {\n            this.impl.getState().showLife = value;\n        }\n\n        get visibility(): Visibility {\n            return this.impl.getState().visibility;\n        }\n\n        set visibility(value: Visibility) {\n            this.impl.getState().visibility = value;\n        }\n\n        get showPlayer(): boolean {\n            return this.impl.getState().showPlayer;\n        }\n\n        set showPlayer(value: boolean) {\n            this.impl.getState().showPlayer = value;\n        }\n\n        get x(): number {\n            return this.impl.x;\n        }\n\n        set x(value: number) {\n            this.impl.x = value;\n        }\n\n        get y(): number {\n            return this.impl.y;\n        }\n\n        set y(value: number) {\n            this.impl.y = value;\n        }\n\n        get left(): boolean {\n            return this.impl.left;\n        }\n\n        set left(value: boolean) {\n            this.impl.left = value;\n        }\n\n        get up(): boolean {\n            return this.impl.up;\n        }\n\n        set up(value: boolean) {\n            this.impl.up = value;\n        }\n\n        getState(): PlayerState {\n            this.init();\n            return infoState.playerStates[this._player - 1];\n        }\n\n        // the id numbera of the player\n        id(): number {\n            return this.impl.id();\n        }\n\n        /**\n         * Get the player score\n         */\n        //% group=\"Multiplayer\"\n        //% blockId=piscore block=\"%player score\"\n        //% help=info/score\n        //% parts=\"multiplayer\"\n        score(): number {\n            return this.impl.score();\n        }\n\n        /**\n         * Set the player score\n         */\n        //% group=\"Multiplayer\"\n        //% blockId=pisetscore block=\"set %player score to %value\"\n        //% value.defl=0\n        //% help=info/set-score\n        //% parts=\"multiplayer\"\n        setScore(value: number) {\n            this.impl.setScore(value);\n        }\n\n        /**\n         * Change the score of a player\n         * @param value\n         */\n        //% group=\"Multiplayer\"\n        //% blockId=pichangescore block=\"change %player score by %value\"\n        //% value.defl=1\n        //% help=info/change-score-by\n        //% parts=\"multiplayer\"\n        changeScoreBy(value: number): void {\n            this.impl.changeScoreBy(value);\n        }\n\n        hasScore() {\n            return this.impl.hasScore();\n        }\n\n        /**\n         * Get the player life\n         */\n        //% group=\"Multiplayer\"\n        //% blockid=piflife block=\"%player life\"\n        //% help=info/life\n        //% parts=\"multiplayer\"\n        life(): number {\n            return this.impl.life();\n        }\n\n        /**\n         * Set the player life\n         */\n        //% group=\"Multiplayer\"\n        //% blockId=pisetlife block=\"set %player life to %value\"\n        //% value.defl=3\n        //% help=info/set-life\n        //% parts=\"multiplayer\"\n        setLife(value: number): void {\n            this.impl.setLife(value);\n        }\n\n        /**\n         * Change the life of a player\n         * @param value\n         */\n        //% group=\"Multiplayer\"\n        //% blockId=pichangelife block=\"change %player life by %value\"\n        //% value.defl=-1\n        //% help=info/change-life-by\n        //% parts=\"multiplayer\"\n        changeLifeBy(value: number): void {\n            this.impl.changeLifeBy(value);\n        }\n\n        /**\n         * Return true if the given player currently has a value set for health,\n         * and false otherwise.\n         * @param player player to check life of\n         */\n        //% group=\"Multiplayer\"\n        //% blockId=pihaslife block=\"%player has life\"\n        //% help=info/has-life\n        //% parts=\"multiplayer\"\n        hasLife(): boolean {\n            return this.impl.hasLife();\n        }\n\n        /**\n         * Runs code when life reaches zero\n         * @param handler\n         */\n        //% group=\"Multiplayer\"\n        //% blockId=playerinfoonlifezero block=\"on %player life zero\"\n        //% help=info/on-life-zero\n        //% parts=\"multiplayer\"\n        onLifeZero(handler: () => void) {\n            this.impl.onLifeZero(handler);\n        }\n\n        /**\n         * Runs code once each time the score reaches a given value. This will also\n         * run if the score \"passes\" the given value in either direction without ever\n         * having the exact value (e.g. if score is changed by more than 1)\n         *\n         * @param score the score to fire the event on\n         * @param handler code to run when the score reaches the given value\n         */\n        //% blockId=playerinfoonscore\n        //% block=\"on $this score $score\"\n        //% score.defl=100\n        //% help=info/on-score\n        //% group=\"Multiplayer\"\n        //% parts=\"multiplayer\"\n        onScore(score: number, handler: () => void) {\n            this.impl.onScore(score, handler);\n        }\n\n        drawPlayer() {\n            const state = this.getState();\n\n            const font = image.font5;\n            let score: string;\n            let life: string;\n            let height = 4;\n            let scoreWidth = 0;\n            let lifeWidth = 0;\n            const offsetX = 1;\n            let offsetY = 2;\n            let showScore = state.showScore && state.score !== undefined;\n            let showLife = state.showLife && state.life !== undefined;\n\n            if (showScore) {\n                score = \"\" + state.score;\n                scoreWidth = score.length * font.charWidth + 3;\n                height += font.charHeight;\n                offsetY += font.charHeight + 1;\n            }\n\n            if (showLife) {\n                life = \"\" + (state.life || 0);\n                lifeWidth = infoState.heartImage.width + infoState.multiplierImage.width + life.length * font.charWidth + 3;\n                height += infoState.heartImage.height;\n            }\n\n            const width = Math.max(scoreWidth, lifeWidth);\n\n            // bump size for space between lines\n            if (showScore && showLife) height++;\n\n            const x = this.impl.x - (this.impl.left ? width : 0);\n            const y = this.impl.y - (this.impl.up ? height : 0);\n\n            // Bordered Box\n            if (showScore || showLife) {\n                screen.fillRect(x, y, width, height, this.impl.border);\n                screen.fillRect(x + 1, y + 1, width - 2, height - 2, this.impl.bg);\n            }\n\n            // print score\n            if (showScore) {\n                const bump = this.impl.left ? width - scoreWidth : 0;\n                screen.print(score, x + offsetX + bump + 1, y + 2, this.impl.fc, font);\n            }\n\n            // print life\n            if (showLife) {\n                const xLoc = x + offsetX + (this.impl.left ? width - lifeWidth : 0);\n\n                let mult = infoState.multiplierImage.clone();\n                mult.replace(1, this.impl.fc);\n\n                screen.drawTransparentImage(\n                    infoState.heartImage,\n                    xLoc,\n                    y + offsetY\n                );\n                screen.drawTransparentImage(\n                    mult,\n                    xLoc + infoState.heartImage.width,\n                    y + offsetY + font.charHeight - infoState.multiplierImage.height - 1\n                );\n                screen.print(\n                    life,\n                    xLoc + infoState.heartImage.width + infoState.multiplierImage.width + 1,\n                    y + offsetY,\n                    this.impl.fc,\n                    font\n                );\n            }\n\n            // print player icon\n            if (state.showPlayer) {\n                const pNum = \"\" + this._player;\n\n                let iconWidth = pNum.length * font.charWidth + 1;\n                const iconHeight = Math.max(height, font.charHeight + 2);\n                let iconX = this.impl.left ? (x - iconWidth + 1) : (x + width - 1);\n                let iconY = y;\n\n                // adjustments when only player icon shown\n                if (!showScore && !showLife) {\n                    iconX += this.impl.left ? -1 : 1;\n                    if (this.impl.up) iconY -= 3;\n                }\n\n                screen.fillRect(\n                    iconX,\n                    iconY,\n                    iconWidth,\n                    iconHeight,\n                    this.impl.border\n                );\n                screen.print(\n                    pNum,\n                    iconX + 1,\n                    iconY + (iconHeight >> 1) - (font.charHeight >> 1),\n                    this.impl.bg,\n                    font\n                );\n            }\n        }\n\n        drawScore() {\n            const s = this.impl.score() | 0;\n\n            let font: image.Font;\n            let offsetY: number;\n            if (s >= 1000000) {\n                offsetY = 2;\n                font = image.font5;\n            }\n            else {\n                offsetY = 1;\n                font = image.font8;\n            }\n\n            const num = s.toString();\n            const width = num.length * font.charWidth;\n\n            screen.fillRect(\n                screen.width - width - 2,\n                0,\n                screen.width,\n                image.font8.charHeight + 3,\n                infoState.borderColor\n            );\n            screen.fillRect(\n                screen.width - width - 1,\n                0,\n                screen.width,\n                image.font8.charHeight + 2,\n                infoState.bgColor\n            );\n            screen.print(\n                num,\n                screen.width - width,\n                offsetY,\n                infoState.fontColor,\n                font\n            );\n        }\n\n        drawLives() {\n            const state = this.getState();\n            if (state.life < 0) return;\n            const font = image.font8;\n            if (state.life <= 4) {\n                screen.fillRect(\n                    0,\n                    0,\n                    state.life * (infoState.heartImage.width + 1) + 3,\n                    infoState.heartImage.height + 4,\n                    infoState.borderColor\n                );\n                screen.fillRect(\n                    0,\n                    0,\n                    state.life * (infoState.heartImage.width + 1) + 2,\n                    infoState.heartImage.height + 3,\n                    infoState.bgColor\n                );\n                for (let i = 0; i < state.life; i++) {\n                    screen.drawTransparentImage(\n                        infoState.heartImage,\n                        1 + i * (infoState.heartImage.width + 1),\n                        1\n                    );\n                }\n            }\n            else {\n                const num = state.life + \"\";\n                const textWidth = num.length * font.charWidth - 1;\n                screen.fillRect(\n                    0,\n                    0,\n                    infoState.heartImage.width + infoState.multiplierImage.width + textWidth + 5,\n                    infoState.heartImage.height + 4,\n                    infoState.borderColor\n                );\n                screen.fillRect(\n                    0,\n                    0,\n                    infoState.heartImage.width + infoState.multiplierImage.width + textWidth + 4,\n                    infoState.heartImage.height + 3,\n                    infoState.bgColor\n                );\n                screen.drawTransparentImage(\n                    infoState.heartImage,\n                    1,\n                    1\n                );\n\n                let mult = infoState.multiplierImage.clone();\n                mult.replace(1, infoState.fontColor);\n\n                screen.drawTransparentImage(\n                    mult,\n                    infoState.heartImage.width + 2,\n                    font.charHeight - infoState.multiplierImage.height - 1\n                );\n                screen.print(\n                    num,\n                    infoState.heartImage.width + 3 + infoState.multiplierImage.width,\n                    1,\n                    infoState.fontColor,\n                    font\n                );\n            }\n        }\n    }\n\n    function formatDecimal(val: number) {\n        val |= 0;\n        if (val < 10) {\n            return \"0\" + val;\n        }\n        return val.toString();\n    }\n\n    //% fixedInstance whenUsed block=\"player 2\"\n    export const player2 = new PlayerInfo(2);\n    //% fixedInstance whenUsed block=\"player 3\"\n    export const player3 = new PlayerInfo(3);\n    //% fixedInstance whenUsed block=\"player 4\"\n    export const player4 = new PlayerInfo(4);\n    //% fixedInstance whenUsed block=\"player 1\"\n    export const player1 = new PlayerInfo(1);\n}\n","keymap.cpp":"#include \"pxt.h\"\n\nnamespace keymap {\n\n    void _setPlayerKeys(int player, int up, int down, int left, int right, int A, int B) {\n        // not supported\n    }\n\n    void _setSystemKeys(int screenshot, int gif) {\n        // not supported\n    }\n}\n","keymap.ts":"namespace keymap {\n    //% shim=keymap::_setPlayerKeys\n    declare function _setPlayerKeys(\n        player: number, // player number is 1-based\n        up: number,\n        down: number,\n        left: number,\n        right: number,\n        A: number,\n        B: number\n    ): void;\n\n    //% shim=keymap::_setSystemKeys\n    declare function _setSystemKeys(screenshot: number, gif: number, menu: number, reset: number): void;\n\n    /**\n     * Sets the keyboard input map for the given player.\n     * @param player The player number. 1 = Player1, etc.\n     * @param up The key code for 'up'.\n     * @param down The key code for 'down'\n     * @param left The key code for 'left'\n     * @param right The key code for 'right'\n     * @param A The key code for 'A'\n     * @param B The key code for 'B'\n     */\n    export function setPlayerKeys(\n        player: number, // player number is 1-based\n        up: KeyCode,\n        down: KeyCode,\n        left: KeyCode,\n        right: KeyCode,\n        A: KeyCode,\n        B: KeyCode\n    ) {\n        _setPlayerKeys(player, up, down, left, right, A, B);\n    }\n\n    /**\n     * Sets the keyboard input map for system keys.\n     * @param screenshot The key code for 'screenshot'\n     * @param gif The key code for 'gif'\n     * @param menu The key code for 'menu'\n     * @param reset The key code for 'reset'\n     */\n    export function setSystemKeys(screenshot: KeyCode, gif: KeyCode, menu: KeyCode, reset: KeyCode) {\n        _setSystemKeys(screenshot, gif, menu, reset);\n    }\n\n    /**\n     * Key codes\n     */\n    export enum KeyCode {\n        None = 0,\n\n        Backspace = 8,\n        Tab = 9,\n        Enter = 13,\n        Shift = 16,\n        Ctrl = 17,\n        Alt = 18,\n        PauseBreak = 19,\n        CapsLock = 20,\n        Escape = 27,\n        Space = 32,\n        PageUp = 33,\n        PageDown = 34,\n        End = 35,\n        Home = 36,\n\n        LeftArrow = 37,\n        UpArrow = 38,\n        RightArrow = 39,\n        DownArrow = 40,\n\n        Insert = 45,\n        Delete = 46,\n\n        Zero = 48,\n        One = 49,\n        Two = 50,\n        Three = 51,\n        Four = 52,\n        Five = 53,\n        Six = 54,\n        Seven = 55,\n        Eight = 56,\n        Nine = 57,\n\n        A = 65,\n        B = 66,\n        C = 67,\n        D = 68,\n        E = 69,\n        F = 70,\n        G = 71,\n        H = 72,\n        I = 73,\n        J = 74,\n        K = 75,\n        L = 76,\n        M = 77,\n        N = 78,\n        O = 79,\n        P = 80,\n        Q = 81,\n        R = 82,\n        S = 83,\n        T = 84,\n        U = 85,\n        V = 86,\n        W = 87,\n        X = 88,\n        Y = 89,\n        Z = 90,\n\n        LeftWindowsKey = 91,\n        RightWindowsKey = 92,\n\n        Numpad0 = 96,\n        Numpad1 = 97,\n        Numpad2 = 98,\n        Numpad3 = 99,\n        Numpad4 = 100,\n        Numpad5 = 101,\n        Numpad6 = 102,\n        Numpad7 = 103,\n        Numpad8 = 104,\n        Numpad9 = 105,\n\n        Multiply = 106,\n        Add = 107,\n        Subtract = 109,\n        DecimalPoint = 110,\n        Divide = 111,\n\n        F1 = 112,\n        F2 = 113,\n        F3 = 114,\n        F4 = 115,\n        F5 = 116,\n        F6 = 117,\n        F7 = 118,\n        F8 = 119,\n        F9 = 120,\n        F10 = 121,\n        F11 = 122,\n        F12 = 123,\n\n        NumLock = 144,\n        ScrollLock = 145,\n\n        SemiColon = 186,\n        Equals = 187,\n        Comma = 188,\n        Dash = 189,\n        Period = 190,\n        ForwardSlash = 191,\n        Tilde = 192,\n\n        OpenBracket = 219,\n        ClosedBracket = 221,\n        SingleQuote = 222,\n\n        // Mouse\n        MouseLeftButton = -1,\n        MouseRightButton = -2,\n        MouseCenterButton = -3,\n    }\n}\n","mathUtil.ts":"namespace Math {\n    /**\n     * Returns a random boolean that is true the given percentage of the time.\n     * @param percentage The percentage chance that the returned value will be true from 0 - 100\n     */\n    //% weight=2\n    //% blockId=percentchance block=\"%percentage|\\\\% chance\"\n    //% percentage.min=0 percentage.max=100;\n    //% help=math/percent-chance\n    export function percentChance(percentage: number): boolean {\n        if (percentage >= 100) {\n            return true;\n        }\n        else if (percentage <= 0) {\n            return false;\n        }\n        return Math.randomRange(0, 99) < percentage;\n    }\n\n    /**\n     * Returns a random element from the given list\n     * @param list The list to choose an element from\n     */\n    //% weight=1\n    export function pickRandom<T>(list: T[]) {\n        if (!list || list.length == 0) {\n            return undefined;\n        }\n        return list[Math.randomRange(0, list.length - 1)];\n    }\n\n    /**\n     * Fast, 16 bit, seedable (pseudo) random generator.\n     */\n    export class FastRandom {\n        // Implementation of the Galois Linear Feedback Shift Register\n        private lfsr: number;\n        // A value between 0x0001 and 0xFFFF to generate random values from\n        public seed: number;\n\n        /**\n         * Create a new Fast Random generator\n         * @param seed [Optional] initial seed between 0x0001 and 0xFFFF.\n         */\n        constructor(seed?: number) {\n            if (seed === undefined) seed = Math.randomRange(0x0001, 0xFFFF);\n            this.seed = seed;\n            this.lfsr = seed;\n        }\n\n        /**\n         * @returns the next random number between 0x0001 and 0xFFFF inclusive\n         */\n        next(): number {\n            return this.lfsr = (this.lfsr >> 1) ^ ((-(this.lfsr & 1)) & 0xb400);\n        }\n\n        /**\n         * @param min the minimum value to generate\n         * @param max the maximum value to generate\n         * @returns a random value between min and max (inclusive). If min is greater than or equal to max, returns min.\n         */\n        randomRange(min: number, max: number): number {\n            return min + (max > min ? this.next() % (max - min + 1) : 0);\n        }\n\n        /**\n         * Returns a random element from the given list\n         * @param list The list to choose an element from\n         */\n        pickRandom<T>(list: T[]) {\n            if (!list || list.length == 0) {\n                return undefined;\n            }\n            return list[this.randomRange(0, list.length - 1)];\n        }\n\n        /**\n         * @returns a random boolean value\n         */\n        randomBool(): boolean {\n            return !(this.next() & 1);\n        }\n\n        /**\n         * @param percent the percentage chance that the returned value will be true from 0 - 100\n         * @returns a boolean with approximately the given percent chance to be true or false\n         */\n        percentChance(percent: number): boolean {\n            return this.randomRange(0, 100) < percent;\n        }\n\n        /**\n         * Reset the state to the current seed\n         */\n        reset() {\n            this.lfsr = this.seed;\n        }\n    }\n}\n","metrics.ts":"namespace performance {\n\n}","multiplayer.cpp":"#include \"pxt.h\"\n\nnamespace multiplayer {\n    //%\n    void postImage(Image_ im) {\n    }\n    //%\n    void postIcon(int type, int icon, Image_ im) {\n    }\n\n    //%\n    void setOrigin(String origin) {\n    }\n\n    //%\n    Image_ getCurrentImage() {\n        return NULL;\n    }\n\n    //%\n    String getOrigin() {\n        return NULL;\n    }\n\n}","multiplayer.ts":"namespace multiplayer {\n    //% shim=multiplayer::getCurrentImage\n    declare function getCurrentImage(): Image;\n\n    //% shim=multiplayer::postImage\n    declare function postImage(im: Image): void;\n\n    //% shim=multiplayer::setOrigin\n    declare function setOrigin(origin: string): void;\n\n    //% shim=multiplayer::getOrigin\n    declare function getOrigin(): string;\n\n    export function init() {\n        game.addScenePushHandler(() => {\n            game.eventContext().registerFrameHandler(scene.MULTIPLAYER_SCREEN_PRIORITY, () => {\n                if (getOrigin() === \"client\") {\n                    const im: Image = getCurrentImage();\n                    scene.setBackgroundImage(im);\n                    // clear default menu button behavior\n                    controller.menu.onEvent(ControllerButtonEvent.Pressed, () => { });\n                }\n            });\n        });\n        game.pushScene();\n    }\n\n    const MULTIPLAYER_PLAYER_JOINED_ID = 3241;\n    const MULTIPLAYER_PLAYER_LEFT_ID = 3242;\n    export function initServer() {\n        if (getOrigin() === \"server\") {\n            game.eventContext().registerFrameHandler(scene.MULTIPLAYER_POST_SCREEN_PRIORITY, () => {\n                if (getOrigin() === \"server\") {\n                    postImage(screen);\n                }\n            })\n        }\n    }\n\n    export function initPlayerConnectionListeners() {\n        for (let p = 1; p <= 4; p++) {\n            registerPlayerConnectionListeners(p);\n        }\n    }\n\n    function registerPlayerConnectionListeners(playerNumber: number) {\n        control.onEvent(\n            MULTIPLAYER_PLAYER_JOINED_ID,\n            playerNumber,\n            () => receiveConnectionChangedEvent(playerNumber, true)\n        );\n        control.onEvent(\n            MULTIPLAYER_PLAYER_LEFT_ID,\n            playerNumber,\n            () => receiveConnectionChangedEvent(playerNumber, false)\n        );\n    }\n\n    function receiveConnectionChangedEvent(playerNumber: number, connected: boolean) {\n        let c: controller.Controller;\n        switch (playerNumber) {\n            case 1:\n                c = controller.player1;\n                break;\n            case 2:\n                c = controller.player2;\n                break;\n            case 3:\n                c = controller.player3;\n                break;\n            case 4:\n                c = controller.player4;\n                break;\n        }\n        if (c)\n            c.connected = connected;\n    }\n}\n\nnamespace mp {\n    enum IconType {\n        Player = 0,\n        Reaction = 1,\n    }\n    //% shim=multiplayer::postIcon\n    declare function postIcon(type: IconType, slot: number, im: Image): void;\n\n    export function postPresenceIcon(slot: number, im: Image, implicit?: boolean) {\n        initIconState();\n        if (slot < 1 || slot > 4)\n            return;\n\n        const presenceSetExplicitly = explicitlySetIcons[IconType.Player];\n        if (implicit && presenceSetExplicitly[slot])\n            return;\n        if (!implicit)\n            presenceSetExplicitly[slot] = true;\n\n        postIcon(IconType.Player, slot, im);\n    }\n\n    export function postReactionIcon(slot: number, im: Image, implicit?: boolean) {\n        initIconState();\n        if (slot < 1 || slot > 6)\n            return;\n\n        const reactionsSetExplicitly = explicitlySetIcons[IconType.Reaction];\n        if (implicit && reactionsSetExplicitly[slot])\n            return;\n        if (!implicit)\n            reactionsSetExplicitly[slot] = true;\n\n        postIcon(IconType.Reaction, slot, im);\n    }\n\n    let explicitlySetIcons: boolean[][];\n    function initIconState() {\n        if (explicitlySetIcons)\n            return;\n        explicitlySetIcons = [];\n        explicitlySetIcons[IconType.Player] = [];\n        explicitlySetIcons[IconType.Reaction] = [];\n    }\n}","ns.ts":"//% color=#8854d0 weight=97 icon=\"\\uf111\"\n//% blockGap=8\n//% groups='[\"Gameplay\", \"Game Over\", \"Prompt\",  \"Dialogs\"]'\nnamespace game {\n}\n","numberprompt.ts":"namespace game {\n\n    /**\n     * Ask the player for a number value.\n     * @param message The message to display on the text-entry screen\n     * @param answerLength The maximum number of digits the user can enter (1 - 10)\n     * @param useOnScreenKeyboard Force the simulator to use the on-screen keyboard for text entry\n     */\n    //% weight=10 help=game/ask-for-number\n    //% blockId=gameaskfornumber\n    //% block=\"ask for number $message || and max length $answerLength use on-screen keyboard $useOnScreenKeyboard\"\n    //% message.shadow=text\n    //% message.defl=\"\"\n    //% answerLength.defl=\"6\"\n    //% answerLength.min=1\n    //% answerLength.max=10\n    //% group=\"Prompt\"\n    export function askForNumber(message: any, answerLength = 6, useOnScreenKeyboard = false) {\n        answerLength = Math.max(0, Math.min(10, answerLength));\n        let p = new game.NumberPrompt();\n        const result = p.show(console.inspect(message), answerLength, useOnScreenKeyboard);\n        return parseFloat(result);\n    }\n\n    export class NumberPrompt extends Prompt {\n        constructor(theme?: PromptTheme) {\n            super(theme);\n\n            this.keyboardColumns = 3;\n            this.keyboardRows = 4;\n        }\n\n        protected numbersOnly() {\n            return true;\n        }\n\n        protected drawBottomBar() {\n            this.drawBottomBarBackground();\n\n            this.drawConfirm(this.cursorRow === 4);\n        }\n\n        protected confirm() {\n            if (this.cursorRow === 4) {\n                this.confirmPressed = true;\n            } else {\n                if (this.selectionStart >= this.answerLength) return;\n\n                const index = this.cursorColumn + this.cursorRow * this.keyboardColumns\n                const letter = this.getSymbolForIndex(index);\n\n                if (letter === \".\") {\n                    if (this.result.indexOf(\".\") !== -1) {\n                        return;\n                    }\n                }\n\n                if (letter === \"-\" && (this.result && this.result.length > 0)) {\n                    return;\n                }\n\n                if (!this.result) {\n                    this.result = letter;\n                }\n                else {\n                    this.result += letter;\n                }\n\n                this.changeInputIndex(1);\n            }\n        }\n\n        protected moveVertical(up: boolean): void {\n            super.moveVertical(up);\n            if (up && this.cursorRow === this.keyboardRows - 1) {\n                this.cursorColumn = this.keyboardColumns - 1;\n            }\n        }\n\n        protected getSymbolForIndex(index: number): string {\n            if (index < 9) {\n                // Calculator Layout\n                return \"\" + (3 * Math.idiv(9 - index - 1, 3) + index % 3 + 1);\n            } else if (index == 9) {\n                return \"-\";\n            } else if (index == 10) {\n                return \"0\";\n            } else if (index == 11) {\n                return \".\";\n            } else {\n                return \"\";\n            }\n        }\n    }\n}","obstacle.ts":"namespace sprites {\n    enum ObstacleFlags {\n        Moved = 1 << 4,\n        Dead = 1 << 5\n    }\n\n    export interface Obstacle {\n        x: number;\n        y: number;\n        left: number;\n        right: number;\n        top: number;\n        bottom: number;\n        width: number;\n        height: number;\n        layer: number;\n        image: Image;\n        tileIndex: number;\n    }\n\n    export class StaticObstacle implements Obstacle {\n        layer: number;\n        image: Image;\n        tileIndex: number;\n\n        top: number;\n        left: number;\n\n        constructor(image: Image, top: number, left: number, layer: number, tileIndex?: number) {\n            this.image = image;\n            this.layer = layer;\n            this.top = top;\n            this.left = left;\n            this.tileIndex = tileIndex;\n        }\n\n        get x(): number {\n            return this.left + (this.width >> 1);\n        }\n\n        get y(): number {\n            return this.top + (this.height >> 1);\n        }\n\n        get height(): number {\n            return this.image.height;\n        }\n\n        get width(): number {\n            return this.image.width;\n        }\n\n        get bottom(): number {\n            return this.top + this.height;\n        }\n\n        get right(): number {\n            return this.left + this.width;\n        }\n    }\n}","particleeffects.ts":"namespace effects {\n\n    //% fixedInstances\n    export interface BackgroundEffect {\n        startScreenEffect(): void;\n    }\n\n    //% fixedInstances\n    export class ParticleEffect {\n        protected sourceFactory: (anchor: particles.ParticleAnchor, pps: number) => particles.ParticleSource;\n        protected defaultRate: number;\n        protected defaultLifespan: number;\n\n        constructor(defaultParticlesPerSecond: number, defaultLifespan: number,\n                sourceFactory: (anchor: particles.ParticleAnchor, particlesPerSecond: number) => particles.ParticleSource) {\n            this.sourceFactory = sourceFactory;\n            this.defaultRate = defaultParticlesPerSecond;\n            this.defaultLifespan = defaultLifespan;\n        }\n\n        /**\n         * Attaches a new particle animation to the sprite or anchor for a short period of time\n         * @param anchor\n         * @param duration\n         * @param particlesPerSecond\n         */\n        start(anchor: particles.ParticleAnchor, duration?: number, particlesPerSecond?: number, relativeToCamera?: boolean): void {\n            if (!this.sourceFactory) return;\n            const src = this.sourceFactory(anchor, particlesPerSecond ? particlesPerSecond : this.defaultRate);\n            src.setRelativeToCamera(!!relativeToCamera);\n            if (duration)\n                src.lifespan = duration > 0 ? duration : this.defaultLifespan;\n        }\n\n        /**\n         * Destroy the provided sprite with an effect\n         * @param sprite\n         * @param duration how long the sprite will remain on the screen. If set to 0 or undefined,\n         *                  uses the default rate for this effect.\n         * @param particlesPerSecond\n         */\n        destroy(anchor: Sprite, duration?: number, particlesPerSecond?: number) {\n            anchor.setFlag(SpriteFlag.Ghost, true);\n            this.start(anchor, particlesPerSecond, null, !!(anchor.flags & sprites.Flag.RelativeToCamera));\n            anchor.lifespan = duration ? duration : this.defaultLifespan >> 2;\n            effects.dissolve.applyTo(anchor);\n        }\n    }\n\n    /**\n     * Anchor used for effects that occur across the screen.\n     */\n    class SceneAnchor implements particles.ParticleAnchor {\n        private camera: scene.Camera;\n\n        constructor() {\n            this.camera = game.currentScene().camera;\n        }\n\n        get x() {\n            return this.camera.offsetX + (screen.width >> 1);\n        }\n\n        get y() {\n            return this.camera.offsetY + (screen.height >> 1);\n        }\n\n        get width() {\n            return screen.width;\n        }\n\n        get height() {\n            return screen.height;\n        }\n    }\n\n    //% fixedInstances\n    export class ScreenEffect extends ParticleEffect implements BackgroundEffect {\n        protected source: particles.ParticleSource;\n        protected sceneDefaultRate: number;\n\n        constructor(anchorDefault: number, sceneDefault: number, defaultLifespan: number,\n                sourceFactory: (anchor: particles.ParticleAnchor, particlesPerSecond: number) => particles.ParticleSource) {\n            super(anchorDefault, defaultLifespan, sourceFactory);\n            this.sceneDefaultRate = sceneDefault;\n        }\n\n        /**\n         * Creates a new effect that occurs over the entire screen\n         * @param particlesPerSecond\n         * @param duration\n         */\n        //% blockId=particlesStartScreenAnimation block=\"start screen %effect effect || for %duration ms\"\n        //% duration.shadow=timePicker\n        //% blockNamespace=scene\n        //% group=\"Effects\" blockGap=8\n        //% weight=90 help=effects/start-screen-effect\n        startScreenEffect(duration?: number, particlesPerSecond?: number): void {\n            if (!this.sourceFactory)\n                return;\n\n            if (this.source && this.source.enabled) {\n                if (duration)\n                    this.source.lifespan = duration;\n                return;\n            }\n\n            this.endScreenEffect();\n            this.source = this.sourceFactory(new SceneAnchor(), particlesPerSecond ? particlesPerSecond : this.sceneDefaultRate);\n            this.source.priority = 10;\n            if (duration)\n                this.source.lifespan = duration;\n        }\n\n        /**\n         * If this effect is currently occurring as a full screen effect, stop producing particles and end the effect\n         * @param particlesPerSecond\n         */\n        //% blockId=particlesEndScreenAnimation block=\"end screen %effect effect\"\n        //% blockNamespace=scene\n        //% group=\"Effects\" blockGap=8\n        //% weight=80 help=effects/end-screen-effect\n        endScreenEffect(): void {\n            if (this.source) {\n                this.source.destroy();\n                this.source = undefined;\n            }\n        }\n    }\n\n    /**\n     * Removes all effects attached to the given anchor\n     * @param anchor the anchor to remove effects from\n     */\n    //% blockId=particlesclearparticles block=\"clear effects on %anchor=variables_get(mySprite)\"\n    //% blockNamespace=sprites\n    //% group=\"Effects\" weight=89\n    //% help=effects/clear-particles\n    export function clearParticles(anchor: Sprite | particles.ParticleAnchor) {\n        const sources = game.currentScene().particleSources;\n        if (!sources) return;\n        sources\n            .filter(ps => ps.anchor === anchor)\n            .forEach(ps => ps.destroy());\n    }\n\n    function createEffect(defaultParticlesPerSecond: number, defaultLifespan: number,\n            factoryFactory: (anchor?: particles.ParticleAnchor) => particles.ParticleFactory): ParticleEffect {\n        return new ParticleEffect(defaultParticlesPerSecond, defaultLifespan,\n                    (anchor: particles.ParticleAnchor, pps: number) =>\n                        new particles.ParticleSource(anchor, pps, factoryFactory()));\n    }\n\n    //% fixedInstance whenUsed block=\"spray\"\n    export const spray = createEffect(20, 2000, function () { return new particles.SprayFactory(100, 0, 120) });\n\n    //% fixedInstance whenUsed block=\"trail\"\n    export const trail = new ParticleEffect(20, 4000, function (anchor: particles.ParticleAnchor, particlesPerSecond: number) {\n        const factory = new particles.TrailFactory(anchor, 250, 1000);\n        return new particles.ParticleSource(anchor, particlesPerSecond, factory);\n    });\n\n    //% fixedInstance whenUsed block=\"fountain\"\n    export const fountain = new ParticleEffect(20, 3000, function (anchor: particles.ParticleAnchor, particlesPerSecond: number) {\n        class FountainFactory extends particles.SprayFactory {\n            galois: Math.FastRandom;\n\n            constructor() {\n                super(40, 180, 90);\n                this.galois = new Math.FastRandom(1234);\n            }\n\n            createParticle(anchor: particles.ParticleAnchor) {\n                const p = super.createParticle(anchor);\n                p.color = this.galois.randomBool() ? 8 : 9;\n                p.lifespan = 1500;\n                return p;\n            }\n\n            drawParticle(p: particles.Particle, x: Fx8, y: Fx8) {\n                screen.setPixel(Fx.toInt(x), Fx.toInt(y), p.color);\n            }\n        }\n\n        const factory = new FountainFactory();\n        const source = new particles.ParticleSource(anchor, particlesPerSecond, factory);\n        source.setAcceleration(0, 40);\n        return source;\n    });\n\n    //% fixedInstance whenUsed block=\"confetti\"\n    export const confetti = new ScreenEffect(10, 40, 4000, function (anchor: particles.ParticleAnchor, particlesPerSecond: number) {\n        const factory = new particles.ConfettiFactory(anchor.width ? anchor.width : 16, 16);\n        factory.setSpeed(30);\n        return new particles.ParticleSource(anchor, particlesPerSecond, factory);\n    });\n\n    //% fixedInstance whenUsed block=\"hearts\"\n    export const hearts = new ScreenEffect(5, 20, 2000, function (anchor: particles.ParticleAnchor, particlesPerSecond: number) {\n        const factory = new particles.ShapeFactory(anchor.width ? anchor.width : 16, 16, img`\n            . F . F .\n            F . F . F\n            F . . . F\n            . F . F .\n            . . F . .\n        `);\n\n        // if large anchor, increase lifespan\n        if (factory.xRange > 50) {\n            factory.minLifespan = 1000;\n            factory.maxLifespan = 2000;\n        }\n\n        factory.setSpeed(90);\n        return new particles.ParticleSource(anchor, particlesPerSecond, factory);\n    });\n\n    //% fixedInstance whenUsed block=\"smiles\"\n    export const smiles = new ScreenEffect(5, 25, 1500, function (anchor: particles.ParticleAnchor, particlesPerSecond: number) {\n        const factory = new particles.ShapeFactory(anchor.width ? anchor.width : 16, 16, img`\n            . f . f .\n            . f . f .\n            . . . . .\n            f . . . f\n            . f f f .\n        `);\n        // if large anchor, increase lifespan\n        if (factory.xRange > 50) {\n            factory.minLifespan = 1250;\n            factory.maxLifespan = 2500;\n        }\n\n        factory.setSpeed(50);\n        return new particles.ParticleSource(anchor, particlesPerSecond, factory);\n    });\n\n    //% fixedInstance whenUsed block=\"rings\"\n    export const rings = createEffect(5, 1000, function () {\n        return new particles.ShapeFactory(16, 16, img`\n            . F F F .\n            F . . . F\n            F . . . F\n            f . . . f\n            . f f f .\n        `);\n    });\n\n    //% fixedInstance whenUsed block=\"fire\"\n    export const fire = new ParticleEffect(50, 5000, function (anchor: particles.ParticleAnchor, particlesPerSecond: number) {\n        const factory = new particles.FireFactory(5);\n        const src = new particles.FireSource(anchor, particlesPerSecond, factory);\n        src.setAcceleration(0, -20);\n        return src;\n    });\n\n    //% fixedInstance whenUsed block=\"warm radial\"\n    export const warmRadial = createEffect(30, 2500, function () { return new particles.RadialFactory(0, 30, 10) });\n\n    //% fixedInstance whenUsed block=\"cool radial\"\n    export const coolRadial = createEffect(30, 2000, function () { return new particles.RadialFactory(0, 30, 10, [0x6, 0x7, 0x8, 0x9, 0xA]) });\n\n    //% fixedInstance whenUsed block=\"halo\"\n    export const halo = createEffect(70, 3000, function () {\n        class RingFactory extends particles.RadialFactory {\n            createParticle(anchor: particles.ParticleAnchor) {\n                const p = super.createParticle(anchor);\n                p.lifespan = this.galois.randomRange(200, 350);\n                return p;\n            }\n        }\n        return new RingFactory(30, 40, 10, [0x4, 0x4, 0x5]);\n    });\n\n    //% fixedInstance whenUsed block=\"ashes\"\n    export const ashes = new ParticleEffect(60, 2000, function (anchor: particles.ParticleAnchor, particlesPerSecond: number) {\n        const factory = new particles.AshFactory(anchor);\n        const src = new particles.ParticleSource(anchor, particlesPerSecond, factory);\n        src.setAcceleration(0, 500);\n        return src;\n    });\n\n    //% fixedInstance whenUsed block=\"disintegrate\"\n    export const disintegrate = new ParticleEffect(60, 1250, function (anchor: particles.ParticleAnchor, particlesPerSecond: number) {\n        const factory = new particles.AshFactory(anchor, true, 30);\n        factory.minLifespan = 200;\n        factory.maxLifespan = 500;\n        const src = new particles.ParticleSource(anchor, particlesPerSecond, factory);\n        src.setAcceleration(0, 750);\n        return src;\n    });\n\n    //% fixedInstance whenUsed block=\"blizzard\"\n    export const blizzard = new ScreenEffect(15, 50, 3000, function (anchor: particles.ParticleAnchor, particlesPerSecond: number) {\n        class SnowFactory extends particles.ShapeFactory {\n            constructor(xRange: number, yRange: number) {\n                super(xRange, yRange, img`F`);\n                this.addShape(img`\n                    F\n                    F`\n                );\n                this.minLifespan = 200;\n                this.maxLifespan = this.xRange > 50 ? 1200: 700;\n            }\n\n            createParticle(anchor: particles.ParticleAnchor) {\n                const p = super.createParticle(anchor);\n                p.color = this.galois.percentChance(80) ? 0x1 : 0x9;\n                return p;\n            }\n        }\n\n        const factory = new SnowFactory(anchor.width ? anchor.width : 16, anchor.height ? anchor.height : 16);\n        const src = new particles.ParticleSource(anchor, particlesPerSecond, factory);\n        src.setAcceleration(-300, -100);\n        return src;\n    });\n\n    //% fixedInstance whenUsed block=\"bubbles\"\n    export const bubbles = new ScreenEffect(15, 40, 5000, function (anchor: particles.ParticleAnchor, particlesPerSecond: number) {\n        const min = anchor.width > 50 ? 2000 : 500;\n        const factory = new particles.BubbleFactory(anchor, min, min * 2.5);\n        return new particles.BubbleSource(anchor, particlesPerSecond, factory.stateCount - 1, factory);\n    });\n\n    //% fixedInstance whenUsed block=\"star field\"\n    export const starField = new ScreenEffect(2, 5, 5000, function (anchor: particles.ParticleAnchor, particlesPerSecond: number) {\n        const factory = new particles.StarFactory([0x1, 0x3, 0x5, 0x9, 0xC]);\n        return new particles.ParticleSource(anchor, particlesPerSecond, factory);\n    });\n\n    //% fixedInstance whenUsed block=\"clouds\"\n    export const clouds = new ScreenEffect(.5, 1.5, 5000, function (anchor: particles.ParticleAnchor, particlesPerSecond: number) {\n        const factory = new particles.CloudFactory();\n        const source = new particles.ParticleSource(anchor, particlesPerSecond, factory);\n\n        // render behind tile map\n        source.z = -2;\n        return source;\n    });\n\n    //% fixedInstance whenUsed block=\"none\"\n    export const none = new ScreenEffect(0, 0, 0, function (anchor: particles.ParticleAnchor, particlesPerSecond: number) {\n        class NullParticleSource extends particles.ParticleSource {\n            constructor() {\n                super(null, 0);\n                this._prune();\n            }\n\n            __draw(camera: scene.Camera) {}\n\n            _update(dt: number) {}\n\n            // remove self at next opportunity\n            _prune() {\n                const scene = game.currentScene();\n                if (!scene)\n                    return;\n                scene.allSprites.removeElement(this);\n                const sources = scene.particleSources;\n                if (sources && sources.length)\n                    sources.removeElement(this);\n            }\n            destroy() { this._prune(); }\n            clear() { this.head = undefined; }\n        }\n        const source = new NullParticleSource();\n\n        return source;\n    });\n}","particlefactories.ts":"namespace particles {\n    let cachedSin: Fx8[];\n    let cachedCos: Fx8[];\n\n    const NUM_SLICES = 100;\n    const galois = new Math.FastRandom();\n    let angleSlice = 2 * Math.PI / NUM_SLICES;\n\n    /**\n     * Initialize sin and cos values for each slice to minimize recomputation\n     */\n    function initTrig() {\n        if (!cachedSin) {\n            cachedSin = cacheSin(NUM_SLICES);\n            cachedCos = cacheCos(NUM_SLICES);\n        }\n    }\n\n    /**\n     * @param slices number of cached sin values to make\n     * @returns array of cached sin values between 0 and 360 degrees\n     */\n    export function cacheSin(slices: number): Fx8[] {\n        let sin: Fx8[] = [];\n        let anglePerSlice = 2 * Math.PI / slices;\n        for (let i = 0; i < slices; i++) {\n            sin.push(Fx8(Math.sin(i * anglePerSlice)));\n        }\n        return sin;\n    }\n\n    /**\n     * @param slices number of cached cos values to make\n     * @returns array of cached cos values between 0 and 360 degrees\n     */\n    export function cacheCos(slices: number): Fx8[] {\n        let cos: Fx8[] = [];\n        let anglePerSlice = 2 * Math.PI / slices;\n        for (let i = 0; i < slices; i++) {\n            cos.push(Fx8(Math.cos(i * anglePerSlice)));\n        }\n        return cos;\n    }\n\n    const ratio = Math.PI / 180;\n    function toRadians(degrees: number) {\n        if (degrees < 0)\n            degrees = 360 - (Math.abs(degrees) % 360);\n        else\n            degrees = degrees % 360;\n\n        return degrees * ratio;\n    }\n\n    /**\n     * A factory for generating particles\n     */\n    export class ParticleFactory {\n\n        constructor() {\n            // Compiler errors if this doesn't exist\n        }\n\n        /**\n         * Generate a particle at the position of the given anchor\n         * @param anchor \n         */\n        createParticle(anchor: ParticleAnchor): Particle {\n            const p = new Particle();\n\n            p._x = Fx8(anchor.x);\n            p._y = Fx8(anchor.y);\n            p.vx = Fx.zeroFx8;\n            p.vy = Fx.zeroFx8;\n            p.lifespan = 500;\n\n            return p;\n        }\n\n        /**\n         * Draw the given particle at the given location\n         * @param particle \n         * @param x \n         * @param y \n         */\n        drawParticle(particle: Particle, x: Fx8, y: Fx8) {\n            screen.setPixel(Fx.toInt(x), Fx.toInt(y), 1);\n        }\n    }\n\n    /**\n     * A factory for creating a spray of particles\n     */\n    export class SprayFactory extends ParticleFactory {\n        protected speed: Fx8;\n        protected minAngle: number;\n        protected spread: number;\n\n        constructor(speed: number, centerDegrees: number, arcDegrees: number) {\n            super();\n            initTrig();\n            this.setSpeed(speed);\n            this.setDirection(centerDegrees, arcDegrees);\n        }\n\n        createParticle(anchor: ParticleAnchor) {\n            const p = super.createParticle(anchor);\n\n            const angle = (this.minAngle + galois.randomRange(0, this.spread)) % NUM_SLICES;\n            p.vx = Fx.mul(cachedSin[angle], this.speed);\n            p.vy = Fx.mul(cachedCos[angle], this.speed);\n\n            return p;\n        }\n\n        drawParticle(particle: Particle, x: Fx8, y: Fx8) {\n            screen.setPixel(Fx.toInt(x), Fx.toInt(y), 1);\n        }\n\n        setSpeed(pixelsPerSecond: number) {\n            this.speed = Fx8(pixelsPerSecond);\n        }\n\n        setDirection(centerDegrees: number, arcDegrees: number) {\n            this.minAngle = (toRadians(centerDegrees - (arcDegrees >> 1)) / angleSlice) | 0;\n            this.spread = (toRadians(arcDegrees) / angleSlice) | 0;\n        }\n    }\n\n    /**\n     * A factory for creating particles within rectangular area\n     */\n    export class AreaFactory extends SprayFactory {\n        xRange: number;\n        yRange: number;\n        minLifespan: number;\n        maxLifespan: number;\n        protected galois: Math.FastRandom;\n\n        constructor(xRange: number, yRange: number, minLifespan?: number, maxLifespan?: number) {\n            super(40, 0, 90);\n            this.xRange = xRange;\n            this.yRange = yRange;\n            this.minLifespan = minLifespan ? minLifespan : 150;\n            this.maxLifespan = maxLifespan ? maxLifespan : 850;\n            this.galois = new Math.FastRandom();\n        }\n\n        createParticle(anchor: ParticleAnchor) {\n            const p = super.createParticle(anchor);\n\n            p.lifespan = this.galois.randomRange(this.minLifespan, this.maxLifespan);\n            p._x = Fx.iadd(this.galois.randomRange(0, this.xRange) - (this.xRange >> 1), p._x);\n            p._y = Fx.iadd(this.galois.randomRange(0, this.yRange) - (anchor.height ? anchor.height >> 1 : 0), p._y);\n\n            return p;\n        }\n\n        drawParticle(p: Particle, x: Fx8, y: Fx8) {\n            const col = p.lifespan > 500 ?\n                4 : p.lifespan > 250 ?\n                    5 : 1;\n            screen.setPixel(Fx.toInt(x), Fx.toInt(y), col);\n        }\n    }\n\n    /**\n     * A factory for creating a trail that is emitted by sprites.\n     */\n    export class TrailFactory extends ParticleFactory {\n        minLifespan: number;\n        maxLifespan: number;\n        xRange: number;\n        yRange: number;\n        protected galois: Math.FastRandom;\n\n        constructor(sprite: ParticleAnchor, minLifespan: number, maxLifespan: number) {\n            super();\n            this.xRange = sprite.width ? sprite.width >> 1 : 8;\n            this.yRange = sprite.height ? sprite.height >> 1 : 8;\n            this.minLifespan = minLifespan;\n            this.maxLifespan = maxLifespan;\n            this.galois = new Math.FastRandom();\n        }\n\n        createParticle(anchor: ParticleAnchor) {\n            const p = super.createParticle(anchor);\n\n            p.lifespan = this.galois.randomRange(this.minLifespan, this.maxLifespan);\n            p._x = Fx.iadd(this.galois.randomRange(0, this.xRange) - (this.xRange >> 1), p._x);\n            p._y = Fx.iadd(this.galois.randomRange(0, this.yRange) - (this.yRange >> 1), p._y);\n            p.color = this.galois.randomRange(0x1, 0xF);\n\n            return p;\n        }\n\n        drawParticle(p: Particle, x: Fx8, y: Fx8) {\n            screen.setPixel(Fx.toInt(x), Fx.toInt(y), p.color);\n        }\n    }\n\n    /**\n     * A factory for creating particles with the provided shapes fall down the screen.\n     * \n     * Any pixels assigned to 0xF (black) in the provided shape will be replaced with a\n     * random color for each particle.\n     */\n    export class ShapeFactory extends AreaFactory {\n        protected sources: Image[];\n        protected ox: Fx8;\n        protected oy: Fx8;\n\n        constructor(xRange: number, yRange: number, source: Image) {\n            super(xRange, yRange);\n            this.sources = [source];\n\n            // Base offsets off of initial shape\n            this.ox = Fx8(source.width >> 1);\n            this.oy = Fx8(source.height >> 1);\n        }\n\n        /**\n         * Add another possible shape for a particle to display as\n         * @param shape \n         */\n        addShape(shape: Image) {\n            if (shape) this.sources.push(shape);\n        }\n\n        drawParticle(p: Particle, x: Fx8, y: Fx8) {\n            const pImage = this.galois.pickRandom(this.sources).clone();\n            pImage.replace(0xF, p.color);\n\n            screen.drawTransparentImage(pImage,\n                Fx.toInt(Fx.sub(x, this.ox)),\n                Fx.toInt(Fx.sub(y, this.oy))\n            );\n        }\n\n        createParticle(anchor: ParticleAnchor) {\n            const p = super.createParticle(anchor);\n            p.color = this.galois.randomRange(1, 14);\n            return p;\n        }\n    }\n\n    export class ConfettiFactory extends ShapeFactory {\n        constructor(xRange: number, yRange: number) {\n            const confetti = [\n                img`\n                    F\n                `,\n                img`\n                    F\n                    F\n                `,\n                img`\n                    F F\n                `,\n                img`\n                    F F\n                    F .\n                `,\n                img`\n                    F F\n                    . F\n            `];\n            super(xRange, yRange, confetti[0]);\n            for (let i = 1; i < confetti.length; i++) {\n                this.addShape(confetti[i]);\n            }\n\n            this.minLifespan = 1000;\n            this.maxLifespan = 4500;\n        }\n    }\n\n    export class FireFactory extends ParticleFactory {\n        protected galois: Math.FastRandom;\n        protected minRadius: number;\n        protected maxRadius: number;\n    \n        constructor(radius: number) {\n            super();\n            initTrig();\n            this.galois = new Math.FastRandom();\n            this.minRadius = radius >> 1;\n            this.maxRadius = radius;\n        }\n\n        createParticle(anchor: ParticleAnchor) {\n            const p = super.createParticle(anchor);\n            p.color = this.galois.randomBool() ?\n                2 : this.galois.randomBool() ?\n                    4 : 5;\n\n            const i = this.galois.randomRange(0, cachedCos.length);\n            const r = this.galois.randomRange(this.minRadius, this.maxRadius);\n\n            p._x = Fx.iadd(anchor.x, Fx.mul(Fx8(r), cachedCos[i]));\n            p._y = Fx.iadd(anchor.y, Fx.mul(Fx8(r), cachedSin[i]));\n            p.vy = Fx8(Math.randomRange(0, 10));\n            p.vx = Fx8(Math.randomRange(-5, 5));\n            p.lifespan = 1500;\n\n            return p;\n        }\n\n        drawParticle(p: Particle, x: Fx8, y: Fx8) {\n            screen.setPixel(\n                Fx.toInt(x),\n                Fx.toInt(y),\n                p.color\n            );\n        }\n    }\n\n    export class RadialFactory extends ParticleFactory {\n        protected r: Fx8;\n        protected speed: Fx8;\n        protected t: number;\n        protected spread: number;\n        protected galois: Math.FastRandom;\n        protected colors: number[];\n\n        constructor(radius: number, speed: number, spread: number, colors?: number[]) {\n            super();\n            initTrig();\n\n            if (colors && colors.length != 0)\n                this.colors = colors;\n            else\n                this.colors = [0x2, 0x3, 0x4, 0x5];\n\n            this.setRadius(radius)\n            this.speed = Fx8(-speed);\n            this.spread = spread;\n            this.t = 0;\n            this.galois = new Math.FastRandom();\n        }\n\n        createParticle(anchor: ParticleAnchor) {\n            const p = super.createParticle(anchor);\n            const time = ++this.t % cachedCos.length;\n            const offsetTime = (time + this.galois.randomRange(0, this.spread)) % cachedCos.length;\n\n            p._x = Fx.iadd(anchor.x, Fx.mul(this.r, cachedCos[time]));\n            p._y = Fx.iadd(anchor.y, Fx.mul(this.r, cachedSin[time]));\n            p.vx = Fx.mul(this.speed, Fx.neg(cachedSin[offsetTime]));\n            p.vy = Fx.mul(this.speed, cachedCos[offsetTime]);\n\n            p.lifespan = this.galois.randomRange(200, 1500);\n            p.color = this.galois.pickRandom(this.colors);\n\n            return p;\n        }\n\n        drawParticle(p: Particle, x: Fx8, y: Fx8) {\n            screen.setPixel(\n                Fx.toInt(x),\n                Fx.toInt(y),\n                p.color\n            );\n        }\n\n        setRadius(r: number) {\n            this.r = Fx8(r >> 1);\n        }\n\n        setSpeed(s: number) {\n            this.speed = Fx8(-s);\n        }\n\n        setSpread(s: number) {\n            this.spread = s;\n        }\n    }\n\n    class ColorCount {\n        constructor(public color: number, public count: number) { }\n    }\n\n    export class AshFactory extends AreaFactory {\n        private colors: ColorCount[];\n        \n        constructor(anchor: ParticleAnchor, updateImage?: boolean, percentKept: number = 20) {\n            super(anchor.width ? anchor.width : 8, anchor.height ? anchor.height >> 1 : 8, 300, 700);\n\n            if (!anchor.image) {\n                this.colors = [new ColorCount(1, 20)];\n                return;\n            }\n\n            let counts: number[] = [];\n            for (let i = 0x0; i <= 0xF; i++) {\n                counts[i] = 0;\n            }\n            let result: Image = anchor.image.clone();\n\n            for (let x = 0; x < result.width; x++) {\n                for (let y = 0; y < result.height; y++) {\n                    const c = result.getPixel(x, y);\n                    if (c && this.galois.percentChance(percentKept)) {\n                        counts[c]++;\n                        result.setPixel(x, y, 0x0);\n                    }\n                }\n            }\n\n            /** TODO: The following should be:\n             * if (updateImage && anchor.setImage) {\n             *     anchor.setImage(result);\n             * }\n             * but this fails due to https://github.com/Microsoft/pxt-arcade/issues/515 .\n             * This is a temporary workaround.\n             */\n            if (updateImage) {\n                (anchor as Sprite).setImage(result);\n            }\n\n            this.colors = counts\n                .map((value: number, index: number) => new ColorCount(index, value))\n                .filter(v => v.count != 0);\n        }\n\n        createParticle(anchor: ParticleAnchor) {\n            if (this.colors.length === 0) return undefined;\n\n            const index = this.galois.randomRange(0, this.colors.length - 1);\n            const choice = this.colors[index];\n            const p = super.createParticle(anchor);\n\n            choice.count--;\n            if (choice.count === 0) this.colors.removeAt(index);\n\n            p.color = choice.color;\n\n            p._y = Fx.iadd(this.galois.randomRange(this.yRange >> 1, this.yRange), p._y);\n            p.vx = anchor.vx ? Fx.neg(Fx8(anchor.vx >> 2)): Fx.zeroFx8;\n            p.vy = Fx8(this.galois.randomRange(-150, -50));\n\n            return p;\n        }\n\n        drawParticle(p: Particle, x: Fx8, y: Fx8) {\n            screen.setPixel(Fx.toInt(x), Fx.toInt(y), p.color);\n        }\n    }\n\n    export class BubbleFactory extends ParticleFactory {\n        minLifespan: number;\n        maxLifespan: number;\n        xRange: number;\n        yRange: number;\n        protected galois: Math.FastRandom;\n        protected states: Image[];\n    \n        constructor(sprite: ParticleAnchor, minLifespan: number, maxLifespan: number) {\n            super();\n            initTrig();\n            this.galois = new Math.FastRandom();\n\n            this.xRange = sprite.width ? sprite.width : 16;\n            this.yRange = 8;\n            this.minLifespan = minLifespan;\n            this.maxLifespan = maxLifespan;\n\n            this.states = [\n                img`\n                    F\n                `, img`\n                    F F\n                `, img`\n                    F F\n                    F F\n                `, img`\n                    F F F\n                    F . F\n                    F F F\n                `, img`\n                    . F F .\n                    F . . F\n                    F . . F\n                    . F F .\n                `, img`\n                    . F F F .\n                    F . . . F\n                    F . . . F\n                    . F F F .\n                `\n            ];\n        }\n\n        get stateCount(): number {\n            return this.states.length;\n        }\n\n        createParticle(anchor: ParticleAnchor) {\n            const p = super.createParticle(anchor);\n\n            p.lifespan = this.galois.randomRange(this.minLifespan, this.maxLifespan);\n            p._x = Fx.iadd(this.galois.randomRange(0, this.xRange) - (this.xRange >> 1), p._x);\n            p._y = Fx.iadd(this.galois.randomRange(-this.yRange, 0) + (anchor.height ? anchor.height >> 1 : 0), p._y);\n\n            p.vy = Fx8(Math.randomRange(-30, -5));\n            p.vx = Fx8(Math.randomRange(-10, 10));\n\n            p.data = this.galois.percentChance(80) ? 0 : 2;\n            p.color = this.galois.percentChance(90) ?\n                0x9 : (this.galois.percentChance(50) ?\n                    0x6 : 0x8);\n\n            return p;\n        }\n\n        drawParticle(p: Particle, x: Fx8, y: Fx8) {\n            const toDraw = this.states[p.data].clone();\n            toDraw.replace(0xF, p.color);\n            screen.drawTransparentImage(toDraw, Fx.toInt(x), Fx.toInt(y));\n        }\n    }\n\n    export class StarFactory extends ParticleFactory {\n        protected galois: Math.FastRandom;\n        protected possibleColors: number[]\n        minRate: number;\n        maxRate: number;\n        images: Image[];\n\n        constructor(possibleColors?: number[], minRate: number = 15, maxRate: number = 25) {\n            super();\n            this.galois = new Math.FastRandom();\n            this.minRate = minRate;\n            this.maxRate = maxRate;\n            this.images = [\n                img`\n                    1\n                `,\n                img`\n                    1 . 1\n                    . 1 .\n                    1 . 1\n                `, img`\n                    . 1 .\n                    1 1 1\n                    . 1 .\n                `\n            ];\n\n            if (possibleColors && possibleColors.length)\n                this.possibleColors = possibleColors\n            else\n                this.possibleColors = [1];\n        }\n\n        createParticle(anchor: ParticleAnchor) {\n            const p = super.createParticle(anchor);\n            const xRange = anchor.width ? anchor.width >> 1 : 8;\n\n            p._x = Fx8(this.galois.randomRange(anchor.x - xRange, anchor.x + xRange));\n            p._y = Fx8(anchor.height ? anchor.y - (anchor.height >> 1) : anchor.y);\n            p.vy = Fx8(this.galois.randomRange(this.minRate, this.maxRate));\n\n            // set lifespan based off velocity and screen height (plus a little to make sure it doesn't disappear early)\n            p.lifespan = Fx.toInt(Fx.mul(Fx.div(Fx8(screen.height + 20), p.vy), Fx8(1000)));\n\n            const length = this.possibleColors.length - 1;\n            p.color = this.possibleColors[this.possibleColors.length - 1];\n            for (let i = 0; i < length; ++i) {\n                if (this.galois.percentChance(80 - (i * 10))) {\n                    p.color = this.possibleColors[i];\n                    break;\n                }\n            }\n\n            // images besides the first one are only used on occasion\n            p.data = this.galois.percentChance(15) ? this.galois.randomRange(1, this.images.length - 1) : 0;\n\n            return p;\n        }\n\n        drawParticle(p: Particle, x: Fx8, y: Fx8) {\n            // on occasion, twinkle from white to yellow\n            const twinkleFlag = 0x8000;\n            const rest = 0x7FFF;\n            if (twinkleFlag && p.data) {\n                if (this.galois.percentChance(10)) {\n                    p.color = 1;\n                    p.data &= rest;\n                }\n            } else if (p.color === 1 && this.galois.percentChance(1)) {\n                p.color = 5;\n                p.data |= twinkleFlag;\n            }\n\n            const selected = this.images[rest & p.data].clone();\n            selected.replace(0x1, p.color);\n            screen.drawTransparentImage(selected, Fx.toInt(x), Fx.toInt(y));\n        }\n    }\n\n    export class CloudFactory extends ParticleFactory {\n        minRate: number;\n        maxRate: number;\n        clouds: Image[];\n        camera: scene.Camera;\n\n        constructor(minRate: number = 8, maxRate: number = 12) {\n            super();\n\n            this.minRate = minRate;\n            this.maxRate = maxRate;\n            this.camera = game.currentScene().camera;\n\n            this.clouds = [\n                img`\n                    . . . . . . . . . . f f f . . .\n                    . . . . . . . . . f f 9 f f . .\n                    . f f f . f f f . f 9 9 9 f f .\n                    f f 1 f f f 1 f f f 1 1 1 9 f f\n                    f 1 9 1 9 9 1 9 9 1 1 1 1 9 9 f\n                    f 9 1 9 9 1 9 1 1 9 1 1 1 1 1 f\n                    f f 1 1 1 1 1 1 1 1 1 1 1 1 1 f\n                    . f 1 1 1 1 9 9 1 f f f 1 1 1 f\n                    . f 1 f f f 9 f f f . f f 1 f f\n                    . f f f . f f f . . . . f f f .\n                `, img`\n                    . . . . . f f f f f . .\n                    . . f f . f 1 1 1 f f .\n                    f f f 1 f f 9 9 1 1 f .\n                    f 9 9 1 1 1 1 1 9 9 f f\n                    . f 1 9 9 1 9 1 1 1 1 f\n                    f 1 f f f 1 1 1 1 9 9 f\n                    f f f . f f f f 9 f f f\n                    . . . . . . . f f f . .\n                `, img`\n                    . . . . . . . . f f f . .\n                    . . . . . . . f f 1 f . .\n                    . f f f . . . f 1 9 f f .\n                    f f 1 f f . f f 1 1 1 f f\n                    f 1 9 1 f f f 1 9 1 1 1 f\n                    f f 1 9 1 1 1 9 1 1 1 1 f\n                    . f f 9 1 1 9 9 1 1 1 f f\n                    . . f 1 1 9 9 1 1 1 f f .\n                    . . f f 1 1 1 1 1 f f . .\n                    . . . f f 1 f f f f . . .\n                    . . . . f f f . . . . . .\n                `, img`\n                    . f f f .\n                    f 1 9 1 f\n                    f 9 1 1 f\n                    f f 1 f f\n                    . f f f .\n                `, img`\n                    . . . . . f f f f f f .\n                    . . . f f f 1 1 1 1 f f\n                    . f f f 1 9 1 1 9 1 1 f\n                    f f 1 1 9 1 1 1 9 1 1 f\n                    f 1 1 9 1 1 1 9 1 1 1 f\n                    f f 1 9 1 1 1 1 1 1 1 f\n                    . f f 1 1 1 1 1 1 1 f f\n                    . . f f f f f f f f f .\n                `, img`\n                    . f f f . .\n                    f f 1 f . .\n                    f 1 1 f f f\n                    f 1 9 9 1 f\n                    f 9 1 1 1 f\n                    f f 1 1 1 f\n                    . f 1 1 1 f\n                    . f f f f f\n                `, img`\n                    . . . . . . . . . . . . f f f\n                    . . . . . . . . . . f f f 1 f\n                    f f f f f . f f f . f 1 1 1 f\n                    f 1 1 1 f f f 1 f . f 1 1 1 f\n                    f f 1 1 1 f 1 1 f f f 1 1 1 f\n                    . f f 1 9 1 1 9 1 1 1 1 1 1 f\n                    . . f 9 1 1 1 9 1 1 1 1 1 f f\n                    . . f 1 1 1 9 9 1 1 1 1 1 f .\n                    . . f 1 1 9 9 1 1 1 1 1 f f .\n                    . . f f f 1 1 1 1 f f f f . .\n                    . . . . f f 1 f f f . . . . .\n                    . . . . . f f f . . . . . . .\n                `\n            ];\n        }\n\n        createParticle(anchor: ParticleAnchor) {\n            const p = super.createParticle(anchor);\n            const yRange = anchor.height ? anchor.height >> 1 : 8;\n            p.data = Math.randomRange(0, this.clouds.length - 1);\n            p._x = Fx8(anchor.width ? anchor.x + (anchor.width >> 1) : anchor.x)\n            p._y = Fx.add(\n                Fx8(Math.randomRange(anchor.y - yRange, anchor.y + yRange)),\n                Fx8(this.clouds[p.data].width >> 1)\n            );\n            p.vx = Fx8(-Math.randomRange(this.minRate, this.maxRate));\n\n            // p.color stores information on conjoined clouds\n            p.color = 0;\n            if (Math.percentChance(30)) {\n                const isConjoined = 1 << 0;\n                const isOffsetX = Math.randomRange(0, 1) << 1;\n                const isOffsetY = Math.randomRange(0, 1) << 2;\n                const selection = Math.randomRange(0, this.clouds.length - 1) << 3;\n\n                p.color = isConjoined | isOffsetX | isOffsetY | selection;\n            }\n\n            p.lifespan = Fx.toInt(\n                Fx.mul(\n                    Fx.div(\n                        Fx8(screen.width + 30),\n                        Fx.abs(p.vx)\n                    ),\n                    Fx8(1000)\n                )\n            );\n\n            return p;\n        }\n\n        drawParticle(p: particles.Particle, x: Fx8, y: Fx8) {\n            const mainImage = this.clouds[p.data];\n            screen.drawTransparentImage(\n                mainImage,\n                Fx.toInt(x),\n                Fx.toInt(y)\n            );\n\n            if (p.color & 1) {\n                const isOffsetX = (p.color >> 1) & 1;\n                const isOffsetY = (p.color >> 2) & 1;\n                const selection = this.clouds[p.color >> 3];\n\n                const xOffset = isOffsetX ? Fx8(mainImage.width >> 2) : Fx.zeroFx8;\n                const yOffset = isOffsetY ? Fx8(mainImage.height >> 2) : Fx.zeroFx8;\n\n                screen.drawTransparentImage(\n                    selection,\n                    Fx.toInt(Fx.add(x, xOffset)),\n                    Fx.toInt(Fx.add(y, yOffset))\n                );\n            }\n        }\n    }\n}\n","particles.ts":"namespace particles {\n    enum Flag {\n        enabled = 1 << 0,\n        destroyed = 1 << 1,\n        relativeToCamera = 1 << 2\n    }\n\n    // maximum count of sources before removing previous sources\n    //% whenUsed\n    const MAX_SOURCES = (() => {\n        const sz = control.ramSize();\n        if (sz <= 1024 * 100) {\n            return 8;\n        } else if (sz <= 1024 * 200) {\n            return 16;\n        } else {\n            return 50;\n        }\n    })();\n    const TIME_PRECISION = 10; // time goes down to down to the 1<<10 seconds\n    let lastUpdate: number;\n\n    /**\n     * A single particle\n     */\n    //% maxBgInstances=200\n    export class Particle {\n        _x: Fx8;\n        _y: Fx8;\n        vx: Fx8;\n        vy: Fx8;\n        lifespan: number;\n        next: Particle;\n        data?: number;\n        color?: number;\n    }\n\n    /**\n     * An anchor for a Particle to originate from\n     */\n    export interface ParticleAnchor {\n        x: number;\n        y: number;\n        vx?: number;\n        vy?: number;\n        width?: number;\n        height?: number;\n        image?: Image;\n        flags?: number;\n        setImage?: (i: Image) => void;\n    }\n\n    /**\n     * A source of particles\n     */\n    export class ParticleSource extends sprites.BaseSprite {\n        /**\n         * A relative ranking of this sources priority\n         * When necessary, a source with a lower priority will\n         * be culled before a source with a higher priority.\n         */\n        priority: number;\n        _dt: number;\n        /**\n         * The anchor this source is currently attached to\n         */\n        anchor: ParticleAnchor;\n        /**\n         * Time to live in milliseconds. The lifespan decreases by 1 on each millisecond\n         * and the source gets destroyed when it reaches 0.\n         */\n        lifespan: number;\n\n        protected pFlags: number;\n        protected head: Particle;\n        protected timer: number;\n        protected period: number;\n        protected _factory: ParticleFactory;\n\n        protected ax: Fx8;\n        protected ay: Fx8;\n\n        /**\n         * @param anchor to emit particles from\n         * @param particlesPerSecond rate at which particles are emitted\n         * @param factory [optional] factory to generate particles with; otherwise,\n         */\n        constructor(anchor: ParticleAnchor, particlesPerSecond: number, factory?: ParticleFactory) {\n            super(scene.SPRITE_Z)\n            init();\n            const sources = particleSources();\n\n            // remove and immediately destroy oldest source if over MAX_SOURCES\n            if (sources.length >= MAX_SOURCES) {\n                sortSources(sources);\n                const removedSource = sources.shift();\n                removedSource.clear();\n                removedSource.destroy();\n            }\n\n            this.pFlags = 0;\n            this.setRate(particlesPerSecond);\n            this.setAcceleration(0, 0);\n            this.setAnchor(anchor);\n            this.lifespan = undefined;\n            this._dt = 0;\n            this.priority = 0;\n            this.setFactory(factory || particles.defaultFactory);\n            sources.push(this);\n            this.enabled = true;\n        }\n\n        __draw(camera: scene.Camera) {\n            let current = this.head;\n            const left = (this.pFlags & Flag.relativeToCamera) ? Fx.zeroFx8 : Fx8(camera.drawOffsetX);\n            const top = (this.pFlags & Flag.relativeToCamera) ? Fx.zeroFx8 : Fx8(camera.drawOffsetY);\n\n            while (current) {\n                if (current.lifespan > 0)\n                    this.drawParticle(current, left, top);\n                current = current.next;\n            }\n        }\n\n        _update(dt: number) {\n            this.timer -= dt;\n\n            if (this.lifespan !== undefined) {\n                this.lifespan -= dt;\n                if (this.lifespan <= 0) {\n                    this.lifespan = undefined;\n                    this.destroy();\n                }\n            } else if (this.anchor && this.anchor.flags !== undefined && (this.anchor.flags & sprites.Flag.Destroyed)) {\n                this.lifespan = 750;\n            }\n\n            while (this.timer < 0 && this.enabled) {\n                this.timer += this.period;\n                const p = this._factory.createParticle(this.anchor);\n                if (!p) continue; // some factories can decide to not produce a particle\n                p.next = this.head;\n                this.head = p;\n            }\n\n            if (!this.head) return;\n\n            let current = this.head;\n\n            this._dt += dt;\n            let fixedDt = Fx8(this._dt);\n            if (fixedDt) {\n                do {\n                    if (current.lifespan > 0) {\n                        current.lifespan -= dt;\n                        this.updateParticle(current, fixedDt)\n                    }\n                } while (current = current.next);\n                this._dt = 0;\n            } else {\n                do {\n                    current.lifespan -= dt;\n                } while (current = current.next);\n            }\n        }\n\n        _prune() {\n            while (this.head && this.head.lifespan <= 0) {\n                this.head = this.head.next;\n            }\n\n            if ((this.pFlags & Flag.destroyed) && !this.head) {\n                const scene = game.currentScene();\n                if (scene)\n                    scene.allSprites.removeElement(this);\n                const sources = particleSources();\n                if (sources && sources.length)\n                    sources.removeElement(this);\n                this.anchor == undefined;\n            }\n\n            let current = this.head;\n            while (current && current.next) {\n                if (current.next.lifespan <= 0) {\n                    current.next = current.next.next;\n                } else {\n                    current = current.next;\n                }\n            }\n        }\n\n        /**\n         * Sets the acceleration applied to the particles\n         */\n        setAcceleration(ax: number, ay: number) {\n            this.ax = Fx8(ax);\n            this.ay = Fx8(ay);\n        }\n\n        /**\n         * Enables or disables particles\n         * @param on\n         */\n        setEnabled(on: boolean) {\n            this.enabled = on;\n        }\n\n        /**\n         * Sets whether the particle source is drawn relative to the camera or not\n         * @param on\n         */\n        setRelativeToCamera(on: boolean) {\n            if (on) this.pFlags |= Flag.relativeToCamera\n            else this.pFlags = ~(~this.pFlags | Flag.relativeToCamera);\n        }\n\n        get enabled() {\n            return !!(this.pFlags & Flag.enabled);\n        }\n\n        /**\n         * Set whether this source is currently enabled (emitting particles) or not\n         */\n        set enabled(v: boolean) {\n            if (v !== this.enabled) {\n                this.pFlags = v ? (this.pFlags | Flag.enabled) : (this.pFlags ^ Flag.enabled);\n                this.timer = 0;\n            }\n        }\n\n        /**\n         * Destroy the source\n         */\n        destroy() {\n            // The `_prune` step will finishing destroying this Source once all emitted particles finish rendering\n            this.enabled = false;\n            this.pFlags |= Flag.destroyed;\n            this._prune();\n        }\n\n        /**\n         * Clear all particles emitted from this source\n         */\n        clear() {\n            this.head = undefined;\n        }\n\n        /**\n         * Set a anchor for particles to be emitted from\n         * @param anchor\n         */\n        setAnchor(anchor: ParticleAnchor) {\n            this.anchor = anchor;\n        }\n\n        /**\n         * Sets the number of particle created per second\n         * @param particlesPerSecond\n         */\n        setRate(particlesPerSecond: number) {\n            this.period = Math.ceil(1000 / particlesPerSecond);\n            this.timer = 0;\n        }\n\n        get factory(): ParticleFactory {\n            return this._factory;\n        }\n\n        /**\n         * Sets the particle factory\n         * @param factory\n         */\n        setFactory(factory: ParticleFactory) {\n            if (factory)\n                this._factory = factory;\n        }\n\n        protected updateParticle(p: Particle, fixedDt: Fx8) {\n            fixedDt = Fx.rightShift(fixedDt, TIME_PRECISION);\n\n            p.vx = Fx.add(p.vx, Fx.mul(this.ax, fixedDt));\n            p.vy = Fx.add(p.vy, Fx.mul(this.ay, fixedDt));\n\n            p._x = Fx.add(p._x, Fx.mul(p.vx, fixedDt));\n            p._y = Fx.add(p._y, Fx.mul(p.vy, fixedDt));\n        }\n\n        protected drawParticle(p: Particle, screenLeft: Fx8, screenTop: Fx8) {\n            this._factory.drawParticle(p, Fx.sub(p._x, screenLeft), Fx.sub(p._y, screenTop));\n        }\n    }\n\n    //% whenUsed\n    export const defaultFactory = new particles.SprayFactory(20, 0, 60);\n\n    /**\n     * Creates a new source of particles attached to a sprite\n     * @param sprite\n     * @param particlesPerSecond number of particles created per second\n     */\n    export function createParticleSource(sprite: Sprite, particlesPerSecond: number): ParticleSource {\n        return new ParticleSource(sprite, particlesPerSecond);\n    }\n\n    function init() {\n        const scene = game.currentScene();\n        if (scene.particleSources) return;\n        scene.particleSources = [];\n        lastUpdate = control.millis();\n        game.onUpdate(updateParticles);\n        game.onUpdateInterval(250, pruneParticles);\n    }\n\n    function updateParticles() {\n        const sources = particleSources();\n        if (!sources) return;\n        sortSources(sources);\n\n        const time = control.millis();\n        const dt = time - lastUpdate;\n        lastUpdate = time;\n\n        for (let i = 0; i < sources.length; i++) {\n            sources[i]._update(dt);\n        }\n    }\n\n    function pruneParticles() {\n        const sources = particleSources();\n        if (sources) sources.slice(0, sources.length).forEach(s => s._prune());\n    }\n\n    function sortSources(sources: ParticleSource[]) {\n        sources.sort((a, b) => (a.priority - b.priority || a.id - b.id));\n    }\n\n    /**\n     * A source of particles where particles will occasionally change speed based off of each other\n     */\n    export class FireSource extends ParticleSource {\n        protected galois: Math.FastRandom;\n\n        constructor(anchor: ParticleAnchor, particlesPerSecond: number, factory?: ParticleFactory) {\n            super(anchor, particlesPerSecond, factory);\n            this.galois = new Math.FastRandom();\n            this.z = 20;\n        }\n\n        updateParticle(p: Particle, fixedDt: Fx8) {\n            super.updateParticle(p, fixedDt);\n            if (p.next && this.galois.percentChance(30)) {\n                p.vx = p.next.vx;\n                p.vy = p.next.vy;\n            }\n        }\n    }\n\n    /**\n     * A source of particles where the particles oscillate horizontally, and occasionally change\n     * between a given number of defined states\n     */\n    export class BubbleSource extends ParticleSource {\n        protected maxState: number;\n        protected galois: Math.FastRandom;\n        stateChangePercentage: number;\n        oscillationPercentage: number\n\n        constructor(anchor: ParticleAnchor, particlesPerSecond: number, maxState: number, factory?: ParticleFactory) {\n            super(anchor, particlesPerSecond, factory);\n            this.galois = new Math.FastRandom();\n            this.maxState = maxState;\n            this.stateChangePercentage = 3;\n            this.oscillationPercentage = 4;\n        }\n\n        updateParticle(p: Particle, fixedDt: Fx8) {\n            super.updateParticle(p, fixedDt);\n            if (this.galois.percentChance(this.stateChangePercentage)) {\n                if (p.data < this.maxState) {\n                    p.data++;\n                } else if (p.data > 0) {\n                    p.data--;\n                }\n            }\n\n            if (this.galois.percentChance(this.oscillationPercentage)) {\n                p.vx = Fx.neg(p.vx);\n            }\n        }\n    }\n\n    export function clearAll() {\n        const sources = particleSources();\n        if (sources) {\n            sources.forEach(s => s.clear());\n            pruneParticles();\n        }\n    }\n\n    /**\n     * Stop all particle sources from creating any new particles\n     */\n    export function disableAll() {\n        const sources = particleSources();\n        if (sources) {\n            sources.forEach(s => s.enabled = false);\n            pruneParticles();\n        }\n    }\n\n    /**\n     * Allow all particle sources to create any new particles\n     */\n    export function enableAll() {\n        const sources = particleSources();\n        if (sources) {\n            sources.forEach(s => s.enabled = true);\n            pruneParticles();\n        }\n    }\n\n    function particleSources() {\n        const sources = game.currentScene().particleSources;\n        return sources;\n    }\n}\n","physics.ts":"class PhysicsEngine {\n    constructor() {\n    }\n\n    /**\n     * Adds sprite to the physics\n     * @param sprite\n     */\n    addSprite(sprite: Sprite) { }\n\n    removeSprite(sprite: Sprite) { }\n\n    /** move a single sprite **/\n    moveSprite(s: Sprite, dx: Fx8, dy: Fx8) { }\n\n    draw() { }\n\n    /** Apply physics and collisions to all sprites **/\n    move(dt: number) { }\n\n    setMaxSpeed(speed: number) { }\n\n    overlaps(sprite: Sprite): Sprite[] { return []; }\n}\n\nconst MAX_TIME_STEP = 100; // milliseconds\nconst MIN_MOVE_GAP = Fx8(0.1);\n\nconst SPRITE_NO_TILE_OVERLAPS = SpriteFlag.GhostThroughTiles | sprites.Flag.Destroyed | SpriteFlag.RelativeToCamera;\nconst SPRITE_NO_WALL_COLLISION = SpriteFlag.GhostThroughWalls | sprites.Flag.IsClipping | sprites.Flag.Destroyed | SpriteFlag.RelativeToCamera;\nconst SPRITE_NO_SPRITE_OVERLAPS = SpriteFlag.GhostThroughSprites | sprites.Flag.Destroyed | SpriteFlag.RelativeToCamera;\n\nclass MovingSprite {\n    constructor(\n        public sprite: Sprite,\n        // vx and vy when last updated\n        public cachedVx: Fx8,\n        public cachedVy: Fx8,\n        // remaining x\n        public dx: Fx8,\n        public dy: Fx8,\n        // how much to move per step\n        public xStep: Fx8,\n        public yStep: Fx8\n    ) { }\n}\n\n/**\n * A physics engine that does simple AABB bounding box check\n */\nclass ArcadePhysicsEngine extends PhysicsEngine {\n    protected sprites: Sprite[];\n    protected map: sprites.SpriteMap;\n    protected maxVelocity: Fx8;\n    protected maxNegativeVelocity: Fx8;\n    protected minSingleStep: Fx8;\n    protected maxSingleStep: Fx8;\n\n    constructor(maxVelocity = 500, minSingleStep = 2, maxSingleStep = 4) {\n        super();\n        this.sprites = [];\n        this.map = new sprites.SpriteMap();\n        this.maxSpeed = maxVelocity;\n        this.maxStep = maxSingleStep;\n        this.minStep = minSingleStep;\n    }\n\n    get maxSpeed(): number {\n        return Fx.toInt(this.maxVelocity);\n    }\n\n    set maxSpeed(v: number) {\n        this.maxVelocity = Fx8(v);\n        this.maxNegativeVelocity = Fx.neg(this.maxVelocity);\n    }\n\n    get minStep(): number {\n        return Fx.toInt(this.minSingleStep);\n    }\n\n    set minStep(v: number) {\n        this.minSingleStep = Fx8(v);\n    }\n\n    get maxStep(): number {\n        return Fx.toInt(this.maxSingleStep);\n    }\n\n    set maxStep(v: number) {\n        this.maxSingleStep = Fx8(v);\n    }\n\n    setMaxSpeed(v: number) {\n        this.maxSpeed = v;\n    }\n\n    addSprite(sprite: Sprite) {\n        this.sprites.push(sprite);\n        const tm = game.currentScene().tileMap;\n        if (tm && tm.isOnWall(sprite)) {\n            sprite.flags |= sprites.Flag.IsClipping;\n        }\n    }\n\n    removeSprite(sprite: Sprite) {\n        this.sprites.removeElement(sprite);\n    }\n\n    draw() {\n        this.map.draw();\n    }\n\n    move(dt: number) {\n        // Sprite movement logic is done in milliseconds to avoid rounding errors with Fx8 numbers\n        const dtMs = Math.min(MAX_TIME_STEP, dt * 1000);\n        const dt2 = Math.idiv(dtMs, 2);\n\n        const scene = game.currentScene();\n\n        const tileMap = scene.tileMap;\n        const movingSprites = this.sprites\n            .map(sprite => this.createMovingSprite(sprite, dtMs, dt2));\n\n        // clear obstacles if moving on that axis\n        this.sprites.forEach(s => {\n            if (s.vx || s.vy) s.clearObstacles();\n        });\n\n        this.map.clear();\n        this.map.resizeBuckets(this.sprites);\n\n        const MAX_STEP_COUNT = Fx.toInt(\n            Fx.idiv(\n                Fx.imul(\n                    Fx.div(\n                        this.maxVelocity,\n                        this.minSingleStep\n                    ),\n                    dtMs\n                ),\n                1000\n            )\n        );\n        const overlapHandlers = scene.overlapHandlers.slice();\n\n        // buffers store the moving sprites on each step; switch back and forth between the two\n        let selected = 0;\n        let buffers = [movingSprites, []];\n        for (let count = 0; count < MAX_STEP_COUNT && buffers[selected].length !== 0; ++count) {\n            const currMovers = buffers[selected];\n            selected ^= 1;\n            const remainingMovers = buffers[selected];\n\n            for (let ms of currMovers) {\n                const s = ms.sprite;\n                // if still moving and speed has changed from a collision or overlap;\n                // reverse direction if speed has reversed\n                if (ms.cachedVx !== s._vx) {\n                    if (s._vx == Fx.zeroFx8) {\n                        ms.dx = Fx.zeroFx8;\n                    } else if (s._vx < Fx.zeroFx8 && ms.cachedVx > Fx.zeroFx8\n                        || s._vx > Fx.zeroFx8 && ms.cachedVx < Fx.zeroFx8) {\n                        ms.dx = Fx.neg(ms.dx);\n                        ms.xStep = Fx.neg(ms.xStep);\n                    }\n\n                    ms.cachedVx = s._vx;\n                }\n                if (ms.cachedVy !== s._vy) {\n                    if (s._vy == Fx.zeroFx8) {\n                        ms.dy = Fx.zeroFx8;\n                    } else if (s._vy < Fx.zeroFx8 && ms.cachedVy > Fx.zeroFx8\n                        || s._vy > Fx.zeroFx8 && ms.cachedVy < Fx.zeroFx8) {\n                        ms.dy = Fx.neg(ms.dy);\n                        ms.yStep = Fx.neg(ms.yStep);\n                    }\n\n                    ms.cachedVy = s._vy;\n                }\n\n                // identify how much to move in this step\n                const stepX = Fx.abs(ms.xStep) > Fx.abs(ms.dx) ? ms.dx : ms.xStep;\n                const stepY = Fx.abs(ms.yStep) > Fx.abs(ms.dy) ? ms.dy : ms.yStep;\n                ms.dx = Fx.sub(ms.dx, stepX);\n                ms.dy = Fx.sub(ms.dy, stepY);\n\n                s._lastX = s._x;\n                s._lastY = s._y;\n                s._x = Fx.add(s._x, stepX);\n                s._y = Fx.add(s._y, stepY);\n\n                if (!(s.flags & SPRITE_NO_SPRITE_OVERLAPS) && s._kindsOverlappedWith.length) {\n                    this.map.insertAABB(s);\n                }\n                if (tileMap && tileMap.enabled) {\n                    this.tilemapCollisions(ms, tileMap);\n                }\n\n                // check for screen edge collisions\n                const bounce = s.flags & sprites.Flag.BounceOnWall;\n                if (s.flags & sprites.Flag.StayInScreen || (bounce && !tileMap)) {\n                    this.screenEdgeCollisions(ms, bounce, scene.camera);\n                }\n\n                // if sprite still needs to move, add it to the next step of movements\n                if (Fx.abs(ms.dx) > MIN_MOVE_GAP || Fx.abs(ms.dy) > MIN_MOVE_GAP) {\n                    remainingMovers.push(ms);\n                }\n            }\n\n            // this step is done; check collisions between sprites\n            this.spriteCollisions(currMovers, overlapHandlers);\n            // clear moving sprites buffer for next step\n            while (currMovers.length) currMovers.pop();\n        }\n    }\n\n    protected createMovingSprite(sprite: Sprite, dtMs: number, dt2: number): MovingSprite {\n        const ovx = this.constrain(sprite._vx);\n        const ovy = this.constrain(sprite._vy);\n        sprite._lastX = sprite._x;\n        sprite._lastY = sprite._y;\n\n        if (sprite._ax) {\n            sprite._vx = Fx.add(\n                sprite._vx,\n                Fx.idiv(\n                    Fx.imul(\n                        sprite._ax,\n                        dtMs\n                    ),\n                    1000\n                )\n            );\n        } else if (sprite._fx) {\n            const fx = Fx.idiv(\n                Fx.imul(\n                    sprite._fx,\n                    dtMs\n                ),\n                1000\n            );\n            const c = Fx.compare(sprite._vx, fx);\n            if (c < 0) // v < f, v += f\n                sprite._vx = Fx.min(Fx.zeroFx8, Fx.add(sprite._vx, fx));\n            else if (c > 0) // v > f, v -= f\n                sprite._vx = Fx.max(Fx.zeroFx8, Fx.sub(sprite._vx, fx));\n            else\n                sprite._vx = Fx.zeroFx8\n        }\n\n        if (sprite._ay) {\n            sprite._vy = Fx.add(\n                sprite._vy,\n                Fx.idiv(\n                    Fx.imul(\n                        sprite._ay,\n                        dtMs\n                    ),\n                    1000\n                )\n            );\n        } else if (sprite._fy) {\n            const fy = Fx.idiv(\n                Fx.imul(\n                    sprite._fy,\n                    dtMs\n                ),\n                1000\n            );\n            const c = Fx.compare(sprite._vy, fy);\n            if (c < 0) // v < f, v += f\n                sprite._vy = Fx.min(Fx.zeroFx8, Fx.add(sprite._vy, fy));\n            else if (c > 0) // v > f, v -= f\n                sprite._vy = Fx.max(Fx.zeroFx8, Fx.sub(sprite._vy, fy));\n            else\n                sprite._vy = Fx.zeroFx8;\n        }\n\n        sprite._vx = this.constrain(sprite._vx);\n        sprite._vy = this.constrain(sprite._vy);\n\n        const dx = Fx8(Fx.toFloat(Fx.add(sprite._vx, ovx)) * dt2 / 1000);\n        const dy = Fx8(Fx.toFloat(Fx.add(sprite._vy, ovy)) * dt2 / 1000);\n\n        let xStep = dx;\n        let yStep = dy;\n\n        // make step increments smaller until under max step size\n        while (Fx.abs(xStep) > this.maxSingleStep || Fx.abs(yStep) > this.maxSingleStep) {\n            if (Fx.abs(xStep) > this.minSingleStep) {\n                xStep = Fx.idiv(xStep, 2);\n            }\n            if (Fx.abs(yStep) > this.minSingleStep) {\n                yStep = Fx.idiv(yStep, 2);\n            }\n        }\n\n        return new MovingSprite(\n            sprite,\n            sprite._vx,\n            sprite._vy,\n            dx,\n            dy,\n            xStep,\n            yStep\n        );\n    }\n\n    protected spriteCollisions(movedSprites: MovingSprite[], handlers: scene.OverlapHandler[]) {\n        control.enablePerfCounter(\"phys_collisions\");\n        if (!handlers.length) return;\n\n        // clear the overlap lists on all sprites\n        for (const sprite of this.sprites) {\n            sprite._alreadyChecked = undefined;\n        }\n\n        for (const bucket of this.map.filledBuckets) {\n            if (bucket.length === 1) continue;\n\n            for (const sprite of bucket) {\n                if (sprite.flags & SPRITE_NO_SPRITE_OVERLAPS) continue;\n\n                for (const overlapper of bucket) {\n                    if (overlapper === sprite) continue;\n                    const thisKind = sprite.kind();\n                    const otherKind = overlapper.kind();\n\n                    // the sprite with the higher id maintains the overlap lists\n                    const higher = sprite.id > overlapper.id ? sprite : overlapper;\n                    const lower = higher === sprite ? overlapper : sprite;\n\n                    if (!higher._alreadyChecked) {\n                        higher._alreadyChecked = [];\n                    }\n\n                    // skip if we already compared these two\n                    if (higher._alreadyChecked.indexOf(lower.id) !== -1) continue;\n\n                    higher._alreadyChecked.push(lower.id);\n\n                    // skip if already overlapping\n                    if (higher._overlappers.indexOf(lower.id) !== -1) continue;\n\n                    // skip if there is no overlap event between these two kinds of sprites\n                    if (sprite._kindsOverlappedWith.indexOf(otherKind) === -1) continue;\n\n                    // perform the actual overlap check\n                    if (!higher.overlapsWith(lower)) continue;\n\n                    // invoke all matching overlap event handlers\n                    for (const h of handlers) {\n                        if ((h.kind === thisKind && h.otherKind === otherKind)\n                            || (h.kind === otherKind && h.otherKind === thisKind)) {\n                            higher._overlappers.push(lower.id);\n                            control.runInParallel(() => {\n                                if (!((sprite.flags | overlapper.flags) & SPRITE_NO_SPRITE_OVERLAPS)) {\n                                    if (thisKind === h.kind) {\n                                        h.handler(sprite, overlapper)\n                                    }\n                                    else {\n                                        h.handler(overlapper, sprite)\n                                    }\n                                }\n                                higher._overlappers.removeElement(lower.id);\n                            });\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    protected screenEdgeCollisions(movingSprite: MovingSprite, bounce: number, camera: scene.Camera) {\n        let s = movingSprite.sprite;\n        if (!s.isStatic()) s.setHitbox();\n        if (!camera.isUpdated()) camera.update();\n\n        let offset = Fx.toFloat(s._hitbox.left) - camera.offsetX;\n        if (offset < 0) {\n            s.left -= offset;\n            if (bounce) s.vx = -s.vx;\n        }\n        else if ((offset = Fx.toFloat(s._hitbox.right) - camera.offsetX - screen.width) > 0) {\n            s.right -= offset;\n            if (bounce) s.vx = -s.vx;\n        }\n        if ((offset = Fx.toFloat(s._hitbox.top) - camera.offsetY) < 0) {\n            s.top -= offset;\n            if (bounce) s.vy = -s.vy;\n        }\n        else if ((offset = Fx.toFloat(s._hitbox.bottom) - camera.offsetY - screen.height) > 0) {\n            s.bottom -= offset;\n            if (bounce) s.vy = -s.vy;\n        }\n    }\n\n    protected tilemapCollisions(movingSprite: MovingSprite, tm: tiles.TileMap) {\n        const s = movingSprite.sprite;\n        // if the sprite is already clipping into a wall,\n        // allow free movement rather than randomly 'fixing' it\n        if (s.flags & sprites.Flag.IsClipping) {\n            if (!tm.isOnWall(s)) {\n                s.flags &= ~sprites.Flag.IsClipping;\n            }\n        }\n        if (!s.isStatic()) s.setHitbox();\n        const hbox = s._hitbox;\n        const tileScale = tm.scale;\n        const tileSize = 1 << tileScale;\n\n        const xDiff = Fx.sub(\n            s._x,\n            s._lastX\n        );\n\n        const yDiff = Fx.sub(\n            s._y,\n            s._lastY\n        );\n\n        if (!(s.flags & SPRITE_NO_WALL_COLLISION)) {\n            if (xDiff !== Fx.zeroFx8) {\n                const right = xDiff > Fx.zeroFx8;\n                const x0 = Fx.toIntShifted(\n                    Fx.add(\n                        right ?\n                            Fx.add(hbox.right, Fx.oneFx8)\n                            :\n                            Fx.sub(hbox.left, Fx.oneFx8),\n                        Fx.oneHalfFx8\n                    ),\n                    tileScale\n                );\n\n                const collidedTiles: sprites.StaticObstacle[] = [];\n\n                // check collisions with tiles sprite is moving towards horizontally\n                for (\n                    let y = Fx.sub(hbox.top, yDiff);\n                    y < Fx.iadd(tileSize, Fx.sub(hbox.bottom, yDiff));\n                    y = Fx.iadd(tileSize, y)\n                ) {\n                    const y0 = Fx.toIntShifted(\n                        Fx.add(\n                            Fx.min(\n                                y,\n                                Fx.sub(\n                                    hbox.bottom,\n                                    yDiff\n                                )\n                            ),\n                            Fx.oneHalfFx8\n                        ),\n                        tileScale\n                    );\n\n                    if (tm.isObstacle(x0, y0)) {\n                        const obstacle = tm.getObstacle(x0, y0);\n                        if (!collidedTiles.some(o => o.tileIndex === obstacle.tileIndex)) {\n                            collidedTiles.push(obstacle);\n                        }\n                    }\n                }\n\n                if (collidedTiles.length) {\n                    const collisionDirection = right ? CollisionDirection.Right : CollisionDirection.Left;\n                    s._x = Fx.sub(\n                        right ?\n                            Fx.sub(\n                                Fx8(x0 << tileScale),\n                                hbox.width\n                            )\n                            :\n                            Fx8((x0 + 1) << tileScale),\n                        hbox.ox\n                    );\n\n                    for (const tile of collidedTiles) {\n                        if(!(s.flags & SPRITE_NO_WALL_COLLISION)) {\n                            s.registerObstacle(collisionDirection, tile, tm);\n                        }\n                    }\n\n                    if (s.flags & sprites.Flag.DestroyOnWall) {\n                        s.destroy();\n                    } else if (s._vx === movingSprite.cachedVx && !(s.flags & SPRITE_NO_WALL_COLLISION)) {\n                        // sprite collision event didn't change velocity in this direction;\n                        // apply normal updates\n                        if (s.flags & sprites.Flag.BounceOnWall) {\n                            if ((!right && s.vx < 0) || (right && s.vx > 0)) {\n                                s._vx = Fx.neg(s._vx);\n                                movingSprite.xStep = Fx.neg(movingSprite.xStep);\n                                movingSprite.dx = Fx.neg(movingSprite.dx);\n                            }\n                        } else {\n                            movingSprite.dx = Fx.zeroFx8;\n                            s._vx = Fx.zeroFx8;\n                        }\n                    } else if (Math.sign(Fx.toInt(s._vx)) === Math.sign(Fx.toInt(movingSprite.cachedVx))) {\n                        // sprite collision event changed velocity,\n                        // but still facing same direction; prevent further movement this update.\n                        movingSprite.dx = Fx.zeroFx8;\n                    }\n                }\n            }\n\n            if (yDiff !== Fx.zeroFx8) {\n                const down = yDiff > Fx.zeroFx8;\n                const y0 = Fx.toIntShifted(\n                    Fx.add(\n                        down ?\n                            Fx.add(hbox.bottom, Fx.oneFx8)\n                            :\n                            Fx.sub(hbox.top, Fx.oneFx8),\n                        Fx.oneHalfFx8\n                    ),\n                    tileScale\n                );\n                const collidedTiles: sprites.StaticObstacle[] = [];\n\n                // check collisions with tiles sprite is moving towards vertically\n                for (\n                    let x = hbox.left;\n                    x < Fx.iadd(tileSize, hbox.right);\n                    x = Fx.iadd(tileSize, x)\n                ) {\n                    const x0 = Fx.toIntShifted(\n                        Fx.add(\n                            Fx.min(\n                                x,\n                                hbox.right\n                            ),\n                            Fx.oneHalfFx8\n                        ),\n                        tileScale\n                    );\n\n                    if (tm.isObstacle(x0, y0)) {\n                        const obstacle = tm.getObstacle(x0, y0);\n                        if (!collidedTiles.some(o => o.tileIndex === obstacle.tileIndex)) {\n                            collidedTiles.push(obstacle);\n                        }\n                    }\n                }\n\n                if (collidedTiles.length) {\n                    const collisionDirection = down ? CollisionDirection.Bottom : CollisionDirection.Top;\n                    s._y = Fx.sub(\n                        down ?\n                            Fx.sub(\n                                Fx8(y0 << tileScale),\n                                hbox.height\n                            )\n                            :\n                            Fx8((y0 + 1) << tileScale),\n                        hbox.oy\n                    );\n\n                    for (const tile of collidedTiles) {\n                        if(!(s.flags & SPRITE_NO_WALL_COLLISION)) {\n                            s.registerObstacle(collisionDirection, tile, tm);\n                        }\n                    }\n\n                    if (s.flags & sprites.Flag.DestroyOnWall) {\n                        s.destroy();\n                    } else if (s._vy === movingSprite.cachedVy && !(s.flags & SPRITE_NO_WALL_COLLISION)) {\n                        // sprite collision event didn't change velocity in this direction;\n                        // apply normal updates\n                        if (s.flags & sprites.Flag.BounceOnWall) {\n                            if ((!down && s.vy < 0) || (down && s.vy > 0)) {\n                                s._vy = Fx.neg(s._vy);\n                                movingSprite.yStep = Fx.neg(movingSprite.yStep);\n                                movingSprite.dy = Fx.neg(movingSprite.dy);\n                            }\n                        } else {\n                            movingSprite.dy = Fx.zeroFx8;\n                            s._vy = Fx.zeroFx8;\n                        }\n                    } else if (Math.sign(Fx.toInt(s._vy)) === Math.sign(Fx.toInt(movingSprite.cachedVy))) {\n                        // sprite collision event changed velocity,\n                        // but still facing same direction; prevent further movement this update.\n                        movingSprite.dy = Fx.zeroFx8;\n                    }\n                }\n            }\n        }\n\n\n        if (!(s.flags & SPRITE_NO_TILE_OVERLAPS)) {\n            // Now that we've moved, check all of the tiles underneath the current position\n            // for overlaps\n            const overlappedTiles: tiles.Location[] = [];\n            for (\n                let x = hbox.left;\n                x < Fx.iadd(tileSize, hbox.right);\n                x = Fx.iadd(tileSize, x)\n            ) {\n                const x0 = Fx.toIntShifted(\n                    Fx.add(\n                        Fx.min(\n                            x,\n                            hbox.right\n                        ),\n                        Fx.oneHalfFx8\n                    ),\n                    tileScale\n                );\n                for (\n                    let y = hbox.top;\n                    y < Fx.iadd(tileSize, hbox.bottom);\n                    y = Fx.iadd(tileSize, y)\n                ) {\n                    const y0 = Fx.toIntShifted(\n                        Fx.add(\n                            Fx.min(\n                                y,\n                                hbox.bottom\n                            ),\n                            Fx.oneHalfFx8\n                        ),\n                        tileScale\n                    );\n\n                    // if the sprite can move through walls, it can overlap the underlying tile.\n                    if (!tm.isObstacle(x0, y0) || !!(s.flags & sprites.Flag.GhostThroughWalls)) {\n                        overlappedTiles.push(tm.getTile(x0, y0));\n                    }\n                }\n            }\n\n            if (overlappedTiles.length) {\n                this.tilemapOverlaps(s, overlappedTiles);\n            }\n        }\n    }\n\n    /**\n     * Given a sprite and a list of overlapped tiles, checks the overlap handlers and calls\n     * the ones appropriate to the sprite and tile kind.\n     * @param sprite the sprite\n     * @param overlappedTiles the list of tiles the sprite is overlapping\n     */\n    protected tilemapOverlaps(sprite: Sprite, overlappedTiles: tiles.Location[]) {\n        const alreadyHandled: tiles.Location[] = [];\n\n        for (const tile of overlappedTiles) {\n            if (alreadyHandled.some(l => l.column === tile.column && l.row === tile.row)) {\n                continue;\n            }\n            alreadyHandled.push(tile);\n\n            const tileOverlapHandlers = game.currentScene().tileOverlapHandlers;\n            if (tileOverlapHandlers) {\n                tileOverlapHandlers\n                    .filter(h => h.spriteKind == sprite.kind() && h.tileKind.equals(tiles.getTileImage(tile)))\n                    .forEach(h => h.handler(sprite, tile));\n            }\n        }\n    }\n\n    /**\n     * Returns sprites that overlap with the given sprite. If type is non-zero, also filter by type.\n     * @param sprite\n     * @param layer\n     */\n    overlaps(sprite: Sprite): Sprite[] {\n        return this.map.overlaps(sprite);\n    }\n\n    /** moves a sprite explicitly outside of the normal velocity changes **/\n    public moveSprite(s: Sprite, dx: Fx8, dy: Fx8) {\n        s._lastX = s._x;\n        s._lastY = s._y;\n        s._x = Fx.add(s._x, dx);\n        s._y = Fx.add(s._y, dy);\n\n        // if the sprite can collide with things, check tile map\n        const tm = game.currentScene().tileMap;\n        if (tm && tm.enabled) {\n            const maxDist = Fx.toInt(this.maxSingleStep);\n            // only check tile map if moving within a single step\n            if (Math.abs(Fx.toInt(dx)) <= maxDist && Math.abs(Fx.toInt(dy)) <= maxDist) {\n                const ms = new MovingSprite(\n                    s,\n                    s._vx,\n                    s._vy,\n                    dx,\n                    dy,\n                    dx,\n                    dy\n                );\n                this.tilemapCollisions(ms, tm);\n                // otherwise, accept movement...\n            } else if (tm.isOnWall(s) && !this.canResolveClipping(s, tm)) {\n                // if no luck, flag as clipping into a wall\n                s.flags |= sprites.Flag.IsClipping;\n            } else {\n                // or clear clipping if no longer clipping\n                s.flags &= ~sprites.Flag.IsClipping;\n            }\n        }\n    }\n\n    // Attempt to resolve clipping by moving the sprite slightly up / down / left / right\n    protected canResolveClipping(s: Sprite, tm: tiles.TileMap) {\n        if (!s.isStatic()) s.setHitbox();\n        const hbox = s._hitbox;\n        const sz = 1 << tm.scale;\n        const maxMove = this.maxStep;\n        const origY = s._y;\n        const origX = s._x;\n        const l = Fx.toInt(hbox.left);\n        const r = Fx.toInt(hbox.right);\n        const t = Fx.toInt(hbox.top);\n        const b = Fx.toInt(hbox.bottom);\n\n        {   // bump up and test;\n            const offset = (b + 1) % sz;\n            if (offset <= maxMove) {\n                s._y = Fx.sub(\n                    s._y,\n                    Fx8(offset)\n                );\n                if (!tm.isOnWall(s)) {\n                    return true;\n                } else {\n                    s._y = origY;\n                }\n            }\n        }\n        {   // bump down and test;\n            const offset = (Math.floor(t / sz) + 1) * sz - t;\n            if (offset <= maxMove) {\n                s._y = Fx.add(\n                    s._y,\n                    Fx8(offset)\n                );\n                if (!tm.isOnWall(s)) {\n                    return true;\n                } else {\n                    s._y = origY;\n                }\n            }\n        }\n        {   // bump left and test;\n            const offset = (r + 1) % sz;\n            if (offset <= maxMove) {\n                s._x = Fx.sub(\n                    s._x,\n                    Fx8(offset)\n                );\n                if (!tm.isOnWall(s)) {\n                    return true;\n                } else {\n                    s._x = origX;\n                }\n            }\n        }\n        {   // bump right and test;\n            const offset = (Math.floor(l / sz) + 1) * sz - l;\n            if (offset <= maxMove) {\n                s._x = Fx.add(\n                    s._x,\n                    Fx8(offset)\n                );\n                if (!tm.isOnWall(s)) {\n                    return true;\n                } else {\n                    s._x = origX;\n                }\n            }\n        }\n\n        // no trivial adjustment worked; it's going to clip for now\n        return false;\n    }\n\n    protected constrain(v: Fx8) {\n        return Fx.max(\n            Fx.min(\n                this.maxVelocity,\n                v\n            ),\n            this.maxNegativeVelocity\n        );\n    }\n}\n","prompt.ts":"namespace game {\n    export const _KEYBOARD_CHANGE_EVENT = 7339;\n    export const _KEYBOARD_ENTER_EVENT = 7340;\n    export const _KEYBOARD_CANCEL_EVENT = 7341;\n\n    export interface PromptTheme {\n        colorPrompt: number;\n        colorInput: number;\n        colorInputHighlighted: number;\n        colorInputText: number;\n        colorAlphabet: number;\n        colorCursor: number;\n        colorBackground: number;\n        colorBottomBackground: number;\n        colorBottomText: number;\n    }\n\n    /**\n     * Ask the player for a string value.\n     * @param message The message to display on the text-entry screen\n     * @param answerLength The maximum number of characters the user can enter (1 - 24)\n     * @param useOnScreenKeyboard Force the simulator to use the on-screen keyboard for text entry\n     */\n    //% weight=10 help=game/ask-for-string\n    //% blockId=gameaskforstring\n    //% block=\"ask for string $message || and max length $answerLength use on-screen keyboard $useOnScreenKeyboard\"\n    //% message.shadow=text\n    //% message.defl=\"\"\n    //% answerLength.defl=\"12\"\n    //% answerLength.min=1\n    //% answerLength.max=24\n    //% group=\"Prompt\"\n    export function askForString(message: any, answerLength = 12, useOnScreenKeyboard = false) {\n        let p = new game.Prompt();\n        const result = p.show(console.inspect(message), answerLength, useOnScreenKeyboard);\n        return result;\n    }\n\n\n    //% whenUsed=true\n    const font = image.font8; // FONT8-TODO\n    //% whenUsed=true\n    const PADDING = 4;\n\n    //% whenUsed=true\n    const NUM_LETTERS = 26;\n    //% whenUsed=true\n    const ALPHABET_ROW_LENGTH = 12;\n    //% whenUsed=true\n    const NUM_ROWS = Math.ceil(NUM_LETTERS / ALPHABET_ROW_LENGTH);\n    //% whenUsed=true\n    const INPUT_ROWS = 2;\n\n    //% whenUsed=true\n    const CONTENT_WIDTH = screen.width - PADDING * 2;\n    //% whenUsed=true\n    const CONTENT_HEIGHT = screen.height - PADDING * 2;\n    //% whenUsed=true\n    const CONTENT_TOP = PADDING;\n\n    // Dimensions of a \"cell\" that contains a letter\n    //% whenUsed=true\n    const CELL_WIDTH = Math.floor(CONTENT_WIDTH / ALPHABET_ROW_LENGTH);\n    //% whenUsed=true\n    const CELL_HEIGHT = CELL_WIDTH;\n    //% whenUsed=true\n    const LETTER_OFFSET_X = Math.floor((CELL_WIDTH - font.charWidth) / 2);\n    //% whenUsed=true\n    const LETTER_OFFSET_Y = Math.floor((CELL_HEIGHT - font.charHeight) / 2);\n    //% whenUsed=true\n    const BLANK_PADDING = 1;\n    //% whenUsed=true\n    const ROW_LEFT = PADDING + Math.floor((CONTENT_WIDTH - (CELL_WIDTH * ALPHABET_ROW_LENGTH)) / 2);\n\n    // Dimensions of the bottom bar\n    //% whenUsed=true\n    const BOTTOM_BAR_ALPHABET_MARGIN = 4;\n    //% whenUsed=true\n    const BOTTOM_BAR_HEIGHT = PADDING + BOTTOM_BAR_ALPHABET_MARGIN + CELL_HEIGHT;\n    //% whenUsed=true\n    const BOTTOM_BAR_BUTTON_WIDTH = PADDING * 2 + font.charWidth * 3;\n    //% whenUsed=true\n    const BOTTOM_BAR_TEXT_Y = (BOTTOM_BAR_HEIGHT - font.charHeight) / 2;\n    //% whenUsed=true\n    const BOTTOM_BAR_SHIFT_X = (BOTTOM_BAR_BUTTON_WIDTH - font.charWidth * 3) / 2;\n    //% whenUsed=true\n    const BOTTOM_BAR_CONFIRM_X = (BOTTOM_BAR_BUTTON_WIDTH - font.charWidth * 2) / 2;\n    //% whenUsed=true\n    const CONFIRM_BUTTON_LEFT = screen.width - BOTTOM_BAR_BUTTON_WIDTH;\n\n    // Dimensions of the alphabet area\n    //% whenUsed=true\n    const ALPHABET_HEIGHT = NUM_ROWS * CELL_HEIGHT;\n    //% whenUsed=true\n    const ALPHABET_TOP = CONTENT_TOP + CONTENT_HEIGHT - ALPHABET_HEIGHT - BOTTOM_BAR_HEIGHT;\n    //% whenUsed=true\n    const ALPHABET_INPUT_MARGIN = 10;\n\n    // Dimensions of area where text is input\n    //% whenUsed=true\n    const INPUT_HEIGHT = INPUT_ROWS * CELL_HEIGHT;\n    //% whenUsed=true\n    const INPUT_TOP = ALPHABET_TOP - INPUT_HEIGHT - ALPHABET_INPUT_MARGIN;\n\n    //% whenUsed=true\n    const lowerShiftText = \"ABC\";\n    //% whenUsed=true\n    const upperShiftText = \"abc\";\n    //% whenUsed=true\n    const digitsUpper = [\" \", \",\", \".\", \"?\", \"!\", \":\", \";\", \"\\\"\", \"(\", \")\"];\n    //% whenUsed=true\n    const confirmText = \"OK\";\n\n\n    export class Prompt {\n        theme: PromptTheme;\n\n        message: string;\n        answerLength: number;\n        result: string;\n\n        protected confirmPressed: boolean;\n        protected cursorRow: number;\n        protected cursorColumn: number;\n        protected upper: boolean;\n        protected useSystemKeyboard: boolean;\n\n        protected renderable: scene.Renderable;\n        protected selectionStart: number;\n        protected selectionEnd: number;\n\n        protected keyboardRows: number;\n        protected keyboardColumns: number;\n\n        private changeTime = 0;\n\n        constructor(theme?: PromptTheme) {\n            if (theme) {\n                this.theme = theme;\n            }\n            else {\n                this.theme = {\n                    colorPrompt: 1,\n                    colorInput: 3,\n                    colorInputHighlighted: 5,\n                    colorInputText: 1,\n                    colorAlphabet: 1,\n                    colorCursor: 7,\n                    colorBackground: 15,\n                    colorBottomBackground: 3,\n                    colorBottomText: 1,\n                };\n            }\n            this.cursorRow = 0;\n            this.cursorColumn = 0;\n            this.upper = false;\n            this.result = \"\";\n            this.keyboardColumns = ALPHABET_ROW_LENGTH;\n            this.keyboardRows = NUM_ROWS;\n            this.selectionStart = 0;\n            this.selectionEnd = 0;\n        }\n\n        show(message: string, answerLength: number, useOnScreenKeyboard = false) {\n            this.message = message;\n            this.answerLength = answerLength;\n\n            controller._setUserEventsEnabled(false);\n            game.pushScene()\n\n            this.createRenderable();\n            this.confirmPressed = false;\n\n            if (!useOnScreenKeyboard && control.deviceDalVersion() === \"sim\" && helpers._isSystemKeyboardSupported()) {\n                this.useSystemKeyboard = true;\n                helpers._promptForText(this.answerLength, this.numbersOnly());\n                this.selectionEnd = 0;\n                this.selectionStart = 0;\n                control.onEvent(_KEYBOARD_CHANGE_EVENT, 0, () => {\n                    this.result = helpers._getTextPromptString().substr(0, this.answerLength);\n\n                    this.changeTime = game.runtime();\n\n                    this.selectionStart = helpers._getTextPromptSelectionStart();\n                    this.selectionEnd = helpers._getTextPromptSelectionEnd();\n                })\n\n                let cancelled = false;\n                let finished = false;\n\n                control.onEvent(_KEYBOARD_CANCEL_EVENT, 0, () => {\n                    cancelled = true;\n                });\n\n                control.onEvent(_KEYBOARD_ENTER_EVENT, 0, () => {\n                    finished = true;\n                });\n\n                pauseUntil(() => cancelled || finished);\n\n                if (cancelled) {\n                    this.useSystemKeyboard = false;\n                    this.selectionStart = this.result.length;\n                    this.selectionEnd = this.selectionStart;\n                    this.registerHandlers();\n                    pauseUntil(() => this.confirmPressed);\n                }\n            }\n            else {\n                this.useSystemKeyboard = false;\n                this.registerHandlers();\n                pauseUntil(() => this.confirmPressed);\n            }\n\n            game.popScene();\n            controller._setUserEventsEnabled(true);\n\n            return this.result;\n        }\n\n        protected numbersOnly() {\n            return false;\n        }\n\n        protected createRenderable() {\n            if (this.renderable) {\n                this.renderable.destroy();\n            }\n\n            const promptText = new sprites.RenderText(this.message, CONTENT_WIDTH);\n            let systemKeyboardText: sprites.RenderText;\n\n            this.renderable = scene.createRenderable(-1, () => {\n                promptText.draw(screen, (screen.width >> 1) - (promptText.width >> 1), CONTENT_TOP, this.theme.colorPrompt, 0, 2)\n                this.drawInputArea();\n\n                if (!this.useSystemKeyboard) {\n                    this.drawKeyboard();\n                    this.drawBottomBar();\n                    return;\n                }\n\n                if (!systemKeyboardText) {\n                    systemKeyboardText = new sprites.RenderText(helpers._getLocalizedInstructions(), CONTENT_WIDTH);\n                }\n\n                screen.fillRect(0, screen.height - (PADDING << 1) - systemKeyboardText.height, screen.width, screen.height, this.theme.colorBottomBackground);\n                systemKeyboardText.draw(screen, PADDING, screen.height - PADDING - systemKeyboardText.height, this.theme.colorBottomText);\n            });\n        }\n\n        protected drawInputArea() {\n            const answerLeft = ROW_LEFT + Math.floor(\n                ((CELL_WIDTH * ALPHABET_ROW_LENGTH) -\n                    CELL_WIDTH * Math.min(this.answerLength, ALPHABET_ROW_LENGTH)) / 2);\n\n            for (let i = 0; i < this.answerLength; i++) {\n                const col = i % ALPHABET_ROW_LENGTH;\n                const row = Math.floor(i / ALPHABET_ROW_LENGTH);\n\n                if (this.selectionStart !== this.selectionEnd && i >= this.selectionStart && i < this.selectionEnd) {\n                    screen.fillRect(\n                        answerLeft + col * CELL_WIDTH,\n                        INPUT_TOP + row * CELL_HEIGHT,\n                        CELL_WIDTH,\n                        CELL_HEIGHT,\n                        this.theme.colorCursor\n                    );\n                }\n\n                screen.fillRect(\n                    answerLeft + col * CELL_WIDTH + BLANK_PADDING,\n                    INPUT_TOP + row * CELL_HEIGHT + CELL_HEIGHT - 1,\n                    CELL_WIDTH - BLANK_PADDING * 2,\n                    1,\n                    !this.useSystemKeyboard && !this.blink() && i === this.selectionStart ? this.theme.colorInputHighlighted : this.theme.colorInput\n                );\n\n                if (i < this.result.length) {\n                    const char = this.result.charAt(i);\n                    screen.print(\n                        char,\n                        answerLeft + col * CELL_WIDTH + LETTER_OFFSET_X,\n                        INPUT_TOP + row * CELL_HEIGHT + LETTER_OFFSET_Y,\n                        this.theme.colorInputText,\n                        font\n                    );\n                }\n            }\n\n            // draw the blinking text cursor\n            if (this.useSystemKeyboard) {\n                if (this.selectionStart === this.selectionEnd && this.selectionStart < this.answerLength) {\n                    const col = this.selectionStart % ALPHABET_ROW_LENGTH;\n                    const row = Math.floor(this.selectionStart / ALPHABET_ROW_LENGTH);\n                    if (!this.blink()) {\n                        screen.fillRect(\n                            answerLeft + col * CELL_WIDTH,\n                            INPUT_TOP + row * CELL_HEIGHT,\n                            1,\n                            CELL_HEIGHT,\n                            this.theme.colorCursor\n                        );\n                    }\n                }\n            }\n        }\n\n        protected drawKeyboard() {\n            const top = screen.height - BOTTOM_BAR_HEIGHT - this.keyboardRows * CELL_HEIGHT - PADDING;\n            const left = (screen.width >> 1) - ((CELL_WIDTH * this.keyboardColumns) >> 1)\n            for (let j = 0; j < this.keyboardRows * this.keyboardColumns; j++) {\n                const col = j % this.keyboardColumns;\n                const row = Math.idiv(j, this.keyboardColumns);\n\n                if (col === this.cursorColumn && row === this.cursorRow) {\n                    screen.fillRect(\n                        left + col * CELL_WIDTH,\n                        top + row * CELL_HEIGHT,\n                        CELL_WIDTH,\n                        CELL_HEIGHT,\n                        this.theme.colorCursor\n                    )\n                }\n\n                screen.print(\n                    this.getSymbolForIndex(j),\n                    left + col * CELL_WIDTH + LETTER_OFFSET_X,\n                    top + row * CELL_HEIGHT + LETTER_OFFSET_Y,\n                    this.theme.colorAlphabet\n                )\n            }\n        }\n\n        protected drawBottomBar() {\n            this.drawBottomBarBackground();\n            this.drawShift(this.cursorRow === 3 && !(this.cursorColumn & 1));\n            this.drawConfirm(this.cursorRow === 3 && !!(this.cursorColumn & 1));\n        }\n\n        protected drawBottomBarBackground() {\n            screen.fillRect(0, screen.height - BOTTOM_BAR_HEIGHT, screen.width, BOTTOM_BAR_HEIGHT, this.theme.colorBottomBackground);\n        }\n\n        protected drawShift(highlighted: boolean) {\n            if (highlighted) {\n                screen.fillRect(\n                    0,\n                    screen.height - BOTTOM_BAR_HEIGHT,\n                    BOTTOM_BAR_BUTTON_WIDTH,\n                    BOTTOM_BAR_HEIGHT,\n                    this.theme.colorCursor\n                );\n            }\n\n            let shiftText = lowerShiftText;\n            if (this.upper) {\n                shiftText = upperShiftText;\n            }\n            screen.print(\n                shiftText,\n                BOTTOM_BAR_SHIFT_X,\n                screen.height - BOTTOM_BAR_HEIGHT + BOTTOM_BAR_TEXT_Y,\n                this.theme.colorBottomText\n            )\n        }\n\n        protected drawConfirm(highlighted: boolean) {\n            if (highlighted) {\n                screen.fillRect(\n                    CONFIRM_BUTTON_LEFT,\n                    screen.height - BOTTOM_BAR_HEIGHT,\n                    BOTTOM_BAR_BUTTON_WIDTH,\n                    BOTTOM_BAR_HEIGHT,\n                    this.theme.colorCursor\n                );\n            }\n\n            screen.print(\n                confirmText,\n                CONFIRM_BUTTON_LEFT + BOTTOM_BAR_CONFIRM_X,\n                screen.height - BOTTOM_BAR_HEIGHT + BOTTOM_BAR_TEXT_Y,\n                this.theme.colorBottomText\n            )\n        }\n\n        protected getSymbolForIndex(index: number) {\n            return getCharForIndex(index, this.upper);\n        }\n\n        private registerHandlers() {\n            controller.up.onEvent(SYSTEM_KEY_DOWN, () => {\n                this.moveVertical(true);\n            })\n\n            controller.down.onEvent(SYSTEM_KEY_DOWN, () => {\n                this.moveVertical(false);\n            })\n\n            controller.right.onEvent(SYSTEM_KEY_DOWN, () => {\n                this.moveHorizontal(true);\n            });\n\n            controller.left.onEvent(SYSTEM_KEY_DOWN, () => {\n                this.moveHorizontal(false);\n            });\n\n            controller.A.onEvent(SYSTEM_KEY_DOWN, () => {\n                this.confirm();\n            });\n\n            controller.B.onEvent(SYSTEM_KEY_DOWN, () => {\n                this.delete();\n            });\n        }\n\n        protected moveVertical(up: boolean) {\n            if (up) {\n                if (this.cursorRow === this.keyboardRows) {\n                    this.cursorRow = this.keyboardRows - 1;\n\n                    if (this.cursorColumn % 2) {\n                        this.cursorColumn = this.keyboardColumns - 1;\n                    }\n                    else {\n                        this.cursorColumn = 0;\n                    }\n                }\n                else {\n                    this.cursorRow = Math.max(0, this.cursorRow - 1);\n                }\n            }\n            else {\n                this.cursorRow = Math.min(this.keyboardRows, this.cursorRow + 1);\n\n                if (this.cursorRow === this.keyboardRows) {\n                    // Go to closest button\n                    this.cursorColumn = this.cursorColumn > 5 ? 1 : 0;\n                }\n            }\n        }\n\n        protected moveHorizontal(right: boolean) {\n            if (right) {\n                this.cursorColumn = (this.cursorColumn + 1) % this.keyboardColumns;\n            }\n            else {\n                this.cursorColumn = (this.cursorColumn + (this.keyboardColumns - 1)) % this.keyboardColumns;\n            }\n        }\n\n        protected confirm() {\n            if (this.cursorRow === 3) {\n                if (this.cursorColumn % 2) {\n                    this.confirmPressed = true;\n                }\n                else {\n                    this.upper = !this.upper;\n                }\n            }\n            else {\n                if (this.selectionStart >= this.answerLength) return;\n\n                const index = this.cursorColumn + this.cursorRow * this.keyboardColumns\n                const letter = getCharForIndex(index, this.upper);\n\n                if (!this.result) {\n                    this.result = letter;\n                }\n                else {\n                    this.result += letter;\n                }\n\n                this.changeTime = game.runtime();\n\n                this.changeInputIndex(1);\n            }\n        }\n\n        protected delete() {\n            if (this.selectionStart <= 0) return;\n\n            this.result = this.result.substr(0, this.result.length - 1);\n            this.changeInputIndex(-1);\n        }\n\n        protected changeInputIndex(delta: number) {\n            this.selectionStart += delta;\n            this.selectionEnd = this.selectionStart;\n        }\n\n        protected blink() {\n            return Math.idiv(game.runtime() - this.changeTime, 500) & 1;\n        }\n    }\n\n    function getCharForIndex(index: number, upper: boolean) {\n        if (index < 26) {\n            return String.fromCharCode(index + (upper ? 65 : 97));\n        }\n        else {\n            if (upper) {\n                return digitsUpper[index - 26];\n            }\n            else {\n                return \"\" + (index - 26);\n            }\n        }\n    }\n}","pxt.json":"{\n    \"name\": \"game\",\n    \"description\": \"The game and sprite library - beta\",\n    \"dependencies\": {\n        \"settings\": \"*\",\n        \"screen\": \"*\",\n        \"mixer\": \"*\",\n        \"power\": \"*\"\n    },\n    \"files\": [\n        \"ns.ts\",\n        \"systemKeyboard.d.ts\",\n        \"systemKeyboard.cpp\",\n        \"gameoverrides.ts\",\n        \"basesprite.ts\",\n        \"constants.ts\",\n        \"controlleroverrides.ts\",\n        \"controller.ts\",\n        \"controllerbutton.ts\",\n        \"hitbox.ts\",\n        \"renderText.ts\",\n        \"spritesay.ts\",\n        \"sprites.ts\",\n        \"sprite.ts\",\n        \"extendableSprite.ts\",\n        \"sprite.d.ts\",\n        \"spritemap.ts\",\n        \"spriteevents.ts\",\n        \"spriteset.ts\",\n        \"spritekind.ts\",\n        \"metrics.ts\",\n        \"obstacle.ts\",\n        \"physics.ts\",\n        \"info.ts\",\n        \"background.ts\",\n        \"tilemap.ts\",\n        \"camera.ts\",\n        \"renderable.ts\",\n        \"scene.ts\",\n        \"scenes.ts\",\n        \"textDialogs.ts\",\n        \"game.ts\",\n        \"gameutil.ts\",\n        \"prompt.ts\",\n        \"numberprompt.ts\",\n        \"ask.ts\",\n        \"targetoverrides.cpp\",\n        \"targetoverrides.ts\",\n        \"controllerbuttons.cpp\",\n        \"mathUtil.ts\",\n        \"systemmenu.ts\",\n        \"systemmenuicons.ts\",\n        \"console.ts\",\n        \"fieldeditors.ts\",\n        \"particles.ts\",\n        \"particlefactories.ts\",\n        \"particleeffects.ts\",\n        \"effects.ts\",\n        \"texteffects.ts\",\n        \"assetTemplates.ts\",\n        \"animation.ts\",\n        \"multiplayer.cpp\",\n        \"multiplayer.ts\",\n        \"keymap.cpp\",\n        \"keymap.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","renderText.ts":"namespace sprites {\n    export class RenderText {\n        linebreaks: number[];\n        font: image.Font;\n        height: number;\n        width: number;\n\n        constructor(public text: string, maxWidth: number) {\n            this.font = image.getFontForText(text);\n\n            this.setMaxWidth(maxWidth);\n        }\n\n        draw(canvas: Image, left: number, top: number, color: number, lineStart?: number, lineEnd?: number) {\n            if (lineStart === undefined) lineStart = 0;\n            if (lineEnd === undefined) lineEnd = this.linebreaks.length + 1;\n\n            for (let i = lineStart; i < lineEnd; i++) {\n                this.drawLine(canvas, left, top, i, color);\n                top += this.font.charHeight;\n            }\n        }\n\n        drawLine(canvas: Image, left: number, top: number, lineIndex: number, color: number) {\n            const start = this.lineStart(lineIndex);\n            const end = this.lineEnd(lineIndex);\n\n            for (let i = start; i < end; i++) {\n                canvas.print(this.text.charAt(i), left, top, color, this.font);\n                left += this.font.charWidth;\n            }\n        }\n\n        drawPartial(canvas: Image, left: number, top: number, color: number, lengthToDraw: number, lineStart?: number, lineEnd?: number) {\n            if (lineStart === undefined) lineStart = 0;\n            if (lineEnd === undefined) lineEnd = this.linebreaks.length + 1;\n\n            let currentTextIndex = 0;\n            for (let i = lineStart; i < lineEnd; i++) {\n                currentTextIndex = this.drawPartialLine(canvas, left, top, i, color, currentTextIndex, lengthToDraw);\n                top += this.font.charHeight;\n                if (currentTextIndex >= lengthToDraw) return false;\n            }\n\n            return true;\n        }\n\n        drawPartialLine(canvas: Image, left: number, top: number, lineIndex: number, color: number, currentTextIndex: number, lengthToDraw: number) {\n            const start = this.lineStart(lineIndex);\n            const end = this.lineEnd(lineIndex);\n\n            for (let i = start; i < end; i++) {\n                canvas.print(this.text.charAt(i), left, top, color, this.font);\n                left += this.font.charWidth;\n\n                if (currentTextIndex + (i - start) >= lengthToDraw) {\n                    return lengthToDraw;\n                }\n            }\n            return currentTextIndex + end - start;\n        }\n\n        calculatePartialHeight(startLine: number, lengthToDraw: number) {\n            if (this.linebreaks.length === 0) return this.font.charHeight;\n\n            let current = 0;\n\n            for (let i = startLine; i < this.linebreaks.length + 1; i++) {\n                current += this.lineEnd(i) - this.lineStart(i);\n                if (current > lengthToDraw) return (i - startLine + 1) * this.font.charHeight\n            }\n            return this.height;\n        }\n\n        lineHeight() {\n            return this.font.charHeight;\n        }\n\n        setMaxWidth(maxWidth: number) {\n            this.linebreaks = getLineBreaks(this.text, [Math.idiv(maxWidth, this.font.charWidth)]);\n            this.height = (this.linebreaks.length + 1) * this.font.charHeight;\n\n            this.width = 0;\n            for (let i = 0; i < this.linebreaks.length + 1; i++) {\n                this.width = Math.max(this.lineEnd(i) - this.lineStart(i), this.width);\n            }\n            this.width *= this.font.charWidth;\n        }\n\n        printableCharacters() {\n            let total = 0;\n            for (let i = 0; i < this.linebreaks.length + 1; i++) {\n                total += this.lineEnd(i) - this.lineStart(i);\n            }\n            return total;\n        }\n\n        lineEnd(lineIndex: number) {\n            const prevEnd = lineIndex > 0 ? this.linebreaks[lineIndex - 1] : 0;\n            let end = lineIndex < this.linebreaks.length ? this.linebreaks[lineIndex] : this.text.length;\n            let didMove = false;\n\n            // Trim trailing whitespace\n            while (end > prevEnd) {\n                if (this.text.charCodeAt(end) <= 32) {\n                    end--;\n                    didMove = true\n                }\n                else if (this.text.charAt(end) === \"n\" && this.text.charAt(end - 1) === \"\\\\\" && end - 1 > prevEnd) {\n                    end -= 2;\n                    didMove = true\n                }\n                else {\n                    break;\n                }\n            }\n            return didMove ? end + 1 : end;\n        }\n\n        lineStart(lineIndex: number) {\n            let start = lineIndex > 0 ? this.linebreaks[lineIndex - 1] : 0;\n\n            // Trim leading whitespace\n            while (start < this.text.length) {\n                if (this.text.charCodeAt(start) <= 32) {\n                    start ++;\n                }\n                else if (this.text.charAt(start) === \"\\\\\" && this.text.charAt(start + 1) === \"n\" && start + 1 < this.text.length) {\n                    start += 2;\n                }\n                else {\n                    break;\n                }\n            }\n\n            return start;\n        }\n\n        widthOfLine(lineIndex: number, fullTextOffset?: number) {\n            if (fullTextOffset != undefined) {\n                return (Math.min(this.lineEnd(lineIndex), fullTextOffset + 1) - this.lineStart(lineIndex)) * this.font.charWidth;\n            }\n            return (this.lineEnd(lineIndex) - this.lineStart(lineIndex)) * this.font.charWidth;\n        }\n\n        widthOfLines(lineStartIndex: number, lineEndIndex: number, offset?: number) {\n            if (this.linebreaks.length === 0) return this.widthOfLine(0, offset);\n\n            let width = 0;\n            let fullTextOffset: number;\n            for (let i = lineStartIndex; i < Math.min(lineEndIndex, this.linebreaks.length + 1); i++) {\n                if (offset != undefined) {\n                    fullTextOffset = this.lineStart(i) + offset;\n                    offset -= this.lineEnd(i) - this.lineStart(i);\n                }\n                if (fullTextOffset !== undefined && this.lineStart(i) > fullTextOffset) break;\n                width = Math.max(width, this.widthOfLine(i, fullTextOffset));\n            }\n            return width;\n        }\n    }\n\n\n    function isBreakCharacter(charCode: number) {\n        return charCode <= 32 ||\n            (charCode >= 58 && charCode <= 64) ||\n            (charCode >= 91 && charCode <= 96) ||\n            (charCode >= 123 && charCode <= 126);\n    }\n\n    function getLineBreaks(text: string, lineLengths: number[]): number[] {\n        const result: number[] = [];\n\n        let lastBreakLocation = 0;\n        let lastBreak = 0;\n        let line = 0;\n        let lineLength = lineLengths[line];\n\n        function nextLine() {\n            line++;\n            lineLength = lineLengths[line % lineLengths.length];\n        }\n\n        for (let index = 0; index < text.length; index++) {\n            if (text.charAt(index) === \"\\n\") {\n                result.push(index);\n                index++;\n                lastBreak = index;\n                nextLine();\n            }\n            // Handle \\\\n in addition to \\n because that's how it gets converted from blocks\n            else if (text.charAt(index) === \"\\\\\" && text.charAt(index + 1) === \"n\") {\n                result.push(index);\n                lastBreak = index;\n                index += 2;\n                nextLine();\n            }\n            else if (isBreakCharacter(text.charCodeAt(index))) {\n                lastBreakLocation = index;\n            }\n\n            if (index - lastBreak === lineLength) {\n                if (lastBreakLocation === index || lastBreakLocation <= lastBreak) {\n                    result.push(index);\n                    lastBreak = index;\n                    nextLine();\n                }\n                else {\n                    result.push(lastBreakLocation);\n                    lastBreak = lastBreakLocation;\n                    nextLine();\n                }\n            }\n        }\n\n        return result;\n    }\n\n    enum RenderTextAnimationState {\n        Idle,\n        Printing,\n        Pausing\n    }\n\n    export class RenderTextAnimation {\n        protected tickPeriod: number;\n        protected state: RenderTextAnimationState;\n        protected pageLine: number;\n        protected timer: number;\n        protected pauseMillis: number;\n        protected onTickCB: () => void;\n        protected onEndCB: () => void;\n        protected prevOffset: number;\n\n        constructor(public text: RenderText, public height: number) {\n            this.state = RenderTextAnimationState.Idle;\n            this.timer = -1;\n\n            this.pageLine = 0;\n            this.setPauseLength(1000);\n            this.setTextSpeed(30);\n        }\n\n        start() {\n            this.state = RenderTextAnimationState.Printing;\n            this.timer = control.millis();\n        }\n\n        numPages() {\n            const maxLinesPerPage =  Math.idiv(this.height, this.text.lineHeight()) + 1;\n            return Math.floor((this.text.linebreaks.length + 1) / maxLinesPerPage);\n        }\n\n        setPauseLength(millis: number) {\n            this.pauseMillis = millis;\n        }\n\n        setTextSpeed(charactersPerSecond: number) {\n            this.tickPeriod = 1000/ charactersPerSecond;\n        }\n\n        currentHeight() {\n            const minHeight = this.text.lineHeight();\n            const maxHeight = Math.max(\n                Math.min(\n                    Math.idiv(this.height, this.text.lineHeight()) + 1,\n                    this.text.linebreaks.length + 1 - this.pageLine\n                ) * this.text.lineHeight(),\n                minHeight\n            );\n\n\n            if (this.state === RenderTextAnimationState.Printing) {\n                return Math.max(Math.min(\n                    this.text.calculatePartialHeight(this.pageLine, this.currentOffset()),\n                    maxHeight\n                ), minHeight)\n            }\n            else if (this.state === RenderTextAnimationState.Pausing) {\n                return maxHeight\n            }\n            else {\n                return 0;\n            }\n        }\n\n        currentWidth() {\n            return this.text.widthOfLines(\n                this.pageLine,\n                this.pageLine + Math.idiv(this.currentHeight(), this.text.lineHeight()) + 1,\n                this.state === RenderTextAnimationState.Printing ? this.currentOffset() : undefined\n            );\n        }\n\n        currentOffset() {\n            return Math.idiv(control.millis() - this.timer, this.tickPeriod)\n        }\n\n        isDone() {\n            return this.state === RenderTextAnimationState.Idle;\n        }\n\n        cancel() {\n            this.state = RenderTextAnimationState.Idle;\n        }\n\n        onCharacterPrinted(cb: () => void) {\n            this.onTickCB = cb;\n        }\n\n        onAnimationEnd(cb: () => void) {\n            this.onEndCB = cb;\n        }\n\n        draw(canvas: Image, left: number, top: number, color: number) {\n            if (this.state === RenderTextAnimationState.Idle) return;\n            else if (this.state === RenderTextAnimationState.Printing) {\n                const pageFinished = this.text.drawPartial(\n                    canvas,\n                    left,\n                    top,\n                    color,\n                    this.currentOffset(),\n                    this.pageLine,\n                    this.pageLine + Math.idiv(this.height, this.text.lineHeight()) + 1\n                );\n\n                if (this.onTickCB && this.prevOffset !== this.currentOffset()) {\n                    this.onTickCB();\n                }\n\n                if (pageFinished) {\n                    this.state = RenderTextAnimationState.Pausing;\n                    this.timer = this.pauseMillis\n                }\n            }\n            else {\n                this.text.draw(\n                    canvas,\n                    left,\n                    top,\n                    color,\n                    this.pageLine,\n                    this.pageLine + Math.idiv(this.height, this.text.lineHeight()) + 1\n                );\n\n                this.timer -= game.currentScene().eventContext.deltaTimeMillis;\n\n                if (this.timer < 0) {\n                    this.pageLine += Math.idiv(this.height, this.text.lineHeight()) + 1;\n                    if (this.pageLine > this.text.linebreaks.length) {\n                        this.state = RenderTextAnimationState.Idle;\n                        if (this.onEndCB) this.onEndCB();\n                    }\n                    else {\n                        this.state = RenderTextAnimationState.Printing;\n                        this.timer = control.millis();\n                    }\n                }\n            }\n\n            this.prevOffset = this.currentOffset();\n        }\n    }\n}","renderable.ts":"namespace scene {\n    export class Renderable extends sprites.BaseSprite {\n        public constructor(\n            protected handler: (target: Image, camera: Camera) => void,\n            protected shouldBeVisible: () => boolean,\n            z: number,\n        ) {\n            super(z);\n        }\n\n        __visible(): boolean {\n            return this.shouldBeVisible();\n        }\n\n        __drawCore(camera: scene.Camera) {\n            this.handler(screen, camera);\n        }\n\n        destroy() {\n            const s = game.currentScene();\n            s.allSprites.removeElement(this);\n        }\n    }\n\n    export function createRenderable(\n        z: number,\n        handler: (target: Image, camera: Camera) => void,\n        shouldBeVisible?: () => boolean\n    ): Renderable {\n        const renderable = new Renderable(\n            handler,\n            shouldBeVisible || (() => true),\n            z,\n        );\n\n        return renderable;\n    }\n}","scene.ts":"interface SparseArray<T> {\n    [index: number]: T;\n}\n\n/**\n * Control the background, tiles and camera\n */\nnamespace scene {\n    export enum Flag {\n        NeedsSorting = 1 << 0, // indicates the sprites in the scene need to be sorted before rendering\n        SeeThrough = 1 << 1, // if set, render the previous scene 'below' this one as the background\n        IsRendering = 1 << 2, // if set, the scene is currently being rendered to the screen\n    }\n\n    export class SpriteHandler {\n        constructor(\n            public kind: number,\n            public handler: (sprite: Sprite) => void\n        ) { }\n    }\n\n    export class OverlapHandler {\n        constructor(\n            public kind: number,\n            public otherKind: number,\n            public handler: (sprite: Sprite, otherSprite: Sprite) => void\n        ) { }\n    }\n\n    export class TileWallHandler {\n        constructor(\n            public spriteKind: number,\n            public handler: (sprite: Sprite, location: tiles.Location) => void\n        ) { }\n    }\n\n    export class TileOverlapHandler {\n        constructor(\n            public spriteKind: number,\n            public tileKind: Image,\n            public handler: (sprite: Sprite, location: tiles.Location) => void\n        ) { }\n    }\n\n\n    export class GameForeverHandler {\n        public lock: boolean;\n        constructor(\n            public handler: () => void\n        ) { }\n    }\n\n    // frame handler priorities\n    export const CONTROLLER_PRIORITY = 8;\n    export const UPDATE_CONTROLLER_PRIORITY = 13;\n    export const FOLLOW_SPRITE_PRIORITY = 14;\n    export const PHYSICS_PRIORITY = 15;\n    export const ANIMATION_UPDATE_PRIORITY = 15;\n    export const CONTROLLER_SPRITES_PRIORITY = 13;\n    export const UPDATE_INTERVAL_PRIORITY = 19;\n    export const UPDATE_PRIORITY = 20;\n    export const PRE_RENDER_UPDATE_PRIORITY = 55;\n    export const RENDER_BACKGROUND_PRIORITY = 60;\n    export const RENDER_SPRITES_PRIORITY = 90;\n    export const RENDER_DIAGNOSTICS_PRIORITY = 150;\n    export const MULTIPLAYER_SCREEN_PRIORITY = 190;\n    export const UPDATE_SCREEN_PRIORITY = 200;\n    export const MULTIPLAYER_POST_SCREEN_PRIORITY = 210;\n\n    // default rendering z indices\n    export const ON_PAINT_Z = -20;\n    export const TILE_MAP_Z = -1;\n    export const SPRITE_Z = 0;\n    export const ON_SHADE_Z = 80;\n    export const HUD_Z = 100;\n\n    export class Scene {\n        eventContext: control.EventContext;\n        background: Background;\n        tileMap: tiles.TileMap;\n        allSprites: SpriteLike[];\n        private spriteNextId: number;\n        spritesByKind: SparseArray<sprites.SpriteSet>;\n        physicsEngine: PhysicsEngine;\n        camera: scene.Camera;\n        flags: number;\n        destroyedHandlers: SpriteHandler[];\n        createdHandlers: SpriteHandler[];\n        overlapHandlers: OverlapHandler[];\n        overlapMap: SparseArray<number[]>;\n        tileOverlapHandlers: TileOverlapHandler[];\n        collisionHandlers: SpriteHandler[][];\n        wallCollisionHandlers: TileWallHandler[];\n        gameForeverHandlers: GameForeverHandler[];\n        particleSources: particles.ParticleSource[];\n        controlledSprites: controller.ControlledSprite[][];\n        controllerConnectionState: boolean[]\n        followingSprites: sprites.FollowingSprite[];\n        buttonEventHandlers: controller.ButtonEventHandlerState[];\n\n        private _millis: number;\n        private _data: any;\n\n        // a set of functions that need to be called when a scene is being initialized\n        static initializers: ((scene: Scene) => void)[] = [];\n\n        constructor(eventContext: control.EventContext, protected previousScene?: Scene) {\n            this.eventContext = eventContext;\n            this.flags = 0;\n            this.physicsEngine = new ArcadePhysicsEngine();\n            this.camera = new scene.Camera();\n            this.background = new Background(this.camera);\n            this.destroyedHandlers = [];\n            this.createdHandlers = [];\n            this.overlapHandlers = [];\n            this.overlapMap = {};\n            this.tileOverlapHandlers = [];\n            this.collisionHandlers = [];\n            this.wallCollisionHandlers = [];\n            this.gameForeverHandlers = [];\n            this.spritesByKind = {};\n            this.controlledSprites = [];\n            this.buttonEventHandlers = [];\n            this._data = {};\n            this._millis = 0;\n        }\n\n        init() {\n            if (this.allSprites) return;\n\n            power.poke(); // keep game alive a little more\n            this.allSprites = [];\n            this.spriteNextId = 0;\n            // update controller state\n            this.eventContext.registerFrameHandler(CONTROLLER_PRIORITY, () => {\n                this._millis += this.eventContext.deltaTimeMillis;\n                control.enablePerfCounter(\"controller_update\")\n                controller.__update(this.eventContext.deltaTime);\n            })\n            // controller update 13\n            this.eventContext.registerFrameHandler(CONTROLLER_SPRITES_PRIORITY, controller._moveSprites);\n            // sprite following 14\n            // apply physics and collisions 15\n            this.eventContext.registerFrameHandler(PHYSICS_PRIORITY, () => {\n                control.enablePerfCounter(\"physics and collisions\")\n                this.physicsEngine.move(this.eventContext.deltaTime);\n            });\n            // user update interval 19s\n\n            // user update 20\n\n            // prerender update 55\n            this.eventContext.registerFrameHandler(PRE_RENDER_UPDATE_PRIORITY, () => {\n                const dt = this.eventContext.deltaTime;\n                this.camera.update();\n\n                for (const s of this.allSprites)\n                    s.__update(this.camera, dt);\n            })\n\n            // render background 60\n\n            // render 90\n            this.eventContext.registerFrameHandler(RENDER_SPRITES_PRIORITY, () => {\n                control.enablePerfCounter(\"scene_draw\");\n                this.render();\n            });\n            // render diagnostics\n            this.eventContext.registerFrameHandler(RENDER_DIAGNOSTICS_PRIORITY, () => {\n                if (game.stats && control.EventContext.onStats) {\n                    control.EventContext.onStats(\n                        control.EventContext.lastStats +\n                        ` sprites:${this.allSprites.length}`\n                    )\n                }\n                if (game.debug)\n                    this.physicsEngine.draw();\n                game.consoleOverlay.draw();\n                // check for power deep sleep\n                power.checkDeepSleep();\n            });\n            // update screen\n            this.eventContext.registerFrameHandler(UPDATE_SCREEN_PRIORITY, control.__screen.update);\n            multiplayer.initServer();\n            multiplayer.initPlayerConnectionListeners();\n            // register additional components\n            Scene.initializers.forEach(f => f(this));\n        }\n\n        get data() {\n            return this._data;\n        }\n\n        /**\n         * Gets the elapsed time in the scene\n         */\n        millis(): number {\n            return this._millis;\n        }\n\n        addSprite(sprite: SpriteLike) {\n            this.allSprites.push(sprite);\n            sprite.id = this.spriteNextId++;\n        }\n\n        destroy() {\n            this.eventContext = undefined;\n            this.background = undefined;\n            this.tileMap = undefined;\n            this.allSprites = undefined;\n            this.spriteNextId = undefined;\n            this.spritesByKind = undefined;\n            this.physicsEngine = undefined;\n            this.camera = undefined;\n            this.flags = undefined;\n            this.destroyedHandlers = undefined;\n            this.createdHandlers = undefined;\n            this.overlapHandlers = undefined;\n            this.tileOverlapHandlers = undefined;\n            this.collisionHandlers = undefined;\n            this.wallCollisionHandlers = undefined;\n            this.gameForeverHandlers = undefined;\n            this._data = undefined;\n        }\n\n        /**\n         * Renders the current frame as an image\n         */\n        render() {\n            // bail out from recursive or parallel call.\n            if (this.flags & scene.Flag.IsRendering) return;\n            this.flags |= scene.Flag.IsRendering;\n\n            control.enablePerfCounter(\"render background\")\n            if ((this.flags & scene.Flag.SeeThrough) && this.previousScene) {\n                this.previousScene.render();\n            } else {\n                this.background.draw();\n            }\n\n            control.enablePerfCounter(\"sprite sort\")\n            if (this.flags & Flag.NeedsSorting) {\n                this.allSprites.sort(function (a, b) { return a.z - b.z || a.id - b.id; })\n                this.flags &= ~scene.Flag.NeedsSorting;\n            }\n\n            control.enablePerfCounter(\"sprite draw\")\n            for (const s of this.allSprites) {\n                s.__draw(this.camera);\n            }\n\n            this.flags &= ~scene.Flag.IsRendering;\n        }\n    }\n}\n","scenes.ts":"/**\n * Control the background, tiles and camera\n */\n\nenum CameraProperty {\n    //% block=\"x\"\n    X,\n    //% block=\"y\"\n    Y,\n    //% block=\"left\"\n    Left,\n    //% block=\"right\"\n    Right,\n    //% block=\"top\"\n    Top,\n    //% block=\"bottom\"\n    Bottom\n}\n\n//% weight=88 color=\"#4b6584\" icon=\"\\uf1bb\"\n//% groups='[\"Screen\", \"Camera\", \"Effects\", \"Tilemaps\", \"Tilemap Operations\", \"Locations\"]'\n//% blockGap=8\nnamespace scene {\n    /**\n     * Get the width of the screen in pixels\n     */\n    //% blockId=scenescreenwidth block=\"screen width\"\n    //% group=\"Screen\"\n    //% weight=100 blockGap=8\n    //% help=scene/screen-width\n    export function screenWidth(): number {\n        return screen.width;\n    }\n\n    /**\n     * Gets the height of the screen in pixels\n     */\n    //% blockId=scenescreenheight block=\"screen height\"\n    //% group=\"Screen\"\n    //% weight=99\n    //% help=scene/screen-width\n    export function screenHeight(): number {\n        return screen.height;\n    }\n\n    /**\n     * Set the game background color\n     * @param color\n     */\n    //% group=\"Screen\"\n    //% weight=25\n    //% blockId=gamesetbackgroundcolor block=\"set background color to %color=colorindexpicker\"\n    //% help=scene/set-background-color\n    export function setBackgroundColor(color: number) {\n        const scene = game.currentScene();\n        scene.background.color = color;\n    }\n\n    /**\n     * Get the game background color\n     * @param color\n     */\n    //% group=\"Screen\"\n    //% weight=22\n    //% blockId=gamebackgroundcolor block=\"background color\"\n    //% help=scene/background-color\n    export function backgroundColor() : number {\n        const scene = game.currentScene();\n        return scene.background.color;\n    }\n\n    /**\n     * Set a picture as the background\n     */\n    //% group=\"Screen\"\n    //% weight=24\n    //% blockId=gamesetbackgroundimage block=\"set background image to %img=background_image_picker\"\n    //% help=scene/set-background-image\n    export function setBackgroundImage(img: Image) {\n        const scene = game.currentScene();\n        scene.background.image = img;\n    }\n\n    /**\n     * Get the current background image\n     */\n    //% weight=22\n    //% group=\"Screen\"\n    //% blockId=gamebackgroundimage block=\"background image\"\n    //% help=scene/background-image\n    export function backgroundImage(): Image {\n        const scene = game.currentScene();\n        return scene.background.image;\n    }\n\n    /**\n     * Adds a moving background layer\n     * @param distance distance of the layer which determines how fast it moves, eg: 10\n     * @param img\n     */\n    //% group=\"Screen\"\n    //% weight=10\n    export function addBackgroundLayer(image: Image, distance?: number, alignment?: BackgroundAlignment) {\n        const scene = game.currentScene();\n        if (image)\n            scene.background.addLayer(image, distance || 100, alignment || BackgroundAlignment.Bottom);\n    }\n\n    /**\n     * Set the map for placing tiles in the scene\n     * @param map\n     * @param scale\n     */\n    export function setTileMapLevel(map: tiles.TileMapData) {\n        const scene = game.currentScene();\n        if (!scene.tileMap)\n            scene.tileMap = new tiles.TileMap();\n        scene.tileMap.setData(map);\n    }\n\n     /**\n     * Shake the camera\n     * @param sprite\n     */\n    //% blockId=camerashake block=\"camera shake by %amplitude pixels for %duration ms\"\n    //% amplitude.min=1 amplitude.max=8 amplitude.defl=4\n    //% duration.shadow=timePicker duration.defl=500\n    //% group=\"Camera\"\n    //% help=scene/camera-shake\n    //% weight=90\n    export function cameraShake(amplitude: number = 4, duration: number = 500) {\n        const scene = game.currentScene();\n        scene.camera.shake(amplitude, duration);\n    }\n\n    /**\n     * Set the game camera to follow a sprite\n     * @param sprite\n     */\n    //% blockId=camerafollow block=\"camera follow sprite %sprite=variables_get(mySprite)\"\n    //% group=\"Camera\"\n    //% help=scene/camera-follow-sprite\n    //% weight=100\n    export function cameraFollowSprite(sprite: Sprite) {\n        const scene = game.currentScene();\n        scene.camera.sprite = sprite;\n        scene.camera.update();\n    }\n\n    /**\n     * Moves the camera center to a coordinate position\n     * @param sprite\n     */\n    //% blockId=camerapos block=\"center camera at x %x y %y\"\n    //% group=\"Camera\"\n    //% help=scene/center-camera-at\n    //% weight=80\n    export function centerCameraAt(x: number, y: number) {\n        const scene = game.currentScene();\n        scene.camera.sprite = undefined;\n        scene.camera.offsetX = x - (screen.width >> 1);\n        scene.camera.offsetY = y - (screen.height >> 1);\n    }\n\n    /**\n     * Returns the x coordinate of the camera (the left of the screen)\n     */\n    //% blockId=cameraleft block=\"camera left\"\n    //% group=\"Camera\"\n    //% help=scene/camera-left\n    //% deprecated=true\n    export function cameraLeft() {\n        const scene = game.currentScene();\n        return scene.camera.drawOffsetX;\n    }\n\n    /**\n     * Returns the y coordinate of the camera (the top of the screen)\n     */\n    //% blockId=cameratop block=\"camera top\"\n    //% group=\"Camera\"\n    //% help=scene/camera-top\n    //% deprecated=true\n    export function cameraTop() {\n        const scene = game.currentScene();\n        return scene.camera.drawOffsetY;\n    }\n\n    /**\n     * Returns the specified camera property\n     * @param property The property to get\n     */\n    //% blockId=cameraproperty block=\"camera $property\"\n    //% group=\"Camera\"\n    //% help=scene/camera-property\n    //% weight=70\n    export function cameraProperty(property: CameraProperty): number {\n        const scene = game.currentScene();\n        if (!scene.camera.isUpdated())\n            scene.camera.update();\n        switch (property) {\n            case CameraProperty.X: return scene.camera.x;\n            case CameraProperty.Y: return scene.camera.y;\n            case CameraProperty.Left: return scene.camera.left;\n            case CameraProperty.Right: return scene.camera.right;\n            case CameraProperty.Top: return scene.camera.top;\n            case CameraProperty.Bottom: return scene.camera.bottom;\n        }\n    }\n}\n","sprite.d.ts":"declare interface Sprite {\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"z (depth)\"\n    z: number;\n    // this is defined in the superclass BaseSprite, so it needs to be declared here to show up\n    // in the blocks for sprites.\n}","sprite.ts":"enum SpriteFlag {\n    //% block=\"ghost\"\n    Ghost = sprites.Flag.Ghost,\n    //% block=\"auto destroy\"\n    AutoDestroy = sprites.Flag.AutoDestroy,\n    //% block=\"stay in screen\"\n    StayInScreen = sprites.Flag.StayInScreen,\n    //% block=\"destroy on wall\"\n    DestroyOnWall = sprites.Flag.DestroyOnWall,\n    //% block=\"bounce on wall\"\n    BounceOnWall = sprites.Flag.BounceOnWall,\n    //% block=\"show physics\"\n    ShowPhysics = sprites.Flag.ShowPhysics,\n    //% block=\"invisible\"\n    Invisible = sprites.Flag.Invisible,\n    //% block=\"relative to camera\"\n    RelativeToCamera = sprites.Flag.RelativeToCamera,\n    //% block=\"ghost through sprites\"\n    GhostThroughSprites = sprites.Flag.GhostThroughSprites,\n    //% block=\"ghost through tiles\"\n    GhostThroughTiles = sprites.Flag.GhostThroughTiles,\n    //% block=\"ghost through walls\"\n    GhostThroughWalls = sprites.Flag.GhostThroughWalls,\n}\n\nenum TileDirection {\n    //% block=\"left\"\n    Left = 0,\n    //% block=\"top\"\n    Top = 1,\n    //% block=\"right\"\n    Right = 2,\n    //% block=\"bottom\"\n    Bottom = 3,\n    //% block=\"center\"\n    Center = 4\n}\n\nenum CollisionDirection {\n    //% block=\"left\"\n    Left = 0,\n    //% block=\"top\"\n    Top = 1,\n    //% block=\"right\"\n    Right = 2,\n    //% block=\"bottom\"\n    Bottom = 3\n}\n\nenum FlipOption {\n    //% block=none\n    None,\n    //% block=\"flip x\"\n    FlipX,\n    //% block=\"flip y\"\n    FlipY,\n    //% block=\"flip x+y\"\n    FlipXY\n}\n\nenum ScaleDirection {\n    //% block=\"vertically\"\n    Vertically = 0x01,\n    //% block=\"horizontally\"\n    Horizontally = 0x02,\n    //% block=\"uniformly\"\n    Uniformly = Vertically | Horizontally,\n}\n\nenum ScaleAnchor {\n    //% block=\"middle\"\n    Middle = 0,\n    //% block=\"top\"\n    Top = 0x01,\n    //% block=\"left\"\n    Left = 0x02,\n    //% block=\"right\"\n    Right = 0x04,\n    //% block=\"bottom\"\n    Bottom = 0x08,\n    //% block=\"top left\"\n    TopLeft = Top | Left,\n    //% block=\"top right\"\n    TopRight = Top | Right,\n    //% block=\"bottom left\"\n    BottomLeft = Bottom | Left,\n    //% block=\"bottom right\"\n    BottomRight = Bottom | Right,\n}\n\n/**\n * A sprite on the screen\n **/\n//% blockNamespace=sprites color=\"#3B6FEA\" blockGap=8\nclass Sprite extends sprites.BaseSprite {\n    _x: Fx8\n    _y: Fx8\n    _vx: Fx8\n    _vy: Fx8\n    _ax: Fx8\n    _ay: Fx8\n    _fx: Fx8 // friction\n    _fy: Fx8 // friction\n    _sx: Fx8 // scale\n    _sy: Fx8 // scale\n    _width: Fx8 // scaled width\n    _height: Fx8 // scaled height\n\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"x\" callInDebugger\n    get x(): number {\n        return Fx.toFloat(Fx.add(this._x, Fx.div(this._width, Fx.twoFx8)));\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"x\"\n    set x(v: number) {\n        this.left = v - (this.width / 2)\n    }\n\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"y\" callInDebugger\n    get y(): number {\n        return Fx.toFloat(Fx.add(this._y, Fx.div(this._height, Fx.twoFx8)));\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"y\"\n    set y(v: number) {\n        this.top = v - (this.height / 2)\n    }\n\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"vx (velocity x)\" callInDebugger\n    get vx(): number {\n        return Fx.toFloat(this._vx)\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"vx (velocity x)\"\n    set vx(v: number) {\n        this._vx = Fx8(v)\n    }\n\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"vy (velocity y)\" callInDebugger\n    get vy(): number {\n        return Fx.toFloat(this._vy)\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"vy (velocity y)\"\n    set vy(v: number) {\n        this._vy = Fx8(v)\n    }\n\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"ax (acceleration x)\" callInDebugger\n    get ax(): number {\n        return Fx.toFloat(this._ax)\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"ax (acceleration x)\"\n    set ax(v: number) {\n        this._ax = Fx8(v)\n    }\n\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"ay (acceleration y)\" callInDebugger\n    get ay(): number {\n        return Fx.toFloat(this._ay)\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"ay (acceleration y)\"\n    set ay(v: number) {\n        this._ay = Fx8(v)\n    }\n\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"fx (friction x)\" callInDebugger\n    get fx(): number {\n        return Fx.toFloat(this._fx)\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"fx (friction x)\"\n    set fx(v: number) {\n        this._fx = Fx8(Math.max(0, v))\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"fy (friction y)\" callInDebugger\n    get fy(): number {\n        return Fx.toFloat(this._fy)\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"fy (friction y)\"\n    set fy(v: number) {\n        this._fy = Fx8(Math.max(0, v))\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"sx (scale x)\" callInDebugger\n    get sx(): number {\n        return Fx.toFloat(this._sx);\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"sx (scale x)\"\n    set sx(v: number) {\n        const x = this.x;\n        this._sx = Fx8(Math.max(0, v));\n        this.recalcSize();\n        this.left = x - this.width / 2;\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"sy (scale y)\" callInDebugger\n    get sy(): number {\n        return Fx.toFloat(this._sy);\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"sy (scale y)\"\n    set sy(v: number) {\n        const y = this.y;\n        this._sy = Fx8(Math.max(0, v));\n        this.recalcSize();\n        this.top = y - this.height / 2;\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"scale\" callInDebugger\n    get scale(): number {\n        return Math.max(this.sx, this.sy);\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"scale\"\n    set scale(v: number) {\n        this.sx = this.sy = v;\n    }\n\n    private _data: any;\n    /**\n     * Custom data\n     */\n    //%\n    get data(): any {\n        if (!this._data) this._data = {};\n        return this._data;\n    }\n\n    set data(value: any) {\n        this._data = value;\n    }\n    _kind: number;\n\n    /**\n     * A bitset of layer. Each bit is a layer, default is 1.\n     */\n    //% group=\"Physics\"\n    layer: number;\n\n    _lastX: Fx8;\n    _lastY: Fx8;\n\n    _action: number; //Used with animation library\n\n    /**\n     * Time to live in milliseconds. The lifespan decreases by 1 on each millisecond\n     * and the sprite gets destroyed when it reaches 0.\n     */\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"lifespan\"\n    lifespan: number;\n    private _image: Image;\n    private _obstacles: sprites.Obstacle[];\n\n    private sayEndTime: number;\n    private sayRenderer: sprites.BaseSpriteSayRenderer;\n\n    _hitbox: game.Hitbox;\n    _overlappers: number[];\n    _alreadyChecked: number[];\n    _kindsOverlappedWith: number[];\n\n    flags: number\n\n    private destroyHandler: () => void;\n\n    constructor(img: Image) {\n        super(scene.SPRITE_Z);\n\n        this._x = Fx8(screen.width - img.width >> 1);\n        this._y = Fx8(screen.height - img.height >> 1);\n        this._lastX = this._x;\n        this._lastY = this._y;\n        this.vx = 0\n        this.vy = 0\n        this.ax = 0\n        this.ay = 0\n        this.fx = 0\n        this.fy = 0\n        this._sx = Fx.oneFx8;\n        this._sy = Fx.oneFx8;\n        this.flags = 0\n        this.setImage(img);\n        this.setKind(-1); // not a member of any type by default\n        this.layer = 1; // by default, in layer 1\n        this.lifespan = undefined;\n        this._overlappers = [];\n        this._obstacles = [];\n    }\n\n    __serialize(offset: number): Buffer {\n        const buf = control.createBuffer(offset + 20);\n        let k = offset;\n        buf.setNumber(NumberFormat.Int16LE, k, Fx.toInt(this._x)); k += 2;\n        buf.setNumber(NumberFormat.Int16LE, k, Fx.toInt(this._y)); k += 2;\n        buf.setNumber(NumberFormat.Int16LE, k, Fx.toInt(this._vx)); k += 2;\n        buf.setNumber(NumberFormat.Int16LE, k, Fx.toInt(this._vy)); k += 2;\n        buf.setNumber(NumberFormat.Int16LE, k, Fx.toInt(this._ax)); k += 2;\n        buf.setNumber(NumberFormat.Int16LE, k, Fx.toInt(this._ay)); k += 2;\n        buf.setNumber(NumberFormat.Float32LE, k, Fx.toFloat(this._sx)); k += 4;\n        buf.setNumber(NumberFormat.Float32LE, k, Fx.toFloat(this._sy)); k += 4;\n        return buf;\n    }\n\n    /**\n     * Gets the current image\n     */\n    //% group=\"Image\"\n    //% blockId=spriteimage block=\"%sprite(mySprite) image\"\n    //% weight=8 help=sprites/sprite/image\n    get image(): Image {\n        return this._image;\n    }\n\n    /**\n     * Sets the image on the sprite\n     */\n    //% group=\"Image\"\n    //% blockId=spritesetimage block=\"set %sprite(mySprite) image to %img=screen_image_picker\"\n    //% weight=7 help=sprites/sprite/set-image\n    setImage(img: Image) {\n        if (!img || img === this._image) return;\n        this._image = img;\n        this.recalcSize();\n    }\n\n    calcDimensionalHash() {\n        return this._image.revision() + Fx.toIntShifted(this._width, 8) + Fx.toIntShifted(this._height, 16);\n    }\n\n    resetHitbox() {\n        this._hitbox = null;\n        this.setHitbox();\n    }\n\n    setHitbox() {\n        if (this._hitbox) {\n            this._hitbox.updateIfInvalid();\n        } else {\n            this._hitbox = game.calculateHitBox(this);\n        }\n    }\n\n    isStatic() {\n        return this._image.isStatic();\n    }\n\n    __visible() {\n        return !(this.flags & SpriteFlag.Invisible);\n    }\n\n    protected recalcSize(): void {\n        this._width = Fx8(this._image.width * this.sx);\n        this._height = Fx8(this._image.height * this.sy);\n        this.resetHitbox();\n    }\n\n    private isScaled(): boolean {\n        return this._sx !== Fx.oneFx8 || this._sy !== Fx.oneFx8;\n    }\n\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"width\" callInDebugger\n    get width() {\n        return Fx.toFloat(this._width);\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"height\" callInDebugger\n    get height() {\n        return Fx.toFloat(this._height);\n    }\n\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"left\" callInDebugger\n    get left() {\n        return Fx.toFloat(this._x)\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"left\"\n    set left(value: number) {\n        const physics = game.currentScene().physicsEngine;\n        physics.moveSprite(\n            this,\n            Fx.sub(\n                Fx8(value),\n                this._x\n            ),\n            Fx.zeroFx8\n        );\n    }\n\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"right\" callInDebugger\n    get right() {\n        return this.left + this.width\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"right\"\n    set right(value: number) {\n        this.left = value - this.width\n    }\n\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"top\" callInDebugger\n    get top() {\n        return Fx.toFloat(this._y);\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"top\"\n    set top(value: number) {\n        const physics = game.currentScene().physicsEngine;\n        physics.moveSprite(\n            this,\n            Fx.zeroFx8,\n            Fx.sub(\n                Fx8(value),\n                this._y\n            )\n        );\n    }\n\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"bottom\" callInDebugger\n    get bottom() {\n        return this.top + this.height;\n    }\n    //% group=\"Physics\" blockSetVariable=\"mySprite\"\n    //% blockCombine block=\"bottom\"\n    set bottom(value: number) {\n        this.top = value - this.height;\n    }\n\n    // The z field (``get z()`` / ``set z()``) is declared in sprite.d.ts\n    // as it is defnied in the superclass\n\n    /**\n     * The type of sprite\n     */\n    //% group=\"Overlaps\"\n    //% blockId=\"spritegetkind\" block=\"%sprite(mySprite) kind\"\n    //% weight=79 help=sprites/sprite/kind\n    kind() {\n        return this._kind;\n    }\n\n    /**\n     * The type of sprite\n     */\n    //% group=\"Overlaps\"\n    //% blockId=\"spritesetkind\" block=\"set %sprite(mySprite) kind to %kind\"\n    //% kind.shadow=spritekind\n    //% weight=80 help=sprites/sprite/set-kind\n    setKind(value: number) {\n        if (value == undefined || this._kind === value) return;\n\n        const spritesByKind = game.currentScene().spritesByKind;\n        if (this._kind >= 0 && spritesByKind[this._kind])\n            spritesByKind[this._kind].remove(this);\n\n        if (value >= 0) {\n            if (!spritesByKind[value]) spritesByKind[value] = new sprites.SpriteSet();\n            spritesByKind[value].add(this);\n        }\n\n        const overlapMap = game.currentScene().overlapMap;\n        if (!overlapMap[value]) {\n            overlapMap[value] = [];\n        }\n\n        this._kindsOverlappedWith = overlapMap[value];\n\n        this._kind = value;\n    }\n\n    /**\n     * Set the sprite position in pixels starting from the top-left corner of the screen.\n     * @param x horizontal position in pixels\n     * @param y vertical position in pixels\n     */\n    //% group=\"Physics\"\n    //% weight=100\n    //% blockId=spritesetpos block=\"set %sprite(mySprite) position to x %x y %y\"\n    //% help=sprites/sprite/set-position\n    //% x.shadow=\"positionPicker\" y.shadow=\"positionPicker\"\n    setPosition(x: number, y: number): void {\n        const physics = game.currentScene().physicsEngine;\n        physics.moveSprite(\n            this,\n            Fx8(x - this.x),\n            Fx8(y - this.y)\n        );\n    }\n\n    /**\n     * Sets the sprite velocity in pixel / sec\n     * @param vx\n     * @param vy\n     */\n    //% group=\"Physics\"\n    //% weight=100\n    //% blockId=spritesetvel block=\"set %sprite(mySprite) velocity to vx %vx vy %vy\"\n    //% help=sprites/sprite/set-velocity\n    //% vx.shadow=spriteSpeedPicker\n    //% vy.shadow=spriteSpeedPicker\n    setVelocity(vx: number, vy: number): void {\n        this.vx = vx;\n        this.vy = vy;\n    }\n\n    /**\n     * Deprecated! Use sayText instead.\n     *\n     * Display a speech bubble with the text, for the given time.\n     * @param text the text to say, eg: \":)\"\n     * @param time time to keep text on\n     */\n    //% group=\"Effects\"\n    //% weight=60\n    //% blockId=spritesay block=\"%sprite(mySprite) say %text||for %millis ms\"\n    //% millis.shadow=timePicker\n    //% text.shadow=text\n    //% inlineInputMode=inline\n    //% deprecated=true\n    //% help=sprites/sprite/say\n    say(text: any, timeOnScreen?: number, textColor = 15, textBoxColor = 1) {\n        if (text === null || text === undefined || text === \"\") {\n            if (this.sayRenderer) this.sayRenderer.destroy();\n            this.sayRenderer = undefined;\n            return;\n        }\n\n        if (this.sayRenderer && this.sayRenderer instanceof sprites.LegacySpriteSayRenderer &&\n            this.sayRenderer.text === text && this.sayRenderer.bgColor === textBoxColor &&\n            this.sayRenderer.fgColor === textColor && timeOnScreen === undefined && this.sayEndTime === undefined) {\n                return;\n        }\n\n        if (timeOnScreen >= 0) this.sayEndTime = control.millis() + timeOnScreen;\n\n        if (this.sayRenderer) this.sayRenderer.destroy();\n        this.sayRenderer = undefined;\n        text = console.inspect(text);\n\n        this.sayRenderer = new sprites.LegacySpriteSayRenderer(text, timeOnScreen, this, textColor, textBoxColor);\n    }\n\n    /**\n     * Display a speech bubble with the text, for the given time\n     * @param text the text to say, eg: \":)\"\n     * @param time time to keep text on\n     * @param animated whether to print the text character by character or not\n     */\n    //% group=\"Effects\"\n    //% weight=60\n    //% blockId=spritesaytext block=\"$this say $text||for $timeOnScreen ms with animation $animated\"\n    //% timeOnScreen.shadow=timePicker\n    //% text.shadow=text\n    //% this.shadow=variables_get\n    //% this.defl=mySprite\n    //% inlineInputMode=inline\n    //% help=sprites/sprite/say\n    //% expandableArgumentMode=toggle\n    sayText(text: any, timeOnScreen?: number, animated = false, textColor = 15, textBoxColor = 1) {\n        if (text === null || text === undefined || text === \"\") {\n            if (this.sayRenderer) this.sayRenderer.destroy();\n            this.sayRenderer = undefined;\n            return;\n        }\n\n        if (this.sayRenderer) this.sayRenderer.destroy();\n        this.sayRenderer = undefined;\n\n        if (timeOnScreen >= 0) this.sayEndTime = control.millis() + timeOnScreen;\n\n        text = console.inspect(text);\n\n        this.sayRenderer = new sprites.SpriteSayRenderer(text, textColor, textBoxColor, animated, timeOnScreen);\n    }\n\n    /**\n     * Start an effect on this sprite\n     * @param effect the type of effect to create\n     */\n    //% group=\"Effects\"\n    //% weight=90\n    //% blockId=startEffectOnSprite block=\"%sprite(mySprite) start %effect effect || for %duration=timePicker|ms\"\n    //% help=sprites/sprite/start-effect\n    startEffect(effect: effects.ParticleEffect, duration?: number) {\n        effect.start(this, duration, null, !!(this.flags & sprites.Flag.RelativeToCamera));\n    }\n\n    /**\n     * Indicates if the sprite is outside the screen\n     */\n    //%\n    isOutOfScreen(camera: scene.Camera): boolean {\n        const ox = (this.flags & sprites.Flag.RelativeToCamera) ? 0 : camera.drawOffsetX;\n        const oy = (this.flags & sprites.Flag.RelativeToCamera) ? 0 : camera.drawOffsetY;\n        return this.right - ox < 0 || this.bottom - oy < 0 || this.left - ox > screen.width || this.top - oy > screen.height;\n    }\n\n    __drawCore(camera: scene.Camera) {\n        this.drawSay(camera);\n\n        if (this.isOutOfScreen(camera)) return;\n\n        const ox = (this.flags & sprites.Flag.RelativeToCamera) ? 0 : camera.drawOffsetX;\n        const oy = (this.flags & sprites.Flag.RelativeToCamera) ? 0 : camera.drawOffsetY;\n\n        const l = Math.floor(this.left - ox);\n        const t = Math.floor(this.top - oy);\n\n        this.drawSprite(l, t);\n        this.drawDebug(l, t, ox, oy);\n    }\n\n    __update(camera: scene.Camera, dt: number) {\n        if (this.lifespan !== undefined) {\n            this.lifespan -= dt * 1000;\n            if (this.lifespan <= 0) {\n                this.lifespan = undefined;\n                this._destroyCore();\n            }\n        }\n        if ((this.flags & sprites.Flag.AutoDestroy)\n            && this.isOutOfScreen(camera)) {\n            this.destroy()\n        }\n\n        if (this.sayRenderer) this.sayRenderer.update(dt, camera, this);\n    }\n\n    /**\n     * Set whether a sprite should be constrained within the screen (on) or not (off)\n     */\n    //% group=\"Effects\"\n    //% weight=30\n    //% blockId=spritesetsetstayinscreen block=\"set %sprite(mySprite) stay in screen %on=toggleOnOff\"\n    //% on.defl=true\n    //% help=sprites/sprite/set-stay-in-screen\n    setStayInScreen(on: boolean) {\n        this.setFlag(SpriteFlag.StayInScreen, on);\n    }\n\n    /**\n     * Set whether a sprite should bounce when it hits a wall (on) or not (off)\n     */\n    //% group=\"Effects\"\n    //% weight=25\n    //% blockId=spritesetsetbounceonwall block=\"set %sprite(mySprite) bounce on wall %on=toggleOnOff\"\n    //% on.defl=true\n    //% help=sprites/sprite/set-bounce-on-wall\n    setBounceOnWall(on: boolean) {\n        this.setFlag(SpriteFlag.BounceOnWall, on);\n    }\n\n    /**\n     * Set a sprite flag\n     */\n    //% group=\"Effects\"\n    //% weight=10\n    //% blockId=spritesetsetflag block=\"set %sprite(mySprite) %flag %on=toggleOnOff\"\n    //% flag.defl=SpriteFlag.AutoDestroy\n    //% help=sprites/sprite/set-flag\n    setFlag(flag: SpriteFlag, on: boolean) {\n        if (on) this.flags |= flag\n        else this.flags = ~(~this.flags | flag);\n    }\n\n    /**\n     * Check if this sprite overlaps another sprite\n     * @param other\n     */\n    //% group=\"Overlaps\"\n    //% blockId=spriteoverlapswith block=\"%sprite(mySprite) overlaps with %other=variables_get(otherSprite)\"\n    //% help=sprites/sprite/overlaps-with\n    //% weight=90\n    overlapsWith(other: Sprite) {\n        control.enablePerfCounter(\"overlapsCPP\")\n        if (other == this) return false;\n        if (this.flags & SPRITE_NO_SPRITE_OVERLAPS)\n            return false\n        if (other.flags & SPRITE_NO_SPRITE_OVERLAPS)\n            return false\n        if (this.flags & sprites.Flag.HitboxOverlaps || other.flags & sprites.Flag.HitboxOverlaps)\n            return other._hitbox.overlapsWith(this._hitbox);\n        if (!other._hitbox.overlapsWith(this._hitbox))\n            return false;\n        if (!this.isScaled() && !other.isScaled()) {\n            return other._image.overlapsWith(\n                this._image,\n                this.left - other.left,\n                this.top - other.top)\n        } else {\n            if (this.sx == 0 || this.sy == 0 || other.sx == 0 || other.sy == 0) return false;\n\n            let A: Sprite;\n            let B: Sprite;\n\n            // Render larger-scaled sprite onto smaller-scaled one so that we don't\n            // skip over source pixels in the check.\n\n            // A is the smaller-scaled sprite\n            if (this.sx * this.sy < other.sx * other.sy) {\n                A = this;\n                B = other;\n            } else {\n                A = other;\n                B = this;\n            }\n\n            // Render B onto A\n            return helpers.imageBlit(\n                A.image,\n                // Dst rect in A\n                (B.left - A.left) / A.sx,\n                (B.top - A.top) / A.sy,\n                B.width / A.sx,\n                B.height / A.sy,\n                B.image,\n                // Src rect in B\n                0, 0,\n                B.image.width,\n                B.image.height,\n                true, true);\n        }\n    }\n\n    /**\n     * Check if there is an obstacle in the given direction\n     * @param direction\n     */\n    //% blockId=spritehasobstacle block=\"is %sprite(mySprite) hitting wall %direction\"\n    //% blockNamespace=\"scene\" group=\"Locations\" blockGap=24\n    //% help=scene/is-hitting-tile\n    //% weight=15\n    isHittingTile(direction: CollisionDirection): boolean {\n        return this._obstacles && !!this._obstacles[direction];\n    }\n\n    /**\n     * Get the tile kind in a given direction if any\n     * @param direction\n     */\n    //% blockId=spritetileat block=\"tile to $direction of $this(mySprite) is $tile\"\n    //% tile.shadow=tileset_tile_picker\n    //% blockNamespace=\"scene\" group=\"Locations\" blockGap=8\n    //% help=scene/tile-kind-at\n    //% weight=20\n    tileKindAt(direction: TileDirection, tile: Image): boolean {\n        const tilemap = game.currentScene().tileMap;\n        let x = this.x >> tilemap.scale;\n        let y = this.y >> tilemap.scale;\n        switch (direction) {\n            case TileDirection.Top:\n                y = y - 1;\n                break;\n            case TileDirection.Bottom:\n                y = y + 1;\n                break;\n            case TileDirection.Left:\n                x = x - 1;\n                break;\n            case TileDirection.Right:\n                x = x + 1;\n                break;\n            case TileDirection.Center:\n            default:\n                break;\n        }\n        return tiles.getTileImage(tilemap.getTile(x, y)).equals(tile);\n    }\n\n    /**\n     * Get the obstacle sprite in a given direction if any\n     * @param direction\n     */\n    //% blockId=spriteobstacle block=\"%sprite(mySprite) wall hit on %direction\"\n    //% blockNamespace=\"scene\" group=\"Locations\"\n    //% help=sprites/sprite/tile-hit-from\n    //% deprecated=1\n    tileHitFrom(direction: number): number {\n        return (this._obstacles && this._obstacles[direction]) ? this._obstacles[direction].tileIndex : -1;\n    }\n\n    /**\n     * Gets the tilemap location at the center of a sprite\n     */\n    //% block=\"tilemap location of $this\"\n    //% blockId=tiles_location_of_sprite\n    //% this.shadow=variables_get\n    //% this.defl=mySprite\n    //% blockNamespace=\"scene\" group=\"Locations\" weight=90\n    //% help=scene/tilemap-location\n    tilemapLocation(): tiles.Location {\n        const scene = game.currentScene();\n        if (!scene.tileMap) return undefined;\n        return tiles.getTileLocation(this.x >> scene.tileMap.scale, this.y >> scene.tileMap.scale);\n    }\n\n    clearObstacles() {\n        this._obstacles = [];\n    }\n\n    registerObstacle(direction: CollisionDirection, other: sprites.Obstacle, tm?: tiles.TileMap) {\n        this._obstacles[direction] = other;\n        const collisionHandlers = game.currentScene().collisionHandlers[other.tileIndex];\n        const wallCollisionHandlers = game.currentScene().wallCollisionHandlers;\n\n        if (collisionHandlers) {\n            collisionHandlers\n                .filter(h => h.kind == this.kind())\n                .forEach(h => h.handler(this));\n        }\n        if (wallCollisionHandlers) {\n            tm = tm || game.currentScene().tileMap;\n            const wallHandlersToRun = wallCollisionHandlers\n                .filter(h => h.spriteKind == this.kind());\n            if (wallHandlersToRun.length) {\n                const asTileLocation = tm.getTile(other.left >> tm.scale, other.top >> tm.scale);\n                wallHandlersToRun\n                    .forEach(h => h.handler(this, asTileLocation));\n            }\n        }\n    }\n\n    /**\n     * Run code when the sprite is destroyed\n     * @param handler\n     */\n    //% group=\"Lifecycle\"\n    //% weight=9\n    onDestroyed(handler: () => void) {\n        this.destroyHandler = handler\n    }\n\n    /**\n     * Destroy the sprite\n     */\n    //% group=\"Effects\"\n    //% weight=80\n    //% blockId=spritedestroy block=\"destroy %sprite(mySprite) || with %effect effect for %duration ms\"\n    //% duration.shadow=timePicker\n    //% expandableArgumentMode=\"toggle\"\n    //% help=sprites/sprite/destroy\n    //% deprecated=1\n    destroy(effect?: effects.ParticleEffect, duration?: number) {\n        if (this.flags & sprites.Flag.Destroyed)\n            return;\n        this.flags |= sprites.Flag.Destroyed;\n\n        if (effect)\n            effect.destroy(this, duration);\n        else\n            this._destroyCore();\n    }\n\n    _destroyCore() {\n        this.flags |= sprites.Flag.Destroyed;\n        const scene = game.currentScene();\n        scene.allSprites.removeElement(this);\n        if (this.kind() >= 0 && scene.spritesByKind[this.kind()])\n            scene.spritesByKind[this.kind()].remove(this);\n        scene.physicsEngine.removeSprite(this);\n        if (this.destroyHandler)\n            this.destroyHandler();\n        scene.destroyedHandlers\n            .filter(h => h.kind == this.kind())\n            .forEach(h => h.handler(this));\n    }\n\n    /**\n     * Make this sprite follow the target sprite.\n     *\n     * @param target the sprite this one should follow\n     * @param speed the rate at which this sprite should move, eg: 100\n     * @param turnRate how quickly the sprite should turn while following.\n     *      The default (400) will cause the sprite to reach max speed after approximately 125 ms when standing still,\n     *      and turn around 180 degrees when at max speed after approximately 250 ms.\n     */\n    //% group=\"Physics\" weight=10\n    //% blockId=spriteFollowOtherSprite\n    //% block=\"set %sprite(myEnemy) follow %target=variables_get(mySprite) || with speed %speed\"\n    //% help=sprites/sprite/follow\n    follow(target: Sprite, speed = 100, turnRate = 400) {\n        if (target === this) return;\n\n        const sc = game.currentScene();\n        if (!sc.followingSprites) {\n            sc.followingSprites = [];\n            let lastTime = game.runtime();\n\n            sc.eventContext.registerFrameHandler(scene.FOLLOW_SPRITE_PRIORITY, () => {\n                const currTime = game.runtime();\n                const timeDiff = (currTime - lastTime) / 1000;\n                let destroyedSprites = false;\n\n                sc.followingSprites.forEach(fs => {\n                    const { target, self, turnRate, rate } = fs;\n                    // one of the involved sprites has been destroyed,\n                    // so exit and remove that in the cleanup step\n                    if ((self.flags | target.flags) & sprites.Flag.Destroyed) {\n                        self.vx = 0;\n                        self.vy = 0;\n                        destroyedSprites = true;\n                        return;\n                    }\n\n                    const dx = target.x - self.x;\n                    const dy = target.y - self.y;\n\n                    // already right on top of target; stop moving\n                    if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {\n                        // snap to target location so it sits 'right on top' of sprite.\n                        self.x = target.x;\n                        self.y = target.y;\n\n                        self.vx = 0;\n                        self.vy = 0;\n                        return;\n                    }\n\n                    const maxMomentumDiff = timeDiff * turnRate * (rate / 50);\n                    const angleToTarget = Math.atan2(dy, dx);\n\n                    // to move directly towards target, use this...\n                    const targetTrajectoryVx = Math.cos(angleToTarget) * rate;\n                    const targetTrajectoryVy = Math.sin(angleToTarget) * rate;\n\n                    // ... but to keep momentum, calculate the diff in velocities and maintain some of the velocity\n                    const diffVx = targetTrajectoryVx - self.vx;\n                    const diffVy = targetTrajectoryVy - self.vy;\n\n                    self.vx += Math.clamp(-maxMomentumDiff, maxMomentumDiff, diffVx);\n                    self.vy += Math.clamp(-maxMomentumDiff, maxMomentumDiff, diffVy);\n                });\n\n                lastTime = currTime;\n\n                // cleanup: remove followers where one has been destroyed\n                if (destroyedSprites) {\n                    sc.followingSprites = sc.followingSprites\n                        .filter(fs => !((fs.self.flags | fs.target.flags) & sprites.Flag.Destroyed));\n                }\n            });\n        }\n\n        const fs = sc.followingSprites.find(fs => fs.self.id == this.id);\n\n        if (!target || !speed) {\n            if (fs) {\n                sc.followingSprites.removeElement(fs);\n                this.vx = 0;\n                this.vy = 0;\n            }\n        } else if (!fs) {\n            sc.followingSprites.push(new sprites.FollowingSprite(\n                this,\n                target,\n                speed,\n                turnRate\n            ));\n        } else {\n            fs.target = target;\n            fs.rate = speed;\n            fs.turnRate = turnRate;\n        }\n    }\n\n    setScaleCore(sx?: number, sy?: number, anchor?: ScaleAnchor, proportional?: boolean): void {\n        anchor = anchor || ScaleAnchor.Middle;\n\n        const hasSx = sx != null;\n        const hasSy = sy != null;\n\n        const oldW = this.width;\n        const oldH = this.height;\n\n        if (hasSx) {\n            const oldSx = this.sx;\n            this.sx = sx;\n            if (!hasSy && proportional) {\n                const ratio = sx / oldSx;\n                this.sy *= ratio;\n            }\n        }\n        if (hasSy) {\n            const oldSy = this.sy;\n            this.sy = sy;\n            if (!hasSx && proportional) {\n                const ratio = sy / oldSy;\n                this.sx *= ratio;\n            }\n        }\n\n        if (anchor & (ScaleAnchor.Left | ScaleAnchor.Right)) {\n            const newW = this.width;\n            const diff = newW - oldW;\n            const diffOver2 = diff / 2;\n            if (anchor & ScaleAnchor.Left) { this.x += diffOver2; }\n            if (anchor & ScaleAnchor.Right) { this.x -= diffOver2; }\n        }\n        if (anchor & (ScaleAnchor.Top | ScaleAnchor.Bottom)) {\n            const newH = this.height;\n            const diff = newH - oldH;\n            const diffOver2 = diff / 2;\n            if (anchor & ScaleAnchor.Top) { this.y += diffOver2; }\n            if (anchor & ScaleAnchor.Bottom) { this.y -= diffOver2; }\n        }\n    }\n\n    //% blockId=sprite_set_scale\n    //% block=\"set %sprite(mySprite) scale to $value anchor $anchor\"\n    //% expandableArgumentMode=enabled\n    //% inlineInputMode=inline\n    //% value.defl=1\n    //% anchor.defl=ScaleAnchor.Middle\n    //% help=sprites/sprite/set-scale\n    //% group=\"Scale\" weight=90\n    setScale(value: number, anchor?: ScaleAnchor): void {\n        const direction = ScaleDirection.Uniformly;\n        anchor = anchor || ScaleAnchor.Middle;\n\n        let sx: number;\n        let sy: number;\n\n        if (direction & ScaleDirection.Horizontally) sx = value;\n        if (direction & ScaleDirection.Vertically) sy = value;\n\n        this.setScaleCore(sx, sy, anchor);\n    }\n\n    //% blockId=sprite_change_scale\n    //% block=\"change %sprite(mySprite) scale by $value anchor $anchor\"\n    //% expandableArgumentMode=enabled\n    //% inlineInputMode=inline\n    //% value.defl=1\n    //% anchor.defl=ScaleAnchor.Middle\n    //% help=sprites/sprite/change-scale\n    //% group=\"Scale\" weight=90\n    changeScale(value: number, anchor?: ScaleAnchor): void {\n        const direction = ScaleDirection.Uniformly;\n        anchor = anchor || ScaleAnchor.Middle;\n\n        let sx: number;\n        let sy: number;\n\n        if (direction & ScaleDirection.Horizontally) sx = this.sx + value;\n        if (direction & ScaleDirection.Vertically) sy = this.sy + value;\n\n        this.setScaleCore(sx, sy, anchor);\n    }\n\n    toString() {\n        return `${this.id}(${this.x},${this.y})->(${this.vx},${this.vy})`;\n    }\n\n    protected drawSay(camera: scene.Camera) {\n        if (this.sayRenderer) {\n            if (this.sayEndTime !== undefined) {\n                if (control.millis() < this.sayEndTime) {\n                    this.sayRenderer.draw(screen, camera, this);\n                }\n                else {\n                    this.sayRenderer.destroy();\n                    this.sayRenderer = undefined;\n                    this.sayEndTime = undefined;\n                }\n            }\n            else {\n                this.sayRenderer.draw(screen, camera, this)\n            }\n        }\n    }\n\n    protected drawDebug(left: number, top: number, offsetX: number, offsetY: number) {\n        if (this.flags & SpriteFlag.ShowPhysics) {\n            const font = image.font5;\n            const margin = 2;\n            let tx = left;\n            let ty = top + this.height + margin;\n            screen.print(`${this.x >> 0},${this.y >> 0}`, tx, ty, 1, font);\n            tx -= font.charWidth;\n            if (this.vx || this.vy) {\n                ty += font.charHeight + margin;\n                screen.print(`v${this.vx >> 0},${this.vy >> 0}`, tx, ty, 1, font);\n            }\n            if (this.ax || this.ay) {\n                ty += font.charHeight + margin;\n                screen.print(`a${this.ax >> 0},${this.ay >> 0}`, tx, ty, 1, font);\n            }\n        }\n\n        // debug info\n        if (game.debug) {\n            screen.drawRect(\n                Fx.toInt(this._hitbox.left) - offsetX,\n                Fx.toInt(this._hitbox.top) - offsetY,\n                Fx.toInt(this._hitbox.width),\n                Fx.toInt(this._hitbox.height),\n                1\n            );\n        }\n    }\n\n    protected drawSprite(drawLeft: number, drawTop: number) {\n        if (!this.isScaled())\n            screen.drawTransparentImage(this._image, drawLeft, drawTop);\n        else\n            screen.blit(\n                // dst rect in screen\n                drawLeft, drawTop,\n                this.width,\n                this.height,\n                // src rect in sprite image\n                this._image,\n                0, 0,\n                this._image.width, this._image.height,\n                true, false);\n    }\n}\n","spriteevents.ts":"namespace sprites {\n    /**\n     * Run code when a certain kind of sprite is created\n     * @param kind\n     * @param sprite\n     */\n    //% group=\"Lifecycle\" draggableParameters=\"reporter\" weight=97\n    //% blockId=spritesoncreated block=\"on created $sprite of kind $kind=spritekind\"\n    //% help=sprites/on-created\n    export function onCreated(kind: number, handler: (sprite: Sprite) => void): void {\n        if (!handler || kind == undefined) return;\n\n        const sc = game.currentScene();\n        sc.createdHandlers.push(\n            new scene.SpriteHandler(\n                kind,\n                handler\n            )\n        )\n    }\n\n    /**\n     * Run code when a certain kind of sprite is destroyed\n     * @param kind\n     * @param sprite\n     */\n    //% group=\"Lifecycle\"\n    //% weight=96 draggableParameters=\"reporter\"\n    //% blockId=spritesondestroyed block=\"on destroyed $sprite of kind $kind=spritekind \"\n    //% help=sprites/on-destroyed\n    export function onDestroyed(kind: number, handler: (sprite: Sprite) => void) {\n        if (!handler || kind == undefined) return;\n\n        const sc = game.currentScene();\n        sc.destroyedHandlers.push(\n            new scene.SpriteHandler(\n                kind,\n                handler\n            )\n        );\n    }\n\n    /**\n     * Run code when two kinds of sprites overlap\n     */\n    //% group=\"Overlaps\"\n    //% weight=100 draggableParameters=\"reporter\"\n    //% blockId=spritesoverlap block=\"on $sprite of kind $kind=spritekind overlaps $otherSprite of kind $otherKind=spritekind\"\n    //% help=sprites/on-overlap\n    //% blockGap=8\n    export function onOverlap(kind: number, otherKind: number, handler: (sprite: Sprite, otherSprite: Sprite) => void) {\n        if (kind == undefined || otherKind == undefined || !handler) return;\n        const sc = game.currentScene();\n        const overlapHandlers = sc.overlapHandlers;\n        const overlapMap = sc.overlapMap;\n\n        function associate(a: number, b: number) {\n            if (!overlapMap[a]) {\n                overlapMap[a] = [];\n            }\n\n            overlapMap[a].push(b);\n        }\n\n        associate(kind, otherKind);\n        associate(otherKind, kind);\n\n        overlapHandlers.push(\n            new scene.OverlapHandler(\n                kind,\n                otherKind,\n                handler\n            )\n        );\n    }\n}\n\nnamespace scene {\n    /**\n     * Run code when a certain kind of sprite overlaps a tile\n     * @param kind\n     * @param tile\n     * @param handler\n     */\n    //% group=\"Tilemaps\"\n    //% weight=120 draggableParameters=\"reporter\" blockGap=8\n    //% blockId=spriteshittile block=\"on $sprite of kind $kind=spritekind overlaps $tile at $location\"\n    //% tile.shadow=tileset_tile_picker\n    //% help=scene/on-overlap-tile\n    export function onOverlapTile(kind: number, tile: Image, handler: (sprite: Sprite, location: tiles.Location) => void) {\n        if (kind == undefined || !tile || !handler) return;\n\n        const tileOverlapHandlers = game.currentScene().tileOverlapHandlers;\n        tileOverlapHandlers.push(\n            new scene.TileOverlapHandler(\n                kind,\n                tile,\n                handler\n            )\n        );\n    }\n\n    /**\n     * Run code when a certain kind of sprite hits a wall\n     * @param kind\n     * @param handler\n     */\n    //% group=\"Tilemaps\"\n    //% weight=100 draggableParameters=\"reporter\" blockGap=8\n    //% blockId=spriteshitwall block=\"on $sprite of kind $kind=spritekind hits wall at $location\"\n    //% help=scene/on-hit-wall\n    export function onHitWall(kind: number, handler: (sprite: Sprite, location: tiles.Location) => void) {\n        if (kind == undefined || !handler) return;\n\n        const wallCollisionHandlers = game.currentScene().wallCollisionHandlers;\n        wallCollisionHandlers.push(\n            new scene.TileWallHandler(\n                kind,\n                handler\n            )\n        );\n    }\n}","spritekind.ts":"namespace sprites {\n    /**\n     * Gets the \"kind\" of sprite\n     */\n    //% shim=KIND_GET\n    //% blockId=spritekind block=\"$kind\"\n    //% kindNamespace=SpriteKind kindMemberName=kind kindPromptHint=\"e.g. Coin, Fireball, Asteroid...\"\n    //% help=sprites/sprite-kind\n    export function _spriteKind(kind: number): number {\n        return kind;\n    }\n\n    /**\n     * Gets the sprite type\n     */\n    //% blockHidden=1 shim=ENUM_GET deprecated=true\n    //% blockId=spritetype block=\"$kind\" enumInitialMembers=\"Player,Projectile,Food,Enemy\"\n    //% enumName=SpriteKindLegacy enumMemberName=kind enumPromptHint=\"e.g. Coin, Fireball, Asteroid...\"\n    export function _spriteType(kind: number): number {\n        return kind;\n    }\n}\n\nnamespace SpriteKind {\n    let nextKind: number;\n\n    export function create() {\n        if (nextKind === undefined) nextKind = 1000;\n        return nextKind++;\n    }\n\n    //% isKind\n    export const Player = create();\n\n    //% isKind\n    export const Projectile = 1;\n\n    //% isKind\n    export const Food = create();\n\n    //% isKind\n    export const Enemy = create();\n}","spritemap.ts":"namespace sprites {\n    export class SpriteMap {\n        private cellWidth: number;\n        private cellHeight: number;\n        private rowCount: number;\n        private columnCount: number;\n        private buckets: Sprite[][];\n        filledBuckets: Sprite[][];\n\n        constructor() {\n            this.buckets = [];\n        }\n\n        /**\n         * Returns a potential list of neighbors\n         */\n        neighbors(sprite: Sprite): Sprite[] {\n            const n: Sprite[] = [];\n            const layer = sprite.layer;\n            this.mergeAtKey(sprite.left, sprite.top, layer, n)\n            this.mergeAtKey(sprite.left, sprite.bottom, layer, n)\n            this.mergeAtKey(sprite.right, sprite.top, layer, n)\n            this.mergeAtKey(sprite.right, sprite.bottom, layer, n)\n            n.removeElement(sprite);\n            return n;\n        }\n\n        /**\n         * Gets the overlaping sprites if any\n         * @param sprite\n         */\n        overlaps(sprite: Sprite): Sprite[] {\n            const n = this.neighbors(sprite);\n            const o = n.filter(neighbor => sprite.overlapsWith(neighbor));\n            return o;\n        }\n\n        draw() {\n            for (let x = 0; x < this.columnCount; ++x) {\n                for (let y = 0; y < this.rowCount; ++y) {\n                    const left = x * this.cellWidth;\n                    const top = y * this.cellHeight;\n                    const k = this.key(left, top);\n                    const b = this.buckets[k];\n                    if (b && b.length)\n                        screen.drawRect(left, top, this.cellWidth, this.cellHeight, 5);\n                }\n            }\n        }\n\n        /**\n         * Recompute hashes for all objects\n         */\n        resizeBuckets(sprites: Sprite[]) {\n            // rescale buckets\n            let maxWidth = 0;\n            let maxHeight = 0;\n            for (const sprite of sprites) {\n                if (sprite.width > maxWidth) maxWidth = sprite.width;\n                if (sprite.height > maxHeight) maxHeight = sprite.height;\n            }\n\n            const tMap = game.currentScene().tileMap;\n\n            const areaWidth = tMap ? tMap.areaWidth() : screen.width;\n            const areaHeight = tMap ? tMap.areaHeight() : screen.height;\n\n            this.cellWidth = Math.clamp(8, areaWidth >> 2, maxWidth << 1);\n            this.cellHeight = Math.clamp(8, areaHeight >> 2, maxHeight << 1);\n            this.rowCount = Math.idiv(areaHeight, this.cellHeight);\n            this.columnCount = Math.idiv(areaWidth, this.cellWidth);\n        }\n\n        clear() {\n            this.buckets = [];\n            this.filledBuckets = [];\n        }\n\n        private key(x: number, y: number): number {\n            const xi = Math.clamp(0, this.columnCount, Math.idiv(x, this.cellWidth));\n            const yi = Math.clamp(0, this.rowCount, Math.idiv(y, this.cellHeight));\n            return xi + yi * this.columnCount;\n        }\n\n        private insertAtKey(x: number, y: number, sprite: Sprite) {\n            const k = this.key(x, y);\n            let bucket = this.buckets[k];\n            if (!bucket) {\n                bucket = this.buckets[k] = [];\n                this.filledBuckets.push(bucket);\n            }\n            if (bucket.indexOf(sprite) < 0)\n                bucket.push(sprite);\n        }\n\n        insertAABB(sprite: Sprite) {\n            const left = sprite.left;\n            const top = sprite.top;\n            const xn = Math.idiv(sprite.width + this.cellWidth - 1, this.cellWidth);\n            const yn = Math.idiv(sprite.height + this.cellHeight - 1, this.cellHeight);\n            for (let x = 0; x <= xn; x++)\n                for (let y = 0; y <= yn; y++)\n                    this.insertAtKey(left + Math.min(sprite.width, x * this.cellWidth), top + Math.min(sprite.height, y * this.cellHeight), sprite)\n        }\n\n        private mergeAtKey(x: number, y: number, layer: number, n: Sprite[]) {\n            const k = this.key(x, y);\n            const bucket = this.buckets[k];\n            if (bucket) {\n                for (const sprite of bucket)\n                    if ((sprite.layer & layer)\n                        && n.indexOf(sprite) < 0)\n                        n.push(sprite);\n            }\n        }\n\n        toString() {\n            return `${this.buckets.length} buckets, ${this.buckets.filter(b => !!b).length} filled`;\n        }\n    }\n}","sprites.ts":"/*\nFrame handlers:\n 10 - physics and collisions\n 20 - frame()\n 60 - screen/sprite background\n 90 - drawing sprites\n 95 - drawing score\n100 - loops.menu()\n200 - screen refresh\n*/\n\n/**\n * Sprites on screen\n */\n//% weight=99 color=\"#4B7BEC\" icon=\"\\uf1d8\"\n//% groups='[\"Create\", \"Physics\", \"Effects\", \"Projectiles\", \"Overlaps\", \"Lifecycle\"]'\nnamespace sprites {\n    export class FollowingSprite {\n        constructor(\n            public self: Sprite,\n            public target: Sprite,\n            public rate: number,\n            public turnRate: number\n        ) { }\n    }\n\n    /**\n     * Create a new sprite from an image\n     * @param img the image\n     */\n    //% group=\"Create\"\n    //% blockId=spritescreate block=\"sprite %img=screen_image_picker of kind %kind=spritekind\"\n    //% expandableArgumentMode=toggle\n    //% blockSetVariable=mySprite\n    //% weight=100 help=sprites/create\n    export function create(img: Image, kind?: number): Sprite {\n        const scene = game.currentScene();\n        const sprite = new Sprite(img)\n        sprite.setKind(kind);\n        scene.physicsEngine.addSprite(sprite);\n\n        // run on created handlers\n        scene.createdHandlers\n            .filter(h => h.kind == kind)\n            .forEach(h => h.handler(sprite));\n\n        return sprite\n    }\n\n    /**\n     * Create a new sprite from an image\n     * @param img the image\n     */\n    //% group=\"Create\"\n    //% blockId=spritescreatenoset block=\"sprite %img=screen_image_picker of kind %kind=spritekind\"\n    //% blockAliasFor=\"sprites.create\"\n    //% expandableArgumentMode=toggle\n    //% weight=99 help=sprites/create\n    //% duplicateShadowOnDrag\n    export function __create(img: Image, kind?: number): Sprite {\n        return sprites.create(img, kind);\n    }\n\n    //% group=\"Effects\"\n    //% weight=80\n    //% blockId=spritedestroy2 block=\"destroy $sprite || with $effect effect for $duration ms\"\n    //% sprite.shadow=variables_get\n    //% sprite.defl=mySprite\n    //% duration.shadow=timePicker\n    //% expandableArgumentMode=\"toggle\"\n    //% help=sprites/sprite/destroy\n    export function destroy(sprite: Sprite, effect?: effects.ParticleEffect, duration?: number) {\n        if (!sprite) return;\n        sprite.destroy(effect, duration);\n    }\n\n    /**\n     * Return an array of all sprites of the given kind.\n     * @param kind the target kind\n     */\n    //% blockId=allOfKind block=\"array of sprites of kind %kind=spritekind\"\n    //% weight=87 help=sprites/all-of-kind\n    export function allOfKind(kind: number): Sprite[] {\n        const spritesByKind = game.currentScene().spritesByKind;\n        if (!(kind >= 0) || !spritesByKind[kind]) return [];\n        else return spritesByKind[kind].sprites();\n    }\n\n    /**\n     * Destroys all sprites of the given kind.\n     */\n    //% group=\"Effects\"\n    //% weight=79 help=sprites/destroy-all-sprites-of-kind\n    //% blockId=sprites_destroy_all_sprites_of_kind\n    //% block=\"destroy all sprites of kind $kind || with $effect effect for $duration ms\"\n    //% kind.shadow=spritekind\n    //% duration.shadow=timePicker\n    //% expandableArgumentMode=\"toggle\"\n    export function destroyAllSpritesOfKind(kind: number, effect?: effects.ParticleEffect, duration?: number) {\n        for (const sprite of allOfKind(kind)) {\n            sprite.destroy(effect, duration);\n        }\n    }\n\n    /**\n     * Create a new sprite with a given speed, and place it at the edge of the screen so it moves towards the middle.\n     * The sprite auto-destroys when it leaves the screen. You can modify position after it's created.\n     */\n    //% group=\"Projectiles\"\n    //% blockId=spritescreateprojectilefromside block=\"projectile %img=screen_image_picker from side with vx %vx vy %vy\"\n    //% vx.shadow=spriteSpeedPicker\n    //% vy.shadow=spriteSpeedPicker\n    //% weight=99 help=sprites/create-projectile-from-side\n    //% blockSetVariable=projectile\n    //% inlineInputMode=inline\n    export function createProjectileFromSide(img: Image, vx: number, vy: number) {\n        return createProjectile(img, vx, vy, SpriteKind.Projectile);\n    }\n\n    /**\n     * Create a new sprite with a given speed that starts from the location of another sprite.\n     * The sprite auto-destroys when it leaves the screen. You can modify position after it's created.\n     */\n    //% group=\"Projectiles\"\n    //% blockId=spritescreateprojectilefromsprite block=\"projectile %img=screen_image_picker from %sprite=variables_get(mySprite) with vx %vx vy %vy\"\n    //% vx.shadow=spriteSpeedPicker\n    //% vy.shadow=spriteSpeedPicker\n    //% weight=99 help=sprites/create-projectile-from-sprite\n    //% blockSetVariable=projectile\n    //% inlineInputMode=inline\n    export function createProjectileFromSprite(img: Image, sprite: Sprite, vx: number, vy: number): Sprite {\n        return createProjectile(img, vx, vy, SpriteKind.Projectile, sprite);\n    }\n\n    /**\n     * Create a new sprite with given speed, and place it at the edge of the screen so it moves towards the middle.\n     * The sprite auto-destroys when it leaves the screen. You can modify position after it's created.\n     */\n    //% group=\"Projectiles\"\n    //% blockId=spritescreateprojectile block=\"projectile %img=screen_image_picker vx %vx vy %vy of kind %kind=spritekind||from sprite %sprite=variables_get(mySprite)\"\n    //% weight=99 help=sprites/create-projectile\n    //% blockSetVariable=projectile\n    //% inlineInputMode=inline\n    //% expandableArgumentMode=toggle\n    //% deprecated=true blockHidden=true\n    export function createProjectile(img: Image, vx: number, vy: number, kind?: number, sprite?: Sprite) {\n        const s = sprites.create(img, kind || SpriteKind.Projectile);\n        const sc = game.currentScene();\n\n        s.vx = vx;\n        s.vy = vy;\n\n        if (sprite) {\n            s.setPosition(sprite.x, sprite.y);\n        } else {\n            // put it at the edge of the screen so that it moves towards the middle\n            // If the scene has a tile map, place the sprite fully on the screen\n            const xOff = sc.tileMap ? -(s.width >> 1) : (s.width >> 1) - 1;\n            const yOff = sc.tileMap ? -(s.height >> 1) : (s.height >> 1) - 1;\n            const cam = game.currentScene().camera;\n\n            let initialX = cam.offsetX;\n            let initialY = cam.offsetY;\n\n            if (vx < 0) {\n                initialX += screen.width + xOff;\n            } else if (vx > 0) {\n                initialX += -xOff;\n            }\n\n            if (vy < 0) {\n                initialY += screen.height + yOff;\n            } else if (vy > 0) {\n                initialY += -yOff;\n            }\n\n            s.setPosition(initialX, initialY);\n        }\n\n        s.flags |= sprites.Flag.AutoDestroy | sprites.Flag.DestroyOnWall;\n\n        return s;\n    }\n\n    export enum Flag {\n        None = 0, // no flags are set\n        // 1 << 0 was previously used for Ghost / is now available.\n        Destroyed = 1 << 1, // whether the sprite has been destroyed or not\n        AutoDestroy = 1 << 2, // remove the sprite when no longer visible\n        StayInScreen = 1 << 3, // sprite cannot move outside the camera region\n        DestroyOnWall = 1 << 4, // destroy sprite on contact with wall\n        BounceOnWall = 1 << 5, // Bounce on walls\n        ShowPhysics = 1 << 6, // display position, velocity, acc\n        Invisible = 1 << 7, // makes the sprite invisible, so it does not show up on the screen\n        IsClipping = 1 << 8, // whether the sprite is currently clipping into a wall. This can happen when a sprite is created or moved explicitly.\n        RelativeToCamera = 1 << 9, // draw relative to the camera, not the world (e.g. HUD elements)\n        GhostThroughTiles = 1 << 10, // No overlaps with tiles\n        GhostThroughWalls = 1 << 11, // No collisions with walls\n        GhostThroughSprites = 1 << 12, // No overlaps with other sprites\n        HitboxOverlaps = 1 << 13, // If set, overlaps with this sprite are based off of both sprites' hitboxes and not pixel perfect\n        Ghost = sprites.Flag.GhostThroughSprites | sprites.Flag.GhostThroughWalls | sprites.Flag.GhostThroughTiles, // doesn't collide with other sprites or walls\n    }\n}\n","spritesay.ts":"namespace sprites {\n    export class BaseSpriteSayRenderer {\n        constructor(public text: string, public fgColor: number, public bgColor: number) {\n        }\n\n        draw(screen: Image, camera: scene.Camera, owner: Sprite) {\n\n        }\n\n        update(dt: number, camera: scene.Camera, owner: Sprite) {\n\n        }\n\n        destroy() {\n\n        }\n    }\n\n    export class SpriteSayRenderer extends BaseSpriteSayRenderer {\n        static drawSayFrame(textLeft: number, textTop: number, textWidth: number, textHeight: number, speakerX: number, speakerY: number, color: number, canvas: Image) {\n            if (textLeft + textWidth < 0 || textTop + textHeight < 0 || textLeft > canvas.width || textTop > canvas.height) return;\n\n            if (textHeight) {\n                // Draw main rectangle\n                canvas.fillRect(\n                    textLeft,\n                    textTop,\n                    textWidth,\n                    textHeight,\n                    color\n                );\n\n                // Draw lines around the rectangle to give it a bubble shape\n                canvas.fillRect(\n                    textLeft - 1,\n                    textTop + 1,\n                    1,\n                    textHeight - 2,\n                    color\n                );\n                canvas.fillRect(\n                    textLeft + textWidth,\n                    textTop + 1,\n                    1,\n                    textHeight - 2,\n                    color\n                );\n                canvas.fillRect(\n                    textLeft + 1,\n                    textTop - 1,\n                    textWidth - 2,\n                    1,\n                    color\n                );\n                canvas.fillRect(\n                    textLeft + 1,\n                    textTop + textHeight,\n                    textWidth - 2,\n                    1,\n                    color\n                );\n\n                // If the speaker location is within the bubble, don't draw an arrow\n                if (speakerX > textLeft && speakerX < textLeft + textWidth && speakerY > textTop && speakerY < textTop + textHeight) return;\n\n                const xDiff = Math.max(\n                    Math.abs(speakerX - textLeft),\n                    Math.abs(speakerX - (textLeft + textWidth))\n                );\n\n                const yDiff = Math.max(\n                    Math.abs(speakerY - textHeight),\n                    Math.abs(speakerY - (textHeight + textHeight))\n                );\n\n                // Draw the arrow\n                if (xDiff > yDiff) {\n                    if (speakerX > textLeft + textWidth) {\n                        const anchorY = Math.max(Math.min(speakerY, textTop + textHeight - 4), textTop + 5);\n                        canvas.fillRect(\n                            textLeft + textWidth + 1,\n                            anchorY - 2,\n                            1,\n                            3,\n                            color\n                        );\n                        canvas.fillRect(\n                            textLeft + textWidth + 2,\n                            anchorY - 1,\n                            1,\n                            1,\n                            color\n                        );\n                    }\n                    else if (speakerX < textLeft) {\n                        const anchorY = Math.max(Math.min(speakerY, textTop + textHeight - 4), textTop + 5);\n                        canvas.fillRect(\n                            textLeft - 2,\n                            anchorY - 2,\n                            1,\n                            3,\n                            color\n                        );\n                        canvas.fillRect(\n                            textLeft - 3,\n                            anchorY - 1,\n                            1,\n                            1,\n                            color\n                        );\n                    }\n                    else if (speakerY > textTop + textHeight) {\n                        const anchorX = Math.max(Math.min(speakerX, textLeft + textWidth - 4), textLeft + 5);\n                        canvas.fillRect(\n                            anchorX - 2,\n                            textTop + textHeight + 1,\n                            3,\n                            1,\n                            color\n                        );\n                        canvas.fillRect(\n                            anchorX - 1,\n                            textTop + textHeight + 2,\n                            1,\n                            1,\n                            color\n                        );\n                    }\n                    else if (speakerY < textTop) {\n                        const anchorX = Math.max(Math.min(speakerX, textLeft + textWidth - 4), textLeft + 5);\n                        canvas.fillRect(\n                            anchorX - 2,\n                            textTop - 2,\n                            3,\n                            1,\n                            color\n                        );\n                        canvas.fillRect(\n                            anchorX - 1,\n                            textTop - 3,\n                            1,\n                            1,\n                            color\n                        );\n                    }\n                }\n                else {\n                    if (speakerY > textTop + textHeight) {\n                        const anchorX = Math.max(Math.min(speakerX, textLeft + textWidth - 4), textLeft + 5);\n                        canvas.fillRect(\n                            anchorX - 2,\n                            textTop + textHeight + 1,\n                            3,\n                            1,\n                            color\n                        );\n                        canvas.fillRect(\n                            anchorX - 1,\n                            textTop + textHeight + 2,\n                            1,\n                            1,\n                            color\n                        );\n                    }\n                    else if (speakerY < textTop) {\n                        const anchorX = Math.max(Math.min(speakerX, textLeft + textWidth - 4), textLeft + 5);\n                        canvas.fillRect(\n                            anchorX - 2,\n                            textTop - 2,\n                            3,\n                            1,\n                            color\n                        );\n                        canvas.fillRect(\n                            anchorX - 1,\n                            textTop - 3,\n                            1,\n                            1,\n                            color\n                        );\n                    }\n                    else if (speakerX > textLeft + textWidth) {\n                        const anchorY = Math.max(Math.min(speakerY, textTop + textHeight - 4), textTop + 5);\n                        canvas.fillRect(\n                            textLeft + textWidth + 1,\n                            anchorY - 2,\n                            1,\n                            3,\n                            color\n                        );\n                        canvas.fillRect(\n                            textLeft + textWidth + 2,\n                            anchorY - 1,\n                            1,\n                            1,\n                            color\n                        );\n                    }\n                    else if (speakerX < textLeft) {\n                        const anchorY = Math.max(Math.min(speakerY, textTop + textHeight - 4), textTop + 5);\n                        canvas.fillRect(\n                            textLeft - 2,\n                            anchorY - 2,\n                            1,\n                            3,\n                            color\n                        );\n                        canvas.fillRect(\n                            textLeft - 3,\n                            anchorY - 1,\n                            1,\n                            1,\n                            color\n                        );\n                    }\n                }\n            }\n        }\n\n        protected renderText: RenderText;\n        protected animation: RenderTextAnimation;\n\n        constructor(text: string, fg: number, bg: number, animated: boolean, timeOnScreen: number) {\n            super(text, fg, bg);\n\n            this.renderText = new sprites.RenderText(text, 100);\n            if (animated) {\n                this.animation = new sprites.RenderTextAnimation(this.renderText, 40);\n                if (timeOnScreen >= 0) {\n                    const numberOfPauses = this.animation.numPages() + 1;\n                    const pauseTime = Math.min((timeOnScreen / (2 * numberOfPauses)) | 0, 1000);\n                    this.animation.setPauseLength(pauseTime);\n                    this.animation.setTextSpeed(this.renderText.printableCharacters() * 1000 / (timeOnScreen - pauseTime * numberOfPauses))\n                }\n\n                this.animation.start();\n            }\n        }\n\n        draw(screen: Image, camera: scene.Camera, owner: Sprite) {\n            const ox = (owner.flags & sprites.Flag.RelativeToCamera) ? 0 : camera.drawOffsetX;\n            const oy = (owner.flags & sprites.Flag.RelativeToCamera) ? 0 : camera.drawOffsetY;\n\n            const l = Math.floor(owner.left - ox);\n            const t = Math.floor(owner.top - oy);\n\n            const height = this.animation ? this.animation.currentHeight() : this.renderText.height;\n            const width = this.animation ? this.animation.currentWidth() : this.renderText.width;\n            const sayLeft = l + (owner.width >> 1) - (width >> 1);\n            const sayTop =  t - height - 4;\n\n            if (sayLeft + width < 0 || sayTop + height < 0 || sayLeft > screen.width || sayTop > screen.height) return;\n\n            SpriteSayRenderer.drawSayFrame(sayLeft, sayTop, width, height, owner.x - ox, owner.y - oy, this.bgColor, screen);\n\n            if (height) {\n                if (this.animation) {\n                    this.animation.draw(screen, sayLeft, sayTop, this.fgColor);\n                }\n                else {\n                    this.renderText.draw(screen, sayLeft, sayTop, this.fgColor);\n                }\n            }\n        }\n    }\n\n    export class LegacySpriteSayRenderer extends BaseSpriteSayRenderer {\n        protected sayBubbleSprite: Sprite;\n        protected updateSay: (dt: number, camera: scene.Camera) => void;\n\n        constructor(text: string, timeOnScreen: number, owner: Sprite, fg: number, bg: number) {\n            super(text, fg, bg);\n\n            const textToDisplay = console.inspect(text).split(\"\\n\").join(\" \");\n\n            let pixelsOffset = 0;\n            let holdTextSeconds = 1.5;\n            let bubblePadding = 4;\n            let maxTextWidth = 100;\n            let font = image.getFontForText(textToDisplay);\n            let startX = 2;\n            let startY = 2;\n            let bubbleWidth = textToDisplay.length * font.charWidth + bubblePadding;\n            let maxOffset = textToDisplay.length * font.charWidth - maxTextWidth;\n            let bubbleOffset: number = Fx.toInt(owner._hitbox.oy);\n            let needsRedraw = true;\n\n            // sets the default scroll speed in pixels per second\n            let speed = 45;\n\n            // Calculates the speed of the scroll if scrolling is needed and a time is specified\n            if (timeOnScreen && maxOffset > 0) {\n                speed = (maxOffset + (2 * maxTextWidth)) / (timeOnScreen / 1000);\n                speed = Math.max(speed, 45);\n                holdTextSeconds = maxTextWidth / speed;\n                holdTextSeconds = Math.min(holdTextSeconds, 1.5);\n            }\n\n            if (timeOnScreen) {\n                timeOnScreen = timeOnScreen + game.runtime();\n            }\n\n            if (bubbleWidth > maxTextWidth + bubblePadding) {\n                bubbleWidth = maxTextWidth + bubblePadding;\n            } else {\n                maxOffset = -1;\n            }\n\n            // reuse previous sprite if possible\n            const imgh = font.charHeight + bubblePadding;\n            if (!this.sayBubbleSprite\n                || this.sayBubbleSprite.width != bubbleWidth\n                || this.sayBubbleSprite.height != imgh) {\n                const sayImg = image.create(bubbleWidth, imgh);\n                if (this.sayBubbleSprite) // sprite with same image size, we can reuse it\n                    this.sayBubbleSprite.setImage(sayImg);\n                else { // needs a new sprite\n                    this.sayBubbleSprite = sprites.create(sayImg, -1);\n                    this.sayBubbleSprite.setFlag(SpriteFlag.Ghost, true);\n                    this.sayBubbleSprite.setFlag(SpriteFlag.RelativeToCamera, !!(owner.flags & sprites.Flag.RelativeToCamera))\n                }\n            }\n            this.updateSay = (dt, camera) => {\n                // The minus 2 is how much transparent padding there is under the sayBubbleSprite\n                this.sayBubbleSprite.y = owner.top + bubbleOffset - ((font.charHeight + bubblePadding) >> 1) - 2;\n                this.sayBubbleSprite.x = owner.x;\n                this.sayBubbleSprite.z = owner.z + 1;\n\n                // Update box stuff as long as timeOnScreen doesn't exist or it can still be on the screen\n                if (!timeOnScreen || timeOnScreen > game.runtime()) {\n                    // move bubble\n                    if (!owner.isOutOfScreen(camera)) {\n                        const ox = camera.offsetX;\n                        const oy = camera.offsetY;\n\n                        if (this.sayBubbleSprite.left - ox < 0) {\n                            this.sayBubbleSprite.left = 0;\n                        }\n\n                        if (this.sayBubbleSprite.right - ox > screen.width) {\n                            this.sayBubbleSprite.right = screen.width;\n                        }\n\n                        // If sprite bubble above the sprite gets cut off on top, place the bubble below the sprite\n                        if (this.sayBubbleSprite.top - oy < 0) {\n                            this.sayBubbleSprite.y = (this.sayBubbleSprite.y - 2 * owner.y) * -1;\n                        }\n                    }\n\n                    // Pauses at beginning of text for holdTextSeconds length\n                    if (holdTextSeconds > 0) {\n                        holdTextSeconds -= game.eventContext().deltaTime;\n                        // If scrolling has reached the end, start back at the beginning\n                        if (holdTextSeconds <= 0 && pixelsOffset > 0) {\n                            pixelsOffset = 0;\n                            holdTextSeconds = maxTextWidth / speed;\n                            needsRedraw = true;\n                        }\n                    } else {\n                        pixelsOffset += dt * speed;\n                        needsRedraw = true;\n\n                        // Pause at end of text for holdTextSeconds length\n                        if (pixelsOffset >= maxOffset) {\n                            pixelsOffset = maxOffset;\n                            holdTextSeconds = maxTextWidth / speed;\n                        }\n                    }\n\n                    if (needsRedraw) {\n                        needsRedraw = false;\n                        this.sayBubbleSprite.image.fill(this.bgColor);\n                        // If maxOffset is negative it won't scroll\n                        if (maxOffset < 0) {\n                            this.sayBubbleSprite.image.print(textToDisplay, startX, startY, this.fgColor, font);\n\n                        } else {\n                            this.sayBubbleSprite.image.print(textToDisplay, startX - pixelsOffset, startY, this.fgColor, font);\n                        }\n\n                        // Left side padding\n                        this.sayBubbleSprite.image.fillRect(0, 0, bubblePadding >> 1, font.charHeight + bubblePadding, this.bgColor);\n                        // Right side padding\n                        this.sayBubbleSprite.image.fillRect(bubbleWidth - (bubblePadding >> 1), 0, bubblePadding >> 1, font.charHeight + bubblePadding, this.bgColor);\n                        // Corners removed\n                        this.sayBubbleSprite.image.setPixel(0, 0, 0);\n                        this.sayBubbleSprite.image.setPixel(bubbleWidth - 1, 0, 0);\n                        this.sayBubbleSprite.image.setPixel(0, font.charHeight + bubblePadding - 1, 0);\n                        this.sayBubbleSprite.image.setPixel(bubbleWidth - 1, font.charHeight + bubblePadding - 1, 0);\n                    }\n                } else {\n                    // If can't update because of timeOnScreen then destroy the sayBubbleSprite and reset updateSay\n                    this.updateSay = undefined;\n                    this.sayBubbleSprite.destroy();\n                    this.sayBubbleSprite = undefined;\n                }\n            }\n            this.updateSay(0, game.currentScene().camera);\n        }\n\n        update(dt: number, camera: scene.Camera, owner: Sprite) {\n            if (!this.sayBubbleSprite) return;\n            this.updateSay(dt, camera);\n            if (!this.sayBubbleSprite) return;\n\n            this.sayBubbleSprite.setFlag(SpriteFlag.RelativeToCamera, !!(owner.flags & SpriteFlag.RelativeToCamera));\n\n            if (owner.flags & Flag.Destroyed) this.destroy();\n        }\n\n        destroy() {\n            if (this.sayBubbleSprite) this.sayBubbleSprite.destroy();\n            this.sayBubbleSprite = undefined;\n        }\n    }\n}","spriteset.ts":"namespace sprites {\n    /*\n    * A set of sprites\n    */\n    export class SpriteSet {\n        private _sprites: Sprite[];\n\n        /**\n         * Create a new set from an array of sprites\n         * @param sprites\n         */\n        static createFromArray(sprites: Sprite[]): SpriteSet {\n            const sp = new SpriteSet();\n            const n = sprites.length;\n            for (let i = 0; i < n; ++i)\n                sp.add(sprites[i]);\n            return sp;\n        }\n\n        constructor() {\n            this._sprites = [];\n        }\n\n        /**\n         * Gets the number of sprites in the set\n         */\n        get length() {\n            return this._sprites.length;\n        }\n\n        /**\n         * Gets the snapshot of the current list of sprites\n         */\n        sprites() {\n            return this._sprites.filter(s => !(s.flags & sprites.Flag.Destroyed));\n        }\n\n        /**\n         * Adds the sprite, returns true if added; false if the sprite was already in the set\n         * @param sprite\n         */\n        add(sprite: Sprite): boolean {\n            if (!sprite) return false; // don't add nulls\n\n            // scan if in set\n            if (this.contains(sprite))\n                return false;\n            this._sprites.push(sprite);\n            return true;\n        }\n\n        /**\n         * Adds sprite and removes from old set. Returns true if sprite was in old set and not in new set.\n         * @param oldSet\n         * @param sprite\n         */\n        addFrom(oldSet: SpriteSet, sprite: Sprite): boolean {\n            const removed = oldSet.remove(sprite);\n            const added = this.add(sprite);\n            return removed && added;\n        }\n\n        /**\n         * Removes sprite from set. Returns true if the sprite was in the set\n         * @param sprite\n         */\n        remove(sprite: Sprite): boolean {\n            const i = this._sprites.indexOf(sprite);\n            if (i > -1) {\n                this._sprites.splice(i, 1);\n                return true;\n            }\n            return false;\n        }\n\n        /**\n         * Checks if the sprite is part of the set\n         * @param sprite\n         */\n        contains(sprite: Sprite): boolean {\n            return this._sprites.indexOf(sprite) > -1;\n        }\n\n        /**\n         * Removes all the sprites from the set\n        */\n        clear() {\n            this._sprites.splice(0, this._sprites.length);\n        }\n\n        /**\n         * Removes the last sprite in the set\n         */\n        pop(): Sprite {\n            return this._sprites.pop();\n        }\n\n        toString() {\n            return `${this.length} sprites`\n        }\n    }\n}","systemKeyboard.cpp":"#include \"pxt.h\"\n\nnamespace Keyboard {\n\n//%\nvoid promptForText(int maxLength, bool numberOnly) {\n}\n\n//%\nvoid cancelTextPrompt() {\n}\n\n//%\nchar* getTextPromptString() {\n    return NULL;\n}\n\n//%\nchar* getLocalizedInstructions() {\n    return NULL;\n}\n\n//%\nint getTextPromptSelectionStart() {\n    return 0;\n}\n\n//%\nint getTextPromptSelectionEnd() {\n    return 0;\n}\n\n//%\nbool isSystemKeyboardSupported() {\n    return false;\n}\n}","systemKeyboard.d.ts":"\n/**\n * These shims are for enabling system keyboard support in text/number prompts.\n */\ndeclare namespace helpers {\n    //% shim=Keyboard::promptForText\n    function _promptForText(maxLength: number, numbersOnly: boolean): void;\n\n    //% shim=Keyboard::cancelTextPrompt\n    function _cancelTextPrompt(): void;\n\n    //% shim=Keyboard::getTextPromptString\n    function _getTextPromptString(): string;\n\n    //% shim=Keyboard::getLocalizedInstructions\n    function _getLocalizedInstructions(): string;\n\n    //% shim=Keyboard::getTextPromptSelectionStart\n    function _getTextPromptSelectionStart(): number;\n\n    //% shim=Keyboard::getTextPromptSelectionEnd\n    function _getTextPromptSelectionEnd(): number;\n\n    //% shim=Keyboard::isSystemKeyboardSupported\n    function _isSystemKeyboardSupported(): boolean;\n}","systemmenu.ts":"namespace scene.systemMenu {\n    let instance: PauseMenu;\n    let customMenuOptions: MenuOption[];\n\n    export enum CardState {\n        Selected,\n        Active,\n        None\n    }\n\n    export interface MenuTheme {\n        cardSpacing: number;\n        cardWidth: number;\n        cardsPerRow: number;\n        padding: number;\n        cardsTop: number;\n        infoTop: number;\n\n        // \"PAUSED\"\n        headerText: string;\n\n        headerFont: image.Font;\n        infoFont: image.Font;\n\n        selectedCard: Image;\n        activeCard: Image;\n        basicCard: Image;\n    }\n\n    export class MenuOption {\n        protected card: Sprite;\n        protected icon: Sprite;\n\n        protected top: number;\n        protected state: CardState;\n\n        protected theme: MenuTheme;\n\n        constructor(protected iconImage: Image, public getText: () => string, public action: () => void) {\n        }\n\n        show() {\n            this.card = sprites.create(this.theme ? this.theme.basicCard : CARD_NORMAL);\n            this.card.z = 1;\n\n            this.icon = sprites.create(this.iconImage);\n            this.icon.z = 2;\n\n            this.state = CardState.None;\n        }\n\n        position(left: number, top: number) {\n            this.top = top;\n\n            this.card.left = left;\n            this.card.top = top;\n\n            this.icon.x = this.card.x;\n            this.icon.y = this.card.y;\n        }\n\n        setOffset(offset: number) {\n            this.card.top = this.top + offset;\n            this.icon.y = this.card.y;\n        }\n\n        setTheme(theme: MenuTheme) {\n            this.theme = theme;\n            this.updateCard();\n        }\n\n        setState(state: CardState) {\n            if (this.state === state) return;\n            this.state = state;\n            this.updateCard();\n        }\n\n        dispose() {\n            if (this.card) {\n                this.card.destroy();\n                this.icon.destroy();\n                this.card = undefined;\n                this.icon = undefined;\n            }\n        }\n\n        protected updateCard() {\n            if (!this.theme) return;\n            switch (this.state) {\n                case CardState.None: this.card.setImage(this.theme.basicCard); break;\n                case CardState.Selected: this.card.setImage(this.theme.selectedCard); break;\n                case CardState.Active: this.card.setImage(this.theme.activeCard); break;\n            }\n\n            // Center the icon\n            this.icon.x = this.card.x;\n            this.icon.y = this.card.y;\n        }\n    }\n\n    export class PauseMenu {\n        protected options: MenuOption[];\n        protected theme: MenuTheme;\n\n        // Index of selected card\n        protected selection: number;\n\n        // The row that is currently at the top of the screen\n        protected scrollRow: number;\n\n        // The pixel offset for the scrollRow\n        protected scrollTarget: number;\n\n        // The current pixel offset of the scroll (might be animating)\n        protected scrollOffset: number;\n\n        constructor(protected generator: () => MenuOption[], theme?: MenuTheme) {\n            this.theme = theme || buildMenuTheme(CARD_NORMAL.width, 3);\n            this.scrollRow = 0;\n            this.scrollOffset = 0;\n            this.scrollTarget = 0;\n        }\n\n        show() {\n            this.options = this.generator();\n            this.selection = 0;\n\n            let current: MenuOption;\n            for (let i = 0; i < this.options.length; i++) {\n                current = this.options[i];\n                current.show();\n                current.setTheme(this.theme);\n                current.position(\n                    this.theme.padding + (i % this.theme.cardsPerRow) * (this.theme.cardWidth + this.theme.cardSpacing),\n                    this.theme.cardsTop + (Math.idiv(i, this.theme.cardsPerRow) * (this.theme.cardWidth + this.theme.cardSpacing))\n                );\n            }\n\n            controller._setUserEventsEnabled(false);\n\n            controller.A.onEvent(SYSTEM_KEY_DOWN, () => {\n                if (!this.options || !this.options[this.selection]) return;\n                this.options[this.selection].setState(CardState.Active);\n            });\n\n            controller.A.onEvent(SYSTEM_KEY_UP, () => {\n                if (!this.options || !this.options[this.selection]) return;\n                this.options[this.selection].setState(CardState.Selected);\n                control.runInParallel(this.options[this.selection].action)\n            });\n\n            controller.B.onEvent(SYSTEM_KEY_DOWN, () => {\n                closeMenu();\n            });\n\n            controller.menu.onEvent(SYSTEM_KEY_DOWN, () => {\n                closeMenu();\n            });\n\n            controller.up.onEvent(SYSTEM_KEY_DOWN, () => {\n                this.setSelection(Math.max(0, this.selection - this.theme.cardsPerRow));\n            });\n\n            controller.left.onEvent(SYSTEM_KEY_DOWN, () => {\n                this.setSelection(Math.max(0, this.selection - 1));\n            });\n\n            controller.down.onEvent(SYSTEM_KEY_DOWN, () => {\n                this.setSelection(Math.min(this.options.length - 1, this.selection + this.theme.cardsPerRow));\n            });\n\n            controller.right.onEvent(SYSTEM_KEY_DOWN, () => {\n                this.setSelection(Math.min(this.options.length - 1, this.selection + 1));\n            });\n\n            game.onShade(() => {\n                this.onUpdate();\n                this.drawText();\n            });\n\n            this.setSelection(0);\n        }\n\n        onUpdate() {\n            // Should probably factor out this animation\n            let t = control.millis() / 250;\n            for (let i = 0; i < this.options.length; i++) {\n                this.options[i].setOffset(2 * Math.sin(t - (i % this.theme.cardsPerRow) * (Math.PI / 2)))\n            }\n\n            const dt = game.currentScene().eventContext.deltaTime;\n            if (this.scrollOffset < this.scrollTarget) {\n                this.scrollOffset += dt * 100;\n            }\n            else if (this.scrollOffset > this.scrollTarget) {\n                this.scrollOffset -= dt * 100;\n            }\n            else {\n                return;\n            }\n\n            if (Math.abs(this.scrollOffset - this.scrollTarget) < 2) {\n                this.scrollOffset = this.scrollTarget;\n            }\n\n            game.currentScene().camera.offsetY = this.scrollOffset;\n        }\n\n        setSelection(selection: number) {\n            if (!this.options) return;\n\n            if (this.options[this.selection]) {\n                this.options[this.selection].setState(CardState.None);\n            }\n\n            this.selection = selection;\n\n            if (this.options[this.selection]) {\n                this.options[this.selection].setState(controller.A.isPressed() ? CardState.Active : CardState.Selected);\n            }\n\n            this.updateScrollTarget();\n        }\n\n        drawText() {\n            if (!this.options) return;\n\n            // Black bar to draw the header on\n            screen.fillRect(0, 0, screen.width, this.theme.cardsTop - 2, 15);\n\n            // Header text\n            screen.printCenter(this.theme.headerText, 2, 1, this.theme.headerFont);\n\n            // Black bar for the info box to draw on\n            screen.fillRect(0, this.theme.infoTop - 3, screen.width, screen.height - this.theme.infoTop + 6, 15);\n\n            // White info box\n            screen.fillRect(this.theme.padding, this.theme.infoTop, screen.width - (this.theme.padding << 1), this.theme.infoFont.charHeight + 1, 1);\n\n            // Info text\n            screen.printCenter(this.options[this.selection].getText(), this.theme.infoTop + 1, 15, this.theme.infoFont);\n        }\n\n        dispose() {\n            if (this.options) {\n                this.options.forEach(o => o.dispose());\n                this.options = undefined;\n            }\n        }\n\n        protected updateScrollTarget() {\n            const row = Math.idiv(this.selection, this.theme.cardsPerRow);\n\n            // FIXME: Assumes that there are always two rows on screen\n            if (row === this.scrollRow || row - 1 === this.scrollRow) return;\n\n            if (row > this.scrollRow) this.scrollRow++;\n            else this.scrollRow--;\n\n            this.scrollTarget = this.scrollRow * (this.theme.cardSpacing + this.theme.cardWidth);\n        }\n    }\n\n    // we intentionally only save volume when the user explicitly adjusts it\n    // we don't want to save it when adjusted programatically, because it could for example changing in a loop\n    function setVolume(newVolume: number) {\n        music.setVolume(newVolume);\n        music.playTone(440, 500);\n        settings.writeNumber(\"#volume\", newVolume)\n    }\n\n    function volumeUp() {\n        const v = music.volume();\n        const remainder = v % 32;\n        const newVolume = v + 32 - remainder;\n        setVolume(newVolume);\n    }\n\n    function volumeDown() {\n        const v = music.volume();\n        const remainder = v % 32;\n        const newVolume = v - (remainder ? remainder : 32);\n        setVolume(newVolume);\n    }\n\n    function brightnessUp() {\n        setScreenBrightness(screen.brightness() + 5);\n    }\n\n    function brightnessDown() {\n        setScreenBrightness(screen.brightness() - 5);\n    }\n\n    function setScreenBrightness(b: number) {\n        screen.setBrightness(b);\n        // we intentionally only save brightness when the user explicitly adjusts it\n        // we don't want to save it when adjusted programatically, because it could for example changing in a loop\n        settings.writeNumber(\"#brightness\", screen.brightness())\n    }\n\n    function toggleStats() {\n        game.stats = !game.stats;\n        if (!game.stats && control.EventContext.onStats) {\n            control.EventContext.onStats(\"\");\n        }\n    }\n\n    function toggleConsole() {\n        if (game.consoleOverlay.isVisible())\n            game.consoleOverlay.setVisible(false);\n        else {\n            game.consoleOverlay.setVisible(true);\n            console.log(\"console\");\n        }\n    }\n\n    function sleep() {\n        power.deepSleep();\n    }\n\n    export function closeMenu() {\n        if (instance) {\n            instance.dispose();\n            instance = undefined;\n            controller._setUserEventsEnabled(true);\n            game.popScene();\n        }\n    }\n\n    //% shim=pxt::setScreenBrightnessSupported\n    function setScreenBrightnessSupported() {\n        return 0 // default to no, in simulator\n    }\n\n    export function buildOptionList(): MenuOption[] {\n        let options: MenuOption[] = [];\n\n        options.push(new MenuOption(VOLUME_DOWN_ICON, () => `VOLUME DOWN (${music.volume()})`, volumeDown));\n        options.push(new MenuOption(VOLUME_UP_ICON, () => `VOLUME UP (${music.volume()})`, volumeUp));\n        if (setScreenBrightnessSupported()) {\n            options.push(new MenuOption(BRIGHTNESS_DOWN_ICON, () => `BRIGHTNESS DOWN (${screen.brightness()})`, brightnessDown));\n            options.push(new MenuOption(BRIGHTNESS_UP_ICON, () => `BRIGHTNESS UP (${screen.brightness()})`, brightnessUp));\n        }\n        options.push(new MenuOption(STATS_ICON, () => game.stats ? \"HIDE STATS\" : \"SHOW STATS\", toggleStats));\n        options.push(new MenuOption(CONSOLE_ICON, () => game.consoleOverlay.isVisible() ? \"HIDE CONSOLE\" : \"SHOW CONSOLE\", toggleConsole));\n        options.push(new MenuOption(SLEEP_ICON, () => \"SLEEP\", sleep));\n\n        if (customMenuOptions) {\n            options = options.concat(customMenuOptions);\n        }\n\n        options.push(new MenuOption(CLOSE_MENU_ICON, () => \"CLOSE\", closeMenu));\n\n        return options;\n    }\n\n    export function buildMenuTheme(cardWidth: number, cardSpacing: number, infoFont?: image.Font, headerFont?: image.Font): MenuTheme {\n        const cardsPerRow = Math.idiv(screen.width, cardWidth + cardSpacing);\n        infoFont = infoFont || image.font8;\n        headerFont = headerFont || image.doubledFont(infoFont);\n\n        return {\n            cardSpacing: cardSpacing,\n            cardWidth: cardWidth,\n            cardsPerRow: cardsPerRow,\n            padding: (screen.width - (cardsPerRow * cardWidth + (cardsPerRow - 1) * cardSpacing)) >> 1,\n            infoFont: infoFont,\n            headerFont: headerFont,\n            cardsTop: headerFont.charHeight + 2 + cardSpacing,\n            infoTop: screen.height - infoFont.charHeight - 2,\n            headerText: \"PAUSED\",\n            selectedCard: CARD_SELECTED,\n            activeCard: CARD_ACTIVE,\n            basicCard: CARD_NORMAL\n        };\n    }\n\n    export function addEntry(name: () => string, clickHandler: () => void, icon: Image) {\n        if (!customMenuOptions) customMenuOptions = [];\n        customMenuOptions.push(new MenuOption(icon, name, clickHandler));\n    }\n\n    export function register() {\n        if (instance) return; // don't show system menu, while in system menu\n\n        controller.menu.onEvent(ControllerButtonEvent.Pressed, showSystemMenu);\n    }\n\n    export function showSystemMenu() {\n        if (instance) return;\n        game.pushScene();\n        instance = new PauseMenu(buildOptionList);\n        instance.show();\n    }\n\n    export function isVisible() {\n        return !!instance;\n    }\n\n    function initVolume() {\n        const vol = settings.readNumber(\"#volume\")\n        if (vol !== undefined)\n            music.setVolume(vol)\n    }\n\n    function initScreen() {\n        const brightness = settings.readNumber(\"#brightness\");\n        if (brightness !== undefined)\n            screen.setBrightness(brightness)\n    }\n\n    initVolume()\n    initScreen()\n    scene.Scene.initializers.push(register);\n}\n","systemmenuicons.ts":"namespace scene.systemMenu {\n    export const CARD_NORMAL = img`\n        . . 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 . .\n        . 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 .\n        1 1 3 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 3 1 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 3 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 3 1\n        1 1 3 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 3 1 1\n        . 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 .\n        . . 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 . .\n    `;\n    export const CARD_SELECTED = img`\n        . . 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 . .\n        . 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 .\n        2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2\n        2 3 2 2 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 2 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 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 2 3 2\n        2 3 2 2 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 2 2 3 2\n        2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2\n        . 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 .\n        . . 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 . .\n    `;\n    export const CARD_ACTIVE = img`\n        . . 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 . .\n        . 4 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 .\n        4 4 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 3 4 4\n        4 3 4 4 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 4 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 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 4 3 4\n        4 3 4 4 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 4 4 3 4\n        4 4 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 3 4 4\n        . 4 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 .\n        . . 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 . .\n    `;\n    export const VOLUME_UP_ICON = img`\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . c c c b b . . . . . . . . . 6 6 7 . . . . .\n        . . . . . . . . . c b 1 1 d b b . . . . . . . . 6 6 6 6 . . . .\n        . . . . . . . . c d 1 d c b d b . . . . . 6 7 . . 6 6 6 7 . . .\n        . . . . . c c c b 1 d c c c b d b . . . . 6 6 6 . 7 6 6 6 . . .\n        . . c c c c b c 1 1 b c c c c d b . . . . 7 6 6 7 . 6 6 6 7 . .\n        . c b d c b 1 b 1 1 c c c c c b c . d 7 . . 6 6 6 . 7 6 6 6 . .\n        . c d b b 1 1 b 1 d c d b c c b c . 7 6 7 . 7 6 6 . 7 6 6 6 . .\n        . f d b b d 1 b d d b d d c c b c . . 6 6 . 7 6 6 . 7 6 6 6 . .\n        . f d b b d d b d d b d b c f b c . . 6 6 . 7 6 6 . 7 6 6 6 . .\n        . f d b b b d b d d f b c f f b c . 7 6 7 . 7 6 6 . 7 6 6 6 . .\n        . f b d c b b b d d f f f f f b c . d 7 . . 6 6 6 . 7 6 6 6 . .\n        . . f f f f b c d d c f f f c d b . . . . 7 6 6 7 . 6 6 6 7 . .\n        . . . . . f f f b 1 d f f f b d b . . . . 6 6 6 . 7 6 6 6 . . .\n        . . . . . . . . c d 1 d c b d b . . . . . 6 7 . . 6 6 6 7 . . .\n        . . . . . . . . . c b 1 1 d b b . . . . . . . . 6 6 6 6 . . . .\n        . . . . . . . . . . c c c c b . . . . . . . . . 6 6 7 . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n    `;\n    export const BRIGHTNESS_DOWN_ICON = img`\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . b b b . . . . . . . . . . . . . .\n        . . . . . . . . . . . b . . . 4 5 4 . . . b . . . . . . . . . .\n        . . . . . . . . . . b 5 4 . . . 4 . . . 4 5 b . . . . . . . . .\n        . . . . . . . . . b 5 5 4 . . . . . . . 4 5 5 b . . . . . . . .\n        . . . . . . . . . . b 4 . . . 4 4 4 . . . 4 4 . . . . . . . . .\n        . . . . . . . . . . . . . 4 4 5 5 5 4 4 . . . . . . . . . . . .\n        . . . . . . . . . . . . . 4 5 5 1 1 5 4 . . . . . . . . . . . .\n        . . . . . . . . b 4 . . 4 d 5 5 1 1 5 d 4 . . 4 b . . . . . . .\n        . . . . . . . . b 5 4 . b d d 5 5 5 d d b . 4 5 b . . . . . . .\n        . . . . . . . . b 4 . . b d d d d d d d b . . 4 b . . . . . . .\n        . . . . . . . . . . . . . b d d d d d b . . . . . . . . . . . .\n        . . . . . . . . . . . . . b b d d d b b . . . . . . . . . . . .\n        . . . . . . . . . . 4 4 . . . b b b . . . 4 4 . . . . . . . . .\n        . . . . . . . . . b 5 5 4 . . . . . . . 4 5 5 b . . . . . . . .\n        . . . . . . . . . . b 5 4 . . . 4 . . . 4 5 b . . . . . . . . .\n        . . . . . . . . . . . b . . . 4 5 4 . . . b . . . . . . . . . .\n        . . . . . . . . . . . . . . . b b b . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n    `;\n    export const CLOSE_MENU_ICON = img`\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . 2 2 . . . . . . . . . . . . . . 2 2 . . . . . . .\n        . . . . . . . 2 2 2 . . . . . . . . . . . . 2 2 2 . . . . . . .\n        . . . . . . . . 2 2 2 . . . . . . . . . . 2 2 2 . . . . . . . .\n        . . . . . . . . . 2 2 2 . . . . . . . . 2 2 2 . . . . . . . . .\n        . . . . . . . . . . 2 2 2 . . . . . . 2 2 2 . . . . . . . . . .\n        . . . . . . . . . . . 2 2 2 . . . . 2 2 2 . . . . . . . . . . .\n        . . . . . . . . . . . . 2 2 2 . . 2 2 2 . . . . . . . . . . . .\n        . . . . . . . . . . . . . 2 2 2 2 2 2 . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . 2 2 2 2 . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . 2 2 2 2 . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . 2 2 2 2 2 2 . . . . . . . . . . . . .\n        . . . . . . . . . . . . 2 2 2 . . 2 2 2 . . . . . . . . . . . .\n        . . . . . . . . . . . 2 2 2 . . . . 2 2 2 . . . . . . . . . . .\n        . . . . . . . . . . 2 2 2 . . . . . . 2 2 2 . . . . . . . . . .\n        . . . . . . . . . 2 2 2 . . . . . . . . 2 2 2 . . . . . . . . .\n        . . . . . . . . 2 2 2 . . . . . . . . . . 2 2 2 . . . . . . . .\n        . . . . . . . 2 2 2 . . . . . . . . . . . . 2 2 2 . . . . . . .\n        . . . . . . . 2 2 . . . . . . . . . . . . . . 2 2 . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n    `;\n    export const VOLUME_DOWN_ICON = img`\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . c c c b b . . . . . . . . . . . .\n        . . . . . . . . . . . . . . c b 1 1 d b b . . . . . . . . . . .\n        . . . . . . . . . . . . . c d 1 d c b d b . . . . . . . . . . .\n        . . . . . . . . . . c c c b 1 d c c c b d b . . . . . . . . . .\n        . . . . . . . c c c c b c 1 1 b c c c c d b . . . . . . . . . .\n        . . . . . . c b d c b 1 b 1 1 c c c c c b c . d 7 . . . . . . .\n        . . . . . . c d b b 1 1 b 1 d c d b c c b c . 7 6 7 . . . . . .\n        . . . . . . f d b b d 1 b d d b d d c c b c . . 6 6 . . . . . .\n        . . . . . . f d b b d d b d d b d b c f b c . . 6 6 . . . . . .\n        . . . . . . f d b b b d b d d f b c f f b c . 7 6 7 . . . . . .\n        . . . . . . f b d c b b b d d f f f f f b c . d 7 . . . . . . .\n        . . . . . . . f f f f b c d d c f f f c d b . . . . . . . . . .\n        . . . . . . . . . . f f f b 1 d f f f b d b . . . . . . . . . .\n        . . . . . . . . . . . . . c d 1 d c b d b . . . . . . . . . . .\n        . . . . . . . . . . . . . . c b 1 1 d b b . . . . . . . . . . .\n        . . . . . . . . . . . . . . . c c c c b . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n    `;\n    export const SLEEP_ICON = img`\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . b b b b b b . . . . . . . . . . . . .\n        . . . . . . . . . . . b b d 5 5 5 5 d c c . . . . . . . . . . .\n        . . . . . . . . . . b d 5 5 5 b c c c c c c . . . . . . . . . .\n        . . . . . . . . . b 5 5 5 5 c c c c c c c c c . . . . . . . . .\n        . . . . . . . . b d 5 5 5 b c c c c c d c c c c . . . . . . . .\n        . . . . . . . . b 5 5 5 5 c c c c c b 5 b c c c . . . . . . . .\n        . . . . . . . b d 5 5 5 5 c c c c d 5 5 5 d c d c . . . . . . .\n        . . . . . . . b 5 5 5 5 5 c c c c b 5 5 5 b c d c . . . . . . .\n        . . . . . . . c 5 5 5 5 5 c c c c c 5 b 5 c c d c . . . . . . .\n        . . . . . . . c 5 5 5 5 5 b c c c c c c c c b d c . . . . . . .\n        . . . . . . . c d 5 5 5 5 5 c c c c c c c c d d c . . . . . . .\n        . . . . . . . c d d 5 5 5 d d b c c c c b d d d c . . . . . . .\n        . . . . . . . . c d d d d d d d d d d d d d d c . . . . . . . .\n        . . . . . . . . c d d d d d d d d d d d d d d c . . . . . . . .\n        . . . . . . . . . c 9 9 d d d d d d d d d 9 c . . . . . . . . .\n        . . . . . . . . . . b 9 9 9 d d d d d 9 9 c . . . . . . . . . .\n        . . . . . . . . . . . b b 9 9 9 9 9 9 c c . . . . . . . . . . .\n        . . . . . . . . . . . . . b b b b c c . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n    `;\n    export const CONSOLE_ICON = img`\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . b b b b b b b b b b b c c . . . . . . . . .\n        . . . . . . . . . b 1 d d d d d d d d d d 1 b c . . . . . . . .\n        . . . . . . . . b 1 1 1 1 1 1 1 1 1 1 1 1 b b c . . . . . . . .\n        . . . . . . . . b d b c c c c c c c c c b b b c . . . . . . . .\n        . . . . . . . . b d c 6 6 6 6 6 6 6 6 6 c b b c . . . . . . . .\n        . . . . . . . . b d c 6 1 6 6 6 6 6 6 6 c b b c . . . . . . . .\n        . . . . . . . . b d c 6 6 1 6 6 6 6 6 6 c b b c . . . . . . . .\n        . . . . . . . . b d c 6 6 6 1 6 6 6 6 6 c b b c . . . . . . . .\n        . . . . . . . . b d c 6 6 1 6 6 6 6 6 6 c b b c . . . . . . . .\n        . . . . . . . . b d c 6 1 6 6 6 1 1 1 6 c b b c . . . . . . . .\n        . . . . . . . . b d c 6 6 6 6 6 6 6 6 6 c b b c . . . . . . . .\n        . . . . . . . . b d c c c c c c c c c c c b b c . . . . . . . .\n        . . . . . . . . c b b b b b b b b b b b b b c . . . . . . . . .\n        . . . . . . . . . c c c c c c c c c c c c c . . . . . . . . . .\n        . . . . . . . . . . . . . c c c c c c . . . . . . . . . . . . .\n        . . . . . . . . . c c c c b b b b b b c c c c c . . . . . . . .\n        . . . . . . . . c 1 1 b 1 1 b 1 1 b 1 1 b d d c . . . . . . . .\n        . . . . . . . c d d d d d d d d d d d d d b c . . . . . . . . .\n        . . . . . . . c c c c c c c c c c c c c c c . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n    `;\n    export const BRIGHTNESS_UP_ICON = img`\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . 4 4 . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . 4 5 5 4 . . . . . . . . . . . . . .\n        . . . . . . . . 4 4 b . . . b b b b . . . b 4 4 . . . . . . . .\n        . . . . . . . 4 5 5 b . . . . . . . . . . b 5 5 4 . . . . . . .\n        . . . . . . . 4 5 b . . . . 4 4 4 4 . . . . b 5 4 . . . . . . .\n        . . . . . . . b b . . . 4 4 5 5 5 5 4 4 . . . b b . . . . . . .\n        . . . . . . . . . . . 4 d 5 5 5 5 5 5 d 4 . . . . . . . . . . .\n        . . . . . . . . . . 4 d 5 5 5 5 5 1 1 5 d 4 . . . . . . . . . .\n        . . . . . . . . . . 4 5 5 5 5 5 5 1 1 5 5 4 . . . . . . . . . .\n        . . . . . . 4 b . 4 d 5 5 5 5 5 5 5 5 5 5 d 4 . b 4 . . . . . .\n        . . . . . 4 5 b . 4 d 5 5 5 5 5 5 5 5 5 5 d 4 . b 5 4 . . . . .\n        . . . . . 4 5 b . b d 5 5 5 5 5 5 5 5 5 5 d b . b 5 4 . . . . .\n        . . . . . . 4 b . b d d 5 5 5 5 5 5 5 5 d d b . b 4 . . . . . .\n        . . . . . . . . . . b d d 5 5 5 5 5 5 d d b . . . . . . . . . .\n        . . . . . . . . . . b d d d d d d d d d d b . . . . . . . . . .\n        . . . . . . . . . . . b d d d d d d d d b . . . . . . . . . . .\n        . . . . . . . b b . . . b b d d d d b b . . . b b . . . . . . .\n        . . . . . . . 4 5 b . . . . b b b b . . . . b 5 4 . . . . . . .\n        . . . . . . . 4 5 5 b . . . . . . . . . . b 5 5 4 . . . . . . .\n        . . . . . . . . 4 4 b . . . b b b b . . . b 4 4 . . . . . . . .\n        . . . . . . . . . . . . . . 4 5 5 4 . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . 4 4 . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n    `;\n    export const STATS_ICON = img`\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . b b b b . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . b 5 5 b b . b b b b b b . . . . . . . . . . . . . .\n        . . . . . . b 5 b d c c b d d d 5 5 b b . . . . . . . . . . . .\n        . . . . . . b b d b c d d b b b b d 5 5 b . . . . . . . . . . .\n        . . . . . . b b b c d d b 1 1 1 1 1 b d 5 b . . . . . . . . . .\n        . . . . . . . . c b d b 1 1 1 1 1 1 1 d b 5 b . . . . . . . . .\n        . . . . . . . . b 5 b d 1 1 b 1 1 1 1 1 d d 5 b . . . . . . . .\n        . . . . . . . b b 5 b 1 1 1 d b 1 1 b 1 1 b 5 b . . . . . . . .\n        . . . . . . . b b 5 b 1 1 1 1 b b 1 b 9 9 1 d 5 b . . . . . . .\n        . . . . . . . b b 5 b 1 1 1 1 1 b b b 9 9 9 b 5 b . . . . . . .\n        . . . . . . . b b 5 5 d 1 1 1 9 9 b b 9 9 9 b 5 b . . . . . . .\n        . . . . . . . b d b 5 b 1 1 9 9 9 9 9 9 9 9 c 5 b . . . . . . .\n        . . . . . . . b d b 5 5 b 1 9 9 9 9 9 9 9 d b 5 b . . . . . . .\n        . . . . . . . . b d b 5 5 b 9 9 9 9 9 9 9 c 5 d . . . . . . . .\n        . . . . . . . . c d d b 5 5 b b 9 9 9 d c b 5 b . . . . . . . .\n        . . . . . . . . . c d d b 5 5 5 b c c b 5 5 b . . . . . . . . .\n        . . . . . . . . . . c b b b d 5 5 5 5 5 d b . . . . . . . . . .\n        . . . . . . . . . . . c c b b b b b b b b . . . . . . . . . . .\n        . . . . . . . . . . . . . c c c c c c . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n        . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n    `;\n}","targetoverrides.cpp":"// Overriden in target\n","targetoverrides.ts":"// Overriden in target\n","textDialogs.ts":"enum DialogLayout {\n    //% block=bottom\n    Bottom,\n    //% block=left\n    Left,\n    //% block=right\n    Right,\n    //% block=top\n    Top,\n    //% block=center\n    Center,\n    //% block=\"full screen\"\n    Full\n}\n\nnamespace game {\n    function padStr(len: number): string {\n        let str = \"\";\n        for (let i = 0; i < len; ++i) {\n            str += \" \";\n        }\n        return str;\n    }\n\n    function replaceRange(dst: string, src: string, start: number, len: number): string {\n        return dst.substr(0, start) + src.substr(0, len) + dst.substr(start + len);\n    }\n\n    function screenColor(c: number): number {\n        return screen.isMono ? 1 : c;\n    }\n\n    let dialogFrame: Image;\n    let dialogCursor: Image;\n    let dialogTextColor: number;\n    const MAX_FRAME_UNIT = 12;\n\n    export class BaseDialog {\n        image: Image;\n        frame: Image;\n        cursor: Image;\n\n        columns: number;\n        rows: number;\n        unit: number;\n\n        innerLeft: number;\n        innerTop: number;\n        cursorCount: number;\n\n        font: image.Font;\n        textColor: number;\n\n        constructor(width: number, height: number, frame?: Image, font?: image.Font, cursor?: Image) {\n            this.cursorCount = 0;\n            this.resize(width, height, frame, font, cursor);\n        }\n\n        resize(width: number, height: number, frame?: Image, font?: image.Font, cursor?: Image) {\n            this.frame = frame || dialogFrame || (dialogFrame = defaultFrame());\n            this.unit = Math.floor(this.frame.width / 3);\n            this.columns = Math.floor(width / this.unit);\n            this.rows = Math.floor(height / this.unit);\n            this.innerLeft = (width - (this.columns * this.unit)) >> 1;\n            this.innerTop = (height - (this.rows * this.unit)) >> 1;\n            this.image = image.create(width, height);\n            this.font = font || image.font8;\n            this.cursor = cursor || dialogCursor || (dialogCursor = defaultCursorImage());\n            this.textColor = dialogTextColor == undefined ? dialogTextColor = 15 : dialogTextColor;\n\n            this.drawBorder();\n            this.clearInterior();\n        }\n\n        update() {\n            this.clearInterior();\n            this.drawTextCore();\n            this.drawCursorRow();\n        }\n\n        setText(rawString: string) {\n            // implemented by subclass\n        }\n\n        drawTextCore() {\n            // Implemented by subclass\n        }\n\n        drawCursorRow() {\n            let offset = 0;\n            if (this.cursorCount > 20) {\n                offset = 1;\n            }\n\n            this.cursorCount = (this.cursorCount + 1) % 40;\n\n            this.image.drawTransparentImage(\n                this.cursor,\n                this.innerLeft + this.textAreaWidth() + this.unit + offset - this.cursor.width,\n                this.innerTop + this.unit + this.textAreaHeight() + 1 - this.cursorRowHeight()\n            )\n        }\n\n        protected drawBorder() {\n            if (this.unit == 1) {\n                this.fastFill(0, 0, 0, 1, 1)\n                this.fastFill(1, 1, 0, this.columns - 2, 1)\n                this.fastFill(2, this.columns - 1, 0, 1, 1)\n\n                this.fastFill(3, 0, 1, 1, this.rows - 2)\n                this.fastFill(5, this.columns - 1, 1, 1, this.rows - 2)\n\n                const y = this.rows - 1\n                this.fastFill(6, 0, y, 1, 1)\n                this.fastFill(7, 1, y, this.columns - 2, 1)\n                this.fastFill(8, this.columns - 1, y, 1, 1)\n\n                return\n            }\n\n            for (let c = 0; c < this.columns; c++) {\n                if (c == 0) {\n                    this.drawPartial(0, 0, 0);\n                    this.drawPartial(6, 0, this.rows - 1);\n                }\n                else if (c === this.columns - 1) {\n                    this.drawPartial(2, c, 0);\n                    this.drawPartial(8, c, this.rows - 1);\n                }\n                else {\n                    this.drawPartial(1, c, 0);\n                    this.drawPartial(7, c, this.rows - 1);\n                }\n            }\n\n            for (let r = 1; r < this.rows - 1; r++) {\n                this.drawPartial(3, 0, r);\n                this.drawPartial(5, this.columns - 1, r);\n            }\n        }\n\n        private fastFill(index: number, x: number, y: number, w: number, h: number) {\n            const color = this.frame.getPixel(index % 3, Math.idiv(index, 3))\n            this.image.fillRect(this.innerLeft + x, this.innerTop + y, w, h, color)\n        }\n\n        protected clearInterior() {\n            if (this.unit == 1)\n                return this.fastFill(4, 1, 1, this.columns - 2, this.rows - 2)\n\n            for (let d = 1; d < this.columns - 1; d++) {\n                for (let s = 1; s < this.rows - 1; s++) {\n                    this.drawPartial(4, d, s)\n                }\n            }\n        }\n\n        protected drawPartial(index: number, colTo: number, rowTo: number) {\n            const x0 = this.innerLeft + colTo * this.unit;\n            const y0 = this.innerTop + rowTo * this.unit;\n\n            const xf = (index % 3) * this.unit;\n            const yf = Math.idiv(index, 3) * this.unit;\n\n            for (let e = 0; e < this.unit; e++) {\n                for (let t = 0; t < this.unit; t++) {\n                    this.image.setPixel(\n                        x0 + e,\n                        y0 + t,\n                        this.frame.getPixel(xf + e, yf + t));\n                }\n            }\n        }\n\n        protected cursorRowHeight() {\n            return this.cursor.height + 1;\n        }\n\n        protected rowHeight() {\n            return this.font.charHeight + 1;\n        }\n\n        protected textAreaWidth() {\n            return this.image.width - ((this.innerLeft + Math.min(this.unit, MAX_FRAME_UNIT)) << 1) - 2;\n        }\n\n        protected textAreaHeight() {\n            return this.image.height - ((this.innerTop + Math.min(this.unit, MAX_FRAME_UNIT)) << 1) - 1;\n        }\n\n        protected setFont(font: image.Font) {\n            this.font = font;\n        }\n    }\n\n    export class Dialog extends BaseDialog {\n        chunks: string[][];\n        chunkIndex: number;\n\n        constructor(width: number, height: number, frame?: Image, font?: image.Font, cursor?: Image) {\n            super(width, height, frame, font, cursor);\n\n            this.chunkIndex = 0;\n        }\n\n        hasNext() {\n            if (!this.chunks || this.chunks.length === 0) return false;\n            return this.chunkIndex < this.chunks.length - 1;\n        }\n\n        hasPrev() {\n            if (!this.chunks || this.chunks.length === 0) return false;\n            return this.chunkIndex > 0;\n        }\n\n        nextPage() {\n            if (this.hasNext()) {\n                this.chunkIndex++;\n            }\n        }\n\n        prevPage() {\n            if (this.hasPrev()) {\n                this.chunkIndex--;\n            }\n        }\n\n        chunkText(str: string): string[][] {\n            const charactersPerRow = Math.floor(this.textAreaWidth() / this.font.charWidth);\n            const charactersPerCursorRow = Math.floor(charactersPerRow - (this.cursor.width / this.font.charWidth));\n            const rowsOfCharacters = Math.floor(this.textAreaHeight() / this.rowHeight());\n            const rowsWithCursor = Math.ceil(this.cursor.height / this.rowHeight());\n\n            let lineLengths: number[] = [];\n\n            for (let i = 0; i < rowsOfCharacters - rowsWithCursor; i++) lineLengths.push(charactersPerRow);\n            for (let i = 0; i < rowsWithCursor; i++) lineLengths.push(charactersPerCursorRow);\n\n            return breakIntoPages(str, lineLengths);\n        }\n\n        setText(rawString: string) {\n            this.setFont(image.getFontForText(rawString));\n            this.chunks = this.chunkText(rawString);\n            this.chunkIndex = 0;\n        }\n\n        drawTextCore() {\n            if (!this.chunks || this.chunks.length === 0) return;\n            const lines = this.chunks[this.chunkIndex];\n            const availableWidth = this.textAreaWidth();\n            const availableHeight = this.textAreaHeight();\n\n            const charactersPerRow = Math.floor(availableWidth / this.font.charWidth);\n            const rowsOfCharacters = Math.floor(availableHeight / this.rowHeight());\n\n            if (this.unit > MAX_FRAME_UNIT) this.drawBorder();\n\n            const textLeft = 1 + this.innerLeft + Math.min(this.unit, MAX_FRAME_UNIT) + ((availableWidth - charactersPerRow * this.font.charWidth) >> 1);\n            const textTop = 1 + (this.image.height >> 1) - ((lines.length * this.rowHeight()) >> 1);\n\n            for (let row = 0; row < lines.length; row++) {\n                this.image.print(\n                    lines[row],\n                    textLeft,\n                    textTop + row * this.rowHeight(),\n                    this.textColor, this.font\n                )\n            }\n        }\n    }\n\n    export class SplashDialog extends game.BaseDialog {\n        text: string;\n        subtext: string;\n\n        timer: number;\n        offset: number;\n        maxOffset: number;\n        maxSubOffset: number;\n\n        constructor(width: number, height: number) {\n            super(width, height, defaultSplashFrame())\n            this.maxOffset = -1;\n            this.maxSubOffset = -1;\n            this.textColor = 1;\n        }\n\n        private updateFont() {\n            this.setFont(image.getFontForText((this.text || \"\") + (this.subtext || \"\")));\n        }\n\n        setText(text: string) {\n            this.text = text;\n            this.updateFont();\n            this.offset = 0;\n            this.maxOffset = text.length * this.font.charWidth - screen.width + (this.unit << 1);\n            this.timer = 2;\n        }\n\n        setSubtext(sub: string) {\n            this.subtext = sub;\n            this.updateFont();\n            this.maxSubOffset = sub.length * (this.font.charWidth) - screen.width + (this.unit << 1);\n        }\n\n        drawTextCore() {\n            const scrollMax = Math.max(this.maxOffset, this.maxSubOffset);\n            if (this.timer > 0) {\n                this.timer -= game.eventContext().deltaTime;\n                if (this.timer <= 0) {\n                    if (this.offset > 0) {\n                        this.offset = 0;\n                        this.timer = 2;\n                    }\n                }\n            }\n            else {\n                this.offset++;\n                if (this.offset >= scrollMax) {\n                    this.offset = scrollMax;\n                    this.timer = 2;\n                }\n            }\n            const ytitle = 10;\n            if (this.maxOffset < 0) {\n                const left = (this.image.width >> 1) - (this.text.length * this.font.charWidth >> 1)\n                this.image.print(this.text, left, ytitle, this.textColor, this.font)\n            }\n            else {\n                this.image.print(this.text, this.unit - this.offset, ytitle, this.textColor, this.font)\n            }\n\n            if (this.subtext) {\n                const ysub = ytitle + this.font.charHeight + 2;\n                if (this.maxSubOffset < 0) {\n                    const left = (this.image.width >> 1) - (this.subtext.length * this.font.charWidth >> 1)\n                    this.image.print(this.subtext, left, ysub, this.textColor, this.font);\n                }\n                else {\n                    this.image.print(this.subtext, this.unit - (Math.min(this.offset, this.maxSubOffset)), ysub, this.textColor, this.font);\n                }\n            }\n            this.drawBorder();\n        }\n    }\n\n    const img_trophy_sm = img`\n    . . . . . . . \n    . 4 5 5 5 1 . \n    . 4 5 5 5 1 . \n    . 4 5 5 5 1 . \n    . . 4 5 1 . . \n    . . . 5 . . . \n    . . 4 5 1 . . \n    . . . . . . . \n    `;\n\n    const img_trophy_lg = img`\n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . 5 5 5 5 5 5 . . . . . \n    . . . . 5 4 4 4 4 4 4 5 . . . . \n    . . . . 5 5 5 5 5 5 5 5 . . . . \n    . . . . 4 5 5 5 5 5 5 1 . . . . \n    . . . 5 4 4 5 5 5 5 1 1 5 . . . \n    . . 5 . 4 4 5 5 5 5 1 1 . 5 . . \n    . . 5 . 4 4 5 5 5 5 1 1 . 5 . . \n    . . . 5 4 4 5 5 5 5 1 1 5 . . . \n    . . . . 4 4 5 5 5 5 1 1 . . . . \n    . . . . . 4 5 5 5 1 1 . . . . . \n    . . . . . . 4 5 1 1 . . . . . . \n    . . . . . . . 4 1 . . . . . . . \n    . . . . . 4 4 5 5 1 1 . . . . . \n    . . . . . . . . . . . . . . . . \n    `;\n\n    const img_sleepy_sim = img`\n    . . . . . . . . . . . . . . . . \n    . . . 6 6 6 6 6 6 6 6 6 6 . . . \n    . . 6 f f f f f f f f f f 6 . . \n    . . 6 f f f f f f f f f f 6 . . \n    . . 6 f f 1 1 f f 1 1 f f 6 . . \n    . . 6 f f f f f f f f f f 6 . . \n    . . 6 f f f f 1 1 f f f f 6 . . \n    . . 6 f f f f f f f f f f 6 . . \n    . . 6 6 6 6 6 6 6 6 6 6 6 6 . . \n    . . 6 6 f 6 6 6 6 6 6 6 f 6 . . \n    . . 6 f f f 6 6 6 6 6 6 6 6 . . \n    . . 6 6 f 6 6 6 6 6 f 6 6 6 . . \n    . . 6 6 6 6 6 6 6 6 6 6 6 6 . . \n    . . . 6 6 6 6 6 6 6 6 6 6 . . . \n    . . . . . . . . . . . . . . . . \n    . . . . . . . . . . . . . . . . \n    `;\n\n    export class GameOverPlayerScore {\n        public str: string;\n        constructor(\n            public player: number,\n            public value: number,\n            public winner: boolean) { }\n    }\n\n    enum GameOverDialogFlags {\n        WIN = 1,\n        HAS_BEST = 2,\n        NEW_BEST = 4,\n        MULTIPLAYER = 8,\n        HAS_SCORES = 16\n    };\n\n    export class GameOverDialog extends game.BaseDialog {\n        protected cursorOn: boolean;\n        protected flags: GameOverDialogFlags;\n        protected height: number;\n\n        get isWinCondition() { return !!(this.flags & GameOverDialogFlags.WIN); }\n        get isJudgedGame() { return this.judged; }\n        get hasScores() { return !!(this.flags & GameOverDialogFlags.HAS_SCORES); }\n        get hasBestScore() { return !!(this.flags & GameOverDialogFlags.HAS_BEST); }\n        get isNewBestScore() { return !!(this.flags & GameOverDialogFlags.NEW_BEST); }\n        get isMultiplayerGame() { return !!(this.flags & GameOverDialogFlags.MULTIPLAYER); }\n\n        constructor(\n            win: boolean,\n            protected message: string,\n            protected judged: boolean,\n            protected scores: GameOverPlayerScore[],\n            protected bestScore?: number,\n            protected winnerOverride?: number\n        ) {\n            super(screen.width, 46, defaultSplashFrame());\n            this.cursorOn = false;\n            this.flags = 0;\n\n            if (win) {\n                this.flags |= GameOverDialogFlags.WIN;\n            }\n\n            // Fixup states in case of winner override\n            if (winnerOverride) {\n                win = true;\n                this.flags |= GameOverDialogFlags.WIN;\n                // For display purposes, treat this as a multiplayer game\n                this.flags |= GameOverDialogFlags.MULTIPLAYER;\n                const score = scores.find(score => score.player === winnerOverride);\n                if (!score) {\n                    scores.push(new GameOverPlayerScore(winnerOverride, null, true));\n                    scores.sort((a, b) => a.player - b.player);\n                }\n                scores.forEach(score => score.winner = score.player === winnerOverride);\n            }\n\n            if (scores.length) {\n                // If any score present is other than player 1, this is a multiplayer game\n                scores.forEach(score => score.player > 1 && (this.flags |= GameOverDialogFlags.MULTIPLAYER));\n                if (win) {\n                    let winner = scores.find(score => score.winner);\n                    if (!winner && scores.length === 1) winner = scores[0];\n                    if (winner) {\n                        if (winner.value != null) {\n                            if (bestScore == null) {\n                                this.bestScore = winner.value;\n                                this.flags |= GameOverDialogFlags.NEW_BEST;\n                            } else if (info.isBetterScore(winner.value, bestScore)) {\n                                this.bestScore = winner.value;\n                                this.flags |= GameOverDialogFlags.NEW_BEST;\n                            }\n                        }\n                        // Replace string tokens with resolved values\n                        this.message = this.message\n                            .replaceAll(\"${WINNER}\", \"PLAYER \" + winner.player)\n                            .replaceAll(\"${Winner}\", \"Player \" + winner.player)\n                            .replaceAll(\"${winner}\", \"player \" + winner.player)\n                            .replaceAll(\"${winner_short}\", \"P\" + winner.player);\n                    }\n                }\n            }\n\n            const scoresWithValues = scores.filter(score => score.value != null);\n            if (scoresWithValues.length) this.flags |= GameOverDialogFlags.HAS_SCORES;\n\n            if (this.isWinCondition && this.isJudgedGame && this.hasScores && (this.bestScore != null)) {\n                this.flags |= GameOverDialogFlags.HAS_BEST;\n            }\n\n            // Two scores per row\n            const scoreRows = Math.max(0, scoresWithValues.length - 1) >> 1;\n            this.height = 47 + scoreRows * image.font5.charHeight;\n            this.resize(screen.width, this.height, defaultSplashFrame());\n        }\n\n        displayCursor() {\n            this.cursorOn = true;\n        }\n\n        update() {\n            this.clearInterior();\n            this.drawTextCore();\n\n            if (this.cursorOn) {\n                this.drawCursorRow();\n            }\n        }\n\n        drawMessage() {\n            const currY = 5;\n            this.image.printCenter(\n                this.message,\n                currY,\n                screenColor(5),\n                image.font8\n            );\n        }\n\n        drawScores() {\n            if (this.hasScores) {\n                const scores = this.scores.filter(score => score.value != null);\n                let currY = image.font5.charHeight + 16;\n                if (this.isMultiplayerGame) {\n                    if (scores.length === 1) {\n                        // Multiplayer special case: Only one player scored\n                        const score = scores[0];\n                        score.str = \"P\" + score.player + \":\" + score.value;\n                        this.image.printCenter(\n                            score.str,\n                            currY,\n                            screenColor(1),\n                            image.font5\n                        );\n                        if (score.winner) {\n                            // In multiplayer, the winning score gets a trophy\n                            const x = (this.image.width >> 1) - ((score.str.length * image.font5.charWidth) >> 1);\n                            this.image.drawTransparentImage(img_trophy_sm, x - img_trophy_sm.width - 3, currY - 2);\n                        }\n                    } else {\n                        // Multiplayer general case: Multiple players scored\n                        // Compute max score width\n                        const strlens = [0, 0];\n                        for (let i = 0; i < scores.length; ++i) {\n                            const col = i % 2;\n                            const score = scores[i];\n                            score.str = \"P\" + score.player + \":\" + score.value;\n                            strlens[col] = Math.max(strlens[col], score.str.length);\n                        }\n                        // Print scores in a grid, two per row\n                        for (let i = 0; i < scores.length; ++i) {\n                            const col = i % 2;\n                            const score = scores[i];\n                            let str = padStr(strlens[col]);\n                            str = replaceRange(str, score.str, 0, score.str.length);\n                            let x = 0;\n                            if (col === 0) {\n                                x = (this.image.width >> 1) - strlens[col] * image.font5.charWidth - 3;\n                            } else {\n                                x = (this.image.width >> 1) + 3;\n                            }\n                            if (score.winner) {\n                                // In multiplayer, the winning score gets a trophy\n                                if (i % 2 === 0) {\n                                    this.image.drawTransparentImage(img_trophy_sm, x - img_trophy_sm.width - 3, currY - 2);\n                                } else {\n                                    this.image.drawTransparentImage(img_trophy_sm, x + score.str.length * image.font5.charWidth + 2, currY - 2);\n                                }\n                            }\n                            this.image.print(\n                                str,\n                                x,\n                                currY,\n                                screenColor(1),\n                                image.font5\n                            );\n                            if (i % 2 === 1) {\n                                currY += image.font5.charHeight + 2;\n                            }\n                        }\n                    }\n                } else {\n                    // Single player case\n                    const score = scores[0];\n                    score.str = \"Score:\" + score.value;\n                    this.image.printCenter(\n                        score.str,\n                        currY - 1,\n                        screenColor(1),\n                        image.font8 // Single player score gets a bigger font\n                    );\n                }\n            } else if (this.isWinCondition) {\n                // No score, but there is a win condition. Show a trophy.\n                let currY = image.font5.charHeight + 14;\n                this.image.drawTransparentImage(img_trophy_lg, (this.image.width >> 1) - (img_trophy_lg.width >> 1), currY);\n            } else {\n                // No score, no win, show a generic game over icon (sleepy sim)\n                let currY = image.font5.charHeight + 14;\n                this.image.drawTransparentImage(img_sleepy_sim, (this.image.width >> 1) - (img_sleepy_sim.width >> 1), currY);\n            }\n        }\n\n        drawBestScore() {\n            if (this.hasBestScore) {\n                const currY = this.height - image.font8.charHeight - 5;\n                if (this.isNewBestScore) {\n                    const label = \"New Best Score!\";\n                    this.image.printCenter(\n                        label,\n                        currY,\n                        screenColor(9),\n                        image.font8\n                    );\n                    // In single player draw trophy icons on either side of the label.\n                    // In multiplayer a trophy icon is drawn next to the winning score instead.\n                    if (!this.isMultiplayerGame) {\n                        const halfWidth = (label.length * image.font8.charWidth) >> 1;\n                        this.image.drawTransparentImage(img_trophy_sm, (this.image.width >> 1) - halfWidth - img_trophy_sm.width - 2, currY);\n                        this.image.drawTransparentImage(img_trophy_sm, (this.image.width >> 1) + halfWidth, currY);\n                    }\n                } else {\n                    this.image.printCenter(\n                        \"Best:\" + this.bestScore,\n                        currY,\n                        screenColor(9),\n                        image.font8\n                    );\n                }\n            }\n        }\n\n        drawTextCore() {\n            this.drawMessage();\n            this.drawScores();\n            this.drawBestScore();\n        }\n    }\n\n    /**\n     * Show a long text string in a dialog box that will scroll\n     * using the \"A\" or \"down\" buttons. The previous section of the\n     * text is shown using the \"up\" button. This function\n     * halts execution until the last page of text is dismissed.\n     *\n     * @param str The text to display\n     * @param layout The layout to use for the dialog box\n     */\n    //% blockId=game_show_long_text group=\"Dialogs\"\n    //% block=\"show long text %str %layout\"\n    //% str.shadow=text\n    //% help=game/show-long-text\n    export function showLongText(str: any, layout: DialogLayout) {\n        str = console.inspect(str);\n        controller._setUserEventsEnabled(false);\n        game.pushScene();\n        game.currentScene().flags |= scene.Flag.SeeThrough;\n\n        let width: number;\n        let height: number;\n        let top: number;\n        let left: number;\n\n        switch (layout) {\n            case DialogLayout.Bottom:\n                width = screen.width - 4;\n                height = Math.idiv(screen.height, 3) + 5;\n                top = screen.height - height;\n                left = screen.width - width >> 1;\n                break;\n            case DialogLayout.Top:\n                width = screen.width - 4;\n                height = Math.idiv(screen.height, 3) + 5;\n                top = 0;\n                left = screen.width - width >> 1;\n                break;\n            case DialogLayout.Left:\n                width = Math.idiv(screen.width, 3) + 5;\n                height = screen.height;\n                top = 0;\n                left = 0;\n                break;\n            case DialogLayout.Right:\n                width = Math.idiv(screen.width, 3) + 5;\n                height = screen.height;\n                top = 0;\n                left = screen.width - width;\n                break;\n            case DialogLayout.Center:\n                width = Math.idiv(screen.width << 1, 3);\n                height = Math.idiv(screen.width << 1, 3);\n                top = (screen.height - height) >> 1;\n                left = (screen.width - width) >> 1;\n                break;\n            case DialogLayout.Full:\n                width = screen.width;\n                height = screen.height;\n                top = 0;\n                left = 0;\n                break;\n        }\n\n        const dialog = new Dialog(width, height);\n        const s = sprites.create(dialog.image, -1);\n        s.top = top;\n        s.left = left;\n\n        dialog.setText(str)\n        let pressed = true;\n        let done = false;\n\n        let upPressed = true;\n\n        game.onUpdate(() => {\n            dialog.update();\n            const currentState = controller.A.isPressed() || controller.down.isPressed();\n            if (currentState && !pressed) {\n                pressed = true;\n                if (dialog.hasNext()) {\n                    dialog.nextPage();\n                }\n                else {\n                    scene.setBackgroundImage(null); // GC it\n                    game.popScene();\n                    done = true;\n                }\n            }\n            else if (pressed && !currentState) {\n                pressed = false;\n            }\n\n            const moveBack = controller.up.isPressed();\n            if (moveBack && !upPressed) {\n                upPressed = true;\n                if (dialog.hasPrev()) {\n                    dialog.prevPage();\n                }\n            }\n            else if (upPressed && !moveBack) {\n                upPressed = false;\n            }\n        })\n\n        pauseUntil(() => done);\n        controller._setUserEventsEnabled(true);\n    }\n\n    function defaultFrame() {\n        return screen.isMono ?\n            img`\n        1 1 1\n        1 . 1\n        1 1 1\n        `\n            :\n            img`\n        . . . . . . . . . . . .\n        . b b b b b b b b b b .\n        . b b b b b b b b b b c\n        . b b d 1 1 1 1 d b b c\n        . b b 1 1 1 1 1 1 b b c\n        . b b 1 1 1 1 1 1 b b c\n        . b b 1 1 1 1 1 1 b b c\n        . b b 1 1 1 1 1 1 b b c\n        . b b d 1 1 1 1 d b b c\n        . b b b b b b b b b b c\n        . b b b b b b b b b b c\n        . . c c c c c c c c c c\n        `\n    }\n\n    function defaultSplashFrame() {\n        return screen.isMono ?\n            img`\n        1 1 1\n        . . .\n        1 1 1\n        `\n            :\n            img`\n        1 1 1\n        f f f\n        1 1 1\n        `\n    }\n\n    function defaultCursorImage() {\n        return screen.isMono ?\n            img`\n        1 1 1 1 1 1 1 . . .\n        1 . . 1 . . . 1 . .\n        1 . 1 . 1 . . . 1 .\n        1 . 1 1 1 . . . . 1\n        1 . 1 . 1 . . . 1 .\n        1 . . . . . . 1 . .\n        1 1 1 1 1 1 1 . . .\n        . . . . . . . . . .\n        `\n            :\n            img`\n        0 0 0 6 6 6 6 6 0 0 0\n        0 6 6 7 7 7 7 7 6 6 0\n        0 6 7 7 1 1 1 7 7 6 0\n        6 7 7 1 7 7 7 1 7 7 6\n        6 7 7 1 7 7 7 1 7 7 6\n        6 7 7 1 1 1 1 1 7 7 6\n        6 6 7 1 7 7 7 1 7 6 6\n        8 6 6 1 7 7 7 1 6 6 8\n        8 6 6 7 6 6 6 7 6 6 8\n        0 8 6 6 6 6 6 6 6 8 0\n        0 0 8 8 8 8 8 8 8 0 0\n        `\n    }\n\n    /**\n     * Change the default dialog frame to a new image. Dialog frames\n     * are divided into three rows and three columns and are used to define\n     * the outer frame of the dialog box.\n     *\n     * @param frame A square image with a width and height divisible by three\n     */\n    //% blockId=game_dialog_set_frame group=\"Dialogs\"\n    //% block=\"set dialog frame to %frame=dialog_image_picker\"\n    //% help=game/set-dialog-frame\n    export function setDialogFrame(frame: Image) {\n        dialogFrame = frame;\n    }\n\n    /**\n     * Change the default image used for the cursor that appears in the\n     * bottom left of the dialog box.\n     *\n     * @param cursor The image to use for the cursor\n     */\n    //% blockId=game_dialog_set_cursor group=\"Dialogs\"\n    //% block=\"set dialog cursor to %frame=screen_image_picker\"\n    //% help=game/set-dialog-cursor\n    export function setDialogCursor(cursor: Image) {\n        dialogCursor = cursor;\n    }\n\n    /**\n     * Change the color for the text in dialog boxes.\n     *\n     * @param color The index of the color 0-15\n     */\n    //% blockId=game_dialog_set_text_color group=\"Dialogs\"\n    //% block=\"set dialog text color to %color=colorindexpicker\"\n    //% help=game/set-dialog-text-color\n    export function setDialogTextColor(color: number) {\n        dialogTextColor = Math.floor(Math.min(15, Math.max(0, color)));\n    }\n\n    // this function is deprecated\n    //% deprecated blockHidden\n    export function setDialogFont(font: image.Font) {\n    }\n\n    /**\n     * Show a title and an optional subtitle menu\n     * @param title\n     * @param subtitle\n     */\n    //% weight=90 help=game/splash\n    //% blockId=gameSplash block=\"splash %title||%subtitle\"\n    //% title.shadow=text\n    //% subtitle.shadow=text\n    //% group=\"Prompt\"\n    export function splash(title: any, subtitle?: any) {\n        title = console.inspect(title);\n        subtitle = subtitle ? console.inspect(subtitle) : subtitle;\n        controller._setUserEventsEnabled(false);\n        game.pushScene();\n        game.currentScene().flags |= scene.Flag.SeeThrough;\n\n        const dialog = new SplashDialog(screen.width, subtitle ? 42 : 35);\n        dialog.setText(title);\n        if (subtitle) dialog.setSubtext(subtitle);\n\n        const s = sprites.create(dialog.image, -1);\n        let pressed = true;\n        let done = false;\n\n        game.onUpdate(() => {\n            dialog.update();\n            const currentState = controller.A.isPressed();\n            if (currentState && !pressed) {\n                pressed = true;\n                scene.setBackgroundImage(null); // GC it\n                game.popScene();\n                done = true;\n            }\n            else if (pressed && !currentState) {\n                pressed = false;\n            }\n        })\n\n        pauseUntil(() => done);\n        controller._setUserEventsEnabled(true);\n    }\n\n    function isBreakCharacter(charCode: number) {\n        return charCode <= 32 ||\n            (charCode >= 58 && charCode <= 64) ||\n            (charCode >= 91 && charCode <= 96) ||\n            (charCode >= 123 && charCode <= 126) || \n            (charCode >= 19968 && charCode <= 40869) ||\n            charCode == 12290 || \n            charCode == 65292;\n    }\n\n    function breakIntoPages(text: string, lineLengths: number[]): string[][] {\n        const result: string[][] = [];\n\n        let currentPage: string[] = [];\n\n        let lastBreakLocation = 0;\n        let lastBreak = 0;\n        let line = 0;\n        let lineLength = lineLengths[line];\n\n        function nextLine() {\n            line++;\n            lineLength = lineLengths[line];\n        }\n\n        for (let index = 0; index < text.length; index++) {\n            if (text.charAt(index) === \"\\n\") {\n                currentPage.push(formatLine(text.substr(lastBreak, index - lastBreak)));\n                index++;\n                lastBreak = index;\n                nextLine();\n            }\n            // Handle \\\\n in addition to \\n because that's how it gets converted from blocks\n            else if (text.charAt(index) === \"\\\\\" && text.charAt(index + 1) === \"n\") {\n                currentPage.push(formatLine(text.substr(lastBreak, index - lastBreak)));\n                index += 2;\n                lastBreak = index\n                nextLine();\n            }\n            else if (isBreakCharacter(text.charCodeAt(index))) {\n                lastBreakLocation = index;\n            }\n\n            if (index - lastBreak === lineLength) {\n                if (lastBreakLocation === index || lastBreakLocation < lastBreak) {\n                    currentPage.push(formatLine(text.substr(lastBreak, lineLength)));\n                    lastBreak = index;\n                    nextLine();\n                }\n                else {\n                    currentPage.push(formatLine(text.substr(lastBreak, lastBreakLocation - lastBreak)));\n                    lastBreak = lastBreakLocation;\n                    nextLine();\n                }\n            }\n\n            if (line >= lineLengths.length) {\n                line = 0;\n                lineLength = lineLengths[line];\n                result.push(currentPage);\n                currentPage = [];\n            }\n        }\n\n        currentPage.push(formatLine(text.substr(lastBreak, text.length - lastBreak)));\n\n        if (currentPage.length > 1 || currentPage[0] !== \"\") {\n            result.push(currentPage);\n        }\n\n        return result;\n    }\n\n    function formatLine(text: string) {\n        let i = 0;\n        while (text.charAt(i) === \" \") i++;\n        return text.substr(i, text.length);\n    }\n}\n\n","texteffects.ts":"namespace texteffects {\n    export enum TextEffectKind {\n        //% block=none\n        None,\n        //% block=shake\n        Shake,\n        //% block=wave\n        Wave\n    }\n\n    export function getTextEffect(e: TextEffectKind) {\n        switch (e) {\n            case texteffects.TextEffectKind.Wave:\n                return texteffects.wave;\n            case texteffects.TextEffectKind.Shake:\n                return texteffects.shake;\n            default:\n                return null;\n        }\n    }\n \n    //% fixedInstances\n    export class TextEffect {\n        public getState: (index?: number, state?: TextEffectState) => TextEffectState;\n    \n        constructor(getState: (index?: number, state?: TextEffectState) => TextEffectState) {\n            this.getState = getState;\n        }\n    }\n\n    //% fixedInstance whenUsed\n    export const shake = new TextEffect(() => { \n        return { xOffset: (Math.random() * 2 - 1),\n                 yOffset: (Math.random() * 2 - 1) }\n    });\n\n\n    interface WaveEffectState extends TextEffectState {\n        up: boolean;\n    }\n\n    //% fixedInstance whenUsed\n    export const wave = new TextEffect((index?: number, state?: WaveEffectState) => {  // TODO cast state type\n        if (!state) {\n            state = {\n                xOffset: 0,\n                yOffset: Math.sin(index) * 2,\n                up: Math.sign(Math.sin(index)) < 0\n            };\n        }\n\n        state.yOffset += (state.up ? 1 : -1) * 0.5;\n        state.up = Math.abs(state.yOffset) > 2 ? !state.up : state.up;\n\n        return state\n    });\n\n    /**\n     * A text sprite on the screen\n     **/\n    export class TextSprite {\n        _str: string\n        _font: image.Font\n        _color: number;\n        _effect: TextEffect\n        _state: TextEffectState[]; // per-character state initialized and used by the effect\n\n        get color(): number {\n            return this._color;\n        }\n\n        get state(): TextEffectState[] {\n            return this._state;\n        }\n\n        constructor(str: string, font: image.Font, color: number, effect?: TextEffect) {\n            this._str = str;\n            this._font = font;\n            this._color = color;\n            this._effect = effect;\n            this._state = [];\n        }\n\n        updateState() {\n            if (!this._effect) return;\n    \n            let i = 0;\n            while (i < this._str.length) {\n                this._state[i] = this._effect.getState(i, (i < this._state.length ? this._state[i] : null));\n                i++;\n            }\n        }\n\n        draw(image: Image, x: number, y: number, start?: number, length?: number): void {\n            this.updateState();\n\n            let s = this._str.substr(Math.max(start, 0), Math.min(length, this._str.length - start));\n            image.print(s, x, y, this._color, this._font, this._state);\n        }\n    }\n}","tilemap.ts":"enum TileScale {\n    //% block=\"4x4\"\n    Four = 2,\n    //% block=\"8x8\"\n    Eight = 3,\n    //% block=\"16x16\"\n    Sixteen = 4,\n    //% block=\"32x32\"\n    ThirtyTwo = 5\n}\n\nnamespace tiles {\n\n    /**\n     * A (col, row) location in the tilemap\n     **/\n    //% blockNamespace=scene color=\"#401255\"\n    export class Location {\n        protected _row: number;\n        protected _col: number;\n\n        constructor(col: number, row: number, map: TileMap) {\n            this._col = col;\n            this._row = row;\n        }\n\n        get tileMap() {\n            return game.currentScene().tileMap;\n        }\n\n        //% group=\"Locations\" blockSetVariable=\"location\"\n        //% blockCombine block=\"column\"\n        //% weight=100\n        get column() {\n            return this._col;\n        }\n\n        //% group=\"Locations\" blockSetVariable=\"location\"\n        //% blockCombine block=\"row\"\n        //% weight=100\n        get row() {\n            return this._row;\n        }\n\n        //% group=\"Locations\" blockSetVariable=\"location\"\n        //% blockCombine block=\"x\"\n        //% weight=100\n        get x(): number {\n            const scale = this.tileMap.scale;\n            return (this._col << scale) + (1 << (scale - 1));\n        }\n\n        //% group=\"Locations\" blockSetVariable=\"location\"\n        //% blockCombine block=\"y\"\n        //% weight=100\n        get y(): number {\n            const scale = this.tileMap.scale;\n            return (this._row << scale) + (1 << (scale - 1));\n        }\n\n        //% group=\"Locations\" blockSetVariable=\"location\"\n        //% blockCombine block=\"left\"\n        //% weight=100\n        get left(): number {\n            return (this._col << this.tileMap.scale);\n        }\n\n        //% group=\"Locations\" blockSetVariable=\"location\"\n        //% blockCombine block=\"top\"\n        //% weight=100\n        get top(): number {\n            return (this._row << this.tileMap.scale);\n        }\n\n        //% group=\"Locations\" blockSetVariable=\"location\"\n        //% blockCombine block=\"right\"\n        //% weight=100\n        get right(): number {\n            return this.left + (1 << this.tileMap.scale);\n        }\n\n        //% group=\"Locations\" blockSetVariable=\"location\"\n        //% blockCombine block=\"bottom\"\n        //% weight=100\n        get bottom(): number {\n            return this.top + (1 << this.tileMap.scale);\n        }\n\n        get tileSet(): number {\n            return this.tileMap.getTileIndex(this._col, this._row);\n        }\n\n        // deprecated\n        get col() {\n            return this.column;\n        }\n\n        public isWall(): boolean {\n            return this.tileMap.isObstacle(this._col, this._row);\n        }\n\n        public getImage(): Image {\n            return this.tileMap.getTileImage(this.tileSet);\n        }\n\n        /**\n         * Returns the neighboring location in a specifc direction from a location in a tilemap\n         * @param direction The direction to fetch the location in\n         */\n        //% blockId=tiles_location_get_neighboring_location\n        //% block=\"tilemap location $direction of $this\"\n        //% this.defl=location\n        //% this.shadow=variables_get\n        //% group=\"Locations\" blockGap=8\n        //% weight=10 help=tiles/get-neighboring-location\n        public getNeighboringLocation(direction: CollisionDirection): Location {\n            switch (direction) {\n                case CollisionDirection.Top:\n                    return this.tileMap.getTile(this._col, this._row - 1);\n                case CollisionDirection.Right:\n                    return this.tileMap.getTile(this._col + 1, this._row);\n                case CollisionDirection.Bottom:\n                    return this.tileMap.getTile(this._col, this._row + 1);\n                case CollisionDirection.Left:\n                    return this.tileMap.getTile(this._col - 1, this._row);\n            }\n        }\n\n        /**\n         * Center the given sprite on this tile\n         * @param sprite\n         */\n        place(mySprite: Sprite): void {\n            if (!mySprite) return;\n            mySprite.setPosition(this.x, this.y);\n        }\n\n        // ## LEGACY: DO NOT USE ##\n        _toTile(): Tile {\n            return new Tile(this._col, this._row, this.tileMap);\n        }\n    }\n\n    /**\n     * DEPRECATED: a tile in the tilemap\n     **/\n    //% blockNamespace=scene color=\"#401255\" blockGap=8\n    export class Tile {\n        protected _row: number;\n        protected _col: number;\n        protected tileMap: TileMap;\n\n        constructor(col: number, row: number, map: TileMap) {\n            this._col = col;\n            this._row = row;\n            this.tileMap = map;\n        }\n\n        get x(): number {\n            const scale = this.tileMap.scale;\n            return (this._col << scale) + (1 << (scale - 1));\n        }\n\n        get y(): number {\n            const scale = this.tileMap.scale;\n            return (this._row << scale) + (1 << (scale - 1));\n        }\n\n        get tileSet(): number {\n            return this.tileMap.getTileIndex(this._col, this._row);\n        }\n\n        /**\n         * Center the given sprite on this tile\n         * @param sprite\n         */\n        //% blockId=gameplaceontile block=\"on top of %tile(myTile) place %sprite=variables_get(mySprite)\"\n        //% blockNamespace=\"scene\" group=\"Tilemap Operations\"\n        //% weight=25\n        //% help=tiles/place\n        //% deprecated=1\n        place(mySprite: Sprite): void {\n            if (!mySprite) return;\n            mySprite.setPosition(this.x, this.y);\n        }\n    }\n\n    const TM_DATA_PREFIX_LENGTH = 4;\n    const TM_WALL = 2;\n\n    //% snippet='tilemap` `'\n    //% pySnippet='tilemap(\"\"\" \"\"\")'\n    export class TileMapData {\n        // The tile data for the map (indices into tileset)\n        protected data: Buffer;\n\n        // The metadata layers for the map. Currently only 1 is used for walls\n        protected layers: Image;\n\n        protected tileset: Image[];\n        protected cachedTileView: Image[];\n\n        protected _scale: TileScale;\n        protected _width: number;\n        protected _height: number;\n\n        constructor(data: Buffer, layers: Image, tileset: Image[], scale: TileScale) {\n            this.data = data;\n            this.layers = layers;\n            this.tileset = tileset;\n            this.scale = scale;\n\n            this._width = data.getNumber(NumberFormat.UInt16LE, 0);\n            this._height = data.getNumber(NumberFormat.UInt16LE, 2);\n        }\n\n        get width(): number {\n            return this._width;\n        }\n\n        get height(): number {\n            return this._height;\n        }\n\n        get scale(): TileScale {\n            return this._scale;\n        }\n\n        set scale(s: TileScale) {\n            this._scale = s;\n            this.cachedTileView = [];\n        }\n\n        getTile(col: number, row: number) {\n            if (this.isOutsideMap(col, row)) return 0;\n\n            return this.data.getUint8(TM_DATA_PREFIX_LENGTH + (col | 0) + (row | 0) * this.width);\n        }\n\n        setTile(col: number, row: number, tile: number) {\n            if (this.isOutsideMap(col, row)) return;\n\n            if (this.data.isReadOnly()) {\n                this.data = this.data.slice();\n            }\n\n            this.data.setUint8(TM_DATA_PREFIX_LENGTH + (col | 0) + (row | 0) * this.width, tile);\n        }\n\n        getTileset() {\n            return this.tileset;\n        }\n\n        getTileImage(index: number) {\n            const size = 1 << this.scale;\n            let cachedImage = this.cachedTileView[index];\n            if (!cachedImage) {\n                const originalImage = this.tileset[index];\n\n                if (originalImage) {\n                    if (originalImage.width <= size && originalImage.height <= size) {\n                        cachedImage = originalImage;\n                    } else {\n                        cachedImage = image.create(size, size);\n                        cachedImage.drawImage(originalImage, 0, 0);\n                    }\n                    this.cachedTileView[index] = cachedImage;\n                }\n            }\n            return cachedImage;\n        }\n\n        setWall(col: number, row: number, on: boolean) {\n            return this.layers.setPixel(col, row, on ? TM_WALL : 0);\n        }\n\n        isWall(col: number, row: number) {\n            return this.layers.getPixel(col, row) === TM_WALL;\n        }\n\n        isOutsideMap(col: number, row: number) {\n            return col < 0 || col >= this.width || row < 0 || row >= this.height;\n        }\n    }\n\n    export enum TileMapEvent {\n        Loaded,\n        Unloaded\n    }\n\n    export class TileMapEventHandler {\n        constructor(public event: TileMapEvent, public callback: (data: TileMapData) => void) {}\n    }\n\n    export class TileMap {\n        protected _scale: TileScale;\n\n        protected _layer: number;\n        protected _map: TileMapData;\n        renderable: scene.Renderable;\n        protected handlerState: TileMapEventHandler[];\n\n        constructor(scale: TileScale = TileScale.Sixteen) {\n            this._layer = 1;\n            this.scale = scale;\n\n            this.renderable = scene.createRenderable(\n                scene.TILE_MAP_Z,\n                (t, c) => this.draw(t, c)\n            );\n        }\n\n        get scale() {\n            return this._scale;\n        }\n\n        set scale(s: TileScale) {\n            this._scale = s;\n            if (this._map) {\n                this._map.scale = s;\n            }\n        }\n\n        get data(): TileMapData {\n            return this._map;\n        }\n\n        offsetX(value: number) {\n            return Math.clamp(0, Math.max(this.areaWidth() - screen.width, 0), value);\n        }\n\n        offsetY(value: number) {\n            return Math.clamp(0, Math.max(this.areaHeight() - screen.height, 0), value);\n        }\n\n        areaWidth() {\n            return this._map ? (this._map.width << this.scale) : 0;\n        }\n\n        areaHeight() {\n            return this._map ? (this._map.height << this.scale) : 0;\n        }\n\n        get layer(): number {\n            return this._layer;\n        }\n\n        set layer(value: number) {\n            if (this._layer != value) {\n                this._layer = value;\n            }\n        }\n\n        get enabled(): boolean {\n            return !!this._map;\n        }\n\n        setData(map: TileMapData) {\n            const previous = this._map;\n\n            if (this.handlerState && previous !== map && previous) {\n                for (const eventHandler of this.handlerState) {\n                    if (eventHandler.event === TileMapEvent.Unloaded) {\n                        eventHandler.callback(previous);\n                    }\n                }\n            }\n\n            this._map = map;\n            if (map) {\n                this._scale = map.scale;\n            }\n\n            if (this.handlerState && previous !== map && map) {\n                for (const eventHandler of this.handlerState) {\n                    if (eventHandler.event === TileMapEvent.Loaded) {\n                        eventHandler.callback(map);\n                    }\n                }\n            }\n        }\n\n        public getTile(col: number, row: number): Location {\n            return new Location(col, row, this);\n        }\n\n        public getTileIndex(col: number, row: number) {\n            return this.data.getTile(col, row);\n        }\n\n        public setTileAt(col: number, row: number, index: number): void {\n            if (!this._map.isOutsideMap(col, row) && !this.isInvalidIndex(index))\n                this._map.setTile(col, row, index);\n        }\n\n        public getImageType(im: Image): number {\n            const tileset = this._map.getTileset();\n            for (let i = 0; i < tileset.length; i++)\n                if (tileset[i].equals(im)) return i;\n\n            // not found; append to the tileset if there are spots left.\n            const newIndex = tileset.length;\n            if (!this.isInvalidIndex(newIndex)) {\n                tileset.push(im);\n                return newIndex;\n            }\n\n            return -1;\n        }\n\n        public setWallAt(col: number, row: number, on: boolean): void {\n            if (!this._map.isOutsideMap(col, row))\n                this._map.setWall(col, row, on);\n        }\n\n        public getTilesByType(index: number): Location[] {\n            if (this.isInvalidIndex(index) || !this.enabled) return [];\n\n            let output: Location[] = [];\n            for (let col = 0; col < this._map.width; ++col) {\n                for (let row = 0; row < this._map.height; ++row) {\n                    let currTile = this._map.getTile(col, row);\n                    if (currTile === index) {\n                        output.push(new Location(col, row, this));\n                    }\n                }\n            }\n            return output;\n        }\n\n        public sampleTilesByType(index: number, maxCount: number): Location[] {\n            if (this.isInvalidIndex(index) || !this.enabled || maxCount <= 0) return [];\n\n            let count = 0;\n            const reservoir: Location[] = [];\n            for (let col = 0; col < this._map.width; ++col) {\n                for (let row = 0; row < this._map.height; ++row) {\n                    let currTile = this._map.getTile(col, row);\n                    if (currTile === index) {\n                        // first **maxCount** elements just enqueue\n                        if (count < maxCount) {\n                            reservoir.push(new Location(col, row, this));\n                        } else {\n                            const potentialIndex = randint(0, count);\n                            if (potentialIndex < maxCount) {\n                                reservoir[potentialIndex] = new Location(col, row, this);\n                            }\n                        }\n                        ++count;\n                    }\n                }\n            }\n\n            return reservoir;\n        }\n\n        protected isInvalidIndex(index: number): boolean {\n            return index < 0 || index > 0xff;\n        }\n\n        protected draw(target: Image, camera: scene.Camera) {\n            if (!this.enabled) return;\n\n            // render tile map\n            const bitmask = (0x1 << this.scale) - 1;\n            const offsetX = camera.drawOffsetX & bitmask;\n            const offsetY = camera.drawOffsetY & bitmask;\n\n            const x0 = Math.max(0, camera.drawOffsetX >> this.scale);\n            const xn = Math.min(this._map.width, ((camera.drawOffsetX + target.width) >> this.scale) + 1);\n            const y0 = Math.max(0, camera.drawOffsetY >> this.scale);\n            const yn = Math.min(this._map.height, ((camera.drawOffsetY + target.height) >> this.scale) + 1);\n\n            for (let x = x0; x <= xn; ++x) {\n                for (let y = y0; y <= yn; ++y) {\n                    const index = this._map.getTile(x, y);\n                    const tile = this._map.getTileImage(index);\n                    if (tile) {\n                        target.drawTransparentImage(\n                            tile,\n                            ((x - x0) << this.scale) - offsetX,\n                            ((y - y0) << this.scale) - offsetY\n                        );\n                    }\n                }\n            }\n\n            if (game.debug) {\n                // render debug grid overlay\n                for (let x = x0; x <= xn; ++x) {\n                    const xLine = ((x - x0) << this.scale) - offsetX;\n                    if (xLine >= 0 && xLine <= screen.width) {\n                        target.drawLine(\n                            xLine,\n                            0,\n                            xLine,\n                            target.height,\n                            1\n                        );\n                    }\n                }\n\n                for (let y = y0; y <= yn; ++y) {\n                    const yLine = ((y - y0) << this.scale) - offsetY;\n                    if (yLine >= 0 && yLine <= screen.height) {\n                        target.drawLine(\n                            0,\n                            yLine,\n                            target.width,\n                            yLine,\n                            1\n                        );\n                    }\n                }\n            }\n        }\n\n        public isObstacle(col: number, row: number) {\n            if (!this.enabled) return false;\n            if (this._map.isOutsideMap(col, row)) return true;\n\n            return this._map.isWall(col, row);\n        }\n\n        public getObstacle(col: number, row: number) {\n            const index = this._map.isOutsideMap(col, row) ? 0 : this._map.getTile(col, row);\n            const tile = this._map.getTileImage(index);\n            return new sprites.StaticObstacle(\n                tile,\n                row << this.scale,\n                col << this.scale,\n                this.layer,\n                index\n            );\n        }\n\n        public isOnWall(s: Sprite) {\n            const hbox = s._hitbox;\n\n            const left = Fx.toIntShifted(hbox.left, this.scale);\n            const right = Fx.toIntShifted(hbox.right, this.scale);\n            const top = Fx.toIntShifted(hbox.top, this.scale);\n            const bottom = Fx.toIntShifted(hbox.bottom, this.scale);\n\n            for (let col = left; col <= right; ++col) {\n                for (let row = top; row <= bottom; ++row) {\n                    if (this.isObstacle(col, row)) {\n                        return true;\n                    }\n                }\n            }\n\n            return false;\n        }\n\n        public getTileImage(index: number) {\n            return this.data.getTileImage(index);\n        }\n\n        public addEventListener(event: TileMapEvent, handler: (data: TileMapData) => void) {\n            if (!this.handlerState) this.handlerState = [];\n\n            for (const eventHandler of this.handlerState) {\n                if (eventHandler.event === event && eventHandler.callback === handler) return;\n            }\n            this.handlerState.push(new TileMapEventHandler(event, handler));\n        }\n\n        public removeEventListener(event: TileMapEvent, handler: (data: TileMapData) => void) {\n            if (!this.handlerState) return;\n\n            for (let i = 0; i < this.handlerState.length; i++) {\n                if (this.handlerState[i].event === event && this.handlerState[i].callback === handler) {\n                    this.handlerState.splice(i, 1)\n                    return;\n                }\n            }\n        }\n    }\n\n    function mkColorTile(index: number, scale: TileScale): Image {\n        const size = 1 << scale\n\n        const i = image.create(size, size);\n        i.fill(index);\n        return i;\n    }\n\n    //% scale.defl=\"TileScale.Sixteen\"\n    export function createTilemap(data: Buffer, layer: Image, tiles: Image[], scale: TileScale): TileMapData {\n        return new TileMapData(data, layer, tiles, scale)\n    }\n\n    //% blockId=tilemap_editor block=\"set tilemap to $tilemap\"\n    //% weight=200 blockGap=8\n    //% tilemap.fieldEditor=\"tilemap\"\n    //% tilemap.fieldOptions.decompileArgumentAsString=\"true\"\n    //% tilemap.fieldOptions.filter=\"tile\"\n    //% tilemap.fieldOptions.taggedTemplate=\"tilemap\"\n    //% blockNamespace=\"scene\" duplicateShadowOnDrag\n    //% help=tiles/set-tilemap\n    //% deprecated=1\n    export function setTilemap(tilemap: TileMapData) {\n        setCurrentTilemap(tilemap);\n    }\n\n    /**\n     * Sets the given tilemap to be the current active tilemap in the game\n     *\n     * @param tilemap The tilemap to set as the current tilemap\n     */\n    //% blockId=set_current_tilemap block=\"set tilemap to $tilemap\"\n    //% weight=201 blockGap=8\n    //% tilemap.shadow=tiles_tilemap_editor\n    //% blockNamespace=\"scene\" group=\"Tilemaps\" duplicateShadowOnDrag\n    //% help=tiles/set-current-tilemap\n    export function setCurrentTilemap(tilemap: TileMapData) {\n        scene.setTileMapLevel(tilemap);\n    }\n\n    /**\n     * Set a location in the map (column, row) to a tile\n     * @param loc\n     * @param tile\n     */\n    //% blockId=mapsettileat block=\"set $tile at $loc=mapgettile\"\n    //% tile.shadow=tileset_tile_picker\n    //% tile.decompileIndirectFixedInstances=true\n    //% blockNamespace=\"scene\" group=\"Tilemap Operations\" blockGap=8\n    //% help=tiles/set-tile-at\n    //% weight=70\n    export function setTileAt(loc: Location, tile: Image): void {\n        const scene = game.currentScene();\n        if (!loc || !tile || !scene.tileMap) return null;\n        const scale = scene.tileMap.scale;\n        const index = scene.tileMap.getImageType(tile);\n        scene.tileMap.setTileAt(loc.x >> scale, loc.y >> scale, index);\n    }\n\n    /**\n     * Set or unset a wall at a location in the map (column, row)\n     * @param loc\n     * @param on\n     */\n    //% blockId=mapsetwallat block=\"set wall $on at $loc\"\n    //% on.shadow=toggleOnOff loc.shadow=mapgettile\n    //% blockNamespace=\"scene\" group=\"Tilemap Operations\"\n    //% help=tiles/set-wall-at\n    //% weight=60\n    export function setWallAt(loc: Location, on: boolean): void {\n        const scene = game.currentScene();\n        if (!loc || !scene.tileMap) return null;\n        const scale = scene.tileMap.scale;\n        scene.tileMap.setWallAt(loc.x >> scale, loc.y >> scale, on);\n    }\n\n    /**\n     * Get the tile position given a column and row in the tilemap\n     * @param col\n     * @param row\n     */\n    //% blockId=mapgettile block=\"tilemap col $col row $row\"\n    //% blockNamespace=\"scene\" group=\"Locations\"\n    //% weight=100 blockGap=8\n    //% help=tiles/get-tile-location\n    export function getTileLocation(col: number, row: number): Location {\n        const scene = game.currentScene();\n        if (col == undefined || row == undefined || !scene.tileMap) return null;\n        return scene.tileMap.getTile(col, row);\n    }\n\n    /**\n     * Get the image of a tile, given a location in the tilemap\n     * @param loc\n     */\n    export function getTileImage(loc: Location): Image {\n        const scene = game.currentScene();\n        if (!loc || !scene.tileMap) return img``;\n        return scene.tileMap.getTileImage(loc.tileSet);\n    }\n\n    /**\n     * Get the image of a tile, given a (column, row) in the tilemap\n     * @param loc\n     */\n    export function getTileAt(col: number, row: number): Image {\n        const scene = game.currentScene();\n        if (col == undefined || row == undefined || !scene.tileMap) return img``;\n        return scene.tileMap.getTileImage(tiles.getTileLocation(col, row).tileSet);\n    }\n\n    /**\n     * Returns true if the tile at the given location is the same as the given tile;\n     * otherwise returns false\n     * @param location\n     * @param tile\n     */\n    //% blockId=maplocationistile block=\"tile at $location is $tile\"\n    //% location.shadow=mapgettile\n    //% tile.shadow=tileset_tile_picker tile.decompileIndirectFixedInstances=true\n    //% blockNamespace=\"scene\" group=\"Locations\" blockGap=8\n    //% weight=40 help=tiles/tile-at-location-equals\n    export function tileAtLocationEquals(location: Location, tile: Image): boolean {\n        const scene = game.currentScene();\n        if (!location || !tile || !scene.tileMap) return false;\n        return location.tileSet === scene.tileMap.getImageType(tile);\n    }\n\n    /**\n     * Returns true if the tile at the given location is a wall in the current tilemap;\n     * otherwise returns false\n     * @param location The location to check for a wall\n     */\n    //% blockId=tiles_tile_at_location_is_wall\n    //% block=\"tile at $location is wall\"\n    //% location.shadow=mapgettile\n    //% blockNamespace=\"scene\" group=\"Locations\" blockGap=8\n    //% weight=30 help=tiles/tile-at-location-is-wall\n    export function tileAtLocationIsWall(location: Location): boolean {\n        if (!location || !location.tileMap) return false;\n        return location.isWall();\n    }\n\n    /**\n     * Returns the image of the tile at the given location in the current tilemap\n     *\n     * @param location The location of the image to fetch\n     */\n    //% blockId=tiles_image_at_location\n    //% block=\"tile image at $location\"\n    //% location.shadow=mapgettile\n    //% weight=0 help=tiles/tile-image-at-location\n    //% blockNamespace=\"scene\" group=\"Locations\"\n    export function tileImageAtLocation(location: Location): Image {\n        const scene = game.currentScene();\n        if (!location || !scene.tileMap) return img``;\n        return location.getImage();\n    }\n\n    /**\n     * Center the given sprite on a given location\n     * @param sprite\n     * @param loc\n     */\n    //% blockId=mapplaceontile block=\"place $sprite=variables_get(mySprite) on top of $loc\"\n    //% loc.shadow=mapgettile\n    //% blockNamespace=\"scene\" group=\"Tilemap Operations\" blockGap=8\n    //% help=tiles/place-on-tile\n    //% weight=100\n    export function placeOnTile(sprite: Sprite, loc: Location): void {\n        if (!sprite || !loc || !loc.tileMap) return;\n        loc.place(sprite);\n    }\n\n    /**\n     * Center the given sprite on a random location that is the given type (image)\n     * @param sprite\n     * @param tile\n     */\n    //% blockId=mapplaceonrandomtile block=\"place $sprite=variables_get(mySprite) on top of random $tile\"\n    //% tile.shadow=tileset_tile_picker\n    //% tile.decompileIndirectFixedInstances=true\n    //% blockNamespace=\"scene\" group=\"Tilemap Operations\"\n    //% help=tiles/place-on-random-tile\n    //% weight=90\n    export function placeOnRandomTile(sprite: Sprite, tile: Image): void {\n        if (!sprite || !game.currentScene().tileMap) return;\n        const loc = getRandomTileByType(tile);\n        if (loc)\n            loc.place(sprite);\n    }\n\n    /**\n     * Get all tiles in the tilemap with the given type (image).\n     * @param tile\n     */\n    //% blockId=mapgettilestype block=\"array of all $tile locations\"\n    //% tile.shadow=tileset_tile_picker\n    //% tile.decompileIndirectFixedInstances=true\n    //% blockNamespace=\"scene\" group=\"Locations\" blockGap=8\n    //% help=tiles/get-tiles-by-type\n    //% weight=10\n    export function getTilesByType(tile: Image): Location[] {\n        const scene = game.currentScene();\n        if (!tile || !scene.tileMap) return [];\n        const index = scene.tileMap.getImageType(tile);\n        return scene.tileMap.getTilesByType(index);\n    }\n\n    /**\n     * Get a random tile of the given type\n     * @param tile the type of tile to get a random selection of\n     */\n    export function getRandomTileByType(tile: Image): Location {\n        const scene = game.currentScene();\n        if (!tile || !scene.tileMap)\n            return undefined;\n        const index = scene.tileMap.getImageType(tile);\n        const sample = scene.tileMap.sampleTilesByType(index, 1);\n        return sample[0];\n    }\n\n    /**\n     * A tilemap\n     */\n    //% blockId=tiles_tilemap_editor shim=TD_ID\n    //% weight=200 blockGap=8\n    //% block=\"tilemap $tilemap\"\n    //% tilemap.fieldEditor=\"tilemap\"\n    //% tilemap.fieldOptions.decompileArgumentAsString=\"true\"\n    //% tilemap.fieldOptions.filter=\"tile\"\n    //% tilemap.fieldOptions.taggedTemplate=\"tilemap\"\n    //% blockNamespace=\"scene\" group=\"Tilemaps\" duplicateShadowOnDrag\n    //% help=tiles/tilemap\n    export function _tilemapEditor(tilemap: TileMapData): TileMapData {\n        return tilemap;\n    }\n\n    /**\n     * Adds an event handler that will fire whenever the specified event\n     * is triggered. Unloaded tilemap events will fire before the new tilemap\n     * is set and loaded events will fire afterwards. The same handler can\n     * not be added for the same event more than once.\n     *\n     * @param event     The event to subscribe to\n     * @param handler   The code to run when the event triggers\n     */\n    export function addEventListener(event: TileMapEvent, callback: (data: TileMapData) => void) {\n        const scene = game.currentScene();\n\n        if (!scene.tileMap) {\n            scene.tileMap = new TileMap();\n        }\n\n        scene.tileMap.addEventListener(event, callback);\n    }\n\n\n    /**\n     * Removes an event handler registered with addEventListener.\n     *\n     * @param event     The event that the handler was registered for\n     * @param handler   The handler to remove\n     */\n    export function removeEventListener(event: TileMapEvent, callback: (data: TileMapData) => void) {\n        const scene = game.currentScene();\n\n        if (!scene.tileMap) return;\n\n        scene.tileMap.removeEventListener(event, callback);\n    }\n}\n"},"game---light":{"compat.ts":"namespace scene.systemMenu {\n    export function isVisible() {\n        return false\n    }\n}\n\nnamespace power {\n    export function poke() {}\n}\n\nnamespace scene {\n    export const SCREEN_CLEAR_PRIORITY = 1;\n    export const UPDATE_INTERVAL_PRIORITY = 19;\n    export const UPDATE_PRIORITY = 20;\n\n    export const PRE_RENDER_UPDATE_PRIORITY = 55;\n    export const RENDER_BACKGROUND_PRIORITY = 60;\n    export const RENDER_SPRITES_PRIORITY = 90;\n    export const RENDER_DIAGNOSTICS_PRIORITY = 150;\n    export const UPDATE_SCREEN_PRIORITY = 200;\n}\n\nclass Scene {\n    millis() {\n        return control.millis()\n    }\n\n    constructor() {\n        this.buttonEventHandlers = []\n    }\n\n    buttonEventHandlers: controller.ButtonEventHandlerState[];\n}\n\nnamespace game {\n    export let stats = false;\n    let inited = false\n\n    const _scene = new Scene()\n    export function currentScene() {\n        return _scene\n    }\n\n    export function pushScene() {\n        const ctx = control.pushEventContext()\n        ctx.registerFrameHandler(scene.RENDER_BACKGROUND_PRIORITY, () => {\n            screen.fill(0)\n        });\n        ctx.registerFrameHandler(scene.UPDATE_SCREEN_PRIORITY, control.__screen.update);\n    }\n\n    export function popScene() {\n        control.popEventContext()\n    }\n\n    export function eventContext() {\n        if (!inited) {\n            inited = true\n            pushScene()\n        }\n        return control.eventContext()\n    }\n\n    let __waitAnyButton: () => void;\n    export function setWaitAnyButton(f: () => void) {\n        __waitAnyButton = f\n    }\n\n    /**\n     * Draw on screen before sprites, after background\n     * @param body code to execute\n     */\n    //% group=\"Gameplay\"\n    //% help=game/paint weight=10 afterOnStart=true\n    export function onPaint(a: () => void): void {\n        if (!a) return;\n        control.eventContext().registerFrameHandler(scene.RENDER_SPRITES_PRIORITY - 1, a);\n    }\n\n    /**\n     * Draw on screen after sprites\n     * @param body code to execute\n     */\n    //% group=\"Gameplay\"\n    //% help=game/shade weight=10 afterOnStart=true\n    export function onShade(a: () => void): void {\n        if (!a) return;\n        control.eventContext().registerFrameHandler(scene.RENDER_SPRITES_PRIORITY, a);\n    }\n\n}\n\nnamespace controller {\n    export function _player1() {\n        return new Controller(1, undefined)\n    }\n    export class Controller {\n        constructor(no: number, v: any) { }\n        connected: boolean\n    }\n}\n","console.ts":"namespace game.consoleOverlay {\n    let consoleColor = 1;\n    let consoleStrings: string[];\n    let tabSize = 8;\n    const marginx = 4;\n    const marginy = 2;\n    const consoleFont = image.font5;\n    const consoleLines = Math.floor(screen.height / (consoleFont.charHeight + marginy)) - 1;\n    const consoleColumns = Math.floor((screen.width - 2 * marginx) / consoleFont.charWidth);\n    console.addListener(listener);\n\n    export function isVisible() {\n        return !!consoleStrings;\n    }\n\n    export function clear() {\n        consoleStrings = [];\n    }\n\n    export function setVisible(value: boolean, col?: number) {\n        if (value != !!consoleStrings)\n            consoleStrings = value ? [] : undefined;\n        if (col !== undefined)\n            consoleColor = col;\n    }\n\n    function listener(priority: ConsolePriority, text: string) {\n        if (!consoleStrings || !text)\n            return;\n\n        // split text into lines\n        text.split(\"\\n\")\n            .filter(line => !!line)\n            .forEach(line => {\n                for (let j = 0; j < line.length; j += consoleColumns) {\n                    consoleStrings.push(line.slice(j, j + consoleColumns));\n                }\n            });\n\n        if (consoleStrings.length > consoleLines) {\n            consoleStrings.splice(0, consoleStrings.length - consoleLines);\n        }\n    }\n\n    export function draw() {\n        if (!consoleStrings || scene.systemMenu.isVisible()) return;\n        const height = consoleFont.charHeight + marginy;\n        const top = 2 + (game.stats ? height : 0);\n        for (let i = 0; i < consoleStrings.length; ++i) {\n            if (consoleStrings[i].indexOf(\"\\t\") >= 0) {\n                const t = consoleStrings[i].split(\"\\t\");\n                let tOff = 0;\n                for (let tab of t) {\n                    let padding = tabSize - ((tOff + tab.length) % tabSize)\n                    screen.print(tab, marginx + (tOff * consoleFont.charWidth), top + i * height, consoleColor, consoleFont);\n                    tOff += tab.length + padding;\n                }\n            }\n            else\n                screen.print(consoleStrings[i], marginx, top + i * height, consoleColor, consoleFont);\n        }\n    }\n}","constants.ts":"const KEY_UP = 2048;\nconst KEY_DOWN = 2049;\nconst INTERNAL_KEY_UP = 2050;\nconst INTERNAL_KEY_DOWN = 2051;\nconst SYSTEM_KEY_UP = 2052;\nconst SYSTEM_KEY_DOWN = 2053;\nconst KEY_REPEAT = 2054;\nconst SYSTEM_KEY_REPEAT = 2055;\n","controllerbutton.ts":"enum ControllerButtonEvent {\n    //% block=\"pressed\"\n    Pressed = KEY_DOWN,\n    //% block=\"released\"\n    Released = KEY_UP,\n    //% block=\"repeat\"\n    Repeated = KEY_REPEAT\n}\n\nenum ControllerButton {\n    //% block=\"{id:controller}A\"\n    A = 5,\n    //% block=\"{id:controller}B\"\n    B = 6,\n    //% block=\"left\"\n    Left = 1,\n    //% block=\"up\"\n    Up = 2,\n    //% block=\"right\"\n    Right = 3,\n    //% block=\"down\"\n    Down = 4\n}\n\n/**\n * Access to game controls\n */\n//% weight=98 color=\"#D54322\" icon=\"\\uf11b\"\n//% groups='[\"Single Player\", \"Multiplayer\"]'\n//% blockGap=8\nnamespace controller {\n    let _userEventsEnabled = true;\n    let defaultRepeatDelay = 500;\n    let defaultRepeatInterval = 30;\n\n    //% shim=pxt::pressureLevelByButtonId\n    declare function pressureLevelByButtonId(btnId: number, codalId: number): number;\n\n    //% shim=pxt::setupButton\n    function setupButton(buttonId: number, key: number) {\n        return // missing in sim\n     }\n\n    export class ButtonHandler {\n        constructor(public event: number, public callback: () => void) { }\n    }\n\n    export class ButtonEventHandlerState {\n        constructor(public id: number) {};\n\n        public user: ButtonHandler[];\n        public system: ButtonHandler[];\n    }\n\n    //% fixedInstances\n    export class Button {\n        _owner: Controller;\n        public id: number;\n        //% help=controller/button/repeat-delay\n        public repeatDelay: number;\n        //% help=controller/button/repeat-interval\n        public repeatInterval: number;\n        private _pressed: boolean;\n        private _pressedElasped: number;\n        private _repeatCount: number;\n\n        protected get handlerState(): ButtonEventHandlerState {\n            for (const state of game.currentScene().buttonEventHandlers) {\n                if (state.id === this.id) return state;\n            }\n            return undefined;\n        }\n\n        toString(): string {\n            return `btn ${this.id} ${this._pressed ? \"down\" : \"up\"}`;\n        }\n\n        constructor(id: number, configKey: number) {\n            this.id = id;\n            this._pressed = false;\n            this.repeatDelay = undefined;\n            this.repeatInterval = undefined;\n            this._repeatCount = 0;\n\n            if (id > 0) {\n                // this is to deal with the \"anyButton\" hack, which creates a button that is not visible\n                // in the UI, but used in event-handler to simulate the wildcard ANY for matching. As\n                // this button can't actually be pressed, we don't want it to propagate events\n                control.internalOnEvent(INTERNAL_KEY_UP, this.id, () => this.setPressed(false), 16)\n                control.internalOnEvent(INTERNAL_KEY_DOWN, this.id, () => this.setPressed(true), 16)\n\n                if (configKey > 0)\n                    setupButton(id, configKey)\n            }\n        }\n\n        private raiseButtonUp() {\n            if (_userEventsEnabled)\n                control.raiseEvent(KEY_UP, this.id)\n            else\n                control.raiseEvent(SYSTEM_KEY_UP, this.id);\n        }\n\n        private raiseButtonDown() {\n            if (_userEventsEnabled)\n                control.raiseEvent(KEY_DOWN, this.id)\n            else\n                control.raiseEvent(SYSTEM_KEY_DOWN, this.id)\n        }\n\n        private raiseButtonRepeat() {\n            if (_userEventsEnabled)\n                control.raiseEvent(KEY_REPEAT, this.id)\n            else\n                control.raiseEvent(SYSTEM_KEY_REPEAT, this.id)\n        }\n\n        /**\n         * Run some code when a button is pressed, released, or held\n         */\n        //% weight=99 blockGap=8 help=controller/button/on-event\n        //% blockId=keyonevent block=\"on %button **button** %event\"\n        //% group=\"Single Player\"\n        onEvent(event: ControllerButtonEvent, handler: () => void) {\n            const eventHandler = this.getOrCreateHandlerForEvent(event);\n            eventHandler.callback = handler;\n        }\n\n        /**\n         * Adds an event handler that will fire whenever the specified event\n         * is triggered on this button. Handlers added using this method will\n         * not conflict with events added via onEvent. The same handler can\n         * not be added for the same event more than once.\n         *\n         * @param event     The event to subscribe to for this button\n         * @param handler   The code to run when the event triggers\n         */\n        addEventListener(event: ControllerButtonEvent, handler: () => void) {\n            this.getOrCreateHandlerForEvent(event);\n\n            const handlerState = this.handlerState;\n\n            if (!handlerState.system) handlerState.system = [];\n\n            for (const eventHandler of handlerState.system) {\n                if (eventHandler.event === event && eventHandler.callback === handler) return;\n            }\n\n            handlerState.system.push(new ButtonHandler(event, handler));\n        }\n\n        /**\n         * Removes an event handler registered with addEventListener.\n         *\n         * @param event     The event that the handler was registered for\n         * @param handler   The handler to remove\n         */\n        removeEventListener(event: ControllerButtonEvent, handler: () => void) {\n            const handlerState = this.handlerState;\n            if (!handlerState || !handlerState.system) return;\n\n            for (let i = 0; i < handlerState.system.length; i++) {\n                if (handlerState.system[i].event === event && handlerState.system[i].callback === handler) {\n                    handlerState.system.splice(i, 1)\n                    return;\n                }\n            }\n        }\n\n        /**\n         * Pauses until a button is pressed or released\n         */\n        //% weight=98 blockGap=8 help=controller/button/pause-until\n        // blockId=keypauseuntil block=\"pause until %button **button** is %event\"\n        //% group=\"Single Player\"\n        pauseUntil(event: ControllerButtonEvent) {\n            control.waitForEvent(event, this.id)\n        }\n\n        /**\n         * Indicates if the button is currently pressed\n         */\n        //% weight=96 blockGap=8 help=controller/button/is-pressed\n        //% blockId=keyispressed block=\"is %button **button** pressed\"\n        //% group=\"Single Player\"\n        isPressed() {\n            return this._pressed;\n        }\n\n        /**\n         * Indicates how hard the button is pressed, 0-512\n         */\n        pressureLevel() {\n            if (control.deviceDalVersion() == \"sim\") {\n                return this.isPressed() ? 512 : 0\n                // once implemented in sim, this could be similar to the one below\n            } else {\n                return pressureLevelByButtonId(this.id, -1);\n            }\n        }\n\n        setPressed(pressed: boolean) {\n            if (this._pressed != pressed) {\n                power.poke();\n                if (this._owner)\n                    this._owner.connected = true;\n                this._pressed = pressed;\n                if (this._pressed) {\n                    this._pressedElasped = 0;\n                    this.raiseButtonDown();\n                } else {\n                    this._repeatCount = 0;\n                    this.raiseButtonUp();\n                }\n            }\n        }\n\n        __update(dtms: number) {\n            if (!this._pressed) return;\n            this._pressedElasped += dtms;\n\n            const delay = this.repeatDelay === undefined ? defaultRepeatDelay : this.repeatDelay;\n            const interval = this.repeatInterval === undefined ? defaultRepeatInterval : this.repeatInterval;\n\n            // inital delay\n            if (this._pressedElasped < delay)\n                return;\n\n            // repeat count for this step\n            const count = Math.floor((this._pressedElasped - delay - interval) / interval);\n            if (count != this._repeatCount) {\n                this.raiseButtonRepeat();\n                this._repeatCount = count;\n            }\n        }\n\n        protected runButtonEvents(event: ControllerButtonEvent) {\n            const handlerState = this.handlerState;\n            if (!handlerState) return;\n\n            const userHandler = this.getOrCreateHandlerForEvent(event);\n            if (userHandler.callback) userHandler.callback();\n\n            if (handlerState.system) {\n                for (const eventHandler of handlerState.system) {\n                    if (eventHandler.event === event && eventHandler.callback) eventHandler.callback();\n                }\n            }\n        }\n\n        protected getOrCreateHandlerForEvent(event: ControllerButtonEvent) {\n            if (!this.handlerState) {\n                game.currentScene().buttonEventHandlers.push(new ButtonEventHandlerState(this.id));\n            }\n\n            const handlerState = this.handlerState;\n            if (!handlerState.user) handlerState.user = [];\n\n            for (const eventHandler of handlerState.user) {\n                if (eventHandler.event === event) {\n                    return eventHandler;\n                }\n            }\n\n            // Register actual handler if this hasn't been used before\n            control.onEvent(event, this.id, () => this.runButtonEvents(event));\n\n            const newHandler = new ButtonHandler(event, undefined);\n            handlerState.user.push(newHandler);\n            return newHandler;\n        }\n    }\n\n    /**\n     * Configures the timing of the on button repeat event for all of the controller buttons\n     * @param delay number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500\n     * @param interval minimum number of milliseconds between calls to the button repeat event, eg: 30\n     */\n    export function setRepeatDefault(delay: number, interval: number) {\n        defaultRepeatDelay = delay;\n        defaultRepeatInterval = interval;\n    }\n\n    /**\n     * Pause the program until a button is pressed\n     */\n    //% weight=10\n    export function pauseUntilAnyButtonIsPressed() {\n        control.waitForEvent(KEY_DOWN, 0)\n    }\n\n    export function _setUserEventsEnabled(enabled: boolean) {\n        _userEventsEnabled = enabled;\n    }\n}\n","controllerbuttons.cpp":"#include \"pxt.h\"\n\n#ifdef PXT_CODAL\n\nnamespace pxt {\n\nclass PressureButton : public codal::Button {\n  public:\n    PressureButton(Pin &pin, uint16_t id,\n                   ButtonEventConfiguration eventConfiguration = DEVICE_BUTTON_ALL_EVENTS,\n                   ButtonPolarity polarity = ACTIVE_LOW, PullMode mode = PullMode::None)\n        : Button(pin, id, eventConfiguration, polarity, mode) {}\n\n    virtual int pressureLevel() { return isPressed() ? 512 : 0; }\n};\n\nstruct AnalogCache {\n    AnalogCache *next;\n    Pin *pin;\n    uint32_t lastMeasureMS;\n    uint16_t lastMeasure;\n    AnalogCache(Pin *pin) : pin(pin) {\n        next = NULL;\n        lastMeasureMS = 0;\n        lastMeasure = pin->getAnalogValue();\n    }\n    uint16_t read();\n};\n\nuint16_t AnalogCache::read() {\n    uint32_t now = current_time_ms();\n    if (now - lastMeasureMS < 50)\n        return lastMeasure;\n    lastMeasureMS = now;\n    lastMeasure = pin->getAnalogValue();\n    return lastMeasure;\n}\n\nstatic AnalogCache *analogCache;\n\nclass AnalogButton : public PressureButton {\n  public:\n    AnalogCache *cache;\n    int16_t threshold;\n    bool state;\n\n    AnalogButton(AnalogCache *cache, uint16_t id, int threshold)\n        : PressureButton(*cache->pin, id), cache(cache), threshold(threshold), state(false) {}\n\n  protected:\n    virtual int pressureLevel() override {\n        int v = cache->read() - 512;\n        if (threshold < 0)\n            v = -v;\n        int vmin = getConfig(CFG_ANALOG_JOYSTICK_MIN, 50);\n        int vmax = getConfig(CFG_ANALOG_JOYSTICK_MAX, 500);\n        v = (v - vmin) * 512 / (vmax - vmin);\n        if (v < 0)\n            v = 0;\n        if (v > 512)\n            v = 512;\n        return v;\n    }\n\n    virtual int buttonActive() override {\n        int v = cache->read() - 512;\n        int thr = threshold;\n\n        if (thr < 0) {\n            v = -v;\n            thr = -thr;\n        }\n\n        if (v > thr)\n            state = true;\n        else if (state && v > thr * 3 / 4)\n            state = true;\n        else\n            state = false;\n\n        return state;\n    }\n};\n\nAnalogCache *lookupAnalogCache(Pin *pin) {\n    for (auto c = analogCache; c; c = c->next)\n        if (c->pin == pin)\n            return c;\n    auto c = new AnalogCache(pin);\n    c->next = analogCache;\n    analogCache = c;\n    return c;\n}\n\nint multiplexedButtonIsPressed(int btnId);\nint registerMultiplexedButton(int pin, int buttonId);\n\n//% expose\nint pressureLevelByButtonId(int btnId, int codalId) {\n    if (codalId <= 0)\n        codalId = DEVICE_ID_FIRST_BUTTON + btnId;\n    auto btn = (PressureButton *)lookupComponent(codalId);\n    if (!btn) {\n        return multiplexedButtonIsPressed(btnId) ? 512 : 0;\n    }\n    return btn->pressureLevel();\n}\n\nstatic void sendBtnDown(Event ev) {\n    Event(PXT_INTERNAL_KEY_DOWN, ev.source - DEVICE_ID_FIRST_BUTTON);\n}\n\nstatic void sendBtnUp(Event ev) {\n    Event(PXT_INTERNAL_KEY_UP, ev.source - DEVICE_ID_FIRST_BUTTON);\n}\n\n//% expose\nvoid setupButton(int buttonId, int key) {\n    int pin = getConfig(key);\n    if (pin == -1)\n        return;\n\n    unsigned highflags = (unsigned)pin >> 16;\n    int flags = BUTTON_ACTIVE_LOW_PULL_UP;\n    if (highflags & 0xff)\n        flags = highflags & 0xff;\n\n    pin &= 0xffff;\n\n    auto cpid = DEVICE_ID_FIRST_BUTTON + buttonId;\n    auto btn = (PressureButton *)lookupComponent(cpid);\n    if (btn == NULL) {\n        if (registerMultiplexedButton(pin, buttonId))\n            return;\n\n        if (1100 <= pin && pin < 1300) {\n            pin -= 1100;\n            int thr = getConfig(CFG_ANALOG_BUTTON_THRESHOLD, 300);\n            if (pin >= 100) {\n                thr = -thr;\n                pin -= 100;\n            }\n            btn = new AnalogButton(lookupAnalogCache(lookupPin(pin)), cpid, thr);\n        } else {\n            auto pull = PullMode::None;\n            if ((flags & 0xf0) == 0x10)\n                pull = PullMode::Down;\n            else if ((flags & 0xf0) == 0x20)\n                pull = PullMode::Up;\n            else if ((flags & 0xf0) == 0x30)\n                pull = PullMode::None;\n            else\n                oops(3);\n            btn = new PressureButton(*lookupPin(pin), cpid, DEVICE_BUTTON_ALL_EVENTS,\n                                     (ButtonPolarity)(flags & 0xf), pull);\n        }\n        EventModel::defaultEventBus->listen(btn->id, DEVICE_BUTTON_EVT_DOWN, sendBtnDown);\n        EventModel::defaultEventBus->listen(btn->id, DEVICE_BUTTON_EVT_UP, sendBtnUp);\n    }\n}\n\n} // namespace pxt\n\n#endif","controlleroverrides.ts":"namespace controller {\n    //% fixedInstance whenUsed block=\"{id:controller}A\"\n    export const A = new Button(ControllerButton.A, DAL.CFG_PIN_BTN_A);\n    //% fixedInstance whenUsed block=\"{id:controller}B\"\n    export const B = new Button(ControllerButton.B, DAL.CFG_PIN_BTN_B);\n    //% fixedInstance whenUsed block=\"left\"\n    export const left = new Button(ControllerButton.Left, DAL.CFG_PIN_BTN_LEFT);\n    //% fixedInstance whenUsed block=\"up\"\n    export const up = new Button(ControllerButton.Up, DAL.CFG_PIN_BTN_UP);\n    //% fixedInstance whenUsed block=\"right\"\n    export const right = new Button(ControllerButton.Right, DAL.CFG_PIN_BTN_RIGHT);\n    //% fixedInstance whenUsed block=\"down\"\n    export const down = new Button(ControllerButton.Down, DAL.CFG_PIN_BTN_DOWN);\n    //% fixedInstance whenUsed block=\"menu\"\n    export const menu = new Button(7, DAL.CFG_PIN_BTN_MENU);\n\n    //% fixedInstance whenUsed block=\"player 2\"\n    export const player2 = new Controller(2, undefined);\n    //% fixedInstance whenUsed block=\"player 3\"\n    export const player3 = new Controller(3, undefined);\n    //% fixedInstance whenUsed block=\"player 4\"\n    export const player4 = new Controller(4, undefined);\n    //% fixedInstance whenUsed block=\"player 1\"\n    export const player1 = controller._player1();\n}","gameutil.ts":"/**\n * Game transitions and dialog\n **/\nnamespace game {\n\n    /**\n     * Update the position and velocities of sprites\n     * @param body code to execute\n     */\n    //% group=\"Gameplay\"\n    //% help=game/on-update weight=100 afterOnStart=true\n    //% blockId=gameupdate block=\"on game update\"\n    //% blockAllowMultiple=1\n    export function onUpdate(a: () => void): void {\n        if (!a) return;\n        game.eventContext().registerFrameHandler(scene.UPDATE_PRIORITY, a);\n    }\n\n    /**\n     * Run code on an interval of time. This executes before game.onUpdate()\n     * @param body code to execute\n     */\n    //% group=\"Gameplay\"\n    //% help=game/on-update-interval weight=99 afterOnStart=true\n    //% blockId=gameinterval block=\"on game update every %period=timePicker ms\"\n    //% blockAllowMultiple=1\n    export function onUpdateInterval(period: number, a: () => void): void {\n        if (!a || period < 0) return;\n        let timer = 0;\n        game.eventContext().registerFrameHandler(scene.UPDATE_INTERVAL_PRIORITY, () => {\n            const time = game.currentScene().millis();\n            if (timer <= time) {\n                timer = time + period;\n                a();\n            }\n        });\n    }\n\n    /**\n     * Returns the time since the game started in milliseconds\n     */\n    //% blockId=arcade_game_runtime block=\"time since start (ms)\"\n    //% group=\"Gameplay\" weight=11\n    //% help=game/runtime\n    export function runtime(): number {\n        return currentScene().millis();\n    }\n}\n","mathUtil.ts":"namespace Math {\n    /**\n     * Returns a random boolean that is true the given percentage of the time.\n     * @param percentage The percentage chance that the returned value will be true from 0 - 100\n     */\n    //% weight=2\n    //% blockId=percentchance block=\"%percentage|\\\\% chance\"\n    //% percentage.min=0 percentage.max=100;\n    //% help=math/percent-chance\n    export function percentChance(percentage: number): boolean {\n        if (percentage >= 100) {\n            return true;\n        }\n        else if (percentage <= 0) {\n            return false;\n        }\n        return Math.randomRange(0, 99) < percentage;\n    }\n\n    /**\n     * Returns a random element from the given list\n     * @param list The list to choose an element from\n     */\n    //% weight=1\n    export function pickRandom<T>(list: T[]) {\n        if (!list || list.length == 0) {\n            return undefined;\n        }\n        return list[Math.randomRange(0, list.length - 1)];\n    }\n\n    /**\n     * Fast, 16 bit, seedable (pseudo) random generator.\n     */\n    export class FastRandom {\n        // Implementation of the Galois Linear Feedback Shift Register\n        private lfsr: number;\n        // A value between 0x0001 and 0xFFFF to generate random values from\n        public seed: number;\n\n        /**\n         * Create a new Fast Random generator\n         * @param seed [Optional] initial seed between 0x0001 and 0xFFFF.\n         */\n        constructor(seed?: number) {\n            if (seed === undefined) seed = Math.randomRange(0x0001, 0xFFFF);\n            this.seed = seed;\n            this.lfsr = seed;\n        }\n\n        /**\n         * @returns the next random number between 0x0001 and 0xFFFF inclusive\n         */\n        next(): number {\n            return this.lfsr = (this.lfsr >> 1) ^ ((-(this.lfsr & 1)) & 0xb400);\n        }\n\n        /**\n         * @param min the minimum value to generate\n         * @param max the maximum value to generate\n         * @returns a random value between min and max (inclusive). If min is greater than or equal to max, returns min.\n         */\n        randomRange(min: number, max: number): number {\n            return min + (max > min ? this.next() % (max - min + 1) : 0);\n        }\n\n        /**\n         * Returns a random element from the given list\n         * @param list The list to choose an element from\n         */\n        pickRandom<T>(list: T[]) {\n            if (!list || list.length == 0) {\n                return undefined;\n            }\n            return list[this.randomRange(0, list.length - 1)];\n        }\n\n        /**\n         * @returns a random boolean value\n         */\n        randomBool(): boolean {\n            return !(this.next() & 1);\n        }\n\n        /**\n         * @param percent the percentage chance that the returned value will be true from 0 - 100\n         * @returns a boolean with approximately the given percent chance to be true or false\n         */\n        percentChance(percent: number): boolean {\n            return this.randomRange(0, 100) < percent;\n        }\n\n        /**\n         * Reset the state to the current seed\n         */\n        reset() {\n            this.lfsr = this.seed;\n        }\n    }\n}\n","pxt.json":"{\n    \"name\": \"game---light\",\n    \"description\": \"Empty game library - beta\",\n    \"dependencies\": {\n        \"settings\": \"*\",\n        \"screen\": \"*\"\n    },\n    \"files\": [\n        \"compat.ts\",\n        \"console.ts\",\n        \"constants.ts\",\n        \"controlleroverrides.ts\",\n        \"controllerbutton.ts\",\n        \"controllerbuttons.cpp\",\n        \"mathUtil.ts\",\n        \"gameutil.ts\",\n        \"targetoverrides.cpp\",\n        \"targetoverrides.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","targetoverrides.cpp":"// Overriden in target\n","targetoverrides.ts":"// Overriden in target\n"},"hw":{"basepins.d.ts":"//% advanced=true\ndeclare namespace pins {\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_LED)\n    const LED: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SDA)\n    const SDA: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SCL)\n    const SCL: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SCK)\n    const SCK: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_MISO)\n    const MISO: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_MOSI)\n    const MOSI: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_RX)\n    const RX: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_TX)\n    const TX: DigitalInOutPin;\n}\n","config.ts":"namespace config {\n    export const DISPLAY_WIDTH = 160;\n    export const DISPLAY_HEIGHT = 120;\n}\n","pxt.json":"{\n    \"name\": \"hw\",\n    \"description\": \"Hardware definition - web-browser only\",\n    \"dependencies\": {\n        \"core\": \"*\",\n        \"screen\": \"*\",\n        \"mixer\": \"*\",\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"basepins.d.ts\",\n        \"config.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"skipLocalization\": true\n}\n"},"hw---n3":{"basepins.d.ts":"//% advanced=true\ndeclare namespace pins {\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_LED)\n    const LED: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SDA)\n    const SDA: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SCL)\n    const SCL: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SCK)\n    const SCK: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_MISO)\n    const MISO: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_MOSI)\n    const MOSI: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_RX)\n    const RX: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_TX)\n    const TX: DigitalInOutPin;\n}\n","config.ts":"// there's no UF2 bootloader for 52833 yet, so we specify example configuration here\nnamespace config {\n    export const PIN_BTNMX_LATCH = DAL.P0_9\n    export const PIN_BTNMX_CLOCK = DAL.P1_0\n    export const PIN_BTNMX_DATA = DAL.P0_1\n\n    // pybadge-like layout\n    export const PIN_BTN_LEFT = 1050\n    export const PIN_BTN_UP = 1051\n    export const PIN_BTN_DOWN = 1052\n    export const PIN_BTN_RIGHT = 1053\n    export const PIN_BTN_A = 1054\n    export const PIN_BTN_B = 1055\n    export const PIN_BTN_MENU = 1056\n\n    export const PIN_JACK_SND = DAL.P0_0\n\n    export const PIN_DISPLAY_SCK = DAL.P0_17\n    export const PIN_DISPLAY_MOSI = DAL.P0_13\n    export const PIN_DISPLAY_MISO = DAL.P0_1\n    export const PIN_DISPLAY_BL = DAL.P0_26\n    export const PIN_DISPLAY_DC = DAL.P0_10\n    export const PIN_DISPLAY_RST = DAL.P1_2\n\n    // Jacdac, when jacdaptor is connected, is on the accessibility pin (P12)\n    export const PIN_JACK_TX = DAL.P0_12\n\n    export const DISPLAY_WIDTH = 160\n    export const DISPLAY_HEIGHT = 128\n    export const DISPLAY_DELAY = 300\n\n    export const DISPLAY_TYPE = 4242 // smart display\n\n    export const DISPLAY_CFG0 = 0x00000080\n    export const DISPLAY_CFG1 = 0x00000603\n    export const DISPLAY_CFG2 = 8\n\n    // mappng for big edge connector pins,\n    export const PIN_P0 = DAL.P0_2\n    export const PIN_P1 = DAL.P0_3 \n    export const PIN_P2 = DAL.P0_4\n}\n\n\n\n\n\n","device.d.ts":"// nothing here yet","pxt.json":"{\n    \"name\": \"hw---n3\",\n    \"description\": \"NRF52833 board\",\n    \"dependencies\": {\n        \"core---nrf52\": \"*\",\n        \"screen---st7735\": \"*\",\n        \"mixer---nrf52\": \"*\",\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"config.ts\",\n        \"basepins.d.ts\",\n        \"device.d.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"card\": {\n        \"name\": \"N3\",\n        \"description\": \"Board based on Nordic NRF52833\",\n        \"learnMoreUrl\": \"https://arcade.makecode.com/hardware#n3\",\n        \"cardType\": \"hw\",\n        \"imageUrl\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAB4BAMAAACHjORcAAAAD1BMVEX/gTX///8knKOkg58AAADai7jeAAAB3UlEQVRo3u2Wi3HDIAxAzQaWNhArNBuk+89U9ImNHahdrCZOgs7Hid9DEmAxfDnL0IEd+EDg93deqhwBXgCuWalyfXdgipkvMAEUKJsiC3gBpxCcDsiOXu1UOgAZYpjLpB06NpdXAzrc5XxTbrrH1VscnA58V6BmFPc/tnuSOn71zg0sJPr+WOrADuzADnwxYHSWDvxUIM4qxQj33QTSLAoByjhUZQuISHlV1iCZnj5TpBExUm4hcHcqb59ahwLD9XKoHFN0LNkkA3IHGzOtPbkRbeFZALiZVBGyKrbyDJSpBkSOkVmIsWwhTqaaNzmQXY65y+IAoMS96HLqR/Eg25R+sN8SSPL6R0fg+qaeEAhywNuB5A7ENuB657JtbYshxioQvYHgBIRJsNB4CAj3uYeOAdEbCO5AfLqFfNgAPGNYyO7tuwxg+TkurCyew11Ayc/2BKGNm7IfSBRrQGwC6tAiMLYBYw2IDcA5/LTxx94HrP/wqw/TxwKheMkOAP8iHXhC4P6s15/ETwZ2+UcJi9pY73okMMAwjlzax5SgLVyO1njrUoUH1GQMAwQ2Jin8AU8Koic1VZddWuUBvwDHYZ4FbJ8Bkxmw7toGBrFhdlk8ShHj9jDHYaHIgM+WH/pHX7EAVIxFAAAAAElFTkSuQmCC\"\n    },\n    \"compileServiceVariant\": \"nrf52833\",\n    \"cppDependencies\": {\n        \"accelerometer\": \"file:../accelerometer\"\n    },\n    \"skipLocalization\": true,\n    \"yotta\": {\n        \"optionalConfig\": {\n            \"DEVICE_JACDAC_DEBUG\": 1\n        },\n        \"config\": {\n            \"DEVICE_USB\": 0,\n            \"DEVICE_WEBUSB\": 0\n        }\n    },\n    \"dalDTS\": {\n        \"corePackage\": \"../core---nrf52\"\n    }\n}\n"},"hw---n4":{"basepins.d.ts":"//% advanced=true\ndeclare namespace pins {\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_LED)\n    const LED: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SDA)\n    const SDA: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SCL)\n    const SCL: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SCK)\n    const SCK: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_MISO)\n    const MISO: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_MOSI)\n    const MOSI: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_RX)\n    const RX: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_TX)\n    const TX: DigitalInOutPin;\n}\n","config.ts":"namespace config {\n    // all should be in bootloader\n}\n","device.d.ts":"// nothing here yet","pxt.json":"{\n    \"name\": \"hw---n4\",\n    \"description\": \"NRF52840 board\",\n    \"dependencies\": {\n        \"core---nrf52\": \"*\",\n        \"screen---st7735\": \"*\",\n        \"mixer---nrf52\": \"*\",\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"config.ts\",\n        \"basepins.d.ts\",\n        \"device.d.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"card\": {\n        \"name\": \"N4\",\n        \"description\": \"Board based on Nordic NRF52840\",\n        \"learnMoreUrl\": \"https://arcade.makecode.com/hardware#n4\",\n        \"cardType\": \"hw\",\n        \"imageUrl\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAB4BAMAAACHjORcAAAAD1BMVEX/gTUAP63///+kg58AAADcmUjBAAAB50lEQVRo3u2YC3KEIAxAHW4AJzC5Qr2B3P9MJSGIulgtZl1byThs+D2S8G27L2XpGrABLwR6n9O5VgscEMeU5vx/B4aoTRjvFYABkYAx9wRgihz9qkyKYIaMPrdshgwchzsD2V2dnZJQ8yV+fuutNuE9gd6T8/FEVAEmGRuw8sT2XndSHnNJqV/07fXVgA3YgA14OdAqSwM+FQhZddbia7VDLmbFIXA7oLb7QAA3z/IYjrrTJwoXAsjIAkSqDmn6rIwKS34cDiJHlNjWMWACUgUZM40tblBrt7IfkYpdVJgcFVgDuasAgWIkFoItWwiTqRGAHMyZy3buMnuNwHEvuhzqgT04Miltp/xloOO/n0ARuN6pNwQiL/B6oFMHQh1wPXOzaa2LIdhNIGgDUQmY/w0AhcJTQHy9e9w5IGgDUR0IH7eQFhuiZgwLt3v9LCPK/WwXVhbX4SEg38/yBHE7O+U4MD5TikCoAsamRaCtA9otIFQAc/jdzol9DLh94G8+TK8FYnGTnQD+RhrwhsDjt157En8Y2OSNYha5frvqSqDBru8plY8oJpZQ2kthqooKNdiS3nRoyJig0IfUybAe1JBdVsUsNfgB2He5F5J9Agxm4LpqH2jYhuwyexQiRuUmx2GhcINnyzfOJXvHTJa1sgAAAABJRU5ErkJggg==\"\n    },\n    \"compileServiceVariant\": \"nrf52840\",\n    \"cppDependencies\": {\n        \"accelerometer\": \"file:../accelerometer\"\n    },\n    \"skipLocalization\": true,\n    \"experimentalHw\": true,\n    \"yotta\": {\n        \"optionalConfig\": {\n            \"DEVICE_JACDAC_DEBUG\": 1\n        },\n        \"config\": {\n            \"DEVICE_USB\": 0,\n            \"DEVICE_WEBUSB\": 0\n        }\n    },\n    \"dalDTS\": {\n        \"corePackage\": \"../core---nrf52\"\n    }\n}\n"},"hw---rpi":{"config.ts":"\nnamespace config {\n    export const DISPLAY_WIDTH = 160;\n    export const DISPLAY_HEIGHT = 120;\n}\n","device.d.ts":"declare namespace input {\n}\n\ndeclare namespace control {\n    //% shim=control::programList\n    function programList() : string[];\n}","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum Key {\n    LEFT = 1,\n    UP = 2,\n    RIGHT = 3,\n    DOWN = 4,\n    A = 5,\n    B = 6,\n    MENU = 7,\n    LEFT2 = 8,\n    UP2 = 9,\n    RIGHT2 = 10,\n    DOWN2 = 11,\n    A2 = 12,\n    B2 = 13,\n    RESET = 14,\n    EXIT = 15,\n    }\n\n// Auto-generated. Do not edit. Really.\n","gamesel.cpp":"#include \"pxt.h\"\n\n#include <sys/types.h>\n#include <dirent.h>\n#include <sys/stat.h>\n#include <stdio.h>\n#include <unistd.h>\n\nnamespace control {\n\n\n//%\nRefCollection *programList() {\n    DIR *d = opendir(PROGDIR);\n    auto res = Array_::mk();\n    registerGCObj(res);\n    for (;;) {\n        struct dirent *ent = readdir(d);\n        if (!ent)\n            break;\n        int len = strlen(ent->d_name);\n        if (len <= 4)\n            continue;\n        if (strcmp(ent->d_name + len - 4, \".elf\") != 0)\n            continue;\n        ent->d_name[len - 4] = 0; // chop extension\n        //DMESG(\"add: '%s'\", ent->d_name);\n        auto tmp = (TValue)mkString(ent->d_name, -1);\n        registerGCPtr(tmp);\n        res->head.push(tmp);\n        unregisterGCPtr(tmp);\n    }\n    closedir(d);\n    unregisterGCObj(res);\n    return res;\n}\n\n/** Run specified user program. */\n//%\nvoid runProgram(String prog) {\n    char *p;\n    asprintf(&p, \"%s/%s.elf\", PROGDIR, prog->getUTF8Data());\n    initialArgv = new char*[3];\n    initialArgv[0] = p;\n    initialArgv[1] = (char*)\"--run\";\n    initialArgv[2] = 0;\n    target_reset();\n}\n\n/**\n * Deletes a user program\n */\n//%\nvoid deleteProgram(String prog) {\n    char *p;\n    asprintf(&p, \"%s/%s.elf\", PROGDIR, prog->getUTF8Data());\n    unlink(p);\n}\n\n} // namespace control\n","keys.cpp":"#include \"pxt.h\"\n\n#include <wiringPi.h>\n#include <wiringPiI2C.h>\n#include <pthread.h>\n\n#include <linux/input.h>\n#include <unistd.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\nnamespace music {\nvoid playTone(int frequency, int ms);\n}\n\nnamespace pxt {\n\nenum class Key {\n    LEFT = 1,\n    UP,\n    RIGHT,\n    DOWN,\n    A,\n    B,\n    MENU,\n    LEFT2,\n    UP2,\n    RIGHT2,\n    DOWN2,\n    A2,\n    B2,\n    RESET,\n    EXIT,\n};\n\n/*\nBTN_A = 12, 16\nBTN_B = 6, 13\nBTN_MENU = 20\nBTN_EXIT = 22, 23\nBTN_RESTART = 26\nJOYSTICK_ADDR = 0x48\n# Free pins: 4, 5, 17, 24, 25, 27\n*/\n\nconst int INTERNAL_KEY_UP = 2050;\nconst int INTERNAL_KEY_DOWN = 2051;\n\nstatic int adcFD;\n\nstatic int useScanCodes, scanCodeFD;\n\n#define SWAP(v) (uint16_t)((v >> 8) | (v << 8))\n#define MID 0x3300\n#define DEAD 0x1000\n\nstatic int readADC(int channel) {\n    if (!adcFD) {\n        int addr = getConfigInt(\"JOYSTICK_ADDR\", -1);\n        if (addr < 0)\n            adcFD = -1;\n        else\n            adcFD = wiringPiI2CSetup(0x48);\n    }\n\n    if (adcFD < 0)\n        return MID;\n\n    uint16_t config = 0x8383;\n    config += 0x4000 + 0x1000 * channel;\n\n    wiringPiI2CWriteReg16(adcFD, 0x01, SWAP(config));\n    sleep_core_us(1000);\n\n    config = wiringPiI2CReadReg16(adcFD, 0x00);\n    return SWAP(config);\n}\n\n#define SET(s) r |= 1 << (int)(Key::s)\n#define KEY(s)                                                                                     \\\n    if (isPressed(\"BTN_\" #s, (int)Key::s))                                                         \\\n    SET(s)\n\nstatic uint8_t pressedScanCodes[1024];\n\nstatic int isPressed(const char *name, int keyPos) {\n    static uint64_t parsedPin[(int)Key::EXIT + 1];\n\n    if (useScanCodes) {\n        auto pins = getConfigInts(name);\n        for (int i = 0; pins[i] != ENDMARK; ++i) {\n            auto p = pins[i];\n            if (p < (int)sizeof(pressedScanCodes) && pressedScanCodes[p])\n                return 1;\n        }\n        return 0;\n    }\n\n    if (parsedPin[keyPos] == 0) {\n        auto pins = getConfigInts(name);\n        for (int i = 0; pins[i] != ENDMARK; ++i) {\n            auto p = pins[i];\n            auto mask = 1ULL << p;\n            parsedPin[keyPos] |= mask;\n            pinMode(p, INPUT);\n            pullUpDnControl(p, PUD_UP);\n        }\n        // make sure it's non-zero\n        parsedPin[keyPos] |= 1ULL << 63;\n    }\n\n    for (int i = 0; i < 63; ++i) {\n        if ((parsedPin[keyPos] >> i) & 1)\n            if (!digitalRead(i))\n                return 1;\n    }\n\n    return 0;\n}\n\nstatic void updateScanCodes() {\n    if (!useScanCodes)\n        return;\n\n    struct input_event ev[64];\n    int rd = read(scanCodeFD, ev, sizeof(ev));\n\n    for (int i = 0; i < rd / (int)sizeof(struct input_event); i++) {\n        if (ev[i].type == 1 && ev[i].code < sizeof(pressedScanCodes))\n            pressedScanCodes[ev[i].code] = ev[i].value;\n    }\n}\n\nstatic uint16_t ch0, ch1;\nstatic uint32_t state;\n\nstatic uint32_t readBtns() {\n    uint32_t r = 0;\n\n    updateScanCodes();\n\n    KEY(A);\n    KEY(B);\n    KEY(LEFT);\n    KEY(RIGHT);\n    KEY(UP);\n    KEY(DOWN);\n    KEY(MENU);\n    KEY(EXIT);\n    KEY(RESET);\n\n    KEY(A2);\n    KEY(B2);\n    KEY(LEFT2);\n    KEY(RIGHT2);\n    KEY(UP2);\n    KEY(DOWN2);\n\n    ch0 = readADC(0);\n    ch1 = readADC(1);\n\n    if (ch0 < MID - DEAD)\n        SET(UP);\n    if (ch0 > MID + DEAD)\n        SET(DOWN);\n\n    if (ch1 < MID - DEAD)\n        SET(LEFT);\n    if (ch1 > MID + DEAD)\n        SET(RIGHT);\n\n    return r;\n}\n\n//% expose\nint pressureLevelByButtonId(int btnId, int codalId) {\n    int inv = 0;\n    int v = 0;\n\n    switch ((Key)btnId) {\n    case Key::DOWN:\n        v = ch0;\n        inv = 1;\n        break;\n    case Key::UP:\n        v = ch0;\n        inv = -1;\n        break;\n    case Key::RIGHT:\n        v = ch1;\n        inv = 1;\n        break;\n    case Key::LEFT:\n        v = ch1;\n        inv = -1;\n        break;\n    default:\n        break;\n    }\n\n    if (adcFD < 0 || inv == 0) {\n        return (state & (1 << btnId)) ? 512 : 0;\n    }\n\n    int dead = DEAD / 4;\n\n    v = (v - MID) * inv;\n    v = (v - dead) * 512 / (MID - dead);\n\n    if (v < 0)\n        v = 0;\n    if (v > 512)\n        v = 512;\n\n    return v;\n}\n\nstatic void *btnPoll(void *dummy) {\n    (void)dummy;\n\n    state = readBtns();\n    int k = 0;\n    while (1) {\n        sleep_core_us(5000);\n        uint32_t nstate = readBtns();\n\n        if (k++ % 30 == 0) {\n            // DMESG(\"CH0 %p CH1 %p\", readADC(0), readADC(1));\n        }\n\n        if (state != nstate) {\n            for (int i = 1; i < 32; ++i) {\n                uint32_t mask = 1 << i;\n                int ev = 0;\n                if ((state & mask) && !(nstate & mask))\n                    ev = INTERNAL_KEY_UP;\n                else if (!(state & mask) && (nstate & mask)) {\n                    ev = INTERNAL_KEY_DOWN;\n                    if (i == (int)Key::EXIT)\n                        target_exit();\n                    else if (i == (int)Key::RESET)\n                        target_reset();\n                }\n                if (ev) {\n                    // DMESG(\"evt: %d at %d\", ev, i);\n                    raiseEvent(ev, i);\n                    raiseEvent(ev, 0); // any key\n                }\n            }\n            state = nstate;\n        }\n    }\n\n    return NULL;\n}\n\nvoid initKeys() {\n    DMESG(\"init keys\");\n    // music::playTone(0, 0); // start music process early\n\n    sleep_core_us(200000); // make sure screen update starts to avoid race on config\n\n    if (getConfigString(\"SCAN_CODES\")) {\n        useScanCodes = 1;\n        scanCodeFD = open(getConfigString(\"SCAN_CODES\"), O_RDONLY);\n        if (scanCodeFD < 0) {\n            DMESG(\"can't open %s\", getConfigString(\"SCAN_CODES\"));\n            return;\n        }\n    } else {\n        wiringPiSetupGpio();\n    }\n\n    pthread_t disp;\n    pthread_create(&disp, NULL, btnPoll, NULL);\n    pthread_detach(disp);\n}\n\n//% expose\nvoid setupButton(int buttonId, int key) {\n    (void)buttonId;\n    (void)key;\n    // not needed on RPi\n}\n\n} // namespace pxt\n","pxt.json":"{\n    \"name\": \"hw---rpi\",\n    \"description\": \"Raspberry Pi\",\n    \"dependencies\": {\n        \"core---linux\": \"*\",\n        \"mixer---linux\": \"*\",\n        \"screen---linux\": \"*\",\n        \"settings---files\": \"*\",\n        \"controller---none\": \"*\",\n        \"serial---linux\": \"*\",\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"keys.cpp\",\n        \"config.ts\",\n        \"gamesel.cpp\",\n        \"enums.d.ts\",\n        \"shims.d.ts\",\n        \"device.d.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"card\": {\n        \"name\": \"Pi0\",\n        \"description\": \"Raspberry Pi Zero (custom piCore Linux image)\",\n        \"learnMoreUrl\": \"https://arcade.makecode.com/hardware#pi0\",\n        \"cardType\": \"hw\",\n        \"imageUrl\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAB4BAMAAACHjORcAAAAD1BMVEUAAAD/k8T/9gn/gTX///8CbOdcAAAB3klEQVRo3u1aQW7EIAyMlBcg+QXNB1D8AiT//01lsONuKZUQzWGjethmhMdMsAu9dLd0Mx5iKIlKYzwBEWUy1iRHr4mI65saqRVslan0LoQUQ695vhuKFCyAABY3EDcSDNJ5p9m6zlALF11oBiQ287lmpE6jHyUT3qBvFHFDHdZPMHYiauCataoztL3Z+23hNRSqK3fa2LCVYz1MtlvEXnqIsMdfNYs/6WC/t2Hg7/i4Gf/WkG0ABx/nwWebg9cMmc/LUJk9dovhwWbIq4YHytTFYAzEeL2Hx4mnglsfEVvuIVArvPi9js1TwdubYedcN8XKDN4q58p7hg5+zZkAwyiDMzxgaMNUz6nPmR1qMhj5A0PPYZ4wZIx9z+BaHAJu4i/0nAmgR7ACaw+zl6lgz4G2jFqhc+Am7Hf3cuIMdudMjwx4cOXmDZFmhzqDYTS4cvMl4+1uyMrDKzffQ/5arL1fuXIO/1MFI+y2+gyvXKXlX2JcuUAgEAgEAoFAIBAIBAKBQOA7HvAf8F8VfMPDQfVHOmnCUIp/6ipKBVZF6pSoeqqUXNIpEsaGWEJ42lqSFiRCvCSSTrIp9AlDfFpxlJphpV7yKf1espAVIlfhMGxx74YmeMlIeNgXJ+42/ASw+1fGCliG7AAAAABJRU5ErkJggg==\"\n    },\n    \"compileServiceVariant\": \"rpi\",\n    \"skipLocalization\": true\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace control {\n\n    /** Run specified user program. */\n    //% shim=control::runProgram\n    function runProgram(prog: string): void;\n\n    /**\n     * Deletes a user program\n     */\n    //% shim=control::deleteProgram\n    function deleteProgram(prog: string): void;\n}\n\n// Auto-generated. Do not edit. Really.\n"},"hw---samd51":{"basepins.d.ts":"//% advanced=true\ndeclare namespace pins {\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_LED)\n    const LED: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SDA)\n    const SDA: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SCL)\n    const SCL: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SCK)\n    const SCK: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_MISO)\n    const MISO: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_MOSI)\n    const MOSI: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_RX)\n    const RX: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_TX)\n    const TX: DigitalInOutPin;\n}\n","config.ts":"namespace config {\n    // all from bootloader\n}\n","device.d.ts":"// \n","pxt.json":"{\n    \"name\": \"hw---samd51\",\n    \"description\": \"SAMD51 board\",\n    \"dependencies\": {\n        \"core---samd\": \"*\",\n        \"screen---st7735\": \"*\",\n        \"mixer---samd\": \"*\",\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"config.ts\",\n        \"basepins.d.ts\",\n        \"device.d.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"card\": {\n        \"name\": \"D5\",\n        \"description\": \"Board based on Microchip ATSAMD51\",\n        \"learnMoreUrl\": \"https://arcade.makecode.com/hardware#d5\",\n        \"cardType\": \"hw\",\n        \"imageUrl\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAB4BAMAAACHjORcAAAAD1BMVEUAP6143FL/gTX///8AAACgtqsbAAABr0lEQVRo3u2WgY2DMAxFI2WCk24CsoDFnwCJ/Wc622lwUxpVgHWlNF+p9eOYRwiUEH6c1YEd+I/A31k1mZfeESBUk3nWVwB53fyAMwvIQJebMlVRdWKgXrAjUPWFQMfHZlYBTsCS6cArAu31NavcX7B+m5T5awPXG/10rk+RDuzADuzADnwF7OryEZmNIWA9HKFpNRFcbuYVkCjmrinGwDluxbCKMYGHJZZ2KxLYI5AybTFam41J+jKZ5dxkRTHUAiQdswm0mOrMecCAPATxVraeIRUjMqBdskZr0C7ZWtfAADH1TQldV1SEiByBGs8NRMAhYHQH0j4gQA0g9q0hhSaQvIFwAmIRPUkeAmK998RjQPIGwh1Ib59hBDHAcw1Jfl53GdCCqPYZkDYCKWolqW38U7YDI4cGkLYDNTaBYR8wtIC0A4iiZ8CwHSihXXgCIO7lAKzVgZ8HxE39a/30GpzVgXdKVW+sht4GTBjGkWNpQkk5I1GMRZYaLmgCxzQgDaMYbZCDknpwEg9DuctqA4VmR0Hml4EyQzwOVcDmJWu0xgcnzaclY6YUXOU53Kk/Y5YfN7mU0qQAAAAASUVORK5CYII=\"\n    },\n    \"compileServiceVariant\": \"samd51\",\n    \"cppDependencies\": {\n        \"accelerometer\": \"file:../accelerometer\",\n        \"lightsensor\": \"file:../lightsensor\"\n    },\n    \"yotta\": {\n        \"optionalConfig\": {\n            \"DEVICE_JACDAC_DEBUG\": 1\n        },\n        \"config\": {\n            \"DEVICE_USB\": 1,\n            \"DEVICE_WEBUSB\": 1\n        }\n    },\n    \"skipLocalization\": true,\n    \"dalDTS\": {\n        \"corePackage\": \"../core---samd\"\n    }\n}\n"},"hw---stm32f401":{"basepins.d.ts":"//% advanced=true\ndeclare namespace pins {\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_LED)\n    const LED: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SDA)\n    const SDA: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SCL)\n    const SCL: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SCK)\n    const SCK: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_MISO)\n    const MISO: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_MOSI)\n    const MOSI: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_RX)\n    const RX: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_TX)\n    const TX: DigitalInOutPin;\n}\n","config.ts":"namespace config {\n    // all defined in bootloader\n}\n","device.d.ts":"// \n","pxt.json":"{\n    \"name\": \"hw---stm32f401\",\n    \"description\": \"STM32F4 board\",\n    \"dependencies\": {\n        \"core---stm32\": \"*\",\n        \"screen---st7735\": \"*\",\n        \"mixer---stm32\": \"*\",\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"config.ts\",\n        \"basepins.d.ts\",\n        \"device.d.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"card\": {\n        \"name\": \"F4\",\n        \"description\": \"Board based on STM32F4xx\",\n        \"learnMoreUrl\": \"https://arcade.makecode.com/hardware#f4\",\n        \"cardType\": \"hw\",\n        \"imageUrl\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAB4BAMAAACHjORcAAAAD1BMVEUAP62OLsT/gTX///8AAAAWHMbsAAABvklEQVRo3u2WDW7DIAyFkTjBpJ4gXMCKTxAp9z/TbEPcNJRtJdbKMj9R6xnMF35SteHDWA504C8Cb2vRovlyDohFi+b/C0gnaADUS5HsNFA3OzDwvuF1NQEKROHGwOU2MDC/gze7SxFnAlz2bnDgSpKNGwFVDuwFrqvVpdT5tYF0Ysd8rL8iDnSgAx3owO+ALpeN4G5jCFgPR+RuMdSoXGL8CRAgllQVI03l7mLKgw9PRhrmuLVcBAw7AiHT1EgtRQaoeIAXo89mSK6udoIIPJ1NIYsRp8oDCmQelhVSe75C2Ayp8B+3LHHXJIV86DUwoBi9FPm4rqiILDAEShwbiAFPAaM5EPqAzZuL2HeGEJpAsAaiERBV8KTzFBDr3554DgjWQDQHwttXGBEIYHmGwB+rW0aUglhsDYQXgRD1DMXW35QeYKTQAEIHkGMTGPqAoQWEDiBuegYMrwOb00UDAHGvTmBbDvx7QNwUXINrMpYDd0oP2VwNvQWYcJpnjqUxJeUejmI0ksRQQRM4pwnTNLORhjwpiSc742Eop6Q2UGg6C3l9GcgrxOOQAr/cssR7o8lJ+pP2qNGCq7yHnfoEQuYXTuqHoj8AAAAASUVORK5CYII=\"\n    },\n    \"compileServiceVariant\": \"stm32f401\",\n    \"cppDependencies\": {\n        \"accelerometer\": \"file:../accelerometer\",\n        \"lightsensor\": \"file:../lightsensor\"\n    },\n    \"skipLocalization\": true,\n    \"yotta\": {\n        \"optionalConfig\": {\n            \"DEVICE_JACDAC_DEBUG\": 1\n        },\n        \"config\": {\n            \"DEVICE_USB\": 1,\n            \"DEVICE_WEBUSB\": 1,\n            \"PXT_DEFAULT_ACCELEROMETER\": \"ACCELEROMETER_TYPE_MMA8453\"\n        }\n    },\n    \"dalDTS\": {\n        \"corePackage\": \"../core---stm32\"\n    }\n}\n"},"hw---rp2040":{"basepins.d.ts":"//% advanced=true\ndeclare namespace pins {\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_LED)\n    const LED: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SDA)\n    const SDA: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SCL)\n    const SCL: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_SCK)\n    const SCK: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_MISO)\n    const MISO: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_MOSI)\n    const MOSI: DigitalInOutPin;\n\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_RX)\n    const RX: DigitalInOutPin;\n    //% fixedInstance shim=pxt::getPinCfg(CFG_PIN_TX)\n    const TX: DigitalInOutPin;\n}\n","config.ts":"namespace config {\n    // in flash now\n}","device.d.ts":"// nothing here yet","pxt.json":"{\n    \"name\": \"hw---rp2040\",\n    \"description\": \"RP2040 board\",\n    \"dependencies\": {\n        \"core---rp2040\": \"*\",\n        \"screen---st7735\": \"*\",\n        \"mixer---rp2040\": \"*\",\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"config.ts\",\n        \"basepins.d.ts\",\n        \"device.d.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"card\": {\n        \"name\": \"R2\",\n        \"description\": \"Board based on Raspberry Pi RP2040\",\n        \"learnMoreUrl\": \"https://arcade.makecode.com/hardware#r2\",\n        \"cardType\": \"hw\",\n        \"imageUrl\": \"/static/hardware/rpi-pico.jpg\"\n    },\n    \"compileServiceVariant\": \"rp2040\",\n    \"cppDependencies\": {\n        \"accelerometer\": \"file:../accelerometer\"\n    },\n    \"skipLocalization\": true,\n    \"yotta\": {\n        \"optionalConfig\": {\n            \"DEVICE_JACDAC_DEBUG\": 1\n        },\n        \"config\": {\n            \"DEVICE_USB\": 1,\n            \"DEVICE_WEBUSB\": 1\n        }\n    },\n    \"dalDTS\": {\n        \"corePackage\": \"../core---rp2040\"\n    }\n}\n"},"hw---vm":{"config.ts":"\nnamespace config {\n    export const DISPLAY_WIDTH = 160;\n    export const DISPLAY_HEIGHT = 120;\n}\n\ncontrol.internalOnEvent(INTERNAL_KEY_DOWN, 100, () => control.reset())\n","device.d.ts":"declare namespace control {\n}","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum Key {\n    KEY_LEFT = 1,\n    KEY_UP = 2,\n    KEY_RIGHT = 3,\n    KEY_DOWN = 4,\n    KEY_A = 5,\n    KEY_B = 6,\n    KEY_MENU = 7,\n    KEY_RESET = 100,\n    KEY_EXIT = 101,\n    }\n\n// Auto-generated. Do not edit. Really.\n","pxt.json":"{\n    \"name\": \"hw---vm\",\n    \"description\": \"VM\",\n    \"dependencies\": {\n        \"core---vm\": \"*\",\n        \"mixer---ext\": \"*\",\n        \"screen---ext\": \"*\",\n        \"settings---files\": \"*\",\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"sdlmain.cpp\",\n        \"config.ts\",\n        \"enums.d.ts\",\n        \"shims.d.ts\",\n        \"device.d.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"card\": {\n        \"name\": \"VM\",\n        \"description\": \"VM\",\n        \"learnMoreUrl\": \"https://arcade.makecode.com/hardware#vm\",\n        \"cardType\": \"hw\"\n    },\n    \"compileServiceVariant\": \"vm\",\n    \"skipLocalization\": true,\n    \"experimentalHw\": true\n}\n","sdlmain.cpp":"#include \"SDL.h\"\n#include <stdint.h>\n#include <stdio.h>\n#include <ctype.h>\n\n#if UINTPTR_MAX == 0xffffffff\n#define BINSUFF \"-32\"\n#elif UINTPTR_MAX == 0xffffffffffffffff\n#define BINSUFF \"\"\n#else\n#error \"UINTPTR_MAX has invalid value\"\n#endif\n\n#if defined(__IPHONEOS__) || defined(__ANDROID__)\n#define PXT_STATIC 1\n#define PXT_TOUCH 1\n#define PXT_IOS 1\n#endif\n\n#if defined(__WINDOWS__)\n#include <windows.h>\n#define WIN_StringToUTF8(S)                                                                        \\\n    SDL_iconv_string(\"UTF-8\", \"UTF-16LE\", (char *)(S), (SDL_wcslen(S) + 1) * sizeof(WCHAR))\n#define WIN_UTF8ToString(S)                                                                        \\\n    (WCHAR *)SDL_iconv_string(\"UTF-16LE\", \"UTF-8\", (char *)(S), SDL_strlen(S) + 1)\n#endif\n\n#ifndef PXT_STATIC\n#if defined(__MACOSX__)\n#define SONAME \"libpxt\" BINSUFF \".dylib\"\n#elif defined(__WINDOWS__)\n#define SONAME \"pxt\" BINSUFF \".dll\"\n#else\n#define SONAME \"libpxt\" BINSUFF \".so\"\n#endif\n#endif\n\n#define WIDTH 160\n#define HEIGHT 120\n\nint win_width, win_height;\n\nSDL_Rect activeDisplayRect;\n\nSDL_Renderer *renderer;\n\nconst int SCREEN_WIDTH = WIDTH * 4;\nconst int SCREEN_HEIGHT = HEIGHT * 4;\n\nconst int INTERNAL_KEY_UP = 2050;\nconst int INTERNAL_KEY_DOWN = 2051;\n\nenum Key {\n    KEY_LEFT = 1,\n    KEY_UP,\n    KEY_RIGHT,\n    KEY_DOWN,\n    KEY_A,\n    KEY_B,\n    KEY_MENU,\n    KEY_RESET = 100, // passed as event to TS, which does control.reset()\n    KEY_EXIT,        // handled here\n};\n\nint mapKeyCode(int sdlCode) {\n    switch (sdlCode) {\n    case SDLK_ESCAPE:\n        return KEY_EXIT;\n    case '/':\n        return KEY_RESET;\n    case 'a':\n    case SDLK_LEFT:\n        return KEY_LEFT;\n    case 'd':\n    case SDLK_RIGHT:\n        return KEY_RIGHT;\n    case 'w':\n    case SDLK_UP:\n        return KEY_UP;\n    case 's':\n    case SDLK_DOWN:\n        return KEY_DOWN;\n    case ' ':\n    case 'q':\n    case 'z':\n        return KEY_A;\n    case 'x':\n    case 'e':\n    case SDLK_RETURN:\n        return KEY_B;\n\n    case 'm':\n        return KEY_MENU;\n\n    case 'j':\n        return KEY_LEFT + 7;\n    case 'i':\n        return KEY_UP + 7;\n    case 'l':\n        return KEY_RIGHT + 7;\n    case 'k':\n        return KEY_DOWN + 7;\n    case 'u':\n        return KEY_A + 7;\n    case 'o':\n        return KEY_B + 7;\n\n    default:\n        return 0;\n    }\n}\n\ntypedef void (*get_pixels_t)(int width, int height, uint32_t *screen);\ntypedef void (*raise_event_t)(int src, int val);\ntypedef void (*vm_start_t)(const char *fn);\ntypedef void (*vm_start_buffer_t)(uint8_t *data, unsigned len);\ntypedef int (*get_logs_t)(int logtype, char *dst, int maxSize);\ntypedef int (*get_panic_code_t)();\ntypedef void (*get_audio_samples_t)(int16_t *buf, unsigned numSamples);\n\n#ifdef PXT_STATIC\nextern \"C\" {\nvoid pxt_screen_get_pixels(int width, int height, uint32_t *screen);\nvoid pxt_raise_event(int src, int val);\nvoid pxt_vm_start(const char *fn);\nvoid pxt_vm_start_buffer(uint8_t *data, unsigned len);\nint pxt_get_logs(int logtype, char *dst, int maxSize);\nint pxt_get_panic_code();\nvoid pxt_get_audio_samples(int16_t *buf, unsigned numSamples);\n}\n#else\nget_audio_samples_t pxt_get_audio_samples;\nraise_event_t pxt_raise_event;\nvm_start_buffer_t pxt_vm_start_buffer;\n#endif\n\nint exitReq;\n\nvoid raise_key(Key k, int ev) {\n    if (k == KEY_EXIT && ev == INTERNAL_KEY_UP)\n        exitReq = 1;\n    pxt_raise_event(ev, k);\n    pxt_raise_event(ev, 0); // any\n}\n\nvoid fatal(const char *msg, const char *info = \"\") {\n    SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, \"%s %s (SDL Error: %s)\", msg, info ? info : \"\",\n                    SDL_GetError());\n    exit(1);\n}\n\n#ifndef PXT_TOUCH\nvoid init_touch_keys() {}\nvoid draw_touch_keys() {}\nvoid handle_touch_events(SDL_Event &) {}\n#else\nstruct OnScreenKey {\n    Key keyId;\n    SDL_Point center;\n    char name;\n    bool isPressed, prevPressed;\n};\n\nstruct TrackedFinger {\n    SDL_FingerID fingerId;\n    OnScreenKey *lastKey, *secondLastKey;\n};\n\n#define NUM_FINGERS 10\n#define NUM_KEYS 8\n\nOnScreenKey keys[NUM_KEYS];\nTrackedFinger fingers[NUM_FINGERS];\n\nint distance(SDL_Point &a, SDL_Point &b) {\n    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);\n}\n\nvoid add_key(Key kid, char name, int x, int y) {\n    for (int i = 0; i < NUM_KEYS; ++i) {\n        if (keys[i].keyId == 0) {\n            auto k = &keys[i];\n            k->keyId = kid;\n            k->center.x = x;\n            k->center.y = y;\n            k->name = name;\n            break;\n        }\n    }\n}\n\nvoid init_touch_keys() {\n    int widthLeft = activeDisplayRect.x;\n    int widthRight = win_width - activeDisplayRect.x - activeDisplayRect.w;\n\n    int kps = widthLeft / 2 - 10;\n    if (kps > win_height / 6)\n        kps = win_height / 6;\n    int kpx = widthLeft / 2;\n    int menuY = win_height / 10;\n    int kpy = win_height / 2 + menuY;\n\n    add_key(KEY_MENU, 'M', kpx - kps, menuY);\n    add_key(KEY_EXIT, 'E', kpx + kps, menuY);\n\n    add_key(KEY_LEFT, '<', kpx - kps, kpy);\n    add_key(KEY_RIGHT, '<', kpx + kps, kpy);\n    add_key(KEY_UP, '^', kpx, kpy - kps);\n    add_key(KEY_DOWN, 'v', kpx, kpy + kps);\n\n    int abx = win_width - widthRight / 2;\n    int ay = win_height / 2 - kps;\n    int by = win_height / 2 + kps;\n\n    add_key(KEY_A, 'A', abx, ay);\n    add_key(KEY_B, 'B', abx, by);\n}\n\nvoid draw_touch_keys() {\n    SDL_Rect keyR;\n    int sz = 3;\n    keyR.w = sz * 2;\n    keyR.h = sz * 2;\n    for (int i = 0; i < NUM_KEYS; ++i) {\n        SDL_SetRenderDrawColor(renderer, 255, keys[i].isPressed ? 255 : 0, 0, 255);\n        keyR.x = keys[i].center.x - sz;\n        keyR.y = keys[i].center.y - sz;\n        SDL_RenderFillRect(renderer, &keyR);\n    }\n}\n\nvoid handle_touch_events(SDL_Event &e) {\n    if (e.type == SDL_FINGERDOWN || e.type == SDL_FINGERUP || e.type == SDL_FINGERMOTION) {\n        SDL_Point p;\n        p.x = e.tfinger.x * win_width;\n        p.y = e.tfinger.y * win_height;\n\n        int i, firstFree = -1;\n        for (i = 0; i < NUM_FINGERS; ++i) {\n            if (fingers[i].lastKey) {\n                if (fingers[i].fingerId == e.tfinger.fingerId)\n                    break;\n            } else {\n                if (firstFree == -1)\n                    firstFree = i;\n            }\n        }\n\n        if (e.type == SDL_FINGERUP) {\n            if (i != NUM_FINGERS)\n                fingers[i].lastKey = NULL;\n        } else {\n            if (i == NUM_FINGERS) {\n                i = firstFree;\n                if (i == -1)\n                    fatal(\"too many fingers?\");\n            }\n            fingers[i].fingerId = e.tfinger.fingerId;\n            auto nearest = &keys[0];\n            auto nearestDistance = -1;\n            for (int j = 0; j < NUM_KEYS; ++j) {\n                auto dist = distance(p, keys[j].center);\n                if (nearestDistance == -1 || nearestDistance > dist) {\n                    nearestDistance = dist;\n                    nearest = &keys[j];\n                }\n            }\n\n            fingers[i].secondLastKey = NULL;\n            auto minDistance = (win_height / 5) * (win_height / 5);\n            if (nearestDistance > minDistance)\n                nearest = NULL;\n            else {\n                auto secondNearest = &keys[0];\n                auto secondNearestDist = -1;\n                for (int j = 0; j < NUM_KEYS; ++j) {\n                    if (&keys[j] == nearest)\n                        continue;\n                    auto dist = distance(p, keys[j].center);\n                    if (secondNearestDist == -1 || secondNearestDist > dist) {\n                        secondNearestDist = dist;\n                        secondNearest = &keys[j];\n                    }\n                }\n\n                auto maxDist = nearestDistance * 16 / 10;\n                if (secondNearestDist < maxDist) {\n                    fingers[i].secondLastKey = secondNearest;\n                }\n            }\n\n            fingers[i].lastKey = nearest;\n        }\n\n        for (int j = 0; j < NUM_KEYS; ++j) {\n            keys[j].prevPressed = keys[j].isPressed;\n            keys[j].isPressed = false;\n        }\n\n        for (int i = 0; i < NUM_FINGERS; ++i) {\n            if (fingers[i].lastKey)\n                fingers[i].lastKey->isPressed = true;\n            if (fingers[i].secondLastKey)\n                fingers[i].secondLastKey->isPressed = true;\n        }\n\n        for (int j = 0; j < NUM_KEYS; ++j) {\n            if (keys[j].prevPressed != keys[j].isPressed)\n                raise_key(keys[j].keyId, keys[j].isPressed ? INTERNAL_KEY_DOWN : INTERNAL_KEY_UP);\n        }\n    }\n}\n#endif\n\n#define SDL_CHECK(call)                                                                            \\\n    if (!(call)) {                                                                                 \\\n        fatal(\"SDL Call error\", #call);                                                            \\\n    }\n\n#ifndef PXT_STATIC\nvoid *loadPXTLib(char *argv[]) {\n    const char *exename = argv[0];\n    if (exename == NULL || !strchr(exename, '/'))\n        exename = \"./vm\";\n    int solen = strlen(exename) + strlen(SONAME);\n    char namebuf[solen + 1];\n    strcpy(namebuf, exename);\n    strcpy(strrchr(namebuf, '/') + 1, SONAME);\n\n    void *vmDLL = SDL_LoadObject(namebuf);\n    if (!vmDLL) {\n        fatal(\"can't load DLL\", namebuf);\n    }\n\n    return vmDLL;\n}\n#endif\n\nchar logtmp[64 * 1024];\n\nvoid flush_logs(get_logs_t get_logs) {\n    while (1) {\n        int sz = get_logs(0, logtmp, sizeof(logtmp) - 1);\n        if (sz <= 0)\n            break;\n        for (int i = 0; i < sz;) {\n            int j;\n            for (j = i; j < sz; ++j) {\n                if (logtmp[j] == '\\n') {\n                    break;\n                }\n            }\n            logtmp[j] = 0;\n            SDL_Log(\"%s\", logtmp + i);\n            i = j + 1;\n        }\n    }\n}\n\nvoid audioCallback(void *userdata, Uint8 *stream, int len) {\n    pxt_get_audio_samples((int16_t *)stream, len / 2);\n}\n\nSDL_AudioDeviceID audioDev;\nvoid openAudio() {\n    SDL_AudioSpec wanted, actual;\n\n    SDL_zero(wanted);\n    SDL_zero(actual);\n    wanted.freq = 44100;\n    wanted.format = AUDIO_S16SYS;\n    wanted.channels = 1;\n    wanted.samples = 1024;\n    wanted.callback = audioCallback;\n\n    int n = SDL_GetNumAudioDevices(0);\n    for (int i = 0; i < n; ++i) {\n        SDL_Log(\"audio %d %s\", i, SDL_GetAudioDeviceName(i, 0));\n    }\n\n    audioDev = SDL_OpenAudioDevice(NULL, 0, &wanted, &actual, 0);\n\n    // SDL_CHECK(SDL_OpenAudio(&wanted, &actual) == 0);\n\n    SDL_Log(\"audio device %d Hz, %d ch, %d sampl\", actual.freq, actual.channels, actual.samples);\n}\n\nstatic void SDLCALL logOutput(void *userdata, int category, SDL_LogPriority priority,\n                              const char *message) {\n    (void)userdata;\n\n#if defined(__WINDOWS__)\n    static HANDLE stdoutHandle;\n\n    if (!stdoutHandle) {\n        AttachConsole(ATTACH_PARENT_PROCESS);\n        stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);\n    }\n\n    unsigned len = strlen(message) + 2;\n    char msgNL[len + 1];\n    strcpy(msgNL, message);\n    strcat(msgNL, \"\\r\\n\");\n\n    OutputDebugString(msgNL);\n\n    unsigned long charsWritten;\n    WriteFile(stdoutHandle, msgNL, len, &charsWritten, NULL);\n#else\n    fprintf(stderr, \"%s\\n\", message);\n#endif\n}\n\n#ifdef PXT_IOS\nextern \"C\" void fetchSources(const char *scriptId);\nextern \"C\" void initCache();\n#endif\n\nextern \"C\" int main(int argc, char *argv[]) {\n#ifdef PXT_IOS\n    initCache();\n#endif\n\n    SDL_LogSetAllPriority(SDL_LOG_PRIORITY_INFO);\n\n    SDL_LogSetOutputFunction(logOutput, NULL);\n\n#ifndef PXT_STATIC\n    SDL_Log(\"loading %s ...\", SONAME);\n\n    void *vmDLL = loadPXTLib(argv);\n    get_pixels_t pxt_screen_get_pixels =\n        (get_pixels_t)SDL_LoadFunction(vmDLL, \"pxt_screen_get_pixels\");\n    vm_start_t pxt_vm_start = (vm_start_t)SDL_LoadFunction(vmDLL, \"pxt_vm_start\");\n    pxt_vm_start_buffer = (vm_start_buffer_t)SDL_LoadFunction(vmDLL, \"pxt_vm_start_buffer\");\n    pxt_raise_event = (raise_event_t)SDL_LoadFunction(vmDLL, \"pxt_raise_event\");\n    get_logs_t pxt_get_logs = (get_logs_t)SDL_LoadFunction(vmDLL, \"pxt_get_logs\");\n    get_panic_code_t pxt_get_panic_code =\n        (get_panic_code_t)SDL_LoadFunction(vmDLL, \"pxt_get_panic_code\");\n    pxt_get_audio_samples = (get_audio_samples_t)SDL_LoadFunction(vmDLL, \"pxt_get_audio_samples\");\n\n    if (!pxt_screen_get_pixels || !pxt_vm_start || !pxt_vm_start_buffer || !pxt_raise_event ||\n        !pxt_get_logs || !pxt_get_panic_code || !pxt_get_audio_samples) {\n        fatal(\"can't load pxt function from DLL\", \"\");\n    }\n#endif\n\n    SDL_CHECK(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) >= 0);\n\n    SDL_Window *window =\n        SDL_CreateWindow(\"MakeCode Arcade64\", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,\n                         SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);\n\n    SDL_GetWindowSize(window, &win_width, &win_height);\n\n    SDL_CHECK(window != NULL);\n\n    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);\n\n    SDL_Surface *surf;\n    surf = SDL_CreateRGBSurfaceWithFormat(0, WIDTH, HEIGHT, 32, SDL_PIXELFORMAT_BGRA32);\n\n    SDL_CHECK(surf != NULL);\n\n    openAudio();\n\n    memset(surf->pixels, 0, HEIGHT * WIDTH * 4);\n\n    SDL_Texture *tex = SDL_CreateTextureFromSurface(renderer, surf);\n\n    int ww2 = win_height * 4 / 3;\n    int freeSpace = win_width - ww2;\n    int widthLeft = 3 * freeSpace / 4;\n    activeDisplayRect.x = widthLeft;\n    activeDisplayRect.y = 0;\n    activeDisplayRect.h = win_height;\n    activeDisplayRect.w = ww2;\n\n    init_touch_keys();\n\n    SDL_RenderClear(renderer);\n    SDL_RenderCopy(renderer, tex, NULL, &activeDisplayRect);\n    SDL_RenderPresent(renderer);\n\n    int now = SDL_GetTicks();\n    int nextLoad = now + 100;\n    int lastLoad = 0;\n\n    SDL_Event e;\n    int quit = 0;\n    int numFr = 0;\n    int prevTicks = SDL_GetTicks();\n\n    const char *imageName = argv[1];\n#ifdef PXT_IOS\n    const char *imageID = NULL;\n    imageName = \"menu.pxt64\";\n#endif\n\n    while (!quit) {\n        now = SDL_GetTicks();\n\n        if (nextLoad && now >= nextLoad) {\n#ifdef PXT_IOS\n            if (imageID) {\n                fetchSources(imageID);\n                imageID = NULL;\n            } else\n#endif\n                pxt_vm_start(imageName);\n            SDL_PauseAudioDevice(audioDev, 0);\n            // SDL_PauseAudio(0);\n            nextLoad = 0;\n            lastLoad = now;\n        }\n\n        while (SDL_PollEvent(&e)) {\n            if (e.type == SDL_QUIT) {\n                quit = 1;\n            }\n            if ((e.type == SDL_KEYDOWN || e.type == SDL_KEYUP) && !e.key.repeat) {\n                int ev = e.type == SDL_KEYDOWN ? INTERNAL_KEY_DOWN : INTERNAL_KEY_UP;\n                auto kk = (Key)mapKeyCode(e.key.keysym.sym);\n                if (kk == KEY_EXIT) {\n                    quit = 1;\n                    break;\n                }\n                if (kk)\n                    raise_key(kk, ev);\n            }\n#ifdef PXT_IOS\n            if (e.type == SDL_DROPFILE) {\n                char *p = e.drop.file;\n                while (*p && *p != ':')\n                    p++;\n                while (*p && (*p == ':' || *p == '/'))\n                    p++;\n                char *beg = p;\n                if (*p == '_') {\n                    p++;\n                    while (isalnum(*p))\n                        p++;\n                } else if (isdigit(*p)) {\n                    while (isdigit(*p) || *p == '-')\n                        p++;\n                }\n                if (p - beg > 8) {\n                    *p = 0;\n                    nextLoad = now + 300;\n                    SDL_free((void *)imageID);\n                    imageID = SDL_strdup(beg);\n                }\n                SDL_free(e.drop.file);\n            }\n#endif\n\n            if (e.type == SDL_MOUSEBUTTONDOWN) {\n                // quit = 1;\n            }\n            handle_touch_events(e);\n        }\n\n        pxt_screen_get_pixels(WIDTH, HEIGHT, (uint32_t *)surf->pixels);\n\n        SDL_UpdateTexture(tex, NULL, surf->pixels, WIDTH * 4);\n\n        SDL_SetRenderDrawColor(renderer, 40, 40, 40, 255);\n        SDL_RenderClear(renderer);\n        SDL_RenderCopy(renderer, tex, NULL, &activeDisplayRect);\n\n        draw_touch_keys();\n        SDL_RenderPresent(renderer);\n\n        flush_logs(pxt_get_logs);\n\n        if (exitReq) {\n            if (!nextLoad && now > 2000 + lastLoad) {\n                SDL_Log(\"exit at key request\");\n                nextLoad = now;\n            }\n            exitReq = 0;\n        }\n\n        if (!nextLoad) {\n            int code = pxt_get_panic_code();\n            if (code == -1) {\n                // restart done in user code\n            } else if (code >= 1000) {\n                SDL_Log(\"hit soft crash, code=%d; restarting\", code - 1000);\n                nextLoad = now + 3000;\n            } else if (code != 0) {\n                SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, \"fatal runtime error %d; bye\", code);\n                exit(1);\n            }\n        }\n\n        numFr++;\n        int now = SDL_GetTicks();\n        if (now - prevTicks > 1000) {\n            // printf(\"fps=%d\\n\", numFr);\n            prevTicks = now;\n            numFr = 0;\n        }\n\n#ifdef PXT_IOS\n        SDL_Delay(25);\n#endif\n    }\n\n    SDL_DestroyWindow(window);\n    SDL_Quit();\n\n    return 0;\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace control {\n\n    /** Run specified user program. */\n    //% shim=control::runProgram\n    function runProgram(prog: string): void;\n}\n\n// Auto-generated. Do not edit. Really.\n"},"keyboard":{"enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum KeyboardKeyEvent {\n    //% block=\"press\"\n    Press = 0,\n    //% block=\"up\"\n    Up = 1,\n    //% block=\"down\"\n    Down = 2,\n    }\n\n// Auto-generated. Do not edit. Really.\n","keyboard.cpp":"// https://github.com/lancaster-university/codal-core/blob/master/source/drivers/HIDKeyboard.cpp\n\n#include \"pxt.h\"\n#include \"USB_HID_Keys.h\"\n\nenum class KeyboardKeyEvent {\n    //% block=\"press\"\n    Press,\n    //% block=\"up\"\n    Up,\n    //% block=\"down\"\n    Down\n};\n\nnamespace keyboard {\n    //%\n    void __flush() {\n        pxt::keyboard.flush();\n    }\n\n    //% \n    void __type(String text) {\n        if (NULL != text)\n            pxt::keyboard.type(text->getUTF8Data(), text->getUTF8Size());\n    }\n\n    //%\n    void __key(uint16_t ckey, KeyboardKeyEvent event) {\n       switch(event) {\n            case KeyboardKeyEvent::Down:\n                pxt::keyboard.keyDown(ckey);\n                break;\n            case KeyboardKeyEvent::Up:\n                pxt::keyboard.keyUp(ckey);\n                break;\n            case KeyboardKeyEvent::Press:\n                pxt::keyboard.press(ckey);\n                break;\n        }\n    }\n\n    //%\n    void __mediaKey(uint16_t key, KeyboardKeyEvent event) {\n        codal::MediaKey ckey = (codal::MediaKey)((int)codal::MediaKey::Mute + (int)key);\n        switch(event) {\n            case KeyboardKeyEvent::Down:\n                pxt::keyboard.keyDown(ckey);\n                break;\n            case KeyboardKeyEvent::Up:\n                pxt::keyboard.keyUp(ckey);\n                break;\n            case KeyboardKeyEvent::Press:\n                pxt::keyboard.press(ckey);\n                break;\n        }\n    }\n\n    //%\n    void __functionKey(uint16_t key, KeyboardKeyEvent event) {\n        codal::FunctionKey ckey = (codal::FunctionKey)key;\n        switch(event) {\n            case KeyboardKeyEvent::Down:\n                pxt::keyboard.keyDown(ckey);\n                break;\n            case KeyboardKeyEvent::Up:\n                pxt::keyboard.keyUp(ckey);\n                break;\n            case KeyboardKeyEvent::Press:\n                pxt::keyboard.press(ckey);\n                break;\n        }\n    }\n\n    //%\n    void __modifierKey(uint16_t modifier, KeyboardKeyEvent event) {\n       const Key key = { .reg = KEYMAP_KEY_DOWN | KEYMAP_MODIFIER_KEY | (uint8_t)modifier };\n        // send keys\n        switch(event) {\n            case KeyboardKeyEvent::Down:\n                pxt::keyboard.keyDown(key);\n                break;\n            case KeyboardKeyEvent::Up:\n                pxt::keyboard.keyUp(key);\n                break;\n            case KeyboardKeyEvent::Press:\n                pxt::keyboard.press(key);\n                break;\n        };\n    }\n}","keyboard.ts":"\nconst enum KeyboardMediaKey\n{\n    //% block=\"mute\"\n    Mute,\n    //% block=\"volume up\"\n    VolumeUp,\n    //% block=\"volume down\"\n    VolumeDown,\n    //% block=\"play pause\"\n    PlayPause,\n    //% block=\"stop\"\n    Stop,\n    //% block=\"previous track\"\n    PreviousTrack,\n    //% block=\"next track\"\n    NextTrack,\n    //% block=\"mail\"\n    Mail,\n    //% block=\"calculator\"\n    Calculator,\n    //% block=\"web search\"\n    WebSearch,\n    //% block=\"web home\"\n    WebHome,\n    //% block=\"web favourites\"\n    WebFavourites,\n    //% block=\"web refresh\"\n    WebRefresh,\n    //% block=\"web stop\"\n    WebStop,\n    //% block=\"web forward\"\n    WebForward,\n    //% block=\"web back\"\n    WebBack\n}\n\nconst enum KeyboardFunctionKey\n{\n    //% block=\"F1\"\n    F1Key = DAL.KEY_F1,  \n    //% block=\"F2\"\n    F2Key = DAL.KEY_F2,\n    //% block=\"F3\"\n    F3Key = DAL.KEY_F3,\n    //% block=\"F4\"\n    F4Key = DAL.KEY_F4, \n    //% block=\"F5\"\n    F5Key = DAL.KEY_F5,\n    //% block=\"F6\"\n    F6Key = DAL.KEY_F6,\n    //% block=\"F7\"\n    F7Key = DAL.KEY_F7,\n    //% block=\"F8\"\n    F8Key = DAL.KEY_F8,\n    //% block=\"F9\"\n    F9Key = DAL.KEY_F9,\n    //% block=\"F0\"\n    F10Key = DAL.KEY_F10,\n    //% block=\"F11\"\n    F11Key = DAL.KEY_F11,\n    //% block=\"F12\"\n    F12Key = DAL.KEY_F12,\n    //% block=\"F13\"\n    F13Key = DAL.KEY_F13,\n    //% block=\"F14\"\n    F14Key = DAL.KEY_F14,\n    //% block=\"F15\"\n    F15Key = DAL.KEY_F15,\n    //% block=\"F16\"\n    F16Key = DAL.KEY_F16,\n    //% block=\"F17\"\n    F17Key = DAL.KEY_F17,\n    //% block=\"F18\"\n    F18Key = DAL.KEY_F18,\n    //% block=\"F19\"\n    F19Key = DAL.KEY_F19,\n    //% block=\"F20\"\n    F20Key = DAL.KEY_F20,\n    //% block=\"F21\"\n    F21Key = DAL.KEY_F21,\n    //% block=\"F22\"\n    F22Key = DAL.KEY_F22,\n    //% block=\"F23\"\n    F23Key = DAL.KEY_F23,\n    //% block=\"F24\"\n    F24Key = DAL.KEY_F24,\n\n    //% block=\"enter\"\n    Enter = DAL.KEY_ENTER,\n    //% block=\"esc\"\n    Esc = DAL.KEY_ESC,\n    //% block=\"backspace\"\n    Backspace = DAL.KEY_BACKSPACE,\n    //% block=\"tab\"\n    Tab = DAL.KEY_TAB,\n    //% block=\"caps lock\"\n    CapsLock = DAL.KEY_CAPSLOCK,\n    //% block=\"num lock\"\n    NumLock = DAL.KEY_NUMLOCK,\n    //% block=\"keypad /\"\n    KeypadSlash = DAL.KEY_KPSLASH,\n    //% block=\"keypad *\"\n    KeypadAsterisk = DAL.KEY_KPASTERISK,\n    //% block=\"keypad -\"\n    KeypadMinus = DAL.KEY_KPMINUS,\n    //% block=\"keypad +\"\n    KeypadPlus = DAL.KEY_KPPLUS,\n    //% block=\"keypad enter\"\n    KeypadEnter = DAL.KEY_KPENTER,\n    //% block=\"keypad 1\"\n    Keypad1 = DAL.KEY_KP1,\n    //% block=\"keypad 2\"\n    Keypad2 = DAL.KEY_KP2,\n    //% block=\"keypad 3\"\n    Keypad3 = DAL.KEY_KP3,\n    //% block=\"keypad 4\"\n    Keypad4 = DAL.KEY_KP4,\n    //% block=\"keypad 5\"\n    Keypad5 = DAL.KEY_KP5,\n    //% block=\"keypad 6\"\n    Keypad6 = DAL.KEY_KP6,\n    //% block=\"keypad 7\"\n    Keypad7 = DAL.KEY_KP7,\n    //% block=\"keypad 8\"\n    Keypad8 = DAL.KEY_KP8,\n    //% block=\"keypad 9\"\n    Keypad9 = DAL.KEY_KP9,\n    //% block=\"keypad 0\"\n    Keypad0 = DAL.KEY_KP0,\n    //% block=\"keypad .\"\n    KeypadDot = DAL.KEY_KPDOT,\n    //% block=\"compose\"\n    Compose = DAL.KEY_COMPOSE,\n    //% block=\"power\"\n    Power = DAL.KEY_POWER,\n    //% block=\"=\"\n    KeypadEqual = DAL.KEY_KPEQUAL,\n    //% block=\"open\"\n    Open = DAL.KEY_OPEN,\n    //% block=\"help\"\n    Help = DAL.KEY_HELP,\n    //% block=\"props\"\n    Props = DAL.KEY_PROPS,\n    //% block=\"front\"\n    Front = DAL.KEY_FRONT,\n    //% block=\"stop\"\n    Stop = DAL.KEY_STOP,\n    //% block=\"again\"\n    Again = DAL.KEY_AGAIN,\n    //% block=\"undo\"\n    Undo = DAL.KEY_UNDO,\n    //% block=\"cut\"\n    Cut = DAL.KEY_CUT,\n    //% block=\"copy\"\n    Copy = DAL.KEY_COPY,\n    //% block=\"paste\"\n    Paste = DAL.KEY_PASTE,\n    //% block=\"find\"\n    Find = DAL.KEY_FIND,\n    //% block=\"mute\"\n    Mute = DAL.KEY_MUTE,\n    //% block=\"volume up\"\n    VolumeUp = DAL.KEY_VOLUMEUP,\n    //% block=\"volume down\"\n    VolumeDown = DAL.KEY_VOLUMEDOWN,\n    //% block=\"keypad ,\"\n    KeypadComma = DAL.KEY_KPCOMMA,\n    //% block=\"keypad jump comma\"\n    KeypadJumpComma = DAL.KEY_KPJPCOMMA,\n    //% block=\"keypad (\"\n    KeypadLeftParenthesis = DAL.KEY_KPLEFTPAREN,\n    //% block=\"keypad )\"\n    KeypadRightParenthesis = DAL.KEY_KPRIGHTPAREN,\n\n    //% block=\"print screen\"\n    PrintScreen = DAL.KEY_SYSRQ,\n    //% block=\"scroll lock\"\n    ScrollLock = DAL.KEY_SCROLLLOCK,\n    //% block=\"pause\"\n    Pause = DAL.KEY_PAUSE,\n    //% block=\"insert\"\n    Insert = DAL.KEY_INSERT,\n    //% block=\"home\"\n    Home = DAL.KEY_HOME,\n    //% block=\"page up\"\n    PageUp = DAL.KEY_PAGEUP,\n    //% block=\"delete\"\n    DeleteForward = DAL.KEY_DELETE,\n    //% block=\"end\"\n    End = DAL.KEY_END,\n    //% block=\"page down\"\n    PageDown = DAL.KEY_PAGEDOWN,\n\n    //% block=\"right arrow\"\n    RightArrow = DAL.KEY_RIGHT,\n    //% block=\"left arrow\"\n    LeftArrow = DAL.KEY_LEFT,\n    //% block=\"down arrow\"\n    DownArrow = DAL.KEY_DOWN,\n    //% block=\"up arrow\"\n    UpArrow = DAL.KEY_UP\n}\n\nconst enum KeyboardModifierKey {\n    //% block=\"Ctrl\"\n    Control = DAL.KEY_MOD_LCTRL,\n    //% block=\"Shift\"\n    Shift = DAL.KEY_MOD_LSHIFT,\n    //% block=\"Alt\"\n    Alt = DAL.KEY_MOD_LALT,\n    //% block=\"Command\"\n    Meta = DAL.KEY_MOD_LMETA,\n    //% block=\"Ctrl+Shift\"\n    ControlShift = Control | Shift,\n    //% block=\"Ctrl+Alt\"\n    ControlAlt = Control | Alt,\n    //% block=\"Shift+Alt\"\n    ShiftAlt = Shift | Alt,\n    //% block=\"Ctrl+Cmd\"\n    ControlCommand = Control | Meta,\n    //% block=\"Ctrl+Cmd\"\n    ShiftCommand = Shift | Meta,\n    //% block=\"Alt+Cmd\"\n    AltCommand = Alt | Meta,\n    //% block=\"Ctrl+Shift+Alt\"\n    ControlShiftAlt = Control | Shift | Alt,\n    //% block=\"Ctrl+Cmd+Shift+Alt\"\n    ControlCommandShiftAlt = Control | Meta | Shift | Alt,\n    //% block=\"Right Ctrl\"\n    RightControl = DAL.KEY_MOD_RCTRL,\n    //% block=\"Right Shift\"\n    RightShift = DAL.KEY_MOD_RSHIFT,\n    //% block=\"Right Alt\"\n    RightAlt = DAL.KEY_MOD_RALT,\n    //% block=\"Right Command\"\n    RightMeta = DAL.KEY_MOD_RMETA\n}\n\n/**\n * Keyboard emulation\n */\n//% icon=\"\\uf11c\" color=\"#303030\"\nnamespace keyboard {\n    /**\n    * Send a sequence of keystrokes to the keyboard\n    */\n    //% blockId=keyboardType block=\"keyboard type $text||with $modifiers\"\n    //% blockGap=8 weight=100\n    //% text.shadowOptions.toString=true\n    //% help=keyboard/type\n    //% weight=100\n    export function type(text: string, modifiers?: KeyboardModifierKey) {\n        if (modifiers)\n            __modifierKey(modifiers, KeyboardKeyEvent.Down);\n        __type(text);\n        __flush();\n    }\n\n    /**\n    * Send a key command\n    */\n    //% blockId=keyboardStandardKey block=\"keyboard key %key|%event\"\n    //% blockGap=8 weight=99\n    //% help=keyboard/key\n    export function key(key: string, event: KeyboardKeyEvent) {\n        if (!key) return;\n        const c = key.charCodeAt(0);\n        __key(c, event);\n    }\n\n    /**\n    * Send a media key command\n    */\n    //% blockId=keyboardMediaKey block=\"keyboard media %key|%event\"\n    //% blockGap=8\n    //% help=keyboard/media-key\n    export function mediaKey(key: KeyboardMediaKey, event: KeyboardKeyEvent) {\n        __mediaKey(key, event);\n    }\n\n    /**\n    * Send a function key command\n    */\n    //% blockId=keyboardFunctionKey block=\"keyboard function %key|%event\"\n    //% blockGap=8\n    //% help=keyboard/function-key\n    export function functionKey(key: KeyboardFunctionKey, event: KeyboardKeyEvent) {\n        __functionKey(key, event)\n    }\n\n    /**\n    * Send a modifier key command\n    */\n    //% blockId=keyboardModiferKey block=\"keyboard modifier %key|%event\"\n    //% blockGap=8\n    //% help=keyboard/modifier-key\n    export function modifierKey(key: KeyboardModifierKey, event: KeyboardKeyEvent) {\n        __modifierKey(key, event)\n    }\n\n    /**\n     * Send up commands for any remaning down keys\n     */\n    //% blockId=keyboardClear block=\"keyboard clear all\"\n    //% blockGap=8\n    //% help=keyboard/clear-all-keys\n    //% weight=10\n    export function clearAllKeys() {\n        __flush()\n    }\n}","pxt.json":"{\n    \"name\": \"keyboard\",\n    \"description\": \"Keyboard emulation over HID\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"keyboard.cpp\",\n        \"shims.d.ts\",\n        \"enums.d.ts\",\n        \"keyboard.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"searchOnly\": true,\n    \"tests\": [\n        \"test.ts\"\n    ],\n    \"yotta\": {\n        \"config\": {\n            \"DEVICE_USB\": 1,\n            \"DEVICE_KEYBOARD\": 1\n        }\n    },\n    \"icon\": \"/static/libs/keyboard.png\"\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace keyboard {\n    //% shim=keyboard::__flush hidden=1\n    function __flush(): void;\n\n    //% shim=keyboard::__type hidden=1\n    function __type(text: string): void;\n\n    //% shim=keyboard::__key hidden=1\n    function __key(ckey: number, event: KeyboardKeyEvent): void;\n\n    //% shim=keyboard::__mediaKey hidden=1\n    function __mediaKey(key: uint16, event: KeyboardKeyEvent): void;\n\n    //% shim=keyboard::__functionKey hidden=1\n    function __functionKey(key: uint16, event: KeyboardKeyEvent): void;\n\n    //% shim=keyboard::__modifierKey hidden=1\n    function __modifierKey(modifier: uint16, event: KeyboardKeyEvent): void;\n}\n\n// Auto-generated. Do not edit. Really.\n"},"light":{"README.md":"# neopixel\n\nThe neopixel library.\n\n","animations.jres":"{\n  \"*\": {\n    \"namespace\": \"light\",\n    \"dataEncoding\": \"base64\"\n  },\n  \"rainbowAnimation\": {\n    \"icon\": \"data:image/png;base64,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\"\n  },\n  \"colorWipeAnimation\": {\n    \"icon\": \"data:image/png;base64,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\"\n  },\n  \"runningLightsAnimation\": {\n    \"icon\": \"data:image/png;base64,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\"\n  },\n  \"sparkleAnimation\": {\n    \"icon\": \"data:image/png;base64,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\"\n  },\n  \"theaterChaseAnimation\": {\n    \"icon\": \"data:image/png;base64,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\"\n  },\n  \"cometAnimation\": {\n    \"icon\": \"data:image/png;base64,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\"\n  }\n}","create.ts":"\nnamespace light {\n    /**\n     * Create a new programmable light strip.\n     * @param pin the pin where the strip is connected.\n     * @param numleds number of leds in the strip, eg: 30\n     * @param mode the light encoding mode for different LED strips, eg: NeoPixelMode.RGB_GRB\n     */\n    //% blockId=\"neopixel_create_strip\" block=\"create WS2812 strip on %pin with %numleds pixels\"\n    //% help=\"light/create-strip\"\n    //% weight=100\n    //% blockSetVariable=strip\n    //% trackArgs=0,2\n    //% parts=\"neopixel\"\n    //% advanced=true\n    export function createStrip(\n        pin: DigitalInOutPin = null,\n        numleds: number = 30,\n        mode: NeoPixelMode = NeoPixelMode.RGB\n    ): NeoPixelStrip {\n        return light.createNeoPixelStrip(pin, numleds, mode);\n    }\n\n    /**\n     * Creates a strip of colored LEDs (APA102)\n     */\n    //% blockId=\"light_create_dotstar\" block=\"create APA102 strip|data %data|clock %clk|with %numleds pixels\"\n    //% help=\"light/create-apa102-strip\"\n    //% trackArgs=0,1,2\n    //% parts=\"dotstar\"\n    //% weight=100 blockSetVariable=strip\n    //% advanced=true\n    export function createAPA102Strip(\n        dataPin: DigitalInOutPin,\n        clkPin: DigitalInOutPin,\n        numleds: number): NeoPixelStrip {\n        const strip = new NeoPixelStrip();\n        strip._mode = NeoPixelMode.APA102;\n        strip._length = Math.max(0, numleds | 0);\n        strip._dataPin = dataPin;\n        strip._clkPin = clkPin;\n        return strip;\n    }\n}","defaultlights.ts":"namespace light {\n    /**\n     * Gets the default external light strip\n     */\n    //% whenUsed\n    export const pixels = light.defaultStrip();\n\n    /**\n     * Set all of the pixels on the strip to one RGB color.\n     * @param rgb RGB color of the LED\n     */\n    //% blockId=\"builtin_neopixel_set_strip_color\" block=\"set all pixels to %rgb=colorNumberPicker\"\n    //% help=\"light/set-all\"\n    //% weight=79 blockGap=8\n    export function setAll(rgb: number) {\n        light.pixels.setAll(rgb);\n    }\n\n    /**\n     * Sets a gradient between two colors\n     * @param startColor the start color\n     * @param endColor the end color\n     */\n    //% blockId=\"builtinlightsetgradient\" block=\"set gradient from %startRgb=colorNumberPicker to %endRgb=colorNumberPicker\"\n    //% weight=78 blockGap=8 blockHidden=true\n    export function setGradient(startRgb: number, endRgb: number) {\n        light.pixels.setGradient(startRgb, endRgb);\n    }\n\n    /**\n     * Turn off all pixel LEDs on the onboard strip.\n     */\n    //% blockId=\"builtin_neopixel_clear\" block=\"clear\"\n    //% parts=\"neopixel\"\n    //% help=\"light/clear\"\n    //% group=\"More\" weight=9 blockGap=8\n    export function clear() {\n        light.pixels.clear();\n    }\n\n    /**\n     * Display 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, 0 to autoscale\n     */\n    //% blockId=builtin_neopixel_show_bar_graph block=\"graph %value||up to %high\" icon=\"\\uf080\"\n    //% help=light/graph blockGap=8\n    //% weight=10\n    export function graph(value: number, high?: number): void {\n        light.pixels.graph(value, high);\n    }\n\n\n    /**\n     * Set the pixel to a given color.\n     * @param pixeloffset position of the NeoPixel in the strip\n     * @param color RGB color of the LED\n     */\n    //% blockId=\"builtin_neopixel_set_pixel_color\" block=\"set pixel color at %pixeloffset|to %rgb=colorNumberPicker\"\n    //% help=\"light/set-pixel-color\"\n    //% group=\"More\" weight=89 blockGap=8\n    export function setPixelColor(pixeloffset: number, color: number): void {\n        light.pixels.setPixelColor(pixeloffset, color);\n    }\n\n    /**\n     * Gets the pixel color at a given offset.\n     * @param pixeloffset position of the NeoPixel in the strip\n     */\n    //% blockId=\"builtin_neopixel_pixel_color\" block=\"pixel color at %pixeloffset\"\n    //% help=\"light/pixel-color\"\n    //% group=\"More\" weight=88\n    export function pixelColor(pixeloffset: number): number {\n        return light.pixels.pixelColor(pixeloffset);\n    }\n\n    /**\n     * Set the brightness of the strip. This flag only applies to future operation.\n     * @param brightness a measure of LED brightness in 0-255. eg: 20\n     */\n    //% blockId=\"builtin_neopixel_set_brightness\" block=\"set brightness %brightness\"\n    //% brightness.min=0 brightness.max=255\n    //% help=\"light/set-brightness\"\n    //% weight=2 blockGap=8\n    export function setBrightness(brightness: number): void {\n        light.pixels.setBrightness(brightness);\n    }\n\n    /**\n     * Move a photon effect along the pixel strip by a number of steps.\n     * @param steps number of steps (lights) to move, eg: 1\n     */\n    //% blockId=builtin_neophoton_fd block=\"photon forward by %steps\"\n    //% help=\"light/photon-forward\"\n    //% group=\"Photon\" weight=41 blockGap=8\n    export function photonForward(steps: number) {\n        light.pixels.photonForward(steps);\n    }\n    /**\n         * Switch the direction of the photon pulse.\n         */\n    //% blockId=builtin_neophoton_flip block=\"photon flip\"\n    //% help=\"light/photon-flip\"\n    //% parts=\"neopixel\"\n    //% group=\"Photon\" weight=40 blockGap=8\n    export function photonFlip() {\n        light.pixels.photonFlip();\n    }\n\n\n    /**\n     * Sets the photon position to a given light index\n     * @param index index of the light, if out of bound, the index is wrapped\n     */\n    //% blockId=builtin_light_photon_set_position block=\"photon set position %index\"\n    //% help=\"light/set-photon-position\"\n    //% parts=\"neopixel\"\n    //% group=\"Photon\" weight=39 blockGap=8\n    export function setPhotonPosition(index: number) {\n        light.pixels.setPhotonPosition(index);\n    }\n\n    /**\n     * Set the photon color hue.\n     * @param hue the color hue of the photon\n     */\n    //% blockId=builtin_neophoton_set_pen_hue block=\"photon set pen hue %hue=colorWheelHsvPicker\"\n    //% help=\"light/set-photon-pen-hue\"\n    //% group=\"Photon\" weight=39 blockGap=8\n    export function setPhotonPenHue(hue: number) {\n        light.pixels.setPhotonPenHue(hue);\n    }\n\n    /**\n     * Set the photon mode to pen up, pen down, or eraser.\n     * @param mode the desired mode\n     */\n    //% blockId=builtin_neophoton_set_photon block=\"photon %mode\"\n    //% help=\"light/set-photon-mode\"\n    //% group=\"Photon\" weight=38\n    export function setPhotonMode(mode: PhotonMode) {\n        light.pixels.setPhotonMode(mode);\n    }\n\n    /**\n     * Show an animation or queue an animation in the animation queue\n     * @param animation the animation to run, eg: light.rainbowAnimation\n     * @param duration the duration to run in milliseconds, eg: 500\n     */\n    //% blockId=builtin_neopixel_show_animation block=\"show animation %animation=light_animation_picker|for %duration=timePicker|ms\"\n    //% help=\"light/show-animation\" blockGap=8\n    //% weight=81\n    export function showAnimation(animation: NeoPixelAnimation, duration: number) {\n        light.pixels.showAnimation(animation, duration);\n    }\n\n    /**\n      * Show a single animation frame\n      * @param animation the animation to run, eg: light.rainbowAnimation\n      */\n    //% blockId=builtin_neopixel_show_animation_frame block=\"show frame of %animation=light_animation_picker|animation\"\n    //% help=\"light/show-animation-frame\"\n    //% group=\"More\" weight=24 blockGap=8\n    export function showAnimationFrame(animation: NeoPixelAnimation) {\n        light.pixels.showAnimationFrame(animation);\n    }\n\n    /**\n     * Stop the current animation and any other animations ready to show.\n     */\n    //% blockId=builtin_neopixel_stop_all_animations block=\"stop all animations\"\n    //% help=\"light/stop-all-animations\"\n    //% group=\"More\" weight=23\n    export function stopAllAnimations() {\n        light.pixels.stopAllAnimations();\n    }\n\n    /**\n     * Creates a builtin animation\n     * @param kind the type of animation\n     */\n    //% kind.fieldEditor=\"imagedropdown\"\n    //% kind.fieldOptions.columns=3 blockGap=8\n    //% blockId=light_animation block=\"%kind\"\n    //% group=\"More\" weight=25\n    //% help=\"light/animation\" blockHidden=true deprecated=1\n    export function animation(kind: LightAnimation): NeoPixelAnimation {\n        switch (kind) {\n            case LightAnimation.RunningLights: return runningLightsAnimation;\n            case LightAnimation.Comet: return cometAnimation;\n            case LightAnimation.ColorWipe: return colorWipeAnimation;\n            case LightAnimation.TheaterChase: return theaterChaseAnimation;\n            case LightAnimation.Sparkle: return sparkleAnimation;\n            default: return rainbowAnimation;\n        }\n    }\n}","defaultlightsoverrides.ts":"namespace light {\n    /**\n     * Create a range of pixels.\n     * @param start offset in the NeoPixel strip to start the range\n     * @param length number of pixels in the range, eg: 4\n     */\n    //% blockId=\"lightstrip_range\" block=\"range from %start|with %length|pixels\"\n    //% weight=1\n    export function range(start: number, length: number): NeoPixelStrip {\n        return pixels.range(start, length);\n    }\n\n    /**\n     * Sets the number of LEDS on the default light strip\n     */\n    //% blockId=lightds_setlength block=\"set pixels length to %numleds pixels\"\n    //% numleds.defl=30\n    //% numleds.shadow=lightLengthPicker\n    //% weight=0\n    export function setLength(numleds: number) {\n        light.pixels.setLength(numleds);\n    }\n\n    /**\n     * Sets the type of RGB light on the default strip\n     */\n    //% blockId=lightds_setmode block=\"set default strip mode to %mode\"\n    //% weight=0\n    export function setMode(mode: NeoPixelMode) {\n        light.pixels.setMode(mode);\n    }\n}","defaultstrip.ts":"namespace light {\n    let _defaultStrip: NeoPixelStrip;\n    /**\n     * Gets the default light strip\n     */\n    //% help=light/default-strip\n    //% blockId=\"neopixel_default_strip\" block=\"default strip\"\n    //% weight=110 blockGap=8\n    //% advanced=true\n    //% parts=pixels\n    export function defaultStrip(): NeoPixelStrip {\n        if (_defaultStrip) return _defaultStrip;\n\n        const data = pins.pinByCfg(DAL.CFG_PIN_DOTSTAR_DATA);\n        const clk = pins.pinByCfg(DAL.CFG_PIN_DOTSTAR_CLOCK);\n        const dsnum = control.getConfigValue(DAL.CFG_NUM_DOTSTARS, 0);\n        const neo = pins.pinByCfg(DAL.CFG_PIN_NEOPIXEL);\n        const neonum = control.getConfigValue(DAL.CFG_NUM_NEOPIXELS, 0);\n        const mosi = pins.pinByCfg(DAL.CFG_PIN_MOSI);\n        const sck = pins.pinByCfg(DAL.CFG_PIN_SCK);\n\n        _defaultStrip = new NeoPixelStrip();\n        if (data && clk && dsnum > 0) {\n            _defaultStrip._mode = NeoPixelMode.APA102;\n            _defaultStrip._dataPin = data;\n            _defaultStrip._clkPin = clk;\n            _defaultStrip._length = dsnum;\n        } else if(neo && neonum > 0) {\n            _defaultStrip._mode = NeoPixelMode.RGB;\n            _defaultStrip._dataPin = neo;\n            _defaultStrip._length = neonum;\n        } else { // mount strip on SPI\n            _defaultStrip._mode = NeoPixelMode.RGB;\n            _defaultStrip._dataPin = mosi;\n            _defaultStrip._clkPin = sck;\n            _defaultStrip._length = 30;\n        }\n\n        return _defaultStrip;\n    }\n}","neopixel.ts":"/**\n * Different modes for RGB or RGB+W NeoPixel strips\n */\nconst enum NeoPixelMode {\n    //% block=\"RGB (GRB format)\"\n    RGB = 1,\n    //% block=\"RGB+W\"\n    RGBW = 2,\n    //% block=\"RGB (RGB format)\"\n    RGB_RGB = 3,\n    //% block=\"APA102\"\n    APA102 = 4\n}\n\nconst enum LightMove {\n    //% block=\"rotate\"\n    Rotate,\n    //% block=\"shift\"\n    Shift\n}\n\n/**\n * A determines the mode of the photon\n */\nconst enum PhotonMode {\n    //% block=\"pen up\"\n    PenUp,\n    //% block=\"pen down\"\n    PenDown,\n    //% block=\"eraser\"\n    Eraser,\n    //% block=\"off\"\n    Off\n}\n\nconst enum LightAnimation {\n    //% blockImage=1\n    //% block=\"rainbow\"\n    Rainbow,\n    //% blockImage=1\n    //% block=\"running lights\"\n    RunningLights,\n    //% blockImage=1\n    //% block=\"comet\"\n    Comet,\n    //% blockImage=1\n    //% block=\"sparkle\"\n    Sparkle,\n    //% blockImage=1\n    //% block=\"theater chase\"\n    TheaterChase,\n    //% blockImage=1\n    //% block=\"color wipe\"\n    ColorWipe\n}\n\n/**\n * Functions to operate colored LEDs.\n */\n//% weight=100 color=\"#0078d7\" icon=\"\\uf00a\"\n//% groups='[\"other\", \"Color\", \"Photon\", \"More\"]'\n//% blockGap=8\nnamespace light {\n    export type LightStrip = NeoPixelStrip;\n    /**\n     * A NeoPixel strip\n     */\n    export class NeoPixelStrip {\n        _parent: NeoPixelStrip;\n        _dataPin: DigitalInOutPin;\n        _clkPin: DigitalInOutPin;\n        _buf: Buffer; // unscaled color buffer\n        // per pixel scaling. This buffer is allocated on-demand when per-pixel brightness is needed.\n        // when rendering, if this buffer is null, use _brightness instead\n        _brightnessBuf: Buffer;\n        _sendBuf: Buffer; // scaled color buffer\n        _brightness: number; // global brightness for this strip\n        _start: number; // start offset in LED strip\n        _length: number; // number of LEDs\n        _mode: NeoPixelMode;\n        _buffered: boolean;\n        _animationQueue: control.AnimationQueue;\n        // what's the current high value\n        _barGraphHigh: number;\n        // when was the current high value recorded\n        _barGraphHighLast: number;\n        // the current photon color, undefined = no photon\n        _photonMode: number;\n        _photonPos: number;\n        _photonDir: number;\n        _photonPenColor: number;\n        // last animation used by showAnimationFrame\n        _lastAnimation: NeoPixelAnimation;\n        _lastAnimationRenderer: () => boolean;\n        _transitionPlayer: BrightnessTransitionPlayer;\n\n        constructor() {\n            this._buffered = false;\n            this._mode = NeoPixelMode.RGB;\n            this._length = 0;\n            this._brightness = 16;\n            this._start = 0;\n            this._dataPin = undefined;\n            this._clkPin = undefined;\n            this._barGraphHigh = 0;\n            this._barGraphHighLast = 0;\n        }\n\n        /**\n         * Gets the underlying color buffer for the entire strip\n         */\n        get buf(): Buffer {\n            if (this._parent) return this._parent.buf;\n            if (!this._buf)\n                this.reallocateBuffer();\n            return this._buf;\n        }\n\n        get brightnessBuf(): Buffer {\n            if (this._parent) return this._parent.brightnessBuf;\n            if (!this._brightnessBuf) {\n                const b = this.buf; // force allocate buffer\n                this._brightnessBuf = control.createBuffer(this._length);\n                this._brightnessBuf.fill(this._brightness, 0, this._brightnessBuf.length);\n            }\n            return this._brightnessBuf;\n        }\n\n        /**\n         * Gets the LED data layout mode\n         */\n        get mode(): NeoPixelMode {\n            return this._mode;\n        }\n\n        /**\n         * Set all of the pixels on the strip to one RGB color.\n         * @param rgb RGB color of the LED\n         */\n        //% blockId=\"light_set_strip_color\" block=\"set %strip all pixels to %rgb=colorNumberPicker\"\n        //% help=\"light/neopixelstrip/set-all\"\n        //% weight=80 blockGap=8\n        //% advanced=true\n        setAll(rgb: number) {\n            rgb = rgb | 0;\n            const red = color.unpackR(rgb);\n            const green = color.unpackG(rgb);\n            const blue = color.unpackB(rgb);\n\n            const end = this._start + this._length;\n            const stride = this.stride();\n            for (let i = this._start; i < end; ++i) {\n                this.setBufferRGB(i * stride, red, green, blue)\n            }\n            this.autoShow();\n        }\n\n        /**\n         * Sets a gradient between two colors\n         * @param startColor the start color\n         * @param endColor the end color\n         */\n        //% blockId=lightsetgradient block=\"set %strip gradient from %startColor=colorNumberPicker to %endColor=colorNumberPicker\"\n        //% weight=79 blockGap=8\n        //% group=\"More\" advanced=true\n        setGradient(startColor: number, endColor: number) {\n            const sr = color.unpackR(startColor);\n            const sg = color.unpackG(startColor);\n            const sb = color.unpackB(startColor);\n            const er = color.unpackR(endColor);\n            const eg = color.unpackG(endColor);\n            const eb = color.unpackB(endColor);\n\n            const end = this._start + this._length;\n            const n1 = this._length - 1;\n            const stride = this.stride();\n            for (let i = this._start; i < end; ++i) {\n                let x = (i - this._start) / n1;\n                const ox = 1 - x;\n                const r = (sr * ox + er * x) | 0;\n                const g = (sg * ox + eg * x) | 0;\n                const b = (sb * ox + eb * x) | 0;\n                this.setBufferRGB(i * stride, r, g, b);\n            }\n            this.autoShow();\n        }\n\n        /**\n         * Display 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, 0 to autoscale\n         */\n        //% blockId=light_show_bar_graph block=\"%strip|graph %value||up to %high\" icon=\"\\uf080\"\n        //% help=light/neopixelstrip/graph\n        //% weight=70 blockGap=8\n        //% advanced=true\n        graph(value: number, high?: number): void {\n            console.logValue(\"\", value);\n            value = Math.abs(value);\n\n            const now = control.millis();\n            if (high > 0) {\n                this._barGraphHigh = high;\n            }\n            else if (value > this._barGraphHigh || now - this._barGraphHighLast > 10000) {\n                this._barGraphHigh = value;\n                this._barGraphHighLast = now;\n            }\n\n            const bfr = this.buffered();\n            this.setBuffered(true);\n            const n = this._length;\n            const n1 = n - 1;\n            const nhalf = n / 2;\n            const v = Math.round((value * n) / this._barGraphHigh);\n            if (v == 0) {\n                this.setAll(0);\n            } else {\n                for (let i = 0; i < n; ++i) {\n                    if (i + 1 <= v) {\n                        if (i < nhalf) {\n                            const b = (i * 255 / nhalf) >> 0;\n                            this.setPixelColor(i, light.rgb(0, b, 255 - b));\n                        } else {\n                            const b = ((i - nhalf) * 255 / nhalf) >> 0;\n                            this.setPixelColor(i, light.rgb(b, 255 - b, 0));\n                        }\n                    }\n                    else {\n                        this.setPixelColor(i, 0);\n                    }\n                }\n            }\n            this.show();\n            this.setBuffered(bfr);\n        }\n\n        /**\n         * Set the pixel to a given color.\n         * You need to call ``show`` to make the changes visible.\n         * @param pixeloffset position of the NeoPixel in the strip\n         * @param color RGB color of the LED\n         */\n        //% blockId=\"light_set_pixel_color\" block=\"set %strip pixel color at %pixeloffset|to %rgb=colorNumberPicker\"\n        //% help=\"light/neopixelstrip/set-pixel-color\"\n        //% weight=79 blockGap=8\n        //% group=\"More\" advanced=true\n        setPixelColor(pixeloffset: number, c: number): void {\n            pixeloffset = pixeloffset | 0;\n            c = c | 0;\n\n            if (pixeloffset < 0\n                || pixeloffset >= this._length)\n                return;\n\n            const stride = this.stride();\n            pixeloffset = (pixeloffset + this._start) * stride;\n            const red = color.unpackR(c);\n            const green = color.unpackG(c);\n            const blue = color.unpackB(c);\n            this.setBufferRGB(pixeloffset, red, green, blue)\n            this.autoShow();\n        }\n\n        /**\n         * Gets the pixel color.\n         * @param pixeloffset position of the NeoPixel in the strip\n         */\n        //% blockId=\"light_get_pixel_color\" block=\"%strip|pixel color at %pixeloffset\"\n        //% help=\"light/neopixelstrip/pixel-color\"\n        //% weight=9 blockGap=8\n        //% group=\"More\" advanced=true\n        pixelColor(pixeloffset: number): number {\n            pixeloffset = pixeloffset | 0;\n            if (pixeloffset < 0\n                || pixeloffset >= this._length) {\n                return 0;\n            }\n\n            const stride = this.stride();\n            const offset = (pixeloffset + this._start) * stride;\n            const b = this.buf;\n            let red = 0, green = 0, blue = 0;\n            switch (this._mode) {\n                case NeoPixelMode.RGB_RGB:\n                    red = this.buf[offset + 0];\n                    green = this.buf[offset + 1];\n                    blue = this.buf[offset + 2];\n                    break;\n                case NeoPixelMode.APA102:\n                    blue = this.buf[offset + 1];\n                    green = this.buf[offset + 2];\n                    red = this.buf[offset + 3];\n                    break;\n                default:\n                    green = this.buf[offset + 0];\n                    red = this.buf[offset + 1];\n                    blue = this.buf[offset + 2];\n                    break;\n            }\n\n            return color.rgb(red, green, blue);\n        }\n\n        /**\n         * Set the white brightness of a pixel in a NeoPixel strip of RGB+W LEDs.\n         * This only works for RGB+W NeoPixels.\n         * @param pixeloffset position of the LED in the strip\n         * @param white brightness of the white LED\n         */\n        //% blockId=\"light_set_pixel_white_led\" block=\"set %strip pixel white LED at %pixeloffset|to %white\"\n        //% help=\"light/neopixelstrip/set-pixel-white-led\"\n        //% weight=5 blockGap=8\n        //% group=\"More\" advanced=true\n        setPixelWhiteLED(pixeloffset: number, white: number): void {\n            if (this._mode != NeoPixelMode.RGBW) return;\n\n            pixeloffset = pixeloffset | 0;\n            if (pixeloffset < 0\n                || pixeloffset >= this._length)\n                return;\n\n            pixeloffset = (pixeloffset + this._start) * 4;\n            white = white & 0xff;\n            const buf = this.buf;\n            buf[pixeloffset + 3] = white;\n            this.autoShow();\n        }\n\n        /**\n         * Make the strip show all the new changes for the pixels.\n         */\n        //% blockId=\"light_show\" block=\"%strip|show\"\n        //% help=\"light/neopixelstrip/show\"\n        //% weight=86 blockGap=8\n        //% group=\"More\" advanced=true\n        show(): void {\n            if (this._parent) this._parent.show();\n            else if (this._dataPin) {\n                const b = this.buf;\n\n                // fast path: no processing\n                if (this._brightness == 0xff && !this._brightnessBuf && !this._photonPenColor) {\n                    // no need to process buffer\n                    light.sendBuffer(this._dataPin, this._clkPin, this._mode, b);\n                    return;\n                }\n\n                // bb may be undefined if the brightness\n                // is uniform over the strip and has not been allocated\n                const _bb = this._brightnessBuf;\n                if (!this._sendBuf) this._sendBuf = control.createBuffer(b.length);\n                const sb = this._sendBuf;\n                const stride = this.stride();\n                const strideOffset = this._mode == NeoPixelMode.APA102 ? 1 : 0;\n                // apply brightness\n                for (let i = 0; i < this._length; ++i) {\n                    const offset = (this._start + i) * stride;\n                    for (let j = 0; j < strideOffset; ++j)\n                        sb[offset + j] = 0xff;\n                    for (let j = strideOffset; j < stride; ++j)\n                        sb[offset + j] = (b[offset + j] * (_bb ? _bb[i] : this._brightness)) >> 8;\n                }\n                // apply photon\n                this.drawPhoton(sb, stride);\n                //console.log(`${!!this._dataPin} ${!!this._clkPin} ${this.mode} hex${sb.toHex()}`)\n                light.sendBuffer(this._dataPin, this._clkPin, this._mode, sb);\n            }\n        }\n\n        protected drawPhoton(sb: Buffer, stride: number) {\n            // apply photon\n            if (this._photonPenColor) {\n                // draw head and trail\n                const tailn = Math.max(1, Math.min(8, this._length >> 4));\n                let pi = this._photonPos * stride;\n                let c = Math.max(128, this._brightness);\n                let dc = (c - 32) / tailn;\n                for (let bi = 0; bi < tailn && c > 0; ++bi) {\n                    if (this._mode == NeoPixelMode.RGBW)\n                        sb[pi + 3] = c;\n                    else if (this._mode == NeoPixelMode.APA102)\n                        sb[pi + 1] = sb[pi + 2] = sb[pi + 3] = c;\n                    else\n                        sb[pi] = sb[pi + 1] = sb[pi + 2] = c;\n\n                    c -= dc;\n                    pi += (-this._photonDir * stride) % sb.length;\n                    if (pi < 0) pi += sb.length;\n                }\n            }\n        }\n\n        /**\n         * Turn off all pixel LEDs.\n         */\n        //% blockId=\"light_clear\" block=\"%strip|clear\"\n        //% help=\"light/neopixelstrip/clear\"\n        //% weight=85 blockGap=8\n        //% group=\"More\" advanced=true\n        clear(): void {\n            const stride = this.stride();\n            this.buf.fill(0, this._start * stride, this._length * stride);\n            this.autoShow();\n        }\n\n        /**\n         * Get the number of pixels on the strip\n         */\n        //% blockId=\"light_length\" block=\"%strip|length\"\n        //% help=\"light/neopixelstrip/length\"\n        //% weight=8 blockGap=8\n        //% group=\"More\" advanced=true\n        length() {\n            return this._length;\n        }\n\n        /**\n         * Set the brightness of the strip. This flag only applies to future operation.\n         * @param brightness a measure of LED brightness in 0-255. eg: 20\n         */\n        //% blockId=\"light_set_brightness\" block=\"set %strip brightness %brightness\"\n        //% brightness.min=0 brightness.max=255\n        //% help=\"light/neopixelstrip/set-brightness\"\n        //% weight=2 blockGap=8\n        //% advanced=true\n        setBrightness(brightness: number): void {\n            const b = Math.max(0, Math.min(0xff, brightness | 0));\n            if (b != this._brightness || this._brightnessBuf) {\n                this._brightness = b;\n                // if this is a top level strip clear any existing brightness buffer\n                if (!this._parent)\n                    this._brightnessBuf = undefined;\n                // if this is a NOT top-level strip or if brightness buff has been allocated,\n                else if (this._parent || this._brightnessBuf)\n                    this.brightnessBuf.fill(this._brightness, this._start, this._length);\n                this.autoShow();\n            }\n        }\n\n        /**\n         * Sets an individual pixel brightness\n         * @param index \n         * @param brightness \n         */\n        setPixelBrightness(index: number, brightness: number): void {\n            const i = (index | 0);\n            if (i < 0 || i > this._length) return;\n\n            const b = Math.max(0, Math.min(0xff, brightness | 0));\n            const bb = this.brightnessBuf;\n            if (bb[this._start + i] != b) {\n                bb[this._start + i] = b;\n                this.autoShow();\n            }\n        }\n\n        /**\n         * Get the brightness of the pixel strip.\n         */\n        //% blockId=\"light_get_brightness\" block=\"%strip|brightness\"\n        //% help=\"light/neopixelstrip/brightness\"\n        //% parts=neopixel\n        //% weight=7 blockGap=8\n        //% group=\"More\" advanced=true\n        brightness(): number {\n            return this._brightness;\n        }\n\n        /**\n         * Create a range of pixels.\n         * @param start offset in the NeoPixel strip to start the range\n         * @param length number of pixels in the range, eg: 4\n         */\n        //% blockId=\"light_range\" block=\"%strip|range from %start|with %length|pixels\"\n        //% help=\"light/neopixelstrip/range\"\n        //% weight=99 blockGap=30\n        //% blockSetVariable=strip\n        //% advanced=true\n        range(start: number, length: number): NeoPixelStrip {\n            start = start | 0;\n            length = length | 0;\n\n            let strip = new NeoPixelStrip();\n            strip._parent = this;\n            strip._dataPin = this._dataPin;\n            strip._clkPin = this._clkPin;\n            strip._brightness = this._brightness;\n            strip._start = this._start + Math.clamp(0, this._length - 1, start);\n            strip._length = Math.clamp(0, this._length - (strip._start - this._start), length);\n            return strip;\n        }\n\n        /**\n         * Shift LEDs forward and clear with zeros.\n         * You need to call ``show`` to make the changes visible.\n         * @param offset number of pixels to shift forward, eg: 1\n         */\n        //% blockId=\"light_move_pixels\" block=\"%strip|%kind=MoveKind|by %offset\"\n        //% help=\"light/neopixelstrip/move\"\n        //% weight=87 blockGap=8\n        //% group=\"More\" advanced=true\n        move(kind: LightMove, offset: number = 1): void {\n            offset = offset | 0;\n\n            const stride = this.stride();\n            if (kind === LightMove.Shift) {\n                this.buf.shift(-offset * stride, this._start * stride, this._length * stride)\n            }\n            else {\n                this.buf.rotate(-offset * stride, this._start * stride, this._length * stride)\n            }\n            this.autoShow();\n        }\n\n        private stride(): number {\n            return this._mode === NeoPixelMode.RGBW || this._mode == NeoPixelMode.APA102 ? 4 : 3;\n        }\n\n        initPhoton() {\n            if (this._photonPos === undefined) {\n                this._photonMode = PhotonMode.PenDown;\n                this._photonPos = 0;\n                this._photonDir = 1;\n                this._photonPenColor = Colors.Red;\n            }\n        }\n\n        /**\n         * Move a photon effect along the pixel strip by a number of steps.\n         * @param steps number of steps (lights) to move, eg: 1\n         */\n        //% blockId=light_photon_fd block=\"%strip|photon forward by %steps\"\n        //% help=\"light/neopixelstrip/photon-forward\"\n        //% weight=41 blockGap=8\n        //% group=\"Photon\" advanced=true\n        photonForward(steps: number) {\n            steps = steps | 0;\n            this.setPhotonPosition(this._photonPos + this._photonDir * steps);\n        }\n\n        /**\n         * Switch the direction of the photon pulse.\n         */\n        //% blockId=light_photon_flip block=\"%strip|photon flip\"\n        //% help=\"light/neopixelstrip/photon-flip\"\n        //% weight=40 blockGap=8\n        //% group=\"Photon\" advanced=true\n        photonFlip() {\n            this.initPhoton();\n            this._photonDir *= -1;\n        }\n\n        /**\n         * Sets the photon position to a given light index\n         * @param index index of the light, if out of bound, the index is wrapped\n         */\n        //% blockId=light_photon_set_position block=\"%strip|photon set position %index\"\n        //% help=\"light/neopixelstrip/set-photon-position\"\n        //% weight=39 blockGap=8\n        //% group=\"Photon\" advanced=true\n        setPhotonPosition(index: number) {\n            index = index | 0;\n\n            this.initPhoton();\n\n            // disable buffering\n            const buffered = this.buffered();\n            this.setBuffered(false);\n\n            // move\n            this._photonPos = (index >> 0) % this._length;\n            if (this._photonPos < 0) this._photonPos += this._length;\n\n            // paint under photon\n            if (this._photonMode == PhotonMode.PenDown)\n                this.setPixelColor(this._photonPos, this._photonPenColor);\n            else if (this._photonMode == PhotonMode.Eraser)\n                this.setPixelColor(this._photonPos, 0); // erase led\n\n            // restoring buffer\n            this.setBuffered(buffered);\n\n            this.autoShow();\n        }\n\n        /**\n         * Set the photon color.\n         * @param color the color of the photon\n         */\n        //% blockId=light_photon_set_pen_color block=\"%strip=variables_get|photon set pen color %color=colorNumberPicker\"\n        //% help=\"light/neopixelstrip/set-photon-pen-color\"\n        //% weight=38 blockGap=8\n        //% group=\"Photon\" advanced=true\n        setPhotonPenColor(color: number) {\n            color = color | 0;\n            this.initPhoton();\n            this._photonPenColor = color;\n            this.photonForward(0);\n        }\n\n        /**\n         * Sets the photon hue.\n         * @param hue the hue of the photon color\n         */\n        //% blockId=light_photon_set_pen_hue block=\"%strip=variables_get|photon set pen hue %hue=colorWheelHsvPicker\"\n        //% help=\"light/neopixelstrip/set-photon-pen-hue\"\n        //% weight=39 blockGap=8\n        //% group=\"Photon\" advanced=true\n        setPhotonPenHue(hue: number) {\n            hue = hue | 0;\n            this.setPhotonPenColor(color.hsv(hue, 0xff, 0xff));\n        }\n\n        //% deprecated=1 blockHidden=1\n        //% group=\"Photon\" advanced=true\n        setPhotonColor(hue: number) {\n            this.setPhotonPenHue(hue);\n        }\n\n        /**\n         * Set the photon mode to pen up, pen down, or eraser.\n         * @param mode the desired mode\n         */\n        //% blockId=light_photon_set_photon block=\"%strip|photon %mode\"\n        //% help=\"light/neopixelstrip/set-photon-mode\"\n        //% weight=38\n        //% group=\"Photon\" advanced=true\n        setPhotonMode(mode: PhotonMode) {\n            if (mode == PhotonMode.Off) {\n                this._photonPos = undefined;\n                this.show();\n            } else {\n                this.initPhoton();\n                if (this._photonMode != mode) {\n                    this._photonMode = mode;\n                    this.photonForward(0);\n                }\n            }\n        }\n\n        /**\n         * Starts a brightness transition on the strip (and cancels any other running transition)\n         * @param transition \n         * @param duration \n         */\n        startBrightnessTransition(\n            startBrightness: number,\n            endBrightness: number,\n            duration: number,\n            repeat?: number,\n            yoyo?: boolean,\n            transition?: BrightnessTransition\n        ) {\n            const player = this._transitionPlayer = new BrightnessTransitionPlayer(\n                transition || new EasingBrightnessTransition(undefined),\n                startBrightness,\n                endBrightness,\n                duration,\n                repeat,\n                yoyo);\n            control.runInBackground(() => {\n                while (player == this._transitionPlayer) {\n                    const buf = this.buffered();\n                    this.setBuffered(true);\n                    const keepRendering = player.update(this);\n                    this.setBuffered(buf);\n                    this.show();\n                    pause(20);\n                    if (!keepRendering) break;\n                }\n            });\n        }\n\n        /**\n         * Stops any running brightness transition\n         */\n        stopBrightnessTransition() {\n            this._transitionPlayer = undefined;\n        }\n\n        /**\n         * Show an animation or queue an animation in the animation queue\n         * @param animation the animation to run\n         * @param duration the duration to run in milliseconds, eg: 500\n         */\n        //% blockId=light_show_animation block=\"%strip|show animation %animation=light_animation_picker|for %duration=timePicker|ms\"\n        //% help=\"light/neopixelstrip/show-animation\"\n        //% weight=90 blockGap=8\n        //% advanced=true\n        showAnimation(animation: NeoPixelAnimation, duration: number) {\n            if (!animation) return;\n\n            // if a previous renderer for the same animation was used, keep using it\n            let animationRenderer = this._lastAnimationRenderer;\n            if (!animationRenderer || this._lastAnimation != animation) {\n                animationRenderer = animation.createRenderer(this);\n                if (!animationRenderer) return;\n            }\n\n            let start = -1;\n            const render: () => boolean = () => {\n                // keep track of whose running\n                this._lastAnimation = animation;\n                this._lastAnimationRenderer = animationRenderer;\n                // execute animation\n                if (start < 0) start = control.millis();\n                const now = control.millis() - start;\n                const buf = this.buffered();\n                this.setBuffered(true);\n                const keepRendering = animationRenderer();\n                this.setBuffered(buf);\n                this.show();\n                pause(1);\n                return duration > 0\n                    ? now <= duration\n                    : keepRendering;\n            };\n            this.queueAnimation(render);\n        }\n\n        /**\n         * Show a single animation frame.\n         * @param animation the animation to run\n         */\n        //% blockId=light_show_animation_frame block=\"%strip|show frame of %animation=light_animation_picker|animation\"\n        //% help=\"light/neopixelstrip/show-animation-frame\"\n        //% weight=87 blockGap=8\n        //% group=\"More\" advanced=true\n        showAnimationFrame(animation: NeoPixelAnimation) {\n            if (!animation) {\n                this._lastAnimation = undefined;\n                this._lastAnimationRenderer = undefined;\n                return;\n            }\n            let renderer = this._lastAnimationRenderer;\n            if (!renderer || this._lastAnimation != animation) {\n                this._lastAnimation = animation;\n                renderer = this._lastAnimationRenderer = animation.createRenderer(this);\n            }\n            if (renderer) {\n                const buf = this.buffered();\n                this.setBuffered(true);\n                renderer();\n                this.setBuffered(buf);\n                this.autoShow();\n            }\n        }\n\n        /**\n         * Renders a pattern of colors on the strip\n         */\n        showColors(leds: string, interval: number = 400) {\n            const n = this._length;\n            let tempColor = \"\";\n            let i = 0;\n            let pi = 0;\n\n            this.queueAnimation(() => {\n                const bf = this.buffered();\n                this.setBuffered(true);\n\n                while (i < leds.length) {\n                    const currChar = leds.charAt(i++);\n                    const isSpace = currChar == ' ' || currChar == '\\n' || currChar == '\\r';\n                    if (!isSpace)\n                        tempColor += currChar;\n\n                    if ((isSpace || i == leds.length) && tempColor) {\n                        this.setPixelColor(pi++, color.parseColor(tempColor))\n                        tempColor = \"\";\n                        if (pi == n) {\n                            this.show();\n                            pause(interval);\n                            pi = 0;\n                            break;\n                        }\n                    }\n                }\n\n                this.setBuffered(bf);\n                return i < leds.length;\n            });\n        }\n\n        //%\n        private queueAnimation(render: () => boolean) {\n            if (!this._animationQueue) {\n                this._animationQueue = new control.AnimationQueue();\n                this._animationQueue.interval = 50;\n                this._lastAnimation = undefined;\n                this._lastAnimationRenderer = undefined;\n            }\n            this._animationQueue.runUntilDone(render);\n        }\n\n        /**\n         * Stop the current animation and any other animations ready to show.\n         */\n        //% blockId=light_stop_all_animations block=\"%strip|stop all animations\"\n        //% help=\"light/neopixelstrip/stop-all-animations\"\n        //% weight=85 blockGap=8\n        //% group=\"More\" advanced=true\n        stopAllAnimations() {\n            if (this._animationQueue) {\n                this._animationQueue.cancel();\n                this._lastAnimation = undefined;\n                this._lastAnimationRenderer = undefined;\n            }\n        }\n\n        /**\n         * Enables or disables automatically calling show when a change is made\n         * @param on call show whenever a light is modified\n         */\n        //% blockId=light_set_buffered block=\"set %strip buffered  %on\"\n        //% help=\"light/neopixelstrip/set-buffered\"\n        //% weight=86 blockGap=8\n        //% group=\"Configuration\" advanced=true\n        setBuffered(on: boolean): void {\n            if (this._parent) this._parent.setBuffered(on);\n            else this._buffered = on;\n        }\n\n        /**\n         * Gets a value indicated if the changes are buffered\n         */\n        //% weight=85 blockGap=8\n        //% group=\"Configuration\" advanced=true\n        buffered(): boolean {\n            return this._parent ? this._parent.buffered() : this._buffered;\n        }\n\n        /**\n         * Sets the color mode and clears the colors.\n         * @param mode the kind of color encoding required by the programmable lights\n         */\n        //% blockId=light_set_mode block=\"set %strip mode to %mode\"\n        //% help=\"light/neopixelstrip/set-mode\"\n        //% weight=1 blockGap=8\n        //% group=\"Configuration\" advanced=true\n        setMode(mode: NeoPixelMode): void {\n            if (this._parent)\n                this._parent.setMode(mode);\n            else if (this._mode != mode) {\n                this._mode = mode;\n                this.reallocateBuffer();\n            }\n        }\n\n        /**\n         * Sets the number of LEDs on a strip\n         * @param numleds \n         */\n        //% blockId=light_set_length block=\"set %strip length to %length pixels\"\n        //% weight=1 blockGap=8\n        //% length.shadow=lightLengthPicker\n        //% group=\"Configuration\" advanced=true\n        setLength(numleds: number): void {\n            const n = Math.max(0, numleds | 0);\n            // lazy update\n            if (n != this._length) {\n                if (this._parent)\n                    this._length = Math.min(n, this._parent.length() - this._start);\n                else {\n                    this._length = n;\n                    this.reallocateBuffer();\n                }\n            }\n        }\n\n        private autoShow() {\n            if (!this.buffered()) {\n                this.show();\n                pause(1);\n            }\n        }\n\n        private setBufferRGB(offset: number, red: number, green: number, blue: number): void {\n            const b = this.buf;\n            // https://cdn-shop.adafruit.com/datasheets/APA102.pdf\n            switch (this._mode) {\n                case NeoPixelMode.RGB_RGB:\n                    b[offset] = red;\n                    b[offset + 1] = green;\n                    b[offset + 2] = blue;\n                    break;\n                case NeoPixelMode.APA102:\n                    // https://cdn-shop.adafruit.com/datasheets/APA102.pdf\n                    b[offset] = 0xe0 | 0x1f; // full brightness\n                    b[offset + 1] = blue;\n                    b[offset + 2] = green;\n                    b[offset + 3] = red;\n                    break;\n                default:\n                    b[offset + 0] = green;\n                    b[offset + 1] = red;\n                    b[offset + 2] = blue;\n                    break;\n            }\n        }\n\n        private reallocateBuffer(): void {\n            if (this._parent) return; // not supported in ranges\n            const stride = this.stride();\n            this._buf = control.createBuffer(this._length * stride);\n            this._brightnessBuf = undefined;\n            this._sendBuf = undefined;\n        }\n\n        // From here onwards, these block definitions are there for compatibility with old blocks\n        // (that have the default instance logic)\n\n        /**\n         * Set all of the pixels on the strip to one RGB color.\n         * @param rgb RGB color of the LED\n         */\n        //% blockId=\"neopixel_set_strip_color\" block=\"set all pixels to %rgb=colorNumberPicker\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __setAll(rgb: number) {\n            this.setAll(rgb);\n        }\n\n        /**\n         * Display 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, 0 to autoscale\n         */\n        //% blockId=neopixel_show_bar_graph block=\"graph %value |up to %high\" icon=\"\\uf080\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __graph(value: number, high: number): void {\n            this.graph(value, high);\n        }\n\n        /**\n         * Set the pixel to a given color.\n         * You need to call ``show`` to make the changes visible.\n         * @param pixeloffset position of the NeoPixel in the strip\n         * @param color RGB color of the LED\n         */\n        //% blockId=\"neopixel_set_pixel_color\" block=\"set pixel color at %pixeloffset|to %rgb=colorNumberPicker\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __setPixelColor(pixeloffset: number, color: number): void {\n            this.setPixelColor(pixeloffset, color);\n        }\n\n        /**\n         * Gets the pixel color.\n         * @param pixeloffset position of the NeoPixel in the strip\n         */\n        //% blockId=\"neopixel_get_pixel_color\" block=\"pixel color at %pixeloffset\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __pixelColor(pixeloffset: number): number {\n            return this.pixelColor(pixeloffset);\n        }\n\n        /**\n         * Set the white brightness of a pixel in a NeoPixel strip of RGB+W LEDs.\n         * This only works for RGB+W NeoPixels.\n         * @param pixeloffset position of the LED in the strip\n         * @param white brightness of the white LED\n         */\n        //% blockId=\"neopixel_set_pixel_white_led\" block=\"set pixel white LED at %pixeloffset|to %white\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __setPixelWhiteLED(pixeloffset: number, white: number): void {\n            this.setPixelWhiteLED(pixeloffset, white);\n        }\n\n        /**\n         * Make the strip show all the new changes for the pixels.\n         */\n        //% blockId=\"neopixel_show\" block=\"show\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __show(): void {\n            this.show();\n        }\n\n        /**\n         * Turn off all pixel LEDs.\n         */\n        //% blockId=\"neopixel_clear\" block=\"clear\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __clear(): void {\n            this.clear();\n        }\n\n        /**\n         * Get the number of pixels on the strip\n         */\n        //% blockId=\"neopixel_length\" block=\"length\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __length() {\n            return this.length();\n        }\n\n        /**\n         * Set the brightness of the strip. This flag only applies to future operation.\n         * @param brightness a measure of LED brightness in 0-255. eg: 20\n         */\n        //% blockId=\"neopixel_set_brightness\" block=\"set brightness %brightness\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __setBrightness(brightness: number): void {\n            this.setBrightness(brightness);\n        }\n\n        /**\n         * Get the brightness of the pixel strip.\n         */\n        //% blockId=\"neopixel_get_brightness\" block=\"brightness\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __brightness(): number {\n            return this.brightness();\n        }\n\n        /**\n         * Create a range of pixels.\n         * @param start offset in the NeoPixel strip to start the range\n         * @param length number of pixels in the range. eg: 4\n         */\n        //% blockId=\"neopixel_range\" block=\"range from %start|with %length|pixels\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __range(start: number, length: number): NeoPixelStrip {\n            return this.range(start, length);\n        }\n\n        /**\n         * Shift LEDs forward and clear with zeros.\n         * You need to call ``show`` to make the changes visible.\n         * @param offset number of pixels to shift forward, eg: 1\n         */\n        //% blockId=\"neopixel_move_pixels\" block=\"%kind=MoveKind|by %offset\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __move(kind: LightMove, offset: number = 1): void {\n            this.move(kind, offset);\n        }\n\n        /**\n         * Move a photon effect along the pixel strip by a number of steps.\n         * @param steps number of steps (lights) to move, eg: 1\n         */\n        //% blockId=neophoton_fd block=\"photon forward by %steps\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __photonForward(steps: number) {\n            this.photonForward(steps);\n        }\n\n        /**\n         * Switch the direction of the photon pulse.\n         */\n        //% blockId=neophoton_flip block=\"photon flip\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __photonFlip() {\n            this.photonFlip();\n        }\n\n        /**\n         * Set the photon color.\n         * @param color the color of the photon\n         */\n        //% blockId=neophoton_set_color block=\"photon set pen color %color\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __setPhotonColor(color: number) {\n            // The photon color has since changed, and we now use setPhotonPenHue to set the hue of the photon color\n            this.setPhotonPenHue(color);\n        }\n\n        /**\n         * Set the photon mode to pen up, pen down, or eraser.\n         * @param mode the desired mode\n         */\n        //% blockId=neophoton_set_photon block=\"photon %mode\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __setPhotonMode(mode: PhotonMode) {\n            this.setPhotonMode(mode);\n        }\n\n        /**\n         * Show an animation or queue an animation in the animation queue\n         * @param animation the animation to run\n         * @param duration the duration to run in milliseconds, eg: 500\n         */\n        //% blockId=neopixel_show_animation block=\"show %animation=light_animation|animation for %duration=timePicker|ms\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __showAnimation(animation: NeoPixelAnimation, duration: number) {\n            this.showAnimation(animation, duration);\n        }\n\n        /**\n         * Show a single animation frame\n         * @param animation the animation to run\n         */\n        //% blockId=neopixel_show_animation_frame block=\"show animation frame %animation=light_animation\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __showAnimationFrame(animation: NeoPixelAnimation) {\n            this.showAnimationFrame(animation);\n        }\n\n        /**\n         * Stop the current animation and any other animations ready to show.\n         */\n        //% blockId=neopixel_stop_all_animations block=\"stop all animations\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __stopAllAnimations() {\n            this.stopAllAnimations();\n        }\n\n        /**\n         * Enables or disables automatically calling show when a change is made\n         * @param on call show whenever a light is modified\n         */\n        //% blockId=neopixel_set_buffered block=\"set buffered  %on\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __setBuffered(on: boolean): void {\n            this.setBuffered(on);\n        }\n\n        /**\n         * Sets the color mode and clears the colors.\n         * @param mode the kind of color encoding required by the programmable lights\n         */\n        //% blockId=neopixel_set_mode block=\"set mode %mode\"\n        //% deprecated=1\n        //% defaultInstance=light.pixels\n        __setMode(mode: NeoPixelMode): void {\n            this.setMode(mode);\n        }\n    }\n\n    /**\n     * Creates a strip of colored LEDs (WS2812b)\n     */\n    //% blockId=\"neopixel_create\" block=\"create WS2812 strip|pin %pin|with %numleds pixels\"\n    //% help=\"light/create-neo-pixel-strip\"\n    //% trackArgs=0,2\n    //% parts=\"neopixel\"\n    //% weight=100 blockSetVariable=strip\n    //% advanced=true blockHidden=1\n    export function createNeoPixelStrip(\n        pin: DigitalInOutPin,\n        numleds: number = 10,\n        mode?: NeoPixelMode\n    ): NeoPixelStrip {\n        if (!mode)\n            mode = NeoPixelMode.RGB;\n\n        const strip = new NeoPixelStrip();\n        strip._mode = mode;\n        strip._length = Math.max(0, numleds | 0);\n        strip._dataPin = pin;\n        if (strip._dataPin) // board with no-board LEDs won't have a default pin\n            strip._dataPin.digitalWrite(false);\n        return strip;\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     */\n    //% blockId=\"neopixel_rgb\" block=\"red %red|green %green|blue %blue\"\n    //% red.min=0 red.max=255 green.min=0 green.max=255 blue.min=0 blue.max=255\n    //% help=\"light/rgb\"\n    //% group=\"Color\" weight=19 blockGap=8\n    export function rgb(red: number, green: number, blue: number): number {\n        return color.rgb(red, green, blue);\n    }\n\n    /**\n     * Get the RGB value of a known color\n    */\n    //% blockId=neopixel_colors block=\"%color\"\n    //% help=\"light/colors\"\n    //% shim=TD_ID\n    //% group=\"Color\" weight=20 blockGap=8\n    export function colors(color: Colors): number {\n        return color;\n    }\n\n    /**\n     * Convert an HSV (hue, saturation, value) color to RGB\n     * @param hue value of the hue channel between 0 and 255. eg: 255\n     * @param sat value of the saturation channel between 0 and 255. eg: 255\n     * @param val value of the value channel between 0 and 255. eg: 255\n     */\n\n    //% blockId=\"neopixel_hsv\" block=\"hue %hue|sat %sat|val %val\"\n    //% hue.min=0 hue.max=255 sat.min=0 sat.max=255 val.min=0 val.max=255\n    //% help=\"light/hsv\"\n    //% group=\"Color\" weight=17\n    export function hsv(hue: number, sat: number = 255, val: number = 255): number {\n        return color.hsv(hue, sat, val);\n    }\n\n    /**\n     * Use color.fade instead\n     * @param color color to fade\n     * @param brightness the amount of brightness to apply to the color, eg: 128\n     */\n    //% blockId=\"neopixel_fade\" block=\"fade %color=neopixel_colors|by %brightness\"\n    //% brightness.min=0 brightness.max=255\n    //% help=\"light/fade\"\n    //% group=\"Color\" weight=18 blockGap=8\n    //% blockHidden=true deprecated\n    export function fade(c: number, brightness: number): number {\n        return color.fade(c, brightness);\n    }\n\n    /**\n     * An animation of a NeoPixel\n     */\n    //% fixedInstances\n    export class NeoPixelAnimation {\n        constructor() { }\n\n        /**\n         * Creates an animator instance\n         * @param strip the strip to execute on\n         */\n        createRenderer(strip: NeoPixelStrip): () => boolean {\n            return undefined;\n        }\n    }\n\n    export class RainbowCycleAnimation extends NeoPixelAnimation {\n        public delay: number;\n        constructor(delay: number) {\n            super();\n            this.delay = delay;\n        }\n\n        public createRenderer(strip: NeoPixelStrip): () => boolean {\n            const n = strip.length();\n            let hueOffset = 0;\n            return () => {\n                for (let i = 0; i < n; i++) {\n                    strip.setPixelColor(i, color.hsv(((i * 256) / (n - 1) + hueOffset) % 0xff, 0xff, 0xff));\n                }\n                hueOffset += Math.ceil(128 / n);\n                if (hueOffset >= 0xff) {\n                    hueOffset = 0;\n                    return false;\n                } else {\n                    return true;\n                }\n            }\n        }\n    }\n\n    //% fixedInstance block=\"rainbow\" whenUsed jres blockIdentity=\"light._animationPicker\"\n    export const rainbowAnimation: NeoPixelAnimation = new RainbowCycleAnimation(50);\n\n    export class RunningLightsAnimation extends NeoPixelAnimation {\n        public red: number;\n        public green: number;\n        public blue: number;\n        public delay: number;\n\n        constructor(red: number, green: number, blue: number, delay: number) {\n            super();\n            this.red = red;\n            this.green = green;\n            this.blue = blue;\n\n            this.delay = delay;\n        }\n\n        public createRenderer(strip: NeoPixelStrip): () => boolean {\n            const l = strip.length();\n            let iteration = 0;\n            let step = 0;\n            return () => {\n                if (iteration < l * 2) {\n                    step++;\n                    for (let i = 0; i < l; i++) {\n                        const level = (Math.isin(i + step) * 127) + 128;\n                        strip.setPixelColor(i, color.rgb(level * this.red / 255, level * this.green / 255, level * this.blue / 255));\n                    }\n                    iteration++;\n                    return true;\n                } else {\n                    step = 0;\n                    iteration = 0;\n                    return false;\n                }\n            }\n        }\n    }\n\n    //% fixedInstance block=\"running lights\" jres blockIdentity=\"light._animationPicker\"\n    export const runningLightsAnimation: NeoPixelAnimation = new RunningLightsAnimation(0xff, 0, 0, 50);\n\n    class CometAnimation extends NeoPixelAnimation {\n        public red: number;\n        public green: number;\n        public blue: number;\n        public delay: number;\n\n        constructor(red: number, green: number, blue: number, delay: number) {\n            super();\n            this.red = red;\n            this.green = green;\n            this.blue = blue;\n            this.delay = delay;\n        }\n\n        public createRenderer(strip: NeoPixelStrip): () => boolean {\n            const l = strip.length();\n            const spacing = (255 / l) >> 0;\n            let start = -1;\n            let step = 0;\n            const offsets: number[] = [];\n            for (let i = 0; i < l; i++) {\n                offsets[i] = spacing * i;\n            }\n            return () => {\n                for (let i = 0; i < l; i++) {\n                    offsets[i] = (offsets[i] + (step * 2)) % 255\n                    strip.setPixelColor(i, color.rgb(255 - offsets[i], this.green, this.blue));\n                }\n                step++;\n                if (step * 2 > 0xff) {\n                    step = 0;\n                    return false;\n                }\n                return true;\n            }\n        }\n    }\n\n    //% fixedInstance block=\"comet\" jres blockIdentity=\"light._animationPicker\"\n    export const cometAnimation: NeoPixelAnimation = new CometAnimation(0xff, 0, 0xff, 50);\n\n    export class SparkleAnimation extends NeoPixelAnimation {\n        public rgb: number;\n        public delay: number;\n\n        constructor(red: number, green: number, blue: number, delay: number) {\n            super();\n            this.rgb = color.rgb(red, green, blue);\n            this.delay = delay;\n        }\n\n        public createRenderer(strip: NeoPixelStrip): () => boolean {\n            const l = strip.length();\n            let count = 0;\n            let pixel = -1;\n            let pixelColor = 0;\n            return () => {\n                if (count == 0)\n                    strip.clear();\n                if (pixel < 0) {\n                    pixel = Math.randomRange(0, l - 1);\n                    pixelColor = strip.pixelColor(pixel);\n                    strip.setPixelColor(pixel, this.rgb);\n\n                } else {\n                    strip.setPixelColor(pixel, pixelColor);\n                    pixel = -1;\n                }\n                count++;\n                if (count > 50) {\n                    count = 0;\n                    return false;\n                } else {\n                    return true;\n                }\n            }\n        }\n    }\n\n    //% fixedInstance block=\"sparkle\" jres blockIdentity=\"light._animationPicker\"\n    export const sparkleAnimation: NeoPixelAnimation = new SparkleAnimation(0xff, 0xff, 0xff, 50);\n\n    class ColorWipeAnimation extends NeoPixelAnimation {\n        public rgb: number;\n        public delay: number;\n\n        constructor(rgb: number, delay: number) {\n            super();\n            this.rgb = rgb;\n            this.delay = delay;\n        }\n\n        public createRenderer(strip: NeoPixelStrip): () => boolean {\n            const l = strip.length();\n            let i = 0;\n            let reveal = true;\n            return () => {\n                if (i < l) {\n                    if (reveal) {\n                        strip.setPixelColor(i, this.rgb);\n                    } else {\n                        strip.setPixelColor(i, 0);\n                    }\n                    i++;\n                } else {\n                    reveal = !reveal;\n                    i = 0;\n                    if (reveal)\n                        return false;\n                }\n                return true;\n            }\n        }\n    }\n\n    //% fixedInstance block=\"color wipe\" jres blockIdentity=\"light._animationPicker\"\n    export const colorWipeAnimation: NeoPixelAnimation = new ColorWipeAnimation(0x0000ff, 50);\n\n    class TheatreChaseAnimation extends NeoPixelAnimation {\n        public rgb: number;\n        public delay: number;\n\n        constructor(red: number, green: number, blue: number, delay: number) {\n            super();\n            this.rgb = color.rgb(red, green, blue);\n            this.delay = delay;\n        }\n\n        public createRenderer(strip: NeoPixelStrip): () => boolean {\n            const l = strip.length();\n            let j = 0;\n            let q = 0;\n            let on = false;\n            return () => {\n                if (j < 10) { // 10 cycles of chasing\n                    if (q < 3) {\n                        if (on) {\n                            for (let i = 0; i < l; i = i + 3) {\n                                strip.setPixelColor(i + q, this.rgb); // every third pixel on\n                            }\n                        }\n                        else {\n                            for (let i = 0; i < l; i = i + 3) {\n                                strip.setPixelColor(i + q, 0); // every third pixel off\n                            }\n                        }\n                        on = !on;\n                        q++;\n                    } else {\n                        q = 0;\n                    }\n                    j++;\n                } else {\n                    j = 0;\n                    return false;\n                }\n                return true;\n            }\n        }\n    }\n\n    //% fixedInstance block=\"theater chase\" jres blockIdentity=\"light._animationPicker\"\n    export const theaterChaseAnimation: NeoPixelAnimation = new TheatreChaseAnimation(0xff, 0, 0, 50);\n\n    /**\n     * An animation that can be shown on a light strip\n     * @param animation The animation type\n     */\n    //% blockId=light_animation_picker block=\"%animation\" shim=TD_ID\n    //% animation.fieldEditor=\"imagedropdown\"\n    //% animation.fieldOptions.columns=3\n    //% weight=0\n    //% group=\"More\"\n    export function _animationPicker(animation: NeoPixelAnimation): NeoPixelAnimation {\n        return animation;\n    }\n\n    /**\n  * Get the light length picker\n  * @param pixels number of LEDs\n  */\n    //% blockId=lightLengthPicker block=\"%pixels\"\n    //% blockHidden=true shim=TD_ID\n    //% colorSecondary=\"#FFFFFF\"\n    //% pixels.fieldEditor=\"numberdropdown\" pixels.fieldOptions.decompileLiterals=true\n    //% pixels.fieldOptions.data='[[\"7\", 7], [\"8\", 8], [\"12\", 12], [\"16\", 16], [\"24\", 24], [\"30\", 30], [\"60\", 60], [\"64\", 64], [\"90\", 90], [\"120\", 120], [\"144\", 144]]'\n    export function __lengthPicker(pixels: number): number {\n        return pixels;\n    }\n}\n","neopixeloverrides.ts":"//% weight=97\nnamespace light {\n\n}","ns.ts":"\n/**\n * Functions to operate colored LEDs.\n */\n//% weight=100 color=\"#0078d7\" icon=\"\\uf00a\"\nnamespace light {\n\n}","onboardstrip.ts":"namespace light {\n    let _onboardStrip: light.LightStrip;\n    /**\n     * Get the onboard light strip.\n     */\n    //% help=light/onboard-strip\n    //% blockId=\"neopixel_onboard_strip\" block=\"onboard strip\"\n    //% weight=111 blockGap=8\n    //% advanced=true\n    export function onboardStrip(): NeoPixelStrip {\n        if (_onboardStrip) return _onboardStrip;\n\n        { // try onboard cfg\n            const data = pins.pinByCfg(DAL.CFG_PIN_ONBOARD_DOTSTAR_DATA);\n            const clk = pins.pinByCfg(DAL.CFG_PIN_ONBOARD_DOTSTAR_CLOCK);\n            const dsnum = control.getConfigValue(DAL.CFG_NUM_ONBOARD_DOTSTARS, 0);\n            const neo = pins.pinByCfg(DAL.CFG_PIN_ONBOARD_NEOPIXEL);\n            const neonum = control.getConfigValue(DAL.CFG_NUM_ONBOARD_NEOPIXELS, 0);\n            if (data && clk && dsnum > 0) {\n                _onboardStrip = light.createAPA102Strip(data, clk, dsnum);\n                _onboardStrip.setBrightness(96);\n                return _onboardStrip;\n            } else if (neo && neonum > 0) {\n                _onboardStrip = light.createNeoPixelStrip(neo, neonum, NeoPixelMode.RGB);\n                return _onboardStrip;\n            }\n        }\n\n        { // resolve from pins\n            const data = pins.pinByCfg(DAL.CFG_PIN_DOTSTAR_DATA);\n            const clk = pins.pinByCfg(DAL.CFG_PIN_DOTSTAR_CLOCK);\n            const dsnum = control.getConfigValue(DAL.CFG_NUM_DOTSTARS, 0);\n            const neo = pins.pinByCfg(DAL.CFG_PIN_NEOPIXEL);\n            const neonum = control.getConfigValue(DAL.CFG_NUM_NEOPIXELS, 0);\n            if (data && clk && dsnum > 0) {\n                _onboardStrip = light.createAPA102Strip(data, clk, dsnum);\n                _onboardStrip.setBrightness(96);\n                return _onboardStrip;\n            } else if (neo && neonum > 0) {\n                _onboardStrip = light.createNeoPixelStrip(neo, neonum, NeoPixelMode.RGB);\n                return _onboardStrip;\n            } else {\n                _onboardStrip = light.createNeoPixelStrip(undefined, 0);\n            }\n        }\n\n        return _onboardStrip;\n    }\n}","pxt.json":"{\n    \"name\": \"light\",\n    \"description\": \"The programmable LED (WS2812b,APA102) driver.\",\n    \"dependencies\": {\n        \"core\": \"*\",\n        \"color\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"neopixel.ts\",\n        \"transitions.ts\",\n        \"create.ts\",\n        \"defaultstrip.ts\",\n        \"onboardstrip.ts\",\n        \"defaultlights.ts\",\n        \"defaultlightsoverrides.ts\",\n        \"ns.ts\",\n        \"neopixeloverrides.ts\",\n        \"animations.jres\",\n        \"targetoverrides.ts\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"icon\": \"/static/libs/light.png\"\n}\n","targetoverrides.ts":"// define built-in strips here","test.ts":"\nlet strip = light.createStrip()\nstrip.setBrightness(20)\n\nfunction flash(n: number) {\n    control.runInParallel(() => {\n        strip.setPixelColor(n, 0x0000ff)\n        pause(1000)\n        strip.setPixelColor(n, 0x000000)\n    })\n}\n\nflash(0)\n\n","transitions.ts":"namespace easing {\n    export function linear(t: number): number { return t; }\n    export function inQuad(t: number): number { return t * t; }\n    export function outQuad(t: number): number { return t * (2 - t); }\n    export function inOutQuad(t: number): number { return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t; }\n    export function inCubic(t: number): number { return t * t * t; }\n    export function outCubic(t: number): number { return (--t) * t * t + 1; }\n    export function inOutCubic(t: number): number { return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1; }\n}\n\nnamespace light {\n    export class BrightnessTransition {\n        constructor() { }\n        apply(strip: LightStrip, t: number, start: number, end: number): void {\n\n        }\n    }\n\n    export class EasingBrightnessTransition extends BrightnessTransition {\n        private timeEasing: (t: number) => number;\n        private spatialEasing: (t: number) => number;\n\n        constructor(\n            timeEasing: (t: number) => number, \n            spatialEasing?: (t: number) => number) {\n            super();\n            this.timeEasing = timeEasing || easing.inOutQuad;\n            this.spatialEasing = spatialEasing;\n        }\n\n        apply(strip: LightStrip, t: number, start: number, end: number): void {\n            // t in [0..1]\n            const db = end - start;\n            const b = this.timeEasing(t); // [0..1]\n            if (!this.spatialEasing) {\n                strip.setBrightness(start + db * b);\n            }\n            else {\n                // convolve desired brightness with spacial easing function\n                const n = strip.length();\n                for (let i = 0; i < n; ++i) {\n                    const x = this.spatialEasing(i / (n - 1)); // [0..1]\n                    strip.setPixelBrightness(i, end - db * (1 - b) * x);\n                }\n            }\n        }\n    }\n\n    export class BrightnessTransitionPlayer {\n        private transition: BrightnessTransition;\n        private startBrightness: number;\n        private endBrightness: number;\n        private duration: number;\n        private startTime: number;\n        private repeat: number;\n        private yoyo: number;\n\n        constructor(\n            transition: BrightnessTransition,\n            startBrightness: number,\n            endBrightness: number,\n            duration: number,\n            repeat: number,\n            yoyo: boolean) {\n            this.transition = transition;\n            this.startBrightness = startBrightness;\n            this.endBrightness = endBrightness;\n            this.duration = duration;\n            this.startTime = control.millis();\n            this.repeat = repeat || 1;\n            this.yoyo = yoyo ? 1 : 0;\n        }\n\n        update(strip: LightStrip): boolean {\n            let elapsed = control.millis() - this.startTime;\n            if (elapsed > this.duration) {\n                this.yoyo = -this.yoyo;\n                if (this.repeat > 0)\n                    this.repeat--;\n                this.startTime = control.millis();\n                elapsed = 0;\n                return this.repeat != 0;\n            }\n\n            let t = elapsed / this.duration;\n            if (this.yoyo < 0)\n                t = 1 - t;\n            this.transition.apply(strip, t, this.startBrightness, this.endBrightness);\n            return true;\n        }\n    }\n}"},"lightsensor":{"README.md":"# lightsensor\n\nThe lightsensor library.\n\n","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum LightCondition {\n    //% block=\"dark\"\n    Dark = 1,  // SENSOR_THRESHOLD_LOW\n    //% block=\"bright\"\n    Bright = 2,  // SENSOR_THRESHOLD_HIGH\n    }\n\n// Auto-generated. Do not edit. Really.\n","lightsensor.cpp":"#include \"pxt.h\"\n#include \"AnalogSensor.h\"\n\n#ifdef CODAL_LIGHT_SENSOR_HEADER\n#include CODAL_LIGHT_SENSOR_HEADER\n#endif\n\n\n#ifndef CODAL_LIGHT_SENSOR\n#define CODAL_LIGHT_SENSOR AnalogSensor\n#endif\n\n#ifndef LIGHTSENSOR_SENSITIVITY\n#define LIGHTSENSOR_SENSITIVITY 868 // codal has 912 now\n#endif\n\n#ifndef LIGHTSENSOR_LOW_THRESHOLD\n#define LIGHTSENSOR_LOW_THRESHOLD 128\n#endif\n\n#ifndef LIGHTSENSOR_HIGH_THRESHOLD\n#define LIGHTSENSOR_HIGH_THRESHOLD 896\n#endif\n\nenum class LightCondition {\n    //% block=\"dark\"\n    Dark = SENSOR_THRESHOLD_LOW,\n    //% block=\"bright\"\n    Bright = SENSOR_THRESHOLD_HIGH\n};\n\nnamespace pxt {\n\nclass WLight {\n  public:\n    CODAL_LIGHT_SENSOR sensor;\n    WLight()\n        : sensor(*LOOKUP_PIN(LIGHT), DEVICE_ID_LIGHT_SENSOR) //\n    {\n        sensor.init();\n        sensor.setPeriod(50);\n        sensor.setSensitivity(LIGHTSENSOR_SENSITIVITY); \n        sensor.setLowThreshold(LIGHTSENSOR_LOW_THRESHOLD);\n        sensor.setHighThreshold(LIGHTSENSOR_HIGH_THRESHOLD);\n    }\n};\nSINGLETON_IF_PIN(WLight, LIGHT);\n\n}\n\nnamespace input {\n\n/**\n* Register an event that runs when light conditions (darker or brighter) change.\n* @param condition the condition that event triggers on\n*/\n//% help=input/on-light-condition-changed\n//% blockId=input_on_light_condition_changed block=\"on light %condition\"\n//% parts=\"lightsensor\"\n//% weight=84 blockGap=12\nvoid onLightConditionChanged(LightCondition condition, Action handler) {\n    auto wlight = getWLight();\n    if (NULL == wlight) return;    \n    auto sensor = wlight->sensor;\n\n    sensor.updateSample();\n    registerWithDal(sensor.id, (int)condition, handler);\n}\n\n/**\n * Read the light level applied to the LED screen in a range from 0 (dark) to 255 (bright).\n */\n//% help=input/light-level\n//% blockId=device_get_light_level block=\"light level\"\n//% parts=\"lightsensor\"\n//% weight=30 blockGap=8\nint lightLevel() {\n    auto wlight = getWLight();\n    if (NULL == wlight) return 127;\n    auto sensor = wlight->sensor;\n    // 0...1023\n    int value = sensor.getValue();\n    return value / 4;\n}\n\n/**\n* Set the threshold value for the light condition event.\n*/\n//% help=input/set-light-threshold\n//% blockId=lightsensor_set_threshold block=\"set %condition| light threshold to %value\"\n//% parts=\"lightsensor\"\n//% value.min=1 value.max=255\n//% group=\"More\" weight=13 blockGap=8\nvoid setLightThreshold(LightCondition condition, int value) {\n    auto wlight = getWLight();\n    if (NULL == wlight) return;\n    auto sensor = wlight->sensor;\n\n    int v = value * 4;\n    if (condition == LightCondition::Dark)\n        sensor.setLowThreshold(v);\n    else\n        sensor.setHighThreshold(v);\n}\n}\n","ns.ts":"\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\nnamespace input {\n}","pxt.json":"{\n    \"name\": \"lightsensor\",\n    \"description\": \"Onboard light level sensor\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"lightsensor.cpp\",\n        \"ns.ts\",\n        \"shims.d.ts\",\n        \"enums.d.ts\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace input {\n\n    /**\n     * Register an event that runs when light conditions (darker or brighter) change.\n     * @param condition the condition that event triggers on\n     */\n    //% help=input/on-light-condition-changed\n    //% blockId=input_on_light_condition_changed block=\"on light %condition\"\n    //% parts=\"lightsensor\"\n    //% weight=84 blockGap=12 shim=input::onLightConditionChanged\n    function onLightConditionChanged(condition: LightCondition, handler: () => void): void;\n\n    /**\n     * Read the light level applied to the LED screen in a range from 0 (dark) to 255 (bright).\n     */\n    //% help=input/light-level\n    //% blockId=device_get_light_level block=\"light level\"\n    //% parts=\"lightsensor\"\n    //% weight=30 blockGap=8 shim=input::lightLevel\n    function lightLevel(): int32;\n\n    /**\n     * Set the threshold value for the light condition event.\n     */\n    //% help=input/set-light-threshold\n    //% blockId=lightsensor_set_threshold block=\"set %condition| light threshold to %value\"\n    //% parts=\"lightsensor\"\n    //% value.min=1 value.max=255\n    //% group=\"More\" weight=13 blockGap=8 shim=input::setLightThreshold\n    function setLightThreshold(condition: LightCondition, value: int32): void;\n}\n\n// Auto-generated. Do not edit. Really.\n","test.ts":"for(let i = 0; i < 100; ++i) {\n    pause(500)\n    console.log(`light=${input.lightLevel()}`);\n}"},"microphone":{"README.md":"# microphone\n\nThe microphone library.\n\n","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare enum LoudnessCondition {\n    //% block=\"quiet\"\n    Quiet = 1,  // LEVEL_THRESHOLD_LOW\n    //% block=\"loud\"\n    Loud = 2,  // LEVEL_THRESHOLD_HIGH\n    }\n\n// Auto-generated. Do not edit. Really.\n","microphone.cpp":"#include \"pxt.h\"\n#include \"LevelDetector.h\"\n#include \"LevelDetectorSPL.h\"\n\n#define MICROPHONE_MIN 52.0f\n#define MICROPHONE_MAX 120.0f\n\nnamespace pxt {\n    codal::LevelDetectorSPL* getMicrophoneLevel();\n}\n\nnamespace input {\n/**\n* Registers an event that runs when a loud sound is detected\n*/\n//% help=input/on-loud-sound\n//% blockId=input_on_loud_sound block=\"on loud sound\"\n//% parts=\"microphone\"\n//% weight=88 blockGap=12\nvoid onLoudSound(Action handler) {\n    pxt::getMicrophoneLevel(); // wake up service\n    registerWithDal(DEVICE_ID_MICROPHONE, LEVEL_THRESHOLD_HIGH, handler);\n}\n\n/**\n* Reads the loudness through the microphone from 0 (silent) to 255 (loud)\n*/\n//% help=input/sound-level\n//% blockId=device_get_sound_level block=\"sound level\"\n//% parts=\"microphone\"\n//% weight=34 blockGap=8\nint soundLevel() {\n    auto level = pxt::getMicrophoneLevel();\n    if (NULL == level)\n        return MICROPHONE_MIN;        \n    const int micValue = level->getValue();\n    const int scaled = max(MICROPHONE_MIN, min(micValue, MICROPHONE_MAX)) - MICROPHONE_MIN;\n    return min(0xff, scaled * 0xff / (MICROPHONE_MAX - MICROPHONE_MIN));\n}\n\n/**\n* Sets the minimum threshold for a loud sound\n*/\n//% help=input/set-loud-sound-threshold\n//% blockId=input_set_loud_sound_threshold block=\"set loud sound threshold %value\"\n//% parts=\"microphone\"\n//% value.min=1 value.max=255\n//% group=\"More\" weight=14 blockGap=8\nvoid setLoudSoundThreshold(int value) {\n    auto level = pxt::getMicrophoneLevel();\n    if (NULL == level)\n        return;\n\n    value = max(0, min(0xff, value));\n    const int scaled = MICROPHONE_MIN + value * (MICROPHONE_MAX - MICROPHONE_MIN) / 0xff;\n    level->setHighThreshold(scaled);\n}\n}","microphonehw.cpp":"#include \"pxt.h\"\n#include \"LevelDetector.h\"\n#include \"LevelDetectorSPL.h\"\n#include \"DataStream.h\"\n\n#ifndef MIC_DEVICE\n// STM?\nclass DummyDataSource : public codal::DataSource {\n  public:\n    DummyDataSource() {}\n};\nclass PanicPDM {\n  public:\n    uint8_t level;\n    DummyDataSource source;\n    codal::DataStream output;\n\n    PanicPDM(Pin &sd, Pin &sck) : output(source) { target_panic(PANIC_MICROPHONE_MISSING); }\n    void enable() {}\n    void disable() {}\n};\n#define MIC_DEVICE PanicPDM\n#endif\n\n#ifndef MIC_INIT\n#define MIC_INIT                                                                                   \\\n        : microphone(*LOOKUP_PIN(MIC_DATA), *LOOKUP_PIN(MIC_CLOCK)) \\\n        , level(microphone.output, 95.0, 75.0, 9, 52, DEVICE_ID_MICROPHONE)\n#endif\n\n#ifndef MIC_ENABLE\n#define MIC_ENABLE microphone.enable()\n#endif\n\nnamespace pxt {\n\nclass WMicrophone {\n  public:\n    MIC_DEVICE microphone;\n    LevelDetectorSPL level;\n    WMicrophone() MIC_INIT { MIC_ENABLE; }\n};\nSINGLETON(WMicrophone);\n\ncodal::LevelDetectorSPL *getMicrophoneLevel() {\n    auto wmic = getWMicrophone();\n    return wmic ? &(wmic->level) : NULL;\n}\n\n} // namespace pxt\n","pxt.json":"{\n    \"name\": \"microphone\",\n    \"description\": \"The microphone library\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"microphone.cpp\",\n        \"microphonehw.cpp\",\n        \"enums.d.ts\",\n        \"shims.d.ts\",\n        \"targetoverrides.ts\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true,\n    \"icon\": \"/static/libs/microphone.png\"\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace input {\n\n    /**\n     * Registers an event that runs when a loud sound is detected\n     */\n    //% help=input/on-loud-sound\n    //% blockId=input_on_loud_sound block=\"on loud sound\"\n    //% parts=\"microphone\"\n    //% weight=88 blockGap=12 shim=input::onLoudSound\n    function onLoudSound(handler: () => void): void;\n\n    /**\n     * Reads the loudness through the microphone from 0 (silent) to 255 (loud)\n     */\n    //% help=input/sound-level\n    //% blockId=device_get_sound_level block=\"sound level\"\n    //% parts=\"microphone\"\n    //% weight=34 blockGap=8 shim=input::soundLevel\n    function soundLevel(): int32;\n\n    /**\n     * Sets the minimum threshold for a loud sound\n     */\n    //% help=input/set-loud-sound-threshold\n    //% blockId=input_set_loud_sound_threshold block=\"set loud sound threshold %value\"\n    //% parts=\"microphone\"\n    //% value.min=1 value.max=255\n    //% group=\"More\" weight=14 blockGap=8 shim=input::setLoudSoundThreshold\n    function setLoudSoundThreshold(value: int32): void;\n}\n\n// Auto-generated. Do not edit. Really.\n","targetoverrides.ts":"// target specific code","test.ts":"// tests"},"mixer":{"SoundOutput.h":"#include \"dmac.h\"\n#include \"SAMD21DAC.h\"\n#include \"Mixer.h\"\n\n// DAC always on PA02 on SAMD21\n#define DAC_PIN PA02\n\nclass SoundOutput {\n  public:\n    SAMD21DAC dac;\n\n    SoundOutput(DataSource &data) : dac(*lookupPin(DAC_PIN), pxt::getWDMAC()->dmac, data) {}\n\n    void setOutput(int output) { (void)output; }\n};\n","headphone.svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"142\" height=\"180\" viewBox=\"0 0 142 180\"><rect ry=\".3\" rx=\"1\" y=\"58.615\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><rect ry=\".3\" rx=\"1\" y=\"32.043\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><path d=\"M.346 7.296c-.394.39-.31 4.797-.18 4.898l13.404 10.18c.117.12.337 4.76.73 4.368l5.506-5.56.01.01 6.51-6.444c.39-.392-4.25-.614-4.366-.73L11.777.612c-.1-.132-4.51-.215-4.898.18L4.087 3.636l-.01-.01-3.73 3.67z\" fill=\"#b3b3b3\"/><rect ry=\"6.85\" rx=\"4.571\" y=\"84.758\" x=\"-20.128\" height=\"75.571\" width=\"39.643\" transform=\"rotate(-45)\"/><rect ry=\".374\" rx=\"1.038\" y=\"29.442\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"55.939\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"82.392\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\"2.317\" rx=\"2.183\" y=\"158.876\" x=\"-9.774\" height=\"25.568\" width=\"18.935\" transform=\"rotate(-45)\"/><path d=\"M128.588 128.82s14.97 11.165 7.547 26.35c-8.426 17.24-25.57 20.653-25.57 20.653\" fill=\"none\" stroke=\"#000\" stroke-width=\"6.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>","instrument.ts":"namespace music.sequencer {\n    const BUFFER_SIZE = 12;\n\n    let currentSequencer: sequencer.Sequencer;\n\n    /**\n     * Byte encoding format for songs\n     * FIXME: should this all be word aligned?\n     *\n     * song(7 + length of all tracks bytes)\n     *     0 version\n     *     1 beats per minute\n     *     3 beats per measure\n     *     4 ticks per beat\n     *     5 measures\n     *     6 number of tracks\n     *     ...tracks\n     *\n     * track(6 + instrument length + note length bytes)\n     *     0 id\n     *     1 flags\n     *     2 instruments byte length\n     *     4...instrument\n     *     notes byte length\n     *     ...note events\n     *\n     * instrument(28 bytes)\n     *     0 waveform\n     *     1 amp attack\n     *     3 amp decay\n     *     5 amp sustain\n     *     7 amp release\n     *     9 amp amp\n     *     11 pitch attack\n     *     13 pitch decay\n     *     15 pitch sustain\n     *     17 pitch release\n     *     19 pitch amp\n     *     21 amp lfo freq\n     *     22 amp lfo amp\n     *     24 pitch lfo freq\n     *     25 pitch lfo amp\n     *     27 octave\n     *\n     * drum(5 + 7 * steps bytes)\n     *     0 steps\n     *     1 start freq\n     *     3 start amp\n     *     5...steps\n     *\n     * drum step(7 bytes)\n     *     0 waveform\n     *     1 freq\n     *     3 volume\n     *     5 duration\n     *\n     * note event(5 + 1 * polyphony bytes)\n     *     0 start tick\n     *     2 end tick\n     *     4 polyphony\n     *     5...notes(1 byte each)\n     *\n     * note (1 byte)\n     *     lower six bits = note - (instrumentOctave - 2) * 12\n     *     upper two bits are the enharmonic spelling:\n     *          0 = normal\n     *          1 = flat\n     *          2 = sharp\n     */\n\n    export class Song extends Playable {\n        tracks: Track[];\n\n        constructor(public buf: Buffer) {\n            super();\n            this.tracks = [];\n\n            let currentOffset = 7;\n            for (let i = 0; i < this.numberOfTracks; i++) {\n                let track: Track = new MelodicTrack(this.buf, currentOffset);\n\n                if (!track.isMelodicTrack) {\n                    track = new DrumTrack(this.buf, currentOffset)\n                }\n\n                this.tracks.push(track);\n                currentOffset += track.byteLength;\n            }\n        }\n\n        get version(): number {\n            return this.buf[0];\n        }\n\n        set version(value: number) {\n            this.buf[0] = value;\n        }\n\n        get beatsPerMinute(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, 1);\n        }\n\n        set beatsPerMinute(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, 1, value);\n        }\n\n        get beatsPerMeasure(): number {\n            return this.buf[3];\n        }\n\n        set beatsPerMeasure(value: number) {\n            this.buf[3] = value;\n        }\n\n        get ticksPerBeat(): number {\n            return this.buf[4];\n        }\n\n        set ticksPerBeat(value: number) {\n            this.buf[4] = value;\n        }\n\n        get measures(): number {\n            return this.buf[5];\n        }\n\n        set measures(value: number) {\n            this.buf[5] = value;\n        }\n\n        get numberOfTracks(): number {\n            return this.buf[6];\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (control.deviceDalVersion() === \"sim\") {\n                const seq = new _SimulatorSequencer();\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    seq.play(this.buf, false);\n\n                    pauseUntil(() => seq.state() === \"stop\");\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    seq.play(this.buf, false);\n                }\n                else {\n                    seq.play(this.buf, true);\n                }\n            }\n            else {\n                if (currentSequencer) currentSequencer.stop();\n                currentSequencer = new sequencer.Sequencer(this);\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    let seq = currentSequencer;\n                    currentSequencer.start(false);\n                    pauseUntil(() => !seq.isRunning);\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    currentSequencer.start(false);\n                }\n                else {\n                    currentSequencer.start(true);\n                }\n            }\n        }\n    }\n\n    export class Envelope {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(10);\n            this.offset = this.offset || 0;\n        }\n\n        // The time in ms for the envelope to reach its maximum value\n        get attack(): number {\n            return this.getValue(0);\n        }\n\n        set attack(value: number) {\n            this.setValue(0, value);\n        }\n\n        // The time in ms for the envelope to reach its sustain value after reaching its maximum value\n        get decay(): number {\n            return this.getValue(2);\n        }\n\n        set decay(value: number) {\n            this.setValue(2, value);\n        }\n\n        // The value (0-1024) to hold at during the sustain stage\n        get sustain(): number {\n            return this.getValue(4);\n        }\n\n        set sustain(value: number) {\n            this.setValue(4, value);\n        }\n\n        // The time in ms for the envelope to reach 0 after the gate length ends\n        get release(): number {\n            return this.getValue(6);\n        }\n\n        set release(value: number) {\n            this.setValue(6, value);\n        }\n\n        // The maximum value that this envelope will reach\n        get amplitude(): number {\n            return this.getValue(8);\n        }\n\n        set amplitude(value: number) {\n            this.setValue(8, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class LFO {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(3);\n            this.offset = this.offset || 0;\n        }\n\n        get frequency(): number {\n            return this.buf[this.offset];\n        }\n\n        set frequency(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get amplitude(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + 1);\n        }\n\n        set amplitude(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + 1, value);\n        }\n    }\n\n    export class NoteEvent {\n        constructor(public buf: Buffer, public offset: number) {\n\n        }\n\n        get startTick(): number {\n            return this.getValue(0);\n        }\n\n        set startTick(value: number) {\n            this.setValue(0, value);\n        }\n\n        get endTick(): number {\n            return this.getValue(2);\n        }\n\n        set endTick(value: number) {\n            this.setValue(2, value);\n        }\n\n        get polyphony(): number {\n            return this.buf[this.offset + 4];\n        }\n\n        set polyphony(value: number) {\n            this.buf[this.offset + 4] = value;\n        }\n\n        get byteLength() {\n            return this.polyphony + 5;\n        }\n\n        getNote(offset: number, octave?: number) {\n            const value = this.buf[this.offset + offset + 5] & 0x3f;\n            if (octave !== undefined) {\n                return value + (octave - 2) * 12\n            }\n            return value\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class Track {\n        currentNoteEvent: NoteEvent;\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.currentNoteEvent = new NoteEvent(this.buf, this.noteEventStart + 2);\n        }\n\n        get isMelodicTrack(): boolean {\n            return this.flags === 0;\n        }\n\n        get id(): number {\n            return this.buf[this.offset];\n        }\n\n        set id(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get flags(): number {\n            return this.buf[this.offset + 1];\n        }\n\n        set flags(value: number) {\n            this.buf[this.offset + 1] = value;\n        }\n\n        get instrumentByteLength(): number {\n            return this.getValue(this.offset + 2);\n        }\n\n        set instrumentByteLength(value: number) {\n            this.setValue(this.offset + 2, value);\n        }\n\n        get noteEventStart(): number {\n            return this.offset + this.instrumentByteLength + 4;\n        }\n\n        get noteEventByteLength(): number {\n            return this.getValue(this.noteEventStart);\n        }\n\n        set noteEventByteLength(value: number) {\n            this.setValue(this.noteEventStart, value);\n        }\n\n        get byteLength() {\n            return this.noteEventByteLength + this.instrumentByteLength + 6;\n        }\n\n        advanceNoteEvent() {\n            this.currentNoteEvent.offset += this.currentNoteEvent.byteLength;\n\n            if (this.currentNoteEvent.offset >= this.offset + this.byteLength) {\n                this.currentNoteEvent.offset = this.noteEventStart + 2;\n            }\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, offset, value);\n        }\n    }\n\n    export class MelodicTrack extends Track {\n        instrument: Instrument;\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.instrument = new Instrument(this.buf, this.offset + 4);\n        }\n    }\n\n    export class DrumTrack extends Track {\n        drums: DrumInstrument[];\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.drums = [];\n\n            let currentOffset = 0;\n            while (currentOffset < this.instrumentByteLength) {\n                this.drums.push(new DrumInstrument(this.buf, this.offset + 4 + currentOffset));\n                currentOffset += this.drums[this.drums.length - 1].byteLength;\n            }\n        }\n    }\n\n    export class Instrument {\n        ampEnvelope: Envelope;\n        pitchEnvelope: Envelope;\n        ampLFO: LFO;\n        pitchLFO: LFO;\n\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(27);\n            this.offset = this.offset || 0;\n            this.ampEnvelope = new Envelope(this.buf, this.offset + 1);\n            this.pitchEnvelope = new Envelope(this.buf, this.offset + 11);\n            this.ampLFO = new LFO(this.buf, this.offset + 21);\n            this.pitchLFO = new LFO(this.buf, this.offset + 24)\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get octave(): number {\n            return this.buf[this.offset + 27]\n        }\n\n        set octave(value: number) {\n            this.buf[this.offset + 27] = value;\n        }\n    }\n\n    export class DrumInstrument {\n        steps: DrumStep[];\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.steps = [];\n\n            for (let i = 0; i < this.numSteps; i++) {\n                this.steps.push(new DrumStep(this.buf, this.offset + 5 + i * 7))\n            }\n        }\n\n        get byteLength(): number {\n            return 5 + this.numSteps * 7;\n        }\n\n        get numSteps(): number {\n            return this.buf[this.offset];\n        }\n\n        set numSteps(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get startFrequency(): number {\n            return this.getValue(1);\n        }\n\n        set startFrequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get startVolume(): number {\n            return this.getValue(3);\n        }\n\n        set startVolume(value: number) {\n            this.setValue(3, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class DrumStep {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(7);\n            this.offset = this.offset || 0;\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get frequency(): number {\n            return this.getValue(1);\n        }\n\n        set frequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get volume(): number {\n            return this.getValue(3);\n        }\n\n        set volume(value: number) {\n            this.setValue(3, value);\n        }\n\n        get duration(): number {\n            return this.getValue(5);\n        }\n\n        set duration(value: number) {\n            this.setValue(5, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    /**\n     * Renders a single note played on an instrument into a buffer of sound instructions.\n     *\n     * @param instrument The instrument being played\n     * @param noteFrequency The frequency of the note being played. In other words, \"the key being pressed on the piano\"\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     * @param volume The peak volume of the note to play (0-1024). Also called the \"velocity\"\n     */\n    export function renderInstrument(instrument: Instrument, noteFrequency: number, gateLength: number, volume: number) {\n        // We cut off the sound at the end of the amplitude envelope's release time. This is to prevent\n        // the amp envelope from making the sound keep playing forever\n        const totalDuration = gateLength + instrument.ampEnvelope.release;\n\n        // Our goal is to calculate the frequency and amplitude at all of the inflection points in this note's lifetime\n\n        // For the ADSR envelopes, the inflection points are:\n        //     1. The end of the envelope atack (which is when the decay begins)\n        //     2. The end of the envelope decay (which is when the sustain begins)\n        //     3. The end of the gateLength (which is when the release begins)\n        //     4. The end of the envelope release\n        // If the gateLength ends before any of these stages (e.g. it's shorter than the envelope's attack), then\n        // we ignore the other stages and go straight to the release stage.\n\n        // For the triangle LFOs, the inflections points occur every time the slope goes from positive to negative. In\n        // other words, it's half the period of the triangle wave.\n\n        const ampLFOInterval = instrument.ampLFO.amplitude ? Math.max(500 / instrument.ampLFO.frequency, 50) : 50;\n        const pitchLFOInterval = instrument.pitchLFO.amplitude ? Math.max(500 / instrument.pitchLFO.frequency, 50) : 50;\n\n        // We're going to add the timepoints to this array in order so that it doesn't need to be sorted\n        let timePoints = [0];\n\n        // For each LFO and envelope, keep track of the next inflection point. If any of the LFOs or envelopes have\n        // an amplitude of 0, we can ignore them entirely.\n        let nextAETime = instrument.ampEnvelope.attack;\n        let nextPETime = instrument.pitchEnvelope.amplitude ? instrument.pitchEnvelope.attack : totalDuration;\n        let nextPLTime = instrument.pitchLFO.amplitude ? pitchLFOInterval : totalDuration;\n        let nextALTime = instrument.ampLFO.amplitude ? ampLFOInterval : totalDuration;\n\n        let time = 0;\n        while (time < totalDuration) {\n            // Amp envelope\n            if (nextAETime <= nextPETime && nextAETime <= nextPLTime && nextAETime <= nextALTime) {\n                time = nextAETime;\n                timePoints.push(nextAETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            // Pitch envelope\n            else if (nextPETime <= nextPLTime && nextPETime <= nextALTime && nextPETime < totalDuration) {\n                time = nextPETime;\n                timePoints.push(nextPETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                // If we reach the end of the release before the amp envelope is finished, bail out\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            // Pitch LFO\n            else if (nextPLTime <= nextALTime && nextPLTime < totalDuration) {\n                time = nextPLTime;\n                timePoints.push(nextPLTime);\n                nextPLTime += pitchLFOInterval;\n            }\n            // Amp LFO\n            else if (nextALTime < totalDuration) {\n                time = nextALTime;\n                timePoints.push(nextALTime);\n                nextALTime += ampLFOInterval;\n            }\n\n\n            if (time >= totalDuration) {\n                break;\n            }\n\n            // Now that we've advanced the time, we need to check all of the envelopes/LFOs again\n            // to see if any of them also need to be pushed forward (e.g. they had the same inflection point\n            // as the one we just added to the array)\n            if (nextAETime <= time) {\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            if (nextPETime <= time) {\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            while (nextALTime <= time) {\n                nextALTime += ampLFOInterval;\n            }\n            while (nextPLTime <= time) {\n                nextPLTime += pitchLFOInterval;\n            }\n        }\n\n        // Once we've calculated the inflection points, calculate the frequency and amplitude at\n        // each step and interpolate between them with sound instructions\n        let prevAmp = instrumentVolumeAtTime(instrument, gateLength, 0, volume) | 0;\n        let prevPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, 0) | 0;\n        let prevTime = 0;\n\n        let nextAmp: number;\n        let nextPitch: number;\n        const out = control.createBuffer(BUFFER_SIZE * timePoints.length);\n        for (let i = 1; i < timePoints.length; i++) {\n            if (timePoints[i] - prevTime < 5) {\n                prevTime = timePoints[i];\n                continue;\n            }\n\n            nextAmp = instrumentVolumeAtTime(instrument, gateLength, timePoints[i], volume) | 0;\n            nextPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, timePoints[i]) | 0\n            addNote(\n                out,\n                (i - 1) * 12,\n                (timePoints[i] - prevTime) | 0,\n                prevAmp,\n                nextAmp,\n                instrument.waveform,\n                prevPitch,\n                255,\n                nextPitch\n            )\n\n            prevAmp = nextAmp;\n            prevPitch = nextPitch;\n            prevTime = timePoints[i];\n        }\n\n        // Finally, add one extra step to move the amplitude to 0 without\n        // clipping just in case the amp LFO caused it to be nonzero\n        addNote(\n            out,\n            (timePoints.length - 1) * 12,\n            10,\n            prevAmp,\n            0,\n            instrument.waveform,\n            prevPitch,\n            255,\n            prevPitch\n        )\n        return out;\n    }\n\n    export function renderDrumInstrument(sound: DrumInstrument, volume: number) {\n        // Drum instruments are rendered just like melodic instruments, but the inflection\n        // points are already calculated for us\n        let prevAmp = sound.startVolume;\n        let prevFreq = sound.startFrequency;\n\n        const scaleVolume = (value: number) => (value / 1024) * volume;\n\n        let out = control.createBuffer((sound.steps.length + 1) * BUFFER_SIZE);\n\n        for (let i = 0; i < sound.steps.length; i++) {\n            addNote(\n                out,\n                i * BUFFER_SIZE,\n                sound.steps[i].duration,\n                scaleVolume(prevAmp),\n                scaleVolume(sound.steps[i].volume),\n                sound.steps[i].waveform,\n                prevFreq,\n                255,\n                sound.steps[i].frequency\n            );\n            prevAmp = sound.steps[i].volume;\n            prevFreq = sound.steps[i].frequency\n        }\n\n        addNote(\n            out,\n            sound.steps.length * BUFFER_SIZE,\n            10,\n            scaleVolume(prevAmp),\n            0,\n            sound.steps[sound.steps.length - 1].waveform,\n            prevFreq,\n            255,\n            prevFreq\n        );\n\n        return out;\n    }\n\n    function instrumentPitchAtTime(instrument: Instrument, noteFrequency: number, gateLength: number, time: number) {\n        let mod = 0;\n        if (instrument.pitchEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.pitchEnvelope, time, gateLength)\n        }\n        if (instrument.pitchLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.pitchLFO, time)\n        }\n        return Math.max(noteFrequency + mod, 0);\n    }\n\n    function instrumentVolumeAtTime(instrument: Instrument, gateLength: number, time: number, maxVolume: number) {\n        let mod = 0;\n        if (instrument.ampEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.ampEnvelope, time, gateLength)\n        }\n        if (instrument.ampLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.ampLFO, time)\n        }\n        return ((Math.max(Math.min(mod, instrument.ampEnvelope.amplitude), 0) / 1024) * maxVolume) | 0;\n    }\n\n    /**\n     * Calculates the value of an ADSR envelope at the given time for a given gate length.\n     *\n     * @param envelope The ADSR envelope\n     * @param time The point and time to calculate the value at\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     */\n    function envelopeValueAtTime(envelope: Envelope, time: number, gateLength: number) {\n        // ADSR envelopes consist of 4 stages. They are (in order):\n        //     1. The attack stage, where the value starts at 0 and rises to the maximum value\n        //     2. The decay stage, where the value falls from the maximum value to the sustain value\n        //     3. The sustain stage, where the value holds steady at the sustain value until the gate length ends\n        //     4. The release stage, where the value falls to 0 after the gate length ends\n        // If the gate length ends before the sustain stage, we immediately skip to the release stage. All stages\n        // use a linear function for the value\n        const adjustedSustain = (envelope.sustain / 1024) * envelope.amplitude;\n\n        // First check to see if we are already in the release stage\n        if (time > gateLength) {\n            if (time - gateLength > envelope.release) return 0;\n\n            // Did the gate length end before the attack stage finished?\n            else if (time < envelope.attack) {\n                const height = (envelope.amplitude / envelope.attack) * gateLength;\n                return height - ((height / envelope.release) * (time - gateLength))\n            }\n            // Did the gate length end before the decay stage finished?\n            else if (time < envelope.attack + envelope.decay) {\n                const height2 = envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (gateLength - envelope.attack);\n                return height2 - ((height2 / envelope.release) * (time - gateLength))\n            }\n            else {\n                return adjustedSustain - (adjustedSustain / envelope.release) * (time - gateLength)\n            }\n        }\n        else if (time < envelope.attack) {\n            return (envelope.amplitude / envelope.attack) * time\n        }\n        else if (time < envelope.attack + envelope.decay) {\n            return envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (time - envelope.attack)\n        }\n        else {\n            return adjustedSustain;\n        }\n    }\n\n    /**\n     * Calculates the value of the LFO at the given time.\n     *\n     * TODO: might be nice to give options to shift the phase of the LFO or let it run free\n     *\n     * @param lfo The LFO to calculate the value of\n     * @param time The time to calculate the value at\n     */\n    function lfoValueAtTime(lfo: LFO, time: number) {\n        // Use cosine to smooth out the value somewhat\n        return Math.cos(((time / 1000) * lfo.frequency) * 2 * Math.PI) * lfo.amplitude\n    }\n\n    export function _stopAllSongs() {\n        if (currentSequencer) {\n            currentSequencer.stop();\n            currentSequencer = undefined;\n        }\n        _stopAllSimSequencers();\n    }\n}","legacy.ts":"//% deprecated=true hidden=true\nenum Sounds {\n    //% block=\"power up\"\n    PowerUp,\n    //% block=\"power down\"\n    PowerDown,\n    //% block=\"jump up\"\n    JumpUp,\n    //% block=\"jump down\"\n    JumpDown,\n    //% block=\"ba ding\"\n    BaDing,\n    //% block=\"wawawawaa\"\n    Wawawawaa,\n    //% block=\"magic wand\"\n    MagicWand,\n    //% block=\"siren\"\n    Siren\n}\n\nnamespace music {\n    /**\n     * Get the melody string for a built-in melody.\n     * @param name the note name, eg: Note.C\n     */\n    //% help=music/sounds\n    //% blockId=music_sounds block=\"%name\"\n    //% blockHidden=true\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=285\n    //% name.fieldOptions.columns=3\n    export function sounds(name: Sounds): string {\n        switch (name) {\n            case Sounds.BaDing:\n                return 'b5:1 e6:3';\n            case Sounds.Wawawawaa:\n                return 'e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8';\n            case Sounds.JumpUp:\n                return 'c5:1 d e f g';\n            case Sounds.JumpDown:\n                return 'g5:1 f e d c';\n            case Sounds.PowerUp:\n                return 'g4:1 c5 e g:2 e:1 g:3';\n            case Sounds.PowerDown:\n                return 'g5:1 d# c g4:2 b:1 c5:3';\n            case Sounds.MagicWand:\n                return 'F#6:1-300 G# A# B C7# D# F F# G# A# B:6'; //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n            case Sounds.Siren:\n                return 'a4 d5 a4 d5 a4 d5';\n            default:\n                return '';\n        }\n    }\n\n    let currMelody: Melody\n\n    /**\n     * Start playing a sound and don't wait for it to finish.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound\n    //% blockId=music_play_sound block=\"play sound %sound=music_sounds\"\n    //% parts=\"headphone\"\n    //% weight=95 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSound(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.play();\n        pause(1);\n    }\n\n\n    /**\n     * Play a sound and wait until the sound is done.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound-until-done\n    //% blockId=music_play_sound_until_done block=\"play sound %sound=music_sounds|until done\"\n    //% parts=\"headphone\"\n    //% weight=94 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSoundUntilDone(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.playUntilDone();\n    }\n}","melody.cpp":"#include \"pxt.h\"\n#include \"SoundOutput.h\"\n#include \"melody.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\nnamespace music {\n\nSINGLETON(WSynthesizer);\n\n// Tone generator arguments:\n//\n// sound: a pointer to the currently-playing sound, usable for looking up the\n// waveform or generator-specific state.\n//\n// position: offset within the currently-playing wave, range 0..1023.\n//\n// cycle: a 6-bit cyclical sequence number of the wave, incremented each time\n// the position loops from 1023 back to 0.\ntypedef int (*gentone_t)(PlayingSound *sound, uint32_t position, uint8_t cycle);\n\nstatic int noiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    // see https://en.wikipedia.org/wiki/Xorshift\n    static uint32_t x = 0xf01ba80;\n    x ^= x << 13;\n    x ^= x >> 17;\n    x ^= x << 5;\n    return (x & 0xffff) - 0x7fff;\n}\n\nstatic int sineTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    int32_t p = position;\n    if (p >= 512) {\n        p -= 512;\n    }\n    if (p > 256) {\n        p = 512 - p;\n    }\n\n    // Approximate sin(x * pi / 2) with the odd polynomial y = cx^5 + bx^3 + ax\n    // using the constraint y(1) = 1 => a = 1 - b - c\n    //   => y = c x^5 + b x^3 + (1 - b - c) * x\n    //\n    // Do a least-squares fit of this to sin(x * pi / 2) in the range 0..1\n    // inclusive, using 21 evenly spaced points. Resulting approximation:\n    //\n    // sin(x*pi/2) ~= 0.0721435357258*x**5 - 0.642443736562*x**3 + 1.57030020084*x\n\n    // Scale the constants by 32767 to match the desired output range.\n    constexpr int32_t c = 0.0721435357258 * 32767;\n    constexpr int32_t b = -0.642443736562 * 32767;\n    constexpr int32_t a = 1.57030020084 * 32767;\n\n    // Calculate using y = ((c * x^2 + b) * x^2 + a) * x\n    //\n    // The position p is x * 256, so after each multiply with p we need to\n    // shift right by 8 bits to keep the decimal point in the same place.  (The\n    // approximation has a negative error near x=1 which helps avoid overflow.)\n    int32_t p2 = p * p;\n    int32_t u = (c * p2 >> 16) + b;\n    int32_t v = (u * p2 >> 16) + a;\n    int32_t w = v * p >> 8;\n\n    // The result is within 7/32767 or 0.02%, signal-to-error ratio about 38 dB.\n    return position >= 512 ? -w : w;\n}\n\nstatic int sawtoothTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return (position << 6) - 0x7fff;\n}\n\nstatic int triangleTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return position < 512 ? (position << 7) - 0x7fff : ((1023 - position) << 7) - 0x7fff;\n}\n\nstatic int squareWaveTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)cycle;\n    uint8_t wave = sound->currInstr->soundWave;\n    return (int)position < (102 * (wave - SW_SQUARE_10 + 1)) ? -0x7fff : 0x7fff;\n}\n\nstatic int tunedNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a random bit sequence. Since the generator\n    // is called multiple times per wave, use PlayingSound state data to ensure we\n    // only generate a random bit once per wave, and then reuse it for future\n    // calls for that wave.\n    //\n    // Use the low 6 bits of generatorState to store the last-used cycle, and\n    // random_bit to store the last on/off state. (random_bit is arbitrary as\n    // long as it isn't one of the low 6 bits.)\n    constexpr uint32_t random_bit = 0x8000;\n    static uint32_t x = 0xf01ba80; // seed for the static RNG state\n    uint8_t prev_cycle = sound->generatorState & 0x3f;\n    uint32_t is_on;\n    if (cycle == prev_cycle) {\n        is_on = sound->generatorState & random_bit;\n    } else {\n        // see https://en.wikipedia.org/wiki/Xorshift\n        x ^= x << 13;\n        x ^= x >> 17;\n        x ^= x << 5;\n        is_on = (x & random_bit);\n        sound->generatorState = (cycle & 0x3f) | is_on;\n    }\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\n// Bit patterns for use by the cyclic noise tone.\n//\n// The bit pattern is arbitrary, but should have equal numbers of 0 and 1 bits,\n// and should avoid long identical-bit runs for the lower parts. The values below\n// were chosen based on a random permutation of the hex nibbles 0..f and then\n// hand-tweaked by swapping some nibbles. Generated by:\n//\n//   shuf -i 0-15 | perl -ne 's/(\\d+)/printf(\"%x\",$1)/e'\nstatic const uint32_t cycle_bits[] = {0x2df0eb47, 0xc8165a93};\nstatic const uint8_t cycle_mask[] = {0xf, 0x1f, 0x3f};\n\nstatic int cycleNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    // The bit sequence repeats every 16/32/64 waves.\n    //\n    // The \"cycle\" argument corresponds to the sequential number of the generated\n    // wave. This is currently a 6-bit value. Since the pseudorandom bit sequences\n    // evenly fit into this, there's no need to track generator state.\n    uint8_t wave = sound->currInstr->soundWave;\n    int cycle_index = wave - SW_SQUARE_CYCLE_16;\n    // CLAMP(0, cycle_index, sizeof cycle_bits / sizeof cycle_bits[0])\n    cycle &= cycle_mask[cycle_index];\n    bool is_on = (cycle_bits[cycle >> 5] & (1U << (cycle & 0x1f)));\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\nstatic int silenceTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    return 0;\n}\n\nstatic gentone_t getWaveFn(uint8_t wave) {\n    switch (wave) {\n    case SW_TRIANGLE:\n        return triangleTone;\n    case SW_SAWTOOTH:\n        return sawtoothTone;\n    case SW_TUNEDNOISE:\n        return tunedNoiseTone;\n    case SW_NOISE:\n        return noiseTone;\n    case SW_SINE:\n        return sineTone;\n    default:\n        if (SW_SQUARE_10 <= wave && wave <= SW_SQUARE_50)\n            return squareWaveTone;\n        if (SW_SQUARE_CYCLE_16 <= wave && wave <= SW_SQUARE_CYCLE_64)\n            return cycleNoiseTone;\n        else\n            return silenceTone;\n    }\n}\n\n#define CLAMP(lo, v, hi) ((v) = ((v) < (lo) ? (lo) : (v) > (hi) ? (hi) : (v)))\n\nint WSynthesizer::updateQueues() {\n    const int maxTime = 0xffffff;\n    while (1) {\n        WaitingSound *p;\n        int minLeft = maxTime;\n        for (p = waiting; p; p = p->next) {\n            int timeLeft =\n                p->state == SoundState::Waiting ? p->startSampleNo - currSample : maxTime;\n            if (timeLeft <= 0) {\n                break;\n            }\n            if (timeLeft < minLeft)\n                minLeft = timeLeft;\n        }\n        if (p) {\n            PlayingSound *snd;\n            int minIdx = -1;\n            for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n                snd = &playingSounds[i];\n                if (snd->sound == NULL)\n                    break;\n                if (minIdx == -1 ||\n                    playingSounds[minIdx].startSampleNo < playingSounds[i].startSampleNo)\n                    minIdx = i;\n                snd = NULL;\n            }\n            // if we didn't find a free slot, expel the oldest sound\n            if (!snd)\n                snd = &playingSounds[minIdx];\n            if (snd->sound)\n                snd->sound->state = SoundState::Done;\n            snd->sound = p;\n            p->state = SoundState::Playing;\n            snd->startSampleNo = currSample;\n            snd->currInstr = (SoundInstruction *)p->instructions->data;\n            snd->instrEnd = snd->currInstr + p->instructions->length / sizeof(SoundInstruction);\n            snd->prevVolume = -1;\n        } else {\n            // no more sounds to move\n            return minLeft;\n        }\n    }\n}\n\nint WSynthesizer::fillSamples(int16_t *dst, int numsamples) {\n    if (numsamples <= 0)\n        return 1;\n\n    int timeLeft = updateQueues();\n    int res = waiting != NULL;\n\n    // if there's a pending sound to be started somewhere during numsamples,\n    // split the call into two\n    if (timeLeft < numsamples) {\n        fillSamples(dst, timeLeft);\n        LOG(\"M split %d\", timeLeft);\n        fillSamples(dst + timeLeft, numsamples - timeLeft);\n        return 1;\n    }\n\n    memset(dst, 0, numsamples * 2);\n\n    uint32_t samplesPerMS = (sampleRate << 8) / 1000;\n    float toneStepMult = (1024.0 * (1 << 16)) / sampleRate;\n    const int MAXVAL = (1 << (OUTPUT_BITS - 1)) - 1;\n\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        PlayingSound *snd = &playingSounds[i];\n        if (snd->sound == NULL)\n            continue;\n\n        res = 1;\n\n        SoundInstruction *instr = NULL;\n        gentone_t fn = NULL;\n        snd->currInstr--;\n        uint32_t toneStep = 0;\n        int32_t toneDelta = 0;\n        int32_t volumeStep = 0;\n        uint32_t tonePosition = snd->tonePosition;\n        uint32_t samplesLeft = 0;\n        uint8_t wave = 0;\n        int32_t volume = 0;\n\n        for (int j = 0; j < numsamples; ++j) {\n            if (samplesLeft == 0) {\n                snd->currInstr++;\n                if (snd->currInstr >= snd->instrEnd) {\n                    break;\n                }\n                SoundInstruction copy = *snd->currInstr;\n                instr = &copy;\n                CLAMP(20, instr->frequency, 20000);\n                CLAMP(20, instr->endFrequency, 20000);\n                CLAMP(0, instr->startVolume, 1023);\n                CLAMP(0, instr->endVolume, 1023);\n                CLAMP(1, instr->duration, 60000);\n\n                wave = instr->soundWave;\n                fn = getWaveFn(wave);\n\n                samplesLeft = (uint32_t)(instr->duration * samplesPerMS >> 8);\n                // make sure the division is signed\n                volumeStep =\n                    (int)((instr->endVolume - instr->startVolume) << 16) / (int)samplesLeft;\n\n                if (j == 0 && snd->prevVolume != -1) {\n                    // restore previous state\n                    samplesLeft = snd->samplesLeftInCurr;\n                    volume = snd->prevVolume;\n                    toneStep = snd->prevToneStep;\n                    toneDelta = snd->prevToneDelta;\n                } else {\n                    LOG(\"#sampl %d %p\", samplesLeft, snd->currInstr);\n                    volume = instr->startVolume << 16;\n                    LOG(\"%d-%dHz %d-%d vol\", instr->frequency, instr->endFrequency,\n                        instr->startVolume, instr->endVolume);\n                    toneStep = (uint32_t)(toneStepMult * instr->frequency);\n                    if (instr->frequency != instr->endFrequency) {\n                        uint32_t endToneStep = (uint32_t)(toneStepMult * instr->endFrequency);\n                        toneDelta = (int32_t)(endToneStep - toneStep) / (int32_t)samplesLeft;\n                    } else {\n                        toneDelta = 0;\n                    }\n                }\n            }\n\n            int v = fn(snd, (tonePosition >> 16) & 1023, tonePosition >> 26);\n            v = (v * (volume >> 16)) >> (10 + (16 - OUTPUT_BITS));\n\n            // if (v > MAXVAL)\n            //    target_panic(123);\n\n            dst[j] += v;\n\n            tonePosition += toneStep;\n            toneStep += toneDelta;\n            volume += volumeStep;\n            samplesLeft--;\n        }\n\n        if (snd->currInstr >= snd->instrEnd) {\n            snd->sound->state = SoundState::Done;\n            snd->sound = NULL;\n        } else {\n            snd->tonePosition = tonePosition;\n            if (samplesLeft == 0)\n                samplesLeft++; // avoid infinite loop in next iteration\n            snd->samplesLeftInCurr = samplesLeft;\n            snd->prevVolume = volume;\n            snd->prevToneDelta = toneDelta;\n            snd->prevToneStep = toneStep;\n        }\n    }\n\n    currSample += numsamples;\n\n    for (int j = 0; j < numsamples; ++j) {\n        if (dst[j] > MAXVAL)\n            dst[j] = MAXVAL;\n        else if (dst[j] < -MAXVAL)\n            dst[j] = -MAXVAL;\n    }\n\n    return res;\n}\n\n//%\nvoid enableAmp(int enabled) {\n    // this is also compiled on linux\n#ifdef LOOKUP_PIN\n    auto pin = LOOKUP_PIN(SPEAKER_AMP);\n    if (pin) {\n        if (PIN(SPEAKER_AMP) & CFG_PIN_CONFIG_ACTIVE_LO)\n            enabled = !enabled;\n        pin->setDigitalValue(enabled);\n    }\n#endif\n}\n\n//%\nvoid forceOutput(int outp) {\n    auto snd = getWSynthesizer();\n    snd->out.setOutput(outp);\n}\n\n//%\nvoid queuePlayInstructions(int when, Buffer buf) {\n    auto snd = getWSynthesizer();\n\n    registerGCObj(buf);\n\n    auto p = new WaitingSound;\n    p->state = SoundState::Waiting;\n    p->instructions = buf;\n    p->startSampleNo = snd->currSample + when * snd->sampleRate / 1000;\n\n    LOG(\"Queue %dms now=%d off=%d %p sampl:%dHz\", when, snd->currSample,\n        p->startSampleNo - snd->currSample, buf->data, snd->sampleRate);\n\n    target_disable_irq();\n    // add new sound to queue\n    p->next = snd->waiting;\n    snd->waiting = p;\n    // remove sounds that have already been fully played\n    while (p) {\n        while (p->next && p->next->state == SoundState::Done) {\n            auto todel = p->next;\n            p->next = todel->next;\n            unregisterGCObj(todel->instructions);\n            delete todel;\n        }\n        p = p->next;\n    }\n    target_enable_irq();\n\n    snd->poke();\n}\n\n//%\nvoid stopPlaying() {\n    LOG(\"stop playing!\");\n\n    auto snd = getWSynthesizer();\n\n    target_disable_irq();\n    auto p = snd->waiting;\n    snd->waiting = NULL;\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        snd->playingSounds[i].sound = NULL;\n    }\n    while (p) {\n        auto n = p->next;\n        unregisterGCObj(p->instructions);\n        delete p;\n        p = n;\n    }\n    target_enable_irq();\n}\n\nWSynthesizer::WSynthesizer() : upstream(NULL), out(*this) {\n    currSample = 0;\n    active = false;\n    sampleRate = out.dac.getSampleRate();\n    memset(&playingSounds, 0, sizeof(playingSounds));\n    waiting = NULL;\n    PXT_REGISTER_RESET(stopPlaying);\n}\n\n//% promise\nint _createSequencer() {\n    return 0;\n}\n\n//%\nString _sequencerState(int id) {\n    return NULL;\n}\n\n//%\nint _sequencerCurrentTick(int id) {\n    return 0;\n}\n\n//%\nvoid _sequencerPlaySong(int id, Buffer buf, bool loop) {\n}\n\n//%\nvoid _sequencerStop(int id) {\n}\n\n//%\nvoid _sequencerSetVolume(int id, int volume) {\n}\n\n//%\nvoid _sequencerSetVolumeForAll(int volume) {\n}\n\n//%\nvoid _sequencerSetTrackVolume(int id, int trackIndex, int volume) {\n}\n\n//%\nvoid _sequencerSetDrumTrackVolume(int id, int trackIndex, int drumIndex, int volume) {\n}\n\n//%\nvoid _sequencerDispose(int id) {\n}\n\n} // namespace music\n\nnamespace pxt {\nint redirectSamples(int16_t *dst, int numsamples, int samplerate) {\n    auto snd = music::getWSynthesizer();\n    snd->upstream = NULL; // disconnect from regular playback mechanism\n    snd->sampleRate = samplerate;\n    return snd->fillSamples(dst, numsamples);\n}\n\n} // namespace pxt\n\nnamespace jacdac {\n__attribute__((weak)) void setJackRouterOutput(int output) {}\n} // namespace jacdac\n","melody.h":"#pragma once\n\n#ifndef OUTPUT_BITS\n#define OUTPUT_BITS 10\n#endif\n\n#define SW_TRIANGLE 1\n#define SW_SAWTOOTH 2\n#define SW_SINE 3\n#define SW_TUNEDNOISE 4\n#define SW_NOISE 5\n#define SW_SQUARE_10 11\n#define SW_SQUARE_50 15\n#define SW_SQUARE_CYCLE_16 16\n#define SW_SQUARE_CYCLE_32 17\n#define SW_SQUARE_CYCLE_64 18\n\nstruct SoundInstruction {\n    uint8_t soundWave;\n    uint8_t flags;\n    uint16_t frequency;    // Hz\n    uint16_t duration;     // ms\n    int16_t startVolume;   // 0-1023\n    int16_t endVolume;     // 0-1023\n    uint16_t endFrequency; // Hz\n};\n\n#ifdef DATASTREAM_MAXIMUM_BUFFERS\n#define CODAL 1\n#endif\n\nnamespace music {\n\n#define MAX_SOUNDS 8\n\nSTATIC_ASSERT((1 << (16 - OUTPUT_BITS)) > MAX_SOUNDS);\n\nenum class SoundState : uint8_t {\n    Waiting, //\n    Playing, //\n    Done     //\n};\n\nstruct WaitingSound {\n    uint32_t startSampleNo;\n    SoundState state;\n    WaitingSound *next;\n    Buffer instructions;\n};\n\nstruct PlayingSound {\n    uint32_t startSampleNo;\n    uint32_t samplesLeftInCurr;\n    uint32_t tonePosition;\n    int32_t prevVolume;\n    uint32_t prevToneStep;\n    int32_t prevToneDelta;\n    uint32_t generatorState;\n    WaitingSound *sound;\n    SoundInstruction *currInstr, *instrEnd;\n};\n\nclass WSynthesizer\n#ifdef CODAL\n    : public DataSource\n#endif\n{\n  public:\n#ifdef CODAL\n    DataSink *upstream;\n#else\n    void *upstream;\n#endif\n    uint32_t currSample; // after 25h of playing we might get a glitch\n    int32_t sampleRate;  // eg 44100\n    PlayingSound playingSounds[MAX_SOUNDS];\n    WaitingSound *waiting;\n    bool active;\n\n    SoundOutput out;\n\n    int fillSamples(int16_t *dst, int numsamples);\n    int updateQueues();\n\n    WSynthesizer();\n    virtual ~WSynthesizer() {}\n\n    void pokeUpstream() {\n#ifdef CODAL\n        if (upstream) {\n            upstream->pullRequest();\n        }\n#endif\n    }\n\n    void poke() {\n        if (!active) {\n            active = true;\n            pokeUpstream();\n        }\n    }\n\n#ifdef CODAL\n    virtual ManagedBuffer pull() {\n        if (!upstream)\n            return ManagedBuffer();\n        ManagedBuffer data(512);\n        auto dp = (int16_t *)data.getBytes();\n        auto sz = 512 / 2;\n        int r = fillSamples(dp, sz);\n#if defined(NRF52_SERIES)\n        int mul = out.dac.getSampleRange();\n#endif\n        while (sz--) {\n#if defined(NRF52_SERIES)\n            *dp = ((-*dp + (1 << (OUTPUT_BITS - 1))) * mul) >> OUTPUT_BITS;\n#else\n            *dp += 1 << (OUTPUT_BITS - 1);\n#endif\n            dp++;\n        }\n        if (!r) {\n            active = false;\n            // return empty - nothing left to play\n            return ManagedBuffer();\n        }\n        pokeUpstream();\n        return data;\n    }\n    virtual void connect(DataSink &sink) { upstream = &sink; }\n#endif\n};\n\n} // namespace music\n","melody.ts":"enum MusicOutput {\n    AutoDetect = 0,\n    Buzzer = 1,\n    HeadPhones = 2,\n}\n\nnamespace music {\n    //% whenUsed\n    const freqs = hex`\n        1f00210023002500270029002c002e003100340037003a003e004100450049004e00520057005c00620068006e00\n        75007b0083008b0093009c00a500af00b900c400d000dc00e900f70006011501260137014a015d01720188019f01\n        b801d201ee010b022a024b026e029302ba02e40210033f037003a403dc03170455049704dd0427057505c8052006\n        7d06e0064907b8072d08a9082d09b9094d0aea0a900b400cfa0cc00d910e6f0f5a1053115b1272139a14d4152017\n        8018f519801b231dde1e`\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n\n    //% shim=music::stopPlaying\n    function stopPlaying() { }\n\n    //% shim=music::forceOutput\n    export function forceOutput(buf: MusicOutput) { }\n\n    let globalVolume: number = null\n\n    const BUFFER_SIZE: number = 12;\n\n    //% shim=music::enableAmp\n    function enableAmp(en: number) {\n        return // for sim\n    }\n\n    function initVolume() {\n        if (globalVolume === null) {\n            globalVolume = 0\n            setVolume(control.getConfigValue(DAL.CFG_SPEAKER_VOLUME, 128))\n        }\n    }\n\n    /**\n     * Set the default output volume of the sound synthesizer.\n     * @param volume the volume 0...255\n     */\n    //% blockId=synth_set_volume block=\"set volume %volume\"\n    //% parts=\"speaker\"\n    //% volume.min=0 volume.max=255\n    //% volume.defl=20\n    //% help=music/set-volume\n    //% weight=70\n    //% group=\"Volume\"\n    export function setVolume(volume: number): void {\n        globalVolume = Math.clamp(0, 255, volume | 0)\n        enableAmp(globalVolume > 0 ? 1 : 0)\n    }\n\n    /**\n     * Gets the current volume\n     */\n    //% parts=\"speaker\"\n    //% weight=70\n    export function volume(): number {\n        initVolume()\n        return globalVolume;\n    }\n\n    function playNoteCore(when: number, frequency: number, ms: number) {\n        let buf = control.createBuffer(BUFFER_SIZE)\n        addNote(buf, 0, ms, 255, 255, 3, frequency, volume(), frequency)\n        queuePlayInstructions(when, buf)\n    }\n\n    /**\n     * Play a tone through the speaker for some amount of time.\n     * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n     * @param ms tone duration in milliseconds (ms), eg: BeatFraction.Half\n     */\n    //% help=music/play-tone\n    //% blockId=mixer_play_note block=\"play tone|at %note=device_note|for %duration=device_beat\"\n    //% parts=\"headphone\" async\n    //% blockNamespace=music\n    //% weight=76 blockGap=8\n    //% group=\"Tone\"\n    //% deprecated=1\n    export function playTone(frequency: number, ms: number): void {\n        if (ms == 0)\n            ms = 86400000 // 1 day\n\n        if (ms <= 2000) {\n            playNoteCore(0, frequency, ms)\n            pause(ms)\n        } else {\n            const id = ++playToneID\n            control.runInParallel(() => {\n                let pos = control.millis()\n                while (id == playToneID && ms > 0) {\n                    let now = control.millis()\n                    let d = pos - now\n                    let t = Math.min(ms, 500)\n                    ms -= t\n                    pos += t\n                    playNoteCore(d - 1, frequency, t)\n                    if (ms == 0)\n                        pause(d + t)\n                    else\n                        pause(d + t - 100)\n                }\n            })\n        }\n    }\n\n    let playToneID = 0\n\n    /**\n     * Play a melody from the melody editor.\n     * @param melody - string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces,\n     * which will be played one at a time, ex: \"E D G F B A C5 B \"\n     * @param tempo - number in beats per minute (bpm), dictating how long each note will play for\n     */\n    //% block=\"play melody $melody at tempo $tempo|(bpm)\" blockId=playMelody\n    //% blockNamespace=music\n    //% weight=85 blockGap=8 help=music/play-melody\n    //% group=\"Melody\"\n    //% melody.shadow=\"melody_editor\"\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% deprecated=1\n    export function playMelody(melody: string, tempo: number) {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        const song = new Melody(formattedMelody);\n        song.playUntilDone();\n    }\n\n\n    /**\n     * Create a melody with the melody editor.\n     * @param melody\n     */\n    //% block=\"$melody\" blockId=melody_editor\n    //% blockNamespace=music\n    //% blockHidden = true\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Melody\" duplicateShadowOnDrag\n    //% melody.fieldEditor=\"melody\"\n    //% melody.fieldOptions.decompileLiterals=true\n    //% melody.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% melody.fieldOptions.onParentBlock=\"true\"\n    //% shim=TD_ID\n    export function melodyEditor(melody: string): string {\n        return melody;\n    }\n\n    /**\n     * Stop all sounds from playing.\n     */\n    //% help=music/stop-all-sounds\n    //% blockId=music_stop_all_sounds block=\"stop all sounds\"\n    //% weight=45\n    //% group=\"Sounds\"\n    export function stopAllSounds() {\n        Melody.stopAll();\n        stopPlaying();\n        _stopPlayables();\n        sequencer._stopAllSongs();\n    }\n\n    //% fixedInstances\n    export class Melody {\n        _text: string;\n        private _player: MelodyPlayer;\n\n        private static playingMelodies: Melody[];\n\n        static stopAll() {\n            if (Melody.playingMelodies) {\n                const ms = Melody.playingMelodies.slice(0, Melody.playingMelodies.length);\n                ms.forEach(p => p.stop());\n            }\n        }\n\n        constructor(text: string) {\n            this._text = text\n        }\n\n        get text() {\n            return this._text;\n        }\n\n        /**\n         * Stop playing a sound\n         */\n        //% blockId=mixer_stop block=\"stop sound %sound\"\n        //% help=music/melody/stop\n        //% parts=\"headphone\"\n        //% weight=92 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        stop() {\n            if (this._player) {\n                this._player.stop()\n                this._player = null\n            }\n            this.unregisterMelody();\n        }\n\n        private registerMelody() {\n            // keep track of the active players\n            if (!Melody.playingMelodies) Melody.playingMelodies = [];\n            // stop and pop melodies if too many playing\n            if (Melody.playingMelodies.length > 4) {\n                // stop last player (also pops)\n                Melody.playingMelodies[Melody.playingMelodies.length - 1].stop();\n            }\n            // put back the melody on top of the melody stack\n            Melody.playingMelodies.removeElement(this);\n            Melody.playingMelodies.push(this);\n        }\n        private unregisterMelody() {\n            // remove from list\n            if (Melody.playingMelodies) {\n                Melody.playingMelodies.removeElement(this); // remove self\n            }\n        }\n\n        private playCore(volume: number, loop: boolean) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this.registerMelody();\n            control.runInParallel(() => {\n                while (this._player == p) {\n                    p.play(volume)\n                    if (!loop) {\n                        // Unregister the melody when done playing, but\n                        // only if it hasn't been restarted. (Looping\n                        // melodies never stop on their own, they only\n                        // get unregistered via stop().)\n                        if (this._player == p) {\n                            this.unregisterMelody();\n                        }\n                        break\n                    }\n                }\n            })\n        }\n\n        /**\n         * Start playing a sound in a loop and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/loop\n        //% blockId=mixer_loop_sound block=\"loop sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=93 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        loop(volume = 255) {\n            this.playCore(volume, true)\n        }\n\n        /**\n         * Start playing a sound and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play\n        //% blockId=mixer_play_sound block=\"play sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=95 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        play(volume = 255) {\n            this.playCore(volume, false)\n        }\n\n\n        /**\n         * Play a sound and wait until the sound is done.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play-until-done\n        //% blockId=mixer_play_sound_until_done block=\"play sound %sound|until done\"\n        //% parts=\"headphone\"\n        //% weight=94 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        playUntilDone(volume = 255) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this._player.onPlayFinished = () => {\n                if (p == this._player)\n                    this.unregisterMelody();\n            }\n            this.registerMelody();\n            this._player.play(volume)\n        }\n\n        toString() {\n            return this._text;\n        }\n    }\n\n    export function addNote(sndInstr: Buffer, sndInstrPtr: number, ms: number, beg: number, end: number, soundWave: number, hz: number, volume: number, endHz: number) {\n        if (ms > 0) {\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, soundWave)\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr + 1, 0)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 2, hz)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 4, ms)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 6, (beg * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 8, (end * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 10, endHz);\n            sndInstrPtr += BUFFER_SIZE;\n        }\n        sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, 0) // terminate\n        return sndInstrPtr\n    }\n\n\n    export class MelodyPlayer {\n        melody: Melody;\n\n        onPlayFinished: () => void;\n\n        constructor(m: Melody) {\n            this.melody = m\n        }\n\n        stop() {\n            this.melody = null\n        }\n\n        protected queuePlayInstructions(timeDelta: number, buf: Buffer) {\n            queuePlayInstructions(timeDelta, buf)\n        }\n\n        play(volume: number) {\n            if (!this.melody)\n                return\n            volume = Math.clamp(0, 255, (volume * music.volume()) >> 8)\n\n            let notes = this.melody._text\n            let pos = 0;\n            let duration = 4; //Default duration (Crotchet)\n            let octave = 4; //Middle octave\n            let tempo = 120; // default tempo\n\n            let hz = 0\n            let endHz = -1\n            let ms = 0\n            let timePos = 0\n            let startTime = control.millis()\n            let now = 0\n\n            let envA = 0\n            let envD = 0\n            let envS = 255\n            let envR = 0\n            let soundWave = 1 // triangle\n            let sndInstr = control.createBuffer(5 * BUFFER_SIZE)\n            let sndInstrPtr = 0\n\n            const addForm = (formDuration: number, beg: number, end: number, msOff: number) => {\n                let freqStart = hz;\n                let freqEnd = endHz;\n\n                const envelopeWidth = ms > 0 ? ms : duration * Math.idiv(15000, tempo) + envR;\n                if (endHz != hz && envelopeWidth != 0) {\n                    const slope = (freqEnd - freqStart) / envelopeWidth;\n                    freqStart = hz + slope * msOff;\n                    freqEnd = hz + slope * (msOff + formDuration);\n                }\n                sndInstrPtr = addNote(sndInstr, sndInstrPtr, formDuration, beg, end, soundWave, freqStart, volume, freqEnd);\n            }\n\n            const scanNextWord = () => {\n                if (!this.melody)\n                    return \"\"\n\n                // eat space\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c != ' ' && c != '\\r' && c != '\\n' && c != '\\t')\n                        break;\n                    pos++;\n                }\n\n                // read note\n                let note = \"\";\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c == ' ' || c == '\\r' || c == '\\n' || c == '\\t')\n                        break;\n                    note += c;\n                    pos++;\n                }\n                return note;\n            }\n\n            enum Token {\n                Note,\n                Octave,\n                Beat,\n                Tempo,\n                Hz,\n                EndHz,\n                Ms,\n                WaveForm,\n                EnvelopeA,\n                EnvelopeD,\n                EnvelopeS,\n                EnvelopeR\n            }\n\n            let token: string = \"\";\n            let tokenKind = Token.Note;\n\n            // [ABCDEFG] (\\d+)  (:\\d+)  (-\\d+)\n            // note      octave length  tempo\n            // R (:\\d+) - rest\n            // !\\d+,\\d+ - sound at frequency with given length (Hz,ms); !\\d+ and !\\d+,:\\d+ also possible\n            // @\\d+,\\d+,\\d+,\\d+ - ADSR envelope - ms,ms,volume,ms; volume is 0-255\n            // ~\\d+ - wave form:\n            //   1 - triangle\n            //   2 - sawtooth\n            //   3 - sine\n            //   4 - pseudorandom square wave noise (tunable)\n            //   5 - white noise (ignores frequency)\n            //   11 - square 10%\n            //   12 - square 20%\n            //   ...\n            //   15 - square 50%\n            //   16 - filtered square wave, cycle length 16\n            //   17 - filtered square wave, cycle length 32\n            //   18 - filtered square wave, cycle length 64\n\n            const consumeToken = () => {\n                if (token && tokenKind != Token.Note) {\n                    const d = parseInt(token);\n                    switch (tokenKind) {\n                        case Token.Octave: octave = d; break;\n                        case Token.Beat:\n                            duration = Math.max(1, Math.min(16, d));\n                            ms = -1;\n                            break;\n                        case Token.Tempo: tempo = Math.max(1, d); break;\n                        case Token.Hz: hz = d; tokenKind = Token.Ms; break;\n                        case Token.Ms: ms = d; break;\n                        case Token.WaveForm: soundWave = Math.clamp(1, 18, d); break;\n                        case Token.EnvelopeA: envA = d; tokenKind = Token.EnvelopeD; break;\n                        case Token.EnvelopeD: envD = d; tokenKind = Token.EnvelopeS; break;\n                        case Token.EnvelopeS: envS = Math.clamp(0, 255, d); tokenKind = Token.EnvelopeR; break;\n                        case Token.EnvelopeR: envR = d; break;\n                        case Token.EndHz: endHz = d; break;\n                    }\n                    token = \"\";\n                }\n            }\n\n            while (true) {\n                let currNote = scanNextWord();\n                let prevNote: boolean = false;\n                if (!currNote) {\n                    let timeLeft = timePos - now\n                    if (timeLeft > 0)\n                        pause(timeLeft)\n                    if (this.onPlayFinished)\n                        this.onPlayFinished();\n                    return;\n                }\n\n                hz = -1;\n\n                let note: number = 0;\n                token = \"\";\n                tokenKind = Token.Note;\n\n                for (let i = 0; i < currNote.length; i++) {\n                    let noteChar = currNote.charAt(i);\n                    switch (noteChar) {\n                        case 'c': case 'C': note = 1; prevNote = true; break;\n                        case 'd': case 'D': note = 3; prevNote = true; break;\n                        case 'e': case 'E': note = 5; prevNote = true; break;\n                        case 'f': case 'F': note = 6; prevNote = true; break;\n                        case 'g': case 'G': note = 8; prevNote = true; break;\n                        case 'a': case 'A': note = 10; prevNote = true; break;\n                        case 'B': note = 12; prevNote = true; break;\n                        case 'r': case 'R': hz = 0; prevNote = false; break;\n                        case '#': note++; prevNote = false; break;\n                        case 'b': if (prevNote) note--; else { note = 12; prevNote = true; } break;\n                        case ',':\n                            consumeToken();\n                            prevNote = false;\n                            break;\n                        case '!':\n                            tokenKind = Token.Hz;\n                            prevNote = false;\n                            break;\n                        case '@':\n                            consumeToken();\n                            tokenKind = Token.EnvelopeA;\n                            prevNote = false;\n                            break;\n                        case '~':\n                            consumeToken();\n                            tokenKind = Token.WaveForm;\n                            prevNote = false;\n                            break;\n                        case ':':\n                            consumeToken();\n                            tokenKind = Token.Beat;\n                            prevNote = false;\n                            break;\n                        case '-':\n                            consumeToken();\n                            tokenKind = Token.Tempo;\n                            prevNote = false;\n                            break;\n                        case '^':\n                            consumeToken();\n                            tokenKind = Token.EndHz;\n                            break;\n                        default:\n                            if (tokenKind == Token.Note)\n                                tokenKind = Token.Octave;\n                            token += noteChar;\n                            prevNote = false;\n                            break;\n                    }\n                }\n                consumeToken();\n\n                if (note && hz < 0) {\n                    const keyNumber = note + (12 * (octave - 1));\n                    hz = freqs.getNumber(NumberFormat.UInt16LE, keyNumber * 2) || 0;\n                }\n\n                let currMs = ms\n\n                if (currMs <= 0) {\n                    const beat = Math.idiv(15000, tempo);\n                    currMs = duration * beat\n                }\n\n                if (hz < 0) {\n                    // no frequency specified, so no duration\n                } else if (hz == 0) {\n                    timePos += currMs\n                } else {\n                    if (endHz < 0) {\n                        endHz = hz;\n                    }\n\n                    sndInstrPtr = 0\n                    addForm(envA, 0, 255, 0)\n                    addForm(envD, 255, envS, envA)\n                    addForm(currMs - (envA + envD), envS, envS, envD + envA)\n                    addForm(envR, envS, 0, currMs)\n\n                    this.queuePlayInstructions(timePos - now, sndInstr.slice(0, sndInstrPtr))\n                    endHz = -1;\n                    timePos += currMs // don't add envR - it's supposed overlap next sound\n                }\n\n                let timeLeft = timePos - now\n                if (timeLeft > 200) {\n                    pause(timeLeft - 100)\n                    now = control.millis() - startTime\n                }\n            }\n        }\n    }\n\n    //% blockId=music_song_field_editor\n    //% block=\"song $song\"\n    //% song.fieldEditor=musiceditor\n    //% song.fieldOptions.decompileLiterals=true\n    //% song.fieldOptions.taggedTemplate=\"hex;assets.song\"\n    //% song.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% song.fieldOptions.decompileArgumentAsString=\"true\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% help=music/create-song\n    export function createSong(song: Buffer): Playable {\n        return new sequencer.Song(song);\n    }\n\n    export function playInstructions(when: number, instructions: Buffer) {\n        queuePlayInstructions(when, instructions);\n    }\n\n    export function lookupFrequency(note: number) {\n        return freqs.getNumber(NumberFormat.UInt16LE, note * 2) || 0\n    }\n\n    //% fixedInstance whenUsed block=\"ba ding\"\n    export const baDing = new Melody('b5:1 e6:3')\n\n    //% fixedInstance whenUsed block=\"wawawawaa\"\n    export const wawawawaa = new Melody('~15 e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8')\n\n    //% fixedInstance whenUsed block=\"jump up\"\n    export const jumpUp = new Melody('c5:1 d e f g')\n\n    //% fixedInstance whenUsed block=\"jump down\"\n    export const jumpDown = new Melody('g5:1 f e d c')\n\n    //% fixedInstance whenUsed block=\"power up\"\n    export const powerUp = new Melody('g4:1 c5 e g:2 e:1 g:3')\n\n    //% fixedInstance whenUsed block=\"power down\"\n    export const powerDown = new Melody('g5:1 d# c g4:2 b:1 c5:3')\n\n    //% fixedInstance whenUsed block=\"magic wand\"\n    export const magicWand = new Melody('F#6:1-300 G# A# B C7# D# F F# G# A# B:6')\n    //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n\n    //% fixedInstance whenUsed block=\"siren\"\n    export const siren = new Melody('a4 d5 a4 d5 a4 d5')\n\n    //% fixedInstance whenUsed block=\"pew pew\"\n    export const pewPew = new Melody('!1200,200^50')\n\n    //% fixedInstance whenUsed block=\"knock\"\n    export const knock = new Melody('~4 @0,0,255,150 !300,1 !211,1')\n\n    //% fixedInstance whenUsed block=\"footstep\"\n    export const footstep = new Melody('~4 @0,0,60,50 !200,1')\n\n    //% fixedInstance whenUsed block=\"thump\"\n    export const thump = new Melody('~4 @0,0,255,150 !100,1')\n\n    //% fixedInstance whenUsed block=\"small crash\"\n    export const smallCrash = new Melody('~4 @10,490,0,1 !800,1')\n\n    //% fixedInstance whenUsed block=\"big crash\"\n    export const bigCrash = new Melody('~4 @10,990,0,1 !400,1')\n\n    //% fixedInstance whenUsed block=\"zapped\"\n    export const zapped = new Melody('~16 @10,490,0,0 !1600,500^1')\n\n    //% fixedInstance whenUsed block=\"buzzer\"\n    export const buzzer = new Melody('~16 @10,0,255,250 !2000,300')\n\n    //% fixedInstance whenUsed block=\"sonar\"\n    export const sonar = new Melody('~16 @10,1500,0,0 !200,1 !200,1500^190')\n\n    //% fixedInstance whenUsed block=\"spooky\"\n    export const spooky = new Melody('~16 @700,1300,0,0 !100,1 ~18 !108,2000')\n\n    //% fixedInstance whenUsed block=\"beam up\"\n    export const beamUp = new Melody('~18 @10,1500,0,0 !200,1500^4000')\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    //% block=\"2\"\n    Double = 32,\n    //% block=\"4\",\n    Breve = 64,\n    //% block=\"1/3\",\n    Triplet = 128\n}\n\nnamespace music {\n\n    let beatsPerMinute: number;\n\n    /**\n    * Play a tone.\n    * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n    */\n    //% help=music/ring-tone\n    //% blockId=music_ring block=\"ring tone|at %note=device_note\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music inBasicCategory=true\n    //% weight=75 blockGap=8\n    //% group=\"Tone\"\n    export function ringTone(frequency: number) {\n        playTone(frequency, 0);\n    }\n\n    /**\n    * Rest, or play silence, for some time (in milliseconds).\n    * @param ms rest duration in milliseconds (ms), eg: BeatFraction.Half\n    */\n    //% help=music/rest\n    //% blockId=music_rest block=\"rest|for %duration=device_beat\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music\n    //% weight=74\n    //% group=\"Tone\"\n    export function rest(ms: number) {\n        playTone(0, Math.max(ms, 20));\n    }\n\n    function init() {\n        if (!beatsPerMinute) beatsPerMinute = 120;\n    }\n\n    /**\n     * Return the duration of a beat in milliseconds (the beat fraction).\n     * @param fraction the fraction of the current whole note, eg: BeatFraction.Half\n     */\n    //% help=music/beat\n    //% blockId=device_beat block=\"%fraction|beat\"\n    //% weight=9 blockGap=8\n    //% group=\"Tempo\"\n    export function beat(fraction?: BeatFraction): number {\n        init();\n        if (fraction == null) fraction = BeatFraction.Whole;\n        let beat = 60000 / beatsPerMinute;\n        switch (fraction) {\n            case BeatFraction.Half: beat /= 2; break;\n            case BeatFraction.Quarter: beat /= 4; break;\n            case BeatFraction.Eighth: beat /= 8; break;\n            case BeatFraction.Sixteenth: beat /= 16; break;\n            case BeatFraction.Double: beat *= 2; break;\n            case BeatFraction.Breve: beat *= 4; break;\n            case BeatFraction.Triplet: beat /= 3; break;\n        }\n        return beat >> 0;\n    }\n\n    /**\n     * Return the tempo in beats per minute (bpm).\n     * 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\n    //% blockId=device_tempo block=\"tempo (bpm)\"\n    //% weight=64\n    //% group=\"Tempo\"\n    export function tempo(): number {\n        init();\n        return beatsPerMinute;\n    }\n\n    /**\n     * Change the tempo up or down by some amount of beats per minute (bpm).\n     * @param bpm The change in beats per minute to the tempo, eg: 20\n     */\n    //% help=music/change-tempo-by weight=37\n    //% blockId=device_change_tempo block=\"change tempo by %value|(bpm)\"\n    //% weight=66 blockGap=8\n    //% group=\"Tempo\"\n    export function changeTempoBy(bpm: number): void {\n        init();\n        setTempo(beatsPerMinute + bpm);\n    }\n\n    /**\n     * Set the tempo a number of beats per minute (bpm).\n     * @param bpm The new tempo in beats per minute, eg: 120\n     */\n    //% help=music/set-tempo\n    //% blockId=device_set_tempo block=\"set tempo to %value|(bpm)\"\n    //% bpm.min=4 bpm.max=400\n    //% weight=65 blockGap=8\n    //% group=\"Tempo\"\n    export function setTempo(bpm: number): void {\n        init();\n        if (bpm > 0) {\n            beatsPerMinute = Math.max(1, bpm >> 0);\n        }\n    }\n}\n","ns.ts":"\n/**\n * Generation of music tones.\n */\n//% color=#E30FC0 weight=90 icon=\"\\uf025\"\n//% blockGap=8\n//% groups='[\"Songs\", \"Sounds\", \"Tone\",  \"Volume\", \"Tempo\"]'\nnamespace music {\n}","piano.ts":"namespace music {\n    /**\n     * Get the frequency of a note.\n     * @param name the note name, eg: Note.C\n     */\n    //% weight=1 help=music/note-frequency\n    //% blockId=device_note block=\"%note\"\n    //% shim=TD_ID\n    //% color=\"#FFFFFF\" colorSecondary=\"#FFFFFF\" colorTertiary=\"#D83B01\"\n    //% note.fieldEditor=\"note\" note.defl=\"262\"\n    //% note.fieldOptions.decompileLiterals=true\n    //% useEnumVal=1\n    //% weight=10 blockGap=8\n    //% group=\"Tone\"\n    export function noteFrequency(name: Note): number {\n        return name;\n    }\n}","playable.ts":"namespace music {\n    export enum PlaybackMode {\n        //% block=\"until done\"\n        UntilDone,\n        //% block=\"in background\"\n        InBackground,\n        //% block=\"looping in background\"\n        LoopingInBackground\n    }\n\n    let stateStack: PlayableState[];\n\n    class PlayableState {\n        looping: Playable[];\n        constructor() {\n            this.looping = [];\n        }\n\n        stopLooping() {\n            for (const p of this.looping) {\n                p.stopped = true;\n            }\n            this.looping = [];\n        }\n    }\n\n    function state() {\n        _init();\n        return stateStack[stateStack.length - 1];\n    }\n\n    function _init() {\n        if (stateStack) return;\n        stateStack = [new PlayableState()];\n\n        game.addScenePushHandler(() => {\n            stateStack.push(new PlayableState());\n        });\n\n        game.addScenePopHandler(() => {\n            stateStack.pop();\n            if (stateStack.length === 0) stateStack.push(new PlayableState());\n        });\n    }\n\n    export class Playable {\n        stopped: boolean;\n        constructor() {\n\n        }\n\n        play(playbackMode: PlaybackMode) {\n            // subclass\n        }\n\n        loop() {\n            state().looping.push(this);\n            this.stopped = false;\n\n            control.runInParallel(() => {\n                while (!this.stopped) {\n                    this.play(PlaybackMode.UntilDone);\n                }\n            });\n        }\n    }\n\n    export class MelodyPlayable extends Playable {\n        constructor(public melody: Melody) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                this.melody.play(music.volume());\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                this.melody.playUntilDone(music.volume());\n            }\n            else {\n                this.melody.loop(music.volume());\n            }\n        }\n    }\n\n    export class TonePlayable extends Playable {\n        constructor(public pitch: number, public duration: number) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                control.runInParallel(() => music.playTone(this.pitch, this.duration));\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                music.playTone(this.pitch, this.duration);\n                if (this.duration > 2000) {\n                    pause(this.duration);\n                }\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n    /**\n     * Play a song, melody, or other sound. The music plays until finished or can play as a\n     * background task.\n     * @param toPlay the song or melody to play\n     * @param playbackMode play the song or melody until it's finished or as background task\n     */\n    //% blockId=\"music_playable_play\"\n    //% block=\"play $toPlay $playbackMode\"\n    //% toPlay.shadow=music_melody_playable\n    //% group=\"Sounds\"\n    //% help=\"music/play\"\n    export function play(toPlay: Playable, playbackMode: PlaybackMode) {\n        toPlay.play(playbackMode);\n    }\n\n    /**\n     * Create a Playable object for a melody.\n     * @param melody the melody to make playable\n     */\n    //% blockId=\"music_melody_playable\"\n    //% block=\"sound $melody\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    //% blockHidden\n    //% help=music/melody-playable\n    export function melodyPlayable(melody: Melody): Playable {\n        return new MelodyPlayable(melody);\n    }\n\n    /**\n     * Create a Playable object for a melody string containg notes.\n     * @param melody the melody string to make playable\n     */\n    //% blockId=\"music_string_playable\"\n    //% block=\"melody $melody at tempo $tempo|(bpm)\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% melody.shadow=melody_editor\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% help=music/string-playable\n    export function stringPlayable(melody: string, tempo: number): Playable {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        return new MelodyPlayable(new Melody(formattedMelody));\n    }\n\n    /**\n     * Create a Playable object for a single tone and its duration.\n     * @param note the note or tone frequency to play\n     * @param duration the duration of the tone in milliseconds (ms)\n     */\n    //% blockId=\"music_tone_playable\"\n    //% block=\"tone $note for $duration\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Tone\"\n    //% duplicateShadowOnDrag\n    //% note.shadow=device_note\n    //% duration.shadow=device_beat\n    //% parts=\"headphone\"\n    //% help=music/tone-playable\n    export function tonePlayable(note: number, duration: number): Playable {\n        return new TonePlayable(note, duration);\n    }\n\n    export function _stopPlayables() {\n        state().stopLooping();\n    }\n}","pxt.json":"{\n    \"name\": \"mixer\",\n    \"description\": \"The music library with a mixer\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"SoundOutput.h\",\n        \"sound.cpp\",\n        \"melody.h\",\n        \"melody.cpp\",\n        \"melody.ts\",\n        \"piano.ts\",\n        \"legacy.ts\",\n        \"ns.ts\",\n        \"targetoverrides.ts\",\n        \"music.ts\",\n        \"soundEffect.ts\",\n        \"instrument.ts\",\n        \"sequencer.ts\",\n        \"playable.ts\",\n        \"pxtparts.json\",\n        \"headphone.svg\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","pxtparts.json":"{\n    \"headphone\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"image\": \"headphone.svg\",\n            \"width\": 142,\n            \"height\": 180,\n            \"pinDistance\": 20,\n            \"pinLocations\": [\n                {\n                    \"x\": 17,\n                    \"y\": 11\n                },\n                {\n                    \"x\": 55,\n                    \"y\": 50\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"A0\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","sequencer.ts":"namespace music.sequencer {\n    const SEQUENCER_STOP_MESSAGE = 3243;\n    const SEQUENCER_TICK_MESSAGE = 3244;\n    const SEQUENCER_STATE_CHANGE_MESSAGE = 3245;\n    const SEQUENCER_LOOPED_MESSAGE = 3246;\n\n    export class Sequencer {\n        currentTick: number;\n        isPlaying: boolean;\n        isLooping: boolean;\n        isRunning: boolean;\n\n        constructor(public song: Song) {\n            this.currentTick = 0;\n            this.isPlaying = false;\n            this.isLooping = false;\n        }\n\n        start(loop: boolean) {\n            this.currentTick = 0;\n            this.isLooping = loop;\n            this.isPlaying = true;\n\n            if (this.isRunning) return;\n            this.isRunning = true;\n\n            control.runInParallel(() => {\n                while (this.isPlaying) {\n                    this.scheduleCurrentTick();\n\n                    this.currentTick ++;\n\n                    if (this.currentTick >= this.song.beatsPerMeasure * this.song.measures * this.song.ticksPerBeat) {\n                        if (this.isLooping) this.currentTick = 0;\n                        else this.isPlaying = false;\n                    }\n\n                    pause(this.tickToMs(1))\n                }\n                this.isRunning = false;\n            })\n        }\n\n        stop() {\n            this.isPlaying = false;\n        }\n\n        tickToMs(ticks: number) {\n            return ((60000 / this.song.beatsPerMinute) / this.song.ticksPerBeat) * ticks;\n        }\n\n        protected scheduleCurrentTick() {\n            for (const track of this.song.tracks) {\n                if (track.currentNoteEvent.startTick === this.currentTick) {\n                    if (track.isMelodicTrack) {\n                        this.scheduleMelodicTrack(track as MelodicTrack);\n                    }\n                    else {\n                        this.scheduleDrumTrack(track as DrumTrack);\n                    }\n\n                    track.advanceNoteEvent();\n                }\n            }\n        }\n\n        protected scheduleMelodicTrack(track: MelodicTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderInstrument(\n                        track.instrument,\n                        lookupFrequency(track.currentNoteEvent.getNote(i, track.instrument.octave)),\n                        this.tickToMs(track.currentNoteEvent.endTick - track.currentNoteEvent.startTick),\n                        music.volume()\n                    )\n                );\n            }\n        }\n\n        protected scheduleDrumTrack(track: DrumTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderDrumInstrument(\n                        track.drums[track.currentNoteEvent.getNote(i, undefined)],\n                        music.volume()\n                    )\n                );\n            }\n        }\n    }\n\n    let activeSimSequencers: _SimulatorSequencer[];\n    export function _stopAllSimSequencers() {\n        if (activeSimSequencers) {\n            for (const seq of activeSimSequencers) {\n                seq.stop();\n                seq.dispose();\n            }\n            activeSimSequencers = [];\n        }\n    }\n\n    // Simulator only! Does nothing on hardware\n    export class _SimulatorSequencer {\n        protected id: number;\n\n        constructor() {\n            if (!activeSimSequencers) activeSimSequencers = [];\n            activeSimSequencers.push(this);\n            this.id = _createSequencer();\n            this.setVolume(music.volume());\n        }\n\n        play(song: Buffer, loop: boolean) {\n            this.setVolume(music.volume());\n            _sequencerPlaySong(this.id, song, loop)\n        }\n\n        stop() {\n            _sequencerStop(this.id);\n        }\n\n        setVolume(volume: number) {\n            _sequencerSetVolume(this.id, volume);\n        }\n\n        setTrackVolume(trackIndex: number, volume: number) {\n            _sequencerSetTrackVolume(this.id, trackIndex, volume)\n        }\n\n        setDrumTrackVolume(trackIndex: number, drumIndex: number, volume: number) {\n            _sequencerSetDrumTrackVolume(this.id, drumIndex, trackIndex, volume)\n        }\n\n        state() {\n            return _sequencerState(this.id) || \"stop\";\n        }\n\n        currentTick() {\n            return _sequencerCurrentTick(this.id);\n        }\n\n        dispose() {\n            _sequencerDispose(this.id);\n        }\n\n        onTick(handler: (tick: number) => void) {\n            control.onEvent(SEQUENCER_TICK_MESSAGE, this.id, () => {\n                handler(this.currentTick());\n            });\n        }\n\n        onStateChange(handler: (state: string) => void) {\n            control.onEvent(SEQUENCER_STATE_CHANGE_MESSAGE, this.id, () => {\n                handler(this.state());\n            });\n        }\n\n        onStop(handler: () => void) {\n            control.onEvent(SEQUENCER_STOP_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n\n        onLooped(handler: () => void) {\n            control.onEvent(SEQUENCER_LOOPED_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n    }\n\n    //% promise\n    //% shim=music::_createSequencer\n    declare function _createSequencer(): number\n\n    //% shim=music::_sequencerState\n    declare function _sequencerState(id: number): string;\n\n    //% shim=music::_sequencerCurrentTick\n    declare function _sequencerCurrentTick(id: number): number;\n\n    //% shim=music::_sequencerPlaySong\n    declare function _sequencerPlaySong(id: number, song: Buffer, loop: boolean): void;\n\n    //% shim=music::_sequencerStop\n    declare function _sequencerStop(id: number): void;\n\n    //% shim=music::_sequencerSetVolume\n    declare function _sequencerSetVolume(id: number, volume: number): void;\n\n    //% shim=music::_sequencerSetVolumeForAll\n    declare function _sequencerSetVolumeForAll(volume: number): void;\n\n    //% shim=music::_sequencerSetTrackVolume\n    declare function _sequencerSetTrackVolume(id: number, trackIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerSetDrumTrackVolume\n    declare function _sequencerSetDrumTrackVolume(id: number, trackIndex: number, drumIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerDispose\n    declare function _sequencerDispose(id: number): void;\n}","sound.cpp":"// to be overridden\n","soundEffect.ts":"enum WaveShape {\n    //% block=\"sine\"\n    Sine = 0,\n    //% block=\"sawtooth\"\n    Sawtooth = 1,\n    //% block=\"triangle\"\n    Triangle = 2,\n    //% block=\"square\"\n    Square = 3,\n    //% block=\"noise\"\n    Noise = 4\n}\n\nenum InterpolationCurve {\n    //% block=\"linear\"\n    Linear,\n    //% block=\"curve\"\n    Curve,\n    //% block=\"logarithmic\"\n    Logarithmic\n}\n\nenum SoundExpressionEffect {\n    //% block=\"none\"\n    None = 0,\n    //% block=\"vibrato\"\n    Vibrato = 1,\n    //% block=\"tremolo\"\n    Tremolo = 2,\n    //% block=\"warble\"\n    Warble = 3\n}\n\nenum SoundExpressionPlayMode {\n    //% block=\"until done\"\n    UntilDone,\n    //% block=\"in background\"\n    InBackground\n}\n\nnamespace music {\n    export class SoundEffect extends Playable {\n        waveShape: WaveShape;\n        startFrequency: number;\n        endFrequency: number;\n        startVolume: number;\n        endVolume: number;\n        duration: number;\n        effect: SoundExpressionEffect;\n        interpolation: InterpolationCurve;\n\n        constructor() {\n            super();\n            this.waveShape = WaveShape.Sine;\n            this.startFrequency = 5000;\n            this.endFrequency = 1;\n            this.startVolume = 255;\n            this.endVolume = 0;\n            this.duration = 1000;\n            this.effect = SoundExpressionEffect.None;\n            this.interpolation = InterpolationCurve.Linear;\n        }\n\n        toBuffer(volume?: number) {\n            if (volume === undefined) volume = music.volume();\n\n            return soundToInstructionBuffer(\n                this.waveShape,\n                this.startFrequency,\n                this.endFrequency,\n                this.startVolume,\n                this.endVolume,\n                this.duration,\n                this.effect,\n                this.interpolation,\n                20,\n                1,\n                volume\n            );\n        }\n\n        play(playbackMode: PlaybackMode) {\n            const toPlay = this.toBuffer(music.volume());\n            if (playbackMode === PlaybackMode.InBackground) {\n                queuePlayInstructions(0, toPlay);\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                queuePlayInstructions(0, toPlay);\n                pause(this.duration)\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n\n    /**\n     * Play a SoundEffect.\n     * @param sound the SoundEffect to play\n     * @param mode the play mode, play until done or in the background\n     */\n    //% blockId=soundExpression_playSoundEffect\n    //% block=\"play sound $sound $mode\"\n    //% weight=30\n    //% help=music/play-sound-effect\n    //% blockGap=8\n    //% group=\"Sounds\"\n    //% deprecated=1\n    export function playSoundEffect(sound: SoundEffect, mode: SoundExpressionPlayMode) {\n        const toPlay = sound.toBuffer(music.volume());\n\n        queuePlayInstructions(0, toPlay);\n        if (mode === SoundExpressionPlayMode.UntilDone) {\n            pause(sound.duration);\n        }\n    }\n\n    /**\n     * Create a sound expression from a set of sound effect parameters.\n     * @param waveShape waveform of the sound effect\n     * @param startFrequency starting frequency for the sound effect waveform\n     * @param endFrequency ending frequency for the sound effect waveform\n     * @param startVolume starting volume of the sound, or starting amplitude\n     * @param endVolume ending volume of the sound, or ending amplitude\n     * @param duration the amount of time in milliseconds (ms) that sound will play for\n     * @param effect the effect to apply to the waveform or volume\n     * @param interpolation interpolation method for frequency scaling\n     */\n    //% blockId=soundExpression_createSoundEffect\n    //% help=music/create-sound-effect\n    //% block=\"$waveShape|| start frequency $startFrequency end frequency $endFrequency duration $duration start volume $startVolume end volume $endVolume effect $effect interpolation $interpolation\"\n    //% waveShape.defl=WaveShape.Sine\n    //% waveShape.fieldEditor=soundeffect\n    //% waveShape.fieldOptions.useMixerSynthesizer=true\n    //% startFrequency.defl=5000\n    //% startFrequency.min=0\n    //% startFrequency.max=5000\n    //% endFrequency.defl=0\n    //% endFrequency.min=0\n    //% endFrequency.max=5000\n    //% startVolume.defl=255\n    //% startVolume.min=0\n    //% startVolume.max=255\n    //% endVolume.defl=0\n    //% endVolume.min=0\n    //% endVolume.max=255\n    //% duration.defl=500\n    //% duration.min=1\n    //% duration.max=9999\n    //% effect.defl=SoundExpressionEffect.None\n    //% interpolation.defl=InterpolationCurve.Linear\n    //% compileHiddenArguments=true\n    //% inlineInputMode=\"variable\"\n    //% inlineInputModeLimit=3\n    //% expandableArgumentBreaks=\"3,5\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=20\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    export function createSoundEffect(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve): SoundEffect {\n        const result = new SoundEffect();\n\n        result.waveShape = waveShape;\n        result.startFrequency = startFrequency;\n        result.endFrequency = endFrequency;\n        result.startVolume = startVolume;\n        result.endVolume = endVolume;\n        result.duration = duration;\n        result.effect = effect;\n        result.interpolation = interpolation;\n\n        return result;\n    }\n\n    interface Step {\n        frequency: number;\n        volume: number;\n    }\n\n     export function soundToInstructionBuffer(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve, fxSteps: number, fxRange: number, globalVolume: number) {\n        const steps: Step[] = [];\n\n        // Optimize the simple case\n        if (interpolation === InterpolationCurve.Linear && effect === SoundExpressionEffect.None) {\n            steps.push({\n                frequency: startFrequency,\n                volume: (startVolume / 255) * globalVolume,\n            })\n            steps.push({\n                frequency: endFrequency,\n                volume: (endVolume / 255) * globalVolume,\n            })\n        }\n        else {\n\n            fxSteps = Math.min(fxSteps, Math.floor(duration / 5))\n\n            const getVolumeAt = (t: number) => ((startVolume + t * (endVolume - startVolume) / duration) / 255) * globalVolume;\n            let getFrequencyAt: (t: number) => number;\n\n            switch (interpolation) {\n                case InterpolationCurve.Linear:\n                    getFrequencyAt = t => startFrequency + t * (endFrequency - startFrequency) / duration;\n                    break;\n                case InterpolationCurve.Curve:\n                    getFrequencyAt = t => startFrequency + (endFrequency - startFrequency) * Math.sin(t / duration * (Math.PI / 2));\n                    break;\n                case InterpolationCurve.Logarithmic:\n                    getFrequencyAt = t => startFrequency + (Math.log(1 + 9 * (t / duration)) / Math.log(10)) * (endFrequency - startFrequency)\n                    break;\n            }\n\n            const timeSlice = duration / fxSteps;\n\n            for (let i = 0; i < fxSteps; i++) {\n                const newStep = {\n                    frequency: getFrequencyAt(i * timeSlice),\n                    volume: getVolumeAt(i * timeSlice)\n                };\n\n                if (effect === SoundExpressionEffect.Tremolo) {\n                    if (i % 2 === 0) {\n                        newStep.volume = Math.max(newStep.volume - fxRange * 500, 0)\n                    }\n                    else {\n                        newStep.volume = Math.min(newStep.volume + fxRange * 500, 1023)\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Vibrato) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 100, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 100\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Warble) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 1000, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 1000\n                    }\n                }\n\n                steps.push(newStep)\n            }\n        }\n\n        const out = control.createBuffer(12 * (steps.length - 1));\n        const stepDuration = Math.floor(duration / (steps.length - 1))\n\n        for (let i = 0; i < steps.length - 1; i++) {\n            const offset = i * 12;\n            out.setNumber(NumberFormat.UInt8LE, offset, waveToValue(waveShape));\n            out.setNumber(NumberFormat.UInt16LE, offset + 2, steps[i].frequency);\n            out.setNumber(NumberFormat.UInt16LE, offset + 4, stepDuration);\n            out.setNumber(NumberFormat.UInt16LE, offset + 6, steps[i].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 8, steps[i + 1].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 10, steps[i + 1].frequency);\n        }\n\n        return out;\n    }\n\n    function waveToValue(wave: WaveShape) {\n        switch (wave) {\n            case WaveShape.Square: return 15;\n            case WaveShape.Sine: return 3;\n            case WaveShape.Triangle: return 1;\n            case WaveShape.Noise: return 18;\n            case WaveShape.Sawtooth: return 2;\n        }\n    }\n\n\n    /**\n     * Generate a random similar sound effect to the given one.\n     *\n     * @param sound the sound effect\n     */\n    //% blockId=soundExpression_generateSimilarSound\n    //% block=\"randomize $sound\"\n    //% sound.shadow=soundExpression_createSoundEffect\n    //% weight=0 help=music/randomize-sound\n    //% blockGap=8\n    //% group=\"Sounds\"\n    export function randomizeSound(sound: SoundEffect) {\n        const res = new SoundEffect();\n        res.waveShape = sound.waveShape;\n        res.startFrequency = sound.startFrequency;\n        res.endFrequency = sound.endFrequency;\n        res.startVolume = sound.startVolume;\n        res.endVolume = sound.endVolume;\n        res.duration = sound.duration;\n        res.effect = sound.effect;\n        res.interpolation = randomInterpolation();\n\n        res.duration = Math.clamp(\n            Math.min(100, res.duration),\n            Math.max(2000, res.duration),\n            res.duration + (Math.random() - 0.5) * res.duration,\n        );\n\n        if (res.waveShape === WaveShape.Noise) {\n            // The primary waveforms don't produce sounds that are similar to noise,\n            // but adding an effect sorta does\n            if (Math.percentChance(20)) {\n                res.waveShape = randomWave();\n                res.effect = randomEffect();\n            }\n        }\n        else {\n            res.waveShape = randomWave();\n\n            // Adding an effect can drastically alter the sound, so keep it\n            // at a low percent chance unless there already is one\n            if (res.effect !== SoundExpressionEffect.None || Math.percentChance(10)) {\n                res.effect = randomEffect();\n            }\n        }\n\n        // Instead of randomly changing the frequency, change the slope and choose\n        // a new start frequency. This keeps a similar profile to the sound\n        const oldFrequencyDifference = res.endFrequency - res.startFrequency;\n        let newFrequencyDifference = oldFrequencyDifference + (oldFrequencyDifference * 2) * (Math.random() - 0.5);\n\n        if (Math.sign(oldFrequencyDifference) !== Math.sign(newFrequencyDifference)) {\n            newFrequencyDifference *= -1;\n        }\n\n        newFrequencyDifference = Math.clamp(-5000, 5000, newFrequencyDifference);\n\n        res.startFrequency = Math.clamp(\n            Math.max(-newFrequencyDifference, 1),\n            Math.clamp(1, 5000, 5000 - newFrequencyDifference),\n            Math.random() * 5000,\n        );\n\n        res.endFrequency = Math.clamp(1, 5000, res.startFrequency + newFrequencyDifference);\n\n        // Same strategy for volume\n        const oldVolumeDifference = res.endVolume - res.startVolume;\n        let newVolumeDifference = oldVolumeDifference + oldVolumeDifference * (Math.random() - 0.5);\n\n        newVolumeDifference = Math.clamp(-255, 255, newVolumeDifference);\n\n        if (Math.sign(oldVolumeDifference) !== Math.sign(newVolumeDifference)) {\n            newVolumeDifference *= -1;\n        }\n\n        res.startVolume = Math.clamp(\n            Math.max(-newVolumeDifference, 0),\n            Math.clamp(0, 255, 255 - newVolumeDifference),\n            Math.random() * 255,\n        );\n\n        res.endVolume = Math.clamp(0, 255, res.startVolume + newVolumeDifference);\n\n        return res;\n    }\n\n    function randomWave() {\n        switch (Math.randomRange(0, 3)) {\n            case 1: return WaveShape.Sawtooth;\n            case 2: return WaveShape.Square;\n            case 3: return WaveShape.Triangle;\n            case 0:\n            default:\n                return WaveShape.Sine;\n        }\n    }\n\n    function randomEffect() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return SoundExpressionEffect.Warble;\n            case 2: return  SoundExpressionEffect.Tremolo;\n            case 0:\n            default:\n                return SoundExpressionEffect.Vibrato;\n        }\n    }\n\n    function randomInterpolation() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return InterpolationCurve.Linear;\n            case 2: return  InterpolationCurve.Curve;\n            case 0:\n            default:\n                return InterpolationCurve.Logarithmic;\n        }\n    }\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n}","targetoverrides.ts":"\n","test.ts":"for(let i = 1000; i > 0; i -= 50)\n    music.playTone(440, i)\n\nfor(let i = 0; i < 1000; i += 20)\n    music.playTone(440, i)\n"},"mixer---ext":{"SoundOutput.h":"#define SAMPLE_RATE 44100\n\nnamespace music {\nclass WSynthesizer;\n\nclass ExtDAC {\n  public:\n    WSynthesizer &src;\n    ExtDAC(WSynthesizer &data);\n    int getSampleRate() { return SAMPLE_RATE; }\n};\n\nclass SoundOutput {\n  public:\n    ExtDAC dac;\n\n    SoundOutput(WSynthesizer &data) : dac(data) {}\n\n    void setOutput(int) {}\n};\n\n} // namespace music","headphone.svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"142\" height=\"180\" viewBox=\"0 0 142 180\"><rect ry=\".3\" rx=\"1\" y=\"58.615\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><rect ry=\".3\" rx=\"1\" y=\"32.043\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><path d=\"M.346 7.296c-.394.39-.31 4.797-.18 4.898l13.404 10.18c.117.12.337 4.76.73 4.368l5.506-5.56.01.01 6.51-6.444c.39-.392-4.25-.614-4.366-.73L11.777.612c-.1-.132-4.51-.215-4.898.18L4.087 3.636l-.01-.01-3.73 3.67z\" fill=\"#b3b3b3\"/><rect ry=\"6.85\" rx=\"4.571\" y=\"84.758\" x=\"-20.128\" height=\"75.571\" width=\"39.643\" transform=\"rotate(-45)\"/><rect ry=\".374\" rx=\"1.038\" y=\"29.442\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"55.939\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"82.392\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\"2.317\" rx=\"2.183\" y=\"158.876\" x=\"-9.774\" height=\"25.568\" width=\"18.935\" transform=\"rotate(-45)\"/><path d=\"M128.588 128.82s14.97 11.165 7.547 26.35c-8.426 17.24-25.57 20.653-25.57 20.653\" fill=\"none\" stroke=\"#000\" stroke-width=\"6.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>","instrument.ts":"namespace music.sequencer {\n    const BUFFER_SIZE = 12;\n\n    let currentSequencer: sequencer.Sequencer;\n\n    /**\n     * Byte encoding format for songs\n     * FIXME: should this all be word aligned?\n     *\n     * song(7 + length of all tracks bytes)\n     *     0 version\n     *     1 beats per minute\n     *     3 beats per measure\n     *     4 ticks per beat\n     *     5 measures\n     *     6 number of tracks\n     *     ...tracks\n     *\n     * track(6 + instrument length + note length bytes)\n     *     0 id\n     *     1 flags\n     *     2 instruments byte length\n     *     4...instrument\n     *     notes byte length\n     *     ...note events\n     *\n     * instrument(28 bytes)\n     *     0 waveform\n     *     1 amp attack\n     *     3 amp decay\n     *     5 amp sustain\n     *     7 amp release\n     *     9 amp amp\n     *     11 pitch attack\n     *     13 pitch decay\n     *     15 pitch sustain\n     *     17 pitch release\n     *     19 pitch amp\n     *     21 amp lfo freq\n     *     22 amp lfo amp\n     *     24 pitch lfo freq\n     *     25 pitch lfo amp\n     *     27 octave\n     *\n     * drum(5 + 7 * steps bytes)\n     *     0 steps\n     *     1 start freq\n     *     3 start amp\n     *     5...steps\n     *\n     * drum step(7 bytes)\n     *     0 waveform\n     *     1 freq\n     *     3 volume\n     *     5 duration\n     *\n     * note event(5 + 1 * polyphony bytes)\n     *     0 start tick\n     *     2 end tick\n     *     4 polyphony\n     *     5...notes(1 byte each)\n     *\n     * note (1 byte)\n     *     lower six bits = note - (instrumentOctave - 2) * 12\n     *     upper two bits are the enharmonic spelling:\n     *          0 = normal\n     *          1 = flat\n     *          2 = sharp\n     */\n\n    export class Song extends Playable {\n        tracks: Track[];\n\n        constructor(public buf: Buffer) {\n            super();\n            this.tracks = [];\n\n            let currentOffset = 7;\n            for (let i = 0; i < this.numberOfTracks; i++) {\n                let track: Track = new MelodicTrack(this.buf, currentOffset);\n\n                if (!track.isMelodicTrack) {\n                    track = new DrumTrack(this.buf, currentOffset)\n                }\n\n                this.tracks.push(track);\n                currentOffset += track.byteLength;\n            }\n        }\n\n        get version(): number {\n            return this.buf[0];\n        }\n\n        set version(value: number) {\n            this.buf[0] = value;\n        }\n\n        get beatsPerMinute(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, 1);\n        }\n\n        set beatsPerMinute(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, 1, value);\n        }\n\n        get beatsPerMeasure(): number {\n            return this.buf[3];\n        }\n\n        set beatsPerMeasure(value: number) {\n            this.buf[3] = value;\n        }\n\n        get ticksPerBeat(): number {\n            return this.buf[4];\n        }\n\n        set ticksPerBeat(value: number) {\n            this.buf[4] = value;\n        }\n\n        get measures(): number {\n            return this.buf[5];\n        }\n\n        set measures(value: number) {\n            this.buf[5] = value;\n        }\n\n        get numberOfTracks(): number {\n            return this.buf[6];\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (control.deviceDalVersion() === \"sim\") {\n                const seq = new _SimulatorSequencer();\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    seq.play(this.buf, false);\n\n                    pauseUntil(() => seq.state() === \"stop\");\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    seq.play(this.buf, false);\n                }\n                else {\n                    seq.play(this.buf, true);\n                }\n            }\n            else {\n                if (currentSequencer) currentSequencer.stop();\n                currentSequencer = new sequencer.Sequencer(this);\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    let seq = currentSequencer;\n                    currentSequencer.start(false);\n                    pauseUntil(() => !seq.isRunning);\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    currentSequencer.start(false);\n                }\n                else {\n                    currentSequencer.start(true);\n                }\n            }\n        }\n    }\n\n    export class Envelope {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(10);\n            this.offset = this.offset || 0;\n        }\n\n        // The time in ms for the envelope to reach its maximum value\n        get attack(): number {\n            return this.getValue(0);\n        }\n\n        set attack(value: number) {\n            this.setValue(0, value);\n        }\n\n        // The time in ms for the envelope to reach its sustain value after reaching its maximum value\n        get decay(): number {\n            return this.getValue(2);\n        }\n\n        set decay(value: number) {\n            this.setValue(2, value);\n        }\n\n        // The value (0-1024) to hold at during the sustain stage\n        get sustain(): number {\n            return this.getValue(4);\n        }\n\n        set sustain(value: number) {\n            this.setValue(4, value);\n        }\n\n        // The time in ms for the envelope to reach 0 after the gate length ends\n        get release(): number {\n            return this.getValue(6);\n        }\n\n        set release(value: number) {\n            this.setValue(6, value);\n        }\n\n        // The maximum value that this envelope will reach\n        get amplitude(): number {\n            return this.getValue(8);\n        }\n\n        set amplitude(value: number) {\n            this.setValue(8, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class LFO {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(3);\n            this.offset = this.offset || 0;\n        }\n\n        get frequency(): number {\n            return this.buf[this.offset];\n        }\n\n        set frequency(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get amplitude(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + 1);\n        }\n\n        set amplitude(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + 1, value);\n        }\n    }\n\n    export class NoteEvent {\n        constructor(public buf: Buffer, public offset: number) {\n\n        }\n\n        get startTick(): number {\n            return this.getValue(0);\n        }\n\n        set startTick(value: number) {\n            this.setValue(0, value);\n        }\n\n        get endTick(): number {\n            return this.getValue(2);\n        }\n\n        set endTick(value: number) {\n            this.setValue(2, value);\n        }\n\n        get polyphony(): number {\n            return this.buf[this.offset + 4];\n        }\n\n        set polyphony(value: number) {\n            this.buf[this.offset + 4] = value;\n        }\n\n        get byteLength() {\n            return this.polyphony + 5;\n        }\n\n        getNote(offset: number, octave?: number) {\n            const value = this.buf[this.offset + offset + 5] & 0x3f;\n            if (octave !== undefined) {\n                return value + (octave - 2) * 12\n            }\n            return value\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class Track {\n        currentNoteEvent: NoteEvent;\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.currentNoteEvent = new NoteEvent(this.buf, this.noteEventStart + 2);\n        }\n\n        get isMelodicTrack(): boolean {\n            return this.flags === 0;\n        }\n\n        get id(): number {\n            return this.buf[this.offset];\n        }\n\n        set id(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get flags(): number {\n            return this.buf[this.offset + 1];\n        }\n\n        set flags(value: number) {\n            this.buf[this.offset + 1] = value;\n        }\n\n        get instrumentByteLength(): number {\n            return this.getValue(this.offset + 2);\n        }\n\n        set instrumentByteLength(value: number) {\n            this.setValue(this.offset + 2, value);\n        }\n\n        get noteEventStart(): number {\n            return this.offset + this.instrumentByteLength + 4;\n        }\n\n        get noteEventByteLength(): number {\n            return this.getValue(this.noteEventStart);\n        }\n\n        set noteEventByteLength(value: number) {\n            this.setValue(this.noteEventStart, value);\n        }\n\n        get byteLength() {\n            return this.noteEventByteLength + this.instrumentByteLength + 6;\n        }\n\n        advanceNoteEvent() {\n            this.currentNoteEvent.offset += this.currentNoteEvent.byteLength;\n\n            if (this.currentNoteEvent.offset >= this.offset + this.byteLength) {\n                this.currentNoteEvent.offset = this.noteEventStart + 2;\n            }\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, offset, value);\n        }\n    }\n\n    export class MelodicTrack extends Track {\n        instrument: Instrument;\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.instrument = new Instrument(this.buf, this.offset + 4);\n        }\n    }\n\n    export class DrumTrack extends Track {\n        drums: DrumInstrument[];\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.drums = [];\n\n            let currentOffset = 0;\n            while (currentOffset < this.instrumentByteLength) {\n                this.drums.push(new DrumInstrument(this.buf, this.offset + 4 + currentOffset));\n                currentOffset += this.drums[this.drums.length - 1].byteLength;\n            }\n        }\n    }\n\n    export class Instrument {\n        ampEnvelope: Envelope;\n        pitchEnvelope: Envelope;\n        ampLFO: LFO;\n        pitchLFO: LFO;\n\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(27);\n            this.offset = this.offset || 0;\n            this.ampEnvelope = new Envelope(this.buf, this.offset + 1);\n            this.pitchEnvelope = new Envelope(this.buf, this.offset + 11);\n            this.ampLFO = new LFO(this.buf, this.offset + 21);\n            this.pitchLFO = new LFO(this.buf, this.offset + 24)\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get octave(): number {\n            return this.buf[this.offset + 27]\n        }\n\n        set octave(value: number) {\n            this.buf[this.offset + 27] = value;\n        }\n    }\n\n    export class DrumInstrument {\n        steps: DrumStep[];\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.steps = [];\n\n            for (let i = 0; i < this.numSteps; i++) {\n                this.steps.push(new DrumStep(this.buf, this.offset + 5 + i * 7))\n            }\n        }\n\n        get byteLength(): number {\n            return 5 + this.numSteps * 7;\n        }\n\n        get numSteps(): number {\n            return this.buf[this.offset];\n        }\n\n        set numSteps(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get startFrequency(): number {\n            return this.getValue(1);\n        }\n\n        set startFrequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get startVolume(): number {\n            return this.getValue(3);\n        }\n\n        set startVolume(value: number) {\n            this.setValue(3, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class DrumStep {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(7);\n            this.offset = this.offset || 0;\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get frequency(): number {\n            return this.getValue(1);\n        }\n\n        set frequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get volume(): number {\n            return this.getValue(3);\n        }\n\n        set volume(value: number) {\n            this.setValue(3, value);\n        }\n\n        get duration(): number {\n            return this.getValue(5);\n        }\n\n        set duration(value: number) {\n            this.setValue(5, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    /**\n     * Renders a single note played on an instrument into a buffer of sound instructions.\n     *\n     * @param instrument The instrument being played\n     * @param noteFrequency The frequency of the note being played. In other words, \"the key being pressed on the piano\"\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     * @param volume The peak volume of the note to play (0-1024). Also called the \"velocity\"\n     */\n    export function renderInstrument(instrument: Instrument, noteFrequency: number, gateLength: number, volume: number) {\n        // We cut off the sound at the end of the amplitude envelope's release time. This is to prevent\n        // the amp envelope from making the sound keep playing forever\n        const totalDuration = gateLength + instrument.ampEnvelope.release;\n\n        // Our goal is to calculate the frequency and amplitude at all of the inflection points in this note's lifetime\n\n        // For the ADSR envelopes, the inflection points are:\n        //     1. The end of the envelope atack (which is when the decay begins)\n        //     2. The end of the envelope decay (which is when the sustain begins)\n        //     3. The end of the gateLength (which is when the release begins)\n        //     4. The end of the envelope release\n        // If the gateLength ends before any of these stages (e.g. it's shorter than the envelope's attack), then\n        // we ignore the other stages and go straight to the release stage.\n\n        // For the triangle LFOs, the inflections points occur every time the slope goes from positive to negative. In\n        // other words, it's half the period of the triangle wave.\n\n        const ampLFOInterval = instrument.ampLFO.amplitude ? Math.max(500 / instrument.ampLFO.frequency, 50) : 50;\n        const pitchLFOInterval = instrument.pitchLFO.amplitude ? Math.max(500 / instrument.pitchLFO.frequency, 50) : 50;\n\n        // We're going to add the timepoints to this array in order so that it doesn't need to be sorted\n        let timePoints = [0];\n\n        // For each LFO and envelope, keep track of the next inflection point. If any of the LFOs or envelopes have\n        // an amplitude of 0, we can ignore them entirely.\n        let nextAETime = instrument.ampEnvelope.attack;\n        let nextPETime = instrument.pitchEnvelope.amplitude ? instrument.pitchEnvelope.attack : totalDuration;\n        let nextPLTime = instrument.pitchLFO.amplitude ? pitchLFOInterval : totalDuration;\n        let nextALTime = instrument.ampLFO.amplitude ? ampLFOInterval : totalDuration;\n\n        let time = 0;\n        while (time < totalDuration) {\n            // Amp envelope\n            if (nextAETime <= nextPETime && nextAETime <= nextPLTime && nextAETime <= nextALTime) {\n                time = nextAETime;\n                timePoints.push(nextAETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            // Pitch envelope\n            else if (nextPETime <= nextPLTime && nextPETime <= nextALTime && nextPETime < totalDuration) {\n                time = nextPETime;\n                timePoints.push(nextPETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                // If we reach the end of the release before the amp envelope is finished, bail out\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            // Pitch LFO\n            else if (nextPLTime <= nextALTime && nextPLTime < totalDuration) {\n                time = nextPLTime;\n                timePoints.push(nextPLTime);\n                nextPLTime += pitchLFOInterval;\n            }\n            // Amp LFO\n            else if (nextALTime < totalDuration) {\n                time = nextALTime;\n                timePoints.push(nextALTime);\n                nextALTime += ampLFOInterval;\n            }\n\n\n            if (time >= totalDuration) {\n                break;\n            }\n\n            // Now that we've advanced the time, we need to check all of the envelopes/LFOs again\n            // to see if any of them also need to be pushed forward (e.g. they had the same inflection point\n            // as the one we just added to the array)\n            if (nextAETime <= time) {\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            if (nextPETime <= time) {\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            while (nextALTime <= time) {\n                nextALTime += ampLFOInterval;\n            }\n            while (nextPLTime <= time) {\n                nextPLTime += pitchLFOInterval;\n            }\n        }\n\n        // Once we've calculated the inflection points, calculate the frequency and amplitude at\n        // each step and interpolate between them with sound instructions\n        let prevAmp = instrumentVolumeAtTime(instrument, gateLength, 0, volume) | 0;\n        let prevPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, 0) | 0;\n        let prevTime = 0;\n\n        let nextAmp: number;\n        let nextPitch: number;\n        const out = control.createBuffer(BUFFER_SIZE * timePoints.length);\n        for (let i = 1; i < timePoints.length; i++) {\n            if (timePoints[i] - prevTime < 5) {\n                prevTime = timePoints[i];\n                continue;\n            }\n\n            nextAmp = instrumentVolumeAtTime(instrument, gateLength, timePoints[i], volume) | 0;\n            nextPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, timePoints[i]) | 0\n            addNote(\n                out,\n                (i - 1) * 12,\n                (timePoints[i] - prevTime) | 0,\n                prevAmp,\n                nextAmp,\n                instrument.waveform,\n                prevPitch,\n                255,\n                nextPitch\n            )\n\n            prevAmp = nextAmp;\n            prevPitch = nextPitch;\n            prevTime = timePoints[i];\n        }\n\n        // Finally, add one extra step to move the amplitude to 0 without\n        // clipping just in case the amp LFO caused it to be nonzero\n        addNote(\n            out,\n            (timePoints.length - 1) * 12,\n            10,\n            prevAmp,\n            0,\n            instrument.waveform,\n            prevPitch,\n            255,\n            prevPitch\n        )\n        return out;\n    }\n\n    export function renderDrumInstrument(sound: DrumInstrument, volume: number) {\n        // Drum instruments are rendered just like melodic instruments, but the inflection\n        // points are already calculated for us\n        let prevAmp = sound.startVolume;\n        let prevFreq = sound.startFrequency;\n\n        const scaleVolume = (value: number) => (value / 1024) * volume;\n\n        let out = control.createBuffer((sound.steps.length + 1) * BUFFER_SIZE);\n\n        for (let i = 0; i < sound.steps.length; i++) {\n            addNote(\n                out,\n                i * BUFFER_SIZE,\n                sound.steps[i].duration,\n                scaleVolume(prevAmp),\n                scaleVolume(sound.steps[i].volume),\n                sound.steps[i].waveform,\n                prevFreq,\n                255,\n                sound.steps[i].frequency\n            );\n            prevAmp = sound.steps[i].volume;\n            prevFreq = sound.steps[i].frequency\n        }\n\n        addNote(\n            out,\n            sound.steps.length * BUFFER_SIZE,\n            10,\n            scaleVolume(prevAmp),\n            0,\n            sound.steps[sound.steps.length - 1].waveform,\n            prevFreq,\n            255,\n            prevFreq\n        );\n\n        return out;\n    }\n\n    function instrumentPitchAtTime(instrument: Instrument, noteFrequency: number, gateLength: number, time: number) {\n        let mod = 0;\n        if (instrument.pitchEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.pitchEnvelope, time, gateLength)\n        }\n        if (instrument.pitchLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.pitchLFO, time)\n        }\n        return Math.max(noteFrequency + mod, 0);\n    }\n\n    function instrumentVolumeAtTime(instrument: Instrument, gateLength: number, time: number, maxVolume: number) {\n        let mod = 0;\n        if (instrument.ampEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.ampEnvelope, time, gateLength)\n        }\n        if (instrument.ampLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.ampLFO, time)\n        }\n        return ((Math.max(Math.min(mod, instrument.ampEnvelope.amplitude), 0) / 1024) * maxVolume) | 0;\n    }\n\n    /**\n     * Calculates the value of an ADSR envelope at the given time for a given gate length.\n     *\n     * @param envelope The ADSR envelope\n     * @param time The point and time to calculate the value at\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     */\n    function envelopeValueAtTime(envelope: Envelope, time: number, gateLength: number) {\n        // ADSR envelopes consist of 4 stages. They are (in order):\n        //     1. The attack stage, where the value starts at 0 and rises to the maximum value\n        //     2. The decay stage, where the value falls from the maximum value to the sustain value\n        //     3. The sustain stage, where the value holds steady at the sustain value until the gate length ends\n        //     4. The release stage, where the value falls to 0 after the gate length ends\n        // If the gate length ends before the sustain stage, we immediately skip to the release stage. All stages\n        // use a linear function for the value\n        const adjustedSustain = (envelope.sustain / 1024) * envelope.amplitude;\n\n        // First check to see if we are already in the release stage\n        if (time > gateLength) {\n            if (time - gateLength > envelope.release) return 0;\n\n            // Did the gate length end before the attack stage finished?\n            else if (time < envelope.attack) {\n                const height = (envelope.amplitude / envelope.attack) * gateLength;\n                return height - ((height / envelope.release) * (time - gateLength))\n            }\n            // Did the gate length end before the decay stage finished?\n            else if (time < envelope.attack + envelope.decay) {\n                const height2 = envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (gateLength - envelope.attack);\n                return height2 - ((height2 / envelope.release) * (time - gateLength))\n            }\n            else {\n                return adjustedSustain - (adjustedSustain / envelope.release) * (time - gateLength)\n            }\n        }\n        else if (time < envelope.attack) {\n            return (envelope.amplitude / envelope.attack) * time\n        }\n        else if (time < envelope.attack + envelope.decay) {\n            return envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (time - envelope.attack)\n        }\n        else {\n            return adjustedSustain;\n        }\n    }\n\n    /**\n     * Calculates the value of the LFO at the given time.\n     *\n     * TODO: might be nice to give options to shift the phase of the LFO or let it run free\n     *\n     * @param lfo The LFO to calculate the value of\n     * @param time The time to calculate the value at\n     */\n    function lfoValueAtTime(lfo: LFO, time: number) {\n        // Use cosine to smooth out the value somewhat\n        return Math.cos(((time / 1000) * lfo.frequency) * 2 * Math.PI) * lfo.amplitude\n    }\n\n    export function _stopAllSongs() {\n        if (currentSequencer) {\n            currentSequencer.stop();\n            currentSequencer = undefined;\n        }\n        _stopAllSimSequencers();\n    }\n}","legacy.ts":"//% deprecated=true hidden=true\nenum Sounds {\n    //% block=\"power up\"\n    PowerUp,\n    //% block=\"power down\"\n    PowerDown,\n    //% block=\"jump up\"\n    JumpUp,\n    //% block=\"jump down\"\n    JumpDown,\n    //% block=\"ba ding\"\n    BaDing,\n    //% block=\"wawawawaa\"\n    Wawawawaa,\n    //% block=\"magic wand\"\n    MagicWand,\n    //% block=\"siren\"\n    Siren\n}\n\nnamespace music {\n    /**\n     * Get the melody string for a built-in melody.\n     * @param name the note name, eg: Note.C\n     */\n    //% help=music/sounds\n    //% blockId=music_sounds block=\"%name\"\n    //% blockHidden=true\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=285\n    //% name.fieldOptions.columns=3\n    export function sounds(name: Sounds): string {\n        switch (name) {\n            case Sounds.BaDing:\n                return 'b5:1 e6:3';\n            case Sounds.Wawawawaa:\n                return 'e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8';\n            case Sounds.JumpUp:\n                return 'c5:1 d e f g';\n            case Sounds.JumpDown:\n                return 'g5:1 f e d c';\n            case Sounds.PowerUp:\n                return 'g4:1 c5 e g:2 e:1 g:3';\n            case Sounds.PowerDown:\n                return 'g5:1 d# c g4:2 b:1 c5:3';\n            case Sounds.MagicWand:\n                return 'F#6:1-300 G# A# B C7# D# F F# G# A# B:6'; //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n            case Sounds.Siren:\n                return 'a4 d5 a4 d5 a4 d5';\n            default:\n                return '';\n        }\n    }\n\n    let currMelody: Melody\n\n    /**\n     * Start playing a sound and don't wait for it to finish.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound\n    //% blockId=music_play_sound block=\"play sound %sound=music_sounds\"\n    //% parts=\"headphone\"\n    //% weight=95 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSound(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.play();\n        pause(1);\n    }\n\n\n    /**\n     * Play a sound and wait until the sound is done.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound-until-done\n    //% blockId=music_play_sound_until_done block=\"play sound %sound=music_sounds|until done\"\n    //% parts=\"headphone\"\n    //% weight=94 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSoundUntilDone(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.playUntilDone();\n    }\n}","melody.cpp":"#include \"pxt.h\"\n#include \"SoundOutput.h\"\n#include \"melody.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\nnamespace music {\n\nSINGLETON(WSynthesizer);\n\n// Tone generator arguments:\n//\n// sound: a pointer to the currently-playing sound, usable for looking up the\n// waveform or generator-specific state.\n//\n// position: offset within the currently-playing wave, range 0..1023.\n//\n// cycle: a 6-bit cyclical sequence number of the wave, incremented each time\n// the position loops from 1023 back to 0.\ntypedef int (*gentone_t)(PlayingSound *sound, uint32_t position, uint8_t cycle);\n\nstatic int noiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    // see https://en.wikipedia.org/wiki/Xorshift\n    static uint32_t x = 0xf01ba80;\n    x ^= x << 13;\n    x ^= x >> 17;\n    x ^= x << 5;\n    return (x & 0xffff) - 0x7fff;\n}\n\nstatic int sineTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    int32_t p = position;\n    if (p >= 512) {\n        p -= 512;\n    }\n    if (p > 256) {\n        p = 512 - p;\n    }\n\n    // Approximate sin(x * pi / 2) with the odd polynomial y = cx^5 + bx^3 + ax\n    // using the constraint y(1) = 1 => a = 1 - b - c\n    //   => y = c x^5 + b x^3 + (1 - b - c) * x\n    //\n    // Do a least-squares fit of this to sin(x * pi / 2) in the range 0..1\n    // inclusive, using 21 evenly spaced points. Resulting approximation:\n    //\n    // sin(x*pi/2) ~= 0.0721435357258*x**5 - 0.642443736562*x**3 + 1.57030020084*x\n\n    // Scale the constants by 32767 to match the desired output range.\n    constexpr int32_t c = 0.0721435357258 * 32767;\n    constexpr int32_t b = -0.642443736562 * 32767;\n    constexpr int32_t a = 1.57030020084 * 32767;\n\n    // Calculate using y = ((c * x^2 + b) * x^2 + a) * x\n    //\n    // The position p is x * 256, so after each multiply with p we need to\n    // shift right by 8 bits to keep the decimal point in the same place.  (The\n    // approximation has a negative error near x=1 which helps avoid overflow.)\n    int32_t p2 = p * p;\n    int32_t u = (c * p2 >> 16) + b;\n    int32_t v = (u * p2 >> 16) + a;\n    int32_t w = v * p >> 8;\n\n    // The result is within 7/32767 or 0.02%, signal-to-error ratio about 38 dB.\n    return position >= 512 ? -w : w;\n}\n\nstatic int sawtoothTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return (position << 6) - 0x7fff;\n}\n\nstatic int triangleTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return position < 512 ? (position << 7) - 0x7fff : ((1023 - position) << 7) - 0x7fff;\n}\n\nstatic int squareWaveTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)cycle;\n    uint8_t wave = sound->currInstr->soundWave;\n    return (int)position < (102 * (wave - SW_SQUARE_10 + 1)) ? -0x7fff : 0x7fff;\n}\n\nstatic int tunedNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a random bit sequence. Since the generator\n    // is called multiple times per wave, use PlayingSound state data to ensure we\n    // only generate a random bit once per wave, and then reuse it for future\n    // calls for that wave.\n    //\n    // Use the low 6 bits of generatorState to store the last-used cycle, and\n    // random_bit to store the last on/off state. (random_bit is arbitrary as\n    // long as it isn't one of the low 6 bits.)\n    constexpr uint32_t random_bit = 0x8000;\n    static uint32_t x = 0xf01ba80; // seed for the static RNG state\n    uint8_t prev_cycle = sound->generatorState & 0x3f;\n    uint32_t is_on;\n    if (cycle == prev_cycle) {\n        is_on = sound->generatorState & random_bit;\n    } else {\n        // see https://en.wikipedia.org/wiki/Xorshift\n        x ^= x << 13;\n        x ^= x >> 17;\n        x ^= x << 5;\n        is_on = (x & random_bit);\n        sound->generatorState = (cycle & 0x3f) | is_on;\n    }\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\n// Bit patterns for use by the cyclic noise tone.\n//\n// The bit pattern is arbitrary, but should have equal numbers of 0 and 1 bits,\n// and should avoid long identical-bit runs for the lower parts. The values below\n// were chosen based on a random permutation of the hex nibbles 0..f and then\n// hand-tweaked by swapping some nibbles. Generated by:\n//\n//   shuf -i 0-15 | perl -ne 's/(\\d+)/printf(\"%x\",$1)/e'\nstatic const uint32_t cycle_bits[] = {0x2df0eb47, 0xc8165a93};\nstatic const uint8_t cycle_mask[] = {0xf, 0x1f, 0x3f};\n\nstatic int cycleNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    // The bit sequence repeats every 16/32/64 waves.\n    //\n    // The \"cycle\" argument corresponds to the sequential number of the generated\n    // wave. This is currently a 6-bit value. Since the pseudorandom bit sequences\n    // evenly fit into this, there's no need to track generator state.\n    uint8_t wave = sound->currInstr->soundWave;\n    int cycle_index = wave - SW_SQUARE_CYCLE_16;\n    // CLAMP(0, cycle_index, sizeof cycle_bits / sizeof cycle_bits[0])\n    cycle &= cycle_mask[cycle_index];\n    bool is_on = (cycle_bits[cycle >> 5] & (1U << (cycle & 0x1f)));\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\nstatic int silenceTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    return 0;\n}\n\nstatic gentone_t getWaveFn(uint8_t wave) {\n    switch (wave) {\n    case SW_TRIANGLE:\n        return triangleTone;\n    case SW_SAWTOOTH:\n        return sawtoothTone;\n    case SW_TUNEDNOISE:\n        return tunedNoiseTone;\n    case SW_NOISE:\n        return noiseTone;\n    case SW_SINE:\n        return sineTone;\n    default:\n        if (SW_SQUARE_10 <= wave && wave <= SW_SQUARE_50)\n            return squareWaveTone;\n        if (SW_SQUARE_CYCLE_16 <= wave && wave <= SW_SQUARE_CYCLE_64)\n            return cycleNoiseTone;\n        else\n            return silenceTone;\n    }\n}\n\n#define CLAMP(lo, v, hi) ((v) = ((v) < (lo) ? (lo) : (v) > (hi) ? (hi) : (v)))\n\nint WSynthesizer::updateQueues() {\n    const int maxTime = 0xffffff;\n    while (1) {\n        WaitingSound *p;\n        int minLeft = maxTime;\n        for (p = waiting; p; p = p->next) {\n            int timeLeft =\n                p->state == SoundState::Waiting ? p->startSampleNo - currSample : maxTime;\n            if (timeLeft <= 0) {\n                break;\n            }\n            if (timeLeft < minLeft)\n                minLeft = timeLeft;\n        }\n        if (p) {\n            PlayingSound *snd;\n            int minIdx = -1;\n            for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n                snd = &playingSounds[i];\n                if (snd->sound == NULL)\n                    break;\n                if (minIdx == -1 ||\n                    playingSounds[minIdx].startSampleNo < playingSounds[i].startSampleNo)\n                    minIdx = i;\n                snd = NULL;\n            }\n            // if we didn't find a free slot, expel the oldest sound\n            if (!snd)\n                snd = &playingSounds[minIdx];\n            if (snd->sound)\n                snd->sound->state = SoundState::Done;\n            snd->sound = p;\n            p->state = SoundState::Playing;\n            snd->startSampleNo = currSample;\n            snd->currInstr = (SoundInstruction *)p->instructions->data;\n            snd->instrEnd = snd->currInstr + p->instructions->length / sizeof(SoundInstruction);\n            snd->prevVolume = -1;\n        } else {\n            // no more sounds to move\n            return minLeft;\n        }\n    }\n}\n\nint WSynthesizer::fillSamples(int16_t *dst, int numsamples) {\n    if (numsamples <= 0)\n        return 1;\n\n    int timeLeft = updateQueues();\n    int res = waiting != NULL;\n\n    // if there's a pending sound to be started somewhere during numsamples,\n    // split the call into two\n    if (timeLeft < numsamples) {\n        fillSamples(dst, timeLeft);\n        LOG(\"M split %d\", timeLeft);\n        fillSamples(dst + timeLeft, numsamples - timeLeft);\n        return 1;\n    }\n\n    memset(dst, 0, numsamples * 2);\n\n    uint32_t samplesPerMS = (sampleRate << 8) / 1000;\n    float toneStepMult = (1024.0 * (1 << 16)) / sampleRate;\n    const int MAXVAL = (1 << (OUTPUT_BITS - 1)) - 1;\n\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        PlayingSound *snd = &playingSounds[i];\n        if (snd->sound == NULL)\n            continue;\n\n        res = 1;\n\n        SoundInstruction *instr = NULL;\n        gentone_t fn = NULL;\n        snd->currInstr--;\n        uint32_t toneStep = 0;\n        int32_t toneDelta = 0;\n        int32_t volumeStep = 0;\n        uint32_t tonePosition = snd->tonePosition;\n        uint32_t samplesLeft = 0;\n        uint8_t wave = 0;\n        int32_t volume = 0;\n\n        for (int j = 0; j < numsamples; ++j) {\n            if (samplesLeft == 0) {\n                snd->currInstr++;\n                if (snd->currInstr >= snd->instrEnd) {\n                    break;\n                }\n                SoundInstruction copy = *snd->currInstr;\n                instr = &copy;\n                CLAMP(20, instr->frequency, 20000);\n                CLAMP(20, instr->endFrequency, 20000);\n                CLAMP(0, instr->startVolume, 1023);\n                CLAMP(0, instr->endVolume, 1023);\n                CLAMP(1, instr->duration, 60000);\n\n                wave = instr->soundWave;\n                fn = getWaveFn(wave);\n\n                samplesLeft = (uint32_t)(instr->duration * samplesPerMS >> 8);\n                // make sure the division is signed\n                volumeStep =\n                    (int)((instr->endVolume - instr->startVolume) << 16) / (int)samplesLeft;\n\n                if (j == 0 && snd->prevVolume != -1) {\n                    // restore previous state\n                    samplesLeft = snd->samplesLeftInCurr;\n                    volume = snd->prevVolume;\n                    toneStep = snd->prevToneStep;\n                    toneDelta = snd->prevToneDelta;\n                } else {\n                    LOG(\"#sampl %d %p\", samplesLeft, snd->currInstr);\n                    volume = instr->startVolume << 16;\n                    LOG(\"%d-%dHz %d-%d vol\", instr->frequency, instr->endFrequency,\n                        instr->startVolume, instr->endVolume);\n                    toneStep = (uint32_t)(toneStepMult * instr->frequency);\n                    if (instr->frequency != instr->endFrequency) {\n                        uint32_t endToneStep = (uint32_t)(toneStepMult * instr->endFrequency);\n                        toneDelta = (int32_t)(endToneStep - toneStep) / (int32_t)samplesLeft;\n                    } else {\n                        toneDelta = 0;\n                    }\n                }\n            }\n\n            int v = fn(snd, (tonePosition >> 16) & 1023, tonePosition >> 26);\n            v = (v * (volume >> 16)) >> (10 + (16 - OUTPUT_BITS));\n\n            // if (v > MAXVAL)\n            //    target_panic(123);\n\n            dst[j] += v;\n\n            tonePosition += toneStep;\n            toneStep += toneDelta;\n            volume += volumeStep;\n            samplesLeft--;\n        }\n\n        if (snd->currInstr >= snd->instrEnd) {\n            snd->sound->state = SoundState::Done;\n            snd->sound = NULL;\n        } else {\n            snd->tonePosition = tonePosition;\n            if (samplesLeft == 0)\n                samplesLeft++; // avoid infinite loop in next iteration\n            snd->samplesLeftInCurr = samplesLeft;\n            snd->prevVolume = volume;\n            snd->prevToneDelta = toneDelta;\n            snd->prevToneStep = toneStep;\n        }\n    }\n\n    currSample += numsamples;\n\n    for (int j = 0; j < numsamples; ++j) {\n        if (dst[j] > MAXVAL)\n            dst[j] = MAXVAL;\n        else if (dst[j] < -MAXVAL)\n            dst[j] = -MAXVAL;\n    }\n\n    return res;\n}\n\n//%\nvoid enableAmp(int enabled) {\n    // this is also compiled on linux\n#ifdef LOOKUP_PIN\n    auto pin = LOOKUP_PIN(SPEAKER_AMP);\n    if (pin) {\n        if (PIN(SPEAKER_AMP) & CFG_PIN_CONFIG_ACTIVE_LO)\n            enabled = !enabled;\n        pin->setDigitalValue(enabled);\n    }\n#endif\n}\n\n//%\nvoid forceOutput(int outp) {\n    auto snd = getWSynthesizer();\n    snd->out.setOutput(outp);\n}\n\n//%\nvoid queuePlayInstructions(int when, Buffer buf) {\n    auto snd = getWSynthesizer();\n\n    registerGCObj(buf);\n\n    auto p = new WaitingSound;\n    p->state = SoundState::Waiting;\n    p->instructions = buf;\n    p->startSampleNo = snd->currSample + when * snd->sampleRate / 1000;\n\n    LOG(\"Queue %dms now=%d off=%d %p sampl:%dHz\", when, snd->currSample,\n        p->startSampleNo - snd->currSample, buf->data, snd->sampleRate);\n\n    target_disable_irq();\n    // add new sound to queue\n    p->next = snd->waiting;\n    snd->waiting = p;\n    // remove sounds that have already been fully played\n    while (p) {\n        while (p->next && p->next->state == SoundState::Done) {\n            auto todel = p->next;\n            p->next = todel->next;\n            unregisterGCObj(todel->instructions);\n            delete todel;\n        }\n        p = p->next;\n    }\n    target_enable_irq();\n\n    snd->poke();\n}\n\n//%\nvoid stopPlaying() {\n    LOG(\"stop playing!\");\n\n    auto snd = getWSynthesizer();\n\n    target_disable_irq();\n    auto p = snd->waiting;\n    snd->waiting = NULL;\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        snd->playingSounds[i].sound = NULL;\n    }\n    while (p) {\n        auto n = p->next;\n        unregisterGCObj(p->instructions);\n        delete p;\n        p = n;\n    }\n    target_enable_irq();\n}\n\nWSynthesizer::WSynthesizer() : upstream(NULL), out(*this) {\n    currSample = 0;\n    active = false;\n    sampleRate = out.dac.getSampleRate();\n    memset(&playingSounds, 0, sizeof(playingSounds));\n    waiting = NULL;\n    PXT_REGISTER_RESET(stopPlaying);\n}\n\n//% promise\nint _createSequencer() {\n    return 0;\n}\n\n//%\nString _sequencerState(int id) {\n    return NULL;\n}\n\n//%\nint _sequencerCurrentTick(int id) {\n    return 0;\n}\n\n//%\nvoid _sequencerPlaySong(int id, Buffer buf, bool loop) {\n}\n\n//%\nvoid _sequencerStop(int id) {\n}\n\n//%\nvoid _sequencerSetVolume(int id, int volume) {\n}\n\n//%\nvoid _sequencerSetVolumeForAll(int volume) {\n}\n\n//%\nvoid _sequencerSetTrackVolume(int id, int trackIndex, int volume) {\n}\n\n//%\nvoid _sequencerSetDrumTrackVolume(int id, int trackIndex, int drumIndex, int volume) {\n}\n\n//%\nvoid _sequencerDispose(int id) {\n}\n\n} // namespace music\n\nnamespace pxt {\nint redirectSamples(int16_t *dst, int numsamples, int samplerate) {\n    auto snd = music::getWSynthesizer();\n    snd->upstream = NULL; // disconnect from regular playback mechanism\n    snd->sampleRate = samplerate;\n    return snd->fillSamples(dst, numsamples);\n}\n\n} // namespace pxt\n\nnamespace jacdac {\n__attribute__((weak)) void setJackRouterOutput(int output) {}\n} // namespace jacdac\n","melody.h":"#pragma once\n\n#ifndef OUTPUT_BITS\n#define OUTPUT_BITS 10\n#endif\n\n#define SW_TRIANGLE 1\n#define SW_SAWTOOTH 2\n#define SW_SINE 3\n#define SW_TUNEDNOISE 4\n#define SW_NOISE 5\n#define SW_SQUARE_10 11\n#define SW_SQUARE_50 15\n#define SW_SQUARE_CYCLE_16 16\n#define SW_SQUARE_CYCLE_32 17\n#define SW_SQUARE_CYCLE_64 18\n\nstruct SoundInstruction {\n    uint8_t soundWave;\n    uint8_t flags;\n    uint16_t frequency;    // Hz\n    uint16_t duration;     // ms\n    int16_t startVolume;   // 0-1023\n    int16_t endVolume;     // 0-1023\n    uint16_t endFrequency; // Hz\n};\n\n#ifdef DATASTREAM_MAXIMUM_BUFFERS\n#define CODAL 1\n#endif\n\nnamespace music {\n\n#define MAX_SOUNDS 8\n\nSTATIC_ASSERT((1 << (16 - OUTPUT_BITS)) > MAX_SOUNDS);\n\nenum class SoundState : uint8_t {\n    Waiting, //\n    Playing, //\n    Done     //\n};\n\nstruct WaitingSound {\n    uint32_t startSampleNo;\n    SoundState state;\n    WaitingSound *next;\n    Buffer instructions;\n};\n\nstruct PlayingSound {\n    uint32_t startSampleNo;\n    uint32_t samplesLeftInCurr;\n    uint32_t tonePosition;\n    int32_t prevVolume;\n    uint32_t prevToneStep;\n    int32_t prevToneDelta;\n    uint32_t generatorState;\n    WaitingSound *sound;\n    SoundInstruction *currInstr, *instrEnd;\n};\n\nclass WSynthesizer\n#ifdef CODAL\n    : public DataSource\n#endif\n{\n  public:\n#ifdef CODAL\n    DataSink *upstream;\n#else\n    void *upstream;\n#endif\n    uint32_t currSample; // after 25h of playing we might get a glitch\n    int32_t sampleRate;  // eg 44100\n    PlayingSound playingSounds[MAX_SOUNDS];\n    WaitingSound *waiting;\n    bool active;\n\n    SoundOutput out;\n\n    int fillSamples(int16_t *dst, int numsamples);\n    int updateQueues();\n\n    WSynthesizer();\n    virtual ~WSynthesizer() {}\n\n    void pokeUpstream() {\n#ifdef CODAL\n        if (upstream) {\n            upstream->pullRequest();\n        }\n#endif\n    }\n\n    void poke() {\n        if (!active) {\n            active = true;\n            pokeUpstream();\n        }\n    }\n\n#ifdef CODAL\n    virtual ManagedBuffer pull() {\n        if (!upstream)\n            return ManagedBuffer();\n        ManagedBuffer data(512);\n        auto dp = (int16_t *)data.getBytes();\n        auto sz = 512 / 2;\n        int r = fillSamples(dp, sz);\n#if defined(NRF52_SERIES)\n        int mul = out.dac.getSampleRange();\n#endif\n        while (sz--) {\n#if defined(NRF52_SERIES)\n            *dp = ((-*dp + (1 << (OUTPUT_BITS - 1))) * mul) >> OUTPUT_BITS;\n#else\n            *dp += 1 << (OUTPUT_BITS - 1);\n#endif\n            dp++;\n        }\n        if (!r) {\n            active = false;\n            // return empty - nothing left to play\n            return ManagedBuffer();\n        }\n        pokeUpstream();\n        return data;\n    }\n    virtual void connect(DataSink &sink) { upstream = &sink; }\n#endif\n};\n\n} // namespace music\n","melody.ts":"enum MusicOutput {\n    AutoDetect = 0,\n    Buzzer = 1,\n    HeadPhones = 2,\n}\n\nnamespace music {\n    //% whenUsed\n    const freqs = hex`\n        1f00210023002500270029002c002e003100340037003a003e004100450049004e00520057005c00620068006e00\n        75007b0083008b0093009c00a500af00b900c400d000dc00e900f70006011501260137014a015d01720188019f01\n        b801d201ee010b022a024b026e029302ba02e40210033f037003a403dc03170455049704dd0427057505c8052006\n        7d06e0064907b8072d08a9082d09b9094d0aea0a900b400cfa0cc00d910e6f0f5a1053115b1272139a14d4152017\n        8018f519801b231dde1e`\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n\n    //% shim=music::stopPlaying\n    function stopPlaying() { }\n\n    //% shim=music::forceOutput\n    export function forceOutput(buf: MusicOutput) { }\n\n    let globalVolume: number = null\n\n    const BUFFER_SIZE: number = 12;\n\n    //% shim=music::enableAmp\n    function enableAmp(en: number) {\n        return // for sim\n    }\n\n    function initVolume() {\n        if (globalVolume === null) {\n            globalVolume = 0\n            setVolume(control.getConfigValue(DAL.CFG_SPEAKER_VOLUME, 128))\n        }\n    }\n\n    /**\n     * Set the default output volume of the sound synthesizer.\n     * @param volume the volume 0...255\n     */\n    //% blockId=synth_set_volume block=\"set volume %volume\"\n    //% parts=\"speaker\"\n    //% volume.min=0 volume.max=255\n    //% volume.defl=20\n    //% help=music/set-volume\n    //% weight=70\n    //% group=\"Volume\"\n    export function setVolume(volume: number): void {\n        globalVolume = Math.clamp(0, 255, volume | 0)\n        enableAmp(globalVolume > 0 ? 1 : 0)\n    }\n\n    /**\n     * Gets the current volume\n     */\n    //% parts=\"speaker\"\n    //% weight=70\n    export function volume(): number {\n        initVolume()\n        return globalVolume;\n    }\n\n    function playNoteCore(when: number, frequency: number, ms: number) {\n        let buf = control.createBuffer(BUFFER_SIZE)\n        addNote(buf, 0, ms, 255, 255, 3, frequency, volume(), frequency)\n        queuePlayInstructions(when, buf)\n    }\n\n    /**\n     * Play a tone through the speaker for some amount of time.\n     * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n     * @param ms tone duration in milliseconds (ms), eg: BeatFraction.Half\n     */\n    //% help=music/play-tone\n    //% blockId=mixer_play_note block=\"play tone|at %note=device_note|for %duration=device_beat\"\n    //% parts=\"headphone\" async\n    //% blockNamespace=music\n    //% weight=76 blockGap=8\n    //% group=\"Tone\"\n    //% deprecated=1\n    export function playTone(frequency: number, ms: number): void {\n        if (ms == 0)\n            ms = 86400000 // 1 day\n\n        if (ms <= 2000) {\n            playNoteCore(0, frequency, ms)\n            pause(ms)\n        } else {\n            const id = ++playToneID\n            control.runInParallel(() => {\n                let pos = control.millis()\n                while (id == playToneID && ms > 0) {\n                    let now = control.millis()\n                    let d = pos - now\n                    let t = Math.min(ms, 500)\n                    ms -= t\n                    pos += t\n                    playNoteCore(d - 1, frequency, t)\n                    if (ms == 0)\n                        pause(d + t)\n                    else\n                        pause(d + t - 100)\n                }\n            })\n        }\n    }\n\n    let playToneID = 0\n\n    /**\n     * Play a melody from the melody editor.\n     * @param melody - string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces,\n     * which will be played one at a time, ex: \"E D G F B A C5 B \"\n     * @param tempo - number in beats per minute (bpm), dictating how long each note will play for\n     */\n    //% block=\"play melody $melody at tempo $tempo|(bpm)\" blockId=playMelody\n    //% blockNamespace=music\n    //% weight=85 blockGap=8 help=music/play-melody\n    //% group=\"Melody\"\n    //% melody.shadow=\"melody_editor\"\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% deprecated=1\n    export function playMelody(melody: string, tempo: number) {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        const song = new Melody(formattedMelody);\n        song.playUntilDone();\n    }\n\n\n    /**\n     * Create a melody with the melody editor.\n     * @param melody\n     */\n    //% block=\"$melody\" blockId=melody_editor\n    //% blockNamespace=music\n    //% blockHidden = true\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Melody\" duplicateShadowOnDrag\n    //% melody.fieldEditor=\"melody\"\n    //% melody.fieldOptions.decompileLiterals=true\n    //% melody.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% melody.fieldOptions.onParentBlock=\"true\"\n    //% shim=TD_ID\n    export function melodyEditor(melody: string): string {\n        return melody;\n    }\n\n    /**\n     * Stop all sounds from playing.\n     */\n    //% help=music/stop-all-sounds\n    //% blockId=music_stop_all_sounds block=\"stop all sounds\"\n    //% weight=45\n    //% group=\"Sounds\"\n    export function stopAllSounds() {\n        Melody.stopAll();\n        stopPlaying();\n        _stopPlayables();\n        sequencer._stopAllSongs();\n    }\n\n    //% fixedInstances\n    export class Melody {\n        _text: string;\n        private _player: MelodyPlayer;\n\n        private static playingMelodies: Melody[];\n\n        static stopAll() {\n            if (Melody.playingMelodies) {\n                const ms = Melody.playingMelodies.slice(0, Melody.playingMelodies.length);\n                ms.forEach(p => p.stop());\n            }\n        }\n\n        constructor(text: string) {\n            this._text = text\n        }\n\n        get text() {\n            return this._text;\n        }\n\n        /**\n         * Stop playing a sound\n         */\n        //% blockId=mixer_stop block=\"stop sound %sound\"\n        //% help=music/melody/stop\n        //% parts=\"headphone\"\n        //% weight=92 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        stop() {\n            if (this._player) {\n                this._player.stop()\n                this._player = null\n            }\n            this.unregisterMelody();\n        }\n\n        private registerMelody() {\n            // keep track of the active players\n            if (!Melody.playingMelodies) Melody.playingMelodies = [];\n            // stop and pop melodies if too many playing\n            if (Melody.playingMelodies.length > 4) {\n                // stop last player (also pops)\n                Melody.playingMelodies[Melody.playingMelodies.length - 1].stop();\n            }\n            // put back the melody on top of the melody stack\n            Melody.playingMelodies.removeElement(this);\n            Melody.playingMelodies.push(this);\n        }\n        private unregisterMelody() {\n            // remove from list\n            if (Melody.playingMelodies) {\n                Melody.playingMelodies.removeElement(this); // remove self\n            }\n        }\n\n        private playCore(volume: number, loop: boolean) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this.registerMelody();\n            control.runInParallel(() => {\n                while (this._player == p) {\n                    p.play(volume)\n                    if (!loop) {\n                        // Unregister the melody when done playing, but\n                        // only if it hasn't been restarted. (Looping\n                        // melodies never stop on their own, they only\n                        // get unregistered via stop().)\n                        if (this._player == p) {\n                            this.unregisterMelody();\n                        }\n                        break\n                    }\n                }\n            })\n        }\n\n        /**\n         * Start playing a sound in a loop and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/loop\n        //% blockId=mixer_loop_sound block=\"loop sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=93 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        loop(volume = 255) {\n            this.playCore(volume, true)\n        }\n\n        /**\n         * Start playing a sound and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play\n        //% blockId=mixer_play_sound block=\"play sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=95 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        play(volume = 255) {\n            this.playCore(volume, false)\n        }\n\n\n        /**\n         * Play a sound and wait until the sound is done.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play-until-done\n        //% blockId=mixer_play_sound_until_done block=\"play sound %sound|until done\"\n        //% parts=\"headphone\"\n        //% weight=94 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        playUntilDone(volume = 255) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this._player.onPlayFinished = () => {\n                if (p == this._player)\n                    this.unregisterMelody();\n            }\n            this.registerMelody();\n            this._player.play(volume)\n        }\n\n        toString() {\n            return this._text;\n        }\n    }\n\n    export function addNote(sndInstr: Buffer, sndInstrPtr: number, ms: number, beg: number, end: number, soundWave: number, hz: number, volume: number, endHz: number) {\n        if (ms > 0) {\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, soundWave)\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr + 1, 0)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 2, hz)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 4, ms)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 6, (beg * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 8, (end * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 10, endHz);\n            sndInstrPtr += BUFFER_SIZE;\n        }\n        sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, 0) // terminate\n        return sndInstrPtr\n    }\n\n\n    export class MelodyPlayer {\n        melody: Melody;\n\n        onPlayFinished: () => void;\n\n        constructor(m: Melody) {\n            this.melody = m\n        }\n\n        stop() {\n            this.melody = null\n        }\n\n        protected queuePlayInstructions(timeDelta: number, buf: Buffer) {\n            queuePlayInstructions(timeDelta, buf)\n        }\n\n        play(volume: number) {\n            if (!this.melody)\n                return\n            volume = Math.clamp(0, 255, (volume * music.volume()) >> 8)\n\n            let notes = this.melody._text\n            let pos = 0;\n            let duration = 4; //Default duration (Crotchet)\n            let octave = 4; //Middle octave\n            let tempo = 120; // default tempo\n\n            let hz = 0\n            let endHz = -1\n            let ms = 0\n            let timePos = 0\n            let startTime = control.millis()\n            let now = 0\n\n            let envA = 0\n            let envD = 0\n            let envS = 255\n            let envR = 0\n            let soundWave = 1 // triangle\n            let sndInstr = control.createBuffer(5 * BUFFER_SIZE)\n            let sndInstrPtr = 0\n\n            const addForm = (formDuration: number, beg: number, end: number, msOff: number) => {\n                let freqStart = hz;\n                let freqEnd = endHz;\n\n                const envelopeWidth = ms > 0 ? ms : duration * Math.idiv(15000, tempo) + envR;\n                if (endHz != hz && envelopeWidth != 0) {\n                    const slope = (freqEnd - freqStart) / envelopeWidth;\n                    freqStart = hz + slope * msOff;\n                    freqEnd = hz + slope * (msOff + formDuration);\n                }\n                sndInstrPtr = addNote(sndInstr, sndInstrPtr, formDuration, beg, end, soundWave, freqStart, volume, freqEnd);\n            }\n\n            const scanNextWord = () => {\n                if (!this.melody)\n                    return \"\"\n\n                // eat space\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c != ' ' && c != '\\r' && c != '\\n' && c != '\\t')\n                        break;\n                    pos++;\n                }\n\n                // read note\n                let note = \"\";\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c == ' ' || c == '\\r' || c == '\\n' || c == '\\t')\n                        break;\n                    note += c;\n                    pos++;\n                }\n                return note;\n            }\n\n            enum Token {\n                Note,\n                Octave,\n                Beat,\n                Tempo,\n                Hz,\n                EndHz,\n                Ms,\n                WaveForm,\n                EnvelopeA,\n                EnvelopeD,\n                EnvelopeS,\n                EnvelopeR\n            }\n\n            let token: string = \"\";\n            let tokenKind = Token.Note;\n\n            // [ABCDEFG] (\\d+)  (:\\d+)  (-\\d+)\n            // note      octave length  tempo\n            // R (:\\d+) - rest\n            // !\\d+,\\d+ - sound at frequency with given length (Hz,ms); !\\d+ and !\\d+,:\\d+ also possible\n            // @\\d+,\\d+,\\d+,\\d+ - ADSR envelope - ms,ms,volume,ms; volume is 0-255\n            // ~\\d+ - wave form:\n            //   1 - triangle\n            //   2 - sawtooth\n            //   3 - sine\n            //   4 - pseudorandom square wave noise (tunable)\n            //   5 - white noise (ignores frequency)\n            //   11 - square 10%\n            //   12 - square 20%\n            //   ...\n            //   15 - square 50%\n            //   16 - filtered square wave, cycle length 16\n            //   17 - filtered square wave, cycle length 32\n            //   18 - filtered square wave, cycle length 64\n\n            const consumeToken = () => {\n                if (token && tokenKind != Token.Note) {\n                    const d = parseInt(token);\n                    switch (tokenKind) {\n                        case Token.Octave: octave = d; break;\n                        case Token.Beat:\n                            duration = Math.max(1, Math.min(16, d));\n                            ms = -1;\n                            break;\n                        case Token.Tempo: tempo = Math.max(1, d); break;\n                        case Token.Hz: hz = d; tokenKind = Token.Ms; break;\n                        case Token.Ms: ms = d; break;\n                        case Token.WaveForm: soundWave = Math.clamp(1, 18, d); break;\n                        case Token.EnvelopeA: envA = d; tokenKind = Token.EnvelopeD; break;\n                        case Token.EnvelopeD: envD = d; tokenKind = Token.EnvelopeS; break;\n                        case Token.EnvelopeS: envS = Math.clamp(0, 255, d); tokenKind = Token.EnvelopeR; break;\n                        case Token.EnvelopeR: envR = d; break;\n                        case Token.EndHz: endHz = d; break;\n                    }\n                    token = \"\";\n                }\n            }\n\n            while (true) {\n                let currNote = scanNextWord();\n                let prevNote: boolean = false;\n                if (!currNote) {\n                    let timeLeft = timePos - now\n                    if (timeLeft > 0)\n                        pause(timeLeft)\n                    if (this.onPlayFinished)\n                        this.onPlayFinished();\n                    return;\n                }\n\n                hz = -1;\n\n                let note: number = 0;\n                token = \"\";\n                tokenKind = Token.Note;\n\n                for (let i = 0; i < currNote.length; i++) {\n                    let noteChar = currNote.charAt(i);\n                    switch (noteChar) {\n                        case 'c': case 'C': note = 1; prevNote = true; break;\n                        case 'd': case 'D': note = 3; prevNote = true; break;\n                        case 'e': case 'E': note = 5; prevNote = true; break;\n                        case 'f': case 'F': note = 6; prevNote = true; break;\n                        case 'g': case 'G': note = 8; prevNote = true; break;\n                        case 'a': case 'A': note = 10; prevNote = true; break;\n                        case 'B': note = 12; prevNote = true; break;\n                        case 'r': case 'R': hz = 0; prevNote = false; break;\n                        case '#': note++; prevNote = false; break;\n                        case 'b': if (prevNote) note--; else { note = 12; prevNote = true; } break;\n                        case ',':\n                            consumeToken();\n                            prevNote = false;\n                            break;\n                        case '!':\n                            tokenKind = Token.Hz;\n                            prevNote = false;\n                            break;\n                        case '@':\n                            consumeToken();\n                            tokenKind = Token.EnvelopeA;\n                            prevNote = false;\n                            break;\n                        case '~':\n                            consumeToken();\n                            tokenKind = Token.WaveForm;\n                            prevNote = false;\n                            break;\n                        case ':':\n                            consumeToken();\n                            tokenKind = Token.Beat;\n                            prevNote = false;\n                            break;\n                        case '-':\n                            consumeToken();\n                            tokenKind = Token.Tempo;\n                            prevNote = false;\n                            break;\n                        case '^':\n                            consumeToken();\n                            tokenKind = Token.EndHz;\n                            break;\n                        default:\n                            if (tokenKind == Token.Note)\n                                tokenKind = Token.Octave;\n                            token += noteChar;\n                            prevNote = false;\n                            break;\n                    }\n                }\n                consumeToken();\n\n                if (note && hz < 0) {\n                    const keyNumber = note + (12 * (octave - 1));\n                    hz = freqs.getNumber(NumberFormat.UInt16LE, keyNumber * 2) || 0;\n                }\n\n                let currMs = ms\n\n                if (currMs <= 0) {\n                    const beat = Math.idiv(15000, tempo);\n                    currMs = duration * beat\n                }\n\n                if (hz < 0) {\n                    // no frequency specified, so no duration\n                } else if (hz == 0) {\n                    timePos += currMs\n                } else {\n                    if (endHz < 0) {\n                        endHz = hz;\n                    }\n\n                    sndInstrPtr = 0\n                    addForm(envA, 0, 255, 0)\n                    addForm(envD, 255, envS, envA)\n                    addForm(currMs - (envA + envD), envS, envS, envD + envA)\n                    addForm(envR, envS, 0, currMs)\n\n                    this.queuePlayInstructions(timePos - now, sndInstr.slice(0, sndInstrPtr))\n                    endHz = -1;\n                    timePos += currMs // don't add envR - it's supposed overlap next sound\n                }\n\n                let timeLeft = timePos - now\n                if (timeLeft > 200) {\n                    pause(timeLeft - 100)\n                    now = control.millis() - startTime\n                }\n            }\n        }\n    }\n\n    //% blockId=music_song_field_editor\n    //% block=\"song $song\"\n    //% song.fieldEditor=musiceditor\n    //% song.fieldOptions.decompileLiterals=true\n    //% song.fieldOptions.taggedTemplate=\"hex;assets.song\"\n    //% song.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% song.fieldOptions.decompileArgumentAsString=\"true\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% help=music/create-song\n    export function createSong(song: Buffer): Playable {\n        return new sequencer.Song(song);\n    }\n\n    export function playInstructions(when: number, instructions: Buffer) {\n        queuePlayInstructions(when, instructions);\n    }\n\n    export function lookupFrequency(note: number) {\n        return freqs.getNumber(NumberFormat.UInt16LE, note * 2) || 0\n    }\n\n    //% fixedInstance whenUsed block=\"ba ding\"\n    export const baDing = new Melody('b5:1 e6:3')\n\n    //% fixedInstance whenUsed block=\"wawawawaa\"\n    export const wawawawaa = new Melody('~15 e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8')\n\n    //% fixedInstance whenUsed block=\"jump up\"\n    export const jumpUp = new Melody('c5:1 d e f g')\n\n    //% fixedInstance whenUsed block=\"jump down\"\n    export const jumpDown = new Melody('g5:1 f e d c')\n\n    //% fixedInstance whenUsed block=\"power up\"\n    export const powerUp = new Melody('g4:1 c5 e g:2 e:1 g:3')\n\n    //% fixedInstance whenUsed block=\"power down\"\n    export const powerDown = new Melody('g5:1 d# c g4:2 b:1 c5:3')\n\n    //% fixedInstance whenUsed block=\"magic wand\"\n    export const magicWand = new Melody('F#6:1-300 G# A# B C7# D# F F# G# A# B:6')\n    //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n\n    //% fixedInstance whenUsed block=\"siren\"\n    export const siren = new Melody('a4 d5 a4 d5 a4 d5')\n\n    //% fixedInstance whenUsed block=\"pew pew\"\n    export const pewPew = new Melody('!1200,200^50')\n\n    //% fixedInstance whenUsed block=\"knock\"\n    export const knock = new Melody('~4 @0,0,255,150 !300,1 !211,1')\n\n    //% fixedInstance whenUsed block=\"footstep\"\n    export const footstep = new Melody('~4 @0,0,60,50 !200,1')\n\n    //% fixedInstance whenUsed block=\"thump\"\n    export const thump = new Melody('~4 @0,0,255,150 !100,1')\n\n    //% fixedInstance whenUsed block=\"small crash\"\n    export const smallCrash = new Melody('~4 @10,490,0,1 !800,1')\n\n    //% fixedInstance whenUsed block=\"big crash\"\n    export const bigCrash = new Melody('~4 @10,990,0,1 !400,1')\n\n    //% fixedInstance whenUsed block=\"zapped\"\n    export const zapped = new Melody('~16 @10,490,0,0 !1600,500^1')\n\n    //% fixedInstance whenUsed block=\"buzzer\"\n    export const buzzer = new Melody('~16 @10,0,255,250 !2000,300')\n\n    //% fixedInstance whenUsed block=\"sonar\"\n    export const sonar = new Melody('~16 @10,1500,0,0 !200,1 !200,1500^190')\n\n    //% fixedInstance whenUsed block=\"spooky\"\n    export const spooky = new Melody('~16 @700,1300,0,0 !100,1 ~18 !108,2000')\n\n    //% fixedInstance whenUsed block=\"beam up\"\n    export const beamUp = new Melody('~18 @10,1500,0,0 !200,1500^4000')\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    //% block=\"2\"\n    Double = 32,\n    //% block=\"4\",\n    Breve = 64,\n    //% block=\"1/3\",\n    Triplet = 128\n}\n\nnamespace music {\n\n    let beatsPerMinute: number;\n\n    /**\n    * Play a tone.\n    * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n    */\n    //% help=music/ring-tone\n    //% blockId=music_ring block=\"ring tone|at %note=device_note\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music inBasicCategory=true\n    //% weight=75 blockGap=8\n    //% group=\"Tone\"\n    export function ringTone(frequency: number) {\n        playTone(frequency, 0);\n    }\n\n    /**\n    * Rest, or play silence, for some time (in milliseconds).\n    * @param ms rest duration in milliseconds (ms), eg: BeatFraction.Half\n    */\n    //% help=music/rest\n    //% blockId=music_rest block=\"rest|for %duration=device_beat\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music\n    //% weight=74\n    //% group=\"Tone\"\n    export function rest(ms: number) {\n        playTone(0, Math.max(ms, 20));\n    }\n\n    function init() {\n        if (!beatsPerMinute) beatsPerMinute = 120;\n    }\n\n    /**\n     * Return the duration of a beat in milliseconds (the beat fraction).\n     * @param fraction the fraction of the current whole note, eg: BeatFraction.Half\n     */\n    //% help=music/beat\n    //% blockId=device_beat block=\"%fraction|beat\"\n    //% weight=9 blockGap=8\n    //% group=\"Tempo\"\n    export function beat(fraction?: BeatFraction): number {\n        init();\n        if (fraction == null) fraction = BeatFraction.Whole;\n        let beat = 60000 / beatsPerMinute;\n        switch (fraction) {\n            case BeatFraction.Half: beat /= 2; break;\n            case BeatFraction.Quarter: beat /= 4; break;\n            case BeatFraction.Eighth: beat /= 8; break;\n            case BeatFraction.Sixteenth: beat /= 16; break;\n            case BeatFraction.Double: beat *= 2; break;\n            case BeatFraction.Breve: beat *= 4; break;\n            case BeatFraction.Triplet: beat /= 3; break;\n        }\n        return beat >> 0;\n    }\n\n    /**\n     * Return the tempo in beats per minute (bpm).\n     * 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\n    //% blockId=device_tempo block=\"tempo (bpm)\"\n    //% weight=64\n    //% group=\"Tempo\"\n    export function tempo(): number {\n        init();\n        return beatsPerMinute;\n    }\n\n    /**\n     * Change the tempo up or down by some amount of beats per minute (bpm).\n     * @param bpm The change in beats per minute to the tempo, eg: 20\n     */\n    //% help=music/change-tempo-by weight=37\n    //% blockId=device_change_tempo block=\"change tempo by %value|(bpm)\"\n    //% weight=66 blockGap=8\n    //% group=\"Tempo\"\n    export function changeTempoBy(bpm: number): void {\n        init();\n        setTempo(beatsPerMinute + bpm);\n    }\n\n    /**\n     * Set the tempo a number of beats per minute (bpm).\n     * @param bpm The new tempo in beats per minute, eg: 120\n     */\n    //% help=music/set-tempo\n    //% blockId=device_set_tempo block=\"set tempo to %value|(bpm)\"\n    //% bpm.min=4 bpm.max=400\n    //% weight=65 blockGap=8\n    //% group=\"Tempo\"\n    export function setTempo(bpm: number): void {\n        init();\n        if (bpm > 0) {\n            beatsPerMinute = Math.max(1, bpm >> 0);\n        }\n    }\n}\n","ns.ts":"\n/**\n * Generation of music tones.\n */\n//% color=#E30FC0 weight=90 icon=\"\\uf025\"\n//% blockGap=8\n//% groups='[\"Songs\", \"Sounds\", \"Tone\",  \"Volume\", \"Tempo\"]'\nnamespace music {\n}","piano.ts":"namespace music {\n    /**\n     * Get the frequency of a note.\n     * @param name the note name, eg: Note.C\n     */\n    //% weight=1 help=music/note-frequency\n    //% blockId=device_note block=\"%note\"\n    //% shim=TD_ID\n    //% color=\"#FFFFFF\" colorSecondary=\"#FFFFFF\" colorTertiary=\"#D83B01\"\n    //% note.fieldEditor=\"note\" note.defl=\"262\"\n    //% note.fieldOptions.decompileLiterals=true\n    //% useEnumVal=1\n    //% weight=10 blockGap=8\n    //% group=\"Tone\"\n    export function noteFrequency(name: Note): number {\n        return name;\n    }\n}","playable.ts":"namespace music {\n    export enum PlaybackMode {\n        //% block=\"until done\"\n        UntilDone,\n        //% block=\"in background\"\n        InBackground,\n        //% block=\"looping in background\"\n        LoopingInBackground\n    }\n\n    let stateStack: PlayableState[];\n\n    class PlayableState {\n        looping: Playable[];\n        constructor() {\n            this.looping = [];\n        }\n\n        stopLooping() {\n            for (const p of this.looping) {\n                p.stopped = true;\n            }\n            this.looping = [];\n        }\n    }\n\n    function state() {\n        _init();\n        return stateStack[stateStack.length - 1];\n    }\n\n    function _init() {\n        if (stateStack) return;\n        stateStack = [new PlayableState()];\n\n        game.addScenePushHandler(() => {\n            stateStack.push(new PlayableState());\n        });\n\n        game.addScenePopHandler(() => {\n            stateStack.pop();\n            if (stateStack.length === 0) stateStack.push(new PlayableState());\n        });\n    }\n\n    export class Playable {\n        stopped: boolean;\n        constructor() {\n\n        }\n\n        play(playbackMode: PlaybackMode) {\n            // subclass\n        }\n\n        loop() {\n            state().looping.push(this);\n            this.stopped = false;\n\n            control.runInParallel(() => {\n                while (!this.stopped) {\n                    this.play(PlaybackMode.UntilDone);\n                }\n            });\n        }\n    }\n\n    export class MelodyPlayable extends Playable {\n        constructor(public melody: Melody) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                this.melody.play(music.volume());\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                this.melody.playUntilDone(music.volume());\n            }\n            else {\n                this.melody.loop(music.volume());\n            }\n        }\n    }\n\n    export class TonePlayable extends Playable {\n        constructor(public pitch: number, public duration: number) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                control.runInParallel(() => music.playTone(this.pitch, this.duration));\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                music.playTone(this.pitch, this.duration);\n                if (this.duration > 2000) {\n                    pause(this.duration);\n                }\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n    /**\n     * Play a song, melody, or other sound. The music plays until finished or can play as a\n     * background task.\n     * @param toPlay the song or melody to play\n     * @param playbackMode play the song or melody until it's finished or as background task\n     */\n    //% blockId=\"music_playable_play\"\n    //% block=\"play $toPlay $playbackMode\"\n    //% toPlay.shadow=music_melody_playable\n    //% group=\"Sounds\"\n    //% help=\"music/play\"\n    export function play(toPlay: Playable, playbackMode: PlaybackMode) {\n        toPlay.play(playbackMode);\n    }\n\n    /**\n     * Create a Playable object for a melody.\n     * @param melody the melody to make playable\n     */\n    //% blockId=\"music_melody_playable\"\n    //% block=\"sound $melody\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    //% blockHidden\n    //% help=music/melody-playable\n    export function melodyPlayable(melody: Melody): Playable {\n        return new MelodyPlayable(melody);\n    }\n\n    /**\n     * Create a Playable object for a melody string containg notes.\n     * @param melody the melody string to make playable\n     */\n    //% blockId=\"music_string_playable\"\n    //% block=\"melody $melody at tempo $tempo|(bpm)\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% melody.shadow=melody_editor\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% help=music/string-playable\n    export function stringPlayable(melody: string, tempo: number): Playable {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        return new MelodyPlayable(new Melody(formattedMelody));\n    }\n\n    /**\n     * Create a Playable object for a single tone and its duration.\n     * @param note the note or tone frequency to play\n     * @param duration the duration of the tone in milliseconds (ms)\n     */\n    //% blockId=\"music_tone_playable\"\n    //% block=\"tone $note for $duration\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Tone\"\n    //% duplicateShadowOnDrag\n    //% note.shadow=device_note\n    //% duration.shadow=device_beat\n    //% parts=\"headphone\"\n    //% help=music/tone-playable\n    export function tonePlayable(note: number, duration: number): Playable {\n        return new TonePlayable(note, duration);\n    }\n\n    export function _stopPlayables() {\n        state().stopLooping();\n    }\n}","pxt.json":"{\n    \"name\": \"mixer---ext\",\n    \"description\": \"The music library with a mixer\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"SoundOutput.h\",\n        \"sound.cpp\",\n        \"melody.h\",\n        \"melody.cpp\",\n        \"melody.ts\",\n        \"piano.ts\",\n        \"legacy.ts\",\n        \"ns.ts\",\n        \"targetoverrides.ts\",\n        \"music.ts\",\n        \"soundEffect.ts\",\n        \"instrument.ts\",\n        \"sequencer.ts\",\n        \"playable.ts\",\n        \"pxtparts.json\",\n        \"headphone.svg\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","pxtparts.json":"{\n    \"headphone\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"image\": \"headphone.svg\",\n            \"width\": 142,\n            \"height\": 180,\n            \"pinDistance\": 20,\n            \"pinLocations\": [\n                {\n                    \"x\": 17,\n                    \"y\": 11\n                },\n                {\n                    \"x\": 55,\n                    \"y\": 50\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"A0\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","sequencer.ts":"namespace music.sequencer {\n    const SEQUENCER_STOP_MESSAGE = 3243;\n    const SEQUENCER_TICK_MESSAGE = 3244;\n    const SEQUENCER_STATE_CHANGE_MESSAGE = 3245;\n    const SEQUENCER_LOOPED_MESSAGE = 3246;\n\n    export class Sequencer {\n        currentTick: number;\n        isPlaying: boolean;\n        isLooping: boolean;\n        isRunning: boolean;\n\n        constructor(public song: Song) {\n            this.currentTick = 0;\n            this.isPlaying = false;\n            this.isLooping = false;\n        }\n\n        start(loop: boolean) {\n            this.currentTick = 0;\n            this.isLooping = loop;\n            this.isPlaying = true;\n\n            if (this.isRunning) return;\n            this.isRunning = true;\n\n            control.runInParallel(() => {\n                while (this.isPlaying) {\n                    this.scheduleCurrentTick();\n\n                    this.currentTick ++;\n\n                    if (this.currentTick >= this.song.beatsPerMeasure * this.song.measures * this.song.ticksPerBeat) {\n                        if (this.isLooping) this.currentTick = 0;\n                        else this.isPlaying = false;\n                    }\n\n                    pause(this.tickToMs(1))\n                }\n                this.isRunning = false;\n            })\n        }\n\n        stop() {\n            this.isPlaying = false;\n        }\n\n        tickToMs(ticks: number) {\n            return ((60000 / this.song.beatsPerMinute) / this.song.ticksPerBeat) * ticks;\n        }\n\n        protected scheduleCurrentTick() {\n            for (const track of this.song.tracks) {\n                if (track.currentNoteEvent.startTick === this.currentTick) {\n                    if (track.isMelodicTrack) {\n                        this.scheduleMelodicTrack(track as MelodicTrack);\n                    }\n                    else {\n                        this.scheduleDrumTrack(track as DrumTrack);\n                    }\n\n                    track.advanceNoteEvent();\n                }\n            }\n        }\n\n        protected scheduleMelodicTrack(track: MelodicTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderInstrument(\n                        track.instrument,\n                        lookupFrequency(track.currentNoteEvent.getNote(i, track.instrument.octave)),\n                        this.tickToMs(track.currentNoteEvent.endTick - track.currentNoteEvent.startTick),\n                        music.volume()\n                    )\n                );\n            }\n        }\n\n        protected scheduleDrumTrack(track: DrumTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderDrumInstrument(\n                        track.drums[track.currentNoteEvent.getNote(i, undefined)],\n                        music.volume()\n                    )\n                );\n            }\n        }\n    }\n\n    let activeSimSequencers: _SimulatorSequencer[];\n    export function _stopAllSimSequencers() {\n        if (activeSimSequencers) {\n            for (const seq of activeSimSequencers) {\n                seq.stop();\n                seq.dispose();\n            }\n            activeSimSequencers = [];\n        }\n    }\n\n    // Simulator only! Does nothing on hardware\n    export class _SimulatorSequencer {\n        protected id: number;\n\n        constructor() {\n            if (!activeSimSequencers) activeSimSequencers = [];\n            activeSimSequencers.push(this);\n            this.id = _createSequencer();\n            this.setVolume(music.volume());\n        }\n\n        play(song: Buffer, loop: boolean) {\n            this.setVolume(music.volume());\n            _sequencerPlaySong(this.id, song, loop)\n        }\n\n        stop() {\n            _sequencerStop(this.id);\n        }\n\n        setVolume(volume: number) {\n            _sequencerSetVolume(this.id, volume);\n        }\n\n        setTrackVolume(trackIndex: number, volume: number) {\n            _sequencerSetTrackVolume(this.id, trackIndex, volume)\n        }\n\n        setDrumTrackVolume(trackIndex: number, drumIndex: number, volume: number) {\n            _sequencerSetDrumTrackVolume(this.id, drumIndex, trackIndex, volume)\n        }\n\n        state() {\n            return _sequencerState(this.id) || \"stop\";\n        }\n\n        currentTick() {\n            return _sequencerCurrentTick(this.id);\n        }\n\n        dispose() {\n            _sequencerDispose(this.id);\n        }\n\n        onTick(handler: (tick: number) => void) {\n            control.onEvent(SEQUENCER_TICK_MESSAGE, this.id, () => {\n                handler(this.currentTick());\n            });\n        }\n\n        onStateChange(handler: (state: string) => void) {\n            control.onEvent(SEQUENCER_STATE_CHANGE_MESSAGE, this.id, () => {\n                handler(this.state());\n            });\n        }\n\n        onStop(handler: () => void) {\n            control.onEvent(SEQUENCER_STOP_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n\n        onLooped(handler: () => void) {\n            control.onEvent(SEQUENCER_LOOPED_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n    }\n\n    //% promise\n    //% shim=music::_createSequencer\n    declare function _createSequencer(): number\n\n    //% shim=music::_sequencerState\n    declare function _sequencerState(id: number): string;\n\n    //% shim=music::_sequencerCurrentTick\n    declare function _sequencerCurrentTick(id: number): number;\n\n    //% shim=music::_sequencerPlaySong\n    declare function _sequencerPlaySong(id: number, song: Buffer, loop: boolean): void;\n\n    //% shim=music::_sequencerStop\n    declare function _sequencerStop(id: number): void;\n\n    //% shim=music::_sequencerSetVolume\n    declare function _sequencerSetVolume(id: number, volume: number): void;\n\n    //% shim=music::_sequencerSetVolumeForAll\n    declare function _sequencerSetVolumeForAll(volume: number): void;\n\n    //% shim=music::_sequencerSetTrackVolume\n    declare function _sequencerSetTrackVolume(id: number, trackIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerSetDrumTrackVolume\n    declare function _sequencerSetDrumTrackVolume(id: number, trackIndex: number, drumIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerDispose\n    declare function _sequencerDispose(id: number): void;\n}","sound.cpp":"#include \"pxt.h\"\n#include \"SoundOutput.h\"\n#include \"melody.h\"\n\nnamespace music {\n\nstatic ExtDAC *dac;\n\nDLLEXPORT void pxt_get_audio_samples(int16_t *buf, unsigned numSamples) {\n    if (!dac) {\n        memset(buf, 0, numSamples * 2);\n        return;\n    }\n\n    target_disable_irq();\n    dac->src.fillSamples(buf, numSamples);\n    target_enable_irq();\n\n    for (unsigned i = 0; i < numSamples; ++i) {\n        // playing at half-volume\n        buf[i] = buf[i] << 3;\n    }\n\n    //DMESG(\"samples %d %d %d %d\", numSamples, buf[0], buf[20], buf[100]);\n}\n\nExtDAC::ExtDAC(WSynthesizer &data) : src(data) {\n    dac = this;\n}\n\n} // namespace music","soundEffect.ts":"enum WaveShape {\n    //% block=\"sine\"\n    Sine = 0,\n    //% block=\"sawtooth\"\n    Sawtooth = 1,\n    //% block=\"triangle\"\n    Triangle = 2,\n    //% block=\"square\"\n    Square = 3,\n    //% block=\"noise\"\n    Noise = 4\n}\n\nenum InterpolationCurve {\n    //% block=\"linear\"\n    Linear,\n    //% block=\"curve\"\n    Curve,\n    //% block=\"logarithmic\"\n    Logarithmic\n}\n\nenum SoundExpressionEffect {\n    //% block=\"none\"\n    None = 0,\n    //% block=\"vibrato\"\n    Vibrato = 1,\n    //% block=\"tremolo\"\n    Tremolo = 2,\n    //% block=\"warble\"\n    Warble = 3\n}\n\nenum SoundExpressionPlayMode {\n    //% block=\"until done\"\n    UntilDone,\n    //% block=\"in background\"\n    InBackground\n}\n\nnamespace music {\n    export class SoundEffect extends Playable {\n        waveShape: WaveShape;\n        startFrequency: number;\n        endFrequency: number;\n        startVolume: number;\n        endVolume: number;\n        duration: number;\n        effect: SoundExpressionEffect;\n        interpolation: InterpolationCurve;\n\n        constructor() {\n            super();\n            this.waveShape = WaveShape.Sine;\n            this.startFrequency = 5000;\n            this.endFrequency = 1;\n            this.startVolume = 255;\n            this.endVolume = 0;\n            this.duration = 1000;\n            this.effect = SoundExpressionEffect.None;\n            this.interpolation = InterpolationCurve.Linear;\n        }\n\n        toBuffer(volume?: number) {\n            if (volume === undefined) volume = music.volume();\n\n            return soundToInstructionBuffer(\n                this.waveShape,\n                this.startFrequency,\n                this.endFrequency,\n                this.startVolume,\n                this.endVolume,\n                this.duration,\n                this.effect,\n                this.interpolation,\n                20,\n                1,\n                volume\n            );\n        }\n\n        play(playbackMode: PlaybackMode) {\n            const toPlay = this.toBuffer(music.volume());\n            if (playbackMode === PlaybackMode.InBackground) {\n                queuePlayInstructions(0, toPlay);\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                queuePlayInstructions(0, toPlay);\n                pause(this.duration)\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n\n    /**\n     * Play a SoundEffect.\n     * @param sound the SoundEffect to play\n     * @param mode the play mode, play until done or in the background\n     */\n    //% blockId=soundExpression_playSoundEffect\n    //% block=\"play sound $sound $mode\"\n    //% weight=30\n    //% help=music/play-sound-effect\n    //% blockGap=8\n    //% group=\"Sounds\"\n    //% deprecated=1\n    export function playSoundEffect(sound: SoundEffect, mode: SoundExpressionPlayMode) {\n        const toPlay = sound.toBuffer(music.volume());\n\n        queuePlayInstructions(0, toPlay);\n        if (mode === SoundExpressionPlayMode.UntilDone) {\n            pause(sound.duration);\n        }\n    }\n\n    /**\n     * Create a sound expression from a set of sound effect parameters.\n     * @param waveShape waveform of the sound effect\n     * @param startFrequency starting frequency for the sound effect waveform\n     * @param endFrequency ending frequency for the sound effect waveform\n     * @param startVolume starting volume of the sound, or starting amplitude\n     * @param endVolume ending volume of the sound, or ending amplitude\n     * @param duration the amount of time in milliseconds (ms) that sound will play for\n     * @param effect the effect to apply to the waveform or volume\n     * @param interpolation interpolation method for frequency scaling\n     */\n    //% blockId=soundExpression_createSoundEffect\n    //% help=music/create-sound-effect\n    //% block=\"$waveShape|| start frequency $startFrequency end frequency $endFrequency duration $duration start volume $startVolume end volume $endVolume effect $effect interpolation $interpolation\"\n    //% waveShape.defl=WaveShape.Sine\n    //% waveShape.fieldEditor=soundeffect\n    //% waveShape.fieldOptions.useMixerSynthesizer=true\n    //% startFrequency.defl=5000\n    //% startFrequency.min=0\n    //% startFrequency.max=5000\n    //% endFrequency.defl=0\n    //% endFrequency.min=0\n    //% endFrequency.max=5000\n    //% startVolume.defl=255\n    //% startVolume.min=0\n    //% startVolume.max=255\n    //% endVolume.defl=0\n    //% endVolume.min=0\n    //% endVolume.max=255\n    //% duration.defl=500\n    //% duration.min=1\n    //% duration.max=9999\n    //% effect.defl=SoundExpressionEffect.None\n    //% interpolation.defl=InterpolationCurve.Linear\n    //% compileHiddenArguments=true\n    //% inlineInputMode=\"variable\"\n    //% inlineInputModeLimit=3\n    //% expandableArgumentBreaks=\"3,5\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=20\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    export function createSoundEffect(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve): SoundEffect {\n        const result = new SoundEffect();\n\n        result.waveShape = waveShape;\n        result.startFrequency = startFrequency;\n        result.endFrequency = endFrequency;\n        result.startVolume = startVolume;\n        result.endVolume = endVolume;\n        result.duration = duration;\n        result.effect = effect;\n        result.interpolation = interpolation;\n\n        return result;\n    }\n\n    interface Step {\n        frequency: number;\n        volume: number;\n    }\n\n     export function soundToInstructionBuffer(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve, fxSteps: number, fxRange: number, globalVolume: number) {\n        const steps: Step[] = [];\n\n        // Optimize the simple case\n        if (interpolation === InterpolationCurve.Linear && effect === SoundExpressionEffect.None) {\n            steps.push({\n                frequency: startFrequency,\n                volume: (startVolume / 255) * globalVolume,\n            })\n            steps.push({\n                frequency: endFrequency,\n                volume: (endVolume / 255) * globalVolume,\n            })\n        }\n        else {\n\n            fxSteps = Math.min(fxSteps, Math.floor(duration / 5))\n\n            const getVolumeAt = (t: number) => ((startVolume + t * (endVolume - startVolume) / duration) / 255) * globalVolume;\n            let getFrequencyAt: (t: number) => number;\n\n            switch (interpolation) {\n                case InterpolationCurve.Linear:\n                    getFrequencyAt = t => startFrequency + t * (endFrequency - startFrequency) / duration;\n                    break;\n                case InterpolationCurve.Curve:\n                    getFrequencyAt = t => startFrequency + (endFrequency - startFrequency) * Math.sin(t / duration * (Math.PI / 2));\n                    break;\n                case InterpolationCurve.Logarithmic:\n                    getFrequencyAt = t => startFrequency + (Math.log(1 + 9 * (t / duration)) / Math.log(10)) * (endFrequency - startFrequency)\n                    break;\n            }\n\n            const timeSlice = duration / fxSteps;\n\n            for (let i = 0; i < fxSteps; i++) {\n                const newStep = {\n                    frequency: getFrequencyAt(i * timeSlice),\n                    volume: getVolumeAt(i * timeSlice)\n                };\n\n                if (effect === SoundExpressionEffect.Tremolo) {\n                    if (i % 2 === 0) {\n                        newStep.volume = Math.max(newStep.volume - fxRange * 500, 0)\n                    }\n                    else {\n                        newStep.volume = Math.min(newStep.volume + fxRange * 500, 1023)\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Vibrato) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 100, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 100\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Warble) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 1000, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 1000\n                    }\n                }\n\n                steps.push(newStep)\n            }\n        }\n\n        const out = control.createBuffer(12 * (steps.length - 1));\n        const stepDuration = Math.floor(duration / (steps.length - 1))\n\n        for (let i = 0; i < steps.length - 1; i++) {\n            const offset = i * 12;\n            out.setNumber(NumberFormat.UInt8LE, offset, waveToValue(waveShape));\n            out.setNumber(NumberFormat.UInt16LE, offset + 2, steps[i].frequency);\n            out.setNumber(NumberFormat.UInt16LE, offset + 4, stepDuration);\n            out.setNumber(NumberFormat.UInt16LE, offset + 6, steps[i].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 8, steps[i + 1].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 10, steps[i + 1].frequency);\n        }\n\n        return out;\n    }\n\n    function waveToValue(wave: WaveShape) {\n        switch (wave) {\n            case WaveShape.Square: return 15;\n            case WaveShape.Sine: return 3;\n            case WaveShape.Triangle: return 1;\n            case WaveShape.Noise: return 18;\n            case WaveShape.Sawtooth: return 2;\n        }\n    }\n\n\n    /**\n     * Generate a random similar sound effect to the given one.\n     *\n     * @param sound the sound effect\n     */\n    //% blockId=soundExpression_generateSimilarSound\n    //% block=\"randomize $sound\"\n    //% sound.shadow=soundExpression_createSoundEffect\n    //% weight=0 help=music/randomize-sound\n    //% blockGap=8\n    //% group=\"Sounds\"\n    export function randomizeSound(sound: SoundEffect) {\n        const res = new SoundEffect();\n        res.waveShape = sound.waveShape;\n        res.startFrequency = sound.startFrequency;\n        res.endFrequency = sound.endFrequency;\n        res.startVolume = sound.startVolume;\n        res.endVolume = sound.endVolume;\n        res.duration = sound.duration;\n        res.effect = sound.effect;\n        res.interpolation = randomInterpolation();\n\n        res.duration = Math.clamp(\n            Math.min(100, res.duration),\n            Math.max(2000, res.duration),\n            res.duration + (Math.random() - 0.5) * res.duration,\n        );\n\n        if (res.waveShape === WaveShape.Noise) {\n            // The primary waveforms don't produce sounds that are similar to noise,\n            // but adding an effect sorta does\n            if (Math.percentChance(20)) {\n                res.waveShape = randomWave();\n                res.effect = randomEffect();\n            }\n        }\n        else {\n            res.waveShape = randomWave();\n\n            // Adding an effect can drastically alter the sound, so keep it\n            // at a low percent chance unless there already is one\n            if (res.effect !== SoundExpressionEffect.None || Math.percentChance(10)) {\n                res.effect = randomEffect();\n            }\n        }\n\n        // Instead of randomly changing the frequency, change the slope and choose\n        // a new start frequency. This keeps a similar profile to the sound\n        const oldFrequencyDifference = res.endFrequency - res.startFrequency;\n        let newFrequencyDifference = oldFrequencyDifference + (oldFrequencyDifference * 2) * (Math.random() - 0.5);\n\n        if (Math.sign(oldFrequencyDifference) !== Math.sign(newFrequencyDifference)) {\n            newFrequencyDifference *= -1;\n        }\n\n        newFrequencyDifference = Math.clamp(-5000, 5000, newFrequencyDifference);\n\n        res.startFrequency = Math.clamp(\n            Math.max(-newFrequencyDifference, 1),\n            Math.clamp(1, 5000, 5000 - newFrequencyDifference),\n            Math.random() * 5000,\n        );\n\n        res.endFrequency = Math.clamp(1, 5000, res.startFrequency + newFrequencyDifference);\n\n        // Same strategy for volume\n        const oldVolumeDifference = res.endVolume - res.startVolume;\n        let newVolumeDifference = oldVolumeDifference + oldVolumeDifference * (Math.random() - 0.5);\n\n        newVolumeDifference = Math.clamp(-255, 255, newVolumeDifference);\n\n        if (Math.sign(oldVolumeDifference) !== Math.sign(newVolumeDifference)) {\n            newVolumeDifference *= -1;\n        }\n\n        res.startVolume = Math.clamp(\n            Math.max(-newVolumeDifference, 0),\n            Math.clamp(0, 255, 255 - newVolumeDifference),\n            Math.random() * 255,\n        );\n\n        res.endVolume = Math.clamp(0, 255, res.startVolume + newVolumeDifference);\n\n        return res;\n    }\n\n    function randomWave() {\n        switch (Math.randomRange(0, 3)) {\n            case 1: return WaveShape.Sawtooth;\n            case 2: return WaveShape.Square;\n            case 3: return WaveShape.Triangle;\n            case 0:\n            default:\n                return WaveShape.Sine;\n        }\n    }\n\n    function randomEffect() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return SoundExpressionEffect.Warble;\n            case 2: return  SoundExpressionEffect.Tremolo;\n            case 0:\n            default:\n                return SoundExpressionEffect.Vibrato;\n        }\n    }\n\n    function randomInterpolation() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return InterpolationCurve.Linear;\n            case 2: return  InterpolationCurve.Curve;\n            case 0:\n            default:\n                return InterpolationCurve.Logarithmic;\n        }\n    }\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n}","targetoverrides.ts":"\n","test.ts":"for(let i = 1000; i > 0; i -= 50)\n    music.playTone(440, i)\n\nfor(let i = 0; i < 1000; i += 20)\n    music.playTone(440, i)\n"},"mixer---linux":{"SoundOutput.h":"#define SAMPLE_RATE 44100\n\nnamespace music {\nclass WSynthesizer;\n\nclass LinuxDAC {\n  public:\n    int16_t data[256];\n    WSynthesizer &src;\n    LinuxDAC(WSynthesizer &data);\n    static void *play(void *);\n    int getSampleRate() { return SAMPLE_RATE; }\n};\n\nclass SoundOutput {\n  public:\n    LinuxDAC dac;\n\n    SoundOutput(WSynthesizer &data) : dac(data) {}\n\n    void setOutput(int) {}\n};\n\n} // namespace music","headphone.svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"142\" height=\"180\" viewBox=\"0 0 142 180\"><rect ry=\".3\" rx=\"1\" y=\"58.615\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><rect ry=\".3\" rx=\"1\" y=\"32.043\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><path d=\"M.346 7.296c-.394.39-.31 4.797-.18 4.898l13.404 10.18c.117.12.337 4.76.73 4.368l5.506-5.56.01.01 6.51-6.444c.39-.392-4.25-.614-4.366-.73L11.777.612c-.1-.132-4.51-.215-4.898.18L4.087 3.636l-.01-.01-3.73 3.67z\" fill=\"#b3b3b3\"/><rect ry=\"6.85\" rx=\"4.571\" y=\"84.758\" x=\"-20.128\" height=\"75.571\" width=\"39.643\" transform=\"rotate(-45)\"/><rect ry=\".374\" rx=\"1.038\" y=\"29.442\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"55.939\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"82.392\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\"2.317\" rx=\"2.183\" y=\"158.876\" x=\"-9.774\" height=\"25.568\" width=\"18.935\" transform=\"rotate(-45)\"/><path d=\"M128.588 128.82s14.97 11.165 7.547 26.35c-8.426 17.24-25.57 20.653-25.57 20.653\" fill=\"none\" stroke=\"#000\" stroke-width=\"6.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>","instrument.ts":"namespace music.sequencer {\n    const BUFFER_SIZE = 12;\n\n    let currentSequencer: sequencer.Sequencer;\n\n    /**\n     * Byte encoding format for songs\n     * FIXME: should this all be word aligned?\n     *\n     * song(7 + length of all tracks bytes)\n     *     0 version\n     *     1 beats per minute\n     *     3 beats per measure\n     *     4 ticks per beat\n     *     5 measures\n     *     6 number of tracks\n     *     ...tracks\n     *\n     * track(6 + instrument length + note length bytes)\n     *     0 id\n     *     1 flags\n     *     2 instruments byte length\n     *     4...instrument\n     *     notes byte length\n     *     ...note events\n     *\n     * instrument(28 bytes)\n     *     0 waveform\n     *     1 amp attack\n     *     3 amp decay\n     *     5 amp sustain\n     *     7 amp release\n     *     9 amp amp\n     *     11 pitch attack\n     *     13 pitch decay\n     *     15 pitch sustain\n     *     17 pitch release\n     *     19 pitch amp\n     *     21 amp lfo freq\n     *     22 amp lfo amp\n     *     24 pitch lfo freq\n     *     25 pitch lfo amp\n     *     27 octave\n     *\n     * drum(5 + 7 * steps bytes)\n     *     0 steps\n     *     1 start freq\n     *     3 start amp\n     *     5...steps\n     *\n     * drum step(7 bytes)\n     *     0 waveform\n     *     1 freq\n     *     3 volume\n     *     5 duration\n     *\n     * note event(5 + 1 * polyphony bytes)\n     *     0 start tick\n     *     2 end tick\n     *     4 polyphony\n     *     5...notes(1 byte each)\n     *\n     * note (1 byte)\n     *     lower six bits = note - (instrumentOctave - 2) * 12\n     *     upper two bits are the enharmonic spelling:\n     *          0 = normal\n     *          1 = flat\n     *          2 = sharp\n     */\n\n    export class Song extends Playable {\n        tracks: Track[];\n\n        constructor(public buf: Buffer) {\n            super();\n            this.tracks = [];\n\n            let currentOffset = 7;\n            for (let i = 0; i < this.numberOfTracks; i++) {\n                let track: Track = new MelodicTrack(this.buf, currentOffset);\n\n                if (!track.isMelodicTrack) {\n                    track = new DrumTrack(this.buf, currentOffset)\n                }\n\n                this.tracks.push(track);\n                currentOffset += track.byteLength;\n            }\n        }\n\n        get version(): number {\n            return this.buf[0];\n        }\n\n        set version(value: number) {\n            this.buf[0] = value;\n        }\n\n        get beatsPerMinute(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, 1);\n        }\n\n        set beatsPerMinute(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, 1, value);\n        }\n\n        get beatsPerMeasure(): number {\n            return this.buf[3];\n        }\n\n        set beatsPerMeasure(value: number) {\n            this.buf[3] = value;\n        }\n\n        get ticksPerBeat(): number {\n            return this.buf[4];\n        }\n\n        set ticksPerBeat(value: number) {\n            this.buf[4] = value;\n        }\n\n        get measures(): number {\n            return this.buf[5];\n        }\n\n        set measures(value: number) {\n            this.buf[5] = value;\n        }\n\n        get numberOfTracks(): number {\n            return this.buf[6];\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (control.deviceDalVersion() === \"sim\") {\n                const seq = new _SimulatorSequencer();\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    seq.play(this.buf, false);\n\n                    pauseUntil(() => seq.state() === \"stop\");\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    seq.play(this.buf, false);\n                }\n                else {\n                    seq.play(this.buf, true);\n                }\n            }\n            else {\n                if (currentSequencer) currentSequencer.stop();\n                currentSequencer = new sequencer.Sequencer(this);\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    let seq = currentSequencer;\n                    currentSequencer.start(false);\n                    pauseUntil(() => !seq.isRunning);\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    currentSequencer.start(false);\n                }\n                else {\n                    currentSequencer.start(true);\n                }\n            }\n        }\n    }\n\n    export class Envelope {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(10);\n            this.offset = this.offset || 0;\n        }\n\n        // The time in ms for the envelope to reach its maximum value\n        get attack(): number {\n            return this.getValue(0);\n        }\n\n        set attack(value: number) {\n            this.setValue(0, value);\n        }\n\n        // The time in ms for the envelope to reach its sustain value after reaching its maximum value\n        get decay(): number {\n            return this.getValue(2);\n        }\n\n        set decay(value: number) {\n            this.setValue(2, value);\n        }\n\n        // The value (0-1024) to hold at during the sustain stage\n        get sustain(): number {\n            return this.getValue(4);\n        }\n\n        set sustain(value: number) {\n            this.setValue(4, value);\n        }\n\n        // The time in ms for the envelope to reach 0 after the gate length ends\n        get release(): number {\n            return this.getValue(6);\n        }\n\n        set release(value: number) {\n            this.setValue(6, value);\n        }\n\n        // The maximum value that this envelope will reach\n        get amplitude(): number {\n            return this.getValue(8);\n        }\n\n        set amplitude(value: number) {\n            this.setValue(8, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class LFO {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(3);\n            this.offset = this.offset || 0;\n        }\n\n        get frequency(): number {\n            return this.buf[this.offset];\n        }\n\n        set frequency(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get amplitude(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + 1);\n        }\n\n        set amplitude(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + 1, value);\n        }\n    }\n\n    export class NoteEvent {\n        constructor(public buf: Buffer, public offset: number) {\n\n        }\n\n        get startTick(): number {\n            return this.getValue(0);\n        }\n\n        set startTick(value: number) {\n            this.setValue(0, value);\n        }\n\n        get endTick(): number {\n            return this.getValue(2);\n        }\n\n        set endTick(value: number) {\n            this.setValue(2, value);\n        }\n\n        get polyphony(): number {\n            return this.buf[this.offset + 4];\n        }\n\n        set polyphony(value: number) {\n            this.buf[this.offset + 4] = value;\n        }\n\n        get byteLength() {\n            return this.polyphony + 5;\n        }\n\n        getNote(offset: number, octave?: number) {\n            const value = this.buf[this.offset + offset + 5] & 0x3f;\n            if (octave !== undefined) {\n                return value + (octave - 2) * 12\n            }\n            return value\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class Track {\n        currentNoteEvent: NoteEvent;\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.currentNoteEvent = new NoteEvent(this.buf, this.noteEventStart + 2);\n        }\n\n        get isMelodicTrack(): boolean {\n            return this.flags === 0;\n        }\n\n        get id(): number {\n            return this.buf[this.offset];\n        }\n\n        set id(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get flags(): number {\n            return this.buf[this.offset + 1];\n        }\n\n        set flags(value: number) {\n            this.buf[this.offset + 1] = value;\n        }\n\n        get instrumentByteLength(): number {\n            return this.getValue(this.offset + 2);\n        }\n\n        set instrumentByteLength(value: number) {\n            this.setValue(this.offset + 2, value);\n        }\n\n        get noteEventStart(): number {\n            return this.offset + this.instrumentByteLength + 4;\n        }\n\n        get noteEventByteLength(): number {\n            return this.getValue(this.noteEventStart);\n        }\n\n        set noteEventByteLength(value: number) {\n            this.setValue(this.noteEventStart, value);\n        }\n\n        get byteLength() {\n            return this.noteEventByteLength + this.instrumentByteLength + 6;\n        }\n\n        advanceNoteEvent() {\n            this.currentNoteEvent.offset += this.currentNoteEvent.byteLength;\n\n            if (this.currentNoteEvent.offset >= this.offset + this.byteLength) {\n                this.currentNoteEvent.offset = this.noteEventStart + 2;\n            }\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, offset, value);\n        }\n    }\n\n    export class MelodicTrack extends Track {\n        instrument: Instrument;\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.instrument = new Instrument(this.buf, this.offset + 4);\n        }\n    }\n\n    export class DrumTrack extends Track {\n        drums: DrumInstrument[];\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.drums = [];\n\n            let currentOffset = 0;\n            while (currentOffset < this.instrumentByteLength) {\n                this.drums.push(new DrumInstrument(this.buf, this.offset + 4 + currentOffset));\n                currentOffset += this.drums[this.drums.length - 1].byteLength;\n            }\n        }\n    }\n\n    export class Instrument {\n        ampEnvelope: Envelope;\n        pitchEnvelope: Envelope;\n        ampLFO: LFO;\n        pitchLFO: LFO;\n\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(27);\n            this.offset = this.offset || 0;\n            this.ampEnvelope = new Envelope(this.buf, this.offset + 1);\n            this.pitchEnvelope = new Envelope(this.buf, this.offset + 11);\n            this.ampLFO = new LFO(this.buf, this.offset + 21);\n            this.pitchLFO = new LFO(this.buf, this.offset + 24)\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get octave(): number {\n            return this.buf[this.offset + 27]\n        }\n\n        set octave(value: number) {\n            this.buf[this.offset + 27] = value;\n        }\n    }\n\n    export class DrumInstrument {\n        steps: DrumStep[];\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.steps = [];\n\n            for (let i = 0; i < this.numSteps; i++) {\n                this.steps.push(new DrumStep(this.buf, this.offset + 5 + i * 7))\n            }\n        }\n\n        get byteLength(): number {\n            return 5 + this.numSteps * 7;\n        }\n\n        get numSteps(): number {\n            return this.buf[this.offset];\n        }\n\n        set numSteps(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get startFrequency(): number {\n            return this.getValue(1);\n        }\n\n        set startFrequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get startVolume(): number {\n            return this.getValue(3);\n        }\n\n        set startVolume(value: number) {\n            this.setValue(3, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class DrumStep {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(7);\n            this.offset = this.offset || 0;\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get frequency(): number {\n            return this.getValue(1);\n        }\n\n        set frequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get volume(): number {\n            return this.getValue(3);\n        }\n\n        set volume(value: number) {\n            this.setValue(3, value);\n        }\n\n        get duration(): number {\n            return this.getValue(5);\n        }\n\n        set duration(value: number) {\n            this.setValue(5, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    /**\n     * Renders a single note played on an instrument into a buffer of sound instructions.\n     *\n     * @param instrument The instrument being played\n     * @param noteFrequency The frequency of the note being played. In other words, \"the key being pressed on the piano\"\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     * @param volume The peak volume of the note to play (0-1024). Also called the \"velocity\"\n     */\n    export function renderInstrument(instrument: Instrument, noteFrequency: number, gateLength: number, volume: number) {\n        // We cut off the sound at the end of the amplitude envelope's release time. This is to prevent\n        // the amp envelope from making the sound keep playing forever\n        const totalDuration = gateLength + instrument.ampEnvelope.release;\n\n        // Our goal is to calculate the frequency and amplitude at all of the inflection points in this note's lifetime\n\n        // For the ADSR envelopes, the inflection points are:\n        //     1. The end of the envelope atack (which is when the decay begins)\n        //     2. The end of the envelope decay (which is when the sustain begins)\n        //     3. The end of the gateLength (which is when the release begins)\n        //     4. The end of the envelope release\n        // If the gateLength ends before any of these stages (e.g. it's shorter than the envelope's attack), then\n        // we ignore the other stages and go straight to the release stage.\n\n        // For the triangle LFOs, the inflections points occur every time the slope goes from positive to negative. In\n        // other words, it's half the period of the triangle wave.\n\n        const ampLFOInterval = instrument.ampLFO.amplitude ? Math.max(500 / instrument.ampLFO.frequency, 50) : 50;\n        const pitchLFOInterval = instrument.pitchLFO.amplitude ? Math.max(500 / instrument.pitchLFO.frequency, 50) : 50;\n\n        // We're going to add the timepoints to this array in order so that it doesn't need to be sorted\n        let timePoints = [0];\n\n        // For each LFO and envelope, keep track of the next inflection point. If any of the LFOs or envelopes have\n        // an amplitude of 0, we can ignore them entirely.\n        let nextAETime = instrument.ampEnvelope.attack;\n        let nextPETime = instrument.pitchEnvelope.amplitude ? instrument.pitchEnvelope.attack : totalDuration;\n        let nextPLTime = instrument.pitchLFO.amplitude ? pitchLFOInterval : totalDuration;\n        let nextALTime = instrument.ampLFO.amplitude ? ampLFOInterval : totalDuration;\n\n        let time = 0;\n        while (time < totalDuration) {\n            // Amp envelope\n            if (nextAETime <= nextPETime && nextAETime <= nextPLTime && nextAETime <= nextALTime) {\n                time = nextAETime;\n                timePoints.push(nextAETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            // Pitch envelope\n            else if (nextPETime <= nextPLTime && nextPETime <= nextALTime && nextPETime < totalDuration) {\n                time = nextPETime;\n                timePoints.push(nextPETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                // If we reach the end of the release before the amp envelope is finished, bail out\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            // Pitch LFO\n            else if (nextPLTime <= nextALTime && nextPLTime < totalDuration) {\n                time = nextPLTime;\n                timePoints.push(nextPLTime);\n                nextPLTime += pitchLFOInterval;\n            }\n            // Amp LFO\n            else if (nextALTime < totalDuration) {\n                time = nextALTime;\n                timePoints.push(nextALTime);\n                nextALTime += ampLFOInterval;\n            }\n\n\n            if (time >= totalDuration) {\n                break;\n            }\n\n            // Now that we've advanced the time, we need to check all of the envelopes/LFOs again\n            // to see if any of them also need to be pushed forward (e.g. they had the same inflection point\n            // as the one we just added to the array)\n            if (nextAETime <= time) {\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            if (nextPETime <= time) {\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            while (nextALTime <= time) {\n                nextALTime += ampLFOInterval;\n            }\n            while (nextPLTime <= time) {\n                nextPLTime += pitchLFOInterval;\n            }\n        }\n\n        // Once we've calculated the inflection points, calculate the frequency and amplitude at\n        // each step and interpolate between them with sound instructions\n        let prevAmp = instrumentVolumeAtTime(instrument, gateLength, 0, volume) | 0;\n        let prevPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, 0) | 0;\n        let prevTime = 0;\n\n        let nextAmp: number;\n        let nextPitch: number;\n        const out = control.createBuffer(BUFFER_SIZE * timePoints.length);\n        for (let i = 1; i < timePoints.length; i++) {\n            if (timePoints[i] - prevTime < 5) {\n                prevTime = timePoints[i];\n                continue;\n            }\n\n            nextAmp = instrumentVolumeAtTime(instrument, gateLength, timePoints[i], volume) | 0;\n            nextPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, timePoints[i]) | 0\n            addNote(\n                out,\n                (i - 1) * 12,\n                (timePoints[i] - prevTime) | 0,\n                prevAmp,\n                nextAmp,\n                instrument.waveform,\n                prevPitch,\n                255,\n                nextPitch\n            )\n\n            prevAmp = nextAmp;\n            prevPitch = nextPitch;\n            prevTime = timePoints[i];\n        }\n\n        // Finally, add one extra step to move the amplitude to 0 without\n        // clipping just in case the amp LFO caused it to be nonzero\n        addNote(\n            out,\n            (timePoints.length - 1) * 12,\n            10,\n            prevAmp,\n            0,\n            instrument.waveform,\n            prevPitch,\n            255,\n            prevPitch\n        )\n        return out;\n    }\n\n    export function renderDrumInstrument(sound: DrumInstrument, volume: number) {\n        // Drum instruments are rendered just like melodic instruments, but the inflection\n        // points are already calculated for us\n        let prevAmp = sound.startVolume;\n        let prevFreq = sound.startFrequency;\n\n        const scaleVolume = (value: number) => (value / 1024) * volume;\n\n        let out = control.createBuffer((sound.steps.length + 1) * BUFFER_SIZE);\n\n        for (let i = 0; i < sound.steps.length; i++) {\n            addNote(\n                out,\n                i * BUFFER_SIZE,\n                sound.steps[i].duration,\n                scaleVolume(prevAmp),\n                scaleVolume(sound.steps[i].volume),\n                sound.steps[i].waveform,\n                prevFreq,\n                255,\n                sound.steps[i].frequency\n            );\n            prevAmp = sound.steps[i].volume;\n            prevFreq = sound.steps[i].frequency\n        }\n\n        addNote(\n            out,\n            sound.steps.length * BUFFER_SIZE,\n            10,\n            scaleVolume(prevAmp),\n            0,\n            sound.steps[sound.steps.length - 1].waveform,\n            prevFreq,\n            255,\n            prevFreq\n        );\n\n        return out;\n    }\n\n    function instrumentPitchAtTime(instrument: Instrument, noteFrequency: number, gateLength: number, time: number) {\n        let mod = 0;\n        if (instrument.pitchEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.pitchEnvelope, time, gateLength)\n        }\n        if (instrument.pitchLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.pitchLFO, time)\n        }\n        return Math.max(noteFrequency + mod, 0);\n    }\n\n    function instrumentVolumeAtTime(instrument: Instrument, gateLength: number, time: number, maxVolume: number) {\n        let mod = 0;\n        if (instrument.ampEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.ampEnvelope, time, gateLength)\n        }\n        if (instrument.ampLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.ampLFO, time)\n        }\n        return ((Math.max(Math.min(mod, instrument.ampEnvelope.amplitude), 0) / 1024) * maxVolume) | 0;\n    }\n\n    /**\n     * Calculates the value of an ADSR envelope at the given time for a given gate length.\n     *\n     * @param envelope The ADSR envelope\n     * @param time The point and time to calculate the value at\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     */\n    function envelopeValueAtTime(envelope: Envelope, time: number, gateLength: number) {\n        // ADSR envelopes consist of 4 stages. They are (in order):\n        //     1. The attack stage, where the value starts at 0 and rises to the maximum value\n        //     2. The decay stage, where the value falls from the maximum value to the sustain value\n        //     3. The sustain stage, where the value holds steady at the sustain value until the gate length ends\n        //     4. The release stage, where the value falls to 0 after the gate length ends\n        // If the gate length ends before the sustain stage, we immediately skip to the release stage. All stages\n        // use a linear function for the value\n        const adjustedSustain = (envelope.sustain / 1024) * envelope.amplitude;\n\n        // First check to see if we are already in the release stage\n        if (time > gateLength) {\n            if (time - gateLength > envelope.release) return 0;\n\n            // Did the gate length end before the attack stage finished?\n            else if (time < envelope.attack) {\n                const height = (envelope.amplitude / envelope.attack) * gateLength;\n                return height - ((height / envelope.release) * (time - gateLength))\n            }\n            // Did the gate length end before the decay stage finished?\n            else if (time < envelope.attack + envelope.decay) {\n                const height2 = envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (gateLength - envelope.attack);\n                return height2 - ((height2 / envelope.release) * (time - gateLength))\n            }\n            else {\n                return adjustedSustain - (adjustedSustain / envelope.release) * (time - gateLength)\n            }\n        }\n        else if (time < envelope.attack) {\n            return (envelope.amplitude / envelope.attack) * time\n        }\n        else if (time < envelope.attack + envelope.decay) {\n            return envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (time - envelope.attack)\n        }\n        else {\n            return adjustedSustain;\n        }\n    }\n\n    /**\n     * Calculates the value of the LFO at the given time.\n     *\n     * TODO: might be nice to give options to shift the phase of the LFO or let it run free\n     *\n     * @param lfo The LFO to calculate the value of\n     * @param time The time to calculate the value at\n     */\n    function lfoValueAtTime(lfo: LFO, time: number) {\n        // Use cosine to smooth out the value somewhat\n        return Math.cos(((time / 1000) * lfo.frequency) * 2 * Math.PI) * lfo.amplitude\n    }\n\n    export function _stopAllSongs() {\n        if (currentSequencer) {\n            currentSequencer.stop();\n            currentSequencer = undefined;\n        }\n        _stopAllSimSequencers();\n    }\n}","legacy.ts":"//% deprecated=true hidden=true\nenum Sounds {\n    //% block=\"power up\"\n    PowerUp,\n    //% block=\"power down\"\n    PowerDown,\n    //% block=\"jump up\"\n    JumpUp,\n    //% block=\"jump down\"\n    JumpDown,\n    //% block=\"ba ding\"\n    BaDing,\n    //% block=\"wawawawaa\"\n    Wawawawaa,\n    //% block=\"magic wand\"\n    MagicWand,\n    //% block=\"siren\"\n    Siren\n}\n\nnamespace music {\n    /**\n     * Get the melody string for a built-in melody.\n     * @param name the note name, eg: Note.C\n     */\n    //% help=music/sounds\n    //% blockId=music_sounds block=\"%name\"\n    //% blockHidden=true\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=285\n    //% name.fieldOptions.columns=3\n    export function sounds(name: Sounds): string {\n        switch (name) {\n            case Sounds.BaDing:\n                return 'b5:1 e6:3';\n            case Sounds.Wawawawaa:\n                return 'e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8';\n            case Sounds.JumpUp:\n                return 'c5:1 d e f g';\n            case Sounds.JumpDown:\n                return 'g5:1 f e d c';\n            case Sounds.PowerUp:\n                return 'g4:1 c5 e g:2 e:1 g:3';\n            case Sounds.PowerDown:\n                return 'g5:1 d# c g4:2 b:1 c5:3';\n            case Sounds.MagicWand:\n                return 'F#6:1-300 G# A# B C7# D# F F# G# A# B:6'; //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n            case Sounds.Siren:\n                return 'a4 d5 a4 d5 a4 d5';\n            default:\n                return '';\n        }\n    }\n\n    let currMelody: Melody\n\n    /**\n     * Start playing a sound and don't wait for it to finish.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound\n    //% blockId=music_play_sound block=\"play sound %sound=music_sounds\"\n    //% parts=\"headphone\"\n    //% weight=95 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSound(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.play();\n        pause(1);\n    }\n\n\n    /**\n     * Play a sound and wait until the sound is done.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound-until-done\n    //% blockId=music_play_sound_until_done block=\"play sound %sound=music_sounds|until done\"\n    //% parts=\"headphone\"\n    //% weight=94 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSoundUntilDone(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.playUntilDone();\n    }\n}","melody.cpp":"#include \"pxt.h\"\n#include \"SoundOutput.h\"\n#include \"melody.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\nnamespace music {\n\nSINGLETON(WSynthesizer);\n\n// Tone generator arguments:\n//\n// sound: a pointer to the currently-playing sound, usable for looking up the\n// waveform or generator-specific state.\n//\n// position: offset within the currently-playing wave, range 0..1023.\n//\n// cycle: a 6-bit cyclical sequence number of the wave, incremented each time\n// the position loops from 1023 back to 0.\ntypedef int (*gentone_t)(PlayingSound *sound, uint32_t position, uint8_t cycle);\n\nstatic int noiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    // see https://en.wikipedia.org/wiki/Xorshift\n    static uint32_t x = 0xf01ba80;\n    x ^= x << 13;\n    x ^= x >> 17;\n    x ^= x << 5;\n    return (x & 0xffff) - 0x7fff;\n}\n\nstatic int sineTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    int32_t p = position;\n    if (p >= 512) {\n        p -= 512;\n    }\n    if (p > 256) {\n        p = 512 - p;\n    }\n\n    // Approximate sin(x * pi / 2) with the odd polynomial y = cx^5 + bx^3 + ax\n    // using the constraint y(1) = 1 => a = 1 - b - c\n    //   => y = c x^5 + b x^3 + (1 - b - c) * x\n    //\n    // Do a least-squares fit of this to sin(x * pi / 2) in the range 0..1\n    // inclusive, using 21 evenly spaced points. Resulting approximation:\n    //\n    // sin(x*pi/2) ~= 0.0721435357258*x**5 - 0.642443736562*x**3 + 1.57030020084*x\n\n    // Scale the constants by 32767 to match the desired output range.\n    constexpr int32_t c = 0.0721435357258 * 32767;\n    constexpr int32_t b = -0.642443736562 * 32767;\n    constexpr int32_t a = 1.57030020084 * 32767;\n\n    // Calculate using y = ((c * x^2 + b) * x^2 + a) * x\n    //\n    // The position p is x * 256, so after each multiply with p we need to\n    // shift right by 8 bits to keep the decimal point in the same place.  (The\n    // approximation has a negative error near x=1 which helps avoid overflow.)\n    int32_t p2 = p * p;\n    int32_t u = (c * p2 >> 16) + b;\n    int32_t v = (u * p2 >> 16) + a;\n    int32_t w = v * p >> 8;\n\n    // The result is within 7/32767 or 0.02%, signal-to-error ratio about 38 dB.\n    return position >= 512 ? -w : w;\n}\n\nstatic int sawtoothTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return (position << 6) - 0x7fff;\n}\n\nstatic int triangleTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return position < 512 ? (position << 7) - 0x7fff : ((1023 - position) << 7) - 0x7fff;\n}\n\nstatic int squareWaveTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)cycle;\n    uint8_t wave = sound->currInstr->soundWave;\n    return (int)position < (102 * (wave - SW_SQUARE_10 + 1)) ? -0x7fff : 0x7fff;\n}\n\nstatic int tunedNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a random bit sequence. Since the generator\n    // is called multiple times per wave, use PlayingSound state data to ensure we\n    // only generate a random bit once per wave, and then reuse it for future\n    // calls for that wave.\n    //\n    // Use the low 6 bits of generatorState to store the last-used cycle, and\n    // random_bit to store the last on/off state. (random_bit is arbitrary as\n    // long as it isn't one of the low 6 bits.)\n    constexpr uint32_t random_bit = 0x8000;\n    static uint32_t x = 0xf01ba80; // seed for the static RNG state\n    uint8_t prev_cycle = sound->generatorState & 0x3f;\n    uint32_t is_on;\n    if (cycle == prev_cycle) {\n        is_on = sound->generatorState & random_bit;\n    } else {\n        // see https://en.wikipedia.org/wiki/Xorshift\n        x ^= x << 13;\n        x ^= x >> 17;\n        x ^= x << 5;\n        is_on = (x & random_bit);\n        sound->generatorState = (cycle & 0x3f) | is_on;\n    }\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\n// Bit patterns for use by the cyclic noise tone.\n//\n// The bit pattern is arbitrary, but should have equal numbers of 0 and 1 bits,\n// and should avoid long identical-bit runs for the lower parts. The values below\n// were chosen based on a random permutation of the hex nibbles 0..f and then\n// hand-tweaked by swapping some nibbles. Generated by:\n//\n//   shuf -i 0-15 | perl -ne 's/(\\d+)/printf(\"%x\",$1)/e'\nstatic const uint32_t cycle_bits[] = {0x2df0eb47, 0xc8165a93};\nstatic const uint8_t cycle_mask[] = {0xf, 0x1f, 0x3f};\n\nstatic int cycleNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    // The bit sequence repeats every 16/32/64 waves.\n    //\n    // The \"cycle\" argument corresponds to the sequential number of the generated\n    // wave. This is currently a 6-bit value. Since the pseudorandom bit sequences\n    // evenly fit into this, there's no need to track generator state.\n    uint8_t wave = sound->currInstr->soundWave;\n    int cycle_index = wave - SW_SQUARE_CYCLE_16;\n    // CLAMP(0, cycle_index, sizeof cycle_bits / sizeof cycle_bits[0])\n    cycle &= cycle_mask[cycle_index];\n    bool is_on = (cycle_bits[cycle >> 5] & (1U << (cycle & 0x1f)));\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\nstatic int silenceTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    return 0;\n}\n\nstatic gentone_t getWaveFn(uint8_t wave) {\n    switch (wave) {\n    case SW_TRIANGLE:\n        return triangleTone;\n    case SW_SAWTOOTH:\n        return sawtoothTone;\n    case SW_TUNEDNOISE:\n        return tunedNoiseTone;\n    case SW_NOISE:\n        return noiseTone;\n    case SW_SINE:\n        return sineTone;\n    default:\n        if (SW_SQUARE_10 <= wave && wave <= SW_SQUARE_50)\n            return squareWaveTone;\n        if (SW_SQUARE_CYCLE_16 <= wave && wave <= SW_SQUARE_CYCLE_64)\n            return cycleNoiseTone;\n        else\n            return silenceTone;\n    }\n}\n\n#define CLAMP(lo, v, hi) ((v) = ((v) < (lo) ? (lo) : (v) > (hi) ? (hi) : (v)))\n\nint WSynthesizer::updateQueues() {\n    const int maxTime = 0xffffff;\n    while (1) {\n        WaitingSound *p;\n        int minLeft = maxTime;\n        for (p = waiting; p; p = p->next) {\n            int timeLeft =\n                p->state == SoundState::Waiting ? p->startSampleNo - currSample : maxTime;\n            if (timeLeft <= 0) {\n                break;\n            }\n            if (timeLeft < minLeft)\n                minLeft = timeLeft;\n        }\n        if (p) {\n            PlayingSound *snd;\n            int minIdx = -1;\n            for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n                snd = &playingSounds[i];\n                if (snd->sound == NULL)\n                    break;\n                if (minIdx == -1 ||\n                    playingSounds[minIdx].startSampleNo < playingSounds[i].startSampleNo)\n                    minIdx = i;\n                snd = NULL;\n            }\n            // if we didn't find a free slot, expel the oldest sound\n            if (!snd)\n                snd = &playingSounds[minIdx];\n            if (snd->sound)\n                snd->sound->state = SoundState::Done;\n            snd->sound = p;\n            p->state = SoundState::Playing;\n            snd->startSampleNo = currSample;\n            snd->currInstr = (SoundInstruction *)p->instructions->data;\n            snd->instrEnd = snd->currInstr + p->instructions->length / sizeof(SoundInstruction);\n            snd->prevVolume = -1;\n        } else {\n            // no more sounds to move\n            return minLeft;\n        }\n    }\n}\n\nint WSynthesizer::fillSamples(int16_t *dst, int numsamples) {\n    if (numsamples <= 0)\n        return 1;\n\n    int timeLeft = updateQueues();\n    int res = waiting != NULL;\n\n    // if there's a pending sound to be started somewhere during numsamples,\n    // split the call into two\n    if (timeLeft < numsamples) {\n        fillSamples(dst, timeLeft);\n        LOG(\"M split %d\", timeLeft);\n        fillSamples(dst + timeLeft, numsamples - timeLeft);\n        return 1;\n    }\n\n    memset(dst, 0, numsamples * 2);\n\n    uint32_t samplesPerMS = (sampleRate << 8) / 1000;\n    float toneStepMult = (1024.0 * (1 << 16)) / sampleRate;\n    const int MAXVAL = (1 << (OUTPUT_BITS - 1)) - 1;\n\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        PlayingSound *snd = &playingSounds[i];\n        if (snd->sound == NULL)\n            continue;\n\n        res = 1;\n\n        SoundInstruction *instr = NULL;\n        gentone_t fn = NULL;\n        snd->currInstr--;\n        uint32_t toneStep = 0;\n        int32_t toneDelta = 0;\n        int32_t volumeStep = 0;\n        uint32_t tonePosition = snd->tonePosition;\n        uint32_t samplesLeft = 0;\n        uint8_t wave = 0;\n        int32_t volume = 0;\n\n        for (int j = 0; j < numsamples; ++j) {\n            if (samplesLeft == 0) {\n                snd->currInstr++;\n                if (snd->currInstr >= snd->instrEnd) {\n                    break;\n                }\n                SoundInstruction copy = *snd->currInstr;\n                instr = &copy;\n                CLAMP(20, instr->frequency, 20000);\n                CLAMP(20, instr->endFrequency, 20000);\n                CLAMP(0, instr->startVolume, 1023);\n                CLAMP(0, instr->endVolume, 1023);\n                CLAMP(1, instr->duration, 60000);\n\n                wave = instr->soundWave;\n                fn = getWaveFn(wave);\n\n                samplesLeft = (uint32_t)(instr->duration * samplesPerMS >> 8);\n                // make sure the division is signed\n                volumeStep =\n                    (int)((instr->endVolume - instr->startVolume) << 16) / (int)samplesLeft;\n\n                if (j == 0 && snd->prevVolume != -1) {\n                    // restore previous state\n                    samplesLeft = snd->samplesLeftInCurr;\n                    volume = snd->prevVolume;\n                    toneStep = snd->prevToneStep;\n                    toneDelta = snd->prevToneDelta;\n                } else {\n                    LOG(\"#sampl %d %p\", samplesLeft, snd->currInstr);\n                    volume = instr->startVolume << 16;\n                    LOG(\"%d-%dHz %d-%d vol\", instr->frequency, instr->endFrequency,\n                        instr->startVolume, instr->endVolume);\n                    toneStep = (uint32_t)(toneStepMult * instr->frequency);\n                    if (instr->frequency != instr->endFrequency) {\n                        uint32_t endToneStep = (uint32_t)(toneStepMult * instr->endFrequency);\n                        toneDelta = (int32_t)(endToneStep - toneStep) / (int32_t)samplesLeft;\n                    } else {\n                        toneDelta = 0;\n                    }\n                }\n            }\n\n            int v = fn(snd, (tonePosition >> 16) & 1023, tonePosition >> 26);\n            v = (v * (volume >> 16)) >> (10 + (16 - OUTPUT_BITS));\n\n            // if (v > MAXVAL)\n            //    target_panic(123);\n\n            dst[j] += v;\n\n            tonePosition += toneStep;\n            toneStep += toneDelta;\n            volume += volumeStep;\n            samplesLeft--;\n        }\n\n        if (snd->currInstr >= snd->instrEnd) {\n            snd->sound->state = SoundState::Done;\n            snd->sound = NULL;\n        } else {\n            snd->tonePosition = tonePosition;\n            if (samplesLeft == 0)\n                samplesLeft++; // avoid infinite loop in next iteration\n            snd->samplesLeftInCurr = samplesLeft;\n            snd->prevVolume = volume;\n            snd->prevToneDelta = toneDelta;\n            snd->prevToneStep = toneStep;\n        }\n    }\n\n    currSample += numsamples;\n\n    for (int j = 0; j < numsamples; ++j) {\n        if (dst[j] > MAXVAL)\n            dst[j] = MAXVAL;\n        else if (dst[j] < -MAXVAL)\n            dst[j] = -MAXVAL;\n    }\n\n    return res;\n}\n\n//%\nvoid enableAmp(int enabled) {\n    // this is also compiled on linux\n#ifdef LOOKUP_PIN\n    auto pin = LOOKUP_PIN(SPEAKER_AMP);\n    if (pin) {\n        if (PIN(SPEAKER_AMP) & CFG_PIN_CONFIG_ACTIVE_LO)\n            enabled = !enabled;\n        pin->setDigitalValue(enabled);\n    }\n#endif\n}\n\n//%\nvoid forceOutput(int outp) {\n    auto snd = getWSynthesizer();\n    snd->out.setOutput(outp);\n}\n\n//%\nvoid queuePlayInstructions(int when, Buffer buf) {\n    auto snd = getWSynthesizer();\n\n    registerGCObj(buf);\n\n    auto p = new WaitingSound;\n    p->state = SoundState::Waiting;\n    p->instructions = buf;\n    p->startSampleNo = snd->currSample + when * snd->sampleRate / 1000;\n\n    LOG(\"Queue %dms now=%d off=%d %p sampl:%dHz\", when, snd->currSample,\n        p->startSampleNo - snd->currSample, buf->data, snd->sampleRate);\n\n    target_disable_irq();\n    // add new sound to queue\n    p->next = snd->waiting;\n    snd->waiting = p;\n    // remove sounds that have already been fully played\n    while (p) {\n        while (p->next && p->next->state == SoundState::Done) {\n            auto todel = p->next;\n            p->next = todel->next;\n            unregisterGCObj(todel->instructions);\n            delete todel;\n        }\n        p = p->next;\n    }\n    target_enable_irq();\n\n    snd->poke();\n}\n\n//%\nvoid stopPlaying() {\n    LOG(\"stop playing!\");\n\n    auto snd = getWSynthesizer();\n\n    target_disable_irq();\n    auto p = snd->waiting;\n    snd->waiting = NULL;\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        snd->playingSounds[i].sound = NULL;\n    }\n    while (p) {\n        auto n = p->next;\n        unregisterGCObj(p->instructions);\n        delete p;\n        p = n;\n    }\n    target_enable_irq();\n}\n\nWSynthesizer::WSynthesizer() : upstream(NULL), out(*this) {\n    currSample = 0;\n    active = false;\n    sampleRate = out.dac.getSampleRate();\n    memset(&playingSounds, 0, sizeof(playingSounds));\n    waiting = NULL;\n    PXT_REGISTER_RESET(stopPlaying);\n}\n\n//% promise\nint _createSequencer() {\n    return 0;\n}\n\n//%\nString _sequencerState(int id) {\n    return NULL;\n}\n\n//%\nint _sequencerCurrentTick(int id) {\n    return 0;\n}\n\n//%\nvoid _sequencerPlaySong(int id, Buffer buf, bool loop) {\n}\n\n//%\nvoid _sequencerStop(int id) {\n}\n\n//%\nvoid _sequencerSetVolume(int id, int volume) {\n}\n\n//%\nvoid _sequencerSetVolumeForAll(int volume) {\n}\n\n//%\nvoid _sequencerSetTrackVolume(int id, int trackIndex, int volume) {\n}\n\n//%\nvoid _sequencerSetDrumTrackVolume(int id, int trackIndex, int drumIndex, int volume) {\n}\n\n//%\nvoid _sequencerDispose(int id) {\n}\n\n} // namespace music\n\nnamespace pxt {\nint redirectSamples(int16_t *dst, int numsamples, int samplerate) {\n    auto snd = music::getWSynthesizer();\n    snd->upstream = NULL; // disconnect from regular playback mechanism\n    snd->sampleRate = samplerate;\n    return snd->fillSamples(dst, numsamples);\n}\n\n} // namespace pxt\n\nnamespace jacdac {\n__attribute__((weak)) void setJackRouterOutput(int output) {}\n} // namespace jacdac\n","melody.h":"#pragma once\n\n#ifndef OUTPUT_BITS\n#define OUTPUT_BITS 10\n#endif\n\n#define SW_TRIANGLE 1\n#define SW_SAWTOOTH 2\n#define SW_SINE 3\n#define SW_TUNEDNOISE 4\n#define SW_NOISE 5\n#define SW_SQUARE_10 11\n#define SW_SQUARE_50 15\n#define SW_SQUARE_CYCLE_16 16\n#define SW_SQUARE_CYCLE_32 17\n#define SW_SQUARE_CYCLE_64 18\n\nstruct SoundInstruction {\n    uint8_t soundWave;\n    uint8_t flags;\n    uint16_t frequency;    // Hz\n    uint16_t duration;     // ms\n    int16_t startVolume;   // 0-1023\n    int16_t endVolume;     // 0-1023\n    uint16_t endFrequency; // Hz\n};\n\n#ifdef DATASTREAM_MAXIMUM_BUFFERS\n#define CODAL 1\n#endif\n\nnamespace music {\n\n#define MAX_SOUNDS 8\n\nSTATIC_ASSERT((1 << (16 - OUTPUT_BITS)) > MAX_SOUNDS);\n\nenum class SoundState : uint8_t {\n    Waiting, //\n    Playing, //\n    Done     //\n};\n\nstruct WaitingSound {\n    uint32_t startSampleNo;\n    SoundState state;\n    WaitingSound *next;\n    Buffer instructions;\n};\n\nstruct PlayingSound {\n    uint32_t startSampleNo;\n    uint32_t samplesLeftInCurr;\n    uint32_t tonePosition;\n    int32_t prevVolume;\n    uint32_t prevToneStep;\n    int32_t prevToneDelta;\n    uint32_t generatorState;\n    WaitingSound *sound;\n    SoundInstruction *currInstr, *instrEnd;\n};\n\nclass WSynthesizer\n#ifdef CODAL\n    : public DataSource\n#endif\n{\n  public:\n#ifdef CODAL\n    DataSink *upstream;\n#else\n    void *upstream;\n#endif\n    uint32_t currSample; // after 25h of playing we might get a glitch\n    int32_t sampleRate;  // eg 44100\n    PlayingSound playingSounds[MAX_SOUNDS];\n    WaitingSound *waiting;\n    bool active;\n\n    SoundOutput out;\n\n    int fillSamples(int16_t *dst, int numsamples);\n    int updateQueues();\n\n    WSynthesizer();\n    virtual ~WSynthesizer() {}\n\n    void pokeUpstream() {\n#ifdef CODAL\n        if (upstream) {\n            upstream->pullRequest();\n        }\n#endif\n    }\n\n    void poke() {\n        if (!active) {\n            active = true;\n            pokeUpstream();\n        }\n    }\n\n#ifdef CODAL\n    virtual ManagedBuffer pull() {\n        if (!upstream)\n            return ManagedBuffer();\n        ManagedBuffer data(512);\n        auto dp = (int16_t *)data.getBytes();\n        auto sz = 512 / 2;\n        int r = fillSamples(dp, sz);\n#if defined(NRF52_SERIES)\n        int mul = out.dac.getSampleRange();\n#endif\n        while (sz--) {\n#if defined(NRF52_SERIES)\n            *dp = ((-*dp + (1 << (OUTPUT_BITS - 1))) * mul) >> OUTPUT_BITS;\n#else\n            *dp += 1 << (OUTPUT_BITS - 1);\n#endif\n            dp++;\n        }\n        if (!r) {\n            active = false;\n            // return empty - nothing left to play\n            return ManagedBuffer();\n        }\n        pokeUpstream();\n        return data;\n    }\n    virtual void connect(DataSink &sink) { upstream = &sink; }\n#endif\n};\n\n} // namespace music\n","melody.ts":"enum MusicOutput {\n    AutoDetect = 0,\n    Buzzer = 1,\n    HeadPhones = 2,\n}\n\nnamespace music {\n    //% whenUsed\n    const freqs = hex`\n        1f00210023002500270029002c002e003100340037003a003e004100450049004e00520057005c00620068006e00\n        75007b0083008b0093009c00a500af00b900c400d000dc00e900f70006011501260137014a015d01720188019f01\n        b801d201ee010b022a024b026e029302ba02e40210033f037003a403dc03170455049704dd0427057505c8052006\n        7d06e0064907b8072d08a9082d09b9094d0aea0a900b400cfa0cc00d910e6f0f5a1053115b1272139a14d4152017\n        8018f519801b231dde1e`\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n\n    //% shim=music::stopPlaying\n    function stopPlaying() { }\n\n    //% shim=music::forceOutput\n    export function forceOutput(buf: MusicOutput) { }\n\n    let globalVolume: number = null\n\n    const BUFFER_SIZE: number = 12;\n\n    //% shim=music::enableAmp\n    function enableAmp(en: number) {\n        return // for sim\n    }\n\n    function initVolume() {\n        if (globalVolume === null) {\n            globalVolume = 0\n            setVolume(control.getConfigValue(DAL.CFG_SPEAKER_VOLUME, 128))\n        }\n    }\n\n    /**\n     * Set the default output volume of the sound synthesizer.\n     * @param volume the volume 0...255\n     */\n    //% blockId=synth_set_volume block=\"set volume %volume\"\n    //% parts=\"speaker\"\n    //% volume.min=0 volume.max=255\n    //% volume.defl=20\n    //% help=music/set-volume\n    //% weight=70\n    //% group=\"Volume\"\n    export function setVolume(volume: number): void {\n        globalVolume = Math.clamp(0, 255, volume | 0)\n        enableAmp(globalVolume > 0 ? 1 : 0)\n    }\n\n    /**\n     * Gets the current volume\n     */\n    //% parts=\"speaker\"\n    //% weight=70\n    export function volume(): number {\n        initVolume()\n        return globalVolume;\n    }\n\n    function playNoteCore(when: number, frequency: number, ms: number) {\n        let buf = control.createBuffer(BUFFER_SIZE)\n        addNote(buf, 0, ms, 255, 255, 3, frequency, volume(), frequency)\n        queuePlayInstructions(when, buf)\n    }\n\n    /**\n     * Play a tone through the speaker for some amount of time.\n     * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n     * @param ms tone duration in milliseconds (ms), eg: BeatFraction.Half\n     */\n    //% help=music/play-tone\n    //% blockId=mixer_play_note block=\"play tone|at %note=device_note|for %duration=device_beat\"\n    //% parts=\"headphone\" async\n    //% blockNamespace=music\n    //% weight=76 blockGap=8\n    //% group=\"Tone\"\n    //% deprecated=1\n    export function playTone(frequency: number, ms: number): void {\n        if (ms == 0)\n            ms = 86400000 // 1 day\n\n        if (ms <= 2000) {\n            playNoteCore(0, frequency, ms)\n            pause(ms)\n        } else {\n            const id = ++playToneID\n            control.runInParallel(() => {\n                let pos = control.millis()\n                while (id == playToneID && ms > 0) {\n                    let now = control.millis()\n                    let d = pos - now\n                    let t = Math.min(ms, 500)\n                    ms -= t\n                    pos += t\n                    playNoteCore(d - 1, frequency, t)\n                    if (ms == 0)\n                        pause(d + t)\n                    else\n                        pause(d + t - 100)\n                }\n            })\n        }\n    }\n\n    let playToneID = 0\n\n    /**\n     * Play a melody from the melody editor.\n     * @param melody - string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces,\n     * which will be played one at a time, ex: \"E D G F B A C5 B \"\n     * @param tempo - number in beats per minute (bpm), dictating how long each note will play for\n     */\n    //% block=\"play melody $melody at tempo $tempo|(bpm)\" blockId=playMelody\n    //% blockNamespace=music\n    //% weight=85 blockGap=8 help=music/play-melody\n    //% group=\"Melody\"\n    //% melody.shadow=\"melody_editor\"\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% deprecated=1\n    export function playMelody(melody: string, tempo: number) {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        const song = new Melody(formattedMelody);\n        song.playUntilDone();\n    }\n\n\n    /**\n     * Create a melody with the melody editor.\n     * @param melody\n     */\n    //% block=\"$melody\" blockId=melody_editor\n    //% blockNamespace=music\n    //% blockHidden = true\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Melody\" duplicateShadowOnDrag\n    //% melody.fieldEditor=\"melody\"\n    //% melody.fieldOptions.decompileLiterals=true\n    //% melody.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% melody.fieldOptions.onParentBlock=\"true\"\n    //% shim=TD_ID\n    export function melodyEditor(melody: string): string {\n        return melody;\n    }\n\n    /**\n     * Stop all sounds from playing.\n     */\n    //% help=music/stop-all-sounds\n    //% blockId=music_stop_all_sounds block=\"stop all sounds\"\n    //% weight=45\n    //% group=\"Sounds\"\n    export function stopAllSounds() {\n        Melody.stopAll();\n        stopPlaying();\n        _stopPlayables();\n        sequencer._stopAllSongs();\n    }\n\n    //% fixedInstances\n    export class Melody {\n        _text: string;\n        private _player: MelodyPlayer;\n\n        private static playingMelodies: Melody[];\n\n        static stopAll() {\n            if (Melody.playingMelodies) {\n                const ms = Melody.playingMelodies.slice(0, Melody.playingMelodies.length);\n                ms.forEach(p => p.stop());\n            }\n        }\n\n        constructor(text: string) {\n            this._text = text\n        }\n\n        get text() {\n            return this._text;\n        }\n\n        /**\n         * Stop playing a sound\n         */\n        //% blockId=mixer_stop block=\"stop sound %sound\"\n        //% help=music/melody/stop\n        //% parts=\"headphone\"\n        //% weight=92 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        stop() {\n            if (this._player) {\n                this._player.stop()\n                this._player = null\n            }\n            this.unregisterMelody();\n        }\n\n        private registerMelody() {\n            // keep track of the active players\n            if (!Melody.playingMelodies) Melody.playingMelodies = [];\n            // stop and pop melodies if too many playing\n            if (Melody.playingMelodies.length > 4) {\n                // stop last player (also pops)\n                Melody.playingMelodies[Melody.playingMelodies.length - 1].stop();\n            }\n            // put back the melody on top of the melody stack\n            Melody.playingMelodies.removeElement(this);\n            Melody.playingMelodies.push(this);\n        }\n        private unregisterMelody() {\n            // remove from list\n            if (Melody.playingMelodies) {\n                Melody.playingMelodies.removeElement(this); // remove self\n            }\n        }\n\n        private playCore(volume: number, loop: boolean) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this.registerMelody();\n            control.runInParallel(() => {\n                while (this._player == p) {\n                    p.play(volume)\n                    if (!loop) {\n                        // Unregister the melody when done playing, but\n                        // only if it hasn't been restarted. (Looping\n                        // melodies never stop on their own, they only\n                        // get unregistered via stop().)\n                        if (this._player == p) {\n                            this.unregisterMelody();\n                        }\n                        break\n                    }\n                }\n            })\n        }\n\n        /**\n         * Start playing a sound in a loop and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/loop\n        //% blockId=mixer_loop_sound block=\"loop sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=93 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        loop(volume = 255) {\n            this.playCore(volume, true)\n        }\n\n        /**\n         * Start playing a sound and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play\n        //% blockId=mixer_play_sound block=\"play sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=95 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        play(volume = 255) {\n            this.playCore(volume, false)\n        }\n\n\n        /**\n         * Play a sound and wait until the sound is done.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play-until-done\n        //% blockId=mixer_play_sound_until_done block=\"play sound %sound|until done\"\n        //% parts=\"headphone\"\n        //% weight=94 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        playUntilDone(volume = 255) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this._player.onPlayFinished = () => {\n                if (p == this._player)\n                    this.unregisterMelody();\n            }\n            this.registerMelody();\n            this._player.play(volume)\n        }\n\n        toString() {\n            return this._text;\n        }\n    }\n\n    export function addNote(sndInstr: Buffer, sndInstrPtr: number, ms: number, beg: number, end: number, soundWave: number, hz: number, volume: number, endHz: number) {\n        if (ms > 0) {\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, soundWave)\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr + 1, 0)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 2, hz)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 4, ms)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 6, (beg * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 8, (end * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 10, endHz);\n            sndInstrPtr += BUFFER_SIZE;\n        }\n        sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, 0) // terminate\n        return sndInstrPtr\n    }\n\n\n    export class MelodyPlayer {\n        melody: Melody;\n\n        onPlayFinished: () => void;\n\n        constructor(m: Melody) {\n            this.melody = m\n        }\n\n        stop() {\n            this.melody = null\n        }\n\n        protected queuePlayInstructions(timeDelta: number, buf: Buffer) {\n            queuePlayInstructions(timeDelta, buf)\n        }\n\n        play(volume: number) {\n            if (!this.melody)\n                return\n            volume = Math.clamp(0, 255, (volume * music.volume()) >> 8)\n\n            let notes = this.melody._text\n            let pos = 0;\n            let duration = 4; //Default duration (Crotchet)\n            let octave = 4; //Middle octave\n            let tempo = 120; // default tempo\n\n            let hz = 0\n            let endHz = -1\n            let ms = 0\n            let timePos = 0\n            let startTime = control.millis()\n            let now = 0\n\n            let envA = 0\n            let envD = 0\n            let envS = 255\n            let envR = 0\n            let soundWave = 1 // triangle\n            let sndInstr = control.createBuffer(5 * BUFFER_SIZE)\n            let sndInstrPtr = 0\n\n            const addForm = (formDuration: number, beg: number, end: number, msOff: number) => {\n                let freqStart = hz;\n                let freqEnd = endHz;\n\n                const envelopeWidth = ms > 0 ? ms : duration * Math.idiv(15000, tempo) + envR;\n                if (endHz != hz && envelopeWidth != 0) {\n                    const slope = (freqEnd - freqStart) / envelopeWidth;\n                    freqStart = hz + slope * msOff;\n                    freqEnd = hz + slope * (msOff + formDuration);\n                }\n                sndInstrPtr = addNote(sndInstr, sndInstrPtr, formDuration, beg, end, soundWave, freqStart, volume, freqEnd);\n            }\n\n            const scanNextWord = () => {\n                if (!this.melody)\n                    return \"\"\n\n                // eat space\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c != ' ' && c != '\\r' && c != '\\n' && c != '\\t')\n                        break;\n                    pos++;\n                }\n\n                // read note\n                let note = \"\";\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c == ' ' || c == '\\r' || c == '\\n' || c == '\\t')\n                        break;\n                    note += c;\n                    pos++;\n                }\n                return note;\n            }\n\n            enum Token {\n                Note,\n                Octave,\n                Beat,\n                Tempo,\n                Hz,\n                EndHz,\n                Ms,\n                WaveForm,\n                EnvelopeA,\n                EnvelopeD,\n                EnvelopeS,\n                EnvelopeR\n            }\n\n            let token: string = \"\";\n            let tokenKind = Token.Note;\n\n            // [ABCDEFG] (\\d+)  (:\\d+)  (-\\d+)\n            // note      octave length  tempo\n            // R (:\\d+) - rest\n            // !\\d+,\\d+ - sound at frequency with given length (Hz,ms); !\\d+ and !\\d+,:\\d+ also possible\n            // @\\d+,\\d+,\\d+,\\d+ - ADSR envelope - ms,ms,volume,ms; volume is 0-255\n            // ~\\d+ - wave form:\n            //   1 - triangle\n            //   2 - sawtooth\n            //   3 - sine\n            //   4 - pseudorandom square wave noise (tunable)\n            //   5 - white noise (ignores frequency)\n            //   11 - square 10%\n            //   12 - square 20%\n            //   ...\n            //   15 - square 50%\n            //   16 - filtered square wave, cycle length 16\n            //   17 - filtered square wave, cycle length 32\n            //   18 - filtered square wave, cycle length 64\n\n            const consumeToken = () => {\n                if (token && tokenKind != Token.Note) {\n                    const d = parseInt(token);\n                    switch (tokenKind) {\n                        case Token.Octave: octave = d; break;\n                        case Token.Beat:\n                            duration = Math.max(1, Math.min(16, d));\n                            ms = -1;\n                            break;\n                        case Token.Tempo: tempo = Math.max(1, d); break;\n                        case Token.Hz: hz = d; tokenKind = Token.Ms; break;\n                        case Token.Ms: ms = d; break;\n                        case Token.WaveForm: soundWave = Math.clamp(1, 18, d); break;\n                        case Token.EnvelopeA: envA = d; tokenKind = Token.EnvelopeD; break;\n                        case Token.EnvelopeD: envD = d; tokenKind = Token.EnvelopeS; break;\n                        case Token.EnvelopeS: envS = Math.clamp(0, 255, d); tokenKind = Token.EnvelopeR; break;\n                        case Token.EnvelopeR: envR = d; break;\n                        case Token.EndHz: endHz = d; break;\n                    }\n                    token = \"\";\n                }\n            }\n\n            while (true) {\n                let currNote = scanNextWord();\n                let prevNote: boolean = false;\n                if (!currNote) {\n                    let timeLeft = timePos - now\n                    if (timeLeft > 0)\n                        pause(timeLeft)\n                    if (this.onPlayFinished)\n                        this.onPlayFinished();\n                    return;\n                }\n\n                hz = -1;\n\n                let note: number = 0;\n                token = \"\";\n                tokenKind = Token.Note;\n\n                for (let i = 0; i < currNote.length; i++) {\n                    let noteChar = currNote.charAt(i);\n                    switch (noteChar) {\n                        case 'c': case 'C': note = 1; prevNote = true; break;\n                        case 'd': case 'D': note = 3; prevNote = true; break;\n                        case 'e': case 'E': note = 5; prevNote = true; break;\n                        case 'f': case 'F': note = 6; prevNote = true; break;\n                        case 'g': case 'G': note = 8; prevNote = true; break;\n                        case 'a': case 'A': note = 10; prevNote = true; break;\n                        case 'B': note = 12; prevNote = true; break;\n                        case 'r': case 'R': hz = 0; prevNote = false; break;\n                        case '#': note++; prevNote = false; break;\n                        case 'b': if (prevNote) note--; else { note = 12; prevNote = true; } break;\n                        case ',':\n                            consumeToken();\n                            prevNote = false;\n                            break;\n                        case '!':\n                            tokenKind = Token.Hz;\n                            prevNote = false;\n                            break;\n                        case '@':\n                            consumeToken();\n                            tokenKind = Token.EnvelopeA;\n                            prevNote = false;\n                            break;\n                        case '~':\n                            consumeToken();\n                            tokenKind = Token.WaveForm;\n                            prevNote = false;\n                            break;\n                        case ':':\n                            consumeToken();\n                            tokenKind = Token.Beat;\n                            prevNote = false;\n                            break;\n                        case '-':\n                            consumeToken();\n                            tokenKind = Token.Tempo;\n                            prevNote = false;\n                            break;\n                        case '^':\n                            consumeToken();\n                            tokenKind = Token.EndHz;\n                            break;\n                        default:\n                            if (tokenKind == Token.Note)\n                                tokenKind = Token.Octave;\n                            token += noteChar;\n                            prevNote = false;\n                            break;\n                    }\n                }\n                consumeToken();\n\n                if (note && hz < 0) {\n                    const keyNumber = note + (12 * (octave - 1));\n                    hz = freqs.getNumber(NumberFormat.UInt16LE, keyNumber * 2) || 0;\n                }\n\n                let currMs = ms\n\n                if (currMs <= 0) {\n                    const beat = Math.idiv(15000, tempo);\n                    currMs = duration * beat\n                }\n\n                if (hz < 0) {\n                    // no frequency specified, so no duration\n                } else if (hz == 0) {\n                    timePos += currMs\n                } else {\n                    if (endHz < 0) {\n                        endHz = hz;\n                    }\n\n                    sndInstrPtr = 0\n                    addForm(envA, 0, 255, 0)\n                    addForm(envD, 255, envS, envA)\n                    addForm(currMs - (envA + envD), envS, envS, envD + envA)\n                    addForm(envR, envS, 0, currMs)\n\n                    this.queuePlayInstructions(timePos - now, sndInstr.slice(0, sndInstrPtr))\n                    endHz = -1;\n                    timePos += currMs // don't add envR - it's supposed overlap next sound\n                }\n\n                let timeLeft = timePos - now\n                if (timeLeft > 200) {\n                    pause(timeLeft - 100)\n                    now = control.millis() - startTime\n                }\n            }\n        }\n    }\n\n    //% blockId=music_song_field_editor\n    //% block=\"song $song\"\n    //% song.fieldEditor=musiceditor\n    //% song.fieldOptions.decompileLiterals=true\n    //% song.fieldOptions.taggedTemplate=\"hex;assets.song\"\n    //% song.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% song.fieldOptions.decompileArgumentAsString=\"true\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% help=music/create-song\n    export function createSong(song: Buffer): Playable {\n        return new sequencer.Song(song);\n    }\n\n    export function playInstructions(when: number, instructions: Buffer) {\n        queuePlayInstructions(when, instructions);\n    }\n\n    export function lookupFrequency(note: number) {\n        return freqs.getNumber(NumberFormat.UInt16LE, note * 2) || 0\n    }\n\n    //% fixedInstance whenUsed block=\"ba ding\"\n    export const baDing = new Melody('b5:1 e6:3')\n\n    //% fixedInstance whenUsed block=\"wawawawaa\"\n    export const wawawawaa = new Melody('~15 e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8')\n\n    //% fixedInstance whenUsed block=\"jump up\"\n    export const jumpUp = new Melody('c5:1 d e f g')\n\n    //% fixedInstance whenUsed block=\"jump down\"\n    export const jumpDown = new Melody('g5:1 f e d c')\n\n    //% fixedInstance whenUsed block=\"power up\"\n    export const powerUp = new Melody('g4:1 c5 e g:2 e:1 g:3')\n\n    //% fixedInstance whenUsed block=\"power down\"\n    export const powerDown = new Melody('g5:1 d# c g4:2 b:1 c5:3')\n\n    //% fixedInstance whenUsed block=\"magic wand\"\n    export const magicWand = new Melody('F#6:1-300 G# A# B C7# D# F F# G# A# B:6')\n    //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n\n    //% fixedInstance whenUsed block=\"siren\"\n    export const siren = new Melody('a4 d5 a4 d5 a4 d5')\n\n    //% fixedInstance whenUsed block=\"pew pew\"\n    export const pewPew = new Melody('!1200,200^50')\n\n    //% fixedInstance whenUsed block=\"knock\"\n    export const knock = new Melody('~4 @0,0,255,150 !300,1 !211,1')\n\n    //% fixedInstance whenUsed block=\"footstep\"\n    export const footstep = new Melody('~4 @0,0,60,50 !200,1')\n\n    //% fixedInstance whenUsed block=\"thump\"\n    export const thump = new Melody('~4 @0,0,255,150 !100,1')\n\n    //% fixedInstance whenUsed block=\"small crash\"\n    export const smallCrash = new Melody('~4 @10,490,0,1 !800,1')\n\n    //% fixedInstance whenUsed block=\"big crash\"\n    export const bigCrash = new Melody('~4 @10,990,0,1 !400,1')\n\n    //% fixedInstance whenUsed block=\"zapped\"\n    export const zapped = new Melody('~16 @10,490,0,0 !1600,500^1')\n\n    //% fixedInstance whenUsed block=\"buzzer\"\n    export const buzzer = new Melody('~16 @10,0,255,250 !2000,300')\n\n    //% fixedInstance whenUsed block=\"sonar\"\n    export const sonar = new Melody('~16 @10,1500,0,0 !200,1 !200,1500^190')\n\n    //% fixedInstance whenUsed block=\"spooky\"\n    export const spooky = new Melody('~16 @700,1300,0,0 !100,1 ~18 !108,2000')\n\n    //% fixedInstance whenUsed block=\"beam up\"\n    export const beamUp = new Melody('~18 @10,1500,0,0 !200,1500^4000')\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    //% block=\"2\"\n    Double = 32,\n    //% block=\"4\",\n    Breve = 64,\n    //% block=\"1/3\",\n    Triplet = 128\n}\n\nnamespace music {\n\n    let beatsPerMinute: number;\n\n    /**\n    * Play a tone.\n    * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n    */\n    //% help=music/ring-tone\n    //% blockId=music_ring block=\"ring tone|at %note=device_note\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music inBasicCategory=true\n    //% weight=75 blockGap=8\n    //% group=\"Tone\"\n    export function ringTone(frequency: number) {\n        playTone(frequency, 0);\n    }\n\n    /**\n    * Rest, or play silence, for some time (in milliseconds).\n    * @param ms rest duration in milliseconds (ms), eg: BeatFraction.Half\n    */\n    //% help=music/rest\n    //% blockId=music_rest block=\"rest|for %duration=device_beat\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music\n    //% weight=74\n    //% group=\"Tone\"\n    export function rest(ms: number) {\n        playTone(0, Math.max(ms, 20));\n    }\n\n    function init() {\n        if (!beatsPerMinute) beatsPerMinute = 120;\n    }\n\n    /**\n     * Return the duration of a beat in milliseconds (the beat fraction).\n     * @param fraction the fraction of the current whole note, eg: BeatFraction.Half\n     */\n    //% help=music/beat\n    //% blockId=device_beat block=\"%fraction|beat\"\n    //% weight=9 blockGap=8\n    //% group=\"Tempo\"\n    export function beat(fraction?: BeatFraction): number {\n        init();\n        if (fraction == null) fraction = BeatFraction.Whole;\n        let beat = 60000 / beatsPerMinute;\n        switch (fraction) {\n            case BeatFraction.Half: beat /= 2; break;\n            case BeatFraction.Quarter: beat /= 4; break;\n            case BeatFraction.Eighth: beat /= 8; break;\n            case BeatFraction.Sixteenth: beat /= 16; break;\n            case BeatFraction.Double: beat *= 2; break;\n            case BeatFraction.Breve: beat *= 4; break;\n            case BeatFraction.Triplet: beat /= 3; break;\n        }\n        return beat >> 0;\n    }\n\n    /**\n     * Return the tempo in beats per minute (bpm).\n     * 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\n    //% blockId=device_tempo block=\"tempo (bpm)\"\n    //% weight=64\n    //% group=\"Tempo\"\n    export function tempo(): number {\n        init();\n        return beatsPerMinute;\n    }\n\n    /**\n     * Change the tempo up or down by some amount of beats per minute (bpm).\n     * @param bpm The change in beats per minute to the tempo, eg: 20\n     */\n    //% help=music/change-tempo-by weight=37\n    //% blockId=device_change_tempo block=\"change tempo by %value|(bpm)\"\n    //% weight=66 blockGap=8\n    //% group=\"Tempo\"\n    export function changeTempoBy(bpm: number): void {\n        init();\n        setTempo(beatsPerMinute + bpm);\n    }\n\n    /**\n     * Set the tempo a number of beats per minute (bpm).\n     * @param bpm The new tempo in beats per minute, eg: 120\n     */\n    //% help=music/set-tempo\n    //% blockId=device_set_tempo block=\"set tempo to %value|(bpm)\"\n    //% bpm.min=4 bpm.max=400\n    //% weight=65 blockGap=8\n    //% group=\"Tempo\"\n    export function setTempo(bpm: number): void {\n        init();\n        if (bpm > 0) {\n            beatsPerMinute = Math.max(1, bpm >> 0);\n        }\n    }\n}\n","ns.ts":"\n/**\n * Generation of music tones.\n */\n//% color=#E30FC0 weight=90 icon=\"\\uf025\"\n//% blockGap=8\n//% groups='[\"Songs\", \"Sounds\", \"Tone\",  \"Volume\", \"Tempo\"]'\nnamespace music {\n}","piano.ts":"namespace music {\n    /**\n     * Get the frequency of a note.\n     * @param name the note name, eg: Note.C\n     */\n    //% weight=1 help=music/note-frequency\n    //% blockId=device_note block=\"%note\"\n    //% shim=TD_ID\n    //% color=\"#FFFFFF\" colorSecondary=\"#FFFFFF\" colorTertiary=\"#D83B01\"\n    //% note.fieldEditor=\"note\" note.defl=\"262\"\n    //% note.fieldOptions.decompileLiterals=true\n    //% useEnumVal=1\n    //% weight=10 blockGap=8\n    //% group=\"Tone\"\n    export function noteFrequency(name: Note): number {\n        return name;\n    }\n}","playable.ts":"namespace music {\n    export enum PlaybackMode {\n        //% block=\"until done\"\n        UntilDone,\n        //% block=\"in background\"\n        InBackground,\n        //% block=\"looping in background\"\n        LoopingInBackground\n    }\n\n    let stateStack: PlayableState[];\n\n    class PlayableState {\n        looping: Playable[];\n        constructor() {\n            this.looping = [];\n        }\n\n        stopLooping() {\n            for (const p of this.looping) {\n                p.stopped = true;\n            }\n            this.looping = [];\n        }\n    }\n\n    function state() {\n        _init();\n        return stateStack[stateStack.length - 1];\n    }\n\n    function _init() {\n        if (stateStack) return;\n        stateStack = [new PlayableState()];\n\n        game.addScenePushHandler(() => {\n            stateStack.push(new PlayableState());\n        });\n\n        game.addScenePopHandler(() => {\n            stateStack.pop();\n            if (stateStack.length === 0) stateStack.push(new PlayableState());\n        });\n    }\n\n    export class Playable {\n        stopped: boolean;\n        constructor() {\n\n        }\n\n        play(playbackMode: PlaybackMode) {\n            // subclass\n        }\n\n        loop() {\n            state().looping.push(this);\n            this.stopped = false;\n\n            control.runInParallel(() => {\n                while (!this.stopped) {\n                    this.play(PlaybackMode.UntilDone);\n                }\n            });\n        }\n    }\n\n    export class MelodyPlayable extends Playable {\n        constructor(public melody: Melody) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                this.melody.play(music.volume());\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                this.melody.playUntilDone(music.volume());\n            }\n            else {\n                this.melody.loop(music.volume());\n            }\n        }\n    }\n\n    export class TonePlayable extends Playable {\n        constructor(public pitch: number, public duration: number) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                control.runInParallel(() => music.playTone(this.pitch, this.duration));\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                music.playTone(this.pitch, this.duration);\n                if (this.duration > 2000) {\n                    pause(this.duration);\n                }\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n    /**\n     * Play a song, melody, or other sound. The music plays until finished or can play as a\n     * background task.\n     * @param toPlay the song or melody to play\n     * @param playbackMode play the song or melody until it's finished or as background task\n     */\n    //% blockId=\"music_playable_play\"\n    //% block=\"play $toPlay $playbackMode\"\n    //% toPlay.shadow=music_melody_playable\n    //% group=\"Sounds\"\n    //% help=\"music/play\"\n    export function play(toPlay: Playable, playbackMode: PlaybackMode) {\n        toPlay.play(playbackMode);\n    }\n\n    /**\n     * Create a Playable object for a melody.\n     * @param melody the melody to make playable\n     */\n    //% blockId=\"music_melody_playable\"\n    //% block=\"sound $melody\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    //% blockHidden\n    //% help=music/melody-playable\n    export function melodyPlayable(melody: Melody): Playable {\n        return new MelodyPlayable(melody);\n    }\n\n    /**\n     * Create a Playable object for a melody string containg notes.\n     * @param melody the melody string to make playable\n     */\n    //% blockId=\"music_string_playable\"\n    //% block=\"melody $melody at tempo $tempo|(bpm)\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% melody.shadow=melody_editor\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% help=music/string-playable\n    export function stringPlayable(melody: string, tempo: number): Playable {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        return new MelodyPlayable(new Melody(formattedMelody));\n    }\n\n    /**\n     * Create a Playable object for a single tone and its duration.\n     * @param note the note or tone frequency to play\n     * @param duration the duration of the tone in milliseconds (ms)\n     */\n    //% blockId=\"music_tone_playable\"\n    //% block=\"tone $note for $duration\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Tone\"\n    //% duplicateShadowOnDrag\n    //% note.shadow=device_note\n    //% duration.shadow=device_beat\n    //% parts=\"headphone\"\n    //% help=music/tone-playable\n    export function tonePlayable(note: number, duration: number): Playable {\n        return new TonePlayable(note, duration);\n    }\n\n    export function _stopPlayables() {\n        state().stopLooping();\n    }\n}","pxt.json":"{\n    \"name\": \"mixer---linux\",\n    \"description\": \"The music library with a mixer\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"SoundOutput.h\",\n        \"sound.cpp\",\n        \"melody.h\",\n        \"melody.cpp\",\n        \"melody.ts\",\n        \"piano.ts\",\n        \"legacy.ts\",\n        \"ns.ts\",\n        \"targetoverrides.ts\",\n        \"music.ts\",\n        \"soundEffect.ts\",\n        \"instrument.ts\",\n        \"sequencer.ts\",\n        \"playable.ts\",\n        \"pxtparts.json\",\n        \"headphone.svg\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","pxtparts.json":"{\n    \"headphone\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"image\": \"headphone.svg\",\n            \"width\": 142,\n            \"height\": 180,\n            \"pinDistance\": 20,\n            \"pinLocations\": [\n                {\n                    \"x\": 17,\n                    \"y\": 11\n                },\n                {\n                    \"x\": 55,\n                    \"y\": 50\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"A0\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","sequencer.ts":"namespace music.sequencer {\n    const SEQUENCER_STOP_MESSAGE = 3243;\n    const SEQUENCER_TICK_MESSAGE = 3244;\n    const SEQUENCER_STATE_CHANGE_MESSAGE = 3245;\n    const SEQUENCER_LOOPED_MESSAGE = 3246;\n\n    export class Sequencer {\n        currentTick: number;\n        isPlaying: boolean;\n        isLooping: boolean;\n        isRunning: boolean;\n\n        constructor(public song: Song) {\n            this.currentTick = 0;\n            this.isPlaying = false;\n            this.isLooping = false;\n        }\n\n        start(loop: boolean) {\n            this.currentTick = 0;\n            this.isLooping = loop;\n            this.isPlaying = true;\n\n            if (this.isRunning) return;\n            this.isRunning = true;\n\n            control.runInParallel(() => {\n                while (this.isPlaying) {\n                    this.scheduleCurrentTick();\n\n                    this.currentTick ++;\n\n                    if (this.currentTick >= this.song.beatsPerMeasure * this.song.measures * this.song.ticksPerBeat) {\n                        if (this.isLooping) this.currentTick = 0;\n                        else this.isPlaying = false;\n                    }\n\n                    pause(this.tickToMs(1))\n                }\n                this.isRunning = false;\n            })\n        }\n\n        stop() {\n            this.isPlaying = false;\n        }\n\n        tickToMs(ticks: number) {\n            return ((60000 / this.song.beatsPerMinute) / this.song.ticksPerBeat) * ticks;\n        }\n\n        protected scheduleCurrentTick() {\n            for (const track of this.song.tracks) {\n                if (track.currentNoteEvent.startTick === this.currentTick) {\n                    if (track.isMelodicTrack) {\n                        this.scheduleMelodicTrack(track as MelodicTrack);\n                    }\n                    else {\n                        this.scheduleDrumTrack(track as DrumTrack);\n                    }\n\n                    track.advanceNoteEvent();\n                }\n            }\n        }\n\n        protected scheduleMelodicTrack(track: MelodicTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderInstrument(\n                        track.instrument,\n                        lookupFrequency(track.currentNoteEvent.getNote(i, track.instrument.octave)),\n                        this.tickToMs(track.currentNoteEvent.endTick - track.currentNoteEvent.startTick),\n                        music.volume()\n                    )\n                );\n            }\n        }\n\n        protected scheduleDrumTrack(track: DrumTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderDrumInstrument(\n                        track.drums[track.currentNoteEvent.getNote(i, undefined)],\n                        music.volume()\n                    )\n                );\n            }\n        }\n    }\n\n    let activeSimSequencers: _SimulatorSequencer[];\n    export function _stopAllSimSequencers() {\n        if (activeSimSequencers) {\n            for (const seq of activeSimSequencers) {\n                seq.stop();\n                seq.dispose();\n            }\n            activeSimSequencers = [];\n        }\n    }\n\n    // Simulator only! Does nothing on hardware\n    export class _SimulatorSequencer {\n        protected id: number;\n\n        constructor() {\n            if (!activeSimSequencers) activeSimSequencers = [];\n            activeSimSequencers.push(this);\n            this.id = _createSequencer();\n            this.setVolume(music.volume());\n        }\n\n        play(song: Buffer, loop: boolean) {\n            this.setVolume(music.volume());\n            _sequencerPlaySong(this.id, song, loop)\n        }\n\n        stop() {\n            _sequencerStop(this.id);\n        }\n\n        setVolume(volume: number) {\n            _sequencerSetVolume(this.id, volume);\n        }\n\n        setTrackVolume(trackIndex: number, volume: number) {\n            _sequencerSetTrackVolume(this.id, trackIndex, volume)\n        }\n\n        setDrumTrackVolume(trackIndex: number, drumIndex: number, volume: number) {\n            _sequencerSetDrumTrackVolume(this.id, drumIndex, trackIndex, volume)\n        }\n\n        state() {\n            return _sequencerState(this.id) || \"stop\";\n        }\n\n        currentTick() {\n            return _sequencerCurrentTick(this.id);\n        }\n\n        dispose() {\n            _sequencerDispose(this.id);\n        }\n\n        onTick(handler: (tick: number) => void) {\n            control.onEvent(SEQUENCER_TICK_MESSAGE, this.id, () => {\n                handler(this.currentTick());\n            });\n        }\n\n        onStateChange(handler: (state: string) => void) {\n            control.onEvent(SEQUENCER_STATE_CHANGE_MESSAGE, this.id, () => {\n                handler(this.state());\n            });\n        }\n\n        onStop(handler: () => void) {\n            control.onEvent(SEQUENCER_STOP_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n\n        onLooped(handler: () => void) {\n            control.onEvent(SEQUENCER_LOOPED_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n    }\n\n    //% promise\n    //% shim=music::_createSequencer\n    declare function _createSequencer(): number\n\n    //% shim=music::_sequencerState\n    declare function _sequencerState(id: number): string;\n\n    //% shim=music::_sequencerCurrentTick\n    declare function _sequencerCurrentTick(id: number): number;\n\n    //% shim=music::_sequencerPlaySong\n    declare function _sequencerPlaySong(id: number, song: Buffer, loop: boolean): void;\n\n    //% shim=music::_sequencerStop\n    declare function _sequencerStop(id: number): void;\n\n    //% shim=music::_sequencerSetVolume\n    declare function _sequencerSetVolume(id: number, volume: number): void;\n\n    //% shim=music::_sequencerSetVolumeForAll\n    declare function _sequencerSetVolumeForAll(volume: number): void;\n\n    //% shim=music::_sequencerSetTrackVolume\n    declare function _sequencerSetTrackVolume(id: number, trackIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerSetDrumTrackVolume\n    declare function _sequencerSetDrumTrackVolume(id: number, trackIndex: number, drumIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerDispose\n    declare function _sequencerDispose(id: number): void;\n}","sound.cpp":"#include \"pxt.h\"\n#include \"SoundOutput.h\"\n#include \"melody.h\"\n\n#include <alsa/asoundlib.h>\n#include <pthread.h>\n\nnamespace music {\n\nstatic void alsa_check(int pos, int fn) {\n    if (fn < 0) {\n        DMESG(\"alsa fail! pos=%d err=%d: %s\", pos, fn, snd_strerror(fn));\n        target_panic(950);\n    }\n}\n\nvoid *LinuxDAC::play(void *self) {\n    auto dac = (LinuxDAC *)self;\n\n    snd_pcm_t *pcm_handle;\n\n    sleep_core_us(1000 * 1000);\n\n    alsa_check(0, snd_pcm_open(&pcm_handle, \"default\", SND_PCM_STREAM_PLAYBACK, 0));\n\n    alsa_check(1, snd_pcm_set_params(pcm_handle, SND_PCM_FORMAT_S16_LE,\n                                     SND_PCM_ACCESS_RW_INTERLEAVED, 1, SAMPLE_RATE, 1, 30 * 1000));\n\n    DMESG(\"PCM name: '%s'\", snd_pcm_name(pcm_handle));\n    DMESG(\"PCM state: %s\", snd_pcm_state_name(snd_pcm_state(pcm_handle)));\n\n    for (;;) {\n        target_disable_irq();\n        auto hasData = dac->src.fillSamples(dac->data, sizeof(dac->data) / 2);\n        target_enable_irq();\n        auto len = (int)sizeof(dac->data) / 2;\n        if (!hasData) {\n            sleep_core_us(5000);\n            continue;\n        }\n        for (int i = 0; i < len; ++i) {\n            // playing at half-volume\n            dac->data[i] = dac->data[i] << 3;\n        }\n        int frames = snd_pcm_writei(pcm_handle, dac->data, len);\n        if (frames < 0)\n            frames = snd_pcm_recover(pcm_handle, frames, 0);\n        if (frames < 0) {\n            DMESG(\"alsa write faield: %s\", snd_strerror(frames));\n            target_panic(951);\n        }\n    }\n\n    return NULL;\n}\n\nLinuxDAC::LinuxDAC(WSynthesizer &data) : src(data) {\n    pthread_t upd;\n    pthread_create(&upd, NULL, LinuxDAC::play, this);\n    pthread_detach(upd);\n}\n\n}","soundEffect.ts":"enum WaveShape {\n    //% block=\"sine\"\n    Sine = 0,\n    //% block=\"sawtooth\"\n    Sawtooth = 1,\n    //% block=\"triangle\"\n    Triangle = 2,\n    //% block=\"square\"\n    Square = 3,\n    //% block=\"noise\"\n    Noise = 4\n}\n\nenum InterpolationCurve {\n    //% block=\"linear\"\n    Linear,\n    //% block=\"curve\"\n    Curve,\n    //% block=\"logarithmic\"\n    Logarithmic\n}\n\nenum SoundExpressionEffect {\n    //% block=\"none\"\n    None = 0,\n    //% block=\"vibrato\"\n    Vibrato = 1,\n    //% block=\"tremolo\"\n    Tremolo = 2,\n    //% block=\"warble\"\n    Warble = 3\n}\n\nenum SoundExpressionPlayMode {\n    //% block=\"until done\"\n    UntilDone,\n    //% block=\"in background\"\n    InBackground\n}\n\nnamespace music {\n    export class SoundEffect extends Playable {\n        waveShape: WaveShape;\n        startFrequency: number;\n        endFrequency: number;\n        startVolume: number;\n        endVolume: number;\n        duration: number;\n        effect: SoundExpressionEffect;\n        interpolation: InterpolationCurve;\n\n        constructor() {\n            super();\n            this.waveShape = WaveShape.Sine;\n            this.startFrequency = 5000;\n            this.endFrequency = 1;\n            this.startVolume = 255;\n            this.endVolume = 0;\n            this.duration = 1000;\n            this.effect = SoundExpressionEffect.None;\n            this.interpolation = InterpolationCurve.Linear;\n        }\n\n        toBuffer(volume?: number) {\n            if (volume === undefined) volume = music.volume();\n\n            return soundToInstructionBuffer(\n                this.waveShape,\n                this.startFrequency,\n                this.endFrequency,\n                this.startVolume,\n                this.endVolume,\n                this.duration,\n                this.effect,\n                this.interpolation,\n                20,\n                1,\n                volume\n            );\n        }\n\n        play(playbackMode: PlaybackMode) {\n            const toPlay = this.toBuffer(music.volume());\n            if (playbackMode === PlaybackMode.InBackground) {\n                queuePlayInstructions(0, toPlay);\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                queuePlayInstructions(0, toPlay);\n                pause(this.duration)\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n\n    /**\n     * Play a SoundEffect.\n     * @param sound the SoundEffect to play\n     * @param mode the play mode, play until done or in the background\n     */\n    //% blockId=soundExpression_playSoundEffect\n    //% block=\"play sound $sound $mode\"\n    //% weight=30\n    //% help=music/play-sound-effect\n    //% blockGap=8\n    //% group=\"Sounds\"\n    //% deprecated=1\n    export function playSoundEffect(sound: SoundEffect, mode: SoundExpressionPlayMode) {\n        const toPlay = sound.toBuffer(music.volume());\n\n        queuePlayInstructions(0, toPlay);\n        if (mode === SoundExpressionPlayMode.UntilDone) {\n            pause(sound.duration);\n        }\n    }\n\n    /**\n     * Create a sound expression from a set of sound effect parameters.\n     * @param waveShape waveform of the sound effect\n     * @param startFrequency starting frequency for the sound effect waveform\n     * @param endFrequency ending frequency for the sound effect waveform\n     * @param startVolume starting volume of the sound, or starting amplitude\n     * @param endVolume ending volume of the sound, or ending amplitude\n     * @param duration the amount of time in milliseconds (ms) that sound will play for\n     * @param effect the effect to apply to the waveform or volume\n     * @param interpolation interpolation method for frequency scaling\n     */\n    //% blockId=soundExpression_createSoundEffect\n    //% help=music/create-sound-effect\n    //% block=\"$waveShape|| start frequency $startFrequency end frequency $endFrequency duration $duration start volume $startVolume end volume $endVolume effect $effect interpolation $interpolation\"\n    //% waveShape.defl=WaveShape.Sine\n    //% waveShape.fieldEditor=soundeffect\n    //% waveShape.fieldOptions.useMixerSynthesizer=true\n    //% startFrequency.defl=5000\n    //% startFrequency.min=0\n    //% startFrequency.max=5000\n    //% endFrequency.defl=0\n    //% endFrequency.min=0\n    //% endFrequency.max=5000\n    //% startVolume.defl=255\n    //% startVolume.min=0\n    //% startVolume.max=255\n    //% endVolume.defl=0\n    //% endVolume.min=0\n    //% endVolume.max=255\n    //% duration.defl=500\n    //% duration.min=1\n    //% duration.max=9999\n    //% effect.defl=SoundExpressionEffect.None\n    //% interpolation.defl=InterpolationCurve.Linear\n    //% compileHiddenArguments=true\n    //% inlineInputMode=\"variable\"\n    //% inlineInputModeLimit=3\n    //% expandableArgumentBreaks=\"3,5\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=20\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    export function createSoundEffect(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve): SoundEffect {\n        const result = new SoundEffect();\n\n        result.waveShape = waveShape;\n        result.startFrequency = startFrequency;\n        result.endFrequency = endFrequency;\n        result.startVolume = startVolume;\n        result.endVolume = endVolume;\n        result.duration = duration;\n        result.effect = effect;\n        result.interpolation = interpolation;\n\n        return result;\n    }\n\n    interface Step {\n        frequency: number;\n        volume: number;\n    }\n\n     export function soundToInstructionBuffer(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve, fxSteps: number, fxRange: number, globalVolume: number) {\n        const steps: Step[] = [];\n\n        // Optimize the simple case\n        if (interpolation === InterpolationCurve.Linear && effect === SoundExpressionEffect.None) {\n            steps.push({\n                frequency: startFrequency,\n                volume: (startVolume / 255) * globalVolume,\n            })\n            steps.push({\n                frequency: endFrequency,\n                volume: (endVolume / 255) * globalVolume,\n            })\n        }\n        else {\n\n            fxSteps = Math.min(fxSteps, Math.floor(duration / 5))\n\n            const getVolumeAt = (t: number) => ((startVolume + t * (endVolume - startVolume) / duration) / 255) * globalVolume;\n            let getFrequencyAt: (t: number) => number;\n\n            switch (interpolation) {\n                case InterpolationCurve.Linear:\n                    getFrequencyAt = t => startFrequency + t * (endFrequency - startFrequency) / duration;\n                    break;\n                case InterpolationCurve.Curve:\n                    getFrequencyAt = t => startFrequency + (endFrequency - startFrequency) * Math.sin(t / duration * (Math.PI / 2));\n                    break;\n                case InterpolationCurve.Logarithmic:\n                    getFrequencyAt = t => startFrequency + (Math.log(1 + 9 * (t / duration)) / Math.log(10)) * (endFrequency - startFrequency)\n                    break;\n            }\n\n            const timeSlice = duration / fxSteps;\n\n            for (let i = 0; i < fxSteps; i++) {\n                const newStep = {\n                    frequency: getFrequencyAt(i * timeSlice),\n                    volume: getVolumeAt(i * timeSlice)\n                };\n\n                if (effect === SoundExpressionEffect.Tremolo) {\n                    if (i % 2 === 0) {\n                        newStep.volume = Math.max(newStep.volume - fxRange * 500, 0)\n                    }\n                    else {\n                        newStep.volume = Math.min(newStep.volume + fxRange * 500, 1023)\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Vibrato) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 100, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 100\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Warble) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 1000, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 1000\n                    }\n                }\n\n                steps.push(newStep)\n            }\n        }\n\n        const out = control.createBuffer(12 * (steps.length - 1));\n        const stepDuration = Math.floor(duration / (steps.length - 1))\n\n        for (let i = 0; i < steps.length - 1; i++) {\n            const offset = i * 12;\n            out.setNumber(NumberFormat.UInt8LE, offset, waveToValue(waveShape));\n            out.setNumber(NumberFormat.UInt16LE, offset + 2, steps[i].frequency);\n            out.setNumber(NumberFormat.UInt16LE, offset + 4, stepDuration);\n            out.setNumber(NumberFormat.UInt16LE, offset + 6, steps[i].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 8, steps[i + 1].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 10, steps[i + 1].frequency);\n        }\n\n        return out;\n    }\n\n    function waveToValue(wave: WaveShape) {\n        switch (wave) {\n            case WaveShape.Square: return 15;\n            case WaveShape.Sine: return 3;\n            case WaveShape.Triangle: return 1;\n            case WaveShape.Noise: return 18;\n            case WaveShape.Sawtooth: return 2;\n        }\n    }\n\n\n    /**\n     * Generate a random similar sound effect to the given one.\n     *\n     * @param sound the sound effect\n     */\n    //% blockId=soundExpression_generateSimilarSound\n    //% block=\"randomize $sound\"\n    //% sound.shadow=soundExpression_createSoundEffect\n    //% weight=0 help=music/randomize-sound\n    //% blockGap=8\n    //% group=\"Sounds\"\n    export function randomizeSound(sound: SoundEffect) {\n        const res = new SoundEffect();\n        res.waveShape = sound.waveShape;\n        res.startFrequency = sound.startFrequency;\n        res.endFrequency = sound.endFrequency;\n        res.startVolume = sound.startVolume;\n        res.endVolume = sound.endVolume;\n        res.duration = sound.duration;\n        res.effect = sound.effect;\n        res.interpolation = randomInterpolation();\n\n        res.duration = Math.clamp(\n            Math.min(100, res.duration),\n            Math.max(2000, res.duration),\n            res.duration + (Math.random() - 0.5) * res.duration,\n        );\n\n        if (res.waveShape === WaveShape.Noise) {\n            // The primary waveforms don't produce sounds that are similar to noise,\n            // but adding an effect sorta does\n            if (Math.percentChance(20)) {\n                res.waveShape = randomWave();\n                res.effect = randomEffect();\n            }\n        }\n        else {\n            res.waveShape = randomWave();\n\n            // Adding an effect can drastically alter the sound, so keep it\n            // at a low percent chance unless there already is one\n            if (res.effect !== SoundExpressionEffect.None || Math.percentChance(10)) {\n                res.effect = randomEffect();\n            }\n        }\n\n        // Instead of randomly changing the frequency, change the slope and choose\n        // a new start frequency. This keeps a similar profile to the sound\n        const oldFrequencyDifference = res.endFrequency - res.startFrequency;\n        let newFrequencyDifference = oldFrequencyDifference + (oldFrequencyDifference * 2) * (Math.random() - 0.5);\n\n        if (Math.sign(oldFrequencyDifference) !== Math.sign(newFrequencyDifference)) {\n            newFrequencyDifference *= -1;\n        }\n\n        newFrequencyDifference = Math.clamp(-5000, 5000, newFrequencyDifference);\n\n        res.startFrequency = Math.clamp(\n            Math.max(-newFrequencyDifference, 1),\n            Math.clamp(1, 5000, 5000 - newFrequencyDifference),\n            Math.random() * 5000,\n        );\n\n        res.endFrequency = Math.clamp(1, 5000, res.startFrequency + newFrequencyDifference);\n\n        // Same strategy for volume\n        const oldVolumeDifference = res.endVolume - res.startVolume;\n        let newVolumeDifference = oldVolumeDifference + oldVolumeDifference * (Math.random() - 0.5);\n\n        newVolumeDifference = Math.clamp(-255, 255, newVolumeDifference);\n\n        if (Math.sign(oldVolumeDifference) !== Math.sign(newVolumeDifference)) {\n            newVolumeDifference *= -1;\n        }\n\n        res.startVolume = Math.clamp(\n            Math.max(-newVolumeDifference, 0),\n            Math.clamp(0, 255, 255 - newVolumeDifference),\n            Math.random() * 255,\n        );\n\n        res.endVolume = Math.clamp(0, 255, res.startVolume + newVolumeDifference);\n\n        return res;\n    }\n\n    function randomWave() {\n        switch (Math.randomRange(0, 3)) {\n            case 1: return WaveShape.Sawtooth;\n            case 2: return WaveShape.Square;\n            case 3: return WaveShape.Triangle;\n            case 0:\n            default:\n                return WaveShape.Sine;\n        }\n    }\n\n    function randomEffect() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return SoundExpressionEffect.Warble;\n            case 2: return  SoundExpressionEffect.Tremolo;\n            case 0:\n            default:\n                return SoundExpressionEffect.Vibrato;\n        }\n    }\n\n    function randomInterpolation() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return InterpolationCurve.Linear;\n            case 2: return  InterpolationCurve.Curve;\n            case 0:\n            default:\n                return InterpolationCurve.Logarithmic;\n        }\n    }\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n}","targetoverrides.ts":"// make sure sound starts\nnew music.Melody(\"!440,100\").playUntilDone(1)\n","test.ts":"for(let i = 1000; i > 0; i -= 50)\n    music.playTone(440, i)\n\nfor(let i = 0; i < 1000; i += 20)\n    music.playTone(440, i)\n"},"mixer---none":{"SoundOutput.h":"\n","headphone.svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"142\" height=\"180\" viewBox=\"0 0 142 180\"><rect ry=\".3\" rx=\"1\" y=\"58.615\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><rect ry=\".3\" rx=\"1\" y=\"32.043\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><path d=\"M.346 7.296c-.394.39-.31 4.797-.18 4.898l13.404 10.18c.117.12.337 4.76.73 4.368l5.506-5.56.01.01 6.51-6.444c.39-.392-4.25-.614-4.366-.73L11.777.612c-.1-.132-4.51-.215-4.898.18L4.087 3.636l-.01-.01-3.73 3.67z\" fill=\"#b3b3b3\"/><rect ry=\"6.85\" rx=\"4.571\" y=\"84.758\" x=\"-20.128\" height=\"75.571\" width=\"39.643\" transform=\"rotate(-45)\"/><rect ry=\".374\" rx=\"1.038\" y=\"29.442\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"55.939\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"82.392\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\"2.317\" rx=\"2.183\" y=\"158.876\" x=\"-9.774\" height=\"25.568\" width=\"18.935\" transform=\"rotate(-45)\"/><path d=\"M128.588 128.82s14.97 11.165 7.547 26.35c-8.426 17.24-25.57 20.653-25.57 20.653\" fill=\"none\" stroke=\"#000\" stroke-width=\"6.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>","instrument.ts":"namespace music.sequencer {\n    const BUFFER_SIZE = 12;\n\n    let currentSequencer: sequencer.Sequencer;\n\n    /**\n     * Byte encoding format for songs\n     * FIXME: should this all be word aligned?\n     *\n     * song(7 + length of all tracks bytes)\n     *     0 version\n     *     1 beats per minute\n     *     3 beats per measure\n     *     4 ticks per beat\n     *     5 measures\n     *     6 number of tracks\n     *     ...tracks\n     *\n     * track(6 + instrument length + note length bytes)\n     *     0 id\n     *     1 flags\n     *     2 instruments byte length\n     *     4...instrument\n     *     notes byte length\n     *     ...note events\n     *\n     * instrument(28 bytes)\n     *     0 waveform\n     *     1 amp attack\n     *     3 amp decay\n     *     5 amp sustain\n     *     7 amp release\n     *     9 amp amp\n     *     11 pitch attack\n     *     13 pitch decay\n     *     15 pitch sustain\n     *     17 pitch release\n     *     19 pitch amp\n     *     21 amp lfo freq\n     *     22 amp lfo amp\n     *     24 pitch lfo freq\n     *     25 pitch lfo amp\n     *     27 octave\n     *\n     * drum(5 + 7 * steps bytes)\n     *     0 steps\n     *     1 start freq\n     *     3 start amp\n     *     5...steps\n     *\n     * drum step(7 bytes)\n     *     0 waveform\n     *     1 freq\n     *     3 volume\n     *     5 duration\n     *\n     * note event(5 + 1 * polyphony bytes)\n     *     0 start tick\n     *     2 end tick\n     *     4 polyphony\n     *     5...notes(1 byte each)\n     *\n     * note (1 byte)\n     *     lower six bits = note - (instrumentOctave - 2) * 12\n     *     upper two bits are the enharmonic spelling:\n     *          0 = normal\n     *          1 = flat\n     *          2 = sharp\n     */\n\n    export class Song extends Playable {\n        tracks: Track[];\n\n        constructor(public buf: Buffer) {\n            super();\n            this.tracks = [];\n\n            let currentOffset = 7;\n            for (let i = 0; i < this.numberOfTracks; i++) {\n                let track: Track = new MelodicTrack(this.buf, currentOffset);\n\n                if (!track.isMelodicTrack) {\n                    track = new DrumTrack(this.buf, currentOffset)\n                }\n\n                this.tracks.push(track);\n                currentOffset += track.byteLength;\n            }\n        }\n\n        get version(): number {\n            return this.buf[0];\n        }\n\n        set version(value: number) {\n            this.buf[0] = value;\n        }\n\n        get beatsPerMinute(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, 1);\n        }\n\n        set beatsPerMinute(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, 1, value);\n        }\n\n        get beatsPerMeasure(): number {\n            return this.buf[3];\n        }\n\n        set beatsPerMeasure(value: number) {\n            this.buf[3] = value;\n        }\n\n        get ticksPerBeat(): number {\n            return this.buf[4];\n        }\n\n        set ticksPerBeat(value: number) {\n            this.buf[4] = value;\n        }\n\n        get measures(): number {\n            return this.buf[5];\n        }\n\n        set measures(value: number) {\n            this.buf[5] = value;\n        }\n\n        get numberOfTracks(): number {\n            return this.buf[6];\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (control.deviceDalVersion() === \"sim\") {\n                const seq = new _SimulatorSequencer();\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    seq.play(this.buf, false);\n\n                    pauseUntil(() => seq.state() === \"stop\");\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    seq.play(this.buf, false);\n                }\n                else {\n                    seq.play(this.buf, true);\n                }\n            }\n            else {\n                if (currentSequencer) currentSequencer.stop();\n                currentSequencer = new sequencer.Sequencer(this);\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    let seq = currentSequencer;\n                    currentSequencer.start(false);\n                    pauseUntil(() => !seq.isRunning);\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    currentSequencer.start(false);\n                }\n                else {\n                    currentSequencer.start(true);\n                }\n            }\n        }\n    }\n\n    export class Envelope {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(10);\n            this.offset = this.offset || 0;\n        }\n\n        // The time in ms for the envelope to reach its maximum value\n        get attack(): number {\n            return this.getValue(0);\n        }\n\n        set attack(value: number) {\n            this.setValue(0, value);\n        }\n\n        // The time in ms for the envelope to reach its sustain value after reaching its maximum value\n        get decay(): number {\n            return this.getValue(2);\n        }\n\n        set decay(value: number) {\n            this.setValue(2, value);\n        }\n\n        // The value (0-1024) to hold at during the sustain stage\n        get sustain(): number {\n            return this.getValue(4);\n        }\n\n        set sustain(value: number) {\n            this.setValue(4, value);\n        }\n\n        // The time in ms for the envelope to reach 0 after the gate length ends\n        get release(): number {\n            return this.getValue(6);\n        }\n\n        set release(value: number) {\n            this.setValue(6, value);\n        }\n\n        // The maximum value that this envelope will reach\n        get amplitude(): number {\n            return this.getValue(8);\n        }\n\n        set amplitude(value: number) {\n            this.setValue(8, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class LFO {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(3);\n            this.offset = this.offset || 0;\n        }\n\n        get frequency(): number {\n            return this.buf[this.offset];\n        }\n\n        set frequency(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get amplitude(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + 1);\n        }\n\n        set amplitude(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + 1, value);\n        }\n    }\n\n    export class NoteEvent {\n        constructor(public buf: Buffer, public offset: number) {\n\n        }\n\n        get startTick(): number {\n            return this.getValue(0);\n        }\n\n        set startTick(value: number) {\n            this.setValue(0, value);\n        }\n\n        get endTick(): number {\n            return this.getValue(2);\n        }\n\n        set endTick(value: number) {\n            this.setValue(2, value);\n        }\n\n        get polyphony(): number {\n            return this.buf[this.offset + 4];\n        }\n\n        set polyphony(value: number) {\n            this.buf[this.offset + 4] = value;\n        }\n\n        get byteLength() {\n            return this.polyphony + 5;\n        }\n\n        getNote(offset: number, octave?: number) {\n            const value = this.buf[this.offset + offset + 5] & 0x3f;\n            if (octave !== undefined) {\n                return value + (octave - 2) * 12\n            }\n            return value\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class Track {\n        currentNoteEvent: NoteEvent;\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.currentNoteEvent = new NoteEvent(this.buf, this.noteEventStart + 2);\n        }\n\n        get isMelodicTrack(): boolean {\n            return this.flags === 0;\n        }\n\n        get id(): number {\n            return this.buf[this.offset];\n        }\n\n        set id(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get flags(): number {\n            return this.buf[this.offset + 1];\n        }\n\n        set flags(value: number) {\n            this.buf[this.offset + 1] = value;\n        }\n\n        get instrumentByteLength(): number {\n            return this.getValue(this.offset + 2);\n        }\n\n        set instrumentByteLength(value: number) {\n            this.setValue(this.offset + 2, value);\n        }\n\n        get noteEventStart(): number {\n            return this.offset + this.instrumentByteLength + 4;\n        }\n\n        get noteEventByteLength(): number {\n            return this.getValue(this.noteEventStart);\n        }\n\n        set noteEventByteLength(value: number) {\n            this.setValue(this.noteEventStart, value);\n        }\n\n        get byteLength() {\n            return this.noteEventByteLength + this.instrumentByteLength + 6;\n        }\n\n        advanceNoteEvent() {\n            this.currentNoteEvent.offset += this.currentNoteEvent.byteLength;\n\n            if (this.currentNoteEvent.offset >= this.offset + this.byteLength) {\n                this.currentNoteEvent.offset = this.noteEventStart + 2;\n            }\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, offset, value);\n        }\n    }\n\n    export class MelodicTrack extends Track {\n        instrument: Instrument;\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.instrument = new Instrument(this.buf, this.offset + 4);\n        }\n    }\n\n    export class DrumTrack extends Track {\n        drums: DrumInstrument[];\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.drums = [];\n\n            let currentOffset = 0;\n            while (currentOffset < this.instrumentByteLength) {\n                this.drums.push(new DrumInstrument(this.buf, this.offset + 4 + currentOffset));\n                currentOffset += this.drums[this.drums.length - 1].byteLength;\n            }\n        }\n    }\n\n    export class Instrument {\n        ampEnvelope: Envelope;\n        pitchEnvelope: Envelope;\n        ampLFO: LFO;\n        pitchLFO: LFO;\n\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(27);\n            this.offset = this.offset || 0;\n            this.ampEnvelope = new Envelope(this.buf, this.offset + 1);\n            this.pitchEnvelope = new Envelope(this.buf, this.offset + 11);\n            this.ampLFO = new LFO(this.buf, this.offset + 21);\n            this.pitchLFO = new LFO(this.buf, this.offset + 24)\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get octave(): number {\n            return this.buf[this.offset + 27]\n        }\n\n        set octave(value: number) {\n            this.buf[this.offset + 27] = value;\n        }\n    }\n\n    export class DrumInstrument {\n        steps: DrumStep[];\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.steps = [];\n\n            for (let i = 0; i < this.numSteps; i++) {\n                this.steps.push(new DrumStep(this.buf, this.offset + 5 + i * 7))\n            }\n        }\n\n        get byteLength(): number {\n            return 5 + this.numSteps * 7;\n        }\n\n        get numSteps(): number {\n            return this.buf[this.offset];\n        }\n\n        set numSteps(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get startFrequency(): number {\n            return this.getValue(1);\n        }\n\n        set startFrequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get startVolume(): number {\n            return this.getValue(3);\n        }\n\n        set startVolume(value: number) {\n            this.setValue(3, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class DrumStep {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(7);\n            this.offset = this.offset || 0;\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get frequency(): number {\n            return this.getValue(1);\n        }\n\n        set frequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get volume(): number {\n            return this.getValue(3);\n        }\n\n        set volume(value: number) {\n            this.setValue(3, value);\n        }\n\n        get duration(): number {\n            return this.getValue(5);\n        }\n\n        set duration(value: number) {\n            this.setValue(5, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    /**\n     * Renders a single note played on an instrument into a buffer of sound instructions.\n     *\n     * @param instrument The instrument being played\n     * @param noteFrequency The frequency of the note being played. In other words, \"the key being pressed on the piano\"\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     * @param volume The peak volume of the note to play (0-1024). Also called the \"velocity\"\n     */\n    export function renderInstrument(instrument: Instrument, noteFrequency: number, gateLength: number, volume: number) {\n        // We cut off the sound at the end of the amplitude envelope's release time. This is to prevent\n        // the amp envelope from making the sound keep playing forever\n        const totalDuration = gateLength + instrument.ampEnvelope.release;\n\n        // Our goal is to calculate the frequency and amplitude at all of the inflection points in this note's lifetime\n\n        // For the ADSR envelopes, the inflection points are:\n        //     1. The end of the envelope atack (which is when the decay begins)\n        //     2. The end of the envelope decay (which is when the sustain begins)\n        //     3. The end of the gateLength (which is when the release begins)\n        //     4. The end of the envelope release\n        // If the gateLength ends before any of these stages (e.g. it's shorter than the envelope's attack), then\n        // we ignore the other stages and go straight to the release stage.\n\n        // For the triangle LFOs, the inflections points occur every time the slope goes from positive to negative. In\n        // other words, it's half the period of the triangle wave.\n\n        const ampLFOInterval = instrument.ampLFO.amplitude ? Math.max(500 / instrument.ampLFO.frequency, 50) : 50;\n        const pitchLFOInterval = instrument.pitchLFO.amplitude ? Math.max(500 / instrument.pitchLFO.frequency, 50) : 50;\n\n        // We're going to add the timepoints to this array in order so that it doesn't need to be sorted\n        let timePoints = [0];\n\n        // For each LFO and envelope, keep track of the next inflection point. If any of the LFOs or envelopes have\n        // an amplitude of 0, we can ignore them entirely.\n        let nextAETime = instrument.ampEnvelope.attack;\n        let nextPETime = instrument.pitchEnvelope.amplitude ? instrument.pitchEnvelope.attack : totalDuration;\n        let nextPLTime = instrument.pitchLFO.amplitude ? pitchLFOInterval : totalDuration;\n        let nextALTime = instrument.ampLFO.amplitude ? ampLFOInterval : totalDuration;\n\n        let time = 0;\n        while (time < totalDuration) {\n            // Amp envelope\n            if (nextAETime <= nextPETime && nextAETime <= nextPLTime && nextAETime <= nextALTime) {\n                time = nextAETime;\n                timePoints.push(nextAETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            // Pitch envelope\n            else if (nextPETime <= nextPLTime && nextPETime <= nextALTime && nextPETime < totalDuration) {\n                time = nextPETime;\n                timePoints.push(nextPETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                // If we reach the end of the release before the amp envelope is finished, bail out\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            // Pitch LFO\n            else if (nextPLTime <= nextALTime && nextPLTime < totalDuration) {\n                time = nextPLTime;\n                timePoints.push(nextPLTime);\n                nextPLTime += pitchLFOInterval;\n            }\n            // Amp LFO\n            else if (nextALTime < totalDuration) {\n                time = nextALTime;\n                timePoints.push(nextALTime);\n                nextALTime += ampLFOInterval;\n            }\n\n\n            if (time >= totalDuration) {\n                break;\n            }\n\n            // Now that we've advanced the time, we need to check all of the envelopes/LFOs again\n            // to see if any of them also need to be pushed forward (e.g. they had the same inflection point\n            // as the one we just added to the array)\n            if (nextAETime <= time) {\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            if (nextPETime <= time) {\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            while (nextALTime <= time) {\n                nextALTime += ampLFOInterval;\n            }\n            while (nextPLTime <= time) {\n                nextPLTime += pitchLFOInterval;\n            }\n        }\n\n        // Once we've calculated the inflection points, calculate the frequency and amplitude at\n        // each step and interpolate between them with sound instructions\n        let prevAmp = instrumentVolumeAtTime(instrument, gateLength, 0, volume) | 0;\n        let prevPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, 0) | 0;\n        let prevTime = 0;\n\n        let nextAmp: number;\n        let nextPitch: number;\n        const out = control.createBuffer(BUFFER_SIZE * timePoints.length);\n        for (let i = 1; i < timePoints.length; i++) {\n            if (timePoints[i] - prevTime < 5) {\n                prevTime = timePoints[i];\n                continue;\n            }\n\n            nextAmp = instrumentVolumeAtTime(instrument, gateLength, timePoints[i], volume) | 0;\n            nextPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, timePoints[i]) | 0\n            addNote(\n                out,\n                (i - 1) * 12,\n                (timePoints[i] - prevTime) | 0,\n                prevAmp,\n                nextAmp,\n                instrument.waveform,\n                prevPitch,\n                255,\n                nextPitch\n            )\n\n            prevAmp = nextAmp;\n            prevPitch = nextPitch;\n            prevTime = timePoints[i];\n        }\n\n        // Finally, add one extra step to move the amplitude to 0 without\n        // clipping just in case the amp LFO caused it to be nonzero\n        addNote(\n            out,\n            (timePoints.length - 1) * 12,\n            10,\n            prevAmp,\n            0,\n            instrument.waveform,\n            prevPitch,\n            255,\n            prevPitch\n        )\n        return out;\n    }\n\n    export function renderDrumInstrument(sound: DrumInstrument, volume: number) {\n        // Drum instruments are rendered just like melodic instruments, but the inflection\n        // points are already calculated for us\n        let prevAmp = sound.startVolume;\n        let prevFreq = sound.startFrequency;\n\n        const scaleVolume = (value: number) => (value / 1024) * volume;\n\n        let out = control.createBuffer((sound.steps.length + 1) * BUFFER_SIZE);\n\n        for (let i = 0; i < sound.steps.length; i++) {\n            addNote(\n                out,\n                i * BUFFER_SIZE,\n                sound.steps[i].duration,\n                scaleVolume(prevAmp),\n                scaleVolume(sound.steps[i].volume),\n                sound.steps[i].waveform,\n                prevFreq,\n                255,\n                sound.steps[i].frequency\n            );\n            prevAmp = sound.steps[i].volume;\n            prevFreq = sound.steps[i].frequency\n        }\n\n        addNote(\n            out,\n            sound.steps.length * BUFFER_SIZE,\n            10,\n            scaleVolume(prevAmp),\n            0,\n            sound.steps[sound.steps.length - 1].waveform,\n            prevFreq,\n            255,\n            prevFreq\n        );\n\n        return out;\n    }\n\n    function instrumentPitchAtTime(instrument: Instrument, noteFrequency: number, gateLength: number, time: number) {\n        let mod = 0;\n        if (instrument.pitchEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.pitchEnvelope, time, gateLength)\n        }\n        if (instrument.pitchLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.pitchLFO, time)\n        }\n        return Math.max(noteFrequency + mod, 0);\n    }\n\n    function instrumentVolumeAtTime(instrument: Instrument, gateLength: number, time: number, maxVolume: number) {\n        let mod = 0;\n        if (instrument.ampEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.ampEnvelope, time, gateLength)\n        }\n        if (instrument.ampLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.ampLFO, time)\n        }\n        return ((Math.max(Math.min(mod, instrument.ampEnvelope.amplitude), 0) / 1024) * maxVolume) | 0;\n    }\n\n    /**\n     * Calculates the value of an ADSR envelope at the given time for a given gate length.\n     *\n     * @param envelope The ADSR envelope\n     * @param time The point and time to calculate the value at\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     */\n    function envelopeValueAtTime(envelope: Envelope, time: number, gateLength: number) {\n        // ADSR envelopes consist of 4 stages. They are (in order):\n        //     1. The attack stage, where the value starts at 0 and rises to the maximum value\n        //     2. The decay stage, where the value falls from the maximum value to the sustain value\n        //     3. The sustain stage, where the value holds steady at the sustain value until the gate length ends\n        //     4. The release stage, where the value falls to 0 after the gate length ends\n        // If the gate length ends before the sustain stage, we immediately skip to the release stage. All stages\n        // use a linear function for the value\n        const adjustedSustain = (envelope.sustain / 1024) * envelope.amplitude;\n\n        // First check to see if we are already in the release stage\n        if (time > gateLength) {\n            if (time - gateLength > envelope.release) return 0;\n\n            // Did the gate length end before the attack stage finished?\n            else if (time < envelope.attack) {\n                const height = (envelope.amplitude / envelope.attack) * gateLength;\n                return height - ((height / envelope.release) * (time - gateLength))\n            }\n            // Did the gate length end before the decay stage finished?\n            else if (time < envelope.attack + envelope.decay) {\n                const height2 = envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (gateLength - envelope.attack);\n                return height2 - ((height2 / envelope.release) * (time - gateLength))\n            }\n            else {\n                return adjustedSustain - (adjustedSustain / envelope.release) * (time - gateLength)\n            }\n        }\n        else if (time < envelope.attack) {\n            return (envelope.amplitude / envelope.attack) * time\n        }\n        else if (time < envelope.attack + envelope.decay) {\n            return envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (time - envelope.attack)\n        }\n        else {\n            return adjustedSustain;\n        }\n    }\n\n    /**\n     * Calculates the value of the LFO at the given time.\n     *\n     * TODO: might be nice to give options to shift the phase of the LFO or let it run free\n     *\n     * @param lfo The LFO to calculate the value of\n     * @param time The time to calculate the value at\n     */\n    function lfoValueAtTime(lfo: LFO, time: number) {\n        // Use cosine to smooth out the value somewhat\n        return Math.cos(((time / 1000) * lfo.frequency) * 2 * Math.PI) * lfo.amplitude\n    }\n\n    export function _stopAllSongs() {\n        if (currentSequencer) {\n            currentSequencer.stop();\n            currentSequencer = undefined;\n        }\n        _stopAllSimSequencers();\n    }\n}","legacy.ts":"//% deprecated=true hidden=true\nenum Sounds {\n    //% block=\"power up\"\n    PowerUp,\n    //% block=\"power down\"\n    PowerDown,\n    //% block=\"jump up\"\n    JumpUp,\n    //% block=\"jump down\"\n    JumpDown,\n    //% block=\"ba ding\"\n    BaDing,\n    //% block=\"wawawawaa\"\n    Wawawawaa,\n    //% block=\"magic wand\"\n    MagicWand,\n    //% block=\"siren\"\n    Siren\n}\n\nnamespace music {\n    /**\n     * Get the melody string for a built-in melody.\n     * @param name the note name, eg: Note.C\n     */\n    //% help=music/sounds\n    //% blockId=music_sounds block=\"%name\"\n    //% blockHidden=true\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=285\n    //% name.fieldOptions.columns=3\n    export function sounds(name: Sounds): string {\n        switch (name) {\n            case Sounds.BaDing:\n                return 'b5:1 e6:3';\n            case Sounds.Wawawawaa:\n                return 'e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8';\n            case Sounds.JumpUp:\n                return 'c5:1 d e f g';\n            case Sounds.JumpDown:\n                return 'g5:1 f e d c';\n            case Sounds.PowerUp:\n                return 'g4:1 c5 e g:2 e:1 g:3';\n            case Sounds.PowerDown:\n                return 'g5:1 d# c g4:2 b:1 c5:3';\n            case Sounds.MagicWand:\n                return 'F#6:1-300 G# A# B C7# D# F F# G# A# B:6'; //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n            case Sounds.Siren:\n                return 'a4 d5 a4 d5 a4 d5';\n            default:\n                return '';\n        }\n    }\n\n    let currMelody: Melody\n\n    /**\n     * Start playing a sound and don't wait for it to finish.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound\n    //% blockId=music_play_sound block=\"play sound %sound=music_sounds\"\n    //% parts=\"headphone\"\n    //% weight=95 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSound(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.play();\n        pause(1);\n    }\n\n\n    /**\n     * Play a sound and wait until the sound is done.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound-until-done\n    //% blockId=music_play_sound_until_done block=\"play sound %sound=music_sounds|until done\"\n    //% parts=\"headphone\"\n    //% weight=94 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSoundUntilDone(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.playUntilDone();\n    }\n}","melody.cpp":"#include \"pxt.h\"\n#include \"melody.h\"\n\nnamespace music {\n//%\nvoid forceOutput(int outp) {}\n\n//%\nvoid queuePlayInstructions(int when, Buffer buf) {\n}\n\n//%\nvoid enableAmp(int enabled) {\n\n}\n\n} // namespace music\n","melody.h":"\n","melody.ts":"enum MusicOutput {\n    AutoDetect = 0,\n    Buzzer = 1,\n    HeadPhones = 2,\n}\n\nnamespace music {\n    //% whenUsed\n    const freqs = hex`\n        1f00210023002500270029002c002e003100340037003a003e004100450049004e00520057005c00620068006e00\n        75007b0083008b0093009c00a500af00b900c400d000dc00e900f70006011501260137014a015d01720188019f01\n        b801d201ee010b022a024b026e029302ba02e40210033f037003a403dc03170455049704dd0427057505c8052006\n        7d06e0064907b8072d08a9082d09b9094d0aea0a900b400cfa0cc00d910e6f0f5a1053115b1272139a14d4152017\n        8018f519801b231dde1e`\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n\n    //% shim=music::stopPlaying\n    function stopPlaying() { }\n\n    //% shim=music::forceOutput\n    export function forceOutput(buf: MusicOutput) { }\n\n    let globalVolume: number = null\n\n    const BUFFER_SIZE: number = 12;\n\n    //% shim=music::enableAmp\n    function enableAmp(en: number) {\n        return // for sim\n    }\n\n    function initVolume() {\n        if (globalVolume === null) {\n            globalVolume = 0\n            setVolume(control.getConfigValue(DAL.CFG_SPEAKER_VOLUME, 128))\n        }\n    }\n\n    /**\n     * Set the default output volume of the sound synthesizer.\n     * @param volume the volume 0...255\n     */\n    //% blockId=synth_set_volume block=\"set volume %volume\"\n    //% parts=\"speaker\"\n    //% volume.min=0 volume.max=255\n    //% volume.defl=20\n    //% help=music/set-volume\n    //% weight=70\n    //% group=\"Volume\"\n    export function setVolume(volume: number): void {\n        globalVolume = Math.clamp(0, 255, volume | 0)\n        enableAmp(globalVolume > 0 ? 1 : 0)\n    }\n\n    /**\n     * Gets the current volume\n     */\n    //% parts=\"speaker\"\n    //% weight=70\n    export function volume(): number {\n        initVolume()\n        return globalVolume;\n    }\n\n    function playNoteCore(when: number, frequency: number, ms: number) {\n        let buf = control.createBuffer(BUFFER_SIZE)\n        addNote(buf, 0, ms, 255, 255, 3, frequency, volume(), frequency)\n        queuePlayInstructions(when, buf)\n    }\n\n    /**\n     * Play a tone through the speaker for some amount of time.\n     * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n     * @param ms tone duration in milliseconds (ms), eg: BeatFraction.Half\n     */\n    //% help=music/play-tone\n    //% blockId=mixer_play_note block=\"play tone|at %note=device_note|for %duration=device_beat\"\n    //% parts=\"headphone\" async\n    //% blockNamespace=music\n    //% weight=76 blockGap=8\n    //% group=\"Tone\"\n    //% deprecated=1\n    export function playTone(frequency: number, ms: number): void {\n        if (ms == 0)\n            ms = 86400000 // 1 day\n\n        if (ms <= 2000) {\n            playNoteCore(0, frequency, ms)\n            pause(ms)\n        } else {\n            const id = ++playToneID\n            control.runInParallel(() => {\n                let pos = control.millis()\n                while (id == playToneID && ms > 0) {\n                    let now = control.millis()\n                    let d = pos - now\n                    let t = Math.min(ms, 500)\n                    ms -= t\n                    pos += t\n                    playNoteCore(d - 1, frequency, t)\n                    if (ms == 0)\n                        pause(d + t)\n                    else\n                        pause(d + t - 100)\n                }\n            })\n        }\n    }\n\n    let playToneID = 0\n\n    /**\n     * Play a melody from the melody editor.\n     * @param melody - string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces,\n     * which will be played one at a time, ex: \"E D G F B A C5 B \"\n     * @param tempo - number in beats per minute (bpm), dictating how long each note will play for\n     */\n    //% block=\"play melody $melody at tempo $tempo|(bpm)\" blockId=playMelody\n    //% blockNamespace=music\n    //% weight=85 blockGap=8 help=music/play-melody\n    //% group=\"Melody\"\n    //% melody.shadow=\"melody_editor\"\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% deprecated=1\n    export function playMelody(melody: string, tempo: number) {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        const song = new Melody(formattedMelody);\n        song.playUntilDone();\n    }\n\n\n    /**\n     * Create a melody with the melody editor.\n     * @param melody\n     */\n    //% block=\"$melody\" blockId=melody_editor\n    //% blockNamespace=music\n    //% blockHidden = true\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Melody\" duplicateShadowOnDrag\n    //% melody.fieldEditor=\"melody\"\n    //% melody.fieldOptions.decompileLiterals=true\n    //% melody.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% melody.fieldOptions.onParentBlock=\"true\"\n    //% shim=TD_ID\n    export function melodyEditor(melody: string): string {\n        return melody;\n    }\n\n    /**\n     * Stop all sounds from playing.\n     */\n    //% help=music/stop-all-sounds\n    //% blockId=music_stop_all_sounds block=\"stop all sounds\"\n    //% weight=45\n    //% group=\"Sounds\"\n    export function stopAllSounds() {\n        Melody.stopAll();\n        stopPlaying();\n        _stopPlayables();\n        sequencer._stopAllSongs();\n    }\n\n    //% fixedInstances\n    export class Melody {\n        _text: string;\n        private _player: MelodyPlayer;\n\n        private static playingMelodies: Melody[];\n\n        static stopAll() {\n            if (Melody.playingMelodies) {\n                const ms = Melody.playingMelodies.slice(0, Melody.playingMelodies.length);\n                ms.forEach(p => p.stop());\n            }\n        }\n\n        constructor(text: string) {\n            this._text = text\n        }\n\n        get text() {\n            return this._text;\n        }\n\n        /**\n         * Stop playing a sound\n         */\n        //% blockId=mixer_stop block=\"stop sound %sound\"\n        //% help=music/melody/stop\n        //% parts=\"headphone\"\n        //% weight=92 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        stop() {\n            if (this._player) {\n                this._player.stop()\n                this._player = null\n            }\n            this.unregisterMelody();\n        }\n\n        private registerMelody() {\n            // keep track of the active players\n            if (!Melody.playingMelodies) Melody.playingMelodies = [];\n            // stop and pop melodies if too many playing\n            if (Melody.playingMelodies.length > 4) {\n                // stop last player (also pops)\n                Melody.playingMelodies[Melody.playingMelodies.length - 1].stop();\n            }\n            // put back the melody on top of the melody stack\n            Melody.playingMelodies.removeElement(this);\n            Melody.playingMelodies.push(this);\n        }\n        private unregisterMelody() {\n            // remove from list\n            if (Melody.playingMelodies) {\n                Melody.playingMelodies.removeElement(this); // remove self\n            }\n        }\n\n        private playCore(volume: number, loop: boolean) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this.registerMelody();\n            control.runInParallel(() => {\n                while (this._player == p) {\n                    p.play(volume)\n                    if (!loop) {\n                        // Unregister the melody when done playing, but\n                        // only if it hasn't been restarted. (Looping\n                        // melodies never stop on their own, they only\n                        // get unregistered via stop().)\n                        if (this._player == p) {\n                            this.unregisterMelody();\n                        }\n                        break\n                    }\n                }\n            })\n        }\n\n        /**\n         * Start playing a sound in a loop and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/loop\n        //% blockId=mixer_loop_sound block=\"loop sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=93 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        loop(volume = 255) {\n            this.playCore(volume, true)\n        }\n\n        /**\n         * Start playing a sound and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play\n        //% blockId=mixer_play_sound block=\"play sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=95 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        play(volume = 255) {\n            this.playCore(volume, false)\n        }\n\n\n        /**\n         * Play a sound and wait until the sound is done.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play-until-done\n        //% blockId=mixer_play_sound_until_done block=\"play sound %sound|until done\"\n        //% parts=\"headphone\"\n        //% weight=94 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        playUntilDone(volume = 255) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this._player.onPlayFinished = () => {\n                if (p == this._player)\n                    this.unregisterMelody();\n            }\n            this.registerMelody();\n            this._player.play(volume)\n        }\n\n        toString() {\n            return this._text;\n        }\n    }\n\n    export function addNote(sndInstr: Buffer, sndInstrPtr: number, ms: number, beg: number, end: number, soundWave: number, hz: number, volume: number, endHz: number) {\n        if (ms > 0) {\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, soundWave)\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr + 1, 0)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 2, hz)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 4, ms)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 6, (beg * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 8, (end * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 10, endHz);\n            sndInstrPtr += BUFFER_SIZE;\n        }\n        sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, 0) // terminate\n        return sndInstrPtr\n    }\n\n\n    export class MelodyPlayer {\n        melody: Melody;\n\n        onPlayFinished: () => void;\n\n        constructor(m: Melody) {\n            this.melody = m\n        }\n\n        stop() {\n            this.melody = null\n        }\n\n        protected queuePlayInstructions(timeDelta: number, buf: Buffer) {\n            queuePlayInstructions(timeDelta, buf)\n        }\n\n        play(volume: number) {\n            if (!this.melody)\n                return\n            volume = Math.clamp(0, 255, (volume * music.volume()) >> 8)\n\n            let notes = this.melody._text\n            let pos = 0;\n            let duration = 4; //Default duration (Crotchet)\n            let octave = 4; //Middle octave\n            let tempo = 120; // default tempo\n\n            let hz = 0\n            let endHz = -1\n            let ms = 0\n            let timePos = 0\n            let startTime = control.millis()\n            let now = 0\n\n            let envA = 0\n            let envD = 0\n            let envS = 255\n            let envR = 0\n            let soundWave = 1 // triangle\n            let sndInstr = control.createBuffer(5 * BUFFER_SIZE)\n            let sndInstrPtr = 0\n\n            const addForm = (formDuration: number, beg: number, end: number, msOff: number) => {\n                let freqStart = hz;\n                let freqEnd = endHz;\n\n                const envelopeWidth = ms > 0 ? ms : duration * Math.idiv(15000, tempo) + envR;\n                if (endHz != hz && envelopeWidth != 0) {\n                    const slope = (freqEnd - freqStart) / envelopeWidth;\n                    freqStart = hz + slope * msOff;\n                    freqEnd = hz + slope * (msOff + formDuration);\n                }\n                sndInstrPtr = addNote(sndInstr, sndInstrPtr, formDuration, beg, end, soundWave, freqStart, volume, freqEnd);\n            }\n\n            const scanNextWord = () => {\n                if (!this.melody)\n                    return \"\"\n\n                // eat space\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c != ' ' && c != '\\r' && c != '\\n' && c != '\\t')\n                        break;\n                    pos++;\n                }\n\n                // read note\n                let note = \"\";\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c == ' ' || c == '\\r' || c == '\\n' || c == '\\t')\n                        break;\n                    note += c;\n                    pos++;\n                }\n                return note;\n            }\n\n            enum Token {\n                Note,\n                Octave,\n                Beat,\n                Tempo,\n                Hz,\n                EndHz,\n                Ms,\n                WaveForm,\n                EnvelopeA,\n                EnvelopeD,\n                EnvelopeS,\n                EnvelopeR\n            }\n\n            let token: string = \"\";\n            let tokenKind = Token.Note;\n\n            // [ABCDEFG] (\\d+)  (:\\d+)  (-\\d+)\n            // note      octave length  tempo\n            // R (:\\d+) - rest\n            // !\\d+,\\d+ - sound at frequency with given length (Hz,ms); !\\d+ and !\\d+,:\\d+ also possible\n            // @\\d+,\\d+,\\d+,\\d+ - ADSR envelope - ms,ms,volume,ms; volume is 0-255\n            // ~\\d+ - wave form:\n            //   1 - triangle\n            //   2 - sawtooth\n            //   3 - sine\n            //   4 - pseudorandom square wave noise (tunable)\n            //   5 - white noise (ignores frequency)\n            //   11 - square 10%\n            //   12 - square 20%\n            //   ...\n            //   15 - square 50%\n            //   16 - filtered square wave, cycle length 16\n            //   17 - filtered square wave, cycle length 32\n            //   18 - filtered square wave, cycle length 64\n\n            const consumeToken = () => {\n                if (token && tokenKind != Token.Note) {\n                    const d = parseInt(token);\n                    switch (tokenKind) {\n                        case Token.Octave: octave = d; break;\n                        case Token.Beat:\n                            duration = Math.max(1, Math.min(16, d));\n                            ms = -1;\n                            break;\n                        case Token.Tempo: tempo = Math.max(1, d); break;\n                        case Token.Hz: hz = d; tokenKind = Token.Ms; break;\n                        case Token.Ms: ms = d; break;\n                        case Token.WaveForm: soundWave = Math.clamp(1, 18, d); break;\n                        case Token.EnvelopeA: envA = d; tokenKind = Token.EnvelopeD; break;\n                        case Token.EnvelopeD: envD = d; tokenKind = Token.EnvelopeS; break;\n                        case Token.EnvelopeS: envS = Math.clamp(0, 255, d); tokenKind = Token.EnvelopeR; break;\n                        case Token.EnvelopeR: envR = d; break;\n                        case Token.EndHz: endHz = d; break;\n                    }\n                    token = \"\";\n                }\n            }\n\n            while (true) {\n                let currNote = scanNextWord();\n                let prevNote: boolean = false;\n                if (!currNote) {\n                    let timeLeft = timePos - now\n                    if (timeLeft > 0)\n                        pause(timeLeft)\n                    if (this.onPlayFinished)\n                        this.onPlayFinished();\n                    return;\n                }\n\n                hz = -1;\n\n                let note: number = 0;\n                token = \"\";\n                tokenKind = Token.Note;\n\n                for (let i = 0; i < currNote.length; i++) {\n                    let noteChar = currNote.charAt(i);\n                    switch (noteChar) {\n                        case 'c': case 'C': note = 1; prevNote = true; break;\n                        case 'd': case 'D': note = 3; prevNote = true; break;\n                        case 'e': case 'E': note = 5; prevNote = true; break;\n                        case 'f': case 'F': note = 6; prevNote = true; break;\n                        case 'g': case 'G': note = 8; prevNote = true; break;\n                        case 'a': case 'A': note = 10; prevNote = true; break;\n                        case 'B': note = 12; prevNote = true; break;\n                        case 'r': case 'R': hz = 0; prevNote = false; break;\n                        case '#': note++; prevNote = false; break;\n                        case 'b': if (prevNote) note--; else { note = 12; prevNote = true; } break;\n                        case ',':\n                            consumeToken();\n                            prevNote = false;\n                            break;\n                        case '!':\n                            tokenKind = Token.Hz;\n                            prevNote = false;\n                            break;\n                        case '@':\n                            consumeToken();\n                            tokenKind = Token.EnvelopeA;\n                            prevNote = false;\n                            break;\n                        case '~':\n                            consumeToken();\n                            tokenKind = Token.WaveForm;\n                            prevNote = false;\n                            break;\n                        case ':':\n                            consumeToken();\n                            tokenKind = Token.Beat;\n                            prevNote = false;\n                            break;\n                        case '-':\n                            consumeToken();\n                            tokenKind = Token.Tempo;\n                            prevNote = false;\n                            break;\n                        case '^':\n                            consumeToken();\n                            tokenKind = Token.EndHz;\n                            break;\n                        default:\n                            if (tokenKind == Token.Note)\n                                tokenKind = Token.Octave;\n                            token += noteChar;\n                            prevNote = false;\n                            break;\n                    }\n                }\n                consumeToken();\n\n                if (note && hz < 0) {\n                    const keyNumber = note + (12 * (octave - 1));\n                    hz = freqs.getNumber(NumberFormat.UInt16LE, keyNumber * 2) || 0;\n                }\n\n                let currMs = ms\n\n                if (currMs <= 0) {\n                    const beat = Math.idiv(15000, tempo);\n                    currMs = duration * beat\n                }\n\n                if (hz < 0) {\n                    // no frequency specified, so no duration\n                } else if (hz == 0) {\n                    timePos += currMs\n                } else {\n                    if (endHz < 0) {\n                        endHz = hz;\n                    }\n\n                    sndInstrPtr = 0\n                    addForm(envA, 0, 255, 0)\n                    addForm(envD, 255, envS, envA)\n                    addForm(currMs - (envA + envD), envS, envS, envD + envA)\n                    addForm(envR, envS, 0, currMs)\n\n                    this.queuePlayInstructions(timePos - now, sndInstr.slice(0, sndInstrPtr))\n                    endHz = -1;\n                    timePos += currMs // don't add envR - it's supposed overlap next sound\n                }\n\n                let timeLeft = timePos - now\n                if (timeLeft > 200) {\n                    pause(timeLeft - 100)\n                    now = control.millis() - startTime\n                }\n            }\n        }\n    }\n\n    //% blockId=music_song_field_editor\n    //% block=\"song $song\"\n    //% song.fieldEditor=musiceditor\n    //% song.fieldOptions.decompileLiterals=true\n    //% song.fieldOptions.taggedTemplate=\"hex;assets.song\"\n    //% song.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% song.fieldOptions.decompileArgumentAsString=\"true\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% help=music/create-song\n    export function createSong(song: Buffer): Playable {\n        return new sequencer.Song(song);\n    }\n\n    export function playInstructions(when: number, instructions: Buffer) {\n        queuePlayInstructions(when, instructions);\n    }\n\n    export function lookupFrequency(note: number) {\n        return freqs.getNumber(NumberFormat.UInt16LE, note * 2) || 0\n    }\n\n    //% fixedInstance whenUsed block=\"ba ding\"\n    export const baDing = new Melody('b5:1 e6:3')\n\n    //% fixedInstance whenUsed block=\"wawawawaa\"\n    export const wawawawaa = new Melody('~15 e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8')\n\n    //% fixedInstance whenUsed block=\"jump up\"\n    export const jumpUp = new Melody('c5:1 d e f g')\n\n    //% fixedInstance whenUsed block=\"jump down\"\n    export const jumpDown = new Melody('g5:1 f e d c')\n\n    //% fixedInstance whenUsed block=\"power up\"\n    export const powerUp = new Melody('g4:1 c5 e g:2 e:1 g:3')\n\n    //% fixedInstance whenUsed block=\"power down\"\n    export const powerDown = new Melody('g5:1 d# c g4:2 b:1 c5:3')\n\n    //% fixedInstance whenUsed block=\"magic wand\"\n    export const magicWand = new Melody('F#6:1-300 G# A# B C7# D# F F# G# A# B:6')\n    //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n\n    //% fixedInstance whenUsed block=\"siren\"\n    export const siren = new Melody('a4 d5 a4 d5 a4 d5')\n\n    //% fixedInstance whenUsed block=\"pew pew\"\n    export const pewPew = new Melody('!1200,200^50')\n\n    //% fixedInstance whenUsed block=\"knock\"\n    export const knock = new Melody('~4 @0,0,255,150 !300,1 !211,1')\n\n    //% fixedInstance whenUsed block=\"footstep\"\n    export const footstep = new Melody('~4 @0,0,60,50 !200,1')\n\n    //% fixedInstance whenUsed block=\"thump\"\n    export const thump = new Melody('~4 @0,0,255,150 !100,1')\n\n    //% fixedInstance whenUsed block=\"small crash\"\n    export const smallCrash = new Melody('~4 @10,490,0,1 !800,1')\n\n    //% fixedInstance whenUsed block=\"big crash\"\n    export const bigCrash = new Melody('~4 @10,990,0,1 !400,1')\n\n    //% fixedInstance whenUsed block=\"zapped\"\n    export const zapped = new Melody('~16 @10,490,0,0 !1600,500^1')\n\n    //% fixedInstance whenUsed block=\"buzzer\"\n    export const buzzer = new Melody('~16 @10,0,255,250 !2000,300')\n\n    //% fixedInstance whenUsed block=\"sonar\"\n    export const sonar = new Melody('~16 @10,1500,0,0 !200,1 !200,1500^190')\n\n    //% fixedInstance whenUsed block=\"spooky\"\n    export const spooky = new Melody('~16 @700,1300,0,0 !100,1 ~18 !108,2000')\n\n    //% fixedInstance whenUsed block=\"beam up\"\n    export const beamUp = new Melody('~18 @10,1500,0,0 !200,1500^4000')\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    //% block=\"2\"\n    Double = 32,\n    //% block=\"4\",\n    Breve = 64,\n    //% block=\"1/3\",\n    Triplet = 128\n}\n\nnamespace music {\n\n    let beatsPerMinute: number;\n\n    /**\n    * Play a tone.\n    * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n    */\n    //% help=music/ring-tone\n    //% blockId=music_ring block=\"ring tone|at %note=device_note\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music inBasicCategory=true\n    //% weight=75 blockGap=8\n    //% group=\"Tone\"\n    export function ringTone(frequency: number) {\n        playTone(frequency, 0);\n    }\n\n    /**\n    * Rest, or play silence, for some time (in milliseconds).\n    * @param ms rest duration in milliseconds (ms), eg: BeatFraction.Half\n    */\n    //% help=music/rest\n    //% blockId=music_rest block=\"rest|for %duration=device_beat\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music\n    //% weight=74\n    //% group=\"Tone\"\n    export function rest(ms: number) {\n        playTone(0, Math.max(ms, 20));\n    }\n\n    function init() {\n        if (!beatsPerMinute) beatsPerMinute = 120;\n    }\n\n    /**\n     * Return the duration of a beat in milliseconds (the beat fraction).\n     * @param fraction the fraction of the current whole note, eg: BeatFraction.Half\n     */\n    //% help=music/beat\n    //% blockId=device_beat block=\"%fraction|beat\"\n    //% weight=9 blockGap=8\n    //% group=\"Tempo\"\n    export function beat(fraction?: BeatFraction): number {\n        init();\n        if (fraction == null) fraction = BeatFraction.Whole;\n        let beat = 60000 / beatsPerMinute;\n        switch (fraction) {\n            case BeatFraction.Half: beat /= 2; break;\n            case BeatFraction.Quarter: beat /= 4; break;\n            case BeatFraction.Eighth: beat /= 8; break;\n            case BeatFraction.Sixteenth: beat /= 16; break;\n            case BeatFraction.Double: beat *= 2; break;\n            case BeatFraction.Breve: beat *= 4; break;\n            case BeatFraction.Triplet: beat /= 3; break;\n        }\n        return beat >> 0;\n    }\n\n    /**\n     * Return the tempo in beats per minute (bpm).\n     * 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\n    //% blockId=device_tempo block=\"tempo (bpm)\"\n    //% weight=64\n    //% group=\"Tempo\"\n    export function tempo(): number {\n        init();\n        return beatsPerMinute;\n    }\n\n    /**\n     * Change the tempo up or down by some amount of beats per minute (bpm).\n     * @param bpm The change in beats per minute to the tempo, eg: 20\n     */\n    //% help=music/change-tempo-by weight=37\n    //% blockId=device_change_tempo block=\"change tempo by %value|(bpm)\"\n    //% weight=66 blockGap=8\n    //% group=\"Tempo\"\n    export function changeTempoBy(bpm: number): void {\n        init();\n        setTempo(beatsPerMinute + bpm);\n    }\n\n    /**\n     * Set the tempo a number of beats per minute (bpm).\n     * @param bpm The new tempo in beats per minute, eg: 120\n     */\n    //% help=music/set-tempo\n    //% blockId=device_set_tempo block=\"set tempo to %value|(bpm)\"\n    //% bpm.min=4 bpm.max=400\n    //% weight=65 blockGap=8\n    //% group=\"Tempo\"\n    export function setTempo(bpm: number): void {\n        init();\n        if (bpm > 0) {\n            beatsPerMinute = Math.max(1, bpm >> 0);\n        }\n    }\n}\n","ns.ts":"\n/**\n * Generation of music tones.\n */\n//% color=#E30FC0 weight=90 icon=\"\\uf025\"\n//% blockGap=8\n//% groups='[\"Songs\", \"Sounds\", \"Tone\",  \"Volume\", \"Tempo\"]'\nnamespace music {\n}","piano.ts":"namespace music {\n    /**\n     * Get the frequency of a note.\n     * @param name the note name, eg: Note.C\n     */\n    //% weight=1 help=music/note-frequency\n    //% blockId=device_note block=\"%note\"\n    //% shim=TD_ID\n    //% color=\"#FFFFFF\" colorSecondary=\"#FFFFFF\" colorTertiary=\"#D83B01\"\n    //% note.fieldEditor=\"note\" note.defl=\"262\"\n    //% note.fieldOptions.decompileLiterals=true\n    //% useEnumVal=1\n    //% weight=10 blockGap=8\n    //% group=\"Tone\"\n    export function noteFrequency(name: Note): number {\n        return name;\n    }\n}","playable.ts":"namespace music {\n    export enum PlaybackMode {\n        //% block=\"until done\"\n        UntilDone,\n        //% block=\"in background\"\n        InBackground,\n        //% block=\"looping in background\"\n        LoopingInBackground\n    }\n\n    let stateStack: PlayableState[];\n\n    class PlayableState {\n        looping: Playable[];\n        constructor() {\n            this.looping = [];\n        }\n\n        stopLooping() {\n            for (const p of this.looping) {\n                p.stopped = true;\n            }\n            this.looping = [];\n        }\n    }\n\n    function state() {\n        _init();\n        return stateStack[stateStack.length - 1];\n    }\n\n    function _init() {\n        if (stateStack) return;\n        stateStack = [new PlayableState()];\n\n        game.addScenePushHandler(() => {\n            stateStack.push(new PlayableState());\n        });\n\n        game.addScenePopHandler(() => {\n            stateStack.pop();\n            if (stateStack.length === 0) stateStack.push(new PlayableState());\n        });\n    }\n\n    export class Playable {\n        stopped: boolean;\n        constructor() {\n\n        }\n\n        play(playbackMode: PlaybackMode) {\n            // subclass\n        }\n\n        loop() {\n            state().looping.push(this);\n            this.stopped = false;\n\n            control.runInParallel(() => {\n                while (!this.stopped) {\n                    this.play(PlaybackMode.UntilDone);\n                }\n            });\n        }\n    }\n\n    export class MelodyPlayable extends Playable {\n        constructor(public melody: Melody) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                this.melody.play(music.volume());\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                this.melody.playUntilDone(music.volume());\n            }\n            else {\n                this.melody.loop(music.volume());\n            }\n        }\n    }\n\n    export class TonePlayable extends Playable {\n        constructor(public pitch: number, public duration: number) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                control.runInParallel(() => music.playTone(this.pitch, this.duration));\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                music.playTone(this.pitch, this.duration);\n                if (this.duration > 2000) {\n                    pause(this.duration);\n                }\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n    /**\n     * Play a song, melody, or other sound. The music plays until finished or can play as a\n     * background task.\n     * @param toPlay the song or melody to play\n     * @param playbackMode play the song or melody until it's finished or as background task\n     */\n    //% blockId=\"music_playable_play\"\n    //% block=\"play $toPlay $playbackMode\"\n    //% toPlay.shadow=music_melody_playable\n    //% group=\"Sounds\"\n    //% help=\"music/play\"\n    export function play(toPlay: Playable, playbackMode: PlaybackMode) {\n        toPlay.play(playbackMode);\n    }\n\n    /**\n     * Create a Playable object for a melody.\n     * @param melody the melody to make playable\n     */\n    //% blockId=\"music_melody_playable\"\n    //% block=\"sound $melody\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    //% blockHidden\n    //% help=music/melody-playable\n    export function melodyPlayable(melody: Melody): Playable {\n        return new MelodyPlayable(melody);\n    }\n\n    /**\n     * Create a Playable object for a melody string containg notes.\n     * @param melody the melody string to make playable\n     */\n    //% blockId=\"music_string_playable\"\n    //% block=\"melody $melody at tempo $tempo|(bpm)\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% melody.shadow=melody_editor\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% help=music/string-playable\n    export function stringPlayable(melody: string, tempo: number): Playable {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        return new MelodyPlayable(new Melody(formattedMelody));\n    }\n\n    /**\n     * Create a Playable object for a single tone and its duration.\n     * @param note the note or tone frequency to play\n     * @param duration the duration of the tone in milliseconds (ms)\n     */\n    //% blockId=\"music_tone_playable\"\n    //% block=\"tone $note for $duration\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Tone\"\n    //% duplicateShadowOnDrag\n    //% note.shadow=device_note\n    //% duration.shadow=device_beat\n    //% parts=\"headphone\"\n    //% help=music/tone-playable\n    export function tonePlayable(note: number, duration: number): Playable {\n        return new TonePlayable(note, duration);\n    }\n\n    export function _stopPlayables() {\n        state().stopLooping();\n    }\n}","pxt.json":"{\n    \"name\": \"mixer---none\",\n    \"description\": \"The music library with a mixer\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"SoundOutput.h\",\n        \"sound.cpp\",\n        \"melody.h\",\n        \"melody.cpp\",\n        \"melody.ts\",\n        \"piano.ts\",\n        \"legacy.ts\",\n        \"ns.ts\",\n        \"targetoverrides.ts\",\n        \"music.ts\",\n        \"soundEffect.ts\",\n        \"instrument.ts\",\n        \"sequencer.ts\",\n        \"playable.ts\",\n        \"pxtparts.json\",\n        \"headphone.svg\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","pxtparts.json":"{\n    \"headphone\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"image\": \"headphone.svg\",\n            \"width\": 142,\n            \"height\": 180,\n            \"pinDistance\": 20,\n            \"pinLocations\": [\n                {\n                    \"x\": 17,\n                    \"y\": 11\n                },\n                {\n                    \"x\": 55,\n                    \"y\": 50\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"A0\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","sequencer.ts":"namespace music.sequencer {\n    const SEQUENCER_STOP_MESSAGE = 3243;\n    const SEQUENCER_TICK_MESSAGE = 3244;\n    const SEQUENCER_STATE_CHANGE_MESSAGE = 3245;\n    const SEQUENCER_LOOPED_MESSAGE = 3246;\n\n    export class Sequencer {\n        currentTick: number;\n        isPlaying: boolean;\n        isLooping: boolean;\n        isRunning: boolean;\n\n        constructor(public song: Song) {\n            this.currentTick = 0;\n            this.isPlaying = false;\n            this.isLooping = false;\n        }\n\n        start(loop: boolean) {\n            this.currentTick = 0;\n            this.isLooping = loop;\n            this.isPlaying = true;\n\n            if (this.isRunning) return;\n            this.isRunning = true;\n\n            control.runInParallel(() => {\n                while (this.isPlaying) {\n                    this.scheduleCurrentTick();\n\n                    this.currentTick ++;\n\n                    if (this.currentTick >= this.song.beatsPerMeasure * this.song.measures * this.song.ticksPerBeat) {\n                        if (this.isLooping) this.currentTick = 0;\n                        else this.isPlaying = false;\n                    }\n\n                    pause(this.tickToMs(1))\n                }\n                this.isRunning = false;\n            })\n        }\n\n        stop() {\n            this.isPlaying = false;\n        }\n\n        tickToMs(ticks: number) {\n            return ((60000 / this.song.beatsPerMinute) / this.song.ticksPerBeat) * ticks;\n        }\n\n        protected scheduleCurrentTick() {\n            for (const track of this.song.tracks) {\n                if (track.currentNoteEvent.startTick === this.currentTick) {\n                    if (track.isMelodicTrack) {\n                        this.scheduleMelodicTrack(track as MelodicTrack);\n                    }\n                    else {\n                        this.scheduleDrumTrack(track as DrumTrack);\n                    }\n\n                    track.advanceNoteEvent();\n                }\n            }\n        }\n\n        protected scheduleMelodicTrack(track: MelodicTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderInstrument(\n                        track.instrument,\n                        lookupFrequency(track.currentNoteEvent.getNote(i, track.instrument.octave)),\n                        this.tickToMs(track.currentNoteEvent.endTick - track.currentNoteEvent.startTick),\n                        music.volume()\n                    )\n                );\n            }\n        }\n\n        protected scheduleDrumTrack(track: DrumTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderDrumInstrument(\n                        track.drums[track.currentNoteEvent.getNote(i, undefined)],\n                        music.volume()\n                    )\n                );\n            }\n        }\n    }\n\n    let activeSimSequencers: _SimulatorSequencer[];\n    export function _stopAllSimSequencers() {\n        if (activeSimSequencers) {\n            for (const seq of activeSimSequencers) {\n                seq.stop();\n                seq.dispose();\n            }\n            activeSimSequencers = [];\n        }\n    }\n\n    // Simulator only! Does nothing on hardware\n    export class _SimulatorSequencer {\n        protected id: number;\n\n        constructor() {\n            if (!activeSimSequencers) activeSimSequencers = [];\n            activeSimSequencers.push(this);\n            this.id = _createSequencer();\n            this.setVolume(music.volume());\n        }\n\n        play(song: Buffer, loop: boolean) {\n            this.setVolume(music.volume());\n            _sequencerPlaySong(this.id, song, loop)\n        }\n\n        stop() {\n            _sequencerStop(this.id);\n        }\n\n        setVolume(volume: number) {\n            _sequencerSetVolume(this.id, volume);\n        }\n\n        setTrackVolume(trackIndex: number, volume: number) {\n            _sequencerSetTrackVolume(this.id, trackIndex, volume)\n        }\n\n        setDrumTrackVolume(trackIndex: number, drumIndex: number, volume: number) {\n            _sequencerSetDrumTrackVolume(this.id, drumIndex, trackIndex, volume)\n        }\n\n        state() {\n            return _sequencerState(this.id) || \"stop\";\n        }\n\n        currentTick() {\n            return _sequencerCurrentTick(this.id);\n        }\n\n        dispose() {\n            _sequencerDispose(this.id);\n        }\n\n        onTick(handler: (tick: number) => void) {\n            control.onEvent(SEQUENCER_TICK_MESSAGE, this.id, () => {\n                handler(this.currentTick());\n            });\n        }\n\n        onStateChange(handler: (state: string) => void) {\n            control.onEvent(SEQUENCER_STATE_CHANGE_MESSAGE, this.id, () => {\n                handler(this.state());\n            });\n        }\n\n        onStop(handler: () => void) {\n            control.onEvent(SEQUENCER_STOP_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n\n        onLooped(handler: () => void) {\n            control.onEvent(SEQUENCER_LOOPED_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n    }\n\n    //% promise\n    //% shim=music::_createSequencer\n    declare function _createSequencer(): number\n\n    //% shim=music::_sequencerState\n    declare function _sequencerState(id: number): string;\n\n    //% shim=music::_sequencerCurrentTick\n    declare function _sequencerCurrentTick(id: number): number;\n\n    //% shim=music::_sequencerPlaySong\n    declare function _sequencerPlaySong(id: number, song: Buffer, loop: boolean): void;\n\n    //% shim=music::_sequencerStop\n    declare function _sequencerStop(id: number): void;\n\n    //% shim=music::_sequencerSetVolume\n    declare function _sequencerSetVolume(id: number, volume: number): void;\n\n    //% shim=music::_sequencerSetVolumeForAll\n    declare function _sequencerSetVolumeForAll(volume: number): void;\n\n    //% shim=music::_sequencerSetTrackVolume\n    declare function _sequencerSetTrackVolume(id: number, trackIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerSetDrumTrackVolume\n    declare function _sequencerSetDrumTrackVolume(id: number, trackIndex: number, drumIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerDispose\n    declare function _sequencerDispose(id: number): void;\n}","sound.cpp":"// to be overridden\n","soundEffect.ts":"enum WaveShape {\n    //% block=\"sine\"\n    Sine = 0,\n    //% block=\"sawtooth\"\n    Sawtooth = 1,\n    //% block=\"triangle\"\n    Triangle = 2,\n    //% block=\"square\"\n    Square = 3,\n    //% block=\"noise\"\n    Noise = 4\n}\n\nenum InterpolationCurve {\n    //% block=\"linear\"\n    Linear,\n    //% block=\"curve\"\n    Curve,\n    //% block=\"logarithmic\"\n    Logarithmic\n}\n\nenum SoundExpressionEffect {\n    //% block=\"none\"\n    None = 0,\n    //% block=\"vibrato\"\n    Vibrato = 1,\n    //% block=\"tremolo\"\n    Tremolo = 2,\n    //% block=\"warble\"\n    Warble = 3\n}\n\nenum SoundExpressionPlayMode {\n    //% block=\"until done\"\n    UntilDone,\n    //% block=\"in background\"\n    InBackground\n}\n\nnamespace music {\n    export class SoundEffect extends Playable {\n        waveShape: WaveShape;\n        startFrequency: number;\n        endFrequency: number;\n        startVolume: number;\n        endVolume: number;\n        duration: number;\n        effect: SoundExpressionEffect;\n        interpolation: InterpolationCurve;\n\n        constructor() {\n            super();\n            this.waveShape = WaveShape.Sine;\n            this.startFrequency = 5000;\n            this.endFrequency = 1;\n            this.startVolume = 255;\n            this.endVolume = 0;\n            this.duration = 1000;\n            this.effect = SoundExpressionEffect.None;\n            this.interpolation = InterpolationCurve.Linear;\n        }\n\n        toBuffer(volume?: number) {\n            if (volume === undefined) volume = music.volume();\n\n            return soundToInstructionBuffer(\n                this.waveShape,\n                this.startFrequency,\n                this.endFrequency,\n                this.startVolume,\n                this.endVolume,\n                this.duration,\n                this.effect,\n                this.interpolation,\n                20,\n                1,\n                volume\n            );\n        }\n\n        play(playbackMode: PlaybackMode) {\n            const toPlay = this.toBuffer(music.volume());\n            if (playbackMode === PlaybackMode.InBackground) {\n                queuePlayInstructions(0, toPlay);\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                queuePlayInstructions(0, toPlay);\n                pause(this.duration)\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n\n    /**\n     * Play a SoundEffect.\n     * @param sound the SoundEffect to play\n     * @param mode the play mode, play until done or in the background\n     */\n    //% blockId=soundExpression_playSoundEffect\n    //% block=\"play sound $sound $mode\"\n    //% weight=30\n    //% help=music/play-sound-effect\n    //% blockGap=8\n    //% group=\"Sounds\"\n    //% deprecated=1\n    export function playSoundEffect(sound: SoundEffect, mode: SoundExpressionPlayMode) {\n        const toPlay = sound.toBuffer(music.volume());\n\n        queuePlayInstructions(0, toPlay);\n        if (mode === SoundExpressionPlayMode.UntilDone) {\n            pause(sound.duration);\n        }\n    }\n\n    /**\n     * Create a sound expression from a set of sound effect parameters.\n     * @param waveShape waveform of the sound effect\n     * @param startFrequency starting frequency for the sound effect waveform\n     * @param endFrequency ending frequency for the sound effect waveform\n     * @param startVolume starting volume of the sound, or starting amplitude\n     * @param endVolume ending volume of the sound, or ending amplitude\n     * @param duration the amount of time in milliseconds (ms) that sound will play for\n     * @param effect the effect to apply to the waveform or volume\n     * @param interpolation interpolation method for frequency scaling\n     */\n    //% blockId=soundExpression_createSoundEffect\n    //% help=music/create-sound-effect\n    //% block=\"$waveShape|| start frequency $startFrequency end frequency $endFrequency duration $duration start volume $startVolume end volume $endVolume effect $effect interpolation $interpolation\"\n    //% waveShape.defl=WaveShape.Sine\n    //% waveShape.fieldEditor=soundeffect\n    //% waveShape.fieldOptions.useMixerSynthesizer=true\n    //% startFrequency.defl=5000\n    //% startFrequency.min=0\n    //% startFrequency.max=5000\n    //% endFrequency.defl=0\n    //% endFrequency.min=0\n    //% endFrequency.max=5000\n    //% startVolume.defl=255\n    //% startVolume.min=0\n    //% startVolume.max=255\n    //% endVolume.defl=0\n    //% endVolume.min=0\n    //% endVolume.max=255\n    //% duration.defl=500\n    //% duration.min=1\n    //% duration.max=9999\n    //% effect.defl=SoundExpressionEffect.None\n    //% interpolation.defl=InterpolationCurve.Linear\n    //% compileHiddenArguments=true\n    //% inlineInputMode=\"variable\"\n    //% inlineInputModeLimit=3\n    //% expandableArgumentBreaks=\"3,5\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=20\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    export function createSoundEffect(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve): SoundEffect {\n        const result = new SoundEffect();\n\n        result.waveShape = waveShape;\n        result.startFrequency = startFrequency;\n        result.endFrequency = endFrequency;\n        result.startVolume = startVolume;\n        result.endVolume = endVolume;\n        result.duration = duration;\n        result.effect = effect;\n        result.interpolation = interpolation;\n\n        return result;\n    }\n\n    interface Step {\n        frequency: number;\n        volume: number;\n    }\n\n     export function soundToInstructionBuffer(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve, fxSteps: number, fxRange: number, globalVolume: number) {\n        const steps: Step[] = [];\n\n        // Optimize the simple case\n        if (interpolation === InterpolationCurve.Linear && effect === SoundExpressionEffect.None) {\n            steps.push({\n                frequency: startFrequency,\n                volume: (startVolume / 255) * globalVolume,\n            })\n            steps.push({\n                frequency: endFrequency,\n                volume: (endVolume / 255) * globalVolume,\n            })\n        }\n        else {\n\n            fxSteps = Math.min(fxSteps, Math.floor(duration / 5))\n\n            const getVolumeAt = (t: number) => ((startVolume + t * (endVolume - startVolume) / duration) / 255) * globalVolume;\n            let getFrequencyAt: (t: number) => number;\n\n            switch (interpolation) {\n                case InterpolationCurve.Linear:\n                    getFrequencyAt = t => startFrequency + t * (endFrequency - startFrequency) / duration;\n                    break;\n                case InterpolationCurve.Curve:\n                    getFrequencyAt = t => startFrequency + (endFrequency - startFrequency) * Math.sin(t / duration * (Math.PI / 2));\n                    break;\n                case InterpolationCurve.Logarithmic:\n                    getFrequencyAt = t => startFrequency + (Math.log(1 + 9 * (t / duration)) / Math.log(10)) * (endFrequency - startFrequency)\n                    break;\n            }\n\n            const timeSlice = duration / fxSteps;\n\n            for (let i = 0; i < fxSteps; i++) {\n                const newStep = {\n                    frequency: getFrequencyAt(i * timeSlice),\n                    volume: getVolumeAt(i * timeSlice)\n                };\n\n                if (effect === SoundExpressionEffect.Tremolo) {\n                    if (i % 2 === 0) {\n                        newStep.volume = Math.max(newStep.volume - fxRange * 500, 0)\n                    }\n                    else {\n                        newStep.volume = Math.min(newStep.volume + fxRange * 500, 1023)\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Vibrato) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 100, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 100\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Warble) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 1000, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 1000\n                    }\n                }\n\n                steps.push(newStep)\n            }\n        }\n\n        const out = control.createBuffer(12 * (steps.length - 1));\n        const stepDuration = Math.floor(duration / (steps.length - 1))\n\n        for (let i = 0; i < steps.length - 1; i++) {\n            const offset = i * 12;\n            out.setNumber(NumberFormat.UInt8LE, offset, waveToValue(waveShape));\n            out.setNumber(NumberFormat.UInt16LE, offset + 2, steps[i].frequency);\n            out.setNumber(NumberFormat.UInt16LE, offset + 4, stepDuration);\n            out.setNumber(NumberFormat.UInt16LE, offset + 6, steps[i].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 8, steps[i + 1].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 10, steps[i + 1].frequency);\n        }\n\n        return out;\n    }\n\n    function waveToValue(wave: WaveShape) {\n        switch (wave) {\n            case WaveShape.Square: return 15;\n            case WaveShape.Sine: return 3;\n            case WaveShape.Triangle: return 1;\n            case WaveShape.Noise: return 18;\n            case WaveShape.Sawtooth: return 2;\n        }\n    }\n\n\n    /**\n     * Generate a random similar sound effect to the given one.\n     *\n     * @param sound the sound effect\n     */\n    //% blockId=soundExpression_generateSimilarSound\n    //% block=\"randomize $sound\"\n    //% sound.shadow=soundExpression_createSoundEffect\n    //% weight=0 help=music/randomize-sound\n    //% blockGap=8\n    //% group=\"Sounds\"\n    export function randomizeSound(sound: SoundEffect) {\n        const res = new SoundEffect();\n        res.waveShape = sound.waveShape;\n        res.startFrequency = sound.startFrequency;\n        res.endFrequency = sound.endFrequency;\n        res.startVolume = sound.startVolume;\n        res.endVolume = sound.endVolume;\n        res.duration = sound.duration;\n        res.effect = sound.effect;\n        res.interpolation = randomInterpolation();\n\n        res.duration = Math.clamp(\n            Math.min(100, res.duration),\n            Math.max(2000, res.duration),\n            res.duration + (Math.random() - 0.5) * res.duration,\n        );\n\n        if (res.waveShape === WaveShape.Noise) {\n            // The primary waveforms don't produce sounds that are similar to noise,\n            // but adding an effect sorta does\n            if (Math.percentChance(20)) {\n                res.waveShape = randomWave();\n                res.effect = randomEffect();\n            }\n        }\n        else {\n            res.waveShape = randomWave();\n\n            // Adding an effect can drastically alter the sound, so keep it\n            // at a low percent chance unless there already is one\n            if (res.effect !== SoundExpressionEffect.None || Math.percentChance(10)) {\n                res.effect = randomEffect();\n            }\n        }\n\n        // Instead of randomly changing the frequency, change the slope and choose\n        // a new start frequency. This keeps a similar profile to the sound\n        const oldFrequencyDifference = res.endFrequency - res.startFrequency;\n        let newFrequencyDifference = oldFrequencyDifference + (oldFrequencyDifference * 2) * (Math.random() - 0.5);\n\n        if (Math.sign(oldFrequencyDifference) !== Math.sign(newFrequencyDifference)) {\n            newFrequencyDifference *= -1;\n        }\n\n        newFrequencyDifference = Math.clamp(-5000, 5000, newFrequencyDifference);\n\n        res.startFrequency = Math.clamp(\n            Math.max(-newFrequencyDifference, 1),\n            Math.clamp(1, 5000, 5000 - newFrequencyDifference),\n            Math.random() * 5000,\n        );\n\n        res.endFrequency = Math.clamp(1, 5000, res.startFrequency + newFrequencyDifference);\n\n        // Same strategy for volume\n        const oldVolumeDifference = res.endVolume - res.startVolume;\n        let newVolumeDifference = oldVolumeDifference + oldVolumeDifference * (Math.random() - 0.5);\n\n        newVolumeDifference = Math.clamp(-255, 255, newVolumeDifference);\n\n        if (Math.sign(oldVolumeDifference) !== Math.sign(newVolumeDifference)) {\n            newVolumeDifference *= -1;\n        }\n\n        res.startVolume = Math.clamp(\n            Math.max(-newVolumeDifference, 0),\n            Math.clamp(0, 255, 255 - newVolumeDifference),\n            Math.random() * 255,\n        );\n\n        res.endVolume = Math.clamp(0, 255, res.startVolume + newVolumeDifference);\n\n        return res;\n    }\n\n    function randomWave() {\n        switch (Math.randomRange(0, 3)) {\n            case 1: return WaveShape.Sawtooth;\n            case 2: return WaveShape.Square;\n            case 3: return WaveShape.Triangle;\n            case 0:\n            default:\n                return WaveShape.Sine;\n        }\n    }\n\n    function randomEffect() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return SoundExpressionEffect.Warble;\n            case 2: return  SoundExpressionEffect.Tremolo;\n            case 0:\n            default:\n                return SoundExpressionEffect.Vibrato;\n        }\n    }\n\n    function randomInterpolation() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return InterpolationCurve.Linear;\n            case 2: return  InterpolationCurve.Curve;\n            case 0:\n            default:\n                return InterpolationCurve.Logarithmic;\n        }\n    }\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n}","targetoverrides.ts":"\n","test.ts":"for(let i = 1000; i > 0; i -= 50)\n    music.playTone(440, i)\n\nfor(let i = 0; i < 1000; i += 20)\n    music.playTone(440, i)\n"},"mixer---nrf52":{"SoundOutput.h":"#include \"NRF52PWM.h\"\n#include \"Synthesizer.h\"\n#include \"Mixer.h\"\n\nclass SoundOutput {\n  public:\n    NRF52PWM dac;\n\n    SoundOutput(DataSource &data) : dac(NRF_PWM0, data) {\n        dac.connectPin(*LOOKUP_PIN(JACK_SND), 0);\n    }\n\n    void setOutput(int output) { }\n};\n","headphone.svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"142\" height=\"180\" viewBox=\"0 0 142 180\"><rect ry=\".3\" rx=\"1\" y=\"58.615\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><rect ry=\".3\" rx=\"1\" y=\"32.043\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><path d=\"M.346 7.296c-.394.39-.31 4.797-.18 4.898l13.404 10.18c.117.12.337 4.76.73 4.368l5.506-5.56.01.01 6.51-6.444c.39-.392-4.25-.614-4.366-.73L11.777.612c-.1-.132-4.51-.215-4.898.18L4.087 3.636l-.01-.01-3.73 3.67z\" fill=\"#b3b3b3\"/><rect ry=\"6.85\" rx=\"4.571\" y=\"84.758\" x=\"-20.128\" height=\"75.571\" width=\"39.643\" transform=\"rotate(-45)\"/><rect ry=\".374\" rx=\"1.038\" y=\"29.442\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"55.939\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"82.392\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\"2.317\" rx=\"2.183\" y=\"158.876\" x=\"-9.774\" height=\"25.568\" width=\"18.935\" transform=\"rotate(-45)\"/><path d=\"M128.588 128.82s14.97 11.165 7.547 26.35c-8.426 17.24-25.57 20.653-25.57 20.653\" fill=\"none\" stroke=\"#000\" stroke-width=\"6.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>","instrument.ts":"namespace music.sequencer {\n    const BUFFER_SIZE = 12;\n\n    let currentSequencer: sequencer.Sequencer;\n\n    /**\n     * Byte encoding format for songs\n     * FIXME: should this all be word aligned?\n     *\n     * song(7 + length of all tracks bytes)\n     *     0 version\n     *     1 beats per minute\n     *     3 beats per measure\n     *     4 ticks per beat\n     *     5 measures\n     *     6 number of tracks\n     *     ...tracks\n     *\n     * track(6 + instrument length + note length bytes)\n     *     0 id\n     *     1 flags\n     *     2 instruments byte length\n     *     4...instrument\n     *     notes byte length\n     *     ...note events\n     *\n     * instrument(28 bytes)\n     *     0 waveform\n     *     1 amp attack\n     *     3 amp decay\n     *     5 amp sustain\n     *     7 amp release\n     *     9 amp amp\n     *     11 pitch attack\n     *     13 pitch decay\n     *     15 pitch sustain\n     *     17 pitch release\n     *     19 pitch amp\n     *     21 amp lfo freq\n     *     22 amp lfo amp\n     *     24 pitch lfo freq\n     *     25 pitch lfo amp\n     *     27 octave\n     *\n     * drum(5 + 7 * steps bytes)\n     *     0 steps\n     *     1 start freq\n     *     3 start amp\n     *     5...steps\n     *\n     * drum step(7 bytes)\n     *     0 waveform\n     *     1 freq\n     *     3 volume\n     *     5 duration\n     *\n     * note event(5 + 1 * polyphony bytes)\n     *     0 start tick\n     *     2 end tick\n     *     4 polyphony\n     *     5...notes(1 byte each)\n     *\n     * note (1 byte)\n     *     lower six bits = note - (instrumentOctave - 2) * 12\n     *     upper two bits are the enharmonic spelling:\n     *          0 = normal\n     *          1 = flat\n     *          2 = sharp\n     */\n\n    export class Song extends Playable {\n        tracks: Track[];\n\n        constructor(public buf: Buffer) {\n            super();\n            this.tracks = [];\n\n            let currentOffset = 7;\n            for (let i = 0; i < this.numberOfTracks; i++) {\n                let track: Track = new MelodicTrack(this.buf, currentOffset);\n\n                if (!track.isMelodicTrack) {\n                    track = new DrumTrack(this.buf, currentOffset)\n                }\n\n                this.tracks.push(track);\n                currentOffset += track.byteLength;\n            }\n        }\n\n        get version(): number {\n            return this.buf[0];\n        }\n\n        set version(value: number) {\n            this.buf[0] = value;\n        }\n\n        get beatsPerMinute(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, 1);\n        }\n\n        set beatsPerMinute(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, 1, value);\n        }\n\n        get beatsPerMeasure(): number {\n            return this.buf[3];\n        }\n\n        set beatsPerMeasure(value: number) {\n            this.buf[3] = value;\n        }\n\n        get ticksPerBeat(): number {\n            return this.buf[4];\n        }\n\n        set ticksPerBeat(value: number) {\n            this.buf[4] = value;\n        }\n\n        get measures(): number {\n            return this.buf[5];\n        }\n\n        set measures(value: number) {\n            this.buf[5] = value;\n        }\n\n        get numberOfTracks(): number {\n            return this.buf[6];\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (control.deviceDalVersion() === \"sim\") {\n                const seq = new _SimulatorSequencer();\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    seq.play(this.buf, false);\n\n                    pauseUntil(() => seq.state() === \"stop\");\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    seq.play(this.buf, false);\n                }\n                else {\n                    seq.play(this.buf, true);\n                }\n            }\n            else {\n                if (currentSequencer) currentSequencer.stop();\n                currentSequencer = new sequencer.Sequencer(this);\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    let seq = currentSequencer;\n                    currentSequencer.start(false);\n                    pauseUntil(() => !seq.isRunning);\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    currentSequencer.start(false);\n                }\n                else {\n                    currentSequencer.start(true);\n                }\n            }\n        }\n    }\n\n    export class Envelope {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(10);\n            this.offset = this.offset || 0;\n        }\n\n        // The time in ms for the envelope to reach its maximum value\n        get attack(): number {\n            return this.getValue(0);\n        }\n\n        set attack(value: number) {\n            this.setValue(0, value);\n        }\n\n        // The time in ms for the envelope to reach its sustain value after reaching its maximum value\n        get decay(): number {\n            return this.getValue(2);\n        }\n\n        set decay(value: number) {\n            this.setValue(2, value);\n        }\n\n        // The value (0-1024) to hold at during the sustain stage\n        get sustain(): number {\n            return this.getValue(4);\n        }\n\n        set sustain(value: number) {\n            this.setValue(4, value);\n        }\n\n        // The time in ms for the envelope to reach 0 after the gate length ends\n        get release(): number {\n            return this.getValue(6);\n        }\n\n        set release(value: number) {\n            this.setValue(6, value);\n        }\n\n        // The maximum value that this envelope will reach\n        get amplitude(): number {\n            return this.getValue(8);\n        }\n\n        set amplitude(value: number) {\n            this.setValue(8, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class LFO {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(3);\n            this.offset = this.offset || 0;\n        }\n\n        get frequency(): number {\n            return this.buf[this.offset];\n        }\n\n        set frequency(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get amplitude(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + 1);\n        }\n\n        set amplitude(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + 1, value);\n        }\n    }\n\n    export class NoteEvent {\n        constructor(public buf: Buffer, public offset: number) {\n\n        }\n\n        get startTick(): number {\n            return this.getValue(0);\n        }\n\n        set startTick(value: number) {\n            this.setValue(0, value);\n        }\n\n        get endTick(): number {\n            return this.getValue(2);\n        }\n\n        set endTick(value: number) {\n            this.setValue(2, value);\n        }\n\n        get polyphony(): number {\n            return this.buf[this.offset + 4];\n        }\n\n        set polyphony(value: number) {\n            this.buf[this.offset + 4] = value;\n        }\n\n        get byteLength() {\n            return this.polyphony + 5;\n        }\n\n        getNote(offset: number, octave?: number) {\n            const value = this.buf[this.offset + offset + 5] & 0x3f;\n            if (octave !== undefined) {\n                return value + (octave - 2) * 12\n            }\n            return value\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class Track {\n        currentNoteEvent: NoteEvent;\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.currentNoteEvent = new NoteEvent(this.buf, this.noteEventStart + 2);\n        }\n\n        get isMelodicTrack(): boolean {\n            return this.flags === 0;\n        }\n\n        get id(): number {\n            return this.buf[this.offset];\n        }\n\n        set id(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get flags(): number {\n            return this.buf[this.offset + 1];\n        }\n\n        set flags(value: number) {\n            this.buf[this.offset + 1] = value;\n        }\n\n        get instrumentByteLength(): number {\n            return this.getValue(this.offset + 2);\n        }\n\n        set instrumentByteLength(value: number) {\n            this.setValue(this.offset + 2, value);\n        }\n\n        get noteEventStart(): number {\n            return this.offset + this.instrumentByteLength + 4;\n        }\n\n        get noteEventByteLength(): number {\n            return this.getValue(this.noteEventStart);\n        }\n\n        set noteEventByteLength(value: number) {\n            this.setValue(this.noteEventStart, value);\n        }\n\n        get byteLength() {\n            return this.noteEventByteLength + this.instrumentByteLength + 6;\n        }\n\n        advanceNoteEvent() {\n            this.currentNoteEvent.offset += this.currentNoteEvent.byteLength;\n\n            if (this.currentNoteEvent.offset >= this.offset + this.byteLength) {\n                this.currentNoteEvent.offset = this.noteEventStart + 2;\n            }\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, offset, value);\n        }\n    }\n\n    export class MelodicTrack extends Track {\n        instrument: Instrument;\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.instrument = new Instrument(this.buf, this.offset + 4);\n        }\n    }\n\n    export class DrumTrack extends Track {\n        drums: DrumInstrument[];\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.drums = [];\n\n            let currentOffset = 0;\n            while (currentOffset < this.instrumentByteLength) {\n                this.drums.push(new DrumInstrument(this.buf, this.offset + 4 + currentOffset));\n                currentOffset += this.drums[this.drums.length - 1].byteLength;\n            }\n        }\n    }\n\n    export class Instrument {\n        ampEnvelope: Envelope;\n        pitchEnvelope: Envelope;\n        ampLFO: LFO;\n        pitchLFO: LFO;\n\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(27);\n            this.offset = this.offset || 0;\n            this.ampEnvelope = new Envelope(this.buf, this.offset + 1);\n            this.pitchEnvelope = new Envelope(this.buf, this.offset + 11);\n            this.ampLFO = new LFO(this.buf, this.offset + 21);\n            this.pitchLFO = new LFO(this.buf, this.offset + 24)\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get octave(): number {\n            return this.buf[this.offset + 27]\n        }\n\n        set octave(value: number) {\n            this.buf[this.offset + 27] = value;\n        }\n    }\n\n    export class DrumInstrument {\n        steps: DrumStep[];\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.steps = [];\n\n            for (let i = 0; i < this.numSteps; i++) {\n                this.steps.push(new DrumStep(this.buf, this.offset + 5 + i * 7))\n            }\n        }\n\n        get byteLength(): number {\n            return 5 + this.numSteps * 7;\n        }\n\n        get numSteps(): number {\n            return this.buf[this.offset];\n        }\n\n        set numSteps(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get startFrequency(): number {\n            return this.getValue(1);\n        }\n\n        set startFrequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get startVolume(): number {\n            return this.getValue(3);\n        }\n\n        set startVolume(value: number) {\n            this.setValue(3, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class DrumStep {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(7);\n            this.offset = this.offset || 0;\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get frequency(): number {\n            return this.getValue(1);\n        }\n\n        set frequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get volume(): number {\n            return this.getValue(3);\n        }\n\n        set volume(value: number) {\n            this.setValue(3, value);\n        }\n\n        get duration(): number {\n            return this.getValue(5);\n        }\n\n        set duration(value: number) {\n            this.setValue(5, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    /**\n     * Renders a single note played on an instrument into a buffer of sound instructions.\n     *\n     * @param instrument The instrument being played\n     * @param noteFrequency The frequency of the note being played. In other words, \"the key being pressed on the piano\"\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     * @param volume The peak volume of the note to play (0-1024). Also called the \"velocity\"\n     */\n    export function renderInstrument(instrument: Instrument, noteFrequency: number, gateLength: number, volume: number) {\n        // We cut off the sound at the end of the amplitude envelope's release time. This is to prevent\n        // the amp envelope from making the sound keep playing forever\n        const totalDuration = gateLength + instrument.ampEnvelope.release;\n\n        // Our goal is to calculate the frequency and amplitude at all of the inflection points in this note's lifetime\n\n        // For the ADSR envelopes, the inflection points are:\n        //     1. The end of the envelope atack (which is when the decay begins)\n        //     2. The end of the envelope decay (which is when the sustain begins)\n        //     3. The end of the gateLength (which is when the release begins)\n        //     4. The end of the envelope release\n        // If the gateLength ends before any of these stages (e.g. it's shorter than the envelope's attack), then\n        // we ignore the other stages and go straight to the release stage.\n\n        // For the triangle LFOs, the inflections points occur every time the slope goes from positive to negative. In\n        // other words, it's half the period of the triangle wave.\n\n        const ampLFOInterval = instrument.ampLFO.amplitude ? Math.max(500 / instrument.ampLFO.frequency, 50) : 50;\n        const pitchLFOInterval = instrument.pitchLFO.amplitude ? Math.max(500 / instrument.pitchLFO.frequency, 50) : 50;\n\n        // We're going to add the timepoints to this array in order so that it doesn't need to be sorted\n        let timePoints = [0];\n\n        // For each LFO and envelope, keep track of the next inflection point. If any of the LFOs or envelopes have\n        // an amplitude of 0, we can ignore them entirely.\n        let nextAETime = instrument.ampEnvelope.attack;\n        let nextPETime = instrument.pitchEnvelope.amplitude ? instrument.pitchEnvelope.attack : totalDuration;\n        let nextPLTime = instrument.pitchLFO.amplitude ? pitchLFOInterval : totalDuration;\n        let nextALTime = instrument.ampLFO.amplitude ? ampLFOInterval : totalDuration;\n\n        let time = 0;\n        while (time < totalDuration) {\n            // Amp envelope\n            if (nextAETime <= nextPETime && nextAETime <= nextPLTime && nextAETime <= nextALTime) {\n                time = nextAETime;\n                timePoints.push(nextAETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            // Pitch envelope\n            else if (nextPETime <= nextPLTime && nextPETime <= nextALTime && nextPETime < totalDuration) {\n                time = nextPETime;\n                timePoints.push(nextPETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                // If we reach the end of the release before the amp envelope is finished, bail out\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            // Pitch LFO\n            else if (nextPLTime <= nextALTime && nextPLTime < totalDuration) {\n                time = nextPLTime;\n                timePoints.push(nextPLTime);\n                nextPLTime += pitchLFOInterval;\n            }\n            // Amp LFO\n            else if (nextALTime < totalDuration) {\n                time = nextALTime;\n                timePoints.push(nextALTime);\n                nextALTime += ampLFOInterval;\n            }\n\n\n            if (time >= totalDuration) {\n                break;\n            }\n\n            // Now that we've advanced the time, we need to check all of the envelopes/LFOs again\n            // to see if any of them also need to be pushed forward (e.g. they had the same inflection point\n            // as the one we just added to the array)\n            if (nextAETime <= time) {\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            if (nextPETime <= time) {\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            while (nextALTime <= time) {\n                nextALTime += ampLFOInterval;\n            }\n            while (nextPLTime <= time) {\n                nextPLTime += pitchLFOInterval;\n            }\n        }\n\n        // Once we've calculated the inflection points, calculate the frequency and amplitude at\n        // each step and interpolate between them with sound instructions\n        let prevAmp = instrumentVolumeAtTime(instrument, gateLength, 0, volume) | 0;\n        let prevPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, 0) | 0;\n        let prevTime = 0;\n\n        let nextAmp: number;\n        let nextPitch: number;\n        const out = control.createBuffer(BUFFER_SIZE * timePoints.length);\n        for (let i = 1; i < timePoints.length; i++) {\n            if (timePoints[i] - prevTime < 5) {\n                prevTime = timePoints[i];\n                continue;\n            }\n\n            nextAmp = instrumentVolumeAtTime(instrument, gateLength, timePoints[i], volume) | 0;\n            nextPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, timePoints[i]) | 0\n            addNote(\n                out,\n                (i - 1) * 12,\n                (timePoints[i] - prevTime) | 0,\n                prevAmp,\n                nextAmp,\n                instrument.waveform,\n                prevPitch,\n                255,\n                nextPitch\n            )\n\n            prevAmp = nextAmp;\n            prevPitch = nextPitch;\n            prevTime = timePoints[i];\n        }\n\n        // Finally, add one extra step to move the amplitude to 0 without\n        // clipping just in case the amp LFO caused it to be nonzero\n        addNote(\n            out,\n            (timePoints.length - 1) * 12,\n            10,\n            prevAmp,\n            0,\n            instrument.waveform,\n            prevPitch,\n            255,\n            prevPitch\n        )\n        return out;\n    }\n\n    export function renderDrumInstrument(sound: DrumInstrument, volume: number) {\n        // Drum instruments are rendered just like melodic instruments, but the inflection\n        // points are already calculated for us\n        let prevAmp = sound.startVolume;\n        let prevFreq = sound.startFrequency;\n\n        const scaleVolume = (value: number) => (value / 1024) * volume;\n\n        let out = control.createBuffer((sound.steps.length + 1) * BUFFER_SIZE);\n\n        for (let i = 0; i < sound.steps.length; i++) {\n            addNote(\n                out,\n                i * BUFFER_SIZE,\n                sound.steps[i].duration,\n                scaleVolume(prevAmp),\n                scaleVolume(sound.steps[i].volume),\n                sound.steps[i].waveform,\n                prevFreq,\n                255,\n                sound.steps[i].frequency\n            );\n            prevAmp = sound.steps[i].volume;\n            prevFreq = sound.steps[i].frequency\n        }\n\n        addNote(\n            out,\n            sound.steps.length * BUFFER_SIZE,\n            10,\n            scaleVolume(prevAmp),\n            0,\n            sound.steps[sound.steps.length - 1].waveform,\n            prevFreq,\n            255,\n            prevFreq\n        );\n\n        return out;\n    }\n\n    function instrumentPitchAtTime(instrument: Instrument, noteFrequency: number, gateLength: number, time: number) {\n        let mod = 0;\n        if (instrument.pitchEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.pitchEnvelope, time, gateLength)\n        }\n        if (instrument.pitchLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.pitchLFO, time)\n        }\n        return Math.max(noteFrequency + mod, 0);\n    }\n\n    function instrumentVolumeAtTime(instrument: Instrument, gateLength: number, time: number, maxVolume: number) {\n        let mod = 0;\n        if (instrument.ampEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.ampEnvelope, time, gateLength)\n        }\n        if (instrument.ampLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.ampLFO, time)\n        }\n        return ((Math.max(Math.min(mod, instrument.ampEnvelope.amplitude), 0) / 1024) * maxVolume) | 0;\n    }\n\n    /**\n     * Calculates the value of an ADSR envelope at the given time for a given gate length.\n     *\n     * @param envelope The ADSR envelope\n     * @param time The point and time to calculate the value at\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     */\n    function envelopeValueAtTime(envelope: Envelope, time: number, gateLength: number) {\n        // ADSR envelopes consist of 4 stages. They are (in order):\n        //     1. The attack stage, where the value starts at 0 and rises to the maximum value\n        //     2. The decay stage, where the value falls from the maximum value to the sustain value\n        //     3. The sustain stage, where the value holds steady at the sustain value until the gate length ends\n        //     4. The release stage, where the value falls to 0 after the gate length ends\n        // If the gate length ends before the sustain stage, we immediately skip to the release stage. All stages\n        // use a linear function for the value\n        const adjustedSustain = (envelope.sustain / 1024) * envelope.amplitude;\n\n        // First check to see if we are already in the release stage\n        if (time > gateLength) {\n            if (time - gateLength > envelope.release) return 0;\n\n            // Did the gate length end before the attack stage finished?\n            else if (time < envelope.attack) {\n                const height = (envelope.amplitude / envelope.attack) * gateLength;\n                return height - ((height / envelope.release) * (time - gateLength))\n            }\n            // Did the gate length end before the decay stage finished?\n            else if (time < envelope.attack + envelope.decay) {\n                const height2 = envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (gateLength - envelope.attack);\n                return height2 - ((height2 / envelope.release) * (time - gateLength))\n            }\n            else {\n                return adjustedSustain - (adjustedSustain / envelope.release) * (time - gateLength)\n            }\n        }\n        else if (time < envelope.attack) {\n            return (envelope.amplitude / envelope.attack) * time\n        }\n        else if (time < envelope.attack + envelope.decay) {\n            return envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (time - envelope.attack)\n        }\n        else {\n            return adjustedSustain;\n        }\n    }\n\n    /**\n     * Calculates the value of the LFO at the given time.\n     *\n     * TODO: might be nice to give options to shift the phase of the LFO or let it run free\n     *\n     * @param lfo The LFO to calculate the value of\n     * @param time The time to calculate the value at\n     */\n    function lfoValueAtTime(lfo: LFO, time: number) {\n        // Use cosine to smooth out the value somewhat\n        return Math.cos(((time / 1000) * lfo.frequency) * 2 * Math.PI) * lfo.amplitude\n    }\n\n    export function _stopAllSongs() {\n        if (currentSequencer) {\n            currentSequencer.stop();\n            currentSequencer = undefined;\n        }\n        _stopAllSimSequencers();\n    }\n}","legacy.ts":"//% deprecated=true hidden=true\nenum Sounds {\n    //% block=\"power up\"\n    PowerUp,\n    //% block=\"power down\"\n    PowerDown,\n    //% block=\"jump up\"\n    JumpUp,\n    //% block=\"jump down\"\n    JumpDown,\n    //% block=\"ba ding\"\n    BaDing,\n    //% block=\"wawawawaa\"\n    Wawawawaa,\n    //% block=\"magic wand\"\n    MagicWand,\n    //% block=\"siren\"\n    Siren\n}\n\nnamespace music {\n    /**\n     * Get the melody string for a built-in melody.\n     * @param name the note name, eg: Note.C\n     */\n    //% help=music/sounds\n    //% blockId=music_sounds block=\"%name\"\n    //% blockHidden=true\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=285\n    //% name.fieldOptions.columns=3\n    export function sounds(name: Sounds): string {\n        switch (name) {\n            case Sounds.BaDing:\n                return 'b5:1 e6:3';\n            case Sounds.Wawawawaa:\n                return 'e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8';\n            case Sounds.JumpUp:\n                return 'c5:1 d e f g';\n            case Sounds.JumpDown:\n                return 'g5:1 f e d c';\n            case Sounds.PowerUp:\n                return 'g4:1 c5 e g:2 e:1 g:3';\n            case Sounds.PowerDown:\n                return 'g5:1 d# c g4:2 b:1 c5:3';\n            case Sounds.MagicWand:\n                return 'F#6:1-300 G# A# B C7# D# F F# G# A# B:6'; //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n            case Sounds.Siren:\n                return 'a4 d5 a4 d5 a4 d5';\n            default:\n                return '';\n        }\n    }\n\n    let currMelody: Melody\n\n    /**\n     * Start playing a sound and don't wait for it to finish.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound\n    //% blockId=music_play_sound block=\"play sound %sound=music_sounds\"\n    //% parts=\"headphone\"\n    //% weight=95 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSound(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.play();\n        pause(1);\n    }\n\n\n    /**\n     * Play a sound and wait until the sound is done.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound-until-done\n    //% blockId=music_play_sound_until_done block=\"play sound %sound=music_sounds|until done\"\n    //% parts=\"headphone\"\n    //% weight=94 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSoundUntilDone(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.playUntilDone();\n    }\n}","melody.cpp":"#include \"pxt.h\"\n#include \"SoundOutput.h\"\n#include \"melody.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\nnamespace music {\n\nSINGLETON(WSynthesizer);\n\n// Tone generator arguments:\n//\n// sound: a pointer to the currently-playing sound, usable for looking up the\n// waveform or generator-specific state.\n//\n// position: offset within the currently-playing wave, range 0..1023.\n//\n// cycle: a 6-bit cyclical sequence number of the wave, incremented each time\n// the position loops from 1023 back to 0.\ntypedef int (*gentone_t)(PlayingSound *sound, uint32_t position, uint8_t cycle);\n\nstatic int noiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    // see https://en.wikipedia.org/wiki/Xorshift\n    static uint32_t x = 0xf01ba80;\n    x ^= x << 13;\n    x ^= x >> 17;\n    x ^= x << 5;\n    return (x & 0xffff) - 0x7fff;\n}\n\nstatic int sineTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    int32_t p = position;\n    if (p >= 512) {\n        p -= 512;\n    }\n    if (p > 256) {\n        p = 512 - p;\n    }\n\n    // Approximate sin(x * pi / 2) with the odd polynomial y = cx^5 + bx^3 + ax\n    // using the constraint y(1) = 1 => a = 1 - b - c\n    //   => y = c x^5 + b x^3 + (1 - b - c) * x\n    //\n    // Do a least-squares fit of this to sin(x * pi / 2) in the range 0..1\n    // inclusive, using 21 evenly spaced points. Resulting approximation:\n    //\n    // sin(x*pi/2) ~= 0.0721435357258*x**5 - 0.642443736562*x**3 + 1.57030020084*x\n\n    // Scale the constants by 32767 to match the desired output range.\n    constexpr int32_t c = 0.0721435357258 * 32767;\n    constexpr int32_t b = -0.642443736562 * 32767;\n    constexpr int32_t a = 1.57030020084 * 32767;\n\n    // Calculate using y = ((c * x^2 + b) * x^2 + a) * x\n    //\n    // The position p is x * 256, so after each multiply with p we need to\n    // shift right by 8 bits to keep the decimal point in the same place.  (The\n    // approximation has a negative error near x=1 which helps avoid overflow.)\n    int32_t p2 = p * p;\n    int32_t u = (c * p2 >> 16) + b;\n    int32_t v = (u * p2 >> 16) + a;\n    int32_t w = v * p >> 8;\n\n    // The result is within 7/32767 or 0.02%, signal-to-error ratio about 38 dB.\n    return position >= 512 ? -w : w;\n}\n\nstatic int sawtoothTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return (position << 6) - 0x7fff;\n}\n\nstatic int triangleTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return position < 512 ? (position << 7) - 0x7fff : ((1023 - position) << 7) - 0x7fff;\n}\n\nstatic int squareWaveTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)cycle;\n    uint8_t wave = sound->currInstr->soundWave;\n    return (int)position < (102 * (wave - SW_SQUARE_10 + 1)) ? -0x7fff : 0x7fff;\n}\n\nstatic int tunedNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a random bit sequence. Since the generator\n    // is called multiple times per wave, use PlayingSound state data to ensure we\n    // only generate a random bit once per wave, and then reuse it for future\n    // calls for that wave.\n    //\n    // Use the low 6 bits of generatorState to store the last-used cycle, and\n    // random_bit to store the last on/off state. (random_bit is arbitrary as\n    // long as it isn't one of the low 6 bits.)\n    constexpr uint32_t random_bit = 0x8000;\n    static uint32_t x = 0xf01ba80; // seed for the static RNG state\n    uint8_t prev_cycle = sound->generatorState & 0x3f;\n    uint32_t is_on;\n    if (cycle == prev_cycle) {\n        is_on = sound->generatorState & random_bit;\n    } else {\n        // see https://en.wikipedia.org/wiki/Xorshift\n        x ^= x << 13;\n        x ^= x >> 17;\n        x ^= x << 5;\n        is_on = (x & random_bit);\n        sound->generatorState = (cycle & 0x3f) | is_on;\n    }\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\n// Bit patterns for use by the cyclic noise tone.\n//\n// The bit pattern is arbitrary, but should have equal numbers of 0 and 1 bits,\n// and should avoid long identical-bit runs for the lower parts. The values below\n// were chosen based on a random permutation of the hex nibbles 0..f and then\n// hand-tweaked by swapping some nibbles. Generated by:\n//\n//   shuf -i 0-15 | perl -ne 's/(\\d+)/printf(\"%x\",$1)/e'\nstatic const uint32_t cycle_bits[] = {0x2df0eb47, 0xc8165a93};\nstatic const uint8_t cycle_mask[] = {0xf, 0x1f, 0x3f};\n\nstatic int cycleNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    // The bit sequence repeats every 16/32/64 waves.\n    //\n    // The \"cycle\" argument corresponds to the sequential number of the generated\n    // wave. This is currently a 6-bit value. Since the pseudorandom bit sequences\n    // evenly fit into this, there's no need to track generator state.\n    uint8_t wave = sound->currInstr->soundWave;\n    int cycle_index = wave - SW_SQUARE_CYCLE_16;\n    // CLAMP(0, cycle_index, sizeof cycle_bits / sizeof cycle_bits[0])\n    cycle &= cycle_mask[cycle_index];\n    bool is_on = (cycle_bits[cycle >> 5] & (1U << (cycle & 0x1f)));\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\nstatic int silenceTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    return 0;\n}\n\nstatic gentone_t getWaveFn(uint8_t wave) {\n    switch (wave) {\n    case SW_TRIANGLE:\n        return triangleTone;\n    case SW_SAWTOOTH:\n        return sawtoothTone;\n    case SW_TUNEDNOISE:\n        return tunedNoiseTone;\n    case SW_NOISE:\n        return noiseTone;\n    case SW_SINE:\n        return sineTone;\n    default:\n        if (SW_SQUARE_10 <= wave && wave <= SW_SQUARE_50)\n            return squareWaveTone;\n        if (SW_SQUARE_CYCLE_16 <= wave && wave <= SW_SQUARE_CYCLE_64)\n            return cycleNoiseTone;\n        else\n            return silenceTone;\n    }\n}\n\n#define CLAMP(lo, v, hi) ((v) = ((v) < (lo) ? (lo) : (v) > (hi) ? (hi) : (v)))\n\nint WSynthesizer::updateQueues() {\n    const int maxTime = 0xffffff;\n    while (1) {\n        WaitingSound *p;\n        int minLeft = maxTime;\n        for (p = waiting; p; p = p->next) {\n            int timeLeft =\n                p->state == SoundState::Waiting ? p->startSampleNo - currSample : maxTime;\n            if (timeLeft <= 0) {\n                break;\n            }\n            if (timeLeft < minLeft)\n                minLeft = timeLeft;\n        }\n        if (p) {\n            PlayingSound *snd;\n            int minIdx = -1;\n            for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n                snd = &playingSounds[i];\n                if (snd->sound == NULL)\n                    break;\n                if (minIdx == -1 ||\n                    playingSounds[minIdx].startSampleNo < playingSounds[i].startSampleNo)\n                    minIdx = i;\n                snd = NULL;\n            }\n            // if we didn't find a free slot, expel the oldest sound\n            if (!snd)\n                snd = &playingSounds[minIdx];\n            if (snd->sound)\n                snd->sound->state = SoundState::Done;\n            snd->sound = p;\n            p->state = SoundState::Playing;\n            snd->startSampleNo = currSample;\n            snd->currInstr = (SoundInstruction *)p->instructions->data;\n            snd->instrEnd = snd->currInstr + p->instructions->length / sizeof(SoundInstruction);\n            snd->prevVolume = -1;\n        } else {\n            // no more sounds to move\n            return minLeft;\n        }\n    }\n}\n\nint WSynthesizer::fillSamples(int16_t *dst, int numsamples) {\n    if (numsamples <= 0)\n        return 1;\n\n    int timeLeft = updateQueues();\n    int res = waiting != NULL;\n\n    // if there's a pending sound to be started somewhere during numsamples,\n    // split the call into two\n    if (timeLeft < numsamples) {\n        fillSamples(dst, timeLeft);\n        LOG(\"M split %d\", timeLeft);\n        fillSamples(dst + timeLeft, numsamples - timeLeft);\n        return 1;\n    }\n\n    memset(dst, 0, numsamples * 2);\n\n    uint32_t samplesPerMS = (sampleRate << 8) / 1000;\n    float toneStepMult = (1024.0 * (1 << 16)) / sampleRate;\n    const int MAXVAL = (1 << (OUTPUT_BITS - 1)) - 1;\n\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        PlayingSound *snd = &playingSounds[i];\n        if (snd->sound == NULL)\n            continue;\n\n        res = 1;\n\n        SoundInstruction *instr = NULL;\n        gentone_t fn = NULL;\n        snd->currInstr--;\n        uint32_t toneStep = 0;\n        int32_t toneDelta = 0;\n        int32_t volumeStep = 0;\n        uint32_t tonePosition = snd->tonePosition;\n        uint32_t samplesLeft = 0;\n        uint8_t wave = 0;\n        int32_t volume = 0;\n\n        for (int j = 0; j < numsamples; ++j) {\n            if (samplesLeft == 0) {\n                snd->currInstr++;\n                if (snd->currInstr >= snd->instrEnd) {\n                    break;\n                }\n                SoundInstruction copy = *snd->currInstr;\n                instr = &copy;\n                CLAMP(20, instr->frequency, 20000);\n                CLAMP(20, instr->endFrequency, 20000);\n                CLAMP(0, instr->startVolume, 1023);\n                CLAMP(0, instr->endVolume, 1023);\n                CLAMP(1, instr->duration, 60000);\n\n                wave = instr->soundWave;\n                fn = getWaveFn(wave);\n\n                samplesLeft = (uint32_t)(instr->duration * samplesPerMS >> 8);\n                // make sure the division is signed\n                volumeStep =\n                    (int)((instr->endVolume - instr->startVolume) << 16) / (int)samplesLeft;\n\n                if (j == 0 && snd->prevVolume != -1) {\n                    // restore previous state\n                    samplesLeft = snd->samplesLeftInCurr;\n                    volume = snd->prevVolume;\n                    toneStep = snd->prevToneStep;\n                    toneDelta = snd->prevToneDelta;\n                } else {\n                    LOG(\"#sampl %d %p\", samplesLeft, snd->currInstr);\n                    volume = instr->startVolume << 16;\n                    LOG(\"%d-%dHz %d-%d vol\", instr->frequency, instr->endFrequency,\n                        instr->startVolume, instr->endVolume);\n                    toneStep = (uint32_t)(toneStepMult * instr->frequency);\n                    if (instr->frequency != instr->endFrequency) {\n                        uint32_t endToneStep = (uint32_t)(toneStepMult * instr->endFrequency);\n                        toneDelta = (int32_t)(endToneStep - toneStep) / (int32_t)samplesLeft;\n                    } else {\n                        toneDelta = 0;\n                    }\n                }\n            }\n\n            int v = fn(snd, (tonePosition >> 16) & 1023, tonePosition >> 26);\n            v = (v * (volume >> 16)) >> (10 + (16 - OUTPUT_BITS));\n\n            // if (v > MAXVAL)\n            //    target_panic(123);\n\n            dst[j] += v;\n\n            tonePosition += toneStep;\n            toneStep += toneDelta;\n            volume += volumeStep;\n            samplesLeft--;\n        }\n\n        if (snd->currInstr >= snd->instrEnd) {\n            snd->sound->state = SoundState::Done;\n            snd->sound = NULL;\n        } else {\n            snd->tonePosition = tonePosition;\n            if (samplesLeft == 0)\n                samplesLeft++; // avoid infinite loop in next iteration\n            snd->samplesLeftInCurr = samplesLeft;\n            snd->prevVolume = volume;\n            snd->prevToneDelta = toneDelta;\n            snd->prevToneStep = toneStep;\n        }\n    }\n\n    currSample += numsamples;\n\n    for (int j = 0; j < numsamples; ++j) {\n        if (dst[j] > MAXVAL)\n            dst[j] = MAXVAL;\n        else if (dst[j] < -MAXVAL)\n            dst[j] = -MAXVAL;\n    }\n\n    return res;\n}\n\n//%\nvoid enableAmp(int enabled) {\n    // this is also compiled on linux\n#ifdef LOOKUP_PIN\n    auto pin = LOOKUP_PIN(SPEAKER_AMP);\n    if (pin) {\n        if (PIN(SPEAKER_AMP) & CFG_PIN_CONFIG_ACTIVE_LO)\n            enabled = !enabled;\n        pin->setDigitalValue(enabled);\n    }\n#endif\n}\n\n//%\nvoid forceOutput(int outp) {\n    auto snd = getWSynthesizer();\n    snd->out.setOutput(outp);\n}\n\n//%\nvoid queuePlayInstructions(int when, Buffer buf) {\n    auto snd = getWSynthesizer();\n\n    registerGCObj(buf);\n\n    auto p = new WaitingSound;\n    p->state = SoundState::Waiting;\n    p->instructions = buf;\n    p->startSampleNo = snd->currSample + when * snd->sampleRate / 1000;\n\n    LOG(\"Queue %dms now=%d off=%d %p sampl:%dHz\", when, snd->currSample,\n        p->startSampleNo - snd->currSample, buf->data, snd->sampleRate);\n\n    target_disable_irq();\n    // add new sound to queue\n    p->next = snd->waiting;\n    snd->waiting = p;\n    // remove sounds that have already been fully played\n    while (p) {\n        while (p->next && p->next->state == SoundState::Done) {\n            auto todel = p->next;\n            p->next = todel->next;\n            unregisterGCObj(todel->instructions);\n            delete todel;\n        }\n        p = p->next;\n    }\n    target_enable_irq();\n\n    snd->poke();\n}\n\n//%\nvoid stopPlaying() {\n    LOG(\"stop playing!\");\n\n    auto snd = getWSynthesizer();\n\n    target_disable_irq();\n    auto p = snd->waiting;\n    snd->waiting = NULL;\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        snd->playingSounds[i].sound = NULL;\n    }\n    while (p) {\n        auto n = p->next;\n        unregisterGCObj(p->instructions);\n        delete p;\n        p = n;\n    }\n    target_enable_irq();\n}\n\nWSynthesizer::WSynthesizer() : upstream(NULL), out(*this) {\n    currSample = 0;\n    active = false;\n    sampleRate = out.dac.getSampleRate();\n    memset(&playingSounds, 0, sizeof(playingSounds));\n    waiting = NULL;\n    PXT_REGISTER_RESET(stopPlaying);\n}\n\n//% promise\nint _createSequencer() {\n    return 0;\n}\n\n//%\nString _sequencerState(int id) {\n    return NULL;\n}\n\n//%\nint _sequencerCurrentTick(int id) {\n    return 0;\n}\n\n//%\nvoid _sequencerPlaySong(int id, Buffer buf, bool loop) {\n}\n\n//%\nvoid _sequencerStop(int id) {\n}\n\n//%\nvoid _sequencerSetVolume(int id, int volume) {\n}\n\n//%\nvoid _sequencerSetVolumeForAll(int volume) {\n}\n\n//%\nvoid _sequencerSetTrackVolume(int id, int trackIndex, int volume) {\n}\n\n//%\nvoid _sequencerSetDrumTrackVolume(int id, int trackIndex, int drumIndex, int volume) {\n}\n\n//%\nvoid _sequencerDispose(int id) {\n}\n\n} // namespace music\n\nnamespace pxt {\nint redirectSamples(int16_t *dst, int numsamples, int samplerate) {\n    auto snd = music::getWSynthesizer();\n    snd->upstream = NULL; // disconnect from regular playback mechanism\n    snd->sampleRate = samplerate;\n    return snd->fillSamples(dst, numsamples);\n}\n\n} // namespace pxt\n\nnamespace jacdac {\n__attribute__((weak)) void setJackRouterOutput(int output) {}\n} // namespace jacdac\n","melody.h":"#pragma once\n\n#ifndef OUTPUT_BITS\n#define OUTPUT_BITS 10\n#endif\n\n#define SW_TRIANGLE 1\n#define SW_SAWTOOTH 2\n#define SW_SINE 3\n#define SW_TUNEDNOISE 4\n#define SW_NOISE 5\n#define SW_SQUARE_10 11\n#define SW_SQUARE_50 15\n#define SW_SQUARE_CYCLE_16 16\n#define SW_SQUARE_CYCLE_32 17\n#define SW_SQUARE_CYCLE_64 18\n\nstruct SoundInstruction {\n    uint8_t soundWave;\n    uint8_t flags;\n    uint16_t frequency;    // Hz\n    uint16_t duration;     // ms\n    int16_t startVolume;   // 0-1023\n    int16_t endVolume;     // 0-1023\n    uint16_t endFrequency; // Hz\n};\n\n#ifdef DATASTREAM_MAXIMUM_BUFFERS\n#define CODAL 1\n#endif\n\nnamespace music {\n\n#define MAX_SOUNDS 8\n\nSTATIC_ASSERT((1 << (16 - OUTPUT_BITS)) > MAX_SOUNDS);\n\nenum class SoundState : uint8_t {\n    Waiting, //\n    Playing, //\n    Done     //\n};\n\nstruct WaitingSound {\n    uint32_t startSampleNo;\n    SoundState state;\n    WaitingSound *next;\n    Buffer instructions;\n};\n\nstruct PlayingSound {\n    uint32_t startSampleNo;\n    uint32_t samplesLeftInCurr;\n    uint32_t tonePosition;\n    int32_t prevVolume;\n    uint32_t prevToneStep;\n    int32_t prevToneDelta;\n    uint32_t generatorState;\n    WaitingSound *sound;\n    SoundInstruction *currInstr, *instrEnd;\n};\n\nclass WSynthesizer\n#ifdef CODAL\n    : public DataSource\n#endif\n{\n  public:\n#ifdef CODAL\n    DataSink *upstream;\n#else\n    void *upstream;\n#endif\n    uint32_t currSample; // after 25h of playing we might get a glitch\n    int32_t sampleRate;  // eg 44100\n    PlayingSound playingSounds[MAX_SOUNDS];\n    WaitingSound *waiting;\n    bool active;\n\n    SoundOutput out;\n\n    int fillSamples(int16_t *dst, int numsamples);\n    int updateQueues();\n\n    WSynthesizer();\n    virtual ~WSynthesizer() {}\n\n    void pokeUpstream() {\n#ifdef CODAL\n        if (upstream) {\n            upstream->pullRequest();\n        }\n#endif\n    }\n\n    void poke() {\n        if (!active) {\n            active = true;\n            pokeUpstream();\n        }\n    }\n\n#ifdef CODAL\n    virtual ManagedBuffer pull() {\n        if (!upstream)\n            return ManagedBuffer();\n        ManagedBuffer data(512);\n        auto dp = (int16_t *)data.getBytes();\n        auto sz = 512 / 2;\n        int r = fillSamples(dp, sz);\n#if defined(NRF52_SERIES)\n        int mul = out.dac.getSampleRange();\n#endif\n        while (sz--) {\n#if defined(NRF52_SERIES)\n            *dp = ((-*dp + (1 << (OUTPUT_BITS - 1))) * mul) >> OUTPUT_BITS;\n#else\n            *dp += 1 << (OUTPUT_BITS - 1);\n#endif\n            dp++;\n        }\n        if (!r) {\n            active = false;\n            // return empty - nothing left to play\n            return ManagedBuffer();\n        }\n        pokeUpstream();\n        return data;\n    }\n    virtual void connect(DataSink &sink) { upstream = &sink; }\n#endif\n};\n\n} // namespace music\n","melody.ts":"enum MusicOutput {\n    AutoDetect = 0,\n    Buzzer = 1,\n    HeadPhones = 2,\n}\n\nnamespace music {\n    //% whenUsed\n    const freqs = hex`\n        1f00210023002500270029002c002e003100340037003a003e004100450049004e00520057005c00620068006e00\n        75007b0083008b0093009c00a500af00b900c400d000dc00e900f70006011501260137014a015d01720188019f01\n        b801d201ee010b022a024b026e029302ba02e40210033f037003a403dc03170455049704dd0427057505c8052006\n        7d06e0064907b8072d08a9082d09b9094d0aea0a900b400cfa0cc00d910e6f0f5a1053115b1272139a14d4152017\n        8018f519801b231dde1e`\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n\n    //% shim=music::stopPlaying\n    function stopPlaying() { }\n\n    //% shim=music::forceOutput\n    export function forceOutput(buf: MusicOutput) { }\n\n    let globalVolume: number = null\n\n    const BUFFER_SIZE: number = 12;\n\n    //% shim=music::enableAmp\n    function enableAmp(en: number) {\n        return // for sim\n    }\n\n    function initVolume() {\n        if (globalVolume === null) {\n            globalVolume = 0\n            setVolume(control.getConfigValue(DAL.CFG_SPEAKER_VOLUME, 128))\n        }\n    }\n\n    /**\n     * Set the default output volume of the sound synthesizer.\n     * @param volume the volume 0...255\n     */\n    //% blockId=synth_set_volume block=\"set volume %volume\"\n    //% parts=\"speaker\"\n    //% volume.min=0 volume.max=255\n    //% volume.defl=20\n    //% help=music/set-volume\n    //% weight=70\n    //% group=\"Volume\"\n    export function setVolume(volume: number): void {\n        globalVolume = Math.clamp(0, 255, volume | 0)\n        enableAmp(globalVolume > 0 ? 1 : 0)\n    }\n\n    /**\n     * Gets the current volume\n     */\n    //% parts=\"speaker\"\n    //% weight=70\n    export function volume(): number {\n        initVolume()\n        return globalVolume;\n    }\n\n    function playNoteCore(when: number, frequency: number, ms: number) {\n        let buf = control.createBuffer(BUFFER_SIZE)\n        addNote(buf, 0, ms, 255, 255, 3, frequency, volume(), frequency)\n        queuePlayInstructions(when, buf)\n    }\n\n    /**\n     * Play a tone through the speaker for some amount of time.\n     * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n     * @param ms tone duration in milliseconds (ms), eg: BeatFraction.Half\n     */\n    //% help=music/play-tone\n    //% blockId=mixer_play_note block=\"play tone|at %note=device_note|for %duration=device_beat\"\n    //% parts=\"headphone\" async\n    //% blockNamespace=music\n    //% weight=76 blockGap=8\n    //% group=\"Tone\"\n    //% deprecated=1\n    export function playTone(frequency: number, ms: number): void {\n        if (ms == 0)\n            ms = 86400000 // 1 day\n\n        if (ms <= 2000) {\n            playNoteCore(0, frequency, ms)\n            pause(ms)\n        } else {\n            const id = ++playToneID\n            control.runInParallel(() => {\n                let pos = control.millis()\n                while (id == playToneID && ms > 0) {\n                    let now = control.millis()\n                    let d = pos - now\n                    let t = Math.min(ms, 500)\n                    ms -= t\n                    pos += t\n                    playNoteCore(d - 1, frequency, t)\n                    if (ms == 0)\n                        pause(d + t)\n                    else\n                        pause(d + t - 100)\n                }\n            })\n        }\n    }\n\n    let playToneID = 0\n\n    /**\n     * Play a melody from the melody editor.\n     * @param melody - string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces,\n     * which will be played one at a time, ex: \"E D G F B A C5 B \"\n     * @param tempo - number in beats per minute (bpm), dictating how long each note will play for\n     */\n    //% block=\"play melody $melody at tempo $tempo|(bpm)\" blockId=playMelody\n    //% blockNamespace=music\n    //% weight=85 blockGap=8 help=music/play-melody\n    //% group=\"Melody\"\n    //% melody.shadow=\"melody_editor\"\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% deprecated=1\n    export function playMelody(melody: string, tempo: number) {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        const song = new Melody(formattedMelody);\n        song.playUntilDone();\n    }\n\n\n    /**\n     * Create a melody with the melody editor.\n     * @param melody\n     */\n    //% block=\"$melody\" blockId=melody_editor\n    //% blockNamespace=music\n    //% blockHidden = true\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Melody\" duplicateShadowOnDrag\n    //% melody.fieldEditor=\"melody\"\n    //% melody.fieldOptions.decompileLiterals=true\n    //% melody.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% melody.fieldOptions.onParentBlock=\"true\"\n    //% shim=TD_ID\n    export function melodyEditor(melody: string): string {\n        return melody;\n    }\n\n    /**\n     * Stop all sounds from playing.\n     */\n    //% help=music/stop-all-sounds\n    //% blockId=music_stop_all_sounds block=\"stop all sounds\"\n    //% weight=45\n    //% group=\"Sounds\"\n    export function stopAllSounds() {\n        Melody.stopAll();\n        stopPlaying();\n        _stopPlayables();\n        sequencer._stopAllSongs();\n    }\n\n    //% fixedInstances\n    export class Melody {\n        _text: string;\n        private _player: MelodyPlayer;\n\n        private static playingMelodies: Melody[];\n\n        static stopAll() {\n            if (Melody.playingMelodies) {\n                const ms = Melody.playingMelodies.slice(0, Melody.playingMelodies.length);\n                ms.forEach(p => p.stop());\n            }\n        }\n\n        constructor(text: string) {\n            this._text = text\n        }\n\n        get text() {\n            return this._text;\n        }\n\n        /**\n         * Stop playing a sound\n         */\n        //% blockId=mixer_stop block=\"stop sound %sound\"\n        //% help=music/melody/stop\n        //% parts=\"headphone\"\n        //% weight=92 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        stop() {\n            if (this._player) {\n                this._player.stop()\n                this._player = null\n            }\n            this.unregisterMelody();\n        }\n\n        private registerMelody() {\n            // keep track of the active players\n            if (!Melody.playingMelodies) Melody.playingMelodies = [];\n            // stop and pop melodies if too many playing\n            if (Melody.playingMelodies.length > 4) {\n                // stop last player (also pops)\n                Melody.playingMelodies[Melody.playingMelodies.length - 1].stop();\n            }\n            // put back the melody on top of the melody stack\n            Melody.playingMelodies.removeElement(this);\n            Melody.playingMelodies.push(this);\n        }\n        private unregisterMelody() {\n            // remove from list\n            if (Melody.playingMelodies) {\n                Melody.playingMelodies.removeElement(this); // remove self\n            }\n        }\n\n        private playCore(volume: number, loop: boolean) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this.registerMelody();\n            control.runInParallel(() => {\n                while (this._player == p) {\n                    p.play(volume)\n                    if (!loop) {\n                        // Unregister the melody when done playing, but\n                        // only if it hasn't been restarted. (Looping\n                        // melodies never stop on their own, they only\n                        // get unregistered via stop().)\n                        if (this._player == p) {\n                            this.unregisterMelody();\n                        }\n                        break\n                    }\n                }\n            })\n        }\n\n        /**\n         * Start playing a sound in a loop and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/loop\n        //% blockId=mixer_loop_sound block=\"loop sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=93 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        loop(volume = 255) {\n            this.playCore(volume, true)\n        }\n\n        /**\n         * Start playing a sound and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play\n        //% blockId=mixer_play_sound block=\"play sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=95 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        play(volume = 255) {\n            this.playCore(volume, false)\n        }\n\n\n        /**\n         * Play a sound and wait until the sound is done.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play-until-done\n        //% blockId=mixer_play_sound_until_done block=\"play sound %sound|until done\"\n        //% parts=\"headphone\"\n        //% weight=94 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        playUntilDone(volume = 255) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this._player.onPlayFinished = () => {\n                if (p == this._player)\n                    this.unregisterMelody();\n            }\n            this.registerMelody();\n            this._player.play(volume)\n        }\n\n        toString() {\n            return this._text;\n        }\n    }\n\n    export function addNote(sndInstr: Buffer, sndInstrPtr: number, ms: number, beg: number, end: number, soundWave: number, hz: number, volume: number, endHz: number) {\n        if (ms > 0) {\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, soundWave)\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr + 1, 0)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 2, hz)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 4, ms)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 6, (beg * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 8, (end * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 10, endHz);\n            sndInstrPtr += BUFFER_SIZE;\n        }\n        sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, 0) // terminate\n        return sndInstrPtr\n    }\n\n\n    export class MelodyPlayer {\n        melody: Melody;\n\n        onPlayFinished: () => void;\n\n        constructor(m: Melody) {\n            this.melody = m\n        }\n\n        stop() {\n            this.melody = null\n        }\n\n        protected queuePlayInstructions(timeDelta: number, buf: Buffer) {\n            queuePlayInstructions(timeDelta, buf)\n        }\n\n        play(volume: number) {\n            if (!this.melody)\n                return\n            volume = Math.clamp(0, 255, (volume * music.volume()) >> 8)\n\n            let notes = this.melody._text\n            let pos = 0;\n            let duration = 4; //Default duration (Crotchet)\n            let octave = 4; //Middle octave\n            let tempo = 120; // default tempo\n\n            let hz = 0\n            let endHz = -1\n            let ms = 0\n            let timePos = 0\n            let startTime = control.millis()\n            let now = 0\n\n            let envA = 0\n            let envD = 0\n            let envS = 255\n            let envR = 0\n            let soundWave = 1 // triangle\n            let sndInstr = control.createBuffer(5 * BUFFER_SIZE)\n            let sndInstrPtr = 0\n\n            const addForm = (formDuration: number, beg: number, end: number, msOff: number) => {\n                let freqStart = hz;\n                let freqEnd = endHz;\n\n                const envelopeWidth = ms > 0 ? ms : duration * Math.idiv(15000, tempo) + envR;\n                if (endHz != hz && envelopeWidth != 0) {\n                    const slope = (freqEnd - freqStart) / envelopeWidth;\n                    freqStart = hz + slope * msOff;\n                    freqEnd = hz + slope * (msOff + formDuration);\n                }\n                sndInstrPtr = addNote(sndInstr, sndInstrPtr, formDuration, beg, end, soundWave, freqStart, volume, freqEnd);\n            }\n\n            const scanNextWord = () => {\n                if (!this.melody)\n                    return \"\"\n\n                // eat space\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c != ' ' && c != '\\r' && c != '\\n' && c != '\\t')\n                        break;\n                    pos++;\n                }\n\n                // read note\n                let note = \"\";\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c == ' ' || c == '\\r' || c == '\\n' || c == '\\t')\n                        break;\n                    note += c;\n                    pos++;\n                }\n                return note;\n            }\n\n            enum Token {\n                Note,\n                Octave,\n                Beat,\n                Tempo,\n                Hz,\n                EndHz,\n                Ms,\n                WaveForm,\n                EnvelopeA,\n                EnvelopeD,\n                EnvelopeS,\n                EnvelopeR\n            }\n\n            let token: string = \"\";\n            let tokenKind = Token.Note;\n\n            // [ABCDEFG] (\\d+)  (:\\d+)  (-\\d+)\n            // note      octave length  tempo\n            // R (:\\d+) - rest\n            // !\\d+,\\d+ - sound at frequency with given length (Hz,ms); !\\d+ and !\\d+,:\\d+ also possible\n            // @\\d+,\\d+,\\d+,\\d+ - ADSR envelope - ms,ms,volume,ms; volume is 0-255\n            // ~\\d+ - wave form:\n            //   1 - triangle\n            //   2 - sawtooth\n            //   3 - sine\n            //   4 - pseudorandom square wave noise (tunable)\n            //   5 - white noise (ignores frequency)\n            //   11 - square 10%\n            //   12 - square 20%\n            //   ...\n            //   15 - square 50%\n            //   16 - filtered square wave, cycle length 16\n            //   17 - filtered square wave, cycle length 32\n            //   18 - filtered square wave, cycle length 64\n\n            const consumeToken = () => {\n                if (token && tokenKind != Token.Note) {\n                    const d = parseInt(token);\n                    switch (tokenKind) {\n                        case Token.Octave: octave = d; break;\n                        case Token.Beat:\n                            duration = Math.max(1, Math.min(16, d));\n                            ms = -1;\n                            break;\n                        case Token.Tempo: tempo = Math.max(1, d); break;\n                        case Token.Hz: hz = d; tokenKind = Token.Ms; break;\n                        case Token.Ms: ms = d; break;\n                        case Token.WaveForm: soundWave = Math.clamp(1, 18, d); break;\n                        case Token.EnvelopeA: envA = d; tokenKind = Token.EnvelopeD; break;\n                        case Token.EnvelopeD: envD = d; tokenKind = Token.EnvelopeS; break;\n                        case Token.EnvelopeS: envS = Math.clamp(0, 255, d); tokenKind = Token.EnvelopeR; break;\n                        case Token.EnvelopeR: envR = d; break;\n                        case Token.EndHz: endHz = d; break;\n                    }\n                    token = \"\";\n                }\n            }\n\n            while (true) {\n                let currNote = scanNextWord();\n                let prevNote: boolean = false;\n                if (!currNote) {\n                    let timeLeft = timePos - now\n                    if (timeLeft > 0)\n                        pause(timeLeft)\n                    if (this.onPlayFinished)\n                        this.onPlayFinished();\n                    return;\n                }\n\n                hz = -1;\n\n                let note: number = 0;\n                token = \"\";\n                tokenKind = Token.Note;\n\n                for (let i = 0; i < currNote.length; i++) {\n                    let noteChar = currNote.charAt(i);\n                    switch (noteChar) {\n                        case 'c': case 'C': note = 1; prevNote = true; break;\n                        case 'd': case 'D': note = 3; prevNote = true; break;\n                        case 'e': case 'E': note = 5; prevNote = true; break;\n                        case 'f': case 'F': note = 6; prevNote = true; break;\n                        case 'g': case 'G': note = 8; prevNote = true; break;\n                        case 'a': case 'A': note = 10; prevNote = true; break;\n                        case 'B': note = 12; prevNote = true; break;\n                        case 'r': case 'R': hz = 0; prevNote = false; break;\n                        case '#': note++; prevNote = false; break;\n                        case 'b': if (prevNote) note--; else { note = 12; prevNote = true; } break;\n                        case ',':\n                            consumeToken();\n                            prevNote = false;\n                            break;\n                        case '!':\n                            tokenKind = Token.Hz;\n                            prevNote = false;\n                            break;\n                        case '@':\n                            consumeToken();\n                            tokenKind = Token.EnvelopeA;\n                            prevNote = false;\n                            break;\n                        case '~':\n                            consumeToken();\n                            tokenKind = Token.WaveForm;\n                            prevNote = false;\n                            break;\n                        case ':':\n                            consumeToken();\n                            tokenKind = Token.Beat;\n                            prevNote = false;\n                            break;\n                        case '-':\n                            consumeToken();\n                            tokenKind = Token.Tempo;\n                            prevNote = false;\n                            break;\n                        case '^':\n                            consumeToken();\n                            tokenKind = Token.EndHz;\n                            break;\n                        default:\n                            if (tokenKind == Token.Note)\n                                tokenKind = Token.Octave;\n                            token += noteChar;\n                            prevNote = false;\n                            break;\n                    }\n                }\n                consumeToken();\n\n                if (note && hz < 0) {\n                    const keyNumber = note + (12 * (octave - 1));\n                    hz = freqs.getNumber(NumberFormat.UInt16LE, keyNumber * 2) || 0;\n                }\n\n                let currMs = ms\n\n                if (currMs <= 0) {\n                    const beat = Math.idiv(15000, tempo);\n                    currMs = duration * beat\n                }\n\n                if (hz < 0) {\n                    // no frequency specified, so no duration\n                } else if (hz == 0) {\n                    timePos += currMs\n                } else {\n                    if (endHz < 0) {\n                        endHz = hz;\n                    }\n\n                    sndInstrPtr = 0\n                    addForm(envA, 0, 255, 0)\n                    addForm(envD, 255, envS, envA)\n                    addForm(currMs - (envA + envD), envS, envS, envD + envA)\n                    addForm(envR, envS, 0, currMs)\n\n                    this.queuePlayInstructions(timePos - now, sndInstr.slice(0, sndInstrPtr))\n                    endHz = -1;\n                    timePos += currMs // don't add envR - it's supposed overlap next sound\n                }\n\n                let timeLeft = timePos - now\n                if (timeLeft > 200) {\n                    pause(timeLeft - 100)\n                    now = control.millis() - startTime\n                }\n            }\n        }\n    }\n\n    //% blockId=music_song_field_editor\n    //% block=\"song $song\"\n    //% song.fieldEditor=musiceditor\n    //% song.fieldOptions.decompileLiterals=true\n    //% song.fieldOptions.taggedTemplate=\"hex;assets.song\"\n    //% song.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% song.fieldOptions.decompileArgumentAsString=\"true\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% help=music/create-song\n    export function createSong(song: Buffer): Playable {\n        return new sequencer.Song(song);\n    }\n\n    export function playInstructions(when: number, instructions: Buffer) {\n        queuePlayInstructions(when, instructions);\n    }\n\n    export function lookupFrequency(note: number) {\n        return freqs.getNumber(NumberFormat.UInt16LE, note * 2) || 0\n    }\n\n    //% fixedInstance whenUsed block=\"ba ding\"\n    export const baDing = new Melody('b5:1 e6:3')\n\n    //% fixedInstance whenUsed block=\"wawawawaa\"\n    export const wawawawaa = new Melody('~15 e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8')\n\n    //% fixedInstance whenUsed block=\"jump up\"\n    export const jumpUp = new Melody('c5:1 d e f g')\n\n    //% fixedInstance whenUsed block=\"jump down\"\n    export const jumpDown = new Melody('g5:1 f e d c')\n\n    //% fixedInstance whenUsed block=\"power up\"\n    export const powerUp = new Melody('g4:1 c5 e g:2 e:1 g:3')\n\n    //% fixedInstance whenUsed block=\"power down\"\n    export const powerDown = new Melody('g5:1 d# c g4:2 b:1 c5:3')\n\n    //% fixedInstance whenUsed block=\"magic wand\"\n    export const magicWand = new Melody('F#6:1-300 G# A# B C7# D# F F# G# A# B:6')\n    //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n\n    //% fixedInstance whenUsed block=\"siren\"\n    export const siren = new Melody('a4 d5 a4 d5 a4 d5')\n\n    //% fixedInstance whenUsed block=\"pew pew\"\n    export const pewPew = new Melody('!1200,200^50')\n\n    //% fixedInstance whenUsed block=\"knock\"\n    export const knock = new Melody('~4 @0,0,255,150 !300,1 !211,1')\n\n    //% fixedInstance whenUsed block=\"footstep\"\n    export const footstep = new Melody('~4 @0,0,60,50 !200,1')\n\n    //% fixedInstance whenUsed block=\"thump\"\n    export const thump = new Melody('~4 @0,0,255,150 !100,1')\n\n    //% fixedInstance whenUsed block=\"small crash\"\n    export const smallCrash = new Melody('~4 @10,490,0,1 !800,1')\n\n    //% fixedInstance whenUsed block=\"big crash\"\n    export const bigCrash = new Melody('~4 @10,990,0,1 !400,1')\n\n    //% fixedInstance whenUsed block=\"zapped\"\n    export const zapped = new Melody('~16 @10,490,0,0 !1600,500^1')\n\n    //% fixedInstance whenUsed block=\"buzzer\"\n    export const buzzer = new Melody('~16 @10,0,255,250 !2000,300')\n\n    //% fixedInstance whenUsed block=\"sonar\"\n    export const sonar = new Melody('~16 @10,1500,0,0 !200,1 !200,1500^190')\n\n    //% fixedInstance whenUsed block=\"spooky\"\n    export const spooky = new Melody('~16 @700,1300,0,0 !100,1 ~18 !108,2000')\n\n    //% fixedInstance whenUsed block=\"beam up\"\n    export const beamUp = new Melody('~18 @10,1500,0,0 !200,1500^4000')\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    //% block=\"2\"\n    Double = 32,\n    //% block=\"4\",\n    Breve = 64,\n    //% block=\"1/3\",\n    Triplet = 128\n}\n\nnamespace music {\n\n    let beatsPerMinute: number;\n\n    /**\n    * Play a tone.\n    * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n    */\n    //% help=music/ring-tone\n    //% blockId=music_ring block=\"ring tone|at %note=device_note\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music inBasicCategory=true\n    //% weight=75 blockGap=8\n    //% group=\"Tone\"\n    export function ringTone(frequency: number) {\n        playTone(frequency, 0);\n    }\n\n    /**\n    * Rest, or play silence, for some time (in milliseconds).\n    * @param ms rest duration in milliseconds (ms), eg: BeatFraction.Half\n    */\n    //% help=music/rest\n    //% blockId=music_rest block=\"rest|for %duration=device_beat\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music\n    //% weight=74\n    //% group=\"Tone\"\n    export function rest(ms: number) {\n        playTone(0, Math.max(ms, 20));\n    }\n\n    function init() {\n        if (!beatsPerMinute) beatsPerMinute = 120;\n    }\n\n    /**\n     * Return the duration of a beat in milliseconds (the beat fraction).\n     * @param fraction the fraction of the current whole note, eg: BeatFraction.Half\n     */\n    //% help=music/beat\n    //% blockId=device_beat block=\"%fraction|beat\"\n    //% weight=9 blockGap=8\n    //% group=\"Tempo\"\n    export function beat(fraction?: BeatFraction): number {\n        init();\n        if (fraction == null) fraction = BeatFraction.Whole;\n        let beat = 60000 / beatsPerMinute;\n        switch (fraction) {\n            case BeatFraction.Half: beat /= 2; break;\n            case BeatFraction.Quarter: beat /= 4; break;\n            case BeatFraction.Eighth: beat /= 8; break;\n            case BeatFraction.Sixteenth: beat /= 16; break;\n            case BeatFraction.Double: beat *= 2; break;\n            case BeatFraction.Breve: beat *= 4; break;\n            case BeatFraction.Triplet: beat /= 3; break;\n        }\n        return beat >> 0;\n    }\n\n    /**\n     * Return the tempo in beats per minute (bpm).\n     * 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\n    //% blockId=device_tempo block=\"tempo (bpm)\"\n    //% weight=64\n    //% group=\"Tempo\"\n    export function tempo(): number {\n        init();\n        return beatsPerMinute;\n    }\n\n    /**\n     * Change the tempo up or down by some amount of beats per minute (bpm).\n     * @param bpm The change in beats per minute to the tempo, eg: 20\n     */\n    //% help=music/change-tempo-by weight=37\n    //% blockId=device_change_tempo block=\"change tempo by %value|(bpm)\"\n    //% weight=66 blockGap=8\n    //% group=\"Tempo\"\n    export function changeTempoBy(bpm: number): void {\n        init();\n        setTempo(beatsPerMinute + bpm);\n    }\n\n    /**\n     * Set the tempo a number of beats per minute (bpm).\n     * @param bpm The new tempo in beats per minute, eg: 120\n     */\n    //% help=music/set-tempo\n    //% blockId=device_set_tempo block=\"set tempo to %value|(bpm)\"\n    //% bpm.min=4 bpm.max=400\n    //% weight=65 blockGap=8\n    //% group=\"Tempo\"\n    export function setTempo(bpm: number): void {\n        init();\n        if (bpm > 0) {\n            beatsPerMinute = Math.max(1, bpm >> 0);\n        }\n    }\n}\n","ns.ts":"\n/**\n * Generation of music tones.\n */\n//% color=#E30FC0 weight=90 icon=\"\\uf025\"\n//% blockGap=8\n//% groups='[\"Songs\", \"Sounds\", \"Tone\",  \"Volume\", \"Tempo\"]'\nnamespace music {\n}","piano.ts":"namespace music {\n    /**\n     * Get the frequency of a note.\n     * @param name the note name, eg: Note.C\n     */\n    //% weight=1 help=music/note-frequency\n    //% blockId=device_note block=\"%note\"\n    //% shim=TD_ID\n    //% color=\"#FFFFFF\" colorSecondary=\"#FFFFFF\" colorTertiary=\"#D83B01\"\n    //% note.fieldEditor=\"note\" note.defl=\"262\"\n    //% note.fieldOptions.decompileLiterals=true\n    //% useEnumVal=1\n    //% weight=10 blockGap=8\n    //% group=\"Tone\"\n    export function noteFrequency(name: Note): number {\n        return name;\n    }\n}","playable.ts":"namespace music {\n    export enum PlaybackMode {\n        //% block=\"until done\"\n        UntilDone,\n        //% block=\"in background\"\n        InBackground,\n        //% block=\"looping in background\"\n        LoopingInBackground\n    }\n\n    let stateStack: PlayableState[];\n\n    class PlayableState {\n        looping: Playable[];\n        constructor() {\n            this.looping = [];\n        }\n\n        stopLooping() {\n            for (const p of this.looping) {\n                p.stopped = true;\n            }\n            this.looping = [];\n        }\n    }\n\n    function state() {\n        _init();\n        return stateStack[stateStack.length - 1];\n    }\n\n    function _init() {\n        if (stateStack) return;\n        stateStack = [new PlayableState()];\n\n        game.addScenePushHandler(() => {\n            stateStack.push(new PlayableState());\n        });\n\n        game.addScenePopHandler(() => {\n            stateStack.pop();\n            if (stateStack.length === 0) stateStack.push(new PlayableState());\n        });\n    }\n\n    export class Playable {\n        stopped: boolean;\n        constructor() {\n\n        }\n\n        play(playbackMode: PlaybackMode) {\n            // subclass\n        }\n\n        loop() {\n            state().looping.push(this);\n            this.stopped = false;\n\n            control.runInParallel(() => {\n                while (!this.stopped) {\n                    this.play(PlaybackMode.UntilDone);\n                }\n            });\n        }\n    }\n\n    export class MelodyPlayable extends Playable {\n        constructor(public melody: Melody) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                this.melody.play(music.volume());\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                this.melody.playUntilDone(music.volume());\n            }\n            else {\n                this.melody.loop(music.volume());\n            }\n        }\n    }\n\n    export class TonePlayable extends Playable {\n        constructor(public pitch: number, public duration: number) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                control.runInParallel(() => music.playTone(this.pitch, this.duration));\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                music.playTone(this.pitch, this.duration);\n                if (this.duration > 2000) {\n                    pause(this.duration);\n                }\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n    /**\n     * Play a song, melody, or other sound. The music plays until finished or can play as a\n     * background task.\n     * @param toPlay the song or melody to play\n     * @param playbackMode play the song or melody until it's finished or as background task\n     */\n    //% blockId=\"music_playable_play\"\n    //% block=\"play $toPlay $playbackMode\"\n    //% toPlay.shadow=music_melody_playable\n    //% group=\"Sounds\"\n    //% help=\"music/play\"\n    export function play(toPlay: Playable, playbackMode: PlaybackMode) {\n        toPlay.play(playbackMode);\n    }\n\n    /**\n     * Create a Playable object for a melody.\n     * @param melody the melody to make playable\n     */\n    //% blockId=\"music_melody_playable\"\n    //% block=\"sound $melody\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    //% blockHidden\n    //% help=music/melody-playable\n    export function melodyPlayable(melody: Melody): Playable {\n        return new MelodyPlayable(melody);\n    }\n\n    /**\n     * Create a Playable object for a melody string containg notes.\n     * @param melody the melody string to make playable\n     */\n    //% blockId=\"music_string_playable\"\n    //% block=\"melody $melody at tempo $tempo|(bpm)\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% melody.shadow=melody_editor\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% help=music/string-playable\n    export function stringPlayable(melody: string, tempo: number): Playable {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        return new MelodyPlayable(new Melody(formattedMelody));\n    }\n\n    /**\n     * Create a Playable object for a single tone and its duration.\n     * @param note the note or tone frequency to play\n     * @param duration the duration of the tone in milliseconds (ms)\n     */\n    //% blockId=\"music_tone_playable\"\n    //% block=\"tone $note for $duration\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Tone\"\n    //% duplicateShadowOnDrag\n    //% note.shadow=device_note\n    //% duration.shadow=device_beat\n    //% parts=\"headphone\"\n    //% help=music/tone-playable\n    export function tonePlayable(note: number, duration: number): Playable {\n        return new TonePlayable(note, duration);\n    }\n\n    export function _stopPlayables() {\n        state().stopLooping();\n    }\n}","pxt.json":"{\n    \"name\": \"mixer---nrf52\",\n    \"description\": \"The music library with a mixer\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"SoundOutput.h\",\n        \"sound.cpp\",\n        \"melody.h\",\n        \"melody.cpp\",\n        \"melody.ts\",\n        \"piano.ts\",\n        \"legacy.ts\",\n        \"ns.ts\",\n        \"targetoverrides.ts\",\n        \"music.ts\",\n        \"soundEffect.ts\",\n        \"instrument.ts\",\n        \"sequencer.ts\",\n        \"playable.ts\",\n        \"pxtparts.json\",\n        \"headphone.svg\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","pxtparts.json":"{\n    \"headphone\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"image\": \"headphone.svg\",\n            \"width\": 142,\n            \"height\": 180,\n            \"pinDistance\": 20,\n            \"pinLocations\": [\n                {\n                    \"x\": 17,\n                    \"y\": 11\n                },\n                {\n                    \"x\": 55,\n                    \"y\": 50\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"A0\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","sequencer.ts":"namespace music.sequencer {\n    const SEQUENCER_STOP_MESSAGE = 3243;\n    const SEQUENCER_TICK_MESSAGE = 3244;\n    const SEQUENCER_STATE_CHANGE_MESSAGE = 3245;\n    const SEQUENCER_LOOPED_MESSAGE = 3246;\n\n    export class Sequencer {\n        currentTick: number;\n        isPlaying: boolean;\n        isLooping: boolean;\n        isRunning: boolean;\n\n        constructor(public song: Song) {\n            this.currentTick = 0;\n            this.isPlaying = false;\n            this.isLooping = false;\n        }\n\n        start(loop: boolean) {\n            this.currentTick = 0;\n            this.isLooping = loop;\n            this.isPlaying = true;\n\n            if (this.isRunning) return;\n            this.isRunning = true;\n\n            control.runInParallel(() => {\n                while (this.isPlaying) {\n                    this.scheduleCurrentTick();\n\n                    this.currentTick ++;\n\n                    if (this.currentTick >= this.song.beatsPerMeasure * this.song.measures * this.song.ticksPerBeat) {\n                        if (this.isLooping) this.currentTick = 0;\n                        else this.isPlaying = false;\n                    }\n\n                    pause(this.tickToMs(1))\n                }\n                this.isRunning = false;\n            })\n        }\n\n        stop() {\n            this.isPlaying = false;\n        }\n\n        tickToMs(ticks: number) {\n            return ((60000 / this.song.beatsPerMinute) / this.song.ticksPerBeat) * ticks;\n        }\n\n        protected scheduleCurrentTick() {\n            for (const track of this.song.tracks) {\n                if (track.currentNoteEvent.startTick === this.currentTick) {\n                    if (track.isMelodicTrack) {\n                        this.scheduleMelodicTrack(track as MelodicTrack);\n                    }\n                    else {\n                        this.scheduleDrumTrack(track as DrumTrack);\n                    }\n\n                    track.advanceNoteEvent();\n                }\n            }\n        }\n\n        protected scheduleMelodicTrack(track: MelodicTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderInstrument(\n                        track.instrument,\n                        lookupFrequency(track.currentNoteEvent.getNote(i, track.instrument.octave)),\n                        this.tickToMs(track.currentNoteEvent.endTick - track.currentNoteEvent.startTick),\n                        music.volume()\n                    )\n                );\n            }\n        }\n\n        protected scheduleDrumTrack(track: DrumTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderDrumInstrument(\n                        track.drums[track.currentNoteEvent.getNote(i, undefined)],\n                        music.volume()\n                    )\n                );\n            }\n        }\n    }\n\n    let activeSimSequencers: _SimulatorSequencer[];\n    export function _stopAllSimSequencers() {\n        if (activeSimSequencers) {\n            for (const seq of activeSimSequencers) {\n                seq.stop();\n                seq.dispose();\n            }\n            activeSimSequencers = [];\n        }\n    }\n\n    // Simulator only! Does nothing on hardware\n    export class _SimulatorSequencer {\n        protected id: number;\n\n        constructor() {\n            if (!activeSimSequencers) activeSimSequencers = [];\n            activeSimSequencers.push(this);\n            this.id = _createSequencer();\n            this.setVolume(music.volume());\n        }\n\n        play(song: Buffer, loop: boolean) {\n            this.setVolume(music.volume());\n            _sequencerPlaySong(this.id, song, loop)\n        }\n\n        stop() {\n            _sequencerStop(this.id);\n        }\n\n        setVolume(volume: number) {\n            _sequencerSetVolume(this.id, volume);\n        }\n\n        setTrackVolume(trackIndex: number, volume: number) {\n            _sequencerSetTrackVolume(this.id, trackIndex, volume)\n        }\n\n        setDrumTrackVolume(trackIndex: number, drumIndex: number, volume: number) {\n            _sequencerSetDrumTrackVolume(this.id, drumIndex, trackIndex, volume)\n        }\n\n        state() {\n            return _sequencerState(this.id) || \"stop\";\n        }\n\n        currentTick() {\n            return _sequencerCurrentTick(this.id);\n        }\n\n        dispose() {\n            _sequencerDispose(this.id);\n        }\n\n        onTick(handler: (tick: number) => void) {\n            control.onEvent(SEQUENCER_TICK_MESSAGE, this.id, () => {\n                handler(this.currentTick());\n            });\n        }\n\n        onStateChange(handler: (state: string) => void) {\n            control.onEvent(SEQUENCER_STATE_CHANGE_MESSAGE, this.id, () => {\n                handler(this.state());\n            });\n        }\n\n        onStop(handler: () => void) {\n            control.onEvent(SEQUENCER_STOP_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n\n        onLooped(handler: () => void) {\n            control.onEvent(SEQUENCER_LOOPED_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n    }\n\n    //% promise\n    //% shim=music::_createSequencer\n    declare function _createSequencer(): number\n\n    //% shim=music::_sequencerState\n    declare function _sequencerState(id: number): string;\n\n    //% shim=music::_sequencerCurrentTick\n    declare function _sequencerCurrentTick(id: number): number;\n\n    //% shim=music::_sequencerPlaySong\n    declare function _sequencerPlaySong(id: number, song: Buffer, loop: boolean): void;\n\n    //% shim=music::_sequencerStop\n    declare function _sequencerStop(id: number): void;\n\n    //% shim=music::_sequencerSetVolume\n    declare function _sequencerSetVolume(id: number, volume: number): void;\n\n    //% shim=music::_sequencerSetVolumeForAll\n    declare function _sequencerSetVolumeForAll(volume: number): void;\n\n    //% shim=music::_sequencerSetTrackVolume\n    declare function _sequencerSetTrackVolume(id: number, trackIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerSetDrumTrackVolume\n    declare function _sequencerSetDrumTrackVolume(id: number, trackIndex: number, drumIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerDispose\n    declare function _sequencerDispose(id: number): void;\n}","sound.cpp":"// to be overridden\n","soundEffect.ts":"enum WaveShape {\n    //% block=\"sine\"\n    Sine = 0,\n    //% block=\"sawtooth\"\n    Sawtooth = 1,\n    //% block=\"triangle\"\n    Triangle = 2,\n    //% block=\"square\"\n    Square = 3,\n    //% block=\"noise\"\n    Noise = 4\n}\n\nenum InterpolationCurve {\n    //% block=\"linear\"\n    Linear,\n    //% block=\"curve\"\n    Curve,\n    //% block=\"logarithmic\"\n    Logarithmic\n}\n\nenum SoundExpressionEffect {\n    //% block=\"none\"\n    None = 0,\n    //% block=\"vibrato\"\n    Vibrato = 1,\n    //% block=\"tremolo\"\n    Tremolo = 2,\n    //% block=\"warble\"\n    Warble = 3\n}\n\nenum SoundExpressionPlayMode {\n    //% block=\"until done\"\n    UntilDone,\n    //% block=\"in background\"\n    InBackground\n}\n\nnamespace music {\n    export class SoundEffect extends Playable {\n        waveShape: WaveShape;\n        startFrequency: number;\n        endFrequency: number;\n        startVolume: number;\n        endVolume: number;\n        duration: number;\n        effect: SoundExpressionEffect;\n        interpolation: InterpolationCurve;\n\n        constructor() {\n            super();\n            this.waveShape = WaveShape.Sine;\n            this.startFrequency = 5000;\n            this.endFrequency = 1;\n            this.startVolume = 255;\n            this.endVolume = 0;\n            this.duration = 1000;\n            this.effect = SoundExpressionEffect.None;\n            this.interpolation = InterpolationCurve.Linear;\n        }\n\n        toBuffer(volume?: number) {\n            if (volume === undefined) volume = music.volume();\n\n            return soundToInstructionBuffer(\n                this.waveShape,\n                this.startFrequency,\n                this.endFrequency,\n                this.startVolume,\n                this.endVolume,\n                this.duration,\n                this.effect,\n                this.interpolation,\n                20,\n                1,\n                volume\n            );\n        }\n\n        play(playbackMode: PlaybackMode) {\n            const toPlay = this.toBuffer(music.volume());\n            if (playbackMode === PlaybackMode.InBackground) {\n                queuePlayInstructions(0, toPlay);\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                queuePlayInstructions(0, toPlay);\n                pause(this.duration)\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n\n    /**\n     * Play a SoundEffect.\n     * @param sound the SoundEffect to play\n     * @param mode the play mode, play until done or in the background\n     */\n    //% blockId=soundExpression_playSoundEffect\n    //% block=\"play sound $sound $mode\"\n    //% weight=30\n    //% help=music/play-sound-effect\n    //% blockGap=8\n    //% group=\"Sounds\"\n    //% deprecated=1\n    export function playSoundEffect(sound: SoundEffect, mode: SoundExpressionPlayMode) {\n        const toPlay = sound.toBuffer(music.volume());\n\n        queuePlayInstructions(0, toPlay);\n        if (mode === SoundExpressionPlayMode.UntilDone) {\n            pause(sound.duration);\n        }\n    }\n\n    /**\n     * Create a sound expression from a set of sound effect parameters.\n     * @param waveShape waveform of the sound effect\n     * @param startFrequency starting frequency for the sound effect waveform\n     * @param endFrequency ending frequency for the sound effect waveform\n     * @param startVolume starting volume of the sound, or starting amplitude\n     * @param endVolume ending volume of the sound, or ending amplitude\n     * @param duration the amount of time in milliseconds (ms) that sound will play for\n     * @param effect the effect to apply to the waveform or volume\n     * @param interpolation interpolation method for frequency scaling\n     */\n    //% blockId=soundExpression_createSoundEffect\n    //% help=music/create-sound-effect\n    //% block=\"$waveShape|| start frequency $startFrequency end frequency $endFrequency duration $duration start volume $startVolume end volume $endVolume effect $effect interpolation $interpolation\"\n    //% waveShape.defl=WaveShape.Sine\n    //% waveShape.fieldEditor=soundeffect\n    //% waveShape.fieldOptions.useMixerSynthesizer=true\n    //% startFrequency.defl=5000\n    //% startFrequency.min=0\n    //% startFrequency.max=5000\n    //% endFrequency.defl=0\n    //% endFrequency.min=0\n    //% endFrequency.max=5000\n    //% startVolume.defl=255\n    //% startVolume.min=0\n    //% startVolume.max=255\n    //% endVolume.defl=0\n    //% endVolume.min=0\n    //% endVolume.max=255\n    //% duration.defl=500\n    //% duration.min=1\n    //% duration.max=9999\n    //% effect.defl=SoundExpressionEffect.None\n    //% interpolation.defl=InterpolationCurve.Linear\n    //% compileHiddenArguments=true\n    //% inlineInputMode=\"variable\"\n    //% inlineInputModeLimit=3\n    //% expandableArgumentBreaks=\"3,5\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=20\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    export function createSoundEffect(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve): SoundEffect {\n        const result = new SoundEffect();\n\n        result.waveShape = waveShape;\n        result.startFrequency = startFrequency;\n        result.endFrequency = endFrequency;\n        result.startVolume = startVolume;\n        result.endVolume = endVolume;\n        result.duration = duration;\n        result.effect = effect;\n        result.interpolation = interpolation;\n\n        return result;\n    }\n\n    interface Step {\n        frequency: number;\n        volume: number;\n    }\n\n     export function soundToInstructionBuffer(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve, fxSteps: number, fxRange: number, globalVolume: number) {\n        const steps: Step[] = [];\n\n        // Optimize the simple case\n        if (interpolation === InterpolationCurve.Linear && effect === SoundExpressionEffect.None) {\n            steps.push({\n                frequency: startFrequency,\n                volume: (startVolume / 255) * globalVolume,\n            })\n            steps.push({\n                frequency: endFrequency,\n                volume: (endVolume / 255) * globalVolume,\n            })\n        }\n        else {\n\n            fxSteps = Math.min(fxSteps, Math.floor(duration / 5))\n\n            const getVolumeAt = (t: number) => ((startVolume + t * (endVolume - startVolume) / duration) / 255) * globalVolume;\n            let getFrequencyAt: (t: number) => number;\n\n            switch (interpolation) {\n                case InterpolationCurve.Linear:\n                    getFrequencyAt = t => startFrequency + t * (endFrequency - startFrequency) / duration;\n                    break;\n                case InterpolationCurve.Curve:\n                    getFrequencyAt = t => startFrequency + (endFrequency - startFrequency) * Math.sin(t / duration * (Math.PI / 2));\n                    break;\n                case InterpolationCurve.Logarithmic:\n                    getFrequencyAt = t => startFrequency + (Math.log(1 + 9 * (t / duration)) / Math.log(10)) * (endFrequency - startFrequency)\n                    break;\n            }\n\n            const timeSlice = duration / fxSteps;\n\n            for (let i = 0; i < fxSteps; i++) {\n                const newStep = {\n                    frequency: getFrequencyAt(i * timeSlice),\n                    volume: getVolumeAt(i * timeSlice)\n                };\n\n                if (effect === SoundExpressionEffect.Tremolo) {\n                    if (i % 2 === 0) {\n                        newStep.volume = Math.max(newStep.volume - fxRange * 500, 0)\n                    }\n                    else {\n                        newStep.volume = Math.min(newStep.volume + fxRange * 500, 1023)\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Vibrato) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 100, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 100\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Warble) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 1000, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 1000\n                    }\n                }\n\n                steps.push(newStep)\n            }\n        }\n\n        const out = control.createBuffer(12 * (steps.length - 1));\n        const stepDuration = Math.floor(duration / (steps.length - 1))\n\n        for (let i = 0; i < steps.length - 1; i++) {\n            const offset = i * 12;\n            out.setNumber(NumberFormat.UInt8LE, offset, waveToValue(waveShape));\n            out.setNumber(NumberFormat.UInt16LE, offset + 2, steps[i].frequency);\n            out.setNumber(NumberFormat.UInt16LE, offset + 4, stepDuration);\n            out.setNumber(NumberFormat.UInt16LE, offset + 6, steps[i].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 8, steps[i + 1].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 10, steps[i + 1].frequency);\n        }\n\n        return out;\n    }\n\n    function waveToValue(wave: WaveShape) {\n        switch (wave) {\n            case WaveShape.Square: return 15;\n            case WaveShape.Sine: return 3;\n            case WaveShape.Triangle: return 1;\n            case WaveShape.Noise: return 18;\n            case WaveShape.Sawtooth: return 2;\n        }\n    }\n\n\n    /**\n     * Generate a random similar sound effect to the given one.\n     *\n     * @param sound the sound effect\n     */\n    //% blockId=soundExpression_generateSimilarSound\n    //% block=\"randomize $sound\"\n    //% sound.shadow=soundExpression_createSoundEffect\n    //% weight=0 help=music/randomize-sound\n    //% blockGap=8\n    //% group=\"Sounds\"\n    export function randomizeSound(sound: SoundEffect) {\n        const res = new SoundEffect();\n        res.waveShape = sound.waveShape;\n        res.startFrequency = sound.startFrequency;\n        res.endFrequency = sound.endFrequency;\n        res.startVolume = sound.startVolume;\n        res.endVolume = sound.endVolume;\n        res.duration = sound.duration;\n        res.effect = sound.effect;\n        res.interpolation = randomInterpolation();\n\n        res.duration = Math.clamp(\n            Math.min(100, res.duration),\n            Math.max(2000, res.duration),\n            res.duration + (Math.random() - 0.5) * res.duration,\n        );\n\n        if (res.waveShape === WaveShape.Noise) {\n            // The primary waveforms don't produce sounds that are similar to noise,\n            // but adding an effect sorta does\n            if (Math.percentChance(20)) {\n                res.waveShape = randomWave();\n                res.effect = randomEffect();\n            }\n        }\n        else {\n            res.waveShape = randomWave();\n\n            // Adding an effect can drastically alter the sound, so keep it\n            // at a low percent chance unless there already is one\n            if (res.effect !== SoundExpressionEffect.None || Math.percentChance(10)) {\n                res.effect = randomEffect();\n            }\n        }\n\n        // Instead of randomly changing the frequency, change the slope and choose\n        // a new start frequency. This keeps a similar profile to the sound\n        const oldFrequencyDifference = res.endFrequency - res.startFrequency;\n        let newFrequencyDifference = oldFrequencyDifference + (oldFrequencyDifference * 2) * (Math.random() - 0.5);\n\n        if (Math.sign(oldFrequencyDifference) !== Math.sign(newFrequencyDifference)) {\n            newFrequencyDifference *= -1;\n        }\n\n        newFrequencyDifference = Math.clamp(-5000, 5000, newFrequencyDifference);\n\n        res.startFrequency = Math.clamp(\n            Math.max(-newFrequencyDifference, 1),\n            Math.clamp(1, 5000, 5000 - newFrequencyDifference),\n            Math.random() * 5000,\n        );\n\n        res.endFrequency = Math.clamp(1, 5000, res.startFrequency + newFrequencyDifference);\n\n        // Same strategy for volume\n        const oldVolumeDifference = res.endVolume - res.startVolume;\n        let newVolumeDifference = oldVolumeDifference + oldVolumeDifference * (Math.random() - 0.5);\n\n        newVolumeDifference = Math.clamp(-255, 255, newVolumeDifference);\n\n        if (Math.sign(oldVolumeDifference) !== Math.sign(newVolumeDifference)) {\n            newVolumeDifference *= -1;\n        }\n\n        res.startVolume = Math.clamp(\n            Math.max(-newVolumeDifference, 0),\n            Math.clamp(0, 255, 255 - newVolumeDifference),\n            Math.random() * 255,\n        );\n\n        res.endVolume = Math.clamp(0, 255, res.startVolume + newVolumeDifference);\n\n        return res;\n    }\n\n    function randomWave() {\n        switch (Math.randomRange(0, 3)) {\n            case 1: return WaveShape.Sawtooth;\n            case 2: return WaveShape.Square;\n            case 3: return WaveShape.Triangle;\n            case 0:\n            default:\n                return WaveShape.Sine;\n        }\n    }\n\n    function randomEffect() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return SoundExpressionEffect.Warble;\n            case 2: return  SoundExpressionEffect.Tremolo;\n            case 0:\n            default:\n                return SoundExpressionEffect.Vibrato;\n        }\n    }\n\n    function randomInterpolation() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return InterpolationCurve.Linear;\n            case 2: return  InterpolationCurve.Curve;\n            case 0:\n            default:\n                return InterpolationCurve.Logarithmic;\n        }\n    }\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n}","targetoverrides.ts":"\n","test.ts":"for(let i = 1000; i > 0; i -= 50)\n    music.playTone(440, i)\n\nfor(let i = 0; i < 1000; i += 20)\n    music.playTone(440, i)\n"},"mixer---samd":{"SoundOutput.h":"#include \"SAMDDAC.h\"\n#include \"Synthesizer.h\"\n#include \"Mixer.h\"\n\nnamespace jacdac {\nvoid setJackRouterOutput(int output);\n}\n\nclass SoundOutput {\n  public:\n    SAMDDAC dac;\n\n    SoundOutput(DataSource &data) : dac(*pxt::lookupPin(PIN_PA02), data) {\n        jacdac::setJackRouterOutput(-1);\n    }\n\n    void setOutput(int output) { jacdac::setJackRouterOutput(output); }\n};\n","headphone.svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"142\" height=\"180\" viewBox=\"0 0 142 180\"><rect ry=\".3\" rx=\"1\" y=\"58.615\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><rect ry=\".3\" rx=\"1\" y=\"32.043\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><path d=\"M.346 7.296c-.394.39-.31 4.797-.18 4.898l13.404 10.18c.117.12.337 4.76.73 4.368l5.506-5.56.01.01 6.51-6.444c.39-.392-4.25-.614-4.366-.73L11.777.612c-.1-.132-4.51-.215-4.898.18L4.087 3.636l-.01-.01-3.73 3.67z\" fill=\"#b3b3b3\"/><rect ry=\"6.85\" rx=\"4.571\" y=\"84.758\" x=\"-20.128\" height=\"75.571\" width=\"39.643\" transform=\"rotate(-45)\"/><rect ry=\".374\" rx=\"1.038\" y=\"29.442\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"55.939\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"82.392\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\"2.317\" rx=\"2.183\" y=\"158.876\" x=\"-9.774\" height=\"25.568\" width=\"18.935\" transform=\"rotate(-45)\"/><path d=\"M128.588 128.82s14.97 11.165 7.547 26.35c-8.426 17.24-25.57 20.653-25.57 20.653\" fill=\"none\" stroke=\"#000\" stroke-width=\"6.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>","instrument.ts":"namespace music.sequencer {\n    const BUFFER_SIZE = 12;\n\n    let currentSequencer: sequencer.Sequencer;\n\n    /**\n     * Byte encoding format for songs\n     * FIXME: should this all be word aligned?\n     *\n     * song(7 + length of all tracks bytes)\n     *     0 version\n     *     1 beats per minute\n     *     3 beats per measure\n     *     4 ticks per beat\n     *     5 measures\n     *     6 number of tracks\n     *     ...tracks\n     *\n     * track(6 + instrument length + note length bytes)\n     *     0 id\n     *     1 flags\n     *     2 instruments byte length\n     *     4...instrument\n     *     notes byte length\n     *     ...note events\n     *\n     * instrument(28 bytes)\n     *     0 waveform\n     *     1 amp attack\n     *     3 amp decay\n     *     5 amp sustain\n     *     7 amp release\n     *     9 amp amp\n     *     11 pitch attack\n     *     13 pitch decay\n     *     15 pitch sustain\n     *     17 pitch release\n     *     19 pitch amp\n     *     21 amp lfo freq\n     *     22 amp lfo amp\n     *     24 pitch lfo freq\n     *     25 pitch lfo amp\n     *     27 octave\n     *\n     * drum(5 + 7 * steps bytes)\n     *     0 steps\n     *     1 start freq\n     *     3 start amp\n     *     5...steps\n     *\n     * drum step(7 bytes)\n     *     0 waveform\n     *     1 freq\n     *     3 volume\n     *     5 duration\n     *\n     * note event(5 + 1 * polyphony bytes)\n     *     0 start tick\n     *     2 end tick\n     *     4 polyphony\n     *     5...notes(1 byte each)\n     *\n     * note (1 byte)\n     *     lower six bits = note - (instrumentOctave - 2) * 12\n     *     upper two bits are the enharmonic spelling:\n     *          0 = normal\n     *          1 = flat\n     *          2 = sharp\n     */\n\n    export class Song extends Playable {\n        tracks: Track[];\n\n        constructor(public buf: Buffer) {\n            super();\n            this.tracks = [];\n\n            let currentOffset = 7;\n            for (let i = 0; i < this.numberOfTracks; i++) {\n                let track: Track = new MelodicTrack(this.buf, currentOffset);\n\n                if (!track.isMelodicTrack) {\n                    track = new DrumTrack(this.buf, currentOffset)\n                }\n\n                this.tracks.push(track);\n                currentOffset += track.byteLength;\n            }\n        }\n\n        get version(): number {\n            return this.buf[0];\n        }\n\n        set version(value: number) {\n            this.buf[0] = value;\n        }\n\n        get beatsPerMinute(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, 1);\n        }\n\n        set beatsPerMinute(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, 1, value);\n        }\n\n        get beatsPerMeasure(): number {\n            return this.buf[3];\n        }\n\n        set beatsPerMeasure(value: number) {\n            this.buf[3] = value;\n        }\n\n        get ticksPerBeat(): number {\n            return this.buf[4];\n        }\n\n        set ticksPerBeat(value: number) {\n            this.buf[4] = value;\n        }\n\n        get measures(): number {\n            return this.buf[5];\n        }\n\n        set measures(value: number) {\n            this.buf[5] = value;\n        }\n\n        get numberOfTracks(): number {\n            return this.buf[6];\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (control.deviceDalVersion() === \"sim\") {\n                const seq = new _SimulatorSequencer();\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    seq.play(this.buf, false);\n\n                    pauseUntil(() => seq.state() === \"stop\");\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    seq.play(this.buf, false);\n                }\n                else {\n                    seq.play(this.buf, true);\n                }\n            }\n            else {\n                if (currentSequencer) currentSequencer.stop();\n                currentSequencer = new sequencer.Sequencer(this);\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    let seq = currentSequencer;\n                    currentSequencer.start(false);\n                    pauseUntil(() => !seq.isRunning);\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    currentSequencer.start(false);\n                }\n                else {\n                    currentSequencer.start(true);\n                }\n            }\n        }\n    }\n\n    export class Envelope {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(10);\n            this.offset = this.offset || 0;\n        }\n\n        // The time in ms for the envelope to reach its maximum value\n        get attack(): number {\n            return this.getValue(0);\n        }\n\n        set attack(value: number) {\n            this.setValue(0, value);\n        }\n\n        // The time in ms for the envelope to reach its sustain value after reaching its maximum value\n        get decay(): number {\n            return this.getValue(2);\n        }\n\n        set decay(value: number) {\n            this.setValue(2, value);\n        }\n\n        // The value (0-1024) to hold at during the sustain stage\n        get sustain(): number {\n            return this.getValue(4);\n        }\n\n        set sustain(value: number) {\n            this.setValue(4, value);\n        }\n\n        // The time in ms for the envelope to reach 0 after the gate length ends\n        get release(): number {\n            return this.getValue(6);\n        }\n\n        set release(value: number) {\n            this.setValue(6, value);\n        }\n\n        // The maximum value that this envelope will reach\n        get amplitude(): number {\n            return this.getValue(8);\n        }\n\n        set amplitude(value: number) {\n            this.setValue(8, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class LFO {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(3);\n            this.offset = this.offset || 0;\n        }\n\n        get frequency(): number {\n            return this.buf[this.offset];\n        }\n\n        set frequency(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get amplitude(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + 1);\n        }\n\n        set amplitude(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + 1, value);\n        }\n    }\n\n    export class NoteEvent {\n        constructor(public buf: Buffer, public offset: number) {\n\n        }\n\n        get startTick(): number {\n            return this.getValue(0);\n        }\n\n        set startTick(value: number) {\n            this.setValue(0, value);\n        }\n\n        get endTick(): number {\n            return this.getValue(2);\n        }\n\n        set endTick(value: number) {\n            this.setValue(2, value);\n        }\n\n        get polyphony(): number {\n            return this.buf[this.offset + 4];\n        }\n\n        set polyphony(value: number) {\n            this.buf[this.offset + 4] = value;\n        }\n\n        get byteLength() {\n            return this.polyphony + 5;\n        }\n\n        getNote(offset: number, octave?: number) {\n            const value = this.buf[this.offset + offset + 5] & 0x3f;\n            if (octave !== undefined) {\n                return value + (octave - 2) * 12\n            }\n            return value\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class Track {\n        currentNoteEvent: NoteEvent;\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.currentNoteEvent = new NoteEvent(this.buf, this.noteEventStart + 2);\n        }\n\n        get isMelodicTrack(): boolean {\n            return this.flags === 0;\n        }\n\n        get id(): number {\n            return this.buf[this.offset];\n        }\n\n        set id(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get flags(): number {\n            return this.buf[this.offset + 1];\n        }\n\n        set flags(value: number) {\n            this.buf[this.offset + 1] = value;\n        }\n\n        get instrumentByteLength(): number {\n            return this.getValue(this.offset + 2);\n        }\n\n        set instrumentByteLength(value: number) {\n            this.setValue(this.offset + 2, value);\n        }\n\n        get noteEventStart(): number {\n            return this.offset + this.instrumentByteLength + 4;\n        }\n\n        get noteEventByteLength(): number {\n            return this.getValue(this.noteEventStart);\n        }\n\n        set noteEventByteLength(value: number) {\n            this.setValue(this.noteEventStart, value);\n        }\n\n        get byteLength() {\n            return this.noteEventByteLength + this.instrumentByteLength + 6;\n        }\n\n        advanceNoteEvent() {\n            this.currentNoteEvent.offset += this.currentNoteEvent.byteLength;\n\n            if (this.currentNoteEvent.offset >= this.offset + this.byteLength) {\n                this.currentNoteEvent.offset = this.noteEventStart + 2;\n            }\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, offset, value);\n        }\n    }\n\n    export class MelodicTrack extends Track {\n        instrument: Instrument;\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.instrument = new Instrument(this.buf, this.offset + 4);\n        }\n    }\n\n    export class DrumTrack extends Track {\n        drums: DrumInstrument[];\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.drums = [];\n\n            let currentOffset = 0;\n            while (currentOffset < this.instrumentByteLength) {\n                this.drums.push(new DrumInstrument(this.buf, this.offset + 4 + currentOffset));\n                currentOffset += this.drums[this.drums.length - 1].byteLength;\n            }\n        }\n    }\n\n    export class Instrument {\n        ampEnvelope: Envelope;\n        pitchEnvelope: Envelope;\n        ampLFO: LFO;\n        pitchLFO: LFO;\n\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(27);\n            this.offset = this.offset || 0;\n            this.ampEnvelope = new Envelope(this.buf, this.offset + 1);\n            this.pitchEnvelope = new Envelope(this.buf, this.offset + 11);\n            this.ampLFO = new LFO(this.buf, this.offset + 21);\n            this.pitchLFO = new LFO(this.buf, this.offset + 24)\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get octave(): number {\n            return this.buf[this.offset + 27]\n        }\n\n        set octave(value: number) {\n            this.buf[this.offset + 27] = value;\n        }\n    }\n\n    export class DrumInstrument {\n        steps: DrumStep[];\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.steps = [];\n\n            for (let i = 0; i < this.numSteps; i++) {\n                this.steps.push(new DrumStep(this.buf, this.offset + 5 + i * 7))\n            }\n        }\n\n        get byteLength(): number {\n            return 5 + this.numSteps * 7;\n        }\n\n        get numSteps(): number {\n            return this.buf[this.offset];\n        }\n\n        set numSteps(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get startFrequency(): number {\n            return this.getValue(1);\n        }\n\n        set startFrequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get startVolume(): number {\n            return this.getValue(3);\n        }\n\n        set startVolume(value: number) {\n            this.setValue(3, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class DrumStep {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(7);\n            this.offset = this.offset || 0;\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get frequency(): number {\n            return this.getValue(1);\n        }\n\n        set frequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get volume(): number {\n            return this.getValue(3);\n        }\n\n        set volume(value: number) {\n            this.setValue(3, value);\n        }\n\n        get duration(): number {\n            return this.getValue(5);\n        }\n\n        set duration(value: number) {\n            this.setValue(5, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    /**\n     * Renders a single note played on an instrument into a buffer of sound instructions.\n     *\n     * @param instrument The instrument being played\n     * @param noteFrequency The frequency of the note being played. In other words, \"the key being pressed on the piano\"\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     * @param volume The peak volume of the note to play (0-1024). Also called the \"velocity\"\n     */\n    export function renderInstrument(instrument: Instrument, noteFrequency: number, gateLength: number, volume: number) {\n        // We cut off the sound at the end of the amplitude envelope's release time. This is to prevent\n        // the amp envelope from making the sound keep playing forever\n        const totalDuration = gateLength + instrument.ampEnvelope.release;\n\n        // Our goal is to calculate the frequency and amplitude at all of the inflection points in this note's lifetime\n\n        // For the ADSR envelopes, the inflection points are:\n        //     1. The end of the envelope atack (which is when the decay begins)\n        //     2. The end of the envelope decay (which is when the sustain begins)\n        //     3. The end of the gateLength (which is when the release begins)\n        //     4. The end of the envelope release\n        // If the gateLength ends before any of these stages (e.g. it's shorter than the envelope's attack), then\n        // we ignore the other stages and go straight to the release stage.\n\n        // For the triangle LFOs, the inflections points occur every time the slope goes from positive to negative. In\n        // other words, it's half the period of the triangle wave.\n\n        const ampLFOInterval = instrument.ampLFO.amplitude ? Math.max(500 / instrument.ampLFO.frequency, 50) : 50;\n        const pitchLFOInterval = instrument.pitchLFO.amplitude ? Math.max(500 / instrument.pitchLFO.frequency, 50) : 50;\n\n        // We're going to add the timepoints to this array in order so that it doesn't need to be sorted\n        let timePoints = [0];\n\n        // For each LFO and envelope, keep track of the next inflection point. If any of the LFOs or envelopes have\n        // an amplitude of 0, we can ignore them entirely.\n        let nextAETime = instrument.ampEnvelope.attack;\n        let nextPETime = instrument.pitchEnvelope.amplitude ? instrument.pitchEnvelope.attack : totalDuration;\n        let nextPLTime = instrument.pitchLFO.amplitude ? pitchLFOInterval : totalDuration;\n        let nextALTime = instrument.ampLFO.amplitude ? ampLFOInterval : totalDuration;\n\n        let time = 0;\n        while (time < totalDuration) {\n            // Amp envelope\n            if (nextAETime <= nextPETime && nextAETime <= nextPLTime && nextAETime <= nextALTime) {\n                time = nextAETime;\n                timePoints.push(nextAETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            // Pitch envelope\n            else if (nextPETime <= nextPLTime && nextPETime <= nextALTime && nextPETime < totalDuration) {\n                time = nextPETime;\n                timePoints.push(nextPETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                // If we reach the end of the release before the amp envelope is finished, bail out\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            // Pitch LFO\n            else if (nextPLTime <= nextALTime && nextPLTime < totalDuration) {\n                time = nextPLTime;\n                timePoints.push(nextPLTime);\n                nextPLTime += pitchLFOInterval;\n            }\n            // Amp LFO\n            else if (nextALTime < totalDuration) {\n                time = nextALTime;\n                timePoints.push(nextALTime);\n                nextALTime += ampLFOInterval;\n            }\n\n\n            if (time >= totalDuration) {\n                break;\n            }\n\n            // Now that we've advanced the time, we need to check all of the envelopes/LFOs again\n            // to see if any of them also need to be pushed forward (e.g. they had the same inflection point\n            // as the one we just added to the array)\n            if (nextAETime <= time) {\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            if (nextPETime <= time) {\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            while (nextALTime <= time) {\n                nextALTime += ampLFOInterval;\n            }\n            while (nextPLTime <= time) {\n                nextPLTime += pitchLFOInterval;\n            }\n        }\n\n        // Once we've calculated the inflection points, calculate the frequency and amplitude at\n        // each step and interpolate between them with sound instructions\n        let prevAmp = instrumentVolumeAtTime(instrument, gateLength, 0, volume) | 0;\n        let prevPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, 0) | 0;\n        let prevTime = 0;\n\n        let nextAmp: number;\n        let nextPitch: number;\n        const out = control.createBuffer(BUFFER_SIZE * timePoints.length);\n        for (let i = 1; i < timePoints.length; i++) {\n            if (timePoints[i] - prevTime < 5) {\n                prevTime = timePoints[i];\n                continue;\n            }\n\n            nextAmp = instrumentVolumeAtTime(instrument, gateLength, timePoints[i], volume) | 0;\n            nextPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, timePoints[i]) | 0\n            addNote(\n                out,\n                (i - 1) * 12,\n                (timePoints[i] - prevTime) | 0,\n                prevAmp,\n                nextAmp,\n                instrument.waveform,\n                prevPitch,\n                255,\n                nextPitch\n            )\n\n            prevAmp = nextAmp;\n            prevPitch = nextPitch;\n            prevTime = timePoints[i];\n        }\n\n        // Finally, add one extra step to move the amplitude to 0 without\n        // clipping just in case the amp LFO caused it to be nonzero\n        addNote(\n            out,\n            (timePoints.length - 1) * 12,\n            10,\n            prevAmp,\n            0,\n            instrument.waveform,\n            prevPitch,\n            255,\n            prevPitch\n        )\n        return out;\n    }\n\n    export function renderDrumInstrument(sound: DrumInstrument, volume: number) {\n        // Drum instruments are rendered just like melodic instruments, but the inflection\n        // points are already calculated for us\n        let prevAmp = sound.startVolume;\n        let prevFreq = sound.startFrequency;\n\n        const scaleVolume = (value: number) => (value / 1024) * volume;\n\n        let out = control.createBuffer((sound.steps.length + 1) * BUFFER_SIZE);\n\n        for (let i = 0; i < sound.steps.length; i++) {\n            addNote(\n                out,\n                i * BUFFER_SIZE,\n                sound.steps[i].duration,\n                scaleVolume(prevAmp),\n                scaleVolume(sound.steps[i].volume),\n                sound.steps[i].waveform,\n                prevFreq,\n                255,\n                sound.steps[i].frequency\n            );\n            prevAmp = sound.steps[i].volume;\n            prevFreq = sound.steps[i].frequency\n        }\n\n        addNote(\n            out,\n            sound.steps.length * BUFFER_SIZE,\n            10,\n            scaleVolume(prevAmp),\n            0,\n            sound.steps[sound.steps.length - 1].waveform,\n            prevFreq,\n            255,\n            prevFreq\n        );\n\n        return out;\n    }\n\n    function instrumentPitchAtTime(instrument: Instrument, noteFrequency: number, gateLength: number, time: number) {\n        let mod = 0;\n        if (instrument.pitchEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.pitchEnvelope, time, gateLength)\n        }\n        if (instrument.pitchLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.pitchLFO, time)\n        }\n        return Math.max(noteFrequency + mod, 0);\n    }\n\n    function instrumentVolumeAtTime(instrument: Instrument, gateLength: number, time: number, maxVolume: number) {\n        let mod = 0;\n        if (instrument.ampEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.ampEnvelope, time, gateLength)\n        }\n        if (instrument.ampLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.ampLFO, time)\n        }\n        return ((Math.max(Math.min(mod, instrument.ampEnvelope.amplitude), 0) / 1024) * maxVolume) | 0;\n    }\n\n    /**\n     * Calculates the value of an ADSR envelope at the given time for a given gate length.\n     *\n     * @param envelope The ADSR envelope\n     * @param time The point and time to calculate the value at\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     */\n    function envelopeValueAtTime(envelope: Envelope, time: number, gateLength: number) {\n        // ADSR envelopes consist of 4 stages. They are (in order):\n        //     1. The attack stage, where the value starts at 0 and rises to the maximum value\n        //     2. The decay stage, where the value falls from the maximum value to the sustain value\n        //     3. The sustain stage, where the value holds steady at the sustain value until the gate length ends\n        //     4. The release stage, where the value falls to 0 after the gate length ends\n        // If the gate length ends before the sustain stage, we immediately skip to the release stage. All stages\n        // use a linear function for the value\n        const adjustedSustain = (envelope.sustain / 1024) * envelope.amplitude;\n\n        // First check to see if we are already in the release stage\n        if (time > gateLength) {\n            if (time - gateLength > envelope.release) return 0;\n\n            // Did the gate length end before the attack stage finished?\n            else if (time < envelope.attack) {\n                const height = (envelope.amplitude / envelope.attack) * gateLength;\n                return height - ((height / envelope.release) * (time - gateLength))\n            }\n            // Did the gate length end before the decay stage finished?\n            else if (time < envelope.attack + envelope.decay) {\n                const height2 = envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (gateLength - envelope.attack);\n                return height2 - ((height2 / envelope.release) * (time - gateLength))\n            }\n            else {\n                return adjustedSustain - (adjustedSustain / envelope.release) * (time - gateLength)\n            }\n        }\n        else if (time < envelope.attack) {\n            return (envelope.amplitude / envelope.attack) * time\n        }\n        else if (time < envelope.attack + envelope.decay) {\n            return envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (time - envelope.attack)\n        }\n        else {\n            return adjustedSustain;\n        }\n    }\n\n    /**\n     * Calculates the value of the LFO at the given time.\n     *\n     * TODO: might be nice to give options to shift the phase of the LFO or let it run free\n     *\n     * @param lfo The LFO to calculate the value of\n     * @param time The time to calculate the value at\n     */\n    function lfoValueAtTime(lfo: LFO, time: number) {\n        // Use cosine to smooth out the value somewhat\n        return Math.cos(((time / 1000) * lfo.frequency) * 2 * Math.PI) * lfo.amplitude\n    }\n\n    export function _stopAllSongs() {\n        if (currentSequencer) {\n            currentSequencer.stop();\n            currentSequencer = undefined;\n        }\n        _stopAllSimSequencers();\n    }\n}","legacy.ts":"//% deprecated=true hidden=true\nenum Sounds {\n    //% block=\"power up\"\n    PowerUp,\n    //% block=\"power down\"\n    PowerDown,\n    //% block=\"jump up\"\n    JumpUp,\n    //% block=\"jump down\"\n    JumpDown,\n    //% block=\"ba ding\"\n    BaDing,\n    //% block=\"wawawawaa\"\n    Wawawawaa,\n    //% block=\"magic wand\"\n    MagicWand,\n    //% block=\"siren\"\n    Siren\n}\n\nnamespace music {\n    /**\n     * Get the melody string for a built-in melody.\n     * @param name the note name, eg: Note.C\n     */\n    //% help=music/sounds\n    //% blockId=music_sounds block=\"%name\"\n    //% blockHidden=true\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=285\n    //% name.fieldOptions.columns=3\n    export function sounds(name: Sounds): string {\n        switch (name) {\n            case Sounds.BaDing:\n                return 'b5:1 e6:3';\n            case Sounds.Wawawawaa:\n                return 'e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8';\n            case Sounds.JumpUp:\n                return 'c5:1 d e f g';\n            case Sounds.JumpDown:\n                return 'g5:1 f e d c';\n            case Sounds.PowerUp:\n                return 'g4:1 c5 e g:2 e:1 g:3';\n            case Sounds.PowerDown:\n                return 'g5:1 d# c g4:2 b:1 c5:3';\n            case Sounds.MagicWand:\n                return 'F#6:1-300 G# A# B C7# D# F F# G# A# B:6'; //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n            case Sounds.Siren:\n                return 'a4 d5 a4 d5 a4 d5';\n            default:\n                return '';\n        }\n    }\n\n    let currMelody: Melody\n\n    /**\n     * Start playing a sound and don't wait for it to finish.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound\n    //% blockId=music_play_sound block=\"play sound %sound=music_sounds\"\n    //% parts=\"headphone\"\n    //% weight=95 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSound(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.play();\n        pause(1);\n    }\n\n\n    /**\n     * Play a sound and wait until the sound is done.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound-until-done\n    //% blockId=music_play_sound_until_done block=\"play sound %sound=music_sounds|until done\"\n    //% parts=\"headphone\"\n    //% weight=94 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSoundUntilDone(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.playUntilDone();\n    }\n}","melody.cpp":"#include \"pxt.h\"\n#include \"SoundOutput.h\"\n#include \"melody.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\nnamespace music {\n\nSINGLETON(WSynthesizer);\n\n// Tone generator arguments:\n//\n// sound: a pointer to the currently-playing sound, usable for looking up the\n// waveform or generator-specific state.\n//\n// position: offset within the currently-playing wave, range 0..1023.\n//\n// cycle: a 6-bit cyclical sequence number of the wave, incremented each time\n// the position loops from 1023 back to 0.\ntypedef int (*gentone_t)(PlayingSound *sound, uint32_t position, uint8_t cycle);\n\nstatic int noiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    // see https://en.wikipedia.org/wiki/Xorshift\n    static uint32_t x = 0xf01ba80;\n    x ^= x << 13;\n    x ^= x >> 17;\n    x ^= x << 5;\n    return (x & 0xffff) - 0x7fff;\n}\n\nstatic int sineTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    int32_t p = position;\n    if (p >= 512) {\n        p -= 512;\n    }\n    if (p > 256) {\n        p = 512 - p;\n    }\n\n    // Approximate sin(x * pi / 2) with the odd polynomial y = cx^5 + bx^3 + ax\n    // using the constraint y(1) = 1 => a = 1 - b - c\n    //   => y = c x^5 + b x^3 + (1 - b - c) * x\n    //\n    // Do a least-squares fit of this to sin(x * pi / 2) in the range 0..1\n    // inclusive, using 21 evenly spaced points. Resulting approximation:\n    //\n    // sin(x*pi/2) ~= 0.0721435357258*x**5 - 0.642443736562*x**3 + 1.57030020084*x\n\n    // Scale the constants by 32767 to match the desired output range.\n    constexpr int32_t c = 0.0721435357258 * 32767;\n    constexpr int32_t b = -0.642443736562 * 32767;\n    constexpr int32_t a = 1.57030020084 * 32767;\n\n    // Calculate using y = ((c * x^2 + b) * x^2 + a) * x\n    //\n    // The position p is x * 256, so after each multiply with p we need to\n    // shift right by 8 bits to keep the decimal point in the same place.  (The\n    // approximation has a negative error near x=1 which helps avoid overflow.)\n    int32_t p2 = p * p;\n    int32_t u = (c * p2 >> 16) + b;\n    int32_t v = (u * p2 >> 16) + a;\n    int32_t w = v * p >> 8;\n\n    // The result is within 7/32767 or 0.02%, signal-to-error ratio about 38 dB.\n    return position >= 512 ? -w : w;\n}\n\nstatic int sawtoothTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return (position << 6) - 0x7fff;\n}\n\nstatic int triangleTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return position < 512 ? (position << 7) - 0x7fff : ((1023 - position) << 7) - 0x7fff;\n}\n\nstatic int squareWaveTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)cycle;\n    uint8_t wave = sound->currInstr->soundWave;\n    return (int)position < (102 * (wave - SW_SQUARE_10 + 1)) ? -0x7fff : 0x7fff;\n}\n\nstatic int tunedNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a random bit sequence. Since the generator\n    // is called multiple times per wave, use PlayingSound state data to ensure we\n    // only generate a random bit once per wave, and then reuse it for future\n    // calls for that wave.\n    //\n    // Use the low 6 bits of generatorState to store the last-used cycle, and\n    // random_bit to store the last on/off state. (random_bit is arbitrary as\n    // long as it isn't one of the low 6 bits.)\n    constexpr uint32_t random_bit = 0x8000;\n    static uint32_t x = 0xf01ba80; // seed for the static RNG state\n    uint8_t prev_cycle = sound->generatorState & 0x3f;\n    uint32_t is_on;\n    if (cycle == prev_cycle) {\n        is_on = sound->generatorState & random_bit;\n    } else {\n        // see https://en.wikipedia.org/wiki/Xorshift\n        x ^= x << 13;\n        x ^= x >> 17;\n        x ^= x << 5;\n        is_on = (x & random_bit);\n        sound->generatorState = (cycle & 0x3f) | is_on;\n    }\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\n// Bit patterns for use by the cyclic noise tone.\n//\n// The bit pattern is arbitrary, but should have equal numbers of 0 and 1 bits,\n// and should avoid long identical-bit runs for the lower parts. The values below\n// were chosen based on a random permutation of the hex nibbles 0..f and then\n// hand-tweaked by swapping some nibbles. Generated by:\n//\n//   shuf -i 0-15 | perl -ne 's/(\\d+)/printf(\"%x\",$1)/e'\nstatic const uint32_t cycle_bits[] = {0x2df0eb47, 0xc8165a93};\nstatic const uint8_t cycle_mask[] = {0xf, 0x1f, 0x3f};\n\nstatic int cycleNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    // The bit sequence repeats every 16/32/64 waves.\n    //\n    // The \"cycle\" argument corresponds to the sequential number of the generated\n    // wave. This is currently a 6-bit value. Since the pseudorandom bit sequences\n    // evenly fit into this, there's no need to track generator state.\n    uint8_t wave = sound->currInstr->soundWave;\n    int cycle_index = wave - SW_SQUARE_CYCLE_16;\n    // CLAMP(0, cycle_index, sizeof cycle_bits / sizeof cycle_bits[0])\n    cycle &= cycle_mask[cycle_index];\n    bool is_on = (cycle_bits[cycle >> 5] & (1U << (cycle & 0x1f)));\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\nstatic int silenceTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    return 0;\n}\n\nstatic gentone_t getWaveFn(uint8_t wave) {\n    switch (wave) {\n    case SW_TRIANGLE:\n        return triangleTone;\n    case SW_SAWTOOTH:\n        return sawtoothTone;\n    case SW_TUNEDNOISE:\n        return tunedNoiseTone;\n    case SW_NOISE:\n        return noiseTone;\n    case SW_SINE:\n        return sineTone;\n    default:\n        if (SW_SQUARE_10 <= wave && wave <= SW_SQUARE_50)\n            return squareWaveTone;\n        if (SW_SQUARE_CYCLE_16 <= wave && wave <= SW_SQUARE_CYCLE_64)\n            return cycleNoiseTone;\n        else\n            return silenceTone;\n    }\n}\n\n#define CLAMP(lo, v, hi) ((v) = ((v) < (lo) ? (lo) : (v) > (hi) ? (hi) : (v)))\n\nint WSynthesizer::updateQueues() {\n    const int maxTime = 0xffffff;\n    while (1) {\n        WaitingSound *p;\n        int minLeft = maxTime;\n        for (p = waiting; p; p = p->next) {\n            int timeLeft =\n                p->state == SoundState::Waiting ? p->startSampleNo - currSample : maxTime;\n            if (timeLeft <= 0) {\n                break;\n            }\n            if (timeLeft < minLeft)\n                minLeft = timeLeft;\n        }\n        if (p) {\n            PlayingSound *snd;\n            int minIdx = -1;\n            for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n                snd = &playingSounds[i];\n                if (snd->sound == NULL)\n                    break;\n                if (minIdx == -1 ||\n                    playingSounds[minIdx].startSampleNo < playingSounds[i].startSampleNo)\n                    minIdx = i;\n                snd = NULL;\n            }\n            // if we didn't find a free slot, expel the oldest sound\n            if (!snd)\n                snd = &playingSounds[minIdx];\n            if (snd->sound)\n                snd->sound->state = SoundState::Done;\n            snd->sound = p;\n            p->state = SoundState::Playing;\n            snd->startSampleNo = currSample;\n            snd->currInstr = (SoundInstruction *)p->instructions->data;\n            snd->instrEnd = snd->currInstr + p->instructions->length / sizeof(SoundInstruction);\n            snd->prevVolume = -1;\n        } else {\n            // no more sounds to move\n            return minLeft;\n        }\n    }\n}\n\nint WSynthesizer::fillSamples(int16_t *dst, int numsamples) {\n    if (numsamples <= 0)\n        return 1;\n\n    int timeLeft = updateQueues();\n    int res = waiting != NULL;\n\n    // if there's a pending sound to be started somewhere during numsamples,\n    // split the call into two\n    if (timeLeft < numsamples) {\n        fillSamples(dst, timeLeft);\n        LOG(\"M split %d\", timeLeft);\n        fillSamples(dst + timeLeft, numsamples - timeLeft);\n        return 1;\n    }\n\n    memset(dst, 0, numsamples * 2);\n\n    uint32_t samplesPerMS = (sampleRate << 8) / 1000;\n    float toneStepMult = (1024.0 * (1 << 16)) / sampleRate;\n    const int MAXVAL = (1 << (OUTPUT_BITS - 1)) - 1;\n\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        PlayingSound *snd = &playingSounds[i];\n        if (snd->sound == NULL)\n            continue;\n\n        res = 1;\n\n        SoundInstruction *instr = NULL;\n        gentone_t fn = NULL;\n        snd->currInstr--;\n        uint32_t toneStep = 0;\n        int32_t toneDelta = 0;\n        int32_t volumeStep = 0;\n        uint32_t tonePosition = snd->tonePosition;\n        uint32_t samplesLeft = 0;\n        uint8_t wave = 0;\n        int32_t volume = 0;\n\n        for (int j = 0; j < numsamples; ++j) {\n            if (samplesLeft == 0) {\n                snd->currInstr++;\n                if (snd->currInstr >= snd->instrEnd) {\n                    break;\n                }\n                SoundInstruction copy = *snd->currInstr;\n                instr = &copy;\n                CLAMP(20, instr->frequency, 20000);\n                CLAMP(20, instr->endFrequency, 20000);\n                CLAMP(0, instr->startVolume, 1023);\n                CLAMP(0, instr->endVolume, 1023);\n                CLAMP(1, instr->duration, 60000);\n\n                wave = instr->soundWave;\n                fn = getWaveFn(wave);\n\n                samplesLeft = (uint32_t)(instr->duration * samplesPerMS >> 8);\n                // make sure the division is signed\n                volumeStep =\n                    (int)((instr->endVolume - instr->startVolume) << 16) / (int)samplesLeft;\n\n                if (j == 0 && snd->prevVolume != -1) {\n                    // restore previous state\n                    samplesLeft = snd->samplesLeftInCurr;\n                    volume = snd->prevVolume;\n                    toneStep = snd->prevToneStep;\n                    toneDelta = snd->prevToneDelta;\n                } else {\n                    LOG(\"#sampl %d %p\", samplesLeft, snd->currInstr);\n                    volume = instr->startVolume << 16;\n                    LOG(\"%d-%dHz %d-%d vol\", instr->frequency, instr->endFrequency,\n                        instr->startVolume, instr->endVolume);\n                    toneStep = (uint32_t)(toneStepMult * instr->frequency);\n                    if (instr->frequency != instr->endFrequency) {\n                        uint32_t endToneStep = (uint32_t)(toneStepMult * instr->endFrequency);\n                        toneDelta = (int32_t)(endToneStep - toneStep) / (int32_t)samplesLeft;\n                    } else {\n                        toneDelta = 0;\n                    }\n                }\n            }\n\n            int v = fn(snd, (tonePosition >> 16) & 1023, tonePosition >> 26);\n            v = (v * (volume >> 16)) >> (10 + (16 - OUTPUT_BITS));\n\n            // if (v > MAXVAL)\n            //    target_panic(123);\n\n            dst[j] += v;\n\n            tonePosition += toneStep;\n            toneStep += toneDelta;\n            volume += volumeStep;\n            samplesLeft--;\n        }\n\n        if (snd->currInstr >= snd->instrEnd) {\n            snd->sound->state = SoundState::Done;\n            snd->sound = NULL;\n        } else {\n            snd->tonePosition = tonePosition;\n            if (samplesLeft == 0)\n                samplesLeft++; // avoid infinite loop in next iteration\n            snd->samplesLeftInCurr = samplesLeft;\n            snd->prevVolume = volume;\n            snd->prevToneDelta = toneDelta;\n            snd->prevToneStep = toneStep;\n        }\n    }\n\n    currSample += numsamples;\n\n    for (int j = 0; j < numsamples; ++j) {\n        if (dst[j] > MAXVAL)\n            dst[j] = MAXVAL;\n        else if (dst[j] < -MAXVAL)\n            dst[j] = -MAXVAL;\n    }\n\n    return res;\n}\n\n//%\nvoid enableAmp(int enabled) {\n    // this is also compiled on linux\n#ifdef LOOKUP_PIN\n    auto pin = LOOKUP_PIN(SPEAKER_AMP);\n    if (pin) {\n        if (PIN(SPEAKER_AMP) & CFG_PIN_CONFIG_ACTIVE_LO)\n            enabled = !enabled;\n        pin->setDigitalValue(enabled);\n    }\n#endif\n}\n\n//%\nvoid forceOutput(int outp) {\n    auto snd = getWSynthesizer();\n    snd->out.setOutput(outp);\n}\n\n//%\nvoid queuePlayInstructions(int when, Buffer buf) {\n    auto snd = getWSynthesizer();\n\n    registerGCObj(buf);\n\n    auto p = new WaitingSound;\n    p->state = SoundState::Waiting;\n    p->instructions = buf;\n    p->startSampleNo = snd->currSample + when * snd->sampleRate / 1000;\n\n    LOG(\"Queue %dms now=%d off=%d %p sampl:%dHz\", when, snd->currSample,\n        p->startSampleNo - snd->currSample, buf->data, snd->sampleRate);\n\n    target_disable_irq();\n    // add new sound to queue\n    p->next = snd->waiting;\n    snd->waiting = p;\n    // remove sounds that have already been fully played\n    while (p) {\n        while (p->next && p->next->state == SoundState::Done) {\n            auto todel = p->next;\n            p->next = todel->next;\n            unregisterGCObj(todel->instructions);\n            delete todel;\n        }\n        p = p->next;\n    }\n    target_enable_irq();\n\n    snd->poke();\n}\n\n//%\nvoid stopPlaying() {\n    LOG(\"stop playing!\");\n\n    auto snd = getWSynthesizer();\n\n    target_disable_irq();\n    auto p = snd->waiting;\n    snd->waiting = NULL;\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        snd->playingSounds[i].sound = NULL;\n    }\n    while (p) {\n        auto n = p->next;\n        unregisterGCObj(p->instructions);\n        delete p;\n        p = n;\n    }\n    target_enable_irq();\n}\n\nWSynthesizer::WSynthesizer() : upstream(NULL), out(*this) {\n    currSample = 0;\n    active = false;\n    sampleRate = out.dac.getSampleRate();\n    memset(&playingSounds, 0, sizeof(playingSounds));\n    waiting = NULL;\n    PXT_REGISTER_RESET(stopPlaying);\n}\n\n//% promise\nint _createSequencer() {\n    return 0;\n}\n\n//%\nString _sequencerState(int id) {\n    return NULL;\n}\n\n//%\nint _sequencerCurrentTick(int id) {\n    return 0;\n}\n\n//%\nvoid _sequencerPlaySong(int id, Buffer buf, bool loop) {\n}\n\n//%\nvoid _sequencerStop(int id) {\n}\n\n//%\nvoid _sequencerSetVolume(int id, int volume) {\n}\n\n//%\nvoid _sequencerSetVolumeForAll(int volume) {\n}\n\n//%\nvoid _sequencerSetTrackVolume(int id, int trackIndex, int volume) {\n}\n\n//%\nvoid _sequencerSetDrumTrackVolume(int id, int trackIndex, int drumIndex, int volume) {\n}\n\n//%\nvoid _sequencerDispose(int id) {\n}\n\n} // namespace music\n\nnamespace pxt {\nint redirectSamples(int16_t *dst, int numsamples, int samplerate) {\n    auto snd = music::getWSynthesizer();\n    snd->upstream = NULL; // disconnect from regular playback mechanism\n    snd->sampleRate = samplerate;\n    return snd->fillSamples(dst, numsamples);\n}\n\n} // namespace pxt\n\nnamespace jacdac {\n__attribute__((weak)) void setJackRouterOutput(int output) {}\n} // namespace jacdac\n","melody.h":"#pragma once\n\n#ifndef OUTPUT_BITS\n#define OUTPUT_BITS 10\n#endif\n\n#define SW_TRIANGLE 1\n#define SW_SAWTOOTH 2\n#define SW_SINE 3\n#define SW_TUNEDNOISE 4\n#define SW_NOISE 5\n#define SW_SQUARE_10 11\n#define SW_SQUARE_50 15\n#define SW_SQUARE_CYCLE_16 16\n#define SW_SQUARE_CYCLE_32 17\n#define SW_SQUARE_CYCLE_64 18\n\nstruct SoundInstruction {\n    uint8_t soundWave;\n    uint8_t flags;\n    uint16_t frequency;    // Hz\n    uint16_t duration;     // ms\n    int16_t startVolume;   // 0-1023\n    int16_t endVolume;     // 0-1023\n    uint16_t endFrequency; // Hz\n};\n\n#ifdef DATASTREAM_MAXIMUM_BUFFERS\n#define CODAL 1\n#endif\n\nnamespace music {\n\n#define MAX_SOUNDS 8\n\nSTATIC_ASSERT((1 << (16 - OUTPUT_BITS)) > MAX_SOUNDS);\n\nenum class SoundState : uint8_t {\n    Waiting, //\n    Playing, //\n    Done     //\n};\n\nstruct WaitingSound {\n    uint32_t startSampleNo;\n    SoundState state;\n    WaitingSound *next;\n    Buffer instructions;\n};\n\nstruct PlayingSound {\n    uint32_t startSampleNo;\n    uint32_t samplesLeftInCurr;\n    uint32_t tonePosition;\n    int32_t prevVolume;\n    uint32_t prevToneStep;\n    int32_t prevToneDelta;\n    uint32_t generatorState;\n    WaitingSound *sound;\n    SoundInstruction *currInstr, *instrEnd;\n};\n\nclass WSynthesizer\n#ifdef CODAL\n    : public DataSource\n#endif\n{\n  public:\n#ifdef CODAL\n    DataSink *upstream;\n#else\n    void *upstream;\n#endif\n    uint32_t currSample; // after 25h of playing we might get a glitch\n    int32_t sampleRate;  // eg 44100\n    PlayingSound playingSounds[MAX_SOUNDS];\n    WaitingSound *waiting;\n    bool active;\n\n    SoundOutput out;\n\n    int fillSamples(int16_t *dst, int numsamples);\n    int updateQueues();\n\n    WSynthesizer();\n    virtual ~WSynthesizer() {}\n\n    void pokeUpstream() {\n#ifdef CODAL\n        if (upstream) {\n            upstream->pullRequest();\n        }\n#endif\n    }\n\n    void poke() {\n        if (!active) {\n            active = true;\n            pokeUpstream();\n        }\n    }\n\n#ifdef CODAL\n    virtual ManagedBuffer pull() {\n        if (!upstream)\n            return ManagedBuffer();\n        ManagedBuffer data(512);\n        auto dp = (int16_t *)data.getBytes();\n        auto sz = 512 / 2;\n        int r = fillSamples(dp, sz);\n#if defined(NRF52_SERIES)\n        int mul = out.dac.getSampleRange();\n#endif\n        while (sz--) {\n#if defined(NRF52_SERIES)\n            *dp = ((-*dp + (1 << (OUTPUT_BITS - 1))) * mul) >> OUTPUT_BITS;\n#else\n            *dp += 1 << (OUTPUT_BITS - 1);\n#endif\n            dp++;\n        }\n        if (!r) {\n            active = false;\n            // return empty - nothing left to play\n            return ManagedBuffer();\n        }\n        pokeUpstream();\n        return data;\n    }\n    virtual void connect(DataSink &sink) { upstream = &sink; }\n#endif\n};\n\n} // namespace music\n","melody.ts":"enum MusicOutput {\n    AutoDetect = 0,\n    Buzzer = 1,\n    HeadPhones = 2,\n}\n\nnamespace music {\n    //% whenUsed\n    const freqs = hex`\n        1f00210023002500270029002c002e003100340037003a003e004100450049004e00520057005c00620068006e00\n        75007b0083008b0093009c00a500af00b900c400d000dc00e900f70006011501260137014a015d01720188019f01\n        b801d201ee010b022a024b026e029302ba02e40210033f037003a403dc03170455049704dd0427057505c8052006\n        7d06e0064907b8072d08a9082d09b9094d0aea0a900b400cfa0cc00d910e6f0f5a1053115b1272139a14d4152017\n        8018f519801b231dde1e`\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n\n    //% shim=music::stopPlaying\n    function stopPlaying() { }\n\n    //% shim=music::forceOutput\n    export function forceOutput(buf: MusicOutput) { }\n\n    let globalVolume: number = null\n\n    const BUFFER_SIZE: number = 12;\n\n    //% shim=music::enableAmp\n    function enableAmp(en: number) {\n        return // for sim\n    }\n\n    function initVolume() {\n        if (globalVolume === null) {\n            globalVolume = 0\n            setVolume(control.getConfigValue(DAL.CFG_SPEAKER_VOLUME, 128))\n        }\n    }\n\n    /**\n     * Set the default output volume of the sound synthesizer.\n     * @param volume the volume 0...255\n     */\n    //% blockId=synth_set_volume block=\"set volume %volume\"\n    //% parts=\"speaker\"\n    //% volume.min=0 volume.max=255\n    //% volume.defl=20\n    //% help=music/set-volume\n    //% weight=70\n    //% group=\"Volume\"\n    export function setVolume(volume: number): void {\n        globalVolume = Math.clamp(0, 255, volume | 0)\n        enableAmp(globalVolume > 0 ? 1 : 0)\n    }\n\n    /**\n     * Gets the current volume\n     */\n    //% parts=\"speaker\"\n    //% weight=70\n    export function volume(): number {\n        initVolume()\n        return globalVolume;\n    }\n\n    function playNoteCore(when: number, frequency: number, ms: number) {\n        let buf = control.createBuffer(BUFFER_SIZE)\n        addNote(buf, 0, ms, 255, 255, 3, frequency, volume(), frequency)\n        queuePlayInstructions(when, buf)\n    }\n\n    /**\n     * Play a tone through the speaker for some amount of time.\n     * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n     * @param ms tone duration in milliseconds (ms), eg: BeatFraction.Half\n     */\n    //% help=music/play-tone\n    //% blockId=mixer_play_note block=\"play tone|at %note=device_note|for %duration=device_beat\"\n    //% parts=\"headphone\" async\n    //% blockNamespace=music\n    //% weight=76 blockGap=8\n    //% group=\"Tone\"\n    //% deprecated=1\n    export function playTone(frequency: number, ms: number): void {\n        if (ms == 0)\n            ms = 86400000 // 1 day\n\n        if (ms <= 2000) {\n            playNoteCore(0, frequency, ms)\n            pause(ms)\n        } else {\n            const id = ++playToneID\n            control.runInParallel(() => {\n                let pos = control.millis()\n                while (id == playToneID && ms > 0) {\n                    let now = control.millis()\n                    let d = pos - now\n                    let t = Math.min(ms, 500)\n                    ms -= t\n                    pos += t\n                    playNoteCore(d - 1, frequency, t)\n                    if (ms == 0)\n                        pause(d + t)\n                    else\n                        pause(d + t - 100)\n                }\n            })\n        }\n    }\n\n    let playToneID = 0\n\n    /**\n     * Play a melody from the melody editor.\n     * @param melody - string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces,\n     * which will be played one at a time, ex: \"E D G F B A C5 B \"\n     * @param tempo - number in beats per minute (bpm), dictating how long each note will play for\n     */\n    //% block=\"play melody $melody at tempo $tempo|(bpm)\" blockId=playMelody\n    //% blockNamespace=music\n    //% weight=85 blockGap=8 help=music/play-melody\n    //% group=\"Melody\"\n    //% melody.shadow=\"melody_editor\"\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% deprecated=1\n    export function playMelody(melody: string, tempo: number) {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        const song = new Melody(formattedMelody);\n        song.playUntilDone();\n    }\n\n\n    /**\n     * Create a melody with the melody editor.\n     * @param melody\n     */\n    //% block=\"$melody\" blockId=melody_editor\n    //% blockNamespace=music\n    //% blockHidden = true\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Melody\" duplicateShadowOnDrag\n    //% melody.fieldEditor=\"melody\"\n    //% melody.fieldOptions.decompileLiterals=true\n    //% melody.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% melody.fieldOptions.onParentBlock=\"true\"\n    //% shim=TD_ID\n    export function melodyEditor(melody: string): string {\n        return melody;\n    }\n\n    /**\n     * Stop all sounds from playing.\n     */\n    //% help=music/stop-all-sounds\n    //% blockId=music_stop_all_sounds block=\"stop all sounds\"\n    //% weight=45\n    //% group=\"Sounds\"\n    export function stopAllSounds() {\n        Melody.stopAll();\n        stopPlaying();\n        _stopPlayables();\n        sequencer._stopAllSongs();\n    }\n\n    //% fixedInstances\n    export class Melody {\n        _text: string;\n        private _player: MelodyPlayer;\n\n        private static playingMelodies: Melody[];\n\n        static stopAll() {\n            if (Melody.playingMelodies) {\n                const ms = Melody.playingMelodies.slice(0, Melody.playingMelodies.length);\n                ms.forEach(p => p.stop());\n            }\n        }\n\n        constructor(text: string) {\n            this._text = text\n        }\n\n        get text() {\n            return this._text;\n        }\n\n        /**\n         * Stop playing a sound\n         */\n        //% blockId=mixer_stop block=\"stop sound %sound\"\n        //% help=music/melody/stop\n        //% parts=\"headphone\"\n        //% weight=92 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        stop() {\n            if (this._player) {\n                this._player.stop()\n                this._player = null\n            }\n            this.unregisterMelody();\n        }\n\n        private registerMelody() {\n            // keep track of the active players\n            if (!Melody.playingMelodies) Melody.playingMelodies = [];\n            // stop and pop melodies if too many playing\n            if (Melody.playingMelodies.length > 4) {\n                // stop last player (also pops)\n                Melody.playingMelodies[Melody.playingMelodies.length - 1].stop();\n            }\n            // put back the melody on top of the melody stack\n            Melody.playingMelodies.removeElement(this);\n            Melody.playingMelodies.push(this);\n        }\n        private unregisterMelody() {\n            // remove from list\n            if (Melody.playingMelodies) {\n                Melody.playingMelodies.removeElement(this); // remove self\n            }\n        }\n\n        private playCore(volume: number, loop: boolean) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this.registerMelody();\n            control.runInParallel(() => {\n                while (this._player == p) {\n                    p.play(volume)\n                    if (!loop) {\n                        // Unregister the melody when done playing, but\n                        // only if it hasn't been restarted. (Looping\n                        // melodies never stop on their own, they only\n                        // get unregistered via stop().)\n                        if (this._player == p) {\n                            this.unregisterMelody();\n                        }\n                        break\n                    }\n                }\n            })\n        }\n\n        /**\n         * Start playing a sound in a loop and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/loop\n        //% blockId=mixer_loop_sound block=\"loop sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=93 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        loop(volume = 255) {\n            this.playCore(volume, true)\n        }\n\n        /**\n         * Start playing a sound and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play\n        //% blockId=mixer_play_sound block=\"play sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=95 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        play(volume = 255) {\n            this.playCore(volume, false)\n        }\n\n\n        /**\n         * Play a sound and wait until the sound is done.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play-until-done\n        //% blockId=mixer_play_sound_until_done block=\"play sound %sound|until done\"\n        //% parts=\"headphone\"\n        //% weight=94 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        playUntilDone(volume = 255) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this._player.onPlayFinished = () => {\n                if (p == this._player)\n                    this.unregisterMelody();\n            }\n            this.registerMelody();\n            this._player.play(volume)\n        }\n\n        toString() {\n            return this._text;\n        }\n    }\n\n    export function addNote(sndInstr: Buffer, sndInstrPtr: number, ms: number, beg: number, end: number, soundWave: number, hz: number, volume: number, endHz: number) {\n        if (ms > 0) {\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, soundWave)\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr + 1, 0)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 2, hz)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 4, ms)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 6, (beg * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 8, (end * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 10, endHz);\n            sndInstrPtr += BUFFER_SIZE;\n        }\n        sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, 0) // terminate\n        return sndInstrPtr\n    }\n\n\n    export class MelodyPlayer {\n        melody: Melody;\n\n        onPlayFinished: () => void;\n\n        constructor(m: Melody) {\n            this.melody = m\n        }\n\n        stop() {\n            this.melody = null\n        }\n\n        protected queuePlayInstructions(timeDelta: number, buf: Buffer) {\n            queuePlayInstructions(timeDelta, buf)\n        }\n\n        play(volume: number) {\n            if (!this.melody)\n                return\n            volume = Math.clamp(0, 255, (volume * music.volume()) >> 8)\n\n            let notes = this.melody._text\n            let pos = 0;\n            let duration = 4; //Default duration (Crotchet)\n            let octave = 4; //Middle octave\n            let tempo = 120; // default tempo\n\n            let hz = 0\n            let endHz = -1\n            let ms = 0\n            let timePos = 0\n            let startTime = control.millis()\n            let now = 0\n\n            let envA = 0\n            let envD = 0\n            let envS = 255\n            let envR = 0\n            let soundWave = 1 // triangle\n            let sndInstr = control.createBuffer(5 * BUFFER_SIZE)\n            let sndInstrPtr = 0\n\n            const addForm = (formDuration: number, beg: number, end: number, msOff: number) => {\n                let freqStart = hz;\n                let freqEnd = endHz;\n\n                const envelopeWidth = ms > 0 ? ms : duration * Math.idiv(15000, tempo) + envR;\n                if (endHz != hz && envelopeWidth != 0) {\n                    const slope = (freqEnd - freqStart) / envelopeWidth;\n                    freqStart = hz + slope * msOff;\n                    freqEnd = hz + slope * (msOff + formDuration);\n                }\n                sndInstrPtr = addNote(sndInstr, sndInstrPtr, formDuration, beg, end, soundWave, freqStart, volume, freqEnd);\n            }\n\n            const scanNextWord = () => {\n                if (!this.melody)\n                    return \"\"\n\n                // eat space\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c != ' ' && c != '\\r' && c != '\\n' && c != '\\t')\n                        break;\n                    pos++;\n                }\n\n                // read note\n                let note = \"\";\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c == ' ' || c == '\\r' || c == '\\n' || c == '\\t')\n                        break;\n                    note += c;\n                    pos++;\n                }\n                return note;\n            }\n\n            enum Token {\n                Note,\n                Octave,\n                Beat,\n                Tempo,\n                Hz,\n                EndHz,\n                Ms,\n                WaveForm,\n                EnvelopeA,\n                EnvelopeD,\n                EnvelopeS,\n                EnvelopeR\n            }\n\n            let token: string = \"\";\n            let tokenKind = Token.Note;\n\n            // [ABCDEFG] (\\d+)  (:\\d+)  (-\\d+)\n            // note      octave length  tempo\n            // R (:\\d+) - rest\n            // !\\d+,\\d+ - sound at frequency with given length (Hz,ms); !\\d+ and !\\d+,:\\d+ also possible\n            // @\\d+,\\d+,\\d+,\\d+ - ADSR envelope - ms,ms,volume,ms; volume is 0-255\n            // ~\\d+ - wave form:\n            //   1 - triangle\n            //   2 - sawtooth\n            //   3 - sine\n            //   4 - pseudorandom square wave noise (tunable)\n            //   5 - white noise (ignores frequency)\n            //   11 - square 10%\n            //   12 - square 20%\n            //   ...\n            //   15 - square 50%\n            //   16 - filtered square wave, cycle length 16\n            //   17 - filtered square wave, cycle length 32\n            //   18 - filtered square wave, cycle length 64\n\n            const consumeToken = () => {\n                if (token && tokenKind != Token.Note) {\n                    const d = parseInt(token);\n                    switch (tokenKind) {\n                        case Token.Octave: octave = d; break;\n                        case Token.Beat:\n                            duration = Math.max(1, Math.min(16, d));\n                            ms = -1;\n                            break;\n                        case Token.Tempo: tempo = Math.max(1, d); break;\n                        case Token.Hz: hz = d; tokenKind = Token.Ms; break;\n                        case Token.Ms: ms = d; break;\n                        case Token.WaveForm: soundWave = Math.clamp(1, 18, d); break;\n                        case Token.EnvelopeA: envA = d; tokenKind = Token.EnvelopeD; break;\n                        case Token.EnvelopeD: envD = d; tokenKind = Token.EnvelopeS; break;\n                        case Token.EnvelopeS: envS = Math.clamp(0, 255, d); tokenKind = Token.EnvelopeR; break;\n                        case Token.EnvelopeR: envR = d; break;\n                        case Token.EndHz: endHz = d; break;\n                    }\n                    token = \"\";\n                }\n            }\n\n            while (true) {\n                let currNote = scanNextWord();\n                let prevNote: boolean = false;\n                if (!currNote) {\n                    let timeLeft = timePos - now\n                    if (timeLeft > 0)\n                        pause(timeLeft)\n                    if (this.onPlayFinished)\n                        this.onPlayFinished();\n                    return;\n                }\n\n                hz = -1;\n\n                let note: number = 0;\n                token = \"\";\n                tokenKind = Token.Note;\n\n                for (let i = 0; i < currNote.length; i++) {\n                    let noteChar = currNote.charAt(i);\n                    switch (noteChar) {\n                        case 'c': case 'C': note = 1; prevNote = true; break;\n                        case 'd': case 'D': note = 3; prevNote = true; break;\n                        case 'e': case 'E': note = 5; prevNote = true; break;\n                        case 'f': case 'F': note = 6; prevNote = true; break;\n                        case 'g': case 'G': note = 8; prevNote = true; break;\n                        case 'a': case 'A': note = 10; prevNote = true; break;\n                        case 'B': note = 12; prevNote = true; break;\n                        case 'r': case 'R': hz = 0; prevNote = false; break;\n                        case '#': note++; prevNote = false; break;\n                        case 'b': if (prevNote) note--; else { note = 12; prevNote = true; } break;\n                        case ',':\n                            consumeToken();\n                            prevNote = false;\n                            break;\n                        case '!':\n                            tokenKind = Token.Hz;\n                            prevNote = false;\n                            break;\n                        case '@':\n                            consumeToken();\n                            tokenKind = Token.EnvelopeA;\n                            prevNote = false;\n                            break;\n                        case '~':\n                            consumeToken();\n                            tokenKind = Token.WaveForm;\n                            prevNote = false;\n                            break;\n                        case ':':\n                            consumeToken();\n                            tokenKind = Token.Beat;\n                            prevNote = false;\n                            break;\n                        case '-':\n                            consumeToken();\n                            tokenKind = Token.Tempo;\n                            prevNote = false;\n                            break;\n                        case '^':\n                            consumeToken();\n                            tokenKind = Token.EndHz;\n                            break;\n                        default:\n                            if (tokenKind == Token.Note)\n                                tokenKind = Token.Octave;\n                            token += noteChar;\n                            prevNote = false;\n                            break;\n                    }\n                }\n                consumeToken();\n\n                if (note && hz < 0) {\n                    const keyNumber = note + (12 * (octave - 1));\n                    hz = freqs.getNumber(NumberFormat.UInt16LE, keyNumber * 2) || 0;\n                }\n\n                let currMs = ms\n\n                if (currMs <= 0) {\n                    const beat = Math.idiv(15000, tempo);\n                    currMs = duration * beat\n                }\n\n                if (hz < 0) {\n                    // no frequency specified, so no duration\n                } else if (hz == 0) {\n                    timePos += currMs\n                } else {\n                    if (endHz < 0) {\n                        endHz = hz;\n                    }\n\n                    sndInstrPtr = 0\n                    addForm(envA, 0, 255, 0)\n                    addForm(envD, 255, envS, envA)\n                    addForm(currMs - (envA + envD), envS, envS, envD + envA)\n                    addForm(envR, envS, 0, currMs)\n\n                    this.queuePlayInstructions(timePos - now, sndInstr.slice(0, sndInstrPtr))\n                    endHz = -1;\n                    timePos += currMs // don't add envR - it's supposed overlap next sound\n                }\n\n                let timeLeft = timePos - now\n                if (timeLeft > 200) {\n                    pause(timeLeft - 100)\n                    now = control.millis() - startTime\n                }\n            }\n        }\n    }\n\n    //% blockId=music_song_field_editor\n    //% block=\"song $song\"\n    //% song.fieldEditor=musiceditor\n    //% song.fieldOptions.decompileLiterals=true\n    //% song.fieldOptions.taggedTemplate=\"hex;assets.song\"\n    //% song.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% song.fieldOptions.decompileArgumentAsString=\"true\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% help=music/create-song\n    export function createSong(song: Buffer): Playable {\n        return new sequencer.Song(song);\n    }\n\n    export function playInstructions(when: number, instructions: Buffer) {\n        queuePlayInstructions(when, instructions);\n    }\n\n    export function lookupFrequency(note: number) {\n        return freqs.getNumber(NumberFormat.UInt16LE, note * 2) || 0\n    }\n\n    //% fixedInstance whenUsed block=\"ba ding\"\n    export const baDing = new Melody('b5:1 e6:3')\n\n    //% fixedInstance whenUsed block=\"wawawawaa\"\n    export const wawawawaa = new Melody('~15 e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8')\n\n    //% fixedInstance whenUsed block=\"jump up\"\n    export const jumpUp = new Melody('c5:1 d e f g')\n\n    //% fixedInstance whenUsed block=\"jump down\"\n    export const jumpDown = new Melody('g5:1 f e d c')\n\n    //% fixedInstance whenUsed block=\"power up\"\n    export const powerUp = new Melody('g4:1 c5 e g:2 e:1 g:3')\n\n    //% fixedInstance whenUsed block=\"power down\"\n    export const powerDown = new Melody('g5:1 d# c g4:2 b:1 c5:3')\n\n    //% fixedInstance whenUsed block=\"magic wand\"\n    export const magicWand = new Melody('F#6:1-300 G# A# B C7# D# F F# G# A# B:6')\n    //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n\n    //% fixedInstance whenUsed block=\"siren\"\n    export const siren = new Melody('a4 d5 a4 d5 a4 d5')\n\n    //% fixedInstance whenUsed block=\"pew pew\"\n    export const pewPew = new Melody('!1200,200^50')\n\n    //% fixedInstance whenUsed block=\"knock\"\n    export const knock = new Melody('~4 @0,0,255,150 !300,1 !211,1')\n\n    //% fixedInstance whenUsed block=\"footstep\"\n    export const footstep = new Melody('~4 @0,0,60,50 !200,1')\n\n    //% fixedInstance whenUsed block=\"thump\"\n    export const thump = new Melody('~4 @0,0,255,150 !100,1')\n\n    //% fixedInstance whenUsed block=\"small crash\"\n    export const smallCrash = new Melody('~4 @10,490,0,1 !800,1')\n\n    //% fixedInstance whenUsed block=\"big crash\"\n    export const bigCrash = new Melody('~4 @10,990,0,1 !400,1')\n\n    //% fixedInstance whenUsed block=\"zapped\"\n    export const zapped = new Melody('~16 @10,490,0,0 !1600,500^1')\n\n    //% fixedInstance whenUsed block=\"buzzer\"\n    export const buzzer = new Melody('~16 @10,0,255,250 !2000,300')\n\n    //% fixedInstance whenUsed block=\"sonar\"\n    export const sonar = new Melody('~16 @10,1500,0,0 !200,1 !200,1500^190')\n\n    //% fixedInstance whenUsed block=\"spooky\"\n    export const spooky = new Melody('~16 @700,1300,0,0 !100,1 ~18 !108,2000')\n\n    //% fixedInstance whenUsed block=\"beam up\"\n    export const beamUp = new Melody('~18 @10,1500,0,0 !200,1500^4000')\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    //% block=\"2\"\n    Double = 32,\n    //% block=\"4\",\n    Breve = 64,\n    //% block=\"1/3\",\n    Triplet = 128\n}\n\nnamespace music {\n\n    let beatsPerMinute: number;\n\n    /**\n    * Play a tone.\n    * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n    */\n    //% help=music/ring-tone\n    //% blockId=music_ring block=\"ring tone|at %note=device_note\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music inBasicCategory=true\n    //% weight=75 blockGap=8\n    //% group=\"Tone\"\n    export function ringTone(frequency: number) {\n        playTone(frequency, 0);\n    }\n\n    /**\n    * Rest, or play silence, for some time (in milliseconds).\n    * @param ms rest duration in milliseconds (ms), eg: BeatFraction.Half\n    */\n    //% help=music/rest\n    //% blockId=music_rest block=\"rest|for %duration=device_beat\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music\n    //% weight=74\n    //% group=\"Tone\"\n    export function rest(ms: number) {\n        playTone(0, Math.max(ms, 20));\n    }\n\n    function init() {\n        if (!beatsPerMinute) beatsPerMinute = 120;\n    }\n\n    /**\n     * Return the duration of a beat in milliseconds (the beat fraction).\n     * @param fraction the fraction of the current whole note, eg: BeatFraction.Half\n     */\n    //% help=music/beat\n    //% blockId=device_beat block=\"%fraction|beat\"\n    //% weight=9 blockGap=8\n    //% group=\"Tempo\"\n    export function beat(fraction?: BeatFraction): number {\n        init();\n        if (fraction == null) fraction = BeatFraction.Whole;\n        let beat = 60000 / beatsPerMinute;\n        switch (fraction) {\n            case BeatFraction.Half: beat /= 2; break;\n            case BeatFraction.Quarter: beat /= 4; break;\n            case BeatFraction.Eighth: beat /= 8; break;\n            case BeatFraction.Sixteenth: beat /= 16; break;\n            case BeatFraction.Double: beat *= 2; break;\n            case BeatFraction.Breve: beat *= 4; break;\n            case BeatFraction.Triplet: beat /= 3; break;\n        }\n        return beat >> 0;\n    }\n\n    /**\n     * Return the tempo in beats per minute (bpm).\n     * 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\n    //% blockId=device_tempo block=\"tempo (bpm)\"\n    //% weight=64\n    //% group=\"Tempo\"\n    export function tempo(): number {\n        init();\n        return beatsPerMinute;\n    }\n\n    /**\n     * Change the tempo up or down by some amount of beats per minute (bpm).\n     * @param bpm The change in beats per minute to the tempo, eg: 20\n     */\n    //% help=music/change-tempo-by weight=37\n    //% blockId=device_change_tempo block=\"change tempo by %value|(bpm)\"\n    //% weight=66 blockGap=8\n    //% group=\"Tempo\"\n    export function changeTempoBy(bpm: number): void {\n        init();\n        setTempo(beatsPerMinute + bpm);\n    }\n\n    /**\n     * Set the tempo a number of beats per minute (bpm).\n     * @param bpm The new tempo in beats per minute, eg: 120\n     */\n    //% help=music/set-tempo\n    //% blockId=device_set_tempo block=\"set tempo to %value|(bpm)\"\n    //% bpm.min=4 bpm.max=400\n    //% weight=65 blockGap=8\n    //% group=\"Tempo\"\n    export function setTempo(bpm: number): void {\n        init();\n        if (bpm > 0) {\n            beatsPerMinute = Math.max(1, bpm >> 0);\n        }\n    }\n}\n","ns.ts":"\n/**\n * Generation of music tones.\n */\n//% color=#E30FC0 weight=90 icon=\"\\uf025\"\n//% blockGap=8\n//% groups='[\"Songs\", \"Sounds\", \"Tone\",  \"Volume\", \"Tempo\"]'\nnamespace music {\n}","piano.ts":"namespace music {\n    /**\n     * Get the frequency of a note.\n     * @param name the note name, eg: Note.C\n     */\n    //% weight=1 help=music/note-frequency\n    //% blockId=device_note block=\"%note\"\n    //% shim=TD_ID\n    //% color=\"#FFFFFF\" colorSecondary=\"#FFFFFF\" colorTertiary=\"#D83B01\"\n    //% note.fieldEditor=\"note\" note.defl=\"262\"\n    //% note.fieldOptions.decompileLiterals=true\n    //% useEnumVal=1\n    //% weight=10 blockGap=8\n    //% group=\"Tone\"\n    export function noteFrequency(name: Note): number {\n        return name;\n    }\n}","playable.ts":"namespace music {\n    export enum PlaybackMode {\n        //% block=\"until done\"\n        UntilDone,\n        //% block=\"in background\"\n        InBackground,\n        //% block=\"looping in background\"\n        LoopingInBackground\n    }\n\n    let stateStack: PlayableState[];\n\n    class PlayableState {\n        looping: Playable[];\n        constructor() {\n            this.looping = [];\n        }\n\n        stopLooping() {\n            for (const p of this.looping) {\n                p.stopped = true;\n            }\n            this.looping = [];\n        }\n    }\n\n    function state() {\n        _init();\n        return stateStack[stateStack.length - 1];\n    }\n\n    function _init() {\n        if (stateStack) return;\n        stateStack = [new PlayableState()];\n\n        game.addScenePushHandler(() => {\n            stateStack.push(new PlayableState());\n        });\n\n        game.addScenePopHandler(() => {\n            stateStack.pop();\n            if (stateStack.length === 0) stateStack.push(new PlayableState());\n        });\n    }\n\n    export class Playable {\n        stopped: boolean;\n        constructor() {\n\n        }\n\n        play(playbackMode: PlaybackMode) {\n            // subclass\n        }\n\n        loop() {\n            state().looping.push(this);\n            this.stopped = false;\n\n            control.runInParallel(() => {\n                while (!this.stopped) {\n                    this.play(PlaybackMode.UntilDone);\n                }\n            });\n        }\n    }\n\n    export class MelodyPlayable extends Playable {\n        constructor(public melody: Melody) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                this.melody.play(music.volume());\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                this.melody.playUntilDone(music.volume());\n            }\n            else {\n                this.melody.loop(music.volume());\n            }\n        }\n    }\n\n    export class TonePlayable extends Playable {\n        constructor(public pitch: number, public duration: number) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                control.runInParallel(() => music.playTone(this.pitch, this.duration));\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                music.playTone(this.pitch, this.duration);\n                if (this.duration > 2000) {\n                    pause(this.duration);\n                }\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n    /**\n     * Play a song, melody, or other sound. The music plays until finished or can play as a\n     * background task.\n     * @param toPlay the song or melody to play\n     * @param playbackMode play the song or melody until it's finished or as background task\n     */\n    //% blockId=\"music_playable_play\"\n    //% block=\"play $toPlay $playbackMode\"\n    //% toPlay.shadow=music_melody_playable\n    //% group=\"Sounds\"\n    //% help=\"music/play\"\n    export function play(toPlay: Playable, playbackMode: PlaybackMode) {\n        toPlay.play(playbackMode);\n    }\n\n    /**\n     * Create a Playable object for a melody.\n     * @param melody the melody to make playable\n     */\n    //% blockId=\"music_melody_playable\"\n    //% block=\"sound $melody\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    //% blockHidden\n    //% help=music/melody-playable\n    export function melodyPlayable(melody: Melody): Playable {\n        return new MelodyPlayable(melody);\n    }\n\n    /**\n     * Create a Playable object for a melody string containg notes.\n     * @param melody the melody string to make playable\n     */\n    //% blockId=\"music_string_playable\"\n    //% block=\"melody $melody at tempo $tempo|(bpm)\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% melody.shadow=melody_editor\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% help=music/string-playable\n    export function stringPlayable(melody: string, tempo: number): Playable {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        return new MelodyPlayable(new Melody(formattedMelody));\n    }\n\n    /**\n     * Create a Playable object for a single tone and its duration.\n     * @param note the note or tone frequency to play\n     * @param duration the duration of the tone in milliseconds (ms)\n     */\n    //% blockId=\"music_tone_playable\"\n    //% block=\"tone $note for $duration\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Tone\"\n    //% duplicateShadowOnDrag\n    //% note.shadow=device_note\n    //% duration.shadow=device_beat\n    //% parts=\"headphone\"\n    //% help=music/tone-playable\n    export function tonePlayable(note: number, duration: number): Playable {\n        return new TonePlayable(note, duration);\n    }\n\n    export function _stopPlayables() {\n        state().stopLooping();\n    }\n}","pxt.json":"{\n    \"name\": \"mixer---samd\",\n    \"description\": \"The music library with a mixer\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"SoundOutput.h\",\n        \"sound.cpp\",\n        \"melody.h\",\n        \"melody.cpp\",\n        \"melody.ts\",\n        \"piano.ts\",\n        \"legacy.ts\",\n        \"ns.ts\",\n        \"targetoverrides.ts\",\n        \"music.ts\",\n        \"soundEffect.ts\",\n        \"instrument.ts\",\n        \"sequencer.ts\",\n        \"playable.ts\",\n        \"pxtparts.json\",\n        \"headphone.svg\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","pxtparts.json":"{\n    \"headphone\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"image\": \"headphone.svg\",\n            \"width\": 142,\n            \"height\": 180,\n            \"pinDistance\": 20,\n            \"pinLocations\": [\n                {\n                    \"x\": 17,\n                    \"y\": 11\n                },\n                {\n                    \"x\": 55,\n                    \"y\": 50\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"A0\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","sequencer.ts":"namespace music.sequencer {\n    const SEQUENCER_STOP_MESSAGE = 3243;\n    const SEQUENCER_TICK_MESSAGE = 3244;\n    const SEQUENCER_STATE_CHANGE_MESSAGE = 3245;\n    const SEQUENCER_LOOPED_MESSAGE = 3246;\n\n    export class Sequencer {\n        currentTick: number;\n        isPlaying: boolean;\n        isLooping: boolean;\n        isRunning: boolean;\n\n        constructor(public song: Song) {\n            this.currentTick = 0;\n            this.isPlaying = false;\n            this.isLooping = false;\n        }\n\n        start(loop: boolean) {\n            this.currentTick = 0;\n            this.isLooping = loop;\n            this.isPlaying = true;\n\n            if (this.isRunning) return;\n            this.isRunning = true;\n\n            control.runInParallel(() => {\n                while (this.isPlaying) {\n                    this.scheduleCurrentTick();\n\n                    this.currentTick ++;\n\n                    if (this.currentTick >= this.song.beatsPerMeasure * this.song.measures * this.song.ticksPerBeat) {\n                        if (this.isLooping) this.currentTick = 0;\n                        else this.isPlaying = false;\n                    }\n\n                    pause(this.tickToMs(1))\n                }\n                this.isRunning = false;\n            })\n        }\n\n        stop() {\n            this.isPlaying = false;\n        }\n\n        tickToMs(ticks: number) {\n            return ((60000 / this.song.beatsPerMinute) / this.song.ticksPerBeat) * ticks;\n        }\n\n        protected scheduleCurrentTick() {\n            for (const track of this.song.tracks) {\n                if (track.currentNoteEvent.startTick === this.currentTick) {\n                    if (track.isMelodicTrack) {\n                        this.scheduleMelodicTrack(track as MelodicTrack);\n                    }\n                    else {\n                        this.scheduleDrumTrack(track as DrumTrack);\n                    }\n\n                    track.advanceNoteEvent();\n                }\n            }\n        }\n\n        protected scheduleMelodicTrack(track: MelodicTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderInstrument(\n                        track.instrument,\n                        lookupFrequency(track.currentNoteEvent.getNote(i, track.instrument.octave)),\n                        this.tickToMs(track.currentNoteEvent.endTick - track.currentNoteEvent.startTick),\n                        music.volume()\n                    )\n                );\n            }\n        }\n\n        protected scheduleDrumTrack(track: DrumTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderDrumInstrument(\n                        track.drums[track.currentNoteEvent.getNote(i, undefined)],\n                        music.volume()\n                    )\n                );\n            }\n        }\n    }\n\n    let activeSimSequencers: _SimulatorSequencer[];\n    export function _stopAllSimSequencers() {\n        if (activeSimSequencers) {\n            for (const seq of activeSimSequencers) {\n                seq.stop();\n                seq.dispose();\n            }\n            activeSimSequencers = [];\n        }\n    }\n\n    // Simulator only! Does nothing on hardware\n    export class _SimulatorSequencer {\n        protected id: number;\n\n        constructor() {\n            if (!activeSimSequencers) activeSimSequencers = [];\n            activeSimSequencers.push(this);\n            this.id = _createSequencer();\n            this.setVolume(music.volume());\n        }\n\n        play(song: Buffer, loop: boolean) {\n            this.setVolume(music.volume());\n            _sequencerPlaySong(this.id, song, loop)\n        }\n\n        stop() {\n            _sequencerStop(this.id);\n        }\n\n        setVolume(volume: number) {\n            _sequencerSetVolume(this.id, volume);\n        }\n\n        setTrackVolume(trackIndex: number, volume: number) {\n            _sequencerSetTrackVolume(this.id, trackIndex, volume)\n        }\n\n        setDrumTrackVolume(trackIndex: number, drumIndex: number, volume: number) {\n            _sequencerSetDrumTrackVolume(this.id, drumIndex, trackIndex, volume)\n        }\n\n        state() {\n            return _sequencerState(this.id) || \"stop\";\n        }\n\n        currentTick() {\n            return _sequencerCurrentTick(this.id);\n        }\n\n        dispose() {\n            _sequencerDispose(this.id);\n        }\n\n        onTick(handler: (tick: number) => void) {\n            control.onEvent(SEQUENCER_TICK_MESSAGE, this.id, () => {\n                handler(this.currentTick());\n            });\n        }\n\n        onStateChange(handler: (state: string) => void) {\n            control.onEvent(SEQUENCER_STATE_CHANGE_MESSAGE, this.id, () => {\n                handler(this.state());\n            });\n        }\n\n        onStop(handler: () => void) {\n            control.onEvent(SEQUENCER_STOP_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n\n        onLooped(handler: () => void) {\n            control.onEvent(SEQUENCER_LOOPED_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n    }\n\n    //% promise\n    //% shim=music::_createSequencer\n    declare function _createSequencer(): number\n\n    //% shim=music::_sequencerState\n    declare function _sequencerState(id: number): string;\n\n    //% shim=music::_sequencerCurrentTick\n    declare function _sequencerCurrentTick(id: number): number;\n\n    //% shim=music::_sequencerPlaySong\n    declare function _sequencerPlaySong(id: number, song: Buffer, loop: boolean): void;\n\n    //% shim=music::_sequencerStop\n    declare function _sequencerStop(id: number): void;\n\n    //% shim=music::_sequencerSetVolume\n    declare function _sequencerSetVolume(id: number, volume: number): void;\n\n    //% shim=music::_sequencerSetVolumeForAll\n    declare function _sequencerSetVolumeForAll(volume: number): void;\n\n    //% shim=music::_sequencerSetTrackVolume\n    declare function _sequencerSetTrackVolume(id: number, trackIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerSetDrumTrackVolume\n    declare function _sequencerSetDrumTrackVolume(id: number, trackIndex: number, drumIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerDispose\n    declare function _sequencerDispose(id: number): void;\n}","sound.cpp":"// to be overridden\n","soundEffect.ts":"enum WaveShape {\n    //% block=\"sine\"\n    Sine = 0,\n    //% block=\"sawtooth\"\n    Sawtooth = 1,\n    //% block=\"triangle\"\n    Triangle = 2,\n    //% block=\"square\"\n    Square = 3,\n    //% block=\"noise\"\n    Noise = 4\n}\n\nenum InterpolationCurve {\n    //% block=\"linear\"\n    Linear,\n    //% block=\"curve\"\n    Curve,\n    //% block=\"logarithmic\"\n    Logarithmic\n}\n\nenum SoundExpressionEffect {\n    //% block=\"none\"\n    None = 0,\n    //% block=\"vibrato\"\n    Vibrato = 1,\n    //% block=\"tremolo\"\n    Tremolo = 2,\n    //% block=\"warble\"\n    Warble = 3\n}\n\nenum SoundExpressionPlayMode {\n    //% block=\"until done\"\n    UntilDone,\n    //% block=\"in background\"\n    InBackground\n}\n\nnamespace music {\n    export class SoundEffect extends Playable {\n        waveShape: WaveShape;\n        startFrequency: number;\n        endFrequency: number;\n        startVolume: number;\n        endVolume: number;\n        duration: number;\n        effect: SoundExpressionEffect;\n        interpolation: InterpolationCurve;\n\n        constructor() {\n            super();\n            this.waveShape = WaveShape.Sine;\n            this.startFrequency = 5000;\n            this.endFrequency = 1;\n            this.startVolume = 255;\n            this.endVolume = 0;\n            this.duration = 1000;\n            this.effect = SoundExpressionEffect.None;\n            this.interpolation = InterpolationCurve.Linear;\n        }\n\n        toBuffer(volume?: number) {\n            if (volume === undefined) volume = music.volume();\n\n            return soundToInstructionBuffer(\n                this.waveShape,\n                this.startFrequency,\n                this.endFrequency,\n                this.startVolume,\n                this.endVolume,\n                this.duration,\n                this.effect,\n                this.interpolation,\n                20,\n                1,\n                volume\n            );\n        }\n\n        play(playbackMode: PlaybackMode) {\n            const toPlay = this.toBuffer(music.volume());\n            if (playbackMode === PlaybackMode.InBackground) {\n                queuePlayInstructions(0, toPlay);\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                queuePlayInstructions(0, toPlay);\n                pause(this.duration)\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n\n    /**\n     * Play a SoundEffect.\n     * @param sound the SoundEffect to play\n     * @param mode the play mode, play until done or in the background\n     */\n    //% blockId=soundExpression_playSoundEffect\n    //% block=\"play sound $sound $mode\"\n    //% weight=30\n    //% help=music/play-sound-effect\n    //% blockGap=8\n    //% group=\"Sounds\"\n    //% deprecated=1\n    export function playSoundEffect(sound: SoundEffect, mode: SoundExpressionPlayMode) {\n        const toPlay = sound.toBuffer(music.volume());\n\n        queuePlayInstructions(0, toPlay);\n        if (mode === SoundExpressionPlayMode.UntilDone) {\n            pause(sound.duration);\n        }\n    }\n\n    /**\n     * Create a sound expression from a set of sound effect parameters.\n     * @param waveShape waveform of the sound effect\n     * @param startFrequency starting frequency for the sound effect waveform\n     * @param endFrequency ending frequency for the sound effect waveform\n     * @param startVolume starting volume of the sound, or starting amplitude\n     * @param endVolume ending volume of the sound, or ending amplitude\n     * @param duration the amount of time in milliseconds (ms) that sound will play for\n     * @param effect the effect to apply to the waveform or volume\n     * @param interpolation interpolation method for frequency scaling\n     */\n    //% blockId=soundExpression_createSoundEffect\n    //% help=music/create-sound-effect\n    //% block=\"$waveShape|| start frequency $startFrequency end frequency $endFrequency duration $duration start volume $startVolume end volume $endVolume effect $effect interpolation $interpolation\"\n    //% waveShape.defl=WaveShape.Sine\n    //% waveShape.fieldEditor=soundeffect\n    //% waveShape.fieldOptions.useMixerSynthesizer=true\n    //% startFrequency.defl=5000\n    //% startFrequency.min=0\n    //% startFrequency.max=5000\n    //% endFrequency.defl=0\n    //% endFrequency.min=0\n    //% endFrequency.max=5000\n    //% startVolume.defl=255\n    //% startVolume.min=0\n    //% startVolume.max=255\n    //% endVolume.defl=0\n    //% endVolume.min=0\n    //% endVolume.max=255\n    //% duration.defl=500\n    //% duration.min=1\n    //% duration.max=9999\n    //% effect.defl=SoundExpressionEffect.None\n    //% interpolation.defl=InterpolationCurve.Linear\n    //% compileHiddenArguments=true\n    //% inlineInputMode=\"variable\"\n    //% inlineInputModeLimit=3\n    //% expandableArgumentBreaks=\"3,5\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=20\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    export function createSoundEffect(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve): SoundEffect {\n        const result = new SoundEffect();\n\n        result.waveShape = waveShape;\n        result.startFrequency = startFrequency;\n        result.endFrequency = endFrequency;\n        result.startVolume = startVolume;\n        result.endVolume = endVolume;\n        result.duration = duration;\n        result.effect = effect;\n        result.interpolation = interpolation;\n\n        return result;\n    }\n\n    interface Step {\n        frequency: number;\n        volume: number;\n    }\n\n     export function soundToInstructionBuffer(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve, fxSteps: number, fxRange: number, globalVolume: number) {\n        const steps: Step[] = [];\n\n        // Optimize the simple case\n        if (interpolation === InterpolationCurve.Linear && effect === SoundExpressionEffect.None) {\n            steps.push({\n                frequency: startFrequency,\n                volume: (startVolume / 255) * globalVolume,\n            })\n            steps.push({\n                frequency: endFrequency,\n                volume: (endVolume / 255) * globalVolume,\n            })\n        }\n        else {\n\n            fxSteps = Math.min(fxSteps, Math.floor(duration / 5))\n\n            const getVolumeAt = (t: number) => ((startVolume + t * (endVolume - startVolume) / duration) / 255) * globalVolume;\n            let getFrequencyAt: (t: number) => number;\n\n            switch (interpolation) {\n                case InterpolationCurve.Linear:\n                    getFrequencyAt = t => startFrequency + t * (endFrequency - startFrequency) / duration;\n                    break;\n                case InterpolationCurve.Curve:\n                    getFrequencyAt = t => startFrequency + (endFrequency - startFrequency) * Math.sin(t / duration * (Math.PI / 2));\n                    break;\n                case InterpolationCurve.Logarithmic:\n                    getFrequencyAt = t => startFrequency + (Math.log(1 + 9 * (t / duration)) / Math.log(10)) * (endFrequency - startFrequency)\n                    break;\n            }\n\n            const timeSlice = duration / fxSteps;\n\n            for (let i = 0; i < fxSteps; i++) {\n                const newStep = {\n                    frequency: getFrequencyAt(i * timeSlice),\n                    volume: getVolumeAt(i * timeSlice)\n                };\n\n                if (effect === SoundExpressionEffect.Tremolo) {\n                    if (i % 2 === 0) {\n                        newStep.volume = Math.max(newStep.volume - fxRange * 500, 0)\n                    }\n                    else {\n                        newStep.volume = Math.min(newStep.volume + fxRange * 500, 1023)\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Vibrato) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 100, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 100\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Warble) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 1000, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 1000\n                    }\n                }\n\n                steps.push(newStep)\n            }\n        }\n\n        const out = control.createBuffer(12 * (steps.length - 1));\n        const stepDuration = Math.floor(duration / (steps.length - 1))\n\n        for (let i = 0; i < steps.length - 1; i++) {\n            const offset = i * 12;\n            out.setNumber(NumberFormat.UInt8LE, offset, waveToValue(waveShape));\n            out.setNumber(NumberFormat.UInt16LE, offset + 2, steps[i].frequency);\n            out.setNumber(NumberFormat.UInt16LE, offset + 4, stepDuration);\n            out.setNumber(NumberFormat.UInt16LE, offset + 6, steps[i].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 8, steps[i + 1].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 10, steps[i + 1].frequency);\n        }\n\n        return out;\n    }\n\n    function waveToValue(wave: WaveShape) {\n        switch (wave) {\n            case WaveShape.Square: return 15;\n            case WaveShape.Sine: return 3;\n            case WaveShape.Triangle: return 1;\n            case WaveShape.Noise: return 18;\n            case WaveShape.Sawtooth: return 2;\n        }\n    }\n\n\n    /**\n     * Generate a random similar sound effect to the given one.\n     *\n     * @param sound the sound effect\n     */\n    //% blockId=soundExpression_generateSimilarSound\n    //% block=\"randomize $sound\"\n    //% sound.shadow=soundExpression_createSoundEffect\n    //% weight=0 help=music/randomize-sound\n    //% blockGap=8\n    //% group=\"Sounds\"\n    export function randomizeSound(sound: SoundEffect) {\n        const res = new SoundEffect();\n        res.waveShape = sound.waveShape;\n        res.startFrequency = sound.startFrequency;\n        res.endFrequency = sound.endFrequency;\n        res.startVolume = sound.startVolume;\n        res.endVolume = sound.endVolume;\n        res.duration = sound.duration;\n        res.effect = sound.effect;\n        res.interpolation = randomInterpolation();\n\n        res.duration = Math.clamp(\n            Math.min(100, res.duration),\n            Math.max(2000, res.duration),\n            res.duration + (Math.random() - 0.5) * res.duration,\n        );\n\n        if (res.waveShape === WaveShape.Noise) {\n            // The primary waveforms don't produce sounds that are similar to noise,\n            // but adding an effect sorta does\n            if (Math.percentChance(20)) {\n                res.waveShape = randomWave();\n                res.effect = randomEffect();\n            }\n        }\n        else {\n            res.waveShape = randomWave();\n\n            // Adding an effect can drastically alter the sound, so keep it\n            // at a low percent chance unless there already is one\n            if (res.effect !== SoundExpressionEffect.None || Math.percentChance(10)) {\n                res.effect = randomEffect();\n            }\n        }\n\n        // Instead of randomly changing the frequency, change the slope and choose\n        // a new start frequency. This keeps a similar profile to the sound\n        const oldFrequencyDifference = res.endFrequency - res.startFrequency;\n        let newFrequencyDifference = oldFrequencyDifference + (oldFrequencyDifference * 2) * (Math.random() - 0.5);\n\n        if (Math.sign(oldFrequencyDifference) !== Math.sign(newFrequencyDifference)) {\n            newFrequencyDifference *= -1;\n        }\n\n        newFrequencyDifference = Math.clamp(-5000, 5000, newFrequencyDifference);\n\n        res.startFrequency = Math.clamp(\n            Math.max(-newFrequencyDifference, 1),\n            Math.clamp(1, 5000, 5000 - newFrequencyDifference),\n            Math.random() * 5000,\n        );\n\n        res.endFrequency = Math.clamp(1, 5000, res.startFrequency + newFrequencyDifference);\n\n        // Same strategy for volume\n        const oldVolumeDifference = res.endVolume - res.startVolume;\n        let newVolumeDifference = oldVolumeDifference + oldVolumeDifference * (Math.random() - 0.5);\n\n        newVolumeDifference = Math.clamp(-255, 255, newVolumeDifference);\n\n        if (Math.sign(oldVolumeDifference) !== Math.sign(newVolumeDifference)) {\n            newVolumeDifference *= -1;\n        }\n\n        res.startVolume = Math.clamp(\n            Math.max(-newVolumeDifference, 0),\n            Math.clamp(0, 255, 255 - newVolumeDifference),\n            Math.random() * 255,\n        );\n\n        res.endVolume = Math.clamp(0, 255, res.startVolume + newVolumeDifference);\n\n        return res;\n    }\n\n    function randomWave() {\n        switch (Math.randomRange(0, 3)) {\n            case 1: return WaveShape.Sawtooth;\n            case 2: return WaveShape.Square;\n            case 3: return WaveShape.Triangle;\n            case 0:\n            default:\n                return WaveShape.Sine;\n        }\n    }\n\n    function randomEffect() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return SoundExpressionEffect.Warble;\n            case 2: return  SoundExpressionEffect.Tremolo;\n            case 0:\n            default:\n                return SoundExpressionEffect.Vibrato;\n        }\n    }\n\n    function randomInterpolation() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return InterpolationCurve.Linear;\n            case 2: return  InterpolationCurve.Curve;\n            case 0:\n            default:\n                return InterpolationCurve.Logarithmic;\n        }\n    }\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n}","targetoverrides.ts":"\n","test.ts":"for(let i = 1000; i > 0; i -= 50)\n    music.playTone(440, i)\n\nfor(let i = 0; i < 1000; i += 20)\n    music.playTone(440, i)\n"},"mixer---stm32":{"SoundOutput.h":"#include \"ZPWM.h\"\n#include \"Synthesizer.h\"\n#include \"Mixer.h\"\n\nnamespace jacdac {\nvoid setJackRouterOutput(int output);\n}\n\nclass SoundOutput {\n  public:\n    ZPWM dac;\n\n    SoundOutput(DataSource &data) : dac(*LOOKUP_PIN(JACK_SND), data) {\n        jacdac::setJackRouterOutput(-1);\n    }\n\n    void setOutput(int output) { jacdac::setJackRouterOutput(output); }\n};\n","headphone.svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"142\" height=\"180\" viewBox=\"0 0 142 180\"><rect ry=\".3\" rx=\"1\" y=\"58.615\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><rect ry=\".3\" rx=\"1\" y=\"32.043\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><path d=\"M.346 7.296c-.394.39-.31 4.797-.18 4.898l13.404 10.18c.117.12.337 4.76.73 4.368l5.506-5.56.01.01 6.51-6.444c.39-.392-4.25-.614-4.366-.73L11.777.612c-.1-.132-4.51-.215-4.898.18L4.087 3.636l-.01-.01-3.73 3.67z\" fill=\"#b3b3b3\"/><rect ry=\"6.85\" rx=\"4.571\" y=\"84.758\" x=\"-20.128\" height=\"75.571\" width=\"39.643\" transform=\"rotate(-45)\"/><rect ry=\".374\" rx=\"1.038\" y=\"29.442\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"55.939\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"82.392\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\"2.317\" rx=\"2.183\" y=\"158.876\" x=\"-9.774\" height=\"25.568\" width=\"18.935\" transform=\"rotate(-45)\"/><path d=\"M128.588 128.82s14.97 11.165 7.547 26.35c-8.426 17.24-25.57 20.653-25.57 20.653\" fill=\"none\" stroke=\"#000\" stroke-width=\"6.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>","instrument.ts":"namespace music.sequencer {\n    const BUFFER_SIZE = 12;\n\n    let currentSequencer: sequencer.Sequencer;\n\n    /**\n     * Byte encoding format for songs\n     * FIXME: should this all be word aligned?\n     *\n     * song(7 + length of all tracks bytes)\n     *     0 version\n     *     1 beats per minute\n     *     3 beats per measure\n     *     4 ticks per beat\n     *     5 measures\n     *     6 number of tracks\n     *     ...tracks\n     *\n     * track(6 + instrument length + note length bytes)\n     *     0 id\n     *     1 flags\n     *     2 instruments byte length\n     *     4...instrument\n     *     notes byte length\n     *     ...note events\n     *\n     * instrument(28 bytes)\n     *     0 waveform\n     *     1 amp attack\n     *     3 amp decay\n     *     5 amp sustain\n     *     7 amp release\n     *     9 amp amp\n     *     11 pitch attack\n     *     13 pitch decay\n     *     15 pitch sustain\n     *     17 pitch release\n     *     19 pitch amp\n     *     21 amp lfo freq\n     *     22 amp lfo amp\n     *     24 pitch lfo freq\n     *     25 pitch lfo amp\n     *     27 octave\n     *\n     * drum(5 + 7 * steps bytes)\n     *     0 steps\n     *     1 start freq\n     *     3 start amp\n     *     5...steps\n     *\n     * drum step(7 bytes)\n     *     0 waveform\n     *     1 freq\n     *     3 volume\n     *     5 duration\n     *\n     * note event(5 + 1 * polyphony bytes)\n     *     0 start tick\n     *     2 end tick\n     *     4 polyphony\n     *     5...notes(1 byte each)\n     *\n     * note (1 byte)\n     *     lower six bits = note - (instrumentOctave - 2) * 12\n     *     upper two bits are the enharmonic spelling:\n     *          0 = normal\n     *          1 = flat\n     *          2 = sharp\n     */\n\n    export class Song extends Playable {\n        tracks: Track[];\n\n        constructor(public buf: Buffer) {\n            super();\n            this.tracks = [];\n\n            let currentOffset = 7;\n            for (let i = 0; i < this.numberOfTracks; i++) {\n                let track: Track = new MelodicTrack(this.buf, currentOffset);\n\n                if (!track.isMelodicTrack) {\n                    track = new DrumTrack(this.buf, currentOffset)\n                }\n\n                this.tracks.push(track);\n                currentOffset += track.byteLength;\n            }\n        }\n\n        get version(): number {\n            return this.buf[0];\n        }\n\n        set version(value: number) {\n            this.buf[0] = value;\n        }\n\n        get beatsPerMinute(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, 1);\n        }\n\n        set beatsPerMinute(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, 1, value);\n        }\n\n        get beatsPerMeasure(): number {\n            return this.buf[3];\n        }\n\n        set beatsPerMeasure(value: number) {\n            this.buf[3] = value;\n        }\n\n        get ticksPerBeat(): number {\n            return this.buf[4];\n        }\n\n        set ticksPerBeat(value: number) {\n            this.buf[4] = value;\n        }\n\n        get measures(): number {\n            return this.buf[5];\n        }\n\n        set measures(value: number) {\n            this.buf[5] = value;\n        }\n\n        get numberOfTracks(): number {\n            return this.buf[6];\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (control.deviceDalVersion() === \"sim\") {\n                const seq = new _SimulatorSequencer();\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    seq.play(this.buf, false);\n\n                    pauseUntil(() => seq.state() === \"stop\");\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    seq.play(this.buf, false);\n                }\n                else {\n                    seq.play(this.buf, true);\n                }\n            }\n            else {\n                if (currentSequencer) currentSequencer.stop();\n                currentSequencer = new sequencer.Sequencer(this);\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    let seq = currentSequencer;\n                    currentSequencer.start(false);\n                    pauseUntil(() => !seq.isRunning);\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    currentSequencer.start(false);\n                }\n                else {\n                    currentSequencer.start(true);\n                }\n            }\n        }\n    }\n\n    export class Envelope {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(10);\n            this.offset = this.offset || 0;\n        }\n\n        // The time in ms for the envelope to reach its maximum value\n        get attack(): number {\n            return this.getValue(0);\n        }\n\n        set attack(value: number) {\n            this.setValue(0, value);\n        }\n\n        // The time in ms for the envelope to reach its sustain value after reaching its maximum value\n        get decay(): number {\n            return this.getValue(2);\n        }\n\n        set decay(value: number) {\n            this.setValue(2, value);\n        }\n\n        // The value (0-1024) to hold at during the sustain stage\n        get sustain(): number {\n            return this.getValue(4);\n        }\n\n        set sustain(value: number) {\n            this.setValue(4, value);\n        }\n\n        // The time in ms for the envelope to reach 0 after the gate length ends\n        get release(): number {\n            return this.getValue(6);\n        }\n\n        set release(value: number) {\n            this.setValue(6, value);\n        }\n\n        // The maximum value that this envelope will reach\n        get amplitude(): number {\n            return this.getValue(8);\n        }\n\n        set amplitude(value: number) {\n            this.setValue(8, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class LFO {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(3);\n            this.offset = this.offset || 0;\n        }\n\n        get frequency(): number {\n            return this.buf[this.offset];\n        }\n\n        set frequency(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get amplitude(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + 1);\n        }\n\n        set amplitude(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + 1, value);\n        }\n    }\n\n    export class NoteEvent {\n        constructor(public buf: Buffer, public offset: number) {\n\n        }\n\n        get startTick(): number {\n            return this.getValue(0);\n        }\n\n        set startTick(value: number) {\n            this.setValue(0, value);\n        }\n\n        get endTick(): number {\n            return this.getValue(2);\n        }\n\n        set endTick(value: number) {\n            this.setValue(2, value);\n        }\n\n        get polyphony(): number {\n            return this.buf[this.offset + 4];\n        }\n\n        set polyphony(value: number) {\n            this.buf[this.offset + 4] = value;\n        }\n\n        get byteLength() {\n            return this.polyphony + 5;\n        }\n\n        getNote(offset: number, octave?: number) {\n            const value = this.buf[this.offset + offset + 5] & 0x3f;\n            if (octave !== undefined) {\n                return value + (octave - 2) * 12\n            }\n            return value\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class Track {\n        currentNoteEvent: NoteEvent;\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.currentNoteEvent = new NoteEvent(this.buf, this.noteEventStart + 2);\n        }\n\n        get isMelodicTrack(): boolean {\n            return this.flags === 0;\n        }\n\n        get id(): number {\n            return this.buf[this.offset];\n        }\n\n        set id(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get flags(): number {\n            return this.buf[this.offset + 1];\n        }\n\n        set flags(value: number) {\n            this.buf[this.offset + 1] = value;\n        }\n\n        get instrumentByteLength(): number {\n            return this.getValue(this.offset + 2);\n        }\n\n        set instrumentByteLength(value: number) {\n            this.setValue(this.offset + 2, value);\n        }\n\n        get noteEventStart(): number {\n            return this.offset + this.instrumentByteLength + 4;\n        }\n\n        get noteEventByteLength(): number {\n            return this.getValue(this.noteEventStart);\n        }\n\n        set noteEventByteLength(value: number) {\n            this.setValue(this.noteEventStart, value);\n        }\n\n        get byteLength() {\n            return this.noteEventByteLength + this.instrumentByteLength + 6;\n        }\n\n        advanceNoteEvent() {\n            this.currentNoteEvent.offset += this.currentNoteEvent.byteLength;\n\n            if (this.currentNoteEvent.offset >= this.offset + this.byteLength) {\n                this.currentNoteEvent.offset = this.noteEventStart + 2;\n            }\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, offset, value);\n        }\n    }\n\n    export class MelodicTrack extends Track {\n        instrument: Instrument;\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.instrument = new Instrument(this.buf, this.offset + 4);\n        }\n    }\n\n    export class DrumTrack extends Track {\n        drums: DrumInstrument[];\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.drums = [];\n\n            let currentOffset = 0;\n            while (currentOffset < this.instrumentByteLength) {\n                this.drums.push(new DrumInstrument(this.buf, this.offset + 4 + currentOffset));\n                currentOffset += this.drums[this.drums.length - 1].byteLength;\n            }\n        }\n    }\n\n    export class Instrument {\n        ampEnvelope: Envelope;\n        pitchEnvelope: Envelope;\n        ampLFO: LFO;\n        pitchLFO: LFO;\n\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(27);\n            this.offset = this.offset || 0;\n            this.ampEnvelope = new Envelope(this.buf, this.offset + 1);\n            this.pitchEnvelope = new Envelope(this.buf, this.offset + 11);\n            this.ampLFO = new LFO(this.buf, this.offset + 21);\n            this.pitchLFO = new LFO(this.buf, this.offset + 24)\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get octave(): number {\n            return this.buf[this.offset + 27]\n        }\n\n        set octave(value: number) {\n            this.buf[this.offset + 27] = value;\n        }\n    }\n\n    export class DrumInstrument {\n        steps: DrumStep[];\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.steps = [];\n\n            for (let i = 0; i < this.numSteps; i++) {\n                this.steps.push(new DrumStep(this.buf, this.offset + 5 + i * 7))\n            }\n        }\n\n        get byteLength(): number {\n            return 5 + this.numSteps * 7;\n        }\n\n        get numSteps(): number {\n            return this.buf[this.offset];\n        }\n\n        set numSteps(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get startFrequency(): number {\n            return this.getValue(1);\n        }\n\n        set startFrequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get startVolume(): number {\n            return this.getValue(3);\n        }\n\n        set startVolume(value: number) {\n            this.setValue(3, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class DrumStep {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(7);\n            this.offset = this.offset || 0;\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get frequency(): number {\n            return this.getValue(1);\n        }\n\n        set frequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get volume(): number {\n            return this.getValue(3);\n        }\n\n        set volume(value: number) {\n            this.setValue(3, value);\n        }\n\n        get duration(): number {\n            return this.getValue(5);\n        }\n\n        set duration(value: number) {\n            this.setValue(5, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    /**\n     * Renders a single note played on an instrument into a buffer of sound instructions.\n     *\n     * @param instrument The instrument being played\n     * @param noteFrequency The frequency of the note being played. In other words, \"the key being pressed on the piano\"\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     * @param volume The peak volume of the note to play (0-1024). Also called the \"velocity\"\n     */\n    export function renderInstrument(instrument: Instrument, noteFrequency: number, gateLength: number, volume: number) {\n        // We cut off the sound at the end of the amplitude envelope's release time. This is to prevent\n        // the amp envelope from making the sound keep playing forever\n        const totalDuration = gateLength + instrument.ampEnvelope.release;\n\n        // Our goal is to calculate the frequency and amplitude at all of the inflection points in this note's lifetime\n\n        // For the ADSR envelopes, the inflection points are:\n        //     1. The end of the envelope atack (which is when the decay begins)\n        //     2. The end of the envelope decay (which is when the sustain begins)\n        //     3. The end of the gateLength (which is when the release begins)\n        //     4. The end of the envelope release\n        // If the gateLength ends before any of these stages (e.g. it's shorter than the envelope's attack), then\n        // we ignore the other stages and go straight to the release stage.\n\n        // For the triangle LFOs, the inflections points occur every time the slope goes from positive to negative. In\n        // other words, it's half the period of the triangle wave.\n\n        const ampLFOInterval = instrument.ampLFO.amplitude ? Math.max(500 / instrument.ampLFO.frequency, 50) : 50;\n        const pitchLFOInterval = instrument.pitchLFO.amplitude ? Math.max(500 / instrument.pitchLFO.frequency, 50) : 50;\n\n        // We're going to add the timepoints to this array in order so that it doesn't need to be sorted\n        let timePoints = [0];\n\n        // For each LFO and envelope, keep track of the next inflection point. If any of the LFOs or envelopes have\n        // an amplitude of 0, we can ignore them entirely.\n        let nextAETime = instrument.ampEnvelope.attack;\n        let nextPETime = instrument.pitchEnvelope.amplitude ? instrument.pitchEnvelope.attack : totalDuration;\n        let nextPLTime = instrument.pitchLFO.amplitude ? pitchLFOInterval : totalDuration;\n        let nextALTime = instrument.ampLFO.amplitude ? ampLFOInterval : totalDuration;\n\n        let time = 0;\n        while (time < totalDuration) {\n            // Amp envelope\n            if (nextAETime <= nextPETime && nextAETime <= nextPLTime && nextAETime <= nextALTime) {\n                time = nextAETime;\n                timePoints.push(nextAETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            // Pitch envelope\n            else if (nextPETime <= nextPLTime && nextPETime <= nextALTime && nextPETime < totalDuration) {\n                time = nextPETime;\n                timePoints.push(nextPETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                // If we reach the end of the release before the amp envelope is finished, bail out\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            // Pitch LFO\n            else if (nextPLTime <= nextALTime && nextPLTime < totalDuration) {\n                time = nextPLTime;\n                timePoints.push(nextPLTime);\n                nextPLTime += pitchLFOInterval;\n            }\n            // Amp LFO\n            else if (nextALTime < totalDuration) {\n                time = nextALTime;\n                timePoints.push(nextALTime);\n                nextALTime += ampLFOInterval;\n            }\n\n\n            if (time >= totalDuration) {\n                break;\n            }\n\n            // Now that we've advanced the time, we need to check all of the envelopes/LFOs again\n            // to see if any of them also need to be pushed forward (e.g. they had the same inflection point\n            // as the one we just added to the array)\n            if (nextAETime <= time) {\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            if (nextPETime <= time) {\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            while (nextALTime <= time) {\n                nextALTime += ampLFOInterval;\n            }\n            while (nextPLTime <= time) {\n                nextPLTime += pitchLFOInterval;\n            }\n        }\n\n        // Once we've calculated the inflection points, calculate the frequency and amplitude at\n        // each step and interpolate between them with sound instructions\n        let prevAmp = instrumentVolumeAtTime(instrument, gateLength, 0, volume) | 0;\n        let prevPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, 0) | 0;\n        let prevTime = 0;\n\n        let nextAmp: number;\n        let nextPitch: number;\n        const out = control.createBuffer(BUFFER_SIZE * timePoints.length);\n        for (let i = 1; i < timePoints.length; i++) {\n            if (timePoints[i] - prevTime < 5) {\n                prevTime = timePoints[i];\n                continue;\n            }\n\n            nextAmp = instrumentVolumeAtTime(instrument, gateLength, timePoints[i], volume) | 0;\n            nextPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, timePoints[i]) | 0\n            addNote(\n                out,\n                (i - 1) * 12,\n                (timePoints[i] - prevTime) | 0,\n                prevAmp,\n                nextAmp,\n                instrument.waveform,\n                prevPitch,\n                255,\n                nextPitch\n            )\n\n            prevAmp = nextAmp;\n            prevPitch = nextPitch;\n            prevTime = timePoints[i];\n        }\n\n        // Finally, add one extra step to move the amplitude to 0 without\n        // clipping just in case the amp LFO caused it to be nonzero\n        addNote(\n            out,\n            (timePoints.length - 1) * 12,\n            10,\n            prevAmp,\n            0,\n            instrument.waveform,\n            prevPitch,\n            255,\n            prevPitch\n        )\n        return out;\n    }\n\n    export function renderDrumInstrument(sound: DrumInstrument, volume: number) {\n        // Drum instruments are rendered just like melodic instruments, but the inflection\n        // points are already calculated for us\n        let prevAmp = sound.startVolume;\n        let prevFreq = sound.startFrequency;\n\n        const scaleVolume = (value: number) => (value / 1024) * volume;\n\n        let out = control.createBuffer((sound.steps.length + 1) * BUFFER_SIZE);\n\n        for (let i = 0; i < sound.steps.length; i++) {\n            addNote(\n                out,\n                i * BUFFER_SIZE,\n                sound.steps[i].duration,\n                scaleVolume(prevAmp),\n                scaleVolume(sound.steps[i].volume),\n                sound.steps[i].waveform,\n                prevFreq,\n                255,\n                sound.steps[i].frequency\n            );\n            prevAmp = sound.steps[i].volume;\n            prevFreq = sound.steps[i].frequency\n        }\n\n        addNote(\n            out,\n            sound.steps.length * BUFFER_SIZE,\n            10,\n            scaleVolume(prevAmp),\n            0,\n            sound.steps[sound.steps.length - 1].waveform,\n            prevFreq,\n            255,\n            prevFreq\n        );\n\n        return out;\n    }\n\n    function instrumentPitchAtTime(instrument: Instrument, noteFrequency: number, gateLength: number, time: number) {\n        let mod = 0;\n        if (instrument.pitchEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.pitchEnvelope, time, gateLength)\n        }\n        if (instrument.pitchLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.pitchLFO, time)\n        }\n        return Math.max(noteFrequency + mod, 0);\n    }\n\n    function instrumentVolumeAtTime(instrument: Instrument, gateLength: number, time: number, maxVolume: number) {\n        let mod = 0;\n        if (instrument.ampEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.ampEnvelope, time, gateLength)\n        }\n        if (instrument.ampLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.ampLFO, time)\n        }\n        return ((Math.max(Math.min(mod, instrument.ampEnvelope.amplitude), 0) / 1024) * maxVolume) | 0;\n    }\n\n    /**\n     * Calculates the value of an ADSR envelope at the given time for a given gate length.\n     *\n     * @param envelope The ADSR envelope\n     * @param time The point and time to calculate the value at\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     */\n    function envelopeValueAtTime(envelope: Envelope, time: number, gateLength: number) {\n        // ADSR envelopes consist of 4 stages. They are (in order):\n        //     1. The attack stage, where the value starts at 0 and rises to the maximum value\n        //     2. The decay stage, where the value falls from the maximum value to the sustain value\n        //     3. The sustain stage, where the value holds steady at the sustain value until the gate length ends\n        //     4. The release stage, where the value falls to 0 after the gate length ends\n        // If the gate length ends before the sustain stage, we immediately skip to the release stage. All stages\n        // use a linear function for the value\n        const adjustedSustain = (envelope.sustain / 1024) * envelope.amplitude;\n\n        // First check to see if we are already in the release stage\n        if (time > gateLength) {\n            if (time - gateLength > envelope.release) return 0;\n\n            // Did the gate length end before the attack stage finished?\n            else if (time < envelope.attack) {\n                const height = (envelope.amplitude / envelope.attack) * gateLength;\n                return height - ((height / envelope.release) * (time - gateLength))\n            }\n            // Did the gate length end before the decay stage finished?\n            else if (time < envelope.attack + envelope.decay) {\n                const height2 = envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (gateLength - envelope.attack);\n                return height2 - ((height2 / envelope.release) * (time - gateLength))\n            }\n            else {\n                return adjustedSustain - (adjustedSustain / envelope.release) * (time - gateLength)\n            }\n        }\n        else if (time < envelope.attack) {\n            return (envelope.amplitude / envelope.attack) * time\n        }\n        else if (time < envelope.attack + envelope.decay) {\n            return envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (time - envelope.attack)\n        }\n        else {\n            return adjustedSustain;\n        }\n    }\n\n    /**\n     * Calculates the value of the LFO at the given time.\n     *\n     * TODO: might be nice to give options to shift the phase of the LFO or let it run free\n     *\n     * @param lfo The LFO to calculate the value of\n     * @param time The time to calculate the value at\n     */\n    function lfoValueAtTime(lfo: LFO, time: number) {\n        // Use cosine to smooth out the value somewhat\n        return Math.cos(((time / 1000) * lfo.frequency) * 2 * Math.PI) * lfo.amplitude\n    }\n\n    export function _stopAllSongs() {\n        if (currentSequencer) {\n            currentSequencer.stop();\n            currentSequencer = undefined;\n        }\n        _stopAllSimSequencers();\n    }\n}","legacy.ts":"//% deprecated=true hidden=true\nenum Sounds {\n    //% block=\"power up\"\n    PowerUp,\n    //% block=\"power down\"\n    PowerDown,\n    //% block=\"jump up\"\n    JumpUp,\n    //% block=\"jump down\"\n    JumpDown,\n    //% block=\"ba ding\"\n    BaDing,\n    //% block=\"wawawawaa\"\n    Wawawawaa,\n    //% block=\"magic wand\"\n    MagicWand,\n    //% block=\"siren\"\n    Siren\n}\n\nnamespace music {\n    /**\n     * Get the melody string for a built-in melody.\n     * @param name the note name, eg: Note.C\n     */\n    //% help=music/sounds\n    //% blockId=music_sounds block=\"%name\"\n    //% blockHidden=true\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=285\n    //% name.fieldOptions.columns=3\n    export function sounds(name: Sounds): string {\n        switch (name) {\n            case Sounds.BaDing:\n                return 'b5:1 e6:3';\n            case Sounds.Wawawawaa:\n                return 'e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8';\n            case Sounds.JumpUp:\n                return 'c5:1 d e f g';\n            case Sounds.JumpDown:\n                return 'g5:1 f e d c';\n            case Sounds.PowerUp:\n                return 'g4:1 c5 e g:2 e:1 g:3';\n            case Sounds.PowerDown:\n                return 'g5:1 d# c g4:2 b:1 c5:3';\n            case Sounds.MagicWand:\n                return 'F#6:1-300 G# A# B C7# D# F F# G# A# B:6'; //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n            case Sounds.Siren:\n                return 'a4 d5 a4 d5 a4 d5';\n            default:\n                return '';\n        }\n    }\n\n    let currMelody: Melody\n\n    /**\n     * Start playing a sound and don't wait for it to finish.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound\n    //% blockId=music_play_sound block=\"play sound %sound=music_sounds\"\n    //% parts=\"headphone\"\n    //% weight=95 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSound(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.play();\n        pause(1);\n    }\n\n\n    /**\n     * Play a sound and wait until the sound is done.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound-until-done\n    //% blockId=music_play_sound_until_done block=\"play sound %sound=music_sounds|until done\"\n    //% parts=\"headphone\"\n    //% weight=94 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSoundUntilDone(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.playUntilDone();\n    }\n}","melody.cpp":"#include \"pxt.h\"\n#include \"SoundOutput.h\"\n#include \"melody.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\nnamespace music {\n\nSINGLETON(WSynthesizer);\n\n// Tone generator arguments:\n//\n// sound: a pointer to the currently-playing sound, usable for looking up the\n// waveform or generator-specific state.\n//\n// position: offset within the currently-playing wave, range 0..1023.\n//\n// cycle: a 6-bit cyclical sequence number of the wave, incremented each time\n// the position loops from 1023 back to 0.\ntypedef int (*gentone_t)(PlayingSound *sound, uint32_t position, uint8_t cycle);\n\nstatic int noiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    // see https://en.wikipedia.org/wiki/Xorshift\n    static uint32_t x = 0xf01ba80;\n    x ^= x << 13;\n    x ^= x >> 17;\n    x ^= x << 5;\n    return (x & 0xffff) - 0x7fff;\n}\n\nstatic int sineTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    int32_t p = position;\n    if (p >= 512) {\n        p -= 512;\n    }\n    if (p > 256) {\n        p = 512 - p;\n    }\n\n    // Approximate sin(x * pi / 2) with the odd polynomial y = cx^5 + bx^3 + ax\n    // using the constraint y(1) = 1 => a = 1 - b - c\n    //   => y = c x^5 + b x^3 + (1 - b - c) * x\n    //\n    // Do a least-squares fit of this to sin(x * pi / 2) in the range 0..1\n    // inclusive, using 21 evenly spaced points. Resulting approximation:\n    //\n    // sin(x*pi/2) ~= 0.0721435357258*x**5 - 0.642443736562*x**3 + 1.57030020084*x\n\n    // Scale the constants by 32767 to match the desired output range.\n    constexpr int32_t c = 0.0721435357258 * 32767;\n    constexpr int32_t b = -0.642443736562 * 32767;\n    constexpr int32_t a = 1.57030020084 * 32767;\n\n    // Calculate using y = ((c * x^2 + b) * x^2 + a) * x\n    //\n    // The position p is x * 256, so after each multiply with p we need to\n    // shift right by 8 bits to keep the decimal point in the same place.  (The\n    // approximation has a negative error near x=1 which helps avoid overflow.)\n    int32_t p2 = p * p;\n    int32_t u = (c * p2 >> 16) + b;\n    int32_t v = (u * p2 >> 16) + a;\n    int32_t w = v * p >> 8;\n\n    // The result is within 7/32767 or 0.02%, signal-to-error ratio about 38 dB.\n    return position >= 512 ? -w : w;\n}\n\nstatic int sawtoothTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return (position << 6) - 0x7fff;\n}\n\nstatic int triangleTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return position < 512 ? (position << 7) - 0x7fff : ((1023 - position) << 7) - 0x7fff;\n}\n\nstatic int squareWaveTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)cycle;\n    uint8_t wave = sound->currInstr->soundWave;\n    return (int)position < (102 * (wave - SW_SQUARE_10 + 1)) ? -0x7fff : 0x7fff;\n}\n\nstatic int tunedNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a random bit sequence. Since the generator\n    // is called multiple times per wave, use PlayingSound state data to ensure we\n    // only generate a random bit once per wave, and then reuse it for future\n    // calls for that wave.\n    //\n    // Use the low 6 bits of generatorState to store the last-used cycle, and\n    // random_bit to store the last on/off state. (random_bit is arbitrary as\n    // long as it isn't one of the low 6 bits.)\n    constexpr uint32_t random_bit = 0x8000;\n    static uint32_t x = 0xf01ba80; // seed for the static RNG state\n    uint8_t prev_cycle = sound->generatorState & 0x3f;\n    uint32_t is_on;\n    if (cycle == prev_cycle) {\n        is_on = sound->generatorState & random_bit;\n    } else {\n        // see https://en.wikipedia.org/wiki/Xorshift\n        x ^= x << 13;\n        x ^= x >> 17;\n        x ^= x << 5;\n        is_on = (x & random_bit);\n        sound->generatorState = (cycle & 0x3f) | is_on;\n    }\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\n// Bit patterns for use by the cyclic noise tone.\n//\n// The bit pattern is arbitrary, but should have equal numbers of 0 and 1 bits,\n// and should avoid long identical-bit runs for the lower parts. The values below\n// were chosen based on a random permutation of the hex nibbles 0..f and then\n// hand-tweaked by swapping some nibbles. Generated by:\n//\n//   shuf -i 0-15 | perl -ne 's/(\\d+)/printf(\"%x\",$1)/e'\nstatic const uint32_t cycle_bits[] = {0x2df0eb47, 0xc8165a93};\nstatic const uint8_t cycle_mask[] = {0xf, 0x1f, 0x3f};\n\nstatic int cycleNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    // The bit sequence repeats every 16/32/64 waves.\n    //\n    // The \"cycle\" argument corresponds to the sequential number of the generated\n    // wave. This is currently a 6-bit value. Since the pseudorandom bit sequences\n    // evenly fit into this, there's no need to track generator state.\n    uint8_t wave = sound->currInstr->soundWave;\n    int cycle_index = wave - SW_SQUARE_CYCLE_16;\n    // CLAMP(0, cycle_index, sizeof cycle_bits / sizeof cycle_bits[0])\n    cycle &= cycle_mask[cycle_index];\n    bool is_on = (cycle_bits[cycle >> 5] & (1U << (cycle & 0x1f)));\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\nstatic int silenceTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    return 0;\n}\n\nstatic gentone_t getWaveFn(uint8_t wave) {\n    switch (wave) {\n    case SW_TRIANGLE:\n        return triangleTone;\n    case SW_SAWTOOTH:\n        return sawtoothTone;\n    case SW_TUNEDNOISE:\n        return tunedNoiseTone;\n    case SW_NOISE:\n        return noiseTone;\n    case SW_SINE:\n        return sineTone;\n    default:\n        if (SW_SQUARE_10 <= wave && wave <= SW_SQUARE_50)\n            return squareWaveTone;\n        if (SW_SQUARE_CYCLE_16 <= wave && wave <= SW_SQUARE_CYCLE_64)\n            return cycleNoiseTone;\n        else\n            return silenceTone;\n    }\n}\n\n#define CLAMP(lo, v, hi) ((v) = ((v) < (lo) ? (lo) : (v) > (hi) ? (hi) : (v)))\n\nint WSynthesizer::updateQueues() {\n    const int maxTime = 0xffffff;\n    while (1) {\n        WaitingSound *p;\n        int minLeft = maxTime;\n        for (p = waiting; p; p = p->next) {\n            int timeLeft =\n                p->state == SoundState::Waiting ? p->startSampleNo - currSample : maxTime;\n            if (timeLeft <= 0) {\n                break;\n            }\n            if (timeLeft < minLeft)\n                minLeft = timeLeft;\n        }\n        if (p) {\n            PlayingSound *snd;\n            int minIdx = -1;\n            for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n                snd = &playingSounds[i];\n                if (snd->sound == NULL)\n                    break;\n                if (minIdx == -1 ||\n                    playingSounds[minIdx].startSampleNo < playingSounds[i].startSampleNo)\n                    minIdx = i;\n                snd = NULL;\n            }\n            // if we didn't find a free slot, expel the oldest sound\n            if (!snd)\n                snd = &playingSounds[minIdx];\n            if (snd->sound)\n                snd->sound->state = SoundState::Done;\n            snd->sound = p;\n            p->state = SoundState::Playing;\n            snd->startSampleNo = currSample;\n            snd->currInstr = (SoundInstruction *)p->instructions->data;\n            snd->instrEnd = snd->currInstr + p->instructions->length / sizeof(SoundInstruction);\n            snd->prevVolume = -1;\n        } else {\n            // no more sounds to move\n            return minLeft;\n        }\n    }\n}\n\nint WSynthesizer::fillSamples(int16_t *dst, int numsamples) {\n    if (numsamples <= 0)\n        return 1;\n\n    int timeLeft = updateQueues();\n    int res = waiting != NULL;\n\n    // if there's a pending sound to be started somewhere during numsamples,\n    // split the call into two\n    if (timeLeft < numsamples) {\n        fillSamples(dst, timeLeft);\n        LOG(\"M split %d\", timeLeft);\n        fillSamples(dst + timeLeft, numsamples - timeLeft);\n        return 1;\n    }\n\n    memset(dst, 0, numsamples * 2);\n\n    uint32_t samplesPerMS = (sampleRate << 8) / 1000;\n    float toneStepMult = (1024.0 * (1 << 16)) / sampleRate;\n    const int MAXVAL = (1 << (OUTPUT_BITS - 1)) - 1;\n\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        PlayingSound *snd = &playingSounds[i];\n        if (snd->sound == NULL)\n            continue;\n\n        res = 1;\n\n        SoundInstruction *instr = NULL;\n        gentone_t fn = NULL;\n        snd->currInstr--;\n        uint32_t toneStep = 0;\n        int32_t toneDelta = 0;\n        int32_t volumeStep = 0;\n        uint32_t tonePosition = snd->tonePosition;\n        uint32_t samplesLeft = 0;\n        uint8_t wave = 0;\n        int32_t volume = 0;\n\n        for (int j = 0; j < numsamples; ++j) {\n            if (samplesLeft == 0) {\n                snd->currInstr++;\n                if (snd->currInstr >= snd->instrEnd) {\n                    break;\n                }\n                SoundInstruction copy = *snd->currInstr;\n                instr = &copy;\n                CLAMP(20, instr->frequency, 20000);\n                CLAMP(20, instr->endFrequency, 20000);\n                CLAMP(0, instr->startVolume, 1023);\n                CLAMP(0, instr->endVolume, 1023);\n                CLAMP(1, instr->duration, 60000);\n\n                wave = instr->soundWave;\n                fn = getWaveFn(wave);\n\n                samplesLeft = (uint32_t)(instr->duration * samplesPerMS >> 8);\n                // make sure the division is signed\n                volumeStep =\n                    (int)((instr->endVolume - instr->startVolume) << 16) / (int)samplesLeft;\n\n                if (j == 0 && snd->prevVolume != -1) {\n                    // restore previous state\n                    samplesLeft = snd->samplesLeftInCurr;\n                    volume = snd->prevVolume;\n                    toneStep = snd->prevToneStep;\n                    toneDelta = snd->prevToneDelta;\n                } else {\n                    LOG(\"#sampl %d %p\", samplesLeft, snd->currInstr);\n                    volume = instr->startVolume << 16;\n                    LOG(\"%d-%dHz %d-%d vol\", instr->frequency, instr->endFrequency,\n                        instr->startVolume, instr->endVolume);\n                    toneStep = (uint32_t)(toneStepMult * instr->frequency);\n                    if (instr->frequency != instr->endFrequency) {\n                        uint32_t endToneStep = (uint32_t)(toneStepMult * instr->endFrequency);\n                        toneDelta = (int32_t)(endToneStep - toneStep) / (int32_t)samplesLeft;\n                    } else {\n                        toneDelta = 0;\n                    }\n                }\n            }\n\n            int v = fn(snd, (tonePosition >> 16) & 1023, tonePosition >> 26);\n            v = (v * (volume >> 16)) >> (10 + (16 - OUTPUT_BITS));\n\n            // if (v > MAXVAL)\n            //    target_panic(123);\n\n            dst[j] += v;\n\n            tonePosition += toneStep;\n            toneStep += toneDelta;\n            volume += volumeStep;\n            samplesLeft--;\n        }\n\n        if (snd->currInstr >= snd->instrEnd) {\n            snd->sound->state = SoundState::Done;\n            snd->sound = NULL;\n        } else {\n            snd->tonePosition = tonePosition;\n            if (samplesLeft == 0)\n                samplesLeft++; // avoid infinite loop in next iteration\n            snd->samplesLeftInCurr = samplesLeft;\n            snd->prevVolume = volume;\n            snd->prevToneDelta = toneDelta;\n            snd->prevToneStep = toneStep;\n        }\n    }\n\n    currSample += numsamples;\n\n    for (int j = 0; j < numsamples; ++j) {\n        if (dst[j] > MAXVAL)\n            dst[j] = MAXVAL;\n        else if (dst[j] < -MAXVAL)\n            dst[j] = -MAXVAL;\n    }\n\n    return res;\n}\n\n//%\nvoid enableAmp(int enabled) {\n    // this is also compiled on linux\n#ifdef LOOKUP_PIN\n    auto pin = LOOKUP_PIN(SPEAKER_AMP);\n    if (pin) {\n        if (PIN(SPEAKER_AMP) & CFG_PIN_CONFIG_ACTIVE_LO)\n            enabled = !enabled;\n        pin->setDigitalValue(enabled);\n    }\n#endif\n}\n\n//%\nvoid forceOutput(int outp) {\n    auto snd = getWSynthesizer();\n    snd->out.setOutput(outp);\n}\n\n//%\nvoid queuePlayInstructions(int when, Buffer buf) {\n    auto snd = getWSynthesizer();\n\n    registerGCObj(buf);\n\n    auto p = new WaitingSound;\n    p->state = SoundState::Waiting;\n    p->instructions = buf;\n    p->startSampleNo = snd->currSample + when * snd->sampleRate / 1000;\n\n    LOG(\"Queue %dms now=%d off=%d %p sampl:%dHz\", when, snd->currSample,\n        p->startSampleNo - snd->currSample, buf->data, snd->sampleRate);\n\n    target_disable_irq();\n    // add new sound to queue\n    p->next = snd->waiting;\n    snd->waiting = p;\n    // remove sounds that have already been fully played\n    while (p) {\n        while (p->next && p->next->state == SoundState::Done) {\n            auto todel = p->next;\n            p->next = todel->next;\n            unregisterGCObj(todel->instructions);\n            delete todel;\n        }\n        p = p->next;\n    }\n    target_enable_irq();\n\n    snd->poke();\n}\n\n//%\nvoid stopPlaying() {\n    LOG(\"stop playing!\");\n\n    auto snd = getWSynthesizer();\n\n    target_disable_irq();\n    auto p = snd->waiting;\n    snd->waiting = NULL;\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        snd->playingSounds[i].sound = NULL;\n    }\n    while (p) {\n        auto n = p->next;\n        unregisterGCObj(p->instructions);\n        delete p;\n        p = n;\n    }\n    target_enable_irq();\n}\n\nWSynthesizer::WSynthesizer() : upstream(NULL), out(*this) {\n    currSample = 0;\n    active = false;\n    sampleRate = out.dac.getSampleRate();\n    memset(&playingSounds, 0, sizeof(playingSounds));\n    waiting = NULL;\n    PXT_REGISTER_RESET(stopPlaying);\n}\n\n//% promise\nint _createSequencer() {\n    return 0;\n}\n\n//%\nString _sequencerState(int id) {\n    return NULL;\n}\n\n//%\nint _sequencerCurrentTick(int id) {\n    return 0;\n}\n\n//%\nvoid _sequencerPlaySong(int id, Buffer buf, bool loop) {\n}\n\n//%\nvoid _sequencerStop(int id) {\n}\n\n//%\nvoid _sequencerSetVolume(int id, int volume) {\n}\n\n//%\nvoid _sequencerSetVolumeForAll(int volume) {\n}\n\n//%\nvoid _sequencerSetTrackVolume(int id, int trackIndex, int volume) {\n}\n\n//%\nvoid _sequencerSetDrumTrackVolume(int id, int trackIndex, int drumIndex, int volume) {\n}\n\n//%\nvoid _sequencerDispose(int id) {\n}\n\n} // namespace music\n\nnamespace pxt {\nint redirectSamples(int16_t *dst, int numsamples, int samplerate) {\n    auto snd = music::getWSynthesizer();\n    snd->upstream = NULL; // disconnect from regular playback mechanism\n    snd->sampleRate = samplerate;\n    return snd->fillSamples(dst, numsamples);\n}\n\n} // namespace pxt\n\nnamespace jacdac {\n__attribute__((weak)) void setJackRouterOutput(int output) {}\n} // namespace jacdac\n","melody.h":"#pragma once\n\n#ifndef OUTPUT_BITS\n#define OUTPUT_BITS 10\n#endif\n\n#define SW_TRIANGLE 1\n#define SW_SAWTOOTH 2\n#define SW_SINE 3\n#define SW_TUNEDNOISE 4\n#define SW_NOISE 5\n#define SW_SQUARE_10 11\n#define SW_SQUARE_50 15\n#define SW_SQUARE_CYCLE_16 16\n#define SW_SQUARE_CYCLE_32 17\n#define SW_SQUARE_CYCLE_64 18\n\nstruct SoundInstruction {\n    uint8_t soundWave;\n    uint8_t flags;\n    uint16_t frequency;    // Hz\n    uint16_t duration;     // ms\n    int16_t startVolume;   // 0-1023\n    int16_t endVolume;     // 0-1023\n    uint16_t endFrequency; // Hz\n};\n\n#ifdef DATASTREAM_MAXIMUM_BUFFERS\n#define CODAL 1\n#endif\n\nnamespace music {\n\n#define MAX_SOUNDS 8\n\nSTATIC_ASSERT((1 << (16 - OUTPUT_BITS)) > MAX_SOUNDS);\n\nenum class SoundState : uint8_t {\n    Waiting, //\n    Playing, //\n    Done     //\n};\n\nstruct WaitingSound {\n    uint32_t startSampleNo;\n    SoundState state;\n    WaitingSound *next;\n    Buffer instructions;\n};\n\nstruct PlayingSound {\n    uint32_t startSampleNo;\n    uint32_t samplesLeftInCurr;\n    uint32_t tonePosition;\n    int32_t prevVolume;\n    uint32_t prevToneStep;\n    int32_t prevToneDelta;\n    uint32_t generatorState;\n    WaitingSound *sound;\n    SoundInstruction *currInstr, *instrEnd;\n};\n\nclass WSynthesizer\n#ifdef CODAL\n    : public DataSource\n#endif\n{\n  public:\n#ifdef CODAL\n    DataSink *upstream;\n#else\n    void *upstream;\n#endif\n    uint32_t currSample; // after 25h of playing we might get a glitch\n    int32_t sampleRate;  // eg 44100\n    PlayingSound playingSounds[MAX_SOUNDS];\n    WaitingSound *waiting;\n    bool active;\n\n    SoundOutput out;\n\n    int fillSamples(int16_t *dst, int numsamples);\n    int updateQueues();\n\n    WSynthesizer();\n    virtual ~WSynthesizer() {}\n\n    void pokeUpstream() {\n#ifdef CODAL\n        if (upstream) {\n            upstream->pullRequest();\n        }\n#endif\n    }\n\n    void poke() {\n        if (!active) {\n            active = true;\n            pokeUpstream();\n        }\n    }\n\n#ifdef CODAL\n    virtual ManagedBuffer pull() {\n        if (!upstream)\n            return ManagedBuffer();\n        ManagedBuffer data(512);\n        auto dp = (int16_t *)data.getBytes();\n        auto sz = 512 / 2;\n        int r = fillSamples(dp, sz);\n#if defined(NRF52_SERIES)\n        int mul = out.dac.getSampleRange();\n#endif\n        while (sz--) {\n#if defined(NRF52_SERIES)\n            *dp = ((-*dp + (1 << (OUTPUT_BITS - 1))) * mul) >> OUTPUT_BITS;\n#else\n            *dp += 1 << (OUTPUT_BITS - 1);\n#endif\n            dp++;\n        }\n        if (!r) {\n            active = false;\n            // return empty - nothing left to play\n            return ManagedBuffer();\n        }\n        pokeUpstream();\n        return data;\n    }\n    virtual void connect(DataSink &sink) { upstream = &sink; }\n#endif\n};\n\n} // namespace music\n","melody.ts":"enum MusicOutput {\n    AutoDetect = 0,\n    Buzzer = 1,\n    HeadPhones = 2,\n}\n\nnamespace music {\n    //% whenUsed\n    const freqs = hex`\n        1f00210023002500270029002c002e003100340037003a003e004100450049004e00520057005c00620068006e00\n        75007b0083008b0093009c00a500af00b900c400d000dc00e900f70006011501260137014a015d01720188019f01\n        b801d201ee010b022a024b026e029302ba02e40210033f037003a403dc03170455049704dd0427057505c8052006\n        7d06e0064907b8072d08a9082d09b9094d0aea0a900b400cfa0cc00d910e6f0f5a1053115b1272139a14d4152017\n        8018f519801b231dde1e`\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n\n    //% shim=music::stopPlaying\n    function stopPlaying() { }\n\n    //% shim=music::forceOutput\n    export function forceOutput(buf: MusicOutput) { }\n\n    let globalVolume: number = null\n\n    const BUFFER_SIZE: number = 12;\n\n    //% shim=music::enableAmp\n    function enableAmp(en: number) {\n        return // for sim\n    }\n\n    function initVolume() {\n        if (globalVolume === null) {\n            globalVolume = 0\n            setVolume(control.getConfigValue(DAL.CFG_SPEAKER_VOLUME, 128))\n        }\n    }\n\n    /**\n     * Set the default output volume of the sound synthesizer.\n     * @param volume the volume 0...255\n     */\n    //% blockId=synth_set_volume block=\"set volume %volume\"\n    //% parts=\"speaker\"\n    //% volume.min=0 volume.max=255\n    //% volume.defl=20\n    //% help=music/set-volume\n    //% weight=70\n    //% group=\"Volume\"\n    export function setVolume(volume: number): void {\n        globalVolume = Math.clamp(0, 255, volume | 0)\n        enableAmp(globalVolume > 0 ? 1 : 0)\n    }\n\n    /**\n     * Gets the current volume\n     */\n    //% parts=\"speaker\"\n    //% weight=70\n    export function volume(): number {\n        initVolume()\n        return globalVolume;\n    }\n\n    function playNoteCore(when: number, frequency: number, ms: number) {\n        let buf = control.createBuffer(BUFFER_SIZE)\n        addNote(buf, 0, ms, 255, 255, 3, frequency, volume(), frequency)\n        queuePlayInstructions(when, buf)\n    }\n\n    /**\n     * Play a tone through the speaker for some amount of time.\n     * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n     * @param ms tone duration in milliseconds (ms), eg: BeatFraction.Half\n     */\n    //% help=music/play-tone\n    //% blockId=mixer_play_note block=\"play tone|at %note=device_note|for %duration=device_beat\"\n    //% parts=\"headphone\" async\n    //% blockNamespace=music\n    //% weight=76 blockGap=8\n    //% group=\"Tone\"\n    //% deprecated=1\n    export function playTone(frequency: number, ms: number): void {\n        if (ms == 0)\n            ms = 86400000 // 1 day\n\n        if (ms <= 2000) {\n            playNoteCore(0, frequency, ms)\n            pause(ms)\n        } else {\n            const id = ++playToneID\n            control.runInParallel(() => {\n                let pos = control.millis()\n                while (id == playToneID && ms > 0) {\n                    let now = control.millis()\n                    let d = pos - now\n                    let t = Math.min(ms, 500)\n                    ms -= t\n                    pos += t\n                    playNoteCore(d - 1, frequency, t)\n                    if (ms == 0)\n                        pause(d + t)\n                    else\n                        pause(d + t - 100)\n                }\n            })\n        }\n    }\n\n    let playToneID = 0\n\n    /**\n     * Play a melody from the melody editor.\n     * @param melody - string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces,\n     * which will be played one at a time, ex: \"E D G F B A C5 B \"\n     * @param tempo - number in beats per minute (bpm), dictating how long each note will play for\n     */\n    //% block=\"play melody $melody at tempo $tempo|(bpm)\" blockId=playMelody\n    //% blockNamespace=music\n    //% weight=85 blockGap=8 help=music/play-melody\n    //% group=\"Melody\"\n    //% melody.shadow=\"melody_editor\"\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% deprecated=1\n    export function playMelody(melody: string, tempo: number) {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        const song = new Melody(formattedMelody);\n        song.playUntilDone();\n    }\n\n\n    /**\n     * Create a melody with the melody editor.\n     * @param melody\n     */\n    //% block=\"$melody\" blockId=melody_editor\n    //% blockNamespace=music\n    //% blockHidden = true\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Melody\" duplicateShadowOnDrag\n    //% melody.fieldEditor=\"melody\"\n    //% melody.fieldOptions.decompileLiterals=true\n    //% melody.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% melody.fieldOptions.onParentBlock=\"true\"\n    //% shim=TD_ID\n    export function melodyEditor(melody: string): string {\n        return melody;\n    }\n\n    /**\n     * Stop all sounds from playing.\n     */\n    //% help=music/stop-all-sounds\n    //% blockId=music_stop_all_sounds block=\"stop all sounds\"\n    //% weight=45\n    //% group=\"Sounds\"\n    export function stopAllSounds() {\n        Melody.stopAll();\n        stopPlaying();\n        _stopPlayables();\n        sequencer._stopAllSongs();\n    }\n\n    //% fixedInstances\n    export class Melody {\n        _text: string;\n        private _player: MelodyPlayer;\n\n        private static playingMelodies: Melody[];\n\n        static stopAll() {\n            if (Melody.playingMelodies) {\n                const ms = Melody.playingMelodies.slice(0, Melody.playingMelodies.length);\n                ms.forEach(p => p.stop());\n            }\n        }\n\n        constructor(text: string) {\n            this._text = text\n        }\n\n        get text() {\n            return this._text;\n        }\n\n        /**\n         * Stop playing a sound\n         */\n        //% blockId=mixer_stop block=\"stop sound %sound\"\n        //% help=music/melody/stop\n        //% parts=\"headphone\"\n        //% weight=92 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        stop() {\n            if (this._player) {\n                this._player.stop()\n                this._player = null\n            }\n            this.unregisterMelody();\n        }\n\n        private registerMelody() {\n            // keep track of the active players\n            if (!Melody.playingMelodies) Melody.playingMelodies = [];\n            // stop and pop melodies if too many playing\n            if (Melody.playingMelodies.length > 4) {\n                // stop last player (also pops)\n                Melody.playingMelodies[Melody.playingMelodies.length - 1].stop();\n            }\n            // put back the melody on top of the melody stack\n            Melody.playingMelodies.removeElement(this);\n            Melody.playingMelodies.push(this);\n        }\n        private unregisterMelody() {\n            // remove from list\n            if (Melody.playingMelodies) {\n                Melody.playingMelodies.removeElement(this); // remove self\n            }\n        }\n\n        private playCore(volume: number, loop: boolean) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this.registerMelody();\n            control.runInParallel(() => {\n                while (this._player == p) {\n                    p.play(volume)\n                    if (!loop) {\n                        // Unregister the melody when done playing, but\n                        // only if it hasn't been restarted. (Looping\n                        // melodies never stop on their own, they only\n                        // get unregistered via stop().)\n                        if (this._player == p) {\n                            this.unregisterMelody();\n                        }\n                        break\n                    }\n                }\n            })\n        }\n\n        /**\n         * Start playing a sound in a loop and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/loop\n        //% blockId=mixer_loop_sound block=\"loop sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=93 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        loop(volume = 255) {\n            this.playCore(volume, true)\n        }\n\n        /**\n         * Start playing a sound and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play\n        //% blockId=mixer_play_sound block=\"play sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=95 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        play(volume = 255) {\n            this.playCore(volume, false)\n        }\n\n\n        /**\n         * Play a sound and wait until the sound is done.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play-until-done\n        //% blockId=mixer_play_sound_until_done block=\"play sound %sound|until done\"\n        //% parts=\"headphone\"\n        //% weight=94 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        playUntilDone(volume = 255) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this._player.onPlayFinished = () => {\n                if (p == this._player)\n                    this.unregisterMelody();\n            }\n            this.registerMelody();\n            this._player.play(volume)\n        }\n\n        toString() {\n            return this._text;\n        }\n    }\n\n    export function addNote(sndInstr: Buffer, sndInstrPtr: number, ms: number, beg: number, end: number, soundWave: number, hz: number, volume: number, endHz: number) {\n        if (ms > 0) {\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, soundWave)\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr + 1, 0)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 2, hz)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 4, ms)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 6, (beg * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 8, (end * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 10, endHz);\n            sndInstrPtr += BUFFER_SIZE;\n        }\n        sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, 0) // terminate\n        return sndInstrPtr\n    }\n\n\n    export class MelodyPlayer {\n        melody: Melody;\n\n        onPlayFinished: () => void;\n\n        constructor(m: Melody) {\n            this.melody = m\n        }\n\n        stop() {\n            this.melody = null\n        }\n\n        protected queuePlayInstructions(timeDelta: number, buf: Buffer) {\n            queuePlayInstructions(timeDelta, buf)\n        }\n\n        play(volume: number) {\n            if (!this.melody)\n                return\n            volume = Math.clamp(0, 255, (volume * music.volume()) >> 8)\n\n            let notes = this.melody._text\n            let pos = 0;\n            let duration = 4; //Default duration (Crotchet)\n            let octave = 4; //Middle octave\n            let tempo = 120; // default tempo\n\n            let hz = 0\n            let endHz = -1\n            let ms = 0\n            let timePos = 0\n            let startTime = control.millis()\n            let now = 0\n\n            let envA = 0\n            let envD = 0\n            let envS = 255\n            let envR = 0\n            let soundWave = 1 // triangle\n            let sndInstr = control.createBuffer(5 * BUFFER_SIZE)\n            let sndInstrPtr = 0\n\n            const addForm = (formDuration: number, beg: number, end: number, msOff: number) => {\n                let freqStart = hz;\n                let freqEnd = endHz;\n\n                const envelopeWidth = ms > 0 ? ms : duration * Math.idiv(15000, tempo) + envR;\n                if (endHz != hz && envelopeWidth != 0) {\n                    const slope = (freqEnd - freqStart) / envelopeWidth;\n                    freqStart = hz + slope * msOff;\n                    freqEnd = hz + slope * (msOff + formDuration);\n                }\n                sndInstrPtr = addNote(sndInstr, sndInstrPtr, formDuration, beg, end, soundWave, freqStart, volume, freqEnd);\n            }\n\n            const scanNextWord = () => {\n                if (!this.melody)\n                    return \"\"\n\n                // eat space\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c != ' ' && c != '\\r' && c != '\\n' && c != '\\t')\n                        break;\n                    pos++;\n                }\n\n                // read note\n                let note = \"\";\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c == ' ' || c == '\\r' || c == '\\n' || c == '\\t')\n                        break;\n                    note += c;\n                    pos++;\n                }\n                return note;\n            }\n\n            enum Token {\n                Note,\n                Octave,\n                Beat,\n                Tempo,\n                Hz,\n                EndHz,\n                Ms,\n                WaveForm,\n                EnvelopeA,\n                EnvelopeD,\n                EnvelopeS,\n                EnvelopeR\n            }\n\n            let token: string = \"\";\n            let tokenKind = Token.Note;\n\n            // [ABCDEFG] (\\d+)  (:\\d+)  (-\\d+)\n            // note      octave length  tempo\n            // R (:\\d+) - rest\n            // !\\d+,\\d+ - sound at frequency with given length (Hz,ms); !\\d+ and !\\d+,:\\d+ also possible\n            // @\\d+,\\d+,\\d+,\\d+ - ADSR envelope - ms,ms,volume,ms; volume is 0-255\n            // ~\\d+ - wave form:\n            //   1 - triangle\n            //   2 - sawtooth\n            //   3 - sine\n            //   4 - pseudorandom square wave noise (tunable)\n            //   5 - white noise (ignores frequency)\n            //   11 - square 10%\n            //   12 - square 20%\n            //   ...\n            //   15 - square 50%\n            //   16 - filtered square wave, cycle length 16\n            //   17 - filtered square wave, cycle length 32\n            //   18 - filtered square wave, cycle length 64\n\n            const consumeToken = () => {\n                if (token && tokenKind != Token.Note) {\n                    const d = parseInt(token);\n                    switch (tokenKind) {\n                        case Token.Octave: octave = d; break;\n                        case Token.Beat:\n                            duration = Math.max(1, Math.min(16, d));\n                            ms = -1;\n                            break;\n                        case Token.Tempo: tempo = Math.max(1, d); break;\n                        case Token.Hz: hz = d; tokenKind = Token.Ms; break;\n                        case Token.Ms: ms = d; break;\n                        case Token.WaveForm: soundWave = Math.clamp(1, 18, d); break;\n                        case Token.EnvelopeA: envA = d; tokenKind = Token.EnvelopeD; break;\n                        case Token.EnvelopeD: envD = d; tokenKind = Token.EnvelopeS; break;\n                        case Token.EnvelopeS: envS = Math.clamp(0, 255, d); tokenKind = Token.EnvelopeR; break;\n                        case Token.EnvelopeR: envR = d; break;\n                        case Token.EndHz: endHz = d; break;\n                    }\n                    token = \"\";\n                }\n            }\n\n            while (true) {\n                let currNote = scanNextWord();\n                let prevNote: boolean = false;\n                if (!currNote) {\n                    let timeLeft = timePos - now\n                    if (timeLeft > 0)\n                        pause(timeLeft)\n                    if (this.onPlayFinished)\n                        this.onPlayFinished();\n                    return;\n                }\n\n                hz = -1;\n\n                let note: number = 0;\n                token = \"\";\n                tokenKind = Token.Note;\n\n                for (let i = 0; i < currNote.length; i++) {\n                    let noteChar = currNote.charAt(i);\n                    switch (noteChar) {\n                        case 'c': case 'C': note = 1; prevNote = true; break;\n                        case 'd': case 'D': note = 3; prevNote = true; break;\n                        case 'e': case 'E': note = 5; prevNote = true; break;\n                        case 'f': case 'F': note = 6; prevNote = true; break;\n                        case 'g': case 'G': note = 8; prevNote = true; break;\n                        case 'a': case 'A': note = 10; prevNote = true; break;\n                        case 'B': note = 12; prevNote = true; break;\n                        case 'r': case 'R': hz = 0; prevNote = false; break;\n                        case '#': note++; prevNote = false; break;\n                        case 'b': if (prevNote) note--; else { note = 12; prevNote = true; } break;\n                        case ',':\n                            consumeToken();\n                            prevNote = false;\n                            break;\n                        case '!':\n                            tokenKind = Token.Hz;\n                            prevNote = false;\n                            break;\n                        case '@':\n                            consumeToken();\n                            tokenKind = Token.EnvelopeA;\n                            prevNote = false;\n                            break;\n                        case '~':\n                            consumeToken();\n                            tokenKind = Token.WaveForm;\n                            prevNote = false;\n                            break;\n                        case ':':\n                            consumeToken();\n                            tokenKind = Token.Beat;\n                            prevNote = false;\n                            break;\n                        case '-':\n                            consumeToken();\n                            tokenKind = Token.Tempo;\n                            prevNote = false;\n                            break;\n                        case '^':\n                            consumeToken();\n                            tokenKind = Token.EndHz;\n                            break;\n                        default:\n                            if (tokenKind == Token.Note)\n                                tokenKind = Token.Octave;\n                            token += noteChar;\n                            prevNote = false;\n                            break;\n                    }\n                }\n                consumeToken();\n\n                if (note && hz < 0) {\n                    const keyNumber = note + (12 * (octave - 1));\n                    hz = freqs.getNumber(NumberFormat.UInt16LE, keyNumber * 2) || 0;\n                }\n\n                let currMs = ms\n\n                if (currMs <= 0) {\n                    const beat = Math.idiv(15000, tempo);\n                    currMs = duration * beat\n                }\n\n                if (hz < 0) {\n                    // no frequency specified, so no duration\n                } else if (hz == 0) {\n                    timePos += currMs\n                } else {\n                    if (endHz < 0) {\n                        endHz = hz;\n                    }\n\n                    sndInstrPtr = 0\n                    addForm(envA, 0, 255, 0)\n                    addForm(envD, 255, envS, envA)\n                    addForm(currMs - (envA + envD), envS, envS, envD + envA)\n                    addForm(envR, envS, 0, currMs)\n\n                    this.queuePlayInstructions(timePos - now, sndInstr.slice(0, sndInstrPtr))\n                    endHz = -1;\n                    timePos += currMs // don't add envR - it's supposed overlap next sound\n                }\n\n                let timeLeft = timePos - now\n                if (timeLeft > 200) {\n                    pause(timeLeft - 100)\n                    now = control.millis() - startTime\n                }\n            }\n        }\n    }\n\n    //% blockId=music_song_field_editor\n    //% block=\"song $song\"\n    //% song.fieldEditor=musiceditor\n    //% song.fieldOptions.decompileLiterals=true\n    //% song.fieldOptions.taggedTemplate=\"hex;assets.song\"\n    //% song.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% song.fieldOptions.decompileArgumentAsString=\"true\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% help=music/create-song\n    export function createSong(song: Buffer): Playable {\n        return new sequencer.Song(song);\n    }\n\n    export function playInstructions(when: number, instructions: Buffer) {\n        queuePlayInstructions(when, instructions);\n    }\n\n    export function lookupFrequency(note: number) {\n        return freqs.getNumber(NumberFormat.UInt16LE, note * 2) || 0\n    }\n\n    //% fixedInstance whenUsed block=\"ba ding\"\n    export const baDing = new Melody('b5:1 e6:3')\n\n    //% fixedInstance whenUsed block=\"wawawawaa\"\n    export const wawawawaa = new Melody('~15 e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8')\n\n    //% fixedInstance whenUsed block=\"jump up\"\n    export const jumpUp = new Melody('c5:1 d e f g')\n\n    //% fixedInstance whenUsed block=\"jump down\"\n    export const jumpDown = new Melody('g5:1 f e d c')\n\n    //% fixedInstance whenUsed block=\"power up\"\n    export const powerUp = new Melody('g4:1 c5 e g:2 e:1 g:3')\n\n    //% fixedInstance whenUsed block=\"power down\"\n    export const powerDown = new Melody('g5:1 d# c g4:2 b:1 c5:3')\n\n    //% fixedInstance whenUsed block=\"magic wand\"\n    export const magicWand = new Melody('F#6:1-300 G# A# B C7# D# F F# G# A# B:6')\n    //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n\n    //% fixedInstance whenUsed block=\"siren\"\n    export const siren = new Melody('a4 d5 a4 d5 a4 d5')\n\n    //% fixedInstance whenUsed block=\"pew pew\"\n    export const pewPew = new Melody('!1200,200^50')\n\n    //% fixedInstance whenUsed block=\"knock\"\n    export const knock = new Melody('~4 @0,0,255,150 !300,1 !211,1')\n\n    //% fixedInstance whenUsed block=\"footstep\"\n    export const footstep = new Melody('~4 @0,0,60,50 !200,1')\n\n    //% fixedInstance whenUsed block=\"thump\"\n    export const thump = new Melody('~4 @0,0,255,150 !100,1')\n\n    //% fixedInstance whenUsed block=\"small crash\"\n    export const smallCrash = new Melody('~4 @10,490,0,1 !800,1')\n\n    //% fixedInstance whenUsed block=\"big crash\"\n    export const bigCrash = new Melody('~4 @10,990,0,1 !400,1')\n\n    //% fixedInstance whenUsed block=\"zapped\"\n    export const zapped = new Melody('~16 @10,490,0,0 !1600,500^1')\n\n    //% fixedInstance whenUsed block=\"buzzer\"\n    export const buzzer = new Melody('~16 @10,0,255,250 !2000,300')\n\n    //% fixedInstance whenUsed block=\"sonar\"\n    export const sonar = new Melody('~16 @10,1500,0,0 !200,1 !200,1500^190')\n\n    //% fixedInstance whenUsed block=\"spooky\"\n    export const spooky = new Melody('~16 @700,1300,0,0 !100,1 ~18 !108,2000')\n\n    //% fixedInstance whenUsed block=\"beam up\"\n    export const beamUp = new Melody('~18 @10,1500,0,0 !200,1500^4000')\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    //% block=\"2\"\n    Double = 32,\n    //% block=\"4\",\n    Breve = 64,\n    //% block=\"1/3\",\n    Triplet = 128\n}\n\nnamespace music {\n\n    let beatsPerMinute: number;\n\n    /**\n    * Play a tone.\n    * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n    */\n    //% help=music/ring-tone\n    //% blockId=music_ring block=\"ring tone|at %note=device_note\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music inBasicCategory=true\n    //% weight=75 blockGap=8\n    //% group=\"Tone\"\n    export function ringTone(frequency: number) {\n        playTone(frequency, 0);\n    }\n\n    /**\n    * Rest, or play silence, for some time (in milliseconds).\n    * @param ms rest duration in milliseconds (ms), eg: BeatFraction.Half\n    */\n    //% help=music/rest\n    //% blockId=music_rest block=\"rest|for %duration=device_beat\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music\n    //% weight=74\n    //% group=\"Tone\"\n    export function rest(ms: number) {\n        playTone(0, Math.max(ms, 20));\n    }\n\n    function init() {\n        if (!beatsPerMinute) beatsPerMinute = 120;\n    }\n\n    /**\n     * Return the duration of a beat in milliseconds (the beat fraction).\n     * @param fraction the fraction of the current whole note, eg: BeatFraction.Half\n     */\n    //% help=music/beat\n    //% blockId=device_beat block=\"%fraction|beat\"\n    //% weight=9 blockGap=8\n    //% group=\"Tempo\"\n    export function beat(fraction?: BeatFraction): number {\n        init();\n        if (fraction == null) fraction = BeatFraction.Whole;\n        let beat = 60000 / beatsPerMinute;\n        switch (fraction) {\n            case BeatFraction.Half: beat /= 2; break;\n            case BeatFraction.Quarter: beat /= 4; break;\n            case BeatFraction.Eighth: beat /= 8; break;\n            case BeatFraction.Sixteenth: beat /= 16; break;\n            case BeatFraction.Double: beat *= 2; break;\n            case BeatFraction.Breve: beat *= 4; break;\n            case BeatFraction.Triplet: beat /= 3; break;\n        }\n        return beat >> 0;\n    }\n\n    /**\n     * Return the tempo in beats per minute (bpm).\n     * 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\n    //% blockId=device_tempo block=\"tempo (bpm)\"\n    //% weight=64\n    //% group=\"Tempo\"\n    export function tempo(): number {\n        init();\n        return beatsPerMinute;\n    }\n\n    /**\n     * Change the tempo up or down by some amount of beats per minute (bpm).\n     * @param bpm The change in beats per minute to the tempo, eg: 20\n     */\n    //% help=music/change-tempo-by weight=37\n    //% blockId=device_change_tempo block=\"change tempo by %value|(bpm)\"\n    //% weight=66 blockGap=8\n    //% group=\"Tempo\"\n    export function changeTempoBy(bpm: number): void {\n        init();\n        setTempo(beatsPerMinute + bpm);\n    }\n\n    /**\n     * Set the tempo a number of beats per minute (bpm).\n     * @param bpm The new tempo in beats per minute, eg: 120\n     */\n    //% help=music/set-tempo\n    //% blockId=device_set_tempo block=\"set tempo to %value|(bpm)\"\n    //% bpm.min=4 bpm.max=400\n    //% weight=65 blockGap=8\n    //% group=\"Tempo\"\n    export function setTempo(bpm: number): void {\n        init();\n        if (bpm > 0) {\n            beatsPerMinute = Math.max(1, bpm >> 0);\n        }\n    }\n}\n","ns.ts":"\n/**\n * Generation of music tones.\n */\n//% color=#E30FC0 weight=90 icon=\"\\uf025\"\n//% blockGap=8\n//% groups='[\"Songs\", \"Sounds\", \"Tone\",  \"Volume\", \"Tempo\"]'\nnamespace music {\n}","piano.ts":"namespace music {\n    /**\n     * Get the frequency of a note.\n     * @param name the note name, eg: Note.C\n     */\n    //% weight=1 help=music/note-frequency\n    //% blockId=device_note block=\"%note\"\n    //% shim=TD_ID\n    //% color=\"#FFFFFF\" colorSecondary=\"#FFFFFF\" colorTertiary=\"#D83B01\"\n    //% note.fieldEditor=\"note\" note.defl=\"262\"\n    //% note.fieldOptions.decompileLiterals=true\n    //% useEnumVal=1\n    //% weight=10 blockGap=8\n    //% group=\"Tone\"\n    export function noteFrequency(name: Note): number {\n        return name;\n    }\n}","playable.ts":"namespace music {\n    export enum PlaybackMode {\n        //% block=\"until done\"\n        UntilDone,\n        //% block=\"in background\"\n        InBackground,\n        //% block=\"looping in background\"\n        LoopingInBackground\n    }\n\n    let stateStack: PlayableState[];\n\n    class PlayableState {\n        looping: Playable[];\n        constructor() {\n            this.looping = [];\n        }\n\n        stopLooping() {\n            for (const p of this.looping) {\n                p.stopped = true;\n            }\n            this.looping = [];\n        }\n    }\n\n    function state() {\n        _init();\n        return stateStack[stateStack.length - 1];\n    }\n\n    function _init() {\n        if (stateStack) return;\n        stateStack = [new PlayableState()];\n\n        game.addScenePushHandler(() => {\n            stateStack.push(new PlayableState());\n        });\n\n        game.addScenePopHandler(() => {\n            stateStack.pop();\n            if (stateStack.length === 0) stateStack.push(new PlayableState());\n        });\n    }\n\n    export class Playable {\n        stopped: boolean;\n        constructor() {\n\n        }\n\n        play(playbackMode: PlaybackMode) {\n            // subclass\n        }\n\n        loop() {\n            state().looping.push(this);\n            this.stopped = false;\n\n            control.runInParallel(() => {\n                while (!this.stopped) {\n                    this.play(PlaybackMode.UntilDone);\n                }\n            });\n        }\n    }\n\n    export class MelodyPlayable extends Playable {\n        constructor(public melody: Melody) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                this.melody.play(music.volume());\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                this.melody.playUntilDone(music.volume());\n            }\n            else {\n                this.melody.loop(music.volume());\n            }\n        }\n    }\n\n    export class TonePlayable extends Playable {\n        constructor(public pitch: number, public duration: number) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                control.runInParallel(() => music.playTone(this.pitch, this.duration));\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                music.playTone(this.pitch, this.duration);\n                if (this.duration > 2000) {\n                    pause(this.duration);\n                }\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n    /**\n     * Play a song, melody, or other sound. The music plays until finished or can play as a\n     * background task.\n     * @param toPlay the song or melody to play\n     * @param playbackMode play the song or melody until it's finished or as background task\n     */\n    //% blockId=\"music_playable_play\"\n    //% block=\"play $toPlay $playbackMode\"\n    //% toPlay.shadow=music_melody_playable\n    //% group=\"Sounds\"\n    //% help=\"music/play\"\n    export function play(toPlay: Playable, playbackMode: PlaybackMode) {\n        toPlay.play(playbackMode);\n    }\n\n    /**\n     * Create a Playable object for a melody.\n     * @param melody the melody to make playable\n     */\n    //% blockId=\"music_melody_playable\"\n    //% block=\"sound $melody\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    //% blockHidden\n    //% help=music/melody-playable\n    export function melodyPlayable(melody: Melody): Playable {\n        return new MelodyPlayable(melody);\n    }\n\n    /**\n     * Create a Playable object for a melody string containg notes.\n     * @param melody the melody string to make playable\n     */\n    //% blockId=\"music_string_playable\"\n    //% block=\"melody $melody at tempo $tempo|(bpm)\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% melody.shadow=melody_editor\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% help=music/string-playable\n    export function stringPlayable(melody: string, tempo: number): Playable {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        return new MelodyPlayable(new Melody(formattedMelody));\n    }\n\n    /**\n     * Create a Playable object for a single tone and its duration.\n     * @param note the note or tone frequency to play\n     * @param duration the duration of the tone in milliseconds (ms)\n     */\n    //% blockId=\"music_tone_playable\"\n    //% block=\"tone $note for $duration\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Tone\"\n    //% duplicateShadowOnDrag\n    //% note.shadow=device_note\n    //% duration.shadow=device_beat\n    //% parts=\"headphone\"\n    //% help=music/tone-playable\n    export function tonePlayable(note: number, duration: number): Playable {\n        return new TonePlayable(note, duration);\n    }\n\n    export function _stopPlayables() {\n        state().stopLooping();\n    }\n}","pxt.json":"{\n    \"name\": \"mixer---stm32\",\n    \"description\": \"The music library with a mixer\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"SoundOutput.h\",\n        \"sound.cpp\",\n        \"melody.h\",\n        \"melody.cpp\",\n        \"melody.ts\",\n        \"piano.ts\",\n        \"legacy.ts\",\n        \"ns.ts\",\n        \"targetoverrides.ts\",\n        \"music.ts\",\n        \"soundEffect.ts\",\n        \"instrument.ts\",\n        \"sequencer.ts\",\n        \"playable.ts\",\n        \"pxtparts.json\",\n        \"headphone.svg\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","pxtparts.json":"{\n    \"headphone\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"image\": \"headphone.svg\",\n            \"width\": 142,\n            \"height\": 180,\n            \"pinDistance\": 20,\n            \"pinLocations\": [\n                {\n                    \"x\": 17,\n                    \"y\": 11\n                },\n                {\n                    \"x\": 55,\n                    \"y\": 50\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"A0\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","sequencer.ts":"namespace music.sequencer {\n    const SEQUENCER_STOP_MESSAGE = 3243;\n    const SEQUENCER_TICK_MESSAGE = 3244;\n    const SEQUENCER_STATE_CHANGE_MESSAGE = 3245;\n    const SEQUENCER_LOOPED_MESSAGE = 3246;\n\n    export class Sequencer {\n        currentTick: number;\n        isPlaying: boolean;\n        isLooping: boolean;\n        isRunning: boolean;\n\n        constructor(public song: Song) {\n            this.currentTick = 0;\n            this.isPlaying = false;\n            this.isLooping = false;\n        }\n\n        start(loop: boolean) {\n            this.currentTick = 0;\n            this.isLooping = loop;\n            this.isPlaying = true;\n\n            if (this.isRunning) return;\n            this.isRunning = true;\n\n            control.runInParallel(() => {\n                while (this.isPlaying) {\n                    this.scheduleCurrentTick();\n\n                    this.currentTick ++;\n\n                    if (this.currentTick >= this.song.beatsPerMeasure * this.song.measures * this.song.ticksPerBeat) {\n                        if (this.isLooping) this.currentTick = 0;\n                        else this.isPlaying = false;\n                    }\n\n                    pause(this.tickToMs(1))\n                }\n                this.isRunning = false;\n            })\n        }\n\n        stop() {\n            this.isPlaying = false;\n        }\n\n        tickToMs(ticks: number) {\n            return ((60000 / this.song.beatsPerMinute) / this.song.ticksPerBeat) * ticks;\n        }\n\n        protected scheduleCurrentTick() {\n            for (const track of this.song.tracks) {\n                if (track.currentNoteEvent.startTick === this.currentTick) {\n                    if (track.isMelodicTrack) {\n                        this.scheduleMelodicTrack(track as MelodicTrack);\n                    }\n                    else {\n                        this.scheduleDrumTrack(track as DrumTrack);\n                    }\n\n                    track.advanceNoteEvent();\n                }\n            }\n        }\n\n        protected scheduleMelodicTrack(track: MelodicTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderInstrument(\n                        track.instrument,\n                        lookupFrequency(track.currentNoteEvent.getNote(i, track.instrument.octave)),\n                        this.tickToMs(track.currentNoteEvent.endTick - track.currentNoteEvent.startTick),\n                        music.volume()\n                    )\n                );\n            }\n        }\n\n        protected scheduleDrumTrack(track: DrumTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderDrumInstrument(\n                        track.drums[track.currentNoteEvent.getNote(i, undefined)],\n                        music.volume()\n                    )\n                );\n            }\n        }\n    }\n\n    let activeSimSequencers: _SimulatorSequencer[];\n    export function _stopAllSimSequencers() {\n        if (activeSimSequencers) {\n            for (const seq of activeSimSequencers) {\n                seq.stop();\n                seq.dispose();\n            }\n            activeSimSequencers = [];\n        }\n    }\n\n    // Simulator only! Does nothing on hardware\n    export class _SimulatorSequencer {\n        protected id: number;\n\n        constructor() {\n            if (!activeSimSequencers) activeSimSequencers = [];\n            activeSimSequencers.push(this);\n            this.id = _createSequencer();\n            this.setVolume(music.volume());\n        }\n\n        play(song: Buffer, loop: boolean) {\n            this.setVolume(music.volume());\n            _sequencerPlaySong(this.id, song, loop)\n        }\n\n        stop() {\n            _sequencerStop(this.id);\n        }\n\n        setVolume(volume: number) {\n            _sequencerSetVolume(this.id, volume);\n        }\n\n        setTrackVolume(trackIndex: number, volume: number) {\n            _sequencerSetTrackVolume(this.id, trackIndex, volume)\n        }\n\n        setDrumTrackVolume(trackIndex: number, drumIndex: number, volume: number) {\n            _sequencerSetDrumTrackVolume(this.id, drumIndex, trackIndex, volume)\n        }\n\n        state() {\n            return _sequencerState(this.id) || \"stop\";\n        }\n\n        currentTick() {\n            return _sequencerCurrentTick(this.id);\n        }\n\n        dispose() {\n            _sequencerDispose(this.id);\n        }\n\n        onTick(handler: (tick: number) => void) {\n            control.onEvent(SEQUENCER_TICK_MESSAGE, this.id, () => {\n                handler(this.currentTick());\n            });\n        }\n\n        onStateChange(handler: (state: string) => void) {\n            control.onEvent(SEQUENCER_STATE_CHANGE_MESSAGE, this.id, () => {\n                handler(this.state());\n            });\n        }\n\n        onStop(handler: () => void) {\n            control.onEvent(SEQUENCER_STOP_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n\n        onLooped(handler: () => void) {\n            control.onEvent(SEQUENCER_LOOPED_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n    }\n\n    //% promise\n    //% shim=music::_createSequencer\n    declare function _createSequencer(): number\n\n    //% shim=music::_sequencerState\n    declare function _sequencerState(id: number): string;\n\n    //% shim=music::_sequencerCurrentTick\n    declare function _sequencerCurrentTick(id: number): number;\n\n    //% shim=music::_sequencerPlaySong\n    declare function _sequencerPlaySong(id: number, song: Buffer, loop: boolean): void;\n\n    //% shim=music::_sequencerStop\n    declare function _sequencerStop(id: number): void;\n\n    //% shim=music::_sequencerSetVolume\n    declare function _sequencerSetVolume(id: number, volume: number): void;\n\n    //% shim=music::_sequencerSetVolumeForAll\n    declare function _sequencerSetVolumeForAll(volume: number): void;\n\n    //% shim=music::_sequencerSetTrackVolume\n    declare function _sequencerSetTrackVolume(id: number, trackIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerSetDrumTrackVolume\n    declare function _sequencerSetDrumTrackVolume(id: number, trackIndex: number, drumIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerDispose\n    declare function _sequencerDispose(id: number): void;\n}","sound.cpp":"// to be overridden\n","soundEffect.ts":"enum WaveShape {\n    //% block=\"sine\"\n    Sine = 0,\n    //% block=\"sawtooth\"\n    Sawtooth = 1,\n    //% block=\"triangle\"\n    Triangle = 2,\n    //% block=\"square\"\n    Square = 3,\n    //% block=\"noise\"\n    Noise = 4\n}\n\nenum InterpolationCurve {\n    //% block=\"linear\"\n    Linear,\n    //% block=\"curve\"\n    Curve,\n    //% block=\"logarithmic\"\n    Logarithmic\n}\n\nenum SoundExpressionEffect {\n    //% block=\"none\"\n    None = 0,\n    //% block=\"vibrato\"\n    Vibrato = 1,\n    //% block=\"tremolo\"\n    Tremolo = 2,\n    //% block=\"warble\"\n    Warble = 3\n}\n\nenum SoundExpressionPlayMode {\n    //% block=\"until done\"\n    UntilDone,\n    //% block=\"in background\"\n    InBackground\n}\n\nnamespace music {\n    export class SoundEffect extends Playable {\n        waveShape: WaveShape;\n        startFrequency: number;\n        endFrequency: number;\n        startVolume: number;\n        endVolume: number;\n        duration: number;\n        effect: SoundExpressionEffect;\n        interpolation: InterpolationCurve;\n\n        constructor() {\n            super();\n            this.waveShape = WaveShape.Sine;\n            this.startFrequency = 5000;\n            this.endFrequency = 1;\n            this.startVolume = 255;\n            this.endVolume = 0;\n            this.duration = 1000;\n            this.effect = SoundExpressionEffect.None;\n            this.interpolation = InterpolationCurve.Linear;\n        }\n\n        toBuffer(volume?: number) {\n            if (volume === undefined) volume = music.volume();\n\n            return soundToInstructionBuffer(\n                this.waveShape,\n                this.startFrequency,\n                this.endFrequency,\n                this.startVolume,\n                this.endVolume,\n                this.duration,\n                this.effect,\n                this.interpolation,\n                20,\n                1,\n                volume\n            );\n        }\n\n        play(playbackMode: PlaybackMode) {\n            const toPlay = this.toBuffer(music.volume());\n            if (playbackMode === PlaybackMode.InBackground) {\n                queuePlayInstructions(0, toPlay);\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                queuePlayInstructions(0, toPlay);\n                pause(this.duration)\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n\n    /**\n     * Play a SoundEffect.\n     * @param sound the SoundEffect to play\n     * @param mode the play mode, play until done or in the background\n     */\n    //% blockId=soundExpression_playSoundEffect\n    //% block=\"play sound $sound $mode\"\n    //% weight=30\n    //% help=music/play-sound-effect\n    //% blockGap=8\n    //% group=\"Sounds\"\n    //% deprecated=1\n    export function playSoundEffect(sound: SoundEffect, mode: SoundExpressionPlayMode) {\n        const toPlay = sound.toBuffer(music.volume());\n\n        queuePlayInstructions(0, toPlay);\n        if (mode === SoundExpressionPlayMode.UntilDone) {\n            pause(sound.duration);\n        }\n    }\n\n    /**\n     * Create a sound expression from a set of sound effect parameters.\n     * @param waveShape waveform of the sound effect\n     * @param startFrequency starting frequency for the sound effect waveform\n     * @param endFrequency ending frequency for the sound effect waveform\n     * @param startVolume starting volume of the sound, or starting amplitude\n     * @param endVolume ending volume of the sound, or ending amplitude\n     * @param duration the amount of time in milliseconds (ms) that sound will play for\n     * @param effect the effect to apply to the waveform or volume\n     * @param interpolation interpolation method for frequency scaling\n     */\n    //% blockId=soundExpression_createSoundEffect\n    //% help=music/create-sound-effect\n    //% block=\"$waveShape|| start frequency $startFrequency end frequency $endFrequency duration $duration start volume $startVolume end volume $endVolume effect $effect interpolation $interpolation\"\n    //% waveShape.defl=WaveShape.Sine\n    //% waveShape.fieldEditor=soundeffect\n    //% waveShape.fieldOptions.useMixerSynthesizer=true\n    //% startFrequency.defl=5000\n    //% startFrequency.min=0\n    //% startFrequency.max=5000\n    //% endFrequency.defl=0\n    //% endFrequency.min=0\n    //% endFrequency.max=5000\n    //% startVolume.defl=255\n    //% startVolume.min=0\n    //% startVolume.max=255\n    //% endVolume.defl=0\n    //% endVolume.min=0\n    //% endVolume.max=255\n    //% duration.defl=500\n    //% duration.min=1\n    //% duration.max=9999\n    //% effect.defl=SoundExpressionEffect.None\n    //% interpolation.defl=InterpolationCurve.Linear\n    //% compileHiddenArguments=true\n    //% inlineInputMode=\"variable\"\n    //% inlineInputModeLimit=3\n    //% expandableArgumentBreaks=\"3,5\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=20\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    export function createSoundEffect(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve): SoundEffect {\n        const result = new SoundEffect();\n\n        result.waveShape = waveShape;\n        result.startFrequency = startFrequency;\n        result.endFrequency = endFrequency;\n        result.startVolume = startVolume;\n        result.endVolume = endVolume;\n        result.duration = duration;\n        result.effect = effect;\n        result.interpolation = interpolation;\n\n        return result;\n    }\n\n    interface Step {\n        frequency: number;\n        volume: number;\n    }\n\n     export function soundToInstructionBuffer(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve, fxSteps: number, fxRange: number, globalVolume: number) {\n        const steps: Step[] = [];\n\n        // Optimize the simple case\n        if (interpolation === InterpolationCurve.Linear && effect === SoundExpressionEffect.None) {\n            steps.push({\n                frequency: startFrequency,\n                volume: (startVolume / 255) * globalVolume,\n            })\n            steps.push({\n                frequency: endFrequency,\n                volume: (endVolume / 255) * globalVolume,\n            })\n        }\n        else {\n\n            fxSteps = Math.min(fxSteps, Math.floor(duration / 5))\n\n            const getVolumeAt = (t: number) => ((startVolume + t * (endVolume - startVolume) / duration) / 255) * globalVolume;\n            let getFrequencyAt: (t: number) => number;\n\n            switch (interpolation) {\n                case InterpolationCurve.Linear:\n                    getFrequencyAt = t => startFrequency + t * (endFrequency - startFrequency) / duration;\n                    break;\n                case InterpolationCurve.Curve:\n                    getFrequencyAt = t => startFrequency + (endFrequency - startFrequency) * Math.sin(t / duration * (Math.PI / 2));\n                    break;\n                case InterpolationCurve.Logarithmic:\n                    getFrequencyAt = t => startFrequency + (Math.log(1 + 9 * (t / duration)) / Math.log(10)) * (endFrequency - startFrequency)\n                    break;\n            }\n\n            const timeSlice = duration / fxSteps;\n\n            for (let i = 0; i < fxSteps; i++) {\n                const newStep = {\n                    frequency: getFrequencyAt(i * timeSlice),\n                    volume: getVolumeAt(i * timeSlice)\n                };\n\n                if (effect === SoundExpressionEffect.Tremolo) {\n                    if (i % 2 === 0) {\n                        newStep.volume = Math.max(newStep.volume - fxRange * 500, 0)\n                    }\n                    else {\n                        newStep.volume = Math.min(newStep.volume + fxRange * 500, 1023)\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Vibrato) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 100, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 100\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Warble) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 1000, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 1000\n                    }\n                }\n\n                steps.push(newStep)\n            }\n        }\n\n        const out = control.createBuffer(12 * (steps.length - 1));\n        const stepDuration = Math.floor(duration / (steps.length - 1))\n\n        for (let i = 0; i < steps.length - 1; i++) {\n            const offset = i * 12;\n            out.setNumber(NumberFormat.UInt8LE, offset, waveToValue(waveShape));\n            out.setNumber(NumberFormat.UInt16LE, offset + 2, steps[i].frequency);\n            out.setNumber(NumberFormat.UInt16LE, offset + 4, stepDuration);\n            out.setNumber(NumberFormat.UInt16LE, offset + 6, steps[i].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 8, steps[i + 1].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 10, steps[i + 1].frequency);\n        }\n\n        return out;\n    }\n\n    function waveToValue(wave: WaveShape) {\n        switch (wave) {\n            case WaveShape.Square: return 15;\n            case WaveShape.Sine: return 3;\n            case WaveShape.Triangle: return 1;\n            case WaveShape.Noise: return 18;\n            case WaveShape.Sawtooth: return 2;\n        }\n    }\n\n\n    /**\n     * Generate a random similar sound effect to the given one.\n     *\n     * @param sound the sound effect\n     */\n    //% blockId=soundExpression_generateSimilarSound\n    //% block=\"randomize $sound\"\n    //% sound.shadow=soundExpression_createSoundEffect\n    //% weight=0 help=music/randomize-sound\n    //% blockGap=8\n    //% group=\"Sounds\"\n    export function randomizeSound(sound: SoundEffect) {\n        const res = new SoundEffect();\n        res.waveShape = sound.waveShape;\n        res.startFrequency = sound.startFrequency;\n        res.endFrequency = sound.endFrequency;\n        res.startVolume = sound.startVolume;\n        res.endVolume = sound.endVolume;\n        res.duration = sound.duration;\n        res.effect = sound.effect;\n        res.interpolation = randomInterpolation();\n\n        res.duration = Math.clamp(\n            Math.min(100, res.duration),\n            Math.max(2000, res.duration),\n            res.duration + (Math.random() - 0.5) * res.duration,\n        );\n\n        if (res.waveShape === WaveShape.Noise) {\n            // The primary waveforms don't produce sounds that are similar to noise,\n            // but adding an effect sorta does\n            if (Math.percentChance(20)) {\n                res.waveShape = randomWave();\n                res.effect = randomEffect();\n            }\n        }\n        else {\n            res.waveShape = randomWave();\n\n            // Adding an effect can drastically alter the sound, so keep it\n            // at a low percent chance unless there already is one\n            if (res.effect !== SoundExpressionEffect.None || Math.percentChance(10)) {\n                res.effect = randomEffect();\n            }\n        }\n\n        // Instead of randomly changing the frequency, change the slope and choose\n        // a new start frequency. This keeps a similar profile to the sound\n        const oldFrequencyDifference = res.endFrequency - res.startFrequency;\n        let newFrequencyDifference = oldFrequencyDifference + (oldFrequencyDifference * 2) * (Math.random() - 0.5);\n\n        if (Math.sign(oldFrequencyDifference) !== Math.sign(newFrequencyDifference)) {\n            newFrequencyDifference *= -1;\n        }\n\n        newFrequencyDifference = Math.clamp(-5000, 5000, newFrequencyDifference);\n\n        res.startFrequency = Math.clamp(\n            Math.max(-newFrequencyDifference, 1),\n            Math.clamp(1, 5000, 5000 - newFrequencyDifference),\n            Math.random() * 5000,\n        );\n\n        res.endFrequency = Math.clamp(1, 5000, res.startFrequency + newFrequencyDifference);\n\n        // Same strategy for volume\n        const oldVolumeDifference = res.endVolume - res.startVolume;\n        let newVolumeDifference = oldVolumeDifference + oldVolumeDifference * (Math.random() - 0.5);\n\n        newVolumeDifference = Math.clamp(-255, 255, newVolumeDifference);\n\n        if (Math.sign(oldVolumeDifference) !== Math.sign(newVolumeDifference)) {\n            newVolumeDifference *= -1;\n        }\n\n        res.startVolume = Math.clamp(\n            Math.max(-newVolumeDifference, 0),\n            Math.clamp(0, 255, 255 - newVolumeDifference),\n            Math.random() * 255,\n        );\n\n        res.endVolume = Math.clamp(0, 255, res.startVolume + newVolumeDifference);\n\n        return res;\n    }\n\n    function randomWave() {\n        switch (Math.randomRange(0, 3)) {\n            case 1: return WaveShape.Sawtooth;\n            case 2: return WaveShape.Square;\n            case 3: return WaveShape.Triangle;\n            case 0:\n            default:\n                return WaveShape.Sine;\n        }\n    }\n\n    function randomEffect() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return SoundExpressionEffect.Warble;\n            case 2: return  SoundExpressionEffect.Tremolo;\n            case 0:\n            default:\n                return SoundExpressionEffect.Vibrato;\n        }\n    }\n\n    function randomInterpolation() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return InterpolationCurve.Linear;\n            case 2: return  InterpolationCurve.Curve;\n            case 0:\n            default:\n                return InterpolationCurve.Logarithmic;\n        }\n    }\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n}","targetoverrides.ts":"\n","test.ts":"for(let i = 1000; i > 0; i -= 50)\n    music.playTone(440, i)\n\nfor(let i = 0; i < 1000; i += 20)\n    music.playTone(440, i)\n"},"mixer---rp2040":{"SoundOutput.h":"#include \"RP2040PWM.h\"\n#include \"Synthesizer.h\"\n#include \"Mixer.h\"\n\nnamespace jacdac {\nvoid setJackRouterOutput(int output);\n}\n\nclass SoundOutput {\n  public:\n    RP2040PWM dac;\n\n    SoundOutput(DataSource &data) : dac(*LOOKUP_PIN(JACK_SND), data, 44000) {\n        jacdac::setJackRouterOutput(-1);\n    }\n\n    void setOutput(int output) { jacdac::setJackRouterOutput(output); }\n};\n","headphone.svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"142\" height=\"180\" viewBox=\"0 0 142 180\"><rect ry=\".3\" rx=\"1\" y=\"58.615\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><rect ry=\".3\" rx=\"1\" y=\"32.043\" x=\"-8.878\" height=\"23.571\" width=\"17.143\" transform=\"rotate(-45)\" fill=\"#b3b3b3\"/><path d=\"M.346 7.296c-.394.39-.31 4.797-.18 4.898l13.404 10.18c.117.12.337 4.76.73 4.368l5.506-5.56.01.01 6.51-6.444c.39-.392-4.25-.614-4.366-.73L11.777.612c-.1-.132-4.51-.215-4.898.18L4.087 3.636l-.01-.01-3.73 3.67z\" fill=\"#b3b3b3\"/><rect ry=\"6.85\" rx=\"4.571\" y=\"84.758\" x=\"-20.128\" height=\"75.571\" width=\"39.643\" transform=\"rotate(-45)\"/><rect ry=\".374\" rx=\"1.038\" y=\"29.442\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"55.939\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\".374\" rx=\"1.038\" y=\"82.392\" x=\"-8.925\" height=\"2.228\" width=\"17.238\" transform=\"rotate(-45)\" fill=\"#fff\"/><rect ry=\"2.317\" rx=\"2.183\" y=\"158.876\" x=\"-9.774\" height=\"25.568\" width=\"18.935\" transform=\"rotate(-45)\"/><path d=\"M128.588 128.82s14.97 11.165 7.547 26.35c-8.426 17.24-25.57 20.653-25.57 20.653\" fill=\"none\" stroke=\"#000\" stroke-width=\"6.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>","instrument.ts":"namespace music.sequencer {\n    const BUFFER_SIZE = 12;\n\n    let currentSequencer: sequencer.Sequencer;\n\n    /**\n     * Byte encoding format for songs\n     * FIXME: should this all be word aligned?\n     *\n     * song(7 + length of all tracks bytes)\n     *     0 version\n     *     1 beats per minute\n     *     3 beats per measure\n     *     4 ticks per beat\n     *     5 measures\n     *     6 number of tracks\n     *     ...tracks\n     *\n     * track(6 + instrument length + note length bytes)\n     *     0 id\n     *     1 flags\n     *     2 instruments byte length\n     *     4...instrument\n     *     notes byte length\n     *     ...note events\n     *\n     * instrument(28 bytes)\n     *     0 waveform\n     *     1 amp attack\n     *     3 amp decay\n     *     5 amp sustain\n     *     7 amp release\n     *     9 amp amp\n     *     11 pitch attack\n     *     13 pitch decay\n     *     15 pitch sustain\n     *     17 pitch release\n     *     19 pitch amp\n     *     21 amp lfo freq\n     *     22 amp lfo amp\n     *     24 pitch lfo freq\n     *     25 pitch lfo amp\n     *     27 octave\n     *\n     * drum(5 + 7 * steps bytes)\n     *     0 steps\n     *     1 start freq\n     *     3 start amp\n     *     5...steps\n     *\n     * drum step(7 bytes)\n     *     0 waveform\n     *     1 freq\n     *     3 volume\n     *     5 duration\n     *\n     * note event(5 + 1 * polyphony bytes)\n     *     0 start tick\n     *     2 end tick\n     *     4 polyphony\n     *     5...notes(1 byte each)\n     *\n     * note (1 byte)\n     *     lower six bits = note - (instrumentOctave - 2) * 12\n     *     upper two bits are the enharmonic spelling:\n     *          0 = normal\n     *          1 = flat\n     *          2 = sharp\n     */\n\n    export class Song extends Playable {\n        tracks: Track[];\n\n        constructor(public buf: Buffer) {\n            super();\n            this.tracks = [];\n\n            let currentOffset = 7;\n            for (let i = 0; i < this.numberOfTracks; i++) {\n                let track: Track = new MelodicTrack(this.buf, currentOffset);\n\n                if (!track.isMelodicTrack) {\n                    track = new DrumTrack(this.buf, currentOffset)\n                }\n\n                this.tracks.push(track);\n                currentOffset += track.byteLength;\n            }\n        }\n\n        get version(): number {\n            return this.buf[0];\n        }\n\n        set version(value: number) {\n            this.buf[0] = value;\n        }\n\n        get beatsPerMinute(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, 1);\n        }\n\n        set beatsPerMinute(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, 1, value);\n        }\n\n        get beatsPerMeasure(): number {\n            return this.buf[3];\n        }\n\n        set beatsPerMeasure(value: number) {\n            this.buf[3] = value;\n        }\n\n        get ticksPerBeat(): number {\n            return this.buf[4];\n        }\n\n        set ticksPerBeat(value: number) {\n            this.buf[4] = value;\n        }\n\n        get measures(): number {\n            return this.buf[5];\n        }\n\n        set measures(value: number) {\n            this.buf[5] = value;\n        }\n\n        get numberOfTracks(): number {\n            return this.buf[6];\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (control.deviceDalVersion() === \"sim\") {\n                const seq = new _SimulatorSequencer();\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    seq.play(this.buf, false);\n\n                    pauseUntil(() => seq.state() === \"stop\");\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    seq.play(this.buf, false);\n                }\n                else {\n                    seq.play(this.buf, true);\n                }\n            }\n            else {\n                if (currentSequencer) currentSequencer.stop();\n                currentSequencer = new sequencer.Sequencer(this);\n\n                if (playbackMode === PlaybackMode.UntilDone) {\n                    let seq = currentSequencer;\n                    currentSequencer.start(false);\n                    pauseUntil(() => !seq.isRunning);\n                }\n                else if (playbackMode === PlaybackMode.InBackground) {\n                    currentSequencer.start(false);\n                }\n                else {\n                    currentSequencer.start(true);\n                }\n            }\n        }\n    }\n\n    export class Envelope {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(10);\n            this.offset = this.offset || 0;\n        }\n\n        // The time in ms for the envelope to reach its maximum value\n        get attack(): number {\n            return this.getValue(0);\n        }\n\n        set attack(value: number) {\n            this.setValue(0, value);\n        }\n\n        // The time in ms for the envelope to reach its sustain value after reaching its maximum value\n        get decay(): number {\n            return this.getValue(2);\n        }\n\n        set decay(value: number) {\n            this.setValue(2, value);\n        }\n\n        // The value (0-1024) to hold at during the sustain stage\n        get sustain(): number {\n            return this.getValue(4);\n        }\n\n        set sustain(value: number) {\n            this.setValue(4, value);\n        }\n\n        // The time in ms for the envelope to reach 0 after the gate length ends\n        get release(): number {\n            return this.getValue(6);\n        }\n\n        set release(value: number) {\n            this.setValue(6, value);\n        }\n\n        // The maximum value that this envelope will reach\n        get amplitude(): number {\n            return this.getValue(8);\n        }\n\n        set amplitude(value: number) {\n            this.setValue(8, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class LFO {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(3);\n            this.offset = this.offset || 0;\n        }\n\n        get frequency(): number {\n            return this.buf[this.offset];\n        }\n\n        set frequency(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get amplitude(): number {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + 1);\n        }\n\n        set amplitude(value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + 1, value);\n        }\n    }\n\n    export class NoteEvent {\n        constructor(public buf: Buffer, public offset: number) {\n\n        }\n\n        get startTick(): number {\n            return this.getValue(0);\n        }\n\n        set startTick(value: number) {\n            this.setValue(0, value);\n        }\n\n        get endTick(): number {\n            return this.getValue(2);\n        }\n\n        set endTick(value: number) {\n            this.setValue(2, value);\n        }\n\n        get polyphony(): number {\n            return this.buf[this.offset + 4];\n        }\n\n        set polyphony(value: number) {\n            this.buf[this.offset + 4] = value;\n        }\n\n        get byteLength() {\n            return this.polyphony + 5;\n        }\n\n        getNote(offset: number, octave?: number) {\n            const value = this.buf[this.offset + offset + 5] & 0x3f;\n            if (octave !== undefined) {\n                return value + (octave - 2) * 12\n            }\n            return value\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class Track {\n        currentNoteEvent: NoteEvent;\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.currentNoteEvent = new NoteEvent(this.buf, this.noteEventStart + 2);\n        }\n\n        get isMelodicTrack(): boolean {\n            return this.flags === 0;\n        }\n\n        get id(): number {\n            return this.buf[this.offset];\n        }\n\n        set id(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get flags(): number {\n            return this.buf[this.offset + 1];\n        }\n\n        set flags(value: number) {\n            this.buf[this.offset + 1] = value;\n        }\n\n        get instrumentByteLength(): number {\n            return this.getValue(this.offset + 2);\n        }\n\n        set instrumentByteLength(value: number) {\n            this.setValue(this.offset + 2, value);\n        }\n\n        get noteEventStart(): number {\n            return this.offset + this.instrumentByteLength + 4;\n        }\n\n        get noteEventByteLength(): number {\n            return this.getValue(this.noteEventStart);\n        }\n\n        set noteEventByteLength(value: number) {\n            this.setValue(this.noteEventStart, value);\n        }\n\n        get byteLength() {\n            return this.noteEventByteLength + this.instrumentByteLength + 6;\n        }\n\n        advanceNoteEvent() {\n            this.currentNoteEvent.offset += this.currentNoteEvent.byteLength;\n\n            if (this.currentNoteEvent.offset >= this.offset + this.byteLength) {\n                this.currentNoteEvent.offset = this.noteEventStart + 2;\n            }\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, offset, value);\n        }\n    }\n\n    export class MelodicTrack extends Track {\n        instrument: Instrument;\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.instrument = new Instrument(this.buf, this.offset + 4);\n        }\n    }\n\n    export class DrumTrack extends Track {\n        drums: DrumInstrument[];\n\n        constructor(buf: Buffer, offset: number) {\n            super(buf, offset);\n            this.drums = [];\n\n            let currentOffset = 0;\n            while (currentOffset < this.instrumentByteLength) {\n                this.drums.push(new DrumInstrument(this.buf, this.offset + 4 + currentOffset));\n                currentOffset += this.drums[this.drums.length - 1].byteLength;\n            }\n        }\n    }\n\n    export class Instrument {\n        ampEnvelope: Envelope;\n        pitchEnvelope: Envelope;\n        ampLFO: LFO;\n        pitchLFO: LFO;\n\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(27);\n            this.offset = this.offset || 0;\n            this.ampEnvelope = new Envelope(this.buf, this.offset + 1);\n            this.pitchEnvelope = new Envelope(this.buf, this.offset + 11);\n            this.ampLFO = new LFO(this.buf, this.offset + 21);\n            this.pitchLFO = new LFO(this.buf, this.offset + 24)\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get octave(): number {\n            return this.buf[this.offset + 27]\n        }\n\n        set octave(value: number) {\n            this.buf[this.offset + 27] = value;\n        }\n    }\n\n    export class DrumInstrument {\n        steps: DrumStep[];\n\n        constructor(public buf: Buffer, public offset: number) {\n            this.steps = [];\n\n            for (let i = 0; i < this.numSteps; i++) {\n                this.steps.push(new DrumStep(this.buf, this.offset + 5 + i * 7))\n            }\n        }\n\n        get byteLength(): number {\n            return 5 + this.numSteps * 7;\n        }\n\n        get numSteps(): number {\n            return this.buf[this.offset];\n        }\n\n        set numSteps(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get startFrequency(): number {\n            return this.getValue(1);\n        }\n\n        set startFrequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get startVolume(): number {\n            return this.getValue(3);\n        }\n\n        set startVolume(value: number) {\n            this.setValue(3, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    export class DrumStep {\n        constructor(public buf?: Buffer, public offset?: number) {\n            if (!buf) this.buf = control.createBuffer(7);\n            this.offset = this.offset || 0;\n        }\n\n        get waveform(): number {\n            return this.buf[this.offset];\n        }\n\n        set waveform(value: number) {\n            this.buf[this.offset] = value;\n        }\n\n        get frequency(): number {\n            return this.getValue(1);\n        }\n\n        set frequency(value: number) {\n            this.setValue(1, value);\n        }\n\n        get volume(): number {\n            return this.getValue(3);\n        }\n\n        set volume(value: number) {\n            this.setValue(3, value);\n        }\n\n        get duration(): number {\n            return this.getValue(5);\n        }\n\n        set duration(value: number) {\n            this.setValue(5, value);\n        }\n\n        protected getValue(offset: number) {\n            return this.buf.getNumber(NumberFormat.UInt16LE, this.offset + offset);\n        }\n\n        protected setValue(offset: number, value: number) {\n            this.buf.setNumber(NumberFormat.UInt16LE, this.offset + offset, value);\n        }\n    }\n\n    /**\n     * Renders a single note played on an instrument into a buffer of sound instructions.\n     *\n     * @param instrument The instrument being played\n     * @param noteFrequency The frequency of the note being played. In other words, \"the key being pressed on the piano\"\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     * @param volume The peak volume of the note to play (0-1024). Also called the \"velocity\"\n     */\n    export function renderInstrument(instrument: Instrument, noteFrequency: number, gateLength: number, volume: number) {\n        // We cut off the sound at the end of the amplitude envelope's release time. This is to prevent\n        // the amp envelope from making the sound keep playing forever\n        const totalDuration = gateLength + instrument.ampEnvelope.release;\n\n        // Our goal is to calculate the frequency and amplitude at all of the inflection points in this note's lifetime\n\n        // For the ADSR envelopes, the inflection points are:\n        //     1. The end of the envelope atack (which is when the decay begins)\n        //     2. The end of the envelope decay (which is when the sustain begins)\n        //     3. The end of the gateLength (which is when the release begins)\n        //     4. The end of the envelope release\n        // If the gateLength ends before any of these stages (e.g. it's shorter than the envelope's attack), then\n        // we ignore the other stages and go straight to the release stage.\n\n        // For the triangle LFOs, the inflections points occur every time the slope goes from positive to negative. In\n        // other words, it's half the period of the triangle wave.\n\n        const ampLFOInterval = instrument.ampLFO.amplitude ? Math.max(500 / instrument.ampLFO.frequency, 50) : 50;\n        const pitchLFOInterval = instrument.pitchLFO.amplitude ? Math.max(500 / instrument.pitchLFO.frequency, 50) : 50;\n\n        // We're going to add the timepoints to this array in order so that it doesn't need to be sorted\n        let timePoints = [0];\n\n        // For each LFO and envelope, keep track of the next inflection point. If any of the LFOs or envelopes have\n        // an amplitude of 0, we can ignore them entirely.\n        let nextAETime = instrument.ampEnvelope.attack;\n        let nextPETime = instrument.pitchEnvelope.amplitude ? instrument.pitchEnvelope.attack : totalDuration;\n        let nextPLTime = instrument.pitchLFO.amplitude ? pitchLFOInterval : totalDuration;\n        let nextALTime = instrument.ampLFO.amplitude ? ampLFOInterval : totalDuration;\n\n        let time = 0;\n        while (time < totalDuration) {\n            // Amp envelope\n            if (nextAETime <= nextPETime && nextAETime <= nextPLTime && nextAETime <= nextALTime) {\n                time = nextAETime;\n                timePoints.push(nextAETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            // Pitch envelope\n            else if (nextPETime <= nextPLTime && nextPETime <= nextALTime && nextPETime < totalDuration) {\n                time = nextPETime;\n                timePoints.push(nextPETime);\n\n                // Check if the end of the decay stage is next\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                // Then check for the end of the sustain stage\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                // Otherwise it must be the end of the release\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                // If we reach the end of the release before the amp envelope is finished, bail out\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            // Pitch LFO\n            else if (nextPLTime <= nextALTime && nextPLTime < totalDuration) {\n                time = nextPLTime;\n                timePoints.push(nextPLTime);\n                nextPLTime += pitchLFOInterval;\n            }\n            // Amp LFO\n            else if (nextALTime < totalDuration) {\n                time = nextALTime;\n                timePoints.push(nextALTime);\n                nextALTime += ampLFOInterval;\n            }\n\n\n            if (time >= totalDuration) {\n                break;\n            }\n\n            // Now that we've advanced the time, we need to check all of the envelopes/LFOs again\n            // to see if any of them also need to be pushed forward (e.g. they had the same inflection point\n            // as the one we just added to the array)\n            if (nextAETime <= time) {\n                if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {\n                    nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextAETime = gateLength;\n                }\n                else {\n                    nextAETime = totalDuration;\n                }\n            }\n            if (nextPETime <= time) {\n                if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {\n                    nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;\n                }\n                else if (time < gateLength) {\n                    nextPETime = gateLength;\n                }\n                else if (time < gateLength + instrument.pitchEnvelope.release) {\n                    nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);\n                }\n                else {\n                    nextPETime = totalDuration\n                }\n            }\n            while (nextALTime <= time) {\n                nextALTime += ampLFOInterval;\n            }\n            while (nextPLTime <= time) {\n                nextPLTime += pitchLFOInterval;\n            }\n        }\n\n        // Once we've calculated the inflection points, calculate the frequency and amplitude at\n        // each step and interpolate between them with sound instructions\n        let prevAmp = instrumentVolumeAtTime(instrument, gateLength, 0, volume) | 0;\n        let prevPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, 0) | 0;\n        let prevTime = 0;\n\n        let nextAmp: number;\n        let nextPitch: number;\n        const out = control.createBuffer(BUFFER_SIZE * timePoints.length);\n        for (let i = 1; i < timePoints.length; i++) {\n            if (timePoints[i] - prevTime < 5) {\n                prevTime = timePoints[i];\n                continue;\n            }\n\n            nextAmp = instrumentVolumeAtTime(instrument, gateLength, timePoints[i], volume) | 0;\n            nextPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, timePoints[i]) | 0\n            addNote(\n                out,\n                (i - 1) * 12,\n                (timePoints[i] - prevTime) | 0,\n                prevAmp,\n                nextAmp,\n                instrument.waveform,\n                prevPitch,\n                255,\n                nextPitch\n            )\n\n            prevAmp = nextAmp;\n            prevPitch = nextPitch;\n            prevTime = timePoints[i];\n        }\n\n        // Finally, add one extra step to move the amplitude to 0 without\n        // clipping just in case the amp LFO caused it to be nonzero\n        addNote(\n            out,\n            (timePoints.length - 1) * 12,\n            10,\n            prevAmp,\n            0,\n            instrument.waveform,\n            prevPitch,\n            255,\n            prevPitch\n        )\n        return out;\n    }\n\n    export function renderDrumInstrument(sound: DrumInstrument, volume: number) {\n        // Drum instruments are rendered just like melodic instruments, but the inflection\n        // points are already calculated for us\n        let prevAmp = sound.startVolume;\n        let prevFreq = sound.startFrequency;\n\n        const scaleVolume = (value: number) => (value / 1024) * volume;\n\n        let out = control.createBuffer((sound.steps.length + 1) * BUFFER_SIZE);\n\n        for (let i = 0; i < sound.steps.length; i++) {\n            addNote(\n                out,\n                i * BUFFER_SIZE,\n                sound.steps[i].duration,\n                scaleVolume(prevAmp),\n                scaleVolume(sound.steps[i].volume),\n                sound.steps[i].waveform,\n                prevFreq,\n                255,\n                sound.steps[i].frequency\n            );\n            prevAmp = sound.steps[i].volume;\n            prevFreq = sound.steps[i].frequency\n        }\n\n        addNote(\n            out,\n            sound.steps.length * BUFFER_SIZE,\n            10,\n            scaleVolume(prevAmp),\n            0,\n            sound.steps[sound.steps.length - 1].waveform,\n            prevFreq,\n            255,\n            prevFreq\n        );\n\n        return out;\n    }\n\n    function instrumentPitchAtTime(instrument: Instrument, noteFrequency: number, gateLength: number, time: number) {\n        let mod = 0;\n        if (instrument.pitchEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.pitchEnvelope, time, gateLength)\n        }\n        if (instrument.pitchLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.pitchLFO, time)\n        }\n        return Math.max(noteFrequency + mod, 0);\n    }\n\n    function instrumentVolumeAtTime(instrument: Instrument, gateLength: number, time: number, maxVolume: number) {\n        let mod = 0;\n        if (instrument.ampEnvelope.amplitude) {\n            mod += envelopeValueAtTime(instrument.ampEnvelope, time, gateLength)\n        }\n        if (instrument.ampLFO.amplitude) {\n            mod += lfoValueAtTime(instrument.ampLFO, time)\n        }\n        return ((Math.max(Math.min(mod, instrument.ampEnvelope.amplitude), 0) / 1024) * maxVolume) | 0;\n    }\n\n    /**\n     * Calculates the value of an ADSR envelope at the given time for a given gate length.\n     *\n     * @param envelope The ADSR envelope\n     * @param time The point and time to calculate the value at\n     * @param gateLength The length of time that the \"piano key\" is held down in ms. The total duration\n     *      of the sound instructions will be longer than this if the amplitude envelope of the\n     *      instrument has a nonzero release time\n     */\n    function envelopeValueAtTime(envelope: Envelope, time: number, gateLength: number) {\n        // ADSR envelopes consist of 4 stages. They are (in order):\n        //     1. The attack stage, where the value starts at 0 and rises to the maximum value\n        //     2. The decay stage, where the value falls from the maximum value to the sustain value\n        //     3. The sustain stage, where the value holds steady at the sustain value until the gate length ends\n        //     4. The release stage, where the value falls to 0 after the gate length ends\n        // If the gate length ends before the sustain stage, we immediately skip to the release stage. All stages\n        // use a linear function for the value\n        const adjustedSustain = (envelope.sustain / 1024) * envelope.amplitude;\n\n        // First check to see if we are already in the release stage\n        if (time > gateLength) {\n            if (time - gateLength > envelope.release) return 0;\n\n            // Did the gate length end before the attack stage finished?\n            else if (time < envelope.attack) {\n                const height = (envelope.amplitude / envelope.attack) * gateLength;\n                return height - ((height / envelope.release) * (time - gateLength))\n            }\n            // Did the gate length end before the decay stage finished?\n            else if (time < envelope.attack + envelope.decay) {\n                const height2 = envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (gateLength - envelope.attack);\n                return height2 - ((height2 / envelope.release) * (time - gateLength))\n            }\n            else {\n                return adjustedSustain - (adjustedSustain / envelope.release) * (time - gateLength)\n            }\n        }\n        else if (time < envelope.attack) {\n            return (envelope.amplitude / envelope.attack) * time\n        }\n        else if (time < envelope.attack + envelope.decay) {\n            return envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (time - envelope.attack)\n        }\n        else {\n            return adjustedSustain;\n        }\n    }\n\n    /**\n     * Calculates the value of the LFO at the given time.\n     *\n     * TODO: might be nice to give options to shift the phase of the LFO or let it run free\n     *\n     * @param lfo The LFO to calculate the value of\n     * @param time The time to calculate the value at\n     */\n    function lfoValueAtTime(lfo: LFO, time: number) {\n        // Use cosine to smooth out the value somewhat\n        return Math.cos(((time / 1000) * lfo.frequency) * 2 * Math.PI) * lfo.amplitude\n    }\n\n    export function _stopAllSongs() {\n        if (currentSequencer) {\n            currentSequencer.stop();\n            currentSequencer = undefined;\n        }\n        _stopAllSimSequencers();\n    }\n}","legacy.ts":"//% deprecated=true hidden=true\nenum Sounds {\n    //% block=\"power up\"\n    PowerUp,\n    //% block=\"power down\"\n    PowerDown,\n    //% block=\"jump up\"\n    JumpUp,\n    //% block=\"jump down\"\n    JumpDown,\n    //% block=\"ba ding\"\n    BaDing,\n    //% block=\"wawawawaa\"\n    Wawawawaa,\n    //% block=\"magic wand\"\n    MagicWand,\n    //% block=\"siren\"\n    Siren\n}\n\nnamespace music {\n    /**\n     * Get the melody string for a built-in melody.\n     * @param name the note name, eg: Note.C\n     */\n    //% help=music/sounds\n    //% blockId=music_sounds block=\"%name\"\n    //% blockHidden=true\n    //% name.fieldEditor=\"gridpicker\"\n    //% name.fieldOptions.width=285\n    //% name.fieldOptions.columns=3\n    export function sounds(name: Sounds): string {\n        switch (name) {\n            case Sounds.BaDing:\n                return 'b5:1 e6:3';\n            case Sounds.Wawawawaa:\n                return 'e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8';\n            case Sounds.JumpUp:\n                return 'c5:1 d e f g';\n            case Sounds.JumpDown:\n                return 'g5:1 f e d c';\n            case Sounds.PowerUp:\n                return 'g4:1 c5 e g:2 e:1 g:3';\n            case Sounds.PowerDown:\n                return 'g5:1 d# c g4:2 b:1 c5:3';\n            case Sounds.MagicWand:\n                return 'F#6:1-300 G# A# B C7# D# F F# G# A# B:6'; //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n            case Sounds.Siren:\n                return 'a4 d5 a4 d5 a4 d5';\n            default:\n                return '';\n        }\n    }\n\n    let currMelody: Melody\n\n    /**\n     * Start playing a sound and don't wait for it to finish.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound\n    //% blockId=music_play_sound block=\"play sound %sound=music_sounds\"\n    //% parts=\"headphone\"\n    //% weight=95 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSound(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.play();\n        pause(1);\n    }\n\n\n    /**\n     * Play a sound and wait until the sound is done.\n     * Notes are expressed as a string of characters with this format: NOTE[octave][:duration]\n     * @param sound the melody to play\n     */\n    //% help=music/play-sound-until-done\n    //% blockId=music_play_sound_until_done block=\"play sound %sound=music_sounds|until done\"\n    //% parts=\"headphone\"\n    //% weight=94 blockGap=8\n    //% deprecated=true hidden=true\n    export function playSoundUntilDone(sound: string) {\n        stopAllSounds();\n        currMelody = new Melody(sound);\n        currMelody.playUntilDone();\n    }\n}","melody.cpp":"#include \"pxt.h\"\n#include \"SoundOutput.h\"\n#include \"melody.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\nnamespace music {\n\nSINGLETON(WSynthesizer);\n\n// Tone generator arguments:\n//\n// sound: a pointer to the currently-playing sound, usable for looking up the\n// waveform or generator-specific state.\n//\n// position: offset within the currently-playing wave, range 0..1023.\n//\n// cycle: a 6-bit cyclical sequence number of the wave, incremented each time\n// the position loops from 1023 back to 0.\ntypedef int (*gentone_t)(PlayingSound *sound, uint32_t position, uint8_t cycle);\n\nstatic int noiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    // see https://en.wikipedia.org/wiki/Xorshift\n    static uint32_t x = 0xf01ba80;\n    x ^= x << 13;\n    x ^= x >> 17;\n    x ^= x << 5;\n    return (x & 0xffff) - 0x7fff;\n}\n\nstatic int sineTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    int32_t p = position;\n    if (p >= 512) {\n        p -= 512;\n    }\n    if (p > 256) {\n        p = 512 - p;\n    }\n\n    // Approximate sin(x * pi / 2) with the odd polynomial y = cx^5 + bx^3 + ax\n    // using the constraint y(1) = 1 => a = 1 - b - c\n    //   => y = c x^5 + b x^3 + (1 - b - c) * x\n    //\n    // Do a least-squares fit of this to sin(x * pi / 2) in the range 0..1\n    // inclusive, using 21 evenly spaced points. Resulting approximation:\n    //\n    // sin(x*pi/2) ~= 0.0721435357258*x**5 - 0.642443736562*x**3 + 1.57030020084*x\n\n    // Scale the constants by 32767 to match the desired output range.\n    constexpr int32_t c = 0.0721435357258 * 32767;\n    constexpr int32_t b = -0.642443736562 * 32767;\n    constexpr int32_t a = 1.57030020084 * 32767;\n\n    // Calculate using y = ((c * x^2 + b) * x^2 + a) * x\n    //\n    // The position p is x * 256, so after each multiply with p we need to\n    // shift right by 8 bits to keep the decimal point in the same place.  (The\n    // approximation has a negative error near x=1 which helps avoid overflow.)\n    int32_t p2 = p * p;\n    int32_t u = (c * p2 >> 16) + b;\n    int32_t v = (u * p2 >> 16) + a;\n    int32_t w = v * p >> 8;\n\n    // The result is within 7/32767 or 0.02%, signal-to-error ratio about 38 dB.\n    return position >= 512 ? -w : w;\n}\n\nstatic int sawtoothTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return (position << 6) - 0x7fff;\n}\n\nstatic int triangleTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)sound;\n    (void)cycle;\n    return position < 512 ? (position << 7) - 0x7fff : ((1023 - position) << 7) - 0x7fff;\n}\n\nstatic int squareWaveTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    (void)cycle;\n    uint8_t wave = sound->currInstr->soundWave;\n    return (int)position < (102 * (wave - SW_SQUARE_10 + 1)) ? -0x7fff : 0x7fff;\n}\n\nstatic int tunedNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a random bit sequence. Since the generator\n    // is called multiple times per wave, use PlayingSound state data to ensure we\n    // only generate a random bit once per wave, and then reuse it for future\n    // calls for that wave.\n    //\n    // Use the low 6 bits of generatorState to store the last-used cycle, and\n    // random_bit to store the last on/off state. (random_bit is arbitrary as\n    // long as it isn't one of the low 6 bits.)\n    constexpr uint32_t random_bit = 0x8000;\n    static uint32_t x = 0xf01ba80; // seed for the static RNG state\n    uint8_t prev_cycle = sound->generatorState & 0x3f;\n    uint32_t is_on;\n    if (cycle == prev_cycle) {\n        is_on = sound->generatorState & random_bit;\n    } else {\n        // see https://en.wikipedia.org/wiki/Xorshift\n        x ^= x << 13;\n        x ^= x >> 17;\n        x ^= x << 5;\n        is_on = (x & random_bit);\n        sound->generatorState = (cycle & 0x3f) | is_on;\n    }\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\n// Bit patterns for use by the cyclic noise tone.\n//\n// The bit pattern is arbitrary, but should have equal numbers of 0 and 1 bits,\n// and should avoid long identical-bit runs for the lower parts. The values below\n// were chosen based on a random permutation of the hex nibbles 0..f and then\n// hand-tweaked by swapping some nibbles. Generated by:\n//\n//   shuf -i 0-15 | perl -ne 's/(\\d+)/printf(\"%x\",$1)/e'\nstatic const uint32_t cycle_bits[] = {0x2df0eb47, 0xc8165a93};\nstatic const uint8_t cycle_mask[] = {0xf, 0x1f, 0x3f};\n\nstatic int cycleNoiseTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    // The bit sequence repeats every 16/32/64 waves.\n    //\n    // The \"cycle\" argument corresponds to the sequential number of the generated\n    // wave. This is currently a 6-bit value. Since the pseudorandom bit sequences\n    // evenly fit into this, there's no need to track generator state.\n    uint8_t wave = sound->currInstr->soundWave;\n    int cycle_index = wave - SW_SQUARE_CYCLE_16;\n    // CLAMP(0, cycle_index, sizeof cycle_bits / sizeof cycle_bits[0])\n    cycle &= cycle_mask[cycle_index];\n    bool is_on = (cycle_bits[cycle >> 5] & (1U << (cycle & 0x1f)));\n    if (!is_on)\n        return 0;\n    return position < 512 ? -0x7fff : 0x7fff;\n}\n\nstatic int silenceTone(PlayingSound *sound, uint32_t position, uint8_t cycle) {\n    // Generate a square wave filtered by a short-cycle pseudorandom bit sequence.\n    (void)sound;\n    (void)position;\n    (void)cycle;\n    return 0;\n}\n\nstatic gentone_t getWaveFn(uint8_t wave) {\n    switch (wave) {\n    case SW_TRIANGLE:\n        return triangleTone;\n    case SW_SAWTOOTH:\n        return sawtoothTone;\n    case SW_TUNEDNOISE:\n        return tunedNoiseTone;\n    case SW_NOISE:\n        return noiseTone;\n    case SW_SINE:\n        return sineTone;\n    default:\n        if (SW_SQUARE_10 <= wave && wave <= SW_SQUARE_50)\n            return squareWaveTone;\n        if (SW_SQUARE_CYCLE_16 <= wave && wave <= SW_SQUARE_CYCLE_64)\n            return cycleNoiseTone;\n        else\n            return silenceTone;\n    }\n}\n\n#define CLAMP(lo, v, hi) ((v) = ((v) < (lo) ? (lo) : (v) > (hi) ? (hi) : (v)))\n\nint WSynthesizer::updateQueues() {\n    const int maxTime = 0xffffff;\n    while (1) {\n        WaitingSound *p;\n        int minLeft = maxTime;\n        for (p = waiting; p; p = p->next) {\n            int timeLeft =\n                p->state == SoundState::Waiting ? p->startSampleNo - currSample : maxTime;\n            if (timeLeft <= 0) {\n                break;\n            }\n            if (timeLeft < minLeft)\n                minLeft = timeLeft;\n        }\n        if (p) {\n            PlayingSound *snd;\n            int minIdx = -1;\n            for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n                snd = &playingSounds[i];\n                if (snd->sound == NULL)\n                    break;\n                if (minIdx == -1 ||\n                    playingSounds[minIdx].startSampleNo < playingSounds[i].startSampleNo)\n                    minIdx = i;\n                snd = NULL;\n            }\n            // if we didn't find a free slot, expel the oldest sound\n            if (!snd)\n                snd = &playingSounds[minIdx];\n            if (snd->sound)\n                snd->sound->state = SoundState::Done;\n            snd->sound = p;\n            p->state = SoundState::Playing;\n            snd->startSampleNo = currSample;\n            snd->currInstr = (SoundInstruction *)p->instructions->data;\n            snd->instrEnd = snd->currInstr + p->instructions->length / sizeof(SoundInstruction);\n            snd->prevVolume = -1;\n        } else {\n            // no more sounds to move\n            return minLeft;\n        }\n    }\n}\n\nint WSynthesizer::fillSamples(int16_t *dst, int numsamples) {\n    if (numsamples <= 0)\n        return 1;\n\n    int timeLeft = updateQueues();\n    int res = waiting != NULL;\n\n    // if there's a pending sound to be started somewhere during numsamples,\n    // split the call into two\n    if (timeLeft < numsamples) {\n        fillSamples(dst, timeLeft);\n        LOG(\"M split %d\", timeLeft);\n        fillSamples(dst + timeLeft, numsamples - timeLeft);\n        return 1;\n    }\n\n    memset(dst, 0, numsamples * 2);\n\n    uint32_t samplesPerMS = (sampleRate << 8) / 1000;\n    float toneStepMult = (1024.0 * (1 << 16)) / sampleRate;\n    const int MAXVAL = (1 << (OUTPUT_BITS - 1)) - 1;\n\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        PlayingSound *snd = &playingSounds[i];\n        if (snd->sound == NULL)\n            continue;\n\n        res = 1;\n\n        SoundInstruction *instr = NULL;\n        gentone_t fn = NULL;\n        snd->currInstr--;\n        uint32_t toneStep = 0;\n        int32_t toneDelta = 0;\n        int32_t volumeStep = 0;\n        uint32_t tonePosition = snd->tonePosition;\n        uint32_t samplesLeft = 0;\n        uint8_t wave = 0;\n        int32_t volume = 0;\n\n        for (int j = 0; j < numsamples; ++j) {\n            if (samplesLeft == 0) {\n                snd->currInstr++;\n                if (snd->currInstr >= snd->instrEnd) {\n                    break;\n                }\n                SoundInstruction copy = *snd->currInstr;\n                instr = &copy;\n                CLAMP(20, instr->frequency, 20000);\n                CLAMP(20, instr->endFrequency, 20000);\n                CLAMP(0, instr->startVolume, 1023);\n                CLAMP(0, instr->endVolume, 1023);\n                CLAMP(1, instr->duration, 60000);\n\n                wave = instr->soundWave;\n                fn = getWaveFn(wave);\n\n                samplesLeft = (uint32_t)(instr->duration * samplesPerMS >> 8);\n                // make sure the division is signed\n                volumeStep =\n                    (int)((instr->endVolume - instr->startVolume) << 16) / (int)samplesLeft;\n\n                if (j == 0 && snd->prevVolume != -1) {\n                    // restore previous state\n                    samplesLeft = snd->samplesLeftInCurr;\n                    volume = snd->prevVolume;\n                    toneStep = snd->prevToneStep;\n                    toneDelta = snd->prevToneDelta;\n                } else {\n                    LOG(\"#sampl %d %p\", samplesLeft, snd->currInstr);\n                    volume = instr->startVolume << 16;\n                    LOG(\"%d-%dHz %d-%d vol\", instr->frequency, instr->endFrequency,\n                        instr->startVolume, instr->endVolume);\n                    toneStep = (uint32_t)(toneStepMult * instr->frequency);\n                    if (instr->frequency != instr->endFrequency) {\n                        uint32_t endToneStep = (uint32_t)(toneStepMult * instr->endFrequency);\n                        toneDelta = (int32_t)(endToneStep - toneStep) / (int32_t)samplesLeft;\n                    } else {\n                        toneDelta = 0;\n                    }\n                }\n            }\n\n            int v = fn(snd, (tonePosition >> 16) & 1023, tonePosition >> 26);\n            v = (v * (volume >> 16)) >> (10 + (16 - OUTPUT_BITS));\n\n            // if (v > MAXVAL)\n            //    target_panic(123);\n\n            dst[j] += v;\n\n            tonePosition += toneStep;\n            toneStep += toneDelta;\n            volume += volumeStep;\n            samplesLeft--;\n        }\n\n        if (snd->currInstr >= snd->instrEnd) {\n            snd->sound->state = SoundState::Done;\n            snd->sound = NULL;\n        } else {\n            snd->tonePosition = tonePosition;\n            if (samplesLeft == 0)\n                samplesLeft++; // avoid infinite loop in next iteration\n            snd->samplesLeftInCurr = samplesLeft;\n            snd->prevVolume = volume;\n            snd->prevToneDelta = toneDelta;\n            snd->prevToneStep = toneStep;\n        }\n    }\n\n    currSample += numsamples;\n\n    for (int j = 0; j < numsamples; ++j) {\n        if (dst[j] > MAXVAL)\n            dst[j] = MAXVAL;\n        else if (dst[j] < -MAXVAL)\n            dst[j] = -MAXVAL;\n    }\n\n    return res;\n}\n\n//%\nvoid enableAmp(int enabled) {\n    // this is also compiled on linux\n#ifdef LOOKUP_PIN\n    auto pin = LOOKUP_PIN(SPEAKER_AMP);\n    if (pin) {\n        if (PIN(SPEAKER_AMP) & CFG_PIN_CONFIG_ACTIVE_LO)\n            enabled = !enabled;\n        pin->setDigitalValue(enabled);\n    }\n#endif\n}\n\n//%\nvoid forceOutput(int outp) {\n    auto snd = getWSynthesizer();\n    snd->out.setOutput(outp);\n}\n\n//%\nvoid queuePlayInstructions(int when, Buffer buf) {\n    auto snd = getWSynthesizer();\n\n    registerGCObj(buf);\n\n    auto p = new WaitingSound;\n    p->state = SoundState::Waiting;\n    p->instructions = buf;\n    p->startSampleNo = snd->currSample + when * snd->sampleRate / 1000;\n\n    LOG(\"Queue %dms now=%d off=%d %p sampl:%dHz\", when, snd->currSample,\n        p->startSampleNo - snd->currSample, buf->data, snd->sampleRate);\n\n    target_disable_irq();\n    // add new sound to queue\n    p->next = snd->waiting;\n    snd->waiting = p;\n    // remove sounds that have already been fully played\n    while (p) {\n        while (p->next && p->next->state == SoundState::Done) {\n            auto todel = p->next;\n            p->next = todel->next;\n            unregisterGCObj(todel->instructions);\n            delete todel;\n        }\n        p = p->next;\n    }\n    target_enable_irq();\n\n    snd->poke();\n}\n\n//%\nvoid stopPlaying() {\n    LOG(\"stop playing!\");\n\n    auto snd = getWSynthesizer();\n\n    target_disable_irq();\n    auto p = snd->waiting;\n    snd->waiting = NULL;\n    for (unsigned i = 0; i < MAX_SOUNDS; ++i) {\n        snd->playingSounds[i].sound = NULL;\n    }\n    while (p) {\n        auto n = p->next;\n        unregisterGCObj(p->instructions);\n        delete p;\n        p = n;\n    }\n    target_enable_irq();\n}\n\nWSynthesizer::WSynthesizer() : upstream(NULL), out(*this) {\n    currSample = 0;\n    active = false;\n    sampleRate = out.dac.getSampleRate();\n    memset(&playingSounds, 0, sizeof(playingSounds));\n    waiting = NULL;\n    PXT_REGISTER_RESET(stopPlaying);\n}\n\n//% promise\nint _createSequencer() {\n    return 0;\n}\n\n//%\nString _sequencerState(int id) {\n    return NULL;\n}\n\n//%\nint _sequencerCurrentTick(int id) {\n    return 0;\n}\n\n//%\nvoid _sequencerPlaySong(int id, Buffer buf, bool loop) {\n}\n\n//%\nvoid _sequencerStop(int id) {\n}\n\n//%\nvoid _sequencerSetVolume(int id, int volume) {\n}\n\n//%\nvoid _sequencerSetVolumeForAll(int volume) {\n}\n\n//%\nvoid _sequencerSetTrackVolume(int id, int trackIndex, int volume) {\n}\n\n//%\nvoid _sequencerSetDrumTrackVolume(int id, int trackIndex, int drumIndex, int volume) {\n}\n\n//%\nvoid _sequencerDispose(int id) {\n}\n\n} // namespace music\n\nnamespace pxt {\nint redirectSamples(int16_t *dst, int numsamples, int samplerate) {\n    auto snd = music::getWSynthesizer();\n    snd->upstream = NULL; // disconnect from regular playback mechanism\n    snd->sampleRate = samplerate;\n    return snd->fillSamples(dst, numsamples);\n}\n\n} // namespace pxt\n\nnamespace jacdac {\n__attribute__((weak)) void setJackRouterOutput(int output) {}\n} // namespace jacdac\n","melody.h":"#pragma once\n\n#ifndef OUTPUT_BITS\n#define OUTPUT_BITS 10\n#endif\n\n#define SW_TRIANGLE 1\n#define SW_SAWTOOTH 2\n#define SW_SINE 3\n#define SW_TUNEDNOISE 4\n#define SW_NOISE 5\n#define SW_SQUARE_10 11\n#define SW_SQUARE_50 15\n#define SW_SQUARE_CYCLE_16 16\n#define SW_SQUARE_CYCLE_32 17\n#define SW_SQUARE_CYCLE_64 18\n\nstruct SoundInstruction {\n    uint8_t soundWave;\n    uint8_t flags;\n    uint16_t frequency;    // Hz\n    uint16_t duration;     // ms\n    int16_t startVolume;   // 0-1023\n    int16_t endVolume;     // 0-1023\n    uint16_t endFrequency; // Hz\n};\n\n#ifdef DATASTREAM_MAXIMUM_BUFFERS\n#define CODAL 1\n#endif\n\nnamespace music {\n\n#define MAX_SOUNDS 8\n\nSTATIC_ASSERT((1 << (16 - OUTPUT_BITS)) > MAX_SOUNDS);\n\nenum class SoundState : uint8_t {\n    Waiting, //\n    Playing, //\n    Done     //\n};\n\nstruct WaitingSound {\n    uint32_t startSampleNo;\n    SoundState state;\n    WaitingSound *next;\n    Buffer instructions;\n};\n\nstruct PlayingSound {\n    uint32_t startSampleNo;\n    uint32_t samplesLeftInCurr;\n    uint32_t tonePosition;\n    int32_t prevVolume;\n    uint32_t prevToneStep;\n    int32_t prevToneDelta;\n    uint32_t generatorState;\n    WaitingSound *sound;\n    SoundInstruction *currInstr, *instrEnd;\n};\n\nclass WSynthesizer\n#ifdef CODAL\n    : public DataSource\n#endif\n{\n  public:\n#ifdef CODAL\n    DataSink *upstream;\n#else\n    void *upstream;\n#endif\n    uint32_t currSample; // after 25h of playing we might get a glitch\n    int32_t sampleRate;  // eg 44100\n    PlayingSound playingSounds[MAX_SOUNDS];\n    WaitingSound *waiting;\n    bool active;\n\n    SoundOutput out;\n\n    int fillSamples(int16_t *dst, int numsamples);\n    int updateQueues();\n\n    WSynthesizer();\n    virtual ~WSynthesizer() {}\n\n    void pokeUpstream() {\n#ifdef CODAL\n        if (upstream) {\n            upstream->pullRequest();\n        }\n#endif\n    }\n\n    void poke() {\n        if (!active) {\n            active = true;\n            pokeUpstream();\n        }\n    }\n\n#ifdef CODAL\n    virtual ManagedBuffer pull() {\n        if (!upstream)\n            return ManagedBuffer();\n        ManagedBuffer data(512);\n        auto dp = (int16_t *)data.getBytes();\n        auto sz = 512 / 2;\n        int r = fillSamples(dp, sz);\n#if defined(NRF52_SERIES)\n        int mul = out.dac.getSampleRange();\n#endif\n        while (sz--) {\n#if defined(NRF52_SERIES)\n            *dp = ((-*dp + (1 << (OUTPUT_BITS - 1))) * mul) >> OUTPUT_BITS;\n#else\n            *dp += 1 << (OUTPUT_BITS - 1);\n#endif\n            dp++;\n        }\n        if (!r) {\n            active = false;\n            // return empty - nothing left to play\n            return ManagedBuffer();\n        }\n        pokeUpstream();\n        return data;\n    }\n    virtual void connect(DataSink &sink) { upstream = &sink; }\n#endif\n};\n\n} // namespace music\n","melody.ts":"enum MusicOutput {\n    AutoDetect = 0,\n    Buzzer = 1,\n    HeadPhones = 2,\n}\n\nnamespace music {\n    //% whenUsed\n    const freqs = hex`\n        1f00210023002500270029002c002e003100340037003a003e004100450049004e00520057005c00620068006e00\n        75007b0083008b0093009c00a500af00b900c400d000dc00e900f70006011501260137014a015d01720188019f01\n        b801d201ee010b022a024b026e029302ba02e40210033f037003a403dc03170455049704dd0427057505c8052006\n        7d06e0064907b8072d08a9082d09b9094d0aea0a900b400cfa0cc00d910e6f0f5a1053115b1272139a14d4152017\n        8018f519801b231dde1e`\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n\n    //% shim=music::stopPlaying\n    function stopPlaying() { }\n\n    //% shim=music::forceOutput\n    export function forceOutput(buf: MusicOutput) { }\n\n    let globalVolume: number = null\n\n    const BUFFER_SIZE: number = 12;\n\n    //% shim=music::enableAmp\n    function enableAmp(en: number) {\n        return // for sim\n    }\n\n    function initVolume() {\n        if (globalVolume === null) {\n            globalVolume = 0\n            setVolume(control.getConfigValue(DAL.CFG_SPEAKER_VOLUME, 128))\n        }\n    }\n\n    /**\n     * Set the default output volume of the sound synthesizer.\n     * @param volume the volume 0...255\n     */\n    //% blockId=synth_set_volume block=\"set volume %volume\"\n    //% parts=\"speaker\"\n    //% volume.min=0 volume.max=255\n    //% volume.defl=20\n    //% help=music/set-volume\n    //% weight=70\n    //% group=\"Volume\"\n    export function setVolume(volume: number): void {\n        globalVolume = Math.clamp(0, 255, volume | 0)\n        enableAmp(globalVolume > 0 ? 1 : 0)\n    }\n\n    /**\n     * Gets the current volume\n     */\n    //% parts=\"speaker\"\n    //% weight=70\n    export function volume(): number {\n        initVolume()\n        return globalVolume;\n    }\n\n    function playNoteCore(when: number, frequency: number, ms: number) {\n        let buf = control.createBuffer(BUFFER_SIZE)\n        addNote(buf, 0, ms, 255, 255, 3, frequency, volume(), frequency)\n        queuePlayInstructions(when, buf)\n    }\n\n    /**\n     * Play a tone through the speaker for some amount of time.\n     * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n     * @param ms tone duration in milliseconds (ms), eg: BeatFraction.Half\n     */\n    //% help=music/play-tone\n    //% blockId=mixer_play_note block=\"play tone|at %note=device_note|for %duration=device_beat\"\n    //% parts=\"headphone\" async\n    //% blockNamespace=music\n    //% weight=76 blockGap=8\n    //% group=\"Tone\"\n    //% deprecated=1\n    export function playTone(frequency: number, ms: number): void {\n        if (ms == 0)\n            ms = 86400000 // 1 day\n\n        if (ms <= 2000) {\n            playNoteCore(0, frequency, ms)\n            pause(ms)\n        } else {\n            const id = ++playToneID\n            control.runInParallel(() => {\n                let pos = control.millis()\n                while (id == playToneID && ms > 0) {\n                    let now = control.millis()\n                    let d = pos - now\n                    let t = Math.min(ms, 500)\n                    ms -= t\n                    pos += t\n                    playNoteCore(d - 1, frequency, t)\n                    if (ms == 0)\n                        pause(d + t)\n                    else\n                        pause(d + t - 100)\n                }\n            })\n        }\n    }\n\n    let playToneID = 0\n\n    /**\n     * Play a melody from the melody editor.\n     * @param melody - string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces,\n     * which will be played one at a time, ex: \"E D G F B A C5 B \"\n     * @param tempo - number in beats per minute (bpm), dictating how long each note will play for\n     */\n    //% block=\"play melody $melody at tempo $tempo|(bpm)\" blockId=playMelody\n    //% blockNamespace=music\n    //% weight=85 blockGap=8 help=music/play-melody\n    //% group=\"Melody\"\n    //% melody.shadow=\"melody_editor\"\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% deprecated=1\n    export function playMelody(melody: string, tempo: number) {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        const song = new Melody(formattedMelody);\n        song.playUntilDone();\n    }\n\n\n    /**\n     * Create a melody with the melody editor.\n     * @param melody\n     */\n    //% block=\"$melody\" blockId=melody_editor\n    //% blockNamespace=music\n    //% blockHidden = true\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Melody\" duplicateShadowOnDrag\n    //% melody.fieldEditor=\"melody\"\n    //% melody.fieldOptions.decompileLiterals=true\n    //% melody.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% melody.fieldOptions.onParentBlock=\"true\"\n    //% shim=TD_ID\n    export function melodyEditor(melody: string): string {\n        return melody;\n    }\n\n    /**\n     * Stop all sounds from playing.\n     */\n    //% help=music/stop-all-sounds\n    //% blockId=music_stop_all_sounds block=\"stop all sounds\"\n    //% weight=45\n    //% group=\"Sounds\"\n    export function stopAllSounds() {\n        Melody.stopAll();\n        stopPlaying();\n        _stopPlayables();\n        sequencer._stopAllSongs();\n    }\n\n    //% fixedInstances\n    export class Melody {\n        _text: string;\n        private _player: MelodyPlayer;\n\n        private static playingMelodies: Melody[];\n\n        static stopAll() {\n            if (Melody.playingMelodies) {\n                const ms = Melody.playingMelodies.slice(0, Melody.playingMelodies.length);\n                ms.forEach(p => p.stop());\n            }\n        }\n\n        constructor(text: string) {\n            this._text = text\n        }\n\n        get text() {\n            return this._text;\n        }\n\n        /**\n         * Stop playing a sound\n         */\n        //% blockId=mixer_stop block=\"stop sound %sound\"\n        //% help=music/melody/stop\n        //% parts=\"headphone\"\n        //% weight=92 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        stop() {\n            if (this._player) {\n                this._player.stop()\n                this._player = null\n            }\n            this.unregisterMelody();\n        }\n\n        private registerMelody() {\n            // keep track of the active players\n            if (!Melody.playingMelodies) Melody.playingMelodies = [];\n            // stop and pop melodies if too many playing\n            if (Melody.playingMelodies.length > 4) {\n                // stop last player (also pops)\n                Melody.playingMelodies[Melody.playingMelodies.length - 1].stop();\n            }\n            // put back the melody on top of the melody stack\n            Melody.playingMelodies.removeElement(this);\n            Melody.playingMelodies.push(this);\n        }\n        private unregisterMelody() {\n            // remove from list\n            if (Melody.playingMelodies) {\n                Melody.playingMelodies.removeElement(this); // remove self\n            }\n        }\n\n        private playCore(volume: number, loop: boolean) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this.registerMelody();\n            control.runInParallel(() => {\n                while (this._player == p) {\n                    p.play(volume)\n                    if (!loop) {\n                        // Unregister the melody when done playing, but\n                        // only if it hasn't been restarted. (Looping\n                        // melodies never stop on their own, they only\n                        // get unregistered via stop().)\n                        if (this._player == p) {\n                            this.unregisterMelody();\n                        }\n                        break\n                    }\n                }\n            })\n        }\n\n        /**\n         * Start playing a sound in a loop and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/loop\n        //% blockId=mixer_loop_sound block=\"loop sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=93 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        loop(volume = 255) {\n            this.playCore(volume, true)\n        }\n\n        /**\n         * Start playing a sound and don't wait for it to finish.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play\n        //% blockId=mixer_play_sound block=\"play sound %sound\"\n        //% parts=\"headphone\"\n        //% weight=95 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        play(volume = 255) {\n            this.playCore(volume, false)\n        }\n\n\n        /**\n         * Play a sound and wait until the sound is done.\n         * @param sound the melody to play\n         */\n        //% help=music/melody/play-until-done\n        //% blockId=mixer_play_sound_until_done block=\"play sound %sound|until done\"\n        //% parts=\"headphone\"\n        //% weight=94 blockGap=8\n        //% group=\"Sounds\"\n        //% deprecated=1\n        playUntilDone(volume = 255) {\n            this.stop()\n            const p = this._player = new MelodyPlayer(this)\n            this._player.onPlayFinished = () => {\n                if (p == this._player)\n                    this.unregisterMelody();\n            }\n            this.registerMelody();\n            this._player.play(volume)\n        }\n\n        toString() {\n            return this._text;\n        }\n    }\n\n    export function addNote(sndInstr: Buffer, sndInstrPtr: number, ms: number, beg: number, end: number, soundWave: number, hz: number, volume: number, endHz: number) {\n        if (ms > 0) {\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, soundWave)\n            sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr + 1, 0)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 2, hz)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 4, ms)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 6, (beg * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 8, (end * volume) >> 6)\n            sndInstr.setNumber(NumberFormat.UInt16LE, sndInstrPtr + 10, endHz);\n            sndInstrPtr += BUFFER_SIZE;\n        }\n        sndInstr.setNumber(NumberFormat.UInt8LE, sndInstrPtr, 0) // terminate\n        return sndInstrPtr\n    }\n\n\n    export class MelodyPlayer {\n        melody: Melody;\n\n        onPlayFinished: () => void;\n\n        constructor(m: Melody) {\n            this.melody = m\n        }\n\n        stop() {\n            this.melody = null\n        }\n\n        protected queuePlayInstructions(timeDelta: number, buf: Buffer) {\n            queuePlayInstructions(timeDelta, buf)\n        }\n\n        play(volume: number) {\n            if (!this.melody)\n                return\n            volume = Math.clamp(0, 255, (volume * music.volume()) >> 8)\n\n            let notes = this.melody._text\n            let pos = 0;\n            let duration = 4; //Default duration (Crotchet)\n            let octave = 4; //Middle octave\n            let tempo = 120; // default tempo\n\n            let hz = 0\n            let endHz = -1\n            let ms = 0\n            let timePos = 0\n            let startTime = control.millis()\n            let now = 0\n\n            let envA = 0\n            let envD = 0\n            let envS = 255\n            let envR = 0\n            let soundWave = 1 // triangle\n            let sndInstr = control.createBuffer(5 * BUFFER_SIZE)\n            let sndInstrPtr = 0\n\n            const addForm = (formDuration: number, beg: number, end: number, msOff: number) => {\n                let freqStart = hz;\n                let freqEnd = endHz;\n\n                const envelopeWidth = ms > 0 ? ms : duration * Math.idiv(15000, tempo) + envR;\n                if (endHz != hz && envelopeWidth != 0) {\n                    const slope = (freqEnd - freqStart) / envelopeWidth;\n                    freqStart = hz + slope * msOff;\n                    freqEnd = hz + slope * (msOff + formDuration);\n                }\n                sndInstrPtr = addNote(sndInstr, sndInstrPtr, formDuration, beg, end, soundWave, freqStart, volume, freqEnd);\n            }\n\n            const scanNextWord = () => {\n                if (!this.melody)\n                    return \"\"\n\n                // eat space\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c != ' ' && c != '\\r' && c != '\\n' && c != '\\t')\n                        break;\n                    pos++;\n                }\n\n                // read note\n                let note = \"\";\n                while (pos < notes.length) {\n                    const c = notes[pos];\n                    if (c == ' ' || c == '\\r' || c == '\\n' || c == '\\t')\n                        break;\n                    note += c;\n                    pos++;\n                }\n                return note;\n            }\n\n            enum Token {\n                Note,\n                Octave,\n                Beat,\n                Tempo,\n                Hz,\n                EndHz,\n                Ms,\n                WaveForm,\n                EnvelopeA,\n                EnvelopeD,\n                EnvelopeS,\n                EnvelopeR\n            }\n\n            let token: string = \"\";\n            let tokenKind = Token.Note;\n\n            // [ABCDEFG] (\\d+)  (:\\d+)  (-\\d+)\n            // note      octave length  tempo\n            // R (:\\d+) - rest\n            // !\\d+,\\d+ - sound at frequency with given length (Hz,ms); !\\d+ and !\\d+,:\\d+ also possible\n            // @\\d+,\\d+,\\d+,\\d+ - ADSR envelope - ms,ms,volume,ms; volume is 0-255\n            // ~\\d+ - wave form:\n            //   1 - triangle\n            //   2 - sawtooth\n            //   3 - sine\n            //   4 - pseudorandom square wave noise (tunable)\n            //   5 - white noise (ignores frequency)\n            //   11 - square 10%\n            //   12 - square 20%\n            //   ...\n            //   15 - square 50%\n            //   16 - filtered square wave, cycle length 16\n            //   17 - filtered square wave, cycle length 32\n            //   18 - filtered square wave, cycle length 64\n\n            const consumeToken = () => {\n                if (token && tokenKind != Token.Note) {\n                    const d = parseInt(token);\n                    switch (tokenKind) {\n                        case Token.Octave: octave = d; break;\n                        case Token.Beat:\n                            duration = Math.max(1, Math.min(16, d));\n                            ms = -1;\n                            break;\n                        case Token.Tempo: tempo = Math.max(1, d); break;\n                        case Token.Hz: hz = d; tokenKind = Token.Ms; break;\n                        case Token.Ms: ms = d; break;\n                        case Token.WaveForm: soundWave = Math.clamp(1, 18, d); break;\n                        case Token.EnvelopeA: envA = d; tokenKind = Token.EnvelopeD; break;\n                        case Token.EnvelopeD: envD = d; tokenKind = Token.EnvelopeS; break;\n                        case Token.EnvelopeS: envS = Math.clamp(0, 255, d); tokenKind = Token.EnvelopeR; break;\n                        case Token.EnvelopeR: envR = d; break;\n                        case Token.EndHz: endHz = d; break;\n                    }\n                    token = \"\";\n                }\n            }\n\n            while (true) {\n                let currNote = scanNextWord();\n                let prevNote: boolean = false;\n                if (!currNote) {\n                    let timeLeft = timePos - now\n                    if (timeLeft > 0)\n                        pause(timeLeft)\n                    if (this.onPlayFinished)\n                        this.onPlayFinished();\n                    return;\n                }\n\n                hz = -1;\n\n                let note: number = 0;\n                token = \"\";\n                tokenKind = Token.Note;\n\n                for (let i = 0; i < currNote.length; i++) {\n                    let noteChar = currNote.charAt(i);\n                    switch (noteChar) {\n                        case 'c': case 'C': note = 1; prevNote = true; break;\n                        case 'd': case 'D': note = 3; prevNote = true; break;\n                        case 'e': case 'E': note = 5; prevNote = true; break;\n                        case 'f': case 'F': note = 6; prevNote = true; break;\n                        case 'g': case 'G': note = 8; prevNote = true; break;\n                        case 'a': case 'A': note = 10; prevNote = true; break;\n                        case 'B': note = 12; prevNote = true; break;\n                        case 'r': case 'R': hz = 0; prevNote = false; break;\n                        case '#': note++; prevNote = false; break;\n                        case 'b': if (prevNote) note--; else { note = 12; prevNote = true; } break;\n                        case ',':\n                            consumeToken();\n                            prevNote = false;\n                            break;\n                        case '!':\n                            tokenKind = Token.Hz;\n                            prevNote = false;\n                            break;\n                        case '@':\n                            consumeToken();\n                            tokenKind = Token.EnvelopeA;\n                            prevNote = false;\n                            break;\n                        case '~':\n                            consumeToken();\n                            tokenKind = Token.WaveForm;\n                            prevNote = false;\n                            break;\n                        case ':':\n                            consumeToken();\n                            tokenKind = Token.Beat;\n                            prevNote = false;\n                            break;\n                        case '-':\n                            consumeToken();\n                            tokenKind = Token.Tempo;\n                            prevNote = false;\n                            break;\n                        case '^':\n                            consumeToken();\n                            tokenKind = Token.EndHz;\n                            break;\n                        default:\n                            if (tokenKind == Token.Note)\n                                tokenKind = Token.Octave;\n                            token += noteChar;\n                            prevNote = false;\n                            break;\n                    }\n                }\n                consumeToken();\n\n                if (note && hz < 0) {\n                    const keyNumber = note + (12 * (octave - 1));\n                    hz = freqs.getNumber(NumberFormat.UInt16LE, keyNumber * 2) || 0;\n                }\n\n                let currMs = ms\n\n                if (currMs <= 0) {\n                    const beat = Math.idiv(15000, tempo);\n                    currMs = duration * beat\n                }\n\n                if (hz < 0) {\n                    // no frequency specified, so no duration\n                } else if (hz == 0) {\n                    timePos += currMs\n                } else {\n                    if (endHz < 0) {\n                        endHz = hz;\n                    }\n\n                    sndInstrPtr = 0\n                    addForm(envA, 0, 255, 0)\n                    addForm(envD, 255, envS, envA)\n                    addForm(currMs - (envA + envD), envS, envS, envD + envA)\n                    addForm(envR, envS, 0, currMs)\n\n                    this.queuePlayInstructions(timePos - now, sndInstr.slice(0, sndInstrPtr))\n                    endHz = -1;\n                    timePos += currMs // don't add envR - it's supposed overlap next sound\n                }\n\n                let timeLeft = timePos - now\n                if (timeLeft > 200) {\n                    pause(timeLeft - 100)\n                    now = control.millis() - startTime\n                }\n            }\n        }\n    }\n\n    //% blockId=music_song_field_editor\n    //% block=\"song $song\"\n    //% song.fieldEditor=musiceditor\n    //% song.fieldOptions.decompileLiterals=true\n    //% song.fieldOptions.taggedTemplate=\"hex;assets.song\"\n    //% song.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% song.fieldOptions.decompileArgumentAsString=\"true\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% help=music/create-song\n    export function createSong(song: Buffer): Playable {\n        return new sequencer.Song(song);\n    }\n\n    export function playInstructions(when: number, instructions: Buffer) {\n        queuePlayInstructions(when, instructions);\n    }\n\n    export function lookupFrequency(note: number) {\n        return freqs.getNumber(NumberFormat.UInt16LE, note * 2) || 0\n    }\n\n    //% fixedInstance whenUsed block=\"ba ding\"\n    export const baDing = new Melody('b5:1 e6:3')\n\n    //% fixedInstance whenUsed block=\"wawawawaa\"\n    export const wawawawaa = new Melody('~15 e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8')\n\n    //% fixedInstance whenUsed block=\"jump up\"\n    export const jumpUp = new Melody('c5:1 d e f g')\n\n    //% fixedInstance whenUsed block=\"jump down\"\n    export const jumpDown = new Melody('g5:1 f e d c')\n\n    //% fixedInstance whenUsed block=\"power up\"\n    export const powerUp = new Melody('g4:1 c5 e g:2 e:1 g:3')\n\n    //% fixedInstance whenUsed block=\"power down\"\n    export const powerDown = new Melody('g5:1 d# c g4:2 b:1 c5:3')\n\n    //% fixedInstance whenUsed block=\"magic wand\"\n    export const magicWand = new Melody('F#6:1-300 G# A# B C7# D# F F# G# A# B:6')\n    //A#7:1-200 A:1 A#7:1 A:1 A#7:2\n\n    //% fixedInstance whenUsed block=\"siren\"\n    export const siren = new Melody('a4 d5 a4 d5 a4 d5')\n\n    //% fixedInstance whenUsed block=\"pew pew\"\n    export const pewPew = new Melody('!1200,200^50')\n\n    //% fixedInstance whenUsed block=\"knock\"\n    export const knock = new Melody('~4 @0,0,255,150 !300,1 !211,1')\n\n    //% fixedInstance whenUsed block=\"footstep\"\n    export const footstep = new Melody('~4 @0,0,60,50 !200,1')\n\n    //% fixedInstance whenUsed block=\"thump\"\n    export const thump = new Melody('~4 @0,0,255,150 !100,1')\n\n    //% fixedInstance whenUsed block=\"small crash\"\n    export const smallCrash = new Melody('~4 @10,490,0,1 !800,1')\n\n    //% fixedInstance whenUsed block=\"big crash\"\n    export const bigCrash = new Melody('~4 @10,990,0,1 !400,1')\n\n    //% fixedInstance whenUsed block=\"zapped\"\n    export const zapped = new Melody('~16 @10,490,0,0 !1600,500^1')\n\n    //% fixedInstance whenUsed block=\"buzzer\"\n    export const buzzer = new Melody('~16 @10,0,255,250 !2000,300')\n\n    //% fixedInstance whenUsed block=\"sonar\"\n    export const sonar = new Melody('~16 @10,1500,0,0 !200,1 !200,1500^190')\n\n    //% fixedInstance whenUsed block=\"spooky\"\n    export const spooky = new Melody('~16 @700,1300,0,0 !100,1 ~18 !108,2000')\n\n    //% fixedInstance whenUsed block=\"beam up\"\n    export const beamUp = new Melody('~18 @10,1500,0,0 !200,1500^4000')\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    //% block=\"2\"\n    Double = 32,\n    //% block=\"4\",\n    Breve = 64,\n    //% block=\"1/3\",\n    Triplet = 128\n}\n\nnamespace music {\n\n    let beatsPerMinute: number;\n\n    /**\n    * Play a tone.\n    * @param frequency pitch of the tone to play in Hertz (Hz), eg: Note.C\n    */\n    //% help=music/ring-tone\n    //% blockId=music_ring block=\"ring tone|at %note=device_note\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music inBasicCategory=true\n    //% weight=75 blockGap=8\n    //% group=\"Tone\"\n    export function ringTone(frequency: number) {\n        playTone(frequency, 0);\n    }\n\n    /**\n    * Rest, or play silence, for some time (in milliseconds).\n    * @param ms rest duration in milliseconds (ms), eg: BeatFraction.Half\n    */\n    //% help=music/rest\n    //% blockId=music_rest block=\"rest|for %duration=device_beat\"\n    //% parts=\"headphone\" trackArgs=0\n    //% blockNamespace=music\n    //% weight=74\n    //% group=\"Tone\"\n    export function rest(ms: number) {\n        playTone(0, Math.max(ms, 20));\n    }\n\n    function init() {\n        if (!beatsPerMinute) beatsPerMinute = 120;\n    }\n\n    /**\n     * Return the duration of a beat in milliseconds (the beat fraction).\n     * @param fraction the fraction of the current whole note, eg: BeatFraction.Half\n     */\n    //% help=music/beat\n    //% blockId=device_beat block=\"%fraction|beat\"\n    //% weight=9 blockGap=8\n    //% group=\"Tempo\"\n    export function beat(fraction?: BeatFraction): number {\n        init();\n        if (fraction == null) fraction = BeatFraction.Whole;\n        let beat = 60000 / beatsPerMinute;\n        switch (fraction) {\n            case BeatFraction.Half: beat /= 2; break;\n            case BeatFraction.Quarter: beat /= 4; break;\n            case BeatFraction.Eighth: beat /= 8; break;\n            case BeatFraction.Sixteenth: beat /= 16; break;\n            case BeatFraction.Double: beat *= 2; break;\n            case BeatFraction.Breve: beat *= 4; break;\n            case BeatFraction.Triplet: beat /= 3; break;\n        }\n        return beat >> 0;\n    }\n\n    /**\n     * Return the tempo in beats per minute (bpm).\n     * 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\n    //% blockId=device_tempo block=\"tempo (bpm)\"\n    //% weight=64\n    //% group=\"Tempo\"\n    export function tempo(): number {\n        init();\n        return beatsPerMinute;\n    }\n\n    /**\n     * Change the tempo up or down by some amount of beats per minute (bpm).\n     * @param bpm The change in beats per minute to the tempo, eg: 20\n     */\n    //% help=music/change-tempo-by weight=37\n    //% blockId=device_change_tempo block=\"change tempo by %value|(bpm)\"\n    //% weight=66 blockGap=8\n    //% group=\"Tempo\"\n    export function changeTempoBy(bpm: number): void {\n        init();\n        setTempo(beatsPerMinute + bpm);\n    }\n\n    /**\n     * Set the tempo a number of beats per minute (bpm).\n     * @param bpm The new tempo in beats per minute, eg: 120\n     */\n    //% help=music/set-tempo\n    //% blockId=device_set_tempo block=\"set tempo to %value|(bpm)\"\n    //% bpm.min=4 bpm.max=400\n    //% weight=65 blockGap=8\n    //% group=\"Tempo\"\n    export function setTempo(bpm: number): void {\n        init();\n        if (bpm > 0) {\n            beatsPerMinute = Math.max(1, bpm >> 0);\n        }\n    }\n}\n","ns.ts":"\n/**\n * Generation of music tones.\n */\n//% color=#E30FC0 weight=90 icon=\"\\uf025\"\n//% blockGap=8\n//% groups='[\"Songs\", \"Sounds\", \"Tone\",  \"Volume\", \"Tempo\"]'\nnamespace music {\n}","piano.ts":"namespace music {\n    /**\n     * Get the frequency of a note.\n     * @param name the note name, eg: Note.C\n     */\n    //% weight=1 help=music/note-frequency\n    //% blockId=device_note block=\"%note\"\n    //% shim=TD_ID\n    //% color=\"#FFFFFF\" colorSecondary=\"#FFFFFF\" colorTertiary=\"#D83B01\"\n    //% note.fieldEditor=\"note\" note.defl=\"262\"\n    //% note.fieldOptions.decompileLiterals=true\n    //% useEnumVal=1\n    //% weight=10 blockGap=8\n    //% group=\"Tone\"\n    export function noteFrequency(name: Note): number {\n        return name;\n    }\n}","playable.ts":"namespace music {\n    export enum PlaybackMode {\n        //% block=\"until done\"\n        UntilDone,\n        //% block=\"in background\"\n        InBackground,\n        //% block=\"looping in background\"\n        LoopingInBackground\n    }\n\n    let stateStack: PlayableState[];\n\n    class PlayableState {\n        looping: Playable[];\n        constructor() {\n            this.looping = [];\n        }\n\n        stopLooping() {\n            for (const p of this.looping) {\n                p.stopped = true;\n            }\n            this.looping = [];\n        }\n    }\n\n    function state() {\n        _init();\n        return stateStack[stateStack.length - 1];\n    }\n\n    function _init() {\n        if (stateStack) return;\n        stateStack = [new PlayableState()];\n\n        game.addScenePushHandler(() => {\n            stateStack.push(new PlayableState());\n        });\n\n        game.addScenePopHandler(() => {\n            stateStack.pop();\n            if (stateStack.length === 0) stateStack.push(new PlayableState());\n        });\n    }\n\n    export class Playable {\n        stopped: boolean;\n        constructor() {\n\n        }\n\n        play(playbackMode: PlaybackMode) {\n            // subclass\n        }\n\n        loop() {\n            state().looping.push(this);\n            this.stopped = false;\n\n            control.runInParallel(() => {\n                while (!this.stopped) {\n                    this.play(PlaybackMode.UntilDone);\n                }\n            });\n        }\n    }\n\n    export class MelodyPlayable extends Playable {\n        constructor(public melody: Melody) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                this.melody.play(music.volume());\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                this.melody.playUntilDone(music.volume());\n            }\n            else {\n                this.melody.loop(music.volume());\n            }\n        }\n    }\n\n    export class TonePlayable extends Playable {\n        constructor(public pitch: number, public duration: number) {\n            super();\n        }\n\n        play(playbackMode: PlaybackMode) {\n            if (playbackMode === PlaybackMode.InBackground) {\n                control.runInParallel(() => music.playTone(this.pitch, this.duration));\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                music.playTone(this.pitch, this.duration);\n                if (this.duration > 2000) {\n                    pause(this.duration);\n                }\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n    /**\n     * Play a song, melody, or other sound. The music plays until finished or can play as a\n     * background task.\n     * @param toPlay the song or melody to play\n     * @param playbackMode play the song or melody until it's finished or as background task\n     */\n    //% blockId=\"music_playable_play\"\n    //% block=\"play $toPlay $playbackMode\"\n    //% toPlay.shadow=music_melody_playable\n    //% group=\"Sounds\"\n    //% help=\"music/play\"\n    export function play(toPlay: Playable, playbackMode: PlaybackMode) {\n        toPlay.play(playbackMode);\n    }\n\n    /**\n     * Create a Playable object for a melody.\n     * @param melody the melody to make playable\n     */\n    //% blockId=\"music_melody_playable\"\n    //% block=\"sound $melody\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    //% blockHidden\n    //% help=music/melody-playable\n    export function melodyPlayable(melody: Melody): Playable {\n        return new MelodyPlayable(melody);\n    }\n\n    /**\n     * Create a Playable object for a melody string containg notes.\n     * @param melody the melody string to make playable\n     */\n    //% blockId=\"music_string_playable\"\n    //% block=\"melody $melody at tempo $tempo|(bpm)\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=85 blockGap=8\n    //% help=music/melody-editor\n    //% group=\"Songs\"\n    //% duplicateShadowOnDrag\n    //% melody.shadow=melody_editor\n    //% tempo.min=40 tempo.max=500\n    //% tempo.defl=120\n    //% help=music/string-playable\n    export function stringPlayable(melody: string, tempo: number): Playable {\n        let notes: string[] = melody.split(\" \").filter(n => !!n);\n        let formattedMelody = \"\";\n        let newOctave = false;\n\n        // build melody string, replace '-' with 'R' and add tempo\n        // creates format like \"C5-174 B4 A G F E D C \"\n        for (let i = 0; i < notes.length; i++) {\n            if (notes[i] === \"-\") {\n                notes[i] = \"R\";\n            } else if (notes[i] === \"C5\") {\n                newOctave = true;\n            } else if (newOctave) { // change the octave if necesary\n                notes[i] += \"4\";\n                newOctave = false;\n            }\n            // add tempo after first note\n            if (i == 0) {\n                formattedMelody += notes[i] + \"-\" + tempo + \" \";\n            } else {\n                formattedMelody += notes[i] + \" \";\n            }\n        }\n\n        return new MelodyPlayable(new Melody(formattedMelody));\n    }\n\n    /**\n     * Create a Playable object for a single tone and its duration.\n     * @param note the note or tone frequency to play\n     * @param duration the duration of the tone in milliseconds (ms)\n     */\n    //% blockId=\"music_tone_playable\"\n    //% block=\"tone $note for $duration\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% group=\"Tone\"\n    //% duplicateShadowOnDrag\n    //% note.shadow=device_note\n    //% duration.shadow=device_beat\n    //% parts=\"headphone\"\n    //% help=music/tone-playable\n    export function tonePlayable(note: number, duration: number): Playable {\n        return new TonePlayable(note, duration);\n    }\n\n    export function _stopPlayables() {\n        state().stopLooping();\n    }\n}","pxt.json":"{\n    \"name\": \"mixer---rp2040\",\n    \"description\": \"The music library with a mixer\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"SoundOutput.h\",\n        \"sound.cpp\",\n        \"melody.h\",\n        \"melody.cpp\",\n        \"melody.ts\",\n        \"piano.ts\",\n        \"legacy.ts\",\n        \"ns.ts\",\n        \"targetoverrides.ts\",\n        \"music.ts\",\n        \"soundEffect.ts\",\n        \"instrument.ts\",\n        \"sequencer.ts\",\n        \"playable.ts\",\n        \"pxtparts.json\",\n        \"headphone.svg\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","pxtparts.json":"{\n    \"headphone\": {\n        \"numberOfPins\": 2,\n        \"visual\": {\n            \"image\": \"headphone.svg\",\n            \"width\": 142,\n            \"height\": 180,\n            \"pinDistance\": 20,\n            \"pinLocations\": [\n                {\n                    \"x\": 17,\n                    \"y\": 11\n                },\n                {\n                    \"x\": 55,\n                    \"y\": 50\n                }\n            ]\n        },\n        \"pinDefinitions\": [\n            {\n                \"target\": \"A0\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            },\n            {\n                \"target\": \"ground\",\n                \"style\": \"croc\",\n                \"orientation\": \"Y\"\n            }\n        ],\n        \"instantiation\": {\n            \"kind\": \"singleton\"\n        },\n        \"assembly\": [\n            {\n                \"part\": true,\n                \"pinIndices\": [\n                    0\n                ]\n            },\n            {\n                \"pinIndices\": [\n                    1\n                ]\n            }\n        ]\n    }\n}","sequencer.ts":"namespace music.sequencer {\n    const SEQUENCER_STOP_MESSAGE = 3243;\n    const SEQUENCER_TICK_MESSAGE = 3244;\n    const SEQUENCER_STATE_CHANGE_MESSAGE = 3245;\n    const SEQUENCER_LOOPED_MESSAGE = 3246;\n\n    export class Sequencer {\n        currentTick: number;\n        isPlaying: boolean;\n        isLooping: boolean;\n        isRunning: boolean;\n\n        constructor(public song: Song) {\n            this.currentTick = 0;\n            this.isPlaying = false;\n            this.isLooping = false;\n        }\n\n        start(loop: boolean) {\n            this.currentTick = 0;\n            this.isLooping = loop;\n            this.isPlaying = true;\n\n            if (this.isRunning) return;\n            this.isRunning = true;\n\n            control.runInParallel(() => {\n                while (this.isPlaying) {\n                    this.scheduleCurrentTick();\n\n                    this.currentTick ++;\n\n                    if (this.currentTick >= this.song.beatsPerMeasure * this.song.measures * this.song.ticksPerBeat) {\n                        if (this.isLooping) this.currentTick = 0;\n                        else this.isPlaying = false;\n                    }\n\n                    pause(this.tickToMs(1))\n                }\n                this.isRunning = false;\n            })\n        }\n\n        stop() {\n            this.isPlaying = false;\n        }\n\n        tickToMs(ticks: number) {\n            return ((60000 / this.song.beatsPerMinute) / this.song.ticksPerBeat) * ticks;\n        }\n\n        protected scheduleCurrentTick() {\n            for (const track of this.song.tracks) {\n                if (track.currentNoteEvent.startTick === this.currentTick) {\n                    if (track.isMelodicTrack) {\n                        this.scheduleMelodicTrack(track as MelodicTrack);\n                    }\n                    else {\n                        this.scheduleDrumTrack(track as DrumTrack);\n                    }\n\n                    track.advanceNoteEvent();\n                }\n            }\n        }\n\n        protected scheduleMelodicTrack(track: MelodicTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderInstrument(\n                        track.instrument,\n                        lookupFrequency(track.currentNoteEvent.getNote(i, track.instrument.octave)),\n                        this.tickToMs(track.currentNoteEvent.endTick - track.currentNoteEvent.startTick),\n                        music.volume()\n                    )\n                );\n            }\n        }\n\n        protected scheduleDrumTrack(track: DrumTrack) {\n            for (let i = 0; i < track.currentNoteEvent.polyphony; i++) {\n                playInstructions(\n                    0,\n                    renderDrumInstrument(\n                        track.drums[track.currentNoteEvent.getNote(i, undefined)],\n                        music.volume()\n                    )\n                );\n            }\n        }\n    }\n\n    let activeSimSequencers: _SimulatorSequencer[];\n    export function _stopAllSimSequencers() {\n        if (activeSimSequencers) {\n            for (const seq of activeSimSequencers) {\n                seq.stop();\n                seq.dispose();\n            }\n            activeSimSequencers = [];\n        }\n    }\n\n    // Simulator only! Does nothing on hardware\n    export class _SimulatorSequencer {\n        protected id: number;\n\n        constructor() {\n            if (!activeSimSequencers) activeSimSequencers = [];\n            activeSimSequencers.push(this);\n            this.id = _createSequencer();\n            this.setVolume(music.volume());\n        }\n\n        play(song: Buffer, loop: boolean) {\n            this.setVolume(music.volume());\n            _sequencerPlaySong(this.id, song, loop)\n        }\n\n        stop() {\n            _sequencerStop(this.id);\n        }\n\n        setVolume(volume: number) {\n            _sequencerSetVolume(this.id, volume);\n        }\n\n        setTrackVolume(trackIndex: number, volume: number) {\n            _sequencerSetTrackVolume(this.id, trackIndex, volume)\n        }\n\n        setDrumTrackVolume(trackIndex: number, drumIndex: number, volume: number) {\n            _sequencerSetDrumTrackVolume(this.id, drumIndex, trackIndex, volume)\n        }\n\n        state() {\n            return _sequencerState(this.id) || \"stop\";\n        }\n\n        currentTick() {\n            return _sequencerCurrentTick(this.id);\n        }\n\n        dispose() {\n            _sequencerDispose(this.id);\n        }\n\n        onTick(handler: (tick: number) => void) {\n            control.onEvent(SEQUENCER_TICK_MESSAGE, this.id, () => {\n                handler(this.currentTick());\n            });\n        }\n\n        onStateChange(handler: (state: string) => void) {\n            control.onEvent(SEQUENCER_STATE_CHANGE_MESSAGE, this.id, () => {\n                handler(this.state());\n            });\n        }\n\n        onStop(handler: () => void) {\n            control.onEvent(SEQUENCER_STOP_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n\n        onLooped(handler: () => void) {\n            control.onEvent(SEQUENCER_LOOPED_MESSAGE, this.id, () => {\n                handler();\n            });\n        }\n    }\n\n    //% promise\n    //% shim=music::_createSequencer\n    declare function _createSequencer(): number\n\n    //% shim=music::_sequencerState\n    declare function _sequencerState(id: number): string;\n\n    //% shim=music::_sequencerCurrentTick\n    declare function _sequencerCurrentTick(id: number): number;\n\n    //% shim=music::_sequencerPlaySong\n    declare function _sequencerPlaySong(id: number, song: Buffer, loop: boolean): void;\n\n    //% shim=music::_sequencerStop\n    declare function _sequencerStop(id: number): void;\n\n    //% shim=music::_sequencerSetVolume\n    declare function _sequencerSetVolume(id: number, volume: number): void;\n\n    //% shim=music::_sequencerSetVolumeForAll\n    declare function _sequencerSetVolumeForAll(volume: number): void;\n\n    //% shim=music::_sequencerSetTrackVolume\n    declare function _sequencerSetTrackVolume(id: number, trackIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerSetDrumTrackVolume\n    declare function _sequencerSetDrumTrackVolume(id: number, trackIndex: number, drumIndex: number, volume: number): void;\n\n    //% shim=music::_sequencerDispose\n    declare function _sequencerDispose(id: number): void;\n}","sound.cpp":"// to be overridden\n","soundEffect.ts":"enum WaveShape {\n    //% block=\"sine\"\n    Sine = 0,\n    //% block=\"sawtooth\"\n    Sawtooth = 1,\n    //% block=\"triangle\"\n    Triangle = 2,\n    //% block=\"square\"\n    Square = 3,\n    //% block=\"noise\"\n    Noise = 4\n}\n\nenum InterpolationCurve {\n    //% block=\"linear\"\n    Linear,\n    //% block=\"curve\"\n    Curve,\n    //% block=\"logarithmic\"\n    Logarithmic\n}\n\nenum SoundExpressionEffect {\n    //% block=\"none\"\n    None = 0,\n    //% block=\"vibrato\"\n    Vibrato = 1,\n    //% block=\"tremolo\"\n    Tremolo = 2,\n    //% block=\"warble\"\n    Warble = 3\n}\n\nenum SoundExpressionPlayMode {\n    //% block=\"until done\"\n    UntilDone,\n    //% block=\"in background\"\n    InBackground\n}\n\nnamespace music {\n    export class SoundEffect extends Playable {\n        waveShape: WaveShape;\n        startFrequency: number;\n        endFrequency: number;\n        startVolume: number;\n        endVolume: number;\n        duration: number;\n        effect: SoundExpressionEffect;\n        interpolation: InterpolationCurve;\n\n        constructor() {\n            super();\n            this.waveShape = WaveShape.Sine;\n            this.startFrequency = 5000;\n            this.endFrequency = 1;\n            this.startVolume = 255;\n            this.endVolume = 0;\n            this.duration = 1000;\n            this.effect = SoundExpressionEffect.None;\n            this.interpolation = InterpolationCurve.Linear;\n        }\n\n        toBuffer(volume?: number) {\n            if (volume === undefined) volume = music.volume();\n\n            return soundToInstructionBuffer(\n                this.waveShape,\n                this.startFrequency,\n                this.endFrequency,\n                this.startVolume,\n                this.endVolume,\n                this.duration,\n                this.effect,\n                this.interpolation,\n                20,\n                1,\n                volume\n            );\n        }\n\n        play(playbackMode: PlaybackMode) {\n            const toPlay = this.toBuffer(music.volume());\n            if (playbackMode === PlaybackMode.InBackground) {\n                queuePlayInstructions(0, toPlay);\n            }\n            else if (playbackMode === PlaybackMode.UntilDone) {\n                queuePlayInstructions(0, toPlay);\n                pause(this.duration)\n            }\n            else {\n                this.loop();\n            }\n        }\n    }\n\n\n    /**\n     * Play a SoundEffect.\n     * @param sound the SoundEffect to play\n     * @param mode the play mode, play until done or in the background\n     */\n    //% blockId=soundExpression_playSoundEffect\n    //% block=\"play sound $sound $mode\"\n    //% weight=30\n    //% help=music/play-sound-effect\n    //% blockGap=8\n    //% group=\"Sounds\"\n    //% deprecated=1\n    export function playSoundEffect(sound: SoundEffect, mode: SoundExpressionPlayMode) {\n        const toPlay = sound.toBuffer(music.volume());\n\n        queuePlayInstructions(0, toPlay);\n        if (mode === SoundExpressionPlayMode.UntilDone) {\n            pause(sound.duration);\n        }\n    }\n\n    /**\n     * Create a sound expression from a set of sound effect parameters.\n     * @param waveShape waveform of the sound effect\n     * @param startFrequency starting frequency for the sound effect waveform\n     * @param endFrequency ending frequency for the sound effect waveform\n     * @param startVolume starting volume of the sound, or starting amplitude\n     * @param endVolume ending volume of the sound, or ending amplitude\n     * @param duration the amount of time in milliseconds (ms) that sound will play for\n     * @param effect the effect to apply to the waveform or volume\n     * @param interpolation interpolation method for frequency scaling\n     */\n    //% blockId=soundExpression_createSoundEffect\n    //% help=music/create-sound-effect\n    //% block=\"$waveShape|| start frequency $startFrequency end frequency $endFrequency duration $duration start volume $startVolume end volume $endVolume effect $effect interpolation $interpolation\"\n    //% waveShape.defl=WaveShape.Sine\n    //% waveShape.fieldEditor=soundeffect\n    //% waveShape.fieldOptions.useMixerSynthesizer=true\n    //% startFrequency.defl=5000\n    //% startFrequency.min=0\n    //% startFrequency.max=5000\n    //% endFrequency.defl=0\n    //% endFrequency.min=0\n    //% endFrequency.max=5000\n    //% startVolume.defl=255\n    //% startVolume.min=0\n    //% startVolume.max=255\n    //% endVolume.defl=0\n    //% endVolume.min=0\n    //% endVolume.max=255\n    //% duration.defl=500\n    //% duration.min=1\n    //% duration.max=9999\n    //% effect.defl=SoundExpressionEffect.None\n    //% interpolation.defl=InterpolationCurve.Linear\n    //% compileHiddenArguments=true\n    //% inlineInputMode=\"variable\"\n    //% inlineInputModeLimit=3\n    //% expandableArgumentBreaks=\"3,5\"\n    //% toolboxParent=music_playable_play\n    //% toolboxParentArgument=toPlay\n    //% weight=20\n    //% group=\"Sounds\"\n    //% duplicateShadowOnDrag\n    export function createSoundEffect(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve): SoundEffect {\n        const result = new SoundEffect();\n\n        result.waveShape = waveShape;\n        result.startFrequency = startFrequency;\n        result.endFrequency = endFrequency;\n        result.startVolume = startVolume;\n        result.endVolume = endVolume;\n        result.duration = duration;\n        result.effect = effect;\n        result.interpolation = interpolation;\n\n        return result;\n    }\n\n    interface Step {\n        frequency: number;\n        volume: number;\n    }\n\n     export function soundToInstructionBuffer(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve, fxSteps: number, fxRange: number, globalVolume: number) {\n        const steps: Step[] = [];\n\n        // Optimize the simple case\n        if (interpolation === InterpolationCurve.Linear && effect === SoundExpressionEffect.None) {\n            steps.push({\n                frequency: startFrequency,\n                volume: (startVolume / 255) * globalVolume,\n            })\n            steps.push({\n                frequency: endFrequency,\n                volume: (endVolume / 255) * globalVolume,\n            })\n        }\n        else {\n\n            fxSteps = Math.min(fxSteps, Math.floor(duration / 5))\n\n            const getVolumeAt = (t: number) => ((startVolume + t * (endVolume - startVolume) / duration) / 255) * globalVolume;\n            let getFrequencyAt: (t: number) => number;\n\n            switch (interpolation) {\n                case InterpolationCurve.Linear:\n                    getFrequencyAt = t => startFrequency + t * (endFrequency - startFrequency) / duration;\n                    break;\n                case InterpolationCurve.Curve:\n                    getFrequencyAt = t => startFrequency + (endFrequency - startFrequency) * Math.sin(t / duration * (Math.PI / 2));\n                    break;\n                case InterpolationCurve.Logarithmic:\n                    getFrequencyAt = t => startFrequency + (Math.log(1 + 9 * (t / duration)) / Math.log(10)) * (endFrequency - startFrequency)\n                    break;\n            }\n\n            const timeSlice = duration / fxSteps;\n\n            for (let i = 0; i < fxSteps; i++) {\n                const newStep = {\n                    frequency: getFrequencyAt(i * timeSlice),\n                    volume: getVolumeAt(i * timeSlice)\n                };\n\n                if (effect === SoundExpressionEffect.Tremolo) {\n                    if (i % 2 === 0) {\n                        newStep.volume = Math.max(newStep.volume - fxRange * 500, 0)\n                    }\n                    else {\n                        newStep.volume = Math.min(newStep.volume + fxRange * 500, 1023)\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Vibrato) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 100, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 100\n                    }\n                }\n                else if (effect === SoundExpressionEffect.Warble) {\n                    if (i % 2 === 0) {\n                        newStep.frequency = Math.max(newStep.frequency - fxRange * 1000, 0)\n                    }\n                    else {\n                        newStep.frequency = newStep.frequency + fxRange * 1000\n                    }\n                }\n\n                steps.push(newStep)\n            }\n        }\n\n        const out = control.createBuffer(12 * (steps.length - 1));\n        const stepDuration = Math.floor(duration / (steps.length - 1))\n\n        for (let i = 0; i < steps.length - 1; i++) {\n            const offset = i * 12;\n            out.setNumber(NumberFormat.UInt8LE, offset, waveToValue(waveShape));\n            out.setNumber(NumberFormat.UInt16LE, offset + 2, steps[i].frequency);\n            out.setNumber(NumberFormat.UInt16LE, offset + 4, stepDuration);\n            out.setNumber(NumberFormat.UInt16LE, offset + 6, steps[i].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 8, steps[i + 1].volume);\n            out.setNumber(NumberFormat.UInt16LE, offset + 10, steps[i + 1].frequency);\n        }\n\n        return out;\n    }\n\n    function waveToValue(wave: WaveShape) {\n        switch (wave) {\n            case WaveShape.Square: return 15;\n            case WaveShape.Sine: return 3;\n            case WaveShape.Triangle: return 1;\n            case WaveShape.Noise: return 18;\n            case WaveShape.Sawtooth: return 2;\n        }\n    }\n\n\n    /**\n     * Generate a random similar sound effect to the given one.\n     *\n     * @param sound the sound effect\n     */\n    //% blockId=soundExpression_generateSimilarSound\n    //% block=\"randomize $sound\"\n    //% sound.shadow=soundExpression_createSoundEffect\n    //% weight=0 help=music/randomize-sound\n    //% blockGap=8\n    //% group=\"Sounds\"\n    export function randomizeSound(sound: SoundEffect) {\n        const res = new SoundEffect();\n        res.waveShape = sound.waveShape;\n        res.startFrequency = sound.startFrequency;\n        res.endFrequency = sound.endFrequency;\n        res.startVolume = sound.startVolume;\n        res.endVolume = sound.endVolume;\n        res.duration = sound.duration;\n        res.effect = sound.effect;\n        res.interpolation = randomInterpolation();\n\n        res.duration = Math.clamp(\n            Math.min(100, res.duration),\n            Math.max(2000, res.duration),\n            res.duration + (Math.random() - 0.5) * res.duration,\n        );\n\n        if (res.waveShape === WaveShape.Noise) {\n            // The primary waveforms don't produce sounds that are similar to noise,\n            // but adding an effect sorta does\n            if (Math.percentChance(20)) {\n                res.waveShape = randomWave();\n                res.effect = randomEffect();\n            }\n        }\n        else {\n            res.waveShape = randomWave();\n\n            // Adding an effect can drastically alter the sound, so keep it\n            // at a low percent chance unless there already is one\n            if (res.effect !== SoundExpressionEffect.None || Math.percentChance(10)) {\n                res.effect = randomEffect();\n            }\n        }\n\n        // Instead of randomly changing the frequency, change the slope and choose\n        // a new start frequency. This keeps a similar profile to the sound\n        const oldFrequencyDifference = res.endFrequency - res.startFrequency;\n        let newFrequencyDifference = oldFrequencyDifference + (oldFrequencyDifference * 2) * (Math.random() - 0.5);\n\n        if (Math.sign(oldFrequencyDifference) !== Math.sign(newFrequencyDifference)) {\n            newFrequencyDifference *= -1;\n        }\n\n        newFrequencyDifference = Math.clamp(-5000, 5000, newFrequencyDifference);\n\n        res.startFrequency = Math.clamp(\n            Math.max(-newFrequencyDifference, 1),\n            Math.clamp(1, 5000, 5000 - newFrequencyDifference),\n            Math.random() * 5000,\n        );\n\n        res.endFrequency = Math.clamp(1, 5000, res.startFrequency + newFrequencyDifference);\n\n        // Same strategy for volume\n        const oldVolumeDifference = res.endVolume - res.startVolume;\n        let newVolumeDifference = oldVolumeDifference + oldVolumeDifference * (Math.random() - 0.5);\n\n        newVolumeDifference = Math.clamp(-255, 255, newVolumeDifference);\n\n        if (Math.sign(oldVolumeDifference) !== Math.sign(newVolumeDifference)) {\n            newVolumeDifference *= -1;\n        }\n\n        res.startVolume = Math.clamp(\n            Math.max(-newVolumeDifference, 0),\n            Math.clamp(0, 255, 255 - newVolumeDifference),\n            Math.random() * 255,\n        );\n\n        res.endVolume = Math.clamp(0, 255, res.startVolume + newVolumeDifference);\n\n        return res;\n    }\n\n    function randomWave() {\n        switch (Math.randomRange(0, 3)) {\n            case 1: return WaveShape.Sawtooth;\n            case 2: return WaveShape.Square;\n            case 3: return WaveShape.Triangle;\n            case 0:\n            default:\n                return WaveShape.Sine;\n        }\n    }\n\n    function randomEffect() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return SoundExpressionEffect.Warble;\n            case 2: return  SoundExpressionEffect.Tremolo;\n            case 0:\n            default:\n                return SoundExpressionEffect.Vibrato;\n        }\n    }\n\n    function randomInterpolation() {\n        switch (Math.randomRange(0, 2)) {\n            case 1: return InterpolationCurve.Linear;\n            case 2: return  InterpolationCurve.Curve;\n            case 0:\n            default:\n                return InterpolationCurve.Logarithmic;\n        }\n    }\n\n    //% shim=music::queuePlayInstructions\n    function queuePlayInstructions(timeDelta: number, buf: Buffer) { }\n}","targetoverrides.ts":"\n","test.ts":"for(let i = 1000; i > 0; i -= 50)\n    music.playTone(440, i)\n\nfor(let i = 0; i < 1000; i += 20)\n    music.playTone(440, i)\n"},"mouse":{"enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum MouseButton {\n    //% block=\"left\" enumval=1\n    Left = 0x01,\n    //% block=\"right\" enumval=2\n    Right = 0x02,\n    //% block=\"middle\" enumval=4\n    Middle = 0x04,\n    }\n\n// Auto-generated. Do not edit. Really.\n","mouse.cpp":"// https://github.com/lancaster-university/codal-core/blob/master/source/drivers/HIDMouse.cpp\n\n#include \"pxt.h\"\n\nenum class MouseButton {\n    //% block=\"left\" enumval=1\n    Left = 0x01,\n    //% block=\"right\" enumval=2\n    Right = 0x02,\n    //% block=\"middle\" enumval=4\n    Middle = 0x04\n};\n\nnamespace mouse {\n    /** \n    * Set the mouse button state to up or down\n    */\n    //% help=mouse/set-button\n    //% blockId=mouseSetButton block=\"mouse button %index|%down=toggleDownUp\"\n    void setButton(MouseButton button, bool down) {\n        if (down)\n            pxt::mouse.buttonDown((codal::USBHIDMouseButton)button);\n        else\n            pxt::mouse.buttonUp((codal::USBHIDMouseButton)button);\n    }\n\n    /**\n    * Move the mouse in the X and Y direction\n    **/\n    //% help=mouse/move\n    //% blockId=mouseMove block=\"mouse move x %x|y %y\"\n    //% x.min=-128 x.max=127\n    //% y.min=-128 y.max=127\n    void move(int x, int y) {\n        pxt::mouse.move(x, y);\n    }\n\n    /**\n    * Turn the mouse wheel\n    **/\n    //% help=mouse/turn-wheel\n    //% blockId=mouseWheel block=\"mouse turn wheel %w\"\n    //% w.min=-128 w.max=127\n    void turnWheel(int w) {\n        pxt::mouse.moveWheel(w);\n    }\n}","mouse.ts":"/**\n * Mouse emulation\n */\n//% icon=\"\\uf245\" color=\"#303030\"\nnamespace mouse {\n    /**\n     * Generates a mouse click\n     * @param button the button to click\n     */\n    //% help=mouse/click\n    //% blockId=mouseClick block=\"mouse click button $button\"\n    //% weight=100\n    export function click(button: MouseButton): void {\n        mouse.setButton(button, true)\n        mouse.setButton(button, false)\n    }\n}","pxt.json":"{\n    \"name\": \"mouse\",\n    \"description\": \"Mouse emulation over HID\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"mouse.cpp\",\n        \"shims.d.ts\",\n        \"enums.d.ts\",\n        \"mouse.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"searchOnly\": true,\n    \"tests\": [\n        \"test.ts\"\n    ],\n    \"yotta\": {\n        \"config\": {\n            \"DEVICE_USB\": 1,\n            \"DEVICE_MOUSE\": 1\n        }\n    },\n    \"icon\": \"/static/libs/mouse.png\"\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace mouse {\n\n    /** \n     * Set the mouse button state to up or down\n     */\n    //% help=mouse/set-button\n    //% blockId=mouseSetButton block=\"mouse button %index|%down=toggleDownUp\" shim=mouse::setButton\n    function setButton(button: MouseButton, down: boolean): void;\n\n    /**\n     * Move the mouse in the X and Y direction\n     **/\n    //% help=mouse/move\n    //% blockId=mouseMove block=\"mouse move x %x|y %y\"\n    //% x.min=-128 x.max=127\n    //% y.min=-128 y.max=127 shim=mouse::move\n    function move(x: int32, y: int32): void;\n\n    /**\n     * Turn the mouse wheel\n     **/\n    //% help=mouse/turn-wheel\n    //% blockId=mouseWheel block=\"mouse turn wheel %w\"\n    //% w.min=-128 w.max=127 shim=mouse::turnWheel\n    function turnWheel(w: int32): void;\n}\n\n// Auto-generated. Do not edit. Really.\n"},"mqtt":{"README.md":"# MQTT\n\nMQTT communication layer. A port of https://github.com/rovale/micro-mqtt for MakeCode.\n","mqtt.ts":"namespace mqtt {\n    /**\n     * Connect flags\n     * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc385349229\n     */\n    export const enum ConnectFlags {\n        UserName = 128,\n        Password = 64,\n        WillRetain = 32,\n        WillQoS2 = 16,\n        WillQoS1 = 8,\n        Will = 4,\n        CleanSession = 2\n    }\n\n    /**\n     * Connect Return code\n     * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc385349256\n     */\n    export const enum ConnectReturnCode {\n        Unknown = -1,\n        Accepted = 0,\n        UnacceptableProtocolVersion = 1,\n        IdentifierRejected = 2,\n        ServerUnavailable = 3,\n        BadUserNameOrPassword = 4,\n        NotAuthorized = 5\n    }\n\n    /**\n     * A message received in a Publish packet.\n     */\n    export interface IMessage {\n        pid?: number;\n        topic: string;\n        content: Buffer;\n        qos: number;\n        retain: number;\n    }\n\n    /**\n     * MQTT Control Packet type\n     * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc353481061\n     */\n    export const enum ControlPacketType {\n        Connect = 1,\n        ConnAck = 2,\n        Publish = 3,\n        PubAck = 4,\n        // PubRec = 5,\n        // PubRel = 6,\n        // PubComp = 7,\n        Subscribe = 8,\n        SubAck = 9,\n        Unsubscribe = 10,\n        UnsubAck = 11,\n        PingReq = 12,\n        PingResp = 13,\n        Disconnect = 14\n    }\n\n    /**\n     * Optimization, the TypeScript compiler replaces the constant enums.\n     */\n    export const enum Constants {\n        PingInterval = 40,\n        WatchDogInterval = 50,\n        DefaultQos = 0,\n        Uninitialized = -123,\n        FixedPackedId = 1,\n        KeepAlive = 60\n    }\n\n    /**\n     * The options used to connect to the MQTT broker.\n     */\n    export interface IConnectionOptions {\n        host: string;\n        port?: number;\n        username?: string;\n        password?: string;\n        clientId: string;\n        will?: IConnectionOptionsWill;\n    }\n\n    export interface IConnectionOptionsWill {\n        topic: string;\n        message: string;\n        qos?: number;\n        retain?: boolean;\n    }\n\n    /**\n     * The specifics of the MQTT protocol.\n     */\n    export module Protocol {\n        function strChr(codes: number[]): Buffer {\n            return pins.createBufferFromArray(codes)\n        }\n\n        /**\n         * Encode remaining length\n         * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718023\n         */\n        function encodeRemainingLength(remainingLength: number): number[] {\n            let length: number = remainingLength;\n            const encBytes: number[] = [];\n            do {\n                let encByte: number = length & 127;\n                length = length >> 7;\n                // if there are more data to encode, set the top bit of this byte\n                if (length > 0) {\n                    encByte += 128;\n                }\n                encBytes.push(encByte);\n            } while (length > 0);\n\n            return encBytes;\n        }\n\n        /**\n         * Connect flags\n         * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc385349229\n         */\n        function createConnectFlags(options: IConnectionOptions): number {\n            let flags: number = 0;\n            flags |= (options.username) ? ConnectFlags.UserName : 0;\n            flags |= (options.username && options.password) ? ConnectFlags.Password : 0;\n            flags |= ConnectFlags.CleanSession;\n\n            if (options.will) {\n                flags |= ConnectFlags.Will;\n                flags |= (options.will.qos || 0) << 3;\n                flags |= (options.will.retain) ? ConnectFlags.WillRetain : 0;\n            }\n\n            return flags;\n        }\n\n        // Returns the MSB and LSB.\n        function getBytes(int16: number): number[] {\n            return [int16 >> 8, int16 & 255];\n        }\n\n        /**\n         * Structure of UTF-8 encoded strings\n         * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Figure_1.1_Structure\n         */\n        function pack(s: string): Buffer {\n            const buf = control.createBufferFromUTF8(s);\n            return strChr(getBytes(buf.length)).concat(buf);\n        }\n\n        /**\n         * Structure of an MQTT Control Packet\n         * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800392\n         */\n        function createPacketHeader(byte1: number, variable: Buffer, payloadSize: number): Buffer {\n            const byte2: number[] = encodeRemainingLength(variable.length + payloadSize);\n            return strChr([byte1])\n                .concat(strChr(byte2))\n                .concat(variable)\n        }\n\n        /**\n         * Structure of an MQTT Control Packet\n         * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800392\n         */\n        function createPacket(byte1: number, variable: Buffer, payload?: Buffer): Buffer {\n            if (payload == null) payload = control.createBuffer(0);\n            return createPacketHeader(byte1, variable, payload.length).concat(payload)\n        }\n\n        /**\n         * CONNECT - Client requests a connection to a Server\n         * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718028\n         */\n        export function createConnect(options: IConnectionOptions): Buffer {\n            const byte1: number = ControlPacketType.Connect << 4;\n\n            const protocolName = pack('MQTT');\n            const nums = control.createBuffer(4)\n            nums[0] = 4; // protocol level\n            nums[1] = createConnectFlags(options)\n            nums[2] = 0\n            nums[3] = Constants.KeepAlive\n\n            let payload = pack(options.clientId);\n\n            if (options.will) {\n                payload = payload\n                    .concat(pack(options.will.topic)\n                        .concat(pack(options.will.message)));\n            }\n\n            if (options.username) {\n                payload = payload.concat(pack(options.username));\n                if (options.password) {\n                    payload = payload.concat(pack(options.password));\n                }\n            }\n\n            return createPacket(\n                byte1,\n                protocolName.concat(nums),\n                payload\n            );\n        }\n\n        /** PINGREQ - PING request\n         * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800454\n         */\n        export function createPingReq() {\n            return strChr([ControlPacketType.PingReq << 4, 0]);\n        }\n\n        /**\n         * PUBLISH - Publish message header - doesn't include \"payload\"\n         * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800410\n         */\n        export function createPublishHeader(topic: string, payloadSize: number, qos: number, retained: boolean) {\n            let byte1: number = ControlPacketType.Publish << 4 | (qos << 1);\n            byte1 |= (retained) ? 1 : 0;\n\n            const pid = strChr(getBytes(Constants.FixedPackedId));\n            const variable = (qos === 0) ? pack(topic) : pack(topic).concat(pid);\n\n            return createPacketHeader(byte1, variable, payloadSize);\n        }\n\n        export function parsePublish(cmd: number, payload: Buffer): IMessage {\n            const qos: number = (cmd & 0b00000110) >> 1;\n\n            const topicLength = payload.getNumber(NumberFormat.UInt16BE, 0);\n            let variableLength: number = 2 + topicLength;\n            if (qos > 0) {\n                variableLength += 2;\n            }\n\n            const message: IMessage = {\n                topic: payload.slice(2, topicLength).toString(),\n                content: payload.slice(variableLength),\n                qos: qos,\n                retain: cmd & 1\n            };\n\n            if (qos > 0)\n                message.pid = payload.getNumber(NumberFormat.UInt16BE, variableLength - 2);\n\n            return message;\n        }\n\n        /**\n         * PUBACK - Publish acknowledgement\n         * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800416\n         */\n        export function createPubAck(pid: number) {\n            const byte1: number = ControlPacketType.PubAck << 4;\n\n            return createPacket(byte1, strChr(getBytes(pid)));\n        }\n\n        /**\n         * SUBSCRIBE - Subscribe to topics\n         * http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800436\n         */\n        export function createSubscribe(topic: string, qos: number): Buffer {\n            const byte1: number = ControlPacketType.Subscribe << 4 | 2;\n            const pid = strChr(getBytes(Constants.FixedPackedId));\n\n            return createPacket(byte1,\n                pid,\n                pack(topic).concat(strChr([qos])))\n        }\n    }\n\n    export type EventHandler = (arg?: string | IMessage) => void;\n\n    export class EventEmitter {\n        private handlers: { [index: string]: EventHandler[] };\n\n        constructor() {\n            this.handlers = {};\n        }\n\n        public on(event: string, listener: EventHandler): void {\n            if (!event || !listener) return;\n\n            let listeners = this.handlers[event];\n            if (!listeners)\n                this.handlers[event] = listeners = [];\n            listeners.push(listener);\n        }\n        protected emit(event: string, arg?: string | IMessage): boolean {\n            let listeners = this.handlers[event];\n            if (listeners) {\n                listeners.forEach(listener => listener(arg));\n            }\n            return true;\n        }\n    }\n\n    enum HandlerStatus {\n        Normal = 0,\n        Once = 1,\n        ToRemove = 2,\n    }\n\n    class MQTTHandler {\n        public status: HandlerStatus\n        constructor(\n            public topic: string,\n            public handler: (m: IMessage) => void\n        ) {\n            this.status = HandlerStatus.Normal\n        }\n    }\n\n    export enum Status {\n        Disconnected = 0,\n        Connecting = 1,\n        Connected = 2,\n        Sending = 3,\n    }\n\n    export class Client extends EventEmitter {\n        public logPriority = ConsolePriority.Debug\n        public tracePriority = -1 as ConsolePriority;\n\n        private log(msg: string) {\n            console.add(this.logPriority, `mqtt: ${msg}`);\n        }\n\n        private trace(msg: string) {\n            console.add(this.tracePriority, `mqtt: ${msg}`);\n        }\n\n        public opt: IConnectionOptions;\n\n        private net: net.Net;\n        private sct?: net.Socket;\n\n        private wdId: number;\n        private piId: number;\n\n        private buf: Buffer;\n        // we re-send subscriptions on re-connect\n        private subs: Buffer[] = [];\n\n        public status = Status.Disconnected\n\n        get connected() {\n            return this.status >= Status.Connected\n        }\n\n        private mqttHandlers: MQTTHandler[];\n\n        constructor(opt: IConnectionOptions) {\n            super();\n\n            this.wdId = Constants.Uninitialized;\n            this.piId = Constants.Uninitialized;\n            opt.port = opt.port || 8883;\n            opt.clientId = opt.clientId;\n\n            if (opt.will) {\n                opt.will.qos = opt.will.qos || Constants.DefaultQos;\n                opt.will.retain = opt.will.retain || false;\n            }\n\n            this.opt = opt;\n            this.net = net.instance();\n        }\n\n        private static describe(code: ConnectReturnCode): string {\n            let error: string = 'Connection refused, ';\n            switch (code) {\n                case ConnectReturnCode.UnacceptableProtocolVersion:\n                    error += 'unacceptable protocol version.';\n                    break;\n                case ConnectReturnCode.IdentifierRejected:\n                    error += 'identifier rejected.';\n                    break;\n                case ConnectReturnCode.ServerUnavailable:\n                    error += 'server unavailable.';\n                    break;\n                case ConnectReturnCode.BadUserNameOrPassword:\n                    error += 'bad user name or password.';\n                    break;\n                case ConnectReturnCode.NotAuthorized:\n                    error += 'not authorized.';\n                    break;\n                default:\n                    error += `unknown return code: ${code}.`;\n            }\n\n            return error;\n        }\n\n        public disconnect(): void {\n            this.log(\"disconnect\")\n            if (this.wdId !== Constants.Uninitialized) {\n                clearInterval(this.wdId);\n                this.wdId = Constants.Uninitialized;\n            }\n\n            if (this.piId !== Constants.Uninitialized) {\n                clearInterval(this.piId);\n                this.piId = Constants.Uninitialized;\n            }\n\n            const s = this.sct\n            if (s) {\n                this.sct = null\n                s.close()\n            }\n\n            this.status = Status.Disconnected\n        }\n\n        public connect(): void {\n            if (this.status != Status.Disconnected)\n                return\n            this.status = Status.Connecting\n            this.log(`Connecting to ${this.opt.host}:${this.opt.port}`);\n            if (this.wdId === Constants.Uninitialized) {\n                this.wdId = setInterval(() => {\n                    if (!this.connected) {\n                        this.emit('disconnected');\n                        this.emit('error', 'No connection. Retrying.');\n                        this.disconnect();\n                        this.connect();\n                    }\n                }, Constants.WatchDogInterval * 1000);\n            }\n\n            this.sct = this.net.createSocket(this.opt.host, this.opt.port, true);\n            this.sct.onOpen(() => {\n                this.log('Network connection established.');\n                this.emit('connect');\n                this.send(Protocol.createConnect(this.opt));\n            });\n            this.sct.onMessage((msg: Buffer) => {\n                this.trace(\"incoming \" + msg.length + \" bytes\")\n                this.handleMessage(msg);\n            });\n            this.sct.onError(() => {\n                this.log('Error.');\n                this.emit('error');\n            });\n            this.sct.onClose(() => {\n                this.log('Close.');\n                this.emit('disconnected');\n                this.status = Status.Disconnected\n                this.sct = null;\n            });\n            this.sct.connect();\n        }\n\n        private canSend() {\n            let cnt = 0\n            while (true) {\n                if (this.status == Status.Connected) {\n                    this.status = Status.Sending\n                    return true\n                }\n                if (cnt++ < 100 && this.status == Status.Sending)\n                    pause(20)\n                else {\n                    this.log(\"drop pkt\")\n                    return false\n                }\n            }\n        }\n\n        private doneSending() {\n            this.trace(\"done send\")\n            if (this.status == Status.Sending)\n                this.status = Status.Connected\n        }\n\n        // Publish a message\n        public publish(topic: string, message?: string | Buffer, qos: number = Constants.DefaultQos, retained: boolean = false): void {\n            const buf = typeof message == \"string\" ? control.createBufferFromUTF8(message) : message\n            message = null\n            if (this.startPublish(topic, buf ? buf.length : 0, qos, retained)) {\n                if (buf)\n                    this.send(buf);\n                this.finishPublish()\n            }\n        }\n\n        public startPublish(topic: string, messageLen: number, qos: number = Constants.DefaultQos, retained: boolean = false) {\n            if (!this.canSend()) return false\n            this.trace(`publish: ${topic} ${messageLen}b`)\n            this.send(Protocol.createPublishHeader(topic, messageLen, qos, retained));\n            return true\n        }\n\n        public continuePublish(data: Buffer) {\n            this.send(data)\n        }\n\n        public finishPublish() {\n            this.doneSending()\n            this.emit(\"published\")\n        }\n\n        private subscribeCore(topic: string, handler: (msg: IMessage) => void, qos: number = Constants.DefaultQos): MQTTHandler {\n            this.log(`subscribe: ${topic}`)\n            const sub = Protocol.createSubscribe(topic, qos)\n            this.subs.push(sub)\n            this.send1(sub);\n            if (handler) {\n                if (topic[topic.length - 1] == \"#\")\n                    topic = topic.slice(0, topic.length - 1)\n                if (!this.mqttHandlers) this.mqttHandlers = []\n                const h = new MQTTHandler(topic, handler)\n                this.mqttHandlers.push(h)\n                return h\n            } else {\n                return null\n            }\n        }\n\n        // Subscribe to topic\n        public subscribe(topic: string, handler?: (msg: IMessage) => void, qos: number = Constants.DefaultQos): void {\n            this.subscribeCore(topic, handler, qos)\n        }\n\n        // Subscribe to one update on the topic. Returns function that waits for the topic to be updated.\n        public awaitUpdate(topic: string, qos: number = Constants.DefaultQos): () => IMessage {\n            let res: IMessage = null\n            const evid = control.allocateNotifyEvent()\n            const h = this.subscribeCore(topic, msg => {\n                res = msg\n                control.raiseEvent(DAL.DEVICE_ID_NOTIFY, evid)\n            }, qos)\n            h.status = HandlerStatus.Once\n            return () => {\n                while (res == null) {\n                    control.waitForEvent(DAL.DEVICE_ID_NOTIFY, evid)\n                }\n                return res\n            }\n        }\n\n        private send(data: Buffer): void {\n            if (this.sct) {\n                this.trace(\"send: \" + data[0] + \" / \" + data.length + \" bytes\")\n                // this.log(\"send: \" + data[0] + \" / \" + data.length + \" bytes: \" + data.toHex())\n                this.sct.send(data);\n            }\n        }\n\n        private handleMessage(data: Buffer) {\n            if (this.buf)\n                data = this.buf.concat(data)\n            this.buf = data\n            if (data.length < 2)\n                return\n            let len = data[1]\n            let payloadOff = 2\n            if (len & 0x80) {\n                if (data.length < 3)\n                    return\n                if (data[2] & 0x80) {\n                    this.emit('error', `too large packet.`);\n                    this.buf = null\n                    return\n                }\n                len = (data[2] << 7) | (len & 0x7f)\n                payloadOff++\n            }\n\n            const payloadEnd = payloadOff + len\n            if (data.length < payloadEnd)\n                return // wait for the rest of data\n\n            this.buf = null\n\n            const cmd = data[0]\n            const controlPacketType: ControlPacketType = cmd >> 4;\n            // this.emit('debug', `Rcvd: ${controlPacketType}: '${data}'.`);\n\n            const payload = data.slice(payloadOff, payloadEnd - payloadOff)\n\n            switch (controlPacketType) {\n                case ControlPacketType.ConnAck:\n                    const returnCode: number = payload[1];\n                    if (returnCode === ConnectReturnCode.Accepted) {\n                        this.log('MQTT connection accepted.');\n                        this.emit('connected');\n                        this.status = Status.Connected;\n                        this.piId = setInterval(() => this.ping(), Constants.PingInterval * 1000);\n                        for (const sub of this.subs)\n                            this.send1(sub);\n                    } else {\n                        const connectionError: string = Client.describe(returnCode);\n                        this.log('MQTT connection error: ' + connectionError);\n                        this.emit('error', connectionError);\n                        this.disconnect()\n                    }\n                    break;\n                case ControlPacketType.Publish:\n                    const message: IMessage = Protocol.parsePublish(cmd, payload);\n                    this.trace(`incoming: ${message.topic}`)\n                    let handled = false\n                    let cleanup = false\n                    if (this.mqttHandlers) {\n                        for (let h of this.mqttHandlers)\n                            if (message.topic.slice(0, h.topic.length) == h.topic) {\n                                h.handler(message)\n                                handled = true\n                                if (h.status == HandlerStatus.Once) {\n                                    h.status = HandlerStatus.ToRemove\n                                    cleanup = true\n                                }\n                            }\n                        if (cleanup)\n                            this.mqttHandlers = this.mqttHandlers.filter(h => h.status != HandlerStatus.ToRemove)\n                    }\n                    if (!handled)\n                        this.emit('receive', message);\n                    if (message.qos > 0) {\n                        setTimeout(() => {\n                            this.send1(Protocol.createPubAck(message.pid || 0));\n                        }, 0);\n                    }\n                    break;\n                case ControlPacketType.PingResp:\n                case ControlPacketType.PubAck:\n                case ControlPacketType.SubAck:\n                    break;\n                default:\n                    this.emit('error', `MQTT unexpected packet type: ${controlPacketType}.`);\n            }\n\n            if (data.length > payloadEnd)\n                this.handleMessage(data.slice(payloadEnd))\n        }\n\n        private send1(msg: Buffer) {\n            if (this.canSend()) {\n                this.send(msg)\n                this.doneSending()\n            }\n        }\n\n        private ping() {\n            this.send1(Protocol.createPingReq());\n            this.emit('debug', 'Sent: Ping request.');\n        }\n    }\n}","pxt.json":"{\n    \"name\": \"mqtt\",\n    \"description\": \"MQTT for MakeCode - beta\",\n    \"dependencies\": {\n        \"core\": \"*\",\n        \"net\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"mqtt.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true,\n    \"tests\": [\n        \"test.ts\"\n    ]\n}\n"},"multiplayer":{"README.md":"# Multplayer\n\nAdditional blocks for multiplayer. For networked and same-screen alike.\n\n","fieldEditors.ts":"namespace mp {\n    /**\n     * A type of state to get for a player\n     */\n    //% shim=KIND_GET\n    //% blockId=mp_multiplayerstate\n    //% block=\"$kind\"\n    //% kindNamespace=MultiplayerState\n    //% kindMemberName=value\n    //% kindPromptHint=\"e.g. Cooldown, Speed, Attack...\"\n    //% blockHidden\n    //% help=multiplayer/multiplayer-state\n    export function _multiplayerState(kind: number): number {\n        return kind;\n    }\n}\n","images.ts":"namespace mp {\n    export function _indicatorForPlayer(player: number, direction: number) {\n        switch (direction) {\n            case CollisionDirection.Top:\n                switch (player) {\n                    case 1:\n                        return img`\n                            . . f f f f f f f f f f f f f . .\n                            . f 2 2 2 2 2 2 2 2 2 2 2 2 2 f .\n                            f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 f\n                            f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 f\n                            f 2 2 1 1 1 1 2 2 2 2 1 1 2 2 2 f\n                            f 2 2 1 1 2 1 1 2 2 1 1 1 2 2 2 f\n                            f 2 2 1 1 2 1 1 2 2 1 1 1 2 2 2 f\n                            f 2 2 1 1 1 1 2 2 2 2 1 1 2 2 2 f\n                            f 2 2 1 1 2 2 2 2 2 2 1 1 2 2 2 f\n                            f 2 2 1 1 2 2 2 2 2 1 1 1 1 2 2 f\n                            f 2 2 1 1 2 2 2 2 2 1 1 1 1 2 2 f\n                            f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 f\n                            . f 2 2 2 2 2 2 2 2 2 2 2 2 2 f .\n                            . . f f f f f 2 2 2 f f f f f . .\n                            . . . . . . . f 2 f . . . . . . .\n                            . . . . . . . . f . . . . . . . .\n                        `;\n                    case 2:\n                        return img`\n                            . . f f f f f f f f f f f f f . .\n                            . f 8 8 8 8 8 8 8 8 8 8 8 8 8 f .\n                            f 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 f\n                            f 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 f\n                            f 8 8 1 1 1 1 8 8 8 1 1 1 8 8 8 f\n                            f 8 8 1 1 8 1 1 8 1 1 8 1 1 8 8 f\n                            f 8 8 1 1 8 1 1 8 8 8 8 1 1 8 8 f\n                            f 8 8 1 1 1 1 8 8 8 1 1 1 8 8 8 f\n                            f 8 8 1 1 8 8 8 8 1 1 8 8 8 8 8 f\n                            f 8 8 1 1 8 8 8 8 1 1 1 1 1 8 8 f\n                            f 8 8 1 1 8 8 8 8 1 1 1 1 1 8 8 f\n                            f 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 f\n                            . f 8 8 8 8 8 8 8 8 8 8 8 8 8 f .\n                            . . f f f f f 8 8 8 f f f f f . .\n                            . . . . . . . f 8 f . . . . . . .\n                            . . . . . . . . f . . . . . . . .\n                        `;\n                    case 3:\n                        return img`\n                            . . f f f f f f f f f f f f f . .\n                            . f 4 4 4 4 4 4 4 4 4 4 4 4 4 f .\n                            f 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 f\n                            f 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 f\n                            f 4 4 1 1 1 1 4 4 4 1 1 1 4 4 4 f\n                            f 4 4 1 1 4 1 1 4 1 1 4 1 1 4 4 f\n                            f 4 4 1 1 4 1 1 4 4 4 4 1 1 4 4 f\n                            f 4 4 1 1 1 1 4 4 4 4 1 1 1 4 4 f\n                            f 4 4 1 1 4 4 4 4 4 4 4 1 1 4 4 f\n                            f 4 4 1 1 4 4 4 4 1 1 4 1 1 4 4 f\n                            f 4 4 1 1 4 4 4 4 4 1 1 1 4 4 4 f\n                            f 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 f\n                            . f 4 4 4 4 4 4 4 4 4 4 4 4 4 f .\n                            . . f f f f f 4 4 4 f f f f f . .\n                            . . . . . . . f 4 f . . . . . . .\n                            . . . . . . . . f . . . . . . . .\n                        `;\n                    case 4:\n                        return img`\n                            . . f f f f f f f f f f f f f . .\n                            . f 6 6 6 6 6 6 6 6 6 6 6 6 6 f .\n                            f 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 f\n                            f 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 f\n                            f 6 6 1 1 1 1 6 6 1 1 6 1 1 6 6 f\n                            f 6 6 1 1 6 1 1 6 1 1 6 1 1 6 6 f\n                            f 6 6 1 1 6 1 1 6 1 1 6 1 1 6 6 f\n                            f 6 6 1 1 1 1 6 6 1 1 1 1 1 6 6 f\n                            f 6 6 1 1 6 6 6 6 6 6 6 1 1 6 6 f\n                            f 6 6 1 1 6 6 6 6 6 6 6 1 1 6 6 f\n                            f 6 6 1 1 6 6 6 6 6 6 6 1 1 6 6 f\n                            f 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 f\n                            . f 6 6 6 6 6 6 6 6 6 6 6 6 6 f .\n                            . . f f f f f 6 6 6 f f f f f . .\n                            . . . . . . . f 6 f . . . . . . .\n                            . . . . . . . . f . . . . . . . .\n                        `;\n                }\n\n            case CollisionDirection.Bottom:\n                switch (player) {\n                    case 1:\n                        return img`\n                            . . . . . . . . f . . . . . . . .\n                            . . . . . . . f 2 f . . . . . . .\n                            . . f f f f f 2 2 2 f f f f f . .\n                            . f 2 2 2 2 2 2 2 2 2 2 2 2 2 f .\n                            f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 f\n                            f 2 2 1 1 1 1 2 2 2 2 1 1 2 2 2 f\n                            f 2 2 1 1 2 1 1 2 2 1 1 1 2 2 2 f\n                            f 2 2 1 1 2 1 1 2 2 1 1 1 2 2 2 f\n                            f 2 2 1 1 1 1 2 2 2 2 1 1 2 2 2 f\n                            f 2 2 1 1 2 2 2 2 2 2 1 1 2 2 2 f\n                            f 2 2 1 1 2 2 2 2 2 1 1 1 1 2 2 f\n                            f 2 2 1 1 2 2 2 2 2 1 1 1 1 2 2 f\n                            f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 f\n                            f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 f\n                            . f 2 2 2 2 2 2 2 2 2 2 2 2 2 f .\n                            . . f f f f f f f f f f f f f . .\n                        `;\n                    case 2:\n                        return img`\n                            . . . . . . . . f . . . . . . . .\n                            . . . . . . . f 8 f . . . . . . .\n                            . . f f f f f 8 8 8 f f f f f . .\n                            . f 8 8 8 8 8 8 8 8 8 8 8 8 8 f .\n                            f 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 f\n                            f 8 8 1 1 1 1 8 8 8 1 1 1 8 8 8 f\n                            f 8 8 1 1 8 1 1 8 1 1 8 1 1 8 8 f\n                            f 8 8 1 1 8 1 1 8 8 8 8 1 1 8 8 f\n                            f 8 8 1 1 1 1 8 8 8 1 1 1 8 8 8 f\n                            f 8 8 1 1 8 8 8 8 1 1 8 8 8 8 8 f\n                            f 8 8 1 1 8 8 8 8 1 1 1 1 1 8 8 f\n                            f 8 8 1 1 8 8 8 8 1 1 1 1 1 8 8 f\n                            f 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 f\n                            f 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 f\n                            . f 8 8 8 8 8 8 8 8 8 8 8 8 8 f .\n                            . . f f f f f f f f f f f f f . .\n                        `;\n                    case 3:\n                        return img`\n                            . . . . . . . . f . . . . . . . .\n                            . . . . . . . f 4 f . . . . . . .\n                            . . f f f f f 4 4 4 f f f f f . .\n                            . f 4 4 4 4 4 4 4 4 4 4 4 4 4 f .\n                            f 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 f\n                            f 4 4 1 1 1 1 4 4 4 1 1 1 4 4 4 f\n                            f 4 4 1 1 4 1 1 4 1 1 4 1 1 4 4 f\n                            f 4 4 1 1 4 1 1 4 4 4 4 1 1 4 4 f\n                            f 4 4 1 1 1 1 4 4 4 4 1 1 1 4 4 f\n                            f 4 4 1 1 4 4 4 4 4 4 4 1 1 4 4 f\n                            f 4 4 1 1 4 4 4 4 1 1 4 1 1 4 4 f\n                            f 4 4 1 1 4 4 4 4 4 1 1 1 4 4 4 f\n                            f 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 f\n                            f 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 f\n                            . f 4 4 4 4 4 4 4 4 4 4 4 4 4 f .\n                            . . f f f f f f f f f f f f f . .\n                        `;\n                    case 4:\n                        return img`\n                            . . . . . . . . f . . . . . . . .\n                            . . . . . . . f 6 f . . . . . . .\n                            . . f f f f f 6 6 6 f f f f f . .\n                            . f 6 6 6 6 6 6 6 6 6 6 6 6 6 f .\n                            f 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 f\n                            f 6 6 1 1 1 1 6 6 1 1 6 1 1 6 6 f\n                            f 6 6 1 1 6 1 1 6 1 1 6 1 1 6 6 f\n                            f 6 6 1 1 6 1 1 6 1 1 6 1 1 6 6 f\n                            f 6 6 1 1 1 1 6 6 1 1 1 1 1 6 6 f\n                            f 6 6 1 1 6 6 6 6 6 6 6 1 1 6 6 f\n                            f 6 6 1 1 6 6 6 6 6 6 6 1 1 6 6 f\n                            f 6 6 1 1 6 6 6 6 6 6 6 1 1 6 6 f\n                            f 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 f\n                            f 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 f\n                            . f 6 6 6 6 6 6 6 6 6 6 6 6 6 f .\n                            . . f f f f f f f f f f f f f . .\n                        `;\n                }\n\n            case CollisionDirection.Left:\n                switch (player) {\n                    case 1:\n                        return img`\n                            . . f f f f f f f f f f f f f . . . .\n                            . f 2 2 2 2 2 2 2 2 2 2 2 2 2 f . . .\n                            f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 f . .\n                            f 2 2 1 1 1 1 2 2 2 2 1 1 2 2 2 f . .\n                            f 2 2 1 1 2 1 1 2 2 1 1 1 2 2 2 f . .\n                            f 2 2 1 1 2 1 1 2 2 1 1 1 2 2 2 2 f .\n                            f 2 2 1 1 1 1 2 2 2 2 1 1 2 2 2 2 2 f\n                            f 2 2 1 1 2 2 2 2 2 2 1 1 2 2 2 2 f .\n                            f 2 2 1 1 2 2 2 2 2 1 1 1 1 2 2 f . .\n                            f 2 2 1 1 2 2 2 2 2 1 1 1 1 2 2 f . .\n                            f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 f . .\n                            . f 2 2 2 2 2 2 2 2 2 2 2 2 2 f . . .\n                            . . f f f f f f f f f f f f f . . . .\n                        `;\n                    case 2:\n                        return img`\n                            . . f f f f f f f f f f f f f . . . .\n                            . f 8 8 8 8 8 8 8 8 8 8 8 8 8 f . . .\n                            f 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 f . .\n                            f 8 8 1 1 1 1 8 8 8 1 1 1 8 8 8 f . .\n                            f 8 8 1 1 8 1 1 8 1 1 8 1 1 8 8 f . .\n                            f 8 8 1 1 8 1 1 8 8 8 8 1 1 8 8 8 f .\n                            f 8 8 1 1 1 1 8 8 8 1 1 1 8 8 8 8 8 f\n                            f 8 8 1 1 8 8 8 8 1 1 8 8 8 8 8 8 f .\n                            f 8 8 1 1 8 8 8 8 1 1 1 1 1 8 8 f . .\n                            f 8 8 1 1 8 8 8 8 1 1 1 1 1 8 8 f . .\n                            f 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 f . .\n                            . f 8 8 8 8 8 8 8 8 8 8 8 8 8 f . . .\n                            . . f f f f f f f f f f f f f . . . .\n                        `;\n                    case 3:\n                        return img`\n                            . . f f f f f f f f f f f f f . . . .\n                            . f 4 4 4 4 4 4 4 4 4 4 4 4 4 f . . .\n                            f 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 f . .\n                            f 4 4 1 1 1 1 4 4 4 1 1 1 4 4 4 f . .\n                            f 4 4 1 1 4 1 1 4 1 1 4 1 1 4 4 f . .\n                            f 4 4 1 1 4 1 1 4 4 4 4 1 1 4 4 4 f .\n                            f 4 4 1 1 1 1 4 4 4 4 1 1 1 4 4 4 4 f\n                            f 4 4 1 1 4 4 4 4 4 4 4 1 1 4 4 4 f .\n                            f 4 4 1 1 4 4 4 4 1 1 4 1 1 4 4 f . .\n                            f 4 4 1 1 4 4 4 4 4 1 1 1 4 4 4 f . .\n                            f 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 f . .\n                            . f 4 4 4 4 4 4 4 4 4 4 4 4 4 f . . .\n                            . . f f f f f f f f f f f f f . . . .\n                        `;\n                    case 4:\n                        return img`\n                            . . f f f f f f f f f f f f f . . . .\n                            . f 6 6 6 6 6 6 6 6 6 6 6 6 6 f . . .\n                            f 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 f . .\n                            f 6 6 1 1 1 1 6 6 1 1 6 1 1 6 6 f . .\n                            f 6 6 1 1 6 1 1 6 1 1 6 1 1 6 6 f . .\n                            f 6 6 1 1 6 1 1 6 1 1 6 1 1 6 6 6 f .\n                            f 6 6 1 1 1 1 6 6 1 1 1 1 1 6 6 6 6 f\n                            f 6 6 1 1 6 6 6 6 6 6 6 1 1 6 6 6 f .\n                            f 6 6 1 1 6 6 6 6 6 6 6 1 1 6 6 f . .\n                            f 6 6 1 1 6 6 6 6 6 6 6 1 1 6 6 f . .\n                            f 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 f . .\n                            . f 6 6 6 6 6 6 6 6 6 6 6 6 6 f . . .\n                            . . f f f f f f f f f f f f f . . . .\n                        `;\n                }\n\n            case CollisionDirection.Right:\n                switch (player) {\n                    case 1:\n                        return img`\n                            . . . . f f f f f f f f f f f f f . .\n                            . . . f 2 2 2 2 2 2 2 2 2 2 2 2 2 f .\n                            . . f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 f\n                            . . f 2 2 1 1 1 1 2 2 2 2 1 1 2 2 2 f\n                            . . f 2 2 1 1 2 1 1 2 2 1 1 1 2 2 2 f\n                            . f 2 2 2 1 1 2 1 1 2 2 1 1 1 2 2 2 f\n                            f 2 2 2 2 1 1 1 1 2 2 2 2 1 1 2 2 2 f\n                            . f 2 2 2 1 1 2 2 2 2 2 2 1 1 2 2 2 f\n                            . . f 2 2 1 1 2 2 2 2 2 1 1 1 1 2 2 f\n                            . . f 2 2 1 1 2 2 2 2 2 1 1 1 1 2 2 f\n                            . . f 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 f\n                            . . . f 2 2 2 2 2 2 2 2 2 2 2 2 2 f .\n                            . . . . f f f f f f f f f f f f f . .\n                        `;\n                    case 2:\n                        return img`\n                            . . . . f f f f f f f f f f f f f . .\n                            . . . f 8 8 8 8 8 8 8 8 8 8 8 8 8 f .\n                            . . f 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 f\n                            . . f 8 8 1 1 1 1 8 8 8 1 1 1 8 8 8 f\n                            . . f 8 8 1 1 8 1 1 8 1 1 8 1 1 8 8 f\n                            . f 8 8 8 1 1 8 1 1 8 8 8 8 1 1 8 8 f\n                            f 8 8 8 8 1 1 1 1 8 8 8 1 1 1 8 8 8 f\n                            . f 8 8 8 1 1 8 8 8 8 1 1 8 8 8 8 8 f\n                            . . f 8 8 1 1 8 8 8 8 1 1 1 1 1 8 8 f\n                            . . f 8 8 1 1 8 8 8 8 1 1 1 1 1 8 8 f\n                            . . f 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 f\n                            . . . f 8 8 8 8 8 8 8 8 8 8 8 8 8 f .\n                            . . . . f f f f f f f f f f f f f . .\n                        `;\n                    case 3:\n                        return img`\n                            . . . . f f f f f f f f f f f f f . .\n                            . . . f 4 4 4 4 4 4 4 4 4 4 4 4 4 f .\n                            . . f 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 f\n                            . . f 4 4 1 1 1 1 4 4 4 1 1 1 4 4 4 f\n                            . . f 4 4 1 1 4 1 1 4 1 1 4 1 1 4 4 f\n                            . f 4 4 4 1 1 4 1 1 4 4 4 4 1 1 4 4 f\n                            f 4 4 4 4 1 1 1 1 4 4 4 4 1 1 1 4 4 f\n                            . f 4 4 4 1 1 4 4 4 4 4 4 4 1 1 4 4 f\n                            . . f 4 4 1 1 4 4 4 4 1 1 4 1 1 4 4 f\n                            . . f 4 4 1 1 4 4 4 4 4 1 1 1 4 4 4 f\n                            . . f 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 f\n                            . . . f 4 4 4 4 4 4 4 4 4 4 4 4 4 f .\n                            . . . . f f f f f f f f f f f f f . .\n                        `;\n                    case 4:\n                        return img`\n                            . . . . f f f f f f f f f f f f f . .\n                            . . . f 6 6 6 6 6 6 6 6 6 6 6 6 6 f .\n                            . . f 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 f\n                            . . f 6 6 1 1 1 1 6 6 1 1 6 1 1 6 6 f\n                            . . f 6 6 1 1 6 1 1 6 1 1 6 1 1 6 6 f\n                            . f 6 6 6 1 1 6 1 1 6 1 1 6 1 1 6 6 f\n                            f 6 6 6 6 1 1 1 1 6 6 1 1 1 1 1 6 6 f\n                            . f 6 6 6 1 1 6 6 6 6 6 6 6 1 1 6 6 f\n                            . . f 6 6 1 1 6 6 6 6 6 6 6 1 1 6 6 f\n                            . . f 6 6 1 1 6 6 6 6 6 6 6 1 1 6 6 f\n                            . . f 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 f\n                            . . . f 6 6 6 6 6 6 6 6 6 6 6 6 6 f .\n                            . . . . f f f f f f f f f f f f f . .\n                        `;\n                }\n        }\n\n        return undefined;\n    }\n}\n","ns.ts":"//% color=\"#207a77\" weight=96 icon=\"\\uf0c0\"\n//% blockGap=8\n//% block=\"Multiplayer\"\n//% groups='[\"Player\", \"Controller\", \"Info\", \"Game\", \"Utility\"]'\nnamespace mp {\n}\n","player.ts":"namespace mp {\n    const MAX_PLAYERS = 4;\n\n    export enum PlayerNumber {\n        //% block=\"1\"\n        One = 1,\n        //% block=\"2\"\n        Two = 2,\n        //% block=\"3\"\n        Three = 3,\n        //% block=\"4\"\n        Four = 4\n    }\n\n    export enum PlayerProperty {\n        //% block=\"index\"\n        Index = 1,\n        //% block=\"number\"\n        Number = 2\n    }\n\n    export enum MultiplayerButton {\n        //% block=\"A\"\n        A,\n        //% block=\"B\"\n        B,\n        //% block=\"up\"\n        Up,\n        //% block=\"right\"\n        Right,\n        //% block=\"down\"\n        Down,\n        //% block=\"left\"\n        Left\n    }\n\n    class ButtonHandler {\n        constructor(public button: MultiplayerButton, public event: ControllerButtonEvent, public handler: (player: Player) => void) {\n        }\n    }\n\n    class ControllerEventHandler {\n        constructor(public event: ControllerEvent, public handler: (player: Player) => void) {\n        }\n    }\n\n    class ScoreHandler {\n        constructor(public target: number, public handler: (player: Player) => void) {\n        }\n    }\n\n    class StateEntry {\n        constructor(public key: number, public value: number) {\n        }\n    }\n\n    /**\n     * A player in the game\n     */\n    export class Player {\n        _sprite: Sprite;\n        _state: StateEntry[];\n        _index: number;\n        _data: any;\n        _mwb: boolean;\n        _vx: number;\n        _vy: number;\n\n        constructor(index: number) {\n            this._index = index;\n        }\n\n        get index(): number {\n            return this._index;\n        }\n\n        get number(): number {\n            return this._index + 1;\n        }\n\n        get data(): any {\n            if (!this._data) this._data = {};\n            return this._data;\n        }\n\n        set data(value: any) {\n            this._data = value;\n        }\n\n        getProperty(prop: PlayerProperty): number {\n            switch (prop) {\n                case PlayerProperty.Index: return this.index;\n                case PlayerProperty.Number: return this.number;\n                default: return 0;\n            }\n        }\n\n        getSprite(): Sprite {\n            return this._sprite;\n        }\n\n        setSprite(sprite: Sprite) {\n            if (sprite && sprite.image) {\n                // Passing 'implicit' flag so we don't override icons that\n                // user has explicitly defined.\n                mp.postPresenceIcon(\n                    this.number,\n                    sprite.image,\n                    /** implicit **/ true\n                );\n            } else {\n                // Passing 'implicit' flag so we don't override icons that\n                // user has explicitly defined.\n                mp.postPresenceIcon(\n                    this.number,\n                    undefined,\n                    /** implicit **/ true\n                );\n\n            }\n\n            if (this._sprite && this._mwb) {\n                this._getController().stopControllingSprite(this._sprite);\n            }\n\n            this._sprite = sprite;\n\n            if (this._sprite && this._mwb) {\n                this._getController().moveSprite(this._sprite, this._vx, this._vy);\n            }\n        }\n\n        moveWithButtons(vx?: number, vy?: number) {\n            this._mwb = true;\n            this._vx = vx;\n            this._vy = vy;\n            this._getController().moveSprite(this.getSprite(), vx, vy);\n        }\n\n        getState(key: number): number {\n            if (key === MultiplayerState.score) {\n                return this._getInfo().score();\n            }\n            if (key === MultiplayerState.life) {\n                return this._getInfo().life();\n            }\n            return this._getState(key);\n        }\n\n        setState(key: number, val: number) {\n            if (key === MultiplayerState.score) {\n                this._getInfo().setScore(val);\n            }\n            if (key === MultiplayerState.life) {\n                this._getInfo().setLife(val);\n            }\n            this._setState(key, val);\n        }\n\n        _setState(key: number, val: number) {\n            this._lookupOrCreateState(key).value = val;\n        }\n\n        _getState(key: number): number {\n            return this._lookupOrCreateState(key).value;\n        }\n\n        _getInfo(): info.PlayerInfo {\n            switch (this._index) {\n                case 0: return info.player1;\n                case 1: return info.player2;\n                case 2: return info.player3;\n                case 3: return info.player4;\n                default: return undefined;\n            }\n        }\n\n        _getController(): controller.Controller {\n            switch (this._index) {\n                case 0: return controller.player1 as any;\n                case 1: return controller.player2;\n                case 2: return controller.player3;\n                case 3: return controller.player4;\n            }\n            return undefined;\n        }\n\n        _lookupOrCreateState(key: number) {\n            if (!this._state) this._state = [];\n            for (const entry of this._state) {\n                if (entry.key === key) return entry;\n            }\n\n            const newEntry = new StateEntry(key, 0);\n            this._state.push(newEntry);\n            return newEntry;\n        }\n    }\n\n    class MPState {\n        players: Player[];\n        buttonHandlers: ButtonHandler[];\n        controllerEventHandlers: ControllerEventHandler[];\n        scoreHandlers: ScoreHandler[];\n        lifeZeroHandler: (player: Player) => void;\n        indicatorsVisible: boolean;\n        indicatorRenderable: scene.Renderable;\n\n        constructor() {\n            this.players = [];\n            for (let i = 0; i < MAX_PLAYERS; ++i)\n                this.players.push(new Player(i));\n            this.buttonHandlers = [];\n            this.controllerEventHandlers = [];\n            this.scoreHandlers = [];\n            this.indicatorsVisible = false;\n        }\n\n        onButtonEvent(button: MultiplayerButton, event: ControllerButtonEvent, handler: (player: Player) => void) {\n            const existing = this.getButtonHandler(button, event);\n\n            if (existing) {\n                existing.handler = handler;\n                return;\n            }\n\n            this.buttonHandlers.push(new ButtonHandler(button, event, handler));\n\n            for (const player of this.players) {\n                getButton(player._getController(), button).onEvent(event, () => {\n                    this.getButtonHandler(button, event).handler(player);\n                })\n            }\n        }\n\n        onControllerEvent(event: ControllerEvent, handler: (player: Player) => void) {\n            const existing = this.getControllerEventHandler(event);\n\n            if (existing) {\n                existing.handler = handler;\n                return;\n            }\n\n            this.controllerEventHandlers.push(new ControllerEventHandler(event, handler));\n\n            for (const player of this.players) {\n                player._getController().onEvent(event, () => {\n                    this.getControllerEventHandler(event).handler(player);\n                })\n            }\n        }\n\n        onReachedScore(score: number, handler: (player: Player) => void) {\n            const existing = this.getScoreHandler(score);\n\n            // Overwrite the existing handler for this score. Last one wins.\n            if (existing) {\n                existing.handler = handler;\n                return;\n            }\n\n            this.scoreHandlers.push(new ScoreHandler(score, handler));\n\n            for (const player of this.players) {\n                player._getInfo().onScore(score, () => {\n                    this.getScoreHandler(score).handler(player);\n                })\n            }\n        }\n\n        onLifeZero(handler: (player: Player) => void) {\n            if (!this.lifeZeroHandler) {\n                for (const player of this.players) {\n                    player._getInfo().onLifeZero(() => {\n                        this.lifeZeroHandler(player);\n                    })\n                }\n            }\n            this.lifeZeroHandler = handler;\n        }\n\n        setPlayerIndicatorsVisible(visible: boolean) {\n            this.indicatorsVisible = visible;\n\n            if (visible && !this.indicatorRenderable) {\n                this.indicatorRenderable = scene.createRenderable(99, (target, camera) => {\n                    if (this.indicatorsVisible) this.drawIndicators(target, camera);\n                })\n            }\n        }\n\n        getButtonHandler(button: MultiplayerButton, event: ControllerButtonEvent) {\n            for (const handler of this.buttonHandlers) {\n                if (handler.button === button && handler.event === event) return handler;\n            }\n            return undefined;\n        }\n\n        getControllerEventHandler(event: ControllerEvent) {\n            for (const handler of this.controllerEventHandlers) {\n                if (handler.event === event) return handler;\n            }\n            return undefined;\n        }\n\n\n        getScoreHandler(score: number) {\n            for (const handler of this.scoreHandlers) {\n                if (handler.target === score) return handler;\n            }\n            return undefined;\n        }\n\n        drawIndicators(target: Image, camera: scene.Camera) {\n            for (const player of this.players) {\n                const sprite = player.getSprite();\n\n                if (!sprite || sprite.flags & (sprites.Flag.Destroyed | sprites.Flag.Invisible)) {\n                    continue;\n                }\n\n                let top = Fx.toInt(sprite._hitbox.top)\n                let bottom = Fx.toInt(sprite._hitbox.bottom)\n                let left = Fx.toInt(sprite._hitbox.left)\n                let right = Fx.toInt(sprite._hitbox.right)\n\n                if (!(sprite.flags & sprites.Flag.RelativeToCamera)) {\n                    top -= camera.drawOffsetY;\n                    bottom -= camera.drawOffsetY;\n                    left -= camera.drawOffsetX;\n                    right -= camera.drawOffsetX;\n                }\n\n                if (left < 0) {\n                    const indicator = _indicatorForPlayer(player.number, CollisionDirection.Right);\n                    target.drawTransparentImage(\n                        indicator,\n                        Math.max(right + 2, 0),\n                        Math.min(\n                            Math.max(\n                                (top + ((bottom - top) >> 1) - (indicator.height >> 1)),\n                                0\n                            ),\n                            screen.height - indicator.height\n                        )\n                    )\n                }\n                else if (right > 160) {\n                    const indicator = _indicatorForPlayer(player.number, CollisionDirection.Left);\n                    target.drawTransparentImage(\n                        indicator,\n                        Math.min(left - indicator.width - 2, screen.width - indicator.width),\n                        Math.min(\n                            Math.max(\n                                (top + ((bottom - top) >> 1) - (indicator.height >> 1)),\n                                0\n                            ),\n                            screen.height - indicator.height\n                        )\n                    )\n                }\n                else if (top < 18) {\n                    const indicator = _indicatorForPlayer(player.number, CollisionDirection.Bottom);\n                    target.drawTransparentImage(\n                        indicator,\n                        (left + ((right - left) >> 1) - (indicator.width >> 1)),\n                        Math.max(bottom + 2, 0)\n                    )\n                }\n                else {\n                    const indicator = _indicatorForPlayer(player.number, CollisionDirection.Top);\n                    target.drawTransparentImage(\n                        indicator,\n                        (left + ((right - left) >> 1) - (indicator.width >> 1)),\n                        Math.min(top - indicator.height - 2, screen.height - indicator.height)\n                    )\n                }\n            }\n        }\n    }\n\n    let stateStack: MPState[];\n\n    function init() {\n        if (stateStack) return;\n        stateStack = [new MPState()];\n        game.addScenePushHandler(() => {\n            stateStack.push(new MPState());\n        });\n        game.addScenePopHandler(() => {\n            stateStack.pop();\n            if (stateStack.length === 0) stateStack.push(new MPState());\n        });\n    }\n\n    export function _mpstate() {\n        init();\n        return stateStack[stateStack.length - 1];\n    }\n\n    function getButton(ctrl: controller.Controller, button: MultiplayerButton) {\n        switch (button) {\n            case MultiplayerButton.A: return ctrl.A;\n            case MultiplayerButton.B: return ctrl.B;\n            case MultiplayerButton.Up: return ctrl.up;\n            case MultiplayerButton.Right: return ctrl.right;\n            case MultiplayerButton.Down: return ctrl.down;\n            case MultiplayerButton.Left: return ctrl.left;\n        }\n    }\n\n    /**\n     * Gets the sprite of the player\n     * @param player The player to get the sprite of\n     * @returns The sprite of the player, or undefined if the player has no assigned sprite\n     */\n    //% blockId=mp_getPlayerSprite\n    //% block=\"$player sprite\"\n    //% player.shadow=mp_playerSelector\n    //% group=Player\n    //% weight=80\n    //% blockGap=8\n    //% help=multiplayer/get-player-sprite\n    //% parts=\"multiplayer\"\n    export function getPlayerSprite(player: Player): Sprite {\n        if (!player) return undefined;\n        return player.getSprite();\n    }\n\n    /**\n     * Sets the sprite of the player\n     * @param player The player to set the sprite for\n     * @param sprite The sprite to set\n     */\n    //% blockId=mp_setPlayerSprite\n    //% block=\"set $player sprite to $sprite\"\n    //% player.shadow=mp_playerSelector\n    //% sprite.shadow=spritescreatenoset\n    //% group=Player\n    //% weight=120\n    //% blockGap=8\n    //% help=multiplayer/set-player-sprite\n    //% parts=\"multiplayer\"\n    export function setPlayerSprite(player: Player, sprite: Sprite) {\n        if (!player) return;\n        player.setSprite(sprite);\n    }\n\n    /**\n     * Selects one of the players by number\n     * @param number The player number\n     * @returns The player\n     */\n    //% blockId=mp_playerSelector\n    //% block=\"player $number\"\n    //% group=Player\n    //% weight=100\n    //% blockGap=8\n    //% help=multiplayer/player-selector\n    //% parts=\"multiplayer\"\n    export function playerSelector(number: PlayerNumber): Player {\n        const index = number - 1;\n        return getPlayerByIndex(index);\n    }\n\n    /**\n     * Returns an array of all players\n     */\n    //% blockId=mp_allPlayers\n    //% block=\"array of all players\"\n    //% group=Player\n    //% weight=90\n    //% blockGap=8\n    //% help=multiplayer/get-all-players\n    //% parts=\"multiplayer\"\n    export function allPlayers(): Player[] {\n        return _mpstate().players.slice();\n    }\n\n    /**\n     * Gets the player the sprite is assigned to\n     * @param sprite the sprite\n     * @returns Player, or undefined if not found\n     */\n    //% blockId=mp_getPlayerBySprite\n    //% block=\"$sprite player\"\n    //% sprite.shadow=variables_get\n    //% sprite.defl=mySprite\n    //% group=Player\n    //% weight=70\n    //% blockGap=8\n    //% help=multiplayer/get-player-by-sprite\n    //% parts=\"multiplayer\"\n    export function getPlayerBySprite(sprite: Sprite): Player {\n        for (const player of _mpstate().players) {\n            if (player.getSprite() === sprite) return player;\n        }\n        return undefined;\n    }\n\n    /**\n     * Control a player's sprite with directional buttons\n     * @param player The player to control\n     * @param vx The horizontal velocity of the sprite (optional)\n     * @param vy The vertical velocity of the sprite (optional)\n     */\n    //% blockId=mp_moveWithButtons\n    //% block=\"move $player with buttons||vx $vx vy $vy\"\n    //% player.shadow=mp_playerSelector\n    //% vx.defl=100\n    //% vy.defl=100\n    //% vx.shadow=\"spriteSpeedPicker\"\n    //% vy.shadow=\"spriteSpeedPicker\"\n    //% expandableArgumentMode=\"toggle\"\n    //% inlineInputMode=inline\n    //% group=Controller\n    //% weight=100\n    //% blockGap=8\n    //% help=multiplayer/move-with-buttons\n    //% parts=\"multiplayer\"\n    export function moveWithButtons(player: Player, vx?: number, vy?: number) {\n        if (!player) return;\n        player.moveWithButtons(vx, vy);\n    }\n\n    /**\n     * Runs code when a button on any controller is pressed, released, or held\n     * @param button The button to listen for\n     * @param event The event to listen for (pressed, released, or held)\n     * @param handler The code to run when the button is pressed, released, or held\n     */\n    //% blockId=mp_onButtonEvent\n    //% block=\"on $button button $event for $player\"\n    //% draggableParameters=reporter\n    //% group=Controller\n    //% weight=90\n    //% blockGap=8\n    //% help=multiplayer/on-button-event\n    //% parts=\"multiplayer\"\n    export function onButtonEvent(button: MultiplayerButton, event: ControllerButtonEvent, handler: (player: Player) => void) {\n        _mpstate().onButtonEvent(button, event, handler);\n    }\n\n    /**\n     * Queries the state of a button on a controller\n     * @param player The player to query\n     * @param button The button to query\n     * @returns true if the button is pressed\n     */\n    //% blockId=mp_isButtonPressed\n    //% block=\"is $player $button button pressed\"\n    //% player.shadow=mp_playerSelector\n    //% group=Controller\n    //% weight=80\n    //% blockGap=8\n    //% help=multiplayer/is-button-pressed\n    //% parts=\"multiplayer\"\n    export function isButtonPressed(player: Player, button: MultiplayerButton): boolean {\n        if (!player) return false;\n        return getButton(player._getController(), button).isPressed();\n    }\n\n    /**\n     * Runs code when a controller is connected or disconnected\n     * @param event The event to listen for (controller connected or disconnected)\n     * @param handler Code to run when the event is raised\n     */\n    //% blockId=mp_onControllerEvent\n    //% block=\"on $player $event\"\n    //% draggableParameters=reporter\n    //% group=Controller\n    //% weight=70\n    //% blockGap=8\n    //% help=multiplayer/on-controller-event\n    //% parts=\"multiplayer\"\n    export function onControllerEvent(event: ControllerEvent, handler: (player: Player) => void) {\n        _mpstate().onControllerEvent(event, handler);\n    }\n\n    /**\n     * Queries the connected state of the player\n     * @param player The player to query\n     * @returns true if the player is connected\n     */\n    //% blockId=mp_isConnected\n    //% block=\"$player connected\"\n    //% player.shadow=mp_playerSelector\n    //% group=Controller\n    //% weight=60\n    //% blockGap=8\n    //% help=multiplayer/is-connected\n    //% parts=\"multiplayer\"\n    export function isConnected(player: Player): boolean {\n        if (!player) return false;\n        return player._getController().connected;\n    }\n\n    /**\n     * Gets the value of the specified player state\n     * @param player The player to get the state for\n     * @param state The state to get\n     * @returns The value of the state\n     */\n    //% blockId=mp_getPlayerState\n    //% block=\"$player $state\"\n    //% player.shadow=mp_playerSelector\n    //% state.shadow=mp_multiplayerstate\n    //% group=Info\n    //% weight=100\n    //% blockGap=8\n    //% help=multiplayer/get-player-state\n    //% parts=\"multiplayer\"\n    export function getPlayerState(player: Player, state: number): number {\n        if (!player) return 0;\n        return player.getState(state);\n    }\n\n    /**\n     * Sets the value of the specified player state\n     * @param player The player to set the state for\n     * @param state The state to set\n     * @param value The value to set the state to\n     */\n    //% blockId=mp_setPlayerState\n    //% block=\"set $player $state to $value\"\n    //% player.shadow=mp_playerSelector\n    //% state.shadow=mp_multiplayerstate\n    //% group=Info\n    //% weight=90\n    //% blockGap=8\n    //% help=multiplayer/set-player-state\n    //% parts=\"multiplayer\"\n    export function setPlayerState(player: Player, state: number, value: number) {\n        if (!player) return;\n        player.setState(state, value);\n    }\n\n    /**\n     * Changes the value of the specified player state\n     * @param player The player to change the state for\n     * @param state The state to change\n     * @param delta The amount to change the state by\n     */\n    //% blockId=mp_changePlayerStateBy\n    //% block=\"change $player $state by $delta\"\n    //% player.shadow=mp_playerSelector\n    //% state.shadow=mp_multiplayerstate\n    //% delta.defl=1\n    //% group=Info\n    //% weight=80\n    //% blockGap=8\n    //% help=multiplayer/change-player-state-by\n    //% parts=\"multiplayer\"\n    export function changePlayerStateBy(player: Player, state: number, delta: number) {\n        if (!player) return;\n        player.setState(state, player.getState(state) + delta);\n    }\n\n    /**\n     * Gets a property of the player\n     * @param player The player to get the property of\n     * @param prop The property to get\n     * @returns The value of the property\n     */\n    //% blockId=mp_getPlayerProperty\n    //% block=\"$player $prop\"\n    //% player.shadow=mp_playerSelector\n    //% group=Info\n    //% weight=100\n    //% blockGap=8\n    //% help=multiplayer/get-player-property\n    //% parts=\"multiplayer\"\n    export function getPlayerProperty(player: Player, prop: PlayerProperty): number {\n        if (!player) return 0;\n        return player.getProperty(prop);\n    }\n\n    /**\n     * Runs code once each time a player's score reaches a given value.\n     * @param score The score to check for, eg: 100\n     * @param handler The code to run when the score is reached\n     */\n    //% blockId=mp_onScore\n    //% block=\"on score $score for $player\"\n    //% score.defl=100\n    //% draggableParameters=reporter\n    //% group=Info\n    //% weight=70\n    //% blockGap=8\n    //% help=multiplayer/on-score\n    //% parts=\"multiplayer\"\n    export function onScore(score: number, handler: (player: Player) => void) {\n        _mpstate().onReachedScore(score, handler);\n    }\n\n    /**\n     * Runs code when a player's number of lives reaches zero\n     * @param handler The code to run when the lives reach zero\n     */\n    //% blockId=mp_onLifeZero\n    //% block=\"on life zero for $player\"\n    //% draggableParameters=reporter\n    //% group=Info\n    //% weight=60\n    //% blockGap=8\n    //% help=multiplayer/on-life-zero\n    //% parts=\"multiplayer\"\n    export function onLifeZero(handler: (player: Player) => void) {\n        _mpstate().onLifeZero(handler);\n    }\n\n    //% blockId=mp_gameOverPlayerWin\n    //% block=\"game over $player wins\"\n    //% player.shadow=mp_playerSelector\n    //% group=Game\n    //% weight=100\n    //% blockGap=8\n    //% help=multiplayer/game-over-player-win\n    //% parts=\"multiplayer\"\n    export function gameOverPlayerWin(player: Player) {\n        if (!player) return;\n        game.gameOverPlayerWin(player.number);\n    }\n\n    /**\n     * Gets the player by number\n     * @param number The one-based number of the player\n     * @returns Player, or undefined if not found\n     */\n    //% blockId=mp_getPlayerByNumber\n    //% block=\"player $number\"\n    //% number.shadow=variables_get\n    //% number.defl=number\n    //% group=Utility\n    //% weight=80\n    //% blockGap=8\n    //% help=multiplayer/get-player-by-number\n    //% parts=\"multiplayer\"\n    export function getPlayerByNumber(number: number): Player {\n        const index = number - 1;\n        return getPlayerByIndex(index);\n    }\n\n    /**\n     * Gets the player by index\n     * @param index The zero-based index of the player\n     * @returns Player, or undefined if not found\n     */\n    //% blockId=mp_getPlayerByIndex\n    //% block=\"player at $index\"\n    //% index.shadow=variables_get\n    //% index.defl=index\n    //% group=Utility\n    //% weight=80\n    //% blockGap=8\n    //% help=multiplayer/get-player-by-index\n    //% parts=\"multiplayer\"\n    export function getPlayerByIndex(index: number): Player {\n        if (index < 0 || index >= MAX_PLAYERS) return undefined;\n        return _mpstate().players[index];\n    }\n\n    /**\n     * Turns player indicators on or off\n     * @param visible indicator visibility\n     */\n    //% blockId=mp_setPlayerIndicatorsVisible\n    //% block=\"set player indicators $visible\"\n    //% visible.shadow=toggleOnOff\n    //% visible.defl=true\n    //% group=Utility\n    //% weight=100\n    //% blockGap=8\n    //% help=multiplayer/set-player-indicators-visible\n    //% parts=\"multiplayer\"\n    export function setPlayerIndicatorsVisible(visible: boolean) {\n        _mpstate().setPlayerIndicatorsVisible(visible);\n    }\n}\n","pxt.json":"{\n    \"name\": \"multiplayer\",\n    \"description\": \"Additional blocks for building multiplayer games\",\n    \"dependencies\": {\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"ns.ts\",\n        \"fieldEditors.ts\",\n        \"images.ts\",\n        \"player.ts\",\n        \"stateKind.ts\",\n        \"targetoverrides.ts\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"weight\": 80,\n    \"icon\": \"/static/libs/multiplayer.png\"\n}\n","stateKind.ts":"namespace MultiplayerState {\n    let nextKind: number;\n\n    export function create() {\n        if (nextKind === undefined) nextKind = 0;\n        return nextKind++;\n    }\n\n    //% isKind\n    export const score = create();\n\n    //% isKind\n    export const life = create();\n}\n","targetoverrides.ts":"// TODO any platform specific overrides","test.ts":""},"net":{"README.md":"# Net\n\nNetworking abstractions and drivers\n\n## WiFi module configuration\n\n* ``PIN_WIFI_CS``, ESP32 CS pin mapping\n* ``PIN_WIFI_BUSY``, ESP32 CS pin mapping\n* ``PIN_WIFI_RESET``, ESP32 RESET pin mapping\n* ``PIN_WIFI_GPIO0`` (optional), ESP32 GPIO0 pin mapping\n\nThe driver uses the default SPI pins. You can override this behavior by specifying these 3 keys.\n\n* ``PIN_WIFI_MOSI`` (optional), dedicated SPI MOSI pin\n* ``PIN_WIFI_MISO`` (optional), dedicated SPI MISO pin\n* ``PIN_WIFI_SCK`` (optional), dedicated SPI SCK pin\n\n## Access Points and passwords\n\nThe module uses access points and password information stored in the device secrets. These secrets can be set programmatically using ``net.updateAccessPoint`` or via the menu items in Arcade (added via the ``net-game`` extension).\n\n> *Friendly reminder:* Do not share .uf2 files or programs with secrets!!\n\n## Example\n\n```\n//\n// to configure your access point password,\n// open the menu and go to the WiFi option (loaded from net-game lib)\n//\ngame.consoleOverlay.setVisible(true)\nnet.logPriority = ConsolePriority.Log;\n\nconsole.log(`connecting...`)\nconst wifi = net.instance();\n// list aps\nconst aps = wifi.scanNetworks();\nconst pwds = net.knownAccessPoints();\nconsole.log(`APs (${aps.length})`)\nfor (const ap of aps) {\n    console.log(` ${ap.ssid} ${pwds[ap.ssid] !== undefined ? \"(known)\" : \"\"}`)\n}\n\n// ping\nfor (let i = 0; i < 4; ++i)\n    console.log(`ping: ${net.ping(\"bing.com\")}ms`)\n\n// curl\nconst r = net.get(\"https://makecode.com/api/md/arcade/about\")\nconsole.log(r.text)\n```","controller.ts":"namespace net {\n    export enum ControllerEvent {\n        NewScan = 1,\n        GotIP = 2,\n        LostIP = 3,\n        NoScannedNetworks = 4,\n        NoKnownNetworks = 5,\n        Connecting = 6,\n        ConnectionFailed = 7,\n        LoginServerStarted = 8\n    }\n    export class Controller {\n        eventID: number\n        private _isConnected = false\n\n        onConnectSSIDFailed: (ssid: string) => void;\n\n        constructor() {\n            this.eventID = control.allocateEventSource()\n        }\n\n        protected setConnected(isConnected: boolean) {\n            if (this._isConnected != isConnected) {\n                this._isConnected = isConnected\n                this.emitEvent(isConnected ? ControllerEvent.GotIP : ControllerEvent.LostIP)\n            }\n        }\n\n        protected emitEvent(ev: ControllerEvent) {\n            control.raiseEvent(this.eventID, ev)\n        }\n\n        onEvent(ev: ControllerEvent, h: () => void) {\n            control.onEvent(this.eventID, ev, h)\n        }\n\n        public scanNetworks(): net.AccessPoint[] {\n            this.lastScanResults = this.scanNetworksCore()\n            this.emitEvent(ControllerEvent.NewScan)\n            return this.lastScanResults\n        }\n\n        protected scanNetworksCore(): net.AccessPoint[] {\n            return [];\n        }\n\n        public startLoginServer(hostName: string): void {\n            \n        }\n\n        public isLoginServerEnabled(): boolean {\n            return false;\n        }\n\n        public socket(): number {\n            return -1;\n        }\n\n        public socketConnect(socket_num: number, dest: string | Buffer, port: number, conn_mode = TCP_MODE): boolean {\n            return false;\n        }\n\n        public socketWrite(socket_num: number, buffer: Buffer): void {\n        }\n\n        public socketAvailable(socket_num: number): number {\n            return -1;\n        }\n\n        public socketRead(socket_num: number, size: number): Buffer {\n            return undefined;\n        }\n\n        public socketClose(socket_num: number): void {\n        }\n\n        public hostbyName(hostname: string): Buffer {\n            return undefined;\n        }\n        get isIdle(): boolean { return false; }\n        get isConnected(): boolean { return this._isConnected; }\n        connectAP(bssid: string, password: string) { return false }\n        disconnectAP() { }\n\n        lastScanResults: net.AccessPoint[]\n        protected reconnectRunning: {}\n\n        autoconnect() {\n            if (this.reconnectRunning)\n                return\n            const myReconn = {}\n            this.reconnectRunning = myReconn\n            this.emitEvent(ControllerEvent.Connecting)\n            control.runInParallel(() => {\n                while (this.reconnectRunning == myReconn) {\n                    if (this.isConnected) {\n                        pause(1000)\n                    } else {\n                        this.connectCore()\n                        pause(500)\n                    }\n                }\n            })\n        }\n\n        disconnect() {\n            this.reconnectRunning = null\n            this.disconnectAP()\n        }\n\n        protected connectCore(): boolean {\n            if (control.deviceDalVersion() == \"sim\") {\n                this.connectAP(\"\", \"\")\n                return true\n            }\n\n            this.scanNetworks()\n            if (!this.lastScanResults || this.lastScanResults.length == 0) {\n                net.log(`no networks detected`)\n                this.emitEvent(ControllerEvent.NoScannedNetworks)\n                return false\n            }\n\n            if (!this.reconnectRunning)\n                return false\n\n            const wifis = net.knownAccessPoints();\n            const ssids = Object.keys(wifis);\n            const networks = this.lastScanResults\n                .filter(network => ssids.indexOf(network.ssid) > -1);\n\n            if (!networks.length) {\n                net.log(`no known networks`)\n                this.emitEvent(ControllerEvent.NoKnownNetworks)\n                return false\n            }\n\n            const priorities = net.accessPointPriorities()\n            networks.sort((a, b) => {\n                const pa = priorities[a.ssid] || 0\n                const pb = priorities[b.ssid] || 0\n                return pb - pa || b.rssi - a.rssi\n            })\n\n            // try connecting to known networks\n            for (const network of networks) {\n                net.log(`connecting to ${network.ssid}...`)\n                const pwd = wifis[network.ssid]\n                if (this.connectAP(network.ssid, pwd)) {\n                    net.log(`connected to ${network.ssid}`)\n                    return true\n                }\n                if (!this.reconnectRunning)\n                    return false\n\n                if (this.onConnectSSIDFailed)\n                    this.onConnectSSIDFailed(network.ssid)\n            }\n\n            net.log(`connection failed`)\n            this.emitEvent(ControllerEvent.ConnectionFailed)\n            return false\n        }\n\n        connect(timeout_ms?: number): boolean {\n            this.autoconnect()\n            pauseUntil(() => this.isConnected, timeout_ms)\n            return this.isConnected\n        }\n\n        get ssid(): string { return undefined; }\n        get rssi(): number { return undefined; }\n        get MACaddress(): Buffer { return undefined; }\n        get IPaddress(): Buffer { return undefined; }\n        public ping(dest: string, ttl: number = 250): number { return -1; }\n\n        // optional dataAvailable event\n        public dataAvailableSrc(socket_num: number): number { return -1; }\n        public dataAvailableValue(socket_num: number): number { return -1; }\n    }\n}","controllersocket.ts":"namespace net {\n\n    export const SOCK_STREAM = 1\n    export const AF_INET = 2\n    export const MAX_PACKET = 4000\n    export const TCP_MODE = 0\n    export const UDP_MODE = 1\n    export const TLS_MODE = 2\n\n    export class ControllerSocket implements net.Socket {\n        _buffer: Buffer;\n        _socknum: number;\n        _timeout: number;\n        _closed: boolean;\n        _openHandler: () => void;\n        _closeHandler: () => void;\n        _errorHandler: (msg: string) => void;\n        _messageHandler: (data: Buffer) => void;\n\n        /** A simplified implementation of the Python 'socket' class, for connecting\n    through an interface to a remote device\n */\n        constructor(private controller: Controller, private host: string | Buffer, private port: number, private conntype: number = null) {\n            if (this.conntype === null) {\n                this.conntype = net.TCP_MODE\n            }\n            this._buffer = hex``\n            this._socknum = this.controller.socket()\n            this.setTimeout(0)\n        }\n\n        /** Connect the socket to the 'address' (which can be 32bit packed IP or\n    a hostname string). 'conntype' is an extra that may indicate SSL or not,\n    depending on the underlying interface\n*/\n        public connect() {\n            if (!this.controller.socketConnect(this._socknum, this.host, this.port, this.conntype)) {\n                this.error(`failed to connect to ${this.host}`)\n                return;\n            }\n\n            this._buffer = hex``\n\n            if (this._openHandler)\n                this._openHandler();\n        }\n\n        /** Send some data to the socket */\n        public send(data: string | Buffer) {\n            //console.log(\"sock wr: \" + data)\n            this.controller.socketWrite(this._socknum, net.dataAsBuffer(data))\n        }\n\n        private error(msg: string) {\n            if (this._errorHandler)\n                this._errorHandler(msg)\n        }\n\n        onOpen(handler: () => void): void {\n            this._openHandler = handler;\n        }\n        onClose(handler: () => void): void {\n            this._closeHandler = handler;\n        }\n        onError(handler: (msg: string) => void): void {\n            this._errorHandler = handler;\n        }\n\n        private flushReadBuffer() {\n            while (!this._closed && this._messageHandler) {\n                const buf = this.read()\n                if (buf.length) {\n                    this._messageHandler(buf)\n                } else {\n                    break\n                }\n            }\n        }\n\n        onMessage(handler: (data: Buffer) => void): void {\n            if (this._messageHandler === undefined) {\n                const src = this.controller.dataAvailableSrc(this._socknum)\n                const value = this.controller.dataAvailableValue(this._socknum)\n                if (src > 0 && value > 0) {\n                    this.flushReadBuffer()\n                    control.internalOnEvent(src, value, () => this.flushReadBuffer())\n                } else {\n                    control.runInParallel(() => {\n                        while (!this._closed) {\n                            this.flushReadBuffer()\n                            pause(200)\n                        }\n                    })\n                }\n            }\n            this._messageHandler = handler || null;\n        }\n\n        /** Attempt to return as many bytes as we can up to but not including '\\r\\n' */\n        public readLine(): string {\n            // print(\"Socket readline\")\n            let stamp = monotonic()\n            while (this._buffer.indexOf(hex`0d0a`) < 0) {\n                // there's no line already in there, read some more\n                let avail = Math.min(this.controller.socketAvailable(this._socknum), MAX_PACKET)\n                if (avail > 0) {\n                    this._buffer = this._buffer.concat(this.controller.socketRead(this._socknum, avail))\n                } else if (avail < 0 || (this._timeout > 0 && monotonic() - stamp > this._timeout)) {\n                    // Make sure to close socket so that we don't exhaust sockets.\n                    this.close()\n                    throw \"Didn't receive full response, failing out\"\n                } else {\n                    pause(20)\n                }\n            }\n            const pos = this._buffer.indexOf(hex`0d0a`)\n            const pref = this._buffer.slice(0, pos)\n            this._buffer = this._buffer.slice(pos + 2)\n            // print(\"rd: \" + this._buffer.length + \" / \" + pref.length + \" :\" + pref.toString())\n            return pref.toString()\n        }\n\n        /** Read up to 'size' bytes from the socket, this may be buffered internally! If 'size' isn't specified, return everything in the buffer. */\n        public read(size: number = 0): Buffer {\n            // print(\"Socket read\", size)\n            if (size == 0) {\n                if (this._buffer.length == 0) {\n                    let avail = Math.min(this.controller.socketAvailable(this._socknum), MAX_PACKET)\n                    if (avail > 0)\n                        this._buffer = this.controller.socketRead(this._socknum, avail)\n                    if (avail < 0)\n                        this.close()\n                }\n                let ret = this._buffer\n                this._buffer = hex``\n                return ret\n            }\n\n            let stamp = monotonic()\n            let to_read = size - this._buffer.length\n            let received = []\n            while (to_read > 0) {\n                // print(\"Bytes to read:\", to_read)\n                let avail = Math.min(this.controller.socketAvailable(this._socknum), MAX_PACKET)\n                if (avail > 0) {\n                    stamp = monotonic()\n                    let recv = this.controller.socketRead(this._socknum, Math.min(to_read, avail))\n                    received.push(recv)\n                    to_read -= recv.length\n                } else {\n                    pause(20)\n                }\n\n                if (avail < 0 || (this._timeout > 0 && monotonic() - stamp > this._timeout)) {\n                    break\n                }\n\n            }\n            // print(received)\n            received.unshift(this._buffer)\n            this._buffer = pins.concatBuffers(received)\n            let ret = null\n            if (this._buffer.length == size) {\n                ret = this._buffer\n                this._buffer = hex``\n            } else {\n                ret = this._buffer.slice(0, size)\n                this._buffer = this._buffer.slice(size)\n            }\n\n            return ret\n        }\n\n        /** Set the read timeout for sockets, if value is 0 it will block */\n        public setTimeout(value: number) {\n            this._timeout = value\n        }\n\n        /** Close the socket, after reading whatever remains */\n        public close() {\n            this._closed = true;\n            this._buffer = hex``\n            this.controller.socketClose(this._socknum)\n            if (this._closeHandler)\n                this._closeHandler();\n        }\n    }\n}\n","net.ts":"/**\n * Networking, WiFi, web requests\n */\n//% weight=1\n//% advanced=true\n//% icon=\"\\uf1eb\" color=\"#8446cf\"\nnamespace net {\n    /**\n     * Default priority of net log messages\n     **/\n    export let logPriority: ConsolePriority = -1;\n    export function log(msg: string) {\n        console.add(logPriority, \"net:\" + msg);\n    }\n    export function debug(msg: string) {\n        if (logPriority > ConsolePriority.Debug)\n            console.add(ConsolePriority.Debug, \"net:\" + msg);\n    }\n    export function fail(reason: string) {\n        net.log(`error: ${reason}`);\n        throw reason;\n    }\n\n    export function monotonic(): number {\n        return control.millis() / 1000.0;\n    }\n\n    export const enum WifiAPFlags {\n        HasPassword = 0x1,\n        WPS = 0x2,\n        HasSecondaryChannelAbove = 0x4,\n        HasSecondaryChannelBelow = 0x8,\n        IEEE_802_11B = 0x100,\n        IEEE_802_11A = 0x200,\n        IEEE_802_11G = 0x400,\n        IEEE_802_11N = 0x800,\n        IEEE_802_11AC = 0x1000,\n        IEEE_802_11AX = 0x2000,\n        IEEE_802_LongRange = 0x8000,\n    }\n\n    export class AccessPoint {\n        flags: WifiAPFlags\n        rssi: number\n        bssid: Buffer\n        channel: number\n        constructor(public ssid: string) { }\n        static fromBuffer(buf: Buffer) {\n            const name = buf.slice(16)\n            let endp = name.length - 1\n            while (endp > 0 && name[endp] == 0)\n                endp--\n            endp++\n            const res = new AccessPoint(name.slice(0, endp).toString())\n            const [flags, _reserved, rssi, channel] = buf.unpack(\"<IIbB\")\n            res.flags = flags\n            res.rssi = rssi\n            res.channel = channel\n            res.bssid = buf.slice(10, 6)\n            if (res.bssid.toArray(NumberFormat.UInt16LE).every(x => x == 0))\n                res.bssid = null\n            return res\n        }\n        toBuffer() {\n            /*\n            flags: APFlags\n            reserved: u32\n            rssi: i8 dB {typical_min = -100, typical_max = -20}\n            channel: u8 {typical_min = 1, typical_max = 13}\n            bssid: u8[6]\n            ssid: string {max_bytes = 33}\n            */\n            const pref = Buffer.pack(\"<IIbB\", [this.flags, 0, this.rssi, this.channel])\n            const bssid = Buffer.create(6)\n            if (this.bssid) bssid.write(0, this.bssid)\n            return pref.concat(bssid).concat(Buffer.fromUTF8(this.ssid))\n        }\n    }\n\n    export interface Socket {\n        connect(): void;\n        send(data: string | Buffer): void;\n        read(contentLength: number): Buffer;\n        close(): void;\n        onOpen(handler: () => void): void;\n        onClose(handler: () => void): void;\n        onError(handler: (msg: string) => void): void;\n        onMessage(handler: (data: Buffer) => void): void;\n        setTimeout(millis: number): void;\n        readLine(): string;\n    }\n\n    export class Net {\n        private _controller: Controller;\n        constructor(private factory: () => Controller) {\n            Net.instance = this;\n            this._controller = undefined; // null failed to initialize\n        }\n\n        static instance: Net;\n\n        get controller(): net.Controller {\n            if (this._controller === undefined) {\n                net.log(`init controller`)\n                this._controller = this.factory();\n                if (!this._controller) {\n                    net.log(`controller not found`)\n                    this._controller = null;\n                }\n            }\n            return this._controller;\n        }\n\n        /**\n         * Scan for APs\n         */\n        scanNetworks(): net.AccessPoint[] {\n            const c = this.controller;\n            try {\n                return c ? c.scanNetworks() : [];\n            } catch (e) {\n                console.error(\"\" + e)\n                return [];\n            }\n        }\n\n        createSocket(host: string, port: number, secure: boolean): net.Socket {\n            const c = this.controller;\n            if (!c) return undefined;\n            const socket = new net.ControllerSocket(c, host, port, secure ? net.TLS_MODE : net.TCP_MODE);\n            return socket;\n        }\n\n        hostByName(host: string): string {\n            const c = this.controller;\n            if (!c) return undefined;\n            const b = this.controller.hostbyName(host);\n            if (b) return b.toString();\n            return undefined;\n        }\n    }\n\n    /**\n     * Gets the current Net instance\n     */\n    export function instance(): Net {\n        return net.Net.instance;\n    }\n\n    const AP_SECRETS_KEY = \"wifi\";\n    const AP_PRI_KEY = \"#wifipriority\";\n    /**\n     * Gets the map of SSID -> password pairs\n     */\n    export function knownAccessPoints(): StringMap {\n        return settings.deviceSecrets.readSecret(AP_SECRETS_KEY) || {};\n    }\n\n    export function clearAccessPoint(ssid: string) {\n        const ap = knownAccessPoints()\n        if (ap[ssid] !== undefined) {\n            delete ap[ssid]\n            settings.deviceSecrets.setSecret(AP_SECRETS_KEY, ap)\n        }\n    }\n\n    export function updateAccessPoint(ssid: string, password: string) {\n        const k: StringMap = {};\n        k[ssid] = password;\n        settings.deviceSecrets.updateSecret(AP_SECRETS_KEY, k);\n    }\n\n    export function setAccessPointPriority(ssid: string, pri: number) {\n        const s = accessPointPriorities()\n        if (s[ssid] != pri) {\n            s[ssid] = pri\n            settings.writeJSON(AP_PRI_KEY, s)\n        }\n    }\n\n    export function accessPointPriorities() {\n        return settings.readJSON(AP_PRI_KEY) || {}\n    }\n\n    export function clearAccessPoints() {\n        settings.deviceSecrets.setSecret(AP_SECRETS_KEY, undefined);\n    }\n}","netutil.ts":"namespace net {\n    export function urlencode(s: string) {\n        const buf = Buffer.fromUTF8(s)\n        let r = \"\"\n        for (let i = 0; i < buf.length; ++i) {\n            const c = buf[i]\n            if ((48 <= c && c <= 57) ||\n                (97 <= (c | 0x20) && (c | 0x20) <= 122) ||\n                (c == 45 || c == 46 || c == 95 || c == 126))\n                r += String.fromCharCode(c)\n            else\n                r += \"%\" + buf.slice(i, 1).toHex()\n        }\n        return r\n    }\n\n    export function urldecode(s: string) {\n        let r = \"\"\n        let isUtf8 = false\n        for (let i = 0; i < s.length; ++i) {\n            const c = s[i]\n            if (c == \"%\") {\n                const h = s.slice(i + 1, i + 3)\n                const chcode = parseInt(h, 16)\n                if (!isNaN(chcode)) {\n                    if (chcode > 127)\n                        isUtf8 = true\n                    r += String.fromCharCode(chcode)\n                    i += 2\n                    continue\n                }\n            }\n            r += c\n        }\n        if (isUtf8) {\n            const buf = Buffer.create(r.length)\n            for (let i = 0; i < buf.length; ++i)\n                buf[i] = r.charCodeAt(i)\n            return buf.toString()\n        } else {\n            return r\n        }\n    }\n}","pxt.json":"{\n    \"name\": \"net\",\n    \"description\": \"Networking abstractions\",\n    \"dependencies\": {\n        \"core\": \"*\",\n        \"settings\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"controller.ts\",\n        \"controllersocket.ts\",\n        \"net.ts\",\n        \"netutil.ts\",\n        \"requests.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true\n}\n","requests.ts":"namespace net {\n    /**\n     * Pings a web site\n     * @param dest host name\n     * @param ttl \n     */\n    //% blockId=netping block=\"net ping $dest\"\n    export function ping(dest: string, ttl: number = 250): number {\n        net.log(`ping ${dest}`);\n        const c = net.instance().controller;\n        if (!c) return Infinity;\n        // don't crash.\n        try {\n            return c.ping(dest, ttl);\n        } catch (e) {\n            console.error(\"\" + e)\n            return Infinity;\n        }\n    }\n\n    export class Response {\n        _cached: Buffer\n        status_code: number\n        reason: string\n        _read_so_far: number\n        headers: StringMap;\n\n        /** \n         * The response from a request, contains all the headers/content \n         */\n        constructor(private socket: Socket) {\n            this._cached = null\n            this.status_code = null\n            this.reason = null\n            this._read_so_far = 0\n            this.headers = {}\n        }\n\n        /** \n         * Close, delete and collect the response data \n         */\n        public close() {\n            if (this.socket) {\n                this.socket.close()\n                this.socket = null\n            }\n            this._cached = null\n        }\n\n        /** \n         * The HTTP content direct from the socket, as bytes \n         */\n        get content() {\n            // print(\"Content length:\", content_length)\n            if (this._cached === null && this.socket) {\n                const content_length = parseInt(this.headers[\"content-length\"]) || 0\n                this._cached = this.socket.read(content_length)\n                this.socket.close()\n                this.socket = null\n            }\n\n            // print(\"Buffer length:\", len(self._cached))\n            return this._cached\n        }\n\n        /** \n         * The HTTP content, encoded into a string according to the HTTP header encoding\n        */\n        get text() {\n            const b = this.content;\n            return b ? b.toString() : undefined;\n        }\n\n        get json() {\n            return JSON.parse(this.text)\n        }\n\n        public toString() {\n            return `HTTP ${this.status_code}; ${Object.keys(this.headers).length} headers; ${this._cached ? this._cached.length : -1} bytes content`\n        }\n    }\n\n    export interface RequestOptions {\n        data?: string | Buffer;\n        json?: any; // will call JSON.stringify()\n        headers?: StringMap;\n        stream?: boolean;\n        timeout?: number; // in ms\n    }\n\n    export function dataAsBuffer(data: string | Buffer): Buffer {\n        if (data == null)\n            return null\n        if (typeof data == \"string\")\n            return control.createBufferFromUTF8(data)\n        return data\n    }\n\n    /*\n    >>> \"a,b,c,d,e\".split(\",\", 2)\n    ['a', 'b', 'c,d,e']\n    */\n    function pysplit(str: string, sep: string, limit: number) {\n        const arr = str.split(sep)\n        if (arr.length >= limit) {\n            return arr.slice(0, limit).concat([arr.slice(limit).join(sep)])\n        } else {\n            return arr\n        }\n    }\n\n\n    /** Perform an HTTP request to the given url which we will parse to determine\nwhether to use SSL ('https://') or not. We can also send some provided 'data'\nor a json dictionary which we will stringify. 'headers' is optional HTTP headers\nsent along. 'stream' will determine if we buffer everything, or whether to only\nread only when requested\n \n*/\n    export function request(method: string, url: string, options?: RequestOptions): net.Response {\n        net.log(`${method} ${url}`);\n\n        if (!net.instance().controller) {\n            // no controller\n            const r = new net.Response(null);\n            r.status_code = 418; // teapot\n            r.reason = \"net controller not configured\";\n            return r;\n        }\n\n        try {\n            return internalRequest(method, url, options);\n        } catch (e) {\n            const r = new net.Response(null);\n            r.status_code = 418; // teapot\n            r.reason = \"\" + e;\n            return r;\n        }\n    }\n\n    function internalRequest(method: string, url: string, options?: RequestOptions): net.Response {\n        if (!options) options = {};\n        if (!options.headers) {\n            options.headers = {}\n        }\n\n        const tmp = pysplit(url, \"/\", 3)\n        let proto = tmp[0]\n        let host = tmp[2]\n        let path = tmp[3] || \"\"\n        // replace spaces in path\n        // TODO\n        // path = path.replace(\" \", \"%20\")\n\n        let port = 0\n        if (proto == \"http:\") {\n            port = 80\n        } else if (proto == \"https:\") {\n            port = 443\n        } else {\n            control.fail(\"Unsupported protocol: \" + proto)\n        }\n\n        if (host.indexOf(\":\") >= 0) {\n            const tmp = host.split(\":\")\n            host = tmp[0]\n            port = parseInt(tmp[1])\n        }\n\n        let sock: Socket;\n        if (proto == \"https:\") {\n            // for SSL we need to know the host name\n            sock = net.instance().createSocket(host, port, true)\n        } else {\n            sock = net.instance().createSocket(host, port, false)\n        }\n        // our response\n        let resp = new Response(sock)\n        // socket read timeout\n        sock.setTimeout(options.timeout)\n\n        sock.connect();\n        sock.send(`${method} /${path} HTTP/1.0\\r\\n`)\n\n        if (!options.headers[\"Host\"])\n            sock.send(`Host: ${host}\\r\\n`)\n\n        if (!options.headers[\"User-Agent\"])\n            sock.send(\"User-Agent: MakeCode ESP32\\r\\n\")\n\n        // Iterate over keys to avoid tuple alloc\n        for (let k of Object.keys(options.headers))\n            sock.send(`${k}: ${options.headers[k]}\\r\\n`)\n\n        if (options.json != null) {\n            control.assert(options.data == null, 100)\n            options.data = JSON.stringify(options.json)\n            sock.send(\"Content-Type: application/json\\r\\n\")\n        }\n\n        let dataBuf = dataAsBuffer(options.data)\n\n        if (dataBuf)\n            sock.send(`Content-Length: ${dataBuf.length}\\r\\n`)\n\n        sock.send(\"\\r\\n\")\n        if (dataBuf)\n            sock.send(dataBuf)\n\n        let line = sock.readLine()\n        // print(line)\n        let line2 = pysplit(line, \" \", 2)\n        let status = parseInt(line2[1])\n        let reason = \"\"\n        if (line2.length > 2) {\n            reason = line2[2]\n        }\n\n        while (true) {\n            line = sock.readLine()\n            if (!line || line == \"\\r\\n\") {\n                break\n            }\n\n            // print(\"**line: \", line)\n            const tmp = pysplit(line, \": \", 1)\n            let title = tmp[0]\n            let content = tmp[1]\n            if (title && content) {\n                resp.headers[title.toLowerCase()] = content.toLowerCase()\n            }\n        }\n\n        /*\n    \n    elif line.startswith(b\"Location:\") and not 200 <= status <= 299:\n    raise NotImplementedError(\"Redirects not yet supported\")\n    */\n\n        if ((resp.headers[\"transfer-encoding\"] || \"\").indexOf(\"chunked\") >= 0)\n            control.fail(\"not supported chunked encoding\")\n\n        resp.status_code = status\n        resp.reason = reason\n        return resp\n    }\n\n    /** \n     * Send HTTP HEAD request \n     **/\n    export function head(url: string, options?: RequestOptions) {\n        return request(\"HEAD\", url, options)\n    }\n\n    /** \n     * Send HTTP GET request \n     **/\n    export function get(url: string, options?: RequestOptions) {\n        return request(\"GET\", url, options)\n    }\n\n    /** \n     * Send HTTP GET request and return text \n     **/\n    //% blockId=netgetstring block=\"get string $url\"\n    export function getString(url: string, options?: RequestOptions): string {\n        const res = get(url, options)\n        const rv = res.status_code == 200 ? res.text : undefined\n        res.close()\n        return rv\n    }\n\n    /** \n     * Send HTTP GET request and return JSON \n     **/\n    //% blockId=netgetjson block=\"get json $url\"\n    export function getJSON(url: string, options?: RequestOptions): any {\n        options = options || {};\n        options.headers = options.headers || {};\n        options.headers[\"accept\"] = options.headers[\"accept\"] || \"application/json\";\n        const res = get(url, options);\n        const rv = res.status_code == 200 ? res.json : undefined;\n        res.close()\n        return rv\n    }\n\n    /** Send HTTP POST request */\n    export function post(url: string, options?: RequestOptions) {\n        return request(\"POST\", url, options)\n    }\n\n    /** Send HTTP PATCH request */\n    export function patch(url: string, options?: RequestOptions) {\n        return request(\"PATCH\", url, options)\n    }\n\n    /** Send HTTP PUT request */\n    export function put(url: string, options?: RequestOptions) {\n        return request(\"PUT\", url, options)\n    }\n\n    /** Send HTTP DELETE request */\n    export function del(url: string, options?: RequestOptions) {\n        return request(\"DELETE\", url, options)\n    }\n}"},"net-game":{"pxt.json":"{\n    \"name\": \"net-game\",\n    \"description\": \"WiFi support in Arcade - beta\",\n    \"dependencies\": {\n        \"core\": \"*\",\n        \"settings\": \"*\",\n        \"net\": \"*\",\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"settings.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true\n}\n","settings.ts":"namespace net {\n    class Configurator {\n        private accessPoints: net.AccessPoint[];\n        private apIndex: number;\n        private scanning: boolean;\n        private wifi: net.Controller;\n\n        constructor() {\n            this.scanning = false;\n            this.apIndex = 0;\n        }\n\n        private select() {\n            const ap = this.accessPoints && this.accessPoints[this.apIndex];\n            if (ap) {\n                const wifis = net.knownAccessPoints();\n                const known = wifis[ap.ssid] !== undefined ? \"*\" : \"?\";\n                console.log(`${known} ${ap.ssid}`);\n            }\n        }\n\n        private connect() {\n            console.log(\"connecting...\")\n            this.wifi.connect();\n            console.log(this.wifi.isConnected ? `connected to ${this.wifi.ssid}` : `disconnected`);\n            if (this.wifi.isConnected) {\n                for (let i = 0; i < 3; ++i) {\n                    const ping = this.wifi.ping(\"bing.com\")\n                    console.log(`bing.com ping ${ping}ms`);\n                }\n            }\n        }\n\n        private scan() {\n            if (this.scanning) return;\n\n            this.scanning = true;\n            const mac = this.wifi.MACaddress;\n            console.log(`MAC: ${mac ? mac.toHex() : \"???\"}`)\n            console.log(\"scanning...\")\n            control.runInBackground(() => {\n                this.accessPoints = this.wifi.scanNetworks()\n                if (this.accessPoints && this.accessPoints.length) {\n                    const wifis = net.knownAccessPoints();\n                    for (let i = 0; i < this.accessPoints.length; ++i) {\n                        const ap = this.accessPoints[i];\n                        const known = wifis[ap.ssid] !== undefined ? \"*\" : \"?\";\n                        console.log(` ${known} ${ap.ssid}`);\n                    }\n                    console.log(\" \");\n                    this.apIndex = 0;\n                    console.log(\"*: AP known\")\n                    console.log(\"up/down: select AP\")\n                    console.log(\"left: erase AP info\")\n                    console.log(\"right: enter AP password\")\n                    console.log(\"A: connect\")\n                    console.log(\" \");\n                    this.select();\n                }\n                this.scanning = false;\n            });\n        }\n\n        main() {\n            this.wifi = net.instance().controller;\n            if (!this.wifi) {\n                console.log(\"WiFi module not configured\");\n                return;\n            }\n            pauseUntil(() => this.wifi.isIdle, 30000);\n            if (!this.wifi.isIdle) {\n                console.log(\"WiFi module not responding\")\n                return;\n            }\n            controller.up.onEvent(ControllerButtonEvent.Pressed, () => {\n                this.apIndex = this.apIndex + 1;\n                if (this.accessPoints)\n                    this.apIndex = this.apIndex % this.accessPoints.length;\n                this.select();\n            })\n            controller.down.onEvent(ControllerButtonEvent.Pressed, () => {\n                this.apIndex = this.apIndex - 1;\n                this.apIndex = (this.apIndex + this.accessPoints.length) % this.accessPoints.length;\n                this.select();\n            })\n            controller.left.onEvent(ControllerButtonEvent.Pressed, () => {\n                const ap = this.accessPoints && this.accessPoints[this.apIndex];\n                if (!ap) return;\n                net.updateAccessPoint(ap.ssid, undefined);\n                console.log(`password erased`)\n                this.scan();\n            })\n            controller.right.onEvent(ControllerButtonEvent.Pressed, () => {\n                const ap = this.accessPoints && this.accessPoints[this.apIndex];\n                if (!ap) return;\n                game.consoleOverlay.setVisible(false);\n                const pwd = game.askForString(`password for ${ap.ssid}`, 24);\n                game.consoleOverlay.setVisible(true);\n                net.updateAccessPoint(ap.ssid, pwd);\n                console.log(`password saved`)\n                this.scan();\n            })\n            controller.A.onEvent(ControllerButtonEvent.Pressed, () => {\n                this.connect();\n            })\n            controller.B.onEvent(ControllerButtonEvent.Pressed, () => {\n                game.popScene();\n                game.consoleOverlay.setVisible(false);\n            });\n            this.scan();\n        }\n    }\n\n    function wifiSystemMenu() {\n        scene.systemMenu.closeMenu();\n        game.pushScene();\n        game.consoleOverlay.setVisible(true);\n        console.log(\"WiFi configuration\")\n        const config = new Configurator();\n        config.main()\n    }\n\n    scene.systemMenu.addEntry(\n        () => \"WiFi\",\n        () => wifiSystemMenu(),\n        img`\n    . . . . . . . . . . . . . . . .\n    . . . . . . 8 8 8 8 . . . . . .\n    . . . . 8 8 8 6 6 6 8 8 . . . .\n    . . . 8 6 6 6 6 6 6 6 6 8 . . .\n    . . 8 6 6 . . . . . . 6 6 8 . .\n    . 8 6 6 . . . . . . . . 6 6 8 .\n    8 6 6 . . . 8 8 8 8 . . . 6 6 8\n    . 6 . . . 8 6 6 6 6 8 . . . 6 .\n    . . . . 8 6 6 6 6 6 6 8 . . . .\n    . . . 8 6 6 . . . . 6 6 8 . . .\n    . . . . 6 . . . . . . 6 . . . .\n    . . . . . . . 8 8 . . . . . . .\n    . . . . . . 8 6 6 8 . . . . . .\n    . . . . . . 6 6 6 6 . . . . . .\n    . . . . . . . 6 6 . . . . . . .\n    . . . . . . . . . . . . . . . .\n`);\n}"},"palette":{"README.md":"# Palette\n\nHelpers to manipulate palette in games.","palette.ts":"/**\n * Update the current scene palette\n */\nnamespace palette {\n    /**\n     * The default palette buffer for the project\n     */\n    //% whenUsed\n    const defaultPaletteBuffer = hex`__palette`\n\n    /**\n     * Returns a clone of the default palette\n     */\n    export function defaultPalette(): color.ColorBuffer {\n        return color.ColorBuffer.fromBuffer(defaultPaletteBuffer.slice(), color.ColorBufferLayout.RGB);\n    }\n\n    const FIELD = \"__palette\";\n    /**\n     * Dynamically set all or part of the game's current palette\n     *\n     * @param palette The colors to set\n     * @param pOffset The offset to start copying from the palette\n     */\n    export function setColors(palette: color.ColorBuffer, pOffset = 0) {\n        const userPalette = getCurrentColors();\n        userPalette.write(pOffset, palette);\n        image.setPalette(userPalette.buf);\n\n        // make sure to clean up\n        game.addScenePushHandler(scenePush);\n        game.addScenePopHandler(scenePop);\n    }\n\n    /**\n     * Get the palette that is currently being used\n     */\n    export function getCurrentColors() {\n        const scene = game.currentScene();\n        let userPalette = scene.data[FIELD] as color.ColorBuffer;\n        if (!userPalette)\n            userPalette = scene.data[FIELD] = defaultPalette();\n        return userPalette;\n    }\n\n    function scenePush(scene: scene.Scene) {\n        if (scene.data[FIELD]) {\n            const userPalette = scene.data[FIELD] as color.ColorBuffer;\n            image.setPalette(userPalette.buf);\n        }\n    }\n\n    function scenePop(scene: scene.Scene) {\n        if (scene.data[FIELD]) {\n            scene.data[FIELD] = undefined;\n            image.setPalette(defaultPaletteBuffer);\n        }\n    }\n\n    /**\n     * Reset to default palette\n     */\n    export function reset() {\n        const scene = game.currentScene();\n        scene.data[FIELD] = undefined;\n        image.setPalette(defaultPaletteBuffer);\n    }\n}\n","pxt.json":"{\n    \"name\": \"palette\",\n    \"description\": \"Palette manipulations\",\n    \"dependencies\": {\n        \"color\": \"*\",\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"palette.ts\",\n        \"README.md\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"searchOnly\": true,\n    \"weight\": 75,\n    \"icon\": \"/static/libs/palette.png\"\n}\n","test.ts":"\nlet mySprite = sprites.create(img`\n0 1 2 3\n4 5 6 7\n8 9 a b\nc d e f\n`.doubled().doubled().doubled().doubled(), SpriteKind.Player)\n\ncontroller.A.onEvent(ControllerButtonEvent.Pressed, function () {\n    const p = palette.defaultPalette();\n    for (let i = 0; i < p.length; ++i) {\n        p.setColor(i, color.rgb(i * 16, 0, 255 - i * 16));\n    }\n    p.setColor(0, 0)\n    palette.setColors(p)\n})\n\ncontroller.B.onEvent(ControllerButtonEvent.Pressed, function () {\n    palette.reset()\n})\n\n"},"power":{"power.ts":"/**\n * Power and sleep management\n */\n//% advanced=true icon=\"\\uf011\" color=\"#898989\"\n//% weight=1 blockGap=8\nnamespace power {\n    let _poked: number;\n    let _timeout: number;\n\n    /**\n     * Set the no-activity duration after which the device should go to deep sleep.\n     * @param seconds duration in seconds until the device should be put in lower power mode\n     */\n    //% blockId=powersetdeepsleeptimout block=\"power set deep sleep timeout to %seconds s\"\n    //% seconds.defl=60\n    //% help=/power/set-deep-sleep-timeout\n    export function setDeepSleepTimeout(seconds: number) {\n        init();\n        _timeout = seconds * 1000;\n    }\n\n    /**\n     * Poke the activity watcher to keep the device awake.\n     */\n    //% blockId=powerpke block=\"power poke\"\n    //% help=/power/poke\n    export function poke() {\n        init();\n        _poked = control.millis();\n    }\n\n    /**\n     * Check if the device has had any \"pokes\" and needs to go into deep sleep mode.\n     */\n    //% blockId=powercheckdeepsleep block=\"power check deep sleep\"\n    //% help=/power/check-deep-sleep\n    export function checkDeepSleep() {\n        init();\n        const p = _poked || 0;\n        const to = _timeout || 0;\n        if (to > 0 && \n            control.millis() - p > to &&\n            !control.isUSBInitialized()) {\n            // going to deep sleep\n            deepSleep();\n        }\n    }\n\n    /**\n     * Put the device into a deep sleep state.\n     */\n    //% blockId=powerdeepsleep block=\"power deep sleep\"\n    //% shim=pxt::deepSleep\n    //% help=/power/deep-sleep\n    export function deepSleep() {\n    }\n\n    function init() {\n        if (_timeout !== undefined) return;\n\n        // read default value\n        _timeout = control.getConfigValue(DAL.CFG_POWER_DEEPSLEEP_TIMEOUT, -1) * 1000;\n        // ensure deepsleep is long enough\n        const minDeepSleepTimeout = 300000;\n        if (_timeout > 0 && _timeout < minDeepSleepTimeout)\n            _timeout = minDeepSleepTimeout;\n    }\n}\n","pxt.json":"{\n    \"name\": \"power\",\n    \"description\": \"Power and sleep management\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"power.ts\"\n    ],\n    \"testFiles\": [],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n"},"radio":{"README.md":"# radio\n\nThe radio library.\n\n","enums.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace radio {\n}\n\n// Auto-generated. Do not edit. Really.\n","pxt.json":"{\n    \"name\": \"radio\",\n    \"description\": \"The radio services\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"shims.d.ts\",\n        \"enums.d.ts\",\n        \"radio.cpp\",\n        \"radio.ts\",\n        \"targetoverrides.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"searchOnly\": true,\n    \"icon\": \"/static/libs/radio.png\"\n}\n","radio.cpp":"#include \"pxt.h\"\n\n// micro:bit dal\n#if defined(MICROBIT_H) \n\n#define CODAL_RADIO MicroBitRadio\n#define DEVICE_OK MICROBIT_OK\n#define DEVICE_NOT_SUPPORTED MICROBIT_NOT_SUPPORTED\n#define CODAL_EVENT MicroBitEvent\n#define CODAL_RADIO_MICROBIT_DAL 1\n\n// any other NRF52 board\n#elif defined(NRF52_SERIES)\n\n#include \"NRF52Radio.h\"\n#define CODAL_RADIO codal::NRF52Radio\n#define CODAL_EVENT codal::Event\n\n#endif\n\nusing namespace pxt;\n\n#ifndef MICROBIT_RADIO_MAX_PACKET_SIZE\n#define MICROBIT_RADIO_MAX_PACKET_SIZE          32\n#endif\n\n#ifndef DEVICE_RADIO_MAX_PACKET_SIZE\n#define DEVICE_RADIO_MAX_PACKET_SIZE MICROBIT_RADIO_MAX_PACKET_SIZE\n#endif\n\n#ifndef MICROBIT_ID_RADIO\n#define MICROBIT_ID_RADIO               29\n#endif\n\n#ifndef DEVICE_ID_RADIO\n#define DEVICE_ID_RADIO MICROBIT_ID_RADIO\n#endif\n\n#ifndef MICROBIT_RADIO_EVT_DATAGRAM\n#define MICROBIT_RADIO_EVT_DATAGRAM             1       // Event to signal that a new datagram has been received.\n#endif\n\n#ifndef DEVICE_RADIO_EVT_DATAGRAM\n#define DEVICE_RADIO_EVT_DATAGRAM MICROBIT_RADIO_EVT_DATAGRAM\n#endif\n\n//% color=#E3008C weight=96 icon=\"\\uf012\"\nnamespace radio {\n    \n#if CODAL_RADIO_MICROBIT_DAL\n    CODAL_RADIO* getRadio() {\n        return &uBit.radio;\n    }\n#elif defined(CODAL_RADIO)\nclass RadioWrap {\n    CODAL_RADIO radio;\n    public:\n        RadioWrap() \n            : radio()\n        {}\n\n    CODAL_RADIO* getRadio() {\n        return &radio;\n    }\n};\nSINGLETON(RadioWrap);\nCODAL_RADIO* getRadio() {\n    auto wrap = getRadioWrap();\n    if (NULL != wrap)\n        return wrap->getRadio();    \n    return NULL;\n}\n#endif // #else\n\n    bool radioEnabled = false;\n    bool init = false;\n    int radioEnable() {\n#ifdef CODAL_RADIO\n        auto radio = getRadio();\n        if (NULL == radio) \n            return DEVICE_NOT_SUPPORTED;\n\n        if (init && !radioEnabled) {\n            //If radio was explicitly disabled from a call to off API\n            //We don't want to enable it here. User needs to call on API first.\n            return DEVICE_NOT_SUPPORTED;\n        }\n\n        int r = radio->enable();\n        if (r != DEVICE_OK) {\n            target_panic(43);\n            return r;\n        }\n        if (!init) {\n            getRadio()->setGroup(0); //Default group zero. This used to be pxt::programHash()\n            getRadio()->setTransmitPower(6); // start with high power by default\n            init = true;\n        }\n        radioEnabled = true;\n        return r;\n#else\n        return DEVICE_NOT_SUPPORTED;\n#endif\n    }\n\n    /**\n    * Disables the radio for use as a multipoint sender/receiver.\n    * Disabling radio will help conserve battery power when it is not in use.\n    */\n    //% help=radio/off\n    void off() {\n#ifdef CODAL_RADIO\n        auto radio = getRadio();\n        if (NULL == radio)\n            return;\n\n        int r = radio->disable();\n        if (r != DEVICE_OK) {\n            target_panic(43);\n        } else {\n            radioEnabled = false;\n        }\n#else\n        return;\n#endif\n    }\n\n    /**\n    * Initialises the radio for use as a multipoint sender/receiver\n    * Only useful when the radio.off() is used beforehand.\n    */\n    //% help=radio/on\n    void on() {\n#ifdef CODAL_RADIO\n        auto radio = getRadio();\n        if (NULL == radio)\n            return;\n\n        int r = radio->enable();\n        if (r != DEVICE_OK) {\n            target_panic(43);\n        } else {\n            radioEnabled = true;\n        }\n#else\n        return;\n#endif\n    }\n\n    /**\n    * Sends an event over radio to neigboring devices\n    */\n    //% blockId=radioRaiseEvent block=\"radio raise event|from source %src=control_event_source_id|with value %value=control_event_value_id\"\n    //% blockExternalInputs=1\n    //% advanced=true\n    //% weight=1\n    //% help=radio/raise-event\n    void raiseEvent(int src, int value) {\n#ifdef CODAL_RADIO        \n        if (radioEnable() != DEVICE_OK) return;\n\n        getRadio()->event.eventReceived(CODAL_EVENT(src, value, CREATE_ONLY));\n#endif        \n    }\n\n    /**\n     * Internal use only. Takes the next packet from the radio queue and returns its contents + RSSI in a Buffer.\n     * @returns NULL if no packet available\n     */\n    //%\n    Buffer readRawPacket() {\n#ifdef CODAL_RADIO        \n        if (radioEnable() != DEVICE_OK) return NULL;\n\n        auto p = getRadio()->datagram.recv();\n#if CODAL_RADIO_MICROBIT_DAL\n        if (p == PacketBuffer::EmptyPacket)\n            return NULL;\n        int rssi = p.getRSSI();\n        auto length = p.length();\n        auto bytes = p.getBytes();\n#else\n        // TODO: RSSI support\n        int rssi = -73;        \n        auto length = p.length();\n        auto bytes = p.getBytes();\n        if (length == 0)\n            return NULL;\n#endif\n\n        uint8_t buf[DEVICE_RADIO_MAX_PACKET_SIZE + sizeof(int)]; // packet length + rssi\n        memset(buf, 0, sizeof(buf));\n        memcpy(buf, bytes, length); // data\n        memcpy(buf + DEVICE_RADIO_MAX_PACKET_SIZE, &rssi, sizeof(int)); // RSSi - assumes Int32LE layout\n        return mkBuffer(buf, sizeof(buf));\n#else\n        return NULL;\n#endif        \n    }\n\n    /**\n     * Internal use only. Sends a raw packet through the radio (assumes RSSI appened to packet)\n     */\n    //% async\n    void sendRawPacket(Buffer msg) {\n#ifdef CODAL_RADIO        \n        if (radioEnable() != DEVICE_OK || NULL == msg) return;\n\n        // don't send RSSI data; and make sure no buffer underflow\n        int len = msg->length - sizeof(int);\n        if (len > 0)\n            getRadio()->datagram.send(msg->data, len);\n#endif            \n    }\n\n    /**\n     * Used internally by the library.\n     */\n    //% help=radio/on-data-received\n    //% weight=0\n    //% blockId=radio_datagram_received_event block=\"radio on data received\" blockGap=8\n    //% deprecated=true blockHidden=1\n    void onDataReceived(Action body) {\n#ifdef CODAL_RADIO        \n        if (radioEnable() != DEVICE_OK) return;\n\n        registerWithDal(DEVICE_ID_RADIO, DEVICE_RADIO_EVT_DATAGRAM, body);\n        getRadio()->datagram.recv(); // wake up read code\n#endif       \n    }\n\n    /**\n     * Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time.\n     * @param id the group id between ``0`` and ``255``, eg: 1\n     */\n    //% help=radio/set-group\n    //% weight=100\n    //% blockId=radio_set_group block=\"radio set group %ID\"\n    //% id.min=0 id.max=255\n    //% group=\"Group\"\n    void setGroup(int id) {\n#ifdef CODAL_RADIO        \n        if (radioEnable() != DEVICE_OK) return;\n\n        getRadio()->setGroup(id);\n#endif       \n    }\n\n    /**\n     * Change the output power level of the transmitter to the given value.\n    * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7\n    */\n    //% help=radio/set-transmit-power\n    //% weight=9 blockGap=8\n    //% blockId=radio_set_transmit_power block=\"radio set transmit power %power\"\n    //% power.min=0 power.max=7\n    //% advanced=true\n    void setTransmitPower(int power) {\n#ifdef CODAL_RADIO        \n        if (radioEnable() != DEVICE_OK) return;\n\n        getRadio()->setTransmitPower(power);\n#endif        \n    }\n\n    /**\n    * Change the transmission and reception band of the radio to the given channel\n    * @param band a frequency band in the range 0 - 83. Each step is 1MHz wide, based at 2400MHz.\n    **/\n    //% help=radio/set-frequency-band\n    //% weight=8 blockGap=8\n    //% blockId=radio_set_frequency_band block=\"radio set frequency band %band\"\n    //% band.min=0 band.max=83\n    //% advanced=true\n    void setFrequencyBand(int band) {\n#ifdef CODAL_RADIO        \n        if (radioEnable() != DEVICE_OK) return;\n        getRadio()->setFrequencyBand(band);\n#endif        \n    }\n}\n","radio.ts":"\nenum RadioPacketProperty {\n    //% blockIdentity=radio._packetProperty\n    //% block=\"signal strength\"\n    SignalStrength = 2,\n    //% blockIdentity=radio._packetProperty\n    //% block=\"time\"\n    Time = 0,\n    //% block=\"serial number\"\n    //% blockIdentity=radio._packetProperty\n    SerialNumber = 1\n}\n\n/**\n * Communicate data using radio packets\n */\n//% color=#E3008C weight=96 icon=\"\\uf012\" groups='[\"Group\", \"Broadcast\", \"Send\", \"Receive\"]'\nnamespace radio {\n\n    // keep in sync with CODAL\n    const RADIO_MAX_PACKET_SIZE = 32;\n    const MAX_FIELD_DOUBLE_NAME_LENGTH = 8;\n    const MAX_PAYLOAD_LENGTH = 20;\n    const PACKET_PREFIX_LENGTH = 9;\n    const VALUE_PACKET_NAME_LEN_OFFSET = 13;\n    const DOUBLE_VALUE_PACKET_NAME_LEN_OFFSET = 17;\n\n    // Packet Spec:\n    // | 0              | 1 ... 4       | 5 ... 8           | 9 ... 28\n    // ----------------------------------------------------------------\n    // | packet type    | system time   | serial number     | payload\n    //\n    // Serial number defaults to 0 unless enabled by user\n\n    // payload: number (9 ... 12)\n    export const PACKET_TYPE_NUMBER = 0;\n    // payload: number (9 ... 12), name length (13), name (14 ... 26)\n    export const PACKET_TYPE_VALUE = 1;\n    // payload: string length (9), string (10 ... 28)\n    export const PACKET_TYPE_STRING = 2;\n    // payload: buffer length (9), buffer (10 ... 28)\n    export const PACKET_TYPE_BUFFER = 3;\n    // payload: number (9 ... 16)\n    export const PACKET_TYPE_DOUBLE = 4;\n    // payload: number (9 ... 16), name length (17), name (18 ... 26)\n    export const PACKET_TYPE_DOUBLE_VALUE = 5;\n\n    let transmittingSerial: boolean;\n    let initialized = false;\n\n    export let lastPacket: RadioPacket;\n    let onReceivedNumberHandler: (receivedNumber: number) => void;\n    let onReceivedValueHandler: (name: string, value: number) => void;\n    let onReceivedStringHandler: (receivedString: string) => void;\n    let onReceivedBufferHandler: (receivedBuffer: Buffer) => void;\n\n    function init() {\n        if (initialized) return;\n        initialized = true;\n        onDataReceived(handleDataReceived);\n    }\n\n    function handleDataReceived() {\n        let buffer: Buffer = readRawPacket();\n        while (buffer) {\n            lastPacket = RadioPacket.getPacket(buffer);\n            switch (lastPacket.packetType) {\n                case PACKET_TYPE_NUMBER:\n                case PACKET_TYPE_DOUBLE:\n                    if (onReceivedNumberHandler)\n                        onReceivedNumberHandler(lastPacket.numberPayload);\n                    break;\n                case PACKET_TYPE_VALUE:\n                case PACKET_TYPE_DOUBLE_VALUE:\n                    if (onReceivedValueHandler)\n                        onReceivedValueHandler(lastPacket.stringPayload, lastPacket.numberPayload);\n                    break;\n                case PACKET_TYPE_BUFFER:\n                    if (onReceivedBufferHandler)\n                        onReceivedBufferHandler(lastPacket.bufferPayload);\n                    break;\n                case PACKET_TYPE_STRING:\n                    if (onReceivedStringHandler)\n                        onReceivedStringHandler(lastPacket.stringPayload);\n                    break;\n            }\n            // read next packet if any\n            buffer = readRawPacket();\n        }\n    }\n\n    /**\n     * Registers code to run when the radio receives a number.\n     */\n    //% help=radio/on-received-number\n    //% blockId=radio_on_number_drag block=\"on radio received\" blockGap=16\n    //% useLoc=\"radio.onDataPacketReceived\" draggableParameters=reporter\n    //% group=\"Receive\"\n    //% weight=20\n    export function onReceivedNumber(cb: (receivedNumber: number) => void) {\n        init();\n        onReceivedNumberHandler = cb;\n    }\n\n    /**\n     * Registers code to run when the radio receives a key value pair.\n     */\n    //% help=radio/on-received-value\n    //% blockId=radio_on_value_drag block=\"on radio received\" blockGap=16\n    //% useLoc=\"radio.onDataPacketReceived\" draggableParameters=reporter\n    //% group=\"Receive\"\n    //% weight=19\n    export function onReceivedValue(cb: (name: string, value: number) => void) {\n        init();\n        onReceivedValueHandler = cb;\n    }\n\n    /**\n     * Registers code to run when the radio receives a string.\n     */\n    //% help=radio/on-received-string\n    //% blockId=radio_on_string_drag block=\"on radio received\" blockGap=16\n    //% useLoc=\"radio.onDataPacketReceived\" draggableParameters=reporter\n    //% group=\"Receive\"\n    //% weight=18\n    export function onReceivedString(cb: (receivedString: string) => void) {\n        init();\n        onReceivedStringHandler = cb;\n    }\n\n    /**\n     * Registers code to run when the radio receives a buffer.\n     */\n    //% help=radio/on-received-buffer blockHidden=1\n    //% blockId=radio_on_buffer_drag block=\"on radio received\" blockGap=16\n    //% useLoc=\"radio.onDataPacketReceived\" draggableParameters=reporter\n    export function onReceivedBuffer(cb: (receivedBuffer: Buffer) => void) {\n        init();\n        onReceivedBufferHandler = cb;\n    }\n\n    /**\n     * Returns properties of the last radio packet received.\n     * @param type the type of property to retrieve from the last packet\n     */\n    //% help=radio/received-packet\n    //% blockGap=8\n    //% blockId=radio_received_packet block=\"received packet %type=radio_packet_property\" blockGap=16\n    //% group=\"Receive\"\n    //% weight=16\n    export function receivedPacket(type: number) {\n        if (lastPacket) {\n            switch (type) {\n                case RadioPacketProperty.Time: return lastPacket.time;\n                case RadioPacketProperty.SerialNumber: return lastPacket.serial;\n                case RadioPacketProperty.SignalStrength: return lastPacket.signal;\n            }\n        }\n        return 0;\n    }\n\n    /**\n     * Gets a packet property.\n     * @param type the packet property type, eg: PacketProperty.time\n     */\n    //% blockId=radio_packet_property block=\"%note\"\n    //% shim=TD_ID blockHidden=1\n    export function _packetProperty(type: RadioPacketProperty): number {\n        return type;\n    }\n\n    export class RadioPacket {\n        public static getPacket(data: Buffer) {\n            if (!data) return undefined;\n            // last 4 bytes is RSSi\n            return new RadioPacket(data);\n        }\n\n        public static mkPacket(packetType: number) {\n            const res = new RadioPacket();\n            res.data[0] = packetType;\n            return res;\n        }\n\n        private constructor(public readonly data?: Buffer) {\n            if (!data) this.data = control.createBuffer(RADIO_MAX_PACKET_SIZE + 4);\n        }\n\n        get signal() {\n            return this.data.getNumber(NumberFormat.Int32LE, this.data.length - 4);\n        }\n\n        get packetType() {\n            return this.data[0];\n        }\n\n        get time() {\n            return this.data.getNumber(NumberFormat.Int32LE, 1);\n        }\n\n        set time(val: number) {\n            this.data.setNumber(NumberFormat.Int32LE, 1, val);\n        }\n\n        get serial() {\n            return this.data.getNumber(NumberFormat.Int32LE, 5);\n        }\n\n        set serial(val: number) {\n            this.data.setNumber(NumberFormat.Int32LE, 5, val);\n        }\n\n        get stringPayload() {\n            const offset = getStringOffset(this.packetType) as number;\n            return offset ? this.data.slice(offset + 1, this.data[offset]).toString() : undefined;\n        }\n\n        set stringPayload(val: string) {\n            const offset = getStringOffset(this.packetType) as number;\n            if (offset) {\n                const buf = control.createBufferFromUTF8(truncateString(val, getMaxStringLength(this.packetType)));\n                this.data[offset] = buf.length;\n                this.data.write(offset + 1, buf);\n            }\n        }\n\n        get numberPayload() {\n            switch (this.packetType) {\n                case PACKET_TYPE_NUMBER:\n                case PACKET_TYPE_VALUE:\n                    return this.data.getNumber(NumberFormat.Int32LE, PACKET_PREFIX_LENGTH);\n                case PACKET_TYPE_DOUBLE:\n                case PACKET_TYPE_DOUBLE_VALUE:\n                    return this.data.getNumber(NumberFormat.Float64LE, PACKET_PREFIX_LENGTH);\n            }\n            return undefined;\n        }\n\n        set numberPayload(val: number) {\n            switch (this.packetType) {\n                case PACKET_TYPE_NUMBER:\n                case PACKET_TYPE_VALUE:\n                    this.data.setNumber(NumberFormat.Int32LE, PACKET_PREFIX_LENGTH, val);\n                    break;\n                case PACKET_TYPE_DOUBLE:\n                case PACKET_TYPE_DOUBLE_VALUE:\n                    this.data.setNumber(NumberFormat.Float64LE, PACKET_PREFIX_LENGTH, val);\n                    break;\n            }\n        }\n\n        get bufferPayload() {\n            const len = this.data[PACKET_PREFIX_LENGTH];\n            return this.data.slice(PACKET_PREFIX_LENGTH + 1, len);\n        }\n\n        set bufferPayload(b: Buffer) {\n            const len = Math.min(b.length, MAX_PAYLOAD_LENGTH - 1);\n            this.data[PACKET_PREFIX_LENGTH] = len;\n            this.data.write(PACKET_PREFIX_LENGTH + 1, b.slice(0, len));\n        }\n\n        hasString() {\n            return this.packetType === PACKET_TYPE_STRING ||\n                this.packetType === PACKET_TYPE_VALUE ||\n                this.packetType === PACKET_TYPE_DOUBLE_VALUE;\n        }\n\n        hasNumber() {\n            return this.packetType === PACKET_TYPE_NUMBER ||\n                this.packetType === PACKET_TYPE_DOUBLE ||\n                this.packetType === PACKET_TYPE_VALUE ||\n                this.packetType === PACKET_TYPE_DOUBLE_VALUE;\n        }\n    }\n\n    /**\n     * Broadcasts a number over radio to any connected micro:bit in the group.\n     */\n    //% help=radio/send-number\n    //% weight=60\n    //% blockId=radio_datagram_send block=\"radio send number %value\" blockGap=8\n    //% group=\"Send\"\n    export function sendNumber(value: number) {\n        let packet: RadioPacket;\n\n        if (value === (value | 0)) {\n            packet = RadioPacket.mkPacket(PACKET_TYPE_NUMBER);\n        }\n        else {\n            packet = RadioPacket.mkPacket(PACKET_TYPE_DOUBLE);\n        }\n\n        packet.numberPayload = value;\n        sendPacket(packet);\n    }\n\n    /**\n    * Broadcasts a name / value pair along with the device serial number\n    * and running time to any connected micro:bit in the group. The name can\n    * include no more than 8 characters.\n    * @param name the field name (max 8 characters), eg: \"name\"\n    * @param value the numeric value\n    */\n    //% help=radio/send-value\n    //% weight=59\n    //% blockId=radio_datagram_send_value block=\"radio send|value %name|= %value\" blockGap=8\n    //% group=\"Send\"\n    export function sendValue(name: string, value: number) {\n        let packet: RadioPacket;\n\n        if (value === (value | 0)) {\n            packet = RadioPacket.mkPacket(PACKET_TYPE_VALUE);\n        }\n        else {\n            packet = RadioPacket.mkPacket(PACKET_TYPE_DOUBLE_VALUE);\n        }\n\n        packet.numberPayload = value;\n        packet.stringPayload = name;\n        sendPacket(packet);\n    }\n\n    /**\n     * Broadcasts a string along with the device serial number\n     * and running time to any connected micro:bit in the group.\n     */\n    //% help=radio/send-string\n    //% weight=58\n    //% blockId=radio_datagram_send_string block=\"radio send string %msg\"\n    //% msg.shadowOptions.toString=true\n    //% group=\"Send\"\n    export function sendString(value: string) {\n        const packet = RadioPacket.mkPacket(PACKET_TYPE_STRING);\n        packet.stringPayload = value;\n        sendPacket(packet);\n    }\n\n    /**\n     * Broadcasts a buffer (up to 19 bytes long) along with the device serial number\n     * and running time to any connected micro:bit in the group.\n     */\n    //% help=radio/send-buffer\n    //% weight=57\n    //% advanced=true\n    export function sendBuffer(msg: Buffer) {\n        const packet = RadioPacket.mkPacket(PACKET_TYPE_BUFFER);\n        packet.bufferPayload = msg;\n        sendPacket(packet);\n    }\n\n    /**\n    * Set the radio to transmit the serial number in each message.\n    * @param transmit value indicating if the serial number is transmitted, eg: true\n    */\n    //% help=radio/set-transmit-serial-number\n    //% weight=8 blockGap=8\n    //% blockId=radio_set_transmit_serial_number block=\"radio set transmit serial number %transmit\"\n    //% advanced=true\n    export function setTransmitSerialNumber(transmit: boolean) {\n        transmittingSerial = transmit;\n    }\n\n    function sendPacket(packet: RadioPacket) {\n        packet.time = control.millis();\n        packet.serial = transmittingSerial ? control.deviceSerialNumber() : 0;\n        radio.sendRawPacket(packet.data);\n    }\n\n    function truncateString(str: string, bytes: number) {\n        str = str.substr(0, bytes);\n        let buff = control.createBufferFromUTF8(str);\n\n        while (buff.length > bytes) {\n            str = str.substr(0, str.length - 1);\n            buff = control.createBufferFromUTF8(str);\n        }\n\n        return str;\n    }\n\n    function getStringOffset(packetType: number) {\n        switch (packetType) {\n            case PACKET_TYPE_STRING:\n                return PACKET_PREFIX_LENGTH;\n            case PACKET_TYPE_VALUE:\n                return VALUE_PACKET_NAME_LEN_OFFSET;\n            case PACKET_TYPE_DOUBLE_VALUE:\n                return DOUBLE_VALUE_PACKET_NAME_LEN_OFFSET;\n            default:\n                return undefined;\n        }\n    }\n\n    function getMaxStringLength(packetType: number) {\n        switch (packetType) {\n            case PACKET_TYPE_STRING:\n                return MAX_PAYLOAD_LENGTH - 1;\n            case PACKET_TYPE_VALUE:\n            case PACKET_TYPE_DOUBLE_VALUE:\n                return MAX_FIELD_DOUBLE_NAME_LENGTH;\n            default:\n                return undefined;\n        }\n    }\n}","shims.d.ts":"// Auto-generated. Do not edit.\n\n\n\n    //% color=#E3008C weight=96 icon=\"\\uf012\"\ndeclare namespace radio {\n\n    /**\n     * Disables the radio for use as a multipoint sender/receiver.\n     * Disabling radio will help conserve battery power when it is not in use.\n     */\n    //% help=radio/off shim=radio::off\n    function off(): void;\n\n    /**\n     * Initialises the radio for use as a multipoint sender/receiver\n     * Only useful when the radio.off() is used beforehand.\n     */\n    //% help=radio/on shim=radio::on\n    function on(): void;\n\n    /**\n     * Sends an event over radio to neigboring devices\n     */\n    //% blockId=radioRaiseEvent block=\"radio raise event|from source %src=control_event_source_id|with value %value=control_event_value_id\"\n    //% blockExternalInputs=1\n    //% advanced=true\n    //% weight=1\n    //% help=radio/raise-event shim=radio::raiseEvent\n    function raiseEvent(src: int32, value: int32): void;\n\n    /**\n     * Internal use only. Takes the next packet from the radio queue and returns its contents + RSSI in a Buffer.\n     * @returns NULL if no packet available\n     */\n    //% shim=radio::readRawPacket\n    function readRawPacket(): Buffer;\n\n    /**\n     * Internal use only. Sends a raw packet through the radio (assumes RSSI appened to packet)\n     */\n    //% async shim=radio::sendRawPacket\n    function sendRawPacket(msg: Buffer): void;\n\n    /**\n     * Used internally by the library.\n     */\n    //% help=radio/on-data-received\n    //% weight=0\n    //% blockId=radio_datagram_received_event block=\"radio on data received\" blockGap=8\n    //% deprecated=true blockHidden=1 shim=radio::onDataReceived\n    function onDataReceived(body: () => void): void;\n\n    /**\n     * Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time.\n     * @param id the group id between ``0`` and ``255``, eg: 1\n     */\n    //% help=radio/set-group\n    //% weight=100\n    //% blockId=radio_set_group block=\"radio set group %ID\"\n    //% id.min=0 id.max=255\n    //% group=\"Group\" shim=radio::setGroup\n    function setGroup(id: int32): void;\n\n    /**\n     * Change the output power level of the transmitter to the given value.\n     * @param power a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7\n     */\n    //% help=radio/set-transmit-power\n    //% weight=9 blockGap=8\n    //% blockId=radio_set_transmit_power block=\"radio set transmit power %power\"\n    //% power.min=0 power.max=7\n    //% advanced=true shim=radio::setTransmitPower\n    function setTransmitPower(power: int32): void;\n\n    /**\n     * Change the transmission and reception band of the radio to the given channel\n     * @param band a frequency band in the range 0 - 83. Each step is 1MHz wide, based at 2400MHz.\n     **/\n    //% help=radio/set-frequency-band\n    //% weight=8 blockGap=8\n    //% blockId=radio_set_frequency_band block=\"radio set frequency band %band\"\n    //% band.min=0 band.max=83\n    //% advanced=true shim=radio::setFrequencyBand\n    function setFrequencyBand(band: int32): void;\n}\n\n// Auto-generated. Do not edit. Really.\n","targetoverrides.ts":"// leave empty"},"radio-broadcast":{"pxt.json":"{\n    \"name\": \"radio-broadcast\",\n    \"description\": \"Adds new blocks for message communication in the radio category\",\n    \"dependencies\": {\n        \"core\": \"*\",\n        \"radio\": \"*\"\n    },\n    \"files\": [\n        \"radio-broadcast.ts\"\n    ],\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"icon\": \"/static/libs/radio-broadcast.png\"\n}\n","radio-broadcast.ts":"namespace radio {\n    const BROADCAST_GENERAL_ID = 2000;\n\n    /**\n     * Gets the message code\n     */\n    //% blockHidden=1 shim=ENUM_GET\n    //% blockId=radioMessageCode block=\"$msg\" enumInitialMembers=\"message1\"\n    //% enumName=RadioMessage enumMemberName=msg enumPromptHint=\"e.g. Start, Stop, Jump...\"\n    //% enumIsHash=1\n    export function __message(msg: number): number {\n        return msg;\n    }\n\n    /**\n     * Broadcasts a message over radio\n     * @param msg \n     */\n    //% blockId=radioBroadcastMessage block=\"radio send $msg\"\n    //% msg.shadow=radioMessageCode draggableParameters\n    //% weight=200\n    //% blockGap=8\n    //% help=radio/send-message\n    //% group=\"Broadcast\"\n    export function sendMessage(msg: number): void {\n        // 0 is MICROBIT_EVT_ANY, shifting by 1\n        radio.raiseEvent(BROADCAST_GENERAL_ID, msg + 1);\n    }\n\n    /**\n     * Registers code to run for a particular message\n     * @param msg \n     * @param handler \n     */\n    //% blockId=radioOnMessageReceived block=\"on radio $msg received\"\n    //% msg.shadow=radioMessageCode draggableParameters\n    //% weight=199\n    //% help=radio/on-received-message\n    //% group=\"Broadcast\"\n    export function onReceivedMessage(msg: number, handler: () => void) {\n        control.onEvent(BROADCAST_GENERAL_ID, msg + 1, handler);\n    }\n}"},"rotary-encoder":{"README.md":"# Rotary Encoder\n\n## Configuration\n\nMap the following pins in your bootloader to configure the default \"crank\".\n\n```typescript\nPIN_ROTARY_ENCODER_A\nPIN_ROTARY_ENCODER_B\n```\n","enums.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace encoders {\n}\n\n// Auto-generated. Do not edit. Really.\n","ns.ts":"/**\n * Rotary encoders\n */\n//% color=\"#03AA74\" weight=87 icon=\"\\uf021\"\nnamespace encoders {\n\n    /**\n     * Gets the default rotary encoder if any\n     */\n    //% block=\"encoder\" fixedInstance whenUsed\n    export const defaultEncoder = encoders.createRotaryEncoder(undefined, undefined);\n}","pxt.json":"{\n    \"name\": \"rotary-encoder\",\n    \"description\": \"Driver for rotary encoder\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"rotary.cpp\",\n        \"enums.d.ts\",\n        \"shims.d.ts\",\n        \"ns.ts\",\n        \"targetoverrides.ts\",\n        \"README.md\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true,\n    \"icon\": \"/static/libs/rotary-encoder.png\"\n}\n","rotary.cpp":"#include \"pxt.h\"\n\n// update sim if modifying these\n#define ROT_EV_TIMER 0x1233\n#define ROT_EV_CHANGED 0x2233\n\nconst static int8_t posMap[] = {0, +1, -1, +2, -1, 0, -2, +1, +1, -2, 0, -1, +2, -1, +1, 0};\n\nclass RotaryEncoder_ {\n  public:\n    uint16_t id;\n    uint16_t state;\n    int position;\n    Pin &pinA, &pinB;\n\n    void process(Event) {\n        // based on comments in https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h\n        uint16_t s = state & 3;\n        if (pinA.getDigitalValue())\n            s |= 4;\n        if (pinB.getDigitalValue())\n            s |= 8;\n\n        state = (s >> 2);\n        if (posMap[s]) {\n            int lastPosition = position;\n            position += posMap[s];\n            if ((lastPosition >> 2) != (position >> 2)) {\n                Event ev(id, ROT_EV_CHANGED);\n            }\n        }\n    }\n\n    RotaryEncoder_(Pin &pinA, Pin &pinB) : pinA(pinA), pinB(pinB) {\n        position = 0;\n        id = pinA.id;\n\n        pinA.setPull(codal::PullMode::Up);\n        pinB.setPull(codal::PullMode::Up);\n\n        // don't do exactly 1000us, so that it doesn't occur exactly at scheduler ticks\n        system_timer_event_every_us(973, id, ROT_EV_TIMER);\n        EventModel::defaultEventBus->listen(id, ROT_EV_TIMER, this, &RotaryEncoder_::process,\n                                            MESSAGE_BUS_LISTENER_IMMEDIATE);\n    }\n};\n\ntypedef class RotaryEncoder_ *RotaryEncoder;\n\n/**\n * Rotary and other encoders\n */\nnamespace encoders {\n/**\n * Create a new rotary encoder connected to given pins\n */\n//% weight=99\nRotaryEncoder createRotaryEncoder(DigitalInOutPin pinA, DigitalInOutPin pinB) {\n    if (!pinA && !pinB) {\n        pinA = LOOKUP_PIN(ROTARY_ENCODER_A);\n        pinB = LOOKUP_PIN(ROTARY_ENCODER_B);\n        // not configured?\n        if (!pinA && !pinB)\n            return NULL;\n    }\n\n    if (!pinA || !pinB)\n        target_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n\n    return new RotaryEncoder_(*pinA, *pinB);\n}\n} // namespace pins\n\n//% noRefCounting fixedInstances\nnamespace RotaryEncoderMethods {\n/**\n * Do something when a rotary encoder changes position\n */\n//% blockNamespace=\"encoders\"\n//% blockId=rotaryencoderonchaned block=\"on %this changed\"\n//% weight=80 blockGap=8\nvoid onChanged(RotaryEncoder encoder, Action body) {\n    registerWithDal(encoder->id, ROT_EV_CHANGED, body);\n}\n\n/**\n * Get current encoder position.\n */\n//% blockNamespace=\"encoders\"\n//% blockId=rotaryencoderposition block=\"%this position\"\n//% weight=79 blockGap=8\nint position(RotaryEncoder encoder) {\n    // the position always changes by 4 per tick\n    return encoder->position >> 2;\n}\n\n} // namespace RotaryEncoderMethods\n","shims.d.ts":"// Auto-generated. Do not edit.\n\n\n    /**\n     * Rotary and other encoders\n     */\n\ndeclare namespace encoders {\n\n    /**\n     * Create a new rotary encoder connected to given pins\n     */\n    //% weight=99 shim=encoders::createRotaryEncoder\n    function createRotaryEncoder(pinA: DigitalInOutPin, pinB: DigitalInOutPin): RotaryEncoder;\n}\n\n\n\n    //% noRefCounting fixedInstances\ndeclare interface RotaryEncoder {\n    /**\n     * Do something when a rotary encoder changes position\n     */\n    //% blockNamespace=\"encoders\"\n    //% blockId=rotaryencoderonchaned block=\"on %this changed\"\n    //% weight=80 blockGap=8 shim=RotaryEncoderMethods::onChanged\n    onChanged(body: () => void): void;\n\n    /**\n     * Get current encoder position.\n     */\n    //% blockNamespace=\"encoders\"\n    //% blockId=rotaryencoderposition block=\"%this position\"\n    //% weight=79 blockGap=8 shim=RotaryEncoderMethods::position\n    position(): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n","targetoverrides.ts":"// target specific\n"},"screen":{"fieldeditors.ts":"/**\n * Image manipulation blocks\n */\n//% weight=70 icon=\"\\uf03e\" color=\"#a5b1c2\"\n//% advanced=true\nnamespace images {\n    //% blockId=screen_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.decompileArgumentAsString=\"true\"\n    //% img.fieldOptions.filter=\"!tile !dialog !background\"\n    //% weight=100 group=\"Create\" duplicateShadowOnDrag\n    //% help=images/sprite-image\n    export function _spriteImage(img: Image) {\n        return img\n    }\n\n    //% blockId=background_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.decompileArgumentAsString=\"true\"\n    //% img.fieldOptions.sizes=\"-1,-1\"\n    //% img.fieldOptions.filter=\"background\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _screenImage(img: Image) {\n        return img\n    }\n\n    //% blockId=tilemap_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.sizes=\"10,8;16,16;32,32;48,48;64,64;16,32;32,48;32,8;64,8;20,15;40,15\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _tileMapImage(img: Image) {\n        return img\n    }\n\n    //% blockId=tile_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.sizes=\"16,16;32,32;8,8\"\n    //% img.fieldOptions.filter=\"tile\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _tileImage(img: Image) {\n        return img\n    }\n\n    //% blockId=tileset_tile_picker block=\"%tile\"\n    //% shim=TD_ID\n    //% tile.fieldEditor=\"tileset\"\n    //% tile.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% weight=10 blockNamespace=\"scene\" group=\"Tiles\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _tile(tile: Image) {\n        return tile\n    }\n\n    //% blockId=dialog_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.decompileArgumentAsString=\"true\"\n    //% img.fieldOptions.sizes=\"15,15;18,18;21,21;24,24;9,9;12,12\"\n    //% img.fieldOptions.filter=\"dialog\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _dialogImage(img: Image) {\n        return img\n    }\n\n    /**\n     * An image\n     * @param image the image\n     */\n    //% blockId=image_picker block=\"$image\" shim=TD_ID\n    //% image.fieldEditor=\"sprite\"\n    //% image.fieldOptions.taggedTemplate=\"img\"\n    //% image.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% image.fieldOptions.decompileArgumentAsString=\"true\"\n    //% weight=0 group=\"Create\"\n    //% deprecated\n    //% help=images/image\n    export function _image(image: Image): Image {\n        return image;\n    }\n\n    //% blockId=colorindexpicker block=\"%index\" blockHidden=true shim=TD_ID\n    //% index.fieldEditor=\"colornumber\"\n    //% index.fieldOptions.valueMode=\"index\"\n    //% index.fieldOptions.decompileLiterals=\"true\"\n    export function __colorIndexPicker(index: number) {\n        return index;\n    }\n\n    /**\n     * A position picker\n     */\n    //% blockId=positionPicker block=\"%index\" blockHidden=true shim=TD_ID\n    //% index.fieldEditor=\"position\" color=\"#ffffff\" colorSecondary=\"#ffffff\"\n    //% index.fieldOptions.decompileLiterals=\"true\"\n    export function __positionPicker(index: number) {\n        return index;\n    }\n}\n","font12.jres":"{\n    \"image.font12\": {\n        \"mimeType\": \"font/x-mkcd-b26\",\n        \"data\": \"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9A9UANwHAAD4AQAI/AcAADhSIAGqCOoIrAS4Aq4BqAi4CKwG6gGqACABOVJQBFQDVAjIB0wAUgFSBgAA/AkACP4PAAA6UgAEdAYUAf4PFAH0AgAA/AEACAAI/gcAADtSAAAkCbQErwJkAhQDxAQAAPwJAAj+DwAAPVIgAJAMiAakBaYEiAawCAAA+AkACP4HAABCUkQIVARUAzYANACsDyQAAAD8CQAI/wcAAENSAAToBKoCrAH4D64AuAcAAPwJAAj+BwAAR1IACP4FKgUqASoB/g0AAPwBAAgACP4HAABKUgAA9g9QAV4JUAn2BwAA/AEACAAI/gcAAE1SAADoD6oCrAqoCugHCADoAw4I6AcIAAAATlIAAFIEUgNMAOQPSgJqBAAA/AkACP4HAABRUhAAWAiEBRIE0wQEB8gCAAL8CAAI/gcAAFRSAAG+BOoCqg2qA6oIvgcAAPwJAAj+BwAAVlIkAKwPrASmBKQEvASsBwAA/AkACP4PAABbUgAA/A8MA+QDFAn8BwAA+AEACPwHAAAAAF1SAADAANgKVgrUB3QAzAYAAPgJAAj+BwAAY1IQCPAEvAbyAbQC5AwAAPwBAAgACP4HAABkUgAAJAisB5YCrAKkDyQAAAD8AQAI/g8AAGVSoAIqCioJ6g8qAb4CoAYAAPwJAAj+BwAAZ1LABz4AqgeqBPoEqgSuBwAA/AAACP8HAABpUogIbARsAgwB/A8MAWoCKAQAAPwJAAj+B2pSAAV8BTwFPgW8A/wBBAF0BQYFdAUEAwAAb1ICAN4PVgXWB1YFVgXeDwAA/AkACP4HAABwUgAArAT8AqwB/A+qAvoGAAD4AQAI/gcAAHJSjAC8D7QFtAX2BbQHtAeMBwAA/AEACP4HdVIQABAO0AP4BfQF5AXoBwAA+AEACPwHAAB/UgAIdgVwBXQD+g94A3ADdgUAAPgJAAj+B4NSSAT8B/wH/gf8B/wH/Af8BwAE+AEACPwHh1IADvgBGATYBn4DbA9sAggE8AEACPwPAACIUoAAfAj0CbQJtAX4A1QBXAn2CVwJVAcAAIlSAACcCcoLyQmwB84FQgUOBPgBAAj+BwAAjVIICOgErALqAEsIogbkBAAA/AEACP4HAACRUjgASAz0A4wClgK8AswPIAD8AQAI/gcAAJtSAAAQCBAEEAKQAX4AEAAQCBAIEAzwAwAAnVIABBQCZAHkABwJAASIA34ACAgICPgHAACeUgAAiAloBAgCiAF+CAgICAz4AwAA4AEAAJ9SBAIEAvwBBAkECRAEEAP+CBAIEAzwAwAAoFIICAgG/gEICAgI+AcAAPwPBAQEBPwPAAChUkAIUAlICSwFNgOkASQJNAlMCUQHQAAAAKNSKAioCKQIogSgA54AkAiICIIIhAcIAAAAqFIAACQE5AMkAqQCJAMACBAH/gAQCPAHAACpUgAE/gOSBJIC/gsABBAD8AgfCBAI8AcAAKpSAAhECVwJZgUkA1wBRAE0CSQJXAdEAAAAq1IAAEgHyAR+AkgCQAcQABAP/gAQCPAHAACxUgAO/AEUDPQDVAjUBwQAEAf8ABAI8AcAALJSAACkCKQElAesBKQEMAAQDv4BEAjwBwAAs1IACLQIlASWBJQD1ACUCJQIlgiUBzQAAAC0UgAIuAiKBIoEiALrAYgIiAiMCIoHOAAAALlSKAioBKgCDAGoAggIUAQQA/4IEAjwBwAAv1IAABQIVAl+BRQFwAM0AR4JBAk8B0AAIADBUgAAtASEBLQHhAS0DAQEEAP+CBAI8AcAAMNSAAA0AhQJXgeUATQJAAQQA/4IEAjwBwAAx1IACAIK+gqqBqoC+gKqAq4Kqgr6BgAAAADJUhAI+ASWA/QAnAfwCBgKmAl+CAgK+AkABMtSAAjuCSoEqgMqCO4LAAAQB/4AEAjwBwAA0lIAAOQCvgL0D74C5AgEBBAD/ggQCPAHAADVUgAAfAl8CfwHeg0IBBgCkAF+CBAI8AcAANhSgACCB/8FqgSqBP8FggwIAv8BCAT4AwAA2VIAACoDqgjqBzYA4AlIBy4BNAk0CSwHRAHdUgAM/gOSCP4HgAFqCTgHrgE4CW4JqgcAAd5SEgiSCKgErgSgAqIBpAioCKYIKAdyAAAA31IAAkQB/AV+A3wDfAF8BX4F/AN8AUQCAADiUgAArAmsCe4FrAWAA/gBGAkOCXgGgABgAORSAAj0CdYF9AfWBfQFAAwQA/4IEAjwBwAA51IAACAB7A+4B+gHqAeoDgAG/AEQCPAHAADyUgAB/g3+Af4B/g3+AQgLmAh+AAgB+AwAAPNSBAh9BW0B/wTsAvwCAAaIAX8ECAT4AwAA9VIADPwDzA/8AewD/AvMDwAM/gMQCPAHAAD4UgAB+g+7B4AHuwe6BwAM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JAAAAK1T+AcEAPQD/AJ8B3QFhAckBPwDJAEUAgAErlMABv4BAgT6AVoD+gECDPoDSgDKD0oAAACyUwAO/gECAOoP6gHqBeIH6gXqBeoJCg8CALNTAA74AQ4E+Ae4BroG/A8IAOgMLAPqBSgIu1NAAEgMSAZIBcgEfgRIBEgFSAZICEAAAAC/UwAAgACABP4GqgWqBKoEqgSqBP4GgASAAMFTIAGoCKgK7Aq6CqgKqgruCqgKqAggAQAAwlMgASgBqAhsCroKqAooCWoErASgACABAADDUwAAAAGwAKQJdgulChQKJgl2BKAEMAFAAchTAAAACAQIHARkBIQCBAGEAmQEHAQECAAIyVMACAQIPAREBJQCFAGUAkQEPAQEBAAIAADKUwAEBAaEAXwIJATEBAQDHAOQAnAEEAQAAMtTAAQIBAgDyAh+BKgEKAMoA6gEaAQICAAEzFMUCDQERALkARwKAAh8BIQDxAI8BAAIAADNUwAAAAz8AyQI5AgkBSQCJAakBWQIBAgAAM5TAAL4AQABAAH+DwAAFAjkBAQDxAQ8BAQI0VMABBACHAuQCPAIXgVQBlAF1ghQCBAIAADUUwACoAEgCP4PJACgCwQIfAaEAeQCHAwACNZTBAT8B5QElASUAvwPAABoCIgFCAPoBBgI11MAAHQIHATcBFQFXAJcAlIF2gQaBDAIAADYUwAIpAiUCIQJvAaGBIYEvAaECZQIJAgACNlTUAZYAVQI8g9UAFQDBAh8BIQDxAI8DAAA21MAAKwIoAb+AaQAAA78AXIMkgOSAnIMAATgUwAA6Ah2CFYPVg9GD1YPXg9WD3gIyAgAAOFTAACoANgHvwfaB/oHkAAMDPQChAF8BgAE4lMIAKoE7Af4B/wH6A/oAPwH7AXqB4gJgAjjUwAAAAD8DwQEBAQEBAQEBAQEBPwPAAAAAORTAAAIAIgPiASIBP4EiASIBIgEiA8IAAAA5VMAAGAAEADMByoCKAIoAugLCAgIDPgDAADmUwAAgAi8BKQEpAPkAKQApAikCLwIgAcAAOhTAAD8AwQB/AkACAQGhAF8BAQIBAz8AwAA6VMAAPwDBAEEAfwBAAD8DwQABAIEAvwBAADqUwAAAAh8BEQCRAFEAEQARAFEAnwEAAgAAOtTAAD8AwQBBAH8AQAA/AMAAQAB/g8AAAAA7FOAAEQARA8kCRQJDAlECUQJRAk8DwAAAADtUwAA/AMEAfwBAAzAAzwAAAB8AIADAAwAAO5TAAD8AwQB/AEAAAQABAgECPwHBAAEAAAA71MAAAQA9AMUARQBFAH0AQQIBAj8BwQAAADwUwAAIACgD5gElgSRBJAEkASUBJgPIAAgAPJTAAh4CEgFSAZIAsgFfgRICEgISAh4CAAI81MAAYgAiADoD1wESgRIBEgESATIDwgAAAD2UwAA/AMEAQQB/AEgACAA/g8gACAAIAAAAPdTAABAAFwB1AFUAVQJVAlUCVQNXANAAAAA+FMAABQA1AdUAlQCVAJUAtQDFAgECPwPAAD5UwAA/AMEAfwFAAwcBGQChAFEAjwEBAgAAPxTAAD8AwQB/AEAAAQBhABECDQIBAz8AwAA/VMAAPwDBAH8CQAE/AMEAAQA/AcACAAGAAABVAAA/AMEAfwBAABEAEQIRAj8D0QARABAAANUAAD8AwQB/AEAABAEDguoCKgIaAgoCAgGBFRIAEgAJA+mBKsEkgSSBKoEpgQiD0AAQAAGVAAA/AMEAfwBAAhgBFgHxgRgBBAHAAgAAAhUIAAgAJAPiAikCKIIogikCIgIkA8gACAACVQAACQApA+kBKQEvwSkBKQEpASkDyQAAAAKVAAAgAe8AKQApADkD6QApACkBLwEgAMAAAtUAAD8AwQBBAH8AQAA0AAQCRAI/gcQABAADFQAAPwPBADUB1QCVAJUAtQDFAgECPwHAAANVAAAGAGIAIwA0wdjBFIESgRGBEAEwA8AAA5UAAAADvwBFACUD5QElASSBJIEkgSSDxAAD1QAAAQI9AiUBpQG/gWUBJQIlAiUCPQIBAgQVAAA/AMEAfwBAAQgBCAE/gcgBCAEIAQAABFUAAD4DwgA6AMsASoBKAHoCQgICAj4BwAAE1QAAPwDBAH8AQAABAAEAPwPBAAkAEQAAAAVVAAAAAC8D6QIpAikCKQIpAikCLwPAAAAABdUAAD8AwQB/AEAAHQBRAFECWQJXAzAAwAAG1QIAggBqgDqD7oErgSqBKoEqgS+DwgAAAAdVIAARABED0wFVAUmBSQFVAVMBUQPRACAAB5UIAIkAaQPZAkkCTwJJAkkCWQJpA8kASACH1QAAPwDBAH8AQAAsACIAKYIpAyIA7AAIAAgVAAA/AMEAQQB/AkABCAD/gAgAyYEKAgAACZUIAAkAKQPlASUBLwEhASUBJQEpA8kACAAJ1QAAPwDBAH8AQAA/AdECEQIfAhECEQI/AYoVPwDBAH8AQAA6AEIAQgB/gcICQgJ6AsICClUAAD8AwQB/AEACGAEWALGAUAIRgiYByAAK1QQAAgAKA8oCSwJKgkqCawJaAkoDwgAEAAsVAAA/AMEAfwBAAgABvwBJAAiAOIPIgAgAC1U/AMEAQQB/AEACAgE6AMqACoA6AcICAgGLlQAAPwDBAH8CQAEMAbsASIA6A8oCDAIIAYvVAAAwA84AKgPqASuBKgEqASoBLgEgA8AADFUAAD8AwQB/AkACGgEqAU+AigF6AQICAAAM1QAAAAJfAlABVwF1ANUAVQDVAXcBQAJAAg0VAAAQAlcCVQFVAfUAVQDVAVUBVwJQAkAADVUAAD8AwQB/AEACHgIAAT+BAACiAEwAAAAOFQAAPwDBAH8CQAEhAN8CIQEJAc8BeAEAAg5VAAA/AMEAfwJYAgeBAgD+AAIAwgEeAgAADtUAAD8AwQB/AEgAJwJagQYA/gICAT4AwAAPFQAAPwDBAH8AQAI9A9MAAAA/AcACAAIAAc+VCAAIgCqD6oEvgSqBKoEqgS6BKIPIAAAAEBUAAD8AwQB/AEABDoCIgGiCGII/gciACAAQlQAAAAAngeSBJIE8gSSBJIEkgSeBwAAAABGVAAIgAieBJICkgHyD5IBkgKSAp4EgAgABEhUAACACLwKpAqkCqQPpAqkCqQKvAqACAAASlQAACgApw+lBKQEpAS/BKQEpASkDyQAAABQVAAA/AMEAfwBAADwDxAD8ABeAJAJ8AcAAFVUAAD8AwQB/AEAAPwHBAQ0BcQEpAQUBQAEWFQAAAAI/gUyBDIDsgAyAjICMgT+BQAIAABbVAAA/AMEAfwBEADIByQIIgkkCcgIEAYQAFxUAAD8AwQB/AEAAHwBRAFGAWQJZAjcBwAAYlQAAPwDBAH8CQAE/gMSANIHkgiSCF4GAABmVAAA/AMEAfwAEAPuAiAJCAb+AQgI+AcAAGhUAAAADv4BAgCqB6oCugKqCyoIAgj+BwAAc1QAAPwDBAH8AQAESAJIAf4PSAFIAkgEAAB1VAAA/AMEAfwBAAD0AxQBFAH0CQQI/AcEAHtUAAD8AwQB/AEAAPwDJAEkAf8PJAEkAfwDfFQAAPwDBAH8AQAAtAiECPwHggCyAIoAAAB9VAAAEADQB1gCWALUAxIA1A9YAEgC0AEQAIZUAAD8AwQB/AEwAPgDlgSUBPQFBAX8BAACi1QAAPwDBAH8ARAACAAOAPgPKAEoASgBAACMVAAClAFUAPwHUgAAAPwHBAIEAgQC/AcAAI9UAAD8AwQB/AQAAtQBFAj0D4QAQAEgBgAEkFQAAPwDBAH8AWAA/A8CANAAEAkQCP4HEACSVAAIHAgUBNQDXABAAFwAVADUBxwIAAgABpVUAAD8AwQB/AEAAJAPkASQBP4EkASQDxAAllQAAPwHBAH8DAAC/gkIDPAD/A8EBPwPAACZVAAA/AMEAfwJAASQA34IEATyB5YIVAgQBJpUAAD8AwQB/AFQAEgCLgK1BDQFTAlEAEAAplQAAPwDBAH8AQAI7ASsAv4BrAKsBLwJAAinVAAA/AMEAfwBQAi8BJQDYAD4CQAI/gcAAKhUIAARAIoPoASsBKMEkgSOBJIEog8uAAAAqlQAAPwHBAL8AwAIrAcgAP4PIACoAyQMAACsVAAA/AMEAfwBAAgoCKgECgPMBQgEaAhACK9UAAD8AwQB/AEQAYgPVgllCXQJXAmED4AAsVQAAPwBBAH8AQAA+AeoAqwCqgKoAvgHAACyVAAA/AMEAfwJAAhOBEwC+AFMAk4ESggAALNUAAD8AwQB/AEACCQFtARvAiQClAVECAAAuFQADPgDCACoB6gCqAoIC/4ICAfKCCwIAAa9VAAA/AMEAfgA/g8CBCIF+gSiBQIE/g8AAMBUAAIEAXQBVA/UBFUE1gRUAVQCdAUEBQAIwVQAAMAPQAReBNIHEgDSD1IEXgRABMAPAADEVAAA/AMEAfwBAAiIBP4CiACIAP4CiAyACMZUAAD8AwQB/AEACCgJpASWBFQCTAHEAAAAx1QAAPwDBAH8AQAIJAkkCb4PJAkkCSAJAADIVAAA/AMEAfwBYAAwD6gEpgSoBDAPYABAAMlUEADUB1QCXgJUAtQJEAz+AhADkgRUCAAHzVQAAPwDBAH8AQAA+A8IAOgDLgHoCQgI+AfOVAAA/AMEAfwBAAgkCM4EBAMEBc4EJAgECNFUAAD8AwQB/AVABAQE/AcEBPwHBATkBAAA11QAAPwDBAH8AQAAfAECAZAPPgFIAUQBJADfVAAA/AMEAfwBAAT8BYIEEALOCAgI+AcAAOFUAAAACP8LrQatBq0CrQKtBq0G/wsACAAA5VQAAEQAfAdsBWwFbAVsB3wARAj8D0QAAADmVAAA/AMEAfwBAAj8D5IAEAz+A5AFVggABuhUAAD8AwQB/AEAAPYPUAFeAVAJUAn2BwAA6VT8AwQB/AEAAHwJVAlUCfwPVAlUCXwJAADqVAAA/AMEAfgMAgL+CZII/gf8DwIA/gMAAO1UgAieCJIIkgSeA8AAnAOUBNQE3AiACAAA7lQAAP4BggD+AIABagEqCb8PagEuASoBCQHyVAAAEgCyD78EigSgBJ4EiQSJBLkHCQAIAPpU/AMEAfwBAADoD6gCqAL+D6gCqgrsBwAA/FQAAPwBhAD8AAAAvAisCK4OrAGsAbwABAABVQAA/AcEA/wDAACoDqgKqgqqCqgKqA4IAAZVAAD8AwQB/AlACCgJngaIBPwGzAVYCEAIB1UAAAAP/gAiDuoKqgpqCqoKqgoqDSIBAAAJVQAA/AMEAfwBAAgoCS4F6gMoBS4JKAkAABBVAAb8AQQAXAdcBVwF/gVcBVwFfAcUAAAAFFUAAPwDBAH8AQAAqge6BK4EqgS6BKIHIAAgVQAA/AMEAfwBAAiUBJYC1AmUCJYMNAMAACRV/AMEAfwBAAj4BJQClgH0AZwClAT0BIAIJ1UAAPwDBAH8AQAE/AdUAjwA+A8EAPwDAAAsVQAA/AMEAfwBAAz4AygIPgdsAGwHTAgABC5VCAAIAHwPXgVcBVwFfgVcBVwFXA9EAAAAL1UAAPwDBAH8AQAA/A+qBKgE/geoBKgEAAAxVQAA/AMEAfwBAAD+B2oFagVqBWoF/gcAADdVAAD8AwQB/AEACPQH7ADmAmUKZAr0ByQAOFUAAPwDBAH8CAAGKACkBLIJNAr0ACQGCAg+VQAA/AMEAfwBAAjUChQK/A8UCtIKUAoQCENVAAD+AYIA/gAIAO4PqAKvAqoKqgrqDwAARFUAAPwDBAH8ASAElAJUCiwJxAdkAJQDAARGVQAAAAD0DxQAfAcWBTQFVAVcBxQA9A8AAEpVAAD8AwQB+AD+DzIAzAHkAxQB5Aj8BwQAT1UAAP4PKgCqB74CgAK+AqoDKggqCP4HAABTVcIAOgCqB6oEqgS6BJAEzgS0BDQHTACEAF9VAAb8AaoHqgKqAroDIAR+AogB6AIYBAAAYVUAAPwDBAH8AQAAKAH+DwAA/g8oASgBAABkVfwDBAH8AQAAfALUAtQCfgJUD1QCfAIAAGVVAAD8AwQB/AEQAEgHRAXyBVQFRAVIB1AAZlUAAPwDBAH8AQAM/gMICGAIiQkKDugJAABqVQAA/AMEAfwBgAj+B0AA+A+MBIoE+A8AAHBVAAD8AwQB+AmOCVIIfgVSAl4B0gFeAAAAeFX8AwQB/AEADKwDLAYsAf4PLAEsArwPCAB8VQAA/AMEAfwBAABsB6QApg+0AKQEpAMAAIBVAAD8BwQC/AMAAKQPtAlWCVQJpA6MAAAAglX8AwQB/AEAAPwA1A/UCPwJ1ALUB/wJAACDVQAA/AMEAfwA4A8UALQCngfUAhQI9AcAAIRVAAFEAVQPVgtUC/wLVAtUC9YL1A9EAQAAh1UAAPwDBAH8DGQCng/0AZQCYAj4CP4HAACJVQAA/AMEAfwBYAD4DwYAUAlUBdQDXAVQCYpVAAD8AwQB/AzwAwgHqAIIDX4CiAVqCAAGlFUAAPwDBAH8DAAC/Ak0CPQKtA+0CrwKAACYVfwDBAH8AQAAvA+wALAP/gCwD7AAvA8AAJpVAAD8AYQAfAjwBVgFNgOUAzwFUAXwCQABnFUAAQQBfA/cC1wLXgtcC1wL3At8DwQBAAGdVQAA/AMEAfwBAAC+BqoEqgWqCKoIvgcAAKdVAAD8AwQB/AEICPQLtAq2CrQK1AscCAAAqlUAAIQIvAisD7wIhAj+CYQCvASsCrwKhAirVQAA/AMEAfwJAAg+BTQDwAM8BQQJfAkAAKxVKAAsAJwP/ADcB9wF3AXcBfwHmgioDyAArlUAAAAE/gVaBVoF/g9QBV4FWgX6BQ4EAACyVQAA/gMCAf4BGAznApAAUAaOAAgI+AcAALNVAAD8AwQB/AEACNQLrAquCqwK1AsUCAAAtVX+AYIA/gAAAPAPkgSXBPIHkASXBPIHAgC2VQAAGAAKB3wFWAXeBVgFWAV8BQoHGAAAALdV/AMEAfwBAAjUC1QIVAZWAVQEVAjUCwAIu1UAAPwDBAH8ARgA2A+0AvIPlAEYCMgHEADFVQAA/AMEAfwBAAh8BVwFXgNeA9wFfAUACc5VAAD8AwQB/AEADP4AqgaqAP4EqgGCDwAA01UAAPwDBAH8AQAIUgV2A4YPlgNSBTAFAAjaVQAA/AMEAfwJAAT8ANQO1gDUBdwIwAcAANxVAAD8AwQB/AFAADQHfgfUB9wH1AfUBwAA4VX8AwQB/AEABMgCVAqiBxAAUgJ0CuQHCADjVQAA3A/UB9QP3A+EAVQC1AsECPwHAAAAAORV/AEEAfwBAATgB2wGeAbuB2gGaAbsDyAI5lUAAPwDBAH8AQAMVAH0CV4HFAGUBTAIAADoVQAA/AMEAfwAAA5EAJADzAKoC6gK6AcAAu9VAAD8AwQB+AA+AWICagRaBVoEQgF+AwAC/VUAAPwDBAH8BCQC/g9UAXQJEAbOAQgGOAgAVgAA/AMEAfwBAAD0DxQC9gVUBVwHFAj0BwFWAAD+AYIA/g74AYQE9AcUAIcEfAOFBnQCBlb8AwQB/AEACPQK1ArWBvQD1AbWCvQKAAAJVgAAgg6+Au4KrgqvBq4M7gquCr4Kgg4AAA5WAAD4AwgB8AUEBXwF/AN8A3wF/AV8BwQDF1YAAAwARg/WC/QL9gv0C/QL9gvFD5wAAAAbVgAA/AMEAfwI+AcEAfQPJgKEAfQPpAAEAx9WAAD8AwQB/ACAD34FUAWID/wHBAD8AwAAMVYAAPwBhAB8CAAH/A60AdwF/AfUAdwPAAAyVgAA/AMEAfwDfAKuD3wC/geSAP4PAAAAADRWAAD8AwQB/AEQBNgD7gL0B/AC7gLUBxAANlYAAPwDBAH4AAQN/gFUAf4N/AMkAOIPIgA5VgAA/gOCAf4BAAz6AVYJUw9WAfoBMgwAADtWAAD8AwQB/AEAAHwP3AteC1wL3At8DwQBP1b8AYQA/AAACF4FVgFSBf4JWgFSBV4AAA5BVgAA/AMEAfwAIA1UAdwHBAvcC1QJdAEADWJWAAD8AwQB+Al8CAwFZAN2ASQDRAV8CQAAaFYAAEACXA9UCdQJfA9gAEwP9Al0CVwPQAJpVgQIxAv8CvwLRAj8D0QI/AvsCvwLBAgAAGpWAAD8AwQB/AnABbwF9AOUD/QPvAPgBQAIdFYAAPwBhAD8BBAE9Af0AvYC9ALUBvQHEAiHVgAA/AMECfwH5As/COQPJA3kA/8PJACgA45WAAD8AwQB/AFACDwGvAa+A7wPvAPkBAAAo1YAAIgH7gWuBW4HWABuB24FrgVuBYgHAAC0VgAO4AG8BPQH9AfsD7gB1Al0BvwFYAgAALdWAAD8AwQB/AUADPwP7An+AfQH7AX8CQAAvFYAAPwDBAH8AQAA9A/yBfoMMgG5CLUHgADCVgAACAL+B/4H/gf+BvgA/gb+B/4HCAUAAclWAAD+AYIAfAH3BqUCBwP9D1cF9QdXBQAAylYABbQD/Av8B/wFngX8AfwD/AXcB5QHAADaVgAA/g8CBAIFggRCBDoEwgQCBQIE/g8AANtWAAD8DwQExAU8BAQEBAR8BIQEBAT8DwAA3lYAAP4PAgTyBJIEkgSSBPIEAgQCBP4PAADgVgAA/g8CBCIFIgWiBHoEogQiBQIE/g8AAOJWAAD+BwIEkgRSBFIFMgX6BRIEAgT+BwAA41YAAP4HAgQKBGoECgUKBfoECgQCBP4HAADkVv4PAgRSBJIEkgT6BZIGkgZSBgIE/g8AAO1WAAD+BwIEKgXqBCoE6gUqBSoFAgT+BwAA8FYAAP4PAgSiBWIE+gViBKIEIgUCBP4PAADxVgAA/A8EBEQFJAVXBZQEdAUUBQQE/A8AAPJWAAD+DwIEkgT6BZIEkgT6BZIEAgT+DwAA81YAAP4PAgZaB0IFygTCBDIFCgUCBP4PAAD0VgAA/g8CBKoEqgT6BaoEqgSKBQIE/g8AAPpWAAD+DwIEEgTSBVIFegVSBdIFAgT+DwAA/VYAAP4PAgQqBSoF+gUqBWoFKgUCBP4PAAD+VgAA/w8BBCkFLQUVBZUFrQYlBgEE/w8AAANXAAD8BwQE9AX0BPwE/AX0BPQE9AUEBPwHBlf+BwIG3gZWBlYFVgVWBF4GwgYCBP4HAAAIVwAA/gcCBD4E/gU6BroGegY6BQIE/gcAAAtXAAD+BwIE6gWqBUoEegWKBW4GAgT+BwAADVcAAP4HAgT+BX4FfgX+BX4FegUCBP4HAAAPVwAA/gcCBGoE6gX6BuoG+gZqBAIE/gcAABJXAAD+DwIM6g1qC3oLagtqC+oLAgz+DwAAE1cAAP4PAgjCC/oL6gvqC+oL+gsCCP4PAAAWVwAA/gcCBP4H9gf2B/YHfgbiBwIE/gcAABhX/g8CBP4E/gX+BP4E/gb+B/4EAgT+DwAAH1cABCAEIAQgBCAE/gcgBCAEIAQgBAAEAAAjV0AIRAhMCSwJNAmkDzQJNAlMCUQIQAgAACdXAAAADPwDBAhECEQI9A9ECEQIRAgECAAAKFcIAYgAyA84AI4IiAiICOgPiAiICIgIAAAtVwAIJAkkCSQJJAm/DyQJJAkkCSQJIAgAADBXAAIQAv4BEAFAAPwHIAggCP4JEAgQCfgEM1cABBAC/gMQAQAM/gMAAAAA/AcAAAAA/g86VwACEAL+AxABAAEiCfIEKgLmCSIM4AMAAD5XAAQQAv4DEAoABIQDfAiEBCQHPAXgBAAIQFcQAhAC/gEQAQAI8A8ACAAI/g8gCCAIIAhCVwACEAL/AZAEAAb+ATIM0gISA5ICcgQCCEdXAAIQAv4BEAEwAAwCKgEoCagICAz4AwAASlcQAhAC/gEQCQAMCAL4AUoISAhICMgHCABOVwACEAL+ARABQAg0CAoG6AEIAkgEOAgAAE9XAAIQAv4BEAFEAUQAJAD8DwQAJADEAIAAUFcgCJAIjgiwCIAI/g+gCJAIjgiQCCAIAABRVwACEAL+ARABAAzoAyoAKgDoBwgICAYAAFdXAAIQAf4BkACACAgESAP+AMgBSAJ4BEAIWlcACD4IAAkACX4JRg8qCRIJKgkmCUAIAABbVwACEAL+ARABAAQkBqQFZAQkBKQFJA4ACF1XAAIQAv4BEAEACP4JAgQCAvoBAgQCBP4JXlcQAhAC/gMQAQAC/AKEAoYCpgqkCJwHAABfVwACEAL+ARABgAkIBHgEigOMAngECAgIBGBXAAR+BQIFPgUCBaAHMAUOBRAFIAVABAAAYVcAAhAC/gMQCQAM+APICX4GSAbICVgIAABkVxAC/gEQAQAA/AMkASQB/w8kASQB/AMAAGZXgAAQAf4AkAAABP4EkgSSBJIEkgT+BAAEalcAABAC/gMQAQIAugCCAP4PggCyAIoAAABvVwAEEAL+AxACQAlECCQI/AskCEQIhAgAAHdXAAIQAv4DEAEEAPQDFAH0CQQI/AcEAAAAglcAAEACVAr0C1QKVAr8D1QK8gtSCkAAAACDVwACEAL+ARABAAQoBMgFCgQIB+gECAQAAIRXiAiICmgKGApMCkgPeAqsCqwKiApICAAAi1cAAEAEygQ+BAoFfgUKBwAFHgVABX4EAASSV0AIaAlICWwJCgkID2gJTAlICSgJQAgAAJtXAAQQBP4DEAIACKAEngLCD4IBvgKgBKAIolcAAhAC/gEQAQAO/AGUD1QEVARSBNIPEACjVwACEAL+AxAJBAj0C1QKVApUClQK9AsECKZXAAAACP4KqgoqCioPagqqCqoK3gqACoAIq1ckBJQF/gUUBQAF1Ac0BR4FBAV8BIAEQACuVwAEEAL8AxACgACoArgDrAqoCpgKqAaoAMJXAAIQAv4DEAkACfwHrAasBfwIrAisCPwAw1cABBAC/gMQAUAIKAkuBegDLAUsCSAJAADLVwACEAL+ARABAAh8CVQJVAn8D1QJVAl8Cc5XAAAQAv4BAAz4AygAKArICX4EiAduCAgG1FcAAhAC/gEQAQAA6A+oAqgC/g+oAqoK6gffVwAAEAL+ARABQACoAugKCAR+AogFaggMBuBXAAIQAv4BEAEAAvwCtAK2D7QCtAL8AgAC91cAAJQC1AKeD/QCEAhIBv4BCAEIAPgHAAz5VwABEAL+AQABJACkB7QEpgSkBLwErAckAPpXAABIAUgF/AR4BXgHeAV4BfwESAVIAQAA/FcAAhAB/gEQAQAAtAe0Aq4LNgg0CPQPNAAAWAAACAH/AAAG/wEFDnUERQT1B0UEdwcAAAJYAAA4CAoK7AqoCq4PqAqoCuwKCgo4CAAABVgABH4FVgV2BVYFXgcABUoFMgU6BUYEQAAGWBACEAH+AYAAMAD8D6oEqAT+B6gEqAQAABVYAAj+CgoKdgoACnwPPgo8CrwK/AoECAAAIVgQABAEfgUABV4FOgcaBXoFOgVeBVAEAAAkWBAEEAT+AxAKgAi+BqoEqg+qCqoKvgqACCpYAAAQBP4DEAMED/4JVAtUC1QJ/g0ECQAAL1gAAJgJnAl8BVwDDgFcAVwHfAlcCVgFAAAwWAACEAH+ARAA/A8EBPwGfAd8BfwFfARAADFYAABUAXQB3gd0AQAA/g9iCLIEMgPuDAAENFgAAggC/gEIAEAJ/gVqA2oFagNqCX4HAAA1WAACEAH+ARAB1ABUAN4HdAVQBVgF1gcQADpYAAEIAf4AgAm+BKoE6gM+ACoA6g++AQABQVgACEAJfgtqCyoKPg8qCqoKagt+C0AJAABKWAAEEAL+AxABAAF8CFYH1QD8B1QIVAt8C0xYCAEIAf8BCAFAAN8BVQXVB5UBVQnfDwAAUVgAAGgIzAp4CkwKKA+ACnwKVApUCvwIAABUWAACEAL+ARABRAAkByYFVAVUBSYFJAdEAFdY2ggCCooKqAosCqwOqgr6CiwKrAqoCAgAWFgAAggB/wEIAQAG/AEcBl0F+gVcBXwHFABaWAACEAL+AZAFBgWqAnoKigk6BsoAJgcAAF5YAACECrQKtAn0CrQKtg70CrQJtAqECgAAaVgAARAB/gEQBTgE9gfUB9QE1Af0BIQHAARrWAAEEAL+AxABAAj8C7wKvgK8CvwLBAoAAHVYAAAADP4H6gT+BWoFawd+BeoF6gX6BAAAflhECHwJfAv+C3wKAA+ICmgKHgr4CAAJwAiDWAACCAL/AYgICAj6BV4DWwFeD/oJCAQAAIVYAAh+C2oL/gtqC34PEAqSCvoKFgpyCAAAilgAAKwIrAruC7wKiA/oCjwKSAr4CAAJwAiTWAABRAX8BH4FfAV8BXwHfAV+BPwERAUAAZdYAAIQAv4BAAF8ANcP1Ar8CtQK1wr8DwAAmVgAABAD/gGQAAQA7AfkB/4G5AZsBeQHAACcWAAAfgSKBnYGAAZWBzwFtAX0BRYFZASAAJ5YAAAQA/8BgAA8AOYPdAV8BWQF5w88AAAAqFgABCAEfgU6BXoFPgd6BT4FOgV+BSAEAACpWBAE/gMQA3AC2grcD/gDAAr+BIgDeAwAAK5YAAD+CAIKfgoACvYPOwp+Cn4K3gp+CAgIs1gAAhAC/gEQAQQI1AfcB94D1APUB9QLEAjBWEAAfgRqBWoFagVuBzQFPAV2BTQFPAUABMdYAAAQAf4BAAF8BMwH/Af+B/wHzAd8BAQEylgAABAC/gEAA/QK1A70Cd4F9ALUBvQIAAjTWAAM/gPKAf4G/ga+B8IHEgf6BvIGtAQAAdVYAAAQAv4BEABEBbwGvAO+C7wHvAHkBgAE2FgABHAFfgV+BX4FfgcuBX4FfgV+BXAEAADeWAAAEAL+AQAAXAKsDjwJbgk8AuwG/AgAAOJYAAAQBPwDAAj8BwQA9A5kCAQO9AqkCgAA5FgAABAC/gEABXwE7A3+C8YB/AfsBfwJBAHrWCAAIAQgBCAEIAT+ByAEIAQgBCAEIAAAAO5YAAIYAgAB/g8AACAIIAj+DyAIIAggCAAA71iACJ4HkAD+DwAAIAggCCAI/g8gCCAIIAjwWAAABAzUA1QBVAHeAVQBVAFUAdQDBAAAAPJYAAjECFQIVAZUAV4AVABUB1QIVAjEBAAA81gACMQIVAhUBNQD3gDUANQHVAhUCMQIAAT2WAAAxAhUClQIVA9UCF4IVA9UCFQKxAgAAPlYAAA0BLwFfAV8BX4FfAV8B/wF3AUUBAAA+lgAAGQINAu0CvQOPgj0DrQKtAo0C2QIAAD9WJQA3Ab8BvwG/Ab+APwE/AL8CtwP1AKAAARZgAhgCN4ECAPoAhgEAAj+CyAIQAiACAAAB1lAAFAASA+sCrYKpA+0CqwKzArED0AAQAAJWQQKRAo0CYQFpAaeBMQG/AaECZQIJAgAAA1ZAAAICAgKdgneB1wFXAVcBVwLfAkECAAID1kACAQKfAl8BfwHfAV8BXwHfAl8CQQIAAgVWQAAQAAgCBAISAROBIoCCAGIAGgAGAAAABZZQABgCFAEjgKIAWgAEAAgAP4PgAAAAQACGlkAAFAISAlECTQFpgSUBkwCRAHAAEAAAAAcWYQARAD0DwQARAhmBLQDFAOUBHQEFAgAAB9ZIADwAywJ6AkICPgHAACoCJYEVAJMAcAAIFkICagEdgVUAswBEADMAyoB6AkICPgHAAAiWcQAfApsCm4L/AtsBWwFdgNsAXwAxAAAACVZAAj8BNQC/A/UAvwAEAhICdYGtASMA4AAJ1kQCBAEEAIQAdAAPgBQAJABEAIQBBAIAAApWUAIRAhEBEQCRAP8AEQBRAJEBEQIQAgAACpZEAgQBBAEEAPQAj4EUAiQARACEAQQCAAAK1lACEgESARIAkgB/gBIAUgCSARIBEAIAAAtWQAAQAhECEQERAREA/wARANEBEIEQghACC5ZAACACPgIiASIA/4AiAGIBogE+AiACAAAL1mAAEgIyAioBJgDzgCICIgImAgoB0gAiAAxWWAIcAROBEgCyAF+AMgBSAJIBEgEQAgAADRZQARICFIEVAREAsABfgBAAkACQARACAAAN1kAAAQI7ASsBKwC/gGsA6wErAq8CoQJAAA4WQAAKACoAKgCuAOsAqgKqAq4CqgGqAAoADlZAACACIgIqAiIBIgD/gCIA4gEqASICIAIOlkAAKgAqACoAJgGjACKCJgImA+oAKgAqAA+WQgJiAhoBAgECAP8AAgDiARoCIgICAkAAERZSAAoAOgHuAKsAuoHqAqoCrgK6AtICAAAR1kAADQAtAe0ArQCrAKuAywINAj0BzQAIABIWSgEqAyoApgIrAiqB6gAmAKoAqgMKAAAAElZAACgAKwCbAIsArwCrg+sAiwCbAKsAqAAS1lAAEQA5A9UBUwFxgdMBVQFZAXkD0QAQABOWRQEVARMBVwFVgV1B1QFXAVMBVQFFAQAAE9ZkABUCFwFfAVcA94BXANcBXwFXAlcCJAAUVkAAFQJVAl+CVQFQANCAyIFHglCCT4JAABUWSABJAkUBawDJAEmAXUBJAGMDxQBJAEgAVVZJAlUCUQJJAUcBQYDBgF8BQQFFAUkCQAIVlkgCSQJEAl+CQAFSANEAyYFJAkcCQQJAABXWSAAJAEUBfwHdAV2BXQFdAV8BRQNJAkgAFpZAAmECawFZAW0A6oBYgNSA0IFSgUACQAAYFkAAAQF/AXuBe4F3APcA+4F7gX8BQQFAABiWSgBKgGqAK4P6gq7CqoKugqmCqYPKgAqAGVZAAAACXwJDAVkBXYDJANMBQQFfAkACQAAZ1kACXwJBAVsBWwFLAN+ASwDLAOEBfwFAAloWQAALgkgCX4FAAUkA5IBFgORBf0FFQkQCWpZAABUATQB/AP0B/YB9AX0BfQD/AGUARQBblkAABoAmg/+Cv4K+w/6CvoK/gr6D0oAAABzWQAAEAgQCdAIMAkeBRICEAKQBXAEEAgQCHRZiAj4BA4DyAE4CAAMNATEA8QCPAQACAAAdlkICPgMDgOIA3AIBAf8AAQEPAgkCOAHAAB4WQAA+AgOBYgDeAwAAEQARAD8D0QARABAAHlZAAj4DA4DiAF4BgAA/AcQCP4JCAj4CAAGfVkACOgMHgOIA3gEAABECEQI9A9MAEQAQACCWQAACAj4CA4F6AMQAPwPBAQEBAQE/A8AAINZAAj4CA4FiAN4BAAAxAdECEQIRAj8CAAGhFmACIQIvAqkC6QKpgSkBKQHpAikCIQIAACGWQAAGAOAAP4PAACQCHAJHgYQA/AEEAgQCIdZCAj4BA4DiAF4AAAERAREBEQERAT8DwAAiFkACPgMDgPoAhgEcAFEAUQJZAlcDMADAACSWQAI+AwOA+gDGAzwA0gASgBKAEgA+AAAAJNZCAj4BI4CyAE4AgAIaASoBT4CqAVoBAgIllkABPwEBwPEAjwAAAwiAqIBfgChASECIASZWQAA6AieBsgBOAIACDwEgAT+AgACjAEwAJ5ZEAjwBA4DiAN4AAgI4A9cCEQI/A9ACAAApVkAAEQIVAbEB2QGbAJEAmIF8gRKBEAIAACoWQgA+AkOBYgDcAQAAAgP+ABOCEgIyAcIAK5ZAAj4DA8D+AgADP4DEgDSB5IIkgheCAAGs1kAANAIPgUQA/gEAADUAwoI+A8IANgBCAK5WQAI+AgOBYgDeAAADEgCSAH+D0gBSAJIBLtZFAlcCVwLXAvcBX4FXAVcB1wFfAkUCQAAxlkACPgJDAb4BQAA/AdEBFQFVAxEDPwHQATJWQAA6AgfB8gBOAbAASQAJAD+DyQA5AMAAMpZCAj4CA4H6AEQBngARA/EAP4PRADEBwAAy1kAAOgNHgOIAXgCAACwD64EoASsBDAHQADQWQAA+AkOBugDEAj8DyQJJAkkCfwPAAgAANFZAAD4DA4DiAN4BAAAkA+QBP4EkASQDwAA01kAAOgIHgXIAzgAIAicCJAI/g+QCJAIAAjUWagIrAisC5wKzAb8BIwCmgWqBKoIqAgAANpZAAj4BA4D8AgMCYAE/gMAAP4HQAicCIQG3FmgCKwIrQquC6wGvASsBq4FrQSsCKQIAADlWRAI8AQeA5ADeAQAAagHfgkoCTgJKAUkAOhZAAj4DI4DcAQEAOwMrAL+AawCrAS8CQAI61kAAPQMjwLkARgA/g+SBJIEngeSBPIEAATsWQAI+AQPA+gBEAD+BwIE8gSeB5IE8gQCBPtZAAD4DA8D6AEQAv4PAgXiBLoFAgT+DwAA/1kAAKIIlArUC8AGpgSUBIwGlAWkCKwIAAABWgAO+AEIBNgFeALYAwgI/gQIA8oEKggABgNaAAj4CA4H+AQAACQJJAm+DyQJJAkgCQAABFrICMgIrgqYC9gG/gSYBpwFqgTqCMgIAAAHWgAI+AQOA8gBOAZQADQPHAAUADIPUgCAABhaAAj4BA4D+AYAAPwPVARWBNQBVAO8BIAEG1oAAPANHgP4AAQIcAlcB+QBZAN8BcAJAAkcWgAA+AyOA3gIAgb+AZII/gf8DwIA/gMAAB9aCAj4CA4F6AMYAMAPvAK0ArQKtAr8DwAAJVoACPgMDgP4AgAKlAj8DxIE/gKQBVYIAAYpWgAI+AgOBcgDOAj4CJQElgP0D5wI8AgABDFaCAj4CAwFiANwCAwJVAfUAVQDVAVcCQAJNFoAAPgMDgP4APIPBACgAfoHogACCP4HAAA2WoAIwgj+CtoL/gaiBsgGtAWUBKwIpAgAAEZaSAhqCQoLYAscBUwFXAUuBSwHXAlECQAASVoAAPgMDgP4AAAITAw0A0YA9AcUCPQJAARaWgAA6ASeAsgBMAC+B2oFagVOBZoHKQAoAGZaAADoCJwGyAEwBoQDvAD8D7wAvASgAwAAdFpAAF4JQgkyC44F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TAVEBQwJAAC/W4AATADkBxQABADWB1QFdAVUBVQF1AcAAMJbAABMA0QI9A9UAEYLFAh0BJQD1AQ0CAAIxFsAAIwAxAfUBbQFtgW0B9QA1AjED4wAAADFWwAIDAjkC7QGtAb2A7QCtAa0BuQLDAgAAMZbAAAMAaQHhATkBE4HpASUBEQEFA9kAAAAx1tACFQE1ANUANQHVggECHQLVAvUCFQIAATMWwAADACEB/wF3AXeB9wF3AX8BYQHDAAAANJbAACMBLwCvAH8BL4IvAr8CLwJvAKMBAAA01sAAIQP9AD0AvQC9gP0AvQC9Ab0BIQHAADbWwAIDAjEC9QL9AfWA9QD9AfUC8QLDAgAAN1bAAAsAQQB/APECX4IfAt8BXwFfAvMCQAI3lsAAAwK5Ar0CvQG9gP0AvQG9ArkCgwKAADfWwAATAlkBbQB9AmGD5QBpAPUAzQFnAgAAOFbAACMAIQF/AX8A/wD/gH8BfwH/AGMAoAA4lsACWwHRAH0DwQA9gn0C/QF9Af0CKwJAADlWwABXAlcCbwKnAt+B0QGvAR8BXwBDAEAAOZbAAAUCNQH/Af8A/4D/AP8B/wH3AcUCAAA51sAAAwBxANUA9QLagvsD2QDRAPUAwwDAADoW4AEtAK0CrQL9AK2DrQC9Aq0C7QKhAIAAOlbAAFMAWQP9AtUC3YPVAtUC/QLVA9EAQAB61sAAAQB9AT0AvQA5gLEAfQA9AX0BIQDAADsWwAIDAjEC9QH1AfWA8QD1AfUC8QPDAgAAO5bAACMCEQI1AP0CtYO1AL0AtQLRAiMCAAA9VsAAFQI9AfUAfQK1AcGAPQHdAt0C3QOAAT2WwAEFgjWB94H1gPHA+4D7gP+B+4HLggAAPhbAAAIACgAaACIAQgICAgICP8HCAAIAAgA+VsACCQMRAKEAXwCAALQABAJEAj/BxAAAAD6W6AAqACoAKgGqAS8AKgIqAjoB6gAqACgAPtbAAAAAUQBVANUA1QBVAlUCVQHfAEAAQAB/FsAAAABPAFUA1QFVAFUCVQJVAdcAUABAAH+WwAIKAxIAo4BaAYIBFAA0AEQCP4PEAAAAP9bQAREBVQDVAH0BV4BVAlUCdQHVAFEAQAAAVwAAKQEpAS/B6QEpAQAANAJEAj+BxAAAAACXAAAAgF+AVYFVgF/CVYJVgnWB34BAgEAAARcgAT+BKoC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/g8QAP4GkAVWDAAA6lwAAPgDAAL+AwAC+AfAAKYPkgiwCMYPiADtXPgDAAL+AwAC+AMAAO4PoAK+AqAK7AcAAPBcAAD4B/8HAAT8BwAAJAVXBdoPVgVSBRAE9lwAAAAO/ARcBVwHXgVcBVwFXAFcCUAHAAD7XAAA+AP+A/gDAAAoBYwFygKIAi4FaAQAAANdAADwA/4D8AMAAFQDxAD+B8QAVAFEAgAAB10ACXwFGAFYCVgJXA9YAVgBWAUYBXwJAAAOXfgHAAL+AwAC+AMAALQDrAKuCzQI9AcgABRdQAAsAOgPWAVYBV4F+AdYBVgFWAVcBQAEFl0ADP4DDAisCqwKrgrsDqwKrAqsCq4KCAgXXQAAAAD2DxQAVAZ2BtYHdAZ0BhQI9gcAACldAAAMDOwDqAnoDw4ACAjoB6gCqArsBwAALV0IAWsBWgHKB0oBSwECDPoDSgDGD0cAAABKXQAA8AP8A/ADDADsBgwB/A8MAWwCqgQABEtd/AMAAv4DAALwBf4Dyg+qCq4KqgruDwAATF0gAOwPKAUoBegPDgDIDCgCqAEoBqwIYABQXQAA5g8cANwJXAn+D1wNXA2MCPwHBggABmldEACWD/QA9AD0B/QF9gX0BfQH9AiWDxAAi10AAAAA8Af+A/AJ/ARcDV4DXAtcCUAHAAC6XSAAkwCqAqoEsgcHAP4FrgWuAa4F/wUACM1dIAl8C3gFeAV4Cw4A+ATYA/gD3AbQBvAC3V0ACAAM/AMAAAAAAAD4BwAAAAAAAPwPAADeXQAAcAgABv4BIAAAAP4HAABwAAAA/g8AAOFdAAhECMgHAAT4CAQLcAiMCSAK2AgECwAI4l0AAAAF+wWoA6oD/Q+oAaoDrgX9BQAFAADjXQAAAAn+BagFqgP8D6gBqAOsBfoFAAkAAOVdAAQEBAQEBAQEBPwHBAQEBAQEBAQABAAA5l0AAAgMCAPICHwISghICMgPSAhICEgICAjnXQQCBAL8AwQBAAEEAHwERAhECEQMxAMAAOhdAAAAAP4PkgSSBJIEkgSSBJIE8gUCBAAA6V0EAgQC/AEECQAE/AMEAHQABAD8DwAIAAbrXQAFhAR0BIQEBAT8BwQFhAR0BIQEBAUAAO5dgAioBKoDrgioCfgJqA+uCaoJqAmACAAA8V0AAAAA5AckCCQIJAgkCCQIJAh8CAAHAAHyXQAA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dAbUBQYIVAr0C1QKVAoAALVeAAz8AwQAVAD0B9YC1AfUCtQK9AtUCFQEtl4ADvwBBAQkByQA9A6mAKQO9AAkAiQMAAC3XgAG/gECBKoCqguqCPsHqgKqBvoFIgkAALheAA78AQQA9A/0A/QD9g/0A/QL9AukDwQAwV4ADPwDBAj8B6wGrAL+CwQA9AsECPQHAADDXgAM/AMECEwF/ANOAUQB3AdsCWQJFAUAAMleAAz8AwQIdAV0A/QPdgH0D3QD9AVUCAAAyl4ADPwDBAj0D7QItAb2DAQA/A8MAPwHAADTXgAM/AMEAPQLvAu8D/YDBAD8DwwE/AMAANZeAAT+A4IAlgiOBmYHvwZiBW4FRgKeAIIA314AB/wABAL0A7QDtAe2A/YHBAb8AawE/APgXgAM/AMMAOQPvAKmC+4PRAj0BSQD5AwAAOJeAAz8A0QALAusCn4ERANsBfQHtAkUAAAA414ABv4BAgjqBfoF+wX7AfoB+gPqA+oFIgTzXgAAgA98AAQLfA/+DyQEdA10CXQDdAUAAPZeBAi0BKwDZAQABfQJBAkECfwJJAkiCSAJ916ECDQHrAVECAAKJAokCvwLJAoiCiAKAAD6XgIIcgwuA+IECAWqCaoJ/wuqCaoJvgkICf9eAAAQABAA/g8QBBAEEAQQBP4PEAAQAAAAAF9ACEQIRAb8AUQARABEAEQA/A9EAEQAQAABX5AIkAiQBMwDiwCIAIgAigDqD4wAiACQAAJfAAAACR4FqgMqASoBKgEqAaoPLgEgAQABA18ECSQJJAW0AywBJgEkASwBvA8kAUQBBAEEX0AJVAlUBVQDVAF8AVQBVAFUD1QBVAFAAQpfAAl6CTgFPgN4AXoBEAEsAbYPNAFMAQQBD18ICEgESATIB0gESAQIAn4AiAMKBAoICAYTXwAAAADyAJIAkgCSAJIIkgiSCJ4HgAAAABVfAADEAKQIpAikCLwHAAAAAAAA/A8AAAAAF18AAIgI6AioBvwBqACoAPwPqACoBLgDAAAYXwAB5AikCKQIvAcAAAAH+AQEBIAEAAcACBtf8giSCB4HQAD8ByAIEAj/CRAICAn4CAAGH18AAAAEyASqAqwCqAH4D6gArASqBLgDAAAgXwAA8giSCJ4HAABACP4PQATQBEgBRgZACCVfBAHkCKQIvAigBxADzAgICPgPCADIAAgD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iAAACqIJcgQqA+YIIg7gAQAAbWKIAIgI/weIAEAIAghCDv4JQghCDv4JAAhuYggBiAj+D4gAIAhQBE4DwABCCE4I8AdgAG9imACYCP4PWAAACPgPAAgACP8PIAggCCAIcGKIAIgI/g+IAEAIEATQAz4AkAcWCBAIEAZxYogAiAj+D0gAAAf8AMQEBAU8A5AEcAgAAHNiiACIDP4DiAgADvwBZASkBSQCpAVkCAAIdmKAAIgI/g9IAAAISARIA/4ASANIBEgIAAB5YogAiAj+D4gAAAD+DyAEAAD+ByAIGAgQBnxiAAGIDPwDiAgADPwDBAD0BxQIFAn0CAAEfmKIAIgI/g9IAAAIEAQ+AtADEgXUCBQIEAZ/YgAAEAQQA/QABAqkCvQHrAIMAuQAIAMQBIBiiACICP4PSAAACGgEqAU+AigF6AQoCAAAhGKIAIgI/g9IAAAIeAgABP4EAAKMAVAAAACKYoAAiAj+B0gAAAD8B0QIRAh8CEQIRAj8CJFigACICP4HAAD8BwICAgD8DwQABAT8AwAAkmKIAIgI/w9IAAAAIggqCOoPNgCmAGIAAACTYoAAiAj+D0gAAA78AQQA/A8CAP4AAg8ACJViiACICP4HSAAACN4EQgVCAt4FUAgICAAAlmKIAIgI/g9IAEgAAAEiAUwBAAH+D4AAgACXYgAAiACICP4HSAAADOgDLgAoAOgHCAgABphiiACICP4HSAAADv4BIgAiACIA4g8iACIAmmKAAIgI/g9IAEAIBASkA3wA5AckCCQIIASbYgAAiAj+B0gAAA//APgHAAn4CA4K+AkABJxiiACICP4PSAAADIgDfgioBSgC6AUoCAgInmIICYgI/g+IAAAM/ANEAEQAxAFEAnwMAAigYogAiAj+D0gAAAD8DwQIFAvkCLQJBAoACKFigACICP4PSAAAANgHhAiCCEQICAgwBiAAomKIAIgI/g9IAEAAEADIBycIJQnICBAGEACkYogAiAj+B0gAAAz4A0gASgBKAEgA+AAAAKViiAiICP4PSAAAAP4PIgDyDDIDMgXuBAAIq2IIAYgM/gOICAAO+AHIBX4GSAXIBFgIAACsYoAAiAj+D0gAAACwD6wEogSgBKQEmA8gALFikACQCPwHUAAAALAHrgioCOgJCAn4CAAGtWKIAIgI/g9IAAAA/A8kBCIAPgziByIIIAa5YogAiAj+D4gAQAQIAkgB/g/IAEgDSAQAALxigACICP4HiAAAAPwBpACkAPwPpACkAPwBvWKIAIgI/gcIAOAPkASQBP4HkASQBPAPAADCYgAAkAj8B0AA6AyoAv4BqAD+D6gAuAcAAMRiiACICP4PiAAIAIAIiAiKCPoPiAiICAgIxWKIAIgI/g9IAAAI/AkkCSQJJAkkCfwJAAjGYogAiAj+B4gAAAz8AyIAogDiDyIBIgIAAMdigACICP4HSAAAAP4DIgKqCiIKIgb+AyACyWKAAIgI/g9IAAAEKATIBQoECAfoBAgEAADLYgAAiAj+B0gAAA/+AMgHAAn+CggK+AkABMxiCAGICP4HiAACACwBIAH+DyABLAEiAQAAzWIIAYgI/geIAAAA+A+IBI4EigSIBPgPAADQYogAiAj8B0gAAAi8BKQCpAGkCKQIvAcAANJiiABICP8PSAAAAP4PkgSSBJIEkgTyBAIE02KIAIgI/g9IAAgBgADkD1wERAREBMQPAADUYogAiAj+D0gAAAyIA34IqAUqAqoFaggICNZigACICP4HiAAgAJAAzgdICOgLSAjoCwgI12IAAIgI/g8AADgD5gIwCxAF8AMeCPAHAADYYoAAiAj+D0AAEADIAy4BKAHoCQgI+AcAANligACICP4HSAAAALwHIAT+ByAEIAS8DwAA2mIAARgJ/geYAAAImATUA5IAkADUD5gAoADbYoAAiAj/B0gAAACiD5oEhgSiBKIEngcAANxiAACUDJQC/AGSAAMAKAEqAf4PKgEqAQAB3WKIAIgI/gdIAEABFAFUAfwPVAFUAQQBAADfYoAAiAj+D0gAAAT+AwABvAwAAsABPgEADuBigABICP4HYAD+DIgDcAT8CQQI/AsACoAJ4WKIAIgI/g9IAAAO+AEIBIgHbgQIBQgFCA7iYoAAiAj/D4gAAA6QAX4MEATyB5QIVAgQBONigACQCPwHkAAABOgCuAqsCOgPiACIAggE5WKAAIgI/gdIAAAM/gOSAJIA/g+SAJII/gfmYoAAiAj+B4gAAASSBJYEkASYBJYEEAQAAOdiCAGICP4PiACAABgASAhICMoPSABYAAAA6GKAAIgI/geIAAACHAnQBH4FUALUBVQIEAjpYogAiAj+D0gAAAKkApwC1A+cAqQCJAIAAOxigABICP4PSAAAAJIPkgj+CJIIkgiRDxAA7WKAAIgI/g9IAAAEUATQBxAE/AEQBhQMAADvYoAAiAj/D0gAAAnSCCIK+gsmCNIIEgkAAPFigACICP4PSAAACIgE/gKIAIgA/gKIBIAI82KgAKgCagJsC3gL7gcoAygDbgKoAqAAAAD0YgABiAj+B4gAIAgYCSQJ4g8kCQgJMAgAAPdiAAEQCfwHkAAAACgBqAP8CqgKuAqoBiQA/GIAAQgJ/gfIAAAIiQT6A4gAiAD8D4sAgAD+YogAiAj+B0gAAACYD4QEogSiBKQEiAcwAP9iCAHIAfgB/AX6BfoD+gH8AfgB+AGIAQgBAWOQAJAI/AdQAAAAqAKoArwIqAjoB6gAIAACY4AAiAj+D0gAAAgkCSQJvg8kCSQJIAkAAAdjiABICP4PSAAAAN4HZAVkBWQFYgXiBxgACWMIAQgN/gMICEAIXAjEBXcGRAPEBFwIAAAOYwABEAn8B9AAAACoArgDrAqoCrgKqAagABFjgACICP4PSAAACYgE/gMAAP4HQAicCIQGFmOAAEgI/g9AAAQAVARUC0YJ1AhUCAQGAAAZY4gCSgIsArgKqgrsB6gCiAI+AkoCSAIAABpjAAAUAtQD/gOUC4AHtAOeA4QDPANAAyACH2MAAQgJ/gfIAAAIqAiIBv4BiAOoBIgIAAAgYwAAiAj+B0gAAAikBKYDvAC0D8wIrAiABCFjiAGICP4HSAAABC4FIAU+BSAFKAXmDwAAI2OAAIgI/g9IABAAWAlWCfQHXAFUAfABQAAkYwAAiAj+B0gAAAhEBEwDNgAkAFwPRABEACVjAACICP8HAACWAtICsgKaAtIPkgKWAgACKGOAAIgI/gdIAEAJLAUrA+gDKgMuBSgJAAgqYwAAiAz/AwAIkgb+AZII/gf8DwIA/gMAACtjgACICP4HSAAgCBwJYAn+DyAJHAkgCUAAL2OAAIgM/wOICAAO/gHCD1IE0gVSAVIOAAg6YwAAiAj/D0gAAgw+A+IEAAgiCf4JIgkiCT1jgACICP4HQAAQCPgIlASWAvQBnAeUCPAIQmNIAEgI/g8oACAAqge+BKoEqgS6BKIHIgBFY4AAiAj8B0gA4A+kArQC9A+sAqwK5AcAAEZjgACICP8HAAD+DwIEUgT6BVIEAgT+DwAASWOAAIgI/g9IAAAMvAMkBOQPpAikCLwIAAhMYwAAiAz+AwAIvAakAbwIAAf4AQAI/gcAAE1jiACICP4PSAAAAX4BagFqAeoPagF+AQABTmMIAQgJ/geIAAAA4g+sAqACvAKgCuwPAABPY4gASAj+D0gAAAS+BKoEqgeqBKoEvgQABFBjiACICP4HSAAAAO4PqgKqAqoKqgruDwAAVWMIAYgI/geIAAAA6A+oAqgC/g+oAqwK7AdcY4gASAz+AwAIvASsBawG/gSsBqwFvAgABF5jgACICP4PSAAACJQElgLUAZQIlgw0AwAAX2OAAIgI/gdIAAAI4AkuBCoCqgEqBC4I4AthY4AAiAj+D4gAIASYBSQEogUkBAgH0AQAAGJjiAz+A0AIEAj4BJQClgH0AZwClAT0BIAIY2MAAQgJ/geIAAAG/ASEBpYEhAa8CIAHAABnY4AASAj/B0gAAABqAr4Cqw+qAuoCqgIAAGhjiACICP4HSAAQAEwHUgV6BVIFRAVIB1AAbmNAAEgI/g9IAAAH/gAyB7IE8gSyBL4HAAByYwABEAn8D5AABALUB3AJXA1QDVQO1AhAA3ZjAACICP4HCABACfQJVAn8D1QJ8glQAQAAd2OAAIgM/wNICAIIqgaqBKoE/w+qCvoKIgh6YwABEAn8BxAAQAQoARgJTA9YASgBSA1AAHtjgACICP4PSABABwgAJAcqCCIJZAgoAwgEgGMAAIgI/gcAAPwPFAD0DwAAFA7qAQgGOAiCY8AARAb/AQAM/gMCAIIPggT7BJIEkg8CAINjgABECP8HBABgALUHtQD1D7UAvwTgAwAAiGOAAIgI/gfIAGAIaAikBKoHogS6BmoFAAiJY4gI/gdIAAAC+AKoAqgCrg+sAqwC/AIEAoxjAAAcAs0C/wL8Cv4H/AL8Av8CjQKcAgAAj2MAAQgJ/gcYAIwCqgLoA6gCqAqICPgHAACQY4gAiAj+D0gAAADQD0gFBgVEBFwFxA8AAJJjiACICP4PSABAAAgBKAHWDvwHKAEoAQAAlmMAAIgI/geIAAAA5A8UAMYIdAWkA+QEJAiYY4AAiAj+BwAA/g8KAOoOigjqD4oI7g4AAJljAAEICf4HiAAAAqwKpArqB6ICqgLqA4AAm2OAAJAI/AcAACgFvgcoBQAA/A9AAMAAAACgY4AAiAj+D4gAAAT0ApQIlgeUAJQC9AIEBKFjgACICP4HSAAABJQChAHUD4IBsgKKBAAAomMAAQgJ/gfAAAwEpAKUAcQPlAGkAqwEAAClY4AAiAj+B0gAAAikCqwLpgSkBrQFpAigAKdjAAGICP4PSAAMCKQIlAiGD5QIpAgMCAAAqGNIAEgI/g9AADAA/A+qBKgE/geoBKgEAASpY4AAkAj8B1AAAADoA7gCrALqB6gKuAroC6pjiABICP4PSAAAANQHXgVUBVQFXgXUBwAAsGMAAJQI/AeyADgG5gH8AxAIkgj+B5IAgACyYwgBCAn+BwgAAAG+A+oFqgSqAqoIvgcAALdjAACICP4HSAACDvgBTgcAAP4PAgD+AwAAuGMAARgJ/geYAAAC8ANSA1QD8A9cA1ID8AO6YwAAiAj+B0gAQABYCrwKWgkYBTwEWAKQAMljgACICPwHSAAACXQFHANcD3wDFAU0CRAAzWOAAEgI/g8oAAAIXAl8BdwDXgF8BVwFXAjPY0AARAT/AyQAAAD0D5QElwT0B5QElwT0D9BjAAEICf4HiAAADL4CqgSqD6oKqgq+CoAI0mMAAEQE/wNEAAAA6g+qBAoE/gcJBOkPAADWY4gAiAj+B0gAAATsB2wFbAVsBWwF7A8gAtpjBAGEDP8HxAAABt8DVQlVBVUDVQlfBwAA22OAAIgI/geIAAgIeAk2BZQDPANQBXAJAAjhYwAAkA78AQAM/AM0CLQK9Aq0D7QKvAoACONjAACICP4HQAAcD7AAsA/+ALAPsAC8DwAA6WOAAIgI/g9IAAAA/gdoBUAFfgVoBeQHFADqY0AAiAj+B0AAEgH+D0IAGgwAA/4AAAM4DO1jAAEICf4HiAAAAP4G6gSqBaoIqgi+BwAA7mMgAEgI/gdIAAAC+gK6AroC+g+6AroC+gL0Y4AAiAj+D4gAAgRWAvIJ1gbSBNkHVQhACPpjiACICP4HSADAAIwOpASsBOwHogSyBKoO/WMAAIgM/wNACB4IwAteCEAHVgjUCwQIAAQAZIAAiAj+B0AAEAC4BHYENAV8CbQKsACAAAFkAABICP4HAADyD0IAWAeqAtoCAgv+BwAAAmRAAIgI/g9IAAAIqgqYC94EmAaqBaoIgAAFZAAAiAj+B0AAGgj8BTgEugc4CO4JCggABg1kiACICP4PSAAACOwF7APsAewB7AXsCQAID2SAAFAI/AeQAAAAeAN4A3gBfgl4CXwHeAETZIAAiAz+A0gIAAzVA1YIfAlUD1cJVAkAABRkgACICP4HSAAAAKYJWglSCdYPWg1WD9IPFmQAAAgJ/geIAAACVArECqYKng+MCoQKAAAcZIgI/gdIAAAIvAi0CaAG/gSgBrQJvAgACB5kgACECP8HJACAD1oAWgdbBVoHWgDCDwAAKmTAAEgI/gdIAAAH/AB0BnUF9gV0BXQHFAAsZAAAEA78AYAM+AN+CfgHAADeDUICngUgCC1kAACICP4HSABAAG4HVgVcBWQFTgdEAAQANmRAAEgI/A8gAJAPaAB4B3QFcgV0BWgHEAA6ZAABBA3/B4QADAj/BasDqgH/BasDqg6CAERkAACIDPwDKAiABLwGvAG8BbwGvAakCQAARmSAAIgI/gdAABwFVA1cC9QJXAVUBVwJAABHZIAAiAj+B0gAAAasBKQE6geiBKoEqg4AAEpkAABICP4POALIATgBMAD+D6gE/gesBAAEVGQAAIgI/geAAIgCBAK0Au4OxAIEArQCgABYZIAAiAj+BwgA4A8UAFwH9gVcBxQI9AcAAGdkAABICP4PSABMAOgHaAVuBegHaAVsBQAAaWQADPwDBAC0A7QLtguEB7QDtAN0A3QDVAJ4ZIAASAj+D0gAAAl0CXYH9AF0A3YFdAkECXlkAAFEA3wD/AN+C/wL/A9+AvwCfANEAwABg2QAAvwD/AP+C/wLvAfYA9YDUgN2A1QCgAKHZAAAiAf+APAPXgD8B3AA9Ac6BsUBPAYABJBkkACQCPwHkAAYCPwL2AbeBtgC/g+YAgACkWSAAJAI/AcAAJgD/AvYC9wH2AP8AxgDAACSZIgI/gdIABAA9A++ArQK/g8QCO4GiAN4DJVkAACQCPwHAAD8DVgB/AUAAPgPJADkDyQAnmRICP4HWAAACPQK9Ar0CvYP9Ar0CvQKEAikZEAARAz/BwAA8g+/AtoPEAg4BMcDfAwAAKVkAAAICfwHCACgC7wK5A5ACygF/AeoCQAAqWSAAIQE/wNEAAAE+gFWCVMPVgH6ATIMAACrZAABkAj8B1AAAA38ASoB6A0oAegNKAHoDaxkAACICP4HSAACA9YPHgM2AK4DrQcoCwAKrWSAAIgI/gdYANQAVAe8BbwHlAW6BdIHkACuZIAAhA7/AWAE4Ae/BrUG9Q91BHUD/wVgBLBkAACICP4HoABOCfYFVgVAAU4F9gVWBUAJsmRAAEgI/g9IAAIJeAVuA+gBbgN4BWoJAAi1ZAAAiAj+B4gAAARcBd4FQA9cBU4FXAUAALxkAABIB/4AAA78ASwB3AesA38CpAMVBAADv2QAAIgI/gcIAOgMtAL0BBIA8gy0AuQECAjBZEAASAj+BwAAtAxkAwQA+gdUBfwHVAUABMJkAACICP4HCACcB8wFnAW8B5wFzAWYBwAAxWQAAIgI/gdAAHwEzAf8B/4H/AfMB3wEAATHZAAASAj+ByAAvgL6Ar4Cug++AvoCvgIAAMpkQAT8BPwH/gf8DvgPkAfuBqIG5gaoBAgBy2SAAEgI/gdIAAAAmgf8BdgF3gfYBf4FigfNZAAAkAz8AxAIwAW8BfQDlA/0A7wF4AkAAM5kFAA8Ar4DuAPOC7wLhA+oA7YDlAMsA0QC0mQAAYgI/geIAAgOxAGSB9oF8gO0CcQPAADUZIAAiAj+D0gAGA74Aa4MvA/MD7wPyA8AANpkgABICP4PAAT4AxgA2AX+A3wPbAFsBgAE4GQAAIgI/gcIAGAM1APkAr4CvAK8AuwPBADmZAAACA3+AwgJLAmUAdQJvg+0AfQBHA0AAOxkAACICPwHAABeDdQDVAwAAywE9A88CWQI9GSAAIgO/gEADPwDRAj0C/QL9gP0C9QLAAD6ZAAAiAz+A8AIdgfKDO4HCgBuBqoKrgoAAP5kAAGICP4HCADCCH4K3gdeB14H/gvCCgAIAGVUAMwCXgJMA+AL5gvUB8IDSANeAswCVAAPZQAAmAz+AwAI6AdmAvQPAADeB9QL9AoAABJliAj+B0gADAjeC14IXAZMAV4EXgisCyAAFGUAAIgI/gcAAP4H9gR+A/AH7gP2CP4HAAAYZQAAiAj+B0gE+APsD/wJxgH8B+wF/AkAABxlQAAkBP8DIACLD34B+gJ7BvoBegT7ByAAHWUAAJAI/AdQAMQD/AL8DzwA/AP8A+QHIAIkZQAAAABICP4P/gv0B/4O9A+uBPoHqAQAAC9lCAgoBGgEqAQoAz4CKAOoBGgEKAQICAAANmUAAPwDAAEAAf4PAAAwBG4EiAPoAhgECAg5ZQAA5AEkAiQBfAVgDDAEzgIIAegCGAQICDtlBAEEAfwBBAlkCRAEbgKIA4gCeAQICAAAPmUACAgG+AEqCMgHIAAQDO4CiAN4BAgIAAA/ZQQE9AMEAvwDJAJkCDAE7gIIA+gEGAgACEVlCADID0gEfgTID2AIPATKAogDeAQICAAASGUICKgEigKMAygEQAAwDM4CiAN4BAgIAABMZQAAkg+SBP4EkgSCDyAAFAzqAogDeAQICE9lQAD4AVYB9AVUBfQDYAkeBOUCxAM8BAQIUWUIAmgJCAn+D8gACglgCH4EiQPoAhgMAABWZQAEVALUAf4E1ATUA0AAfgaIAWgCGAYABFdlAAj8BVQFVAH8BWAAOAzMAogDeAQICAAAWGVQAlgJVAjyB0QAZAswCO4ECAPoBBgIAAhZZQACVAJUCd4P9AFYCTYIfASLA8gCOAwICFtlAADQBRgE1AQWA4gIMARuAogBeAIIDAAAXWUAAPYP0AH+D9AB9g8ACD4EyQPoBBgIAABeZQAA7g/gAX4CoAnuD0AIfgSIA+gEGAgAAGJlAAAIAvoDqgKqAv4PAAAwDO4CiAN4BAgIY2UAAOoPrwKqAq8KygcgABoMdQLEAzwEBAhmZQgC+ArYCtwO2AN4CmAI/gQIA/gECAgAAGxlRAD0A1YB1AkWDPQDMAhuBogB6AIYDAAIcGWgCKoKmAf+BJgHigggCD4EyQOIAngECAhyZQAA9A/0A/YCdAn0BwAA4Aw+AygD6AwACHRlQABcCDwIvg68CNwP2Aq2CrQKTAhECAAAdWUAAPoPDgP7Ag4J+gcQAD8MxAN8BgQIAAB3ZQAEvwKrAf8FqwW/A5gIPwTCA3ICDgwCBHhlCAl8C3wL/gV8BXwLYAkwBO4DeAQICAAAg2UAAF0JfgX/B1QDXgFoAOYDVgVcBWQFQASHZQAACAgICBgEaASIAgoBiAJoBBgECAgICIllIgQSDNIDVgFaAUsBSgFWAVYB0gcSABIAi2VkAGQPZAFUAVwP1gFUAVwPZAFkCWQHYACMZQgIaASOA3wCAAjUD/QHEAD+AxAEFg4AAI5lJAgkD6QAHAJUCVYPVAEsBSQApA8kAAAAkGWkCKwIrASsBZ4GwAKAAr4GrAWsCKwIoAiRZQAAJAT8AwAIKAbKATgCAAhECPwPRAgACJdlAAIQAiQBJAFIAQgBAAH+DwABgACAAAAAmWUMAKAD/g+gAKwAAAIkAUgBAAH+DwABAAGcZQAEWANUCPIPVAAEAyAAbAEAAf4PgAAAAJ9lQADIA3wF+AT4BXwFAAQoAIAA/weAAAAApGUAAAAO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rAL8BAQEAAB+Z4gBSAD/B0gAgAQ4BIYHYAQBBI4FMAYAAH9nCAOIAP4PiAAADPwDZAikBSQGpAVkCAAAgWeIA0gA/g9IAAAMhAN8CIQFNAIsBeAIAAiEZ4gBSAD+D0gAAACcAWoBCAnICQgM+AMAAIlniANIAP4PSACIAAAIRAhECPwPRAhECEQIkGeIA0gA/w9IAIgAAAz8AyIAIgDiDyIAIACVZ4gDSAD+D2gAgAg4BIgDfgDoBwgIOAgABpdnAACIAUgA/w8oACgCgAFIAP8PaACIAwABmmeIA0gA/w9IAKAIEARuBIgDyAI4BAgIAACcZwAAgAS+BKoCqgGqAf4PqgGqAr4EgAQAAJ1niAFIAP8PSACICCAEqAQoBT4CKAXoBAgInmeAAUgA/wdIAAAH/gAABIADfgCAAwAEAACgZ4gDSAD+D0gAAAEkARwBBgGEDzwBIAEQAaJniANIAP4PSAAAAPwPBAgUC+QItAkECgAIo2cAAAQBtACUBFQEfglUClQKlAq0AAQBAACqZ4gDSAD/D0AAEADIByQIIwkkCcgIEAYQAKtngAFIAP4PKABAD/wABAb0AQQC/AcADAAAr2eIAUgA/g9IAEAAEA+QBP4EkASQBJAHEAC2ZwAApAiUBI4ChAHcD4ABvAKkAqQEvAQABLdngAFIAP4PSAAADv4BCAzwA/wPBAT8DwAAxGeAAUgA/g8oAAAA9A8UAJQBfACUCRQI9AfPZwgBiAD+D0gAAAD4D4gEjgSKBIgE+A8AANBnAACEBIQEvgKsAewHrACsAb4ChASEBAAA0WcIAYgA/g9IAAAA/g+IBIgEiAT+DwgAAADSZwQJZQkRBRIDBAPEDx8DJAMkBSQJFAkAANNniASqBKoCgAKkAbQPjgGEAvwCwATABLAE1GcACVAJVAU0A3wD3A90AxwDFAU0CRAJAADYZ4gBSAD+DygAKAGAAPQPTAREBEQExA8EANxnCAOIAP4PSAAAAPwPJAkkCSQJJAnkCQQI4GcIA4gA/g9IAAAAWABICEoIzA9IAFgAAADlZwAASAgoCKgPWA1cDUgNWA2oDygISAgAAOxnAAAECPQEtAKUAf4PlAG0ApQE9AQECAAA72eIA0gA/g9IAAAA9AMUAfQJBAj8BwQAAADxZwAAiANIAP8PyAAICQAIigj6D4wIiAgICPNngANIAP4PAAD8CQIF+gIAAPwPBAD8AwAA9GegBL4EoAK/AqQBgA+fAaQCpAKkBKIEkAT7ZwAAJAgUCNQPrAquCqQKrArUDxQIJAgAAP9niAFIAP4PSAAAAOgDKAAqAPwPKAAoAugBA2iIAUgA/w9IAAAP/AAUDvQBUghSCNIHAAAEaAAEUARcAlAB0gDUD9AAUAFYAlQCUAQABAVoAAOIAP4PAAT+A0II/gdAAP4HQgD+D0AAB2iIAUgA/g9IAIgEIAKkCSQI5A8kAKQBIAYIaIgBSAD+DygAQAgQBFAEfgTIAyoFqgigBgtokANQAP8PUAAEBnwBRwjkD0QARAMEBAAAD2iIAUgA/g9IAEAEEgSWBJAEmASWBBAEAAARaAADiAD+D0gAAAbkARwDQADQCRAI/gcQABNoiANIAP4PQAAQCAgJJAniDyQJCAkwCAAAFmiIAUgA/g9oAPoPigV+BAoEfgSKBPoPAAAXaAQJdAlUBVQFfAPUD1QBfANUBVQFdAkECSFoiAFIAP8PSAAICGAEGATYAg4ByAIoBEgIKmiIA0gA/g9oAIAEEAROA8gA/g/IAUgCQAQ3aAgBiAD+D0gAAAFKAUoB+A9IAU4BCAEAADhoiAFIAP8PSACICCAEaAWYBE4CKAOoBIgIOWiIA0gA/w9IAAAA/g9SCNIIUgFSBn4FAAk8aMQBJAD/DwQATADkD2cEWwRaBGYE4gdAAD1oEARUAlQB3g9UAVQJEAT+AhAD0gQUCAAGPmhACGQJFAUEBTwDBg9EATwDBAUUBSQJAAhCaIgDSAD+D0gAAAgkCSQJvg8kCSQJIAkAAENogANIAP4PQAAMCYAE/gMAAP4HQAicCAQFRWiIA0gA/g8IACAO+AGWB1QIXArQCRAIAARGaIgDSAD+DygAQAD8DwQIVAr0C1QKVAoACEhoAACUCZQFtAVUA1YPVAF0A5QFlAUUCQAITGgAAAAJeAVYBVgD3g9cAVwDXAV8BQQJAABQaAgDiAD+DwAA/A8EANQDVALUAwQI/AcAAFFokAmYBV4FfgMWAYYPVgFaA1oFsAWACQAAU2jEASQA/w8kAAAE/QUlBSUFJQUlBf0FAQBcaIgDSAD/D0gAyghCCMQFcQZWAkAF3ARCCGNoiANIAP8PSAACBCwFIAU/BSAFKAXmDwAAZWiIAUgA/g8oAIAIVAQ0AxwAFAAyD1IAgABmaIgBSAD+D0gAAAF8AQIBkA8+AUgBRgEkAGhooASUBJACvgKAAagPpgGWApQCjASEBAAAaWjEASQA/wcUAAAO/AEEBCUE9QckBCQEAAB2aIABSAD+BwgA4g9SAVoB+g9WAVIJ8gcAAH9oiAFIAP4HSAAAAX4BagFqAeoHagF+AQABgWhMCWAJEgVYA0IDMg8OAUIDQgU+BQwJMAmFaBABkAD8D5AAoATYA6wCqALoC6gK6AeAAoZoAAOIAP4PSAAACSgN/gMAAPwPBAD8AwAAk2gIA4gA/g9IAAAAVAFEAcYPdAFEAUQBAACXaIgDSAD+DwAA/AisBqwG/AWsCKwI/AgAAJ1oAAAgAPwPAgD4AwAAqAauAJQPtACsAqQEomiEAUQA/g8kAAQA8QdWAVABXgFQBfYHAACmaAAAEgmKBF8ERgVqAkgCSgHfAEYACgAQAKdoiAFIAP4HKAAgAKoHvgSqBKoEugSiBwAAqGhACCoJGgV+BRkDqg8AAR4DQAVABX8JAAmtaIADSAD+D0gAQApYCR4FygaYBp4JqAgACK9oiAFIAP4PSAAABOoErAL4D6gArgS4AwAAsGgAA4gA/w9IAIAM6AOIAOgP/gQIB+oIIASzaIABSAD+D0gAAAy0AywApw8kALQPIAQAALVoAAA0CAwE3gNMAVQBQAJMAN4HDAgUCCQGtmiIA0gA/w9IAAAP/gAKAqoC6gdKCU4JAATAaAgBiAD+D0AAEAUIBSQEogQMBpAFUAQAAMRoRAlUBdQFzAPMAe4PzAHMA8wDzAVUBVQJyWiEA0QA/w8kAEAAngeqAKoA6w+qAL4EgAPLaIgBSAD+D2gAQAkIBf4FWAFYAf4BCA0AAM1okANQAP4PUAAAAPwPVAlUANQHfAkABQAA0miIAUgA/g9IAAAAbAI8Aq4PrAI8AmwCoADVaIQBRAD/D2QATAZEAVQE1wdUAEQBTAIAANhoAAD0DBQC/g8UAfQIYAQUAv4PFAL0DAAA2miAA0gA/g8ABP4Dkgj+BwAM/gOSCP4HAADfaIgBSAD/D0gAAAT8BKwCrAH+D6wBrAL8BOBoAAgYCQoFfAVYA94PWANYA34FCgUYCQAA42gIA4gA/g9IAIAIFAZUAP4PVABUBXwFEAjuaAAApASUAtQPjAKMBD4EjALUD5QBpAKABPFogANIAP4PSABACjQJ1AbeBJQGtAkUCAAA9WgAAMQBJAD/DyQAAAPfAPUH/wfVAF8DQAL6aIgBSAD+B0AAHAD8B/QHVgVUBWQFDAcAAAVpiANIAP4PCAAgALQHrAKuCywI5AcgAAAADWnIACgA/wcIAOAPBAT8BVwFXgVcBfwFBAQOaYgBSAD+DwAAMAD8D6oEqAT+B6gEqAQAABJpgAFIAP4PCAAgDf4DKAiACRwE5AN0BgwIHGmQA1AA/g8QAPAJOAk0BfIDNAM4BfgJEAgtaQAAkAD/DwAA/g8SAO4BAAD4D68C6A8AADBpgANIAP4PAAD8A1QC/A8AAP4PAgD+AwAAP2mAAVAA/AcAAKgA+A94BXgFfAX4D3gAgABKaRADkAD8D5AAAAj8B9QB1AXUA9QJ/AcAAFNpgAFIAP4DAAz+A0IAqgT6B6oEQgT+AwAMVGmAAUgA/g8AACwJfgkMB6ADHgVCCT4JAABaaQAAVAhMBl4DVATAD1QJTAleCUwI1AgACF5pAAOIAP4PQAAcCFQE3ANUAVwJVAlcB0AAY2nAASQA/w8UAIADfwDlD1UFVwVVBfUPBwBtaQgJagVsBXgDbgHoD2gBfgNsBWoFCAkAAHVpiANIAP8PCADiCaII7gj6C0IIkglyCgAAd2mAAUgA/g9IAAAAvA+oCoAKvgqkCqQPFAB8aYABSAD+DygAiAiqCpgH3gSYBqoFqggAAH1pAACkBKQEgAL8AdYH1AH8AYACrASiBAAAgmkAA4gA/g8AAPwHVAJ8CSAExAN8D0QIRASEaQADiAD/D0AAHgjACV4EQANOBtQLBAgABIZpgAFIAP4PCADwB7gC9A8WANYDBAjoBwgAlGkAA4gA/w8AAPwHVgJ8BwAA/A8EAPwDAACVaYgDSAD+DygADAGUD0QJJglECZQPLAMAAJtpgAFIAP4PKACACOwFvAOuD6wDbAUkBQAAnGmIAUgA/g8IAEAIXAbcAVYJVAlUCVQHAACoacQBJAD/DyAAggBKACYA9w+iAqoCqgIAAK5pAATiBOwErgKiAKAPsgCoAqYCqASiBAAAtGkAA4gA/g/IAAAAvA+iCpAKpA+cCoQKvA/LaQAAyAMoAP8PAAD8D74CvAL8A74K/AcQAs1pyAAoAP8HKAAIBugBfAd7BXwFdAV0BwAA0GmAAUgA/g8IAHwAVAhWB/wA1AdUCXwLAAjYaQgDiAD+D4gAAARWBVQA/A9UAlYFVAUAAP1piANIAP4PSAB6ANoP/wraCv8K2gr6DwAAAmrABOwE2gLAArwA1gfWAPwCiAL2BOAEAAAKaiQIFAl/CRQFUAVKAzYBQQM0BX8JFAkkCRFqiAdIAP8PSAGEASYJDA24Dw4BfgUQCQAAE2qAAUgA/g9oAAAIfAt8C/wFfgV8B3wJfAkZaogDSAD/D0gAHAVsAXwJbA98AWwFfAUABR5qAAOQAP4PAAD8BwQJ9ArUC1QJtAqECwAAH2qAAVAA/g9QAAAC9AL8AvYP9AL0AvQCEAIhaoABSAD+D2gAAAl0BXYD9AF0A3YFdAUECSNqhAFEAP8PRAAADSsDqgg+B2oCKwWiDAAAKWo4A7gA/Ae4ACgAgADsB7gHqAeoB6gHAAAqaogBSAD/D0gACAj6CV8FWgX6AV8FWgX6CTFqiANIAP4PAABeCToLjg0cBUIFegtCCV4JOWoAA4gA/w/IAOAItAq+DPQGAASQAP4PEABEagAAyAD+DwgA+gOqAqoC/g94BI4DeAwACEtqkANQAP4PEAAyD7IA8gf+BfIH0QCwDyAAWGqIAUgA/g8oAIAPWgFaB0oF3gZaAMoPAABZasABKAD+ByAA2gS6BboEtQS+B9oFEAQAAF9qiANIAP8PQADmDLgDtArfCKQHuAq0CKAEYWqAAUgA/g9IAAgEuAVsA+4KvAmsB6wBOAJraogBSAD/D0gAEgjyBX8FegX6AX8FcgXyCXFqgANIAP8PAAT8A0QErAdsBwQApAj0ByAAgGoAA4gA/w/IAHgIzAv8C/4L/AvMC/wLAACQaogBSAD/DygAiA98ACcH7gX2BeQF9AcEAJRqiANIAP8PQAAaB/wF2AXeB9gF/gWIBwAAomqAAUgA/g8IANgMuAL0BBYAxAyoAugEAAipagAByAH+B2gAeAXMAfwF/gfMAfwFhAUAAKxqAAOQAP4PAAAUBtQG9gN0C3YHVANUBAAAw2qAAUgA/gcAAP4HAgT+Bf4F/gX+Bf4FEgT7aoADSAD+DwgAfgkuC/4NAAVeBS4LXgkAAARrgAFIAP4PAAD+B+4E5gPwD+YD7gz+BwAACmsIA4gA/g+IATAB1A82D4APNg9UD3QJAAAga0AIMAgMBAoCiAF4AIgBCAJIBDgICAgAACFrAAAEBoQBCAhgCB4ECgPoAAgDSAQ4BAAIImsUBCQCxAE8AwQIMAQOA+gACAMoBBgIAAAjawAE/AMUABQA8gcCADAMDgPoAAgBOAYICCdrAAD8DwQFpATUBAQNYAweB/gACAN4DAgIMmuIAMQPogSQBJIE5AewDA4D+AAIAzgEAAg6awAACAn8BVgB/AUAATAMDgPoAAgDOAwIAD1rUAhYC1QI8gdUDQAIMAQOA+gACAM4BAgIPmsABKoCqgivB6oAogIwCA4G6AEIAzgMCAhHawAB/geqBKoFqgi+BwAAHA7KAQgCOAwAAElrJAStAv4H/AOuAf0EOAwHA+QADAMEBAAATGuAALwHrAW8B4QIvAewCA4G+AEIA3gMAABQawAA/gOCBNoFqgTaBQAMEAPuAAgDKAwYAFNrIAHsD6wHuAeoB+AMYAQcA/ABEALwDAAAYWsAAboPuweAB7sHmgcwAA8O5AEEA3wMAABiawAEAATwBwAEAAQABP4HIAQgBCAEIAQAAGNrAAQEBOQHBAQEBAQE/AdEBEQERAREBAAEZGsACPAPAAgACP4HIAQAAP4HIAggCBAIEAZlayAIIAu8CKAIIAggBP4HJAIkAqQBpAAgAGZrAAAQCNQHFATUB5QEEAT+ABAHFAgUCBAGZ2sACPAHAAT+ByACCApoCKgFPgIoBegECAhpa6AAoAV8CGAIIAUgBf4EJAKkASQApAAgAWprJAikCKQOlAiUCLwIhA+UCpQKpAqkCgAIb2sQANAHHATQBZAF3gWeBbQFFAT0B/AHEAByawgM6AMoAGwL6AdoAi4JfASsA7wEqAgoBnNrEA7QAVAE3ALQD9AAXgn0DFQDdAVUCRAEdGsADPwDBAhUCHQPFAiED1QK9Ao0CtQIAAB3awAM/AMECGwI/A5sCAQPbAr8CmwKpAgAAHhrAAh8B1QE1gc8BUAAPAe8APwPvACoBwAAeWsAAIQARAgkBFQEnAIUAZQAdAAUAAQAAAB7awAAxAhkBJwGFAH0AAQA/AdECCQINAgkBnxrwAAiCJ4EEgPyAAAARABEAP4PQgBCAEAAg2sAAMIIPgSSA3IAAAj4CIgG/gGIBvgIgAiJa8AAIgieBJIDcgAQAM4HqQLoCwgI+AcAAIprgABiCB4GkgFyBBAETgPIAP4PSAFIAkAEi2uAAOIIngSSA3IAAAioBP8EaANlBVUJQASWa0AAYgxeApIBcADkDwQE/AVuBWwF/AUEBJhrgABiCF4GkgFyCAIJqAUvBxgFXQsVC6AItGsAAPwPFAXkBBQNQAzeCEIHQgb+CWAIGAi1awAAAAL8D1ICUgIRCUAI3gVCAl4FoAgYCLdrAAz+A1UJVQk9B0AA4AheB0IG/gVgCAAAumsAAFIGVAHMD1MBAAjeBEIFQgJ+BeAEGAi8awAAbAxsA+4A7AcEAmAI3gRCA14DwAQACL9rAAf/APUOpQD1AqcEAASvAqECLwHoAgAEwGsAAHwJUglAB1QFPA1ACH4JQgb+CWAIAADBawAA/ATSBMAH1AQ8AkAI/gVCAv4FYAgAAMVrAABUATQL1goUB8QCEAjOBUIC3gVQCAAAy2sAACAA4Ak8BSQDpAF8CSQJJAf8ASABAADNawAAIADwAy4CogKqAqoKIgoiDv4DIAIAAM5rAABIAMQHcwJKAsoDegpKCkoO+gNCAkAAz2vAAMgC6AOmApQDlAPUA5QKlAr0B8QCwADSayABIgHqB2oFagX/B2oFag1qDeoHIgUAAdNrEAD4B7YFlAz0BwAAtA8sAKYPJAC0ByAI1GsAAAAA/g8gBCAEAAD+B0AIIAgQCBAHAADVawAAQAF+AUgBKAGADz4BSAFIAUQBJAEAANlrAABACn4L5AdkBVQDXgDkB2QKZAlQCUAE22sAACgBKAEoASQB/AckCaQIkgiSCJAIgAbhayQBJAH8ByQJoggQCMALfgpICkgKyAkIBOtrAADEBPwF7AXsA+4H7AvsCuwKfArECgAA72skASQB/AeSCIIIKApkChAJzgkQCswKAAQPbAAAAAj8ByQEIgQiBH4AogMiBCEIIgggBhFsAAAACPwHpASkBKQE5ASkAaQGvAiACAAGE2wIAPgBCgIIAgAI/g+SCJIE8gGSBp4IAAQUbCAAGABGAFUAVABUAFQAVADUAxQEBAgABBdsAAhYCUYFVAJUAtQF1ARUANQDFAwECAAEG2wQABgJhAUjAyoJKgmqB6oAKgHqAwoMAAYibAgAqAS2Bb4FfAd8BbwFvAUcAPwDBAwABiNsEAAYCUQFIwGqDyoBKgFqDSoA6gcCCAAGJ2wQAMgCxALeAtwP3ALcAtwCHAD8BwQIAAYobAgAUAlYC1YLXAVcB1wJXAkcAPwHBAgABi5sEAiICrYEXANcAlwEXAccCPwBDAYECAAG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AAQRcBAAJA8kAIAFvAT8DrwMvA78ArwEvAmAAh9wEQSmAwAAAgATDLoDOgP4DzoBuwe6A7oPLHAQDKIDhAA2BlQB/gcmAfIEbgVqAfoFAARMcAAAIghEBgQDdA7UDzYPhA92D1QPdA8AAFFwAAAiBqwBAATqA+oH+gXiAeoD+gXqBQAEY3AQACYPQAAXAk0DoAOcA7YL+gtcBxICQABrcAAIYAgYBAACgAF+AIABAAJABDgIAAgAAG1wAAACCEIEMgQCAsIBPgDCAAIDYgISBAAEb3BACHAEAAL+ARACBAAECAQI/AcEAAQAAABwcAQChAF0AA4I5AQkAgQB9AAEAWQCJAwAAHVwAAgACaoIKgQqAqoBKgIqBCoFvggACAAAdnBwBAAO/gEAARgFAAQgBCAE/gcgBCAEIAR4cAAAQAhICigJJAQWAtQBHAIkBKAJIAhACHxweAgABv4BEAEABjAAjgCICAgJCAz4AwAAfXAACAwJ0gQABAgD1gACAwgEDAXSCAAIAAB+cAAAmAiICGgECAIKAewACAMIBMgEGAgAAH9wOAgABv4BAAMIAPAHAAQABP4HAAQABPgPiXBwCAAG/gEAAjgIAgzyA5IAkgCSAPIBAACKcHAAAAz+AwACGAgwBA4C6AEIAygEGAgAAI5wAABACCgJpAQgBBgDxgEYAiAEpAUkCEAIknBAADAO/gEAARgKQAg4BAAE/gIAApgBIACVcDgIAAb+ARACAAjoByoAKgDoBwgICAYAAKtwOAgABv4BAAMIAEgEaAbaBUgEKAcIBAAArHBwCAAE/AMgAgAA/A8kCSQJJAkkCeQJBAitcAAM7AMoCKgJqAQuBqgBKAIoBCgJrAggCK5wcAgABPwDMAYAAPgHLgkoCegLCAr4CQAEs3AYCAAG/gEAAhgA4A8UAJwBfACUCRQI9Ae4cHAIAA7+AQACKAQwAA4A+A8oASgBKAEIALlwAAAADOACoACgBr4ApAKkBKQA5AIEBAAAunAAAYgMigLKALgGrACqAqgIuArgCIAHAAC8cDgIAAb+AQgBEAR0A14I9A9EAEQDRAQAAMFweAgABv4BCAMQADwHpAAkCPQPJACiAyAEwnB4CAAG/gEAARgBAASWBJAEmASWBBAEAADIcCAJEgcOA8oAagwaAAAEfAkAAQAF/gUACM9wAAgADPwBVAFUBVQBVgVUAVQLXAlABwAA2HA4CAAG/gEQAoAIiAT+AogAiAD+AogMAAjZcCAIEA7+AQADWABID64EtASkBLQETA9AANtwQAgwBv4BEAYABPgIiAj+B4gE+AYACAAA33B4CAAO/gEQAP4PAgQiBfoEogUCBP4PAADkcPAIAAz8AwAEEAUAAagD/AqoCrgKqAYkAOZwIAQYBAAD/wAIAwAI+QQJAu8BCQT5BQAI53B4CAAG/gEAApAIhASmA7wAtA/ECKQIgATrcAAIighiChQJAAQqA1oELgSaCIoKeAgAAO1wAAAkBCQDfwAUBoAAZAA/BwQAfAKABkAI+XAAACIIIgY+ADYFNgG3AHYCdgQ+ACICAgQJcQAAEAgUBPQBVAlcA1wBXANcCVwJFAcAAApxPAQADv4BCAMAAF4BVgHWD1YBVgFeAQAAFXEgCBAO/gEQAoAI+ASWAvQBnAL0BIAIAAAZcTgEAAb/AQgDIACsB6QEpgSkBLwEpAcgABpxAAAkChQLvgQMBKQDMAIMBH4FDAUUCCAEIXEoCCgN/gElAfwNJAH8BSQJ/AEkBSAIAAAmcRAIEAz4AV4BWA1YAfwBWg1YAVgBCA0ACDBxeAgABv4BAAI4ANAPSAUGBUQEXAXEDwAANnGICKgGbgJuABQFDAGAAGgGHgBoAooOgAg8cUAIOAQAAv4BEAikBPQDpgCkD/QIpAgABExxeAgABv4BAAKQCPwK1ArWD9QK1Ar8CAAATnEECfwEXQReAVwN/AAEAHYMBQH8AQQMAABVcQAAAAj+BLIAzgK6DAAA/gQSCRIDng8ACFlx8AgADPwDIAj0CpQK/AqUDvwKlAr0CgAAXnEAABgJVgVUAVwN9AEAABwN6gjIAjgFCAlkcTgEAAb+AQABEASEBL4CrAHsB74BhAIABGdxAAj8DZQAlADsDBQAzAFEBVQJVAHMDQAIaXE4CAAG/AEQAgAI/AusCqwCrAasBvwLAAhucQAAMA40APQBdAV+AXQFdAV4AfQBEgwAAH1xAAAQDv4BEA78A6wEbADqB6oEagL6DwAAhHE8CAAG/wEIAgAM/gCqBqsIqgqqAP4GAASKcQQEfAc/ALwAvgb8AAACZwSqAIkCRAwAAI9xAAAICvoK2gLaCv4D2gr6CtkC+QoICgAAlHEYACAM/gMQBCQBlA9ECSYJRAmUDyQBAACZcQAE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t3MEAiQC/AMkAgQAgA+ABP4EiASIBIgPCAC7cwAEJAL8AyQAAAz4A8gJfgZIBsgJGAgAAMJzAAQkBPwDJAIAAPQDFAH0CQQI/AcEAAAAynMAACQE/AMEAkAI/gdCAP4H/A9CAP4PQADNcwQCJAL8AyQBEAFICCQFkgTEBEgCEAEAAOBzBAQkAvwDJAIAAFwGSAH+D0gBSAJABAAA7XMAAEQE/AdEBAAC8AgABP4DAAj8D0QIBAjycwAAJAT8AyACDACMAvQClALUD5QClAIAAv5zJAQkAvwDJAoACPwFVANUAVQPVAn8CQAEA3QAAiQC/AMkAQwDaAIICP4HiAAKA2oEAAQFdAQCJAL8ASQBAAD8D1QEVgTUAVQDvASABAZ0AAQkAvwDJAIACXwIVAnUD/wPVAlUCXwJCXQABCQC/AMkAgAItAcsAKYPJAC0ByQIAAAQdAAEJAL8AyQCAAj0CRQEEALeARAEFAj0CyJ0AAQkAvwDJAKAANQC1Am8CMQHZACUAwAEJnQAAiQC/AEkAQAAtAe0AqwDLgj0DzQAAAAqdAAEJAL8AyQCAAgIBf4FWAFYAf4FCAUACDN0AAAkAvwBIAOIAP4PSAAAA8gA/g9IAIgDNHQAAFoAWgFeAXoBWgFYAXoFXgNaAVoAkAA8dAAIRAT8B0QGAADoBqgArA+oAKgB6AMIBEt0AAAkBPwDJAIAAPQHvAW2BbQPvAXwBQAFW3QAAiQC/AEgAQQE9gSUApAB8ACUApYC9ARcdAAAJAT8AwQI8Ae4AvQPFgDWAwQIyAcQAF50AAQkAvwDJAIAADwAsA+wB/4AsA+wALwPX3QAAJQOVAh8BFQGlApACVQJvARUAVQGAABqdAQCJAL8ASQBAAz+AKoGqgD+BqoBgg8AAHB0AAQkAvwDJAIACHwEVALUAf4HVghUC3wLg3QAAiQE/AMkAgQAdA9kA9YFZANECXQPAACHdAAAJAT8AwAM+gMqCMAHFgcqBOgPKAloCYt0AAAkAvwBJAAAAvQC9AL2D/QC9AL0AhACnnQAAiQC/AMgAQoEaAV+A+gBbgVoBW4JAACndIAAfAh0C7QLtAv8CwAPVAt2D1QLVAkAALB0AAIkAvwBJAUABP4Evge6Ab4CugJ+BRAFynQABCQE/AcgAggM/A/+B+wH7AfoC+gLAAjcdAAIAAb8AQQABAb8BQIEggc+CMIDAAwAAOJ0AAB0DfwB/A90AQAO/AEEBvwFBAL6DwAA43QEAE0N5gMADfwH/AsCCP4HWAHnD1QBAADkdAAE/AX+D/QJ7AHwDfwDBA78BQQG+gsADOZ0AAAEBAQO5AkcCNQEFAUUAPQHBAgECAQG7nQAAFgISA7kB3IHaAdiB2oBcg9kCEgISATvdAAA/AcEBbQE5AQQAQIM/guSAPIPAggABvZ0AACIDPoDiAD+D4oAAAj8D5QA9A8ECAQE93QAAEIIVAzAC2gJZAtWAUwBVA9kCGAEAAAEdQAAfAl8BVwHbAU8AIAPfAiUAPQPBAgABhh1AAAIAAgA/g+IBIgEiASIBP4PCAAIAAAAGnUAAAQBBA/+CVQJVAtUCVQL/gsECQQJAAAcdQAAkg+SBP4EkgcAAP4PiASIBIgE/g8IAB91AAAgCJAIjgiICIgI/g+ICIgIiAiICAAIInUADOQDJAm0CrwKrgqsD7wKtAqkCiQIAAAjdQAM5AMkCLwKpAqkCqYPtAqsCqQKIAggACV1AAArAiQC/wEkAQAIvgbqAb4EqgS+AwAAKHUAAAAM/AMkASQBJAH8DyQBJAkkCfwHAAApdQAAAAz+A5IAkgD+B5IIkgiSCpIK/gkABCt1AAAIAOgPqAKoAqgC/A+oAqwK7AcIAAAAMHUAAPwPRAREBEQE/AdEBEQERAREBPwPAAAxdQAA+A+IBIgEiAT+B4gEiASIBIgE+A8AADJ1AAAAAPwBlACUAJQA/A+UAJQAlAD8AQAAM3UAAPwDJAEkASQB/w8kASQBJAEkAfwDAAA1dQAAAAD8AyQBJAH/ByQJJAkkCfwJAAgABjd1AAAACXwJVAVUA/wBVAlUCVQJfAkABwAAOHVAACAA+AeuAqgC6AOoAugLCAgIDPgDAAA6dQAA/gciAv4DIgL+AwAACAgICPgHCAAIADt1AAD0DwQE9AVUBVQF/AVUBVQF9AUEBPQPRXUAAPgB/g+uD3gAIgnyBDoC5gkiDOADAABMdQAAAAG+CKoEagI+ACoAag+qAL4AAAEAAE91AACACPwP1AjUCPwI1APUBNQG/AiACAAAUXV4CAAG/AEABhAA/A9EBEQE/AdEBEQE/A9UdQAA/AckAvwDJAL8A4AAqAD+D6AArACAAFl1AAA8AKQPogqSCqIKgA+8CoQKRA88AAAAXHUAAEQA1A/UCvwK1g/UCsQKpAqkDyQAAABidQAAoACuAu4CrgLuB64CrgLuAq4CgAAAAGV1AAD8B/wDJAL8A5AAiA/WCKQI3AjED0AAZnUAAPwH/AMkAvwDAAgoCSgJvg8oCSgJAAhqdZAAlADcB7QFlAW8B5QFsgXaBdoHkABAAGt1SAB8BPwH/Af8B/4H/Af8B/wH/AdIBAAAcHUAAAAKvArsB6wGvAKsAqwG7Ae8CgAKAAB0dQAA/AckAvwHdAasA/QDXg1UDVQJVAcAAXZ1AAA4AAoP7AuoC64LqA+oC+wLCg84AAAAeHX8ByQC/AMkAvwDIAC0A7QCrgs0CPQHIAB/dUAA5gdZBdQHWAX/D+AEdgN5B7QIUghABoZ1AAB0BVQPXAzABwQA/A/0DvwP9A78D0QIinUAAPAJ/gj+D/4P/g+uD/4P/g/+CPAJAACOdQAE5AcEBPQDTAIECPQElAL+D5QC9AwAAI91AATEA/QDTAIACKQHPACmDywAPA9kCEQEkXUACW4JVAXUA1IBCA2iAyoE6g82CWIJIAiXdTgJgAT8AwQAJAAkCCcIpA9kAGQAJAAAAJl1MAkABfgDCABIBCgKrAmoCagIqAgoBAAAmnUYCYAM/AMECMQINAQmAqQBZAIEBAQIAACfdZgIgAb8AQQAhAD0B5UElgSUBJQElASEAKR1mASAAvwBBAD0A5QE9gSUBJQE9AQEAgAAq3WICLAO/AEECEQItAWWBpQG9AXECEQIAACudYwIQAb+AWIAIgDyBysIKwkqCfIIEgYiAK91OAGADPwDBAz0AxQAlgLUAxQA9AcECAQEsnWYAIAO/AEEDvQBVATWBXQCVAWUBDQIAAC5dbgIgAb8AUQAJAqUClYJFAWkBCQCRAEAALx1GAmADPwDBAAkBbQE1gjUCrQKlAAEAQAAvnWYCKAO/AEECIQEtASmAuQBpAKkBKQIAATFdZgIgAb8AQQA1A9UAFYD9ABUA1QI1A8AAMd1mASABvwBBATUBxQEFgT0B5QElASUBAAAynWYBIAG/AEEBCQFFAVWBdQHVAUUBSQFJATSdYgIkAb8AQQApAK0AqYC5A+kArQCpAIEANV1mAiABvwBBAD8D6wErgSsAawGfAUECQAA2HU4CYAE/AMECNQJVAtWCVQJVA3UCRQIAADbdZgIgA78AQQA7A+8Ar4C7A+8AqwK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JALkA3wA1AF+AVQB1Ad8AQABl3iEAPQHLATgB8QANAykA0YA9AcUCPQJAASYeEIA+gcWAvIBAAT8DKQC/wCkAP8CpAT8AJ94hAD0D0wEwAcIAHwNSAP8D2gDfAVICQAAp3gAAMoE6gL+D+oKgAr8CtQK1grUDvwAAACpeAAAhAD8ByQC5AsACPwHrAKsAqwG/A8ACLB4hAD8DyQE4AeIAA4J/A8ICPwPCgjICQAAsXgEAdQPLATEC/AHCACoDwgHfgKIBWoIAAazeIQA/AckAuQDAAisB2gALg2oAygErAkgALR4hAD0DywE5AcAAKgL2ArcCtgKqAsoCAAAuniEAPQPTATEB0wA5A9cCVYJ9A9UCVQJTAm8eAAAggD+ByICwAd+A6oEqgD+BqoBgg8AAL54wgD6ByYC4gEABP4DigjqB6oB6gKuBAAAwXiEAfwPJATkAwwIaA+OCOgOSAioD84IKA7FeEQA9AdMBMQHAAB0CFwG3AF2CVQJVAcAAMp4AABSAtIHegVuBWoHagLqB2oFegVCB0AA0HhQBVAFPANUDxYLfAsIC2YLUgu+D5gBgAHVeAAARAD0DywE4APID/wPzgjMD+wIyA8ACNp4hAH0DywEJATEB/wC3AbcDv4K3A/8AgQD6HgADvwBBAS0BLQOtAuWCoQKtAq0CrQOlAD0eEQA9A8sBMQHIACaCdoP1gjWDJoKIAgAAPd4QgD6BxYC8gOACHYHzAFfAMwB9QdUAQAA+ngAAIIA/gcSAuADSgjvBOoC+gDvAuoCAAwBeQAAQgD6BxYC4gEIDP8ArAb9AKwGLAAABw55hAD8ByQCxAsUCEwEXgfQD0wJXglUCRAIGXkAAAQB/APkCw4IVAfUAUAIDAfsDywJZAA6eQAAIAQkAqQBJAgkCOQPJAAkAKQBJAIgBDx5AACIAYoA7g9YAIgBAAD+BwAIAAgACAAGPnkAAAgBiADOD7gACAkgCCAI/g8gCCAIIAhBeQAAiABKAOwPWACIAAAA/A8EAHQCjAEAAEJ5AAGIAMoPeACIACAA/AcgCP4JEAj4CAAGSHkIAYgAzg94AIgJAAT8AyQAIgDiDyIAIABJeQgBiADuD1gAiAgACPAPAAj+DyAIIAgACFB5iACIAO4PWAAIAYAA+A9OBEgESATIDwAAVXmIAIgAzg98AAgI4AwAAvIHxAgwCGwGgABWeQgBiADKD7gAAAj8DyQJJAkkCSQJ/A8ACF15iAFIAO4PWACACDwEJAPkACQA5A88CAAGXnmIAYgA7g9cAIAA+AMoASgB/g8oAfgBAABfeQAAgASWBLQCtAC+B7QAtAK0ApYEgAQAAGB5gABJAOsHWACCAOoDKgEqAeoJAgj+BwAAZXkIAYgAzg94AAgAQAFKAUoB+A9KAUoBCAFoeQQJdAXUBdQB/AnUCdQH/AHUBdQFdA0ECW15EAAQAZgIbgRMAXQJSAlGD1gBZANUA4wMd3kIAYgAyg+4AAAEVALUAX4DVAlUD0QBAAB4eQgBigDqD5gAAADcD1QB9ABUC1QI3A8AAHp5CAGIAOoPWABACAgJ/gVYAVgB/gUICQAAgHkAAAQK/AuMA/wL3AveD/wDjAf8BwQKAACBeQAAFAlMBV4BTAlECVAPTAFeBQwFNAkgAIR5iACIAM4PfAAIAEIEKgIqCeoHKgG+AqAEhXmEAEQA5g9cAAQB8AGqAfgHrAGqAfgBAACNeYAAiADsDxgAwA98AMQH9ALUA1QI/AcAAI95iABIAO4HWACCAPoPagVqBeoHagV6BcIHpnkAACQFswWABesB/gHaB4ABvgOCAz4FAAWneQABigDqD5AABAB8D9wLXgtcC9wLfA8EAap5xAAkAPUPLQBAAv8CrQL/D6oCrQL/AgACrnmIAUoA6g+YAAAI/gv/CuoK/wrqCv4LAAixeQABigDqD5AAxA/8BfwH/gb8AvwP3AIAALl5AACED7wArASsBPwHrASsAqwKugiCBwAAunkAAIAP/ADUAtQC/APUAtQC1Aj8CIAPAAC7eQQABA90AWQFZAfWBVQFVANECXQJBAcEAL15EAAID+gBxAGUBbIHugWyB4QJ6A8IAAAAvnkgBCQCJAGkAGQA/A9iAKIAIgEiAiAEAAC/eQAAkAhUCFQENAN8ADQANAdSCFIIkASAAMB5iAhMCCwEnAOMALwAigqaCSoJSgdIAAAAwXkAApIBUgD+D1IAUgQAB/gEBgTABAAPAAjDeQAAUAhUCFQENAO8AJQANAdSCFQIUAYAAMZ5AAAYA5gA/A+UAAABRABEAPwPRABEAEAAyXkAACgEugS6AroBugH+D7oBugL5AigEAADLeQAAkgNSAP4PUgAACDgEgAN+AIADMAQICM15lANSAP4PUgACAPgBiACIAP4PiACIAPgB0XkAAJQDUgD+D1IAEAFCAUwBAAH+DwABAAHSeQAAlAFSAP4PEgCACDgEgAR+AgAB2AAAANV5EgOSAP4PUgAAAP4PIAQAAP4HIAgQCAgG2HkSA5IA/g9SAIAJYAT6B4IIYAgeCOAGAADfeRQDlAD8D1QAlAkACPwPJAkkCfwPAAgAAOR5AAAUA5QA/A+QAIQAtACEAPwPhAC0AIQA5nkgAawIbASsA7wDrg9sASwDbASsCCABAADneQAAFAOUAPwPkgAACPgIiAb+AYgG+AiACOl5lANUAPwPUgCSCBAETgJIAf4ASANIBEAI63mSA1IA/g9SAJICAAaQAXAA/g9QAJYBEAbveQAAlANUAPwPUgAACHwGRAFEAEQBfA4ACPB5kgNSAP4PUgCSAhACzwEECPwPBADsAQQC+HkUA5QA/A+SABoASA9ICUgJfglICUgPCAD7eQAAlAFUAPwPUgACCagErARWBXQCzAFAAP15FAOUAP4PUwAACZ4JUAhwBV8GUALQAV4AAHoQA5IA/g8SAAAB6gesALwApA+sAKoEqAMFehIDkgD+D0IACAj0BJIDkACSD+QICAgQBAt6AAAYA5gA/A8AATwIpAqkCqQPpAq8CgAIDXqSAVIA/g9SAAAA8gdUAVABXgFQBfYHAAAOegAAlANSAP4PAgA4DMoDSADMD04IeggABhp6AACUAVQA/A9SABAA/g+oBPwHqgSoBAAAIHoYA5gA+A+UAAAM/AMEANQH9ALUCwQI/AcjehAA+AVWBfQFXAX0BiAHpAD8D6QAIgcAAC56AADKASoA/wMACP4Krgr+D64K/QoACAAAMXoUA5IA/g+SAAAC6A+kAqQC6gOiCroK4gcyehQDkgD+D1IAEgDADxIAwg9aBUIF2g8AADN6JAIkAfwPogAABlgAVgVWC1QJXAHwBQAIN3qUA1QA/A9SAAAJfgmWBdYGvgZWBVYIXgA7eooBSgD+D0kAAADKB6oEgQQtBKEE7QcAADx6FAOUAPwPUgBABVwFtAJ2CbQG1ABcA0AEPXoUA5IA/geSABAAdAesB64HtAe2B5YHVAA/eooDSgD+D0kAgA9eAFYPVgVXB14Awg8CAEJ6FAOSAP4PUgCABnwArAysCf4KrAKsBvwIRnoSA5IA/g9SAIAIvAwsBSwF7gYsArwCgABMehAM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fXwsA6AA/g+gAAwBQABECEQI9A9MAEQAQACJfCwDoAD+D6AALAlgBFgGxAFACEYImAcgAJJ8LAYgAf4PoAAsAQAIaAiICw4IiA9oCAgIl3wIACAD/A+gACwBAAj8DyQJJAkkCfwPAAiYfAAALgOgAP4PJACAD4AE/gSIBIgEiA8AAJ58jAMgAP4PhAH8DxQE/AUUBPwEFAX0DwAAn3wECXQF1AXUBXwDVA9UAXwDVAVUBXQFBAmkfAAAgAD8AMQD1gLWAtQK9ArEDvwCgAAAAKV8AADyCJIIngc8A/4PKAAEA3AIkgieBwAAp3wsB6AA/g+oAAAM+AMICEgI7g9ICEgIAACqfAAAKAqoCqoKnAu+AogCmAacB6oKqAooCq58JgegAP4PoAAuAQAA/A9UBNYAVAN8BAAEsXxkCREFQQWMAyABkg8uAUIDwgV+BQwFMAm5fAMA0AH/D1AAkwGAALoAggDjB5oAkgCiAL18AAa4Af4PIAAIAwQIpAanAKQPpACMAoAMvnwCACwH4AC+DwAA1A/cAtwC3grcCtwPFADKfAwAIAP+DywAgA9+BMgDAAz+A5II/gcAANV8BgCgA/4P6AAACKgGqgCsDvgArAyqAIgO1nwGANgA/wNYABAP/AB0A/QC9gL0AvQDIADZfAwAoAH+D6gAJAlABNwHAAisC7wKqAqoC9x8AA78AQQIHAW8BS4Dhg8cA7wDHAUsBQAA33wGAKAB/g+MADoA1g//CtYK/wrWCv4PAADgfAMAkAH/D8IC/wEBAlUB/wfXAz0BkQKBAud8qAH+D6AAKAjgC/wL/Av8D/wL/AvcCwAI73wDANAA/w/eAY0HvQClB+8ApQetAL0HAAD4fIAEhASYA5QB4wDQD0gARAF0AUACgAQAAPt8AAAABJQE1ALcCLQIlA9SAEoBQgKCBIAE/nwAAJAO3ACyDIgCAAD8AwABAAEAAf4PAAAAfQAASAd8ANIPSAEAAOQHJAgkCCQIfAgABgR9SAd+ANAPTAAAAxAATgCICQgICAz4AwAABX0AAEgHdgDQD0wA4AoECAQI/A8ECAQIAAgKfQAAFAhUBVQFfAH0CVYPVAEcBZQJJAokAAt9SAduANAPTADgCggIOATIAg4DyAQ4BAgIDX1IB24A0A9MAAAB+A8IAcgAPgDICPgHAAAQfRAOnADyDsgAgAIECEQM/AtECPwPQAgAABR9SAduANAPTAEAAOgDCAEIAf4HBAnkCQAEGX1IB3YA0A9MAGQBAAT+ByIE/gEiBiEMAAAafUgHWAD2D2AAQAsEB/wAhAQkBTwD4AQgCBt9SAd2ANAPTAAAC3AITgbAAUIITgjQByAAIH0gACoJagVqA+oL/wlqByoBqgWqCSALIAghfUgHfgDQD0wAxAoACAgH+AAuCCgI6AcIACJ9AAA0CBQFVAX0AV4JVA80AbQFFAU0CQAAJ30ACB4JgAXeAcAJogmSD14BUgUeBSIJIAArfRAJHAlQBV4FtAGQD04BFAWUBRIJCAoAAC99AAAACD4FagXqAX4Jag8qAaoFPgUACAAIMH1IB3YA0A9MAcAA/A9EBEQE/AdEBEQE/A85fUgHbgDQD0wAAAMgAKIPngSCBKIEng8AAEJ9SAduANAPTACAAogATgQ1BTQFTAlAAAAAQ30QDtwAsgZIAEAHSABoBloFzAQoBggMAABEfUgHbgDQD0wAAAMACPwPJAkkCSQJ/A8ACEx9SAduANAPTAAAA0IIJgkqCZIPKgkmCUAIUH1IB24A0A9MAKADBACkD6QEvwSkBKQPJABVfbAN7ACiBJgCAAD0BzQJLAnkCTQJLAngBV59SAd4ANYPUAAACygImAQYA84DCAQoCCgAYX1IB24A0A/MAMQDkADID9YEpATcBEQPgABmfUgHbgDQD2wBIACQD4wEogSkBIgEkA8gAG59AAAsCCwFlgHUCcwJgA9eAVIFEgUeCQAAcX1ID3YA0Q9MAAAJBAS8AycALAC8DwQIAARyfQAAkA78AJIGSAIAAFgDdgjQD0wA4AIABHV9SAd2ANAPTAAACxAIiAamBaQEiAawDBAAdn1IB24A0A9MAQAA+AeWCJYI/AicCJQI8AaTfZAMvAHiDNgAAAo6CEIJEgnqD4IJPglGCJl9QAduANAPTAAAAf4PAASoBP4FoAQsBQAEmn0AAEgHfgDQD6wDgAlUBFQDXgBUBtQIBAScfTAO7ACiDJgCAACMDKQCpwCkD6QArAKADKB9MA7sAKICmAQABNoCVAjUD3QATAKABAAArX1IB24A0A9MAEADEAD+D6gE/AeqBKgEAACxfU4HcADsD0AB/A/sA+QDJAKsCyQI/AcAALJ9SAd4ANYPgAL8DwwAvAPkBLQEBAD8DwAAv31IB24A0A9sAQAAvgeqAKoA6w+qAL4EgAPKfQABPgUuBb4F7gGuB6IBWgMaAyYFQgUAAM99SAd2ANAPTAAAAV4EQAD8D2QJcQhGA4gE0X1IB24A0A9MAAAFIASqAioI6gc+AaAGAADSfUgDdgDQD0wA4AOEAJQHfgVUBVwF1gcQANp9SAduANAPzADABZwCrAksCO4PLAO8BAAE4H1IB3gA1g9IAQgAoAeUAJwA1g+cALQHAADjfSAIvAziAtgCgAQgBH4DtAq0B7wBIAYAAOh9SAduANAPTAAAD/wHrAKsD6wCrA+8AoQP6X1IB24A0A9MAEAJFARcA/QJ1AbSBtwFVAjvfUgHWAD2D2ACAAT0BbwHtgW0D7wF8AUABPR9SAd4ANYPSAAAAvwErAKsAf4PrAH8AgQE+32QDtwAsgTAAZwE1AeUBAQA8AwOA/gEAAgBfkgHXgDwD2wAgAIgBGoDqgpqB74AIAcAAAR+RANfAOgPJgAAAfwHvAK8AvwHvAq8CvwNI35AAnwBfAD8B/wASAIYAXwE1ANUANACgAAmfkgHbgDQD8wAQAL2D5gHFgTwD5YIEAgAACt+EA7eAHEEbAMBCHYG4AksCLsK+wsmCgAILn5AB34A0A9MAUAA7A8EANYHdAVUBdQHAAAxfhAO3gCxDMwCAAD3DwAEzgMBBOgHhgiYCD1+kA7cALIMiAIADPwChAaWCaQLhAD8BgAAPn5IB24A0A9MAAAK/Aj8Bf4F/AH8BfwJEAhBfgAIMAq+CjwL/AM8D4gCXgZkB1wKhAoAAEp+QAdOAPAP7AHAB/QHHgT0A5AG/geQDBYCVH6gAy4A8Ae8ABAA/Ae2AtgPPwPQBBYOAABefpAO3ACyBIgCAAiqCeoHrwEKD+oJqgmABWp+AAd4AJQGUgEIADQH8gX6BdIF9AX0BwQAa34AAH4Kfgd/B/4PfgsYB/YC0gp+CpgKgAhwfkgHbgDQD0wBAATwAt4B+gfqAdYC8AQAAHN+kA7cALICCAk+DOsD6wm+BzQMiwN4DAAAfH4QDtwAsgZIAv4PNAi6DzgJPgisDxALAAiMfpgO9gCRBkgBEgjuB/4H7wP+A+4H+gcACI9+gA7cAKIGWAEADPwD9An+C/4O/Av8C4QJln5QB3wAagIACXYE9QcQBPYPMAT+B9AMFgKgfqAEsAVsBSIFkAQAAPwBAAEAAQAB/g8AAKJ+AAAwCewEogSYBgAABAQEBPwHBAQEBAQEpH4AADAJqAVmBRAFQABEAEQA/A9EAEIAQACmfqAEuAXkBJIEgAIwAI4AiAgICQgM+AMAAKd+IAW4BeYEkAIQDIQDfAiEBTQCrAVgCAAIqn4AACAFuAVmBRAFAADEB0QIRAhECPwIAAarfgAAMAXoBaYEkAIACHQEBAP8CAQM/AMAAKx+IAW4BWYFEAQAAqgAqAD+D6gAqASIAwAAr34gBbgFZwUQBQAE9AEEAQQB/wcECfQNBASxfgAAMAXoBaYEkAIACHgIAAT+BAACmAEgALJ+AACYBdcEsQQAAP4PAgCyAdoBAgj+DwAAs34AADAFzgUiBQAA8A8QA/AAnggQCPAPAAC1fgAAMAXsBaIEkAAADv4BAAwAA/4AAAcACLd+AAAgBbgFZgUAAWAIWATEA0AIRgjYB2AAuH4gBbgFZgUwBQAA/A9ECEQE/AFEBkIIQAa5fgAAMAXsBKICmAoACDgEygIOA+gEGAQICLp+AAAwBawFYgUYAQAICAf4AE4ISAjIBwgAvX4AADAJrAVjBRgBAghCDP4LQghCDv4JAAi/fgAAuAXkBJICgAoQCFAEfgTIAyoFqggABMN+uATkBLICAABUBnwBVgj0D0QARAEEBgAAxH4AACAFuAVmBRABAAj8DyQJJAn8DwAIAADFfgAAIAm4BWYFAAD4AygBKAH+DygB+AEAAMZ+IAWwBW4FIgUAAPwPRAREBPwHRAT8DwAAx34gBbgE5gSQAgAIfAZEAUQARABEAXwOAAjIfgAAMAXoBaYEkAQQAEgCVgQkBVQFTAiAAMp+MAqsCWIJEAUAACwBIAH+DyABLAEiAQAAzX4wBZwE8gKIAiAAog+aBIYEogSiBJ4HAADOfiAF+AWmBJAEBACsAqwClA+0AqwCpAIAAM9+IA24BeYEkAAACKQIpAiUD6wIpAggCAAA0X4AADgL5gmQAQAIKA3+AwAA/A8EAHwChAHSfiAAmATkArICCABABugBCAh+BIgHaggIBtN+MAXsBKICmAIAAKQHpASkBL8EpASkBwAA1X4gBbwE4gSYAgAIpASmA7wAtA/ECKQIAATYfjAF7AWiBIACIAiQDqwJpgSIBpAEoAgAANl+IAW4BOYCgAIgAKAPsA+uBKgEsA8gAEAA234gBLgFZgUSAkAAqAKoAq4ClA+sAqQCIALcfgAAMAXsBKICkAIQAEgPtgSkBLQETA9AAN1+IAWcBOIEmAQAAPgHlgiWCPQInAjwCAAG3n4gCbgFZgUQAUAIOAiYBQoCyAUoCEgIAADffiAFuAVmBZIEEAJACGgHXgBID2gISAhIBuJ+AAAgCbgFZAUAAOAPvAK0ArQKtAr8DwAA434wBawE4gSYAgAIrAScA4wAvACaCSoHAADlfjAF6ASmAqACCAhEBeQGagLCBVoMQAQAAOd+IAC4BeYEsAIAAPgHBASgBP4FYASsBQAA6X4wBZwE8gKYCgAI3AVcBF4DXABcBNwJEADqfgAAmAT2ApICAAJUANQHfgVUBVwF1AcSAO1+IAW4BOYEkAIAALQIFAUeA9QBFAVwBRAI7n4AALAF7ASiBDgAoAe0AqwCrgs0CNQHNADwfiAFnATiBJgCAAD4AqgCqAKuD6wC/AIAAvN+AACwBWwFIgUAAPwDtAL0B7QKtAr8CwAA9H6wBOwEogKYAiAA/A+qBKgE+geoBKgEAAD1fiAAmAXWBLECAAC+B6oA6w+qAKoEvgMAAPd+IAX8BbIEAAz+A5II/gcADP4Dkgj+BwAA+H4AALAF7ASiAgAI/AcEANQH9AIECfwHAAD8fgAAIAW4BWYFAAUYAIgCqgisD6gAqAKABP1+AAAwBegFJAUAASgMqAMoBO4PKAkoCQAA/34AALgFZAUSBYgAQAQqAioJ6gcqAb4CoAQAfwAAOAqkC3MJAAyqCJoGBAmgCZIGnguiCAV/AAC8BeIEmQIIAOIHEgTyB14F8gfyBwAABn8AANgCTgJ5AQAE7wQ/AqABKAMmBOwFBAQOfwAAOAXmBJEAAAL8D1ICAAjeBUIC/gVgCBN/IAW8BOMEmALADFQC8gnWBtEG3QVVCAAIFH8QBawFYgUYBQAAtAecANYPnACUBLQDAAAVfwAAOAXkBLIECAKgCKoLmAbeBJgHmgSoCBZ/AAC4AuQCkgAABvwBlAfWA9QHVAHcBwAAGH8gBLwFYwUZAAAFbAVrBaoKqge+ASAGIAQZf5AE3AKjApgCAgDqD2IFfgV+BWIF6g8gABp/IAWwBG4FIAUAAHgBeAV8AXgJ/A/4AQABHX8AANwFswSIACII4AcECK8K6guuCqIKAAggfwAAOAXkBRIBAAz8A3QIrgr+D6wK/AoACCR/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SANABAAA/A8EAPwDK4EADP4Dkgn+BwgA9AySA5AAkg/8CBAIAAQvgQAM/gOSCP4HAADoD6gCqAL8D6gCrgroBzGBAAz+A5II/gcAAHgESgfMAMwPSgh5CAAGM4EADP4Dkgj+BwAA7g8ABEEFzgQABO4PAAA4gQAM/AMkCfwPIASQBSgEpgQoBxAHoAQAAD6BAAz+A5II/gcAAPwB1AFUAX4HVAFUAXwBSoEADP4Dkgj+BwAAFADeB1QFVAVeBdQHAABLgQAM/gOSCP4PAAD0DwQA5gxUA5QFdAgACEyBAAj+B5IA/g8AAOgDuALsB6gK+AsoCAAEUIHADzwApA+kALQGhAWmBZQF1Aj0CJQPBABUgQAM/gOSCP4HAACkCJQIhg+UCKQILAgAAFWBAAz+A5II/geAAEwItAdGAPQHFAj0CQAEZYEADP4Dkgj+BwAB/gjqCqoKqg+qCr4KgAhmgQAM/wPJAP8HAADvDyAEtwQoBSIE7QcAAG6BAAz+A5II/gcABHwDVABUB/wIVAhUAXwHcIEADP4Dkgj+B5IAqgf+BqoEvgOqBLoIAABzgQAI/geyAP4PgAD8D6AExA/4BwQA/AMAAHiBAAz+AxII/gcAAP4G6gHqBOoD/gjABwAAeYEADP4Dkgj+BwAAfAXuBewC7AX8BAAEAAB6gQAM/gOSCP4HAAC8AqwJLAjuDywDvAQABHuBAAz+A5II/geAAXgOeAD4BQgI/gMIDAoGfoEACP4HkgH+D4AB6gS4Bq4GqApqC6kGgAB/gQAM/gOSCP4PAAjuBwAI/AtUCNQJ/AoACICBAAz+A5II/gcAAFQO1AFUCVYJVAlUBwAAioEADP4Dkgj+BwAAeAV4BXgBfAl4D3wBeAGPgQAAZAA8D/wHvAe+B7wHvA/8DwwPZAAAAJiBAAz+A5II/gckAdQF/AHUD/wB1AX0BQAAmoEADPgDCAD4CPgH/gP8B/wH/A3cDxgAAACbgQAM/gMCCP4HEADKBagFrgeoBcoFGgUAAJyBAAz+A5II/gcAAHQFdgf0AXYDdAV0BQAJnYEADP4Dkgj+B4AAVAVMAj4PTAJMBVQEAACggQAM/gO2CP4HAABUCqIKvgpABVQFAgI+AKiBAAj+B5IA/g9AALQGvgR0BQAATAwiAwABs4EACP4HkgD+DwAAVA9WC/wLVAvWC1QPAAG9gQAM/gOiCP4HEAD4B5YItA+cD7QP0A/AAMCB8AAOAPoPugP6A74DgAP2C9ILPgdYAEAAwoFAADwA/A/cA9wD/AOwA7wL9gu8BzQAEADJgQAM/gOiCP4HAADwB7gF9wBVDKQC6AwAAMqBAAz+A5II/gfgAN4G+gH6B+oH1gHwAgAE04EADP4Dkgj+D+QH/g90B/QFHgD8BJwHWAzjgQAA/geSBJIEkgSSBJ4HkgSSBPIEAgQAAOWBAAD8B6QEpAS8B+QEAAyAA3wAgAEABgAI6IEAAPwPlAScB5QEcAuYBKYHVA/UBPQPBADqgQAAAAD8DyQJJAknCSQJJAkkCfwPAAAAAO2BAAAACXwFXAVcA14BXAFcA1wFfAUACQAE84EECKQItAisCKQIpA+kCKQIlAikCAQIAAD0gQAAvASkBJQHlAS0AiAIfgSIA+gCGAQICPqBhAn8DdwP3A3cDd4P3A/cD9wP/A2ECQAA/IEAAPwPRARCBEIEAAREBEQERAREBPwPAAAAggAA1A9UBUQFRAUUBCQFAgViBXoFyg8AAAWCAAAcBfwF/AX6A/AB/AH8BfwF/AX8AwAABoIAAAAJ/AVSBQAFXgF0AVQFAAXUBTwJAAAHggAAAAn8BVQFAAU+AXQBAAVUBdQFPAkAAAiCAAAACfwFBAX8BSwBXAEkAfwFQAX8CQAJCYIAAMAAfAJaAsAC7gfcAsgCXAL8AsAAAAAKggAAJAD0B/QH9gfwBvAG9gf0B/QHlAcAAAyCAAAKAMoPSgRKBH4ESgRJBEkEyQcIAAAADYIQAFAAUAdYBVQF8gVUBVQFWAVQB1AAEAAOghAAUABID0QJUgl6CVIJVAlYCUgPUAAQABKCEABID0QF8wVEBQgHYABqCPIPLgDiAAAAFIIAAJIP/gSSBNAP1AE0CJwPFAA0AlQAUAMXghAASA9WBXwFWAcQAMAPqAL+D6gC6g8AABiCEABYD1QF8gVEDwwA9A9WBVQFdAUcDwAAHIIACbAIUgVWAtIBFgDSA1IC2Q9VAlACAAAeghgJWAn+BtQC/AHUAPwD1AK8B9QCkAIAAB+CQAhABvwBRABMAU4BVQJECEQI/A9AAEAAKoJADPwDRwBVCfwHAADoDygALgDoDwgEAAAsgkAM/ANOAEUN/AMACN4IQgVCBs4FUAgAADCCAABADPgD1Aj4DwAAfg4CAfoHAgj+CAAGMYJADPwD1gBECPwHEADoBycIJQnoCDAGAAA1gkAM/APWAEUI/AcAAOgHigiMCEgIWAgABjaCQAjAB3wAVgn8BwAA+A+IBI4EiAT4DwAAN4JADPwDVwFFDPwDAAhoBFgHzgRoBCgHCAg5gkAM/ANEAFcJ/AcAALgPhgSABI4EsAcgAEeCQAz4A14BSgj4D7QH7AQACCQK/AsiCgACWIJADPwDzwhFCPwHAAC+CKAH/wSgBrwFgAhmgkAP/gBbB/4BAAT/B9UE9wfcBI8HpASkB2+CAAAACPwHVARUBNYEVAFUAlQFfAWACAAAcIIUBCQCxAF8BgAA/g9SCNIIUgFSBn4FAAlygiAAEAD4B5QIlgiUCPQInAiQCPAJAAQAAHOCAAAoASgB/g8oAQgA+AeWCPQInAjwCAAGeoIAAAQAJAQuCiQJpAikCGQILghECAQGAAB+ggQIBAgkBM4EBAMEAgQDzgQkBAQIBAgAAIKCBAAkACQALgDkDyQAJAAkAi4C5AEEAAAAi4KEAJQAlACWCJQIlAj0B5YAlACUAIQAAACNgoQARAA0ALYAJAEkAiQIJAguCCQM5AMAAJKCBABEAMQHTgREBFQEZAREBE4ERAREBAQAl4IECAQJRApmCdQFVAdEAg4DxABEAAQAAACZgoQIpAikBK4EpAL0AaQBpAKuBKQEpAiECJyCggiSCJIIlwSSApIB8geSCJcIkgiSBIIAnYIECEQERAJeBEQMdApECkQJ3ghECEQIBAilgkQARAgkBK4DJAAUABQAJACuDyQARABEAKaCAAgEBvQBVgFUAVQBVAFWAUwBzAMEAAAArIKEAEQIxAiuBKQDhACECKQILgdEAIQABACtggAABAD0B5YIlAjwCJQIlAiWCJQI9AgEBq6CAgDiDyIALwIiAbIAcACiAC8LIgjiDwIAr4IIBIgDCACcBwgIKAhICIgIHAaIAAgHCACxggAABAGEAOQPDgAEAeQHjghECEQIJAgABrOCJAgkBCQGLgHkALQIpAikCK4IpAckACQAt4IACAQIxA8OCAQIBAjwD4QIjgiECAQIAAC4goQApAikCK4PpAykDKQMpAyuDKQGpAiECLmCBAgEBPQDlgCUAJQAkACUD5YAjACMAAAAvYIECJQE1ASWApQClAmUCZQI9geUAJQAhADHggQAFAFUAVYB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5APWD/AL6AvwC9QL9gvkDyQAIAC/hAQAFACUD/YA9Af0BfQF9Af2AJQIlAcEAMSEkACUALQH1gfUB9QH9Af0B9YH1AbUAJAAyYQAADQCFAFWD5QJVAlUCVQJlglUD1QDAAHLhAQARAjUDtYK1A70CtAO1ArWCtQMRAlEANaEAAAEAPQO9gr0CrwAvAa0CpYK9AoECAAE3YQEAAQIZA8OCWQPBAk8Dx4J1AmUDwQIAADmhEABRAX8BP4G/Ab8BvwG/gv8CvwGRAAAAOyEFAhUBMQHDgjkC9QLtAu0C7YLtAs0CkQA7oQACLQE8gMDBPoJWAtaC/4LXwtaC/oLAAIRhQQAdAzUA9YB9ArUCNQJ9gbUBtQI9AiABBOFAAjEC3wLfgv8D3wHfAf+B3wLfAvECQAIF4UEDPQDFAhWBNQBVA1UAVQF1glUAFQOBAAahQQP9ABUDNYB1A/wAQQEpAEmCPQPJAAAACGFJAmkCJQF3gG0CZQJhA/2AdQFtAwUCQAAI4UECXQHRAHuDwQAVAWQBXQJVgk0DxQBAAErhQQIVARUANYB1An0BfQB9gH0A/QF1AMAACyFBASUB/QHlgQEAFQPdABWD1YAdAd0CIQENYXEDzQA9A92BXQHdAXUDX4ElAf0CDQIAAY6hQQAxAcUAMYD1APUA9QD1gdUBhQE9AMAADyFRABUBMQHBgB0AfQH9Ab2BfQG9A70BwAAPYUUANQPxAfuD8QD1A+ECO4EJAPkBSQIAABDhUACSgJKD+sLSgt4D0oLRgvnC1YPQgEAAkmFJAgkBvQAdgF0DXAB9AF0DXYBdAEUDQAASoUEBnQABAauCEQFVABUA0QGLgiECTQIBANphUQIVAwEAo4AhAX0BfAD9AX2A/QJhAcEAG2FAAAkCHQHdgdwD/AHdAJ2D3QHdAckDwQAcoUEAOQB9AHmB/wB7AEEDP4DTADMD0QAAAB0hUIKYgnSCkcFIg0CCPoPqw+qD6oJ+g8CCH6FAABkACwP7gssC3gPLAvsC64LLA9kAAAAhIUkBEwHRAAWAfQB9AP0Af4F9Af0AfQBAAGHhQABNAGEDwYAtA6wALQOhADeCCwH5AUgCJuFAAD0D1QFVgV0BwQAlALeApQP1AKUAoAApoUEDvQBtAi2A/QLtAO0C/QDtge0C/QHBACphQAA+g86AMMN6gMoCKoKrgq/D6oKqgogCKqFBARUAVwJ3gd0AQQM9ANeAFQA1A9UAEAArIWEAJQIRAUGBfQDtA+0AfQDBgVEBZQIlACvhQACdAPUA9YP9A/UD9AP9A/WD1QPdAEAALCFAgiKDf4F2wHeBf4B3gX+Bd8B/gWKBQAAyYW0BLQC9A+2AZQCBADUD/4K3Ar0CtQPAADNhQAA9AT0B/YF9AfwBQQHXAVeBVQHVAQAAM+FAAl0B0QB9A/2A7QG9AYeD/wEFAfUCBAE0IUUBlQGVAPOCiQHBAD0CVQHXgFUD/QJAATVhYoEqgL6D6sDqgECDvoB+wOqA6oJ+g8AAN2FBANcB1wH/gv8C5gLQAc2BxQHdAqEAkQA5IUEDPQDVAn2DwQBdAX0AH4PZAL0BWQJAADlhQAItAXkBQYF9AGwD7QB1AN+A2wFBAUAAOmFIgRqAwIBNwCyD/IKsgqzD6oK6g+iAAAA+4UCACoMSgMLBeIDvgN2D5cPdgO+BeIFAgUHhiQM5AF8Df4BdA3kBAACVAH2D0wBTAYEAAuGRABkC0QI7gVkAnAI9Av2CvQC9Ab0BwAIEYYCCPoHCgRrBWoPagsKC2oLawtqDyoBCgAthgAAAAD+D/8H/gLgB8AC/gP/BT4A/gcAADiGBAD0D/QGfga0BvQLJA7+AH4F/AN0ARQFToYAAAAM8AMQCFAHfgHUAbQHlAi0CLAEEABPhgAAAAz4AwgIKAk+B1wBXAVMCVwNWAMIAFCGAADADzgAiA+oCr4K3ArcCswK3ApICCgAUYYAAAAP8AAQBlAAfgbUCLQKtAiUArAGAABUhgAM+AMICCgJKAs+DWwFbAtMC1wJWAkIAFWGAAz4AwgLqAaoBj4JXAjcC9wI3AtYCggAWoYAAAAP8AAQClAIfg60CLQOlAi0CpAIUABbhgAAgA9wABALUAp+D1QItA6UCrQKMAgAAF6GAAAADPwDBAiUC38HtgO2A7YH5gcsCgAAX4YgAO4EqgSqAyYG8AEYDDgDXwBaB0oEGAJnhgAM+AMYAd4PvA+MCxgI8gCSCJIIkgcAAGuGAAAABPgEiASIBP4HiASIBIgG+AQACAAAcYYABPQFNAU0BfQHNAUsB+wHBAj8AwAMAAZ5hgAA+ASIBP4D+AIABAQEBAT8BwQEBAQABH2GAAAACNwLVAlUCfQHVAVUBVQF3AUACAAIfoYABPgJjgf+B/gGAAgEAPwPJABEAIQAAACAhiAAFAjKDwgEGALwCIgIiAT+B4gEiAX4B4GGAAj4CYgE/gf4DgAIeASCBQwD4AQcCAAIgoYAAPgE/gOOA/gHAAB0AUQBRAl8DMADAACKhgAA+An+B44H+AYACBgI6gwKB4gDeAQICIyGAAD4BIgE/gf4BgAEKAEoAf4PJAEkAQABk4YAAPgEjgf+B/gGAADyCJIIngcAAP4PAACVhogASgjqCVoJTgnqB0oFSgVaB+oHSgxICJyG+AWIBP4HiAT4BBICIgGiCWII/gciAAAAo4YAAPgJiAT+B/gGAAw8AAIOwAkOCHALIAykhiAEIgTSBVYFWgXSB1YFWgVWB9IFIAgAAKqGAAD4CYgE/gf4BgAMJADIAgAC/g8AAQABr4YAAPgJiAT+B4gE+A4ACPwPIgjiDyIIAADAhgAA+A3IBP4D+AoADMgIygj6D8gIyAgACMaGAAT4Bf4HiAT4BgAI/A8kCSQJ/A8ACAAAx4YAAPgE/geIBPAGCADoBwoJjAiICFgIAAbJhgAI+AX+B4gE+AoAAFgARAJTBkQJyAAQAMuGAAASBMoFSgVSBd4HVgVWBVYH1gUSCAAA1IYAAvgCzgP+A0gCMAP+D2IEkgRiBP4PAADZhgAA+Az+B/4H+AYACCQJJAm/DyQJJAkgCNuGAAj4Bf4HiAT4BgAAXgZIAf4PSAFIAgAE5IYAAPgESAT+A3gDIAC4D6YErASwBKAPAADuhgAEFATUBUQFXAXGB0QFXAVEBdQFFAgAAPmGAAj4Bf4HiAT4CgAA5A9kAvQPbALkDwAA/oYABHgE/gN4AwABlAj8B5AMfgKQBVYIAAYAh0AAXAD0BXQFfAX0B3QFfAX0DTQI/AcAAAKHAAj4Cf4Hjgf4ClAASAVuBdQPbAVEBUAECIcACPgF/geIBIgE8A5MCVQF1ANUBVwJQAkShwAA+AX/B/gGAgi+B0II8AsCCv4LIgoACBOH+AWIBP8HiATwBhoP5gUACCQK/gsiCiIKFYcAAPgEjgf+B4gE+AIwDM4DyA9OCHkIAAYXhwAA+AX8B4gEcAKMD1QAVAH0AVQI3A8AABiHAAR8Av8DxAd4DCsC/AEkA/4FAgL+BwAAHIcAABQEpAekBrQGtge0BqwGjAaUBxQIAAAhhwAA+ARIAv4DeAMABtQHXgVUBV4F1AcQADuHAAD4BYgE/gf4CgAA/A88Az4DPAv8BxAAR4cAAPgJ+ASOB/gGAAj8A7QC9Ae0CvwNAARJhwAA+AmOB/4HiAT4BnAAqgL4D6wC+gIAAEyHAAR4Av4DOAOAAP4PkAAkAAgB/g+AAAAATof4CYgE/geIBHgB4AdeBGoFagVqCP4HAABXhwAE+AWOB/4HiAfwCLwK1ArWD9QK/AqACFmHAAj4Bf4HiAR4AsAHvALUB1YB1AdUAdwHYIcAAPgJmAj+B/gKAAD0D1QK1A9UCvQPBABmhwAI+AT+B4gEcAL+D5ICDghgCWIH3ggACHSH+AmIBP4HiAR4AIAHfwKAD/4DEgj+BwAAdocACPgF/gf4BgAAfA1IA/wPaAN8BUgJAACChwAI+AX+B4gGcAT8B1YFPAL4DwQA/AMAAIOHAAj4Bf4HiATwDgQIVAbcAVYJVAlUBwAAjYcEAPwP7ATsAnwJgAd4AIgI/geIBPgGAAiehwAA+ATOA/4DSAIwAX4GqgL+AaoJggcAAJ+HAAT4Av4DyAJ2A34JWgVaBdoBWgV+BQ4JoocAAGIE6AfuBuQG4AfyBugG7gboB3QIAAi6hwAA+AmOB/4HiATwBR4J6g1+DyoBvgsACsCHAAj4Cf4H+AYACJQC9ALuDtQCBANUAgAAxocABPgCSAL+A0gCMAtkCHYH9AF2A3QNAATLhwAE+AX+B4gE+AQAAlwENAl8CTIAWgaQANGHAAj4Bf4H+AYACPQDdAN0A3YP9AMQAgAA8ocAAKALrAqsB6wHPgisA6wKvAesBqAHAAj5h4QEfAQ3Bb4FtgV4B8oHtgWyBboHNggAAPuHAAT8Av8DRAJ+ATsL2g9+A+oHKwdqCwAJDYgACPgF/gfwBnwPPAO8B+ADMAf+AAgDOAQViAAI+AX+B/gCAgA6D0oH3gFaD2oBag9AAB+IAAD4Cf4HiARwAiYPeAt0APoPUAR+AwAMIYgAANQF3AW+B78Ftwk/AJcFrQesBaQFAAAiiAAAqgWeBf4H/gX+Cf8A/gX+B54FqgcgCDuILAAXBN4FQAV2Bf8HfgVwBWQFvwc0CBIAQIgABPgHCAQIBPwHCgQIBPgHCAQIBPgHAARFiAAA+Af8B/oH+AMCABwBIAH+DyABLAEAAEaIAAggCbwEJAS8AKYPfAEkAiQFvAQgCAAATIiIAEgA5A8SAAAAJAAkACQIJAjkDyQAIABNiIgARADzDwgAIgwiAoQBIAgiCOIPIgAAAFOIQABEAPMPCQDIAf8HCADDBRAE8gcSAAAAVIgAAMwA8g8YAIYI9QeUBAAAJAjkDyQAAABXiEAARADyDxkCUALeA1QCVAYABPIHEgAAAFmIAADIAOQPAgBUD3wFdAdkACQAJAjkByAAW4gEAEIA+Q8IAPoD3wLaB/4CAgDyBxIAAABdiAAAJADyDwgAeglaCf4H+gUJBCAA5A8gAGGIAABEAPIPCAn4Ba4D/AOsDfgBAAjkDyAAYogAAIwA4A8cALwHnAeYB7wHvAQAAOQPIABjiIAAiABICMgPKAgaBDwEyACIA0gEKAgACGWIAAAIAYoA6g+YAEgBAAD+DyAAQADAAIAAaIggATQJtAS0B3QEPgT0BDQBtAK0BCAIAABpiAgBiADuD5wAQAkcCOQEFAOEAnQEDAgAAGuICAGIAO4PnABIAQAIiARIBEQCMgIQAQAAbIgIAYgA7g+cAEgBAADQABAJEAj+BxAAAABwiBQBFAV8BVwH3AReBNwEXAFcA3wFFAUQBHeIAAAEAnQCVA5UCfYIVAlUAlQGdAkECQAAgYgAAhAC9AK0DrQJvgS0AbQCtAZ0BRAJAAiEiAQBhQD3D44AZAEADCICogF+AKEDIQQgBIuIkAKIArwKgg6ICcgIjgmYAqoGygrKCqgIjYgAAYwA7A9YAQAA8AcsCSgJ6AsICvgJAASSiAgBiADqD5gAAAj8CSQJJAkkCSQJ/AkACJaICAGIAOoP2AAAAPgPiASIBP8HiASIBPgPnIgAAYoA6g/YAAAESAJIAf4PSAFIAkgEAACriAgBiADKD7gBAAz4A8gISAl+BkgGyAkYCK2IhAKkAqQKlA6MCaYIvAnWAtYG1AXEBbQIsYgAAYgA6g/wACAA/A8CABAH/gCQAxYMAAC0iAgBiADsD5gAAACoALgDrAKoCpgKqAagAMGIAAFUC9QHXgRUAVQDEAz+AhAD0gQUCAAGwojWAtYC3gquDp4JxgSAAZ4CwAbABf4JAAjFiKACrAKQCrwOgAmoBKgBvAKoBqgEqAgAAMaICAGIAO4PnABIAQAELAUgBT4FIAXsDwAAz4gABEQFfA18D3wJ/gl8A3wFfAV8C0QLAAjUiBQA1A90APQHbAVkBWYFzAbUAKQPJAAAANWICAGIAO4PWACIAAABxA+yCIgIsgjED4gB2IiABKwCrAqsDoQJ3gSEAaYCrgasBKQIAADZiAABiADrD9gAgAIqAeoHvgSqBKoEvgcIANyICAEIAc4PuAAAAOgPqAKoAv4PqAKqCuoH3YiQAr4CmAqYDr4JgASoBKgBvgKoBqgEiAjhiAgBiADsD9gAAAB8CVQJVAn8D1QJfAkAAOSIAAGKAOoP2AAADPwDRAC2ApQPlAKUAgAA84gAApwEhQK2DrQJ9gS0AbQCtgaFBJwIAAD4iAgBigDqD9AAgAT8BNQC1A/8D9QB/AKABPmIgAJEAnwBfAf8BP4EfAF8AnwCfAXEBAAA/YgIAr4CnAq+BpwF/ASAAZwCwAbABb4JAAQCiQAAxAD1D2wAAASUBN8HlAQAAP8HIABAAAeJgABIAO4HeAAABT4F/gW8ArwCvAW8BAQEEIkIAYkAyg+4AAABvgeqBKoFqgaqCL4HAAASiSACFAL0AgQOZAl8CT4JfAI8BnwFJAkABCWJAAGIAMwP+AAADvwBdARcATwJ3A8cAQAAKokAAIgB7A/YACAI7AcACPwLVAhUCXwKAAgyiQABlADUB7AAAAT4A+gD7AP4B+gD6AMIAkSJQAXEBfwD7A/8CcYJ/APsBewF/AlECQAAX4kAAIgA7g/cAQAJTAVeAVAPTAFeBVQJEAByiQAFDAV8A34PfAt8CQAJfgP8BfwL4AtACX+JBAD0D5QE1AQ8BBQEFAR8BJQElAT0DwQAgYkAAIIIugiqC/4GqgSqBL4GqgWqBLoIgACGiUQBXAG8D1wA3AjsC/wH/Af8B/wLPAgACIeJAgBeB9YH1g/eB1YHFgz+A7YCtgr+BwIAi4kACAAI/AlUBVQDVAFUAVQHVAn8CQAIAASPiUgISAT8A0gBSAoACPwFVANUD1QJ/AkABJOJAAgMCPwL5AbkBuwC5ALkBuIK+gsCCAAElokIAYgAzg+4AAgJAAj8BVQDVA9UCfwJAASaiQAIOAgKCOwL6AbqAuwC6A7sCwoIOAgABKeJAAg8CPwL/Af8B/wDwAPsB+gL6AsoCAAEqokAAKQErALmD6wCoAj8BVQDVAFUD/wJAASziQAAMAHsB7gH6AeoB/wNVANUAVQH/AkABLqJAAAwCB4I3gvQB9oD2gPYD94LHggwCAAEvYkACD4I7gv+B+4H7gPAA/YH/Av8CzQI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AAAAAPwProsgACQI7A8ABAQCeAiCBQwCgAV4CAQIAAiviyAAJAjkBwgCQAJEAPwPRAAEAPwHAAgABrCLIAAiCOQPCAQAAMQHRAhECEQIRAj8CAAGsosgACII5AcAAogIiAT+A4gAiAD+D4gAgACziyAAJADoDwAEiAKoAKgA/g+oAKgEiAMAALaLEAASBvQBBAWADDoCIgGiCGII/gciACIAuIsgACIA7A8ABLAAjgCIAPgPiACIAIgAAAC5iyAAIgjkBwgCYAD4DwYAgAD+ByAIGAgIBrqLIAAiCOQPCAIgAJAHCAmGCIgIkAggBiAAvIsgACII5AcIBGAAGA6GBWAEBgUYB2AIAAC9iwAAJAjkBwgCAAz8AyQGxAEkAvwHAAgABL6LIAAiCOQHCAIgCqAIXgVCAkIGfgXgCCAIv4sgACIE7AcEAgAICAb4AUoISghICMgHCADAiyAAIgTkBwgCQAlIBEgD/gDIA3gEQAgAAMGLIAAiCOwHCAIACOQPBAgECPwPRAhECAQIxIsAACII7AcEBIACugCCAP4PggCyAIoAAADFiyAAJAjoDwgEAAD8DyQJJAkkCfwPAAgAAMaLIAAiBOwHCAIACHwGRAFEAEQARAF8DgAIyIsgACII7AcIAmACEAAOAPgPKAEoASgBKAHJiyAAIgjkDwgEAAD8DyQAJAHkDyICIgIAAMqLIAAiCOQHCAQAAlAISAkGBcgEUAIQAQAAzYsgACII5AcABgIA6gMqASoB6gkCCP4HAADPiyAAIgTsBwQCIACiD5oEhgSiBKIEngcAANGLIAAkCOgHAAIkAqQCrAKUD7QCrAIkAgAA1YsAACII4gcCBAgASATIBwgC/gAIBwoMCALXiyAAJAjoBwgCoACoAqgCvAioCOgHqACgANqLAAAiDOwDAA74AygAKALICX4EiAfqCAgG3YsAACQI6AcIAiAApA+kCPwIpAikCKIPIADeiwAAIgjsBwAAsg0uA8IE8AkCCv4LIgoCCuGLAAAiAOwPAAD4DxYA1AdUCFwK0AkQCAAE4osgACQI7AcABBAAyAOuAqgK6AsICPgHAADliyAAIgjsDwAEJAG0CKwEZwQkBhQFhAgAAOaLIAAiCOQHAAIIAEoBSgH4D0gBTgEIAQAA54sgACQI6AcAAhgACAEoAe4HqAiICJgEAADriwAAIgjkDwAA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gAT/BJgEmA8YAL+MAAQQBPwF9APsA/AB9AHsA+QD1AUMBAAAwIwAABQIzAvmCvQK7ALgAv4K8gryCx4IAAjDjBAACADcA8QL4AvqA+oD/gvqC+kDKgAAAMSMAAj8DVQFVAH8BUAA+A+sAqgCqAroBwAAx4wQCBII9Av0BuQG9AL2AuwG9Ab0CxQIAADKjAAI/A1UAVQF/AFIAOgJSAR+AogFbAgIBtOMIAAsCOwH/AbsAv4C7AL8AvwG/AcMCAAI24wAABwIzAXuBewF7AHgAfwF7gX8BRwIIADcjAAI/A1UAVQF/AUAAb4C6gmqBKoDvgiAB96MAAAcCMYP9g30DfYF9AX0DfYNxQ8cCAAA4IwACPwFVAVUAfwFIAC0B6QEpgSkBLQHJADijAAIPgj6B/4H+gf6A+AD4gfaB5oHJgggAOOMAAQ6CO4H7gf+B+8D7gP+B+4H7gc+CAIA5IwACPwFVAVUAfwDqAjsBBgH2ga8CbgJEATmjAAI/A1UAfwFAAjUDxQI0AeQBP4DEAwUBuqMIAAcCMwL7Ab6BvgC7gLqBuoG2gsKCAgA7YwABPwHVAFUA/wFAAGkB/4FpAW8BaYHIAD0jAAEeAJYAfwPWAE4AMAL7ArkAvQG7AcACPqMAAD8DVQB/AIICGwF+A9oAfgPbgPoBUAI/IwACPwNVAFUA/wGwA/sAv4C7Av+CuwHIAL9jAAArAh8BPwH/AP+A/wD/AP8B7QEpAQAAAiNAAj8BVQB/AUAAPwP5wrkCvwK5ArnD3wACo0AACgI/g9eDVwFXAV8BV4FXgXsDxwICAgPjQAMggO2CjoHugm7A7oFOgC6B7oPCgQAAB2NAAAACPwJBAQEBAQC9AEEBAQE/AkACAAAHo0ACAAI8AsQCBAEHgLUARQEFAT0BQQIAAAfjSAIEAj4CRQIFgQUAtQBHAQQBPAJAAgAACGNAAAUCNQLVAhUBlwBVARUBFQI1AsUCAAAIo0ACP4JAgT6AwIA/g4AAAgDiAhoCP8HCAAjjRAAFAjcC1wIXARcA14AXARcBNwFFAgAACSNAAAeCMAFQAReAkABZgRaBFoI1gsSACAAJY0ACP4IAgb6Af4MAABwCI4EiAN4BAgIAAAmjQAEfwf5AAEC/wIACP8HIAToACYDIQQAACeNAAAICMQLXghBBkQBTwRUBFQI0gsKCAAAKI0AAPAHDADsCSwELAK8ASoEKgTqBQgIAAApjQAAfA/0AAQC/AAADvwBNAzUAhQD8gQECCqNCAAICNQLVAhSBFoDUgB0BFQE1AUECAgAK40IACgI7AtqCFoESANoAGoEXATEBQgICAAsjQAI/g3yAwIC/gAADCQCIgYqCeIIIQgACC2NAAj8DeQDBAD8DhAAzAEKAcgJCAj4BwAALo0AAPwJBAT0AwQA/A4QAAgEDgQIBAgEOAQvjQAACAj8C2oIagZ+AWoEagRqCP4LCAgAADCNAAAoCLgJuAS4ArgIuAsICP4BCAYOCAgEMY0ACPwIBAb0AfwCAAhQBP4EUAdUCVAJAAQ0jQAI/A30AwQA/AYAAIAP/gSIBIgEiA8AADWNAAAgCPwLdAh0BHQDfgB0BHQE/AUgCAAAN40QAAgI3AtCCEgESANOAFgEagjiCxQAAAA4jQAAAAjcC1IIWwRAA1IATgRiBOIFHggAADmNAAhACN4LdghfBFYDVgBfBFYE1gUWCAAAOo0AABQI1AtOCGQGXAFABFwEVAjUCxwAAAA8jQAE/AL0AQQE/AAABugBCAh+BIgH6ggIBj6NAgg6COoFagR+BGoDagB+AmoE6gU6CAIAP40AAPwN9AMEAPwFwAD4D64CqAKoCugPCABBjQgABAjfBUAEagNqAGoCfgJqBOkFKggAAEKNAAj8BuQBBAT8BAAAyA/WBKQE1ARMD0AAQ40AAPwN5AP8DAAM+AMICEoI6g9ICEgIAABEjRAIEgjUBUAEaAJmA1YATAJUBNQFDAgAAEqNAAD8DeQDBAD8DgAAUANoCOYPaABIBxAES40AAPwN5AP8AAAI1A8UCNQHEAD+AxAMFgZMjQAA/A/0AQQE/AWAANQPfgVUBVgF1A8QAE6NAAj+BfIDAgD+BQAApAlUB/4BFAU0CQAAT40AABwIhgu0CLQEtgK0ALQEtgSFBRwIAABQjQAI/AkEBPQDBAD8DgAAvgDqC6oGqgm+B1SNAAj8B+QBBAT8BQAAqA+kBKYEtASkByAAVo0ACPQElAL+D5QB9AoACPgH1gMcCPQLAAhYjSAELgSeBV4EXgJeA0gAbAJeBJwFJAQkAFqNAAj8DeQD/AAACFoF/A9YAfgPXgX4CUAAW40AAKwIvAj8BbwEvgK8ALwE/AW0BCQJAABejSAALgicC04IfARAA24AXAROBJwFLAgoAGCNAAB+BAID+gACAn4AmAd/BXwFfwX8BwAAYY0AAPwN9AP8DAAA+AcOAOwPzAvIC9APAABijQAM4gO+Cv4H3gw/A/4M3gc+Af4PBgQAAGSNIAKkAaQIJAbkAT4IJAjkDyQApAAgAwACZo2ACSQE5AM+COQHJACACTQEygKIA3gECAhrjYAJJATkAz4I5AekAIAH5AE+COQHJACAA3CNIAgoBKgDKAQoBPwPKAkoCSgJKAkgCAAAdI0QBtQBFAL+A1QEVARQBAAE/gUIBBAEIAR1jRAG1AEUAf4DVARUBAAFzAQwBEwEggUABHaNIAykAyQE/gekCKQIAAgkCPwLJAgkCAAAd40QCNQHFAL+B5QIlAgACOQJJAokCjwKgAmBjRAG1AEUAf4DVARQBAQFUgUiBaQEiAQIBIWNAAjYBxgE/AeYCBAI1AtMCmQKZArcCwAIio0gDKgD/AeoCAAI+AmICAgKfgnICioKAAiLjSAGqAEoAv4DiAQgBBgFVgVUBVwF9AUABJWNIAaoASgC/AOoBQAFXATcBNwF3ATcBAAEmY0gDKgDKAL8B6gIAAj0CzAIvAiQCvQJAAifjQAIpAckAv8HpAgECPQLkAheCZAI9gsACKONFAAUBJ4D9AMQBP4EqgT+BQAE5AUcBQAEqI0QDNQDFAL+B5QIpAjvC14JSgluCN4LAACzjQAAAAg8BKQDJAQkCOQPJAkkCTwJAAgAALSNAAjeBxIE8geeAAAO/AEAAAQA/AAABwAIvo0ACN4HEgTyB54AAAj4DwAI/g9ACEAIAADDjQAI3gfyB5IEngQAACQMIgP+ACIDIgQgCMuNAAieDxII8geeDAAICAf/AEgLSgbKCUgAzI0ABN4HEgTyA14CAAhOBEgD/gBIA0gESAjRjQAE3gcSBPIHngQAAPoHtAj0CgQK/AkABNuNAASeDxIE8geeAAAM+APICX8GSAXYCAgI3Y0ABNwHFAT0A5wCAAD8DxQFFAUUBfQFAATfjQAI3gcSBPIHngAACPwPVAjUAVQGfAUACeGNAASeB/IHkgQOAuAM+AMOCPgHCADoAQAA6I0ABJ4H8gfyB44EIAC4A6gKrAq4CqgGqADqjQAAHgfyB5IEPgz4BxYA1AdUCFwK0AkQBO+NAAjeBxIE8geeBJAAiA/WCKQIvAjED4AA840ACN4H8geeBAAA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dAV0BfwPIASTjwAAfAJGAvQPIAD4D7QC8g+UARgI8AcAAJWPRAB0Ak4C5A9AAhAC9A60Cb4JtAJ0BRAJlo8AAHwBRgH0B0ABFAC0B7QF9gW0BZQHgACZjwAAdAJOAuQPFADuB7QK5A90BIoDeAQACJuPIAAkASwBPAEkAecPJAE0ASQBJAEgAAAAnI8AAEIFXgVWBdYFVgV3D1YF1gVeBQIFAACejwQAkg+SBP4EkgcQAEQBdAHGD3QBRAFAAJ+PAAT8A6QPpAS8BwAAWAFIAc4PaAFIAUAAo48AAEQJVAnHB3QBBAjwBJQC/g+UAvQEAAimjxAIzAfoAUAIEAf+AOAPCABaAcYPaAEAAKiPRABVCcYHdAEACHAG/gEAAFQBxw90AUAAqY9EAFUJxgd0AUAADgjkBwAAVAHHD3QBQACrjwgAWgnsB0ABHATyBIgEAARVAccPdAEAAK2PBADMD1IBegfWANYPAABUAccPdAFEAQAAr48IAFoJ7AdIAUgPawVoBwwAXQHvD0wBAACwjwAAAAz8A0QA1A9UCFQE1AFUAlQFVAlACLGPAACAAn4CIgbqBqoCKgpqCqoG6gJiAwACso8ADPwDbAnsCf4H7AnsBf4H7AXsBfwLQAm5jwAIIgTsAwgEAAgIC8gIPggICggK+AkABLqPQghGBMgHAAQECMQLPAgECgQKBAr8CQAIu49ICFIE1gMEBBAIEAgQCP8LEAgQCBAIAAi8j0IIQgTMBwAIAAqCCWIIPgjACAAJAAoAAL2PAAgkBOgDAAQECAQKBAr0CxQIDAgECAAAvo8gCCIE7AMABAgICAvICD4ISAiICAgLAAjBjyAIJgToAwAEJAgkCCQI/AsiCCIIIggABMKPAAgkBOgDCAQgCCQKJAr8CSQIJAgkCAAAxI8gCCQE6AMABDAECAmsCmgKKAooCggJAADFjyQIJAToBwAEJAgkCPQLJAgECPwJAAqACcePIAgiBOwDAAQICCgIyAgICggK/gkICAgIyI8kCCQE6AcACAQLxAg8CBQIFAoUCvQJBATOjwAIRgzIAwAE/AkECQAI/AsECAQJ/AgAANCPIAgkBOgHAAgQCtQJNAkUCVQJlAkUCgAI0Y9CCEIExAcACAAL/ggSCBII8gsSCBIIAADUjwAIQgTMBwAIAAv+CDIK0goSCdIKMgoCCtiPAAgiBOwDCASACEQIJAj8CwQIJAjECIAI2Y8ACCQE6AcACCgKKAnKCEwIuAgICQgKAADbjyAIIgTsAwAESAhIC/4ISAhICP4LSAhICNyPIAgkBOgHAAgQChQJ9AgUCPQLFAqQCQAA3Y8ABCIE7AMABFQEVARUBP4FVARUBMQFAADejwAIIgTsBwAEFAksCSYJ9AskCSQJBAkAAN+PIAgkBOgDAAQACfwIJAhkCOQIJAk8CgAI5o8ACE4EwAcEBfwEBgj8CwAI/AsECvwLAAjqjwAIJAToBwAI+AtICkgK/gtICkgK+AsAAOuPRAhEBMgHAAQACPgLSApOCkgKSAr4CwAI8I9CCEIEzAcABIgJaAgICP4LCAhqCIoJAAj0j5AI1AS0AwAE/AkECvQKlAr0CgQK/AsAAPePQghGBMgHAAgkC6gIYAj+C2AIqAgkCwAK+Y8ACCQE6AMIBGAICAv6CAwK+AsICOgIAAD9j0IIQgTEAwAE/AlUClYKVQpUClwKwAsACACQQAhCBMwHBAgACv4LKgpqCKoJXgpACgAAAZBCCEIEzAcABEgITgpICfgISglKCkgKAAgCkCAIJgToBwAEFAjUC1QKfApSClIK0gsQCAOQAAhECMgHAAScCEAK/gkACP4JQAqcCoAKBpAACE4MwAMIBOoIjgqICvgJiAiOCOoICAgJkAAIJAjoBwAIIAqsCWgIPgjoCygKKAogCQqQAAgiBOwHAAQiCPoLRggwCv4LAAg4CMAADZAAAJII9AaUBQAI9gsQCF4JEAmUCvILAAgPkAAIJAjoBwAELAgsC9wIXAicCqoKqgkgCBCQAAgiBOwDAAQSBaoIrgpSCuIJUgiKCAAEEpAgBCIE7AMABHQFVwXUBPwFVgRVBdwEAAQUkAAITgTABxAESAlUCFQK8glUCEgJUAkQCBeQAAgkDMgDEAQECHQK1ApUCtQL9AoECgAIGZAAAFQEfALYAwAE+AV4BXwFeAX4BQgEAAQakCAIIgTkAwAE+gmuCK4I+guuCK4K+gkAABuQAAgkBOgHQAguC/QIAAokCvwLJAokCgAAHZAACCYI6AcACEgK/gkICPwLEgjyCxIIAAAekAAA0gi8BpgFAAi8CrQK9Au0CrwKAAoAAB+QQghCBMwHAAh0ClQJ1Aj+C9QIVAl0CgQKIJAACCQI6AcABCAIrAuoCrwKqAqoCyAIAAAikAAIJgTgBwQIlAqSCq8K6guuCqoKCAoQCCOQAggmBOQDAAR8CVwJXAn+C1wJXAl8CQQJLpAACE4IwAcQCJQKVApUCP4LVAl8ChAKAAgxkAAIQgzMAwAE/gkCCOoJegnqCQIK/gkACDKQAAhGCMgHAAQQCP4LqAr8C6oKqAoICgAIOJBCCEQExAcQCHgKVgnWCHQI3AtQCnAKAAE7kCAIJAToAwAEnAhUCnwKVAlcCdQIHAgAADyQJAgoBOgHgAt8BWwN7A9sDWwN/A8ACAAAPpAACCIM4gMIBOgF/Aj8CwsI6ggEDOgPCABCkAAIRgTIAwAEKAluCdgIqArICa4IqAgICUWQQAhEBNgDAAX8CBQI1AnUCdQL9AncCQAIR5AACCQE7AcACP4Lagj+CX4Jagt+DMAPAABKkAAIRgzAAwQF/AgXCuQJDAhGCvQLVAhECEuQAAgiDOQDAAR6CXoJegn6C3oJegl6CQABTZAACCIE7AMABfwI1Au0CPYLtAj0C7wI4AtOkAAIQgjMBwAI4As+COIJegnqCT4I4AsAAE+QAAQiAuwDgALcBTwFvAW8BTwFPAf8BwACU5AgCCQE6AcABAgI+gu+CrgKvgr6CwgIAABUkAAIRgTIAwAE1An0CdQJ3gvUCfQJ1AkQCFWQAAhECMgHAAj8CtwL3AreCtwL/AqICgAIV5AACCIE7AMABO4IagpqCX8IagrqCi4IIARZkJAI9gaQBQAIuA6kDrwO9g+sDqwOpA6ACFyQAADRDLYCEAVCBPoJBgpcCPYLQgjBCgAAXpCQCPMEFAOABH4IAgvyCD4Kfgh1CXUKMAFgkAIIQgjCBwgEfAlcCdwI3gtcCfwJiAoACGOQAghCDMQDEAT8CfwK/Ar+CvwK/AqQCwAIZZAACCQM6AMABEwJfApkCuwLZApiCmoLQABokIAI1ggwBwQG9Al+DVQNRAsQCI4LeAoICmmQAAhGDMgDAAT0CTQI/Al2CfwJNAr0CQAIbZAACBEE9gMABP4Jvgq/Cr4Kvwr+Cx4IAARukAAEJgLoA4ACfAQUBXQEVgZUBXQEFAUAAHKQkAjUBLQHAAb8CQwItAqMCtwLjAq8CgAKdZAACCYI6AcABHwJbgtsCWwJfA3+D3wJBAF3kIAI1AS0AwAF/AjsC/wM7A78D+wMfAkACXiQAQgmBOQDgASuCu4KrgigCO4KrgquCggIepAECEQExAMQBPwN/Av8Cf4J/Av8CxAIAAh/kAAARAzIAwAF/AtUCtwLCAi4COwLtAioCICQAggsDOAHTAb8CX4JXAsQCA4L6AgYCwAIgZCQCNYEsAcACIQL9An+CfQJ9An+CPQLAAiEkAIIRAjEBxAEfgl6Cf4I+gt+CfoJngoQCIqQkAjWBLAHwAj8DfwLfgt8D/wP/AvACAAIj5AAAKQM6AMABPwPVAucC9QL3AvUC9wLAAqRkAAAAADcB1QJVAnUCVQJVAlUCdwJAAQAAJOQAAAUBCQCxAE0AQwCAAD8DwQAdAKMAQAAlZAAAAQA+gfQCtQK2gvQCtQK2gr6CwAIAACXkEAARABEAPwPRABEAAAA/A8EAHQCjAEAAKGQCAgIB/gALggoCOgHAAD8DwQAdAKMAQAAopAACEQO/AFEAEQA/AdEAAAA/A8EAHQCjAGjkCQAJA38AyQJJAn8BwAA/A8EAPQCDAEAAKaQgACkDKQD/wCkAKQAAAD+DwIAegKGAQAAqpAAAAQGNAGkCPwPJAAAAPwPBAB0AowBAACukAAA+AdIAv4DSAL4BwAA/A8EAHQCjAEAAK+QCAD+D0gESARIBP4PAAD8DwQAfAKEAQAAsZAABPwHJAQkAuQDJAIAAPwPBAB0AowBAACzkIQERAQkBPwHJALEAgAA/A8EAHQCjAEAALWQIACiD54EggSiBJ4HAAD+DwYAdgKMAQAAuJAAAv4JIgkiCX4IogsAAP4PAgB6AoYBAAC5kAgAGASUBJMEkgSeBOAP/gMCADoBxgAAALuQEABQAUgDVg7ICVAAAAD8DwQAdAKMAQAAwZAAAMgA+A+sAqgK6AcAAPwPBAD0BAwDAADKkEgEKASoAgwBqAEoAgAA/AcEAHQCjAEAAM6QAAT8B5QClgKUAvwEAAD8DwQAdAKMAQAA0ZBACEoESgP4AEgBTgYAAPwPBAB8AoQBAADTkAAAlgLyApoC0g+SAgYA/A8CAHoChgEAAN2QIACkCCQG/gHkD6QAAAD+DwIAegKGAQAA4ZAKAioB/g+qBKoEvgcAAP4PAgB6AoYBAADokCAAqA+kBKYEpASoDwAA/A8EAHQCjAEAAOuQAAB8AdQBfgFUB3wBAAD8DwQAdAKMAQAA7ZAEAvQC1ArWD9QC9AIAAPwPBAB0AowBAADvkAAApAikBBACzgMQAqQN/g8CADoCxgEAAPSQgAFIAP8PKAHAAP8PKAAAAP4PAgB6AoYB9ZBMCfwJTAn8B0oF+gUAAP4PAgA6AsYBAAD3kJgI3AajAQAE/gdSAn4DAAD+DwIA/gMAAPiQAALwArYC8A++AvACAAD8DwQAdAKMAQAA/ZAAAJQA1A9+BVQFXAXUBwAA/A8EAHwChAECkYAAvAC0C7wKqAq0BrwAAAD8D2QEnAMAAAmREAncBDIDgAD8B5YE/AYAAP4PAgD+AwAAGZEQANcH1QT9BdUFVwTQBwAA/g8CADoBxgAnkSgAGgjaClYJQA2+CUAA/g8CAHoChgEAAC2RAAr0CxYHvAM8C1YL5AP8DwQAdAKMAQAAMJEAACgJ7AaIA74BiALcD4AA/A8EAvwBAABMkQAA+g9+BD4FSgT6DzAAzggICQgI+AcAAE2RAAD6Dz4FOgVOBfoPAADiByIIIgh+CAAGUpEAABkEowMAAPkPSQU/BQkFPwVJBfkHAABXkQAA+g8+BX4F8g/4A4wFcASOBPgPAAAAAF2RAAD6D34FPgVKBfoPAAAkB+QEJASkByAIY5EAAPoPPgV+BfoPAAD+D4gEiAT+DwgAAABlkQAA+g9+BT4FSgX6DwAApAH8D6IAIgMAAGqRAAD6Dz4FfgX6D5gAxA+uCLwIxA9AAAAAbJEAAPoPfgU+BfoP8AD+ByAA/gcgAP8PAABxkUAAwg/UDtAO3g3ADOgM5g3WDtQOzA9EAHWRAAD6D34FHgX6DwAAKgEvCboPbAEqAQAAd5EAAPoPPgV+BfgPPAOqBKgEvgSoBwAAAAB4kQAA+g8+BX4F+g8AASwFmgW4AqwFKAgAAH+RAAD6D34FPgX6DwAA/A9UBNYAVAN8BAAEh5EAAPYPPgV+BfYPAAC8CqwKrg+sArwCBAKJkQAA+g9+BT4F+g8AACQBFAHGDzQBZAEAAYuRAAD6D34EHgX6DwAA5Ad/BWQFfwXkBwAAkpEAAPoPfgU+BUoF8A+eCKoKqg+qCr4KAACckQIA+g9+BD4F8g94CFQH/gDUB/wLAAQAAKuRAABeAPoH/gXuBv4GvAb2B9IH9gdUAAAArJGQALwPmAu+CYANuA28DZwP3A/0C5QPkAC0kQIA+g9+BD4FSgS2D2oI/w3qCv8K6w7+C8eRQARUAlQCRAHMAOQPxABiAXICSgJABAAAyJEAAJYBUgD+B1UAAAb/ASEA4QAhAz8MAATKkQAAKgOiAP4PowCqAKACrgKSD6oCpgIiAsuRBACsAfwPogCoAD4C+gK+AroHvgL6Ai4CzJEAAAAEvgSqBKoEqgT+B6oEqgS+BAAEAADNkQAAEAT0BfQF9AX8B/QF9AXyBfIFEAQAAM6RAAB8CVQJ/AdUBXwBAAgkCPQPLADkAAAAz5EAACAE/Af8B/wH/Af8B/wH/Af8ByAEIADRkRAAsAiQCZgLlgjxD5IIlAiYCpAIMAgAAN2RUAhYC1QI8gdUBEQFAAAgAP4PIAAgAAAA45FQCFgLVAjyB1QERAUQAM4ICAkIDPgDAADnkUAIWAtUCPIHVAYADP4DAAD8BwAA/g8AABWSUAhYCfYHVARUAQAIRAj8D0QIxA98CEAAHpJQCFgLVAjyB1QEWAUGASUJJAkEBfwDAAA0klAIWAtUCPIHVAUQBEgA1w9SAEwE0AcQAESSUAlcCPIHVAREARAETgRIA/4ASANIBEgIcZJQCFwJ8gdUBAAN+AMIAAgH7gQIBIgHAAh0kkAIXglAC2AJXgnQD1YJZA00CVQJRAgAAICSUAhYC1QI8gdUBwAA/g9KCMoBSgZ+CQAIg5JQCFwJ8gdSBAQNZAQ0AywAJgC0DzQIRAaFklAIXAnyB1IEhAT+DwIA6gMqAcII/gcAAJiSWARUBfIHUgREBRACGAGUD+YEnASEDwAArZJQCFwF8gdUBFQBAAioBP4FqAaqCaoIAAazklAIXAX2B0AFEAD8BJIGkAGSD/QIGAgQBLeSQAhQCVwE8gdEBggN9gcQAF4BEAn2BwAA0pIAAFAIXAXyB1QFAABIBa8Fkg+uBaIFQATqklALWAT2B0gEWAUIAOgPqAL+D6gC6g8AAO2SUAlYBVQE8gdUBAABegzMA0gAzA96CAAG/JIAAFALXAjyB1QH/AsMBKQD5AMMC/wHAAAEk1AIWAn2B1QERAUABNgCVgjUD3QATAVABSKTUAhYBfYHVARUAQAIKAmeBRgHWgcqC6gIJpMoBC4F+QMqBioHgAe+AOsPqgCqBL4DAAArk1AIWAlUBPIHRAcABL4E6gOqBqoJvgcAAC+TWAhUCfIHVAQEBSQA/gdkBWQFfgXkBwAAMpNQCFgJ9gdUBAAFogQqAOoPqgEqAr4CoAQ2k0gLXAjyB1QERAEUAFQP1Ah+CNQDVAVACUqTWAhUCfIHVAQEBfQEtAKUAf4PtAH0AgQES5NQCVgI9gdUBQQA4A8+ALIDqgI+CeAHAAB1k0gIXAnyB8QHMAwuA+AEqgb/C6oKvgoICH6TaAhsCWoE+QdqBwIM/giuCv4Prgr9CgAIjJNIBM4E+QdKBewFrQL+D6wA/A+vAvwEAACWk1AIWAhUCfIHVAQACfQLsAq+ArAC9gsACK6TQAhQC1wI8gfUBQAA/AvsCu4C7Ar8CwAK4ZNQCFgIVgnxB1IECg3qCG4HawFuD+oJCAQYlFAIXAXyB1QFAADyC3oLcwvzD3ILfgvyCzWUMAhaCvwHHAd0ALQHvgdUDP4FEAfWCAAGUZRQCFwJ8gcEB34Aqg/uCboPAAlOD0gJSA9wlAgIXAnyB0QFCADoD8QHkgL0D4QCaA8AAH2UUAhcBfIHVA0ACBgI3gXcA9wL3gusCygAiJSYAIYI9Q+UBIQEIAAgACAA/g8gACAAIACJlAAAmACGCPUPlASUBAAABAgECPwHBAAEAJOUAACYAIYI9A+UBKACHABKAIgJCAj4BwAAmZSYAIYA9Q+UBJQEAADyAIIA/giSCJIHAgCdlJgAhgj1D5QEAAToAQgBCAH+BwgJCAnoDZ6UmACGCPUPlASEDIAIOAgABP4DgAEIADAAn5SYAIYI9Q+UBAQE8AGQAJAA/g+QAJAA8AGglLgAhgjlD6QEBADwDxACkAF+AJAJ8A8AAKKUmACGAPUPlAQAAP4PAgIyAfoBAgj+BwAApZS4AIYI5Q+kBKQAAAz8AyQBJAkkCfwPAACmlAAAmACGCPQPlASEDDAIDgboAQgDOAQICKeUmACECPYHlASEAhAATgJICUgJCAz4AwAAqZSYAIYA9Q+UBAQEEAHuAQgJyAsICPgHAACulJgAhgj0D5QEhAwACEIO/glCCEIO/gkACLGUmACGCPUHlAQAAsgISAT+BEgHKgmqCQAEs5SAAKwI6geoBIACEAD8D5AEkASQBPwPEAC7lJgAhgT1B5QElAIEAIAPgAT+BJAEkA8AAL6UmACGCPUPlAQABP4BkgCSAP4PkgCSAP4BwZSYAIYI9Q+UBBQEwADODMgC/gFIAkgEQAjDlJgAhgj1D5QEhAQQAEgBVgJEDcgAEAAAAMWUmACGCPUHlASUAgAAvg+CBIIE/gTADwAA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AAT+AtAI3gfQAPYCAASblgAA/w8ZAO8AbAa3AK4EoAenALgCrgIiAJyWAAD+DwIAOgHGABAC9AL8AvYP/AL0AhACoJYAAP4PMgDOCQQEbAFkDWwJZAtyCeoBAAyjlgAA/g8yAM4AAAnuBZgDvwCYA+oPqAIAAKeWAAD+DzIAzAhABLYHgASqCfgMyAvOCCgJqJYAAP4PMgDMCOIHFATUC+wI7gl8DewPBAiqlgAA/g86AcYIUAS4AvQAEwj0BrgE6AwIALGWAAD+DwIB/gDADfYB8gf6C/IN+QH1DaAItpYQBFQFVAVUAlQK/gdUAVQCVAO8BJAEAAC7lhAIEAl4CXwJeAd4BXwFeAV4B3gJSAgACL6WAAAUBqQB5AAcAyAA/g+oBPoHqASoBAAAwJYAAFAAWADED+AK3grwCvAPxArECtgKEADBlgAG/gFCAPoHAgAiAPoHUgX6B1IFUgUAAMSWCAzoAx4IyAcIBCAD/AeqBKgE/AeqBKgExZYkBrwBZAj8ByQA8A+uBKgE/geqBKgEAADGlggICAV8BV4DXAPcD34BXQNcBVwFRAkAAceWAAAEDvwBrADsD+wK7ArsD+wK7Ar8CgQIzJYAAPAPAAT+BwAE/gcwAv4PqAT6B6gECATPlhAAuASmBLQE7A8gAPgPrgSoBPoHqAQIBNGWJAC0BI4ChA+8AkAEMAD+B0gF/AdKBUgF1ZaAD3wANAe0AjQJ/AcwAPwPqgT0B6gECATWlgAA7gSqBPoDrgLgBjAA/g+oBPoHqASoBNmWAAAICL8EvAS+BbwGiAK+ArwFvgW8BCQE3JYgAKQGlADGD7QCAAD+D6gEqgT6B6gEqATelgQIfAl8BaoDUg04AfwPqgSoBP4HqAQIBOKWgA/0ANQD1gLECPQHIAD+DygF/AcqBQAE45YAAPQJ1gX0A9YF9AUgAP4PqAT8B6oEqATolgQA9A8UAFQBFAD8DxQAVAFUChQI9A8EAOqWGADKCsoKygqKCr4KigrKCsoKyg8YAAAA75YACJgIygjqCcoGngTKBIoG2gnKCJgIAAjwlgAKGAmaBboFCgM+ARoJOgmKBxgBAAIAAPKWAAEMBWUFZQdFBV8FRQVlB2UHBQ0cCQAA85YcDMYDdgh2CX4HRgF2CXYJdglGCVwHAAD2loAAmACaAboFSgXeBcoFWg26C4oBmACAAPeWGADKD8oKygqKCr4PigrKCsoKyg8YAAAA+ZaAAJgA+gf6CuoK/grKCvoLegrKCRgEAAD7lgAAGADaB/oCygLeB9oK+grKCxgIAAYAAP6WAAFYC1wLXAvMBtwC3AJ8C0wLXAcAAAAAAJcAAFgAWg96AUoP3gFaD3oBSglYB0AAAAAElwAAHgAOCK4HhgHeBYYG1gLeCoYHHgAAAAaXAAhMCeYFdgsmCD4NRg32D3YNZg0MDQAAB5cYDNoDegn6B8oF3gXKB/oF+gXKB1gLAAkJlwAADAFmBeYG5gbGB94Gxg7mDuYHTAUAAAqXAAg4CYoLqgmKD74Jig+qD6oJCgs4CwAIDZcAAQwBpg+2C4YL3g+GC7YLpguMCAAAAAAOlxgCWgtKC2oLyg9uD0oPWgf6B0oLWgsYCBOXAAAOAA4I1guuCq4GBgKuBr4K5gsOCAAEFpcAAJgEigK6D4oCPgCKBroBug+KApgEAAQclwAAmAS6AroPugI+AL4H+gX6BfoFyAcAAB6XGADKD/oF+gXKBd4MCgj6C/oFygXYCwAIJ5cAAAAMTAPmD/YBRgMeCsYGdgPmC0wHAAEylxgIyg16CXoPygueAooOegv6CkoPWAIAADiXAABMB+YH9g/GB14DBgz2A/YC5grMBwAAOZcABuwBdQdtBW0FBQcvAuUCpQ+tAu0CoABClwAO7AFlBP0E/QZ1BOcHZQb9BvUG9QQgAEiXAAgMCeYL/gtGCa4PpgnmDU4LtgjkCAAAUpcQABQA/A+8ArwCvgK8ArwKvAr8BxQAEABWlwgC6AIOAugBAAD8D7wCvgK8CrwK/A8UAFmXEADcD9wC3grcDxAAWAlWCfQHXAHwAUAAXJcQCNwH3ALeCtwHAACIAqQK6geiAuoDgABelwABKAEoASgB/g8AAAAA/g8oASgBKAEAAWCXAAQIB3wHXgdcD1wAXgBcD1wHfAcIBwAEYZcADvwBBAQ0B3QHVA8GADQPdAc0B1QHAABilwAA8g8SBPIHXgVSBfIHEgQSBPIPAgAAAGmXAAAEAuQCvgK0AvQPtAK0Ar4C5AIEAgAAdJcEAu4C/A+uAuQCAAIwAP4PAAD+BxAICAZ2lwQA7gKsAvwPrgJAAP4HQgh+CEII/ggABouXAADkAq4C/A/uAgQKIAgkCb8PJAkkCQAAjZcEAO4CrAP+DuQCAABICcYJdAZEBegEQAiRlwQC7gL8D64CZAjgBwQIkAt+CNAIEAsAAJiXBAD+ArQC9A++AkAI9AcQAF4BEAn0BwAAoJcEAv4C9A+0Au4C/AaKA+gP6AGICvgHAACtlwQC7gL8D24A/g98CawH/ASsCPwIBAgAANOX/AKsAq4PrAb8BgAE7AeuBawPrAXsBQgE5pcAAJIAkgCSAJIA/w+SAJIAkgSSBIADAADnl6gAqAD8D6gAqAIAAXQMhAN8CAQI/AcAAOmXAAD0AtQC3g/UAvQCAACoAP4PqACoBIgD7ZcAAFAFUAVQBf4HAAQABP4HqASoBKgEAADzlxAAFADUB1QFVAVWBVQFVAVcBdQHFAAQAPWXIADoB2YFdAXkByAAEAEuBagICAj4BwAA9pcQANwHVgVcBdQHBACwB44EogSiBJ4HAAD7lxAA3AdVBVoF1AcEAPgPVANUA1QD/A8ACP+XlAC+ANUH4Af+B+4HzgfAB94HxgeaAAAAAZgACAQI/AusBqwGrAKsAqwGrAb8CwQIAAACmAQIBAj8DwQAAAj8C6wKrAKsBqwG/AsAAAWYBAEEAfwBBAEECPwHrAasAqwGrAb8CwAIBpgACPwHAAD4AwAA/g8AAPwHrAasAqwK/AsImEgIyAQkBBADBAj8C6wKrAKsAqwK/AsACBCYJAgkCPQPPADkCAAI/AusAqwCrAr8CwAAEZgAABQH9AAUAvQDAAj8B6wGrAKsAvwLAAgTmOgAiAD8D4gE6AIACPQHtAa8ArQK9AsAABeYAA74ASgMvAKoA1gI/AusCqwCrAb8BwAIGJgAAFgA1AdSAMQJDAT8B6wCrAKsBvwPAAAtmAAAfAhMBUwEfAcADPwJrAqsAqwG/AcACDuYEADeBRAEfwIUAZAA/g1WA1YDVgH+BQAEPJgAAHgGWAH8D1gBOAr8CawGrAKsBvwHAAhGmAAEvASsAvwPrAKcCPgJrAqsAqwG/AcACEyYQAxcA1wE3AdcCQAM/A1cCVwJXAn8DQAMTZggAawPtAVWBaQHDAD8B6wGrAKsCvwLAABPmAAM7AM8CK4JLAUkAvwLrAqsAqwG/AcACFSYAAzkAywIpgosBSQA/AusCqwCrAr8CwAIWJgAD/wAfAasAKwP/AEACPwHrAasAvwLAAhbmAQK/AvcCt4C/AsAAPwHrAasAqwG/AsAAF6YAACsBJgC3gGcAogI/AusBqwCrAL8BwAIZ5gADvoBKg+qB9oHgAcCCPoLrgaqAvoHAgxvmAAB/A3aARoJ+gO8AwAJ/AesBqwC/AsACHWYAAAECPQLFAgUBBQC3AEUBBQI9AsECAAAdpgAAAQIBAj8BwQAAAj6CQoE7gMKCPoJAAB3mAAAAAD8AxACEAEACPQFFATcAxQE9AkECHmYBAEEAfwBhAAACPoFCgQKA+4ACgIKBPoFepgADPwDAAD4AwAA/g8AAPwIDAbsAQwC/Ax7mAAESAQmApABAgj6BAoC7gEKAAoC+gQCCH2YAAASBvIBEgDyBwAC+ggKBu4BCgD6DgAAfpj8DwIA+gcKBPoCAAj6BAoG7gEKAPoOAAB/mAAA9ACEAP8PhARgAvoICgbuAQoA+g4ACIGYMAwMAuIJIAjvBxAA+gkKBO4DCgj6CQAAgpgwBAwD4gIAAt4HAAD6DAoC7gEKAPoNAASEmCIAKgjqBzYA4gAACPoECgbuAQoA+g4AAIWYAAjwB5AAngD0AQAI/AkMBOwDDAj8CQAIhpgQAFABTAJqDdAAAAj0BBQG3AEUAPQOAAiHmAAO/AEkDD4D5AYMAPAEFAbcARQA9A4ACIiYAACiCJIIige2BAAM+gkKBO4DCgj6CwAAiphIBFgESAP+AHgDSAjgBBQC3AEUAvQEAACRmCAAuAsgCPwFKAMgCPQJFATcAxQE9AkAAJOYAAAsCKwHvACqBwAE8ggSBt4BEgTyCQAAlpgABM8C1AHUD7IBAAryCBoG1gESBPIFAAiXmAAE/ATUAvwP1AH8AOAJFATcAxQI9AkAAJiYQAxcA1wE3AdcCQAM9AwUC9wIFAr0DAQMnJgACPIHGgGzBKoCEgj6BAoC7gEKAPoOAACdmKwAFAZeBXQFlA4cAPQJFAbcARQA9A0ABKCYBAr8C+wK7gL8CwAA9AkUBNwDFAj0CwAApJgACPwL/Av+C8wLPAPwCAoE7gMKCPoJAAComAAAAA78AQQE7AUsBfwHLAXEDPwHAAgABLGYAA7+AUIE+gNCAv4AAAPYBFYJUAncDQAAxJgEAPQN/AH8B6QP/gdmBPYD+gP6BwQIAATGmEAGygFqAGcG6wFiDP8DYQT9A2EH/wEABs6YAAAADv4BAgQaAqIB4gAaBwIA/gcACAAG0pgoBMoEDgLsAwAK/AcEAvQBBAL8BwAMAADYmHQN1AH8CdQH/APUASQN/AMUBuQB/AcADNuYUAhSBvoBQgBCAPoPQgBCAM4DFAUqCUgF3pgAAAQABAAEAAQABAAEAPwAIAdQCIgIiAbfmAAAEAAQCPgPtAiyCbQCtAb4CZAIEAgAAO+YCATkB9IE0gT0BgAO/gFiDKIFIgPiBAAI8pgIBPQHsgSyBPQGIAAcDIoD+AAIAzgECAj8mBAE/AeyBLIE9AYAAOwDLAHsCQQI/AcAAP2YCAAIBPwHugS6AvQGAAD4A5YE9AQEBPwE/pgQBPwHsgS6BPIGNAToASYA/A8kAOQDAAAFmQQA8g9aCVoF8gkAAIoM+gOIAP8PiQAAAAqZgACUAFwI/g/cCdwJ3AfcBf4NXAiUCAAAEJkQAJAAqAjuD9wLgAO2B9YHlgWuCKIAAAATmQQI8gdxBnUDIQSJBP8DWAAfAvgD2wYQABiZCAjsD1oJVgX0DQQAlAKUCPMHlACEAogEKJkQBPgHtASyBOwGHAD0D5QFlgWUBfwHAABSmQAA8A++BLIE9A5AAGoNegNvASoP+g0oBWWZMAAMCOoPCAQ4AAAO/AEEAAQA/A8ACAAGbZkwAAwIygcYAAAO/AE0DNQCFAPyBBIIAABumXAADAjqDwgEOAIACDAEDgPoAAgDKAQYCHCZIAAUAMoPGAIAAOgDJwAkAPwPJAAkAuQBcZlgABQAyg8YBEAA8AcsCSgJ6AsICvgJAARymTAADAjKBxgCCADiAyoBKgHqCQII/gcAAHWZcAAMCOoPCAQwAAQE/AeUBJQElAL8DwQCdpkgABQIygcYAggIoASuA7gApA/UCJQIAAR6mTAACgjlBwQCCApgCBQEhQOGAwQEdAhABHyZIAAUCMoPCAS4AoEI+geIAIgA/A+LAIAAf5kgABAAzg8YBIAClAj8DxAE/gKQBVYIAAaAmSAAHADKDwgEGACQBpgAlAjyD5QAmAKQBIGZIAAUCMoHGAIACFQJxAVsAkQDwgRaCEAAhZkgABQEygcIAjgA0A9IBQYFRARcBcQPAACGmSAAFATKBxACBAD8B/QHVQVWBWQFDAcAAIuZMAAMCMoHGAKQALgCbgQ8BWwJrAq4AIAAjZkgABQEygcYAwAIdAV2BXQD9AF2A3QFAAiPmTAAjg8oBBgEQAA+D7AK5A+cCoQKvA8AAJKZEAAcAOoHCAFgBN4F/gbeAv4G3gX+BAAAlpkAAAQA9A9XBVQFXAVUBVQFVwX0DwQAAACZmZAAVABUD7QKlAq8CpQKsgrSCtIPUACQAKiZAAC8ArwC/g78D/QP+A72DvIP/g7YAgACrJkACAAM/AFUAVQFVAH8DVQBVAtUCQAHAACzmQAG/gCqB/4CqgoAB/wHEAj+CRAI+AgABsGZAAb+AKoC/gmqC6oHAADWDAgDDgXRBBAIxZkABv4AqgP+C6oOgA3+AyIA4gAiAz4MAADGmQAG/gCqBv4CqgsAB/4PAgSiBXIEigUABdCZAA7+AKoG/g6qCaoHAACKCPoPjAiICAAI0pkABv4Aqgf+AoIKEAfMASoB6AkICPgHAADVmQAAFAjMBeYB5AXsAeAD/gHyA/IFHgMAANuZAAN/ANUDfwNVBcEDHAwkA/8CJAQ8BAAI3ZkABv4Aqgf+A6oPAAAYAPgHjgiICFgIQAb/mQAG/gCqBP4Bqg8AADwHigS4Bq4JIAgAAA6aAAb+AKoD/guKByAApAe0Aq4LNAjUByAAEpoABv4Aqgf+A4oPQACiCWYJ+g9aCeYNIAgTmgAG/gCqA/4GqgoKB+gIJgXyAyQH6AkICBmaAAb+A6oB/gmAD/wH7APsB+oDagX6BwAAMJoADP4Dkgj+B0QA9gXcC9YL3Af2C1QGQAA3mgAO/gCqAv4LqgcAAPQJagnSD2oP5g8gCEWaAAb+BqoB/gmCBwAA/AdUCuwLnAnECwAAVZoABn4H/gKqCQIHqA/6A94F2gf5AKkPAABXmgAG/geqAf4NggNwCLgG9gBUDLgC0AwAAFqaEAg6DP4D+gP6C9oDyAvsA9YLrAssBiQAX5oADv4Aqgf+DgAHfga6AP4PbAAUAywEAABsmgAAAAIEAnQCRAJEAkQCRAp8CEAHwAAAAG6aAAJ6AkIJQgj+BwAAEAyQA34AkAEQBhAIb5oAAnoCQglyCM4HAAD+DwAA/gcAAP4PAABwmgACegJCCkII/gcAAPwHEAj+CQgI+AgABnGaAAB6AkIKQgn+B/gPBAgUC+QIlAkECgAAc5oAAnQCRAlECPwHAABUDIgCiANUBBIIAAB0mgAAegJCCkII/gcAAPgPSABKAEgA+AAAAHaaAAJ0AkQIRAz8AzAISAVIAv4FSAR4CAAAeZoAAnoKQgl6CMYHEADOAykB6AkICPgHAAB7mgAA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\"\n    }\n}\n","frame.ts":"namespace control.__screen {\n    let __update: () => void\n    let __updated = false;\n\n    export function update() {\n        if (__update)\n            __update()\n        __updated = true\n    }\n\n    export function setupUpdate(update: () => void) {\n        __updated = true;\n        __update = update;\n        update()\n    }\n\n    // low frequency fallback screen refresh\n    control.runInParallel(() => {\n        while (true) {\n            __updated = false\n            pause(200)\n            if (!__updated) {\n                __screen.update();\n                __updated = true\n            }\n        }\n    })\n}\n","image.cpp":"#include \"pxt.h\"\n\n#if IMAGE_BITS == 1\n// OK\n#elif IMAGE_BITS == 4\n// OK\n#else\n#error \"Invalid IMAGE_BITS\"\n#endif\n\n#define XX(v) (int)(((int16_t)(v)))\n#define YY(v) (int)(((int16_t)(((int32_t)(v)) >> 16)))\n\nnamespace pxt {\n\nPXT_VTABLE(RefImage, ValType::Object)\n\nvoid RefImage::destroy(RefImage *t) {}\n\nvoid RefImage::print(RefImage *t) {\n    DMESG(\"RefImage %p size=%d x %d\", t, t->width(), t->height());\n}\n\nint RefImage::wordHeight() {\n    if (bpp() == 1)\n        oops(20);\n    return ((height() * 4 + 31) >> 5);\n}\n\nvoid RefImage::makeWritable() {\n    ++revision;\n    if (buffer->isReadOnly()) {\n        buffer = mkBuffer(data(), length());\n    }\n}\n\nuint8_t RefImage::fillMask(color c) {\n    return this->bpp() == 1 ? (c & 1) * 0xff : 0x11 * (c & 0xf);\n}\n\nbool RefImage::inRange(int x, int y) {\n    return 0 <= x && x < width() && 0 <= y && y < height();\n}\n\nvoid RefImage::clamp(int *x, int *y) {\n    *x = min(max(*x, 0), width() - 1);\n    *y = min(max(*y, 0), height() - 1);\n}\n\nRefImage::RefImage(BoxedBuffer *buf) : PXT_VTABLE_INIT(RefImage), buffer(buf) {\n    revision = 0;\n    if (!buf)\n        oops(21);\n}\n\nstatic inline int byteSize(int w, int h, int bpp) {\n    if (bpp == 1)\n        return sizeof(ImageHeader) + ((h + 7) >> 3) * w;\n    else\n        return sizeof(ImageHeader) + (((h * 4 + 31) / 32) * 4) * w;\n}\n\nImage_ allocImage(const uint8_t *data, uint32_t sz) {\n    auto buf = mkBuffer(data, sz);\n    registerGCObj(buf);\n    Image_ r = NEW_GC(RefImage, buf);\n    unregisterGCObj(buf);\n    return r;\n}\n\nImage_ mkImage(int width, int height, int bpp) {\n    if (width < 0 || height < 0 || width > 2000 || height > 2000)\n        return NULL;\n    if (bpp != 1 && bpp != 4)\n        return NULL;\n    uint32_t sz = byteSize(width, height, bpp);\n    Image_ r = allocImage(NULL, sz);\n    auto hd = r->header();\n    hd->magic = IMAGE_HEADER_MAGIC;\n    hd->bpp = bpp;\n    hd->width = width;\n    hd->height = height;\n    hd->padding = 0;\n    MEMDBG(\"mkImage: %d X %d => %p\", width, height, r);\n    return r;\n}\n\nbool isValidImage(Buffer buf) {\n    if (!buf || buf->length < 9)\n        return false;\n\n    auto hd = (ImageHeader *)(buf->data);\n    if (hd->magic != IMAGE_HEADER_MAGIC || (hd->bpp != 1 && hd->bpp != 4))\n        return false;\n\n    int sz = byteSize(hd->width, hd->height, hd->bpp);\n    if (sz != (int)buf->length)\n        return false;\n\n    return true;\n}\n\nbool isLegacyImage(Buffer buf) {\n    if (!buf || buf->length < 5)\n        return false;\n\n    if (buf->data[0] != 0xe1 && buf->data[0] != 0xe4)\n        return false;\n\n    int sz = byteSize(buf->data[1], buf->data[2], buf->data[0] & 0xf) - 4;\n    if (sz != (int)buf->length)\n        return false;\n\n    return true;\n}\n\n} // namespace pxt\n\nnamespace ImageMethods {\n\n/**\n * Get the width of the image\n */\n//% property\nint width(Image_ img) {\n    return img->width();\n}\n\n/**\n * Get the height of the image\n */\n//% property\nint height(Image_ img) {\n    return img->height();\n}\n\n/**\n * True if the image is monochromatic (black and white)\n */\n//% property\nbool isMono(Image_ img) {\n    return img->bpp() == 1;\n}\n\n//% property\nbool isStatic(Image_ img) {\n    return img->buffer->isReadOnly();\n}\n\n//% property\nbool revision(Image_ img) {\n    return img->revision;\n}\n\n/**\n * Sets all pixels in the current image from the other image, which has to be of the same size and\n * bpp.\n */\n//%\nvoid copyFrom(Image_ img, Image_ from) {\n    if (img->width() != from->width() || img->height() != from->height() ||\n        img->bpp() != from->bpp())\n        return;\n    img->makeWritable();\n    memcpy(img->pix(), from->pix(), from->pixLength());\n}\n\nstatic void setCore(Image_ img, int x, int y, int c) {\n    auto ptr = img->pix(x, y);\n    if (img->bpp() == 4) {\n        if (y & 1)\n            *ptr = (*ptr & 0x0f) | (c << 4);\n        else\n            *ptr = (*ptr & 0xf0) | (c & 0xf);\n    } else if (img->bpp() == 1) {\n        uint8_t mask = 0x01 << (y & 7);\n        if (c)\n            *ptr |= mask;\n        else\n            *ptr &= ~mask;\n    }\n}\n\nstatic int getCore(Image_ img, int x, int y) {\n    auto ptr = img->pix(x, y);\n    if (img->bpp() == 4) {\n        if (y & 1)\n            return *ptr >> 4;\n        else\n            return *ptr & 0x0f;\n    } else if (img->bpp() == 1) {\n        uint8_t mask = 0x01 << (y & 7);\n        return (*ptr & mask) ? 1 : 0;\n    }\n    return 0;\n}\n\n/**\n * Set pixel color\n */\n//%\nvoid setPixel(Image_ img, int x, int y, int c) {\n    if (!img->inRange(x, y))\n        return;\n    img->makeWritable();\n    setCore(img, x, y, c);\n}\n\n/**\n * Get a pixel color\n */\n//%\nint getPixel(Image_ img, int x, int y) {\n    if (!img->inRange(x, y))\n        return 0;\n    return getCore(img, x, y);\n}\n\nvoid fillRect(Image_ img, int x, int y, int w, int h, int c);\n\n/**\n * Fill entire image with a given color\n */\n//%\nvoid fill(Image_ img, int c) {\n    if (c && img->hasPadding()) {\n        fillRect(img, 0, 0, img->width(), img->height(), c);\n        return;\n    }\n    img->makeWritable();\n    memset(img->pix(), img->fillMask(c), img->pixLength());\n}\n\n/**\n * Copy row(s) of pixel from image to buffer (8 bit per pixel).\n */\n//%\nvoid getRows(Image_ img, int x, Buffer dst) {\n    if (img->bpp() != 4)\n        return;\n\n    int w = img->width();\n    int h = img->height();\n    if (x >= w || x < 0)\n        return;\n\n    uint8_t *sp = img->pix(x, 0);\n    uint8_t *dp = dst->data;\n    int n = min(dst->length, (w - x) * h) >> 1;\n\n    while (n--) {\n        *dp++ = *sp & 0xf;\n        *dp++ = *sp >> 4;\n        sp++;\n    }\n}\n\n/**\n * Copy row(s) of pixel from buffer to image.\n */\n//%\nvoid setRows(Image_ img, int x, Buffer src) {\n    if (img->bpp() != 4)\n        return;\n\n    int w = img->width();\n    int h = img->height();\n    if (x >= w || x < 0)\n        return;\n\n    img->makeWritable();\n\n    uint8_t *dp = img->pix(x, 0);\n    uint8_t *sp = src->data;\n    int n = min(src->length, (w - x) * h) >> 1;\n\n    while (n--) {\n        *dp++ = (sp[0] & 0xf) | (sp[1] << 4);\n        sp += 2;\n    }\n}\n\nvoid fillRect(Image_ img, int x, int y, int w, int h, int c) {\n    if (w == 0 || h == 0 || x >= img->width() || y >= img->height())\n        return;\n\n    int x2 = x + w - 1;\n    int y2 = y + h - 1;\n\n    if (x2 < 0 || y2 < 0)\n        return;\n\n    img->clamp(&x2, &y2);\n    img->clamp(&x, &y);\n    w = x2 - x + 1;\n    h = y2 - y + 1;\n\n    if (!img->hasPadding() && x == 0 && y == 0 && w == img->width() && h == img->height()) {\n        fill(img, c);\n        return;\n    }\n\n    img->makeWritable();\n\n    auto bh = img->byteHeight();\n    uint8_t f = img->fillMask(c);\n\n    uint8_t *p = img->pix(x, y);\n    while (w-- > 0) {\n        if (img->bpp() == 1) {\n            auto ptr = p;\n            unsigned mask = 0x01 << (y & 7);\n\n            for (int i = 0; i < h; ++i) {\n                if (mask == 0x100) {\n                    if (h - i >= 8) {\n                        *++ptr = f;\n                        i += 7;\n                        continue;\n                    } else {\n                        mask = 0x01;\n                        ++ptr;\n                    }\n                }\n                if (c)\n                    *ptr |= mask;\n                else\n                    *ptr &= ~mask;\n                mask <<= 1;\n            }\n\n        } else if (img->bpp() == 4) {\n            auto ptr = p;\n            unsigned mask = 0x0f;\n            if (y & 1)\n                mask <<= 4;\n\n            for (int i = 0; i < h; ++i) {\n                if (mask == 0xf00) {\n                    if (h - i >= 2) {\n                        *++ptr = f;\n                        i++;\n                        continue;\n                    } else {\n                        mask = 0x0f;\n                        ptr++;\n                    }\n                }\n                *ptr = (*ptr & ~mask) | (f & mask);\n                mask <<= 4;\n            }\n        }\n        p += bh;\n    }\n}\n\n//%\nvoid _fillRect(Image_ img, int xy, int wh, int c) {\n    fillRect(img, XX(xy), YY(xy), XX(wh), YY(wh), c);\n}\n\nvoid mapRect(Image_ img, int x, int y, int w, int h, Buffer map) {\n    if (w == 0 || h == 0 || x >= img->width() || y >= img->height())\n        return;\n\n    if (img->bpp() != 4 || map->length < 16)\n        return;\n\n    int x2 = x + w - 1;\n    int y2 = y + h - 1;\n\n    if (x2 < 0 || y2 < 0)\n        return;\n\n    img->clamp(&x2, &y2);\n    img->clamp(&x, &y);\n    w = x2 - x + 1;\n    h = y2 - y + 1;\n\n    img->makeWritable();\n\n    auto bh = img->byteHeight();\n    auto m = map->data;\n    uint8_t *p = img->pix(x, y);\n    while (w-- > 0) {\n        auto ptr = p;\n        unsigned shift = y & 1;\n        for (int i = 0; i < h; i++) {\n            if (shift) {\n                *ptr = (m[*ptr >> 4] << 4) | (*ptr & 0x0f);\n                ptr++;\n                shift = 0;\n            } else {\n                *ptr = (m[*ptr & 0xf] & 0xf) | (*ptr & 0xf0);\n                shift = 1;\n            }\n        }\n        p += bh;\n    }\n}\n\n//%\nvoid _mapRect(Image_ img, int xy, int wh, Buffer c) {\n    mapRect(img, XX(xy), YY(xy), XX(wh), YY(wh), c);\n}\n\n//% argsNullable\nbool equals(Image_ img, Image_ other) {\n    if (!other) {\n        return false;\n    }\n    auto len = img->length();\n    if (len != other->length()) {\n        return false;\n    }\n    return 0 == memcmp(img->data(), other->data(), len);\n}\n\n/**\n * Return a copy of the current image\n */\n//%\nImage_ clone(Image_ img) {\n    auto r = allocImage(img->data(), img->length());\n    MEMDBG(\"mkImageClone: %d X %d => %p\", img->width(), img->height(), r);\n    return r;\n}\n\n/**\n * Flips (mirrors) pixels horizontally in the current image\n */\n//%\nvoid flipX(Image_ img) {\n    img->makeWritable();\n\n    int bh = img->byteHeight();\n    auto a = img->pix();\n    auto b = img->pix(img->width() - 1, 0);\n\n    uint8_t tmp[bh];\n\n    while (a < b) {\n        memcpy(tmp, a, bh);\n        memcpy(a, b, bh);\n        memcpy(b, tmp, bh);\n        a += bh;\n        b -= bh;\n    }\n}\n\n/**\n * Flips (mirrors) pixels vertically in the current image\n */\n//%\nvoid flipY(Image_ img) {\n    img->makeWritable();\n\n    // this is quite slow - for small 16x16 sprite it will take in the order of 1ms\n    // something faster requires quite a bit of bit tweaking, especially for mono images\n    for (int i = 0; i < img->width(); ++i) {\n        int a = 0;\n        int b = img->height() - 1;\n        while (a < b) {\n            int tmp = getCore(img, i, a);\n            setCore(img, i, a, getCore(img, i, b));\n            setCore(img, i, b, tmp);\n            a++;\n            b--;\n        }\n    }\n}\n\n/**\n * Returns a transposed image (with X/Y swapped)\n */\n//%\nImage_ transposed(Image_ img) {\n    Image_ r = mkImage(img->height(), img->width(), img->bpp());\n\n    // this is quite slow\n    for (int i = 0; i < img->width(); ++i) {\n        for (int j = 0; j < img->height(); ++j) {\n            setCore(r, j, i, getCore(img, i, j));\n        }\n    }\n\n    return r;\n}\n\nvoid drawImage(Image_ img, Image_ from, int x, int y);\n\n/**\n * Every pixel in image is moved by (dx,dy)\n */\n//%\nvoid scroll(Image_ img, int dx, int dy) {\n    img->makeWritable();\n    auto bh = img->byteHeight();\n    auto w = img->width();\n    if (dy != 0) {\n        // TODO one day we may want a more memory-efficient implementation\n        auto img2 = clone(img);\n        fill(img, 0);\n        drawImage(img, img2, dx, dy);\n    } else if (dx < 0) {\n        dx = -dx;\n        if (dx < w)\n            memmove(img->pix(), img->pix(dx, 0), (w - dx) * bh);\n        else\n            dx = w;\n        memset(img->pix(w - dx, 0), 0, dx * bh);\n    } else if (dx > 0) {\n        if (dx < w)\n            memmove(img->pix(dx, 0), img->pix(), (w - dx) * bh);\n        else\n            dx = w;\n        memset(img->pix(), 0, dx * bh);\n    }\n}\n\nconst uint8_t bitdouble[] = {0x00, 0x03, 0x0c, 0x0f, 0x30, 0x33, 0x3c, 0x3f,\n                             0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, 0xff};\nconst uint8_t nibdouble[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,\n                             0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};\n\n/**\n * Stretches the image horizontally by 100%\n */\n//%\nImage_ doubledX(Image_ img) {\n    if (img->width() > 126)\n        return NULL;\n\n    Image_ r = mkImage(img->width() * 2, img->height(), img->bpp());\n    auto src = img->pix();\n    auto dst = r->pix();\n    auto w = img->width();\n    auto bh = img->byteHeight();\n\n    for (int i = 0; i < w; ++i) {\n        memcpy(dst, src, bh);\n        dst += bh;\n        memcpy(dst, src, bh);\n        dst += bh;\n\n        src += bh;\n    }\n\n    return r;\n}\n\n/**\n * Stretches the image vertically by 100%\n */\n//%\nImage_ doubledY(Image_ img) {\n    if (img->height() > 126)\n        return NULL;\n\n    Image_ r = mkImage(img->width(), img->height() * 2, img->bpp());\n    auto src0 = img->pix();\n    auto dst = r->pix();\n\n    auto w = img->width();\n    auto sbh = img->byteHeight();\n    auto bh = r->byteHeight();\n    auto dbl = img->bpp() == 1 ? bitdouble : nibdouble;\n\n    for (int i = 0; i < w; ++i) {\n        auto src = src0 + i * sbh;\n        for (int j = 0; j < bh; j += 2) {\n            *dst++ = dbl[*src & 0xf];\n            if (j != bh - 1)\n                *dst++ = dbl[*src >> 4];\n            src++;\n        }\n    }\n\n    return r;\n}\n\n/**\n * Replaces one color in an image with another\n */\n//%\nvoid replace(Image_ img, int from, int to) {\n    if (img->bpp() != 4)\n        return;\n    to &= 0xf;\n    if (from == to)\n        return;\n\n    img->makeWritable();\n\n    // avoid bleeding 'to' color into the overflow areas of the picture\n    if (from == 0 && img->hasPadding()) {\n        for (int i = 0; i < img->height(); ++i)\n            for (int j = 0; j < img->width(); ++j)\n                if (getCore(img, j, i) == from)\n                    setCore(img, j, i, to);\n        return;\n    }\n\n    auto ptr = img->pix();\n    auto len = img->pixLength();\n    while (len--) {\n        auto b = *ptr;\n        if ((b & 0xf) == from)\n            b = (b & 0xf0) | to;\n        if ((b >> 4) == from)\n            b = (to << 4) | (b & 0xf);\n        *ptr++ = b;\n    }\n}\n\n/**\n * Stretches the image in both directions by 100%\n */\n//%\nImage_ doubled(Image_ img) {\n    Image_ tmp = doubledX(img);\n    registerGCObj(tmp);\n    Image_ r = doubledY(tmp);\n    unregisterGCObj(tmp);\n    return r;\n}\n\nbool drawImageCore(Image_ img, Image_ from, int x, int y, int color) {\n    auto w = from->width();\n    auto h = from->height();\n    auto sh = img->height();\n    auto sw = img->width();\n\n    if (x + w <= 0)\n        return false;\n    if (x >= sw)\n        return false;\n    if (y + h <= 0)\n        return false;\n    if (y >= sh)\n        return false;\n\n    auto len = y < 0 ? min(sh, h + y) : min(sh - y, h);\n    auto tbp = img->bpp();\n    auto fbp = from->bpp();\n    auto y0 = y;\n\n    if (color == -2 && x == 0 && y == 0 && tbp == fbp && w == sw && h == sh) {\n        copyFrom(img, from);\n        return false;\n    }\n\n    // DMESG(\"drawIMG(%d,%d) at (%d,%d) w=%d bh=%d len=%d\",\n    //    w,h,x, y, img->width(), img->byteHeight(), len );\n\n    auto fromH = from->byteHeight();\n    auto imgH = img->byteHeight();\n    auto fromBase = from->pix();\n    auto imgBase = img->pix(0, y);\n\n#define LOOPHD                                                                                     \\\n    for (int xx = 0; xx < w; ++xx, ++x)                                                            \\\n        if (0 <= x && x < sw)\n\n    if (tbp == 4 && fbp == 4) {\n        auto wordH = fromH >> 2;\n        LOOPHD {\n            y = y0;\n\n            auto fdata = (uint32_t *)fromBase + wordH * xx;\n            auto tdata = imgBase + imgH * x;\n\n            // DMESG(\"%d,%d xx=%d/%d - %p (%p) -- %d\",x,y,xx,w,tdata,img->pix(),\n            //    (uint8_t*)fdata - from->pix());\n\n            auto cnt = wordH;\n            auto bot = min(sh, y + h);\n\n#define COLS(s) ((v >> (s)) & 0xf)\n#define COL(s) COLS(s)\n\n#define STEPA(s)                                                                                   \\\n    if (COL(s) && 0 <= y && y < bot)                                                               \\\n        SETLOW(s);                                                                                 \\\n    y++;\n#define STEPB(s)                                                                                   \\\n    if (COL(s) && 0 <= y && y < bot)                                                               \\\n        SETHIGH(s);                                                                                \\\n    y++;                                                                                           \\\n    tdata++;\n#define STEPAQ(s)                                                                                  \\\n    if (COL(s))                                                                                    \\\n        SETLOW(s);\n#define STEPBQ(s)                                                                                  \\\n    if (COL(s))                                                                                    \\\n        SETHIGH(s);                                                                                \\\n    tdata++;\n\n// perf: expanded version 5% faster\n#define ORDER(A, B)                                                                                \\\n    A(0);                                                                                          \\\n    B(4);                                                                                          \\\n    A(8);                                                                                          \\\n    B(12);                                                                                         \\\n    A(16);                                                                                         \\\n    B(20);                                                                                         \\\n    A(24);                                                                                         \\\n    B(28)\n//#define ORDER(A,B) for (int k = 0; k < 32; k += 8) { A(k); B(4+k); }\n#define LOOP(A, B, xbot)                                                                           \\\n    while (cnt--) {                                                                                \\\n        auto v = *fdata++;                                                                         \\\n        if (0 <= y && y <= xbot - 8) {                                                             \\\n            ORDER(A##Q, B##Q);                                                                     \\\n            y += 8;                                                                                \\\n        } else {                                                                                   \\\n            ORDER(A, B);                                                                           \\\n        }                                                                                          \\\n    }\n#define LOOPS(xbot)                                                                                \\\n    if (y & 1)                                                                                     \\\n        LOOP(STEPB, STEPA, xbot)                                                                   \\\n    else                                                                                           \\\n        LOOP(STEPA, STEPB, xbot)\n\n            if (color >= 0) {\n#define SETHIGH(s) *tdata = (*tdata & 0x0f) | ((COLS(s)) << 4)\n#define SETLOW(s) *tdata = (*tdata & 0xf0) | COLS(s)\n                LOOPS(sh)\n            } else if (color == -2) {\n#undef COL\n#define COL(s) 1\n                LOOPS(bot)\n            } else {\n#undef COL\n#define COL(s) COLS(s)\n#undef SETHIGH\n#define SETHIGH(s)                                                                                 \\\n    if (*tdata & 0xf0)                                                                             \\\n    return true\n#undef SETLOW\n#define SETLOW(s)                                                                                  \\\n    if (*tdata & 0x0f)                                                                             \\\n    return true\n                LOOPS(sh)\n            }\n        }\n    } else if (tbp == 1 && fbp == 1) {\n        auto left = img->pix() - imgBase;\n        auto right = img->pix(0, img->height() - 1) - imgBase;\n        LOOPHD {\n            y = y0;\n\n            auto data = fromBase + fromH * xx;\n            auto off = imgBase + imgH * x;\n            auto off0 = off + left;\n            auto off1 = off + right;\n\n            int shift = (y & 7);\n\n            int y1 = y + h + (y & 7);\n            int prev = 0;\n\n            while (y < y1 - 8) {\n                int curr = *data++ << shift;\n                if (off0 <= off && off <= off1) {\n                    uint8_t v = (curr >> 0) | (prev >> 8);\n\n                    if (color == -1) {\n                        if (*off & v)\n                            return true;\n                    } else {\n                        *off |= v;\n                    }\n                }\n                off++;\n                prev = curr;\n                y += 8;\n            }\n\n            int left = y1 - y;\n            if (left > 0) {\n                int curr = *data << shift;\n                if (off0 <= off && off <= off1) {\n                    uint8_t v = ((curr >> 0) | (prev >> 8)) & (0xff >> (8 - left));\n                    if (color == -1) {\n                        if (*off & v)\n                            return true;\n                    } else {\n                        *off |= v;\n                    }\n                }\n            }\n        }\n    } else if (tbp == 4 && fbp == 1) {\n        if (y < 0) {\n            fromBase = from->pix(0, -y);\n            imgBase = img->pix();\n        }\n        // icon mode\n        LOOPHD {\n            auto fdata = fromBase + fromH * xx;\n            auto tdata = imgBase + imgH * x;\n\n            unsigned mask = 0x01;\n            auto v = *fdata++;\n            int off = (y & 1) ? 1 : 0;\n            if (y < 0) {\n                mask <<= -y & 7;\n                off = 0;\n            }\n            for (int i = off; i < len + off; ++i) {\n                if (mask == 0x100) {\n                    mask = 0x01;\n                    v = *fdata++;\n                }\n                if (v & mask) {\n                    if (i & 1)\n                        *tdata = (*tdata & 0x0f) | (color << 4);\n                    else\n                        *tdata = (*tdata & 0xf0) | color;\n                }\n                mask <<= 1;\n                if (i & 1)\n                    tdata++;\n            }\n        }\n    }\n\n    return false;\n}\n\n/**\n * Draw given image on the current image\n */\n//%\nvoid drawImage(Image_ img, Image_ from, int x, int y) {\n    img->makeWritable();\n    if (img->bpp() == 4 && from->bpp() == 4) {\n        drawImageCore(img, from, x, y, -2);\n    } else {\n        fillRect(img, x, y, from->width(), from->height(), 0);\n        drawImageCore(img, from, x, y, 0);\n    }\n}\n\n/**\n * Draw given image with transparent background on the current image\n */\n//%\nvoid drawTransparentImage(Image_ img, Image_ from, int x, int y) {\n    img->makeWritable();\n    drawImageCore(img, from, x, y, 0);\n}\n\n/**\n * Check if the current image \"collides\" with another\n */\n//%\nbool overlapsWith(Image_ img, Image_ other, int x, int y) {\n    return drawImageCore(img, other, x, y, -1);\n}\n\n// Image_ format (legacy)\n//  byte 0: magic 0xe4 - 4 bit color; 0xe1 is monochromatic\n//  byte 1: width in pixels\n//  byte 2: height in pixels\n//  byte 3: padding (should be zero)\n//  byte 4...N: data 4 bits per pixels, high order nibble printed first, lines aligned to 32 bit\n//  words byte 4...N: data 1 bit per pixels, high order bit printed first, lines aligned to byte\n\nImage_ convertAndWrap(Buffer buf) {\n    if (isValidImage(buf))\n        return NEW_GC(RefImage, buf);\n\n    // What follows in this function is mostly dead code, except if people construct image buffers\n    // by hand. Probably safe to remove in a year (middle of 2020) or so. When removing, also remove\n    // from sim.\n    if (!isLegacyImage(buf))\n        return NULL;\n\n    auto tmp = mkBuffer(NULL, buf->length + 4);\n    auto hd = (ImageHeader *)tmp->data;\n    auto src = buf->data;\n    hd->magic = IMAGE_HEADER_MAGIC;\n    hd->bpp = src[0] & 0xf;\n    hd->width = src[1];\n    hd->height = src[2];\n    hd->padding = 0;\n    memcpy(hd->pixels, src + 4, buf->length - 4);\n\n    registerGCObj(tmp);\n    auto r = NEW_GC(RefImage, tmp);\n    unregisterGCObj(tmp);\n    return r;\n}\n\n//%\nvoid _drawIcon(Image_ img, Buffer icon, int xy, int c) {\n    img->makeWritable();\n\n    auto iconImg = convertAndWrap(icon);\n    if (!iconImg || iconImg->bpp() != 1)\n        return;\n\n    drawImageCore(img, iconImg, XX(xy), YY(xy), c);\n}\n\nstatic void drawLineLow(Image_ img, int x0, int y0, int x1, int y1, int c) {\n    int dx = x1 - x0;\n    int dy = y1 - y0;\n    int yi = 1;\n    if (dy < 0) {\n        yi = -1;\n        dy = -dy;\n    }\n    int D = 2 * dy - dx;\n    dx <<= 1;\n    dy <<= 1;\n    int y = y0;\n    for (int x = x0; x <= x1; ++x) {\n        setCore(img, x, y, c);\n        if (D > 0) {\n            y += yi;\n            D -= dx;\n        }\n        D += dy;\n    }\n}\n\nstatic void drawLineHigh(Image_ img, int x0, int y0, int x1, int y1, int c) {\n    int dx = x1 - x0;\n    int dy = y1 - y0;\n    int xi = 1;\n    if (dx < 0) {\n        xi = -1;\n        dx = -dx;\n    }\n    int D = 2 * dx - dy;\n    dx <<= 1;\n    dy <<= 1;\n    int x = x0;\n    for (int y = y0; y <= y1; ++y) {\n        setCore(img, x, y, c);\n        if (D > 0) {\n            x += xi;\n            D -= dy;\n        }\n        D += dx;\n    }\n}\n\nvoid drawLine(Image_ img, int x0, int y0, int x1, int y1, int c) {\n    if (x1 < x0) {\n        drawLine(img, x1, y1, x0, y0, c);\n        return;\n    }\n    int w = x1 - x0;\n    int h = y1 - y0;\n\n    if (h == 0) {\n        if (w == 0)\n            setPixel(img, x0, y0, c);\n        else\n            fillRect(img, x0, y0, w + 1, 1, c);\n        return;\n    }\n\n    if (w == 0) {\n        if (h > 0)\n            fillRect(img, x0, y0, 1, h + 1, c);\n        else\n            fillRect(img, x0, y1, 1, -h + 1, c);\n        return;\n    }\n\n    if (x1 < 0 || x0 >= img->width())\n        return;\n    if (x0 < 0) {\n        y0 -= (h * x0 / w);\n        x0 = 0;\n    }\n    if (x1 >= img->width()) {\n        int d = (img->width() - 1) - x1;\n        y1 += (h * d / w);\n        x1 = img->width() - 1;\n    }\n\n    if (y0 < y1) {\n        if (y0 >= img->height() || y1 < 0)\n            return;\n        if (y0 < 0) {\n            x0 -= (w * y0 / h);\n            y0 = 0;\n        }\n        if (y1 >= img->height()) {\n            int d = (img->height() - 1) - y1;\n            x1 += (w * d / h);\n            y1 = img->height() - 1;\n        }\n    } else {\n        if (y1 >= img->height() || y0 < 0)\n            return;\n        if (y1 < 0) {\n            x1 -= (w * y1 / h);\n            y1 = 0;\n        }\n        if (y0 >= img->height()) {\n            int d = (img->height() - 1) - y0;\n            x0 += (w * d / h);\n            y0 = img->height() - 1;\n        }\n    }\n\n    img->makeWritable();\n\n    if (h < 0) {\n        h = -h;\n        if (h < w)\n            drawLineLow(img, x0, y0, x1, y1, c);\n        else\n            drawLineHigh(img, x1, y1, x0, y0, c);\n    } else {\n        if (h < w)\n            drawLineLow(img, x0, y0, x1, y1, c);\n        else\n            drawLineHigh(img, x0, y0, x1, y1, c);\n    }\n}\n\n//%\nvoid _drawLine(Image_ img, int xy, int wh, int c) {\n    drawLine(img, XX(xy), YY(xy), XX(wh), YY(wh), c);\n}\n\nvoid blitRow(Image_ img, int x, int y, Image_ from, int fromX, int fromH) {\n    if (!img->inRange(x, 0) || !img->inRange(fromX, 0) || fromH <= 0)\n        return;\n\n    if (img->bpp() != 4 || from->bpp() != 4)\n        return;\n\n    int fy = 0;\n    int stepFY = (from->width() << 16) / fromH;\n    int endY = y + fromH;\n    if (endY > img->height())\n        endY = img->height();\n    if (y < 0) {\n        fy += -y * stepFY;\n        y = 0;\n    }\n\n    auto dp = img->pix(x, y);\n    auto sp = from->pix(fromX, 0);\n\n    while (y < endY) {\n        int p = fy >> 16, c;\n        if (p & 1)\n            c = sp[p >> 1] >> 4;\n        else\n            c = sp[p >> 1] & 0xf;\n        if (y & 1) {\n            *dp = (*dp & 0x0f) | (c << 4);\n            dp++;\n        } else {\n            *dp = (*dp & 0xf0) | (c & 0xf);\n        }\n        y++;\n        fy += stepFY;\n    }\n}\n\n//%\nvoid _blitRow(Image_ img, int xy, Image_ from, int xh) {\n    blitRow(img, XX(xy), YY(xy), from, XX(xh), YY(xh));\n}\n\nbool blit(Image_ dst, Image_ src, pxt::RefCollection *args) {\n    int xDst = pxt::toInt(args->getAt(0));\n    int yDst = pxt::toInt(args->getAt(1));\n    int wDst = pxt::toInt(args->getAt(2));\n    int hDst = pxt::toInt(args->getAt(3));\n    int xSrc = pxt::toInt(args->getAt(4));\n    int ySrc = pxt::toInt(args->getAt(5));\n    int wSrc = pxt::toInt(args->getAt(6));\n    int hSrc = pxt::toInt(args->getAt(7));\n    bool transparent = pxt::toBoolQuick(args->getAt(8));\n    bool check = pxt::toBoolQuick(args->getAt(9));\n\n    int xSrcStep = (wSrc << 16) / wDst;\n    int ySrcStep = (hSrc << 16) / hDst;\n\n    int xDstClip = abs(min(0, xDst));\n    int yDstClip = abs(min(0, yDst));\n    int xDstStart = xDst + xDstClip;\n    int yDstStart = yDst + yDstClip;\n    int xDstEnd = min(dst->width(), xDst + wDst);\n    int yDstEnd = min(dst->height(), yDst + hDst);\n\n    int xSrcStart = max(0, (xSrc << 16) + xDstClip * xSrcStep);\n    int ySrcStart = max(0, (ySrc << 16) + yDstClip * ySrcStep);\n    int xSrcEnd = min(src->width(), xSrc + wSrc) << 16;\n    int ySrcEnd = min(src->height(), ySrc + hSrc) << 16;\n\n    if (!check)\n        dst->makeWritable();\n\n    for (int yDstCur = yDstStart, ySrcCur = ySrcStart; yDstCur < yDstEnd && ySrcCur < ySrcEnd; ++yDstCur, ySrcCur += ySrcStep) {\n        int ySrcCurI = ySrcCur >> 16;\n        for (int xDstCur = xDstStart, xSrcCur = xSrcStart; xDstCur < xDstEnd && xSrcCur < xSrcEnd; ++xDstCur, xSrcCur += xSrcStep) {\n            int xSrcCurI = xSrcCur >> 16;\n            int cSrc = getCore(src, xSrcCurI, ySrcCurI);\n            if (check && cSrc) {\n                int cDst = getCore(dst, xDstCur, yDstCur);\n                if (cDst) {\n                    return true;\n                }\n                continue;\n            }\n            if (!transparent || cSrc) {\n                setCore(dst, xDstCur, yDstCur, cSrc);\n            }\n        }\n    }\n    return false;\n}\n\n//%\nbool _blit(Image_ img, Image_ src, pxt::RefCollection *args) {\n    return blit(img, src, args);\n}\n\nvoid fillCircle(Image_ img, int cx, int cy, int r, int c) {\n    int x = r - 1;\n    int y = 0;\n    int dx = 1;\n    int dy = 1;\n    int err = dx - (r << 1);\n\n    while (x >= y) {\n        fillRect(img, cx + x, cy - y, 1, 1 + (y << 1), c);\n        fillRect(img, cx + y, cy - x, 1, 1 + (x << 1), c);\n        fillRect(img, cx - x, cy - y, 1, 1 + (y << 1), c);\n        fillRect(img, cx - y, cy - x, 1, 1 + (x << 1), c);\n        if (err <= 0) {\n            ++y;\n            err += dy;\n            dy += 2;\n        } else {\n            --x;\n            dx += 2;\n            err += dx - (r << 1);\n        }\n    }\n}\n\n//%\nvoid _fillCircle(Image_ img, int cxy, int r, int c) {\n    fillCircle(img, XX(cxy), YY(cxy), r, c);\n}\n\ntypedef struct\n{\n    int x, y;\n    int x0, y0;\n    int x1, y1;\n    int W,H;\n    int dx, dy;\n    int yi, xi;\n    int D;\n    int nextFuncIndex;\n} LineGenState; // For keeping track of the state when generating Y values for a line, even when moving to the next X.\n\ntypedef struct\n{\n    int min;\n    int max;\n} ValueRange;\n\nvoid nextYRange_Low(int x, LineGenState *line, ValueRange *yRange) {\n    while (line->x == x && line->x <= line->x1 && line->x < line->W) {\n        if (0 <= line->x) {\n            if (line->y < yRange->min) yRange->min = line->y;\n            if (line->y > yRange->max) yRange->max = line->y;\n        }\n        if (line->D > 0) {\n            line->y += line->yi;\n            line->D -= line->dx;\n        }\n        line->D += line->dy;\n        ++line->x;\n    }\n}\n\nvoid nextYRange_HighUp(int x, LineGenState *line, ValueRange *yRange) {\n    while (line->x == x && line->y >= line->y1 && line->x < line->W) {\n        if (0 <= line->x) {\n            if (line->y < yRange->min) yRange->min = line->y;\n            if (line->y > yRange->max) yRange->max = line->y;\n        }\n        if (line->D > 0) {\n            line->x += line->xi;\n            line->D += line->dy;\n        }\n        line->D += line->dx;\n        --line->y;\n    }\n}\n// This function is similar to the sub-function drawLineHigh for drawLine. However, it yields back after calculating all Y values of a given X. When the function is called again, it continues from the state where it yielded back previously.\nvoid nextYRange_HighDown(int x, LineGenState *line, ValueRange *yRange) {\n    while (line->x == x && line->y <= line->y1 && line->x < line->W) {\n        if (0 <= line->x) {\n            if (line->y < yRange->min) yRange->min = line->y;\n            if (line->y > yRange->max) yRange->max = line->y;\n        }\n        if (line->D > 0) {\n            line->x += line->xi;\n            line->D -= line->dy;\n        }\n        line->D += line->dx;\n        ++line->y;\n    }\n}\n\nLineGenState initYRangeGenerator(int16_t X0, int16_t Y0, int16_t X1, int16_t Y1) {\n    LineGenState line;\n\n    line.x0 = X0, line.y0 = Y0, line.x1 = X1, line.y1 = Y1;\n\n    line.dx = line.x1 - line.x0;\n    line.dy = line.y1 - line.y0;\n    line.y = line.y0;\n    line.x = line.x0;\n\n    if ((line.dy < 0 ? -line.dy : line.dy) < line.dx) {\n        line.yi = 1;\n        if (line.dy < 0) {\n            line.yi = -1;\n            line.dy = -line.dy;\n        }\n        line.D = 2 * line.dy - line.dx;\n        line.dx <<= 1;\n        line.dy <<= 1;\n\n        line.nextFuncIndex = 0;\n        return line;\n    } else {\n        line.xi = 1;\n        // if (dx < 0) {//should not hit\n        //     PANIC();\n        // }\n        if (line.dy < 0) {\n            line.D = 2 * line.dx + line.dy;\n            line.dx <<= 1;\n            line.dy <<= 1;\n\n            line.nextFuncIndex = 1;\n            return line;\n        } else {\n            line.D = 2 * line.dx - line.dy;\n            line.dx <<= 1;\n            line.dy <<= 1;\n\n            line.nextFuncIndex = 2;\n            return line;\n        }\n    }\n}\n\n// core of draw vertical line for repeatly calling, eg.: fillTriangle() or fillPolygon4()\n// value range/safety check not included\n// prepare \"img->makeWritable();\" and \"uint8_t f = img->fillMask(c);\" outside required.\n// bpp=4 support only right now\nvoid drawVLineCore(Image_ img, int x, int y, int h, uint8_t f) {\n    uint8_t *p = img->pix(x, y);\n    auto ptr = p;\n    unsigned mask = 0x0f;\n    if (y & 1)\n        mask <<= 4;\n    for (int i = 0; i < h; ++i) {\n        if (mask == 0xf00) {\n            if (h - i >= 2) {\n                *++ptr = f;\n                i++;\n                continue;\n            } else {\n                mask = 0x0f;\n                ptr++;\n            }\n        }\n        *ptr = (*ptr & ~mask) | (f & mask);\n        mask <<= 4;\n    }\n}\n\nvoid drawVLine(Image_ img, int x, int y, int h, int c) {\n    int H = height(img);\n    uint8_t f = img->fillMask(c);\n    if (x < 0 || x >= width(img) || y >= H || y + h - 1 < 0)\n        return;\n    if (y < 0){\n        h += y;\n        y = 0;\n    }\n    if (y + h > H)\n        h = H - y;\n    drawVLineCore(img, x, y, h, f);\n}\n\nvoid fillTriangle(Image_ img, int x0, int y0, int x1, int y1, int x2, int y2, int c) {\n    if (x1 < x0) {\n        swap(x0, x1);\n        swap(y0, y1);\n    }\n    if (x2 < x1) {\n        swap(x1, x2);\n        swap(y1, y2);\n    }\n    if (x1 < x0) {\n        swap(x0, x1);\n        swap(y0, y1);\n    }\n\n    LineGenState lines[] = {\n        initYRangeGenerator(x0, y0, x2, y2),\n        initYRangeGenerator(x0, y0, x1, y1),\n        initYRangeGenerator(x1, y1, x2, y2)\n    };\n\n    int W = width(img), H = height(img);\n    lines[0].W = lines[1].W = lines[2].W = W;\n    lines[0].H = lines[1].H = lines[2].H = H;\n\n    // We have 3 different sub-functions to generate Ys of edges, each particular edge maps to one of them.\n    // Use function pointers to avoid judging which function to call at every X.\n    typedef void (*FP_NEXT)(int x, LineGenState *line, ValueRange *yRange);\n    FP_NEXT nextFuncList[] = { nextYRange_Low, nextYRange_HighUp, nextYRange_HighDown };\n    FP_NEXT fpNext0 = nextFuncList[lines[0].nextFuncIndex];\n    FP_NEXT fpNext1 = nextFuncList[lines[1].nextFuncIndex];\n    FP_NEXT fpNext2 = nextFuncList[lines[2].nextFuncIndex];\n\n    ValueRange yRange = {H, -1};\n    img->makeWritable();\n    uint8_t f = img->fillMask(c);\n\n    for (int x = lines[1].x0; x <= min(x1, W - 1); x++) {\n        yRange.min = H;\n        yRange.max = -1;\n        fpNext0(x, &lines[0], &yRange);\n        fpNext1(x, &lines[1], &yRange);\n\n        if (x < 0 || yRange.min >= H || yRange.max < 0)\n            continue;\n        if (yRange.min < 0)\n            yRange.min = 0;\n        if (yRange.max >= H)\n            yRange.max = H - 1;\n        drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);\n    }\n\n    fpNext2(lines[2].x0, &lines[2], &yRange);\n\n    for (int x = lines[2].x0 + 1; x <= min(x2, W - 1); x++) {\n        yRange.min = H;\n        yRange.max = -1;\n        fpNext0(x, &lines[0], &yRange);\n        fpNext2(x, &lines[2], &yRange);\n\n        if (x < 0 || yRange.min >= H || yRange.max < 0)\n            continue;\n        if (yRange.min < 0)\n            yRange.min = 0;\n        if (yRange.max >= H)\n            yRange.max = H - 1;\n        drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);\n    }\n}\n\nvoid fillPolygon4(Image_ img, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, int c) {\n    LineGenState lines[] = {\n        (x0 < x1) ? initYRangeGenerator(x0, y0, x1, y1) : initYRangeGenerator(x1, y1, x0, y0),\n        (x1 < x2) ? initYRangeGenerator(x1, y1, x2, y2) : initYRangeGenerator(x2, y2, x1, y1),\n        (x2 < x3) ? initYRangeGenerator(x2, y2, x3, y3) : initYRangeGenerator(x3, y3, x2, y2),\n        (x0 < x3) ? initYRangeGenerator(x0, y0, x3, y3) : initYRangeGenerator(x3, y3, x0, y0)};\n\n    int W = width(img), H = height(img);\n    lines[0].W = lines[1].W = lines[2].W = lines[3].W = W;\n    lines[0].H = lines[1].H = lines[2].H = lines[3].H = H;\n\n    int minX = min(min(x0, x1), min(x2, x3));\n    int maxX = min(max(max(x0, x1), max(x2, x3)), W - 1);\n\n    typedef void (*FP_NEXT)(int x, LineGenState *line, ValueRange *yRange);\n    FP_NEXT nextFuncList[] = { nextYRange_Low, nextYRange_HighUp, nextYRange_HighDown };\n    FP_NEXT fpNext0 = nextFuncList[lines[0].nextFuncIndex];\n    FP_NEXT fpNext1 = nextFuncList[lines[1].nextFuncIndex];\n    FP_NEXT fpNext2 = nextFuncList[lines[2].nextFuncIndex];\n    FP_NEXT fpNext3 = nextFuncList[lines[3].nextFuncIndex];\n\n    ValueRange yRange = { H, -1 };\n    img->makeWritable();\n    uint8_t f = img->fillMask(c);\n\n    for (int x = minX; x <= maxX; x++) {\n        yRange.min = H;\n        yRange.max = -1;\n        fpNext0(x, &lines[0], &yRange);\n        fpNext1(x, &lines[1], &yRange);\n        fpNext2(x, &lines[2], &yRange);\n        fpNext3(x, &lines[3], &yRange);\n\n        if (x < 0 || yRange.min >= H || yRange.max < 0)\n            continue;\n        if (yRange.min < 0)\n            yRange.min = 0;\n        if (yRange.max >= H)\n            yRange.max = H - 1;\n        drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);\n    }\n}\n\n//%\nvoid _fillTriangle(Image_ img, pxt::RefCollection *args) {\n    fillTriangle(\n        img,\n        pxt::toInt(args->getAt(0)),\n        pxt::toInt(args->getAt(1)),\n        pxt::toInt(args->getAt(2)),\n        pxt::toInt(args->getAt(3)),\n        pxt::toInt(args->getAt(4)),\n        pxt::toInt(args->getAt(5)),\n        pxt::toInt(args->getAt(6))\n    );\n}\n\n// This polygon fill is similar to fillTriangle(): Scan minY and maxY of all edges at each X, and draw a vertical line between (x,minY)~(x,maxY).\n// The main difference is that it sorts the endpoints of each edge, x0 < x1, to draw from left to right, but doesn't sort the edges as it's too time consuming.\n// Instead, just call next(), which returns immediately if the x is not in range of the edge in horizon.\n// NOTE: Unlike triangles, edges of a polygon can cross a vertical line at a given X multi time. This algorithm can fill correctly only if edges meet this condition: Any vertical line(x) cross edges at most 2 times.\n// Fortunately, no matter what perspective transform is applied, a rectangle/trapezoid will still meet this condition.\n// Ref: https://forum.makecode.com/t/new-3d-engine-help-filling-4-sided-polygons/18641/9\n//%\nvoid _fillPolygon4(Image_ img, pxt::RefCollection *args) {\n    fillPolygon4(\n        img,\n        pxt::toInt(args->getAt(0)),\n        pxt::toInt(args->getAt(1)),\n        pxt::toInt(args->getAt(2)),\n        pxt::toInt(args->getAt(3)),\n        pxt::toInt(args->getAt(4)),\n        pxt::toInt(args->getAt(5)),\n        pxt::toInt(args->getAt(6)),\n        pxt::toInt(args->getAt(7)),\n        pxt::toInt(args->getAt(8))\n    );\n}\n\n} // namespace ImageMethods\n\nnamespace image {\n/**\n * Create new empty (transparent) image\n */\n//%\nImage_ create(int width, int height) {\n    Image_ r = mkImage(width, height, IMAGE_BITS);\n    if (r)\n        memset(r->pix(), 0, r->pixLength());\n    else\n        target_panic(PANIC_INVALID_IMAGE);\n    return r;\n}\n\n/**\n * Create new image with given content\n */\n//%\nImage_ ofBuffer(Buffer buf) {\n    return ImageMethods::convertAndWrap(buf);\n}\n\n/**\n * Double the size of an icon\n */\n//%\nBuffer doubledIcon(Buffer icon) {\n    if (!isValidImage(icon))\n        return NULL;\n\n    auto r = NEW_GC(RefImage, icon);\n    registerGCObj(r);\n    auto t = ImageMethods::doubled(r);\n    unregisterGCObj(r);\n    return t->buffer;\n}\n\n} // namespace image\n\n// This is  6.5x faster than standard on word-aligned copy\n// probably should move to codal\n\n#ifndef __linux__\nextern \"C\" void *memcpy(void *dst, const void *src, size_t sz) {\n    void *dst0 = dst;\n    if (sz >= 4 && !((uintptr_t)dst & 3) && !((uintptr_t)src & 3)) {\n        size_t cnt = sz >> 2;\n        uint32_t *d = (uint32_t *)dst;\n        const uint32_t *s = (const uint32_t *)src;\n        while (cnt--) {\n            *d++ = *s++;\n        }\n        sz &= 3;\n        dst = d;\n        src = s;\n    }\n\n    // see comment in memset() below (have not seen optimization here, but better safe than sorry)\n    volatile uint8_t *dd = (uint8_t *)dst;\n    volatile uint8_t *ss = (uint8_t *)src;\n\n    while (sz--) {\n        *dd++ = *ss++;\n    }\n\n    return dst0;\n}\n\nextern \"C\" void *memset(void *dst, int v, size_t sz) {\n    void *dst0 = dst;\n    if (sz >= 4 && !((uintptr_t)dst & 3)) {\n        size_t cnt = sz >> 2;\n        uint32_t vv = 0x01010101 * v;\n        uint32_t *d = (uint32_t *)dst;\n        while (cnt--) {\n            *d++ = vv;\n        }\n        sz &= 3;\n        dst = d;\n    }\n\n    // without volatile here, GCC may optimize the loop to memset() call which is obviously not great\n    volatile uint8_t *dd = (uint8_t *)dst;\n\n    while (sz--) {\n        *dd++ = v;\n    }\n\n    return dst0;\n}\n#endif\n","image.d.ts":"//% fixedInstances decompileIndirectFixedInstances\ninterface Image {\n    /**\n     * Fill a rectangle\n     */\n    //% helper=imageFillRect blockNamespace=\"images\" inlineInputMode=\"inline\" group=\"Drawing\"\n    //% block=\"fill rectangle in %picture=variables_get at x %x y %y width %w height %h %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/fill-rect\n    fillRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Replace colors in a rectangle\n     */\n    //% helper=imageMapRect\n    mapRect(x: number, y: number, w: number, h: number, colorMap: Buffer): void;\n\n    /**\n     * Draw a line\n     */\n    //% helper=imageDrawLine blockNamespace=\"images\" inlineInputMode=\"inline\" group=\"Drawing\"\n    //% block=\"draw line in %picture=variables_get from x %x0 y %y0 to x %x1 y %y1 %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/draw-line\n    drawLine(x0: number, y0: number, x1: number, y1: number, c: color): void;\n\n    /**\n     * Draw an empty rectangle\n     */\n    //% helper=imageDrawRect blockNamespace=\"images\" inlineInputMode=\"inline\" group=\"Drawing\"\n    //% block=\"draw rectangle in %picture=variables_get at x %x y %y width %w height %h %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/draw-rect\n    drawRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Set pixel color\n     */\n    //% shim=ImageMethods::setPixel blockNamespace=\"images\" group=\"Drawing\"\n    //% block=\"set %picture=variables_get color at x %x y %y to %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/set-pixel\n    setPixel(x: int32, y: int32, c: int32): void;\n\n    /**\n     * Get a pixel color\n     */\n    //% shim=ImageMethods::getPixel blockNamespace=\"images\" group=\"Drawing\"\n    //% block=\"%picture=variables_get color at x %x y %y\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/get-pixel\n    getPixel(x: int32, y: int32): int32;\n\n    /**\n     * Fill entire image with a given color\n     */\n    //% shim=ImageMethods::fill blockNamespace=\"images\" group=\"Drawing\"\n    //% block=\"fill %picture=variables_get with %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/fill\n    fill(c: int32): void;\n\n    /**\n     * Return a copy of the current image\n     */\n    //% shim=ImageMethods::clone blockNamespace=\"images\" group=\"Create\"\n    //% block=\"clone %picture=variables_get\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/clone\n    clone(): Image;\n\n    /**\n     * Flips (mirrors) pixels horizontally in the current image\n     */\n    //% shim=ImageMethods::flipX blockNamespace=\"images\" group=\"Transformations\"\n    //% block=\"flip %picture=variables_get horizontally\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/flip-x\n    flipX(): void;\n\n    /**\n     * Flips (mirrors) pixels vertically in the current image\n     */\n    //% shim=ImageMethods::flipY blockNamespace=\"images\" group=\"Transformations\"\n    //% block=\"flip %picture=variables_get vertically\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/flip-y\n    flipY(): void;\n\n    /**\n     * Every pixel in image is moved by (dx,dy)\n     */\n    //% shim=ImageMethods::scroll blockNamespace=\"images\" group=\"Transformations\"\n    //% help=images/image/scroll\n    scroll(dx: int32, dy: int32): void;\n\n    /**\n     * Replaces one color in an image with another\n     */\n    //% shim=ImageMethods::replace blockNamespace=\"images\" group=\"Transformations\"\n    //% block=\"change color in %picture=variables_get from %from=colorindexpicker to %to=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/replace\n    replace(from: int32, to: int32): void;\n\n    /**\n     * Returns true if the provided image is the same as this image,\n     * otherwise returns false.\n     */\n    //% shim=ImageMethods::equals\n    //% blockNamespace=\"images\" group=\"Compare\"\n    //% block=\"$this is equal to image $other\"\n    //% this.shadow=variables_get\n    //% this.defl=\"picture\"\n    //% other.shadow=screen_image_picker\n    //% help=images/image/equals\n    equals(other: Image): boolean;\n\n    //% shim=ImageMethods::isStatic\n    isStatic(): boolean;\n\n    //% shim=ImageMethods::revision\n    revision(): number;\n\n     /**\n     * Draw given image with transparent background on the current image\n     */\n    //% shim=ImageMethods::drawTransparentImage\n    //% blockNamespace=\"images\"\n    //% blockId=image_draw_transparent_image\n    //% group=\"Drawing\"\n    //% block=\"$this draw $from at x $x y $y\"\n    //% this.shadow=variables_get\n    //% this.defl=\"picture\"\n    //% from.shadow=screen_image_picker\n    //% weight=0\n    drawTransparentImage(from: Image, x: int32, y: int32): void;\n}\n\ndeclare namespace image {\n    //% blockNamespace=\"images\"\n    //% block=\"create image width %width height %height\" group=\"Create\"\n    //% help=images/create\n    function create(width: number, height: number): Image;\n}","image.ts":"type color = number\n\nnamespace image {\n    export enum Dimension {\n        //% block=\"width\"\n        Width,\n        //% block=\"height\"\n        Height\n    }\n\n    export function repeatY(count: number, image: Image) {\n        let arr = [image]\n        while (--count > 0)\n            arr.push(image)\n        return concatY(arr)\n    }\n\n    export function concatY(images: Image[]) {\n        let w = 0\n        let h = 0\n        for (let img of images) {\n            w = Math.max(img.width, w)\n            h += img.height\n        }\n        let r = image.create(w, h)\n        let y = 0\n        for (let img of images) {\n            let x = (w - img.width) >> 1\n            r.drawImage(img, x, y)\n            y += img.height\n        }\n        return r\n    }\n\n    /**\n     * Returns the width or height of a picture.\n     *\n     * @param picture The picture to get the width or height of\n     * @param dimension The dimension to get\n     * @returns\n     */\n    //% blockId=image_get_dimension\n    //% group=\"Create\"\n    //% blockNamespace=\"images\"\n    //% block=\"$picture $dimension\"\n    //% picture.shadow=variables_get\n    //% picture.defl=picture\n    export function getDimension(picture: Image, dimension: Dimension) {\n        if (dimension === Dimension.Width) return picture.width;\n        else return picture.height;\n    }\n}\n\n\n//% snippet='img` `'\n//% pySnippet='img(\"\"\" \"\"\")'\n//% fixedInstances\ninterface Image {\n    /**\n     * Draw an icon (monochromatic image) using given color\n     */\n    //% helper=imageDrawIcon\n    drawIcon(icon: Buffer, x: number, y: number, c: color): void;\n\n    /**\n     * Fill a rectangle\n     */\n    //% helper=imageFillRect\n    fillRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Draw a line\n     */\n    //% helper=imageDrawLine\n    drawLine(x0: number, y0: number, x1: number, y1: number, c: color): void;\n\n    /**\n     * Draw an empty rectangle\n     */\n    //% helper=imageDrawRect\n    drawRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Draw a circle\n     */\n    //% helper=imageDrawCircle\n    drawCircle(cx: number, cy: number, r: number, c: color): void;\n\n    /**\n     * Fills a circle\n     */\n    //% helper=imageFillCircle\n    fillCircle(cx: number, cy: number, r: number, c: color): void;\n\n    /**\n     * Fills a triangle\n     */\n    //% helper=imageFillTriangle\n    fillTriangle(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, col: number): void;\n\n    /**\n     * Fills a 4-side-polygon\n     */\n    //% helper=imageFillPolygon4\n    fillPolygon4(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, col: number): void;\n\n    /**\n     * Returns an image rotated by -90, 90, -180, 180, -270, 270 deg clockwise\n     */\n    //% helper=imageRotated\n    rotated(deg: number): Image;\n\n    /**\n     * Scale and copy a row of pixels from a texture.\n     */\n    //% helper=imageBlitRow\n    blitRow(dstX: number, dstY: number, from: Image, fromX: number, fromH: number): void;\n\n    /**\n     * Copy an image from a source rectangle to a destination rectangle, stretching or\n     * compressing to fit the dimensions of the destination rectangle, if necessary.\n     */\n    //% helper=imageBlit\n    blit(xDst: number, yDst: number, wDst: number, hDst: number, src: Image, xSrc: number, ySrc: number, wSrc: number, hSrc: number, transparent: boolean, check: boolean): boolean;\n}\n\ninterface ScreenImage extends Image {\n    /**\n     * Sets the screen backlight brightness (10-100)\n     */\n    //% helper=setScreenBrightness\n    setBrightness(deg: number): Image;\n\n    /**\n     * Gets current screen backlight brightness (0-100)\n     */\n    //% helper=screenBrightness\n    brightness(): number;\n}\n\n// pxt compiler currently crashes on non-functions in helpers namespace; will fix\nnamespace _helpers_workaround {\n    export let brightness = 100\n}\n\nnamespace helpers {\n    //% shim=ImageMethods::_drawLine\n    function _drawLine(img: Image, xy: number, wh: number, c: color): void { }\n\n    //% shim=ImageMethods::_fillRect\n    function _fillRect(img: Image, xy: number, wh: number, c: color): void { }\n\n    //% shim=ImageMethods::_mapRect\n    function _mapRect(img: Image, xy: number, wh: number, m: Buffer): void { }\n\n    //% shim=ImageMethods::_drawIcon\n    function _drawIcon(img: Image, icon: Buffer, xy: number, c: color): void { }\n\n    //% shim=ImageMethods::_fillCircle\n    declare function _fillCircle(img: Image, cxy: number, r: number, c: color): void;\n\n    //% shim=ImageMethods::_blitRow\n    declare function _blitRow(img: Image, xy: number, from: Image, xh: number): void;\n\n    //% shim=ImageMethods::_blit\n    declare function _blit(img: Image, src: Image, args: number[]): boolean;\n\n    //% shim=ImageMethods::_fillTriangle\n    declare function _fillTriangle(img: Image, args: number[]): void;\n\n    //% shim=ImageMethods::_fillPolygon4\n    declare function _fillPolygon4(img: Image, args: number[]): void;\n\n    function pack(x: number, y: number) {\n        return (Math.clamp(-30000, 30000, x | 0) & 0xffff) | (Math.clamp(-30000, 30000, y | 0) << 16)\n    }\n\n    let _blitArgs: number[];\n\n    export function imageBlit(img: Image, xDst: number, yDst: number, wDst: number, hDst: number, src: Image, xSrc: number, ySrc: number, wSrc: number, hSrc: number, transparent: boolean, check: boolean): boolean {\n        _blitArgs = _blitArgs || [];\n        _blitArgs[0] = xDst | 0;\n        _blitArgs[1] = yDst | 0;\n        _blitArgs[2] = wDst | 0;\n        _blitArgs[3] = hDst | 0;\n        _blitArgs[4] = xSrc | 0;\n        _blitArgs[5] = ySrc | 0;\n        _blitArgs[6] = wSrc | 0;\n        _blitArgs[7] = hSrc | 0;\n        _blitArgs[8] = transparent ? 1 : 0;\n        _blitArgs[9] = check ? 1 : 0;\n        return _blit(img, src, _blitArgs);\n    }\n\n    export function imageBlitRow(img: Image, dstX: number, dstY: number, from: Image, fromX: number, fromH: number): void {\n        _blitRow(img, pack(dstX, dstY), from, pack(fromX, fromH))\n    }\n\n    export function imageDrawIcon(img: Image, icon: Buffer, x: number, y: number, c: color): void {\n        _drawIcon(img, icon, pack(x, y), c)\n    }\n    export function imageFillRect(img: Image, x: number, y: number, w: number, h: number, c: color): void {\n        _fillRect(img, pack(x, y), pack(w, h), c)\n    }\n    export function imageMapRect(img: Image, x: number, y: number, w: number, h: number, m: Buffer): void {\n        _mapRect(img, pack(x, y), pack(w, h), m)\n    }\n    export function imageDrawLine(img: Image, x: number, y: number, w: number, h: number, c: color): void {\n        _drawLine(img, pack(x, y), pack(w, h), c)\n    }\n    export function imageDrawRect(img: Image, x: number, y: number, w: number, h: number, c: color): void {\n        if (w == 0 || h == 0) return\n        w--\n        h--\n        imageDrawLine(img, x, y, x + w, y, c)\n        imageDrawLine(img, x, y, x, y + h, c)\n        imageDrawLine(img, x + w, y + h, x + w, y, c)\n        imageDrawLine(img, x + w, y + h, x, y + h, c)\n    }\n\n    export function imageDrawCircle(img: Image, cx: number, cy: number, r: number, col: number) {\n        cx = cx | 0;\n        cy = cy | 0;\n        r = r | 0;\n        // short cuts\n        if (r < 0)\n            return;\n\n        // Bresenham's algorithm\n        let x = 0\n        let y = r\n        let d = 3 - 2 * r\n\n        while (y >= x) {\n            img.setPixel(cx + x, cy + y, col)\n            img.setPixel(cx - x, cy + y, col)\n            img.setPixel(cx + x, cy - y, col)\n            img.setPixel(cx - x, cy - y, col)\n            img.setPixel(cx + y, cy + x, col)\n            img.setPixel(cx - y, cy + x, col)\n            img.setPixel(cx + y, cy - x, col)\n            img.setPixel(cx - y, cy - x, col)\n            x++\n            if (d > 0) {\n                y--\n                d += 4 * (x - y) + 10\n            } else {\n                d += 4 * x + 6\n            }\n        }\n    }\n\n    export function imageFillCircle(img: Image, cx: number, cy: number, r: number, col: number) {\n        _fillCircle(img, pack(cx, cy), r, col);\n    }\n\n    export function imageFillTriangle(img: Image, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, col: number) {\n        _blitArgs = _blitArgs || [];\n        _blitArgs[0] = x0;\n        _blitArgs[1] = y0;\n        _blitArgs[2] = x1;\n        _blitArgs[3] = y1;\n        _blitArgs[4] = x2;\n        _blitArgs[5] = y2;\n        _blitArgs[6] = col;\n        _fillTriangle(img, _blitArgs);\n    }\n\n    export function imageFillPolygon4(img: Image, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, col: number) {\n        _blitArgs = _blitArgs || [];\n        _blitArgs[0] = x0;\n        _blitArgs[1] = y0;\n        _blitArgs[2] = x1;\n        _blitArgs[3] = y1;\n        _blitArgs[4] = x2;\n        _blitArgs[5] = y2;\n        _blitArgs[6] = x3;\n        _blitArgs[7] = y3;\n        _blitArgs[8] = col;\n        _fillPolygon4(img, _blitArgs);\n    }\n\n    /**\n     * Returns an image rotated by 90, 180, 270 deg clockwise\n     */\n    export function imageRotated(img: Image, deg: number) {\n        if (deg == -90 || deg == 270) {\n            let r = img.transposed();\n            r.flipY();\n            return r;\n        } else if (deg == 180 || deg == -180) {\n            let r = img.clone();\n            r.flipX();\n            r.flipY();\n            return r;\n        } else if (deg == 90 || deg == -270) {\n            let r = img.transposed();\n            r.flipX();\n            return r;\n        } else {\n            return null;\n        }\n    }\n\n    //% shim=pxt::setScreenBrightness\n    function _setScreenBrightness(brightness: number) { }\n\n    export function setScreenBrightness(img: Image, b: number) {\n        b = Math.clamp(10, 100, b | 0);\n        _helpers_workaround.brightness = b\n        _setScreenBrightness(_helpers_workaround.brightness)\n    }\n\n    export function screenBrightness(img: Image) {\n        return _helpers_workaround.brightness\n    }\n}\n","imagesoverrides.jres":"{\n  \n}","imagesoverrides.ts":"// replace with built-in images","ns.ts":"\n//% color=\"#a5b1c2\"\nnamespace images {\n\n}","panic.cpp":"// potentially overriden in targets","pxt.json":"{\n    \"name\": \"screen\",\n    \"description\": \"The screen library\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"screen.cpp\",\n        \"panic.cpp\",\n        \"image.cpp\",\n        \"image.ts\",\n        \"screenimage.ts\",\n        \"text.ts\",\n        \"frame.ts\",\n        \"shims.d.ts\",\n        \"fieldeditors.ts\",\n        \"targetoverrides.ts\",\n        \"ns.ts\",\n        \"image.d.ts\",\n        \"pxtparts.json\",\n        \"imagesoverrides.jres\",\n        \"imagesoverrides.ts\",\n        \"font12.jres\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","pxtparts.json":"{\n  \"screen\": {\n    \"simulationBehavior\": \"screen\",\n    \"visual\": {\n      \"builtIn\": \"screen\",\n      \"width\": 158.43856811523438,\n      \"height\": 146.8025665283203,\n      \"pinDistance\": 14.91,\n      \"pinLocations\": [\n        {\n          \"x\": 4.227952701380444,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 18.170226805137037,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 46.05478386015504,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 59.99706238766404,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 73.93934976267785,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 87.88161944268204,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 101.82389797019104,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 32.11250533264604,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 117.68761950246274,\n          \"y\": 3.1650031792503945\n        }\n      ]\n    },\n    \"numberOfPins\": 9,\n    \"instantiation\": {\n      \"kind\": \"singleton\"\n    },\n    \"pinDefinitions\": [\n      {\n        \"target\": \"ground\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"threeVolt\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_DC\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_CS\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_MOSI\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_SCK\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_MISO\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_RST\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"threeVolt\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      }\n    ],\n    \"assembly\": [\n      {\n        \"pinIndices\": [\n          0,\n          1,\n          2,\n          3,\n          4,\n          5,\n          6,\n          7,\n          8\n        ]\n      }\n    ]\n  }\n}","screen.cpp":"// overriden in targets","screenimage.ts":"\nnamespace image {\n    /**\n    * Get the screen image\n    */\n    //% blockNamespace=\"images\" group=\"Create\"\n    //% blockId=imagescreen block=\"screen\"\n    //% help=images/screen-image\n    export function screenImage(): Image {\n        return screen;\n    }\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\n\n\ndeclare interface Image {\n    /**\n     * Get the width of the image\n     */\n    //% property shim=ImageMethods::width\n    width: int32;\n\n    /**\n     * Get the height of the image\n     */\n    //% property shim=ImageMethods::height\n    height: int32;\n\n    /**\n     * True if the image is monochromatic (black and white)\n     */\n    //% property shim=ImageMethods::isMono\n    isMono: boolean;\n\n    /**\n     * Sets all pixels in the current image from the other image, which has to be of the same size and\n     * bpp.\n     */\n    //% shim=ImageMethods::copyFrom\n    copyFrom(from: Image): void;\n\n    /**\n     * Set pixel color\n     */\n    //% shim=ImageMethods::setPixel\n    setPixel(x: int32, y: int32, c: int32): void;\n\n    /**\n     * Get a pixel color\n     */\n    //% shim=ImageMethods::getPixel\n    getPixel(x: int32, y: int32): int32;\n\n    /**\n     * Fill entire image with a given color\n     */\n    //% shim=ImageMethods::fill\n    fill(c: int32): void;\n\n    /**\n     * Copy row(s) of pixel from image to buffer (8 bit per pixel).\n     */\n    //% shim=ImageMethods::getRows\n    getRows(x: int32, dst: Buffer): void;\n\n    /**\n     * Copy row(s) of pixel from buffer to image.\n     */\n    //% shim=ImageMethods::setRows\n    setRows(x: int32, src: Buffer): void;\n\n    /**\n     * Return a copy of the current image\n     */\n    //% shim=ImageMethods::clone\n    clone(): Image;\n\n    /**\n     * Flips (mirrors) pixels horizontally in the current image\n     */\n    //% shim=ImageMethods::flipX\n    flipX(): void;\n\n    /**\n     * Flips (mirrors) pixels vertically in the current image\n     */\n    //% shim=ImageMethods::flipY\n    flipY(): void;\n\n    /**\n     * Returns a transposed image (with X/Y swapped)\n     */\n    //% shim=ImageMethods::transposed\n    transposed(): Image;\n\n    /**\n     * Every pixel in image is moved by (dx,dy)\n     */\n    //% shim=ImageMethods::scroll\n    scroll(dx: int32, dy: int32): void;\n\n    /**\n     * Stretches the image horizontally by 100%\n     */\n    //% shim=ImageMethods::doubledX\n    doubledX(): Image;\n\n    /**\n     * Stretches the image vertically by 100%\n     */\n    //% shim=ImageMethods::doubledY\n    doubledY(): Image;\n\n    /**\n     * Replaces one color in an image with another\n     */\n    //% shim=ImageMethods::replace\n    replace(from: int32, to: int32): void;\n\n    /**\n     * Stretches the image in both directions by 100%\n     */\n    //% shim=ImageMethods::doubled\n    doubled(): Image;\n\n    /**\n     * Draw given image on the current image\n     */\n    //% shim=ImageMethods::drawImage\n    drawImage(from: Image, x: int32, y: int32): void;\n\n    /**\n     * Draw given image with transparent background on the current image\n     */\n    //% shim=ImageMethods::drawTransparentImage\n    drawTransparentImage(from: Image, x: int32, y: int32): void;\n\n    /**\n     * Check if the current image \"collides\" with another\n     */\n    //% shim=ImageMethods::overlapsWith\n    overlapsWith(other: Image, x: int32, y: int32): boolean;\n}\ndeclare namespace image {\n\n    /**\n     * Create new empty (transparent) image\n     */\n    //% shim=image::create\n    function create(width: int32, height: int32): Image;\n\n    /**\n     * Create new image with given content\n     */\n    //% shim=image::ofBuffer\n    function ofBuffer(buf: Buffer): Image;\n\n    /**\n     * Double the size of an icon\n     */\n    //% shim=image::doubledIcon\n    function doubledIcon(icon: Buffer): Buffer;\n}\n\n// Auto-generated. Do not edit. Really.\n","targetoverrides.ts":"/**\n * Tagged image literal converter\n */\n//% shim=@f4 helper=image::ofBuffer blockIdentity=\"images._spriteImage\"\n//% groups=[\"0.\",\"1#\",\"2T\",\"3t\",\"4N\",\"5n\",\"6G\",\"7g\",\"8\",\"9\",\"aAR\",\"bBP\",\"cCp\",\"dDO\",\"eEY\",\"fFW\"]\nfunction img(lits: any, ...args: any[]): Image { return null }\n\n// set palette before creating screen, so the JS version has the right BPP\nimage.setPalette(hex`__palette`)\nlet screen = image.create(_screen_internal.getScreenWidth(160), _screen_internal.getScreenHeight(120)) as ScreenImage\n\nnamespace image {\n    //% shim=pxt::setPalette\n    export function setPalette(buf: Buffer) { }\n}\n\nnamespace _screen_internal {\n    //% shim=pxt::updateScreen\n    function updateScreen(img: Image): void { }\n    //% shim=pxt::updateStats\n    function updateStats(msg: string): void { }\n\n    //% shim=TD_ID\n    export function getScreenWidth(defl: number) {\n        return control.getConfigValue(DAL.CFG_ARCADE_SCREEN_WIDTH, defl)\n    }\n\n    //% shim=TD_ID\n    export function getScreenHeight(defl: number) {\n        return control.getConfigValue(DAL.CFG_ARCADE_SCREEN_HEIGHT, defl)\n    }\n\n    control.__screen.setupUpdate(() => updateScreen(screen))\n    control.EventContext.onStats = function (msg: string) {\n        updateStats(msg);\n    }\n}\n","text.ts":"namespace image {\n\n    export interface Font {\n        charWidth: number;\n        charHeight: number;\n        data: Buffer;\n        multiplier?: number;\n    }\n\n    //% whenUsed\n    export const font8: Font = {\n        charWidth: 6,\n        charHeight: 8,\n        data: hex`\n2000000000000000 210000005e000000 2200000e000e0000 230028fe28fe2800 24004c92ff926400 250002651248a640\n26006c92926ca000 270000000e000000 280000007c820000 29000000827c0000 2a00543810385400 2b0010107c101000\n2c00000090700000 2d00101010101000 2e00000060600000 2f00006010080600 3000003c42423c00 310000447e400000\n3200004462524c00 330000424a4e3200 34003028247e2000 3500004e4a4a3200 3600003c4a4a3000 3700000262120e00\n380000344a4a3400 3900000c52523c00 3a0000006c6c0000 3b00000096760000 3c00102828444400 3d00282828282800\n3e00444428281000 3f00000259090600 40003c425a560800 4100781412147800 42007e4a4a4a3400 4300003c42422400\n4400007e42423c00 4500007e4a4a4200 4600007e0a0a0200 4700003c42523400 4800007e08087e00 490000427e420000\n4a002040423e0200 4b00007e08146200 4c00007e40404000 4d007e0418047e00 4e00007e04087e00 4f003c4242423c00\n5000007e12120c00 5100003c5262bc00 5200007e12126c00 530000244a522400 540002027e020200 5500003e40403e00\n5600001e70701e00 57007e2018207e00 5800422418244200 5900060870080600 5a000062524a4600 5b00007e42420000\n5c00000608106000 5d000042427e0000 5e00080402040800 5f00808080808000 6000000002040000 6100003048487800\n6200007e48483000 6300003048484800 6400003048487e00 6500003068585000 660000107c120400 67000018a4a47800\n6800007e08087000 690000487a400000 6a000040847d0000 6b00007e10284000 6c0000427e400000 6d00780830087000\n6e00007808087000 6f00003048483000 700000fc24241800 710000182424fc00 7200007810081000 7300005058682800\n740000083e482000 7500003840407800 7600001860601800 7700384030403800 7800004830304800 7900005ca0a07c00\n7a00004868584800 7b00000836410000 7c000000fe000000 7d00004136080000 7e00000804080400 a000000000000000\na10000007a000000 a200003048fc4800 a30090fc92928400 a400542844285400 a5002a2c782c2a00 a6000000ee000000\na7000094aaaa5200 a800000200020000 a9003e414955413e aa0000242a2e0000 ab00102854284400 ac00001010107000\nad00001010101000 ae003e415d45413e af00000202020200 b000000814140800 b1008888be888800 b2000024322c0000\nb30000222a140000 b400000004020000 b50000f840207800 b6000c1e7e027e00 b700000010000000 b800000080400000\nb90000243e200000 ba0000242a240000 bb00442854281000 bc00025f70f84000 bd00021f90c8b000 be0011557af84000\nbf000030484d2000 c000601916186000 c100601816196000 c200601a151a6000 c300601a151a6100 c400601914196000\nc500601a151a6000 c6007c0a7e4a4200 c700001ea1611200 c800007c55564400 c900007c56554400 ca00007c56554600\ncb00007c55544500 cc0000457e440000 cd0000447e450000 ce0000467d460000 cf0000457c450000 d000087e4a423c00\nd100007e09127d00 d200003845463800 d300003846453800 d400003846453a00 d500003a45463900 d600003845443900\nd700442810284400 d80000fc724e3f00 d900003c41423c00 da00003c42413c00 db00003c42413e00 dc00003c41403d00\ndd00040872090400 de00007e24241800 df00007c025a2400 e0000030494a7800 e10000304a497800 e20000304a497a00\ne3000032494a7900 e40000304a487a00 e50000304a4d7a00 e600304878685000 e7000018a4642400 e8000030695a5000\ne90000306a595000 ea0000306a595200 eb0000306a585200 ec0000497a400000 ed0000487a410000 ee00004a79420000\nef00004a78420000 f00000304a4b3d00 f100007a090a7100 f2000030494a3000 f30000304a493000 f40000304a493200\nf5000032494a3100 f60000304a483200 f700101054101000 f800007068583800 f900003841427800 fa00003842417800\nfb00003842417a00 fc00003842407a00 fd0000b84241f800 fe0000ff24241800 ff00005ca1a07d00 0001601915196000\n010100304a4a7a00 0201611a16196000 030100314a4a7900 04013c0a094abc00 050100182464bc00 0601003846452800\n070100304a494800 0801003846452a00 090100304a494a00 0a01003844452800 0b010030484a4800 0c01003845462900\n0d010030494a4900 0e01007c45463900 0f0100314a497e00 1001087e4a423c00 110130484c7e0400 1201007d55554500\n130100326a5a5200 1401007d56564500 150100316a5a5100 1601007c55544400 170100306a585000 1801003f65a52100\n1901001874ac2800 1a01007c55564500 1b010030695a5100 1c01003846553600 1d0100304a49f200 1e01003946563500\n1f0100314a4af100 2001003844553400 21010018a4a57800 2201001ea1691a00 23010018a6a57800 2401007812117a00\n25017e080a710200 2601047e147e0400 2701047e0c087000 28010002457e4500 29010002497a4100 2a0100457d450000\n2b01004a7a420000 2c0100014a7a4900 2d0100014a7a4100 2e0100217fa10000 2f0100247da00000 300100447d440000\n3101004878400000 32017e0022423e00 33013d0040847d00 34012040463d0600 350100800af90200 360100bf440a3100\n370100bf48142000 3801007810284800 3901007c40424100 3a0100467d400000 3b01003fa0602000 3c0100a17f200000\n3d01007c41424100 3e0100457e410000 3f01007e40484000 400100427e400800 4101107e48404000 420100527e480000\n4301007c0a117c00 440100780a097000 450100bf42043f00 460100bc44043800 4701007c09127d00 480100790a097000\n49010a0678087000 4a01003f02847f00 4b01003c04847800 4c01394545453900 4d0100324a4a3200 4e01394646463900\n4f0100314a4a3100 50013a4544463900 5101324948320100 52013c427e4a4200 5301304830685000 5401007c16354800\n5501007812091000 560100bf49093600 570100bc48040800 5801007d16354800 5901007912091000 5a01004856552400\n5b0100505a692800 5c01004856552600 5d0100505a692a00 5e010012a5691200 5f010028ac741400 6001004855562500\n61010050596a2900 62010101bf410100 630100049f641000 640104057e050400 650100083d4a2100 660102127e120200\n670100183e582000 6801003a41423900 6901003a41427900 6a01003d41413d00 6b01003a42427a00 6c01003942423900\n6d01003942427900 6e01003a45453a00 6f01003a45457a00 70013a41403a0100 71013a41407a0100 7201001f60a01f00\n7301001c60a03c00 7401782211227800 7501384231423800 7601081261120800 770100b84241fa00 7801040970090400\n79010064564d4400 7a0100486a594800 7b010064544d4400 7c010048685a4800 7d010064554e4500 7e010048695a4900\n7f0100087c020400 8f01003452523c00 920100887e090200 a0013c42423c0806 a101003048483008 af01003e403e0806\nb001003840781008 b501006a5a4a4e00 b601005878585800 d101003845463900 d2010030494a3100 e601003845563500\ne7010030494af100 fa0100742a750000 fb0100304c4a7d00 fc0178147e554400 fd0130487a695000 fe010078744e3d00\nff0100706a593800 18020012a5691200 19020028ac741400 1a020101bf410100 1b0200049f641000 bb0200000c0a0000\nbc0200000a060000 bd020000060a0000 c602000201020000 c702000102010000 c902000202020000 d802000102020100\nd902000002000000 da02000205020000 db02000040800000 dc02000201020100 dd02020100020100 7403000002010000\n7503000080400000 7a030000c0800000 7e03000096760000 8403000003000000 8503020003000200 8603037c12127c00\n8703000010000000 880303007e4a4200 890303007e087e00 8a030300427e4200 8c03033c42423c00 8e0303000e700e00\n8f03035c62625c00 900302003b400200 9103781412147800 92037e4a4a4a3400 9303007e02020200 9403605846586000\n9503007e4a4a4200 96030062524a4600 9703007e08087e00 98033c4a4a4a3c00 990300427e420000 9a03007e08146200\n9b03601806186000 9c037e0418047e00 9d03007e04087e00 9e0300424a4a4200 9f033c4242423c00 a003007e02027e00\na103007e12120c00 a30300665a424200 a40302027e020200 a503060870080600 a60318247e241800 a703422418244200\na8030e107e100e00 a9035c6202625c00 aa0300457c450000 ab03040970090400 ac030030484a7900 ad030030685a5100\nae0378100a09f000 af03003a41200000 b0033a4043403a00 b103003048487800 b20300fe25251a00 b3030c30c0300c00\nb403344a4a4a3000 b503003068585000 b603021aa6a24200 b7033c080404f800 b803003c4a4a3c00 b903003840200000\nba03007820504800 bb03641212227c00 bc03fc2020103c00 bd03182040201800 be03112d2ba94100 bf03003048483000\nc003087808780800 c103f82424241800 c2031824a4a44800 c303304848582800 c403000838482800 c503384040403800\nc6031c20f8241800 c703c4281028c400 c8031c20fc201c00 c903304820483000 ca03000238422000 cb03384240423800\ncc0330484a493000 cd03384042413800 ce03304822493000 d0033c52525c2000 d10310344a3c0800 d203067804020400\nd303120a7c020400 d4030d7009040800 d5031824ff241800 d603384828483800 d70348302221d800 da031c2221a14200\ndb031824a4a44200 dc037e1212020200 dd0300fc24240400 de033e2010087c00 df030c0ac9281800 e003700c621c7000\ne10301092516f800 e2039ea0bea07e00 e30398a0b8a07800 e4030c1214107e00 e503001028207800 e603be9088887000\ne70348544e443800 e803245252524c00 e903285454544800 ea0364524c526400 eb03086458640800 ec03385454542200\ned03306848682400 ee03184a7e4a1800 ef031848ff0a0800 f003483020205800 f10378a4a4a49800 f203304848485000\nf303006080847d00 f4033c4a4a4a3c00 f503003058584800 0004007c55564400 0104007c55544500 020401013f857900\n0304007c06050400 04043c4a4a422400 050400244a522400 060400427e420000 070400457c450000 08042040423e0200\n09047c027e483000 0a047e087e483000 0b0402027e0a7200 0c04007c102a4500 0d047c2112087c00 0e040c5152523d00\n0f043f20e0203f00 1004781412147800 11047e4a4a4a3000 12047e4a4a4a3400 1304007e02020200 1404c07c427ec000\n1504007e4a4a4200 160476087e087600 170424424a4a3400 1804007e08047e00 1904007d120a7d00 1a04007e08146200\n1b04403c02027e00 1c047e0418047e00 1d04007e08087e00 1e043c4242423c00 1f047e0202027e00 2004007e12120c00\n2104003c42422400 220402027e020200 23040e5050503e00 240418247e241800 2504422418244200 26043f2020bf6000\n27040e1010107e00 28047e407e407e00 29043f203fa07f00 2a04027e48483000 2b047e4848307e00 2c04007e48483000\n2d0424424a4a3c00 2e047e183c423c00 2f04006c12127e00 3004304848784000 3104003c4a4a3100 3204007868502000\n3304007808080800 3404c0704878c000 3504306868500000 3604483078304800 3704004058683000 3804784020107800\n3904794222127900 3a04007820304800 3b04403008087800 3c04781020107800 3d04781010107800 3e04304848483000\n3f04780808087800 4004fc2424241800 4104304848485000 4204080878080800 43041ca0a0a07c00 44041824ff241800\n4504004830304800 46043c2020bc6000 4704182020207800 4804784078407800 49043c203ca07c00 4a04087850502000\n4b04785050207800 4c04007850502000 4d04485868300000 4e04783030483000 4f04502828780000 50040030696a5000\n51040032686a5000 5204023f0a887000 530400780a090800 5404003068584800 5504005058682800 560400487a400000\n5704004a78420000 5804004080847d00 5904700878502000 5a04781078502000 5b04047e14106000 5c04007822314800\n5d04784122107800 5e0418a1a2a27900 5f043c20e0203c00 6204027f4a483000 6304087e58502000 70040e107e100e00\n7104182078201800 72043c4a4a4a3c00 7304306858683000 7404001e70180c00 7504001860301000 9004007e02020300\n9104007808080c00 9204087e0a0a0200 9304207828080800 96043b043f043be0 970424183c1824c0 9a04003f040a31c0\n9b04003c101824c0 ae04060870080600 af040c10e0100c00 b004161870181600 b1042c30e0302c00 b20421120c1221c0\nb3040024181824c0 ba047e0808087000 bb04007e08087000 d804003452523c00 d904002868583000 e20400457d450000\ne304004a7a420000 e8043c4a4a4a3c00 e904003058583000 ee04003d41413d00 ef04003a42427a00 d005681020285000\nd105484848784000 d205004830600000 d305080808780800 d405680808087800 d505000008780000 d605080818680800\nd705087808087800 d805784050487800 d905000008180000 da0504040404fc00 db05484848483800 dc050e4848281800\ndd05087848487800 de05582010487000 df05000004fc0000 e005004040487800 e105000878483800 e205487840281800\ne305041c0404fc00 e405485848483800 e50504f820140800 e605485060685000 e705f40424241c00 e805080808087000\ne905785058403800 ea05487808087800 f005087800087800 f105081800087800 f205081800081800 f305000010080000\nf405100800100800 021e7c5455542800 031e007e48493000 0a1e007c45443800 0b1e003049487e00 1e1e007c15140400\n1f1e001079140800 401e7e0419047e00 411e780832087000 561e007c15140800 571e00fc25241800 601e004854552400\n611e0050586a2800 6a1e04047d040400 6b1e00083d482000 801e7c2112207c00 811e384132403800 821e7c2012217c00\n831e384032413800 841e7c2110217c00 851e384230423800 f21e040972080400 f31e00b84142f800 a3207e0a7a120a00\na420a8fcaa828400 a720087e2a1c0800 ab200098a4a6bf02 ac20183c5a5a4200 af20627f22443800 9021103854101000\n912108047e040800 9221101054381000 932110207e201000 9421103810103810 95212844fe442800 \n`,\n\n    }\n\n    // A unicode 12x12 pixel font based on https://github.com/adobe-fonts/source-han-sans\n    //% whenUsed jres\n    export const font12: Font = {\n        charWidth: 12,\n        charHeight: 12,\n        data: hex``\n    }\n\n    export function getFontForText(text: string) {\n        for (let i = 0; i < text.length; ++i) {\n            // this is quite approximate\n            if (text.charCodeAt(i) > 0x2000)\n                return image.font12\n        }\n        return image.font8\n    }\n\n    //% deprecated=1 hidden=1\n    export function doubledFont(f: Font): Font {\n        return scaledFont(f, 2)\n    }\n\n    export function scaledFont(f: Font, size: number): Font {\n        size |= 0\n        if (size < 2)\n            return f\n        return {\n            charWidth: f.charWidth * size,\n            charHeight: f.charHeight * size,\n            data: f.data,\n            multiplier: f.multiplier ? size * f.multiplier : size\n        }\n    }\n\n    //% whenUsed\n    export const font5: Font = {\n        charWidth: 6,\n        charHeight: 5,\n        // source https://github.com/lancaster-university/microbit-dal/blob/master/source/core/MicroBitFont.cpp\n        data: hex`\n2000000000000000 2100001700000000 2200000300030000 23000a1f0a1f0a00 24000a17151d0a00 2500130904121900\n26000a15150a1000 2700000300000000 2800000e11000000 290000110e000000 2a00000a040a0000 2b0000040e040000\n2c00001008000000 2d00000404040000 2e00000800000000 2f00100804020100 30000e11110e0000 310000121f100000\n3200191515120000 33000911150b0000 34000c0a091f0800 3500171515150900 3600081416150800 3700110905030100\n38000a1515150a00 390002150d050200 3a00000a00000000 3b0000100a000000 3c0000040a110000 3d00000a0a0a0000\n3e0000110a040000 3f00020115050200 40000e1115090e00 41001e05051e0000 42001f15150a0000 43000e1111110000\n44001f11110e0000 45001f1515110000 46001f0505010000 47000e1111150c00 48001f04041f0000 4900111f11000000\n4a000911110f0100 4b001f040a110000 4c001f1010100000 4d001f0204021f00 4e001f0204081f00 4f000e11110e0000\n50001f0505020000 5100060919160000 52001f05050a1000 5300121515090000 540001011f010100 55000f10100f0000\n5600070810080700 57001f0804081f00 58001b04041b0000 590001021c020100 5a00191513110000 5b00001f11110000\n5c00010204081000 5d000011111f0000 5e00000201020000 5f00101010101000 6000000102000000 61000c12121e1000\n62001f1414080000 63000c1212120000 64000814141f0000 65000e1515120000 6600041e05010000 67000215150f0000\n68001f0404180000 6900001d00000000 6a000010100d0000 6b001f040a100000 6c00000f10100000 6d001e0204021e00\n6e001e02021c0000 6f000c12120c0000 70001e0a0a040000 7100040a0a1e0000 72001c0202020000 730010140a020000\n7400000f14141000 75000e10101e1000 7600060810080600 77001e1008101e00 7800120c0c120000 7900121408040200\n7a00121a16120000 7b0000041f110000 7c00001f00000000 7d00111f04000000 7e00000404080800 d3000c1213130c00\nf3000c12130d0000 04010e05051e1000 05010609191f0800 06010c1213131200 07010c1213130000 18010f0b1b190000\n19010e151d1a0000 41011f1412100000 4201100f14120000 43011f0205081f00 44011e03031c0000 5a0110140b030200\n5b0110140b030000 7901121a17130000 7a01121a17130000 7b01121b17120000 7c01121b17120000`,\n    }\n}\n\nnamespace texteffects {\n    export interface TextEffectState {\n        xOffset: number;\n        yOffset: number;\n    }\n}\n\ninterface Image {\n    //% helper=imagePrint\n    print(text: string, x: number, y: number, color?: number, font?: image.Font, offsets?: texteffects.TextEffectState[]): void;\n\n    //% helper=imagePrintCenter\n    printCenter(text: string, y: number, color?: number, font?: image.Font): void;\n}\n\nnamespace helpers {\n    export function imagePrintCenter(img: Image, text: string, y: number, color?: number, font?: image.Font) {\n        if (!font) font = image.getFontForText(text)\n        let w = text.length * font.charWidth\n        let x = (img.width - w) / 2\n        imagePrint(img, text, x, y, color, font)\n    }\n\n    export function imagePrint(img: Image, text: string, x: number, y: number, color?: number, font?: image.Font, offsets?: texteffects.TextEffectState[]) {\n        x |= 0\n        y |= 0\n        if (!font)\n            font = image.getFontForText(text)\n        if (!color) color = 1\n        let x0 = x\n        let cp = 0\n        let mult = font.multiplier ? font.multiplier : 1\n        let dataW = Math.idiv(font.charWidth, mult)\n        let dataH = Math.idiv(font.charHeight, mult)\n        let byteHeight = (dataH + 7) >> 3\n        let charSize = byteHeight * dataW\n        let dataSize = 2 + charSize\n        let fontdata = font.data\n        let lastchar = Math.idiv(fontdata.length, dataSize) - 1\n        let imgBuf: Buffer\n        if (mult == 1) {\n            imgBuf = control.createBuffer(8 + charSize)\n            imgBuf[0] = 0x87\n            imgBuf[1] = 1\n            imgBuf[2] = dataW\n            imgBuf[4] = dataH\n        }\n        while (cp < text.length) {\n            let xOffset = 0, yOffset = 0;\n            if (offsets && cp < offsets.length) {\n                xOffset = offsets[cp].xOffset\n                yOffset = offsets[cp].yOffset\n            }\n\n            let ch = text.charCodeAt(cp++)\n            if (ch == 10) {\n                y += font.charHeight + 2\n                x = x0\n            }\n\n            if (ch < 32)\n                continue // skip control chars\n\n            let l = 0\n            let r = lastchar\n            let off = 0 // this should be a space (0x0020)\n            let guess = (ch - 32) * dataSize\n            if (fontdata.getNumber(NumberFormat.UInt16LE, guess) == ch)\n                off = guess\n            else {\n                while (l <= r) {\n                    let m = l + ((r - l) >> 1);\n                    let v = fontdata.getNumber(NumberFormat.UInt16LE, m * dataSize)\n                    if (v == ch) {\n                        off = m * dataSize\n                        break\n                    }\n                    if (v < ch)\n                        l = m + 1\n                    else\n                        r = m - 1\n                }\n            }\n\n            if (mult == 1) {\n                imgBuf.write(8, fontdata.slice(off + 2, charSize))\n                img.drawIcon(imgBuf, x + xOffset, y + yOffset, color)\n                x += font.charWidth\n            } else {\n                off += 2\n                for (let i = 0; i < dataW; ++i) {\n                    let j = 0\n                    let mask = 0x01\n                    let c = fontdata[off++]\n                    while (j < dataH) {\n                        if (mask == 0x100) {\n                            c = fontdata[off++]\n                            mask = 0x01\n                        }\n                        let n = 0\n                        while (c & mask) {\n                            n++\n                            mask <<= 1\n                        }\n                        if (n) {\n                            img.fillRect(x + xOffset * mult, y + (j + yOffset) * mult, mult, mult * n, color)\n                            j += n\n                        } else {\n                            mask <<= 1\n                            j++\n                        }\n                    }\n                    x += mult\n                }\n            }\n        }\n    }\n}\n"},"screen---ext":{"fieldeditors.ts":"/**\n * Image manipulation blocks\n */\n//% weight=70 icon=\"\\uf03e\" color=\"#a5b1c2\"\n//% advanced=true\nnamespace images {\n    //% blockId=screen_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.decompileArgumentAsString=\"true\"\n    //% img.fieldOptions.filter=\"!tile !dialog !background\"\n    //% weight=100 group=\"Create\" duplicateShadowOnDrag\n    //% help=images/sprite-image\n    export function _spriteImage(img: Image) {\n        return img\n    }\n\n    //% blockId=background_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.decompileArgumentAsString=\"true\"\n    //% img.fieldOptions.sizes=\"-1,-1\"\n    //% img.fieldOptions.filter=\"background\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _screenImage(img: Image) {\n        return img\n    }\n\n    //% blockId=tilemap_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.sizes=\"10,8;16,16;32,32;48,48;64,64;16,32;32,48;32,8;64,8;20,15;40,15\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _tileMapImage(img: Image) {\n        return img\n    }\n\n    //% blockId=tile_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.sizes=\"16,16;32,32;8,8\"\n    //% img.fieldOptions.filter=\"tile\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _tileImage(img: Image) {\n        return img\n    }\n\n    //% blockId=tileset_tile_picker block=\"%tile\"\n    //% shim=TD_ID\n    //% tile.fieldEditor=\"tileset\"\n    //% tile.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% weight=10 blockNamespace=\"scene\" group=\"Tiles\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _tile(tile: Image) {\n        return tile\n    }\n\n    //% blockId=dialog_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.decompileArgumentAsString=\"true\"\n    //% img.fieldOptions.sizes=\"15,15;18,18;21,21;24,24;9,9;12,12\"\n    //% img.fieldOptions.filter=\"dialog\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _dialogImage(img: Image) {\n        return img\n    }\n\n    /**\n     * An image\n     * @param image the image\n     */\n    //% blockId=image_picker block=\"$image\" shim=TD_ID\n    //% image.fieldEditor=\"sprite\"\n    //% image.fieldOptions.taggedTemplate=\"img\"\n    //% image.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% image.fieldOptions.decompileArgumentAsString=\"true\"\n    //% weight=0 group=\"Create\"\n    //% deprecated\n    //% help=images/image\n    export function _image(image: Image): Image {\n        return image;\n    }\n\n    //% blockId=colorindexpicker block=\"%index\" blockHidden=true shim=TD_ID\n    //% index.fieldEditor=\"colornumber\"\n    //% index.fieldOptions.valueMode=\"index\"\n    //% index.fieldOptions.decompileLiterals=\"true\"\n    export function __colorIndexPicker(index: number) {\n        return index;\n    }\n\n    /**\n     * A position picker\n     */\n    //% blockId=positionPicker block=\"%index\" blockHidden=true shim=TD_ID\n    //% index.fieldEditor=\"position\" color=\"#ffffff\" colorSecondary=\"#ffffff\"\n    //% index.fieldOptions.decompileLiterals=\"true\"\n    export function __positionPicker(index: number) {\n        return index;\n    }\n}\n","font12.jres":"{\n    \"image.font12\": {\n        \"mimeType\": \"font/x-mkcd-b26\",\n        \"data\": \"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9A9UANwHAAD4AQAI/AcAADhSIAGqCOoIrAS4Aq4BqAi4CKwG6gGqACABOVJQBFQDVAjIB0wAUgFSBgAA/AkACP4PAAA6UgAEdAYUAf4PFAH0AgAA/AEACAAI/gcAADtSAAAkCbQErwJkAhQDxAQAAPwJAAj+DwAAPVIgAJAMiAakBaYEiAawCAAA+AkACP4HAABCUkQIVARUAzYANACsDyQAAAD8CQAI/wcAAENSAAToBKoCrAH4D64AuAcAAPwJAAj+BwAAR1IACP4FKgUqASoB/g0AAPwBAAgACP4HAABKUgAA9g9QAV4JUAn2BwAA/AEACAAI/gcAAE1SAADoD6oCrAqoCugHCADoAw4I6AcIAAAATlIAAFIEUgNMAOQPSgJqBAAA/AkACP4HAABRUhAAWAiEBRIE0wQEB8gCAAL8CAAI/gcAAFRSAAG+BOoCqg2qA6oIvgcAAPwJAAj+BwAAVlIkAKwPrASmBKQEvASsBwAA/AkACP4PAABbUgAA/A8MA+QDFAn8BwAA+AEACPwHAAAAAF1SAADAANgKVgrUB3QAzAYAAPgJAAj+BwAAY1IQCPAEvAbyAbQC5AwAAPwBAAgACP4HAABkUgAAJAisB5YCrAKkDyQAAAD8AQAI/g8AAGVSoAIqCioJ6g8qAb4CoAYAAPwJAAj+BwAAZ1LABz4AqgeqBPoEqgSuBwAA/AAACP8HAABpUogIbARsAgwB/A8MAWoCKAQAAPwJAAj+B2pSAAV8BTwFPgW8A/wBBAF0BQYFdAUEAwAAb1ICAN4PVgXWB1YFVgXeDwAA/AkACP4HAABwUgAArAT8AqwB/A+qAvoGAAD4AQAI/gcAAHJSjAC8D7QFtAX2BbQHtAeMBwAA/AEACP4HdVIQABAO0AP4BfQF5AXoBwAA+AEACPwHAAB/UgAIdgVwBXQD+g94A3ADdgUAAPgJAAj+B4NSSAT8B/wH/gf8B/wH/Af8BwAE+AEACPwHh1IADvgBGATYBn4DbA9sAggE8AEACPwPAACIUoAAfAj0CbQJtAX4A1QBXAn2CVwJVAcAAIlSAACcCcoLyQmwB84FQgUOBPgBAAj+BwAAjVIICOgErALqAEsIogbkBAAA/AEACP4HAACRUjgASAz0A4wClgK8AswPIAD8AQAI/gcAAJtSAAAQCBAEEAKQAX4AEAAQCBAIEAzwAwAAnVIABBQCZAHkABwJAASIA34ACAgICPgHAACeUgAAiAloBAgCiAF+CAgICAz4AwAA4AEAAJ9SBAIEAvwBBAkECRAEEAP+CBAIEAzwAwAAoFIICAgG/gEICAgI+AcAAPwPBAQEBPwPAAChUkAIUAlICSwFNgOkASQJNAlMCUQHQAAAAKNSKAioCKQIogSgA54AkAiICIIIhAcIAAAAqFIAACQE5AMkAqQCJAMACBAH/gAQCPAHAACpUgAE/gOSBJIC/gsABBAD8AgfCBAI8AcAAKpSAAhECVwJZgUkA1wBRAE0CSQJXAdEAAAAq1IAAEgHyAR+AkgCQAcQABAP/gAQCPAHAACxUgAO/AEUDPQDVAjUBwQAEAf8ABAI8AcAALJSAACkCKQElAesBKQEMAAQDv4BEAjwBwAAs1IACLQIlASWBJQD1ACUCJQIlgiUBzQAAAC0UgAIuAiKBIoEiALrAYgIiAiMCIoHOAAAALlSKAioBKgCDAGoAggIUAQQA/4IEAjwBwAAv1IAABQIVAl+BRQFwAM0AR4JBAk8B0AAIADBUgAAtASEBLQHhAS0DAQEEAP+CBAI8AcAAMNSAAA0AhQJXgeUATQJAAQQA/4IEAjwBwAAx1IACAIK+gqqBqoC+gKqAq4Kqgr6BgAAAADJUhAI+ASWA/QAnAfwCBgKmAl+CAgK+AkABMtSAAjuCSoEqgMqCO4LAAAQB/4AEAjwBwAA0lIAAOQCvgL0D74C5AgEBBAD/ggQCPAHAADVUgAAfAl8CfwHeg0IBBgCkAF+CBAI8AcAANhSgACCB/8FqgSqBP8FggwIAv8BCAT4AwAA2VIAACoDqgjqBzYA4AlIBy4BNAk0CSwHRAHdUgAM/gOSCP4HgAFqCTgHrgE4CW4JqgcAAd5SEgiSCKgErgSgAqIBpAioCKYIKAdyAAAA31IAAkQB/AV+A3wDfAF8BX4F/AN8AUQCAADiUgAArAmsCe4FrAWAA/gBGAkOCXgGgABgAORSAAj0CdYF9AfWBfQFAAwQA/4IEAjwBwAA51IAACAB7A+4B+gHqAeoDgAG/AEQCPAHAADyUgAB/g3+Af4B/g3+AQgLmAh+AAgB+AwAAPNSBAh9BW0B/wTsAvwCAAaIAX8ECAT4AwAA9VIADPwDzA/8AewD/AvMDwAM/gMQCPAHAAD4UgAB+g+7B4AHuwe6BwAM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JAAAAK1T+AcEAPQD/AJ8B3QFhAckBPwDJAEUAgAErlMABv4BAgT6AVoD+gECDPoDSgDKD0oAAACyUwAO/gECAOoP6gHqBeIH6gXqBeoJCg8CALNTAA74AQ4E+Ae4BroG/A8IAOgMLAPqBSgIu1NAAEgMSAZIBcgEfgRIBEgFSAZICEAAAAC/UwAAgACABP4GqgWqBKoEqgSqBP4GgASAAMFTIAGoCKgK7Aq6CqgKqgruCqgKqAggAQAAwlMgASgBqAhsCroKqAooCWoErASgACABAADDUwAAAAGwAKQJdgulChQKJgl2BKAEMAFAAchTAAAACAQIHARkBIQCBAGEAmQEHAQECAAIyVMACAQIPAREBJQCFAGUAkQEPAQEBAAIAADKUwAEBAaEAXwIJATEBAQDHAOQAnAEEAQAAMtTAAQIBAgDyAh+BKgEKAMoA6gEaAQICAAEzFMUCDQERALkARwKAAh8BIQDxAI8BAAIAADNUwAAAAz8AyQI5AgkBSQCJAakBWQIBAgAAM5TAAL4AQABAAH+DwAAFAjkBAQDxAQ8BAQI0VMABBACHAuQCPAIXgVQBlAF1ghQCBAIAADUUwACoAEgCP4PJACgCwQIfAaEAeQCHAwACNZTBAT8B5QElASUAvwPAABoCIgFCAPoBBgI11MAAHQIHATcBFQFXAJcAlIF2gQaBDAIAADYUwAIpAiUCIQJvAaGBIYEvAaECZQIJAgACNlTUAZYAVQI8g9UAFQDBAh8BIQDxAI8DAAA21MAAKwIoAb+AaQAAA78AXIMkgOSAnIMAATgUwAA6Ah2CFYPVg9GD1YPXg9WD3gIyAgAAOFTAACoANgHvwfaB/oHkAAMDPQChAF8BgAE4lMIAKoE7Af4B/wH6A/oAPwH7AXqB4gJgAjjUwAAAAD8DwQEBAQEBAQEBAQEBPwPAAAAAORTAAAIAIgPiASIBP4EiASIBIgEiA8IAAAA5VMAAGAAEADMByoCKAIoAugLCAgIDPgDAADmUwAAgAi8BKQEpAPkAKQApAikCLwIgAcAAOhTAAD8AwQB/AkACAQGhAF8BAQIBAz8AwAA6VMAAPwDBAEEAfwBAAD8DwQABAIEAvwBAADqUwAAAAh8BEQCRAFEAEQARAFEAnwEAAgAAOtTAAD8AwQBBAH8AQAA/AMAAQAB/g8AAAAA7FOAAEQARA8kCRQJ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ggCyAIoAAAB9VAAAEADQB1gCWALUAxIA1A9YAEgC0AEQAIZUAAD8AwQB/AEwAPgDlgSUBPQFBAX8BAACi1QAAPwDBAH8ARAACAAOAPgPKAEoASgBAACMVAAClAFUAPwHUgAAAPwHBAIEAgQC/AcAAI9UAAD8AwQB/AQAAtQBFAj0D4QAQAEgBgAEkFQAAPwDBAH8AWAA/A8CANAAEAkQCP4HEACSVAAIHAgUBNQDXABAAFwAVADUBxwIAAgABpVUAAD8AwQB/AEAAJAPkASQBP4EkASQDxAAllQAAPwHBAH8DAAC/gkIDPAD/A8EBPwPAACZVAAA/AMEAfwJAASQA34IEATyB5YIVAgQBJpUAAD8AwQB/AFQAEgCLgK1BDQFTAlEAEAAplQAAPwDBAH8AQAI7ASsAv4BrAKsBLwJAAinVAAA/AMEAfwBQAi8BJQDYAD4CQAI/gcAAKhUIAARAIoPoASsBKMEkgSOBJIEog8uAAAAqlQAAPwHBAL8AwAIrAcgAP4PIACoAyQMAACsVAAA/AMEAfwBAAgoCKgECgPMBQgEaAhACK9UAAD8AwQB/AEQAYgPVgllCXQJXAmED4AAsVQAAPwBBAH8AQAA+AeoAqwCqgKoAvgHAACyVAAA/AMEAfwJAAhOBEwC+AFMAk4ESggAALNUAAD8AwQB/AEACCQFtARvAiQClAVECAAAuFQADPgDCACoB6gCqAoIC/4ICAfKCCwIAAa9VAAA/AMEAfgA/g8CBCIF+gSiBQIE/g8AAMBUAAIEAXQBVA/UBFUE1gRUAVQCdAUEBQAIwVQAAMAPQAReBNIHEgDSD1IEXgRABMAPAADEVAAA/AMEAfwBAAiIBP4CiACIAP4CiAyACMZUAAD8AwQB/AEACCgJpASWBFQCTAHEAAAAx1QAAPwDBAH8AQAIJAkkCb4PJAkkCSAJAADIVAAA/AMEAfwBYAAwD6gEpgSoBDAPYABAAMlUEADUB1QCXgJUAtQJEAz+AhADkgRUCAAHzVQAAPwDBAH8AQAA+A8IAOgDLgHoCQgI+AfOVAAA/AMEAfwBAAgkCM4EBAMEBc4EJAgECNFUAAD8AwQB/AVABAQE/AcEBPwHBATkBAAA11QAAPwDBAH8AQAAfAECAZAPPgFIAUQBJADfVAAA/AMEAfwBAAT8BYIEEALOCAgI+AcAAOFUAAAACP8LrQatBq0CrQKtBq0G/wsACAAA5VQAAEQAfAdsBWwFbAVsB3wARAj8D0QAAADmVAAA/AMEAfwBAAj8D5IAEAz+A5AFVggABuhUAAD8AwQB/AEAAPYPUAFeAVAJUAn2BwAA6VT8AwQB/AEAAHwJVAlUCfwPVAlUCXwJAADqVAAA/AMEAfgMAgL+CZII/gf8DwIA/gMAAO1UgAieCJIIkgSeA8AAnAOUBNQE3AiACAAA7lQAAP4BggD+AIABagEqCb8PagEuASoBCQHyVAAAEgCyD78EigSgBJ4EiQSJBLkHCQAIAPpU/AMEAfwBAADoD6gCqAL+D6gCqgrsBwAA/FQAAPwBhAD8AAAAvAisCK4OrAGsAbwABAABVQAA/AcEA/wDAACoDqgKqgqqCqgKqA4IAAZVAAD8AwQB/AlACCgJngaIBPwGzAVYCEAIB1UAAAAP/gAiDuoKqgpqCqoKqgoqDSIBAAAJVQAA/AMEAfwBAAgoCS4F6gMoBS4JKAkAABBVAAb8AQQAXAdcBVwF/gVcBVwFfAcUAAAAFFUAAPwDBAH8AQAAqge6BK4EqgS6BKIHIAAgVQAA/AMEAfwBAAiUBJYC1AmUCJYMNAMAACRV/AMEAfwBAAj4BJQClgH0AZwClAT0BIAIJ1UAAPwDBAH8AQAE/AdUAjwA+A8EAPwDAAAsVQAA/AMEAfwBAAz4AygIPgdsAGwHTAgABC5VCAAIAHwPXgVcBVwFfgVcBVwFXA9EAAAAL1UAAPwDBAH8AQAA/A+qBKgE/geoBKgEAAAxVQAA/AMEAfwBAAD+B2oFagVqBWoF/gcAADdVAAD8AwQB/AEACPQH7ADmAmUKZAr0ByQAOFUAAPwDBAH8CAAGKACkBLIJNAr0ACQGCAg+VQAA/AMEAfwBAAjUChQK/A8UCtIKUAoQCENVAAD+AYIA/gAIAO4PqAKvAqoKqgrqDwAARFUAAPwDBAH8ASAElAJUCiwJxAdkAJQDAARGVQAAAAD0DxQAfAcWBTQFVAVcBxQA9A8AAEpVAAD8AwQB+AD+DzIAzAHkAxQB5Aj8BwQAT1UAAP4PKgCqB74CgAK+AqoDKggqCP4HAABTVcIAOgCqB6oEqgS6BJAEzgS0BDQHTACEAF9VAAb8AaoHqgKqAroDIAR+AogB6AIYBAAAYVUAAPwDBAH8AQAAKAH+DwAA/g8oASgBAABkVfwDBAH8AQAAfALUAtQCfgJUD1QCfAIAAGVVAAD8AwQB/AEQAEgHRAXyBVQFRAVIB1AAZlUAAPwDBAH8AQAM/gMICGAIiQkKDugJAABqVQAA/AMEAfwBgAj+B0AA+A+MBIoE+A8AAHBVAAD8AwQB+AmOCVIIfgVSAl4B0gFeAAAAeFX8AwQB/AEADKwDLAYsAf4PLAEsArwPCAB8VQAA/AMEAfwBAABsB6QApg+0AKQEpAMAAIBVAAD8BwQC/AMAAKQPtAlWCVQJpA6MAAAAglX8AwQB/AEAAPwA1A/UCPwJ1ALUB/wJAACDVQAA/AMEAfwA4A8UALQCngfUAhQI9AcAAIRVAAFEAVQPVgtUC/wLVAtUC9YL1A9EAQAAh1UAAPwDBAH8DGQCng/0AZQCYAj4CP4HAACJVQAA/AMEAfwBYAD4DwYAUAlUBdQDXAVQCYpVAAD8AwQB/AzwAwgHqAIIDX4CiAVqCAAGlFUAAPwDBAH8DAAC/Ak0CPQKtA+0CrwKAACYVfwDBAH8AQAAvA+wALAP/gCwD7AAvA8AAJpVAAD8AYQAfAjwBVgFNgOUAzwFUAXwCQABnFUAAQQBfA/cC1wLXgtcC1wL3At8DwQBAAGdVQAA/AMEAfwBAAC+BqoEqgWqCKoIvgcAAKdVAAD8AwQB/AEICPQLtAq2CrQK1AscCAAAqlUAAIQIvAisD7wIhAj+CYQCvASsCrwKhAirVQAA/AMEAfwJAAg+BTQDwAM8BQQJfAkAAKxVKAAsAJwP/ADcB9wF3AXcBfwHmgioDyAArlUAAAAE/gVaBVoF/g9QBV4FWgX6BQ4EAACyVQAA/gMCAf4BGAznApAAUAaOAAgI+AcAALNVAAD8AwQB/AEACNQLrAquCqwK1AsUCAAAtVX+AYIA/gAAAPAPkgSXBPIHkASXBPIHAgC2VQAAGAAKB3wFWAXeBVgFWAV8BQoHGAAAALdV/AMEAfwBAAjUC1QIVAZWAVQEVAjUCwAIu1UAAPwDBAH8ARgA2A+0AvIPlAEYCMgHEADFVQAA/AMEAfwBAAh8BVwFXgNeA9wFfAUACc5VAAD8AwQB/AEADP4AqgaqAP4EqgGCDwAA01UAAPwDBAH8AQAIUgV2A4YPlgNSBTAFAAjaVQAA/AMEAfwJAAT8ANQO1gDUBdwIwAcAANxVAAD8AwQB/AFAADQHfgfUB9wH1AfUBwAA4VX8AwQB/AEABMgCVAqiBxAAUgJ0CuQHCADjVQAA3A/UB9QP3A+EAVQC1AsECPwHAAAAAORV/AEEAfwBAATgB2wGeAbuB2gGaAbsDyAI5lUAAPwDBAH8AQAMVAH0CV4HFAGUBTAIAADoVQAA/AMEAfwAAA5EAJADzAKoC6gK6AcAAu9VAAD8AwQB+AA+AWICagRaBVoEQgF+AwAC/VUAAPwDBAH8BCQC/g9UAXQJEAbOAQgGOAgAVgAA/AMEAfwBAAD0DxQC9gVUBVwHFAj0BwFWAAD+AYIA/g74AYQE9AcUAIcEfAOFBnQCBlb8AwQB/AEACPQK1ArWBvQD1AbWCvQKAAAJVgAAgg6+Au4KrgqvBq4M7gquCr4Kgg4AAA5WAAD4AwgB8AUEBXwF/AN8A3wF/AV8BwQDF1YAAAwARg/WC/QL9gv0C/QL9gvFD5wAAAAbVgAA/AMEAfwI+AcEAfQPJgKEAfQPpAAEAx9WAAD8AwQB/ACAD34FUAWID/wHBAD8AwAAMVYAAPwBhAB8CAAH/A60AdwF/AfUAdwPAAAyVgAA/AMEAfwDfAKuD3wC/geSAP4PAAAAADRWAAD8AwQB/AEQBNgD7gL0B/AC7gLUBxAANlYAAPwDBAH4AAQN/gFUAf4N/AMkAOIPIgA5VgAA/gOCAf4BAAz6AVYJUw9WAfoBMgwAADtWAAD8AwQB/AEAAHwP3AteC1wL3At8DwQBP1b8AYQA/AAACF4FVgFSBf4JWgFSBV4AAA5BVgAA/AMEAfwAIA1UAdwHBAvcC1QJdAEADWJWAAD8AwQB+Al8CAwFZAN2ASQDRAV8CQAAaFYAAEACXA9UCdQJfA9gAEwP9Al0CVwPQAJpVgQIxAv8CvwLRAj8D0QI/AvsCvwLBAgAAGpWAAD8AwQB/AnABbwF9AOUD/QPvAPgBQAIdFYAAPwBhAD8BBAE9Af0AvYC9ALUBvQHEAiHVgAA/AMECfwH5As/COQPJA3kA/8PJACgA45WAAD8AwQB/AFACDwGvAa+A7wPvAPkBAAAo1YAAIgH7gWuBW4HWABuB24FrgVuBYgHAAC0VgAO4AG8BPQH9AfsD7gB1Al0BvwFYAgAALdWAAD8AwQB/AUADPwP7An+AfQH7AX8CQAAvFYAAPwDBAH8AQAA9A/yBfoMMgG5CLUHgADCVgAACAL+B/4H/gf+BvgA/gb+B/4HCAUAAclWAAD+AYIAfAH3BqUCBwP9D1cF9QdXBQAAylYABbQD/Av8B/wFngX8AfwD/AXcB5QHAADaVgAA/g8CBAIFggRCBDoEwgQCBQIE/g8AANtWAAD8DwQExAU8BAQEBAR8BIQEBAT8DwAA3lYAAP4PAgTyBJIEkgSSBPIEAgQCBP4PAADgVgAA/g8CBCIFIgWiBHoEogQiBQIE/g8AAOJWAAD+BwIEkgRSBFIFMgX6BRIEAgT+BwAA41YAAP4HAgQKBGoECgUKBfoECgQCBP4HAADkVv4PAgRSBJIEkgT6BZIGkgZSBgIE/g8AAO1WAAD+BwIEKgXqBCoE6gUqBSoFAgT+BwAA8FYAAP4PAgSiBWIE+gViBKIEIgUCBP4PAADxVgAA/A8EBEQFJAVXBZQEdAUUBQQE/A8AAPJWAAD+DwIEkgT6BZIEkgT6BZIEAgT+DwAA81YAAP4PAgZaB0IFygTCBDIFCgUCBP4PAAD0VgAA/g8CBKoEqgT6BaoEqgSKBQIE/g8AAPpWAAD+DwIEEgTSBVIFegVSBdIFAgT+DwAA/VYAAP4PAgQqBSoF+gUqBWoFKgUCBP4PAAD+VgAA/w8BBCkFLQUVBZUFrQYlBgEE/w8AAANXAAD8BwQE9AX0BPwE/AX0BPQE9AUEBPwHBlf+BwIG3gZWBlYFVgVWBF4GwgYCBP4HAAAIVwAA/gcCBD4E/gU6BroGegY6BQIE/gcAAAtXAAD+BwIE6gWqBUoEegWKBW4GAgT+BwAADVcAAP4HAgT+BX4FfgX+BX4FegUCBP4HAAAPVwAA/gcCBGoE6gX6BuoG+gZqBAIE/gcAABJXAAD+DwIM6g1qC3oLagtqC+oLAgz+DwAAE1cAAP4PAgjCC/oL6gvqC+oL+gsCCP4PAAAWVwAA/gcCBP4H9gf2B/YHfgbiBwIE/gcAABhX/g8CBP4E/gX+BP4E/gb+B/4EAgT+DwAAH1cABCAEIAQgBCAE/gcgBCAEIAQgBAAEAAAjV0AIRAhMCSwJNAmkDzQJNAlMCUQIQAgAACdXAAAADPwDBAhECEQI9A9ECEQIRAgECAAAKFcIAYgAyA84AI4IiAiICOgPiAiICIgIAAAtVwAIJAkkCSQJJAm/DyQJJAkkCSQJIAgAADBXAAIQAv4BEAFAAPwHIAggCP4JEAgQCfgEM1cABBAC/gMQAQAM/gMAAAAA/AcAAAAA/g86VwACEAL+AxABAAEiCfIEKgLmCSIM4AMAAD5XAAQQAv4DEAoABIQDfAiEBCQHPAXgBAAIQFcQAhAC/gEQAQAI8A8ACAAI/g8gCCAIIAhCVwACEAL/AZAEAAb+ATIM0gISA5ICcgQCCEdXAAIQAv4BEAEwAAwCKgEoCagICAz4AwAASlcQAhAC/gEQCQAMCAL4AUoISAhICMgHCABOVwACEAL+ARABQAg0CAoG6AEIAkgEOAgAAE9XAAIQAv4BEAFEAUQAJAD8DwQAJADEAIAAUFcgCJAIjgiwCIAI/g+gCJAIjgiQCCAIAABRVwACEAL+ARABAAzoAyoAKgDoBwgICAYAAFdXAAIQAf4BkACACAgESAP+AMgBSAJ4BEAIWlcACD4IAAkACX4JRg8qCRIJKgkmCUAIAABbVwACEAL+ARABAAQkBqQFZAQkBKQFJA4ACF1XAAIQAv4BEAEACP4JAgQCAvoBAgQCBP4JXlcQAhAC/gMQAQAC/AKEAoYCpgqkCJwHAABfVwACEAL+ARABgAkIBHgEigOMAngECAgIBGBXAAR+BQIFPgUCBaAHMAUOBRAFIAVABAAAYVcAAhAC/gMQCQAM+APICX4GSAbICVgIAABkVxAC/gEQAQAA/AMkASQB/w8kASQB/AMAAGZXgAAQAf4AkAAABP4EkgSSBJIEkgT+BAAEalcAABAC/gMQAQIAugCCAP4PggCyAIoAAABvVwAEEAL+AxACQAlECCQI/AskCEQIhAgAAHdXAAIQAv4DEAEEAPQDFAH0CQQI/AcEAAAAglcAAEACVAr0C1QKVAr8D1QK8gtSCkAAAACDVwACEAL+ARABAAQoBMgFCgQIB+gECAQAAIRXiAiICmgKGApMCkgPeAqsCqwKiApICAAAi1cAAEAEygQ+BAoFfgUKBwAFHgVABX4EAASSV0AIaAlICWwJCgkID2gJTAlICSgJQAgAAJtXAAQQBP4DEAIACKAEngLCD4IBvgKgBKAIolcAAhAC/gEQAQAO/AGUD1QEVARSBNIPEACjVwACEAL+AxAJBAj0C1QKVApUClQK9AsECKZXAAAACP4KqgoqCioPagqqCqoK3gqACoAIq1ckBJQF/gUUBQAF1Ac0BR4FBAV8BIAEQACuVwAEEAL8AxACgACoArgDrAqoCpgKqAaoAMJXAAIQAv4DEAkACfwHrAasBfwIrAisCPwAw1cABBAC/gMQAUAIKAkuBegDLAUsCSAJAADLVwACEAL+ARABAAh8CVQJVAn8D1QJVAl8Cc5XAAAQAv4BAAz4AygAKArICX4EiAduCAgG1FcAAhAC/gEQAQAA6A+oAqgC/g+oAqoK6gffVwAAEAL+ARABQACoAugKCAR+AogFaggMBuBXAAIQAv4BEAEAAvwCtAK2D7QCtAL8AgAC91cAAJQC1AKeD/QCEAhIBv4BCAEIAPgHAAz5VwABEAL+AQABJACkB7QEpgSkBLwErAckAPpXAABIAUgF/AR4BXgHeAV4BfwESAVIAQAA/FcAAhAB/gEQAQAAtAe0Aq4LNgg0CPQPNAAAWAAACAH/AAAG/wEFDnUERQT1B0UEdwcAAAJYAAA4CAoK7AqoCq4PqAqoCuwKCgo4CAAABVgABH4FVgV2BVYFXgcABUoFMgU6BUYEQAAGWBACEAH+AYAAMAD8D6oEqAT+B6gEqAQAABVYAAj+CgoKdgoACnwPPgo8CrwK/AoECAAAIVgQABAEfgUABV4FOgcaBXoFOgVeBVAEAAAkWBAEEAT+AxAKgAi+BqoEqg+qCqoKvgqACCpYAAAQBP4DEAMED/4JVAtUC1QJ/g0ECQAAL1gAAJgJnAl8BVwDDgFcAVwHfAlcCVgFAAAwWAACEAH+ARAA/A8EBPwGfAd8BfwFfARAADFYAABUAXQB3gd0AQAA/g9iCLIEMgPuDAAENFgAAggC/gEIAEAJ/gVqA2oFagNqCX4HAAA1WAACEAH+ARAB1ABUAN4HdAVQBVgF1gcQADpYAAEIAf4AgAm+BKoE6gM+ACoA6g++AQABQVgACEAJfgtqCyoKPg8qCqoKagt+C0AJAABKWAAEEAL+AxABAAF8CFYH1QD8B1QIVAt8C0xYCAEIAf8BCAFAAN8BVQXVB5UBVQnfDwAAUVgAAGgIzAp4CkwKKA+ACnwKVApUCvwIAABUWAACEAL+ARABRAAkByYFVAVUBSYFJAdEAFdY2ggCCooKqAosCqwOqgr6CiwKrAqoCAgAWFgAAggB/wEIAQAG/AEcBl0F+gVcBXwHFABaWAACEAL+AZAFBgWqAnoKigk6BsoAJgcAAF5YAACECrQKtAn0CrQKtg70CrQJtAqECgAAaVgAARAB/gEQBTgE9gfUB9QE1Af0BIQHAARrWAAEEAL+AxABAAj8C7wKvgK8CvwLBAoAAHVYAAAADP4H6gT+BWoFawd+BeoF6gX6BAAAflhECHwJfAv+C3wKAA+ICmgKHgr4CAAJwAiDWAACCAL/AYgICAj6BV4DWwFeD/oJCAQAAIVYAAh+C2oL/gtqC34PEAqSCvoKFgpyCAAAilgAAKwIrAruC7wKiA/oCjwKSAr4CAAJwAiTWAABRAX8BH4FfAV8BXwHfAV+BPwERAUAAZdYAAIQAv4BAAF8ANcP1Ar8CtQK1wr8DwAAmVgAABAD/gGQAAQA7AfkB/4G5AZsBeQHAACcWAAAfgSKBnYGAAZWBzwFtAX0BRYFZASAAJ5YAAAQA/8BgAA8AOYPdAV8BWQF5w88AAAAqFgABCAEfgU6BXoFPgd6BT4FOgV+BSAEAACpWBAE/gMQA3AC2grcD/gDAAr+BIgDeAwAAK5YAAD+CAIKfgoACvYPOwp+Cn4K3gp+CAgIs1gAAhAC/gEQAQQI1AfcB94D1APUB9QLEAjBWEAAfgRqBWoFagVuBzQFPAV2BTQFPAUABMdYAAAQAf4BAAF8BMwH/Af+B/wHzAd8BAQEylgAABAC/gEAA/QK1A70Cd4F9ALUBvQIAAjTWAAM/gPKAf4G/ga+B8IHEgf6BvIGtAQAAdVYAAAQAv4BEABEBbwGvAO+C7wHvAHkBgAE2FgABHAFfgV+BX4FfgcuBX4FfgV+BXAEAADeWAAAEAL+AQAAXAKsDjwJbgk8AuwG/AgAAOJYAAAQBPwDAAj8BwQA9A5kCAQO9AqkCgAA5FgAABAC/gEABXwE7A3+C8YB/AfsBfwJBAHrWCAAIAQgBCAEIAT+ByAEIAQgBCAEIAAAAO5YAAIYAgAB/g8AACAIIAj+DyAIIAggCAAA71iACJ4HkAD+DwAAIAggCCAI/g8gCCAIIAjwWAAABAzUA1QBVAHeAVQBVAFUAdQDBAAAAPJYAAjECFQIVAZUAV4AVABUB1QIVAjEBAAA81gACMQIVAhUBNQD3gDUANQHVAhUCMQIAAT2WAAAxAhUClQIVA9UCF4IVA9UCFQKxAgAAPlYAAA0BLwFfAV8BX4FfAV8B/wF3AUUBAAA+lgAAGQINAu0CvQOPgj0DrQKtAo0C2QIAAD9WJQA3Ab8BvwG/Ab+APwE/AL8CtwP1AKAAARZgAhgCN4ECAPoAhgEAAj+CyAIQAiACAAAB1lAAFAASA+sCrYKpA+0CqwKzArED0AAQAAJWQQKRAo0CYQFpAaeBMQG/AaECZQIJAgAAA1ZAAAICAgKdgneB1wFXAVcBVwLfAkECAAID1kACAQKfAl8BfwHfAV8BXwHfAl8CQQIAAgVWQAAQAAgCBAISAROBIoCCAGIAGgAGAAAABZZQABgCFAEjgKIAWgAEAAgAP4PgAAAAQACGlkAAFAISAlECTQFpgSUBkwCRAHAAEAAAAAcWYQARAD0DwQARAhmBLQDFAOUBHQEFAgAAB9ZIADwAywJ6AkICPgHAACoCJYEVAJMAcAAIFkICagEdgVUAswBEADMAyoB6AkICPgHAAAiWcQAfApsCm4L/AtsBWwFdgNsAXwAxAAAACVZAAj8BNQC/A/UAvwAEAhICdYGtASMA4AAJ1kQCBAEEAIQAdAAPgBQAJABEAIQBBAIAAApWUAIRAhEBEQCRAP8AEQBRAJEBEQIQAgAACpZEAgQBBAEEAPQAj4EUAiQARACEAQQCAAAK1lACEgESARIAkgB/gBIAUgCSARIBEAIAAAtWQAAQAhECEQERAREA/wARANEBEIEQghACC5ZAACACPgIiASIA/4AiAGIBogE+AiACAAAL1mAAEgIyAioBJgDzgCICIgImAgoB0gAiAAxWWAIcAROBEgCyAF+AMgBSAJIBEgEQAgAADRZQARICFIEVAREAsABfgBAAkACQARACAAAN1kAAAQI7ASsBKwC/gGsA6wErAq8CoQJAAA4WQAAKACoAKgCuAOsAqgKqAq4CqgGqAAoADlZAACACIgIqAiIBIgD/gCIA4gEqASICIAIOlkAAKgAqACoAJgGjACKCJgImA+oAKgAqAA+WQgJiAhoBAgECAP8AAgDiARoCIgICAkAAERZSAAoAOgHuAKsAuoHqAqoCrgK6AtICAAAR1kAADQAtAe0ArQCrAKuAywINAj0BzQAIABIWSgEqAyoApgIrAiqB6gAmAKoAqgMKAAAAElZAACgAKwCbAIsArwCrg+sAiwCbAKsAqAAS1lAAEQA5A9UBUwFxgdMBVQFZAXkD0QAQABOWRQEVARMBVwFVgV1B1QFXAVMBVQFFAQAAE9ZkABUCFwFfAVcA94BXANcBXwFXAlcCJAAUVkAAFQJVAl+CVQFQANCAyIFHglCCT4JAABUWSABJAkUBawDJAEmAXUBJAGMDxQBJAEgAVVZJAlUCUQJJAUcBQYDBgF8BQQFFAUkCQAIVlkgCSQJEAl+CQAFSANEAyYFJAkcCQQJAABXWSAAJAEUBfwHdAV2BXQFdAV8BRQNJAkgAFpZAAmECawFZAW0A6oBYgNSA0IFSgUACQAAYFkAAAQF/AXuBe4F3APcA+4F7gX8BQQFAABiWSgBKgGqAK4P6gq7CqoKugqmCqYPKgAqAGVZAAAACXwJDAVkBXYDJANMBQQFfAkACQAAZ1kACXwJBAVsBWwFLAN+ASwDLAOEBfwFAAloWQAALgkgCX4FAAUkA5IBFgORBf0FFQkQCWpZAABUATQB/AP0B/YB9AX0BfQD/AGUARQBblkAABoAmg/+Cv4K+w/6CvoK/gr6D0oAAABzWQAAEAgQCdAIMAkeBRICEAKQBXAEEAgQCHRZiAj4BA4DyAE4CAAMNATEA8QCPAQACAAAdlkICPgMDgOIA3AIBAf8AAQEPAgkCOAHAAB4WQAA+AgOBYgDeAwAAEQARAD8D0QARABAAHlZAAj4DA4DiAF4BgAA/AcQCP4JCAj4CAAGfVkACOgMHgOIA3gEAABECEQI9A9MAEQAQACCWQAACAj4CA4F6AMQAPwPBAQEBAQE/A8AAINZAAj4CA4FiAN4BAAAxAdECEQIRAj8CAAGhFmACIQIvAqkC6QKpgSkBKQHpAikCIQIAACGWQAAGAOAAP4PAACQCHAJHgYQA/AEEAgQCIdZCAj4BA4DiAF4AAAERAREBEQERAT8DwAAiFkACPgMDgPoAhgEcAFEAUQJZAlcDMADAACSWQAI+AwOA+gDGAzwA0gASgBKAEgA+AAAAJNZCAj4BI4CyAE4AgAIaASoBT4CqAVoBAgIllkABPwEBwPEAjwAAAwiAqIBfgChASECIASZWQAA6AieBsgBOAIACDwEgAT+AgACjAEwAJ5ZEAjwBA4DiAN4AAgI4A9cCEQI/A9ACAAApVkAAEQIVAbEB2QGbAJEAmIF8gRKBEAIAACoWQgA+AkOBYgDcAQAAAgP+ABOCEgIyAcIAK5ZAAj4DA8D+AgADP4DEgDSB5IIkgheCAAGs1kAANAIPgUQA/gEAADUAwoI+A8IANgBCAK5WQAI+AgOBYgDeAAADEgCSAH+D0gBSAJIBLtZFAlcCVwLXAvcBX4FXAVcB1wFfAkUCQAAxlkACPgJDAb4BQAA/AdEBFQFVAxEDPwHQATJWQAA6AgfB8gBOAbAASQAJAD+DyQA5AMAAMpZCAj4CA4H6AEQBngARA/EAP4PRADEBwAAy1kAAOgNHgOIAXgCAACwD64EoASsBDAHQADQWQAA+AkOBugDEAj8DyQJJAkkCfwPAAgAANFZAAD4DA4DiAN4BAAAkA+QBP4EkASQDwAA01kAAOgIHgXIAzgAIAicCJAI/g+QCJAIAAjUWagIrAisC5wKzAb8BIwCmgWqBKoIqAgAANpZAAj4BA4D8AgMCYAE/gMAAP4HQAicCIQG3FmgCKwIrQquC6wGvASsBq4FrQSsCKQIAADlWRAI8AQeA5ADeAQAAagHfgkoCTgJKAUkAOhZAAj4DI4DcAQEAOwMrAL+AawCrAS8CQAI61kAAPQMjwLkARgA/g+SBJIEngeSBPIEAATsWQAI+AQPA+gBEAD+BwIE8gSeB5IE8gQCBPtZAAD4DA8D6AEQAv4PAgXiBLoFAgT+DwAA/1kAAKIIlArUC8AGpgSUBIwGlAWkCKwIAAABWgAO+AEIBNgFeALYAwgI/gQIA8oEKggABgNaAAj4CA4H+AQAACQJJAm+DyQJJAkgCQAABFrICMgIrgqYC9gG/gSYBpwFqgTqCMgIAAAHWgAI+AQOA8gBOAZQADQPHAAUADIPUgCAABhaAAj4BA4D+AYAAPwPVARWBNQBVAO8BIAEG1oAAPANHgP4AAQIcAlcB+QBZAN8BcAJAAkcWgAA+AyOA3gIAgb+AZII/gf8DwIA/gMAAB9aCAj4CA4F6AMYAMAPvAK0ArQKtAr8DwAAJVoACPgMDgP4AgAKlAj8DxIE/gKQBVYIAAYpWgAI+AgOBcgDOAj4CJQElgP0D5wI8AgABDFaCAj4CAwFiANwCAwJVAfUAVQDVAVcCQAJNFoAAPgMDgP4APIPBACgAfoHogACCP4HAAA2WoAIwgj+CtoL/gaiBsgGtAWUBKwIpAgAAEZaSAhqCQoLYAscBUwFXAUuBSwHXAlECQAASVoAAPgMDgP4AAAITAw0A0YA9AcUCPQJAARaWgAA6ASeAsgBMAC+B2oFagVOBZoHKQAoAGZaAADoCJwGyAEwBoQDvAD8D7wAvASgAwAAdFpAAF4JQgkyC44F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TAVEBQwJAAC/W4AATADkBxQABADWB1QFdAVUBVQF1AcAAMJbAABMA0QI9A9UAEYLFAh0BJQD1AQ0CAAIxFsAAIwAxAfUBbQFtgW0B9QA1AjED4wAAADFWwAIDAjkC7QGtAb2A7QCtAa0BuQLDAgAAMZbAAAMAaQHhATkBE4HpASUBEQEFA9kAAAAx1tACFQE1ANUANQHVggECHQLVAvUCFQIAATMWwAADACEB/wF3AXeB9wF3AX8BYQHDAAAANJbAACMBLwCvAH8BL4IvAr8CLwJvAKMBAAA01sAAIQP9AD0AvQC9gP0AvQC9Ab0BIQHAADbWwAIDAjEC9QL9AfWA9QD9AfUC8QLDAgAAN1bAAAsAQQB/APECX4IfAt8BXwFfAvMCQAI3lsAAAwK5Ar0CvQG9gP0AvQG9ArkCgwKAADfWwAATAlkBbQB9AmGD5QBpAPUAzQFnAgAAOFbAACMAIQF/AX8A/wD/gH8BfwH/AGMAoAA4lsACWwHRAH0DwQA9gn0C/QF9Af0CKwJAADlWwABXAlcCbwKnAt+B0QGvAR8BXwBDAEAAOZbAAAUCNQH/Af8A/4D/AP8B/wH3AcUCAAA51sAAAwBxANUA9QLagvsD2QDRAPUAwwDAADoW4AEtAK0CrQL9AK2DrQC9Aq0C7QKhAIAAOlbAAFMAWQP9AtUC3YPVAtUC/QLVA9EAQAB61sAAAQB9AT0AvQA5gLEAfQA9AX0BIQDAADsWwAIDAjEC9QH1AfWA8QD1AfUC8QPDAgAAO5bAACMCEQI1AP0CtYO1AL0AtQLRAiMCAAA9VsAAFQI9AfUAfQK1AcGAPQHdAt0C3QOAAT2WwAEFgjWB94H1gPHA+4D7gP+B+4HLggAAPhbAAAIACgAaACIAQgICAgICP8HCAAIAAgA+VsACCQMRAKEAXwCAALQABAJEAj/BxAAAAD6W6AAqACoAKgGqAS8AKgIqAjoB6gAqACgAPtbAAAAAUQBVANUA1QBVAlUCVQHfAEAAQAB/FsAAAABPAFUA1QFVAFUCVQJVAdcAUABAAH+WwAIKAxIAo4BaAYIBFAA0AEQCP4PEAAAAP9bQAREBVQDVAH0BV4BVAlUCdQHVAFEAQAAAVwAAKQEpAS/B6QEpAQAANAJEAj+BxAAAAACXAAAAgF+AVYFVgF/CVYJVgnWB34BAgEAAARcgAT+BKoC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/g8QAP4GkAVWDAAA6lwAAPgDAAL+AwAC+AfAAKYPkgiwCMYPiADtXPgDAAL+AwAC+AMAAO4PoAK+AqAK7AcAAPBcAAD4B/8HAAT8BwAAJAVXBdoPVgVSBRAE9lwAAAAO/ARcBVwHXgVcBVwFXAFcCUAHAAD7XAAA+AP+A/gDAAAoBYwFygKIAi4FaAQAAANdAADwA/4D8AMAAFQDxAD+B8QAVAFEAgAAB10ACXwFGAFYCVgJXA9YAVgBWAUYBXwJAAAOXfgHAAL+AwAC+AMAALQDrAKuCzQI9AcgABRdQAAsAOgPWAVYBV4F+AdYBVgFWAVcBQAEFl0ADP4DDAisCqwKrgrsDqwKrAqsCq4KCAgXXQAAAAD2DxQAVAZ2BtYHdAZ0BhQI9gcAACldAAAMDOwDqAnoDw4ACAjoB6gCqArsBwAALV0IAWsBWgHKB0oBSwECDPoDSgDGD0cAAABKXQAA8AP8A/ADDADsBgwB/A8MAWwCqgQABEtd/AMAAv4DAALwBf4Dyg+qCq4KqgruDwAATF0gAOwPKAUoBegPDgDIDCgCqAEoBqwIYABQXQAA5g8cANwJXAn+D1wNXA2MCPwHBggABmldEACWD/QA9AD0B/QF9gX0BfQH9AiWDxAAi10AAAAA8Af+A/AJ/ARcDV4DXAtcCUAHAAC6XSAAkwCqAqoEsgcHAP4FrgWuAa4F/wUACM1dIAl8C3gFeAV4Cw4A+ATYA/gD3AbQBvAC3V0ACAAM/AMAAAAAAAD4BwAAAAAAAPwPAADeXQAAcAgABv4BIAAAAP4HAABwAAAA/g8AAOFdAAhECMgHAAT4CAQLcAiMCSAK2AgECwAI4l0AAAAF+wWoA6oD/Q+oAaoDrgX9BQAFAADjXQAAAAn+BagFqgP8D6gBqAOsBfoFAAkAAOVdAAQEBAQEBAQEBPwHBAQEBAQEBAQABAAA5l0AAAgMCAPICHwISghICMgPSAhICEgICAjnXQQCBAL8AwQBAAEEAHwERAhECEQMxAMAAOhdAAAAAP4PkgSSBJIEkgSSBJIE8gUCBAAA6V0EAgQC/AEECQAE/AMEAHQABAD8DwAIAAbrXQAFhAR0BIQEBAT8BwQFhAR0BIQEBAUAAO5dgAioBKoDrgioCfgJqA+uCaoJqAmACAAA8V0AAAAA5AckCCQIJAgkCCQIJAh8CAAHAAHyXQAABAD0B0QIRAhECEQIRAhECPwIAAYAAvRdAAAAAPwHRAhECHwIRAhECEQI/AgABgAA910AACABKAHoB74KqAqoCr4K6AuoCCAFAAH7XQAAIAGqAOwGuAquCrgKKAtuCKgEIAEAAP5dAAD4AwgACAAIAAgA/g8IAAgCCAL4AwAAAV4AAAQA5AMkACQA/A8kACQCJALiAwIAAAACXgAACADoAygAKAD+DygAKAIoAugDCAAAAANeAACIAYgA6AdcAEoA6A9IAEgESATIBwgABV4AAPwIAAb+AQAA+AMIAAgA/g8IAAgC+AEGXgAA+AEIAP4PCADwDf4DIgACAP4PAAgABwheAAD4CAAG/gEAAPQDFAAUAPwPFAAUAvQBDF4AACgBKgGqB+wAtACkD6wAqgSqByAAAAAQXgAA/AD/DwQA/AEACP8HIARoAKYDIQQgBBVeAAD4AwgA/g8IAPgD8A+IBI4EiAT4DwAAFl4AAPgDCAD+DwgA+AOAD0AEfgRIBMgPCAAYXgAADADEB1QATABOAOYPRABUBMQHDAAAABpeYACuB64BrgGuAa4PrgGuBa4FLgNgAAAAHF74AwgA/g8IAPgDAAh8BkQBRABEA3wMAAAdXgAA5ACkB7wApADmD6QAtASsBKQHZAAAACVeAAD4D6wEqgS4BwAA+AMIAP4PCAD4AwAAJl4AAGQApAeuAKQA7g/uD6QApAQuB2QABAArXgAA+A+uBKkEuAcCAPIDEgD+DxIA8gMAAC1eAAb8AQQAFAd0AVQB1gdUAXQFFAUUBxQALl4AANQA1AZ+AVQBVA8AAX4BAgVeA2IAAAAvXgAA5AAkBz4BNAH+DzQBNAU+BSQG5AAAADBeAAD4CAAG/AFAALwHvAD8D7wAPAdgAAAAM14AAPgA/g8IAPgBAAj+B1YE1gBWA1YFQAk2XgAA9AC0B64AvgD0D7QAvgSkBK4HVAAUADheAAAYAAoHfAFYAVgB3gdYAXoFCgcYAAAAPV4AAPgBCAD+DwgA8AGeD8IKygrCCt4PAABFXvgBCAD+DwgA+AEAD7wKrA+sCqwKvA8EAExeAAD8AQQA/w8EAfgF7wKVAfUAlQevBAACVF4AAPwA/w/8ARAErwS/Ba8CvwKvBb8EAARVXgACRAH8B34BfAH8B3wBfgX8BXwDRAEAAWFeAAD4AQgA/g/4AEAAPA+UCrwPsgpaD0AAYl74AQgA/g8IAPgBAAT0BvQG9gf8BvQGEARjXgAAegA4B34BOAG6DxABTgU0BVwGxAAAAGteKAA8DvwD/gP8A+gPwAPUA+QL3gsEDgAAcl5AAEQARABEAEQA/A9EAEQARABEAEAAAABzXoAAhAC0AIQAhAD8D4QAhAC0AIQAgAAAAHReAAAwAQgB5gElASQB/A8kASQBJAEkAQAAdl6ACIgIiQb6AYgAiACIAIgA/g+JAIgAgAB4XpAAlAK0AtQClAKeD5QC1AK0ApQCkAAAAHleAAD8AqwCrg+sAvwCEACsAOIPpACIADAAe14AADAGrAViBDAFEA4EAAQIBAgEDPwDAAB8XggEMAbOA0ECOAsABAgD/wAICAgI+AcAAH1eAAD8ByAFvAXwBe4G/gcQBOwFAAT8DwAAfl4AAK4IuQSkA4AKngjgBY4G+Aa0CKAMAAB/XgAAAAz4AwgACAAIAA4ACAAIAAgACAAIAIFeAAz8AwQAJAAkACQIJgjkByQAJAAkACQAg14AAAAO+AEIBAgGyAUsBAgEiAQIBQgGCAiEXgAAAAz8AwQIRAhFCPYPRAhECEQIBAgAAIZeAAz8AwQIRAhEBEUD5gBUAUQGRARECAAAh14ADPwDBAD0D0QIRQQGAPQHhAhECCQIJAaKXgAG/AEEBCQCJAGlAPYPZACkASQCJAYAAI9eAAz8AwQAlACUCNYI1Ae0ALQClAGEAAAAkF4ADPwDBAgEBPQDNAE2ASwBLAHkAQQAAACTXgAM/AMEAJQC9AKeAp4C1A+UApQClAIAAJReAA78AQQEdASEBRUE5gQEBoQFdAQEBAAAlV4ADPwDBAAECPQPlASWAPQMlAGUBpQIBAaXXgAM/AMEAAQPBAkECfYJJAkkCSQPJAAAAJleAAAADPwDBADkDyQJJgn0DyQJJAnkDwAAml4ABvwBBASsBKwErgL+AawBrAKsBPwEJAScXgAM/AOEAEQA9A8EAKYAJAkkCPQPJAAAAJ5eAAz8AwQIJAYkAfQEJgTsBywJpAikCAQGn14ADvwBBAQ0AiQJ5gW2BqQGpAW0BCQIAACmXgAG/AEEBJQElAT0BdYC1AL0BZQEFAQAAKdeAAz8AwQIRAk0CUQJ9g9ECTQJJAlECAAAq14ADPgDCADoA+gD6APsB+gD6APoAygCAACtXgAM/AMECFQHdAbUBQYIVAr0C1QKVAoAALVeAAz8AwQAVAD0B9YC1AfUCtQK9AtUCFQEtl4ADvwBBAQkByQA9A6mAKQO9AAkAiQMAAC3XgAG/gECBKoCqguqCPsHqgKqBvoFIgkAALheAA78AQQA9A/0A/QD9g/0A/QL9AukDwQAwV4ADPwDBAj8B6wGrAL+CwQA9AsECPQHAADDXgAM/AMECEwF/ANOAUQB3AdsCWQJFAUAAMleAAz8AwQIdAV0A/QPdgH0D3QD9AVUCAAAyl4ADPwDBAj0D7QItAb2DAQA/A8MAPwHAADTXgAM/AMEAPQLvAu8D/YDBAD8DwwE/AMAANZeAAT+A4IAlgiOBmYHvwZiBW4FRgKeAIIA314AB/wABAL0A7QDtAe2A/YHBAb8AawE/APgXgAM/AMMAOQPvAKmC+4PRAj0BSQD5AwAAOJeAAz8A0QALAusCn4ERANsBfQHtAkUAAAA414ABv4BAgjqBfoF+wX7AfoB+gPqA+oFIgTzXgAAgA98AAQLfA/+DyQEdA10CXQDdAUAAPZeBAi0BKwDZAQABfQJBAkECfwJJAkiCSAJ916ECDQHrAVECAAKJAokCvwLJAoiCiAKAAD6XgIIcgwuA+IECAWqCaoJ/wuqCaoJvgkICf9eAAAQABAA/g8QBBAEEAQQBP4PEAAQAAAAAF9ACEQIRAb8AUQARABEAEQA/A9EAEQAQAABX5AIkAiQBMwDiwCIAIgAigDqD4wAiACQAAJfAAAACR4FqgMqASoBKgEqAaoPLgEgAQABA18ECSQJJAW0AywBJgEkASwBvA8kAUQBBAEEX0AJVAlUBVQDVAF8AVQBVAFUD1QBVAFAAQpfAAl6CTgFPgN4AXoBEAEsAbYPNAFMAQQBD18ICEgESATIB0gESAQIAn4AiAMKBAoICAYTXwAAAADyAJIAkgCSAJIIkgiSCJ4HgAAAABVfAADEAKQIpAikCLwHAAAAAAAA/A8AAAAAF18AAIgI6AioBvwBqACoAPwPqACoBLgDAAAYXwAB5AikCKQIvAcAAAAH+AQEBIAEAAcACBtf8giSCB4HQAD8ByAIEAj/CRAICAn4CAAGH18AAAAEyASqAqwCqAH4D6gArASqBLgDAAAgXwAA8giSCJ4HAABACP4PQATQBEgBRgZACCVfBAHkCKQIvAigBxADzAgICPgPCADIAAgD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iAAACqIJcgQqA+YIIg7gAQAAbWKIAIgI/weIAEAIAghCDv4JQghCDv4JAAhuYggBiAj+D4gAIAhQBE4DwABCCE4I8AdgAG9imACYCP4PWAAACPgPAAgACP8PIAggCCAIcGKIAIgI/g+IAEAIEATQAz4AkAcWCBAIEAZxYogAiAj+D0gAAAf8AMQEBAU8A5AEcAgAAHNiiACIDP4DiAgADvwBZASkBSQCpAVkCAAIdmKAAIgI/g9IAAAISARIA/4ASANIBEgIAAB5YogAiAj+D4gAAAD+DyAEAAD+ByAIGAgQBnxiAAGIDPwDiAgADPwDBAD0BxQIFAn0CAAEfmKIAIgI/g9IAAAIEAQ+AtADEgXUCBQIEAZ/YgAAEAQQA/QABAqkCvQHrAIMAuQAIAMQBIBiiACICP4PSAAACGgEqAU+AigF6AQoCAAAhGKIAIgI/g9IAAAIeAgABP4EAAKMAVAAAACKYoAAiAj+B0gAAAD8B0QIRAh8CEQIRAj8CJFigACICP4HAAD8BwICAgD8DwQABAT8AwAAkmKIAIgI/w9IAAAAIggqCOoPNgCmAGIAAACTYoAAiAj+D0gAAA78AQQA/A8CAP4AAg8ACJViiACICP4HSAAACN4EQgVCAt4FUAgICAAAlmKIAIgI/g9IAEgAAAEiAUwBAAH+D4AAgACXYgAAiACICP4HSAAADOgDLgAoAOgHCAgABphiiACICP4HSAAADv4BIgAiACIA4g8iACIAmmKAAIgI/g9IAEAIBASkA3wA5AckCCQIIASbYgAAiAj+B0gAAA//APgHAAn4CA4K+AkABJxiiACICP4PSAAADIgDfgioBSgC6AUoCAgInmIICYgI/g+IAAAM/ANEAEQAxAFEAnwMAAigYogAiAj+D0gAAAD8DwQIFAvkCLQJBAoACKFigACICP4PSAAAANgHhAiCCEQICAgwBiAAomKIAIgI/g9IAEAAEADIBycIJQnICBAGEACkYogAiAj+B0gAAAz4A0gASgBKAEgA+AAAAKViiAiICP4PSAAAAP4PIgDyDDIDMgXuBAAIq2IIAYgM/gOICAAO+AHIBX4GSAXIBFgIAACsYoAAiAj+D0gAAACwD6wEogSgBKQEmA8gALFikACQCPwHUAAAALAHrgioCOgJCAn4CAAGtWKIAIgI/g9IAAAA/A8kBCIAPgziByIIIAa5YogAiAj+D4gAQAQIAkgB/g/IAEgDSAQAALxigACICP4HiAAAAPwBpACkAPwPpACkAPwBvWKIAIgI/gcIAOAPkASQBP4HkASQBPAPAADCYgAAkAj8B0AA6AyoAv4BqAD+D6gAuAcAAMRiiACICP4PiAAIAIAIiAiKCPoPiAiICAgIxWKIAIgI/g9IAAAI/AkkCSQJJAkkCfwJAAjGYogAiAj+B4gAAAz8AyIAogDiDyIBIgIAAMdigACICP4HSAAAAP4DIgKqCiIKIgb+AyACyWKAAIgI/g9IAAAEKATIBQoECAfoBAgEAADLYgAAiAj+B0gAAA/+AMgHAAn+CggK+AkABMxiCAGICP4HiAACACwBIAH+DyABLAEiAQAAzWIIAYgI/geIAAAA+A+IBI4EigSIBPgPAADQYogAiAj8B0gAAAi8BKQCpAGkCKQIvAcAANJiiABICP8PSAAAAP4PkgSSBJIEkgTyBAIE02KIAIgI/g9IAAgBgADkD1wERAREBMQPAADUYogAiAj+D0gAAAyIA34IqAUqAqoFaggICNZigACICP4HiAAgAJAAzgdICOgLSAjoCwgI12IAAIgI/g8AADgD5gIwCxAF8AMeCPAHAADYYoAAiAj+D0AAEADIAy4BKAHoCQgI+AcAANligACICP4HSAAAALwHIAT+ByAEIAS8DwAA2mIAARgJ/geYAAAImATUA5IAkADUD5gAoADbYoAAiAj/B0gAAACiD5oEhgSiBKIEngcAANxiAACUDJQC/AGSAAMAKAEqAf4PKgEqAQAB3WKIAIgI/gdIAEABFAFUAfwPVAFUAQQBAADfYoAAiAj+D0gAAAT+AwABvAwAAsABPgEADuBigABICP4HYAD+DIgDcAT8CQQI/AsACoAJ4WKIAIgI/g9IAAAO+AEIBIgHbgQIBQgFCA7iYoAAiAj/D4gAAA6QAX4MEATyB5QIVAgQBONigACQCPwHkAAABOgCuAqsCOgPiACIAggE5WKAAIgI/gdIAAAM/gOSAJIA/g+SAJII/gfmYoAAiAj+B4gAAASSBJYEkASYBJYEEAQAAOdiCAGICP4PiACAABgASAhICMoPSABYAAAA6GKAAIgI/geIAAACHAnQBH4FUALUBVQIEAjpYogAiAj+D0gAAAKkApwC1A+cAqQCJAIAAOxigABICP4PSAAAAJIPkgj+CJIIkgiRDxAA7WKAAIgI/g9IAAAEUATQBxAE/AEQBhQMAADvYoAAiAj/D0gAAAnSCCIK+gsmCNIIEgkAAPFigACICP4PSAAACIgE/gKIAIgA/gKIBIAI82KgAKgCagJsC3gL7gcoAygDbgKoAqAAAAD0YgABiAj+B4gAIAgYCSQJ4g8kCQgJMAgAAPdiAAEQCfwHkAAAACgBqAP8CqgKuAqoBiQA/GIAAQgJ/gfIAAAIiQT6A4gAiAD8D4sAgAD+YogAiAj+B0gAAACYD4QEogSiBKQEiAcwAP9iCAHIAfgB/AX6BfoD+gH8AfgB+AGIAQgBAWOQAJAI/AdQAAAAqAKoArwIqAjoB6gAIAACY4AAiAj+D0gAAAgkCSQJvg8kCSQJIAkAAAdjiABICP4PSAAAAN4HZAVkBWQFYgXiBxgACWMIAQgN/gMICEAIXAjEBXcGRAPEBFwIAAAOYwABEAn8B9AAAACoArgDrAqoCrgKqAagABFjgACICP4PSAAACYgE/gMAAP4HQAicCIQGFmOAAEgI/g9AAAQAVARUC0YJ1AhUCAQGAAAZY4gCSgIsArgKqgrsB6gCiAI+AkoCSAIAABpjAAAUAtQD/gOUC4AHtAOeA4QDPANAAyACH2MAAQgJ/gfIAAAIqAiIBv4BiAOoBIgIAAAgYwAAiAj+B0gAAAikBKYDvAC0D8wIrAiABCFjiAGICP4HSAAABC4FIAU+BSAFKAXmDwAAI2OAAIgI/g9IABAAWAlWCfQHXAFUAfABQAAkYwAAiAj+B0gAAAhEBEwDNgAkAFwPRABEACVjAACICP8HAACWAtICsgKaAtIPkgKWAgACKGOAAIgI/gdIAEAJLAUrA+gDKgMuBSgJAAgqYwAAiAz/AwAIkgb+AZII/gf8DwIA/gMAACtjgACICP4HSAAgCBwJYAn+DyAJHAkgCUAAL2OAAIgM/wOICAAO/gHCD1IE0gVSAVIOAAg6YwAAiAj/D0gAAgw+A+IEAAgiCf4JIgkiCT1jgACICP4HQAAQCPgIlASWAvQBnAeUCPAIQmNIAEgI/g8oACAAqge+BKoEqgS6BKIHIgBFY4AAiAj8B0gA4A+kArQC9A+sAqwK5AcAAEZjgACICP8HAAD+DwIEUgT6BVIEAgT+DwAASWOAAIgI/g9IAAAMvAMkBOQPpAikCLwIAAhMYwAAiAz+AwAIvAakAbwIAAf4AQAI/gcAAE1jiACICP4PSAAAAX4BagFqAeoPagF+AQABTmMIAQgJ/geIAAAA4g+sAqACvAKgCuwPAABPY4gASAj+D0gAAAS+BKoEqgeqBKoEvgQABFBjiACICP4HSAAAAO4PqgKqAqoKqgruDwAAVWMIAYgI/geIAAAA6A+oAqgC/g+oAqwK7AdcY4gASAz+AwAIvASsBawG/gSsBqwFvAgABF5jgACICP4PSAAACJQElgLUAZQIlgw0AwAAX2OAAIgI/gdIAAAI4AkuBCoCqgEqBC4I4AthY4AAiAj+D4gAIASYBSQEogUkBAgH0AQAAGJjiAz+A0AIEAj4BJQClgH0AZwClAT0BIAIY2MAAQgJ/geIAAAG/ASEBpYEhAa8CIAHAABnY4AASAj/B0gAAABqAr4Cqw+qAuoCqgIAAGhjiACICP4HSAAQAEwHUgV6BVIFRAVIB1AAbmNAAEgI/g9IAAAH/gAyB7IE8gSyBL4HAAByYwABEAn8D5AABALUB3AJXA1QDVQO1AhAA3ZjAACICP4HCABACfQJVAn8D1QJ8glQAQAAd2OAAIgM/wNICAIIqgaqBKoE/w+qCvoKIgh6YwABEAn8BxAAQAQoARgJTA9YASgBSA1AAHtjgACICP4PSABABwgAJAcqCCIJZAgoAwgEgGMAAIgI/gcAAPwPFAD0DwAAFA7qAQgGOAiCY8AARAb/AQAM/gMCAIIPggT7BJIEkg8CAINjgABECP8HBABgALUHtQD1D7UAvwTgAwAAiGOAAIgI/gfIAGAIaAikBKoHogS6BmoFAAiJY4gI/gdIAAAC+AKoAqgCrg+sAqwC/AIEAoxjAAAcAs0C/wL8Cv4H/AL8Av8CjQKcAgAAj2MAAQgJ/gcYAIwCqgLoA6gCqAqICPgHAACQY4gAiAj+D0gAAADQD0gFBgVEBFwFxA8AAJJjiACICP4PSABAAAgBKAHWDvwHKAEoAQAAlmMAAIgI/geIAAAA5A8UAMYIdAWkA+QEJAiYY4AAiAj+BwAA/g8KAOoOigjqD4oI7g4AAJljAAEICf4HiAAAAqwKpArqB6ICqgLqA4AAm2OAAJAI/AcAACgFvgcoBQAA/A9AAMAAAACgY4AAiAj+D4gAAAT0ApQIlgeUAJQC9AIEBKFjgACICP4HSAAABJQChAHUD4IBsgKKBAAAomMAAQgJ/gfAAAwEpAKUAcQPlAGkAqwEAAClY4AAiAj+B0gAAAikCqwLpgSkBrQFpAigAKdjAAGICP4PSAAMCKQIlAiGD5QIpAgMCAAAqGNIAEgI/g9AADAA/A+qBKgE/geoBKgEAASpY4AAkAj8B1AAAADoA7gCrALqB6gKuAroC6pjiABICP4PSAAAANQHXgVUBVQFXgXUBwAAsGMAAJQI/AeyADgG5gH8AxAIkgj+B5IAgACyYwgBCAn+BwgAAAG+A+oFqgSqAqoIvgcAALdjAACICP4HSAACDvgBTgcAAP4PAgD+AwAAuGMAARgJ/geYAAAC8ANSA1QD8A9cA1ID8AO6YwAAiAj+B0gAQABYCrwKWgkYBTwEWAKQAMljgACICPwHSAAACXQFHANcD3wDFAU0CRAAzWOAAEgI/g8oAAAIXAl8BdwDXgF8BVwFXAjPY0AARAT/AyQAAAD0D5QElwT0B5QElwT0D9BjAAEICf4HiAAADL4CqgSqD6oKqgq+CoAI0mMAAEQE/wNEAAAA6g+qBAoE/gcJBOkPAADWY4gAiAj+B0gAAATsB2wFbAVsBWwF7A8gAtpjBAGEDP8HxAAABt8DVQlVBVUDVQlfBwAA22OAAIgI/geIAAgIeAk2BZQDPANQBXAJAAjhYwAAkA78AQAM/AM0CLQK9Aq0D7QKvAoACONjAACICP4HQAAcD7AAsA/+ALAPsAC8DwAA6WOAAIgI/g9IAAAA/gdoBUAFfgVoBeQHFADqY0AAiAj+B0AAEgH+D0IAGgwAA/4AAAM4DO1jAAEICf4HiAAAAP4G6gSqBaoIqgi+BwAA7mMgAEgI/gdIAAAC+gK6AroC+g+6AroC+gL0Y4AAiAj+D4gAAgRWAvIJ1gbSBNkHVQhACPpjiACICP4HSADAAIwOpASsBOwHogSyBKoO/WMAAIgM/wNACB4IwAteCEAHVgjUCwQIAAQAZIAAiAj+B0AAEAC4BHYENAV8CbQKsACAAAFkAABICP4HAADyD0IAWAeqAtoCAgv+BwAAAmRAAIgI/g9IAAAIqgqYC94EmAaqBaoIgAAFZAAAiAj+B0AAGgj8BTgEugc4CO4JCggABg1kiACICP4PSAAACOwF7APsAewB7AXsCQAID2SAAFAI/AeQAAAAeAN4A3gBfgl4CXwHeAETZIAAiAz+A0gIAAzVA1YIfAlUD1cJVAkAABRkgACICP4HSAAAAKYJWglSCdYPWg1WD9IPFmQAAAgJ/geIAAACVArECqYKng+MCoQKAAAcZIgI/gdIAAAIvAi0CaAG/gSgBrQJvAgACB5kgACECP8HJACAD1oAWgdbBVoHWgDCDwAAKmTAAEgI/gdIAAAH/AB0BnUF9gV0BXQHFAAsZAAAEA78AYAM+AN+CfgHAADeDUICngUgCC1kAACICP4HSABAAG4HVgVcBWQFTgdEAAQANmRAAEgI/A8gAJAPaAB4B3QFcgV0BWgHEAA6ZAABBA3/B4QADAj/BasDqgH/BasDqg6CAERkAACIDPwDKAiABLwGvAG8BbwGvAakCQAARmSAAIgI/gdAABwFVA1cC9QJXAVUBVwJAABHZIAAiAj+B0gAAAasBKQE6geiBKoEqg4AAEpkAABICP4POALIATgBMAD+D6gE/gesBAAEVGQAAIgI/geAAIgCBAK0Au4OxAIEArQCgABYZIAAiAj+BwgA4A8UAFwH9gVcBxQI9AcAAGdkAABICP4PSABMAOgHaAVuBegHaAVsBQAAaWQADPwDBAC0A7QLtguEB7QDtAN0A3QDVAJ4ZIAASAj+D0gAAAl0CXYH9AF0A3YFdAkECXlkAAFEA3wD/AN+C/wL/A9+AvwCfANEAwABg2QAAvwD/AP+C/wLvAfYA9YDUgN2A1QCgAKHZAAAiAf+APAPXgD8B3AA9Ac6BsUBPAYABJBkkACQCPwHkAAYCPwL2AbeBtgC/g+YAgACkWSAAJAI/AcAAJgD/AvYC9wH2AP8AxgDAACSZIgI/gdIABAA9A++ArQK/g8QCO4GiAN4DJVkAACQCPwHAAD8DVgB/AUAAPgPJADkDyQAnmRICP4HWAAACPQK9Ar0CvYP9Ar0CvQKEAikZEAARAz/BwAA8g+/AtoPEAg4BMcDfAwAAKVkAAAICfwHCACgC7wK5A5ACygF/AeoCQAAqWSAAIQE/wNEAAAE+gFWCVMPVgH6ATIMAACrZAABkAj8B1AAAA38ASoB6A0oAegNKAHoDaxkAACICP4HSAACA9YPHgM2AK4DrQcoCwAKrWSAAIgI/gdYANQAVAe8BbwHlAW6BdIHkACuZIAAhA7/AWAE4Ae/BrUG9Q91BHUD/wVgBLBkAACICP4HoABOCfYFVgVAAU4F9gVWBUAJsmRAAEgI/g9IAAIJeAVuA+gBbgN4BWoJAAi1ZAAAiAj+B4gAAARcBd4FQA9cBU4FXAUAALxkAABIB/4AAA78ASwB3AesA38CpAMVBAADv2QAAIgI/gcIAOgMtAL0BBIA8gy0AuQECAjBZEAASAj+BwAAtAxkAwQA+gdUBfwHVAUABMJkAACICP4HCACcB8wFnAW8B5wFzAWYBwAAxWQAAIgI/gdAAHwEzAf8B/4H/AfMB3wEAATHZAAASAj+ByAAvgL6Ar4Cug++AvoCvgIAAMpkQAT8BPwH/gf8DvgPkAfuBqIG5gaoBAgBy2SAAEgI/gdIAAAAmgf8BdgF3gfYBf4FigfNZAAAkAz8AxAIwAW8BfQDlA/0A7wF4AkAAM5kFAA8Ar4DuAPOC7wLhA+oA7YDlAMsA0QC0mQAAYgI/geIAAgOxAGSB9oF8gO0CcQPAADUZIAAiAj+D0gAGA74Aa4MvA/MD7wPyA8AANpkgABICP4PAAT4AxgA2AX+A3wPbAFsBgAE4GQAAIgI/gcIAGAM1APkAr4CvAK8AuwPBADmZAAACA3+AwgJLAmUAdQJvg+0AfQBHA0AAOxkAACICPwHAABeDdQDVAwAAywE9A88CWQI9GSAAIgO/gEADPwDRAj0C/QL9gP0C9QLAAD6ZAAAiAz+A8AIdgfKDO4HCgBuBqoKrgoAAP5kAAGICP4HCADCCH4K3gdeB14H/gvCCgAIAGVUAMwCXgJMA+AL5gvUB8IDSANeAswCVAAPZQAAmAz+AwAI6AdmAvQPAADeB9QL9AoAABJliAj+B0gADAjeC14IXAZMAV4EXgisCyAAFGUAAIgI/gcAAP4H9gR+A/AH7gP2CP4HAAAYZQAAiAj+B0gE+APsD/wJxgH8B+wF/AkAABxlQAAkBP8DIACLD34B+gJ7BvoBegT7ByAAHWUAAJAI/AdQAMQD/AL8DzwA/AP8A+QHIAIkZQAAAABICP4P/gv0B/4O9A+uBPoHqAQAAC9lCAgoBGgEqAQoAz4CKAOoBGgEKAQICAAANmUAAPwDAAEAAf4PAAAwBG4EiAPoAhgECAg5ZQAA5AEkAiQBfAVgDDAEzgIIAegCGAQICDtlBAEEAfwBBAlkCRAEbgKIA4gCeAQICAAAPmUACAgG+AEqCMgHIAAQDO4CiAN4BAgIAAA/ZQQE9AMEAvwDJAJkCDAE7gIIA+gEGAgACEVlCADID0gEfgTID2AIPATKAogDeAQICAAASGUICKgEigKMAygEQAAwDM4CiAN4BAgIAABMZQAAkg+SBP4EkgSCDyAAFAzqAogDeAQICE9lQAD4AVYB9AVUBfQDYAkeBOUCxAM8BAQIUWUIAmgJCAn+D8gACglgCH4EiQPoAhgMAABWZQAEVALUAf4E1ATUA0AAfgaIAWgCGAYABFdlAAj8BVQFVAH8BWAAOAzMAogDeAQICAAAWGVQAlgJVAjyB0QAZAswCO4ECAPoBBgIAAhZZQACVAJUCd4P9AFYCTYIfASLA8gCOAwICFtlAADQBRgE1AQWA4gIMARuAogBeAIIDAAAXWUAAPYP0AH+D9AB9g8ACD4EyQPoBBgIAABeZQAA7g/gAX4CoAnuD0AIfgSIA+gEGAgAAGJlAAAIAvoDqgKqAv4PAAAwDO4CiAN4BAgIY2UAAOoPrwKqAq8KygcgABoMdQLEAzwEBAhmZQgC+ArYCtwO2AN4CmAI/gQIA/gECAgAAGxlRAD0A1YB1AkWDPQDMAhuBogB6AIYDAAIcGWgCKoKmAf+BJgHigggCD4EyQOIAngECAhyZQAA9A/0A/YCdAn0BwAA4Aw+AygD6AwACHRlQABcCDwIvg68CNwP2Aq2CrQKTAhECAAAdWUAAPoPDgP7Ag4J+gcQAD8MxAN8BgQIAAB3ZQAEvwKrAf8FqwW/A5gIPwTCA3ICDgwCBHhlCAl8C3wL/gV8BXwLYAkwBO4DeAQICAAAg2UAAF0JfgX/B1QDXgFoAOYDVgVcBWQFQASHZQAACAgICBgEaASIAgoBiAJoBBgECAgICIllIgQSDNIDVgFaAUsBSgFWAVYB0gcSABIAi2VkAGQPZAFUAVwP1gFUAVwPZAFkCWQHYACMZQgIaASOA3wCAAjUD/QHEAD+AxAEFg4AAI5lJAgkD6QAHAJUCVYPVAEsBSQApA8kAAAAkGWkCKwIrASsBZ4GwAKAAr4GrAWsCKwIoAiRZQAAJAT8AwAIKAbKATgCAAhECPwPRAgACJdlAAIQAiQBJAFIAQgBAAH+DwABgACAAAAAmWUMAKAD/g+gAKwAAAIkAUgBAAH+DwABAAGcZQAEWANUCPIPVAAEAyAAbAEAAf4PgAAAAJ9lQADIA3wF+AT4BXwFAAQoAIAA/weAAAAApGUAAAAO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rAL8BAQEAAB+Z4gBSAD/B0gAgAQ4BIYHYAQBBI4FMAYAAH9nCAOIAP4PiAAADPwDZAikBSQGpAVkCAAAgWeIA0gA/g9IAAAMhAN8CIQFNAIsBeAIAAiEZ4gBSAD+D0gAAACcAWoBCAnICQgM+AMAAIlniANIAP4PSACIAAAIRAhECPwPRAhECEQIkGeIA0gA/w9IAIgAAAz8AyIAIgDiDyIAIACVZ4gDSAD+D2gAgAg4BIgDfgDoBwgIOAgABpdnAACIAUgA/w8oACgCgAFIAP8PaACIAwABmmeIA0gA/w9IAKAIEARuBIgDyAI4BAgIAACcZwAAgAS+BKoCqgGqAf4PqgGqAr4EgAQAAJ1niAFIAP8PSACICCAEqAQoBT4CKAXoBAgInmeAAUgA/wdIAAAH/gAABIADfgCAAwAEAACgZ4gDSAD+D0gAAAEkARwBBgGEDzwBIAEQAaJniANIAP4PSAAAAPwPBAgUC+QItAkECgAIo2cAAAQBtACUBFQEfglUClQKlAq0AAQBAACqZ4gDSAD/D0AAEADIByQIIwkkCcgIEAYQAKtngAFIAP4PKABAD/wABAb0AQQC/AcADAAAr2eIAUgA/g9IAEAAEA+QBP4EkASQBJAHEAC2ZwAApAiUBI4ChAHcD4ABvAKkAqQEvAQABLdngAFIAP4PSAAADv4BCAzwA/wPBAT8DwAAxGeAAUgA/g8oAAAA9A8UAJQBfACUCRQI9AfPZwgBiAD+D0gAAAD4D4gEjgSKBIgE+A8AANBnAACEBIQEvgKsAewHrACsAb4ChASEBAAA0WcIAYgA/g9IAAAA/g+IBIgEiAT+DwgAAADSZwQJZQkRBRIDBAPEDx8DJAMkBSQJFAkAANNniASqBKoCgAKkAbQPjgGEAvwCwATABLAE1GcACVAJVAU0A3wD3A90AxwDFAU0CRAJAADYZ4gBSAD+DygAKAGAAPQPTAREBEQExA8EANxnCAOIAP4PSAAAAPwPJAkkCSQJJAnkCQQI4GcIA4gA/g9IAAAAWABICEoIzA9IAFgAAADlZwAASAgoCKgPWA1cDUgNWA2oDygISAgAAOxnAAAECPQEtAKUAf4PlAG0ApQE9AQECAAA72eIA0gA/g9IAAAA9AMUAfQJBAj8BwQAAADxZwAAiANIAP8PyAAICQAIigj6D4wIiAgICPNngANIAP4PAAD8CQIF+gIAAPwPBAD8AwAA9GegBL4EoAK/AqQBgA+fAaQCpAKkBKIEkAT7ZwAAJAgUCNQPrAquCqQKrArUDxQIJAgAAP9niAFIAP4PSAAAAOgDKAAqAPwPKAAoAugBA2iIAUgA/w9IAAAP/AAUDvQBUghSCNIHAAAEaAAEUARcAlAB0gDUD9AAUAFYAlQCUAQABAVoAAOIAP4PAAT+A0II/gdAAP4HQgD+D0AAB2iIAUgA/g9IAIgEIAKkCSQI5A8kAKQBIAYIaIgBSAD+DygAQAgQBFAEfgTIAyoFqgigBgtokANQAP8PUAAEBnwBRwjkD0QARAMEBAAAD2iIAUgA/g9IAEAEEgSWBJAEmASWBBAEAAARaAADiAD+D0gAAAbkARwDQADQCRAI/gcQABNoiANIAP4PQAAQCAgJJAniDyQJCAkwCAAAFmiIAUgA/g9oAPoPigV+BAoEfgSKBPoPAAAXaAQJdAlUBVQFfAPUD1QBfANUBVQFdAkECSFoiAFIAP8PSAAICGAEGATYAg4ByAIoBEgIKmiIA0gA/g9oAIAEEAROA8gA/g/IAUgCQAQ3aAgBiAD+D0gAAAFKAUoB+A9IAU4BCAEAADhoiAFIAP8PSACICCAEaAWYBE4CKAOoBIgIOWiIA0gA/w9IAAAA/g9SCNIIUgFSBn4FAAk8aMQBJAD/DwQATADkD2cEWwRaBGYE4gdAAD1oEARUAlQB3g9UAVQJEAT+AhAD0gQUCAAGPmhACGQJFAUEBTwDBg9EATwDBAUUBSQJAAhCaIgDSAD+D0gAAAgkCSQJvg8kCSQJIAkAAENogANIAP4PQAAMCYAE/gMAAP4HQAicCAQFRWiIA0gA/g8IACAO+AGWB1QIXArQCRAIAARGaIgDSAD+DygAQAD8DwQIVAr0C1QKVAoACEhoAACUCZQFtAVUA1YPVAF0A5QFlAUUCQAITGgAAAAJeAVYBVgD3g9cAVwDXAV8BQQJAABQaAgDiAD+DwAA/A8EANQDVALUAwQI/AcAAFFokAmYBV4FfgMWAYYPVgFaA1oFsAWACQAAU2jEASQA/w8kAAAE/QUlBSUFJQUlBf0FAQBcaIgDSAD/D0gAyghCCMQFcQZWAkAF3ARCCGNoiANIAP8PSAACBCwFIAU/BSAFKAXmDwAAZWiIAUgA/g8oAIAIVAQ0AxwAFAAyD1IAgABmaIgBSAD+D0gAAAF8AQIBkA8+AUgBRgEkAGhooASUBJACvgKAAagPpgGWApQCjASEBAAAaWjEASQA/wcUAAAO/AEEBCUE9QckBCQEAAB2aIABSAD+BwgA4g9SAVoB+g9WAVIJ8gcAAH9oiAFIAP4HSAAAAX4BagFqAeoHagF+AQABgWhMCWAJEgVYA0IDMg8OAUIDQgU+BQwJMAmFaBABkAD8D5AAoATYA6wCqALoC6gK6AeAAoZoAAOIAP4PSAAACSgN/gMAAPwPBAD8AwAAk2gIA4gA/g9IAAAAVAFEAcYPdAFEAUQBAACXaIgDSAD+DwAA/AisBqwG/AWsCKwI/AgAAJ1oAAAgAPwPAgD4AwAAqAauAJQPtACsAqQEomiEAUQA/g8kAAQA8QdWAVABXgFQBfYHAACmaAAAEgmKBF8ERgVqAkgCSgHfAEYACgAQAKdoiAFIAP4HKAAgAKoHvgSqBKoEugSiBwAAqGhACCoJGgV+BRkDqg8AAR4DQAVABX8JAAmtaIADSAD+D0gAQApYCR4FygaYBp4JqAgACK9oiAFIAP4PSAAABOoErAL4D6gArgS4AwAAsGgAA4gA/w9IAIAM6AOIAOgP/gQIB+oIIASzaIABSAD+D0gAAAy0AywApw8kALQPIAQAALVoAAA0CAwE3gNMAVQBQAJMAN4HDAgUCCQGtmiIA0gA/w9IAAAP/gAKAqoC6gdKCU4JAATAaAgBiAD+D0AAEAUIBSQEogQMBpAFUAQAAMRoRAlUBdQFzAPMAe4PzAHMA8wDzAVUBVQJyWiEA0QA/w8kAEAAngeqAKoA6w+qAL4EgAPLaIgBSAD+D2gAQAkIBf4FWAFYAf4BCA0AAM1okANQAP4PUAAAAPwPVAlUANQHfAkABQAA0miIAUgA/g9IAAAAbAI8Aq4PrAI8AmwCoADVaIQBRAD/D2QATAZEAVQE1wdUAEQBTAIAANhoAAD0DBQC/g8UAfQIYAQUAv4PFAL0DAAA2miAA0gA/g8ABP4Dkgj+BwAM/gOSCP4HAADfaIgBSAD/D0gAAAT8BKwCrAH+D6wBrAL8BOBoAAgYCQoFfAVYA94PWANYA34FCgUYCQAA42gIA4gA/g9IAIAIFAZUAP4PVABUBXwFEAjuaAAApASUAtQPjAKMBD4EjALUD5QBpAKABPFogANIAP4PSABACjQJ1AbeBJQGtAkUCAAA9WgAAMQBJAD/DyQAAAPfAPUH/wfVAF8DQAL6aIgBSAD+B0AAHAD8B/QHVgVUBWQFDAcAAAVpiANIAP4PCAAgALQHrAKuCywI5AcgAAAADWnIACgA/wcIAOAPBAT8BVwFXgVcBfwFBAQOaYgBSAD+DwAAMAD8D6oEqAT+B6gEqAQAABJpgAFIAP4PCAAgDf4DKAiACRwE5AN0BgwIHGmQA1AA/g8QAPAJOAk0BfIDNAM4BfgJEAgtaQAAkAD/DwAA/g8SAO4BAAD4D68C6A8AADBpgANIAP4PAAD8A1QC/A8AAP4PAgD+AwAAP2mAAVAA/AcAAKgA+A94BXgFfAX4D3gAgABKaRADkAD8D5AAAAj8B9QB1AXUA9QJ/AcAAFNpgAFIAP4DAAz+A0IAqgT6B6oEQgT+AwAMVGmAAUgA/g8AACwJfgkMB6ADHgVCCT4JAABaaQAAVAhMBl4DVATAD1QJTAleCUwI1AgACF5pAAOIAP4PQAAcCFQE3ANUAVwJVAlcB0AAY2nAASQA/w8UAIADfwDlD1UFVwVVBfUPBwBtaQgJagVsBXgDbgHoD2gBfgNsBWoFCAkAAHVpiANIAP8PCADiCaII7gj6C0IIkglyCgAAd2mAAUgA/g9IAAAAvA+oCoAKvgqkCqQPFAB8aYABSAD+DygAiAiqCpgH3gSYBqoFqggAAH1pAACkBKQEgAL8AdYH1AH8AYACrASiBAAAgmkAA4gA/g8AAPwHVAJ8CSAExAN8D0QIRASEaQADiAD/D0AAHgjACV4EQANOBtQLBAgABIZpgAFIAP4PCADwB7gC9A8WANYDBAjoBwgAlGkAA4gA/w8AAPwHVgJ8BwAA/A8EAPwDAACVaYgDSAD+DygADAGUD0QJJglECZQPLAMAAJtpgAFIAP4PKACACOwFvAOuD6wDbAUkBQAAnGmIAUgA/g8IAEAIXAbcAVYJVAlUCVQHAACoacQBJAD/DyAAggBKACYA9w+iAqoCqgIAAK5pAATiBOwErgKiAKAPsgCoAqYCqASiBAAAtGkAA4gA/g/IAAAAvA+iCpAKpA+cCoQKvA/LaQAAyAMoAP8PAAD8D74CvAL8A74K/AcQAs1pyAAoAP8HKAAIBugBfAd7BXwFdAV0BwAA0GmAAUgA/g8IAHwAVAhWB/wA1AdUCXwLAAjYaQgDiAD+D4gAAARWBVQA/A9UAlYFVAUAAP1piANIAP4PSAB6ANoP/wraCv8K2gr6DwAAAmrABOwE2gLAArwA1gfWAPwCiAL2BOAEAAAKaiQIFAl/CRQFUAVKAzYBQQM0BX8JFAkkCRFqiAdIAP8PSAGEASYJDA24Dw4BfgUQCQAAE2qAAUgA/g9oAAAIfAt8C/wFfgV8B3wJfAkZaogDSAD/D0gAHAVsAXwJbA98AWwFfAUABR5qAAOQAP4PAAD8BwQJ9ArUC1QJtAqECwAAH2qAAVAA/g9QAAAC9AL8AvYP9AL0AvQCEAIhaoABSAD+D2gAAAl0BXYD9AF0A3YFdAUECSNqhAFEAP8PRAAADSsDqgg+B2oCKwWiDAAAKWo4A7gA/Ae4ACgAgADsB7gHqAeoB6gHAAAqaogBSAD/D0gACAj6CV8FWgX6AV8FWgX6CTFqiANIAP4PAABeCToLjg0cBUIFegtCCV4JOWoAA4gA/w/IAOAItAq+DPQGAASQAP4PEABEagAAyAD+DwgA+gOqAqoC/g94BI4DeAwACEtqkANQAP4PEAAyD7IA8gf+BfIH0QCwDyAAWGqIAUgA/g8oAIAPWgFaB0oF3gZaAMoPAABZasABKAD+ByAA2gS6BboEtQS+B9oFEAQAAF9qiANIAP8PQADmDLgDtArfCKQHuAq0CKAEYWqAAUgA/g9IAAgEuAVsA+4KvAmsB6wBOAJraogBSAD/D0gAEgjyBX8FegX6AX8FcgXyCXFqgANIAP8PAAT8A0QErAdsBwQApAj0ByAAgGoAA4gA/w/IAHgIzAv8C/4L/AvMC/wLAACQaogBSAD/DygAiA98ACcH7gX2BeQF9AcEAJRqiANIAP8PQAAaB/wF2AXeB9gF/gWIBwAAomqAAUgA/g8IANgMuAL0BBYAxAyoAugEAAipagAByAH+B2gAeAXMAfwF/gfMAfwFhAUAAKxqAAOQAP4PAAAUBtQG9gN0C3YHVANUBAAAw2qAAUgA/gcAAP4HAgT+Bf4F/gX+Bf4FEgT7aoADSAD+DwgAfgkuC/4NAAVeBS4LXgkAAARrgAFIAP4PAAD+B+4E5gPwD+YD7gz+BwAACmsIA4gA/g+IATAB1A82D4APNg9UD3QJAAAga0AIMAgMBAoCiAF4AIgBCAJIBDgICAgAACFrAAAEBoQBCAhgCB4ECgPoAAgDSAQ4BAAIImsUBCQCxAE8AwQIMAQOA+gACAMoBBgIAAAjawAE/AMUABQA8gcCADAMDgPoAAgBOAYICCdrAAD8DwQFpATUBAQNYAweB/gACAN4DAgIMmuIAMQPogSQBJIE5AewDA4D+AAIAzgEAAg6awAACAn8BVgB/AUAATAMDgPoAAgDOAwIAD1rUAhYC1QI8gdUDQAIMAQOA+gACAM4BAgIPmsABKoCqgivB6oAogIwCA4G6AEIAzgMCAhHawAB/geqBKoFqgi+BwAAHA7KAQgCOAwAAElrJAStAv4H/AOuAf0EOAwHA+QADAMEBAAATGuAALwHrAW8B4QIvAewCA4G+AEIA3gMAABQawAA/gOCBNoFqgTaBQAMEAPuAAgDKAwYAFNrIAHsD6wHuAeoB+AMYAQcA/ABEALwDAAAYWsAAboPuweAB7sHmgcwAA8O5AEEA3wMAABiawAEAATwBwAEAAQABP4HIAQgBCAEIAQAAGNrAAQEBOQHBAQEBAQE/AdEBEQERAREBAAEZGsACPAPAAgACP4HIAQAAP4HIAggCBAIEAZlayAIIAu8CKAIIAggBP4HJAIkAqQBpAAgAGZrAAAQCNQHFATUB5QEEAT+ABAHFAgUCBAGZ2sACPAHAAT+ByACCApoCKgFPgIoBegECAhpa6AAoAV8CGAIIAUgBf4EJAKkASQApAAgAWprJAikCKQOlAiUCLwIhA+UCpQKpAqkCgAIb2sQANAHHATQBZAF3gWeBbQFFAT0B/AHEAByawgM6AMoAGwL6AdoAi4JfASsA7wEqAgoBnNrEA7QAVAE3ALQD9AAXgn0DFQDdAVUCRAEdGsADPwDBAhUCHQPFAiED1QK9Ao0CtQIAAB3awAM/AMECGwI/A5sCAQPbAr8CmwKpAgAAHhrAAh8B1QE1gc8BUAAPAe8APwPvACoBwAAeWsAAIQARAgkBFQEnAIUAZQAdAAUAAQAAAB7awAAxAhkBJwGFAH0AAQA/AdECCQINAgkBnxrwAAiCJ4EEgPyAAAARABEAP4PQgBCAEAAg2sAAMIIPgSSA3IAAAj4CIgG/gGIBvgIgAiJa8AAIgieBJIDcgAQAM4HqQLoCwgI+AcAAIprgABiCB4GkgFyBBAETgPIAP4PSAFIAkAEi2uAAOIIngSSA3IAAAioBP8EaANlBVUJQASWa0AAYgxeApIBcADkDwQE/AVuBWwF/AUEBJhrgABiCF4GkgFyCAIJqAUvBxgFXQsVC6AItGsAAPwPFAXkBBQNQAzeCEIHQgb+CWAIGAi1awAAAAL8D1ICUgIRCUAI3gVCAl4FoAgYCLdrAAz+A1UJVQk9B0AA4AheB0IG/gVgCAAAumsAAFIGVAHMD1MBAAjeBEIFQgJ+BeAEGAi8awAAbAxsA+4A7AcEAmAI3gRCA14DwAQACL9rAAf/APUOpQD1AqcEAASvAqECLwHoAgAEwGsAAHwJUglAB1QFPA1ACH4JQgb+CWAIAADBawAA/ATSBMAH1AQ8AkAI/gVCAv4FYAgAAMVrAABUATQL1goUB8QCEAjOBUIC3gVQCAAAy2sAACAA4Ak8BSQDpAF8CSQJJAf8ASABAADNawAAIADwAy4CogKqAqoKIgoiDv4DIAIAAM5rAABIAMQHcwJKAsoDegpKCkoO+gNCAkAAz2vAAMgC6AOmApQDlAPUA5QKlAr0B8QCwADSayABIgHqB2oFagX/B2oFag1qDeoHIgUAAdNrEAD4B7YFlAz0BwAAtA8sAKYPJAC0ByAI1GsAAAAA/g8gBCAEAAD+B0AIIAgQCBAHAADVawAAQAF+AUgBKAGADz4BSAFIAUQBJAEAANlrAABACn4L5AdkBVQDXgDkB2QKZAlQCUAE22sAACgBKAEoASQB/AckCaQIkgiSCJAIgAbhayQBJAH8ByQJoggQCMALfgpICkgKyAkIBOtrAADEBPwF7AXsA+4H7AvsCuwKfArECgAA72skASQB/AeSCIIIKApkChAJzgkQCswKAAQPbAAAAAj8ByQEIgQiBH4AogMiBCEIIgggBhFsAAAACPwHpASkBKQE5ASkAaQGvAiACAAGE2wIAPgBCgIIAgAI/g+SCJIE8gGSBp4IAAQUbCAAGABGAFUAVABUAFQAVADUAxQEBAgABBdsAAhYCUYFVAJUAtQF1ARUANQDFAwECAAEG2wQABgJhAUjAyoJKgmqB6oAKgHqAwoMAAYibAgAqAS2Bb4FfAd8BbwFvAUcAPwDBAwABiNsEAAYCUQFIwGqDyoBKgFqDSoA6gcCCAAGJ2wQAMgCxALeAtwP3ALcAtwCHAD8BwQIAAYobAgAUAlYC1YLXAVcB1wJXAkcAPwHBAgABi5sEAiICrYEXANcAlwEXAccCPwBDAYECAAG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AAQRcBAAJA8kAIAFvAT8DrwMvA78ArwEvAmAAh9wEQSmAwAAAgATDLoDOgP4DzoBuwe6A7oPLHAQDKIDhAA2BlQB/gcmAfIEbgVqAfoFAARMcAAAIghEBgQDdA7UDzYPhA92D1QPdA8AAFFwAAAiBqwBAATqA+oH+gXiAeoD+gXqBQAEY3AQACYPQAAXAk0DoAOcA7YL+gtcBxICQABrcAAIYAgYBAACgAF+AIABAAJABDgIAAgAAG1wAAACCEIEMgQCAsIBPgDCAAIDYgISBAAEb3BACHAEAAL+ARACBAAECAQI/AcEAAQAAABwcAQChAF0AA4I5AQkAgQB9AAEAWQCJAwAAHVwAAgACaoIKgQqAqoBKgIqBCoFvggACAAAdnBwBAAO/gEAARgFAAQgBCAE/gcgBCAEIAR4cAAAQAhICigJJAQWAtQBHAIkBKAJIAhACHxweAgABv4BEAEABjAAjgCICAgJCAz4AwAAfXAACAwJ0gQABAgD1gACAwgEDAXSCAAIAAB+cAAAmAiICGgECAIKAewACAMIBMgEGAgAAH9wOAgABv4BAAMIAPAHAAQABP4HAAQABPgPiXBwCAAG/gEAAjgIAgzyA5IAkgCSAPIBAACKcHAAAAz+AwACGAgwBA4C6AEIAygEGAgAAI5wAABACCgJpAQgBBgDxgEYAiAEpAUkCEAIknBAADAO/gEAARgKQAg4BAAE/gIAApgBIACVcDgIAAb+ARACAAjoByoAKgDoBwgICAYAAKtwOAgABv4BAAMIAEgEaAbaBUgEKAcIBAAArHBwCAAE/AMgAgAA/A8kCSQJJAkkCeQJBAitcAAM7AMoCKgJqAQuBqgBKAIoBCgJrAggCK5wcAgABPwDMAYAAPgHLgkoCegLCAr4CQAEs3AYCAAG/gEAAhgA4A8UAJwBfACUCRQI9Ae4cHAIAA7+AQACKAQwAA4A+A8oASgBKAEIALlwAAAADOACoACgBr4ApAKkBKQA5AIEBAAAunAAAYgMigLKALgGrACqAqgIuArgCIAHAAC8cDgIAAb+AQgBEAR0A14I9A9EAEQDRAQAAMFweAgABv4BCAMQADwHpAAkCPQPJACiAyAEwnB4CAAG/gEAARgBAASWBJAEmASWBBAEAADIcCAJEgcOA8oAagwaAAAEfAkAAQAF/gUACM9wAAgADPwBVAFUBVQBVgVUAVQLXAlABwAA2HA4CAAG/gEQAoAIiAT+AogAiAD+AogMAAjZcCAIEA7+AQADWABID64EtASkBLQETA9AANtwQAgwBv4BEAYABPgIiAj+B4gE+AYACAAA33B4CAAO/gEQAP4PAgQiBfoEogUCBP4PAADkcPAIAAz8AwAEEAUAAagD/AqoCrgKqAYkAOZwIAQYBAAD/wAIAwAI+QQJAu8BCQT5BQAI53B4CAAG/gEAApAIhASmA7wAtA/ECKQIgATrcAAIighiChQJAAQqA1oELgSaCIoKeAgAAO1wAAAkBCQDfwAUBoAAZAA/BwQAfAKABkAI+XAAACIIIgY+ADYFNgG3AHYCdgQ+ACICAgQJcQAAEAgUBPQBVAlcA1wBXANcCVwJFAcAAApxPAQADv4BCAMAAF4BVgHWD1YBVgFeAQAAFXEgCBAO/gEQAoAI+ASWAvQBnAL0BIAIAAAZcTgEAAb/AQgDIACsB6QEpgSkBLwEpAcgABpxAAAkChQLvgQMBKQDMAIMBH4FDAUUCCAEIXEoCCgN/gElAfwNJAH8BSQJ/AEkBSAIAAAmcRAIEAz4AV4BWA1YAfwBWg1YAVgBCA0ACDBxeAgABv4BAAI4ANAPSAUGBUQEXAXEDwAANnGICKgGbgJuABQFDAGAAGgGHgBoAooOgAg8cUAIOAQAAv4BEAikBPQDpgCkD/QIpAgABExxeAgABv4BAAKQCPwK1ArWD9QK1Ar8CAAATnEECfwEXQReAVwN/AAEAHYMBQH8AQQMAABVcQAAAAj+BLIAzgK6DAAA/gQSCRIDng8ACFlx8AgADPwDIAj0CpQK/AqUDvwKlAr0CgAAXnEAABgJVgVUAVwN9AEAABwN6gjIAjgFCAlkcTgEAAb+AQABEASEBL4CrAHsB74BhAIABGdxAAj8DZQAlADsDBQAzAFEBVQJVAHMDQAIaXE4CAAG/AEQAgAI/AusCqwCrAasBvwLAAhucQAAMA40APQBdAV+AXQFdAV4AfQBEgwAAH1xAAAQDv4BEA78A6wEbADqB6oEagL6DwAAhHE8CAAG/wEIAgAM/gCqBqsIqgqqAP4GAASKcQQEfAc/ALwAvgb8AAACZwSqAIkCRAwAAI9xAAAICvoK2gLaCv4D2gr6CtkC+QoICgAAlHEYACAM/gMQBCQBlA9ECSYJRAmUDyQBAACZcQAE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t3MEAiQC/AMkAgQAgA+ABP4EiASIBIgPCAC7cwAEJAL8AyQAAAz4A8gJfgZIBsgJGAgAAMJzAAQkBPwDJAIAAPQDFAH0CQQI/AcEAAAAynMAACQE/AMEAkAI/gdCAP4H/A9CAP4PQADNcwQCJAL8AyQBEAFICCQFkgTEBEgCEAEAAOBzBAQkAvwDJAIAAFwGSAH+D0gBSAJABAAA7XMAAEQE/AdEBAAC8AgABP4DAAj8D0QIBAjycwAAJAT8AyACDACMAvQClALUD5QClAIAAv5zJAQkAvwDJAoACPwFVANUAVQPVAn8CQAEA3QAAiQC/AMkAQwDaAIICP4HiAAKA2oEAAQFdAQCJAL8ASQBAAD8D1QEVgTUAVQDvASABAZ0AAQkAvwDJAIACXwIVAnUD/wPVAlUCXwJCXQABCQC/AMkAgAItAcsAKYPJAC0ByQIAAAQdAAEJAL8AyQCAAj0CRQEEALeARAEFAj0CyJ0AAQkAvwDJAKAANQC1Am8CMQHZACUAwAEJnQAAiQC/AEkAQAAtAe0AqwDLgj0DzQAAAAqdAAEJAL8AyQCAAgIBf4FWAFYAf4FCAUACDN0AAAkAvwBIAOIAP4PSAAAA8gA/g9IAIgDNHQAAFoAWgFeAXoBWgFYAXoFXgNaAVoAkAA8dAAIRAT8B0QGAADoBqgArA+oAKgB6AMIBEt0AAAkBPwDJAIAAPQHvAW2BbQPvAXwBQAFW3QAAiQC/AEgAQQE9gSUApAB8ACUApYC9ARcdAAAJAT8AwQI8Ae4AvQPFgDWAwQIyAcQAF50AAQkAvwDJAIAADwAsA+wB/4AsA+wALwPX3QAAJQOVAh8BFQGlApACVQJvARUAVQGAABqdAQCJAL8ASQBAAz+AKoGqgD+BqoBgg8AAHB0AAQkAvwDJAIACHwEVALUAf4HVghUC3wLg3QAAiQE/AMkAgQAdA9kA9YFZANECXQPAACHdAAAJAT8AwAM+gMqCMAHFgcqBOgPKAloCYt0AAAkAvwBJAAAAvQC9AL2D/QC9AL0AhACnnQAAiQC/AMgAQoEaAV+A+gBbgVoBW4JAACndIAAfAh0C7QLtAv8CwAPVAt2D1QLVAkAALB0AAIkAvwBJAUABP4Evge6Ab4CugJ+BRAFynQABCQE/AcgAggM/A/+B+wH7AfoC+gLAAjcdAAIAAb8AQQABAb8BQIEggc+CMIDAAwAAOJ0AAB0DfwB/A90AQAO/AEEBvwFBAL6DwAA43QEAE0N5gMADfwH/AsCCP4HWAHnD1QBAADkdAAE/AX+D/QJ7AHwDfwDBA78BQQG+gsADOZ0AAAEBAQO5AkcCNQEFAUUAPQHBAgECAQG7nQAAFgISA7kB3IHaAdiB2oBcg9kCEgISATvdAAA/AcEBbQE5AQQAQIM/guSAPIPAggABvZ0AACIDPoDiAD+D4oAAAj8D5QA9A8ECAQE93QAAEIIVAzAC2gJZAtWAUwBVA9kCGAEAAAEdQAAfAl8BVwHbAU8AIAPfAiUAPQPBAgABhh1AAAIAAgA/g+IBIgEiASIBP4PCAAIAAAAGnUAAAQBBA/+CVQJVAtUCVQL/gsECQQJAAAcdQAAkg+SBP4EkgcAAP4PiASIBIgE/g8IAB91AAAgCJAIjgiICIgI/g+ICIgIiAiICAAIInUADOQDJAm0CrwKrgqsD7wKtAqkCiQIAAAjdQAM5AMkCLwKpAqkCqYPtAqsCqQKIAggACV1AAArAiQC/wEkAQAIvgbqAb4EqgS+AwAAKHUAAAAM/AMkASQBJAH8DyQBJAkkCfwHAAApdQAAAAz+A5IAkgD+B5IIkgiSCpIK/gkABCt1AAAIAOgPqAKoAqgC/A+oAqwK7AcIAAAAMHUAAPwPRAREBEQE/AdEBEQERAREBPwPAAAxdQAA+A+IBIgEiAT+B4gEiASIBIgE+A8AADJ1AAAAAPwBlACUAJQA/A+UAJQAlAD8AQAAM3UAAPwDJAEkASQB/w8kASQBJAEkAfwDAAA1dQAAAAD8AyQBJAH/ByQJJAkkCfwJAAgABjd1AAAACXwJVAVUA/wBVAlUCVQJfAkABwAAOHVAACAA+AeuAqgC6AOoAugLCAgIDPgDAAA6dQAA/gciAv4DIgL+AwAACAgICPgHCAAIADt1AAD0DwQE9AVUBVQF/AVUBVQF9AUEBPQPRXUAAPgB/g+uD3gAIgnyBDoC5gkiDOADAABMdQAAAAG+CKoEagI+ACoAag+qAL4AAAEAAE91AACACPwP1AjUCPwI1APUBNQG/AiACAAAUXV4CAAG/AEABhAA/A9EBEQE/AdEBEQE/A9UdQAA/AckAvwDJAL8A4AAqAD+D6AArACAAFl1AAA8AKQPogqSCqIKgA+8CoQKRA88AAAAXHUAAEQA1A/UCvwK1g/UCsQKpAqkDyQAAABidQAAoACuAu4CrgLuB64CrgLuAq4CgAAAAGV1AAD8B/wDJAL8A5AAiA/WCKQI3AjED0AAZnUAAPwH/AMkAvwDAAgoCSgJvg8oCSgJAAhqdZAAlADcB7QFlAW8B5QFsgXaBdoHkABAAGt1SAB8BPwH/Af8B/4H/Af8B/wH/AdIBAAAcHUAAAAKvArsB6wGvAKsAqwG7Ae8CgAKAAB0dQAA/AckAvwHdAasA/QDXg1UDVQJVAcAAXZ1AAA4AAoP7AuoC64LqA+oC+wLCg84AAAAeHX8ByQC/AMkAvwDIAC0A7QCrgs0CPQHIAB/dUAA5gdZBdQHWAX/D+AEdgN5B7QIUghABoZ1AAB0BVQPXAzABwQA/A/0DvwP9A78D0QIinUAAPAJ/gj+D/4P/g+uD/4P/g/+CPAJAACOdQAE5AcEBPQDTAIECPQElAL+D5QC9AwAAI91AATEA/QDTAIACKQHPACmDywAPA9kCEQEkXUACW4JVAXUA1IBCA2iAyoE6g82CWIJIAiXdTgJgAT8AwQAJAAkCCcIpA9kAGQAJAAAAJl1MAkABfgDCABIBCgKrAmoCagIqAgoBAAAmnUYCYAM/AMECMQINAQmAqQBZAIEBAQIAACfdZgIgAb8AQQAhAD0B5UElgSUBJQElASEAKR1mASAAvwBBAD0A5QE9gSUBJQE9AQEAgAAq3WICLAO/AEECEQItAWWBpQG9AXECEQIAACudYwIQAb+AWIAIgDyBysIKwkqCfIIEgYiAK91OAGADPwDBAz0AxQAlgLUAxQA9AcECAQEsnWYAIAO/AEEDvQBVATWBXQCVAWUBDQIAAC5dbgIgAb8AUQAJAqUClYJFAWkBCQCRAEAALx1GAmADPwDBAAkBbQE1gjUCrQKlAAEAQAAvnWYCKAO/AEECIQEtASmAuQBpAKkBKQIAATFdZgIgAb8AQQA1A9UAFYD9ABUA1QI1A8AAMd1mASABvwBBATUBxQEFgT0B5QElASUBAAAynWYBIAG/AEEBCQFFAVWBdQHVAUUBSQFJATSdYgIkAb8AQQApAK0AqYC5A+kArQCpAIEANV1mAiABvwBBAD8D6wErgSsAawGfAUECQAA2HU4CYAE/AMECNQJVAtWCVQJVA3UCRQIAADbdZgIgA78AQQA7A+8Ar4C7A+8AqwK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JALkA3wA1AF+AVQB1Ad8AQABl3iEAPQHLATgB8QANAykA0YA9AcUCPQJAASYeEIA+gcWAvIBAAT8DKQC/wCkAP8CpAT8AJ94hAD0D0wEwAcIAHwNSAP8D2gDfAVICQAAp3gAAMoE6gL+D+oKgAr8CtQK1grUDvwAAACpeAAAhAD8ByQC5AsACPwHrAKsAqwG/A8ACLB4hAD8DyQE4AeIAA4J/A8ICPwPCgjICQAAsXgEAdQPLATEC/AHCACoDwgHfgKIBWoIAAazeIQA/AckAuQDAAisB2gALg2oAygErAkgALR4hAD0DywE5AcAAKgL2ArcCtgKqAsoCAAAuniEAPQPTATEB0wA5A9cCVYJ9A9UCVQJTAm8eAAAggD+ByICwAd+A6oEqgD+BqoBgg8AAL54wgD6ByYC4gEABP4DigjqB6oB6gKuBAAAwXiEAfwPJATkAwwIaA+OCOgOSAioD84IKA7FeEQA9AdMBMQHAAB0CFwG3AF2CVQJVAcAAMp4AABSAtIHegVuBWoHagLqB2oFegVCB0AA0HhQBVAFPANUDxYLfAsIC2YLUgu+D5gBgAHVeAAARAD0DywE4APID/wPzgjMD+wIyA8ACNp4hAH0DywEJATEB/wC3AbcDv4K3A/8AgQD6HgADvwBBAS0BLQOtAuWCoQKtAq0CrQOlAD0eEQA9A8sBMQHIACaCdoP1gjWDJoKIAgAAPd4QgD6BxYC8gOACHYHzAFfAMwB9QdUAQAA+ngAAIIA/gcSAuADSgjvBOoC+gDvAuoCAAwBeQAAQgD6BxYC4gEIDP8ArAb9AKwGLAAABw55hAD8ByQCxAsUCEwEXgfQD0wJXglUCRAIGXkAAAQB/APkCw4IVAfUAUAIDAfsDywJZAA6eQAAIAQkAqQBJAgkCOQPJAAkAKQBJAIgBDx5AACIAYoA7g9YAIgBAAD+BwAIAAgACAAGPnkAAAgBiADOD7gACAkgCCAI/g8gCCAIIAhBeQAAiABKAOwPWACIAAAA/A8EAHQCjAEAAEJ5AAGIAMoPeACIACAA/AcgCP4JEAj4CAAGSHkIAYgAzg94AIgJAAT8AyQAIgDiDyIAIABJeQgBiADuD1gAiAgACPAPAAj+DyAIIAgACFB5iACIAO4PWAAIAYAA+A9OBEgESATIDwAAVXmIAIgAzg98AAgI4AwAAvIHxAgwCGwGgABWeQgBiADKD7gAAAj8DyQJJAkkCSQJ/A8ACF15iAFIAO4PWACACDwEJAPkACQA5A88CAAGXnmIAYgA7g9cAIAA+AMoASgB/g8oAfgBAABfeQAAgASWBLQCtAC+B7QAtAK0ApYEgAQAAGB5gABJAOsHWACCAOoDKgEqAeoJAgj+BwAAZXkIAYgAzg94AAgAQAFKAUoB+A9KAUoBCAFoeQQJdAXUBdQB/AnUCdQH/AHUBdQFdA0ECW15EAAQAZgIbgRMAXQJSAlGD1gBZANUA4wMd3kIAYgAyg+4AAAEVALUAX4DVAlUD0QBAAB4eQgBigDqD5gAAADcD1QB9ABUC1QI3A8AAHp5CAGIAOoPWABACAgJ/gVYAVgB/gUICQAAgHkAAAQK/AuMA/wL3AveD/wDjAf8BwQKAACBeQAAFAlMBV4BTAlECVAPTAFeBQwFNAkgAIR5iACIAM4PfAAIAEIEKgIqCeoHKgG+AqAEhXmEAEQA5g9cAAQB8AGqAfgHrAGqAfgBAACNeYAAiADsDxgAwA98AMQH9ALUA1QI/AcAAI95iABIAO4HWACCAPoPagVqBeoHagV6BcIHpnkAACQFswWABesB/gHaB4ABvgOCAz4FAAWneQABigDqD5AABAB8D9wLXgtcC9wLfA8EAap5xAAkAPUPLQBAAv8CrQL/D6oCrQL/AgACrnmIAUoA6g+YAAAI/gv/CuoK/wrqCv4LAAixeQABigDqD5AAxA/8BfwH/gb8AvwP3AIAALl5AACED7wArASsBPwHrASsAqwKugiCBwAAunkAAIAP/ADUAtQC/APUAtQC1Aj8CIAPAAC7eQQABA90AWQFZAfWBVQFVANECXQJBAcEAL15EAAID+gBxAGUBbIHugWyB4QJ6A8IAAAAvnkgBCQCJAGkAGQA/A9iAKIAIgEiAiAEAAC/eQAAkAhUCFQENAN8ADQANAdSCFIIkASAAMB5iAhMCCwEnAOMALwAigqaCSoJSgdIAAAAwXkAApIBUgD+D1IAUgQAB/gEBgTABAAPAAjDeQAAUAhUCFQENAO8AJQANAdSCFQIUAYAAMZ5AAAYA5gA/A+UAAABRABEAPwPRABEAEAAyXkAACgEugS6AroBugH+D7oBugL5AigEAADLeQAAkgNSAP4PUgAACDgEgAN+AIADMAQICM15lANSAP4PUgACAPgBiACIAP4PiACIAPgB0XkAAJQDUgD+D1IAEAFCAUwBAAH+DwABAAHSeQAAlAFSAP4PEgCACDgEgAR+AgAB2AAAANV5EgOSAP4PUgAAAP4PIAQAAP4HIAgQCAgG2HkSA5IA/g9SAIAJYAT6B4IIYAgeCOAGAADfeRQDlAD8D1QAlAkACPwPJAkkCfwPAAgAAOR5AAAUA5QA/A+QAIQAtACEAPwPhAC0AIQA5nkgAawIbASsA7wDrg9sASwDbASsCCABAADneQAAFAOUAPwPkgAACPgIiAb+AYgG+AiACOl5lANUAPwPUgCSCBAETgJIAf4ASANIBEAI63mSA1IA/g9SAJICAAaQAXAA/g9QAJYBEAbveQAAlANUAPwPUgAACHwGRAFEAEQBfA4ACPB5kgNSAP4PUgCSAhACzwEECPwPBADsAQQC+HkUA5QA/A+SABoASA9ICUgJfglICUgPCAD7eQAAlAFUAPwPUgACCagErARWBXQCzAFAAP15FAOUAP4PUwAACZ4JUAhwBV8GUALQAV4AAHoQA5IA/g8SAAAB6gesALwApA+sAKoEqAMFehIDkgD+D0IACAj0BJIDkACSD+QICAgQBAt6AAAYA5gA/A8AATwIpAqkCqQPpAq8CgAIDXqSAVIA/g9SAAAA8gdUAVABXgFQBfYHAAAOegAAlANSAP4PAgA4DMoDSADMD04IeggABhp6AACUAVQA/A9SABAA/g+oBPwHqgSoBAAAIHoYA5gA+A+UAAAM/AMEANQH9ALUCwQI/AcjehAA+AVWBfQFXAX0BiAHpAD8D6QAIgcAAC56AADKASoA/wMACP4Krgr+D64K/QoACAAAMXoUA5IA/g+SAAAC6A+kAqQC6gOiCroK4gcyehQDkgD+D1IAEgDADxIAwg9aBUIF2g8AADN6JAIkAfwPogAABlgAVgVWC1QJXAHwBQAIN3qUA1QA/A9SAAAJfgmWBdYGvgZWBVYIXgA7eooBSgD+D0kAAADKB6oEgQQtBKEE7QcAADx6FAOUAPwPUgBABVwFtAJ2CbQG1ABcA0AEPXoUA5IA/geSABAAdAesB64HtAe2B5YHVAA/eooDSgD+D0kAgA9eAFYPVgVXB14Awg8CAEJ6FAOSAP4PUgCABnwArAysCf4KrAKsBvwIRnoSA5IA/g9SAIAIvAwsBSwF7gYsArwCgABMehAM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fXwsA6AA/g+gAAwBQABECEQI9A9MAEQAQACJfCwDoAD+D6AALAlgBFgGxAFACEYImAcgAJJ8LAYgAf4PoAAsAQAIaAiICw4IiA9oCAgIl3wIACAD/A+gACwBAAj8DyQJJAkkCfwPAAiYfAAALgOgAP4PJACAD4AE/gSIBIgEiA8AAJ58jAMgAP4PhAH8DxQE/AUUBPwEFAX0DwAAn3wECXQF1AXUBXwDVA9UAXwDVAVUBXQFBAmkfAAAgAD8AMQD1gLWAtQK9ArEDvwCgAAAAKV8AADyCJIIngc8A/4PKAAEA3AIkgieBwAAp3wsB6AA/g+oAAAM+AMICEgI7g9ICEgIAACqfAAAKAqoCqoKnAu+AogCmAacB6oKqAooCq58JgegAP4PoAAuAQAA/A9UBNYAVAN8BAAEsXxkCREFQQWMAyABkg8uAUIDwgV+BQwFMAm5fAMA0AH/D1AAkwGAALoAggDjB5oAkgCiAL18AAa4Af4PIAAIAwQIpAanAKQPpACMAoAMvnwCACwH4AC+DwAA1A/cAtwC3grcCtwPFADKfAwAIAP+DywAgA9+BMgDAAz+A5II/gcAANV8BgCgA/4P6AAACKgGqgCsDvgArAyqAIgO1nwGANgA/wNYABAP/AB0A/QC9gL0AvQDIADZfAwAoAH+D6gAJAlABNwHAAisC7wKqAqoC9x8AA78AQQIHAW8BS4Dhg8cA7wDHAUsBQAA33wGAKAB/g+MADoA1g//CtYK/wrWCv4PAADgfAMAkAH/D8IC/wEBAlUB/wfXAz0BkQKBAud8qAH+D6AAKAjgC/wL/Av8D/wL/AvcCwAI73wDANAA/w/eAY0HvQClB+8ApQetAL0HAAD4fIAEhASYA5QB4wDQD0gARAF0AUACgAQAAPt8AAAABJQE1ALcCLQIlA9SAEoBQgKCBIAE/nwAAJAO3ACyDIgCAAD8AwABAAEAAf4PAAAAfQAASAd8ANIPSAEAAOQHJAgkCCQIfAgABgR9SAd+ANAPTAAAAxAATgCICQgICAz4AwAABX0AAEgHdgDQD0wA4AoECAQI/A8ECAQIAAgKfQAAFAhUBVQFfAH0CVYPVAEcBZQJJAokAAt9SAduANAPTADgCggIOATIAg4DyAQ4BAgIDX1IB24A0A9MAAAB+A8IAcgAPgDICPgHAAAQfRAOnADyDsgAgAIECEQM/AtECPwPQAgAABR9SAduANAPTAEAAOgDCAEIAf4HBAnkCQAEGX1IB3YA0A9MAGQBAAT+ByIE/gEiBiEMAAAafUgHWAD2D2AAQAsEB/wAhAQkBTwD4AQgCBt9SAd2ANAPTAAAC3AITgbAAUIITgjQByAAIH0gACoJagVqA+oL/wlqByoBqgWqCSALIAghfUgHfgDQD0wAxAoACAgH+AAuCCgI6AcIACJ9AAA0CBQFVAX0AV4JVA80AbQFFAU0CQAAJ30ACB4JgAXeAcAJogmSD14BUgUeBSIJIAArfRAJHAlQBV4FtAGQD04BFAWUBRIJCAoAAC99AAAACD4FagXqAX4Jag8qAaoFPgUACAAIMH1IB3YA0A9MAcAA/A9EBEQE/AdEBEQE/A85fUgHbgDQD0wAAAMgAKIPngSCBKIEng8AAEJ9SAduANAPTACAAogATgQ1BTQFTAlAAAAAQ30QDtwAsgZIAEAHSABoBloFzAQoBggMAABEfUgHbgDQD0wAAAMACPwPJAkkCSQJ/A8ACEx9SAduANAPTAAAA0IIJgkqCZIPKgkmCUAIUH1IB24A0A9MAKADBACkD6QEvwSkBKQPJABVfbAN7ACiBJgCAAD0BzQJLAnkCTQJLAngBV59SAd4ANYPUAAACygImAQYA84DCAQoCCgAYX1IB24A0A/MAMQDkADID9YEpATcBEQPgABmfUgHbgDQD2wBIACQD4wEogSkBIgEkA8gAG59AAAsCCwFlgHUCcwJgA9eAVIFEgUeCQAAcX1ID3YA0Q9MAAAJBAS8AycALAC8DwQIAARyfQAAkA78AJIGSAIAAFgDdgjQD0wA4AIABHV9SAd2ANAPTAAACxAIiAamBaQEiAawDBAAdn1IB24A0A9MAQAA+AeWCJYI/AicCJQI8AaTfZAMvAHiDNgAAAo6CEIJEgnqD4IJPglGCJl9QAduANAPTAAAAf4PAASoBP4FoAQsBQAEmn0AAEgHfgDQD6wDgAlUBFQDXgBUBtQIBAScfTAO7ACiDJgCAACMDKQCpwCkD6QArAKADKB9MA7sAKICmAQABNoCVAjUD3QATAKABAAArX1IB24A0A9MAEADEAD+D6gE/AeqBKgEAACxfU4HcADsD0AB/A/sA+QDJAKsCyQI/AcAALJ9SAd4ANYPgAL8DwwAvAPkBLQEBAD8DwAAv31IB24A0A9sAQAAvgeqAKoA6w+qAL4EgAPKfQABPgUuBb4F7gGuB6IBWgMaAyYFQgUAAM99SAd2ANAPTAAAAV4EQAD8D2QJcQhGA4gE0X1IB24A0A9MAAAFIASqAioI6gc+AaAGAADSfUgDdgDQD0wA4AOEAJQHfgVUBVwF1gcQANp9SAduANAPzADABZwCrAksCO4PLAO8BAAE4H1IB3gA1g9IAQgAoAeUAJwA1g+cALQHAADjfSAIvAziAtgCgAQgBH4DtAq0B7wBIAYAAOh9SAduANAPTAAAD/wHrAKsD6wCrA+8AoQP6X1IB24A0A9MAEAJFARcA/QJ1AbSBtwFVAjvfUgHWAD2D2ACAAT0BbwHtgW0D7wF8AUABPR9SAd4ANYPSAAAAvwErAKsAf4PrAH8AgQE+32QDtwAsgTAAZwE1AeUBAQA8AwOA/gEAAgBfkgHXgDwD2wAgAIgBGoDqgpqB74AIAcAAAR+RANfAOgPJgAAAfwHvAK8AvwHvAq8CvwNI35AAnwBfAD8B/wASAIYAXwE1ANUANACgAAmfkgHbgDQD8wAQAL2D5gHFgTwD5YIEAgAACt+EA7eAHEEbAMBCHYG4AksCLsK+wsmCgAILn5AB34A0A9MAUAA7A8EANYHdAVUBdQHAAAxfhAO3gCxDMwCAAD3DwAEzgMBBOgHhgiYCD1+kA7cALIMiAIADPwChAaWCaQLhAD8BgAAPn5IB24A0A9MAAAK/Aj8Bf4F/AH8BfwJEAhBfgAIMAq+CjwL/AM8D4gCXgZkB1wKhAoAAEp+QAdOAPAP7AHAB/QHHgT0A5AG/geQDBYCVH6gAy4A8Ae8ABAA/Ae2AtgPPwPQBBYOAABefpAO3ACyBIgCAAiqCeoHrwEKD+oJqgmABWp+AAd4AJQGUgEIADQH8gX6BdIF9AX0BwQAa34AAH4Kfgd/B/4PfgsYB/YC0gp+CpgKgAhwfkgHbgDQD0wBAATwAt4B+gfqAdYC8AQAAHN+kA7cALICCAk+DOsD6wm+BzQMiwN4DAAAfH4QDtwAsgZIAv4PNAi6DzgJPgisDxALAAiMfpgO9gCRBkgBEgjuB/4H7wP+A+4H+gcACI9+gA7cAKIGWAEADPwD9An+C/4O/Av8C4QJln5QB3wAagIACXYE9QcQBPYPMAT+B9AMFgKgfqAEsAVsBSIFkAQAAPwBAAEAAQAB/g8AAKJ+AAAwCewEogSYBgAABAQEBPwHBAQEBAQEpH4AADAJqAVmBRAFQABEAEQA/A9EAEIAQACmfqAEuAXkBJIEgAIwAI4AiAgICQgM+AMAAKd+IAW4BeYEkAIQDIQDfAiEBTQCrAVgCAAIqn4AACAFuAVmBRAFAADEB0QIRAhECPwIAAarfgAAMAXoBaYEkAIACHQEBAP8CAQM/AMAAKx+IAW4BWYFEAQAAqgAqAD+D6gAqASIAwAAr34gBbgFZwUQBQAE9AEEAQQB/wcECfQNBASxfgAAMAXoBaYEkAIACHgIAAT+BAACmAEgALJ+AACYBdcEsQQAAP4PAgCyAdoBAgj+DwAAs34AADAFzgUiBQAA8A8QA/AAnggQCPAPAAC1fgAAMAXsBaIEkAAADv4BAAwAA/4AAAcACLd+AAAgBbgFZgUAAWAIWATEA0AIRgjYB2AAuH4gBbgFZgUwBQAA/A9ECEQE/AFEBkIIQAa5fgAAMAXsBKICmAoACDgEygIOA+gEGAQICLp+AAAwBawFYgUYAQAICAf4AE4ISAjIBwgAvX4AADAJrAVjBRgBAghCDP4LQghCDv4JAAi/fgAAuAXkBJICgAoQCFAEfgTIAyoFqggABMN+uATkBLICAABUBnwBVgj0D0QARAEEBgAAxH4AACAFuAVmBRABAAj8DyQJJAn8DwAIAADFfgAAIAm4BWYFAAD4AygBKAH+DygB+AEAAMZ+IAWwBW4FIgUAAPwPRAREBPwHRAT8DwAAx34gBbgE5gSQAgAIfAZEAUQARABEAXwOAAjIfgAAMAXoBaYEkAQQAEgCVgQkBVQFTAiAAMp+MAqsCWIJEAUAACwBIAH+DyABLAEiAQAAzX4wBZwE8gKIAiAAog+aBIYEogSiBJ4HAADOfiAF+AWmBJAEBACsAqwClA+0AqwCpAIAAM9+IA24BeYEkAAACKQIpAiUD6wIpAggCAAA0X4AADgL5gmQAQAIKA3+AwAA/A8EAHwChAHSfiAAmATkArICCABABugBCAh+BIgHaggIBtN+MAXsBKICmAIAAKQHpASkBL8EpASkBwAA1X4gBbwE4gSYAgAIpASmA7wAtA/ECKQIAATYfjAF7AWiBIACIAiQDqwJpgSIBpAEoAgAANl+IAW4BOYCgAIgAKAPsA+uBKgEsA8gAEAA234gBLgFZgUSAkAAqAKoAq4ClA+sAqQCIALcfgAAMAXsBKICkAIQAEgPtgSkBLQETA9AAN1+IAWcBOIEmAQAAPgHlgiWCPQInAjwCAAG3n4gCbgFZgUQAUAIOAiYBQoCyAUoCEgIAADffiAFuAVmBZIEEAJACGgHXgBID2gISAhIBuJ+AAAgCbgFZAUAAOAPvAK0ArQKtAr8DwAA434wBawE4gSYAgAIrAScA4wAvACaCSoHAADlfjAF6ASmAqACCAhEBeQGagLCBVoMQAQAAOd+IAC4BeYEsAIAAPgHBASgBP4FYASsBQAA6X4wBZwE8gKYCgAI3AVcBF4DXABcBNwJEADqfgAAmAT2ApICAAJUANQHfgVUBVwF1AcSAO1+IAW4BOYEkAIAALQIFAUeA9QBFAVwBRAI7n4AALAF7ASiBDgAoAe0AqwCrgs0CNQHNADwfiAFnATiBJgCAAD4AqgCqAKuD6wC/AIAAvN+AACwBWwFIgUAAPwDtAL0B7QKtAr8CwAA9H6wBOwEogKYAiAA/A+qBKgE+geoBKgEAAD1fiAAmAXWBLECAAC+B6oA6w+qAKoEvgMAAPd+IAX8BbIEAAz+A5II/gcADP4Dkgj+BwAA+H4AALAF7ASiAgAI/AcEANQH9AIECfwHAAD8fgAAIAW4BWYFAAUYAIgCqgisD6gAqAKABP1+AAAwBegFJAUAASgMqAMoBO4PKAkoCQAA/34AALgFZAUSBYgAQAQqAioJ6gcqAb4CoAQAfwAAOAqkC3MJAAyqCJoGBAmgCZIGnguiCAV/AAC8BeIEmQIIAOIHEgTyB14F8gfyBwAABn8AANgCTgJ5AQAE7wQ/AqABKAMmBOwFBAQOfwAAOAXmBJEAAAL8D1ICAAjeBUIC/gVgCBN/IAW8BOMEmALADFQC8gnWBtEG3QVVCAAIFH8QBawFYgUYBQAAtAecANYPnACUBLQDAAAVfwAAOAXkBLIECAKgCKoLmAbeBJgHmgSoCBZ/AAC4AuQCkgAABvwBlAfWA9QHVAHcBwAAGH8gBLwFYwUZAAAFbAVrBaoKqge+ASAGIAQZf5AE3AKjApgCAgDqD2IFfgV+BWIF6g8gABp/IAWwBG4FIAUAAHgBeAV8AXgJ/A/4AQABHX8AANwFswSIACII4AcECK8K6guuCqIKAAggfwAAOAXkBRIBAAz8A3QIrgr+D6wK/AoACCR/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SANABAAA/A8EAPwDK4EADP4Dkgn+BwgA9AySA5AAkg/8CBAIAAQvgQAM/gOSCP4HAADoD6gCqAL8D6gCrgroBzGBAAz+A5II/gcAAHgESgfMAMwPSgh5CAAGM4EADP4Dkgj+BwAA7g8ABEEFzgQABO4PAAA4gQAM/AMkCfwPIASQBSgEpgQoBxAHoAQAAD6BAAz+A5II/gcAAPwB1AFUAX4HVAFUAXwBSoEADP4Dkgj+BwAAFADeB1QFVAVeBdQHAABLgQAM/gOSCP4PAAD0DwQA5gxUA5QFdAgACEyBAAj+B5IA/g8AAOgDuALsB6gK+AsoCAAEUIHADzwApA+kALQGhAWmBZQF1Aj0CJQPBABUgQAM/gOSCP4HAACkCJQIhg+UCKQILAgAAFWBAAz+A5II/geAAEwItAdGAPQHFAj0CQAEZYEADP4Dkgj+BwAB/gjqCqoKqg+qCr4KgAhmgQAM/wPJAP8HAADvDyAEtwQoBSIE7QcAAG6BAAz+A5II/gcABHwDVABUB/wIVAhUAXwHcIEADP4Dkgj+B5IAqgf+BqoEvgOqBLoIAABzgQAI/geyAP4PgAD8D6AExA/4BwQA/AMAAHiBAAz+AxII/gcAAP4G6gHqBOoD/gjABwAAeYEADP4Dkgj+BwAAfAXuBewC7AX8BAAEAAB6gQAM/gOSCP4HAAC8AqwJLAjuDywDvAQABHuBAAz+A5II/geAAXgOeAD4BQgI/gMIDAoGfoEACP4HkgH+D4AB6gS4Bq4GqApqC6kGgAB/gQAM/gOSCP4PAAjuBwAI/AtUCNQJ/AoACICBAAz+A5II/gcAAFQO1AFUCVYJVAlUBwAAioEADP4Dkgj+BwAAeAV4BXgBfAl4D3wBeAGPgQAAZAA8D/wHvAe+B7wHvA/8DwwPZAAAAJiBAAz+A5II/gckAdQF/AHUD/wB1AX0BQAAmoEADPgDCAD4CPgH/gP8B/wH/A3cDxgAAACbgQAM/gMCCP4HEADKBagFrgeoBcoFGgUAAJyBAAz+A5II/gcAAHQFdgf0AXYDdAV0BQAJnYEADP4Dkgj+B4AAVAVMAj4PTAJMBVQEAACggQAM/gO2CP4HAABUCqIKvgpABVQFAgI+AKiBAAj+B5IA/g9AALQGvgR0BQAATAwiAwABs4EACP4HkgD+DwAAVA9WC/wLVAvWC1QPAAG9gQAM/gOiCP4HEAD4B5YItA+cD7QP0A/AAMCB8AAOAPoPugP6A74DgAP2C9ILPgdYAEAAwoFAADwA/A/cA9wD/AOwA7wL9gu8BzQAEADJgQAM/gOiCP4HAADwB7gF9wBVDKQC6AwAAMqBAAz+A5II/gfgAN4G+gH6B+oH1gHwAgAE04EADP4Dkgj+D+QH/g90B/QFHgD8BJwHWAzjgQAA/geSBJIEkgSSBJ4HkgSSBPIEAgQAAOWBAAD8B6QEpAS8B+QEAAyAA3wAgAEABgAI6IEAAPwPlAScB5QEcAuYBKYHVA/UBPQPBADqgQAAAAD8DyQJJAknCSQJJAkkCfwPAAAAAO2BAAAACXwFXAVcA14BXAFcA1wFfAUACQAE84EECKQItAisCKQIpA+kCKQIlAikCAQIAAD0gQAAvASkBJQHlAS0AiAIfgSIA+gCGAQICPqBhAn8DdwP3A3cDd4P3A/cD9wP/A2ECQAA/IEAAPwPRARCBEIEAAREBEQERAREBPwPAAAAggAA1A9UBUQFRAUUBCQFAgViBXoFyg8AAAWCAAAcBfwF/AX6A/AB/AH8BfwF/AX8AwAABoIAAAAJ/AVSBQAFXgF0AVQFAAXUBTwJAAAHggAAAAn8BVQFAAU+AXQBAAVUBdQFPAkAAAiCAAAACfwFBAX8BSwBXAEkAfwFQAX8CQAJCYIAAMAAfAJaAsAC7gfcAsgCXAL8AsAAAAAKggAAJAD0B/QH9gfwBvAG9gf0B/QHlAcAAAyCAAAKAMoPSgRKBH4ESgRJBEkEyQcIAAAADYIQAFAAUAdYBVQF8gVUBVQFWAVQB1AAEAAOghAAUABID0QJUgl6CVIJVAlYCUgPUAAQABKCEABID0QF8wVEBQgHYABqCPIPLgDiAAAAFIIAAJIP/gSSBNAP1AE0CJwPFAA0AlQAUAMXghAASA9WBXwFWAcQAMAPqAL+D6gC6g8AABiCEABYD1QF8gVEDwwA9A9WBVQFdAUcDwAAHIIACbAIUgVWAtIBFgDSA1IC2Q9VAlACAAAeghgJWAn+BtQC/AHUAPwD1AK8B9QCkAIAAB+CQAhABvwBRABMAU4BVQJECEQI/A9AAEAAKoJADPwDRwBVCfwHAADoDygALgDoDwgEAAAsgkAM/ANOAEUN/AMACN4IQgVCBs4FUAgAADCCAABADPgD1Aj4DwAAfg4CAfoHAgj+CAAGMYJADPwD1gBECPwHEADoBycIJQnoCDAGAAA1gkAM/APWAEUI/AcAAOgHigiMCEgIWAgABjaCQAjAB3wAVgn8BwAA+A+IBI4EiAT4DwAAN4JADPwDVwFFDPwDAAhoBFgHzgRoBCgHCAg5gkAM/ANEAFcJ/AcAALgPhgSABI4EsAcgAEeCQAz4A14BSgj4D7QH7AQACCQK/AsiCgACWIJADPwDzwhFCPwHAAC+CKAH/wSgBrwFgAhmgkAP/gBbB/4BAAT/B9UE9wfcBI8HpASkB2+CAAAACPwHVARUBNYEVAFUAlQFfAWACAAAcIIUBCQCxAF8BgAA/g9SCNIIUgFSBn4FAAlygiAAEAD4B5QIlgiUCPQInAiQCPAJAAQAAHOCAAAoASgB/g8oAQgA+AeWCPQInAjwCAAGeoIAAAQAJAQuCiQJpAikCGQILghECAQGAAB+ggQIBAgkBM4EBAMEAgQDzgQkBAQIBAgAAIKCBAAkACQALgDkDyQAJAAkAi4C5AEEAAAAi4KEAJQAlACWCJQIlAj0B5YAlACUAIQAAACNgoQARAA0ALYAJAEkAiQIJAguCCQM5AMAAJKCBABEAMQHTgREBFQEZAREBE4ERAREBAQAl4IECAQJRApmCdQFVAdEAg4DxABEAAQAAACZgoQIpAikBK4EpAL0AaQBpAKuBKQEpAiECJyCggiSCJIIlwSSApIB8geSCJcIkgiSBIIAnYIECEQERAJeBEQMdApECkQJ3ghECEQIBAilgkQARAgkBK4DJAAUABQAJACuDyQARABEAKaCAAgEBvQBVgFUAVQBVAFWAUwBzAMEAAAArIKEAEQIxAiuBKQDhACECKQILgdEAIQABACtggAABAD0B5YIlAjwCJQIlAiWCJQI9AgEBq6CAgDiDyIALwIiAbIAcACiAC8LIgjiDwIAr4IIBIgDCACcBwgIKAhICIgIHAaIAAgHCACxggAABAGEAOQPDgAEAeQHjghECEQIJAgABrOCJAgkBCQGLgHkALQIpAikCK4IpAckACQAt4IACAQIxA8OCAQIBAjwD4QIjgiECAQIAAC4goQApAikCK4PpAykDKQMpAyuDKQGpAiECLmCBAgEBPQDlgCUAJQAkACUD5YAjACMAAAAvYIECJQE1ASWApQClAmUCZQI9geUAJQAhADHggQAFAFUAVYB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5APWD/AL6AvwC9QL9gvkDyQAIAC/hAQAFACUD/YA9Af0BfQF9Af2AJQIlAcEAMSEkACUALQH1gfUB9QH9Af0B9YH1AbUAJAAyYQAADQCFAFWD5QJVAlUCVQJlglUD1QDAAHLhAQARAjUDtYK1A70CtAO1ArWCtQMRAlEANaEAAAEAPQO9gr0CrwAvAa0CpYK9AoECAAE3YQEAAQIZA8OCWQPBAk8Dx4J1AmUDwQIAADmhEABRAX8BP4G/Ab8BvwG/gv8CvwGRAAAAOyEFAhUBMQHDgjkC9QLtAu0C7YLtAs0CkQA7oQACLQE8gMDBPoJWAtaC/4LXwtaC/oLAAIRhQQAdAzUA9YB9ArUCNQJ9gbUBtQI9AiABBOFAAjEC3wLfgv8D3wHfAf+B3wLfAvECQAIF4UEDPQDFAhWBNQBVA1UAVQF1glUAFQOBAAahQQP9ABUDNYB1A/wAQQEpAEmCPQPJAAAACGFJAmkCJQF3gG0CZQJhA/2AdQFtAwUCQAAI4UECXQHRAHuDwQAVAWQBXQJVgk0DxQBAAErhQQIVARUANYB1An0BfQB9gH0A/QF1AMAACyFBASUB/QHlgQEAFQPdABWD1YAdAd0CIQENYXEDzQA9A92BXQHdAXUDX4ElAf0CDQIAAY6hQQAxAcUAMYD1APUA9QD1gdUBhQE9AMAADyFRABUBMQHBgB0AfQH9Ab2BfQG9A70BwAAPYUUANQPxAfuD8QD1A+ECO4EJAPkBSQIAABDhUACSgJKD+sLSgt4D0oLRgvnC1YPQgEAAkmFJAgkBvQAdgF0DXAB9AF0DXYBdAEUDQAASoUEBnQABAauCEQFVABUA0QGLgiECTQIBANphUQIVAwEAo4AhAX0BfAD9AX2A/QJhAcEAG2FAAAkCHQHdgdwD/AHdAJ2D3QHdAckDwQAcoUEAOQB9AHmB/wB7AEEDP4DTADMD0QAAAB0hUIKYgnSCkcFIg0CCPoPqw+qD6oJ+g8CCH6FAABkACwP7gssC3gPLAvsC64LLA9kAAAAhIUkBEwHRAAWAfQB9AP0Af4F9Af0AfQBAAGHhQABNAGEDwYAtA6wALQOhADeCCwH5AUgCJuFAAD0D1QFVgV0BwQAlALeApQP1AKUAoAApoUEDvQBtAi2A/QLtAO0C/QDtge0C/QHBACphQAA+g86AMMN6gMoCKoKrgq/D6oKqgogCKqFBARUAVwJ3gd0AQQM9ANeAFQA1A9UAEAArIWEAJQIRAUGBfQDtA+0AfQDBgVEBZQIlACvhQACdAPUA9YP9A/UD9AP9A/WD1QPdAEAALCFAgiKDf4F2wHeBf4B3gX+Bd8B/gWKBQAAyYW0BLQC9A+2AZQCBADUD/4K3Ar0CtQPAADNhQAA9AT0B/YF9AfwBQQHXAVeBVQHVAQAAM+FAAl0B0QB9A/2A7QG9AYeD/wEFAfUCBAE0IUUBlQGVAPOCiQHBAD0CVQHXgFUD/QJAATVhYoEqgL6D6sDqgECDvoB+wOqA6oJ+g8AAN2FBANcB1wH/gv8C5gLQAc2BxQHdAqEAkQA5IUEDPQDVAn2DwQBdAX0AH4PZAL0BWQJAADlhQAItAXkBQYF9AGwD7QB1AN+A2wFBAUAAOmFIgRqAwIBNwCyD/IKsgqzD6oK6g+iAAAA+4UCACoMSgMLBeIDvgN2D5cPdgO+BeIFAgUHhiQM5AF8Df4BdA3kBAACVAH2D0wBTAYEAAuGRABkC0QI7gVkAnAI9Av2CvQC9Ab0BwAIEYYCCPoHCgRrBWoPagsKC2oLawtqDyoBCgAthgAAAAD+D/8H/gLgB8AC/gP/BT4A/gcAADiGBAD0D/QGfga0BvQLJA7+AH4F/AN0ARQFToYAAAAM8AMQCFAHfgHUAbQHlAi0CLAEEABPhgAAAAz4AwgIKAk+B1wBXAVMCVwNWAMIAFCGAADADzgAiA+oCr4K3ArcCswK3ApICCgAUYYAAAAP8AAQBlAAfgbUCLQKtAiUArAGAABUhgAM+AMICCgJKAs+DWwFbAtMC1wJWAkIAFWGAAz4AwgLqAaoBj4JXAjcC9wI3AtYCggAWoYAAAAP8AAQClAIfg60CLQOlAi0CpAIUABbhgAAgA9wABALUAp+D1QItA6UCrQKMAgAAF6GAAAADPwDBAiUC38HtgO2A7YH5gcsCgAAX4YgAO4EqgSqAyYG8AEYDDgDXwBaB0oEGAJnhgAM+AMYAd4PvA+MCxgI8gCSCJIIkgcAAGuGAAAABPgEiASIBP4HiASIBIgG+AQACAAAcYYABPQFNAU0BfQHNAUsB+wHBAj8AwAMAAZ5hgAA+ASIBP4D+AIABAQEBAT8BwQEBAQABH2GAAAACNwLVAlUCfQHVAVUBVQF3AUACAAIfoYABPgJjgf+B/gGAAgEAPwPJABEAIQAAACAhiAAFAjKDwgEGALwCIgIiAT+B4gEiAX4B4GGAAj4CYgE/gf4DgAIeASCBQwD4AQcCAAIgoYAAPgE/gOOA/gHAAB0AUQBRAl8DMADAACKhgAA+An+B44H+AYACBgI6gwKB4gDeAQICIyGAAD4BIgE/gf4BgAEKAEoAf4PJAEkAQABk4YAAPgEjgf+B/gGAADyCJIIngcAAP4PAACVhogASgjqCVoJTgnqB0oFSgVaB+oHSgxICJyG+AWIBP4HiAT4BBICIgGiCWII/gciAAAAo4YAAPgJiAT+B/gGAAw8AAIOwAkOCHALIAykhiAEIgTSBVYFWgXSB1YFWgVWB9IFIAgAAKqGAAD4CYgE/gf4BgAMJADIAgAC/g8AAQABr4YAAPgJiAT+B4gE+A4ACPwPIgjiDyIIAADAhgAA+A3IBP4D+AoADMgIygj6D8gIyAgACMaGAAT4Bf4HiAT4BgAI/A8kCSQJ/A8ACAAAx4YAAPgE/geIBPAGCADoBwoJjAiICFgIAAbJhgAI+AX+B4gE+AoAAFgARAJTBkQJyAAQAMuGAAASBMoFSgVSBd4HVgVWBVYH1gUSCAAA1IYAAvgCzgP+A0gCMAP+D2IEkgRiBP4PAADZhgAA+Az+B/4H+AYACCQJJAm/DyQJJAkgCNuGAAj4Bf4HiAT4BgAAXgZIAf4PSAFIAgAE5IYAAPgESAT+A3gDIAC4D6YErASwBKAPAADuhgAEFATUBUQFXAXGB0QFXAVEBdQFFAgAAPmGAAj4Bf4HiAT4CgAA5A9kAvQPbALkDwAA/oYABHgE/gN4AwABlAj8B5AMfgKQBVYIAAYAh0AAXAD0BXQFfAX0B3QFfAX0DTQI/AcAAAKHAAj4Cf4Hjgf4ClAASAVuBdQPbAVEBUAECIcACPgF/geIBIgE8A5MCVQF1ANUBVwJQAkShwAA+AX/B/gGAgi+B0II8AsCCv4LIgoACBOH+AWIBP8HiATwBhoP5gUACCQK/gsiCiIKFYcAAPgEjgf+B4gE+AIwDM4DyA9OCHkIAAYXhwAA+AX8B4gEcAKMD1QAVAH0AVQI3A8AABiHAAR8Av8DxAd4DCsC/AEkA/4FAgL+BwAAHIcAABQEpAekBrQGtge0BqwGjAaUBxQIAAAhhwAA+ARIAv4DeAMABtQHXgVUBV4F1AcQADuHAAD4BYgE/gf4CgAA/A88Az4DPAv8BxAAR4cAAPgJ+ASOB/gGAAj8A7QC9Ae0CvwNAARJhwAA+AmOB/4HiAT4BnAAqgL4D6wC+gIAAEyHAAR4Av4DOAOAAP4PkAAkAAgB/g+AAAAATof4CYgE/geIBHgB4AdeBGoFagVqCP4HAABXhwAE+AWOB/4HiAfwCLwK1ArWD9QK/AqACFmHAAj4Bf4HiAR4AsAHvALUB1YB1AdUAdwHYIcAAPgJmAj+B/gKAAD0D1QK1A9UCvQPBABmhwAI+AT+B4gEcAL+D5ICDghgCWIH3ggACHSH+AmIBP4HiAR4AIAHfwKAD/4DEgj+BwAAdocACPgF/gf4BgAAfA1IA/wPaAN8BUgJAACChwAI+AX+B4gGcAT8B1YFPAL4DwQA/AMAAIOHAAj4Bf4HiATwDgQIVAbcAVYJVAlUBwAAjYcEAPwP7ATsAnwJgAd4AIgI/geIBPgGAAiehwAA+ATOA/4DSAIwAX4GqgL+AaoJggcAAJ+HAAT4Av4DyAJ2A34JWgVaBdoBWgV+BQ4JoocAAGIE6AfuBuQG4AfyBugG7gboB3QIAAi6hwAA+AmOB/4HiATwBR4J6g1+DyoBvgsACsCHAAj4Cf4H+AYACJQC9ALuDtQCBANUAgAAxocABPgCSAL+A0gCMAtkCHYH9AF2A3QNAATLhwAE+AX+B4gE+AQAAlwENAl8CTIAWgaQANGHAAj4Bf4H+AYACPQDdAN0A3YP9AMQAgAA8ocAAKALrAqsB6wHPgisA6wKvAesBqAHAAj5h4QEfAQ3Bb4FtgV4B8oHtgWyBboHNggAAPuHAAT8Av8DRAJ+ATsL2g9+A+oHKwdqCwAJDYgACPgF/gfwBnwPPAO8B+ADMAf+AAgDOAQViAAI+AX+B/gCAgA6D0oH3gFaD2oBag9AAB+IAAD4Cf4HiARwAiYPeAt0APoPUAR+AwAMIYgAANQF3AW+B78Ftwk/AJcFrQesBaQFAAAiiAAAqgWeBf4H/gX+Cf8A/gX+B54FqgcgCDuILAAXBN4FQAV2Bf8HfgVwBWQFvwc0CBIAQIgABPgHCAQIBPwHCgQIBPgHCAQIBPgHAARFiAAA+Af8B/oH+AMCABwBIAH+DyABLAEAAEaIAAggCbwEJAS8AKYPfAEkAiQFvAQgCAAATIiIAEgA5A8SAAAAJAAkACQIJAjkDyQAIABNiIgARADzDwgAIgwiAoQBIAgiCOIPIgAAAFOIQABEAPMPCQDIAf8HCADDBRAE8gcSAAAAVIgAAMwA8g8YAIYI9QeUBAAAJAjkDyQAAABXiEAARADyDxkCUALeA1QCVAYABPIHEgAAAFmIAADIAOQPAgBUD3wFdAdkACQAJAjkByAAW4gEAEIA+Q8IAPoD3wLaB/4CAgDyBxIAAABdiAAAJADyDwgAeglaCf4H+gUJBCAA5A8gAGGIAABEAPIPCAn4Ba4D/AOsDfgBAAjkDyAAYogAAIwA4A8cALwHnAeYB7wHvAQAAOQPIABjiIAAiABICMgPKAgaBDwEyACIA0gEKAgACGWIAAAIAYoA6g+YAEgBAAD+DyAAQADAAIAAaIggATQJtAS0B3QEPgT0BDQBtAK0BCAIAABpiAgBiADuD5wAQAkcCOQEFAOEAnQEDAgAAGuICAGIAO4PnABIAQAIiARIBEQCMgIQAQAAbIgIAYgA7g+cAEgBAADQABAJEAj+BxAAAABwiBQBFAV8BVwH3AReBNwEXAFcA3wFFAUQBHeIAAAEAnQCVA5UCfYIVAlUAlQGdAkECQAAgYgAAhAC9AK0DrQJvgS0AbQCtAZ0BRAJAAiEiAQBhQD3D44AZAEADCICogF+AKEDIQQgBIuIkAKIArwKgg6ICcgIjgmYAqoGygrKCqgIjYgAAYwA7A9YAQAA8AcsCSgJ6AsICvgJAASSiAgBiADqD5gAAAj8CSQJJAkkCSQJ/AkACJaICAGIAOoP2AAAAPgPiASIBP8HiASIBPgPnIgAAYoA6g/YAAAESAJIAf4PSAFIAkgEAACriAgBiADKD7gBAAz4A8gISAl+BkgGyAkYCK2IhAKkAqQKlA6MCaYIvAnWAtYG1AXEBbQIsYgAAYgA6g/wACAA/A8CABAH/gCQAxYMAAC0iAgBiADsD5gAAACoALgDrAKoCpgKqAagAMGIAAFUC9QHXgRUAVQDEAz+AhAD0gQUCAAGwojWAtYC3gquDp4JxgSAAZ4CwAbABf4JAAjFiKACrAKQCrwOgAmoBKgBvAKoBqgEqAgAAMaICAGIAO4PnABIAQAELAUgBT4FIAXsDwAAz4gABEQFfA18D3wJ/gl8A3wFfAV8C0QLAAjUiBQA1A90APQHbAVkBWYFzAbUAKQPJAAAANWICAGIAO4PWACIAAABxA+yCIgIsgjED4gB2IiABKwCrAqsDoQJ3gSEAaYCrgasBKQIAADZiAABiADrD9gAgAIqAeoHvgSqBKoEvgcIANyICAEIAc4PuAAAAOgPqAKoAv4PqAKqCuoH3YiQAr4CmAqYDr4JgASoBKgBvgKoBqgEiAjhiAgBiADsD9gAAAB8CVQJVAn8D1QJfAkAAOSIAAGKAOoP2AAADPwDRAC2ApQPlAKUAgAA84gAApwEhQK2DrQJ9gS0AbQCtgaFBJwIAAD4iAgBigDqD9AAgAT8BNQC1A/8D9QB/AKABPmIgAJEAnwBfAf8BP4EfAF8AnwCfAXEBAAA/YgIAr4CnAq+BpwF/ASAAZwCwAbABb4JAAQCiQAAxAD1D2wAAASUBN8HlAQAAP8HIABAAAeJgABIAO4HeAAABT4F/gW8ArwCvAW8BAQEEIkIAYkAyg+4AAABvgeqBKoFqgaqCL4HAAASiSACFAL0AgQOZAl8CT4JfAI8BnwFJAkABCWJAAGIAMwP+AAADvwBdARcATwJ3A8cAQAAKokAAIgB7A/YACAI7AcACPwLVAhUCXwKAAgyiQABlADUB7AAAAT4A+gD7AP4B+gD6AMIAkSJQAXEBfwD7A/8CcYJ/APsBewF/AlECQAAX4kAAIgA7g/cAQAJTAVeAVAPTAFeBVQJEAByiQAFDAV8A34PfAt8CQAJfgP8BfwL4AtACX+JBAD0D5QE1AQ8BBQEFAR8BJQElAT0DwQAgYkAAIIIugiqC/4GqgSqBL4GqgWqBLoIgACGiUQBXAG8D1wA3AjsC/wH/Af8B/wLPAgACIeJAgBeB9YH1g/eB1YHFgz+A7YCtgr+BwIAi4kACAAI/AlUBVQDVAFUAVQHVAn8CQAIAASPiUgISAT8A0gBSAoACPwFVANUD1QJ/AkABJOJAAgMCPwL5AbkBuwC5ALkBuIK+gsCCAAElokIAYgAzg+4AAgJAAj8BVQDVA9UCfwJAASaiQAIOAgKCOwL6AbqAuwC6A7sCwoIOAgABKeJAAg8CPwL/Af8B/wDwAPsB+gL6AsoCAAEqokAAKQErALmD6wCoAj8BVQDVAFUD/wJAASziQAAMAHsB7gH6AeoB/wNVANUAVQH/AkABLqJAAAwCB4I3gvQB9oD2gPYD94LHggwCAAEvYkACD4I7gv+B+4H7gPAA/YH/Av8CzQI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AAAAAPwProsgACQI7A8ABAQCeAiCBQwCgAV4CAQIAAiviyAAJAjkBwgCQAJEAPwPRAAEAPwHAAgABrCLIAAiCOQPCAQAAMQHRAhECEQIRAj8CAAGsosgACII5AcAAogIiAT+A4gAiAD+D4gAgACziyAAJADoDwAEiAKoAKgA/g+oAKgEiAMAALaLEAASBvQBBAWADDoCIgGiCGII/gciACIAuIsgACIA7A8ABLAAjgCIAPgPiACIAIgAAAC5iyAAIgjkBwgCYAD4DwYAgAD+ByAIGAgIBrqLIAAiCOQPCAIgAJAHCAmGCIgIkAggBiAAvIsgACII5AcIBGAAGA6GBWAEBgUYB2AIAAC9iwAAJAjkBwgCAAz8AyQGxAEkAvwHAAgABL6LIAAiCOQHCAIgCqAIXgVCAkIGfgXgCCAIv4sgACIE7AcEAgAICAb4AUoISghICMgHCADAiyAAIgTkBwgCQAlIBEgD/gDIA3gEQAgAAMGLIAAiCOwHCAIACOQPBAgECPwPRAhECAQIxIsAACII7AcEBIACugCCAP4PggCyAIoAAADFiyAAJAjoDwgEAAD8DyQJJAkkCfwPAAgAAMaLIAAiBOwHCAIACHwGRAFEAEQARAF8DgAIyIsgACII7AcIAmACEAAOAPgPKAEoASgBKAHJiyAAIgjkDwgEAAD8DyQAJAHkDyICIgIAAMqLIAAiCOQHCAQAAlAISAkGBcgEUAIQAQAAzYsgACII5AcABgIA6gMqASoB6gkCCP4HAADPiyAAIgTsBwQCIACiD5oEhgSiBKIEngcAANGLIAAkCOgHAAIkAqQCrAKUD7QCrAIkAgAA1YsAACII4gcCBAgASATIBwgC/gAIBwoMCALXiyAAJAjoBwgCoACoAqgCvAioCOgHqACgANqLAAAiDOwDAA74AygAKALICX4EiAfqCAgG3YsAACQI6AcIAiAApA+kCPwIpAikCKIPIADeiwAAIgjsBwAAsg0uA8IE8AkCCv4LIgoCCuGLAAAiAOwPAAD4DxYA1AdUCFwK0AkQCAAE4osgACQI7AcABBAAyAOuAqgK6AsICPgHAADliyAAIgjsDwAEJAG0CKwEZwQkBhQFhAgAAOaLIAAiCOQHAAIIAEoBSgH4D0gBTgEIAQAA54sgACQI6AcAAhgACAEoAe4HqAiICJgEAADriwAAIgjkDwAA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gAT/BJgEmA8YAL+MAAQQBPwF9APsA/AB9AHsA+QD1AUMBAAAwIwAABQIzAvmCvQK7ALgAv4K8gryCx4IAAjDjBAACADcA8QL4AvqA+oD/gvqC+kDKgAAAMSMAAj8DVQFVAH8BUAA+A+sAqgCqAroBwAAx4wQCBII9Av0BuQG9AL2AuwG9Ab0CxQIAADKjAAI/A1UAVQF/AFIAOgJSAR+AogFbAgIBtOMIAAsCOwH/AbsAv4C7AL8AvwG/AcMCAAI24wAABwIzAXuBewF7AHgAfwF7gX8BRwIIADcjAAI/A1UAVQF/AUAAb4C6gmqBKoDvgiAB96MAAAcCMYP9g30DfYF9AX0DfYNxQ8cCAAA4IwACPwFVAVUAfwFIAC0B6QEpgSkBLQHJADijAAIPgj6B/4H+gf6A+AD4gfaB5oHJgggAOOMAAQ6CO4H7gf+B+8D7gP+B+4H7gc+CAIA5IwACPwFVAVUAfwDqAjsBBgH2ga8CbgJEATmjAAI/A1UAfwFAAjUDxQI0AeQBP4DEAwUBuqMIAAcCMwL7Ab6BvgC7gLqBuoG2gsKCAgA7YwABPwHVAFUA/wFAAGkB/4FpAW8BaYHIAD0jAAEeAJYAfwPWAE4AMAL7ArkAvQG7AcACPqMAAD8DVQB/AIICGwF+A9oAfgPbgPoBUAI/IwACPwNVAFUA/wGwA/sAv4C7Av+CuwHIAL9jAAArAh8BPwH/AP+A/wD/AP8B7QEpAQAAAiNAAj8BVQB/AUAAPwP5wrkCvwK5ArnD3wACo0AACgI/g9eDVwFXAV8BV4FXgXsDxwICAgPjQAMggO2CjoHugm7A7oFOgC6B7oPCgQAAB2NAAAACPwJBAQEBAQC9AEEBAQE/AkACAAAHo0ACAAI8AsQCBAEHgLUARQEFAT0BQQIAAAfjSAIEAj4CRQIFgQUAtQBHAQQBPAJAAgAACGNAAAUCNQLVAhUBlwBVARUBFQI1AsUCAAAIo0ACP4JAgT6AwIA/g4AAAgDiAhoCP8HCAAjjRAAFAjcC1wIXARcA14AXARcBNwFFAgAACSNAAAeCMAFQAReAkABZgRaBFoI1gsSACAAJY0ACP4IAgb6Af4MAABwCI4EiAN4BAgIAAAmjQAEfwf5AAEC/wIACP8HIAToACYDIQQAACeNAAAICMQLXghBBkQBTwRUBFQI0gsKCAAAKI0AAPAHDADsCSwELAK8ASoEKgTqBQgIAAApjQAAfA/0AAQC/AAADvwBNAzUAhQD8gQECCqNCAAICNQLVAhSBFoDUgB0BFQE1AUECAgAK40IACgI7AtqCFoESANoAGoEXATEBQgICAAsjQAI/g3yAwIC/gAADCQCIgYqCeIIIQgACC2NAAj8DeQDBAD8DhAAzAEKAcgJCAj4BwAALo0AAPwJBAT0AwQA/A4QAAgEDgQIBAgEOAQvjQAACAj8C2oIagZ+AWoEagRqCP4LCAgAADCNAAAoCLgJuAS4ArgIuAsICP4BCAYOCAgEMY0ACPwIBAb0AfwCAAhQBP4EUAdUCVAJAAQ0jQAI/A30AwQA/AYAAIAP/gSIBIgEiA8AADWNAAAgCPwLdAh0BHQDfgB0BHQE/AUgCAAAN40QAAgI3AtCCEgESANOAFgEagjiCxQAAAA4jQAAAAjcC1IIWwRAA1IATgRiBOIFHggAADmNAAhACN4LdghfBFYDVgBfBFYE1gUWCAAAOo0AABQI1AtOCGQGXAFABFwEVAjUCxwAAAA8jQAE/AL0AQQE/AAABugBCAh+BIgH6ggIBj6NAgg6COoFagR+BGoDagB+AmoE6gU6CAIAP40AAPwN9AMEAPwFwAD4D64CqAKoCugPCABBjQgABAjfBUAEagNqAGoCfgJqBOkFKggAAEKNAAj8BuQBBAT8BAAAyA/WBKQE1ARMD0AAQ40AAPwN5AP8DAAM+AMICEoI6g9ICEgIAABEjRAIEgjUBUAEaAJmA1YATAJUBNQFDAgAAEqNAAD8DeQDBAD8DgAAUANoCOYPaABIBxAES40AAPwN5AP8AAAI1A8UCNQHEAD+AxAMFgZMjQAA/A/0AQQE/AWAANQPfgVUBVgF1A8QAE6NAAj+BfIDAgD+BQAApAlUB/4BFAU0CQAAT40AABwIhgu0CLQEtgK0ALQEtgSFBRwIAABQjQAI/AkEBPQDBAD8DgAAvgDqC6oGqgm+B1SNAAj8B+QBBAT8BQAAqA+kBKYEtASkByAAVo0ACPQElAL+D5QB9AoACPgH1gMcCPQLAAhYjSAELgSeBV4EXgJeA0gAbAJeBJwFJAQkAFqNAAj8DeQD/AAACFoF/A9YAfgPXgX4CUAAW40AAKwIvAj8BbwEvgK8ALwE/AW0BCQJAABejSAALgicC04IfARAA24AXAROBJwFLAgoAGCNAAB+BAID+gACAn4AmAd/BXwFfwX8BwAAYY0AAPwN9AP8DAAA+AcOAOwPzAvIC9APAABijQAM4gO+Cv4H3gw/A/4M3gc+Af4PBgQAAGSNIAKkAaQIJAbkAT4IJAjkDyQApAAgAwACZo2ACSQE5AM+COQHJACACTQEygKIA3gECAhrjYAJJATkAz4I5AekAIAH5AE+COQHJACAA3CNIAgoBKgDKAQoBPwPKAkoCSgJKAkgCAAAdI0QBtQBFAL+A1QEVARQBAAE/gUIBBAEIAR1jRAG1AEUAf4DVARUBAAFzAQwBEwEggUABHaNIAykAyQE/gekCKQIAAgkCPwLJAgkCAAAd40QCNQHFAL+B5QIlAgACOQJJAokCjwKgAmBjRAG1AEUAf4DVARQBAQFUgUiBaQEiAQIBIWNAAjYBxgE/AeYCBAI1AtMCmQKZArcCwAIio0gDKgD/AeoCAAI+AmICAgKfgnICioKAAiLjSAGqAEoAv4DiAQgBBgFVgVUBVwF9AUABJWNIAaoASgC/AOoBQAFXATcBNwF3ATcBAAEmY0gDKgDKAL8B6gIAAj0CzAIvAiQCvQJAAifjQAIpAckAv8HpAgECPQLkAheCZAI9gsACKONFAAUBJ4D9AMQBP4EqgT+BQAE5AUcBQAEqI0QDNQDFAL+B5QIpAjvC14JSgluCN4LAACzjQAAAAg8BKQDJAQkCOQPJAkkCTwJAAgAALSNAAjeBxIE8geeAAAO/AEAAAQA/AAABwAIvo0ACN4HEgTyB54AAAj4DwAI/g9ACEAIAADDjQAI3gfyB5IEngQAACQMIgP+ACIDIgQgCMuNAAieDxII8geeDAAICAf/AEgLSgbKCUgAzI0ABN4HEgTyA14CAAhOBEgD/gBIA0gESAjRjQAE3gcSBPIHngQAAPoHtAj0CgQK/AkABNuNAASeDxIE8geeAAAM+APICX8GSAXYCAgI3Y0ABNwHFAT0A5wCAAD8DxQFFAUUBfQFAATfjQAI3gcSBPIHngAACPwPVAjUAVQGfAUACeGNAASeB/IHkgQOAuAM+AMOCPgHCADoAQAA6I0ABJ4H8gfyB44EIAC4A6gKrAq4CqgGqADqjQAAHgfyB5IEPgz4BxYA1AdUCFwK0AkQBO+NAAjeBxIE8geeBJAAiA/WCKQIvAjED4AA840ACN4H8geeBAAA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dAV0BfwPIASTjwAAfAJGAvQPIAD4D7QC8g+UARgI8AcAAJWPRAB0Ak4C5A9AAhAC9A60Cb4JtAJ0BRAJlo8AAHwBRgH0B0ABFAC0B7QF9gW0BZQHgACZjwAAdAJOAuQPFADuB7QK5A90BIoDeAQACJuPIAAkASwBPAEkAecPJAE0ASQBJAEgAAAAnI8AAEIFXgVWBdYFVgV3D1YF1gVeBQIFAACejwQAkg+SBP4EkgcQAEQBdAHGD3QBRAFAAJ+PAAT8A6QPpAS8BwAAWAFIAc4PaAFIAUAAo48AAEQJVAnHB3QBBAjwBJQC/g+UAvQEAAimjxAIzAfoAUAIEAf+AOAPCABaAcYPaAEAAKiPRABVCcYHdAEACHAG/gEAAFQBxw90AUAAqY9EAFUJxgd0AUAADgjkBwAAVAHHD3QBQACrjwgAWgnsB0ABHATyBIgEAARVAccPdAEAAK2PBADMD1IBegfWANYPAABUAccPdAFEAQAAr48IAFoJ7AdIAUgPawVoBwwAXQHvD0wBAACwjwAAAAz8A0QA1A9UCFQE1AFUAlQFVAlACLGPAACAAn4CIgbqBqoCKgpqCqoG6gJiAwACso8ADPwDbAnsCf4H7AnsBf4H7AXsBfwLQAm5jwAIIgTsAwgEAAgIC8gIPggICggK+AkABLqPQghGBMgHAAQECMQLPAgECgQKBAr8CQAIu49ICFIE1gMEBBAIEAgQCP8LEAgQCBAIAAi8j0IIQgTMBwAIAAqCCWIIPgjACAAJAAoAAL2PAAgkBOgDAAQECAQKBAr0CxQIDAgECAAAvo8gCCIE7AMABAgICAvICD4ISAiICAgLAAjBjyAIJgToAwAEJAgkCCQI/AsiCCIIIggABMKPAAgkBOgDCAQgCCQKJAr8CSQIJAgkCAAAxI8gCCQE6AMABDAECAmsCmgKKAooCggJAADFjyQIJAToBwAEJAgkCPQLJAgECPwJAAqACcePIAgiBOwDAAQICCgIyAgICggK/gkICAgIyI8kCCQE6AcACAQLxAg8CBQIFAoUCvQJBATOjwAIRgzIAwAE/AkECQAI/AsECAQJ/AgAANCPIAgkBOgHAAgQCtQJNAkUCVQJlAkUCgAI0Y9CCEIExAcACAAL/ggSCBII8gsSCBIIAADUjwAIQgTMBwAIAAv+CDIK0goSCdIKMgoCCtiPAAgiBOwDCASACEQIJAj8CwQIJAjECIAI2Y8ACCQE6AcACCgKKAnKCEwIuAgICQgKAADbjyAIIgTsAwAESAhIC/4ISAhICP4LSAhICNyPIAgkBOgHAAgQChQJ9AgUCPQLFAqQCQAA3Y8ABCIE7AMABFQEVARUBP4FVARUBMQFAADejwAIIgTsBwAEFAksCSYJ9AskCSQJBAkAAN+PIAgkBOgDAAQACfwIJAhkCOQIJAk8CgAI5o8ACE4EwAcEBfwEBgj8CwAI/AsECvwLAAjqjwAIJAToBwAI+AtICkgK/gtICkgK+AsAAOuPRAhEBMgHAAQACPgLSApOCkgKSAr4CwAI8I9CCEIEzAcABIgJaAgICP4LCAhqCIoJAAj0j5AI1AS0AwAE/AkECvQKlAr0CgQK/AsAAPePQghGBMgHAAgkC6gIYAj+C2AIqAgkCwAK+Y8ACCQE6AMIBGAICAv6CAwK+AsICOgIAAD9j0IIQgTEAwAE/AlUClYKVQpUClwKwAsACACQQAhCBMwHBAgACv4LKgpqCKoJXgpACgAAAZBCCEIEzAcABEgITgpICfgISglKCkgKAAgCkCAIJgToBwAEFAjUC1QKfApSClIK0gsQCAOQAAhECMgHAAScCEAK/gkACP4JQAqcCoAKBpAACE4MwAMIBOoIjgqICvgJiAiOCOoICAgJkAAIJAjoBwAIIAqsCWgIPgjoCygKKAogCQqQAAgiBOwHAAQiCPoLRggwCv4LAAg4CMAADZAAAJII9AaUBQAI9gsQCF4JEAmUCvILAAgPkAAIJAjoBwAELAgsC9wIXAicCqoKqgkgCBCQAAgiBOwDAAQSBaoIrgpSCuIJUgiKCAAEEpAgBCIE7AMABHQFVwXUBPwFVgRVBdwEAAQUkAAITgTABxAESAlUCFQK8glUCEgJUAkQCBeQAAgkDMgDEAQECHQK1ApUCtQL9AoECgAIGZAAAFQEfALYAwAE+AV4BXwFeAX4BQgEAAQakCAIIgTkAwAE+gmuCK4I+guuCK4K+gkAABuQAAgkBOgHQAguC/QIAAokCvwLJAokCgAAHZAACCYI6AcACEgK/gkICPwLEgjyCxIIAAAekAAA0gi8BpgFAAi8CrQK9Au0CrwKAAoAAB+QQghCBMwHAAh0ClQJ1Aj+C9QIVAl0CgQKIJAACCQI6AcABCAIrAuoCrwKqAqoCyAIAAAikAAIJgTgBwQIlAqSCq8K6guuCqoKCAoQCCOQAggmBOQDAAR8CVwJXAn+C1wJXAl8CQQJLpAACE4IwAcQCJQKVApUCP4LVAl8ChAKAAgxkAAIQgzMAwAE/gkCCOoJegnqCQIK/gkACDKQAAhGCMgHAAQQCP4LqAr8C6oKqAoICgAIOJBCCEQExAcQCHgKVgnWCHQI3AtQCnAKAAE7kCAIJAToAwAEnAhUCnwKVAlcCdQIHAgAADyQJAgoBOgHgAt8BWwN7A9sDWwN/A8ACAAAPpAACCIM4gMIBOgF/Aj8CwsI6ggEDOgPCABCkAAIRgTIAwAEKAluCdgIqArICa4IqAgICUWQQAhEBNgDAAX8CBQI1AnUCdQL9AncCQAIR5AACCQE7AcACP4Lagj+CX4Jagt+DMAPAABKkAAIRgzAAwQF/AgXCuQJDAhGCvQLVAhECEuQAAgiDOQDAAR6CXoJegn6C3oJegl6CQABTZAACCIE7AMABfwI1Au0CPYLtAj0C7wI4AtOkAAIQgjMBwAI4As+COIJegnqCT4I4AsAAE+QAAQiAuwDgALcBTwFvAW8BTwFPAf8BwACU5AgCCQE6AcABAgI+gu+CrgKvgr6CwgIAABUkAAIRgTIAwAE1An0CdQJ3gvUCfQJ1AkQCFWQAAhECMgHAAj8CtwL3AreCtwL/AqICgAIV5AACCIE7AMABO4IagpqCX8IagrqCi4IIARZkJAI9gaQBQAIuA6kDrwO9g+sDqwOpA6ACFyQAADRDLYCEAVCBPoJBgpcCPYLQgjBCgAAXpCQCPMEFAOABH4IAgvyCD4Kfgh1CXUKMAFgkAIIQgjCBwgEfAlcCdwI3gtcCfwJiAoACGOQAghCDMQDEAT8CfwK/Ar+CvwK/AqQCwAIZZAACCQM6AMABEwJfApkCuwLZApiCmoLQABokIAI1ggwBwQG9Al+DVQNRAsQCI4LeAoICmmQAAhGDMgDAAT0CTQI/Al2CfwJNAr0CQAIbZAACBEE9gMABP4Jvgq/Cr4Kvwr+Cx4IAARukAAEJgLoA4ACfAQUBXQEVgZUBXQEFAUAAHKQkAjUBLQHAAb8CQwItAqMCtwLjAq8CgAKdZAACCYI6AcABHwJbgtsCWwJfA3+D3wJBAF3kIAI1AS0AwAF/AjsC/wM7A78D+wMfAkACXiQAQgmBOQDgASuCu4K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SgJABAAAyJEAAJYBUgD+B1UAAAb/ASEA4QAhAz8MAATKkQAAKgOiAP4PowCqAKACrgKSD6oCpgIiAsuRBACsAfwPogCoAD4C+gK+AroHvgL6Ai4CzJEAAAAEvgSqBKoEqgT+B6oEqgS+BAAEAADNkQAAEAT0BfQF9AX8B/QF9AXyBfIFEAQAAM6RAAB8CVQJ/AdUBXwBAAgkCPQPLADkAAAAz5EAACAE/Af8B/wH/Af8B/wH/Af8ByAEIADRkRAAsAiQCZgLlgjxD5IIlAiYCpAIMAgAAN2RUAhYC1QI8gdUBEQFAAAgAP4PIAAgAAAA45FQCFgLVAjyB1QERAUQAM4ICAkIDPgDAADnkUAIWAtUCPIHVAYADP4DAAD8BwAA/g8AABWSUAhYCfYHVARUAQAIRAj8D0QIxA98CEAAHpJQCFgLVAjyB1QEWAUGASUJJAkEBfwDAAA0klAIWAtUCPIHVAUQBEgA1w9SAEwE0AcQAESSUAlcCPIHVAREARAETgRIA/4ASANIBEgIcZJQCFwJ8gdUBAAN+AMIAAgH7gQIBIgHAAh0kkAIXglAC2AJXgnQD1YJZA00CVQJRAgAAICSUAhYC1QI8gdUBwAA/g9KCMoBSgZ+CQAIg5JQCFwJ8gdSBAQNZAQ0AywAJgC0DzQIRAaFklAIXAnyB1IEhAT+DwIA6gMqAcII/gcAAJiSWARUBfIHUgREBRACGAGUD+YEnASEDwAArZJQCFwF8gdUBFQBAAioBP4FqAaqCaoIAAazklAIXAX2B0AFEAD8BJIGkAGSD/QIGAgQBLeSQAhQCVwE8gdEBggN9gcQAF4BEAn2BwAA0pIAAFAIXAXyB1QFAABIBa8Fkg+uBaIFQATqklALWAT2B0gEWAUIAOgPqAL+D6gC6g8AAO2SUAlYBVQE8gdUBAABegzMA0gAzA96CAAG/JIAAFALXAjyB1QH/AsMBKQD5AMMC/wHAAAEk1AIWAn2B1QERAUABNgCVgjUD3QATAVABSKTUAhYBfYHVARUAQAIKAmeBRgHWgcqC6gIJpMoBC4F+QMqBioHgAe+AOsPqgCqBL4DAAArk1AIWAlUBPIHRAcABL4E6gOqBqoJvgcAAC+TWAhUCfIHVAQEBSQA/gdkBWQFfgXkBwAAMpNQCFgJ9gdUBAAFogQqAOoPqgEqAr4CoAQ2k0gLXAjyB1QERAEUAFQP1Ah+CNQDVAVACUqTWAhUCfIHVAQEBfQEtAKUAf4PtAH0AgQES5NQCVgI9gdUBQQA4A8+ALIDqgI+CeAHAAB1k0gIXAnyB8QHMAwuA+AEqgb/C6oKvgoICH6TaAhsCWoE+QdqBwIM/giuCv4Prgr9CgAIjJNIBM4E+QdKBewFrQL+D6wA/A+vAvwEAACWk1AIWAhUCfIHVAQACfQLsAq+ArAC9gsACK6TQAhQC1wI8gfUBQAA/AvsCu4C7Ar8CwAK4ZNQCFgIVgnxB1IECg3qCG4HawFuD+oJCAQYlFAIXAXyB1QFAADyC3oLcwvzD3ILfgvyCzWUMAhaCvwHHAd0ALQHvgdUDP4FEAfWCAAGUZRQCFwJ8gcEB34Aqg/uCboPAAlOD0gJSA9wlAgIXAnyB0QFCADoD8QHkgL0D4QCaA8AAH2UUAhcBfIHVA0ACBgI3gXcA9wL3gusCygAiJSYAIYI9Q+UBIQEIAAgACAA/g8gACAAIACJlAAAmACGCPUPlASUBAAABAgECPwHBAAEAJOUAACYAIYI9A+UBKACHABKAIgJCAj4BwAAmZSYAIYA9Q+UBJQEAADyAIIA/giSCJIHAgCdlJgAhgj1D5QEAAToAQgBCAH+BwgJCAnoDZ6UmACGCPUPlASEDIAIOAgABP4DgAEIADAAn5SYAIYI9Q+UBAQE8AGQAJAA/g+QAJAA8AGglLgAhgjlD6QEBADwDxACkAF+AJAJ8A8AAKKUmACGAPUPlAQAAP4PAgIyAfoBAgj+BwAApZS4AIYI5Q+kBKQAAAz8AyQBJAkkCfwPAACmlAAAmACGCPQPlASEDDAIDgboAQgDOAQICKeUmACECPYHlASEAhAATgJICUgJCAz4AwAAqZSYAIYA9Q+UBAQEEAHuAQgJyAsICPgHAACulJgAhgj0D5QEhAwACEIO/glCCEIO/gkACLGUmACGCPUHlAQAAsgISAT+BEgHKgmqCQAEs5SAAKwI6geoBIACEAD8D5AEkASQBPwPEAC7lJgAhgT1B5QElAIEAIAPgAT+BJAEkA8AAL6UmACGCPUPlAQABP4BkgCSAP4PkgCSAP4BwZSYAIYI9Q+UBBQEwADODMgC/gFIAkgEQAjDlJgAhgj1D5QEhAQQAEgBVgJEDcgAEAAAAMWUmACGCPUHlASUAgAAvg+CBIIE/gTADwAA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AAT+AtAI3gfQAPYCAASblgAA/w8ZAO8AbAa3AK4EoAenALgCrgIiAJyWAAD+DwIAOgHGABAC9AL8AvYP/AL0AhACoJYAAP4PMgDOCQQEbAFkDWwJZAtyCeoBAAyjlgAA/g8yAM4AAAnuBZgDvwCYA+oPqAIAAKeWAAD+DzIAzAhABLYHgASqCfgMyAvOCCgJqJYAAP4PMgDMCOIHFATUC+wI7gl8DewPBAiqlgAA/g86AcYIUAS4AvQAEwj0BrgE6AwIALGWAAD+DwIB/gDADfYB8gf6C/IN+QH1DaAItpYQBFQFVAVUAlQK/gdUAVQCVAO8BJAEAAC7lhAIEAl4CXwJeAd4BXwFeAV4B3gJSAgACL6WAAAUBqQB5AAcAyAA/g+oBPoHqASoBAAAwJYAAFAAWADED+AK3grwCvAPxArECtgKEADBlgAG/gFCAPoHAgAiAPoHUgX6B1IFUgUAAMSWCAzoAx4IyAcIBCAD/AeqBKgE/AeqBKgExZYkBrwBZAj8ByQA8A+uBKgE/geqBKgEAADGlggICAV8BV4DXAPcD34BXQNcBVwFRAkAAceWAAAEDvwBrADsD+wK7ArsD+wK7Ar8CgQIzJYAAPAPAAT+BwAE/gcwAv4PqAT6B6gECATPlhAAuASmBLQE7A8gAPgPrgSoBPoHqAQIBNGWJAC0BI4ChA+8AkAEMAD+B0gF/AdKBUgF1ZaAD3wANAe0AjQJ/AcwAPwPqgT0B6gECATWlgAA7gSqBPoDrgLgBjAA/g+oBPoHqASoBNmWAAAICL8EvAS+BbwGiAK+ArwFvgW8BCQE3JYgAKQGlADGD7QCAAD+D6gEqgT6B6gEqATelgQIfAl8BaoDUg04AfwPqgSoBP4HqAQIBOKWgA/0ANQD1gLECPQHIAD+DygF/AcqBQAE45YAAPQJ1gX0A9YF9AUgAP4PqAT8B6oEqATolgQA9A8UAFQBFAD8DxQAVAFUChQI9A8EAOqWGADKCsoKygqKCr4KigrKCsoKyg8YAAAA75YACJgIygjqCcoGngTKBIoG2gnKCJgIAAjwlgAKGAmaBboFCgM+ARoJOgmKBxgBAAIAAPKWAAEMBWUFZQdFBV8FRQVlB2UHBQ0cCQAA85YcDMYDdgh2CX4HRgF2CXYJdglGCVwHAAD2loAAmACaAboFSgXeBcoFWg26C4oBmACAAPeWGADKD8oKygqKCr4PigrKCsoKyg8YAAAA+ZaAAJgA+gf6CuoK/grKCvoLegrKCRgEAAD7lgAAGADaB/oCygLeB9oK+grKCxgIAAYAAP6WAAFYC1wLXAvMBtwC3AJ8C0wLXAcAAAAAAJcAAFgAWg96AUoP3gFaD3oBSglYB0AAAAAElwAAHgAOCK4HhgHeBYYG1gLeCoYHHgAAAAaXAAhMCeYFdgsmCD4NRg32D3YNZg0MDQAAB5cYDNoDegn6B8oF3gXKB/oF+gXKB1gLAAkJlwAADAFmBeYG5gbGB94Gxg7mDuYHTAUAAAqXAAg4CYoLqgmKD74Jig+qD6oJCgs4CwAIDZcAAQwBpg+2C4YL3g+GC7YLpguMCAAAAAAOlxgCWgtKC2oLyg9uD0oPWgf6B0oLWgsYCBOXAAAOAA4I1guuCq4GBgKuBr4K5gsOCAAEFpcAAJgEigK6D4oCPgCKBroBug+KApgEAAQclwAAmAS6AroPugI+AL4H+gX6BfoFyAcAAB6XGADKD/oF+gXKBd4MCgj6C/oFygXYCwAIJ5cAAAAMTAPmD/YBRgMeCsYGdgPmC0wHAAEylxgIyg16CXoPygueAooOegv6CkoPWAIAADiXAABMB+YH9g/GB14DBgz2A/YC5grMBwAAOZcABuwBdQdtBW0FBQcvAuUCpQ+tAu0CoABClwAO7AFlBP0E/QZ1BOcHZQb9BvUG9QQgAEiXAAgMCeYL/gtGCa4PpgnmDU4LtgjkCAAAUpcQABQA/A+8ArwCvgK8ArwKvAr8BxQAEABWlwgC6AIOAugBAAD8D7wCvgK8CrwK/A8UAFmXEADcD9wC3grcDxAAWAlWCfQHXAHwAUAAXJcQCNwH3ALeCtwHAACIAqQK6geiAuoDgABelwABKAEoASgB/g8AAAAA/g8oASgBKAEAAWCXAAQIB3wHXgdcD1wAXgBcD1wHfAcIBwAEYZcADvwBBAQ0B3QHVA8GADQPdAc0B1QHAABilwAA8g8SBPIHXgVSBfIHEgQSBPIPAgAAAGmXAAAEAuQCvgK0AvQPtAK0Ar4C5AIEAgAAdJcEAu4C/A+uAuQCAAIwAP4PAAD+BxAICAZ2lwQA7gKsAvwPrgJAAP4HQgh+CEII/ggABouXAADkAq4C/A/uAgQKIAgkCb8PJAkkCQAAjZcEAO4CrAP+DuQCAABICcYJdAZEBegEQAiRlwQC7gL8D64CZAjgBwQIkAt+CNAIEAsAAJiXBAD+ArQC9A++AkAI9AcQAF4BEAn0BwAAoJcEAv4C9A+0Au4C/AaKA+gP6AGICvgHAACtlwQC7gL8D24A/g98CawH/ASsCPwIBAgAANOX/AKsAq4PrAb8BgAE7AeuBawPrAXsBQgE5pcAAJIAkgCSAJIA/w+SAJIAkgSSBIADAADnl6gAqAD8D6gAqAIAAXQMhAN8CAQI/AcAAOmXAAD0AtQC3g/UAvQCAACoAP4PqACoBIgD7ZcAAFAFUAVQBf4HAAQABP4HqASoBKgEAADzlxAAFADUB1QFVAVWBVQFVAVcBdQHFAAQAPWXIADoB2YFdAXkByAAEAEuBagICAj4BwAA9pcQANwHVgVcBdQHBACwB44EogSiBJ4HAAD7lxAA3AdVBVoF1AcEAPgPVANUA1QD/A8ACP+XlAC+ANUH4Af+B+4HzgfAB94HxgeaAAAAAZgACAQI/AusBqwGrAKsAqwGrAb8CwQIAAACmAQIBAj8DwQAAAj8C6wKrAKsBqwG/AsAAAWYBAEEAfwBBAEECPwHrAasAqwGrAb8CwAIBpgACPwHAAD4AwAA/g8AAPwHrAasAqwK/AsImEgIyAQkBBADBAj8C6wKrAKsAqwK/AsACBCYJAgkCPQPPADkCAAI/AusAqwCrAr8CwAAEZgAABQH9AAUAvQDAAj8B6wGrAKsAvwLAAgTmOgAiAD8D4gE6AIACPQHtAa8ArQK9AsAABeYAA74ASgMvAKoA1gI/AusCqwCrAb8BwAIGJgAAFgA1AdSAMQJDAT8B6wCrAKsBvwPAAAtmAAAfAhMBUwEfAcADPwJrAqsAqwG/AcACDuYEADeBRAEfwIUAZAA/g1WA1YDVgH+BQAEPJgAAHgGWAH8D1gBOAr8CawGrAKsBvwHAAhGmAAEvASsAvwPrAKcCPgJrAqsAqwG/AcACEyYQAxcA1wE3AdcCQAM/A1cCVwJXAn8DQAMTZggAawPtAVWBaQHDAD8B6wGrAKsCvwLAABPmAAM7AM8CK4JLAUkAvwLrAqsAqwG/AcACFSYAAzkAywIpgosBSQA/AusCqwCrAr8CwAIWJgAD/wAfAasAKwP/AEACPwHrAasAvwLAAhbmAQK/AvcCt4C/AsAAPwHrAasAqwG/AsAAF6YAACsBJgC3gGcAogI/AusBqwCrAL8BwAIZ5gADvoBKg+qB9oHgAcCCPoLrgaqAvoHAgxvmAAB/A3aARoJ+gO8AwAJ/AesBqwC/AsACHWYAAAECPQLFAgUBBQC3AEUBBQI9AsECAAAdpgAAAQIBAj8BwQAAAj6CQoE7gMKCPoJAAB3mAAAAAD8AxACEAEACPQFFATcAxQE9AkECHmYBAEEAfwBhAAACPoFCgQKA+4ACgIKBPoFepgADPwDAAD4AwAA/g8AAPwIDAbsAQwC/Ax7mAAESAQmApABAgj6BAoC7gEKAAoC+gQCCH2YAAASBvIBEgDyBwAC+ggKBu4BCgD6DgAAfpj8DwIA+gcKBPoCAAj6BAoG7gEKAPoOAAB/mAAA9ACEAP8PhARgAvoICgbuAQoA+g4ACIGYMAwMAuIJIAjvBxAA+gkKBO4DCgj6CQAAgpgwBAwD4gIAAt4HAAD6DAoC7gEKAPoNAASEmCIAKgjqBzYA4gAACPoECgbuAQoA+g4AAIWYAAjwB5AAngD0AQAI/AkMBOwDDAj8CQAIhpgQAFABTAJqDdAAAAj0BBQG3AEUAPQOAAiHmAAO/AEkDD4D5AYMAPAEFAbcARQA9A4ACIiYAACiCJIIige2BAAM+gkKBO4DCgj6CwAAiphIBFgESAP+AHgDSAjgBBQC3AEUAvQEAACRmCAAuAsgCPwFKAMgCPQJFATcAxQE9AkAAJOYAAAsCKwHvACqBwAE8ggSBt4BEgTyCQAAlpgABM8C1AHUD7IBAAryCBoG1gESBPIFAAiXmAAE/ATUAvwP1AH8AOAJFATcAxQI9AkAAJiYQAxcA1wE3AdcCQAM9AwUC9wIFAr0DAQMnJgACPIHGgGzBKoCEgj6BAoC7gEKAPoOAACdmKwAFAZeBXQFlA4cAPQJFAbcARQA9A0ABKCYBAr8C+wK7gL8CwAA9AkUBNwDFAj0CwAApJgACPwL/Av+C8wLPAPwCAoE7gMKCPoJAAComAAAAA78AQQE7AUsBfwHLAXEDPwHAAgABLGYAA7+AUIE+gNCAv4AAAPYBFYJUAncDQAAxJgEAPQN/AH8B6QP/gdmBPYD+gP6BwQIAATGmEAGygFqAGcG6wFiDP8DYQT9A2EH/wEABs6YAAAADv4BAgQaAqIB4gAaBwIA/gcACAAG0pgoBMoEDgLsAwAK/AcEAvQBBAL8BwAMAADYmHQN1AH8CdQH/APUASQN/AMUBuQB/AcADNuYUAhSBvoBQgBCAPoPQgBCAM4DFAUqCUgF3pgAAAQABAAEAAQABAAEAPwAIAdQCIgIiAbfmAAAEAAQCPgPtAiyCbQCtAb4CZAIEAgAAO+YCATkB9IE0gT0BgAO/gFiDKIFIgPiBAAI8pgIBPQHsgSyBPQGIAAcDIoD+AAIAzgECAj8mBAE/AeyBLIE9AYAAOwDLAHsCQQI/AcAAP2YCAAIBPwHugS6AvQGAAD4A5YE9AQEBPwE/pgQBPwHsgS6BPIGNAToASYA/A8kAOQDAAAFmQQA8g9aCVoF8gkAAIoM+gOIAP8PiQAAAAqZgACUAFwI/g/cCdwJ3AfcBf4NXAiUCAAAEJkQAJAAqAjuD9wLgAO2B9YHlgWuCKIAAAATmQQI8gdxBnUDIQSJBP8DWAAfAvgD2wYQABiZCAjsD1oJVgX0DQQAlAKUCPMHlACEAogEKJkQBPgHtASyBOwGHAD0D5QFlgWUBfwHAABSmQAA8A++BLIE9A5AAGoNegNvASoP+g0oBWWZMAAMCOoPCAQ4AAAO/AEEAAQA/A8ACAAGbZkwAAwIygcYAAAO/AE0DNQCFAPyBBIIAABumXAADAjqDwgEOAIACDAEDgPoAAgDKAQYCHCZIAAUAMoPGAIAAOgDJwAkAPwPJAAkAuQBcZlgABQAyg8YBEAA8AcsCSgJ6AsICvgJAARymTAADAjKBxgCCADiAyoBKgHqCQII/gcAAHWZcAAMCOoPCAQwAAQE/AeUBJQElAL8DwQCdpkgABQIygcYAggIoASuA7gApA/UCJQIAAR6mTAACgjlBwQCCApgCBQEhQOGAwQEdAhABHyZIAAUCMoPCAS4AoEI+geIAIgA/A+LAIAAf5kgABAAzg8YBIAClAj8DxAE/gKQBVYIAAaAmSAAHADKDwgEGACQBpgAlAjyD5QAmAKQBIGZIAAUCMoHGAIACFQJxAVsAkQDwgRaCEAAhZkgABQEygcIAjgA0A9IBQYFRARcBcQPAACGmSAAFATKBxACBAD8B/QHVQVWBWQFDAcAAIuZMAAMCMoHGAKQALgCbgQ8BWwJrAq4AIAAjZkgABQEygcYAwAIdAV2BXQD9AF2A3QFAAiPmTAAjg8oBBgEQAA+D7AK5A+cCoQKvA8AAJKZEAAcAOoHCAFgBN4F/gbeAv4G3gX+BAAAlpkAAAQA9A9XBVQFXAVUBVQFVwX0DwQAAACZmZAAVABUD7QKlAq8CpQKsgrSCtIPUACQAKiZAAC8ArwC/g78D/QP+A72DvIP/g7YAgACrJkACAAM/AFUAVQFVAH8DVQBVAtUCQAHAACzmQAG/gCqB/4CqgoAB/wHEAj+CRAI+AgABsGZAAb+AKoC/gmqC6oHAADWDAgDDgXRBBAIxZkABv4AqgP+C6oOgA3+AyIA4gAiAz4MAADGmQAG/gCqBv4CqgsAB/4PAgSiBXIEigUABdCZAA7+AKoG/g6qCaoHAACKCPoPjAiICAAI0pkABv4Aqgf+AoIKEAfMASoB6AkICPgHAADVmQAAFAjMBeYB5AXsAeAD/gHyA/IFHgMAANuZAAN/ANUDfwNVBcEDHAwkA/8CJAQ8BAAI3ZkABv4Aqgf+A6oPAAAYAPgHjgiICFgIQAb/mQAG/gCqBP4Bqg8AADwHigS4Bq4JIAgAAA6aAAb+AKoD/guKByAApAe0Aq4LNAjUByAAEpoABv4Aqgf+A4oPQACiCWYJ+g9aCeYNIAgTmgAG/gCqA/4GqgoKB+gIJgXyAyQH6AkICBmaAAb+A6oB/gmAD/wH7APsB+oDagX6BwAAMJoADP4Dkgj+B0QA9gXcC9YL3Af2C1QGQAA3mgAO/gCqAv4LqgcAAPQJagnSD2oP5g8gCEWaAAb+BqoB/gmCBwAA/AdUCuwLnAnECwAAVZoABn4H/gKqCQIHqA/6A94F2gf5AKkPAABXmgAG/geqAf4NggNwCLgG9gBUDLgC0AwAAFqaEAg6DP4D+gP6C9oDyAvsA9YLrAssBiQAX5oADv4Aqgf+DgAHfga6AP4PbAAUAywEAABsmgAAAAIEAnQCRAJEAkQCRAp8CEAHwAAAAG6aAAJ6AkIJQgj+BwAAEAyQA34AkAEQBhAIb5oAAnoCQglyCM4HAAD+DwAA/gcAAP4PAABwmgACegJCCkII/gcAAPwHEAj+CQgI+AgABnGaAAB6AkIKQgn+B/gPBAgUC+QIlAkECgAAc5oAAnQCRAlECPwHAABUDIgCiANUBBIIAAB0mgAAegJCCkII/gcAAPgPSABKAEgA+AAAAHaaAAJ0AkQIRAz8AzAISAVIAv4FSAR4CAAAeZoAAnoKQgl6CMYHEADOAykB6AkICPgHAAB7mgAA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\"\n    }\n}\n","frame.ts":"namespace control.__screen {\n    let __update: () => void\n    let __updated = false;\n\n    export function update() {\n        if (__update)\n            __update()\n        __updated = true\n    }\n\n    export function setupUpdate(update: () => void) {\n        __updated = true;\n        __update = update;\n        update()\n    }\n\n    // low frequency fallback screen refresh\n    control.runInParallel(() => {\n        while (true) {\n            __updated = false\n            pause(200)\n            if (!__updated) {\n                __screen.update();\n                __updated = true\n            }\n        }\n    })\n}\n","image.cpp":"#include \"pxt.h\"\n\n#if IMAGE_BITS == 1\n// OK\n#elif IMAGE_BITS == 4\n// OK\n#else\n#error \"Invalid IMAGE_BITS\"\n#endif\n\n#define XX(v) (int)(((int16_t)(v)))\n#define YY(v) (int)(((int16_t)(((int32_t)(v)) >> 16)))\n\nnamespace pxt {\n\nPXT_VTABLE(RefImage, ValType::Object)\n\nvoid RefImage::destroy(RefImage *t) {}\n\nvoid RefImage::print(RefImage *t) {\n    DMESG(\"RefImage %p size=%d x %d\", t, t->width(), t->height());\n}\n\nint RefImage::wordHeight() {\n    if (bpp() == 1)\n        oops(20);\n    return ((height() * 4 + 31) >> 5);\n}\n\nvoid RefImage::makeWritable() {\n    ++revision;\n    if (buffer->isReadOnly()) {\n        buffer = mkBuffer(data(), length());\n    }\n}\n\nuint8_t RefImage::fillMask(color c) {\n    return this->bpp() == 1 ? (c & 1) * 0xff : 0x11 * (c & 0xf);\n}\n\nbool RefImage::inRange(int x, int y) {\n    return 0 <= x && x < width() && 0 <= y && y < height();\n}\n\nvoid RefImage::clamp(int *x, int *y) {\n    *x = min(max(*x, 0), width() - 1);\n    *y = min(max(*y, 0), height() - 1);\n}\n\nRefImage::RefImage(BoxedBuffer *buf) : PXT_VTABLE_INIT(RefImage), buffer(buf) {\n    revision = 0;\n    if (!buf)\n        oops(21);\n}\n\nstatic inline int byteSize(int w, int h, int bpp) {\n    if (bpp == 1)\n        return sizeof(ImageHeader) + ((h + 7) >> 3) * w;\n    else\n        return sizeof(ImageHeader) + (((h * 4 + 31) / 32) * 4) * w;\n}\n\nImage_ allocImage(const uint8_t *data, uint32_t sz) {\n    auto buf = mkBuffer(data, sz);\n    registerGCObj(buf);\n    Image_ r = NEW_GC(RefImage, buf);\n    unregisterGCObj(buf);\n    return r;\n}\n\nImage_ mkImage(int width, int height, int bpp) {\n    if (width < 0 || height < 0 || width > 2000 || height > 2000)\n        return NULL;\n    if (bpp != 1 && bpp != 4)\n        return NULL;\n    uint32_t sz = byteSize(width, height, bpp);\n    Image_ r = allocImage(NULL, sz);\n    auto hd = r->header();\n    hd->magic = IMAGE_HEADER_MAGIC;\n    hd->bpp = bpp;\n    hd->width = width;\n    hd->height = height;\n    hd->padding = 0;\n    MEMDBG(\"mkImage: %d X %d => %p\", width, height, r);\n    return r;\n}\n\nbool isValidImage(Buffer buf) {\n    if (!buf || buf->length < 9)\n        return false;\n\n    auto hd = (ImageHeader *)(buf->data);\n    if (hd->magic != IMAGE_HEADER_MAGIC || (hd->bpp != 1 && hd->bpp != 4))\n        return false;\n\n    int sz = byteSize(hd->width, hd->height, hd->bpp);\n    if (sz != (int)buf->length)\n        return false;\n\n    return true;\n}\n\nbool isLegacyImage(Buffer buf) {\n    if (!buf || buf->length < 5)\n        return false;\n\n    if (buf->data[0] != 0xe1 && buf->data[0] != 0xe4)\n        return false;\n\n    int sz = byteSize(buf->data[1], buf->data[2], buf->data[0] & 0xf) - 4;\n    if (sz != (int)buf->length)\n        return false;\n\n    return true;\n}\n\n} // namespace pxt\n\nnamespace ImageMethods {\n\n/**\n * Get the width of the image\n */\n//% property\nint width(Image_ img) {\n    return img->width();\n}\n\n/**\n * Get the height of the image\n */\n//% property\nint height(Image_ img) {\n    return img->height();\n}\n\n/**\n * True if the image is monochromatic (black and white)\n */\n//% property\nbool isMono(Image_ img) {\n    return img->bpp() == 1;\n}\n\n//% property\nbool isStatic(Image_ img) {\n    return img->buffer->isReadOnly();\n}\n\n//% property\nbool revision(Image_ img) {\n    return img->revision;\n}\n\n/**\n * Sets all pixels in the current image from the other image, which has to be of the same size and\n * bpp.\n */\n//%\nvoid copyFrom(Image_ img, Image_ from) {\n    if (img->width() != from->width() || img->height() != from->height() ||\n        img->bpp() != from->bpp())\n        return;\n    img->makeWritable();\n    memcpy(img->pix(), from->pix(), from->pixLength());\n}\n\nstatic void setCore(Image_ img, int x, int y, int c) {\n    auto ptr = img->pix(x, y);\n    if (img->bpp() == 4) {\n        if (y & 1)\n            *ptr = (*ptr & 0x0f) | (c << 4);\n        else\n            *ptr = (*ptr & 0xf0) | (c & 0xf);\n    } else if (img->bpp() == 1) {\n        uint8_t mask = 0x01 << (y & 7);\n        if (c)\n            *ptr |= mask;\n        else\n            *ptr &= ~mask;\n    }\n}\n\nstatic int getCore(Image_ img, int x, int y) {\n    auto ptr = img->pix(x, y);\n    if (img->bpp() == 4) {\n        if (y & 1)\n            return *ptr >> 4;\n        else\n            return *ptr & 0x0f;\n    } else if (img->bpp() == 1) {\n        uint8_t mask = 0x01 << (y & 7);\n        return (*ptr & mask) ? 1 : 0;\n    }\n    return 0;\n}\n\n/**\n * Set pixel color\n */\n//%\nvoid setPixel(Image_ img, int x, int y, int c) {\n    if (!img->inRange(x, y))\n        return;\n    img->makeWritable();\n    setCore(img, x, y, c);\n}\n\n/**\n * Get a pixel color\n */\n//%\nint getPixel(Image_ img, int x, int y) {\n    if (!img->inRange(x, y))\n        return 0;\n    return getCore(img, x, y);\n}\n\nvoid fillRect(Image_ img, int x, int y, int w, int h, int c);\n\n/**\n * Fill entire image with a given color\n */\n//%\nvoid fill(Image_ img, int c) {\n    if (c && img->hasPadding()) {\n        fillRect(img, 0, 0, img->width(), img->height(), c);\n        return;\n    }\n    img->makeWritable();\n    memset(img->pix(), img->fillMask(c), img->pixLength());\n}\n\n/**\n * Copy row(s) of pixel from image to buffer (8 bit per pixel).\n */\n//%\nvoid getRows(Image_ img, int x, Buffer dst) {\n    if (img->bpp() != 4)\n        return;\n\n    int w = img->width();\n    int h = img->height();\n    if (x >= w || x < 0)\n        return;\n\n    uint8_t *sp = img->pix(x, 0);\n    uint8_t *dp = dst->data;\n    int n = min(dst->length, (w - x) * h) >> 1;\n\n    while (n--) {\n        *dp++ = *sp & 0xf;\n        *dp++ = *sp >> 4;\n        sp++;\n    }\n}\n\n/**\n * Copy row(s) of pixel from buffer to image.\n */\n//%\nvoid setRows(Image_ img, int x, Buffer src) {\n    if (img->bpp() != 4)\n        return;\n\n    int w = img->width();\n    int h = img->height();\n    if (x >= w || x < 0)\n        return;\n\n    img->makeWritable();\n\n    uint8_t *dp = img->pix(x, 0);\n    uint8_t *sp = src->data;\n    int n = min(src->length, (w - x) * h) >> 1;\n\n    while (n--) {\n        *dp++ = (sp[0] & 0xf) | (sp[1] << 4);\n        sp += 2;\n    }\n}\n\nvoid fillRect(Image_ img, int x, int y, int w, int h, int c) {\n    if (w == 0 || h == 0 || x >= img->width() || y >= img->height())\n        return;\n\n    int x2 = x + w - 1;\n    int y2 = y + h - 1;\n\n    if (x2 < 0 || y2 < 0)\n        return;\n\n    img->clamp(&x2, &y2);\n    img->clamp(&x, &y);\n    w = x2 - x + 1;\n    h = y2 - y + 1;\n\n    if (!img->hasPadding() && x == 0 && y == 0 && w == img->width() && h == img->height()) {\n        fill(img, c);\n        return;\n    }\n\n    img->makeWritable();\n\n    auto bh = img->byteHeight();\n    uint8_t f = img->fillMask(c);\n\n    uint8_t *p = img->pix(x, y);\n    while (w-- > 0) {\n        if (img->bpp() == 1) {\n            auto ptr = p;\n            unsigned mask = 0x01 << (y & 7);\n\n            for (int i = 0; i < h; ++i) {\n                if (mask == 0x100) {\n                    if (h - i >= 8) {\n                        *++ptr = f;\n                        i += 7;\n                        continue;\n                    } else {\n                        mask = 0x01;\n                        ++ptr;\n                    }\n                }\n                if (c)\n                    *ptr |= mask;\n                else\n                    *ptr &= ~mask;\n                mask <<= 1;\n            }\n\n        } else if (img->bpp() == 4) {\n            auto ptr = p;\n            unsigned mask = 0x0f;\n            if (y & 1)\n                mask <<= 4;\n\n            for (int i = 0; i < h; ++i) {\n                if (mask == 0xf00) {\n                    if (h - i >= 2) {\n                        *++ptr = f;\n                        i++;\n                        continue;\n                    } else {\n                        mask = 0x0f;\n                        ptr++;\n                    }\n                }\n                *ptr = (*ptr & ~mask) | (f & mask);\n                mask <<= 4;\n            }\n        }\n        p += bh;\n    }\n}\n\n//%\nvoid _fillRect(Image_ img, int xy, int wh, int c) {\n    fillRect(img, XX(xy), YY(xy), XX(wh), YY(wh), c);\n}\n\nvoid mapRect(Image_ img, int x, int y, int w, int h, Buffer map) {\n    if (w == 0 || h == 0 || x >= img->width() || y >= img->height())\n        return;\n\n    if (img->bpp() != 4 || map->length < 16)\n        return;\n\n    int x2 = x + w - 1;\n    int y2 = y + h - 1;\n\n    if (x2 < 0 || y2 < 0)\n        return;\n\n    img->clamp(&x2, &y2);\n    img->clamp(&x, &y);\n    w = x2 - x + 1;\n    h = y2 - y + 1;\n\n    img->makeWritable();\n\n    auto bh = img->byteHeight();\n    auto m = map->data;\n    uint8_t *p = img->pix(x, y);\n    while (w-- > 0) {\n        auto ptr = p;\n        unsigned shift = y & 1;\n        for (int i = 0; i < h; i++) {\n            if (shift) {\n                *ptr = (m[*ptr >> 4] << 4) | (*ptr & 0x0f);\n                ptr++;\n                shift = 0;\n            } else {\n                *ptr = (m[*ptr & 0xf] & 0xf) | (*ptr & 0xf0);\n                shift = 1;\n            }\n        }\n        p += bh;\n    }\n}\n\n//%\nvoid _mapRect(Image_ img, int xy, int wh, Buffer c) {\n    mapRect(img, XX(xy), YY(xy), XX(wh), YY(wh), c);\n}\n\n//% argsNullable\nbool equals(Image_ img, Image_ other) {\n    if (!other) {\n        return false;\n    }\n    auto len = img->length();\n    if (len != other->length()) {\n        return false;\n    }\n    return 0 == memcmp(img->data(), other->data(), len);\n}\n\n/**\n * Return a copy of the current image\n */\n//%\nImage_ clone(Image_ img) {\n    auto r = allocImage(img->data(), img->length());\n    MEMDBG(\"mkImageClone: %d X %d => %p\", img->width(), img->height(), r);\n    return r;\n}\n\n/**\n * Flips (mirrors) pixels horizontally in the current image\n */\n//%\nvoid flipX(Image_ img) {\n    img->makeWritable();\n\n    int bh = img->byteHeight();\n    auto a = img->pix();\n    auto b = img->pix(img->width() - 1, 0);\n\n    uint8_t tmp[bh];\n\n    while (a < b) {\n        memcpy(tmp, a, bh);\n        memcpy(a, b, bh);\n        memcpy(b, tmp, bh);\n        a += bh;\n        b -= bh;\n    }\n}\n\n/**\n * Flips (mirrors) pixels vertically in the current image\n */\n//%\nvoid flipY(Image_ img) {\n    img->makeWritable();\n\n    // this is quite slow - for small 16x16 sprite it will take in the order of 1ms\n    // something faster requires quite a bit of bit tweaking, especially for mono images\n    for (int i = 0; i < img->width(); ++i) {\n        int a = 0;\n        int b = img->height() - 1;\n        while (a < b) {\n            int tmp = getCore(img, i, a);\n            setCore(img, i, a, getCore(img, i, b));\n            setCore(img, i, b, tmp);\n            a++;\n            b--;\n        }\n    }\n}\n\n/**\n * Returns a transposed image (with X/Y swapped)\n */\n//%\nImage_ transposed(Image_ img) {\n    Image_ r = mkImage(img->height(), img->width(), img->bpp());\n\n    // this is quite slow\n    for (int i = 0; i < img->width(); ++i) {\n        for (int j = 0; j < img->height(); ++j) {\n            setCore(r, j, i, getCore(img, i, j));\n        }\n    }\n\n    return r;\n}\n\nvoid drawImage(Image_ img, Image_ from, int x, int y);\n\n/**\n * Every pixel in image is moved by (dx,dy)\n */\n//%\nvoid scroll(Image_ img, int dx, int dy) {\n    img->makeWritable();\n    auto bh = img->byteHeight();\n    auto w = img->width();\n    if (dy != 0) {\n        // TODO one day we may want a more memory-efficient implementation\n        auto img2 = clone(img);\n        fill(img, 0);\n        drawImage(img, img2, dx, dy);\n    } else if (dx < 0) {\n        dx = -dx;\n        if (dx < w)\n            memmove(img->pix(), img->pix(dx, 0), (w - dx) * bh);\n        else\n            dx = w;\n        memset(img->pix(w - dx, 0), 0, dx * bh);\n    } else if (dx > 0) {\n        if (dx < w)\n            memmove(img->pix(dx, 0), img->pix(), (w - dx) * bh);\n        else\n            dx = w;\n        memset(img->pix(), 0, dx * bh);\n    }\n}\n\nconst uint8_t bitdouble[] = {0x00, 0x03, 0x0c, 0x0f, 0x30, 0x33, 0x3c, 0x3f,\n                             0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, 0xff};\nconst uint8_t nibdouble[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,\n                             0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};\n\n/**\n * Stretches the image horizontally by 100%\n */\n//%\nImage_ doubledX(Image_ img) {\n    if (img->width() > 126)\n        return NULL;\n\n    Image_ r = mkImage(img->width() * 2, img->height(), img->bpp());\n    auto src = img->pix();\n    auto dst = r->pix();\n    auto w = img->width();\n    auto bh = img->byteHeight();\n\n    for (int i = 0; i < w; ++i) {\n        memcpy(dst, src, bh);\n        dst += bh;\n        memcpy(dst, src, bh);\n        dst += bh;\n\n        src += bh;\n    }\n\n    return r;\n}\n\n/**\n * Stretches the image vertically by 100%\n */\n//%\nImage_ doubledY(Image_ img) {\n    if (img->height() > 126)\n        return NULL;\n\n    Image_ r = mkImage(img->width(), img->height() * 2, img->bpp());\n    auto src0 = img->pix();\n    auto dst = r->pix();\n\n    auto w = img->width();\n    auto sbh = img->byteHeight();\n    auto bh = r->byteHeight();\n    auto dbl = img->bpp() == 1 ? bitdouble : nibdouble;\n\n    for (int i = 0; i < w; ++i) {\n        auto src = src0 + i * sbh;\n        for (int j = 0; j < bh; j += 2) {\n            *dst++ = dbl[*src & 0xf];\n            if (j != bh - 1)\n                *dst++ = dbl[*src >> 4];\n            src++;\n        }\n    }\n\n    return r;\n}\n\n/**\n * Replaces one color in an image with another\n */\n//%\nvoid replace(Image_ img, int from, int to) {\n    if (img->bpp() != 4)\n        return;\n    to &= 0xf;\n    if (from == to)\n        return;\n\n    img->makeWritable();\n\n    // avoid bleeding 'to' color into the overflow areas of the picture\n    if (from == 0 && img->hasPadding()) {\n        for (int i = 0; i < img->height(); ++i)\n            for (int j = 0; j < img->width(); ++j)\n                if (getCore(img, j, i) == from)\n                    setCore(img, j, i, to);\n        return;\n    }\n\n    auto ptr = img->pix();\n    auto len = img->pixLength();\n    while (len--) {\n        auto b = *ptr;\n        if ((b & 0xf) == from)\n            b = (b & 0xf0) | to;\n        if ((b >> 4) == from)\n            b = (to << 4) | (b & 0xf);\n        *ptr++ = b;\n    }\n}\n\n/**\n * Stretches the image in both directions by 100%\n */\n//%\nImage_ doubled(Image_ img) {\n    Image_ tmp = doubledX(img);\n    registerGCObj(tmp);\n    Image_ r = doubledY(tmp);\n    unregisterGCObj(tmp);\n    return r;\n}\n\nbool drawImageCore(Image_ img, Image_ from, int x, int y, int color) {\n    auto w = from->width();\n    auto h = from->height();\n    auto sh = img->height();\n    auto sw = img->width();\n\n    if (x + w <= 0)\n        return false;\n    if (x >= sw)\n        return false;\n    if (y + h <= 0)\n        return false;\n    if (y >= sh)\n        return false;\n\n    auto len = y < 0 ? min(sh, h + y) : min(sh - y, h);\n    auto tbp = img->bpp();\n    auto fbp = from->bpp();\n    auto y0 = y;\n\n    if (color == -2 && x == 0 && y == 0 && tbp == fbp && w == sw && h == sh) {\n        copyFrom(img, from);\n        return false;\n    }\n\n    // DMESG(\"drawIMG(%d,%d) at (%d,%d) w=%d bh=%d len=%d\",\n    //    w,h,x, y, img->width(), img->byteHeight(), len );\n\n    auto fromH = from->byteHeight();\n    auto imgH = img->byteHeight();\n    auto fromBase = from->pix();\n    auto imgBase = img->pix(0, y);\n\n#define LOOPHD                                                                                     \\\n    for (int xx = 0; xx < w; ++xx, ++x)                                                            \\\n        if (0 <= x && x < sw)\n\n    if (tbp == 4 && fbp == 4) {\n        auto wordH = fromH >> 2;\n        LOOPHD {\n            y = y0;\n\n            auto fdata = (uint32_t *)fromBase + wordH * xx;\n            auto tdata = imgBase + imgH * x;\n\n            // DMESG(\"%d,%d xx=%d/%d - %p (%p) -- %d\",x,y,xx,w,tdata,img->pix(),\n            //    (uint8_t*)fdata - from->pix());\n\n            auto cnt = wordH;\n            auto bot = min(sh, y + h);\n\n#define COLS(s) ((v >> (s)) & 0xf)\n#define COL(s) COLS(s)\n\n#define STEPA(s)                                                                                   \\\n    if (COL(s) && 0 <= y && y < bot)                                                               \\\n        SETLOW(s);                                                                                 \\\n    y++;\n#define STEPB(s)                                                                                   \\\n    if (COL(s) && 0 <= y && y < bot)                                                               \\\n        SETHIGH(s);                                                                                \\\n    y++;                                                                                           \\\n    tdata++;\n#define STEPAQ(s)                                                                                  \\\n    if (COL(s))                                                                                    \\\n        SETLOW(s);\n#define STEPBQ(s)                                                                                  \\\n    if (COL(s))                                                                                    \\\n        SETHIGH(s);                                                                                \\\n    tdata++;\n\n// perf: expanded version 5% faster\n#define ORDER(A, B)                                                                                \\\n    A(0);                                                                                          \\\n    B(4);                                                                                          \\\n    A(8);                                                                                          \\\n    B(12);                                                                                         \\\n    A(16);                                                                                         \\\n    B(20);                                                                                         \\\n    A(24);                                                                                         \\\n    B(28)\n//#define ORDER(A,B) for (int k = 0; k < 32; k += 8) { A(k); B(4+k); }\n#define LOOP(A, B, xbot)                                                                           \\\n    while (cnt--) {                                                                                \\\n        auto v = *fdata++;                                                                         \\\n        if (0 <= y && y <= xbot - 8) {                                                             \\\n            ORDER(A##Q, B##Q);                                                                     \\\n            y += 8;                                                                                \\\n        } else {                                                                                   \\\n            ORDER(A, B);                                                                           \\\n        }                                                                                          \\\n    }\n#define LOOPS(xbot)                                                                                \\\n    if (y & 1)                                                                                     \\\n        LOOP(STEPB, STEPA, xbot)                                                                   \\\n    else                                                                                           \\\n        LOOP(STEPA, STEPB, xbot)\n\n            if (color >= 0) {\n#define SETHIGH(s) *tdata = (*tdata & 0x0f) | ((COLS(s)) << 4)\n#define SETLOW(s) *tdata = (*tdata & 0xf0) | COLS(s)\n                LOOPS(sh)\n            } else if (color == -2) {\n#undef COL\n#define COL(s) 1\n                LOOPS(bot)\n            } else {\n#undef COL\n#define COL(s) COLS(s)\n#undef SETHIGH\n#define SETHIGH(s)                                                                                 \\\n    if (*tdata & 0xf0)                                                                             \\\n    return true\n#undef SETLOW\n#define SETLOW(s)                                                                                  \\\n    if (*tdata & 0x0f)                                                                             \\\n    return true\n                LOOPS(sh)\n            }\n        }\n    } else if (tbp == 1 && fbp == 1) {\n        auto left = img->pix() - imgBase;\n        auto right = img->pix(0, img->height() - 1) - imgBase;\n        LOOPHD {\n            y = y0;\n\n            auto data = fromBase + fromH * xx;\n            auto off = imgBase + imgH * x;\n            auto off0 = off + left;\n            auto off1 = off + right;\n\n            int shift = (y & 7);\n\n            int y1 = y + h + (y & 7);\n            int prev = 0;\n\n            while (y < y1 - 8) {\n                int curr = *data++ << shift;\n                if (off0 <= off && off <= off1) {\n                    uint8_t v = (curr >> 0) | (prev >> 8);\n\n                    if (color == -1) {\n                        if (*off & v)\n                            return true;\n                    } else {\n                        *off |= v;\n                    }\n                }\n                off++;\n                prev = curr;\n                y += 8;\n            }\n\n            int left = y1 - y;\n            if (left > 0) {\n                int curr = *data << shift;\n                if (off0 <= off && off <= off1) {\n                    uint8_t v = ((curr >> 0) | (prev >> 8)) & (0xff >> (8 - left));\n                    if (color == -1) {\n                        if (*off & v)\n                            return true;\n                    } else {\n                        *off |= v;\n                    }\n                }\n            }\n        }\n    } else if (tbp == 4 && fbp == 1) {\n        if (y < 0) {\n            fromBase = from->pix(0, -y);\n            imgBase = img->pix();\n        }\n        // icon mode\n        LOOPHD {\n            auto fdata = fromBase + fromH * xx;\n            auto tdata = imgBase + imgH * x;\n\n            unsigned mask = 0x01;\n            auto v = *fdata++;\n            int off = (y & 1) ? 1 : 0;\n            if (y < 0) {\n                mask <<= -y & 7;\n                off = 0;\n            }\n            for (int i = off; i < len + off; ++i) {\n                if (mask == 0x100) {\n                    mask = 0x01;\n                    v = *fdata++;\n                }\n                if (v & mask) {\n                    if (i & 1)\n                        *tdata = (*tdata & 0x0f) | (color << 4);\n                    else\n                        *tdata = (*tdata & 0xf0) | color;\n                }\n                mask <<= 1;\n                if (i & 1)\n                    tdata++;\n            }\n        }\n    }\n\n    return false;\n}\n\n/**\n * Draw given image on the current image\n */\n//%\nvoid drawImage(Image_ img, Image_ from, int x, int y) {\n    img->makeWritable();\n    if (img->bpp() == 4 && from->bpp() == 4) {\n        drawImageCore(img, from, x, y, -2);\n    } else {\n        fillRect(img, x, y, from->width(), from->height(), 0);\n        drawImageCore(img, from, x, y, 0);\n    }\n}\n\n/**\n * Draw given image with transparent background on the current image\n */\n//%\nvoid drawTransparentImage(Image_ img, Image_ from, int x, int y) {\n    img->makeWritable();\n    drawImageCore(img, from, x, y, 0);\n}\n\n/**\n * Check if the current image \"collides\" with another\n */\n//%\nbool overlapsWith(Image_ img, Image_ other, int x, int y) {\n    return drawImageCore(img, other, x, y, -1);\n}\n\n// Image_ format (legacy)\n//  byte 0: magic 0xe4 - 4 bit color; 0xe1 is monochromatic\n//  byte 1: width in pixels\n//  byte 2: height in pixels\n//  byte 3: padding (should be zero)\n//  byte 4...N: data 4 bits per pixels, high order nibble printed first, lines aligned to 32 bit\n//  words byte 4...N: data 1 bit per pixels, high order bit printed first, lines aligned to byte\n\nImage_ convertAndWrap(Buffer buf) {\n    if (isValidImage(buf))\n        return NEW_GC(RefImage, buf);\n\n    // What follows in this function is mostly dead code, except if people construct image buffers\n    // by hand. Probably safe to remove in a year (middle of 2020) or so. When removing, also remove\n    // from sim.\n    if (!isLegacyImage(buf))\n        return NULL;\n\n    auto tmp = mkBuffer(NULL, buf->length + 4);\n    auto hd = (ImageHeader *)tmp->data;\n    auto src = buf->data;\n    hd->magic = IMAGE_HEADER_MAGIC;\n    hd->bpp = src[0] & 0xf;\n    hd->width = src[1];\n    hd->height = src[2];\n    hd->padding = 0;\n    memcpy(hd->pixels, src + 4, buf->length - 4);\n\n    registerGCObj(tmp);\n    auto r = NEW_GC(RefImage, tmp);\n    unregisterGCObj(tmp);\n    return r;\n}\n\n//%\nvoid _drawIcon(Image_ img, Buffer icon, int xy, int c) {\n    img->makeWritable();\n\n    auto iconImg = convertAndWrap(icon);\n    if (!iconImg || iconImg->bpp() != 1)\n        return;\n\n    drawImageCore(img, iconImg, XX(xy), YY(xy), c);\n}\n\nstatic void drawLineLow(Image_ img, int x0, int y0, int x1, int y1, int c) {\n    int dx = x1 - x0;\n    int dy = y1 - y0;\n    int yi = 1;\n    if (dy < 0) {\n        yi = -1;\n        dy = -dy;\n    }\n    int D = 2 * dy - dx;\n    dx <<= 1;\n    dy <<= 1;\n    int y = y0;\n    for (int x = x0; x <= x1; ++x) {\n        setCore(img, x, y, c);\n        if (D > 0) {\n            y += yi;\n            D -= dx;\n        }\n        D += dy;\n    }\n}\n\nstatic void drawLineHigh(Image_ img, int x0, int y0, int x1, int y1, int c) {\n    int dx = x1 - x0;\n    int dy = y1 - y0;\n    int xi = 1;\n    if (dx < 0) {\n        xi = -1;\n        dx = -dx;\n    }\n    int D = 2 * dx - dy;\n    dx <<= 1;\n    dy <<= 1;\n    int x = x0;\n    for (int y = y0; y <= y1; ++y) {\n        setCore(img, x, y, c);\n        if (D > 0) {\n            x += xi;\n            D -= dy;\n        }\n        D += dx;\n    }\n}\n\nvoid drawLine(Image_ img, int x0, int y0, int x1, int y1, int c) {\n    if (x1 < x0) {\n        drawLine(img, x1, y1, x0, y0, c);\n        return;\n    }\n    int w = x1 - x0;\n    int h = y1 - y0;\n\n    if (h == 0) {\n        if (w == 0)\n            setPixel(img, x0, y0, c);\n        else\n            fillRect(img, x0, y0, w + 1, 1, c);\n        return;\n    }\n\n    if (w == 0) {\n        if (h > 0)\n            fillRect(img, x0, y0, 1, h + 1, c);\n        else\n            fillRect(img, x0, y1, 1, -h + 1, c);\n        return;\n    }\n\n    if (x1 < 0 || x0 >= img->width())\n        return;\n    if (x0 < 0) {\n        y0 -= (h * x0 / w);\n        x0 = 0;\n    }\n    if (x1 >= img->width()) {\n        int d = (img->width() - 1) - x1;\n        y1 += (h * d / w);\n        x1 = img->width() - 1;\n    }\n\n    if (y0 < y1) {\n        if (y0 >= img->height() || y1 < 0)\n            return;\n        if (y0 < 0) {\n            x0 -= (w * y0 / h);\n            y0 = 0;\n        }\n        if (y1 >= img->height()) {\n            int d = (img->height() - 1) - y1;\n            x1 += (w * d / h);\n            y1 = img->height() - 1;\n        }\n    } else {\n        if (y1 >= img->height() || y0 < 0)\n            return;\n        if (y1 < 0) {\n            x1 -= (w * y1 / h);\n            y1 = 0;\n        }\n        if (y0 >= img->height()) {\n            int d = (img->height() - 1) - y0;\n            x0 += (w * d / h);\n            y0 = img->height() - 1;\n        }\n    }\n\n    img->makeWritable();\n\n    if (h < 0) {\n        h = -h;\n        if (h < w)\n            drawLineLow(img, x0, y0, x1, y1, c);\n        else\n            drawLineHigh(img, x1, y1, x0, y0, c);\n    } else {\n        if (h < w)\n            drawLineLow(img, x0, y0, x1, y1, c);\n        else\n            drawLineHigh(img, x0, y0, x1, y1, c);\n    }\n}\n\n//%\nvoid _drawLine(Image_ img, int xy, int wh, int c) {\n    drawLine(img, XX(xy), YY(xy), XX(wh), YY(wh), c);\n}\n\nvoid blitRow(Image_ img, int x, int y, Image_ from, int fromX, int fromH) {\n    if (!img->inRange(x, 0) || !img->inRange(fromX, 0) || fromH <= 0)\n        return;\n\n    if (img->bpp() != 4 || from->bpp() != 4)\n        return;\n\n    int fy = 0;\n    int stepFY = (from->width() << 16) / fromH;\n    int endY = y + fromH;\n    if (endY > img->height())\n        endY = img->height();\n    if (y < 0) {\n        fy += -y * stepFY;\n        y = 0;\n    }\n\n    auto dp = img->pix(x, y);\n    auto sp = from->pix(fromX, 0);\n\n    while (y < endY) {\n        int p = fy >> 16, c;\n        if (p & 1)\n            c = sp[p >> 1] >> 4;\n        else\n            c = sp[p >> 1] & 0xf;\n        if (y & 1) {\n            *dp = (*dp & 0x0f) | (c << 4);\n            dp++;\n        } else {\n            *dp = (*dp & 0xf0) | (c & 0xf);\n        }\n        y++;\n        fy += stepFY;\n    }\n}\n\n//%\nvoid _blitRow(Image_ img, int xy, Image_ from, int xh) {\n    blitRow(img, XX(xy), YY(xy), from, XX(xh), YY(xh));\n}\n\nbool blit(Image_ dst, Image_ src, pxt::RefCollection *args) {\n    int xDst = pxt::toInt(args->getAt(0));\n    int yDst = pxt::toInt(args->getAt(1));\n    int wDst = pxt::toInt(args->getAt(2));\n    int hDst = pxt::toInt(args->getAt(3));\n    int xSrc = pxt::toInt(args->getAt(4));\n    int ySrc = pxt::toInt(args->getAt(5));\n    int wSrc = pxt::toInt(args->getAt(6));\n    int hSrc = pxt::toInt(args->getAt(7));\n    bool transparent = pxt::toBoolQuick(args->getAt(8));\n    bool check = pxt::toBoolQuick(args->getAt(9));\n\n    int xSrcStep = (wSrc << 16) / wDst;\n    int ySrcStep = (hSrc << 16) / hDst;\n\n    int xDstClip = abs(min(0, xDst));\n    int yDstClip = abs(min(0, yDst));\n    int xDstStart = xDst + xDstClip;\n    int yDstStart = yDst + yDstClip;\n    int xDstEnd = min(dst->width(), xDst + wDst);\n    int yDstEnd = min(dst->height(), yDst + hDst);\n\n    int xSrcStart = max(0, (xSrc << 16) + xDstClip * xSrcStep);\n    int ySrcStart = max(0, (ySrc << 16) + yDstClip * ySrcStep);\n    int xSrcEnd = min(src->width(), xSrc + wSrc) << 16;\n    int ySrcEnd = min(src->height(), ySrc + hSrc) << 16;\n\n    if (!check)\n        dst->makeWritable();\n\n    for (int yDstCur = yDstStart, ySrcCur = ySrcStart; yDstCur < yDstEnd && ySrcCur < ySrcEnd; ++yDstCur, ySrcCur += ySrcStep) {\n        int ySrcCurI = ySrcCur >> 16;\n        for (int xDstCur = xDstStart, xSrcCur = xSrcStart; xDstCur < xDstEnd && xSrcCur < xSrcEnd; ++xDstCur, xSrcCur += xSrcStep) {\n            int xSrcCurI = xSrcCur >> 16;\n            int cSrc = getCore(src, xSrcCurI, ySrcCurI);\n            if (check && cSrc) {\n                int cDst = getCore(dst, xDstCur, yDstCur);\n                if (cDst) {\n                    return true;\n                }\n                continue;\n            }\n            if (!transparent || cSrc) {\n                setCore(dst, xDstCur, yDstCur, cSrc);\n            }\n        }\n    }\n    return false;\n}\n\n//%\nbool _blit(Image_ img, Image_ src, pxt::RefCollection *args) {\n    return blit(img, src, args);\n}\n\nvoid fillCircle(Image_ img, int cx, int cy, int r, int c) {\n    int x = r - 1;\n    int y = 0;\n    int dx = 1;\n    int dy = 1;\n    int err = dx - (r << 1);\n\n    while (x >= y) {\n        fillRect(img, cx + x, cy - y, 1, 1 + (y << 1), c);\n        fillRect(img, cx + y, cy - x, 1, 1 + (x << 1), c);\n        fillRect(img, cx - x, cy - y, 1, 1 + (y << 1), c);\n        fillRect(img, cx - y, cy - x, 1, 1 + (x << 1), c);\n        if (err <= 0) {\n            ++y;\n            err += dy;\n            dy += 2;\n        } else {\n            --x;\n            dx += 2;\n            err += dx - (r << 1);\n        }\n    }\n}\n\n//%\nvoid _fillCircle(Image_ img, int cxy, int r, int c) {\n    fillCircle(img, XX(cxy), YY(cxy), r, c);\n}\n\ntypedef struct\n{\n    int x, y;\n    int x0, y0;\n    int x1, y1;\n    int W,H;\n    int dx, dy;\n    int yi, xi;\n    int D;\n    int nextFuncIndex;\n} LineGenState; // For keeping track of the state when generating Y values for a line, even when moving to the next X.\n\ntypedef struct\n{\n    int min;\n    int max;\n} ValueRange;\n\nvoid nextYRange_Low(int x, LineGenState *line, ValueRange *yRange) {\n    while (line->x == x && line->x <= line->x1 && line->x < line->W) {\n        if (0 <= line->x) {\n            if (line->y < yRange->min) yRange->min = line->y;\n            if (line->y > yRange->max) yRange->max = line->y;\n        }\n        if (line->D > 0) {\n            line->y += line->yi;\n            line->D -= line->dx;\n        }\n        line->D += line->dy;\n        ++line->x;\n    }\n}\n\nvoid nextYRange_HighUp(int x, LineGenState *line, ValueRange *yRange) {\n    while (line->x == x && line->y >= line->y1 && line->x < line->W) {\n        if (0 <= line->x) {\n            if (line->y < yRange->min) yRange->min = line->y;\n            if (line->y > yRange->max) yRange->max = line->y;\n        }\n        if (line->D > 0) {\n            line->x += line->xi;\n            line->D += line->dy;\n        }\n        line->D += line->dx;\n        --line->y;\n    }\n}\n// This function is similar to the sub-function drawLineHigh for drawLine. However, it yields back after calculating all Y values of a given X. When the function is called again, it continues from the state where it yielded back previously.\nvoid nextYRange_HighDown(int x, LineGenState *line, ValueRange *yRange) {\n    while (line->x == x && line->y <= line->y1 && line->x < line->W) {\n        if (0 <= line->x) {\n            if (line->y < yRange->min) yRange->min = line->y;\n            if (line->y > yRange->max) yRange->max = line->y;\n        }\n        if (line->D > 0) {\n            line->x += line->xi;\n            line->D -= line->dy;\n        }\n        line->D += line->dx;\n        ++line->y;\n    }\n}\n\nLineGenState initYRangeGenerator(int16_t X0, int16_t Y0, int16_t X1, int16_t Y1) {\n    LineGenState line;\n\n    line.x0 = X0, line.y0 = Y0, line.x1 = X1, line.y1 = Y1;\n\n    line.dx = line.x1 - line.x0;\n    line.dy = line.y1 - line.y0;\n    line.y = line.y0;\n    line.x = line.x0;\n\n    if ((line.dy < 0 ? -line.dy : line.dy) < line.dx) {\n        line.yi = 1;\n        if (line.dy < 0) {\n            line.yi = -1;\n            line.dy = -line.dy;\n        }\n        line.D = 2 * line.dy - line.dx;\n        line.dx <<= 1;\n        line.dy <<= 1;\n\n        line.nextFuncIndex = 0;\n        return line;\n    } else {\n        line.xi = 1;\n        // if (dx < 0) {//should not hit\n        //     PANIC();\n        // }\n        if (line.dy < 0) {\n            line.D = 2 * line.dx + line.dy;\n            line.dx <<= 1;\n            line.dy <<= 1;\n\n            line.nextFuncIndex = 1;\n            return line;\n        } else {\n            line.D = 2 * line.dx - line.dy;\n            line.dx <<= 1;\n            line.dy <<= 1;\n\n            line.nextFuncIndex = 2;\n            return line;\n        }\n    }\n}\n\n// core of draw vertical line for repeatly calling, eg.: fillTriangle() or fillPolygon4()\n// value range/safety check not included\n// prepare \"img->makeWritable();\" and \"uint8_t f = img->fillMask(c);\" outside required.\n// bpp=4 support only right now\nvoid drawVLineCore(Image_ img, int x, int y, int h, uint8_t f) {\n    uint8_t *p = img->pix(x, y);\n    auto ptr = p;\n    unsigned mask = 0x0f;\n    if (y & 1)\n        mask <<= 4;\n    for (int i = 0; i < h; ++i) {\n        if (mask == 0xf00) {\n            if (h - i >= 2) {\n                *++ptr = f;\n                i++;\n                continue;\n            } else {\n                mask = 0x0f;\n                ptr++;\n            }\n        }\n        *ptr = (*ptr & ~mask) | (f & mask);\n        mask <<= 4;\n    }\n}\n\nvoid drawVLine(Image_ img, int x, int y, int h, int c) {\n    int H = height(img);\n    uint8_t f = img->fillMask(c);\n    if (x < 0 || x >= width(img) || y >= H || y + h - 1 < 0)\n        return;\n    if (y < 0){\n        h += y;\n        y = 0;\n    }\n    if (y + h > H)\n        h = H - y;\n    drawVLineCore(img, x, y, h, f);\n}\n\nvoid fillTriangle(Image_ img, int x0, int y0, int x1, int y1, int x2, int y2, int c) {\n    if (x1 < x0) {\n        swap(x0, x1);\n        swap(y0, y1);\n    }\n    if (x2 < x1) {\n        swap(x1, x2);\n        swap(y1, y2);\n    }\n    if (x1 < x0) {\n        swap(x0, x1);\n        swap(y0, y1);\n    }\n\n    LineGenState lines[] = {\n        initYRangeGenerator(x0, y0, x2, y2),\n        initYRangeGenerator(x0, y0, x1, y1),\n        initYRangeGenerator(x1, y1, x2, y2)\n    };\n\n    int W = width(img), H = height(img);\n    lines[0].W = lines[1].W = lines[2].W = W;\n    lines[0].H = lines[1].H = lines[2].H = H;\n\n    // We have 3 different sub-functions to generate Ys of edges, each particular edge maps to one of them.\n    // Use function pointers to avoid judging which function to call at every X.\n    typedef void (*FP_NEXT)(int x, LineGenState *line, ValueRange *yRange);\n    FP_NEXT nextFuncList[] = { nextYRange_Low, nextYRange_HighUp, nextYRange_HighDown };\n    FP_NEXT fpNext0 = nextFuncList[lines[0].nextFuncIndex];\n    FP_NEXT fpNext1 = nextFuncList[lines[1].nextFuncIndex];\n    FP_NEXT fpNext2 = nextFuncList[lines[2].nextFuncIndex];\n\n    ValueRange yRange = {H, -1};\n    img->makeWritable();\n    uint8_t f = img->fillMask(c);\n\n    for (int x = lines[1].x0; x <= min(x1, W - 1); x++) {\n        yRange.min = H;\n        yRange.max = -1;\n        fpNext0(x, &lines[0], &yRange);\n        fpNext1(x, &lines[1], &yRange);\n\n        if (x < 0 || yRange.min >= H || yRange.max < 0)\n            continue;\n        if (yRange.min < 0)\n            yRange.min = 0;\n        if (yRange.max >= H)\n            yRange.max = H - 1;\n        drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);\n    }\n\n    fpNext2(lines[2].x0, &lines[2], &yRange);\n\n    for (int x = lines[2].x0 + 1; x <= min(x2, W - 1); x++) {\n        yRange.min = H;\n        yRange.max = -1;\n        fpNext0(x, &lines[0], &yRange);\n        fpNext2(x, &lines[2], &yRange);\n\n        if (x < 0 || yRange.min >= H || yRange.max < 0)\n            continue;\n        if (yRange.min < 0)\n            yRange.min = 0;\n        if (yRange.max >= H)\n            yRange.max = H - 1;\n        drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);\n    }\n}\n\nvoid fillPolygon4(Image_ img, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, int c) {\n    LineGenState lines[] = {\n        (x0 < x1) ? initYRangeGenerator(x0, y0, x1, y1) : initYRangeGenerator(x1, y1, x0, y0),\n        (x1 < x2) ? initYRangeGenerator(x1, y1, x2, y2) : initYRangeGenerator(x2, y2, x1, y1),\n        (x2 < x3) ? initYRangeGenerator(x2, y2, x3, y3) : initYRangeGenerator(x3, y3, x2, y2),\n        (x0 < x3) ? initYRangeGenerator(x0, y0, x3, y3) : initYRangeGenerator(x3, y3, x0, y0)};\n\n    int W = width(img), H = height(img);\n    lines[0].W = lines[1].W = lines[2].W = lines[3].W = W;\n    lines[0].H = lines[1].H = lines[2].H = lines[3].H = H;\n\n    int minX = min(min(x0, x1), min(x2, x3));\n    int maxX = min(max(max(x0, x1), max(x2, x3)), W - 1);\n\n    typedef void (*FP_NEXT)(int x, LineGenState *line, ValueRange *yRange);\n    FP_NEXT nextFuncList[] = { nextYRange_Low, nextYRange_HighUp, nextYRange_HighDown };\n    FP_NEXT fpNext0 = nextFuncList[lines[0].nextFuncIndex];\n    FP_NEXT fpNext1 = nextFuncList[lines[1].nextFuncIndex];\n    FP_NEXT fpNext2 = nextFuncList[lines[2].nextFuncIndex];\n    FP_NEXT fpNext3 = nextFuncList[lines[3].nextFuncIndex];\n\n    ValueRange yRange = { H, -1 };\n    img->makeWritable();\n    uint8_t f = img->fillMask(c);\n\n    for (int x = minX; x <= maxX; x++) {\n        yRange.min = H;\n        yRange.max = -1;\n        fpNext0(x, &lines[0], &yRange);\n        fpNext1(x, &lines[1], &yRange);\n        fpNext2(x, &lines[2], &yRange);\n        fpNext3(x, &lines[3], &yRange);\n\n        if (x < 0 || yRange.min >= H || yRange.max < 0)\n            continue;\n        if (yRange.min < 0)\n            yRange.min = 0;\n        if (yRange.max >= H)\n            yRange.max = H - 1;\n        drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);\n    }\n}\n\n//%\nvoid _fillTriangle(Image_ img, pxt::RefCollection *args) {\n    fillTriangle(\n        img,\n        pxt::toInt(args->getAt(0)),\n        pxt::toInt(args->getAt(1)),\n        pxt::toInt(args->getAt(2)),\n        pxt::toInt(args->getAt(3)),\n        pxt::toInt(args->getAt(4)),\n        pxt::toInt(args->getAt(5)),\n        pxt::toInt(args->getAt(6))\n    );\n}\n\n// This polygon fill is similar to fillTriangle(): Scan minY and maxY of all edges at each X, and draw a vertical line between (x,minY)~(x,maxY).\n// The main difference is that it sorts the endpoints of each edge, x0 < x1, to draw from left to right, but doesn't sort the edges as it's too time consuming.\n// Instead, just call next(), which returns immediately if the x is not in range of the edge in horizon.\n// NOTE: Unlike triangles, edges of a polygon can cross a vertical line at a given X multi time. This algorithm can fill correctly only if edges meet this condition: Any vertical line(x) cross edges at most 2 times.\n// Fortunately, no matter what perspective transform is applied, a rectangle/trapezoid will still meet this condition.\n// Ref: https://forum.makecode.com/t/new-3d-engine-help-filling-4-sided-polygons/18641/9\n//%\nvoid _fillPolygon4(Image_ img, pxt::RefCollection *args) {\n    fillPolygon4(\n        img,\n        pxt::toInt(args->getAt(0)),\n        pxt::toInt(args->getAt(1)),\n        pxt::toInt(args->getAt(2)),\n        pxt::toInt(args->getAt(3)),\n        pxt::toInt(args->getAt(4)),\n        pxt::toInt(args->getAt(5)),\n        pxt::toInt(args->getAt(6)),\n        pxt::toInt(args->getAt(7)),\n        pxt::toInt(args->getAt(8))\n    );\n}\n\n} // namespace ImageMethods\n\nnamespace image {\n/**\n * Create new empty (transparent) image\n */\n//%\nImage_ create(int width, int height) {\n    Image_ r = mkImage(width, height, IMAGE_BITS);\n    if (r)\n        memset(r->pix(), 0, r->pixLength());\n    else\n        target_panic(PANIC_INVALID_IMAGE);\n    return r;\n}\n\n/**\n * Create new image with given content\n */\n//%\nImage_ ofBuffer(Buffer buf) {\n    return ImageMethods::convertAndWrap(buf);\n}\n\n/**\n * Double the size of an icon\n */\n//%\nBuffer doubledIcon(Buffer icon) {\n    if (!isValidImage(icon))\n        return NULL;\n\n    auto r = NEW_GC(RefImage, icon);\n    registerGCObj(r);\n    auto t = ImageMethods::doubled(r);\n    unregisterGCObj(r);\n    return t->buffer;\n}\n\n} // namespace image\n\n// This is  6.5x faster than standard on word-aligned copy\n// probably should move to codal\n\n#ifndef __linux__\nextern \"C\" void *memcpy(void *dst, const void *src, size_t sz) {\n    void *dst0 = dst;\n    if (sz >= 4 && !((uintptr_t)dst & 3) && !((uintptr_t)src & 3)) {\n        size_t cnt = sz >> 2;\n        uint32_t *d = (uint32_t *)dst;\n        const uint32_t *s = (const uint32_t *)src;\n        while (cnt--) {\n            *d++ = *s++;\n        }\n        sz &= 3;\n        dst = d;\n        src = s;\n    }\n\n    // see comment in memset() below (have not seen optimization here, but better safe than sorry)\n    volatile uint8_t *dd = (uint8_t *)dst;\n    volatile uint8_t *ss = (uint8_t *)src;\n\n    while (sz--) {\n        *dd++ = *ss++;\n    }\n\n    return dst0;\n}\n\nextern \"C\" void *memset(void *dst, int v, size_t sz) {\n    void *dst0 = dst;\n    if (sz >= 4 && !((uintptr_t)dst & 3)) {\n        size_t cnt = sz >> 2;\n        uint32_t vv = 0x01010101 * v;\n        uint32_t *d = (uint32_t *)dst;\n        while (cnt--) {\n            *d++ = vv;\n        }\n        sz &= 3;\n        dst = d;\n    }\n\n    // without volatile here, GCC may optimize the loop to memset() call which is obviously not great\n    volatile uint8_t *dd = (uint8_t *)dst;\n\n    while (sz--) {\n        *dd++ = v;\n    }\n\n    return dst0;\n}\n#endif\n","image.d.ts":"//% fixedInstances decompileIndirectFixedInstances\ninterface Image {\n    /**\n     * Fill a rectangle\n     */\n    //% helper=imageFillRect blockNamespace=\"images\" inlineInputMode=\"inline\" group=\"Drawing\"\n    //% block=\"fill rectangle in %picture=variables_get at x %x y %y width %w height %h %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/fill-rect\n    fillRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Replace colors in a rectangle\n     */\n    //% helper=imageMapRect\n    mapRect(x: number, y: number, w: number, h: number, colorMap: Buffer): void;\n\n    /**\n     * Draw a line\n     */\n    //% helper=imageDrawLine blockNamespace=\"images\" inlineInputMode=\"inline\" group=\"Drawing\"\n    //% block=\"draw line in %picture=variables_get from x %x0 y %y0 to x %x1 y %y1 %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/draw-line\n    drawLine(x0: number, y0: number, x1: number, y1: number, c: color): void;\n\n    /**\n     * Draw an empty rectangle\n     */\n    //% helper=imageDrawRect blockNamespace=\"images\" inlineInputMode=\"inline\" group=\"Drawing\"\n    //% block=\"draw rectangle in %picture=variables_get at x %x y %y width %w height %h %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/draw-rect\n    drawRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Set pixel color\n     */\n    //% shim=ImageMethods::setPixel blockNamespace=\"images\" group=\"Drawing\"\n    //% block=\"set %picture=variables_get color at x %x y %y to %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/set-pixel\n    setPixel(x: int32, y: int32, c: int32): void;\n\n    /**\n     * Get a pixel color\n     */\n    //% shim=ImageMethods::getPixel blockNamespace=\"images\" group=\"Drawing\"\n    //% block=\"%picture=variables_get color at x %x y %y\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/get-pixel\n    getPixel(x: int32, y: int32): int32;\n\n    /**\n     * Fill entire image with a given color\n     */\n    //% shim=ImageMethods::fill blockNamespace=\"images\" group=\"Drawing\"\n    //% block=\"fill %picture=variables_get with %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/fill\n    fill(c: int32): void;\n\n    /**\n     * Return a copy of the current image\n     */\n    //% shim=ImageMethods::clone blockNamespace=\"images\" group=\"Create\"\n    //% block=\"clone %picture=variables_get\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/clone\n    clone(): Image;\n\n    /**\n     * Flips (mirrors) pixels horizontally in the current image\n     */\n    //% shim=ImageMethods::flipX blockNamespace=\"images\" group=\"Transformations\"\n    //% block=\"flip %picture=variables_get horizontally\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/flip-x\n    flipX(): void;\n\n    /**\n     * Flips (mirrors) pixels vertically in the current image\n     */\n    //% shim=ImageMethods::flipY blockNamespace=\"images\" group=\"Transformations\"\n    //% block=\"flip %picture=variables_get vertically\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/flip-y\n    flipY(): void;\n\n    /**\n     * Every pixel in image is moved by (dx,dy)\n     */\n    //% shim=ImageMethods::scroll blockNamespace=\"images\" group=\"Transformations\"\n    //% help=images/image/scroll\n    scroll(dx: int32, dy: int32): void;\n\n    /**\n     * Replaces one color in an image with another\n     */\n    //% shim=ImageMethods::replace blockNamespace=\"images\" group=\"Transformations\"\n    //% block=\"change color in %picture=variables_get from %from=colorindexpicker to %to=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/replace\n    replace(from: int32, to: int32): void;\n\n    /**\n     * Returns true if the provided image is the same as this image,\n     * otherwise returns false.\n     */\n    //% shim=ImageMethods::equals\n    //% blockNamespace=\"images\" group=\"Compare\"\n    //% block=\"$this is equal to image $other\"\n    //% this.shadow=variables_get\n    //% this.defl=\"picture\"\n    //% other.shadow=screen_image_picker\n    //% help=images/image/equals\n    equals(other: Image): boolean;\n\n    //% shim=ImageMethods::isStatic\n    isStatic(): boolean;\n\n    //% shim=ImageMethods::revision\n    revision(): number;\n\n     /**\n     * Draw given image with transparent background on the current image\n     */\n    //% shim=ImageMethods::drawTransparentImage\n    //% blockNamespace=\"images\"\n    //% blockId=image_draw_transparent_image\n    //% group=\"Drawing\"\n    //% block=\"$this draw $from at x $x y $y\"\n    //% this.shadow=variables_get\n    //% this.defl=\"picture\"\n    //% from.shadow=screen_image_picker\n    //% weight=0\n    drawTransparentImage(from: Image, x: int32, y: int32): void;\n}\n\ndeclare namespace image {\n    //% blockNamespace=\"images\"\n    //% block=\"create image width %width height %height\" group=\"Create\"\n    //% help=images/create\n    function create(width: number, height: number): Image;\n}","image.ts":"type color = number\n\nnamespace image {\n    export enum Dimension {\n        //% block=\"width\"\n        Width,\n        //% block=\"height\"\n        Height\n    }\n\n    export function repeatY(count: number, image: Image) {\n        let arr = [image]\n        while (--count > 0)\n            arr.push(image)\n        return concatY(arr)\n    }\n\n    export function concatY(images: Image[]) {\n        let w = 0\n        let h = 0\n        for (let img of images) {\n            w = Math.max(img.width, w)\n            h += img.height\n        }\n        let r = image.create(w, h)\n        let y = 0\n        for (let img of images) {\n            let x = (w - img.width) >> 1\n            r.drawImage(img, x, y)\n            y += img.height\n        }\n        return r\n    }\n\n    /**\n     * Returns the width or height of a picture.\n     *\n     * @param picture The picture to get the width or height of\n     * @param dimension The dimension to get\n     * @returns\n     */\n    //% blockId=image_get_dimension\n    //% group=\"Create\"\n    //% blockNamespace=\"images\"\n    //% block=\"$picture $dimension\"\n    //% picture.shadow=variables_get\n    //% picture.defl=picture\n    export function getDimension(picture: Image, dimension: Dimension) {\n        if (dimension === Dimension.Width) return picture.width;\n        else return picture.height;\n    }\n}\n\n\n//% snippet='img` `'\n//% pySnippet='img(\"\"\" \"\"\")'\n//% fixedInstances\ninterface Image {\n    /**\n     * Draw an icon (monochromatic image) using given color\n     */\n    //% helper=imageDrawIcon\n    drawIcon(icon: Buffer, x: number, y: number, c: color): void;\n\n    /**\n     * Fill a rectangle\n     */\n    //% helper=imageFillRect\n    fillRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Draw a line\n     */\n    //% helper=imageDrawLine\n    drawLine(x0: number, y0: number, x1: number, y1: number, c: color): void;\n\n    /**\n     * Draw an empty rectangle\n     */\n    //% helper=imageDrawRect\n    drawRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Draw a circle\n     */\n    //% helper=imageDrawCircle\n    drawCircle(cx: number, cy: number, r: number, c: color): void;\n\n    /**\n     * Fills a circle\n     */\n    //% helper=imageFillCircle\n    fillCircle(cx: number, cy: number, r: number, c: color): void;\n\n    /**\n     * Fills a triangle\n     */\n    //% helper=imageFillTriangle\n    fillTriangle(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, col: number): void;\n\n    /**\n     * Fills a 4-side-polygon\n     */\n    //% helper=imageFillPolygon4\n    fillPolygon4(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, col: number): void;\n\n    /**\n     * Returns an image rotated by -90, 90, -180, 180, -270, 270 deg clockwise\n     */\n    //% helper=imageRotated\n    rotated(deg: number): Image;\n\n    /**\n     * Scale and copy a row of pixels from a texture.\n     */\n    //% helper=imageBlitRow\n    blitRow(dstX: number, dstY: number, from: Image, fromX: number, fromH: number): void;\n\n    /**\n     * Copy an image from a source rectangle to a destination rectangle, stretching or\n     * compressing to fit the dimensions of the destination rectangle, if necessary.\n     */\n    //% helper=imageBlit\n    blit(xDst: number, yDst: number, wDst: number, hDst: number, src: Image, xSrc: number, ySrc: number, wSrc: number, hSrc: number, transparent: boolean, check: boolean): boolean;\n}\n\ninterface ScreenImage extends Image {\n    /**\n     * Sets the screen backlight brightness (10-100)\n     */\n    //% helper=setScreenBrightness\n    setBrightness(deg: number): Image;\n\n    /**\n     * Gets current screen backlight brightness (0-100)\n     */\n    //% helper=screenBrightness\n    brightness(): number;\n}\n\n// pxt compiler currently crashes on non-functions in helpers namespace; will fix\nnamespace _helpers_workaround {\n    export let brightness = 100\n}\n\nnamespace helpers {\n    //% shim=ImageMethods::_drawLine\n    function _drawLine(img: Image, xy: number, wh: number, c: color): void { }\n\n    //% shim=ImageMethods::_fillRect\n    function _fillRect(img: Image, xy: number, wh: number, c: color): void { }\n\n    //% shim=ImageMethods::_mapRect\n    function _mapRect(img: Image, xy: number, wh: number, m: Buffer): void { }\n\n    //% shim=ImageMethods::_drawIcon\n    function _drawIcon(img: Image, icon: Buffer, xy: number, c: color): void { }\n\n    //% shim=ImageMethods::_fillCircle\n    declare function _fillCircle(img: Image, cxy: number, r: number, c: color): void;\n\n    //% shim=ImageMethods::_blitRow\n    declare function _blitRow(img: Image, xy: number, from: Image, xh: number): void;\n\n    //% shim=ImageMethods::_blit\n    declare function _blit(img: Image, src: Image, args: number[]): boolean;\n\n    //% shim=ImageMethods::_fillTriangle\n    declare function _fillTriangle(img: Image, args: number[]): void;\n\n    //% shim=ImageMethods::_fillPolygon4\n    declare function _fillPolygon4(img: Image, args: number[]): void;\n\n    function pack(x: number, y: number) {\n        return (Math.clamp(-30000, 30000, x | 0) & 0xffff) | (Math.clamp(-30000, 30000, y | 0) << 16)\n    }\n\n    let _blitArgs: number[];\n\n    export function imageBlit(img: Image, xDst: number, yDst: number, wDst: number, hDst: number, src: Image, xSrc: number, ySrc: number, wSrc: number, hSrc: number, transparent: boolean, check: boolean): boolean {\n        _blitArgs = _blitArgs || [];\n        _blitArgs[0] = xDst | 0;\n        _blitArgs[1] = yDst | 0;\n        _blitArgs[2] = wDst | 0;\n        _blitArgs[3] = hDst | 0;\n        _blitArgs[4] = xSrc | 0;\n        _blitArgs[5] = ySrc | 0;\n        _blitArgs[6] = wSrc | 0;\n        _blitArgs[7] = hSrc | 0;\n        _blitArgs[8] = transparent ? 1 : 0;\n        _blitArgs[9] = check ? 1 : 0;\n        return _blit(img, src, _blitArgs);\n    }\n\n    export function imageBlitRow(img: Image, dstX: number, dstY: number, from: Image, fromX: number, fromH: number): void {\n        _blitRow(img, pack(dstX, dstY), from, pack(fromX, fromH))\n    }\n\n    export function imageDrawIcon(img: Image, icon: Buffer, x: number, y: number, c: color): void {\n        _drawIcon(img, icon, pack(x, y), c)\n    }\n    export function imageFillRect(img: Image, x: number, y: number, w: number, h: number, c: color): void {\n        _fillRect(img, pack(x, y), pack(w, h), c)\n    }\n    export function imageMapRect(img: Image, x: number, y: number, w: number, h: number, m: Buffer): void {\n        _mapRect(img, pack(x, y), pack(w, h), m)\n    }\n    export function imageDrawLine(img: Image, x: number, y: number, w: number, h: number, c: color): void {\n        _drawLine(img, pack(x, y), pack(w, h), c)\n    }\n    export function imageDrawRect(img: Image, x: number, y: number, w: number, h: number, c: color): void {\n        if (w == 0 || h == 0) return\n        w--\n        h--\n        imageDrawLine(img, x, y, x + w, y, c)\n        imageDrawLine(img, x, y, x, y + h, c)\n        imageDrawLine(img, x + w, y + h, x + w, y, c)\n        imageDrawLine(img, x + w, y + h, x, y + h, c)\n    }\n\n    export function imageDrawCircle(img: Image, cx: number, cy: number, r: number, col: number) {\n        cx = cx | 0;\n        cy = cy | 0;\n        r = r | 0;\n        // short cuts\n        if (r < 0)\n            return;\n\n        // Bresenham's algorithm\n        let x = 0\n        let y = r\n        let d = 3 - 2 * r\n\n        while (y >= x) {\n            img.setPixel(cx + x, cy + y, col)\n            img.setPixel(cx - x, cy + y, col)\n            img.setPixel(cx + x, cy - y, col)\n            img.setPixel(cx - x, cy - y, col)\n            img.setPixel(cx + y, cy + x, col)\n            img.setPixel(cx - y, cy + x, col)\n            img.setPixel(cx + y, cy - x, col)\n            img.setPixel(cx - y, cy - x, col)\n            x++\n            if (d > 0) {\n                y--\n                d += 4 * (x - y) + 10\n            } else {\n                d += 4 * x + 6\n            }\n        }\n    }\n\n    export function imageFillCircle(img: Image, cx: number, cy: number, r: number, col: number) {\n        _fillCircle(img, pack(cx, cy), r, col);\n    }\n\n    export function imageFillTriangle(img: Image, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, col: number) {\n        _blitArgs = _blitArgs || [];\n        _blitArgs[0] = x0;\n        _blitArgs[1] = y0;\n        _blitArgs[2] = x1;\n        _blitArgs[3] = y1;\n        _blitArgs[4] = x2;\n        _blitArgs[5] = y2;\n        _blitArgs[6] = col;\n        _fillTriangle(img, _blitArgs);\n    }\n\n    export function imageFillPolygon4(img: Image, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, col: number) {\n        _blitArgs = _blitArgs || [];\n        _blitArgs[0] = x0;\n        _blitArgs[1] = y0;\n        _blitArgs[2] = x1;\n        _blitArgs[3] = y1;\n        _blitArgs[4] = x2;\n        _blitArgs[5] = y2;\n        _blitArgs[6] = x3;\n        _blitArgs[7] = y3;\n        _blitArgs[8] = col;\n        _fillPolygon4(img, _blitArgs);\n    }\n\n    /**\n     * Returns an image rotated by 90, 180, 270 deg clockwise\n     */\n    export function imageRotated(img: Image, deg: number) {\n        if (deg == -90 || deg == 270) {\n            let r = img.transposed();\n            r.flipY();\n            return r;\n        } else if (deg == 180 || deg == -180) {\n            let r = img.clone();\n            r.flipX();\n            r.flipY();\n            return r;\n        } else if (deg == 90 || deg == -270) {\n            let r = img.transposed();\n            r.flipX();\n            return r;\n        } else {\n            return null;\n        }\n    }\n\n    //% shim=pxt::setScreenBrightness\n    function _setScreenBrightness(brightness: number) { }\n\n    export function setScreenBrightness(img: Image, b: number) {\n        b = Math.clamp(10, 100, b | 0);\n        _helpers_workaround.brightness = b\n        _setScreenBrightness(_helpers_workaround.brightness)\n    }\n\n    export function screenBrightness(img: Image) {\n        return _helpers_workaround.brightness\n    }\n}\n","imagesoverrides.jres":"{\n  \n}","imagesoverrides.ts":"// replace with built-in images","ns.ts":" ","panic.cpp":"// potentially overriden in targets","pxt.json":"{\n    \"name\": \"screen---ext\",\n    \"description\": \"The screen library\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"screen.cpp\",\n        \"panic.cpp\",\n        \"image.cpp\",\n        \"image.ts\",\n        \"screenimage.ts\",\n        \"text.ts\",\n        \"frame.ts\",\n        \"shims.d.ts\",\n        \"fieldeditors.ts\",\n        \"targetoverrides.ts\",\n        \"ns.ts\",\n        \"image.d.ts\",\n        \"pxtparts.json\",\n        \"imagesoverrides.jres\",\n        \"imagesoverrides.ts\",\n        \"font12.jres\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","pxtparts.json":"{\n  \"screen\": {\n    \"simulationBehavior\": \"screen\",\n    \"visual\": {\n      \"builtIn\": \"screen\",\n      \"width\": 158.43856811523438,\n      \"height\": 146.8025665283203,\n      \"pinDistance\": 14.91,\n      \"pinLocations\": [\n        {\n          \"x\": 4.227952701380444,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 18.170226805137037,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 46.05478386015504,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 59.99706238766404,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 73.93934976267785,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 87.88161944268204,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 101.82389797019104,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 32.11250533264604,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 117.68761950246274,\n          \"y\": 3.1650031792503945\n        }\n      ]\n    },\n    \"numberOfPins\": 9,\n    \"instantiation\": {\n      \"kind\": \"singleton\"\n    },\n    \"pinDefinitions\": [\n      {\n        \"target\": \"ground\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"threeVolt\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_DC\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_CS\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_MOSI\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_SCK\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_MISO\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_RST\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"threeVolt\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      }\n    ],\n    \"assembly\": [\n      {\n        \"pinIndices\": [\n          0,\n          1,\n          2,\n          3,\n          4,\n          5,\n          6,\n          7,\n          8\n        ]\n      }\n    ]\n  }\n}","screen.cpp":"#include \"pxt.h\"\n\nnamespace pxt {\nclass WDisplay {\n  public:\n    uint32_t currPalette[16];\n    bool newPalette, dataWaiting;\n    uint8_t *screenBuf;\n\n    int width, height;\n\n    WDisplay();\n    void updateLoop();\n    void update(Image_ img);\n};\n\nSINGLETON(WDisplay);\n\nWDisplay::WDisplay() {\n    width = getConfig(CFG_DISPLAY_WIDTH, 160);\n    height = getConfig(CFG_DISPLAY_HEIGHT, 128);\n    DMESG(\"init display: %dx%d\", width, height);\n    screenBuf = new uint8_t[width * height / 2 + 20];\n    newPalette = false;\n}\n\n//% expose\nint setScreenBrightnessSupported() {\n    return 0;\n}\n\n//% expose\nvoid setScreenBrightness(int level) {\n    // TODO\n}\n\n//% expose\nvoid setPalette(Buffer buf) {\n    auto display = getWDisplay();\n    if (48 != buf->length)\n        target_panic(PANIC_SCREEN_ERROR);\n    for (int i = 0; i < 16; ++i) {\n        uint8_t r = buf->data[i * 3];\n        uint8_t g = buf->data[i * 3 + 1];\n        uint8_t b = buf->data[i * 3 + 2];\n        display->currPalette[i] = (0xff << 24) | (r << 16) | (g << 8) | (b << 0);\n    }\n    display->newPalette = true;\n}\n\nstatic pthread_mutex_t screenMutex;\nstatic pthread_cond_t dataBroadcast;\nstatic int numGetPixels;\n\nDLLEXPORT void pxt_screen_get_pixels(int width, int height, uint32_t *screen) {\n    auto disp = instWDisplay;\n    numGetPixels++;\n\n    if (!disp) {\n        int n = width * height;\n        uint32_t *p = screen;\n        // blue screen\n        while (n--)\n            *p++ = 0xff000000;\n        return;\n    }\n\n    pthread_mutex_lock(&screenMutex);\n    if (!disp->dataWaiting) {\n        struct timespec timeout = {0, 100 * 1000 * 1000}; // up to 100ms\n        pthread_cond_timedwait(&dataBroadcast, &screenMutex, &timeout);\n    }\n    if (width != disp->width || height != disp->height)\n        target_panic(PANIC_SCREEN_ERROR);\n    if (panicCode > 0) {\n        int n = width * height;\n        uint32_t *p = screen;\n        // blue screen\n        while (n--)\n            *p++ = 0xff0000ff;\n    } else {\n        auto sp = disp->screenBuf;\n        auto pal = disp->currPalette;\n        for (int x = 0; x < width; ++x) {\n            uint32_t *p = screen + x;\n            for (int y = 0; y < (height >> 1); ++y) {\n                uint8_t v = *sp++;\n                *p = pal[v & 0xf];\n                p += width;\n                *p = pal[v >> 4];\n                p += width;\n            }\n        }\n    }\n    pthread_cond_broadcast(&dataBroadcast);\n    disp->dataWaiting = false;\n    pthread_mutex_unlock(&screenMutex);\n}\n\nvoid WDisplay::update(Image_ img) {\n    if (!img)\n        return;\n\n    if (img->bpp() != 4 || img->width() != width || img->height() != height)\n        target_panic(PANIC_SCREEN_ERROR);\n\n    pthread_mutex_lock(&screenMutex);\n    // if the data have not been picked up, but it had been in the past, wait\n    if (dataWaiting && numGetPixels)\n        pthread_cond_wait(&dataBroadcast, &screenMutex);\n    memcpy(screenBuf, img->pix(), img->pixLength());\n    dataWaiting = true;\n    pthread_cond_broadcast(&dataBroadcast);\n    pthread_mutex_unlock(&screenMutex);\n\n    if (newPalette) {\n        newPalette = false;\n    }\n}\n\n//% expose\nvoid updateScreen(Image_ img) {\n    getWDisplay()->update(img);\n}\n\n//% expose\nvoid updateStats(String msg) {\n    DMESG(\"stats: %s\", msg->getUTF8Data());\n}\n} // namespace pxt","screenimage.ts":"\nnamespace image {\n    /**\n    * Get the screen image\n    */\n    //% blockNamespace=\"images\" group=\"Create\"\n    //% blockId=imagescreen block=\"screen\"\n    //% help=images/screen-image\n    export function screenImage(): Image {\n        return screen;\n    }\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\n\n\ndeclare interface Image {\n    /**\n     * Get the width of the image\n     */\n    //% property shim=ImageMethods::width\n    width: int32;\n\n    /**\n     * Get the height of the image\n     */\n    //% property shim=ImageMethods::height\n    height: int32;\n\n    /**\n     * True if the image is monochromatic (black and white)\n     */\n    //% property shim=ImageMethods::isMono\n    isMono: boolean;\n\n    /**\n     * Sets all pixels in the current image from the other image, which has to be of the same size and\n     * bpp.\n     */\n    //% shim=ImageMethods::copyFrom\n    copyFrom(from: Image): void;\n\n    /**\n     * Set pixel color\n     */\n    //% shim=ImageMethods::setPixel\n    setPixel(x: int32, y: int32, c: int32): void;\n\n    /**\n     * Get a pixel color\n     */\n    //% shim=ImageMethods::getPixel\n    getPixel(x: int32, y: int32): int32;\n\n    /**\n     * Fill entire image with a given color\n     */\n    //% shim=ImageMethods::fill\n    fill(c: int32): void;\n\n    /**\n     * Copy row(s) of pixel from image to buffer (8 bit per pixel).\n     */\n    //% shim=ImageMethods::getRows\n    getRows(x: int32, dst: Buffer): void;\n\n    /**\n     * Copy row(s) of pixel from buffer to image.\n     */\n    //% shim=ImageMethods::setRows\n    setRows(x: int32, src: Buffer): void;\n\n    /**\n     * Return a copy of the current image\n     */\n    //% shim=ImageMethods::clone\n    clone(): Image;\n\n    /**\n     * Flips (mirrors) pixels horizontally in the current image\n     */\n    //% shim=ImageMethods::flipX\n    flipX(): void;\n\n    /**\n     * Flips (mirrors) pixels vertically in the current image\n     */\n    //% shim=ImageMethods::flipY\n    flipY(): void;\n\n    /**\n     * Returns a transposed image (with X/Y swapped)\n     */\n    //% shim=ImageMethods::transposed\n    transposed(): Image;\n\n    /**\n     * Every pixel in image is moved by (dx,dy)\n     */\n    //% shim=ImageMethods::scroll\n    scroll(dx: int32, dy: int32): void;\n\n    /**\n     * Stretches the image horizontally by 100%\n     */\n    //% shim=ImageMethods::doubledX\n    doubledX(): Image;\n\n    /**\n     * Stretches the image vertically by 100%\n     */\n    //% shim=ImageMethods::doubledY\n    doubledY(): Image;\n\n    /**\n     * Replaces one color in an image with another\n     */\n    //% shim=ImageMethods::replace\n    replace(from: int32, to: int32): void;\n\n    /**\n     * Stretches the image in both directions by 100%\n     */\n    //% shim=ImageMethods::doubled\n    doubled(): Image;\n\n    /**\n     * Draw given image on the current image\n     */\n    //% shim=ImageMethods::drawImage\n    drawImage(from: Image, x: int32, y: int32): void;\n\n    /**\n     * Draw given image with transparent background on the current image\n     */\n    //% shim=ImageMethods::drawTransparentImage\n    drawTransparentImage(from: Image, x: int32, y: int32): void;\n\n    /**\n     * Check if the current image \"collides\" with another\n     */\n    //% shim=ImageMethods::overlapsWith\n    overlapsWith(other: Image, x: int32, y: int32): boolean;\n}\ndeclare namespace image {\n\n    /**\n     * Create new empty (transparent) image\n     */\n    //% shim=image::create\n    function create(width: int32, height: int32): Image;\n\n    /**\n     * Create new image with given content\n     */\n    //% shim=image::ofBuffer\n    function ofBuffer(buf: Buffer): Image;\n\n    /**\n     * Double the size of an icon\n     */\n    //% shim=image::doubledIcon\n    function doubledIcon(icon: Buffer): Buffer;\n}\n\n// Auto-generated. Do not edit. Really.\n","targetoverrides.ts":"/**\n * Tagged image literal converter\n */\n//% shim=@f4 helper=image::ofBuffer blockIdentity=\"images._spriteImage\"\n//% groups=[\"0.\",\"1#\",\"2T\",\"3t\",\"4N\",\"5n\",\"6G\",\"7g\",\"8\",\"9\",\"aAR\",\"bBP\",\"cCp\",\"dDO\",\"eEY\",\"fFW\"]\nfunction img(lits: any, ...args: any[]): Image { return null }\n\n// set palette before creating screen, so the JS version has the right BPP\nimage.setPalette(hex`__palette`)\nlet screen = image.create(_screen_internal.getScreenWidth(160), _screen_internal.getScreenHeight(120)) as ScreenImage\n\nnamespace image {\n    //% shim=pxt::setPalette\n    export function setPalette(buf: Buffer) { }\n}\n\nnamespace _screen_internal {\n    //% shim=pxt::updateScreen\n    function updateScreen(img: Image): void { }\n    //% shim=pxt::updateStats\n    function updateStats(msg: string): void { }\n\n    //% shim=TD_ID\n    export function getScreenWidth(defl: number) {\n        return control.getConfigValue(DAL.CFG_ARCADE_SCREEN_WIDTH, defl)\n    }\n\n    //% shim=TD_ID\n    export function getScreenHeight(defl: number) {\n        return control.getConfigValue(DAL.CFG_ARCADE_SCREEN_HEIGHT, defl)\n    }\n\n    control.__screen.setupUpdate(() => updateScreen(screen))\n    control.EventContext.onStats = function (msg: string) {\n        updateStats(msg);\n    }\n}\n","text.ts":"namespace image {\n\n    export interface Font {\n        charWidth: number;\n        charHeight: number;\n        data: Buffer;\n        multiplier?: number;\n    }\n\n    //% whenUsed\n    export const font8: Font = {\n        charWidth: 6,\n        charHeight: 8,\n        data: hex`\n2000000000000000 210000005e000000 2200000e000e0000 230028fe28fe2800 24004c92ff926400 250002651248a640\n26006c92926ca000 270000000e000000 280000007c820000 29000000827c0000 2a00543810385400 2b0010107c101000\n2c00000090700000 2d00101010101000 2e00000060600000 2f00006010080600 3000003c42423c00 310000447e400000\n3200004462524c00 330000424a4e3200 34003028247e2000 3500004e4a4a3200 3600003c4a4a3000 3700000262120e00\n380000344a4a3400 3900000c52523c00 3a0000006c6c0000 3b00000096760000 3c00102828444400 3d00282828282800\n3e00444428281000 3f00000259090600 40003c425a560800 4100781412147800 42007e4a4a4a3400 4300003c42422400\n4400007e42423c00 4500007e4a4a4200 4600007e0a0a0200 4700003c42523400 4800007e08087e00 490000427e420000\n4a002040423e0200 4b00007e08146200 4c00007e40404000 4d007e0418047e00 4e00007e04087e00 4f003c4242423c00\n5000007e12120c00 5100003c5262bc00 5200007e12126c00 530000244a522400 540002027e020200 5500003e40403e00\n5600001e70701e00 57007e2018207e00 5800422418244200 5900060870080600 5a000062524a4600 5b00007e42420000\n5c00000608106000 5d000042427e0000 5e00080402040800 5f00808080808000 6000000002040000 6100003048487800\n6200007e48483000 6300003048484800 6400003048487e00 6500003068585000 660000107c120400 67000018a4a47800\n6800007e08087000 690000487a400000 6a000040847d0000 6b00007e10284000 6c0000427e400000 6d00780830087000\n6e00007808087000 6f00003048483000 700000fc24241800 710000182424fc00 7200007810081000 7300005058682800\n740000083e482000 7500003840407800 7600001860601800 7700384030403800 7800004830304800 7900005ca0a07c00\n7a00004868584800 7b00000836410000 7c000000fe000000 7d00004136080000 7e00000804080400 a000000000000000\na10000007a000000 a200003048fc4800 a30090fc92928400 a400542844285400 a5002a2c782c2a00 a6000000ee000000\na7000094aaaa5200 a800000200020000 a9003e414955413e aa0000242a2e0000 ab00102854284400 ac00001010107000\nad00001010101000 ae003e415d45413e af00000202020200 b000000814140800 b1008888be888800 b2000024322c0000\nb30000222a140000 b400000004020000 b50000f840207800 b6000c1e7e027e00 b700000010000000 b800000080400000\nb90000243e200000 ba0000242a240000 bb00442854281000 bc00025f70f84000 bd00021f90c8b000 be0011557af84000\nbf000030484d2000 c000601916186000 c100601816196000 c200601a151a6000 c300601a151a6100 c400601914196000\nc500601a151a6000 c6007c0a7e4a4200 c700001ea1611200 c800007c55564400 c900007c56554400 ca00007c56554600\ncb00007c55544500 cc0000457e440000 cd0000447e450000 ce0000467d460000 cf0000457c450000 d000087e4a423c00\nd100007e09127d00 d200003845463800 d300003846453800 d400003846453a00 d500003a45463900 d600003845443900\nd700442810284400 d80000fc724e3f00 d900003c41423c00 da00003c42413c00 db00003c42413e00 dc00003c41403d00\ndd00040872090400 de00007e24241800 df00007c025a2400 e0000030494a7800 e10000304a497800 e20000304a497a00\ne3000032494a7900 e40000304a487a00 e50000304a4d7a00 e600304878685000 e7000018a4642400 e8000030695a5000\ne90000306a595000 ea0000306a595200 eb0000306a585200 ec0000497a400000 ed0000487a410000 ee00004a79420000\nef00004a78420000 f00000304a4b3d00 f100007a090a7100 f2000030494a3000 f30000304a493000 f40000304a493200\nf5000032494a3100 f60000304a483200 f700101054101000 f800007068583800 f900003841427800 fa00003842417800\nfb00003842417a00 fc00003842407a00 fd0000b84241f800 fe0000ff24241800 ff00005ca1a07d00 0001601915196000\n010100304a4a7a00 0201611a16196000 030100314a4a7900 04013c0a094abc00 050100182464bc00 0601003846452800\n070100304a494800 0801003846452a00 090100304a494a00 0a01003844452800 0b010030484a4800 0c01003845462900\n0d010030494a4900 0e01007c45463900 0f0100314a497e00 1001087e4a423c00 110130484c7e0400 1201007d55554500\n130100326a5a5200 1401007d56564500 150100316a5a5100 1601007c55544400 170100306a585000 1801003f65a52100\n1901001874ac2800 1a01007c55564500 1b010030695a5100 1c01003846553600 1d0100304a49f200 1e01003946563500\n1f0100314a4af100 2001003844553400 21010018a4a57800 2201001ea1691a00 23010018a6a57800 2401007812117a00\n25017e080a710200 2601047e147e0400 2701047e0c087000 28010002457e4500 29010002497a4100 2a0100457d450000\n2b01004a7a420000 2c0100014a7a4900 2d0100014a7a4100 2e0100217fa10000 2f0100247da00000 300100447d440000\n3101004878400000 32017e0022423e00 33013d0040847d00 34012040463d0600 350100800af90200 360100bf440a3100\n370100bf48142000 3801007810284800 3901007c40424100 3a0100467d400000 3b01003fa0602000 3c0100a17f200000\n3d01007c41424100 3e0100457e410000 3f01007e40484000 400100427e400800 4101107e48404000 420100527e480000\n4301007c0a117c00 440100780a097000 450100bf42043f00 460100bc44043800 4701007c09127d00 480100790a097000\n49010a0678087000 4a01003f02847f00 4b01003c04847800 4c01394545453900 4d0100324a4a3200 4e01394646463900\n4f0100314a4a3100 50013a4544463900 5101324948320100 52013c427e4a4200 5301304830685000 5401007c16354800\n5501007812091000 560100bf49093600 570100bc48040800 5801007d16354800 5901007912091000 5a01004856552400\n5b0100505a692800 5c01004856552600 5d0100505a692a00 5e010012a5691200 5f010028ac741400 6001004855562500\n61010050596a2900 62010101bf410100 630100049f641000 640104057e050400 650100083d4a2100 660102127e120200\n670100183e582000 6801003a41423900 6901003a41427900 6a01003d41413d00 6b01003a42427a00 6c01003942423900\n6d01003942427900 6e01003a45453a00 6f01003a45457a00 70013a41403a0100 71013a41407a0100 7201001f60a01f00\n7301001c60a03c00 7401782211227800 7501384231423800 7601081261120800 770100b84241fa00 7801040970090400\n79010064564d4400 7a0100486a594800 7b010064544d4400 7c010048685a4800 7d010064554e4500 7e010048695a4900\n7f0100087c020400 8f01003452523c00 920100887e090200 a0013c42423c0806 a101003048483008 af01003e403e0806\nb001003840781008 b501006a5a4a4e00 b601005878585800 d101003845463900 d2010030494a3100 e601003845563500\ne7010030494af100 fa0100742a750000 fb0100304c4a7d00 fc0178147e554400 fd0130487a695000 fe010078744e3d00\nff0100706a593800 18020012a5691200 19020028ac741400 1a020101bf410100 1b0200049f641000 bb0200000c0a0000\nbc0200000a060000 bd020000060a0000 c602000201020000 c702000102010000 c902000202020000 d802000102020100\nd902000002000000 da02000205020000 db02000040800000 dc02000201020100 dd02020100020100 7403000002010000\n7503000080400000 7a030000c0800000 7e03000096760000 8403000003000000 8503020003000200 8603037c12127c00\n8703000010000000 880303007e4a4200 890303007e087e00 8a030300427e4200 8c03033c42423c00 8e0303000e700e00\n8f03035c62625c00 900302003b400200 9103781412147800 92037e4a4a4a3400 9303007e02020200 9403605846586000\n9503007e4a4a4200 96030062524a4600 9703007e08087e00 98033c4a4a4a3c00 990300427e420000 9a03007e08146200\n9b03601806186000 9c037e0418047e00 9d03007e04087e00 9e0300424a4a4200 9f033c4242423c00 a003007e02027e00\na103007e12120c00 a30300665a424200 a40302027e020200 a503060870080600 a60318247e241800 a703422418244200\na8030e107e100e00 a9035c6202625c00 aa0300457c450000 ab03040970090400 ac030030484a7900 ad030030685a5100\nae0378100a09f000 af03003a41200000 b0033a4043403a00 b103003048487800 b20300fe25251a00 b3030c30c0300c00\nb403344a4a4a3000 b503003068585000 b603021aa6a24200 b7033c080404f800 b803003c4a4a3c00 b903003840200000\nba03007820504800 bb03641212227c00 bc03fc2020103c00 bd03182040201800 be03112d2ba94100 bf03003048483000\nc003087808780800 c103f82424241800 c2031824a4a44800 c303304848582800 c403000838482800 c503384040403800\nc6031c20f8241800 c703c4281028c400 c8031c20fc201c00 c903304820483000 ca03000238422000 cb03384240423800\ncc0330484a493000 cd03384042413800 ce03304822493000 d0033c52525c2000 d10310344a3c0800 d203067804020400\nd303120a7c020400 d4030d7009040800 d5031824ff241800 d603384828483800 d70348302221d800 da031c2221a14200\ndb031824a4a44200 dc037e1212020200 dd0300fc24240400 de033e2010087c00 df030c0ac9281800 e003700c621c7000\ne10301092516f800 e2039ea0bea07e00 e30398a0b8a07800 e4030c1214107e00 e503001028207800 e603be9088887000\ne70348544e443800 e803245252524c00 e903285454544800 ea0364524c526400 eb03086458640800 ec03385454542200\ned03306848682400 ee03184a7e4a1800 ef031848ff0a0800 f003483020205800 f10378a4a4a49800 f203304848485000\nf303006080847d00 f4033c4a4a4a3c00 f503003058584800 0004007c55564400 0104007c55544500 020401013f857900\n0304007c06050400 04043c4a4a422400 050400244a522400 060400427e420000 070400457c450000 08042040423e0200\n09047c027e483000 0a047e087e483000 0b0402027e0a7200 0c04007c102a4500 0d047c2112087c00 0e040c5152523d00\n0f043f20e0203f00 1004781412147800 11047e4a4a4a3000 12047e4a4a4a3400 1304007e02020200 1404c07c427ec000\n1504007e4a4a4200 160476087e087600 170424424a4a3400 1804007e08047e00 1904007d120a7d00 1a04007e08146200\n1b04403c02027e00 1c047e0418047e00 1d04007e08087e00 1e043c4242423c00 1f047e0202027e00 2004007e12120c00\n2104003c42422400 220402027e020200 23040e5050503e00 240418247e241800 2504422418244200 26043f2020bf6000\n27040e1010107e00 28047e407e407e00 29043f203fa07f00 2a04027e48483000 2b047e4848307e00 2c04007e48483000\n2d0424424a4a3c00 2e047e183c423c00 2f04006c12127e00 3004304848784000 3104003c4a4a3100 3204007868502000\n3304007808080800 3404c0704878c000 3504306868500000 3604483078304800 3704004058683000 3804784020107800\n3904794222127900 3a04007820304800 3b04403008087800 3c04781020107800 3d04781010107800 3e04304848483000\n3f04780808087800 4004fc2424241800 4104304848485000 4204080878080800 43041ca0a0a07c00 44041824ff241800\n4504004830304800 46043c2020bc6000 4704182020207800 4804784078407800 49043c203ca07c00 4a04087850502000\n4b04785050207800 4c04007850502000 4d04485868300000 4e04783030483000 4f04502828780000 50040030696a5000\n51040032686a5000 5204023f0a887000 530400780a090800 5404003068584800 5504005058682800 560400487a400000\n5704004a78420000 5804004080847d00 5904700878502000 5a04781078502000 5b04047e14106000 5c04007822314800\n5d04784122107800 5e0418a1a2a27900 5f043c20e0203c00 6204027f4a483000 6304087e58502000 70040e107e100e00\n7104182078201800 72043c4a4a4a3c00 7304306858683000 7404001e70180c00 7504001860301000 9004007e02020300\n9104007808080c00 9204087e0a0a0200 9304207828080800 96043b043f043be0 970424183c1824c0 9a04003f040a31c0\n9b04003c101824c0 ae04060870080600 af040c10e0100c00 b004161870181600 b1042c30e0302c00 b20421120c1221c0\nb3040024181824c0 ba047e0808087000 bb04007e08087000 d804003452523c00 d904002868583000 e20400457d450000\ne304004a7a420000 e8043c4a4a4a3c00 e904003058583000 ee04003d41413d00 ef04003a42427a00 d005681020285000\nd105484848784000 d205004830600000 d305080808780800 d405680808087800 d505000008780000 d605080818680800\nd705087808087800 d805784050487800 d905000008180000 da0504040404fc00 db05484848483800 dc050e4848281800\ndd05087848487800 de05582010487000 df05000004fc0000 e005004040487800 e105000878483800 e205487840281800\ne305041c0404fc00 e405485848483800 e50504f820140800 e605485060685000 e705f40424241c00 e805080808087000\ne905785058403800 ea05487808087800 f005087800087800 f105081800087800 f205081800081800 f305000010080000\nf405100800100800 021e7c5455542800 031e007e48493000 0a1e007c45443800 0b1e003049487e00 1e1e007c15140400\n1f1e001079140800 401e7e0419047e00 411e780832087000 561e007c15140800 571e00fc25241800 601e004854552400\n611e0050586a2800 6a1e04047d040400 6b1e00083d482000 801e7c2112207c00 811e384132403800 821e7c2012217c00\n831e384032413800 841e7c2110217c00 851e384230423800 f21e040972080400 f31e00b84142f800 a3207e0a7a120a00\na420a8fcaa828400 a720087e2a1c0800 ab200098a4a6bf02 ac20183c5a5a4200 af20627f22443800 9021103854101000\n912108047e040800 9221101054381000 932110207e201000 9421103810103810 95212844fe442800 \n`,\n\n    }\n\n    // A unicode 12x12 pixel font based on https://github.com/adobe-fonts/source-han-sans\n    //% whenUsed jres\n    export const font12: Font = {\n        charWidth: 12,\n        charHeight: 12,\n        data: hex``\n    }\n\n    export function getFontForText(text: string) {\n        for (let i = 0; i < text.length; ++i) {\n            // this is quite approximate\n            if (text.charCodeAt(i) > 0x2000)\n                return image.font12\n        }\n        return image.font8\n    }\n\n    //% deprecated=1 hidden=1\n    export function doubledFont(f: Font): Font {\n        return scaledFont(f, 2)\n    }\n\n    export function scaledFont(f: Font, size: number): Font {\n        size |= 0\n        if (size < 2)\n            return f\n        return {\n            charWidth: f.charWidth * size,\n            charHeight: f.charHeight * size,\n            data: f.data,\n            multiplier: f.multiplier ? size * f.multiplier : size\n        }\n    }\n\n    //% whenUsed\n    export const font5: Font = {\n        charWidth: 6,\n        charHeight: 5,\n        // source https://github.com/lancaster-university/microbit-dal/blob/master/source/core/MicroBitFont.cpp\n        data: hex`\n2000000000000000 2100001700000000 2200000300030000 23000a1f0a1f0a00 24000a17151d0a00 2500130904121900\n26000a15150a1000 2700000300000000 2800000e11000000 290000110e000000 2a00000a040a0000 2b0000040e040000\n2c00001008000000 2d00000404040000 2e00000800000000 2f00100804020100 30000e11110e0000 310000121f100000\n3200191515120000 33000911150b0000 34000c0a091f0800 3500171515150900 3600081416150800 3700110905030100\n38000a1515150a00 390002150d050200 3a00000a00000000 3b0000100a000000 3c0000040a110000 3d00000a0a0a0000\n3e0000110a040000 3f00020115050200 40000e1115090e00 41001e05051e0000 42001f15150a0000 43000e1111110000\n44001f11110e0000 45001f1515110000 46001f0505010000 47000e1111150c00 48001f04041f0000 4900111f11000000\n4a000911110f0100 4b001f040a110000 4c001f1010100000 4d001f0204021f00 4e001f0204081f00 4f000e11110e0000\n50001f0505020000 5100060919160000 52001f05050a1000 5300121515090000 540001011f010100 55000f10100f0000\n5600070810080700 57001f0804081f00 58001b04041b0000 590001021c020100 5a00191513110000 5b00001f11110000\n5c00010204081000 5d000011111f0000 5e00000201020000 5f00101010101000 6000000102000000 61000c12121e1000\n62001f1414080000 63000c1212120000 64000814141f0000 65000e1515120000 6600041e05010000 67000215150f0000\n68001f0404180000 6900001d00000000 6a000010100d0000 6b001f040a100000 6c00000f10100000 6d001e0204021e00\n6e001e02021c0000 6f000c12120c0000 70001e0a0a040000 7100040a0a1e0000 72001c0202020000 730010140a020000\n7400000f14141000 75000e10101e1000 7600060810080600 77001e1008101e00 7800120c0c120000 7900121408040200\n7a00121a16120000 7b0000041f110000 7c00001f00000000 7d00111f04000000 7e00000404080800 d3000c1213130c00\nf3000c12130d0000 04010e05051e1000 05010609191f0800 06010c1213131200 07010c1213130000 18010f0b1b190000\n19010e151d1a0000 41011f1412100000 4201100f14120000 43011f0205081f00 44011e03031c0000 5a0110140b030200\n5b0110140b030000 7901121a17130000 7a01121a17130000 7b01121b17120000 7c01121b17120000`,\n    }\n}\n\nnamespace texteffects {\n    export interface TextEffectState {\n        xOffset: number;\n        yOffset: number;\n    }\n}\n\ninterface Image {\n    //% helper=imagePrint\n    print(text: string, x: number, y: number, color?: number, font?: image.Font, offsets?: texteffects.TextEffectState[]): void;\n\n    //% helper=imagePrintCenter\n    printCenter(text: string, y: number, color?: number, font?: image.Font): void;\n}\n\nnamespace helpers {\n    export function imagePrintCenter(img: Image, text: string, y: number, color?: number, font?: image.Font) {\n        if (!font) font = image.getFontForText(text)\n        let w = text.length * font.charWidth\n        let x = (img.width - w) / 2\n        imagePrint(img, text, x, y, color, font)\n    }\n\n    export function imagePrint(img: Image, text: string, x: number, y: number, color?: number, font?: image.Font, offsets?: texteffects.TextEffectState[]) {\n        x |= 0\n        y |= 0\n        if (!font)\n            font = image.getFontForText(text)\n        if (!color) color = 1\n        let x0 = x\n        let cp = 0\n        let mult = font.multiplier ? font.multiplier : 1\n        let dataW = Math.idiv(font.charWidth, mult)\n        let dataH = Math.idiv(font.charHeight, mult)\n        let byteHeight = (dataH + 7) >> 3\n        let charSize = byteHeight * dataW\n        let dataSize = 2 + charSize\n        let fontdata = font.data\n        let lastchar = Math.idiv(fontdata.length, dataSize) - 1\n        let imgBuf: Buffer\n        if (mult == 1) {\n            imgBuf = control.createBuffer(8 + charSize)\n            imgBuf[0] = 0x87\n            imgBuf[1] = 1\n            imgBuf[2] = dataW\n            imgBuf[4] = dataH\n        }\n        while (cp < text.length) {\n            let xOffset = 0, yOffset = 0;\n            if (offsets && cp < offsets.length) {\n                xOffset = offsets[cp].xOffset\n                yOffset = offsets[cp].yOffset\n            }\n\n            let ch = text.charCodeAt(cp++)\n            if (ch == 10) {\n                y += font.charHeight + 2\n                x = x0\n            }\n\n            if (ch < 32)\n                continue // skip control chars\n\n            let l = 0\n            let r = lastchar\n            let off = 0 // this should be a space (0x0020)\n            let guess = (ch - 32) * dataSize\n            if (fontdata.getNumber(NumberFormat.UInt16LE, guess) == ch)\n                off = guess\n            else {\n                while (l <= r) {\n                    let m = l + ((r - l) >> 1);\n                    let v = fontdata.getNumber(NumberFormat.UInt16LE, m * dataSize)\n                    if (v == ch) {\n                        off = m * dataSize\n                        break\n                    }\n                    if (v < ch)\n                        l = m + 1\n                    else\n                        r = m - 1\n                }\n            }\n\n            if (mult == 1) {\n                imgBuf.write(8, fontdata.slice(off + 2, charSize))\n                img.drawIcon(imgBuf, x + xOffset, y + yOffset, color)\n                x += font.charWidth\n            } else {\n                off += 2\n                for (let i = 0; i < dataW; ++i) {\n                    let j = 0\n                    let mask = 0x01\n                    let c = fontdata[off++]\n                    while (j < dataH) {\n                        if (mask == 0x100) {\n                            c = fontdata[off++]\n                            mask = 0x01\n                        }\n                        let n = 0\n                        while (c & mask) {\n                            n++\n                            mask <<= 1\n                        }\n                        if (n) {\n                            img.fillRect(x + xOffset * mult, y + (j + yOffset) * mult, mult, mult * n, color)\n                            j += n\n                        } else {\n                            mask <<= 1\n                            j++\n                        }\n                    }\n                    x += mult\n                }\n            }\n        }\n    }\n}\n"},"screen---linux":{"fieldeditors.ts":"/**\n * Image manipulation blocks\n */\n//% weight=70 icon=\"\\uf03e\" color=\"#a5b1c2\"\n//% advanced=true\nnamespace images {\n    //% blockId=screen_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.decompileArgumentAsString=\"true\"\n    //% img.fieldOptions.filter=\"!tile !dialog !background\"\n    //% weight=100 group=\"Create\" duplicateShadowOnDrag\n    //% help=images/sprite-image\n    export function _spriteImage(img: Image) {\n        return img\n    }\n\n    //% blockId=background_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.decompileArgumentAsString=\"true\"\n    //% img.fieldOptions.sizes=\"-1,-1\"\n    //% img.fieldOptions.filter=\"background\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _screenImage(img: Image) {\n        return img\n    }\n\n    //% blockId=tilemap_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.sizes=\"10,8;16,16;32,32;48,48;64,64;16,32;32,48;32,8;64,8;20,15;40,15\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _tileMapImage(img: Image) {\n        return img\n    }\n\n    //% blockId=tile_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.sizes=\"16,16;32,32;8,8\"\n    //% img.fieldOptions.filter=\"tile\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _tileImage(img: Image) {\n        return img\n    }\n\n    //% blockId=tileset_tile_picker block=\"%tile\"\n    //% shim=TD_ID\n    //% tile.fieldEditor=\"tileset\"\n    //% tile.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% weight=10 blockNamespace=\"scene\" group=\"Tiles\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _tile(tile: Image) {\n        return tile\n    }\n\n    //% blockId=dialog_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.decompileArgumentAsString=\"true\"\n    //% img.fieldOptions.sizes=\"15,15;18,18;21,21;24,24;9,9;12,12\"\n    //% img.fieldOptions.filter=\"dialog\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _dialogImage(img: Image) {\n        return img\n    }\n\n    /**\n     * An image\n     * @param image the image\n     */\n    //% blockId=image_picker block=\"$image\" shim=TD_ID\n    //% image.fieldEditor=\"sprite\"\n    //% image.fieldOptions.taggedTemplate=\"img\"\n    //% image.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% image.fieldOptions.decompileArgumentAsString=\"true\"\n    //% weight=0 group=\"Create\"\n    //% deprecated\n    //% help=images/image\n    export function _image(image: Image): Image {\n        return image;\n    }\n\n    //% blockId=colorindexpicker block=\"%index\" blockHidden=true shim=TD_ID\n    //% index.fieldEditor=\"colornumber\"\n    //% index.fieldOptions.valueMode=\"index\"\n    //% index.fieldOptions.decompileLiterals=\"true\"\n    export function __colorIndexPicker(index: number) {\n        return index;\n    }\n\n    /**\n     * A position picker\n     */\n    //% blockId=positionPicker block=\"%index\" blockHidden=true shim=TD_ID\n    //% index.fieldEditor=\"position\" color=\"#ffffff\" colorSecondary=\"#ffffff\"\n    //% index.fieldOptions.decompileLiterals=\"true\"\n    export function __positionPicker(index: number) {\n        return index;\n    }\n}\n","font12.jres":"{\n    \"image.font12\": {\n        \"mimeType\": \"font/x-mkcd-b26\",\n        \"data\": \"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9A9UANwHAAD4AQAI/AcAADhSIAGqCOoIrAS4Aq4BqAi4CKwG6gGqACABOVJQBFQDVAjIB0wAUgFSBgAA/AkACP4PAAA6UgAEdAYUAf4PFAH0AgAA/AEACAAI/gcAADtSAAAkCbQErwJkAhQDxAQAAPwJAAj+DwAAPVIgAJAMiAakBaYEiAawCAAA+AkACP4HAABCUkQIVARUAzYANACsDyQAAAD8CQAI/wcAAENSAAToBKoCrAH4D64AuAcAAPwJAAj+BwAAR1IACP4FKgUqASoB/g0AAPwBAAgACP4HAABKUgAA9g9QAV4JUAn2BwAA/AEACAAI/gcAAE1SAADoD6oCrAqoCugHCADoAw4I6AcIAAAATlIAAFIEUgNMAOQPSgJqBAAA/AkACP4HAABRUhAAWAiEBRIE0wQEB8gCAAL8CAAI/gcAAFRSAAG+BOoCqg2qA6oIvgcAAPwJAAj+BwAAVlIkAKwPrASmBKQEvASsBwAA/AkACP4PAABbUgAA/A8MA+QDFAn8BwAA+AEACPwHAAAAAF1SAADAANgKVgrUB3QAzAYAAPgJAAj+BwAAY1IQCPAEvAbyAbQC5AwAAPwBAAgACP4HAABkUgAAJAisB5YCrAKkDyQAAAD8AQAI/g8AAGVSoAIqCioJ6g8qAb4CoAYAAPwJAAj+BwAAZ1LABz4AqgeqBPoEqgSuBwAA/AAACP8HAABpUogIbARsAgwB/A8MAWoCKAQAAPwJAAj+B2pSAAV8BTwFPgW8A/wBBAF0BQYFdAUEAwAAb1ICAN4PVgXWB1YFVgXeDwAA/AkACP4HAABwUgAArAT8AqwB/A+qAvoGAAD4AQAI/gcAAHJSjAC8D7QFtAX2BbQHtAeMBwAA/AEACP4HdVIQABAO0AP4BfQF5AXoBwAA+AEACPwHAAB/UgAIdgVwBXQD+g94A3ADdgUAAPgJAAj+B4NSSAT8B/wH/gf8B/wH/Af8BwAE+AEACPwHh1IADvgBGATYBn4DbA9sAggE8AEACPwPAACIUoAAfAj0CbQJtAX4A1QBXAn2CVwJVAcAAIlSAACcCcoLyQmwB84FQgUOBPgBAAj+BwAAjVIICOgErALqAEsIogbkBAAA/AEACP4HAACRUjgASAz0A4wClgK8AswPIAD8AQAI/gcAAJtSAAAQCBAEEAKQAX4AEAAQCBAIEAzwAwAAnVIABBQCZAHkABwJAASIA34ACAgICPgHAACeUgAAiAloBAgCiAF+CAgICAz4AwAA4AEAAJ9SBAIEAvwBBAkECRAEEAP+CBAIEAzwAwAAoFIICAgG/gEICAgI+AcAAPwPBAQEBPwPAAChUkAIUAlICSwFNgOkASQJNAlMCUQHQAAAAKNSKAioCKQIogSgA54AkAiICIIIhAcIAAAAqFIAACQE5AMkAqQCJAMACBAH/gAQCPAHAACpUgAE/gOSBJIC/gsABBAD8AgfCBAI8AcAAKpSAAhECVwJZgUkA1wBRAE0CSQJXAdEAAAAq1IAAEgHyAR+AkgCQAcQABAP/gAQCPAHAACxUgAO/AEUDPQDVAjUBwQAEAf8ABAI8AcAALJSAACkCKQElAesBKQEMAAQDv4BEAjwBwAAs1IACLQIlASWBJQD1ACUCJQIlgiUBzQAAAC0UgAIuAiKBIoEiALrAYgIiAiMCIoHOAAAALlSKAioBKgCDAGoAggIUAQQA/4IEAjwBwAAv1IAABQIVAl+BRQFwAM0AR4JBAk8B0AAIADBUgAAtASEBLQHhAS0DAQEEAP+CBAI8AcAAMNSAAA0AhQJXgeUATQJAAQQA/4IEAjwBwAAx1IACAIK+gqqBqoC+gKqAq4Kqgr6BgAAAADJUhAI+ASWA/QAnAfwCBgKmAl+CAgK+AkABMtSAAjuCSoEqgMqCO4LAAAQB/4AEAjwBwAA0lIAAOQCvgL0D74C5AgEBBAD/ggQCPAHAADVUgAAfAl8CfwHeg0IBBgCkAF+CBAI8AcAANhSgACCB/8FqgSqBP8FggwIAv8BCAT4AwAA2VIAACoDqgjqBzYA4AlIBy4BNAk0CSwHRAHdUgAM/gOSCP4HgAFqCTgHrgE4CW4JqgcAAd5SEgiSCKgErgSgAqIBpAioCKYIKAdyAAAA31IAAkQB/AV+A3wDfAF8BX4F/AN8AUQCAADiUgAArAmsCe4FrAWAA/gBGAkOCXgGgABgAORSAAj0CdYF9AfWBfQFAAwQA/4IEAjwBwAA51IAACAB7A+4B+gHqAeoDgAG/AEQCPAHAADyUgAB/g3+Af4B/g3+AQgLmAh+AAgB+AwAAPNSBAh9BW0B/wTsAvwCAAaIAX8ECAT4AwAA9VIADPwDzA/8AewD/AvMDwAM/gMQCPAHAAD4UgAB+g+7B4AHuwe6BwAM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JAAAAK1T+AcEAPQD/AJ8B3QFhAckBPwDJAEUAgAErlMABv4BAgT6AVoD+gECDPoDSgDKD0oAAACyUwAO/gECAOoP6gHqBeIH6gXqBeoJCg8CALNTAA74AQ4E+Ae4BroG/A8IAOgMLAPqBSgIu1NAAEgMSAZIBcgEfgRIBEgFSAZICEAAAAC/UwAAgACABP4GqgWqBKoEqgSqBP4GgASAAMFTIAGoCKgK7Aq6CqgKqgruCqgKqAggAQAAwlMgASgBqAhsCroKqAooCWoErASgACABAADDUwAAAAGwAKQJdgulChQKJgl2BKAEMAFAAchTAAAACAQIHARkBIQCBAGEAmQEHAQECAAIyVMACAQIPAREBJQCFAGUAkQEPAQEBAAIAADKUwAEBAaEAXwIJATEBAQDHAOQAnAEEAQAAMtTAAQIBAgDyAh+BKgEKAMoA6gEaAQICAAEzFMUCDQERALkARwKAAh8BIQDxAI8BAAIAADNUwAAAAz8AyQI5AgkBSQCJAakBWQIBAgAAM5TAAL4AQABAAH+DwAAFAjkBAQDxAQ8BAQI0VMABBACHAuQCPAIXgVQBlAF1ghQCBAIAADUUwACoAEgCP4PJACgCwQIfAaEAeQCHAwACNZTBAT8B5QElASUAvwPAABoCIgFCAPoBBgI11MAAHQIHATcBFQFXAJcAlIF2gQaBDAIAADYUwAIpAiUCIQJvAaGBIYEvAaECZQIJAgACNlTUAZYAVQI8g9UAFQDBAh8BIQDxAI8DAAA21MAAKwIoAb+AaQAAA78AXIMkgOSAnIMAATgUwAA6Ah2CFYPVg9GD1YPXg9WD3gIyAgAAOFTAACoANgHvwfaB/oHkAAMDPQChAF8BgAE4lMIAKoE7Af4B/wH6A/oAPwH7AXqB4gJgAjjUwAAAAD8DwQEBAQEBAQEBAQEBPwPAAAAAORTAAAIAIgPiASIBP4EiASIBIgEiA8IAAAA5VMAAGAAEADMByoCKAIoAugLCAgIDPgDAADmUwAAgAi8BKQEpAPkAKQApAikCLwIgAcAAOhTAAD8AwQB/AkACAQGhAF8BAQIBAz8AwAA6VMAAPwDBAEEAfwBAAD8DwQABAIEAvwBAADqUwAAAAh8BEQCRAFEAEQARAFEAnwEAAgAAOtTAAD8AwQBBAH8AQAA/AMAAQAB/g8AAAAA7FOAAEQARA8kCRQJ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ggCyAIoAAAB9VAAAEADQB1gCWALUAxIA1A9YAEgC0AEQAIZUAAD8AwQB/AEwAPgDlgSUBPQFBAX8BAACi1QAAPwDBAH8ARAACAAOAPgPKAEoASgBAACMVAAClAFUAPwHUgAAAPwHBAIEAgQC/AcAAI9UAAD8AwQB/AQAAtQBFAj0D4QAQAEgBgAEkFQAAPwDBAH8AWAA/A8CANAAEAkQCP4HEACSVAAIHAgUBNQDXABAAFwAVADUBxwIAAgABpVUAAD8AwQB/AEAAJAPkASQBP4EkASQDxAAllQAAPwHBAH8DAAC/gkIDPAD/A8EBPwPAACZVAAA/AMEAfwJAASQA34IEATyB5YIVAgQBJpUAAD8AwQB/AFQAEgCLgK1BDQFTAlEAEAAplQAAPwDBAH8AQAI7ASsAv4BrAKsBLwJAAinVAAA/AMEAfwBQAi8BJQDYAD4CQAI/gcAAKhUIAARAIoPoASsBKMEkgSOBJIEog8uAAAAqlQAAPwHBAL8AwAIrAcgAP4PIACoAyQMAACsVAAA/AMEAfwBAAgoCKgECgPMBQgEaAhACK9UAAD8AwQB/AEQAYgPVgllCXQJXAmED4AAsVQAAPwBBAH8AQAA+AeoAqwCqgKoAvgHAACyVAAA/AMEAfwJAAhOBEwC+AFMAk4ESggAALNUAAD8AwQB/AEACCQFtARvAiQClAVECAAAuFQADPgDCACoB6gCqAoIC/4ICAfKCCwIAAa9VAAA/AMEAfgA/g8CBCIF+gSiBQIE/g8AAMBUAAIEAXQBVA/UBFUE1gRUAVQCdAUEBQAIwVQAAMAPQAReBNIHEgDSD1IEXgRABMAPAADEVAAA/AMEAfwBAAiIBP4CiACIAP4CiAyACMZUAAD8AwQB/AEACCgJpASWBFQCTAHEAAAAx1QAAPwDBAH8AQAIJAkkCb4PJAkkCSAJAADIVAAA/AMEAfwBYAAwD6gEpgSoBDAPYABAAMlUEADUB1QCXgJUAtQJEAz+AhADkgRUCAAHzVQAAPwDBAH8AQAA+A8IAOgDLgHoCQgI+AfOVAAA/AMEAfwBAAgkCM4EBAMEBc4EJAgECNFUAAD8AwQB/AVABAQE/AcEBPwHBATkBAAA11QAAPwDBAH8AQAAfAECAZAPPgFIAUQBJADfVAAA/AMEAfwBAAT8BYIEEALOCAgI+AcAAOFUAAAACP8LrQatBq0CrQKtBq0G/wsACAAA5VQAAEQAfAdsBWwFbAVsB3wARAj8D0QAAADmVAAA/AMEAfwBAAj8D5IAEAz+A5AFVggABuhUAAD8AwQB/AEAAPYPUAFeAVAJUAn2BwAA6VT8AwQB/AEAAHwJVAlUCfwPVAlUCXwJAADqVAAA/AMEAfgMAgL+CZII/gf8DwIA/gMAAO1UgAieCJIIkgSeA8AAnAOUBNQE3AiACAAA7lQAAP4BggD+AIABagEqCb8PagEuASoBCQHyVAAAEgCyD78EigSgBJ4EiQSJBLkHCQAIAPpU/AMEAfwBAADoD6gCqAL+D6gCqgrsBwAA/FQAAPwBhAD8AAAAvAisCK4OrAGsAbwABAABVQAA/AcEA/wDAACoDqgKqgqqCqgKqA4IAAZVAAD8AwQB/AlACCgJngaIBPwGzAVYCEAIB1UAAAAP/gAiDuoKqgpqCqoKqgoqDSIBAAAJVQAA/AMEAfwBAAgoCS4F6gMoBS4JKAkAABBVAAb8AQQAXAdcBVwF/gVcBVwFfAcUAAAAFFUAAPwDBAH8AQAAqge6BK4EqgS6BKIHIAAgVQAA/AMEAfwBAAiUBJYC1AmUCJYMNAMAACRV/AMEAfwBAAj4BJQClgH0AZwClAT0BIAIJ1UAAPwDBAH8AQAE/AdUAjwA+A8EAPwDAAAsVQAA/AMEAfwBAAz4AygIPgdsAGwHTAgABC5VCAAIAHwPXgVcBVwFfgVcBVwFXA9EAAAAL1UAAPwDBAH8AQAA/A+qBKgE/geoBKgEAAAxVQAA/AMEAfwBAAD+B2oFagVqBWoF/gcAADdVAAD8AwQB/AEACPQH7ADmAmUKZAr0ByQAOFUAAPwDBAH8CAAGKACkBLIJNAr0ACQGCAg+VQAA/AMEAfwBAAjUChQK/A8UCtIKUAoQCENVAAD+AYIA/gAIAO4PqAKvAqoKqgrqDwAARFUAAPwDBAH8ASAElAJUCiwJxAdkAJQDAARGVQAAAAD0DxQAfAcWBTQFVAVcBxQA9A8AAEpVAAD8AwQB+AD+DzIAzAHkAxQB5Aj8BwQAT1UAAP4PKgCqB74CgAK+AqoDKggqCP4HAABTVcIAOgCqB6oEqgS6BJAEzgS0BDQHTACEAF9VAAb8AaoHqgKqAroDIAR+AogB6AIYBAAAYVUAAPwDBAH8AQAAKAH+DwAA/g8oASgBAABkVfwDBAH8AQAAfALUAtQCfgJUD1QCfAIAAGVVAAD8AwQB/AEQAEgHRAXyBVQFRAVIB1AAZlUAAPwDBAH8AQAM/gMICGAIiQkKDugJAABqVQAA/AMEAfwBgAj+B0AA+A+MBIoE+A8AAHBVAAD8AwQB+AmOCVIIfgVSAl4B0gFeAAAAeFX8AwQB/AEADKwDLAYsAf4PLAEsArwPCAB8VQAA/AMEAfwBAABsB6QApg+0AKQEpAMAAIBVAAD8BwQC/AMAAKQPtAlWCVQJpA6MAAAAglX8AwQB/AEAAPwA1A/UCPwJ1ALUB/wJAACDVQAA/AMEAfwA4A8UALQCngfUAhQI9AcAAIRVAAFEAVQPVgtUC/wLVAtUC9YL1A9EAQAAh1UAAPwDBAH8DGQCng/0AZQCYAj4CP4HAACJVQAA/AMEAfwBYAD4DwYAUAlUBdQDXAVQCYpVAAD8AwQB/AzwAwgHqAIIDX4CiAVqCAAGlFUAAPwDBAH8DAAC/Ak0CPQKtA+0CrwKAACYVfwDBAH8AQAAvA+wALAP/gCwD7AAvA8AAJpVAAD8AYQAfAjwBVgFNgOUAzwFUAXwCQABnFUAAQQBfA/cC1wLXgtcC1wL3At8DwQBAAGdVQAA/AMEAfwBAAC+BqoEqgWqCKoIvgcAAKdVAAD8AwQB/AEICPQLtAq2CrQK1AscCAAAqlUAAIQIvAisD7wIhAj+CYQCvASsCrwKhAirVQAA/AMEAfwJAAg+BTQDwAM8BQQJfAkAAKxVKAAsAJwP/ADcB9wF3AXcBfwHmgioDyAArlUAAAAE/gVaBVoF/g9QBV4FWgX6BQ4EAACyVQAA/gMCAf4BGAznApAAUAaOAAgI+AcAALNVAAD8AwQB/AEACNQLrAquCqwK1AsUCAAAtVX+AYIA/gAAAPAPkgSXBPIHkASXBPIHAgC2VQAAGAAKB3wFWAXeBVgFWAV8BQoHGAAAALdV/AMEAfwBAAjUC1QIVAZWAVQEVAjUCwAIu1UAAPwDBAH8ARgA2A+0AvIPlAEYCMgHEADFVQAA/AMEAfwBAAh8BVwFXgNeA9wFfAUACc5VAAD8AwQB/AEADP4AqgaqAP4EqgGCDwAA01UAAPwDBAH8AQAIUgV2A4YPlgNSBTAFAAjaVQAA/AMEAfwJAAT8ANQO1gDUBdwIwAcAANxVAAD8AwQB/AFAADQHfgfUB9wH1AfUBwAA4VX8AwQB/AEABMgCVAqiBxAAUgJ0CuQHCADjVQAA3A/UB9QP3A+EAVQC1AsECPwHAAAAAORV/AEEAfwBAATgB2wGeAbuB2gGaAbsDyAI5lUAAPwDBAH8AQAMVAH0CV4HFAGUBTAIAADoVQAA/AMEAfwAAA5EAJADzAKoC6gK6AcAAu9VAAD8AwQB+AA+AWICagRaBVoEQgF+AwAC/VUAAPwDBAH8BCQC/g9UAXQJEAbOAQgGOAgAVgAA/AMEAfwBAAD0DxQC9gVUBVwHFAj0BwFWAAD+AYIA/g74AYQE9AcUAIcEfAOFBnQCBlb8AwQB/AEACPQK1ArWBvQD1AbWCvQKAAAJVgAAgg6+Au4KrgqvBq4M7gquCr4Kgg4AAA5WAAD4AwgB8AUEBXwF/AN8A3wF/AV8BwQDF1YAAAwARg/WC/QL9gv0C/QL9gvFD5wAAAAbVgAA/AMEAfwI+AcEAfQPJgKEAfQPpAAEAx9WAAD8AwQB/ACAD34FUAWID/wHBAD8AwAAMVYAAPwBhAB8CAAH/A60AdwF/AfUAdwPAAAyVgAA/AMEAfwDfAKuD3wC/geSAP4PAAAAADRWAAD8AwQB/AEQBNgD7gL0B/AC7gLUBxAANlYAAPwDBAH4AAQN/gFUAf4N/AMkAOIPIgA5VgAA/gOCAf4BAAz6AVYJUw9WAfoBMgwAADtWAAD8AwQB/AEAAHwP3AteC1wL3At8DwQBP1b8AYQA/AAACF4FVgFSBf4JWgFSBV4AAA5BVgAA/AMEAfwAIA1UAdwHBAvcC1QJdAEADWJWAAD8AwQB+Al8CAwFZAN2ASQDRAV8CQAAaFYAAEACXA9UCdQJfA9gAEwP9Al0CVwPQAJpVgQIxAv8CvwLRAj8D0QI/AvsCvwLBAgAAGpWAAD8AwQB/AnABbwF9AOUD/QPvAPgBQAIdFYAAPwBhAD8BBAE9Af0AvYC9ALUBvQHEAiHVgAA/AMECfwH5As/COQPJA3kA/8PJACgA45WAAD8AwQB/AFACDwGvAa+A7wPvAPkBAAAo1YAAIgH7gWuBW4HWABuB24FrgVuBYgHAAC0VgAO4AG8BPQH9AfsD7gB1Al0BvwFYAgAALdWAAD8AwQB/AUADPwP7An+AfQH7AX8CQAAvFYAAPwDBAH8AQAA9A/yBfoMMgG5CLUHgADCVgAACAL+B/4H/gf+BvgA/gb+B/4HCAUAAclWAAD+AYIAfAH3BqUCBwP9D1cF9QdXBQAAylYABbQD/Av8B/wFngX8AfwD/AXcB5QHAADaVgAA/g8CBAIFggRCBDoEwgQCBQIE/g8AANtWAAD8DwQExAU8BAQEBAR8BIQEBAT8DwAA3lYAAP4PAgTyBJIEkgSSBPIEAgQCBP4PAADgVgAA/g8CBCIFIgWiBHoEogQiBQIE/g8AAOJWAAD+BwIEkgRSBFIFMgX6BRIEAgT+BwAA41YAAP4HAgQKBGoECgUKBfoECgQCBP4HAADkVv4PAgRSBJIEkgT6BZIGkgZSBgIE/g8AAO1WAAD+BwIEKgXqBCoE6gUqBSoFAgT+BwAA8FYAAP4PAgSiBWIE+gViBKIEIgUCBP4PAADxVgAA/A8EBEQFJAVXBZQEdAUUBQQE/A8AAPJWAAD+DwIEkgT6BZIEkgT6BZIEAgT+DwAA81YAAP4PAgZaB0IFygTCBDIFCgUCBP4PAAD0VgAA/g8CBKoEqgT6BaoEqgSKBQIE/g8AAPpWAAD+DwIEEgTSBVIFegVSBdIFAgT+DwAA/VYAAP4PAgQqBSoF+gUqBWoFKgUCBP4PAAD+VgAA/w8BBCkFLQUVBZUFrQYlBgEE/w8AAANXAAD8BwQE9AX0BPwE/AX0BPQE9AUEBPwHBlf+BwIG3gZWBlYFVgVWBF4GwgYCBP4HAAAIVwAA/gcCBD4E/gU6BroGegY6BQIE/gcAAAtXAAD+BwIE6gWqBUoEegWKBW4GAgT+BwAADVcAAP4HAgT+BX4FfgX+BX4FegUCBP4HAAAPVwAA/gcCBGoE6gX6BuoG+gZqBAIE/gcAABJXAAD+DwIM6g1qC3oLagtqC+oLAgz+DwAAE1cAAP4PAgjCC/oL6gvqC+oL+gsCCP4PAAAWVwAA/gcCBP4H9gf2B/YHfgbiBwIE/gcAABhX/g8CBP4E/gX+BP4E/gb+B/4EAgT+DwAAH1cABCAEIAQgBCAE/gcgBCAEIAQgBAAEAAAjV0AIRAhMCSwJNAmkDzQJNAlMCUQIQAgAACdXAAAADPwDBAhECEQI9A9ECEQIRAgECAAAKFcIAYgAyA84AI4IiAiICOgPiAiICIgIAAAtVwAIJAkkCSQJJAm/DyQJJAkkCSQJIAgAADBXAAIQAv4BEAFAAPwHIAggCP4JEAgQCfgEM1cABBAC/gMQAQAM/gMAAAAA/AcAAAAA/g86VwACEAL+AxABAAEiCfIEKgLmCSIM4AMAAD5XAAQQAv4DEAoABIQDfAiEBCQHPAXgBAAIQFcQAhAC/gEQAQAI8A8ACAAI/g8gCCAIIAhCVwACEAL/AZAEAAb+ATIM0gISA5ICcgQCCEdXAAIQAv4BEAEwAAwCKgEoCagICAz4AwAASlcQAhAC/gEQCQAMCAL4AUoISAhICMgHCABOVwACEAL+ARABQAg0CAoG6AEIAkgEOAgAAE9XAAIQAv4BEAFEAUQAJAD8DwQAJADEAIAAUFcgCJAIjgiwCIAI/g+gCJAIjgiQCCAIAABRVwACEAL+ARABAAzoAyoAKgDoBwgICAYAAFdXAAIQAf4BkACACAgESAP+AMgBSAJ4BEAIWlcACD4IAAkACX4JRg8qCRIJKgkmCUAIAABbVwACEAL+ARABAAQkBqQFZAQkBKQFJA4ACF1XAAIQAv4BEAEACP4JAgQCAvoBAgQCBP4JXlcQAhAC/gMQAQAC/AKEAoYCpgqkCJwHAABfVwACEAL+ARABgAkIBHgEigOMAngECAgIBGBXAAR+BQIFPgUCBaAHMAUOBRAFIAVABAAAYVcAAhAC/gMQCQAM+APICX4GSAbICVgIAABkVxAC/gEQAQAA/AMkASQB/w8kASQB/AMAAGZXgAAQAf4AkAAABP4EkgSSBJIEkgT+BAAEalcAABAC/gMQAQIAugCCAP4PggCyAIoAAABvVwAEEAL+AxACQAlECCQI/AskCEQIhAgAAHdXAAIQAv4DEAEEAPQDFAH0CQQI/AcEAAAAglcAAEACVAr0C1QKVAr8D1QK8gtSCkAAAACDVwACEAL+ARABAAQoBMgFCgQIB+gECAQAAIRXiAiICmgKGApMCkgPeAqsCqwKiApICAAAi1cAAEAEygQ+BAoFfgUKBwAFHgVABX4EAASSV0AIaAlICWwJCgkID2gJTAlICSgJQAgAAJtXAAQQBP4DEAIACKAEngLCD4IBvgKgBKAIolcAAhAC/gEQAQAO/AGUD1QEVARSBNIPEACjVwACEAL+AxAJBAj0C1QKVApUClQK9AsECKZXAAAACP4KqgoqCioPagqqCqoK3gqACoAIq1ckBJQF/gUUBQAF1Ac0BR4FBAV8BIAEQACuVwAEEAL8AxACgACoArgDrAqoCpgKqAaoAMJXAAIQAv4DEAkACfwHrAasBfwIrAisCPwAw1cABBAC/gMQAUAIKAkuBegDLAUsCSAJAADLVwACEAL+ARABAAh8CVQJVAn8D1QJVAl8Cc5XAAAQAv4BAAz4AygAKArICX4EiAduCAgG1FcAAhAC/gEQAQAA6A+oAqgC/g+oAqoK6gffVwAAEAL+ARABQACoAugKCAR+AogFaggMBuBXAAIQAv4BEAEAAvwCtAK2D7QCtAL8AgAC91cAAJQC1AKeD/QCEAhIBv4BCAEIAPgHAAz5VwABEAL+AQABJACkB7QEpgSkBLwErAckAPpXAABIAUgF/AR4BXgHeAV4BfwESAVIAQAA/FcAAhAB/gEQAQAAtAe0Aq4LNgg0CPQPNAAAWAAACAH/AAAG/wEFDnUERQT1B0UEdwcAAAJYAAA4CAoK7AqoCq4PqAqoCuwKCgo4CAAABVgABH4FVgV2BVYFXgcABUoFMgU6BUYEQAAGWBACEAH+AYAAMAD8D6oEqAT+B6gEqAQAABVYAAj+CgoKdgoACnwPPgo8CrwK/AoECAAAIVgQABAEfgUABV4FOgcaBXoFOgVeBVAEAAAkWBAEEAT+AxAKgAi+BqoEqg+qCqoKvgqACCpYAAAQBP4DEAMED/4JVAtUC1QJ/g0ECQAAL1gAAJgJnAl8BVwDDgFcAVwHfAlcCVgFAAAwWAACEAH+ARAA/A8EBPwGfAd8BfwFfARAADFYAABUAXQB3gd0AQAA/g9iCLIEMgPuDAAENFgAAggC/gEIAEAJ/gVqA2oFagNqCX4HAAA1WAACEAH+ARAB1ABUAN4HdAVQBVgF1gcQADpYAAEIAf4AgAm+BKoE6gM+ACoA6g++AQABQVgACEAJfgtqCyoKPg8qCqoKagt+C0AJAABKWAAEEAL+AxABAAF8CFYH1QD8B1QIVAt8C0xYCAEIAf8BCAFAAN8BVQXVB5UBVQnfDwAAUVgAAGgIzAp4CkwKKA+ACnwKVApUCvwIAABUWAACEAL+ARABRAAkByYFVAVUBSYFJAdEAFdY2ggCCooKqAosCqwOqgr6CiwKrAqoCAgAWFgAAggB/wEIAQAG/AEcBl0F+gVcBXwHFABaWAACEAL+AZAFBgWqAnoKigk6BsoAJgcAAF5YAACECrQKtAn0CrQKtg70CrQJtAqECgAAaVgAARAB/gEQBTgE9gfUB9QE1Af0BIQHAARrWAAEEAL+AxABAAj8C7wKvgK8CvwLBAoAAHVYAAAADP4H6gT+BWoFawd+BeoF6gX6BAAAflhECHwJfAv+C3wKAA+ICmgKHgr4CAAJwAiDWAACCAL/AYgICAj6BV4DWwFeD/oJCAQAAIVYAAh+C2oL/gtqC34PEAqSCvoKFgpyCAAAilgAAKwIrAruC7wKiA/oCjwKSAr4CAAJwAiTWAABRAX8BH4FfAV8BXwHfAV+BPwERAUAAZdYAAIQAv4BAAF8ANcP1Ar8CtQK1wr8DwAAmVgAABAD/gGQAAQA7AfkB/4G5AZsBeQHAACcWAAAfgSKBnYGAAZWBzwFtAX0BRYFZASAAJ5YAAAQA/8BgAA8AOYPdAV8BWQF5w88AAAAqFgABCAEfgU6BXoFPgd6BT4FOgV+BSAEAACpWBAE/gMQA3AC2grcD/gDAAr+BIgDeAwAAK5YAAD+CAIKfgoACvYPOwp+Cn4K3gp+CAgIs1gAAhAC/gEQAQQI1AfcB94D1APUB9QLEAjBWEAAfgRqBWoFagVuBzQFPAV2BTQFPAUABMdYAAAQAf4BAAF8BMwH/Af+B/wHzAd8BAQEylgAABAC/gEAA/QK1A70Cd4F9ALUBvQIAAjTWAAM/gPKAf4G/ga+B8IHEgf6BvIGtAQAAdVYAAAQAv4BEABEBbwGvAO+C7wHvAHkBgAE2FgABHAFfgV+BX4FfgcuBX4FfgV+BXAEAADeWAAAEAL+AQAAXAKsDjwJbgk8AuwG/AgAAOJYAAAQBPwDAAj8BwQA9A5kCAQO9AqkCgAA5FgAABAC/gEABXwE7A3+C8YB/AfsBfwJBAHrWCAAIAQgBCAEIAT+ByAEIAQgBCAEIAAAAO5YAAIYAgAB/g8AACAIIAj+DyAIIAggCAAA71iACJ4HkAD+DwAAIAggCCAI/g8gCCAIIAjwWAAABAzUA1QBVAHeAVQBVAFUAdQDBAAAAPJYAAjECFQIVAZUAV4AVABUB1QIVAjEBAAA81gACMQIVAhUBNQD3gDUANQHVAhUCMQIAAT2WAAAxAhUClQIVA9UCF4IVA9UCFQKxAgAAPlYAAA0BLwFfAV8BX4FfAV8B/wF3AUUBAAA+lgAAGQINAu0CvQOPgj0DrQKtAo0C2QIAAD9WJQA3Ab8BvwG/Ab+APwE/AL8CtwP1AKAAARZgAhgCN4ECAPoAhgEAAj+CyAIQAiACAAAB1lAAFAASA+sCrYKpA+0CqwKzArED0AAQAAJWQQKRAo0CYQFpAaeBMQG/AaECZQIJAgAAA1ZAAAICAgKdgneB1wFXAVcBVwLfAkECAAID1kACAQKfAl8BfwHfAV8BXwHfAl8CQQIAAgVWQAAQAAgCBAISAROBIoCCAGIAGgAGAAAABZZQABgCFAEjgKIAWgAEAAgAP4PgAAAAQACGlkAAFAISAlECTQFpgSUBkwCRAHAAEAAAAAcWYQARAD0DwQARAhmBLQDFAOUBHQEFAgAAB9ZIADwAywJ6AkICPgHAACoCJYEVAJMAcAAIFkICagEdgVUAswBEADMAyoB6AkICPgHAAAiWcQAfApsCm4L/AtsBWwFdgNsAXwAxAAAACVZAAj8BNQC/A/UAvwAEAhICdYGtASMA4AAJ1kQCBAEEAIQAdAAPgBQAJABEAIQBBAIAAApWUAIRAhEBEQCRAP8AEQBRAJEBEQIQAgAACpZEAgQBBAEEAPQAj4EUAiQARACEAQQCAAAK1lACEgESARIAkgB/gBIAUgCSARIBEAIAAAtWQAAQAhECEQERAREA/wARANEBEIEQghACC5ZAACACPgIiASIA/4AiAGIBogE+AiACAAAL1mAAEgIyAioBJgDzgCICIgImAgoB0gAiAAxWWAIcAROBEgCyAF+AMgBSAJIBEgEQAgAADRZQARICFIEVAREAsABfgBAAkACQARACAAAN1kAAAQI7ASsBKwC/gGsA6wErAq8CoQJAAA4WQAAKACoAKgCuAOsAqgKqAq4CqgGqAAoADlZAACACIgIqAiIBIgD/gCIA4gEqASICIAIOlkAAKgAqACoAJgGjACKCJgImA+oAKgAqAA+WQgJiAhoBAgECAP8AAgDiARoCIgICAkAAERZSAAoAOgHuAKsAuoHqAqoCrgK6AtICAAAR1kAADQAtAe0ArQCrAKuAywINAj0BzQAIABIWSgEqAyoApgIrAiqB6gAmAKoAqgMKAAAAElZAACgAKwCbAIsArwCrg+sAiwCbAKsAqAAS1lAAEQA5A9UBUwFxgdMBVQFZAXkD0QAQABOWRQEVARMBVwFVgV1B1QFXAVMBVQFFAQAAE9ZkABUCFwFfAVcA94BXANcBXwFXAlcCJAAUVkAAFQJVAl+CVQFQANCAyIFHglCCT4JAABUWSABJAkUBawDJAEmAXUBJAGMDxQBJAEgAVVZJAlUCUQJJAUcBQYDBgF8BQQFFAUkCQAIVlkgCSQJEAl+CQAFSANEAyYFJAkcCQQJAABXWSAAJAEUBfwHdAV2BXQFdAV8BRQNJAkgAFpZAAmECawFZAW0A6oBYgNSA0IFSgUACQAAYFkAAAQF/AXuBe4F3APcA+4F7gX8BQQFAABiWSgBKgGqAK4P6gq7CqoKugqmCqYPKgAqAGVZAAAACXwJDAVkBXYDJANMBQQFfAkACQAAZ1kACXwJBAVsBWwFLAN+ASwDLAOEBfwFAAloWQAALgkgCX4FAAUkA5IBFgORBf0FFQkQCWpZAABUATQB/AP0B/YB9AX0BfQD/AGUARQBblkAABoAmg/+Cv4K+w/6CvoK/gr6D0oAAABzWQAAEAgQCdAIMAkeBRICEAKQBXAEEAgQCHRZiAj4BA4DyAE4CAAMNATEA8QCPAQACAAAdlkICPgMDgOIA3AIBAf8AAQEPAgkCOAHAAB4WQAA+AgOBYgDeAwAAEQARAD8D0QARABAAHlZAAj4DA4DiAF4BgAA/AcQCP4JCAj4CAAGfVkACOgMHgOIA3gEAABECEQI9A9MAEQAQACCWQAACAj4CA4F6AMQAPwPBAQEBAQE/A8AAINZAAj4CA4FiAN4BAAAxAdECEQIRAj8CAAGhFmACIQIvAqkC6QKpgSkBKQHpAikCIQIAACGWQAAGAOAAP4PAACQCHAJHgYQA/AEEAgQCIdZCAj4BA4DiAF4AAAERAREBEQERAT8DwAAiFkACPgMDgPoAhgEcAFEAUQJZAlcDMADAACSWQAI+AwOA+gDGAzwA0gASgBKAEgA+AAAAJNZCAj4BI4CyAE4AgAIaASoBT4CqAVoBAgIllkABPwEBwPEAjwAAAwiAqIBfgChASECIASZWQAA6AieBsgBOAIACDwEgAT+AgACjAEwAJ5ZEAjwBA4DiAN4AAgI4A9cCEQI/A9ACAAApVkAAEQIVAbEB2QGbAJEAmIF8gRKBEAIAACoWQgA+AkOBYgDcAQAAAgP+ABOCEgIyAcIAK5ZAAj4DA8D+AgADP4DEgDSB5IIkgheCAAGs1kAANAIPgUQA/gEAADUAwoI+A8IANgBCAK5WQAI+AgOBYgDeAAADEgCSAH+D0gBSAJIBLtZFAlcCVwLXAvcBX4FXAVcB1wFfAkUCQAAxlkACPgJDAb4BQAA/AdEBFQFVAxEDPwHQATJWQAA6AgfB8gBOAbAASQAJAD+DyQA5AMAAMpZCAj4CA4H6AEQBngARA/EAP4PRADEBwAAy1kAAOgNHgOIAXgCAACwD64EoASsBDAHQADQWQAA+AkOBugDEAj8DyQJJAkkCfwPAAgAANFZAAD4DA4DiAN4BAAAkA+QBP4EkASQDwAA01kAAOgIHgXIAzgAIAicCJAI/g+QCJAIAAjUWagIrAisC5wKzAb8BIwCmgWqBKoIqAgAANpZAAj4BA4D8AgMCYAE/gMAAP4HQAicCIQG3FmgCKwIrQquC6wGvASsBq4FrQSsCKQIAADlWRAI8AQeA5ADeAQAAagHfgkoCTgJKAUkAOhZAAj4DI4DcAQEAOwMrAL+AawCrAS8CQAI61kAAPQMjwLkARgA/g+SBJIEngeSBPIEAATsWQAI+AQPA+gBEAD+BwIE8gSeB5IE8gQCBPtZAAD4DA8D6AEQAv4PAgXiBLoFAgT+DwAA/1kAAKIIlArUC8AGpgSUBIwGlAWkCKwIAAABWgAO+AEIBNgFeALYAwgI/gQIA8oEKggABgNaAAj4CA4H+AQAACQJJAm+DyQJJAkgCQAABFrICMgIrgqYC9gG/gSYBpwFqgTqCMgIAAAHWgAI+AQOA8gBOAZQADQPHAAUADIPUgCAABhaAAj4BA4D+AYAAPwPVARWBNQBVAO8BIAEG1oAAPANHgP4AAQIcAlcB+QBZAN8BcAJAAkcWgAA+AyOA3gIAgb+AZII/gf8DwIA/gMAAB9aCAj4CA4F6AMYAMAPvAK0ArQKtAr8DwAAJVoACPgMDgP4AgAKlAj8DxIE/gKQBVYIAAYpWgAI+AgOBcgDOAj4CJQElgP0D5wI8AgABDFaCAj4CAwFiANwCAwJVAfUAVQDVAVcCQAJNFoAAPgMDgP4APIPBACgAfoHogACCP4HAAA2WoAIwgj+CtoL/gaiBsgGtAWUBKwIpAgAAEZaSAhqCQoLYAscBUwFXAUuBSwHXAlECQAASVoAAPgMDgP4AAAITAw0A0YA9AcUCPQJAARaWgAA6ASeAsgBMAC+B2oFagVOBZoHKQAoAGZaAADoCJwGyAEwBoQDvAD8D7wAvASgAwAAdFpAAF4JQgkyC44F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TAVEBQwJAAC/W4AATADkBxQABADWB1QFdAVUBVQF1AcAAMJbAABMA0QI9A9UAEYLFAh0BJQD1AQ0CAAIxFsAAIwAxAfUBbQFtgW0B9QA1AjED4wAAADFWwAIDAjkC7QGtAb2A7QCtAa0BuQLDAgAAMZbAAAMAaQHhATkBE4HpASUBEQEFA9kAAAAx1tACFQE1ANUANQHVggECHQLVAvUCFQIAATMWwAADACEB/wF3AXeB9wF3AX8BYQHDAAAANJbAACMBLwCvAH8BL4IvAr8CLwJvAKMBAAA01sAAIQP9AD0AvQC9gP0AvQC9Ab0BIQHAADbWwAIDAjEC9QL9AfWA9QD9AfUC8QLDAgAAN1bAAAsAQQB/APECX4IfAt8BXwFfAvMCQAI3lsAAAwK5Ar0CvQG9gP0AvQG9ArkCgwKAADfWwAATAlkBbQB9AmGD5QBpAPUAzQFnAgAAOFbAACMAIQF/AX8A/wD/gH8BfwH/AGMAoAA4lsACWwHRAH0DwQA9gn0C/QF9Af0CKwJAADlWwABXAlcCbwKnAt+B0QGvAR8BXwBDAEAAOZbAAAUCNQH/Af8A/4D/AP8B/wH3AcUCAAA51sAAAwBxANUA9QLagvsD2QDRAPUAwwDAADoW4AEtAK0CrQL9AK2DrQC9Aq0C7QKhAIAAOlbAAFMAWQP9AtUC3YPVAtUC/QLVA9EAQAB61sAAAQB9AT0AvQA5gLEAfQA9AX0BIQDAADsWwAIDAjEC9QH1AfWA8QD1AfUC8QPDAgAAO5bAACMCEQI1AP0CtYO1AL0AtQLRAiMCAAA9VsAAFQI9AfUAfQK1AcGAPQHdAt0C3QOAAT2WwAEFgjWB94H1gPHA+4D7gP+B+4HLggAAPhbAAAIACgAaACIAQgICAgICP8HCAAIAAgA+VsACCQMRAKEAXwCAALQABAJEAj/BxAAAAD6W6AAqACoAKgGqAS8AKgIqAjoB6gAqACgAPtbAAAAAUQBVANUA1QBVAlUCVQHfAEAAQAB/FsAAAABPAFUA1QFVAFUCVQJVAdcAUABAAH+WwAIKAxIAo4BaAYIBFAA0AEQCP4PEAAAAP9bQAREBVQDVAH0BV4BVAlUCdQHVAFEAQAAAVwAAKQEpAS/B6QEpAQAANAJEAj+BxAAAAACXAAAAgF+AVYFVgF/CVYJVgnWB34BAgEAAARcgAT+BKoC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/g8QAP4GkAVWDAAA6lwAAPgDAAL+AwAC+AfAAKYPkgiwCMYPiADtXPgDAAL+AwAC+AMAAO4PoAK+AqAK7AcAAPBcAAD4B/8HAAT8BwAAJAVXBdoPVgVSBRAE9lwAAAAO/ARcBVwHXgVcBVwFXAFcCUAHAAD7XAAA+AP+A/gDAAAoBYwFygKIAi4FaAQAAANdAADwA/4D8AMAAFQDxAD+B8QAVAFEAgAAB10ACXwFGAFYCVgJXA9YAVgBWAUYBXwJAAAOXfgHAAL+AwAC+AMAALQDrAKuCzQI9AcgABRdQAAsAOgPWAVYBV4F+AdYBVgFWAVcBQAEFl0ADP4DDAisCqwKrgrsDqwKrAqsCq4KCAgXXQAAAAD2DxQAVAZ2BtYHdAZ0BhQI9gcAACldAAAMDOwDqAnoDw4ACAjoB6gCqArsBwAALV0IAWsBWgHKB0oBSwECDPoDSgDGD0cAAABKXQAA8AP8A/ADDADsBgwB/A8MAWwCqgQABEtd/AMAAv4DAALwBf4Dyg+qCq4KqgruDwAATF0gAOwPKAUoBegPDgDIDCgCqAEoBqwIYABQXQAA5g8cANwJXAn+D1wNXA2MCPwHBggABmldEACWD/QA9AD0B/QF9gX0BfQH9AiWDxAAi10AAAAA8Af+A/AJ/ARcDV4DXAtcCUAHAAC6XSAAkwCqAqoEsgcHAP4FrgWuAa4F/wUACM1dIAl8C3gFeAV4Cw4A+ATYA/gD3AbQBvAC3V0ACAAM/AMAAAAAAAD4BwAAAAAAAPwPAADeXQAAcAgABv4BIAAAAP4HAABwAAAA/g8AAOFdAAhECMgHAAT4CAQLcAiMCSAK2AgECwAI4l0AAAAF+wWoA6oD/Q+oAaoDrgX9BQAFAADjXQAAAAn+BagFqgP8D6gBqAOsBfoFAAkAAOVdAAQEBAQEBAQEBPwHBAQEBAQEBAQABAAA5l0AAAgMCAPICHwISghICMgPSAhICEgICAjnXQQCBAL8AwQBAAEEAHwERAhECEQMxAMAAOhdAAAAAP4PkgSSBJIEkgSSBJIE8gUCBAAA6V0EAgQC/AEECQAE/AMEAHQABAD8DwAIAAbrXQAFhAR0BIQEBAT8BwQFhAR0BIQEBAUAAO5dgAioBKoDrgioCfgJqA+uCaoJqAmACAAA8V0AAAAA5AckCCQIJAgkCCQIJAh8CAAHAAHyXQAABAD0B0QIRAhECEQIRAhECPwIAAYAAvRdAAAAAPwHRAhECHwIRAhECEQI/AgABgAA910AACABKAHoB74KqAqoCr4K6AuoCCAFAAH7XQAAIAGqAOwGuAquCrgKKAtuCKgEIAEAAP5dAAD4AwgACAAIAAgA/g8IAAgCCAL4AwAAAV4AAAQA5AMkACQA/A8kACQCJALiAwIAAAACXgAACADoAygAKAD+DygAKAIoAugDCAAAAANeAACIAYgA6AdcAEoA6A9IAEgESATIBwgABV4AAPwIAAb+AQAA+AMIAAgA/g8IAAgC+AEGXgAA+AEIAP4PCADwDf4DIgACAP4PAAgABwheAAD4CAAG/gEAAPQDFAAUAPwPFAAUAvQBDF4AACgBKgGqB+wAtACkD6wAqgSqByAAAAAQXgAA/AD/DwQA/AEACP8HIARoAKYDIQQgBBVeAAD4AwgA/g8IAPgD8A+IBI4EiAT4DwAAFl4AAPgDCAD+DwgA+AOAD0AEfgRIBMgPCAAYXgAADADEB1QATABOAOYPRABUBMQHDAAAABpeYACuB64BrgGuAa4PrgGuBa4FLgNgAAAAHF74AwgA/g8IAPgDAAh8BkQBRABEA3wMAAAdXgAA5ACkB7wApADmD6QAtASsBKQHZAAAACVeAAD4D6wEqgS4BwAA+AMIAP4PCAD4AwAAJl4AAGQApAeuAKQA7g/uD6QApAQuB2QABAArXgAA+A+uBKkEuAcCAPIDEgD+DxIA8gMAAC1eAAb8AQQAFAd0AVQB1gdUAXQFFAUUBxQALl4AANQA1AZ+AVQBVA8AAX4BAgVeA2IAAAAvXgAA5AAkBz4BNAH+DzQBNAU+BSQG5AAAADBeAAD4CAAG/AFAALwHvAD8D7wAPAdgAAAAM14AAPgA/g8IAPgBAAj+B1YE1gBWA1YFQAk2XgAA9AC0B64AvgD0D7QAvgSkBK4HVAAUADheAAAYAAoHfAFYAVgB3gdYAXoFCgcYAAAAPV4AAPgBCAD+DwgA8AGeD8IKygrCCt4PAABFXvgBCAD+DwgA+AEAD7wKrA+sCqwKvA8EAExeAAD8AQQA/w8EAfgF7wKVAfUAlQevBAACVF4AAPwA/w/8ARAErwS/Ba8CvwKvBb8EAARVXgACRAH8B34BfAH8B3wBfgX8BXwDRAEAAWFeAAD4AQgA/g/4AEAAPA+UCrwPsgpaD0AAYl74AQgA/g8IAPgBAAT0BvQG9gf8BvQGEARjXgAAegA4B34BOAG6DxABTgU0BVwGxAAAAGteKAA8DvwD/gP8A+gPwAPUA+QL3gsEDgAAcl5AAEQARABEAEQA/A9EAEQARABEAEAAAABzXoAAhAC0AIQAhAD8D4QAhAC0AIQAgAAAAHReAAAwAQgB5gElASQB/A8kASQBJAEkAQAAdl6ACIgIiQb6AYgAiACIAIgA/g+JAIgAgAB4XpAAlAK0AtQClAKeD5QC1AK0ApQCkAAAAHleAAD8AqwCrg+sAvwCEACsAOIPpACIADAAe14AADAGrAViBDAFEA4EAAQIBAgEDPwDAAB8XggEMAbOA0ECOAsABAgD/wAICAgI+AcAAH1eAAD8ByAFvAXwBe4G/gcQBOwFAAT8DwAAfl4AAK4IuQSkA4AKngjgBY4G+Aa0CKAMAAB/XgAAAAz4AwgACAAIAA4ACAAIAAgACAAIAIFeAAz8AwQAJAAkACQIJgjkByQAJAAkACQAg14AAAAO+AEIBAgGyAUsBAgEiAQIBQgGCAiEXgAAAAz8AwQIRAhFCPYPRAhECEQIBAgAAIZeAAz8AwQIRAhEBEUD5gBUAUQGRARECAAAh14ADPwDBAD0D0QIRQQGAPQHhAhECCQIJAaKXgAG/AEEBCQCJAGlAPYPZACkASQCJAYAAI9eAAz8AwQAlACUCNYI1Ae0ALQClAGEAAAAkF4ADPwDBAgEBPQDNAE2ASwBLAHkAQQAAACTXgAM/AMEAJQC9AKeAp4C1A+UApQClAIAAJReAA78AQQEdASEBRUE5gQEBoQFdAQEBAAAlV4ADPwDBAAECPQPlASWAPQMlAGUBpQIBAaXXgAM/AMEAAQPBAkECfYJJAkkCSQPJAAAAJleAAAADPwDBADkDyQJJgn0DyQJJAnkDwAAml4ABvwBBASsBKwErgL+AawBrAKsBPwEJAScXgAM/AOEAEQA9A8EAKYAJAkkCPQPJAAAAJ5eAAz8AwQIJAYkAfQEJgTsBywJpAikCAQGn14ADvwBBAQ0AiQJ5gW2BqQGpAW0BCQIAACmXgAG/AEEBJQElAT0BdYC1AL0BZQEFAQAAKdeAAz8AwQIRAk0CUQJ9g9ECTQJJAlECAAAq14ADPgDCADoA+gD6APsB+gD6APoAygCAACtXgAM/AMECFQHdAbUBQYIVAr0C1QKVAoAALVeAAz8AwQAVAD0B9YC1AfUCtQK9AtUCFQEtl4ADvwBBAQkByQA9A6mAKQO9AAkAiQMAAC3XgAG/gECBKoCqguqCPsHqgKqBvoFIgkAALheAA78AQQA9A/0A/QD9g/0A/QL9AukDwQAwV4ADPwDBAj8B6wGrAL+CwQA9AsECPQHAADDXgAM/AMECEwF/ANOAUQB3AdsCWQJFAUAAMleAAz8AwQIdAV0A/QPdgH0D3QD9AVUCAAAyl4ADPwDBAj0D7QItAb2DAQA/A8MAPwHAADTXgAM/AMEAPQLvAu8D/YDBAD8DwwE/AMAANZeAAT+A4IAlgiOBmYHvwZiBW4FRgKeAIIA314AB/wABAL0A7QDtAe2A/YHBAb8AawE/APgXgAM/AMMAOQPvAKmC+4PRAj0BSQD5AwAAOJeAAz8A0QALAusCn4ERANsBfQHtAkUAAAA414ABv4BAgjqBfoF+wX7AfoB+gPqA+oFIgTzXgAAgA98AAQLfA/+DyQEdA10CXQDdAUAAPZeBAi0BKwDZAQABfQJBAkECfwJJAkiCSAJ916ECDQHrAVECAAKJAokCvwLJAoiCiAKAAD6XgIIcgwuA+IECAWqCaoJ/wuqCaoJvgkICf9eAAAQABAA/g8QBBAEEAQQBP4PEAAQAAAAAF9ACEQIRAb8AUQARABEAEQA/A9EAEQAQAABX5AIkAiQBMwDiwCIAIgAigDqD4wAiACQAAJfAAAACR4FqgMqASoBKgEqAaoPLgEgAQABA18ECSQJJAW0AywBJgEkASwBvA8kAUQBBAEEX0AJVAlUBVQDVAF8AVQBVAFUD1QBVAFAAQpfAAl6CTgFPgN4AXoBEAEsAbYPNAFMAQQBD18ICEgESATIB0gESAQIAn4AiAMKBAoICAYTXwAAAADyAJIAkgCSAJIIkgiSCJ4HgAAAABVfAADEAKQIpAikCLwHAAAAAAAA/A8AAAAAF18AAIgI6AioBvwBqACoAPwPqACoBLgDAAAYXwAB5AikCKQIvAcAAAAH+AQEBIAEAAcACBtf8giSCB4HQAD8ByAIEAj/CRAICAn4CAAGH18AAAAEyASqAqwCqAH4D6gArASqBLgDAAAgXwAA8giSCJ4HAABACP4PQATQBEgBRgZACCVfBAHkCKQIvAigBxADzAgICPgPCADIAAgD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iAAACqIJcgQqA+YIIg7gAQAAbWKIAIgI/weIAEAIAghCDv4JQghCDv4JAAhuYggBiAj+D4gAIAhQBE4DwABCCE4I8AdgAG9imACYCP4PWAAACPgPAAgACP8PIAggCCAIcGKIAIgI/g+IAEAIEATQAz4AkAcWCBAIEAZxYogAiAj+D0gAAAf8AMQEBAU8A5AEcAgAAHNiiACIDP4DiAgADvwBZASkBSQCpAVkCAAIdmKAAIgI/g9IAAAISARIA/4ASANIBEgIAAB5YogAiAj+D4gAAAD+DyAEAAD+ByAIGAgQBnxiAAGIDPwDiAgADPwDBAD0BxQIFAn0CAAEfmKIAIgI/g9IAAAIEAQ+AtADEgXUCBQIEAZ/YgAAEAQQA/QABAqkCvQHrAIMAuQAIAMQBIBiiACICP4PSAAACGgEqAU+AigF6AQoCAAAhGKIAIgI/g9IAAAIeAgABP4EAAKMAVAAAACKYoAAiAj+B0gAAAD8B0QIRAh8CEQIRAj8CJFigACICP4HAAD8BwICAgD8DwQABAT8AwAAkmKIAIgI/w9IAAAAIggqCOoPNgCmAGIAAACTYoAAiAj+D0gAAA78AQQA/A8CAP4AAg8ACJViiACICP4HSAAACN4EQgVCAt4FUAgICAAAlmKIAIgI/g9IAEgAAAEiAUwBAAH+D4AAgACXYgAAiACICP4HSAAADOgDLgAoAOgHCAgABphiiACICP4HSAAADv4BIgAiACIA4g8iACIAmmKAAIgI/g9IAEAIBASkA3wA5AckCCQIIASbYgAAiAj+B0gAAA//APgHAAn4CA4K+AkABJxiiACICP4PSAAADIgDfgioBSgC6AUoCAgInmIICYgI/g+IAAAM/ANEAEQAxAFEAnwMAAigYogAiAj+D0gAAAD8DwQIFAvkCLQJBAoACKFigACICP4PSAAAANgHhAiCCEQICAgwBiAAomKIAIgI/g9IAEAAEADIBycIJQnICBAGEACkYogAiAj+B0gAAAz4A0gASgBKAEgA+AAAAKViiAiICP4PSAAAAP4PIgDyDDIDMgXuBAAIq2IIAYgM/gOICAAO+AHIBX4GSAXIBFgIAACsYoAAiAj+D0gAAACwD6wEogSgBKQEmA8gALFikACQCPwHUAAAALAHrgioCOgJCAn4CAAGtWKIAIgI/g9IAAAA/A8kBCIAPgziByIIIAa5YogAiAj+D4gAQAQIAkgB/g/IAEgDSAQAALxigACICP4HiAAAAPwBpACkAPwPpACkAPwBvWKIAIgI/gcIAOAPkASQBP4HkASQBPAPAADCYgAAkAj8B0AA6AyoAv4BqAD+D6gAuAcAAMRiiACICP4PiAAIAIAIiAiKCPoPiAiICAgIxWKIAIgI/g9IAAAI/AkkCSQJJAkkCfwJAAjGYogAiAj+B4gAAAz8AyIAogDiDyIBIgIAAMdigACICP4HSAAAAP4DIgKqCiIKIgb+AyACyWKAAIgI/g9IAAAEKATIBQoECAfoBAgEAADLYgAAiAj+B0gAAA/+AMgHAAn+CggK+AkABMxiCAGICP4HiAACACwBIAH+DyABLAEiAQAAzWIIAYgI/geIAAAA+A+IBI4EigSIBPgPAADQYogAiAj8B0gAAAi8BKQCpAGkCKQIvAcAANJiiABICP8PSAAAAP4PkgSSBJIEkgTyBAIE02KIAIgI/g9IAAgBgADkD1wERAREBMQPAADUYogAiAj+D0gAAAyIA34IqAUqAqoFaggICNZigACICP4HiAAgAJAAzgdICOgLSAjoCwgI12IAAIgI/g8AADgD5gIwCxAF8AMeCPAHAADYYoAAiAj+D0AAEADIAy4BKAHoCQgI+AcAANligACICP4HSAAAALwHIAT+ByAEIAS8DwAA2mIAARgJ/geYAAAImATUA5IAkADUD5gAoADbYoAAiAj/B0gAAACiD5oEhgSiBKIEngcAANxiAACUDJQC/AGSAAMAKAEqAf4PKgEqAQAB3WKIAIgI/gdIAEABFAFUAfwPVAFUAQQBAADfYoAAiAj+D0gAAAT+AwABvAwAAsABPgEADuBigABICP4HYAD+DIgDcAT8CQQI/AsACoAJ4WKIAIgI/g9IAAAO+AEIBIgHbgQIBQgFCA7iYoAAiAj/D4gAAA6QAX4MEATyB5QIVAgQBONigACQCPwHkAAABOgCuAqsCOgPiACIAggE5WKAAIgI/gdIAAAM/gOSAJIA/g+SAJII/gfmYoAAiAj+B4gAAASSBJYEkASYBJYEEAQAAOdiCAGICP4PiACAABgASAhICMoPSABYAAAA6GKAAIgI/geIAAACHAnQBH4FUALUBVQIEAjpYogAiAj+D0gAAAKkApwC1A+cAqQCJAIAAOxigABICP4PSAAAAJIPkgj+CJIIkgiRDxAA7WKAAIgI/g9IAAAEUATQBxAE/AEQBhQMAADvYoAAiAj/D0gAAAnSCCIK+gsmCNIIEgkAAPFigACICP4PSAAACIgE/gKIAIgA/gKIBIAI82KgAKgCagJsC3gL7gcoAygDbgKoAqAAAAD0YgABiAj+B4gAIAgYCSQJ4g8kCQgJMAgAAPdiAAEQCfwHkAAAACgBqAP8CqgKuAqoBiQA/GIAAQgJ/gfIAAAIiQT6A4gAiAD8D4sAgAD+YogAiAj+B0gAAACYD4QEogSiBKQEiAcwAP9iCAHIAfgB/AX6BfoD+gH8AfgB+AGIAQgBAWOQAJAI/AdQAAAAqAKoArwIqAjoB6gAIAACY4AAiAj+D0gAAAgkCSQJvg8kCSQJIAkAAAdjiABICP4PSAAAAN4HZAVkBWQFYgXiBxgACWMIAQgN/gMICEAIXAjEBXcGRAPEBFwIAAAOYwABEAn8B9AAAACoArgDrAqoCrgKqAagABFjgACICP4PSAAACYgE/gMAAP4HQAicCIQGFmOAAEgI/g9AAAQAVARUC0YJ1AhUCAQGAAAZY4gCSgIsArgKqgrsB6gCiAI+AkoCSAIAABpjAAAUAtQD/gOUC4AHtAOeA4QDPANAAyACH2MAAQgJ/gfIAAAIqAiIBv4BiAOoBIgIAAAgYwAAiAj+B0gAAAikBKYDvAC0D8wIrAiABCFjiAGICP4HSAAABC4FIAU+BSAFKAXmDwAAI2OAAIgI/g9IABAAWAlWCfQHXAFUAfABQAAkYwAAiAj+B0gAAAhEBEwDNgAkAFwPRABEACVjAACICP8HAACWAtICsgKaAtIPkgKWAgACKGOAAIgI/gdIAEAJLAUrA+gDKgMuBSgJAAgqYwAAiAz/AwAIkgb+AZII/gf8DwIA/gMAACtjgACICP4HSAAgCBwJYAn+DyAJHAkgCUAAL2OAAIgM/wOICAAO/gHCD1IE0gVSAVIOAAg6YwAAiAj/D0gAAgw+A+IEAAgiCf4JIgkiCT1jgACICP4HQAAQCPgIlASWAvQBnAeUCPAIQmNIAEgI/g8oACAAqge+BKoEqgS6BKIHIgBFY4AAiAj8B0gA4A+kArQC9A+sAqwK5AcAAEZjgACICP8HAAD+DwIEUgT6BVIEAgT+DwAASWOAAIgI/g9IAAAMvAMkBOQPpAikCLwIAAhMYwAAiAz+AwAIvAakAbwIAAf4AQAI/gcAAE1jiACICP4PSAAAAX4BagFqAeoPagF+AQABTmMIAQgJ/geIAAAA4g+sAqACvAKgCuwPAABPY4gASAj+D0gAAAS+BKoEqgeqBKoEvgQABFBjiACICP4HSAAAAO4PqgKqAqoKqgruDwAAVWMIAYgI/geIAAAA6A+oAqgC/g+oAqwK7AdcY4gASAz+AwAIvASsBawG/gSsBqwFvAgABF5jgACICP4PSAAACJQElgLUAZQIlgw0AwAAX2OAAIgI/gdIAAAI4AkuBCoCqgEqBC4I4AthY4AAiAj+D4gAIASYBSQEogUkBAgH0AQAAGJjiAz+A0AIEAj4BJQClgH0AZwClAT0BIAIY2MAAQgJ/geIAAAG/ASEBpYEhAa8CIAHAABnY4AASAj/B0gAAABqAr4Cqw+qAuoCqgIAAGhjiACICP4HSAAQAEwHUgV6BVIFRAVIB1AAbmNAAEgI/g9IAAAH/gAyB7IE8gSyBL4HAAByYwABEAn8D5AABALUB3AJXA1QDVQO1AhAA3ZjAACICP4HCABACfQJVAn8D1QJ8glQAQAAd2OAAIgM/wNICAIIqgaqBKoE/w+qCvoKIgh6YwABEAn8BxAAQAQoARgJTA9YASgBSA1AAHtjgACICP4PSABABwgAJAcqCCIJZAgoAwgEgGMAAIgI/gcAAPwPFAD0DwAAFA7qAQgGOAiCY8AARAb/AQAM/gMCAIIPggT7BJIEkg8CAINjgABECP8HBABgALUHtQD1D7UAvwTgAwAAiGOAAIgI/gfIAGAIaAikBKoHogS6BmoFAAiJY4gI/gdIAAAC+AKoAqgCrg+sAqwC/AIEAoxjAAAcAs0C/wL8Cv4H/AL8Av8CjQKcAgAAj2MAAQgJ/gcYAIwCqgLoA6gCqAqICPgHAACQY4gAiAj+D0gAAADQD0gFBgVEBFwFxA8AAJJjiACICP4PSABAAAgBKAHWDvwHKAEoAQAAlmMAAIgI/geIAAAA5A8UAMYIdAWkA+QEJAiYY4AAiAj+BwAA/g8KAOoOigjqD4oI7g4AAJljAAEICf4HiAAAAqwKpArqB6ICqgLqA4AAm2OAAJAI/AcAACgFvgcoBQAA/A9AAMAAAACgY4AAiAj+D4gAAAT0ApQIlgeUAJQC9AIEBKFjgACICP4HSAAABJQChAHUD4IBsgKKBAAAomMAAQgJ/gfAAAwEpAKUAcQPlAGkAqwEAAClY4AAiAj+B0gAAAikCqwLpgSkBrQFpAigAKdjAAGICP4PSAAMCKQIlAiGD5QIpAgMCAAAqGNIAEgI/g9AADAA/A+qBKgE/geoBKgEAASpY4AAkAj8B1AAAADoA7gCrALqB6gKuAroC6pjiABICP4PSAAAANQHXgVUBVQFXgXUBwAAsGMAAJQI/AeyADgG5gH8AxAIkgj+B5IAgACyYwgBCAn+BwgAAAG+A+oFqgSqAqoIvgcAALdjAACICP4HSAACDvgBTgcAAP4PAgD+AwAAuGMAARgJ/geYAAAC8ANSA1QD8A9cA1ID8AO6YwAAiAj+B0gAQABYCrwKWgkYBTwEWAKQAMljgACICPwHSAAACXQFHANcD3wDFAU0CRAAzWOAAEgI/g8oAAAIXAl8BdwDXgF8BVwFXAjPY0AARAT/AyQAAAD0D5QElwT0B5QElwT0D9BjAAEICf4HiAAADL4CqgSqD6oKqgq+CoAI0mMAAEQE/wNEAAAA6g+qBAoE/gcJBOkPAADWY4gAiAj+B0gAAATsB2wFbAVsBWwF7A8gAtpjBAGEDP8HxAAABt8DVQlVBVUDVQlfBwAA22OAAIgI/geIAAgIeAk2BZQDPANQBXAJAAjhYwAAkA78AQAM/AM0CLQK9Aq0D7QKvAoACONjAACICP4HQAAcD7AAsA/+ALAPsAC8DwAA6WOAAIgI/g9IAAAA/gdoBUAFfgVoBeQHFADqY0AAiAj+B0AAEgH+D0IAGgwAA/4AAAM4DO1jAAEICf4HiAAAAP4G6gSqBaoIqgi+BwAA7mMgAEgI/gdIAAAC+gK6AroC+g+6AroC+gL0Y4AAiAj+D4gAAgRWAvIJ1gbSBNkHVQhACPpjiACICP4HSADAAIwOpASsBOwHogSyBKoO/WMAAIgM/wNACB4IwAteCEAHVgjUCwQIAAQAZIAAiAj+B0AAEAC4BHYENAV8CbQKsACAAAFkAABICP4HAADyD0IAWAeqAtoCAgv+BwAAAmRAAIgI/g9IAAAIqgqYC94EmAaqBaoIgAAFZAAAiAj+B0AAGgj8BTgEugc4CO4JCggABg1kiACICP4PSAAACOwF7APsAewB7AXsCQAID2SAAFAI/AeQAAAAeAN4A3gBfgl4CXwHeAETZIAAiAz+A0gIAAzVA1YIfAlUD1cJVAkAABRkgACICP4HSAAAAKYJWglSCdYPWg1WD9IPFmQAAAgJ/geIAAACVArECqYKng+MCoQKAAAcZIgI/gdIAAAIvAi0CaAG/gSgBrQJvAgACB5kgACECP8HJACAD1oAWgdbBVoHWgDCDwAAKmTAAEgI/gdIAAAH/AB0BnUF9gV0BXQHFAAsZAAAEA78AYAM+AN+CfgHAADeDUICngUgCC1kAACICP4HSABAAG4HVgVcBWQFTgdEAAQANmRAAEgI/A8gAJAPaAB4B3QFcgV0BWgHEAA6ZAABBA3/B4QADAj/BasDqgH/BasDqg6CAERkAACIDPwDKAiABLwGvAG8BbwGvAakCQAARmSAAIgI/gdAABwFVA1cC9QJXAVUBVwJAABHZIAAiAj+B0gAAAasBKQE6geiBKoEqg4AAEpkAABICP4POALIATgBMAD+D6gE/gesBAAEVGQAAIgI/geAAIgCBAK0Au4OxAIEArQCgABYZIAAiAj+BwgA4A8UAFwH9gVcBxQI9AcAAGdkAABICP4PSABMAOgHaAVuBegHaAVsBQAAaWQADPwDBAC0A7QLtguEB7QDtAN0A3QDVAJ4ZIAASAj+D0gAAAl0CXYH9AF0A3YFdAkECXlkAAFEA3wD/AN+C/wL/A9+AvwCfANEAwABg2QAAvwD/AP+C/wLvAfYA9YDUgN2A1QCgAKHZAAAiAf+APAPXgD8B3AA9Ac6BsUBPAYABJBkkACQCPwHkAAYCPwL2AbeBtgC/g+YAgACkWSAAJAI/AcAAJgD/AvYC9wH2AP8AxgDAACSZIgI/gdIABAA9A++ArQK/g8QCO4GiAN4DJVkAACQCPwHAAD8DVgB/AUAAPgPJADkDyQAnmRICP4HWAAACPQK9Ar0CvYP9Ar0CvQKEAikZEAARAz/BwAA8g+/AtoPEAg4BMcDfAwAAKVkAAAICfwHCACgC7wK5A5ACygF/AeoCQAAqWSAAIQE/wNEAAAE+gFWCVMPVgH6ATIMAACrZAABkAj8B1AAAA38ASoB6A0oAegNKAHoDaxkAACICP4HSAACA9YPHgM2AK4DrQcoCwAKrWSAAIgI/gdYANQAVAe8BbwHlAW6BdIHkACuZIAAhA7/AWAE4Ae/BrUG9Q91BHUD/wVgBLBkAACICP4HoABOCfYFVgVAAU4F9gVWBUAJsmRAAEgI/g9IAAIJeAVuA+gBbgN4BWoJAAi1ZAAAiAj+B4gAAARcBd4FQA9cBU4FXAUAALxkAABIB/4AAA78ASwB3AesA38CpAMVBAADv2QAAIgI/gcIAOgMtAL0BBIA8gy0AuQECAjBZEAASAj+BwAAtAxkAwQA+gdUBfwHVAUABMJkAACICP4HCACcB8wFnAW8B5wFzAWYBwAAxWQAAIgI/gdAAHwEzAf8B/4H/AfMB3wEAATHZAAASAj+ByAAvgL6Ar4Cug++AvoCvgIAAMpkQAT8BPwH/gf8DvgPkAfuBqIG5gaoBAgBy2SAAEgI/gdIAAAAmgf8BdgF3gfYBf4FigfNZAAAkAz8AxAIwAW8BfQDlA/0A7wF4AkAAM5kFAA8Ar4DuAPOC7wLhA+oA7YDlAMsA0QC0mQAAYgI/geIAAgOxAGSB9oF8gO0CcQPAADUZIAAiAj+D0gAGA74Aa4MvA/MD7wPyA8AANpkgABICP4PAAT4AxgA2AX+A3wPbAFsBgAE4GQAAIgI/gcIAGAM1APkAr4CvAK8AuwPBADmZAAACA3+AwgJLAmUAdQJvg+0AfQBHA0AAOxkAACICPwHAABeDdQDVAwAAywE9A88CWQI9GSAAIgO/gEADPwDRAj0C/QL9gP0C9QLAAD6ZAAAiAz+A8AIdgfKDO4HCgBuBqoKrgoAAP5kAAGICP4HCADCCH4K3gdeB14H/gvCCgAIAGVUAMwCXgJMA+AL5gvUB8IDSANeAswCVAAPZQAAmAz+AwAI6AdmAvQPAADeB9QL9AoAABJliAj+B0gADAjeC14IXAZMAV4EXgisCyAAFGUAAIgI/gcAAP4H9gR+A/AH7gP2CP4HAAAYZQAAiAj+B0gE+APsD/wJxgH8B+wF/AkAABxlQAAkBP8DIACLD34B+gJ7BvoBegT7ByAAHWUAAJAI/AdQAMQD/AL8DzwA/AP8A+QHIAIkZQAAAABICP4P/gv0B/4O9A+uBPoHqAQAAC9lCAgoBGgEqAQoAz4CKAOoBGgEKAQICAAANmUAAPwDAAEAAf4PAAAwBG4EiAPoAhgECAg5ZQAA5AEkAiQBfAVgDDAEzgIIAegCGAQICDtlBAEEAfwBBAlkCRAEbgKIA4gCeAQICAAAPmUACAgG+AEqCMgHIAAQDO4CiAN4BAgIAAA/ZQQE9AMEAvwDJAJkCDAE7gIIA+gEGAgACEVlCADID0gEfgTID2AIPATKAogDeAQICAAASGUICKgEigKMAygEQAAwDM4CiAN4BAgIAABMZQAAkg+SBP4EkgSCDyAAFAzqAogDeAQICE9lQAD4AVYB9AVUBfQDYAkeBOUCxAM8BAQIUWUIAmgJCAn+D8gACglgCH4EiQPoAhgMAABWZQAEVALUAf4E1ATUA0AAfgaIAWgCGAYABFdlAAj8BVQFVAH8BWAAOAzMAogDeAQICAAAWGVQAlgJVAjyB0QAZAswCO4ECAPoBBgIAAhZZQACVAJUCd4P9AFYCTYIfASLA8gCOAwICFtlAADQBRgE1AQWA4gIMARuAogBeAIIDAAAXWUAAPYP0AH+D9AB9g8ACD4EyQPoBBgIAABeZQAA7g/gAX4CoAnuD0AIfgSIA+gEGAgAAGJlAAAIAvoDqgKqAv4PAAAwDO4CiAN4BAgIY2UAAOoPrwKqAq8KygcgABoMdQLEAzwEBAhmZQgC+ArYCtwO2AN4CmAI/gQIA/gECAgAAGxlRAD0A1YB1AkWDPQDMAhuBogB6AIYDAAIcGWgCKoKmAf+BJgHigggCD4EyQOIAngECAhyZQAA9A/0A/YCdAn0BwAA4Aw+AygD6AwACHRlQABcCDwIvg68CNwP2Aq2CrQKTAhECAAAdWUAAPoPDgP7Ag4J+gcQAD8MxAN8BgQIAAB3ZQAEvwKrAf8FqwW/A5gIPwTCA3ICDgwCBHhlCAl8C3wL/gV8BXwLYAkwBO4DeAQICAAAg2UAAF0JfgX/B1QDXgFoAOYDVgVcBWQFQASHZQAACAgICBgEaASIAgoBiAJoBBgECAgICIllIgQSDNIDVgFaAUsBSgFWAVYB0gcSABIAi2VkAGQPZAFUAVwP1gFUAVwPZAFkCWQHYACMZQgIaASOA3wCAAjUD/QHEAD+AxAEFg4AAI5lJAgkD6QAHAJUCVYPVAEsBSQApA8kAAAAkGWkCKwIrASsBZ4GwAKAAr4GrAWsCKwIoAiRZQAAJAT8AwAIKAbKATgCAAhECPwPRAgACJdlAAIQAiQBJAFIAQgBAAH+DwABgACAAAAAmWUMAKAD/g+gAKwAAAIkAUgBAAH+DwABAAGcZQAEWANUCPIPVAAEAyAAbAEAAf4PgAAAAJ9lQADIA3wF+AT4BXwFAAQoAIAA/weAAAAApGUAAAAO/AEkACQAJAAkAOIPIgAiACAAAAClZQAAAAz8AyQApAAkASQB5A8kAiICJAIgAKdlAAAgCCgMpANWAVgBWAFaD2QBZAEoAQAAqWUEAnQCTgLkD0QBAAz8AyQAIgDiDyIAAACsZQAA/AKsAv4PrAL8DvwDJAAkAOIPIgAAAK1l/g8ABJQFUAT/BVAEBAz4AyQAJADiDyIAr2UICfwFWAFYBfwBAAz4AyQAJADkDyQAAACwZQAEqASkAuYPpAKoCAAE/AMkAOIPIgAAALdlAAD+B+gGvgW8B/4HnAr4ByQA4g8iAAAAuWUICAgICASIA3gATghICEgISAzIAwgAAAC8ZQAACA76ASoI6AcAABACSAJGBIgIEAAQAL1lAAAIDvgBLgjoBwAA7gdKCOgLKAjoCQAEwWUACFQIVARcAtQBVgFUCVQJXAlUB1QAAADFZQAICAb4AS4IyAcYAMcPJABUAYwCTAwAAMtlAAAIDPoDLAjABxAMrAMqBOgPKAloCSgIzGUAAAgO+gEsCMgHGACmBKQE9AekBKQEBATPZQAICA74AS4M6AMACI8ItQbkAaQCpAQACNdlCAgIDv4BKAzoAxgI/gV0BXQB9AUUCQAI4GUgCCQIJAQkAqQBfADkByQIJAgkCCAIAAbiZQAA/A9UBFQDfAcAAHQORAH8D0QIRAhABuVlAAAAAPwPRAREBEQERAREBEQE/A8AAAAA5mUACAAI/AkkCSQJJAkkCSQJJAn8CQAIAAjnZQAA/A8AAAAA/A9EBEQERAREBEQE/A8AAOhlAAAAAM4HVAVUBVQFVAVSBVIF0gcIAAAA6WUAAAABPgEqASoB6g8qASoBKgE+AQABAADsZQAAYAAQAM4HqgKoAugLCAgICAgM+AMAAO1lAAgIDv4BCAD4BwAI/AkkCSQJJAn8CQAE8WUAAEABXgFWAVYB1gdWAVYBVgFeAUABAAD2ZQAA/AckAiQC/AMAAGgAiAkICP4HCAAAAPdlAAD8ByQC/AMACPgHCAAKAAwACAAIAAAA+mUAAPwDJAL8AwAARAREBPwHRAREBEQEAAACZgAEAAe+BKoEqgIqAKoPqgCqBL4EgAMAAAZmAAAABL4HqgSqAioAqgOqBKoEvgSABAACB2YAAIAJvAlsBawDbAFsASwBrA88AQABAAEMZgAAwA9+BWoFagVqBWoFagVqBX4FwAcAAA5mAAD8AyQBJAH8CQAE/AMkASQJJAn8BwAAD2YAAEAA/A/UCrQKtAqcCrQKsgpSD1AAAAATZgABAAn8BNQC1AHUDNQC1AnUCPwIgAcAABRmEAAUANQHXgVUBVQFVAVUBV4F1AcUABAAGWYAAAABfg1qC2oLaglqBWoHagd+BQAJAAAfZgAAgAi+CqoKqgqqCqoPqgqqCr4KAAgAACBmAAD8ByQC/AMACPgIiAb+AYgCiAT4CIAIJWYAASIDqgDqD7oKrwqqCroK6g+qACIBAAAnZgAA/AckAvwHAAxIAkgB/g9IAUgCSAwAAChmAAD8ByQCJAL8AxAADgD4DygBKAEoAQgALWYAAPwDJAL8AwAAog+aBIYEogSiBJ4HAAAvZgAIgAj8BtQE1ATUCNQP1ArUCvwKgAoACDFmAACABL4EqgWqBKoEqgSqBqoEvgSABAAANWYAAPwHJAL8AwAI/gcSANIHkgiSCF4IAAY8ZgAB8AQOBOoHqgaqBqoGqgb6B04EgAUAAD5mAASABL4FKgSqByoEKgSqByoEvgWABAAEQmYAAPwHJAL8AwAApAKkAr4IpAjkB6QAIABDZgAAAAk+CaoFKgPqASoBKgeqCT4JAAkABElmQABUANwP3ArUCsQK1ArUCtQK1A9EAAAAS2YAABIA1g9SBV4FUgVSBV4FUgXWDxIAAABMZgAA/AckAvwDAAD4DwgA6AMuAegJCAj4B1JmAAD8ByQC/AHwD4oFfgQKBH4EigT6DwAAU2YAAPwHJAL8AwAIqASuA5gAuA/MCKwIgARVZgAE4AS8BrwHvAa8BrwOvAa8BuAE4AQABFpmAAD8ByQC/AsQCPgElgL0AZwPlAjwCAAEZGYAAPwHJAL8AyAAqge+BK4EqgS6BKIHAgBmZgAA/gMSAf4BAAD2A0sC2gpKCkoG+gNCAmhmAAzgAzwBfAl8D3wJfAV8A3wFfAsgCwAAaWb8ByQC/AsQCPgElAOWAPQAnA+UCPAIAARuZiAAJADsB2YFfAVkBWQFfAVmBewHJAAgAG9mAAQgBK4HrgKuCr4OrgKuBq4GrgcgCAAIcGYAAPwHJAL8AwAB/g/IAAAM+AMkAOIPIgB0ZgAA/AckAvwDAADcD9wC3gLcCtwK3AcQAHZmAADAB0AFfgXqByoA6gdqBX4FQAXABwAAemZAAFAANg+8CrQKgAq8CqQKpAqkDzwAAAB+ZgAA/AdEAvwDAADoAqgIrAeoAKgC6AIIBIJmAAA+ALMPugqyCrIKgAq+CpIKsg8RAAAAh2YAAPwHRAL8AwAA/A+kAhwKwAhUB9wJQAiRZgAAQAH8APwP/Ar8CvwK/ArcCvwPUAAAAJZmAAD8ByQC/AkABEoC8gnWBtIE2QdVCEAIl2YAAPwHJAL4AwQA1AdcBVYFVAVcBdQHFACiZgAA/AP/DyQBJAH4AZ4LqgaqDqoCvg4AAKhmIAg+CK4Prg2uDc4Nzg2qDf4Nyg9qCCAAq2YAAD4Atg+/CrYKvgqcCooKigq6DwkACACuZkQBRAH8D/4K/Ar8CvwK/gr8CvwPRAEAArRmAAKgArwJvAX8ArwOvAD8BrwEvAmgAgAAxmYADPwDBAC8D7wKvAqECrwKvAq8DxQAAADJZgAA/AckAvwLDAnsB6wBDgGsD+wJrA0ABdlmAAD8ByQC+ANOA9oHfgZaBv4G2gZOBwAA3GYAAPwDJAL8A4ABqgdqB14H4AdaB14HAATdZgAA/AckAvwDAAi8BfwOvA68BPwEvAWAAPBmAAAAAPwPRAREBEQERAREBEQEBAT8DwAA8mYAAPgPiASIBP4HiASIBP4HiASIBPgPAAD0ZgAABAj8CawFrAasBvwFrAisCPwIBAgAAPhmSAB8APwP/Ar8Cv4K/Ar8CvwK/A9oAAAA+WYCAH4A1g/WCv8K1grWCv8K1grWD34AAgD8ZgAI4Am8CbwJ/Ae8BbwF/AW8C7wJ4AgACP1mAAB8ANUP1grUCvwK1ArWCtUK/A8AAAAA/mYAAAAA/A99BWYFfAVkBWYFbQXkDzwAAAD/ZgAALACcB14FTAVMBUAFXAVOBZwHLAAoAABnAABABP4H6gXqBeoPagjqBeoC/gbABUAIA2cAABAAeADYD/wK+grcCvwK2A9oABAAAAAIZwAIAAb8ASQBJAEkASQJJAkkCfwHAAAAAAlngACIAEgA+A+sAqoCqAKoCqgK6AcIAAAAC2cAAAAM/gOSAJIO/gEADP4DkgiSCP4HAAANZwAM/gOSCJII/gcAAP4PYgCyDTID/gwACBRnAADpCIoG+AGOAOkIAAb+AZIAkgj+BwAAF2cABPwHVARWAlQDfAwABvwBJAEkCfwHAAAbZwAAFARcBVYFVAXAB14FTgVuBW4FfgQAAB1nAAD8AywDLg8sA/wJAAT8AyQBJAn8BwAAH2cAAAgJ/gVYAVgF/gEADP4DkgCSCP4HAAAmZwAI/geSAP4PEABMBf4DfAt8B34BfAZABChnEAQQAhABkABQAP4PUACQABABEAIQBAAAKmdACEgESAJIAcgA/g/IAEgBSAJIBEAIAAArZwgESARIAkgByAD+D8gASAFIAkgECAQAACxnCAIIAYgASAI4Av8POAJIAogACAEIAgAALWcAAogBSAD/D0gAAAD+BwAIAAgACAAIAAYvZwAAEAQQAhABkABQAP4PUACSABQBFAIQBDFnQARQBE4CSAHIAP4PyABIAUgCSARABAAANGcAAIgBSAD+DygAyAAAAP4PMAAgAMAAgAA1Z4AIoASQBI4CggHCD4IBggGeAqAEoASgCDpnAACIA0gA/g9IAAAO/AEEAAQA/AcACAAGPWcAAIgDSAD+D0gAAABkAFwIRAhEDMQDAABAZwAAoASkAqQClAqYCMgPmACUAqICoASABEJngACgBKQClAqMCMYPhACEALwCoASQAAAAQ2cAAIgBSAD+DygAwAgcBGQChAHEAjwEBAhGZwAAiANIAP4PSAAIAEAARAD8D0QARABEAEhniAFIAP4PKADACBwEZASEAjQDhAR8BAAISWcAAIgBSAD/DygACACACJgERAIiAhEBgABOZyQBFAFUAUwJRAleB8QBTAFUARQBJAEAAE9nSAAoAKgPmAiYCL4IiAiYCKgIqA8oAEgAUGcAAIgDSAD/DygAQAIIAcgIKAj/BwgAAABRZwAAiANIAP8PSACIACAAyAkICP8HCAAAAFZniAFIAP4PKADICAAE6AKIA3gEDgQICAgAXGcAAIgBSAD+D0gACAQgBCAE/gcgBCAEIARfZwAABAj0BJQClAH+D5QBlAKUBPQEBAgAAGBnAACIAUgA/g8oAEgEAAQEBPwHBAQEBAQEYWcQAKgEqAKsApYI1AeUAKwCpAKgDCAAAABlZ0AERARUAkQBxAD+D8QARAFcAkwEQAQAAGhnCAOIAP8PSAAACqIJcgQqA+YIIg7gAQAAbWcAAIgBSAD/D0gAAAzoAyoAKgDoBwgICAZvZ4gBSAD+DygAjABEACQAJAD8DwQANADEAHBniAiIBkgAKAAYAv4MGAAoDEgAiAaICAgAcWcAAAQE/ASsAqwB/g+sAawCrAL8BAQEAAB+Z4gBSAD/B0gAgAQ4BIYHYAQBBI4FMAYAAH9nCAOIAP4PiAAADPwDZAikBSQGpAVkCAAAgWeIA0gA/g9IAAAMhAN8CIQFNAIsBeAIAAiEZ4gBSAD+D0gAAACcAWoBCAnICQgM+AMAAIlniANIAP4PSACIAAAIRAhECPwPRAhECEQIkGeIA0gA/w9IAIgAAAz8AyIAIgDiDyIAIACVZ4gDSAD+D2gAgAg4BIgDfgDoBwgIOAgABpdnAACIAUgA/w8oACgCgAFIAP8PaACIAwABmmeIA0gA/w9IAKAIEARuBIgDyAI4BAgIAACcZwAAgAS+BKoCqgGqAf4PqgGqAr4EgAQAAJ1niAFIAP8PSACICCAEqAQoBT4CKAXoBAgInmeAAUgA/wdIAAAH/gAABIADfgCAAwAEAACgZ4gDSAD+D0gAAAEkARwBBgGEDzwBIAEQAaJniANIAP4PSAAAAPwPBAgUC+QItAkECgAIo2cAAAQBtACUBFQEfglUClQKlAq0AAQBAACqZ4gDSAD/D0AAEADIByQIIwkkCcgIEAYQAKtngAFIAP4PKABAD/wABAb0AQQC/AcADAAAr2eIAUgA/g9IAEAAEA+QBP4EkASQBJAHEAC2ZwAApAiUBI4ChAHcD4ABvAKkAqQEvAQABLdngAFIAP4PSAAADv4BCAzwA/wPBAT8DwAAxGeAAUgA/g8oAAAA9A8UAJQBfACUCRQI9AfPZwgBiAD+D0gAAAD4D4gEjgSKBIgE+A8AANBnAACEBIQEvgKsAewHrACsAb4ChASEBAAA0WcIAYgA/g9IAAAA/g+IBIgEiAT+DwgAAADSZwQJZQkRBRIDBAPEDx8DJAMkBSQJFAkAANNniASqBKoCgAKkAbQPjgGEAvwCwATABLAE1GcACVAJVAU0A3wD3A90AxwDFAU0CRAJAADYZ4gBSAD+DygAKAGAAPQPTAREBEQExA8EANxnCAOIAP4PSAAAAPwPJAkkCSQJJAnkCQQI4GcIA4gA/g9IAAAAWABICEoIzA9IAFgAAADlZwAASAgoCKgPWA1cDUgNWA2oDygISAgAAOxnAAAECPQEtAKUAf4PlAG0ApQE9AQECAAA72eIA0gA/g9IAAAA9AMUAfQJBAj8BwQAAADxZwAAiANIAP8PyAAICQAIigj6D4wIiAgICPNngANIAP4PAAD8CQIF+gIAAPwPBAD8AwAA9GegBL4EoAK/AqQBgA+fAaQCpAKkBKIEkAT7ZwAAJAgUCNQPrAquCqQKrArUDxQIJAgAAP9niAFIAP4PSAAAAOgDKAAqAPwPKAAoAugBA2iIAUgA/w9IAAAP/AAUDvQBUghSCNIHAAAEaAAEUARcAlAB0gDUD9AAUAFYAlQCUAQABAVoAAOIAP4PAAT+A0II/gdAAP4HQgD+D0AAB2iIAUgA/g9IAIgEIAKkCSQI5A8kAKQBIAYIaIgBSAD+DygAQAgQBFAEfgTIAyoFqgigBgtokANQAP8PUAAEBnwBRwjkD0QARAMEBAAAD2iIAUgA/g9IAEAEEgSWBJAEmASWBBAEAAARaAADiAD+D0gAAAbkARwDQADQCRAI/gcQABNoiANIAP4PQAAQCAgJJAniDyQJCAkwCAAAFmiIAUgA/g9oAPoPigV+BAoEfgSKBPoPAAAXaAQJdAlUBVQFfAPUD1QBfANUBVQFdAkECSFoiAFIAP8PSAAICGAEGATYAg4ByAIoBEgIKmiIA0gA/g9oAIAEEAROA8gA/g/IAUgCQAQ3aAgBiAD+D0gAAAFKAUoB+A9IAU4BCAEAADhoiAFIAP8PSACICCAEaAWYBE4CKAOoBIgIOWiIA0gA/w9IAAAA/g9SCNIIUgFSBn4FAAk8aMQBJAD/DwQATADkD2cEWwRaBGYE4gdAAD1oEARUAlQB3g9UAVQJEAT+AhAD0gQUCAAGPmhACGQJFAUEBTwDBg9EATwDBAUUBSQJAAhCaIgDSAD+D0gAAAgkCSQJvg8kCSQJIAkAAENogANIAP4PQAAMCYAE/gMAAP4HQAicCAQFRWiIA0gA/g8IACAO+AGWB1QIXArQCRAIAARGaIgDSAD+DygAQAD8DwQIVAr0C1QKVAoACEhoAACUCZQFtAVUA1YPVAF0A5QFlAUUCQAITGgAAAAJeAVYBVgD3g9cAVwDXAV8BQQJAABQaAgDiAD+DwAA/A8EANQDVALUAwQI/AcAAFFokAmYBV4FfgMWAYYPVgFaA1oFsAWACQAAU2jEASQA/w8kAAAE/QUlBSUFJQUlBf0FAQBcaIgDSAD/D0gAyghCCMQFcQZWAkAF3ARCCGNoiANIAP8PSAACBCwFIAU/BSAFKAXmDwAAZWiIAUgA/g8oAIAIVAQ0AxwAFAAyD1IAgABmaIgBSAD+D0gAAAF8AQIBkA8+AUgBRgEkAGhooASUBJACvgKAAagPpgGWApQCjASEBAAAaWjEASQA/wcUAAAO/AEEBCUE9QckBCQEAAB2aIABSAD+BwgA4g9SAVoB+g9WAVIJ8gcAAH9oiAFIAP4HSAAAAX4BagFqAeoHagF+AQABgWhMCWAJEgVYA0IDMg8OAUIDQgU+BQwJMAmFaBABkAD8D5AAoATYA6wCqALoC6gK6AeAAoZoAAOIAP4PSAAACSgN/gMAAPwPBAD8AwAAk2gIA4gA/g9IAAAAVAFEAcYPdAFEAUQBAACXaIgDSAD+DwAA/AisBqwG/AWsCKwI/AgAAJ1oAAAgAPwPAgD4AwAAqAauAJQPtACsAqQEomiEAUQA/g8kAAQA8QdWAVABXgFQBfYHAACmaAAAEgmKBF8ERgVqAkgCSgHfAEYACgAQAKdoiAFIAP4HKAAgAKoHvgSqBKoEugSiBwAAqGhACCoJGgV+BRkDqg8AAR4DQAVABX8JAAmtaIADSAD+D0gAQApYCR4FygaYBp4JqAgACK9oiAFIAP4PSAAABOoErAL4D6gArgS4AwAAsGgAA4gA/w9IAIAM6AOIAOgP/gQIB+oIIASzaIABSAD+D0gAAAy0AywApw8kALQPIAQAALVoAAA0CAwE3gNMAVQBQAJMAN4HDAgUCCQGtmiIA0gA/w9IAAAP/gAKAqoC6gdKCU4JAATAaAgBiAD+D0AAEAUIBSQEogQMBpAFUAQAAMRoRAlUBdQFzAPMAe4PzAHMA8wDzAVUBVQJyWiEA0QA/w8kAEAAngeqAKoA6w+qAL4EgAPLaIgBSAD+D2gAQAkIBf4FWAFYAf4BCA0AAM1okANQAP4PUAAAAPwPVAlUANQHfAkABQAA0miIAUgA/g9IAAAAbAI8Aq4PrAI8AmwCoADVaIQBRAD/D2QATAZEAVQE1wdUAEQBTAIAANhoAAD0DBQC/g8UAfQIYAQUAv4PFAL0DAAA2miAA0gA/g8ABP4Dkgj+BwAM/gOSCP4HAADfaIgBSAD/D0gAAAT8BKwCrAH+D6wBrAL8BOBoAAgYCQoFfAVYA94PWANYA34FCgUYCQAA42gIA4gA/g9IAIAIFAZUAP4PVABUBXwFEAjuaAAApASUAtQPjAKMBD4EjALUD5QBpAKABPFogANIAP4PSABACjQJ1AbeBJQGtAkUCAAA9WgAAMQBJAD/DyQAAAPfAPUH/wfVAF8DQAL6aIgBSAD+B0AAHAD8B/QHVgVUBWQFDAcAAAVpiANIAP4PCAAgALQHrAKuCywI5AcgAAAADWnIACgA/wcIAOAPBAT8BVwFXgVcBfwFBAQOaYgBSAD+DwAAMAD8D6oEqAT+B6gEqAQAABJpgAFIAP4PCAAgDf4DKAiACRwE5AN0BgwIHGmQA1AA/g8QAPAJOAk0BfIDNAM4BfgJEAgtaQAAkAD/DwAA/g8SAO4BAAD4D68C6A8AADBpgANIAP4PAAD8A1QC/A8AAP4PAgD+AwAAP2mAAVAA/AcAAKgA+A94BXgFfAX4D3gAgABKaRADkAD8D5AAAAj8B9QB1AXUA9QJ/AcAAFNpgAFIAP4DAAz+A0IAqgT6B6oEQgT+AwAMVGmAAUgA/g8AACwJfgkMB6ADHgVCCT4JAABaaQAAVAhMBl4DVATAD1QJTAleCUwI1AgACF5pAAOIAP4PQAAcCFQE3ANUAVwJVAlcB0AAY2nAASQA/w8UAIADfwDlD1UFVwVVBfUPBwBtaQgJagVsBXgDbgHoD2gBfgNsBWoFCAkAAHVpiANIAP8PCADiCaII7gj6C0IIkglyCgAAd2mAAUgA/g9IAAAAvA+oCoAKvgqkCqQPFAB8aYABSAD+DygAiAiqCpgH3gSYBqoFqggAAH1pAACkBKQEgAL8AdYH1AH8AYACrASiBAAAgmkAA4gA/g8AAPwHVAJ8CSAExAN8D0QIRASEaQADiAD/D0AAHgjACV4EQANOBtQLBAgABIZpgAFIAP4PCADwB7gC9A8WANYDBAjoBwgAlGkAA4gA/w8AAPwHVgJ8BwAA/A8EAPwDAACVaYgDSAD+DygADAGUD0QJJglECZQPLAMAAJtpgAFIAP4PKACACOwFvAOuD6wDbAUkBQAAnGmIAUgA/g8IAEAIXAbcAVYJVAlUCVQHAACoacQBJAD/DyAAggBKACYA9w+iAqoCqgIAAK5pAATiBOwErgKiAKAPsgCoAqYCqASiBAAAtGkAA4gA/g/IAAAAvA+iCpAKpA+cCoQKvA/LaQAAyAMoAP8PAAD8D74CvAL8A74K/AcQAs1pyAAoAP8HKAAIBugBfAd7BXwFdAV0BwAA0GmAAUgA/g8IAHwAVAhWB/wA1AdUCXwLAAjYaQgDiAD+D4gAAARWBVQA/A9UAlYFVAUAAP1piANIAP4PSAB6ANoP/wraCv8K2gr6DwAAAmrABOwE2gLAArwA1gfWAPwCiAL2BOAEAAAKaiQIFAl/CRQFUAVKAzYBQQM0BX8JFAkkCRFqiAdIAP8PSAGEASYJDA24Dw4BfgUQCQAAE2qAAUgA/g9oAAAIfAt8C/wFfgV8B3wJfAkZaogDSAD/D0gAHAVsAXwJbA98AWwFfAUABR5qAAOQAP4PAAD8BwQJ9ArUC1QJtAqECwAAH2qAAVAA/g9QAAAC9AL8AvYP9AL0AvQCEAIhaoABSAD+D2gAAAl0BXYD9AF0A3YFdAUECSNqhAFEAP8PRAAADSsDqgg+B2oCKwWiDAAAKWo4A7gA/Ae4ACgAgADsB7gHqAeoB6gHAAAqaogBSAD/D0gACAj6CV8FWgX6AV8FWgX6CTFqiANIAP4PAABeCToLjg0cBUIFegtCCV4JOWoAA4gA/w/IAOAItAq+DPQGAASQAP4PEABEagAAyAD+DwgA+gOqAqoC/g94BI4DeAwACEtqkANQAP4PEAAyD7IA8gf+BfIH0QCwDyAAWGqIAUgA/g8oAIAPWgFaB0oF3gZaAMoPAABZasABKAD+ByAA2gS6BboEtQS+B9oFEAQAAF9qiANIAP8PQADmDLgDtArfCKQHuAq0CKAEYWqAAUgA/g9IAAgEuAVsA+4KvAmsB6wBOAJraogBSAD/D0gAEgjyBX8FegX6AX8FcgXyCXFqgANIAP8PAAT8A0QErAdsBwQApAj0ByAAgGoAA4gA/w/IAHgIzAv8C/4L/AvMC/wLAACQaogBSAD/DygAiA98ACcH7gX2BeQF9AcEAJRqiANIAP8PQAAaB/wF2AXeB9gF/gWIBwAAomqAAUgA/g8IANgMuAL0BBYAxAyoAugEAAipagAByAH+B2gAeAXMAfwF/gfMAfwFhAUAAKxqAAOQAP4PAAAUBtQG9gN0C3YHVANUBAAAw2qAAUgA/gcAAP4HAgT+Bf4F/gX+Bf4FEgT7aoADSAD+DwgAfgkuC/4NAAVeBS4LXgkAAARrgAFIAP4PAAD+B+4E5gPwD+YD7gz+BwAACmsIA4gA/g+IATAB1A82D4APNg9UD3QJAAAga0AIMAgMBAoCiAF4AIgBCAJIBDgICAgAACFrAAAEBoQBCAhgCB4ECgPoAAgDSAQ4BAAIImsUBCQCxAE8AwQIMAQOA+gACAMoBBgIAAAjawAE/AMUABQA8gcCADAMDgPoAAgBOAYICCdrAAD8DwQFpATUBAQNYAweB/gACAN4DAgIMmuIAMQPogSQBJIE5AewDA4D+AAIAzgEAAg6awAACAn8BVgB/AUAATAMDgPoAAgDOAwIAD1rUAhYC1QI8gdUDQAIMAQOA+gACAM4BAgIPmsABKoCqgivB6oAogIwCA4G6AEIAzgMCAhHawAB/geqBKoFqgi+BwAAHA7KAQgCOAwAAElrJAStAv4H/AOuAf0EOAwHA+QADAMEBAAATGuAALwHrAW8B4QIvAewCA4G+AEIA3gMAABQawAA/gOCBNoFqgTaBQAMEAPuAAgDKAwYAFNrIAHsD6wHuAeoB+AMYAQcA/ABEALwDAAAYWsAAboPuweAB7sHmgcwAA8O5AEEA3wMAABiawAEAATwBwAEAAQABP4HIAQgBCAEIAQAAGNrAAQEBOQHBAQEBAQE/AdEBEQERAREBAAEZGsACPAPAAgACP4HIAQAAP4HIAggCBAIEAZlayAIIAu8CKAIIAggBP4HJAIkAqQBpAAgAGZrAAAQCNQHFATUB5QEEAT+ABAHFAgUCBAGZ2sACPAHAAT+ByACCApoCKgFPgIoBegECAhpa6AAoAV8CGAIIAUgBf4EJAKkASQApAAgAWprJAikCKQOlAiUCLwIhA+UCpQKpAqkCgAIb2sQANAHHATQBZAF3gWeBbQFFAT0B/AHEAByawgM6AMoAGwL6AdoAi4JfASsA7wEqAgoBnNrEA7QAVAE3ALQD9AAXgn0DFQDdAVUCRAEdGsADPwDBAhUCHQPFAiED1QK9Ao0CtQIAAB3awAM/AMECGwI/A5sCAQPbAr8CmwKpAgAAHhrAAh8B1QE1gc8BUAAPAe8APwPvACoBwAAeWsAAIQARAgkBFQEnAIUAZQAdAAUAAQAAAB7awAAxAhkBJwGFAH0AAQA/AdECCQINAgkBnxrwAAiCJ4EEgPyAAAARABEAP4PQgBCAEAAg2sAAMIIPgSSA3IAAAj4CIgG/gGIBvgIgAiJa8AAIgieBJIDcgAQAM4HqQLoCwgI+AcAAIprgABiCB4GkgFyBBAETgPIAP4PSAFIAkAEi2uAAOIIngSSA3IAAAioBP8EaANlBVUJQASWa0AAYgxeApIBcADkDwQE/AVuBWwF/AUEBJhrgABiCF4GkgFyCAIJqAUvBxgFXQsVC6AItGsAAPwPFAXkBBQNQAzeCEIHQgb+CWAIGAi1awAAAAL8D1ICUgIRCUAI3gVCAl4FoAgYCLdrAAz+A1UJVQk9B0AA4AheB0IG/gVgCAAAumsAAFIGVAHMD1MBAAjeBEIFQgJ+BeAEGAi8awAAbAxsA+4A7AcEAmAI3gRCA14DwAQACL9rAAf/APUOpQD1AqcEAASvAqECLwHoAgAEwGsAAHwJUglAB1QFPA1ACH4JQgb+CWAIAADBawAA/ATSBMAH1AQ8AkAI/gVCAv4FYAgAAMVrAABUATQL1goUB8QCEAjOBUIC3gVQCAAAy2sAACAA4Ak8BSQDpAF8CSQJJAf8ASABAADNawAAIADwAy4CogKqAqoKIgoiDv4DIAIAAM5rAABIAMQHcwJKAsoDegpKCkoO+gNCAkAAz2vAAMgC6AOmApQDlAPUA5QKlAr0B8QCwADSayABIgHqB2oFagX/B2oFag1qDeoHIgUAAdNrEAD4B7YFlAz0BwAAtA8sAKYPJAC0ByAI1GsAAAAA/g8gBCAEAAD+B0AIIAgQCBAHAADVawAAQAF+AUgBKAGADz4BSAFIAUQBJAEAANlrAABACn4L5AdkBVQDXgDkB2QKZAlQCUAE22sAACgBKAEoASQB/AckCaQIkgiSCJAIgAbhayQBJAH8ByQJoggQCMALfgpICkgKyAkIBOtrAADEBPwF7AXsA+4H7AvsCuwKfArECgAA72skASQB/AeSCIIIKApkChAJzgkQCswKAAQPbAAAAAj8ByQEIgQiBH4AogMiBCEIIgggBhFsAAAACPwHpASkBKQE5ASkAaQGvAiACAAGE2wIAPgBCgIIAgAI/g+SCJIE8gGSBp4IAAQUbCAAGABGAFUAVABUAFQAVADUAxQEBAgABBdsAAhYCUYFVAJUAtQF1ARUANQDFAwECAAEG2wQABgJhAUjAyoJKgmqB6oAKgHqAwoMAAYibAgAqAS2Bb4FfAd8BbwFvAUcAPwDBAwABiNsEAAYCUQFIwGqDyoBKgFqDSoA6gcCCAAGJ2wQAMgCxALeAtwP3ALcAtwCHAD8BwQIAAYobAgAUAlYC1YLXAVcB1wJXAkcAPwHBAgABi5sEAiICrYEXANcAlwEXAccCPwBDAYECAAG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AAQRcBAAJA8kAIAFvAT8DrwMvA78ArwEvAmAAh9wEQSmAwAAAgATDLoDOgP4DzoBuwe6A7oPLHAQDKIDhAA2BlQB/gcmAfIEbgVqAfoFAARMcAAAIghEBgQDdA7UDzYPhA92D1QPdA8AAFFwAAAiBqwBAATqA+oH+gXiAeoD+gXqBQAEY3AQACYPQAAXAk0DoAOcA7YL+gtcBxICQABrcAAIYAgYBAACgAF+AIABAAJABDgIAAgAAG1wAAACCEIEMgQCAsIBPgDCAAIDYgISBAAEb3BACHAEAAL+ARACBAAECAQI/AcEAAQAAABwcAQChAF0AA4I5AQkAgQB9AAEAWQCJAwAAHVwAAgACaoIKgQqAqoBKgIqBCoFvggACAAAdnBwBAAO/gEAARgFAAQgBCAE/gcgBCAEIAR4cAAAQAhICigJJAQWAtQBHAIkBKAJIAhACHxweAgABv4BEAEABjAAjgCICAgJCAz4AwAAfXAACAwJ0gQABAgD1gACAwgEDAXSCAAIAAB+cAAAmAiICGgECAIKAewACAMIBMgEGAgAAH9wOAgABv4BAAMIAPAHAAQABP4HAAQABPgPiXBwCAAG/gEAAjgIAgzyA5IAkgCSAPIBAACKcHAAAAz+AwACGAgwBA4C6AEIAygEGAgAAI5wAABACCgJpAQgBBgDxgEYAiAEpAUkCEAIknBAADAO/gEAARgKQAg4BAAE/gIAApgBIACVcDgIAAb+ARACAAjoByoAKgDoBwgICAYAAKtwOAgABv4BAAMIAEgEaAbaBUgEKAcIBAAArHBwCAAE/AMgAgAA/A8kCSQJJAkkCeQJBAitcAAM7AMoCKgJqAQuBqgBKAIoBCgJrAggCK5wcAgABPwDMAYAAPgHLgkoCegLCAr4CQAEs3AYCAAG/gEAAhgA4A8UAJwBfACUCRQI9Ae4cHAIAA7+AQACKAQwAA4A+A8oASgBKAEIALlwAAAADOACoACgBr4ApAKkBKQA5AIEBAAAunAAAYgMigLKALgGrACqAqgIuArgCIAHAAC8cDgIAAb+AQgBEAR0A14I9A9EAEQDRAQAAMFweAgABv4BCAMQADwHpAAkCPQPJACiAyAEwnB4CAAG/gEAARgBAASWBJAEmASWBBAEAADIcCAJEgcOA8oAagwaAAAEfAkAAQAF/gUACM9wAAgADPwBVAFUBVQBVgVUAVQLXAlABwAA2HA4CAAG/gEQAoAIiAT+AogAiAD+AogMAAjZcCAIEA7+AQADWABID64EtASkBLQETA9AANtwQAgwBv4BEAYABPgIiAj+B4gE+AYACAAA33B4CAAO/gEQAP4PAgQiBfoEogUCBP4PAADkcPAIAAz8AwAEEAUAAagD/AqoCrgKqAYkAOZwIAQYBAAD/wAIAwAI+QQJAu8BCQT5BQAI53B4CAAG/gEAApAIhASmA7wAtA/ECKQIgATrcAAIighiChQJAAQqA1oELgSaCIoKeAgAAO1wAAAkBCQDfwAUBoAAZAA/BwQAfAKABkAI+XAAACIIIgY+ADYFNgG3AHYCdgQ+ACICAgQJcQAAEAgUBPQBVAlcA1wBXANcCVwJFAcAAApxPAQADv4BCAMAAF4BVgHWD1YBVgFeAQAAFXEgCBAO/gEQAoAI+ASWAvQBnAL0BIAIAAAZcTgEAAb/AQgDIACsB6QEpgSkBLwEpAcgABpxAAAkChQLvgQMBKQDMAIMBH4FDAUUCCAEIXEoCCgN/gElAfwNJAH8BSQJ/AEkBSAIAAAmcRAIEAz4AV4BWA1YAfwBWg1YAVgBCA0ACDBxeAgABv4BAAI4ANAPSAUGBUQEXAXEDwAANnGICKgGbgJuABQFDAGAAGgGHgBoAooOgAg8cUAIOAQAAv4BEAikBPQDpgCkD/QIpAgABExxeAgABv4BAAKQCPwK1ArWD9QK1Ar8CAAATnEECfwEXQReAVwN/AAEAHYMBQH8AQQMAABVcQAAAAj+BLIAzgK6DAAA/gQSCRIDng8ACFlx8AgADPwDIAj0CpQK/AqUDvwKlAr0CgAAXnEAABgJVgVUAVwN9AEAABwN6gjIAjgFCAlkcTgEAAb+AQABEASEBL4CrAHsB74BhAIABGdxAAj8DZQAlADsDBQAzAFEBVQJVAHMDQAIaXE4CAAG/AEQAgAI/AusCqwCrAasBvwLAAhucQAAMA40APQBdAV+AXQFdAV4AfQBEgwAAH1xAAAQDv4BEA78A6wEbADqB6oEagL6DwAAhHE8CAAG/wEIAgAM/gCqBqsIqgqqAP4GAASKcQQEfAc/ALwAvgb8AAACZwSqAIkCRAwAAI9xAAAICvoK2gLaCv4D2gr6CtkC+QoICgAAlHEYACAM/gMQBCQBlA9ECSYJRAmUDyQBAACZcQAE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t3MEAiQC/AMkAgQAgA+ABP4EiASIBIgPCAC7cwAEJAL8AyQAAAz4A8gJfgZIBsgJGAgAAMJzAAQkBPwDJAIAAPQDFAH0CQQI/AcEAAAAynMAACQE/AMEAkAI/gdCAP4H/A9CAP4PQADNcwQCJAL8AyQBEAFICCQFkgTEBEgCEAEAAOBzBAQkAvwDJAIAAFwGSAH+D0gBSAJABAAA7XMAAEQE/AdEBAAC8AgABP4DAAj8D0QIBAjycwAAJAT8AyACDACMAvQClALUD5QClAIAAv5zJAQkAvwDJAoACPwFVANUAVQPVAn8CQAEA3QAAiQC/AMkAQwDaAIICP4HiAAKA2oEAAQFdAQCJAL8ASQBAAD8D1QEVgTUAVQDvASABAZ0AAQkAvwDJAIACXwIVAnUD/wPVAlUCXwJCXQABCQC/AMkAgAItAcsAKYPJAC0ByQIAAAQdAAEJAL8AyQCAAj0CRQEEALeARAEFAj0CyJ0AAQkAvwDJAKAANQC1Am8CMQHZACUAwAEJnQAAiQC/AEkAQAAtAe0AqwDLgj0DzQAAAAqdAAEJAL8AyQCAAgIBf4FWAFYAf4FCAUACDN0AAAkAvwBIAOIAP4PSAAAA8gA/g9IAIgDNHQAAFoAWgFeAXoBWgFYAXoFXgNaAVoAkAA8dAAIRAT8B0QGAADoBqgArA+oAKgB6AMIBEt0AAAkBPwDJAIAAPQHvAW2BbQPvAXwBQAFW3QAAiQC/AEgAQQE9gSUApAB8ACUApYC9ARcdAAAJAT8AwQI8Ae4AvQPFgDWAwQIyAcQAF50AAQkAvwDJAIAADwAsA+wB/4AsA+wALwPX3QAAJQOVAh8BFQGlApACVQJvARUAVQGAABqdAQCJAL8ASQBAAz+AKoGqgD+BqoBgg8AAHB0AAQkAvwDJAIACHwEVALUAf4HVghUC3wLg3QAAiQE/AMkAgQAdA9kA9YFZANECXQPAACHdAAAJAT8AwAM+gMqCMAHFgcqBOgPKAloCYt0AAAkAvwBJAAAAvQC9AL2D/QC9AL0AhACnnQAAiQC/AMgAQoEaAV+A+gBbgVoBW4JAACndIAAfAh0C7QLtAv8CwAPVAt2D1QLVAkAALB0AAIkAvwBJAUABP4Evge6Ab4CugJ+BRAFynQABCQE/AcgAggM/A/+B+wH7AfoC+gLAAjcdAAIAAb8AQQABAb8BQIEggc+CMIDAAwAAOJ0AAB0DfwB/A90AQAO/AEEBvwFBAL6DwAA43QEAE0N5gMADfwH/AsCCP4HWAHnD1QBAADkdAAE/AX+D/QJ7AHwDfwDBA78BQQG+gsADOZ0AAAEBAQO5AkcCNQEFAUUAPQHBAgECAQG7nQAAFgISA7kB3IHaAdiB2oBcg9kCEgISATvdAAA/AcEBbQE5AQQAQIM/guSAPIPAggABvZ0AACIDPoDiAD+D4oAAAj8D5QA9A8ECAQE93QAAEIIVAzAC2gJZAtWAUwBVA9kCGAEAAAEdQAAfAl8BVwHbAU8AIAPfAiUAPQPBAgABhh1AAAIAAgA/g+IBIgEiASIBP4PCAAIAAAAGnUAAAQBBA/+CVQJVAtUCVQL/gsECQQJAAAcdQAAkg+SBP4EkgcAAP4PiASIBIgE/g8IAB91AAAgCJAIjgiICIgI/g+ICIgIiAiICAAIInUADOQDJAm0CrwKrgqsD7wKtAqkCiQIAAAjdQAM5AMkCLwKpAqkCqYPtAqsCqQKIAggACV1AAArAiQC/wEkAQAIvgbqAb4EqgS+AwAAKHUAAAAM/AMkASQBJAH8DyQBJAkkCfwHAAApdQAAAAz+A5IAkgD+B5IIkgiSCpIK/gkABCt1AAAIAOgPqAKoAqgC/A+oAqwK7AcIAAAAMHUAAPwPRAREBEQE/AdEBEQERAREBPwPAAAxdQAA+A+IBIgEiAT+B4gEiASIBIgE+A8AADJ1AAAAAPwBlACUAJQA/A+UAJQAlAD8AQAAM3UAAPwDJAEkASQB/w8kASQBJAEkAfwDAAA1dQAAAAD8AyQBJAH/ByQJJAkkCfwJAAgABjd1AAAACXwJVAVUA/wBVAlUCVQJfAkABwAAOHVAACAA+AeuAqgC6AOoAugLCAgIDPgDAAA6dQAA/gciAv4DIgL+AwAACAgICPgHCAAIADt1AAD0DwQE9AVUBVQF/AVUBVQF9AUEBPQPRXUAAPgB/g+uD3gAIgnyBDoC5gkiDOADAABMdQAAAAG+CKoEagI+ACoAag+qAL4AAAEAAE91AACACPwP1AjUCPwI1APUBNQG/AiACAAAUXV4CAAG/AEABhAA/A9EBEQE/AdEBEQE/A9UdQAA/AckAvwDJAL8A4AAqAD+D6AArACAAFl1AAA8AKQPogqSCqIKgA+8CoQKRA88AAAAXHUAAEQA1A/UCvwK1g/UCsQKpAqkDyQAAABidQAAoACuAu4CrgLuB64CrgLuAq4CgAAAAGV1AAD8B/wDJAL8A5AAiA/WCKQI3AjED0AAZnUAAPwH/AMkAvwDAAgoCSgJvg8oCSgJAAhqdZAAlADcB7QFlAW8B5QFsgXaBdoHkABAAGt1SAB8BPwH/Af8B/4H/Af8B/wH/AdIBAAAcHUAAAAKvArsB6wGvAKsAqwG7Ae8CgAKAAB0dQAA/AckAvwHdAasA/QDXg1UDVQJVAcAAXZ1AAA4AAoP7AuoC64LqA+oC+wLCg84AAAAeHX8ByQC/AMkAvwDIAC0A7QCrgs0CPQHIAB/dUAA5gdZBdQHWAX/D+AEdgN5B7QIUghABoZ1AAB0BVQPXAzABwQA/A/0DvwP9A78D0QIinUAAPAJ/gj+D/4P/g+uD/4P/g/+CPAJAACOdQAE5AcEBPQDTAIECPQElAL+D5QC9AwAAI91AATEA/QDTAIACKQHPACmDywAPA9kCEQEkXUACW4JVAXUA1IBCA2iAyoE6g82CWIJIAiXdTgJgAT8AwQAJAAkCCcIpA9kAGQAJAAAAJl1MAkABfgDCABIBCgKrAmoCagIqAgoBAAAmnUYCYAM/AMECMQINAQmAqQBZAIEBAQIAACfdZgIgAb8AQQAhAD0B5UElgSUBJQElASEAKR1mASAAvwBBAD0A5QE9gSUBJQE9AQEAgAAq3WICLAO/AEECEQItAWWBpQG9AXECEQIAACudYwIQAb+AWIAIgDyBysIKwkqCfIIEgYiAK91OAGADPwDBAz0AxQAlgLUAxQA9AcECAQEsnWYAIAO/AEEDvQBVATWBXQCVAWUBDQIAAC5dbgIgAb8AUQAJAqUClYJFAWkBCQCRAEAALx1GAmADPwDBAAkBbQE1gjUCrQKlAAEAQAAvnWYCKAO/AEECIQEtASmAuQBpAKkBKQIAATFdZgIgAb8AQQA1A9UAFYD9ABUA1QI1A8AAMd1mASABvwBBATUBxQEFgT0B5QElASUBAAAynWYBIAG/AEEBCQFFAVWBdQHVAUUBSQFJATSdYgIkAb8AQQApAK0AqYC5A+kArQCpAIEANV1mAiABvwBBAD8D6wErgSsAawGfAUECQAA2HU4CYAE/AMECNQJVAtWCVQJVA3UCRQIAADbdZgIgA78AQQA7A+8Ar4C7A+8AqwK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JALkA3wA1AF+AVQB1Ad8AQABl3iEAPQHLATgB8QANAykA0YA9AcUCPQJAASYeEIA+gcWAvIBAAT8DKQC/wCkAP8CpAT8AJ94hAD0D0wEwAcIAHwNSAP8D2gDfAVICQAAp3gAAMoE6gL+D+oKgAr8CtQK1grUDvwAAACpeAAAhAD8ByQC5AsACPwHrAKsAqwG/A8ACLB4hAD8DyQE4AeIAA4J/A8ICPwPCgjICQAAsXgEAdQPLATEC/AHCACoDwgHfgKIBWoIAAazeIQA/AckAuQDAAisB2gALg2oAygErAkgALR4hAD0DywE5AcAAKgL2ArcCtgKqAsoCAAAuniEAPQPTATEB0wA5A9cCVYJ9A9UCVQJTAm8eAAAggD+ByICwAd+A6oEqgD+BqoBgg8AAL54wgD6ByYC4gEABP4DigjqB6oB6gKuBAAAwXiEAfwPJATkAwwIaA+OCOgOSAioD84IKA7FeEQA9AdMBMQHAAB0CFwG3AF2CVQJVAcAAMp4AABSAtIHegVuBWoHagLqB2oFegVCB0AA0HhQBVAFPANUDxYLfAsIC2YLUgu+D5gBgAHVeAAARAD0DywE4APID/wPzgjMD+wIyA8ACNp4hAH0DywEJATEB/wC3AbcDv4K3A/8AgQD6HgADvwBBAS0BLQOtAuWCoQKtAq0CrQOlAD0eEQA9A8sBMQHIACaCdoP1gjWDJoKIAgAAPd4QgD6BxYC8gOACHYHzAFfAMwB9QdUAQAA+ngAAIIA/gcSAuADSgjvBOoC+gDvAuoCAAwBeQAAQgD6BxYC4gEIDP8ArAb9AKwGLAAABw55hAD8ByQCxAsUCEwEXgfQD0wJXglUCRAIGXkAAAQB/APkCw4IVAfUAUAIDAfsDywJZAA6eQAAIAQkAqQBJAgkCOQPJAAkAKQBJAIgBDx5AACIAYoA7g9YAIgBAAD+BwAIAAgACAAGPnkAAAgBiADOD7gACAkgCCAI/g8gCCAIIAhBeQAAiABKAOwPWACIAAAA/A8EAHQCjAEAAEJ5AAGIAMoPeACIACAA/AcgCP4JEAj4CAAGSHkIAYgAzg94AIgJAAT8AyQAIgDiDyIAIABJeQgBiADuD1gAiAgACPAPAAj+DyAIIAgACFB5iACIAO4PWAAIAYAA+A9OBEgESATIDwAAVXmIAIgAzg98AAgI4AwAAvIHxAgwCGwGgABWeQgBiADKD7gAAAj8DyQJJAkkCSQJ/A8ACF15iAFIAO4PWACACDwEJAPkACQA5A88CAAGXnmIAYgA7g9cAIAA+AMoASgB/g8oAfgBAABfeQAAgASWBLQCtAC+B7QAtAK0ApYEgAQAAGB5gABJAOsHWACCAOoDKgEqAeoJAgj+BwAAZXkIAYgAzg94AAgAQAFKAUoB+A9KAUoBCAFoeQQJdAXUBdQB/AnUCdQH/AHUBdQFdA0ECW15EAAQAZgIbgRMAXQJSAlGD1gBZANUA4wMd3kIAYgAyg+4AAAEVALUAX4DVAlUD0QBAAB4eQgBigDqD5gAAADcD1QB9ABUC1QI3A8AAHp5CAGIAOoPWABACAgJ/gVYAVgB/gUICQAAgHkAAAQK/AuMA/wL3AveD/wDjAf8BwQKAACBeQAAFAlMBV4BTAlECVAPTAFeBQwFNAkgAIR5iACIAM4PfAAIAEIEKgIqCeoHKgG+AqAEhXmEAEQA5g9cAAQB8AGqAfgHrAGqAfgBAACNeYAAiADsDxgAwA98AMQH9ALUA1QI/AcAAI95iABIAO4HWACCAPoPagVqBeoHagV6BcIHpnkAACQFswWABesB/gHaB4ABvgOCAz4FAAWneQABigDqD5AABAB8D9wLXgtcC9wLfA8EAap5xAAkAPUPLQBAAv8CrQL/D6oCrQL/AgACrnmIAUoA6g+YAAAI/gv/CuoK/wrqCv4LAAixeQABigDqD5AAxA/8BfwH/gb8AvwP3AIAALl5AACED7wArASsBPwHrASsAqwKugiCBwAAunkAAIAP/ADUAtQC/APUAtQC1Aj8CIAPAAC7eQQABA90AWQFZAfWBVQFVANECXQJBAcEAL15EAAID+gBxAGUBbIHugWyB4QJ6A8IAAAAvnkgBCQCJAGkAGQA/A9iAKIAIgEiAiAEAAC/eQAAkAhUCFQENAN8ADQANAdSCFIIkASAAMB5iAhMCCwEnAOMALwAigqaCSoJSgdIAAAAwXkAApIBUgD+D1IAUgQAB/gEBgTABAAPAAjDeQAAUAhUCFQENAO8AJQANAdSCFQIUAYAAMZ5AAAYA5gA/A+UAAABRABEAPwPRABEAEAAyXkAACgEugS6AroBugH+D7oBugL5AigEAADLeQAAkgNSAP4PUgAACDgEgAN+AIADMAQICM15lANSAP4PUgACAPgBiACIAP4PiACIAPgB0XkAAJQDUgD+D1IAEAFCAUwBAAH+DwABAAHSeQAAlAFSAP4PEgCACDgEgAR+AgAB2AAAANV5EgOSAP4PUgAAAP4PIAQAAP4HIAgQCAgG2HkSA5IA/g9SAIAJYAT6B4IIYAgeCOAGAADfeRQDlAD8D1QAlAkACPwPJAkkCfwPAAgAAOR5AAAUA5QA/A+QAIQAtACEAPwPhAC0AIQA5nkgAawIbASsA7wDrg9sASwDbASsCCABAADneQAAFAOUAPwPkgAACPgIiAb+AYgG+AiACOl5lANUAPwPUgCSCBAETgJIAf4ASANIBEAI63mSA1IA/g9SAJICAAaQAXAA/g9QAJYBEAbveQAAlANUAPwPUgAACHwGRAFEAEQBfA4ACPB5kgNSAP4PUgCSAhACzwEECPwPBADsAQQC+HkUA5QA/A+SABoASA9ICUgJfglICUgPCAD7eQAAlAFUAPwPUgACCagErARWBXQCzAFAAP15FAOUAP4PUwAACZ4JUAhwBV8GUALQAV4AAHoQA5IA/g8SAAAB6gesALwApA+sAKoEqAMFehIDkgD+D0IACAj0BJIDkACSD+QICAgQBAt6AAAYA5gA/A8AATwIpAqkCqQPpAq8CgAIDXqSAVIA/g9SAAAA8gdUAVABXgFQBfYHAAAOegAAlANSAP4PAgA4DMoDSADMD04IeggABhp6AACUAVQA/A9SABAA/g+oBPwHqgSoBAAAIHoYA5gA+A+UAAAM/AMEANQH9ALUCwQI/AcjehAA+AVWBfQFXAX0BiAHpAD8D6QAIgcAAC56AADKASoA/wMACP4Krgr+D64K/QoACAAAMXoUA5IA/g+SAAAC6A+kAqQC6gOiCroK4gcyehQDkgD+D1IAEgDADxIAwg9aBUIF2g8AADN6JAIkAfwPogAABlgAVgVWC1QJXAHwBQAIN3qUA1QA/A9SAAAJfgmWBdYGvgZWBVYIXgA7eooBSgD+D0kAAADKB6oEgQQtBKEE7QcAADx6FAOUAPwPUgBABVwFtAJ2CbQG1ABcA0AEPXoUA5IA/geSABAAdAesB64HtAe2B5YHVAA/eooDSgD+D0kAgA9eAFYPVgVXB14Awg8CAEJ6FAOSAP4PUgCABnwArAysCf4KrAKsBvwIRnoSA5IA/g9SAIAIvAwsBSwF7gYsArwCgABMehAM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fXwsA6AA/g+gAAwBQABECEQI9A9MAEQAQACJfCwDoAD+D6AALAlgBFgGxAFACEYImAcgAJJ8LAYgAf4PoAAsAQAIaAiICw4IiA9oCAgIl3wIACAD/A+gACwBAAj8DyQJJAkkCfwPAAiYfAAALgOgAP4PJACAD4AE/gSIBIgEiA8AAJ58jAMgAP4PhAH8DxQE/AUUBPwEFAX0DwAAn3wECXQF1AXUBXwDVA9UAXwDVAVUBXQFBAmkfAAAgAD8AMQD1gLWAtQK9ArEDvwCgAAAAKV8AADyCJIIngc8A/4PKAAEA3AIkgieBwAAp3wsB6AA/g+oAAAM+AMICEgI7g9ICEgIAACqfAAAKAqoCqoKnAu+AogCmAacB6oKqAooCq58JgegAP4PoAAuAQAA/A9UBNYAVAN8BAAEsXxkCREFQQWMAyABkg8uAUIDwgV+BQwFMAm5fAMA0AH/D1AAkwGAALoAggDjB5oAkgCiAL18AAa4Af4PIAAIAwQIpAanAKQPpACMAoAMvnwCACwH4AC+DwAA1A/cAtwC3grcCtwPFADKfAwAIAP+DywAgA9+BMgDAAz+A5II/gcAANV8BgCgA/4P6AAACKgGqgCsDvgArAyqAIgO1nwGANgA/wNYABAP/AB0A/QC9gL0AvQDIADZfAwAoAH+D6gAJAlABNwHAAisC7wKqAqoC9x8AA78AQQIHAW8BS4Dhg8cA7wDHAUsBQAA33wGAKAB/g+MADoA1g//CtYK/wrWCv4PAADgfAMAkAH/D8IC/wEBAlUB/wfXAz0BkQKBAud8qAH+D6AAKAjgC/wL/Av8D/wL/AvcCwAI73wDANAA/w/eAY0HvQClB+8ApQetAL0HAAD4fIAEhASYA5QB4wDQD0gARAF0AUACgAQAAPt8AAAABJQE1ALcCLQIlA9SAEoBQgKCBIAE/nwAAJAO3ACyDIgCAAD8AwABAAEAAf4PAAAAfQAASAd8ANIPSAEAAOQHJAgkCCQIfAgABgR9SAd+ANAPTAAAAxAATgCICQgICAz4AwAABX0AAEgHdgDQD0wA4AoECAQI/A8ECAQIAAgKfQAAFAhUBVQFfAH0CVYPVAEcBZQJJAokAAt9SAduANAPTADgCggIOATIAg4DyAQ4BAgIDX1IB24A0A9MAAAB+A8IAcgAPgDICPgHAAAQfRAOnADyDsgAgAIECEQM/AtECPwPQAgAABR9SAduANAPTAEAAOgDCAEIAf4HBAnkCQAEGX1IB3YA0A9MAGQBAAT+ByIE/gEiBiEMAAAafUgHWAD2D2AAQAsEB/wAhAQkBTwD4AQgCBt9SAd2ANAPTAAAC3AITgbAAUIITgjQByAAIH0gACoJagVqA+oL/wlqByoBqgWqCSALIAghfUgHfgDQD0wAxAoACAgH+AAuCCgI6AcIACJ9AAA0CBQFVAX0AV4JVA80AbQFFAU0CQAAJ30ACB4JgAXeAcAJogmSD14BUgUeBSIJIAArfRAJHAlQBV4FtAGQD04BFAWUBRIJCAoAAC99AAAACD4FagXqAX4Jag8qAaoFPgUACAAIMH1IB3YA0A9MAcAA/A9EBEQE/AdEBEQE/A85fUgHbgDQD0wAAAMgAKIPngSCBKIEng8AAEJ9SAduANAPTACAAogATgQ1BTQFTAlAAAAAQ30QDtwAsgZIAEAHSABoBloFzAQoBggMAABEfUgHbgDQD0wAAAMACPwPJAkkCSQJ/A8ACEx9SAduANAPTAAAA0IIJgkqCZIPKgkmCUAIUH1IB24A0A9MAKADBACkD6QEvwSkBKQPJABVfbAN7ACiBJgCAAD0BzQJLAnkCTQJLAngBV59SAd4ANYPUAAACygImAQYA84DCAQoCCgAYX1IB24A0A/MAMQDkADID9YEpATcBEQPgABmfUgHbgDQD2wBIACQD4wEogSkBIgEkA8gAG59AAAsCCwFlgHUCcwJgA9eAVIFEgUeCQAAcX1ID3YA0Q9MAAAJBAS8AycALAC8DwQIAARyfQAAkA78AJIGSAIAAFgDdgjQD0wA4AIABHV9SAd2ANAPTAAACxAIiAamBaQEiAawDBAAdn1IB24A0A9MAQAA+AeWCJYI/AicCJQI8AaTfZAMvAHiDNgAAAo6CEIJEgnqD4IJPglGCJl9QAduANAPTAAAAf4PAASoBP4FoAQsBQAEmn0AAEgHfgDQD6wDgAlUBFQDXgBUBtQIBAScfTAO7ACiDJgCAACMDKQCpwCkD6QArAKADKB9MA7sAKICmAQABNoCVAjUD3QATAKABAAArX1IB24A0A9MAEADEAD+D6gE/AeqBKgEAACxfU4HcADsD0AB/A/sA+QDJAKsCyQI/AcAALJ9SAd4ANYPgAL8DwwAvAPkBLQEBAD8DwAAv31IB24A0A9sAQAAvgeqAKoA6w+qAL4EgAPKfQABPgUuBb4F7gGuB6IBWgMaAyYFQgUAAM99SAd2ANAPTAAAAV4EQAD8D2QJcQhGA4gE0X1IB24A0A9MAAAFIASqAioI6gc+AaAGAADSfUgDdgDQD0wA4AOEAJQHfgVUBVwF1gcQANp9SAduANAPzADABZwCrAksCO4PLAO8BAAE4H1IB3gA1g9IAQgAoAeUAJwA1g+cALQHAADjfSAIvAziAtgCgAQgBH4DtAq0B7wBIAYAAOh9SAduANAPTAAAD/wHrAKsD6wCrA+8AoQP6X1IB24A0A9MAEAJFARcA/QJ1AbSBtwFVAjvfUgHWAD2D2ACAAT0BbwHtgW0D7wF8AUABPR9SAd4ANYPSAAAAvwErAKsAf4PrAH8AgQE+32QDtwAsgTAAZwE1AeUBAQA8AwOA/gEAAgBfkgHXgDwD2wAgAIgBGoDqgpqB74AIAcAAAR+RANfAOgPJgAAAfwHvAK8AvwHvAq8CvwNI35AAnwBfAD8B/wASAIYAXwE1ANUANACgAAmfkgHbgDQD8wAQAL2D5gHFgTwD5YIEAgAACt+EA7eAHEEbAMBCHYG4AksCLsK+wsmCgAILn5AB34A0A9MAUAA7A8EANYHdAVUBdQHAAAxfhAO3gCxDMwCAAD3DwAEzgMBBOgHhgiYCD1+kA7cALIMiAIADPwChAaWCaQLhAD8BgAAPn5IB24A0A9MAAAK/Aj8Bf4F/AH8BfwJEAhBfgAIMAq+CjwL/AM8D4gCXgZkB1wKhAoAAEp+QAdOAPAP7AHAB/QHHgT0A5AG/geQDBYCVH6gAy4A8Ae8ABAA/Ae2AtgPPwPQBBYOAABefpAO3ACyBIgCAAiqCeoHrwEKD+oJqgmABWp+AAd4AJQGUgEIADQH8gX6BdIF9AX0BwQAa34AAH4Kfgd/B/4PfgsYB/YC0gp+CpgKgAhwfkgHbgDQD0wBAATwAt4B+gfqAdYC8AQAAHN+kA7cALICCAk+DOsD6wm+BzQMiwN4DAAAfH4QDtwAsgZIAv4PNAi6DzgJPgisDxALAAiMfpgO9gCRBkgBEgjuB/4H7wP+A+4H+gcACI9+gA7cAKIGWAEADPwD9An+C/4O/Av8C4QJln5QB3wAagIACXYE9QcQBPYPMAT+B9AMFgKgfqAEsAVsBSIFkAQAAPwBAAEAAQAB/g8AAKJ+AAAwCewEogSYBgAABAQEBPwHBAQEBAQEpH4AADAJqAVmBRAFQABEAEQA/A9EAEIAQACmfqAEuAXkBJIEgAIwAI4AiAgICQgM+AMAAKd+IAW4BeYEkAIQDIQDfAiEBTQCrAVgCAAIqn4AACAFuAVmBRAFAADEB0QIRAhECPwIAAarfgAAMAXoBaYEkAIACHQEBAP8CAQM/AMAAKx+IAW4BWYFEAQAAqgAqAD+D6gAqASIAwAAr34gBbgFZwUQBQAE9AEEAQQB/wcECfQNBASxfgAAMAXoBaYEkAIACHgIAAT+BAACmAEgALJ+AACYBdcEsQQAAP4PAgCyAdoBAgj+DwAAs34AADAFzgUiBQAA8A8QA/AAnggQCPAPAAC1fgAAMAXsBaIEkAAADv4BAAwAA/4AAAcACLd+AAAgBbgFZgUAAWAIWATEA0AIRgjYB2AAuH4gBbgFZgUwBQAA/A9ECEQE/AFEBkIIQAa5fgAAMAXsBKICmAoACDgEygIOA+gEGAQICLp+AAAwBawFYgUYAQAICAf4AE4ISAjIBwgAvX4AADAJrAVjBRgBAghCDP4LQghCDv4JAAi/fgAAuAXkBJICgAoQCFAEfgTIAyoFqggABMN+uATkBLICAABUBnwBVgj0D0QARAEEBgAAxH4AACAFuAVmBRABAAj8DyQJJAn8DwAIAADFfgAAIAm4BWYFAAD4AygBKAH+DygB+AEAAMZ+IAWwBW4FIgUAAPwPRAREBPwHRAT8DwAAx34gBbgE5gSQAgAIfAZEAUQARABEAXwOAAjIfgAAMAXoBaYEkAQQAEgCVgQkBVQFTAiAAMp+MAqsCWIJEAUAACwBIAH+DyABLAEiAQAAzX4wBZwE8gKIAiAAog+aBIYEogSiBJ4HAADOfiAF+AWmBJAEBACsAqwClA+0AqwCpAIAAM9+IA24BeYEkAAACKQIpAiUD6wIpAggCAAA0X4AADgL5gmQAQAIKA3+AwAA/A8EAHwChAHSfiAAmATkArICCABABugBCAh+BIgHaggIBtN+MAXsBKICmAIAAKQHpASkBL8EpASkBwAA1X4gBbwE4gSYAgAIpASmA7wAtA/ECKQIAATYfjAF7AWiBIACIAiQDqwJpgSIBpAEoAgAANl+IAW4BOYCgAIgAKAPsA+uBKgEsA8gAEAA234gBLgFZgUSAkAAqAKoAq4ClA+sAqQCIALcfgAAMAXsBKICkAIQAEgPtgSkBLQETA9AAN1+IAWcBOIEmAQAAPgHlgiWCPQInAjwCAAG3n4gCbgFZgUQAUAIOAiYBQoCyAUoCEgIAADffiAFuAVmBZIEEAJACGgHXgBID2gISAhIBuJ+AAAgCbgFZAUAAOAPvAK0ArQKtAr8DwAA434wBawE4gSYAgAIrAScA4wAvACaCSoHAADlfjAF6ASmAqACCAhEBeQGagLCBVoMQAQAAOd+IAC4BeYEsAIAAPgHBASgBP4FYASsBQAA6X4wBZwE8gKYCgAI3AVcBF4DXABcBNwJEADqfgAAmAT2ApICAAJUANQHfgVUBVwF1AcSAO1+IAW4BOYEkAIAALQIFAUeA9QBFAVwBRAI7n4AALAF7ASiBDgAoAe0AqwCrgs0CNQHNADwfiAFnATiBJgCAAD4AqgCqAKuD6wC/AIAAvN+AACwBWwFIgUAAPwDtAL0B7QKtAr8CwAA9H6wBOwEogKYAiAA/A+qBKgE+geoBKgEAAD1fiAAmAXWBLECAAC+B6oA6w+qAKoEvgMAAPd+IAX8BbIEAAz+A5II/gcADP4Dkgj+BwAA+H4AALAF7ASiAgAI/AcEANQH9AIECfwHAAD8fgAAIAW4BWYFAAUYAIgCqgisD6gAqAKABP1+AAAwBegFJAUAASgMqAMoBO4PKAkoCQAA/34AALgFZAUSBYgAQAQqAioJ6gcqAb4CoAQAfwAAOAqkC3MJAAyqCJoGBAmgCZIGnguiCAV/AAC8BeIEmQIIAOIHEgTyB14F8gfyBwAABn8AANgCTgJ5AQAE7wQ/AqABKAMmBOwFBAQOfwAAOAXmBJEAAAL8D1ICAAjeBUIC/gVgCBN/IAW8BOMEmALADFQC8gnWBtEG3QVVCAAIFH8QBawFYgUYBQAAtAecANYPnACUBLQDAAAVfwAAOAXkBLIECAKgCKoLmAbeBJgHmgSoCBZ/AAC4AuQCkgAABvwBlAfWA9QHVAHcBwAAGH8gBLwFYwUZAAAFbAVrBaoKqge+ASAGIAQZf5AE3AKjApgCAgDqD2IFfgV+BWIF6g8gABp/IAWwBG4FIAUAAHgBeAV8AXgJ/A/4AQABHX8AANwFswSIACII4AcECK8K6guuCqIKAAggfwAAOAXkBRIBAAz8A3QIrgr+D6wK/AoACCR/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SANABAAA/A8EAPwDK4EADP4Dkgn+BwgA9AySA5AAkg/8CBAIAAQvgQAM/gOSCP4HAADoD6gCqAL8D6gCrgroBzGBAAz+A5II/gcAAHgESgfMAMwPSgh5CAAGM4EADP4Dkgj+BwAA7g8ABEEFzgQABO4PAAA4gQAM/AMkCfwPIASQBSgEpgQoBxAHoAQAAD6BAAz+A5II/gcAAPwB1AFUAX4HVAFUAXwBSoEADP4Dkgj+BwAAFADeB1QFVAVeBdQHAABLgQAM/gOSCP4PAAD0DwQA5gxUA5QFdAgACEyBAAj+B5IA/g8AAOgDuALsB6gK+AsoCAAEUIHADzwApA+kALQGhAWmBZQF1Aj0CJQPBABUgQAM/gOSCP4HAACkCJQIhg+UCKQILAgAAFWBAAz+A5II/geAAEwItAdGAPQHFAj0CQAEZYEADP4Dkgj+BwAB/gjqCqoKqg+qCr4KgAhmgQAM/wPJAP8HAADvDyAEtwQoBSIE7QcAAG6BAAz+A5II/gcABHwDVABUB/wIVAhUAXwHcIEADP4Dkgj+B5IAqgf+BqoEvgOqBLoIAABzgQAI/geyAP4PgAD8D6AExA/4BwQA/AMAAHiBAAz+AxII/gcAAP4G6gHqBOoD/gjABwAAeYEADP4Dkgj+BwAAfAXuBewC7AX8BAAEAAB6gQAM/gOSCP4HAAC8AqwJLAjuDywDvAQABHuBAAz+A5II/geAAXgOeAD4BQgI/gMIDAoGfoEACP4HkgH+D4AB6gS4Bq4GqApqC6kGgAB/gQAM/gOSCP4PAAjuBwAI/AtUCNQJ/AoACICBAAz+A5II/gcAAFQO1AFUCVYJVAlUBwAAioEADP4Dkgj+BwAAeAV4BXgBfAl4D3wBeAGPgQAAZAA8D/wHvAe+B7wHvA/8DwwPZAAAAJiBAAz+A5II/gckAdQF/AHUD/wB1AX0BQAAmoEADPgDCAD4CPgH/gP8B/wH/A3cDxgAAACbgQAM/gMCCP4HEADKBagFrgeoBcoFGgUAAJyBAAz+A5II/gcAAHQFdgf0AXYDdAV0BQAJnYEADP4Dkgj+B4AAVAVMAj4PTAJMBVQEAACggQAM/gO2CP4HAABUCqIKvgpABVQFAgI+AKiBAAj+B5IA/g9AALQGvgR0BQAATAwiAwABs4EACP4HkgD+DwAAVA9WC/wLVAvWC1QPAAG9gQAM/gOiCP4HEAD4B5YItA+cD7QP0A/AAMCB8AAOAPoPugP6A74DgAP2C9ILPgdYAEAAwoFAADwA/A/cA9wD/AOwA7wL9gu8BzQAEADJgQAM/gOiCP4HAADwB7gF9wBVDKQC6AwAAMqBAAz+A5II/gfgAN4G+gH6B+oH1gHwAgAE04EADP4Dkgj+D+QH/g90B/QFHgD8BJwHWAzjgQAA/geSBJIEkgSSBJ4HkgSSBPIEAgQAAOWBAAD8B6QEpAS8B+QEAAyAA3wAgAEABgAI6IEAAPwPlAScB5QEcAuYBKYHVA/UBPQPBADqgQAAAAD8DyQJJAknCSQJJAkkCfwPAAAAAO2BAAAACXwFXAVcA14BXAFcA1wFfAUACQAE84EECKQItAisCKQIpA+kCKQIlAikCAQIAAD0gQAAvASkBJQHlAS0AiAIfgSIA+gCGAQICPqBhAn8DdwP3A3cDd4P3A/cD9wP/A2ECQAA/IEAAPwPRARCBEIEAAREBEQERAREBPwPAAAAggAA1A9UBUQFRAUUBCQFAgViBXoFyg8AAAWCAAAcBfwF/AX6A/AB/AH8BfwF/AX8AwAABoIAAAAJ/AVSBQAFXgF0AVQFAAXUBTwJAAAHggAAAAn8BVQFAAU+AXQBAAVUBdQFPAkAAAiCAAAACfwFBAX8BSwBXAEkAfwFQAX8CQAJCYIAAMAAfAJaAsAC7gfcAsgCXAL8AsAAAAAKggAAJAD0B/QH9gfwBvAG9gf0B/QHlAcAAAyCAAAKAMoPSgRKBH4ESgRJBEkEyQcIAAAADYIQAFAAUAdYBVQF8gVUBVQFWAVQB1AAEAAOghAAUABID0QJUgl6CVIJVAlYCUgPUAAQABKCEABID0QF8wVEBQgHYABqCPIPLgDiAAAAFIIAAJIP/gSSBNAP1AE0CJwPFAA0AlQAUAMXghAASA9WBXwFWAcQAMAPqAL+D6gC6g8AABiCEABYD1QF8gVEDwwA9A9WBVQFdAUcDwAAHIIACbAIUgVWAtIBFgDSA1IC2Q9VAlACAAAeghgJWAn+BtQC/AHUAPwD1AK8B9QCkAIAAB+CQAhABvwBRABMAU4BVQJECEQI/A9AAEAAKoJADPwDRwBVCfwHAADoDygALgDoDwgEAAAsgkAM/ANOAEUN/AMACN4IQgVCBs4FUAgAADCCAABADPgD1Aj4DwAAfg4CAfoHAgj+CAAGMYJADPwD1gBECPwHEADoBycIJQnoCDAGAAA1gkAM/APWAEUI/AcAAOgHigiMCEgIWAgABjaCQAjAB3wAVgn8BwAA+A+IBI4EiAT4DwAAN4JADPwDVwFFDPwDAAhoBFgHzgRoBCgHCAg5gkAM/ANEAFcJ/AcAALgPhgSABI4EsAcgAEeCQAz4A14BSgj4D7QH7AQACCQK/AsiCgACWIJADPwDzwhFCPwHAAC+CKAH/wSgBrwFgAhmgkAP/gBbB/4BAAT/B9UE9wfcBI8HpASkB2+CAAAACPwHVARUBNYEVAFUAlQFfAWACAAAcIIUBCQCxAF8BgAA/g9SCNIIUgFSBn4FAAlygiAAEAD4B5QIlgiUCPQInAiQCPAJAAQAAHOCAAAoASgB/g8oAQgA+AeWCPQInAjwCAAGeoIAAAQAJAQuCiQJpAikCGQILghECAQGAAB+ggQIBAgkBM4EBAMEAgQDzgQkBAQIBAgAAIKCBAAkACQALgDkDyQAJAAkAi4C5AEEAAAAi4KEAJQAlACWCJQIlAj0B5YAlACUAIQAAACNgoQARAA0ALYAJAEkAiQIJAguCCQM5AMAAJKCBABEAMQHTgREBFQEZAREBE4ERAREBAQAl4IECAQJRApmCdQFVAdEAg4DxABEAAQAAACZgoQIpAikBK4EpAL0AaQBpAKuBKQEpAiECJyCggiSCJIIlwSSApIB8geSCJcIkgiSBIIAnYIECEQERAJeBEQMdApECkQJ3ghECEQIBAilgkQARAgkBK4DJAAUABQAJACuDyQARABEAKaCAAgEBvQBVgFUAVQBVAFWAUwBzAMEAAAArIKEAEQIxAiuBKQDhACECKQILgdEAIQABACtggAABAD0B5YIlAjwCJQIlAiWCJQI9AgEBq6CAgDiDyIALwIiAbIAcACiAC8LIgjiDwIAr4IIBIgDCACcBwgIKAhICIgIHAaIAAgHCACxggAABAGEAOQPDgAEAeQHjghECEQIJAgABrOCJAgkBCQGLgHkALQIpAikCK4IpAckACQAt4IACAQIxA8OCAQIBAjwD4QIjgiECAQIAAC4goQApAikCK4PpAykDKQMpAyuDKQGpAiECLmCBAgEBPQDlgCUAJQAkACUD5YAjACMAAAAvYIECJQE1ASWApQClAmUCZQI9geUAJQAhADHggQAFAFUAVYB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5APWD/AL6AvwC9QL9gvkDyQAIAC/hAQAFACUD/YA9Af0BfQF9Af2AJQIlAcEAMSEkACUALQH1gfUB9QH9Af0B9YH1AbUAJAAyYQAADQCFAFWD5QJVAlUCVQJlglUD1QDAAHLhAQARAjUDtYK1A70CtAO1ArWCtQMRAlEANaEAAAEAPQO9gr0CrwAvAa0CpYK9AoECAAE3YQEAAQIZA8OCWQPBAk8Dx4J1AmUDwQIAADmhEABRAX8BP4G/Ab8BvwG/gv8CvwGRAAAAOyEFAhUBMQHDgjkC9QLtAu0C7YLtAs0CkQA7oQACLQE8gMDBPoJWAtaC/4LXwtaC/oLAAIRhQQAdAzUA9YB9ArUCNQJ9gbUBtQI9AiABBOFAAjEC3wLfgv8D3wHfAf+B3wLfAvECQAIF4UEDPQDFAhWBNQBVA1UAVQF1glUAFQOBAAahQQP9ABUDNYB1A/wAQQEpAEmCPQPJAAAACGFJAmkCJQF3gG0CZQJhA/2AdQFtAwUCQAAI4UECXQHRAHuDwQAVAWQBXQJVgk0DxQBAAErhQQIVARUANYB1An0BfQB9gH0A/QF1AMAACyFBASUB/QHlgQEAFQPdABWD1YAdAd0CIQENYXEDzQA9A92BXQHdAXUDX4ElAf0CDQIAAY6hQQAxAcUAMYD1APUA9QD1gdUBhQE9AMAADyFRABUBMQHBgB0AfQH9Ab2BfQG9A70BwAAPYUUANQPxAfuD8QD1A+ECO4EJAPkBSQIAABDhUACSgJKD+sLSgt4D0oLRgvnC1YPQgEAAkmFJAgkBvQAdgF0DXAB9AF0DXYBdAEUDQAASoUEBnQABAauCEQFVABUA0QGLgiECTQIBANphUQIVAwEAo4AhAX0BfAD9AX2A/QJhAcEAG2FAAAkCHQHdgdwD/AHdAJ2D3QHdAckDwQAcoUEAOQB9AHmB/wB7AEEDP4DTADMD0QAAAB0hUIKYgnSCkcFIg0CCPoPqw+qD6oJ+g8CCH6FAABkACwP7gssC3gPLAvsC64LLA9kAAAAhIUkBEwHRAAWAfQB9AP0Af4F9Af0AfQBAAGHhQABNAGEDwYAtA6wALQOhADeCCwH5AUgCJuFAAD0D1QFVgV0BwQAlALeApQP1AKUAoAApoUEDvQBtAi2A/QLtAO0C/QDtge0C/QHBACphQAA+g86AMMN6gMoCKoKrgq/D6oKqgogCKqFBARUAVwJ3gd0AQQM9ANeAFQA1A9UAEAArIWEAJQIRAUGBfQDtA+0AfQDBgVEBZQIlACvhQACdAPUA9YP9A/UD9AP9A/WD1QPdAEAALCFAgiKDf4F2wHeBf4B3gX+Bd8B/gWKBQAAyYW0BLQC9A+2AZQCBADUD/4K3Ar0CtQPAADNhQAA9AT0B/YF9AfwBQQHXAVeBVQHVAQAAM+FAAl0B0QB9A/2A7QG9AYeD/wEFAfUCBAE0IUUBlQGVAPOCiQHBAD0CVQHXgFUD/QJAATVhYoEqgL6D6sDqgECDvoB+wOqA6oJ+g8AAN2FBANcB1wH/gv8C5gLQAc2BxQHdAqEAkQA5IUEDPQDVAn2DwQBdAX0AH4PZAL0BWQJAADlhQAItAXkBQYF9AGwD7QB1AN+A2wFBAUAAOmFIgRqAwIBNwCyD/IKsgqzD6oK6g+iAAAA+4UCACoMSgMLBeIDvgN2D5cPdgO+BeIFAgUHhiQM5AF8Df4BdA3kBAACVAH2D0wBTAYEAAuGRABkC0QI7gVkAnAI9Av2CvQC9Ab0BwAIEYYCCPoHCgRrBWoPagsKC2oLawtqDyoBCgAthgAAAAD+D/8H/gLgB8AC/gP/BT4A/gcAADiGBAD0D/QGfga0BvQLJA7+AH4F/AN0ARQFToYAAAAM8AMQCFAHfgHUAbQHlAi0CLAEEABPhgAAAAz4AwgIKAk+B1wBXAVMCVwNWAMIAFCGAADADzgAiA+oCr4K3ArcCswK3ApICCgAUYYAAAAP8AAQBlAAfgbUCLQKtAiUArAGAABUhgAM+AMICCgJKAs+DWwFbAtMC1wJWAkIAFWGAAz4AwgLqAaoBj4JXAjcC9wI3AtYCggAWoYAAAAP8AAQClAIfg60CLQOlAi0CpAIUABbhgAAgA9wABALUAp+D1QItA6UCrQKMAgAAF6GAAAADPwDBAiUC38HtgO2A7YH5gcsCgAAX4YgAO4EqgSqAyYG8AEYDDgDXwBaB0oEGAJnhgAM+AMYAd4PvA+MCxgI8gCSCJIIkgcAAGuGAAAABPgEiASIBP4HiASIBIgG+AQACAAAcYYABPQFNAU0BfQHNAUsB+wHBAj8AwAMAAZ5hgAA+ASIBP4D+AIABAQEBAT8BwQEBAQABH2GAAAACNwLVAlUCfQHVAVUBVQF3AUACAAIfoYABPgJjgf+B/gGAAgEAPwPJABEAIQAAACAhiAAFAjKDwgEGALwCIgIiAT+B4gEiAX4B4GGAAj4CYgE/gf4DgAIeASCBQwD4AQcCAAIgoYAAPgE/gOOA/gHAAB0AUQBRAl8DMADAACKhgAA+An+B44H+AYACBgI6gwKB4gDeAQICIyGAAD4BIgE/gf4BgAEKAEoAf4PJAEkAQABk4YAAPgEjgf+B/gGAADyCJIIngcAAP4PAACVhogASgjqCVoJTgnqB0oFSgVaB+oHSgxICJyG+AWIBP4HiAT4BBICIgGiCWII/gciAAAAo4YAAPgJiAT+B/gGAAw8AAIOwAkOCHALIAykhiAEIgTSBVYFWgXSB1YFWgVWB9IFIAgAAKqGAAD4CYgE/gf4BgAMJADIAgAC/g8AAQABr4YAAPgJiAT+B4gE+A4ACPwPIgjiDyIIAADAhgAA+A3IBP4D+AoADMgIygj6D8gIyAgACMaGAAT4Bf4HiAT4BgAI/A8kCSQJ/A8ACAAAx4YAAPgE/geIBPAGCADoBwoJjAiICFgIAAbJhgAI+AX+B4gE+AoAAFgARAJTBkQJyAAQAMuGAAASBMoFSgVSBd4HVgVWBVYH1gUSCAAA1IYAAvgCzgP+A0gCMAP+D2IEkgRiBP4PAADZhgAA+Az+B/4H+AYACCQJJAm/DyQJJAkgCNuGAAj4Bf4HiAT4BgAAXgZIAf4PSAFIAgAE5IYAAPgESAT+A3gDIAC4D6YErASwBKAPAADuhgAEFATUBUQFXAXGB0QFXAVEBdQFFAgAAPmGAAj4Bf4HiAT4CgAA5A9kAvQPbALkDwAA/oYABHgE/gN4AwABlAj8B5AMfgKQBVYIAAYAh0AAXAD0BXQFfAX0B3QFfAX0DTQI/AcAAAKHAAj4Cf4Hjgf4ClAASAVuBdQPbAVEBUAECIcACPgF/geIBIgE8A5MCVQF1ANUBVwJQAkShwAA+AX/B/gGAgi+B0II8AsCCv4LIgoACBOH+AWIBP8HiATwBhoP5gUACCQK/gsiCiIKFYcAAPgEjgf+B4gE+AIwDM4DyA9OCHkIAAYXhwAA+AX8B4gEcAKMD1QAVAH0AVQI3A8AABiHAAR8Av8DxAd4DCsC/AEkA/4FAgL+BwAAHIcAABQEpAekBrQGtge0BqwGjAaUBxQIAAAhhwAA+ARIAv4DeAMABtQHXgVUBV4F1AcQADuHAAD4BYgE/gf4CgAA/A88Az4DPAv8BxAAR4cAAPgJ+ASOB/gGAAj8A7QC9Ae0CvwNAARJhwAA+AmOB/4HiAT4BnAAqgL4D6wC+gIAAEyHAAR4Av4DOAOAAP4PkAAkAAgB/g+AAAAATof4CYgE/geIBHgB4AdeBGoFagVqCP4HAABXhwAE+AWOB/4HiAfwCLwK1ArWD9QK/AqACFmHAAj4Bf4HiAR4AsAHvALUB1YB1AdUAdwHYIcAAPgJmAj+B/gKAAD0D1QK1A9UCvQPBABmhwAI+AT+B4gEcAL+D5ICDghgCWIH3ggACHSH+AmIBP4HiAR4AIAHfwKAD/4DEgj+BwAAdocACPgF/gf4BgAAfA1IA/wPaAN8BUgJAACChwAI+AX+B4gGcAT8B1YFPAL4DwQA/AMAAIOHAAj4Bf4HiATwDgQIVAbcAVYJVAlUBwAAjYcEAPwP7ATsAnwJgAd4AIgI/geIBPgGAAiehwAA+ATOA/4DSAIwAX4GqgL+AaoJggcAAJ+HAAT4Av4DyAJ2A34JWgVaBdoBWgV+BQ4JoocAAGIE6AfuBuQG4AfyBugG7gboB3QIAAi6hwAA+AmOB/4HiATwBR4J6g1+DyoBvgsACsCHAAj4Cf4H+AYACJQC9ALuDtQCBANUAgAAxocABPgCSAL+A0gCMAtkCHYH9AF2A3QNAATLhwAE+AX+B4gE+AQAAlwENAl8CTIAWgaQANGHAAj4Bf4H+AYACPQDdAN0A3YP9AMQAgAA8ocAAKALrAqsB6wHPgisA6wKvAesBqAHAAj5h4QEfAQ3Bb4FtgV4B8oHtgWyBboHNggAAPuHAAT8Av8DRAJ+ATsL2g9+A+oHKwdqCwAJDYgACPgF/gfwBnwPPAO8B+ADMAf+AAgDOAQViAAI+AX+B/gCAgA6D0oH3gFaD2oBag9AAB+IAAD4Cf4HiARwAiYPeAt0APoPUAR+AwAMIYgAANQF3AW+B78Ftwk/AJcFrQesBaQFAAAiiAAAqgWeBf4H/gX+Cf8A/gX+B54FqgcgCDuILAAXBN4FQAV2Bf8HfgVwBWQFvwc0CBIAQIgABPgHCAQIBPwHCgQIBPgHCAQIBPgHAARFiAAA+Af8B/oH+AMCABwBIAH+DyABLAEAAEaIAAggCbwEJAS8AKYPfAEkAiQFvAQgCAAATIiIAEgA5A8SAAAAJAAkACQIJAjkDyQAIABNiIgARADzDwgAIgwiAoQBIAgiCOIPIgAAAFOIQABEAPMPCQDIAf8HCADDBRAE8gcSAAAAVIgAAMwA8g8YAIYI9QeUBAAAJAjkDyQAAABXiEAARADyDxkCUALeA1QCVAYABPIHEgAAAFmIAADIAOQPAgBUD3wFdAdkACQAJAjkByAAW4gEAEIA+Q8IAPoD3wLaB/4CAgDyBxIAAABdiAAAJADyDwgAeglaCf4H+gUJBCAA5A8gAGGIAABEAPIPCAn4Ba4D/AOsDfgBAAjkDyAAYogAAIwA4A8cALwHnAeYB7wHvAQAAOQPIABjiIAAiABICMgPKAgaBDwEyACIA0gEKAgACGWIAAAIAYoA6g+YAEgBAAD+DyAAQADAAIAAaIggATQJtAS0B3QEPgT0BDQBtAK0BCAIAABpiAgBiADuD5wAQAkcCOQEFAOEAnQEDAgAAGuICAGIAO4PnABIAQAIiARIBEQCMgIQAQAAbIgIAYgA7g+cAEgBAADQABAJEAj+BxAAAABwiBQBFAV8BVwH3AReBNwEXAFcA3wFFAUQBHeIAAAEAnQCVA5UCfYIVAlUAlQGdAkECQAAgYgAAhAC9AK0DrQJvgS0AbQCtAZ0BRAJAAiEiAQBhQD3D44AZAEADCICogF+AKEDIQQgBIuIkAKIArwKgg6ICcgIjgmYAqoGygrKCqgIjYgAAYwA7A9YAQAA8AcsCSgJ6AsICvgJAASSiAgBiADqD5gAAAj8CSQJJAkkCSQJ/AkACJaICAGIAOoP2AAAAPgPiASIBP8HiASIBPgPnIgAAYoA6g/YAAAESAJIAf4PSAFIAkgEAACriAgBiADKD7gBAAz4A8gISAl+BkgGyAkYCK2IhAKkAqQKlA6MCaYIvAnWAtYG1AXEBbQIsYgAAYgA6g/wACAA/A8CABAH/gCQAxYMAAC0iAgBiADsD5gAAACoALgDrAKoCpgKqAagAMGIAAFUC9QHXgRUAVQDEAz+AhAD0gQUCAAGwojWAtYC3gquDp4JxgSAAZ4CwAbABf4JAAjFiKACrAKQCrwOgAmoBKgBvAKoBqgEqAgAAMaICAGIAO4PnABIAQAELAUgBT4FIAXsDwAAz4gABEQFfA18D3wJ/gl8A3wFfAV8C0QLAAjUiBQA1A90APQHbAVkBWYFzAbUAKQPJAAAANWICAGIAO4PWACIAAABxA+yCIgIsgjED4gB2IiABKwCrAqsDoQJ3gSEAaYCrgasBKQIAADZiAABiADrD9gAgAIqAeoHvgSqBKoEvgcIANyICAEIAc4PuAAAAOgPqAKoAv4PqAKqCuoH3YiQAr4CmAqYDr4JgASoBKgBvgKoBqgEiAjhiAgBiADsD9gAAAB8CVQJVAn8D1QJfAkAAOSIAAGKAOoP2AAADPwDRAC2ApQPlAKUAgAA84gAApwEhQK2DrQJ9gS0AbQCtgaFBJwIAAD4iAgBigDqD9AAgAT8BNQC1A/8D9QB/AKABPmIgAJEAnwBfAf8BP4EfAF8AnwCfAXEBAAA/YgIAr4CnAq+BpwF/ASAAZwCwAbABb4JAAQCiQAAxAD1D2wAAASUBN8HlAQAAP8HIABAAAeJgABIAO4HeAAABT4F/gW8ArwCvAW8BAQEEIkIAYkAyg+4AAABvgeqBKoFqgaqCL4HAAASiSACFAL0AgQOZAl8CT4JfAI8BnwFJAkABCWJAAGIAMwP+AAADvwBdARcATwJ3A8cAQAAKokAAIgB7A/YACAI7AcACPwLVAhUCXwKAAgyiQABlADUB7AAAAT4A+gD7AP4B+gD6AMIAkSJQAXEBfwD7A/8CcYJ/APsBewF/AlECQAAX4kAAIgA7g/cAQAJTAVeAVAPTAFeBVQJEAByiQAFDAV8A34PfAt8CQAJfgP8BfwL4AtACX+JBAD0D5QE1AQ8BBQEFAR8BJQElAT0DwQAgYkAAIIIugiqC/4GqgSqBL4GqgWqBLoIgACGiUQBXAG8D1wA3AjsC/wH/Af8B/wLPAgACIeJAgBeB9YH1g/eB1YHFgz+A7YCtgr+BwIAi4kACAAI/AlUBVQDVAFUAVQHVAn8CQAIAASPiUgISAT8A0gBSAoACPwFVANUD1QJ/AkABJOJAAgMCPwL5AbkBuwC5ALkBuIK+gsCCAAElokIAYgAzg+4AAgJAAj8BVQDVA9UCfwJAASaiQAIOAgKCOwL6AbqAuwC6A7sCwoIOAgABKeJAAg8CPwL/Af8B/wDwAPsB+gL6AsoCAAEqokAAKQErALmD6wCoAj8BVQDVAFUD/wJAASziQAAMAHsB7gH6AeoB/wNVANUAVQH/AkABLqJAAAwCB4I3gvQB9oD2gPYD94LHggwCAAEvYkACD4I7gv+B+4H7gPAA/YH/Av8CzQI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AAAAAPwProsgACQI7A8ABAQCeAiCBQwCgAV4CAQIAAiviyAAJAjkBwgCQAJEAPwPRAAEAPwHAAgABrCLIAAiCOQPCAQAAMQHRAhECEQIRAj8CAAGsosgACII5AcAAogIiAT+A4gAiAD+D4gAgACziyAAJADoDwAEiAKoAKgA/g+oAKgEiAMAALaLEAASBvQBBAWADDoCIgGiCGII/gciACIAuIsgACIA7A8ABLAAjgCIAPgPiACIAIgAAAC5iyAAIgjkBwgCYAD4DwYAgAD+ByAIGAgIBrqLIAAiCOQPCAIgAJAHCAmGCIgIkAggBiAAvIsgACII5AcIBGAAGA6GBWAEBgUYB2AIAAC9iwAAJAjkBwgCAAz8AyQGxAEkAvwHAAgABL6LIAAiCOQHCAIgCqAIXgVCAkIGfgXgCCAIv4sgACIE7AcEAgAICAb4AUoISghICMgHCADAiyAAIgTkBwgCQAlIBEgD/gDIA3gEQAgAAMGLIAAiCOwHCAIACOQPBAgECPwPRAhECAQIxIsAACII7AcEBIACugCCAP4PggCyAIoAAADFiyAAJAjoDwgEAAD8DyQJJAkkCfwPAAgAAMaLIAAiBOwHCAIACHwGRAFEAEQARAF8DgAIyIsgACII7AcIAmACEAAOAPgPKAEoASgBKAHJiyAAIgjkDwgEAAD8DyQAJAHkDyICIgIAAMqLIAAiCOQHCAQAAlAISAkGBcgEUAIQAQAAzYsgACII5AcABgIA6gMqASoB6gkCCP4HAADPiyAAIgTsBwQCIACiD5oEhgSiBKIEngcAANGLIAAkCOgHAAIkAqQCrAKUD7QCrAIkAgAA1YsAACII4gcCBAgASATIBwgC/gAIBwoMCALXiyAAJAjoBwgCoACoAqgCvAioCOgHqACgANqLAAAiDOwDAA74AygAKALICX4EiAfqCAgG3YsAACQI6AcIAiAApA+kCPwIpAikCKIPIADeiwAAIgjsBwAAsg0uA8IE8AkCCv4LIgoCCuGLAAAiAOwPAAD4DxYA1AdUCFwK0AkQCAAE4osgACQI7AcABBAAyAOuAqgK6AsICPgHAADliyAAIgjsDwAEJAG0CKwEZwQkBhQFhAgAAOaLIAAiCOQHAAIIAEoBSgH4D0gBTgEIAQAA54sgACQI6AcAAhgACAEoAe4HqAiICJgEAADriwAAIgjkDwAA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gAT/BJgEmA8YAL+MAAQQBPwF9APsA/AB9AHsA+QD1AUMBAAAwIwAABQIzAvmCvQK7ALgAv4K8gryCx4IAAjDjBAACADcA8QL4AvqA+oD/gvqC+kDKgAAAMSMAAj8DVQFVAH8BUAA+A+sAqgCqAroBwAAx4wQCBII9Av0BuQG9AL2AuwG9Ab0CxQIAADKjAAI/A1UAVQF/AFIAOgJSAR+AogFbAgIBtOMIAAsCOwH/AbsAv4C7AL8AvwG/AcMCAAI24wAABwIzAXuBewF7AHgAfwF7gX8BRwIIADcjAAI/A1UAVQF/AUAAb4C6gmqBKoDvgiAB96MAAAcCMYP9g30DfYF9AX0DfYNxQ8cCAAA4IwACPwFVAVUAfwFIAC0B6QEpgSkBLQHJADijAAIPgj6B/4H+gf6A+AD4gfaB5oHJgggAOOMAAQ6CO4H7gf+B+8D7gP+B+4H7gc+CAIA5IwACPwFVAVUAfwDqAjsBBgH2ga8CbgJEATmjAAI/A1UAfwFAAjUDxQI0AeQBP4DEAwUBuqMIAAcCMwL7Ab6BvgC7gLqBuoG2gsKCAgA7YwABPwHVAFUA/wFAAGkB/4FpAW8BaYHIAD0jAAEeAJYAfwPWAE4AMAL7ArkAvQG7AcACPqMAAD8DVQB/AIICGwF+A9oAfgPbgPoBUAI/IwACPwNVAFUA/wGwA/sAv4C7Av+CuwHIAL9jAAArAh8BPwH/AP+A/wD/AP8B7QEpAQAAAiNAAj8BVQB/AUAAPwP5wrkCvwK5ArnD3wACo0AACgI/g9eDVwFXAV8BV4FXgXsDxwICAgPjQAMggO2CjoHugm7A7oFOgC6B7oPCgQAAB2NAAAACPwJBAQEBAQC9AEEBAQE/AkACAAAHo0ACAAI8AsQCBAEHgLUARQEFAT0BQQIAAAfjSAIEAj4CRQIFgQUAtQBHAQQBPAJAAgAACGNAAAUCNQLVAhUBlwBVARUBFQI1AsUCAAAIo0ACP4JAgT6AwIA/g4AAAgDiAhoCP8HCAAjjRAAFAjcC1wIXARcA14AXARcBNwFFAgAACSNAAAeCMAFQAReAkABZgRaBFoI1gsSACAAJY0ACP4IAgb6Af4MAABwCI4EiAN4BAgIAAAmjQAEfwf5AAEC/wIACP8HIAToACYDIQQAACeNAAAICMQLXghBBkQBTwRUBFQI0gsKCAAAKI0AAPAHDADsCSwELAK8ASoEKgTqBQgIAAApjQAAfA/0AAQC/AAADvwBNAzUAhQD8gQECCqNCAAICNQLVAhSBFoDUgB0BFQE1AUECAgAK40IACgI7AtqCFoESANoAGoEXATEBQgICAAsjQAI/g3yAwIC/gAADCQCIgYqCeIIIQgACC2NAAj8DeQDBAD8DhAAzAEKAcgJCAj4BwAALo0AAPwJBAT0AwQA/A4QAAgEDgQIBAgEOAQvjQAACAj8C2oIagZ+AWoEagRqCP4LCAgAADCNAAAoCLgJuAS4ArgIuAsICP4BCAYOCAgEMY0ACPwIBAb0AfwCAAhQBP4EUAdUCVAJAAQ0jQAI/A30AwQA/AYAAIAP/gSIBIgEiA8AADWNAAAgCPwLdAh0BHQDfgB0BHQE/AUgCAAAN40QAAgI3AtCCEgESANOAFgEagjiCxQAAAA4jQAAAAjcC1IIWwRAA1IATgRiBOIFHggAADmNAAhACN4LdghfBFYDVgBfBFYE1gUWCAAAOo0AABQI1AtOCGQGXAFABFwEVAjUCxwAAAA8jQAE/AL0AQQE/AAABugBCAh+BIgH6ggIBj6NAgg6COoFagR+BGoDagB+AmoE6gU6CAIAP40AAPwN9AMEAPwFwAD4D64CqAKoCugPCABBjQgABAjfBUAEagNqAGoCfgJqBOkFKggAAEKNAAj8BuQBBAT8BAAAyA/WBKQE1ARMD0AAQ40AAPwN5AP8DAAM+AMICEoI6g9ICEgIAABEjRAIEgjUBUAEaAJmA1YATAJUBNQFDAgAAEqNAAD8DeQDBAD8DgAAUANoCOYPaABIBxAES40AAPwN5AP8AAAI1A8UCNQHEAD+AxAMFgZMjQAA/A/0AQQE/AWAANQPfgVUBVgF1A8QAE6NAAj+BfIDAgD+BQAApAlUB/4BFAU0CQAAT40AABwIhgu0CLQEtgK0ALQEtgSFBRwIAABQjQAI/AkEBPQDBAD8DgAAvgDqC6oGqgm+B1SNAAj8B+QBBAT8BQAAqA+kBKYEtASkByAAVo0ACPQElAL+D5QB9AoACPgH1gMcCPQLAAhYjSAELgSeBV4EXgJeA0gAbAJeBJwFJAQkAFqNAAj8DeQD/AAACFoF/A9YAfgPXgX4CUAAW40AAKwIvAj8BbwEvgK8ALwE/AW0BCQJAABejSAALgicC04IfARAA24AXAROBJwFLAgoAGCNAAB+BAID+gACAn4AmAd/BXwFfwX8BwAAYY0AAPwN9AP8DAAA+AcOAOwPzAvIC9APAABijQAM4gO+Cv4H3gw/A/4M3gc+Af4PBgQAAGSNIAKkAaQIJAbkAT4IJAjkDyQApAAgAwACZo2ACSQE5AM+COQHJACACTQEygKIA3gECAhrjYAJJATkAz4I5AekAIAH5AE+COQHJACAA3CNIAgoBKgDKAQoBPwPKAkoCSgJKAkgCAAAdI0QBtQBFAL+A1QEVARQBAAE/gUIBBAEIAR1jRAG1AEUAf4DVARUBAAFzAQwBEwEggUABHaNIAykAyQE/gekCKQIAAgkCPwLJAgkCAAAd40QCNQHFAL+B5QIlAgACOQJJAokCjwKgAmBjRAG1AEUAf4DVARQBAQFUgUiBaQEiAQIBIWNAAjYBxgE/AeYCBAI1AtMCmQKZArcCwAIio0gDKgD/AeoCAAI+AmICAgKfgnICioKAAiLjSAGqAEoAv4DiAQgBBgFVgVUBVwF9AUABJWNIAaoASgC/AOoBQAFXATcBNwF3ATcBAAEmY0gDKgDKAL8B6gIAAj0CzAIvAiQCvQJAAifjQAIpAckAv8HpAgECPQLkAheCZAI9gsACKONFAAUBJ4D9AMQBP4EqgT+BQAE5AUcBQAEqI0QDNQDFAL+B5QIpAjvC14JSgluCN4LAACzjQAAAAg8BKQDJAQkCOQPJAkkCTwJAAgAALSNAAjeBxIE8geeAAAO/AEAAAQA/AAABwAIvo0ACN4HEgTyB54AAAj4DwAI/g9ACEAIAADDjQAI3gfyB5IEngQAACQMIgP+ACIDIgQgCMuNAAieDxII8geeDAAICAf/AEgLSgbKCUgAzI0ABN4HEgTyA14CAAhOBEgD/gBIA0gESAjRjQAE3gcSBPIHngQAAPoHtAj0CgQK/AkABNuNAASeDxIE8geeAAAM+APICX8GSAXYCAgI3Y0ABNwHFAT0A5wCAAD8DxQFFAUUBfQFAATfjQAI3gcSBPIHngAACPwPVAjUAVQGfAUACeGNAASeB/IHkgQOAuAM+AMOCPgHCADoAQAA6I0ABJ4H8gfyB44EIAC4A6gKrAq4CqgGqADqjQAAHgfyB5IEPgz4BxYA1AdUCFwK0AkQBO+NAAjeBxIE8geeBJAAiA/WCKQIvAjED4AA840ACN4H8geeBAAA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dAV0BfwPIASTjwAAfAJGAvQPIAD4D7QC8g+UARgI8AcAAJWPRAB0Ak4C5A9AAhAC9A60Cb4JtAJ0BRAJlo8AAHwBRgH0B0ABFAC0B7QF9gW0BZQHgACZjwAAdAJOAuQPFADuB7QK5A90BIoDeAQACJuPIAAkASwBPAEkAecPJAE0ASQBJAEgAAAAnI8AAEIFXgVWBdYFVgV3D1YF1gVeBQIFAACejwQAkg+SBP4EkgcQAEQBdAHGD3QBRAFAAJ+PAAT8A6QPpAS8BwAAWAFIAc4PaAFIAUAAo48AAEQJVAnHB3QBBAjwBJQC/g+UAvQEAAimjxAIzAfoAUAIEAf+AOAPCABaAcYPaAEAAKiPRABVCcYHdAEACHAG/gEAAFQBxw90AUAAqY9EAFUJxgd0AUAADgjkBwAAVAHHD3QBQACrjwgAWgnsB0ABHATyBIgEAARVAccPdAEAAK2PBADMD1IBegfWANYPAABUAccPdAFEAQAAr48IAFoJ7AdIAUgPawVoBwwAXQHvD0wBAACwjwAAAAz8A0QA1A9UCFQE1AFUAlQFVAlACLGPAACAAn4CIgbqBqoCKgpqCqoG6gJiAwACso8ADPwDbAnsCf4H7AnsBf4H7AXsBfwLQAm5jwAIIgTsAwgEAAgIC8gIPggICggK+AkABLqPQghGBMgHAAQECMQLPAgECgQKBAr8CQAIu49ICFIE1gMEBBAIEAgQCP8LEAgQCBAIAAi8j0IIQgTMBwAIAAqCCWIIPgjACAAJAAoAAL2PAAgkBOgDAAQECAQKBAr0CxQIDAgECAAAvo8gCCIE7AMABAgICAvICD4ISAiICAgLAAjBjyAIJgToAwAEJAgkCCQI/AsiCCIIIggABMKPAAgkBOgDCAQgCCQKJAr8CSQIJAgkCAAAxI8gCCQE6AMABDAECAmsCmgKKAooCggJAADFjyQIJAToBwAEJAgkCPQLJAgECPwJAAqACcePIAgiBOwDAAQICCgIyAgICggK/gkICAgIyI8kCCQE6AcACAQLxAg8CBQIFAoUCvQJBATOjwAIRgzIAwAE/AkECQAI/AsECAQJ/AgAANCPIAgkBOgHAAgQCtQJNAkUCVQJlAkUCgAI0Y9CCEIExAcACAAL/ggSCBII8gsSCBIIAADUjwAIQgTMBwAIAAv+CDIK0goSCdIKMgoCCtiPAAgiBOwDCASACEQIJAj8CwQIJAjECIAI2Y8ACCQE6AcACCgKKAnKCEwIuAgICQgKAADbjyAIIgTsAwAESAhIC/4ISAhICP4LSAhICNyPIAgkBOgHAAgQChQJ9AgUCPQLFAqQCQAA3Y8ABCIE7AMABFQEVARUBP4FVARUBMQFAADejwAIIgTsBwAEFAksCSYJ9AskCSQJBAkAAN+PIAgkBOgDAAQACfwIJAhkCOQIJAk8CgAI5o8ACE4EwAcEBfwEBgj8CwAI/AsECvwLAAjqjwAIJAToBwAI+AtICkgK/gtICkgK+AsAAOuPRAhEBMgHAAQACPgLSApOCkgKSAr4CwAI8I9CCEIEzAcABIgJaAgICP4LCAhqCIoJAAj0j5AI1AS0AwAE/AkECvQKlAr0CgQK/AsAAPePQghGBMgHAAgkC6gIYAj+C2AIqAgkCwAK+Y8ACCQE6AMIBGAICAv6CAwK+AsICOgIAAD9j0IIQgTEAwAE/AlUClYKVQpUClwKwAsACACQQAhCBMwHBAgACv4LKgpqCKoJXgpACgAAAZBCCEIEzAcABEgITgpICfgISglKCkgKAAgCkCAIJgToBwAEFAjUC1QKfApSClIK0gsQCAOQAAhECMgHAAScCEAK/gkACP4JQAqcCoAKBpAACE4MwAMIBOoIjgqICvgJiAiOCOoICAgJkAAIJAjoBwAIIAqsCWgIPgjoCygKKAogCQqQAAgiBOwHAAQiCPoLRggwCv4LAAg4CMAADZAAAJII9AaUBQAI9gsQCF4JEAmUCvILAAgPkAAIJAjoBwAELAgsC9wIXAicCqoKqgkgCBCQAAgiBOwDAAQSBaoIrgpSCuIJUgiKCAAEEpAgBCIE7AMABHQFVwXUBPwFVgRVBdwEAAQUkAAITgTABxAESAlUCFQK8glUCEgJUAkQCBeQAAgkDMgDEAQECHQK1ApUCtQL9AoECgAIGZAAAFQEfALYAwAE+AV4BXwFeAX4BQgEAAQakCAIIgTkAwAE+gmuCK4I+guuCK4K+gkAABuQAAgkBOgHQAguC/QIAAokCvwLJAokCgAAHZAACCYI6AcACEgK/gkICPwLEgjyCxIIAAAekAAA0gi8BpgFAAi8CrQK9Au0CrwKAAoAAB+QQghCBMwHAAh0ClQJ1Aj+C9QIVAl0CgQKIJAACCQI6AcABCAIrAuoCrwKqAqoCyAIAAAikAAIJgTgBwQIlAqSCq8K6guuCqoKCAoQCCOQAggmBOQDAAR8CVwJXAn+C1wJXAl8CQQJLpAACE4IwAcQCJQKVApUCP4LVAl8ChAKAAgxkAAIQgzMAwAE/gkCCOoJegnqCQIK/gkACDKQAAhGCMgHAAQQCP4LqAr8C6oKqAoICgAIOJBCCEQExAcQCHgKVgnWCHQI3AtQCnAKAAE7kCAIJAToAwAEnAhUCnwKVAlcCdQIHAgAADyQJAgoBOgHgAt8BWwN7A9sDWwN/A8ACAAAPpAACCIM4gMIBOgF/Aj8CwsI6ggEDOgPCABCkAAIRgTIAwAEKAluCdgIqArICa4IqAgICUWQQAhEBNgDAAX8CBQI1AnUCdQL9AncCQAIR5AACCQE7AcACP4Lagj+CX4Jagt+DMAPAABKkAAIRgzAAwQF/AgXCuQJDAhGCvQLVAhECEuQAAgiDOQDAAR6CXoJegn6C3oJegl6CQABTZAACCIE7AMABfwI1Au0CPYLtAj0C7wI4AtOkAAIQgjMBwAI4As+COIJegnqCT4I4AsAAE+QAAQiAuwDgALcBTwFvAW8BTwFPAf8BwACU5AgCCQE6AcABAgI+gu+CrgKvgr6CwgIAABUkAAIRgTIAwAE1An0CdQJ3gvUCfQJ1AkQCFWQAAhECMgHAAj8CtwL3AreCtwL/AqICgAIV5AACCIE7AMABO4IagpqCX8IagrqCi4IIARZkJAI9gaQBQAIuA6kDrwO9g+sDqwOpA6ACFyQAADRDLYCEAVCBPoJBgpcCPYLQgjBCgAAXpCQCPMEFAOABH4IAgvyCD4Kfgh1CXUKMAFgkAIIQgjCBwgEfAlcCdwI3gtcCfwJiAoACGOQAghCDMQDEAT8CfwK/Ar+CvwK/AqQCwAIZZAACCQM6AMABEwJfApkCuwLZApiCmoLQABokIAI1ggwBwQG9Al+DVQNRAsQCI4LeAoICmmQAAhGDMgDAAT0CTQI/Al2CfwJNAr0CQAIbZAACBEE9gMABP4Jvgq/Cr4Kvwr+Cx4IAARukAAEJgLoA4ACfAQUBXQEVgZUBXQEFAUAAHKQkAjUBLQHAAb8CQwItAqMCtwLjAq8CgAKdZAACCYI6AcABHwJbgtsCWwJfA3+D3wJBAF3kIAI1AS0AwAF/AjsC/wM7A78D+wMfAkACXiQAQgmBOQDgASuCu4K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SgJABAAAyJEAAJYBUgD+B1UAAAb/ASEA4QAhAz8MAATKkQAAKgOiAP4PowCqAKACrgKSD6oCpgIiAsuRBACsAfwPogCoAD4C+gK+AroHvgL6Ai4CzJEAAAAEvgSqBKoEqgT+B6oEqgS+BAAEAADNkQAAEAT0BfQF9AX8B/QF9AXyBfIFEAQAAM6RAAB8CVQJ/AdUBXwBAAgkCPQPLADkAAAAz5EAACAE/Af8B/wH/Af8B/wH/Af8ByAEIADRkRAAsAiQCZgLlgjxD5IIlAiYCpAIMAgAAN2RUAhYC1QI8gdUBEQFAAAgAP4PIAAgAAAA45FQCFgLVAjyB1QERAUQAM4ICAkIDPgDAADnkUAIWAtUCPIHVAYADP4DAAD8BwAA/g8AABWSUAhYCfYHVARUAQAIRAj8D0QIxA98CEAAHpJQCFgLVAjyB1QEWAUGASUJJAkEBfwDAAA0klAIWAtUCPIHVAUQBEgA1w9SAEwE0AcQAESSUAlcCPIHVAREARAETgRIA/4ASANIBEgIcZJQCFwJ8gdUBAAN+AMIAAgH7gQIBIgHAAh0kkAIXglAC2AJXgnQD1YJZA00CVQJRAgAAICSUAhYC1QI8gdUBwAA/g9KCMoBSgZ+CQAIg5JQCFwJ8gdSBAQNZAQ0AywAJgC0DzQIRAaFklAIXAnyB1IEhAT+DwIA6gMqAcII/gcAAJiSWARUBfIHUgREBRACGAGUD+YEnASEDwAArZJQCFwF8gdUBFQBAAioBP4FqAaqCaoIAAazklAIXAX2B0AFEAD8BJIGkAGSD/QIGAgQBLeSQAhQCVwE8gdEBggN9gcQAF4BEAn2BwAA0pIAAFAIXAXyB1QFAABIBa8Fkg+uBaIFQATqklALWAT2B0gEWAUIAOgPqAL+D6gC6g8AAO2SUAlYBVQE8gdUBAABegzMA0gAzA96CAAG/JIAAFALXAjyB1QH/AsMBKQD5AMMC/wHAAAEk1AIWAn2B1QERAUABNgCVgjUD3QATAVABSKTUAhYBfYHVARUAQAIKAmeBRgHWgcqC6gIJpMoBC4F+QMqBioHgAe+AOsPqgCqBL4DAAArk1AIWAlUBPIHRAcABL4E6gOqBqoJvgcAAC+TWAhUCfIHVAQEBSQA/gdkBWQFfgXkBwAAMpNQCFgJ9gdUBAAFogQqAOoPqgEqAr4CoAQ2k0gLXAjyB1QERAEUAFQP1Ah+CNQDVAVACUqTWAhUCfIHVAQEBfQEtAKUAf4PtAH0AgQES5NQCVgI9gdUBQQA4A8+ALIDqgI+CeAHAAB1k0gIXAnyB8QHMAwuA+AEqgb/C6oKvgoICH6TaAhsCWoE+QdqBwIM/giuCv4Prgr9CgAIjJNIBM4E+QdKBewFrQL+D6wA/A+vAvwEAACWk1AIWAhUCfIHVAQACfQLsAq+ArAC9gsACK6TQAhQC1wI8gfUBQAA/AvsCu4C7Ar8CwAK4ZNQCFgIVgnxB1IECg3qCG4HawFuD+oJCAQYlFAIXAXyB1QFAADyC3oLcwvzD3ILfgvyCzWUMAhaCvwHHAd0ALQHvgdUDP4FEAfWCAAGUZRQCFwJ8gcEB34Aqg/uCboPAAlOD0gJSA9wlAgIXAnyB0QFCADoD8QHkgL0D4QCaA8AAH2UUAhcBfIHVA0ACBgI3gXcA9wL3gusCygAiJSYAIYI9Q+UBIQEIAAgACAA/g8gACAAIACJlAAAmACGCPUPlASUBAAABAgECPwHBAAEAJOUAACYAIYI9A+UBKACHABKAIgJCAj4BwAAmZSYAIYA9Q+UBJQEAADyAIIA/giSCJIHAgCdlJgAhgj1D5QEAAToAQgBCAH+BwgJCAnoDZ6UmACGCPUPlASEDIAIOAgABP4DgAEIADAAn5SYAIYI9Q+UBAQE8AGQAJAA/g+QAJAA8AGglLgAhgjlD6QEBADwDxACkAF+AJAJ8A8AAKKUmACGAPUPlAQAAP4PAgIyAfoBAgj+BwAApZS4AIYI5Q+kBKQAAAz8AyQBJAkkCfwPAACmlAAAmACGCPQPlASEDDAIDgboAQgDOAQICKeUmACECPYHlASEAhAATgJICUgJCAz4AwAAqZSYAIYA9Q+UBAQEEAHuAQgJyAsICPgHAACulJgAhgj0D5QEhAwACEIO/glCCEIO/gkACLGUmACGCPUHlAQAAsgISAT+BEgHKgmqCQAEs5SAAKwI6geoBIACEAD8D5AEkASQBPwPEAC7lJgAhgT1B5QElAIEAIAPgAT+BJAEkA8AAL6UmACGCPUPlAQABP4BkgCSAP4PkgCSAP4BwZSYAIYI9Q+UBBQEwADODMgC/gFIAkgEQAjDlJgAhgj1D5QEhAQQAEgBVgJEDcgAEAAAAMWUmACGCPUHlASUAgAAvg+CBIIE/gTADwAA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AAT+AtAI3gfQAPYCAASblgAA/w8ZAO8AbAa3AK4EoAenALgCrgIiAJyWAAD+DwIAOgHGABAC9AL8AvYP/AL0AhACoJYAAP4PMgDOCQQEbAFkDWwJZAtyCeoBAAyjlgAA/g8yAM4AAAnuBZgDvwCYA+oPqAIAAKeWAAD+DzIAzAhABLYHgASqCfgMyAvOCCgJqJYAAP4PMgDMCOIHFATUC+wI7gl8DewPBAiqlgAA/g86AcYIUAS4AvQAEwj0BrgE6AwIALGWAAD+DwIB/gDADfYB8gf6C/IN+QH1DaAItpYQBFQFVAVUAlQK/gdUAVQCVAO8BJAEAAC7lhAIEAl4CXwJeAd4BXwFeAV4B3gJSAgACL6WAAAUBqQB5AAcAyAA/g+oBPoHqASoBAAAwJYAAFAAWADED+AK3grwCvAPxArECtgKEADBlgAG/gFCAPoHAgAiAPoHUgX6B1IFUgUAAMSWCAzoAx4IyAcIBCAD/AeqBKgE/AeqBKgExZYkBrwBZAj8ByQA8A+uBKgE/geqBKgEAADGlggICAV8BV4DXAPcD34BXQNcBVwFRAkAAceWAAAEDvwBrADsD+wK7ArsD+wK7Ar8CgQIzJYAAPAPAAT+BwAE/gcwAv4PqAT6B6gECATPlhAAuASmBLQE7A8gAPgPrgSoBPoHqAQIBNGWJAC0BI4ChA+8AkAEMAD+B0gF/AdKBUgF1ZaAD3wANAe0AjQJ/AcwAPwPqgT0B6gECATWlgAA7gSqBPoDrgLgBjAA/g+oBPoHqASoBNmWAAAICL8EvAS+BbwGiAK+ArwFvgW8BCQE3JYgAKQGlADGD7QCAAD+D6gEqgT6B6gEqATelgQIfAl8BaoDUg04AfwPqgSoBP4HqAQIBOKWgA/0ANQD1gLECPQHIAD+DygF/AcqBQAE45YAAPQJ1gX0A9YF9AUgAP4PqAT8B6oEqATolgQA9A8UAFQBFAD8DxQAVAFUChQI9A8EAOqWGADKCsoKygqKCr4KigrKCsoKyg8YAAAA75YACJgIygjqCcoGngTKBIoG2gnKCJgIAAjwlgAKGAmaBboFCgM+ARoJOgmKBxgBAAIAAPKWAAEMBWUFZQdFBV8FRQVlB2UHBQ0cCQAA85YcDMYDdgh2CX4HRgF2CXYJdglGCVwHAAD2loAAmACaAboFSgXeBcoFWg26C4oBmACAAPeWGADKD8oKygqKCr4PigrKCsoKyg8YAAAA+ZaAAJgA+gf6CuoK/grKCvoLegrKCRgEAAD7lgAAGADaB/oCygLeB9oK+grKCxgIAAYAAP6WAAFYC1wLXAvMBtwC3AJ8C0wLXAcAAAAAAJcAAFgAWg96AUoP3gFaD3oBSglYB0AAAAAElwAAHgAOCK4HhgHeBYYG1gLeCoYHHgAAAAaXAAhMCeYFdgsmCD4NRg32D3YNZg0MDQAAB5cYDNoDegn6B8oF3gXKB/oF+gXKB1gLAAkJlwAADAFmBeYG5gbGB94Gxg7mDuYHTAUAAAqXAAg4CYoLqgmKD74Jig+qD6oJCgs4CwAIDZcAAQwBpg+2C4YL3g+GC7YLpguMCAAAAAAOlxgCWgtKC2oLyg9uD0oPWgf6B0oLWgsYCBOXAAAOAA4I1guuCq4GBgKuBr4K5gsOCAAEFpcAAJgEigK6D4oCPgCKBroBug+KApgEAAQclwAAmAS6AroPugI+AL4H+gX6BfoFyAcAAB6XGADKD/oF+gXKBd4MCgj6C/oFygXYCwAIJ5cAAAAMTAPmD/YBRgMeCsYGdgPmC0wHAAEylxgIyg16CXoPygueAooOegv6CkoPWAIAADiXAABMB+YH9g/GB14DBgz2A/YC5grMBwAAOZcABuwBdQdtBW0FBQcvAuUCpQ+tAu0CoABClwAO7AFlBP0E/QZ1BOcHZQb9BvUG9QQgAEiXAAgMCeYL/gtGCa4PpgnmDU4LtgjkCAAAUpcQABQA/A+8ArwCvgK8ArwKvAr8BxQAEABWlwgC6AIOAugBAAD8D7wCvgK8CrwK/A8UAFmXEADcD9wC3grcDxAAWAlWCfQHXAHwAUAAXJcQCNwH3ALeCtwHAACIAqQK6geiAuoDgABelwABKAEoASgB/g8AAAAA/g8oASgBKAEAAWCXAAQIB3wHXgdcD1wAXgBcD1wHfAcIBwAEYZcADvwBBAQ0B3QHVA8GADQPdAc0B1QHAABilwAA8g8SBPIHXgVSBfIHEgQSBPIPAgAAAGmXAAAEAuQCvgK0AvQPtAK0Ar4C5AIEAgAAdJcEAu4C/A+uAuQCAAIwAP4PAAD+BxAICAZ2lwQA7gKsAvwPrgJAAP4HQgh+CEII/ggABouXAADkAq4C/A/uAgQKIAgkCb8PJAkkCQAAjZcEAO4CrAP+DuQCAABICcYJdAZEBegEQAiRlwQC7gL8D64CZAjgBwQIkAt+CNAIEAsAAJiXBAD+ArQC9A++AkAI9AcQAF4BEAn0BwAAoJcEAv4C9A+0Au4C/AaKA+gP6AGICvgHAACtlwQC7gL8D24A/g98CawH/ASsCPwIBAgAANOX/AKsAq4PrAb8BgAE7AeuBawPrAXsBQgE5pcAAJIAkgCSAJIA/w+SAJIAkgSSBIADAADnl6gAqAD8D6gAqAIAAXQMhAN8CAQI/AcAAOmXAAD0AtQC3g/UAvQCAACoAP4PqACoBIgD7ZcAAFAFUAVQBf4HAAQABP4HqASoBKgEAADzlxAAFADUB1QFVAVWBVQFVAVcBdQHFAAQAPWXIADoB2YFdAXkByAAEAEuBagICAj4BwAA9pcQANwHVgVcBdQHBACwB44EogSiBJ4HAAD7lxAA3AdVBVoF1AcEAPgPVANUA1QD/A8ACP+XlAC+ANUH4Af+B+4HzgfAB94HxgeaAAAAAZgACAQI/AusBqwGrAKsAqwGrAb8CwQIAAACmAQIBAj8DwQAAAj8C6wKrAKsBqwG/AsAAAWYBAEEAfwBBAEECPwHrAasAqwGrAb8CwAIBpgACPwHAAD4AwAA/g8AAPwHrAasAqwK/AsImEgIyAQkBBADBAj8C6wKrAKsAqwK/AsACBCYJAgkCPQPPADkCAAI/AusAqwCrAr8CwAAEZgAABQH9AAUAvQDAAj8B6wGrAKsAvwLAAgTmOgAiAD8D4gE6AIACPQHtAa8ArQK9AsAABeYAA74ASgMvAKoA1gI/AusCqwCrAb8BwAIGJgAAFgA1AdSAMQJDAT8B6wCrAKsBvwPAAAtmAAAfAhMBUwEfAcADPwJrAqsAqwG/AcACDuYEADeBRAEfwIUAZAA/g1WA1YDVgH+BQAEPJgAAHgGWAH8D1gBOAr8CawGrAKsBvwHAAhGmAAEvASsAvwPrAKcCPgJrAqsAqwG/AcACEyYQAxcA1wE3AdcCQAM/A1cCVwJXAn8DQAMTZggAawPtAVWBaQHDAD8B6wGrAKsCvwLAABPmAAM7AM8CK4JLAUkAvwLrAqsAqwG/AcACFSYAAzkAywIpgosBSQA/AusCqwCrAr8CwAIWJgAD/wAfAasAKwP/AEACPwHrAasAvwLAAhbmAQK/AvcCt4C/AsAAPwHrAasAqwG/AsAAF6YAACsBJgC3gGcAogI/AusBqwCrAL8BwAIZ5gADvoBKg+qB9oHgAcCCPoLrgaqAvoHAgxvmAAB/A3aARoJ+gO8AwAJ/AesBqwC/AsACHWYAAAECPQLFAgUBBQC3AEUBBQI9AsECAAAdpgAAAQIBAj8BwQAAAj6CQoE7gMKCPoJAAB3mAAAAAD8AxACEAEACPQFFATcAxQE9AkECHmYBAEEAfwBhAAACPoFCgQKA+4ACgIKBPoFepgADPwDAAD4AwAA/g8AAPwIDAbsAQwC/Ax7mAAESAQmApABAgj6BAoC7gEKAAoC+gQCCH2YAAASBvIBEgDyBwAC+ggKBu4BCgD6DgAAfpj8DwIA+gcKBPoCAAj6BAoG7gEKAPoOAAB/mAAA9ACEAP8PhARgAvoICgbuAQoA+g4ACIGYMAwMAuIJIAjvBxAA+gkKBO4DCgj6CQAAgpgwBAwD4gIAAt4HAAD6DAoC7gEKAPoNAASEmCIAKgjqBzYA4gAACPoECgbuAQoA+g4AAIWYAAjwB5AAngD0AQAI/AkMBOwDDAj8CQAIhpgQAFABTAJqDdAAAAj0BBQG3AEUAPQOAAiHmAAO/AEkDD4D5AYMAPAEFAbcARQA9A4ACIiYAACiCJIIige2BAAM+gkKBO4DCgj6CwAAiphIBFgESAP+AHgDSAjgBBQC3AEUAvQEAACRmCAAuAsgCPwFKAMgCPQJFATcAxQE9AkAAJOYAAAsCKwHvACqBwAE8ggSBt4BEgTyCQAAlpgABM8C1AHUD7IBAAryCBoG1gESBPIFAAiXmAAE/ATUAvwP1AH8AOAJFATcAxQI9AkAAJiYQAxcA1wE3AdcCQAM9AwUC9wIFAr0DAQMnJgACPIHGgGzBKoCEgj6BAoC7gEKAPoOAACdmKwAFAZeBXQFlA4cAPQJFAbcARQA9A0ABKCYBAr8C+wK7gL8CwAA9AkUBNwDFAj0CwAApJgACPwL/Av+C8wLPAPwCAoE7gMKCPoJAAComAAAAA78AQQE7AUsBfwHLAXEDPwHAAgABLGYAA7+AUIE+gNCAv4AAAPYBFYJUAncDQAAxJgEAPQN/AH8B6QP/gdmBPYD+gP6BwQIAATGmEAGygFqAGcG6wFiDP8DYQT9A2EH/wEABs6YAAAADv4BAgQaAqIB4gAaBwIA/gcACAAG0pgoBMoEDgLsAwAK/AcEAvQBBAL8BwAMAADYmHQN1AH8CdQH/APUASQN/AMUBuQB/AcADNuYUAhSBvoBQgBCAPoPQgBCAM4DFAUqCUgF3pgAAAQABAAEAAQABAAEAPwAIAdQCIgIiAbfmAAAEAAQCPgPtAiyCbQCtAb4CZAIEAgAAO+YCATkB9IE0gT0BgAO/gFiDKIFIgPiBAAI8pgIBPQHsgSyBPQGIAAcDIoD+AAIAzgECAj8mBAE/AeyBLIE9AYAAOwDLAHsCQQI/AcAAP2YCAAIBPwHugS6AvQGAAD4A5YE9AQEBPwE/pgQBPwHsgS6BPIGNAToASYA/A8kAOQDAAAFmQQA8g9aCVoF8gkAAIoM+gOIAP8PiQAAAAqZgACUAFwI/g/cCdwJ3AfcBf4NXAiUCAAAEJkQAJAAqAjuD9wLgAO2B9YHlgWuCKIAAAATmQQI8gdxBnUDIQSJBP8DWAAfAvgD2wYQABiZCAjsD1oJVgX0DQQAlAKUCPMHlACEAogEKJkQBPgHtASyBOwGHAD0D5QFlgWUBfwHAABSmQAA8A++BLIE9A5AAGoNegNvASoP+g0oBWWZMAAMCOoPCAQ4AAAO/AEEAAQA/A8ACAAGbZkwAAwIygcYAAAO/AE0DNQCFAPyBBIIAABumXAADAjqDwgEOAIACDAEDgPoAAgDKAQYCHCZIAAUAMoPGAIAAOgDJwAkAPwPJAAkAuQBcZlgABQAyg8YBEAA8AcsCSgJ6AsICvgJAARymTAADAjKBxgCCADiAyoBKgHqCQII/gcAAHWZcAAMCOoPCAQwAAQE/AeUBJQElAL8DwQCdpkgABQIygcYAggIoASuA7gApA/UCJQIAAR6mTAACgjlBwQCCApgCBQEhQOGAwQEdAhABHyZIAAUCMoPCAS4AoEI+geIAIgA/A+LAIAAf5kgABAAzg8YBIAClAj8DxAE/gKQBVYIAAaAmSAAHADKDwgEGACQBpgAlAjyD5QAmAKQBIGZIAAUCMoHGAIACFQJxAVsAkQDwgRaCEAAhZkgABQEygcIAjgA0A9IBQYFRARcBcQPAACGmSAAFATKBxACBAD8B/QHVQVWBWQFDAcAAIuZMAAMCMoHGAKQALgCbgQ8BWwJrAq4AIAAjZkgABQEygcYAwAIdAV2BXQD9AF2A3QFAAiPmTAAjg8oBBgEQAA+D7AK5A+cCoQKvA8AAJKZEAAcAOoHCAFgBN4F/gbeAv4G3gX+BAAAlpkAAAQA9A9XBVQFXAVUBVQFVwX0DwQAAACZmZAAVABUD7QKlAq8CpQKsgrSCtIPUACQAKiZAAC8ArwC/g78D/QP+A72DvIP/g7YAgACrJkACAAM/AFUAVQFVAH8DVQBVAtUCQAHAACzmQAG/gCqB/4CqgoAB/wHEAj+CRAI+AgABsGZAAb+AKoC/gmqC6oHAADWDAgDDgXRBBAIxZkABv4AqgP+C6oOgA3+AyIA4gAiAz4MAADGmQAG/gCqBv4CqgsAB/4PAgSiBXIEigUABdCZAA7+AKoG/g6qCaoHAACKCPoPjAiICAAI0pkABv4Aqgf+AoIKEAfMASoB6AkICPgHAADVmQAAFAjMBeYB5AXsAeAD/gHyA/IFHgMAANuZAAN/ANUDfwNVBcEDHAwkA/8CJAQ8BAAI3ZkABv4Aqgf+A6oPAAAYAPgHjgiICFgIQAb/mQAG/gCqBP4Bqg8AADwHigS4Bq4JIAgAAA6aAAb+AKoD/guKByAApAe0Aq4LNAjUByAAEpoABv4Aqgf+A4oPQACiCWYJ+g9aCeYNIAgTmgAG/gCqA/4GqgoKB+gIJgXyAyQH6AkICBmaAAb+A6oB/gmAD/wH7APsB+oDagX6BwAAMJoADP4Dkgj+B0QA9gXcC9YL3Af2C1QGQAA3mgAO/gCqAv4LqgcAAPQJagnSD2oP5g8gCEWaAAb+BqoB/gmCBwAA/AdUCuwLnAnECwAAVZoABn4H/gKqCQIHqA/6A94F2gf5AKkPAABXmgAG/geqAf4NggNwCLgG9gBUDLgC0AwAAFqaEAg6DP4D+gP6C9oDyAvsA9YLrAssBiQAX5oADv4Aqgf+DgAHfga6AP4PbAAUAywEAABsmgAAAAIEAnQCRAJEAkQCRAp8CEAHwAAAAG6aAAJ6AkIJQgj+BwAAEAyQA34AkAEQBhAIb5oAAnoCQglyCM4HAAD+DwAA/gcAAP4PAABwmgACegJCCkII/gcAAPwHEAj+CQgI+AgABnGaAAB6AkIKQgn+B/gPBAgUC+QIlAkECgAAc5oAAnQCRAlECPwHAABUDIgCiANUBBIIAAB0mgAAegJCCkII/gcAAPgPSABKAEgA+AAAAHaaAAJ0AkQIRAz8AzAISAVIAv4FSAR4CAAAeZoAAnoKQgl6CMYHEADOAykB6AkICPgHAAB7mgAA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\"\n    }\n}\n","frame.ts":"namespace control.__screen {\n    let __update: () => void\n    let __updated = false;\n\n    export function update() {\n        if (__update)\n            __update()\n        __updated = true\n    }\n\n    export function setupUpdate(update: () => void) {\n        __updated = true;\n        __update = update;\n        update()\n    }\n\n    // low frequency fallback screen refresh\n    control.runInParallel(() => {\n        while (true) {\n            __updated = false\n            pause(200)\n            if (!__updated) {\n                __screen.update();\n                __updated = true\n            }\n        }\n    })\n}\n","image.cpp":"#include \"pxt.h\"\n\n#if IMAGE_BITS == 1\n// OK\n#elif IMAGE_BITS == 4\n// OK\n#else\n#error \"Invalid IMAGE_BITS\"\n#endif\n\n#define XX(v) (int)(((int16_t)(v)))\n#define YY(v) (int)(((int16_t)(((int32_t)(v)) >> 16)))\n\nnamespace pxt {\n\nPXT_VTABLE(RefImage, ValType::Object)\n\nvoid RefImage::destroy(RefImage *t) {}\n\nvoid RefImage::print(RefImage *t) {\n    DMESG(\"RefImage %p size=%d x %d\", t, t->width(), t->height());\n}\n\nint RefImage::wordHeight() {\n    if (bpp() == 1)\n        oops(20);\n    return ((height() * 4 + 31) >> 5);\n}\n\nvoid RefImage::makeWritable() {\n    ++revision;\n    if (buffer->isReadOnly()) {\n        buffer = mkBuffer(data(), length());\n    }\n}\n\nuint8_t RefImage::fillMask(color c) {\n    return this->bpp() == 1 ? (c & 1) * 0xff : 0x11 * (c & 0xf);\n}\n\nbool RefImage::inRange(int x, int y) {\n    return 0 <= x && x < width() && 0 <= y && y < height();\n}\n\nvoid RefImage::clamp(int *x, int *y) {\n    *x = min(max(*x, 0), width() - 1);\n    *y = min(max(*y, 0), height() - 1);\n}\n\nRefImage::RefImage(BoxedBuffer *buf) : PXT_VTABLE_INIT(RefImage), buffer(buf) {\n    revision = 0;\n    if (!buf)\n        oops(21);\n}\n\nstatic inline int byteSize(int w, int h, int bpp) {\n    if (bpp == 1)\n        return sizeof(ImageHeader) + ((h + 7) >> 3) * w;\n    else\n        return sizeof(ImageHeader) + (((h * 4 + 31) / 32) * 4) * w;\n}\n\nImage_ allocImage(const uint8_t *data, uint32_t sz) {\n    auto buf = mkBuffer(data, sz);\n    registerGCObj(buf);\n    Image_ r = NEW_GC(RefImage, buf);\n    unregisterGCObj(buf);\n    return r;\n}\n\nImage_ mkImage(int width, int height, int bpp) {\n    if (width < 0 || height < 0 || width > 2000 || height > 2000)\n        return NULL;\n    if (bpp != 1 && bpp != 4)\n        return NULL;\n    uint32_t sz = byteSize(width, height, bpp);\n    Image_ r = allocImage(NULL, sz);\n    auto hd = r->header();\n    hd->magic = IMAGE_HEADER_MAGIC;\n    hd->bpp = bpp;\n    hd->width = width;\n    hd->height = height;\n    hd->padding = 0;\n    MEMDBG(\"mkImage: %d X %d => %p\", width, height, r);\n    return r;\n}\n\nbool isValidImage(Buffer buf) {\n    if (!buf || buf->length < 9)\n        return false;\n\n    auto hd = (ImageHeader *)(buf->data);\n    if (hd->magic != IMAGE_HEADER_MAGIC || (hd->bpp != 1 && hd->bpp != 4))\n        return false;\n\n    int sz = byteSize(hd->width, hd->height, hd->bpp);\n    if (sz != (int)buf->length)\n        return false;\n\n    return true;\n}\n\nbool isLegacyImage(Buffer buf) {\n    if (!buf || buf->length < 5)\n        return false;\n\n    if (buf->data[0] != 0xe1 && buf->data[0] != 0xe4)\n        return false;\n\n    int sz = byteSize(buf->data[1], buf->data[2], buf->data[0] & 0xf) - 4;\n    if (sz != (int)buf->length)\n        return false;\n\n    return true;\n}\n\n} // namespace pxt\n\nnamespace ImageMethods {\n\n/**\n * Get the width of the image\n */\n//% property\nint width(Image_ img) {\n    return img->width();\n}\n\n/**\n * Get the height of the image\n */\n//% property\nint height(Image_ img) {\n    return img->height();\n}\n\n/**\n * True if the image is monochromatic (black and white)\n */\n//% property\nbool isMono(Image_ img) {\n    return img->bpp() == 1;\n}\n\n//% property\nbool isStatic(Image_ img) {\n    return img->buffer->isReadOnly();\n}\n\n//% property\nbool revision(Image_ img) {\n    return img->revision;\n}\n\n/**\n * Sets all pixels in the current image from the other image, which has to be of the same size and\n * bpp.\n */\n//%\nvoid copyFrom(Image_ img, Image_ from) {\n    if (img->width() != from->width() || img->height() != from->height() ||\n        img->bpp() != from->bpp())\n        return;\n    img->makeWritable();\n    memcpy(img->pix(), from->pix(), from->pixLength());\n}\n\nstatic void setCore(Image_ img, int x, int y, int c) {\n    auto ptr = img->pix(x, y);\n    if (img->bpp() == 4) {\n        if (y & 1)\n            *ptr = (*ptr & 0x0f) | (c << 4);\n        else\n            *ptr = (*ptr & 0xf0) | (c & 0xf);\n    } else if (img->bpp() == 1) {\n        uint8_t mask = 0x01 << (y & 7);\n        if (c)\n            *ptr |= mask;\n        else\n            *ptr &= ~mask;\n    }\n}\n\nstatic int getCore(Image_ img, int x, int y) {\n    auto ptr = img->pix(x, y);\n    if (img->bpp() == 4) {\n        if (y & 1)\n            return *ptr >> 4;\n        else\n            return *ptr & 0x0f;\n    } else if (img->bpp() == 1) {\n        uint8_t mask = 0x01 << (y & 7);\n        return (*ptr & mask) ? 1 : 0;\n    }\n    return 0;\n}\n\n/**\n * Set pixel color\n */\n//%\nvoid setPixel(Image_ img, int x, int y, int c) {\n    if (!img->inRange(x, y))\n        return;\n    img->makeWritable();\n    setCore(img, x, y, c);\n}\n\n/**\n * Get a pixel color\n */\n//%\nint getPixel(Image_ img, int x, int y) {\n    if (!img->inRange(x, y))\n        return 0;\n    return getCore(img, x, y);\n}\n\nvoid fillRect(Image_ img, int x, int y, int w, int h, int c);\n\n/**\n * Fill entire image with a given color\n */\n//%\nvoid fill(Image_ img, int c) {\n    if (c && img->hasPadding()) {\n        fillRect(img, 0, 0, img->width(), img->height(), c);\n        return;\n    }\n    img->makeWritable();\n    memset(img->pix(), img->fillMask(c), img->pixLength());\n}\n\n/**\n * Copy row(s) of pixel from image to buffer (8 bit per pixel).\n */\n//%\nvoid getRows(Image_ img, int x, Buffer dst) {\n    if (img->bpp() != 4)\n        return;\n\n    int w = img->width();\n    int h = img->height();\n    if (x >= w || x < 0)\n        return;\n\n    uint8_t *sp = img->pix(x, 0);\n    uint8_t *dp = dst->data;\n    int n = min(dst->length, (w - x) * h) >> 1;\n\n    while (n--) {\n        *dp++ = *sp & 0xf;\n        *dp++ = *sp >> 4;\n        sp++;\n    }\n}\n\n/**\n * Copy row(s) of pixel from buffer to image.\n */\n//%\nvoid setRows(Image_ img, int x, Buffer src) {\n    if (img->bpp() != 4)\n        return;\n\n    int w = img->width();\n    int h = img->height();\n    if (x >= w || x < 0)\n        return;\n\n    img->makeWritable();\n\n    uint8_t *dp = img->pix(x, 0);\n    uint8_t *sp = src->data;\n    int n = min(src->length, (w - x) * h) >> 1;\n\n    while (n--) {\n        *dp++ = (sp[0] & 0xf) | (sp[1] << 4);\n        sp += 2;\n    }\n}\n\nvoid fillRect(Image_ img, int x, int y, int w, int h, int c) {\n    if (w == 0 || h == 0 || x >= img->width() || y >= img->height())\n        return;\n\n    int x2 = x + w - 1;\n    int y2 = y + h - 1;\n\n    if (x2 < 0 || y2 < 0)\n        return;\n\n    img->clamp(&x2, &y2);\n    img->clamp(&x, &y);\n    w = x2 - x + 1;\n    h = y2 - y + 1;\n\n    if (!img->hasPadding() && x == 0 && y == 0 && w == img->width() && h == img->height()) {\n        fill(img, c);\n        return;\n    }\n\n    img->makeWritable();\n\n    auto bh = img->byteHeight();\n    uint8_t f = img->fillMask(c);\n\n    uint8_t *p = img->pix(x, y);\n    while (w-- > 0) {\n        if (img->bpp() == 1) {\n            auto ptr = p;\n            unsigned mask = 0x01 << (y & 7);\n\n            for (int i = 0; i < h; ++i) {\n                if (mask == 0x100) {\n                    if (h - i >= 8) {\n                        *++ptr = f;\n                        i += 7;\n                        continue;\n                    } else {\n                        mask = 0x01;\n                        ++ptr;\n                    }\n                }\n                if (c)\n                    *ptr |= mask;\n                else\n                    *ptr &= ~mask;\n                mask <<= 1;\n            }\n\n        } else if (img->bpp() == 4) {\n            auto ptr = p;\n            unsigned mask = 0x0f;\n            if (y & 1)\n                mask <<= 4;\n\n            for (int i = 0; i < h; ++i) {\n                if (mask == 0xf00) {\n                    if (h - i >= 2) {\n                        *++ptr = f;\n                        i++;\n                        continue;\n                    } else {\n                        mask = 0x0f;\n                        ptr++;\n                    }\n                }\n                *ptr = (*ptr & ~mask) | (f & mask);\n                mask <<= 4;\n            }\n        }\n        p += bh;\n    }\n}\n\n//%\nvoid _fillRect(Image_ img, int xy, int wh, int c) {\n    fillRect(img, XX(xy), YY(xy), XX(wh), YY(wh), c);\n}\n\nvoid mapRect(Image_ img, int x, int y, int w, int h, Buffer map) {\n    if (w == 0 || h == 0 || x >= img->width() || y >= img->height())\n        return;\n\n    if (img->bpp() != 4 || map->length < 16)\n        return;\n\n    int x2 = x + w - 1;\n    int y2 = y + h - 1;\n\n    if (x2 < 0 || y2 < 0)\n        return;\n\n    img->clamp(&x2, &y2);\n    img->clamp(&x, &y);\n    w = x2 - x + 1;\n    h = y2 - y + 1;\n\n    img->makeWritable();\n\n    auto bh = img->byteHeight();\n    auto m = map->data;\n    uint8_t *p = img->pix(x, y);\n    while (w-- > 0) {\n        auto ptr = p;\n        unsigned shift = y & 1;\n        for (int i = 0; i < h; i++) {\n            if (shift) {\n                *ptr = (m[*ptr >> 4] << 4) | (*ptr & 0x0f);\n                ptr++;\n                shift = 0;\n            } else {\n                *ptr = (m[*ptr & 0xf] & 0xf) | (*ptr & 0xf0);\n                shift = 1;\n            }\n        }\n        p += bh;\n    }\n}\n\n//%\nvoid _mapRect(Image_ img, int xy, int wh, Buffer c) {\n    mapRect(img, XX(xy), YY(xy), XX(wh), YY(wh), c);\n}\n\n//% argsNullable\nbool equals(Image_ img, Image_ other) {\n    if (!other) {\n        return false;\n    }\n    auto len = img->length();\n    if (len != other->length()) {\n        return false;\n    }\n    return 0 == memcmp(img->data(), other->data(), len);\n}\n\n/**\n * Return a copy of the current image\n */\n//%\nImage_ clone(Image_ img) {\n    auto r = allocImage(img->data(), img->length());\n    MEMDBG(\"mkImageClone: %d X %d => %p\", img->width(), img->height(), r);\n    return r;\n}\n\n/**\n * Flips (mirrors) pixels horizontally in the current image\n */\n//%\nvoid flipX(Image_ img) {\n    img->makeWritable();\n\n    int bh = img->byteHeight();\n    auto a = img->pix();\n    auto b = img->pix(img->width() - 1, 0);\n\n    uint8_t tmp[bh];\n\n    while (a < b) {\n        memcpy(tmp, a, bh);\n        memcpy(a, b, bh);\n        memcpy(b, tmp, bh);\n        a += bh;\n        b -= bh;\n    }\n}\n\n/**\n * Flips (mirrors) pixels vertically in the current image\n */\n//%\nvoid flipY(Image_ img) {\n    img->makeWritable();\n\n    // this is quite slow - for small 16x16 sprite it will take in the order of 1ms\n    // something faster requires quite a bit of bit tweaking, especially for mono images\n    for (int i = 0; i < img->width(); ++i) {\n        int a = 0;\n        int b = img->height() - 1;\n        while (a < b) {\n            int tmp = getCore(img, i, a);\n            setCore(img, i, a, getCore(img, i, b));\n            setCore(img, i, b, tmp);\n            a++;\n            b--;\n        }\n    }\n}\n\n/**\n * Returns a transposed image (with X/Y swapped)\n */\n//%\nImage_ transposed(Image_ img) {\n    Image_ r = mkImage(img->height(), img->width(), img->bpp());\n\n    // this is quite slow\n    for (int i = 0; i < img->width(); ++i) {\n        for (int j = 0; j < img->height(); ++j) {\n            setCore(r, j, i, getCore(img, i, j));\n        }\n    }\n\n    return r;\n}\n\nvoid drawImage(Image_ img, Image_ from, int x, int y);\n\n/**\n * Every pixel in image is moved by (dx,dy)\n */\n//%\nvoid scroll(Image_ img, int dx, int dy) {\n    img->makeWritable();\n    auto bh = img->byteHeight();\n    auto w = img->width();\n    if (dy != 0) {\n        // TODO one day we may want a more memory-efficient implementation\n        auto img2 = clone(img);\n        fill(img, 0);\n        drawImage(img, img2, dx, dy);\n    } else if (dx < 0) {\n        dx = -dx;\n        if (dx < w)\n            memmove(img->pix(), img->pix(dx, 0), (w - dx) * bh);\n        else\n            dx = w;\n        memset(img->pix(w - dx, 0), 0, dx * bh);\n    } else if (dx > 0) {\n        if (dx < w)\n            memmove(img->pix(dx, 0), img->pix(), (w - dx) * bh);\n        else\n            dx = w;\n        memset(img->pix(), 0, dx * bh);\n    }\n}\n\nconst uint8_t bitdouble[] = {0x00, 0x03, 0x0c, 0x0f, 0x30, 0x33, 0x3c, 0x3f,\n                             0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, 0xff};\nconst uint8_t nibdouble[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,\n                             0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};\n\n/**\n * Stretches the image horizontally by 100%\n */\n//%\nImage_ doubledX(Image_ img) {\n    if (img->width() > 126)\n        return NULL;\n\n    Image_ r = mkImage(img->width() * 2, img->height(), img->bpp());\n    auto src = img->pix();\n    auto dst = r->pix();\n    auto w = img->width();\n    auto bh = img->byteHeight();\n\n    for (int i = 0; i < w; ++i) {\n        memcpy(dst, src, bh);\n        dst += bh;\n        memcpy(dst, src, bh);\n        dst += bh;\n\n        src += bh;\n    }\n\n    return r;\n}\n\n/**\n * Stretches the image vertically by 100%\n */\n//%\nImage_ doubledY(Image_ img) {\n    if (img->height() > 126)\n        return NULL;\n\n    Image_ r = mkImage(img->width(), img->height() * 2, img->bpp());\n    auto src0 = img->pix();\n    auto dst = r->pix();\n\n    auto w = img->width();\n    auto sbh = img->byteHeight();\n    auto bh = r->byteHeight();\n    auto dbl = img->bpp() == 1 ? bitdouble : nibdouble;\n\n    for (int i = 0; i < w; ++i) {\n        auto src = src0 + i * sbh;\n        for (int j = 0; j < bh; j += 2) {\n            *dst++ = dbl[*src & 0xf];\n            if (j != bh - 1)\n                *dst++ = dbl[*src >> 4];\n            src++;\n        }\n    }\n\n    return r;\n}\n\n/**\n * Replaces one color in an image with another\n */\n//%\nvoid replace(Image_ img, int from, int to) {\n    if (img->bpp() != 4)\n        return;\n    to &= 0xf;\n    if (from == to)\n        return;\n\n    img->makeWritable();\n\n    // avoid bleeding 'to' color into the overflow areas of the picture\n    if (from == 0 && img->hasPadding()) {\n        for (int i = 0; i < img->height(); ++i)\n            for (int j = 0; j < img->width(); ++j)\n                if (getCore(img, j, i) == from)\n                    setCore(img, j, i, to);\n        return;\n    }\n\n    auto ptr = img->pix();\n    auto len = img->pixLength();\n    while (len--) {\n        auto b = *ptr;\n        if ((b & 0xf) == from)\n            b = (b & 0xf0) | to;\n        if ((b >> 4) == from)\n            b = (to << 4) | (b & 0xf);\n        *ptr++ = b;\n    }\n}\n\n/**\n * Stretches the image in both directions by 100%\n */\n//%\nImage_ doubled(Image_ img) {\n    Image_ tmp = doubledX(img);\n    registerGCObj(tmp);\n    Image_ r = doubledY(tmp);\n    unregisterGCObj(tmp);\n    return r;\n}\n\nbool drawImageCore(Image_ img, Image_ from, int x, int y, int color) {\n    auto w = from->width();\n    auto h = from->height();\n    auto sh = img->height();\n    auto sw = img->width();\n\n    if (x + w <= 0)\n        return false;\n    if (x >= sw)\n        return false;\n    if (y + h <= 0)\n        return false;\n    if (y >= sh)\n        return false;\n\n    auto len = y < 0 ? min(sh, h + y) : min(sh - y, h);\n    auto tbp = img->bpp();\n    auto fbp = from->bpp();\n    auto y0 = y;\n\n    if (color == -2 && x == 0 && y == 0 && tbp == fbp && w == sw && h == sh) {\n        copyFrom(img, from);\n        return false;\n    }\n\n    // DMESG(\"drawIMG(%d,%d) at (%d,%d) w=%d bh=%d len=%d\",\n    //    w,h,x, y, img->width(), img->byteHeight(), len );\n\n    auto fromH = from->byteHeight();\n    auto imgH = img->byteHeight();\n    auto fromBase = from->pix();\n    auto imgBase = img->pix(0, y);\n\n#define LOOPHD                                                                                     \\\n    for (int xx = 0; xx < w; ++xx, ++x)                                                            \\\n        if (0 <= x && x < sw)\n\n    if (tbp == 4 && fbp == 4) {\n        auto wordH = fromH >> 2;\n        LOOPHD {\n            y = y0;\n\n            auto fdata = (uint32_t *)fromBase + wordH * xx;\n            auto tdata = imgBase + imgH * x;\n\n            // DMESG(\"%d,%d xx=%d/%d - %p (%p) -- %d\",x,y,xx,w,tdata,img->pix(),\n            //    (uint8_t*)fdata - from->pix());\n\n            auto cnt = wordH;\n            auto bot = min(sh, y + h);\n\n#define COLS(s) ((v >> (s)) & 0xf)\n#define COL(s) COLS(s)\n\n#define STEPA(s)                                                                                   \\\n    if (COL(s) && 0 <= y && y < bot)                                                               \\\n        SETLOW(s);                                                                                 \\\n    y++;\n#define STEPB(s)                                                                                   \\\n    if (COL(s) && 0 <= y && y < bot)                                                               \\\n        SETHIGH(s);                                                                                \\\n    y++;                                                                                           \\\n    tdata++;\n#define STEPAQ(s)                                                                                  \\\n    if (COL(s))                                                                                    \\\n        SETLOW(s);\n#define STEPBQ(s)                                                                                  \\\n    if (COL(s))                                                                                    \\\n        SETHIGH(s);                                                                                \\\n    tdata++;\n\n// perf: expanded version 5% faster\n#define ORDER(A, B)                                                                                \\\n    A(0);                                                                                          \\\n    B(4);                                                                                          \\\n    A(8);                                                                                          \\\n    B(12);                                                                                         \\\n    A(16);                                                                                         \\\n    B(20);                                                                                         \\\n    A(24);                                                                                         \\\n    B(28)\n//#define ORDER(A,B) for (int k = 0; k < 32; k += 8) { A(k); B(4+k); }\n#define LOOP(A, B, xbot)                                                                           \\\n    while (cnt--) {                                                                                \\\n        auto v = *fdata++;                                                                         \\\n        if (0 <= y && y <= xbot - 8) {                                                             \\\n            ORDER(A##Q, B##Q);                                                                     \\\n            y += 8;                                                                                \\\n        } else {                                                                                   \\\n            ORDER(A, B);                                                                           \\\n        }                                                                                          \\\n    }\n#define LOOPS(xbot)                                                                                \\\n    if (y & 1)                                                                                     \\\n        LOOP(STEPB, STEPA, xbot)                                                                   \\\n    else                                                                                           \\\n        LOOP(STEPA, STEPB, xbot)\n\n            if (color >= 0) {\n#define SETHIGH(s) *tdata = (*tdata & 0x0f) | ((COLS(s)) << 4)\n#define SETLOW(s) *tdata = (*tdata & 0xf0) | COLS(s)\n                LOOPS(sh)\n            } else if (color == -2) {\n#undef COL\n#define COL(s) 1\n                LOOPS(bot)\n            } else {\n#undef COL\n#define COL(s) COLS(s)\n#undef SETHIGH\n#define SETHIGH(s)                                                                                 \\\n    if (*tdata & 0xf0)                                                                             \\\n    return true\n#undef SETLOW\n#define SETLOW(s)                                                                                  \\\n    if (*tdata & 0x0f)                                                                             \\\n    return true\n                LOOPS(sh)\n            }\n        }\n    } else if (tbp == 1 && fbp == 1) {\n        auto left = img->pix() - imgBase;\n        auto right = img->pix(0, img->height() - 1) - imgBase;\n        LOOPHD {\n            y = y0;\n\n            auto data = fromBase + fromH * xx;\n            auto off = imgBase + imgH * x;\n            auto off0 = off + left;\n            auto off1 = off + right;\n\n            int shift = (y & 7);\n\n            int y1 = y + h + (y & 7);\n            int prev = 0;\n\n            while (y < y1 - 8) {\n                int curr = *data++ << shift;\n                if (off0 <= off && off <= off1) {\n                    uint8_t v = (curr >> 0) | (prev >> 8);\n\n                    if (color == -1) {\n                        if (*off & v)\n                            return true;\n                    } else {\n                        *off |= v;\n                    }\n                }\n                off++;\n                prev = curr;\n                y += 8;\n            }\n\n            int left = y1 - y;\n            if (left > 0) {\n                int curr = *data << shift;\n                if (off0 <= off && off <= off1) {\n                    uint8_t v = ((curr >> 0) | (prev >> 8)) & (0xff >> (8 - left));\n                    if (color == -1) {\n                        if (*off & v)\n                            return true;\n                    } else {\n                        *off |= v;\n                    }\n                }\n            }\n        }\n    } else if (tbp == 4 && fbp == 1) {\n        if (y < 0) {\n            fromBase = from->pix(0, -y);\n            imgBase = img->pix();\n        }\n        // icon mode\n        LOOPHD {\n            auto fdata = fromBase + fromH * xx;\n            auto tdata = imgBase + imgH * x;\n\n            unsigned mask = 0x01;\n            auto v = *fdata++;\n            int off = (y & 1) ? 1 : 0;\n            if (y < 0) {\n                mask <<= -y & 7;\n                off = 0;\n            }\n            for (int i = off; i < len + off; ++i) {\n                if (mask == 0x100) {\n                    mask = 0x01;\n                    v = *fdata++;\n                }\n                if (v & mask) {\n                    if (i & 1)\n                        *tdata = (*tdata & 0x0f) | (color << 4);\n                    else\n                        *tdata = (*tdata & 0xf0) | color;\n                }\n                mask <<= 1;\n                if (i & 1)\n                    tdata++;\n            }\n        }\n    }\n\n    return false;\n}\n\n/**\n * Draw given image on the current image\n */\n//%\nvoid drawImage(Image_ img, Image_ from, int x, int y) {\n    img->makeWritable();\n    if (img->bpp() == 4 && from->bpp() == 4) {\n        drawImageCore(img, from, x, y, -2);\n    } else {\n        fillRect(img, x, y, from->width(), from->height(), 0);\n        drawImageCore(img, from, x, y, 0);\n    }\n}\n\n/**\n * Draw given image with transparent background on the current image\n */\n//%\nvoid drawTransparentImage(Image_ img, Image_ from, int x, int y) {\n    img->makeWritable();\n    drawImageCore(img, from, x, y, 0);\n}\n\n/**\n * Check if the current image \"collides\" with another\n */\n//%\nbool overlapsWith(Image_ img, Image_ other, int x, int y) {\n    return drawImageCore(img, other, x, y, -1);\n}\n\n// Image_ format (legacy)\n//  byte 0: magic 0xe4 - 4 bit color; 0xe1 is monochromatic\n//  byte 1: width in pixels\n//  byte 2: height in pixels\n//  byte 3: padding (should be zero)\n//  byte 4...N: data 4 bits per pixels, high order nibble printed first, lines aligned to 32 bit\n//  words byte 4...N: data 1 bit per pixels, high order bit printed first, lines aligned to byte\n\nImage_ convertAndWrap(Buffer buf) {\n    if (isValidImage(buf))\n        return NEW_GC(RefImage, buf);\n\n    // What follows in this function is mostly dead code, except if people construct image buffers\n    // by hand. Probably safe to remove in a year (middle of 2020) or so. When removing, also remove\n    // from sim.\n    if (!isLegacyImage(buf))\n        return NULL;\n\n    auto tmp = mkBuffer(NULL, buf->length + 4);\n    auto hd = (ImageHeader *)tmp->data;\n    auto src = buf->data;\n    hd->magic = IMAGE_HEADER_MAGIC;\n    hd->bpp = src[0] & 0xf;\n    hd->width = src[1];\n    hd->height = src[2];\n    hd->padding = 0;\n    memcpy(hd->pixels, src + 4, buf->length - 4);\n\n    registerGCObj(tmp);\n    auto r = NEW_GC(RefImage, tmp);\n    unregisterGCObj(tmp);\n    return r;\n}\n\n//%\nvoid _drawIcon(Image_ img, Buffer icon, int xy, int c) {\n    img->makeWritable();\n\n    auto iconImg = convertAndWrap(icon);\n    if (!iconImg || iconImg->bpp() != 1)\n        return;\n\n    drawImageCore(img, iconImg, XX(xy), YY(xy), c);\n}\n\nstatic void drawLineLow(Image_ img, int x0, int y0, int x1, int y1, int c) {\n    int dx = x1 - x0;\n    int dy = y1 - y0;\n    int yi = 1;\n    if (dy < 0) {\n        yi = -1;\n        dy = -dy;\n    }\n    int D = 2 * dy - dx;\n    dx <<= 1;\n    dy <<= 1;\n    int y = y0;\n    for (int x = x0; x <= x1; ++x) {\n        setCore(img, x, y, c);\n        if (D > 0) {\n            y += yi;\n            D -= dx;\n        }\n        D += dy;\n    }\n}\n\nstatic void drawLineHigh(Image_ img, int x0, int y0, int x1, int y1, int c) {\n    int dx = x1 - x0;\n    int dy = y1 - y0;\n    int xi = 1;\n    if (dx < 0) {\n        xi = -1;\n        dx = -dx;\n    }\n    int D = 2 * dx - dy;\n    dx <<= 1;\n    dy <<= 1;\n    int x = x0;\n    for (int y = y0; y <= y1; ++y) {\n        setCore(img, x, y, c);\n        if (D > 0) {\n            x += xi;\n            D -= dy;\n        }\n        D += dx;\n    }\n}\n\nvoid drawLine(Image_ img, int x0, int y0, int x1, int y1, int c) {\n    if (x1 < x0) {\n        drawLine(img, x1, y1, x0, y0, c);\n        return;\n    }\n    int w = x1 - x0;\n    int h = y1 - y0;\n\n    if (h == 0) {\n        if (w == 0)\n            setPixel(img, x0, y0, c);\n        else\n            fillRect(img, x0, y0, w + 1, 1, c);\n        return;\n    }\n\n    if (w == 0) {\n        if (h > 0)\n            fillRect(img, x0, y0, 1, h + 1, c);\n        else\n            fillRect(img, x0, y1, 1, -h + 1, c);\n        return;\n    }\n\n    if (x1 < 0 || x0 >= img->width())\n        return;\n    if (x0 < 0) {\n        y0 -= (h * x0 / w);\n        x0 = 0;\n    }\n    if (x1 >= img->width()) {\n        int d = (img->width() - 1) - x1;\n        y1 += (h * d / w);\n        x1 = img->width() - 1;\n    }\n\n    if (y0 < y1) {\n        if (y0 >= img->height() || y1 < 0)\n            return;\n        if (y0 < 0) {\n            x0 -= (w * y0 / h);\n            y0 = 0;\n        }\n        if (y1 >= img->height()) {\n            int d = (img->height() - 1) - y1;\n            x1 += (w * d / h);\n            y1 = img->height() - 1;\n        }\n    } else {\n        if (y1 >= img->height() || y0 < 0)\n            return;\n        if (y1 < 0) {\n            x1 -= (w * y1 / h);\n            y1 = 0;\n        }\n        if (y0 >= img->height()) {\n            int d = (img->height() - 1) - y0;\n            x0 += (w * d / h);\n            y0 = img->height() - 1;\n        }\n    }\n\n    img->makeWritable();\n\n    if (h < 0) {\n        h = -h;\n        if (h < w)\n            drawLineLow(img, x0, y0, x1, y1, c);\n        else\n            drawLineHigh(img, x1, y1, x0, y0, c);\n    } else {\n        if (h < w)\n            drawLineLow(img, x0, y0, x1, y1, c);\n        else\n            drawLineHigh(img, x0, y0, x1, y1, c);\n    }\n}\n\n//%\nvoid _drawLine(Image_ img, int xy, int wh, int c) {\n    drawLine(img, XX(xy), YY(xy), XX(wh), YY(wh), c);\n}\n\nvoid blitRow(Image_ img, int x, int y, Image_ from, int fromX, int fromH) {\n    if (!img->inRange(x, 0) || !img->inRange(fromX, 0) || fromH <= 0)\n        return;\n\n    if (img->bpp() != 4 || from->bpp() != 4)\n        return;\n\n    int fy = 0;\n    int stepFY = (from->width() << 16) / fromH;\n    int endY = y + fromH;\n    if (endY > img->height())\n        endY = img->height();\n    if (y < 0) {\n        fy += -y * stepFY;\n        y = 0;\n    }\n\n    auto dp = img->pix(x, y);\n    auto sp = from->pix(fromX, 0);\n\n    while (y < endY) {\n        int p = fy >> 16, c;\n        if (p & 1)\n            c = sp[p >> 1] >> 4;\n        else\n            c = sp[p >> 1] & 0xf;\n        if (y & 1) {\n            *dp = (*dp & 0x0f) | (c << 4);\n            dp++;\n        } else {\n            *dp = (*dp & 0xf0) | (c & 0xf);\n        }\n        y++;\n        fy += stepFY;\n    }\n}\n\n//%\nvoid _blitRow(Image_ img, int xy, Image_ from, int xh) {\n    blitRow(img, XX(xy), YY(xy), from, XX(xh), YY(xh));\n}\n\nbool blit(Image_ dst, Image_ src, pxt::RefCollection *args) {\n    int xDst = pxt::toInt(args->getAt(0));\n    int yDst = pxt::toInt(args->getAt(1));\n    int wDst = pxt::toInt(args->getAt(2));\n    int hDst = pxt::toInt(args->getAt(3));\n    int xSrc = pxt::toInt(args->getAt(4));\n    int ySrc = pxt::toInt(args->getAt(5));\n    int wSrc = pxt::toInt(args->getAt(6));\n    int hSrc = pxt::toInt(args->getAt(7));\n    bool transparent = pxt::toBoolQuick(args->getAt(8));\n    bool check = pxt::toBoolQuick(args->getAt(9));\n\n    int xSrcStep = (wSrc << 16) / wDst;\n    int ySrcStep = (hSrc << 16) / hDst;\n\n    int xDstClip = abs(min(0, xDst));\n    int yDstClip = abs(min(0, yDst));\n    int xDstStart = xDst + xDstClip;\n    int yDstStart = yDst + yDstClip;\n    int xDstEnd = min(dst->width(), xDst + wDst);\n    int yDstEnd = min(dst->height(), yDst + hDst);\n\n    int xSrcStart = max(0, (xSrc << 16) + xDstClip * xSrcStep);\n    int ySrcStart = max(0, (ySrc << 16) + yDstClip * ySrcStep);\n    int xSrcEnd = min(src->width(), xSrc + wSrc) << 16;\n    int ySrcEnd = min(src->height(), ySrc + hSrc) << 16;\n\n    if (!check)\n        dst->makeWritable();\n\n    for (int yDstCur = yDstStart, ySrcCur = ySrcStart; yDstCur < yDstEnd && ySrcCur < ySrcEnd; ++yDstCur, ySrcCur += ySrcStep) {\n        int ySrcCurI = ySrcCur >> 16;\n        for (int xDstCur = xDstStart, xSrcCur = xSrcStart; xDstCur < xDstEnd && xSrcCur < xSrcEnd; ++xDstCur, xSrcCur += xSrcStep) {\n            int xSrcCurI = xSrcCur >> 16;\n            int cSrc = getCore(src, xSrcCurI, ySrcCurI);\n            if (check && cSrc) {\n                int cDst = getCore(dst, xDstCur, yDstCur);\n                if (cDst) {\n                    return true;\n                }\n                continue;\n            }\n            if (!transparent || cSrc) {\n                setCore(dst, xDstCur, yDstCur, cSrc);\n            }\n        }\n    }\n    return false;\n}\n\n//%\nbool _blit(Image_ img, Image_ src, pxt::RefCollection *args) {\n    return blit(img, src, args);\n}\n\nvoid fillCircle(Image_ img, int cx, int cy, int r, int c) {\n    int x = r - 1;\n    int y = 0;\n    int dx = 1;\n    int dy = 1;\n    int err = dx - (r << 1);\n\n    while (x >= y) {\n        fillRect(img, cx + x, cy - y, 1, 1 + (y << 1), c);\n        fillRect(img, cx + y, cy - x, 1, 1 + (x << 1), c);\n        fillRect(img, cx - x, cy - y, 1, 1 + (y << 1), c);\n        fillRect(img, cx - y, cy - x, 1, 1 + (x << 1), c);\n        if (err <= 0) {\n            ++y;\n            err += dy;\n            dy += 2;\n        } else {\n            --x;\n            dx += 2;\n            err += dx - (r << 1);\n        }\n    }\n}\n\n//%\nvoid _fillCircle(Image_ img, int cxy, int r, int c) {\n    fillCircle(img, XX(cxy), YY(cxy), r, c);\n}\n\ntypedef struct\n{\n    int x, y;\n    int x0, y0;\n    int x1, y1;\n    int W,H;\n    int dx, dy;\n    int yi, xi;\n    int D;\n    int nextFuncIndex;\n} LineGenState; // For keeping track of the state when generating Y values for a line, even when moving to the next X.\n\ntypedef struct\n{\n    int min;\n    int max;\n} ValueRange;\n\nvoid nextYRange_Low(int x, LineGenState *line, ValueRange *yRange) {\n    while (line->x == x && line->x <= line->x1 && line->x < line->W) {\n        if (0 <= line->x) {\n            if (line->y < yRange->min) yRange->min = line->y;\n            if (line->y > yRange->max) yRange->max = line->y;\n        }\n        if (line->D > 0) {\n            line->y += line->yi;\n            line->D -= line->dx;\n        }\n        line->D += line->dy;\n        ++line->x;\n    }\n}\n\nvoid nextYRange_HighUp(int x, LineGenState *line, ValueRange *yRange) {\n    while (line->x == x && line->y >= line->y1 && line->x < line->W) {\n        if (0 <= line->x) {\n            if (line->y < yRange->min) yRange->min = line->y;\n            if (line->y > yRange->max) yRange->max = line->y;\n        }\n        if (line->D > 0) {\n            line->x += line->xi;\n            line->D += line->dy;\n        }\n        line->D += line->dx;\n        --line->y;\n    }\n}\n// This function is similar to the sub-function drawLineHigh for drawLine. However, it yields back after calculating all Y values of a given X. When the function is called again, it continues from the state where it yielded back previously.\nvoid nextYRange_HighDown(int x, LineGenState *line, ValueRange *yRange) {\n    while (line->x == x && line->y <= line->y1 && line->x < line->W) {\n        if (0 <= line->x) {\n            if (line->y < yRange->min) yRange->min = line->y;\n            if (line->y > yRange->max) yRange->max = line->y;\n        }\n        if (line->D > 0) {\n            line->x += line->xi;\n            line->D -= line->dy;\n        }\n        line->D += line->dx;\n        ++line->y;\n    }\n}\n\nLineGenState initYRangeGenerator(int16_t X0, int16_t Y0, int16_t X1, int16_t Y1) {\n    LineGenState line;\n\n    line.x0 = X0, line.y0 = Y0, line.x1 = X1, line.y1 = Y1;\n\n    line.dx = line.x1 - line.x0;\n    line.dy = line.y1 - line.y0;\n    line.y = line.y0;\n    line.x = line.x0;\n\n    if ((line.dy < 0 ? -line.dy : line.dy) < line.dx) {\n        line.yi = 1;\n        if (line.dy < 0) {\n            line.yi = -1;\n            line.dy = -line.dy;\n        }\n        line.D = 2 * line.dy - line.dx;\n        line.dx <<= 1;\n        line.dy <<= 1;\n\n        line.nextFuncIndex = 0;\n        return line;\n    } else {\n        line.xi = 1;\n        // if (dx < 0) {//should not hit\n        //     PANIC();\n        // }\n        if (line.dy < 0) {\n            line.D = 2 * line.dx + line.dy;\n            line.dx <<= 1;\n            line.dy <<= 1;\n\n            line.nextFuncIndex = 1;\n            return line;\n        } else {\n            line.D = 2 * line.dx - line.dy;\n            line.dx <<= 1;\n            line.dy <<= 1;\n\n            line.nextFuncIndex = 2;\n            return line;\n        }\n    }\n}\n\n// core of draw vertical line for repeatly calling, eg.: fillTriangle() or fillPolygon4()\n// value range/safety check not included\n// prepare \"img->makeWritable();\" and \"uint8_t f = img->fillMask(c);\" outside required.\n// bpp=4 support only right now\nvoid drawVLineCore(Image_ img, int x, int y, int h, uint8_t f) {\n    uint8_t *p = img->pix(x, y);\n    auto ptr = p;\n    unsigned mask = 0x0f;\n    if (y & 1)\n        mask <<= 4;\n    for (int i = 0; i < h; ++i) {\n        if (mask == 0xf00) {\n            if (h - i >= 2) {\n                *++ptr = f;\n                i++;\n                continue;\n            } else {\n                mask = 0x0f;\n                ptr++;\n            }\n        }\n        *ptr = (*ptr & ~mask) | (f & mask);\n        mask <<= 4;\n    }\n}\n\nvoid drawVLine(Image_ img, int x, int y, int h, int c) {\n    int H = height(img);\n    uint8_t f = img->fillMask(c);\n    if (x < 0 || x >= width(img) || y >= H || y + h - 1 < 0)\n        return;\n    if (y < 0){\n        h += y;\n        y = 0;\n    }\n    if (y + h > H)\n        h = H - y;\n    drawVLineCore(img, x, y, h, f);\n}\n\nvoid fillTriangle(Image_ img, int x0, int y0, int x1, int y1, int x2, int y2, int c) {\n    if (x1 < x0) {\n        swap(x0, x1);\n        swap(y0, y1);\n    }\n    if (x2 < x1) {\n        swap(x1, x2);\n        swap(y1, y2);\n    }\n    if (x1 < x0) {\n        swap(x0, x1);\n        swap(y0, y1);\n    }\n\n    LineGenState lines[] = {\n        initYRangeGenerator(x0, y0, x2, y2),\n        initYRangeGenerator(x0, y0, x1, y1),\n        initYRangeGenerator(x1, y1, x2, y2)\n    };\n\n    int W = width(img), H = height(img);\n    lines[0].W = lines[1].W = lines[2].W = W;\n    lines[0].H = lines[1].H = lines[2].H = H;\n\n    // We have 3 different sub-functions to generate Ys of edges, each particular edge maps to one of them.\n    // Use function pointers to avoid judging which function to call at every X.\n    typedef void (*FP_NEXT)(int x, LineGenState *line, ValueRange *yRange);\n    FP_NEXT nextFuncList[] = { nextYRange_Low, nextYRange_HighUp, nextYRange_HighDown };\n    FP_NEXT fpNext0 = nextFuncList[lines[0].nextFuncIndex];\n    FP_NEXT fpNext1 = nextFuncList[lines[1].nextFuncIndex];\n    FP_NEXT fpNext2 = nextFuncList[lines[2].nextFuncIndex];\n\n    ValueRange yRange = {H, -1};\n    img->makeWritable();\n    uint8_t f = img->fillMask(c);\n\n    for (int x = lines[1].x0; x <= min(x1, W - 1); x++) {\n        yRange.min = H;\n        yRange.max = -1;\n        fpNext0(x, &lines[0], &yRange);\n        fpNext1(x, &lines[1], &yRange);\n\n        if (x < 0 || yRange.min >= H || yRange.max < 0)\n            continue;\n        if (yRange.min < 0)\n            yRange.min = 0;\n        if (yRange.max >= H)\n            yRange.max = H - 1;\n        drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);\n    }\n\n    fpNext2(lines[2].x0, &lines[2], &yRange);\n\n    for (int x = lines[2].x0 + 1; x <= min(x2, W - 1); x++) {\n        yRange.min = H;\n        yRange.max = -1;\n        fpNext0(x, &lines[0], &yRange);\n        fpNext2(x, &lines[2], &yRange);\n\n        if (x < 0 || yRange.min >= H || yRange.max < 0)\n            continue;\n        if (yRange.min < 0)\n            yRange.min = 0;\n        if (yRange.max >= H)\n            yRange.max = H - 1;\n        drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);\n    }\n}\n\nvoid fillPolygon4(Image_ img, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, int c) {\n    LineGenState lines[] = {\n        (x0 < x1) ? initYRangeGenerator(x0, y0, x1, y1) : initYRangeGenerator(x1, y1, x0, y0),\n        (x1 < x2) ? initYRangeGenerator(x1, y1, x2, y2) : initYRangeGenerator(x2, y2, x1, y1),\n        (x2 < x3) ? initYRangeGenerator(x2, y2, x3, y3) : initYRangeGenerator(x3, y3, x2, y2),\n        (x0 < x3) ? initYRangeGenerator(x0, y0, x3, y3) : initYRangeGenerator(x3, y3, x0, y0)};\n\n    int W = width(img), H = height(img);\n    lines[0].W = lines[1].W = lines[2].W = lines[3].W = W;\n    lines[0].H = lines[1].H = lines[2].H = lines[3].H = H;\n\n    int minX = min(min(x0, x1), min(x2, x3));\n    int maxX = min(max(max(x0, x1), max(x2, x3)), W - 1);\n\n    typedef void (*FP_NEXT)(int x, LineGenState *line, ValueRange *yRange);\n    FP_NEXT nextFuncList[] = { nextYRange_Low, nextYRange_HighUp, nextYRange_HighDown };\n    FP_NEXT fpNext0 = nextFuncList[lines[0].nextFuncIndex];\n    FP_NEXT fpNext1 = nextFuncList[lines[1].nextFuncIndex];\n    FP_NEXT fpNext2 = nextFuncList[lines[2].nextFuncIndex];\n    FP_NEXT fpNext3 = nextFuncList[lines[3].nextFuncIndex];\n\n    ValueRange yRange = { H, -1 };\n    img->makeWritable();\n    uint8_t f = img->fillMask(c);\n\n    for (int x = minX; x <= maxX; x++) {\n        yRange.min = H;\n        yRange.max = -1;\n        fpNext0(x, &lines[0], &yRange);\n        fpNext1(x, &lines[1], &yRange);\n        fpNext2(x, &lines[2], &yRange);\n        fpNext3(x, &lines[3], &yRange);\n\n        if (x < 0 || yRange.min >= H || yRange.max < 0)\n            continue;\n        if (yRange.min < 0)\n            yRange.min = 0;\n        if (yRange.max >= H)\n            yRange.max = H - 1;\n        drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);\n    }\n}\n\n//%\nvoid _fillTriangle(Image_ img, pxt::RefCollection *args) {\n    fillTriangle(\n        img,\n        pxt::toInt(args->getAt(0)),\n        pxt::toInt(args->getAt(1)),\n        pxt::toInt(args->getAt(2)),\n        pxt::toInt(args->getAt(3)),\n        pxt::toInt(args->getAt(4)),\n        pxt::toInt(args->getAt(5)),\n        pxt::toInt(args->getAt(6))\n    );\n}\n\n// This polygon fill is similar to fillTriangle(): Scan minY and maxY of all edges at each X, and draw a vertical line between (x,minY)~(x,maxY).\n// The main difference is that it sorts the endpoints of each edge, x0 < x1, to draw from left to right, but doesn't sort the edges as it's too time consuming.\n// Instead, just call next(), which returns immediately if the x is not in range of the edge in horizon.\n// NOTE: Unlike triangles, edges of a polygon can cross a vertical line at a given X multi time. This algorithm can fill correctly only if edges meet this condition: Any vertical line(x) cross edges at most 2 times.\n// Fortunately, no matter what perspective transform is applied, a rectangle/trapezoid will still meet this condition.\n// Ref: https://forum.makecode.com/t/new-3d-engine-help-filling-4-sided-polygons/18641/9\n//%\nvoid _fillPolygon4(Image_ img, pxt::RefCollection *args) {\n    fillPolygon4(\n        img,\n        pxt::toInt(args->getAt(0)),\n        pxt::toInt(args->getAt(1)),\n        pxt::toInt(args->getAt(2)),\n        pxt::toInt(args->getAt(3)),\n        pxt::toInt(args->getAt(4)),\n        pxt::toInt(args->getAt(5)),\n        pxt::toInt(args->getAt(6)),\n        pxt::toInt(args->getAt(7)),\n        pxt::toInt(args->getAt(8))\n    );\n}\n\n} // namespace ImageMethods\n\nnamespace image {\n/**\n * Create new empty (transparent) image\n */\n//%\nImage_ create(int width, int height) {\n    Image_ r = mkImage(width, height, IMAGE_BITS);\n    if (r)\n        memset(r->pix(), 0, r->pixLength());\n    else\n        target_panic(PANIC_INVALID_IMAGE);\n    return r;\n}\n\n/**\n * Create new image with given content\n */\n//%\nImage_ ofBuffer(Buffer buf) {\n    return ImageMethods::convertAndWrap(buf);\n}\n\n/**\n * Double the size of an icon\n */\n//%\nBuffer doubledIcon(Buffer icon) {\n    if (!isValidImage(icon))\n        return NULL;\n\n    auto r = NEW_GC(RefImage, icon);\n    registerGCObj(r);\n    auto t = ImageMethods::doubled(r);\n    unregisterGCObj(r);\n    return t->buffer;\n}\n\n} // namespace image\n\n// This is  6.5x faster than standard on word-aligned copy\n// probably should move to codal\n\n#ifndef __linux__\nextern \"C\" void *memcpy(void *dst, const void *src, size_t sz) {\n    void *dst0 = dst;\n    if (sz >= 4 && !((uintptr_t)dst & 3) && !((uintptr_t)src & 3)) {\n        size_t cnt = sz >> 2;\n        uint32_t *d = (uint32_t *)dst;\n        const uint32_t *s = (const uint32_t *)src;\n        while (cnt--) {\n            *d++ = *s++;\n        }\n        sz &= 3;\n        dst = d;\n        src = s;\n    }\n\n    // see comment in memset() below (have not seen optimization here, but better safe than sorry)\n    volatile uint8_t *dd = (uint8_t *)dst;\n    volatile uint8_t *ss = (uint8_t *)src;\n\n    while (sz--) {\n        *dd++ = *ss++;\n    }\n\n    return dst0;\n}\n\nextern \"C\" void *memset(void *dst, int v, size_t sz) {\n    void *dst0 = dst;\n    if (sz >= 4 && !((uintptr_t)dst & 3)) {\n        size_t cnt = sz >> 2;\n        uint32_t vv = 0x01010101 * v;\n        uint32_t *d = (uint32_t *)dst;\n        while (cnt--) {\n            *d++ = vv;\n        }\n        sz &= 3;\n        dst = d;\n    }\n\n    // without volatile here, GCC may optimize the loop to memset() call which is obviously not great\n    volatile uint8_t *dd = (uint8_t *)dst;\n\n    while (sz--) {\n        *dd++ = v;\n    }\n\n    return dst0;\n}\n#endif\n","image.d.ts":"//% fixedInstances decompileIndirectFixedInstances\ninterface Image {\n    /**\n     * Fill a rectangle\n     */\n    //% helper=imageFillRect blockNamespace=\"images\" inlineInputMode=\"inline\" group=\"Drawing\"\n    //% block=\"fill rectangle in %picture=variables_get at x %x y %y width %w height %h %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/fill-rect\n    fillRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Replace colors in a rectangle\n     */\n    //% helper=imageMapRect\n    mapRect(x: number, y: number, w: number, h: number, colorMap: Buffer): void;\n\n    /**\n     * Draw a line\n     */\n    //% helper=imageDrawLine blockNamespace=\"images\" inlineInputMode=\"inline\" group=\"Drawing\"\n    //% block=\"draw line in %picture=variables_get from x %x0 y %y0 to x %x1 y %y1 %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/draw-line\n    drawLine(x0: number, y0: number, x1: number, y1: number, c: color): void;\n\n    /**\n     * Draw an empty rectangle\n     */\n    //% helper=imageDrawRect blockNamespace=\"images\" inlineInputMode=\"inline\" group=\"Drawing\"\n    //% block=\"draw rectangle in %picture=variables_get at x %x y %y width %w height %h %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/draw-rect\n    drawRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Set pixel color\n     */\n    //% shim=ImageMethods::setPixel blockNamespace=\"images\" group=\"Drawing\"\n    //% block=\"set %picture=variables_get color at x %x y %y to %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/set-pixel\n    setPixel(x: int32, y: int32, c: int32): void;\n\n    /**\n     * Get a pixel color\n     */\n    //% shim=ImageMethods::getPixel blockNamespace=\"images\" group=\"Drawing\"\n    //% block=\"%picture=variables_get color at x %x y %y\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/get-pixel\n    getPixel(x: int32, y: int32): int32;\n\n    /**\n     * Fill entire image with a given color\n     */\n    //% shim=ImageMethods::fill blockNamespace=\"images\" group=\"Drawing\"\n    //% block=\"fill %picture=variables_get with %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/fill\n    fill(c: int32): void;\n\n    /**\n     * Return a copy of the current image\n     */\n    //% shim=ImageMethods::clone blockNamespace=\"images\" group=\"Create\"\n    //% block=\"clone %picture=variables_get\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/clone\n    clone(): Image;\n\n    /**\n     * Flips (mirrors) pixels horizontally in the current image\n     */\n    //% shim=ImageMethods::flipX blockNamespace=\"images\" group=\"Transformations\"\n    //% block=\"flip %picture=variables_get horizontally\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/flip-x\n    flipX(): void;\n\n    /**\n     * Flips (mirrors) pixels vertically in the current image\n     */\n    //% shim=ImageMethods::flipY blockNamespace=\"images\" group=\"Transformations\"\n    //% block=\"flip %picture=variables_get vertically\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/flip-y\n    flipY(): void;\n\n    /**\n     * Every pixel in image is moved by (dx,dy)\n     */\n    //% shim=ImageMethods::scroll blockNamespace=\"images\" group=\"Transformations\"\n    //% help=images/image/scroll\n    scroll(dx: int32, dy: int32): void;\n\n    /**\n     * Replaces one color in an image with another\n     */\n    //% shim=ImageMethods::replace blockNamespace=\"images\" group=\"Transformations\"\n    //% block=\"change color in %picture=variables_get from %from=colorindexpicker to %to=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/replace\n    replace(from: int32, to: int32): void;\n\n    /**\n     * Returns true if the provided image is the same as this image,\n     * otherwise returns false.\n     */\n    //% shim=ImageMethods::equals\n    //% blockNamespace=\"images\" group=\"Compare\"\n    //% block=\"$this is equal to image $other\"\n    //% this.shadow=variables_get\n    //% this.defl=\"picture\"\n    //% other.shadow=screen_image_picker\n    //% help=images/image/equals\n    equals(other: Image): boolean;\n\n    //% shim=ImageMethods::isStatic\n    isStatic(): boolean;\n\n    //% shim=ImageMethods::revision\n    revision(): number;\n\n     /**\n     * Draw given image with transparent background on the current image\n     */\n    //% shim=ImageMethods::drawTransparentImage\n    //% blockNamespace=\"images\"\n    //% blockId=image_draw_transparent_image\n    //% group=\"Drawing\"\n    //% block=\"$this draw $from at x $x y $y\"\n    //% this.shadow=variables_get\n    //% this.defl=\"picture\"\n    //% from.shadow=screen_image_picker\n    //% weight=0\n    drawTransparentImage(from: Image, x: int32, y: int32): void;\n}\n\ndeclare namespace image {\n    //% blockNamespace=\"images\"\n    //% block=\"create image width %width height %height\" group=\"Create\"\n    //% help=images/create\n    function create(width: number, height: number): Image;\n}","image.ts":"type color = number\n\nnamespace image {\n    export enum Dimension {\n        //% block=\"width\"\n        Width,\n        //% block=\"height\"\n        Height\n    }\n\n    export function repeatY(count: number, image: Image) {\n        let arr = [image]\n        while (--count > 0)\n            arr.push(image)\n        return concatY(arr)\n    }\n\n    export function concatY(images: Image[]) {\n        let w = 0\n        let h = 0\n        for (let img of images) {\n            w = Math.max(img.width, w)\n            h += img.height\n        }\n        let r = image.create(w, h)\n        let y = 0\n        for (let img of images) {\n            let x = (w - img.width) >> 1\n            r.drawImage(img, x, y)\n            y += img.height\n        }\n        return r\n    }\n\n    /**\n     * Returns the width or height of a picture.\n     *\n     * @param picture The picture to get the width or height of\n     * @param dimension The dimension to get\n     * @returns\n     */\n    //% blockId=image_get_dimension\n    //% group=\"Create\"\n    //% blockNamespace=\"images\"\n    //% block=\"$picture $dimension\"\n    //% picture.shadow=variables_get\n    //% picture.defl=picture\n    export function getDimension(picture: Image, dimension: Dimension) {\n        if (dimension === Dimension.Width) return picture.width;\n        else return picture.height;\n    }\n}\n\n\n//% snippet='img` `'\n//% pySnippet='img(\"\"\" \"\"\")'\n//% fixedInstances\ninterface Image {\n    /**\n     * Draw an icon (monochromatic image) using given color\n     */\n    //% helper=imageDrawIcon\n    drawIcon(icon: Buffer, x: number, y: number, c: color): void;\n\n    /**\n     * Fill a rectangle\n     */\n    //% helper=imageFillRect\n    fillRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Draw a line\n     */\n    //% helper=imageDrawLine\n    drawLine(x0: number, y0: number, x1: number, y1: number, c: color): void;\n\n    /**\n     * Draw an empty rectangle\n     */\n    //% helper=imageDrawRect\n    drawRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Draw a circle\n     */\n    //% helper=imageDrawCircle\n    drawCircle(cx: number, cy: number, r: number, c: color): void;\n\n    /**\n     * Fills a circle\n     */\n    //% helper=imageFillCircle\n    fillCircle(cx: number, cy: number, r: number, c: color): void;\n\n    /**\n     * Fills a triangle\n     */\n    //% helper=imageFillTriangle\n    fillTriangle(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, col: number): void;\n\n    /**\n     * Fills a 4-side-polygon\n     */\n    //% helper=imageFillPolygon4\n    fillPolygon4(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, col: number): void;\n\n    /**\n     * Returns an image rotated by -90, 90, -180, 180, -270, 270 deg clockwise\n     */\n    //% helper=imageRotated\n    rotated(deg: number): Image;\n\n    /**\n     * Scale and copy a row of pixels from a texture.\n     */\n    //% helper=imageBlitRow\n    blitRow(dstX: number, dstY: number, from: Image, fromX: number, fromH: number): void;\n\n    /**\n     * Copy an image from a source rectangle to a destination rectangle, stretching or\n     * compressing to fit the dimensions of the destination rectangle, if necessary.\n     */\n    //% helper=imageBlit\n    blit(xDst: number, yDst: number, wDst: number, hDst: number, src: Image, xSrc: number, ySrc: number, wSrc: number, hSrc: number, transparent: boolean, check: boolean): boolean;\n}\n\ninterface ScreenImage extends Image {\n    /**\n     * Sets the screen backlight brightness (10-100)\n     */\n    //% helper=setScreenBrightness\n    setBrightness(deg: number): Image;\n\n    /**\n     * Gets current screen backlight brightness (0-100)\n     */\n    //% helper=screenBrightness\n    brightness(): number;\n}\n\n// pxt compiler currently crashes on non-functions in helpers namespace; will fix\nnamespace _helpers_workaround {\n    export let brightness = 100\n}\n\nnamespace helpers {\n    //% shim=ImageMethods::_drawLine\n    function _drawLine(img: Image, xy: number, wh: number, c: color): void { }\n\n    //% shim=ImageMethods::_fillRect\n    function _fillRect(img: Image, xy: number, wh: number, c: color): void { }\n\n    //% shim=ImageMethods::_mapRect\n    function _mapRect(img: Image, xy: number, wh: number, m: Buffer): void { }\n\n    //% shim=ImageMethods::_drawIcon\n    function _drawIcon(img: Image, icon: Buffer, xy: number, c: color): void { }\n\n    //% shim=ImageMethods::_fillCircle\n    declare function _fillCircle(img: Image, cxy: number, r: number, c: color): void;\n\n    //% shim=ImageMethods::_blitRow\n    declare function _blitRow(img: Image, xy: number, from: Image, xh: number): void;\n\n    //% shim=ImageMethods::_blit\n    declare function _blit(img: Image, src: Image, args: number[]): boolean;\n\n    //% shim=ImageMethods::_fillTriangle\n    declare function _fillTriangle(img: Image, args: number[]): void;\n\n    //% shim=ImageMethods::_fillPolygon4\n    declare function _fillPolygon4(img: Image, args: number[]): void;\n\n    function pack(x: number, y: number) {\n        return (Math.clamp(-30000, 30000, x | 0) & 0xffff) | (Math.clamp(-30000, 30000, y | 0) << 16)\n    }\n\n    let _blitArgs: number[];\n\n    export function imageBlit(img: Image, xDst: number, yDst: number, wDst: number, hDst: number, src: Image, xSrc: number, ySrc: number, wSrc: number, hSrc: number, transparent: boolean, check: boolean): boolean {\n        _blitArgs = _blitArgs || [];\n        _blitArgs[0] = xDst | 0;\n        _blitArgs[1] = yDst | 0;\n        _blitArgs[2] = wDst | 0;\n        _blitArgs[3] = hDst | 0;\n        _blitArgs[4] = xSrc | 0;\n        _blitArgs[5] = ySrc | 0;\n        _blitArgs[6] = wSrc | 0;\n        _blitArgs[7] = hSrc | 0;\n        _blitArgs[8] = transparent ? 1 : 0;\n        _blitArgs[9] = check ? 1 : 0;\n        return _blit(img, src, _blitArgs);\n    }\n\n    export function imageBlitRow(img: Image, dstX: number, dstY: number, from: Image, fromX: number, fromH: number): void {\n        _blitRow(img, pack(dstX, dstY), from, pack(fromX, fromH))\n    }\n\n    export function imageDrawIcon(img: Image, icon: Buffer, x: number, y: number, c: color): void {\n        _drawIcon(img, icon, pack(x, y), c)\n    }\n    export function imageFillRect(img: Image, x: number, y: number, w: number, h: number, c: color): void {\n        _fillRect(img, pack(x, y), pack(w, h), c)\n    }\n    export function imageMapRect(img: Image, x: number, y: number, w: number, h: number, m: Buffer): void {\n        _mapRect(img, pack(x, y), pack(w, h), m)\n    }\n    export function imageDrawLine(img: Image, x: number, y: number, w: number, h: number, c: color): void {\n        _drawLine(img, pack(x, y), pack(w, h), c)\n    }\n    export function imageDrawRect(img: Image, x: number, y: number, w: number, h: number, c: color): void {\n        if (w == 0 || h == 0) return\n        w--\n        h--\n        imageDrawLine(img, x, y, x + w, y, c)\n        imageDrawLine(img, x, y, x, y + h, c)\n        imageDrawLine(img, x + w, y + h, x + w, y, c)\n        imageDrawLine(img, x + w, y + h, x, y + h, c)\n    }\n\n    export function imageDrawCircle(img: Image, cx: number, cy: number, r: number, col: number) {\n        cx = cx | 0;\n        cy = cy | 0;\n        r = r | 0;\n        // short cuts\n        if (r < 0)\n            return;\n\n        // Bresenham's algorithm\n        let x = 0\n        let y = r\n        let d = 3 - 2 * r\n\n        while (y >= x) {\n            img.setPixel(cx + x, cy + y, col)\n            img.setPixel(cx - x, cy + y, col)\n            img.setPixel(cx + x, cy - y, col)\n            img.setPixel(cx - x, cy - y, col)\n            img.setPixel(cx + y, cy + x, col)\n            img.setPixel(cx - y, cy + x, col)\n            img.setPixel(cx + y, cy - x, col)\n            img.setPixel(cx - y, cy - x, col)\n            x++\n            if (d > 0) {\n                y--\n                d += 4 * (x - y) + 10\n            } else {\n                d += 4 * x + 6\n            }\n        }\n    }\n\n    export function imageFillCircle(img: Image, cx: number, cy: number, r: number, col: number) {\n        _fillCircle(img, pack(cx, cy), r, col);\n    }\n\n    export function imageFillTriangle(img: Image, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, col: number) {\n        _blitArgs = _blitArgs || [];\n        _blitArgs[0] = x0;\n        _blitArgs[1] = y0;\n        _blitArgs[2] = x1;\n        _blitArgs[3] = y1;\n        _blitArgs[4] = x2;\n        _blitArgs[5] = y2;\n        _blitArgs[6] = col;\n        _fillTriangle(img, _blitArgs);\n    }\n\n    export function imageFillPolygon4(img: Image, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, col: number) {\n        _blitArgs = _blitArgs || [];\n        _blitArgs[0] = x0;\n        _blitArgs[1] = y0;\n        _blitArgs[2] = x1;\n        _blitArgs[3] = y1;\n        _blitArgs[4] = x2;\n        _blitArgs[5] = y2;\n        _blitArgs[6] = x3;\n        _blitArgs[7] = y3;\n        _blitArgs[8] = col;\n        _fillPolygon4(img, _blitArgs);\n    }\n\n    /**\n     * Returns an image rotated by 90, 180, 270 deg clockwise\n     */\n    export function imageRotated(img: Image, deg: number) {\n        if (deg == -90 || deg == 270) {\n            let r = img.transposed();\n            r.flipY();\n            return r;\n        } else if (deg == 180 || deg == -180) {\n            let r = img.clone();\n            r.flipX();\n            r.flipY();\n            return r;\n        } else if (deg == 90 || deg == -270) {\n            let r = img.transposed();\n            r.flipX();\n            return r;\n        } else {\n            return null;\n        }\n    }\n\n    //% shim=pxt::setScreenBrightness\n    function _setScreenBrightness(brightness: number) { }\n\n    export function setScreenBrightness(img: Image, b: number) {\n        b = Math.clamp(10, 100, b | 0);\n        _helpers_workaround.brightness = b\n        _setScreenBrightness(_helpers_workaround.brightness)\n    }\n\n    export function screenBrightness(img: Image) {\n        return _helpers_workaround.brightness\n    }\n}\n","imagesoverrides.jres":"{\n  \n}","imagesoverrides.ts":"// replace with built-in images","ns.ts":" ","panic.cpp":"// potentially overriden in targets","pxt.json":"{\n    \"name\": \"screen---linux\",\n    \"description\": \"The screen library\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"screen.cpp\",\n        \"panic.cpp\",\n        \"image.cpp\",\n        \"image.ts\",\n        \"screenimage.ts\",\n        \"text.ts\",\n        \"frame.ts\",\n        \"shims.d.ts\",\n        \"fieldeditors.ts\",\n        \"targetoverrides.ts\",\n        \"ns.ts\",\n        \"image.d.ts\",\n        \"pxtparts.json\",\n        \"imagesoverrides.jres\",\n        \"imagesoverrides.ts\",\n        \"font12.jres\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","pxtparts.json":"{\n  \"screen\": {\n    \"simulationBehavior\": \"screen\",\n    \"visual\": {\n      \"builtIn\": \"screen\",\n      \"width\": 158.43856811523438,\n      \"height\": 146.8025665283203,\n      \"pinDistance\": 14.91,\n      \"pinLocations\": [\n        {\n          \"x\": 4.227952701380444,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 18.170226805137037,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 46.05478386015504,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 59.99706238766404,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 73.93934976267785,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 87.88161944268204,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 101.82389797019104,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 32.11250533264604,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 117.68761950246274,\n          \"y\": 3.1650031792503945\n        }\n      ]\n    },\n    \"numberOfPins\": 9,\n    \"instantiation\": {\n      \"kind\": \"singleton\"\n    },\n    \"pinDefinitions\": [\n      {\n        \"target\": \"ground\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"threeVolt\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_DC\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_CS\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_MOSI\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_SCK\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_MISO\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_RST\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"threeVolt\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      }\n    ],\n    \"assembly\": [\n      {\n        \"pinIndices\": [\n          0,\n          1,\n          2,\n          3,\n          4,\n          5,\n          6,\n          7,\n          8\n        ]\n      }\n    ]\n  }\n}","screen.cpp":"#include \"pxt.h\"\n#include \"pins.h\"\n\n#include <stdlib.h>\n#include <unistd.h>\n#include <stdio.h>\n#include <fcntl.h>\n#include <linux/fb.h>\n#include <linux/kd.h>\n#include <sys/mman.h>\n#include <sys/ioctl.h>\n#include <pthread.h>\n\nnamespace pxt {\nclass WDisplay {\n  public:\n    uint32_t currPalette[16];\n    bool newPalette;\n    volatile bool painted;\n    volatile bool dirty;\n\n    uint8_t *screenBuf;\n    Image_ lastImg;\n\n    int width, height;\n\n    int fb_fd;\n    uint32_t *fbuf;\n    struct fb_fix_screeninfo finfo;\n    struct fb_var_screeninfo vinfo;\n\n    int eventId;\n\n    int is32Bit;\n\n    pthread_mutex_t mutex;\n\n    WDisplay();\n    void updateLoop();\n    void update(Image_ img);\n};\n\nSINGLETON(WDisplay);\n\nstatic void *updateDisplay(void *wd) {\n    ((WDisplay *)wd)->updateLoop();\n    return NULL;\n}\n\nvoid WDisplay::updateLoop() {\n    int cur_page = 1;\n    int frameNo = 0;\n    int numPages = vinfo.yres_virtual / vinfo.yres;\n    int ledScreen = getConfigInt(\"LED_SCREEN\", 0);\n\n    int sx = vinfo.xres / width;\n    int sy = vinfo.yres / height;\n\n    if (ledScreen)\n        sx = ledScreen;\n\n    if (sx > sy)\n        sx = sy;\n    else\n        sy = sx;\n\n    if (sx > 1)\n        sx &= ~1;\n\n    int offx = (vinfo.xres - width * sx) / 2;\n    int offy = (vinfo.yres - height * sy) / 2;\n\n    if (ledScreen) {\n        offx = getConfigInt(\"LED_SCREEN_X\", 0);\n        offy = getConfigInt(\"LED_SCREEN_Y\", 0);\n    }\n\n    int screensize = finfo.line_length * vinfo.yres;\n    uint32_t skip = offx;\n\n    if (sx > 1)\n        offx &= ~1;\n\n    DMESG(\"sx=%d sy=%d ox=%d oy=%d 32=%d\", sx, sy, offx, offy, is32Bit);\n    DMESG(\"fbuf=%p sz:%d\", fbuf, screensize);\n    memset(fbuf, 0x00, screensize * numPages);\n\n    if (numPages == 1)\n        cur_page = 0;\n\n    dirty = true;\n\n    DMESG(\"loop\");\n\n    for (;;) {\n        auto start0 = current_time_us();\n\n        while (!dirty)\n            sleep_core_us(2000);\n\n        // auto start = current_time_us();\n        // DMESG(\"update\");\n\n        pthread_mutex_lock(&mutex);\n        dirty = false;\n\n        if (!is32Bit) {\n            uint16_t *dst =\n                (uint16_t *)fbuf + cur_page * screensize / 2 + offx + offy * finfo.line_length / 2;\n            if (sx == 1 && sy == 1) {\n                skip = vinfo.xres - width * sx;\n                for (int yy = 0; yy < height; yy++) {\n                    auto shift = yy & 1 ? 4 : 0;\n                    auto src = screenBuf + yy / 2;\n                    for (int xx = 0; xx < width; ++xx) {\n                        int c = this->currPalette[(*src >> shift) & 0xf];\n                        src += height / 2;\n                        *dst++ = c;\n                    }\n                    dst += skip;\n                }\n            } else {\n                uint32_t *d2 = (uint32_t *)dst;\n                for (int yy = 0; yy < height; yy++) {\n                    auto shift = yy & 1 ? 4 : 0;\n                    for (int i = 0; i < sy; ++i) {\n                        auto src = screenBuf + yy / 2;\n                        for (int xx = 0; xx < width; ++xx) {\n                            int c = this->currPalette[(*src >> shift) & 0xf];\n                            src += height / 2;\n                            for (int j = 0; j < sx / 2; ++j)\n                                *d2++ = c;\n                        }\n                        d2 += skip;\n                    }\n                }\n            }\n        } else {\n            uint32_t *d2 =\n                (uint32_t *)fbuf + cur_page * screensize / 4 + offx + offy * finfo.line_length / 4;\n            skip = vinfo.xres - width * sx;\n            for (int yy = 0; yy < height; yy++) {\n                auto shift = yy & 1 ? 4 : 0;\n                for (int i = 0; i < sy; ++i) {\n                    auto src = screenBuf + yy / 2;\n                    for (int xx = 0; xx < width; ++xx) {\n                        int c = this->currPalette[(*src >> shift) & 0xf];\n                        src += height / 2;\n                        for (int j = 0; j < sx; ++j)\n                            *d2++ = c;\n                    }\n                    d2 += skip;\n                }\n            }\n        }\n\n        pthread_mutex_unlock(&mutex);\n\n        // auto len = current_time_us() - start;\n\n        painted = true;\n        raiseEvent(DEVICE_ID_NOTIFY_ONE, eventId);\n\n        vinfo.yoffset = cur_page * vinfo.yres;\n        ioctl(fb_fd, FBIOPAN_DISPLAY, &vinfo);\n        ioctl(fb_fd, FBIO_WAITFORVSYNC, 0);\n        if (numPages > 1)\n            cur_page = !cur_page;\n        frameNo++;\n\n        auto fulllen = current_time_us() - start0;\n        // throttle it to 40fps (really 30fps)\n        if (fulllen < 25000) {\n            ioctl(fb_fd, FBIO_WAITFORVSYNC, 0);\n        }\n\n        // auto tot = current_time_us() - start;\n        // if (frameNo % 37 == 0)\n        //    DMESG(\"copy %d us, tot %d us delay %d us\",  (int)len, (int)tot, (int)(start-start0));\n    }\n}\n\nWDisplay::WDisplay() {\n    pthread_mutex_init(&mutex, NULL);\n\n    width = getConfig(CFG_DISPLAY_WIDTH, 160);\n    height = getConfig(CFG_DISPLAY_HEIGHT, 128);\n    screenBuf = new uint8_t[width * height / 2 + 20];\n    lastImg = NULL;\n    newPalette = false;\n\n    registerGC((TValue *)&lastImg);\n\n    eventId = allocateNotifyEvent();\n\n    int tty_fd = open(\"/dev/tty0\", O_RDWR);\n    ioctl(tty_fd, KDSETMODE, KD_GRAPHICS);\n\n    fb_fd = open(\"/dev/fb0\", O_RDWR);\n\n    if (fb_fd < 0)\n        target_panic(PANIC_SCREEN_ERROR);\n\n    ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo);\n    ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo);\n\n    DMESG(\"FB: %s at %dx%d %dx%d bpp=%d\", finfo.id, vinfo.xres, vinfo.yres, vinfo.xres_virtual,\n          vinfo.yres_virtual, vinfo.bits_per_pixel);\n\n    vinfo.yres_virtual = vinfo.yres * 2;\n    vinfo.xres_virtual = vinfo.xres;\n\n    if (vinfo.bits_per_pixel == 32) {\n        is32Bit = true;\n    } else {\n        vinfo.bits_per_pixel = 16;\n        is32Bit = false;\n    }\n\n    ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vinfo);\n    ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo);\n    ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo);\n\n    DMESG(\"FB: %s at %dx%d %dx%d bpp=%d %d\", finfo.id, vinfo.xres, vinfo.yres, vinfo.xres_virtual,\n          vinfo.yres_virtual, vinfo.bits_per_pixel, finfo.line_length);\n\n    fbuf = (uint32_t *)mmap(0, finfo.line_length * vinfo.yres_virtual, PROT_READ | PROT_WRITE,\n                            MAP_SHARED, fb_fd, (off_t)0);\n\n    pthread_t upd;\n    pthread_create(&upd, NULL, updateDisplay, this);\n    pthread_detach(upd);\n}\n\n//%\nint setScreenBrightnessSupported() {\n    return 0;\n}\n\n//%\nvoid setScreenBrightness(int level) {\n    // TODO\n}\n\n//%\nvoid setPalette(Buffer buf) {\n    auto display = getWDisplay();\n    if (48 != buf->length)\n        target_panic(PANIC_SCREEN_ERROR);\n    for (int i = 0; i < 16; ++i) {\n        uint8_t r = buf->data[i * 3];\n        uint8_t g = buf->data[i * 3 + 1];\n        uint8_t b = buf->data[i * 3 + 2];\n        if (display->is32Bit) {\n            display->currPalette[i] = (r << 16) | (g << 8) | (b << 0);\n        } else {\n            r >>= 3;\n            g >>= 2;\n            b >>= 3;\n            uint16_t cc = (r << 11) | (g << 5) | (b << 0);\n            display->currPalette[i] = (cc << 16) | cc;\n        }\n    }\n    display->newPalette = true;\n}\n\nvoid WDisplay::update(Image_ img) {\n    if (img && img != lastImg) {\n        lastImg = img;\n    }\n    img = lastImg;\n\n    if (img) {\n        if (img->bpp() != 4 || img->width() != width || img->height() != height)\n            target_panic(PANIC_SCREEN_ERROR);\n\n        if (!painted) {\n            // race is possible (though very unlikely), but in such case we just\n            // wait for next frame paint\n            waitForEvent(DEVICE_ID_NOTIFY, eventId);\n        }\n        painted = false;\n\n        pthread_mutex_lock(&mutex);\n        dirty = true;\n        if (newPalette) {\n            newPalette = false;\n        }\n        memcpy(screenBuf, img->pix(), img->pixLength());\n        pthread_mutex_unlock(&mutex);\n    }\n}\n\n//%\nvoid updateScreen(Image_ img) {\n    getWDisplay()->update(img);\n}\n\n//%\nvoid updateStats(String msg) {\n    // DMESG(\"render: %s\", msg->data);\n}\n} // namespace pxt","screenimage.ts":"\nnamespace image {\n    /**\n    * Get the screen image\n    */\n    //% blockNamespace=\"images\" group=\"Create\"\n    //% blockId=imagescreen block=\"screen\"\n    //% help=images/screen-image\n    export function screenImage(): Image {\n        return screen;\n    }\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\n\n\ndeclare interface Image {\n    /**\n     * Get the width of the image\n     */\n    //% property shim=ImageMethods::width\n    width: int32;\n\n    /**\n     * Get the height of the image\n     */\n    //% property shim=ImageMethods::height\n    height: int32;\n\n    /**\n     * True if the image is monochromatic (black and white)\n     */\n    //% property shim=ImageMethods::isMono\n    isMono: boolean;\n\n    /**\n     * Sets all pixels in the current image from the other image, which has to be of the same size and\n     * bpp.\n     */\n    //% shim=ImageMethods::copyFrom\n    copyFrom(from: Image): void;\n\n    /**\n     * Set pixel color\n     */\n    //% shim=ImageMethods::setPixel\n    setPixel(x: int32, y: int32, c: int32): void;\n\n    /**\n     * Get a pixel color\n     */\n    //% shim=ImageMethods::getPixel\n    getPixel(x: int32, y: int32): int32;\n\n    /**\n     * Fill entire image with a given color\n     */\n    //% shim=ImageMethods::fill\n    fill(c: int32): void;\n\n    /**\n     * Copy row(s) of pixel from image to buffer (8 bit per pixel).\n     */\n    //% shim=ImageMethods::getRows\n    getRows(x: int32, dst: Buffer): void;\n\n    /**\n     * Copy row(s) of pixel from buffer to image.\n     */\n    //% shim=ImageMethods::setRows\n    setRows(x: int32, src: Buffer): void;\n\n    /**\n     * Return a copy of the current image\n     */\n    //% shim=ImageMethods::clone\n    clone(): Image;\n\n    /**\n     * Flips (mirrors) pixels horizontally in the current image\n     */\n    //% shim=ImageMethods::flipX\n    flipX(): void;\n\n    /**\n     * Flips (mirrors) pixels vertically in the current image\n     */\n    //% shim=ImageMethods::flipY\n    flipY(): void;\n\n    /**\n     * Returns a transposed image (with X/Y swapped)\n     */\n    //% shim=ImageMethods::transposed\n    transposed(): Image;\n\n    /**\n     * Every pixel in image is moved by (dx,dy)\n     */\n    //% shim=ImageMethods::scroll\n    scroll(dx: int32, dy: int32): void;\n\n    /**\n     * Stretches the image horizontally by 100%\n     */\n    //% shim=ImageMethods::doubledX\n    doubledX(): Image;\n\n    /**\n     * Stretches the image vertically by 100%\n     */\n    //% shim=ImageMethods::doubledY\n    doubledY(): Image;\n\n    /**\n     * Replaces one color in an image with another\n     */\n    //% shim=ImageMethods::replace\n    replace(from: int32, to: int32): void;\n\n    /**\n     * Stretches the image in both directions by 100%\n     */\n    //% shim=ImageMethods::doubled\n    doubled(): Image;\n\n    /**\n     * Draw given image on the current image\n     */\n    //% shim=ImageMethods::drawImage\n    drawImage(from: Image, x: int32, y: int32): void;\n\n    /**\n     * Draw given image with transparent background on the current image\n     */\n    //% shim=ImageMethods::drawTransparentImage\n    drawTransparentImage(from: Image, x: int32, y: int32): void;\n\n    /**\n     * Check if the current image \"collides\" with another\n     */\n    //% shim=ImageMethods::overlapsWith\n    overlapsWith(other: Image, x: int32, y: int32): boolean;\n}\ndeclare namespace image {\n\n    /**\n     * Create new empty (transparent) image\n     */\n    //% shim=image::create\n    function create(width: int32, height: int32): Image;\n\n    /**\n     * Create new image with given content\n     */\n    //% shim=image::ofBuffer\n    function ofBuffer(buf: Buffer): Image;\n\n    /**\n     * Double the size of an icon\n     */\n    //% shim=image::doubledIcon\n    function doubledIcon(icon: Buffer): Buffer;\n}\n\n// Auto-generated. Do not edit. Really.\n","targetoverrides.ts":"/**\n * Tagged image literal converter\n */\n//% shim=@f4 helper=image::ofBuffer blockIdentity=\"images._spriteImage\"\n//% groups=[\"0.\",\"1#\",\"2T\",\"3t\",\"4N\",\"5n\",\"6G\",\"7g\",\"8\",\"9\",\"aAR\",\"bBP\",\"cCp\",\"dDO\",\"eEY\",\"fFW\"]\nfunction img(lits: any, ...args: any[]): Image { return null }\n\n// set palette before creating screen, so the JS version has the right BPP\nimage.setPalette(hex`__palette`)\nlet screen = image.create(_screen_internal.getScreenWidth(160), _screen_internal.getScreenHeight(120)) as ScreenImage\n\nnamespace image {\n    //% shim=pxt::setPalette\n    export function setPalette(buf: Buffer) { }\n}\n\nnamespace _screen_internal {\n    //% shim=pxt::updateScreen\n    function updateScreen(img: Image): void { }\n    //% shim=pxt::updateStats\n    function updateStats(msg: string): void { }\n\n    //% shim=TD_ID\n    export function getScreenWidth(defl: number) {\n        return control.getConfigValue(DAL.CFG_ARCADE_SCREEN_WIDTH, defl)\n    }\n\n    //% shim=TD_ID\n    export function getScreenHeight(defl: number) {\n        return control.getConfigValue(DAL.CFG_ARCADE_SCREEN_HEIGHT, defl)\n    }\n\n    control.__screen.setupUpdate(() => updateScreen(screen))\n    control.EventContext.onStats = function (msg: string) {\n        updateStats(msg);\n    }\n}\n","text.ts":"namespace image {\n\n    export interface Font {\n        charWidth: number;\n        charHeight: number;\n        data: Buffer;\n        multiplier?: number;\n    }\n\n    //% whenUsed\n    export const font8: Font = {\n        charWidth: 6,\n        charHeight: 8,\n        data: hex`\n2000000000000000 210000005e000000 2200000e000e0000 230028fe28fe2800 24004c92ff926400 250002651248a640\n26006c92926ca000 270000000e000000 280000007c820000 29000000827c0000 2a00543810385400 2b0010107c101000\n2c00000090700000 2d00101010101000 2e00000060600000 2f00006010080600 3000003c42423c00 310000447e400000\n3200004462524c00 330000424a4e3200 34003028247e2000 3500004e4a4a3200 3600003c4a4a3000 3700000262120e00\n380000344a4a3400 3900000c52523c00 3a0000006c6c0000 3b00000096760000 3c00102828444400 3d00282828282800\n3e00444428281000 3f00000259090600 40003c425a560800 4100781412147800 42007e4a4a4a3400 4300003c42422400\n4400007e42423c00 4500007e4a4a4200 4600007e0a0a0200 4700003c42523400 4800007e08087e00 490000427e420000\n4a002040423e0200 4b00007e08146200 4c00007e40404000 4d007e0418047e00 4e00007e04087e00 4f003c4242423c00\n5000007e12120c00 5100003c5262bc00 5200007e12126c00 530000244a522400 540002027e020200 5500003e40403e00\n5600001e70701e00 57007e2018207e00 5800422418244200 5900060870080600 5a000062524a4600 5b00007e42420000\n5c00000608106000 5d000042427e0000 5e00080402040800 5f00808080808000 6000000002040000 6100003048487800\n6200007e48483000 6300003048484800 6400003048487e00 6500003068585000 660000107c120400 67000018a4a47800\n6800007e08087000 690000487a400000 6a000040847d0000 6b00007e10284000 6c0000427e400000 6d00780830087000\n6e00007808087000 6f00003048483000 700000fc24241800 710000182424fc00 7200007810081000 7300005058682800\n740000083e482000 7500003840407800 7600001860601800 7700384030403800 7800004830304800 7900005ca0a07c00\n7a00004868584800 7b00000836410000 7c000000fe000000 7d00004136080000 7e00000804080400 a000000000000000\na10000007a000000 a200003048fc4800 a30090fc92928400 a400542844285400 a5002a2c782c2a00 a6000000ee000000\na7000094aaaa5200 a800000200020000 a9003e414955413e aa0000242a2e0000 ab00102854284400 ac00001010107000\nad00001010101000 ae003e415d45413e af00000202020200 b000000814140800 b1008888be888800 b2000024322c0000\nb30000222a140000 b400000004020000 b50000f840207800 b6000c1e7e027e00 b700000010000000 b800000080400000\nb90000243e200000 ba0000242a240000 bb00442854281000 bc00025f70f84000 bd00021f90c8b000 be0011557af84000\nbf000030484d2000 c000601916186000 c100601816196000 c200601a151a6000 c300601a151a6100 c400601914196000\nc500601a151a6000 c6007c0a7e4a4200 c700001ea1611200 c800007c55564400 c900007c56554400 ca00007c56554600\ncb00007c55544500 cc0000457e440000 cd0000447e450000 ce0000467d460000 cf0000457c450000 d000087e4a423c00\nd100007e09127d00 d200003845463800 d300003846453800 d400003846453a00 d500003a45463900 d600003845443900\nd700442810284400 d80000fc724e3f00 d900003c41423c00 da00003c42413c00 db00003c42413e00 dc00003c41403d00\ndd00040872090400 de00007e24241800 df00007c025a2400 e0000030494a7800 e10000304a497800 e20000304a497a00\ne3000032494a7900 e40000304a487a00 e50000304a4d7a00 e600304878685000 e7000018a4642400 e8000030695a5000\ne90000306a595000 ea0000306a595200 eb0000306a585200 ec0000497a400000 ed0000487a410000 ee00004a79420000\nef00004a78420000 f00000304a4b3d00 f100007a090a7100 f2000030494a3000 f30000304a493000 f40000304a493200\nf5000032494a3100 f60000304a483200 f700101054101000 f800007068583800 f900003841427800 fa00003842417800\nfb00003842417a00 fc00003842407a00 fd0000b84241f800 fe0000ff24241800 ff00005ca1a07d00 0001601915196000\n010100304a4a7a00 0201611a16196000 030100314a4a7900 04013c0a094abc00 050100182464bc00 0601003846452800\n070100304a494800 0801003846452a00 090100304a494a00 0a01003844452800 0b010030484a4800 0c01003845462900\n0d010030494a4900 0e01007c45463900 0f0100314a497e00 1001087e4a423c00 110130484c7e0400 1201007d55554500\n130100326a5a5200 1401007d56564500 150100316a5a5100 1601007c55544400 170100306a585000 1801003f65a52100\n1901001874ac2800 1a01007c55564500 1b010030695a5100 1c01003846553600 1d0100304a49f200 1e01003946563500\n1f0100314a4af100 2001003844553400 21010018a4a57800 2201001ea1691a00 23010018a6a57800 2401007812117a00\n25017e080a710200 2601047e147e0400 2701047e0c087000 28010002457e4500 29010002497a4100 2a0100457d450000\n2b01004a7a420000 2c0100014a7a4900 2d0100014a7a4100 2e0100217fa10000 2f0100247da00000 300100447d440000\n3101004878400000 32017e0022423e00 33013d0040847d00 34012040463d0600 350100800af90200 360100bf440a3100\n370100bf48142000 3801007810284800 3901007c40424100 3a0100467d400000 3b01003fa0602000 3c0100a17f200000\n3d01007c41424100 3e0100457e410000 3f01007e40484000 400100427e400800 4101107e48404000 420100527e480000\n4301007c0a117c00 440100780a097000 450100bf42043f00 460100bc44043800 4701007c09127d00 480100790a097000\n49010a0678087000 4a01003f02847f00 4b01003c04847800 4c01394545453900 4d0100324a4a3200 4e01394646463900\n4f0100314a4a3100 50013a4544463900 5101324948320100 52013c427e4a4200 5301304830685000 5401007c16354800\n5501007812091000 560100bf49093600 570100bc48040800 5801007d16354800 5901007912091000 5a01004856552400\n5b0100505a692800 5c01004856552600 5d0100505a692a00 5e010012a5691200 5f010028ac741400 6001004855562500\n61010050596a2900 62010101bf410100 630100049f641000 640104057e050400 650100083d4a2100 660102127e120200\n670100183e582000 6801003a41423900 6901003a41427900 6a01003d41413d00 6b01003a42427a00 6c01003942423900\n6d01003942427900 6e01003a45453a00 6f01003a45457a00 70013a41403a0100 71013a41407a0100 7201001f60a01f00\n7301001c60a03c00 7401782211227800 7501384231423800 7601081261120800 770100b84241fa00 7801040970090400\n79010064564d4400 7a0100486a594800 7b010064544d4400 7c010048685a4800 7d010064554e4500 7e010048695a4900\n7f0100087c020400 8f01003452523c00 920100887e090200 a0013c42423c0806 a101003048483008 af01003e403e0806\nb001003840781008 b501006a5a4a4e00 b601005878585800 d101003845463900 d2010030494a3100 e601003845563500\ne7010030494af100 fa0100742a750000 fb0100304c4a7d00 fc0178147e554400 fd0130487a695000 fe010078744e3d00\nff0100706a593800 18020012a5691200 19020028ac741400 1a020101bf410100 1b0200049f641000 bb0200000c0a0000\nbc0200000a060000 bd020000060a0000 c602000201020000 c702000102010000 c902000202020000 d802000102020100\nd902000002000000 da02000205020000 db02000040800000 dc02000201020100 dd02020100020100 7403000002010000\n7503000080400000 7a030000c0800000 7e03000096760000 8403000003000000 8503020003000200 8603037c12127c00\n8703000010000000 880303007e4a4200 890303007e087e00 8a030300427e4200 8c03033c42423c00 8e0303000e700e00\n8f03035c62625c00 900302003b400200 9103781412147800 92037e4a4a4a3400 9303007e02020200 9403605846586000\n9503007e4a4a4200 96030062524a4600 9703007e08087e00 98033c4a4a4a3c00 990300427e420000 9a03007e08146200\n9b03601806186000 9c037e0418047e00 9d03007e04087e00 9e0300424a4a4200 9f033c4242423c00 a003007e02027e00\na103007e12120c00 a30300665a424200 a40302027e020200 a503060870080600 a60318247e241800 a703422418244200\na8030e107e100e00 a9035c6202625c00 aa0300457c450000 ab03040970090400 ac030030484a7900 ad030030685a5100\nae0378100a09f000 af03003a41200000 b0033a4043403a00 b103003048487800 b20300fe25251a00 b3030c30c0300c00\nb403344a4a4a3000 b503003068585000 b603021aa6a24200 b7033c080404f800 b803003c4a4a3c00 b903003840200000\nba03007820504800 bb03641212227c00 bc03fc2020103c00 bd03182040201800 be03112d2ba94100 bf03003048483000\nc003087808780800 c103f82424241800 c2031824a4a44800 c303304848582800 c403000838482800 c503384040403800\nc6031c20f8241800 c703c4281028c400 c8031c20fc201c00 c903304820483000 ca03000238422000 cb03384240423800\ncc0330484a493000 cd03384042413800 ce03304822493000 d0033c52525c2000 d10310344a3c0800 d203067804020400\nd303120a7c020400 d4030d7009040800 d5031824ff241800 d603384828483800 d70348302221d800 da031c2221a14200\ndb031824a4a44200 dc037e1212020200 dd0300fc24240400 de033e2010087c00 df030c0ac9281800 e003700c621c7000\ne10301092516f800 e2039ea0bea07e00 e30398a0b8a07800 e4030c1214107e00 e503001028207800 e603be9088887000\ne70348544e443800 e803245252524c00 e903285454544800 ea0364524c526400 eb03086458640800 ec03385454542200\ned03306848682400 ee03184a7e4a1800 ef031848ff0a0800 f003483020205800 f10378a4a4a49800 f203304848485000\nf303006080847d00 f4033c4a4a4a3c00 f503003058584800 0004007c55564400 0104007c55544500 020401013f857900\n0304007c06050400 04043c4a4a422400 050400244a522400 060400427e420000 070400457c450000 08042040423e0200\n09047c027e483000 0a047e087e483000 0b0402027e0a7200 0c04007c102a4500 0d047c2112087c00 0e040c5152523d00\n0f043f20e0203f00 1004781412147800 11047e4a4a4a3000 12047e4a4a4a3400 1304007e02020200 1404c07c427ec000\n1504007e4a4a4200 160476087e087600 170424424a4a3400 1804007e08047e00 1904007d120a7d00 1a04007e08146200\n1b04403c02027e00 1c047e0418047e00 1d04007e08087e00 1e043c4242423c00 1f047e0202027e00 2004007e12120c00\n2104003c42422400 220402027e020200 23040e5050503e00 240418247e241800 2504422418244200 26043f2020bf6000\n27040e1010107e00 28047e407e407e00 29043f203fa07f00 2a04027e48483000 2b047e4848307e00 2c04007e48483000\n2d0424424a4a3c00 2e047e183c423c00 2f04006c12127e00 3004304848784000 3104003c4a4a3100 3204007868502000\n3304007808080800 3404c0704878c000 3504306868500000 3604483078304800 3704004058683000 3804784020107800\n3904794222127900 3a04007820304800 3b04403008087800 3c04781020107800 3d04781010107800 3e04304848483000\n3f04780808087800 4004fc2424241800 4104304848485000 4204080878080800 43041ca0a0a07c00 44041824ff241800\n4504004830304800 46043c2020bc6000 4704182020207800 4804784078407800 49043c203ca07c00 4a04087850502000\n4b04785050207800 4c04007850502000 4d04485868300000 4e04783030483000 4f04502828780000 50040030696a5000\n51040032686a5000 5204023f0a887000 530400780a090800 5404003068584800 5504005058682800 560400487a400000\n5704004a78420000 5804004080847d00 5904700878502000 5a04781078502000 5b04047e14106000 5c04007822314800\n5d04784122107800 5e0418a1a2a27900 5f043c20e0203c00 6204027f4a483000 6304087e58502000 70040e107e100e00\n7104182078201800 72043c4a4a4a3c00 7304306858683000 7404001e70180c00 7504001860301000 9004007e02020300\n9104007808080c00 9204087e0a0a0200 9304207828080800 96043b043f043be0 970424183c1824c0 9a04003f040a31c0\n9b04003c101824c0 ae04060870080600 af040c10e0100c00 b004161870181600 b1042c30e0302c00 b20421120c1221c0\nb3040024181824c0 ba047e0808087000 bb04007e08087000 d804003452523c00 d904002868583000 e20400457d450000\ne304004a7a420000 e8043c4a4a4a3c00 e904003058583000 ee04003d41413d00 ef04003a42427a00 d005681020285000\nd105484848784000 d205004830600000 d305080808780800 d405680808087800 d505000008780000 d605080818680800\nd705087808087800 d805784050487800 d905000008180000 da0504040404fc00 db05484848483800 dc050e4848281800\ndd05087848487800 de05582010487000 df05000004fc0000 e005004040487800 e105000878483800 e205487840281800\ne305041c0404fc00 e405485848483800 e50504f820140800 e605485060685000 e705f40424241c00 e805080808087000\ne905785058403800 ea05487808087800 f005087800087800 f105081800087800 f205081800081800 f305000010080000\nf405100800100800 021e7c5455542800 031e007e48493000 0a1e007c45443800 0b1e003049487e00 1e1e007c15140400\n1f1e001079140800 401e7e0419047e00 411e780832087000 561e007c15140800 571e00fc25241800 601e004854552400\n611e0050586a2800 6a1e04047d040400 6b1e00083d482000 801e7c2112207c00 811e384132403800 821e7c2012217c00\n831e384032413800 841e7c2110217c00 851e384230423800 f21e040972080400 f31e00b84142f800 a3207e0a7a120a00\na420a8fcaa828400 a720087e2a1c0800 ab200098a4a6bf02 ac20183c5a5a4200 af20627f22443800 9021103854101000\n912108047e040800 9221101054381000 932110207e201000 9421103810103810 95212844fe442800 \n`,\n\n    }\n\n    // A unicode 12x12 pixel font based on https://github.com/adobe-fonts/source-han-sans\n    //% whenUsed jres\n    export const font12: Font = {\n        charWidth: 12,\n        charHeight: 12,\n        data: hex``\n    }\n\n    export function getFontForText(text: string) {\n        for (let i = 0; i < text.length; ++i) {\n            // this is quite approximate\n            if (text.charCodeAt(i) > 0x2000)\n                return image.font12\n        }\n        return image.font8\n    }\n\n    //% deprecated=1 hidden=1\n    export function doubledFont(f: Font): Font {\n        return scaledFont(f, 2)\n    }\n\n    export function scaledFont(f: Font, size: number): Font {\n        size |= 0\n        if (size < 2)\n            return f\n        return {\n            charWidth: f.charWidth * size,\n            charHeight: f.charHeight * size,\n            data: f.data,\n            multiplier: f.multiplier ? size * f.multiplier : size\n        }\n    }\n\n    //% whenUsed\n    export const font5: Font = {\n        charWidth: 6,\n        charHeight: 5,\n        // source https://github.com/lancaster-university/microbit-dal/blob/master/source/core/MicroBitFont.cpp\n        data: hex`\n2000000000000000 2100001700000000 2200000300030000 23000a1f0a1f0a00 24000a17151d0a00 2500130904121900\n26000a15150a1000 2700000300000000 2800000e11000000 290000110e000000 2a00000a040a0000 2b0000040e040000\n2c00001008000000 2d00000404040000 2e00000800000000 2f00100804020100 30000e11110e0000 310000121f100000\n3200191515120000 33000911150b0000 34000c0a091f0800 3500171515150900 3600081416150800 3700110905030100\n38000a1515150a00 390002150d050200 3a00000a00000000 3b0000100a000000 3c0000040a110000 3d00000a0a0a0000\n3e0000110a040000 3f00020115050200 40000e1115090e00 41001e05051e0000 42001f15150a0000 43000e1111110000\n44001f11110e0000 45001f1515110000 46001f0505010000 47000e1111150c00 48001f04041f0000 4900111f11000000\n4a000911110f0100 4b001f040a110000 4c001f1010100000 4d001f0204021f00 4e001f0204081f00 4f000e11110e0000\n50001f0505020000 5100060919160000 52001f05050a1000 5300121515090000 540001011f010100 55000f10100f0000\n5600070810080700 57001f0804081f00 58001b04041b0000 590001021c020100 5a00191513110000 5b00001f11110000\n5c00010204081000 5d000011111f0000 5e00000201020000 5f00101010101000 6000000102000000 61000c12121e1000\n62001f1414080000 63000c1212120000 64000814141f0000 65000e1515120000 6600041e05010000 67000215150f0000\n68001f0404180000 6900001d00000000 6a000010100d0000 6b001f040a100000 6c00000f10100000 6d001e0204021e00\n6e001e02021c0000 6f000c12120c0000 70001e0a0a040000 7100040a0a1e0000 72001c0202020000 730010140a020000\n7400000f14141000 75000e10101e1000 7600060810080600 77001e1008101e00 7800120c0c120000 7900121408040200\n7a00121a16120000 7b0000041f110000 7c00001f00000000 7d00111f04000000 7e00000404080800 d3000c1213130c00\nf3000c12130d0000 04010e05051e1000 05010609191f0800 06010c1213131200 07010c1213130000 18010f0b1b190000\n19010e151d1a0000 41011f1412100000 4201100f14120000 43011f0205081f00 44011e03031c0000 5a0110140b030200\n5b0110140b030000 7901121a17130000 7a01121a17130000 7b01121b17120000 7c01121b17120000`,\n    }\n}\n\nnamespace texteffects {\n    export interface TextEffectState {\n        xOffset: number;\n        yOffset: number;\n    }\n}\n\ninterface Image {\n    //% helper=imagePrint\n    print(text: string, x: number, y: number, color?: number, font?: image.Font, offsets?: texteffects.TextEffectState[]): void;\n\n    //% helper=imagePrintCenter\n    printCenter(text: string, y: number, color?: number, font?: image.Font): void;\n}\n\nnamespace helpers {\n    export function imagePrintCenter(img: Image, text: string, y: number, color?: number, font?: image.Font) {\n        if (!font) font = image.getFontForText(text)\n        let w = text.length * font.charWidth\n        let x = (img.width - w) / 2\n        imagePrint(img, text, x, y, color, font)\n    }\n\n    export function imagePrint(img: Image, text: string, x: number, y: number, color?: number, font?: image.Font, offsets?: texteffects.TextEffectState[]) {\n        x |= 0\n        y |= 0\n        if (!font)\n            font = image.getFontForText(text)\n        if (!color) color = 1\n        let x0 = x\n        let cp = 0\n        let mult = font.multiplier ? font.multiplier : 1\n        let dataW = Math.idiv(font.charWidth, mult)\n        let dataH = Math.idiv(font.charHeight, mult)\n        let byteHeight = (dataH + 7) >> 3\n        let charSize = byteHeight * dataW\n        let dataSize = 2 + charSize\n        let fontdata = font.data\n        let lastchar = Math.idiv(fontdata.length, dataSize) - 1\n        let imgBuf: Buffer\n        if (mult == 1) {\n            imgBuf = control.createBuffer(8 + charSize)\n            imgBuf[0] = 0x87\n            imgBuf[1] = 1\n            imgBuf[2] = dataW\n            imgBuf[4] = dataH\n        }\n        while (cp < text.length) {\n            let xOffset = 0, yOffset = 0;\n            if (offsets && cp < offsets.length) {\n                xOffset = offsets[cp].xOffset\n                yOffset = offsets[cp].yOffset\n            }\n\n            let ch = text.charCodeAt(cp++)\n            if (ch == 10) {\n                y += font.charHeight + 2\n                x = x0\n            }\n\n            if (ch < 32)\n                continue // skip control chars\n\n            let l = 0\n            let r = lastchar\n            let off = 0 // this should be a space (0x0020)\n            let guess = (ch - 32) * dataSize\n            if (fontdata.getNumber(NumberFormat.UInt16LE, guess) == ch)\n                off = guess\n            else {\n                while (l <= r) {\n                    let m = l + ((r - l) >> 1);\n                    let v = fontdata.getNumber(NumberFormat.UInt16LE, m * dataSize)\n                    if (v == ch) {\n                        off = m * dataSize\n                        break\n                    }\n                    if (v < ch)\n                        l = m + 1\n                    else\n                        r = m - 1\n                }\n            }\n\n            if (mult == 1) {\n                imgBuf.write(8, fontdata.slice(off + 2, charSize))\n                img.drawIcon(imgBuf, x + xOffset, y + yOffset, color)\n                x += font.charWidth\n            } else {\n                off += 2\n                for (let i = 0; i < dataW; ++i) {\n                    let j = 0\n                    let mask = 0x01\n                    let c = fontdata[off++]\n                    while (j < dataH) {\n                        if (mask == 0x100) {\n                            c = fontdata[off++]\n                            mask = 0x01\n                        }\n                        let n = 0\n                        while (c & mask) {\n                            n++\n                            mask <<= 1\n                        }\n                        if (n) {\n                            img.fillRect(x + xOffset * mult, y + (j + yOffset) * mult, mult, mult * n, color)\n                            j += n\n                        } else {\n                            mask <<= 1\n                            j++\n                        }\n                    }\n                    x += mult\n                }\n            }\n        }\n    }\n}\n"},"screen---st7735":{"arcadegamepad.h":"// Autogenerated C header file for Arcade Gamepad\n#ifndef _JACDAC_SPEC_ARCADE_GAMEPAD_H\n#define _JACDAC_SPEC_ARCADE_GAMEPAD_H 1\n\n#define JD_SERVICE_CLASS_ARCADE_GAMEPAD  0x1deaa06e\n\n// enum Button (uint8_t)\n#define JD_ARCADE_GAMEPAD_BUTTON_LEFT 0x1\n#define JD_ARCADE_GAMEPAD_BUTTON_UP 0x2\n#define JD_ARCADE_GAMEPAD_BUTTON_RIGHT 0x3\n#define JD_ARCADE_GAMEPAD_BUTTON_DOWN 0x4\n#define JD_ARCADE_GAMEPAD_BUTTON_A 0x5\n#define JD_ARCADE_GAMEPAD_BUTTON_B 0x6\n#define JD_ARCADE_GAMEPAD_BUTTON_MENU 0x7\n#define JD_ARCADE_GAMEPAD_BUTTON_SELECT 0x8\n#define JD_ARCADE_GAMEPAD_BUTTON_RESET 0x9\n#define JD_ARCADE_GAMEPAD_BUTTON_EXIT 0xa\n\n/**\n * Indicates which buttons are currently active (pressed).\n * `pressure` should be `0xff` for digital buttons, and proportional for analog ones.\n */\n#define JD_ARCADE_GAMEPAD_REG_BUTTONS JD_REG_READING\ntypedef struct jd_arcade_gamepad_buttons {\n    uint8_t button;  // Button\n    uint8_t pressure;  // ratio u0.8\n} jd_arcade_gamepad_buttons_t;\n\n\n/**\n * Constant. Indicates number of players supported and which buttons are present on the controller.\n */\n#define JD_ARCADE_GAMEPAD_REG_AVAILABLE_BUTTONS 0x180\ntypedef struct jd_arcade_gamepad_available_buttons {\n    uint8_t button[0];  // Button\n} jd_arcade_gamepad_available_buttons_t;\n\n\n/**\n * Argument: button Button (uint8_t). Emitted when button goes from inactive to active.\n */\n#define JD_ARCADE_GAMEPAD_EV_DOWN JD_EV_ACTIVE\n\n/**\n * Argument: button Button (uint8_t). Emitted when button goes from active to inactive.\n */\n#define JD_ARCADE_GAMEPAD_EV_UP JD_EV_INACTIVE\n\n#endif\n","arcadesound.h":"// Autogenerated C header file for Arcade sound\n#ifndef _JACDAC_SPEC_ARCADE_SOUND_H\n#define _JACDAC_SPEC_ARCADE_SOUND_H 1\n\n#define JD_SERVICE_CLASS_ARCADE_SOUND  0x1fc63606\n\n/**\n * Argument: samples bytes. Play samples, which are single channel, signed 16-bit little endian values.\n */\n#define JD_ARCADE_SOUND_CMD_PLAY 0x80\n\n/**\n * Read-write Hz u22.10 (uint32_t). Get or set playback sample rate (in samples per second).\n * If you set it, read it back, as the value may be rounded up or down.\n */\n#define JD_ARCADE_SOUND_REG_SAMPLE_RATE 0x80\n\n/**\n * Constant B uint32_t. The size of the internal audio buffer.\n */\n#define JD_ARCADE_SOUND_REG_BUFFER_SIZE 0x180\n\n/**\n * Read-only B uint32_t. How much data is still left in the buffer to play.\n * Clients should not send more data than `buffer_size - buffer_pending`,\n * but can keep the `buffer_pending` as low as they want to ensure low latency\n * of audio playback.\n */\n#define JD_ARCADE_SOUND_REG_BUFFER_PENDING 0x181\n\n#endif\n","fieldeditors.ts":"/**\n * Image manipulation blocks\n */\n//% weight=70 icon=\"\\uf03e\" color=\"#a5b1c2\"\n//% advanced=true\nnamespace images {\n    //% blockId=screen_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.decompileArgumentAsString=\"true\"\n    //% img.fieldOptions.filter=\"!tile !dialog !background\"\n    //% weight=100 group=\"Create\" duplicateShadowOnDrag\n    //% help=images/sprite-image\n    export function _spriteImage(img: Image) {\n        return img\n    }\n\n    //% blockId=background_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.decompileArgumentAsString=\"true\"\n    //% img.fieldOptions.sizes=\"-1,-1\"\n    //% img.fieldOptions.filter=\"background\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _screenImage(img: Image) {\n        return img\n    }\n\n    //% blockId=tilemap_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.sizes=\"10,8;16,16;32,32;48,48;64,64;16,32;32,48;32,8;64,8;20,15;40,15\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _tileMapImage(img: Image) {\n        return img\n    }\n\n    //% blockId=tile_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.sizes=\"16,16;32,32;8,8\"\n    //% img.fieldOptions.filter=\"tile\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _tileImage(img: Image) {\n        return img\n    }\n\n    //% blockId=tileset_tile_picker block=\"%tile\"\n    //% shim=TD_ID\n    //% tile.fieldEditor=\"tileset\"\n    //% tile.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% weight=10 blockNamespace=\"scene\" group=\"Tiles\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _tile(tile: Image) {\n        return tile\n    }\n\n    //% blockId=dialog_image_picker block=\"%img\"\n    //% shim=TD_ID\n    //% img.fieldEditor=\"sprite\"\n    //% img.fieldOptions.taggedTemplate=\"img\"\n    //% img.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% img.fieldOptions.decompileArgumentAsString=\"true\"\n    //% img.fieldOptions.sizes=\"15,15;18,18;21,21;24,24;9,9;12,12\"\n    //% img.fieldOptions.filter=\"dialog\"\n    //% weight=100 group=\"Create\"\n    //% blockHidden=1 duplicateShadowOnDrag\n    export function _dialogImage(img: Image) {\n        return img\n    }\n\n    /**\n     * An image\n     * @param image the image\n     */\n    //% blockId=image_picker block=\"$image\" shim=TD_ID\n    //% image.fieldEditor=\"sprite\"\n    //% image.fieldOptions.taggedTemplate=\"img\"\n    //% image.fieldOptions.decompileIndirectFixedInstances=\"true\"\n    //% image.fieldOptions.decompileArgumentAsString=\"true\"\n    //% weight=0 group=\"Create\"\n    //% deprecated\n    //% help=images/image\n    export function _image(image: Image): Image {\n        return image;\n    }\n\n    //% blockId=colorindexpicker block=\"%index\" blockHidden=true shim=TD_ID\n    //% index.fieldEditor=\"colornumber\"\n    //% index.fieldOptions.valueMode=\"index\"\n    //% index.fieldOptions.decompileLiterals=\"true\"\n    export function __colorIndexPicker(index: number) {\n        return index;\n    }\n\n    /**\n     * A position picker\n     */\n    //% blockId=positionPicker block=\"%index\" blockHidden=true shim=TD_ID\n    //% index.fieldEditor=\"position\" color=\"#ffffff\" colorSecondary=\"#ffffff\"\n    //% index.fieldOptions.decompileLiterals=\"true\"\n    export function __positionPicker(index: number) {\n        return index;\n    }\n}\n","font12.jres":"{\n    \"image.font12\": {\n        \"mimeType\": \"font/x-mkcd-b26\",\n        \"data\": \"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9A9UANwHAAD4AQAI/AcAADhSIAGqCOoIrAS4Aq4BqAi4CKwG6gGqACABOVJQBFQDVAjIB0wAUgFSBgAA/AkACP4PAAA6UgAEdAYUAf4PFAH0AgAA/AEACAAI/gcAADtSAAAkCbQErwJkAhQDxAQAAPwJAAj+DwAAPVIgAJAMiAakBaYEiAawCAAA+AkACP4HAABCUkQIVARUAzYANACsDyQAAAD8CQAI/wcAAENSAAToBKoCrAH4D64AuAcAAPwJAAj+BwAAR1IACP4FKgUqASoB/g0AAPwBAAgACP4HAABKUgAA9g9QAV4JUAn2BwAA/AEACAAI/gcAAE1SAADoD6oCrAqoCugHCADoAw4I6AcIAAAATlIAAFIEUgNMAOQPSgJqBAAA/AkACP4HAABRUhAAWAiEBRIE0wQEB8gCAAL8CAAI/gcAAFRSAAG+BOoCqg2qA6oIvgcAAPwJAAj+BwAAVlIkAKwPrASmBKQEvASsBwAA/AkACP4PAABbUgAA/A8MA+QDFAn8BwAA+AEACPwHAAAAAF1SAADAANgKVgrUB3QAzAYAAPgJAAj+BwAAY1IQCPAEvAbyAbQC5AwAAPwBAAgACP4HAABkUgAAJAisB5YCrAKkDyQAAAD8AQAI/g8AAGVSoAIqCioJ6g8qAb4CoAYAAPwJAAj+BwAAZ1LABz4AqgeqBPoEqgSuBwAA/AAACP8HAABpUogIbARsAgwB/A8MAWoCKAQAAPwJAAj+B2pSAAV8BTwFPgW8A/wBBAF0BQYFdAUEAwAAb1ICAN4PVgXWB1YFVgXeDwAA/AkACP4HAABwUgAArAT8AqwB/A+qAvoGAAD4AQAI/gcAAHJSjAC8D7QFtAX2BbQHtAeMBwAA/AEACP4HdVIQABAO0AP4BfQF5AXoBwAA+AEACPwHAAB/UgAIdgVwBXQD+g94A3ADdgUAAPgJAAj+B4NSSAT8B/wH/gf8B/wH/Af8BwAE+AEACPwHh1IADvgBGATYBn4DbA9sAggE8AEACPwPAACIUoAAfAj0CbQJtAX4A1QBXAn2CVwJVAcAAIlSAACcCcoLyQmwB84FQgUOBPgBAAj+BwAAjVIICOgErALqAEsIogbkBAAA/AEACP4HAACRUjgASAz0A4wClgK8AswPIAD8AQAI/gcAAJtSAAAQCBAEEAKQAX4AEAAQCBAIEAzwAwAAnVIABBQCZAHkABwJAASIA34ACAgICPgHAACeUgAAiAloBAgCiAF+CAgICAz4AwAA4AEAAJ9SBAIEAvwBBAkECRAEEAP+CBAIEAzwAwAAoFIICAgG/gEICAgI+AcAAPwPBAQEBPwPAAChUkAIUAlICSwFNgOkASQJNAlMCUQHQAAAAKNSKAioCKQIogSgA54AkAiICIIIhAcIAAAAqFIAACQE5AMkAqQCJAMACBAH/gAQCPAHAACpUgAE/gOSBJIC/gsABBAD8AgfCBAI8AcAAKpSAAhECVwJZgUkA1wBRAE0CSQJXAdEAAAAq1IAAEgHyAR+AkgCQAcQABAP/gAQCPAHAACxUgAO/AEUDPQDVAjUBwQAEAf8ABAI8AcAALJSAACkCKQElAesBKQEMAAQDv4BEAjwBwAAs1IACLQIlASWBJQD1ACUCJQIlgiUBzQAAAC0UgAIuAiKBIoEiALrAYgIiAiMCIoHOAAAALlSKAioBKgCDAGoAggIUAQQA/4IEAjwBwAAv1IAABQIVAl+BRQFwAM0AR4JBAk8B0AAIADBUgAAtASEBLQHhAS0DAQEEAP+CBAI8AcAAMNSAAA0AhQJXgeUATQJAAQQA/4IEAjwBwAAx1IACAIK+gqqBqoC+gKqAq4Kqgr6BgAAAADJUhAI+ASWA/QAnAfwCBgKmAl+CAgK+AkABMtSAAjuCSoEqgMqCO4LAAAQB/4AEAjwBwAA0lIAAOQCvgL0D74C5AgEBBAD/ggQCPAHAADVUgAAfAl8CfwHeg0IBBgCkAF+CBAI8AcAANhSgACCB/8FqgSqBP8FggwIAv8BCAT4AwAA2VIAACoDqgjqBzYA4AlIBy4BNAk0CSwHRAHdUgAM/gOSCP4HgAFqCTgHrgE4CW4JqgcAAd5SEgiSCKgErgSgAqIBpAioCKYIKAdyAAAA31IAAkQB/AV+A3wDfAF8BX4F/AN8AUQCAADiUgAArAmsCe4FrAWAA/gBGAkOCXgGgABgAORSAAj0CdYF9AfWBfQFAAwQA/4IEAjwBwAA51IAACAB7A+4B+gHqAeoDgAG/AEQCPAHAADyUgAB/g3+Af4B/g3+AQgLmAh+AAgB+AwAAPNSBAh9BW0B/wTsAvwCAAaIAX8ECAT4AwAA9VIADPwDzA/8AewD/AvMDwAM/gMQCPAHAAD4UgAB+g+7B4AHuwe6BwAM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JAAAAK1T+AcEAPQD/AJ8B3QFhAckBPwDJAEUAgAErlMABv4BAgT6AVoD+gECDPoDSgDKD0oAAACyUwAO/gECAOoP6gHqBeIH6gXqBeoJCg8CALNTAA74AQ4E+Ae4BroG/A8IAOgMLAPqBSgIu1NAAEgMSAZIBcgEfgRIBEgFSAZICEAAAAC/UwAAgACABP4GqgWqBKoEqgSqBP4GgASAAMFTIAGoCKgK7Aq6CqgKqgruCqgKqAggAQAAwlMgASgBqAhsCroKqAooCWoErASgACABAADDUwAAAAGwAKQJdgulChQKJgl2BKAEMAFAAchTAAAACAQIHARkBIQCBAGEAmQEHAQECAAIyVMACAQIPAREBJQCFAGUAkQEPAQEBAAIAADKUwAEBAaEAXwIJATEBAQDHAOQAnAEEAQAAMtTAAQIBAgDyAh+BKgEKAMoA6gEaAQICAAEzFMUCDQERALkARwKAAh8BIQDxAI8BAAIAADNUwAAAAz8AyQI5AgkBSQCJAakBWQIBAgAAM5TAAL4AQABAAH+DwAAFAjkBAQDxAQ8BAQI0VMABBACHAuQCPAIXgVQBlAF1ghQCBAIAADUUwACoAEgCP4PJACgCwQIfAaEAeQCHAwACNZTBAT8B5QElASUAvwPAABoCIgFCAPoBBgI11MAAHQIHATcBFQFXAJcAlIF2gQaBDAIAADYUwAIpAiUCIQJvAaGBIYEvAaECZQIJAgACNlTUAZYAVQI8g9UAFQDBAh8BIQDxAI8DAAA21MAAKwIoAb+AaQAAA78AXIMkgOSAnIMAATgUwAA6Ah2CFYPVg9GD1YPXg9WD3gIyAgAAOFTAACoANgHvwfaB/oHkAAMDPQChAF8BgAE4lMIAKoE7Af4B/wH6A/oAPwH7AXqB4gJgAjjUwAAAAD8DwQEBAQEBAQEBAQEBPwPAAAAAORTAAAIAIgPiASIBP4EiASIBIgEiA8IAAAA5VMAAGAAEADMByoCKAIoAugLCAgIDPgDAADmUwAAgAi8BKQEpAPkAKQApAikCLwIgAcAAOhTAAD8AwQB/AkACAQGhAF8BAQIBAz8AwAA6VMAAPwDBAEEAfwBAAD8DwQABAIEAvwBAADqUwAAAAh8BEQCRAFEAEQARAFEAnwEAAgAAOtTAAD8AwQBBAH8AQAA/AMAAQAB/g8AAAAA7FOAAEQARA8kCRQJ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ggCyAIoAAAB9VAAAEADQB1gCWALUAxIA1A9YAEgC0AEQAIZUAAD8AwQB/AEwAPgDlgSUBPQFBAX8BAACi1QAAPwDBAH8ARAACAAOAPgPKAEoASgBAACMVAAClAFUAPwHUgAAAPwHBAIEAgQC/AcAAI9UAAD8AwQB/AQAAtQBFAj0D4QAQAEgBgAEkFQAAPwDBAH8AWAA/A8CANAAEAkQCP4HEACSVAAIHAgUBNQDXABAAFwAVADUBxwIAAgABpVUAAD8AwQB/AEAAJAPkASQBP4EkASQDxAAllQAAPwHBAH8DAAC/gkIDPAD/A8EBPwPAACZVAAA/AMEAfwJAASQA34IEATyB5YIVAgQBJpUAAD8AwQB/AFQAEgCLgK1BDQFTAlEAEAAplQAAPwDBAH8AQAI7ASsAv4BrAKsBLwJAAinVAAA/AMEAfwBQAi8BJQDYAD4CQAI/gcAAKhUIAARAIoPoASsBKMEkgSOBJIEog8uAAAAqlQAAPwHBAL8AwAIrAcgAP4PIACoAyQMAACsVAAA/AMEAfwBAAgoCKgECgPMBQgEaAhACK9UAAD8AwQB/AEQAYgPVgllCXQJXAmED4AAsVQAAPwBBAH8AQAA+AeoAqwCqgKoAvgHAACyVAAA/AMEAfwJAAhOBEwC+AFMAk4ESggAALNUAAD8AwQB/AEACCQFtARvAiQClAVECAAAuFQADPgDCACoB6gCqAoIC/4ICAfKCCwIAAa9VAAA/AMEAfgA/g8CBCIF+gSiBQIE/g8AAMBUAAIEAXQBVA/UBFUE1gRUAVQCdAUEBQAIwVQAAMAPQAReBNIHEgDSD1IEXgRABMAPAADEVAAA/AMEAfwBAAiIBP4CiACIAP4CiAyACMZUAAD8AwQB/AEACCgJpASWBFQCTAHEAAAAx1QAAPwDBAH8AQAIJAkkCb4PJAkkCSAJAADIVAAA/AMEAfwBYAAwD6gEpgSoBDAPYABAAMlUEADUB1QCXgJUAtQJEAz+AhADkgRUCAAHzVQAAPwDBAH8AQAA+A8IAOgDLgHoCQgI+AfOVAAA/AMEAfwBAAgkCM4EBAMEBc4EJAgECNFUAAD8AwQB/AVABAQE/AcEBPwHBATkBAAA11QAAPwDBAH8AQAAfAECAZAPPgFIAUQBJADfVAAA/AMEAfwBAAT8BYIEEALOCAgI+AcAAOFUAAAACP8LrQatBq0CrQKtBq0G/wsACAAA5VQAAEQAfAdsBWwFbAVsB3wARAj8D0QAAADmVAAA/AMEAfwBAAj8D5IAEAz+A5AFVggABuhUAAD8AwQB/AEAAPYPUAFeAVAJUAn2BwAA6VT8AwQB/AEAAHwJVAlUCfwPVAlUCXwJAADqVAAA/AMEAfgMAgL+CZII/gf8DwIA/gMAAO1UgAieCJIIkgSeA8AAnAOUBNQE3AiACAAA7lQAAP4BggD+AIABagEqCb8PagEuASoBCQHyVAAAEgCyD78EigSgBJ4EiQSJBLkHCQAIAPpU/AMEAfwBAADoD6gCqAL+D6gCqgrsBwAA/FQAAPwBhAD8AAAAvAisCK4OrAGsAbwABAABVQAA/AcEA/wDAACoDqgKqgqqCqgKqA4IAAZVAAD8AwQB/AlACCgJngaIBPwGzAVYCEAIB1UAAAAP/gAiDuoKqgpqCqoKqgoqDSIBAAAJVQAA/AMEAfwBAAgoCS4F6gMoBS4JKAkAABBVAAb8AQQAXAdcBVwF/gVcBVwFfAcUAAAAFFUAAPwDBAH8AQAAqge6BK4EqgS6BKIHIAAgVQAA/AMEAfwBAAiUBJYC1AmUCJYMNAMAACRV/AMEAfwBAAj4BJQClgH0AZwClAT0BIAIJ1UAAPwDBAH8AQAE/AdUAjwA+A8EAPwDAAAsVQAA/AMEAfwBAAz4AygIPgdsAGwHTAgABC5VCAAIAHwPXgVcBVwFfgVcBVwFXA9EAAAAL1UAAPwDBAH8AQAA/A+qBKgE/geoBKgEAAAxVQAA/AMEAfwBAAD+B2oFagVqBWoF/gcAADdVAAD8AwQB/AEACPQH7ADmAmUKZAr0ByQAOFUAAPwDBAH8CAAGKACkBLIJNAr0ACQGCAg+VQAA/AMEAfwBAAjUChQK/A8UCtIKUAoQCENVAAD+AYIA/gAIAO4PqAKvAqoKqgrqDwAARFUAAPwDBAH8ASAElAJUCiwJxAdkAJQDAARGVQAAAAD0DxQAfAcWBTQFVAVcBxQA9A8AAEpVAAD8AwQB+AD+DzIAzAHkAxQB5Aj8BwQAT1UAAP4PKgCqB74CgAK+AqoDKggqCP4HAABTVcIAOgCqB6oEqgS6BJAEzgS0BDQHTACEAF9VAAb8AaoHqgKqAroDIAR+AogB6AIYBAAAYVUAAPwDBAH8AQAAKAH+DwAA/g8oASgBAABkVfwDBAH8AQAAfALUAtQCfgJUD1QCfAIAAGVVAAD8AwQB/AEQAEgHRAXyBVQFRAVIB1AAZlUAAPwDBAH8AQAM/gMICGAIiQkKDugJAABqVQAA/AMEAfwBgAj+B0AA+A+MBIoE+A8AAHBVAAD8AwQB+AmOCVIIfgVSAl4B0gFeAAAAeFX8AwQB/AEADKwDLAYsAf4PLAEsArwPCAB8VQAA/AMEAfwBAABsB6QApg+0AKQEpAMAAIBVAAD8BwQC/AMAAKQPtAlWCVQJpA6MAAAAglX8AwQB/AEAAPwA1A/UCPwJ1ALUB/wJAACDVQAA/AMEAfwA4A8UALQCngfUAhQI9AcAAIRVAAFEAVQPVgtUC/wLVAtUC9YL1A9EAQAAh1UAAPwDBAH8DGQCng/0AZQCYAj4CP4HAACJVQAA/AMEAfwBYAD4DwYAUAlUBdQDXAVQCYpVAAD8AwQB/AzwAwgHqAIIDX4CiAVqCAAGlFUAAPwDBAH8DAAC/Ak0CPQKtA+0CrwKAACYVfwDBAH8AQAAvA+wALAP/gCwD7AAvA8AAJpVAAD8AYQAfAjwBVgFNgOUAzwFUAXwCQABnFUAAQQBfA/cC1wLXgtcC1wL3At8DwQBAAGdVQAA/AMEAfwBAAC+BqoEqgWqCKoIvgcAAKdVAAD8AwQB/AEICPQLtAq2CrQK1AscCAAAqlUAAIQIvAisD7wIhAj+CYQCvASsCrwKhAirVQAA/AMEAfwJAAg+BTQDwAM8BQQJfAkAAKxVKAAsAJwP/ADcB9wF3AXcBfwHmgioDyAArlUAAAAE/gVaBVoF/g9QBV4FWgX6BQ4EAACyVQAA/gMCAf4BGAznApAAUAaOAAgI+AcAALNVAAD8AwQB/AEACNQLrAquCqwK1AsUCAAAtVX+AYIA/gAAAPAPkgSXBPIHkASXBPIHAgC2VQAAGAAKB3wFWAXeBVgFWAV8BQoHGAAAALdV/AMEAfwBAAjUC1QIVAZWAVQEVAjUCwAIu1UAAPwDBAH8ARgA2A+0AvIPlAEYCMgHEADFVQAA/AMEAfwBAAh8BVwFXgNeA9wFfAUACc5VAAD8AwQB/AEADP4AqgaqAP4EqgGCDwAA01UAAPwDBAH8AQAIUgV2A4YPlgNSBTAFAAjaVQAA/AMEAfwJAAT8ANQO1gDUBdwIwAcAANxVAAD8AwQB/AFAADQHfgfUB9wH1AfUBwAA4VX8AwQB/AEABMgCVAqiBxAAUgJ0CuQHCADjVQAA3A/UB9QP3A+EAVQC1AsECPwHAAAAAORV/AEEAfwBAATgB2wGeAbuB2gGaAbsDyAI5lUAAPwDBAH8AQAMVAH0CV4HFAGUBTAIAADoVQAA/AMEAfwAAA5EAJADzAKoC6gK6AcAAu9VAAD8AwQB+AA+AWICagRaBVoEQgF+AwAC/VUAAPwDBAH8BCQC/g9UAXQJEAbOAQgGOAgAVgAA/AMEAfwBAAD0DxQC9gVUBVwHFAj0BwFWAAD+AYIA/g74AYQE9AcUAIcEfAOFBnQCBlb8AwQB/AEACPQK1ArWBvQD1AbWCvQKAAAJVgAAgg6+Au4KrgqvBq4M7gquCr4Kgg4AAA5WAAD4AwgB8AUEBXwF/AN8A3wF/AV8BwQDF1YAAAwARg/WC/QL9gv0C/QL9gvFD5wAAAAbVgAA/AMEAfwI+AcEAfQPJgKEAfQPpAAEAx9WAAD8AwQB/ACAD34FUAWID/wHBAD8AwAAMVYAAPwBhAB8CAAH/A60AdwF/AfUAdwPAAAyVgAA/AMEAfwDfAKuD3wC/geSAP4PAAAAADRWAAD8AwQB/AEQBNgD7gL0B/AC7gLUBxAANlYAAPwDBAH4AAQN/gFUAf4N/AMkAOIPIgA5VgAA/gOCAf4BAAz6AVYJUw9WAfoBMgwAADtWAAD8AwQB/AEAAHwP3AteC1wL3At8DwQBP1b8AYQA/AAACF4FVgFSBf4JWgFSBV4AAA5BVgAA/AMEAfwAIA1UAdwHBAvcC1QJdAEADWJWAAD8AwQB+Al8CAwFZAN2ASQDRAV8CQAAaFYAAEACXA9UCdQJfA9gAEwP9Al0CVwPQAJpVgQIxAv8CvwLRAj8D0QI/AvsCvwLBAgAAGpWAAD8AwQB/AnABbwF9AOUD/QPvAPgBQAIdFYAAPwBhAD8BBAE9Af0AvYC9ALUBvQHEAiHVgAA/AMECfwH5As/COQPJA3kA/8PJACgA45WAAD8AwQB/AFACDwGvAa+A7wPvAPkBAAAo1YAAIgH7gWuBW4HWABuB24FrgVuBYgHAAC0VgAO4AG8BPQH9AfsD7gB1Al0BvwFYAgAALdWAAD8AwQB/AUADPwP7An+AfQH7AX8CQAAvFYAAPwDBAH8AQAA9A/yBfoMMgG5CLUHgADCVgAACAL+B/4H/gf+BvgA/gb+B/4HCAUAAclWAAD+AYIAfAH3BqUCBwP9D1cF9QdXBQAAylYABbQD/Av8B/wFngX8AfwD/AXcB5QHAADaVgAA/g8CBAIFggRCBDoEwgQCBQIE/g8AANtWAAD8DwQExAU8BAQEBAR8BIQEBAT8DwAA3lYAAP4PAgTyBJIEkgSSBPIEAgQCBP4PAADgVgAA/g8CBCIFIgWiBHoEogQiBQIE/g8AAOJWAAD+BwIEkgRSBFIFMgX6BRIEAgT+BwAA41YAAP4HAgQKBGoECgUKBfoECgQCBP4HAADkVv4PAgRSBJIEkgT6BZIGkgZSBgIE/g8AAO1WAAD+BwIEKgXqBCoE6gUqBSoFAgT+BwAA8FYAAP4PAgSiBWIE+gViBKIEIgUCBP4PAADxVgAA/A8EBEQFJAVXBZQEdAUUBQQE/A8AAPJWAAD+DwIEkgT6BZIEkgT6BZIEAgT+DwAA81YAAP4PAgZaB0IFygTCBDIFCgUCBP4PAAD0VgAA/g8CBKoEqgT6BaoEqgSKBQIE/g8AAPpWAAD+DwIEEgTSBVIFegVSBdIFAgT+DwAA/VYAAP4PAgQqBSoF+gUqBWoFKgUCBP4PAAD+VgAA/w8BBCkFLQUVBZUFrQYlBgEE/w8AAANXAAD8BwQE9AX0BPwE/AX0BPQE9AUEBPwHBlf+BwIG3gZWBlYFVgVWBF4GwgYCBP4HAAAIVwAA/gcCBD4E/gU6BroGegY6BQIE/gcAAAtXAAD+BwIE6gWqBUoEegWKBW4GAgT+BwAADVcAAP4HAgT+BX4FfgX+BX4FegUCBP4HAAAPVwAA/gcCBGoE6gX6BuoG+gZqBAIE/gcAABJXAAD+DwIM6g1qC3oLagtqC+oLAgz+DwAAE1cAAP4PAgjCC/oL6gvqC+oL+gsCCP4PAAAWVwAA/gcCBP4H9gf2B/YHfgbiBwIE/gcAABhX/g8CBP4E/gX+BP4E/gb+B/4EAgT+DwAAH1cABCAEIAQgBCAE/gcgBCAEIAQgBAAEAAAjV0AIRAhMCSwJNAmkDzQJNAlMCUQIQAgAACdXAAAADPwDBAhECEQI9A9ECEQIRAgECAAAKFcIAYgAyA84AI4IiAiICOgPiAiICIgIAAAtVwAIJAkkCSQJJAm/DyQJJAkkCSQJIAgAADBXAAIQAv4BEAFAAPwHIAggCP4JEAgQCfgEM1cABBAC/gMQAQAM/gMAAAAA/AcAAAAA/g86VwACEAL+AxABAAEiCfIEKgLmCSIM4AMAAD5XAAQQAv4DEAoABIQDfAiEBCQHPAXgBAAIQFcQAhAC/gEQAQAI8A8ACAAI/g8gCCAIIAhCVwACEAL/AZAEAAb+ATIM0gISA5ICcgQCCEdXAAIQAv4BEAEwAAwCKgEoCagICAz4AwAASlcQAhAC/gEQCQAMCAL4AUoISAhICMgHCABOVwACEAL+ARABQAg0CAoG6AEIAkgEOAgAAE9XAAIQAv4BEAFEAUQAJAD8DwQAJADEAIAAUFcgCJAIjgiwCIAI/g+gCJAIjgiQCCAIAABRVwACEAL+ARABAAzoAyoAKgDoBwgICAYAAFdXAAIQAf4BkACACAgESAP+AMgBSAJ4BEAIWlcACD4IAAkACX4JRg8qCRIJKgkmCUAIAABbVwACEAL+ARABAAQkBqQFZAQkBKQFJA4ACF1XAAIQAv4BEAEACP4JAgQCAvoBAgQCBP4JXlcQAhAC/gMQAQAC/AKEAoYCpgqkCJwHAABfVwACEAL+ARABgAkIBHgEigOMAngECAgIBGBXAAR+BQIFPgUCBaAHMAUOBRAFIAVABAAAYVcAAhAC/gMQCQAM+APICX4GSAbICVgIAABkVxAC/gEQAQAA/AMkASQB/w8kASQB/AMAAGZXgAAQAf4AkAAABP4EkgSSBJIEkgT+BAAEalcAABAC/gMQAQIAugCCAP4PggCyAIoAAABvVwAEEAL+AxACQAlECCQI/AskCEQIhAgAAHdXAAIQAv4DEAEEAPQDFAH0CQQI/AcEAAAAglcAAEACVAr0C1QKVAr8D1QK8gtSCkAAAACDVwACEAL+ARABAAQoBMgFCgQIB+gECAQAAIRXiAiICmgKGApMCkgPeAqsCqwKiApICAAAi1cAAEAEygQ+BAoFfgUKBwAFHgVABX4EAASSV0AIaAlICWwJCgkID2gJTAlICSgJQAgAAJtXAAQQBP4DEAIACKAEngLCD4IBvgKgBKAIolcAAhAC/gEQAQAO/AGUD1QEVARSBNIPEACjVwACEAL+AxAJBAj0C1QKVApUClQK9AsECKZXAAAACP4KqgoqCioPagqqCqoK3gqACoAIq1ckBJQF/gUUBQAF1Ac0BR4FBAV8BIAEQACuVwAEEAL8AxACgACoArgDrAqoCpgKqAaoAMJXAAIQAv4DEAkACfwHrAasBfwIrAisCPwAw1cABBAC/gMQAUAIKAkuBegDLAUsCSAJAADLVwACEAL+ARABAAh8CVQJVAn8D1QJVAl8Cc5XAAAQAv4BAAz4AygAKArICX4EiAduCAgG1FcAAhAC/gEQAQAA6A+oAqgC/g+oAqoK6gffVwAAEAL+ARABQACoAugKCAR+AogFaggMBuBXAAIQAv4BEAEAAvwCtAK2D7QCtAL8AgAC91cAAJQC1AKeD/QCEAhIBv4BCAEIAPgHAAz5VwABEAL+AQABJACkB7QEpgSkBLwErAckAPpXAABIAUgF/AR4BXgHeAV4BfwESAVIAQAA/FcAAhAB/gEQAQAAtAe0Aq4LNgg0CPQPNAAAWAAACAH/AAAG/wEFDnUERQT1B0UEdwcAAAJYAAA4CAoK7AqoCq4PqAqoCuwKCgo4CAAABVgABH4FVgV2BVYFXgcABUoFMgU6BUYEQAAGWBACEAH+AYAAMAD8D6oEqAT+B6gEqAQAABVYAAj+CgoKdgoACnwPPgo8CrwK/AoECAAAIVgQABAEfgUABV4FOgcaBXoFOgVeBVAEAAAkWBAEEAT+AxAKgAi+BqoEqg+qCqoKvgqACCpYAAAQBP4DEAMED/4JVAtUC1QJ/g0ECQAAL1gAAJgJnAl8BVwDDgFcAVwHfAlcCVgFAAAwWAACEAH+ARAA/A8EBPwGfAd8BfwFfARAADFYAABUAXQB3gd0AQAA/g9iCLIEMgPuDAAENFgAAggC/gEIAEAJ/gVqA2oFagNqCX4HAAA1WAACEAH+ARAB1ABUAN4HdAVQBVgF1gcQADpYAAEIAf4AgAm+BKoE6gM+ACoA6g++AQABQVgACEAJfgtqCyoKPg8qCqoKagt+C0AJAABKWAAEEAL+AxABAAF8CFYH1QD8B1QIVAt8C0xYCAEIAf8BCAFAAN8BVQXVB5UBVQnfDwAAUVgAAGgIzAp4CkwKKA+ACnwKVApUCvwIAABUWAACEAL+ARABRAAkByYFVAVUBSYFJAdEAFdY2ggCCooKqAosCqwOqgr6CiwKrAqoCAgAWFgAAggB/wEIAQAG/AEcBl0F+gVcBXwHFABaWAACEAL+AZAFBgWqAnoKigk6BsoAJgcAAF5YAACECrQKtAn0CrQKtg70CrQJtAqECgAAaVgAARAB/gEQBTgE9gfUB9QE1Af0BIQHAARrWAAEEAL+AxABAAj8C7wKvgK8CvwLBAoAAHVYAAAADP4H6gT+BWoFawd+BeoF6gX6BAAAflhECHwJfAv+C3wKAA+ICmgKHgr4CAAJwAiDWAACCAL/AYgICAj6BV4DWwFeD/oJCAQAAIVYAAh+C2oL/gtqC34PEAqSCvoKFgpyCAAAilgAAKwIrAruC7wKiA/oCjwKSAr4CAAJwAiTWAABRAX8BH4FfAV8BXwHfAV+BPwERAUAAZdYAAIQAv4BAAF8ANcP1Ar8CtQK1wr8DwAAmVgAABAD/gGQAAQA7AfkB/4G5AZsBeQHAACcWAAAfgSKBnYGAAZWBzwFtAX0BRYFZASAAJ5YAAAQA/8BgAA8AOYPdAV8BWQF5w88AAAAqFgABCAEfgU6BXoFPgd6BT4FOgV+BSAEAACpWBAE/gMQA3AC2grcD/gDAAr+BIgDeAwAAK5YAAD+CAIKfgoACvYPOwp+Cn4K3gp+CAgIs1gAAhAC/gEQAQQI1AfcB94D1APUB9QLEAjBWEAAfgRqBWoFagVuBzQFPAV2BTQFPAUABMdYAAAQAf4BAAF8BMwH/Af+B/wHzAd8BAQEylgAABAC/gEAA/QK1A70Cd4F9ALUBvQIAAjTWAAM/gPKAf4G/ga+B8IHEgf6BvIGtAQAAdVYAAAQAv4BEABEBbwGvAO+C7wHvAHkBgAE2FgABHAFfgV+BX4FfgcuBX4FfgV+BXAEAADeWAAAEAL+AQAAXAKsDjwJbgk8AuwG/AgAAOJYAAAQBPwDAAj8BwQA9A5kCAQO9AqkCgAA5FgAABAC/gEABXwE7A3+C8YB/AfsBfwJBAHrWCAAIAQgBCAEIAT+ByAEIAQgBCAEIAAAAO5YAAIYAgAB/g8AACAIIAj+DyAIIAggCAAA71iACJ4HkAD+DwAAIAggCCAI/g8gCCAIIAjwWAAABAzUA1QBVAHeAVQBVAFUAdQDBAAAAPJYAAjECFQIVAZUAV4AVABUB1QIVAjEBAAA81gACMQIVAhUBNQD3gDUANQHVAhUCMQIAAT2WAAAxAhUClQIVA9UCF4IVA9UCFQKxAgAAPlYAAA0BLwFfAV8BX4FfAV8B/wF3AUUBAAA+lgAAGQINAu0CvQOPgj0DrQKtAo0C2QIAAD9WJQA3Ab8BvwG/Ab+APwE/AL8CtwP1AKAAARZgAhgCN4ECAPoAhgEAAj+CyAIQAiACAAAB1lAAFAASA+sCrYKpA+0CqwKzArED0AAQAAJWQQKRAo0CYQFpAaeBMQG/AaECZQIJAgAAA1ZAAAICAgKdgneB1wFXAVcBVwLfAkECAAID1kACAQKfAl8BfwHfAV8BXwHfAl8CQQIAAgVWQAAQAAgCBAISAROBIoCCAGIAGgAGAAAABZZQABgCFAEjgKIAWgAEAAgAP4PgAAAAQACGlkAAFAISAlECTQFpgSUBkwCRAHAAEAAAAAcWYQARAD0DwQARAhmBLQDFAOUBHQEFAgAAB9ZIADwAywJ6AkICPgHAACoCJYEVAJMAcAAIFkICagEdgVUAswBEADMAyoB6AkICPgHAAAiWcQAfApsCm4L/AtsBWwFdgNsAXwAxAAAACVZAAj8BNQC/A/UAvwAEAhICdYGtASMA4AAJ1kQCBAEEAIQAdAAPgBQAJABEAIQBBAIAAApWUAIRAhEBEQCRAP8AEQBRAJEBEQIQAgAACpZEAgQBBAEEAPQAj4EUAiQARACEAQQCAAAK1lACEgESARIAkgB/gBIAUgCSARIBEAIAAAtWQAAQAhECEQERAREA/wARANEBEIEQghACC5ZAACACPgIiASIA/4AiAGIBogE+AiACAAAL1mAAEgIyAioBJgDzgCICIgImAgoB0gAiAAxWWAIcAROBEgCyAF+AMgBSAJIBEgEQAgAADRZQARICFIEVAREAsABfgBAAkACQARACAAAN1kAAAQI7ASsBKwC/gGsA6wErAq8CoQJAAA4WQAAKACoAKgCuAOsAqgKqAq4CqgGqAAoADlZAACACIgIqAiIBIgD/gCIA4gEqASICIAIOlkAAKgAqACoAJgGjACKCJgImA+oAKgAqAA+WQgJiAhoBAgECAP8AAgDiARoCIgICAkAAERZSAAoAOgHuAKsAuoHqAqoCrgK6AtICAAAR1kAADQAtAe0ArQCrAKuAywINAj0BzQAIABIWSgEqAyoApgIrAiqB6gAmAKoAqgMKAAAAElZAACgAKwCbAIsArwCrg+sAiwCbAKsAqAAS1lAAEQA5A9UBUwFxgdMBVQFZAXkD0QAQABOWRQEVARMBVwFVgV1B1QFXAVMBVQFFAQAAE9ZkABUCFwFfAVcA94BXANcBXwFXAlcCJAAUVkAAFQJVAl+CVQFQANCAyIFHglCCT4JAABUWSABJAkUBawDJAEmAXUBJAGMDxQBJAEgAVVZJAlUCUQJJAUcBQYDBgF8BQQFFAUkCQAIVlkgCSQJEAl+CQAFSANEAyYFJAkcCQQJAABXWSAAJAEUBfwHdAV2BXQFdAV8BRQNJAkgAFpZAAmECawFZAW0A6oBYgNSA0IFSgUACQAAYFkAAAQF/AXuBe4F3APcA+4F7gX8BQQFAABiWSgBKgGqAK4P6gq7CqoKugqmCqYPKgAqAGVZAAAACXwJDAVkBXYDJANMBQQFfAkACQAAZ1kACXwJBAVsBWwFLAN+ASwDLAOEBfwFAAloWQAALgkgCX4FAAUkA5IBFgORBf0FFQkQCWpZAABUATQB/AP0B/YB9AX0BfQD/AGUARQBblkAABoAmg/+Cv4K+w/6CvoK/gr6D0oAAABzWQAAEAgQCdAIMAkeBRICEAKQBXAEEAgQCHRZiAj4BA4DyAE4CAAMNATEA8QCPAQACAAAdlkICPgMDgOIA3AIBAf8AAQEPAgkCOAHAAB4WQAA+AgOBYgDeAwAAEQARAD8D0QARABAAHlZAAj4DA4DiAF4BgAA/AcQCP4JCAj4CAAGfVkACOgMHgOIA3gEAABECEQI9A9MAEQAQACCWQAACAj4CA4F6AMQAPwPBAQEBAQE/A8AAINZAAj4CA4FiAN4BAAAxAdECEQIRAj8CAAGhFmACIQIvAqkC6QKpgSkBKQHpAikCIQIAACGWQAAGAOAAP4PAACQCHAJHgYQA/AEEAgQCIdZCAj4BA4DiAF4AAAERAREBEQERAT8DwAAiFkACPgMDgPoAhgEcAFEAUQJZAlcDMADAACSWQAI+AwOA+gDGAzwA0gASgBKAEgA+AAAAJNZCAj4BI4CyAE4AgAIaASoBT4CqAVoBAgIllkABPwEBwPEAjwAAAwiAqIBfgChASECIASZWQAA6AieBsgBOAIACDwEgAT+AgACjAEwAJ5ZEAjwBA4DiAN4AAgI4A9cCEQI/A9ACAAApVkAAEQIVAbEB2QGbAJEAmIF8gRKBEAIAACoWQgA+AkOBYgDcAQAAAgP+ABOCEgIyAcIAK5ZAAj4DA8D+AgADP4DEgDSB5IIkgheCAAGs1kAANAIPgUQA/gEAADUAwoI+A8IANgBCAK5WQAI+AgOBYgDeAAADEgCSAH+D0gBSAJIBLtZFAlcCVwLXAvcBX4FXAVcB1wFfAkUCQAAxlkACPgJDAb4BQAA/AdEBFQFVAxEDPwHQATJWQAA6AgfB8gBOAbAASQAJAD+DyQA5AMAAMpZCAj4CA4H6AEQBngARA/EAP4PRADEBwAAy1kAAOgNHgOIAXgCAACwD64EoASsBDAHQADQWQAA+AkOBugDEAj8DyQJJAkkCfwPAAgAANFZAAD4DA4DiAN4BAAAkA+QBP4EkASQDwAA01kAAOgIHgXIAzgAIAicCJAI/g+QCJAIAAjUWagIrAisC5wKzAb8BIwCmgWqBKoIqAgAANpZAAj4BA4D8AgMCYAE/gMAAP4HQAicCIQG3FmgCKwIrQquC6wGvASsBq4FrQSsCKQIAADlWRAI8AQeA5ADeAQAAagHfgkoCTgJKAUkAOhZAAj4DI4DcAQEAOwMrAL+AawCrAS8CQAI61kAAPQMjwLkARgA/g+SBJIEngeSBPIEAATsWQAI+AQPA+gBEAD+BwIE8gSeB5IE8gQCBPtZAAD4DA8D6AEQAv4PAgXiBLoFAgT+DwAA/1kAAKIIlArUC8AGpgSUBIwGlAWkCKwIAAABWgAO+AEIBNgFeALYAwgI/gQIA8oEKggABgNaAAj4CA4H+AQAACQJJAm+DyQJJAkgCQAABFrICMgIrgqYC9gG/gSYBpwFqgTqCMgIAAAHWgAI+AQOA8gBOAZQADQPHAAUADIPUgCAABhaAAj4BA4D+AYAAPwPVARWBNQBVAO8BIAEG1oAAPANHgP4AAQIcAlcB+QBZAN8BcAJAAkcWgAA+AyOA3gIAgb+AZII/gf8DwIA/gMAAB9aCAj4CA4F6AMYAMAPvAK0ArQKtAr8DwAAJVoACPgMDgP4AgAKlAj8DxIE/gKQBVYIAAYpWgAI+AgOBcgDOAj4CJQElgP0D5wI8AgABDFaCAj4CAwFiANwCAwJVAfUAVQDVAVcCQAJNFoAAPgMDgP4APIPBACgAfoHogACCP4HAAA2WoAIwgj+CtoL/gaiBsgGtAWUBKwIpAgAAEZaSAhqCQoLYAscBUwFXAUuBSwHXAlECQAASVoAAPgMDgP4AAAITAw0A0YA9AcUCPQJAARaWgAA6ASeAsgBMAC+B2oFagVOBZoHKQAoAGZaAADoCJwGyAEwBoQDvAD8D7wAvASgAwAAdFpAAF4JQgkyC44F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TAVEBQwJAAC/W4AATADkBxQABADWB1QFdAVUBVQF1AcAAMJbAABMA0QI9A9UAEYLFAh0BJQD1AQ0CAAIxFsAAIwAxAfUBbQFtgW0B9QA1AjED4wAAADFWwAIDAjkC7QGtAb2A7QCtAa0BuQLDAgAAMZbAAAMAaQHhATkBE4HpASUBEQEFA9kAAAAx1tACFQE1ANUANQHVggECHQLVAvUCFQIAATMWwAADACEB/wF3AXeB9wF3AX8BYQHDAAAANJbAACMBLwCvAH8BL4IvAr8CLwJvAKMBAAA01sAAIQP9AD0AvQC9gP0AvQC9Ab0BIQHAADbWwAIDAjEC9QL9AfWA9QD9AfUC8QLDAgAAN1bAAAsAQQB/APECX4IfAt8BXwFfAvMCQAI3lsAAAwK5Ar0CvQG9gP0AvQG9ArkCgwKAADfWwAATAlkBbQB9AmGD5QBpAPUAzQFnAgAAOFbAACMAIQF/AX8A/wD/gH8BfwH/AGMAoAA4lsACWwHRAH0DwQA9gn0C/QF9Af0CKwJAADlWwABXAlcCbwKnAt+B0QGvAR8BXwBDAEAAOZbAAAUCNQH/Af8A/4D/AP8B/wH3AcUCAAA51sAAAwBxANUA9QLagvsD2QDRAPUAwwDAADoW4AEtAK0CrQL9AK2DrQC9Aq0C7QKhAIAAOlbAAFMAWQP9AtUC3YPVAtUC/QLVA9EAQAB61sAAAQB9AT0AvQA5gLEAfQA9AX0BIQDAADsWwAIDAjEC9QH1AfWA8QD1AfUC8QPDAgAAO5bAACMCEQI1AP0CtYO1AL0AtQLRAiMCAAA9VsAAFQI9AfUAfQK1AcGAPQHdAt0C3QOAAT2WwAEFgjWB94H1gPHA+4D7gP+B+4HLggAAPhbAAAIACgAaACIAQgICAgICP8HCAAIAAgA+VsACCQMRAKEAXwCAALQABAJEAj/BxAAAAD6W6AAqACoAKgGqAS8AKgIqAjoB6gAqACgAPtbAAAAAUQBVANUA1QBVAlUCVQHfAEAAQAB/FsAAAABPAFUA1QFVAFUCVQJVAdcAUABAAH+WwAIKAxIAo4BaAYIBFAA0AEQCP4PEAAAAP9bQAREBVQDVAH0BV4BVAlUCdQHVAFEAQAAAVwAAKQEpAS/B6QEpAQAANAJEAj+BxAAAAACXAAAAgF+AVYFVgF/CVYJVgnWB34BAgEAAARcgAT+BKoC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/g8QAP4GkAVWDAAA6lwAAPgDAAL+AwAC+AfAAKYPkgiwCMYPiADtXPgDAAL+AwAC+AMAAO4PoAK+AqAK7AcAAPBcAAD4B/8HAAT8BwAAJAVXBdoPVgVSBRAE9lwAAAAO/ARcBVwHXgVcBVwFXAFcCUAHAAD7XAAA+AP+A/gDAAAoBYwFygKIAi4FaAQAAANdAADwA/4D8AMAAFQDxAD+B8QAVAFEAgAAB10ACXwFGAFYCVgJXA9YAVgBWAUYBXwJAAAOXfgHAAL+AwAC+AMAALQDrAKuCzQI9AcgABRdQAAsAOgPWAVYBV4F+AdYBVgFWAVcBQAEFl0ADP4DDAisCqwKrgrsDqwKrAqsCq4KCAgXXQAAAAD2DxQAVAZ2BtYHdAZ0BhQI9gcAACldAAAMDOwDqAnoDw4ACAjoB6gCqArsBwAALV0IAWsBWgHKB0oBSwECDPoDSgDGD0cAAABKXQAA8AP8A/ADDADsBgwB/A8MAWwCqgQABEtd/AMAAv4DAALwBf4Dyg+qCq4KqgruDwAATF0gAOwPKAUoBegPDgDIDCgCqAEoBqwIYABQXQAA5g8cANwJXAn+D1wNXA2MCPwHBggABmldEACWD/QA9AD0B/QF9gX0BfQH9AiWDxAAi10AAAAA8Af+A/AJ/ARcDV4DXAtcCUAHAAC6XSAAkwCqAqoEsgcHAP4FrgWuAa4F/wUACM1dIAl8C3gFeAV4Cw4A+ATYA/gD3AbQBvAC3V0ACAAM/AMAAAAAAAD4BwAAAAAAAPwPAADeXQAAcAgABv4BIAAAAP4HAABwAAAA/g8AAOFdAAhECMgHAAT4CAQLcAiMCSAK2AgECwAI4l0AAAAF+wWoA6oD/Q+oAaoDrgX9BQAFAADjXQAAAAn+BagFqgP8D6gBqAOsBfoFAAkAAOVdAAQEBAQEBAQEBPwHBAQEBAQEBAQABAAA5l0AAAgMCAPICHwISghICMgPSAhICEgICAjnXQQCBAL8AwQBAAEEAHwERAhECEQMxAMAAOhdAAAAAP4PkgSSBJIEkgSSBJIE8gUCBAAA6V0EAgQC/AEECQAE/AMEAHQABAD8DwAIAAbrXQAFhAR0BIQEBAT8BwQFhAR0BIQEBAUAAO5dgAioBKoDrgioCfgJqA+uCaoJqAmACAAA8V0AAAAA5AckCCQIJAgkCCQIJAh8CAAHAAHyXQAA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dAbUBQYIVAr0C1QKVAoAALVeAAz8AwQAVAD0B9YC1AfUCtQK9AtUCFQEtl4ADvwBBAQkByQA9A6mAKQO9AAkAiQMAAC3XgAG/gECBKoCqguqCPsHqgKqBvoFIgkAALheAA78AQQA9A/0A/QD9g/0A/QL9AukDwQAwV4ADPwDBAj8B6wGrAL+CwQA9AsECPQHAADDXgAM/AMECEwF/ANOAUQB3AdsCWQJFAUAAMleAAz8AwQIdAV0A/QPdgH0D3QD9AVUCAAAyl4ADPwDBAj0D7QItAb2DAQA/A8MAPwHAADTXgAM/AMEAPQLvAu8D/YDBAD8DwwE/AMAANZeAAT+A4IAlgiOBmYHvwZiBW4FRgKeAIIA314AB/wABAL0A7QDtAe2A/YHBAb8AawE/APgXgAM/AMMAOQPvAKmC+4PRAj0BSQD5AwAAOJeAAz8A0QALAusCn4ERANsBfQHtAkUAAAA414ABv4BAgjqBfoF+wX7AfoB+gPqA+oFIgTzXgAAgA98AAQLfA/+DyQEdA10CXQDdAUAAPZeBAi0BKwDZAQABfQJBAkECfwJJAkiCSAJ916ECDQHrAVECAAKJAokCvwLJAoiCiAKAAD6XgIIcgwuA+IECAWqCaoJ/wuqCaoJvgkICf9eAAAQABAA/g8QBBAEEAQQBP4PEAAQAAAAAF9ACEQIRAb8AUQARABEAEQA/A9EAEQAQAABX5AIkAiQBMwDiwCIAIgAigDqD4wAiACQAAJfAAAACR4FqgMqASoBKgEqAaoPLgEgAQABA18ECSQJJAW0AywBJgEkASwBvA8kAUQBBAEEX0AJVAlUBVQDVAF8AVQBVAFUD1QBVAFAAQpfAAl6CTgFPgN4AXoBEAEsAbYPNAFMAQQBD18ICEgESATIB0gESAQIAn4AiAMKBAoICAYTXwAAAADyAJIAkgCSAJIIkgiSCJ4HgAAAABVfAADEAKQIpAikCLwHAAAAAAAA/A8AAAAAF18AAIgI6AioBvwBqACoAPwPqACoBLgDAAAYXwAB5AikCKQIvAcAAAAH+AQEBIAEAAcACBtf8giSCB4HQAD8ByAIEAj/CRAICAn4CAAGH18AAAAEyASqAqwCqAH4D6gArASqBLgDAAAgXwAA8giSCJ4HAABACP4PQATQBEgBRgZACCVfBAHkCKQIvAigBxADzAgICPgPCADIAAgD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iAAACqIJcgQqA+YIIg7gAQAAbWKIAIgI/weIAEAIAghCDv4JQghCDv4JAAhuYggBiAj+D4gAIAhQBE4DwABCCE4I8AdgAG9imACYCP4PWAAACPgPAAgACP8PIAggCCAIcGKIAIgI/g+IAEAIEATQAz4AkAcWCBAIEAZxYogAiAj+D0gAAAf8AMQEBAU8A5AEcAgAAHNiiACIDP4DiAgADvwBZASkBSQCpAVkCAAIdmKAAIgI/g9IAAAISARIA/4ASANIBEgIAAB5YogAiAj+D4gAAAD+DyAEAAD+ByAIGAgQBnxiAAGIDPwDiAgADPwDBAD0BxQIFAn0CAAEfmKIAIgI/g9IAAAIEAQ+AtADEgXUCBQIEAZ/YgAAEAQQA/QABAqkCvQHrAIMAuQAIAMQBIBiiACICP4PSAAACGgEqAU+AigF6AQoCAAAhGKIAIgI/g9IAAAIeAgABP4EAAKMAVAAAACKYoAAiAj+B0gAAAD8B0QIRAh8CEQIRAj8CJFigACICP4HAAD8BwICAgD8DwQABAT8AwAAkmKIAIgI/w9IAAAAIggqCOoPNgCmAGIAAACTYoAAiAj+D0gAAA78AQQA/A8CAP4AAg8ACJViiACICP4HSAAACN4EQgVCAt4FUAgICAAAlmKIAIgI/g9IAEgAAAEiAUwBAAH+D4AAgACXYgAAiACICP4HSAAADOgDLgAoAOgHCAgABphiiACICP4HSAAADv4BIgAiACIA4g8iACIAmmKAAIgI/g9IAEAIBASkA3wA5AckCCQIIASbYgAAiAj+B0gAAA//APgHAAn4CA4K+AkABJxiiACICP4PSAAADIgDfgioBSgC6AUoCAgInmIICYgI/g+IAAAM/ANEAEQAxAFEAnwMAAigYogAiAj+D0gAAAD8DwQIFAvkCLQJBAoACKFigACICP4PSAAAANgHhAiCCEQICAgwBiAAomKIAIgI/g9IAEAAEADIBycIJQnICBAGEACkYogAiAj+B0gAAAz4A0gASgBKAEgA+AAAAKViiAiICP4PSAAAAP4PIgDyDDIDMgXuBAAIq2IIAYgM/gOICAAO+AHIBX4GSAXIBFgIAACsYoAAiAj+D0gAAACwD6wEogSgBKQEmA8gALFikACQCPwHUAAAALAHrgioCOgJCAn4CAAGtWKIAIgI/g9IAAAA/A8kBCIAPgziByIIIAa5YogAiAj+D4gAQAQIAkgB/g/IAEgDSAQAALxigACICP4HiAAAAPwBpACkAPwPpACkAPwBvWKIAIgI/gcIAOAPkASQBP4HkASQBPAPAADCYgAAkAj8B0AA6AyoAv4BqAD+D6gAuAcAAMRiiACICP4PiAAIAIAIiAiKCPoPiAiICAgIxWKIAIgI/g9IAAAI/AkkCSQJJAkkCfwJAAjGYogAiAj+B4gAAAz8AyIAogDiDyIBIgIAAMdigACICP4HSAAAAP4DIgKqCiIKIgb+AyACyWKAAIgI/g9IAAAEKATIBQoECAfoBAgEAADLYgAAiAj+B0gAAA/+AMgHAAn+CggK+AkABMxiCAGICP4HiAACACwBIAH+DyABLAEiAQAAzWIIAYgI/geIAAAA+A+IBI4EigSIBPgPAADQYogAiAj8B0gAAAi8BKQCpAGkCKQIvAcAANJiiABICP8PSAAAAP4PkgSSBJIEkgTyBAIE02KIAIgI/g9IAAgBgADkD1wERAREBMQPAADUYogAiAj+D0gAAAyIA34IqAUqAqoFaggICNZigACICP4HiAAgAJAAzgdICOgLSAjoCwgI12IAAIgI/g8AADgD5gIwCxAF8AMeCPAHAADYYoAAiAj+D0AAEADIAy4BKAHoCQgI+AcAANligACICP4HSAAAALwHIAT+ByAEIAS8DwAA2mIAARgJ/geYAAAImATUA5IAkADUD5gAoADbYoAAiAj/B0gAAACiD5oEhgSiBKIEngcAANxiAACUDJQC/AGSAAMAKAEqAf4PKgEqAQAB3WKIAIgI/gdIAEABFAFUAfwPVAFUAQQBAADfYoAAiAj+D0gAAAT+AwABvAwAAsABPgEADuBigABICP4HYAD+DIgDcAT8CQQI/AsACoAJ4WKIAIgI/g9IAAAO+AEIBIgHbgQIBQgFCA7iYoAAiAj/D4gAAA6QAX4MEATyB5QIVAgQBONigACQCPwHkAAABOgCuAqsCOgPiACIAggE5WKAAIgI/gdIAAAM/gOSAJIA/g+SAJII/gfmYoAAiAj+B4gAAASSBJYEkASYBJYEEAQAAOdiCAGICP4PiACAABgASAhICMoPSABYAAAA6GKAAIgI/geIAAACHAnQBH4FUALUBVQIEAjpYogAiAj+D0gAAAKkApwC1A+cAqQCJAIAAOxigABICP4PSAAAAJIPkgj+CJIIkgiRDxAA7WKAAIgI/g9IAAAEUATQBxAE/AEQBhQMAADvYoAAiAj/D0gAAAnSCCIK+gsmCNIIEgkAAPFigACICP4PSAAACIgE/gKIAIgA/gKIBIAI82KgAKgCagJsC3gL7gcoAygDbgKoAqAAAAD0YgABiAj+B4gAIAgYCSQJ4g8kCQgJMAgAAPdiAAEQCfwHkAAAACgBqAP8CqgKuAqoBiQA/GIAAQgJ/gfIAAAIiQT6A4gAiAD8D4sAgAD+YogAiAj+B0gAAACYD4QEogSiBKQEiAcwAP9iCAHIAfgB/AX6BfoD+gH8AfgB+AGIAQgBAWOQAJAI/AdQAAAAqAKoArwIqAjoB6gAIAACY4AAiAj+D0gAAAgkCSQJvg8kCSQJIAkAAAdjiABICP4PSAAAAN4HZAVkBWQFYgXiBxgACWMIAQgN/gMICEAIXAjEBXcGRAPEBFwIAAAOYwABEAn8B9AAAACoArgDrAqoCrgKqAagABFjgACICP4PSAAACYgE/gMAAP4HQAicCIQGFmOAAEgI/g9AAAQAVARUC0YJ1AhUCAQGAAAZY4gCSgIsArgKqgrsB6gCiAI+AkoCSAIAABpjAAAUAtQD/gOUC4AHtAOeA4QDPANAAyACH2MAAQgJ/gfIAAAIqAiIBv4BiAOoBIgIAAAgYwAAiAj+B0gAAAikBKYDvAC0D8wIrAiABCFjiAGICP4HSAAABC4FIAU+BSAFKAXmDwAAI2OAAIgI/g9IABAAWAlWCfQHXAFUAfABQAAkYwAAiAj+B0gAAAhEBEwDNgAkAFwPRABEACVjAACICP8HAACWAtICsgKaAtIPkgKWAgACKGOAAIgI/gdIAEAJLAUrA+gDKgMuBSgJAAgqYwAAiAz/AwAIkgb+AZII/gf8DwIA/gMAACtjgACICP4HSAAgCBwJYAn+DyAJHAkgCUAAL2OAAIgM/wOICAAO/gHCD1IE0gVSAVIOAAg6YwAAiAj/D0gAAgw+A+IEAAgiCf4JIgkiCT1jgACICP4HQAAQCPgIlASWAvQBnAeUCPAIQmNIAEgI/g8oACAAqge+BKoEqgS6BKIHIgBFY4AAiAj8B0gA4A+kArQC9A+sAqwK5AcAAEZjgACICP8HAAD+DwIEUgT6BVIEAgT+DwAASWOAAIgI/g9IAAAMvAMkBOQPpAikCLwIAAhMYwAAiAz+AwAIvAakAbwIAAf4AQAI/gcAAE1jiACICP4PSAAAAX4BagFqAeoPagF+AQABTmMIAQgJ/geIAAAA4g+sAqACvAKgCuwPAABPY4gASAj+D0gAAAS+BKoEqgeqBKoEvgQABFBjiACICP4HSAAAAO4PqgKqAqoKqgruDwAAVWMIAYgI/geIAAAA6A+oAqgC/g+oAqwK7AdcY4gASAz+AwAIvASsBawG/gSsBqwFvAgABF5jgACICP4PSAAACJQElgLUAZQIlgw0AwAAX2OAAIgI/gdIAAAI4AkuBCoCqgEqBC4I4AthY4AAiAj+D4gAIASYBSQEogUkBAgH0AQAAGJjiAz+A0AIEAj4BJQClgH0AZwClAT0BIAIY2MAAQgJ/geIAAAG/ASEBpYEhAa8CIAHAABnY4AASAj/B0gAAABqAr4Cqw+qAuoCqgIAAGhjiACICP4HSAAQAEwHUgV6BVIFRAVIB1AAbmNAAEgI/g9IAAAH/gAyB7IE8gSyBL4HAAByYwABEAn8D5AABALUB3AJXA1QDVQO1AhAA3ZjAACICP4HCABACfQJVAn8D1QJ8glQAQAAd2OAAIgM/wNICAIIqgaqBKoE/w+qCvoKIgh6YwABEAn8BxAAQAQoARgJTA9YASgBSA1AAHtjgACICP4PSABABwgAJAcqCCIJZAgoAwgEgGMAAIgI/gcAAPwPFAD0DwAAFA7qAQgGOAiCY8AARAb/AQAM/gMCAIIPggT7BJIEkg8CAINjgABECP8HBABgALUHtQD1D7UAvwTgAwAAiGOAAIgI/gfIAGAIaAikBKoHogS6BmoFAAiJY4gI/gdIAAAC+AKoAqgCrg+sAqwC/AIEAoxjAAAcAs0C/wL8Cv4H/AL8Av8CjQKcAgAAj2MAAQgJ/gcYAIwCqgLoA6gCqAqICPgHAACQY4gAiAj+D0gAAADQD0gFBgVEBFwFxA8AAJJjiACICP4PSABAAAgBKAHWDvwHKAEoAQAAlmMAAIgI/geIAAAA5A8UAMYIdAWkA+QEJAiYY4AAiAj+BwAA/g8KAOoOigjqD4oI7g4AAJljAAEICf4HiAAAAqwKpArqB6ICqgLqA4AAm2OAAJAI/AcAACgFvgcoBQAA/A9AAMAAAACgY4AAiAj+D4gAAAT0ApQIlgeUAJQC9AIEBKFjgACICP4HSAAABJQChAHUD4IBsgKKBAAAomMAAQgJ/gfAAAwEpAKUAcQPlAGkAqwEAAClY4AAiAj+B0gAAAikCqwLpgSkBrQFpAigAKdjAAGICP4PSAAMCKQIlAiGD5QIpAgMCAAAqGNIAEgI/g9AADAA/A+qBKgE/geoBKgEAASpY4AAkAj8B1AAAADoA7gCrALqB6gKuAroC6pjiABICP4PSAAAANQHXgVUBVQFXgXUBwAAsGMAAJQI/AeyADgG5gH8AxAIkgj+B5IAgACyYwgBCAn+BwgAAAG+A+oFqgSqAqoIvgcAALdjAACICP4HSAACDvgBTgcAAP4PAgD+AwAAuGMAARgJ/geYAAAC8ANSA1QD8A9cA1ID8AO6YwAAiAj+B0gAQABYCrwKWgkYBTwEWAKQAMljgACICPwHSAAACXQFHANcD3wDFAU0CRAAzWOAAEgI/g8oAAAIXAl8BdwDXgF8BVwFXAjPY0AARAT/AyQAAAD0D5QElwT0B5QElwT0D9BjAAEICf4HiAAADL4CqgSqD6oKqgq+CoAI0mMAAEQE/wNEAAAA6g+qBAoE/gcJBOkPAADWY4gAiAj+B0gAAATsB2wFbAVsBWwF7A8gAtpjBAGEDP8HxAAABt8DVQlVBVUDVQlfBwAA22OAAIgI/geIAAgIeAk2BZQDPANQBXAJAAjhYwAAkA78AQAM/AM0CLQK9Aq0D7QKvAoACONjAACICP4HQAAcD7AAsA/+ALAPsAC8DwAA6WOAAIgI/g9IAAAA/gdoBUAFfgVoBeQHFADqY0AAiAj+B0AAEgH+D0IAGgwAA/4AAAM4DO1jAAEICf4HiAAAAP4G6gSqBaoIqgi+BwAA7mMgAEgI/gdIAAAC+gK6AroC+g+6AroC+gL0Y4AAiAj+D4gAAgRWAvIJ1gbSBNkHVQhACPpjiACICP4HSADAAIwOpASsBOwHogSyBKoO/WMAAIgM/wNACB4IwAteCEAHVgjUCwQIAAQAZIAAiAj+B0AAEAC4BHYENAV8CbQKsACAAAFkAABICP4HAADyD0IAWAeqAtoCAgv+BwAAAmRAAIgI/g9IAAAIqgqYC94EmAaqBaoIgAAFZAAAiAj+B0AAGgj8BTgEugc4CO4JCggABg1kiACICP4PSAAACOwF7APsAewB7AXsCQAID2SAAFAI/AeQAAAAeAN4A3gBfgl4CXwHeAETZIAAiAz+A0gIAAzVA1YIfAlUD1cJVAkAABRkgACICP4HSAAAAKYJWglSCdYPWg1WD9IPFmQAAAgJ/geIAAACVArECqYKng+MCoQKAAAcZIgI/gdIAAAIvAi0CaAG/gSgBrQJvAgACB5kgACECP8HJACAD1oAWgdbBVoHWgDCDwAAKmTAAEgI/gdIAAAH/AB0BnUF9gV0BXQHFAAsZAAAEA78AYAM+AN+CfgHAADeDUICngUgCC1kAACICP4HSABAAG4HVgVcBWQFTgdEAAQANmRAAEgI/A8gAJAPaAB4B3QFcgV0BWgHEAA6ZAABBA3/B4QADAj/BasDqgH/BasDqg6CAERkAACIDPwDKAiABLwGvAG8BbwGvAakCQAARmSAAIgI/gdAABwFVA1cC9QJXAVUBVwJAABHZIAAiAj+B0gAAAasBKQE6geiBKoEqg4AAEpkAABICP4POALIATgBMAD+D6gE/gesBAAEVGQAAIgI/geAAIgCBAK0Au4OxAIEArQCgABYZIAAiAj+BwgA4A8UAFwH9gVcBxQI9AcAAGdkAABICP4PSABMAOgHaAVuBegHaAVsBQAAaWQADPwDBAC0A7QLtguEB7QDtAN0A3QDVAJ4ZIAASAj+D0gAAAl0CXYH9AF0A3YFdAkECXlkAAFEA3wD/AN+C/wL/A9+AvwCfANEAwABg2QAAvwD/AP+C/wLvAfYA9YDUgN2A1QCgAKHZAAAiAf+APAPXgD8B3AA9Ac6BsUBPAYABJBkkACQCPwHkAAYCPwL2AbeBtgC/g+YAgACkWSAAJAI/AcAAJgD/AvYC9wH2AP8AxgDAACSZIgI/gdIABAA9A++ArQK/g8QCO4GiAN4DJVkAACQCPwHAAD8DVgB/AUAAPgPJADkDyQAnmRICP4HWAAACPQK9Ar0CvYP9Ar0CvQKEAikZEAARAz/BwAA8g+/AtoPEAg4BMcDfAwAAKVkAAAICfwHCACgC7wK5A5ACygF/AeoCQAAqWSAAIQE/wNEAAAE+gFWCVMPVgH6ATIMAACrZAABkAj8B1AAAA38ASoB6A0oAegNKAHoDaxkAACICP4HSAACA9YPHgM2AK4DrQcoCwAKrWSAAIgI/gdYANQAVAe8BbwHlAW6BdIHkACuZIAAhA7/AWAE4Ae/BrUG9Q91BHUD/wVgBLBkAACICP4HoABOCfYFVgVAAU4F9gVWBUAJsmRAAEgI/g9IAAIJeAVuA+gBbgN4BWoJAAi1ZAAAiAj+B4gAAARcBd4FQA9cBU4FXAUAALxkAABIB/4AAA78ASwB3AesA38CpAMVBAADv2QAAIgI/gcIAOgMtAL0BBIA8gy0AuQECAjBZEAASAj+BwAAtAxkAwQA+gdUBfwHVAUABMJkAACICP4HCACcB8wFnAW8B5wFzAWYBwAAxWQAAIgI/gdAAHwEzAf8B/4H/AfMB3wEAATHZAAASAj+ByAAvgL6Ar4Cug++AvoCvgIAAMpkQAT8BPwH/gf8DvgPkAfuBqIG5gaoBAgBy2SAAEgI/gdIAAAAmgf8BdgF3gfYBf4FigfNZAAAkAz8AxAIwAW8BfQDlA/0A7wF4AkAAM5kFAA8Ar4DuAPOC7wLhA+oA7YDlAMsA0QC0mQAAYgI/geIAAgOxAGSB9oF8gO0CcQPAADUZIAAiAj+D0gAGA74Aa4MvA/MD7wPyA8AANpkgABICP4PAAT4AxgA2AX+A3wPbAFsBgAE4GQAAIgI/gcIAGAM1APkAr4CvAK8AuwPBADmZAAACA3+AwgJLAmUAdQJvg+0AfQBHA0AAOxkAACICPwHAABeDdQDVAwAAywE9A88CWQI9GSAAIgO/gEADPwDRAj0C/QL9gP0C9QLAAD6ZAAAiAz+A8AIdgfKDO4HCgBuBqoKrgoAAP5kAAGICP4HCADCCH4K3gdeB14H/gvCCgAIAGVUAMwCXgJMA+AL5gvUB8IDSANeAswCVAAPZQAAmAz+AwAI6AdmAvQPAADeB9QL9AoAABJliAj+B0gADAjeC14IXAZMAV4EXgisCyAAFGUAAIgI/gcAAP4H9gR+A/AH7gP2CP4HAAAYZQAAiAj+B0gE+APsD/wJxgH8B+wF/AkAABxlQAAkBP8DIACLD34B+gJ7BvoBegT7ByAAHWUAAJAI/AdQAMQD/AL8DzwA/AP8A+QHIAIkZQAAAABICP4P/gv0B/4O9A+uBPoHqAQAAC9lCAgoBGgEqAQoAz4CKAOoBGgEKAQICAAANmUAAPwDAAEAAf4PAAAwBG4EiAPoAhgECAg5ZQAA5AEkAiQBfAVgDDAEzgIIAegCGAQICDtlBAEEAfwBBAlkCRAEbgKIA4gCeAQICAAAPmUACAgG+AEqCMgHIAAQDO4CiAN4BAgIAAA/ZQQE9AMEAvwDJAJkCDAE7gIIA+gEGAgACEVlCADID0gEfgTID2AIPATKAogDeAQICAAASGUICKgEigKMAygEQAAwDM4CiAN4BAgIAABMZQAAkg+SBP4EkgSCDyAAFAzqAogDeAQICE9lQAD4AVYB9AVUBfQDYAkeBOUCxAM8BAQIUWUIAmgJCAn+D8gACglgCH4EiQPoAhgMAABWZQAEVALUAf4E1ATUA0AAfgaIAWgCGAYABFdlAAj8BVQFVAH8BWAAOAzMAogDeAQICAAAWGVQAlgJVAjyB0QAZAswCO4ECAPoBBgIAAhZZQACVAJUCd4P9AFYCTYIfASLA8gCOAwICFtlAADQBRgE1AQWA4gIMARuAogBeAIIDAAAXWUAAPYP0AH+D9AB9g8ACD4EyQPoBBgIAABeZQAA7g/gAX4CoAnuD0AIfgSIA+gEGAgAAGJlAAAIAvoDqgKqAv4PAAAwDO4CiAN4BAgIY2UAAOoPrwKqAq8KygcgABoMdQLEAzwEBAhmZQgC+ArYCtwO2AN4CmAI/gQIA/gECAgAAGxlRAD0A1YB1AkWDPQDMAhuBogB6AIYDAAIcGWgCKoKmAf+BJgHigggCD4EyQOIAngECAhyZQAA9A/0A/YCdAn0BwAA4Aw+AygD6AwACHRlQABcCDwIvg68CNwP2Aq2CrQKTAhECAAAdWUAAPoPDgP7Ag4J+gcQAD8MxAN8BgQIAAB3ZQAEvwKrAf8FqwW/A5gIPwTCA3ICDgwCBHhlCAl8C3wL/gV8BXwLYAkwBO4DeAQICAAAg2UAAF0JfgX/B1QDXgFoAOYDVgVcBWQFQASHZQAACAgICBgEaASIAgoBiAJoBBgECAgICIllIgQSDNIDVgFaAUsBSgFWAVYB0gcSABIAi2VkAGQPZAFUAVwP1gFUAVwPZAFkCWQHYACMZQgIaASOA3wCAAjUD/QHEAD+AxAEFg4AAI5lJAgkD6QAHAJUCVYPVAEsBSQApA8kAAAAkGWkCKwIrASsBZ4GwAKAAr4GrAWsCKwIoAiRZQAAJAT8AwAIKAbKATgCAAhECPwPRAgACJdlAAIQAiQBJAFIAQgBAAH+DwABgACAAAAAmWUMAKAD/g+gAKwAAAIkAUgBAAH+DwABAAGcZQAEWANUCPIPVAAEAyAAbAEAAf4PgAAAAJ9lQADIA3wF+AT4BXwFAAQoAIAA/weAAAAApGUAAAAO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rAL8BAQEAAB+Z4gBSAD/B0gAgAQ4BIYHYAQBBI4FMAYAAH9nCAOIAP4PiAAADPwDZAikBSQGpAVkCAAAgWeIA0gA/g9IAAAMhAN8CIQFNAIsBeAIAAiEZ4gBSAD+D0gAAACcAWoBCAnICQgM+AMAAIlniANIAP4PSACIAAAIRAhECPwPRAhECEQIkGeIA0gA/w9IAIgAAAz8AyIAIgDiDyIAIACVZ4gDSAD+D2gAgAg4BIgDfgDoBwgIOAgABpdnAACIAUgA/w8oACgCgAFIAP8PaACIAwABmmeIA0gA/w9IAKAIEARuBIgDyAI4BAgIAACcZwAAgAS+BKoCqgGqAf4PqgGqAr4EgAQAAJ1niAFIAP8PSACICCAEqAQoBT4CKAXoBAgInmeAAUgA/wdIAAAH/gAABIADfgCAAwAEAACgZ4gDSAD+D0gAAAEkARwBBgGEDzwBIAEQAaJniANIAP4PSAAAAPwPBAgUC+QItAkECgAIo2cAAAQBtACUBFQEfglUClQKlAq0AAQBAACqZ4gDSAD/D0AAEADIByQIIwkkCcgIEAYQAKtngAFIAP4PKABAD/wABAb0AQQC/AcADAAAr2eIAUgA/g9IAEAAEA+QBP4EkASQBJAHEAC2ZwAApAiUBI4ChAHcD4ABvAKkAqQEvAQABLdngAFIAP4PSAAADv4BCAzwA/wPBAT8DwAAxGeAAUgA/g8oAAAA9A8UAJQBfACUCRQI9AfPZwgBiAD+D0gAAAD4D4gEjgSKBIgE+A8AANBnAACEBIQEvgKsAewHrACsAb4ChASEBAAA0WcIAYgA/g9IAAAA/g+IBIgEiAT+DwgAAADSZwQJZQkRBRIDBAPEDx8DJAMkBSQJFAkAANNniASqBKoCgAKkAbQPjgGEAvwCwATABLAE1GcACVAJVAU0A3wD3A90AxwDFAU0CRAJAADYZ4gBSAD+DygAKAGAAPQPTAREBEQExA8EANxnCAOIAP4PSAAAAPwPJAkkCSQJJAnkCQQI4GcIA4gA/g9IAAAAWABICEoIzA9IAFgAAADlZwAASAgoCKgPWA1cDUgNWA2oDygISAgAAOxnAAAECPQEtAKUAf4PlAG0ApQE9AQECAAA72eIA0gA/g9IAAAA9AMUAfQJBAj8BwQAAADxZwAAiANIAP8PyAAICQAIigj6D4wIiAgICPNngANIAP4PAAD8CQIF+gIAAPwPBAD8AwAA9GegBL4EoAK/AqQBgA+fAaQCpAKkBKIEkAT7ZwAAJAgUCNQPrAquCqQKrArUDxQIJAgAAP9niAFIAP4PSAAAAOgDKAAqAPwPKAAoAugBA2iIAUgA/w9IAAAP/AAUDvQBUghSCNIHAAAEaAAEUARcAlAB0gDUD9AAUAFYAlQCUAQABAVoAAOIAP4PAAT+A0II/gdAAP4HQgD+D0AAB2iIAUgA/g9IAIgEIAKkCSQI5A8kAKQBIAYIaIgBSAD+DygAQAgQBFAEfgTIAyoFqgigBgtokANQAP8PUAAEBnwBRwjkD0QARAMEBAAAD2iIAUgA/g9IAEAEEgSWBJAEmASWBBAEAAARaAADiAD+D0gAAAbkARwDQADQCRAI/gcQABNoiANIAP4PQAAQCAgJJAniDyQJCAkwCAAAFmiIAUgA/g9oAPoPigV+BAoEfgSKBPoPAAAXaAQJdAlUBVQFfAPUD1QBfANUBVQFdAkECSFoiAFIAP8PSAAICGAEGATYAg4ByAIoBEgIKmiIA0gA/g9oAIAEEAROA8gA/g/IAUgCQAQ3aAgBiAD+D0gAAAFKAUoB+A9IAU4BCAEAADhoiAFIAP8PSACICCAEaAWYBE4CKAOoBIgIOWiIA0gA/w9IAAAA/g9SCNIIUgFSBn4FAAk8aMQBJAD/DwQATADkD2cEWwRaBGYE4gdAAD1oEARUAlQB3g9UAVQJEAT+AhAD0gQUCAAGPmhACGQJFAUEBTwDBg9EATwDBAUUBSQJAAhCaIgDSAD+D0gAAAgkCSQJvg8kCSQJIAkAAENogANIAP4PQAAMCYAE/gMAAP4HQAicCAQFRWiIA0gA/g8IACAO+AGWB1QIXArQCRAIAARGaIgDSAD+DygAQAD8DwQIVAr0C1QKVAoACEhoAACUCZQFtAVUA1YPVAF0A5QFlAUUCQAITGgAAAAJeAVYBVgD3g9cAVwDXAV8BQQJAABQaAgDiAD+DwAA/A8EANQDVALUAwQI/AcAAFFokAmYBV4FfgMWAYYPVgFaA1oFsAWACQAAU2jEASQA/w8kAAAE/QUlBSUFJQUlBf0FAQBcaIgDSAD/D0gAyghCCMQFcQZWAkAF3ARCCGNoiANIAP8PSAACBCwFIAU/BSAFKAXmDwAAZWiIAUgA/g8oAIAIVAQ0AxwAFAAyD1IAgABmaIgBSAD+D0gAAAF8AQIBkA8+AUgBRgEkAGhooASUBJACvgKAAagPpgGWApQCjASEBAAAaWjEASQA/wcUAAAO/AEEBCUE9QckBCQEAAB2aIABSAD+BwgA4g9SAVoB+g9WAVIJ8gcAAH9oiAFIAP4HSAAAAX4BagFqAeoHagF+AQABgWhMCWAJEgVYA0IDMg8OAUIDQgU+BQwJMAmFaBABkAD8D5AAoATYA6wCqALoC6gK6AeAAoZoAAOIAP4PSAAACSgN/gMAAPwPBAD8AwAAk2gIA4gA/g9IAAAAVAFEAcYPdAFEAUQBAACXaIgDSAD+DwAA/AisBqwG/AWsCKwI/AgAAJ1oAAAgAPwPAgD4AwAAqAauAJQPtACsAqQEomiEAUQA/g8kAAQA8QdWAVABXgFQBfYHAACmaAAAEgmKBF8ERgVqAkgCSgHfAEYACgAQAKdoiAFIAP4HKAAgAKoHvgSqBKoEugSiBwAAqGhACCoJGgV+BRkDqg8AAR4DQAVABX8JAAmtaIADSAD+D0gAQApYCR4FygaYBp4JqAgACK9oiAFIAP4PSAAABOoErAL4D6gArgS4AwAAsGgAA4gA/w9IAIAM6AOIAOgP/gQIB+oIIASzaIABSAD+D0gAAAy0AywApw8kALQPIAQAALVoAAA0CAwE3gNMAVQBQAJMAN4HDAgUCCQGtmiIA0gA/w9IAAAP/gAKAqoC6gdKCU4JAATAaAgBiAD+D0AAEAUIBSQEogQMBpAFUAQAAMRoRAlUBdQFzAPMAe4PzAHMA8wDzAVUBVQJyWiEA0QA/w8kAEAAngeqAKoA6w+qAL4EgAPLaIgBSAD+D2gAQAkIBf4FWAFYAf4BCA0AAM1okANQAP4PUAAAAPwPVAlUANQHfAkABQAA0miIAUgA/g9IAAAAbAI8Aq4PrAI8AmwCoADVaIQBRAD/D2QATAZEAVQE1wdUAEQBTAIAANhoAAD0DBQC/g8UAfQIYAQUAv4PFAL0DAAA2miAA0gA/g8ABP4Dkgj+BwAM/gOSCP4HAADfaIgBSAD/D0gAAAT8BKwCrAH+D6wBrAL8BOBoAAgYCQoFfAVYA94PWANYA34FCgUYCQAA42gIA4gA/g9IAIAIFAZUAP4PVABUBXwFEAjuaAAApASUAtQPjAKMBD4EjALUD5QBpAKABPFogANIAP4PSABACjQJ1AbeBJQGtAkUCAAA9WgAAMQBJAD/DyQAAAPfAPUH/wfVAF8DQAL6aIgBSAD+B0AAHAD8B/QHVgVUBWQFDAcAAAVpiANIAP4PCAAgALQHrAKuCywI5AcgAAAADWnIACgA/wcIAOAPBAT8BVwFXgVcBfwFBAQOaYgBSAD+DwAAMAD8D6oEqAT+B6gEqAQAABJpgAFIAP4PCAAgDf4DKAiACRwE5AN0BgwIHGmQA1AA/g8QAPAJOAk0BfIDNAM4BfgJEAgtaQAAkAD/DwAA/g8SAO4BAAD4D68C6A8AADBpgANIAP4PAAD8A1QC/A8AAP4PAgD+AwAAP2mAAVAA/AcAAKgA+A94BXgFfAX4D3gAgABKaRADkAD8D5AAAAj8B9QB1AXUA9QJ/AcAAFNpgAFIAP4DAAz+A0IAqgT6B6oEQgT+AwAMVGmAAUgA/g8AACwJfgkMB6ADHgVCCT4JAABaaQAAVAhMBl4DVATAD1QJTAleCUwI1AgACF5pAAOIAP4PQAAcCFQE3ANUAVwJVAlcB0AAY2nAASQA/w8UAIADfwDlD1UFVwVVBfUPBwBtaQgJagVsBXgDbgHoD2gBfgNsBWoFCAkAAHVpiANIAP8PCADiCaII7gj6C0IIkglyCgAAd2mAAUgA/g9IAAAAvA+oCoAKvgqkCqQPFAB8aYABSAD+DygAiAiqCpgH3gSYBqoFqggAAH1pAACkBKQEgAL8AdYH1AH8AYACrASiBAAAgmkAA4gA/g8AAPwHVAJ8CSAExAN8D0QIRASEaQADiAD/D0AAHgjACV4EQANOBtQLBAgABIZpgAFIAP4PCADwB7gC9A8WANYDBAjoBwgAlGkAA4gA/w8AAPwHVgJ8BwAA/A8EAPwDAACVaYgDSAD+DygADAGUD0QJJglECZQPLAMAAJtpgAFIAP4PKACACOwFvAOuD6wDbAUkBQAAnGmIAUgA/g8IAEAIXAbcAVYJVAlUCVQHAACoacQBJAD/DyAAggBKACYA9w+iAqoCqgIAAK5pAATiBOwErgKiAKAPsgCoAqYCqASiBAAAtGkAA4gA/g/IAAAAvA+iCpAKpA+cCoQKvA/LaQAAyAMoAP8PAAD8D74CvAL8A74K/AcQAs1pyAAoAP8HKAAIBugBfAd7BXwFdAV0BwAA0GmAAUgA/g8IAHwAVAhWB/wA1AdUCXwLAAjYaQgDiAD+D4gAAARWBVQA/A9UAlYFVAUAAP1piANIAP4PSAB6ANoP/wraCv8K2gr6DwAAAmrABOwE2gLAArwA1gfWAPwCiAL2BOAEAAAKaiQIFAl/CRQFUAVKAzYBQQM0BX8JFAkkCRFqiAdIAP8PSAGEASYJDA24Dw4BfgUQCQAAE2qAAUgA/g9oAAAIfAt8C/wFfgV8B3wJfAkZaogDSAD/D0gAHAVsAXwJbA98AWwFfAUABR5qAAOQAP4PAAD8BwQJ9ArUC1QJtAqECwAAH2qAAVAA/g9QAAAC9AL8AvYP9AL0AvQCEAIhaoABSAD+D2gAAAl0BXYD9AF0A3YFdAUECSNqhAFEAP8PRAAADSsDqgg+B2oCKwWiDAAAKWo4A7gA/Ae4ACgAgADsB7gHqAeoB6gHAAAqaogBSAD/D0gACAj6CV8FWgX6AV8FWgX6CTFqiANIAP4PAABeCToLjg0cBUIFegtCCV4JOWoAA4gA/w/IAOAItAq+DPQGAASQAP4PEABEagAAyAD+DwgA+gOqAqoC/g94BI4DeAwACEtqkANQAP4PEAAyD7IA8gf+BfIH0QCwDyAAWGqIAUgA/g8oAIAPWgFaB0oF3gZaAMoPAABZasABKAD+ByAA2gS6BboEtQS+B9oFEAQAAF9qiANIAP8PQADmDLgDtArfCKQHuAq0CKAEYWqAAUgA/g9IAAgEuAVsA+4KvAmsB6wBOAJraogBSAD/D0gAEgjyBX8FegX6AX8FcgXyCXFqgANIAP8PAAT8A0QErAdsBwQApAj0ByAAgGoAA4gA/w/IAHgIzAv8C/4L/AvMC/wLAACQaogBSAD/DygAiA98ACcH7gX2BeQF9AcEAJRqiANIAP8PQAAaB/wF2AXeB9gF/gWIBwAAomqAAUgA/g8IANgMuAL0BBYAxAyoAugEAAipagAByAH+B2gAeAXMAfwF/gfMAfwFhAUAAKxqAAOQAP4PAAAUBtQG9gN0C3YHVANUBAAAw2qAAUgA/gcAAP4HAgT+Bf4F/gX+Bf4FEgT7aoADSAD+DwgAfgkuC/4NAAVeBS4LXgkAAARrgAFIAP4PAAD+B+4E5gPwD+YD7gz+BwAACmsIA4gA/g+IATAB1A82D4APNg9UD3QJAAAga0AIMAgMBAoCiAF4AIgBCAJIBDgICAgAACFrAAAEBoQBCAhgCB4ECgPoAAgDSAQ4BAAIImsUBCQCxAE8AwQIMAQOA+gACAMoBBgIAAAjawAE/AMUABQA8gcCADAMDgPoAAgBOAYICCdrAAD8DwQFpATUBAQNYAweB/gACAN4DAgIMmuIAMQPogSQBJIE5AewDA4D+AAIAzgEAAg6awAACAn8BVgB/AUAATAMDgPoAAgDOAwIAD1rUAhYC1QI8gdUDQAIMAQOA+gACAM4BAgIPmsABKoCqgivB6oAogIwCA4G6AEIAzgMCAhHawAB/geqBKoFqgi+BwAAHA7KAQgCOAwAAElrJAStAv4H/AOuAf0EOAwHA+QADAMEBAAATGuAALwHrAW8B4QIvAewCA4G+AEIA3gMAABQawAA/gOCBNoFqgTaBQAMEAPuAAgDKAwYAFNrIAHsD6wHuAeoB+AMYAQcA/ABEALwDAAAYWsAAboPuweAB7sHmgcwAA8O5AEEA3wMAABiawAEAATwBwAEAAQABP4HIAQgBCAEIAQAAGNrAAQEBOQHBAQEBAQE/AdEBEQERAREBAAEZGsACPAPAAgACP4HIAQAAP4HIAggCBAIEAZlayAIIAu8CKAIIAggBP4HJAIkAqQBpAAgAGZrAAAQCNQHFATUB5QEEAT+ABAHFAgUCBAGZ2sACPAHAAT+ByACCApoCKgFPgIoBegECAhpa6AAoAV8CGAIIAUgBf4EJAKkASQApAAgAWprJAikCKQOlAiUCLwIhA+UCpQKpAqkCgAIb2sQANAHHATQBZAF3gWeBbQFFAT0B/AHEAByawgM6AMoAGwL6AdoAi4JfASsA7wEqAgoBnNrEA7QAVAE3ALQD9AAXgn0DFQDdAVUCRAEdGsADPwDBAhUCHQPFAiED1QK9Ao0CtQIAAB3awAM/AMECGwI/A5sCAQPbAr8CmwKpAgAAHhrAAh8B1QE1gc8BUAAPAe8APwPvACoBwAAeWsAAIQARAgkBFQEnAIUAZQAdAAUAAQAAAB7awAAxAhkBJwGFAH0AAQA/AdECCQINAgkBnxrwAAiCJ4EEgPyAAAARABEAP4PQgBCAEAAg2sAAMIIPgSSA3IAAAj4CIgG/gGIBvgIgAiJa8AAIgieBJIDcgAQAM4HqQLoCwgI+AcAAIprgABiCB4GkgFyBBAETgPIAP4PSAFIAkAEi2uAAOIIngSSA3IAAAioBP8EaANlBVUJQASWa0AAYgxeApIBcADkDwQE/AVuBWwF/AUEBJhrgABiCF4GkgFyCAIJqAUvBxgFXQsVC6AItGsAAPwPFAXkBBQNQAzeCEIHQgb+CWAIGAi1awAAAAL8D1ICUgIRCUAI3gVCAl4FoAgYCLdrAAz+A1UJVQk9B0AA4AheB0IG/gVgCAAAumsAAFIGVAHMD1MBAAjeBEIFQgJ+BeAEGAi8awAAbAxsA+4A7AcEAmAI3gRCA14DwAQACL9rAAf/APUOpQD1AqcEAASvAqECLwHoAgAEwGsAAHwJUglAB1QFPA1ACH4JQgb+CWAIAADBawAA/ATSBMAH1AQ8AkAI/gVCAv4FYAgAAMVrAABUATQL1goUB8QCEAjOBUIC3gVQCAAAy2sAACAA4Ak8BSQDpAF8CSQJJAf8ASABAADNawAAIADwAy4CogKqAqoKIgoiDv4DIAIAAM5rAABIAMQHcwJKAsoDegpKCkoO+gNCAkAAz2vAAMgC6AOmApQDlAPUA5QKlAr0B8QCwADSayABIgHqB2oFagX/B2oFag1qDeoHIgUAAdNrEAD4B7YFlAz0BwAAtA8sAKYPJAC0ByAI1GsAAAAA/g8gBCAEAAD+B0AIIAgQCBAHAADVawAAQAF+AUgBKAGADz4BSAFIAUQBJAEAANlrAABACn4L5AdkBVQDXgDkB2QKZAlQCUAE22sAACgBKAEoASQB/AckCaQIkgiSCJAIgAbhayQBJAH8ByQJoggQCMALfgpICkgKyAkIBOtrAADEBPwF7AXsA+4H7AvsCuwKfArECgAA72skASQB/AeSCIIIKApkChAJzgkQCswKAAQPbAAAAAj8ByQEIgQiBH4AogMiBCEIIgggBhFsAAAACPwHpASkBKQE5ASkAaQGvAiACAAGE2wIAPgBCgIIAgAI/g+SCJIE8gGSBp4IAAQUbCAAGABGAFUAVABUAFQAVADUAxQEBAgABBdsAAhYCUYFVAJUAtQF1ARUANQDFAwECAAEG2wQABgJhAUjAyoJKgmqB6oAKgHqAwoMAAYibAgAqAS2Bb4FfAd8BbwFvAUcAPwDBAwABiNsEAAYCUQFIwGqDyoBKgFqDSoA6gcCCAAGJ2wQAMgCxALeAtwP3ALcAtwCHAD8BwQIAAYobAgAUAlYC1YLXAVcB1wJXAkcAPwHBAgABi5sEAiICrYEXANcAlwEXAccCPwBDAYECAAG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AAQRcBAAJA8kAIAFvAT8DrwMvA78ArwEvAmAAh9wEQSmAwAAAgATDLoDOgP4DzoBuwe6A7oPLHAQDKIDhAA2BlQB/gcmAfIEbgVqAfoFAARMcAAAIghEBgQDdA7UDzYPhA92D1QPdA8AAFFwAAAiBqwBAATqA+oH+gXiAeoD+gXqBQAEY3AQACYPQAAXAk0DoAOcA7YL+gtcBxICQABrcAAIYAgYBAACgAF+AIABAAJABDgIAAgAAG1wAAACCEIEMgQCAsIBPgDCAAIDYgISBAAEb3BACHAEAAL+ARACBAAECAQI/AcEAAQAAABwcAQChAF0AA4I5AQkAgQB9AAEAWQCJAwAAHVwAAgACaoIKgQqAqoBKgIqBCoFvggACAAAdnBwBAAO/gEAARgFAAQgBCAE/gcgBCAEIAR4cAAAQAhICigJJAQWAtQBHAIkBKAJIAhACHxweAgABv4BEAEABjAAjgCICAgJCAz4AwAAfXAACAwJ0gQABAgD1gACAwgEDAXSCAAIAAB+cAAAmAiICGgECAIKAewACAMIBMgEGAgAAH9wOAgABv4BAAMIAPAHAAQABP4HAAQABPgPiXBwCAAG/gEAAjgIAgzyA5IAkgCSAPIBAACKcHAAAAz+AwACGAgwBA4C6AEIAygEGAgAAI5wAABACCgJpAQgBBgDxgEYAiAEpAUkCEAIknBAADAO/gEAARgKQAg4BAAE/gIAApgBIACVcDgIAAb+ARACAAjoByoAKgDoBwgICAYAAKtwOAgABv4BAAMIAEgEaAbaBUgEKAcIBAAArHBwCAAE/AMgAgAA/A8kCSQJJAkkCeQJBAitcAAM7AMoCKgJqAQuBqgBKAIoBCgJrAggCK5wcAgABPwDMAYAAPgHLgkoCegLCAr4CQAEs3AYCAAG/gEAAhgA4A8UAJwBfACUCRQI9Ae4cHAIAA7+AQACKAQwAA4A+A8oASgBKAEIALlwAAAADOACoACgBr4ApAKkBKQA5AIEBAAAunAAAYgMigLKALgGrACqAqgIuArgCIAHAAC8cDgIAAb+AQgBEAR0A14I9A9EAEQDRAQAAMFweAgABv4BCAMQADwHpAAkCPQPJACiAyAEwnB4CAAG/gEAARgBAASWBJAEmASWBBAEAADIcCAJEgcOA8oAagwaAAAEfAkAAQAF/gUACM9wAAgADPwBVAFUBVQBVgVUAVQLXAlABwAA2HA4CAAG/gEQAoAIiAT+AogAiAD+AogMAAjZcCAIEA7+AQADWABID64EtASkBLQETA9AANtwQAgwBv4BEAYABPgIiAj+B4gE+AYACAAA33B4CAAO/gEQAP4PAgQiBfoEogUCBP4PAADkcPAIAAz8AwAEEAUAAagD/AqoCrgKqAYkAOZwIAQYBAAD/wAIAwAI+QQJAu8BCQT5BQAI53B4CAAG/gEAApAIhASmA7wAtA/ECKQIgATrcAAIighiChQJAAQqA1oELgSaCIoKeAgAAO1wAAAkBCQDfwAUBoAAZAA/BwQAfAKABkAI+XAAACIIIgY+ADYFNgG3AHYCdgQ+ACICAgQJcQAAEAgUBPQBVAlcA1wBXANcCVwJFAcAAApxPAQADv4BCAMAAF4BVgHWD1YBVgFeAQAAFXEgCBAO/gEQAoAI+ASWAvQBnAL0BIAIAAAZcTgEAAb/AQgDIACsB6QEpgSkBLwEpAcgABpxAAAkChQLvgQMBKQDMAIMBH4FDAUUCCAEIXEoCCgN/gElAfwNJAH8BSQJ/AEkBSAIAAAmcRAIEAz4AV4BWA1YAfwBWg1YAVgBCA0ACDBxeAgABv4BAAI4ANAPSAUGBUQEXAXEDwAANnGICKgGbgJuABQFDAGAAGgGHgBoAooOgAg8cUAIOAQAAv4BEAikBPQDpgCkD/QIpAgABExxeAgABv4BAAKQCPwK1ArWD9QK1Ar8CAAATnEECfwEXQReAVwN/AAEAHYMBQH8AQQMAABVcQAAAAj+BLIAzgK6DAAA/gQSCRIDng8ACFlx8AgADPwDIAj0CpQK/AqUDvwKlAr0CgAAXnEAABgJVgVUAVwN9AEAABwN6gjIAjgFCAlkcTgEAAb+AQABEASEBL4CrAHsB74BhAIABGdxAAj8DZQAlADsDBQAzAFEBVQJVAHMDQAIaXE4CAAG/AEQAgAI/AusCqwCrAasBvwLAAhucQAAMA40APQBdAV+AXQFdAV4AfQBEgwAAH1xAAAQDv4BEA78A6wEbADqB6oEagL6DwAAhHE8CAAG/wEIAgAM/gCqBqsIqgqqAP4GAASKcQQEfAc/ALwAvgb8AAACZwSqAIkCRAwAAI9xAAAICvoK2gLaCv4D2gr6CtkC+QoICgAAlHEYACAM/gMQBCQBlA9ECSYJRAmUDyQBAACZcQAE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t3MEAiQC/AMkAgQAgA+ABP4EiASIBIgPCAC7cwAEJAL8AyQAAAz4A8gJfgZIBsgJGAgAAMJzAAQkBPwDJAIAAPQDFAH0CQQI/AcEAAAAynMAACQE/AMEAkAI/gdCAP4H/A9CAP4PQADNcwQCJAL8AyQBEAFICCQFkgTEBEgCEAEAAOBzBAQkAvwDJAIAAFwGSAH+D0gBSAJABAAA7XMAAEQE/AdEBAAC8AgABP4DAAj8D0QIBAjycwAAJAT8AyACDACMAvQClALUD5QClAIAAv5zJAQkAvwDJAoACPwFVANUAVQPVAn8CQAEA3QAAiQC/AMkAQwDaAIICP4HiAAKA2oEAAQFdAQCJAL8ASQBAAD8D1QEVgTUAVQDvASABAZ0AAQkAvwDJAIACXwIVAnUD/wPVAlUCXwJCXQABCQC/AMkAgAItAcsAKYPJAC0ByQIAAAQdAAEJAL8AyQCAAj0CRQEEALeARAEFAj0CyJ0AAQkAvwDJAKAANQC1Am8CMQHZACUAwAEJnQAAiQC/AEkAQAAtAe0AqwDLgj0DzQAAAAqdAAEJAL8AyQCAAgIBf4FWAFYAf4FCAUACDN0AAAkAvwBIAOIAP4PSAAAA8gA/g9IAIgDNHQAAFoAWgFeAXoBWgFYAXoFXgNaAVoAkAA8dAAIRAT8B0QGAADoBqgArA+oAKgB6AMIBEt0AAAkBPwDJAIAAPQHvAW2BbQPvAXwBQAFW3QAAiQC/AEgAQQE9gSUApAB8ACUApYC9ARcdAAAJAT8AwQI8Ae4AvQPFgDWAwQIyAcQAF50AAQkAvwDJAIAADwAsA+wB/4AsA+wALwPX3QAAJQOVAh8BFQGlApACVQJvARUAVQGAABqdAQCJAL8ASQBAAz+AKoGqgD+BqoBgg8AAHB0AAQkAvwDJAIACHwEVALUAf4HVghUC3wLg3QAAiQE/AMkAgQAdA9kA9YFZANECXQPAACHdAAAJAT8AwAM+gMqCMAHFgcqBOgPKAloCYt0AAAkAvwBJAAAAvQC9AL2D/QC9AL0AhACnnQAAiQC/AMgAQoEaAV+A+gBbgVoBW4JAACndIAAfAh0C7QLtAv8CwAPVAt2D1QLVAkAALB0AAIkAvwBJAUABP4Evge6Ab4CugJ+BRAFynQABCQE/AcgAggM/A/+B+wH7AfoC+gLAAjcdAAIAAb8AQQABAb8BQIEggc+CMIDAAwAAOJ0AAB0DfwB/A90AQAO/AEEBvwFBAL6DwAA43QEAE0N5gMADfwH/AsCCP4HWAHnD1QBAADkdAAE/AX+D/QJ7AHwDfwDBA78BQQG+gsADOZ0AAAEBAQO5AkcCNQEFAUUAPQHBAgECAQG7nQAAFgISA7kB3IHaAdiB2oBcg9kCEgISATvdAAA/AcEBbQE5AQQAQIM/guSAPIPAggABvZ0AACIDPoDiAD+D4oAAAj8D5QA9A8ECAQE93QAAEIIVAzAC2gJZAtWAUwBVA9kCGAEAAAEdQAAfAl8BVwHbAU8AIAPfAiUAPQPBAgABhh1AAAIAAgA/g+IBIgEiASIBP4PCAAIAAAAGnUAAAQBBA/+CVQJVAtUCVQL/gsECQQJAAAcdQAAkg+SBP4EkgcAAP4PiASIBIgE/g8IAB91AAAgCJAIjgiICIgI/g+ICIgIiAiICAAIInUADOQDJAm0CrwKrgqsD7wKtAqkCiQIAAAjdQAM5AMkCLwKpAqkCqYPtAqsCqQKIAggACV1AAArAiQC/wEkAQAIvgbqAb4EqgS+AwAAKHUAAAAM/AMkASQBJAH8DyQBJAkkCfwHAAApdQAAAAz+A5IAkgD+B5IIkgiSCpIK/gkABCt1AAAIAOgPqAKoAqgC/A+oAqwK7AcIAAAAMHUAAPwPRAREBEQE/AdEBEQERAREBPwPAAAxdQAA+A+IBIgEiAT+B4gEiASIBIgE+A8AADJ1AAAAAPwBlACUAJQA/A+UAJQAlAD8AQAAM3UAAPwDJAEkASQB/w8kASQBJAEkAfwDAAA1dQAAAAD8AyQBJAH/ByQJJAkkCfwJAAgABjd1AAAACXwJVAVUA/wBVAlUCVQJfAkABwAAOHVAACAA+AeuAqgC6AOoAugLCAgIDPgDAAA6dQAA/gciAv4DIgL+AwAACAgICPgHCAAIADt1AAD0DwQE9AVUBVQF/AVUBVQF9AUEBPQPRXUAAPgB/g+uD3gAIgnyBDoC5gkiDOADAABMdQAAAAG+CKoEagI+ACoAag+qAL4AAAEAAE91AACACPwP1AjUCPwI1APUBNQG/AiACAAAUXV4CAAG/AEABhAA/A9EBEQE/AdEBEQE/A9UdQAA/AckAvwDJAL8A4AAqAD+D6AArACAAFl1AAA8AKQPogqSCqIKgA+8CoQKRA88AAAAXHUAAEQA1A/UCvwK1g/UCsQKpAqkDyQAAABidQAAoACuAu4CrgLuB64CrgLuAq4CgAAAAGV1AAD8B/wDJAL8A5AAiA/WCKQI3AjED0AAZnUAAPwH/AMkAvwDAAgoCSgJvg8oCSgJAAhqdZAAlADcB7QFlAW8B5QFsgXaBdoHkABAAGt1SAB8BPwH/Af8B/4H/Af8B/wH/AdIBAAAcHUAAAAKvArsB6wGvAKsAqwG7Ae8CgAKAAB0dQAA/AckAvwHdAasA/QDXg1UDVQJVAcAAXZ1AAA4AAoP7AuoC64LqA+oC+wLCg84AAAAeHX8ByQC/AMkAvwDIAC0A7QCrgs0CPQHIAB/dUAA5gdZBdQHWAX/D+AEdgN5B7QIUghABoZ1AAB0BVQPXAzABwQA/A/0DvwP9A78D0QIinUAAPAJ/gj+D/4P/g+uD/4P/g/+CPAJAACOdQAE5AcEBPQDTAIECPQElAL+D5QC9AwAAI91AATEA/QDTAIACKQHPACmDywAPA9kCEQEkXUACW4JVAXUA1IBCA2iAyoE6g82CWIJIAiXdTgJgAT8AwQAJAAkCCcIpA9kAGQAJAAAAJl1MAkABfgDCABIBCgKrAmoCagIqAgoBAAAmnUYCYAM/AMECMQINAQmAqQBZAIEBAQIAACfdZgIgAb8AQQAhAD0B5UElgSUBJQElASEAKR1mASAAvwBBAD0A5QE9gSUBJQE9AQEAgAAq3WICLAO/AEECEQItAWWBpQG9AXECEQIAACudYwIQAb+AWIAIgDyBysIKwkqCfIIEgYiAK91OAGADPwDBAz0AxQAlgLUAxQA9AcECAQEsnWYAIAO/AEEDvQBVATWBXQCVAWUBDQIAAC5dbgIgAb8AUQAJAqUClYJFAWkBCQCRAEAALx1GAmADPwDBAAkBbQE1gjUCrQKlAAEAQAAvnWYCKAO/AEECIQEtASmAuQBpAKkBKQIAATFdZgIgAb8AQQA1A9UAFYD9ABUA1QI1A8AAMd1mASABvwBBATUBxQEFgT0B5QElASUBAAAynWYBIAG/AEEBCQFFAVWBdQHVAUUBSQFJATSdYgIkAb8AQQApAK0AqYC5A+kArQCpAIEANV1mAiABvwBBAD8D6wErgSsAawGfAUECQAA2HU4CYAE/AMECNQJVAtWCVQJVA3UCRQIAADbdZgIgA78AQQA7A+8Ar4C7A+8AqwK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JALkA3wA1AF+AVQB1Ad8AQABl3iEAPQHLATgB8QANAykA0YA9AcUCPQJAASYeEIA+gcWAvIBAAT8DKQC/wCkAP8CpAT8AJ94hAD0D0wEwAcIAHwNSAP8D2gDfAVICQAAp3gAAMoE6gL+D+oKgAr8CtQK1grUDvwAAACpeAAAhAD8ByQC5AsACPwHrAKsAqwG/A8ACLB4hAD8DyQE4AeIAA4J/A8ICPwPCgjICQAAsXgEAdQPLATEC/AHCACoDwgHfgKIBWoIAAazeIQA/AckAuQDAAisB2gALg2oAygErAkgALR4hAD0DywE5AcAAKgL2ArcCtgKqAsoCAAAuniEAPQPTATEB0wA5A9cCVYJ9A9UCVQJTAm8eAAAggD+ByICwAd+A6oEqgD+BqoBgg8AAL54wgD6ByYC4gEABP4DigjqB6oB6gKuBAAAwXiEAfwPJATkAwwIaA+OCOgOSAioD84IKA7FeEQA9AdMBMQHAAB0CFwG3AF2CVQJVAcAAMp4AABSAtIHegVuBWoHagLqB2oFegVCB0AA0HhQBVAFPANUDxYLfAsIC2YLUgu+D5gBgAHVeAAARAD0DywE4APID/wPzgjMD+wIyA8ACNp4hAH0DywEJATEB/wC3AbcDv4K3A/8AgQD6HgADvwBBAS0BLQOtAuWCoQKtAq0CrQOlAD0eEQA9A8sBMQHIACaCdoP1gjWDJoKIAgAAPd4QgD6BxYC8gOACHYHzAFfAMwB9QdUAQAA+ngAAIIA/gcSAuADSgjvBOoC+gDvAuoCAAwBeQAAQgD6BxYC4gEIDP8ArAb9AKwGLAAABw55hAD8ByQCxAsUCEwEXgfQD0wJXglUCRAIGXkAAAQB/APkCw4IVAfUAUAIDAfsDywJZAA6eQAAIAQkAqQBJAgkCOQPJAAkAKQBJAIgBDx5AACIAYoA7g9YAIgBAAD+BwAIAAgACAAGPnkAAAgBiADOD7gACAkgCCAI/g8gCCAIIAhBeQAAiABKAOwPWACIAAAA/A8EAHQCjAEAAEJ5AAGIAMoPeACIACAA/AcgCP4JEAj4CAAGSHkIAYgAzg94AIgJAAT8AyQAIgDiDyIAIABJeQgBiADuD1gAiAgACPAPAAj+DyAIIAgACFB5iACIAO4PWAAIAYAA+A9OBEgESATIDwAAVXmIAIgAzg98AAgI4AwAAvIHxAgwCGwGgABWeQgBiADKD7gAAAj8DyQJJAkkCSQJ/A8ACF15iAFIAO4PWACACDwEJAPkACQA5A88CAAGXnmIAYgA7g9cAIAA+AMoASgB/g8oAfgBAABfeQAAgASWBLQCtAC+B7QAtAK0ApYEgAQAAGB5gABJAOsHWACCAOoDKgEqAeoJAgj+BwAAZXkIAYgAzg94AAgAQAFKAUoB+A9KAUoBCAFoeQQJdAXUBdQB/AnUCdQH/AHUBdQFdA0ECW15EAAQAZgIbgRMAXQJSAlGD1gBZANUA4wMd3kIAYgAyg+4AAAEVALUAX4DVAlUD0QBAAB4eQgBigDqD5gAAADcD1QB9ABUC1QI3A8AAHp5CAGIAOoPWABACAgJ/gVYAVgB/gUICQAAgHkAAAQK/AuMA/wL3AveD/wDjAf8BwQKAACBeQAAFAlMBV4BTAlECVAPTAFeBQwFNAkgAIR5iACIAM4PfAAIAEIEKgIqCeoHKgG+AqAEhXmEAEQA5g9cAAQB8AGqAfgHrAGqAfgBAACNeYAAiADsDxgAwA98AMQH9ALUA1QI/AcAAI95iABIAO4HWACCAPoPagVqBeoHagV6BcIHpnkAACQFswWABesB/gHaB4ABvgOCAz4FAAWneQABigDqD5AABAB8D9wLXgtcC9wLfA8EAap5xAAkAPUPLQBAAv8CrQL/D6oCrQL/AgACrnmIAUoA6g+YAAAI/gv/CuoK/wrqCv4LAAixeQABigDqD5AAxA/8BfwH/gb8AvwP3AIAALl5AACED7wArASsBPwHrASsAqwKugiCBwAAunkAAIAP/ADUAtQC/APUAtQC1Aj8CIAPAAC7eQQABA90AWQFZAfWBVQFVANECXQJBAcEAL15EAAID+gBxAGUBbIHugWyB4QJ6A8IAAAAvnkgBCQCJAGkAGQA/A9iAKIAIgEiAiAEAAC/eQAAkAhUCFQENAN8ADQANAdSCFIIkASAAMB5iAhMCCwEnAOMALwAigqaCSoJSgdIAAAAwXkAApIBUgD+D1IAUgQAB/gEBgTABAAPAAjDeQAAUAhUCFQENAO8AJQANAdSCFQIUAYAAMZ5AAAYA5gA/A+UAAABRABEAPwPRABEAEAAyXkAACgEugS6AroBugH+D7oBugL5AigEAADLeQAAkgNSAP4PUgAACDgEgAN+AIADMAQICM15lANSAP4PUgACAPgBiACIAP4PiACIAPgB0XkAAJQDUgD+D1IAEAFCAUwBAAH+DwABAAHSeQAAlAFSAP4PEgCACDgEgAR+AgAB2AAAANV5EgOSAP4PUgAAAP4PIAQAAP4HIAgQCAgG2HkSA5IA/g9SAIAJYAT6B4IIYAgeCOAGAADfeRQDlAD8D1QAlAkACPwPJAkkCfwPAAgAAOR5AAAUA5QA/A+QAIQAtACEAPwPhAC0AIQA5nkgAawIbASsA7wDrg9sASwDbASsCCABAADneQAAFAOUAPwPkgAACPgIiAb+AYgG+AiACOl5lANUAPwPUgCSCBAETgJIAf4ASANIBEAI63mSA1IA/g9SAJICAAaQAXAA/g9QAJYBEAbveQAAlANUAPwPUgAACHwGRAFEAEQBfA4ACPB5kgNSAP4PUgCSAhACzwEECPwPBADsAQQC+HkUA5QA/A+SABoASA9ICUgJfglICUgPCAD7eQAAlAFUAPwPUgACCagErARWBXQCzAFAAP15FAOUAP4PUwAACZ4JUAhwBV8GUALQAV4AAHoQA5IA/g8SAAAB6gesALwApA+sAKoEqAMFehIDkgD+D0IACAj0BJIDkACSD+QICAgQBAt6AAAYA5gA/A8AATwIpAqkCqQPpAq8CgAIDXqSAVIA/g9SAAAA8gdUAVABXgFQBfYHAAAOegAAlANSAP4PAgA4DMoDSADMD04IeggABhp6AACUAVQA/A9SABAA/g+oBPwHqgSoBAAAIHoYA5gA+A+UAAAM/AMEANQH9ALUCwQI/AcjehAA+AVWBfQFXAX0BiAHpAD8D6QAIgcAAC56AADKASoA/wMACP4Krgr+D64K/QoACAAAMXoUA5IA/g+SAAAC6A+kAqQC6gOiCroK4gcyehQDkgD+D1IAEgDADxIAwg9aBUIF2g8AADN6JAIkAfwPogAABlgAVgVWC1QJXAHwBQAIN3qUA1QA/A9SAAAJfgmWBdYGvgZWBVYIXgA7eooBSgD+D0kAAADKB6oEgQQtBKEE7QcAADx6FAOUAPwPUgBABVwFtAJ2CbQG1ABcA0AEPXoUA5IA/geSABAAdAesB64HtAe2B5YHVAA/eooDSgD+D0kAgA9eAFYPVgVXB14Awg8CAEJ6FAOSAP4PUgCABnwArAysCf4KrAKsBvwIRnoSA5IA/g9SAIAIvAwsBSwF7gYsArwCgABMehAM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fXwsA6AA/g+gAAwBQABECEQI9A9MAEQAQACJfCwDoAD+D6AALAlgBFgGxAFACEYImAcgAJJ8LAYgAf4PoAAsAQAIaAiICw4IiA9oCAgIl3wIACAD/A+gACwBAAj8DyQJJAkkCfwPAAiYfAAALgOgAP4PJACAD4AE/gSIBIgEiA8AAJ58jAMgAP4PhAH8DxQE/AUUBPwEFAX0DwAAn3wECXQF1AXUBXwDVA9UAXwDVAVUBXQFBAmkfAAAgAD8AMQD1gLWAtQK9ArEDvwCgAAAAKV8AADyCJIIngc8A/4PKAAEA3AIkgieBwAAp3wsB6AA/g+oAAAM+AMICEgI7g9ICEgIAACqfAAAKAqoCqoKnAu+AogCmAacB6oKqAooCq58JgegAP4PoAAuAQAA/A9UBNYAVAN8BAAEsXxkCREFQQWMAyABkg8uAUIDwgV+BQwFMAm5fAMA0AH/D1AAkwGAALoAggDjB5oAkgCiAL18AAa4Af4PIAAIAwQIpAanAKQPpACMAoAMvnwCACwH4AC+DwAA1A/cAtwC3grcCtwPFADKfAwAIAP+DywAgA9+BMgDAAz+A5II/gcAANV8BgCgA/4P6AAACKgGqgCsDvgArAyqAIgO1nwGANgA/wNYABAP/AB0A/QC9gL0AvQDIADZfAwAoAH+D6gAJAlABNwHAAisC7wKqAqoC9x8AA78AQQIHAW8BS4Dhg8cA7wDHAUsBQAA33wGAKAB/g+MADoA1g//CtYK/wrWCv4PAADgfAMAkAH/D8IC/wEBAlUB/wfXAz0BkQKBAud8qAH+D6AAKAjgC/wL/Av8D/wL/AvcCwAI73wDANAA/w/eAY0HvQClB+8ApQetAL0HAAD4fIAEhASYA5QB4wDQD0gARAF0AUACgAQAAPt8AAAABJQE1ALcCLQIlA9SAEoBQgKCBIAE/nwAAJAO3ACyDIgCAAD8AwABAAEAAf4PAAAAfQAASAd8ANIPSAEAAOQHJAgkCCQIfAgABgR9SAd+ANAPTAAAAxAATgCICQgICAz4AwAABX0AAEgHdgDQD0wA4AoECAQI/A8ECAQIAAgKfQAAFAhUBVQFfAH0CVYPVAEcBZQJJAokAAt9SAduANAPTADgCggIOATIAg4DyAQ4BAgIDX1IB24A0A9MAAAB+A8IAcgAPgDICPgHAAAQfRAOnADyDsgAgAIECEQM/AtECPwPQAgAABR9SAduANAPTAEAAOgDCAEIAf4HBAnkCQAEGX1IB3YA0A9MAGQBAAT+ByIE/gEiBiEMAAAafUgHWAD2D2AAQAsEB/wAhAQkBTwD4AQgCBt9SAd2ANAPTAAAC3AITgbAAUIITgjQByAAIH0gACoJagVqA+oL/wlqByoBqgWqCSALIAghfUgHfgDQD0wAxAoACAgH+AAuCCgI6AcIACJ9AAA0CBQFVAX0AV4JVA80AbQFFAU0CQAAJ30ACB4JgAXeAcAJogmSD14BUgUeBSIJIAArfRAJHAlQBV4FtAGQD04BFAWUBRIJCAoAAC99AAAACD4FagXqAX4Jag8qAaoFPgUACAAIMH1IB3YA0A9MAcAA/A9EBEQE/AdEBEQE/A85fUgHbgDQD0wAAAMgAKIPngSCBKIEng8AAEJ9SAduANAPTACAAogATgQ1BTQFTAlAAAAAQ30QDtwAsgZIAEAHSABoBloFzAQoBggMAABEfUgHbgDQD0wAAAMACPwPJAkkCSQJ/A8ACEx9SAduANAPTAAAA0IIJgkqCZIPKgkmCUAIUH1IB24A0A9MAKADBACkD6QEvwSkBKQPJABVfbAN7ACiBJgCAAD0BzQJLAnkCTQJLAngBV59SAd4ANYPUAAACygImAQYA84DCAQoCCgAYX1IB24A0A/MAMQDkADID9YEpATcBEQPgABmfUgHbgDQD2wBIACQD4wEogSkBIgEkA8gAG59AAAsCCwFlgHUCcwJgA9eAVIFEgUeCQAAcX1ID3YA0Q9MAAAJBAS8AycALAC8DwQIAARyfQAAkA78AJIGSAIAAFgDdgjQD0wA4AIABHV9SAd2ANAPTAAACxAIiAamBaQEiAawDBAAdn1IB24A0A9MAQAA+AeWCJYI/AicCJQI8AaTfZAMvAHiDNgAAAo6CEIJEgnqD4IJPglGCJl9QAduANAPTAAAAf4PAASoBP4FoAQsBQAEmn0AAEgHfgDQD6wDgAlUBFQDXgBUBtQIBAScfTAO7ACiDJgCAACMDKQCpwCkD6QArAKADKB9MA7sAKICmAQABNoCVAjUD3QATAKABAAArX1IB24A0A9MAEADEAD+D6gE/AeqBKgEAACxfU4HcADsD0AB/A/sA+QDJAKsCyQI/AcAALJ9SAd4ANYPgAL8DwwAvAPkBLQEBAD8DwAAv31IB24A0A9sAQAAvgeqAKoA6w+qAL4EgAPKfQABPgUuBb4F7gGuB6IBWgMaAyYFQgUAAM99SAd2ANAPTAAAAV4EQAD8D2QJcQhGA4gE0X1IB24A0A9MAAAFIASqAioI6gc+AaAGAADSfUgDdgDQD0wA4AOEAJQHfgVUBVwF1gcQANp9SAduANAPzADABZwCrAksCO4PLAO8BAAE4H1IB3gA1g9IAQgAoAeUAJwA1g+cALQHAADjfSAIvAziAtgCgAQgBH4DtAq0B7wBIAYAAOh9SAduANAPTAAAD/wHrAKsD6wCrA+8AoQP6X1IB24A0A9MAEAJFARcA/QJ1AbSBtwFVAjvfUgHWAD2D2ACAAT0BbwHtgW0D7wF8AUABPR9SAd4ANYPSAAAAvwErAKsAf4PrAH8AgQE+32QDtwAsgTAAZwE1AeUBAQA8AwOA/gEAAgBfkgHXgDwD2wAgAIgBGoDqgpqB74AIAcAAAR+RANfAOgPJgAAAfwHvAK8AvwHvAq8CvwNI35AAnwBfAD8B/wASAIYAXwE1ANUANACgAAmfkgHbgDQD8wAQAL2D5gHFgTwD5YIEAgAACt+EA7eAHEEbAMBCHYG4AksCLsK+wsmCgAILn5AB34A0A9MAUAA7A8EANYHdAVUBdQHAAAxfhAO3gCxDMwCAAD3DwAEzgMBBOgHhgiYCD1+kA7cALIMiAIADPwChAaWCaQLhAD8BgAAPn5IB24A0A9MAAAK/Aj8Bf4F/AH8BfwJEAhBfgAIMAq+CjwL/AM8D4gCXgZkB1wKhAoAAEp+QAdOAPAP7AHAB/QHHgT0A5AG/geQDBYCVH6gAy4A8Ae8ABAA/Ae2AtgPPwPQBBYOAABefpAO3ACyBIgCAAiqCeoHrwEKD+oJqgmABWp+AAd4AJQGUgEIADQH8gX6BdIF9AX0BwQAa34AAH4Kfgd/B/4PfgsYB/YC0gp+CpgKgAhwfkgHbgDQD0wBAATwAt4B+gfqAdYC8AQAAHN+kA7cALICCAk+DOsD6wm+BzQMiwN4DAAAfH4QDtwAsgZIAv4PNAi6DzgJPgisDxALAAiMfpgO9gCRBkgBEgjuB/4H7wP+A+4H+gcACI9+gA7cAKIGWAEADPwD9An+C/4O/Av8C4QJln5QB3wAagIACXYE9QcQBPYPMAT+B9AMFgKgfqAEsAVsBSIFkAQAAPwBAAEAAQAB/g8AAKJ+AAAwCewEogSYBgAABAQEBPwHBAQEBAQEpH4AADAJqAVmBRAFQABEAEQA/A9EAEIAQACmfqAEuAXkBJIEgAIwAI4AiAgICQgM+AMAAKd+IAW4BeYEkAIQDIQDfAiEBTQCrAVgCAAIqn4AACAFuAVmBRAFAADEB0QIRAhECPwIAAarfgAAMAXoBaYEkAIACHQEBAP8CAQM/AMAAKx+IAW4BWYFEAQAAqgAqAD+D6gAqASIAwAAr34gBbgFZwUQBQAE9AEEAQQB/wcECfQNBASxfgAAMAXoBaYEkAIACHgIAAT+BAACmAEgALJ+AACYBdcEsQQAAP4PAgCyAdoBAgj+DwAAs34AADAFzgUiBQAA8A8QA/AAnggQCPAPAAC1fgAAMAXsBaIEkAAADv4BAAwAA/4AAAcACLd+AAAgBbgFZgUAAWAIWATEA0AIRgjYB2AAuH4gBbgFZgUwBQAA/A9ECEQE/AFEBkIIQAa5fgAAMAXsBKICmAoACDgEygIOA+gEGAQICLp+AAAwBawFYgUYAQAICAf4AE4ISAjIBwgAvX4AADAJrAVjBRgBAghCDP4LQghCDv4JAAi/fgAAuAXkBJICgAoQCFAEfgTIAyoFqggABMN+uATkBLICAABUBnwBVgj0D0QARAEEBgAAxH4AACAFuAVmBRABAAj8DyQJJAn8DwAIAADFfgAAIAm4BWYFAAD4AygBKAH+DygB+AEAAMZ+IAWwBW4FIgUAAPwPRAREBPwHRAT8DwAAx34gBbgE5gSQAgAIfAZEAUQARABEAXwOAAjIfgAAMAXoBaYEkAQQAEgCVgQkBVQFTAiAAMp+MAqsCWIJEAUAACwBIAH+DyABLAEiAQAAzX4wBZwE8gKIAiAAog+aBIYEogSiBJ4HAADOfiAF+AWmBJAEBACsAqwClA+0AqwCpAIAAM9+IA24BeYEkAAACKQIpAiUD6wIpAggCAAA0X4AADgL5gmQAQAIKA3+AwAA/A8EAHwChAHSfiAAmATkArICCABABugBCAh+BIgHaggIBtN+MAXsBKICmAIAAKQHpASkBL8EpASkBwAA1X4gBbwE4gSYAgAIpASmA7wAtA/ECKQIAATYfjAF7AWiBIACIAiQDqwJpgSIBpAEoAgAANl+IAW4BOYCgAIgAKAPsA+uBKgEsA8gAEAA234gBLgFZgUSAkAAqAKoAq4ClA+sAqQCIALcfgAAMAXsBKICkAIQAEgPtgSkBLQETA9AAN1+IAWcBOIEmAQAAPgHlgiWCPQInAjwCAAG3n4gCbgFZgUQAUAIOAiYBQoCyAUoCEgIAADffiAFuAVmBZIEEAJACGgHXgBID2gISAhIBuJ+AAAgCbgFZAUAAOAPvAK0ArQKtAr8DwAA434wBawE4gSYAgAIrAScA4wAvACaCSoHAADlfjAF6ASmAqACCAhEBeQGagLCBVoMQAQAAOd+IAC4BeYEsAIAAPgHBASgBP4FYASsBQAA6X4wBZwE8gKYCgAI3AVcBF4DXABcBNwJEADqfgAAmAT2ApICAAJUANQHfgVUBVwF1AcSAO1+IAW4BOYEkAIAALQIFAUeA9QBFAVwBRAI7n4AALAF7ASiBDgAoAe0AqwCrgs0CNQHNADwfiAFnATiBJgCAAD4AqgCqAKuD6wC/AIAAvN+AACwBWwFIgUAAPwDtAL0B7QKtAr8CwAA9H6wBOwEogKYAiAA/A+qBKgE+geoBKgEAAD1fiAAmAXWBLECAAC+B6oA6w+qAKoEvgMAAPd+IAX8BbIEAAz+A5II/gcADP4Dkgj+BwAA+H4AALAF7ASiAgAI/AcEANQH9AIECfwHAAD8fgAAIAW4BWYFAAUYAIgCqgisD6gAqAKABP1+AAAwBegFJAUAASgMqAMoBO4PKAkoCQAA/34AALgFZAUSBYgAQAQqAioJ6gcqAb4CoAQAfwAAOAqkC3MJAAyqCJoGBAmgCZIGnguiCAV/AAC8BeIEmQIIAOIHEgTyB14F8gfyBwAABn8AANgCTgJ5AQAE7wQ/AqABKAMmBOwFBAQOfwAAOAXmBJEAAAL8D1ICAAjeBUIC/gVgCBN/IAW8BOMEmALADFQC8gnWBtEG3QVVCAAIFH8QBawFYgUYBQAAtAecANYPnACUBLQDAAAVfwAAOAXkBLIECAKgCKoLmAbeBJgHmgSoCBZ/AAC4AuQCkgAABvwBlAfWA9QHVAHcBwAAGH8gBLwFYwUZAAAFbAVrBaoKqge+ASAGIAQZf5AE3AKjApgCAgDqD2IFfgV+BWIF6g8gABp/IAWwBG4FIAUAAHgBeAV8AXgJ/A/4AQABHX8AANwFswSIACII4AcECK8K6guuCqIKAAggfwAAOAXkBRIBAAz8A3QIrgr+D6wK/AoACCR/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SANABAAA/A8EAPwDK4EADP4Dkgn+BwgA9AySA5AAkg/8CBAIAAQvgQAM/gOSCP4HAADoD6gCqAL8D6gCrgroBzGBAAz+A5II/gcAAHgESgfMAMwPSgh5CAAGM4EADP4Dkgj+BwAA7g8ABEEFzgQABO4PAAA4gQAM/AMkCfwPIASQBSgEpgQoBxAHoAQAAD6BAAz+A5II/gcAAPwB1AFUAX4HVAFUAXwBSoEADP4Dkgj+BwAAFADeB1QFVAVeBdQHAABLgQAM/gOSCP4PAAD0DwQA5gxUA5QFdAgACEyBAAj+B5IA/g8AAOgDuALsB6gK+AsoCAAEUIHADzwApA+kALQGhAWmBZQF1Aj0CJQPBABUgQAM/gOSCP4HAACkCJQIhg+UCKQILAgAAFWBAAz+A5II/geAAEwItAdGAPQHFAj0CQAEZYEADP4Dkgj+BwAB/gjqCqoKqg+qCr4KgAhmgQAM/wPJAP8HAADvDyAEtwQoBSIE7QcAAG6BAAz+A5II/gcABHwDVABUB/wIVAhUAXwHcIEADP4Dkgj+B5IAqgf+BqoEvgOqBLoIAABzgQAI/geyAP4PgAD8D6AExA/4BwQA/AMAAHiBAAz+AxII/gcAAP4G6gHqBOoD/gjABwAAeYEADP4Dkgj+BwAAfAXuBewC7AX8BAAEAAB6gQAM/gOSCP4HAAC8AqwJLAjuDywDvAQABHuBAAz+A5II/geAAXgOeAD4BQgI/gMIDAoGfoEACP4HkgH+D4AB6gS4Bq4GqApqC6kGgAB/gQAM/gOSCP4PAAjuBwAI/AtUCNQJ/AoACICBAAz+A5II/gcAAFQO1AFUCVYJVAlUBwAAioEADP4Dkgj+BwAAeAV4BXgBfAl4D3wBeAGPgQAAZAA8D/wHvAe+B7wHvA/8DwwPZAAAAJiBAAz+A5II/gckAdQF/AHUD/wB1AX0BQAAmoEADPgDCAD4CPgH/gP8B/wH/A3cDxgAAACbgQAM/gMCCP4HEADKBagFrgeoBcoFGgUAAJyBAAz+A5II/gcAAHQFdgf0AXYDdAV0BQAJnYEADP4Dkgj+B4AAVAVMAj4PTAJMBVQEAACggQAM/gO2CP4HAABUCqIKvgpABVQFAgI+AKiBAAj+B5IA/g9AALQGvgR0BQAATAwiAwABs4EACP4HkgD+DwAAVA9WC/wLVAvWC1QPAAG9gQAM/gOiCP4HEAD4B5YItA+cD7QP0A/AAMCB8AAOAPoPugP6A74DgAP2C9ILPgdYAEAAwoFAADwA/A/cA9wD/AOwA7wL9gu8BzQAEADJgQAM/gOiCP4HAADwB7gF9wBVDKQC6AwAAMqBAAz+A5II/gfgAN4G+gH6B+oH1gHwAgAE04EADP4Dkgj+D+QH/g90B/QFHgD8BJwHWAzjgQAA/geSBJIEkgSSBJ4HkgSSBPIEAgQAAOWBAAD8B6QEpAS8B+QEAAyAA3wAgAEABgAI6IEAAPwPlAScB5QEcAuYBKYHVA/UBPQPBADqgQAAAAD8DyQJJAknCSQJJAkkCfwPAAAAAO2BAAAACXwFXAVcA14BXAFcA1wFfAUACQAE84EECKQItAisCKQIpA+kCKQIlAikCAQIAAD0gQAAvASkBJQHlAS0AiAIfgSIA+gCGAQICPqBhAn8DdwP3A3cDd4P3A/cD9wP/A2ECQAA/IEAAPwPRARCBEIEAAREBEQERAREBPwPAAAAggAA1A9UBUQFRAUUBCQFAgViBXoFyg8AAAWCAAAcBfwF/AX6A/AB/AH8BfwF/AX8AwAABoIAAAAJ/AVSBQAFXgF0AVQFAAXUBTwJAAAHggAAAAn8BVQFAAU+AXQBAAVUBdQFPAkAAAiCAAAACfwFBAX8BSwBXAEkAfwFQAX8CQAJCYIAAMAAfAJaAsAC7gfcAsgCXAL8AsAAAAAKggAAJAD0B/QH9gfwBvAG9gf0B/QHlAcAAAyCAAAKAMoPSgRKBH4ESgRJBEkEyQcIAAAADYIQAFAAUAdYBVQF8gVUBVQFWAVQB1AAEAAOghAAUABID0QJUgl6CVIJVAlYCUgPUAAQABKCEABID0QF8wVEBQgHYABqCPIPLgDiAAAAFIIAAJIP/gSSBNAP1AE0CJwPFAA0AlQAUAMXghAASA9WBXwFWAcQAMAPqAL+D6gC6g8AABiCEABYD1QF8gVEDwwA9A9WBVQFdAUcDwAAHIIACbAIUgVWAtIBFgDSA1IC2Q9VAlACAAAeghgJWAn+BtQC/AHUAPwD1AK8B9QCkAIAAB+CQAhABvwBRABMAU4BVQJECEQI/A9AAEAAKoJADPwDRwBVCfwHAADoDygALgDoDwgEAAAsgkAM/ANOAEUN/AMACN4IQgVCBs4FUAgAADCCAABADPgD1Aj4DwAAfg4CAfoHAgj+CAAGMYJADPwD1gBECPwHEADoBycIJQnoCDAGAAA1gkAM/APWAEUI/AcAAOgHigiMCEgIWAgABjaCQAjAB3wAVgn8BwAA+A+IBI4EiAT4DwAAN4JADPwDVwFFDPwDAAhoBFgHzgRoBCgHCAg5gkAM/ANEAFcJ/AcAALgPhgSABI4EsAcgAEeCQAz4A14BSgj4D7QH7AQACCQK/AsiCgACWIJADPwDzwhFCPwHAAC+CKAH/wSgBrwFgAhmgkAP/gBbB/4BAAT/B9UE9wfcBI8HpASkB2+CAAAACPwHVARUBNYEVAFUAlQFfAWACAAAcIIUBCQCxAF8BgAA/g9SCNIIUgFSBn4FAAlygiAAEAD4B5QIlgiUCPQInAiQCPAJAAQAAHOCAAAoASgB/g8oAQgA+AeWCPQInAjwCAAGeoIAAAQAJAQuCiQJpAikCGQILghECAQGAAB+ggQIBAgkBM4EBAMEAgQDzgQkBAQIBAgAAIKCBAAkACQALgDkDyQAJAAkAi4C5AEEAAAAi4KEAJQAlACWCJQIlAj0B5YAlACUAIQAAACNgoQARAA0ALYAJAEkAiQIJAguCCQM5AMAAJKCBABEAMQHTgREBFQEZAREBE4ERAREBAQAl4IECAQJRApmCdQFVAdEAg4DxABEAAQAAACZgoQIpAikBK4EpAL0AaQBpAKuBKQEpAiECJyCggiSCJIIlwSSApIB8geSCJcIkgiSBIIAnYIECEQERAJeBEQMdApECkQJ3ghECEQIBAilgkQARAgkBK4DJAAUABQAJACuDyQARABEAKaCAAgEBvQBVgFUAVQBVAFWAUwBzAMEAAAArIKEAEQIxAiuBKQDhACECKQILgdEAIQABACtggAABAD0B5YIlAjwCJQIlAiWCJQI9AgEBq6CAgDiDyIALwIiAbIAcACiAC8LIgjiDwIAr4IIBIgDCACcBwgIKAhICIgIHAaIAAgHCACxggAABAGEAOQPDgAEAeQHjghECEQIJAgABrOCJAgkBCQGLgHkALQIpAikCK4IpAckACQAt4IACAQIxA8OCAQIBAjwD4QIjgiECAQIAAC4goQApAikCK4PpAykDKQMpAyuDKQGpAiECLmCBAgEBPQDlgCUAJQAkACUD5YAjACMAAAAvYIECJQE1ASWApQClAmUCZQI9geUAJQAhADHggQAFAFUAVYB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5APWD/AL6AvwC9QL9gvkDyQAIAC/hAQAFACUD/YA9Af0BfQF9Af2AJQIlAcEAMSEkACUALQH1gfUB9QH9Af0B9YH1AbUAJAAyYQAADQCFAFWD5QJVAlUCVQJlglUD1QDAAHLhAQARAjUDtYK1A70CtAO1ArWCtQMRAlEANaEAAAEAPQO9gr0CrwAvAa0CpYK9AoECAAE3YQEAAQIZA8OCWQPBAk8Dx4J1AmUDwQIAADmhEABRAX8BP4G/Ab8BvwG/gv8CvwGRAAAAOyEFAhUBMQHDgjkC9QLtAu0C7YLtAs0CkQA7oQACLQE8gMDBPoJWAtaC/4LXwtaC/oLAAIRhQQAdAzUA9YB9ArUCNQJ9gbUBtQI9AiABBOFAAjEC3wLfgv8D3wHfAf+B3wLfAvECQAIF4UEDPQDFAhWBNQBVA1UAVQF1glUAFQOBAAahQQP9ABUDNYB1A/wAQQEpAEmCPQPJAAAACGFJAmkCJQF3gG0CZQJhA/2AdQFtAwUCQAAI4UECXQHRAHuDwQAVAWQBXQJVgk0DxQBAAErhQQIVARUANYB1An0BfQB9gH0A/QF1AMAACyFBASUB/QHlgQEAFQPdABWD1YAdAd0CIQENYXEDzQA9A92BXQHdAXUDX4ElAf0CDQIAAY6hQQAxAcUAMYD1APUA9QD1gdUBhQE9AMAADyFRABUBMQHBgB0AfQH9Ab2BfQG9A70BwAAPYUUANQPxAfuD8QD1A+ECO4EJAPkBSQIAABDhUACSgJKD+sLSgt4D0oLRgvnC1YPQgEAAkmFJAgkBvQAdgF0DXAB9AF0DXYBdAEUDQAASoUEBnQABAauCEQFVABUA0QGLgiECTQIBANphUQIVAwEAo4AhAX0BfAD9AX2A/QJhAcEAG2FAAAkCHQHdgdwD/AHdAJ2D3QHdAckDwQAcoUEAOQB9AHmB/wB7AEEDP4DTADMD0QAAAB0hUIKYgnSCkcFIg0CCPoPqw+qD6oJ+g8CCH6FAABkACwP7gssC3gPLAvsC64LLA9kAAAAhIUkBEwHRAAWAfQB9AP0Af4F9Af0AfQBAAGHhQABNAGEDwYAtA6wALQOhADeCCwH5AUgCJuFAAD0D1QFVgV0BwQAlALeApQP1AKUAoAApoUEDvQBtAi2A/QLtAO0C/QDtge0C/QHBACphQAA+g86AMMN6gMoCKoKrgq/D6oKqgogCKqFBARUAVwJ3gd0AQQM9ANeAFQA1A9UAEAArIWEAJQIRAUGBfQDtA+0AfQDBgVEBZQIlACvhQACdAPUA9YP9A/UD9AP9A/WD1QPdAEAALCFAgiKDf4F2wHeBf4B3gX+Bd8B/gWKBQAAyYW0BLQC9A+2AZQCBADUD/4K3Ar0CtQPAADNhQAA9AT0B/YF9AfwBQQHXAVeBVQHVAQAAM+FAAl0B0QB9A/2A7QG9AYeD/wEFAfUCBAE0IUUBlQGVAPOCiQHBAD0CVQHXgFUD/QJAATVhYoEqgL6D6sDqgECDvoB+wOqA6oJ+g8AAN2FBANcB1wH/gv8C5gLQAc2BxQHdAqEAkQA5IUEDPQDVAn2DwQBdAX0AH4PZAL0BWQJAADlhQAItAXkBQYF9AGwD7QB1AN+A2wFBAUAAOmFIgRqAwIBNwCyD/IKsgqzD6oK6g+iAAAA+4UCACoMSgMLBeIDvgN2D5cPdgO+BeIFAgUHhiQM5AF8Df4BdA3kBAACVAH2D0wBTAYEAAuGRABkC0QI7gVkAnAI9Av2CvQC9Ab0BwAIEYYCCPoHCgRrBWoPagsKC2oLawtqDyoBCgAthgAAAAD+D/8H/gLgB8AC/gP/BT4A/gcAADiGBAD0D/QGfga0BvQLJA7+AH4F/AN0ARQFToYAAAAM8AMQCFAHfgHUAbQHlAi0CLAEEABPhgAAAAz4AwgIKAk+B1wBXAVMCVwNWAMIAFCGAADADzgAiA+oCr4K3ArcCswK3ApICCgAUYYAAAAP8AAQBlAAfgbUCLQKtAiUArAGAABUhgAM+AMICCgJKAs+DWwFbAtMC1wJWAkIAFWGAAz4AwgLqAaoBj4JXAjcC9wI3AtYCggAWoYAAAAP8AAQClAIfg60CLQOlAi0CpAIUABbhgAAgA9wABALUAp+D1QItA6UCrQKMAgAAF6GAAAADPwDBAiUC38HtgO2A7YH5gcsCgAAX4YgAO4EqgSqAyYG8AEYDDgDXwBaB0oEGAJnhgAM+AMYAd4PvA+MCxgI8gCSCJIIkgcAAGuGAAAABPgEiASIBP4HiASIBIgG+AQACAAAcYYABPQFNAU0BfQHNAUsB+wHBAj8AwAMAAZ5hgAA+ASIBP4D+AIABAQEBAT8BwQEBAQABH2GAAAACNwLVAlUCfQHVAVUBVQF3AUACAAIfoYABPgJjgf+B/gGAAgEAPwPJABEAIQAAACAhiAAFAjKDwgEGALwCIgIiAT+B4gEiAX4B4GGAAj4CYgE/gf4DgAIeASCBQwD4AQcCAAIgoYAAPgE/gOOA/gHAAB0AUQBRAl8DMADAACKhgAA+An+B44H+AYACBgI6gwKB4gDeAQICIyGAAD4BIgE/gf4BgAEKAEoAf4PJAEkAQABk4YAAPgEjgf+B/gGAADyCJIIngcAAP4PAACVhogASgjqCVoJTgnqB0oFSgVaB+oHSgxICJyG+AWIBP4HiAT4BBICIgGiCWII/gciAAAAo4YAAPgJiAT+B/gGAAw8AAIOwAkOCHALIAykhiAEIgTSBVYFWgXSB1YFWgVWB9IFIAgAAKqGAAD4CYgE/gf4BgAMJADIAgAC/g8AAQABr4YAAPgJiAT+B4gE+A4ACPwPIgjiDyIIAADAhgAA+A3IBP4D+AoADMgIygj6D8gIyAgACMaGAAT4Bf4HiAT4BgAI/A8kCSQJ/A8ACAAAx4YAAPgE/geIBPAGCADoBwoJjAiICFgIAAbJhgAI+AX+B4gE+AoAAFgARAJTBkQJyAAQAMuGAAASBMoFSgVSBd4HVgVWBVYH1gUSCAAA1IYAAvgCzgP+A0gCMAP+D2IEkgRiBP4PAADZhgAA+Az+B/4H+AYACCQJJAm/DyQJJAkgCNuGAAj4Bf4HiAT4BgAAXgZIAf4PSAFIAgAE5IYAAPgESAT+A3gDIAC4D6YErASwBKAPAADuhgAEFATUBUQFXAXGB0QFXAVEBdQFFAgAAPmGAAj4Bf4HiAT4CgAA5A9kAvQPbALkDwAA/oYABHgE/gN4AwABlAj8B5AMfgKQBVYIAAYAh0AAXAD0BXQFfAX0B3QFfAX0DTQI/AcAAAKHAAj4Cf4Hjgf4ClAASAVuBdQPbAVEBUAECIcACPgF/geIBIgE8A5MCVQF1ANUBVwJQAkShwAA+AX/B/gGAgi+B0II8AsCCv4LIgoACBOH+AWIBP8HiATwBhoP5gUACCQK/gsiCiIKFYcAAPgEjgf+B4gE+AIwDM4DyA9OCHkIAAYXhwAA+AX8B4gEcAKMD1QAVAH0AVQI3A8AABiHAAR8Av8DxAd4DCsC/AEkA/4FAgL+BwAAHIcAABQEpAekBrQGtge0BqwGjAaUBxQIAAAhhwAA+ARIAv4DeAMABtQHXgVUBV4F1AcQADuHAAD4BYgE/gf4CgAA/A88Az4DPAv8BxAAR4cAAPgJ+ASOB/gGAAj8A7QC9Ae0CvwNAARJhwAA+AmOB/4HiAT4BnAAqgL4D6wC+gIAAEyHAAR4Av4DOAOAAP4PkAAkAAgB/g+AAAAATof4CYgE/geIBHgB4AdeBGoFagVqCP4HAABXhwAE+AWOB/4HiAfwCLwK1ArWD9QK/AqACFmHAAj4Bf4HiAR4AsAHvALUB1YB1AdUAdwHYIcAAPgJmAj+B/gKAAD0D1QK1A9UCvQPBABmhwAI+AT+B4gEcAL+D5ICDghgCWIH3ggACHSH+AmIBP4HiAR4AIAHfwKAD/4DEgj+BwAAdocACPgF/gf4BgAAfA1IA/wPaAN8BUgJAACChwAI+AX+B4gGcAT8B1YFPAL4DwQA/AMAAIOHAAj4Bf4HiATwDgQIVAbcAVYJVAlUBwAAjYcEAPwP7ATsAnwJgAd4AIgI/geIBPgGAAiehwAA+ATOA/4DSAIwAX4GqgL+AaoJggcAAJ+HAAT4Av4DyAJ2A34JWgVaBdoBWgV+BQ4JoocAAGIE6AfuBuQG4AfyBugG7gboB3QIAAi6hwAA+AmOB/4HiATwBR4J6g1+DyoBvgsACsCHAAj4Cf4H+AYACJQC9ALuDtQCBANUAgAAxocABPgCSAL+A0gCMAtkCHYH9AF2A3QNAATLhwAE+AX+B4gE+AQAAlwENAl8CTIAWgaQANGHAAj4Bf4H+AYACPQDdAN0A3YP9AMQAgAA8ocAAKALrAqsB6wHPgisA6wKvAesBqAHAAj5h4QEfAQ3Bb4FtgV4B8oHtgWyBboHNggAAPuHAAT8Av8DRAJ+ATsL2g9+A+oHKwdqCwAJDYgACPgF/gfwBnwPPAO8B+ADMAf+AAgDOAQViAAI+AX+B/gCAgA6D0oH3gFaD2oBag9AAB+IAAD4Cf4HiARwAiYPeAt0APoPUAR+AwAMIYgAANQF3AW+B78Ftwk/AJcFrQesBaQFAAAiiAAAqgWeBf4H/gX+Cf8A/gX+B54FqgcgCDuILAAXBN4FQAV2Bf8HfgVwBWQFvwc0CBIAQIgABPgHCAQIBPwHCgQIBPgHCAQIBPgHAARFiAAA+Af8B/oH+AMCABwBIAH+DyABLAEAAEaIAAggCbwEJAS8AKYPfAEkAiQFvAQgCAAATIiIAEgA5A8SAAAAJAAkACQIJAjkDyQAIABNiIgARADzDwgAIgwiAoQBIAgiCOIPIgAAAFOIQABEAPMPCQDIAf8HCADDBRAE8gcSAAAAVIgAAMwA8g8YAIYI9QeUBAAAJAjkDyQAAABXiEAARADyDxkCUALeA1QCVAYABPIHEgAAAFmIAADIAOQPAgBUD3wFdAdkACQAJAjkByAAW4gEAEIA+Q8IAPoD3wLaB/4CAgDyBxIAAABdiAAAJADyDwgAeglaCf4H+gUJBCAA5A8gAGGIAABEAPIPCAn4Ba4D/AOsDfgBAAjkDyAAYogAAIwA4A8cALwHnAeYB7wHvAQAAOQPIABjiIAAiABICMgPKAgaBDwEyACIA0gEKAgACGWIAAAIAYoA6g+YAEgBAAD+DyAAQADAAIAAaIggATQJtAS0B3QEPgT0BDQBtAK0BCAIAABpiAgBiADuD5wAQAkcCOQEFAOEAnQEDAgAAGuICAGIAO4PnABIAQAIiARIBEQCMgIQAQAAbIgIAYgA7g+cAEgBAADQABAJEAj+BxAAAABwiBQBFAV8BVwH3AReBNwEXAFcA3wFFAUQBHeIAAAEAnQCVA5UCfYIVAlUAlQGdAkECQAAgYgAAhAC9AK0DrQJvgS0AbQCtAZ0BRAJAAiEiAQBhQD3D44AZAEADCICogF+AKEDIQQgBIuIkAKIArwKgg6ICcgIjgmYAqoGygrKCqgIjYgAAYwA7A9YAQAA8AcsCSgJ6AsICvgJAASSiAgBiADqD5gAAAj8CSQJJAkkCSQJ/AkACJaICAGIAOoP2AAAAPgPiASIBP8HiASIBPgPnIgAAYoA6g/YAAAESAJIAf4PSAFIAkgEAACriAgBiADKD7gBAAz4A8gISAl+BkgGyAkYCK2IhAKkAqQKlA6MCaYIvAnWAtYG1AXEBbQIsYgAAYgA6g/wACAA/A8CABAH/gCQAxYMAAC0iAgBiADsD5gAAACoALgDrAKoCpgKqAagAMGIAAFUC9QHXgRUAVQDEAz+AhAD0gQUCAAGwojWAtYC3gquDp4JxgSAAZ4CwAbABf4JAAjFiKACrAKQCrwOgAmoBKgBvAKoBqgEqAgAAMaICAGIAO4PnABIAQAELAUgBT4FIAXsDwAAz4gABEQFfA18D3wJ/gl8A3wFfAV8C0QLAAjUiBQA1A90APQHbAVkBWYFzAbUAKQPJAAAANWICAGIAO4PWACIAAABxA+yCIgIsgjED4gB2IiABKwCrAqsDoQJ3gSEAaYCrgasBKQIAADZiAABiADrD9gAgAIqAeoHvgSqBKoEvgcIANyICAEIAc4PuAAAAOgPqAKoAv4PqAKqCuoH3YiQAr4CmAqYDr4JgASoBKgBvgKoBqgEiAjhiAgBiADsD9gAAAB8CVQJVAn8D1QJfAkAAOSIAAGKAOoP2AAADPwDRAC2ApQPlAKUAgAA84gAApwEhQK2DrQJ9gS0AbQCtgaFBJwIAAD4iAgBigDqD9AAgAT8BNQC1A/8D9QB/AKABPmIgAJEAnwBfAf8BP4EfAF8AnwCfAXEBAAA/YgIAr4CnAq+BpwF/ASAAZwCwAbABb4JAAQCiQAAxAD1D2wAAASUBN8HlAQAAP8HIABAAAeJgABIAO4HeAAABT4F/gW8ArwCvAW8BAQEEIkIAYkAyg+4AAABvgeqBKoFqgaqCL4HAAASiSACFAL0AgQOZAl8CT4JfAI8BnwFJAkABCWJAAGIAMwP+AAADvwBdARcATwJ3A8cAQAAKokAAIgB7A/YACAI7AcACPwLVAhUCXwKAAgyiQABlADUB7AAAAT4A+gD7AP4B+gD6AMIAkSJQAXEBfwD7A/8CcYJ/APsBewF/AlECQAAX4kAAIgA7g/cAQAJTAVeAVAPTAFeBVQJEAByiQAFDAV8A34PfAt8CQAJfgP8BfwL4AtACX+JBAD0D5QE1AQ8BBQEFAR8BJQElAT0DwQAgYkAAIIIugiqC/4GqgSqBL4GqgWqBLoIgACGiUQBXAG8D1wA3AjsC/wH/Af8B/wLPAgACIeJAgBeB9YH1g/eB1YHFgz+A7YCtgr+BwIAi4kACAAI/AlUBVQDVAFUAVQHVAn8CQAIAASPiUgISAT8A0gBSAoACPwFVANUD1QJ/AkABJOJAAgMCPwL5AbkBuwC5ALkBuIK+gsCCAAElokIAYgAzg+4AAgJAAj8BVQDVA9UCfwJAASaiQAIOAgKCOwL6AbqAuwC6A7sCwoIOAgABKeJAAg8CPwL/Af8B/wDwAPsB+gL6AsoCAAEqokAAKQErALmD6wCoAj8BVQDVAFUD/wJAASziQAAMAHsB7gH6AeoB/wNVANUAVQH/AkABLqJAAAwCB4I3gvQB9oD2gPYD94LHggwCAAEvYkACD4I7gv+B+4H7gPAA/YH/Av8CzQI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AAAAAPwProsgACQI7A8ABAQCeAiCBQwCgAV4CAQIAAiviyAAJAjkBwgCQAJEAPwPRAAEAPwHAAgABrCLIAAiCOQPCAQAAMQHRAhECEQIRAj8CAAGsosgACII5AcAAogIiAT+A4gAiAD+D4gAgACziyAAJADoDwAEiAKoAKgA/g+oAKgEiAMAALaLEAASBvQBBAWADDoCIgGiCGII/gciACIAuIsgACIA7A8ABLAAjgCIAPgPiACIAIgAAAC5iyAAIgjkBwgCYAD4DwYAgAD+ByAIGAgIBrqLIAAiCOQPCAIgAJAHCAmGCIgIkAggBiAAvIsgACII5AcIBGAAGA6GBWAEBgUYB2AIAAC9iwAAJAjkBwgCAAz8AyQGxAEkAvwHAAgABL6LIAAiCOQHCAIgCqAIXgVCAkIGfgXgCCAIv4sgACIE7AcEAgAICAb4AUoISghICMgHCADAiyAAIgTkBwgCQAlIBEgD/gDIA3gEQAgAAMGLIAAiCOwHCAIACOQPBAgECPwPRAhECAQIxIsAACII7AcEBIACugCCAP4PggCyAIoAAADFiyAAJAjoDwgEAAD8DyQJJAkkCfwPAAgAAMaLIAAiBOwHCAIACHwGRAFEAEQARAF8DgAIyIsgACII7AcIAmACEAAOAPgPKAEoASgBKAHJiyAAIgjkDwgEAAD8DyQAJAHkDyICIgIAAMqLIAAiCOQHCAQAAlAISAkGBcgEUAIQAQAAzYsgACII5AcABgIA6gMqASoB6gkCCP4HAADPiyAAIgTsBwQCIACiD5oEhgSiBKIEngcAANGLIAAkCOgHAAIkAqQCrAKUD7QCrAIkAgAA1YsAACII4gcCBAgASATIBwgC/gAIBwoMCALXiyAAJAjoBwgCoACoAqgCvAioCOgHqACgANqLAAAiDOwDAA74AygAKALICX4EiAfqCAgG3YsAACQI6AcIAiAApA+kCPwIpAikCKIPIADeiwAAIgjsBwAAsg0uA8IE8AkCCv4LIgoCCuGLAAAiAOwPAAD4DxYA1AdUCFwK0AkQCAAE4osgACQI7AcABBAAyAOuAqgK6AsICPgHAADliyAAIgjsDwAEJAG0CKwEZwQkBhQFhAgAAOaLIAAiCOQHAAIIAEoBSgH4D0gBTgEIAQAA54sgACQI6AcAAhgACAEoAe4HqAiICJgEAADriwAAIgjkDwAA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gAT/BJgEmA8YAL+MAAQQBPwF9APsA/AB9AHsA+QD1AUMBAAAwIwAABQIzAvmCvQK7ALgAv4K8gryCx4IAAjDjBAACADcA8QL4AvqA+oD/gvqC+kDKgAAAMSMAAj8DVQFVAH8BUAA+A+sAqgCqAroBwAAx4wQCBII9Av0BuQG9AL2AuwG9Ab0CxQIAADKjAAI/A1UAVQF/AFIAOgJSAR+AogFbAgIBtOMIAAsCOwH/AbsAv4C7AL8AvwG/AcMCAAI24wAABwIzAXuBewF7AHgAfwF7gX8BRwIIADcjAAI/A1UAVQF/AUAAb4C6gmqBKoDvgiAB96MAAAcCMYP9g30DfYF9AX0DfYNxQ8cCAAA4IwACPwFVAVUAfwFIAC0B6QEpgSkBLQHJADijAAIPgj6B/4H+gf6A+AD4gfaB5oHJgggAOOMAAQ6CO4H7gf+B+8D7gP+B+4H7gc+CAIA5IwACPwFVAVUAfwDqAjsBBgH2ga8CbgJEATmjAAI/A1UAfwFAAjUDxQI0AeQBP4DEAwUBuqMIAAcCMwL7Ab6BvgC7gLqBuoG2gsKCAgA7YwABPwHVAFUA/wFAAGkB/4FpAW8BaYHIAD0jAAEeAJYAfwPWAE4AMAL7ArkAvQG7AcACPqMAAD8DVQB/AIICGwF+A9oAfgPbgPoBUAI/IwACPwNVAFUA/wGwA/sAv4C7Av+CuwHIAL9jAAArAh8BPwH/AP+A/wD/AP8B7QEpAQAAAiNAAj8BVQB/AUAAPwP5wrkCvwK5ArnD3wACo0AACgI/g9eDVwFXAV8BV4FXgXsDxwICAgPjQAMggO2CjoHugm7A7oFOgC6B7oPCgQAAB2NAAAACPwJBAQEBAQC9AEEBAQE/AkACAAAHo0ACAAI8AsQCBAEHgLUARQEFAT0BQQIAAAfjSAIEAj4CRQIFgQUAtQBHAQQBPAJAAgAACGNAAAUCNQLVAhUBlwBVARUBFQI1AsUCAAAIo0ACP4JAgT6AwIA/g4AAAgDiAhoCP8HCAAjjRAAFAjcC1wIXARcA14AXARcBNwFFAgAACSNAAAeCMAFQAReAkABZgRaBFoI1gsSACAAJY0ACP4IAgb6Af4MAABwCI4EiAN4BAgIAAAmjQAEfwf5AAEC/wIACP8HIAToACYDIQQAACeNAAAICMQLXghBBkQBTwRUBFQI0gsKCAAAKI0AAPAHDADsCSwELAK8ASoEKgTqBQgIAAApjQAAfA/0AAQC/AAADvwBNAzUAhQD8gQECCqNCAAICNQLVAhSBFoDUgB0BFQE1AUECAgAK40IACgI7AtqCFoESANoAGoEXATEBQgICAAsjQAI/g3yAwIC/gAADCQCIgYqCeIIIQgACC2NAAj8DeQDBAD8DhAAzAEKAcgJCAj4BwAALo0AAPwJBAT0AwQA/A4QAAgEDgQIBAgEOAQvjQAACAj8C2oIagZ+AWoEagRqCP4LCAgAADCNAAAoCLgJuAS4ArgIuAsICP4BCAYOCAgEMY0ACPwIBAb0AfwCAAhQBP4EUAdUCVAJAAQ0jQAI/A30AwQA/AYAAIAP/gSIBIgEiA8AADWNAAAgCPwLdAh0BHQDfgB0BHQE/AUgCAAAN40QAAgI3AtCCEgESANOAFgEagjiCxQAAAA4jQAAAAjcC1IIWwRAA1IATgRiBOIFHggAADmNAAhACN4LdghfBFYDVgBfBFYE1gUWCAAAOo0AABQI1AtOCGQGXAFABFwEVAjUCxwAAAA8jQAE/AL0AQQE/AAABugBCAh+BIgH6ggIBj6NAgg6COoFagR+BGoDagB+AmoE6gU6CAIAP40AAPwN9AMEAPwFwAD4D64CqAKoCugPCABBjQgABAjfBUAEagNqAGoCfgJqBOkFKggAAEKNAAj8BuQBBAT8BAAAyA/WBKQE1ARMD0AAQ40AAPwN5AP8DAAM+AMICEoI6g9ICEgIAABEjRAIEgjUBUAEaAJmA1YATAJUBNQFDAgAAEqNAAD8DeQDBAD8DgAAUANoCOYPaABIBxAES40AAPwN5AP8AAAI1A8UCNQHEAD+AxAMFgZMjQAA/A/0AQQE/AWAANQPfgVUBVgF1A8QAE6NAAj+BfIDAgD+BQAApAlUB/4BFAU0CQAAT40AABwIhgu0CLQEtgK0ALQEtgSFBRwIAABQjQAI/AkEBPQDBAD8DgAAvgDqC6oGqgm+B1SNAAj8B+QBBAT8BQAAqA+kBKYEtASkByAAVo0ACPQElAL+D5QB9AoACPgH1gMcCPQLAAhYjSAELgSeBV4EXgJeA0gAbAJeBJwFJAQkAFqNAAj8DeQD/AAACFoF/A9YAfgPXgX4CUAAW40AAKwIvAj8BbwEvgK8ALwE/AW0BCQJAABejSAALgicC04IfARAA24AXAROBJwFLAgoAGCNAAB+BAID+gACAn4AmAd/BXwFfwX8BwAAYY0AAPwN9AP8DAAA+AcOAOwPzAvIC9APAABijQAM4gO+Cv4H3gw/A/4M3gc+Af4PBgQAAGSNIAKkAaQIJAbkAT4IJAjkDyQApAAgAwACZo2ACSQE5AM+COQHJACACTQEygKIA3gECAhrjYAJJATkAz4I5AekAIAH5AE+COQHJACAA3CNIAgoBKgDKAQoBPwPKAkoCSgJKAkgCAAAdI0QBtQBFAL+A1QEVARQBAAE/gUIBBAEIAR1jRAG1AEUAf4DVARUBAAFzAQwBEwEggUABHaNIAykAyQE/gekCKQIAAgkCPwLJAgkCAAAd40QCNQHFAL+B5QIlAgACOQJJAokCjwKgAmBjRAG1AEUAf4DVARQBAQFUgUiBaQEiAQIBIWNAAjYBxgE/AeYCBAI1AtMCmQKZArcCwAIio0gDKgD/AeoCAAI+AmICAgKfgnICioKAAiLjSAGqAEoAv4DiAQgBBgFVgVUBVwF9AUABJWNIAaoASgC/AOoBQAFXATcBNwF3ATcBAAEmY0gDKgDKAL8B6gIAAj0CzAIvAiQCvQJAAifjQAIpAckAv8HpAgECPQLkAheCZAI9gsACKONFAAUBJ4D9AMQBP4EqgT+BQAE5AUcBQAEqI0QDNQDFAL+B5QIpAjvC14JSgluCN4LAACzjQAAAAg8BKQDJAQkCOQPJAkkCTwJAAgAALSNAAjeBxIE8geeAAAO/AEAAAQA/AAABwAIvo0ACN4HEgTyB54AAAj4DwAI/g9ACEAIAADDjQAI3gfyB5IEngQAACQMIgP+ACIDIgQgCMuNAAieDxII8geeDAAICAf/AEgLSgbKCUgAzI0ABN4HEgTyA14CAAhOBEgD/gBIA0gESAjRjQAE3gcSBPIHngQAAPoHtAj0CgQK/AkABNuNAASeDxIE8geeAAAM+APICX8GSAXYCAgI3Y0ABNwHFAT0A5wCAAD8DxQFFAUUBfQFAATfjQAI3gcSBPIHngAACPwPVAjUAVQGfAUACeGNAASeB/IHkgQOAuAM+AMOCPgHCADoAQAA6I0ABJ4H8gfyB44EIAC4A6gKrAq4CqgGqADqjQAAHgfyB5IEPgz4BxYA1AdUCFwK0AkQBO+NAAjeBxIE8geeBJAAiA/WCKQIvAjED4AA840ACN4H8geeBAAA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dAV0BfwPIASTjwAAfAJGAvQPIAD4D7QC8g+UARgI8AcAAJWPRAB0Ak4C5A9AAhAC9A60Cb4JtAJ0BRAJlo8AAHwBRgH0B0ABFAC0B7QF9gW0BZQHgACZjwAAdAJOAuQPFADuB7QK5A90BIoDeAQACJuPIAAkASwBPAEkAecPJAE0ASQBJAEgAAAAnI8AAEIFXgVWBdYFVgV3D1YF1gVeBQIFAACejwQAkg+SBP4EkgcQAEQBdAHGD3QBRAFAAJ+PAAT8A6QPpAS8BwAAWAFIAc4PaAFIAUAAo48AAEQJVAnHB3QBBAjwBJQC/g+UAvQEAAimjxAIzAfoAUAIEAf+AOAPCABaAcYPaAEAAKiPRABVCcYHdAEACHAG/gEAAFQBxw90AUAAqY9EAFUJxgd0AUAADgjkBwAAVAHHD3QBQACrjwgAWgnsB0ABHATyBIgEAARVAccPdAEAAK2PBADMD1IBegfWANYPAABUAccPdAFEAQAAr48IAFoJ7AdIAUgPawVoBwwAXQHvD0wBAACwjwAAAAz8A0QA1A9UCFQE1AFUAlQFVAlACLGPAACAAn4CIgbqBqoCKgpqCqoG6gJiAwACso8ADPwDbAnsCf4H7AnsBf4H7AXsBfwLQAm5jwAIIgTsAwgEAAgIC8gIPggICggK+AkABLqPQghGBMgHAAQECMQLPAgECgQKBAr8CQAIu49ICFIE1gMEBBAIEAgQCP8LEAgQCBAIAAi8j0IIQgTMBwAIAAqCCWIIPgjACAAJAAoAAL2PAAgkBOgDAAQECAQKBAr0CxQIDAgECAAAvo8gCCIE7AMABAgICAvICD4ISAiICAgLAAjBjyAIJgToAwAEJAgkCCQI/AsiCCIIIggABMKPAAgkBOgDCAQgCCQKJAr8CSQIJAgkCAAAxI8gCCQE6AMABDAECAmsCmgKKAooCggJAADFjyQIJAToBwAEJAgkCPQLJAgECPwJAAqACcePIAgiBOwDAAQICCgIyAgICggK/gkICAgIyI8kCCQE6AcACAQLxAg8CBQIFAoUCvQJBATOjwAIRgzIAwAE/AkECQAI/AsECAQJ/AgAANCPIAgkBOgHAAgQCtQJNAkUCVQJlAkUCgAI0Y9CCEIExAcACAAL/ggSCBII8gsSCBIIAADUjwAIQgTMBwAIAAv+CDIK0goSCdIKMgoCCtiPAAgiBOwDCASACEQIJAj8CwQIJAjECIAI2Y8ACCQE6AcACCgKKAnKCEwIuAgICQgKAADbjyAIIgTsAwAESAhIC/4ISAhICP4LSAhICNyPIAgkBOgHAAgQChQJ9AgUCPQLFAqQCQAA3Y8ABCIE7AMABFQEVARUBP4FVARUBMQFAADejwAIIgTsBwAEFAksCSYJ9AskCSQJBAkAAN+PIAgkBOgDAAQACfwIJAhkCOQIJAk8CgAI5o8ACE4EwAcEBfwEBgj8CwAI/AsECvwLAAjqjwAIJAToBwAI+AtICkgK/gtICkgK+AsAAOuPRAhEBMgHAAQACPgLSApOCkgKSAr4CwAI8I9CCEIEzAcABIgJaAgICP4LCAhqCIoJAAj0j5AI1AS0AwAE/AkECvQKlAr0CgQK/AsAAPePQghGBMgHAAgkC6gIYAj+C2AIqAgkCwAK+Y8ACCQE6AMIBGAICAv6CAwK+AsICOgIAAD9j0IIQgTEAwAE/AlUClYKVQpUClwKwAsACACQQAhCBMwHBAgACv4LKgpqCKoJXgpACgAAAZBCCEIEzAcABEgITgpICfgISglKCkgKAAgCkCAIJgToBwAEFAjUC1QKfApSClIK0gsQCAOQAAhECMgHAAScCEAK/gkACP4JQAqcCoAKBpAACE4MwAMIBOoIjgqICvgJiAiOCOoICAgJkAAIJAjoBwAIIAqsCWgIPgjoCygKKAogCQqQAAgiBOwHAAQiCPoLRggwCv4LAAg4CMAADZAAAJII9AaUBQAI9gsQCF4JEAmUCvILAAgPkAAIJAjoBwAELAgsC9wIXAicCqoKqgkgCBCQAAgiBOwDAAQSBaoIrgpSCuIJUgiKCAAEEpAgBCIE7AMABHQFVwXUBPwFVgRVBdwEAAQUkAAITgTABxAESAlUCFQK8glUCEgJUAkQCBeQAAgkDMgDEAQECHQK1ApUCtQL9AoECgAIGZAAAFQEfALYAwAE+AV4BXwFeAX4BQgEAAQakCAIIgTkAwAE+gmuCK4I+guuCK4K+gkAABuQAAgkBOgHQAguC/QIAAokCvwLJAokCgAAHZAACCYI6AcACEgK/gkICPwLEgjyCxIIAAAekAAA0gi8BpgFAAi8CrQK9Au0CrwKAAoAAB+QQghCBMwHAAh0ClQJ1Aj+C9QIVAl0CgQKIJAACCQI6AcABCAIrAuoCrwKqAqoCyAIAAAikAAIJgTgBwQIlAqSCq8K6guuCqoKCAoQCCOQAggmBOQDAAR8CVwJXAn+C1wJXAl8CQQJLpAACE4IwAcQCJQKVApUCP4LVAl8ChAKAAgxkAAIQgzMAwAE/gkCCOoJegnqCQIK/gkACDKQAAhGCMgHAAQQCP4LqAr8C6oKqAoICgAIOJBCCEQExAcQCHgKVgnWCHQI3AtQCnAKAAE7kCAIJAToAwAEnAhUCnwKVAlcCdQIHAgAADyQJAgoBOgHgAt8BWwN7A9sDWwN/A8ACAAAPpAACCIM4gMIBOgF/Aj8CwsI6ggEDOgPCABCkAAIRgTIAwAEKAluCdgIqArICa4IqAgICUWQQAhEBNgDAAX8CBQI1AnUCdQL9AncCQAIR5AACCQE7AcACP4Lagj+CX4Jagt+DMAPAABKkAAIRgzAAwQF/AgXCuQJDAhGCvQLVAhECEuQAAgiDOQDAAR6CXoJegn6C3oJegl6CQABTZAACCIE7AMABfwI1Au0CPYLtAj0C7wI4AtOkAAIQgjMBwAI4As+COIJegnqCT4I4AsAAE+QAAQiAuwDgALcBTwFvAW8BTwFPAf8BwACU5AgCCQE6AcABAgI+gu+CrgKvgr6CwgIAABUkAAIRgTIAwAE1An0CdQJ3gvUCfQJ1AkQCFWQAAhECMgHAAj8CtwL3AreCtwL/AqICgAIV5AACCIE7AMABO4IagpqCX8IagrqCi4IIARZkJAI9gaQBQAIuA6kDrwO9g+sDqwOpA6ACFyQAADRDLYCEAVCBPoJBgpcCPYLQgjBCgAAXpCQCPMEFAOABH4IAgvyCD4Kfgh1CXUKMAFgkAIIQgjCBwgEfAlcCdwI3gtcCfwJiAoACGOQAghCDMQDEAT8CfwK/Ar+CvwK/AqQCwAIZZAACCQM6AMABEwJfApkCuwLZApiCmoLQABokIAI1ggwBwQG9Al+DVQNRAsQCI4LeAoICmmQAAhGDMgDAAT0CTQI/Al2CfwJNAr0CQAIbZAACBEE9gMABP4Jvgq/Cr4Kvwr+Cx4IAARukAAEJgLoA4ACfAQUBXQEVgZUBXQEFAUAAHKQkAjUBLQHAAb8CQwItAqMCtwLjAq8CgAKdZAACCYI6AcABHwJbgtsCWwJfA3+D3wJBAF3kIAI1AS0AwAF/AjsC/wM7A78D+wMfAkACXiQAQgmBOQDgASuCu4K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SgJABAAAyJEAAJYBUgD+B1UAAAb/ASEA4QAhAz8MAATKkQAAKgOiAP4PowCqAKACrgKSD6oCpgIiAsuRBACsAfwPogCoAD4C+gK+AroHvgL6Ai4CzJEAAAAEvgSqBKoEqgT+B6oEqgS+BAAEAADNkQAAEAT0BfQF9AX8B/QF9AXyBfIFEAQAAM6RAAB8CVQJ/AdUBXwBAAgkCPQPLADkAAAAz5EAACAE/Af8B/wH/Af8B/wH/Af8ByAEIADRkRAAsAiQCZgLlgjxD5IIlAiYCpAIMAgAAN2RUAhYC1QI8gdUBEQFAAAgAP4PIAAgAAAA45FQCFgLVAjyB1QERAUQAM4ICAkIDPgDAADnkUAIWAtUCPIHVAYADP4DAAD8BwAA/g8AABWSUAhYCfYHVARUAQAIRAj8D0QIxA98CEAAHpJQCFgLVAjyB1QEWAUGASUJJAkEBfwDAAA0klAIWAtUCPIHVAUQBEgA1w9SAEwE0AcQAESSUAlcCPIHVAREARAETgRIA/4ASANIBEgIcZJQCFwJ8gdUBAAN+AMIAAgH7gQIBIgHAAh0kkAIXglAC2AJXgnQD1YJZA00CVQJRAgAAICSUAhYC1QI8gdUBwAA/g9KCMoBSgZ+CQAIg5JQCFwJ8gdSBAQNZAQ0AywAJgC0DzQIRAaFklAIXAnyB1IEhAT+DwIA6gMqAcII/gcAAJiSWARUBfIHUgREBRACGAGUD+YEnASEDwAArZJQCFwF8gdUBFQBAAioBP4FqAaqCaoIAAazklAIXAX2B0AFEAD8BJIGkAGSD/QIGAgQBLeSQAhQCVwE8gdEBggN9gcQAF4BEAn2BwAA0pIAAFAIXAXyB1QFAABIBa8Fkg+uBaIFQATqklALWAT2B0gEWAUIAOgPqAL+D6gC6g8AAO2SUAlYBVQE8gdUBAABegzMA0gAzA96CAAG/JIAAFALXAjyB1QH/AsMBKQD5AMMC/wHAAAEk1AIWAn2B1QERAUABNgCVgjUD3QATAVABSKTUAhYBfYHVARUAQAIKAmeBRgHWgcqC6gIJpMoBC4F+QMqBioHgAe+AOsPqgCqBL4DAAArk1AIWAlUBPIHRAcABL4E6gOqBqoJvgcAAC+TWAhUCfIHVAQEBSQA/gdkBWQFfgXkBwAAMpNQCFgJ9gdUBAAFogQqAOoPqgEqAr4CoAQ2k0gLXAjyB1QERAEUAFQP1Ah+CNQDVAVACUqTWAhUCfIHVAQEBfQEtAKUAf4PtAH0AgQES5NQCVgI9gdUBQQA4A8+ALIDqgI+CeAHAAB1k0gIXAnyB8QHMAwuA+AEqgb/C6oKvgoICH6TaAhsCWoE+QdqBwIM/giuCv4Prgr9CgAIjJNIBM4E+QdKBewFrQL+D6wA/A+vAvwEAACWk1AIWAhUCfIHVAQACfQLsAq+ArAC9gsACK6TQAhQC1wI8gfUBQAA/AvsCu4C7Ar8CwAK4ZNQCFgIVgnxB1IECg3qCG4HawFuD+oJCAQYlFAIXAXyB1QFAADyC3oLcwvzD3ILfgvyCzWUMAhaCvwHHAd0ALQHvgdUDP4FEAfWCAAGUZRQCFwJ8gcEB34Aqg/uCboPAAlOD0gJSA9wlAgIXAnyB0QFCADoD8QHkgL0D4QCaA8AAH2UUAhcBfIHVA0ACBgI3gXcA9wL3gusCygAiJSYAIYI9Q+UBIQEIAAgACAA/g8gACAAIACJlAAAmACGCPUPlASUBAAABAgECPwHBAAEAJOUAACYAIYI9A+UBKACHABKAIgJCAj4BwAAmZSYAIYA9Q+UBJQEAADyAIIA/giSCJIHAgCdlJgAhgj1D5QEAAToAQgBCAH+BwgJCAnoDZ6UmACGCPUPlASEDIAIOAgABP4DgAEIADAAn5SYAIYI9Q+UBAQE8AGQAJAA/g+QAJAA8AGglLgAhgjlD6QEBADwDxACkAF+AJAJ8A8AAKKUmACGAPUPlAQAAP4PAgIyAfoBAgj+BwAApZS4AIYI5Q+kBKQAAAz8AyQBJAkkCfwPAACmlAAAmACGCPQPlASEDDAIDgboAQgDOAQICKeUmACECPYHlASEAhAATgJICUgJCAz4AwAAqZSYAIYA9Q+UBAQEEAHuAQgJyAsICPgHAACulJgAhgj0D5QEhAwACEIO/glCCEIO/gkACLGUmACGCPUHlAQAAsgISAT+BEgHKgmqCQAEs5SAAKwI6geoBIACEAD8D5AEkASQBPwPEAC7lJgAhgT1B5QElAIEAIAPgAT+BJAEkA8AAL6UmACGCPUPlAQABP4BkgCSAP4PkgCSAP4BwZSYAIYI9Q+UBBQEwADODMgC/gFIAkgEQAjDlJgAhgj1D5QEhAQQAEgBVgJEDcgAEAAAAMWUmACGCPUHlASUAgAAvg+CBIIE/gTADwAA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AAT+AtAI3gfQAPYCAASblgAA/w8ZAO8AbAa3AK4EoAenALgCrgIiAJyWAAD+DwIAOgHGABAC9AL8AvYP/AL0AhACoJYAAP4PMgDOCQQEbAFkDWwJZAtyCeoBAAyjlgAA/g8yAM4AAAnuBZgDvwCYA+oPqAIAAKeWAAD+DzIAzAhABLYHgASqCfgMyAvOCCgJqJYAAP4PMgDMCOIHFATUC+wI7gl8DewPBAiqlgAA/g86AcYIUAS4AvQAEwj0BrgE6AwIALGWAAD+DwIB/gDADfYB8gf6C/IN+QH1DaAItpYQBFQFVAVUAlQK/gdUAVQCVAO8BJAEAAC7lhAIEAl4CXwJeAd4BXwFeAV4B3gJSAgACL6WAAAUBqQB5AAcAyAA/g+oBPoHqASoBAAAwJYAAFAAWADED+AK3grwCvAPxArECtgKEADBlgAG/gFCAPoHAgAiAPoHUgX6B1IFUgUAAMSWCAzoAx4IyAcIBCAD/AeqBKgE/AeqBKgExZYkBrwBZAj8ByQA8A+uBKgE/geqBKgEAADGlggICAV8BV4DXAPcD34BXQNcBVwFRAkAAceWAAAEDvwBrADsD+wK7ArsD+wK7Ar8CgQIzJYAAPAPAAT+BwAE/gcwAv4PqAT6B6gECATPlhAAuASmBLQE7A8gAPgPrgSoBPoHqAQIBNGWJAC0BI4ChA+8AkAEMAD+B0gF/AdKBUgF1ZaAD3wANAe0AjQJ/AcwAPwPqgT0B6gECATWlgAA7gSqBPoDrgLgBjAA/g+oBPoHqASoBNmWAAAICL8EvAS+BbwGiAK+ArwFvgW8BCQE3JYgAKQGlADGD7QCAAD+D6gEqgT6B6gEqATelgQIfAl8BaoDUg04AfwPqgSoBP4HqAQIBOKWgA/0ANQD1gLECPQHIAD+DygF/AcqBQAE45YAAPQJ1gX0A9YF9AUgAP4PqAT8B6oEqATolgQA9A8UAFQBFAD8DxQAVAFUChQI9A8EAOqWGADKCsoKygqKCr4KigrKCsoKyg8YAAAA75YACJgIygjqCcoGngTKBIoG2gnKCJgIAAjwlgAKGAmaBboFCgM+ARoJOgmKBxgBAAIAAPKWAAEMBWUFZQdFBV8FRQVlB2UHBQ0cCQAA85YcDMYDdgh2CX4HRgF2CXYJdglGCVwHAAD2loAAmACaAboFSgXeBcoFWg26C4oBmACAAPeWGADKD8oKygqKCr4PigrKCsoKyg8YAAAA+ZaAAJgA+gf6CuoK/grKCvoLegrKCRgEAAD7lgAAGADaB/oCygLeB9oK+grKCxgIAAYAAP6WAAFYC1wLXAvMBtwC3AJ8C0wLXAcAAAAAAJcAAFgAWg96AUoP3gFaD3oBSglYB0AAAAAElwAAHgAOCK4HhgHeBYYG1gLeCoYHHgAAAAaXAAhMCeYFdgsmCD4NRg32D3YNZg0MDQAAB5cYDNoDegn6B8oF3gXKB/oF+gXKB1gLAAkJlwAADAFmBeYG5gbGB94Gxg7mDuYHTAUAAAqXAAg4CYoLqgmKD74Jig+qD6oJCgs4CwAIDZcAAQwBpg+2C4YL3g+GC7YLpguMCAAAAAAOlxgCWgtKC2oLyg9uD0oPWgf6B0oLWgsYCBOXAAAOAA4I1guuCq4GBgKuBr4K5gsOCAAEFpcAAJgEigK6D4oCPgCKBroBug+KApgEAAQclwAAmAS6AroPugI+AL4H+gX6BfoFyAcAAB6XGADKD/oF+gXKBd4MCgj6C/oFygXYCwAIJ5cAAAAMTAPmD/YBRgMeCsYGdgPmC0wHAAEylxgIyg16CXoPygueAooOegv6CkoPWAIAADiXAABMB+YH9g/GB14DBgz2A/YC5grMBwAAOZcABuwBdQdtBW0FBQcvAuUCpQ+tAu0CoABClwAO7AFlBP0E/QZ1BOcHZQb9BvUG9QQgAEiXAAgMCeYL/gtGCa4PpgnmDU4LtgjkCAAAUpcQABQA/A+8ArwCvgK8ArwKvAr8BxQAEABWlwgC6AIOAugBAAD8D7wCvgK8CrwK/A8UAFmXEADcD9wC3grcDxAAWAlWCfQHXAHwAUAAXJcQCNwH3ALeCtwHAACIAqQK6geiAuoDgABelwABKAEoASgB/g8AAAAA/g8oASgBKAEAAWCXAAQIB3wHXgdcD1wAXgBcD1wHfAcIBwAEYZcADvwBBAQ0B3QHVA8GADQPdAc0B1QHAABilwAA8g8SBPIHXgVSBfIHEgQSBPIPAgAAAGmXAAAEAuQCvgK0AvQPtAK0Ar4C5AIEAgAAdJcEAu4C/A+uAuQCAAIwAP4PAAD+BxAICAZ2lwQA7gKsAvwPrgJAAP4HQgh+CEII/ggABouXAADkAq4C/A/uAgQKIAgkCb8PJAkkCQAAjZcEAO4CrAP+DuQCAABICcYJdAZEBegEQAiRlwQC7gL8D64CZAjgBwQIkAt+CNAIEAsAAJiXBAD+ArQC9A++AkAI9AcQAF4BEAn0BwAAoJcEAv4C9A+0Au4C/AaKA+gP6AGICvgHAACtlwQC7gL8D24A/g98CawH/ASsCPwIBAgAANOX/AKsAq4PrAb8BgAE7AeuBawPrAXsBQgE5pcAAJIAkgCSAJIA/w+SAJIAkgSSBIADAADnl6gAqAD8D6gAqAIAAXQMhAN8CAQI/AcAAOmXAAD0AtQC3g/UAvQCAACoAP4PqACoBIgD7ZcAAFAFUAVQBf4HAAQABP4HqASoBKgEAADzlxAAFADUB1QFVAVWBVQFVAVcBdQHFAAQAPWXIADoB2YFdAXkByAAEAEuBagICAj4BwAA9pcQANwHVgVcBdQHBACwB44EogSiBJ4HAAD7lxAA3AdVBVoF1AcEAPgPVANUA1QD/A8ACP+XlAC+ANUH4Af+B+4HzgfAB94HxgeaAAAAAZgACAQI/AusBqwGrAKsAqwGrAb8CwQIAAACmAQIBAj8DwQAAAj8C6wKrAKsBqwG/AsAAAWYBAEEAfwBBAEECPwHrAasAqwGrAb8CwAIBpgACPwHAAD4AwAA/g8AAPwHrAasAqwK/AsImEgIyAQkBBADBAj8C6wKrAKsAqwK/AsACBCYJAgkCPQPPADkCAAI/AusAqwCrAr8CwAAEZgAABQH9AAUAvQDAAj8B6wGrAKsAvwLAAgTmOgAiAD8D4gE6AIACPQHtAa8ArQK9AsAABeYAA74ASgMvAKoA1gI/AusCqwCrAb8BwAIGJgAAFgA1AdSAMQJDAT8B6wCrAKsBvwPAAAtmAAAfAhMBUwEfAcADPwJrAqsAqwG/AcACDuYEADeBRAEfwIUAZAA/g1WA1YDVgH+BQAEPJgAAHgGWAH8D1gBOAr8CawGrAKsBvwHAAhGmAAEvASsAvwPrAKcCPgJrAqsAqwG/AcACEyYQAxcA1wE3AdcCQAM/A1cCVwJXAn8DQAMTZggAawPtAVWBaQHDAD8B6wGrAKsCvwLAABPmAAM7AM8CK4JLAUkAvwLrAqsAqwG/AcACFSYAAzkAywIpgosBSQA/AusCqwCrAr8CwAIWJgAD/wAfAasAKwP/AEACPwHrAasAvwLAAhbmAQK/AvcCt4C/AsAAPwHrAasAqwG/AsAAF6YAACsBJgC3gGcAogI/AusBqwCrAL8BwAIZ5gADvoBKg+qB9oHgAcCCPoLrgaqAvoHAgxvmAAB/A3aARoJ+gO8AwAJ/AesBqwC/AsACHWYAAAECPQLFAgUBBQC3AEUBBQI9AsECAAAdpgAAAQIBAj8BwQAAAj6CQoE7gMKCPoJAAB3mAAAAAD8AxACEAEACPQFFATcAxQE9AkECHmYBAEEAfwBhAAACPoFCgQKA+4ACgIKBPoFepgADPwDAAD4AwAA/g8AAPwIDAbsAQwC/Ax7mAAESAQmApABAgj6BAoC7gEKAAoC+gQCCH2YAAASBvIBEgDyBwAC+ggKBu4BCgD6DgAAfpj8DwIA+gcKBPoCAAj6BAoG7gEKAPoOAAB/mAAA9ACEAP8PhARgAvoICgbuAQoA+g4ACIGYMAwMAuIJIAjvBxAA+gkKBO4DCgj6CQAAgpgwBAwD4gIAAt4HAAD6DAoC7gEKAPoNAASEmCIAKgjqBzYA4gAACPoECgbuAQoA+g4AAIWYAAjwB5AAngD0AQAI/AkMBOwDDAj8CQAIhpgQAFABTAJqDdAAAAj0BBQG3AEUAPQOAAiHmAAO/AEkDD4D5AYMAPAEFAbcARQA9A4ACIiYAACiCJIIige2BAAM+gkKBO4DCgj6CwAAiphIBFgESAP+AHgDSAjgBBQC3AEUAvQEAACRmCAAuAsgCPwFKAMgCPQJFATcAxQE9AkAAJOYAAAsCKwHvACqBwAE8ggSBt4BEgTyCQAAlpgABM8C1AHUD7IBAAryCBoG1gESBPIFAAiXmAAE/ATUAvwP1AH8AOAJFATcAxQI9AkAAJiYQAxcA1wE3AdcCQAM9AwUC9wIFAr0DAQMnJgACPIHGgGzBKoCEgj6BAoC7gEKAPoOAACdmKwAFAZeBXQFlA4cAPQJFAbcARQA9A0ABKCYBAr8C+wK7gL8CwAA9AkUBNwDFAj0CwAApJgACPwL/Av+C8wLPAPwCAoE7gMKCPoJAAComAAAAA78AQQE7AUsBfwHLAXEDPwHAAgABLGYAA7+AUIE+gNCAv4AAAPYBFYJUAncDQAAxJgEAPQN/AH8B6QP/gdmBPYD+gP6BwQIAATGmEAGygFqAGcG6wFiDP8DYQT9A2EH/wEABs6YAAAADv4BAgQaAqIB4gAaBwIA/gcACAAG0pgoBMoEDgLsAwAK/AcEAvQBBAL8BwAMAADYmHQN1AH8CdQH/APUASQN/AMUBuQB/AcADNuYUAhSBvoBQgBCAPoPQgBCAM4DFAUqCUgF3pgAAAQABAAEAAQABAAEAPwAIAdQCIgIiAbfmAAAEAAQCPgPtAiyCbQCtAb4CZAIEAgAAO+YCATkB9IE0gT0BgAO/gFiDKIFIgPiBAAI8pgIBPQHsgSyBPQGIAAcDIoD+AAIAzgECAj8mBAE/AeyBLIE9AYAAOwDLAHsCQQI/AcAAP2YCAAIBPwHugS6AvQGAAD4A5YE9AQEBPwE/pgQBPwHsgS6BPIGNAToASYA/A8kAOQDAAAFmQQA8g9aCVoF8gkAAIoM+gOIAP8PiQAAAAqZgACUAFwI/g/cCdwJ3AfcBf4NXAiUCAAAEJkQAJAAqAjuD9wLgAO2B9YHlgWuCKIAAAATmQQI8gdxBnUDIQSJBP8DWAAfAvgD2wYQABiZCAjsD1oJVgX0DQQAlAKUCPMHlACEAogEKJkQBPgHtASyBOwGHAD0D5QFlgWUBfwHAABSmQAA8A++BLIE9A5AAGoNegNvASoP+g0oBWWZMAAMCOoPCAQ4AAAO/AEEAAQA/A8ACAAGbZkwAAwIygcYAAAO/AE0DNQCFAPyBBIIAABumXAADAjqDwgEOAIACDAEDgPoAAgDKAQYCHCZIAAUAMoPGAIAAOgDJwAkAPwPJAAkAuQBcZlgABQAyg8YBEAA8AcsCSgJ6AsICvgJAARymTAADAjKBxgCCADiAyoBKgHqCQII/gcAAHWZcAAMCOoPCAQwAAQE/AeUBJQElAL8DwQCdpkgABQIygcYAggIoASuA7gApA/UCJQIAAR6mTAACgjlBwQCCApgCBQEhQOGAwQEdAhABHyZIAAUCMoPCAS4AoEI+geIAIgA/A+LAIAAf5kgABAAzg8YBIAClAj8DxAE/gKQBVYIAAaAmSAAHADKDwgEGACQBpgAlAjyD5QAmAKQBIGZIAAUCMoHGAIACFQJxAVsAkQDwgRaCEAAhZkgABQEygcIAjgA0A9IBQYFRARcBcQPAACGmSAAFATKBxACBAD8B/QHVQVWBWQFDAcAAIuZMAAMCMoHGAKQALgCbgQ8BWwJrAq4AIAAjZkgABQEygcYAwAIdAV2BXQD9AF2A3QFAAiPmTAAjg8oBBgEQAA+D7AK5A+cCoQKvA8AAJKZEAAcAOoHCAFgBN4F/gbeAv4G3gX+BAAAlpkAAAQA9A9XBVQFXAVUBVQFVwX0DwQAAACZmZAAVABUD7QKlAq8CpQKsgrSCtIPUACQAKiZAAC8ArwC/g78D/QP+A72DvIP/g7YAgACrJkACAAM/AFUAVQFVAH8DVQBVAtUCQAHAACzmQAG/gCqB/4CqgoAB/wHEAj+CRAI+AgABsGZAAb+AKoC/gmqC6oHAADWDAgDDgXRBBAIxZkABv4AqgP+C6oOgA3+AyIA4gAiAz4MAADGmQAG/gCqBv4CqgsAB/4PAgSiBXIEigUABdCZAA7+AKoG/g6qCaoHAACKCPoPjAiICAAI0pkABv4Aqgf+AoIKEAfMASoB6AkICPgHAADVmQAAFAjMBeYB5AXsAeAD/gHyA/IFHgMAANuZAAN/ANUDfwNVBcEDHAwkA/8CJAQ8BAAI3ZkABv4Aqgf+A6oPAAAYAPgHjgiICFgIQAb/mQAG/gCqBP4Bqg8AADwHigS4Bq4JIAgAAA6aAAb+AKoD/guKByAApAe0Aq4LNAjUByAAEpoABv4Aqgf+A4oPQACiCWYJ+g9aCeYNIAgTmgAG/gCqA/4GqgoKB+gIJgXyAyQH6AkICBmaAAb+A6oB/gmAD/wH7APsB+oDagX6BwAAMJoADP4Dkgj+B0QA9gXcC9YL3Af2C1QGQAA3mgAO/gCqAv4LqgcAAPQJagnSD2oP5g8gCEWaAAb+BqoB/gmCBwAA/AdUCuwLnAnECwAAVZoABn4H/gKqCQIHqA/6A94F2gf5AKkPAABXmgAG/geqAf4NggNwCLgG9gBUDLgC0AwAAFqaEAg6DP4D+gP6C9oDyAvsA9YLrAssBiQAX5oADv4Aqgf+DgAHfga6AP4PbAAUAywEAABsmgAAAAIEAnQCRAJEAkQCRAp8CEAHwAAAAG6aAAJ6AkIJQgj+BwAAEAyQA34AkAEQBhAIb5oAAnoCQglyCM4HAAD+DwAA/gcAAP4PAABwmgACegJCCkII/gcAAPwHEAj+CQgI+AgABnGaAAB6AkIKQgn+B/gPBAgUC+QIlAkECgAAc5oAAnQCRAlECPwHAABUDIgCiANUBBIIAAB0mgAAegJCCkII/gcAAPgPSABKAEgA+AAAAHaaAAJ0AkQIRAz8AzAISAVIAv4FSAR4CAAAeZoAAnoKQgl6CMYHEADOAykB6AkICPgHAAB7mgAA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\"\n    }\n}\n","frame.ts":"namespace control.__screen {\n    let __update: () => void\n    let __updated = false;\n\n    export function update() {\n        if (__update)\n            __update()\n        __updated = true\n    }\n\n    export function setupUpdate(update: () => void) {\n        __updated = true;\n        __update = update;\n        update()\n    }\n\n    // low frequency fallback screen refresh\n    control.runInParallel(() => {\n        while (true) {\n            __updated = false\n            pause(200)\n            if (!__updated) {\n                __screen.update();\n                __updated = true\n            }\n        }\n    })\n}\n","image.cpp":"#include \"pxt.h\"\n\n#if IMAGE_BITS == 1\n// OK\n#elif IMAGE_BITS == 4\n// OK\n#else\n#error \"Invalid IMAGE_BITS\"\n#endif\n\n#define XX(v) (int)(((int16_t)(v)))\n#define YY(v) (int)(((int16_t)(((int32_t)(v)) >> 16)))\n\nnamespace pxt {\n\nPXT_VTABLE(RefImage, ValType::Object)\n\nvoid RefImage::destroy(RefImage *t) {}\n\nvoid RefImage::print(RefImage *t) {\n    DMESG(\"RefImage %p size=%d x %d\", t, t->width(), t->height());\n}\n\nint RefImage::wordHeight() {\n    if (bpp() == 1)\n        oops(20);\n    return ((height() * 4 + 31) >> 5);\n}\n\nvoid RefImage::makeWritable() {\n    ++revision;\n    if (buffer->isReadOnly()) {\n        buffer = mkBuffer(data(), length());\n    }\n}\n\nuint8_t RefImage::fillMask(color c) {\n    return this->bpp() == 1 ? (c & 1) * 0xff : 0x11 * (c & 0xf);\n}\n\nbool RefImage::inRange(int x, int y) {\n    return 0 <= x && x < width() && 0 <= y && y < height();\n}\n\nvoid RefImage::clamp(int *x, int *y) {\n    *x = min(max(*x, 0), width() - 1);\n    *y = min(max(*y, 0), height() - 1);\n}\n\nRefImage::RefImage(BoxedBuffer *buf) : PXT_VTABLE_INIT(RefImage), buffer(buf) {\n    revision = 0;\n    if (!buf)\n        oops(21);\n}\n\nstatic inline int byteSize(int w, int h, int bpp) {\n    if (bpp == 1)\n        return sizeof(ImageHeader) + ((h + 7) >> 3) * w;\n    else\n        return sizeof(ImageHeader) + (((h * 4 + 31) / 32) * 4) * w;\n}\n\nImage_ allocImage(const uint8_t *data, uint32_t sz) {\n    auto buf = mkBuffer(data, sz);\n    registerGCObj(buf);\n    Image_ r = NEW_GC(RefImage, buf);\n    unregisterGCObj(buf);\n    return r;\n}\n\nImage_ mkImage(int width, int height, int bpp) {\n    if (width < 0 || height < 0 || width > 2000 || height > 2000)\n        return NULL;\n    if (bpp != 1 && bpp != 4)\n        return NULL;\n    uint32_t sz = byteSize(width, height, bpp);\n    Image_ r = allocImage(NULL, sz);\n    auto hd = r->header();\n    hd->magic = IMAGE_HEADER_MAGIC;\n    hd->bpp = bpp;\n    hd->width = width;\n    hd->height = height;\n    hd->padding = 0;\n    MEMDBG(\"mkImage: %d X %d => %p\", width, height, r);\n    return r;\n}\n\nbool isValidImage(Buffer buf) {\n    if (!buf || buf->length < 9)\n        return false;\n\n    auto hd = (ImageHeader *)(buf->data);\n    if (hd->magic != IMAGE_HEADER_MAGIC || (hd->bpp != 1 && hd->bpp != 4))\n        return false;\n\n    int sz = byteSize(hd->width, hd->height, hd->bpp);\n    if (sz != (int)buf->length)\n        return false;\n\n    return true;\n}\n\nbool isLegacyImage(Buffer buf) {\n    if (!buf || buf->length < 5)\n        return false;\n\n    if (buf->data[0] != 0xe1 && buf->data[0] != 0xe4)\n        return false;\n\n    int sz = byteSize(buf->data[1], buf->data[2], buf->data[0] & 0xf) - 4;\n    if (sz != (int)buf->length)\n        return false;\n\n    return true;\n}\n\n} // namespace pxt\n\nnamespace ImageMethods {\n\n/**\n * Get the width of the image\n */\n//% property\nint width(Image_ img) {\n    return img->width();\n}\n\n/**\n * Get the height of the image\n */\n//% property\nint height(Image_ img) {\n    return img->height();\n}\n\n/**\n * True if the image is monochromatic (black and white)\n */\n//% property\nbool isMono(Image_ img) {\n    return img->bpp() == 1;\n}\n\n//% property\nbool isStatic(Image_ img) {\n    return img->buffer->isReadOnly();\n}\n\n//% property\nbool revision(Image_ img) {\n    return img->revision;\n}\n\n/**\n * Sets all pixels in the current image from the other image, which has to be of the same size and\n * bpp.\n */\n//%\nvoid copyFrom(Image_ img, Image_ from) {\n    if (img->width() != from->width() || img->height() != from->height() ||\n        img->bpp() != from->bpp())\n        return;\n    img->makeWritable();\n    memcpy(img->pix(), from->pix(), from->pixLength());\n}\n\nstatic void setCore(Image_ img, int x, int y, int c) {\n    auto ptr = img->pix(x, y);\n    if (img->bpp() == 4) {\n        if (y & 1)\n            *ptr = (*ptr & 0x0f) | (c << 4);\n        else\n            *ptr = (*ptr & 0xf0) | (c & 0xf);\n    } else if (img->bpp() == 1) {\n        uint8_t mask = 0x01 << (y & 7);\n        if (c)\n            *ptr |= mask;\n        else\n            *ptr &= ~mask;\n    }\n}\n\nstatic int getCore(Image_ img, int x, int y) {\n    auto ptr = img->pix(x, y);\n    if (img->bpp() == 4) {\n        if (y & 1)\n            return *ptr >> 4;\n        else\n            return *ptr & 0x0f;\n    } else if (img->bpp() == 1) {\n        uint8_t mask = 0x01 << (y & 7);\n        return (*ptr & mask) ? 1 : 0;\n    }\n    return 0;\n}\n\n/**\n * Set pixel color\n */\n//%\nvoid setPixel(Image_ img, int x, int y, int c) {\n    if (!img->inRange(x, y))\n        return;\n    img->makeWritable();\n    setCore(img, x, y, c);\n}\n\n/**\n * Get a pixel color\n */\n//%\nint getPixel(Image_ img, int x, int y) {\n    if (!img->inRange(x, y))\n        return 0;\n    return getCore(img, x, y);\n}\n\nvoid fillRect(Image_ img, int x, int y, int w, int h, int c);\n\n/**\n * Fill entire image with a given color\n */\n//%\nvoid fill(Image_ img, int c) {\n    if (c && img->hasPadding()) {\n        fillRect(img, 0, 0, img->width(), img->height(), c);\n        return;\n    }\n    img->makeWritable();\n    memset(img->pix(), img->fillMask(c), img->pixLength());\n}\n\n/**\n * Copy row(s) of pixel from image to buffer (8 bit per pixel).\n */\n//%\nvoid getRows(Image_ img, int x, Buffer dst) {\n    if (img->bpp() != 4)\n        return;\n\n    int w = img->width();\n    int h = img->height();\n    if (x >= w || x < 0)\n        return;\n\n    uint8_t *sp = img->pix(x, 0);\n    uint8_t *dp = dst->data;\n    int n = min(dst->length, (w - x) * h) >> 1;\n\n    while (n--) {\n        *dp++ = *sp & 0xf;\n        *dp++ = *sp >> 4;\n        sp++;\n    }\n}\n\n/**\n * Copy row(s) of pixel from buffer to image.\n */\n//%\nvoid setRows(Image_ img, int x, Buffer src) {\n    if (img->bpp() != 4)\n        return;\n\n    int w = img->width();\n    int h = img->height();\n    if (x >= w || x < 0)\n        return;\n\n    img->makeWritable();\n\n    uint8_t *dp = img->pix(x, 0);\n    uint8_t *sp = src->data;\n    int n = min(src->length, (w - x) * h) >> 1;\n\n    while (n--) {\n        *dp++ = (sp[0] & 0xf) | (sp[1] << 4);\n        sp += 2;\n    }\n}\n\nvoid fillRect(Image_ img, int x, int y, int w, int h, int c) {\n    if (w == 0 || h == 0 || x >= img->width() || y >= img->height())\n        return;\n\n    int x2 = x + w - 1;\n    int y2 = y + h - 1;\n\n    if (x2 < 0 || y2 < 0)\n        return;\n\n    img->clamp(&x2, &y2);\n    img->clamp(&x, &y);\n    w = x2 - x + 1;\n    h = y2 - y + 1;\n\n    if (!img->hasPadding() && x == 0 && y == 0 && w == img->width() && h == img->height()) {\n        fill(img, c);\n        return;\n    }\n\n    img->makeWritable();\n\n    auto bh = img->byteHeight();\n    uint8_t f = img->fillMask(c);\n\n    uint8_t *p = img->pix(x, y);\n    while (w-- > 0) {\n        if (img->bpp() == 1) {\n            auto ptr = p;\n            unsigned mask = 0x01 << (y & 7);\n\n            for (int i = 0; i < h; ++i) {\n                if (mask == 0x100) {\n                    if (h - i >= 8) {\n                        *++ptr = f;\n                        i += 7;\n                        continue;\n                    } else {\n                        mask = 0x01;\n                        ++ptr;\n                    }\n                }\n                if (c)\n                    *ptr |= mask;\n                else\n                    *ptr &= ~mask;\n                mask <<= 1;\n            }\n\n        } else if (img->bpp() == 4) {\n            auto ptr = p;\n            unsigned mask = 0x0f;\n            if (y & 1)\n                mask <<= 4;\n\n            for (int i = 0; i < h; ++i) {\n                if (mask == 0xf00) {\n                    if (h - i >= 2) {\n                        *++ptr = f;\n                        i++;\n                        continue;\n                    } else {\n                        mask = 0x0f;\n                        ptr++;\n                    }\n                }\n                *ptr = (*ptr & ~mask) | (f & mask);\n                mask <<= 4;\n            }\n        }\n        p += bh;\n    }\n}\n\n//%\nvoid _fillRect(Image_ img, int xy, int wh, int c) {\n    fillRect(img, XX(xy), YY(xy), XX(wh), YY(wh), c);\n}\n\nvoid mapRect(Image_ img, int x, int y, int w, int h, Buffer map) {\n    if (w == 0 || h == 0 || x >= img->width() || y >= img->height())\n        return;\n\n    if (img->bpp() != 4 || map->length < 16)\n        return;\n\n    int x2 = x + w - 1;\n    int y2 = y + h - 1;\n\n    if (x2 < 0 || y2 < 0)\n        return;\n\n    img->clamp(&x2, &y2);\n    img->clamp(&x, &y);\n    w = x2 - x + 1;\n    h = y2 - y + 1;\n\n    img->makeWritable();\n\n    auto bh = img->byteHeight();\n    auto m = map->data;\n    uint8_t *p = img->pix(x, y);\n    while (w-- > 0) {\n        auto ptr = p;\n        unsigned shift = y & 1;\n        for (int i = 0; i < h; i++) {\n            if (shift) {\n                *ptr = (m[*ptr >> 4] << 4) | (*ptr & 0x0f);\n                ptr++;\n                shift = 0;\n            } else {\n                *ptr = (m[*ptr & 0xf] & 0xf) | (*ptr & 0xf0);\n                shift = 1;\n            }\n        }\n        p += bh;\n    }\n}\n\n//%\nvoid _mapRect(Image_ img, int xy, int wh, Buffer c) {\n    mapRect(img, XX(xy), YY(xy), XX(wh), YY(wh), c);\n}\n\n//% argsNullable\nbool equals(Image_ img, Image_ other) {\n    if (!other) {\n        return false;\n    }\n    auto len = img->length();\n    if (len != other->length()) {\n        return false;\n    }\n    return 0 == memcmp(img->data(), other->data(), len);\n}\n\n/**\n * Return a copy of the current image\n */\n//%\nImage_ clone(Image_ img) {\n    auto r = allocImage(img->data(), img->length());\n    MEMDBG(\"mkImageClone: %d X %d => %p\", img->width(), img->height(), r);\n    return r;\n}\n\n/**\n * Flips (mirrors) pixels horizontally in the current image\n */\n//%\nvoid flipX(Image_ img) {\n    img->makeWritable();\n\n    int bh = img->byteHeight();\n    auto a = img->pix();\n    auto b = img->pix(img->width() - 1, 0);\n\n    uint8_t tmp[bh];\n\n    while (a < b) {\n        memcpy(tmp, a, bh);\n        memcpy(a, b, bh);\n        memcpy(b, tmp, bh);\n        a += bh;\n        b -= bh;\n    }\n}\n\n/**\n * Flips (mirrors) pixels vertically in the current image\n */\n//%\nvoid flipY(Image_ img) {\n    img->makeWritable();\n\n    // this is quite slow - for small 16x16 sprite it will take in the order of 1ms\n    // something faster requires quite a bit of bit tweaking, especially for mono images\n    for (int i = 0; i < img->width(); ++i) {\n        int a = 0;\n        int b = img->height() - 1;\n        while (a < b) {\n            int tmp = getCore(img, i, a);\n            setCore(img, i, a, getCore(img, i, b));\n            setCore(img, i, b, tmp);\n            a++;\n            b--;\n        }\n    }\n}\n\n/**\n * Returns a transposed image (with X/Y swapped)\n */\n//%\nImage_ transposed(Image_ img) {\n    Image_ r = mkImage(img->height(), img->width(), img->bpp());\n\n    // this is quite slow\n    for (int i = 0; i < img->width(); ++i) {\n        for (int j = 0; j < img->height(); ++j) {\n            setCore(r, j, i, getCore(img, i, j));\n        }\n    }\n\n    return r;\n}\n\nvoid drawImage(Image_ img, Image_ from, int x, int y);\n\n/**\n * Every pixel in image is moved by (dx,dy)\n */\n//%\nvoid scroll(Image_ img, int dx, int dy) {\n    img->makeWritable();\n    auto bh = img->byteHeight();\n    auto w = img->width();\n    if (dy != 0) {\n        // TODO one day we may want a more memory-efficient implementation\n        auto img2 = clone(img);\n        fill(img, 0);\n        drawImage(img, img2, dx, dy);\n    } else if (dx < 0) {\n        dx = -dx;\n        if (dx < w)\n            memmove(img->pix(), img->pix(dx, 0), (w - dx) * bh);\n        else\n            dx = w;\n        memset(img->pix(w - dx, 0), 0, dx * bh);\n    } else if (dx > 0) {\n        if (dx < w)\n            memmove(img->pix(dx, 0), img->pix(), (w - dx) * bh);\n        else\n            dx = w;\n        memset(img->pix(), 0, dx * bh);\n    }\n}\n\nconst uint8_t bitdouble[] = {0x00, 0x03, 0x0c, 0x0f, 0x30, 0x33, 0x3c, 0x3f,\n                             0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, 0xff};\nconst uint8_t nibdouble[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,\n                             0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};\n\n/**\n * Stretches the image horizontally by 100%\n */\n//%\nImage_ doubledX(Image_ img) {\n    if (img->width() > 126)\n        return NULL;\n\n    Image_ r = mkImage(img->width() * 2, img->height(), img->bpp());\n    auto src = img->pix();\n    auto dst = r->pix();\n    auto w = img->width();\n    auto bh = img->byteHeight();\n\n    for (int i = 0; i < w; ++i) {\n        memcpy(dst, src, bh);\n        dst += bh;\n        memcpy(dst, src, bh);\n        dst += bh;\n\n        src += bh;\n    }\n\n    return r;\n}\n\n/**\n * Stretches the image vertically by 100%\n */\n//%\nImage_ doubledY(Image_ img) {\n    if (img->height() > 126)\n        return NULL;\n\n    Image_ r = mkImage(img->width(), img->height() * 2, img->bpp());\n    auto src0 = img->pix();\n    auto dst = r->pix();\n\n    auto w = img->width();\n    auto sbh = img->byteHeight();\n    auto bh = r->byteHeight();\n    auto dbl = img->bpp() == 1 ? bitdouble : nibdouble;\n\n    for (int i = 0; i < w; ++i) {\n        auto src = src0 + i * sbh;\n        for (int j = 0; j < bh; j += 2) {\n            *dst++ = dbl[*src & 0xf];\n            if (j != bh - 1)\n                *dst++ = dbl[*src >> 4];\n            src++;\n        }\n    }\n\n    return r;\n}\n\n/**\n * Replaces one color in an image with another\n */\n//%\nvoid replace(Image_ img, int from, int to) {\n    if (img->bpp() != 4)\n        return;\n    to &= 0xf;\n    if (from == to)\n        return;\n\n    img->makeWritable();\n\n    // avoid bleeding 'to' color into the overflow areas of the picture\n    if (from == 0 && img->hasPadding()) {\n        for (int i = 0; i < img->height(); ++i)\n            for (int j = 0; j < img->width(); ++j)\n                if (getCore(img, j, i) == from)\n                    setCore(img, j, i, to);\n        return;\n    }\n\n    auto ptr = img->pix();\n    auto len = img->pixLength();\n    while (len--) {\n        auto b = *ptr;\n        if ((b & 0xf) == from)\n            b = (b & 0xf0) | to;\n        if ((b >> 4) == from)\n            b = (to << 4) | (b & 0xf);\n        *ptr++ = b;\n    }\n}\n\n/**\n * Stretches the image in both directions by 100%\n */\n//%\nImage_ doubled(Image_ img) {\n    Image_ tmp = doubledX(img);\n    registerGCObj(tmp);\n    Image_ r = doubledY(tmp);\n    unregisterGCObj(tmp);\n    return r;\n}\n\nbool drawImageCore(Image_ img, Image_ from, int x, int y, int color) {\n    auto w = from->width();\n    auto h = from->height();\n    auto sh = img->height();\n    auto sw = img->width();\n\n    if (x + w <= 0)\n        return false;\n    if (x >= sw)\n        return false;\n    if (y + h <= 0)\n        return false;\n    if (y >= sh)\n        return false;\n\n    auto len = y < 0 ? min(sh, h + y) : min(sh - y, h);\n    auto tbp = img->bpp();\n    auto fbp = from->bpp();\n    auto y0 = y;\n\n    if (color == -2 && x == 0 && y == 0 && tbp == fbp && w == sw && h == sh) {\n        copyFrom(img, from);\n        return false;\n    }\n\n    // DMESG(\"drawIMG(%d,%d) at (%d,%d) w=%d bh=%d len=%d\",\n    //    w,h,x, y, img->width(), img->byteHeight(), len );\n\n    auto fromH = from->byteHeight();\n    auto imgH = img->byteHeight();\n    auto fromBase = from->pix();\n    auto imgBase = img->pix(0, y);\n\n#define LOOPHD                                                                                     \\\n    for (int xx = 0; xx < w; ++xx, ++x)                                                            \\\n        if (0 <= x && x < sw)\n\n    if (tbp == 4 && fbp == 4) {\n        auto wordH = fromH >> 2;\n        LOOPHD {\n            y = y0;\n\n            auto fdata = (uint32_t *)fromBase + wordH * xx;\n            auto tdata = imgBase + imgH * x;\n\n            // DMESG(\"%d,%d xx=%d/%d - %p (%p) -- %d\",x,y,xx,w,tdata,img->pix(),\n            //    (uint8_t*)fdata - from->pix());\n\n            auto cnt = wordH;\n            auto bot = min(sh, y + h);\n\n#define COLS(s) ((v >> (s)) & 0xf)\n#define COL(s) COLS(s)\n\n#define STEPA(s)                                                                                   \\\n    if (COL(s) && 0 <= y && y < bot)                                                               \\\n        SETLOW(s);                                                                                 \\\n    y++;\n#define STEPB(s)                                                                                   \\\n    if (COL(s) && 0 <= y && y < bot)                                                               \\\n        SETHIGH(s);                                                                                \\\n    y++;                                                                                           \\\n    tdata++;\n#define STEPAQ(s)                                                                                  \\\n    if (COL(s))                                                                                    \\\n        SETLOW(s);\n#define STEPBQ(s)                                                                                  \\\n    if (COL(s))                                                                                    \\\n        SETHIGH(s);                                                                                \\\n    tdata++;\n\n// perf: expanded version 5% faster\n#define ORDER(A, B)                                                                                \\\n    A(0);                                                                                          \\\n    B(4);                                                                                          \\\n    A(8);                                                                                          \\\n    B(12);                                                                                         \\\n    A(16);                                                                                         \\\n    B(20);                                                                                         \\\n    A(24);                                                                                         \\\n    B(28)\n//#define ORDER(A,B) for (int k = 0; k < 32; k += 8) { A(k); B(4+k); }\n#define LOOP(A, B, xbot)                                                                           \\\n    while (cnt--) {                                                                                \\\n        auto v = *fdata++;                                                                         \\\n        if (0 <= y && y <= xbot - 8) {                                                             \\\n            ORDER(A##Q, B##Q);                                                                     \\\n            y += 8;                                                                                \\\n        } else {                                                                                   \\\n            ORDER(A, B);                                                                           \\\n        }                                                                                          \\\n    }\n#define LOOPS(xbot)                                                                                \\\n    if (y & 1)                                                                                     \\\n        LOOP(STEPB, STEPA, xbot)                                                                   \\\n    else                                                                                           \\\n        LOOP(STEPA, STEPB, xbot)\n\n            if (color >= 0) {\n#define SETHIGH(s) *tdata = (*tdata & 0x0f) | ((COLS(s)) << 4)\n#define SETLOW(s) *tdata = (*tdata & 0xf0) | COLS(s)\n                LOOPS(sh)\n            } else if (color == -2) {\n#undef COL\n#define COL(s) 1\n                LOOPS(bot)\n            } else {\n#undef COL\n#define COL(s) COLS(s)\n#undef SETHIGH\n#define SETHIGH(s)                                                                                 \\\n    if (*tdata & 0xf0)                                                                             \\\n    return true\n#undef SETLOW\n#define SETLOW(s)                                                                                  \\\n    if (*tdata & 0x0f)                                                                             \\\n    return true\n                LOOPS(sh)\n            }\n        }\n    } else if (tbp == 1 && fbp == 1) {\n        auto left = img->pix() - imgBase;\n        auto right = img->pix(0, img->height() - 1) - imgBase;\n        LOOPHD {\n            y = y0;\n\n            auto data = fromBase + fromH * xx;\n            auto off = imgBase + imgH * x;\n            auto off0 = off + left;\n            auto off1 = off + right;\n\n            int shift = (y & 7);\n\n            int y1 = y + h + (y & 7);\n            int prev = 0;\n\n            while (y < y1 - 8) {\n                int curr = *data++ << shift;\n                if (off0 <= off && off <= off1) {\n                    uint8_t v = (curr >> 0) | (prev >> 8);\n\n                    if (color == -1) {\n                        if (*off & v)\n                            return true;\n                    } else {\n                        *off |= v;\n                    }\n                }\n                off++;\n                prev = curr;\n                y += 8;\n            }\n\n            int left = y1 - y;\n            if (left > 0) {\n                int curr = *data << shift;\n                if (off0 <= off && off <= off1) {\n                    uint8_t v = ((curr >> 0) | (prev >> 8)) & (0xff >> (8 - left));\n                    if (color == -1) {\n                        if (*off & v)\n                            return true;\n                    } else {\n                        *off |= v;\n                    }\n                }\n            }\n        }\n    } else if (tbp == 4 && fbp == 1) {\n        if (y < 0) {\n            fromBase = from->pix(0, -y);\n            imgBase = img->pix();\n        }\n        // icon mode\n        LOOPHD {\n            auto fdata = fromBase + fromH * xx;\n            auto tdata = imgBase + imgH * x;\n\n            unsigned mask = 0x01;\n            auto v = *fdata++;\n            int off = (y & 1) ? 1 : 0;\n            if (y < 0) {\n                mask <<= -y & 7;\n                off = 0;\n            }\n            for (int i = off; i < len + off; ++i) {\n                if (mask == 0x100) {\n                    mask = 0x01;\n                    v = *fdata++;\n                }\n                if (v & mask) {\n                    if (i & 1)\n                        *tdata = (*tdata & 0x0f) | (color << 4);\n                    else\n                        *tdata = (*tdata & 0xf0) | color;\n                }\n                mask <<= 1;\n                if (i & 1)\n                    tdata++;\n            }\n        }\n    }\n\n    return false;\n}\n\n/**\n * Draw given image on the current image\n */\n//%\nvoid drawImage(Image_ img, Image_ from, int x, int y) {\n    img->makeWritable();\n    if (img->bpp() == 4 && from->bpp() == 4) {\n        drawImageCore(img, from, x, y, -2);\n    } else {\n        fillRect(img, x, y, from->width(), from->height(), 0);\n        drawImageCore(img, from, x, y, 0);\n    }\n}\n\n/**\n * Draw given image with transparent background on the current image\n */\n//%\nvoid drawTransparentImage(Image_ img, Image_ from, int x, int y) {\n    img->makeWritable();\n    drawImageCore(img, from, x, y, 0);\n}\n\n/**\n * Check if the current image \"collides\" with another\n */\n//%\nbool overlapsWith(Image_ img, Image_ other, int x, int y) {\n    return drawImageCore(img, other, x, y, -1);\n}\n\n// Image_ format (legacy)\n//  byte 0: magic 0xe4 - 4 bit color; 0xe1 is monochromatic\n//  byte 1: width in pixels\n//  byte 2: height in pixels\n//  byte 3: padding (should be zero)\n//  byte 4...N: data 4 bits per pixels, high order nibble printed first, lines aligned to 32 bit\n//  words byte 4...N: data 1 bit per pixels, high order bit printed first, lines aligned to byte\n\nImage_ convertAndWrap(Buffer buf) {\n    if (isValidImage(buf))\n        return NEW_GC(RefImage, buf);\n\n    // What follows in this function is mostly dead code, except if people construct image buffers\n    // by hand. Probably safe to remove in a year (middle of 2020) or so. When removing, also remove\n    // from sim.\n    if (!isLegacyImage(buf))\n        return NULL;\n\n    auto tmp = mkBuffer(NULL, buf->length + 4);\n    auto hd = (ImageHeader *)tmp->data;\n    auto src = buf->data;\n    hd->magic = IMAGE_HEADER_MAGIC;\n    hd->bpp = src[0] & 0xf;\n    hd->width = src[1];\n    hd->height = src[2];\n    hd->padding = 0;\n    memcpy(hd->pixels, src + 4, buf->length - 4);\n\n    registerGCObj(tmp);\n    auto r = NEW_GC(RefImage, tmp);\n    unregisterGCObj(tmp);\n    return r;\n}\n\n//%\nvoid _drawIcon(Image_ img, Buffer icon, int xy, int c) {\n    img->makeWritable();\n\n    auto iconImg = convertAndWrap(icon);\n    if (!iconImg || iconImg->bpp() != 1)\n        return;\n\n    drawImageCore(img, iconImg, XX(xy), YY(xy), c);\n}\n\nstatic void drawLineLow(Image_ img, int x0, int y0, int x1, int y1, int c) {\n    int dx = x1 - x0;\n    int dy = y1 - y0;\n    int yi = 1;\n    if (dy < 0) {\n        yi = -1;\n        dy = -dy;\n    }\n    int D = 2 * dy - dx;\n    dx <<= 1;\n    dy <<= 1;\n    int y = y0;\n    for (int x = x0; x <= x1; ++x) {\n        setCore(img, x, y, c);\n        if (D > 0) {\n            y += yi;\n            D -= dx;\n        }\n        D += dy;\n    }\n}\n\nstatic void drawLineHigh(Image_ img, int x0, int y0, int x1, int y1, int c) {\n    int dx = x1 - x0;\n    int dy = y1 - y0;\n    int xi = 1;\n    if (dx < 0) {\n        xi = -1;\n        dx = -dx;\n    }\n    int D = 2 * dx - dy;\n    dx <<= 1;\n    dy <<= 1;\n    int x = x0;\n    for (int y = y0; y <= y1; ++y) {\n        setCore(img, x, y, c);\n        if (D > 0) {\n            x += xi;\n            D -= dy;\n        }\n        D += dx;\n    }\n}\n\nvoid drawLine(Image_ img, int x0, int y0, int x1, int y1, int c) {\n    if (x1 < x0) {\n        drawLine(img, x1, y1, x0, y0, c);\n        return;\n    }\n    int w = x1 - x0;\n    int h = y1 - y0;\n\n    if (h == 0) {\n        if (w == 0)\n            setPixel(img, x0, y0, c);\n        else\n            fillRect(img, x0, y0, w + 1, 1, c);\n        return;\n    }\n\n    if (w == 0) {\n        if (h > 0)\n            fillRect(img, x0, y0, 1, h + 1, c);\n        else\n            fillRect(img, x0, y1, 1, -h + 1, c);\n        return;\n    }\n\n    if (x1 < 0 || x0 >= img->width())\n        return;\n    if (x0 < 0) {\n        y0 -= (h * x0 / w);\n        x0 = 0;\n    }\n    if (x1 >= img->width()) {\n        int d = (img->width() - 1) - x1;\n        y1 += (h * d / w);\n        x1 = img->width() - 1;\n    }\n\n    if (y0 < y1) {\n        if (y0 >= img->height() || y1 < 0)\n            return;\n        if (y0 < 0) {\n            x0 -= (w * y0 / h);\n            y0 = 0;\n        }\n        if (y1 >= img->height()) {\n            int d = (img->height() - 1) - y1;\n            x1 += (w * d / h);\n            y1 = img->height() - 1;\n        }\n    } else {\n        if (y1 >= img->height() || y0 < 0)\n            return;\n        if (y1 < 0) {\n            x1 -= (w * y1 / h);\n            y1 = 0;\n        }\n        if (y0 >= img->height()) {\n            int d = (img->height() - 1) - y0;\n            x0 += (w * d / h);\n            y0 = img->height() - 1;\n        }\n    }\n\n    img->makeWritable();\n\n    if (h < 0) {\n        h = -h;\n        if (h < w)\n            drawLineLow(img, x0, y0, x1, y1, c);\n        else\n            drawLineHigh(img, x1, y1, x0, y0, c);\n    } else {\n        if (h < w)\n            drawLineLow(img, x0, y0, x1, y1, c);\n        else\n            drawLineHigh(img, x0, y0, x1, y1, c);\n    }\n}\n\n//%\nvoid _drawLine(Image_ img, int xy, int wh, int c) {\n    drawLine(img, XX(xy), YY(xy), XX(wh), YY(wh), c);\n}\n\nvoid blitRow(Image_ img, int x, int y, Image_ from, int fromX, int fromH) {\n    if (!img->inRange(x, 0) || !img->inRange(fromX, 0) || fromH <= 0)\n        return;\n\n    if (img->bpp() != 4 || from->bpp() != 4)\n        return;\n\n    int fy = 0;\n    int stepFY = (from->width() << 16) / fromH;\n    int endY = y + fromH;\n    if (endY > img->height())\n        endY = img->height();\n    if (y < 0) {\n        fy += -y * stepFY;\n        y = 0;\n    }\n\n    auto dp = img->pix(x, y);\n    auto sp = from->pix(fromX, 0);\n\n    while (y < endY) {\n        int p = fy >> 16, c;\n        if (p & 1)\n            c = sp[p >> 1] >> 4;\n        else\n            c = sp[p >> 1] & 0xf;\n        if (y & 1) {\n            *dp = (*dp & 0x0f) | (c << 4);\n            dp++;\n        } else {\n            *dp = (*dp & 0xf0) | (c & 0xf);\n        }\n        y++;\n        fy += stepFY;\n    }\n}\n\n//%\nvoid _blitRow(Image_ img, int xy, Image_ from, int xh) {\n    blitRow(img, XX(xy), YY(xy), from, XX(xh), YY(xh));\n}\n\nbool blit(Image_ dst, Image_ src, pxt::RefCollection *args) {\n    int xDst = pxt::toInt(args->getAt(0));\n    int yDst = pxt::toInt(args->getAt(1));\n    int wDst = pxt::toInt(args->getAt(2));\n    int hDst = pxt::toInt(args->getAt(3));\n    int xSrc = pxt::toInt(args->getAt(4));\n    int ySrc = pxt::toInt(args->getAt(5));\n    int wSrc = pxt::toInt(args->getAt(6));\n    int hSrc = pxt::toInt(args->getAt(7));\n    bool transparent = pxt::toBoolQuick(args->getAt(8));\n    bool check = pxt::toBoolQuick(args->getAt(9));\n\n    int xSrcStep = (wSrc << 16) / wDst;\n    int ySrcStep = (hSrc << 16) / hDst;\n\n    int xDstClip = abs(min(0, xDst));\n    int yDstClip = abs(min(0, yDst));\n    int xDstStart = xDst + xDstClip;\n    int yDstStart = yDst + yDstClip;\n    int xDstEnd = min(dst->width(), xDst + wDst);\n    int yDstEnd = min(dst->height(), yDst + hDst);\n\n    int xSrcStart = max(0, (xSrc << 16) + xDstClip * xSrcStep);\n    int ySrcStart = max(0, (ySrc << 16) + yDstClip * ySrcStep);\n    int xSrcEnd = min(src->width(), xSrc + wSrc) << 16;\n    int ySrcEnd = min(src->height(), ySrc + hSrc) << 16;\n\n    if (!check)\n        dst->makeWritable();\n\n    for (int yDstCur = yDstStart, ySrcCur = ySrcStart; yDstCur < yDstEnd && ySrcCur < ySrcEnd; ++yDstCur, ySrcCur += ySrcStep) {\n        int ySrcCurI = ySrcCur >> 16;\n        for (int xDstCur = xDstStart, xSrcCur = xSrcStart; xDstCur < xDstEnd && xSrcCur < xSrcEnd; ++xDstCur, xSrcCur += xSrcStep) {\n            int xSrcCurI = xSrcCur >> 16;\n            int cSrc = getCore(src, xSrcCurI, ySrcCurI);\n            if (check && cSrc) {\n                int cDst = getCore(dst, xDstCur, yDstCur);\n                if (cDst) {\n                    return true;\n                }\n                continue;\n            }\n            if (!transparent || cSrc) {\n                setCore(dst, xDstCur, yDstCur, cSrc);\n            }\n        }\n    }\n    return false;\n}\n\n//%\nbool _blit(Image_ img, Image_ src, pxt::RefCollection *args) {\n    return blit(img, src, args);\n}\n\nvoid fillCircle(Image_ img, int cx, int cy, int r, int c) {\n    int x = r - 1;\n    int y = 0;\n    int dx = 1;\n    int dy = 1;\n    int err = dx - (r << 1);\n\n    while (x >= y) {\n        fillRect(img, cx + x, cy - y, 1, 1 + (y << 1), c);\n        fillRect(img, cx + y, cy - x, 1, 1 + (x << 1), c);\n        fillRect(img, cx - x, cy - y, 1, 1 + (y << 1), c);\n        fillRect(img, cx - y, cy - x, 1, 1 + (x << 1), c);\n        if (err <= 0) {\n            ++y;\n            err += dy;\n            dy += 2;\n        } else {\n            --x;\n            dx += 2;\n            err += dx - (r << 1);\n        }\n    }\n}\n\n//%\nvoid _fillCircle(Image_ img, int cxy, int r, int c) {\n    fillCircle(img, XX(cxy), YY(cxy), r, c);\n}\n\ntypedef struct\n{\n    int x, y;\n    int x0, y0;\n    int x1, y1;\n    int W,H;\n    int dx, dy;\n    int yi, xi;\n    int D;\n    int nextFuncIndex;\n} LineGenState; // For keeping track of the state when generating Y values for a line, even when moving to the next X.\n\ntypedef struct\n{\n    int min;\n    int max;\n} ValueRange;\n\nvoid nextYRange_Low(int x, LineGenState *line, ValueRange *yRange) {\n    while (line->x == x && line->x <= line->x1 && line->x < line->W) {\n        if (0 <= line->x) {\n            if (line->y < yRange->min) yRange->min = line->y;\n            if (line->y > yRange->max) yRange->max = line->y;\n        }\n        if (line->D > 0) {\n            line->y += line->yi;\n            line->D -= line->dx;\n        }\n        line->D += line->dy;\n        ++line->x;\n    }\n}\n\nvoid nextYRange_HighUp(int x, LineGenState *line, ValueRange *yRange) {\n    while (line->x == x && line->y >= line->y1 && line->x < line->W) {\n        if (0 <= line->x) {\n            if (line->y < yRange->min) yRange->min = line->y;\n            if (line->y > yRange->max) yRange->max = line->y;\n        }\n        if (line->D > 0) {\n            line->x += line->xi;\n            line->D += line->dy;\n        }\n        line->D += line->dx;\n        --line->y;\n    }\n}\n// This function is similar to the sub-function drawLineHigh for drawLine. However, it yields back after calculating all Y values of a given X. When the function is called again, it continues from the state where it yielded back previously.\nvoid nextYRange_HighDown(int x, LineGenState *line, ValueRange *yRange) {\n    while (line->x == x && line->y <= line->y1 && line->x < line->W) {\n        if (0 <= line->x) {\n            if (line->y < yRange->min) yRange->min = line->y;\n            if (line->y > yRange->max) yRange->max = line->y;\n        }\n        if (line->D > 0) {\n            line->x += line->xi;\n            line->D -= line->dy;\n        }\n        line->D += line->dx;\n        ++line->y;\n    }\n}\n\nLineGenState initYRangeGenerator(int16_t X0, int16_t Y0, int16_t X1, int16_t Y1) {\n    LineGenState line;\n\n    line.x0 = X0, line.y0 = Y0, line.x1 = X1, line.y1 = Y1;\n\n    line.dx = line.x1 - line.x0;\n    line.dy = line.y1 - line.y0;\n    line.y = line.y0;\n    line.x = line.x0;\n\n    if ((line.dy < 0 ? -line.dy : line.dy) < line.dx) {\n        line.yi = 1;\n        if (line.dy < 0) {\n            line.yi = -1;\n            line.dy = -line.dy;\n        }\n        line.D = 2 * line.dy - line.dx;\n        line.dx <<= 1;\n        line.dy <<= 1;\n\n        line.nextFuncIndex = 0;\n        return line;\n    } else {\n        line.xi = 1;\n        // if (dx < 0) {//should not hit\n        //     PANIC();\n        // }\n        if (line.dy < 0) {\n            line.D = 2 * line.dx + line.dy;\n            line.dx <<= 1;\n            line.dy <<= 1;\n\n            line.nextFuncIndex = 1;\n            return line;\n        } else {\n            line.D = 2 * line.dx - line.dy;\n            line.dx <<= 1;\n            line.dy <<= 1;\n\n            line.nextFuncIndex = 2;\n            return line;\n        }\n    }\n}\n\n// core of draw vertical line for repeatly calling, eg.: fillTriangle() or fillPolygon4()\n// value range/safety check not included\n// prepare \"img->makeWritable();\" and \"uint8_t f = img->fillMask(c);\" outside required.\n// bpp=4 support only right now\nvoid drawVLineCore(Image_ img, int x, int y, int h, uint8_t f) {\n    uint8_t *p = img->pix(x, y);\n    auto ptr = p;\n    unsigned mask = 0x0f;\n    if (y & 1)\n        mask <<= 4;\n    for (int i = 0; i < h; ++i) {\n        if (mask == 0xf00) {\n            if (h - i >= 2) {\n                *++ptr = f;\n                i++;\n                continue;\n            } else {\n                mask = 0x0f;\n                ptr++;\n            }\n        }\n        *ptr = (*ptr & ~mask) | (f & mask);\n        mask <<= 4;\n    }\n}\n\nvoid drawVLine(Image_ img, int x, int y, int h, int c) {\n    int H = height(img);\n    uint8_t f = img->fillMask(c);\n    if (x < 0 || x >= width(img) || y >= H || y + h - 1 < 0)\n        return;\n    if (y < 0){\n        h += y;\n        y = 0;\n    }\n    if (y + h > H)\n        h = H - y;\n    drawVLineCore(img, x, y, h, f);\n}\n\nvoid fillTriangle(Image_ img, int x0, int y0, int x1, int y1, int x2, int y2, int c) {\n    if (x1 < x0) {\n        swap(x0, x1);\n        swap(y0, y1);\n    }\n    if (x2 < x1) {\n        swap(x1, x2);\n        swap(y1, y2);\n    }\n    if (x1 < x0) {\n        swap(x0, x1);\n        swap(y0, y1);\n    }\n\n    LineGenState lines[] = {\n        initYRangeGenerator(x0, y0, x2, y2),\n        initYRangeGenerator(x0, y0, x1, y1),\n        initYRangeGenerator(x1, y1, x2, y2)\n    };\n\n    int W = width(img), H = height(img);\n    lines[0].W = lines[1].W = lines[2].W = W;\n    lines[0].H = lines[1].H = lines[2].H = H;\n\n    // We have 3 different sub-functions to generate Ys of edges, each particular edge maps to one of them.\n    // Use function pointers to avoid judging which function to call at every X.\n    typedef void (*FP_NEXT)(int x, LineGenState *line, ValueRange *yRange);\n    FP_NEXT nextFuncList[] = { nextYRange_Low, nextYRange_HighUp, nextYRange_HighDown };\n    FP_NEXT fpNext0 = nextFuncList[lines[0].nextFuncIndex];\n    FP_NEXT fpNext1 = nextFuncList[lines[1].nextFuncIndex];\n    FP_NEXT fpNext2 = nextFuncList[lines[2].nextFuncIndex];\n\n    ValueRange yRange = {H, -1};\n    img->makeWritable();\n    uint8_t f = img->fillMask(c);\n\n    for (int x = lines[1].x0; x <= min(x1, W - 1); x++) {\n        yRange.min = H;\n        yRange.max = -1;\n        fpNext0(x, &lines[0], &yRange);\n        fpNext1(x, &lines[1], &yRange);\n\n        if (x < 0 || yRange.min >= H || yRange.max < 0)\n            continue;\n        if (yRange.min < 0)\n            yRange.min = 0;\n        if (yRange.max >= H)\n            yRange.max = H - 1;\n        drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);\n    }\n\n    fpNext2(lines[2].x0, &lines[2], &yRange);\n\n    for (int x = lines[2].x0 + 1; x <= min(x2, W - 1); x++) {\n        yRange.min = H;\n        yRange.max = -1;\n        fpNext0(x, &lines[0], &yRange);\n        fpNext2(x, &lines[2], &yRange);\n\n        if (x < 0 || yRange.min >= H || yRange.max < 0)\n            continue;\n        if (yRange.min < 0)\n            yRange.min = 0;\n        if (yRange.max >= H)\n            yRange.max = H - 1;\n        drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);\n    }\n}\n\nvoid fillPolygon4(Image_ img, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, int c) {\n    LineGenState lines[] = {\n        (x0 < x1) ? initYRangeGenerator(x0, y0, x1, y1) : initYRangeGenerator(x1, y1, x0, y0),\n        (x1 < x2) ? initYRangeGenerator(x1, y1, x2, y2) : initYRangeGenerator(x2, y2, x1, y1),\n        (x2 < x3) ? initYRangeGenerator(x2, y2, x3, y3) : initYRangeGenerator(x3, y3, x2, y2),\n        (x0 < x3) ? initYRangeGenerator(x0, y0, x3, y3) : initYRangeGenerator(x3, y3, x0, y0)};\n\n    int W = width(img), H = height(img);\n    lines[0].W = lines[1].W = lines[2].W = lines[3].W = W;\n    lines[0].H = lines[1].H = lines[2].H = lines[3].H = H;\n\n    int minX = min(min(x0, x1), min(x2, x3));\n    int maxX = min(max(max(x0, x1), max(x2, x3)), W - 1);\n\n    typedef void (*FP_NEXT)(int x, LineGenState *line, ValueRange *yRange);\n    FP_NEXT nextFuncList[] = { nextYRange_Low, nextYRange_HighUp, nextYRange_HighDown };\n    FP_NEXT fpNext0 = nextFuncList[lines[0].nextFuncIndex];\n    FP_NEXT fpNext1 = nextFuncList[lines[1].nextFuncIndex];\n    FP_NEXT fpNext2 = nextFuncList[lines[2].nextFuncIndex];\n    FP_NEXT fpNext3 = nextFuncList[lines[3].nextFuncIndex];\n\n    ValueRange yRange = { H, -1 };\n    img->makeWritable();\n    uint8_t f = img->fillMask(c);\n\n    for (int x = minX; x <= maxX; x++) {\n        yRange.min = H;\n        yRange.max = -1;\n        fpNext0(x, &lines[0], &yRange);\n        fpNext1(x, &lines[1], &yRange);\n        fpNext2(x, &lines[2], &yRange);\n        fpNext3(x, &lines[3], &yRange);\n\n        if (x < 0 || yRange.min >= H || yRange.max < 0)\n            continue;\n        if (yRange.min < 0)\n            yRange.min = 0;\n        if (yRange.max >= H)\n            yRange.max = H - 1;\n        drawVLineCore(img, x, yRange.min, yRange.max - yRange.min + 1, f);\n    }\n}\n\n//%\nvoid _fillTriangle(Image_ img, pxt::RefCollection *args) {\n    fillTriangle(\n        img,\n        pxt::toInt(args->getAt(0)),\n        pxt::toInt(args->getAt(1)),\n        pxt::toInt(args->getAt(2)),\n        pxt::toInt(args->getAt(3)),\n        pxt::toInt(args->getAt(4)),\n        pxt::toInt(args->getAt(5)),\n        pxt::toInt(args->getAt(6))\n    );\n}\n\n// This polygon fill is similar to fillTriangle(): Scan minY and maxY of all edges at each X, and draw a vertical line between (x,minY)~(x,maxY).\n// The main difference is that it sorts the endpoints of each edge, x0 < x1, to draw from left to right, but doesn't sort the edges as it's too time consuming.\n// Instead, just call next(), which returns immediately if the x is not in range of the edge in horizon.\n// NOTE: Unlike triangles, edges of a polygon can cross a vertical line at a given X multi time. This algorithm can fill correctly only if edges meet this condition: Any vertical line(x) cross edges at most 2 times.\n// Fortunately, no matter what perspective transform is applied, a rectangle/trapezoid will still meet this condition.\n// Ref: https://forum.makecode.com/t/new-3d-engine-help-filling-4-sided-polygons/18641/9\n//%\nvoid _fillPolygon4(Image_ img, pxt::RefCollection *args) {\n    fillPolygon4(\n        img,\n        pxt::toInt(args->getAt(0)),\n        pxt::toInt(args->getAt(1)),\n        pxt::toInt(args->getAt(2)),\n        pxt::toInt(args->getAt(3)),\n        pxt::toInt(args->getAt(4)),\n        pxt::toInt(args->getAt(5)),\n        pxt::toInt(args->getAt(6)),\n        pxt::toInt(args->getAt(7)),\n        pxt::toInt(args->getAt(8))\n    );\n}\n\n} // namespace ImageMethods\n\nnamespace image {\n/**\n * Create new empty (transparent) image\n */\n//%\nImage_ create(int width, int height) {\n    Image_ r = mkImage(width, height, IMAGE_BITS);\n    if (r)\n        memset(r->pix(), 0, r->pixLength());\n    else\n        target_panic(PANIC_INVALID_IMAGE);\n    return r;\n}\n\n/**\n * Create new image with given content\n */\n//%\nImage_ ofBuffer(Buffer buf) {\n    return ImageMethods::convertAndWrap(buf);\n}\n\n/**\n * Double the size of an icon\n */\n//%\nBuffer doubledIcon(Buffer icon) {\n    if (!isValidImage(icon))\n        return NULL;\n\n    auto r = NEW_GC(RefImage, icon);\n    registerGCObj(r);\n    auto t = ImageMethods::doubled(r);\n    unregisterGCObj(r);\n    return t->buffer;\n}\n\n} // namespace image\n\n// This is  6.5x faster than standard on word-aligned copy\n// probably should move to codal\n\n#ifndef __linux__\nextern \"C\" void *memcpy(void *dst, const void *src, size_t sz) {\n    void *dst0 = dst;\n    if (sz >= 4 && !((uintptr_t)dst & 3) && !((uintptr_t)src & 3)) {\n        size_t cnt = sz >> 2;\n        uint32_t *d = (uint32_t *)dst;\n        const uint32_t *s = (const uint32_t *)src;\n        while (cnt--) {\n            *d++ = *s++;\n        }\n        sz &= 3;\n        dst = d;\n        src = s;\n    }\n\n    // see comment in memset() below (have not seen optimization here, but better safe than sorry)\n    volatile uint8_t *dd = (uint8_t *)dst;\n    volatile uint8_t *ss = (uint8_t *)src;\n\n    while (sz--) {\n        *dd++ = *ss++;\n    }\n\n    return dst0;\n}\n\nextern \"C\" void *memset(void *dst, int v, size_t sz) {\n    void *dst0 = dst;\n    if (sz >= 4 && !((uintptr_t)dst & 3)) {\n        size_t cnt = sz >> 2;\n        uint32_t vv = 0x01010101 * v;\n        uint32_t *d = (uint32_t *)dst;\n        while (cnt--) {\n            *d++ = vv;\n        }\n        sz &= 3;\n        dst = d;\n    }\n\n    // without volatile here, GCC may optimize the loop to memset() call which is obviously not great\n    volatile uint8_t *dd = (uint8_t *)dst;\n\n    while (sz--) {\n        *dd++ = v;\n    }\n\n    return dst0;\n}\n#endif\n","image.d.ts":"//% fixedInstances decompileIndirectFixedInstances\ninterface Image {\n    /**\n     * Fill a rectangle\n     */\n    //% helper=imageFillRect blockNamespace=\"images\" inlineInputMode=\"inline\" group=\"Drawing\"\n    //% block=\"fill rectangle in %picture=variables_get at x %x y %y width %w height %h %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/fill-rect\n    fillRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Replace colors in a rectangle\n     */\n    //% helper=imageMapRect\n    mapRect(x: number, y: number, w: number, h: number, colorMap: Buffer): void;\n\n    /**\n     * Draw a line\n     */\n    //% helper=imageDrawLine blockNamespace=\"images\" inlineInputMode=\"inline\" group=\"Drawing\"\n    //% block=\"draw line in %picture=variables_get from x %x0 y %y0 to x %x1 y %y1 %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/draw-line\n    drawLine(x0: number, y0: number, x1: number, y1: number, c: color): void;\n\n    /**\n     * Draw an empty rectangle\n     */\n    //% helper=imageDrawRect blockNamespace=\"images\" inlineInputMode=\"inline\" group=\"Drawing\"\n    //% block=\"draw rectangle in %picture=variables_get at x %x y %y width %w height %h %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/draw-rect\n    drawRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Set pixel color\n     */\n    //% shim=ImageMethods::setPixel blockNamespace=\"images\" group=\"Drawing\"\n    //% block=\"set %picture=variables_get color at x %x y %y to %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/set-pixel\n    setPixel(x: int32, y: int32, c: int32): void;\n\n    /**\n     * Get a pixel color\n     */\n    //% shim=ImageMethods::getPixel blockNamespace=\"images\" group=\"Drawing\"\n    //% block=\"%picture=variables_get color at x %x y %y\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/get-pixel\n    getPixel(x: int32, y: int32): int32;\n\n    /**\n     * Fill entire image with a given color\n     */\n    //% shim=ImageMethods::fill blockNamespace=\"images\" group=\"Drawing\"\n    //% block=\"fill %picture=variables_get with %c=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/fill\n    fill(c: int32): void;\n\n    /**\n     * Return a copy of the current image\n     */\n    //% shim=ImageMethods::clone blockNamespace=\"images\" group=\"Create\"\n    //% block=\"clone %picture=variables_get\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/clone\n    clone(): Image;\n\n    /**\n     * Flips (mirrors) pixels horizontally in the current image\n     */\n    //% shim=ImageMethods::flipX blockNamespace=\"images\" group=\"Transformations\"\n    //% block=\"flip %picture=variables_get horizontally\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/flip-x\n    flipX(): void;\n\n    /**\n     * Flips (mirrors) pixels vertically in the current image\n     */\n    //% shim=ImageMethods::flipY blockNamespace=\"images\" group=\"Transformations\"\n    //% block=\"flip %picture=variables_get vertically\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/flip-y\n    flipY(): void;\n\n    /**\n     * Every pixel in image is moved by (dx,dy)\n     */\n    //% shim=ImageMethods::scroll blockNamespace=\"images\" group=\"Transformations\"\n    //% help=images/image/scroll\n    scroll(dx: int32, dy: int32): void;\n\n    /**\n     * Replaces one color in an image with another\n     */\n    //% shim=ImageMethods::replace blockNamespace=\"images\" group=\"Transformations\"\n    //% block=\"change color in %picture=variables_get from %from=colorindexpicker to %to=colorindexpicker\"\n    //% picture.defl=\"picture\"\n    //% help=images/image/replace\n    replace(from: int32, to: int32): void;\n\n    /**\n     * Returns true if the provided image is the same as this image,\n     * otherwise returns false.\n     */\n    //% shim=ImageMethods::equals\n    //% blockNamespace=\"images\" group=\"Compare\"\n    //% block=\"$this is equal to image $other\"\n    //% this.shadow=variables_get\n    //% this.defl=\"picture\"\n    //% other.shadow=screen_image_picker\n    //% help=images/image/equals\n    equals(other: Image): boolean;\n\n    //% shim=ImageMethods::isStatic\n    isStatic(): boolean;\n\n    //% shim=ImageMethods::revision\n    revision(): number;\n\n     /**\n     * Draw given image with transparent background on the current image\n     */\n    //% shim=ImageMethods::drawTransparentImage\n    //% blockNamespace=\"images\"\n    //% blockId=image_draw_transparent_image\n    //% group=\"Drawing\"\n    //% block=\"$this draw $from at x $x y $y\"\n    //% this.shadow=variables_get\n    //% this.defl=\"picture\"\n    //% from.shadow=screen_image_picker\n    //% weight=0\n    drawTransparentImage(from: Image, x: int32, y: int32): void;\n}\n\ndeclare namespace image {\n    //% blockNamespace=\"images\"\n    //% block=\"create image width %width height %height\" group=\"Create\"\n    //% help=images/create\n    function create(width: number, height: number): Image;\n}","image.ts":"type color = number\n\nnamespace image {\n    export enum Dimension {\n        //% block=\"width\"\n        Width,\n        //% block=\"height\"\n        Height\n    }\n\n    export function repeatY(count: number, image: Image) {\n        let arr = [image]\n        while (--count > 0)\n            arr.push(image)\n        return concatY(arr)\n    }\n\n    export function concatY(images: Image[]) {\n        let w = 0\n        let h = 0\n        for (let img of images) {\n            w = Math.max(img.width, w)\n            h += img.height\n        }\n        let r = image.create(w, h)\n        let y = 0\n        for (let img of images) {\n            let x = (w - img.width) >> 1\n            r.drawImage(img, x, y)\n            y += img.height\n        }\n        return r\n    }\n\n    /**\n     * Returns the width or height of a picture.\n     *\n     * @param picture The picture to get the width or height of\n     * @param dimension The dimension to get\n     * @returns\n     */\n    //% blockId=image_get_dimension\n    //% group=\"Create\"\n    //% blockNamespace=\"images\"\n    //% block=\"$picture $dimension\"\n    //% picture.shadow=variables_get\n    //% picture.defl=picture\n    export function getDimension(picture: Image, dimension: Dimension) {\n        if (dimension === Dimension.Width) return picture.width;\n        else return picture.height;\n    }\n}\n\n\n//% snippet='img` `'\n//% pySnippet='img(\"\"\" \"\"\")'\n//% fixedInstances\ninterface Image {\n    /**\n     * Draw an icon (monochromatic image) using given color\n     */\n    //% helper=imageDrawIcon\n    drawIcon(icon: Buffer, x: number, y: number, c: color): void;\n\n    /**\n     * Fill a rectangle\n     */\n    //% helper=imageFillRect\n    fillRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Draw a line\n     */\n    //% helper=imageDrawLine\n    drawLine(x0: number, y0: number, x1: number, y1: number, c: color): void;\n\n    /**\n     * Draw an empty rectangle\n     */\n    //% helper=imageDrawRect\n    drawRect(x: number, y: number, w: number, h: number, c: color): void;\n\n    /**\n     * Draw a circle\n     */\n    //% helper=imageDrawCircle\n    drawCircle(cx: number, cy: number, r: number, c: color): void;\n\n    /**\n     * Fills a circle\n     */\n    //% helper=imageFillCircle\n    fillCircle(cx: number, cy: number, r: number, c: color): void;\n\n    /**\n     * Fills a triangle\n     */\n    //% helper=imageFillTriangle\n    fillTriangle(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, col: number): void;\n\n    /**\n     * Fills a 4-side-polygon\n     */\n    //% helper=imageFillPolygon4\n    fillPolygon4(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, col: number): void;\n\n    /**\n     * Returns an image rotated by -90, 90, -180, 180, -270, 270 deg clockwise\n     */\n    //% helper=imageRotated\n    rotated(deg: number): Image;\n\n    /**\n     * Scale and copy a row of pixels from a texture.\n     */\n    //% helper=imageBlitRow\n    blitRow(dstX: number, dstY: number, from: Image, fromX: number, fromH: number): void;\n\n    /**\n     * Copy an image from a source rectangle to a destination rectangle, stretching or\n     * compressing to fit the dimensions of the destination rectangle, if necessary.\n     */\n    //% helper=imageBlit\n    blit(xDst: number, yDst: number, wDst: number, hDst: number, src: Image, xSrc: number, ySrc: number, wSrc: number, hSrc: number, transparent: boolean, check: boolean): boolean;\n}\n\ninterface ScreenImage extends Image {\n    /**\n     * Sets the screen backlight brightness (10-100)\n     */\n    //% helper=setScreenBrightness\n    setBrightness(deg: number): Image;\n\n    /**\n     * Gets current screen backlight brightness (0-100)\n     */\n    //% helper=screenBrightness\n    brightness(): number;\n}\n\n// pxt compiler currently crashes on non-functions in helpers namespace; will fix\nnamespace _helpers_workaround {\n    export let brightness = 100\n}\n\nnamespace helpers {\n    //% shim=ImageMethods::_drawLine\n    function _drawLine(img: Image, xy: number, wh: number, c: color): void { }\n\n    //% shim=ImageMethods::_fillRect\n    function _fillRect(img: Image, xy: number, wh: number, c: color): void { }\n\n    //% shim=ImageMethods::_mapRect\n    function _mapRect(img: Image, xy: number, wh: number, m: Buffer): void { }\n\n    //% shim=ImageMethods::_drawIcon\n    function _drawIcon(img: Image, icon: Buffer, xy: number, c: color): void { }\n\n    //% shim=ImageMethods::_fillCircle\n    declare function _fillCircle(img: Image, cxy: number, r: number, c: color): void;\n\n    //% shim=ImageMethods::_blitRow\n    declare function _blitRow(img: Image, xy: number, from: Image, xh: number): void;\n\n    //% shim=ImageMethods::_blit\n    declare function _blit(img: Image, src: Image, args: number[]): boolean;\n\n    //% shim=ImageMethods::_fillTriangle\n    declare function _fillTriangle(img: Image, args: number[]): void;\n\n    //% shim=ImageMethods::_fillPolygon4\n    declare function _fillPolygon4(img: Image, args: number[]): void;\n\n    function pack(x: number, y: number) {\n        return (Math.clamp(-30000, 30000, x | 0) & 0xffff) | (Math.clamp(-30000, 30000, y | 0) << 16)\n    }\n\n    let _blitArgs: number[];\n\n    export function imageBlit(img: Image, xDst: number, yDst: number, wDst: number, hDst: number, src: Image, xSrc: number, ySrc: number, wSrc: number, hSrc: number, transparent: boolean, check: boolean): boolean {\n        _blitArgs = _blitArgs || [];\n        _blitArgs[0] = xDst | 0;\n        _blitArgs[1] = yDst | 0;\n        _blitArgs[2] = wDst | 0;\n        _blitArgs[3] = hDst | 0;\n        _blitArgs[4] = xSrc | 0;\n        _blitArgs[5] = ySrc | 0;\n        _blitArgs[6] = wSrc | 0;\n        _blitArgs[7] = hSrc | 0;\n        _blitArgs[8] = transparent ? 1 : 0;\n        _blitArgs[9] = check ? 1 : 0;\n        return _blit(img, src, _blitArgs);\n    }\n\n    export function imageBlitRow(img: Image, dstX: number, dstY: number, from: Image, fromX: number, fromH: number): void {\n        _blitRow(img, pack(dstX, dstY), from, pack(fromX, fromH))\n    }\n\n    export function imageDrawIcon(img: Image, icon: Buffer, x: number, y: number, c: color): void {\n        _drawIcon(img, icon, pack(x, y), c)\n    }\n    export function imageFillRect(img: Image, x: number, y: number, w: number, h: number, c: color): void {\n        _fillRect(img, pack(x, y), pack(w, h), c)\n    }\n    export function imageMapRect(img: Image, x: number, y: number, w: number, h: number, m: Buffer): void {\n        _mapRect(img, pack(x, y), pack(w, h), m)\n    }\n    export function imageDrawLine(img: Image, x: number, y: number, w: number, h: number, c: color): void {\n        _drawLine(img, pack(x, y), pack(w, h), c)\n    }\n    export function imageDrawRect(img: Image, x: number, y: number, w: number, h: number, c: color): void {\n        if (w == 0 || h == 0) return\n        w--\n        h--\n        imageDrawLine(img, x, y, x + w, y, c)\n        imageDrawLine(img, x, y, x, y + h, c)\n        imageDrawLine(img, x + w, y + h, x + w, y, c)\n        imageDrawLine(img, x + w, y + h, x, y + h, c)\n    }\n\n    export function imageDrawCircle(img: Image, cx: number, cy: number, r: number, col: number) {\n        cx = cx | 0;\n        cy = cy | 0;\n        r = r | 0;\n        // short cuts\n        if (r < 0)\n            return;\n\n        // Bresenham's algorithm\n        let x = 0\n        let y = r\n        let d = 3 - 2 * r\n\n        while (y >= x) {\n            img.setPixel(cx + x, cy + y, col)\n            img.setPixel(cx - x, cy + y, col)\n            img.setPixel(cx + x, cy - y, col)\n            img.setPixel(cx - x, cy - y, col)\n            img.setPixel(cx + y, cy + x, col)\n            img.setPixel(cx - y, cy + x, col)\n            img.setPixel(cx + y, cy - x, col)\n            img.setPixel(cx - y, cy - x, col)\n            x++\n            if (d > 0) {\n                y--\n                d += 4 * (x - y) + 10\n            } else {\n                d += 4 * x + 6\n            }\n        }\n    }\n\n    export function imageFillCircle(img: Image, cx: number, cy: number, r: number, col: number) {\n        _fillCircle(img, pack(cx, cy), r, col);\n    }\n\n    export function imageFillTriangle(img: Image, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, col: number) {\n        _blitArgs = _blitArgs || [];\n        _blitArgs[0] = x0;\n        _blitArgs[1] = y0;\n        _blitArgs[2] = x1;\n        _blitArgs[3] = y1;\n        _blitArgs[4] = x2;\n        _blitArgs[5] = y2;\n        _blitArgs[6] = col;\n        _fillTriangle(img, _blitArgs);\n    }\n\n    export function imageFillPolygon4(img: Image, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, col: number) {\n        _blitArgs = _blitArgs || [];\n        _blitArgs[0] = x0;\n        _blitArgs[1] = y0;\n        _blitArgs[2] = x1;\n        _blitArgs[3] = y1;\n        _blitArgs[4] = x2;\n        _blitArgs[5] = y2;\n        _blitArgs[6] = x3;\n        _blitArgs[7] = y3;\n        _blitArgs[8] = col;\n        _fillPolygon4(img, _blitArgs);\n    }\n\n    /**\n     * Returns an image rotated by 90, 180, 270 deg clockwise\n     */\n    export function imageRotated(img: Image, deg: number) {\n        if (deg == -90 || deg == 270) {\n            let r = img.transposed();\n            r.flipY();\n            return r;\n        } else if (deg == 180 || deg == -180) {\n            let r = img.clone();\n            r.flipX();\n            r.flipY();\n            return r;\n        } else if (deg == 90 || deg == -270) {\n            let r = img.transposed();\n            r.flipX();\n            return r;\n        } else {\n            return null;\n        }\n    }\n\n    //% shim=pxt::setScreenBrightness\n    function _setScreenBrightness(brightness: number) { }\n\n    export function setScreenBrightness(img: Image, b: number) {\n        b = Math.clamp(10, 100, b | 0);\n        _helpers_workaround.brightness = b\n        _setScreenBrightness(_helpers_workaround.brightness)\n    }\n\n    export function screenBrightness(img: Image) {\n        return _helpers_workaround.brightness\n    }\n}\n","imagesoverrides.jres":"{\n  \n}","imagesoverrides.ts":"// replace with built-in images","indexedscreen.h":"// Autogenerated C header file for Indexed screen\n#ifndef _JACDAC_SPEC_INDEXED_SCREEN_H\n#define _JACDAC_SPEC_INDEXED_SCREEN_H 1\n\n#define JD_SERVICE_CLASS_INDEXED_SCREEN  0x16fa36e5\n\n/**\n * Sets the update window for subsequent `set_pixels` commands.\n */\n#define JD_INDEXED_SCREEN_CMD_START_UPDATE 0x81\ntypedef struct jd_indexed_screen_start_update {\n    uint16_t x; // px\n    uint16_t y; // px\n    uint16_t width; // px\n    uint16_t height; // px\n} jd_indexed_screen_start_update_t;\n\n\n/**\n * Argument: pixels bytes. Set pixels in current window, according to current palette.\n * Each \"line\" of data is aligned to a byte.\n */\n#define JD_INDEXED_SCREEN_CMD_SET_PIXELS 0x83\n\n/**\n * Read-write ratio u0.8 (uint8_t). Set backlight brightness.\n * If set to `0` the display may go to sleep.\n */\n#define JD_INDEXED_SCREEN_REG_BRIGHTNESS JD_REG_INTENSITY\n\n/**\n * The current palette.\n * The color entry repeats `1 << bits_per_pixel` times.\n * This register may be write-only.\n */\n#define JD_INDEXED_SCREEN_REG_PALETTE 0x80\ntypedef struct jd_indexed_screen_palette {\n    uint8_t blue;\n    uint8_t green;\n    uint8_t red;\n    uint8_t padding;\n} jd_indexed_screen_palette_t;\n\n\n/**\n * Constant bit uint8_t. Determines the number of palette entries.\n * Typical values are 1, 2, 4, or 8.\n */\n#define JD_INDEXED_SCREEN_REG_BITS_PER_PIXEL 0x180\n\n/**\n * Constant px uint16_t. Screen width in \"natural\" orientation.\n */\n#define JD_INDEXED_SCREEN_REG_WIDTH 0x181\n\n/**\n * Constant px uint16_t. Screen height in \"natural\" orientation.\n */\n#define JD_INDEXED_SCREEN_REG_HEIGHT 0x182\n\n/**\n * Read-write bool (uint8_t). If true, consecutive pixels in the \"width\" direction are sent next to each other (this is typical for graphics cards).\n * If false, consecutive pixels in the \"height\" direction are sent next to each other.\n * For embedded screen controllers, this is typically true iff `width < height`\n * (in other words, it's only true for portrait orientation screens).\n * Some controllers may allow the user to change this (though the refresh order may not be optimal then).\n * This is independent of the `rotation` register.\n */\n#define JD_INDEXED_SCREEN_REG_WIDTH_MAJOR 0x81\n\n/**\n * Read-write px uint8_t. Every pixel sent over wire is represented by `up_sampling x up_sampling` square of physical pixels.\n * Some displays may allow changing this (which will also result in changes to `width` and `height`).\n * Typical values are 1 and 2.\n */\n#define JD_INDEXED_SCREEN_REG_UP_SAMPLING 0x82\n\n/**\n * Read-write ° uint16_t. Possible values are 0, 90, 180 and 270 only.\n * Write to this register do not affect `width` and `height` registers,\n * and may be ignored by some screens.\n */\n#define JD_INDEXED_SCREEN_REG_ROTATION 0x83\n\n#endif\n","jddisplay.cpp":"#include \"pxt.h\"\n#include \"jddisplay.h\"\n\n#define VLOG NOLOG\n//#define VLOG DMESG\n\nnamespace pxt {\n\n#define ALIGN(x) (((x) + 3) & ~3)\n\nstatic void jd_panic(void) {\n    target_panic(PANIC_SCREEN_ERROR);\n}\n\nstatic int jd_shift_frame(jd_frame_t *frame) {\n    int psize = frame->size;\n    jd_packet_t *pkt = (jd_packet_t *)frame;\n    int oldsz = pkt->service_size + 4;\n    if (ALIGN(oldsz) >= psize)\n        return 0; // nothing to shift\n\n    int ptr;\n    if (frame->data[oldsz] == 0xff) {\n        ptr = frame->data[oldsz + 1];\n        if (ptr >= psize)\n            return 0; // End-of-frame\n        if (ptr <= oldsz) {\n            DMESG(\"invalid super-frame %d %d\", ptr, oldsz);\n            return 0; // don't let it go back, must be some corruption\n        }\n    } else {\n        ptr = ALIGN(oldsz);\n    }\n\n    // assume the first one got the ACK sorted\n    frame->flags &= ~JD_FRAME_FLAG_ACK_REQUESTED;\n\n    uint8_t *src = &frame->data[ptr];\n    int newsz = *src + 4;\n    if (ptr + newsz > psize) {\n        DMESG(\"invalid super-frame %d %d %d\", ptr, newsz, psize);\n        return 0;\n    }\n    uint32_t *dst = (uint32_t *)frame->data;\n    uint32_t *srcw = (uint32_t *)src;\n    // don't trust memmove()\n    for (int i = 0; i < newsz; i += 4)\n        *dst++ = *srcw++;\n    // store ptr\n    ptr += ALIGN(newsz);\n    frame->data[newsz] = 0xff;\n    frame->data[newsz + 1] = ptr;\n\n    return 1;\n}\n\nstatic void *jd_push_in_frame(jd_frame_t *frame, unsigned service_num, unsigned service_cmd,\n                              unsigned service_size) {\n    if (service_num >> 8)\n        jd_panic();\n    if (service_cmd >> 16)\n        jd_panic();\n    uint8_t *dst = frame->data + frame->size;\n    unsigned szLeft = (uint8_t *)frame + sizeof(*frame) - dst;\n    if (service_size + 4 > szLeft)\n        return NULL;\n    *dst++ = service_size;\n    *dst++ = service_num;\n    *dst++ = service_cmd & 0xff;\n    *dst++ = service_cmd >> 8;\n    frame->size += ALIGN(service_size + 4);\n    return dst;\n}\n\nJDDisplay::JDDisplay(SPI *spi, Pin *cs, Pin *flow) : spi(spi), cs(cs), flow(flow) {\n    inProgress = false;\n    stepWaiting = false;\n    displayServiceNum = 0;\n    controlsStartServiceNum = 0;\n    controlsEndServiceNum = 0;\n    soundServiceNum = 0;\n    buttonState = 0;\n    brightness = 100;\n    soundBufferPending = 0;\n    soundSampleRate = 44100;\n    avgFrameTime = 26300; // start with a reasonable default\n    lastFrameTimestamp = 0;\n\n    EventModel::defaultEventBus->listen(DEVICE_ID_DISPLAY, 4243, this, &JDDisplay::sendDone);\n\n    flow->getDigitalValue(PullMode::Down);\n    EventModel::defaultEventBus->listen(flow->id, DEVICE_PIN_EVENT_ON_EDGE, this,\n                                        &JDDisplay::onFlowHi, MESSAGE_BUS_LISTENER_IMMEDIATE);\n    flow->eventOn(DEVICE_PIN_EVT_RISE);\n}\n\nvoid JDDisplay::waitForSendDone() {\n    if (inProgress)\n        fiber_wait_for_event(DEVICE_ID_DISPLAY, 4242);\n}\n\nvoid JDDisplay::sendDone(Event) {\n    inProgress = false;\n    Event(DEVICE_ID_DISPLAY, 4242);\n}\n\nvoid *JDDisplay::queuePkt(uint32_t service_num, uint32_t service_cmd, uint32_t size) {\n    void *res = jd_push_in_frame(&sendFrame, service_num, service_cmd, size);\n    if (res == NULL)\n        target_panic(PANIC_SCREEN_ERROR);\n    return res;\n}\n\nvoid JDDisplay::flushSend() {\n    if (cs)\n        cs->setDigitalValue(0);\n    spi->startTransfer((uint8_t *)&sendFrame, sizeof(sendFrame), (uint8_t *)&recvFrame,\n                       sizeof(recvFrame), &JDDisplay::stepStatic, this);\n}\n\nvoid JDDisplay::stepStatic(void *p) {\n    ((JDDisplay *)p)->step();\n}\n\n// We assume EIC IRQ pre-empts SPI/DMA IRQ (that is the numerical priority value of EIC is lower)\n// This is true for codal STM32, SAMD, and NRF52\nvoid JDDisplay::onFlowHi(Event) {\n    if (stepWaiting)\n        step();\n}\n\nvoid JDDisplay::handleIncoming(jd_packet_t *pkt) {\n    if (pkt->service_number == JD_SERVICE_NUMBER_CTRL &&\n        pkt->service_command == JD_CMD_ADVERTISEMENT_DATA) {\n        uint32_t *servptr = (uint32_t *)pkt->data;\n        int numServ = pkt->service_size >> 2;\n        for (uint8_t servIdx = 1; servIdx < numServ; ++servIdx) {\n            uint32_t service_class = servptr[servIdx];\n            if (service_class == JD_SERVICE_CLASS_INDEXED_SCREEN) {\n                displayServiceNum = servIdx;\n                VLOG(\"JDA: found screen, serv=%d\", servIdx);\n            } else if (service_class == JD_SERVICE_CLASS_ARCADE_GAMEPAD) {\n                if (!controlsStartServiceNum)\n                    controlsStartServiceNum = servIdx;\n                controlsEndServiceNum = servIdx;\n                VLOG(\"JDA: found controls, serv=%d\", servIdx);\n            } else if (service_class == JD_SERVICE_CLASS_ARCADE_SOUND) {\n                soundServiceNum = servIdx;\n                VLOG(\"JDA: found sound, serv=%d\", servIdx);\n            } else {\n                VLOG(\"JDA: unknown service: %x\", service_class);\n            }\n        }\n    } else if (pkt->service_number == JD_SERVICE_NUMBER_CTRL &&\n               pkt->service_command == JD_CMD_CTRL_NOOP) {\n        // do nothing\n    } else if (pkt->service_number == soundServiceNum) {\n        switch (pkt->service_command) {\n        case JD_GET(JD_ARCADE_SOUND_REG_BUFFER_PENDING):\n            soundBufferPending = *(uint32_t *)pkt->data;\n            break;\n        case JD_GET(JD_ARCADE_SOUND_REG_SAMPLE_RATE):\n            soundSampleRate = *(uint32_t *)pkt->data >> 10;\n            break;\n        }\n    } else if (pkt->service_number == displayServiceNum) {\n        switch (pkt->service_command) {\n        case JD_GET(JD_INDEXED_SCREEN_REG_HEIGHT):\n            screenHeight = *(uint16_t *)pkt->data;\n            break;\n        case JD_GET(JD_INDEXED_SCREEN_REG_WIDTH):\n            screenWidth = *(uint16_t *)pkt->data;\n            break;\n        }\n    } else if (controlsStartServiceNum <= pkt->service_number &&\n               pkt->service_number <= controlsEndServiceNum &&\n               pkt->service_command == (JD_CMD_GET_REG | JD_REG_READING)) {\n        auto report = (jd_arcade_gamepad_buttons_t *)pkt->data;\n        auto endp = pkt->data + pkt->service_size;\n        uint32_t state = 0;\n\n        while ((uint8_t *)report < endp) {\n            int idx = 0;\n            int b = report->button;\n\n            if (report->pressure < 0x20)\n                continue;\n\n            if (b == JD_ARCADE_GAMEPAD_BUTTON_SELECT)\n                b = JD_ARCADE_GAMEPAD_BUTTON_MENU;\n\n            if (b == JD_ARCADE_GAMEPAD_BUTTON_RESET || b == JD_ARCADE_GAMEPAD_BUTTON_EXIT)\n                target_reset();\n\n            if (1 <= b && b <= 7) {\n                idx = b + 7 * (pkt->service_number - controlsStartServiceNum);\n            }\n\n            if (idx > 0)\n                state |= 1 << idx;\n\n            report++;\n        }\n\n        if (state != buttonState) {\n            for (int i = 0; i < 32; ++i) {\n                if ((state & (1 << i)) && !(buttonState & (1 << i)))\n                    Event(PXT_INTERNAL_KEY_DOWN, i);\n                if (!(state & (1 << i)) && (buttonState & (1 << i)))\n                    Event(PXT_INTERNAL_KEY_UP, i);\n            }\n            buttonState = state;\n        }\n    } else {\n        // TODO remove later\n        VLOG(\"JDA: unknown packet for %d (cmd=%x)\", pkt->service_number, pkt->service_command);\n    }\n}\n\nvoid JDDisplay::step() {\n    if (cs)\n        cs->setDigitalValue(1);\n\n    target_disable_irq();\n    if (!flow->getDigitalValue()) {\n        stepWaiting = true;\n        target_enable_irq();\n        return;\n    } else {\n        stepWaiting = false;\n    }\n    target_enable_irq();\n\n    memset(&sendFrame, 0, JD_SERIAL_FULL_HEADER_SIZE);\n    sendFrame.crc = JDSPI_MAGIC;\n    sendFrame.device_identifier = pxt::getLongSerialNumber();\n\n    if (recvFrame.crc == JDSPI_MAGIC_NOOP) {\n        // empty frame, skip\n    } else if (recvFrame.crc != JDSPI_MAGIC) {\n        DMESG(\"JDA: magic mismatch %x\", (int)recvFrame.crc);\n    } else if (recvFrame.size == 0) {\n        // empty frame, skip\n    } else {\n        for (;;) {\n            handleIncoming((jd_packet_t *)&recvFrame);\n            if (!jd_shift_frame(&recvFrame))\n                break;\n        }\n    }\n\n    if (displayServiceNum == 0) {\n        // poke the control service to enumerate\n        queuePkt(JD_SERVICE_NUMBER_CTRL, JD_CMD_ADVERTISEMENT_DATA, 0);\n        flushSend();\n        return;\n    }\n\n    if (palette) {\n        {\n#define PALETTE_SIZE (16 * 4)\n            auto cmd =\n                queuePkt(displayServiceNum, JD_SET(JD_INDEXED_SCREEN_REG_PALETTE), PALETTE_SIZE);\n            memcpy(cmd, palette, PALETTE_SIZE);\n            palette = NULL;\n        }\n        {\n            auto cmd = (jd_indexed_screen_start_update_t *)queuePkt(\n                displayServiceNum, JD_INDEXED_SCREEN_CMD_START_UPDATE,\n                sizeof(jd_indexed_screen_start_update_t));\n            *cmd = this->addr;\n        }\n        {\n            auto cmd =\n                (uint8_t *)queuePkt(displayServiceNum, JD_SET(JD_INDEXED_SCREEN_REG_BRIGHTNESS), 1);\n            *cmd = this->brightness * 0xff / 100;\n        }\n\n        if (soundServiceNum) {\n            // we only need this for sending sound\n            uint32_t now = (uint32_t)current_time_us();\n            if (lastFrameTimestamp) {\n                uint32_t thisFrame = now - lastFrameTimestamp;\n                avgFrameTime = (avgFrameTime * 15 + thisFrame) >> 4;\n            }\n            lastFrameTimestamp = now;\n            // send around 2 frames of sound; typically around 60ms, so ~3000 samples\n            soundBufferDesiredSize =\n                sizeof(int16_t *) * ((((avgFrameTime * 2) >> 10) * soundSampleRate) >> 10);\n        }\n\n        flushSend();\n        return;\n    }\n\n    if (dataLeft > 0) {\n        uint32_t transfer = bytesPerTransfer;\n        if (dataLeft < transfer)\n            transfer = dataLeft;\n        auto pixels = queuePkt(displayServiceNum, JD_INDEXED_SCREEN_CMD_SET_PIXELS, transfer);\n        memcpy(pixels, dataPtr, transfer);\n        dataPtr += transfer;\n        dataLeft -= transfer;\n        flushSend();\n    } else if (soundServiceNum && soundBufferPending < soundBufferDesiredSize) {\n        int bytesLeft = soundBufferDesiredSize - soundBufferPending;\n        if (bytesLeft > bytesPerTransfer)\n            bytesLeft = bytesPerTransfer;\n        auto samples = (int16_t *)queuePkt(soundServiceNum, JD_ARCADE_SOUND_CMD_PLAY, bytesLeft);\n        if (pxt::redirectSamples(samples, bytesLeft >> 1, soundSampleRate)) {\n            soundBufferPending += bytesLeft;\n        } else {\n            // no sound generated, fill with 0 and stop\n            memset(samples, 0, bytesLeft);\n            soundBufferDesiredSize = 0;\n        }\n        flushSend();\n    } else {\n        // trigger sendDone(), which executes outside of IRQ context, so there\n        // is no race with waitForSendDone\n        Event(DEVICE_ID_DISPLAY, 4243);\n    }\n}\n\nint JDDisplay::sendIndexedImage(const uint8_t *src, unsigned width, unsigned height,\n                                uint32_t *palette) {\n    if (height & 1 || !height || !width)\n        target_panic(PANIC_SCREEN_ERROR);\n    if (width != addr.width || height != addr.height)\n        target_panic(PANIC_SCREEN_ERROR);\n    if (inProgress)\n        target_panic(PANIC_SCREEN_ERROR);\n\n    if (addr.y && addr.y >= screenHeight)\n        return 0; // out of range\n\n    inProgress = true;\n\n    int numcols = JD_SERIAL_PAYLOAD_SIZE / (height / 2);\n\n    bytesPerTransfer = numcols * (height / 2);\n    dataLeft = (height / 2) * width;\n    dataPtr = src;\n\n    this->palette = palette;\n\n    memset(&sendFrame, 0, sizeof(sendFrame));\n\n    step();\n\n    return 0;\n}\n\n} // namespace pxt","jddisplay.h":"#ifndef __JDDISPLAY_H\n#define __JDDISPLAY_H\n\n#include \"pxt.h\"\n#include \"jdprotocol.h\"\n#include \"arcadegamepad.h\"\n#include \"indexedscreen.h\"\n#include \"arcadesound.h\"\n\nnamespace pxt {\n\nclass JDDisplay {\n    jd_indexed_screen_start_update_t addr;\n    SPI *spi;\n    Pin *cs;\n    Pin *flow;\n    uint32_t dataLeft;\n    const uint8_t *dataPtr;\n    uint32_t *palette;\n    jd_frame_t sendFrame;\n    jd_frame_t recvFrame;\n    uint8_t bytesPerTransfer;\n    bool inProgress;\n    volatile bool stepWaiting;\n    uint8_t displayServiceNum;\n    uint8_t controlsStartServiceNum;\n    uint8_t controlsEndServiceNum;    \n    uint8_t soundServiceNum;    \n    uint16_t screenWidth, screenHeight;\n    uint32_t buttonState;\n    uint32_t avgFrameTime; // in us\n    uint32_t lastFrameTimestamp;\n\n    uint32_t soundBufferDesiredSize;\n    uint32_t soundBufferPending;\n    uint16_t soundSampleRate;\n\n    void *queuePkt(uint32_t service_num, uint32_t service_cmd, uint32_t size);\n    void flushSend();\n    void step();\n    void sendDone(Event);\n    static void stepStatic(void *);\n    void onFlowHi(Event);\n    void handleIncoming(jd_packet_t *pkt);\n\n  public:\n    uint8_t brightness;\n    JDDisplay(SPI *spi, Pin *cs, Pin *flow);\n    void setAddrWindow(int x, int y, int w, int h) {\n        addr.x = x;\n        addr.y = y;\n        addr.width = w;\n        addr.height = h;\n    }\n    void waitForSendDone();\n\n    int sendIndexedImage(const uint8_t *src, unsigned width, unsigned height, uint32_t *palette);\n};\n\n} // namespace pxt\n\n#endif\n","jdprotocol.h":"#ifndef __JDPROTOCOL_H\n#define __JDPROTOCOL_H\n\n#include <stdint.h>\n#include <stdbool.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n// 255 minus size of the serial header, rounded down to 4\n#define JD_SERIAL_PAYLOAD_SIZE 236\n#define JD_SERIAL_FULL_HEADER_SIZE 16\n\n#define JD_SERVICE_CLASS_CTRL 0x00000000\n\n#define JD_SERVICE_NUMBER_CTRL 0x00\n#define JD_SERVICE_NUMBER_MASK 0x3f\n#define JD_SERVICE_NUMBER_CRC_ACK 0x3f\n\n// the COMMAND flag signifies that the device_identifier is the recipent\n// (i.e., it's a command for the peripheral); the bit clear means device_identifier is the source\n// (i.e., it's a report from peripheral or a broadcast message)\n#define JD_FRAME_FLAG_COMMAND 0x01\n// an ACK should be issued with CRC of this package upon reception\n#define JD_FRAME_FLAG_ACK_REQUESTED 0x02\n// the device_identifier contains target service class number\n#define JD_FRAME_FLAG_IDENTIFIER_IS_SERVICE_CLASS 0x04\n\n#define JD_FRAME_SIZE(pkt) ((pkt)->size + 12)\n\n// Registers 0x001-0x07f - r/w common to all services\n// Registers 0x080-0x0ff - r/w defined per-service\n// Registers 0x100-0x17f - r/o common to all services\n// Registers 0x180-0x1ff - r/o defined per-service\n// Registers 0x200-0xeff - custom, defined per-service\n// Registers 0xf00-0xfff - reserved for implementation, should not be on the wire\n\n// this is either binary (0 or non-zero), or can be gradual (eg. brightness of neopixel)\n#define JD_REG_INTENSITY 0x01\n// the primary value of actuator (eg. servo angle)\n#define JD_REG_VALUE 0x02\n// enable/disable streaming\n#define JD_REG_IS_STREAMING 0x03\n// streaming interval in miliseconds\n#define JD_REG_STREAMING_INTERVAL 0x04\n// for analog sensors\n#define JD_REG_LOW_THRESHOLD 0x05\n#define JD_REG_HIGH_THRESHOLD 0x06\n// limit power drawn; in mA\n#define JD_REG_MAX_POWER 0x07\n\n// eg. one number for light sensor, all 3 coordinates for accelerometer\n#define JD_REG_READING 0x101\n\n#define JD_CMD_GET_REG 0x1000\n#define JD_CMD_SET_REG 0x2000\n\n#define JD_GET(reg) (JD_CMD_GET_REG | (reg))\n#define JD_SET(reg) (JD_CMD_SET_REG | (reg))\n\n// Commands 0x000-0x07f - common to all services\n// Commands 0x080-0xeff - defined per-service\n// Commands 0xf00-0xfff - reserved for implementation\n// enumeration data for CTRL, ad-data for other services\n#define JD_CMD_ADVERTISEMENT_DATA 0x00\n// event from sensor or on broadcast service\n#define JD_CMD_EVENT 0x01\n// request to calibrate sensor\n#define JD_CMD_CALIBRATE 0x02\n// request human-readable description of service\n#define JD_CMD_GET_DESCRIPTION 0x03\n\n// Commands specific to control service\n// do nothing\n#define JD_CMD_CTRL_NOOP 0x80\n// blink led or otherwise draw user's attention\n#define JD_CMD_CTRL_IDENTIFY 0x81\n// reset device\n#define JD_CMD_CTRL_RESET 0x82\n// identifies the type of hardware (eg., ACME Corp. Servo X-42 Rev C)\n#define JD_REG_CTRL_DEVICE_DESCRIPTION 0x180\n// a numeric code for the string above; used to mark firmware images\n#define JD_REG_CTRL_DEVICE_CLASS 0x181\n// MCU temperature in Celsius\n#define JD_REG_CTRL_TEMPERATURE 0x182\n// this is very approximate; ADC reading from backward-biasing the identification LED\n#define JD_REG_CTRL_LIGHT_LEVEL 0x183\n// typically the same as JD_REG_CTRL_DEVICE_CLASS; the bootloader will respond to that code\n#define JD_REG_CTRL_BL_DEVICE_CLASS 0x184\n\nstruct _jd_packet_t {\n    uint16_t crc;\n    uint8_t _size; // of frame data[]\n    uint8_t flags;\n\n    uint64_t device_identifier;\n\n    uint8_t service_size;\n    uint8_t service_number;\n    uint16_t service_command;\n\n    uint8_t data[0];\n} __attribute__((__packed__, aligned(4)));\ntypedef struct _jd_packet_t jd_packet_t;\n\nstruct _jd_frame_t {\n    uint16_t crc;\n    uint8_t size;\n    uint8_t flags;\n\n    uint64_t device_identifier;\n\n    uint8_t data[JD_SERIAL_PAYLOAD_SIZE + 4];\n} __attribute__((__packed__, aligned(4)));\ntypedef struct _jd_frame_t jd_frame_t;\n\n#define JDSPI_MAGIC 0x7ACD\n#define JDSPI_MAGIC_NOOP 0xB3CD\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n","ns.ts":"\n//% color=\"#a5b1c2\"\nnamespace images {\n\n}","panic.cpp":"#include \"pxt.h\"\n\n// This adds about 1.2k of binary size, but allows for displaying\n// panic codes regardless of heap state etc. with IRQs disabled.\n\n#define ST7735_NOP 0x00\n#define ST7735_SWRESET 0x01\n#define ST7735_RDDID 0x04\n#define ST7735_RDDST 0x09\n\n#define ST7735_SLPIN 0x10\n#define ST7735_SLPOUT 0x11\n#define ST7735_PTLON 0x12\n#define ST7735_NORON 0x13\n\n#define ST7735_INVOFF 0x20\n#define ST7735_INVON 0x21\n#define ST7735_DISPOFF 0x28\n#define ST7735_DISPON 0x29\n#define ST7735_CASET 0x2A\n#define ST7735_RASET 0x2B\n#define ST7735_RAMWR 0x2C\n#define ST7735_RAMRD 0x2E\n\n#define ST7735_PTLAR 0x30\n#define ST7735_COLMOD 0x3A\n#define ST7735_MADCTL 0x36\n\n#define ST7735_FRMCTR1 0xB1\n#define ST7735_FRMCTR2 0xB2\n#define ST7735_FRMCTR3 0xB3\n#define ST7735_INVCTR 0xB4\n\n#define ST7735_GMCTRP1 0xE0\n#define ST7735_GMCTRN1 0xE1\n\n#define MADCTL_MY 0x80\n#define MADCTL_MX 0x40\n#define MADCTL_MV 0x20\n#define MADCTL_ML 0x10\n#define MADCTL_RGB 0x00\n#define MADCTL_BGR 0x08\n#define MADCTL_MH 0x04\n\nnamespace _pxt_panic {\n\n// target_panic has been called\nstatic bool panicMode = false;\n\n#define DELAY 0x80\n\nclass ST7735 {\n    Pin *sck, *mosi, *dc, *cs;\n\n    void sendBytes(uint8_t *ptr, uint32_t len);\n    void sendCmd(uint8_t *buf, int len);\n    void sendCmdSeq(const uint8_t *buf);\n    void configure(uint8_t madctl, uint32_t frmctr1);\n\n  public:\n    uint16_t width, height;\n    void fill(int color, int numpixels);\n    void setAddrWindow(int x, int y, int w, int h);\n    void init();\n    void drawNumber(int idx, int x, int y, int color);\n};\n\n// clang-format off\nstatic const uint8_t initCmds[] = {\n    ST7735_SWRESET,   DELAY,  //  1: Software reset, 0 args, w/delay\n      120,                    //     150 ms delay\n    ST7735_SLPOUT ,   DELAY,  //  2: Out of sleep mode, 0 args, w/delay\n      120,                    //     500 ms delay\n    ST7735_INVOFF , 0      ,  // 13: Don't invert display, no args, no delay\n    ST7735_COLMOD , 1      ,  // 15: set color mode, 1 arg, no delay:\n      0x03,                  //     12-bit color\n\n    ST7735_NORON  ,    DELAY, //  3: Normal display on, no args, w/delay\n      10,                     //     10 ms delay\n    ST7735_DISPON ,    DELAY, //  4: Main screen turn on, no args w/delay\n      10,\n    0, 0 // END\n};\n// clang-format on\n\nstatic const uint8_t numbers[] = {\n    0x06, 0x09, 0x09, 0x09, 0x06, // 0\n    0x04, 0x06, 0x04, 0x04, 0x0e, // 1\n    0x07, 0x08, 0x06, 0x01, 0x0f, // 2\n    0x0f, 0x08, 0x04, 0x09, 0x06, // 3\n    0x0c, 0x0a, 0x09, 0x1f, 0x08, // 4\n    0x1f, 0x01, 0x0f, 0x10, 0x0f, // 5\n    0x08, 0x04, 0x0e, 0x11, 0x0e, // 6\n    0x1f, 0x08, 0x04, 0x02, 0x01, // 7\n    0x0e, 0x11, 0x0e, 0x11, 0x0e, // 8\n    0x0e, 0x11, 0x0e, 0x04, 0x02, // 9\n    0x11, 0x00, 0x0e, 0x1b, 0x11, // :(\n    // 0x11, 0x04, 0x04, 0x0a, 0x11, // :(\n};\n\nvoid ST7735::sendBytes(uint8_t *ptr, uint32_t len) {\n    uint8_t mask = 0, b;\n    for (;;) {\n        if (!mask) {\n            if (!len--)\n                break;\n            mask = 0x80;\n            b = *ptr++;\n        }\n        mosi->setDigitalValue((b & mask) ? 1 : 0);\n        sck->setDigitalValue(1);\n        mask >>= 1;\n        sck->setDigitalValue(0);\n    }\n}\n\nvoid ST7735::fill(int color, int numpixels) {\n    uint8_t cmd[20] = {ST7735_RAMWR};\n    sendCmd(cmd, 1);\n\n    dc->setDigitalValue(1);\n    if (cs)\n        cs->setDigitalValue(0);\n\n    cmd[0] = color >> 4;\n    cmd[1] = (color << 4) | (color >> 8);\n    cmd[2] = color;\n\n    int n = (numpixels + 1) >> 1;\n    while (n--) {\n        sendBytes(cmd, 3);\n    }\n\n    if (cs)\n        cs->setDigitalValue(1);\n}\n\nvoid ST7735::sendCmd(uint8_t *buf, int len) {\n    // make sure cmd isn't on stack\n    dc->setDigitalValue(0);\n    if (cs)\n        cs->setDigitalValue(0);\n    sendBytes(buf, 1);\n    dc->setDigitalValue(1);\n    len--;\n    buf++;\n    if (len > 0)\n        sendBytes(buf, len);\n    if (cs)\n        cs->setDigitalValue(1);\n}\n\nstatic void busy_wait_us(int ms) {\n    target_wait_us(ms);\n    /*\n    // this is for 120MHz\n    while (ms--) {\n        for (int i = 0; i < 30; ++i)\n            asm volatile(\"nop\");\n    }\n    */\n}\n\nvoid ST7735::sendCmdSeq(const uint8_t *buf) {\n    uint8_t cmdBuf[32];\n\n    while (*buf) {\n        cmdBuf[0] = *buf++;\n        int v = *buf++;\n        int len = v & ~DELAY;\n        // note that we have to copy to RAM\n        memcpy(cmdBuf + 1, buf, len);\n        sendCmd(cmdBuf, len + 1);\n        buf += len;\n        if (v & DELAY) {\n            busy_wait_us(1000 * *buf++);\n        }\n    }\n}\n\nvoid ST7735::setAddrWindow(int x, int y, int w, int h) {\n    w += x - 1;\n    h += y - 1;\n    uint8_t cmd0[] = {ST7735_RASET, 0, (uint8_t)x, (uint8_t)(w >> 8), (uint8_t)w};\n    uint8_t cmd1[] = {ST7735_CASET, 0, (uint8_t)y, (uint8_t)(h >> 8), (uint8_t)h};\n    sendCmd(cmd1, sizeof(cmd1));\n    sendCmd(cmd0, sizeof(cmd0));\n}\n\nvoid ST7735::init() {\n    mosi = LOOKUP_PIN(DISPLAY_MOSI);\n    sck = LOOKUP_PIN(DISPLAY_SCK);\n    cs = LOOKUP_PIN(DISPLAY_CS);\n    dc = LOOKUP_PIN(DISPLAY_DC);\n    auto bl = LOOKUP_PIN(DISPLAY_BL);\n    auto rst = LOOKUP_PIN(DISPLAY_RST);\n\n    if (cs)\n        cs->setDigitalValue(1);\n    dc->setDigitalValue(1);\n\n    if (bl) {\n        bl->setDigitalValue(1);\n    }\n\n    if (rst) {\n        rst->setDigitalValue(0);\n        busy_wait_us(20 * 1000);\n        rst->setDigitalValue(1);\n        busy_wait_us(20 * 1000);\n    }\n\n    uint32_t cfg0 = getConfig(CFG_DISPLAY_CFG0, 0x40);\n    uint32_t frmctr1 = getConfig(CFG_DISPLAY_CFG1, 0x000603);\n    auto madctl = cfg0 & 0xff;\n\n    sendCmdSeq(initCmds);\n    configure(madctl, frmctr1);\n\n    width = getConfig(CFG_DISPLAY_WIDTH, 160);\n    height = getConfig(CFG_DISPLAY_HEIGHT, 128);\n}\n\nvoid ST7735::configure(uint8_t madctl, uint32_t frmctr1) {\n    uint8_t cmd0[] = {ST7735_MADCTL, madctl};\n    uint8_t cmd1[] = {ST7735_FRMCTR1, (uint8_t)(frmctr1 >> 16), (uint8_t)(frmctr1 >> 8),\n                      (uint8_t)frmctr1};\n    sendCmd(cmd0, sizeof(cmd0));\n    sendCmd(cmd1, cmd1[3] == 0xff ? 3 : 4);\n}\n\n#define SIZE 4\n\nvoid ST7735::drawNumber(int idx, int x, int y, int color) {\n    const uint8_t *src = &numbers[idx * 5];\n    for (int i = 0; i < 5; i++) {\n        uint8_t ch = *src++;\n        for (int j = 0; j < 5; j++) {\n            if (ch & (1 << j)) {\n                setAddrWindow(x + j * SIZE, y + i * SIZE, SIZE - 1, SIZE - 1);\n                fill(color, (SIZE - 1) * (SIZE - 1));\n            }\n        }\n    }\n}\n\nstatic void drawPanic(int code) {\n    if (!LOOKUP_PIN(DISPLAY_MOSI))\n        return;\n\n    ST7735 display;\n\n    display.init();\n    display.setAddrWindow(0, 0, display.width, display.height);\n    display.fill(0, display.width * display.height);\n\n    display.drawNumber(10, 70, 20, 0xf00);\n    int x = 50;\n    int y = 60;\n    display.drawNumber((code / 100) % 10, x, y, 0xff0);\n    x += 24;\n    display.drawNumber((code / 10) % 10, x, y, 0xff0);\n    x += 24;\n    display.drawNumber((code / 1) % 10, x, y, 0xff0);\n    x += 24;\n}\n\nextern \"C\" __attribute__((weak)) void platform_panic(int statusCode) {}\n\nextern \"C\" void target_panic(int statusCode) {\n    __disable_irq();      // low-level disable\n    target_disable_irq(); // make sure they stay disabled in DMESG()\n\n    DMESG(\"*** CODAL PANIC : [%d]\", statusCode);\n\n    __disable_irq(); // disable IRQ after DMESG() again just to make sure\n\n    if (panicMode) {\n        // avoid recursive panic invocation\n        while (1) {\n        }\n    }\n\n    gcFreeze();\n\n    // remember first panic code\n    panicMode = true;\n\n    drawPanic(statusCode);\n\n    platform_panic(statusCode);\n\n    auto led = LOOKUP_PIN(LED);\n\n    const int unit = 100000;\n    const int dit = unit;\n    const int dat = 3 * unit;\n    const int intra = unit;\n    const int inter = 2 * unit;\n    const int word = 6 * unit;\n    while (1) {\n        if (led) {\n            // SOS\n            // . . .\n            for (int i = 0; i < 3; ++i) {\n                led->setDigitalValue(1);\n                busy_wait_us(dit);\n                led->setDigitalValue(0);\n                busy_wait_us(intra);\n            }\n            // inter character space\n            busy_wait_us(inter);\n            // - - -\n            for (int i = 0; i < 3; ++i) {\n                led->setDigitalValue(1);\n                busy_wait_us(dat);\n                led->setDigitalValue(0);\n                busy_wait_us(intra);\n            }\n            // inter character space\n            busy_wait_us(inter);\n            // . . .\n            for (int i = 0; i < 3; ++i) {\n                led->setDigitalValue(1);\n                busy_wait_us(dit);\n                led->setDigitalValue(0);\n                busy_wait_us(intra);\n            }\n            // inter character space\n            busy_wait_us(word);\n        }\n    }\n}\n\n} // namespace _pxt_panic","pxt.json":"{\n    \"name\": \"screen---st7735\",\n    \"description\": \"The screen library\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"screen.cpp\",\n        \"panic.cpp\",\n        \"image.cpp\",\n        \"image.ts\",\n        \"screenimage.ts\",\n        \"text.ts\",\n        \"frame.ts\",\n        \"shims.d.ts\",\n        \"fieldeditors.ts\",\n        \"targetoverrides.ts\",\n        \"ns.ts\",\n        \"image.d.ts\",\n        \"pxtparts.json\",\n        \"imagesoverrides.jres\",\n        \"imagesoverrides.ts\",\n        \"font12.jres\",\n        \"jdprotocol.h\",\n        \"arcadegamepad.h\",\n        \"indexedscreen.h\",\n        \"arcadesound.h\",\n        \"jddisplay.h\",\n        \"jddisplay.cpp\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","pxtparts.json":"{\n  \"screen\": {\n    \"simulationBehavior\": \"screen\",\n    \"visual\": {\n      \"builtIn\": \"screen\",\n      \"width\": 158.43856811523438,\n      \"height\": 146.8025665283203,\n      \"pinDistance\": 14.91,\n      \"pinLocations\": [\n        {\n          \"x\": 4.227952701380444,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 18.170226805137037,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 46.05478386015504,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 59.99706238766404,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 73.93934976267785,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 87.88161944268204,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 101.82389797019104,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 32.11250533264604,\n          \"y\": 3.1650031792503945\n        },\n        {\n          \"x\": 117.68761950246274,\n          \"y\": 3.1650031792503945\n        }\n      ]\n    },\n    \"numberOfPins\": 9,\n    \"instantiation\": {\n      \"kind\": \"singleton\"\n    },\n    \"pinDefinitions\": [\n      {\n        \"target\": \"ground\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"threeVolt\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_DC\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_CS\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_MOSI\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_SCK\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_MISO\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"DISPLAY_RST\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      },\n      {\n        \"target\": \"threeVolt\",\n        \"style\": \"male\",\n        \"orientation\": \"-Z\"\n      }\n    ],\n    \"assembly\": [\n      {\n        \"pinIndices\": [\n          0,\n          1,\n          2,\n          3,\n          4,\n          5,\n          6,\n          7,\n          8\n        ]\n      }\n    ]\n  }\n}","screen.cpp":"#include \"pxt.h\"\n#include \"ST7735.h\"\n#include \"ILI9341.h\"\n\n#include \"SPIScreenIO.h\"\n#ifdef STM32F4\n#include \"FSMCIO.h\"\n#endif\n\n#include \"jddisplay.h\"\n\nnamespace pxt {\n\nclass WDisplay {\n  public:\n    ScreenIO *io;\n    ST7735 *lcd;\n    JDDisplay *smart;\n\n    uint32_t currPalette[16];\n    bool newPalette;\n    bool inUpdate;\n\n    uint8_t *screenBuf;\n    Image_ lastStatus;\n\n    uint16_t width, height;\n    uint16_t displayHeight;\n    uint8_t offX, offY;\n    bool doubleSize;\n    uint32_t palXOR;\n\n    WDisplay() {\n        uint32_t cfg2 = getConfig(CFG_DISPLAY_CFG2, 0x0);\n        int conn = cfg2 >> 24;\n\n        uint32_t cfg0 = getConfig(CFG_DISPLAY_CFG0, 0x40);\n        uint32_t frmctr1 = getConfig(CFG_DISPLAY_CFG1, 0x000603);\n\n        int dispTp = getConfig(CFG_DISPLAY_TYPE, DISPLAY_TYPE_ST7735);\n\n        doubleSize = false;\n        smart = NULL;\n\n        auto miso = LOOKUP_PIN(DISPLAY_MISO);\n\n        if (dispTp == DISPLAY_TYPE_SMART) {\n            dispTp = smartConfigure(&cfg0, &frmctr1, &cfg2);\n        }\n\n        if (dispTp != DISPLAY_TYPE_SMART)\n            miso = NULL; // only JDDisplay needs MISO, otherwise leave free\n\n        SPI *spi = NULL;\n        if (conn == 0) {\n            spi = new CODAL_SPI(*LOOKUP_PIN(DISPLAY_MOSI), *miso, *LOOKUP_PIN(DISPLAY_SCK));\n            io = new SPIScreenIO(*spi);\n        } else if (conn == 1) {\n#ifdef CODAL_CREATE_PARALLEL_SCREEN_IO\n            io = CODAL_CREATE_PARALLEL_SCREEN_IO(cfg2 & 0xffffff, PIN(DISPLAY_MOSI),\n                                                 PIN(DISPLAY_MISO));\n#else\n            target_panic(PANIC_SCREEN_ERROR);\n#endif\n        } else {\n            target_panic(PANIC_SCREEN_ERROR);\n        }\n\n        if (dispTp == DISPLAY_TYPE_ST7735)\n            lcd = new ST7735(*io, *LOOKUP_PIN(DISPLAY_CS), *LOOKUP_PIN(DISPLAY_DC));\n        else if (dispTp == DISPLAY_TYPE_ILI9341) {\n            lcd = new ILI9341(*io, *LOOKUP_PIN(DISPLAY_CS), *LOOKUP_PIN(DISPLAY_DC));\n            doubleSize = true;\n        } else if (dispTp == DISPLAY_TYPE_SMART) {\n            lcd = NULL;\n            smart = new JDDisplay(spi, LOOKUP_PIN(DISPLAY_CS), LOOKUP_PIN(DISPLAY_DC));\n        } else\n            target_panic(PANIC_SCREEN_ERROR);\n\n        palXOR = (cfg0 & 0x1000000) ? 0xffffff : 0x000000;\n        auto madctl = cfg0 & 0xff;\n        offX = (cfg0 >> 8) & 0xff;\n        offY = (cfg0 >> 16) & 0xff;\n\n        DMESG(\"configure screen: FRMCTR1=%p MADCTL=%p type=%d\", frmctr1, madctl, dispTp);\n\n        if (spi) {\n            auto freq = (cfg2 & 0xff);\n            if (!freq)\n                freq = 15;\n            spi->setFrequency(freq * 1000000);\n            spi->setMode(0);\n            auto cs = LOOKUP_PIN(DISPLAY_CS);\n            if (cs)\n                cs->setDigitalValue(1);\n\n            // make sure the SPI peripheral is initialized before toggling reset\n            spi->write(0);\n        }\n\n        auto rst = LOOKUP_PIN(DISPLAY_RST);\n        if (rst) {\n            rst->setDigitalValue(0);\n            fiber_sleep(20);\n            rst->setDigitalValue(1);\n            fiber_sleep(20);\n        }\n\n        if (lcd) {\n            auto bl = LOOKUP_PIN(DISPLAY_BL);\n            if (bl) {\n                bl->setDigitalValue(1);\n            }\n\n            lcd->init();\n            lcd->configure(madctl, frmctr1);\n        }\n\n        width = getConfig(CFG_DISPLAY_WIDTH, 160);\n        height = getConfig(CFG_DISPLAY_HEIGHT, 128);\n        displayHeight = height;\n        setAddrMain();\n        DMESG(\"screen: %d x %d, off=%d,%d\", width, height, offX, offY);\n        int sz = doubleSize ? (width >> 1) * (height >> 1) : width * height;\n        screenBuf = (uint8_t *)app_alloc(sz / 2 + 20);\n\n        lastStatus = NULL;\n        registerGC((TValue *)&lastStatus);\n        inUpdate = false;\n    }\n\n    uint32_t smartConfigure(uint32_t *cfg0, uint32_t *cfg1, uint32_t *cfg2) {\n        uint32_t hc;\n\n        DMESG(\"74HC: waiting...\");\n\n        // wait while nothing is connected\n        for (;;) {\n            auto rst = LOOKUP_PIN(DISPLAY_RST);\n            if (rst) {\n                rst->setDigitalValue(0);\n                target_wait_us(10);\n                rst->setDigitalValue(1);\n                fiber_sleep(3); // in reality we need around 1.2ms\n            }\n\n            hc = readButtonMultiplexer(17);\n            if (hc != 0)\n                break;\n\n            fiber_sleep(100);\n\n            // the device will run without shield when the following is specified in user program:\n            // namespace userconfig { export const DISPLAY_CFG0 = 0x02000080 }\n            if (*cfg0 & 0x2000000) {\n                DMESG(\"74HC: no wait requested\");\n                return DISPLAY_TYPE_ST7735;\n            }\n        }\n\n        DMESG(\"74HC: %x\", hc);\n\n        // is the line forced up? if so, assume JDDisplay\n        if (hc == 0x1FFFF) {\n            disableButtonMultiplexer();\n            return DISPLAY_TYPE_SMART;\n        }\n\n        hc = hc >> 1;\n\n        // SER pin (or first bit of second HC) is orientation\n        if (hc & 0x0010)\n            *cfg0 = 0x80;\n        else\n            *cfg0 = 0x40;\n\n        uint32_t configId = (hc & 0xe0) >> 5;\n\n        switch (configId) {\n        case 1:\n            *cfg1 = 0x0603; // ST7735\n            break;\n        case 2:\n            *cfg1 = 0xe14ff; // ILI9163C\n            *cfg0 |= 0x08;   // BGR colors\n            break;\n        case 3:\n            *cfg1 = 0x0603;     // ST7735\n            *cfg0 |= 0x1000000; // inverted colors\n            break;\n        default:\n            target_panic(PANIC_SCREEN_ERROR);\n            break;\n        }\n\n        DMESG(\"config type: %d; cfg0=%x cfg1=%x\", configId, *cfg0, *cfg1);\n\n        *cfg2 = 32; // Damn the torpedoes! 32MHz\n\n        return DISPLAY_TYPE_ST7735;\n    }\n\n    void setAddrStatus() {\n        if (lcd)\n            lcd->setAddrWindow(offX, offY + displayHeight, width, height - displayHeight);\n        else\n            smart->setAddrWindow(offX, offY + displayHeight, width, height - displayHeight);\n    }\n    void setAddrMain() {\n        if (lcd)\n            lcd->setAddrWindow(offX, offY, width, displayHeight);\n        else\n            smart->setAddrWindow(offX, offY, width, displayHeight);\n    }\n    void waitForSendDone() {\n        if (lcd)\n            lcd->waitForSendDone();\n        else\n            smart->waitForSendDone();\n    }\n    int sendIndexedImage(const uint8_t *src, unsigned width, unsigned height, uint32_t *palette) {\n        if (lcd)\n            return lcd->sendIndexedImage(src, width, height, palette);\n        else\n            return smart->sendIndexedImage(src, width, height, palette);\n    }\n};\n\nSINGLETON_IF_PIN(WDisplay, DISPLAY_MOSI);\n\n//%\nint setScreenBrightnessSupported() {\n    auto display = getWDisplay();\n    if (display && display->smart)\n        return 1;\n\n    auto bl = LOOKUP_PIN(DISPLAY_BL);\n    if (!bl)\n        return 0;\n#ifdef SAMD51\n    if (bl->name == PA06)\n        return 0;\n#endif\n#ifdef NRF52_SERIES\n    // PWM not implemented yet\n    return 0;\n#else\n    return 1;\n#endif\n}\n\n//%\nvoid setScreenBrightness(int level) {\n    if (level < 0)\n        level = 0;\n    if (level > 100)\n        level = 100;\n\n    auto display = getWDisplay();\n    if (display && display->smart) {\n        display->smart->brightness = level;\n        return;\n    }\n\n    auto bl = LOOKUP_PIN(DISPLAY_BL);\n    if (!bl)\n        return;\n\n    if (level == 0)\n        bl->setDigitalValue(0);\n    else if (level == 100)\n        bl->setDigitalValue(1);\n    else {\n        if (setScreenBrightnessSupported()) {\n            bl->setAnalogPeriodUs(1000);\n            bl->setAnalogValue(level * level * 1023 / 10000);\n        }\n    }\n}\n\n//%\nvoid setPalette(Buffer buf) {\n    auto display = getWDisplay();\n    if (!display)\n        return;\n\n    if (48 != buf->length)\n        target_panic(PANIC_SCREEN_ERROR);\n    for (int i = 0; i < 16; ++i) {\n        display->currPalette[i] =\n            (buf->data[i * 3] << 16) | (buf->data[i * 3 + 1] << 8) | (buf->data[i * 3 + 2] << 0);\n        display->currPalette[i] ^= display->palXOR;\n    }\n    display->newPalette = true;\n}\n\n//%\nvoid setupScreenStatusBar(int barHeight) {\n    auto display = getWDisplay();\n    if (!display)\n        return;\n    if (!display->doubleSize) {\n        display->displayHeight = display->height - barHeight;\n        display->setAddrMain();\n    }\n}\n\n//%\nvoid updateScreenStatusBar(Image_ img) {\n    auto display = getWDisplay();\n    if (!display)\n        return;\n\n    if (!img)\n        return;\n    display->lastStatus = img;\n}\n\n//%\nvoid updateScreen(Image_ img) {\n    auto display = getWDisplay();\n    if (!display)\n        return;\n\n    if (display->inUpdate)\n        return;\n\n    display->inUpdate = true;\n\n    auto mult = display->doubleSize ? 2 : 1;\n\n    if (img) {\n        if (img->bpp() != 4 || img->width() * mult != display->width ||\n            img->height() * mult != display->displayHeight)\n            target_panic(PANIC_SCREEN_ERROR);\n\n        // DMESG(\"wait for done\");\n        display->waitForSendDone();\n\n        auto palette = display->currPalette;\n\n        if (display->newPalette) {\n            display->newPalette = false;\n        } else {\n            // smart mode always sends palette\n            if (!display->smart)\n                palette = NULL;\n        }\n\n        memcpy(display->screenBuf, img->pix(), img->pixLength());\n\n        // DMESG(\"send\");\n        display->sendIndexedImage(display->screenBuf, img->width(), img->height(), palette);\n    }\n\n    if (display->lastStatus && !display->doubleSize) {\n        display->waitForSendDone();\n        img = display->lastStatus;\n        auto barHeight = display->height - display->displayHeight;\n        if (img->bpp() != 4 || barHeight != img->height() || img->width() != display->width)\n            target_panic(PANIC_SCREEN_ERROR);\n        memcpy(display->screenBuf, img->pix(), img->pixLength());\n        display->setAddrStatus();\n        display->sendIndexedImage(display->screenBuf, img->width(), img->height(), NULL);\n        display->waitForSendDone();\n        display->setAddrMain();\n        display->lastStatus = NULL;\n    }\n\n    display->inUpdate = false;\n}\n\n//%\nvoid updateStats(String msg) {\n    // ignore...\n}\n\n} // namespace pxt","screenimage.ts":"\nnamespace image {\n    /**\n    * Get the screen image\n    */\n    //% blockNamespace=\"images\" group=\"Create\"\n    //% blockId=imagescreen block=\"screen\"\n    //% help=images/screen-image\n    export function screenImage(): Image {\n        return screen;\n    }\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\n\n\ndeclare interface Image {\n    /**\n     * Get the width of the image\n     */\n    //% property shim=ImageMethods::width\n    width: int32;\n\n    /**\n     * Get the height of the image\n     */\n    //% property shim=ImageMethods::height\n    height: int32;\n\n    /**\n     * True if the image is monochromatic (black and white)\n     */\n    //% property shim=ImageMethods::isMono\n    isMono: boolean;\n\n    /**\n     * Sets all pixels in the current image from the other image, which has to be of the same size and\n     * bpp.\n     */\n    //% shim=ImageMethods::copyFrom\n    copyFrom(from: Image): void;\n\n    /**\n     * Set pixel color\n     */\n    //% shim=ImageMethods::setPixel\n    setPixel(x: int32, y: int32, c: int32): void;\n\n    /**\n     * Get a pixel color\n     */\n    //% shim=ImageMethods::getPixel\n    getPixel(x: int32, y: int32): int32;\n\n    /**\n     * Fill entire image with a given color\n     */\n    //% shim=ImageMethods::fill\n    fill(c: int32): void;\n\n    /**\n     * Copy row(s) of pixel from image to buffer (8 bit per pixel).\n     */\n    //% shim=ImageMethods::getRows\n    getRows(x: int32, dst: Buffer): void;\n\n    /**\n     * Copy row(s) of pixel from buffer to image.\n     */\n    //% shim=ImageMethods::setRows\n    setRows(x: int32, src: Buffer): void;\n\n    /**\n     * Return a copy of the current image\n     */\n    //% shim=ImageMethods::clone\n    clone(): Image;\n\n    /**\n     * Flips (mirrors) pixels horizontally in the current image\n     */\n    //% shim=ImageMethods::flipX\n    flipX(): void;\n\n    /**\n     * Flips (mirrors) pixels vertically in the current image\n     */\n    //% shim=ImageMethods::flipY\n    flipY(): void;\n\n    /**\n     * Returns a transposed image (with X/Y swapped)\n     */\n    //% shim=ImageMethods::transposed\n    transposed(): Image;\n\n    /**\n     * Every pixel in image is moved by (dx,dy)\n     */\n    //% shim=ImageMethods::scroll\n    scroll(dx: int32, dy: int32): void;\n\n    /**\n     * Stretches the image horizontally by 100%\n     */\n    //% shim=ImageMethods::doubledX\n    doubledX(): Image;\n\n    /**\n     * Stretches the image vertically by 100%\n     */\n    //% shim=ImageMethods::doubledY\n    doubledY(): Image;\n\n    /**\n     * Replaces one color in an image with another\n     */\n    //% shim=ImageMethods::replace\n    replace(from: int32, to: int32): void;\n\n    /**\n     * Stretches the image in both directions by 100%\n     */\n    //% shim=ImageMethods::doubled\n    doubled(): Image;\n\n    /**\n     * Draw given image on the current image\n     */\n    //% shim=ImageMethods::drawImage\n    drawImage(from: Image, x: int32, y: int32): void;\n\n    /**\n     * Draw given image with transparent background on the current image\n     */\n    //% shim=ImageMethods::drawTransparentImage\n    drawTransparentImage(from: Image, x: int32, y: int32): void;\n\n    /**\n     * Check if the current image \"collides\" with another\n     */\n    //% shim=ImageMethods::overlapsWith\n    overlapsWith(other: Image, x: int32, y: int32): boolean;\n}\ndeclare namespace image {\n\n    /**\n     * Create new empty (transparent) image\n     */\n    //% shim=image::create\n    function create(width: int32, height: int32): Image;\n\n    /**\n     * Create new image with given content\n     */\n    //% shim=image::ofBuffer\n    function ofBuffer(buf: Buffer): Image;\n\n    /**\n     * Double the size of an icon\n     */\n    //% shim=image::doubledIcon\n    function doubledIcon(icon: Buffer): Buffer;\n}\n\n// Auto-generated. Do not edit. Really.\n","targetoverrides.ts":"/**\n * Tagged image literal converter\n */\n//% shim=@f4 helper=image::ofBuffer blockIdentity=\"images._spriteImage\"\n//% groups=[\"0.\",\"1#\",\"2T\",\"3t\",\"4N\",\"5n\",\"6G\",\"7g\",\"8\",\"9\",\"aAR\",\"bBP\",\"cCp\",\"dDO\",\"eEY\",\"fFW\"]\nfunction img(lits: any, ...args: any[]): Image { return null }\n\n// this wait needed in case of an ESD event for arcade shield\nconst delay = control.getConfigValue(DAL.CFG_DISPLAY_DELAY, 0)\nif (delay > 0)\n    control.waitMicros(delay * 1000)\n\n// set palette before creating screen, so the JS version has the right BPP\nimage.setPalette(hex`__palette`)\n//% whenUsed\nconst screen = _screen_internal.createScreen();\n\nnamespace image {\n    //% shim=pxt::setPalette\n    export function setPalette(buf: Buffer) { }\n}\n\nnamespace _screen_internal {\n    //% shim=pxt::updateScreen\n    function updateScreen(img: Image): void { }\n    //% shim=pxt::updateStats\n    function updateStats(msg: string): void { }\n\n    //% shim=pxt::updateScreenStatusBar\n    function updateScreenStatusBar(img: Image): void { return }\n    //% shim=pxt::setupScreenStatusBar\n    function setupScreenStatusBar(barHeight: number): void { return }\n\n    //% shim=TD_ID\n    function getScreenWidth(defl: number) {\n        return control.getConfigValue(DAL.CFG_ARCADE_SCREEN_WIDTH, defl)\n    }\n\n    //% shim=TD_ID\n    function getScreenHeight(defl: number) {\n        return control.getConfigValue(DAL.CFG_ARCADE_SCREEN_HEIGHT, defl)\n    }\n\n    export function createScreen() {\n        const img = image.create(getScreenWidth(160), getScreenHeight(120));\n        setupScreenStatusBar(8);\n\n        const status = image.create(160, 8)\n        updateScreenStatusBar(status) // clear the status area\n\n        control.__screen.setupUpdate(() => updateScreen(img))\n        control.EventContext.onStats = function (msg: string) {\n            status.fill(0)\n            status.print(msg, 2, 2, 1, image.font5)\n            updateScreenStatusBar(status)\n            updateStats(msg);\n        }\n\n        return img as ScreenImage;\n    }\n\n}\n","text.ts":"namespace image {\n\n    export interface Font {\n        charWidth: number;\n        charHeight: number;\n        data: Buffer;\n        multiplier?: number;\n    }\n\n    //% whenUsed\n    export const font8: Font = {\n        charWidth: 6,\n        charHeight: 8,\n        data: hex`\n2000000000000000 210000005e000000 2200000e000e0000 230028fe28fe2800 24004c92ff926400 250002651248a640\n26006c92926ca000 270000000e000000 280000007c820000 29000000827c0000 2a00543810385400 2b0010107c101000\n2c00000090700000 2d00101010101000 2e00000060600000 2f00006010080600 3000003c42423c00 310000447e400000\n3200004462524c00 330000424a4e3200 34003028247e2000 3500004e4a4a3200 3600003c4a4a3000 3700000262120e00\n380000344a4a3400 3900000c52523c00 3a0000006c6c0000 3b00000096760000 3c00102828444400 3d00282828282800\n3e00444428281000 3f00000259090600 40003c425a560800 4100781412147800 42007e4a4a4a3400 4300003c42422400\n4400007e42423c00 4500007e4a4a4200 4600007e0a0a0200 4700003c42523400 4800007e08087e00 490000427e420000\n4a002040423e0200 4b00007e08146200 4c00007e40404000 4d007e0418047e00 4e00007e04087e00 4f003c4242423c00\n5000007e12120c00 5100003c5262bc00 5200007e12126c00 530000244a522400 540002027e020200 5500003e40403e00\n5600001e70701e00 57007e2018207e00 5800422418244200 5900060870080600 5a000062524a4600 5b00007e42420000\n5c00000608106000 5d000042427e0000 5e00080402040800 5f00808080808000 6000000002040000 6100003048487800\n6200007e48483000 6300003048484800 6400003048487e00 6500003068585000 660000107c120400 67000018a4a47800\n6800007e08087000 690000487a400000 6a000040847d0000 6b00007e10284000 6c0000427e400000 6d00780830087000\n6e00007808087000 6f00003048483000 700000fc24241800 710000182424fc00 7200007810081000 7300005058682800\n740000083e482000 7500003840407800 7600001860601800 7700384030403800 7800004830304800 7900005ca0a07c00\n7a00004868584800 7b00000836410000 7c000000fe000000 7d00004136080000 7e00000804080400 a000000000000000\na10000007a000000 a200003048fc4800 a30090fc92928400 a400542844285400 a5002a2c782c2a00 a6000000ee000000\na7000094aaaa5200 a800000200020000 a9003e414955413e aa0000242a2e0000 ab00102854284400 ac00001010107000\nad00001010101000 ae003e415d45413e af00000202020200 b000000814140800 b1008888be888800 b2000024322c0000\nb30000222a140000 b400000004020000 b50000f840207800 b6000c1e7e027e00 b700000010000000 b800000080400000\nb90000243e200000 ba0000242a240000 bb00442854281000 bc00025f70f84000 bd00021f90c8b000 be0011557af84000\nbf000030484d2000 c000601916186000 c100601816196000 c200601a151a6000 c300601a151a6100 c400601914196000\nc500601a151a6000 c6007c0a7e4a4200 c700001ea1611200 c800007c55564400 c900007c56554400 ca00007c56554600\ncb00007c55544500 cc0000457e440000 cd0000447e450000 ce0000467d460000 cf0000457c450000 d000087e4a423c00\nd100007e09127d00 d200003845463800 d300003846453800 d400003846453a00 d500003a45463900 d600003845443900\nd700442810284400 d80000fc724e3f00 d900003c41423c00 da00003c42413c00 db00003c42413e00 dc00003c41403d00\ndd00040872090400 de00007e24241800 df00007c025a2400 e0000030494a7800 e10000304a497800 e20000304a497a00\ne3000032494a7900 e40000304a487a00 e50000304a4d7a00 e600304878685000 e7000018a4642400 e8000030695a5000\ne90000306a595000 ea0000306a595200 eb0000306a585200 ec0000497a400000 ed0000487a410000 ee00004a79420000\nef00004a78420000 f00000304a4b3d00 f100007a090a7100 f2000030494a3000 f30000304a493000 f40000304a493200\nf5000032494a3100 f60000304a483200 f700101054101000 f800007068583800 f900003841427800 fa00003842417800\nfb00003842417a00 fc00003842407a00 fd0000b84241f800 fe0000ff24241800 ff00005ca1a07d00 0001601915196000\n010100304a4a7a00 0201611a16196000 030100314a4a7900 04013c0a094abc00 050100182464bc00 0601003846452800\n070100304a494800 0801003846452a00 090100304a494a00 0a01003844452800 0b010030484a4800 0c01003845462900\n0d010030494a4900 0e01007c45463900 0f0100314a497e00 1001087e4a423c00 110130484c7e0400 1201007d55554500\n130100326a5a5200 1401007d56564500 150100316a5a5100 1601007c55544400 170100306a585000 1801003f65a52100\n1901001874ac2800 1a01007c55564500 1b010030695a5100 1c01003846553600 1d0100304a49f200 1e01003946563500\n1f0100314a4af100 2001003844553400 21010018a4a57800 2201001ea1691a00 23010018a6a57800 2401007812117a00\n25017e080a710200 2601047e147e0400 2701047e0c087000 28010002457e4500 29010002497a4100 2a0100457d450000\n2b01004a7a420000 2c0100014a7a4900 2d0100014a7a4100 2e0100217fa10000 2f0100247da00000 300100447d440000\n3101004878400000 32017e0022423e00 33013d0040847d00 34012040463d0600 350100800af90200 360100bf440a3100\n370100bf48142000 3801007810284800 3901007c40424100 3a0100467d400000 3b01003fa0602000 3c0100a17f200000\n3d01007c41424100 3e0100457e410000 3f01007e40484000 400100427e400800 4101107e48404000 420100527e480000\n4301007c0a117c00 440100780a097000 450100bf42043f00 460100bc44043800 4701007c09127d00 480100790a097000\n49010a0678087000 4a01003f02847f00 4b01003c04847800 4c01394545453900 4d0100324a4a3200 4e01394646463900\n4f0100314a4a3100 50013a4544463900 5101324948320100 52013c427e4a4200 5301304830685000 5401007c16354800\n5501007812091000 560100bf49093600 570100bc48040800 5801007d16354800 5901007912091000 5a01004856552400\n5b0100505a692800 5c01004856552600 5d0100505a692a00 5e010012a5691200 5f010028ac741400 6001004855562500\n61010050596a2900 62010101bf410100 630100049f641000 640104057e050400 650100083d4a2100 660102127e120200\n670100183e582000 6801003a41423900 6901003a41427900 6a01003d41413d00 6b01003a42427a00 6c01003942423900\n6d01003942427900 6e01003a45453a00 6f01003a45457a00 70013a41403a0100 71013a41407a0100 7201001f60a01f00\n7301001c60a03c00 7401782211227800 7501384231423800 7601081261120800 770100b84241fa00 7801040970090400\n79010064564d4400 7a0100486a594800 7b010064544d4400 7c010048685a4800 7d010064554e4500 7e010048695a4900\n7f0100087c020400 8f01003452523c00 920100887e090200 a0013c42423c0806 a101003048483008 af01003e403e0806\nb001003840781008 b501006a5a4a4e00 b601005878585800 d101003845463900 d2010030494a3100 e601003845563500\ne7010030494af100 fa0100742a750000 fb0100304c4a7d00 fc0178147e554400 fd0130487a695000 fe010078744e3d00\nff0100706a593800 18020012a5691200 19020028ac741400 1a020101bf410100 1b0200049f641000 bb0200000c0a0000\nbc0200000a060000 bd020000060a0000 c602000201020000 c702000102010000 c902000202020000 d802000102020100\nd902000002000000 da02000205020000 db02000040800000 dc02000201020100 dd02020100020100 7403000002010000\n7503000080400000 7a030000c0800000 7e03000096760000 8403000003000000 8503020003000200 8603037c12127c00\n8703000010000000 880303007e4a4200 890303007e087e00 8a030300427e4200 8c03033c42423c00 8e0303000e700e00\n8f03035c62625c00 900302003b400200 9103781412147800 92037e4a4a4a3400 9303007e02020200 9403605846586000\n9503007e4a4a4200 96030062524a4600 9703007e08087e00 98033c4a4a4a3c00 990300427e420000 9a03007e08146200\n9b03601806186000 9c037e0418047e00 9d03007e04087e00 9e0300424a4a4200 9f033c4242423c00 a003007e02027e00\na103007e12120c00 a30300665a424200 a40302027e020200 a503060870080600 a60318247e241800 a703422418244200\na8030e107e100e00 a9035c6202625c00 aa0300457c450000 ab03040970090400 ac030030484a7900 ad030030685a5100\nae0378100a09f000 af03003a41200000 b0033a4043403a00 b103003048487800 b20300fe25251a00 b3030c30c0300c00\nb403344a4a4a3000 b503003068585000 b603021aa6a24200 b7033c080404f800 b803003c4a4a3c00 b903003840200000\nba03007820504800 bb03641212227c00 bc03fc2020103c00 bd03182040201800 be03112d2ba94100 bf03003048483000\nc003087808780800 c103f82424241800 c2031824a4a44800 c303304848582800 c403000838482800 c503384040403800\nc6031c20f8241800 c703c4281028c400 c8031c20fc201c00 c903304820483000 ca03000238422000 cb03384240423800\ncc0330484a493000 cd03384042413800 ce03304822493000 d0033c52525c2000 d10310344a3c0800 d203067804020400\nd303120a7c020400 d4030d7009040800 d5031824ff241800 d603384828483800 d70348302221d800 da031c2221a14200\ndb031824a4a44200 dc037e1212020200 dd0300fc24240400 de033e2010087c00 df030c0ac9281800 e003700c621c7000\ne10301092516f800 e2039ea0bea07e00 e30398a0b8a07800 e4030c1214107e00 e503001028207800 e603be9088887000\ne70348544e443800 e803245252524c00 e903285454544800 ea0364524c526400 eb03086458640800 ec03385454542200\ned03306848682400 ee03184a7e4a1800 ef031848ff0a0800 f003483020205800 f10378a4a4a49800 f203304848485000\nf303006080847d00 f4033c4a4a4a3c00 f503003058584800 0004007c55564400 0104007c55544500 020401013f857900\n0304007c06050400 04043c4a4a422400 050400244a522400 060400427e420000 070400457c450000 08042040423e0200\n09047c027e483000 0a047e087e483000 0b0402027e0a7200 0c04007c102a4500 0d047c2112087c00 0e040c5152523d00\n0f043f20e0203f00 1004781412147800 11047e4a4a4a3000 12047e4a4a4a3400 1304007e02020200 1404c07c427ec000\n1504007e4a4a4200 160476087e087600 170424424a4a3400 1804007e08047e00 1904007d120a7d00 1a04007e08146200\n1b04403c02027e00 1c047e0418047e00 1d04007e08087e00 1e043c4242423c00 1f047e0202027e00 2004007e12120c00\n2104003c42422400 220402027e020200 23040e5050503e00 240418247e241800 2504422418244200 26043f2020bf6000\n27040e1010107e00 28047e407e407e00 29043f203fa07f00 2a04027e48483000 2b047e4848307e00 2c04007e48483000\n2d0424424a4a3c00 2e047e183c423c00 2f04006c12127e00 3004304848784000 3104003c4a4a3100 3204007868502000\n3304007808080800 3404c0704878c000 3504306868500000 3604483078304800 3704004058683000 3804784020107800\n3904794222127900 3a04007820304800 3b04403008087800 3c04781020107800 3d04781010107800 3e04304848483000\n3f04780808087800 4004fc2424241800 4104304848485000 4204080878080800 43041ca0a0a07c00 44041824ff241800\n4504004830304800 46043c2020bc6000 4704182020207800 4804784078407800 49043c203ca07c00 4a04087850502000\n4b04785050207800 4c04007850502000 4d04485868300000 4e04783030483000 4f04502828780000 50040030696a5000\n51040032686a5000 5204023f0a887000 530400780a090800 5404003068584800 5504005058682800 560400487a400000\n5704004a78420000 5804004080847d00 5904700878502000 5a04781078502000 5b04047e14106000 5c04007822314800\n5d04784122107800 5e0418a1a2a27900 5f043c20e0203c00 6204027f4a483000 6304087e58502000 70040e107e100e00\n7104182078201800 72043c4a4a4a3c00 7304306858683000 7404001e70180c00 7504001860301000 9004007e02020300\n9104007808080c00 9204087e0a0a0200 9304207828080800 96043b043f043be0 970424183c1824c0 9a04003f040a31c0\n9b04003c101824c0 ae04060870080600 af040c10e0100c00 b004161870181600 b1042c30e0302c00 b20421120c1221c0\nb3040024181824c0 ba047e0808087000 bb04007e08087000 d804003452523c00 d904002868583000 e20400457d450000\ne304004a7a420000 e8043c4a4a4a3c00 e904003058583000 ee04003d41413d00 ef04003a42427a00 d005681020285000\nd105484848784000 d205004830600000 d305080808780800 d405680808087800 d505000008780000 d605080818680800\nd705087808087800 d805784050487800 d905000008180000 da0504040404fc00 db05484848483800 dc050e4848281800\ndd05087848487800 de05582010487000 df05000004fc0000 e005004040487800 e105000878483800 e205487840281800\ne305041c0404fc00 e405485848483800 e50504f820140800 e605485060685000 e705f40424241c00 e805080808087000\ne905785058403800 ea05487808087800 f005087800087800 f105081800087800 f205081800081800 f305000010080000\nf405100800100800 021e7c5455542800 031e007e48493000 0a1e007c45443800 0b1e003049487e00 1e1e007c15140400\n1f1e001079140800 401e7e0419047e00 411e780832087000 561e007c15140800 571e00fc25241800 601e004854552400\n611e0050586a2800 6a1e04047d040400 6b1e00083d482000 801e7c2112207c00 811e384132403800 821e7c2012217c00\n831e384032413800 841e7c2110217c00 851e384230423800 f21e040972080400 f31e00b84142f800 a3207e0a7a120a00\na420a8fcaa828400 a720087e2a1c0800 ab200098a4a6bf02 ac20183c5a5a4200 af20627f22443800 9021103854101000\n912108047e040800 9221101054381000 932110207e201000 9421103810103810 95212844fe442800 \n`,\n\n    }\n\n    // A unicode 12x12 pixel font based on https://github.com/adobe-fonts/source-han-sans\n    //% whenUsed jres\n    export const font12: Font = {\n        charWidth: 12,\n        charHeight: 12,\n        data: hex``\n    }\n\n    export function getFontForText(text: string) {\n        for (let i = 0; i < text.length; ++i) {\n            // this is quite approximate\n            if (text.charCodeAt(i) > 0x2000)\n                return image.font12\n        }\n        return image.font8\n    }\n\n    //% deprecated=1 hidden=1\n    export function doubledFont(f: Font): Font {\n        return scaledFont(f, 2)\n    }\n\n    export function scaledFont(f: Font, size: number): Font {\n        size |= 0\n        if (size < 2)\n            return f\n        return {\n            charWidth: f.charWidth * size,\n            charHeight: f.charHeight * size,\n            data: f.data,\n            multiplier: f.multiplier ? size * f.multiplier : size\n        }\n    }\n\n    //% whenUsed\n    export const font5: Font = {\n        charWidth: 6,\n        charHeight: 5,\n        // source https://github.com/lancaster-university/microbit-dal/blob/master/source/core/MicroBitFont.cpp\n        data: hex`\n2000000000000000 2100001700000000 2200000300030000 23000a1f0a1f0a00 24000a17151d0a00 2500130904121900\n26000a15150a1000 2700000300000000 2800000e11000000 290000110e000000 2a00000a040a0000 2b0000040e040000\n2c00001008000000 2d00000404040000 2e00000800000000 2f00100804020100 30000e11110e0000 310000121f100000\n3200191515120000 33000911150b0000 34000c0a091f0800 3500171515150900 3600081416150800 3700110905030100\n38000a1515150a00 390002150d050200 3a00000a00000000 3b0000100a000000 3c0000040a110000 3d00000a0a0a0000\n3e0000110a040000 3f00020115050200 40000e1115090e00 41001e05051e0000 42001f15150a0000 43000e1111110000\n44001f11110e0000 45001f1515110000 46001f0505010000 47000e1111150c00 48001f04041f0000 4900111f11000000\n4a000911110f0100 4b001f040a110000 4c001f1010100000 4d001f0204021f00 4e001f0204081f00 4f000e11110e0000\n50001f0505020000 5100060919160000 52001f05050a1000 5300121515090000 540001011f010100 55000f10100f0000\n5600070810080700 57001f0804081f00 58001b04041b0000 590001021c020100 5a00191513110000 5b00001f11110000\n5c00010204081000 5d000011111f0000 5e00000201020000 5f00101010101000 6000000102000000 61000c12121e1000\n62001f1414080000 63000c1212120000 64000814141f0000 65000e1515120000 6600041e05010000 67000215150f0000\n68001f0404180000 6900001d00000000 6a000010100d0000 6b001f040a100000 6c00000f10100000 6d001e0204021e00\n6e001e02021c0000 6f000c12120c0000 70001e0a0a040000 7100040a0a1e0000 72001c0202020000 730010140a020000\n7400000f14141000 75000e10101e1000 7600060810080600 77001e1008101e00 7800120c0c120000 7900121408040200\n7a00121a16120000 7b0000041f110000 7c00001f00000000 7d00111f04000000 7e00000404080800 d3000c1213130c00\nf3000c12130d0000 04010e05051e1000 05010609191f0800 06010c1213131200 07010c1213130000 18010f0b1b190000\n19010e151d1a0000 41011f1412100000 4201100f14120000 43011f0205081f00 44011e03031c0000 5a0110140b030200\n5b0110140b030000 7901121a17130000 7a01121a17130000 7b01121b17120000 7c01121b17120000`,\n    }\n}\n\nnamespace texteffects {\n    export interface TextEffectState {\n        xOffset: number;\n        yOffset: number;\n    }\n}\n\ninterface Image {\n    //% helper=imagePrint\n    print(text: string, x: number, y: number, color?: number, font?: image.Font, offsets?: texteffects.TextEffectState[]): void;\n\n    //% helper=imagePrintCenter\n    printCenter(text: string, y: number, color?: number, font?: image.Font): void;\n}\n\nnamespace helpers {\n    export function imagePrintCenter(img: Image, text: string, y: number, color?: number, font?: image.Font) {\n        if (!font) font = image.getFontForText(text)\n        let w = text.length * font.charWidth\n        let x = (img.width - w) / 2\n        imagePrint(img, text, x, y, color, font)\n    }\n\n    export function imagePrint(img: Image, text: string, x: number, y: number, color?: number, font?: image.Font, offsets?: texteffects.TextEffectState[]) {\n        x |= 0\n        y |= 0\n        if (!font)\n            font = image.getFontForText(text)\n        if (!color) color = 1\n        let x0 = x\n        let cp = 0\n        let mult = font.multiplier ? font.multiplier : 1\n        let dataW = Math.idiv(font.charWidth, mult)\n        let dataH = Math.idiv(font.charHeight, mult)\n        let byteHeight = (dataH + 7) >> 3\n        let charSize = byteHeight * dataW\n        let dataSize = 2 + charSize\n        let fontdata = font.data\n        let lastchar = Math.idiv(fontdata.length, dataSize) - 1\n        let imgBuf: Buffer\n        if (mult == 1) {\n            imgBuf = control.createBuffer(8 + charSize)\n            imgBuf[0] = 0x87\n            imgBuf[1] = 1\n            imgBuf[2] = dataW\n            imgBuf[4] = dataH\n        }\n        while (cp < text.length) {\n            let xOffset = 0, yOffset = 0;\n            if (offsets && cp < offsets.length) {\n                xOffset = offsets[cp].xOffset\n                yOffset = offsets[cp].yOffset\n            }\n\n            let ch = text.charCodeAt(cp++)\n            if (ch == 10) {\n                y += font.charHeight + 2\n                x = x0\n            }\n\n            if (ch < 32)\n                continue // skip control chars\n\n            let l = 0\n            let r = lastchar\n            let off = 0 // this should be a space (0x0020)\n            let guess = (ch - 32) * dataSize\n            if (fontdata.getNumber(NumberFormat.UInt16LE, guess) == ch)\n                off = guess\n            else {\n                while (l <= r) {\n                    let m = l + ((r - l) >> 1);\n                    let v = fontdata.getNumber(NumberFormat.UInt16LE, m * dataSize)\n                    if (v == ch) {\n                        off = m * dataSize\n                        break\n                    }\n                    if (v < ch)\n                        l = m + 1\n                    else\n                        r = m - 1\n                }\n            }\n\n            if (mult == 1) {\n                imgBuf.write(8, fontdata.slice(off + 2, charSize))\n                img.drawIcon(imgBuf, x + xOffset, y + yOffset, color)\n                x += font.charWidth\n            } else {\n                off += 2\n                for (let i = 0; i < dataW; ++i) {\n                    let j = 0\n                    let mask = 0x01\n                    let c = fontdata[off++]\n                    while (j < dataH) {\n                        if (mask == 0x100) {\n                            c = fontdata[off++]\n                            mask = 0x01\n                        }\n                        let n = 0\n                        while (c & mask) {\n                            n++\n                            mask <<= 1\n                        }\n                        if (n) {\n                            img.fillRect(x + xOffset * mult, y + (j + yOffset) * mult, mult, mult * n, color)\n                            j += n\n                        } else {\n                            mask <<= 1\n                            j++\n                        }\n                    }\n                    x += mult\n                }\n            }\n        }\n    }\n}\n"},"serial":{"enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum BaudRate {\n    //% block=115200\n    BaudRate115200 = 115200,\n    //% block=57600\n    BaudRate57600 = 57600,\n    //% block=38400\n    BaudRate38400 = 38400,\n    //% block=31250\n    BaudRate31250 = 31250,\n    //% block=28800\n    BaudRate28800 = 28800,\n    //% block=19200\n    BaudRate19200 = 19200,\n    //% block=14400\n    BaudRate14400 = 14400,\n    //% block=9600\n    BaudRate9600 = 9600,\n    //% block=4800\n    BaudRate4800 = 4800,\n    //% block=2400\n    BaudRate2400 = 2400,\n    //% block=1200\n    BaudRate1200 = 1200,\n    //% block=300\n    BaudRate300 = 300,\n    }\n\n\n    declare const enum SerialEvent {\n    //% block=\"data received\"\n    DataReceived = 4,  // CODAL_SERIAL_EVT_DATA_RECEIVED\n    //% block=\"rx buffer full\"\n    RxBufferFull = 3,  // CODAL_SERIAL_EVT_RX_FULL\n    }\n\n\n    declare const enum Delimiters {\n    //% block=\"new line (\\n)\"\n    NewLine = 10,\n    //% block=\",\"\n    Comma = 44,\n    //% block=\"$\"\n    Dollar = 36,\n    //% block=\":\"\n    Colon = 58,\n    //% block=\".\"\n    Fullstop = 46,\n    //% block=\"#\"\n    Hash = 35,\n    //% block=\"carriage return (\\r)\"\n    CarriageReturn = 13,\n    //% block=\"space\"\n    Space = 32,\n    //% block=\"tab (\\t)\"\n    Tab = 9,\n    //% block=\"|\"\n    Pipe = 124,\n    //% block=\";\"\n    SemiColon = 59,\n    }\n\n// Auto-generated. Do not edit. Really.\n","pxt.json":"{\n    \"name\": \"serial\",\n    \"description\": \"UART communication\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"serial-target.h\",\n        \"serial-common.h\",\n        \"serial-target.cpp\",\n        \"serial-common.cpp\",\n        \"serial-target.ts\",\n        \"serial.ts\",\n        \"enums.d.ts\",\n        \"shims.d.ts\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true\n}\n","serial-common.cpp":"#include \"pxt.h\"\n#include \"serial-target.h\"\n\nnamespace SerialDeviceMethods {\n/**\n * Sets the size of the RX buffer in bytes\n */\n//%\nvoid setRxBufferSize(SerialDevice device, uint8_t size) {\n    device->setRxBufferSize(size);\n}\n\n/**\n * Sets the size of the TX buffer in bytes\n */\n//%\nvoid setTxBufferSize(SerialDevice device, uint8_t size) {\n    device->setTxBufferSize(size);\n}\n\n/**\nSet the baud rate of the serial port\n*/\n//%\nvoid setBaudRate(SerialDevice device, BaudRate rate) {\n    device->setBaudRate((int)rate);\n}\n\n/**\n * Reads a single byte from the serial receive buffer. Negative if error, 0 if no data.\n */\n//%\nint read(SerialDevice device) {\n    return device->read();\n}\n\n/**\n * Read the buffered received data as a buffer\n */\n//%\nBuffer readBuffer(SerialDevice device) {\n    return device->readBuffer();\n}\n\n/**\n * Send a buffer across the serial connection.\n */\n//%\nvoid writeBuffer(SerialDevice device, Buffer buffer) {\n    device->writeBuffer(buffer);\n}\n\n/**\n * Register code when a serial event occurs\n */\n//%\nvoid onEvent(SerialDevice device, SerialEvent event, Action handler) {\n    device->onEvent(event, handler);\n}\n\n/**\n * Registers code when a delimiter is received\n **/\n//%\nvoid onDelimiterReceived(SerialDevice device, Delimiters delimiter, Action handler) {\n    device->onDelimiterReceived(delimiter, handler);\n}\n} // namespace SerialDeviceMethods\n","serial-common.h":"#pragma once\n#include \"pxt.h\"\n#include \"serial-target.h\"\n\nenum class BaudRate {\n  //% block=115200\n  BaudRate115200 = 115200,\n  //% block=57600\n  BaudRate57600 = 57600,\n  //% block=38400\n  BaudRate38400 = 38400,\n  //% block=31250\n  BaudRate31250 = 31250,\n  //% block=28800\n  BaudRate28800 = 28800,\n  //% block=19200\n  BaudRate19200 = 19200,\n  //% block=14400\n  BaudRate14400 = 14400,\n  //% block=9600\n  BaudRate9600 = 9600,\n  //% block=4800\n  BaudRate4800 = 4800,\n  //% block=2400\n  BaudRate2400 = 2400,\n  //% block=1200\n  BaudRate1200 = 1200,\n  //% block=300\n  BaudRate300 = 300\n};\n\nenum class SerialEvent {\n    //% block=\"data received\"\n    DataReceived = CODAL_SERIAL_EVT_DATA_RECEIVED,\n    //% block=\"rx buffer full\"\n    RxBufferFull = CODAL_SERIAL_EVT_RX_FULL\n};\n\nenum class Delimiters {\n    //% block=\"new line (\\n)\"\n    NewLine = 10,\n    //% block=\",\"\n    Comma = 44,\n    //% block=\"$\"\n    Dollar = 36,\n    //% block=\":\"\n    Colon = 58,\n    //% block=\".\"\n    Fullstop = 46,\n    //% block=\"#\"\n    Hash = 35,\n    //% block=\"carriage return (\\r)\"\n    CarriageReturn = 13,\n    //% block=\"space\"\n    Space = 32,\n    //% block=\"tab (\\t)\"\n    Tab = 9,\n    //% block=\"|\"\n    Pipe = 124,\n    //% block=\";\"\n    SemiColon = 59,\n};\n\n","serial-target.cpp":"#include \"pxt.h\"\n#include \"serial-target.h\"\n\nnamespace serial {\n\nstatic SerialDevice serialDevices(NULL);\n/**\n * Opens a Serial communication driver\n */\n//%\nSerialDevice internalCreateSerialDevice(DigitalInOutPin tx, DigitalInOutPin rx, int id) {\n    auto dev = serialDevices;\n    while (dev) {\n        if (dev->matchPins(tx, rx))\n            return dev;\n        dev = dev->next;\n    }\n\n    // allocate new one\n    auto ser = new CodalSerialDeviceProxy(tx, rx, id);\n    ser->next = serialDevices;\n    serialDevices = ser;\n    return ser;\n}\n\n} // namespace serial\n\nnamespace SerialDeviceMethods {\n\n/**\n */\n//%\nvoid redirect(SerialDevice device, DigitalInOutPin tx, DigitalInOutPin rx, BaudRate rate) {\n    device->redirect(tx, rx, rate);\n}\n\n} // namespace SerialDeviceMethods\n","serial-target.h":"#pragma once\n#include \"pxt.h\"\n#include \"Serial.h\"\n\nenum class SerialEvent;\nenum class BaudRate;\nenum class Delimiters;\n\nnamespace serial {\n\nclass CodalSerialDeviceProxy {\n  private:\n    DevicePin *tx;\n    DevicePin *rx;\n\n  public:\n    CODAL_SERIAL ser;\n    CodalSerialDeviceProxy *next;\n\n    CodalSerialDeviceProxy(DevicePin *_tx, DevicePin *_rx, uint16_t id)\n        : tx(_tx), rx(_rx), ser(*tx, *rx), next(NULL) {\n        if (id <= 0)\n            id = allocateNotifyEvent();\n        ser.id = id;\n        ser.setBaud(115200);\n    }\n\n    bool matchPins(DevicePin *_tx, DevicePin *_rx) { return this->tx == _tx && this->rx == _rx; }\n\n    void setRxBufferSize(uint8_t size) { ser.setRxBufferSize(size); }\n\n    void setTxBufferSize(uint8_t size) { ser.setTxBufferSize(size); }\n\n    void setBaudRate(int rate) { ser.setBaud(rate); }\n\n    int read() {\n        uint8_t buf[1];\n        auto r = ser.read(buf, 1, codal::SerialMode::ASYNC);\n        // r < 0 => error\n        if (r < 0)\n            return r;\n        // r == 0, nothing read\n        if (r == 0)\n            return DEVICE_NO_DATA;\n        // read 1 char\n        return buf[0];\n    }\n\n    Buffer readBuffer() {\n        int n = ser.getRxBufferSize();\n        // n maybe 0 but we still call read to force\n        // to initialize rx\n        auto buf = mkBuffer(NULL, n);\n        auto res = buf;\n        registerGCObj(buf);\n        auto read = ser.read(buf->data, buf->length, SerialMode::ASYNC);\n        if (read == DEVICE_SERIAL_IN_USE || read == 0) { // someone else is reading\n            res = mkBuffer(NULL, 0);\n        } else if (buf->length != read) {\n            res = mkBuffer(buf->data, read);\n        }\n        unregisterGCObj(buf);\n        return res;\n    }\n\n    void writeBuffer(Buffer buffer) {\n        if (NULL == buffer)\n            return;\n        ser.send(buffer->data, buffer->length);\n    }\n\n    void redirect(DevicePin *tx, DevicePin *rx, BaudRate rate) {\n        this->tx = tx;\n        this->rx = rx;\n        this->ser.redirect(*tx, *rx);\n        this->setBaudRate((int)rate);\n    }\n\n    void onEvent(SerialEvent event, Action handler) {\n        ser.setRxBufferSize(ser.getRxBufferSize()); // turn on reading\n        registerWithDal(ser.id, (int)event, handler);\n    }\n\n    void onDelimiterReceived(Delimiters delimiter, Action handler) {\n        registerWithDal(ser.id, CODAL_SERIAL_EVT_DELIM_MATCH, handler);\n        ManagedString d((char)delimiter);\n        ser.eventOn(d);\n    }\n};\n\ntypedef CodalSerialDeviceProxy *SerialDevice;\n\n} // namespace serial\n","serial-target.ts":"namespace serial {\n    /**\n     * Creates a serial comm device\n     * @param tx \n     * @param rx \n     * @param id \n     */\n    //% help=serial/create-serial\n    //% parts=serial\n    export function createSerial(tx: DigitalInOutPin, rx: DigitalInOutPin, id?: number): Serial {\n        const dev = serial.internalCreateSerialDevice(tx, rx, id || 0);\n        return new Serial(dev);\n    }\n\n    let _device: Serial;\n    export function device(): Serial {\n        if (!_device) {\n            const tx = pins.pinByCfg(DAL.CFG_PIN_TX);\n            const rx = pins.pinByCfg(DAL.CFG_PIN_RX);\n            if (!tx || !rx) return undefined;\n            _device = serial.createSerial(tx, rx, DAL.DEVICE_ID_SERIAL);\n        }\n        return _device;\n    }\n\n\n    /**\n    * Set the serial input and output to use pins instead of the USB connection.\n    * @param tx the new transmission pin\n    * @param rx the new reception pin\n    * @param rate the new baud rate\n    */\n    //% weight=10\n    //% help=serial/redirect\n    //% blockId=serial_redirect block=\"serial|redirect to|TX %tx|RX %rx at rate %rate\"\n    //% tx.fieldEditor=\"gridpicker\" tx.fieldOptions.columns=3\n    //% tx.fieldOptions.tooltips=\"false\"\n    //% rx.fieldEditor=\"gridpicker\" rx.fieldOptions.columns=3\n    //% rx.fieldOptions.tooltips=\"false\"\n    //% blockGap=8 inlineInputMode=inline\n    //% group=\"Configuration\"\n    export function redirect(tx: DigitalInOutPin, rx: DigitalInOutPin, rate: BaudRate) {\n        const ser = device();\n        if (ser)\n            ser.serialDevice.redirect(tx, rx, rate);\n    }\n}\n","serial.ts":"/**\n * Reading and writing data over a serial connection.\n */\n//% weight=2 color=#002050 icon=\"\\uf287\"\n//% advanced=true blockGap=8\n//% groups='[\"Write\", \"Read\", \"Events\", \"Configuration\"]'\nnamespace serial {\n    export let NEW_LINE = \"\\r\\n\"; // \\r require or Putty really unhappy on windows\n    export let NEW_LINE_DELIMITER: Delimiters = Delimiters.NewLine;\n\n    export class Serial {\n        serialDevice: SerialDevice;\n        decoder: UTF8Decoder;\n        constructor(serialDevice: SerialDevice) {\n            this.serialDevice = serialDevice;\n            this.decoder = new UTF8Decoder();\n        }\n\n        readString(): string {\n            const buf = this.serialDevice.readBuffer();\n            this.decoder.add(buf);\n            return this.decoder.decode();\n        }\n\n        readLine(timeOut?: number): string {\n            return this.readUntil(NEW_LINE_DELIMITER, timeOut);\n        }\n\n        readUntil(delimiter: Delimiters, timeOut?: number): string {\n            const start = control.millis();\n            do {\n                const s = this.decoder.decodeUntil(delimiter);\n                if (s !== undefined)\n                    return s;\n                const b = this.serialDevice.readBuffer()\n                this.decoder.add(b);\n                pause(1);\n            }\n            while (timeOut === undefined || (control.millis() - start < timeOut));\n            // giving up\n            return \"\";\n        }\n\n        writeString(text: string) {\n            if (!text) return;\n            const buf = control.createBufferFromUTF8(text);\n            this.serialDevice.writeBuffer(buf);\n        }\n\n        writeLine(text: string) {\n            this.writeString(text);\n            this.writeString(serial.NEW_LINE);\n        }\n    }\n\n    /**\n    * Read the buffered received data as a string\n    */\n    //% help=serial/read-string\n    //% blockId=serial_read_string block=\"serial|read string\"\n    //% weight=18\n    //% group=\"Read\"\n    export function readString(): string {\n        const d = device();\n        return d ? d.readString() : \"\";\n    }\n\n    /**\n     * Read a line of text from the serial port.\n     */\n    //% help=serial/read-line\n    //% blockId=serial_read_line block=\"serial|read line\"\n    //% weight=20 blockGap=8\n    //% group=\"Read\"\n    export function readLine(): string {\n        const d = device();\n        return d ? d.readLine() : \"\";\n    }\n\n    /**\n     * Read a line of text from the serial port and return the buffer when the delimiter is met.\n     * @param delimiter text delimiter that separates each text chunk\n     */\n    //% help=serial/read-until\n    //% blockId=serial_read_until block=\"serial|read until %delimiter=serial_delimiter_conv\"\n    //% weight=19\n    //% group=\"Read\"    \n    export function readUntil(delimiter: Delimiters, timeOut?: number): string {\n        const d = device();\n        return d ? d.readUntil(delimiter, timeOut) : \"\";\n    }\n\n    /**\n     * Write some text to the serial port.\n     */\n    //% help=serial/write-string\n    //% weight=87\n    //% blockId=serial_writestring block=\"serial|write string %text\"\n    //% group=\"Write\"\n    export function writeString(text: string) {\n        const d = device();\n        if (d) d.writeString(text);\n    }\n\n    /**\n     * Write a line of text to the serial port.\n     * @param value to send over serial\n     */\n    //% weight=90\n    //% help=serial/write-line blockGap=8\n    //% blockId=serial_writeline block=\"serial|write line %text\"\n    //% group=\"Write\"\n    export function writeLine(text: string): void {\n        const d = device();\n        if (d) d.writeLine(text);\n    }\n\n    /**\n     * Write a number to the serial port.\n     */\n    //% help=serial/write-number\n    //% weight=89 blockGap=8\n    //% blockId=serial_writenumber block=\"serial|write number %value\"\n    //% group=\"Write\"\n    export function writeNumber(value: number): void {\n        writeString(value.toString());\n    }\n\n    /**\n     * Write a name:value pair as a line of text to the serial port.\n     * @param name name of the value stream, eg: \"x\"\n     * @param value to write\n     */\n    //% weight=88 blockGap=8\n    //% help=serial/write-value\n    //% blockId=serial_writevalue block=\"serial|write value %name|= %value\"\n    //% group=\"Write\"\n    export function writeValue(name: string, value: number): void {\n        if (name) {\n            writeString(name);\n            writeString(\":\");\n        }\n        writeNumber(value);\n        writeString(NEW_LINE);\n    }\n\n    /**\n    * Sets the size of the RX buffer in bytes\n    */\n    //% help=serial/set-rx-buffer-size\n    //% blockId=serialsetrxbuffersize block=\"serial set rx buffer size to $size\"\n    //% weight=10\n    //% group=\"Configuration\"\n    export function setRxBufferSize(size: number) {\n        const ser = device();\n        if (ser)\n            ser.serialDevice.setRxBufferSize(size);\n    }\n\n    /**\n    * Sets the size of the TX buffer in bytes\n    */\n    //% help=serial/set-tx-buffer-size\n    //% blockId=serialsettxbuffersize block=\"serial set tx buffer size to $size\"\n    //% weight=9\n    //% group=\"Configuration\"\n    export function setTxBufferSize(size: number) {\n        const ser = device();\n        if (ser)\n            ser.serialDevice.setTxBufferSize(size);\n    }\n\n    /**\n    * Reads a single byte from the serial receive buffer. Negative if error, 0 if no data.\n    */\n    //% Group=\"Read\"\n    export function read(): number {\n        const ser = device();\n        if (ser)\n            return ser.serialDevice.read();\n        else return DAL.DEVICE_NOT_SUPPORTED;\n    }\n\n    /**\n    * Read the buffered received data as a buffer\n    */\n    //% help=serial/read-buffer\n    //% blockId=serial_read_buffer block=\"serial|read buffer\"\n    //% weight=17\n    //% group=\"Read\"\n    export function readBuffer(): Buffer {\n        const ser = device();\n        if (ser)\n            return ser.serialDevice.readBuffer();\n        else\n            return control.createBuffer(0);\n    }\n\n\n    /**\n    * Send a buffer across the serial connection.\n    */\n    //% help=serial/write-buffer weight=6\n    //% blockId=serial_writebuffer block=\"serial|write buffer %buffer\"\n    //% group=\"Write\"\n    export function writeBuffer(buffer: Buffer) {\n        const ser = device();\n        if (ser)\n            ser.serialDevice.writeBuffer(buffer);\n    }\n\n    /**\n    Set the baud rate of the serial port\n    */\n    //% weight=10\n    //% blockId=serial_setbaudrate block=\"serial|set baud rate %rate\"\n    //% blockGap=8 inlineInputMode=inline\n    //% help=serial/set-baud-rate\n    //% group=\"Configuration\"\n    export function setBaudRate(rate: BaudRate) {\n        const ser = device();\n        if (ser)\n            ser.serialDevice.setBaudRate(rate);\n    }\n\n    /**\n      Send console messages through the TX, RX pins\n      **/\n    //% blockId=serialsendtoconsole block=\"serial attach to console\"\n    //% group=\"Configuration\"\n    //% help=serial/attach-to-console\n    export function attachToConsole() {\n        console.addListener(logListener)\n    }\n\n    function logListener(priority: ConsolePriority, text: string) {\n        switch (priority) {\n            case ConsolePriority.Debug: writeString(\"dbg> \"); break;\n            case ConsolePriority.Error: writeString(\"err> \"); break;\n            case ConsolePriority.Warning: writeString(\"wrn> \"); break;\n        }\n        writeLine(text);\n    }\n\n\n    /**\n    * Registers code when serial events happen\n    **/\n    //% weight=9\n    //% help=serial/on-event\n    //% blockId=serial_onevent block=\"serial on %event\"\n    //% blockGap=8\n    //% group=\"Events\"\n    export function onEvent(event: SerialEvent, handler: () => void) {\n        const ser = device();\n        if (ser)\n            ser.serialDevice.onEvent(event, handler);\n    }\n\n    /**\n    * Registers code when a delimiter is received\n    **/\n    //% weight=10\n    //% help=serial/on-delimiter-received\n    //% blockId=serial_ondelimiter block=\"serial on delimiter $delimiter received\"\n    //% blockGap=8\n    //% group=\"Events\"\n    export function onDelimiterReceived(delimiter: Delimiters, handler: () => void) {\n        const ser = device();\n        if (ser)\n            ser.serialDevice.onDelimiterReceived(delimiter, handler);\n    }\n\n    /**\n     * Return the corresponding delimiter string\n     */\n    //% blockId=\"serial_delimiter_conv\" block=\"%del\"\n    //% weight=1 blockHidden=true hidden=true\n    export function delimiters(del: Delimiters): string {\n        return String.fromCharCode(del as number);\n    }\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace serial {\n\n    /**\n     * Opens a Serial communication driver\n     */\n    //% shim=serial::internalCreateSerialDevice\n    function internalCreateSerialDevice(tx: DigitalInOutPin, rx: DigitalInOutPin, id: int32): SerialDevice;\n}\n\n\ndeclare interface SerialDevice {\n    /**\n     */\n    //% shim=SerialDeviceMethods::redirect\n    redirect(tx: DigitalInOutPin, rx: DigitalInOutPin, rate: BaudRate): void;\n}\n\n\ndeclare interface SerialDevice {\n    /**\n     * Sets the size of the RX buffer in bytes\n     */\n    //% shim=SerialDeviceMethods::setRxBufferSize\n    setRxBufferSize(size: uint8): void;\n\n    /**\n     * Sets the size of the TX buffer in bytes\n     */\n    //% shim=SerialDeviceMethods::setTxBufferSize\n    setTxBufferSize(size: uint8): void;\n\n    /**\n    Set the baud rate of the serial port\n     */\n    //% shim=SerialDeviceMethods::setBaudRate\n    setBaudRate(rate: BaudRate): void;\n\n    /**\n     * Reads a single byte from the serial receive buffer. Negative if error, 0 if no data.\n     */\n    //% shim=SerialDeviceMethods::read\n    read(): int32;\n\n    /**\n     * Read the buffered received data as a buffer\n     */\n    //% shim=SerialDeviceMethods::readBuffer\n    readBuffer(): Buffer;\n\n    /**\n     * Send a buffer across the serial connection.\n     */\n    //% shim=SerialDeviceMethods::writeBuffer\n    writeBuffer(buffer: Buffer): void;\n\n    /**\n     * Register code when a serial event occurs\n     */\n    //% shim=SerialDeviceMethods::onEvent\n    onEvent(event: SerialEvent, handler: () => void): void;\n\n    /**\n     * Registers code when a delimiter is received\n     **/\n    //% shim=SerialDeviceMethods::onDelimiterReceived\n    onDelimiterReceived(delimiter: Delimiters, handler: () => void): void;\n}\n\n// Auto-generated. Do not edit. Really.\n","test.ts":"for(let i = 0; i < 10; ++i) {\n    serial.writeLine((++i).toString())\n}"},"serial---linux":{"enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum BaudRate {\n    //% block=115200\n    BaudRate115200 = 115200,\n    //% block=57600\n    BaudRate57600 = 57600,\n    //% block=38400\n    BaudRate38400 = 38400,\n    //% block=31250\n    BaudRate31250 = 31250,\n    //% block=28800\n    BaudRate28800 = 28800,\n    //% block=19200\n    BaudRate19200 = 19200,\n    //% block=14400\n    BaudRate14400 = 14400,\n    //% block=9600\n    BaudRate9600 = 9600,\n    //% block=4800\n    BaudRate4800 = 4800,\n    //% block=2400\n    BaudRate2400 = 2400,\n    //% block=1200\n    BaudRate1200 = 1200,\n    //% block=300\n    BaudRate300 = 300,\n    }\n\n\n    declare const enum SerialEvent {\n    //% block=\"data received\"\n    DataReceived = 4,  // CODAL_SERIAL_EVT_DATA_RECEIVED\n    //% block=\"rx buffer full\"\n    RxBufferFull = 3,  // CODAL_SERIAL_EVT_RX_FULL\n    }\n\n\n    declare const enum Delimiters {\n    //% block=\"new line (\\n)\"\n    NewLine = 10,\n    //% block=\",\"\n    Comma = 44,\n    //% block=\"$\"\n    Dollar = 36,\n    //% block=\":\"\n    Colon = 58,\n    //% block=\".\"\n    Fullstop = 46,\n    //% block=\"#\"\n    Hash = 35,\n    //% block=\"carriage return (\\r)\"\n    CarriageReturn = 13,\n    //% block=\"space\"\n    Space = 32,\n    //% block=\"tab (\\t)\"\n    Tab = 9,\n    //% block=\"|\"\n    Pipe = 124,\n    //% block=\";\"\n    SemiColon = 59,\n    }\n\n// Auto-generated. Do not edit. Really.\n","pxt.json":"{\n    \"name\": \"serial---linux\",\n    \"description\": \"UART communication\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"serial-target.h\",\n        \"serial-common.h\",\n        \"serial-target.cpp\",\n        \"serial-common.cpp\",\n        \"serial-target.ts\",\n        \"serial.ts\",\n        \"enums.d.ts\",\n        \"shims.d.ts\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true\n}\n","serial-common.cpp":"#include \"pxt.h\"\n#include \"serial-target.h\"\n\nnamespace SerialDeviceMethods {\n/**\n * Sets the size of the RX buffer in bytes\n */\n//%\nvoid setRxBufferSize(SerialDevice device, uint8_t size) {\n    device->setRxBufferSize(size);\n}\n\n/**\n * Sets the size of the TX buffer in bytes\n */\n//%\nvoid setTxBufferSize(SerialDevice device, uint8_t size) {\n    device->setTxBufferSize(size);\n}\n\n/**\nSet the baud rate of the serial port\n*/\n//%\nvoid setBaudRate(SerialDevice device, BaudRate rate) {\n    device->setBaudRate((int)rate);\n}\n\n/**\n * Reads a single byte from the serial receive buffer. Negative if error, 0 if no data.\n */\n//%\nint read(SerialDevice device) {\n    return device->read();\n}\n\n/**\n * Read the buffered received data as a buffer\n */\n//%\nBuffer readBuffer(SerialDevice device) {\n    return device->readBuffer();\n}\n\n/**\n * Send a buffer across the serial connection.\n */\n//%\nvoid writeBuffer(SerialDevice device, Buffer buffer) {\n    device->writeBuffer(buffer);\n}\n\n/**\n * Register code when a serial event occurs\n */\n//%\nvoid onEvent(SerialDevice device, SerialEvent event, Action handler) {\n    device->onEvent(event, handler);\n}\n\n/**\n * Registers code when a delimiter is received\n **/\n//%\nvoid onDelimiterReceived(SerialDevice device, Delimiters delimiter, Action handler) {\n    device->onDelimiterReceived(delimiter, handler);\n}\n} // namespace SerialDeviceMethods\n","serial-common.h":"#pragma once\n#include \"pxt.h\"\n#include \"serial-target.h\"\n\nenum class BaudRate {\n  //% block=115200\n  BaudRate115200 = 115200,\n  //% block=57600\n  BaudRate57600 = 57600,\n  //% block=38400\n  BaudRate38400 = 38400,\n  //% block=31250\n  BaudRate31250 = 31250,\n  //% block=28800\n  BaudRate28800 = 28800,\n  //% block=19200\n  BaudRate19200 = 19200,\n  //% block=14400\n  BaudRate14400 = 14400,\n  //% block=9600\n  BaudRate9600 = 9600,\n  //% block=4800\n  BaudRate4800 = 4800,\n  //% block=2400\n  BaudRate2400 = 2400,\n  //% block=1200\n  BaudRate1200 = 1200,\n  //% block=300\n  BaudRate300 = 300\n};\n\nenum class SerialEvent {\n    //% block=\"data received\"\n    DataReceived = CODAL_SERIAL_EVT_DATA_RECEIVED,\n    //% block=\"rx buffer full\"\n    RxBufferFull = CODAL_SERIAL_EVT_RX_FULL\n};\n\nenum class Delimiters {\n    //% block=\"new line (\\n)\"\n    NewLine = 10,\n    //% block=\",\"\n    Comma = 44,\n    //% block=\"$\"\n    Dollar = 36,\n    //% block=\":\"\n    Colon = 58,\n    //% block=\".\"\n    Fullstop = 46,\n    //% block=\"#\"\n    Hash = 35,\n    //% block=\"carriage return (\\r)\"\n    CarriageReturn = 13,\n    //% block=\"space\"\n    Space = 32,\n    //% block=\"tab (\\t)\"\n    Tab = 9,\n    //% block=\"|\"\n    Pipe = 124,\n    //% block=\";\"\n    SemiColon = 59,\n};\n\n","serial-target.cpp":"#include \"pxt.h\"\n#include \"serial-common.h\"\n\n#include <string.h>\n#include <unistd.h>\n#include <fcntl.h>\n#include <stdint.h>\n#include <sys/signal.h>\n#include <sys/types.h>\n#include <termios.h>\n#include <errno.h>\n\n#ifndef SERIAL_DEVICE\n#define SERIAL_DEVICE \"/dev/ttyS0\"\n#endif\n\nnamespace serial {\n/**\n * Opens a Serial communication driver\n */\n//%\nSerialDevice internalCreateSerialDevice(int id) {\n    return new LinuxSerialDevice(id);\n}\n\nstruct SerialSpeed {\n    int code;\n    int speed;\n};\n\nstatic const SerialSpeed serialSpeeds[] = {\n    {B50, 50},           {B75, 75},           {B110, 110},         {B134, 134},\n    {B150, 150},         {B200, 200},         {B300, 300},         {B600, 600},\n    {B1200, 1200},       {B1800, 1800},       {B2400, 2400},       {B4800, 4800},\n    {B9600, 9600},       {B19200, 19200},     {B38400, 38400},     {B57600, 57600},\n    {B115200, 115200},   {B230400, 230400},   {B460800, 460800},   {B500000, 500000},\n    {B576000, 576000},   {B921600, 921600},   {B1000000, 1000000}, {B1152000, 1152000},\n    {B1500000, 1500000}, {B2000000, 2000000}, {B2500000, 2500000}, {B3000000, 3000000},\n    {B3500000, 3500000}, {B4000000, 4000000}};\n\nvoid LinuxSerialDevice::init() {\n    auto serialDev = getConfigString(\"SERIAL_DEVICE\");\n    if (!serialDev) {\n        char buf[40];\n        int fd = open(\"/proc/device-tree/model\", O_RDONLY);\n        if (fd >= 0) {\n            int len = ::read(fd, buf, sizeof(buf) - 1);\n            DMESG(\"device model: %s\", buf);\n            if (len > 0) {\n                buf[len] = 0;\n                if (strstr(buf, \"Raspberry Pi\")) {\n                    if (strstr(buf, \"Raspberry Pi 3 Model\") || strstr(buf, \"Raspberry Pi Zero W\"))\n                        serialDev = \"/dev/ttyS0\";\n                    else\n                        serialDev = \"/dev/ttyAMA0\";\n                }\n            }\n            close(fd);\n        }\n    }\n\n    if (!serialDev)\n        serialDev = SERIAL_DEVICE;\n\n    DMESG(\"serial device: %s\", serialDev);\n\n    fd = open(serialDev, O_RDWR | O_NOCTTY);\n    if (fd < 0)\n        target_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n\n    setRxBufferSize(128);\n    setBaudRate(115200);\n\n    pthread_t pid;\n    pthread_create(&pid, NULL, &LinuxSerialDevice::readLoop, this);\n    pthread_detach(pid);\n}\n\nvoid *LinuxSerialDevice::readLoop(void *th) {\n    ((LinuxSerialDevice *)th)->readLoopInner();\n    return NULL;\n}\n\nvoid LinuxSerialDevice::readLoopInner() {\n    uint8_t buf[128];\n    while (true) {\n        pthread_mutex_lock(&lock);\n        int left = buffersz - bufferedSize();\n        pthread_mutex_unlock(&lock);\n        if (left == 0) {\n            raiseEvent(id, CODAL_SERIAL_EVT_RX_FULL);\n            sleep_core_us(20 * 1000);\n            continue;\n        }\n        if (left > (int)sizeof(buf))\n            left = sizeof(buf);\n        int r = ::read(fd, buf, left);\n        if (r <= 0)\n            target_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n\n        pthread_mutex_lock(&lock);\n        int chunk = buffersz - writep;\n        if (r < chunk)\n            chunk = r;\n        memcpy(buffer + writep, buf, chunk);\n        writep += chunk;\n        if (writep == buffersz) {\n            writep = 0;\n            int r2 = r - chunk;\n            if (r2) {\n                memcpy(buffer, buf + chunk, r2);\n                writep += r2;\n            }\n        }\n        pthread_mutex_unlock(&lock);\n\n        raiseEvent(id, CODAL_SERIAL_EVT_DATA_RECEIVED);\n\n        if (delim != -1)\n            for (int i = 0; i < r; ++i)\n                if (buf[i] == delim)\n                    raiseEvent(id, CODAL_SERIAL_EVT_DELIM_MATCH);\n    }\n}\n\nvoid LinuxSerialDevice::setBaudRate(int rate) {\n    struct termios tio;\n    memset(&tio, 0, sizeof(tio));\n    if (tcgetattr(fd, &tio) != 0) {\n        target_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n        return;\n    }\n\n    int speedCode = B115200;\n    for (int i = sizeof(serialSpeeds) / sizeof(serialSpeeds[0]); i >= 0; i--) {\n        if (serialSpeeds[i].speed <= rate) {\n            speedCode = serialSpeeds[i].code;\n            DMESG(\"set serial speed: %d->%d\", rate, serialSpeeds[i].speed);\n            break;\n        }\n    }\n\n    cfmakeraw(&tio);\n    cfsetispeed(&tio, speedCode);\n    cfsetospeed(&tio, speedCode);\n\n    tio.c_cflag |= CLOCAL | CREAD;\n    tio.c_cflag &= ~(PARENB | CSTOPB | CSIZE);\n    tio.c_cflag |= CS8;\n    tio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);\n    tio.c_oflag &= ~OPOST;\n\n    tio.c_cc[VMIN] = 1;  // read blocks\n    tio.c_cc[VTIME] = 0; // no intra-character timeout\n\n    if (tcsetattr(fd, TCSANOW, &tio) != 0) {\n        target_panic(PANIC_CODAL_HARDWARE_CONFIGURATION_ERROR);\n        return;\n    }\n}\n\nvoid LinuxSerialDevice::setRxBufferSize(unsigned size) {\n    pthread_mutex_lock(&lock);\n    auto tmp = malloc(size);\n    if (buffer) {\n        auto bsz = bufferedSize();\n        if (bsz > (int)size)\n            bsz = size;\n        readBuf(tmp, bsz);\n        readp = 0;\n        writep = bsz;\n        free(buffer);\n    }\n    buffer = (uint8_t *)tmp;\n    buffersz = size;\n    pthread_mutex_unlock(&lock);\n}\n\nint LinuxSerialDevice::read() {\n    pthread_mutex_lock(&lock);\n    uint8_t c;\n    int r = readBuf(&c, 1);\n    pthread_mutex_unlock(&lock);\n    if (r)\n        return c;\n    return -1;\n}\n\nBuffer LinuxSerialDevice::readBuffer() {\n    pthread_mutex_lock(&lock);\n    int sz = bufferedSize();\n    auto r = mkBuffer(NULL, sz);\n    registerGCObj(r);\n    int sz2 = readBuf(r->data, sz);\n    unregisterGCObj(r);\n    if (sz != sz2)\n        target_panic(999);\n    pthread_mutex_unlock(&lock);\n    return r;\n}\n\nvoid LinuxSerialDevice::writeBuffer(Buffer buffer) {\n    if (NULL == buffer)\n        return;\n    auto p = buffer->data;\n    auto len = buffer->length;\n    while (len) {\n        int r = write(fd, p, len);\n        if (r >= 0) {\n            len -= r;\n            p += r;\n        } else {\n            DMESG(\"serial write error: %d / %d\", r, errno);\n            break;\n        }\n    }\n}\n\nint LinuxSerialDevice::readBuf(void *buf, int sz) {\n    int amount = bufferedSize();\n    if (amount < sz)\n        sz = amount;\n    if (sz > 0) {\n        int chunk = buffersz - readp;\n        if (chunk > sz)\n            chunk = sz;\n\n        memcpy(buf, buffer + readp, chunk);\n        readp += chunk;\n        if (readp == buffersz)\n            readp = 0;\n        buf = (uint8_t *)buf + chunk;\n\n        if (sz - chunk > 0) {\n            memcpy(buf, buffer + readp, sz - chunk);\n            readp += chunk;\n        }\n    }\n    return sz;\n}\n\n} // namespace serial\n","serial-target.h":"#pragma once\n#include \"pxt.h\"\n\n#include <pthread.h>\n\n#define CODAL_SERIAL_EVT_DELIM_MATCH      1\n#define CODAL_SERIAL_EVT_HEAD_MATCH       2\n#define CODAL_SERIAL_EVT_RX_FULL          3\n#define CODAL_SERIAL_EVT_DATA_RECEIVED    4\n\nenum class SerialEvent;\nenum class BaudRate;\nenum class Delimiters;\n\nnamespace serial {\n\nclass LinuxSerialDevice {\n    void init();\n    uint16_t id;\n    uint8_t *buffer;\n    int delim;\n    unsigned readp, writep, buffersz;\n    pthread_mutex_t lock;\n    int fd;\n\n  public:\n    LinuxSerialDevice *next;\n\n    LinuxSerialDevice(uint16_t id) : id(id) {\n        readp = writep = buffersz = 0;\n        buffer = NULL;\n        next = NULL;\n        delim = -1;\n        fd = -1;\n        pthread_mutex_init(&lock, NULL);\n        init();\n    }\n\n    void setBaudRate(int rate);\n    void setRxBufferSize(unsigned size);\n\n    void setTxBufferSize(unsigned size) {}\n\n    int read();\n    Buffer readBuffer();\n    void writeBuffer(Buffer buffer);\n\n    void onEvent(SerialEvent event, Action handler) { registerWithDal(id, (int)event, handler); }\n\n    void onDelimiterReceived(Delimiters delimiter, Action handler) {\n        registerWithDal(id, CODAL_SERIAL_EVT_DELIM_MATCH, handler);\n        delim = (int)delimiter;\n    }\n\n  private:\n    int bufferedSize() {\n        int amount = writep - readp;\n        if (amount < 0)\n            amount += buffersz;\n        return amount;\n    }\n\n    int readBuf(void *buf, int sz);\n\n    static void *readLoop(void*);\n    void readLoopInner();\n};\n\ntypedef LinuxSerialDevice *SerialDevice;\n\n} // namespace serial\n","serial-target.ts":"namespace serial {\n    let _device: Serial;\n    export function device(): Serial {\n        if (!_device) {\n            _device = new Serial(serial.internalCreateSerialDevice(3000));\n        }\n        return _device;\n    }\n}\n","serial.ts":"/**\n * Reading and writing data over a serial connection.\n */\n//% weight=2 color=#002050 icon=\"\\uf287\"\n//% advanced=true blockGap=8\n//% groups='[\"Write\", \"Read\", \"Events\", \"Configuration\"]'\nnamespace serial {\n    export let NEW_LINE = \"\\r\\n\"; // \\r require or Putty really unhappy on windows\n    export let NEW_LINE_DELIMITER: Delimiters = Delimiters.NewLine;\n\n    export class Serial {\n        serialDevice: SerialDevice;\n        decoder: UTF8Decoder;\n        constructor(serialDevice: SerialDevice) {\n            this.serialDevice = serialDevice;\n            this.decoder = new UTF8Decoder();\n        }\n\n        readString(): string {\n            const buf = this.serialDevice.readBuffer();\n            this.decoder.add(buf);\n            return this.decoder.decode();\n        }\n\n        readLine(timeOut?: number): string {\n            return this.readUntil(NEW_LINE_DELIMITER, timeOut);\n        }\n\n        readUntil(delimiter: Delimiters, timeOut?: number): string {\n            const start = control.millis();\n            do {\n                const s = this.decoder.decodeUntil(delimiter);\n                if (s !== undefined)\n                    return s;\n                const b = this.serialDevice.readBuffer()\n                this.decoder.add(b);\n                pause(1);\n            }\n            while (timeOut === undefined || (control.millis() - start < timeOut));\n            // giving up\n            return \"\";\n        }\n\n        writeString(text: string) {\n            if (!text) return;\n            const buf = control.createBufferFromUTF8(text);\n            this.serialDevice.writeBuffer(buf);\n        }\n\n        writeLine(text: string) {\n            this.writeString(text);\n            this.writeString(serial.NEW_LINE);\n        }\n    }\n\n    /**\n    * Read the buffered received data as a string\n    */\n    //% help=serial/read-string\n    //% blockId=serial_read_string block=\"serial|read string\"\n    //% weight=18\n    //% group=\"Read\"\n    export function readString(): string {\n        const d = device();\n        return d ? d.readString() : \"\";\n    }\n\n    /**\n     * Read a line of text from the serial port.\n     */\n    //% help=serial/read-line\n    //% blockId=serial_read_line block=\"serial|read line\"\n    //% weight=20 blockGap=8\n    //% group=\"Read\"\n    export function readLine(): string {\n        const d = device();\n        return d ? d.readLine() : \"\";\n    }\n\n    /**\n     * Read a line of text from the serial port and return the buffer when the delimiter is met.\n     * @param delimiter text delimiter that separates each text chunk\n     */\n    //% help=serial/read-until\n    //% blockId=serial_read_until block=\"serial|read until %delimiter=serial_delimiter_conv\"\n    //% weight=19\n    //% group=\"Read\"    \n    export function readUntil(delimiter: Delimiters, timeOut?: number): string {\n        const d = device();\n        return d ? d.readUntil(delimiter, timeOut) : \"\";\n    }\n\n    /**\n     * Write some text to the serial port.\n     */\n    //% help=serial/write-string\n    //% weight=87\n    //% blockId=serial_writestring block=\"serial|write string %text\"\n    //% group=\"Write\"\n    export function writeString(text: string) {\n        const d = device();\n        if (d) d.writeString(text);\n    }\n\n    /**\n     * Write a line of text to the serial port.\n     * @param value to send over serial\n     */\n    //% weight=90\n    //% help=serial/write-line blockGap=8\n    //% blockId=serial_writeline block=\"serial|write line %text\"\n    //% group=\"Write\"\n    export function writeLine(text: string): void {\n        const d = device();\n        if (d) d.writeLine(text);\n    }\n\n    /**\n     * Write a number to the serial port.\n     */\n    //% help=serial/write-number\n    //% weight=89 blockGap=8\n    //% blockId=serial_writenumber block=\"serial|write number %value\"\n    //% group=\"Write\"\n    export function writeNumber(value: number): void {\n        writeString(value.toString());\n    }\n\n    /**\n     * Write a name:value pair as a line of text to the serial port.\n     * @param name name of the value stream, eg: \"x\"\n     * @param value to write\n     */\n    //% weight=88 blockGap=8\n    //% help=serial/write-value\n    //% blockId=serial_writevalue block=\"serial|write value %name|= %value\"\n    //% group=\"Write\"\n    export function writeValue(name: string, value: number): void {\n        if (name) {\n            writeString(name);\n            writeString(\":\");\n        }\n        writeNumber(value);\n        writeString(NEW_LINE);\n    }\n\n    /**\n    * Sets the size of the RX buffer in bytes\n    */\n    //% help=serial/set-rx-buffer-size\n    //% blockId=serialsetrxbuffersize block=\"serial set rx buffer size to $size\"\n    //% weight=10\n    //% group=\"Configuration\"\n    export function setRxBufferSize(size: number) {\n        const ser = device();\n        if (ser)\n            ser.serialDevice.setRxBufferSize(size);\n    }\n\n    /**\n    * Sets the size of the TX buffer in bytes\n    */\n    //% help=serial/set-tx-buffer-size\n    //% blockId=serialsettxbuffersize block=\"serial set tx buffer size to $size\"\n    //% weight=9\n    //% group=\"Configuration\"\n    export function setTxBufferSize(size: number) {\n        const ser = device();\n        if (ser)\n            ser.serialDevice.setTxBufferSize(size);\n    }\n\n    /**\n    * Reads a single byte from the serial receive buffer. Negative if error, 0 if no data.\n    */\n    //% Group=\"Read\"\n    export function read(): number {\n        const ser = device();\n        if (ser)\n            return ser.serialDevice.read();\n        else return DAL.DEVICE_NOT_SUPPORTED;\n    }\n\n    /**\n    * Read the buffered received data as a buffer\n    */\n    //% help=serial/read-buffer\n    //% blockId=serial_read_buffer block=\"serial|read buffer\"\n    //% weight=17\n    //% group=\"Read\"\n    export function readBuffer(): Buffer {\n        const ser = device();\n        if (ser)\n            return ser.serialDevice.readBuffer();\n        else\n            return control.createBuffer(0);\n    }\n\n\n    /**\n    * Send a buffer across the serial connection.\n    */\n    //% help=serial/write-buffer weight=6\n    //% blockId=serial_writebuffer block=\"serial|write buffer %buffer\"\n    //% group=\"Write\"\n    export function writeBuffer(buffer: Buffer) {\n        const ser = device();\n        if (ser)\n            ser.serialDevice.writeBuffer(buffer);\n    }\n\n    /**\n    Set the baud rate of the serial port\n    */\n    //% weight=10\n    //% blockId=serial_setbaudrate block=\"serial|set baud rate %rate\"\n    //% blockGap=8 inlineInputMode=inline\n    //% help=serial/set-baud-rate\n    //% group=\"Configuration\"\n    export function setBaudRate(rate: BaudRate) {\n        const ser = device();\n        if (ser)\n            ser.serialDevice.setBaudRate(rate);\n    }\n\n    /**\n      Send console messages through the TX, RX pins\n      **/\n    //% blockId=serialsendtoconsole block=\"serial attach to console\"\n    //% group=\"Configuration\"\n    //% help=serial/attach-to-console\n    export function attachToConsole() {\n        console.addListener(logListener)\n    }\n\n    function logListener(priority: ConsolePriority, text: string) {\n        switch (priority) {\n            case ConsolePriority.Debug: writeString(\"dbg> \"); break;\n            case ConsolePriority.Error: writeString(\"err> \"); break;\n            case ConsolePriority.Warning: writeString(\"wrn> \"); break;\n        }\n        writeLine(text);\n    }\n\n\n    /**\n    * Registers code when serial events happen\n    **/\n    //% weight=9\n    //% help=serial/on-event\n    //% blockId=serial_onevent block=\"serial on %event\"\n    //% blockGap=8\n    //% group=\"Events\"\n    export function onEvent(event: SerialEvent, handler: () => void) {\n        const ser = device();\n        if (ser)\n            ser.serialDevice.onEvent(event, handler);\n    }\n\n    /**\n    * Registers code when a delimiter is received\n    **/\n    //% weight=10\n    //% help=serial/on-delimiter-received\n    //% blockId=serial_ondelimiter block=\"serial on delimiter $delimiter received\"\n    //% blockGap=8\n    //% group=\"Events\"\n    export function onDelimiterReceived(delimiter: Delimiters, handler: () => void) {\n        const ser = device();\n        if (ser)\n            ser.serialDevice.onDelimiterReceived(delimiter, handler);\n    }\n\n    /**\n     * Return the corresponding delimiter string\n     */\n    //% blockId=\"serial_delimiter_conv\" block=\"%del\"\n    //% weight=1 blockHidden=true hidden=true\n    export function delimiters(del: Delimiters): string {\n        return String.fromCharCode(del as number);\n    }\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace serial {\n\n    /**\n     * Opens a Serial communication driver\n     */\n    //% shim=serial::internalCreateSerialDevice\n    function internalCreateSerialDevice(id: int32): SerialDevice;\n}\n\n\ndeclare interface SerialDevice {\n    /**\n     * Sets the size of the RX buffer in bytes\n     */\n    //% shim=SerialDeviceMethods::setRxBufferSize\n    setRxBufferSize(size: uint8): void;\n\n    /**\n     * Sets the size of the TX buffer in bytes\n     */\n    //% shim=SerialDeviceMethods::setTxBufferSize\n    setTxBufferSize(size: uint8): void;\n\n    /**\n    Set the baud rate of the serial port\n     */\n    //% shim=SerialDeviceMethods::setBaudRate\n    setBaudRate(rate: BaudRate): void;\n\n    /**\n     * Reads a single byte from the serial receive buffer. Negative if error, 0 if no data.\n     */\n    //% shim=SerialDeviceMethods::read\n    read(): int32;\n\n    /**\n     * Read the buffered received data as a buffer\n     */\n    //% shim=SerialDeviceMethods::readBuffer\n    readBuffer(): Buffer;\n\n    /**\n     * Send a buffer across the serial connection.\n     */\n    //% shim=SerialDeviceMethods::writeBuffer\n    writeBuffer(buffer: Buffer): void;\n\n    /**\n     * Register code when a serial event occurs\n     */\n    //% shim=SerialDeviceMethods::onEvent\n    onEvent(event: SerialEvent, handler: () => void): void;\n\n    /**\n     * Registers code when a delimiter is received\n     **/\n    //% shim=SerialDeviceMethods::onDelimiterReceived\n    onDelimiterReceived(delimiter: Delimiters, handler: () => void): void;\n}\n\n// Auto-generated. Do not edit. Really.\n","test.ts":"for(let i = 0; i < 10; ++i) {\n    serial.writeLine((++i).toString())\n}"},"servo":{"README.md":"# Servo\n\nA small micro-servo library.","ns.ts":"/**\n * Control micro servos\n */\n//% color=\"#03AA74\" weight=88 icon=\"\\uf021\"\nnamespace servos {\n}","pxt.json":"{\n    \"name\": \"servo\",\n    \"description\": \"A micro-servo library\",\n    \"dependencies\": {\n        \"core\": \"*\",\n        \"edge-connector\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"servo.ts\",\n        \"ns.ts\",\n        \"targetoverrides.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"icon\": \"/static/libs/servo.png\"\n}\n","servo.ts":"/**\n * Control micro servos\n */\n//% color=\"#03AA74\" weight=88 icon=\"\\uf021\" blockGap=8\n//% groups='[\"Positional\", \"Continuous\", \"Configuration\"]'\nnamespace servos {\n    //% fixedInstances\n    export class Servo {\n        private _minAngle: number;\n        private _maxAngle: number;\n        private _stopOnNeutral: boolean;\n        private _angle: number;\n\n        constructor() {\n            this._angle = undefined;\n            this._minAngle = 0;\n            this._maxAngle = 180;\n            this._stopOnNeutral = false;\n        }\n\n        private clampDegrees(degrees: number): number {\n            degrees = degrees | 0;\n            degrees = Math.clamp(this._minAngle, this._maxAngle, degrees);\n            return degrees;\n        }\n\n        /**\n         * Set the servo angle\n         */\n        //% weight=100 help=servos/set-angle\n        //% blockId=servoservosetangle block=\"set %servo angle to %degrees=protractorPicker °\"\n        //% degrees.defl=90\n        //% servo.fieldEditor=\"gridpicker\"\n        //% servo.fieldOptions.width=220\n        //% servo.fieldOptions.columns=2\n        //% blockGap=8\n        //% parts=microservo trackArgs=0\n        //% group=\"Positional\"\n        setAngle(degrees: number) {\n            degrees = this.clampDegrees(degrees);\n            this.internalSetContinuous(false);\n            this._angle = this.internalSetAngle(degrees);\n        }\n\n        get angle() {\n            return this._angle || 90;\n        }\n\n        protected internalSetContinuous(continuous: boolean): void {\n\n        }\n\n        protected internalSetAngle(angle: number): number {\n            return 0;\n        }\n\n        /**\n         * Set the throttle on a continuous servo\n         * @param speed the throttle of the motor from -100% to 100%\n         */\n        //% weight=99 help=servos/run\n        //% blockId=servoservorun block=\"continuous %servo run at %speed=speedPicker \\\\%\"\n        //% servo.fieldEditor=\"gridpicker\"\n        //% servo.fieldOptions.width=220\n        //% servo.fieldOptions.columns=2\n        //% parts=microservo trackArgs=0\n        //% group=\"Continuous\"\n        //% blockGap=8\n        run(speed: number): void {\n            const degrees = this.clampDegrees(Math.map(speed, -100, 100, this._minAngle, this._maxAngle));\n            const neutral = (this.maxAngle - this.minAngle) >> 1;\n            this.internalSetContinuous(true);\n            if (this._stopOnNeutral && degrees == neutral)\n                this.stop();\n            else\n                this._angle = this.internalSetAngle(degrees);\n        }\n\n        /**\n         * Set the pulse width to the servo in microseconds\n         * @param micros the width of the pulse in microseconds\n         */\n\n        //% weight=10 help=servos/set-pulse\n        //% blockId=servoservosetpulse block=\"set %servo pulse to %micros μs\"\n        //% micros.min=500 micros.max=2500\n        //% micros.defl=1500\n        //% servo.fieldEditor=\"gridpicker\"\n        //% servo.fieldOptions.width=220\n        //% servo.fieldOptions.columns=2\n        //% parts=microservo trackArgs=0\n        //% group=\"Configuration\"\n        //% blockGap=8\n        setPulse(micros: number) {\n            micros = micros | 0;\n            micros = Math.clamp(500, 2500, micros);\n            this.internalSetPulse(micros);\n        }\n\n        protected internalSetPulse(micros: number): void {\n\n        }\n\n        /**\n         * Stop sending commands to the servo so that its rotation will stop at the current position.\n         */\n        // On a normal servo this will stop the servo where it is, rather than return it to neutral position.\n        // It will also not provide any holding force.\n        //% weight=10 help=servos/stop\n        //% blockId=servoservostop block=\"stop %servo\"\n        //% servo.fieldEditor=\"gridpicker\"\n        //% servo.fieldOptions.width=220\n        //% servo.fieldOptions.columns=2\n        //% parts=microservo trackArgs=0\n        //% group=\"Continuous\"\n        //% blockGap=8\n        stop() {\n            if (this._angle !== undefined)\n                this.internalStop();\n        }\n\n        /**\n         * Gets the minimum angle for the servo\n         */\n        public get minAngle() {\n            return this._minAngle;\n        }\n\n        /**\n         * Gets the maximum angle for the servo\n         */\n        public get maxAngle() {\n            return this._maxAngle;\n        }\n\n        /**\n         * Set the possible rotation range angles for the servo between 0 and 180\n         * @param minAngle the minimum angle from 0 to 90\n         * @param maxAngle the maximum angle from 90 to 180\n         */\n        //% help=servos/set-range\n        //% blockId=servosetrange block=\"set %servo range from %minAngle to %maxAngle\"\n        //% minAngle.min=0 minAngle.max=90\n        //% maxAngle.min=90 maxAngle.max=180 maxAngle.defl=180\n        //% servo.fieldEditor=\"gridpicker\"\n        //% servo.fieldOptions.width=220\n        //% servo.fieldOptions.columns=2\n        //% parts=microservo trackArgs=0\n        //% group=\"Configuration\"\n        //% blockGap=8\n        public setRange(minAngle: number, maxAngle: number) {\n            this._minAngle = Math.max(0, Math.min(90, minAngle | 0));\n            this._maxAngle = Math.max(90, Math.min(180, maxAngle | 0));\n        }\n\n        /**\n         * Set a servo stop mode so it will stop when the rotation angle is in the neutral position, 90 degrees.\n         * @param on true to enable this mode\n         */\n        //% help=servos/set-stop-on-neutral\n        //% blockId=servostoponneutral block=\"set %servo stop on neutral %enabled\"\n        //% enabled.shadow=toggleOnOff\n        //% group=\"Configuration\"\n        //% blockGap=8\n        //% servo.fieldEditor=\"gridpicker\"\n        //% servo.fieldOptions.width=220\n        //% servo.fieldOptions.columns=2\n        public setStopOnNeutral(enabled: boolean) {\n            this._stopOnNeutral = enabled;\n        }\n\n        protected internalStop() { }\n    }\n\n    export class PinServo extends Servo {\n        private _pin: PwmOnlyPin;\n\n        constructor(pin: PwmOnlyPin) {\n            super();\n            this._pin = pin;\n        }\n\n        protected internalSetAngle(angle: number): number {\n            this._pin.servoWrite(angle);\n            return angle;\n        }\n\n        protected internalSetContinuous(continuous: boolean): void {\n            this._pin.servoSetContinuous(continuous);\n        }\n\n        protected internalSetPulse(micros: number): void {\n            this._pin.servoSetPulse(micros);\n        }\n\n        protected internalStop() {\n            this._pin.digitalRead();\n            this._pin.setPull(PinPullMode.PullNone);\n        }\n    }\n}\n","targetoverrides.ts":"namespace servos {\n    //% block=\"servo P0\" fixedInstance whenUsed\n    export const P0 = new servos.PinServo(pins.P0);\n    //% block=\"servo P1\" fixedInstance whenUsed\n    export const P1 = new servos.PinServo(pins.P1);\n    //% block=\"servo P2\" fixedInstance whenUsed\n    export const P2 = new servos.PinServo(pins.P2);\n}"},"settings":{"Flash.h":"#ifndef CODAL_FLASH_H\n#define CODAL_FLASH_H\n\n#include \"CodalDevice.h\"\n\nnamespace codal {\nclass Flash {\n  public:\n    /**\n     * Return page size in bytes at given address (doesn't have to be page-aligned).\n     */\n    virtual int pageSize(uintptr_t address) = 0;\n\n    /**\n     * Erase page at given page-aligned address.\n     */\n    virtual int erasePage(uintptr_t address) = 0;\n\n    /**\n     * Write given number of bytes within one page. Flash has to be erased first.\n     */\n    virtual int writeBytes(uintptr_t dst, const void *src, uint32_t len) = 0;\n\n    /**\n     * Return the total size of flash.\n     */\n    virtual int totalSize();\n};\n\nclass ZFlash : public Flash {\n  public:\n    virtual int pageSize(uintptr_t address);\n    virtual int totalSize();\n    virtual int erasePage(uintptr_t address);\n    virtual int writeBytes(uintptr_t dst, const void *src, uint32_t len);\n};\n\n#define CODAL_FLASH codal::ZFlash\n#define DEVICE_FLASH_ERROR 922\n\n\n} // namespace codal\n\n#endif\n","NRF52Flash.cpp":"#include \"pxt.h\"\n#include \"Flash.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\n#if defined(NRF52_SERIES)\nnamespace codal {\n\n#define waitForLast() while ((NRF_NVMC->READY & NVMC_READY_READY_Msk) == 0);\n\nstatic volatile bool flash_op_complete = false;\n\n#ifdef SOFTDEVICE_PRESENT\n#include \"nrf_sdh_soc.h\"\n#include \"nrf_sdm.h\"\n\nstatic void nvmc_event_handler(uint32_t sys_evt, void *)\n{\n    if (sys_evt == NRF_EVT_FLASH_OPERATION_SUCCESS)\n        flash_op_complete = true;\n}\n\nNRF_SDH_SOC_OBSERVER(nrfflash_soc_observer, 0, nvmc_event_handler, NULL);\n\n#ifndef MICROBIT_CODAL\nbool ble_running()\n{\n    uint8_t t = 0;\n    sd_softdevice_is_enabled(&t);\n    return t==1;\n}\n#endif\n\n#endif\n\n\nstatic inline uint32_t NRF_PAGE_SIZE() {\n#if defined(FICR_INFO_CODEPAGESIZE_CODEPAGESIZE_Msk)\n    return NRF_FICR->INFO.CODEPAGESIZE;\n#else\n    return NRF_FICR->CODEPAGESIZE;\n#endif\n}\n\nint ZFlash::pageSize(uintptr_t address) {\n    (void)address;\n#if defined(FICR_INFO_CODEPAGESIZE_CODEPAGESIZE_Msk)\n    return NRF_FICR->INFO.CODEPAGESIZE;\n#else\n    return NRF_FICR->CODEPAGESIZE;\n#endif\n}\n\nint ZFlash::totalSize() {\n#if defined(FICR_INFO_CODEPAGESIZE_CODEPAGESIZE_Msk)\n    return NRF_FICR->INFO.CODESIZE * pageSize(0);\n#else\n    return NRF_FICR->CODESIZE * pageSize(0);\n#endif\n}\n\nint ZFlash::erasePage(uintptr_t address) {\n    if (address & (pageSize(address) - 1))\n        target_panic(DEVICE_FLASH_ERROR);\n\n#ifdef SOFTDEVICE_PRESENT\n    if (ble_running())\n    {\n        flash_op_complete = false;\n        while(1)\n        {\n            if ( sd_flash_page_erase(((uint32_t)address)/NRF_PAGE_SIZE()) == NRF_SUCCESS)\n                break;\n\n            system_timer_wait_ms(10);\n        }\n\n        while(!flash_op_complete);\n    }\n    else\n#endif\n    {\n        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een;\n        waitForLast();\n        NRF_NVMC->ERASEPAGE = address;\n        waitForLast();\n        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;\n        waitForLast();\n    }\n    \n    return 0;\n}\n\nint ZFlash::writeBytes(uintptr_t dst, const void *src, uint32_t len) {\n    LOG(\"WR flash at %p len=%d\", (void *)dst, len);\n\n    if ((dst & 3) || ((uintptr_t)src & 3) || (len & 3))\n        return -1;\n\n    for (unsigned i = 0; i < len; ++i)\n        if (((uint8_t *)dst)[i] != 0xff && ((uint8_t *)src)[i] != 0xff)\n            return -3;\n\n    \n    volatile uint32_t *sp = (uint32_t *)src;\n    volatile uint32_t *dp = (uint32_t *)dst;\n\n    len >>= 2;\n\n#ifdef SOFTDEVICE_PRESENT\n    if (ble_running())\n    {\n        flash_op_complete = false;\n\n        while(1)\n        {\n            if (sd_flash_write((uint32_t *)dp, (uint32_t *)sp, len) == NRF_SUCCESS)\n                break;\n\n            system_timer_wait_ms(10);\n        }\n\n        while(!flash_op_complete);\n    }\n    else\n#endif\n    {\n        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;\n        waitForLast();\n\n        while (len-- > 0) {\n            uint32_t v = *sp++;\n            if (v != 0xffffffff) {\n                *dp++ = v;\n                waitForLast();\n            } else {\n                dp++;\n            }\n        }\n        \n        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;\n        waitForLast();\n    }\n\n    LOG(\"WR flash OK\");\n\n    return 0;\n}\n} // namespace codal\n#endif\n","RAFFS.cpp":"#include \"RAFFS.h\"\n#include \"CodalDmesg.h\"\n#include \"NotifyEvents.h\"\n#include \"MessageBus.h\"\n#include \"Timer.h\"\n#include \"pxtbase.h\"\n\n#include <stddef.h>\n\n#define RAFFS_MAGIC 0x7776e0da\n#define M1 0xffffffffU\n\n#define CHECK\n//#undef CHECK\n\nusing namespace codal;\n\n#define oops() target_panic(DEVICE_FLASH_ERROR)\n\n#define OFF2(v, basePtr) (uint32_t)((uint8_t *)v - (uint8_t *)basePtr)\n#define OFF(v) OFF2(v, basePtr)\n\n#define REAL_OFF(dst) (OFF(dst) <= OFF2(dst, altBasePtr()) ? OFF(dst) : OFF2(dst, altBasePtr()))\n\n#undef NOLOG\n#define NOLOG(...) ((void)0)\n#ifndef RAFFS_TEST\n#define LOG DMESG\n#define LOGV NOLOG\n#endif\n\n#define LOGVV NOLOG\n\n#if 0\n#undef LOGV\n#define LOGV DMESG\n#endif\n\n#if 0\n#undef LOGVV\n#define LOGVV DMESG\n#endif\n\nusing namespace pxt::raffs;\n\nstatic uint16_t raffs_unlocked_event;\n\nstruct FSHeader {\n    uint32_t magic;\n    uint32_t bytes;\n    uint32_t numgc;\n    uint32_t reserved;\n};\n\nstatic uint16_t fnhash(const char *fn) {\n    uint32_t h = hash_fnv1(fn, strlen(fn));\n    return h ^ (h >> 16);\n}\n\nFS::FS(Flash &flash, uintptr_t baseAddr, uint32_t bytes)\n    : flash(flash), baseAddr(baseAddr), bytes(bytes) {\n    locked = false;\n\n    basePtr = NULL;\n    endPtr = NULL;\n    freeDataPtr = NULL;\n    metaPtr = NULL;\n    readDirPtr = NULL;\n    cachedMeta = NULL;\n    flashBufAddr = 0;\n    blocked = NULL;\n    gcHorizon = -10000000;\n    minGCSpacing = 0;\n\n    if (bytes > 0x20000)\n        oops();\n\n    auto page = flash.pageSize(baseAddr);\n    // baseAddr and bytes needs to page-aligned, and we need even number of pages\n    auto numPages = bytes / page;\n    if ((baseAddr & (page - 1)) || bytes % page || numPages < 2 || (numPages & 1))\n        oops();\n\n    if (!raffs_unlocked_event)\n        raffs_unlocked_event = codal::allocateNotifyEvent();\n}\n\nvoid FS::erasePages(uintptr_t addr, uint32_t len) {\n    auto end = addr + len;\n    auto page = flash.pageSize(addr);\n    if (addr & (page - 1))\n        oops();\n    while (addr < end) {\n        if (flash.pageSize(addr) != page)\n            oops();\n        flash.erasePage(addr);\n#ifdef CHECK\n        for (int i = 0; i < page; ++i)\n            if (((uint8_t *)addr)[i] != 0xff)\n                oops();\n#endif\n        addr += page;\n    }\n}\n\nvoid FS::oopsAndClear() {\n    erasePages(baseAddr, bytes);\n    oops();\n}\n\nvoid FS::flushFlash() {\n    if (flashBufAddr) {\n        int r = flash.writeBytes(flashBufAddr, flashBuf, sizeof(flashBuf));\n        if (r)\n            oopsAndClear();\n#ifdef CHECK\n        for (unsigned i = 0; i < sizeof(flashBuf); ++i)\n            if (flashBuf[i] != 0xff && flashBuf[i] != ((uint8_t *)flashBufAddr)[i])\n                oopsAndClear();\n#endif\n        flashBufAddr = 0;\n    }\n}\n\nvoid FS::writeBytes(void *dst, const void *src, uint32_t size) {\n    LOGVV(\"write %x%s %d %x:%x:%x:%x\", REAL_OFF(dst), OFF(dst) == REAL_OFF(dst) ? \"\" : \"*\", size,\n          ((const uint8_t *)src)[0], ((const uint8_t *)src)[1], ((const uint8_t *)src)[2],\n          ((const uint8_t *)src)[3]);\n\n    while (size > 0) {\n        uint32_t off = (uintptr_t)dst & (sizeof(flashBuf) - 1);\n        uintptr_t newaddr = (uintptr_t)dst - off;\n        if (newaddr != flashBufAddr) {\n            flushFlash();\n            memset(flashBuf, 0xff, sizeof(flashBuf));\n            flashBufAddr = newaddr;\n        }\n\n        unsigned n = sizeof(flashBuf) - off;\n        if (n > size)\n            n = size;\n        memcpy(flashBuf + off, src, n);\n        size -= n;\n        src = (const uint8_t *)src + n;\n        dst = (uint8_t *)dst + n;\n    }\n}\n\n#define IS_VALID(hd) ((hd)->magic == RAFFS_MAGIC && (hd)->bytes == bytes)\n\nvoid FS::format() {\n    cachedMeta = NULL;\n    readDirPtr = NULL;\n    clearBlocked();\n\n    LOG(\"formatting...\");\n\n    FSHeader hd;\n    hd.reserved = M1;\n    hd.numgc = 1;\n\n    // in case the secondary header is valid, copy #gc\n    auto hd2 = (FSHeader *)(baseAddr + bytes / 2);\n    if (IS_VALID(hd2)) {\n        hd.numgc = hd2->numgc + 1;\n    }\n\n    // write the primary header\n    erasePages(baseAddr, bytes / 2);\n    hd.magic = RAFFS_MAGIC;\n    hd.bytes = bytes;\n    writeBytes((void *)baseAddr, &hd, sizeof(hd));\n\n    flushFlash();\n}\n\n#define NUMBLOCKED (int)(sizeof(blocked->fnptrs) / sizeof(uint16_t))\n\nbool FS::checkBlocked(MetaEntry *m) {\n    auto fnptr = m->fnptr;\n    for (auto p = blocked; p; p = p->next) {\n        for (int i = 0; i < NUMBLOCKED; ++i)\n            if (p->fnptrs[i] == fnptr) {\n                if (m->isFirst())\n                    p->fnptrs[i] = 0;\n                return true;\n            }\n    }\n    if (!m->isFirst()) {\n        for (auto p = blocked; p; p = p->next) {\n            for (int i = 0; i < NUMBLOCKED; ++i)\n                if (p->fnptrs[i] == 0) {\n                    p->fnptrs[i] = fnptr;\n                    return false;\n                }\n        }\n        auto p = new BlockedEntries;\n        memset(p, 0, sizeof(*p));\n        p->next = blocked;\n        blocked = p;\n        p->fnptrs[0] = fnptr;\n    }\n    return false;\n}\n\nvoid FS::clearBlocked() {\n    while (blocked) {\n        auto p = blocked;\n        blocked = p->next;\n        delete p;\n    }\n}\n\nbool FS::tryMount() {\n    if (basePtr)\n        return true;\n\n    auto hd0 = (FSHeader *)baseAddr;\n    auto hd1 = (FSHeader *)(baseAddr + bytes / 2);\n\n    auto v0 = IS_VALID(hd0);\n    auto v1 = IS_VALID(hd1);\n\n    if (v0 && v1) {\n        // we account for overflows\n        // they should not occur in normal operation though\n        if (hd0->numgc + 1 == hd1->numgc)\n            v0 = false;\n        else if (hd1->numgc + 1 == hd0->numgc || hd1->numgc < hd0->numgc)\n            v1 = false;\n        else\n            v0 = false;\n    }\n\n    uintptr_t addr;\n\n    if (v0)\n        addr = baseAddr;\n    else if (v1)\n        addr = baseAddr + bytes / 2;\n    else\n        return false;\n\n    basePtr = (uint8_t *)addr;\n    endPtr = (MetaEntry *)(addr + bytes / 2);\n\n    auto p = (uint32_t *)endPtr - 2;\n    while (*p != M1)\n        p -= 2;\n    metaPtr = (MetaEntry *)(p + 2);\n\n    p = (uint32_t *)metaPtr - 1;\n    while (*p == M1)\n        p--;\n    freeDataPtr = (uint8_t *)RAFFS_ROUND(p + 1);\n\n    auto fp = (uint32_t *)freeDataPtr;\n    if (fp[0] != M1 || fp[1] != M1)\n        oopsAndClear();\n\n    LOG(\"mounted, end=%x meta=%x free=%x\", OFF(endPtr), OFF(metaPtr), OFF(freeDataPtr));\n\n    return true;\n}\n\nvoid FS::mount() {\n    // if (basePtr) return;\n    if (tryMount())\n        return;\n    format();\n    if (!tryMount())\n        oopsAndClear();\n}\n\nFS::~FS() {}\n\nint FS::write(const char *keyName, const void *data, uint32_t bytes) {\n    auto isDel = data == NULL && bytes == M1;\n    if (!isDel && !data && bytes)\n        oops();\n\n    if (isDel)\n        LOGV(\"del: %s\", keyName);\n    else\n        LOGV(\"write: %s sz=%d\", keyName, bytes);\n\n    lock();\n    uint32_t szneeded = bytes;\n    auto existing = findMetaEntry(keyName);\n    auto prevBase = basePtr;\n\n    cachedMeta = NULL;\n\n    if (!existing) {\n        if (isDel) {\n            unlock();\n            return -1;\n        }\n        szneeded += strlen(keyName) + 1;\n    }\n\n    if (!tryGC(sizeof(MetaEntry) + RAFFS_ROUND(szneeded))) {\n        unlock();\n        return -1;\n    }\n\n    // if the GC happened, find the relocated meta entry\n    if (prevBase != basePtr)\n        existing = findMetaEntry(keyName);\n\n    MetaEntry newMeta;\n    if (existing) {\n        newMeta.fnhash = existing->fnhash;\n        newMeta.fnptr = existing->fnptr;\n    } else {\n        newMeta.fnhash = fnhash(keyName);\n        newMeta.fnptr = writeData(keyName, strlen(keyName) + 1);\n    }\n    newMeta.dataptr = isDel ? 0 : writeData(data, bytes);\n    newMeta._datasize = bytes;\n    if (existing)\n        newMeta._datasize |= RAFFS_FOLLOWING_MASK;\n    finishWrite();\n\n    writeBytes(--metaPtr, &newMeta, sizeof(newMeta));\n    flushFlash();\n\n    unlock();\n    return 0;\n}\n\nint FS::read(const char *keyName, void *data, uint32_t bytes) {\n    lock();\n    int r = -1;\n    MetaEntry *meta;\n    if (keyName) {\n        cachedMeta = meta = findMetaEntry(keyName);\n    } else {\n        meta = cachedMeta;\n    }\n    if (meta != NULL && meta->dataptr) {\n        r = meta->datasize();\n        if (data) {\n            if (bytes > (unsigned)r)\n                bytes = r;\n            memcpy(data, basePtr + meta->dataptr, bytes);\n        }\n    }\n    unlock();\n    return r;\n}\n\nint FS::remove(const char *keyName) {\n    return write(keyName, NULL, M1);\n}\n\nvoid FS::lock() {\n    while (locked)\n        fiber_wait_for_event(DEVICE_ID_NOTIFY, raffs_unlocked_event);\n    locked = true;\n    mount();\n}\n\nvoid FS::unlock() {\n    if (!locked)\n        oops();\n    flushFlash();\n    locked = false;\n#ifndef RAFFS_TEST\n    Event(DEVICE_ID_NOTIFY, raffs_unlocked_event);\n#endif\n}\n\nMetaEntry *FS::findMetaEntry(const char *filename) {\n    uint16_t h = fnhash(filename);\n    uint16_t buflen = strlen(filename) + 1;\n\n    for (auto p = metaPtr; p < endPtr; p++) {\n        // LOGV(\"check at %x %x %x\", OFF(p),p->fnhash,h);\n        if (p->fnhash == h && memcmp(fnptr(p), filename, buflen) == 0)\n            return p;\n    }\n\n    // LOGV(\"fail\");\n\n    return NULL;\n}\n\nvoid FS::forceGC(filename_filter filter) {\n    lock();\n    tryGC(0x7fff0000, filter);\n    unlock();\n}\n\nbool FS::tryGC(int spaceNeeded, filename_filter filter) {\n    int spaceLeft = (intptr_t)metaPtr - (intptr_t)freeDataPtr;\n\n#ifdef RAFFS_TEST\n    for (auto p = (uint32_t *)freeDataPtr; p < (uint32_t *)metaPtr; p++) {\n        if (*p != M1) {\n            LOG(\"value at %x = %x\", OFF(p), *p);\n            oopsAndClear();\n        }\n    }\n#endif\n\n    if (spaceLeft > spaceNeeded + 32)\n        return true;\n    \n    int now = (int)system_timer_current_time();\n    if (minGCSpacing) {\n        gcHorizon += minGCSpacing;\n        int nextGC = now - minGCSpacing * 2;\n        // LOG(\"now=%d n=%d gch=%d\", now, nextGC, gcHorizon);\n        if (nextGC > gcHorizon)\n            gcHorizon = nextGC;\n        if (gcHorizon > now)\n            target_panic(921);\n    }\n\n    LOG(\"running flash FS GC; needed %d, left %d\", spaceNeeded, spaceLeft);\n\n    readDirPtr = NULL;\n    cachedMeta = NULL;\n\n    auto newBase = (uintptr_t)altBasePtr();\n\n    flushFlash();\n\n    erasePages(newBase, bytes / 2);\n\n    auto metaDst = (MetaEntry *)(newBase + bytes / 2);\n    auto newBaseP = (uint8_t *)newBase;\n    freeDataPtr = newBaseP + sizeof(FSHeader);\n\n    for (int iter = 0; iter < 2; ++iter) {\n        clearBlocked();\n        auto offset = sizeof(FSHeader);\n        for (auto p = metaPtr; p < endPtr; p++) {\n            MetaEntry m = *p;\n            const char *fn = fnptr(&m);\n\n            if (filter && !filter(fn))\n                continue;\n\n            if (checkBlocked(&m) || m.dataptr == 0)\n                continue;\n\n            LOGV(\"GC %s sz=%d @%x\", fn, m.datasize(), m.dataptr);\n            auto fnlen = strlen(fn) + 1;\n            auto sz = fnlen + m.datasize();\n\n            if (iter == 0) {\n                auto fd = freeDataPtr;\n                writeData(fn, fnlen);\n                writeData(basePtr + m.dataptr, m.datasize());\n                if (freeDataPtr - fd != (int)sz)\n                    oops();\n            } else {\n                m.fnptr = offset;\n                m.dataptr = offset + fnlen;\n                m._datasize &= ~RAFFS_FOLLOWING_MASK;\n                writeBytes(--metaDst, &m, sizeof(m));\n            }\n            offset += sz;\n        }\n        if (iter == 0)\n            finishWrite();\n    }\n\n    clearBlocked();\n    flushFlash();\n\n    LOG(\"GC done: %d free\", (int)((intptr_t)metaDst - (intptr_t)freeDataPtr));\n\n    FSHeader hd;\n    hd.magic = RAFFS_MAGIC;\n    hd.bytes = bytes;\n    hd.numgc = ((FSHeader*)basePtr)->numgc + 1;\n    hd.reserved = M1;\n    writeBytes(newBaseP, &hd, sizeof(hd));\n    flushFlash();\n\n    basePtr = newBaseP;\n    endPtr = (MetaEntry *)(newBase + bytes / 2);\n    metaPtr = metaDst;\n\n    if ((intptr_t)metaDst - (intptr_t)freeDataPtr <= spaceNeeded + 64) {\n        if (filter != NULL && spaceNeeded != 0x7fff0000) {\n            LOG(\"out of space! needed=%d\", spaceNeeded);\n#ifdef RAFFS_TEST\n            oops();\n#endif\n        }\n        return false;\n    }\n\n    return true;\n}\n\nDirEntry *FS::dirRead() {\n    lock();\n\n    if (readDirPtr == NULL) {\n        readDirPtr = metaPtr;\n        clearBlocked();\n    }\n\n    while (readDirPtr < endPtr) {\n        auto m = *readDirPtr++;\n        if (checkBlocked(&m) || m.dataptr == 0)\n            continue;\n        dirEnt.size = m.datasize();\n        dirEnt.flags = 0;\n        dirEnt.name = fnptr(&m);\n        unlock();\n        return &dirEnt;\n    }\n\n    readDirPtr = NULL;\n    clearBlocked();\n    unlock();\n    return NULL;\n}\n\nuint16_t FS::writeData(const void *data, uint32_t len) {\n    LOGVV(\"writeData: @%x %x:%x sz=%d\", REAL_OFF(freeDataPtr), ((const uint8_t *)data)[0],\n          ((const uint8_t *)data)[1], len);\n    writeBytes(freeDataPtr, data, len);\n    auto r = freeDataPtr - basePtr;\n    freeDataPtr += len;\n    return r;\n}\n\nvoid FS::finishWrite() {\n    auto nfp = RAFFS_ROUND(freeDataPtr);\n    int tailSz = nfp - (uintptr_t)freeDataPtr;\n    uint64_t z = 0;\n    if (tailSz) {\n        writeData(&z, tailSz);\n    } else {\n        if (((uint32_t *)nfp)[-1] == M1)\n            writeData(&z, 8);\n    }\n    flushFlash();\n}\n\nint FS::readFlashBytes(uintptr_t addr, void *buffer, uint32_t len) {\n    lock();\n    memcpy(buffer, (void *)addr, len);\n    unlock();\n    return len;\n}\n\n#ifdef RAFFS_TEST\nvoid FS::dump() {}\n\nvoid FS::debugDump() {\n    // dump();\n}\n#endif","RAFFS.h":"#ifndef CODAL_RAFFS_H\n#define CODAL_RAFFS_H\n\n#include \"Flash.h\"\n\nnamespace pxt {\nnamespace raffs {\n\nstruct DirEntry {\n    uint32_t size;\n    uint16_t flags;\n    const char *name;\n};\n\nstruct BlockedEntries {\n    BlockedEntries *next;\n    uint16_t fnptrs[32];\n};\n\n#define RAFFS_FOLLOWING_MASK 0x8000\n\n#ifdef PICO_BOARD\n#define RAFFS_FLASH_BUFFER_SIZE 256\n#else\n#define RAFFS_FLASH_BUFFER_SIZE 64\n#endif\n\nstruct MetaEntry {\n    uint16_t fnhash;    // hash of file name\n    uint16_t fnptr;     // offset in bytes; can't be 0xffff\n    uint16_t _datasize; // size in bytes; highest bit is set if this isn't first block\n    uint16_t dataptr;   // offset in bytes; 0x0 - deleted\n\n    uint16_t datasize() { return _datasize & 0x7fff; }\n    bool isFirst() { return (_datasize & RAFFS_FOLLOWING_MASK) == 0; }\n};\n\n#define RAFFS_ROUND(x) ((((uintptr_t)(x) + 7) >> 3) << 3)\n\ntypedef bool (*filename_filter)(const char *);\n\nclass FS {\n    codal::Flash &flash;\n\n    uint8_t *basePtr, *freeDataPtr;\n    MetaEntry *endPtr, *metaPtr, *readDirPtr, *cachedMeta;\n    int32_t gcHorizon;\n    DirEntry dirEnt;\n    uintptr_t flashBufAddr;\n    uint8_t flashBuf[RAFFS_FLASH_BUFFER_SIZE];\n    BlockedEntries *blocked;\n    volatile bool locked;\n\n    void erasePages(uintptr_t addr, uint32_t len);\n    void flushFlash();\n    void writeBytes(void *dst, const void *src, uint32_t size);\n    void mount();\n    void lock();\n    void unlock();\n    MetaEntry *findMetaEntry(const char *filename);\n    bool tryGC(int spaceNeeded, filename_filter filter = NULL);\n\n    bool checkBlocked(MetaEntry *m);\n    void clearBlocked();\n    void oopsAndClear();\n\n    uint16_t writeData(const void *data, uint32_t len);\n    void finishWrite();\n    const char *fnptr(MetaEntry *m) { return (const char *)(basePtr + m->fnptr); }\n\n    uint32_t *altBasePtr() {\n        if ((uintptr_t)basePtr == baseAddr)\n            return (uint32_t *)(baseAddr + bytes / 2);\n        else\n            return (uint32_t *)baseAddr;\n    }\n\n  public:\n    // Minimum time in ms that has to pass between two GCs; we shall panic 920 if GCs happen more often\n    // (avareged over 3x this time).\n    // This is usually set to around 10s (10000), so that if user writes a program that writes to flash in\n    // a loop, it doesn't wear out flash completely.\n    uint16_t minGCSpacing;\n    uintptr_t baseAddr;\n    uint32_t bytes;\n\n    FS(codal::Flash &flash, uintptr_t baseAddr, uint32_t bytes);\n    ~FS();\n\n    // returns 0 for success, negative for error\n    int write(const char *keyName, const void *data, uint32_t bytes);\n    // returns total number of bytes in key's value or -1 when file doesn't exists\n    // if keyName==NULL it will re-use last keyName\n    int read(const char *keyName, void *data, uint32_t bytes);\n    // deletes given key if it exists\n    int remove(const char *keyName);\n\n    void format();\n    bool exists(const char *keyName) { return read(keyName, NULL, 0) >= 0; }\n    uint32_t totalSize() { return bytes / 2; }\n    uint32_t freeSize() { return (uintptr_t)endPtr - (uintptr_t)freeDataPtr; }\n    void forceGC(filename_filter filter = NULL);\n    // this allow raw r/o access; will lock the instance as needed\n    int readFlashBytes(uintptr_t addr, void *buffer, uint32_t len);\n    bool tryMount();\n\n    void dirRewind() { readDirPtr = NULL; }\n    DirEntry *dirRead(); // data is only valid until next call to to any of File or FS function\n\n#ifdef RAFFS_TEST\n    void debugDump();\n    void dump();\n#else\n    void debugDump() {}\n#endif\n};\n\n} // namespace raffs\n} // namespace pxt\n\n#endif\n","README.md":"# Settings store in internal MCU flash\n\nThis packages implements a simple key-value storage, in vein of browser's `localStorage`.\nKeys are strings and values are buffers, but APIs are provided for using strings,\nnumbers and number arrays as values.\n\nKeys with names starting with `#` are _system keys_.\nUser applications should not read or write these directly.\n\nFollowing system keys are used:\n* `#run` - current run number; incremented on each reset; it's also used to seed the\n  random number generator; accessible via `settings.runNumber()`\n* `#volume` - last music volume set explicitly by user using the game menu\n* `#scope` - keeps the name of the program; if the current name of the program\n  doesn't match what is in that key, all non-system keys are cleared;\n  this happens for example when a new game (or rather a game with a new name) \n  is uploaded to a hardware device\n\nThe size of storage is typically limited to 16 kilobytes.\nThis applies in browser and in Arcade devices.\nSmaller MCUs may limit it further (eg., it's 1k on SAMD21 devices).\n\n## Panics 920, 921 and 922\n\nWhen there is no more space to write a key to storage, all non-system keys\nare deleted.\nThen, if more than 25% of space is still occupied (by system keys),\nall keys are deleted.\nFinally, a panic 920 is issued.\nThe user has to reset the device, and hopefully next run will fix things.\n\nAll flash devices have a limited number of erases (at least 10,000),\nbefore they start failing.\nThe settings storage implemented here doesn't erase on every write (typically\nit will erase every hundred writes or so);\nif your program keeps writing in a loop, you will likely\nhit 10,000 erases in about half hour.\n\nFor this reason, if erases happen too often (i.e., you're writing too much),\npanic 921 will be issued.\n\nIf flash memory is found to be inconsistent, panic 922 is issued.\nIn most cases, the entire flash memory is cleared before that, so that\na device reset will hopefully fix things.\n\n## Storage structure\n\nSettings are written using a very simple log file system.\nThe flash is divided in two equal regions.\nOne region is used for writing, and when it fills up, data is compressed\n(garbage collected) into the other region, which is to be used from now\non until next compression\n\nEach region starts with a header, followed by data section containing\nkey names and values.\nData section grows in the positive direction.\nFrom the end of the region, the meta-data section grows in the negative\ndirection.\nMeta-data entries are 8 bytes each and contain hash of key name,\nvalue size, and points to key name and value in the data sections.\nWhen a key value is overwritten, a new meta-data section for it\nis created. When a key is to be found, it is searched for from the most \nrecent meta-data entry.\n","RP2040Flash.cpp":"#include \"pxt.h\"\n#include \"Flash.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\n#ifdef PICO_BOARD\n#include \"hardware/flash.h\"\n\n#define XIP_BIAS 0x10000000\n\nnamespace codal {\n\nint ZFlash::pageSize(uintptr_t address) {\n  return FLASH_SECTOR_SIZE;\n}\n\nint ZFlash::totalSize() {\n#ifndef PICO_FLASH_SIZE_BYTES\n  return 2*1024*1024;\n#else\n  return PICO_FLASH_SIZE_BYTES;\n#endif\n}\n\nint ZFlash::erasePage(uintptr_t address) {\n  // address should be aligned to 4096\n  if (address % 4096 == 0){\n    target_disable_irq();\n    flash_range_erase(address - XIP_BIAS, FLASH_SECTOR_SIZE);  \n    target_enable_irq();\n  }\n  return 0;\n}\n\nint ZFlash::writeBytes(uintptr_t dst, const void *src, uint32_t len) {\n  if (len != FLASH_PAGE_SIZE || (dst & (FLASH_PAGE_SIZE - 1))) return -1;\n  // should be aligned to 256\n  target_disable_irq();\n  flash_range_program(dst - XIP_BIAS, (const uint8_t*)src, FLASH_PAGE_SIZE);\n  target_enable_irq();\n  \n  return 0;\n}\n\n\n\n\n}\n\n#endif\n","SAMDFlash.cpp":"#include \"pxt.h\"\n#include \"Flash.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\n#if defined(SAMD51) || defined(SAMD21)\nnamespace codal {\n\n#ifdef SAMD51\n#define waitForLast()                                                                              \\\n    while (NVMCTRL->STATUS.bit.READY == 0)                                                         \\\n        ;\n#else\n#define waitForLast()                                                                              \\\n    while (NVMCTRL->INTFLAG.bit.READY == 0)                                                        \\\n        ;\n#endif\n\nstatic void unlock() {\n#ifdef SAMD51\n    // see errata 2.14.1\n    NVMCTRL->CTRLA.bit.CACHEDIS0 = true;\n    NVMCTRL->CTRLA.bit.CACHEDIS1 = true;\n\n    CMCC->CTRL.bit.CEN = 0;\n    while (CMCC->SR.bit.CSTS) {\n    }\n    CMCC->MAINT0.bit.INVALL = 1;\n#endif\n}\n\nstatic void lock() {\n#ifdef SAMD51\n    // re-enable cache\n    NVMCTRL->CTRLA.bit.CACHEDIS0 = false;\n    NVMCTRL->CTRLA.bit.CACHEDIS1 = false;\n\n    // re-enable cortex-m cache - it's a separate one\n    CMCC->CTRL.bit.CEN = 0;\n    while (CMCC->SR.bit.CSTS) {\n    }\n    CMCC->MAINT0.bit.INVALL = 1;\n    CMCC->CTRL.bit.CEN = 1;\n#endif\n}\n\nint ZFlash::totalSize() {\n    return (8 << NVMCTRL->PARAM.bit.PSZ) * NVMCTRL->PARAM.bit.NVMP;\n}\n\n// this returns the size of \"page\" that can be erased (\"row\" in datasheet)\nint ZFlash::pageSize(uintptr_t address) {\n#ifdef SAMD51\n    if (address < (uintptr_t)totalSize())\n        return NVMCTRL_BLOCK_SIZE; // 8k\n#else\n    if (address < (uintptr_t)totalSize())\n        return 256;\n#endif\n    target_panic(DEVICE_FLASH_ERROR);\n    return 0;\n}\n\n#ifdef SAMD51\n#define CMD(D21, D51) NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | D51\n#else\n#define CMD(D21, D51) NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | D21\n#endif\n\nint ZFlash::erasePage(uintptr_t address) {\n    LOG(\"Erase %x\", address);\n#ifdef SAMD51\n    NVMCTRL->CTRLA.bit.WMODE = NVMCTRL_CTRLA_WMODE_MAN_Val;\n#else\n    NVMCTRL->CTRLB.bit.MANW = 1;\n#endif\n    waitForLast();\n    unlock();\n#ifdef SAMD51\n    NVMCTRL->ADDR.reg = address;\n#else\n    // yeah... /2\n    NVMCTRL->ADDR.reg = address / 2;\n#endif\n    CMD(NVMCTRL_CTRLA_CMD_ER, NVMCTRL_CTRLB_CMD_EB);\n    waitForLast();\n    lock();\n    return 0;\n}\n\n#if 0\n#define CHECK_ECC()                                                                                \\\n    if (NVMCTRL->INTFLAG.bit.ECCSE || NVMCTRL->INTFLAG.bit.ECCDE)                                  \\\n    return -10\n#else\n#define CHECK_ECC() ((void)0)\n#endif\n\nint ZFlash::writeBytes(uintptr_t dst, const void *src, uint32_t len) {\n#ifdef SAMD51\n    CHECK_ECC();\n\n    // only allow writing double word at a time\n    if (len & 7)\n        return -1;\n    if (dst & 7)\n        return -2;\n\n    // every double-word can only be written once, otherwise we get ECC errors\n    // and no, ECC cannot be disabled\n    for (unsigned i = 0; i < (len >> 3); ++i)\n        if (((uint64_t *)dst)[i] != 0xffffffffffffffff &&\n            ((uint64_t *)src)[i] != 0xffffffffffffffff)\n            return -3;\n#define WRITE_SIZE 16\n#else\n    if ((dst & 3) || (len & 3))\n        return -1;\n\n    for (unsigned i = 0; i < len; ++i)\n        if (((uint8_t *)dst)[i] != 0xff && ((uint8_t *)src)[i] != 0xff)\n            return -3;\n#define WRITE_SIZE 64\n#endif\n\n    uint32_t writeBuf[WRITE_SIZE >> 2];\n    uint32_t idx = 0;\n\n    waitForLast();\n    unlock();\n    __DMB();\n\n    while (idx < len) {\n        uint32_t off = dst & (WRITE_SIZE - 1);\n        uint32_t n = WRITE_SIZE - off;\n        if (n > len - idx)\n            n = len - idx;\n        uint32_t *sp;\n        volatile uint32_t *dp;\n        if (n != WRITE_SIZE) {\n            memset(writeBuf, 0xff, WRITE_SIZE);\n            memcpy((uint8_t *)writeBuf + off, src, n);\n            sp = writeBuf;\n            dp = (uint32_t *)(dst - off);\n        } else {\n            sp = (uint32_t *)src;\n            dp = (uint32_t *)dst;\n        }\n\n        bool need = false;\n        for (unsigned i = 0; i < (WRITE_SIZE >> 2); ++i)\n            if (sp[i] != 0xffffffff) {\n                need = true;\n                break;\n            }\n\n        if (need) {\n            CMD(NVMCTRL_CTRLA_CMD_PBC, NVMCTRL_CTRLB_CMD_PBC);\n            waitForLast();\n\n            uint32_t q = WRITE_SIZE >> 2;\n\n            target_disable_irq();\n            while (q--) {\n                auto v = *sp++;\n                *dp = v;\n                dp++;\n            }\n\n            CMD(NVMCTRL_CTRLA_CMD_WP, NVMCTRL_CTRLB_CMD_WQW);\n            target_enable_irq();\n            waitForLast();\n        }\n\n        src = (uint8_t *)src + n;\n        dst += n;\n        idx += n;\n    }\n\n    CHECK_ECC();\n\n    lock();\n\n    return 0;\n}\n} // namespace codal\n#endif\n","STM32Flash.cpp":"#include \"pxt.h\"\n#include \"Flash.h\"\n\n//#define LOG DMESG\n#define LOG NOLOG\n\n#ifdef STM32F4\nnamespace codal {\nstatic void waitForLast() {\n    while ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY)\n        ;\n}\n\nstatic void unlock() {\n    FLASH->CR |= FLASH_CR_LOCK;\n    FLASH->KEYR = FLASH_KEY1;\n    FLASH->KEYR = FLASH_KEY2;\n}\n\nstatic void lock() {\n    FLASH->CR |= FLASH_CR_LOCK;\n}\n\nint ZFlash::pageSize(uintptr_t address) {\n    address |= 0x08000000;\n    if (address < 0x08010000)\n        return 16 * 1024;\n    if (address < 0x08020000)\n        return 64 * 1024;\n    if (address < 0x08100000)\n        return 128 * 1024;\n    target_panic(DEVICE_FLASH_ERROR);\n    return 0;\n}\n\nint ZFlash::totalSize() {\n    return *((uint16_t *)0x1FFF7A22) * 1024;\n}\n\nint ZFlash::erasePage(uintptr_t address) {\n    waitForLast();\n    unlock();\n\n    address |= 0x08000000;\n    uintptr_t ptr = 0x08000000;\n    int sectNum = 0;\n    while (1) {\n        ptr += pageSize(ptr);\n        if (ptr > address)\n            break;\n        sectNum++;\n    }\n\n    FLASH->CR = FLASH_CR_PSIZE_1 | (sectNum << FLASH_CR_SNB_Pos) | FLASH_CR_SER;\n    FLASH->CR |= FLASH_CR_STRT;\n\n    waitForLast();\n\n    FLASH->CR = FLASH_CR_PSIZE_1;\n    lock();\n\n    // cache flushing only required after erase, not programming (3.5.4)\n    __HAL_FLASH_DATA_CACHE_DISABLE();\n    __HAL_FLASH_DATA_CACHE_RESET();\n    __HAL_FLASH_DATA_CACHE_ENABLE();\n\n    // we skip instruction cache, as we're not expecting to erase that\n\n    return 0;\n}\n\nint ZFlash::writeBytes(uintptr_t dst, const void *src, uint32_t len) {\n    LOG(\"WR flash at %p len=%d\", (void *)dst, len);\n\n    if ((dst & 3) || ((uintptr_t)src & 3) || (len & 3))\n        return -1;\n\n    for (unsigned i = 0; i < len; ++i)\n        if (((uint8_t *)dst)[i] != 0xff && ((uint8_t *)src)[i] != 0xff)\n            return -3;\n\n    waitForLast();\n    unlock();\n\n    dst |= 0x08000000;\n\n    FLASH->CR = FLASH_CR_PSIZE_1 | FLASH_CR_PG;\n\n    volatile uint32_t *sp = (uint32_t *)src;\n    volatile uint32_t *dp = (uint32_t *)dst;\n    len >>= 2;\n\n    while (len-- > 0) {\n        uint32_t v = *sp++;\n        if (v != 0xffffffff) {\n            *dp++ = v;\n            waitForLast();\n        } else {\n            dp++;\n        }\n    }\n\n    FLASH->CR = FLASH_CR_PSIZE_1;\n    lock();\n\n    LOG(\"WR flash OK\");\n\n    return 0;\n}\n} // namespace codal\n#endif\n","pxt.json":"{\n    \"name\": \"settings\",\n    \"description\": \"Settings storage in internal flash\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"RAFFS.cpp\",\n        \"RAFFS.h\",\n        \"Flash.h\",\n        \"STM32Flash.cpp\",\n        \"SAMDFlash.cpp\",\n        \"NRF52Flash.cpp\",\n        \"RP2040Flash.cpp\",\n        \"settings.cpp\",\n        \"settings.ts\",\n        \"shims.d.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","settings.cpp":"\n#include \"pxt.h\"\n#include \"RAFFS.h\"\n#include \"GhostFAT.h\"\n\nusing namespace pxt::raffs;\nusing namespace codal;\n\nnamespace settings {\n\n#if defined(SAMD21)\n#define SETTINGS_SIZE (2 * 1024)\n#else\n#define SETTINGS_SIZE (32 * 1024)\n#endif\n\nclass WStorage {\n  public:\n    CODAL_FLASH flash;\n    FS fs;\n    bool isMounted;\n\n    WStorage()\n        : flash(),\n#if defined(STM32F4)\n          fs(flash, 0x8008000, SETTINGS_SIZE),\n#elif defined(SAMD51)\n          fs(flash, 512 * 1024 - SETTINGS_SIZE, SETTINGS_SIZE),\n#elif defined(SAMD21)\n          fs(flash, 256 * 1024 - SETTINGS_SIZE, SETTINGS_SIZE),\n#elif defined(MICROBIT_CODAL) && MICROBIT_CODAL\n          // micro:bit V2 memory map\n          // https://github.com/lancaster-university/codal-microbit-v2/blob/master/docs/MemoryMap.md\n          // 73000\tCODAL scratch page (is used as temporary scratch by MicroBitFlash, MicroBitFileSystem and MicroBitStorage)\n          fs(flash, 0x73000 - SETTINGS_SIZE, SETTINGS_SIZE),\n#elif defined(NRF52_SERIES)\n#define NRF_BOOTLOADER_START *(uint32_t *)0x10001014\n          fs(flash,\n             128 * 1024 < NRF_BOOTLOADER_START && NRF_BOOTLOADER_START < (uint32_t)flash.totalSize()\n                 ? NRF_BOOTLOADER_START - SETTINGS_SIZE\n                 : flash.totalSize() - SETTINGS_SIZE,\n             SETTINGS_SIZE),\n#elif defined(PICO_BOARD)\n          // XIP bias 0x10000000\n          fs(flash, 0x10000000 + flash.totalSize() - SETTINGS_SIZE - 4096, SETTINGS_SIZE),\n#else\n          fs(flash),\n#endif\n          isMounted(false) {\n        fs.minGCSpacing = 10000;\n    }\n};\nSINGLETON(WStorage);\n\nstatic WStorage *mountedStorage() {\n    auto s = getWStorage();\n    if (s->fs.tryMount())\n        return s;\n    s->fs.exists(\"foobar\"); // forces mount and possibly format\n    return s;\n}\n\n// large store is area for storing large binary objects, eg ML models\n// it may be already occupied by the user program, in which case largeStoreStart() will return 0\nsize_t largeStoreSize() {\n#if defined(SAMD21)\n    return 64 * 1024;\n#else\n    return 128 * 1024;\n#endif\n}\n\nuintptr_t largeStoreStart() {\n    auto s = getWStorage();\n    uintptr_t r;\n#if defined(STM32F4)\n    r = 0x08000000 + s->flash.totalSize() - largeStoreSize();\n#else\n    r = s->fs.baseAddr - s->fs.bytes - largeStoreSize();\n#endif\n\n    if (r < afterProgramPage())\n        return 0;\n\n    return r;\n}\n\nCODAL_FLASH *largeStoreFlash() {\n    return &getWStorage()->flash;\n}\n\n//%\nint _set(String key, Buffer data) {\n    auto s = mountedStorage();\n    return s->fs.write(key->getUTF8Data(), data->data, data->length);\n}\n\n//%\nint _remove(String key) {\n    auto s = mountedStorage();\n    return s->fs.remove(key->getUTF8Data());\n}\n\n//%\nbool _exists(String key) {\n    auto s = mountedStorage();\n    return s->fs.exists(key->getUTF8Data());\n}\n\n//%\nBuffer _get(String key) {\n    auto s = mountedStorage();\n    auto sz = s->fs.read(key->getUTF8Data(), NULL, 0);\n    if (sz < 0)\n        return NULL;\n    auto ret = mkBuffer(NULL, sz);\n    registerGCObj(ret);\n    s->fs.read(NULL, ret->data, ret->length);\n    unregisterGCObj(ret);\n    return ret;\n}\n\nstatic bool isSystem(const char *fn) {\n    return fn[0] == '#';\n}\n\n//%\nvoid _userClean() {\n    auto s = mountedStorage();\n    DMESG(\"clearing user files\");\n    s->fs.forceGC(isSystem);\n    // if system files take more than 25% of storage size, we reformat\n    // it likely means user code has written some 'system' files\n    if (s->fs.freeSize() < 3 * s->fs.totalSize() / 4) {\n        s->fs.format();\n    }\n}\n\n//%\nRefCollection *_list(String prefix) {\n    auto st = mountedStorage();\n    st->fs.dirRewind();\n    auto res = Array_::mk();\n    registerGCObj(res);\n\n    auto prefData = prefix->getUTF8Data();\n    auto prefLen = prefix->getUTF8Size();\n    auto wantsInternal = prefData[0] == '#';\n\n    for (;;) {\n        auto d = st->fs.dirRead();\n        if (!d)\n            break;\n        if (!wantsInternal && d->name[0] == '#')\n            continue;\n        if (memcmp(d->name, prefData, prefLen) != 0)\n            continue;\n        auto str = mkString(d->name, -1);\n        registerGCObj(str);\n        res->head.push((TValue)str);\n        unregisterGCObj(str);\n    }\n    unregisterGCObj(res);\n    return res;\n}\n\n} // namespace settings\n","settings.ts":"namespace settings {\n    const RUN_KEY = \"#run\";\n    const SCOPE_KEY = \"#scope\";\n    const DEVICE_SECRETS_KEY = \"#secrets\";\n    const SECRETS_KEY = \"__secrets\";\n\n    //% shim=pxt::seedAddRandom\n    declare function seedAddRandom(n: number): void;\n\n    //% shim=settings::_set\n    declare function _set(key: string, data: Buffer): int32;\n\n    //% shim=settings::_remove\n    declare function _remove(key: string): int32;\n\n    //% shim=settings::_exists\n    declare function _exists(key: string): boolean;\n\n    //% shim=settings::_get\n    declare function _get(key: string): Buffer;\n\n    //% shim=settings::_userClean\n    declare function _userClean(): void;\n\n    //% shim=settings::_list\n    declare function _list(prefix: string): string[];\n\n    export function runNumber() {\n        return readNumber(RUN_KEY) || 0\n    }\n\n    function setScope(scope: string) {\n        if (!scope || scope.length > 100)\n            control.panic(922)\n        const currScope = readString(SCOPE_KEY)\n        if (currScope != scope) {\n            _userClean()\n            writeString(SCOPE_KEY, scope)\n        }\n    }\n\n    function initScopes() {\n        const rn = runNumber() + 1\n        writeNumber(RUN_KEY, rn)\n\n        seedAddRandom(control.deviceSerialNumber() & 0x7fffffff)\n        seedAddRandom(rn)\n\n        setScope(control.programName())\n    }\n\n    initScopes()\n\n    /** \n     * Delete all non-system settings.\n     */\n    export function clear(): void {\n        _userClean()\n    }\n\n    /**\n     * Set named setting to a given buffer.\n     */\n    export function writeBuffer(key: string, value: Buffer) {\n        if (_set(key, value)) {\n            // if we're out of space, clear user storage\n            _userClean()\n            // and panic - reset should hopefully recreate needed files\n            control.panic(920)\n        }\n    }\n\n    /**\n     * Set named settings to a given string.\n     */\n    export function writeString(key: string, value: string) {\n        writeBuffer(key, control.createBufferFromUTF8(value))\n    }\n\n    /**\n     * Set named settings to a given JSON object.\n     */\n    export function writeJSON(key: string, value: any) {\n        writeString(key, JSON.stringify(value))\n    }\n\n    /**\n     * Set named settings to a given number.\n     */\n    export function writeNumber(key: string, value: number) {\n        writeBuffer(key, msgpack.packNumberArray([value]))\n    }\n\n    /**\n     * Set named settings to a given array of numbers.\n     */\n    export function writeNumberArray(key: string, value: number[]) {\n        writeBuffer(key, msgpack.packNumberArray(value))\n    }\n\n    /**\n     * Read named setting as a buffer. Returns undefined when setting not found.\n     */\n    export function readBuffer(key: string) {\n        return _get(key)\n    }\n\n    /**\n     * Read named setting as a string.\n     */\n    export function readString(key: string) {\n        const buf = readBuffer(key)\n        if (!buf)\n            return undefined\n        else\n            return buf.toString()\n    }\n\n    /**\n     * Read named setting as a JSON object.\n     */\n    export function readJSON(key: string) {\n        const s = readString(key)\n        if (s)\n            return JSON.parse(s)\n        return undefined\n    }\n\n    /**\n     * Read named setting as a number.\n     */\n    export function readNumber(key: string) {\n        const buf = readBuffer(key)\n        if (!buf)\n            return undefined\n        else {\n            const nums = msgpack.unpackNumberArray(buf)\n            if (nums && nums.length >= 1)\n                return nums[0]\n            return undefined\n        }\n    }\n\n    /**\n     * Read named setting as a number.\n     */\n    export function readNumberArray(key: string) {\n        const buf = readBuffer(key)\n        if (!buf)\n            return undefined\n        else\n            return msgpack.unpackNumberArray(buf)\n    }\n\n    /**\n     * Return a list of settings starting with a given prefix.\n     */\n    export function list(prefix?: string) {\n        if (!prefix) prefix = \"\"\n        return _list(prefix)\n    }\n\n    /**\n     * Remove named setting.\n     */\n    export function remove(key: string) {\n        _remove(key)\n    }\n\n    /**\n     * Check if a named setting exists.\n     */\n    export function exists(key: string) {\n        return _exists(key)\n    }\n\n    function clone(v: any): any {\n        if (v == null) return null\n        return JSON.parse(JSON.stringify(v))\n    }\n\n    function isKV(v: any) {\n        return !!v && typeof v === \"object\" && !Array.isArray(v)\n    }\n\n    function jsonMergeFrom(trg: any, src: any) {\n        if (!src) return;\n        const keys = Object.keys(src)\n        keys.forEach(k => {\n            const srck = src[k];\n            if (isKV(trg[k]) && isKV(srck))\n                jsonMergeFrom(trg[k], srck);\n            else\n                trg[k] = clone(srck);\n        });\n    }\n\n    //% fixedInstances\n    export class SecretStore {\n        constructor(private key: string) { }\n\n        setSecret(name: string, value: any) {\n            const secrets = this.readSecrets();\n            secrets[name] = value;\n            writeJSON(this.key, secrets);\n        }\n\n        updateSecret(name: string, value: any) {\n            const secrets = this.readSecrets();\n            const secret = secrets[name];\n            if (secret === undefined)\n                secrets[name] = value;\n            else jsonMergeFrom(secret, value);\n            writeJSON(this.key, secrets)\n        }\n\n        readSecret(name: string, ensure: boolean = false): any {\n            const secrets = this.readSecrets();\n            const secret = secrets[name];\n            if (ensure && !secret)\n                throw \"missing secret \" + name;\n            return secret;\n        }\n\n        clearSecrets() {\n            writeString(this.key, \"{}\");\n        }\n\n        readSecrets(): any {\n            try {\n                return readJSON(this.key) || {}\n            } catch {\n                control.dmesg(\"invalid secret format\")\n                return {};\n            }\n        }\n    }\n\n    /**\n     * Secrets shared by any program on the device\n     */\n    //% fixedInstance whenUsed block=\"device secrets\"\n    export const deviceSecrets = new SecretStore(DEVICE_SECRETS_KEY);\n\n    /**\n     * Program secrets\n     */\n    //% fixedInstance whenUsed block=\"program secrets\"\n    export const programSecrets = new SecretStore(SECRETS_KEY);\n}\n","shims.d.ts":"\n"},"settings---files":{"pxt.json":"{\n    \"name\": \"settings---files\",\n    \"description\": \"Settings storage in files\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"settings.cpp\",\n        \"settings.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    }\n}\n","settings.cpp":"#define _GNU_SOURCE 1\n\n#include \"pxt.h\"\n\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <dirent.h>\n#include <errno.h>\n\n#define FAIL(msg)                                                                                  \\\n    do {                                                                                           \\\n        DMESG(\"FAILURE: %s\", msg);                                                                 \\\n        abort();                                                                                   \\\n    } while (0)\n\nnamespace settings {\n\n#define ADD(c)                                                                                     \\\n    do {                                                                                           \\\n        buf[dp] = (c);                                                                             \\\n        dp++;                                                                                      \\\n        if (dp > 1000)                                                                             \\\n            FAIL(\"too long\");                                                                      \\\n    } while (0)\n\nconst char *hexD = \"0123456789abcdef\";\n\nstatic char *encodeString(const char *str) {\n    static char buf[1024];\n    int dp = 0;\n    for (auto sp = str; *sp; ++sp) {\n        auto c = *sp;\n        if (('0' <= c && c <= '9') || ('a' <= c && c <= 'z'))\n            ADD(c);\n        else if (('A' <= c && c <= 'Z')) {\n            ADD('-');\n            ADD(c | 0x20);\n        } else {\n            ADD('_');\n            ADD(hexD[(c >> 4) & 0xf]);\n            ADD(hexD[c & 0xf]);\n        }\n    }\n\n    ADD(0);\n\n    return buf;\n}\n\nstatic int hex(char c) {\n    if ('0' <= c && c <= '9')\n        return c - '0';\n    c |= 0x20;\n    if ('a' <= c && c <= 'f')\n        return c - 'a' + 10;\n    return -1;\n}\n\nstatic char *decodeString(const char *str) {\n    static char buf[1024];\n    int dp = 0;\n\n    if (strlen(str) > 1000)\n        FAIL(\"too long decode\");\n\n    for (auto sp = str; *sp; ++sp) {\n        auto c = *sp;\n        if (('0' <= c && c <= '9') || ('a' <= c && c <= 'z'))\n            ADD(c);\n        else if (c == '-' && sp[1]) {\n            ADD(sp[1] & ~0x20);\n            sp++;\n        } else if (c == '_' && hex(sp[1]) >= 0 && hex(sp[2]) >= 0) {\n            ADD((hex(sp[1]) << 4) | hex(sp[2]));\n            sp += 2;\n        }\n    }\n\n    ADD(0);\n\n    return buf;\n}\n\nstatic const char *settingsDirectory() {\n    static char *name;\n    if (name)\n        return name;\n#ifdef SETTINGSDIR\n    asprintf(&name, \"%s/%s\", SETTINGSDIR, encodeString(programName()->getUTF8Data()));\n#else\n    asprintf(&name, \"%s.data\", initialArgv[0]);\n#endif\n#ifdef __WIN32__\n    mkdir(name);\n#else\n    mkdir(name, 0777);\n#endif\n    return name;\n}\n\nstatic const char *keyName(const char *key) {\n    static char *lastName;\n    if (lastName)\n        free(lastName);\n    auto dirname = settingsDirectory();\n    asprintf(&lastName, \"%s/%s\", dirname, encodeString(key));\n    return lastName;\n}\n\nstatic const char *keyName(String key) {\n    return keyName(key->getUTF8Data());\n}\n\nstatic FILE *openKey(String key, const char *mode) {\n    return fopen(keyName(key), mode);\n}\n\n//%\nint _set(String key, Buffer data) {\n    // DMESG(\"set[%s] - %p\", key->getUTF8Data(), data);\n    auto f = openKey(key, \"wb\");\n    if (!f) {\n        DMESG(\"errno=%d\", errno);\n        FAIL(\"can't write file\");\n    }\n    fwrite(data->data, data->length, 1, f);\n    fclose(f);\n    return 0;\n}\n\n//%\nint _remove(String key) {\n    return remove(keyName(key));\n}\n\n//%\nbool _exists(String key) {\n    auto f = openKey(key, \"rb\");\n    if (f != NULL)\n        fclose(f);\n    return f != NULL;\n}\n\n//%\nBuffer _get(String key) {\n    auto f = openKey(key, \"rb\");\n    if (f == NULL)\n        return NULL;\n    fseek(f, 0, SEEK_END);\n    auto sz = ftell(f);\n    auto ret = mkBuffer(NULL, sz);\n    registerGCObj(ret);\n    fseek(f, 0, SEEK_SET);\n    fread(ret->data, ret->length, 1, f);\n    fclose(f);\n    unregisterGCObj(ret);\n    return ret;\n}\n\n//%\nvoid _userClean() {\n    auto dp = opendir(settingsDirectory());\n    if (!dp)\n        return;\n    for (;;) {\n        dirent *ep = readdir(dp);\n        if (!ep)\n            break;\n        auto name = decodeString(ep->d_name);\n        if (name[0] == '#')\n            continue;\n        remove(keyName(name));\n    }\n    closedir(dp);\n}\n\n//%\nRefCollection *_list(String prefix) {\n    auto res = Array_::mk();\n    registerGCObj(res);\n\n    auto prefData = prefix->getUTF8Data();\n    auto prefLen = prefix->getUTF8Size();\n    auto wantsInternal = prefData[0] == '#';\n\n    auto dp = opendir(settingsDirectory());\n\n    for (;;) {\n        dirent *ep = dp ? readdir(dp) : NULL;\n        if (!ep)\n            break;\n        auto name = decodeString(ep->d_name);\n        if (!wantsInternal && name[0] == '#')\n            continue;\n        if (memcmp(name, prefData, prefLen) != 0)\n            continue;\n        auto str = mkString(name, -1);\n        registerGCObj(str);\n        res->head.push((TValue)str);\n        unregisterGCObj(str);\n    }\n    if (dp)\n        closedir(dp);\n    unregisterGCObj(res);\n\n    return res;\n}\n\n} // namespace settings\n","settings.ts":"namespace settings {\n    const RUN_KEY = \"#run\";\n    const SCOPE_KEY = \"#scope\";\n    const DEVICE_SECRETS_KEY = \"#secrets\";\n    const SECRETS_KEY = \"__secrets\";\n\n    //% shim=pxt::seedAddRandom\n    declare function seedAddRandom(n: number): void;\n\n    //% shim=settings::_set\n    declare function _set(key: string, data: Buffer): int32;\n\n    //% shim=settings::_remove\n    declare function _remove(key: string): int32;\n\n    //% shim=settings::_exists\n    declare function _exists(key: string): boolean;\n\n    //% shim=settings::_get\n    declare function _get(key: string): Buffer;\n\n    //% shim=settings::_userClean\n    declare function _userClean(): void;\n\n    //% shim=settings::_list\n    declare function _list(prefix: string): string[];\n\n    export function runNumber() {\n        return readNumber(RUN_KEY) || 0\n    }\n\n    function setScope(scope: string) {\n        if (!scope || scope.length > 100)\n            control.panic(922)\n        const currScope = readString(SCOPE_KEY)\n        if (currScope != scope) {\n            _userClean()\n            writeString(SCOPE_KEY, scope)\n        }\n    }\n\n    function initScopes() {\n        const rn = runNumber() + 1\n        writeNumber(RUN_KEY, rn)\n\n        seedAddRandom(control.deviceSerialNumber() & 0x7fffffff)\n        seedAddRandom(rn)\n\n        setScope(control.programName())\n    }\n\n    initScopes()\n\n    /** \n     * Delete all non-system settings.\n     */\n    export function clear(): void {\n        _userClean()\n    }\n\n    /**\n     * Set named setting to a given buffer.\n     */\n    export function writeBuffer(key: string, value: Buffer) {\n        if (_set(key, value)) {\n            // if we're out of space, clear user storage\n            _userClean()\n            // and panic - reset should hopefully recreate needed files\n            control.panic(920)\n        }\n    }\n\n    /**\n     * Set named settings to a given string.\n     */\n    export function writeString(key: string, value: string) {\n        writeBuffer(key, control.createBufferFromUTF8(value))\n    }\n\n    /**\n     * Set named settings to a given JSON object.\n     */\n    export function writeJSON(key: string, value: any) {\n        writeString(key, JSON.stringify(value))\n    }\n\n    /**\n     * Set named settings to a given number.\n     */\n    export function writeNumber(key: string, value: number) {\n        writeBuffer(key, msgpack.packNumberArray([value]))\n    }\n\n    /**\n     * Set named settings to a given array of numbers.\n     */\n    export function writeNumberArray(key: string, value: number[]) {\n        writeBuffer(key, msgpack.packNumberArray(value))\n    }\n\n    /**\n     * Read named setting as a buffer. Returns undefined when setting not found.\n     */\n    export function readBuffer(key: string) {\n        return _get(key)\n    }\n\n    /**\n     * Read named setting as a string.\n     */\n    export function readString(key: string) {\n        const buf = readBuffer(key)\n        if (!buf)\n            return undefined\n        else\n            return buf.toString()\n    }\n\n    /**\n     * Read named setting as a JSON object.\n     */\n    export function readJSON(key: string) {\n        const s = readString(key)\n        if (s)\n            return JSON.parse(s)\n        return undefined\n    }\n\n    /**\n     * Read named setting as a number.\n     */\n    export function readNumber(key: string) {\n        const buf = readBuffer(key)\n        if (!buf)\n            return undefined\n        else {\n            const nums = msgpack.unpackNumberArray(buf)\n            if (nums && nums.length >= 1)\n                return nums[0]\n            return undefined\n        }\n    }\n\n    /**\n     * Read named setting as a number.\n     */\n    export function readNumberArray(key: string) {\n        const buf = readBuffer(key)\n        if (!buf)\n            return undefined\n        else\n            return msgpack.unpackNumberArray(buf)\n    }\n\n    /**\n     * Return a list of settings starting with a given prefix.\n     */\n    export function list(prefix?: string) {\n        if (!prefix) prefix = \"\"\n        return _list(prefix)\n    }\n\n    /**\n     * Remove named setting.\n     */\n    export function remove(key: string) {\n        _remove(key)\n    }\n\n    /**\n     * Check if a named setting exists.\n     */\n    export function exists(key: string) {\n        return _exists(key)\n    }\n\n    function clone(v: any): any {\n        if (v == null) return null\n        return JSON.parse(JSON.stringify(v))\n    }\n\n    function isKV(v: any) {\n        return !!v && typeof v === \"object\" && !Array.isArray(v)\n    }\n\n    function jsonMergeFrom(trg: any, src: any) {\n        if (!src) return;\n        const keys = Object.keys(src)\n        keys.forEach(k => {\n            const srck = src[k];\n            if (isKV(trg[k]) && isKV(srck))\n                jsonMergeFrom(trg[k], srck);\n            else\n                trg[k] = clone(srck);\n        });\n    }\n\n    //% fixedInstances\n    export class SecretStore {\n        constructor(private key: string) { }\n\n        setSecret(name: string, value: any) {\n            const secrets = this.readSecrets();\n            secrets[name] = value;\n            writeJSON(this.key, secrets);\n        }\n\n        updateSecret(name: string, value: any) {\n            const secrets = this.readSecrets();\n            const secret = secrets[name];\n            if (secret === undefined)\n                secrets[name] = value;\n            else jsonMergeFrom(secret, value);\n            writeJSON(this.key, secrets)\n        }\n\n        readSecret(name: string, ensure: boolean = false): any {\n            const secrets = this.readSecrets();\n            const secret = secrets[name];\n            if (ensure && !secret)\n                throw \"missing secret \" + name;\n            return secret;\n        }\n\n        clearSecrets() {\n            writeString(this.key, \"{}\");\n        }\n\n        readSecrets(): any {\n            try {\n                return readJSON(this.key) || {}\n            } catch {\n                control.dmesg(\"invalid secret format\")\n                return {};\n            }\n        }\n    }\n\n    /**\n     * Secrets shared by any program on the device\n     */\n    //% fixedInstance whenUsed block=\"device secrets\"\n    export const deviceSecrets = new SecretStore(DEVICE_SECRETS_KEY);\n\n    /**\n     * Program secrets\n     */\n    //% fixedInstance whenUsed block=\"program secrets\"\n    export const programSecrets = new SecretStore(SECRETS_KEY);\n}\n"},"sevenseg":{"README.md":"# Seven segment\n\nFunctions and classes to create a seven segment display.\n","pxt.json":"{\n    \"name\": \"sevenseg\",\n    \"description\": \"Seven segment digit display\",\n    \"dependencies\": {\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"sevenseg.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"icon\": \"/static/libs/sevenseg.png\"\n}\n","sevenseg.ts":"enum SegmentStyle {\n    //% block=\"blank\"\n    Blank = 0,\n    //% block=\"thin\"\n    Thin = 1,\n    //% block=\"narrow\"\n    Narrow = 2,\n    //% block=\"medium\"\n    Medium = 3,\n    //% block=\"thick\"\n    Thick = 4\n}\n\nenum DigitRadix {\n    //% block=\"decimal\"\n    Decimal = 10,\n    //% block=\"hex\"\n    Hex = 16,\n    //% block=\"octal\"\n    Octal = 8,\n    //% block=\"alpha\"\n    Alpha = 26\n}\n\nenum SegmentScale {\n    //% block=\"full\"\n    Full,\n    //% block=\"half\"\n    Half\n}\n\n// \"0123456789ABCDEFHJLoPrUY-°\"\nenum SegmentCharacter {\n    //% block=\"0\"\n    ZERO,\n    //% block=\"1\"\n    ONE,\n    //% block=\"2\"\n    TWO,\n    //% block=\"3\"\n    THREE,\n    //% block=\"4\"\n    FOUR,\n    //% block=\"5\"\n    FIVE,\n    //% block=\"6\"\n    SIX,\n    //% block=\"7\"\n    SEVEN,\n    //% block=\"8\"\n    EIGHT,\n    //% block=\"9\"\n    NINE,\n    //% block=\"A\"\n    A,\n    //% block=\"B\"\n    B,\n    //% block=\"C\"\n    C,\n    //% block=\"D\"\n    D,\n    //% block=\"E\"\n    E,\n    //% block=\"F\"\n    F,\n    //% block=\"H\"\n    H,\n    //% block=\"J\"\n    J,\n    //% block=\"L\"\n    L,\n    //% block=\"o\"\n    o,\n    //% block=\"P\"\n    P,\n    //% block=\"r\"\n    r,\n    //% block=\"U\"\n    U,\n    //% block=\"Y\"\n    Y,\n    //% block=\"-\"\n    Hyphen,\n    //% block=\"°\"\n    Degree\n}\n\n/**\n* Seven segment display digits and gizmos\n*/\n//% icon=\"\\uf2a1\" color=\"#4682B4\" blockGap=8\n//% groups='[\"Create\", \"Counter\", \"Digits\"]'\nnamespace sevenseg {\n\n    // Copy these array sets along with the array mapping string into Node to get the\n    // formatting of the segment buffer data.\n\n    /*\n    var fullSegment: number[][] = [\n        [1, 0, 14, 0, 2, 1, 13, 1, 3, 2, 12, 2, 4, 3, 11, 3],\n        [15, 2, 15, 14, 14, 3, 14, 13, 13, 4, 13, 12, 12, 5, 12, 11],\n        [15, 17, 15, 29, 14, 18, 14, 28, 13, 19, 13, 27, 12, 20, 12, 26],\n        [1, 31, 14, 31, 2, 30, 13, 30, 3, 29, 12, 29, 4, 28, 11, 28],\n        [0, 17, 0, 29, 1, 18, 1, 28, 2, 19, 2, 27, 3, 20, 3, 26],\n        [0, 2, 0, 14, 1, 3, 1, 13, 2, 4, 2, 12, 3, 5, 3, 11],\n        [2, 15, 13, 15, 2, 16, 13, 16, 3, 14, 12, 14, 3, 17, 12, 17]\n    ];\n    \"hex`\" + fullSegment.map(n => n.toString(16)).map(n => n.length < 2 ? \"0\" + n : n).join(\"\") + \"`\"\n    */\n\n    // packed metrics of pixel drawing for full size digit segments\n    const fullSegment: Buffer[] = [\n        hex`01000e0002010d0103020c0204030b03`,\n        hex`0f020f0e0e030e0d0d040d0c0c050c0b`,\n        hex`0f110f1d0e120e1c0d130d1b0c140c1a`,\n        hex`011f0e1f021e0d1e031d0c1d041c0b1c`,\n        hex`0011001d0112011c0213021b0314031a`,\n        hex`0002000e0103010d0204020c0305030b`,\n        hex`020f0d0f02100d10030e0c0e03110c11`\n    ];\n\n    /*\n    var halfSegment: number[][] = [\n        [1, 0, 6, 0, 2, 1, 5, 1],\n        [7, 2, 7, 6, 6, 3, 6, 5],\n        [7, 8, 7, 13, 6, 9, 6, 12],\n        [1, 15, 6, 15, 2, 14, 5, 14],\n        [0, 8, 0, 13, 1, 9, 1, 12],\n        [0, 2, 0, 6, 1, 3, 1, 5],\n        [2, 7, 5, 7, 2, 7, 5, 7]\n    ];\n    \"hex`\" + halfSegment.map(n => n.toString(16)).map(n => n.length < 2 ? \"0\" + n : n).join(\"\") + \"`\"\n    */\n\n    // packed metrics of pixel drawing for half size digit segments\n    const halfSegment: Buffer[] = [\n        hex`0100060002010501`,\n        hex`0702070606030605`,\n        hex`0708070d0609060c`,\n        hex`010f060f020e050e`,\n        hex`0008000d0109010c`,\n        hex`0002000601030105`,\n        hex`0207050702070507`\n    ];\n\n    // Seven segment layout and id assignments\n    //\n    //          a\n    //      =========\n    //     ||       ||\n    //   f ||       || b\n    //     ||   g   ||\n    //      =========\n    //     ||       ||\n    //   e ||       || c\n    //     ||   d   ||\n    //      =========\n\n    /*\n    const segmapIds = [\"abcdef\", \"bc\", \"abdeg\", \"abcdg\", \"bcfg\", \"acdfg\", \"acdefg\", \"abc\", \"abcdefg\", \"abcdfg\"];\n    var segmap = [\n        0b11111100, // '0' digit maps \"abcdef..\"\n        0b01100000, // '1' digit maps \".bc.....\"\n        0b11011010, // '2' digit maps \"ab.de.g.\"\n        0b11110010, // '3' digit maps \"abcd..g.\"\n        0b01100110, // '4' digit maps \".bc..fg.\"\n        0b10110110, // '5' digit maps \"a.cd.fg.\"\n        0b10111110, // '6' digit maps \"a.cdefg.\"\n        0b11100000, // '7' digit maps \"abc.....\"\n        0b11111110, // '8' digit maps \"abcdefg.\"\n        0b11110110, // '9' digit maps \"abcd.fg.\"\n        0b11101110, // 'A' digit maps \"abc.efg.\"\n        0b00111110, // 'b' digit maps \"..cdefg.\"\n        0b10011100, // 'C' digit maps \"a..def..\"\n        0b01111010, // 'd' digit maps \".bcde.g.\"\n        0b10011110, // 'E' digit maps \"a..defg.\"\n        0b10001110, // 'F' digit maps \"a...efg.\"\n        0b01101110, // 'H' digit maps \".bc.efg.\"\n        0b01111000, // 'J' digit maps \".bcde...\"\n        0b00011100, // 'L' digit maps \"...def..\"\n        0b00111010, // 'o' digit maps \"..cde.g.\"\n        0b11001110, // 'P' digit maps \"ab..efg.\"\n        0b00001010, // 'r' digit maps \"....e.g.\"\n        0b01111100, // 'U' digit maps \".bcdef..\"\n        0b01110110, // 'Y' digit maps \".bcd.fg.\"\n        0b00000010, // '-' digit maps \"......g.\"\n        0b11000110  // '°' digit maps \"ab...fg.\"\n    ];\n    \"hex`\" + segmap.map(n => n.toString(16)).map(n => n.length < 2 ? \"0\" + n : n).join(\"\") + \"`\"\n    */\n    \n    const segmap: Buffer = hex`fc60daf266b6bee0fef6ee3e9c7a9e8e6e781c3ace0a7c7602c6`;\n\n    export function drawSegment(digit: Image, segment: Buffer, thickness: SegmentStyle, color: number) {\n        let offset = 0;\n        let x, y, w, h = 0;\n        if (segment.length >= thickness * 4) {\n            for (let i = 0; i < thickness; i++) {\n                x = segment.getNumber(NumberFormat.Int8LE, offset + 0);\n                y = segment.getNumber(NumberFormat.Int8LE, offset + 1);\n                w = segment.getNumber(NumberFormat.Int8LE, offset + 2) - x + 1;\n                h = segment.getNumber(NumberFormat.Int8LE, offset + 3) - y + 1;\n                digit.fillRect(x, y, w, h, color);\n                offset += 4;\n            }\n        }\n    }\n    \n    export function drawDigit(digit: Image, value: number, thickness: SegmentStyle, scale: SegmentScale, color: number) {\n        let segment: Buffer = null;\n        let digitMap = segmap.getNumber(NumberFormat.Int8LE, value)\n\n        digit.fill(0);\n        for (let i = 0; digitMap != 0; i++) {\n            if ((digitMap & 0x80) != 0) {\n                segment = scale == SegmentScale.Full ? fullSegment[i] : halfSegment[i];\n                if (scale == SegmentScale.Half && thickness > SegmentStyle.Narrow) {\n                    thickness = SegmentStyle.Narrow;\n                }\n                drawSegment(digit, segment, thickness, color)\n            }\n            digitMap = digitMap << 1;\n        }\n    }\n    \n    /**\n     * Create a seven segment display digit\n     * @param thickness the width of the segments, eg: SegmentStyle.Thick\n     * @param value optional initial display value, eg: 0\n     */\n    //% group=\"Create\"\n    //% blockId=sevenseg_create block=\"seven segment digit || of %thickness with value %value\"\n    //% expandableArgumentMode=toggle\n    //% blockSetVariable=myDigit\n    //% value.min=0 value.max=9 value.defl=0\n    //% weight=99\n    //% help=sevenseg/create-digit\n    export function createDigit(thickness: SegmentStyle = SegmentStyle.Thick, value: number = 0): SevenSegDigit {\n        return new SevenSegDigit(thickness, value)\n    }\n\n    /**\n     * Create a seven segment counter display\n     * @param thickness the width of the segments, eg: SegmentStyle.Thick\n     * @param scale the size of the segments, eg: SegmentScale.Full\n     * @param numDigits the number of digits displayed, eg: 1\n     */\n    //% group=\"Create\"\n    //% blockId=sevenseg_createcounter block=\"counter || of %thickness segments at %scale size with %numDigits digits\"\n    //% expandableArgumentMode=toggle\n    //% blockSetVariable=myCounter\n    //% numDigits.min=1 numDigits.max=5 numDigits.defl=1\n    //% weight=100\n    //% help=sevenseg/create-counter\n    export function createCounter(thickness: SegmentStyle = SegmentStyle.Thick, scale: SegmentScale = SegmentScale.Full, numDigits: number = 1): DigitCounter {\n        return new DigitCounter(thickness, scale, numDigits)\n    }\n}\n\n//% blockNamespace=sevenseg color=\"#4682B4\" blockGap=8\nclass SevenSegDigit {\n    private digit: Image;\n    private digitSprite: Sprite;\n    private _value: number;\n    private thickness: SegmentStyle;\n    private color: number;\n    private scale: SegmentScale;\n    private _x: number;\n    private _y: number;\n    private _radix: number;\n    \n    constructor(thickness: SegmentStyle = SegmentStyle.Thick, value: number = 0) {\n        this._value = value;\n        this.digit = image.create(16, 32);\n        this.digitSprite = sprites.create(this.digit, 0);\n        this._x = this.digitSprite.x\n        this._y = this.digitSprite.y\n        this.thickness = thickness;\n        this.color = 2;\n        this.scale = SegmentScale.Full;\n        this._radix = DigitRadix.Decimal;\n        sevenseg.drawDigit(this.digit, this.value, thickness, this.scale, this.color);\n    }\n\n    /**\n     * Set the display value to a digit character: '0'- '9'\n     * @param alphaChar the display value, eg: \"0\"\n     */\n    //% group=\"Digits\"\n    //% blockId=sevenseg_setalpha block=\"set %sevenseg(myDigit) display value to %alphaChar\"\n    //% weight=40\n    setDigitAlpha(alphaChar: SegmentCharacter) {\n        const matchChars = \"0123456789ABCDEFHJLoPrUY-°\";\n        if (alphaChar == this.value || alphaChar < 0 || alphaChar >= matchChars.length)\n            return;\n        this._value = alphaChar;\n        sevenseg.drawDigit(this.digit, this.value, this.thickness, this.scale, this.color);\n    }\n\n    //% group=\"Digits\" blockSetVariable=\"myDigit\"\n    //% blockCombine block=\"value\" weight=90\n    get value(): number {\n        return this._value;\n    }\n\n    //% group=\"Digits\" blockSetVariable=\"myDigit\"\n    //% blockCombine block=\"value\" weight=90\n    set value(value: number) {\n        value = value | 0;\n        if (value != this.value) {\n            if (value >= 0 && value < this._radix) {\n                this._value = value;\n            } else {\n                this._value = value % this._radix;\n            }\n            sevenseg.drawDigit(this.digit, this._value, this.thickness, this.scale, this.color);\n        }\n    }\n\n    /**\n     * Set the display digit color\n     * @param color of the digit display, eg: 2\n     */\n    //% group=\"Digits\"\n    //% blockId=sevenseg_setcolor block=\"set %sevenseg(myDigit) display color to %color=colorindexpicker\"\n    //% weight=35\n    //% help=sevenseg/sevensegdigit/set-digit-color\n    setDigitColor(color: number): void {\n        this.color = color;\n        sevenseg.drawDigit(this.digit, this.value, this.thickness, this.scale, this.color);\n    }\n\n    //% group=\"Digits\" blockSetVariable=\"myDigit\"\n    //% blockCombine block=\"x\"\n    get x(): number {\n        return this.digitSprite.x;\n    }\n\n    //% group=\"Digits\" blockSetVariable=\"myDigit\"\n    //% blockCombine block=\"x\"\n    set x(v: number) {\n        this._x = v;\n        this.digitSprite.x = v;\n    }\n\n    //% group=\"Digits\" blockSetVariable=\"myDigit\"\n    //% blockCombine block=\"y\"\n    get y(): number {\n        return this.digitSprite.y;\n    }\n\n    //% group=\"Digits\" blockSetVariable=\"myDigit\"\n    //% blockCombine block=\"y\"\n    set y(v: number) {\n        this._y = v;\n        this.digitSprite.y = v;\n    }\n\n    //% group=\"Digits\" blockSetVariable=\"myDigit\"\n    //% blockCombine block=\"width\"\n    get width(): number {\n        return this.digitSprite.width;\n    }\n\n    //% group=\"Digits\" blockSetVariable=\"myDigit\"\n    //% blockCombine block=\"height\"\n    get height(): number {\n        return this.digitSprite.height;\n    }\n\n    /**\n     * Set the display radix of the digit\n     * @param radix of the digit display, eg: DigitRadix.Decimal\n     */\n    //% blockId=sevenseg_setradix block=\"set display radix of %sevenseg(myDigit) to %radix\"\n    //% group=\"Digits\" weight=30\n    //% help=sevenseg/sevensegdigit/set-radix\n    setRadix(radix: DigitRadix) {\n        this._radix = radix;\n        sevenseg.drawDigit(this.digit, this.value, this.thickness, this.scale, this.color);\n    }\n\n    /**\n     * Set the display digit size\n     * @param scale of the digit display, eg: SegmentScale.Full\n     */\n    //% group=\"Digits\"\n    //% blockId=sevenseg_setdigitscale block=\"set %sevenseg(myDigit) to %scale size\"\n    //% weight=25 \n    //% help=sevenseg/sevensegdigit/set-scale\n    setScale(scale: SegmentScale): void {\n        if (scale != this.scale) {\n            this.scale = scale;\n            if (scale == SegmentScale.Full) {\n                this.digit = image.create(16, 32)\n           } else {\n                this.digit = image.create(8, 16)\n           }\n           this.digitSprite.setImage(this.digit);\n           this.digitSprite.x = this._x;\n           this.digitSprite.y = this._y;\n           sevenseg.drawDigit(this.digit, this.value, this.thickness,this.scale, this.color);\n        }\n    }\n}\n\n//% blockNamespace=sevenseg color=\"#4682B4\" blockGap=8\nclass DigitCounter {\n    private _count: number;\n    private limit: number\n    private _x: number;\n    private _y: number;\n    private numDigits: number;\n    private maxDigits: number\n    private digits: SevenSegDigit[];\n    private thickness: SegmentStyle;\n    private color: number;\n    private scale: SegmentScale;\n\n    constructor(thickness: SegmentStyle = SegmentStyle.Thick, scale: SegmentScale = SegmentScale.Full, numDigits: number = 3) {\n        this._count = 0;\n        this.maxDigits = 5;\n        this.color = 2\n        this.scale = scale;\n        numDigits = Math.clamp(1, this.maxDigits, numDigits);\n\n        this.thickness = thickness;\n        this.digits = [];\n        this.digits.push(new SevenSegDigit(this.thickness, 0));\n        this.digits[0].setScale(this.scale);\n        this.digits[0].setDigitColor(this.color);\n        this.numDigits = 1;\n        this.limit = 10;\n        this._x = this.digits[0].x;\n        this._y = this.digits[0].y;\n\n        for (let i = 1; i < numDigits; i++) {\n            this.addDigit();\n        }\n    }\n\n    /**\n     * Add a digit to the counter\n     */\n    addDigit() {\n        let newDigit: SevenSegDigit = null\n        if (this.numDigits < this.maxDigits) {\n            newDigit = new SevenSegDigit(this.thickness, 0);\n            newDigit.setScale(this.scale)\n            newDigit.setDigitColor(this.color)\n            this.digits.push(newDigit);\n            this.numDigits += 1;\n            this.limit = this.limit * 10;\n            this.adjustDigitPositions();\n        }\n    }\n\n    //% group=\"Counter\" blockSetVariable=\"myCounter\"\n    //% blockCombine block=\"count\"\n    get count() {\n        return this._count;\n    }\n\n    //% group=\"Counter\" blockSetVariable=\"myCounter\"\n    //% blockCombine block=\"count\"\n    set count(value: number) {\n        if (value >= 0 && value < this.limit) {\n            this._count = value;\n            this.updateDisplayValue()\n        }\n    }\n\n    private updateDisplayValue()\n    {\n        let decimator = 1;\n        let updateValue = 0;\n        for (let i = 0; i < this.digits.length; i++) {\n            updateValue = this._count / decimator % 10;\n            this.digits[i].value = updateValue;\n            decimator = decimator * 10;\n        }\n    }\n\n    private adjustDigitPositions() {\n        let spacing = this.digits[0].width * 4 / 3;\n        let offset = this.digits[0].x + spacing / 2;\n        for (let i = 0; i < this.numDigits; i++) {\n            this.digits[i].x = offset;\n            offset -= spacing;\n        }\n    }\n\n    private moveDigits() {\n        let spacing = this.digits[0].width * 4 / 3;\n        for (let i = 1; i < this.numDigits; i++) {\n            this.digits[i].x = this.digits[i - 1].x - spacing;\n            this.digits[i].y = this.digits[0].y;\n        }\n        this._x = (this.digits[0].x + this.digits[this.numDigits - 1].x) / 2;\n        this._y = this.digits[0].y;\n    }\n    \n    /**\n     * Set the counter display digit color\n     * @param color of the digit display, eg: 2\n     */\n    //% group=\"Counter\"\n    //% blockId=sevenseg_setcountercolor block=\"set %sevenseg(myCounter) display color to %color=colorindexpicker\"\n    //% weight=86\n    //% help=sevenseg/digitcounter/set-digit-color\n    setDigitColor(color: number): void {\n        this.color = color;\n        for (let i = 0; i < this.numDigits; i++) {\n            this.digits[i].setDigitColor(color);\n        }\n    }\n\n    //% group=\"Counter\" blockSetVariable=\"myCounter\"\n    //% blockCombine block=\"x\"\n    get x(): number {\n        return this._x;\n    }\n\n    //% group=\"Counter\" blockSetVariable=\"myCounter\"\n    //% blockCombine block=\"x\"\n    set x(v: number) {\n        this.digits[0].x += v - this._x;\n        this.moveDigits()\n    }\n\n    //% group=\"Counter\" blockSetVariable=\"myCounter\"\n    //% blockCombine block=\"y\"\n    get y(): number {\n        return this._y;\n    }\n\n    //% group=\"Counter\" blockSetVariable=\"myCounter\"\n    //% blockCombine block=\"y\"\n    set y(v: number) {\n        this.digits[0].y = v;\n        this.moveDigits()\n    }\n}\n"},"shader":{"pxt.json":"{\n    \"name\": \"shader\",\n    \"description\": \"Utility methods for shading images\",\n    \"dependencies\": {\n        \"core\": \"*\",\n        \"screen\": \"*\"\n    },\n    \"files\": [\n        \"shader.cpp\",\n        \"shader.ts\",\n        \"shims.d.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true\n}\n","shader.cpp":"#include \"pxt.h\"\n\n#define XX(v) (int)(((int16_t)(v)))\n#define YY(v) (int)(((int16_t)(((int32_t)(v)) >> 16)))\n\nnamespace ShaderMethods {\n\nvoid mapImage(Image_ toShade, Image_ shadeLevels, int x, int y, Buffer map) {\n    if (x >= toShade->width() || y >= toShade->height())\n        return;\n\n    if (toShade->bpp() != 4 || shadeLevels->bpp() != 4 || map->length < 16 || map->length % 16 != 0)\n        return;\n\n    int maxShadeLevel = map->length >> 4;\n\n    int x2 = x + shadeLevels->width() - 1;\n    int y2 = y + shadeLevels->height() - 1;\n\n    if (x2 < 0 || y2 < 0)\n        return;\n\n    int x0 = x;\n    int y0 = y;\n\n    toShade->clamp(&x2, &y2);\n    toShade->clamp(&x, &y);\n    int w = x2 - x + 1;\n    int h = y2 - y + 1;\n\n    toShade->makeWritable();\n\n    auto mapData = map->data;\n\n    auto toShadeByteHeight = toShade->byteHeight();\n    uint8_t *toShadeAddr = toShade->pix(x, y);\n\n    auto shadeLevelsByteHeight = shadeLevels->byteHeight();\n    uint8_t *shadeLevelsAddr = shadeLevels->pix(x - x0, y - y0);\n\n    while (w-- > 0) {\n        auto ptr1 = toShadeAddr;\n        auto ptr2 = shadeLevelsAddr;\n        unsigned shift1 = y & 1;\n        unsigned shift2 = (y - y0) & 1;\n        uint8_t shadeLevel = 0;\n        for (int i = 0; i < h; i++) {\n            if (shift2) {\n                shadeLevel = min(*ptr2 >> 4, maxShadeLevel);\n                ptr2++;\n                shift2 = 0;\n            } else {\n                shadeLevel = min(*ptr2 & 0x0f, maxShadeLevel);\n                shift2 = 1;\n            }\n\n            if (shift1) {\n                *ptr1 = (mapData[(*ptr1 >> 4) + (shadeLevel << 4)] << 4) | (*ptr1 & 0x0f);\n                ptr1++;\n                shift1 = 0;\n            } else {\n                *ptr1 = (mapData[(*ptr1 & 0xf) + (shadeLevel << 4)] & 0xf) | (*ptr1 & 0xf0);\n                shift1 = 1;\n            }\n        }\n        toShadeAddr += toShadeByteHeight;\n        shadeLevelsAddr += shadeLevelsByteHeight;\n    }\n}\n\nvoid mergeImage(Image_ dst, Image_ src, int x, int y) {\n    if (x >= dst->width() || y >= dst->height())\n        return;\n\n    if (dst->bpp() != 4 || src->bpp() != 4)\n        return;\n\n    int x2 = x + src->width() - 1;\n    int y2 = y + src->height() - 1;\n\n    if (x2 < 0 || y2 < 0)\n        return;\n\n    int x0 = x;\n    int y0 = y;\n\n    dst->clamp(&x2, &y2);\n    dst->clamp(&x, &y);\n    int w = x2 - x + 1;\n    int h = y2 - y + 1;\n\n    dst->makeWritable();\n\n    auto dstByteHeight = dst->byteHeight();\n    uint8_t *dstAddr = dst->pix(x, y);\n\n    auto srcByteHeight = src->byteHeight();\n    uint8_t *srcAddr = src->pix(x - x0, y - y0);\n\n    while (w-- > 0) {\n        auto ptr1 = dstAddr;\n        auto ptr2 = srcAddr;\n        unsigned shift1 = y & 1;\n        unsigned shift2 = (y - y0) & 1;\n        int srcValue = 0;\n        for (int i = 0; i < h; i++) {\n            if (shift2) {\n                srcValue = *ptr2 >> 4;\n                ptr2++;\n                shift2 = 0;\n            } else {\n                srcValue = *ptr2 & 0x0f;\n                shift2 = 1;\n            }\n\n            if (shift1) {\n                *ptr1 = (min(*ptr1 >> 4, srcValue) << 4) | (*ptr1 & 0x0f);\n                ptr1++;\n                shift1 = 0;\n            } else {\n                *ptr1 = (min(*ptr1 & 0xf, srcValue) & 0xf) | (*ptr1 & 0xf0);\n                shift1 = 1;\n            }\n        }\n        dstAddr += dstByteHeight;\n        srcAddr += srcByteHeight;\n    }\n}\n\n//%\nvoid _mapImage(Image_ toShade, Image_ shadeLevels, int xy, Buffer c) {\n    mapImage(toShade, shadeLevels, XX(xy), YY(xy), c);\n}\n\n//%\nvoid _mergeImage(Image_ toShade, Image_ shadeLevels, int xy) {\n    mergeImage(toShade, shadeLevels, XX(xy), YY(xy));\n}\n\n}","shader.ts":"namespace helpers {\n    //% shim=ShaderMethods::_mapImage\n    function _mapImage(toShade: Image, shadeLevels: Image, xy: number, m: Buffer): void { }\n\n    export function mapImage(toShade: Image, shadeLevels: Image, x: number, y: number, m: Buffer) {\n        _mapImage(toShade, shadeLevels, pack(x, y), m);\n    }\n\n    //% shim=ShaderMethods::_mergeImage\n    function _mergeImage(dst: Image, src: Image, xy: number): void { }\n\n    export function mergeImage(dst: Image, src: Image, x: number, y: number) {\n        _mergeImage(dst, src, pack(x, y));\n    }\n\n    function pack(x: number, y: number) {\n        return (Math.clamp(-30000, 30000, x | 0) & 0xffff) | (Math.clamp(-30000, 30000, y | 0) << 16)\n    }\n}","shims.d.ts":"// Auto-generated. Do not edit.\n\n\ndeclare interface Shader {}\n\n// Auto-generated. Do not edit. Really.\n"},"sprite-scaling":{"README.md":"# Sprite Scaling\n\nAdditional sprite scaling methods.\n","pxt.json":"{\n    \"name\": \"sprite-scaling\",\n    \"description\": \"Additional scaling blocks for sprites\",\n    \"dependencies\": {\n        \"game\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"scaling.ts\",\n        \"targetoverrides.ts\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"weight\": 80,\n    \"icon\": \"/static/libs/sprite-scaling.png\"\n}\n","scaling.ts":"//% color=\"#95078E\" weight=99 icon=\"\\uf338\"\nnamespace scaling {\n    /**\n    * Scale a sprite to a percentage of its original size.\n    * @param sprite to scale to a percentage of its original size\n    * @param value that is the percentage to scale the sprite, eg: 150\n    * @param direction from the sprite anchor point, eg: ScaleDirection.Uniformly\n    */\n    //% blockId=sprite_scale_to_percent_ex\n    //% block=\"set $sprite=variables_get(mySprite) scale to $value percent $direction anchor $anchor\"\n    //% expandableArgumentMode=enabled\n    //% inlineInputMode=inline\n    //% value.defl=150\n    //% direction.defl=ScaleDirection.Uniformly\n    //% anchor.defl=ScaleAnchor.Middle\n    //% help=sprites/scaling/scale-to-percent\n    export function scaleToPercent(sprite: Sprite, value: number, direction?: ScaleDirection, anchor?: ScaleAnchor): void {\n        value /= 100;\n        direction = direction || ScaleDirection.Uniformly;\n        anchor = anchor || ScaleAnchor.Middle;\n\n        let sx: number;\n        let sy: number;\n\n        if (direction & ScaleDirection.Horizontally) sx = value;\n        if (direction & ScaleDirection.Vertically) sy = value;\n\n        sprite.setScaleCore(sx, sy, anchor);\n    }\n\n    /**\n    * Scale a sprite by a percentage of its original size.\n    * @param sprite to scale to a percentage of its original size\n    * @param value that is the percentage to scale the sprite by, eg: 50\n    * @param direction from the sprite anchor point, eg: ScaleDirection.Uniformly\n    */\n    //% blockId=sprite_scale_by_percent_ex\n    //% block=\"change $sprite=variables_get(mySprite) scale by $value percent $direction anchor $anchor\"\n    //% expandableArgumentMode=enabled\n    //% inlineInputMode=inline\n    //% value.defl=50\n    //% direction.defl=ScaleDirection.Uniformly\n    //% anchor.defl=ScaleAnchor.Middle\n    //% help=sprites/scaling/scale-by-percent\n    export function scaleByPercent(sprite: Sprite, value: number, direction?: ScaleDirection, anchor?: ScaleAnchor): void {\n        value /= 100;\n        direction = direction || ScaleDirection.Uniformly;\n        anchor = anchor || ScaleAnchor.Middle;\n\n        let sx: number;\n        let sy: number;\n\n        if (direction & ScaleDirection.Horizontally) sx = sprite.sx + value;\n        if (direction & ScaleDirection.Vertically) sy = sprite.sy + value;\n\n        sprite.setScaleCore(sx, sy, anchor);\n    }\n\n    /**\n    * Scale a sprite to a number of pixels.\n    * @param sprite to scale to new pixel size\n    * @param value that is the number of pixels to scale the sprite to, eg: 32\n    * @param direction from the sprite anchor point, eg: ScaleDirection.Horizontally\n    */\n    //% blockId=sprite_scale_to_pixels_ex\n    //% block=\"set $sprite=variables_get(mySprite) scale to $value pixels $direction anchor $anchor || proportional $proportional\"\n    //% expandableArgumentMode=enabled\n    //% inlineInputMode=inline\n    //% value.defl=32\n    //% direction.defl=ScaleDirection.Horizontally\n    //% anchor.defl=ScaleAnchor.Middle\n    //% proportional.defl=0\n    //% help=sprites/scaling/scale-to-pixels\n    export function scaleToPixels(sprite: Sprite, value: number, direction?: ScaleDirection, anchor?: ScaleAnchor, proportional?: boolean): void {\n        direction = direction || ScaleDirection.Horizontally;\n        anchor = anchor || ScaleAnchor.Middle;\n\n        if (proportional == null) proportional = direction === ScaleDirection.Uniformly;\n\n        let sx: number;\n        let sy: number;\n\n        if (direction & ScaleDirection.Horizontally) {\n            const imgW = sprite.image.width;\n            const newW = value;\n            sx = newW / imgW;\n        }\n\n        if (direction & ScaleDirection.Vertically) {\n            const imgH = sprite.image.height;\n            const newH = value;\n            sy = newH / imgH;\n        }\n\n        sprite.setScaleCore(sx, sy, anchor, proportional);\n    }\n\n    /**\n    * Scale a sprite by a number of pixels.\n    * @param sprite to scale to new pixel size\n    * @param value that is the number of pixels to scale the sprite by, eg: 10\n    * @param direction from the sprite anchor point, eg: ScaleDirection.Horizontally\n    */\n    //% blockId=sprite_scale_by_pixels_ex\n    //% block=\"change $sprite=variables_get(mySprite) scale by $value pixels $direction anchor $anchor || proportional $proportional\"\n    //% expandableArgumentMode=enabled\n    //% inlineInputMode=inline\n    //% value.defl=10\n    //% direction.defl=ScaleDirection.Horizontally\n    //% anchor.defl=ScaleAnchor.Middle\n    //% proportional.defl=0\n    //% help=sprites/scaling/scale-by-pixels\n    export function scaleByPixels(sprite: Sprite, value: number, direction?: ScaleDirection, anchor?: ScaleAnchor, proportional?: boolean): void {\n        direction = direction || ScaleDirection.Horizontally;\n        anchor = anchor || ScaleAnchor.Middle;\n\n        if (proportional == null) proportional = direction === ScaleDirection.Uniformly;\n\n        let sx: number;\n        let sy: number;\n\n        if (direction & ScaleDirection.Horizontally) {\n            const imgW = sprite.image.width;\n            const newW = sprite.width + value;\n            sx = newW / imgW;\n        }\n\n        if (direction & ScaleDirection.Vertically) {\n            const imgH = sprite.image.height;\n            const newH = sprite.height + value;\n            sy = newH / imgH;\n        }\n\n        sprite.setScaleCore(sx, sy, anchor, proportional);\n    }\n}","targetoverrides.ts":"// TODO any platform specific overrides","test.ts":""},"storyboard":{"README.md":"# Storyboard\n\nOrchestrate scenes","loader.ts":"namespace storyboard {\n    function loader(done: () => void) {\n        const font = image.font8;\n        let m = 40;\n        let w = screen.width - 2 * m;\n        let c = 2;\n        let y = screen.height / 2 - c;\n        let x = 0;\n        game.onPaint(function() {\n            screen.printCenter(\"MakeCode Arcade\", y - font.charHeight - c, 1, font);\n            screen.drawRect(m, y, w, 2 * c, 1)\n            screen.fillRect(m, y + 1, x, 2 * c - 2, 3);\n\n            x++;\n            if (x == w) done();\n        })\n    }\n\n    /**\n     * Default boot sequence\n     */\n    //% block=\"loader\" fixedInstance whenUsed\n    export const loaderBootSequence = new BootSequence(loader, 0);\n}","pxt.json":"{\n    \"name\": \"storyboard\",\n    \"description\": \"Scene manager\",\n    \"dependencies\": {\n        \"game\": \"*\",\n        \"color\": \"*\",\n        \"palette\": \"*\"\n    },\n    \"files\": [\n        \"storyboard.ts\",\n        \"loader.ts\",\n        \"README.md\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"searchOnly\": true,\n    \"weight\": 81,\n    \"icon\": \"/static/libs/storyboard.png\"\n}\n","storyboard.ts":"/**\n * A manager of scenes\n */\n//% icon=\"\\uf009\"\n//% weight=87 color=\"#401255\"\nnamespace storyboard {\n    export interface FrameOptions {\n        background?: number;\n    }\n\n    export class Frame {\n        start: () => void;\n        options: FrameOptions;\n\n        constructor(start: () => void, options: FrameOptions) {\n            this.start = start;\n            this.options = options || {};\n        }\n    }\n\n    //% fixedInstances\n    export class BootSequence {\n        start: (done: () => void) => void;\n        background: number;\n        constructor(start: (done: () => void) => void, background: number) {\n            this.start = start;\n            this.background = background;\n        }\n\n        /**\n         * Registers the boot sequence\n         */\n        //% block=\"storyboard register %boot| boot sequence\" blockId=storyboardregister\n        register() {\n            registerBootSequence(this);\n        }\n    }\n\n    let _boots: BootSequence[];\n    let _scenes: {\n        [index: string]: Frame\n    };\n    let _nav: Frame[];\n\n    function registerBootSequence(boot: BootSequence) {\n        if (!_boots)\n            _boots = [];\n        if (_boots.indexOf(boot) < 0)\n            _boots.push(boot);\n    }\n\n    /**\n     * Registers a scene\n     * @param name \n     * @param scene \n     */\n    export function registerScene(name: string, start: () => void, options?: FrameOptions) {\n        if (!name) return;\n        if (!_scenes) {\n            _scenes = {};\n        }\n        _scenes[name] = new Frame(start, options);\n    }\n\n    function fadeBackground(last: BootSequence, next: BootSequence) {\n        if (last.background == next.background) return;\n\n        const fadeLength = palette.defaultPalette().length;\n        const fadeGradient = color.gradient(\n            last.background,\n            next.background,\n            fadeLength\n        );\n\n        palette.setColors(fadeGradient);\n        for (let i = 0; i < fadeLength; i++) {\n            scene.setBackgroundColor(i);\n            pause(50);\n        }\n        scene.setBackgroundColor(0xf);\n        palette.reset();\n    }\n\n    function consumeBootSequence() {\n        // run boot sequences if any\n        let boot: BootSequence;\n        let previous: BootSequence;\n        while (boot = _boots && _boots.shift()) {\n            game.pushScene();\n            if (previous)\n                fadeBackground(previous, boot);\n            let isDone = false;\n            boot.start(() => isDone = true);\n            pauseUntil(() => isDone);\n            game.popScene();\n            previous = boot;\n        }\n    }\n\n    /**\n     * Starts the story board by running boot sequences then entering a scene\n     * @param name \n     */\n    //% block=\"storyboard start at $name\" blockId=storyboardstart\n    export function start(name?: string) {\n        consumeBootSequence();\n        // grab the first frame\n        push(name || (_scenes && Object.keys(_scenes)[0]));\n    }\n\n    function isActive(name: string): boolean {\n        const scene = name && _scenes && _scenes[name];\n        return scene && (_nav && _nav.length && _nav[_nav.length - 1] == scene);\n    }\n\n    /**\n     * Replace the current scene with the given scene\n     * @param name \n     */\n    //% block=\"storyboard replace scene $name\" blockId=storyboardreplace\n    export function replace(name: string) {\n        if (isActive(name)) return;\n\n        const scene = name && _scenes && _scenes[name];\n        if (!scene) return; // not found\n\n        if (!_nav) _nav = [];\n        if (_nav.length) {\n            _nav.pop();\n            game.popScene();\n        }\n        _nav.push(scene);\n        game.pushScene();\n        scene.start();\n    }\n\n    /**\n     * Transition to a registered scene\n     * @param name \n     */\n    //% block=\"storyboard push scene $name\" blockId=storyboardpush\n    export function push(name: string) {\n        if (isActive(name)) return;\n\n        const scene = name && _scenes && _scenes[name];\n        if (!scene) return; // not found\n\n        if (!_nav) _nav = [];\n        if (_nav.length) {\n            game.popScene();\n        }\n        _nav.push(scene);\n        game.pushScene();\n        scene.start();\n    }\n\n    /**\n     * Stops the current scene and restart the previous scene\n     */\n    //% block=\"storyboard pop frame\" blockId=storyboardpop\n    export function pop() {\n        const n = _nav && _nav.pop();\n        if (n) {\n            game.popScene();\n        }\n        // restart previous\n        if (_nav && _nav.length) {\n            const sc = _nav[_nav.length - 1];\n            game.pushScene();\n            sc.start();\n        }\n    }\n}","test.ts":"let mySprite = sprites.create(img`\n    . . . . . . b b b b a a . . . .\n    . . . . b b d d d 3 3 3 a a . .\n    . . . b d d d 3 3 3 3 3 3 a a .\n    . . b d d 3 3 3 3 3 3 3 3 3 a .\n    . b 3 d 3 3 3 3 3 b 3 3 3 3 a b\n    . b 3 3 3 3 3 a a 3 3 3 3 3 a b\n    b 3 3 3 3 3 a a 3 3 3 3 d a 4 b\n    b 3 3 3 3 b a 3 3 3 3 3 d a 4 b\n    b 3 3 3 3 3 3 3 3 3 3 d a 4 4 e\n    a 3 3 3 3 3 3 3 3 3 d a 4 4 4 e\n    a 3 3 3 3 3 3 3 d d a 4 4 4 e .\n    a a 3 3 3 d d d a a 4 4 4 e e .\n    . e a a a a a a 4 4 4 4 e e . .\n    . . e e b b 4 4 4 4 b e e . . .\n    . . . e e e e e e e e . . . . .\n    . . . . . . . . . . . . . . . .\n`, SpriteKind.Player)\nmySprite.x = 10\ncontroller.moveSprite(mySprite)\nstoryboard.loaderBootSequence.register()\nstoryboard.registerScene(\"lemon\", function () {\n    let mySprite2 = sprites.create(img`\n        4 4 4 . . 4 4 4 4 4 . . . . . .\n        4 5 5 4 4 5 5 5 5 5 4 4 . . . .\n        b 4 5 5 1 5 1 1 1 5 5 5 4 . . .\n        . b 5 5 5 5 1 1 5 5 1 1 5 4 . .\n        . b d 5 5 5 5 5 5 5 5 1 1 5 4 .\n        b 4 5 5 5 5 5 5 5 5 5 5 1 5 4 .\n        c d 5 5 5 5 5 5 5 5 5 5 5 5 5 4\n        c d 4 5 5 5 5 5 5 5 5 5 5 1 5 4\n        c 4 5 5 5 d 5 5 5 5 5 5 5 5 5 4\n        c 4 d 5 4 5 d 5 5 5 5 5 5 5 5 4\n        . c 4 5 5 5 5 d d d 5 5 5 5 5 b\n        . c 4 d 5 4 5 d 4 4 d 5 5 5 4 c\n        . . c 4 4 d 4 4 4 4 4 d d 5 d c\n        . . . c 4 4 4 4 4 4 4 4 5 5 5 4\n        . . . . c c b 4 4 4 b b 4 5 4 4\n        . . . . . . c c c c c c b b 4 .\n    `, SpriteKind.Player)\n    mySprite2.y = 20\n    controller.moveSprite(mySprite2)\n    controller.A.onEvent(ControllerButtonEvent.Pressed, function () {\n        storyboard.push(\"burger\");\n    })\n    controller.B.onEvent(ControllerButtonEvent.Pressed, function () {\n        storyboard.pop();\n    })\n})\nstoryboard.registerScene(\"burger\", function () {\n    let mySprite3 = sprites.create(img`\n        . . . . c c c b b b b b . . . .\n        . . c c b 4 4 4 4 4 4 b b b . .\n        . c c 4 4 4 4 4 5 4 4 4 4 b c .\n        . e 4 4 4 4 4 4 4 4 4 5 4 4 e .\n        e b 4 5 4 4 5 4 4 4 4 4 4 4 b c\n        e b 4 4 4 4 4 4 4 4 4 4 5 4 4 e\n        e b b 4 4 4 4 4 4 4 4 4 4 4 b e\n        . e b 4 4 4 4 4 5 4 4 4 4 b e .\n        8 7 e e b 4 4 4 4 4 4 b e e 6 8\n        8 7 2 e e e e e e e e e e 2 7 8\n        e 6 6 2 2 2 2 2 2 2 2 2 2 6 c e\n        e c 6 7 6 6 7 7 7 6 6 7 6 c c e\n        e b e 8 8 c c 8 8 c c c 8 e b e\n        e e b e c c e e e e e c e b e e\n        . e e b b 4 4 4 4 4 4 4 4 e e .\n        . . . c c c c c e e e e e . . .\n    `, SpriteKind.Player)\n    mySprite3.y = 80\n    controller.moveSprite(mySprite3)\n    controller.A.onEvent(ControllerButtonEvent.Pressed, function () {\n        storyboard.replace(\"lemon\");\n    })\n    controller.B.onEvent(ControllerButtonEvent.Pressed, function () {\n        storyboard.pop()\n    })\n})\ncontroller.A.onEvent(ControllerButtonEvent.Pressed, function () {\n    storyboard.start(\"lemon\")\n})\ncontroller.B.onEvent(ControllerButtonEvent.Pressed, function () {\n    storyboard.start(\"burger\")\n})\n\n"},"template":{".gitattributes":"index.html linguist-generated=true\nassets/index.html linguist-generated=true\nassets/js/loader.js linguist-generated=true\nassets/js/binary.js linguist-generated=true\nassets/version.txt linguist-generated=true\n",".github/workflows/makecode-release.yml":"name: MakeCode Arcade Release\n\non: \n  release:\n    types:\n      - created\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        node-version: [8.x]\n\n    steps:\n      - uses: actions/checkout@v1\n      - name: install node.js ${{ matrix.node-version }}\n        uses: actions/setup-node@v1\n        with:\n          node-version: ${{ matrix.node-version }}\n      - name: install makecode\n        run: |\n          npm install -g pxt\n          pxt target arcade\n      - name: build js\n        run: |\n          pxt clean\n          pxt install\n          pxt build --cloud\n      - name: build D51\n        continue-on-error: true\n        run: |\n          pxt clean\n          pxt install --hw samd51\n          pxt build --hw samd51 --cloud\n          cp ./built/binary.uf2 binary-d51.uf2\n      - name: build F4\n        continue-on-error: true\n        run: |\n          pxt clean\n          pxt install --hw stm32f401\n          pxt build --hw stm32f401 --cloud\n          cp ./built/binary.uf2 binary-f4.uf2\n      - name: build P0\n        continue-on-error: true\n        run: |\n          pxt clean\n          pxt install --hw rpi\n          pxt build --hw rpi --cloud\n          cp ./built/binary.uf2 binary-p0.uf2\n      - name: bundle all\n        run: |\n          cat binary-*.uf2 > built/arcade.uf2\n      - name: upload bundled\n        uses: actions/upload-release-asset@v1.0.1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          upload_url: ${{ github.event.release.upload_url }}\n          asset_path: ./built/arcade.uf2\n          asset_name: arcade.uf2\n          asset_content_type: application/octet-stream","assets/index.html":"<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <script type=\"text/javascript\" src=\"./js/loader.js\"></script>\n    <script type=\"text/javascript\" src=\"./js/custom.js\"></script>\n    <style>\n        body {\n            background: black;\n            color: white;\n            font-family: monospace;\n            overflow: hidden;\n            font-size: 14pt;\n        }\n\n        iframe {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            border: none;\n        }\n        #fullscreen {\n            position: absolute;\n            right: 0.25rem;\n            bottom: 0;\n            cursor: pointer;\n        }\n        .lds-ripple {\n            width: 80px;\n            height: 80px;\n            margin: auto;\n            position: absolute;\n            margin: auto;\n            top: 0;\n            right: 0;\n            bottom: 0;\n            left: 0;\n            z-index: -1;\n        }\n\n        .lds-ripple div {\n            position: absolute;\n            border: 4px solid #fff;\n            opacity: 1;\n            border-radius: 50%;\n            animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite;\n        }\n\n        .lds-ripple div:nth-child(2) {\n            animation-delay: -0.5s;\n        }\n\n        @keyframes lds-ripple {\n            0% {\n                top: 36px;\n                left: 36px;\n                width: 0;\n                height: 0;\n                opacity: 1;\n            }\n\n            100% {\n                top: 0px;\n                left: 0px;\n                width: 72px;\n                height: 72px;\n                opacity: 0;\n            }\n        }\n    </style>\n</head>\n\n<body id=\"root\">\n    <div id=\"loader\" class=\"lds-ripple\">\n        <div></div>\n        <div></div>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" x=\"0\" y=\"0\" viewBox=\"0 0 32 32\" xml:space=\"preserve\"\n            id=\"svg2\">\n            <style type=\"text/css\" id=\"style4\"></style>\n            <g id=\"g4212\" transform=\"matrix(.79626 0 0 .79626 -68.322 9.868)\">\n                <path\n                    d=\"M105.989-5.487v.01a1.91 1.91 0 00-1.613 1.83c0 .779.417 1.119.417 1.15.413.435.238.913-.589.874 0 0-3.009.015-3.066 0a.724.724 0 00-.53.696v9.894c-.001.39.314.705.705.705h9.848c.39 0 .705-.314.705-.705V5.475c-.126-.423-.489-.463-.827-.141-.032 0-.369.417-1.147.417-.93-.03-1.69-.72-1.83-1.616h-.013a6.771 6.771 0 010-.494h.012c.142-.897.9-1.587 1.83-1.616.78 0 1.116.417 1.148.417.329.313.695.238.827-.138V-.927a.72.72 0 00-.527-.696c-.057.015-3.07 0-3.07 0-.74.06-.998-.44-.585-.874 0-.031.417-.371.417-1.15-.029-.93-.72-1.69-1.616-1.83v-.01a6.241 6.241 0 00-.496 0z\"\n                    id=\"path167\" fill=\"#fff\" fill-opacity=\"1\" stroke-width=\"1.57\" />\n                <path\n                    d=\"M98.633-7.18c-.917 0-1.624.252-2.158.774-.534.521-.802 1.208-.822 2.094a552.379 552.379 0 01-.062 2.732c-.02.776-.081 1.354-.187 1.766-.118.46-.331.853-.637 1.168-.272.28-.684.587-1.254.938-.255.156-.368.387-.368.748 0 .351.077.481.11.521.12.145.32.3.592.463.376.226.702.494.972.795.3.334.518.786.662 1.38.052.213.112.882.172 4.228.006.566.138 1.07.39 1.502.25.431.584.753 1.02.984.443.235.971.356 1.57.356.974 0 1.055-.377 1.055-.764 0-.266-.054-.465-.157-.591a.501.501 0 00-.334-.2c-.374-.042-.66-.103-.87-.187a1.29 1.29 0 01-.678-.622c-.127-.244-.206-.588-.242-1.049a22.82 22.82 0 01-.046-1.68c0-.707-.034-1.327-.099-1.846a4.868 4.868 0 00-.31-1.26 2.848 2.848 0 00-.52-.843 4.267 4.267 0 00-.874-.702l-.773-.485.773-.487c.502-.318.88-.657 1.128-1.012.244-.35.413-.783.503-1.282.099-.55.153-1.333.169-2.333 0-.713.014-1.247.042-1.625.032-.437.105-.774.221-1.027.147-.317.382-.548.68-.672.214-.086.506-.152.896-.205a.429.429 0 00.224-.089.622.622 0 00.178-.251 1.11 1.11 0 00.089-.451c0-.268-.07-.45-.215-.57-.175-.144-.456-.215-.84-.215z\"\n                    id=\"path165\" fill=\"#fff\" fill-opacity=\"1\" stroke-width=\"1.57\" />\n                <path\n                    d=\"M113.887-7.182c-.974 0-1.055.377-1.055.763 0 .267.05.467.153.592.1.12.205.182.338.2.374.042.658.103.867.186.294.116.524.326.678.623.127.245.206.588.242 1.048.032.397.046.945.046 1.68 0 .708.034 1.328.098 1.846.06.49.166.917.31 1.264.138.332.313.616.521.843.22.239.511.473.871.699l.773.487-.77.488c-.502.317-.882.656-1.128 1.009-.244.35-.414.78-.503 1.278-.099.551-.154 1.338-.169 2.337 0 .712-.015 1.246-.043 1.625-.03.437-.1.77-.217 1.024a1.294 1.294 0 01-.68.674c-.214.087-.506.154-.896.206a.44.44 0 00-.227.089.64.64 0 00-.178.251c-.06.135-.086.282-.086.45 0 .268.066.45.212.571.174.144.458.218.843.218.917 0 1.62-.254 2.155-.776.534-.522.802-1.205.822-2.091.023-1.095.046-2.007.064-2.735.02-.777.079-1.355.184-1.766.12-.46.333-.854.638-1.168.273-.28.684-.587 1.254-.938.254-.157.368-.385.368-.746 0-.35-.077-.483-.11-.524-.119-.143-.316-.298-.589-.463a4.268 4.268 0 01-.975-.794c-.3-.334-.515-.784-.66-1.377-.051-.213-.114-.885-.174-4.23-.007-.568-.138-1.072-.39-1.503a2.524 2.524 0 00-1.02-.984c-.443-.235-.968-.356-1.567-.356z\"\n                    id=\"path163\" fill=\"#fff\" fill-opacity=\"1\" stroke-width=\"1.57\" />\n            </g>\n            <path\n                d=\"M28.621 31.422c.224-.102.208 1.099.208-15.49 0-16.588.016-15.388-.208-15.49-.144-.065-24.6-.065-24.744 0-.223.102-.207-1.1-.206 15.498.001 12.58.01 15.259.052 15.334.112.203-.702.19 12.515.192 9.446.001 12.307-.01 12.383-.044zm-9.415-1.705c-.283-.11-.57-.4-.678-.687a1.216 1.216 0 011.131-1.655c.669 0 1.213.544 1.213 1.213 0 .853-.862 1.437-1.666 1.129zm-8.337-1.054v-.757H9.353v-1.668h1.516V24.723H12.536V26.238h1.516v1.668h-1.516V29.42H10.869zm10.99-1.22c-.284-.109-.57-.399-.678-.686a1.204 1.204 0 01.276-1.298c.762-.762 2.067-.222 2.067.855 0 .854-.862 1.438-1.666 1.13zM4.765 23.475l-.111-.11V1.377l.11-.111.111-.11h22.746l.11.11.112.11V23.366l-.111.11-.11.111H4.875z\"\n                id=\"path4210\" fill=\"#fff\" fill-opacity=\"1\" />\n        </svg>\n    </div>\n    <iframe id=\"simframe\" allowfullscreen=\"allowfullscreen\"\n        sandbox=\"allow-popups allow-forms allow-scripts allow-same-origin\">\n    </iframe>\n    <div id=\"fullscreen\">⇲</div>\n    <script type=\"text/javascript\">\nmakeCodeRun({ js: \"./js/binary.js\"})\n        </script>\n</body>\n</html>\n","assets/js/custom.js":"/**\n * This will be loaded before starting the simulator.\n * If you wish to add custom javascript, \n * ** make sure to add this line to pxt.json**\n * \n *      \"disableTargetTemplateFiles\": true\n * \n * otherwise MakeCode will override your changes.\n * \n * To register a constrol simmessages, use addSimMessageHandler\n */\n","assets/js/loader.js":"var channelHandlers = {}\n\nfunction addSimMessageHandler(channel, handler) {\n    channelHandlers[channel] = handler;\n}\n\nfunction makeCodeRun(options) {\n    var code = \"\";\n    var isReady = false;\n    var simState = {}\n    var simStateChanged = false\n    var started = false;\n    var meta = undefined;\n\n    // hide scrollbar\n    window.scrollTo(0, 1);\n    // init runtime\n    initSimState();\n    fetchCode();\n\n    // helpers\n    function fetchCode() {\n        sendReq(options.js, function (c, status) {\n            if (status != 200)\n                return;\n            code = c;\n            // find metadata\n            code.replace(/^\\/\\/\\s+meta=([^\\n]+)\\n/m, function (m, metasrc) {\n                meta = JSON.parse(metasrc);\n            })\n            var vel = document.getElementById(\"version\");\n            if (meta.version && meta.repo && vel) {\n                var ap = document.createElement(\"a\");\n                ap.download = \"arcade.uf2\";\n                ap.href = \"https://github.com/\" + meta.repo + \"/releases/download/v\" + meta.version + \"/arcade.uf2\";\n                ap.innerText = \"v\" + meta.version;\n                vel.appendChild(ap);\n            }\n            // load simulator with correct version\n            document.getElementById(\"simframe\")\n                .setAttribute(\"src\", meta.simUrl);\n            initFullScreen();\n        })\n    }\n\n    function startSim() {\n        if (!code || !isReady || started)\n            return\n        setState(\"run\");\n        started = true;\n        const runMsg = {\n            type: \"run\",\n            parts: [],\n            code: code,\n            partDefinitions: {},\n            cdnUrl: meta.cdnUrl,\n            version: meta.target,\n            storedState: simState,\n            frameCounter: 1,\n            options: {\n                \"theme\": \"green\",\n                \"player\": \"\"\n            },\n            id: \"green-\" + Math.random()\n        }\n        postMessage(runMsg);\n    }\n\n    function stopSim() {\n        setState(\"stopped\");\n        postMessage({\n            type: \"stop\"\n        });\n        started = false;\n    }\n\n    window.addEventListener('message', function (ev) {\n        var d = ev.data\n        if (d.type == \"ready\") {\n            var loader = document.getElementById(\"loader\");\n            if (loader)\n                loader.remove();\n            isReady = true;\n            startSim();\n        } else if (d.type == \"simulator\") {\n            switch (d.command) {\n                case \"restart\":\n                    stopSim();\n                    startSim();\n                    break;\n                case \"setstate\":\n                    if (d.stateValue === null)\n                        delete simState[d.stateKey];\n                    else\n                        simState[d.stateKey] = d.stateValue;\n                    simStateChanged = true;\n                    break;\n            }\n        } else if (d.type === \"messagepacket\" && d.channel) {\n            const handler = channelHandlers[d.channel]\n            if (handler) {\n                try {\n                    const buf = d.data;\n                    const str = uint8ArrayToString(buf);\n                    const data = JSON.parse(str)\n                    handler(data);\n                } catch (e) {\n                    console.log(`invalid simmessage`)\n                    console.log(e)\n                }\n            }\n        }            \n    }, false);\n\n    // helpers\n    function uint8ArrayToString(input) {\n        let len = input.length;\n        let res = \"\"\n        for (let i = 0; i < len; ++i)\n            res += String.fromCharCode(input[i]);\n        return res;\n    }            \n\n    function setState(st) {\n        var r = document.getElementById(\"root\");\n        if (r)\n            r.setAttribute(\"data-state\", st);\n    }\n\n    function postMessage(msg) {\n        const frame = document.getElementById(\"simframe\");\n        if (frame)\n            frame.contentWindow.postMessage(msg, meta.simUrl);\n    }\n\n    function sendReq(url, cb) {\n        var xhttp = new XMLHttpRequest();\n        xhttp.onreadystatechange = function () {\n            if (xhttp.readyState == 4) {\n                cb(xhttp.responseText, xhttp.status)\n            }\n        };\n        xhttp.open(\"GET\", url, true);\n        xhttp.send();\n    }\n\n    function initSimState() {\n        try {\n            simState = JSON.parse(localStorage[\"simstate\"])\n        } catch (e) {\n            simState = {}\n        }\n        setInterval(function () {\n            if (simStateChanged)\n                localStorage[\"simstate\"] = JSON.stringify(simState)\n            simStateChanged = false\n        }, 200)\n    }\n    \n    function initFullScreen() {\n        var sim = document.getElementById(\"simframe\");\n        var fs = document.getElementById(\"fullscreen\");\n        if (fs && sim.requestFullscreen) {\n            fs.onclick = function() { sim.requestFullscreen(); }\n        } else if (fs) {\n            fs.remove();\n        }\n    }\n}","index.html":"---\n# this is an empty front matter\n---\n<!DOCTYPE html>\n<html>\n\n<head>\n    <meta charset=\"utf-8\">\n    <title>{{ site.github.project_title }}</title>\n    <meta name=\"description\" content=\"{{ site.github.project_tagline }}\" />\n    <meta name=\"author\" content=\"{{ site.github.owner_name }}\">\n    <meta name=\"twitter:card\" content=\"summary\" />\n    <meta name=\"twitter:site\" content=\"/\" />\n    <meta name=\"twitter:title\" content=\"{{ site.github.project_tagline }}\" />\n    <meta name=\"twitter:description\" content=\"{{ site.github.project_tagline }}\" />\n    <meta name=\"twitter:image\" content=\"./icon.png\" />\n    <meta name=\"mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"apple-mobile-web-app-title\" content=\"{{ site.github.project_title }}\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"translucent-black\">\n    <meta name=\"format-detection\" content=\"telephone=no\">\n    <meta name=\"application-name\" content=\"{{ site.github.project_title }}\">\n    <meta name=\"theme-color\" content=\"#000\">\n    <meta property=\"og:title\" content=\"{{ site.github.project_title }}\" />\n    <meta property=\"og:site_name\" content=\"{{ site.github.project_title }}\" />\n    <meta property=\"og:description\" content=\"{{ site.github.project_tagline }}\" />\n    <meta property=\"og:image\" content=\"./icon.png\" />\n    <link rel=\"apple-touch-icon\" href=\"./icon.png\">\n    <link rel=\"icon\" type=\"image/png\" href=\"./icon.png\">\n    <link rel=\"shortcut icon\" href=\"./icon.png\">\n    <script type=\"text/javascript\" src=\"./assets/js/loader.js?v={{ site.github.build_revision }}\"></script>\n    <script type=\"text/javascript\" src=\"./assets/js/custom.js?v={{ site.github.build_revision }}\"></script>\n    <style>\n        body {\n            background: black;\n            color: white;\n            font-family: monospace;\n            overflow: hidden;\n            font-size: 14pt;\n        }\n\n        .embed {\n            background: transparent;\n        }\n\n        iframe {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: calc(100% - 1.5em);\n            border: none;\n        }\n\n        .nofooter iframe {\n            height: 100%;\n        }\n\n        footer {\n            color: grey;\n            position: absolute;\n            bottom: 0;\n            width: 100%;\n            left: 0;\n            z-index: 100;\n            text-align: center;\n            font-size: 1em;\n            margin-bottom: 0.25em;\n        }\n\n        footer a {\n            color: grey;\n        }\n\n        .embed footer,\n        .embed footer a {\n            color: black;\n        }\n\n        #fullscreen {\n            position: absolute;\n            right: 0.25rem;\n            bottom: 0;\n            cursor: pointer;\n        }\n        .lds-ripple {\n            width: 80px;\n            height: 80px;\n            margin: auto;\n            position: absolute;\n            margin: auto;\n            top: 0;\n            right: 0;\n            bottom: 0;\n            left: 0;\n            z-index: -1;\n        }\n\n        .lds-ripple div {\n            position: absolute;\n            border: 4px solid #fff;\n            opacity: 1;\n            border-radius: 50%;\n            animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite;\n        }\n\n        .lds-ripple div:nth-child(2) {\n            animation-delay: -0.5s;\n        }\n\n        @keyframes lds-ripple {\n            0% {\n                top: 36px;\n                left: 36px;\n                width: 0;\n                height: 0;\n                opacity: 1;\n            }\n\n            100% {\n                top: 0px;\n                left: 0px;\n                width: 72px;\n                height: 72px;\n                opacity: 0;\n            }\n        }\n    </style>\n</head>\n\n<body id=\"root\">\n    <div id=\"loader\" class=\"lds-ripple\">\n        <div></div>\n        <div></div>\n        <svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" x=\"0\" y=\"0\" viewBox=\"0 0 32 32\" xml:space=\"preserve\"\n            id=\"svg2\">\n            <style type=\"text/css\" id=\"style4\"></style>\n            <g id=\"g4212\" transform=\"matrix(.79626 0 0 .79626 -68.322 9.868)\">\n                <path\n                    d=\"M105.989-5.487v.01a1.91 1.91 0 00-1.613 1.83c0 .779.417 1.119.417 1.15.413.435.238.913-.589.874 0 0-3.009.015-3.066 0a.724.724 0 00-.53.696v9.894c-.001.39.314.705.705.705h9.848c.39 0 .705-.314.705-.705V5.475c-.126-.423-.489-.463-.827-.141-.032 0-.369.417-1.147.417-.93-.03-1.69-.72-1.83-1.616h-.013a6.771 6.771 0 010-.494h.012c.142-.897.9-1.587 1.83-1.616.78 0 1.116.417 1.148.417.329.313.695.238.827-.138V-.927a.72.72 0 00-.527-.696c-.057.015-3.07 0-3.07 0-.74.06-.998-.44-.585-.874 0-.031.417-.371.417-1.15-.029-.93-.72-1.69-1.616-1.83v-.01a6.241 6.241 0 00-.496 0z\"\n                    id=\"path167\" fill=\"#fff\" fill-opacity=\"1\" stroke-width=\"1.57\" />\n                <path\n                    d=\"M98.633-7.18c-.917 0-1.624.252-2.158.774-.534.521-.802 1.208-.822 2.094a552.379 552.379 0 01-.062 2.732c-.02.776-.081 1.354-.187 1.766-.118.46-.331.853-.637 1.168-.272.28-.684.587-1.254.938-.255.156-.368.387-.368.748 0 .351.077.481.11.521.12.145.32.3.592.463.376.226.702.494.972.795.3.334.518.786.662 1.38.052.213.112.882.172 4.228.006.566.138 1.07.39 1.502.25.431.584.753 1.02.984.443.235.971.356 1.57.356.974 0 1.055-.377 1.055-.764 0-.266-.054-.465-.157-.591a.501.501 0 00-.334-.2c-.374-.042-.66-.103-.87-.187a1.29 1.29 0 01-.678-.622c-.127-.244-.206-.588-.242-1.049a22.82 22.82 0 01-.046-1.68c0-.707-.034-1.327-.099-1.846a4.868 4.868 0 00-.31-1.26 2.848 2.848 0 00-.52-.843 4.267 4.267 0 00-.874-.702l-.773-.485.773-.487c.502-.318.88-.657 1.128-1.012.244-.35.413-.783.503-1.282.099-.55.153-1.333.169-2.333 0-.713.014-1.247.042-1.625.032-.437.105-.774.221-1.027.147-.317.382-.548.68-.672.214-.086.506-.152.896-.205a.429.429 0 00.224-.089.622.622 0 00.178-.251 1.11 1.11 0 00.089-.451c0-.268-.07-.45-.215-.57-.175-.144-.456-.215-.84-.215z\"\n                    id=\"path165\" fill=\"#fff\" fill-opacity=\"1\" stroke-width=\"1.57\" />\n                <path\n                    d=\"M113.887-7.182c-.974 0-1.055.377-1.055.763 0 .267.05.467.153.592.1.12.205.182.338.2.374.042.658.103.867.186.294.116.524.326.678.623.127.245.206.588.242 1.048.032.397.046.945.046 1.68 0 .708.034 1.328.098 1.846.06.49.166.917.31 1.264.138.332.313.616.521.843.22.239.511.473.871.699l.773.487-.77.488c-.502.317-.882.656-1.128 1.009-.244.35-.414.78-.503 1.278-.099.551-.154 1.338-.169 2.337 0 .712-.015 1.246-.043 1.625-.03.437-.1.77-.217 1.024a1.294 1.294 0 01-.68.674c-.214.087-.506.154-.896.206a.44.44 0 00-.227.089.64.64 0 00-.178.251c-.06.135-.086.282-.086.45 0 .268.066.45.212.571.174.144.458.218.843.218.917 0 1.62-.254 2.155-.776.534-.522.802-1.205.822-2.091.023-1.095.046-2.007.064-2.735.02-.777.079-1.355.184-1.766.12-.46.333-.854.638-1.168.273-.28.684-.587 1.254-.938.254-.157.368-.385.368-.746 0-.35-.077-.483-.11-.524-.119-.143-.316-.298-.589-.463a4.268 4.268 0 01-.975-.794c-.3-.334-.515-.784-.66-1.377-.051-.213-.114-.885-.174-4.23-.007-.568-.138-1.072-.39-1.503a2.524 2.524 0 00-1.02-.984c-.443-.235-.968-.356-1.567-.356z\"\n                    id=\"path163\" fill=\"#fff\" fill-opacity=\"1\" stroke-width=\"1.57\" />\n            </g>\n            <path\n                d=\"M28.621 31.422c.224-.102.208 1.099.208-15.49 0-16.588.016-15.388-.208-15.49-.144-.065-24.6-.065-24.744 0-.223.102-.207-1.1-.206 15.498.001 12.58.01 15.259.052 15.334.112.203-.702.19 12.515.192 9.446.001 12.307-.01 12.383-.044zm-9.415-1.705c-.283-.11-.57-.4-.678-.687a1.216 1.216 0 011.131-1.655c.669 0 1.213.544 1.213 1.213 0 .853-.862 1.437-1.666 1.129zm-8.337-1.054v-.757H9.353v-1.668h1.516V24.723H12.536V26.238h1.516v1.668h-1.516V29.42H10.869zm10.99-1.22c-.284-.109-.57-.399-.678-.686a1.204 1.204 0 01.276-1.298c.762-.762 2.067-.222 2.067.855 0 .854-.862 1.438-1.666 1.13zM4.765 23.475l-.111-.11V1.377l.11-.111.111-.11h22.746l.11.11.112.11V23.366l-.111.11-.11.111H4.875z\"\n                id=\"path4210\" fill=\"#fff\" fill-opacity=\"1\" />\n        </svg>\n    </div>\n    <iframe id=\"simframe\" allowfullscreen=\"allowfullscreen\"\n        sandbox=\"allow-popups allow-forms allow-scripts allow-same-origin\">\n    </iframe>\n    <footer id=\"footer\">\n        <a target=\"blank\" rel=\"nofollow noopener\" href=\"https://{{ site.github.owner_name }}.github.io/{{ site.github.repository_name }}/README\">Manual</a>\n        <a target=\"blank\" rel=\"nofollow noopener\" href=\"https://arcade.makecode.com/#pub:github:{{ site.github.owner_name }}/{{ site.github.repository_name }}\">Edit</a>\n        <a target=\"blank\" rel=\"nofollow noopener\" href=\"https://github.com/{{ site.github.owner_name }}/{{ site.github.repository_name }}\">GitHub</a>\n        <span id=\"version\"></span>\n        <div id=\"fullscreen\">⇲</div>\n    </footer>\n    <script type=\"text/javascript\">\n        makeCodeRun({ js: \"./assets/js/binary.js?v={{ site.github.build_revision }}\" });\n\n        if (window.location && window.location.search) {\n            var noFooter = /nofooter=1/i.test(window.location.search);\n            var embed = /embed=1/i.test(window.location.search);\n            var root = document.querySelector(\"#root\");\n\n            if (noFooter) {\n                var footer = document.querySelector(\"#footer\");\n                if (root)\n                    root.className += \" nofooter\";\n                if (footer)\n                    footer.remove();\n            }\n\n            if (embed && root) {\n                root.className += \" embed\";\n            }\n        }\n    </script>\n</body>\n\n</html>\n","pxt.json":"{\n    \"name\": \"template\",\n    \"description\": \"Contains overriden or additional files for the default project template\",\n    \"dependencies\": {\n        \"device\": \"*\"\n    },\n    \"files\": [\n        \"index.html\",\n        \".gitattributes\",\n        \"assets/index.html\",\n        \"assets/js/loader.js\",\n        \"assets/js/custom.js\",\n        \".github/workflows/makecode-release.yml\"\n    ],\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true\n}\n"},"thermometer":{"README.md":"# temperature\n\nThe temperature library.\n\n","enums.d.ts":"// Auto-generated. Do not edit.\n\n\n    declare const enum TemperatureCondition {\n    //% block=\"hot\"\n    Hot = 2,  // SENSOR_THRESHOLD_HIGH\n    //% block=\"cold\"\n    Cold = 1,  // SENSOR_THRESHOLD_LOW\n    }\n\n\n    declare const enum TemperatureUnit {\n    //% block=\"°C\"\n    Celsius = 0,\n    //% block=\"°F\"\n    Fahrenheit = 1,\n    }\n\n// Auto-generated. Do not edit. Really.\n","ns.ts":"\n//% color=\"#B4009E\" weight=98 icon=\"\\uf192\"\nnamespace input {\n}","pxt.json":"{\n    \"name\": \"thermometer\",\n    \"description\": \"A thermometer driver\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"README.md\",\n        \"temperature.cpp\",\n        \"target_temperature.h\",\n        \"shims.d.ts\",\n        \"enums.d.ts\",\n        \"ns.ts\"\n    ],\n    \"testFiles\": [\n        \"test.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"hidden\": true\n}\n","shims.d.ts":"// Auto-generated. Do not edit.\ndeclare namespace input {\n\n    /**\n     * Run some code when the temperature changes from hot to cold, or from cold to hot.\n     * @param condition the condition, hot or cold, the event triggers on\n     * @param temperature the temperature at which this event happens, eg: 15\n     * @param unit the unit of the temperature\n     */\n    //% blockId=input_on_temperature_condition_changed block=\"on temperature %condition|at %temperature|%unit\"\n    //% parts=\"thermometer\"\n    //% help=input/on-temperature-condition-changed blockExternalInputs=0\n    //% group=\"More\" weight=76 shim=input::onTemperatureConditionChanged\n    function onTemperatureConditionChanged(condition: TemperatureCondition, temperature: int32, unit: TemperatureUnit, handler: () => void): void;\n\n    /**\n     * Get the temperature in Celsius or Fahrenheit degrees.\n     */\n    //% help=input/temperature\n    //% blockId=device_temperature block=\"temperature in %unit\"\n    //% parts=\"thermometer\"\n    //% weight=26 shim=input::temperature\n    function temperature(unit: TemperatureUnit): int32;\n}\n\n// Auto-generated. Do not edit. Really.\n","target_temperature.h":"#include \"NonLinearAnalogSensor.h\"\n\n/*\n * @param nominalValue The value (in SI units) of a nominal position.\n * @param nominalReading The raw reading from the sensor at the nominal position.\n * @param beta The Steinhart-Hart Beta constant for the device\n * @param seriesResistor The value (in ohms) of the resistor in series with the sensor.\n * @param zeroOffset Optional zero offset applied to all SI units (e.g. 273.15 for temperature\n * sensing in C vs Kelvin).\n */\n\n#ifndef TEMPERATURE_NOMINAL_VALUE\n#define TEMPERATURE_NOMINAL_VALUE 25\n#endif\n\n#ifndef TEMPERATURE_NOMINAL_READING\n#define TEMPERATURE_NOMINAL_READING 10000\n#endif\n\n#ifndef TEMPERATURE_BETA\n#define TEMPERATURE_BETA 3380\n#endif\n\n#ifndef TEMPERATURE_SERIES_RESISTOR\n#define TEMPERATURE_SERIES_RESISTOR 10000\n#endif\n\n#ifndef TEMPERATURE_ZERO_OFFSET\n#define TEMPERATURE_ZERO_OFFSET 273.5\n#endif\n\nnamespace pxt {\nclass WTemp {\n  public:\n    NonLinearAnalogSensor sensor;\n    WTemp()\n        : sensor(*LOOKUP_PIN(TEMPERATURE), DEVICE_ID_THERMOMETER,\n                TEMPERATURE_NOMINAL_VALUE, \n                TEMPERATURE_NOMINAL_READING, \n                TEMPERATURE_BETA, \n                TEMPERATURE_SERIES_RESISTOR,\n                TEMPERATURE_ZERO_OFFSET)\n    {\n        sensor.init();\n    }\n};\n}","temperature.cpp":"#include \"pxt.h\"\n#include \"target_temperature.h\"\n\nenum class TemperatureCondition {\n    //% block=\"hot\"\n    Hot = SENSOR_THRESHOLD_HIGH,\n    //% block=\"cold\"\n    Cold = SENSOR_THRESHOLD_LOW\n};\n\nenum class TemperatureUnit {\n    //% block=\"°C\"\n    Celsius,\n    //% block=\"°F\"\n    Fahrenheit\n};\n\nnamespace pxt {\nSINGLETON_IF_PIN(WTemp, TEMPERATURE);\n}\n\nnamespace input {\n\n/**\n* Run some code when the temperature changes from hot to cold, or from cold to hot.\n* @param condition the condition, hot or cold, the event triggers on\n* @param temperature the temperature at which this event happens, eg: 15\n* @param unit the unit of the temperature\n*/\n//% blockId=input_on_temperature_condition_changed block=\"on temperature %condition|at %temperature|%unit\"\n//% parts=\"thermometer\"\n//% help=input/on-temperature-condition-changed blockExternalInputs=0\n//% group=\"More\" weight=76\nvoid onTemperatureConditionChanged(TemperatureCondition condition, int temperature, TemperatureUnit unit, Action handler) {\n    auto thermo = getWTemp();\n    if (!thermo) return;\n\n    auto sensor = &thermo->sensor;\n    sensor->updateSample();\n\n    int t = unit == TemperatureUnit::Celsius ? temperature : ((temperature - 32) * 10) / 18;\n\n    if (condition == TemperatureCondition::Cold)\n        sensor->setLowThreshold(t);\n    else\n        sensor->setHighThreshold(t);\n    registerWithDal(sensor->id, (int)condition, handler);\n}\n\n/**\n * Get the temperature in Celsius or Fahrenheit degrees.\n */\n//% help=input/temperature\n//% blockId=device_temperature block=\"temperature in %unit\"\n//% parts=\"thermometer\"\n//% weight=26\nint temperature(TemperatureUnit unit) {\n    auto thermo = getWTemp();\n    // default to 21 if not present\n    int value = (NULL != thermo) ? thermo->sensor.getValue() : 21;\n    if (unit == TemperatureUnit::Celsius) return value;\n    else return (value * 18) / 10 + 32;\n}\n}\n","test.ts":""},"browser-events":{"browserEvents.cpp":"#include \"pxt.h\"\n\nnamespace browserEvents {\n\n//%\nint mouseX() {\n    return -1;\n}\n\n//%\nint mouseY() {\n    return -1;\n}\n\n//%\nint wheelDx() {\n    return -1;\n}\n\n//%\nint wheelDy() {\n    return -1;\n}\n\n//%\nint wheelDz() {\n    return -1;\n}\n\n//%\nvoid _setCursorVisible(bool visible) {\n}\n\n//%\nint currentTime() {\n    return -1;\n}\n\n//%\nint getYear(int time) {\n    return -1;\n}\n\n//%\nint getMonth(int time) {\n    return -1;\n}\n\n//%\nint getDayOfMonth(int time) {\n    return -1;\n}\n\n//%\nint getDayOfWeek(int time) {\n    return -1;\n}\n\n//%\nint getHours(int time) {\n    return -1;\n}\n\n//%\nint getMinutes(int time) {\n    return -1;\n}\n\n//%\nint getSeconds(int time) {\n    return -1;\n}\n}","browserEvents.ts":"\n//% icon=\"\\uf245\"\n//% color=\"#9c1355\"\n//% block=\"Browser Events\"\nnamespace browserEvents {\n    export enum Event {\n        //% block=\"pointer down\"\n        PointerDown = 6857,\n        //% block=\"pointer up\"\n        PointerUp = 6858,\n        //% block=\"pointer move\"\n        PointerMove = 6859,\n        //% block=\"pointer leave\"\n        PointerLeave = 6860,\n        //% block=\"pointer enter\"\n        PointerEnter = 6861,\n        //% block=\"pointer cancel\"\n        PointerCancel = 6862,\n        //% block=\"pointer over\"\n        PointerOver = 6863,\n        //% block=\"pointer out\"\n        PointerOut = 6864,\n        //% block=\"wheel\"\n        Wheel = 6865,\n        //% block=\"key down\"\n        KeyDown = 6866,\n        //% block=\"key up\"\n        KeyUp = 6867\n    }\n\n    export enum MouseButtonId {\n        //% block=\"left\"\n        Left = 1,\n        //% block=\"right\"\n        Right = 3,\n        //% block=\"wheel\"\n        Wheel = 2,\n        //% block=\"back\"\n        Back = 4,\n        //% block=\"forward\"\n        Forward = 5\n    }\n\n    export enum MouseButtonEvent {\n        //% block=\"pressed\"\n        Pressed = Event.PointerDown,\n        //% block=\"released\"\n        Released = Event.PointerUp,\n    }\n\n    //% whenUsed\n    const INTERNAL_POINTER_DOWN = 6868;\n    //% whenUsed\n    const INTERNAL_POINTER_UP = 6869;\n\n    type MouseHandler = (x: number, y: number) => void;\n\n    //% fixedInstances\n    export class MouseButton {\n        protected _pressed: boolean;\n\n        protected sceneStack: _SceneButtonHandlers<MouseHandler>[];\n\n        protected get state(): _SceneButtonHandlers<MouseHandler> {\n            return this.sceneStack[this.sceneStack.length - 1];\n        }\n\n        constructor(public id: number) {\n            control.internalOnEvent(INTERNAL_POINTER_DOWN, this.id, () => this.setPressed(true), 16);\n            control.internalOnEvent(INTERNAL_POINTER_UP, this.id, () => this.setPressed(false), 16);\n\n            this._pressed = false;\n\n            this.sceneStack = [new _SceneButtonHandlers<MouseHandler>(id, invokeMouseHandler)];\n\n            game.addScenePushHandler(() => {\n                this.sceneStack.push(new _SceneButtonHandlers<MouseHandler>(id, invokeMouseHandler));\n            });\n            game.addScenePopHandler(() => {\n                this.sceneStack.pop();\n                if (this.sceneStack.length === 0) {\n                    this.sceneStack = [new _SceneButtonHandlers<MouseHandler>(id, invokeMouseHandler)];\n                }\n            });\n        }\n\n        setPressed(pressed: boolean) {\n            this._pressed = pressed;\n\n            if (pressed) {\n                control.raiseEvent(MouseButtonEvent.Pressed, this.id);\n            }\n            else {\n                control.raiseEvent(MouseButtonEvent.Released, this.id);\n            }\n        }\n\n        //% blockId=browserEvents_mouseButton_onEvent\n        //% block=\"on $this mouse button $event $x $y\"\n        //% draggableParameters=\"reporter\"\n        //% group=\"Mouse\"\n        //% weight=50\n        onEvent(event: MouseButtonEvent, handler: (x: number, y: number) => void) {\n            this.state.onEvent(event, handler);\n        }\n\n        //% blockId=browserEvents_mouseButton_isPressed\n        //% block=\"is $this mouse button pressed\"\n        //% group=\"Mouse\"\n        //% weight=40\n        isPressed() {\n            return this._pressed;\n        }\n\n        //% blockId=browserEvents_mouseButton_pauseUntil\n        //% block=\"pause until $this mouse button is $event\"\n        //% group=\"Mouse\"\n        //% weight=30\n        pauseUntil(event: MouseButtonEvent) {\n            control.waitForEvent(event, this.id)\n        }\n\n        addEventListener(event: MouseButtonEvent, handler: (x: number, y: number) => void) {\n            this.state.addEventListener(event, handler);\n        }\n\n        removeEventListener(event: MouseButtonEvent, handler: (x: number, y: number) => void) {\n            this.state.removeEventListener(event, handler);\n        }\n    }\n\n    export class _SceneButtonHandlers<U> {\n        protected handlers: ButtonHandler<U>[];\n\n        constructor(public id: number, protected invokeHandler: (handler: U) => void) {\n            this.handlers = [];\n        }\n\n        onEvent(event: number, handler: U) {\n            this.getHandler(event, true).handler = handler;\n        }\n\n        addEventListener(event: number, handler: U) {\n            this.getHandler(event, true).listeners.push(handler);\n        }\n\n        removeEventListener(event: number, handler: U) {\n            const eventHandler = this.getHandler(event);\n\n            if (eventHandler) {\n                eventHandler.listeners = eventHandler.listeners.filter(h => h !== handler);\n            }\n        }\n\n        protected getHandler(event: number, createIfMissing?: boolean) {\n            for (const handler of this.handlers) {\n                if (handler.event === event) return handler;\n            }\n\n            if (createIfMissing) {\n                const newHandler = new ButtonHandler<U>(event, this.id, this.invokeHandler);\n                this.handlers.push(newHandler);\n                return newHandler;\n            }\n\n            return undefined;\n        }\n    }\n\n    class ButtonHandler<U> {\n        handler: U;\n        listeners: U[] = [];\n\n        constructor(public readonly event: number, id: number, invokeHandler: (handler: U) => void) {\n            control.onEvent(event, id, () => {\n                if (this.handler) {\n                    invokeHandler(this.handler);\n                }\n                for (const listener of this.listeners) {\n                    invokeHandler(listener);\n                }\n            });\n        }\n    }\n\n    function invokeMouseHandler(handler: MouseHandler) {\n        handler(mouseX(), mouseY());\n    }\n\n    //% blockId=browserEvents_onEvent\n    //% block=\"on browser event $event\"\n    //% draggableParameters=\"reporter\"\n    //% group=\"Mouse\"\n    //% weight=10\n    export function onEvent(event: Event, handler: () => void) {\n        control.onEvent(event, 0, handler);\n    }\n\n    //% blockId=browserEvents_onMouseMove\n    //% block=\"on mouse move $x $y\"\n    //% draggableParameters=\"reporter\"\n    //% group=\"Mouse\"\n    //% weight=100\n    export function onMouseMove(handler: (x: number, y: number) => void) {\n        control.onEvent(Event.PointerMove, 0, () => {\n            handler(mouseX(), mouseY());\n        });\n    }\n\n    //% blockId=browserEvents_onWheel\n    //% block=\"on mouse wheel $dx $dy $dz\"\n    //% draggableParameters=\"reporter\"\n    //% group=\"Mouse\"\n    //% weight=20\n    export function onWheel(handler: (dx: number, dy: number, dz: number) => void) {\n        control.onEvent(Event.Wheel, 0, () => {\n            handler(wheelDx(), wheelDy(), wheelDz());\n        });\n    }\n\n    //% blockId=browserEvents_setCursorVisible\n    //% block=\"set cursor visible $visible\"\n    //% group=\"Mouse\"\n    //% weight=0\n    export function setCursorVisible(visible: boolean) {\n        _setCursorVisible(visible);\n    }\n\n    //% fixedInstance whenUsed block=\"left\"\n    export const MouseLeft = new MouseButton(MouseButtonId.Left);\n\n    //% fixedInstance whenUsed block=\"right\"\n    export const MouseRight = new MouseButton(MouseButtonId.Right);\n\n    //% fixedInstance whenUsed block=\"wheel\"\n    export const MouseWheel = new MouseButton(MouseButtonId.Wheel);\n\n    //% fixedInstance whenUsed block=\"back\"\n    export const MouseBack = new MouseButton(MouseButtonId.Back);\n\n    //% fixedInstance whenUsed block=\"forward\"\n    export const MouseForward = new MouseButton(MouseButtonId.Forward);\n\n    //% fixedInstance whenUsed block=\"any\"\n    export const MouseAny = new MouseButton(0);\n}","keyboard.ts":"namespace browserEvents {\n    export enum Key {\n        Zero = 48,\n        One = 49,\n        Two = 50,\n        Three = 51,\n        Four = 52,\n        Five = 53,\n        Six = 54,\n        Seven = 55,\n        Eight = 56,\n        Nine = 57,\n        BackTick = 192,\n        Hyphen = 189,\n        Equals = 187,\n        Q = 81,\n        W = 87,\n        E = 69,\n        R = 82,\n        T = 84,\n        Y = 89,\n        U = 85,\n        I = 73,\n        O = 79,\n        P = 80,\n        OpenBracket = 219,\n        CloseBracket = 221,\n        BackSlash = 220,\n        A = 65,\n        S = 83,\n        D = 68,\n        F = 70,\n        G = 71,\n        H = 72,\n        Space = 32,\n        PageUp = 33,\n        J = 74,\n        K = 75,\n        L = 76,\n        SemiColon = 186,\n        Apostrophe = 222,\n        Z = 90,\n        X = 88,\n        C = 67,\n        V = 86,\n        B = 66,\n        N = 78,\n        M = 77,\n        Comma = 188,\n        Period = 190,\n        ForwardSlash = 191,\n        Shift = 16,\n        Enter = 13,\n        CapsLock = 20,\n        Tab = 9,\n        Control = 17,\n        Meta = 91,\n        Alt = 18,\n        ArrowUp = 38,\n        ArrowDown = 40,\n        ArrowLeft = 37,\n        ArrowRight = 39,\n        PageDown = 34,\n        End = 35,\n        Home = 36,\n        LeftShift = 1016,\n        RightShift = 1017,\n        LeftControl = 1018,\n        RightControl = 1019,\n        Backspace = 8,\n        Delete = 46,\n    }\n\n    export enum KeyEvent {\n        //% block=\"pressed\"\n        Pressed = 6872,\n        //% block=\"released\"\n        Released = 6873,\n        //% block=\"repeat\"\n        Repeat = 6874\n    }\n\n    //% whenUsed\n    const INTERNAL_KEY_DOWN = 6870;\n    //% whenUsed\n    const INTERNAL_KEY_UP = 6871;\n\n    export function keyToString(key: Key) {\n        switch (key) {\n            case Key.Q:\n                return \"Q\";\n            case Key.W:\n                return \"W\";\n            case Key.E:\n                return \"E\";\n            case Key.R:\n                return \"R\";\n            case Key.T:\n                return \"T\";\n            case Key.Y:\n                return \"Y\";\n            case Key.U:\n                return \"U\";\n            case Key.I:\n                return \"I\";\n            case Key.O:\n                return \"O\";\n            case Key.P:\n                return \"P\";\n            case Key.OpenBracket:\n                return \"[\";\n            case Key.CloseBracket:\n                return \"]\";\n            case Key.BackSlash:\n                return \"\\\\\";\n            case Key.A:\n                return \"A\";\n            case Key.S:\n                return \"S\";\n            case Key.D:\n                return \"D\";\n            case Key.F:\n                return \"F\";\n            case Key.G:\n                return \"G\";\n            case Key.H:\n                return \"H\";\n            case Key.Space:\n                return \" \";\n            case Key.PageUp:\n                return \"PageUp\";\n            case Key.J:\n                return \"J\";\n            case Key.K:\n                return \"K\";\n            case Key.L:\n                return \"L\";\n            case Key.SemiColon:\n                return \";\";\n            case Key.Apostrophe:\n                return \"'\";\n            case Key.Z:\n                return \"Z\";\n            case Key.X:\n                return \"X\";\n            case Key.C:\n                return \"C\";\n            case Key.V:\n                return \"V\";\n            case Key.B:\n                return \"B\";\n            case Key.N:\n                return \"N\";\n            case Key.M:\n                return \"M\";\n            case Key.Comma:\n                return \",\";\n            case Key.Period:\n                return \".\";\n            case Key.ForwardSlash:\n                return \"/\";\n            case Key.Shift:\n                return \"Shift\";\n            case Key.Enter:\n                return \"Enter\";\n            case Key.CapsLock:\n                return \"CapsLock\";\n            case Key.Tab:\n                return \"Tab\";\n            case Key.Control:\n                return \"Control\";\n            case Key.Meta:\n                return \"Meta\";\n            case Key.Alt:\n                return \"Alt\";\n            case Key.ArrowUp:\n                return \"ArrowUp\";\n            case Key.ArrowDown:\n                return \"ArrowDown\";\n            case Key.ArrowLeft:\n                return \"ArrowLeft\";\n            case Key.ArrowRight:\n                return \"ArrowRight\";\n            case Key.PageDown:\n                return \"PageDown\";\n            case Key.End:\n                return \"End\";\n            case Key.Home:\n                return \"Home\";\n            case Key.Zero:\n                return \"0\";\n            case Key.One:\n                return \"1\";\n            case Key.Two:\n                return \"2\";\n            case Key.Three:\n                return \"3\";\n            case Key.Four:\n                return \"4\";\n            case Key.Five:\n                return \"5\";\n            case Key.Six:\n                return \"6\";\n            case Key.Seven:\n                return \"7\";\n            case Key.Eight:\n                return \"8\";\n            case Key.Nine:\n                return \"9\";\n            case Key.BackTick:\n                return \"`\";\n            case Key.Hyphen:\n                return \"-\";\n            case Key.Equals:\n                return \"=\";\n            case Key.LeftShift:\n                return \"LeftShift\";\n            case Key.RightShift:\n                return \"RightShift\";\n            case Key.LeftControl:\n                return \"LeftControl\";\n            case Key.RightControl:\n                return \"RightControl\";\n            case Key.Backspace:\n                return \"Backspace\";\n            case Key.Delete:\n                return \"Delete\";\n        }\n    }\n\n    //% whenUsed\n    let _buttonsPendingInit: KeyButton[];\n\n    let defaultRepeatDelay = 500;\n    let defaultRepeatInterval = 30;\n\n    type KeyHandler = () => void;\n\n    //% fixedInstances\n    export class KeyButton {\n        protected _pressed: boolean;\n        public repeatDelay: number;\n        public repeatInterval: number;\n        private _repeatCount: number;\n        private _pressedElapsed: number;\n\n        protected sceneStack: _SceneButtonHandlers<KeyHandler>[];\n\n        protected get state(): _SceneButtonHandlers<KeyHandler> {\n            return this.sceneStack[this.sceneStack.length - 1];\n        }\n\n        constructor(public id: number) {\n            // use internalOnEvent so that events fire regardless of the current scene\n            control.internalOnEvent(INTERNAL_KEY_UP, this.id, () => this.setPressed(false), 16);\n            control.internalOnEvent(INTERNAL_KEY_DOWN, this.id, () => this.setPressed(true), 16);\n            this._pressed = false;\n\n            // this code may run before game/scene.ts, in which case calling this.__registerUpdate\n            // will trigger an exception. to prevent that, start a thread that pauses until we\n            // detect that an event context has been registered and then call it\n            if (control.eventContext()) {\n                this.__registerUpdate();\n            }\n            else {\n                if (!_buttonsPendingInit) {\n                    _buttonsPendingInit = [];\n                    control.runInBackground(() => {\n                        pauseUntil(() => !!control.eventContext());\n                        for (const button of _buttonsPendingInit) {\n                            button.__registerUpdate();\n                        }\n                        _buttonsPendingInit = undefined;\n                    });\n                }\n                _buttonsPendingInit.push(this);\n            }\n\n            this.sceneStack = [new _SceneButtonHandlers<KeyHandler>(id, invokeKeyHandler)];\n\n            game.addScenePushHandler(() => {\n                this.sceneStack.push(new _SceneButtonHandlers<KeyHandler>(id, invokeKeyHandler));\n                this.__registerUpdate();\n            });\n            game.addScenePopHandler(() => {\n                this.sceneStack.pop();\n                if (this.sceneStack.length === 0) {\n                    this.sceneStack = [new _SceneButtonHandlers<KeyHandler>(id, invokeKeyHandler)];\n                    this.__registerUpdate();\n                }\n            });\n        }\n\n        setPressed(pressed: boolean) {\n            if (this._pressed === pressed) return;\n\n            this._pressed = pressed;\n            if (pressed) {\n                this._repeatCount = 0;\n                this._pressedElapsed = 0;\n                control.raiseEvent(KeyEvent.Pressed, this.id);\n            }\n            else {\n                control.raiseEvent(KeyEvent.Released, this.id);\n            }\n        }\n\n        //% blockId=browserEvents_key_onEvent\n        //% block=\"on $this key $event\"\n        //% group=\"Keyboard\"\n        //% weight=100\n        onEvent(event: KeyEvent, handler: () => void) {\n            this.state.onEvent(event, handler);\n        }\n\n        //% blockId=browserEvents_key_isPressed\n        //% block=\"is $this key pressed\"\n        //% group=\"Keyboard\"\n        //% weight=90\n        isPressed() {\n            return this._pressed;\n        }\n\n        //% blockId=browserEvents_key_pauseUntil\n        //% block=\"pause until $this key is $event\"\n        //% group=\"Keyboard\"\n        //% weight=80\n        pauseUntil(event: KeyEvent) {\n            control.waitForEvent(event, this.id)\n        }\n\n        addEventListener(event: KeyEvent, handler: () => void) {\n            this.state.addEventListener(event, handler);\n        }\n\n        removeEventListener(event: KeyEvent, handler: () => void) {\n            this.state.removeEventListener(event, handler);\n        }\n\n        __update() {\n            const delay = this.repeatDelay === undefined ? defaultRepeatDelay : this.repeatDelay;\n            const interval = this.repeatInterval === undefined ? defaultRepeatInterval : this.repeatInterval;\n            if (!this._pressed) return;\n            this._pressedElapsed += game.eventContext().deltaTimeMillis;\n\n            // inital delay\n            if (this._pressedElapsed < delay)\n                return;\n\n            // repeat count for this step\n            const count = Math.floor((this._pressedElapsed - delay - interval) / interval);\n            if (count != this._repeatCount) {\n                this._repeatCount = count;\n                control.raiseEvent(KeyEvent.Repeat, this.id);\n            }\n        }\n\n        __registerUpdate() {\n            game.eventContext().registerFrameHandler(scene.CONTROLLER_PRIORITY, () => this.__update());\n        }\n    }\n\n    function invokeKeyHandler(handler: KeyHandler) {\n        handler();\n    }\n\n    //% fixedInstance whenUsed\n    export const A = new KeyButton(Key.A);\n\n    //% fixedInstance whenUsed\n    export const B = new KeyButton(Key.B);\n\n    //% fixedInstance whenUsed\n    export const C = new KeyButton(Key.C);\n\n    //% fixedInstance whenUsed\n    export const D = new KeyButton(Key.D);\n\n    //% fixedInstance whenUsed\n    export const E = new KeyButton(Key.E);\n\n    //% fixedInstance whenUsed\n    export const F = new KeyButton(Key.F);\n\n    //% fixedInstance whenUsed\n    export const G = new KeyButton(Key.G);\n\n    //% fixedInstance whenUsed\n    export const H = new KeyButton(Key.H);\n\n    //% fixedInstance whenUsed\n    export const I = new KeyButton(Key.I);\n\n    //% fixedInstance whenUsed\n    export const J = new KeyButton(Key.J);\n\n    //% fixedInstance whenUsed\n    export const K = new KeyButton(Key.K);\n\n    //% fixedInstance whenUsed\n    export const L = new KeyButton(Key.L);\n\n    //% fixedInstance whenUsed\n    export const M = new KeyButton(Key.M);\n\n    //% fixedInstance whenUsed\n    export const N = new KeyButton(Key.N);\n\n    //% fixedInstance whenUsed\n    export const O = new KeyButton(Key.O);\n\n    //% fixedInstance whenUsed\n    export const P = new KeyButton(Key.P);\n\n    //% fixedInstance whenUsed\n    export const Q = new KeyButton(Key.Q);\n\n    //% fixedInstance whenUsed\n    export const R = new KeyButton(Key.R);\n\n    //% fixedInstance whenUsed\n    export const S = new KeyButton(Key.S);\n\n    //% fixedInstance whenUsed\n    export const T = new KeyButton(Key.T);\n\n    //% fixedInstance whenUsed\n    export const U = new KeyButton(Key.U);\n\n    //% fixedInstance whenUsed\n    export const V = new KeyButton(Key.V);\n\n    //% fixedInstance whenUsed\n    export const W = new KeyButton(Key.W);\n\n    //% fixedInstance whenUsed\n    export const X = new KeyButton(Key.X);\n\n    //% fixedInstance whenUsed\n    export const Y = new KeyButton(Key.Y);\n\n    //% fixedInstance whenUsed\n    export const Z = new KeyButton(Key.Z);\n\n    //% fixedInstance whenUsed\n    export const Zero = new KeyButton(Key.Zero);\n\n    //% fixedInstance whenUsed\n    export const One = new KeyButton(Key.One);\n\n    //% fixedInstance whenUsed\n    export const Two = new KeyButton(Key.Two);\n\n    //% fixedInstance whenUsed\n    export const Three = new KeyButton(Key.Three);\n\n    //% fixedInstance whenUsed\n    export const Four = new KeyButton(Key.Four);\n\n    //% fixedInstance whenUsed\n    export const Five = new KeyButton(Key.Five);\n\n    //% fixedInstance whenUsed\n    export const Six = new KeyButton(Key.Six);\n\n    //% fixedInstance whenUsed\n    export const Seven = new KeyButton(Key.Seven);\n\n    //% fixedInstance whenUsed\n    export const Eight = new KeyButton(Key.Eight);\n\n    //% fixedInstance whenUsed\n    export const Nine = new KeyButton(Key.Nine);\n\n    //% fixedInstance whenUsed\n    export const Shift = new KeyButton(Key.Shift);\n\n    //% fixedInstance whenUsed\n    export const Enter = new KeyButton(Key.Enter);\n\n    //% fixedInstance whenUsed\n    export const CapsLock = new KeyButton(Key.CapsLock);\n\n    //% fixedInstance whenUsed\n    export const Tab = new KeyButton(Key.Tab);\n\n    //% fixedInstance whenUsed\n    export const Control = new KeyButton(Key.Control);\n\n    //% fixedInstance whenUsed\n    export const Meta = new KeyButton(Key.Meta);\n\n    //% fixedInstance whenUsed\n    export const Alt = new KeyButton(Key.Alt);\n\n    //% fixedInstance whenUsed\n    export const ArrowUp = new KeyButton(Key.ArrowUp);\n\n    //% fixedInstance whenUsed\n    export const ArrowDown = new KeyButton(Key.ArrowDown);\n\n    //% fixedInstance whenUsed\n    export const ArrowLeft = new KeyButton(Key.ArrowLeft);\n\n    //% fixedInstance whenUsed\n    export const ArrowRight = new KeyButton(Key.ArrowRight);\n\n    //% fixedInstance whenUsed\n    export const BackTick = new KeyButton(Key.BackTick);\n\n    //% fixedInstance whenUsed\n    export const Hyphen = new KeyButton(Key.Hyphen);\n\n    //% fixedInstance whenUsed\n    export const Equals = new KeyButton(Key.Equals);\n\n    //% fixedInstance whenUsed\n    export const OpenBracket = new KeyButton(Key.OpenBracket);\n\n    //% fixedInstance whenUsed\n    export const CloseBracket = new KeyButton(Key.CloseBracket);\n\n    //% fixedInstance whenUsed\n    export const BackSlash = new KeyButton(Key.BackSlash);\n\n    //% fixedInstance whenUsed\n    export const Space = new KeyButton(Key.Space);\n\n    //% fixedInstance whenUsed\n    export const PageUp = new KeyButton(Key.PageUp);\n\n    //% fixedInstance whenUsed\n    export const SemiColon = new KeyButton(Key.SemiColon);\n\n    //% fixedInstance whenUsed\n    export const Apostrophe = new KeyButton(Key.Apostrophe);\n\n    //% fixedInstance whenUsed\n    export const Comma = new KeyButton(Key.Comma);\n\n    //% fixedInstance whenUsed\n    export const Period = new KeyButton(Key.Period);\n\n    //% fixedInstance whenUsed\n    export const ForwardSlash = new KeyButton(Key.ForwardSlash);\n\n    //% fixedInstance whenUsed\n    export const PageDown = new KeyButton(Key.PageDown);\n\n    //% fixedInstance whenUsed\n    export const End = new KeyButton(Key.End);\n\n    //% fixedInstance whenUsed\n    export const Home = new KeyButton(Key.Home);\n\n    //% fixedInstance whenUsed\n    export const LeftShift = new KeyButton(Key.LeftShift);\n\n    //% fixedInstance whenUsed\n    export const RightShift = new KeyButton(Key.RightShift);\n\n    //% fixedInstance whenUsed\n    export const LeftControl = new KeyButton(Key.LeftControl);\n\n    //% fixedInstance whenUsed\n    export const RightControl = new KeyButton(Key.RightControl);\n\n    //% fixedInstance whenUsed\n    export const Backspace = new KeyButton(Key.Backspace);\n\n    //% fixedInstance whenUsed\n    export const Delete = new KeyButton(Key.Delete);\n\n    //% fixedInstance whenUsed\n    export const Any = new KeyButton(0);\n\n    //% blockId=browser_events_setKeyboardRepeatDefault\n    //% block=\"set keyboard repeat delay $delay ms interval $interval ms\"\n    //% delay.defl=500\n    //% interval.defl=30\n    //% group=\"Keyboard\"\n    //% weight=0\n    export function setKeyboardRepeatDefault(delay: number, interval: number) {\n        defaultRepeatDelay = Math.max(delay, 0);\n        defaultRepeatInterval = Math.max(interval, 1);\n    }\n}","pxt.json":"{\n    \"name\": \"browser-events\",\n    \"description\": \"A package for interacting with browser-only functionality like keyboard and mouse events\",\n    \"dependencies\": {\n        \"core\": \"*\"\n    },\n    \"files\": [\n        \"browserEvents.cpp\",\n        \"browserEvents.ts\",\n        \"keyboard.ts\",\n        \"shims.d.ts\"\n    ],\n    \"public\": true,\n    \"targetVersions\": {\n        \"target\": \"2.0.56\",\n        \"pxt\": \"11.3.59\"\n    },\n    \"icon\": \"/static/libs/browser-events.png\"\n}\n","shims.d.ts":"declare namespace browserEvents {\n    //% shim=browserEvents::mouseX\n    function mouseX(): number;\n    //% shim=browserEvents::mouseY\n    function mouseY(): number;\n    //% shim=browserEvents::wheelDx\n    function wheelDx(): number;\n    //% shim=browserEvents::wheelDy\n    function wheelDy(): number;\n    //% shim=browserEvents::wheelDz\n    function wheelDz(): number;\n    //% shim=browserEvents::_setCursorVisible\n    function _setCursorVisible(visible: boolean): void;\n\n    //% shim=browserEvents::currentTime\n    function currentTime(): number;\n    //% shim=browserEvents::getYear\n    function getYear(time: number): number;\n    //% shim=browserEvents::getMonth\n    function getMonth(time: number): number;\n    //% shim=browserEvents::getDayOfMonth\n    function getDayOfMonth(time: number): number;\n    //% shim=browserEvents::getDayOfWeek\n    function getDayOfWeek(time: number): number;\n    //% shim=browserEvents::getHours\n    function getHours(time: number): number;\n    //% shim=browserEvents::getMinutes\n    function getMinutes(time: number): number;\n    //% shim=browserEvents::getSeconds\n    function getSeconds(time: number): number;\n}"}},"tutorialInfo":{},"apiInfo":{"libs/animation":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"animation":{"kind":5,"retType":"","attributes":{"color":"#03AA74","weight":5,"icon":"","block":"Animation","groups":["Animate","Advanced"],"_def":{"parts":[{"kind":"label","text":"Animation","style":[]}],"parameters":[]}}},"animation.Animation":{"kind":8,"retType":"animation.Animation","extendsTypes":[]},"animation.Animation.sprites":{"kind":2,"retType":"Sprite[]","isInstance":true},"animation.Animation.frames":{"kind":2,"retType":"Image[]","isInstance":true},"animation.Animation.index":{"kind":2,"retType":"number","isInstance":true},"animation.Animation.interval":{"kind":2,"retType":"number","isInstance":true},"animation.Animation.action":{"kind":2,"retType":"number","isInstance":true},"animation.Animation.lastTime":{"kind":2,"retType":"number","isInstance":true,"pyQName":"animation.Animation.last_time"},"animation.Animation.__constructor":{"kind":-3,"parameters":[{"name":"action"},{"name":"interval"}],"isInstance":true},"animation.Animation._init":{"kind":-1,"parameters":[],"isInstance":true},"animation.Animation.update":{"kind":-1,"parameters":[],"isInstance":true},"animation.Animation.getImage":{"kind":-1,"retType":"Image","parameters":[],"isInstance":true,"pyQName":"animation.Animation.get_image"},"animation.Animation.getAction":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"animation.Animation.get_action"},"animation.Animation.getInterval":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"animation.Animation.get_interval"},"animation.Animation.setInterval":{"kind":-1,"parameters":[{"name":"interval"}],"isInstance":true,"pyQName":"animation.Animation.set_interval"},"animation.Animation.addAnimationFrame":{"kind":-1,"attributes":{"blockId":"addAnimationFrame","block":"add frame $frame=screen_image_picker to $this=variables_get(anim)","group":"Advanced","weight":40,"help":"animation/add-animation-frame","jsDoc":"Add an image frame to an animation","_def":{"parts":[{"kind":"label","text":"add frame ","style":[]},{"kind":"param","name":"frame","shadowBlockId":"screen_image_picker","ref":true},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"this","shadowBlockId":"variables_get","ref":true,"varName":"anim"}],"parameters":[{"kind":"param","name":"frame","shadowBlockId":"screen_image_picker","ref":true},{"kind":"param","name":"this","shadowBlockId":"variables_get","ref":true,"varName":"anim"}]}},"parameters":[{"name":"frame","type":"Image"}],"isInstance":true,"pyQName":"animation.Animation.add_animation_frame"},"animation.Animation.registerSprite":{"kind":-1,"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true,"pyQName":"animation.Animation.register_sprite"},"animation._actionEnumShim":{"kind":-3,"retType":"number","attributes":{"shim":"ENUM_GET","blockId":"action_enum_shim","block":"%arg","group":"Advanced","enumName":"ActionKind","enumMemberName":"action","enumPromptHint":"e.g. Walking, Idle, Jumping, ...","enumInitialMembers":["Walking","Idle","Jumping"],"weight":10,"_def":{"parts":[{"kind":"param","name":"arg","ref":false}],"parameters":[{"kind":"param","name":"arg","ref":false}]}},"parameters":[{"name":"arg"}],"pyQName":"animation._action_enum_shim"},"animation.createAnimation":{"kind":-3,"retType":"animation.Animation","attributes":{"paramDefl":{"interval":"1000"},"blockId":"createAnimation","block":"create animation of $action=action_enum_shim with interval $interval ms","group":"Advanced","explicitDefaults":["interval"],"blockSetVariable":"anim","weight":50,"help":"animation/create-animation","jsDoc":"Create an animation","_def":{"parts":[{"kind":"label","text":"create animation of ","style":[]},{"kind":"param","name":"action","shadowBlockId":"action_enum_shim","ref":true},{"kind":"label","text":" with interval ","style":[]},{"kind":"param","name":"interval","ref":true},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"action","shadowBlockId":"action_enum_shim","ref":true},{"kind":"param","name":"interval","ref":true}]}},"parameters":[{"name":"action"},{"name":"interval","initializer":"1000","default":"1000"}],"pyQName":"animation.create_animation"},"animation.attachAnimation":{"kind":-3,"attributes":{"blockId":"attachAnimation","block":"attach animation $set=variables_get(anim) to sprite $sprite=variables_get(mySprite)","group":"Advanced","weight":30,"help":"animation/attach-animation","jsDoc":"Attach an animation to a sprite","_def":{"parts":[{"kind":"label","text":"attach animation ","style":[]},{"kind":"param","name":"set","shadowBlockId":"variables_get","ref":true,"varName":"anim"},{"kind":"label","text":" to sprite ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"}],"parameters":[{"kind":"param","name":"set","shadowBlockId":"variables_get","ref":true,"varName":"anim"},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"}]}},"parameters":[{"name":"sprite","type":"Sprite"},{"name":"set","type":"animation.Animation"}],"pyQName":"animation.attach_animation"},"animation.setAction":{"kind":-3,"attributes":{"blockId":"setAction","block":"activate animation $action=action_enum_shim on $sprite=variables_get(mySprite)","group":"Advanced","weight":20,"help":"animation/set-action","jsDoc":"Set an animation action to a sprite","_def":{"parts":[{"kind":"label","text":"activate animation ","style":[]},{"kind":"param","name":"action","shadowBlockId":"action_enum_shim","ref":true},{"kind":"label","text":" on ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"}],"parameters":[{"kind":"param","name":"action","shadowBlockId":"action_enum_shim","ref":true},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"}]}},"parameters":[{"name":"sprite","type":"Sprite"},{"name":"action"}],"pyQName":"animation.set_action"}}},"sha":"ce1a07c53536245f330e7a6c411a2959e489ece7e8519f32c1e94a48fade5aba"},"libs/accelerometer":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"input":{"kind":5,"retType":"","attributes":{"color":"#B4009E","weight":98,"icon":"","groups":["other","More"],"jsDoc":"Respond to and read data from buttons and sensors.\n\nEvents and data from sensors."}},"basic":{"kind":5,"retType":""},"input.onCustomGesture":{"kind":-3,"attributes":{"paramHelp":{"id":"@param update true if gesture detected","handler":""},"jsDoc":"Registers a custom gesture recognizer"},"parameters":[{"name":"id","description":"@param update true if gesture detected"},{"name":"update","type":"() => boolean","handlerParameters":[]},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"input.on_custom_gesture"},"input.onGesture":{"kind":-3,"attributes":{"paramDefl":{"gesture":"Gesture.Shake"},"help":"input/on-gesture","blockId":"device_gesture_event","block":"on |%NAME","parts":"accelerometer","paramFieldEditor":{"gesture":"gridpicker"},"paramFieldEditorOptions":{"gesture":{"width":"220","columns":"3"}},"weight":92,"blockGap":"12","paramHelp":{"gesture":"the type of gesture to track, eg: Gesture.Shake","body":"code to run when gesture is raised"},"jsDoc":"Do something when a gesture happens (like shaking the board).","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"gesture","description":"the type of gesture to track, eg: Gesture.Shake","type":"Gesture","default":"Gesture.Shake","isEnum":true},{"name":"body","description":"code to run when gesture is raised","type":"() => void","handlerParameters":[]}],"pyQName":"input.on_gesture"},"input.acceleration":{"kind":-3,"retType":"number","attributes":{"help":"input/acceleration","blockId":"device_acceleration","block":"acceleration (mg)|%NAME","parts":"accelerometer","paramFieldEditor":{"dimension":"gridpicker"},"paramFieldEditorOptions":{"dimension":{"width":"180","columns":"2"}},"weight":42,"blockGap":"8","paramHelp":{"dimension":"TODO"},"jsDoc":"Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\nx=0, y=0 and z=-1023)","_def":{"parts":[{"kind":"label","text":"acceleration (mg)","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"dimension","description":"TODO","type":"Dimension","isEnum":true}]},"input.rotation":{"kind":-3,"retType":"number","attributes":{"help":"input/rotation","blockId":"device_get_rotation","block":"rotation (°)|%NAME","parts":"accelerometer","group":"More","weight":38,"paramHelp":{"kind":"TODO"},"jsDoc":"The pitch or roll of the device, rotation along the ``x-axis`` or ``y-axis``, in degrees.","_def":{"parts":[{"kind":"label","text":"rotation (°)","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"kind","description":"TODO","type":"Rotation","isEnum":true}]},"input.setAccelerometerRange":{"kind":-3,"attributes":{"help":"input/set-accelerometer-range","blockId":"device_set_accelerometer_range","block":"set accelerometer|range %range","weight":15,"parts":"accelerometer","group":"More","blockGap":"8","paramHelp":{"range":"a value describe the maximum strengh of acceleration measured"},"jsDoc":"Sets the accelerometer sample range in gravities.","_def":{"parts":[{"kind":"label","text":"set accelerometer","style":[]},{"kind":"break"},{"kind":"label","text":"range ","style":[]},{"kind":"param","name":"range","ref":false}],"parameters":[{"kind":"param","name":"range","ref":false}]}},"parameters":[{"name":"range","description":"a value describe the maximum strengh of acceleration measured","type":"AcceleratorRange","isEnum":true}],"pyQName":"input.set_accelerometer_range"},"Dimension":{"kind":6,"retType":"Dimension","extendsTypes":["Dimension","Number"]},"Dimension.X":{"retType":"Dimension.X","attributes":{"block":"x","_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"extendsTypes":["Dimension.X","Number"]},"Dimension.Y":{"retType":"Dimension.Y","attributes":{"block":"y","_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"extendsTypes":["Dimension.Y","Number"]},"Dimension.Z":{"retType":"Dimension.Z","attributes":{"block":"z","_def":{"parts":[{"kind":"label","text":"z","style":[]}],"parameters":[]}},"extendsTypes":["Dimension.Z","Number"]},"Dimension.Strength":{"retType":"Dimension.Strength","attributes":{"block":"strength","_def":{"parts":[{"kind":"label","text":"strength","style":[]}],"parameters":[]}},"extendsTypes":["Dimension.Strength","Number"],"pyQName":"Dimension.STRENGTH"},"Rotation":{"kind":6,"retType":"Rotation","extendsTypes":["Rotation","Number"]},"Rotation.Pitch":{"retType":"Rotation.Pitch","attributes":{"block":"pitch","_def":{"parts":[{"kind":"label","text":"pitch","style":[]}],"parameters":[]}},"extendsTypes":["Rotation.Pitch","Number"],"pyQName":"Rotation.PITCH"},"Rotation.Roll":{"retType":"Rotation.Roll","attributes":{"block":"roll","_def":{"parts":[{"kind":"label","text":"roll","style":[]}],"parameters":[]}},"extendsTypes":["Rotation.Roll","Number"],"pyQName":"Rotation.ROLL"},"AcceleratorRange":{"kind":6,"retType":"AcceleratorRange","extendsTypes":["AcceleratorRange","Number"]},"AcceleratorRange.OneG":{"retType":"AcceleratorRange.OneG","attributes":{"block":"1g","jsDoc":"The accelerator measures forces up to 1 gravity","_def":{"parts":[{"kind":"label","text":"1g","style":[]}],"parameters":[]}},"extendsTypes":["AcceleratorRange.OneG","Number"],"pyQName":"AcceleratorRange.ONE_G"},"AcceleratorRange.TwoG":{"retType":"AcceleratorRange.TwoG","attributes":{"block":"2g","jsDoc":"The accelerator measures forces up to 2 gravity","_def":{"parts":[{"kind":"label","text":"2g","style":[]}],"parameters":[]}},"extendsTypes":["AcceleratorRange.TwoG","Number"],"pyQName":"AcceleratorRange.TWO_G"},"AcceleratorRange.FourG":{"retType":"AcceleratorRange.FourG","attributes":{"block":"4g","jsDoc":"The accelerator measures forces up to 4 gravity","_def":{"parts":[{"kind":"label","text":"4g","style":[]}],"parameters":[]}},"extendsTypes":["AcceleratorRange.FourG","Number"],"pyQName":"AcceleratorRange.FOUR_G"},"AcceleratorRange.EightG":{"retType":"AcceleratorRange.EightG","attributes":{"block":"8g","jsDoc":"The accelerator measures forces up to 8 gravity","_def":{"parts":[{"kind":"label","text":"8g","style":[]}],"parameters":[]}},"extendsTypes":["AcceleratorRange.EightG","Number"],"pyQName":"AcceleratorRange.EIGHT_G"},"Gesture":{"kind":6,"retType":"Gesture","extendsTypes":["Gesture","Number"]},"Gesture.Shake":{"retType":"Gesture.Shake","attributes":{"block":"shake","jsDoc":"Raised when shaken","_def":{"parts":[{"kind":"label","text":"shake","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.Shake","Number"],"pyQName":"Gesture.SHAKE"},"Gesture.TiltUp":{"retType":"Gesture.TiltUp","attributes":{"block":"tilt up","jsDoc":"Raised when the device tilts up","_def":{"parts":[{"kind":"label","text":"tilt up","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.TiltUp","Number"],"pyQName":"Gesture.TILT_UP"},"Gesture.TiltDown":{"retType":"Gesture.TiltDown","attributes":{"block":"tilt down","jsDoc":"Raised when the device tilts down","_def":{"parts":[{"kind":"label","text":"tilt down","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.TiltDown","Number"],"pyQName":"Gesture.TILT_DOWN"},"Gesture.TiltLeft":{"retType":"Gesture.TiltLeft","attributes":{"block":"tilt left","jsDoc":"Raised when the screen is pointing left","_def":{"parts":[{"kind":"label","text":"tilt left","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.TiltLeft","Number"],"pyQName":"Gesture.TILT_LEFT"},"Gesture.TiltRight":{"retType":"Gesture.TiltRight","attributes":{"block":"tilt right","jsDoc":"Raised when the screen is pointing right","_def":{"parts":[{"kind":"label","text":"tilt right","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.TiltRight","Number"],"pyQName":"Gesture.TILT_RIGHT"},"Gesture.FaceUp":{"retType":"Gesture.FaceUp","attributes":{"block":"face up","jsDoc":"Raised when the screen faces up","_def":{"parts":[{"kind":"label","text":"face up","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.FaceUp","Number"],"pyQName":"Gesture.FACE_UP"},"Gesture.FaceDown":{"retType":"Gesture.FaceDown","attributes":{"block":"face down","jsDoc":"Raised when the screen is pointing up and the board is horizontal","_def":{"parts":[{"kind":"label","text":"face down","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.FaceDown","Number"],"pyQName":"Gesture.FACE_DOWN"},"Gesture.FreeFall":{"retType":"Gesture.FreeFall","attributes":{"block":"free fall","jsDoc":"Raised when the board is falling!","_def":{"parts":[{"kind":"label","text":"free fall","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.FreeFall","Number"],"pyQName":"Gesture.FREE_FALL"},"Gesture.TwoG":{"retType":"Gesture.TwoG","attributes":{"block":"2g (step)","jsDoc":"Raised when a 2G shock is detected","_def":{"parts":[{"kind":"label","text":"2g (step)","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.TwoG","Number"],"pyQName":"Gesture.TWO_G"},"Gesture.ThreeG":{"retType":"Gesture.ThreeG","attributes":{"block":"3g","jsDoc":"Raised when a 3G shock is detected","_def":{"parts":[{"kind":"label","text":"3g","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.ThreeG","Number"],"pyQName":"Gesture.THREE_G"},"Gesture.SixG":{"retType":"Gesture.SixG","attributes":{"block":"6g","jsDoc":"Raised when a 6G shock is detected","_def":{"parts":[{"kind":"label","text":"6g","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.SixG","Number"],"pyQName":"Gesture.SIX_G"},"Gesture.EightG":{"retType":"Gesture.EightG","attributes":{"block":"8g","jsDoc":"Raised when a 8G shock is detected","_def":{"parts":[{"kind":"label","text":"8g","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.EightG","Number"],"pyQName":"Gesture.EIGHT_G"}}},"sha":"1d616e98a8b9659d6bb485146178b7ce5bafdbc751dd0f3de0cb9afed2596554"},"libs/azureiot":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"net":{"kind":5,"retType":"","attributes":{"weight":1,"advanced":true,"icon":"","color":"#8446cf","jsDoc":"Networking, WiFi, web requests"}},"net.ControllerEvent":{"kind":6,"retType":"net.ControllerEvent","extendsTypes":["net.ControllerEvent","Number"]},"net.ControllerEvent.NewScan":{"retType":"net.ControllerEvent.NewScan","extendsTypes":["net.ControllerEvent.NewScan","Number"],"pyQName":"net.ControllerEvent.NEW_SCAN"},"net.ControllerEvent.GotIP":{"retType":"net.ControllerEvent.GotIP","extendsTypes":["net.ControllerEvent.GotIP","Number"],"pyQName":"net.ControllerEvent.GOT_IP"},"net.ControllerEvent.LostIP":{"retType":"net.ControllerEvent.LostIP","extendsTypes":["net.ControllerEvent.LostIP","Number"],"pyQName":"net.ControllerEvent.LOST_IP"},"net.ControllerEvent.NoScannedNetworks":{"retType":"net.ControllerEvent.NoScannedNetworks","extendsTypes":["net.ControllerEvent.NoScannedNetworks","Number"],"pyQName":"net.ControllerEvent.NO_SCANNED_NETWORKS"},"net.ControllerEvent.NoKnownNetworks":{"retType":"net.ControllerEvent.NoKnownNetworks","extendsTypes":["net.ControllerEvent.NoKnownNetworks","Number"],"pyQName":"net.ControllerEvent.NO_KNOWN_NETWORKS"},"net.ControllerEvent.Connecting":{"retType":"net.ControllerEvent.Connecting","extendsTypes":["net.ControllerEvent.Connecting","Number"],"pyQName":"net.ControllerEvent.CONNECTING"},"net.ControllerEvent.ConnectionFailed":{"retType":"net.ControllerEvent.ConnectionFailed","extendsTypes":["net.ControllerEvent.ConnectionFailed","Number"],"pyQName":"net.ControllerEvent.CONNECTION_FAILED"},"net.ControllerEvent.LoginServerStarted":{"retType":"net.ControllerEvent.LoginServerStarted","extendsTypes":["net.ControllerEvent.LoginServerStarted","Number"],"pyQName":"net.ControllerEvent.LOGIN_SERVER_STARTED"},"net.Controller":{"kind":8,"retType":"net.Controller","extendsTypes":["net.Controller"]},"net.Controller.eventID":{"kind":2,"retType":"number","isInstance":true,"pyQName":"net.Controller.event_id"},"net.Controller.onConnectSSIDFailed":{"kind":2,"retType":"(ssid: string) => void","isInstance":true,"pyQName":"net.Controller.on_connect_ssid_failed"},"net.Controller.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"net.Controller.onEvent":{"kind":-1,"parameters":[{"name":"ev","type":"net.ControllerEvent","isEnum":true},{"name":"h","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Controller.on_event"},"net.Controller.scanNetworks":{"kind":-1,"retType":"net.AccessPoint[]","parameters":[],"isInstance":true,"pyQName":"net.Controller.scan_networks"},"net.Controller.startLoginServer":{"kind":-1,"parameters":[{"name":"hostName","type":"string"}],"isInstance":true,"pyQName":"net.Controller.start_login_server"},"net.Controller.isLoginServerEnabled":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"net.Controller.is_login_server_enabled"},"net.Controller.socket":{"kind":-1,"retType":"number","parameters":[],"isInstance":true},"net.Controller.socketConnect":{"kind":-1,"retType":"boolean","parameters":[{"name":"socket_num"},{"name":"dest","type":"string | Buffer"},{"name":"port"},{"name":"conn_mode","initializer":"TCP_MODE"}],"isInstance":true,"pyQName":"net.Controller.socket_connect"},"net.Controller.socketWrite":{"kind":-1,"parameters":[{"name":"socket_num"},{"name":"buffer","type":"Buffer"}],"isInstance":true,"pyQName":"net.Controller.socket_write"},"net.Controller.socketAvailable":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.socket_available"},"net.Controller.socketRead":{"kind":-1,"retType":"Buffer","parameters":[{"name":"socket_num"},{"name":"size"}],"isInstance":true,"pyQName":"net.Controller.socket_read"},"net.Controller.socketClose":{"kind":-1,"parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.socket_close"},"net.Controller.hostbyName":{"kind":-1,"retType":"Buffer","parameters":[{"name":"hostname","type":"string"}],"isInstance":true,"pyQName":"net.Controller.hostby_name"},"net.Controller.isIdle":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.is_idle"},"net.Controller.isConnected":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.is_connected"},"net.Controller.connectAP":{"kind":-1,"retType":"boolean","parameters":[{"name":"bssid","type":"string"},{"name":"password","type":"string"}],"isInstance":true,"pyQName":"net.Controller.connect_ap"},"net.Controller.disconnectAP":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"net.Controller.disconnect_ap"},"net.Controller.lastScanResults":{"kind":2,"retType":"net.AccessPoint[]","isInstance":true,"pyQName":"net.Controller.last_scan_results"},"net.Controller.autoconnect":{"kind":-1,"parameters":[],"isInstance":true},"net.Controller.disconnect":{"kind":-1,"parameters":[],"isInstance":true},"net.Controller.connect":{"kind":-1,"retType":"boolean","parameters":[{"name":"timeout_ms","initializer":"undefined"}],"isInstance":true},"net.Controller.ssid":{"kind":-2,"retType":"string","isInstance":true,"isReadOnly":true},"net.Controller.rssi":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"net.Controller.MACaddress":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.ma_caddress"},"net.Controller.IPaddress":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.ipaddress"},"net.Controller.ping":{"kind":-1,"retType":"number","parameters":[{"name":"dest","type":"string"},{"name":"ttl","initializer":"250"}],"isInstance":true},"net.Controller.dataAvailableSrc":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.data_available_src"},"net.Controller.dataAvailableValue":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.data_available_value"},"net.SOCK_STREAM":{"kind":4,"retType":"number"},"net.AF_INET":{"kind":4,"retType":"number"},"net.MAX_PACKET":{"kind":4,"retType":"number"},"net.TCP_MODE":{"kind":4,"retType":"number"},"net.UDP_MODE":{"kind":4,"retType":"number"},"net.TLS_MODE":{"kind":4,"retType":"number"},"net.ControllerSocket":{"kind":8,"retType":"net.ControllerSocket","extendsTypes":["net.ControllerSocket","net.Socket"]},"net.ControllerSocket._buffer":{"kind":2,"retType":"Buffer","isInstance":true},"net.ControllerSocket._socknum":{"kind":2,"retType":"number","isInstance":true},"net.ControllerSocket._timeout":{"kind":2,"retType":"number","isInstance":true},"net.ControllerSocket._closed":{"kind":2,"retType":"boolean","isInstance":true},"net.ControllerSocket._openHandler":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"net.ControllerSocket._open_handler"},"net.ControllerSocket._closeHandler":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"net.ControllerSocket._close_handler"},"net.ControllerSocket._errorHandler":{"kind":2,"retType":"(msg: string) => void","isInstance":true,"pyQName":"net.ControllerSocket._error_handler"},"net.ControllerSocket._messageHandler":{"kind":2,"retType":"(data: Buffer) => void","isInstance":true,"pyQName":"net.ControllerSocket._message_handler"},"net.ControllerSocket.__constructor":{"kind":-3,"attributes":{"jsDoc":"A simplified implementation of the Python 'socket' class, for connecting\nthrough an interface to a remote device"},"parameters":[{"name":"controller","type":"net.Controller"},{"name":"host","type":"string | Buffer"},{"name":"port"},{"name":"conntype","initializer":"null"}],"isInstance":true},"net.ControllerSocket.connect":{"kind":-1,"attributes":{"jsDoc":"Connect the socket to the 'address' (which can be 32bit packed IP or\na hostname string). 'conntype' is an extra that may indicate SSL or not,\ndepending on the underlying interface"},"parameters":[],"isInstance":true},"net.ControllerSocket.send":{"kind":-1,"attributes":{"jsDoc":"Send some data to the socket"},"parameters":[{"name":"data","type":"string | Buffer"}],"isInstance":true},"net.ControllerSocket.onOpen":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_open"},"net.ControllerSocket.onClose":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_close"},"net.ControllerSocket.onError":{"kind":-1,"parameters":[{"name":"handler","type":"(msg: string) => void","handlerParameters":[{"name":"msg","type":"string"}]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_error"},"net.ControllerSocket.onMessage":{"kind":-1,"parameters":[{"name":"handler","type":"(data: Buffer) => void","handlerParameters":[{"name":"data","type":"Buffer"}]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_message"},"net.ControllerSocket.readLine":{"kind":-1,"retType":"string","attributes":{"jsDoc":"Attempt to return as many bytes as we can up to but not including '\\r\\n'"},"parameters":[],"isInstance":true,"pyQName":"net.ControllerSocket.read_line"},"net.ControllerSocket.read":{"kind":-1,"retType":"Buffer","attributes":{"jsDoc":"Read up to 'size' bytes from the socket, this may be buffered internally! If 'size' isn't specified, return everything in the buffer."},"parameters":[{"name":"size","initializer":"0"}],"isInstance":true},"net.ControllerSocket.setTimeout":{"kind":-1,"attributes":{"jsDoc":"Set the read timeout for sockets, if value is 0 it will block"},"parameters":[{"name":"value"}],"isInstance":true,"pyQName":"net.ControllerSocket.set_timeout"},"net.ControllerSocket.close":{"kind":-1,"attributes":{"jsDoc":"Close the socket, after reading whatever remains"},"parameters":[],"isInstance":true},"net.logPriority":{"kind":4,"retType":"ConsolePriority","attributes":{"jsDoc":"Default priority of net log messages"},"pyQName":"net.log_priority"},"net.log":{"kind":-3,"parameters":[{"name":"msg","type":"string"}]},"net.debug":{"kind":-3,"parameters":[{"name":"msg","type":"string"}]},"net.fail":{"kind":-3,"parameters":[{"name":"reason","type":"string"}]},"net.monotonic":{"kind":-3,"retType":"number","parameters":[]},"net.WifiAPFlags":{"kind":6,"retType":"net.WifiAPFlags","extendsTypes":["net.WifiAPFlags","Number"]},"net.WifiAPFlags.HasPassword":{"retType":"net.WifiAPFlags.HasPassword","extendsTypes":["net.WifiAPFlags.HasPassword","Number"],"pyQName":"net.WifiAPFlags.HAS_PASSWORD"},"net.WifiAPFlags.WPS":{"retType":"net.WifiAPFlags.WPS","extendsTypes":["net.WifiAPFlags.WPS","Number"]},"net.WifiAPFlags.HasSecondaryChannelAbove":{"retType":"net.WifiAPFlags.HasSecondaryChannelAbove","extendsTypes":["net.WifiAPFlags.HasSecondaryChannelAbove","Number"],"pyQName":"net.WifiAPFlags.HAS_SECONDARY_CHANNEL_ABOVE"},"net.WifiAPFlags.HasSecondaryChannelBelow":{"retType":"net.WifiAPFlags.HasSecondaryChannelBelow","extendsTypes":["net.WifiAPFlags.HasSecondaryChannelBelow","Number"],"pyQName":"net.WifiAPFlags.HAS_SECONDARY_CHANNEL_BELOW"},"net.WifiAPFlags.IEEE_802_11B":{"retType":"net.WifiAPFlags.IEEE_802_11B","extendsTypes":["net.WifiAPFlags.IEEE_802_11B","Number"]},"net.WifiAPFlags.IEEE_802_11A":{"retType":"net.WifiAPFlags.IEEE_802_11A","extendsTypes":["net.WifiAPFlags.IEEE_802_11A","Number"]},"net.WifiAPFlags.IEEE_802_11G":{"retType":"net.WifiAPFlags.IEEE_802_11G","extendsTypes":["net.WifiAPFlags.IEEE_802_11G","Number"]},"net.WifiAPFlags.IEEE_802_11N":{"retType":"net.WifiAPFlags.IEEE_802_11N","extendsTypes":["net.WifiAPFlags.IEEE_802_11N","Number"]},"net.WifiAPFlags.IEEE_802_11AC":{"retType":"net.WifiAPFlags.IEEE_802_11AC","extendsTypes":["net.WifiAPFlags.IEEE_802_11AC","Number"]},"net.WifiAPFlags.IEEE_802_11AX":{"retType":"net.WifiAPFlags.IEEE_802_11AX","extendsTypes":["net.WifiAPFlags.IEEE_802_11AX","Number"]},"net.WifiAPFlags.IEEE_802_LongRange":{"retType":"net.WifiAPFlags.IEEE_802_LongRange","extendsTypes":["net.WifiAPFlags.IEEE_802_LongRange","Number"],"pyQName":"net.WifiAPFlags.IEEE_802_LONGRANGE"},"net.AccessPoint":{"kind":8,"retType":"net.AccessPoint","extendsTypes":[]},"net.AccessPoint.flags":{"kind":2,"retType":"net.WifiAPFlags","isInstance":true},"net.AccessPoint.rssi":{"kind":2,"retType":"number","isInstance":true},"net.AccessPoint.bssid":{"kind":2,"retType":"Buffer","isInstance":true},"net.AccessPoint.channel":{"kind":2,"retType":"number","isInstance":true},"net.AccessPoint.__constructor":{"kind":-3,"parameters":[{"name":"ssid","type":"string"}],"isInstance":true},"net.AccessPoint.fromBuffer":{"kind":-1,"retType":"net.AccessPoint","parameters":[{"name":"buf","type":"Buffer"}],"pyQName":"net.AccessPoint.from_buffer"},"net.AccessPoint.toBuffer":{"kind":-1,"retType":"Buffer","parameters":[],"isInstance":true,"pyQName":"net.AccessPoint.to_buffer"},"net.Socket":{"kind":9,"retType":"net.Socket","extendsTypes":["net.Socket"]},"net.Socket.connect":{"kind":-1,"parameters":[],"isInstance":true},"net.Socket.send":{"kind":-1,"parameters":[{"name":"data","type":"string | Buffer"}],"isInstance":true},"net.Socket.read":{"kind":-1,"retType":"Buffer","parameters":[{"name":"contentLength"}],"isInstance":true},"net.Socket.close":{"kind":-1,"parameters":[],"isInstance":true},"net.Socket.onOpen":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Socket.on_open"},"net.Socket.onClose":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Socket.on_close"},"net.Socket.onError":{"kind":-1,"parameters":[{"name":"handler","type":"(msg: string) => void","handlerParameters":[{"name":"msg","type":"string"}]}],"isInstance":true,"pyQName":"net.Socket.on_error"},"net.Socket.onMessage":{"kind":-1,"parameters":[{"name":"handler","type":"(data: Buffer) => void","handlerParameters":[{"name":"data","type":"Buffer"}]}],"isInstance":true,"pyQName":"net.Socket.on_message"},"net.Socket.setTimeout":{"kind":-1,"parameters":[{"name":"millis"}],"isInstance":true,"pyQName":"net.Socket.set_timeout"},"net.Socket.readLine":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"net.Socket.read_line"},"net.Net":{"kind":8,"retType":"net.Net","extendsTypes":[]},"net.Net.__constructor":{"kind":-3,"parameters":[{"name":"factory","type":"() => net.Controller","handlerParameters":[]}],"isInstance":true},"net.Net.instance":{"kind":2,"retType":"net.Net"},"net.Net.controller":{"kind":-2,"retType":"net.Controller","isInstance":true,"isReadOnly":true},"net.Net.scanNetworks":{"kind":-1,"retType":"net.AccessPoint[]","attributes":{"jsDoc":"Scan for APs"},"parameters":[],"isInstance":true,"pyQName":"net.Net.scan_networks"},"net.Net.createSocket":{"kind":-1,"retType":"net.Socket","parameters":[{"name":"host","type":"string"},{"name":"port"},{"name":"secure","type":"boolean"}],"isInstance":true,"pyQName":"net.Net.create_socket"},"net.Net.hostByName":{"kind":-1,"retType":"string","parameters":[{"name":"host","type":"string"}],"isInstance":true,"pyQName":"net.Net.host_by_name"},"net.instance":{"kind":-3,"retType":"net.Net","attributes":{"jsDoc":"Gets the current Net instance"},"parameters":[]},"net.knownAccessPoints":{"kind":-3,"retType":"StringMap","attributes":{"jsDoc":"Gets the map of SSID -> password pairs"},"parameters":[],"pyQName":"net.known_access_points"},"net.clearAccessPoint":{"kind":-3,"parameters":[{"name":"ssid","type":"string"}],"pyQName":"net.clear_access_point"},"net.updateAccessPoint":{"kind":-3,"parameters":[{"name":"ssid","type":"string"},{"name":"password","type":"string"}],"pyQName":"net.update_access_point"},"net.setAccessPointPriority":{"kind":-3,"parameters":[{"name":"ssid","type":"string"},{"name":"pri"}],"pyQName":"net.set_access_point_priority"},"net.accessPointPriorities":{"kind":-3,"retType":"any","parameters":[],"pyQName":"net.access_point_priorities"},"net.clearAccessPoints":{"kind":-3,"parameters":[],"pyQName":"net.clear_access_points"},"net.urlencode":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"}]},"net.urldecode":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"}]},"net.ping":{"kind":-3,"retType":"number","attributes":{"blockId":"netping","block":"net ping $dest","paramHelp":{"dest":"host name","ttl":""},"jsDoc":"Pings a web site","_def":{"parts":[{"kind":"label","text":"net ping ","style":[]},{"kind":"param","name":"dest","ref":true}],"parameters":[{"kind":"param","name":"dest","ref":true}]}},"parameters":[{"name":"dest","description":"host name","type":"string"},{"name":"ttl","initializer":"250"}]},"net.Response":{"kind":8,"retType":"net.Response","extendsTypes":[]},"net.Response._cached":{"kind":2,"retType":"Buffer","isInstance":true},"net.Response.status_code":{"kind":2,"retType":"number","isInstance":true},"net.Response.reason":{"kind":2,"retType":"string","isInstance":true},"net.Response._read_so_far":{"kind":2,"retType":"number","isInstance":true},"net.Response.headers":{"kind":2,"retType":"StringMap","isInstance":true},"net.Response.__constructor":{"kind":-3,"attributes":{"jsDoc":"The response from a request, contains all the headers/content"},"parameters":[{"name":"socket","type":"net.Socket"}],"isInstance":true},"net.Response.close":{"kind":-1,"attributes":{"jsDoc":"Close, delete and collect the response data"},"parameters":[],"isInstance":true},"net.Response.content":{"kind":-2,"retType":"Buffer","attributes":{"jsDoc":"The HTTP content direct from the socket, as bytes"},"isInstance":true,"isReadOnly":true},"net.Response.text":{"kind":-2,"retType":"string","attributes":{"jsDoc":"The HTTP content, encoded into a string according to the HTTP header encoding"},"isInstance":true,"isReadOnly":true},"net.Response.json":{"kind":-2,"retType":"any","isInstance":true,"isReadOnly":true},"net.Response.toString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"net.Response.to_string"},"net.RequestOptions":{"kind":9,"retType":"net.RequestOptions","extendsTypes":[]},"net.RequestOptions.data":{"kind":2,"retType":"string | Buffer","isInstance":true},"net.RequestOptions.json":{"kind":2,"retType":"any","isInstance":true},"net.RequestOptions.headers":{"kind":2,"retType":"StringMap","isInstance":true},"net.RequestOptions.stream":{"kind":2,"retType":"boolean","isInstance":true},"net.RequestOptions.timeout":{"kind":2,"retType":"number","isInstance":true},"net.dataAsBuffer":{"kind":-3,"retType":"Buffer","parameters":[{"name":"data","type":"string | Buffer"}],"pyQName":"net.data_as_buffer"},"net.request":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Perform an HTTP request to the given url which we will parse to determine\nwhether to use SSL ('https://') or not. We can also send some provided 'data'\nor a json dictionary which we will stringify. 'headers' is optional HTTP headers\nsent along. 'stream' will determine if we buffer everything, or whether to only\nread only when requested"},"parameters":[{"name":"method","type":"string"},{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.head":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP HEAD request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.get":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP GET request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.getString":{"kind":-3,"retType":"string","attributes":{"blockId":"netgetstring","block":"get string $url","jsDoc":"Send HTTP GET request and return text","_def":{"parts":[{"kind":"label","text":"get string ","style":[]},{"kind":"param","name":"url","ref":true}],"parameters":[{"kind":"param","name":"url","ref":true}]}},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}],"pyQName":"net.get_string"},"net.getJSON":{"kind":-3,"retType":"any","attributes":{"blockId":"netgetjson","block":"get json $url","jsDoc":"Send HTTP GET request and return JSON","_def":{"parts":[{"kind":"label","text":"get json ","style":[]},{"kind":"param","name":"url","ref":true}],"parameters":[{"kind":"param","name":"url","ref":true}]}},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}],"pyQName":"net.get_json"},"net.post":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP POST request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.patch":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP PATCH request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.put":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP PUT request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.del":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP DELETE request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"esp32":{"kind":5,"retType":""},"esp32.SOCKET_CLOSED":{"kind":4,"retType":"number"},"esp32.SOCKET_LISTEN":{"kind":4,"retType":"number"},"esp32.SOCKET_SYN_SENT":{"kind":4,"retType":"number"},"esp32.SOCKET_SYN_RCVD":{"kind":4,"retType":"number"},"esp32.SOCKET_ESTABLISHED":{"kind":4,"retType":"number"},"esp32.SOCKET_FIN_WAIT_1":{"kind":4,"retType":"number"},"esp32.SOCKET_FIN_WAIT_2":{"kind":4,"retType":"number"},"esp32.SOCKET_CLOSE_WAIT":{"kind":4,"retType":"number"},"esp32.SOCKET_CLOSING":{"kind":4,"retType":"number"},"esp32.SOCKET_LAST_ACK":{"kind":4,"retType":"number"},"esp32.SOCKET_TIME_WAIT":{"kind":4,"retType":"number"},"esp32.WL_NO_SHIELD":{"kind":4,"retType":"number"},"esp32.WL_NO_MODULE":{"kind":4,"retType":"number"},"esp32.WL_IDLE_STATUS":{"kind":4,"retType":"number"},"esp32.WL_NO_SSID_AVAIL":{"kind":4,"retType":"number"},"esp32.WL_SCAN_COMPLETED":{"kind":4,"retType":"number"},"esp32.WL_CONNECTED":{"kind":4,"retType":"number"},"esp32.WL_CONNECT_FAILED":{"kind":4,"retType":"number"},"esp32.WL_CONNECTION_LOST":{"kind":4,"retType":"number"},"esp32.WL_DISCONNECTED":{"kind":4,"retType":"number"},"esp32.WL_AP_LISTENING":{"kind":4,"retType":"number"},"esp32.WL_AP_CONNECTED":{"kind":4,"retType":"number"},"esp32.WL_AP_FAILED":{"kind":4,"retType":"number"},"esp32.NinaController":{"kind":8,"retType":"esp32.NinaController","extendsTypes":["esp32.NinaController","net.Controller"]},"esp32.NinaController.wasConnected":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"esp32.NinaController.was_connected"},"esp32.NinaController.__constructor":{"kind":-3,"parameters":[{"name":"_spi","type":"SPI"},{"name":"_cs","type":"DigitalInOutPin"},{"name":"_busy","type":"DigitalInOutPin"},{"name":"_reset","type":"DigitalInOutPin"},{"name":"_gpio0","type":"DigitalInOutPin","initializer":"null"}],"isInstance":true},"esp32.NinaController.reset":{"kind":-1,"attributes":{"jsDoc":"Hard reset the ESP32 using the reset pin"},"parameters":[],"isInstance":true},"esp32.NinaController.status":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"esp32.NinaController.firmwareVersion":{"kind":-2,"retType":"string","attributes":{"jsDoc":"A string of the firmware version on the ESP32"},"isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.firmware_version"},"esp32.NinaController.MACaddress":{"kind":-2,"retType":"Buffer","attributes":{"jsDoc":"A bytearray containing the MAC address of the ESP32"},"isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.ma_caddress"},"esp32.NinaController.wifiSetNetwork":{"kind":-1,"attributes":{"jsDoc":"Tells the ESP32 to set the access point to the given ssid"},"parameters":[{"name":"ssid","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.wifi_set_network"},"esp32.NinaController.wifiSetPassphrase":{"kind":-1,"attributes":{"jsDoc":"Sets the desired access point ssid and passphrase"},"parameters":[{"name":"ssid","type":"string"},{"name":"passphrase","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.wifi_set_passphrase"},"esp32.NinaController.wifiSetEntidentity":{"kind":-1,"attributes":{"jsDoc":"Sets the WPA2 Enterprise anonymous identity"},"parameters":[{"name":"ident","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.wifi_set_entidentity"},"esp32.NinaController.wifiSetEntusername":{"kind":-1,"attributes":{"jsDoc":"Sets the desired WPA2 Enterprise username"},"parameters":[{"name":"username","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.wifi_set_entusername"},"esp32.NinaController.wifiSetEntpassword":{"kind":-1,"attributes":{"jsDoc":"Sets the desired WPA2 Enterprise password"},"parameters":[{"name":"password","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.wifi_set_entpassword"},"esp32.NinaController.wifiSetEntenable":{"kind":-1,"attributes":{"jsDoc":"Enables WPA2 Enterprise mode"},"parameters":[],"isInstance":true,"pyQName":"esp32.NinaController.wifi_set_entenable"},"esp32.NinaController.ssidBuffer":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.ssid_buffer"},"esp32.NinaController.ssid":{"kind":-2,"retType":"string","isInstance":true,"isReadOnly":true},"esp32.NinaController.rssi":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"esp32.NinaController.networkData":{"kind":-2,"retType":"any","isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.network_data"},"esp32.NinaController.ipAddress":{"kind":-2,"retType":"string","isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.ip_address"},"esp32.NinaController.isConnected":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.is_connected"},"esp32.NinaController.isIdle":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.is_idle"},"esp32.NinaController.connectAP":{"kind":-1,"retType":"boolean","attributes":{"jsDoc":"Connect to an access point with given name and password.\nWill retry up to 10 times and return on success"},"parameters":[{"name":"ssid","type":"string"},{"name":"password","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.connect_ap"},"esp32.NinaController.hostbyName":{"kind":-1,"retType":"Buffer","attributes":{"jsDoc":"Convert a hostname to a packed 4-byte IP address. Returns\na 4 bytearray"},"parameters":[{"name":"hostname","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.hostby_name"},"esp32.NinaController.ping":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Ping a destination IP address or hostname, with a max time-to-live\n(ttl). Returns a millisecond timing value"},"parameters":[{"name":"dest","type":"string"},{"name":"ttl","initializer":"250"}],"isInstance":true},"esp32.NinaController.socket":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Request a socket from the ESP32, will allocate and return a number that\ncan then be passed to the other socket commands"},"parameters":[],"isInstance":true},"esp32.NinaController.socketOpen":{"kind":-1,"attributes":{"jsDoc":"Open a socket to a destination IP address or hostname\nusing the ESP32's internal reference number. By default we use\n'conn_mode' TCP_MODE but can also use UDP_MODE or TLS_MODE\n(dest must be hostname for TLS_MODE!)"},"parameters":[{"name":"socket_num"},{"name":"dest","type":"string | Buffer"},{"name":"port"},{"name":"conn_mode","initializer":"net.TCP_MODE"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_open"},"esp32.NinaController.socketStatus":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Get the socket connection status, can be SOCKET_CLOSED, SOCKET_LISTEN,\nSOCKET_SYN_SENT, SOCKET_SYN_RCVD, SOCKET_ESTABLISHED, SOCKET_FIN_WAIT_1,\nSOCKET_FIN_WAIT_2, SOCKET_CLOSE_WAIT, SOCKET_CLOSING, SOCKET_LAST_ACK, or\nSOCKET_TIME_WAIT"},"parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_status"},"esp32.NinaController.socket_connected":{"kind":-1,"retType":"boolean","attributes":{"jsDoc":"Test if a socket is connected to the destination, returns boolean true/false"},"parameters":[{"name":"socket_num"}],"isInstance":true},"esp32.NinaController.socketWrite":{"kind":-1,"attributes":{"jsDoc":"Write the bytearray buffer to a socket"},"parameters":[{"name":"socket_num"},{"name":"buffer","type":"Buffer"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_write"},"esp32.NinaController.socketAvailable":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Determine how many bytes are waiting to be read on the socket"},"parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_available"},"esp32.NinaController.socketRead":{"kind":-1,"retType":"Buffer","attributes":{"jsDoc":"Read up to 'size' bytes from the socket number. Returns a bytearray"},"parameters":[{"name":"socket_num"},{"name":"size"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_read"},"esp32.NinaController.socketConnect":{"kind":-1,"retType":"boolean","attributes":{"jsDoc":"Open and verify we connected a socket to a destination IP address or hostname\nusing the ESP32's internal reference number. By default we use\n'conn_mode' TCP_MODE but can also use UDP_MODE or TLS_MODE (dest must\nbe hostname for TLS_MODE!)"},"parameters":[{"name":"socket_num"},{"name":"dest","type":"string | Buffer"},{"name":"port"},{"name":"conn_mode","initializer":"net.TCP_MODE"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_connect"},"esp32.NinaController.socketClose":{"kind":-1,"attributes":{"jsDoc":"Close a socket using the ESP32's internal reference number"},"parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_close"},"esp32.NinaController.setESPdebug":{"kind":-1,"attributes":{"jsDoc":"Enable/disable debug mode on the ESP32. Debug messages will be\nwritten to the ESP32's UART."},"parameters":[{"name":"enabled","type":"boolean"}],"isInstance":true,"pyQName":"esp32.NinaController.set_es_pdebug"},"esp32.NinaController.getTemperature":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"esp32.NinaController.get_temperature"},"esp32.NinaController.setPinMode":{"kind":-1,"attributes":{"jsDoc":"Set the io mode for a GPIO pin.\n:param int pin: ESP32 GPIO pin to set.\n:param value: direction for pin, digitalio.Direction or integer (0=input, 1=output)."},"parameters":[{"name":"pin"},{"name":"pin_mode"}],"isInstance":true,"pyQName":"esp32.NinaController.set_pin_mode"},"esp32.NinaController.setDigitalWrite":{"kind":-1,"attributes":{"jsDoc":"Set the digital output value of pin.\n:param int pin: ESP32 GPIO pin to write to.\n:param bool value: Value for the pin."},"parameters":[{"name":"pin"},{"name":"value"}],"isInstance":true,"pyQName":"esp32.NinaController.set_digital_write"},"esp32.NinaController.setAnalogWrite":{"kind":-1,"attributes":{"jsDoc":"Set the analog output value of pin, using PWM.\n:param int pin: ESP32 GPIO pin to write to.\n:param float value: 0=off 1.0=full on"},"parameters":[{"name":"pin"},{"name":"analog_value"}],"isInstance":true,"pyQName":"esp32.NinaController.set_analog_write"},"esp32.flashDevice":{"kind":-3,"parameters":[],"pyQName":"esp32.flash_device"},"mqtt":{"kind":5,"retType":""},"mqtt.ConnectFlags":{"kind":6,"retType":"mqtt.ConnectFlags","attributes":{"jsDoc":"Connect flags\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc385349229"},"extendsTypes":["mqtt.ConnectFlags","Number"]},"mqtt.ConnectFlags.UserName":{"retType":"mqtt.ConnectFlags.UserName","extendsTypes":["mqtt.ConnectFlags.UserName","Number"],"pyQName":"mqtt.ConnectFlags.USER_NAME"},"mqtt.ConnectFlags.Password":{"retType":"mqtt.ConnectFlags.Password","extendsTypes":["mqtt.ConnectFlags.Password","Number"],"pyQName":"mqtt.ConnectFlags.PASSWORD"},"mqtt.ConnectFlags.WillRetain":{"retType":"mqtt.ConnectFlags.WillRetain","extendsTypes":["mqtt.ConnectFlags.WillRetain","Number"],"pyQName":"mqtt.ConnectFlags.WILL_RETAIN"},"mqtt.ConnectFlags.WillQoS2":{"retType":"mqtt.ConnectFlags.WillQoS2","extendsTypes":["mqtt.ConnectFlags.WillQoS2","Number"],"pyQName":"mqtt.ConnectFlags.WILL_QO_S2"},"mqtt.ConnectFlags.WillQoS1":{"retType":"mqtt.ConnectFlags.WillQoS1","extendsTypes":["mqtt.ConnectFlags.WillQoS1","Number"],"pyQName":"mqtt.ConnectFlags.WILL_QO_S1"},"mqtt.ConnectFlags.Will":{"retType":"mqtt.ConnectFlags.Will","extendsTypes":["mqtt.ConnectFlags.Will","Number"],"pyQName":"mqtt.ConnectFlags.WILL"},"mqtt.ConnectFlags.CleanSession":{"retType":"mqtt.ConnectFlags.CleanSession","extendsTypes":["mqtt.ConnectFlags.CleanSession","Number"],"pyQName":"mqtt.ConnectFlags.CLEAN_SESSION"},"mqtt.ConnectReturnCode":{"kind":6,"retType":"mqtt.ConnectReturnCode","attributes":{"jsDoc":"Connect Return code\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc385349256"},"extendsTypes":["mqtt.ConnectReturnCode","Number"]},"mqtt.ConnectReturnCode.Unknown":{"retType":"mqtt.ConnectReturnCode.Unknown","extendsTypes":["mqtt.ConnectReturnCode.Unknown","Number"],"pyQName":"mqtt.ConnectReturnCode.UNKNOWN"},"mqtt.ConnectReturnCode.Accepted":{"retType":"mqtt.ConnectReturnCode.Accepted","extendsTypes":["mqtt.ConnectReturnCode.Accepted","Number"],"pyQName":"mqtt.ConnectReturnCode.ACCEPTED"},"mqtt.ConnectReturnCode.UnacceptableProtocolVersion":{"retType":"mqtt.ConnectReturnCode.UnacceptableProtocolVersion","extendsTypes":["mqtt.ConnectReturnCode.UnacceptableProtocolVersion","Number"],"pyQName":"mqtt.ConnectReturnCode.UNACCEPTABLE_PROTOCOL_VERSION"},"mqtt.ConnectReturnCode.IdentifierRejected":{"retType":"mqtt.ConnectReturnCode.IdentifierRejected","extendsTypes":["mqtt.ConnectReturnCode.IdentifierRejected","Number"],"pyQName":"mqtt.ConnectReturnCode.IDENTIFIER_REJECTED"},"mqtt.ConnectReturnCode.ServerUnavailable":{"retType":"mqtt.ConnectReturnCode.ServerUnavailable","extendsTypes":["mqtt.ConnectReturnCode.ServerUnavailable","Number"],"pyQName":"mqtt.ConnectReturnCode.SERVER_UNAVAILABLE"},"mqtt.ConnectReturnCode.BadUserNameOrPassword":{"retType":"mqtt.ConnectReturnCode.BadUserNameOrPassword","extendsTypes":["mqtt.ConnectReturnCode.BadUserNameOrPassword","Number"],"pyQName":"mqtt.ConnectReturnCode.BAD_USER_NAME_OR_PASSWORD"},"mqtt.ConnectReturnCode.NotAuthorized":{"retType":"mqtt.ConnectReturnCode.NotAuthorized","extendsTypes":["mqtt.ConnectReturnCode.NotAuthorized","Number"],"pyQName":"mqtt.ConnectReturnCode.NOT_AUTHORIZED"},"mqtt.IMessage":{"kind":9,"retType":"mqtt.IMessage","attributes":{"jsDoc":"A message received in a Publish packet."},"extendsTypes":[]},"mqtt.IMessage.pid":{"kind":2,"retType":"number","isInstance":true},"mqtt.IMessage.topic":{"kind":2,"retType":"string","isInstance":true},"mqtt.IMessage.content":{"kind":2,"retType":"Buffer","isInstance":true},"mqtt.IMessage.qos":{"kind":2,"retType":"number","isInstance":true},"mqtt.IMessage.retain":{"kind":2,"retType":"number","isInstance":true},"mqtt.ControlPacketType":{"kind":6,"retType":"mqtt.ControlPacketType","attributes":{"jsDoc":"MQTT Control Packet type\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc353481061"},"extendsTypes":["mqtt.ControlPacketType","Number"]},"mqtt.ControlPacketType.Connect":{"retType":"mqtt.ControlPacketType.Connect","extendsTypes":["mqtt.ControlPacketType.Connect","Number"],"pyQName":"mqtt.ControlPacketType.CONNECT"},"mqtt.ControlPacketType.ConnAck":{"retType":"mqtt.ControlPacketType.ConnAck","extendsTypes":["mqtt.ControlPacketType.ConnAck","Number"],"pyQName":"mqtt.ControlPacketType.CONN_ACK"},"mqtt.ControlPacketType.Publish":{"retType":"mqtt.ControlPacketType.Publish","extendsTypes":["mqtt.ControlPacketType.Publish","Number"],"pyQName":"mqtt.ControlPacketType.PUBLISH"},"mqtt.ControlPacketType.PubAck":{"retType":"mqtt.ControlPacketType.PubAck","extendsTypes":["mqtt.ControlPacketType.PubAck","Number"],"pyQName":"mqtt.ControlPacketType.PUB_ACK"},"mqtt.ControlPacketType.Subscribe":{"retType":"mqtt.ControlPacketType.Subscribe","extendsTypes":["mqtt.ControlPacketType.Subscribe","Number"],"pyQName":"mqtt.ControlPacketType.SUBSCRIBE"},"mqtt.ControlPacketType.SubAck":{"retType":"mqtt.ControlPacketType.SubAck","extendsTypes":["mqtt.ControlPacketType.SubAck","Number"],"pyQName":"mqtt.ControlPacketType.SUB_ACK"},"mqtt.ControlPacketType.Unsubscribe":{"retType":"mqtt.ControlPacketType.Unsubscribe","extendsTypes":["mqtt.ControlPacketType.Unsubscribe","Number"],"pyQName":"mqtt.ControlPacketType.UNSUBSCRIBE"},"mqtt.ControlPacketType.UnsubAck":{"retType":"mqtt.ControlPacketType.UnsubAck","extendsTypes":["mqtt.ControlPacketType.UnsubAck","Number"],"pyQName":"mqtt.ControlPacketType.UNSUB_ACK"},"mqtt.ControlPacketType.PingReq":{"retType":"mqtt.ControlPacketType.PingReq","extendsTypes":["mqtt.ControlPacketType.PingReq","Number"],"pyQName":"mqtt.ControlPacketType.PING_REQ"},"mqtt.ControlPacketType.PingResp":{"retType":"mqtt.ControlPacketType.PingResp","extendsTypes":["mqtt.ControlPacketType.PingResp","Number"],"pyQName":"mqtt.ControlPacketType.PING_RESP"},"mqtt.ControlPacketType.Disconnect":{"retType":"mqtt.ControlPacketType.Disconnect","extendsTypes":["mqtt.ControlPacketType.Disconnect","Number"],"pyQName":"mqtt.ControlPacketType.DISCONNECT"},"mqtt.Constants":{"kind":6,"retType":"mqtt.Constants","attributes":{"jsDoc":"Optimization, the TypeScript compiler replaces the constant enums."},"extendsTypes":["mqtt.Constants","Number"]},"mqtt.Constants.PingInterval":{"retType":"mqtt.Constants.PingInterval","extendsTypes":["mqtt.Constants.PingInterval","Number"],"pyQName":"mqtt.Constants.PING_INTERVAL"},"mqtt.Constants.WatchDogInterval":{"retType":"mqtt.Constants.WatchDogInterval","extendsTypes":["mqtt.Constants.WatchDogInterval","Number"],"pyQName":"mqtt.Constants.WATCH_DOG_INTERVAL"},"mqtt.Constants.DefaultQos":{"retType":"mqtt.Constants.DefaultQos","extendsTypes":["mqtt.Constants.DefaultQos","Number"],"pyQName":"mqtt.Constants.DEFAULT_QOS"},"mqtt.Constants.Uninitialized":{"retType":"mqtt.Constants.Uninitialized","extendsTypes":["mqtt.Constants.Uninitialized","Number"],"pyQName":"mqtt.Constants.UNINITIALIZED"},"mqtt.Constants.FixedPackedId":{"retType":"mqtt.Constants.FixedPackedId","extendsTypes":["mqtt.Constants.FixedPackedId","Number"],"pyQName":"mqtt.Constants.FIXED_PACKED_ID"},"mqtt.Constants.KeepAlive":{"retType":"mqtt.Constants.KeepAlive","extendsTypes":["mqtt.Constants.KeepAlive","Number"],"pyQName":"mqtt.Constants.KEEP_ALIVE"},"mqtt.IConnectionOptions":{"kind":9,"retType":"mqtt.IConnectionOptions","attributes":{"jsDoc":"The options used to connect to the MQTT broker."},"extendsTypes":[]},"mqtt.IConnectionOptions.host":{"kind":2,"retType":"string","isInstance":true},"mqtt.IConnectionOptions.port":{"kind":2,"retType":"number","isInstance":true},"mqtt.IConnectionOptions.username":{"kind":2,"retType":"string","isInstance":true},"mqtt.IConnectionOptions.password":{"kind":2,"retType":"string","isInstance":true},"mqtt.IConnectionOptions.clientId":{"kind":2,"retType":"string","isInstance":true,"pyQName":"mqtt.IConnectionOptions.client_id"},"mqtt.IConnectionOptions.will":{"kind":2,"retType":"mqtt.IConnectionOptionsWill","isInstance":true},"mqtt.IConnectionOptionsWill":{"kind":9,"retType":"mqtt.IConnectionOptionsWill","extendsTypes":[]},"mqtt.IConnectionOptionsWill.topic":{"kind":2,"retType":"string","isInstance":true},"mqtt.IConnectionOptionsWill.message":{"kind":2,"retType":"string","isInstance":true},"mqtt.IConnectionOptionsWill.qos":{"kind":2,"retType":"number","isInstance":true},"mqtt.IConnectionOptionsWill.retain":{"kind":2,"retType":"boolean","isInstance":true},"mqtt.Protocol":{"kind":5,"retType":"","attributes":{"jsDoc":"The specifics of the MQTT protocol."}},"mqtt.Protocol.createConnect":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"CONNECT - Client requests a connection to a Server\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718028"},"parameters":[{"name":"options","type":"mqtt.IConnectionOptions"}],"pyQName":"mqtt.Protocol.create_connect"},"mqtt.Protocol.createPingReq":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"PINGREQ - PING request\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800454"},"parameters":[],"pyQName":"mqtt.Protocol.create_ping_req"},"mqtt.Protocol.createPublishHeader":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"PUBLISH - Publish message header - doesn't include \"payload\"\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800410"},"parameters":[{"name":"topic","type":"string"},{"name":"payloadSize"},{"name":"qos"},{"name":"retained","type":"boolean"}],"pyQName":"mqtt.Protocol.create_publish_header"},"mqtt.Protocol.parsePublish":{"kind":-3,"retType":"mqtt.IMessage","parameters":[{"name":"cmd"},{"name":"payload","type":"Buffer"}],"pyQName":"mqtt.Protocol.parse_publish"},"mqtt.Protocol.createPubAck":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"PUBACK - Publish acknowledgement\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800416"},"parameters":[{"name":"pid"}],"pyQName":"mqtt.Protocol.create_pub_ack"},"mqtt.Protocol.createSubscribe":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"SUBSCRIBE - Subscribe to topics\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800436"},"parameters":[{"name":"topic","type":"string"},{"name":"qos"}],"pyQName":"mqtt.Protocol.create_subscribe"},"mqtt.EventEmitter":{"kind":8,"retType":"mqtt.EventEmitter","extendsTypes":["mqtt.EventEmitter"]},"mqtt.EventEmitter.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"mqtt.EventEmitter.on":{"kind":-1,"parameters":[{"name":"event","type":"string"},{"name":"listener","type":"mqtt.EventHandler"}],"isInstance":true},"mqtt.Status":{"kind":6,"retType":"mqtt.Status","extendsTypes":["mqtt.Status","Number"]},"mqtt.Status.Disconnected":{"retType":"mqtt.Status.Disconnected","extendsTypes":["mqtt.Status.Disconnected","Number"],"pyQName":"mqtt.Status.DISCONNECTED"},"mqtt.Status.Connecting":{"retType":"mqtt.Status.Connecting","extendsTypes":["mqtt.Status.Connecting","Number"],"pyQName":"mqtt.Status.CONNECTING"},"mqtt.Status.Connected":{"retType":"mqtt.Status.Connected","extendsTypes":["mqtt.Status.Connected","Number"],"pyQName":"mqtt.Status.CONNECTED"},"mqtt.Status.Sending":{"retType":"mqtt.Status.Sending","extendsTypes":["mqtt.Status.Sending","Number"],"pyQName":"mqtt.Status.SENDING"},"mqtt.Client":{"kind":8,"retType":"mqtt.Client","extendsTypes":["mqtt.Client","mqtt.EventEmitter"]},"mqtt.Client.logPriority":{"kind":2,"retType":"ConsolePriority","isInstance":true,"pyQName":"mqtt.Client.log_priority"},"mqtt.Client.tracePriority":{"kind":2,"retType":"ConsolePriority","isInstance":true,"pyQName":"mqtt.Client.trace_priority"},"mqtt.Client.opt":{"kind":2,"retType":"mqtt.IConnectionOptions","isInstance":true},"mqtt.Client.status":{"kind":2,"retType":"mqtt.Status","isInstance":true},"mqtt.Client.connected":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true},"mqtt.Client.__constructor":{"kind":-3,"parameters":[{"name":"opt","type":"mqtt.IConnectionOptions"}],"isInstance":true},"mqtt.Client.disconnect":{"kind":-1,"parameters":[],"isInstance":true},"mqtt.Client.connect":{"kind":-1,"parameters":[],"isInstance":true},"mqtt.Client.publish":{"kind":-1,"parameters":[{"name":"topic","type":"string"},{"name":"message","type":"string | Buffer","initializer":"undefined"},{"name":"qos","initializer":"Constants.DefaultQos"},{"name":"retained","type":"boolean","initializer":"false"}],"isInstance":true},"mqtt.Client.startPublish":{"kind":-1,"retType":"boolean","parameters":[{"name":"topic","type":"string"},{"name":"messageLen"},{"name":"qos","initializer":"Constants.DefaultQos"},{"name":"retained","type":"boolean","initializer":"false"}],"isInstance":true,"pyQName":"mqtt.Client.start_publish"},"mqtt.Client.continuePublish":{"kind":-1,"parameters":[{"name":"data","type":"Buffer"}],"isInstance":true,"pyQName":"mqtt.Client.continue_publish"},"mqtt.Client.finishPublish":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"mqtt.Client.finish_publish"},"mqtt.Client.subscribe":{"kind":-1,"parameters":[{"name":"topic","type":"string"},{"name":"handler","type":"(msg: mqtt.IMessage) => void","initializer":"undefined","handlerParameters":[{"name":"msg","type":"mqtt.IMessage"}]},{"name":"qos","initializer":"Constants.DefaultQos"}],"isInstance":true},"mqtt.Client.awaitUpdate":{"kind":-1,"retType":"() => mqtt.IMessage","parameters":[{"name":"topic","type":"string"},{"name":"qos","initializer":"Constants.DefaultQos"}],"isInstance":true,"pyQName":"mqtt.Client.await_update"},"AzureIotEvent":{"kind":6,"retType":"AzureIotEvent","extendsTypes":["AzureIotEvent","Number"]},"AzureIotEvent.Connected":{"retType":"AzureIotEvent.Connected","extendsTypes":["AzureIotEvent.Connected","Number"],"pyQName":"AzureIotEvent.CONNECTED"},"AzureIotEvent.Disconnected":{"retType":"AzureIotEvent.Disconnected","extendsTypes":["AzureIotEvent.Disconnected","Number"],"pyQName":"AzureIotEvent.DISCONNECTED"},"AzureIotEvent.Error":{"retType":"AzureIotEvent.Error","extendsTypes":["AzureIotEvent.Error","Number"],"pyQName":"AzureIotEvent.ERROR"},"AzureIotEvent.GotTwinResponse":{"retType":"AzureIotEvent.GotTwinResponse","extendsTypes":["AzureIotEvent.GotTwinResponse","Number"],"pyQName":"AzureIotEvent.GOT_TWIN_RESPONSE"},"azureiot":{"kind":5,"retType":""},"azureiot.SECRETS_KEY":{"kind":4,"retType":"\"azureiot\""},"azureiot.logPriority":{"kind":4,"retType":"ConsolePriority","pyQName":"azureiot.log_priority"},"azureiot.mqttClient":{"kind":-3,"retType":"mqtt.Client","parameters":[{"name":"skipCreate","type":"boolean","initializer":"undefined"}],"pyQName":"azureiot.mqtt_client"},"azureiot.hubName":{"kind":-3,"retType":"string","parameters":[],"pyQName":"azureiot.hub_name"},"azureiot.hubDeviceId":{"kind":-3,"retType":"string","parameters":[],"pyQName":"azureiot.hub_device_id"},"azureiot.setConnectionString":{"kind":-3,"parameters":[{"name":"connectionString","type":"string"}],"pyQName":"azureiot.set_connection_string"},"azureiot.disconnect":{"kind":-3,"attributes":{"jsDoc":"Disconnects the hub if any"},"parameters":[]},"azureiot.connect":{"kind":-3,"attributes":{"jsDoc":"Connects to the IoT hub"},"parameters":[]},"azureiot.onEvent":{"kind":-3,"attributes":{"paramHelp":{"event":"@param handler "},"jsDoc":"Registers code when the MQTT client gets connected or disconnected"},"parameters":[{"name":"event","description":"@param handler ","type":"AzureIotEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"azureiot.on_event"},"azureiot.isConnected":{"kind":-3,"retType":"boolean","attributes":{"jsDoc":"Indicates if the MQTT client is connected"},"parameters":[],"pyQName":"azureiot.is_connected"},"azureiot.publishMessageJSON":{"kind":-3,"attributes":{"paramHelp":{"msg":""},"jsDoc":"Send a message via mqtt"},"parameters":[{"name":"msg","type":"any"},{"name":"sysProps","type":"SMap<string>","initializer":"undefined"}],"pyQName":"azureiot.publish_message_json"},"azureiot.publishMessageBuffer":{"kind":-3,"attributes":{"paramHelp":{"msg":""},"jsDoc":"Send a message via mqtt"},"parameters":[{"name":"msg","type":"Buffer"},{"name":"sysProps","type":"SMap<string>","initializer":"undefined"}],"pyQName":"azureiot.publish_message_buffer"},"azureiot.publishMessageHex":{"kind":-3,"attributes":{"paramHelp":{"msg":""},"jsDoc":"Send a message via mqtt"},"parameters":[{"name":"msg","type":"Buffer"},{"name":"len","initializer":"undefined"},{"name":"sysProps","type":"SMap<string>","initializer":"undefined"}],"pyQName":"azureiot.publish_message_hex"},"azureiot.onMessageReceived":{"kind":-3,"attributes":{"paramHelp":{"handler":""},"jsDoc":"Registers code to run when a message is received"},"parameters":[{"name":"handler","type":"(body: any, sysProps: SMap<string>) => void","handlerParameters":[{"name":"body","type":"any"},{"name":"sysProps","type":"SMap<string>"}]}],"pyQName":"azureiot.on_message_received"},"azureiot.ValueAwaiter":{"kind":8,"retType":"azureiot.ValueAwaiter","extendsTypes":[]},"azureiot.ValueAwaiter.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"azureiot.ValueAwaiter.setValue":{"kind":-1,"parameters":[{"name":"v","type":"any"}],"isInstance":true,"pyQName":"azureiot.ValueAwaiter.set_value"},"azureiot.ValueAwaiter.wait":{"kind":-1,"retType":"any","parameters":[],"isInstance":true},"azureiot.getTwin":{"kind":-3,"retType":"any","parameters":[],"pyQName":"azureiot.get_twin"},"azureiot.patchTwin":{"kind":-3,"parameters":[{"name":"patch","type":"any"}],"pyQName":"azureiot.patch_twin"},"azureiot.computePatch":{"kind":-3,"retType":"any","parameters":[{"name":"curr","type":"any"},{"name":"target","type":"any"}],"pyQName":"azureiot.compute_patch"},"azureiot.applyPatch":{"kind":-3,"parameters":[{"name":"trg","type":"any"},{"name":"patch","type":"any"}],"pyQName":"azureiot.apply_patch"},"azureiot.onTwinUpdate":{"kind":-3,"parameters":[{"name":"handler","type":"(twin: any, patch: any) => void","handlerParameters":[{"name":"twin","type":"any"},{"name":"patch","type":"any"}]}],"pyQName":"azureiot.on_twin_update"},"azureiot.onMethod":{"kind":-3,"parameters":[{"name":"methodName","type":"string"},{"name":"handler","type":"(msg: any) => any","handlerParameters":[{"name":"msg","type":"any"}]}],"pyQName":"azureiot.on_method"}}},"sha":"c73d07082598dec7dc9a370a182ba8f76d4e56a10d20a1e6f7d6d2b94bb32d3d"},"libs/base":{"apis":{"byQName":{}},"sha":"0555505553f9ee0001acb1a170fbb98d0b7bffdf0948d171d53bcc32556da585"},"libs/buttons":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"DigitalInOutPin.pushButton":{"kind":-1,"retType":"Button","attributes":{"jsDoc":"Get the push button (connected to GND) for given pin"},"parameters":[],"isInstance":true,"pyQName":"DigitalInOutPin.push_button"},"Button":{"kind":9,"retType":"Button","attributes":{"noRefCounting":"true","fixedInstances":"true"},"extendsTypes":[]},"Button.onEvent":{"kind":-1,"attributes":{"help":"input/button/on-event","blockId":"buttonEvent","block":"on %button|%event","blockNamespace":"input","paramFieldEditor":{"button":"gridpicker"},"paramFieldEditorOptions":{"button":{"width":"220","columns":"3"}},"weight":96,"blockGap":"12","trackArgs":[0],"paramHelp":{"button":"the button that needs to be clicked or used","event":"the kind of button gesture that needs to be detected","body":"code to run when the event is raised"},"jsDoc":"Do something when a button (`A`, `B` or both `A` + `B`) is clicked, double clicked, etc...","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"button","ref":false},{"kind":"break"},{"kind":"param","name":"event","ref":false}],"parameters":[{"kind":"param","name":"button","ref":false},{"kind":"param","name":"event","ref":false}]}},"parameters":[{"name":"ev","type":"ButtonEvent","isEnum":true},{"name":"body","description":"code to run when the event is raised","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"Button.on_event"},"Button.isPressed":{"kind":-1,"retType":"boolean","attributes":{"help":"input/button/is-pressed","block":"%button|is pressed","blockId":"buttonIsPressed","blockNamespace":"input","paramFieldEditor":{"button":"gridpicker"},"paramFieldEditorOptions":{"button":{"width":"220","columns":"3"}},"weight":50,"blockGap":"8","trackArgs":[0],"paramHelp":{"button":"the button to query the request"},"jsDoc":"Check if a button is pressed or not.","_def":{"parts":[{"kind":"param","name":"button","ref":false},{"kind":"break"},{"kind":"label","text":"is pressed","style":[]}],"parameters":[{"kind":"param","name":"button","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"Button.is_pressed"},"Button.wasPressed":{"kind":-1,"retType":"boolean","attributes":{"help":"input/button/was-pressed","block":"%button|was pressed","blockId":"buttonWasPressed","blockNamespace":"input","paramFieldEditor":{"button":"gridpicker"},"paramFieldEditorOptions":{"button":{"width":"220","columns":"3"}},"group":"More","weight":46,"blockGap":"8","trackArgs":[0],"paramHelp":{"button":"the button to query the request"},"jsDoc":"See if the button was pressed again since the last time you checked.","_def":{"parts":[{"kind":"param","name":"button","ref":false},{"kind":"break"},{"kind":"label","text":"was pressed","style":[]}],"parameters":[{"kind":"param","name":"button","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"Button.was_pressed"},"Button.id":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Gets the component identifier for the button"},"parameters":[],"isInstance":true},"ButtonEvent":{"kind":6,"retType":"ButtonEvent","attributes":{"jsDoc":"User interaction on buttons"},"extendsTypes":["ButtonEvent","Number"]},"ButtonEvent.Click":{"retType":"ButtonEvent.Click","attributes":{"block":"click","_def":{"parts":[{"kind":"label","text":"click","style":[]}],"parameters":[]}},"extendsTypes":["ButtonEvent.Click","Number"],"pyQName":"ButtonEvent.CLICK"},"ButtonEvent.LongClick":{"retType":"ButtonEvent.LongClick","attributes":{"block":"long click","_def":{"parts":[{"kind":"label","text":"long click","style":[]}],"parameters":[]}},"extendsTypes":["ButtonEvent.LongClick","Number"],"pyQName":"ButtonEvent.LONG_CLICK"},"ButtonEvent.Up":{"retType":"ButtonEvent.Up","attributes":{"block":"up","_def":{"parts":[{"kind":"label","text":"up","style":[]}],"parameters":[]}},"extendsTypes":["ButtonEvent.Up","Number"],"pyQName":"ButtonEvent.UP"},"ButtonEvent.Down":{"retType":"ButtonEvent.Down","attributes":{"block":"down","_def":{"parts":[{"kind":"label","text":"down","style":[]}],"parameters":[]}},"extendsTypes":["ButtonEvent.Down","Number"],"pyQName":"ButtonEvent.DOWN"}}},"sha":"3c249f1fa9f93fb549ef2623c1bb7ab519fdf0fa84401beab513e4fb3e2d8fd8"},"libs/color":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"Colors":{"kind":6,"retType":"Colors","attributes":{"jsDoc":"Well known colors"},"extendsTypes":["Colors","Number"]},"Colors.Red":{"retType":"Colors.Red","attributes":{"block":"red","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"red","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Red","Number"],"pyQName":"Colors.RED"},"Colors.Orange":{"retType":"Colors.Orange","attributes":{"block":"orange","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"orange","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Orange","Number"],"pyQName":"Colors.ORANGE"},"Colors.Yellow":{"retType":"Colors.Yellow","attributes":{"block":"yellow","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"yellow","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Yellow","Number"],"pyQName":"Colors.YELLOW"},"Colors.Green":{"retType":"Colors.Green","attributes":{"block":"green","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"green","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Green","Number"],"pyQName":"Colors.GREEN"},"Colors.Blue":{"retType":"Colors.Blue","attributes":{"block":"blue","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"blue","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Blue","Number"],"pyQName":"Colors.BLUE"},"Colors.Indigo":{"retType":"Colors.Indigo","attributes":{"block":"indigo","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"indigo","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Indigo","Number"],"pyQName":"Colors.INDIGO"},"Colors.Violet":{"retType":"Colors.Violet","attributes":{"block":"violet","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"violet","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Violet","Number"],"pyQName":"Colors.VIOLET"},"Colors.Purple":{"retType":"Colors.Purple","attributes":{"block":"purple","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"purple","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Purple","Number"],"pyQName":"Colors.PURPLE"},"Colors.Pink":{"retType":"Colors.Pink","attributes":{"block":"pink","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"pink","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Pink","Number"],"pyQName":"Colors.PINK"},"Colors.White":{"retType":"Colors.White","attributes":{"block":"white","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"white","style":[]}],"parameters":[]}},"extendsTypes":["Colors.White","Number"],"pyQName":"Colors.WHITE"},"Colors.Black":{"retType":"Colors.Black","attributes":{"block":"black","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"black","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Black","Number"],"pyQName":"Colors.BLACK"},"ColorHues":{"kind":6,"retType":"ColorHues","attributes":{"jsDoc":"Well known color hues"},"extendsTypes":["ColorHues","Number"]},"ColorHues.Red":{"retType":"ColorHues.Red","attributes":{"block":"red","_def":{"parts":[{"kind":"label","text":"red","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Red","Number"],"pyQName":"ColorHues.RED"},"ColorHues.Orange":{"retType":"ColorHues.Orange","attributes":{"block":"orange","_def":{"parts":[{"kind":"label","text":"orange","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Orange","Number"],"pyQName":"ColorHues.ORANGE"},"ColorHues.Yellow":{"retType":"ColorHues.Yellow","attributes":{"block":"yellow","_def":{"parts":[{"kind":"label","text":"yellow","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Yellow","Number"],"pyQName":"ColorHues.YELLOW"},"ColorHues.Green":{"retType":"ColorHues.Green","attributes":{"block":"green","_def":{"parts":[{"kind":"label","text":"green","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Green","Number"],"pyQName":"ColorHues.GREEN"},"ColorHues.Aqua":{"retType":"ColorHues.Aqua","attributes":{"block":"aqua","_def":{"parts":[{"kind":"label","text":"aqua","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Aqua","Number"],"pyQName":"ColorHues.AQUA"},"ColorHues.Blue":{"retType":"ColorHues.Blue","attributes":{"block":"blue","_def":{"parts":[{"kind":"label","text":"blue","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Blue","Number"],"pyQName":"ColorHues.BLUE"},"ColorHues.Purple":{"retType":"ColorHues.Purple","attributes":{"block":"purple","_def":{"parts":[{"kind":"label","text":"purple","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Purple","Number"],"pyQName":"ColorHues.PURPLE"},"ColorHues.Magenta":{"retType":"ColorHues.Magenta","attributes":{"block":"magenta","_def":{"parts":[{"kind":"label","text":"magenta","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Magenta","Number"],"pyQName":"ColorHues.MAGENTA"},"ColorHues.Pink":{"retType":"ColorHues.Pink","attributes":{"block":"pink","_def":{"parts":[{"kind":"label","text":"pink","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Pink","Number"],"pyQName":"ColorHues.PINK"},"color":{"kind":5,"retType":"","attributes":{"advanced":true,"jsDoc":"Color manipulation"}},"color.rgb":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"red":"255","green":"255","blue":"255"},"blockId":"colorsrgb","block":"red %red|green %green|blue %blue","paramMin":{"red":"0","green":"0","blue":"0"},"paramMax":{"red":"255","green":"255","blue":"255"},"help":"colors/rgb","weight":19,"blockGap":"8","blockHidden":true,"paramHelp":{"red":"value of the red channel between 0 and 255. eg: 255","green":"value of the green channel between 0 and 255. eg: 255","blue":"value of the blue channel between 0 and 255. eg: 255"},"jsDoc":"Converts red, green, blue channels into a RGB color","_def":{"parts":[{"kind":"label","text":"red ","style":[]},{"kind":"param","name":"red","ref":false},{"kind":"break"},{"kind":"label","text":"green ","style":[]},{"kind":"param","name":"green","ref":false},{"kind":"break"},{"kind":"label","text":"blue ","style":[]},{"kind":"param","name":"blue","ref":false}],"parameters":[{"kind":"param","name":"red","ref":false},{"kind":"param","name":"green","ref":false},{"kind":"param","name":"blue","ref":false}]}},"parameters":[{"name":"red","description":"value of the red channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"green","description":"value of the green channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"blue","description":"value of the blue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.argb":{"kind":-3,"retType":"number","parameters":[{"name":"alpha"},{"name":"red"},{"name":"green"},{"name":"blue"}]},"color.wellKnown":{"kind":-3,"retType":"number","attributes":{"blockId":"colorscolors","block":"%color","help":"colors/well-known","shim":"TD_ID","weight":20,"blockGap":"8","blockHidden":true,"jsDoc":"Get the RGB value of a known color","_def":{"parts":[{"kind":"param","name":"color","ref":false}],"parameters":[{"kind":"param","name":"color","ref":false}]}},"parameters":[{"name":"color","type":"Colors","isEnum":true}],"pyQName":"color.well_known"},"color.hsv":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"hue":"255","sat":"255","val":"255"},"blockId":"colorshsv","block":"hue %hue|sat %sat|val %val","paramMin":{"hue":"0","sat":"0","val":"0"},"paramMax":{"hue":"255","sat":"255","val":"255"},"help":"colors/hsv","weight":17,"blockHidden":true,"paramHelp":{"hue":"value of the hue channel between 0 and 255. eg: 255","sat":"value of the saturation channel between 0 and 255. eg: 255","val":"value of the value channel between 0 and 255. eg: 255"},"jsDoc":"Convert an HSV (hue, saturation, value) color to RGB","_def":{"parts":[{"kind":"label","text":"hue ","style":[]},{"kind":"param","name":"hue","ref":false},{"kind":"break"},{"kind":"label","text":"sat ","style":[]},{"kind":"param","name":"sat","ref":false},{"kind":"break"},{"kind":"label","text":"val ","style":[]},{"kind":"param","name":"val","ref":false}],"parameters":[{"kind":"param","name":"hue","ref":false},{"kind":"param","name":"sat","ref":false},{"kind":"param","name":"val","ref":false}]}},"parameters":[{"name":"hue","description":"value of the hue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"sat","description":"value of the saturation channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"val","description":"value of the value channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.fade":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"brightness":"128"},"blockId":"colorsfade","block":"fade %color=neopixel_colors|by %brightness","paramMin":{"brightness":"0"},"paramMax":{"brightness":"255"},"help":"light/fade","group":"Color","weight":18,"blockGap":"8","blockHidden":true,"paramHelp":{"color":"color to fade","brightness":"the amount of brightness to apply to the color, eg: 128"},"jsDoc":"Fade the color by the brightness","_def":{"parts":[{"kind":"label","text":"fade ","style":[]},{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"break"},{"kind":"label","text":"by ","style":[]},{"kind":"param","name":"brightness","ref":false}],"parameters":[{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"param","name":"brightness","ref":false}]}},"parameters":[{"name":"color","description":"color to fade"},{"name":"brightness","description":"the amount of brightness to apply to the color, eg: 128","default":"128","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.blend":{"kind":-3,"retType":"number","parameters":[{"name":"color"},{"name":"alpha"},{"name":"otherColor"}]},"color.gradient":{"kind":-3,"retType":"color.ColorBuffer","parameters":[{"name":"startColor"},{"name":"endColor"},{"name":"steps"}]},"color.unpackR":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_r"},"color.unpackG":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_g"},"color.unpackB":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_b"},"color.parseColor":{"kind":-3,"retType":"number","parameters":[{"name":"color","type":"string"}],"pyQName":"color.parse_color"},"color.ColorBufferLayout":{"kind":6,"retType":"color.ColorBufferLayout","extendsTypes":["color.ColorBufferLayout","Number"]},"color.ColorBufferLayout.RGB":{"retType":"color.ColorBufferLayout.RGB","attributes":{"jsDoc":"24bit RGB color"},"extendsTypes":["color.ColorBufferLayout.RGB","Number"]},"color.ColorBufferLayout.ARGB":{"retType":"color.ColorBufferLayout.ARGB","attributes":{"jsDoc":"32bit RGB color with alpha"},"extendsTypes":["color.ColorBufferLayout.ARGB","Number"]},"color.ColorBuffer":{"kind":8,"retType":"color.ColorBuffer","attributes":{"jsDoc":"A buffer of colors"},"extendsTypes":[]},"color.ColorBuffer.layout":{"kind":2,"retType":"color.ColorBufferLayout","isInstance":true},"color.ColorBuffer.buf":{"kind":2,"retType":"Buffer","isInstance":true},"color.ColorBuffer.__constructor":{"kind":-3,"parameters":[{"name":"length"},{"name":"layout","type":"color.ColorBufferLayout","initializer":"undefined","isEnum":true}],"isInstance":true},"color.ColorBuffer.fromBuffer":{"kind":-1,"retType":"color.ColorBuffer","parameters":[{"name":"buffer","type":"Buffer"},{"name":"layout","type":"color.ColorBufferLayout","isEnum":true}],"pyQName":"color.ColorBuffer.from_buffer"},"color.ColorBuffer.stride":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"color.ColorBuffer.length":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"color.ColorBuffer.color":{"kind":-1,"retType":"number","parameters":[{"name":"index"}],"isInstance":true},"color.ColorBuffer.setColor":{"kind":-1,"parameters":[{"name":"index"},{"name":"color"}],"isInstance":true,"pyQName":"color.ColorBuffer.set_color"},"color.ColorBuffer.slice":{"kind":-1,"retType":"color.ColorBuffer","parameters":[{"name":"start","initializer":"undefined"},{"name":"length","initializer":"undefined"}],"isInstance":true},"color.ColorBuffer.write":{"kind":-1,"attributes":{"paramHelp":{"dstOffset":"@param src"},"jsDoc":"Writes the content of the src color buffer starting at the start dstOffset in the current buffer"},"parameters":[{"name":"dstOffset","description":"@param src"},{"name":"src","type":"color.ColorBuffer"}],"isInstance":true},"color.createBuffer":{"kind":-3,"retType":"color.ColorBuffer","attributes":{"jsDoc":"Converts an array of colors into a color buffer"},"parameters":[{"name":"colors","type":"number[]"},{"name":"layout","type":"color.ColorBufferLayout","initializer":"undefined","isEnum":true}],"pyQName":"color.create_buffer"}}},"sha":"202045c3590051beb21cb41695d65dd9af6b772445dc617f28f326948c63902e"},"libs/color-coded-tilemap":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"tiles":{"kind":5,"retType":""},"tiles.TileMap":{"kind":8,"retType":"tiles.TileMap","extendsTypes":["tiles.TileMap"]},"scene.setTileMap":{"kind":-3,"attributes":{"paramDefl":{"scale":"TileScale.Sixteen"},"blockId":"gamesettilemap","block":"set tile map to %map=tilemap_image_picker || with %scale pixel tiles","explicitDefaults":["scale"],"group":"Color-coded Tilemap","help":"color-coded-tilemap/set-tile-map","paramHelp":{"map":"@param scale"},"jsDoc":"Package for color-coded tilemap blocks, to support existing curriculum.\n\nSet the map for placing tiles in the scene","_def":{"parts":[{"kind":"label","text":"set tile map to ","style":[]},{"kind":"param","name":"map","shadowBlockId":"tilemap_image_picker","ref":false},{"kind":"label","text":" ","style":[]}],"parameters":[{"kind":"param","name":"map","shadowBlockId":"tilemap_image_picker","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":" with ","style":[]},{"kind":"param","name":"scale","ref":false},{"kind":"label","text":" pixel tiles","style":[]}],"parameters":[{"kind":"param","name":"scale","ref":false}]}},"parameters":[{"name":"map","description":"@param scale","type":"Image"},{"name":"scale","type":"TileScale","initializer":"TileScale.Sixteen","default":"TileScale.Sixteen","isEnum":true}],"pyQName":"scene.set_tile_map"},"scene.setTile":{"kind":-3,"attributes":{"blockId":"gamesettile","block":"set tile %index=colorindexpicker to %img=tile_image_picker with wall %wall=toggleOnOff","group":"Color-coded Tilemap","help":"color-coded-tilemap/set-tile","paramHelp":{"index":"@param img"},"jsDoc":"Set an image as a tile at the given index. Tiles should be a 16x16 image","_def":{"parts":[{"kind":"label","text":"set tile ","style":[]},{"kind":"param","name":"index","shadowBlockId":"colorindexpicker","ref":false},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"img","shadowBlockId":"tile_image_picker","ref":false},{"kind":"label","text":" with wall ","style":[]},{"kind":"param","name":"wall","shadowBlockId":"toggleOnOff","ref":false}],"parameters":[{"kind":"param","name":"index","shadowBlockId":"colorindexpicker","ref":false},{"kind":"param","name":"img","shadowBlockId":"tile_image_picker","ref":false},{"kind":"param","name":"wall","shadowBlockId":"toggleOnOff","ref":false}]}},"parameters":[{"name":"index","description":"@param img"},{"name":"img","type":"Image"},{"name":"wall","type":"boolean","initializer":"undefined"}],"pyQName":"scene.set_tile"},"scene.getTile":{"kind":-3,"retType":"tiles.Tile","attributes":{"blockId":"gamegettile","block":"tile col %col row %row","group":"Color-coded Tilemap","blockSetVariable":"myTile","help":"color-coded-tilemap/get-tile","paramHelp":{"col":"@param row"},"jsDoc":"Get the tile at a position in the tile map","_def":{"parts":[{"kind":"label","text":"tile col ","style":[]},{"kind":"param","name":"col","ref":false},{"kind":"label","text":" row ","style":[]},{"kind":"param","name":"row","ref":false}],"parameters":[{"kind":"param","name":"col","ref":false},{"kind":"param","name":"row","ref":false}]}},"parameters":[{"name":"col","description":"@param row"},{"name":"row"}],"pyQName":"scene.get_tile"},"scene.getTilesByType":{"kind":-3,"retType":"tiles.Tile[]","attributes":{"blockId":"gamegettilestype","block":"array of all %index=colorindexpicker tiles","group":"Color-coded Tilemap","blockSetVariable":"tile list","help":"color-coded-tilemap/get-tiles-by-type","paramHelp":{"index":""},"jsDoc":"Get all tiles in the tile map with the given index.","_def":{"parts":[{"kind":"label","text":"array of all ","style":[]},{"kind":"param","name":"index","shadowBlockId":"colorindexpicker","ref":false},{"kind":"label","text":" tiles","style":[]}],"parameters":[{"kind":"param","name":"index","shadowBlockId":"colorindexpicker","ref":false}]}},"parameters":[{"name":"index"}],"pyQName":"scene.get_tiles_by_type"},"scene.placeOnRandomTile":{"kind":-3,"attributes":{"blockId":"gameplaceonrandomtile","block":"place %sprite=variables_get(mySprite) on top of random $color tile","group":"Color-coded Tilemap","_shadowOverrides":{"color":"colorindexpicker"},"help":"color-coded-tilemap/place-on-random-tile","paramHelp":{"sprite":"@param color"},"jsDoc":"Center the given sprite on a random tile that is the given color","_def":{"parts":[{"kind":"label","text":"place ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"},{"kind":"label","text":" on top of random ","style":[]},{"kind":"param","name":"color","shadowBlockId":"colorindexpicker","ref":true},{"kind":"label","text":" tile","style":[]}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"},{"kind":"param","name":"color","shadowBlockId":"colorindexpicker","ref":true}]}},"parameters":[{"name":"sprite","description":"@param color","type":"Sprite"},{"name":"color"}],"pyQName":"scene.place_on_random_tile"},"scene.setTileAt":{"kind":-3,"attributes":{"blockId":"gamesettileat","block":"set %tile=gamegettile to %index=colorindexpicker","group":"Color-coded Tilemap","help":"color-coded-tilemap/set-tile-at","paramHelp":{"tile":"@param index"},"jsDoc":"Set a tile at the given index","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"tile","shadowBlockId":"gamegettile","ref":false},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"index","shadowBlockId":"colorindexpicker","ref":false}],"parameters":[{"kind":"param","name":"tile","shadowBlockId":"gamegettile","ref":false},{"kind":"param","name":"index","shadowBlockId":"colorindexpicker","ref":false}]}},"parameters":[{"name":"tile","description":"@param index","type":"tiles.Tile"},{"name":"index"}],"pyQName":"scene.set_tile_at"},"scene.place":{"kind":-3,"attributes":{"blockId":"legacyplaceontile","block":"on top of %tile=variables_get(myTile) place %sprite=variables_get(mySprite)","group":"Color-coded Tilemap","help":"tiles/place","paramHelp":{"sprite":""},"jsDoc":"Center the given sprite on this tile","_def":{"parts":[{"kind":"label","text":"on top of ","style":[]},{"kind":"param","name":"tile","shadowBlockId":"variables_get","ref":false,"varName":"myTile"},{"kind":"label","text":" place ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"}],"parameters":[{"kind":"param","name":"tile","shadowBlockId":"variables_get","ref":false,"varName":"myTile"},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"}]}},"parameters":[{"name":"tile","type":"tiles.Tile"},{"name":"mySprite","type":"Sprite"}]},"scene.onHitTile":{"kind":-3,"attributes":{"group":"Color-coded Tilemap","draggableParameters":"reporter","blockId":"spritesollisions","block":"on $sprite of kind $kind=spritekind hits wall $tile=colorindexpicker","help":"color-coded-tilemap/on-hit-tile","paramHelp":{"direction":"@param tile","handler":""},"jsDoc":"Run code when a certain kind of sprite hits a tile","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"sprite","ref":true},{"kind":"label","text":" of kind ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true},{"kind":"label","text":" hits wall ","style":[]},{"kind":"param","name":"tile","shadowBlockId":"colorindexpicker","ref":true}],"parameters":[{"kind":"param","name":"sprite","ref":true},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true},{"kind":"param","name":"tile","shadowBlockId":"colorindexpicker","ref":true}]}},"parameters":[{"name":"kind"},{"name":"tile"},{"name":"handler","type":"(sprite: Sprite) => void","handlerParameters":[{"name":"sprite","type":"Sprite"}]}],"pyQName":"scene.on_hit_tile"},"scene.tileHitFrom":{"kind":-3,"retType":"number","attributes":{"blockId":"legacyspriteobstacle","block":"%sprite=variables_get(mySprite) wall hit on %direction","group":"Color-coded Tilemap","help":"sprites/sprite/tile-hit-from","paramHelp":{"direction":""},"jsDoc":"Get the obstacle sprite in a given direction if any","_def":{"parts":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"},{"kind":"label","text":" wall hit on ","style":[]},{"kind":"param","name":"direction","ref":false}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"},{"kind":"param","name":"direction","ref":false}]}},"parameters":[{"name":"sprite","type":"Sprite"},{"name":"direction","type":"CollisionDirection","isEnum":true}],"pyQName":"scene.tile_hit_from"},"tiles.legacy":{"kind":5,"retType":""},"tiles.legacy.LegacyTilemap":{"kind":8,"retType":"tiles.legacy.LegacyTilemap","extendsTypes":["tiles.legacy.LegacyTilemap","tiles.TileMap"]},"tiles.legacy.LegacyTilemap.isLegacy":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.is_legacy"},"tiles.legacy.LegacyTilemap.__constructor":{"kind":-3,"parameters":[{"name":"scale","type":"TileScale","initializer":"TileScale.Sixteen","isEnum":true}],"isInstance":true},"tiles.legacy.LegacyTilemap.data":{"kind":-2,"retType":"tiles.TileMapData","isInstance":true,"isReadOnly":true},"tiles.legacy.LegacyTilemap.image":{"kind":-2,"retType":"Image","isInstance":true,"isReadOnly":true},"tiles.legacy.LegacyTilemap.offsetX":{"kind":-1,"retType":"number","parameters":[{"name":"value"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.offset_x"},"tiles.legacy.LegacyTilemap.offsetY":{"kind":-1,"retType":"number","parameters":[{"name":"value"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.offset_y"},"tiles.legacy.LegacyTilemap.areaWidth":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.area_width"},"tiles.legacy.LegacyTilemap.areaHeight":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.area_height"},"tiles.legacy.LegacyTilemap.layer":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"tiles.legacy.LegacyTilemap.layer@set":{"kind":-2,"retType":"number","isInstance":true},"tiles.legacy.LegacyTilemap.enabled":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true},"tiles.legacy.LegacyTilemap.setTile":{"kind":-1,"parameters":[{"name":"index"},{"name":"img","type":"Image"},{"name":"collisions","type":"boolean","initializer":"undefined"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.set_tile"},"tiles.legacy.LegacyTilemap.setMap":{"kind":-1,"parameters":[{"name":"map","type":"Image"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.set_map"},"tiles.legacy.LegacyTilemap.getTileLegacy":{"kind":-1,"retType":"tiles.Tile","parameters":[{"name":"col"},{"name":"row"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.get_tile_legacy"},"tiles.legacy.LegacyTilemap.getTile":{"kind":-1,"retType":"tiles.Location","parameters":[{"name":"col"},{"name":"row"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.get_tile"},"tiles.legacy.LegacyTilemap.setTileAt":{"kind":-1,"parameters":[{"name":"col"},{"name":"row"},{"name":"index"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.set_tile_at"},"tiles.legacy.LegacyTilemap.getTilesByType":{"kind":-1,"retType":"tiles.Location[]","parameters":[{"name":"index"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.get_tiles_by_type"},"tiles.legacy.LegacyTilemap.getTilesByTypeLegacy":{"kind":-1,"retType":"tiles.Tile[]","parameters":[{"name":"index"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.get_tiles_by_type_legacy"},"tiles.legacy.LegacyTilemap.isObstacle":{"kind":-1,"retType":"boolean","parameters":[{"name":"col"},{"name":"row"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.is_obstacle"},"tiles.legacy.LegacyTilemap.getObstacle":{"kind":-1,"retType":"sprites.StaticObstacle","parameters":[{"name":"col"},{"name":"row"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.get_obstacle"},"tiles.legacy.LegacyTilemap.isOnWall":{"kind":-1,"retType":"boolean","parameters":[{"name":"s","type":"Sprite"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.is_on_wall"},"tiles.legacy.LegacyTilemap.getTileIndex":{"kind":-1,"retType":"number","parameters":[{"name":"col"},{"name":"row"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.get_tile_index"},"tiles.legacy.LegacyTilemap.getTileImage":{"kind":-1,"retType":"Image","parameters":[{"name":"index"}],"isInstance":true,"pyQName":"tiles.legacy.LegacyTilemap.get_tile_image"}}},"sha":"2fcd902ba6e5b96a2c582a6c77908e93572bccacbc603483012216ccad11ab09"},"libs/controller":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"input":{"kind":5,"retType":"","attributes":{"color":"#B4009E","weight":98,"icon":"","groups":["other","More"],"jsDoc":"Respond to and read data from buttons and sensors.\n\nEvents and data from sensors."}},"light":{"kind":5,"retType":"","attributes":{"weight":97,"color":"#0078d7","icon":"","groups":["other","Color","Photon","More"],"blockGap":"8","advanced":true,"jsDoc":"Functions to operate colored LEDs."}},"input.onCustomGesture":{"kind":-3,"attributes":{"paramHelp":{"id":"@param update true if gesture detected","handler":""},"jsDoc":"Registers a custom gesture recognizer"},"parameters":[{"name":"id","description":"@param update true if gesture detected"},{"name":"update","type":"() => boolean","handlerParameters":[]},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"input.on_custom_gesture"},"input.onGesture":{"kind":-3,"attributes":{"paramDefl":{"gesture":"Gesture.Shake"},"help":"input/on-gesture","blockId":"device_gesture_event","block":"on |%NAME","parts":"accelerometer","paramFieldEditor":{"gesture":"gridpicker"},"paramFieldEditorOptions":{"gesture":{"width":"220","columns":"3"}},"weight":92,"blockGap":"12","paramHelp":{"gesture":"the type of gesture to track, eg: Gesture.Shake","body":"code to run when gesture is raised"},"jsDoc":"Do something when a gesture happens (like shaking the board).","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"gesture","description":"the type of gesture to track, eg: Gesture.Shake","type":"Gesture","default":"Gesture.Shake","isEnum":true},{"name":"body","description":"code to run when gesture is raised","type":"() => void","handlerParameters":[]}],"pyQName":"input.on_gesture"},"input.acceleration":{"kind":-3,"retType":"number","attributes":{"help":"input/acceleration","blockId":"device_acceleration","block":"acceleration (mg)|%NAME","parts":"accelerometer","paramFieldEditor":{"dimension":"gridpicker"},"paramFieldEditorOptions":{"dimension":{"width":"180","columns":"2"}},"weight":42,"blockGap":"8","paramHelp":{"dimension":"TODO"},"jsDoc":"Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\nx=0, y=0 and z=-1023)","_def":{"parts":[{"kind":"label","text":"acceleration (mg)","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"dimension","description":"TODO","type":"Dimension","isEnum":true}]},"input.rotation":{"kind":-3,"retType":"number","attributes":{"help":"input/rotation","blockId":"device_get_rotation","block":"rotation (°)|%NAME","parts":"accelerometer","group":"More","weight":38,"paramHelp":{"kind":"TODO"},"jsDoc":"The pitch or roll of the device, rotation along the ``x-axis`` or ``y-axis``, in degrees.","_def":{"parts":[{"kind":"label","text":"rotation (°)","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"kind","description":"TODO","type":"Rotation","isEnum":true}]},"input.setAccelerometerRange":{"kind":-3,"attributes":{"help":"input/set-accelerometer-range","blockId":"device_set_accelerometer_range","block":"set accelerometer|range %range","weight":15,"parts":"accelerometer","group":"More","blockGap":"8","paramHelp":{"range":"a value describe the maximum strengh of acceleration measured"},"jsDoc":"Sets the accelerometer sample range in gravities.","_def":{"parts":[{"kind":"label","text":"set accelerometer","style":[]},{"kind":"break"},{"kind":"label","text":"range ","style":[]},{"kind":"param","name":"range","ref":false}],"parameters":[{"kind":"param","name":"range","ref":false}]}},"parameters":[{"name":"range","description":"a value describe the maximum strengh of acceleration measured","type":"AcceleratorRange","isEnum":true}],"pyQName":"input.set_accelerometer_range"},"Dimension":{"kind":6,"retType":"Dimension","extendsTypes":["Dimension","Number"]},"Dimension.X":{"retType":"Dimension.X","attributes":{"block":"x","_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"extendsTypes":["Dimension.X","Number"]},"Dimension.Y":{"retType":"Dimension.Y","attributes":{"block":"y","_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"extendsTypes":["Dimension.Y","Number"]},"Dimension.Z":{"retType":"Dimension.Z","attributes":{"block":"z","_def":{"parts":[{"kind":"label","text":"z","style":[]}],"parameters":[]}},"extendsTypes":["Dimension.Z","Number"]},"Dimension.Strength":{"retType":"Dimension.Strength","attributes":{"block":"strength","_def":{"parts":[{"kind":"label","text":"strength","style":[]}],"parameters":[]}},"extendsTypes":["Dimension.Strength","Number"],"pyQName":"Dimension.STRENGTH"},"Rotation":{"kind":6,"retType":"Rotation","extendsTypes":["Rotation","Number"]},"Rotation.Pitch":{"retType":"Rotation.Pitch","attributes":{"block":"pitch","_def":{"parts":[{"kind":"label","text":"pitch","style":[]}],"parameters":[]}},"extendsTypes":["Rotation.Pitch","Number"],"pyQName":"Rotation.PITCH"},"Rotation.Roll":{"retType":"Rotation.Roll","attributes":{"block":"roll","_def":{"parts":[{"kind":"label","text":"roll","style":[]}],"parameters":[]}},"extendsTypes":["Rotation.Roll","Number"],"pyQName":"Rotation.ROLL"},"AcceleratorRange":{"kind":6,"retType":"AcceleratorRange","extendsTypes":["AcceleratorRange","Number"]},"AcceleratorRange.OneG":{"retType":"AcceleratorRange.OneG","attributes":{"block":"1g","jsDoc":"The accelerator measures forces up to 1 gravity","_def":{"parts":[{"kind":"label","text":"1g","style":[]}],"parameters":[]}},"extendsTypes":["AcceleratorRange.OneG","Number"],"pyQName":"AcceleratorRange.ONE_G"},"AcceleratorRange.TwoG":{"retType":"AcceleratorRange.TwoG","attributes":{"block":"2g","jsDoc":"The accelerator measures forces up to 2 gravity","_def":{"parts":[{"kind":"label","text":"2g","style":[]}],"parameters":[]}},"extendsTypes":["AcceleratorRange.TwoG","Number"],"pyQName":"AcceleratorRange.TWO_G"},"AcceleratorRange.FourG":{"retType":"AcceleratorRange.FourG","attributes":{"block":"4g","jsDoc":"The accelerator measures forces up to 4 gravity","_def":{"parts":[{"kind":"label","text":"4g","style":[]}],"parameters":[]}},"extendsTypes":["AcceleratorRange.FourG","Number"],"pyQName":"AcceleratorRange.FOUR_G"},"AcceleratorRange.EightG":{"retType":"AcceleratorRange.EightG","attributes":{"block":"8g","jsDoc":"The accelerator measures forces up to 8 gravity","_def":{"parts":[{"kind":"label","text":"8g","style":[]}],"parameters":[]}},"extendsTypes":["AcceleratorRange.EightG","Number"],"pyQName":"AcceleratorRange.EIGHT_G"},"Gesture":{"kind":6,"retType":"Gesture","extendsTypes":["Gesture","Number"]},"Gesture.Shake":{"retType":"Gesture.Shake","attributes":{"block":"shake","jsDoc":"Raised when shaken","_def":{"parts":[{"kind":"label","text":"shake","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.Shake","Number"],"pyQName":"Gesture.SHAKE"},"Gesture.TiltUp":{"retType":"Gesture.TiltUp","attributes":{"block":"tilt up","jsDoc":"Raised when the device tilts up","_def":{"parts":[{"kind":"label","text":"tilt up","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.TiltUp","Number"],"pyQName":"Gesture.TILT_UP"},"Gesture.TiltDown":{"retType":"Gesture.TiltDown","attributes":{"block":"tilt down","jsDoc":"Raised when the device tilts down","_def":{"parts":[{"kind":"label","text":"tilt down","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.TiltDown","Number"],"pyQName":"Gesture.TILT_DOWN"},"Gesture.TiltLeft":{"retType":"Gesture.TiltLeft","attributes":{"block":"tilt left","jsDoc":"Raised when the screen is pointing left","_def":{"parts":[{"kind":"label","text":"tilt left","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.TiltLeft","Number"],"pyQName":"Gesture.TILT_LEFT"},"Gesture.TiltRight":{"retType":"Gesture.TiltRight","attributes":{"block":"tilt right","jsDoc":"Raised when the screen is pointing right","_def":{"parts":[{"kind":"label","text":"tilt right","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.TiltRight","Number"],"pyQName":"Gesture.TILT_RIGHT"},"Gesture.FaceUp":{"retType":"Gesture.FaceUp","attributes":{"block":"face up","jsDoc":"Raised when the screen faces up","_def":{"parts":[{"kind":"label","text":"face up","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.FaceUp","Number"],"pyQName":"Gesture.FACE_UP"},"Gesture.FaceDown":{"retType":"Gesture.FaceDown","attributes":{"block":"face down","jsDoc":"Raised when the screen is pointing up and the board is horizontal","_def":{"parts":[{"kind":"label","text":"face down","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.FaceDown","Number"],"pyQName":"Gesture.FACE_DOWN"},"Gesture.FreeFall":{"retType":"Gesture.FreeFall","attributes":{"block":"free fall","jsDoc":"Raised when the board is falling!","_def":{"parts":[{"kind":"label","text":"free fall","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.FreeFall","Number"],"pyQName":"Gesture.FREE_FALL"},"Gesture.TwoG":{"retType":"Gesture.TwoG","attributes":{"block":"2g (step)","jsDoc":"Raised when a 2G shock is detected","_def":{"parts":[{"kind":"label","text":"2g (step)","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.TwoG","Number"],"pyQName":"Gesture.TWO_G"},"Gesture.ThreeG":{"retType":"Gesture.ThreeG","attributes":{"block":"3g","jsDoc":"Raised when a 3G shock is detected","_def":{"parts":[{"kind":"label","text":"3g","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.ThreeG","Number"],"pyQName":"Gesture.THREE_G"},"Gesture.SixG":{"retType":"Gesture.SixG","attributes":{"block":"6g","jsDoc":"Raised when a 6G shock is detected","_def":{"parts":[{"kind":"label","text":"6g","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.SixG","Number"],"pyQName":"Gesture.SIX_G"},"Gesture.EightG":{"retType":"Gesture.EightG","attributes":{"block":"8g","jsDoc":"Raised when a 8G shock is detected","_def":{"parts":[{"kind":"label","text":"8g","style":[]}],"parameters":[]}},"extendsTypes":["Gesture.EightG","Number"],"pyQName":"Gesture.EIGHT_G"},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"controller":{"kind":5,"retType":"","attributes":{"weight":98,"color":"#D54322","icon":"","groups":["Single Player","Multiplayer"],"blockGap":"8","jsDoc":"Access to game controls"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"Colors":{"kind":6,"retType":"Colors","attributes":{"jsDoc":"Well known colors"},"extendsTypes":["Colors","Number"]},"Colors.Red":{"retType":"Colors.Red","attributes":{"block":"red","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"red","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Red","Number"],"pyQName":"Colors.RED"},"Colors.Orange":{"retType":"Colors.Orange","attributes":{"block":"orange","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"orange","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Orange","Number"],"pyQName":"Colors.ORANGE"},"Colors.Yellow":{"retType":"Colors.Yellow","attributes":{"block":"yellow","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"yellow","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Yellow","Number"],"pyQName":"Colors.YELLOW"},"Colors.Green":{"retType":"Colors.Green","attributes":{"block":"green","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"green","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Green","Number"],"pyQName":"Colors.GREEN"},"Colors.Blue":{"retType":"Colors.Blue","attributes":{"block":"blue","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"blue","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Blue","Number"],"pyQName":"Colors.BLUE"},"Colors.Indigo":{"retType":"Colors.Indigo","attributes":{"block":"indigo","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"indigo","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Indigo","Number"],"pyQName":"Colors.INDIGO"},"Colors.Violet":{"retType":"Colors.Violet","attributes":{"block":"violet","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"violet","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Violet","Number"],"pyQName":"Colors.VIOLET"},"Colors.Purple":{"retType":"Colors.Purple","attributes":{"block":"purple","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"purple","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Purple","Number"],"pyQName":"Colors.PURPLE"},"Colors.Pink":{"retType":"Colors.Pink","attributes":{"block":"pink","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"pink","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Pink","Number"],"pyQName":"Colors.PINK"},"Colors.White":{"retType":"Colors.White","attributes":{"block":"white","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"white","style":[]}],"parameters":[]}},"extendsTypes":["Colors.White","Number"],"pyQName":"Colors.WHITE"},"Colors.Black":{"retType":"Colors.Black","attributes":{"block":"black","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"black","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Black","Number"],"pyQName":"Colors.BLACK"},"ColorHues":{"kind":6,"retType":"ColorHues","attributes":{"jsDoc":"Well known color hues"},"extendsTypes":["ColorHues","Number"]},"ColorHues.Red":{"retType":"ColorHues.Red","attributes":{"block":"red","_def":{"parts":[{"kind":"label","text":"red","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Red","Number"],"pyQName":"ColorHues.RED"},"ColorHues.Orange":{"retType":"ColorHues.Orange","attributes":{"block":"orange","_def":{"parts":[{"kind":"label","text":"orange","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Orange","Number"],"pyQName":"ColorHues.ORANGE"},"ColorHues.Yellow":{"retType":"ColorHues.Yellow","attributes":{"block":"yellow","_def":{"parts":[{"kind":"label","text":"yellow","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Yellow","Number"],"pyQName":"ColorHues.YELLOW"},"ColorHues.Green":{"retType":"ColorHues.Green","attributes":{"block":"green","_def":{"parts":[{"kind":"label","text":"green","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Green","Number"],"pyQName":"ColorHues.GREEN"},"ColorHues.Aqua":{"retType":"ColorHues.Aqua","attributes":{"block":"aqua","_def":{"parts":[{"kind":"label","text":"aqua","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Aqua","Number"],"pyQName":"ColorHues.AQUA"},"ColorHues.Blue":{"retType":"ColorHues.Blue","attributes":{"block":"blue","_def":{"parts":[{"kind":"label","text":"blue","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Blue","Number"],"pyQName":"ColorHues.BLUE"},"ColorHues.Purple":{"retType":"ColorHues.Purple","attributes":{"block":"purple","_def":{"parts":[{"kind":"label","text":"purple","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Purple","Number"],"pyQName":"ColorHues.PURPLE"},"ColorHues.Magenta":{"retType":"ColorHues.Magenta","attributes":{"block":"magenta","_def":{"parts":[{"kind":"label","text":"magenta","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Magenta","Number"],"pyQName":"ColorHues.MAGENTA"},"ColorHues.Pink":{"retType":"ColorHues.Pink","attributes":{"block":"pink","_def":{"parts":[{"kind":"label","text":"pink","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Pink","Number"],"pyQName":"ColorHues.PINK"},"color":{"kind":5,"retType":"","attributes":{"advanced":true,"jsDoc":"Color manipulation"}},"color.rgb":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"red":"255","green":"255","blue":"255"},"blockId":"colorsrgb","block":"red %red|green %green|blue %blue","paramMin":{"red":"0","green":"0","blue":"0"},"paramMax":{"red":"255","green":"255","blue":"255"},"help":"colors/rgb","weight":19,"blockGap":"8","blockHidden":true,"paramHelp":{"red":"value of the red channel between 0 and 255. eg: 255","green":"value of the green channel between 0 and 255. eg: 255","blue":"value of the blue channel between 0 and 255. eg: 255"},"jsDoc":"Converts red, green, blue channels into a RGB color","_def":{"parts":[{"kind":"label","text":"red ","style":[]},{"kind":"param","name":"red","ref":false},{"kind":"break"},{"kind":"label","text":"green ","style":[]},{"kind":"param","name":"green","ref":false},{"kind":"break"},{"kind":"label","text":"blue ","style":[]},{"kind":"param","name":"blue","ref":false}],"parameters":[{"kind":"param","name":"red","ref":false},{"kind":"param","name":"green","ref":false},{"kind":"param","name":"blue","ref":false}]}},"parameters":[{"name":"red","description":"value of the red channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"green","description":"value of the green channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"blue","description":"value of the blue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.argb":{"kind":-3,"retType":"number","parameters":[{"name":"alpha"},{"name":"red"},{"name":"green"},{"name":"blue"}]},"color.wellKnown":{"kind":-3,"retType":"number","attributes":{"blockId":"colorscolors","block":"%color","help":"colors/well-known","shim":"TD_ID","weight":20,"blockGap":"8","blockHidden":true,"jsDoc":"Get the RGB value of a known color","_def":{"parts":[{"kind":"param","name":"color","ref":false}],"parameters":[{"kind":"param","name":"color","ref":false}]}},"parameters":[{"name":"color","type":"Colors","isEnum":true}],"pyQName":"color.well_known"},"color.hsv":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"hue":"255","sat":"255","val":"255"},"blockId":"colorshsv","block":"hue %hue|sat %sat|val %val","paramMin":{"hue":"0","sat":"0","val":"0"},"paramMax":{"hue":"255","sat":"255","val":"255"},"help":"colors/hsv","weight":17,"blockHidden":true,"paramHelp":{"hue":"value of the hue channel between 0 and 255. eg: 255","sat":"value of the saturation channel between 0 and 255. eg: 255","val":"value of the value channel between 0 and 255. eg: 255"},"jsDoc":"Convert an HSV (hue, saturation, value) color to RGB","_def":{"parts":[{"kind":"label","text":"hue ","style":[]},{"kind":"param","name":"hue","ref":false},{"kind":"break"},{"kind":"label","text":"sat ","style":[]},{"kind":"param","name":"sat","ref":false},{"kind":"break"},{"kind":"label","text":"val ","style":[]},{"kind":"param","name":"val","ref":false}],"parameters":[{"kind":"param","name":"hue","ref":false},{"kind":"param","name":"sat","ref":false},{"kind":"param","name":"val","ref":false}]}},"parameters":[{"name":"hue","description":"value of the hue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"sat","description":"value of the saturation channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"val","description":"value of the value channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.fade":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"brightness":"128"},"blockId":"colorsfade","block":"fade %color=neopixel_colors|by %brightness","paramMin":{"brightness":"0"},"paramMax":{"brightness":"255"},"help":"light/fade","group":"Color","weight":18,"blockGap":"8","blockHidden":true,"paramHelp":{"color":"color to fade","brightness":"the amount of brightness to apply to the color, eg: 128"},"jsDoc":"Fade the color by the brightness","_def":{"parts":[{"kind":"label","text":"fade ","style":[]},{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"break"},{"kind":"label","text":"by ","style":[]},{"kind":"param","name":"brightness","ref":false}],"parameters":[{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"param","name":"brightness","ref":false}]}},"parameters":[{"name":"color","description":"color to fade"},{"name":"brightness","description":"the amount of brightness to apply to the color, eg: 128","default":"128","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.blend":{"kind":-3,"retType":"number","parameters":[{"name":"color"},{"name":"alpha"},{"name":"otherColor"}]},"color.gradient":{"kind":-3,"retType":"color.ColorBuffer","parameters":[{"name":"startColor"},{"name":"endColor"},{"name":"steps"}]},"color.unpackR":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_r"},"color.unpackG":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_g"},"color.unpackB":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_b"},"color.parseColor":{"kind":-3,"retType":"number","parameters":[{"name":"color","type":"string"}],"pyQName":"color.parse_color"},"color.ColorBufferLayout":{"kind":6,"retType":"color.ColorBufferLayout","extendsTypes":["color.ColorBufferLayout","Number"]},"color.ColorBufferLayout.RGB":{"retType":"color.ColorBufferLayout.RGB","attributes":{"jsDoc":"24bit RGB color"},"extendsTypes":["color.ColorBufferLayout.RGB","Number"]},"color.ColorBufferLayout.ARGB":{"retType":"color.ColorBufferLayout.ARGB","attributes":{"jsDoc":"32bit RGB color with alpha"},"extendsTypes":["color.ColorBufferLayout.ARGB","Number"]},"color.ColorBuffer":{"kind":8,"retType":"color.ColorBuffer","attributes":{"jsDoc":"A buffer of colors"},"extendsTypes":[]},"color.ColorBuffer.layout":{"kind":2,"retType":"color.ColorBufferLayout","isInstance":true},"color.ColorBuffer.buf":{"kind":2,"retType":"Buffer","isInstance":true},"color.ColorBuffer.__constructor":{"kind":-3,"parameters":[{"name":"length"},{"name":"layout","type":"color.ColorBufferLayout","initializer":"undefined","isEnum":true}],"isInstance":true},"color.ColorBuffer.fromBuffer":{"kind":-1,"retType":"color.ColorBuffer","parameters":[{"name":"buffer","type":"Buffer"},{"name":"layout","type":"color.ColorBufferLayout","isEnum":true}],"pyQName":"color.ColorBuffer.from_buffer"},"color.ColorBuffer.stride":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"color.ColorBuffer.length":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"color.ColorBuffer.color":{"kind":-1,"retType":"number","parameters":[{"name":"index"}],"isInstance":true},"color.ColorBuffer.setColor":{"kind":-1,"parameters":[{"name":"index"},{"name":"color"}],"isInstance":true,"pyQName":"color.ColorBuffer.set_color"},"color.ColorBuffer.slice":{"kind":-1,"retType":"color.ColorBuffer","parameters":[{"name":"start","initializer":"undefined"},{"name":"length","initializer":"undefined"}],"isInstance":true},"color.ColorBuffer.write":{"kind":-1,"attributes":{"paramHelp":{"dstOffset":"@param src"},"jsDoc":"Writes the content of the src color buffer starting at the start dstOffset in the current buffer"},"parameters":[{"name":"dstOffset","description":"@param src"},{"name":"src","type":"color.ColorBuffer"}],"isInstance":true},"color.createBuffer":{"kind":-3,"retType":"color.ColorBuffer","attributes":{"jsDoc":"Converts an array of colors into a color buffer"},"parameters":[{"name":"colors","type":"number[]"},{"name":"layout","type":"color.ColorBufferLayout","initializer":"undefined","isEnum":true}],"pyQName":"color.create_buffer"},"NeoPixelMode":{"kind":6,"retType":"NeoPixelMode","attributes":{"jsDoc":"Different modes for RGB or RGB+W NeoPixel strips"},"extendsTypes":["NeoPixelMode","Number"]},"NeoPixelMode.RGB":{"retType":"NeoPixelMode.RGB","attributes":{"block":"RGB (GRB format)","_def":{"parts":[{"kind":"label","text":"RGB (GRB format)","style":[]}],"parameters":[]}},"extendsTypes":["NeoPixelMode.RGB","Number"]},"NeoPixelMode.RGBW":{"retType":"NeoPixelMode.RGBW","attributes":{"block":"RGB+W","_def":{"parts":[{"kind":"label","text":"RGB+W","style":[]}],"parameters":[]}},"extendsTypes":["NeoPixelMode.RGBW","Number"]},"NeoPixelMode.RGB_RGB":{"retType":"NeoPixelMode.RGB_RGB","attributes":{"block":"RGB (RGB format)","_def":{"parts":[{"kind":"label","text":"RGB (RGB format)","style":[]}],"parameters":[]}},"extendsTypes":["NeoPixelMode.RGB_RGB","Number"]},"NeoPixelMode.APA102":{"retType":"NeoPixelMode.APA102","attributes":{"block":"APA102","_def":{"parts":[{"kind":"label","text":"APA102","style":[]}],"parameters":[]}},"extendsTypes":["NeoPixelMode.APA102","Number"]},"LightMove":{"kind":6,"retType":"LightMove","extendsTypes":["LightMove","Number"]},"LightMove.Rotate":{"retType":"LightMove.Rotate","attributes":{"block":"rotate","_def":{"parts":[{"kind":"label","text":"rotate","style":[]}],"parameters":[]}},"extendsTypes":["LightMove.Rotate","Number"],"pyQName":"LightMove.ROTATE"},"LightMove.Shift":{"retType":"LightMove.Shift","attributes":{"block":"shift","_def":{"parts":[{"kind":"label","text":"shift","style":[]}],"parameters":[]}},"extendsTypes":["LightMove.Shift","Number"],"pyQName":"LightMove.SHIFT"},"PhotonMode":{"kind":6,"retType":"PhotonMode","attributes":{"jsDoc":"A determines the mode of the photon"},"extendsTypes":["PhotonMode","Number"]},"PhotonMode.PenUp":{"retType":"PhotonMode.PenUp","attributes":{"block":"pen up","_def":{"parts":[{"kind":"label","text":"pen up","style":[]}],"parameters":[]}},"extendsTypes":["PhotonMode.PenUp","Number"],"pyQName":"PhotonMode.PEN_UP"},"PhotonMode.PenDown":{"retType":"PhotonMode.PenDown","attributes":{"block":"pen down","_def":{"parts":[{"kind":"label","text":"pen down","style":[]}],"parameters":[]}},"extendsTypes":["PhotonMode.PenDown","Number"],"pyQName":"PhotonMode.PEN_DOWN"},"PhotonMode.Eraser":{"retType":"PhotonMode.Eraser","attributes":{"block":"eraser","_def":{"parts":[{"kind":"label","text":"eraser","style":[]}],"parameters":[]}},"extendsTypes":["PhotonMode.Eraser","Number"],"pyQName":"PhotonMode.ERASER"},"PhotonMode.Off":{"retType":"PhotonMode.Off","attributes":{"block":"off","_def":{"parts":[{"kind":"label","text":"off","style":[]}],"parameters":[]}},"extendsTypes":["PhotonMode.Off","Number"],"pyQName":"PhotonMode.OFF"},"LightAnimation":{"kind":6,"retType":"LightAnimation","extendsTypes":["LightAnimation","Number"]},"LightAnimation.Rainbow":{"retType":"LightAnimation.Rainbow","attributes":{"blockImage":"1","block":"rainbow","_def":{"parts":[{"kind":"label","text":"rainbow","style":[]}],"parameters":[]}},"extendsTypes":["LightAnimation.Rainbow","Number"],"pyQName":"LightAnimation.RAINBOW"},"LightAnimation.RunningLights":{"retType":"LightAnimation.RunningLights","attributes":{"blockImage":"1","block":"running lights","_def":{"parts":[{"kind":"label","text":"running lights","style":[]}],"parameters":[]}},"extendsTypes":["LightAnimation.RunningLights","Number"],"pyQName":"LightAnimation.RUNNING_LIGHTS"},"LightAnimation.Comet":{"retType":"LightAnimation.Comet","attributes":{"blockImage":"1","block":"comet","_def":{"parts":[{"kind":"label","text":"comet","style":[]}],"parameters":[]}},"extendsTypes":["LightAnimation.Comet","Number"],"pyQName":"LightAnimation.COMET"},"LightAnimation.Sparkle":{"retType":"LightAnimation.Sparkle","attributes":{"blockImage":"1","block":"sparkle","_def":{"parts":[{"kind":"label","text":"sparkle","style":[]}],"parameters":[]}},"extendsTypes":["LightAnimation.Sparkle","Number"],"pyQName":"LightAnimation.SPARKLE"},"LightAnimation.TheaterChase":{"retType":"LightAnimation.TheaterChase","attributes":{"blockImage":"1","block":"theater chase","_def":{"parts":[{"kind":"label","text":"theater chase","style":[]}],"parameters":[]}},"extendsTypes":["LightAnimation.TheaterChase","Number"],"pyQName":"LightAnimation.THEATER_CHASE"},"LightAnimation.ColorWipe":{"retType":"LightAnimation.ColorWipe","attributes":{"blockImage":"1","block":"color wipe","_def":{"parts":[{"kind":"label","text":"color wipe","style":[]}],"parameters":[]}},"extendsTypes":["LightAnimation.ColorWipe","Number"],"pyQName":"LightAnimation.COLOR_WIPE"},"light.NeoPixelStrip":{"kind":8,"retType":"light.NeoPixelStrip","attributes":{"jsDoc":"A NeoPixel strip"},"extendsTypes":[]},"light.NeoPixelStrip._parent":{"kind":2,"retType":"light.NeoPixelStrip","isInstance":true},"light.NeoPixelStrip._dataPin":{"kind":2,"retType":"DigitalInOutPin","isInstance":true,"pyQName":"light.NeoPixelStrip._data_pin"},"light.NeoPixelStrip._clkPin":{"kind":2,"retType":"DigitalInOutPin","isInstance":true,"pyQName":"light.NeoPixelStrip._clk_pin"},"light.NeoPixelStrip._buf":{"kind":2,"retType":"Buffer","isInstance":true},"light.NeoPixelStrip._brightnessBuf":{"kind":2,"retType":"Buffer","isInstance":true,"pyQName":"light.NeoPixelStrip._brightness_buf"},"light.NeoPixelStrip._sendBuf":{"kind":2,"retType":"Buffer","isInstance":true,"pyQName":"light.NeoPixelStrip._send_buf"},"light.NeoPixelStrip._brightness":{"kind":2,"retType":"number","isInstance":true},"light.NeoPixelStrip._start":{"kind":2,"retType":"number","isInstance":true},"light.NeoPixelStrip._length":{"kind":2,"retType":"number","isInstance":true},"light.NeoPixelStrip._mode":{"kind":2,"retType":"NeoPixelMode","isInstance":true},"light.NeoPixelStrip._buffered":{"kind":2,"retType":"boolean","isInstance":true},"light.NeoPixelStrip._animationQueue":{"kind":2,"retType":"control.AnimationQueue","isInstance":true,"pyQName":"light.NeoPixelStrip._animation_queue"},"light.NeoPixelStrip._barGraphHigh":{"kind":2,"retType":"number","isInstance":true,"pyQName":"light.NeoPixelStrip._bar_graph_high"},"light.NeoPixelStrip._barGraphHighLast":{"kind":2,"retType":"number","isInstance":true,"pyQName":"light.NeoPixelStrip._bar_graph_high_last"},"light.NeoPixelStrip._photonMode":{"kind":2,"retType":"number","isInstance":true,"pyQName":"light.NeoPixelStrip._photon_mode"},"light.NeoPixelStrip._photonPos":{"kind":2,"retType":"number","isInstance":true,"pyQName":"light.NeoPixelStrip._photon_pos"},"light.NeoPixelStrip._photonDir":{"kind":2,"retType":"number","isInstance":true,"pyQName":"light.NeoPixelStrip._photon_dir"},"light.NeoPixelStrip._photonPenColor":{"kind":2,"retType":"number","isInstance":true,"pyQName":"light.NeoPixelStrip._photon_pen_color"},"light.NeoPixelStrip._lastAnimation":{"kind":2,"retType":"light.NeoPixelAnimation","isInstance":true,"pyQName":"light.NeoPixelStrip._last_animation"},"light.NeoPixelStrip._lastAnimationRenderer":{"kind":2,"retType":"() => boolean","isInstance":true,"pyQName":"light.NeoPixelStrip._last_animation_renderer"},"light.NeoPixelStrip._transitionPlayer":{"kind":2,"retType":"light.BrightnessTransitionPlayer","isInstance":true,"pyQName":"light.NeoPixelStrip._transition_player"},"light.NeoPixelStrip.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"light.NeoPixelStrip.buf":{"kind":-2,"retType":"Buffer","attributes":{"jsDoc":"Gets the underlying color buffer for the entire strip"},"isInstance":true,"isReadOnly":true},"light.NeoPixelStrip.brightnessBuf":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"light.NeoPixelStrip.brightness_buf"},"light.NeoPixelStrip.mode":{"kind":-2,"retType":"NeoPixelMode","attributes":{"jsDoc":"Gets the LED data layout mode"},"isInstance":true,"isReadOnly":true},"light.NeoPixelStrip.setAll":{"kind":-1,"attributes":{"blockId":"light_set_strip_color","block":"set %strip all pixels to %rgb=colorNumberPicker","help":"light/neopixelstrip/set-all","weight":80,"blockGap":"8","advanced":true,"paramHelp":{"rgb":"RGB color of the LED"},"jsDoc":"Set all of the pixels on the strip to one RGB color.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" all pixels to ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"rgb","description":"RGB color of the LED"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_all"},"light.NeoPixelStrip.setGradient":{"kind":-1,"attributes":{"blockId":"lightsetgradient","block":"set %strip gradient from %startColor=colorNumberPicker to %endColor=colorNumberPicker","weight":79,"blockGap":"8","group":"More","advanced":true,"paramHelp":{"startColor":"the start color","endColor":"the end color"},"jsDoc":"Sets a gradient between two colors","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" gradient from ","style":[]},{"kind":"param","name":"startColor","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"endColor","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"startColor","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"param","name":"endColor","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"startColor","description":"the start color"},{"name":"endColor","description":"the end color"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_gradient"},"light.NeoPixelStrip.graph":{"kind":-1,"attributes":{"blockId":"light_show_bar_graph","block":"%strip|graph %value||up to %high","icon":"","help":"light/neopixelstrip/graph","weight":70,"blockGap":"8","advanced":true,"paramHelp":{"value":"current value to plot","high":"maximum value, 0 to autoscale"},"jsDoc":"Display a vertical bar graph based on the `value` and `high` value.\nIf `high` is 0, the chart gets adjusted automatically.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"graph ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"value","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":"up to ","style":[]},{"kind":"param","name":"high","ref":false}],"parameters":[{"kind":"param","name":"high","ref":false}]}},"parameters":[{"name":"value","description":"current value to plot"},{"name":"high","description":"maximum value, 0 to autoscale","initializer":"undefined"}],"isInstance":true},"light.NeoPixelStrip.setPixelColor":{"kind":-1,"attributes":{"blockId":"light_set_pixel_color","block":"set %strip pixel color at %pixeloffset|to %rgb=colorNumberPicker","help":"light/neopixelstrip/set-pixel-color","weight":79,"blockGap":"8","group":"More","advanced":true,"paramHelp":{"pixeloffset":"position of the NeoPixel in the strip","color":"RGB color of the LED"},"jsDoc":"Set the pixel to a given color.\nYou need to call ``show`` to make the changes visible.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" pixel color at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the NeoPixel in the strip"},{"name":"c"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_pixel_color"},"light.NeoPixelStrip.pixelColor":{"kind":-1,"retType":"number","attributes":{"blockId":"light_get_pixel_color","block":"%strip|pixel color at %pixeloffset","help":"light/neopixelstrip/pixel-color","weight":9,"blockGap":"8","group":"More","advanced":true,"paramHelp":{"pixeloffset":"position of the NeoPixel in the strip"},"jsDoc":"Gets the pixel color.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"pixel color at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"pixeloffset","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the NeoPixel in the strip"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.pixel_color"},"light.NeoPixelStrip.setPixelWhiteLED":{"kind":-1,"attributes":{"blockId":"light_set_pixel_white_led","block":"set %strip pixel white LED at %pixeloffset|to %white","help":"light/neopixelstrip/set-pixel-white-led","weight":5,"blockGap":"8","group":"More","advanced":true,"paramHelp":{"pixeloffset":"position of the LED in the strip","white":"brightness of the white LED"},"jsDoc":"Set the white brightness of a pixel in a NeoPixel strip of RGB+W LEDs.\nThis only works for RGB+W NeoPixels.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" pixel white LED at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"white","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"param","name":"white","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the LED in the strip"},{"name":"white","description":"brightness of the white LED"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_pixel_white_led"},"light.NeoPixelStrip.show":{"kind":-1,"attributes":{"blockId":"light_show","block":"%strip|show","help":"light/neopixelstrip/show","weight":86,"blockGap":"8","group":"More","advanced":true,"jsDoc":"Make the strip show all the new changes for the pixels.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"show","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false}]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.clear":{"kind":-1,"attributes":{"blockId":"light_clear","block":"%strip|clear","help":"light/neopixelstrip/clear","weight":85,"blockGap":"8","group":"More","advanced":true,"jsDoc":"Turn off all pixel LEDs.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"clear","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false}]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.length":{"kind":-1,"retType":"number","attributes":{"blockId":"light_length","block":"%strip|length","help":"light/neopixelstrip/length","weight":8,"blockGap":"8","group":"More","advanced":true,"jsDoc":"Get the number of pixels on the strip","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"length","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false}]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.setBrightness":{"kind":-1,"attributes":{"paramDefl":{"brightness":"20"},"blockId":"light_set_brightness","block":"set %strip brightness %brightness","paramMin":{"brightness":"0"},"paramMax":{"brightness":"255"},"help":"light/neopixelstrip/set-brightness","weight":2,"blockGap":"8","advanced":true,"paramHelp":{"brightness":"a measure of LED brightness in 0-255. eg: 20"},"jsDoc":"Set the brightness of the strip. This flag only applies to future operation.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" brightness ","style":[]},{"kind":"param","name":"brightness","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"brightness","ref":false}]}},"parameters":[{"name":"brightness","description":"a measure of LED brightness in 0-255. eg: 20","default":"20","options":{"min":{"value":"0"},"max":{"value":"255"}}}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_brightness"},"light.NeoPixelStrip.setPixelBrightness":{"kind":-1,"attributes":{"paramHelp":{"index":"@param brightness "},"jsDoc":"Sets an individual pixel brightness"},"parameters":[{"name":"index","description":"@param brightness "},{"name":"brightness"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_pixel_brightness"},"light.NeoPixelStrip.brightness":{"kind":-1,"retType":"number","attributes":{"blockId":"light_get_brightness","block":"%strip|brightness","help":"light/neopixelstrip/brightness","parts":"neopixel","weight":7,"blockGap":"8","group":"More","advanced":true,"jsDoc":"Get the brightness of the pixel strip.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"brightness","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false}]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.range":{"kind":-1,"retType":"light.NeoPixelStrip","attributes":{"paramDefl":{"length":"4"},"blockId":"light_range","block":"%strip|range from %start|with %length|pixels","help":"light/neopixelstrip/range","weight":99,"blockGap":"30","blockSetVariable":"strip","advanced":true,"paramHelp":{"start":"offset in the NeoPixel strip to start the range","length":"number of pixels in the range, eg: 4"},"jsDoc":"Create a range of pixels.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"range from ","style":[]},{"kind":"param","name":"start","ref":false},{"kind":"break"},{"kind":"label","text":"with ","style":[]},{"kind":"param","name":"length","ref":false},{"kind":"break"},{"kind":"label","text":"pixels","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"start","ref":false},{"kind":"param","name":"length","ref":false}]}},"parameters":[{"name":"start","description":"offset in the NeoPixel strip to start the range"},{"name":"length","description":"number of pixels in the range, eg: 4","default":"4"}],"isInstance":true},"light.NeoPixelStrip.move":{"kind":-1,"attributes":{"paramDefl":{"offset":"1"},"blockId":"light_move_pixels","block":"%strip|%kind=MoveKind|by %offset","help":"light/neopixelstrip/move","weight":87,"blockGap":"8","group":"More","advanced":true,"paramHelp":{"offset":"number of pixels to shift forward, eg: 1"},"jsDoc":"Shift LEDs forward and clear with zeros.\nYou need to call ``show`` to make the changes visible.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"param","name":"kind","shadowBlockId":"MoveKind","ref":false},{"kind":"break"},{"kind":"label","text":"by ","style":[]},{"kind":"param","name":"offset","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"kind","shadowBlockId":"MoveKind","ref":false},{"kind":"param","name":"offset","ref":false}]}},"parameters":[{"name":"kind","type":"LightMove","isEnum":true},{"name":"offset","description":"number of pixels to shift forward, eg: 1","initializer":"1","default":"1"}],"isInstance":true},"light.NeoPixelStrip.initPhoton":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"light.NeoPixelStrip.init_photon"},"light.NeoPixelStrip.photonForward":{"kind":-1,"attributes":{"paramDefl":{"steps":"1"},"blockId":"light_photon_fd","block":"%strip|photon forward by %steps","help":"light/neopixelstrip/photon-forward","weight":41,"blockGap":"8","group":"Photon","advanced":true,"paramHelp":{"steps":"number of steps (lights) to move, eg: 1"},"jsDoc":"Move a photon effect along the pixel strip by a number of steps.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"photon forward by ","style":[]},{"kind":"param","name":"steps","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"steps","ref":false}]}},"parameters":[{"name":"steps","description":"number of steps (lights) to move, eg: 1","default":"1"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.photon_forward"},"light.NeoPixelStrip.photonFlip":{"kind":-1,"attributes":{"blockId":"light_photon_flip","block":"%strip|photon flip","help":"light/neopixelstrip/photon-flip","weight":40,"blockGap":"8","group":"Photon","advanced":true,"jsDoc":"Switch the direction of the photon pulse.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"photon flip","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"light.NeoPixelStrip.photon_flip"},"light.NeoPixelStrip.setPhotonPosition":{"kind":-1,"attributes":{"blockId":"light_photon_set_position","block":"%strip|photon set position %index","help":"light/neopixelstrip/set-photon-position","weight":39,"blockGap":"8","group":"Photon","advanced":true,"paramHelp":{"index":"index of the light, if out of bound, the index is wrapped"},"jsDoc":"Sets the photon position to a given light index","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"photon set position ","style":[]},{"kind":"param","name":"index","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"index","ref":false}]}},"parameters":[{"name":"index","description":"index of the light, if out of bound, the index is wrapped"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_photon_position"},"light.NeoPixelStrip.setPhotonPenColor":{"kind":-1,"attributes":{"blockId":"light_photon_set_pen_color","block":"%strip=variables_get|photon set pen color %color=colorNumberPicker","help":"light/neopixelstrip/set-photon-pen-color","weight":38,"blockGap":"8","group":"Photon","advanced":true,"paramHelp":{"color":"the color of the photon"},"jsDoc":"Set the photon color.","_def":{"parts":[{"kind":"param","name":"strip","shadowBlockId":"variables_get","ref":false},{"kind":"break"},{"kind":"label","text":"photon set pen color ","style":[]},{"kind":"param","name":"color","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"strip","shadowBlockId":"variables_get","ref":false},{"kind":"param","name":"color","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"color","description":"the color of the photon"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_photon_pen_color"},"light.NeoPixelStrip.setPhotonPenHue":{"kind":-1,"attributes":{"blockId":"light_photon_set_pen_hue","block":"%strip=variables_get|photon set pen hue %hue=colorWheelHsvPicker","help":"light/neopixelstrip/set-photon-pen-hue","weight":39,"blockGap":"8","group":"Photon","advanced":true,"paramHelp":{"hue":"the hue of the photon color"},"jsDoc":"Sets the photon hue.","_def":{"parts":[{"kind":"param","name":"strip","shadowBlockId":"variables_get","ref":false},{"kind":"break"},{"kind":"label","text":"photon set pen hue ","style":[]},{"kind":"param","name":"hue","shadowBlockId":"colorWheelHsvPicker","ref":false}],"parameters":[{"kind":"param","name":"strip","shadowBlockId":"variables_get","ref":false},{"kind":"param","name":"hue","shadowBlockId":"colorWheelHsvPicker","ref":false}]}},"parameters":[{"name":"hue","description":"the hue of the photon color"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_photon_pen_hue"},"light.NeoPixelStrip.setPhotonColor":{"kind":-1,"attributes":{"deprecated":"1","blockHidden":true,"group":"Photon","advanced":true},"parameters":[{"name":"hue"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_photon_color"},"light.NeoPixelStrip.setPhotonMode":{"kind":-1,"attributes":{"blockId":"light_photon_set_photon","block":"%strip|photon %mode","help":"light/neopixelstrip/set-photon-mode","weight":38,"group":"Photon","advanced":true,"paramHelp":{"mode":"the desired mode"},"jsDoc":"Set the photon mode to pen up, pen down, or eraser.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"photon ","style":[]},{"kind":"param","name":"mode","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"mode","ref":false}]}},"parameters":[{"name":"mode","description":"the desired mode","type":"PhotonMode","isEnum":true}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_photon_mode"},"light.NeoPixelStrip.startBrightnessTransition":{"kind":-1,"attributes":{"paramHelp":{"transition":"@param duration "},"jsDoc":"Starts a brightness transition on the strip (and cancels any other running transition)"},"parameters":[{"name":"startBrightness"},{"name":"endBrightness"},{"name":"duration"},{"name":"repeat","initializer":"undefined"},{"name":"yoyo","type":"boolean","initializer":"undefined"},{"name":"transition","description":"@param duration ","type":"light.BrightnessTransition","initializer":"undefined"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.start_brightness_transition"},"light.NeoPixelStrip.stopBrightnessTransition":{"kind":-1,"attributes":{"jsDoc":"Stops any running brightness transition"},"parameters":[],"isInstance":true,"pyQName":"light.NeoPixelStrip.stop_brightness_transition"},"light.NeoPixelStrip.showAnimation":{"kind":-1,"attributes":{"paramDefl":{"duration":"500"},"blockId":"light_show_animation","block":"%strip|show animation %animation=light_animation_picker|for %duration=timePicker|ms","help":"light/neopixelstrip/show-animation","weight":90,"blockGap":"8","advanced":true,"paramHelp":{"animation":"the animation to run","duration":"the duration to run in milliseconds, eg: 500"},"jsDoc":"Show an animation or queue an animation in the animation queue","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"show animation ","style":[]},{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"break"},{"kind":"label","text":"for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"animation","description":"the animation to run","type":"light.NeoPixelAnimation"},{"name":"duration","description":"the duration to run in milliseconds, eg: 500","default":"500"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.show_animation"},"light.NeoPixelStrip.showAnimationFrame":{"kind":-1,"attributes":{"blockId":"light_show_animation_frame","block":"%strip|show frame of %animation=light_animation_picker|animation","help":"light/neopixelstrip/show-animation-frame","weight":87,"blockGap":"8","group":"More","advanced":true,"paramHelp":{"animation":"the animation to run"},"jsDoc":"Show a single animation frame.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"show frame of ","style":[]},{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"break"},{"kind":"label","text":"animation","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false}]}},"parameters":[{"name":"animation","description":"the animation to run","type":"light.NeoPixelAnimation"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.show_animation_frame"},"light.NeoPixelStrip.showColors":{"kind":-1,"attributes":{"jsDoc":"Renders a pattern of colors on the strip"},"parameters":[{"name":"leds","type":"string"},{"name":"interval","initializer":"400"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.show_colors"},"light.NeoPixelStrip.stopAllAnimations":{"kind":-1,"attributes":{"blockId":"light_stop_all_animations","block":"%strip|stop all animations","help":"light/neopixelstrip/stop-all-animations","weight":85,"blockGap":"8","group":"More","advanced":true,"jsDoc":"Stop the current animation and any other animations ready to show.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"stop all animations","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"light.NeoPixelStrip.stop_all_animations"},"light.NeoPixelStrip.setBuffered":{"kind":-1,"attributes":{"blockId":"light_set_buffered","block":"set %strip buffered  %on","help":"light/neopixelstrip/set-buffered","weight":86,"blockGap":"8","group":"Configuration","advanced":true,"paramHelp":{"on":"call show whenever a light is modified"},"jsDoc":"Enables or disables automatically calling show when a change is made","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" buffered  ","style":[]},{"kind":"param","name":"on","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"on","ref":false}]}},"parameters":[{"name":"on","description":"call show whenever a light is modified","type":"boolean"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_buffered"},"light.NeoPixelStrip.buffered":{"kind":-1,"retType":"boolean","attributes":{"weight":85,"blockGap":"8","group":"Configuration","advanced":true,"jsDoc":"Gets a value indicated if the changes are buffered"},"parameters":[],"isInstance":true},"light.NeoPixelStrip.setMode":{"kind":-1,"attributes":{"blockId":"light_set_mode","block":"set %strip mode to %mode","help":"light/neopixelstrip/set-mode","weight":1,"blockGap":"8","group":"Configuration","advanced":true,"paramHelp":{"mode":"the kind of color encoding required by the programmable lights"},"jsDoc":"Sets the color mode and clears the colors.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" mode to ","style":[]},{"kind":"param","name":"mode","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"mode","ref":false}]}},"parameters":[{"name":"mode","description":"the kind of color encoding required by the programmable lights","type":"NeoPixelMode","isEnum":true}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_mode"},"light.NeoPixelStrip.setLength":{"kind":-1,"attributes":{"blockId":"light_set_length","block":"set %strip length to %length pixels","weight":1,"blockGap":"8","_shadowOverrides":{"length":"lightLengthPicker"},"group":"Configuration","advanced":true,"paramHelp":{"numleds":""},"jsDoc":"Sets the number of LEDs on a strip","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" length to ","style":[]},{"kind":"param","name":"length","shadowBlockId":"lightLengthPicker","ref":false},{"kind":"label","text":" pixels","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"length","shadowBlockId":"lightLengthPicker","ref":false}]}},"parameters":[{"name":"numleds"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_length"},"light.NeoPixelStrip.__setAll":{"kind":-1,"attributes":{"blockId":"neopixel_set_strip_color","block":"set all pixels to %rgb=colorNumberPicker","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"rgb":"RGB color of the LED"},"jsDoc":"Set all of the pixels on the strip to one RGB color.","_def":{"parts":[{"kind":"label","text":"set all pixels to ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"rgb","description":"RGB color of the LED"}],"isInstance":true},"light.NeoPixelStrip.__graph":{"kind":-1,"attributes":{"blockId":"neopixel_show_bar_graph","block":"graph %value |up to %high","icon":"","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"value":"current value to plot","high":"maximum value, 0 to autoscale"},"jsDoc":"Display a vertical bar graph based on the `value` and `high` value.\nIf `high` is 0, the chart gets adjusted automatically.","_def":{"parts":[{"kind":"label","text":"graph ","style":[]},{"kind":"param","name":"value","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"break"},{"kind":"label","text":"up to ","style":[]},{"kind":"param","name":"high","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false},{"kind":"param","name":"high","ref":false}]}},"parameters":[{"name":"value","description":"current value to plot"},{"name":"high","description":"maximum value, 0 to autoscale"}],"isInstance":true},"light.NeoPixelStrip.__setPixelColor":{"kind":-1,"attributes":{"blockId":"neopixel_set_pixel_color","block":"set pixel color at %pixeloffset|to %rgb=colorNumberPicker","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"pixeloffset":"position of the NeoPixel in the strip","color":"RGB color of the LED"},"jsDoc":"Set the pixel to a given color.\nYou need to call ``show`` to make the changes visible.","_def":{"parts":[{"kind":"label","text":"set pixel color at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"pixeloffset","ref":false},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the NeoPixel in the strip"},{"name":"color","description":"RGB color of the LED"}],"isInstance":true},"light.NeoPixelStrip.__pixelColor":{"kind":-1,"retType":"number","attributes":{"blockId":"neopixel_get_pixel_color","block":"pixel color at %pixeloffset","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"pixeloffset":"position of the NeoPixel in the strip"},"jsDoc":"Gets the pixel color.","_def":{"parts":[{"kind":"label","text":"pixel color at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false}],"parameters":[{"kind":"param","name":"pixeloffset","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the NeoPixel in the strip"}],"isInstance":true},"light.NeoPixelStrip.__setPixelWhiteLED":{"kind":-1,"attributes":{"blockId":"neopixel_set_pixel_white_led","block":"set pixel white LED at %pixeloffset|to %white","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"pixeloffset":"position of the LED in the strip","white":"brightness of the white LED"},"jsDoc":"Set the white brightness of a pixel in a NeoPixel strip of RGB+W LEDs.\nThis only works for RGB+W NeoPixels.","_def":{"parts":[{"kind":"label","text":"set pixel white LED at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"white","ref":false}],"parameters":[{"kind":"param","name":"pixeloffset","ref":false},{"kind":"param","name":"white","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the LED in the strip"},{"name":"white","description":"brightness of the white LED"}],"isInstance":true},"light.NeoPixelStrip.__show":{"kind":-1,"attributes":{"blockId":"neopixel_show","block":"show","deprecated":"1","defaultInstance":"light.pixels","jsDoc":"Make the strip show all the new changes for the pixels.","_def":{"parts":[{"kind":"label","text":"show","style":[]}],"parameters":[]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.__clear":{"kind":-1,"attributes":{"blockId":"neopixel_clear","block":"clear","deprecated":"1","defaultInstance":"light.pixels","jsDoc":"Turn off all pixel LEDs.","_def":{"parts":[{"kind":"label","text":"clear","style":[]}],"parameters":[]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.__length":{"kind":-1,"retType":"number","attributes":{"blockId":"neopixel_length","block":"length","deprecated":"1","defaultInstance":"light.pixels","jsDoc":"Get the number of pixels on the strip","_def":{"parts":[{"kind":"label","text":"length","style":[]}],"parameters":[]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.__setBrightness":{"kind":-1,"attributes":{"paramDefl":{"brightness":"20"},"blockId":"neopixel_set_brightness","block":"set brightness %brightness","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"brightness":"a measure of LED brightness in 0-255. eg: 20"},"jsDoc":"Set the brightness of the strip. This flag only applies to future operation.","_def":{"parts":[{"kind":"label","text":"set brightness ","style":[]},{"kind":"param","name":"brightness","ref":false}],"parameters":[{"kind":"param","name":"brightness","ref":false}]}},"parameters":[{"name":"brightness","description":"a measure of LED brightness in 0-255. eg: 20","default":"20"}],"isInstance":true},"light.NeoPixelStrip.__brightness":{"kind":-1,"retType":"number","attributes":{"blockId":"neopixel_get_brightness","block":"brightness","deprecated":"1","defaultInstance":"light.pixels","jsDoc":"Get the brightness of the pixel strip.","_def":{"parts":[{"kind":"label","text":"brightness","style":[]}],"parameters":[]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.__range":{"kind":-1,"retType":"light.NeoPixelStrip","attributes":{"paramDefl":{"length":"4"},"blockId":"neopixel_range","block":"range from %start|with %length|pixels","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"start":"offset in the NeoPixel strip to start the range","length":"number of pixels in the range. eg: 4"},"jsDoc":"Create a range of pixels.","_def":{"parts":[{"kind":"label","text":"range from ","style":[]},{"kind":"param","name":"start","ref":false},{"kind":"break"},{"kind":"label","text":"with ","style":[]},{"kind":"param","name":"length","ref":false},{"kind":"break"},{"kind":"label","text":"pixels","style":[]}],"parameters":[{"kind":"param","name":"start","ref":false},{"kind":"param","name":"length","ref":false}]}},"parameters":[{"name":"start","description":"offset in the NeoPixel strip to start the range"},{"name":"length","description":"number of pixels in the range. eg: 4","default":"4"}],"isInstance":true},"light.NeoPixelStrip.__move":{"kind":-1,"attributes":{"paramDefl":{"offset":"1"},"blockId":"neopixel_move_pixels","block":"%kind=MoveKind|by %offset","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"offset":"number of pixels to shift forward, eg: 1"},"jsDoc":"Shift LEDs forward and clear with zeros.\nYou need to call ``show`` to make the changes visible.","_def":{"parts":[{"kind":"param","name":"kind","shadowBlockId":"MoveKind","ref":false},{"kind":"break"},{"kind":"label","text":"by ","style":[]},{"kind":"param","name":"offset","ref":false}],"parameters":[{"kind":"param","name":"kind","shadowBlockId":"MoveKind","ref":false},{"kind":"param","name":"offset","ref":false}]}},"parameters":[{"name":"kind","type":"LightMove","isEnum":true},{"name":"offset","description":"number of pixels to shift forward, eg: 1","initializer":"1","default":"1"}],"isInstance":true},"light.NeoPixelStrip.__photonForward":{"kind":-1,"attributes":{"paramDefl":{"steps":"1"},"blockId":"neophoton_fd","block":"photon forward by %steps","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"steps":"number of steps (lights) to move, eg: 1"},"jsDoc":"Move a photon effect along the pixel strip by a number of steps.","_def":{"parts":[{"kind":"label","text":"photon forward by ","style":[]},{"kind":"param","name":"steps","ref":false}],"parameters":[{"kind":"param","name":"steps","ref":false}]}},"parameters":[{"name":"steps","description":"number of steps (lights) to move, eg: 1","default":"1"}],"isInstance":true},"light.NeoPixelStrip.__photonFlip":{"kind":-1,"attributes":{"blockId":"neophoton_flip","block":"photon flip","deprecated":"1","defaultInstance":"light.pixels","jsDoc":"Switch the direction of the photon pulse.","_def":{"parts":[{"kind":"label","text":"photon flip","style":[]}],"parameters":[]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.__setPhotonColor":{"kind":-1,"attributes":{"blockId":"neophoton_set_color","block":"photon set pen color %color","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"color":"the color of the photon"},"jsDoc":"Set the photon color.","_def":{"parts":[{"kind":"label","text":"photon set pen color ","style":[]},{"kind":"param","name":"color","ref":false}],"parameters":[{"kind":"param","name":"color","ref":false}]}},"parameters":[{"name":"color","description":"the color of the photon"}],"isInstance":true},"light.NeoPixelStrip.__setPhotonMode":{"kind":-1,"attributes":{"blockId":"neophoton_set_photon","block":"photon %mode","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"mode":"the desired mode"},"jsDoc":"Set the photon mode to pen up, pen down, or eraser.","_def":{"parts":[{"kind":"label","text":"photon ","style":[]},{"kind":"param","name":"mode","ref":false}],"parameters":[{"kind":"param","name":"mode","ref":false}]}},"parameters":[{"name":"mode","description":"the desired mode","type":"PhotonMode","isEnum":true}],"isInstance":true},"light.NeoPixelStrip.__showAnimation":{"kind":-1,"attributes":{"paramDefl":{"duration":"500"},"blockId":"neopixel_show_animation","block":"show %animation=light_animation|animation for %duration=timePicker|ms","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"animation":"the animation to run","duration":"the duration to run in milliseconds, eg: 500"},"jsDoc":"Show an animation or queue an animation in the animation queue","_def":{"parts":[{"kind":"label","text":"show ","style":[]},{"kind":"param","name":"animation","shadowBlockId":"light_animation","ref":false},{"kind":"break"},{"kind":"label","text":"animation for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"animation","shadowBlockId":"light_animation","ref":false},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"animation","description":"the animation to run","type":"light.NeoPixelAnimation"},{"name":"duration","description":"the duration to run in milliseconds, eg: 500","default":"500"}],"isInstance":true},"light.NeoPixelStrip.__showAnimationFrame":{"kind":-1,"attributes":{"blockId":"neopixel_show_animation_frame","block":"show animation frame %animation=light_animation","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"animation":"the animation to run"},"jsDoc":"Show a single animation frame","_def":{"parts":[{"kind":"label","text":"show animation frame ","style":[]},{"kind":"param","name":"animation","shadowBlockId":"light_animation","ref":false}],"parameters":[{"kind":"param","name":"animation","shadowBlockId":"light_animation","ref":false}]}},"parameters":[{"name":"animation","description":"the animation to run","type":"light.NeoPixelAnimation"}],"isInstance":true},"light.NeoPixelStrip.__stopAllAnimations":{"kind":-1,"attributes":{"blockId":"neopixel_stop_all_animations","block":"stop all animations","deprecated":"1","defaultInstance":"light.pixels","jsDoc":"Stop the current animation and any other animations ready to show.","_def":{"parts":[{"kind":"label","text":"stop all animations","style":[]}],"parameters":[]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.__setBuffered":{"kind":-1,"attributes":{"blockId":"neopixel_set_buffered","block":"set buffered  %on","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"on":"call show whenever a light is modified"},"jsDoc":"Enables or disables automatically calling show when a change is made","_def":{"parts":[{"kind":"label","text":"set buffered  ","style":[]},{"kind":"param","name":"on","ref":false}],"parameters":[{"kind":"param","name":"on","ref":false}]}},"parameters":[{"name":"on","description":"call show whenever a light is modified","type":"boolean"}],"isInstance":true},"light.NeoPixelStrip.__setMode":{"kind":-1,"attributes":{"blockId":"neopixel_set_mode","block":"set mode %mode","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"mode":"the kind of color encoding required by the programmable lights"},"jsDoc":"Sets the color mode and clears the colors.","_def":{"parts":[{"kind":"label","text":"set mode ","style":[]},{"kind":"param","name":"mode","ref":false}],"parameters":[{"kind":"param","name":"mode","ref":false}]}},"parameters":[{"name":"mode","description":"the kind of color encoding required by the programmable lights","type":"NeoPixelMode","isEnum":true}],"isInstance":true},"light.createNeoPixelStrip":{"kind":-3,"retType":"light.NeoPixelStrip","attributes":{"blockId":"neopixel_create","block":"create WS2812 strip|pin %pin|with %numleds pixels","help":"light/create-neo-pixel-strip","trackArgs":[0,2],"parts":"neopixel","weight":100,"blockSetVariable":"strip","advanced":true,"blockHidden":true,"jsDoc":"Creates a strip of colored LEDs (WS2812b)","_def":{"parts":[{"kind":"label","text":"create WS2812 strip","style":[]},{"kind":"break"},{"kind":"label","text":"pin ","style":[]},{"kind":"param","name":"pin","ref":false},{"kind":"break"},{"kind":"label","text":"with ","style":[]},{"kind":"param","name":"numleds","ref":false},{"kind":"label","text":" pixels","style":[]}],"parameters":[{"kind":"param","name":"pin","ref":false},{"kind":"param","name":"numleds","ref":false}]}},"parameters":[{"name":"pin","type":"DigitalInOutPin"},{"name":"numleds","initializer":"10"},{"name":"mode","type":"NeoPixelMode","initializer":"undefined","isEnum":true}],"pyQName":"light.create_neo_pixel_strip"},"light.rgb":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"red":"255","green":"255","blue":"255"},"blockId":"neopixel_rgb","block":"red %red|green %green|blue %blue","paramMin":{"red":"0","green":"0","blue":"0"},"paramMax":{"red":"255","green":"255","blue":"255"},"help":"light/rgb","group":"Color","weight":19,"blockGap":"8","paramHelp":{"red":"value of the red channel between 0 and 255. eg: 255","green":"value of the green channel between 0 and 255. eg: 255","blue":"value of the blue channel between 0 and 255. eg: 255"},"jsDoc":"Converts red, green, blue channels into a RGB color","_def":{"parts":[{"kind":"label","text":"red ","style":[]},{"kind":"param","name":"red","ref":false},{"kind":"break"},{"kind":"label","text":"green ","style":[]},{"kind":"param","name":"green","ref":false},{"kind":"break"},{"kind":"label","text":"blue ","style":[]},{"kind":"param","name":"blue","ref":false}],"parameters":[{"kind":"param","name":"red","ref":false},{"kind":"param","name":"green","ref":false},{"kind":"param","name":"blue","ref":false}]}},"parameters":[{"name":"red","description":"value of the red channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"green","description":"value of the green channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"blue","description":"value of the blue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"light.colors":{"kind":-3,"retType":"number","attributes":{"blockId":"neopixel_colors","block":"%color","help":"light/colors","shim":"TD_ID","group":"Color","weight":20,"blockGap":"8","jsDoc":"Get the RGB value of a known color","_def":{"parts":[{"kind":"param","name":"color","ref":false}],"parameters":[{"kind":"param","name":"color","ref":false}]}},"parameters":[{"name":"color","type":"Colors","isEnum":true}]},"light.hsv":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"hue":"255","sat":"255","val":"255"},"blockId":"neopixel_hsv","block":"hue %hue|sat %sat|val %val","paramMin":{"hue":"0","sat":"0","val":"0"},"paramMax":{"hue":"255","sat":"255","val":"255"},"help":"light/hsv","group":"Color","weight":17,"paramHelp":{"hue":"value of the hue channel between 0 and 255. eg: 255","sat":"value of the saturation channel between 0 and 255. eg: 255","val":"value of the value channel between 0 and 255. eg: 255"},"jsDoc":"Convert an HSV (hue, saturation, value) color to RGB","_def":{"parts":[{"kind":"label","text":"hue ","style":[]},{"kind":"param","name":"hue","ref":false},{"kind":"break"},{"kind":"label","text":"sat ","style":[]},{"kind":"param","name":"sat","ref":false},{"kind":"break"},{"kind":"label","text":"val ","style":[]},{"kind":"param","name":"val","ref":false}],"parameters":[{"kind":"param","name":"hue","ref":false},{"kind":"param","name":"sat","ref":false},{"kind":"param","name":"val","ref":false}]}},"parameters":[{"name":"hue","description":"value of the hue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"sat","description":"value of the saturation channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"val","description":"value of the value channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"light.fade":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"brightness":"128"},"blockId":"neopixel_fade","block":"fade %color=neopixel_colors|by %brightness","paramMin":{"brightness":"0"},"paramMax":{"brightness":"255"},"help":"light/fade","group":"Color","weight":18,"blockGap":"8","blockHidden":true,"deprecated":"true","paramHelp":{"color":"color to fade","brightness":"the amount of brightness to apply to the color, eg: 128"},"jsDoc":"Use color.fade instead","_def":{"parts":[{"kind":"label","text":"fade ","style":[]},{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"break"},{"kind":"label","text":"by ","style":[]},{"kind":"param","name":"brightness","ref":false}],"parameters":[{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"param","name":"brightness","ref":false}]}},"parameters":[{"name":"c"},{"name":"brightness","description":"the amount of brightness to apply to the color, eg: 128","default":"128","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"light.NeoPixelAnimation":{"kind":8,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstances":"true","jsDoc":"An animation of a NeoPixel"},"extendsTypes":["light.NeoPixelAnimation"]},"light.NeoPixelAnimation.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"light.NeoPixelAnimation.createRenderer":{"kind":-1,"retType":"() => boolean","attributes":{"paramHelp":{"strip":"the strip to execute on"},"jsDoc":"Creates an animator instance"},"parameters":[{"name":"strip","description":"the strip to execute on","type":"light.NeoPixelStrip"}],"isInstance":true,"pyQName":"light.NeoPixelAnimation.create_renderer"},"light.RainbowCycleAnimation":{"kind":8,"retType":"light.RainbowCycleAnimation","extendsTypes":["light.RainbowCycleAnimation","light.NeoPixelAnimation"]},"light.RainbowCycleAnimation.delay":{"kind":2,"retType":"number","isInstance":true},"light.RainbowCycleAnimation.__constructor":{"kind":-3,"parameters":[{"name":"delay"}],"isInstance":true},"light.RainbowCycleAnimation.createRenderer":{"kind":-1,"retType":"() => boolean","parameters":[{"name":"strip","type":"light.NeoPixelStrip"}],"isInstance":true,"pyQName":"light.RainbowCycleAnimation.create_renderer"},"light.rainbowAnimation":{"kind":4,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstance":"true","block":"rainbow","whenUsed":true,"jres":"true","blockIdentity":"light._animationPicker","_def":{"parts":[{"kind":"label","text":"rainbow","style":[]}],"parameters":[]}},"pyQName":"light.rainbow_animation"},"light.RunningLightsAnimation":{"kind":8,"retType":"light.RunningLightsAnimation","extendsTypes":["light.RunningLightsAnimation","light.NeoPixelAnimation"]},"light.RunningLightsAnimation.red":{"kind":2,"retType":"number","isInstance":true},"light.RunningLightsAnimation.green":{"kind":2,"retType":"number","isInstance":true},"light.RunningLightsAnimation.blue":{"kind":2,"retType":"number","isInstance":true},"light.RunningLightsAnimation.delay":{"kind":2,"retType":"number","isInstance":true},"light.RunningLightsAnimation.__constructor":{"kind":-3,"parameters":[{"name":"red"},{"name":"green"},{"name":"blue"},{"name":"delay"}],"isInstance":true},"light.RunningLightsAnimation.createRenderer":{"kind":-1,"retType":"() => boolean","parameters":[{"name":"strip","type":"light.NeoPixelStrip"}],"isInstance":true,"pyQName":"light.RunningLightsAnimation.create_renderer"},"light.runningLightsAnimation":{"kind":4,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstance":"true","block":"running lights","jres":"true","blockIdentity":"light._animationPicker","whenUsed":true,"_def":{"parts":[{"kind":"label","text":"running lights","style":[]}],"parameters":[]}},"pyQName":"light.running_lights_animation"},"light.cometAnimation":{"kind":4,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstance":"true","block":"comet","jres":"true","blockIdentity":"light._animationPicker","whenUsed":true,"_def":{"parts":[{"kind":"label","text":"comet","style":[]}],"parameters":[]}},"pyQName":"light.comet_animation"},"light.SparkleAnimation":{"kind":8,"retType":"light.SparkleAnimation","extendsTypes":["light.SparkleAnimation","light.NeoPixelAnimation"]},"light.SparkleAnimation.rgb":{"kind":2,"retType":"number","isInstance":true},"light.SparkleAnimation.delay":{"kind":2,"retType":"number","isInstance":true},"light.SparkleAnimation.__constructor":{"kind":-3,"parameters":[{"name":"red"},{"name":"green"},{"name":"blue"},{"name":"delay"}],"isInstance":true},"light.SparkleAnimation.createRenderer":{"kind":-1,"retType":"() => boolean","parameters":[{"name":"strip","type":"light.NeoPixelStrip"}],"isInstance":true,"pyQName":"light.SparkleAnimation.create_renderer"},"light.sparkleAnimation":{"kind":4,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstance":"true","block":"sparkle","jres":"true","blockIdentity":"light._animationPicker","whenUsed":true,"_def":{"parts":[{"kind":"label","text":"sparkle","style":[]}],"parameters":[]}},"pyQName":"light.sparkle_animation"},"light.colorWipeAnimation":{"kind":4,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstance":"true","block":"color wipe","jres":"true","blockIdentity":"light._animationPicker","whenUsed":true,"_def":{"parts":[{"kind":"label","text":"color wipe","style":[]}],"parameters":[]}},"pyQName":"light.color_wipe_animation"},"light.theaterChaseAnimation":{"kind":4,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstance":"true","block":"theater chase","jres":"true","blockIdentity":"light._animationPicker","whenUsed":true,"_def":{"parts":[{"kind":"label","text":"theater chase","style":[]}],"parameters":[]}},"pyQName":"light.theater_chase_animation"},"light._animationPicker":{"kind":-3,"retType":"light.NeoPixelAnimation","attributes":{"blockId":"light_animation_picker","block":"%animation","shim":"TD_ID","paramFieldEditor":{"animation":"imagedropdown"},"paramFieldEditorOptions":{"animation":{"columns":"3"}},"weight":0,"group":"More","paramHelp":{"animation":"The animation type"},"jsDoc":"An animation that can be shown on a light strip","_def":{"parts":[{"kind":"param","name":"animation","ref":false}],"parameters":[{"kind":"param","name":"animation","ref":false}]}},"parameters":[{"name":"animation","description":"The animation type","type":"light.NeoPixelAnimation"}],"pyQName":"light._animation_picker"},"light.__lengthPicker":{"kind":-3,"retType":"number","attributes":{"blockId":"lightLengthPicker","block":"%pixels","blockHidden":true,"shim":"TD_ID","colorSecondary":"#FFFFFF","paramFieldEditor":{"pixels":"numberdropdown"},"paramFieldEditorOptions":{"pixels":{"decompileLiterals":"true","data":"[[\"7\", 7], [\"8\", 8], [\"12\", 12], [\"16\", 16], [\"24\", 24], [\"30\", 30], [\"60\", 60], [\"64\", 64], [\"90\", 90], [\"120\", 120], [\"144\", 144]]"}},"paramHelp":{"pixels":"number of LEDs"},"jsDoc":"Get the light length picker","_def":{"parts":[{"kind":"param","name":"pixels","ref":false}],"parameters":[{"kind":"param","name":"pixels","ref":false}]}},"parameters":[{"name":"pixels","description":"number of LEDs"}]},"easing":{"kind":5,"retType":""},"easing.linear":{"kind":-3,"retType":"number","parameters":[{"name":"t"}]},"easing.inQuad":{"kind":-3,"retType":"number","parameters":[{"name":"t"}],"pyQName":"easing.in_quad"},"easing.outQuad":{"kind":-3,"retType":"number","parameters":[{"name":"t"}],"pyQName":"easing.out_quad"},"easing.inOutQuad":{"kind":-3,"retType":"number","parameters":[{"name":"t"}],"pyQName":"easing.in_out_quad"},"easing.inCubic":{"kind":-3,"retType":"number","parameters":[{"name":"t"}],"pyQName":"easing.in_cubic"},"easing.outCubic":{"kind":-3,"retType":"number","parameters":[{"name":"t"}],"pyQName":"easing.out_cubic"},"easing.inOutCubic":{"kind":-3,"retType":"number","parameters":[{"name":"t"}],"pyQName":"easing.in_out_cubic"},"light.BrightnessTransition":{"kind":8,"retType":"light.BrightnessTransition","extendsTypes":["light.BrightnessTransition"]},"light.BrightnessTransition.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"light.BrightnessTransition.apply":{"kind":-1,"parameters":[{"name":"strip","type":"light.NeoPixelStrip"},{"name":"t"},{"name":"start"},{"name":"end"}],"isInstance":true},"light.EasingBrightnessTransition":{"kind":8,"retType":"light.EasingBrightnessTransition","extendsTypes":["light.EasingBrightnessTransition","light.BrightnessTransition"]},"light.EasingBrightnessTransition.__constructor":{"kind":-3,"parameters":[{"name":"timeEasing","type":"(t: number) => number","handlerParameters":[{"name":"t","type":"number"}]},{"name":"spatialEasing","type":"(t: number) => number","initializer":"undefined","handlerParameters":[{"name":"t","type":"number"}]}],"isInstance":true},"light.EasingBrightnessTransition.apply":{"kind":-1,"parameters":[{"name":"strip","type":"light.NeoPixelStrip"},{"name":"t"},{"name":"start"},{"name":"end"}],"isInstance":true},"light.BrightnessTransitionPlayer":{"kind":8,"retType":"light.BrightnessTransitionPlayer","extendsTypes":[]},"light.BrightnessTransitionPlayer.__constructor":{"kind":-3,"parameters":[{"name":"transition","type":"light.BrightnessTransition"},{"name":"startBrightness"},{"name":"endBrightness"},{"name":"duration"},{"name":"repeat"},{"name":"yoyo","type":"boolean"}],"isInstance":true},"light.BrightnessTransitionPlayer.update":{"kind":-1,"retType":"boolean","parameters":[{"name":"strip","type":"light.NeoPixelStrip"}],"isInstance":true},"light.createStrip":{"kind":-3,"retType":"light.NeoPixelStrip","attributes":{"paramDefl":{"numleds":"30","mode":"NeoPixelMode.RGB_GRB"},"blockId":"neopixel_create_strip","block":"create WS2812 strip on %pin with %numleds pixels","help":"light/create-strip","weight":100,"blockSetVariable":"strip","trackArgs":[0,2],"parts":"neopixel","advanced":true,"paramHelp":{"pin":"the pin where the strip is connected.","numleds":"number of leds in the strip, eg: 30","mode":"the light encoding mode for different LED strips, eg: NeoPixelMode.RGB_GRB"},"jsDoc":"Create a new programmable light strip.","_def":{"parts":[{"kind":"label","text":"create WS2812 strip on ","style":[]},{"kind":"param","name":"pin","ref":false},{"kind":"label","text":" with ","style":[]},{"kind":"param","name":"numleds","ref":false},{"kind":"label","text":" pixels","style":[]}],"parameters":[{"kind":"param","name":"pin","ref":false},{"kind":"param","name":"numleds","ref":false}]}},"parameters":[{"name":"pin","description":"the pin where the strip is connected.","type":"DigitalInOutPin","initializer":"null"},{"name":"numleds","description":"number of leds in the strip, eg: 30","initializer":"30","default":"30"},{"name":"mode","description":"the light encoding mode for different LED strips, eg: NeoPixelMode.RGB_GRB","type":"NeoPixelMode","initializer":"NeoPixelMode.RGB","default":"NeoPixelMode.RGB_GRB","isEnum":true}],"pyQName":"light.create_strip"},"light.createAPA102Strip":{"kind":-3,"retType":"light.NeoPixelStrip","attributes":{"blockId":"light_create_dotstar","block":"create APA102 strip|data %data|clock %clk|with %numleds pixels","help":"light/create-apa102-strip","trackArgs":[0,1,2],"parts":"dotstar","weight":100,"blockSetVariable":"strip","advanced":true,"jsDoc":"Creates a strip of colored LEDs (APA102)","_def":{"parts":[{"kind":"label","text":"create APA102 strip","style":[]},{"kind":"break"},{"kind":"label","text":"data ","style":[]},{"kind":"param","name":"data","ref":false},{"kind":"break"},{"kind":"label","text":"clock ","style":[]},{"kind":"param","name":"clk","ref":false},{"kind":"break"},{"kind":"label","text":"with ","style":[]},{"kind":"param","name":"numleds","ref":false},{"kind":"label","text":" pixels","style":[]}],"parameters":[{"kind":"param","name":"data","ref":false},{"kind":"param","name":"clk","ref":false},{"kind":"param","name":"numleds","ref":false}]}},"parameters":[{"name":"dataPin","type":"DigitalInOutPin"},{"name":"clkPin","type":"DigitalInOutPin"},{"name":"numleds"}],"pyQName":"light.create_apa102_strip"},"light.defaultStrip":{"kind":-3,"retType":"light.NeoPixelStrip","attributes":{"help":"light/default-strip","blockId":"neopixel_default_strip","block":"default strip","weight":110,"blockGap":"8","advanced":true,"parts":"pixels","jsDoc":"Gets the default light strip","_def":{"parts":[{"kind":"label","text":"default strip","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"light.default_strip"},"light.onboardStrip":{"kind":-3,"retType":"light.NeoPixelStrip","attributes":{"help":"light/onboard-strip","blockId":"neopixel_onboard_strip","block":"onboard strip","weight":111,"blockGap":"8","advanced":true,"jsDoc":"Get the onboard light strip.","_def":{"parts":[{"kind":"label","text":"onboard strip","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"light.onboard_strip"},"light.pixels":{"kind":4,"retType":"light.NeoPixelStrip","attributes":{"whenUsed":"true","jsDoc":"Gets the default external light strip"}},"light.setAll":{"kind":-3,"attributes":{"blockId":"builtin_neopixel_set_strip_color","block":"set all pixels to %rgb=colorNumberPicker","help":"light/set-all","weight":79,"blockGap":"8","paramHelp":{"rgb":"RGB color of the LED"},"jsDoc":"Set all of the pixels on the strip to one RGB color.","_def":{"parts":[{"kind":"label","text":"set all pixels to ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"rgb","description":"RGB color of the LED"}],"pyQName":"light.set_all"},"light.setGradient":{"kind":-3,"attributes":{"blockId":"builtinlightsetgradient","block":"set gradient from %startRgb=colorNumberPicker to %endRgb=colorNumberPicker","weight":78,"blockGap":"8","blockHidden":true,"paramHelp":{"startColor":"the start color","endColor":"the end color"},"jsDoc":"Sets a gradient between two colors","_def":{"parts":[{"kind":"label","text":"set gradient from ","style":[]},{"kind":"param","name":"startRgb","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"endRgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"startRgb","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"param","name":"endRgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"startRgb"},{"name":"endRgb"}],"pyQName":"light.set_gradient"},"light.clear":{"kind":-3,"attributes":{"blockId":"builtin_neopixel_clear","block":"clear","parts":"neopixel","help":"light/clear","group":"More","weight":9,"blockGap":"8","jsDoc":"Turn off all pixel LEDs on the onboard strip.","_def":{"parts":[{"kind":"label","text":"clear","style":[]}],"parameters":[]}},"parameters":[]},"light.graph":{"kind":-3,"attributes":{"blockId":"builtin_neopixel_show_bar_graph","block":"graph %value||up to %high","icon":"","help":"light/graph","blockGap":"8","weight":10,"paramHelp":{"value":"current value to plot","high":"maximum value, 0 to autoscale"},"jsDoc":"Display a vertical bar graph based on the `value` and `high` value.\nIf `high` is 0, the chart gets adjusted automatically.","_def":{"parts":[{"kind":"label","text":"graph ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":"up to ","style":[]},{"kind":"param","name":"high","ref":false}],"parameters":[{"kind":"param","name":"high","ref":false}]}},"parameters":[{"name":"value","description":"current value to plot"},{"name":"high","description":"maximum value, 0 to autoscale","initializer":"undefined"}]},"light.setPixelColor":{"kind":-3,"attributes":{"blockId":"builtin_neopixel_set_pixel_color","block":"set pixel color at %pixeloffset|to %rgb=colorNumberPicker","help":"light/set-pixel-color","group":"More","weight":89,"blockGap":"8","paramHelp":{"pixeloffset":"position of the NeoPixel in the strip","color":"RGB color of the LED"},"jsDoc":"Set the pixel to a given color.","_def":{"parts":[{"kind":"label","text":"set pixel color at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"pixeloffset","ref":false},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the NeoPixel in the strip"},{"name":"color","description":"RGB color of the LED"}],"pyQName":"light.set_pixel_color"},"light.pixelColor":{"kind":-3,"retType":"number","attributes":{"blockId":"builtin_neopixel_pixel_color","block":"pixel color at %pixeloffset","help":"light/pixel-color","group":"More","weight":88,"paramHelp":{"pixeloffset":"position of the NeoPixel in the strip"},"jsDoc":"Gets the pixel color at a given offset.","_def":{"parts":[{"kind":"label","text":"pixel color at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false}],"parameters":[{"kind":"param","name":"pixeloffset","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the NeoPixel in the strip"}],"pyQName":"light.pixel_color"},"light.setBrightness":{"kind":-3,"attributes":{"paramDefl":{"brightness":"20"},"blockId":"builtin_neopixel_set_brightness","block":"set brightness %brightness","paramMin":{"brightness":"0"},"paramMax":{"brightness":"255"},"help":"light/set-brightness","weight":2,"blockGap":"8","paramHelp":{"brightness":"a measure of LED brightness in 0-255. eg: 20"},"jsDoc":"Set the brightness of the strip. This flag only applies to future operation.","_def":{"parts":[{"kind":"label","text":"set brightness ","style":[]},{"kind":"param","name":"brightness","ref":false}],"parameters":[{"kind":"param","name":"brightness","ref":false}]}},"parameters":[{"name":"brightness","description":"a measure of LED brightness in 0-255. eg: 20","default":"20","options":{"min":{"value":"0"},"max":{"value":"255"}}}],"pyQName":"light.set_brightness"},"light.photonForward":{"kind":-3,"attributes":{"paramDefl":{"steps":"1"},"blockId":"builtin_neophoton_fd","block":"photon forward by %steps","help":"light/photon-forward","group":"Photon","weight":41,"blockGap":"8","paramHelp":{"steps":"number of steps (lights) to move, eg: 1"},"jsDoc":"Move a photon effect along the pixel strip by a number of steps.","_def":{"parts":[{"kind":"label","text":"photon forward by ","style":[]},{"kind":"param","name":"steps","ref":false}],"parameters":[{"kind":"param","name":"steps","ref":false}]}},"parameters":[{"name":"steps","description":"number of steps (lights) to move, eg: 1","default":"1"}],"pyQName":"light.photon_forward"},"light.photonFlip":{"kind":-3,"attributes":{"blockId":"builtin_neophoton_flip","block":"photon flip","help":"light/photon-flip","parts":"neopixel","group":"Photon","weight":40,"blockGap":"8","jsDoc":"Switch the direction of the photon pulse.","_def":{"parts":[{"kind":"label","text":"photon flip","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"light.photon_flip"},"light.setPhotonPosition":{"kind":-3,"attributes":{"blockId":"builtin_light_photon_set_position","block":"photon set position %index","help":"light/set-photon-position","parts":"neopixel","group":"Photon","weight":39,"blockGap":"8","paramHelp":{"index":"index of the light, if out of bound, the index is wrapped"},"jsDoc":"Sets the photon position to a given light index","_def":{"parts":[{"kind":"label","text":"photon set position ","style":[]},{"kind":"param","name":"index","ref":false}],"parameters":[{"kind":"param","name":"index","ref":false}]}},"parameters":[{"name":"index","description":"index of the light, if out of bound, the index is wrapped"}],"pyQName":"light.set_photon_position"},"light.setPhotonPenHue":{"kind":-3,"attributes":{"blockId":"builtin_neophoton_set_pen_hue","block":"photon set pen hue %hue=colorWheelHsvPicker","help":"light/set-photon-pen-hue","group":"Photon","weight":39,"blockGap":"8","paramHelp":{"hue":"the color hue of the photon"},"jsDoc":"Set the photon color hue.","_def":{"parts":[{"kind":"label","text":"photon set pen hue ","style":[]},{"kind":"param","name":"hue","shadowBlockId":"colorWheelHsvPicker","ref":false}],"parameters":[{"kind":"param","name":"hue","shadowBlockId":"colorWheelHsvPicker","ref":false}]}},"parameters":[{"name":"hue","description":"the color hue of the photon"}],"pyQName":"light.set_photon_pen_hue"},"light.setPhotonMode":{"kind":-3,"attributes":{"blockId":"builtin_neophoton_set_photon","block":"photon %mode","help":"light/set-photon-mode","group":"Photon","weight":38,"paramHelp":{"mode":"the desired mode"},"jsDoc":"Set the photon mode to pen up, pen down, or eraser.","_def":{"parts":[{"kind":"label","text":"photon ","style":[]},{"kind":"param","name":"mode","ref":false}],"parameters":[{"kind":"param","name":"mode","ref":false}]}},"parameters":[{"name":"mode","description":"the desired mode","type":"PhotonMode","isEnum":true}],"pyQName":"light.set_photon_mode"},"light.showAnimation":{"kind":-3,"attributes":{"paramDefl":{"animation":"light.rainbowAnimation","duration":"500"},"blockId":"builtin_neopixel_show_animation","block":"show animation %animation=light_animation_picker|for %duration=timePicker|ms","help":"light/show-animation","blockGap":"8","weight":81,"paramHelp":{"animation":"the animation to run, eg: light.rainbowAnimation","duration":"the duration to run in milliseconds, eg: 500"},"jsDoc":"Show an animation or queue an animation in the animation queue","_def":{"parts":[{"kind":"label","text":"show animation ","style":[]},{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"break"},{"kind":"label","text":"for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"animation","description":"the animation to run, eg: light.rainbowAnimation","type":"light.NeoPixelAnimation","default":"light.rainbowAnimation"},{"name":"duration","description":"the duration to run in milliseconds, eg: 500","default":"500"}],"pyQName":"light.show_animation"},"light.showAnimationFrame":{"kind":-3,"attributes":{"paramDefl":{"animation":"light.rainbowAnimation"},"blockId":"builtin_neopixel_show_animation_frame","block":"show frame of %animation=light_animation_picker|animation","help":"light/show-animation-frame","group":"More","weight":24,"blockGap":"8","paramHelp":{"animation":"the animation to run, eg: light.rainbowAnimation"},"jsDoc":"Show a single animation frame","_def":{"parts":[{"kind":"label","text":"show frame of ","style":[]},{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"break"},{"kind":"label","text":"animation","style":[]}],"parameters":[{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false}]}},"parameters":[{"name":"animation","description":"the animation to run, eg: light.rainbowAnimation","type":"light.NeoPixelAnimation","default":"light.rainbowAnimation"}],"pyQName":"light.show_animation_frame"},"light.stopAllAnimations":{"kind":-3,"attributes":{"blockId":"builtin_neopixel_stop_all_animations","block":"stop all animations","help":"light/stop-all-animations","group":"More","weight":23,"jsDoc":"Stop the current animation and any other animations ready to show.","_def":{"parts":[{"kind":"label","text":"stop all animations","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"light.stop_all_animations"},"light.animation":{"kind":-3,"retType":"light.NeoPixelAnimation","attributes":{"paramFieldEditor":{"kind":"imagedropdown"},"paramFieldEditorOptions":{"kind":{"columns":"3"}},"blockGap":"8","blockId":"light_animation","block":"%kind","group":"More","weight":25,"help":"light/animation","blockHidden":true,"deprecated":"1","paramHelp":{"kind":"the type of animation"},"jsDoc":"Creates a builtin animation","_def":{"parts":[{"kind":"param","name":"kind","ref":false}],"parameters":[{"kind":"param","name":"kind","ref":false}]}},"parameters":[{"name":"kind","description":"the type of animation","type":"LightAnimation","isEnum":true}]},"light.range":{"kind":-3,"retType":"light.NeoPixelStrip","attributes":{"paramDefl":{"length":"4"},"blockId":"lightstrip_range","block":"range from %start|with %length|pixels","weight":1,"paramHelp":{"start":"offset in the NeoPixel strip to start the range","length":"number of pixels in the range, eg: 4"},"jsDoc":"Create a range of pixels.","_def":{"parts":[{"kind":"label","text":"range from ","style":[]},{"kind":"param","name":"start","ref":false},{"kind":"break"},{"kind":"label","text":"with ","style":[]},{"kind":"param","name":"length","ref":false},{"kind":"break"},{"kind":"label","text":"pixels","style":[]}],"parameters":[{"kind":"param","name":"start","ref":false},{"kind":"param","name":"length","ref":false}]}},"parameters":[{"name":"start","description":"offset in the NeoPixel strip to start the range"},{"name":"length","description":"number of pixels in the range, eg: 4","default":"4"}]},"light.setLength":{"kind":-3,"attributes":{"paramDefl":{"numleds":"30"},"blockId":"lightds_setlength","block":"set pixels length to %numleds pixels","explicitDefaults":["numleds"],"_shadowOverrides":{"numleds":"lightLengthPicker"},"weight":0,"jsDoc":"Sets the number of LEDS on the default light strip","_def":{"parts":[{"kind":"label","text":"set pixels length to ","style":[]},{"kind":"param","name":"numleds","shadowBlockId":"lightLengthPicker","ref":false},{"kind":"label","text":" pixels","style":[]}],"parameters":[{"kind":"param","name":"numleds","shadowBlockId":"lightLengthPicker","ref":false}]}},"parameters":[{"name":"numleds","initializer":"30","default":"30"}],"pyQName":"light.set_length"},"light.setMode":{"kind":-3,"attributes":{"blockId":"lightds_setmode","block":"set default strip mode to %mode","weight":0,"jsDoc":"Sets the type of RGB light on the default strip","_def":{"parts":[{"kind":"label","text":"set default strip mode to ","style":[]},{"kind":"param","name":"mode","ref":false}],"parameters":[{"kind":"param","name":"mode","ref":false}]}},"parameters":[{"name":"mode","type":"NeoPixelMode","isEnum":true}],"pyQName":"light.set_mode"},"input.onLightConditionChanged":{"kind":-3,"attributes":{"help":"input/on-light-condition-changed","blockId":"input_on_light_condition_changed","block":"on light %condition","parts":"lightsensor","weight":84,"blockGap":"12","paramHelp":{"condition":"the condition that event triggers on"},"jsDoc":"Register an event that runs when light conditions (darker or brighter) change.","_def":{"parts":[{"kind":"label","text":"on light ","style":[]},{"kind":"param","name":"condition","ref":false}],"parameters":[{"kind":"param","name":"condition","ref":false}]}},"parameters":[{"name":"condition","description":"the condition that event triggers on","type":"LightCondition","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"input.on_light_condition_changed"},"input.lightLevel":{"kind":-3,"retType":"number","attributes":{"help":"input/light-level","blockId":"device_get_light_level","block":"light level","parts":"lightsensor","weight":30,"blockGap":"8","jsDoc":"Read the light level applied to the LED screen in a range from 0 (dark) to 255 (bright).","_def":{"parts":[{"kind":"label","text":"light level","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"input.light_level"},"input.setLightThreshold":{"kind":-3,"attributes":{"help":"input/set-light-threshold","blockId":"lightsensor_set_threshold","block":"set %condition| light threshold to %value","parts":"lightsensor","paramMin":{"value":"1"},"paramMax":{"value":"255"},"group":"More","weight":13,"blockGap":"8","jsDoc":"Set the threshold value for the light condition event.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"condition","ref":false},{"kind":"break"},{"kind":"label","text":" light threshold to ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"condition","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"condition","type":"LightCondition","isEnum":true},{"name":"value","options":{"min":{"value":"1"},"max":{"value":"255"}}}],"pyQName":"input.set_light_threshold"},"LightCondition":{"kind":6,"retType":"LightCondition","extendsTypes":["LightCondition","Number"]},"LightCondition.Dark":{"retType":"LightCondition.Dark","attributes":{"block":"dark","_def":{"parts":[{"kind":"label","text":"dark","style":[]}],"parameters":[]}},"extendsTypes":["LightCondition.Dark","Number"],"pyQName":"LightCondition.DARK"},"LightCondition.Bright":{"retType":"LightCondition.Bright","attributes":{"block":"bright","_def":{"parts":[{"kind":"label","text":"bright","style":[]}],"parameters":[]}},"extendsTypes":["LightCondition.Bright","Number"],"pyQName":"LightCondition.BRIGHT"},"encoders":{"kind":5,"retType":"","attributes":{"color":"#03AA74","weight":87,"icon":"","jsDoc":"Rotary and other encoders\n\nRotary encoders"}},"encoders.createRotaryEncoder":{"kind":-3,"retType":"RotaryEncoder","attributes":{"weight":99,"jsDoc":"Create a new rotary encoder connected to given pins"},"parameters":[{"name":"pinA","type":"DigitalInOutPin"},{"name":"pinB","type":"DigitalInOutPin"}],"pyQName":"encoders.create_rotary_encoder"},"RotaryEncoder":{"kind":9,"retType":"RotaryEncoder","attributes":{"noRefCounting":"true","fixedInstances":"true"},"extendsTypes":[]},"RotaryEncoder.onChanged":{"kind":-1,"attributes":{"blockNamespace":"encoders","blockId":"rotaryencoderonchaned","block":"on %this changed","weight":80,"blockGap":"8","jsDoc":"Do something when a rotary encoder changes position","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"this","ref":false},{"kind":"label","text":" changed","style":[]}],"parameters":[{"kind":"param","name":"this","ref":false}]}},"parameters":[{"name":"body","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"RotaryEncoder.on_changed"},"RotaryEncoder.position":{"kind":-1,"retType":"number","attributes":{"blockNamespace":"encoders","blockId":"rotaryencoderposition","block":"%this position","weight":79,"blockGap":"8","jsDoc":"Get current encoder position.","_def":{"parts":[{"kind":"param","name":"this","ref":false},{"kind":"label","text":" position","style":[]}],"parameters":[{"kind":"param","name":"this","ref":false}]}},"parameters":[],"isInstance":true},"encoders.defaultEncoder":{"kind":4,"retType":"RotaryEncoder","attributes":{"block":"encoder","fixedInstance":"true","whenUsed":"true","jsDoc":"Gets the default rotary encoder if any","_def":{"parts":[{"kind":"label","text":"encoder","style":[]}],"parameters":[]}},"pyQName":"encoders.default_encoder"},"input.onTemperatureConditionChanged":{"kind":-3,"attributes":{"paramDefl":{"temperature":"15"},"blockId":"input_on_temperature_condition_changed","block":"on temperature %condition|at %temperature|%unit","parts":"thermometer","help":"input/on-temperature-condition-changed","blockExternalInputs":"0","group":"More","weight":76,"inlineInputMode":"external","paramHelp":{"condition":"the condition, hot or cold, the event triggers on","temperature":"the temperature at which this event happens, eg: 15","unit":"the unit of the temperature"},"jsDoc":"Run some code when the temperature changes from hot to cold, or from cold to hot.","_def":{"parts":[{"kind":"label","text":"on temperature ","style":[]},{"kind":"param","name":"condition","ref":false},{"kind":"break"},{"kind":"label","text":"at ","style":[]},{"kind":"param","name":"temperature","ref":false},{"kind":"break"},{"kind":"param","name":"unit","ref":false}],"parameters":[{"kind":"param","name":"condition","ref":false},{"kind":"param","name":"temperature","ref":false},{"kind":"param","name":"unit","ref":false}]}},"parameters":[{"name":"condition","description":"the condition, hot or cold, the event triggers on","type":"TemperatureCondition","isEnum":true},{"name":"temperature","description":"the temperature at which this event happens, eg: 15","default":"15"},{"name":"unit","description":"the unit of the temperature","type":"TemperatureUnit","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"input.on_temperature_condition_changed"},"input.temperature":{"kind":-3,"retType":"number","attributes":{"help":"input/temperature","blockId":"device_temperature","block":"temperature in %unit","parts":"thermometer","weight":26,"jsDoc":"Get the temperature in Celsius or Fahrenheit degrees.","_def":{"parts":[{"kind":"label","text":"temperature in ","style":[]},{"kind":"param","name":"unit","ref":false}],"parameters":[{"kind":"param","name":"unit","ref":false}]}},"parameters":[{"name":"unit","type":"TemperatureUnit","isEnum":true}]},"TemperatureCondition":{"kind":6,"retType":"TemperatureCondition","extendsTypes":["TemperatureCondition","Number"]},"TemperatureCondition.Hot":{"retType":"TemperatureCondition.Hot","attributes":{"block":"hot","_def":{"parts":[{"kind":"label","text":"hot","style":[]}],"parameters":[]}},"extendsTypes":["TemperatureCondition.Hot","Number"],"pyQName":"TemperatureCondition.HOT"},"TemperatureCondition.Cold":{"retType":"TemperatureCondition.Cold","attributes":{"block":"cold","_def":{"parts":[{"kind":"label","text":"cold","style":[]}],"parameters":[]}},"extendsTypes":["TemperatureCondition.Cold","Number"],"pyQName":"TemperatureCondition.COLD"},"TemperatureUnit":{"kind":6,"retType":"TemperatureUnit","extendsTypes":["TemperatureUnit","Number"]},"TemperatureUnit.Celsius":{"retType":"TemperatureUnit.Celsius","attributes":{"block":"°C","_def":{"parts":[{"kind":"label","text":"°C","style":[]}],"parameters":[]}},"extendsTypes":["TemperatureUnit.Celsius","Number"],"pyQName":"TemperatureUnit.CELSIUS"},"TemperatureUnit.Fahrenheit":{"retType":"TemperatureUnit.Fahrenheit","attributes":{"block":"°F","_def":{"parts":[{"kind":"label","text":"°F","style":[]}],"parameters":[]}},"extendsTypes":["TemperatureUnit.Fahrenheit","Number"],"pyQName":"TemperatureUnit.FAHRENHEIT"},"controller.ControllerSceneState":{"kind":9,"retType":"controller.ControllerSceneState","extendsTypes":[]},"controller.ControllerSceneState.lastGesture":{"kind":2,"retType":"ControllerGesture","isInstance":true,"pyQName":"controller.ControllerSceneState.last_gesture"},"controller.ControllerSceneState.gestureHandlers":{"kind":2,"retType":"any","isInstance":true,"pyQName":"controller.ControllerSceneState.gesture_handlers"},"controller.ControllerSceneState.lastCustomGesture":{"kind":2,"retType":"number","isInstance":true,"pyQName":"controller.ControllerSceneState.last_custom_gesture"},"controller.ControllerSceneState.customGestureHandlers":{"kind":2,"retType":"any","isInstance":true,"pyQName":"controller.ControllerSceneState.custom_gesture_handlers"},"controller.ControllerSceneState.lastLightCondition":{"kind":2,"retType":"ControllerLightCondition","isInstance":true,"pyQName":"controller.ControllerSceneState.last_light_condition"},"controller.ControllerSceneState.lightHandlers":{"kind":2,"retType":"any","isInstance":true,"pyQName":"controller.ControllerSceneState.light_handlers"},"controller.CustomGestureHandler":{"kind":9,"retType":"controller.CustomGestureHandler","extendsTypes":[]},"controller.CustomGestureHandler.update":{"kind":2,"retType":"() => boolean","isInstance":true},"controller.CustomGestureHandler.handler":{"kind":2,"retType":"() => void","isInstance":true},"controller.sceneState":{"kind":-3,"retType":"controller.ControllerSceneState","parameters":[],"pyQName":"controller.scene_state"},"controller.vibrate":{"kind":-3,"attributes":{"blockId":"ctrlvibrate","block":"vibrate $millis ms","_shadowOverrides":{"millis":"timePicker"},"group":"Extras","paramHelp":{"millis":""},"jsDoc":"Vibrates the controller for the given duration (in milli seconds)","_def":{"parts":[{"kind":"label","text":"vibrate ","style":[]},{"kind":"param","name":"millis","shadowBlockId":"timePicker","ref":true},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"millis","shadowBlockId":"timePicker","ref":true}]}},"parameters":[{"name":"millis"}]},"ControllerGesture":{"kind":6,"retType":"ControllerGesture","extendsTypes":["ControllerGesture","Number"]},"ControllerGesture.Shake":{"retType":"ControllerGesture.Shake","attributes":{"block":"shake","jsDoc":"Shake gesture","_def":{"parts":[{"kind":"label","text":"shake","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.Shake","Number"],"pyQName":"ControllerGesture.SHAKE"},"ControllerGesture.TiltUp":{"retType":"ControllerGesture.TiltUp","attributes":{"block":"tilt up","jsDoc":"Raised when the device tilts up","_def":{"parts":[{"kind":"label","text":"tilt up","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltUp","Number"],"pyQName":"ControllerGesture.TILT_UP"},"ControllerGesture.TiltDown":{"retType":"ControllerGesture.TiltDown","attributes":{"block":"tilt down","jsDoc":"Raised when the device tilts down","_def":{"parts":[{"kind":"label","text":"tilt down","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltDown","Number"],"pyQName":"ControllerGesture.TILT_DOWN"},"ControllerGesture.TiltLeft":{"retType":"ControllerGesture.TiltLeft","attributes":{"block":"tilt left","jsDoc":"Raised when the screen is pointing left","_def":{"parts":[{"kind":"label","text":"tilt left","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltLeft","Number"],"pyQName":"ControllerGesture.TILT_LEFT"},"ControllerGesture.TiltRight":{"retType":"ControllerGesture.TiltRight","attributes":{"block":"tilt right","jsDoc":"Raised when the screen is pointing right","_def":{"parts":[{"kind":"label","text":"tilt right","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltRight","Number"],"pyQName":"ControllerGesture.TILT_RIGHT"},"ControllerGesture.ScreenUp":{"retType":"ControllerGesture.ScreenUp","attributes":{"block":"screen up","jsDoc":"Raised when the screen faces up","_def":{"parts":[{"kind":"label","text":"screen up","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.ScreenUp","Number"],"pyQName":"ControllerGesture.SCREEN_UP"},"ControllerGesture.ScreenDown":{"retType":"ControllerGesture.ScreenDown","attributes":{"block":"screen down","jsDoc":"Raised when the screen is pointing up and the board is horizontal","_def":{"parts":[{"kind":"label","text":"screen down","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.ScreenDown","Number"],"pyQName":"ControllerGesture.SCREEN_DOWN"},"ControllerGesture.TwoG":{"retType":"ControllerGesture.TwoG","attributes":{"block":"2g (step)","jsDoc":"Raised when a 2G shock is detected","_def":{"parts":[{"kind":"label","text":"2g (step)","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TwoG","Number"],"pyQName":"ControllerGesture.TWO_G"},"ControllerGesture.ThreeG":{"retType":"ControllerGesture.ThreeG","attributes":{"block":"3g","jsDoc":"Raised when a 3G shock is detected","_def":{"parts":[{"kind":"label","text":"3g","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.ThreeG","Number"],"pyQName":"ControllerGesture.THREE_G"},"ControllerGesture.SixG":{"retType":"ControllerGesture.SixG","attributes":{"block":"6g","jsDoc":"Raised when a 6G shock is detected","_def":{"parts":[{"kind":"label","text":"6g","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.SixG","Number"],"pyQName":"ControllerGesture.SIX_G"},"ControllerGesture.EightG":{"retType":"ControllerGesture.EightG","attributes":{"block":"8g","jsDoc":"Raised when a 8G shock is detected","_def":{"parts":[{"kind":"label","text":"8g","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.EightG","Number"],"pyQName":"ControllerGesture.EIGHT_G"},"ControllerDimension":{"kind":6,"retType":"ControllerDimension","extendsTypes":["ControllerDimension","Number"]},"ControllerDimension.X":{"retType":"ControllerDimension.X","attributes":{"block":"x","_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.X","Number"]},"ControllerDimension.Y":{"retType":"ControllerDimension.Y","attributes":{"block":"y","_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.Y","Number"]},"ControllerDimension.Z":{"retType":"ControllerDimension.Z","attributes":{"block":"z","_def":{"parts":[{"kind":"label","text":"z","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.Z","Number"]},"ControllerDimension.Strength":{"retType":"ControllerDimension.Strength","attributes":{"block":"strength","_def":{"parts":[{"kind":"label","text":"strength","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.Strength","Number"],"pyQName":"ControllerDimension.STRENGTH"},"controller.onGesture":{"kind":-3,"attributes":{"blockId":"ctrlongesture","block":"on |%NAME","parts":"accelerometer","paramFieldEditor":{"gesture":"gridpicker"},"paramFieldEditorOptions":{"gesture":{"width":"220","columns":"3"}},"group":"Extras","paramHelp":{"gesture":"the type of gesture to track","body":"code to run when gesture is raised"},"jsDoc":"Do something when a gesture happens (like shaking the board).","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"gesture","description":"the type of gesture to track","type":"ControllerGesture","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.on_gesture"},"controller.onCustomGesture":{"kind":-3,"attributes":{"paramHelp":{"id":"@param update","handler":""},"jsDoc":"Register a custom gesture for the controller"},"parameters":[{"name":"id","description":"@param update"},{"name":"update","type":"() => boolean","handlerParameters":[]},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.on_custom_gesture"},"controller.acceleration":{"kind":-3,"retType":"number","attributes":{"blockId":"ctrlaccelerationvalue","block":"acceleration (mg)|%NAME","parts":"accelerometer","paramFieldEditor":{"dimension":"gridpicker"},"paramFieldEditorOptions":{"dimension":{"width":"180","columns":"2"}},"group":"Extras","paramHelp":{"dimension":"the axis along which the acceleration if measured"},"jsDoc":"Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\nx=0, y=0 and z=-1023)","_def":{"parts":[{"kind":"label","text":"acceleration (mg)","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"dimension","description":"the axis along which the acceleration if measured","type":"ControllerDimension","isEnum":true}]},"ControllerLightCondition":{"kind":6,"retType":"ControllerLightCondition","extendsTypes":["ControllerLightCondition","Number"]},"ControllerLightCondition.Dark":{"retType":"ControllerLightCondition.Dark","attributes":{"block":"dark","_def":{"parts":[{"kind":"label","text":"dark","style":[]}],"parameters":[]}},"extendsTypes":["ControllerLightCondition.Dark","Number"],"pyQName":"ControllerLightCondition.DARK"},"ControllerLightCondition.Bright":{"retType":"ControllerLightCondition.Bright","attributes":{"block":"bright","_def":{"parts":[{"kind":"label","text":"bright","style":[]}],"parameters":[]}},"extendsTypes":["ControllerLightCondition.Bright","Number"],"pyQName":"ControllerLightCondition.BRIGHT"},"controller.lightLevel":{"kind":-3,"retType":"number","attributes":{"blockId":"ctrllightlevel","block":"light level","parts":"lightsensor","weight":30,"blockGap":"8","group":"Extras","jsDoc":"Read the light level applied to the LED screen in a range from 0 (dark) to 255 (bright).","_def":{"parts":[{"kind":"label","text":"light level","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"controller.light_level"},"controller.onLightConditionChanged":{"kind":-3,"attributes":{"blockId":"ctrlonlightcondition","block":"on light %condition","parts":"lightsensor","weight":84,"blockGap":"12","group":"Extras","paramHelp":{"condition":"the condition that event triggers on"},"jsDoc":"Register an event that runs when light conditions (darker or brighter) change.","_def":{"parts":[{"kind":"label","text":"on light ","style":[]},{"kind":"param","name":"condition","ref":false}],"parameters":[{"kind":"param","name":"condition","ref":false}]}},"parameters":[{"name":"condition","description":"the condition that event triggers on","type":"ControllerLightCondition","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.on_light_condition_changed"},"ControllerTemperatureUnit":{"kind":6,"retType":"ControllerTemperatureUnit","extendsTypes":["ControllerTemperatureUnit","Number"]},"ControllerTemperatureUnit.Celsius":{"retType":"ControllerTemperatureUnit.Celsius","attributes":{"block":"°C","_def":{"parts":[{"kind":"label","text":"°C","style":[]}],"parameters":[]}},"extendsTypes":["ControllerTemperatureUnit.Celsius","Number"],"pyQName":"ControllerTemperatureUnit.CELSIUS"},"ControllerTemperatureUnit.Fahrenheit":{"retType":"ControllerTemperatureUnit.Fahrenheit","attributes":{"block":"°F","_def":{"parts":[{"kind":"label","text":"°F","style":[]}],"parameters":[]}},"extendsTypes":["ControllerTemperatureUnit.Fahrenheit","Number"],"pyQName":"ControllerTemperatureUnit.FAHRENHEIT"},"controller.temperature":{"kind":-3,"retType":"number","attributes":{"blockId":"ctrltemperature","block":"temperature in %unit","parts":"thermometer","weight":26,"group":"Extras","jsDoc":"Get the temperature in Celsius or Fahrenheit degrees.","_def":{"parts":[{"kind":"label","text":"temperature in ","style":[]},{"kind":"param","name":"unit","ref":false}],"parameters":[{"kind":"param","name":"unit","ref":false}]}},"parameters":[{"name":"unit","type":"ControllerTemperatureUnit","isEnum":true}]},"controller.configureRepeatEventDefaults":{"kind":-3,"attributes":{"paramDefl":{"delay":"500","interval":"30"},"blockId":"repeatDefaultDelayInterval","block":"set button repeat delay $delay ms interval $interval ms","weight":10,"group":"Single Player","paramHelp":{"delay":"number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500","interval":"minimum number of milliseconds between calls to the button repeat event, eg: 30"},"jsDoc":"Configures the timing of the on button repeat event for all of the controller buttons","_def":{"parts":[{"kind":"label","text":"set button repeat delay ","style":[]},{"kind":"param","name":"delay","ref":true},{"kind":"label","text":" ms interval ","style":[]},{"kind":"param","name":"interval","ref":true},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"delay","ref":true},{"kind":"param","name":"interval","ref":true}]}},"parameters":[{"name":"delay","description":"number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500","default":"500"},{"name":"interval","description":"minimum number of milliseconds between calls to the button repeat event, eg: 30","default":"30"}],"pyQName":"controller.configure_repeat_event_defaults"},"controller.startLightPulse":{"kind":-3,"attributes":{"blockId":"ctrllightpulse","block":"start light pulse %rgb=colorNumberPicker|for %duration=timePicker|ms","weight":80,"blockGap":"8","group":"Extras","paramHelp":{"rgb":"RGB color of the LED"},"jsDoc":"Shows a color pulse","_def":{"parts":[{"kind":"label","text":"start light pulse ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"break"},{"kind":"label","text":"for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"rgb","description":"RGB color of the LED"},{"name":"duration"}],"pyQName":"controller.start_light_pulse"},"controller.crankPosition":{"kind":-3,"retType":"number","attributes":{"blockId":"controller_crank_position","block":"crank position","weight":29,"blockGap":"8","group":"Extras","jsDoc":"Gets the current position of the crank.","_def":{"parts":[{"kind":"label","text":"crank position","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"controller.crank_position"},"controller.__internal":{"kind":5,"retType":""},"controller.__internal.onGesture":{"kind":-3,"parameters":[{"name":"gesture","type":"ControllerGesture","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.__internal.on_gesture"},"controller.__internal.onCustomGesture":{"kind":-3,"parameters":[{"name":"id"},{"name":"update","type":"() => boolean","handlerParameters":[]},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.__internal.on_custom_gesture"},"controller.__internal.acceleration":{"kind":-3,"retType":"number","parameters":[{"name":"dimension","type":"ControllerDimension","isEnum":true}]},"controller.setCrankPins":{"kind":-3,"attributes":{"blockId":"controller_crank_setpins","block":"set crank pinA $pinA pin B $pinB","weight":28,"blockGap":"8","group":"Extras","paramHelp":{"pinA":"@param pinB "},"jsDoc":"Configures the pins used by the crank","_def":{"parts":[{"kind":"label","text":"set crank pinA ","style":[]},{"kind":"param","name":"pinA","ref":true},{"kind":"label","text":" pin B ","style":[]},{"kind":"param","name":"pinB","ref":true}],"parameters":[{"kind":"param","name":"pinA","ref":true},{"kind":"param","name":"pinB","ref":true}]}},"parameters":[{"name":"pinA","description":"@param pinB ","type":"DigitalInOutPin"},{"name":"pinB","type":"DigitalInOutPin"}],"pyQName":"controller.set_crank_pins"},"controller.__internal.crankPosition":{"kind":-3,"retType":"number","parameters":[],"pyQName":"controller.__internal.crank_position"},"controller.__internal.setCrankPins":{"kind":-3,"parameters":[{"name":"pinA","type":"DigitalInOutPin"},{"name":"pinB","type":"DigitalInOutPin"}],"pyQName":"controller.__internal.set_crank_pins"},"controller.startLightAnimation":{"kind":-3,"attributes":{"blockId":"controller_show_animation","block":"start light animation %animation=light_animation_picker|for %duration=timePicker|ms","weight":30,"blockGap":"8","group":"Extras","paramHelp":{"animation":"@param duration "},"jsDoc":"Shows an animation on the controller lights","_def":{"parts":[{"kind":"label","text":"start light animation ","style":[]},{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"break"},{"kind":"label","text":"for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"animation","description":"@param duration ","type":"light.NeoPixelAnimation"},{"name":"duration"}],"pyQName":"controller.start_light_animation"},"controller.__internal.startLightAnimation":{"kind":-3,"parameters":[{"name":"animation","type":"light.NeoPixelAnimation"},{"name":"duration"}],"pyQName":"controller.__internal.start_light_animation"},"controller.__internal.startLightPulse":{"kind":-3,"parameters":[{"name":"rgb"},{"name":"duration"}],"pyQName":"controller.__internal.start_light_pulse"},"controller.__internal.lightLevel":{"kind":-3,"retType":"number","parameters":[],"pyQName":"controller.__internal.light_level"},"controller.__internal.onLightConditionChanged":{"kind":-3,"parameters":[{"name":"condition","type":"ControllerLightCondition","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.__internal.on_light_condition_changed"},"controller.__internal.temperature":{"kind":-3,"retType":"number","parameters":[{"name":"unit","type":"ControllerTemperatureUnit","isEnum":true}]},"controller.__internal.vibrate":{"kind":-3,"parameters":[{"name":"millis"}]}}},"sha":"ca4008164496462fa4bfcf6bc0fcd6cc6aff568ee8da2b4f1433406fe21ed43a"},"libs/controller---none":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"light":{"kind":5,"retType":"","attributes":{"advanced":true}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"controller":{"kind":5,"retType":"","attributes":{"weight":98,"color":"#D54322","icon":"","groups":["Single Player","Multiplayer"],"blockGap":"8","jsDoc":"Access to game controls"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"controller.ControllerSceneState":{"kind":9,"retType":"controller.ControllerSceneState","extendsTypes":[]},"controller.ControllerSceneState.lastGesture":{"kind":2,"retType":"ControllerGesture","isInstance":true,"pyQName":"controller.ControllerSceneState.last_gesture"},"controller.ControllerSceneState.gestureHandlers":{"kind":2,"retType":"any","isInstance":true,"pyQName":"controller.ControllerSceneState.gesture_handlers"},"controller.ControllerSceneState.lastCustomGesture":{"kind":2,"retType":"number","isInstance":true,"pyQName":"controller.ControllerSceneState.last_custom_gesture"},"controller.ControllerSceneState.customGestureHandlers":{"kind":2,"retType":"any","isInstance":true,"pyQName":"controller.ControllerSceneState.custom_gesture_handlers"},"controller.ControllerSceneState.lastLightCondition":{"kind":2,"retType":"ControllerLightCondition","isInstance":true,"pyQName":"controller.ControllerSceneState.last_light_condition"},"controller.ControllerSceneState.lightHandlers":{"kind":2,"retType":"any","isInstance":true,"pyQName":"controller.ControllerSceneState.light_handlers"},"controller.CustomGestureHandler":{"kind":9,"retType":"controller.CustomGestureHandler","extendsTypes":[]},"controller.CustomGestureHandler.update":{"kind":2,"retType":"() => boolean","isInstance":true},"controller.CustomGestureHandler.handler":{"kind":2,"retType":"() => void","isInstance":true},"controller.sceneState":{"kind":-3,"retType":"controller.ControllerSceneState","parameters":[],"pyQName":"controller.scene_state"},"controller.vibrate":{"kind":-3,"attributes":{"blockId":"ctrlvibrate","block":"vibrate $millis ms","_shadowOverrides":{"millis":"timePicker"},"group":"Extras","paramHelp":{"millis":""},"jsDoc":"Vibrates the controller for the given duration (in milli seconds)","_def":{"parts":[{"kind":"label","text":"vibrate ","style":[]},{"kind":"param","name":"millis","shadowBlockId":"timePicker","ref":true},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"millis","shadowBlockId":"timePicker","ref":true}]}},"parameters":[{"name":"millis"}]},"ControllerGesture":{"kind":6,"retType":"ControllerGesture","extendsTypes":["ControllerGesture","Number"]},"ControllerGesture.Shake":{"retType":"ControllerGesture.Shake","attributes":{"block":"shake","jsDoc":"Shake gesture","_def":{"parts":[{"kind":"label","text":"shake","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.Shake","Number"],"pyQName":"ControllerGesture.SHAKE"},"ControllerGesture.TiltUp":{"retType":"ControllerGesture.TiltUp","attributes":{"block":"tilt up","jsDoc":"Raised when the device tilts up","_def":{"parts":[{"kind":"label","text":"tilt up","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltUp","Number"],"pyQName":"ControllerGesture.TILT_UP"},"ControllerGesture.TiltDown":{"retType":"ControllerGesture.TiltDown","attributes":{"block":"tilt down","jsDoc":"Raised when the device tilts down","_def":{"parts":[{"kind":"label","text":"tilt down","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltDown","Number"],"pyQName":"ControllerGesture.TILT_DOWN"},"ControllerGesture.TiltLeft":{"retType":"ControllerGesture.TiltLeft","attributes":{"block":"tilt left","jsDoc":"Raised when the screen is pointing left","_def":{"parts":[{"kind":"label","text":"tilt left","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltLeft","Number"],"pyQName":"ControllerGesture.TILT_LEFT"},"ControllerGesture.TiltRight":{"retType":"ControllerGesture.TiltRight","attributes":{"block":"tilt right","jsDoc":"Raised when the screen is pointing right","_def":{"parts":[{"kind":"label","text":"tilt right","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltRight","Number"],"pyQName":"ControllerGesture.TILT_RIGHT"},"ControllerGesture.ScreenUp":{"retType":"ControllerGesture.ScreenUp","attributes":{"block":"screen up","jsDoc":"Raised when the screen faces up","_def":{"parts":[{"kind":"label","text":"screen up","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.ScreenUp","Number"],"pyQName":"ControllerGesture.SCREEN_UP"},"ControllerGesture.ScreenDown":{"retType":"ControllerGesture.ScreenDown","attributes":{"block":"screen down","jsDoc":"Raised when the screen is pointing up and the board is horizontal","_def":{"parts":[{"kind":"label","text":"screen down","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.ScreenDown","Number"],"pyQName":"ControllerGesture.SCREEN_DOWN"},"ControllerGesture.TwoG":{"retType":"ControllerGesture.TwoG","attributes":{"block":"2g (step)","jsDoc":"Raised when a 2G shock is detected","_def":{"parts":[{"kind":"label","text":"2g (step)","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TwoG","Number"],"pyQName":"ControllerGesture.TWO_G"},"ControllerGesture.ThreeG":{"retType":"ControllerGesture.ThreeG","attributes":{"block":"3g","jsDoc":"Raised when a 3G shock is detected","_def":{"parts":[{"kind":"label","text":"3g","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.ThreeG","Number"],"pyQName":"ControllerGesture.THREE_G"},"ControllerGesture.SixG":{"retType":"ControllerGesture.SixG","attributes":{"block":"6g","jsDoc":"Raised when a 6G shock is detected","_def":{"parts":[{"kind":"label","text":"6g","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.SixG","Number"],"pyQName":"ControllerGesture.SIX_G"},"ControllerGesture.EightG":{"retType":"ControllerGesture.EightG","attributes":{"block":"8g","jsDoc":"Raised when a 8G shock is detected","_def":{"parts":[{"kind":"label","text":"8g","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.EightG","Number"],"pyQName":"ControllerGesture.EIGHT_G"},"ControllerDimension":{"kind":6,"retType":"ControllerDimension","extendsTypes":["ControllerDimension","Number"]},"ControllerDimension.X":{"retType":"ControllerDimension.X","attributes":{"block":"x","_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.X","Number"]},"ControllerDimension.Y":{"retType":"ControllerDimension.Y","attributes":{"block":"y","_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.Y","Number"]},"ControllerDimension.Z":{"retType":"ControllerDimension.Z","attributes":{"block":"z","_def":{"parts":[{"kind":"label","text":"z","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.Z","Number"]},"ControllerDimension.Strength":{"retType":"ControllerDimension.Strength","attributes":{"block":"strength","_def":{"parts":[{"kind":"label","text":"strength","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.Strength","Number"],"pyQName":"ControllerDimension.STRENGTH"},"controller.onGesture":{"kind":-3,"attributes":{"blockId":"ctrlongesture","block":"on |%NAME","parts":"accelerometer","paramFieldEditor":{"gesture":"gridpicker"},"paramFieldEditorOptions":{"gesture":{"width":"220","columns":"3"}},"group":"Extras","paramHelp":{"gesture":"the type of gesture to track","body":"code to run when gesture is raised"},"jsDoc":"Do something when a gesture happens (like shaking the board).","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"gesture","description":"the type of gesture to track","type":"ControllerGesture","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.on_gesture"},"controller.onCustomGesture":{"kind":-3,"attributes":{"paramHelp":{"id":"@param update","handler":""},"jsDoc":"Register a custom gesture for the controller"},"parameters":[{"name":"id","description":"@param update"},{"name":"update","type":"() => boolean","handlerParameters":[]},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.on_custom_gesture"},"controller.acceleration":{"kind":-3,"retType":"number","attributes":{"blockId":"ctrlaccelerationvalue","block":"acceleration (mg)|%NAME","parts":"accelerometer","paramFieldEditor":{"dimension":"gridpicker"},"paramFieldEditorOptions":{"dimension":{"width":"180","columns":"2"}},"group":"Extras","paramHelp":{"dimension":"the axis along which the acceleration if measured"},"jsDoc":"Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\nx=0, y=0 and z=-1023)","_def":{"parts":[{"kind":"label","text":"acceleration (mg)","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"dimension","description":"the axis along which the acceleration if measured","type":"ControllerDimension","isEnum":true}]},"ControllerLightCondition":{"kind":6,"retType":"ControllerLightCondition","extendsTypes":["ControllerLightCondition","Number"]},"ControllerLightCondition.Dark":{"retType":"ControllerLightCondition.Dark","attributes":{"block":"dark","_def":{"parts":[{"kind":"label","text":"dark","style":[]}],"parameters":[]}},"extendsTypes":["ControllerLightCondition.Dark","Number"],"pyQName":"ControllerLightCondition.DARK"},"ControllerLightCondition.Bright":{"retType":"ControllerLightCondition.Bright","attributes":{"block":"bright","_def":{"parts":[{"kind":"label","text":"bright","style":[]}],"parameters":[]}},"extendsTypes":["ControllerLightCondition.Bright","Number"],"pyQName":"ControllerLightCondition.BRIGHT"},"controller.lightLevel":{"kind":-3,"retType":"number","attributes":{"blockId":"ctrllightlevel","block":"light level","parts":"lightsensor","weight":30,"blockGap":"8","group":"Extras","jsDoc":"Read the light level applied to the LED screen in a range from 0 (dark) to 255 (bright).","_def":{"parts":[{"kind":"label","text":"light level","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"controller.light_level"},"controller.onLightConditionChanged":{"kind":-3,"attributes":{"blockId":"ctrlonlightcondition","block":"on light %condition","parts":"lightsensor","weight":84,"blockGap":"12","group":"Extras","paramHelp":{"condition":"the condition that event triggers on"},"jsDoc":"Register an event that runs when light conditions (darker or brighter) change.","_def":{"parts":[{"kind":"label","text":"on light ","style":[]},{"kind":"param","name":"condition","ref":false}],"parameters":[{"kind":"param","name":"condition","ref":false}]}},"parameters":[{"name":"condition","description":"the condition that event triggers on","type":"ControllerLightCondition","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.on_light_condition_changed"},"ControllerTemperatureUnit":{"kind":6,"retType":"ControllerTemperatureUnit","extendsTypes":["ControllerTemperatureUnit","Number"]},"ControllerTemperatureUnit.Celsius":{"retType":"ControllerTemperatureUnit.Celsius","attributes":{"block":"°C","_def":{"parts":[{"kind":"label","text":"°C","style":[]}],"parameters":[]}},"extendsTypes":["ControllerTemperatureUnit.Celsius","Number"],"pyQName":"ControllerTemperatureUnit.CELSIUS"},"ControllerTemperatureUnit.Fahrenheit":{"retType":"ControllerTemperatureUnit.Fahrenheit","attributes":{"block":"°F","_def":{"parts":[{"kind":"label","text":"°F","style":[]}],"parameters":[]}},"extendsTypes":["ControllerTemperatureUnit.Fahrenheit","Number"],"pyQName":"ControllerTemperatureUnit.FAHRENHEIT"},"controller.temperature":{"kind":-3,"retType":"number","attributes":{"blockId":"ctrltemperature","block":"temperature in %unit","parts":"thermometer","weight":26,"group":"Extras","jsDoc":"Get the temperature in Celsius or Fahrenheit degrees.","_def":{"parts":[{"kind":"label","text":"temperature in ","style":[]},{"kind":"param","name":"unit","ref":false}],"parameters":[{"kind":"param","name":"unit","ref":false}]}},"parameters":[{"name":"unit","type":"ControllerTemperatureUnit","isEnum":true}]},"controller.configureRepeatEventDefaults":{"kind":-3,"attributes":{"paramDefl":{"delay":"500","interval":"30"},"blockId":"repeatDefaultDelayInterval","block":"set button repeat delay $delay ms interval $interval ms","weight":10,"group":"Single Player","paramHelp":{"delay":"number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500","interval":"minimum number of milliseconds between calls to the button repeat event, eg: 30"},"jsDoc":"Configures the timing of the on button repeat event for all of the controller buttons","_def":{"parts":[{"kind":"label","text":"set button repeat delay ","style":[]},{"kind":"param","name":"delay","ref":true},{"kind":"label","text":" ms interval ","style":[]},{"kind":"param","name":"interval","ref":true},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"delay","ref":true},{"kind":"param","name":"interval","ref":true}]}},"parameters":[{"name":"delay","description":"number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500","default":"500"},{"name":"interval","description":"minimum number of milliseconds between calls to the button repeat event, eg: 30","default":"30"}],"pyQName":"controller.configure_repeat_event_defaults"},"controller.startLightPulse":{"kind":-3,"attributes":{"blockId":"ctrllightpulse","block":"start light pulse %rgb=colorNumberPicker|for %duration=timePicker|ms","weight":80,"blockGap":"8","group":"Extras","paramHelp":{"rgb":"RGB color of the LED"},"jsDoc":"Shows a color pulse","_def":{"parts":[{"kind":"label","text":"start light pulse ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"break"},{"kind":"label","text":"for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"rgb","description":"RGB color of the LED"},{"name":"duration"}],"pyQName":"controller.start_light_pulse"},"controller.crankPosition":{"kind":-3,"retType":"number","attributes":{"blockId":"controller_crank_position","block":"crank position","weight":29,"blockGap":"8","group":"Extras","jsDoc":"Gets the current position of the crank.","_def":{"parts":[{"kind":"label","text":"crank position","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"controller.crank_position"},"controller.__internal":{"kind":5,"retType":""},"controller.__internal.onGesture":{"kind":-3,"parameters":[{"name":"gesture","type":"ControllerGesture","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.__internal.on_gesture"},"controller.__internal.onCustomGesture":{"kind":-3,"parameters":[{"name":"id"},{"name":"update","type":"() => boolean","handlerParameters":[]},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.__internal.on_custom_gesture"},"controller.__internal.acceleration":{"kind":-3,"retType":"number","parameters":[{"name":"dimension","type":"ControllerDimension","isEnum":true}]},"controller.__internal.crankPosition":{"kind":-3,"retType":"number","parameters":[],"pyQName":"controller.__internal.crank_position"},"controller.__internal.startLightPulse":{"kind":-3,"parameters":[{"name":"rgb"},{"name":"duration"}],"pyQName":"controller.__internal.start_light_pulse"},"controller.__internal.lightLevel":{"kind":-3,"retType":"number","parameters":[],"pyQName":"controller.__internal.light_level"},"controller.__internal.onLightConditionChanged":{"kind":-3,"parameters":[{"name":"condition","type":"ControllerLightCondition","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.__internal.on_light_condition_changed"},"controller.__internal.temperature":{"kind":-3,"retType":"number","parameters":[{"name":"unit","type":"ControllerTemperatureUnit","isEnum":true}]},"controller.__internal.vibrate":{"kind":-3,"parameters":[{"name":"millis"}]}}},"sha":"37c48be3f462a317fc9b29fc2d17dbaf7af4c47353a5c9c29095ffd6419226bd"},"libs/core":{"apis":{"byQName":{}},"sha":"034ec557e45ec0eaf316f00f36d77b556ea6561e25a99c41538cc12c2fba0c3b"},"libs/core---linux":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":""},"basic":{"kind":5,"retType":""},"control.raiseEvent":{"kind":-3,"attributes":{"weight":21,"blockGap":"12","blockId":"control_raise_event","block":"raise event|from %src|with value %value","blockExternalInputs":"1","help":"control/raise-event","inlineInputMode":"external","paramHelp":{"src":"ID of the Component that generated the event","value":"Component specific code indicating the cause of the event.","mode":"optional definition of how the event should be processed after construction."},"jsDoc":"Announce that an event happened to registered handlers.","_def":{"parts":[{"kind":"label","text":"raise event","style":[]},{"kind":"break"},{"kind":"label","text":"from ","style":[]},{"kind":"param","name":"src","ref":false},{"kind":"break"},{"kind":"label","text":"with value ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"src","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"src","description":"ID of the Component that generated the event"},{"name":"value","description":"Component specific code indicating the cause of the event."}],"pyQName":"control.raise_event"},"control.dmesg":{"kind":-3,"attributes":{"jsDoc":"Write data to DMESG debugging buffer."},"parameters":[{"name":"s","type":"string"}]},"serial":{"kind":5,"retType":""},"serial.writeDmesg":{"kind":-3,"attributes":{"jsDoc":"Send DMESG debug buffer over serial."},"parameters":[],"pyQName":"serial.write_dmesg"}}},"sha":"e93330f47ff334ba6ca2c5ac3b0d7f93393384a3a31c6ca5ba7ee9eab2295ff3"},"libs/core---nrf52":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""}}},"sha":"cda8fdd1845078914ba45e4bacfa0ba6e537ca1d2c222888ede86d1f50df558e"},"libs/core---samd":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""}}},"sha":"034ec557e45ec0eaf316f00f36d77b556ea6561e25a99c41538cc12c2fba0c3b"},"libs/core---stm32":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""}}},"sha":"779c77a9b1b7849b97598fe56cb9fc07f9e28c4d1d8558128c01c380de1c5b09"},"libs/core---rp2040":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""}}},"sha":"c6f74f4e4269e0c4bcf3fb5d8eff621dc9b291793c3b7d82adbe65b2ef3e655c"},"libs/core---vm":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":""},"basic":{"kind":5,"retType":""},"control.raiseEvent":{"kind":-3,"attributes":{"weight":21,"blockGap":"12","blockId":"control_raise_event","block":"raise event|from %src|with value %value","blockExternalInputs":"1","help":"control/raise-event","inlineInputMode":"external","paramHelp":{"src":"ID of the Component that generated the event","value":"Component specific code indicating the cause of the event.","mode":"optional definition of how the event should be processed after construction."},"jsDoc":"Announce that an event happened to registered handlers.","_def":{"parts":[{"kind":"label","text":"raise event","style":[]},{"kind":"break"},{"kind":"label","text":"from ","style":[]},{"kind":"param","name":"src","ref":false},{"kind":"break"},{"kind":"label","text":"with value ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"src","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"src","description":"ID of the Component that generated the event"},{"name":"value","description":"Component specific code indicating the cause of the event."}],"pyQName":"control.raise_event"},"control.dmesg":{"kind":-3,"attributes":{"jsDoc":"Write data to DMESG debugging buffer."},"parameters":[{"name":"s","type":"string"}]},"serial":{"kind":5,"retType":""},"serial.writeDmesg":{"kind":-3,"attributes":{"jsDoc":"Send DMESG debug buffer over serial."},"parameters":[],"pyQName":"serial.write_dmesg"}}},"sha":"3cca4ec1766e274a60a4d63164b79d382da90e6a754e835aaa7e32e960ac3a1c"},"libs/corgio":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"corgio":{"kind":5,"retType":"","attributes":{"weight":100,"color":"#d2b48c","icon":"","groups":["Create","Movement","Speak","Properties"],"jsDoc":"Sprite Wrapper for a Corgi Platformer"}},"corgio.CorgiFlags":{"kind":6,"retType":"corgio.CorgiFlags","extendsTypes":["corgio.CorgiFlags","Number"]},"corgio.CorgiFlags.None":{"retType":"corgio.CorgiFlags","extendsTypes":["corgio.CorgiFlags.None","Number"],"pyQName":"corgio.CorgiFlags.NONE"},"corgio.CorgiFlags.HorizontalMovement":{"retType":"corgio.CorgiFlags","extendsTypes":["corgio.CorgiFlags.HorizontalMovement","Number"],"pyQName":"corgio.CorgiFlags.HORIZONTAL_MOVEMENT"},"corgio.CorgiFlags.VerticalMovement":{"retType":"corgio.CorgiFlags","extendsTypes":["corgio.CorgiFlags.VerticalMovement","Number"],"pyQName":"corgio.CorgiFlags.VERTICAL_MOVEMENT"},"corgio.CorgiFlags.UpdateSprite":{"retType":"corgio.CorgiFlags","extendsTypes":["corgio.CorgiFlags.UpdateSprite","Number"],"pyQName":"corgio.CorgiFlags.UPDATE_SPRITE"},"corgio.CorgiFlags.CameraFollow":{"retType":"corgio.CorgiFlags","extendsTypes":["corgio.CorgiFlags.CameraFollow","Number"],"pyQName":"corgio.CorgiFlags.CAMERA_FOLLOW"},"corgio.CorgiFlags.All":{"retType":"corgio.CorgiFlags","extendsTypes":["corgio.CorgiFlags.All","Number"],"pyQName":"corgio.CorgiFlags.ALL"},"corgio._corgi_still":{"kind":4,"retType":"Image[]"},"corgio._corgi_left":{"kind":4,"retType":"Image[]"},"corgio._corgi_right":{"kind":4,"retType":"Image[]"},"corgio.create":{"kind":-3,"retType":"Corgio","attributes":{"paramDefl":{"x":"10","y":"70"},"blockId":"corgiCreate","block":"corgi of kind %kind=spritekind || at x %x y %y","expandableArgumentMode":"toggle","inlineInputMode":"inline","blockSetVariable":"myCorg","weight":100,"group":"Create","help":"corgio/create","paramHelp":{"kind":"the kind to make the corgi","x":"optional initial x position, eg: 10","y":"optional initial y position, eg: 70"},"jsDoc":"Creates a new corgi from an image and kind","_def":{"parts":[{"kind":"label","text":"corgi of kind ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false},{"kind":"label","text":" ","style":[]}],"parameters":[{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":" at x ","style":[]},{"kind":"param","name":"x","ref":false},{"kind":"label","text":" y ","style":[]},{"kind":"param","name":"y","ref":false}],"parameters":[{"kind":"param","name":"x","ref":false},{"kind":"param","name":"y","ref":false}]}},"parameters":[{"name":"kind","description":"the kind to make the corgi"},{"name":"x","description":"optional initial x position, eg: 10","initializer":"10","default":"10"},{"name":"y","description":"optional initial y position, eg: 70","initializer":"70","default":"70"}]},"corgio.roundTowardsZero":{"kind":-3,"retType":"number","parameters":[{"name":"input"}],"pyQName":"corgio.round_towards_zero"},"corgio.normalize":{"kind":-3,"retType":"number","parameters":[{"name":"input"}]},"corgio.reflect":{"kind":-3,"retType":"Image[]","parameters":[{"name":"input","type":"Image[]"}]},"Corgio":{"kind":8,"retType":"Corgio","attributes":{"blockNamespace":"corgio","color":"#d2b48c","blockGap":"8","jsDoc":"A Corgi Platformer"},"extendsTypes":["Corgio","sprites.ExtendableSprite","Sprite","sprites.BaseSprite","SpriteLike"]},"Corgio.maxMoveVelocity":{"kind":2,"retType":"number","attributes":{"group":"Properties","blockSetVariable":"myCorg","blockCombine":true,"block":"horizontal speed","_def":{"parts":[{"kind":"label","text":"horizontal speed","style":[]}],"parameters":[]}},"isInstance":true,"pyQName":"Corgio.max_move_velocity"},"Corgio.gravity":{"kind":2,"retType":"number","attributes":{"group":"Properties","blockSetVariable":"myCorg","blockCombine":true,"block":"gravity","_def":{"parts":[{"kind":"label","text":"gravity","style":[]}],"parameters":[]}},"isInstance":true},"Corgio.jumpVelocity":{"kind":2,"retType":"number","attributes":{"group":"Properties","blockSetVariable":"myCorg","blockCombine":true,"block":"jump speed","_def":{"parts":[{"kind":"label","text":"jump speed","style":[]}],"parameters":[]}},"isInstance":true,"pyQName":"Corgio.jump_velocity"},"Corgio.maxJump":{"kind":2,"retType":"number","attributes":{"group":"Properties","blockSetVariable":"myCorg","blockCombine":true,"block":"max jumps in a row","_def":{"parts":[{"kind":"label","text":"max jumps in a row","style":[]}],"parameters":[]}},"isInstance":true,"pyQName":"Corgio.max_jump"},"Corgio.decelerationRate":{"kind":2,"retType":"number","attributes":{"group":"Properties","blockSetVariable":"myCorg","blockCombine":true,"block":"rate horizontal movement is slowed","_def":{"parts":[{"kind":"label","text":"rate horizontal movement is slowed","style":[]}],"parameters":[]}},"isInstance":true,"pyQName":"Corgio.deceleration_rate"},"Corgio.__constructor":{"kind":-3,"parameters":[{"name":"kind"},{"name":"x"},{"name":"y"}],"isInstance":true},"Corgio.sprite":{"kind":-2,"retType":"Sprite","attributes":{"group":"Properties","blockId":"corgSprite","block":"%corgio(myCorg) sprite","weight":8,"deprecated":"true","jsDoc":"Get the Corgio's sprite","_def":{"parts":[{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"},{"kind":"label","text":" sprite","style":[]}],"parameters":[{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"}]}},"isInstance":true,"isReadOnly":true},"Corgio.horizontalMovement":{"kind":-1,"attributes":{"group":"Movement","blockId":"horizontalMovement","block":"make %corgio(myCorg) move left and right with arrow keys || %on=toggleOnOff","weight":100,"blockGap":"5","help":"corgio/horizontal-movement","jsDoc":"Make the character move in the direction indicated by the left and right arrow keys.","_def":{"parts":[{"kind":"label","text":"make ","style":[]},{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"},{"kind":"label","text":" move left and right with arrow keys ","style":[]}],"parameters":[{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"}]},"_expandedDef":{"parts":[{"kind":"label","text":" ","style":[]},{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}],"parameters":[{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}]}},"parameters":[{"name":"on","type":"boolean","initializer":"true"}],"isInstance":true,"pyQName":"Corgio.horizontal_movement"},"Corgio.verticalMovement":{"kind":-1,"attributes":{"group":"Movement","blockId":"verticalMovement","block":"make %corgio(myCorg) jump if up arrow key is pressed || %on=toggleOnOff","weight":100,"blockGap":"5","help":"corgio/vertical-movement","jsDoc":"Make the character jump when the up arrow key is pressed, and grab onto the wall when falling.","_def":{"parts":[{"kind":"label","text":"make ","style":[]},{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"},{"kind":"label","text":" jump if up arrow key is pressed ","style":[]}],"parameters":[{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"}]},"_expandedDef":{"parts":[{"kind":"label","text":" ","style":[]},{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}],"parameters":[{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}]}},"parameters":[{"name":"on","type":"boolean","initializer":"true"}],"isInstance":true,"pyQName":"Corgio.vertical_movement"},"Corgio.cameraFollow":{"kind":-1,"attributes":{"group":"Movement","blockId":"followCorgi","block":"make camera follow %corgio(myCorg) left and right || %on=toggleOnOff","weight":90,"blockGap":"5","help":"corgio/camera-follow","jsDoc":"Set camera to follow corgio horizontally, while keeping the screen centered vertically.","_def":{"parts":[{"kind":"label","text":"make camera follow ","style":[]},{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"},{"kind":"label","text":" left and right ","style":[]}],"parameters":[{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"}]},"_expandedDef":{"parts":[{"kind":"label","text":" ","style":[]},{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}],"parameters":[{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}]}},"parameters":[{"name":"on","type":"boolean","initializer":"true"}],"isInstance":true,"pyQName":"Corgio.camera_follow"},"Corgio.updateSprite":{"kind":-1,"attributes":{"group":"Movement","blockId":"updateSprite","block":"change image when %corgio(myCorg) is moving || %on=toggleOnOff","weight":100,"blockGap":"5","help":"corgio/update-sprite","jsDoc":"Make the character change sprite images when moving.","_def":{"parts":[{"kind":"label","text":"change image when ","style":[]},{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"},{"kind":"label","text":" is moving ","style":[]}],"parameters":[{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"}]},"_expandedDef":{"parts":[{"kind":"label","text":" ","style":[]},{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}],"parameters":[{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}]}},"parameters":[{"name":"on","type":"boolean","initializer":"true"}],"isInstance":true,"pyQName":"Corgio.update_sprite"},"Corgio.addToScript":{"kind":-1,"attributes":{"paramDefl":{"input":"bark"},"group":"Speak","blockId":"addScript","block":"teach %corgio(myCorg) the word %input","weight":95,"blockGap":"5","help":"corgio/add-to-script","paramHelp":{"input":"phrase to add to script, eg: \"bark\""},"jsDoc":"Add new phrase for the character to bark","_def":{"parts":[{"kind":"label","text":"teach ","style":[]},{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"},{"kind":"label","text":" the word ","style":[]},{"kind":"param","name":"input","ref":false}],"parameters":[{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"},{"kind":"param","name":"input","ref":false}]}},"parameters":[{"name":"input","description":"phrase to add to script, eg: \"bark\"","type":"string","default":"bark"}],"isInstance":true,"pyQName":"Corgio.add_to_script"},"Corgio.bark":{"kind":-1,"attributes":{"group":"Speak","blockId":"bark","block":"make %corgio(myCorg) bark!","weight":95,"blockGap":"5","help":"corgio/bark","jsDoc":"Have the character say one of the phrases in the script at random","_def":{"parts":[{"kind":"label","text":"make ","style":[]},{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"},{"kind":"label","text":" bark!","style":[]}],"parameters":[{"kind":"param","name":"corgio","ref":false,"varName":"myCorg"}]}},"parameters":[],"isInstance":true}}},"sha":"5cff98a2e17064e091ee589e20da46252aeb43926d11acf3376a0b1ac6bd3e73"},"libs/d5prj":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":"","attributes":{"jsDoc":"These shims are for enabling system keyboard support in text/number prompts."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"texteffects":{"kind":5,"retType":""},"delay":{"kind":4,"retType":"number"},"screen":{"kind":4,"retType":"ScreenImage","attributes":{"whenUsed":"true"}},"_screen_internal.createScreen":{"kind":-3,"retType":"ScreenImage","parameters":[],"pyQName":"_screen_internal.create_screen"}}},"sha":"a80cc39379283e268650cc0a62976190569bd78ae9722cfc04543cc7ffcee63b"},"libs/darts":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"darts":{"kind":5,"retType":"","attributes":{"weight":100,"color":"#6699CC","icon":"","groups":["Create","Actions","Properties"],"jsDoc":"A dart with path prediction"}},"darts.create":{"kind":-3,"retType":"Dart","attributes":{"paramDefl":{"x":"10","y":"110"},"blockId":"dartsCreate","block":"dart %img=screen_image_picker of kind %kind=spritekind || at x %x y %y","expandableArgumentMode":"toggle","inlineInputMode":"inline","blockSetVariable":"myDart","weight":100,"group":"Create","help":"darts/create","paramHelp":{"img":"the image for the sprite","kind":"the kind to make the dart","x":"optional initial x position, eg: 10","y":"optional initial y position, eg: 110"},"jsDoc":"Creates a new dart from an image and kind","_def":{"parts":[{"kind":"label","text":"dart ","style":[]},{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false},{"kind":"label","text":" of kind ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false},{"kind":"label","text":" ","style":[]}],"parameters":[{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":" at x ","style":[]},{"kind":"param","name":"x","ref":false},{"kind":"label","text":" y ","style":[]},{"kind":"param","name":"y","ref":false}],"parameters":[{"kind":"param","name":"x","ref":false},{"kind":"param","name":"y","ref":false}]}},"parameters":[{"name":"img","description":"the image for the sprite","type":"Image"},{"name":"kind","description":"the kind to make the dart"},{"name":"x","description":"optional initial x position, eg: 10","initializer":"10","default":"10"},{"name":"y","description":"optional initial y position, eg: 110","initializer":"110","default":"110"}]},"darts.degreeToRadian":{"kind":-3,"retType":"number","attributes":{"paramHelp":{"degree":"to convert"},"jsDoc":"Convert degrees to radians\n\n@return converted value in radians"},"parameters":[{"name":"degree","description":"to convert"}],"pyQName":"darts.degree_to_radian"},"darts.xComponent":{"kind":-3,"retType":"number","attributes":{"paramHelp":{"degree":"angle of vector","magnitude":"magnitude of vector"},"jsDoc":"Evaluate the x component of a given vector\n\n\n@return x component of vector"},"parameters":[{"name":"degree","description":"angle of vector"},{"name":"magnitude","description":"magnitude of vector"}],"pyQName":"darts.x_component"},"darts.yComponent":{"kind":-3,"retType":"number","attributes":{"paramHelp":{"degree":"angle of vector","magnitude":"magnitude of vector"},"jsDoc":"Evaluate the y component of a given vector\n\n\n@return y component of vector"},"parameters":[{"name":"degree","description":"angle of vector"},{"name":"magnitude","description":"magnitude of vector"}],"pyQName":"darts.y_component"},"Dart":{"kind":8,"retType":"Dart","attributes":{"blockNamespace":"darts","color":"#6699CC","blockGap":"8","jsDoc":"A dart"},"extendsTypes":["Dart","sprites.ExtendableSprite","Sprite","sprites.BaseSprite","SpriteLike"]},"Dart.angle":{"kind":2,"retType":"number","attributes":{"group":"Properties","blockSetVariable":"myDart","blockCombine":true,"block":"angle","weight":8,"_def":{"parts":[{"kind":"label","text":"angle","style":[]}],"parameters":[]}},"isInstance":true},"Dart.pow":{"kind":2,"retType":"number","attributes":{"group":"Properties","blockSetVariable":"myDart","blockCombine":true,"block":"power","weight":8,"_def":{"parts":[{"kind":"label","text":"power","style":[]}],"parameters":[]}},"isInstance":true},"Dart.iter":{"kind":2,"retType":"number","attributes":{"group":"Properties","blockSetVariable":"myDart","blockCombine":true,"block":"tracing time (seconds)","weight":8,"_def":{"parts":[{"kind":"label","text":"tracing time (seconds)","style":[]}],"parameters":[]}},"isInstance":true},"Dart.traceColor":{"kind":2,"retType":"number","attributes":{"group":"Properties","blockSetVariable":"myDart","blockCombine":true,"block":"trace color","weight":8,"_def":{"parts":[{"kind":"label","text":"trace color","style":[]}],"parameters":[]}},"isInstance":true,"pyQName":"Dart.trace_color"},"Dart.gravity":{"kind":2,"retType":"number","attributes":{"group":"Properties","blockSetVariable":"myDart","blockCombine":true,"block":"gravity","weight":8,"_def":{"parts":[{"kind":"label","text":"gravity","style":[]}],"parameters":[]}},"isInstance":true},"Dart.wind":{"kind":2,"retType":"number","attributes":{"group":"Properties","blockSetVariable":"myDart","blockCombine":true,"block":"wind","weight":8,"_def":{"parts":[{"kind":"label","text":"wind","style":[]}],"parameters":[]}},"isInstance":true},"Dart.angleRate":{"kind":2,"retType":"number","attributes":{"group":"Properties","blockSetVariable":"myDart","blockCombine":true,"block":"angle adjust rate","weight":8,"_def":{"parts":[{"kind":"label","text":"angle adjust rate","style":[]}],"parameters":[]}},"isInstance":true,"pyQName":"Dart.angle_rate"},"Dart.powerRate":{"kind":2,"retType":"number","attributes":{"group":"Properties","blockSetVariable":"myDart","blockCombine":true,"block":"power adjust rate","weight":8,"_def":{"parts":[{"kind":"label","text":"power adjust rate","style":[]}],"parameters":[]}},"isInstance":true,"pyQName":"Dart.power_rate"},"Dart.__constructor":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"kind"},{"name":"x"},{"name":"y"}],"isInstance":true},"Dart.sprite":{"kind":-2,"retType":"Sprite","attributes":{"group":"Properties","blockId":"dartSprite","block":"%dart(myDart) sprite","weight":8,"deprecated":"true","jsDoc":"NO LONGER NECESSARY -- the dart is now a sprite by itself.\nGets the dart's sprite.","_def":{"parts":[{"kind":"param","name":"dart","ref":false,"varName":"myDart"},{"kind":"label","text":" sprite","style":[]}],"parameters":[{"kind":"param","name":"dart","ref":false,"varName":"myDart"}]}},"isInstance":true,"isReadOnly":true},"Dart.setTrace":{"kind":-1,"attributes":{"paramDefl":{"on":"true"},"blockId":"setTrace","block":"trace %dart(myDart) path estimate || %on=toggleOnOff","weight":50,"group":"Actions","help":"darts/set-trace","paramHelp":{"on":"whether to turn on or off this feature, eg: true"},"jsDoc":"Set whether to show the trace for the estimated path","_def":{"parts":[{"kind":"label","text":"trace ","style":[]},{"kind":"param","name":"dart","ref":false,"varName":"myDart"},{"kind":"label","text":" path estimate ","style":[]}],"parameters":[{"kind":"param","name":"dart","ref":false,"varName":"myDart"}]},"_expandedDef":{"parts":[{"kind":"label","text":" ","style":[]},{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}],"parameters":[{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}]}},"parameters":[{"name":"on","description":"whether to turn on or off this feature, eg: true","type":"boolean","initializer":"true","default":"true"}],"isInstance":true,"pyQName":"Dart.set_trace"},"Dart.throwDart":{"kind":-1,"attributes":{"blockId":"throwDart","block":"throw %dart(myDart)","weight":50,"group":"Actions","help":"darts/throw-dart","jsDoc":"Throw the dart with the current settings","_def":{"parts":[{"kind":"label","text":"throw ","style":[]},{"kind":"param","name":"dart","ref":false,"varName":"myDart"}],"parameters":[{"kind":"param","name":"dart","ref":false,"varName":"myDart"}]}},"parameters":[],"isInstance":true,"pyQName":"Dart.throw_dart"},"Dart.stopDart":{"kind":-1,"attributes":{"blockId":"stopDart","block":"stop %dart(myDart)","weight":50,"group":"Actions","help":"darts/stop-dart","jsDoc":"Stop the dart at the current location","_def":{"parts":[{"kind":"label","text":"stop ","style":[]},{"kind":"param","name":"dart","ref":false,"varName":"myDart"}],"parameters":[{"kind":"param","name":"dart","ref":false,"varName":"myDart"}]}},"parameters":[],"isInstance":true,"pyQName":"Dart.stop_dart"},"Dart.controlWithArrowKeys":{"kind":-1,"attributes":{"paramDefl":{"on":"true"},"blockId":"controlKeys","block":"control %dart(myDart) with arrow keys || %on=toggleOnOff","weight":50,"group":"Actions","help":"darts/control-with-arrow-keys","paramHelp":{"on":"whether to turn on or off this feature, eg: true"},"jsDoc":"Set whether to control the dart with the arrow keys; left and right\nto adjust the angle, and up and down to increase / decrease power","_def":{"parts":[{"kind":"label","text":"control ","style":[]},{"kind":"param","name":"dart","ref":false,"varName":"myDart"},{"kind":"label","text":" with arrow keys ","style":[]}],"parameters":[{"kind":"param","name":"dart","ref":false,"varName":"myDart"}]},"_expandedDef":{"parts":[{"kind":"label","text":" ","style":[]},{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}],"parameters":[{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}]}},"parameters":[{"name":"on","description":"whether to turn on or off this feature, eg: true","type":"boolean","initializer":"true","default":"true"}],"isInstance":true,"pyQName":"Dart.control_with_arrow_keys"},"Dart.destroy":{"kind":-1,"parameters":[{"name":"effect","type":"effects.ParticleEffect","initializer":"undefined"},{"name":"duration","initializer":"undefined"}],"isInstance":true},"Dart.updateBackground":{"kind":-1,"attributes":{"blockId":"updateBackground","block":"change %dart(myDart) background to image %img=background_image_picker","weight":15,"group":"Properties","deprecated":"true","jsDoc":"NO LONGER NECESSARY as this uses renderables now to draw onto the background.","_def":{"parts":[{"kind":"label","text":"change ","style":[]},{"kind":"param","name":"dart","ref":false,"varName":"myDart"},{"kind":"label","text":" background to image ","style":[]},{"kind":"param","name":"img","shadowBlockId":"background_image_picker","ref":false}],"parameters":[{"kind":"param","name":"dart","ref":false,"varName":"myDart"},{"kind":"param","name":"img","shadowBlockId":"background_image_picker","ref":false}]}},"parameters":[{"name":"img","type":"Image"}],"isInstance":true,"pyQName":"Dart.update_background"}}},"sha":"e3a74103bcf50ef5221e91f301545c4cdc23514f01c7a9015e4ebbf3a8d5dd13"},"libs/device":{"apis":{"byQName":{"Array":{"kind":5,"retType":"","attributes":{"blockNamespace":"Arrays","jsDoc":"Add, remove, and replace items in lists."}},"Array.length":{"kind":2,"retType":"number","attributes":{"weight":84,"blockId":"lists_length","block":"length of %VALUE","blockBuiltin":"true","blockNamespace":"arrays","jsDoc":"Get or set the length of an array. This number is one more than the index of the last element the array.","_def":{"parts":[{"kind":"label","text":"length of ","style":[]},{"kind":"param","name":"VALUE","ref":false}],"parameters":[{"kind":"param","name":"VALUE","ref":false}]}},"isInstance":true},"Array.push":{"kind":-1,"attributes":{"help":"arrays/push","weight":50,"blockId":"array_push","block":"%list| add value %value| to end","blockNamespace":"arrays","group":"Modify","paramHelp":{"items":"New elements of the Array."},"jsDoc":"Append a new element to an array.","_def":{"parts":[{"kind":"param","name":"list","ref":false},{"kind":"break"},{"kind":"label","text":" add value ","style":[]},{"kind":"param","name":"value","ref":false},{"kind":"break"},{"kind":"label","text":" to end","style":[]}],"parameters":[{"kind":"param","name":"list","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"item","type":"T"}],"isInstance":true,"pyQName":"Array.append"},"Array.concat":{"kind":-1,"retType":"T[]","attributes":{"helper":"arrayConcat","weight":40,"paramHelp":{"arr":"The other array that is being concatenated with"},"jsDoc":"Concatenates the values with another array."},"parameters":[{"name":"arr","description":"The other array that is being concatenated with","type":"T[]"}],"isInstance":true},"Array.pop":{"kind":-1,"retType":"T","attributes":{"help":"arrays/pop","weight":45,"blockId":"array_pop","block":"get and remove last value from %list","blockNamespace":"arrays","group":"Read","jsDoc":"Remove the last element from an array and return it.","_def":{"parts":[{"kind":"label","text":"get and remove last value from ","style":[]},{"kind":"param","name":"list","ref":false}],"parameters":[{"kind":"param","name":"list","ref":false}]}},"parameters":[],"isInstance":true},"Array.reverse":{"kind":-1,"attributes":{"help":"arrays/reverse","helper":"arrayReverse","weight":10,"blockId":"array_reverse","block":"reverse %list","blockNamespace":"arrays","group":"Operations","jsDoc":"Reverse the elements in an array. The first array element becomes the last, and the last array element becomes the first.","_def":{"parts":[{"kind":"label","text":"reverse ","style":[]},{"kind":"param","name":"list","ref":false}],"parameters":[{"kind":"param","name":"list","ref":false}]}},"parameters":[],"isInstance":true},"Array.shift":{"kind":-1,"retType":"T","attributes":{"help":"arrays/shift","helper":"arrayShift","weight":30,"blockId":"array_shift","block":"get and remove first value from %list","blockNamespace":"arrays","group":"Read","jsDoc":"Remove the first element from an array and return it. This method changes the length of the array.","_def":{"parts":[{"kind":"label","text":"get and remove first value from ","style":[]},{"kind":"param","name":"list","ref":false}],"parameters":[{"kind":"param","name":"list","ref":false}]}},"parameters":[],"isInstance":true},"Array.unshift":{"kind":-1,"retType":"number","attributes":{"help":"arrays/unshift","helper":"arrayUnshift","weight":25,"blockId":"array_unshift","block":"%list| insert %value| at beginning","blockNamespace":"arrays","group":"Modify","paramHelp":{"element":"to insert at the start of the Array."},"jsDoc":"Add one element to the beginning of an array and return the new length of the array.","_def":{"parts":[{"kind":"param","name":"list","ref":false},{"kind":"break"},{"kind":"label","text":" insert ","style":[]},{"kind":"param","name":"value","ref":false},{"kind":"break"},{"kind":"label","text":" at beginning","style":[]}],"parameters":[{"kind":"param","name":"list","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","type":"T"}],"isInstance":true},"Array.slice":{"kind":-1,"retType":"T[]","attributes":{"paramDefl":{"start":"0","end":"0"},"help":"arrays/slice","helper":"arraySlice","weight":41,"blockNamespace":"arrays","paramHelp":{"start":"The beginning of the specified portion of the array. eg: 0","end":"The end of the specified portion of the array. eg: 0"},"jsDoc":"Return a section of an array."},"parameters":[{"name":"start","description":"The beginning of the specified portion of the array. eg: 0","initializer":"undefined","default":"0"},{"name":"end","description":"The end of the specified portion of the array. eg: 0","initializer":"undefined","default":"0"}],"isInstance":true},"Array.splice":{"kind":-1,"attributes":{"paramDefl":{"start":"0","deleteCount":"0"},"helper":"arraySplice","weight":40,"paramHelp":{"start":"The zero-based location in the array from which to start removing elements. eg: 0","deleteCount":"The number of elements to remove. eg: 0"},"jsDoc":"Remove elements from an array."},"parameters":[{"name":"start","description":"The zero-based location in the array from which to start removing elements. eg: 0","default":"0"},{"name":"deleteCount","description":"The number of elements to remove. eg: 0","default":"0"}],"isInstance":true},"Array.join":{"kind":-1,"retType":"string","attributes":{"helper":"arrayJoin","weight":40,"paramHelp":{"sep":"the string separator"},"jsDoc":"joins all elements of an array into a string and returns this string."},"parameters":[{"name":"sep","description":"the string separator","type":"string","initializer":"undefined"}],"isInstance":true},"Array.some":{"kind":-1,"retType":"boolean","attributes":{"helper":"arraySome","weight":40,"paramHelp":{"callbackfn":"A function that accepts up to two arguments. The some method calls the callbackfn function one time for each element in the array."},"jsDoc":"Tests whether at least one element in the array passes the test implemented by the provided function."},"parameters":[{"name":"callbackfn","description":"A function that accepts up to two arguments. The some method calls the callbackfn function one time for each element in the array.","type":"(value: T, index: number) => boolean","handlerParameters":[{"name":"value","type":"T"},{"name":"index","type":"number"}]}],"isInstance":true},"Array.every":{"kind":-1,"retType":"boolean","attributes":{"helper":"arrayEvery","weight":40,"paramHelp":{"callbackfn":"A function that accepts up to two arguments. The every method calls the callbackfn function one time for each element in the array."},"jsDoc":"Tests whether all elements in the array pass the test implemented by the provided function."},"parameters":[{"name":"callbackfn","description":"A function that accepts up to two arguments. The every method calls the callbackfn function one time for each element in the array.","type":"(value: T, index: number) => boolean","handlerParameters":[{"name":"value","type":"T"},{"name":"index","type":"number"}]}],"isInstance":true},"Array.sort":{"kind":-1,"retType":"T[]","attributes":{"helper":"arraySort","weight":40,"paramHelp":{"specifies":"a function that defines the sort order. If omitted, the array is sorted according to the prmitive type"},"jsDoc":"Sort the elements of an array in place and returns the array. The sort is not necessarily stable."},"parameters":[{"name":"callbackfn","type":"(value1: T, value2: T) => number","initializer":"undefined","handlerParameters":[{"name":"value1","type":"T"},{"name":"value2","type":"T"}]}],"isInstance":true},"Array.map":{"kind":-1,"retType":"U[]","attributes":{"helper":"arrayMap","weight":40,"paramHelp":{"callbackfn":"A function that accepts up to two arguments. The map method calls the callbackfn function one time for each element in the array."},"jsDoc":"Call a defined callback function on each element of an array, and return an array containing the results."},"parameters":[{"name":"callbackfn","description":"A function that accepts up to two arguments. The map method calls the callbackfn function one time for each element in the array.","type":"(value: T, index: number) => U","handlerParameters":[{"name":"value","type":"T"},{"name":"index","type":"number"}]}],"isInstance":true},"Array.forEach":{"kind":-1,"attributes":{"helper":"arrayForEach","weight":40,"paramHelp":{"callbackfn":"A function that accepts up to two arguments. The forEach method calls the callbackfn function one time for each element in the array."},"jsDoc":"Call a defined callback function on each element of an array."},"parameters":[{"name":"callbackfn","description":"A function that accepts up to two arguments. The forEach method calls the callbackfn function one time for each element in the array.","type":"(value: T, index: number) => void","handlerParameters":[{"name":"value","type":"T"},{"name":"index","type":"number"}]}],"isInstance":true,"pyQName":"Array.for_each"},"Array.filter":{"kind":-1,"retType":"T[]","attributes":{"helper":"arrayFilter","weight":40,"paramHelp":{"callbackfn":"A function that accepts up to two arguments. The filter method calls the callbackfn function one time for each element in the array."},"jsDoc":"Return the elements of an array that meet the condition specified in a callback function."},"parameters":[{"name":"callbackfn","description":"A function that accepts up to two arguments. The filter method calls the callbackfn function one time for each element in the array.","type":"(value: T, index: number) => boolean","handlerParameters":[{"name":"value","type":"T"},{"name":"index","type":"number"}]}],"isInstance":true},"Array.fill":{"kind":-1,"retType":"T[]","attributes":{"helper":"arrayFill","weight":39,"jsDoc":"Fills all the elements of an array from a start index to an end index with a static value. The end index is not included."},"parameters":[{"name":"value","type":"T"},{"name":"start","initializer":"undefined"},{"name":"end","initializer":"undefined"}],"isInstance":true},"Array.find":{"kind":-1,"retType":"T","attributes":{"helper":"arrayFind","weight":40,"paramHelp":{"callbackfn":""},"jsDoc":"Returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned."},"parameters":[{"name":"callbackfn","type":"(value: T, index: number) => boolean","handlerParameters":[{"name":"value","type":"T"},{"name":"index","type":"number"}]}],"isInstance":true},"Array.reduce":{"kind":-1,"retType":"U","attributes":{"helper":"arrayReduce","weight":40,"paramHelp":{"callbackfn":"A function that accepts up to three arguments. The reduce method calls the callbackfn function one time for each element in the array.","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."},"jsDoc":"Call 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."},"parameters":[{"name":"callbackfn","description":"A function that accepts up to three arguments. The reduce method calls the callbackfn function one time for each element in the array.","type":"(previousValue: U, currentValue: T, currentIndex: number) => U","handlerParameters":[{"name":"previousValue","type":"U"},{"name":"currentValue","type":"T"},{"name":"currentIndex","type":"number"}]},{"name":"initialValue","description":"Initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.","type":"U"}],"isInstance":true},"Array.removeElement":{"kind":-1,"retType":"boolean","attributes":{"weight":48,"jsDoc":"Remove the first occurence of an object. Returns true if removed."},"parameters":[{"name":"element","type":"T"}],"isInstance":true,"pyQName":"Array.remove_element"},"Array.removeAt":{"kind":-1,"retType":"T","attributes":{"help":"arrays/remove-at","weight":47,"blockId":"array_removeat","block":"%list| get and remove value at %index","blockNamespace":"arrays","group":"Read","jsDoc":"Remove and return the element at a certain index.","_def":{"parts":[{"kind":"param","name":"list","ref":false},{"kind":"break"},{"kind":"label","text":" get and remove value at ","style":[]},{"kind":"param","name":"index","ref":false}],"parameters":[{"kind":"param","name":"list","ref":false},{"kind":"param","name":"index","ref":false}]}},"parameters":[{"name":"index"}],"isInstance":true,"pyQName":"Array.remove_at"},"Array.insertAt":{"kind":-1,"attributes":{"paramDefl":{"index":"0","the":"0"},"help":"arrays/insert-at","weight":20,"blockId":"array_insertAt","block":"%list| insert at %index| value %value","blockNamespace":"arrays","group":"Modify","paramHelp":{"index":"the zero-based position in the list to insert the value, eg: 0","the":"value to insert, eg: 0"},"jsDoc":"Insert the value at a particular index, increases length by 1","_def":{"parts":[{"kind":"param","name":"list","ref":false},{"kind":"break"},{"kind":"label","text":" insert at ","style":[]},{"kind":"param","name":"index","ref":false},{"kind":"break"},{"kind":"label","text":" value ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"list","ref":false},{"kind":"param","name":"index","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"index","description":"the zero-based position in the list to insert the value, eg: 0","default":"0"},{"name":"value","type":"T"}],"isInstance":true,"pyQName":"Array.insert_at"},"Array.indexOf":{"kind":-1,"retType":"number","attributes":{"help":"arrays/index-of","weight":40,"blockId":"array_indexof","block":"%list| find index of %value","blockNamespace":"arrays","group":"Operations","paramHelp":{"item":"The value to locate in the array.","fromIndex":"The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0."},"jsDoc":"Return the index of the first occurrence of a value in an array.","_def":{"parts":[{"kind":"param","name":"list","ref":false},{"kind":"break"},{"kind":"label","text":" find index of ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"list","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"item","description":"The value to locate in the array.","type":"T"},{"name":"fromIndex","description":"The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.","initializer":"undefined"}],"isInstance":true,"pyQName":"Array.index_of"},"Array.get":{"kind":-1,"retType":"T","attributes":{"paramDefl":{"index":"0"},"help":"arrays/get","weight":85,"paramHelp":{"index":"the zero-based position in the list of the item, eg: 0"},"jsDoc":"Get the value at a particular index"},"parameters":[{"name":"index","description":"the zero-based position in the list of the item, eg: 0","default":"0"}],"isInstance":true},"Array.set":{"kind":-1,"attributes":{"paramDefl":{"index":"0","value":"0"},"help":"arrays/set","weight":84,"paramHelp":{"index":"the zero-based position in the list to store the value, eg: 0","value":"the value to insert, eg: 0"},"jsDoc":"Store a value at a particular index"},"parameters":[{"name":"index","description":"the zero-based position in the list to store the value, eg: 0","default":"0"},{"name":"value","description":"the value to insert, eg: 0","type":"T","default":"0"}],"isInstance":true},"Array._pickRandom":{"kind":-1,"retType":"T","attributes":{"help":"arrays/pick-random","helper":"arrayPickRandom","weight":25,"blockId":"array_pickRandom","block":"get random value from %list","blockNamespace":"arrays","group":"Read","jsDoc":"Return a random value from the array","_def":{"parts":[{"kind":"label","text":"get random value from ","style":[]},{"kind":"param","name":"list","ref":false}],"parameters":[{"kind":"param","name":"list","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"Array._pick_random"},"Array._unshiftStatement":{"kind":-1,"attributes":{"help":"arrays/unshift","helper":"arrayUnshift","weight":24,"blockId":"array_unshift_statement","block":"%list| insert %value| at beginning","blockNamespace":"arrays","blockAliasFor":"Array.unshift","group":"Modify","paramHelp":{"element":"to insert at the start of the Array."},"jsDoc":"Add one element to the beginning of an array and return the new length of the array.","_def":{"parts":[{"kind":"param","name":"list","ref":false},{"kind":"break"},{"kind":"label","text":" insert ","style":[]},{"kind":"param","name":"value","ref":false},{"kind":"break"},{"kind":"label","text":" at beginning","style":[]}],"parameters":[{"kind":"param","name":"list","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","type":"T"}],"isInstance":true,"pyQName":"Array._unshift_statement"},"Array._popStatement":{"kind":-1,"attributes":{"help":"arrays/pop","weight":44,"blockId":"array_pop_statement","block":"remove last value from %list","blockNamespace":"arrays","blockAliasFor":"Array.pop","group":"Modify","jsDoc":"Remove the last element from an array and return it.","_def":{"parts":[{"kind":"label","text":"remove last value from ","style":[]},{"kind":"param","name":"list","ref":false}],"parameters":[{"kind":"param","name":"list","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"Array._pop_statement"},"Array._shiftStatement":{"kind":-1,"attributes":{"help":"arrays/shift","helper":"arrayShift","weight":29,"blockId":"array_shift_statement","block":"remove first value from %list","blockNamespace":"arrays","blockAliasFor":"Array.shift","group":"Modify","jsDoc":"Remove the first element from an array and return it. This method changes the length of the array.","_def":{"parts":[{"kind":"label","text":"remove first value from ","style":[]},{"kind":"param","name":"list","ref":false}],"parameters":[{"kind":"param","name":"list","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"Array._shift_statement"},"Array._removeAtStatement":{"kind":-1,"attributes":{"help":"arrays/remove-at-statement","weight":14,"blockId":"array_removeat_statement","block":"%list| remove value at %index","blockNamespace":"arrays","blockAliasFor":"Array.removeAt","group":"Modify","jsDoc":"Remove the element at a certain index.","_def":{"parts":[{"kind":"param","name":"list","ref":false},{"kind":"break"},{"kind":"label","text":" remove value at ","style":[]},{"kind":"param","name":"index","ref":false}],"parameters":[{"kind":"param","name":"list","ref":false},{"kind":"param","name":"index","ref":false}]}},"parameters":[{"name":"index"}],"isInstance":true,"pyQName":"Array._remove_at_statement"},"String":{"kind":5,"retType":"","attributes":{"blockNamespace":"text","jsDoc":"Combine, split, and search text strings."}},"String.concat":{"kind":-1,"retType":"string","attributes":{"weight":49,"blockId":"string_concat","blockNamespace":"text","paramHelp":{"other":"The string to append to the end of the string."},"jsDoc":"Returns a string that contains the concatenation of two or more strings."},"parameters":[{"name":"other","description":"The string to append to the end of the string.","type":"string"}],"isInstance":true},"String.charAt":{"kind":-1,"retType":"string","attributes":{"paramDefl":{"this":"this"},"weight":48,"help":"text/char-at","blockId":"string_get","block":"char from %this=text|at %pos","blockNamespace":"text","explicitDefaults":["this"],"paramHelp":{"index":"The zero-based index of the desired character."},"jsDoc":"Return the character at the specified index.","_def":{"parts":[{"kind":"label","text":"char from ","style":[]},{"kind":"param","name":"this","shadowBlockId":"text","ref":false},{"kind":"break"},{"kind":"label","text":"at ","style":[]},{"kind":"param","name":"pos","ref":false}],"parameters":[{"kind":"param","name":"this","shadowBlockId":"text","ref":false},{"kind":"param","name":"pos","ref":false}]}},"parameters":[{"name":"index","description":"The zero-based index of the desired character."}],"isInstance":true,"pyQName":"String.char_at"},"String.length":{"kind":2,"retType":"number","attributes":{"property":"true","weight":47,"blockId":"text_length","block":"length of %VALUE","blockBuiltin":"true","blockNamespace":"text","jsDoc":"Returns the length of a String object.","_def":{"parts":[{"kind":"label","text":"length of ","style":[]},{"kind":"param","name":"VALUE","ref":false}],"parameters":[{"kind":"param","name":"VALUE","ref":false}]}},"isInstance":true},"String.charCodeAt":{"kind":-1,"retType":"number","attributes":{"paramDefl":{"this":"this"},"weight":46,"help":"text/char-code-at","blockId":"string_charcode_at","block":"char code from $this=text|at $index","blockNamespace":"text","explicitDefaults":["this"],"paramHelp":{"index":"The zero-based index of the desired character. If there is no character at the specified index, NaN is returned."},"jsDoc":"Return the Unicode value of the character at the specified location.","_def":{"parts":[{"kind":"label","text":"char code from ","style":[]},{"kind":"param","name":"this","shadowBlockId":"text","ref":true},{"kind":"break"},{"kind":"label","text":"at ","style":[]},{"kind":"param","name":"index","ref":true}],"parameters":[{"kind":"param","name":"this","shadowBlockId":"text","ref":true},{"kind":"param","name":"index","ref":true}]}},"parameters":[{"name":"index","description":"The zero-based index of the desired character. If there is no character at the specified index, NaN is returned."}],"isInstance":true,"pyQName":"String.char_code_at"},"String.compare":{"kind":-1,"retType":"number","attributes":{"paramDefl":{"this":"this"},"help":"text/compare","blockId":"string_compare","block":"compare %this=text| to %that","blockNamespace":"text","explicitDefaults":["this"],"paramHelp":{"that":"String to compare to target string"},"jsDoc":"See how the order of characters in two strings is different (in ASCII encoding).","_def":{"parts":[{"kind":"label","text":"compare ","style":[]},{"kind":"param","name":"this","shadowBlockId":"text","ref":false},{"kind":"break"},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"that","ref":false}],"parameters":[{"kind":"param","name":"this","shadowBlockId":"text","ref":false},{"kind":"param","name":"that","ref":false}]}},"parameters":[{"name":"that","description":"String to compare to target string","type":"string"}],"isInstance":true},"String.substr":{"kind":-1,"retType":"string","attributes":{"paramDefl":{"this":"this","start":"0","length":"10"},"helper":"stringSubstr","help":"text/substr","blockId":"string_substr","block":"substring of %this=text|from %start|of length %length","blockNamespace":"text","explicitDefaults":["this"],"paramHelp":{"start":"first character index; can be negative from counting from the end, eg:0","length":"number of characters to extract, eg: 10"},"jsDoc":"Return a substring of the current string.","_def":{"parts":[{"kind":"label","text":"substring of ","style":[]},{"kind":"param","name":"this","shadowBlockId":"text","ref":false},{"kind":"break"},{"kind":"label","text":"from ","style":[]},{"kind":"param","name":"start","ref":false},{"kind":"break"},{"kind":"label","text":"of length ","style":[]},{"kind":"param","name":"length","ref":false}],"parameters":[{"kind":"param","name":"this","shadowBlockId":"text","ref":false},{"kind":"param","name":"start","ref":false},{"kind":"param","name":"length","ref":false}]}},"parameters":[{"name":"start","description":"first character index; can be negative from counting from the end, eg:0","default":"0"},{"name":"length","description":"number of characters to extract, eg: 10","initializer":"undefined","default":"10"}],"isInstance":true},"String.replace":{"kind":-1,"retType":"string","attributes":{"helper":"stringReplace","paramHelp":{"toReplace":"the substring to replace in the current string","replacer":"either the string that replaces toReplace in the current string,"},"jsDoc":"Return the current string with the first occurence of toReplace\nreplaced with the replacer\n\n\nor a function that accepts the substring and returns the replacement string."},"parameters":[{"name":"toReplace","description":"the substring to replace in the current string","type":"string"},{"name":"replacer","description":"either the string that replaces toReplace in the current string,","type":"string | ((sub: string) => string)"}],"isInstance":true},"String.replaceAll":{"kind":-1,"retType":"string","attributes":{"helper":"stringReplaceAll","paramHelp":{"toReplace":"the substring to replace in the current string","replacer":"either the string that replaces toReplace in the current string,"},"jsDoc":"Return the current string with each occurence of toReplace\nreplaced with the replacer\n\n\nor a function that accepts the substring and returns the replacement string."},"parameters":[{"name":"toReplace","description":"the substring to replace in the current string","type":"string"},{"name":"replacer","description":"either the string that replaces toReplace in the current string,","type":"string | ((sub: string) => string)"}],"isInstance":true,"pyQName":"String.replace_all"},"String.slice":{"kind":-1,"retType":"string","attributes":{"paramDefl":{"start":"0"},"helper":"stringSlice","paramHelp":{"start":"first character index; can be negative from counting from the end, eg:0","end":"one-past-last character index"},"jsDoc":"Return a substring of the current string."},"parameters":[{"name":"start","description":"first character index; can be negative from counting from the end, eg:0","default":"0"},{"name":"end","description":"one-past-last character index","initializer":"undefined"}],"isInstance":true},"String.isEmpty":{"kind":-1,"retType":"boolean","attributes":{"paramDefl":{"this":"this"},"helper":"stringEmpty","help":"text/is-empty","blockId":"string_isempty","blockNamespace":"text","block":"%this=text| is empty","explicitDefaults":["this"],"jsDoc":"Returns a value indicating if the string is empty","_def":{"parts":[{"kind":"param","name":"this","shadowBlockId":"text","ref":false},{"kind":"break"},{"kind":"label","text":" is empty","style":[]}],"parameters":[{"kind":"param","name":"this","shadowBlockId":"text","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"String.is_empty"},"String.indexOf":{"kind":-1,"retType":"number","attributes":{"paramDefl":{"this":"this"},"help":"text/index-of","blockId":"string_indexof","blockNamespace":"text","block":"%this=text|find index of %searchValue","explicitDefaults":["this"],"paramHelp":{"searchValue":"the text to find","start":"optional start index for the search"},"jsDoc":"Returns the position of the first occurrence of a specified value in a string.","_def":{"parts":[{"kind":"param","name":"this","shadowBlockId":"text","ref":false},{"kind":"break"},{"kind":"label","text":"find index of ","style":[]},{"kind":"param","name":"searchValue","ref":false}],"parameters":[{"kind":"param","name":"this","shadowBlockId":"text","ref":false},{"kind":"param","name":"searchValue","ref":false}]}},"parameters":[{"name":"searchValue","description":"the text to find","type":"string"},{"name":"start","description":"optional start index for the search","initializer":"undefined"}],"isInstance":true,"pyQName":"String.index_of"},"String.includes":{"kind":-1,"retType":"boolean","attributes":{"paramDefl":{"this":"this"},"help":"text/includes","blockId":"string_includes","blockNamespace":"text","block":"%this=text|includes %searchValue","explicitDefaults":["this"],"paramHelp":{"searchValue":"the text to find","start":"optional start index for the search"},"jsDoc":"Determines whether a string contains the characters of a specified string.","_def":{"parts":[{"kind":"param","name":"this","shadowBlockId":"text","ref":false},{"kind":"break"},{"kind":"label","text":"includes ","style":[]},{"kind":"param","name":"searchValue","ref":false}],"parameters":[{"kind":"param","name":"this","shadowBlockId":"text","ref":false},{"kind":"param","name":"searchValue","ref":false}]}},"parameters":[{"name":"searchValue","description":"the text to find","type":"string"},{"name":"start","description":"optional start index for the search","initializer":"undefined"}],"isInstance":true},"String.split":{"kind":-1,"retType":"string[]","attributes":{"paramDefl":{"this":"this"},"helper":"stringSplit","help":"text/split","blockId":"string_split","blockNamespace":"text","block":"split %this=text|at %separator","explicitDefaults":["this"],"paramHelp":{"separator":"@param limit"},"jsDoc":"Splits the string according to the separators","_def":{"parts":[{"kind":"label","text":"split ","style":[]},{"kind":"param","name":"this","shadowBlockId":"text","ref":false},{"kind":"break"},{"kind":"label","text":"at ","style":[]},{"kind":"param","name":"separator","ref":false}],"parameters":[{"kind":"param","name":"this","shadowBlockId":"text","ref":false},{"kind":"param","name":"separator","ref":false}]}},"parameters":[{"name":"separator","description":"@param limit","type":"string","initializer":"undefined"},{"name":"limit","initializer":"undefined"}],"isInstance":true},"String.trim":{"kind":-1,"retType":"string","attributes":{"helper":"stringTrim","jsDoc":"Return a substring of the current string with whitespace removed from both ends"},"parameters":[],"isInstance":true},"String.toUpperCase":{"kind":-1,"retType":"string","attributes":{"helper":"stringToUpperCase","help":"text/to-upper-case","jsDoc":"Converts the string to upper case characters."},"parameters":[],"isInstance":true,"pyQName":"String.to_upper_case"},"String.toLowerCase":{"kind":-1,"retType":"string","attributes":{"helper":"stringToLowerCase","help":"text/to-lower-case","jsDoc":"Converts the string to lower case characters."},"parameters":[],"isInstance":true,"pyQName":"String.to_lower_case"},"parseFloat":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"text":"123","s":"123"},"help":"text/parse-float","blockId":"string_parsefloat","block":"parse to number %text","blockNamespace":"text","explicitDefaults":["text"],"paramHelp":{"s":"A string to convert into a number. eg: 123"},"jsDoc":"Convert a string to a number.","_def":{"parts":[{"kind":"label","text":"parse to number ","style":[]},{"kind":"param","name":"text","ref":false}],"parameters":[{"kind":"param","name":"text","ref":false}]}},"parameters":[{"name":"text","type":"string","initializer":"123","default":"123"}],"pyQName":"parse_float"},"randint":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"min":"0","max":"10"},"blockId":"device_random","block":"pick random %min|to %limit","blockNamespace":"Math","help":"math/randint","paramHelp":{"min":"the lower inclusive bound, eg: 0","max":"the upper inclusive bound, eg: 10"},"jsDoc":"Returns a pseudorandom number between min and max included.\nIf both numbers are integral, the result is integral.","_def":{"parts":[{"kind":"label","text":"pick random ","style":[]},{"kind":"param","name":"min","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"limit","ref":false}],"parameters":[{"kind":"param","name":"min","ref":false},{"kind":"param","name":"limit","ref":false}]}},"parameters":[{"name":"min","description":"the lower inclusive bound, eg: 0","default":"0"},{"name":"max","description":"the upper inclusive bound, eg: 10","default":"10"}]},"Object":{"kind":5,"retType":""},"Function":{"kind":9,"retType":"Function","extendsTypes":[]},"Function.__assignableToFunction":{"kind":2,"retType":"Function","isInstance":true},"IArguments":{"kind":9,"retType":"IArguments","extendsTypes":[]},"IArguments.__assignableToIArguments":{"kind":2,"retType":"IArguments","isInstance":true},"RegExp":{"kind":9,"retType":"RegExp","extendsTypes":[]},"RegExp.__assignableToRegExp":{"kind":2,"retType":"RegExp","isInstance":true},"Boolean":{"kind":9,"retType":"Boolean","extendsTypes":[]},"Boolean.toString":{"kind":-1,"retType":"string","attributes":{"jsDoc":"Returns a string representation of an object."},"parameters":[],"isInstance":true,"pyQName":"Boolean.to_string"},"String@type":{"kind":9,"retType":"String","attributes":{"blockNamespace":"text","jsDoc":"Combine, split, and search text strings."},"extendsTypes":[],"pyQName":"String"},"String.fromCharCode":{"kind":-3,"retType":"string","attributes":{"help":"math/from-char-code","weight":1,"blockNamespace":"text","blockId":"stringFromCharCode","block":"text from char code %code","jsDoc":"Make a string from the given ASCII character code.","_def":{"parts":[{"kind":"label","text":"text from char code ","style":[]},{"kind":"param","name":"code","ref":false}],"parameters":[{"kind":"param","name":"code","ref":false}]}},"parameters":[{"name":"code"}],"pyQName":"String.from_char_code"},"Number":{"kind":5,"retType":"","extendsTypes":["Number"]},"Number.toString":{"kind":-1,"retType":"string","attributes":{"jsDoc":"Returns a string representation of a number."},"parameters":[],"isInstance":true,"pyQName":"Number.to_string"},"Array@type":{"kind":9,"retType":"T[]","attributes":{"blockNamespace":"Arrays","jsDoc":"Add, remove, and replace items in lists."},"extendsTypes":[],"pyQName":"Array"},"Array.isArray":{"kind":-3,"retType":"boolean","attributes":{"jsDoc":"Check if a given object is an array."},"parameters":[{"name":"obj","type":"any"}],"pyQName":"Array.is_array"},"Object@type":{"kind":9,"retType":"Object","extendsTypes":[],"pyQName":"Object"},"Object.keys":{"kind":-3,"retType":"string[]","attributes":{"jsDoc":"Return the field names in an object."},"parameters":[{"name":"obj","type":"any"}]},"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"Math.pow":{"kind":-3,"retType":"number","attributes":{"paramHelp":{"x":"The base value of the expression.","y":"The exponent value of the expression."},"jsDoc":"Returns the value of a base expression taken to a specified power."},"parameters":[{"name":"x","description":"The base value of the expression."},{"name":"y","description":"The exponent value of the expression."}]},"Math.random":{"kind":-3,"retType":"number","attributes":{"help":"math/random","jsDoc":"Returns a pseudorandom number between 0 and 1."},"parameters":[]},"Math.randomRange":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"min":"0","max":"10"},"blockId":"device_random_deprecated","block":"pick random %min|to %limit","help":"math/random-range","deprecated":"true","paramHelp":{"min":"the lower inclusive bound, eg: 0","max":"the upper inclusive bound, eg: 10"},"jsDoc":"Returns a pseudorandom number between min and max included.\nIf both numbers are integral, the result is integral.","_def":{"parts":[{"kind":"label","text":"pick random ","style":[]},{"kind":"param","name":"min","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"limit","ref":false}],"parameters":[{"kind":"param","name":"min","ref":false},{"kind":"param","name":"limit","ref":false}]}},"parameters":[{"name":"min","description":"the lower inclusive bound, eg: 0","default":"0"},{"name":"max","description":"the upper inclusive bound, eg: 10","default":"10"}],"pyQName":"Math.random_range"},"Math.log":{"kind":-3,"retType":"number","attributes":{"help":"math","paramHelp":{"x":"A number"},"jsDoc":"Returns the natural logarithm (base e) of a number."},"parameters":[{"name":"x","description":"A number"}]},"Math.exp":{"kind":-3,"retType":"number","attributes":{"help":"math","paramHelp":{"x":"A number"},"jsDoc":"Returns returns ``e^x``."},"parameters":[{"name":"x","description":"A number"}]},"Math.sin":{"kind":-3,"retType":"number","attributes":{"help":"math/trigonometry","paramHelp":{"x":"An angle in radians"},"jsDoc":"Returns the sine of a number."},"parameters":[{"name":"x","description":"An angle in radians"}]},"Math.cos":{"kind":-3,"retType":"number","attributes":{"help":"math/trigonometry","paramHelp":{"x":"An angle in radians"},"jsDoc":"Returns the cosine of a number."},"parameters":[{"name":"x","description":"An angle in radians"}]},"Math.tan":{"kind":-3,"retType":"number","attributes":{"help":"math/trigonometry","paramHelp":{"x":"An angle in radians"},"jsDoc":"Returns the tangent of a number."},"parameters":[{"name":"x","description":"An angle in radians"}]},"Math.asin":{"kind":-3,"retType":"number","attributes":{"help":"math/trigonometry","paramHelp":{"x":"A number"},"jsDoc":"Returns the arcsine (in radians) of a number"},"parameters":[{"name":"x","description":"A number"}]},"Math.acos":{"kind":-3,"retType":"number","attributes":{"help":"math/trigonometry","paramHelp":{"x":"A number"},"jsDoc":"Returns the arccosine (in radians) of a number"},"parameters":[{"name":"x","description":"A number"}]},"Math.atan":{"kind":-3,"retType":"number","attributes":{"help":"math/trigonometry","paramHelp":{"x":"A number"},"jsDoc":"Returns the arctangent (in radians) of a number"},"parameters":[{"name":"x","description":"A number"}]},"Math.atan2":{"kind":-3,"retType":"number","attributes":{"help":"math/trigonometry","paramHelp":{"y":"A number","x":"A number"},"jsDoc":"Returns the arctangent of the quotient of its arguments."},"parameters":[{"name":"y","description":"A number"},{"name":"x","description":"A number"}]},"Math.sqrt":{"kind":-3,"retType":"number","attributes":{"help":"math","paramHelp":{"x":"A numeric expression."},"jsDoc":"Returns the square root of a number."},"parameters":[{"name":"x","description":"A numeric expression."}]},"Math.ceil":{"kind":-3,"retType":"number","attributes":{"help":"math","paramHelp":{"x":"A numeric expression."},"jsDoc":"Returns the smallest number greater than or equal to its numeric argument."},"parameters":[{"name":"x","description":"A numeric expression."}]},"Math.floor":{"kind":-3,"retType":"number","attributes":{"help":"math","paramHelp":{"x":"A numeric expression."},"jsDoc":"Returns the greatest number less than or equal to its numeric argument."},"parameters":[{"name":"x","description":"A numeric expression."}]},"Math.trunc":{"kind":-3,"retType":"number","attributes":{"help":"math","paramHelp":{"x":"A numeric expression."},"jsDoc":"Returns the number with the decimal part truncated."},"parameters":[{"name":"x","description":"A numeric expression."}],"pyQName":"int"},"Math.round":{"kind":-3,"retType":"number","attributes":{"help":"math","paramHelp":{"x":"The value to be rounded to the nearest number."},"jsDoc":"Returns a supplied numeric expression rounded to the nearest number."},"parameters":[{"name":"x","description":"The value to be rounded to the nearest number."}]},"Math.imul":{"kind":-3,"retType":"number","attributes":{"help":"math","paramHelp":{"x":"The first number","y":"The second number"},"jsDoc":"Returns the value of integer signed 32 bit multiplication of two numbers."},"parameters":[{"name":"x","description":"The first number"},{"name":"y","description":"The second number"}]},"Math.idiv":{"kind":-3,"retType":"number","attributes":{"help":"math","paramHelp":{"x":"The first number","y":"The second number"},"jsDoc":"Returns the value of integer signed 32 bit division of two numbers."},"parameters":[{"name":"x","description":"The first number"},{"name":"y","description":"The second number"}]},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"control._onCodeStart":{"kind":-3,"parameters":[{"name":"arg","type":"any"}],"pyQName":"control._on_code_start"},"control._onCodeStop":{"kind":-3,"parameters":[{"name":"arg","type":"any"}],"pyQName":"control._on_code_stop"},"NaN":{"kind":4,"retType":"number","attributes":{"jsDoc":"Constant representing Not-A-Number."},"pyQName":"na_n"},"Infinity":{"kind":4,"retType":"number","attributes":{"jsDoc":"Constant representing positive infinity."},"pyQName":"infinity"},"isNaN":{"kind":-3,"retType":"boolean","parameters":[{"name":"x"}],"pyQName":"is_na_n"},"Number@type":{"kind":9,"retType":"Number","extendsTypes":[],"pyQName":"Number"},"Number.isNaN":{"kind":-3,"retType":"boolean","attributes":{"jsDoc":"Check if a given value is of type Number and it is a NaN."},"parameters":[{"name":"x","type":"any"}],"pyQName":"Number.is_na_n"},"StringMap":{"kind":9,"retType":"StringMap","attributes":{"jsDoc":"A dictionary from string key to string values"},"extendsTypes":[]},"parseInt":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"text":"123"},"help":"text/parse-int","blockId":"string_parseint","block":"parse to integer %text","blockNamespace":"text","explicitDefaults":["text"],"blockHidden":true,"paramHelp":{"text":"A string to convert into an integral number. eg: \"123\"","radix":"optional A value between 2 and 36 that specifies the base of the number in text."},"jsDoc":"Convert a string to an integer.\n\n\nIf this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.\nAll other strings are considered decimal.","_def":{"parts":[{"kind":"label","text":"parse to integer ","style":[]},{"kind":"param","name":"text","ref":false}],"parameters":[{"kind":"param","name":"text","ref":false}]}},"parameters":[{"name":"text","description":"A string to convert into an integral number. eg: \"123\"","type":"string","initializer":"123","default":"123"},{"name":"radix","description":"optional A value between 2 and 36 that specifies the base of the number in text.","initializer":"undefined"}],"pyQName":"int"},"helpers":{"kind":5,"retType":"","attributes":{"jsDoc":"These shims are for enabling system keyboard support in text/number prompts."}},"helpers.arrayFill":{"kind":-3,"retType":"T[]","parameters":[{"name":"O","type":"T[]"},{"name":"value","type":"T"},{"name":"start","initializer":"undefined"},{"name":"end","initializer":"undefined"}],"pyQName":"helpers.array_fill"},"helpers.arraySplice":{"kind":-3,"parameters":[{"name":"arr","type":"T[]"},{"name":"start"},{"name":"len"}],"pyQName":"helpers.array_splice"},"helpers.arrayReverse":{"kind":-3,"parameters":[{"name":"arr","type":"T[]"}],"pyQName":"helpers.array_reverse"},"helpers.arrayShift":{"kind":-3,"retType":"T","parameters":[{"name":"arr","type":"T[]"}],"pyQName":"helpers.array_shift"},"helpers.arrayJoin":{"kind":-3,"retType":"string","parameters":[{"name":"arr","type":"T[]"},{"name":"sep","type":"string","initializer":"undefined"}],"pyQName":"helpers.array_join"},"helpers.arrayUnshift":{"kind":-3,"retType":"number","parameters":[{"name":"arr","type":"T[]"},{"name":"value","type":"T"}],"pyQName":"helpers.array_unshift"},"helpers.arraySort":{"kind":-3,"retType":"T[]","parameters":[{"name":"arr","type":"T[]"},{"name":"callbackfn","type":"(value1: T, value2: T) => number","initializer":"undefined","handlerParameters":[{"name":"value1","type":"T"},{"name":"value2","type":"T"}]}],"pyQName":"helpers.array_sort"},"helpers.arrayMap":{"kind":-3,"retType":"U[]","parameters":[{"name":"arr","type":"T[]"},{"name":"callbackfn","type":"(value: T, index: number) => U","handlerParameters":[{"name":"value","type":"T"},{"name":"index","type":"number"}]}],"pyQName":"helpers.array_map"},"helpers.arraySome":{"kind":-3,"retType":"boolean","parameters":[{"name":"arr","type":"T[]"},{"name":"callbackfn","type":"(value: T, index: number) => boolean","handlerParameters":[{"name":"value","type":"T"},{"name":"index","type":"number"}]}],"pyQName":"helpers.array_some"},"helpers.arrayEvery":{"kind":-3,"retType":"boolean","parameters":[{"name":"arr","type":"T[]"},{"name":"callbackfn","type":"(value: T, index: number) => boolean","handlerParameters":[{"name":"value","type":"T"},{"name":"index","type":"number"}]}],"pyQName":"helpers.array_every"},"helpers.arrayForEach":{"kind":-3,"parameters":[{"name":"arr","type":"T[]"},{"name":"callbackfn","type":"(value: T, index: number) => void","handlerParameters":[{"name":"value","type":"T"},{"name":"index","type":"number"}]}],"pyQName":"helpers.array_for_each"},"helpers.arrayFilter":{"kind":-3,"retType":"T[]","parameters":[{"name":"arr","type":"T[]"},{"name":"callbackfn","type":"(value: T, index: number) => boolean","handlerParameters":[{"name":"value","type":"T"},{"name":"index","type":"number"}]}],"pyQName":"helpers.array_filter"},"helpers.arrayFind":{"kind":-3,"retType":"T","parameters":[{"name":"arr","type":"T[]"},{"name":"callbackfn","type":"(value: T, index: number) => boolean","handlerParameters":[{"name":"value","type":"T"},{"name":"index","type":"number"}]}],"pyQName":"helpers.array_find"},"helpers.arrayReduce":{"kind":-3,"retType":"U","parameters":[{"name":"arr","type":"T[]"},{"name":"callbackfn","type":"(previousValue: U, currentValue: T, currentIndex: number) => U","handlerParameters":[{"name":"previousValue","type":"U"},{"name":"currentValue","type":"T"},{"name":"currentIndex","type":"number"}]},{"name":"initialValue","type":"U"}],"pyQName":"helpers.array_reduce"},"helpers.arrayConcat":{"kind":-3,"retType":"T[]","parameters":[{"name":"arr","type":"T[]"},{"name":"otherArr","type":"T[]"}],"pyQName":"helpers.array_concat"},"helpers.arrayPickRandom":{"kind":-3,"retType":"T","parameters":[{"name":"arr","type":"T[]"}],"pyQName":"helpers.array_pick_random"},"helpers.arraySlice":{"kind":-3,"retType":"T[]","parameters":[{"name":"arr","type":"T[]"},{"name":"start","initializer":"undefined"},{"name":"end","initializer":"undefined"}],"pyQName":"helpers.array_slice"},"helpers.stringReplace":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"},{"name":"toReplace","type":"string"},{"name":"replacer","type":"string | ((sub: string) => string)"}],"pyQName":"helpers.string_replace"},"helpers.stringReplaceAll":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"},{"name":"toReplace","type":"string"},{"name":"replacer","type":"string | ((sub: string) => string)"}],"pyQName":"helpers.string_replace_all"},"helpers.stringSubstr":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"},{"name":"start"},{"name":"length","initializer":"undefined"}],"pyQName":"helpers.string_substr"},"helpers.stringSlice":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"},{"name":"start"},{"name":"end","initializer":"undefined"}],"pyQName":"helpers.string_slice"},"helpers.stringToUpperCase":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"}],"pyQName":"helpers.string_to_upper_case"},"helpers.stringToLowerCase":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"}],"pyQName":"helpers.string_to_lower_case"},"helpers.stringSplit":{"kind":-3,"retType":"string[]","parameters":[{"name":"S","type":"string"},{"name":"separator","type":"string","initializer":"undefined"},{"name":"limit","initializer":"undefined"}],"pyQName":"helpers.string_split"},"helpers.stringTrim":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"}],"pyQName":"helpers.string_trim"},"helpers.isWhitespace":{"kind":-3,"retType":"boolean","parameters":[{"name":"c"}],"pyQName":"helpers.is_whitespace"},"helpers.stringEmpty":{"kind":-3,"retType":"boolean","parameters":[{"name":"S","type":"string"}],"pyQName":"helpers.string_empty"},"Math.clamp":{"kind":-3,"retType":"number","parameters":[{"name":"min"},{"name":"max"},{"name":"value"}]},"Math.abs":{"kind":-3,"retType":"number","attributes":{"blockId":"math_op3","help":"math/abs","paramHelp":{"x":"A numeric expression for which the absolute value is needed."},"jsDoc":"Returns the absolute value of a number (the value without regard to whether it is positive or negative).\nFor example, the absolute value of -5 is the same as the absolute value of 5."},"parameters":[{"name":"x","description":"A numeric expression for which the absolute value is needed."}],"pyQName":"abs"},"Math.sign":{"kind":-3,"retType":"number","attributes":{"paramHelp":{"x":"The numeric expression to test"},"jsDoc":"Returns the sign of the x, indicating whether x is positive, negative or zero."},"parameters":[{"name":"x","description":"The numeric expression to test"}]},"Math.max":{"kind":-3,"retType":"number","attributes":{"blockId":"math_op2","help":"math/max","jsDoc":"Returns the larger of two supplied numeric expressions."},"parameters":[{"name":"a"},{"name":"b"}],"pyQName":"max"},"Math.min":{"kind":-3,"retType":"number","attributes":{"blockId":"math_op2","help":"math/min","jsDoc":"Returns the smaller of two supplied numeric expressions."},"parameters":[{"name":"a"},{"name":"b"}],"pyQName":"min"},"Math.roundWithPrecision":{"kind":-3,"retType":"number","attributes":{"paramHelp":{"x":"the number to round","digits":"the number of resulting digits"},"jsDoc":"Rounds ``x`` to a number with the given number of ``digits``"},"parameters":[{"name":"x","description":"the number to round"},{"name":"digits","description":"the number of resulting digits"}],"pyQName":"Math.round_with_precision"},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"__internal.__downUp":{"kind":-3,"retType":"boolean","attributes":{"shim":"TD_ID","blockHidden":true,"blockId":"toggleDownUp","block":"%down","paramFieldEditor":{"down":"toggledownup"},"paramFieldEditorOptions":{"down":{"decompileLiterals":"true"}},"jsDoc":"A shim to render a boolean as a down/up toggle","_def":{"parts":[{"kind":"param","name":"down","ref":false}],"parameters":[{"kind":"param","name":"down","ref":false}]}},"parameters":[{"name":"down","type":"boolean"}]},"__internal.__upDown":{"kind":-3,"retType":"boolean","attributes":{"shim":"TD_ID","blockHidden":true,"blockId":"toggleUpDown","block":"%up","paramFieldEditor":{"up":"toggleupdown"},"paramFieldEditorOptions":{"up":{"decompileLiterals":"true"}},"jsDoc":"A shim to render a boolean as a up/down toggle","_def":{"parts":[{"kind":"param","name":"up","ref":false}],"parameters":[{"kind":"param","name":"up","ref":false}]}},"parameters":[{"name":"up","type":"boolean"}]},"__internal.__highLow":{"kind":-3,"retType":"boolean","attributes":{"shim":"TD_ID","blockHidden":true,"blockId":"toggleHighLow","block":"%high","paramFieldEditor":{"high":"togglehighlow"},"paramFieldEditorOptions":{"high":{"decompileLiterals":"true"}},"jsDoc":"A shim to render a boolean as a high/low toggle","_def":{"parts":[{"kind":"param","name":"high","ref":false}],"parameters":[{"kind":"param","name":"high","ref":false}]}},"parameters":[{"name":"high","type":"boolean"}]},"__internal.__onOff":{"kind":-3,"retType":"boolean","attributes":{"shim":"TD_ID","blockHidden":true,"blockId":"toggleOnOff","block":"%on","paramFieldEditor":{"on":"toggleonoff"},"paramFieldEditorOptions":{"on":{"decompileLiterals":"true"}},"jsDoc":"A shim to render a boolean as a on/off toggle","_def":{"parts":[{"kind":"param","name":"on","ref":false}],"parameters":[{"kind":"param","name":"on","ref":false}]}},"parameters":[{"name":"on","type":"boolean"}]},"__internal.__yesNo":{"kind":-3,"retType":"boolean","attributes":{"shim":"TD_ID","blockHidden":true,"blockId":"toggleYesNo","block":"%yes","paramFieldEditor":{"yes":"toggleyesno"},"paramFieldEditorOptions":{"yes":{"decompileLiterals":"true"}},"jsDoc":"A shim to render a boolean as a yes/no toggle","_def":{"parts":[{"kind":"param","name":"yes","ref":false}],"parameters":[{"kind":"param","name":"yes","ref":false}]}},"parameters":[{"name":"yes","type":"boolean"}]},"__internal.__winLose":{"kind":-3,"retType":"boolean","attributes":{"shim":"TD_ID","blockHidden":true,"blockId":"toggleWinLose","block":"%win","paramFieldEditor":{"win":"togglewinlose"},"paramFieldEditorOptions":{"win":{"decompileLiterals":"true"}},"jsDoc":"A shim to render a boolean as a win/lose toggle","_def":{"parts":[{"kind":"param","name":"win","ref":false}],"parameters":[{"kind":"param","name":"win","ref":false}]}},"parameters":[{"name":"win","type":"boolean"}]},"__internal.__colorNumberPicker":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"value":"0xff0000"},"blockId":"colorNumberPicker","block":"%value","blockHidden":true,"shim":"TD_ID","colorSecondary":"#FFFFFF","paramFieldEditor":{"value":"colornumber"},"paramFieldEditorOptions":{"value":{"decompileLiterals":"true","colours":"[\"#ff0000\",\"#ff8000\",\"#ffff00\",\"#ff9da5\",\"#00ff00\",\"#b09eff\",\"#00ffff\",\"#007fff\",\"#65471f\",\"#0000ff\",\"#7f00ff\",\"#ff0080\",\"#ff00ff\",\"#ffffff\",\"#999999\",\"#000000\"]","columns":"4","className":"rgbColorPicker"}},"explicitDefaults":["value"],"paramHelp":{"color":"color"},"jsDoc":"Get the color wheel field editor","_def":{"parts":[{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","initializer":"0xff0000","default":"0xff0000"}]},"__internal.__colorWheelPicker":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"value":"10"},"blockId":"colorWheelPicker","block":"%value","blockHidden":true,"shim":"TD_ID","colorSecondary":"#FFFFFF","paramFieldEditor":{"value":"colorwheel"},"paramFieldEditorOptions":{"value":{"decompileLiterals":"true","sliderWidth":"200","min":"0","max":"255"}},"paramHelp":{"value":"value between 0 to 255 to get a color value, eg: 10"},"jsDoc":"Get the color wheel field editor","_def":{"parts":[{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","description":"value between 0 to 255 to get a color value, eg: 10","default":"10"}]},"__internal.__colorWheelHsvPicker":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"value":"10"},"blockId":"colorWheelHsvPicker","block":"%value","blockHidden":true,"shim":"TD_ID","colorSecondary":"#FFFFFF","paramFieldEditor":{"value":"colorwheel"},"paramFieldEditorOptions":{"value":{"decompileLiterals":"true","sliderWidth":"200","min":"0","max":"255","channel":"hsvfast"}},"paramHelp":{"value":"value between 0 to 255 to get a color value, eg: 10"},"jsDoc":"Get the color wheel field editor using HSV values","_def":{"parts":[{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","description":"value between 0 to 255 to get a color value, eg: 10","default":"10"}]},"__internal.__speedPicker":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"speed":"50"},"blockId":"speedPicker","block":"%speed","shim":"TD_ID","paramFieldEditor":{"speed":"speed"},"colorSecondary":"#FFFFFF","weight":0,"blockHidden":true,"paramFieldEditorOptions":{"speed":{"decompileLiterals":"1"}},"paramHelp":{"speed":"the speed, eg: 50"},"jsDoc":"A speed picker","_def":{"parts":[{"kind":"param","name":"speed","ref":false}],"parameters":[{"kind":"param","name":"speed","ref":false}]}},"parameters":[{"name":"speed","description":"the speed, eg: 50","default":"50"}]},"__internal.__turnRatioPicker":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"turnratio":"0"},"blockId":"turnRatioPicker","block":"%turnratio","shim":"TD_ID","paramFieldEditor":{"turnratio":"turnratio"},"colorSecondary":"#FFFFFF","weight":0,"blockHidden":true,"paramFieldEditorOptions":{"turnRatio":{"decompileLiterals":"1"}},"paramHelp":{"turnratio":"the turn ratio, eg: 0"},"jsDoc":"A turn ratio picker","_def":{"parts":[{"kind":"param","name":"turnratio","ref":false}],"parameters":[{"kind":"param","name":"turnratio","ref":false}]}},"parameters":[{"name":"turnratio","description":"the turn ratio, eg: 0","default":"0"}]},"__internal.__protractor":{"kind":-3,"retType":"number","attributes":{"blockId":"protractorPicker","block":"%angle","shim":"TD_ID","paramFieldEditor":{"angle":"protractor"},"paramFieldEditorOptions":{"angle":{"decompileLiterals":"1"}},"colorSecondary":"#FFFFFF","blockHidden":true,"jsDoc":"A field editor that displays a protractor","_def":{"parts":[{"kind":"param","name":"angle","ref":false}],"parameters":[{"kind":"param","name":"angle","ref":false}]}},"parameters":[{"name":"angle"}]},"__internal.__timePicker":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"ms":"500"},"blockId":"timePicker","block":"%ms","blockHidden":true,"shim":"TD_ID","colorSecondary":"#FFFFFF","paramFieldEditor":{"ms":"numberdropdown"},"paramFieldEditorOptions":{"ms":{"decompileLiterals":"true","data":"[[\"100 ms\", 100], [\"200 ms\", 200], [\"500 ms\", 500], [\"1 second\", 1000], [\"2 seconds\", 2000], [\"5 seconds\", 5000]]"}},"paramHelp":{"ms":"time duration in milliseconds, eg: 500, 1000"},"jsDoc":"Get the time field editor","_def":{"parts":[{"kind":"param","name":"ms","ref":false}],"parameters":[{"kind":"param","name":"ms","ref":false}]}},"parameters":[{"name":"ms","description":"time duration in milliseconds, eg: 500, 1000","default":"500"}]},"Fx8":{"kind":-3,"retType":"Fx8","parameters":[{"name":"v"}],"pyQName":"fx8"},"Fx8._dummyFx8":{"kind":2,"retType":"string","isInstance":true,"pyQName":"fx8._dummy_fx8"},"Fx8@type":{"kind":9,"retType":"Fx8","extendsTypes":[],"pyQName":"Fx8"},"Fx":{"kind":5,"retType":""},"Fx.zeroFx8":{"kind":4,"retType":"Fx8","pyQName":"Fx.zero_fx8"},"Fx.oneHalfFx8":{"kind":4,"retType":"Fx8","pyQName":"Fx.one_half_fx8"},"Fx.oneFx8":{"kind":4,"retType":"Fx8","pyQName":"Fx.one_fx8"},"Fx.twoFx8":{"kind":4,"retType":"Fx8","pyQName":"Fx.two_fx8"},"Fx.neg":{"kind":-3,"retType":"Fx8","parameters":[{"name":"a","type":"Fx8"}]},"Fx.toIntShifted":{"kind":-3,"retType":"number","parameters":[{"name":"a","type":"Fx8"},{"name":"n"}],"pyQName":"Fx.to_int_shifted"},"Fx.add":{"kind":-3,"retType":"Fx8","parameters":[{"name":"a","type":"Fx8"},{"name":"b","type":"Fx8"}]},"Fx.iadd":{"kind":-3,"retType":"Fx8","parameters":[{"name":"a"},{"name":"b","type":"Fx8"}]},"Fx.sub":{"kind":-3,"retType":"Fx8","parameters":[{"name":"a","type":"Fx8"},{"name":"b","type":"Fx8"}]},"Fx.mul":{"kind":-3,"retType":"Fx8","parameters":[{"name":"a","type":"Fx8"},{"name":"b","type":"Fx8"}]},"Fx.imul":{"kind":-3,"retType":"Fx8","parameters":[{"name":"a","type":"Fx8"},{"name":"b"}]},"Fx.div":{"kind":-3,"retType":"Fx8","parameters":[{"name":"a","type":"Fx8"},{"name":"b","type":"Fx8"}]},"Fx.idiv":{"kind":-3,"retType":"Fx8","parameters":[{"name":"a","type":"Fx8"},{"name":"b"}]},"Fx.compare":{"kind":-3,"retType":"number","parameters":[{"name":"a","type":"Fx8"},{"name":"b","type":"Fx8"}]},"Fx.abs":{"kind":-3,"retType":"Fx8","parameters":[{"name":"a","type":"Fx8"}]},"Fx.min":{"kind":-3,"retType":"Fx8","parameters":[{"name":"a","type":"Fx8"},{"name":"b","type":"Fx8"}]},"Fx.max":{"kind":-3,"retType":"Fx8","parameters":[{"name":"a","type":"Fx8"},{"name":"b","type":"Fx8"}]},"Fx.floor":{"kind":-3,"retType":"Fx8","parameters":[{"name":"v","type":"Fx8"}]},"Fx.ceil":{"kind":-3,"retType":"Fx8","parameters":[{"name":"v","type":"Fx8"}]},"Fx.leftShift":{"kind":-3,"retType":"Fx8","parameters":[{"name":"a","type":"Fx8"},{"name":"n"}],"pyQName":"Fx.left_shift"},"Fx.rightShift":{"kind":-3,"retType":"Fx8","parameters":[{"name":"a","type":"Fx8"},{"name":"n"}],"pyQName":"Fx.right_shift"},"Fx.toInt":{"kind":-3,"retType":"number","parameters":[{"name":"v","type":"Fx8"}],"pyQName":"Fx.to_int"},"Fx.toFloat":{"kind":-3,"retType":"number","parameters":[{"name":"v","type":"Fx8"}],"pyQName":"Fx.to_float"},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"pins.sizeOf":{"kind":-3,"retType":"number","attributes":{"deprecated":"1"},"parameters":[{"name":"format","type":"NumberFormat","isEnum":true}],"pyQName":"pins.size_of"},"pins.createBufferFromArray":{"kind":-3,"retType":"Buffer","attributes":{"deprecated":"1"},"parameters":[{"name":"bytes","type":"number[]"}],"pyQName":"bytes"},"pins.packedSize":{"kind":-3,"retType":"number","attributes":{"deprecated":"1"},"parameters":[{"name":"format","type":"string"}],"pyQName":"pins.packed_size"},"pins.packBuffer":{"kind":-3,"retType":"Buffer","attributes":{"deprecated":"1"},"parameters":[{"name":"format","type":"string"},{"name":"nums","type":"number[]"}],"pyQName":"pins.pack_buffer"},"pins.packIntoBuffer":{"kind":-3,"attributes":{"deprecated":"1"},"parameters":[{"name":"format","type":"string"},{"name":"buf","type":"Buffer"},{"name":"offset"},{"name":"nums","type":"number[]"}],"pyQName":"pins.pack_into_buffer"},"pins.unpackBuffer":{"kind":-3,"retType":"number[]","attributes":{"deprecated":"1"},"parameters":[{"name":"format","type":"string"},{"name":"buf","type":"Buffer"},{"name":"offset","initializer":"0"}],"pyQName":"pins.unpack_buffer"},"pins.concatBuffers":{"kind":-3,"retType":"Buffer","attributes":{"deprecated":"1"},"parameters":[{"name":"bufs","type":"Buffer[]"}],"pyQName":"pins.concat_buffers"},"msgpack":{"kind":5,"retType":""},"msgpack.unpackNumberArray":{"kind":-3,"retType":"number[]","attributes":{"jsDoc":"Unpacks a buffer into a number array."},"parameters":[{"name":"buf","type":"Buffer"},{"name":"offset","initializer":"0"}],"pyQName":"msgpack.unpack_number_array"},"msgpack.packNumberArray":{"kind":-3,"retType":"Buffer","attributes":{"paramHelp":{"nums":"the numbers to be packed"},"jsDoc":"Pack a number array into a buffer."},"parameters":[{"name":"nums","description":"the numbers to be packed","type":"number[]"}],"pyQName":"msgpack.pack_number_array"},"helpers.bufferConcat":{"kind":-3,"retType":"Buffer","parameters":[{"name":"a","type":"Buffer"},{"name":"b","type":"Buffer"}],"pyQName":"helpers.buffer_concat"},"helpers.bufferEquals":{"kind":-3,"retType":"boolean","parameters":[{"name":"l","type":"Buffer"},{"name":"r","type":"Buffer"}],"pyQName":"helpers.buffer_equals"},"helpers.bufferIndexOf":{"kind":-3,"retType":"number","parameters":[{"name":"a","type":"Buffer"},{"name":"b","type":"Buffer"}],"pyQName":"helpers.buffer_index_of"},"helpers.bufferUnpack":{"kind":-3,"retType":"number[]","parameters":[{"name":"buf","type":"Buffer"},{"name":"format","type":"string"},{"name":"offset","initializer":"undefined"}],"pyQName":"helpers.buffer_unpack"},"helpers.bufferPackAt":{"kind":-3,"parameters":[{"name":"buf","type":"Buffer"},{"name":"offset"},{"name":"format","type":"string"},{"name":"nums","type":"number[]"}],"pyQName":"helpers.buffer_pack_at"},"helpers.bufferChunked":{"kind":-3,"retType":"Buffer[]","parameters":[{"name":"buf","type":"Buffer"},{"name":"maxBytes"}],"pyQName":"helpers.buffer_chunked"},"helpers.bufferToArray":{"kind":-3,"retType":"number[]","parameters":[{"name":"buf","type":"Buffer"},{"name":"format","type":"NumberFormat","isEnum":true}],"pyQName":"helpers.buffer_to_array"},"helpers._b64":{"kind":4,"retType":"\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\""},"helpers.bufferToBase64":{"kind":-3,"retType":"string","parameters":[{"name":"buf","type":"Buffer"}],"pyQName":"helpers.buffer_to_base64"},"Buffer":{"kind":5,"retType":""},"Buffer.concat":{"kind":-3,"retType":"Buffer","attributes":{"helper":"bufferConcat","jsDoc":"Return concatenation of current buffer and the given buffer\n\nConcatenates all buffers in the list"},"parameters":[{"name":"buffers","type":"Buffer[]"}]},"Buffer.indexOf":{"kind":-1,"retType":"number","attributes":{"helper":"bufferIndexOf","jsDoc":"Return position of other buffer in current buffer"},"parameters":[{"name":"other","type":"Buffer"}],"isInstance":true,"pyQName":"Buffer.index_of"},"Buffer.unpack":{"kind":-1,"retType":"number[]","attributes":{"helper":"bufferUnpack","jsDoc":"Reads numbers from the buffer according to the format"},"parameters":[{"name":"format","type":"string"},{"name":"offset","initializer":"undefined"}],"isInstance":true},"Buffer.packAt":{"kind":-1,"attributes":{"helper":"bufferPackAt","jsDoc":"Writes numbers to the buffer according to the format"},"parameters":[{"name":"offset"},{"name":"format","type":"string"},{"name":"nums","type":"number[]"}],"isInstance":true,"pyQName":"Buffer.pack_at"},"Buffer.equals":{"kind":-1,"retType":"boolean","attributes":{"helper":"bufferEquals","jsDoc":"Returns true if this and the other buffer hold the same data"},"parameters":[{"name":"other","type":"Buffer"}],"isInstance":true},"Buffer.chunked":{"kind":-1,"retType":"Buffer[]","attributes":{"helper":"bufferChunked","jsDoc":"Splits buffer into parts no larger than specified"},"parameters":[{"name":"maxSize"}],"isInstance":true},"Buffer.toArray":{"kind":-1,"retType":"number[]","attributes":{"helper":"bufferToArray","jsDoc":"Read contents of buffer as an array in specified format"},"parameters":[{"name":"format","type":"NumberFormat","isEnum":true}],"isInstance":true,"pyQName":"Buffer.to_array"},"Buffer.toBase64":{"kind":-1,"retType":"string","attributes":{"helper":"bufferToBase64","jsDoc":"Convert buffer to ASCII base64 encoding."},"parameters":[],"isInstance":true,"pyQName":"Buffer.to_base64"},"Buffer@type":{"kind":9,"retType":"Buffer","attributes":{"indexerGet":"BufferMethods::getByte","indexerSet":"BufferMethods::setByte"},"extendsTypes":[],"pyQName":"Buffer"},"Buffer.create":{"kind":-3,"retType":"Buffer","attributes":{"paramHelp":{"size":"number of bytes in the buffer"},"jsDoc":"Allocate a new buffer."},"parameters":[{"name":"size","description":"number of bytes in the buffer"}]},"Buffer.fromHex":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"Create a new buffer, decoding a hex string"},"parameters":[{"name":"hex","type":"string"}],"pyQName":"Buffer.from_hex"},"Buffer.fromBase64":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"Create a new buffer, decoding a Base64 string"},"parameters":[{"name":"b64","type":"string"}],"pyQName":"Buffer.from_base64"},"Buffer.fromUTF8":{"kind":-3,"retType":"Buffer","attributes":{"paramHelp":{"str":"the string to put in the buffer"},"jsDoc":"Create a new buffer from an UTF8-encoded string"},"parameters":[{"name":"str","description":"the string to put in the buffer","type":"string"}],"pyQName":"Buffer.from_utf8"},"Buffer.chunkedFromUTF8":{"kind":-3,"retType":"Buffer[]","parameters":[{"name":"str","type":"string"},{"name":"maxBytes"}],"pyQName":"Buffer.chunked_from_utf8"},"Buffer.fromArray":{"kind":-3,"retType":"Buffer","attributes":{"paramHelp":{"bytes":"data to initialize with"},"jsDoc":"Create a new buffer initialized to bytes from given array."},"parameters":[{"name":"bytes","description":"data to initialize with","type":"number[]"}],"pyQName":"Buffer.from_array"},"Buffer.packedSize":{"kind":-3,"retType":"number","parameters":[{"name":"format","type":"string"}],"pyQName":"Buffer.packed_size"},"Buffer.pack":{"kind":-3,"retType":"Buffer","parameters":[{"name":"format","type":"string"},{"name":"nums","type":"number[]"}]},"Buffer.__packUnpackCore":{"kind":-3,"retType":"number","parameters":[{"name":"format","type":"string"},{"name":"nums","type":"number[]"},{"name":"buf","type":"Buffer"},{"name":"isPack","type":"boolean"},{"name":"off","initializer":"0"}]},"Buffer.sizeOfNumberFormat":{"kind":-3,"retType":"number","attributes":{"jsDoc":"Get the size in bytes of specified number format."},"parameters":[{"name":"format","type":"NumberFormat","isEnum":true}],"pyQName":"Buffer.size_of_number_format"},"Buffer.getUint8":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Reads an unsigned byte at a particular location"},"parameters":[{"name":"off"}],"isInstance":true,"pyQName":"Buffer.get_uint8"},"Buffer.isReadOnly":{"kind":-1,"retType":"boolean","attributes":{"jsDoc":"Returns false when the buffer can be written to."},"parameters":[],"isInstance":true,"pyQName":"Buffer.is_read_only"},"Buffer.setUint8":{"kind":-1,"attributes":{"jsDoc":"Writes an unsigned byte at a particular location"},"parameters":[{"name":"off"},{"name":"v"}],"isInstance":true,"pyQName":"Buffer.set_uint8"},"Buffer.setNumber":{"kind":-1,"attributes":{"jsDoc":"Write a number in specified format in the buffer."},"parameters":[{"name":"format","type":"NumberFormat","isEnum":true},{"name":"offset"},{"name":"value"}],"isInstance":true,"pyQName":"Buffer.set_number"},"Buffer.getNumber":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Read a number in specified format from the buffer."},"parameters":[{"name":"format","type":"NumberFormat","isEnum":true},{"name":"offset"}],"isInstance":true,"pyQName":"Buffer.get_number"},"Buffer.length":{"kind":2,"retType":"number","attributes":{"property":"true","jsDoc":"Returns the length of a Buffer object."},"isInstance":true},"Buffer.fill":{"kind":-1,"attributes":{"paramDefl":{"offset":"0","length":"-1"},"explicitDefaults":["offset","length"],"jsDoc":"Fill (a fragment) of the buffer with given value."},"parameters":[{"name":"value"},{"name":"offset","initializer":"0","default":"0"},{"name":"length","initializer":"-1","default":"-1"}],"isInstance":true},"Buffer.slice":{"kind":-1,"retType":"Buffer","attributes":{"paramDefl":{"offset":"0","length":"-1"},"explicitDefaults":["offset","length"],"jsDoc":"Return a copy of a fragment of a buffer."},"parameters":[{"name":"offset","initializer":"0","default":"0"},{"name":"length","initializer":"-1","default":"-1"}],"isInstance":true},"Buffer.shift":{"kind":-1,"attributes":{"paramDefl":{"start":"0","length":"-1"},"explicitDefaults":["start","length"],"paramHelp":{"offset":"number of bytes to shift; use negative value to shift right","start":"start offset in buffer. Default is 0.","length":"number of elements in buffer. If negative, length is set as the buffer length minus"},"jsDoc":"Shift buffer left in place, with zero padding.\n\n\n\nstart. eg: -1"},"parameters":[{"name":"offset","description":"number of bytes to shift; use negative value to shift right"},{"name":"start","description":"start offset in buffer. Default is 0.","initializer":"0","default":"0"},{"name":"length","description":"number of elements in buffer. If negative, length is set as the buffer length minus","initializer":"-1","default":"-1"}],"isInstance":true},"Buffer.toString":{"kind":-1,"retType":"string","attributes":{"jsDoc":"Convert a buffer to string assuming UTF8 encoding"},"parameters":[],"isInstance":true,"pyQName":"Buffer.to_string"},"Buffer.toHex":{"kind":-1,"retType":"string","attributes":{"jsDoc":"Convert a buffer to its hexadecimal representation."},"parameters":[],"isInstance":true,"pyQName":"Buffer.to_hex"},"Buffer.rotate":{"kind":-1,"attributes":{"paramDefl":{"start":"0","length":"-1"},"explicitDefaults":["start","length"],"paramHelp":{"offset":"number of bytes to shift; use negative value to shift right","start":"start offset in buffer. Default is 0.","length":"number of elements in buffer. If negative, length is set as the buffer length minus"},"jsDoc":"Rotate buffer left in place.\n\n\n\nstart. eg: -1"},"parameters":[{"name":"offset","description":"number of bytes to shift; use negative value to shift right"},{"name":"start","description":"start offset in buffer. Default is 0.","initializer":"0","default":"0"},{"name":"length","description":"number of elements in buffer. If negative, length is set as the buffer length minus","initializer":"-1","default":"-1"}],"isInstance":true},"Buffer.write":{"kind":-1,"attributes":{"jsDoc":"Write contents of `src` at `dstOffset` in current buffer."},"parameters":[{"name":"dstOffset"},{"name":"src","type":"Buffer"}],"isInstance":true},"Buffer.hash":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Compute k-bit FNV-1 non-cryptographic hash of the buffer."},"parameters":[{"name":"bits"}],"isInstance":true},"control.createBuffer":{"kind":-3,"retType":"Buffer","attributes":{"deprecated":"1","paramHelp":{"size":"number of bytes in the buffer"},"jsDoc":"Create a new zero-initialized buffer."},"parameters":[{"name":"size","description":"number of bytes in the buffer"}],"pyQName":"bytearray"},"control.createBufferFromUTF8":{"kind":-3,"retType":"Buffer","attributes":{"deprecated":"1","paramHelp":{"str":"the string to put in the buffer"},"jsDoc":"Create a new buffer with UTF8-encoded string"},"parameters":[{"name":"str","description":"the string to put in the buffer","type":"string"}],"pyQName":"control.create_buffer_from_utf8"},"loops":{"kind":5,"retType":""},"loops.forever":{"kind":-3,"attributes":{"help":"loops/forever","weight":100,"afterOnStart":true,"deprecated":"true","blockId":"forever_deprecated","block":"forever","blockAllowMultiple":"1","paramHelp":{"body":"code to execute"},"jsDoc":"Repeats the code forever in the background. On each iteration, allows other codes to run.","_def":{"parts":[{"kind":"label","text":"forever","style":[]}],"parameters":[]}},"parameters":[{"name":"a","type":"() => void","handlerParameters":[]}]},"loops.pause":{"kind":-3,"attributes":{"paramDefl":{"ms":"100"},"callingConvention":1,"help":"loops/pause","weight":99,"deprecated":"true","async":"true","block":"pause %pause=timePicker|ms","blockId":"device_pause_deprecated","paramHelp":{"ms":"how long to pause for, eg: 100, 200, 500, 1000, 2000"},"jsDoc":"Pause for the specified time in milliseconds","_def":{"parts":[{"kind":"label","text":"pause ","style":[]},{"kind":"param","name":"pause","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"pause","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"ms","description":"how long to pause for, eg: 100, 200, 500, 1000, 2000","default":"100"}]},"control.millis":{"kind":-3,"retType":"number","attributes":{"help":"control/millis","weight":50,"blockId":"control_running_time","block":"millis (ms)","jsDoc":"Gets the number of milliseconds elapsed since power on.","_def":{"parts":[{"kind":"label","text":"millis (ms)","style":[]}],"parameters":[]}},"parameters":[]},"control.micros":{"kind":-3,"retType":"number","attributes":{"jsDoc":"Gets current time in microseconds. Overflows every ~18 minutes."},"parameters":[]},"control.internalOnEvent":{"kind":-3,"attributes":{"paramDefl":{"flags":"16"},"explicitDefaults":["flags"],"jsDoc":"Used internally"},"parameters":[{"name":"src"},{"name":"value"},{"name":"handler","type":"() => void","handlerParameters":[]},{"name":"flags","initializer":"16","default":"16"}],"pyQName":"control.internal_on_event"},"control.reset":{"kind":-3,"attributes":{"callingConvention":1,"weight":30,"async":"true","help":"control/reset","blockGap":"8","blockId":"control_reset","block":"reset","jsDoc":"Reset the device.","_def":{"parts":[{"kind":"label","text":"reset","style":[]}],"parameters":[]}},"parameters":[]},"control.waitMicros":{"kind":-3,"attributes":{"paramDefl":{"micros":"4"},"callingConvention":1,"help":"control/wait-micros","weight":29,"async":"true","blockId":"control_wait_us","block":"wait (µs)%micros","paramHelp":{"micros":"number of micro-seconds to wait. eg: 4"},"jsDoc":"Block the current fiber for the given microseconds","_def":{"parts":[{"kind":"label","text":"wait (µs)","style":[]},{"kind":"param","name":"micros","ref":false}],"parameters":[{"kind":"param","name":"micros","ref":false}]}},"parameters":[{"name":"micros","description":"number of micro-seconds to wait. eg: 4","default":"4"}],"pyQName":"control.wait_micros"},"control.runInParallel":{"kind":-3,"attributes":{"help":"control/run-in-parallel","handlerStatement":true,"blockId":"control_run_in_parallel","block":"run in parallel","blockGap":"8","jsDoc":"Run other code in the parallel.","_def":{"parts":[{"kind":"label","text":"run in parallel","style":[]}],"parameters":[]}},"parameters":[{"name":"a","type":"() => void","handlerParameters":[]}],"pyQName":"control.run_in_parallel"},"control.waitForEvent":{"kind":-3,"attributes":{"callingConvention":1,"help":"control/wait-for-event","async":"true","blockId":"control_wait_for_event","block":"wait for event|from %src|with value %value","jsDoc":"Blocks the calling thread until the specified event is raised.","_def":{"parts":[{"kind":"label","text":"wait for event","style":[]},{"kind":"break"},{"kind":"label","text":"from ","style":[]},{"kind":"param","name":"src","ref":false},{"kind":"break"},{"kind":"label","text":"with value ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"src","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"src"},{"name":"value"}],"pyQName":"control.wait_for_event"},"control.deviceSerialNumber":{"kind":-3,"retType":"number","attributes":{"blockId":"control_device_serial_number","block":"device serial number","weight":9,"help":"control/device-serial-number","jsDoc":"Derive a unique, consistent serial number of this device from internal data.","_def":{"parts":[{"kind":"label","text":"device serial number","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"control.device_serial_number"},"control.deviceLongSerialNumber":{"kind":-3,"retType":"Buffer","attributes":{"blockId":"control_device_long_serial_number","block":"device long serial number","weight":9,"help":"control/device-long-serial-number","jsDoc":"Derive a unique, consistent 64-bit serial number of this device from internal data.","_def":{"parts":[{"kind":"label","text":"device long serial number","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"control.device_long_serial_number"},"control.__log":{"kind":-3,"parameters":[{"name":"prority"},{"name":"text","type":"string"}]},"control.dmesgValue":{"kind":-3,"attributes":{"jsDoc":"Dump internal information about a value."},"parameters":[{"name":"v","type":"any"}],"pyQName":"control.dmesg_value"},"control.gc":{"kind":-3,"attributes":{"jsDoc":"Force GC and dump basic information about heap."},"parameters":[]},"control.heapDump":{"kind":-3,"attributes":{"jsDoc":"Force GC and halt waiting for debugger to do a full heap dump."},"parameters":[],"pyQName":"control.heap_dump"},"control.setDebugFlags":{"kind":-3,"attributes":{"jsDoc":"Set flags used when connecting an external debugger."},"parameters":[{"name":"flags"}],"pyQName":"control.set_debug_flags"},"control.heapSnapshot":{"kind":-3,"attributes":{"jsDoc":"Record a heap snapshot to debug memory leaks."},"parameters":[],"pyQName":"control.heap_snapshot"},"control.profilingEnabled":{"kind":-3,"retType":"boolean","attributes":{"jsDoc":"Return true if profiling is enabled in the current build."},"parameters":[],"pyQName":"control.profiling_enabled"},"NumberFormat":{"kind":6,"retType":"NumberFormat","extendsTypes":["NumberFormat","Number"]},"NumberFormat.Int8LE":{"retType":"NumberFormat.Int8LE","extendsTypes":["NumberFormat.Int8LE","Number"],"pyQName":"NumberFormat.INT8_LE"},"NumberFormat.UInt8LE":{"retType":"NumberFormat.UInt8LE","extendsTypes":["NumberFormat.UInt8LE","Number"],"pyQName":"NumberFormat.UINT8_LE"},"NumberFormat.Int16LE":{"retType":"NumberFormat.Int16LE","extendsTypes":["NumberFormat.Int16LE","Number"],"pyQName":"NumberFormat.INT16_LE"},"NumberFormat.UInt16LE":{"retType":"NumberFormat.UInt16LE","extendsTypes":["NumberFormat.UInt16LE","Number"],"pyQName":"NumberFormat.UINT16_LE"},"NumberFormat.Int32LE":{"retType":"NumberFormat.Int32LE","extendsTypes":["NumberFormat.Int32LE","Number"],"pyQName":"NumberFormat.INT32_LE"},"NumberFormat.Int8BE":{"retType":"NumberFormat.Int8BE","extendsTypes":["NumberFormat.Int8BE","Number"],"pyQName":"NumberFormat.INT8_BE"},"NumberFormat.UInt8BE":{"retType":"NumberFormat.UInt8BE","extendsTypes":["NumberFormat.UInt8BE","Number"],"pyQName":"NumberFormat.UINT8_BE"},"NumberFormat.Int16BE":{"retType":"NumberFormat.Int16BE","extendsTypes":["NumberFormat.Int16BE","Number"],"pyQName":"NumberFormat.INT16_BE"},"NumberFormat.UInt16BE":{"retType":"NumberFormat.UInt16BE","extendsTypes":["NumberFormat.UInt16BE","Number"],"pyQName":"NumberFormat.UINT16_BE"},"NumberFormat.Int32BE":{"retType":"NumberFormat.Int32BE","extendsTypes":["NumberFormat.Int32BE","Number"],"pyQName":"NumberFormat.INT32_BE"},"NumberFormat.UInt32LE":{"retType":"NumberFormat.UInt32LE","extendsTypes":["NumberFormat.UInt32LE","Number"],"pyQName":"NumberFormat.UINT32_LE"},"NumberFormat.UInt32BE":{"retType":"NumberFormat.UInt32BE","extendsTypes":["NumberFormat.UInt32BE","Number"],"pyQName":"NumberFormat.UINT32_BE"},"NumberFormat.Float32LE":{"retType":"NumberFormat.Float32LE","extendsTypes":["NumberFormat.Float32LE","Number"],"pyQName":"NumberFormat.FLOAT32_LE"},"NumberFormat.Float64LE":{"retType":"NumberFormat.Float64LE","extendsTypes":["NumberFormat.Float64LE","Number"],"pyQName":"NumberFormat.FLOAT64_LE"},"NumberFormat.Float32BE":{"retType":"NumberFormat.Float32BE","extendsTypes":["NumberFormat.Float32BE","Number"],"pyQName":"NumberFormat.FLOAT32_BE"},"NumberFormat.Float64BE":{"retType":"NumberFormat.Float64BE","extendsTypes":["NumberFormat.Float64BE","Number"],"pyQName":"NumberFormat.FLOAT64_BE"},"PerfCounters":{"kind":6,"retType":"PerfCounters","extendsTypes":["PerfCounters","Number"]},"PerfCounters.GC":{"retType":"PerfCounters","extendsTypes":["PerfCounters.GC","Number"]},"Math.E":{"kind":4,"retType":"number"},"Math.LN2":{"kind":4,"retType":"number"},"Math.LN10":{"kind":4,"retType":"number"},"Math.LOG2E":{"kind":4,"retType":"number"},"Math.LOG10E":{"kind":4,"retType":"number"},"Math.PI":{"kind":4,"retType":"number"},"Math.SQRT1_2":{"kind":4,"retType":"number"},"Math.SQRT2":{"kind":4,"retType":"number"},"Math.map":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"fromHigh":"1023","toHigh":"4"},"help":"math/map","weight":10,"blockGap":"8","blockId":"math_map","block":"map %value|from low %fromLow|high %fromHigh|to low %toLow|high %toHigh","inlineInputMode":"inline","paramHelp":{"value":"value to map in ranges","fromLow":"the lower bound of the value's current range","fromHigh":"the upper bound of the value's current range, eg: 1023","toLow":"the lower bound of the value's target range","toHigh":"the upper bound of the value's target range, eg: 4"},"jsDoc":"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.","_def":{"parts":[{"kind":"label","text":"map ","style":[]},{"kind":"param","name":"value","ref":false},{"kind":"break"},{"kind":"label","text":"from low ","style":[]},{"kind":"param","name":"fromLow","ref":false},{"kind":"break"},{"kind":"label","text":"high ","style":[]},{"kind":"param","name":"fromHigh","ref":false},{"kind":"break"},{"kind":"label","text":"to low ","style":[]},{"kind":"param","name":"toLow","ref":false},{"kind":"break"},{"kind":"label","text":"high ","style":[]},{"kind":"param","name":"toHigh","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false},{"kind":"param","name":"fromLow","ref":false},{"kind":"param","name":"fromHigh","ref":false},{"kind":"param","name":"toLow","ref":false},{"kind":"param","name":"toHigh","ref":false}]}},"parameters":[{"name":"value","description":"value to map in ranges"},{"name":"fromLow","description":"the lower bound of the value's current range"},{"name":"fromHigh","description":"the upper bound of the value's current range, eg: 1023","default":"1023"},{"name":"toLow","description":"the lower bound of the value's target range"},{"name":"toHigh","description":"the upper bound of the value's target range, eg: 4","default":"4"}]},"Math.constrain":{"kind":-3,"retType":"number","attributes":{"help":"math/constrain","weight":11,"blockGap":"8","blockId":"math_constrain_value","block":"constrain %value|between %low|and %high","paramHelp":{"x":"the number to constrain, all data types","y":"the lower end of the range, all data types","z":"the upper end of the range, all data types"},"jsDoc":"Constrains a number to be within a range","_def":{"parts":[{"kind":"label","text":"constrain ","style":[]},{"kind":"param","name":"value","ref":false},{"kind":"break"},{"kind":"label","text":"between ","style":[]},{"kind":"param","name":"low","ref":false},{"kind":"break"},{"kind":"label","text":"and ","style":[]},{"kind":"param","name":"high","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false},{"kind":"param","name":"low","ref":false},{"kind":"param","name":"high","ref":false}]}},"parameters":[{"name":"value"},{"name":"low"},{"name":"high"}]},"Math.isin":{"kind":-3,"retType":"number","attributes":{"help":"math/isin","weight":11,"advanced":true,"blockGap":"8","paramHelp":{"theta":"input angle from 0-255"},"jsDoc":"Returns the sine of an input angle. This is an 8-bit approximation."},"parameters":[{"name":"theta","description":"input angle from 0-255"}]},"Math.icos":{"kind":-3,"retType":"number","attributes":{"help":"math/icos","weight":10,"advanced":true,"blockGap":"8","paramHelp":{"theta":"input angle from 0-255"},"jsDoc":"Returns the cosine of an input angle. This is an 8-bit approximation."},"parameters":[{"name":"theta","description":"input angle from 0-255"}]},"Number.EPSILON":{"kind":4,"retType":"number"},"input":{"kind":5,"retType":"","attributes":{"color":"#B4009E","weight":98,"icon":"","groups":["other","More"],"jsDoc":"Respond to and read data from buttons and sensors.\n\nEvents and data from sensors."}},"control.runInBackground":{"kind":-3,"attributes":{"deprecated":"1","hidden":"1","help":"control/run-in-background","blockAllowMultiple":"1","afterOnStart":true,"blockId":"control_run_in_background","block":"run in background","blockGap":"8","weight":0,"jsDoc":"Deprecated, use ``control.runInParallel`` instead.","_def":{"parts":[{"kind":"label","text":"run in background","style":[]}],"parameters":[]}},"parameters":[{"name":"a","type":"() => void","handlerParameters":[]}],"pyQName":"control.run_in_background"},"control.PXT_PANIC":{"kind":6,"retType":"control.PXT_PANIC","extendsTypes":["control.PXT_PANIC","Number"]},"control.PXT_PANIC.CODAL_OOM":{"retType":"control.PXT_PANIC.CODAL_OOM","extendsTypes":["control.PXT_PANIC.CODAL_OOM","Number"]},"control.PXT_PANIC.GC_OOM":{"retType":"control.PXT_PANIC.GC_OOM","extendsTypes":["control.PXT_PANIC.GC_OOM","Number"]},"control.PXT_PANIC.GC_TOO_BIG_ALLOCATION":{"retType":"control.PXT_PANIC.GC_TOO_BIG_ALLOCATION","extendsTypes":["control.PXT_PANIC.GC_TOO_BIG_ALLOCATION","Number"]},"control.PXT_PANIC.CODAL_HEAP_ERROR":{"retType":"control.PXT_PANIC.CODAL_HEAP_ERROR","extendsTypes":["control.PXT_PANIC.CODAL_HEAP_ERROR","Number"]},"control.PXT_PANIC.CODAL_NULL_DEREFERENCE":{"retType":"control.PXT_PANIC.CODAL_NULL_DEREFERENCE","extendsTypes":["control.PXT_PANIC.CODAL_NULL_DEREFERENCE","Number"]},"control.PXT_PANIC.CODAL_USB_ERROR":{"retType":"control.PXT_PANIC.CODAL_USB_ERROR","extendsTypes":["control.PXT_PANIC.CODAL_USB_ERROR","Number"]},"control.PXT_PANIC.CODAL_HARDWARE_CONFIGURATION_ERROR":{"retType":"control.PXT_PANIC.CODAL_HARDWARE_CONFIGURATION_ERROR","extendsTypes":["control.PXT_PANIC.CODAL_HARDWARE_CONFIGURATION_ERROR","Number"]},"control.PXT_PANIC.INVALID_BINARY_HEADER":{"retType":"control.PXT_PANIC.INVALID_BINARY_HEADER","extendsTypes":["control.PXT_PANIC.INVALID_BINARY_HEADER","Number"]},"control.PXT_PANIC.OUT_OF_BOUNDS":{"retType":"control.PXT_PANIC.OUT_OF_BOUNDS","extendsTypes":["control.PXT_PANIC.OUT_OF_BOUNDS","Number"]},"control.PXT_PANIC.REF_DELETED":{"retType":"control.PXT_PANIC.REF_DELETED","extendsTypes":["control.PXT_PANIC.REF_DELETED","Number"]},"control.PXT_PANIC.SIZE":{"retType":"control.PXT_PANIC.SIZE","extendsTypes":["control.PXT_PANIC.SIZE","Number"]},"control.PXT_PANIC.INVALID_VTABLE":{"retType":"control.PXT_PANIC.INVALID_VTABLE","extendsTypes":["control.PXT_PANIC.INVALID_VTABLE","Number"]},"control.PXT_PANIC.INTERNAL_ERROR":{"retType":"control.PXT_PANIC.INTERNAL_ERROR","extendsTypes":["control.PXT_PANIC.INTERNAL_ERROR","Number"]},"control.PXT_PANIC.NO_SUCH_CONFIG":{"retType":"control.PXT_PANIC.NO_SUCH_CONFIG","extendsTypes":["control.PXT_PANIC.NO_SUCH_CONFIG","Number"]},"control.PXT_PANIC.NO_SUCH_PIN":{"retType":"control.PXT_PANIC.NO_SUCH_PIN","extendsTypes":["control.PXT_PANIC.NO_SUCH_PIN","Number"]},"control.PXT_PANIC.INVALID_ARGUMENT":{"retType":"control.PXT_PANIC.INVALID_ARGUMENT","extendsTypes":["control.PXT_PANIC.INVALID_ARGUMENT","Number"]},"control.PXT_PANIC.MEMORY_LIMIT_EXCEEDED":{"retType":"control.PXT_PANIC.MEMORY_LIMIT_EXCEEDED","extendsTypes":["control.PXT_PANIC.MEMORY_LIMIT_EXCEEDED","Number"]},"control.PXT_PANIC.SCREEN_ERROR":{"retType":"control.PXT_PANIC.SCREEN_ERROR","extendsTypes":["control.PXT_PANIC.SCREEN_ERROR","Number"]},"control.PXT_PANIC.MISSING_PROPERTY":{"retType":"control.PXT_PANIC.MISSING_PROPERTY","extendsTypes":["control.PXT_PANIC.MISSING_PROPERTY","Number"]},"control.PXT_PANIC.INVALID_IMAGE":{"retType":"control.PXT_PANIC.INVALID_IMAGE","extendsTypes":["control.PXT_PANIC.INVALID_IMAGE","Number"]},"control.PXT_PANIC.CALLED_FROM_ISR":{"retType":"control.PXT_PANIC.CALLED_FROM_ISR","extendsTypes":["control.PXT_PANIC.CALLED_FROM_ISR","Number"]},"control.PXT_PANIC.HEAP_DUMPED":{"retType":"control.PXT_PANIC.HEAP_DUMPED","extendsTypes":["control.PXT_PANIC.HEAP_DUMPED","Number"]},"control.PXT_PANIC.STACK_OVERFLOW":{"retType":"control.PXT_PANIC.STACK_OVERFLOW","extendsTypes":["control.PXT_PANIC.STACK_OVERFLOW","Number"]},"control.PXT_PANIC.BLOCKING_TO_STRING":{"retType":"control.PXT_PANIC.BLOCKING_TO_STRING","extendsTypes":["control.PXT_PANIC.BLOCKING_TO_STRING","Number"]},"control.PXT_PANIC.VM_ERROR":{"retType":"control.PXT_PANIC.VM_ERROR","extendsTypes":["control.PXT_PANIC.VM_ERROR","Number"]},"control.PXT_PANIC.SETTINGS_CLEARED":{"retType":"control.PXT_PANIC.SETTINGS_CLEARED","extendsTypes":["control.PXT_PANIC.SETTINGS_CLEARED","Number"]},"control.PXT_PANIC.SETTINGS_OVERLOAD":{"retType":"control.PXT_PANIC.SETTINGS_OVERLOAD","extendsTypes":["control.PXT_PANIC.SETTINGS_OVERLOAD","Number"]},"control.PXT_PANIC.SETTINGS_SECRET_MISSING":{"retType":"control.PXT_PANIC.SETTINGS_SECRET_MISSING","extendsTypes":["control.PXT_PANIC.SETTINGS_SECRET_MISSING","Number"]},"control.PXT_PANIC.DELETE_ON_CLASS":{"retType":"control.PXT_PANIC.DELETE_ON_CLASS","extendsTypes":["control.PXT_PANIC.DELETE_ON_CLASS","Number"]},"control.PXT_PANIC.CAST_FIRST":{"retType":"control.PXT_PANIC.CAST_FIRST","extendsTypes":["control.PXT_PANIC.CAST_FIRST","Number"]},"control.PXT_PANIC.CAST_FROM_UNDEFINED":{"retType":"control.PXT_PANIC.CAST_FIRST","extendsTypes":["control.PXT_PANIC.CAST_FROM_UNDEFINED","Number"]},"control.PXT_PANIC.CAST_FROM_BOOLEAN":{"retType":"control.PXT_PANIC.CAST_FROM_BOOLEAN","extendsTypes":["control.PXT_PANIC.CAST_FROM_BOOLEAN","Number"]},"control.PXT_PANIC.CAST_FROM_NUMBER":{"retType":"control.PXT_PANIC.CAST_FROM_NUMBER","extendsTypes":["control.PXT_PANIC.CAST_FROM_NUMBER","Number"]},"control.PXT_PANIC.CAST_FROM_STRING":{"retType":"control.PXT_PANIC.CAST_FROM_STRING","extendsTypes":["control.PXT_PANIC.CAST_FROM_STRING","Number"]},"control.PXT_PANIC.CAST_FROM_OBJECT":{"retType":"control.PXT_PANIC.CAST_FROM_OBJECT","extendsTypes":["control.PXT_PANIC.CAST_FROM_OBJECT","Number"]},"control.PXT_PANIC.CAST_FROM_FUNCTION":{"retType":"control.PXT_PANIC.CAST_FROM_FUNCTION","extendsTypes":["control.PXT_PANIC.CAST_FROM_FUNCTION","Number"]},"control.PXT_PANIC.CAST_FROM_NULL":{"retType":"control.PXT_PANIC.CAST_FROM_NULL","extendsTypes":["control.PXT_PANIC.CAST_FROM_NULL","Number"]},"control.PXT_PANIC.UNHANDLED_EXCEPTION":{"retType":"control.PXT_PANIC.UNHANDLED_EXCEPTION","extendsTypes":["control.PXT_PANIC.UNHANDLED_EXCEPTION","Number"]},"control.panic":{"kind":-3,"attributes":{"paramDefl":{"code":"5"},"help":"control/panic","weight":29,"blockId":"control_panic","block":"panic %code","paramHelp":{"code":"an error number to display. eg: 5"},"jsDoc":"Display an error code and stop the program.","_def":{"parts":[{"kind":"label","text":"panic ","style":[]},{"kind":"param","name":"code","ref":false}],"parameters":[{"kind":"param","name":"code","ref":false}]}},"parameters":[{"name":"code","description":"an error number to display. eg: 5","default":"5"}]},"control.assert":{"kind":-3,"attributes":{"help":"control/assert","weight":30,"blockId":"control_assert","block":"assert %cond|with value %code","jsDoc":"Display an error code and stop the program when the assertion is `false`.","_def":{"parts":[{"kind":"label","text":"assert ","style":[]},{"kind":"param","name":"cond","ref":false},{"kind":"break"},{"kind":"label","text":"with value ","style":[]},{"kind":"param","name":"code","ref":false}],"parameters":[{"kind":"param","name":"cond","ref":false},{"kind":"param","name":"code","ref":false}]}},"parameters":[{"name":"cond","type":"boolean"},{"name":"code"}]},"control.fail":{"kind":-3,"parameters":[{"name":"message","type":"string"}]},"control.allocateEventSource":{"kind":-3,"retType":"number","parameters":[],"pyQName":"control.allocate_event_source"},"control.AnimationQueue":{"kind":8,"retType":"control.AnimationQueue","extendsTypes":[]},"control.AnimationQueue.running":{"kind":2,"retType":"boolean","isInstance":true},"control.AnimationQueue.eventID":{"kind":2,"retType":"number","isInstance":true,"pyQName":"control.AnimationQueue.event_id"},"control.AnimationQueue.interval":{"kind":2,"retType":"number","isInstance":true},"control.AnimationQueue.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"control.AnimationQueue.runUntilDone":{"kind":-1,"attributes":{"jsDoc":"Runs 'render' in a loop until it returns false or the 'stop' function is called"},"parameters":[{"name":"render","type":"() => boolean","handlerParameters":[]}],"isInstance":true,"pyQName":"control.AnimationQueue.run_until_done"},"control.AnimationQueue.isCancelled":{"kind":-1,"retType":"boolean","parameters":[{"name":"evid"}],"isInstance":true,"pyQName":"control.AnimationQueue.is_cancelled"},"control.AnimationQueue.cancel":{"kind":-1,"attributes":{"jsDoc":"Cancels the current running animation and clears the queue"},"parameters":[],"isInstance":true},"control.getConfigValue":{"kind":-3,"retType":"number","parameters":[{"name":"key"},{"name":"defl"}],"pyQName":"control.get_config_value"},"control.programHash":{"kind":-3,"retType":"number","parameters":[],"pyQName":"control.program_hash"},"control.programName":{"kind":-3,"retType":"string","parameters":[],"pyQName":"control.program_name"},"control.ramSize":{"kind":-3,"retType":"number","attributes":{"jsDoc":"Returns estimated size of memory in bytes."},"parameters":[],"pyQName":"control.ram_size"},"control.benchmark":{"kind":-3,"retType":"number","attributes":{"jsDoc":"Runs the function and returns run time in microseconds."},"parameters":[{"name":"f","type":"() => void","handlerParameters":[]}]},"convertToText":{"kind":-3,"retType":"string","attributes":{"help":"text/convert-to-text","weight":1,"block":"convert $value=math_number to text","blockId":"variable_to_text","blockNamespace":"text","paramHelp":{"value":"value to be converted to text"},"jsDoc":"Convert any value to text","_def":{"parts":[{"kind":"label","text":"convert ","style":[]},{"kind":"param","name":"value","shadowBlockId":"math_number","ref":true},{"kind":"label","text":" to text","style":[]}],"parameters":[{"kind":"param","name":"value","shadowBlockId":"math_number","ref":true}]}},"parameters":[{"name":"value","description":"value to be converted to text","type":"any"}],"pyQName":"convert_to_text"},"control.IntervalMode":{"kind":6,"retType":"control.IntervalMode","extendsTypes":["control.IntervalMode","Number"]},"control.IntervalMode.Interval":{"retType":"control.IntervalMode.Interval","extendsTypes":["control.IntervalMode.Interval","Number"],"pyQName":"control.IntervalMode.INTERVAL"},"control.IntervalMode.Timeout":{"retType":"control.IntervalMode.Timeout","extendsTypes":["control.IntervalMode.Timeout","Number"],"pyQName":"control.IntervalMode.TIMEOUT"},"control.IntervalMode.Immediate":{"retType":"control.IntervalMode.Immediate","extendsTypes":["control.IntervalMode.Immediate","Number"],"pyQName":"control.IntervalMode.IMMEDIATE"},"control.setInterval":{"kind":-3,"retType":"number","parameters":[{"name":"func","type":"() => void","handlerParameters":[]},{"name":"delay"},{"name":"mode","type":"control.IntervalMode","isEnum":true}],"pyQName":"control.set_interval"},"control.clearInterval":{"kind":-3,"parameters":[{"name":"intervalId"},{"name":"mode","type":"control.IntervalMode","isEnum":true}],"pyQName":"control.clear_interval"},"control.GCStats":{"kind":9,"retType":"control.GCStats","extendsTypes":[]},"control.GCStats.numGC":{"kind":2,"retType":"number","isInstance":true,"pyQName":"control.GCStats.num_gc"},"control.GCStats.numBlocks":{"kind":2,"retType":"number","isInstance":true,"pyQName":"control.GCStats.num_blocks"},"control.GCStats.totalBytes":{"kind":2,"retType":"number","isInstance":true,"pyQName":"control.GCStats.total_bytes"},"control.GCStats.lastFreeBytes":{"kind":2,"retType":"number","isInstance":true,"pyQName":"control.GCStats.last_free_bytes"},"control.GCStats.lastMaxBlockBytes":{"kind":2,"retType":"number","isInstance":true,"pyQName":"control.GCStats.last_max_block_bytes"},"control.GCStats.minFreeBytes":{"kind":2,"retType":"number","isInstance":true,"pyQName":"control.GCStats.min_free_bytes"},"control.gcStats":{"kind":-3,"retType":"control.GCStats","attributes":{"jsDoc":"Get various statistics about the garbage collector (GC)"},"parameters":[],"pyQName":"control.gc_stats"},"control.__queuePollEvent":{"kind":-3,"parameters":[{"name":"timeOut"},{"name":"condition","type":"() => boolean","handlerParameters":[]},{"name":"handler","type":"() => void","handlerParameters":[]}]},"pauseUntil":{"kind":-3,"attributes":{"blockId":"pxt_pause_until","paramHelp":{"condition":"condition to test for","timeOut":"if positive, maximum duration to wait for in milliseconds"},"jsDoc":"Busy wait for a condition to be true"},"parameters":[{"name":"condition","description":"condition to test for","type":"() => boolean","handlerParameters":[]},{"name":"timeOut","description":"if positive, maximum duration to wait for in milliseconds","initializer":"undefined"}],"pyQName":"pause_until"},"ConsolePriority":{"kind":6,"retType":"ConsolePriority","extendsTypes":["ConsolePriority","Number"]},"ConsolePriority.Debug":{"retType":"ConsolePriority.Debug","extendsTypes":["ConsolePriority.Debug","Number"],"pyQName":"ConsolePriority.DEBUG"},"ConsolePriority.Log":{"retType":"ConsolePriority.Log","extendsTypes":["ConsolePriority.Log","Number"],"pyQName":"ConsolePriority.LOG"},"ConsolePriority.Warning":{"retType":"ConsolePriority.Warning","extendsTypes":["ConsolePriority.Warning","Number"],"pyQName":"ConsolePriority.WARNING"},"ConsolePriority.Error":{"retType":"ConsolePriority.Error","extendsTypes":["ConsolePriority.Error","Number"],"pyQName":"ConsolePriority.ERROR"},"ConsolePriority.Silent":{"retType":"ConsolePriority.Silent","extendsTypes":["ConsolePriority.Silent","Number"],"pyQName":"ConsolePriority.SILENT"},"console":{"kind":5,"retType":"","attributes":{"weight":12,"color":"#002050","icon":"","advanced":true,"jsDoc":"Reading and writing data to the console output."}},"console.minPriority":{"kind":4,"retType":"ConsolePriority","attributes":{"jsDoc":"Minimum priority to send messages to listeners"},"pyQName":"console.min_priority"},"console.add":{"kind":-3,"parameters":[{"name":"priority","type":"ConsolePriority","isEnum":true},{"name":"message","type":"any"}]},"console.debug":{"kind":-3,"parameters":[{"name":"text","type":"any"}]},"console.warn":{"kind":-3,"parameters":[{"name":"text","type":"any"}]},"console.error":{"kind":-3,"parameters":[{"name":"text","type":"any"}]},"console.log":{"kind":-3,"attributes":{"weight":90,"help":"console/log","blockGap":"8","blockId":"console_log","block":"console log $value","_shadowOverrides":{"value":"text"},"paramHelp":{"value":"to send"},"jsDoc":"Write a line of text to the console output.","_def":{"parts":[{"kind":"label","text":"console log ","style":[]},{"kind":"param","name":"value","shadowBlockId":"text","ref":true}],"parameters":[{"kind":"param","name":"value","shadowBlockId":"text","ref":true}]}},"parameters":[{"name":"value","description":"to send","type":"any"}],"pyQName":"print"},"console.logValue":{"kind":-3,"attributes":{"paramDefl":{"name":"x"},"weight":88,"blockGap":"8","help":"console/log-value","blockId":"console_log_value","block":"console|log value %name|= %value","_shadowOverrides":{"name":"text","value":"math_number"},"paramHelp":{"name":"name of the value stream, eg: \"x\"","value":"to write"},"jsDoc":"Write a name:value pair as a line of text to the console output.","_def":{"parts":[{"kind":"label","text":"console","style":[]},{"kind":"break"},{"kind":"label","text":"log value ","style":[]},{"kind":"param","name":"name","shadowBlockId":"text","ref":false},{"kind":"break"},{"kind":"label","text":"= ","style":[]},{"kind":"param","name":"value","shadowBlockId":"math_number","ref":false}],"parameters":[{"kind":"param","name":"name","shadowBlockId":"text","ref":false},{"kind":"param","name":"value","shadowBlockId":"math_number","ref":false}]}},"parameters":[{"name":"name","description":"name of the value stream, eg: \"x\"","type":"any","default":"x"},{"name":"value","description":"to write","type":"any"}],"pyQName":"console.log_value"},"console.inspect":{"kind":-3,"retType":"string","attributes":{"paramHelp":{"obj":"value to be converted to a string","maxElements":"[optional] max number values in an object to include in output"},"jsDoc":"Convert any object or value to a string representation"},"parameters":[{"name":"obj","description":"value to be converted to a string","type":"any"},{"name":"maxElements","description":"[optional] max number values in an object to include in output","initializer":"20"}]},"console.addListener":{"kind":-3,"attributes":{"paramHelp":{"listener":""},"jsDoc":"Adds a listener for the log messages"},"parameters":[{"name":"listener","type":"(priority: ConsolePriority, text: string) => void","handlerParameters":[{"name":"priority","type":"ConsolePriority"},{"name":"text","type":"string"}]}],"pyQName":"console.add_listener"},"console.removeListener":{"kind":-3,"attributes":{"paramHelp":{"listener":""},"jsDoc":"Removes a listener"},"parameters":[{"name":"listener","type":"(priority: ConsolePriority, text: string) => void","handlerParameters":[{"name":"priority","type":"ConsolePriority"},{"name":"text","type":"string"}]}],"pyQName":"console.remove_listener"},"JSON":{"kind":5,"retType":""},"JSON.parseIntRadix":{"kind":-3,"retType":"number","parameters":[{"name":"s","type":"string"},{"name":"base","initializer":"undefined"}],"pyQName":"JSON.parse_int_radix"},"JSON.stringify":{"kind":-3,"retType":"string","attributes":{"paramHelp":{"value":"A JavaScript value, usually an object or array, to be converted.","replacer":"Not supported; use null.","indent":"Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read."},"jsDoc":"Converts a JavaScript value to a JavaScript Object Notation (JSON) string."},"parameters":[{"name":"value","description":"A JavaScript value, usually an object or array, to be converted.","type":"any"},{"name":"replacer","description":"Not supported; use null.","type":"any","initializer":"null"},{"name":"indent","description":"Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.","initializer":"0"}]},"JSON.parse":{"kind":-3,"retType":"any","attributes":{"paramHelp":{"text":"A valid JSON string."},"jsDoc":"Converts a JavaScript Object Notation (JSON) string into an object."},"parameters":[{"name":"s","type":"string"}]},"hex":{"kind":-3,"retType":"Buffer","attributes":{"shim":"@hex","jsDoc":"Tagged hex literal converter"},"parameters":[{"name":"lits","type":"any"},{"name":"args","type":"any[]"}]},"control.onEvent":{"kind":-3,"attributes":{"weight":20,"blockGap":"8","blockId":"control_on_event","block":"on event|from %src|with value %value","blockExternalInputs":"1","help":"control/on-event","inlineInputMode":"external","paramHelp":{"id":"the event compoent id","value":"the event value to match"},"jsDoc":"Run code when a registered event happens.","_def":{"parts":[{"kind":"label","text":"on event","style":[]},{"kind":"break"},{"kind":"label","text":"from ","style":[]},{"kind":"param","name":"src","ref":false},{"kind":"break"},{"kind":"label","text":"with value ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"src","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"src"},{"name":"value","description":"the event value to match"},{"name":"handler","type":"() => void","handlerParameters":[]},{"name":"flags","initializer":"16"}],"pyQName":"control.on_event"},"control.FrameCallback":{"kind":8,"retType":"control.FrameCallback","extendsTypes":[]},"control.FrameCallback.order":{"kind":2,"retType":"number","isInstance":true},"control.FrameCallback.handler":{"kind":2,"retType":"() => void","isInstance":true},"control.EventContext":{"kind":8,"retType":"control.EventContext","extendsTypes":[]},"control.EventContext.deltaTimeMillis":{"kind":2,"retType":"number","isInstance":true,"pyQName":"control.EventContext.delta_time_millis"},"control.EventContext.lastStats":{"kind":2,"retType":"string","pyQName":"control.EventContext.last_stats"},"control.EventContext.onStats":{"kind":2,"retType":"(stats: string) => void","pyQName":"control.EventContext.on_stats"},"control.EventContext.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"control.EventContext.deltaTime":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"control.EventContext.delta_time"},"control.EventContext.register":{"kind":-1,"parameters":[],"isInstance":true},"control.EventContext.unregister":{"kind":-1,"parameters":[],"isInstance":true},"control.EventContext.registerFrameHandler":{"kind":-1,"retType":"control.FrameCallback","parameters":[{"name":"order"},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"control.EventContext.register_frame_handler"},"control.EventContext.unregisterFrameHandler":{"kind":-1,"parameters":[{"name":"fn","type":"control.FrameCallback"}],"isInstance":true,"pyQName":"control.EventContext.unregister_frame_handler"},"control.EventContext.registerHandler":{"kind":-1,"parameters":[{"name":"src"},{"name":"value"},{"name":"handler","type":"() => void","handlerParameters":[]},{"name":"flags"}],"isInstance":true,"pyQName":"control.EventContext.register_handler"},"control.EventContext.addIdleHandler":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"control.EventContext.add_idle_handler"},"control.EventContext.removeIdleHandler":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"control.EventContext.remove_idle_handler"},"control.eventContext":{"kind":-3,"retType":"control.EventContext","attributes":{"jsDoc":"Gets the current event context if any"},"parameters":[],"pyQName":"control.event_context"},"control.pushEventContext":{"kind":-3,"retType":"control.EventContext","attributes":{"jsDoc":"Pushes a new event context and clears all handlers"},"parameters":[],"pyQName":"control.push_event_context"},"control.popEventContext":{"kind":-3,"attributes":{"jsDoc":"Pops the current event context and restore handlers if any previous context"},"parameters":[],"pyQName":"control.pop_event_context"},"control.onIdle":{"kind":-3,"attributes":{"paramHelp":{"handler":""},"jsDoc":"Registers a function to run when the device is idling"},"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"control.on_idle"},"control.removeIdleHandler":{"kind":-3,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"control.remove_idle_handler"},"pause":{"kind":-3,"attributes":{"paramDefl":{"ms":"100"},"callingConvention":1,"help":"loops/pause","weight":99,"async":"true","block":"pause %pause=timePicker|ms","blockId":"device_pause","blockNamespace":"loops","paramHelp":{"ms":"how long to pause for, eg: 100, 200, 500, 1000, 2000"},"jsDoc":"Pause for the specified time in milliseconds","_def":{"parts":[{"kind":"label","text":"pause ","style":[]},{"kind":"param","name":"pause","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"pause","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"ms","description":"how long to pause for, eg: 100, 200, 500, 1000, 2000","default":"100"}]},"basic":{"kind":5,"retType":""},"basic.pause":{"kind":-3,"parameters":[{"name":"millis"}]},"UTF8Decoder":{"kind":8,"retType":"UTF8Decoder","extendsTypes":[]},"UTF8Decoder.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"UTF8Decoder.add":{"kind":-1,"parameters":[{"name":"buf","type":"Buffer"}],"isInstance":true},"UTF8Decoder.decodeUntil":{"kind":-1,"retType":"string","parameters":[{"name":"delimiter"}],"isInstance":true,"pyQName":"UTF8Decoder.decode_until"},"UTF8Decoder.decode":{"kind":-1,"retType":"string","parameters":[],"isInstance":true},"setInterval":{"kind":-3,"retType":"number","attributes":{"paramHelp":{"func":"@param delay "},"jsDoc":"Calls a function with a fixed time delay between each call to that function."},"parameters":[{"name":"func","description":"@param delay ","type":"() => void","handlerParameters":[]},{"name":"delay"}],"pyQName":"set_interval"},"clearInterval":{"kind":-3,"attributes":{"paramHelp":{"intervalId":""},"jsDoc":"Cancels repeated action which was set up using setInterval()."},"parameters":[{"name":"intervalId"}],"pyQName":"clear_interval"},"setTimeout":{"kind":-3,"retType":"number","attributes":{"paramHelp":{"func":"@param delay "},"jsDoc":"Calls a function after specified delay."},"parameters":[{"name":"func","description":"@param delay ","type":"() => void","handlerParameters":[]},{"name":"delay"}],"pyQName":"set_timeout"},"clearTimeout":{"kind":-3,"attributes":{"paramHelp":{"intervalId":""},"jsDoc":"Clears the delay set by setTimeout()."},"parameters":[{"name":"intervalId"}],"pyQName":"clear_timeout"},"setImmediate":{"kind":-3,"retType":"number","attributes":{"paramHelp":{"func":""},"jsDoc":"Calls a function as soon as possible."},"parameters":[{"name":"func","type":"() => void","handlerParameters":[]}],"pyQName":"set_immediate"},"clearImmediate":{"kind":-3,"attributes":{"paramHelp":{"intervalId":""},"jsDoc":"Cancels the immediate actions."},"parameters":[{"name":"intervalId"}],"pyQName":"clear_immediate"},"control.simmessages":{"kind":5,"retType":""},"control.simmessages.CONTROL_MESSAGE_EVT_ID":{"kind":4,"retType":"number"},"control.simmessages.CONTROL_MESSAGE_RECEIVED":{"kind":4,"retType":"number"},"control.simmessages.send":{"kind":-3,"parameters":[{"name":"channel","type":"string"},{"name":"message","type":"Buffer"},{"name":"parentOnly","type":"boolean","initializer":"undefined"}]},"control.simmessages.onReceived":{"kind":-3,"attributes":{"jsDoc":"Registers the handler for a message on a given channel"},"parameters":[{"name":"channel","type":"string"},{"name":"handler","type":"(msg: Buffer) => void","handlerParameters":[{"name":"msg","type":"Buffer"}]}],"pyQName":"control.simmessages.on_received"},"control.enablePerfCounter":{"kind":-3,"attributes":{"shim":"TD_NOOP","shimArgument":"perfCounter","jsDoc":"Enable profiling for current function."},"parameters":[{"name":"name","type":"string","initializer":"undefined"}],"pyQName":"control.enable_perf_counter"},"control.dmesgPerfCounters":{"kind":-3,"attributes":{"jsDoc":"Dump values of profiling performance counters."},"parameters":[],"pyQName":"control.dmesg_perf_counters"},"DAL":{"kind":6,"retType":"DAL","extendsTypes":["DAL","Number"]},"DigitalInOutPin":{"kind":9,"retType":"DigitalInOutPin","attributes":{"noRefCounting":"true","fixedInstances":"true"},"extendsTypes":["DigitalInOutPin"]},"AnalogInPin":{"kind":9,"retType":"AnalogInPin","attributes":{"noRefCounting":"true","fixedInstances":"true"},"extendsTypes":["AnalogInPin","DigitalInOutPin"]},"AnalogOutPin":{"kind":9,"retType":"AnalogOutPin","attributes":{"noRefCounting":"true","fixedInstances":"true"},"extendsTypes":["AnalogOutPin","DigitalInOutPin"]},"AnalogInOutPin":{"kind":9,"retType":"AnalogInOutPin","attributes":{"noRefCounting":"true","fixedInstances":"true"},"extendsTypes":["AnalogInOutPin","AnalogInPin","DigitalInOutPin","AnalogOutPin"]},"PwmOnlyPin":{"kind":9,"retType":"PwmOnlyPin","attributes":{"noRefCounting":"true","fixedInstances":"true"},"extendsTypes":["PwmOnlyPin","DigitalInOutPin","AnalogOutPin"]},"PwmPin":{"kind":9,"retType":"PwmPin","attributes":{"noRefCounting":"true","fixedInstances":"true"},"extendsTypes":["PwmPin","PwmOnlyPin","DigitalInOutPin","AnalogOutPin","AnalogInOutPin","AnalogInPin"]},"pins.i2cReadNumber":{"kind":-3,"retType":"number","attributes":{"help":"pins/i2c-read-number","weight":5,"group":"i2c","inlineInputMode":"external","blockId":"pins_i2c_readnumber","block":"i2c read number at address %address|of format %format|repeated %repeated","jsDoc":"Read one number from an I2C address.","_def":{"parts":[{"kind":"label","text":"i2c read number at address ","style":[]},{"kind":"param","name":"address","ref":false},{"kind":"break"},{"kind":"label","text":"of format ","style":[]},{"kind":"param","name":"format","ref":false},{"kind":"break"},{"kind":"label","text":"repeated ","style":[]},{"kind":"param","name":"repeated","ref":false}],"parameters":[{"kind":"param","name":"address","ref":false},{"kind":"param","name":"format","ref":false},{"kind":"param","name":"repeated","ref":false}]}},"parameters":[{"name":"address"},{"name":"format","type":"NumberFormat","isEnum":true},{"name":"repeated","type":"boolean","initializer":"undefined"}],"pyQName":"pins.i2c_read_number"},"pins.i2cWriteNumber":{"kind":-3,"attributes":{"help":"pins/i2c-write-number","weight":4,"group":"i2c","blockId":"i2c_writenumber","block":"i2c write number|at address %address|with value %value|of format %format|repeated %repeated","jsDoc":"Write one number to an I2C address.","_def":{"parts":[{"kind":"label","text":"i2c write number","style":[]},{"kind":"break"},{"kind":"label","text":"at address ","style":[]},{"kind":"param","name":"address","ref":false},{"kind":"break"},{"kind":"label","text":"with value ","style":[]},{"kind":"param","name":"value","ref":false},{"kind":"break"},{"kind":"label","text":"of format ","style":[]},{"kind":"param","name":"format","ref":false},{"kind":"break"},{"kind":"label","text":"repeated ","style":[]},{"kind":"param","name":"repeated","ref":false}],"parameters":[{"kind":"param","name":"address","ref":false},{"kind":"param","name":"value","ref":false},{"kind":"param","name":"format","ref":false},{"kind":"param","name":"repeated","ref":false}]}},"parameters":[{"name":"address"},{"name":"value"},{"name":"format","type":"NumberFormat","initializer":"undefined","isEnum":true},{"name":"repeated","type":"boolean","initializer":"undefined"}],"pyQName":"pins.i2c_write_number"},"pins.i2cWriteRegister":{"kind":-3,"attributes":{"weight":3,"group":"i2c","help":"pins/i2c-write-register","blockId":"i2c_writereg","block":"i2c write register|at address $address|at register $register|value $value","paramHelp":{"address":"I2c address of the device","register":"register index","value":"value to write","valueFormat":"format of the value, default is UInt8LE"},"jsDoc":"Write a value in a I2C register.","_def":{"parts":[{"kind":"label","text":"i2c write register","style":[]},{"kind":"break"},{"kind":"label","text":"at address ","style":[]},{"kind":"param","name":"address","ref":true},{"kind":"break"},{"kind":"label","text":"at register ","style":[]},{"kind":"param","name":"register","ref":true},{"kind":"break"},{"kind":"label","text":"value ","style":[]},{"kind":"param","name":"value","ref":true}],"parameters":[{"kind":"param","name":"address","ref":true},{"kind":"param","name":"register","ref":true},{"kind":"param","name":"value","ref":true}]}},"parameters":[{"name":"address","description":"I2c address of the device"},{"name":"register","description":"register index"},{"name":"value","description":"value to write"},{"name":"valueFormat","description":"format of the value, default is UInt8LE","type":"NumberFormat","initializer":"undefined","isEnum":true}],"pyQName":"pins.i2c_write_register"},"pins.i2cReadRegister":{"kind":-3,"retType":"number","attributes":{"weight":3,"group":"i2c","help":"pins/i2c-read-register","blockId":"i2c_readreg","block":"i2c read register|at address $address|at register $register","paramHelp":{"address":"I2c address of the device","register":"register index","valueFormat":"format of the value, default is UInt8LE"},"jsDoc":"Read the value from a I2C register.","_def":{"parts":[{"kind":"label","text":"i2c read register","style":[]},{"kind":"break"},{"kind":"label","text":"at address ","style":[]},{"kind":"param","name":"address","ref":true},{"kind":"break"},{"kind":"label","text":"at register ","style":[]},{"kind":"param","name":"register","ref":true}],"parameters":[{"kind":"param","name":"address","ref":true},{"kind":"param","name":"register","ref":true}]}},"parameters":[{"name":"address","description":"I2c address of the device"},{"name":"register","description":"register index"},{"name":"valueFormat","description":"format of the value, default is UInt8LE","type":"NumberFormat","initializer":"undefined","isEnum":true}],"pyQName":"pins.i2c_read_register"},"pins.i2cReadBuffer":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"Read `size` bytes from a 7-bit I2C `address`."},"parameters":[{"name":"address"},{"name":"size"},{"name":"repeat","type":"boolean","initializer":"false"}],"pyQName":"pins.i2c_read_buffer"},"pins.i2cWriteBuffer":{"kind":-3,"retType":"number","attributes":{"jsDoc":"Write bytes to a 7-bit I2C `address`."},"parameters":[{"name":"address"},{"name":"buf","type":"Buffer"},{"name":"repeat","type":"boolean","initializer":"false"}],"pyQName":"pins.i2c_write_buffer"},"pins.i2c":{"kind":-3,"retType":"I2C","attributes":{"jsDoc":"Gets the default I2C bus"},"parameters":[]},"pins.I2CDevice":{"kind":8,"retType":"pins.I2CDevice","extendsTypes":[]},"pins.I2CDevice.address":{"kind":2,"retType":"number","isInstance":true},"pins.I2CDevice.bus":{"kind":2,"retType":"I2C","isInstance":true},"pins.I2CDevice.__constructor":{"kind":-3,"parameters":[{"name":"address"},{"name":"bus","type":"I2C","initializer":"undefined"}],"isInstance":true},"pins.I2CDevice.readInto":{"kind":-1,"parameters":[{"name":"buf","type":"Buffer"},{"name":"repeat","type":"boolean","initializer":"false"},{"name":"start","initializer":"0"},{"name":"end","initializer":"null"}],"isInstance":true,"pyQName":"pins.I2CDevice.read_into"},"pins.I2CDevice.write":{"kind":-1,"parameters":[{"name":"buf","type":"Buffer"},{"name":"repeat","type":"boolean","initializer":"false"}],"isInstance":true},"pins.I2CDevice.begin":{"kind":-1,"retType":"pins.I2CDevice","parameters":[],"isInstance":true},"pins.I2CDevice.end":{"kind":-1,"parameters":[],"isInstance":true},"pins.I2CDevice.ok":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true},"pins.I2CDevice.transfer":{"kind":-1,"parameters":[{"name":"command","type":"Buffer"},{"name":"response","type":"Buffer"},{"name":"responseStart","initializer":"undefined"},{"name":"responseEnd","initializer":"undefined"}],"isInstance":true},"pins.spi":{"kind":-3,"retType":"SPI","attributes":{"jsDoc":"Gets the default SPI driver"},"parameters":[]},"pins.spiWrite":{"kind":-3,"retType":"number","attributes":{"help":"pins/spi-write","weight":5,"advanced":true,"blockId":"spi_write","block":"spi write %value","paramHelp":{"value":"Data to be sent to the SPI slave"},"jsDoc":"Write to the SPI slave and return the response","_def":{"parts":[{"kind":"label","text":"spi write ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","description":"Data to be sent to the SPI slave"}],"pyQName":"pins.spi_write"},"pins.spiTransfer":{"kind":-3,"attributes":{"help":"pins/spi-transfer","weight":4,"advanced":true,"blockId":"spi_transfer","block":"spi transfer %command into %response","jsDoc":"Write a given command to SPI bus, and at the same time read the response.","_def":{"parts":[{"kind":"label","text":"spi transfer ","style":[]},{"kind":"param","name":"command","ref":false},{"kind":"label","text":" into ","style":[]},{"kind":"param","name":"response","ref":false}],"parameters":[{"kind":"param","name":"command","ref":false},{"kind":"param","name":"response","ref":false}]}},"parameters":[{"name":"command","type":"Buffer"},{"name":"response","type":"Buffer"}],"pyQName":"pins.spi_transfer"},"pins.spiFrequency":{"kind":-3,"attributes":{"paramDefl":{"frequency":"1000000"},"help":"pins/spi-frequency","weight":4,"advanced":true,"blockId":"spi_frequency","block":"spi frequency %frequency","paramHelp":{"frequency":"the clock frequency, eg: 1000000"},"jsDoc":"Set the SPI frequency","_def":{"parts":[{"kind":"label","text":"spi frequency ","style":[]},{"kind":"param","name":"frequency","ref":false}],"parameters":[{"kind":"param","name":"frequency","ref":false}]}},"parameters":[{"name":"frequency","description":"the clock frequency, eg: 1000000","default":"1000000"}],"pyQName":"pins.spi_frequency"},"pins.spiMode":{"kind":-3,"attributes":{"paramDefl":{"mode":"3"},"help":"pins/spi-mode","weight":3,"advanced":true,"blockId":"spi_mode","block":"spi mode %mode","paramHelp":{"mode":"the mode, eg: 3"},"jsDoc":"Set the SPI signal mode","_def":{"parts":[{"kind":"label","text":"spi mode ","style":[]},{"kind":"param","name":"mode","ref":false}],"parameters":[{"kind":"param","name":"mode","ref":false}]}},"parameters":[{"name":"mode","description":"the mode, eg: 3","default":"3"}],"pyQName":"pins.spi_mode"},"light":{"kind":5,"retType":""},"light.sendBuffer":{"kind":-3,"attributes":{"paramHelp":{"data":"The pin that the lights are connected to","clk":"the clock line if any","mode":"the color encoding mode","buf":"The buffer to send to the pin"},"jsDoc":"Send a programmable light buffer to the specified digital pin"},"parameters":[{"name":"data","description":"The pin that the lights are connected to","type":"DigitalInOutPin"},{"name":"clk","description":"the clock line if any","type":"DigitalInOutPin"},{"name":"mode","description":"the color encoding mode"},{"name":"buf","description":"The buffer to send to the pin","type":"Buffer"}],"pyQName":"light.send_buffer"},"control.isUSBInitialized":{"kind":-3,"retType":"boolean","attributes":{"jsDoc":"Determines if the USB has been enumerated."},"parameters":[],"pyQName":"control.is_usb_initialized"},"pins.pinByCfg":{"kind":-3,"retType":"DigitalInOutPin","attributes":{"jsDoc":"Get a pin by configuration id (DAL.CFG_PIN...)"},"parameters":[{"name":"key"}],"pyQName":"pins.pin_by_cfg"},"pins.createBuffer":{"kind":-3,"retType":"Buffer","attributes":{"paramHelp":{"size":"number of bytes in the buffer"},"jsDoc":"Create a new zero-initialized buffer."},"parameters":[{"name":"size","description":"number of bytes in the buffer"}],"pyQName":"bytearray"},"pins.pulseDuration":{"kind":-3,"retType":"number","attributes":{"help":"pins/pulse-duration","blockGap":"8","blockId":"pins_pulse_duration","block":"pulse duration (µs)","weight":19,"jsDoc":"Get the duration of the last pulse in microseconds. This function should be called from a\n``onPulsed`` handler.","_def":{"parts":[{"kind":"label","text":"pulse duration (µs)","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"pins.pulse_duration"},"AnalogInPin.analogRead":{"kind":-1,"retType":"number","attributes":{"help":"pins/analog-read","weight":53,"blockId":"device_get_analog_pin","block":"analog read|pin %name","blockGap":"8","blockNamespace":"pins","paramFieldEditor":{"name":"gridpicker"},"paramFieldEditorOptions":{"name":{"width":"220","columns":"4"}},"paramHelp":{"name":"pin to write to"},"jsDoc":"Read the connector value as analog, that is, as a value comprised between 0 and 1023.","_def":{"parts":[{"kind":"label","text":"analog read","style":[]},{"kind":"break"},{"kind":"label","text":"pin ","style":[]},{"kind":"param","name":"name","ref":false}],"parameters":[{"kind":"param","name":"name","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"AnalogInPin.analog_read"},"AnalogOutPin.analogWrite":{"kind":-1,"attributes":{"paramDefl":{"value":"1023"},"help":"pins/analog-write","weight":52,"blockId":"device_set_analog_pin","block":"analog write|pin %name|to %value","blockGap":"8","blockNamespace":"pins","paramFieldEditor":{"name":"gridpicker"},"paramFieldEditorOptions":{"name":{"width":"220","columns":"4"}},"paramMin":{"value":"0"},"paramMax":{"value":"1023"},"paramHelp":{"name":"pin name to write to","value":"value to write to the pin between ``0`` and ``1023``. eg:1023,0"},"jsDoc":"Set the connector value as analog. Value must be comprised between 0 and 1023.","_def":{"parts":[{"kind":"label","text":"analog write","style":[]},{"kind":"break"},{"kind":"label","text":"pin ","style":[]},{"kind":"param","name":"name","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"name","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","description":"value to write to the pin between ``0`` and ``1023``. eg:1023,0","default":"1023","options":{"min":{"value":"0"},"max":{"value":"1023"}}}],"isInstance":true,"pyQName":"AnalogOutPin.analog_write"},"DigitalInOutPin.digitalRead":{"kind":-1,"retType":"boolean","attributes":{"help":"pins/digital-read","weight":61,"blockId":"device_get_digital_pin","block":"digital read|pin %name","blockGap":"8","blockNamespace":"pins","paramFieldEditor":{"name":"gridpicker"},"paramFieldEditorOptions":{"name":{"width":"220","columns":"4"}},"paramHelp":{"name":"pin to read from"},"jsDoc":"Read a pin or connector as either 0 or 1","_def":{"parts":[{"kind":"label","text":"digital read","style":[]},{"kind":"break"},{"kind":"label","text":"pin ","style":[]},{"kind":"param","name":"name","ref":false}],"parameters":[{"kind":"param","name":"name","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"DigitalInOutPin.digital_read"},"DigitalInOutPin.digitalWrite":{"kind":-1,"attributes":{"help":"pins/digital-write","weight":60,"blockId":"device_set_digital_pin","block":"digital write|pin %name|to %value=toggleHighLow","blockNamespace":"pins","paramFieldEditor":{"name":"gridpicker"},"paramFieldEditorOptions":{"name":{"width":"220","columns":"4"}},"paramHelp":{"name":"pin to write to","value":"value to set on the pin"},"jsDoc":"Set a pin or connector value to either 0 or 1.","_def":{"parts":[{"kind":"label","text":"digital write","style":[]},{"kind":"break"},{"kind":"label","text":"pin ","style":[]},{"kind":"param","name":"name","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"value","shadowBlockId":"toggleHighLow","ref":false}],"parameters":[{"kind":"param","name":"name","ref":false},{"kind":"param","name":"value","shadowBlockId":"toggleHighLow","ref":false}]}},"parameters":[{"name":"value","description":"value to set on the pin","type":"boolean"}],"isInstance":true,"pyQName":"DigitalInOutPin.digital_write"},"DigitalInOutPin.onPulsed":{"kind":-1,"attributes":{"help":"pins/on-pulsed","weight":16,"blockGap":"8","blockId":"pins_on_pulsed","block":"on|pin %pin|pulsed %pulse","blockNamespace":"pins","paramFieldEditor":{"pin":"gridpicker"},"paramFieldEditorOptions":{"pin":{"width":"220","columns":"4"}},"deprecated":"1","hidden":"1","jsDoc":"Make this pin a digital input, and create events where the timestamp is the duration\nthat this pin was either ``high`` or ``low``.","_def":{"parts":[{"kind":"label","text":"on","style":[]},{"kind":"break"},{"kind":"label","text":"pin ","style":[]},{"kind":"param","name":"pin","ref":false},{"kind":"break"},{"kind":"label","text":"pulsed ","style":[]},{"kind":"param","name":"pulse","ref":false}],"parameters":[{"kind":"param","name":"pin","ref":false},{"kind":"param","name":"pulse","ref":false}]}},"parameters":[{"name":"pulse","type":"PulseValue","isEnum":true},{"name":"body","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"DigitalInOutPin.on_pulsed"},"DigitalInOutPin.onEvent":{"kind":-1,"attributes":{"help":"pins/on-event","weight":20,"blockGap":"8","blockId":"pinsonevent","block":"on|pin %pin|%event","blockNamespace":"pins","paramFieldEditor":{"pin":"gridpicker"},"paramFieldEditorOptions":{"pin":{"width":"220","columns":"4"}},"jsDoc":"Register code to run when a pin event occurs.","_def":{"parts":[{"kind":"label","text":"on","style":[]},{"kind":"break"},{"kind":"label","text":"pin ","style":[]},{"kind":"param","name":"pin","ref":false},{"kind":"break"},{"kind":"param","name":"event","ref":false}],"parameters":[{"kind":"param","name":"pin","ref":false},{"kind":"param","name":"event","ref":false}]}},"parameters":[{"name":"event","type":"PinEvent","isEnum":true},{"name":"body","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"DigitalInOutPin.on_event"},"DigitalInOutPin.pulseIn":{"kind":-1,"retType":"number","attributes":{"paramDefl":{"maxDuration":"2000000"},"blockId":"pins_pulse_in","block":"pulse in (µs)|pin %name|pulsed %high||timeout %maxDuration (µs)","weight":18,"blockGap":"8","help":"pins/pulse-in","blockNamespace":"pins","paramFieldEditor":{"pin":"gridpicker"},"paramFieldEditorOptions":{"pin":{"width":"220","columns":"4"}},"explicitDefaults":["maxDuration"],"paramHelp":{"name":"the pin which measures the pulse","value":"the value of the pulse (default high)","maximum":"duration in micro-seconds"},"jsDoc":"Return the duration of a pulse in microseconds","_def":{"parts":[{"kind":"label","text":"pulse in (µs)","style":[]},{"kind":"break"},{"kind":"label","text":"pin ","style":[]},{"kind":"param","name":"name","ref":false},{"kind":"break"},{"kind":"label","text":"pulsed ","style":[]},{"kind":"param","name":"high","ref":false}],"parameters":[{"kind":"param","name":"name","ref":false},{"kind":"param","name":"high","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":"timeout ","style":[]},{"kind":"param","name":"maxDuration","ref":false},{"kind":"label","text":" (µs)","style":[]}],"parameters":[{"kind":"param","name":"maxDuration","ref":false}]}},"parameters":[{"name":"value","description":"the value of the pulse (default high)","type":"PulseValue","isEnum":true},{"name":"maxDuration","initializer":"2000000","default":"2000000"}],"isInstance":true,"pyQName":"DigitalInOutPin.pulse_in"},"DigitalInOutPin.setPull":{"kind":-1,"attributes":{"help":"pins/set-pull","weight":17,"blockGap":"8","blockId":"device_set_pull","block":"set pull|pin %pin|to %pull","blockNamespace":"pins","paramFieldEditor":{"name":"gridpicker"},"paramFieldEditorOptions":{"name":{"width":"220","columns":"4"}},"paramHelp":{"name":"pin to set the pull mode on","pull":"one of the mbed pull configurations: PullUp, PullDown, PullNone"},"jsDoc":"Set the pull direction of this pin.","_def":{"parts":[{"kind":"label","text":"set pull","style":[]},{"kind":"break"},{"kind":"label","text":"pin ","style":[]},{"kind":"param","name":"pin","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"pull","ref":false}],"parameters":[{"kind":"param","name":"pin","ref":false},{"kind":"param","name":"pull","ref":false}]}},"parameters":[{"name":"pull","description":"one of the mbed pull configurations: PullUp, PullDown, PullNone","type":"PinPullMode","isEnum":true}],"isInstance":true,"pyQName":"DigitalInOutPin.set_pull"},"PwmOnlyPin.analogSetPeriod":{"kind":-1,"attributes":{"paramDefl":{"micros":"20000"},"help":"pins/analog-set-period","weight":51,"blockId":"device_set_analog_period","block":"analog set period|pin %pin|to (µs)%period","blockNamespace":"pins","paramFieldEditor":{"name":"gridpicker"},"paramFieldEditorOptions":{"name":{"width":"220","columns":"4"}},"paramHelp":{"name":"analog pin to set period to","micros":"period in micro seconds. eg:20000"},"jsDoc":"Set the Pulse-width modulation (PWM) period of the analog output. The period is in\n**microseconds** or `1/1000` milliseconds.\nIf this pin is not configured as an analog output (using `analog write pin`), the operation has\nno effect.","_def":{"parts":[{"kind":"label","text":"analog set period","style":[]},{"kind":"break"},{"kind":"label","text":"pin ","style":[]},{"kind":"param","name":"pin","ref":false},{"kind":"break"},{"kind":"label","text":"to (µs)","style":[]},{"kind":"param","name":"period","ref":false}],"parameters":[{"kind":"param","name":"pin","ref":false},{"kind":"param","name":"period","ref":false}]}},"parameters":[{"name":"period"}],"isInstance":true,"pyQName":"PwmOnlyPin.analog_set_period"},"PwmOnlyPin.servoWrite":{"kind":-1,"attributes":{"paramDefl":{"value":"90"},"help":"pins/servo-write","weight":41,"group":"Servo","blockId":"device_set_servo_pin","block":"servo write|pin %name|to %value=protractorPicker","blockGap":"8","parts":"microservo","trackArgs":[0],"blockNamespace":"pins","paramFieldEditor":{"name":"gridpicker"},"paramFieldEditorOptions":{"name":{"width":"220","columns":"4"}},"explicitDefaults":["value"],"paramHelp":{"name":"pin to write to","value":"angle or rotation speed"},"jsDoc":"Write a value to the servo to control the rotation of the shaft. On a standard servo, this will\nset the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous\nrotation servo, this will set the speed of the servo (with ``0`` being full-speed in one\ndirection, ``180`` being full speed in the other, and a value near ``90`` being no movement).","_def":{"parts":[{"kind":"label","text":"servo write","style":[]},{"kind":"break"},{"kind":"label","text":"pin ","style":[]},{"kind":"param","name":"name","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"value","shadowBlockId":"protractorPicker","ref":false}],"parameters":[{"kind":"param","name":"name","ref":false},{"kind":"param","name":"value","shadowBlockId":"protractorPicker","ref":false}]}},"parameters":[{"name":"value","description":"angle or rotation speed","initializer":"90","default":"90"}],"isInstance":true,"pyQName":"PwmOnlyPin.servo_write"},"PwmOnlyPin.servoSetPulse":{"kind":-1,"attributes":{"paramDefl":{"duration":"1500"},"help":"pins/servo-set-pulse","weight":40,"group":"Servo","blockGap":"8","blockId":"device_set_servo_pulse","block":"servo set pulse|pin %value|to (µs) %duration","parts":"microservo","blockNamespace":"pins","paramFieldEditor":{"name":"gridpicker"},"paramFieldEditorOptions":{"name":{"width":"220","columns":"4"}},"paramHelp":{"name":"pin name","duration":"pulse duration in micro seconds, eg:1500"},"jsDoc":"Set the pin for PWM analog output, make the period be 20 ms, and set the pulse width.\nThe pulse width is based on the value it is given **microseconds** or `1/1000` milliseconds.","_def":{"parts":[{"kind":"label","text":"servo set pulse","style":[]},{"kind":"break"},{"kind":"label","text":"pin ","style":[]},{"kind":"param","name":"value","ref":false},{"kind":"break"},{"kind":"label","text":"to (µs) ","style":[]},{"kind":"param","name":"duration","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false},{"kind":"param","name":"duration","ref":false}]}},"parameters":[{"name":"duration","description":"pulse duration in micro seconds, eg:1500","default":"1500"}],"isInstance":true,"pyQName":"PwmOnlyPin.servo_set_pulse"},"PwmOnlyPin.servoSetContinuous":{"kind":-1,"attributes":{"blockHidden":true,"jsDoc":"Indicates if the servo is running continuously"},"parameters":[{"name":"continuous","type":"boolean"}],"isInstance":true,"pyQName":"PwmOnlyPin.servo_set_continuous"},"control.raiseEvent":{"kind":-3,"attributes":{"weight":21,"blockGap":"12","blockId":"control_raise_event","help":"control/raise-event","block":"raise event|from %src|with value %value","blockExternalInputs":"1","inlineInputMode":"external","paramHelp":{"src":"ID of the MicroBit Component that generated the event","value":"Component specific code indicating the cause of the event."},"jsDoc":"Announce that an event happened to registered handlers.","_def":{"parts":[{"kind":"label","text":"raise event","style":[]},{"kind":"break"},{"kind":"label","text":"from ","style":[]},{"kind":"param","name":"src","ref":false},{"kind":"break"},{"kind":"label","text":"with value ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"src","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"src","description":"ID of the MicroBit Component that generated the event"},{"name":"value","description":"Component specific code indicating the cause of the event."}],"pyQName":"control.raise_event"},"control.deviceDalVersion":{"kind":-3,"retType":"string","attributes":{"blockId":"control_device_dal_version","block":"device dal version","help":"control/device-dal-version","jsDoc":"Determine the version of system software currently running.","_def":{"parts":[{"kind":"label","text":"device dal version","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"control.device_dal_version"},"control.allocateNotifyEvent":{"kind":-3,"retType":"number","attributes":{"help":"control/allocate-notify-event","jsDoc":"Allocates the next user notification event"},"parameters":[],"pyQName":"control.allocate_notify_event"},"control.dmesg":{"kind":-3,"attributes":{"jsDoc":"Write a message to DMESG debugging buffer."},"parameters":[{"name":"s","type":"string"}]},"control.dmesgPtr":{"kind":-3,"attributes":{"jsDoc":"Write a message and value (pointer) to DMESG debugging buffer."},"parameters":[{"name":"str","type":"string"},{"name":"ptr","type":"Object"}],"pyQName":"control.dmesg_ptr"},"I2C":{"kind":9,"retType":"I2C","extendsTypes":[]},"I2C.readBuffer":{"kind":-1,"retType":"Buffer","attributes":{"paramDefl":{"repeat":"0"},"explicitDefaults":["repeat"],"jsDoc":"Read `size` bytes from a 7-bit I2C `address`."},"parameters":[{"name":"address"},{"name":"size"},{"name":"repeat","type":"boolean","initializer":"0","default":"0"}],"isInstance":true,"pyQName":"I2C.read_buffer"},"I2C.writeBuffer":{"kind":-1,"retType":"number","attributes":{"paramDefl":{"repeat":"0"},"explicitDefaults":["repeat"],"jsDoc":"Write bytes to a 7-bit I2C `address`."},"parameters":[{"name":"address"},{"name":"buf","type":"Buffer"},{"name":"repeat","type":"boolean","initializer":"0","default":"0"}],"isInstance":true,"pyQName":"I2C.write_buffer"},"pins.createI2C":{"kind":-3,"retType":"I2C","attributes":{"help":"pins/create-i2c","parts":"i2c","jsDoc":"Opens a Serial communication driver"},"parameters":[{"name":"sda","type":"DigitalInOutPin"},{"name":"scl","type":"DigitalInOutPin"}],"pyQName":"pins.create_i2c"},"pins.createSPI":{"kind":-3,"retType":"SPI","attributes":{"help":"pins/create-spi","parts":"spi","jsDoc":"Opens a SPI driver"},"parameters":[{"name":"mosiPin","type":"DigitalInOutPin"},{"name":"misoPin","type":"DigitalInOutPin"},{"name":"sckPin","type":"DigitalInOutPin"}],"pyQName":"pins.create_spi"},"pins.createSlaveSPI":{"kind":-3,"retType":"SPI","attributes":{"parts":"spi","jsDoc":"Opens a slave SPI driver"},"parameters":[{"name":"mosiPin","type":"DigitalInOutPin"},{"name":"misoPin","type":"DigitalInOutPin"},{"name":"sckPin","type":"DigitalInOutPin"},{"name":"csPin","type":"DigitalInOutPin"}],"pyQName":"pins.create_slave_spi"},"SPI":{"kind":9,"retType":"SPI","extendsTypes":[]},"SPI.write":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Write to the SPI bus"},"parameters":[{"name":"value"}],"isInstance":true},"SPI.transfer":{"kind":-1,"attributes":{"argsNullable":true,"jsDoc":"Transfer buffers over the SPI bus"},"parameters":[{"name":"command","type":"Buffer"},{"name":"response","type":"Buffer"}],"isInstance":true},"SPI.setFrequency":{"kind":-1,"attributes":{"jsDoc":"Sets the SPI clock frequency"},"parameters":[{"name":"frequency"}],"isInstance":true,"pyQName":"SPI.set_frequency"},"SPI.setMode":{"kind":-1,"attributes":{"jsDoc":"Sets the SPI bus mode"},"parameters":[{"name":"mode"}],"isInstance":true,"pyQName":"SPI.set_mode"},"configStorage":{"kind":5,"retType":""},"configStorage.setBuffer":{"kind":-3,"attributes":{"paramHelp":{"key":"the identifier (max 16 characters)","value":"the data (max 32 characters)"},"jsDoc":"Puts an entry in the device storage. Key may have up to 16 characters (bytes)."},"parameters":[{"name":"key","description":"the identifier (max 16 characters)","type":"string"},{"name":"value","description":"the data (max 32 characters)","type":"Buffer"}],"pyQName":"configStorage.set_buffer"},"configStorage.getBuffer":{"kind":-3,"retType":"Buffer","attributes":{"paramHelp":{"key":"the identifier (max 16 characters)"},"jsDoc":"Gets an entry from the device storage. Key may have up to 16 characters (bytes)."},"parameters":[{"name":"key","description":"the identifier (max 16 characters)","type":"string"}],"pyQName":"configStorage.get_buffer"},"configStorage.removeItem":{"kind":-3,"attributes":{"paramHelp":{"key":"the identifier (max 16 characters)"},"jsDoc":"Removes the key from local storage"},"parameters":[{"name":"key","description":"the identifier (max 16 characters)","type":"string"}],"pyQName":"configStorage.remove_item"},"configStorage.clear":{"kind":-3,"attributes":{"jsDoc":"Clears the local storage"},"parameters":[]},"PulseValue":{"kind":6,"retType":"PulseValue","extendsTypes":["PulseValue","Number"]},"PulseValue.High":{"retType":"PulseValue.High","attributes":{"block":"high","_def":{"parts":[{"kind":"label","text":"high","style":[]}],"parameters":[]}},"extendsTypes":["PulseValue.High","Number"],"pyQName":"PulseValue.HIGH"},"PulseValue.Low":{"retType":"PulseValue.Low","attributes":{"block":"low","_def":{"parts":[{"kind":"label","text":"low","style":[]}],"parameters":[]}},"extendsTypes":["PulseValue.Low","Number"],"pyQName":"PulseValue.LOW"},"PinEvent":{"kind":6,"retType":"PinEvent","extendsTypes":["PinEvent","Number"]},"PinEvent.PulseHigh":{"retType":"PinEvent.PulseHigh","attributes":{"block":"pulse high","_def":{"parts":[{"kind":"label","text":"pulse high","style":[]}],"parameters":[]}},"extendsTypes":["PinEvent.PulseHigh","Number"],"pyQName":"PinEvent.PULSE_HIGH"},"PinEvent.PulseLow":{"retType":"PinEvent.PulseLow","attributes":{"block":"pulse low","_def":{"parts":[{"kind":"label","text":"pulse low","style":[]}],"parameters":[]}},"extendsTypes":["PinEvent.PulseLow","Number"],"pyQName":"PinEvent.PULSE_LOW"},"PinEvent.Rise":{"retType":"PinEvent.Rise","attributes":{"block":"rise","_def":{"parts":[{"kind":"label","text":"rise","style":[]}],"parameters":[]}},"extendsTypes":["PinEvent.Rise","Number"],"pyQName":"PinEvent.RISE"},"PinEvent.Fall":{"retType":"PinEvent.Fall","attributes":{"block":"fall","_def":{"parts":[{"kind":"label","text":"fall","style":[]}],"parameters":[]}},"extendsTypes":["PinEvent.Fall","Number"],"pyQName":"PinEvent.FALL"},"PinPullMode":{"kind":6,"retType":"PinPullMode","extendsTypes":["PinPullMode","Number"]},"PinPullMode.PullDown":{"retType":"PinPullMode.PullDown","attributes":{"block":"down","_def":{"parts":[{"kind":"label","text":"down","style":[]}],"parameters":[]}},"extendsTypes":["PinPullMode.PullDown","Number"],"pyQName":"PinPullMode.PULL_DOWN"},"PinPullMode.PullUp":{"retType":"PinPullMode.PullUp","attributes":{"block":"up","_def":{"parts":[{"kind":"label","text":"up","style":[]}],"parameters":[]}},"extendsTypes":["PinPullMode.PullUp","Number"],"pyQName":"PinPullMode.PULL_UP"},"PinPullMode.PullNone":{"retType":"PinPullMode.PullNone","attributes":{"block":"none","_def":{"parts":[{"kind":"label","text":"none","style":[]}],"parameters":[]}},"extendsTypes":["PinPullMode.PullNone","Number"],"pyQName":"PinPullMode.PULL_NONE"},"servos":{"kind":5,"retType":"","attributes":{"color":"#03AA74","weight":88,"icon":"","jsDoc":"Servos"}},"jacdac":{"kind":5,"retType":"","attributes":{"color":"#E79251","weight":1,"icon":"","groups":["Broadcast","Console","Control"],"blockGap":"8","jsDoc":"A Joint Asynchronous Communications, Device Agnostic Control."}},"control.Timer":{"kind":8,"retType":"control.Timer","attributes":{"fixedInstances":"true","jsDoc":"A timer"},"extendsTypes":[]},"control.Timer.start":{"kind":2,"retType":"number","isInstance":true},"control.Timer.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"control.Timer.millis":{"kind":-1,"retType":"number","attributes":{"blockId":"timerMillis","block":"%timer|millis","jsDoc":"Gets the elapsed time in millis since the last reset","_def":{"parts":[{"kind":"param","name":"timer","ref":false},{"kind":"break"},{"kind":"label","text":"millis","style":[]}],"parameters":[{"kind":"param","name":"timer","ref":false}]}},"parameters":[],"isInstance":true},"control.Timer.seconds":{"kind":-1,"retType":"number","attributes":{"blockId":"timerSeconds","block":"%timer|seconds","jsDoc":"Gets the elapsed time in seconds since the last reset","_def":{"parts":[{"kind":"param","name":"timer","ref":false},{"kind":"break"},{"kind":"label","text":"seconds","style":[]}],"parameters":[{"kind":"param","name":"timer","ref":false}]}},"parameters":[],"isInstance":true},"control.Timer.reset":{"kind":-1,"attributes":{"blockId":"timerRest","block":"%timer|reset","jsDoc":"Resets the timer","_def":{"parts":[{"kind":"param","name":"timer","ref":false},{"kind":"break"},{"kind":"label","text":"reset","style":[]}],"parameters":[{"kind":"param","name":"timer","ref":false}]}},"parameters":[],"isInstance":true},"control.Timer.pauseUntil":{"kind":-1,"attributes":{"paramDefl":{"ms":"5"},"blockId":"timerPauseUntil","block":"%timer|pause until (ms) %ms","paramHelp":{"ms":"how long to pause for, eg: 5, 100, 200, 500, 1000, 2000"},"jsDoc":"Pauses until the timer reaches the given amount of milliseconds","_def":{"parts":[{"kind":"param","name":"timer","ref":false},{"kind":"break"},{"kind":"label","text":"pause until (ms) ","style":[]},{"kind":"param","name":"ms","ref":false}],"parameters":[{"kind":"param","name":"timer","ref":false},{"kind":"param","name":"ms","ref":false}]}},"parameters":[{"name":"ms","description":"how long to pause for, eg: 5, 100, 200, 500, 1000, 2000","default":"5"}],"isInstance":true,"pyQName":"control.Timer.pause_until"},"control.timer1":{"kind":4,"retType":"control.Timer","attributes":{"whenUsed":"true","fixedInstance":"true","block":"timer 1","_def":{"parts":[{"kind":"label","text":"timer 1","style":[]}],"parameters":[]}}},"control.timer2":{"kind":4,"retType":"control.Timer","attributes":{"whenUsed":"true","fixedInstance":"true","block":"timer 2","_def":{"parts":[{"kind":"label","text":"timer 2","style":[]}],"parameters":[]}}},"control.timer3":{"kind":4,"retType":"control.Timer","attributes":{"whenUsed":"true","fixedInstance":"true","block":"timer 3","_def":{"parts":[{"kind":"label","text":"timer 3","style":[]}],"parameters":[]}}},"control.timer4":{"kind":4,"retType":"control.Timer","attributes":{"whenUsed":"true","fixedInstance":"true","block":"timer 4","_def":{"parts":[{"kind":"label","text":"timer 4","style":[]}],"parameters":[]}}},"control.timer5":{"kind":4,"retType":"control.Timer","attributes":{"whenUsed":"true","fixedInstance":"true","block":"timer 5","_def":{"parts":[{"kind":"label","text":"timer 5","style":[]}],"parameters":[]}}},"control.timer6":{"kind":4,"retType":"control.Timer","attributes":{"whenUsed":"true","fixedInstance":"true","block":"timer 6","_def":{"parts":[{"kind":"label","text":"timer 6","style":[]}],"parameters":[]}}},"control.timer7":{"kind":4,"retType":"control.Timer","attributes":{"whenUsed":"true","fixedInstance":"true","block":"timer 7","_def":{"parts":[{"kind":"label","text":"timer 7","style":[]}],"parameters":[]}}},"control.timer8":{"kind":4,"retType":"control.Timer","attributes":{"whenUsed":"true","fixedInstance":"true","block":"timer 8","_def":{"parts":[{"kind":"label","text":"timer 8","style":[]}],"parameters":[]}}},"configStorage.setItem":{"kind":-3,"attributes":{"paramHelp":{"key":"identifier of the key (max 16 characters)","value":"identifier of the value (max 32 characters)"},"jsDoc":"Stores the value at the key entry"},"parameters":[{"name":"key","description":"identifier of the key (max 16 characters)","type":"string"},{"name":"value","description":"identifier of the value (max 32 characters)","type":"string"}],"pyQName":"configStorage.set_item"},"configStorage.getItem":{"kind":-3,"retType":"string","attributes":{"paramHelp":{"key":"identifier of the key (max 16 characters)"},"jsDoc":"Retrieves the value at the key entry"},"parameters":[{"name":"key","description":"identifier of the key (max 16 characters)","type":"string"}],"pyQName":"configStorage.get_item"},"pins.LevelDetector":{"kind":8,"retType":"pins.LevelDetector","extendsTypes":[]},"pins.LevelDetector.id":{"kind":2,"retType":"number","isInstance":true},"pins.LevelDetector.min":{"kind":2,"retType":"number","isInstance":true},"pins.LevelDetector.max":{"kind":2,"retType":"number","isInstance":true},"pins.LevelDetector.lowThreshold":{"kind":2,"retType":"number","isInstance":true,"pyQName":"pins.LevelDetector.low_threshold"},"pins.LevelDetector.highThreshold":{"kind":2,"retType":"number","isInstance":true,"pyQName":"pins.LevelDetector.high_threshold"},"pins.LevelDetector.onHigh":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"pins.LevelDetector.on_high"},"pins.LevelDetector.onLow":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"pins.LevelDetector.on_low"},"pins.LevelDetector.onNeutral":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"pins.LevelDetector.on_neutral"},"pins.LevelDetector.transitionWindow":{"kind":2,"retType":"number","isInstance":true,"pyQName":"pins.LevelDetector.transition_window"},"pins.LevelDetector.transitionInterval":{"kind":2,"retType":"number","isInstance":true,"pyQName":"pins.LevelDetector.transition_interval"},"pins.LevelDetector.LEVEL_THRESHOLD_NEUTRAL":{"kind":2,"retType":"number"},"pins.LevelDetector.__constructor":{"kind":-3,"parameters":[{"name":"id"},{"name":"min"},{"name":"max"},{"name":"lowThreshold"},{"name":"highThreshold"}],"isInstance":true},"pins.LevelDetector.reset":{"kind":-1,"parameters":[],"isInstance":true},"pins.LevelDetector.level":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"pins.LevelDetector.level@set":{"kind":-2,"retType":"number","isInstance":true},"pins.LevelDetector.setLowThreshold":{"kind":-1,"parameters":[{"name":"value"}],"isInstance":true,"pyQName":"pins.LevelDetector.set_low_threshold"},"pins.LevelDetector.setHighThreshold":{"kind":-1,"parameters":[{"name":"value"}],"isInstance":true,"pyQName":"pins.LevelDetector.set_high_threshold"},"MusicOutput":{"kind":6,"retType":"MusicOutput","extendsTypes":["MusicOutput","Number"]},"MusicOutput.AutoDetect":{"retType":"MusicOutput.AutoDetect","extendsTypes":["MusicOutput.AutoDetect","Number"],"pyQName":"MusicOutput.AUTO_DETECT"},"MusicOutput.Buzzer":{"retType":"MusicOutput.Buzzer","extendsTypes":["MusicOutput.Buzzer","Number"],"pyQName":"MusicOutput.BUZZER"},"MusicOutput.HeadPhones":{"retType":"MusicOutput.HeadPhones","extendsTypes":["MusicOutput.HeadPhones","Number"],"pyQName":"MusicOutput.HEAD_PHONES"},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"music.forceOutput":{"kind":-3,"parameters":[{"name":"buf","type":"MusicOutput","isEnum":true}],"pyQName":"music.force_output"},"music.setVolume":{"kind":-3,"attributes":{"paramDefl":{"volume":"20"},"blockId":"synth_set_volume","block":"set volume %volume","parts":"speaker","paramMin":{"volume":"0"},"paramMax":{"volume":"255"},"explicitDefaults":["volume"],"help":"music/set-volume","weight":70,"group":"Volume","paramHelp":{"volume":"the volume 0...255"},"jsDoc":"Set the default output volume of the sound synthesizer.","_def":{"parts":[{"kind":"label","text":"set volume ","style":[]},{"kind":"param","name":"volume","ref":false}],"parameters":[{"kind":"param","name":"volume","ref":false}]}},"parameters":[{"name":"volume","description":"the volume 0...255","initializer":"20","default":"20","options":{"min":{"value":"0"},"max":{"value":"255"}}}],"pyQName":"music.set_volume"},"music.volume":{"kind":-3,"retType":"number","attributes":{"parts":"speaker","weight":70,"jsDoc":"Gets the current volume"},"parameters":[]},"music.playTone":{"kind":-3,"attributes":{"paramDefl":{"frequency":"Note.C","ms":"BeatFraction.Half"},"callingConvention":1,"help":"music/play-tone","blockId":"mixer_play_note","block":"play tone|at %note=device_note|for %duration=device_beat","parts":"headphone","async":"true","blockNamespace":"music","weight":76,"blockGap":"8","group":"Tone","deprecated":"1","paramHelp":{"frequency":"pitch of the tone to play in Hertz (Hz), eg: Note.C","ms":"tone duration in milliseconds (ms), eg: BeatFraction.Half"},"jsDoc":"Play a tone through the speaker for some amount of time.","_def":{"parts":[{"kind":"label","text":"play tone","style":[]},{"kind":"break"},{"kind":"label","text":"at ","style":[]},{"kind":"param","name":"note","shadowBlockId":"device_note","ref":false},{"kind":"break"},{"kind":"label","text":"for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"device_beat","ref":false}],"parameters":[{"kind":"param","name":"note","shadowBlockId":"device_note","ref":false},{"kind":"param","name":"duration","shadowBlockId":"device_beat","ref":false}]}},"parameters":[{"name":"frequency","description":"pitch of the tone to play in Hertz (Hz), eg: Note.C","default":"Note.C"},{"name":"ms","description":"tone duration in milliseconds (ms), eg: BeatFraction.Half","default":"BeatFraction.Half"}],"pyQName":"music.play_tone"},"music.playMelody":{"kind":-3,"attributes":{"paramDefl":{"tempo":"120"},"block":"play melody $melody at tempo $tempo|(bpm)","blockId":"playMelody","blockNamespace":"music","weight":85,"blockGap":"8","help":"music/play-melody","group":"Melody","_shadowOverrides":{"melody":"melody_editor"},"paramMin":{"tempo":"40"},"paramMax":{"tempo":"500"},"explicitDefaults":["tempo"],"deprecated":"1","paramHelp":{"melody":"- string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces,","tempo":"- number in beats per minute (bpm), dictating how long each note will play for"},"jsDoc":"Play a melody from the melody editor.\n\nwhich will be played one at a time, ex: \"E D G F B A C5 B \"","_def":{"parts":[{"kind":"label","text":"play melody ","style":[]},{"kind":"param","name":"melody","shadowBlockId":"melody_editor","ref":true},{"kind":"label","text":" at tempo ","style":[]},{"kind":"param","name":"tempo","ref":true},{"kind":"break"},{"kind":"label","text":"(bpm)","style":[]}],"parameters":[{"kind":"param","name":"melody","shadowBlockId":"melody_editor","ref":true},{"kind":"param","name":"tempo","ref":true}]}},"parameters":[{"name":"melody","description":"- string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces,","type":"string"},{"name":"tempo","description":"- number in beats per minute (bpm), dictating how long each note will play for","initializer":"120","default":"120","options":{"min":{"value":"40"},"max":{"value":"500"}}}],"pyQName":"music.play_melody"},"music.melodyEditor":{"kind":-3,"retType":"string","attributes":{"block":"$melody","blockId":"melody_editor","blockNamespace":"music","blockHidden":true,"weight":85,"blockGap":"8","help":"music/melody-editor","group":"Melody","duplicateShadowOnDrag":true,"paramFieldEditor":{"melody":"melody"},"paramFieldEditorOptions":{"melody":{"decompileLiterals":"true","decompileIndirectFixedInstances":"true","onParentBlock":"true"}},"shim":"TD_ID","paramHelp":{"melody":""},"jsDoc":"Create a melody with the melody editor.","_def":{"parts":[{"kind":"param","name":"melody","ref":true}],"parameters":[{"kind":"param","name":"melody","ref":true}]}},"parameters":[{"name":"melody","type":"string"}],"pyQName":"music.melody_editor"},"music.stopAllSounds":{"kind":-3,"attributes":{"help":"music/stop-all-sounds","blockId":"music_stop_all_sounds","block":"stop all sounds","weight":45,"group":"Sounds","jsDoc":"Stop all sounds from playing.","_def":{"parts":[{"kind":"label","text":"stop all sounds","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"music.stop_all_sounds"},"music.Melody":{"kind":8,"retType":"music.Melody","attributes":{"fixedInstances":"true"},"extendsTypes":[]},"music.Melody._text":{"kind":2,"retType":"string","isInstance":true},"music.Melody.stopAll":{"kind":-1,"parameters":[],"pyQName":"music.Melody.stop_all"},"music.Melody.__constructor":{"kind":-3,"parameters":[{"name":"text","type":"string"}],"isInstance":true},"music.Melody.text":{"kind":-2,"retType":"string","isInstance":true,"isReadOnly":true},"music.Melody.stop":{"kind":-1,"attributes":{"blockId":"mixer_stop","block":"stop sound %sound","help":"music/melody/stop","parts":"headphone","weight":92,"blockGap":"8","group":"Sounds","deprecated":"1","jsDoc":"Stop playing a sound","_def":{"parts":[{"kind":"label","text":"stop sound ","style":[]},{"kind":"param","name":"sound","ref":false}],"parameters":[{"kind":"param","name":"sound","ref":false}]}},"parameters":[],"isInstance":true},"music.Melody.loop":{"kind":-1,"attributes":{"help":"music/melody/loop","blockId":"mixer_loop_sound","block":"loop sound %sound","parts":"headphone","weight":93,"blockGap":"8","group":"Sounds","deprecated":"1","paramHelp":{"sound":"the melody to play"},"jsDoc":"Start playing a sound in a loop and don't wait for it to finish.","_def":{"parts":[{"kind":"label","text":"loop sound ","style":[]},{"kind":"param","name":"sound","ref":false}],"parameters":[{"kind":"param","name":"sound","ref":false}]}},"parameters":[{"name":"volume","initializer":"255"}],"isInstance":true},"music.Melody.play":{"kind":-1,"attributes":{"help":"music/melody/play","blockId":"mixer_play_sound","block":"play sound %sound","parts":"headphone","weight":95,"blockGap":"8","group":"Sounds","deprecated":"1","paramHelp":{"sound":"the melody to play"},"jsDoc":"Start playing a sound and don't wait for it to finish.","_def":{"parts":[{"kind":"label","text":"play sound ","style":[]},{"kind":"param","name":"sound","ref":false}],"parameters":[{"kind":"param","name":"sound","ref":false}]}},"parameters":[{"name":"volume","initializer":"255"}],"isInstance":true},"music.Melody.playUntilDone":{"kind":-1,"attributes":{"help":"music/melody/play-until-done","blockId":"mixer_play_sound_until_done","block":"play sound %sound|until done","parts":"headphone","weight":94,"blockGap":"8","group":"Sounds","deprecated":"1","paramHelp":{"sound":"the melody to play"},"jsDoc":"Play a sound and wait until the sound is done.","_def":{"parts":[{"kind":"label","text":"play sound ","style":[]},{"kind":"param","name":"sound","ref":false},{"kind":"break"},{"kind":"label","text":"until done","style":[]}],"parameters":[{"kind":"param","name":"sound","ref":false}]}},"parameters":[{"name":"volume","initializer":"255"}],"isInstance":true,"pyQName":"music.Melody.play_until_done"},"music.Melody.toString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"music.Melody.to_string"},"music.addNote":{"kind":-3,"retType":"number","parameters":[{"name":"sndInstr","type":"Buffer"},{"name":"sndInstrPtr"},{"name":"ms"},{"name":"beg"},{"name":"end"},{"name":"soundWave"},{"name":"hz"},{"name":"volume"},{"name":"endHz"}],"pyQName":"music.add_note"},"music.MelodyPlayer":{"kind":8,"retType":"music.MelodyPlayer","extendsTypes":[]},"music.MelodyPlayer.melody":{"kind":2,"retType":"music.Melody","isInstance":true},"music.MelodyPlayer.onPlayFinished":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"music.MelodyPlayer.on_play_finished"},"music.MelodyPlayer.__constructor":{"kind":-3,"parameters":[{"name":"m","type":"music.Melody"}],"isInstance":true},"music.MelodyPlayer.stop":{"kind":-1,"parameters":[],"isInstance":true},"music.MelodyPlayer.play":{"kind":-1,"parameters":[{"name":"volume"}],"isInstance":true},"music.createSong":{"kind":-3,"retType":"music.Playable","attributes":{"blockId":"music_song_field_editor","block":"song $song","paramFieldEditor":{"song":"musiceditor"},"paramFieldEditorOptions":{"song":{"decompileLiterals":"true","taggedTemplate":"hex;assets.song","decompileIndirectFixedInstances":"true","decompileArgumentAsString":"true"}},"toolboxParent":"music_playable_play","toolboxParentArgument":"toPlay","group":"Songs","duplicateShadowOnDrag":true,"help":"music/create-song","_def":{"parts":[{"kind":"label","text":"song ","style":[]},{"kind":"param","name":"song","ref":true}],"parameters":[{"kind":"param","name":"song","ref":true}]}},"parameters":[{"name":"song","type":"Buffer"}],"pyQName":"music.create_song"},"music.playInstructions":{"kind":-3,"parameters":[{"name":"when"},{"name":"instructions","type":"Buffer"}],"pyQName":"music.play_instructions"},"music.lookupFrequency":{"kind":-3,"retType":"number","parameters":[{"name":"note"}],"pyQName":"music.lookup_frequency"},"music.baDing":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"ba ding","_def":{"parts":[{"kind":"label","text":"ba ding","style":[]}],"parameters":[]}},"pyQName":"music.ba_ding"},"music.wawawawaa":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"wawawawaa","_def":{"parts":[{"kind":"label","text":"wawawawaa","style":[]}],"parameters":[]}}},"music.jumpUp":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"jump up","_def":{"parts":[{"kind":"label","text":"jump up","style":[]}],"parameters":[]}},"pyQName":"music.jump_up"},"music.jumpDown":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"jump down","_def":{"parts":[{"kind":"label","text":"jump down","style":[]}],"parameters":[]}},"pyQName":"music.jump_down"},"music.powerUp":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"power up","_def":{"parts":[{"kind":"label","text":"power up","style":[]}],"parameters":[]}},"pyQName":"music.power_up"},"music.powerDown":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"power down","_def":{"parts":[{"kind":"label","text":"power down","style":[]}],"parameters":[]}},"pyQName":"music.power_down"},"music.magicWand":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"magic wand","_def":{"parts":[{"kind":"label","text":"magic wand","style":[]}],"parameters":[]}},"pyQName":"music.magic_wand"},"music.siren":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"siren","_def":{"parts":[{"kind":"label","text":"siren","style":[]}],"parameters":[]}}},"music.pewPew":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"pew pew","_def":{"parts":[{"kind":"label","text":"pew pew","style":[]}],"parameters":[]}},"pyQName":"music.pew_pew"},"music.knock":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"knock","_def":{"parts":[{"kind":"label","text":"knock","style":[]}],"parameters":[]}}},"music.footstep":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"footstep","_def":{"parts":[{"kind":"label","text":"footstep","style":[]}],"parameters":[]}}},"music.thump":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"thump","_def":{"parts":[{"kind":"label","text":"thump","style":[]}],"parameters":[]}}},"music.smallCrash":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"small crash","_def":{"parts":[{"kind":"label","text":"small crash","style":[]}],"parameters":[]}},"pyQName":"music.small_crash"},"music.bigCrash":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"big crash","_def":{"parts":[{"kind":"label","text":"big crash","style":[]}],"parameters":[]}},"pyQName":"music.big_crash"},"music.zapped":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"zapped","_def":{"parts":[{"kind":"label","text":"zapped","style":[]}],"parameters":[]}}},"music.buzzer":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"buzzer","_def":{"parts":[{"kind":"label","text":"buzzer","style":[]}],"parameters":[]}}},"music.sonar":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"sonar","_def":{"parts":[{"kind":"label","text":"sonar","style":[]}],"parameters":[]}}},"music.spooky":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"spooky","_def":{"parts":[{"kind":"label","text":"spooky","style":[]}],"parameters":[]}}},"music.beamUp":{"kind":4,"retType":"music.Melody","attributes":{"fixedInstance":"true","whenUsed":"true","block":"beam up","_def":{"parts":[{"kind":"label","text":"beam up","style":[]}],"parameters":[]}},"pyQName":"music.beam_up"},"music.noteFrequency":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"note":"262","name":"Note.C"},"weight":10,"help":"music/note-frequency","blockId":"device_note","block":"%note","shim":"TD_ID","color":"#FFFFFF","colorSecondary":"#FFFFFF","colorTertiary":"#D83B01","paramFieldEditor":{"note":"note"},"explicitDefaults":["note"],"paramFieldEditorOptions":{"note":{"decompileLiterals":"true"}},"useEnumVal":"1","blockGap":"8","group":"Tone","paramHelp":{"name":"the note name, eg: Note.C"},"jsDoc":"Get the frequency of a note.","_def":{"parts":[{"kind":"param","name":"note","ref":false}],"parameters":[{"kind":"param","name":"note","ref":false}]}},"parameters":[{"name":"name","description":"the note name, eg: Note.C","type":"Note","default":"Note.C","isEnum":true}],"pyQName":"music.note_frequency"},"Sounds":{"kind":6,"retType":"Sounds","attributes":{"deprecated":"true","hidden":"true"},"extendsTypes":["Sounds","Number"]},"Sounds.PowerUp":{"retType":"Sounds.PowerUp","attributes":{"block":"power up","_def":{"parts":[{"kind":"label","text":"power up","style":[]}],"parameters":[]}},"extendsTypes":["Sounds.PowerUp","Number"],"pyQName":"Sounds.POWER_UP"},"Sounds.PowerDown":{"retType":"Sounds.PowerDown","attributes":{"block":"power down","_def":{"parts":[{"kind":"label","text":"power down","style":[]}],"parameters":[]}},"extendsTypes":["Sounds.PowerDown","Number"],"pyQName":"Sounds.POWER_DOWN"},"Sounds.JumpUp":{"retType":"Sounds.JumpUp","attributes":{"block":"jump up","_def":{"parts":[{"kind":"label","text":"jump up","style":[]}],"parameters":[]}},"extendsTypes":["Sounds.JumpUp","Number"],"pyQName":"Sounds.JUMP_UP"},"Sounds.JumpDown":{"retType":"Sounds.JumpDown","attributes":{"block":"jump down","_def":{"parts":[{"kind":"label","text":"jump down","style":[]}],"parameters":[]}},"extendsTypes":["Sounds.JumpDown","Number"],"pyQName":"Sounds.JUMP_DOWN"},"Sounds.BaDing":{"retType":"Sounds.BaDing","attributes":{"block":"ba ding","_def":{"parts":[{"kind":"label","text":"ba ding","style":[]}],"parameters":[]}},"extendsTypes":["Sounds.BaDing","Number"],"pyQName":"Sounds.BA_DING"},"Sounds.Wawawawaa":{"retType":"Sounds.Wawawawaa","attributes":{"block":"wawawawaa","_def":{"parts":[{"kind":"label","text":"wawawawaa","style":[]}],"parameters":[]}},"extendsTypes":["Sounds.Wawawawaa","Number"],"pyQName":"Sounds.WAWAWAWAA"},"Sounds.MagicWand":{"retType":"Sounds.MagicWand","attributes":{"block":"magic wand","_def":{"parts":[{"kind":"label","text":"magic wand","style":[]}],"parameters":[]}},"extendsTypes":["Sounds.MagicWand","Number"],"pyQName":"Sounds.MAGIC_WAND"},"Sounds.Siren":{"retType":"Sounds.Siren","attributes":{"block":"siren","_def":{"parts":[{"kind":"label","text":"siren","style":[]}],"parameters":[]}},"extendsTypes":["Sounds.Siren","Number"],"pyQName":"Sounds.SIREN"},"music.sounds":{"kind":-3,"retType":"string","attributes":{"paramDefl":{"name":"Note.C"},"help":"music/sounds","blockId":"music_sounds","block":"%name","blockHidden":true,"paramFieldEditor":{"name":"gridpicker"},"paramFieldEditorOptions":{"name":{"width":"285","columns":"3"}},"paramHelp":{"name":"the note name, eg: Note.C"},"jsDoc":"Get the melody string for a built-in melody.","_def":{"parts":[{"kind":"param","name":"name","ref":false}],"parameters":[{"kind":"param","name":"name","ref":false}]}},"parameters":[{"name":"name","description":"the note name, eg: Note.C","type":"Sounds","default":"Note.C","isEnum":true}]},"music.playSound":{"kind":-3,"attributes":{"help":"music/play-sound","blockId":"music_play_sound","block":"play sound %sound=music_sounds","parts":"headphone","weight":95,"blockGap":"8","deprecated":"true","hidden":"true","paramHelp":{"sound":"the melody to play"},"jsDoc":"Start playing a sound and don't wait for it to finish.\nNotes are expressed as a string of characters with this format: NOTE[octave][:duration]","_def":{"parts":[{"kind":"label","text":"play sound ","style":[]},{"kind":"param","name":"sound","shadowBlockId":"music_sounds","ref":false}],"parameters":[{"kind":"param","name":"sound","shadowBlockId":"music_sounds","ref":false}]}},"parameters":[{"name":"sound","description":"the melody to play","type":"string"}],"pyQName":"music.play_sound"},"music.playSoundUntilDone":{"kind":-3,"attributes":{"help":"music/play-sound-until-done","blockId":"music_play_sound_until_done","block":"play sound %sound=music_sounds|until done","parts":"headphone","weight":94,"blockGap":"8","deprecated":"true","hidden":"true","paramHelp":{"sound":"the melody to play"},"jsDoc":"Play a sound and wait until the sound is done.\nNotes are expressed as a string of characters with this format: NOTE[octave][:duration]","_def":{"parts":[{"kind":"label","text":"play sound ","style":[]},{"kind":"param","name":"sound","shadowBlockId":"music_sounds","ref":false},{"kind":"break"},{"kind":"label","text":"until done","style":[]}],"parameters":[{"kind":"param","name":"sound","shadowBlockId":"music_sounds","ref":false}]}},"parameters":[{"name":"sound","description":"the melody to play","type":"string"}],"pyQName":"music.play_sound_until_done"},"Note":{"kind":6,"retType":"Note","extendsTypes":["Note","Number"]},"Note.C":{"retType":"Note.C","attributes":{"blockIdentity":"music.noteFrequency","enumval":"262"},"extendsTypes":["Note.C","Number"]},"Note.CSharp":{"retType":"Note.CSharp","attributes":{"block":"C#","blockIdentity":"music.noteFrequency","enumval":"277","_def":{"parts":[{"kind":"label","text":"C#","style":[]}],"parameters":[]}},"extendsTypes":["Note.CSharp","Number"],"pyQName":"Note.CSHARP"},"Note.D":{"retType":"Note.D","attributes":{"blockIdentity":"music.noteFrequency","enumval":"294"},"extendsTypes":["Note.D","Number"]},"Note.Eb":{"retType":"Note.Eb","attributes":{"blockIdentity":"music.noteFrequency","enumval":"311"},"extendsTypes":["Note.Eb","Number"],"pyQName":"Note.EB"},"Note.E":{"retType":"Note.E","attributes":{"blockIdentity":"music.noteFrequency","enumval":"330"},"extendsTypes":["Note.E","Number"]},"Note.F":{"retType":"Note.F","attributes":{"blockIdentity":"music.noteFrequency","enumval":"349"},"extendsTypes":["Note.F","Number"]},"Note.FSharp":{"retType":"Note.FSharp","attributes":{"block":"F#","blockIdentity":"music.noteFrequency","enumval":"370","_def":{"parts":[{"kind":"label","text":"F#","style":[]}],"parameters":[]}},"extendsTypes":["Note.FSharp","Number"],"pyQName":"Note.FSHARP"},"Note.G":{"retType":"Note.G","attributes":{"blockIdentity":"music.noteFrequency","enumval":"392"},"extendsTypes":["Note.G","Number"]},"Note.GSharp":{"retType":"Note.GSharp","attributes":{"block":"G#","blockIdentity":"music.noteFrequency","enumval":"415","_def":{"parts":[{"kind":"label","text":"G#","style":[]}],"parameters":[]}},"extendsTypes":["Note.GSharp","Number"],"pyQName":"Note.GSHARP"},"Note.A":{"retType":"Note.A","attributes":{"blockIdentity":"music.noteFrequency","enumval":"440"},"extendsTypes":["Note.A","Number"]},"Note.Bb":{"retType":"Note.Bb","attributes":{"blockIdentity":"music.noteFrequency","enumval":"466"},"extendsTypes":["Note.Bb","Number"],"pyQName":"Note.BB"},"Note.B":{"retType":"Note.B","attributes":{"blockIdentity":"music.noteFrequency","enumval":"494"},"extendsTypes":["Note.B","Number"]},"Note.C3":{"retType":"Note.C3","attributes":{"blockIdentity":"music.noteFrequency","enumval":"131"},"extendsTypes":["Note.C3","Number"]},"Note.CSharp3":{"retType":"Note.CSharp3","attributes":{"block":"C#3","blockIdentity":"music.noteFrequency","enumval":"139","_def":{"parts":[{"kind":"label","text":"C#3","style":[]}],"parameters":[]}},"extendsTypes":["Note.CSharp3","Number"],"pyQName":"Note.CSHARP3"},"Note.D3":{"retType":"Note.D3","attributes":{"blockIdentity":"music.noteFrequency","enumval":"147"},"extendsTypes":["Note.D3","Number"]},"Note.Eb3":{"retType":"Note.Eb3","attributes":{"blockIdentity":"music.noteFrequency","enumval":"156"},"extendsTypes":["Note.Eb3","Number"],"pyQName":"Note.EB3"},"Note.E3":{"retType":"Note.E3","attributes":{"blockIdentity":"music.noteFrequency","enumval":"165"},"extendsTypes":["Note.E3","Number"]},"Note.F3":{"retType":"Note.F3","attributes":{"blockIdentity":"music.noteFrequency","enumval":"175"},"extendsTypes":["Note.F3","Number"]},"Note.FSharp3":{"retType":"Note.FSharp3","attributes":{"block":"F#3","blockIdentity":"music.noteFrequency","enumval":"185","_def":{"parts":[{"kind":"label","text":"F#3","style":[]}],"parameters":[]}},"extendsTypes":["Note.FSharp3","Number"],"pyQName":"Note.FSHARP3"},"Note.G3":{"retType":"Note.G3","attributes":{"blockIdentity":"music.noteFrequency","enumval":"196"},"extendsTypes":["Note.G3","Number"]},"Note.GSharp3":{"retType":"Note.GSharp3","attributes":{"block":"G#3","blockIdentity":"music.noteFrequency","enumval":"208","_def":{"parts":[{"kind":"label","text":"G#3","style":[]}],"parameters":[]}},"extendsTypes":["Note.GSharp3","Number"],"pyQName":"Note.GSHARP3"},"Note.A3":{"retType":"Note.A3","attributes":{"blockIdentity":"music.noteFrequency","enumval":"220"},"extendsTypes":["Note.A3","Number"]},"Note.Bb3":{"retType":"Note.Bb3","attributes":{"blockIdentity":"music.noteFrequency","enumval":"233"},"extendsTypes":["Note.Bb3","Number"],"pyQName":"Note.BB3"},"Note.B3":{"retType":"Note.B3","attributes":{"blockIdentity":"music.noteFrequency","enumval":"247"},"extendsTypes":["Note.B3","Number"]},"Note.C4":{"retType":"Note.C","attributes":{"blockIdentity":"music.noteFrequency","enumval":"262"},"extendsTypes":["Note.C4","Number"]},"Note.CSharp4":{"retType":"Note.CSharp","attributes":{"block":"C#4","blockIdentity":"music.noteFrequency","enumval":"277","_def":{"parts":[{"kind":"label","text":"C#4","style":[]}],"parameters":[]}},"extendsTypes":["Note.CSharp4","Number"],"pyQName":"Note.CSHARP4"},"Note.D4":{"retType":"Note.D","attributes":{"blockIdentity":"music.noteFrequency","enumval":"294"},"extendsTypes":["Note.D4","Number"]},"Note.Eb4":{"retType":"Note.Eb","attributes":{"blockIdentity":"music.noteFrequency","enumval":"311"},"extendsTypes":["Note.Eb4","Number"],"pyQName":"Note.EB4"},"Note.E4":{"retType":"Note.E","attributes":{"blockIdentity":"music.noteFrequency","enumval":"330"},"extendsTypes":["Note.E4","Number"]},"Note.F4":{"retType":"Note.F","attributes":{"blockIdentity":"music.noteFrequency","enumval":"349"},"extendsTypes":["Note.F4","Number"]},"Note.FSharp4":{"retType":"Note.FSharp","attributes":{"block":"F#4","blockIdentity":"music.noteFrequency","enumval":"370","_def":{"parts":[{"kind":"label","text":"F#4","style":[]}],"parameters":[]}},"extendsTypes":["Note.FSharp4","Number"],"pyQName":"Note.FSHARP4"},"Note.G4":{"retType":"Note.G","attributes":{"blockIdentity":"music.noteFrequency","enumval":"392"},"extendsTypes":["Note.G4","Number"]},"Note.GSharp4":{"retType":"Note.GSharp","attributes":{"block":"G#4","blockIdentity":"music.noteFrequency","enumval":"415","_def":{"parts":[{"kind":"label","text":"G#4","style":[]}],"parameters":[]}},"extendsTypes":["Note.GSharp4","Number"],"pyQName":"Note.GSHARP4"},"Note.A4":{"retType":"Note.A","attributes":{"blockIdentity":"music.noteFrequency","enumval":"440"},"extendsTypes":["Note.A4","Number"]},"Note.Bb4":{"retType":"Note.Bb","attributes":{"blockIdentity":"music.noteFrequency","enumval":"466"},"extendsTypes":["Note.Bb4","Number"],"pyQName":"Note.BB4"},"Note.B4":{"retType":"Note.B","attributes":{"blockIdentity":"music.noteFrequency","enumval":"494"},"extendsTypes":["Note.B4","Number"]},"Note.C5":{"retType":"Note.C5","attributes":{"blockIdentity":"music.noteFrequency","enumval":"523"},"extendsTypes":["Note.C5","Number"]},"Note.CSharp5":{"retType":"Note.CSharp5","attributes":{"block":"C#5","blockIdentity":"music.noteFrequency","enumval":"555","_def":{"parts":[{"kind":"label","text":"C#5","style":[]}],"parameters":[]}},"extendsTypes":["Note.CSharp5","Number"],"pyQName":"Note.CSHARP5"},"Note.D5":{"retType":"Note.D5","attributes":{"blockIdentity":"music.noteFrequency","enumval":"587"},"extendsTypes":["Note.D5","Number"]},"Note.Eb5":{"retType":"Note.Eb5","attributes":{"blockIdentity":"music.noteFrequency","enumval":"622"},"extendsTypes":["Note.Eb5","Number"],"pyQName":"Note.EB5"},"Note.E5":{"retType":"Note.E5","attributes":{"blockIdentity":"music.noteFrequency","enumval":"659"},"extendsTypes":["Note.E5","Number"]},"Note.F5":{"retType":"Note.F5","attributes":{"blockIdentity":"music.noteFrequency","enumval":"698"},"extendsTypes":["Note.F5","Number"]},"Note.FSharp5":{"retType":"Note.FSharp5","attributes":{"block":"F#5","blockIdentity":"music.noteFrequency","enumval":"740","_def":{"parts":[{"kind":"label","text":"F#5","style":[]}],"parameters":[]}},"extendsTypes":["Note.FSharp5","Number"],"pyQName":"Note.FSHARP5"},"Note.G5":{"retType":"Note.G5","attributes":{"blockIdentity":"music.noteFrequency","enumval":"784"},"extendsTypes":["Note.G5","Number"]},"Note.GSharp5":{"retType":"Note.GSharp5","attributes":{"block":"G#5","blockIdentity":"music.noteFrequency","enumval":"831","_def":{"parts":[{"kind":"label","text":"G#5","style":[]}],"parameters":[]}},"extendsTypes":["Note.GSharp5","Number"],"pyQName":"Note.GSHARP5"},"Note.A5":{"retType":"Note.A5","attributes":{"blockIdentity":"music.noteFrequency","enumval":"880"},"extendsTypes":["Note.A5","Number"]},"Note.Bb5":{"retType":"Note.Bb5","attributes":{"blockIdentity":"music.noteFrequency","enumval":"932"},"extendsTypes":["Note.Bb5","Number"],"pyQName":"Note.BB5"},"Note.B5":{"retType":"Note.B5","attributes":{"blockIdentity":"music.noteFrequency","enumval":"988"},"extendsTypes":["Note.B5","Number"]},"BeatFraction":{"kind":6,"retType":"BeatFraction","extendsTypes":["BeatFraction","Number"]},"BeatFraction.Whole":{"retType":"BeatFraction.Whole","attributes":{"block":"1","_def":{"parts":[{"kind":"label","text":"1","style":[]}],"parameters":[]}},"extendsTypes":["BeatFraction.Whole","Number"],"pyQName":"BeatFraction.WHOLE"},"BeatFraction.Half":{"retType":"BeatFraction.Half","attributes":{"block":"1/2","_def":{"parts":[{"kind":"label","text":"1/2","style":[]}],"parameters":[]}},"extendsTypes":["BeatFraction.Half","Number"],"pyQName":"BeatFraction.HALF"},"BeatFraction.Quarter":{"retType":"BeatFraction.Quarter","attributes":{"block":"1/4","_def":{"parts":[{"kind":"label","text":"1/4","style":[]}],"parameters":[]}},"extendsTypes":["BeatFraction.Quarter","Number"],"pyQName":"BeatFraction.QUARTER"},"BeatFraction.Eighth":{"retType":"BeatFraction.Eighth","attributes":{"block":"1/8","_def":{"parts":[{"kind":"label","text":"1/8","style":[]}],"parameters":[]}},"extendsTypes":["BeatFraction.Eighth","Number"],"pyQName":"BeatFraction.EIGHTH"},"BeatFraction.Sixteenth":{"retType":"BeatFraction.Sixteenth","attributes":{"block":"1/16","_def":{"parts":[{"kind":"label","text":"1/16","style":[]}],"parameters":[]}},"extendsTypes":["BeatFraction.Sixteenth","Number"],"pyQName":"BeatFraction.SIXTEENTH"},"BeatFraction.Double":{"retType":"BeatFraction.Double","attributes":{"block":"2","_def":{"parts":[{"kind":"label","text":"2","style":[]}],"parameters":[]}},"extendsTypes":["BeatFraction.Double","Number"],"pyQName":"BeatFraction.DOUBLE"},"BeatFraction.Breve":{"retType":"BeatFraction.Breve","attributes":{"block":"4","_def":{"parts":[{"kind":"label","text":"4","style":[]}],"parameters":[]}},"extendsTypes":["BeatFraction.Breve","Number"],"pyQName":"BeatFraction.BREVE"},"BeatFraction.Triplet":{"retType":"BeatFraction.Triplet","attributes":{"block":"1/3","_def":{"parts":[{"kind":"label","text":"1/3","style":[]}],"parameters":[]}},"extendsTypes":["BeatFraction.Triplet","Number"],"pyQName":"BeatFraction.TRIPLET"},"music.ringTone":{"kind":-3,"attributes":{"paramDefl":{"frequency":"Note.C"},"help":"music/ring-tone","blockId":"music_ring","block":"ring tone|at %note=device_note","parts":"headphone","trackArgs":[0],"blockNamespace":"music","inBasicCategory":"true","weight":75,"blockGap":"8","group":"Tone","paramHelp":{"frequency":"pitch of the tone to play in Hertz (Hz), eg: Note.C"},"jsDoc":"Play a tone.","_def":{"parts":[{"kind":"label","text":"ring tone","style":[]},{"kind":"break"},{"kind":"label","text":"at ","style":[]},{"kind":"param","name":"note","shadowBlockId":"device_note","ref":false}],"parameters":[{"kind":"param","name":"note","shadowBlockId":"device_note","ref":false}]}},"parameters":[{"name":"frequency","description":"pitch of the tone to play in Hertz (Hz), eg: Note.C","default":"Note.C"}],"pyQName":"music.ring_tone"},"music.rest":{"kind":-3,"attributes":{"paramDefl":{"ms":"BeatFraction.Half"},"help":"music/rest","blockId":"music_rest","block":"rest|for %duration=device_beat","parts":"headphone","trackArgs":[0],"blockNamespace":"music","weight":74,"group":"Tone","paramHelp":{"ms":"rest duration in milliseconds (ms), eg: BeatFraction.Half"},"jsDoc":"Rest, or play silence, for some time (in milliseconds).","_def":{"parts":[{"kind":"label","text":"rest","style":[]},{"kind":"break"},{"kind":"label","text":"for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"device_beat","ref":false}],"parameters":[{"kind":"param","name":"duration","shadowBlockId":"device_beat","ref":false}]}},"parameters":[{"name":"ms","description":"rest duration in milliseconds (ms), eg: BeatFraction.Half","default":"BeatFraction.Half"}]},"music.beat":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"fraction":"BeatFraction.Half"},"help":"music/beat","blockId":"device_beat","block":"%fraction|beat","weight":9,"blockGap":"8","group":"Tempo","paramHelp":{"fraction":"the fraction of the current whole note, eg: BeatFraction.Half"},"jsDoc":"Return the duration of a beat in milliseconds (the beat fraction).","_def":{"parts":[{"kind":"param","name":"fraction","ref":false},{"kind":"break"},{"kind":"label","text":"beat","style":[]}],"parameters":[{"kind":"param","name":"fraction","ref":false}]}},"parameters":[{"name":"fraction","description":"the fraction of the current whole note, eg: BeatFraction.Half","type":"BeatFraction","initializer":"undefined","default":"BeatFraction.Half","isEnum":true}]},"music.tempo":{"kind":-3,"retType":"number","attributes":{"help":"music/tempo","blockId":"device_tempo","block":"tempo (bpm)","weight":64,"group":"Tempo","jsDoc":"Return the tempo in beats per minute (bpm).\nTempo is the speed (bpm = beats per minute) at which notes play. The larger the tempo value, the faster the notes will play.","_def":{"parts":[{"kind":"label","text":"tempo (bpm)","style":[]}],"parameters":[]}},"parameters":[]},"music.changeTempoBy":{"kind":-3,"attributes":{"paramDefl":{"bpm":"20"},"help":"music/change-tempo-by","weight":66,"blockId":"device_change_tempo","block":"change tempo by %value|(bpm)","blockGap":"8","group":"Tempo","paramHelp":{"bpm":"The change in beats per minute to the tempo, eg: 20"},"jsDoc":"Change the tempo up or down by some amount of beats per minute (bpm).","_def":{"parts":[{"kind":"label","text":"change tempo by ","style":[]},{"kind":"param","name":"value","ref":false},{"kind":"break"},{"kind":"label","text":"(bpm)","style":[]}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"bpm","description":"The change in beats per minute to the tempo, eg: 20","default":"20"}],"pyQName":"music.change_tempo_by"},"music.setTempo":{"kind":-3,"attributes":{"paramDefl":{"bpm":"120"},"help":"music/set-tempo","blockId":"device_set_tempo","block":"set tempo to %value|(bpm)","paramMin":{"bpm":"4"},"paramMax":{"bpm":"400"},"weight":65,"blockGap":"8","group":"Tempo","paramHelp":{"bpm":"The new tempo in beats per minute, eg: 120"},"jsDoc":"Set the tempo a number of beats per minute (bpm).","_def":{"parts":[{"kind":"label","text":"set tempo to ","style":[]},{"kind":"param","name":"value","ref":false},{"kind":"break"},{"kind":"label","text":"(bpm)","style":[]}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"bpm","description":"The new tempo in beats per minute, eg: 120","default":"120","options":{"min":{"value":"4"},"max":{"value":"400"}}}],"pyQName":"music.set_tempo"},"WaveShape":{"kind":6,"retType":"WaveShape","extendsTypes":["WaveShape","Number"]},"WaveShape.Sine":{"retType":"WaveShape.Sine","attributes":{"block":"sine","_def":{"parts":[{"kind":"label","text":"sine","style":[]}],"parameters":[]}},"extendsTypes":["WaveShape.Sine","Number"],"pyQName":"WaveShape.SINE"},"WaveShape.Sawtooth":{"retType":"WaveShape.Sawtooth","attributes":{"block":"sawtooth","_def":{"parts":[{"kind":"label","text":"sawtooth","style":[]}],"parameters":[]}},"extendsTypes":["WaveShape.Sawtooth","Number"],"pyQName":"WaveShape.SAWTOOTH"},"WaveShape.Triangle":{"retType":"WaveShape.Triangle","attributes":{"block":"triangle","_def":{"parts":[{"kind":"label","text":"triangle","style":[]}],"parameters":[]}},"extendsTypes":["WaveShape.Triangle","Number"],"pyQName":"WaveShape.TRIANGLE"},"WaveShape.Square":{"retType":"WaveShape.Square","attributes":{"block":"square","_def":{"parts":[{"kind":"label","text":"square","style":[]}],"parameters":[]}},"extendsTypes":["WaveShape.Square","Number"],"pyQName":"WaveShape.SQUARE"},"WaveShape.Noise":{"retType":"WaveShape.Noise","attributes":{"block":"noise","_def":{"parts":[{"kind":"label","text":"noise","style":[]}],"parameters":[]}},"extendsTypes":["WaveShape.Noise","Number"],"pyQName":"WaveShape.NOISE"},"InterpolationCurve":{"kind":6,"retType":"InterpolationCurve","extendsTypes":["InterpolationCurve","Number"]},"InterpolationCurve.Linear":{"retType":"InterpolationCurve.Linear","attributes":{"block":"linear","_def":{"parts":[{"kind":"label","text":"linear","style":[]}],"parameters":[]}},"extendsTypes":["InterpolationCurve.Linear","Number"],"pyQName":"InterpolationCurve.LINEAR"},"InterpolationCurve.Curve":{"retType":"InterpolationCurve.Curve","attributes":{"block":"curve","_def":{"parts":[{"kind":"label","text":"curve","style":[]}],"parameters":[]}},"extendsTypes":["InterpolationCurve.Curve","Number"],"pyQName":"InterpolationCurve.CURVE"},"InterpolationCurve.Logarithmic":{"retType":"InterpolationCurve.Logarithmic","attributes":{"block":"logarithmic","_def":{"parts":[{"kind":"label","text":"logarithmic","style":[]}],"parameters":[]}},"extendsTypes":["InterpolationCurve.Logarithmic","Number"],"pyQName":"InterpolationCurve.LOGARITHMIC"},"SoundExpressionEffect":{"kind":6,"retType":"SoundExpressionEffect","extendsTypes":["SoundExpressionEffect","Number"]},"SoundExpressionEffect.None":{"retType":"SoundExpressionEffect.None","attributes":{"block":"none","_def":{"parts":[{"kind":"label","text":"none","style":[]}],"parameters":[]}},"extendsTypes":["SoundExpressionEffect.None","Number"],"pyQName":"SoundExpressionEffect.NONE"},"SoundExpressionEffect.Vibrato":{"retType":"SoundExpressionEffect.Vibrato","attributes":{"block":"vibrato","_def":{"parts":[{"kind":"label","text":"vibrato","style":[]}],"parameters":[]}},"extendsTypes":["SoundExpressionEffect.Vibrato","Number"],"pyQName":"SoundExpressionEffect.VIBRATO"},"SoundExpressionEffect.Tremolo":{"retType":"SoundExpressionEffect.Tremolo","attributes":{"block":"tremolo","_def":{"parts":[{"kind":"label","text":"tremolo","style":[]}],"parameters":[]}},"extendsTypes":["SoundExpressionEffect.Tremolo","Number"],"pyQName":"SoundExpressionEffect.TREMOLO"},"SoundExpressionEffect.Warble":{"retType":"SoundExpressionEffect.Warble","attributes":{"block":"warble","_def":{"parts":[{"kind":"label","text":"warble","style":[]}],"parameters":[]}},"extendsTypes":["SoundExpressionEffect.Warble","Number"],"pyQName":"SoundExpressionEffect.WARBLE"},"SoundExpressionPlayMode":{"kind":6,"retType":"SoundExpressionPlayMode","extendsTypes":["SoundExpressionPlayMode","Number"]},"SoundExpressionPlayMode.UntilDone":{"retType":"SoundExpressionPlayMode.UntilDone","attributes":{"block":"until done","_def":{"parts":[{"kind":"label","text":"until done","style":[]}],"parameters":[]}},"extendsTypes":["SoundExpressionPlayMode.UntilDone","Number"],"pyQName":"SoundExpressionPlayMode.UNTIL_DONE"},"SoundExpressionPlayMode.InBackground":{"retType":"SoundExpressionPlayMode.InBackground","attributes":{"block":"in background","_def":{"parts":[{"kind":"label","text":"in background","style":[]}],"parameters":[]}},"extendsTypes":["SoundExpressionPlayMode.InBackground","Number"],"pyQName":"SoundExpressionPlayMode.IN_BACKGROUND"},"music.SoundEffect":{"kind":8,"retType":"music.SoundEffect","extendsTypes":["music.SoundEffect","music.Playable"]},"music.SoundEffect.waveShape":{"kind":2,"retType":"WaveShape","isInstance":true,"pyQName":"music.SoundEffect.wave_shape"},"music.SoundEffect.startFrequency":{"kind":2,"retType":"number","isInstance":true,"pyQName":"music.SoundEffect.start_frequency"},"music.SoundEffect.endFrequency":{"kind":2,"retType":"number","isInstance":true,"pyQName":"music.SoundEffect.end_frequency"},"music.SoundEffect.startVolume":{"kind":2,"retType":"number","isInstance":true,"pyQName":"music.SoundEffect.start_volume"},"music.SoundEffect.endVolume":{"kind":2,"retType":"number","isInstance":true,"pyQName":"music.SoundEffect.end_volume"},"music.SoundEffect.duration":{"kind":2,"retType":"number","isInstance":true},"music.SoundEffect.effect":{"kind":2,"retType":"SoundExpressionEffect","isInstance":true},"music.SoundEffect.interpolation":{"kind":2,"retType":"InterpolationCurve","isInstance":true},"music.SoundEffect.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"music.SoundEffect.toBuffer":{"kind":-1,"retType":"Buffer","parameters":[{"name":"volume","initializer":"undefined"}],"isInstance":true,"pyQName":"music.SoundEffect.to_buffer"},"music.SoundEffect.play":{"kind":-1,"parameters":[{"name":"playbackMode","type":"music.PlaybackMode","isEnum":true}],"isInstance":true},"music.playSoundEffect":{"kind":-3,"attributes":{"blockId":"soundExpression_playSoundEffect","block":"play sound $sound $mode","weight":30,"help":"music/play-sound-effect","blockGap":"8","group":"Sounds","deprecated":"1","paramHelp":{"sound":"the SoundEffect to play","mode":"the play mode, play until done or in the background"},"jsDoc":"Play a SoundEffect.","_def":{"parts":[{"kind":"label","text":"play sound ","style":[]},{"kind":"param","name":"sound","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"mode","ref":true}],"parameters":[{"kind":"param","name":"sound","ref":true},{"kind":"param","name":"mode","ref":true}]}},"parameters":[{"name":"sound","description":"the SoundEffect to play","type":"music.SoundEffect"},{"name":"mode","description":"the play mode, play until done or in the background","type":"SoundExpressionPlayMode","isEnum":true}],"pyQName":"music.play_sound_effect"},"music.createSoundEffect":{"kind":-3,"retType":"music.SoundEffect","attributes":{"paramDefl":{"waveShape":"WaveShape.Sine","startFrequency":"5000","endFrequency":"0","startVolume":"255","endVolume":"0","duration":"500","effect":"SoundExpressionEffect.None","interpolation":"InterpolationCurve.Linear"},"blockId":"soundExpression_createSoundEffect","help":"music/create-sound-effect","block":"$waveShape|| start frequency $startFrequency end frequency $endFrequency duration $duration start volume $startVolume end volume $endVolume effect $effect interpolation $interpolation","explicitDefaults":["waveShape","startFrequency","endFrequency","startVolume","endVolume","duration","effect","interpolation"],"paramFieldEditor":{"waveShape":"soundeffect"},"paramFieldEditorOptions":{"waveShape":{"useMixerSynthesizer":"true"}},"paramMin":{"startFrequency":"0","endFrequency":"0","startVolume":"0","endVolume":"0","duration":"1"},"paramMax":{"startFrequency":"5000","endFrequency":"5000","startVolume":"255","endVolume":"255","duration":"9999"},"compileHiddenArguments":true,"inlineInputMode":"variable","inlineInputModeLimit":3,"expandableArgumentBreaks":"3,5","toolboxParent":"music_playable_play","toolboxParentArgument":"toPlay","weight":20,"group":"Sounds","duplicateShadowOnDrag":true,"paramHelp":{"waveShape":"waveform of the sound effect","startFrequency":"starting frequency for the sound effect waveform","endFrequency":"ending frequency for the sound effect waveform","startVolume":"starting volume of the sound, or starting amplitude","endVolume":"ending volume of the sound, or ending amplitude","duration":"the amount of time in milliseconds (ms) that sound will play for","effect":"the effect to apply to the waveform or volume","interpolation":"interpolation method for frequency scaling"},"jsDoc":"Create a sound expression from a set of sound effect parameters.","_def":{"parts":[{"kind":"param","name":"waveShape","ref":true}],"parameters":[{"kind":"param","name":"waveShape","ref":true}]},"_expandedDef":{"parts":[{"kind":"label","text":" start frequency ","style":[]},{"kind":"param","name":"startFrequency","ref":true},{"kind":"label","text":" end frequency ","style":[]},{"kind":"param","name":"endFrequency","ref":true},{"kind":"label","text":" duration ","style":[]},{"kind":"param","name":"duration","ref":true},{"kind":"label","text":" start volume ","style":[]},{"kind":"param","name":"startVolume","ref":true},{"kind":"label","text":" end volume ","style":[]},{"kind":"param","name":"endVolume","ref":true},{"kind":"label","text":" effect ","style":[]},{"kind":"param","name":"effect","ref":true},{"kind":"label","text":" interpolation ","style":[]},{"kind":"param","name":"interpolation","ref":true}],"parameters":[{"kind":"param","name":"startFrequency","ref":true},{"kind":"param","name":"endFrequency","ref":true},{"kind":"param","name":"duration","ref":true},{"kind":"param","name":"startVolume","ref":true},{"kind":"param","name":"endVolume","ref":true},{"kind":"param","name":"effect","ref":true},{"kind":"param","name":"interpolation","ref":true}]}},"parameters":[{"name":"waveShape","description":"waveform of the sound effect","type":"WaveShape","initializer":"WaveShape.Sine","default":"WaveShape.Sine","isEnum":true},{"name":"startFrequency","description":"starting frequency for the sound effect waveform","initializer":"5000","default":"5000","options":{"min":{"value":"0"},"max":{"value":"5000"}}},{"name":"endFrequency","description":"ending frequency for the sound effect waveform","initializer":"0","default":"0","options":{"min":{"value":"0"},"max":{"value":"5000"}}},{"name":"startVolume","description":"starting volume of the sound, or starting amplitude","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"endVolume","description":"ending volume of the sound, or ending amplitude","initializer":"0","default":"0","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"duration","description":"the amount of time in milliseconds (ms) that sound will play for","initializer":"500","default":"500","options":{"min":{"value":"1"},"max":{"value":"9999"}}},{"name":"effect","description":"the effect to apply to the waveform or volume","type":"SoundExpressionEffect","initializer":"SoundExpressionEffect.None","default":"SoundExpressionEffect.None","isEnum":true},{"name":"interpolation","description":"interpolation method for frequency scaling","type":"InterpolationCurve","initializer":"InterpolationCurve.Linear","default":"InterpolationCurve.Linear","isEnum":true}],"pyQName":"music.create_sound_effect"},"music.soundToInstructionBuffer":{"kind":-3,"retType":"Buffer","parameters":[{"name":"waveShape","type":"WaveShape","isEnum":true},{"name":"startFrequency"},{"name":"endFrequency"},{"name":"startVolume"},{"name":"endVolume"},{"name":"duration"},{"name":"effect","type":"SoundExpressionEffect","isEnum":true},{"name":"interpolation","type":"InterpolationCurve","isEnum":true},{"name":"fxSteps"},{"name":"fxRange"},{"name":"globalVolume"}],"pyQName":"music.sound_to_instruction_buffer"},"music.randomizeSound":{"kind":-3,"retType":"music.SoundEffect","attributes":{"blockId":"soundExpression_generateSimilarSound","block":"randomize $sound","_shadowOverrides":{"sound":"soundExpression_createSoundEffect"},"weight":0,"help":"music/randomize-sound","blockGap":"8","group":"Sounds","jsDoc":"Generate a random similar sound effect to the given one.\n* @param sound the sound effect","_def":{"parts":[{"kind":"label","text":"randomize ","style":[]},{"kind":"param","name":"sound","shadowBlockId":"soundExpression_createSoundEffect","ref":true}],"parameters":[{"kind":"param","name":"sound","shadowBlockId":"soundExpression_createSoundEffect","ref":true}]}},"parameters":[{"name":"sound","type":"music.SoundEffect"}],"pyQName":"music.randomize_sound"},"music.sequencer":{"kind":5,"retType":""},"music.sequencer.Song":{"kind":8,"retType":"music.sequencer.Song","attributes":{"jsDoc":"Byte encoding format for songs\nFIXME: should this all be word aligned?\n* song(7 + length of all tracks bytes)\n0 version\n1 beats per minute\n3 beats per measure\n4 ticks per beat\n5 measures\n6 number of tracks\n...tracks\n* track(6 + instrument length + note length bytes)\n0 id\n1 flags\n2 instruments byte length\n4...instrument\nnotes byte length\n...note events\n* instrument(28 bytes)\n0 waveform\n1 amp attack\n3 amp decay\n5 amp sustain\n7 amp release\n9 amp amp\n11 pitch attack\n13 pitch decay\n15 pitch sustain\n17 pitch release\n19 pitch amp\n21 amp lfo freq\n22 amp lfo amp\n24 pitch lfo freq\n25 pitch lfo amp\n27 octave\n* drum(5 + 7 * steps bytes)\n0 steps\n1 start freq\n3 start amp\n5...steps\n* drum step(7 bytes)\n0 waveform\n1 freq\n3 volume\n5 duration\n* note event(5 + 1 * polyphony bytes)\n0 start tick\n2 end tick\n4 polyphony\n5...notes(1 byte each)\n* note (1 byte)\nlower six bits = note - (instrumentOctave - 2) * 12\nupper two bits are the enharmonic spelling:\n0 = normal\n1 = flat\n2 = sharp"},"extendsTypes":["music.sequencer.Song","music.Playable"]},"music.sequencer.Song.tracks":{"kind":2,"retType":"music.sequencer.Track[]","isInstance":true},"music.sequencer.Song.__constructor":{"kind":-3,"parameters":[{"name":"buf","type":"Buffer"}],"isInstance":true},"music.sequencer.Song.version":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.Song.version@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.Song.beatsPerMinute":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.Song.beats_per_minute"},"music.sequencer.Song.beatsPerMinute@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"music.sequencer.Song.beats_per_minute@set"},"music.sequencer.Song.beatsPerMeasure":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.Song.beats_per_measure"},"music.sequencer.Song.beatsPerMeasure@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"music.sequencer.Song.beats_per_measure@set"},"music.sequencer.Song.ticksPerBeat":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.Song.ticks_per_beat"},"music.sequencer.Song.ticksPerBeat@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"music.sequencer.Song.ticks_per_beat@set"},"music.sequencer.Song.measures":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.Song.measures@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.Song.numberOfTracks":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.Song.number_of_tracks"},"music.sequencer.Song.play":{"kind":-1,"parameters":[{"name":"playbackMode","type":"music.PlaybackMode","isEnum":true}],"isInstance":true},"music.sequencer.Envelope":{"kind":8,"retType":"music.sequencer.Envelope","extendsTypes":[]},"music.sequencer.Envelope.__constructor":{"kind":-3,"parameters":[{"name":"buf","type":"Buffer","initializer":"undefined"},{"name":"offset","initializer":"undefined"}],"isInstance":true},"music.sequencer.Envelope.attack":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.Envelope.attack@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.Envelope.decay":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.Envelope.decay@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.Envelope.sustain":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.Envelope.sustain@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.Envelope.release":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.Envelope.release@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.Envelope.amplitude":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.Envelope.amplitude@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.LFO":{"kind":8,"retType":"music.sequencer.LFO","extendsTypes":[]},"music.sequencer.LFO.__constructor":{"kind":-3,"parameters":[{"name":"buf","type":"Buffer","initializer":"undefined"},{"name":"offset","initializer":"undefined"}],"isInstance":true},"music.sequencer.LFO.frequency":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.LFO.frequency@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.LFO.amplitude":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.LFO.amplitude@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.NoteEvent":{"kind":8,"retType":"music.sequencer.NoteEvent","extendsTypes":[]},"music.sequencer.NoteEvent.__constructor":{"kind":-3,"parameters":[{"name":"buf","type":"Buffer"},{"name":"offset"}],"isInstance":true},"music.sequencer.NoteEvent.startTick":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.NoteEvent.start_tick"},"music.sequencer.NoteEvent.startTick@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"music.sequencer.NoteEvent.start_tick@set"},"music.sequencer.NoteEvent.endTick":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.NoteEvent.end_tick"},"music.sequencer.NoteEvent.endTick@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"music.sequencer.NoteEvent.end_tick@set"},"music.sequencer.NoteEvent.polyphony":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.NoteEvent.polyphony@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.NoteEvent.byteLength":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.NoteEvent.byte_length"},"music.sequencer.NoteEvent.getNote":{"kind":-1,"retType":"number","parameters":[{"name":"offset"},{"name":"octave","initializer":"undefined"}],"isInstance":true,"pyQName":"music.sequencer.NoteEvent.get_note"},"music.sequencer.Track":{"kind":8,"retType":"music.sequencer.Track","extendsTypes":["music.sequencer.Track"]},"music.sequencer.Track.currentNoteEvent":{"kind":2,"retType":"music.sequencer.NoteEvent","isInstance":true,"pyQName":"music.sequencer.Track.current_note_event"},"music.sequencer.Track.__constructor":{"kind":-3,"parameters":[{"name":"buf","type":"Buffer"},{"name":"offset"}],"isInstance":true},"music.sequencer.Track.isMelodicTrack":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.Track.is_melodic_track"},"music.sequencer.Track.id":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.Track.id@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.Track.flags":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.Track.flags@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.Track.instrumentByteLength":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.Track.instrument_byte_length"},"music.sequencer.Track.instrumentByteLength@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"music.sequencer.Track.instrument_byte_length@set"},"music.sequencer.Track.noteEventStart":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.Track.note_event_start"},"music.sequencer.Track.noteEventByteLength":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.Track.note_event_byte_length"},"music.sequencer.Track.noteEventByteLength@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"music.sequencer.Track.note_event_byte_length@set"},"music.sequencer.Track.byteLength":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.Track.byte_length"},"music.sequencer.Track.advanceNoteEvent":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"music.sequencer.Track.advance_note_event"},"music.sequencer.MelodicTrack":{"kind":8,"retType":"music.sequencer.MelodicTrack","extendsTypes":["music.sequencer.MelodicTrack","music.sequencer.Track"]},"music.sequencer.MelodicTrack.instrument":{"kind":2,"retType":"music.sequencer.Instrument","isInstance":true},"music.sequencer.MelodicTrack.__constructor":{"kind":-3,"parameters":[{"name":"buf","type":"Buffer"},{"name":"offset"}],"isInstance":true},"music.sequencer.DrumTrack":{"kind":8,"retType":"music.sequencer.DrumTrack","extendsTypes":["music.sequencer.DrumTrack","music.sequencer.Track"]},"music.sequencer.DrumTrack.drums":{"kind":2,"retType":"music.sequencer.DrumInstrument[]","isInstance":true},"music.sequencer.DrumTrack.__constructor":{"kind":-3,"parameters":[{"name":"buf","type":"Buffer"},{"name":"offset"}],"isInstance":true},"music.sequencer.Instrument":{"kind":8,"retType":"music.sequencer.Instrument","extendsTypes":[]},"music.sequencer.Instrument.ampEnvelope":{"kind":2,"retType":"music.sequencer.Envelope","isInstance":true,"pyQName":"music.sequencer.Instrument.amp_envelope"},"music.sequencer.Instrument.pitchEnvelope":{"kind":2,"retType":"music.sequencer.Envelope","isInstance":true,"pyQName":"music.sequencer.Instrument.pitch_envelope"},"music.sequencer.Instrument.ampLFO":{"kind":2,"retType":"music.sequencer.LFO","isInstance":true,"pyQName":"music.sequencer.Instrument.amp_lfo"},"music.sequencer.Instrument.pitchLFO":{"kind":2,"retType":"music.sequencer.LFO","isInstance":true,"pyQName":"music.sequencer.Instrument.pitch_lfo"},"music.sequencer.Instrument.__constructor":{"kind":-3,"parameters":[{"name":"buf","type":"Buffer","initializer":"undefined"},{"name":"offset","initializer":"undefined"}],"isInstance":true},"music.sequencer.Instrument.waveform":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.Instrument.waveform@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.Instrument.octave":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.Instrument.octave@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.DrumInstrument":{"kind":8,"retType":"music.sequencer.DrumInstrument","extendsTypes":[]},"music.sequencer.DrumInstrument.steps":{"kind":2,"retType":"music.sequencer.DrumStep[]","isInstance":true},"music.sequencer.DrumInstrument.__constructor":{"kind":-3,"parameters":[{"name":"buf","type":"Buffer"},{"name":"offset"}],"isInstance":true},"music.sequencer.DrumInstrument.byteLength":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.DrumInstrument.byte_length"},"music.sequencer.DrumInstrument.numSteps":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.DrumInstrument.num_steps"},"music.sequencer.DrumInstrument.numSteps@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"music.sequencer.DrumInstrument.num_steps@set"},"music.sequencer.DrumInstrument.startFrequency":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.DrumInstrument.start_frequency"},"music.sequencer.DrumInstrument.startFrequency@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"music.sequencer.DrumInstrument.start_frequency@set"},"music.sequencer.DrumInstrument.startVolume":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"music.sequencer.DrumInstrument.start_volume"},"music.sequencer.DrumInstrument.startVolume@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"music.sequencer.DrumInstrument.start_volume@set"},"music.sequencer.DrumStep":{"kind":8,"retType":"music.sequencer.DrumStep","extendsTypes":[]},"music.sequencer.DrumStep.__constructor":{"kind":-3,"parameters":[{"name":"buf","type":"Buffer","initializer":"undefined"},{"name":"offset","initializer":"undefined"}],"isInstance":true},"music.sequencer.DrumStep.waveform":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.DrumStep.waveform@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.DrumStep.frequency":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.DrumStep.frequency@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.DrumStep.volume":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.DrumStep.volume@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.DrumStep.duration":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"music.sequencer.DrumStep.duration@set":{"kind":-2,"retType":"number","isInstance":true},"music.sequencer.renderInstrument":{"kind":-3,"retType":"Buffer","attributes":{"paramHelp":{"noteFrequency":"The frequency of the note being played. In other words, \"the key being pressed on the piano\"","gateLength":"The length of time that the \"piano key\" is held down in ms. The total duration","volume":"The peak volume of the note to play (0-1024). Also called the \"velocity\""},"jsDoc":"Renders a single note played on an instrument into a buffer of sound instructions.\n* @param instrument The instrument being played\n\n\nof the sound instructions will be longer than this if the amplitude envelope of the\ninstrument has a nonzero release time"},"parameters":[{"name":"instrument","type":"music.sequencer.Instrument"},{"name":"noteFrequency","description":"The frequency of the note being played. In other words, \"the key being pressed on the piano\""},{"name":"gateLength","description":"The length of time that the \"piano key\" is held down in ms. The total duration"},{"name":"volume","description":"The peak volume of the note to play (0-1024). Also called the \"velocity\""}],"pyQName":"music.sequencer.render_instrument"},"music.sequencer.renderDrumInstrument":{"kind":-3,"retType":"Buffer","parameters":[{"name":"sound","type":"music.sequencer.DrumInstrument"},{"name":"volume"}],"pyQName":"music.sequencer.render_drum_instrument"},"music.sequencer._stopAllSongs":{"kind":-3,"parameters":[],"pyQName":"music.sequencer._stop_all_songs"},"music.sequencer.Sequencer":{"kind":8,"retType":"music.sequencer.Sequencer","extendsTypes":[]},"music.sequencer.Sequencer.currentTick":{"kind":2,"retType":"number","isInstance":true,"pyQName":"music.sequencer.Sequencer.current_tick"},"music.sequencer.Sequencer.isPlaying":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"music.sequencer.Sequencer.is_playing"},"music.sequencer.Sequencer.isLooping":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"music.sequencer.Sequencer.is_looping"},"music.sequencer.Sequencer.isRunning":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"music.sequencer.Sequencer.is_running"},"music.sequencer.Sequencer.__constructor":{"kind":-3,"parameters":[{"name":"song","type":"music.sequencer.Song"}],"isInstance":true},"music.sequencer.Sequencer.start":{"kind":-1,"parameters":[{"name":"loop","type":"boolean"}],"isInstance":true},"music.sequencer.Sequencer.stop":{"kind":-1,"parameters":[],"isInstance":true},"music.sequencer.Sequencer.tickToMs":{"kind":-1,"retType":"number","parameters":[{"name":"ticks"}],"isInstance":true,"pyQName":"music.sequencer.Sequencer.tick_to_ms"},"music.sequencer._stopAllSimSequencers":{"kind":-3,"parameters":[],"pyQName":"music.sequencer._stop_all_sim_sequencers"},"music.sequencer._SimulatorSequencer":{"kind":8,"retType":"music.sequencer._SimulatorSequencer","extendsTypes":[]},"music.sequencer._SimulatorSequencer.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"music.sequencer._SimulatorSequencer.play":{"kind":-1,"parameters":[{"name":"song","type":"Buffer"},{"name":"loop","type":"boolean"}],"isInstance":true},"music.sequencer._SimulatorSequencer.stop":{"kind":-1,"parameters":[],"isInstance":true},"music.sequencer._SimulatorSequencer.setVolume":{"kind":-1,"parameters":[{"name":"volume"}],"isInstance":true,"pyQName":"music.sequencer._SimulatorSequencer.set_volume"},"music.sequencer._SimulatorSequencer.setTrackVolume":{"kind":-1,"parameters":[{"name":"trackIndex"},{"name":"volume"}],"isInstance":true,"pyQName":"music.sequencer._SimulatorSequencer.set_track_volume"},"music.sequencer._SimulatorSequencer.setDrumTrackVolume":{"kind":-1,"parameters":[{"name":"trackIndex"},{"name":"drumIndex"},{"name":"volume"}],"isInstance":true,"pyQName":"music.sequencer._SimulatorSequencer.set_drum_track_volume"},"music.sequencer._SimulatorSequencer.state":{"kind":-1,"retType":"string","parameters":[],"isInstance":true},"music.sequencer._SimulatorSequencer.currentTick":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"music.sequencer._SimulatorSequencer.current_tick"},"music.sequencer._SimulatorSequencer.dispose":{"kind":-1,"parameters":[],"isInstance":true},"music.sequencer._SimulatorSequencer.onTick":{"kind":-1,"parameters":[{"name":"handler","type":"(tick: number) => void","handlerParameters":[{"name":"tick","type":"number"}]}],"isInstance":true,"pyQName":"music.sequencer._SimulatorSequencer.on_tick"},"music.sequencer._SimulatorSequencer.onStateChange":{"kind":-1,"parameters":[{"name":"handler","type":"(state: string) => void","handlerParameters":[{"name":"state","type":"string"}]}],"isInstance":true,"pyQName":"music.sequencer._SimulatorSequencer.on_state_change"},"music.sequencer._SimulatorSequencer.onStop":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"music.sequencer._SimulatorSequencer.on_stop"},"music.sequencer._SimulatorSequencer.onLooped":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"music.sequencer._SimulatorSequencer.on_looped"},"music.PlaybackMode":{"kind":6,"retType":"music.PlaybackMode","extendsTypes":["music.PlaybackMode","Number"]},"music.PlaybackMode.UntilDone":{"retType":"music.PlaybackMode.UntilDone","attributes":{"block":"until done","_def":{"parts":[{"kind":"label","text":"until done","style":[]}],"parameters":[]}},"extendsTypes":["music.PlaybackMode.UntilDone","Number"],"pyQName":"music.PlaybackMode.UNTIL_DONE"},"music.PlaybackMode.InBackground":{"retType":"music.PlaybackMode.InBackground","attributes":{"block":"in background","_def":{"parts":[{"kind":"label","text":"in background","style":[]}],"parameters":[]}},"extendsTypes":["music.PlaybackMode.InBackground","Number"],"pyQName":"music.PlaybackMode.IN_BACKGROUND"},"music.PlaybackMode.LoopingInBackground":{"retType":"music.PlaybackMode.LoopingInBackground","attributes":{"block":"looping in background","_def":{"parts":[{"kind":"label","text":"looping in background","style":[]}],"parameters":[]}},"extendsTypes":["music.PlaybackMode.LoopingInBackground","Number"],"pyQName":"music.PlaybackMode.LOOPING_IN_BACKGROUND"},"music.Playable":{"kind":8,"retType":"music.Playable","extendsTypes":["music.Playable"]},"music.Playable.stopped":{"kind":2,"retType":"boolean","isInstance":true},"music.Playable.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"music.Playable.play":{"kind":-1,"parameters":[{"name":"playbackMode","type":"music.PlaybackMode","isEnum":true}],"isInstance":true},"music.Playable.loop":{"kind":-1,"parameters":[],"isInstance":true},"music.MelodyPlayable":{"kind":8,"retType":"music.MelodyPlayable","extendsTypes":["music.MelodyPlayable","music.Playable"]},"music.MelodyPlayable.__constructor":{"kind":-3,"parameters":[{"name":"melody","type":"music.Melody"}],"isInstance":true},"music.MelodyPlayable.play":{"kind":-1,"parameters":[{"name":"playbackMode","type":"music.PlaybackMode","isEnum":true}],"isInstance":true},"music.TonePlayable":{"kind":8,"retType":"music.TonePlayable","extendsTypes":["music.TonePlayable","music.Playable"]},"music.TonePlayable.__constructor":{"kind":-3,"parameters":[{"name":"pitch"},{"name":"duration"}],"isInstance":true},"music.TonePlayable.play":{"kind":-1,"parameters":[{"name":"playbackMode","type":"music.PlaybackMode","isEnum":true}],"isInstance":true},"music.play":{"kind":-3,"attributes":{"blockId":"music_playable_play","block":"play $toPlay $playbackMode","_shadowOverrides":{"toPlay":"music_melody_playable"},"group":"Sounds","help":"music/play","paramHelp":{"toPlay":"the song or melody to play","playbackMode":"play the song or melody until it's finished or as background task"},"jsDoc":"Play a song, melody, or other sound. The music plays until finished or can play as a\nbackground task.","_def":{"parts":[{"kind":"label","text":"play ","style":[]},{"kind":"param","name":"toPlay","shadowBlockId":"music_melody_playable","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"playbackMode","ref":true}],"parameters":[{"kind":"param","name":"toPlay","shadowBlockId":"music_melody_playable","ref":true},{"kind":"param","name":"playbackMode","ref":true}]}},"parameters":[{"name":"toPlay","description":"the song or melody to play","type":"music.Playable"},{"name":"playbackMode","description":"play the song or melody until it's finished or as background task","type":"music.PlaybackMode","isEnum":true}]},"music.melodyPlayable":{"kind":-3,"retType":"music.Playable","attributes":{"blockId":"music_melody_playable","block":"sound $melody","toolboxParent":"music_playable_play","toolboxParentArgument":"toPlay","group":"Sounds","duplicateShadowOnDrag":true,"blockHidden":true,"help":"music/melody-playable","paramHelp":{"melody":"the melody to make playable"},"jsDoc":"Create a Playable object for a melody.","_def":{"parts":[{"kind":"label","text":"sound ","style":[]},{"kind":"param","name":"melody","ref":true}],"parameters":[{"kind":"param","name":"melody","ref":true}]}},"parameters":[{"name":"melody","description":"the melody to make playable","type":"music.Melody"}],"pyQName":"music.melody_playable"},"music.stringPlayable":{"kind":-3,"retType":"music.Playable","attributes":{"paramDefl":{"tempo":"120"},"blockId":"music_string_playable","block":"melody $melody at tempo $tempo|(bpm)","toolboxParent":"music_playable_play","toolboxParentArgument":"toPlay","weight":85,"blockGap":"8","help":"music/string-playable","group":"Songs","duplicateShadowOnDrag":true,"_shadowOverrides":{"melody":"melody_editor"},"paramMin":{"tempo":"40"},"paramMax":{"tempo":"500"},"explicitDefaults":["tempo"],"paramHelp":{"melody":"the melody string to make playable"},"jsDoc":"Create a Playable object for a melody string containg notes.","_def":{"parts":[{"kind":"label","text":"melody ","style":[]},{"kind":"param","name":"melody","shadowBlockId":"melody_editor","ref":true},{"kind":"label","text":" at tempo ","style":[]},{"kind":"param","name":"tempo","ref":true},{"kind":"break"},{"kind":"label","text":"(bpm)","style":[]}],"parameters":[{"kind":"param","name":"melody","shadowBlockId":"melody_editor","ref":true},{"kind":"param","name":"tempo","ref":true}]}},"parameters":[{"name":"melody","description":"the melody string to make playable","type":"string"},{"name":"tempo","initializer":"120","default":"120","options":{"min":{"value":"40"},"max":{"value":"500"}}}],"pyQName":"music.string_playable"},"music.tonePlayable":{"kind":-3,"retType":"music.Playable","attributes":{"blockId":"music_tone_playable","block":"tone $note for $duration","toolboxParent":"music_playable_play","toolboxParentArgument":"toPlay","group":"Tone","duplicateShadowOnDrag":true,"_shadowOverrides":{"note":"device_note","duration":"device_beat"},"parts":"headphone","help":"music/tone-playable","paramHelp":{"note":"the note or tone frequency to play","duration":"the duration of the tone in milliseconds (ms)"},"jsDoc":"Create a Playable object for a single tone and its duration.","_def":{"parts":[{"kind":"label","text":"tone ","style":[]},{"kind":"param","name":"note","shadowBlockId":"device_note","ref":true},{"kind":"label","text":" for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"device_beat","ref":true}],"parameters":[{"kind":"param","name":"note","shadowBlockId":"device_note","ref":true},{"kind":"param","name":"duration","shadowBlockId":"device_beat","ref":true}]}},"parameters":[{"name":"note","description":"the note or tone frequency to play"},{"name":"duration","description":"the duration of the tone in milliseconds (ms)"}],"pyQName":"music.tone_playable"},"music._stopPlayables":{"kind":-3,"parameters":[],"pyQName":"music._stop_playables"},"power":{"kind":5,"retType":"","attributes":{"advanced":true,"icon":"","color":"#898989","weight":1,"blockGap":"8","jsDoc":"Power and sleep management"}},"power.setDeepSleepTimeout":{"kind":-3,"attributes":{"paramDefl":{"seconds":"60"},"blockId":"powersetdeepsleeptimout","block":"power set deep sleep timeout to %seconds s","explicitDefaults":["seconds"],"help":"/power/set-deep-sleep-timeout","paramHelp":{"seconds":"duration in seconds until the device should be put in lower power mode"},"jsDoc":"Set the no-activity duration after which the device should go to deep sleep.","_def":{"parts":[{"kind":"label","text":"power set deep sleep timeout to ","style":[]},{"kind":"param","name":"seconds","ref":false},{"kind":"label","text":" s","style":[]}],"parameters":[{"kind":"param","name":"seconds","ref":false}]}},"parameters":[{"name":"seconds","description":"duration in seconds until the device should be put in lower power mode","initializer":"60","default":"60"}],"pyQName":"power.set_deep_sleep_timeout"},"power.poke":{"kind":-3,"attributes":{"blockId":"powerpke","block":"power poke","help":"/power/poke","jsDoc":"Poke the activity watcher to keep the device awake.","_def":{"parts":[{"kind":"label","text":"power poke","style":[]}],"parameters":[]}},"parameters":[]},"power.checkDeepSleep":{"kind":-3,"attributes":{"blockId":"powercheckdeepsleep","block":"power check deep sleep","help":"/power/check-deep-sleep","jsDoc":"Check if the device has had any \"pokes\" and needs to go into deep sleep mode.","_def":{"parts":[{"kind":"label","text":"power check deep sleep","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"power.check_deep_sleep"},"power.deepSleep":{"kind":-3,"attributes":{"blockId":"powerdeepsleep","block":"power deep sleep","help":"/power/deep-sleep","jsDoc":"Put the device into a deep sleep state.","_def":{"parts":[{"kind":"label","text":"power deep sleep","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"power.deep_sleep"},"image":{"kind":5,"retType":""},"image.Dimension":{"kind":6,"retType":"image.Dimension","extendsTypes":["image.Dimension","Number"]},"image.Dimension.Width":{"retType":"image.Dimension.Width","attributes":{"block":"width","_def":{"parts":[{"kind":"label","text":"width","style":[]}],"parameters":[]}},"extendsTypes":["image.Dimension.Width","Number"],"pyQName":"image.Dimension.WIDTH"},"image.Dimension.Height":{"retType":"image.Dimension.Height","attributes":{"block":"height","_def":{"parts":[{"kind":"label","text":"height","style":[]}],"parameters":[]}},"extendsTypes":["image.Dimension.Height","Number"],"pyQName":"image.Dimension.HEIGHT"},"image.repeatY":{"kind":-3,"retType":"Image","parameters":[{"name":"count"},{"name":"image","type":"Image"}],"pyQName":"image.repeat_y"},"image.concatY":{"kind":-3,"retType":"Image","parameters":[{"name":"images","type":"Image[]"}],"pyQName":"image.concat_y"},"image.getDimension":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"picture":"picture"},"blockId":"image_get_dimension","group":"Create","blockNamespace":"images","block":"$picture $dimension","_shadowOverrides":{"picture":"variables_get"},"explicitDefaults":["picture"],"paramHelp":{"dimension":"The dimension to get"},"jsDoc":"Returns the width or height of a picture.\n* @param picture The picture to get the width or height of\n\n@returns","_def":{"parts":[{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"dimension","ref":true}],"parameters":[{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":true},{"kind":"param","name":"dimension","ref":true}]}},"parameters":[{"name":"picture","type":"Image","initializer":"picture","default":"picture"},{"name":"dimension","description":"The dimension to get","type":"image.Dimension","isEnum":true}],"pyQName":"image.get_dimension"},"Image":{"kind":9,"retType":"Image","attributes":{"snippet":"img` `","pySnippet":"img(\"\"\" \"\"\")","fixedInstances":"true","decompileIndirectFixedInstances":true},"extendsTypes":["Image"]},"Image.drawIcon":{"kind":-1,"attributes":{"helper":"imageDrawIcon","jsDoc":"Draw an icon (monochromatic image) using given color"},"parameters":[{"name":"icon","type":"Buffer"},{"name":"x"},{"name":"y"},{"name":"c"}],"isInstance":true,"pyQName":"Image.draw_icon"},"Image.fillRect":{"kind":-1,"attributes":{"paramDefl":{"picture":"picture"},"helper":"imageFillRect","blockNamespace":"images","inlineInputMode":"inline","group":"Drawing","block":"fill rectangle in %picture=variables_get at x %x y %y width %w height %h %c=colorindexpicker","explicitDefaults":["picture"],"help":"images/image/fill-rect","jsDoc":"Fill a rectangle","_def":{"parts":[{"kind":"label","text":"fill rectangle in ","style":[]},{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"label","text":" at x ","style":[]},{"kind":"param","name":"x","ref":false},{"kind":"label","text":" y ","style":[]},{"kind":"param","name":"y","ref":false},{"kind":"label","text":" width ","style":[]},{"kind":"param","name":"w","ref":false},{"kind":"label","text":" height ","style":[]},{"kind":"param","name":"h","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"c","shadowBlockId":"colorindexpicker","ref":false}],"parameters":[{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"param","name":"x","ref":false},{"kind":"param","name":"y","ref":false},{"kind":"param","name":"w","ref":false},{"kind":"param","name":"h","ref":false},{"kind":"param","name":"c","shadowBlockId":"colorindexpicker","ref":false}]}},"parameters":[{"name":"x"},{"name":"y"},{"name":"w"},{"name":"h"},{"name":"c"}],"isInstance":true,"pyQName":"Image.fill_rect"},"Image.drawLine":{"kind":-1,"attributes":{"paramDefl":{"picture":"picture"},"helper":"imageDrawLine","blockNamespace":"images","inlineInputMode":"inline","group":"Drawing","block":"draw line in %picture=variables_get from x %x0 y %y0 to x %x1 y %y1 %c=colorindexpicker","explicitDefaults":["picture"],"help":"images/image/draw-line","jsDoc":"Draw a line","_def":{"parts":[{"kind":"label","text":"draw line in ","style":[]},{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"label","text":" from x ","style":[]},{"kind":"param","name":"x0","ref":false},{"kind":"label","text":" y ","style":[]},{"kind":"param","name":"y0","ref":false},{"kind":"label","text":" to x ","style":[]},{"kind":"param","name":"x1","ref":false},{"kind":"label","text":" y ","style":[]},{"kind":"param","name":"y1","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"c","shadowBlockId":"colorindexpicker","ref":false}],"parameters":[{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"param","name":"x0","ref":false},{"kind":"param","name":"y0","ref":false},{"kind":"param","name":"x1","ref":false},{"kind":"param","name":"y1","ref":false},{"kind":"param","name":"c","shadowBlockId":"colorindexpicker","ref":false}]}},"parameters":[{"name":"x0"},{"name":"y0"},{"name":"x1"},{"name":"y1"},{"name":"c"}],"isInstance":true,"pyQName":"Image.draw_line"},"Image.drawRect":{"kind":-1,"attributes":{"paramDefl":{"picture":"picture"},"helper":"imageDrawRect","blockNamespace":"images","inlineInputMode":"inline","group":"Drawing","block":"draw rectangle in %picture=variables_get at x %x y %y width %w height %h %c=colorindexpicker","explicitDefaults":["picture"],"help":"images/image/draw-rect","jsDoc":"Draw an empty rectangle","_def":{"parts":[{"kind":"label","text":"draw rectangle in ","style":[]},{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"label","text":" at x ","style":[]},{"kind":"param","name":"x","ref":false},{"kind":"label","text":" y ","style":[]},{"kind":"param","name":"y","ref":false},{"kind":"label","text":" width ","style":[]},{"kind":"param","name":"w","ref":false},{"kind":"label","text":" height ","style":[]},{"kind":"param","name":"h","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"c","shadowBlockId":"colorindexpicker","ref":false}],"parameters":[{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"param","name":"x","ref":false},{"kind":"param","name":"y","ref":false},{"kind":"param","name":"w","ref":false},{"kind":"param","name":"h","ref":false},{"kind":"param","name":"c","shadowBlockId":"colorindexpicker","ref":false}]}},"parameters":[{"name":"x"},{"name":"y"},{"name":"w"},{"name":"h"},{"name":"c"}],"isInstance":true,"pyQName":"Image.draw_rect"},"Image.drawCircle":{"kind":-1,"attributes":{"helper":"imageDrawCircle","jsDoc":"Draw a circle"},"parameters":[{"name":"cx"},{"name":"cy"},{"name":"r"},{"name":"c"}],"isInstance":true,"pyQName":"Image.draw_circle"},"Image.fillCircle":{"kind":-1,"attributes":{"helper":"imageFillCircle","jsDoc":"Fills a circle"},"parameters":[{"name":"cx"},{"name":"cy"},{"name":"r"},{"name":"c"}],"isInstance":true,"pyQName":"Image.fill_circle"},"Image.fillTriangle":{"kind":-1,"attributes":{"helper":"imageFillTriangle","jsDoc":"Fills a triangle"},"parameters":[{"name":"x0"},{"name":"y0"},{"name":"x1"},{"name":"y1"},{"name":"x2"},{"name":"y2"},{"name":"col"}],"isInstance":true,"pyQName":"Image.fill_triangle"},"Image.fillPolygon4":{"kind":-1,"attributes":{"helper":"imageFillPolygon4","jsDoc":"Fills a 4-side-polygon"},"parameters":[{"name":"x0"},{"name":"y0"},{"name":"x1"},{"name":"y1"},{"name":"x2"},{"name":"y2"},{"name":"x3"},{"name":"y3"},{"name":"col"}],"isInstance":true,"pyQName":"Image.fill_polygon4"},"Image.rotated":{"kind":-1,"retType":"Image","attributes":{"helper":"imageRotated","jsDoc":"Returns an image rotated by -90, 90, -180, 180, -270, 270 deg clockwise"},"parameters":[{"name":"deg"}],"isInstance":true},"Image.blitRow":{"kind":-1,"attributes":{"helper":"imageBlitRow","jsDoc":"Scale and copy a row of pixels from a texture."},"parameters":[{"name":"dstX"},{"name":"dstY"},{"name":"from","type":"Image"},{"name":"fromX"},{"name":"fromH"}],"isInstance":true,"pyQName":"Image.blit_row"},"Image.blit":{"kind":-1,"retType":"boolean","attributes":{"helper":"imageBlit","jsDoc":"Copy an image from a source rectangle to a destination rectangle, stretching or\ncompressing to fit the dimensions of the destination rectangle, if necessary."},"parameters":[{"name":"xDst"},{"name":"yDst"},{"name":"wDst"},{"name":"hDst"},{"name":"src","type":"Image"},{"name":"xSrc"},{"name":"ySrc"},{"name":"wSrc"},{"name":"hSrc"},{"name":"transparent","type":"boolean"},{"name":"check","type":"boolean"}],"isInstance":true},"ScreenImage":{"kind":9,"retType":"ScreenImage","extendsTypes":["ScreenImage","Image"]},"ScreenImage.setBrightness":{"kind":-1,"retType":"Image","attributes":{"helper":"setScreenBrightness","jsDoc":"Sets the screen backlight brightness (10-100)"},"parameters":[{"name":"deg"}],"isInstance":true,"pyQName":"ScreenImage.set_brightness"},"ScreenImage.brightness":{"kind":-1,"retType":"number","attributes":{"helper":"screenBrightness","jsDoc":"Gets current screen backlight brightness (0-100)"},"parameters":[],"isInstance":true},"_helpers_workaround":{"kind":5,"retType":""},"_helpers_workaround.brightness":{"kind":4,"retType":"number"},"helpers.imageBlit":{"kind":-3,"retType":"boolean","parameters":[{"name":"img","type":"Image"},{"name":"xDst"},{"name":"yDst"},{"name":"wDst"},{"name":"hDst"},{"name":"src","type":"Image"},{"name":"xSrc"},{"name":"ySrc"},{"name":"wSrc"},{"name":"hSrc"},{"name":"transparent","type":"boolean"},{"name":"check","type":"boolean"}],"pyQName":"helpers.image_blit"},"helpers.imageBlitRow":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"dstX"},{"name":"dstY"},{"name":"from","type":"Image"},{"name":"fromX"},{"name":"fromH"}],"pyQName":"helpers.image_blit_row"},"helpers.imageDrawIcon":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"icon","type":"Buffer"},{"name":"x"},{"name":"y"},{"name":"c"}],"pyQName":"helpers.image_draw_icon"},"helpers.imageFillRect":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"x"},{"name":"y"},{"name":"w"},{"name":"h"},{"name":"c"}],"pyQName":"helpers.image_fill_rect"},"helpers.imageMapRect":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"x"},{"name":"y"},{"name":"w"},{"name":"h"},{"name":"m","type":"Buffer"}],"pyQName":"helpers.image_map_rect"},"helpers.imageDrawLine":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"x"},{"name":"y"},{"name":"w"},{"name":"h"},{"name":"c"}],"pyQName":"helpers.image_draw_line"},"helpers.imageDrawRect":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"x"},{"name":"y"},{"name":"w"},{"name":"h"},{"name":"c"}],"pyQName":"helpers.image_draw_rect"},"helpers.imageDrawCircle":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"cx"},{"name":"cy"},{"name":"r"},{"name":"col"}],"pyQName":"helpers.image_draw_circle"},"helpers.imageFillCircle":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"cx"},{"name":"cy"},{"name":"r"},{"name":"col"}],"pyQName":"helpers.image_fill_circle"},"helpers.imageFillTriangle":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"x0"},{"name":"y0"},{"name":"x1"},{"name":"y1"},{"name":"x2"},{"name":"y2"},{"name":"col"}],"pyQName":"helpers.image_fill_triangle"},"helpers.imageFillPolygon4":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"x0"},{"name":"y0"},{"name":"x1"},{"name":"y1"},{"name":"x2"},{"name":"y2"},{"name":"x3"},{"name":"y3"},{"name":"col"}],"pyQName":"helpers.image_fill_polygon4"},"helpers.imageRotated":{"kind":-3,"retType":"Image","attributes":{"jsDoc":"Returns an image rotated by 90, 180, 270 deg clockwise"},"parameters":[{"name":"img","type":"Image"},{"name":"deg"}],"pyQName":"helpers.image_rotated"},"helpers.setScreenBrightness":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"b"}],"pyQName":"helpers.set_screen_brightness"},"helpers.screenBrightness":{"kind":-3,"retType":"number","parameters":[{"name":"img","type":"Image"}],"pyQName":"helpers.screen_brightness"},"image.screenImage":{"kind":-3,"retType":"Image","attributes":{"blockNamespace":"images","group":"Create","blockId":"imagescreen","block":"screen","help":"images/screen-image","jsDoc":"Get the screen image","_def":{"parts":[{"kind":"label","text":"screen","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"image.screen_image"},"image.Font":{"kind":9,"retType":"image.Font","extendsTypes":[]},"image.Font.charWidth":{"kind":2,"retType":"number","isInstance":true,"pyQName":"image.Font.char_width"},"image.Font.charHeight":{"kind":2,"retType":"number","isInstance":true,"pyQName":"image.Font.char_height"},"image.Font.data":{"kind":2,"retType":"Buffer","isInstance":true},"image.Font.multiplier":{"kind":2,"retType":"number","isInstance":true},"image.font8":{"kind":4,"retType":"image.Font","attributes":{"whenUsed":"true"}},"image.font12":{"kind":4,"retType":"image.Font","attributes":{"whenUsed":true,"jres":"true","jresURL":"data:font/x-mkcd-b26;base64,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9A9UANwHAAD4AQAI/AcAADhSIAGqCOoIrAS4Aq4BqAi4CKwG6gGqACABOVJQBFQDVAjIB0wAUgFSBgAA/AkACP4PAAA6UgAEdAYUAf4PFAH0AgAA/AEACAAI/gcAADtSAAAkCbQErwJkAhQDxAQAAPwJAAj+DwAAPVIgAJAMiAakBaYEiAawCAAA+AkACP4HAABCUkQIVARUAzYANACsDyQAAAD8CQAI/wcAAENSAAToBKoCrAH4D64AuAcAAPwJAAj+BwAAR1IACP4FKgUqASoB/g0AAPwBAAgACP4HAABKUgAA9g9QAV4JUAn2BwAA/AEACAAI/gcAAE1SAADoD6oCrAqoCugHCADoAw4I6AcIAAAATlIAAFIEUgNMAOQPSgJqBAAA/AkACP4HAABRUhAAWAiEBRIE0wQEB8gCAAL8CAAI/gcAAFRSAAG+BOoCqg2qA6oIvgcAAPwJAAj+BwAAVlIkAKwPrASmBKQEvASsBwAA/AkACP4PAABbUgAA/A8MA+QDFAn8BwAA+AEACPwHAAAAAF1SAADAANgKVgrUB3QAzAYAAPgJAAj+BwAAY1IQCPAEvAbyAbQC5AwAAPwBAAgACP4HAABkUgAAJAisB5YCrAKkDyQAAAD8AQAI/g8AAGVSoAIqCioJ6g8qAb4CoAYAAPwJAAj+BwAAZ1LABz4AqgeqBPoEqgSuBwAA/AAACP8HAABpUogIbARsAgwB/A8MAWoCKAQAAPwJAAj+B2pSAAV8BTwFPgW8A/wBBAF0BQYFdAUEAwAAb1ICAN4PVgXWB1YFVgXeDwAA/AkACP4HAABwUgAArAT8AqwB/A+qAvoGAAD4AQAI/gcAAHJSjAC8D7QFtAX2BbQHtAeMBwAA/AEACP4HdVIQABAO0AP4BfQF5AXoBwAA+AEACPwHAAB/UgAIdgVwBXQD+g94A3ADdgUAAPgJAAj+B4NSSAT8B/wH/gf8B/wH/Af8BwAE+AEACPwHh1IADvgBGATYBn4DbA9sAggE8AEACPwPAACIUoAAfAj0CbQJtAX4A1QBXAn2CVwJVAcAAIlSAACcCcoLyQmwB84FQgUOBPgBAAj+BwAAjVIICOgErALqAEsIogbkBAAA/AEACP4HAACRUjgASAz0A4wClgK8AswPIAD8AQAI/gcAAJtSAAAQCBAEEAKQAX4AEAAQCBAIEAzwAwAAnVIABBQCZAHkABwJAASIA34ACAgICPgHAACeUgAAiAloBAgCiAF+CAgICAz4AwAA4AEAAJ9SBAIEAvwBBAkECRAEEAP+CBAIEAzwAwAAoFIICAgG/gEICAgI+AcAAPwPBAQEBPwPAAChUkAIUAlICSwFNgOkASQJNAlMCUQHQAAAAKNSKAioCKQIogSgA54AkAiICIIIhAcIAAAAqFIAACQE5AMkAqQCJAMACBAH/gAQCPAHAACpUgAE/gOSBJIC/gsABBAD8AgfCBAI8AcAAKpSAAhECVwJZgUkA1wBRAE0CSQJXAdEAAAAq1IAAEgHyAR+AkgCQAcQABAP/gAQCPAHAACxUgAO/AEUDPQDVAjUBwQAEAf8ABAI8AcAALJSAACkCKQElAesBKQEMAAQDv4BEAjwBwAAs1IACLQIlASWBJQD1ACUCJQIlgiUBzQAAAC0UgAIuAiKBIoEiALrAYgIiAiMCIoHOAAAALlSKAioBKgCDAGoAggIUAQQA/4IEAjwBwAAv1IAABQIVAl+BRQFwAM0AR4JBAk8B0AAIADBUgAAtASEBLQHhAS0DAQEEAP+CBAI8AcAAMNSAAA0AhQJXgeUATQJAAQQA/4IEAjwBwAAx1IACAIK+gqqBqoC+gKqAq4Kqgr6BgAAAADJUhAI+ASWA/QAnAfwCBgKmAl+CAgK+AkABMtSAAjuCSoEqgMqCO4LAAAQB/4AEAjwBwAA0lIAAOQCvgL0D74C5AgEBBAD/ggQCPAHAADVUgAAfAl8CfwHeg0IBBgCkAF+CBAI8AcAANhSgACCB/8FqgSqBP8FggwIAv8BCAT4AwAA2VIAACoDqgjqBzYA4AlIBy4BNAk0CSwHRAHdUgAM/gOSCP4HgAFqCTgHrgE4CW4JqgcAAd5SEgiSCKgErgSgAqIBpAioCKYIKAdyAAAA31IAAkQB/AV+A3wDfAF8BX4F/AN8AUQCAADiUgAArAmsCe4FrAWAA/gBGAkOCXgGgABgAORSAAj0CdYF9AfWBfQFAAwQA/4IEAjwBwAA51IAACAB7A+4B+gHqAeoDgAG/AEQCPAHAADyUgAB/g3+Af4B/g3+AQgLmAh+AAgB+AwAAPNSBAh9BW0B/wTsAvwCAAaIAX8ECAT4AwAA9VIADPwDzA/8AewD/AvMDwAM/gMQCPAHAAD4UgAB+g+7B4AHuwe6BwAM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JAAAAK1T+AcEAPQD/AJ8B3QFhAckBPwDJAEUAgAErlMABv4BAgT6AVoD+gECDPoDSgDKD0oAAACyUwAO/gECAOoP6gHqBeIH6gXqBeoJCg8CALNTAA74AQ4E+Ae4BroG/A8IAOgMLAPqBSgIu1NAAEgMSAZIBcgEfgRIBEgFSAZICEAAAAC/UwAAgACABP4GqgWqBKoEqgSqBP4GgASAAMFTIAGoCKgK7Aq6CqgKqgruCqgKqAggAQAAwlMgASgBqAhsCroKqAooCWoErASgACABAADDUwAAAAGwAKQJdgulChQKJgl2BKAEMAFAAchTAAAACAQIHARkBIQCBAGEAmQEHAQECAAIyVMACAQIPAREBJQCFAGUAkQEPAQEBAAIAADKUwAEBAaEAXwIJATEBAQDHAOQAnAEEAQAAMtTAAQIBAgDyAh+BKgEKAMoA6gEaAQICAAEzFMUCDQERALkARwKAAh8BIQDxAI8BAAIAADNUwAAAAz8AyQI5AgkBSQCJAakBWQIBAgAAM5TAAL4AQABAAH+DwAAFAjkBAQDxAQ8BAQI0VMABBACHAuQCPAIXgVQBlAF1ghQCBAIAADUUwACoAEgCP4PJACgCwQIfAaEAeQCHAwACNZTBAT8B5QElASUAvwPAABoCIgFCAPoBBgI11MAAHQIHATcBFQFXAJcAlIF2gQaBDAIAADYUwAIpAiUCIQJvAaGBIYEvAaECZQIJAgACNlTUAZYAVQI8g9UAFQDBAh8BIQDxAI8DAAA21MAAKwIoAb+AaQAAA78AXIMkgOSAnIMAATgUwAA6Ah2CFYPVg9GD1YPXg9WD3gIyAgAAOFTAACoANgHvwfaB/oHkAAMDPQChAF8BgAE4lMIAKoE7Af4B/wH6A/oAPwH7AXqB4gJgAjjUwAAAAD8DwQEBAQEBAQEBAQEBPwPAAAAAORTAAAIAIgPiASIBP4EiASIBIgEiA8IAAAA5VMAAGAAEADMByoCKAIoAugLCAgIDPgDAADmUwAAgAi8BKQEpAPkAKQApAikCLwIgAcAAOhTAAD8AwQB/AkACAQGhAF8BAQIBAz8AwAA6VMAAPwDBAEEAfwBAAD8DwQABAIEAvwBAADqUwAAAAh8BEQCRAFEAEQARAFEAnwEAAgAAOtTAAD8AwQBBAH8AQAA/AMAAQAB/g8AAAAA7FOAAEQARA8kCRQJDAlECUQJRAk8DwAAAADtUwAA/AMEAfwBAAzAAzwAAAB8AIADAAwAAO5TAAD8AwQB/AEAAAQABAgECPwHBAAEAAAA71MAAAQA9AMUARQBFAH0AQQIBAj8BwQAAADwUwAAIACgD5gElgSRBJAEkASUBJgPIAAgAPJTAAh4CEgFSAZIAsgFfgRICEgISAh4CAAI81MAAYgAiADoD1wESgRIBEgESATIDwgAAAD2UwAA/AMEAQQB/AEgACAA/g8gACAAIAAAAPdTAABAAFwB1AFUAVQJVAlUCVQNXANAAAAA+FMAABQA1AdUAlQCVAJUAtQDFAgECPwPAAD5UwAA/AMEAfwFAAwcBGQChAFEAjwEBAgAAPxTAAD8AwQB/AEAAAQBhABECDQIBAz8AwAA/VMAAPwDBAH8CQAE/AMEAAQA/AcACAAGAAABVAAA/AMEAfwBAABEAEQIRAj8D0QARABAAANUAAD8AwQB/AEAABAEDguoCKgIaAgoCAgGBFRIAEgAJA+mBKsEkgSSBKoEpgQiD0AAQAAGVAAA/AMEAfwBAAhgBFgHxgRgBBAHAAgAAAhUIAAgAJAPiAikCKIIogikCIgIkA8gACAACVQAACQApA+kBKQEvwSkBKQEpASkDyQAAAAKVAAAgAe8AKQApADkD6QApACkBLwEgAMAAAtUAAD8AwQBBAH8AQAA0AAQCRAI/gcQABAADFQAAPwPBADUB1QCVAJUAtQDFAgECPwHAAANVAAAGAGIAIwA0wdjBFIESgRGBEAEwA8AAA5UAAAADvwBFACUD5QElASSBJIEkgSSDxAAD1QAAAQI9AiUBpQG/gWUBJQIlAiUCPQIBAgQVAAA/AMEAfwBAAQgBCAE/gcgBCAEIAQAABFUAAD4DwgA6AMsASoBKAHoCQgICAj4BwAAE1QAAPwDBAH8AQAABAAEAPwPBAAkAEQAAAAVVAAAAAC8D6QIpAikCKQIpAikCLwPAAAAABdUAAD8AwQB/AEAAHQBRAFECWQJXAzAAwAAG1QIAggBqgDqD7oErgSqBKoEqgS+DwgAAAAdVIAARABED0wFVAUmBSQFVAVMBUQPRACAAB5UIAIkAaQPZAkkCTwJJAkkCWQJpA8kASACH1QAAPwDBAH8AQAAsACIAKYIpAyIA7AAIAAgVAAA/AMEAQQB/AkABCAD/gAgAyYEKAgAACZUIAAkAKQPlASUBLwEhASUBJQEpA8kACAAJ1QAAPwDBAH8AQAA/AdECEQIfAhECEQI/AYoVPwDBAH8AQAA6AEIAQgB/gcICQgJ6AsICClUAAD8AwQB/AEACGAEWALGAUAIRgiYByAAK1QQAAgAKA8oCSwJKgkqCawJaAkoDwgAEAAsVAAA/AMEAfwBAAgABvwBJAAiAOIPIgAgAC1U/AMEAQQB/AEACAgE6AMqACoA6AcICAgGLlQAAPwDBAH8CQAEMAbsASIA6A8oCDAIIAYvVAAAwA84AKgPqASuBKgEqASoBLgEgA8AADFUAAD8AwQB/AkACGgEqAU+AigF6AQICAAAM1QAAAAJfAlABVwF1ANUAVQDVAXcBQAJAAg0VAAAQAlcCVQFVAfUAVQDVAVUBVwJQAkAADVUAAD8AwQB/AEACHgIAAT+BAACiAEwAAAAOFQAAPwDBAH8CQAEhAN8CIQEJAc8BeAEAAg5VAAA/AMEAfwJYAgeBAgD+AAIAwgEeAgAADtUAAD8AwQB/AEgAJwJagQYA/gICAT4AwAAPFQAAPwDBAH8AQAI9A9MAAAA/AcACAAIAAc+VCAAIgCqD6oEvgSqBKoEqgS6BKIPIAAAAEBUAAD8AwQB/AEABDoCIgGiCGII/gciACAAQlQAAAAAngeSBJIE8gSSBJIEkgSeBwAAAABGVAAIgAieBJICkgHyD5IBkgKSAp4EgAgABEhUAACACLwKpAqkCqQPpAqkCqQKvAqACAAASlQAACgApw+lBKQEpAS/BKQEpASkDyQAAABQVAAA/AMEAfwBAADwDxAD8ABeAJAJ8AcAAFVUAAD8AwQB/AEAAPwHBAQ0BcQEpAQUBQAEWFQAAAAI/gUyBDIDsgAyAjICMgT+BQAIAABbVAAA/AMEAfwBEADIByQIIgkkCcgIEAYQAFxUAAD8AwQB/AEAAHwBRAFGAWQJZAjcBwAAYlQAAPwDBAH8CQAE/gMSANIHkgiSCF4GAABmVAAA/AMEAfwAEAPuAiAJCAb+AQgI+AcAAGhUAAAADv4BAgCqB6oCugKqCyoIAgj+BwAAc1QAAPwDBAH8AQAESAJIAf4PSAFIAkgEAAB1VAAA/AMEAfwBAAD0AxQBFAH0CQQI/AcEAHtUAAD8AwQB/AEAAPwDJAEkAf8PJAEkAfwDfFQAAPwDBAH8AQAAtAiECPwHggCyAIoAAAB9VAAAEADQB1gCWALUAxIA1A9YAEgC0AEQAIZUAAD8AwQB/AEwAPgDlgSUBPQFBAX8BAACi1QAAPwDBAH8ARAACAAOAPgPKAEoASgBAACMVAAClAFUAPwHUgAAAPwHBAIEAgQC/AcAAI9UAAD8AwQB/AQAAtQBFAj0D4QAQAEgBgAEkFQAAPwDBAH8AWAA/A8CANAAEAkQCP4HEACSVAAIHAgUBNQDXABAAFwAVADUBxwIAAgABpVUAAD8AwQB/AEAAJAPkASQBP4EkASQDxAAllQAAPwHBAH8DAAC/gkIDPAD/A8EBPwPAACZVAAA/AMEAfwJAASQA34IEATyB5YIVAgQBJpUAAD8AwQB/AFQAEgCLgK1BDQFTAlEAEAAplQAAPwDBAH8AQAI7ASsAv4BrAKsBLwJAAinVAAA/AMEAfwBQAi8BJQDYAD4CQAI/gcAAKhUIAARAIoPoASsBKMEkgSOBJIEog8uAAAAqlQAAPwHBAL8AwAIrAcgAP4PIACoAyQMAACsVAAA/AMEAfwBAAgoCKgECgPMBQgEaAhACK9UAAD8AwQB/AEQAYgPVgllCXQJXAmED4AAsVQAAPwBBAH8AQAA+AeoAqwCqgKoAvgHAACyVAAA/AMEAfwJAAhOBEwC+AFMAk4ESggAALNUAAD8AwQB/AEACCQFtARvAiQClAVECAAAuFQADPgDCACoB6gCqAoIC/4ICAfKCCwIAAa9VAAA/AMEAfgA/g8CBCIF+gSiBQIE/g8AAMBUAAIEAXQBVA/UBFUE1gRUAVQCdAUEBQAIwVQAAMAPQAReBNIHEgDSD1IEXgRABMAPAADEVAAA/AMEAfwBAAiIBP4CiACIAP4CiAyACMZUAAD8AwQB/AEACCgJpASWBFQCTAHEAAAAx1QAAPwDBAH8AQAIJAkkCb4PJAkkCSAJAADIVAAA/AMEAfwBYAAwD6gEpgSoBDAPYABAAMlUEADUB1QCXgJUAtQJEAz+AhADkgRUCAAHzVQAAPwDBAH8AQAA+A8IAOgDLgHoCQgI+AfOVAAA/AMEAfwBAAgkCM4EBAMEBc4EJAgECNFUAAD8AwQB/AVABAQE/AcEBPwHBATkBAAA11QAAPwDBAH8AQAAfAECAZAPPgFIAUQBJADfVAAA/AMEAfwBAAT8BYIEEALOCAgI+AcAAOFUAAAACP8LrQatBq0CrQKtBq0G/wsACAAA5VQAAEQAfAdsBWwFbAVsB3wARAj8D0QAAADmVAAA/AMEAfwBAAj8D5IAEAz+A5AFVggABuhUAAD8AwQB/AEAAPYPUAFeAVAJUAn2BwAA6VT8AwQB/AEAAHwJVAlUCfwPVAlUCXwJAADqVAAA/AMEAfgMAgL+CZII/gf8DwIA/gMAAO1UgAieCJIIkgSeA8AAnAOUBNQE3AiACAAA7lQAAP4BggD+AIABagEqCb8PagEuASoBCQHyVAAAEgCyD78EigSgBJ4EiQSJBLkHCQAIAPpU/AMEAfwBAADoD6gCqAL+D6gCqgrsBwAA/FQAAPwBhAD8AAAAvAisCK4OrAGsAbwABAABVQAA/AcEA/wDAACoDqgKqgqqCqgKqA4IAAZVAAD8AwQB/AlACCgJngaIBPwGzAVYCEAIB1UAAAAP/gAiDuoKqgpqCqoKqgoqDSIBAAAJVQAA/AMEAfwBAAgoCS4F6gMoBS4JKAkAABBVAAb8AQQAXAdcBVwF/gVcBVwFfAcUAAAAFFUAAPwDBAH8AQAAqge6BK4EqgS6BKIHIAAgVQAA/AMEAfwBAAiUBJYC1AmUCJYMNAMAACRV/AMEAfwBAAj4BJQClgH0AZwClAT0BIAIJ1UAAPwDBAH8AQAE/AdUAjwA+A8EAPwDAAAsVQAA/AMEAfwBAAz4AygIPgdsAGwHTAgABC5VCAAIAHwPXgVcBVwFfgVcBVwFXA9EAAAAL1UAAPwDBAH8AQAA/A+qBKgE/geoBKgEAAAxVQAA/AMEAfwBAAD+B2oFagVqBWoF/gcAADdVAAD8AwQB/AEACPQH7ADmAmUKZAr0ByQAOFUAAPwDBAH8CAAGKACkBLIJNAr0ACQGCAg+VQAA/AMEAfwBAAjUChQK/A8UCtIKUAoQCENVAAD+AYIA/gAIAO4PqAKvAqoKqgrqDwAARFUAAPwDBAH8ASAElAJUCiwJxAdkAJQDAARGVQAAAAD0DxQAfAcWBTQFVAVcBxQA9A8AAEpVAAD8AwQB+AD+DzIAzAHkAxQB5Aj8BwQAT1UAAP4PKgCqB74CgAK+AqoDKggqCP4HAABTVcIAOgCqB6oEqgS6BJAEzgS0BDQHTACEAF9VAAb8AaoHqgKqAroDIAR+AogB6AIYBAAAYVUAAPwDBAH8AQAAKAH+DwAA/g8oASgBAABkVfwDBAH8AQAAfALUAtQCfgJUD1QCfAIAAGVVAAD8AwQB/AEQAEgHRAXyBVQFRAVIB1AAZlUAAPwDBAH8AQAM/gMICGAIiQkKDugJAABqVQAA/AMEAfwBgAj+B0AA+A+MBIoE+A8AAHBVAAD8AwQB+AmOCVIIfgVSAl4B0gFeAAAAeFX8AwQB/AEADKwDLAYsAf4PLAEsArwPCAB8VQAA/AMEAfwBAABsB6QApg+0AKQEpAMAAIBVAAD8BwQC/AMAAKQPtAlWCVQJpA6MAAAAglX8AwQB/AEAAPwA1A/UCPwJ1ALUB/wJAACDVQAA/AMEAfwA4A8UALQCngfUAhQI9AcAAIRVAAFEAVQPVgtUC/wLVAtUC9YL1A9EAQAAh1UAAPwDBAH8DGQCng/0AZQCYAj4CP4HAACJVQAA/AMEAfwBYAD4DwYAUAlUBdQDXAVQCYpVAAD8AwQB/AzwAwgHqAIIDX4CiAVqCAAGlFUAAPwDBAH8DAAC/Ak0CPQKtA+0CrwKAACYVfwDBAH8AQAAvA+wALAP/gCwD7AAvA8AAJpVAAD8AYQAfAjwBVgFNgOUAzwFUAXwCQABnFUAAQQBfA/cC1wLXgtcC1wL3At8DwQBAAGdVQAA/AMEAfwBAAC+BqoEqgWqCKoIvgcAAKdVAAD8AwQB/AEICPQLtAq2CrQK1AscCAAAqlUAAIQIvAisD7wIhAj+CYQCvASsCrwKhAirVQAA/AMEAfwJAAg+BTQDwAM8BQQJfAkAAKxVKAAsAJwP/ADcB9wF3AXcBfwHmgioDyAArlUAAAAE/gVaBVoF/g9QBV4FWgX6BQ4EAACyVQAA/gMCAf4BGAznApAAUAaOAAgI+AcAALNVAAD8AwQB/AEACNQLrAquCqwK1AsUCAAAtVX+AYIA/gAAAPAPkgSXBPIHkASXBPIHAgC2VQAAGAAKB3wFWAXeBVgFWAV8BQoHGAAAALdV/AMEAfwBAAjUC1QIVAZWAVQEVAjUCwAIu1UAAPwDBAH8ARgA2A+0AvIPlAEYCMgHEADFVQAA/AMEAfwBAAh8BVwFXgNeA9wFfAUACc5VAAD8AwQB/AEADP4AqgaqAP4EqgGCDwAA01UAAPwDBAH8AQAIUgV2A4YPlgNSBTAFAAjaVQAA/AMEAfwJAAT8ANQO1gDUBdwIwAcAANxVAAD8AwQB/AFAADQHfgfUB9wH1AfUBwAA4VX8AwQB/AEABMgCVAqiBxAAUgJ0CuQHCADjVQAA3A/UB9QP3A+EAVQC1AsECPwHAAAAAORV/AEEAfwBAATgB2wGeAbuB2gGaAbsDyAI5lUAAPwDBAH8AQAMVAH0CV4HFAGUBTAIAADoVQAA/AMEAfwAAA5EAJADzAKoC6gK6AcAAu9VAAD8AwQB+AA+AWICagRaBVoEQgF+AwAC/VUAAPwDBAH8BCQC/g9UAXQJEAbOAQgGOAgAVgAA/AMEAfwBAAD0DxQC9gVUBVwHFAj0BwFWAAD+AYIA/g74AYQE9AcUAIcEfAOFBnQCBlb8AwQB/AEACPQK1ArWBvQD1AbWCvQKAAAJVgAAgg6+Au4KrgqvBq4M7gquCr4Kgg4AAA5WAAD4AwgB8AUEBXwF/AN8A3wF/AV8BwQDF1YAAAwARg/WC/QL9gv0C/QL9gvFD5wAAAAbVgAA/AMEAfwI+AcEAfQPJgKEAfQPpAAEAx9WAAD8AwQB/ACAD34FUAWID/wHBAD8AwAAMVYAAPwBhAB8CAAH/A60AdwF/AfUAdwPAAAyVgAA/AMEAfwDfAKuD3wC/geSAP4PAAAAADRWAAD8AwQB/AEQBNgD7gL0B/AC7gLUBxAANlYAAPwDBAH4AAQN/gFUAf4N/AMkAOIPIgA5VgAA/gOCAf4BAAz6AVYJUw9WAfoBMgwAADtWAAD8AwQB/AEAAHwP3AteC1wL3At8DwQBP1b8AYQA/AAACF4FVgFSBf4JWgFSBV4AAA5BVgAA/AMEAfwAIA1UAdwHBAvcC1QJdAEADWJWAAD8AwQB+Al8CAwFZAN2ASQDRAV8CQAAaFYAAEACXA9UCdQJfA9gAEwP9Al0CVwPQAJpVgQIxAv8CvwLRAj8D0QI/AvsCvwLBAgAAGpWAAD8AwQB/AnABbwF9AOUD/QPvAPgBQAIdFYAAPwBhAD8BBAE9Af0AvYC9ALUBvQHEAiHVgAA/AMECfwH5As/COQPJA3kA/8PJACgA45WAAD8AwQB/AFACDwGvAa+A7wPvAPkBAAAo1YAAIgH7gWuBW4HWABuB24FrgVuBYgHAAC0VgAO4AG8BPQH9AfsD7gB1Al0BvwFYAgAALdWAAD8AwQB/AUADPwP7An+AfQH7AX8CQAAvFYAAPwDBAH8AQAA9A/yBfoMMgG5CLUHgADCVgAACAL+B/4H/gf+BvgA/gb+B/4HCAUAAclWAAD+AYIAfAH3BqUCBwP9D1cF9QdXBQAAylYABbQD/Av8B/wFngX8AfwD/AXcB5QHAADaVgAA/g8CBAIFggRCBDoEwgQCBQIE/g8AANtWAAD8DwQExAU8BAQEBAR8BIQEBAT8DwAA3lYAAP4PAgTyBJIEkgSSBPIEAgQCBP4PAADgVgAA/g8CBCIFIgWiBHoEogQiBQIE/g8AAOJWAAD+BwIEkgRSBFIFMgX6BRIEAgT+BwAA41YAAP4HAgQKBGoECgUKBfoECgQCBP4HAADkVv4PAgRSBJIEkgT6BZIGkgZSBgIE/g8AAO1WAAD+BwIEKgXqBCoE6gUqBSoFAgT+BwAA8FYAAP4PAgSiBWIE+gViBKIEIgUCBP4PAADxVgAA/A8EBEQFJAVXBZQEdAUUBQQE/A8AAPJWAAD+DwIEkgT6BZIEkgT6BZIEAgT+DwAA81YAAP4PAgZaB0IFygTCBDIFCgUCBP4PAAD0VgAA/g8CBKoEqgT6BaoEqgSKBQIE/g8AAPpWAAD+DwIEEgTSBVIFegVSBdIFAgT+DwAA/VYAAP4PAgQqBSoF+gUqBWoFKgUCBP4PAAD+VgAA/w8BBCkFLQUVBZUFrQYlBgEE/w8AAANXAAD8BwQE9AX0BPwE/AX0BPQE9AUEBPwHBlf+BwIG3gZWBlYFVgVWBF4GwgYCBP4HAAAIVwAA/gcCBD4E/gU6BroGegY6BQIE/gcAAAtXAAD+BwIE6gWqBUoEegWKBW4GAgT+BwAADVcAAP4HAgT+BX4FfgX+BX4FegUCBP4HAAAPVwAA/gcCBGoE6gX6BuoG+gZqBAIE/gcAABJXAAD+DwIM6g1qC3oLagtqC+oLAgz+DwAAE1cAAP4PAgjCC/oL6gvqC+oL+gsCCP4PAAAWVwAA/gcCBP4H9gf2B/YHfgbiBwIE/gcAABhX/g8CBP4E/gX+BP4E/gb+B/4EAgT+DwAAH1cABCAEIAQgBCAE/gcgBCAEIAQgBAAEAAAjV0AIRAhMCSwJNAmkDzQJNAlMCUQIQAgAACdXAAAADPwDBAhECEQI9A9ECEQIRAgECAAAKFcIAYgAyA84AI4IiAiICOgPiAiICIgIAAAtVwAIJAkkCSQJJAm/DyQJJAkkCSQJIAgAADBXAAIQAv4BEAFAAPwHIAggCP4JEAgQCfgEM1cABBAC/gMQAQAM/gMAAAAA/AcAAAAA/g86VwACEAL+AxABAAEiCfIEKgLmCSIM4AMAAD5XAAQQAv4DEAoABIQDfAiEBCQHPAXgBAAIQFcQAhAC/gEQAQAI8A8ACAAI/g8gCCAIIAhCVwACEAL/AZAEAAb+ATIM0gISA5ICcgQCCEdXAAIQAv4BEAEwAAwCKgEoCagICAz4AwAASlcQAhAC/gEQCQAMCAL4AUoISAhICMgHCABOVwACEAL+ARABQAg0CAoG6AEIAkgEOAgAAE9XAAIQAv4BEAFEAUQAJAD8DwQAJADEAIAAUFcgCJAIjgiwCIAI/g+gCJAIjgiQCCAIAABRVwACEAL+ARABAAzoAyoAKgDoBwgICAYAAFdXAAIQAf4BkACACAgESAP+AMgBSAJ4BEAIWlcACD4IAAkACX4JRg8qCRIJKgkmCUAIAABbVwACEAL+ARABAAQkBqQFZAQkBKQFJA4ACF1XAAIQAv4BEAEACP4JAgQCAvoBAgQCBP4JXlcQAhAC/gMQAQAC/AKEAoYCpgqkCJwHAABfVwACEAL+ARABgAkIBHgEigOMAngECAgIBGBXAAR+BQIFPgUCBaAHMAUOBRAFIAVABAAAYVcAAhAC/gMQCQAM+APICX4GSAbICVgIAABkVxAC/gEQAQAA/AMkASQB/w8kASQB/AMAAGZXgAAQAf4AkAAABP4EkgSSBJIEkgT+BAAEalcAABAC/gMQAQIAugCCAP4PggCyAIoAAABvVwAEEAL+AxACQAlECCQI/AskCEQIhAgAAHdXAAIQAv4DEAEEAPQDFAH0CQQI/AcEAAAAglcAAEACVAr0C1QKVAr8D1QK8gtSCkAAAACDVwACEAL+ARABAAQoBMgFCgQIB+gECAQAAIRXiAiICmgKGApMCkgPeAqsCqwKiApICAAAi1cAAEAEygQ+BAoFfgUKBwAFHgVABX4EAASSV0AIaAlICWwJCgkID2gJTAlICSgJQAgAAJtXAAQQBP4DEAIACKAEngLCD4IBvgKgBKAIolcAAhAC/gEQAQAO/AGUD1QEVARSBNIPEACjVwACEAL+AxAJBAj0C1QKVApUClQK9AsECKZXAAAACP4KqgoqCioPagqqCqoK3gqACoAIq1ckBJQF/gUUBQAF1Ac0BR4FBAV8BIAEQACuVwAEEAL8AxACgACoArgDrAqoCpgKqAaoAMJXAAIQAv4DEAkACfwHrAasBfwIrAisCPwAw1cABBAC/gMQAUAIKAkuBegDLAUsCSAJAADLVwACEAL+ARABAAh8CVQJVAn8D1QJVAl8Cc5XAAAQAv4BAAz4AygAKArICX4EiAduCAgG1FcAAhAC/gEQAQAA6A+oAqgC/g+oAqoK6gffVwAAEAL+ARABQACoAugKCAR+AogFaggMBuBXAAIQAv4BEAEAAvwCtAK2D7QCtAL8AgAC91cAAJQC1AKeD/QCEAhIBv4BCAEIAPgHAAz5VwABEAL+AQABJACkB7QEpgSkBLwErAckAPpXAABIAUgF/AR4BXgHeAV4BfwESAVIAQAA/FcAAhAB/gEQAQAAtAe0Aq4LNgg0CPQPNAAAWAAACAH/AAAG/wEFDnUERQT1B0UEdwcAAAJYAAA4CAoK7AqoCq4PqAqoCuwKCgo4CAAABVgABH4FVgV2BVYFXgcABUoFMgU6BUYEQAAGWBACEAH+AYAAMAD8D6oEqAT+B6gEqAQAABVYAAj+CgoKdgoACnwPPgo8CrwK/AoECAAAIVgQABAEfgUABV4FOgcaBXoFOgVeBVAEAAAkWBAEEAT+AxAKgAi+BqoEqg+qCqoKvgqACCpYAAAQBP4DEAMED/4JVAtUC1QJ/g0ECQAAL1gAAJgJnAl8BVwDDgFcAVwHfAlcCVgFAAAwWAACEAH+ARAA/A8EBPwGfAd8BfwFfARAADFYAABUAXQB3gd0AQAA/g9iCLIEMgPuDAAENFgAAggC/gEIAEAJ/gVqA2oFagNqCX4HAAA1WAACEAH+ARAB1ABUAN4HdAVQBVgF1gcQADpYAAEIAf4AgAm+BKoE6gM+ACoA6g++AQABQVgACEAJfgtqCyoKPg8qCqoKagt+C0AJAABKWAAEEAL+AxABAAF8CFYH1QD8B1QIVAt8C0xYCAEIAf8BCAFAAN8BVQXVB5UBVQnfDwAAUVgAAGgIzAp4CkwKKA+ACnwKVApUCvwIAABUWAACEAL+ARABRAAkByYFVAVUBSYFJAdEAFdY2ggCCooKqAosCqwOqgr6CiwKrAqoCAgAWFgAAggB/wEIAQAG/AEcBl0F+gVcBXwHFABaWAACEAL+AZAFBgWqAnoKigk6BsoAJgcAAF5YAACECrQKtAn0CrQKtg70CrQJtAqECgAAaVgAARAB/gEQBTgE9gfUB9QE1Af0BIQHAARrWAAEEAL+AxABAAj8C7wKvgK8CvwLBAoAAHVYAAAADP4H6gT+BWoFawd+BeoF6gX6BAAAflhECHwJfAv+C3wKAA+ICmgKHgr4CAAJwAiDWAACCAL/AYgICAj6BV4DWwFeD/oJCAQAAIVYAAh+C2oL/gtqC34PEAqSCvoKFgpyCAAAilgAAKwIrAruC7wKiA/oCjwKSAr4CAAJwAiTWAABRAX8BH4FfAV8BXwHfAV+BPwERAUAAZdYAAIQAv4BAAF8ANcP1Ar8CtQK1wr8DwAAmVgAABAD/gGQAAQA7AfkB/4G5AZsBeQHAACcWAAAfgSKBnYGAAZWBzwFtAX0BRYFZASAAJ5YAAAQA/8BgAA8AOYPdAV8BWQF5w88AAAAqFgABCAEfgU6BXoFPgd6BT4FOgV+BSAEAACpWBAE/gMQA3AC2grcD/gDAAr+BIgDeAwAAK5YAAD+CAIKfgoACvYPOwp+Cn4K3gp+CAgIs1gAAhAC/gEQAQQI1AfcB94D1APUB9QLEAjBWEAAfgRqBWoFagVuBzQFPAV2BTQFPAUABMdYAAAQAf4BAAF8BMwH/Af+B/wHzAd8BAQEylgAABAC/gEAA/QK1A70Cd4F9ALUBvQIAAjTWAAM/gPKAf4G/ga+B8IHEgf6BvIGtAQAAdVYAAAQAv4BEABEBbwGvAO+C7wHvAHkBgAE2FgABHAFfgV+BX4FfgcuBX4FfgV+BXAEAADeWAAAEAL+AQAAXAKsDjwJbgk8AuwG/AgAAOJYAAAQBPwDAAj8BwQA9A5kCAQO9AqkCgAA5FgAABAC/gEABXwE7A3+C8YB/AfsBfwJBAHrWCAAIAQgBCAEIAT+ByAEIAQgBCAEIAAAAO5YAAIYAgAB/g8AACAIIAj+DyAIIAggCAAA71iACJ4HkAD+DwAAIAggCCAI/g8gCCAIIAjwWAAABAzUA1QBVAHeAVQBVAFUAdQDBAAAAPJYAAjECFQIVAZUAV4AVABUB1QIVAjEBAAA81gACMQIVAhUBNQD3gDUANQHVAhUCMQIAAT2WAAAxAhUClQIVA9UCF4IVA9UCFQKxAgAAPlYAAA0BLwFfAV8BX4FfAV8B/wF3AUUBAAA+lgAAGQINAu0CvQOPgj0DrQKtAo0C2QIAAD9WJQA3Ab8BvwG/Ab+APwE/AL8CtwP1AKAAARZgAhgCN4ECAPoAhgEAAj+CyAIQAiACAAAB1lAAFAASA+sCrYKpA+0CqwKzArED0AAQAAJWQQKRAo0CYQFpAaeBMQG/AaECZQIJAgAAA1ZAAAICAgKdgneB1wFXAVcBVwLfAkECAAID1kACAQKfAl8BfwHfAV8BXwHfAl8CQQIAAgVWQAAQAAgCBAISAROBIoCCAGIAGgAGAAAABZZQABgCFAEjgKIAWgAEAAgAP4PgAAAAQACGlkAAFAISAlECTQFpgSUBkwCRAHAAEAAAAAcWYQARAD0DwQARAhmBLQDFAOUBHQEFAgAAB9ZIADwAywJ6AkICPgHAACoCJYEVAJMAcAAIFkICagEdgVUAswBEADMAyoB6AkICPgHAAAiWcQAfApsCm4L/AtsBWwFdgNsAXwAxAAAACVZAAj8BNQC/A/UAvwAEAhICdYGtASMA4AAJ1kQCBAEEAIQAdAAPgBQAJABEAIQBBAIAAApWUAIRAhEBEQCRAP8AEQBRAJEBEQIQAgAACpZEAgQBBAEEAPQAj4EUAiQARACEAQQCAAAK1lACEgESARIAkgB/gBIAUgCSARIBEAIAAAtWQAAQAhECEQERAREA/wARANEBEIEQghACC5ZAACACPgIiASIA/4AiAGIBogE+AiACAAAL1mAAEgIyAioBJgDzgCICIgImAgoB0gAiAAxWWAIcAROBEgCyAF+AMgBSAJIBEgEQAgAADRZQARICFIEVAREAsABfgBAAkACQARACAAAN1kAAAQI7ASsBKwC/gGsA6wErAq8CoQJAAA4WQAAKACoAKgCuAOsAqgKqAq4CqgGqAAoADlZAACACIgIqAiIBIgD/gCIA4gEqASICIAIOlkAAKgAqACoAJgGjACKCJgImA+oAKgAqAA+WQgJiAhoBAgECAP8AAgDiARoCIgICAkAAERZSAAoAOgHuAKsAuoHqAqoCrgK6AtICAAAR1kAADQAtAe0ArQCrAKuAywINAj0BzQAIABIWSgEqAyoApgIrAiqB6gAmAKoAqgMKAAAAElZAACgAKwCbAIsArwCrg+sAiwCbAKsAqAAS1lAAEQA5A9UBUwFxgdMBVQFZAXkD0QAQABOWRQEVARMBVwFVgV1B1QFXAVMBVQFFAQAAE9ZkABUCFwFfAVcA94BXANcBXwFXAlcCJAAUVkAAFQJVAl+CVQFQANCAyIFHglCCT4JAABUWSABJAkUBawDJAEmAXUBJAGMDxQBJAEgAVVZJAlUCUQJJAUcBQYDBgF8BQQFFAUkCQAIVlkgCSQJEAl+CQAFSANEAyYFJAkcCQQJAABXWSAAJAEUBfwHdAV2BXQFdAV8BRQNJAkgAFpZAAmECawFZAW0A6oBYgNSA0IFSgUACQAAYFkAAAQF/AXuBe4F3APcA+4F7gX8BQQFAABiWSgBKgGqAK4P6gq7CqoKugqmCqYPKgAqAGVZAAAACXwJDAVkBXYDJANMBQQFfAkACQAAZ1kACXwJBAVsBWwFLAN+ASwDLAOEBfwFAAloWQAALgkgCX4FAAUkA5IBFgORBf0FFQkQCWpZAABUATQB/AP0B/YB9AX0BfQD/AGUARQBblkAABoAmg/+Cv4K+w/6CvoK/gr6D0oAAABzWQAAEAgQCdAIMAkeBRICEAKQBXAEEAgQCHRZiAj4BA4DyAE4CAAMNATEA8QCPAQACAAAdlkICPgMDgOIA3AIBAf8AAQEPAgkCOAHAAB4WQAA+AgOBYgDeAwAAEQARAD8D0QARABAAHlZAAj4DA4DiAF4BgAA/AcQCP4JCAj4CAAGfVkACOgMHgOIA3gEAABECEQI9A9MAEQAQACCWQAACAj4CA4F6AMQAPwPBAQEBAQE/A8AAINZAAj4CA4FiAN4BAAAxAdECEQIRAj8CAAGhFmACIQIvAqkC6QKpgSkBKQHpAikCIQIAACGWQAAGAOAAP4PAACQCHAJHgYQA/AEEAgQCIdZCAj4BA4DiAF4AAAERAREBEQERAT8DwAAiFkACPgMDgPoAhgEcAFEAUQJZAlcDMADAACSWQAI+AwOA+gDGAzwA0gASgBKAEgA+AAAAJNZCAj4BI4CyAE4AgAIaASoBT4CqAVoBAgIllkABPwEBwPEAjwAAAwiAqIBfgChASECIASZWQAA6AieBsgBOAIACDwEgAT+AgACjAEwAJ5ZEAjwBA4DiAN4AAgI4A9cCEQI/A9ACAAApVkAAEQIVAbEB2QGbAJEAmIF8gRKBEAIAACoWQgA+AkOBYgDcAQAAAgP+ABOCEgIyAcIAK5ZAAj4DA8D+AgADP4DEgDSB5IIkgheCAAGs1kAANAIPgUQA/gEAADUAwoI+A8IANgBCAK5WQAI+AgOBYgDeAAADEgCSAH+D0gBSAJIBLtZFAlcCVwLXAvcBX4FXAVcB1wFfAkUCQAAxlkACPgJDAb4BQAA/AdEBFQFVAxEDPwHQATJWQAA6AgfB8gBOAbAASQAJAD+DyQA5AMAAMpZCAj4CA4H6AEQBngARA/EAP4PRADEBwAAy1kAAOgNHgOIAXgCAACwD64EoASsBDAHQADQWQAA+AkOBugDEAj8DyQJJAkkCfwPAAgAANFZAAD4DA4DiAN4BAAAkA+QBP4EkASQDwAA01kAAOgIHgXIAzgAIAicCJAI/g+QCJAIAAjUWagIrAisC5wKzAb8BIwCmgWqBKoIqAgAANpZAAj4BA4D8AgMCYAE/gMAAP4HQAicCIQG3FmgCKwIrQquC6wGvASsBq4FrQSsCKQIAADlWRAI8AQeA5ADeAQAAagHfgkoCTgJKAUkAOhZAAj4DI4DcAQEAOwMrAL+AawCrAS8CQAI61kAAPQMjwLkARgA/g+SBJIEngeSBPIEAATsWQAI+AQPA+gBEAD+BwIE8gSeB5IE8gQCBPtZAAD4DA8D6AEQAv4PAgXiBLoFAgT+DwAA/1kAAKIIlArUC8AGpgSUBIwGlAWkCKwIAAABWgAO+AEIBNgFeALYAwgI/gQIA8oEKggABgNaAAj4CA4H+AQAACQJJAm+DyQJJAkgCQAABFrICMgIrgqYC9gG/gSYBpwFqgTqCMgIAAAHWgAI+AQOA8gBOAZQADQPHAAUADIPUgCAABhaAAj4BA4D+AYAAPwPVARWBNQBVAO8BIAEG1oAAPANHgP4AAQIcAlcB+QBZAN8BcAJAAkcWgAA+AyOA3gIAgb+AZII/gf8DwIA/gMAAB9aCAj4CA4F6AMYAMAPvAK0ArQKtAr8DwAAJVoACPgMDgP4AgAKlAj8DxIE/gKQBVYIAAYpWgAI+AgOBcgDOAj4CJQElgP0D5wI8AgABDFaCAj4CAwFiANwCAwJVAfUAVQDVAVcCQAJNFoAAPgMDgP4APIPBACgAfoHogACCP4HAAA2WoAIwgj+CtoL/gaiBsgGtAWUBKwIpAgAAEZaSAhqCQoLYAscBUwFXAUuBSwHXAlECQAASVoAAPgMDgP4AAAITAw0A0YA9AcUCPQJAARaWgAA6ASeAsgBMAC+B2oFagVOBZoHKQAoAGZaAADoCJwGyAEwBoQDvAD8D7wAvASgAwAAdFpAAF4JQgkyC44FAAVeBUIHMglOCQABAAB2WggE+ASPA3gCAAD0A1QB9gdUAVQB9AEAAHdaAADwCI8HfAyABXwAbAluD2wBfADEAQAAf1oAAPAMDgP8BAgAog/aAN4CagtqCuoPIgCSWgAE+AQOA/gCAACEBr4B7AesAb4ChAQAAJpaAAj4CI4HeAAAB/4Ayg+uCqoKqgruDwAAm1rICL4EiANwCAQOXAH0BdwG0gbaBVIIAACzWgAA8AkcBvABAAz8AVQJVgNVAVQF/A0AAL1aAADwCI8FfAIADP4Aqg6qAP4EqgGCDwAAwVrICL4EiAN4AgAAVAW0AnYJtAfUAFQDQATCWgAA+AwOA/gCAAq8CKwH/gSgBqwFvAgAAMla6AgcBcoDMAKIDPwDBAiVBvYBlAaUCAAAzFrICT4FiAN4CAAIXAX4D1gB+A9cA/gFSAjhWgAA+AgOBegDGADgDxwC9gVUBRwC9A8AAONaAADwCI8FfAIACPoBogm+A6oLqgmiBwAA6VoAAPgMDgPwBCQC/g/eD2QBcAyOA3gEAAgJWwAA+AgOB/AEBAB8D9wLXgtcC9wLfA8EAQxbAAD4BI8DfAIAAJYP/gPWBdYH/QCVDyQAUFsAAEAARABEAEQIRAjkB1QATABMAEQAQABUW4AAhAiECPQPTABEAAAA/AcACAAIAAgABlVbQAFCATIBLgkiCaIHagEuAWgBSAE4AQAAV1sAAIwAhACUCJQI1ge0ALQAlACEAIwAAABYWwABiADIDzgADAEoCSgJqAdoASgBCAEAAFlbgACECOQHXABEAAAB8AgACP4PAABwAIABXFsAAEIIQgjyD0oAJggwBG8EiAPIAjgECAhdWwAAkABUAVQBVAl+CVQH1AFcAVQBEgEQAV9bAAAAABAEkAeSBJIHugSWB5IEkAcABAAAY1uQAlQCVAK0CpQKvAeUA7ICUgJSApACAABkW4AAhAj0B0wAAA/8AAQO/AUEBvwIAgMADGZbAAA4AQoBLAEoCSoJrAdoASgBDgE4AQAAaVuECIQI9A9MAAAIKAW4BGoCLAOIBEgIAABrW4QARAj0D0wAxASUAuwApA+UANIEBAUAAHVbAAD8C3QH8AD8D/wBCAAkCaoPYgEqAQAAeFsAAOACPAK8ArwKsAq2BqADvAI8AuACAAB9WwIA+gK+Ar8CugrgCrAOtwP2ArYCNgIAAIFbAABYAEgASAhICMoHSABIAEgASABYAAAAg1sAABgACADoB4gIigiOCEgIKAgICBgGAACFWwAADAEkASQBpADmB5QIlAiUCIQInAYAAIdbAACcAIQAlAiUCPYHlACUAJQAhACcAAAAiFsAACwApAAkAyQAJggkCPQPJAAkACwAAACJWwAALAgkBeQFNAUmAiQDpAJkBCQMLAQAAItbAAhcDEQERAPEAPYPxABEAUQCRARcCAAEjFsAAJwIhAiUBJQDlQCWAJQHlAiECJwIgASPWwAALAQkA+QINAjmB2QEJAQkBSQGJAgIAJdbAACcBIQClAKUCJYPlACUAJQChAKcBAAAmFsAABwABAD0B1QFVgVUBVQFdAUEBxwAAACZWwAABgDyD5IEkgT7B5IEkgSSBPIPBgAAAJpbAAgcDIQDNAI0BPYPtAi0CLQIhAgcCAAAm1uAAIwIRAQ0A6QBRgDkByQIJAkkCewEAACcWwAAHAQEBPQHVAVVBVYFVAX0BwQEHAQAAJ1bAAAMCLQItAi0CPcPtAi0CrQKtAocCAAAnlsAABgJSAkICSgFCgPsAQgDCAUIBRgJAACfWwAADAlcCVwFXAP+AVwDXAVcBVwJHAkAAKBbAAgsDCQC5AE0BCYC7AcsCaQIpAgsBAAAoVsAAAwA5ANUAVQB9gdUAVQBVAHkAwwAAACiW4ACLAEkAaQPtAlWCVQJtAmUD4QBDAGAAKNbAAAcCAQI1A9UDVYNVA1UDdQPBAgcCAAApFsAAAwIhAqUCvQK1g9UCnQKdArECowIAACmWwAADAD0D1QJVAlWCXQPVAlUCdQJHAgAAKpbAADMCMQItASkA6YA9gCkB6QIpAiMCAAGq1sAABwABAd0BVQFVgVUBVQFdAUEBxwAAACuWwAAHAAEB3QFVAXWBVQFVAV0BQQHHAAAALBbAACMAIQC1AKUApYPlALUApQChAKMAAAAs1sAABwBRA9UC1QL9gtUC1QLVAtEDxwBAAG0WwAADAkECXQLdA32BXQFdAd0CQQJDAkAALVbAAAMCOwHLACkArYCpAKkCjQJ5A8MAAAAtlsAAFwFRAVcA7wKXgmcB5wAXAFEAhwEAAS5WwAALAIkAZQPRAkmCSQJRAmUDyQBDAIAAL1bAAAMCNwLXAh8BF4DXAR8CFwI3AscCAAGvlsAAAwJBAX0BVQFTgFMAcwFTAVEBQwJAAC/W4AATADkBxQABADWB1QFdAVUBVQF1AcAAMJbAABMA0QI9A9UAEYLFAh0BJQD1AQ0CAAIxFsAAIwAxAfUBbQFtgW0B9QA1AjED4wAAADFWwAIDAjkC7QGtAb2A7QCtAa0BuQLDAgAAMZbAAAMAaQHhATkBE4HpASUBEQEFA9kAAAAx1tACFQE1ANUANQHVggECHQLVAvUCFQIAATMWwAADACEB/wF3AXeB9wF3AX8BYQHDAAAANJbAACMBLwCvAH8BL4IvAr8CLwJvAKMBAAA01sAAIQP9AD0AvQC9gP0AvQC9Ab0BIQHAADbWwAIDAjEC9QL9AfWA9QD9AfUC8QLDAgAAN1bAAAsAQQB/APECX4IfAt8BXwFfAvMCQAI3lsAAAwK5Ar0CvQG9gP0AvQG9ArkCgwKAADfWwAATAlkBbQB9AmGD5QBpAPUAzQFnAgAAOFbAACMAIQF/AX8A/wD/gH8BfwH/AGMAoAA4lsACWwHRAH0DwQA9gn0C/QF9Af0CKwJAADlWwABXAlcCbwKnAt+B0QGvAR8BXwBDAEAAOZbAAAUCNQH/Af8A/4D/AP8B/wH3AcUCAAA51sAAAwBxANUA9QLagvsD2QDRAPUAwwDAADoW4AEtAK0CrQL9AK2DrQC9Aq0C7QKhAIAAOlbAAFMAWQP9AtUC3YPVAtUC/QLVA9EAQAB61sAAAQB9AT0AvQA5gLEAfQA9AX0BIQDAADsWwAIDAjEC9QH1AfWA8QD1AfUC8QPDAgAAO5bAACMCEQI1AP0CtYO1AL0AtQLRAiMCAAA9VsAAFQI9AfUAfQK1AcGAPQHdAt0C3QOAAT2WwAEFgjWB94H1gPHA+4D7gP+B+4HLggAAPhbAAAIACgAaACIAQgICAgICP8HCAAIAAgA+VsACCQMRAKEAXwCAALQABAJEAj/BxAAAAD6W6AAqACoAKgGqAS8AKgIqAjoB6gAqACgAPtbAAAAAUQBVANUA1QBVAlUCVQHfAEAAQAB/FsAAAABPAFUA1QFVAFUCVQJVAdcAUABAAH+WwAIKAxIAo4BaAYIBFAA0AEQCP4PEAAAAP9bQAREBVQDVAH0BV4BVAlUCdQHVAFEAQAAAVwAAKQEpAS/B6QEpAQAANAJEAj+BxAAAAACXAAAAgF+AVYFVgF/CVYJVgnWB34BAgEAAARcgAT+BKoC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/g8QAP4GkAVWDAAA6lwAAPgDAAL+AwAC+AfAAKYPkgiwCMYPiADtXPgDAAL+AwAC+AMAAO4PoAK+AqAK7AcAAPBcAAD4B/8HAAT8BwAAJAVXBdoPVgVSBRAE9lwAAAAO/ARcBVwHXgVcBVwFXAFcCUAHAAD7XAAA+AP+A/gDAAAoBYwFygKIAi4FaAQAAANdAADwA/4D8AMAAFQDxAD+B8QAVAFEAgAAB10ACXwFGAFYCVgJXA9YAVgBWAUYBXwJAAAOXfgHAAL+AwAC+AMAALQDrAKuCzQI9AcgABRdQAAsAOgPWAVYBV4F+AdYBVgFWAVcBQAEFl0ADP4DDAisCqwKrgrsDqwKrAqsCq4KCAgXXQAAAAD2DxQAVAZ2BtYHdAZ0BhQI9gcAACldAAAMDOwDqAnoDw4ACAjoB6gCqArsBwAALV0IAWsBWgHKB0oBSwECDPoDSgDGD0cAAABKXQAA8AP8A/ADDADsBgwB/A8MAWwCqgQABEtd/AMAAv4DAALwBf4Dyg+qCq4KqgruDwAATF0gAOwPKAUoBegPDgDIDCgCqAEoBqwIYABQXQAA5g8cANwJXAn+D1wNXA2MCPwHBggABmldEACWD/QA9AD0B/QF9gX0BfQH9AiWDxAAi10AAAAA8Af+A/AJ/ARcDV4DXAtcCUAHAAC6XSAAkwCqAqoEsgcHAP4FrgWuAa4F/wUACM1dIAl8C3gFeAV4Cw4A+ATYA/gD3AbQBvAC3V0ACAAM/AMAAAAAAAD4BwAAAAAAAPwPAADeXQAAcAgABv4BIAAAAP4HAABwAAAA/g8AAOFdAAhECMgHAAT4CAQLcAiMCSAK2AgECwAI4l0AAAAF+wWoA6oD/Q+oAaoDrgX9BQAFAADjXQAAAAn+BagFqgP8D6gBqAOsBfoFAAkAAOVdAAQEBAQEBAQEBPwHBAQEBAQEBAQABAAA5l0AAAgMCAPICHwISghICMgPSAhICEgICAjnXQQCBAL8AwQBAAEEAHwERAhECEQMxAMAAOhdAAAAAP4PkgSSBJIEkgSSBJIE8gUCBAAA6V0EAgQC/AEECQAE/AMEAHQABAD8DwAIAAbrXQAFhAR0BIQEBAT8BwQFhAR0BIQEBAUAAO5dgAioBKoDrgioCfgJqA+uCaoJqAmACAAA8V0AAAAA5AckCCQIJAgkCCQIJAh8CAAHAAHyXQAA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dAbUBQYIVAr0C1QKVAoAALVeAAz8AwQAVAD0B9YC1AfUCtQK9AtUCFQEtl4ADvwBBAQkByQA9A6mAKQO9AAkAiQMAAC3XgAG/gECBKoCqguqCPsHqgKqBvoFIgkAALheAA78AQQA9A/0A/QD9g/0A/QL9AukDwQAwV4ADPwDBAj8B6wGrAL+CwQA9AsECPQHAADDXgAM/AMECEwF/ANOAUQB3AdsCWQJFAUAAMleAAz8AwQIdAV0A/QPdgH0D3QD9AVUCAAAyl4ADPwDBAj0D7QItAb2DAQA/A8MAPwHAADTXgAM/AMEAPQLvAu8D/YDBAD8DwwE/AMAANZeAAT+A4IAlgiOBmYHvwZiBW4FRgKeAIIA314AB/wABAL0A7QDtAe2A/YHBAb8AawE/APgXgAM/AMMAOQPvAKmC+4PRAj0BSQD5AwAAOJeAAz8A0QALAusCn4ERANsBfQHtAkUAAAA414ABv4BAgjqBfoF+wX7AfoB+gPqA+oFIgTzXgAAgA98AAQLfA/+DyQEdA10CXQDdAUAAPZeBAi0BKwDZAQABfQJBAkECfwJJAkiCSAJ916ECDQHrAVECAAKJAokCvwLJAoiCiAKAAD6XgIIcgwuA+IECAWqCaoJ/wuqCaoJvgkICf9eAAAQABAA/g8QBBAEEAQQBP4PEAAQAAAAAF9ACEQIRAb8AUQARABEAEQA/A9EAEQAQAABX5AIkAiQBMwDiwCIAIgAigDqD4wAiACQAAJfAAAACR4FqgMqASoBKgEqAaoPLgEgAQABA18ECSQJJAW0AywBJgEkASwBvA8kAUQBBAEEX0AJVAlUBVQDVAF8AVQBVAFUD1QBVAFAAQpfAAl6CTgFPgN4AXoBEAEsAbYPNAFMAQQBD18ICEgESATIB0gESAQIAn4AiAMKBAoICAYTXwAAAADyAJIAkgCSAJIIkgiSCJ4HgAAAABVfAADEAKQIpAikCLwHAAAAAAAA/A8AAAAAF18AAIgI6AioBvwBqACoAPwPqACoBLgDAAAYXwAB5AikCKQIvAcAAAAH+AQEBIAEAAcACBtf8giSCB4HQAD8ByAIEAj/CRAICAn4CAAGH18AAAAEyASqAqwCqAH4D6gArASqBLgDAAAgXwAA8giSCJ4HAABACP4PQATQBEgBRgZACCVfBAHkCKQIvAigBxADzAgICPgPCADIAAgD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iAAACqIJcgQqA+YIIg7gAQAAbWKIAIgI/weIAEAIAghCDv4JQghCDv4JAAhuYggBiAj+D4gAIAhQBE4DwABCCE4I8AdgAG9imACYCP4PWAAACPgPAAgACP8PIAggCCAIcGKIAIgI/g+IAEAIEATQAz4AkAcWCBAIEAZxYogAiAj+D0gAAAf8AMQEBAU8A5AEcAgAAHNiiACIDP4DiAgADvwBZASkBSQCpAVkCAAIdmKAAIgI/g9IAAAISARIA/4ASANIBEgIAAB5YogAiAj+D4gAAAD+DyAEAAD+ByAIGAgQBnxiAAGIDPwDiAgADPwDBAD0BxQIFAn0CAAEfmKIAIgI/g9IAAAIEAQ+AtADEgXUCBQIEAZ/YgAAEAQQA/QABAqkCvQHrAIMAuQAIAMQBIBiiACICP4PSAAACGgEqAU+AigF6AQoCAAAhGKIAIgI/g9IAAAIeAgABP4EAAKMAVAAAACKYoAAiAj+B0gAAAD8B0QIRAh8CEQIRAj8CJFigACICP4HAAD8BwICAgD8DwQABAT8AwAAkmKIAIgI/w9IAAAAIggqCOoPNgCmAGIAAACTYoAAiAj+D0gAAA78AQQA/A8CAP4AAg8ACJViiACICP4HSAAACN4EQgVCAt4FUAgICAAAlmKIAIgI/g9IAEgAAAEiAUwBAAH+D4AAgACXYgAAiACICP4HSAAADOgDLgAoAOgHCAgABphiiACICP4HSAAADv4BIgAiACIA4g8iACIAmmKAAIgI/g9IAEAIBASkA3wA5AckCCQIIASbYgAAiAj+B0gAAA//APgHAAn4CA4K+AkABJxiiACICP4PSAAADIgDfgioBSgC6AUoCAgInmIICYgI/g+IAAAM/ANEAEQAxAFEAnwMAAigYogAiAj+D0gAAAD8DwQIFAvkCLQJBAoACKFigACICP4PSAAAANgHhAiCCEQICAgwBiAAomKIAIgI/g9IAEAAEADIBycIJQnICBAGEACkYogAiAj+B0gAAAz4A0gASgBKAEgA+AAAAKViiAiICP4PSAAAAP4PIgDyDDIDMgXuBAAIq2IIAYgM/gOICAAO+AHIBX4GSAXIBFgIAACsYoAAiAj+D0gAAACwD6wEogSgBKQEmA8gALFikACQCPwHUAAAALAHrgioCOgJCAn4CAAGtWKIAIgI/g9IAAAA/A8kBCIAPgziByIIIAa5YogAiAj+D4gAQAQIAkgB/g/IAEgDSAQAALxigACICP4HiAAAAPwBpACkAPwPpACkAPwBvWKIAIgI/gcIAOAPkASQBP4HkASQBPAPAADCYgAAkAj8B0AA6AyoAv4BqAD+D6gAuAcAAMRiiACICP4PiAAIAIAIiAiKCPoPiAiICAgIxWKIAIgI/g9IAAAI/AkkCSQJJAkkCfwJAAjGYogAiAj+B4gAAAz8AyIAogDiDyIBIgIAAMdigACICP4HSAAAAP4DIgKqCiIKIgb+AyACyWKAAIgI/g9IAAAEKATIBQoECAfoBAgEAADLYgAAiAj+B0gAAA/+AMgHAAn+CggK+AkABMxiCAGICP4HiAACACwBIAH+DyABLAEiAQAAzWIIAYgI/geIAAAA+A+IBI4EigSIBPgPAADQYogAiAj8B0gAAAi8BKQCpAGkCKQIvAcAANJiiABICP8PSAAAAP4PkgSSBJIEkgTyBAIE02KIAIgI/g9IAAgBgADkD1wERAREBMQPAADUYogAiAj+D0gAAAyIA34IqAUqAqoFaggICNZigACICP4HiAAgAJAAzgdICOgLSAjoCwgI12IAAIgI/g8AADgD5gIwCxAF8AMeCPAHAADYYoAAiAj+D0AAEADIAy4BKAHoCQgI+AcAANligACICP4HSAAAALwHIAT+ByAEIAS8DwAA2mIAARgJ/geYAAAImATUA5IAkADUD5gAoADbYoAAiAj/B0gAAACiD5oEhgSiBKIEngcAANxiAACUDJQC/AGSAAMAKAEqAf4PKgEqAQAB3WKIAIgI/gdIAEABFAFUAfwPVAFUAQQBAADfYoAAiAj+D0gAAAT+AwABvAwAAsABPgEADuBigABICP4HYAD+DIgDcAT8CQQI/AsACoAJ4WKIAIgI/g9IAAAO+AEIBIgHbgQIBQgFCA7iYoAAiAj/D4gAAA6QAX4MEATyB5QIVAgQBONigACQCPwHkAAABOgCuAqsCOgPiACIAggE5WKAAIgI/gdIAAAM/gOSAJIA/g+SAJII/gfmYoAAiAj+B4gAAASSBJYEkASYBJYEEAQAAOdiCAGICP4PiACAABgASAhICMoPSABYAAAA6GKAAIgI/geIAAACHAnQBH4FUALUBVQIEAjpYogAiAj+D0gAAAKkApwC1A+cAqQCJAIAAOxigABICP4PSAAAAJIPkgj+CJIIkgiRDxAA7WKAAIgI/g9IAAAEUATQBxAE/AEQBhQMAADvYoAAiAj/D0gAAAnSCCIK+gsmCNIIEgkAAPFigACICP4PSAAACIgE/gKIAIgA/gKIBIAI82KgAKgCagJsC3gL7gcoAygDbgKoAqAAAAD0YgABiAj+B4gAIAgYCSQJ4g8kCQgJMAgAAPdiAAEQCfwHkAAAACgBqAP8CqgKuAqoBiQA/GIAAQgJ/gfIAAAIiQT6A4gAiAD8D4sAgAD+YogAiAj+B0gAAACYD4QEogSiBKQEiAcwAP9iCAHIAfgB/AX6BfoD+gH8AfgB+AGIAQgBAWOQAJAI/AdQAAAAqAKoArwIqAjoB6gAIAACY4AAiAj+D0gAAAgkCSQJvg8kCSQJIAkAAAdjiABICP4PSAAAAN4HZAVkBWQFYgXiBxgACWMIAQgN/gMICEAIXAjEBXcGRAPEBFwIAAAOYwABEAn8B9AAAACoArgDrAqoCrgKqAagABFjgACICP4PSAAACYgE/gMAAP4HQAicCIQGFmOAAEgI/g9AAAQAVARUC0YJ1AhUCAQGAAAZY4gCSgIsArgKqgrsB6gCiAI+AkoCSAIAABpjAAAUAtQD/gOUC4AHtAOeA4QDPANAAyACH2MAAQgJ/gfIAAAIqAiIBv4BiAOoBIgIAAAgYwAAiAj+B0gAAAikBKYDvAC0D8wIrAiABCFjiAGICP4HSAAABC4FIAU+BSAFKAXmDwAAI2OAAIgI/g9IABAAWAlWCfQHXAFUAfABQAAkYwAAiAj+B0gAAAhEBEwDNgAkAFwPRABEACVjAACICP8HAACWAtICsgKaAtIPkgKWAgACKGOAAIgI/gdIAEAJLAUrA+gDKgMuBSgJAAgqYwAAiAz/AwAIkgb+AZII/gf8DwIA/gMAACtjgACICP4HSAAgCBwJYAn+DyAJHAkgCUAAL2OAAIgM/wOICAAO/gHCD1IE0gVSAVIOAAg6YwAAiAj/D0gAAgw+A+IEAAgiCf4JIgkiCT1jgACICP4HQAAQCPgIlASWAvQBnAeUCPAIQmNIAEgI/g8oACAAqge+BKoEqgS6BKIHIgBFY4AAiAj8B0gA4A+kArQC9A+sAqwK5AcAAEZjgACICP8HAAD+DwIEUgT6BVIEAgT+DwAASWOAAIgI/g9IAAAMvAMkBOQPpAikCLwIAAhMYwAAiAz+AwAIvAakAbwIAAf4AQAI/gcAAE1jiACICP4PSAAAAX4BagFqAeoPagF+AQABTmMIAQgJ/geIAAAA4g+sAqACvAKgCuwPAABPY4gASAj+D0gAAAS+BKoEqgeqBKoEvgQABFBjiACICP4HSAAAAO4PqgKqAqoKqgruDwAAVWMIAYgI/geIAAAA6A+oAqgC/g+oAqwK7AdcY4gASAz+AwAIvASsBawG/gSsBqwFvAgABF5jgACICP4PSAAACJQElgLUAZQIlgw0AwAAX2OAAIgI/gdIAAAI4AkuBCoCqgEqBC4I4AthY4AAiAj+D4gAIASYBSQEogUkBAgH0AQAAGJjiAz+A0AIEAj4BJQClgH0AZwClAT0BIAIY2MAAQgJ/geIAAAG/ASEBpYEhAa8CIAHAABnY4AASAj/B0gAAABqAr4Cqw+qAuoCqgIAAGhjiACICP4HSAAQAEwHUgV6BVIFRAVIB1AAbmNAAEgI/g9IAAAH/gAyB7IE8gSyBL4HAAByYwABEAn8D5AABALUB3AJXA1QDVQO1AhAA3ZjAACICP4HCABACfQJVAn8D1QJ8glQAQAAd2OAAIgM/wNICAIIqgaqBKoE/w+qCvoKIgh6YwABEAn8BxAAQAQoARgJTA9YASgBSA1AAHtjgACICP4PSABABwgAJAcqCCIJZAgoAwgEgGMAAIgI/gcAAPwPFAD0DwAAFA7qAQgGOAiCY8AARAb/AQAM/gMCAIIPggT7BJIEkg8CAINjgABECP8HBABgALUHtQD1D7UAvwTgAwAAiGOAAIgI/gfIAGAIaAikBKoHogS6BmoFAAiJY4gI/gdIAAAC+AKoAqgCrg+sAqwC/AIEAoxjAAAcAs0C/wL8Cv4H/AL8Av8CjQKcAgAAj2MAAQgJ/gcYAIwCqgLoA6gCqAqICPgHAACQY4gAiAj+D0gAAADQD0gFBgVEBFwFxA8AAJJjiACICP4PSABAAAgBKAHWDvwHKAEoAQAAlmMAAIgI/geIAAAA5A8UAMYIdAWkA+QEJAiYY4AAiAj+BwAA/g8KAOoOigjqD4oI7g4AAJljAAEICf4HiAAAAqwKpArqB6ICqgLqA4AAm2OAAJAI/AcAACgFvgcoBQAA/A9AAMAAAACgY4AAiAj+D4gAAAT0ApQIlgeUAJQC9AIEBKFjgACICP4HSAAABJQChAHUD4IBsgKKBAAAomMAAQgJ/gfAAAwEpAKUAcQPlAGkAqwEAAClY4AAiAj+B0gAAAikCqwLpgSkBrQFpAigAKdjAAGICP4PSAAMCKQIlAiGD5QIpAgMCAAAqGNIAEgI/g9AADAA/A+qBKgE/geoBKgEAASpY4AAkAj8B1AAAADoA7gCrALqB6gKuAroC6pjiABICP4PSAAAANQHXgVUBVQFXgXUBwAAsGMAAJQI/AeyADgG5gH8AxAIkgj+B5IAgACyYwgBCAn+BwgAAAG+A+oFqgSqAqoIvgcAALdjAACICP4HSAACDvgBTgcAAP4PAgD+AwAAuGMAARgJ/geYAAAC8ANSA1QD8A9cA1ID8AO6YwAAiAj+B0gAQABYCrwKWgkYBTwEWAKQAMljgACICPwHSAAACXQFHANcD3wDFAU0CRAAzWOAAEgI/g8oAAAIXAl8BdwDXgF8BVwFXAjPY0AARAT/AyQAAAD0D5QElwT0B5QElwT0D9BjAAEICf4HiAAADL4CqgSqD6oKqgq+CoAI0mMAAEQE/wNEAAAA6g+qBAoE/gcJBOkPAADWY4gAiAj+B0gAAATsB2wFbAVsBWwF7A8gAtpjBAGEDP8HxAAABt8DVQlVBVUDVQlfBwAA22OAAIgI/geIAAgIeAk2BZQDPANQBXAJAAjhYwAAkA78AQAM/AM0CLQK9Aq0D7QKvAoACONjAACICP4HQAAcD7AAsA/+ALAPsAC8DwAA6WOAAIgI/g9IAAAA/gdoBUAFfgVoBeQHFADqY0AAiAj+B0AAEgH+D0IAGgwAA/4AAAM4DO1jAAEICf4HiAAAAP4G6gSqBaoIqgi+BwAA7mMgAEgI/gdIAAAC+gK6AroC+g+6AroC+gL0Y4AAiAj+D4gAAgRWAvIJ1gbSBNkHVQhACPpjiACICP4HSADAAIwOpASsBOwHogSyBKoO/WMAAIgM/wNACB4IwAteCEAHVgjUCwQIAAQAZIAAiAj+B0AAEAC4BHYENAV8CbQKsACAAAFkAABICP4HAADyD0IAWAeqAtoCAgv+BwAAAmRAAIgI/g9IAAAIqgqYC94EmAaqBaoIgAAFZAAAiAj+B0AAGgj8BTgEugc4CO4JCggABg1kiACICP4PSAAACOwF7APsAewB7AXsCQAID2SAAFAI/AeQAAAAeAN4A3gBfgl4CXwHeAETZIAAiAz+A0gIAAzVA1YIfAlUD1cJVAkAABRkgACICP4HSAAAAKYJWglSCdYPWg1WD9IPFmQAAAgJ/geIAAACVArECqYKng+MCoQKAAAcZIgI/gdIAAAIvAi0CaAG/gSgBrQJvAgACB5kgACECP8HJACAD1oAWgdbBVoHWgDCDwAAKmTAAEgI/gdIAAAH/AB0BnUF9gV0BXQHFAAsZAAAEA78AYAM+AN+CfgHAADeDUICngUgCC1kAACICP4HSABAAG4HVgVcBWQFTgdEAAQANmRAAEgI/A8gAJAPaAB4B3QFcgV0BWgHEAA6ZAABBA3/B4QADAj/BasDqgH/BasDqg6CAERkAACIDPwDKAiABLwGvAG8BbwGvAakCQAARmSAAIgI/gdAABwFVA1cC9QJXAVUBVwJAABHZIAAiAj+B0gAAAasBKQE6geiBKoEqg4AAEpkAABICP4POALIATgBMAD+D6gE/gesBAAEVGQAAIgI/geAAIgCBAK0Au4OxAIEArQCgABYZIAAiAj+BwgA4A8UAFwH9gVcBxQI9AcAAGdkAABICP4PSABMAOgHaAVuBegHaAVsBQAAaWQADPwDBAC0A7QLtguEB7QDtAN0A3QDVAJ4ZIAASAj+D0gAAAl0CXYH9AF0A3YFdAkECXlkAAFEA3wD/AN+C/wL/A9+AvwCfANEAwABg2QAAvwD/AP+C/wLvAfYA9YDUgN2A1QCgAKHZAAAiAf+APAPXgD8B3AA9Ac6BsUBPAYABJBkkACQCPwHkAAYCPwL2AbeBtgC/g+YAgACkWSAAJAI/AcAAJgD/AvYC9wH2AP8AxgDAACSZIgI/gdIABAA9A++ArQK/g8QCO4GiAN4DJVkAACQCPwHAAD8DVgB/AUAAPgPJADkDyQAnmRICP4HWAAACPQK9Ar0CvYP9Ar0CvQKEAikZEAARAz/BwAA8g+/AtoPEAg4BMcDfAwAAKVkAAAICfwHCACgC7wK5A5ACygF/AeoCQAAqWSAAIQE/wNEAAAE+gFWCVMPVgH6ATIMAACrZAABkAj8B1AAAA38ASoB6A0oAegNKAHoDaxkAACICP4HSAACA9YPHgM2AK4DrQcoCwAKrWSAAIgI/gdYANQAVAe8BbwHlAW6BdIHkACuZIAAhA7/AWAE4Ae/BrUG9Q91BHUD/wVgBLBkAACICP4HoABOCfYFVgVAAU4F9gVWBUAJsmRAAEgI/g9IAAIJeAVuA+gBbgN4BWoJAAi1ZAAAiAj+B4gAAARcBd4FQA9cBU4FXAUAALxkAABIB/4AAA78ASwB3AesA38CpAMVBAADv2QAAIgI/gcIAOgMtAL0BBIA8gy0AuQECAjBZEAASAj+BwAAtAxkAwQA+gdUBfwHVAUABMJkAACICP4HCACcB8wFnAW8B5wFzAWYBwAAxWQAAIgI/gdAAHwEzAf8B/4H/AfMB3wEAATHZAAASAj+ByAAvgL6Ar4Cug++AvoCvgIAAMpkQAT8BPwH/gf8DvgPkAfuBqIG5gaoBAgBy2SAAEgI/gdIAAAAmgf8BdgF3gfYBf4FigfNZAAAkAz8AxAIwAW8BfQDlA/0A7wF4AkAAM5kFAA8Ar4DuAPOC7wLhA+oA7YDlAMsA0QC0mQAAYgI/geIAAgOxAGSB9oF8gO0CcQPAADUZIAAiAj+D0gAGA74Aa4MvA/MD7wPyA8AANpkgABICP4PAAT4AxgA2AX+A3wPbAFsBgAE4GQAAIgI/gcIAGAM1APkAr4CvAK8AuwPBADmZAAACA3+AwgJLAmUAdQJvg+0AfQBHA0AAOxkAACICPwHAABeDdQDVAwAAywE9A88CWQI9GSAAIgO/gEADPwDRAj0C/QL9gP0C9QLAAD6ZAAAiAz+A8AIdgfKDO4HCgBuBqoKrgoAAP5kAAGICP4HCADCCH4K3gdeB14H/gvCCgAIAGVUAMwCXgJMA+AL5gvUB8IDSANeAswCVAAPZQAAmAz+AwAI6AdmAvQPAADeB9QL9AoAABJliAj+B0gADAjeC14IXAZMAV4EXgisCyAAFGUAAIgI/gcAAP4H9gR+A/AH7gP2CP4HAAAYZQAAiAj+B0gE+APsD/wJxgH8B+wF/AkAABxlQAAkBP8DIACLD34B+gJ7BvoBegT7ByAAHWUAAJAI/AdQAMQD/AL8DzwA/AP8A+QHIAIkZQAAAABICP4P/gv0B/4O9A+uBPoHqAQAAC9lCAgoBGgEqAQoAz4CKAOoBGgEKAQICAAANmUAAPwDAAEAAf4PAAAwBG4EiAPoAhgECAg5ZQAA5AEkAiQBfAVgDDAEzgIIAegCGAQICDtlBAEEAfwBBAlkCRAEbgKIA4gCeAQICAAAPmUACAgG+AEqCMgHIAAQDO4CiAN4BAgIAAA/ZQQE9AMEAvwDJAJkCDAE7gIIA+gEGAgACEVlCADID0gEfgTID2AIPATKAogDeAQICAAASGUICKgEigKMAygEQAAwDM4CiAN4BAgIAABMZQAAkg+SBP4EkgSCDyAAFAzqAogDeAQICE9lQAD4AVYB9AVUBfQDYAkeBOUCxAM8BAQIUWUIAmgJCAn+D8gACglgCH4EiQPoAhgMAABWZQAEVALUAf4E1ATUA0AAfgaIAWgCGAYABFdlAAj8BVQFVAH8BWAAOAzMAogDeAQICAAAWGVQAlgJVAjyB0QAZAswCO4ECAPoBBgIAAhZZQACVAJUCd4P9AFYCTYIfASLA8gCOAwICFtlAADQBRgE1AQWA4gIMARuAogBeAIIDAAAXWUAAPYP0AH+D9AB9g8ACD4EyQPoBBgIAABeZQAA7g/gAX4CoAnuD0AIfgSIA+gEGAgAAGJlAAAIAvoDqgKqAv4PAAAwDO4CiAN4BAgIY2UAAOoPrwKqAq8KygcgABoMdQLEAzwEBAhmZQgC+ArYCtwO2AN4CmAI/gQIA/gECAgAAGxlRAD0A1YB1AkWDPQDMAhuBogB6AIYDAAIcGWgCKoKmAf+BJgHigggCD4EyQOIAngECAhyZQAA9A/0A/YCdAn0BwAA4Aw+AygD6AwACHRlQABcCDwIvg68CNwP2Aq2CrQKTAhECAAAdWUAAPoPDgP7Ag4J+gcQAD8MxAN8BgQIAAB3ZQAEvwKrAf8FqwW/A5gIPwTCA3ICDgwCBHhlCAl8C3wL/gV8BXwLYAkwBO4DeAQICAAAg2UAAF0JfgX/B1QDXgFoAOYDVgVcBWQFQASHZQAACAgICBgEaASIAgoBiAJoBBgECAgICIllIgQSDNIDVgFaAUsBSgFWAVYB0gcSABIAi2VkAGQPZAFUAVwP1gFUAVwPZAFkCWQHYACMZQgIaASOA3wCAAjUD/QHEAD+AxAEFg4AAI5lJAgkD6QAHAJUCVYPVAEsBSQApA8kAAAAkGWkCKwIrASsBZ4GwAKAAr4GrAWsCKwIoAiRZQAAJAT8AwAIKAbKATgCAAhECPwPRAgACJdlAAIQAiQBJAFIAQgBAAH+DwABgACAAAAAmWUMAKAD/g+gAKwAAAIkAUgBAAH+DwABAAGcZQAEWANUCPIPVAAEAyAAbAEAAf4PgAAAAJ9lQADIA3wF+AT4BXwFAAQoAIAA/weAAAAApGUAAAAO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rAL8BAQEAAB+Z4gBSAD/B0gAgAQ4BIYHYAQBBI4FMAYAAH9nCAOIAP4PiAAADPwDZAikBSQGpAVkCAAAgWeIA0gA/g9IAAAMhAN8CIQFNAIsBeAIAAiEZ4gBSAD+D0gAAACcAWoBCAnICQgM+AMAAIlniANIAP4PSACIAAAIRAhECPwPRAhECEQIkGeIA0gA/w9IAIgAAAz8AyIAIgDiDyIAIACVZ4gDSAD+D2gAgAg4BIgDfgDoBwgIOAgABpdnAACIAUgA/w8oACgCgAFIAP8PaACIAwABmmeIA0gA/w9IAKAIEARuBIgDyAI4BAgIAACcZwAAgAS+BKoCqgGqAf4PqgGqAr4EgAQAAJ1niAFIAP8PSACICCAEqAQoBT4CKAXoBAgInmeAAUgA/wdIAAAH/gAABIADfgCAAwAEAACgZ4gDSAD+D0gAAAEkARwBBgGEDzwBIAEQAaJniANIAP4PSAAAAPwPBAgUC+QItAkECgAIo2cAAAQBtACUBFQEfglUClQKlAq0AAQBAACqZ4gDSAD/D0AAEADIByQIIwkkCcgIEAYQAKtngAFIAP4PKABAD/wABAb0AQQC/AcADAAAr2eIAUgA/g9IAEAAEA+QBP4EkASQBJAHEAC2ZwAApAiUBI4ChAHcD4ABvAKkAqQEvAQABLdngAFIAP4PSAAADv4BCAzwA/wPBAT8DwAAxGeAAUgA/g8oAAAA9A8UAJQBfACUCRQI9AfPZwgBiAD+D0gAAAD4D4gEjgSKBIgE+A8AANBnAACEBIQEvgKsAewHrACsAb4ChASEBAAA0WcIAYgA/g9IAAAA/g+IBIgEiAT+DwgAAADSZwQJZQkRBRIDBAPEDx8DJAMkBSQJFAkAANNniASqBKoCgAKkAbQPjgGEAvwCwATABLAE1GcACVAJVAU0A3wD3A90AxwDFAU0CRAJAADYZ4gBSAD+DygAKAGAAPQPTAREBEQExA8EANxnCAOIAP4PSAAAAPwPJAkkCSQJJAnkCQQI4GcIA4gA/g9IAAAAWABICEoIzA9IAFgAAADlZwAASAgoCKgPWA1cDUgNWA2oDygISAgAAOxnAAAECPQEtAKUAf4PlAG0ApQE9AQECAAA72eIA0gA/g9IAAAA9AMUAfQJBAj8BwQAAADxZwAAiANIAP8PyAAICQAIigj6D4wIiAgICPNngANIAP4PAAD8CQIF+gIAAPwPBAD8AwAA9GegBL4EoAK/AqQBgA+fAaQCpAKkBKIEkAT7ZwAAJAgUCNQPrAquCqQKrArUDxQIJAgAAP9niAFIAP4PSAAAAOgDKAAqAPwPKAAoAugBA2iIAUgA/w9IAAAP/AAUDvQBUghSCNIHAAAEaAAEUARcAlAB0gDUD9AAUAFYAlQCUAQABAVoAAOIAP4PAAT+A0II/gdAAP4HQgD+D0AAB2iIAUgA/g9IAIgEIAKkCSQI5A8kAKQBIAYIaIgBSAD+DygAQAgQBFAEfgTIAyoFqgigBgtokANQAP8PUAAEBnwBRwjkD0QARAMEBAAAD2iIAUgA/g9IAEAEEgSWBJAEmASWBBAEAAARaAADiAD+D0gAAAbkARwDQADQCRAI/gcQABNoiANIAP4PQAAQCAgJJAniDyQJCAkwCAAAFmiIAUgA/g9oAPoPigV+BAoEfgSKBPoPAAAXaAQJdAlUBVQFfAPUD1QBfANUBVQFdAkECSFoiAFIAP8PSAAICGAEGATYAg4ByAIoBEgIKmiIA0gA/g9oAIAEEAROA8gA/g/IAUgCQAQ3aAgBiAD+D0gAAAFKAUoB+A9IAU4BCAEAADhoiAFIAP8PSACICCAEaAWYBE4CKAOoBIgIOWiIA0gA/w9IAAAA/g9SCNIIUgFSBn4FAAk8aMQBJAD/DwQATADkD2cEWwRaBGYE4gdAAD1oEARUAlQB3g9UAVQJEAT+AhAD0gQUCAAGPmhACGQJFAUEBTwDBg9EATwDBAUUBSQJAAhCaIgDSAD+D0gAAAgkCSQJvg8kCSQJIAkAAENogANIAP4PQAAMCYAE/gMAAP4HQAicCAQFRWiIA0gA/g8IACAO+AGWB1QIXArQCRAIAARGaIgDSAD+DygAQAD8DwQIVAr0C1QKVAoACEhoAACUCZQFtAVUA1YPVAF0A5QFlAUUCQAITGgAAAAJeAVYBVgD3g9cAVwDXAV8BQQJAABQaAgDiAD+DwAA/A8EANQDVALUAwQI/AcAAFFokAmYBV4FfgMWAYYPVgFaA1oFsAWACQAAU2jEASQA/w8kAAAE/QUlBSUFJQUlBf0FAQBcaIgDSAD/D0gAyghCCMQFcQZWAkAF3ARCCGNoiANIAP8PSAACBCwFIAU/BSAFKAXmDwAAZWiIAUgA/g8oAIAIVAQ0AxwAFAAyD1IAgABmaIgBSAD+D0gAAAF8AQIBkA8+AUgBRgEkAGhooASUBJACvgKAAagPpgGWApQCjASEBAAAaWjEASQA/wcUAAAO/AEEBCUE9QckBCQEAAB2aIABSAD+BwgA4g9SAVoB+g9WAVIJ8gcAAH9oiAFIAP4HSAAAAX4BagFqAeoHagF+AQABgWhMCWAJEgVYA0IDMg8OAUIDQgU+BQwJMAmFaBABkAD8D5AAoATYA6wCqALoC6gK6AeAAoZoAAOIAP4PSAAACSgN/gMAAPwPBAD8AwAAk2gIA4gA/g9IAAAAVAFEAcYPdAFEAUQBAACXaIgDSAD+DwAA/AisBqwG/AWsCKwI/AgAAJ1oAAAgAPwPAgD4AwAAqAauAJQPtACsAqQEomiEAUQA/g8kAAQA8QdWAVABXgFQBfYHAACmaAAAEgmKBF8ERgVqAkgCSgHfAEYACgAQAKdoiAFIAP4HKAAgAKoHvgSqBKoEugSiBwAAqGhACCoJGgV+BRkDqg8AAR4DQAVABX8JAAmtaIADSAD+D0gAQApYCR4FygaYBp4JqAgACK9oiAFIAP4PSAAABOoErAL4D6gArgS4AwAAsGgAA4gA/w9IAIAM6AOIAOgP/gQIB+oIIASzaIABSAD+D0gAAAy0AywApw8kALQPIAQAALVoAAA0CAwE3gNMAVQBQAJMAN4HDAgUCCQGtmiIA0gA/w9IAAAP/gAKAqoC6gdKCU4JAATAaAgBiAD+D0AAEAUIBSQEogQMBpAFUAQAAMRoRAlUBdQFzAPMAe4PzAHMA8wDzAVUBVQJyWiEA0QA/w8kAEAAngeqAKoA6w+qAL4EgAPLaIgBSAD+D2gAQAkIBf4FWAFYAf4BCA0AAM1okANQAP4PUAAAAPwPVAlUANQHfAkABQAA0miIAUgA/g9IAAAAbAI8Aq4PrAI8AmwCoADVaIQBRAD/D2QATAZEAVQE1wdUAEQBTAIAANhoAAD0DBQC/g8UAfQIYAQUAv4PFAL0DAAA2miAA0gA/g8ABP4Dkgj+BwAM/gOSCP4HAADfaIgBSAD/D0gAAAT8BKwCrAH+D6wBrAL8BOBoAAgYCQoFfAVYA94PWANYA34FCgUYCQAA42gIA4gA/g9IAIAIFAZUAP4PVABUBXwFEAjuaAAApASUAtQPjAKMBD4EjALUD5QBpAKABPFogANIAP4PSABACjQJ1AbeBJQGtAkUCAAA9WgAAMQBJAD/DyQAAAPfAPUH/wfVAF8DQAL6aIgBSAD+B0AAHAD8B/QHVgVUBWQFDAcAAAVpiANIAP4PCAAgALQHrAKuCywI5AcgAAAADWnIACgA/wcIAOAPBAT8BVwFXgVcBfwFBAQOaYgBSAD+DwAAMAD8D6oEqAT+B6gEqAQAABJpgAFIAP4PCAAgDf4DKAiACRwE5AN0BgwIHGmQA1AA/g8QAPAJOAk0BfIDNAM4BfgJEAgtaQAAkAD/DwAA/g8SAO4BAAD4D68C6A8AADBpgANIAP4PAAD8A1QC/A8AAP4PAgD+AwAAP2mAAVAA/AcAAKgA+A94BXgFfAX4D3gAgABKaRADkAD8D5AAAAj8B9QB1AXUA9QJ/AcAAFNpgAFIAP4DAAz+A0IAqgT6B6oEQgT+AwAMVGmAAUgA/g8AACwJfgkMB6ADHgVCCT4JAABaaQAAVAhMBl4DVATAD1QJTAleCUwI1AgACF5pAAOIAP4PQAAcCFQE3ANUAVwJVAlcB0AAY2nAASQA/w8UAIADfwDlD1UFVwVVBfUPBwBtaQgJagVsBXgDbgHoD2gBfgNsBWoFCAkAAHVpiANIAP8PCADiCaII7gj6C0IIkglyCgAAd2mAAUgA/g9IAAAAvA+oCoAKvgqkCqQPFAB8aYABSAD+DygAiAiqCpgH3gSYBqoFqggAAH1pAACkBKQEgAL8AdYH1AH8AYACrASiBAAAgmkAA4gA/g8AAPwHVAJ8CSAExAN8D0QIRASEaQADiAD/D0AAHgjACV4EQANOBtQLBAgABIZpgAFIAP4PCADwB7gC9A8WANYDBAjoBwgAlGkAA4gA/w8AAPwHVgJ8BwAA/A8EAPwDAACVaYgDSAD+DygADAGUD0QJJglECZQPLAMAAJtpgAFIAP4PKACACOwFvAOuD6wDbAUkBQAAnGmIAUgA/g8IAEAIXAbcAVYJVAlUCVQHAACoacQBJAD/DyAAggBKACYA9w+iAqoCqgIAAK5pAATiBOwErgKiAKAPsgCoAqYCqASiBAAAtGkAA4gA/g/IAAAAvA+iCpAKpA+cCoQKvA/LaQAAyAMoAP8PAAD8D74CvAL8A74K/AcQAs1pyAAoAP8HKAAIBugBfAd7BXwFdAV0BwAA0GmAAUgA/g8IAHwAVAhWB/wA1AdUCXwLAAjYaQgDiAD+D4gAAARWBVQA/A9UAlYFVAUAAP1piANIAP4PSAB6ANoP/wraCv8K2gr6DwAAAmrABOwE2gLAArwA1gfWAPwCiAL2BOAEAAAKaiQIFAl/CRQFUAVKAzYBQQM0BX8JFAkkCRFqiAdIAP8PSAGEASYJDA24Dw4BfgUQCQAAE2qAAUgA/g9oAAAIfAt8C/wFfgV8B3wJfAkZaogDSAD/D0gAHAVsAXwJbA98AWwFfAUABR5qAAOQAP4PAAD8BwQJ9ArUC1QJtAqECwAAH2qAAVAA/g9QAAAC9AL8AvYP9AL0AvQCEAIhaoABSAD+D2gAAAl0BXYD9AF0A3YFdAUECSNqhAFEAP8PRAAADSsDqgg+B2oCKwWiDAAAKWo4A7gA/Ae4ACgAgADsB7gHqAeoB6gHAAAqaogBSAD/D0gACAj6CV8FWgX6AV8FWgX6CTFqiANIAP4PAABeCToLjg0cBUIFegtCCV4JOWoAA4gA/w/IAOAItAq+DPQGAASQAP4PEABEagAAyAD+DwgA+gOqAqoC/g94BI4DeAwACEtqkANQAP4PEAAyD7IA8gf+BfIH0QCwDyAAWGqIAUgA/g8oAIAPWgFaB0oF3gZaAMoPAABZasABKAD+ByAA2gS6BboEtQS+B9oFEAQAAF9qiANIAP8PQADmDLgDtArfCKQHuAq0CKAEYWqAAUgA/g9IAAgEuAVsA+4KvAmsB6wBOAJraogBSAD/D0gAEgjyBX8FegX6AX8FcgXyCXFqgANIAP8PAAT8A0QErAdsBwQApAj0ByAAgGoAA4gA/w/IAHgIzAv8C/4L/AvMC/wLAACQaogBSAD/DygAiA98ACcH7gX2BeQF9AcEAJRqiANIAP8PQAAaB/wF2AXeB9gF/gWIBwAAomqAAUgA/g8IANgMuAL0BBYAxAyoAugEAAipagAByAH+B2gAeAXMAfwF/gfMAfwFhAUAAKxqAAOQAP4PAAAUBtQG9gN0C3YHVANUBAAAw2qAAUgA/gcAAP4HAgT+Bf4F/gX+Bf4FEgT7aoADSAD+DwgAfgkuC/4NAAVeBS4LXgkAAARrgAFIAP4PAAD+B+4E5gPwD+YD7gz+BwAACmsIA4gA/g+IATAB1A82D4APNg9UD3QJAAAga0AIMAgMBAoCiAF4AIgBCAJIBDgICAgAACFrAAAEBoQBCAhgCB4ECgPoAAgDSAQ4BAAIImsUBCQCxAE8AwQIMAQOA+gACAMoBBgIAAAjawAE/AMUABQA8gcCADAMDgPoAAgBOAYICCdrAAD8DwQFpATUBAQNYAweB/gACAN4DAgIMmuIAMQPogSQBJIE5AewDA4D+AAIAzgEAAg6awAACAn8BVgB/AUAATAMDgPoAAgDOAwIAD1rUAhYC1QI8gdUDQAIMAQOA+gACAM4BAgIPmsABKoCqgivB6oAogIwCA4G6AEIAzgMCAhHawAB/geqBKoFqgi+BwAAHA7KAQgCOAwAAElrJAStAv4H/AOuAf0EOAwHA+QADAMEBAAATGuAALwHrAW8B4QIvAewCA4G+AEIA3gMAABQawAA/gOCBNoFqgTaBQAMEAPuAAgDKAwYAFNrIAHsD6wHuAeoB+AMYAQcA/ABEALwDAAAYWsAAboPuweAB7sHmgcwAA8O5AEEA3wMAABiawAEAATwBwAEAAQABP4HIAQgBCAEIAQAAGNrAAQEBOQHBAQEBAQE/AdEBEQERAREBAAEZGsACPAPAAgACP4HIAQAAP4HIAggCBAIEAZlayAIIAu8CKAIIAggBP4HJAIkAqQBpAAgAGZrAAAQCNQHFATUB5QEEAT+ABAHFAgUCBAGZ2sACPAHAAT+ByACCApoCKgFPgIoBegECAhpa6AAoAV8CGAIIAUgBf4EJAKkASQApAAgAWprJAikCKQOlAiUCLwIhA+UCpQKpAqkCgAIb2sQANAHHATQBZAF3gWeBbQFFAT0B/AHEAByawgM6AMoAGwL6AdoAi4JfASsA7wEqAgoBnNrEA7QAVAE3ALQD9AAXgn0DFQDdAVUCRAEdGsADPwDBAhUCHQPFAiED1QK9Ao0CtQIAAB3awAM/AMECGwI/A5sCAQPbAr8CmwKpAgAAHhrAAh8B1QE1gc8BUAAPAe8APwPvACoBwAAeWsAAIQARAgkBFQEnAIUAZQAdAAUAAQAAAB7awAAxAhkBJwGFAH0AAQA/AdECCQINAgkBnxrwAAiCJ4EEgPyAAAARABEAP4PQgBCAEAAg2sAAMIIPgSSA3IAAAj4CIgG/gGIBvgIgAiJa8AAIgieBJIDcgAQAM4HqQLoCwgI+AcAAIprgABiCB4GkgFyBBAETgPIAP4PSAFIAkAEi2uAAOIIngSSA3IAAAioBP8EaANlBVUJQASWa0AAYgxeApIBcADkDwQE/AVuBWwF/AUEBJhrgABiCF4GkgFyCAIJqAUvBxgFXQsVC6AItGsAAPwPFAXkBBQNQAzeCEIHQgb+CWAIGAi1awAAAAL8D1ICUgIRCUAI3gVCAl4FoAgYCLdrAAz+A1UJVQk9B0AA4AheB0IG/gVgCAAAumsAAFIGVAHMD1MBAAjeBEIFQgJ+BeAEGAi8awAAbAxsA+4A7AcEAmAI3gRCA14DwAQACL9rAAf/APUOpQD1AqcEAASvAqECLwHoAgAEwGsAAHwJUglAB1QFPA1ACH4JQgb+CWAIAADBawAA/ATSBMAH1AQ8AkAI/gVCAv4FYAgAAMVrAABUATQL1goUB8QCEAjOBUIC3gVQCAAAy2sAACAA4Ak8BSQDpAF8CSQJJAf8ASABAADNawAAIADwAy4CogKqAqoKIgoiDv4DIAIAAM5rAABIAMQHcwJKAsoDegpKCkoO+gNCAkAAz2vAAMgC6AOmApQDlAPUA5QKlAr0B8QCwADSayABIgHqB2oFagX/B2oFag1qDeoHIgUAAdNrEAD4B7YFlAz0BwAAtA8sAKYPJAC0ByAI1GsAAAAA/g8gBCAEAAD+B0AIIAgQCBAHAADVawAAQAF+AUgBKAGADz4BSAFIAUQBJAEAANlrAABACn4L5AdkBVQDXgDkB2QKZAlQCUAE22sAACgBKAEoASQB/AckCaQIkgiSCJAIgAbhayQBJAH8ByQJoggQCMALfgpICkgKyAkIBOtrAADEBPwF7AXsA+4H7AvsCuwKfArECgAA72skASQB/AeSCIIIKApkChAJzgkQCswKAAQPbAAAAAj8ByQEIgQiBH4AogMiBCEIIgggBhFsAAAACPwHpASkBKQE5ASkAaQGvAiACAAGE2wIAPgBCgIIAgAI/g+SCJIE8gGSBp4IAAQUbCAAGABGAFUAVABUAFQAVADUAxQEBAgABBdsAAhYCUYFVAJUAtQF1ARUANQDFAwECAAEG2wQABgJhAUjAyoJKgmqB6oAKgHqAwoMAAYibAgAqAS2Bb4FfAd8BbwFvAUcAPwDBAwABiNsEAAYCUQFIwGqDyoBKgFqDSoA6gcCCAAGJ2wQAMgCxALeAtwP3ALcAtwCHAD8BwQIAAYobAgAUAlYC1YLXAVcB1wJXAkcAPwHBAgABi5sEAiICrYEXANcAlwEXAccCPwBDAYECAAG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AAQRcBAAJA8kAIAFvAT8DrwMvA78ArwEvAmAAh9wEQSmAwAAAgATDLoDOgP4DzoBuwe6A7oPLHAQDKIDhAA2BlQB/gcmAfIEbgVqAfoFAARMcAAAIghEBgQDdA7UDzYPhA92D1QPdA8AAFFwAAAiBqwBAATqA+oH+gXiAeoD+gXqBQAEY3AQACYPQAAXAk0DoAOcA7YL+gtcBxICQABrcAAIYAgYBAACgAF+AIABAAJABDgIAAgAAG1wAAACCEIEMgQCAsIBPgDCAAIDYgISBAAEb3BACHAEAAL+ARACBAAECAQI/AcEAAQAAABwcAQChAF0AA4I5AQkAgQB9AAEAWQCJAwAAHVwAAgACaoIKgQqAqoBKgIqBCoFvggACAAAdnBwBAAO/gEAARgFAAQgBCAE/gcgBCAEIAR4cAAAQAhICigJJAQWAtQBHAIkBKAJIAhACHxweAgABv4BEAEABjAAjgCICAgJCAz4AwAAfXAACAwJ0gQABAgD1gACAwgEDAXSCAAIAAB+cAAAmAiICGgECAIKAewACAMIBMgEGAgAAH9wOAgABv4BAAMIAPAHAAQABP4HAAQABPgPiXBwCAAG/gEAAjgIAgzyA5IAkgCSAPIBAACKcHAAAAz+AwACGAgwBA4C6AEIAygEGAgAAI5wAABACCgJpAQgBBgDxgEYAiAEpAUkCEAIknBAADAO/gEAARgKQAg4BAAE/gIAApgBIACVcDgIAAb+ARACAAjoByoAKgDoBwgICAYAAKtwOAgABv4BAAMIAEgEaAbaBUgEKAcIBAAArHBwCAAE/AMgAgAA/A8kCSQJJAkkCeQJBAitcAAM7AMoCKgJqAQuBqgBKAIoBCgJrAggCK5wcAgABPwDMAYAAPgHLgkoCegLCAr4CQAEs3AYCAAG/gEAAhgA4A8UAJwBfACUCRQI9Ae4cHAIAA7+AQACKAQwAA4A+A8oASgBKAEIALlwAAAADOACoACgBr4ApAKkBKQA5AIEBAAAunAAAYgMigLKALgGrACqAqgIuArgCIAHAAC8cDgIAAb+AQgBEAR0A14I9A9EAEQDRAQAAMFweAgABv4BCAMQADwHpAAkCPQPJACiAyAEwnB4CAAG/gEAARgBAASWBJAEmASWBBAEAADIcCAJEgcOA8oAagwaAAAEfAkAAQAF/gUACM9wAAgADPwBVAFUBVQBVgVUAVQLXAlABwAA2HA4CAAG/gEQAoAIiAT+AogAiAD+AogMAAjZcCAIEA7+AQADWABID64EtASkBLQETA9AANtwQAgwBv4BEAYABPgIiAj+B4gE+AYACAAA33B4CAAO/gEQAP4PAgQiBfoEogUCBP4PAADkcPAIAAz8AwAEEAUAAagD/AqoCrgKqAYkAOZwIAQYBAAD/wAIAwAI+QQJAu8BCQT5BQAI53B4CAAG/gEAApAIhASmA7wAtA/ECKQIgATrcAAIighiChQJAAQqA1oELgSaCIoKeAgAAO1wAAAkBCQDfwAUBoAAZAA/BwQAfAKABkAI+XAAACIIIgY+ADYFNgG3AHYCdgQ+ACICAgQJcQAAEAgUBPQBVAlcA1wBXANcCVwJFAcAAApxPAQADv4BCAMAAF4BVgHWD1YBVgFeAQAAFXEgCBAO/gEQAoAI+ASWAvQBnAL0BIAIAAAZcTgEAAb/AQgDIACsB6QEpgSkBLwEpAcgABpxAAAkChQLvgQMBKQDMAIMBH4FDAUUCCAEIXEoCCgN/gElAfwNJAH8BSQJ/AEkBSAIAAAmcRAIEAz4AV4BWA1YAfwBWg1YAVgBCA0ACDBxeAgABv4BAAI4ANAPSAUGBUQEXAXEDwAANnGICKgGbgJuABQFDAGAAGgGHgBoAooOgAg8cUAIOAQAAv4BEAikBPQDpgCkD/QIpAgABExxeAgABv4BAAKQCPwK1ArWD9QK1Ar8CAAATnEECfwEXQReAVwN/AAEAHYMBQH8AQQMAABVcQAAAAj+BLIAzgK6DAAA/gQSCRIDng8ACFlx8AgADPwDIAj0CpQK/AqUDvwKlAr0CgAAXnEAABgJVgVUAVwN9AEAABwN6gjIAjgFCAlkcTgEAAb+AQABEASEBL4CrAHsB74BhAIABGdxAAj8DZQAlADsDBQAzAFEBVQJVAHMDQAIaXE4CAAG/AEQAgAI/AusCqwCrAasBvwLAAhucQAAMA40APQBdAV+AXQFdAV4AfQBEgwAAH1xAAAQDv4BEA78A6wEbADqB6oEagL6DwAAhHE8CAAG/wEIAgAM/gCqBqsIqgqqAP4GAASKcQQEfAc/ALwAvgb8AAACZwSqAIkCRAwAAI9xAAAICvoK2gLaCv4D2gr6CtkC+QoICgAAlHEYACAM/gMQBCQBlA9ECSYJRAmUDyQBAACZcQAE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t3MEAiQC/AMkAgQAgA+ABP4EiASIBIgPCAC7cwAEJAL8AyQAAAz4A8gJfgZIBsgJGAgAAMJzAAQkBPwDJAIAAPQDFAH0CQQI/AcEAAAAynMAACQE/AMEAkAI/gdCAP4H/A9CAP4PQADNcwQCJAL8AyQBEAFICCQFkgTEBEgCEAEAAOBzBAQkAvwDJAIAAFwGSAH+D0gBSAJABAAA7XMAAEQE/AdEBAAC8AgABP4DAAj8D0QIBAjycwAAJAT8AyACDACMAvQClALUD5QClAIAAv5zJAQkAvwDJAoACPwFVANUAVQPVAn8CQAEA3QAAiQC/AMkAQwDaAIICP4HiAAKA2oEAAQFdAQCJAL8ASQBAAD8D1QEVgTUAVQDvASABAZ0AAQkAvwDJAIACXwIVAnUD/wPVAlUCXwJCXQABCQC/AMkAgAItAcsAKYPJAC0ByQIAAAQdAAEJAL8AyQCAAj0CRQEEALeARAEFAj0CyJ0AAQkAvwDJAKAANQC1Am8CMQHZACUAwAEJnQAAiQC/AEkAQAAtAe0AqwDLgj0DzQAAAAqdAAEJAL8AyQCAAgIBf4FWAFYAf4FCAUACDN0AAAkAvwBIAOIAP4PSAAAA8gA/g9IAIgDNHQAAFoAWgFeAXoBWgFYAXoFXgNaAVoAkAA8dAAIRAT8B0QGAADoBqgArA+oAKgB6AMIBEt0AAAkBPwDJAIAAPQHvAW2BbQPvAXwBQAFW3QAAiQC/AEgAQQE9gSUApAB8ACUApYC9ARcdAAAJAT8AwQI8Ae4AvQPFgDWAwQIyAcQAF50AAQkAvwDJAIAADwAsA+wB/4AsA+wALwPX3QAAJQOVAh8BFQGlApACVQJvARUAVQGAABqdAQCJAL8ASQBAAz+AKoGqgD+BqoBgg8AAHB0AAQkAvwDJAIACHwEVALUAf4HVghUC3wLg3QAAiQE/AMkAgQAdA9kA9YFZANECXQPAACHdAAAJAT8AwAM+gMqCMAHFgcqBOgPKAloCYt0AAAkAvwBJAAAAvQC9AL2D/QC9AL0AhACnnQAAiQC/AMgAQoEaAV+A+gBbgVoBW4JAACndIAAfAh0C7QLtAv8CwAPVAt2D1QLVAkAALB0AAIkAvwBJAUABP4Evge6Ab4CugJ+BRAFynQABCQE/AcgAggM/A/+B+wH7AfoC+gLAAjcdAAIAAb8AQQABAb8BQIEggc+CMIDAAwAAOJ0AAB0DfwB/A90AQAO/AEEBvwFBAL6DwAA43QEAE0N5gMADfwH/AsCCP4HWAHnD1QBAADkdAAE/AX+D/QJ7AHwDfwDBA78BQQG+gsADOZ0AAAEBAQO5AkcCNQEFAUUAPQHBAgECAQG7nQAAFgISA7kB3IHaAdiB2oBcg9kCEgISATvdAAA/AcEBbQE5AQQAQIM/guSAPIPAggABvZ0AACIDPoDiAD+D4oAAAj8D5QA9A8ECAQE93QAAEIIVAzAC2gJZAtWAUwBVA9kCGAEAAAEdQAAfAl8BVwHbAU8AIAPfAiUAPQPBAgABhh1AAAIAAgA/g+IBIgEiASIBP4PCAAIAAAAGnUAAAQBBA/+CVQJVAtUCVQL/gsECQQJAAAcdQAAkg+SBP4EkgcAAP4PiASIBIgE/g8IAB91AAAgCJAIjgiICIgI/g+ICIgIiAiICAAIInUADOQDJAm0CrwKrgqsD7wKtAqkCiQIAAAjdQAM5AMkCLwKpAqkCqYPtAqsCqQKIAggACV1AAArAiQC/wEkAQAIvgbqAb4EqgS+AwAAKHUAAAAM/AMkASQBJAH8DyQBJAkkCfwHAAApdQAAAAz+A5IAkgD+B5IIkgiSCpIK/gkABCt1AAAIAOgPqAKoAqgC/A+oAqwK7AcIAAAAMHUAAPwPRAREBEQE/AdEBEQERAREBPwPAAAxdQAA+A+IBIgEiAT+B4gEiASIBIgE+A8AADJ1AAAAAPwBlACUAJQA/A+UAJQAlAD8AQAAM3UAAPwDJAEkASQB/w8kASQBJAEkAfwDAAA1dQAAAAD8AyQBJAH/ByQJJAkkCfwJAAgABjd1AAAACXwJVAVUA/wBVAlUCVQJfAkABwAAOHVAACAA+AeuAqgC6AOoAugLCAgIDPgDAAA6dQAA/gciAv4DIgL+AwAACAgICPgHCAAIADt1AAD0DwQE9AVUBVQF/AVUBVQF9AUEBPQPRXUAAPgB/g+uD3gAIgnyBDoC5gkiDOADAABMdQAAAAG+CKoEagI+ACoAag+qAL4AAAEAAE91AACACPwP1AjUCPwI1APUBNQG/AiACAAAUXV4CAAG/AEABhAA/A9EBEQE/AdEBEQE/A9UdQAA/AckAvwDJAL8A4AAqAD+D6AArACAAFl1AAA8AKQPogqSCqIKgA+8CoQKRA88AAAAXHUAAEQA1A/UCvwK1g/UCsQKpAqkDyQAAABidQAAoACuAu4CrgLuB64CrgLuAq4CgAAAAGV1AAD8B/wDJAL8A5AAiA/WCKQI3AjED0AAZnUAAPwH/AMkAvwDAAgoCSgJvg8oCSgJAAhqdZAAlADcB7QFlAW8B5QFsgXaBdoHkABAAGt1SAB8BPwH/Af8B/4H/Af8B/wH/AdIBAAAcHUAAAAKvArsB6wGvAKsAqwG7Ae8CgAKAAB0dQAA/AckAvwHdAasA/QDXg1UDVQJVAcAAXZ1AAA4AAoP7AuoC64LqA+oC+wLCg84AAAAeHX8ByQC/AMkAvwDIAC0A7QCrgs0CPQHIAB/dUAA5gdZBdQHWAX/D+AEdgN5B7QIUghABoZ1AAB0BVQPXAzABwQA/A/0DvwP9A78D0QIinUAAPAJ/gj+D/4P/g+uD/4P/g/+CPAJAACOdQAE5AcEBPQDTAIECPQElAL+D5QC9AwAAI91AATEA/QDTAIACKQHPACmDywAPA9kCEQEkXUACW4JVAXUA1IBCA2iAyoE6g82CWIJIAiXdTgJgAT8AwQAJAAkCCcIpA9kAGQAJAAAAJl1MAkABfgDCABIBCgKrAmoCagIqAgoBAAAmnUYCYAM/AMECMQINAQmAqQBZAIEBAQIAACfdZgIgAb8AQQAhAD0B5UElgSUBJQElASEAKR1mASAAvwBBAD0A5QE9gSUBJQE9AQEAgAAq3WICLAO/AEECEQItAWWBpQG9AXECEQIAACudYwIQAb+AWIAIgDyBysIKwkqCfIIEgYiAK91OAGADPwDBAz0AxQAlgLUAxQA9AcECAQEsnWYAIAO/AEEDvQBVATWBXQCVAWUBDQIAAC5dbgIgAb8AUQAJAqUClYJFAWkBCQCRAEAALx1GAmADPwDBAAkBbQE1gjUCrQKlAAEAQAAvnWYCKAO/AEECIQEtASmAuQBpAKkBKQIAATFdZgIgAb8AQQA1A9UAFYD9ABUA1QI1A8AAMd1mASABvwBBATUBxQEFgT0B5QElASUBAAAynWYBIAG/AEEBCQFFAVWBdQHVAUUBSQFJATSdYgIkAb8AQQApAK0AqYC5A+kArQCpAIEANV1mAiABvwBBAD8D6wErgSsAawGfAUECQAA2HU4CYAE/AMECNQJVAtWCVQJVA3UCRQIAADbdZgIgA78AQQA7A+8Ar4C7A+8AqwK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JALkA3wA1AF+AVQB1Ad8AQABl3iEAPQHLATgB8QANAykA0YA9AcUCPQJAASYeEIA+gcWAvIBAAT8DKQC/wCkAP8CpAT8AJ94hAD0D0wEwAcIAHwNSAP8D2gDfAVICQAAp3gAAMoE6gL+D+oKgAr8CtQK1grUDvwAAACpeAAAhAD8ByQC5AsACPwHrAKsAqwG/A8ACLB4hAD8DyQE4AeIAA4J/A8ICPwPCgjICQAAsXgEAdQPLATEC/AHCACoDwgHfgKIBWoIAAazeIQA/AckAuQDAAisB2gALg2oAygErAkgALR4hAD0DywE5AcAAKgL2ArcCtgKqAsoCAAAuniEAPQPTATEB0wA5A9cCVYJ9A9UCVQJTAm8eAAAggD+ByICwAd+A6oEqgD+BqoBgg8AAL54wgD6ByYC4gEABP4DigjqB6oB6gKuBAAAwXiEAfwPJATkAwwIaA+OCOgOSAioD84IKA7FeEQA9AdMBMQHAAB0CFwG3AF2CVQJVAcAAMp4AABSAtIHegVuBWoHagLqB2oFegVCB0AA0HhQBVAFPANUDxYLfAsIC2YLUgu+D5gBgAHVeAAARAD0DywE4APID/wPzgjMD+wIyA8ACNp4hAH0DywEJATEB/wC3AbcDv4K3A/8AgQD6HgADvwBBAS0BLQOtAuWCoQKtAq0CrQOlAD0eEQA9A8sBMQHIACaCdoP1gjWDJoKIAgAAPd4QgD6BxYC8gOACHYHzAFfAMwB9QdUAQAA+ngAAIIA/gcSAuADSgjvBOoC+gDvAuoCAAwBeQAAQgD6BxYC4gEIDP8ArAb9AKwGLAAABw55hAD8ByQCxAsUCEwEXgfQD0wJXglUCRAIGXkAAAQB/APkCw4IVAfUAUAIDAfsDywJZAA6eQAAIAQkAqQBJAgkCOQPJAAkAKQBJAIgBDx5AACIAYoA7g9YAIgBAAD+BwAIAAgACAAGPnkAAAgBiADOD7gACAkgCCAI/g8gCCAIIAhBeQAAiABKAOwPWACIAAAA/A8EAHQCjAEAAEJ5AAGIAMoPeACIACAA/AcgCP4JEAj4CAAGSHkIAYgAzg94AIgJAAT8AyQAIgDiDyIAIABJeQgBiADuD1gAiAgACPAPAAj+DyAIIAgACFB5iACIAO4PWAAIAYAA+A9OBEgESATIDwAAVXmIAIgAzg98AAgI4AwAAvIHxAgwCGwGgABWeQgBiADKD7gAAAj8DyQJJAkkCSQJ/A8ACF15iAFIAO4PWACACDwEJAPkACQA5A88CAAGXnmIAYgA7g9cAIAA+AMoASgB/g8oAfgBAABfeQAAgASWBLQCtAC+B7QAtAK0ApYEgAQAAGB5gABJAOsHWACCAOoDKgEqAeoJAgj+BwAAZXkIAYgAzg94AAgAQAFKAUoB+A9KAUoBCAFoeQQJdAXUBdQB/AnUCdQH/AHUBdQFdA0ECW15EAAQAZgIbgRMAXQJSAlGD1gBZANUA4wMd3kIAYgAyg+4AAAEVALUAX4DVAlUD0QBAAB4eQgBigDqD5gAAADcD1QB9ABUC1QI3A8AAHp5CAGIAOoPWABACAgJ/gVYAVgB/gUICQAAgHkAAAQK/AuMA/wL3AveD/wDjAf8BwQKAACBeQAAFAlMBV4BTAlECVAPTAFeBQwFNAkgAIR5iACIAM4PfAAIAEIEKgIqCeoHKgG+AqAEhXmEAEQA5g9cAAQB8AGqAfgHrAGqAfgBAACNeYAAiADsDxgAwA98AMQH9ALUA1QI/AcAAI95iABIAO4HWACCAPoPagVqBeoHagV6BcIHpnkAACQFswWABesB/gHaB4ABvgOCAz4FAAWneQABigDqD5AABAB8D9wLXgtcC9wLfA8EAap5xAAkAPUPLQBAAv8CrQL/D6oCrQL/AgACrnmIAUoA6g+YAAAI/gv/CuoK/wrqCv4LAAixeQABigDqD5AAxA/8BfwH/gb8AvwP3AIAALl5AACED7wArASsBPwHrASsAqwKugiCBwAAunkAAIAP/ADUAtQC/APUAtQC1Aj8CIAPAAC7eQQABA90AWQFZAfWBVQFVANECXQJBAcEAL15EAAID+gBxAGUBbIHugWyB4QJ6A8IAAAAvnkgBCQCJAGkAGQA/A9iAKIAIgEiAiAEAAC/eQAAkAhUCFQENAN8ADQANAdSCFIIkASAAMB5iAhMCCwEnAOMALwAigqaCSoJSgdIAAAAwXkAApIBUgD+D1IAUgQAB/gEBgTABAAPAAjDeQAAUAhUCFQENAO8AJQANAdSCFQIUAYAAMZ5AAAYA5gA/A+UAAABRABEAPwPRABEAEAAyXkAACgEugS6AroBugH+D7oBugL5AigEAADLeQAAkgNSAP4PUgAACDgEgAN+AIADMAQICM15lANSAP4PUgACAPgBiACIAP4PiACIAPgB0XkAAJQDUgD+D1IAEAFCAUwBAAH+DwABAAHSeQAAlAFSAP4PEgCACDgEgAR+AgAB2AAAANV5EgOSAP4PUgAAAP4PIAQAAP4HIAgQCAgG2HkSA5IA/g9SAIAJYAT6B4IIYAgeCOAGAADfeRQDlAD8D1QAlAkACPwPJAkkCfwPAAgAAOR5AAAUA5QA/A+QAIQAtACEAPwPhAC0AIQA5nkgAawIbASsA7wDrg9sASwDbASsCCABAADneQAAFAOUAPwPkgAACPgIiAb+AYgG+AiACOl5lANUAPwPUgCSCBAETgJIAf4ASANIBEAI63mSA1IA/g9SAJICAAaQAXAA/g9QAJYBEAbveQAAlANUAPwPUgAACHwGRAFEAEQBfA4ACPB5kgNSAP4PUgCSAhACzwEECPwPBADsAQQC+HkUA5QA/A+SABoASA9ICUgJfglICUgPCAD7eQAAlAFUAPwPUgACCagErARWBXQCzAFAAP15FAOUAP4PUwAACZ4JUAhwBV8GUALQAV4AAHoQA5IA/g8SAAAB6gesALwApA+sAKoEqAMFehIDkgD+D0IACAj0BJIDkACSD+QICAgQBAt6AAAYA5gA/A8AATwIpAqkCqQPpAq8CgAIDXqSAVIA/g9SAAAA8gdUAVABXgFQBfYHAAAOegAAlANSAP4PAgA4DMoDSADMD04IeggABhp6AACUAVQA/A9SABAA/g+oBPwHqgSoBAAAIHoYA5gA+A+UAAAM/AMEANQH9ALUCwQI/AcjehAA+AVWBfQFXAX0BiAHpAD8D6QAIgcAAC56AADKASoA/wMACP4Krgr+D64K/QoACAAAMXoUA5IA/g+SAAAC6A+kAqQC6gOiCroK4gcyehQDkgD+D1IAEgDADxIAwg9aBUIF2g8AADN6JAIkAfwPogAABlgAVgVWC1QJXAHwBQAIN3qUA1QA/A9SAAAJfgmWBdYGvgZWBVYIXgA7eooBSgD+D0kAAADKB6oEgQQtBKEE7QcAADx6FAOUAPwPUgBABVwFtAJ2CbQG1ABcA0AEPXoUA5IA/geSABAAdAesB64HtAe2B5YHVAA/eooDSgD+D0kAgA9eAFYPVgVXB14Awg8CAEJ6FAOSAP4PUgCABnwArAysCf4KrAKsBvwIRnoSA5IA/g9SAIAIvAwsBSwF7gYsArwCgABMehAM+AFWDfQBXA3wAgQGpAH8D6QAIgcAAk16mAFYAPwHVAAQBPwF/AX+AfwB/AX8BRAETnoABM4C1AHUD7QBgAj8B6wGrAKsBvwHAAhXehIDkgD+D5EAAA5+AFYJVgv/C1YF1g9+AWl6EgOSAP4PkgAADPQB8gX6C/IJ+QH1DaAIa3qUA1QA/A8SADQI9An+B/QF/AX+B7QJBAh0egAAOAgIBsgBCAAOAAgASACIAQgGOAgACHZ6AACsCKQIlAScAsQBhgC8AKQHJAgsCAAGd3oAAKwIpAiUBIQD5gCECJQIlAikBywAAAB5egAADAAEA5QCrAKkAqYKvAq0CvQGFAIAAHp6AAAMCKQIpAiUCIcPlAiUCKQIpAgMCAAAf3oACDQFtAUsBSwDJgssCewHNAE0ASQBAACBegAArAikCJQEjASOA+YAjAPMBJQIhAgAAIN6AACsCKQHlASUAgYIRAbUAVQIVAjUBwAAhHoAAJQAVABMACwA5g+kAqwCrAK0AjQAAACNegAAbATkB1QCFAJGAMQBVAlUCWQJbAcAAJF6AACUAJQGtASsBKwE5gesBKwElAaUAAAAknoAABQItAr0CqQKpg+sCqwKtAq0CgQIAACTegAArAykApQAbAZECEYLfAh0CEwDTAQACJZ6AACkANQOtAqsCqYK9AqkCrQKtA6UAAAAl3oAABQA1AcsBmQGdgVkBewGLATUBxQAAACYegAASgRaA1oP1gtzC1MLXgtaC/oPSgBAAJx6AAAkB9QFtAWkBaQF9g+kBawF9AUUBwAAnXoAABQPDAF8BVwF1gNcA1wFfAkMCRQPAACfegAAFA/0ALQKrAqmCqQOvAq0CvQIFAwAAKV6AACmBKIC9gGmAgcI8gUWBNYDFgT2BQAEqXoAABQP9AE0ASwH5gdkB3wHdAf0CRQHAACuegAK9Af0BvQO7ArmBwYAvAO0CrQK9AYAAL96AAD0D7wEfAMMCMYK9A6kD+wPrA+MCAAAy3oAAAgECARoBIgFDgQIBsgFKAQIBAgEAADWegAIfgkACQALfgkACcYJKgkyDSoJRglACNl6AAAIAuoCigNoAQAAgA/+BIgEiASIDwgA3HoAABQA9AO8ArQC9ge0CrwKtAr0CxQIAATeehAIFAjUCVQFVANWAVQBVAdUCdQJEAQAAN96AAAUCPQLtAq0BrYCtAK0BrQK9AsUCBAE4HoAAAoE+gVaBVoFWw9aBV4FXgX6BQoEAADjeigEyQSKA2ACCAgsCasGiASqB6wIKAgAAOV6AAAUCPQK/Ar0CvYP9Ar8CvQK9AoUCAAA7XooBMkFCgQIA8gAHgaqBKoFqgaqCL4HAADveggE/AIIA+gCDACwD7AH/gCwD7AAvA8AAPZ6AAjUDtwB1gfcBBQAwAlcB1YBVA/cCQAE+XogADAADgD5DwgAIAAQAA4ICAj4DwgACAD/eggBJAEuASQBIAHoDyYBLgEkASQBBAEAAAZ7AAAIAOYHLAkkCSAJ6AkmCSwJ5AkEBAAAC3tIAEQIVgVUBVQD8AFWAVYBVAH0A0QAAAARe4gIpASmBKwCpAPgAKYBlAKUBJQEhAgAABR7CACoAqYCrAKkAuQHlApWClQJVAkEBQAAGXsAACgEpgSsBKwEpATwB6YEpgSsBKQEBAQbewAAGADGD1wFQAX4B0YFRAVMBcQHBAAAACB7EABYCEYIXAlACngIRgxFC1wIRAgECAAAJHsIAIgAVgZcBTwFEAUWBVQFVAU0BwQAAAAmexABiADmDwwARABQAUgCRghMCOQHRABEACh7KAImAiYBrAJgAvgPJgLkAiwBJAIkAgAALHsAAAAE1gVUBVQD9AdUAVYFVAV0BQQDBAA8e1AISAhGBkwB5ARABNgHRgpsCcwJxAhABEZ7WAJGA+4D5APsA/wH5gPkA+wD5ANEAgAASXtAAVYBVgVUBVABeAlWCVYJ3AdcAUQBQABLewAACAzmA2wJ4A8IAEYM5ANMCEQIxAcAAE97CAGIAOYPDABECEwEaATGA0wGbAlkCEQGUHsAAAAA9g8UCLQKsAr0C7YKvAq8ChQIAABRewAAKAIoAuYDLAoABOgDJgAkAewHBAgEBFJ7AAAIAPYPHABcB1AFWAVWBVQHFAj0BwQAVHuIAEYARg9sCWQJWAlWCWYJTAlMD0QAhABWewAAEATWBVYEVAJQAfgPVgFUAtQEFAQAAFt7CADoCQYE7AMMAMQHUABWAPYPVABUBNQDXXuMAKIAswKuCqoK6Ae6AqMCpgLmA4IAAABge0gERATmAwwCxAIgALgCpgqsCiQI5AcAAHd7yAEIAOYPDABUCIQEoAL2AaQArAPkBIQIeXuEBIwEqwSqA/oGrgasBqsCqg6qAooCgAB+ewAAWAhGCCYLJAhQCFgLVggkDCwLRAhECIB7CADIDxYA1AdQBVgFXAXWBxwA9A8EAAAAjXsoASQJ9g8EAPAPGAjWC1YI1AtUCNQLAAiPe4IAigK7AqoKqgroB6gCqwKqAuYDggCCAJV7AAAQChYK/Ae0BrACtgK2BvwHFAoUCgAAl3sIAAgK5gr8BvQD8AL4AvYC9A/8AgQCAAChewAAcAAWANQPVAtUC1ALVgtUC5QPNAAAAKl7CAB0CVYJ1AT0BtgG1AT2AtQB1AB0AAQAq3sgAHAOdgF0DHQA+Ad2AHYGdAB0DyQAAACtexAAFADyD7sCsgryBxAA0wMaCBII0gcSALF7AABYBkYB/A9UAQQA9AdWBVwFXAX0BwAAwHsAAAQI9A+2CLQG4AwIAOYPFAAUBPQDAADEewgA6AV2BfQPdAX0BQQA9gcUCBQJ9AgABsd7AACAD3YAVA/UAtwP2ALWD9QC1Ar0BwQAyXsAAFQJVAV2BQQDiA9mAXYDVAX0BYQFRAnTe6gJpAl2CyQNpAXwBSYFJAd0CaQJpAkAANl7AACUD/QA9gD0B/AF9gX0B/QAlAiUDwAA4HuAAEgA/g/MAQAIkAV2A1QPdANUBVQJAADhe4AChAL7Af4E+gb4BPwE+wb+BPoJggIAAO57AAAACHYPBAlsDwAJNg8kCawJrA8kCAAA8XsIABQP1gHUBdQH2AXUBdYDlAnUCRQPFAD3e4QIlASmBwwIxArQC7QLtgu0C9QLxAoAAAd8CAgoBu4BpAysAygIHAVWBdQDVANUBRAJIXwCAPoHOwD6B3oFQAV7BfoHOgA6CPoHAAA4fCQK9AvmAuQG9A8EAOQPpgn0BqQGpAkAAD18AAAoCKYFXAVUBegJsAhWBWQF7AUkCAAAP3xEAFQGBgEEAPQB8Af0BfYB9Af0AfQBBAFDfAQA/AlbD94LWg98C28OEwqWCpIOkggQAEx8CAJIAtYP/A/0D/wH9A/2D/QPfAdUBgQCTXwAALQEtAL2D7QBAADQD/YK1Ar0CtQPBABgfAAAVAj0B9YB/ArQBxAA/gd0C3QLdA4EBGR8AADgCtYLxgdMBOQH4A92BMQDXAdECEQEcnwoAOgP9gc0A/wP5APoDuYJ9Ar0AvQLAAhzfEAIRARYAkABwAD+D8AAQAFQAkwEQAgAAHt8SAlICSoJKgUYA74BGAMaBSoFSAlICQAAfXwsA6AA/g+gAAwBQABECEQI9A9MAEQAQACJfCwDoAD+D6AALAlgBFgGxAFACEYImAcgAJJ8LAYgAf4PoAAsAQAIaAiICw4IiA9oCAgIl3wIACAD/A+gACwBAAj8DyQJJAkkCfwPAAiYfAAALgOgAP4PJACAD4AE/gSIBIgEiA8AAJ58jAMgAP4PhAH8DxQE/AUUBPwEFAX0DwAAn3wECXQF1AXUBXwDVA9UAXwDVAVUBXQFBAmkfAAAgAD8AMQD1gLWAtQK9ArEDvwCgAAAAKV8AADyCJIIngc8A/4PKAAEA3AIkgieBwAAp3wsB6AA/g+oAAAM+AMICEgI7g9ICEgIAACqfAAAKAqoCqoKnAu+AogCmAacB6oKqAooCq58JgegAP4PoAAuAQAA/A9UBNYAVAN8BAAEsXxkCREFQQWMAyABkg8uAUIDwgV+BQwFMAm5fAMA0AH/D1AAkwGAALoAggDjB5oAkgCiAL18AAa4Af4PIAAIAwQIpAanAKQPpACMAoAMvnwCACwH4AC+DwAA1A/cAtwC3grcCtwPFADKfAwAIAP+DywAgA9+BMgDAAz+A5II/gcAANV8BgCgA/4P6AAACKgGqgCsDvgArAyqAIgO1nwGANgA/wNYABAP/AB0A/QC9gL0AvQDIADZfAwAoAH+D6gAJAlABNwHAAisC7wKqAqoC9x8AA78AQQIHAW8BS4Dhg8cA7wDHAUsBQAA33wGAKAB/g+MADoA1g//CtYK/wrWCv4PAADgfAMAkAH/D8IC/wEBAlUB/wfXAz0BkQKBAud8qAH+D6AAKAjgC/wL/Av8D/wL/AvcCwAI73wDANAA/w/eAY0HvQClB+8ApQetAL0HAAD4fIAEhASYA5QB4wDQD0gARAF0AUACgAQAAPt8AAAABJQE1ALcCLQIlA9SAEoBQgKCBIAE/nwAAJAO3ACyDIgCAAD8AwABAAEAAf4PAAAAfQAASAd8ANIPSAEAAOQHJAgkCCQIfAgABgR9SAd+ANAPTAAAAxAATgCICQgICAz4AwAABX0AAEgHdgDQD0wA4AoECAQI/A8ECAQIAAgKfQAAFAhUBVQFfAH0CVYPVAEcBZQJJAokAAt9SAduANAPTADgCggIOATIAg4DyAQ4BAgIDX1IB24A0A9MAAAB+A8IAcgAPgDICPgHAAAQfRAOnADyDsgAgAIECEQM/AtECPwPQAgAABR9SAduANAPTAEAAOgDCAEIAf4HBAnkCQAEGX1IB3YA0A9MAGQBAAT+ByIE/gEiBiEMAAAafUgHWAD2D2AAQAsEB/wAhAQkBTwD4AQgCBt9SAd2ANAPTAAAC3AITgbAAUIITgjQByAAIH0gACoJagVqA+oL/wlqByoBqgWqCSALIAghfUgHfgDQD0wAxAoACAgH+AAuCCgI6AcIACJ9AAA0CBQFVAX0AV4JVA80AbQFFAU0CQAAJ30ACB4JgAXeAcAJogmSD14BUgUeBSIJIAArfRAJHAlQBV4FtAGQD04BFAWUBRIJCAoAAC99AAAACD4FagXqAX4Jag8qAaoFPgUACAAIMH1IB3YA0A9MAcAA/A9EBEQE/AdEBEQE/A85fUgHbgDQD0wAAAMgAKIPngSCBKIEng8AAEJ9SAduANAPTACAAogATgQ1BTQFTAlAAAAAQ30QDtwAsgZIAEAHSABoBloFzAQoBggMAABEfUgHbgDQD0wAAAMACPwPJAkkCSQJ/A8ACEx9SAduANAPTAAAA0IIJgkqCZIPKgkmCUAIUH1IB24A0A9MAKADBACkD6QEvwSkBKQPJABVfbAN7ACiBJgCAAD0BzQJLAnkCTQJLAngBV59SAd4ANYPUAAACygImAQYA84DCAQoCCgAYX1IB24A0A/MAMQDkADID9YEpATcBEQPgABmfUgHbgDQD2wBIACQD4wEogSkBIgEkA8gAG59AAAsCCwFlgHUCcwJgA9eAVIFEgUeCQAAcX1ID3YA0Q9MAAAJBAS8AycALAC8DwQIAARyfQAAkA78AJIGSAIAAFgDdgjQD0wA4AIABHV9SAd2ANAPTAAACxAIiAamBaQEiAawDBAAdn1IB24A0A9MAQAA+AeWCJYI/AicCJQI8AaTfZAMvAHiDNgAAAo6CEIJEgnqD4IJPglGCJl9QAduANAPTAAAAf4PAASoBP4FoAQsBQAEmn0AAEgHfgDQD6wDgAlUBFQDXgBUBtQIBAScfTAO7ACiDJgCAACMDKQCpwCkD6QArAKADKB9MA7sAKICmAQABNoCVAjUD3QATAKABAAArX1IB24A0A9MAEADEAD+D6gE/AeqBKgEAACxfU4HcADsD0AB/A/sA+QDJAKsCyQI/AcAALJ9SAd4ANYPgAL8DwwAvAPkBLQEBAD8DwAAv31IB24A0A9sAQAAvgeqAKoA6w+qAL4EgAPKfQABPgUuBb4F7gGuB6IBWgMaAyYFQgUAAM99SAd2ANAPTAAAAV4EQAD8D2QJcQhGA4gE0X1IB24A0A9MAAAFIASqAioI6gc+AaAGAADSfUgDdgDQD0wA4AOEAJQHfgVUBVwF1gcQANp9SAduANAPzADABZwCrAksCO4PLAO8BAAE4H1IB3gA1g9IAQgAoAeUAJwA1g+cALQHAADjfSAIvAziAtgCgAQgBH4DtAq0B7wBIAYAAOh9SAduANAPTAAAD/wHrAKsD6wCrA+8AoQP6X1IB24A0A9MAEAJFARcA/QJ1AbSBtwFVAjvfUgHWAD2D2ACAAT0BbwHtgW0D7wF8AUABPR9SAd4ANYPSAAAAvwErAKsAf4PrAH8AgQE+32QDtwAsgTAAZwE1AeUBAQA8AwOA/gEAAgBfkgHXgDwD2wAgAIgBGoDqgpqB74AIAcAAAR+RANfAOgPJgAAAfwHvAK8AvwHvAq8CvwNI35AAnwBfAD8B/wASAIYAXwE1ANUANACgAAmfkgHbgDQD8wAQAL2D5gHFgTwD5YIEAgAACt+EA7eAHEEbAMBCHYG4AksCLsK+wsmCgAILn5AB34A0A9MAUAA7A8EANYHdAVUBdQHAAAxfhAO3gCxDMwCAAD3DwAEzgMBBOgHhgiYCD1+kA7cALIMiAIADPwChAaWCaQLhAD8BgAAPn5IB24A0A9MAAAK/Aj8Bf4F/AH8BfwJEAhBfgAIMAq+CjwL/AM8D4gCXgZkB1wKhAoAAEp+QAdOAPAP7AHAB/QHHgT0A5AG/geQDBYCVH6gAy4A8Ae8ABAA/Ae2AtgPPwPQBBYOAABefpAO3ACyBIgCAAiqCeoHrwEKD+oJqgmABWp+AAd4AJQGUgEIADQH8gX6BdIF9AX0BwQAa34AAH4Kfgd/B/4PfgsYB/YC0gp+CpgKgAhwfkgHbgDQD0wBAATwAt4B+gfqAdYC8AQAAHN+kA7cALICCAk+DOsD6wm+BzQMiwN4DAAAfH4QDtwAsgZIAv4PNAi6DzgJPgisDxALAAiMfpgO9gCRBkgBEgjuB/4H7wP+A+4H+gcACI9+gA7cAKIGWAEADPwD9An+C/4O/Av8C4QJln5QB3wAagIACXYE9QcQBPYPMAT+B9AMFgKgfqAEsAVsBSIFkAQAAPwBAAEAAQAB/g8AAKJ+AAAwCewEogSYBgAABAQEBPwHBAQEBAQEpH4AADAJqAVmBRAFQABEAEQA/A9EAEIAQACmfqAEuAXkBJIEgAIwAI4AiAgICQgM+AMAAKd+IAW4BeYEkAIQDIQDfAiEBTQCrAVgCAAIqn4AACAFuAVmBRAFAADEB0QIRAhECPwIAAarfgAAMAXoBaYEkAIACHQEBAP8CAQM/AMAAKx+IAW4BWYFEAQAAqgAqAD+D6gAqASIAwAAr34gBbgFZwUQBQAE9AEEAQQB/wcECfQNBASxfgAAMAXoBaYEkAIACHgIAAT+BAACmAEgALJ+AACYBdcEsQQAAP4PAgCyAdoBAgj+DwAAs34AADAFzgUiBQAA8A8QA/AAnggQCPAPAAC1fgAAMAXsBaIEkAAADv4BAAwAA/4AAAcACLd+AAAgBbgFZgUAAWAIWATEA0AIRgjYB2AAuH4gBbgFZgUwBQAA/A9ECEQE/AFEBkIIQAa5fgAAMAXsBKICmAoACDgEygIOA+gEGAQICLp+AAAwBawFYgUYAQAICAf4AE4ISAjIBwgAvX4AADAJrAVjBRgBAghCDP4LQghCDv4JAAi/fgAAuAXkBJICgAoQCFAEfgTIAyoFqggABMN+uATkBLICAABUBnwBVgj0D0QARAEEBgAAxH4AACAFuAVmBRABAAj8DyQJJAn8DwAIAADFfgAAIAm4BWYFAAD4AygBKAH+DygB+AEAAMZ+IAWwBW4FIgUAAPwPRAREBPwHRAT8DwAAx34gBbgE5gSQAgAIfAZEAUQARABEAXwOAAjIfgAAMAXoBaYEkAQQAEgCVgQkBVQFTAiAAMp+MAqsCWIJEAUAACwBIAH+DyABLAEiAQAAzX4wBZwE8gKIAiAAog+aBIYEogSiBJ4HAADOfiAF+AWmBJAEBACsAqwClA+0AqwCpAIAAM9+IA24BeYEkAAACKQIpAiUD6wIpAggCAAA0X4AADgL5gmQAQAIKA3+AwAA/A8EAHwChAHSfiAAmATkArICCABABugBCAh+BIgHaggIBtN+MAXsBKICmAIAAKQHpASkBL8EpASkBwAA1X4gBbwE4gSYAgAIpASmA7wAtA/ECKQIAATYfjAF7AWiBIACIAiQDqwJpgSIBpAEoAgAANl+IAW4BOYCgAIgAKAPsA+uBKgEsA8gAEAA234gBLgFZgUSAkAAqAKoAq4ClA+sAqQCIALcfgAAMAXsBKICkAIQAEgPtgSkBLQETA9AAN1+IAWcBOIEmAQAAPgHlgiWCPQInAjwCAAG3n4gCbgFZgUQAUAIOAiYBQoCyAUoCEgIAADffiAFuAVmBZIEEAJACGgHXgBID2gISAhIBuJ+AAAgCbgFZAUAAOAPvAK0ArQKtAr8DwAA434wBawE4gSYAgAIrAScA4wAvACaCSoHAADlfjAF6ASmAqACCAhEBeQGagLCBVoMQAQAAOd+IAC4BeYEsAIAAPgHBASgBP4FYASsBQAA6X4wBZwE8gKYCgAI3AVcBF4DXABcBNwJEADqfgAAmAT2ApICAAJUANQHfgVUBVwF1AcSAO1+IAW4BOYEkAIAALQIFAUeA9QBFAVwBRAI7n4AALAF7ASiBDgAoAe0AqwCrgs0CNQHNADwfiAFnATiBJgCAAD4AqgCqAKuD6wC/AIAAvN+AACwBWwFIgUAAPwDtAL0B7QKtAr8CwAA9H6wBOwEogKYAiAA/A+qBKgE+geoBKgEAAD1fiAAmAXWBLECAAC+B6oA6w+qAKoEvgMAAPd+IAX8BbIEAAz+A5II/gcADP4Dkgj+BwAA+H4AALAF7ASiAgAI/AcEANQH9AIECfwHAAD8fgAAIAW4BWYFAAUYAIgCqgisD6gAqAKABP1+AAAwBegFJAUAASgMqAMoBO4PKAkoCQAA/34AALgFZAUSBYgAQAQqAioJ6gcqAb4CoAQAfwAAOAqkC3MJAAyqCJoGBAmgCZIGnguiCAV/AAC8BeIEmQIIAOIHEgTyB14F8gfyBwAABn8AANgCTgJ5AQAE7wQ/AqABKAMmBOwFBAQOfwAAOAXmBJEAAAL8D1ICAAjeBUIC/gVgCBN/IAW8BOMEmALADFQC8gnWBtEG3QVVCAAIFH8QBawFYgUYBQAAtAecANYPnACUBLQDAAAVfwAAOAXkBLIECAKgCKoLmAbeBJgHmgSoCBZ/AAC4AuQCkgAABvwBlAfWA9QHVAHcBwAAGH8gBLwFYwUZAAAFbAVrBaoKqge+ASAGIAQZf5AE3AKjApgCAgDqD2IFfgV+BWIF6g8gABp/IAWwBG4FIAUAAHgBeAV8AXgJ/A/4AQABHX8AANwFswSIACII4AcECK8K6guuCqIKAAggfwAAOAXkBRIBAAz8A3QIrgr+D6wK/AoACCR/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SANABAAA/A8EAPwDK4EADP4Dkgn+BwgA9AySA5AAkg/8CBAIAAQvgQAM/gOSCP4HAADoD6gCqAL8D6gCrgroBzGBAAz+A5II/gcAAHgESgfMAMwPSgh5CAAGM4EADP4Dkgj+BwAA7g8ABEEFzgQABO4PAAA4gQAM/AMkCfwPIASQBSgEpgQoBxAHoAQAAD6BAAz+A5II/gcAAPwB1AFUAX4HVAFUAXwBSoEADP4Dkgj+BwAAFADeB1QFVAVeBdQHAABLgQAM/gOSCP4PAAD0DwQA5gxUA5QFdAgACEyBAAj+B5IA/g8AAOgDuALsB6gK+AsoCAAEUIHADzwApA+kALQGhAWmBZQF1Aj0CJQPBABUgQAM/gOSCP4HAACkCJQIhg+UCKQILAgAAFWBAAz+A5II/geAAEwItAdGAPQHFAj0CQAEZYEADP4Dkgj+BwAB/gjqCqoKqg+qCr4KgAhmgQAM/wPJAP8HAADvDyAEtwQoBSIE7QcAAG6BAAz+A5II/gcABHwDVABUB/wIVAhUAXwHcIEADP4Dkgj+B5IAqgf+BqoEvgOqBLoIAABzgQAI/geyAP4PgAD8D6AExA/4BwQA/AMAAHiBAAz+AxII/gcAAP4G6gHqBOoD/gjABwAAeYEADP4Dkgj+BwAAfAXuBewC7AX8BAAEAAB6gQAM/gOSCP4HAAC8AqwJLAjuDywDvAQABHuBAAz+A5II/geAAXgOeAD4BQgI/gMIDAoGfoEACP4HkgH+D4AB6gS4Bq4GqApqC6kGgAB/gQAM/gOSCP4PAAjuBwAI/AtUCNQJ/AoACICBAAz+A5II/gcAAFQO1AFUCVYJVAlUBwAAioEADP4Dkgj+BwAAeAV4BXgBfAl4D3wBeAGPgQAAZAA8D/wHvAe+B7wHvA/8DwwPZAAAAJiBAAz+A5II/gckAdQF/AHUD/wB1AX0BQAAmoEADPgDCAD4CPgH/gP8B/wH/A3cDxgAAACbgQAM/gMCCP4HEADKBagFrgeoBcoFGgUAAJyBAAz+A5II/gcAAHQFdgf0AXYDdAV0BQAJnYEADP4Dkgj+B4AAVAVMAj4PTAJMBVQEAACggQAM/gO2CP4HAABUCqIKvgpABVQFAgI+AKiBAAj+B5IA/g9AALQGvgR0BQAATAwiAwABs4EACP4HkgD+DwAAVA9WC/wLVAvWC1QPAAG9gQAM/gOiCP4HEAD4B5YItA+cD7QP0A/AAMCB8AAOAPoPugP6A74DgAP2C9ILPgdYAEAAwoFAADwA/A/cA9wD/AOwA7wL9gu8BzQAEADJgQAM/gOiCP4HAADwB7gF9wBVDKQC6AwAAMqBAAz+A5II/gfgAN4G+gH6B+oH1gHwAgAE04EADP4Dkgj+D+QH/g90B/QFHgD8BJwHWAzjgQAA/geSBJIEkgSSBJ4HkgSSBPIEAgQAAOWBAAD8B6QEpAS8B+QEAAyAA3wAgAEABgAI6IEAAPwPlAScB5QEcAuYBKYHVA/UBPQPBADqgQAAAAD8DyQJJAknCSQJJAkkCfwPAAAAAO2BAAAACXwFXAVcA14BXAFcA1wFfAUACQAE84EECKQItAisCKQIpA+kCKQIlAikCAQIAAD0gQAAvASkBJQHlAS0AiAIfgSIA+gCGAQICPqBhAn8DdwP3A3cDd4P3A/cD9wP/A2ECQAA/IEAAPwPRARCBEIEAAREBEQERAREBPwPAAAAggAA1A9UBUQFRAUUBCQFAgViBXoFyg8AAAWCAAAcBfwF/AX6A/AB/AH8BfwF/AX8AwAABoIAAAAJ/AVSBQAFXgF0AVQFAAXUBTwJAAAHggAAAAn8BVQFAAU+AXQBAAVUBdQFPAkAAAiCAAAACfwFBAX8BSwBXAEkAfwFQAX8CQAJCYIAAMAAfAJaAsAC7gfcAsgCXAL8AsAAAAAKggAAJAD0B/QH9gfwBvAG9gf0B/QHlAcAAAyCAAAKAMoPSgRKBH4ESgRJBEkEyQcIAAAADYIQAFAAUAdYBVQF8gVUBVQFWAVQB1AAEAAOghAAUABID0QJUgl6CVIJVAlYCUgPUAAQABKCEABID0QF8wVEBQgHYABqCPIPLgDiAAAAFIIAAJIP/gSSBNAP1AE0CJwPFAA0AlQAUAMXghAASA9WBXwFWAcQAMAPqAL+D6gC6g8AABiCEABYD1QF8gVEDwwA9A9WBVQFdAUcDwAAHIIACbAIUgVWAtIBFgDSA1IC2Q9VAlACAAAeghgJWAn+BtQC/AHUAPwD1AK8B9QCkAIAAB+CQAhABvwBRABMAU4BVQJECEQI/A9AAEAAKoJADPwDRwBVCfwHAADoDygALgDoDwgEAAAsgkAM/ANOAEUN/AMACN4IQgVCBs4FUAgAADCCAABADPgD1Aj4DwAAfg4CAfoHAgj+CAAGMYJADPwD1gBECPwHEADoBycIJQnoCDAGAAA1gkAM/APWAEUI/AcAAOgHigiMCEgIWAgABjaCQAjAB3wAVgn8BwAA+A+IBI4EiAT4DwAAN4JADPwDVwFFDPwDAAhoBFgHzgRoBCgHCAg5gkAM/ANEAFcJ/AcAALgPhgSABI4EsAcgAEeCQAz4A14BSgj4D7QH7AQACCQK/AsiCgACWIJADPwDzwhFCPwHAAC+CKAH/wSgBrwFgAhmgkAP/gBbB/4BAAT/B9UE9wfcBI8HpASkB2+CAAAACPwHVARUBNYEVAFUAlQFfAWACAAAcIIUBCQCxAF8BgAA/g9SCNIIUgFSBn4FAAlygiAAEAD4B5QIlgiUCPQInAiQCPAJAAQAAHOCAAAoASgB/g8oAQgA+AeWCPQInAjwCAAGeoIAAAQAJAQuCiQJpAikCGQILghECAQGAAB+ggQIBAgkBM4EBAMEAgQDzgQkBAQIBAgAAIKCBAAkACQALgDkDyQAJAAkAi4C5AEEAAAAi4KEAJQAlACWCJQIlAj0B5YAlACUAIQAAACNgoQARAA0ALYAJAEkAiQIJAguCCQM5AMAAJKCBABEAMQHTgREBFQEZAREBE4ERAREBAQAl4IECAQJRApmCdQFVAdEAg4DxABEAAQAAACZgoQIpAikBK4EpAL0AaQBpAKuBKQEpAiECJyCggiSCJIIlwSSApIB8geSCJcIkgiSBIIAnYIECEQERAJeBEQMdApECkQJ3ghECEQIBAilgkQARAgkBK4DJAAUABQAJACuDyQARABEAKaCAAgEBvQBVgFUAVQBVAFWAUwBzAMEAAAArIKEAEQIxAiuBKQDhACECKQILgdEAIQABACtggAABAD0B5YIlAjwCJQIlAiWCJQI9AgEBq6CAgDiDyIALwIiAbIAcACiAC8LIgjiDwIAr4IIBIgDCACcBwgIKAhICIgIHAaIAAgHCACxggAABAGEAOQPDgAEAeQHjghECEQIJAgABrOCJAgkBCQGLgHkALQIpAikCK4IpAckACQAt4IACAQIxA8OCAQIBAjwD4QIjgiECAQIAAC4goQApAikCK4PpAykDKQMpAyuDKQGpAiECLmCBAgEBPQDlgCUAJQAkACUD5YAjACMAAAAvYIECJQE1ASWApQClAmUCZQI9geUAJQAhADHggQAFAFUAVYBVAH0D1QBVAFWBVQFFAMAAM2CRABEACQA5gdUCFQIVApUCuYJJAREAAQAz4IECiQJpAQuAqQBdAAkCCQI7gcEAIQDBADRgoQIRAi0BD4D5AAAAOQHJAguCSQJ5AkABNSCAABEAEQPZgVUBVQFRAVUBVYFZA8EAAAA14IEAAQA9AeWBJQE9AeUBJQElgT0BwQABADbggAAFADUB1YCVAJUAtADFAgWCPQHFAAQAN6CggBCACIHugqvCqIKogqiCy8I4gsCCAAE34KEAEQAJAe2AqQCoAKkCyQILggkDOQDAADlggQCJAMkAa4P5AS0BKQEpASuBKQHJAAAAOaCAAAkAKQPrgSkBPQEpASkBK4EpAckAAAA64IAAAQAhAeOBIQE9ASkBKQErgSkByQAAADxggAABAnkCS4FJAf0ASQDJAUuCeQJBAkAAPmCBAEUAVQBFgEUAfQPFAEUARYBVAEUAQQBAYMAAAQA5AaOBIQE9AeEBIQEjgTkBAQOBAACgwAABAzkAy4IJAgkBHQEpAMuBaQItAgkBgODhACUCCQETgMEAOQHJAgkCC4J5AgECAAEBINECEQG5AFOCEQIhAfkDyQELgQkBOQPAAAFg4QElASUArYKtAnUCNQH1AC2AJQChAGEAAmDJAikBKQErgKkAfQPpACkAa4CpASkBCQIDoOECJQIVAhWCVQJVA9UCXQJdglUCUQIhAgngwAABATkBS4FJAX0ByQFLgUkBeQFBAgAACiDBAAkAiQKDglEBDQEJAPkAS4CpARkCAQIK4NEBFQERAIOASQA5AckBDQEPgQkBCQEJAAsgxQBlADUDz4AlAiUCJQI1A+WCJQIlAgEADKDAAjEDKQKjglEBCQMgADkBo4JhAREBgAINIMEAPQHFATWBVQFVAVUBdQFFgT0BwQAAAA1gwQA9A8UDJYMlArUCZQJlAqWChQI9A8EADaDRAAkDKQCpgKUANQPlACkAK4CpAIkBEQAOIMEABQEFAT2B1QFVAVUBVQF9g8UBBQEBABGg4QIlAT2A5QAlAD2D5QAAAD8BQAI/gcAAEmDAAAEAvwCrgKsAqwPrAKsAq4C/AIEAgAAT4MAAIQB5A8OACQJJAkgCeQPLgkkCSQJAABQgxQBlADUDzYAFAFUCVQJ1A9WAVQBFAEUAFKDBAAUCHQElgKUAJQOlACUAJYOlAgUCAQEVIMAAEQJVAVWAzQJGAcQAFQFVgM0CQQHAABYgwQEZAIEAu4PBABECEQI5A9OCEQIRAgEAFqDggiKBKoEiwKKAfoAigGKAosCqgSKBIIEXoNEAkQBVAnWCFQGdABUANQPTgFMAUQCBABgg4QAlAiUDJYCdABUAFQAdACWD5QAlACEAGGDRAhUBEQDDgBEAlQJ1AR0AtYBVAjEBwAAY4MACLQIlASUBJYC1A+UAZYClASUBLQIAAhkgwQEVARUBdYFVAVUBVQPVAVWBVQFVAQEAGWDAAS0DJQElAKWCRQI1A8WAxQFlAQ0CAAAZ4MAADQElAQWAhQB1ACUABQBFgKUBTQEAARrgwAA9A8UAHYClAkEBPQDVglUCVQJ9AcAAG+DRAl0BcQFTgUEBUQAJAC0ACYJJAjkBwAAd4OAAEQA9A8WANQHVAJUAtQLFgj0BxQAAAB4gwAAdAI0ArYKtAq0CrQOtAO2AjQCdAIAAIaDAAAUAPQPtgK0AvAP/A+0Ar4K/AcUAAAAiYNEBFQCVAH2D9QAVAMEAOQDDggECPQPAACKgwAJdAdEAe4PBABECEQIRAjuD0QIRAhACI6DBAAEAFQIlgYkAoQIZAgEBO4EBAIkAsQAkoMAAAQAdAdWBVQF0AVUBVYFVAV0BwQAAACTg0QBJAGcB14FVAXUB9QHVA1WDdQHFAUAAJiDAACUApQC9gKQApgPkALUArYClAKUAgAAnoMACLQI9Aj2BvQB9ADwAPQH9giUCLQEAACrgwAIBAr0CrYKtAa0A7QCtAa2CvQKBAoAALGDhAiUBLQElgKUAfQPlACUAZYCtASUBIQIsoMACFQExAcGBVQJdAlUCdQLVglUCRQJBAC3gwAARAo0CdQHFgBEDEQD5ABOA0QEVAgEALmDAAB0CBQJVglUCdQPVAlUCVYLFAk0CAAAuoMAADwC7AMuA2wDfAM8AywDLgtsCRwHAAC9g1QAVAlUCTYFlAMUARQBlA8+AVwBVAFEAMGDAABUDPQD9gP0A/QD8AP0A/YL9A9UAAAAxYMAADQAFAD2B7QFtAW0BbQFtgXUBxQAAADHg6QI5AQ0A6YCZAQEAKQPpgT0BKQEpAcAAMqDQgBCCXoFLwMiA6IPIgMiA28JIgjiBwAAzIMEAPQPFAi2CrQJ9Au0CbYKlAoUCPQPBADPg0QAVAwUAxYA1ANQAVAB1AkWCPQPFAAEANyDBAlUCVQFFgM0A5QPFAMOA0wFLAkECQAA4INECFQOlAAGDPQDlAmUCvwElgaUCTQIBADpg4QAlACUDtYKlAqcCpwKlAr2CpQOlACAAO+DBABEBFQF9gVUBfQPVAVUBfYFVAVEBQQA8YOkCKQKtAp2BjQFNAU0BXQFtgu0CSQIBAjygwQCpAKkAq4C5A8EAAQA7g+kAqQCpAIAAgOEAACUApQCVgIQAhgPkAJUApYClAMUAwAABIRAACQBFAVWBVQF1AdUBVQFFgEUCPQHAAAKhAAAFA3UBBYCFAH4D/APFAFWApQEFA0ABAyEBADkB6QCrgLkCQQG9AFUAVYJ9A8AAAAADYRECFQEBAM2AXQBFAEUAfQPFgFUAVQBBAEOhKQJtAl0CzYLtAX0BTQFbgdsBWwJpAmkCR2EBAB0CVQJ1gT0BtQG1AT0AtYB1AB0AAQAJIQAADQIlAlWCVQJ1AdUBVYFVAWUBTQIAAAlhAAANAAUB3YFdAV0BXQFdAV2BRQHNAAAACeEIAC0DrQAtgy0APQPtAC0BrYA9A4kAAAAKIQAAPQPFAD2CQQElAO0ANQAngDUALQAlAAshAIAAg/6AasFqgX4B6oFqgWrBfoJAg8AAD2ERAhUBEQDDgCkAKQPtAlUCVYJtA6EAAAASYQUBRQFfAVeA1QB9A90AX4DdAVUBVQFAABXhAIBIgGqAKsPqgr6CqoKqgq7CqoPIgAAAFuEBAIEAXQH9gT0BvQF9AT2DPQI9AiEBwAAYYSAAMQA5A/eA9QD1Af0A9QPFggUCPQHBABjhAAAJAT0B/YH9Af0B/QH9gf0B+QHJAQAAGuEBACkD6QE9gSkAyAI9AcWAFQJFAn0DwAAbIQAANQK1Ap0BnYDFAJ0AtYCtA+0ApQCAAJxhCQIpAacAF4GNAjUClQKdAoeCPQCBAwEAHWEBAhUCVQJVgV0BVQDxANEA24FRAVkCSQAgoQAANQAVAdWAVQB1A9UAVQBVgVUBtQAAACLhHQCBAHkDw4ApAGUBVQBVgk0CbQPFAEAAZmEAAtcC1wH3gbcA1wLXAdcAV4DTARcCAAEnIQEAFQHVADWD1QAVAFEAlQI1g9UAFQHBASyhCQALAxEAxYA9A+0ArQC/g+0ArQK9AcQALiEkgSSBloAOwEKDWoBGgU7CWoAogQSCQAAvIQEACQM5APWD/AL6AvwC9QL9gvkDyQAIAC/hAQAFACUD/YA9Af0BfQF9Af2AJQIlAcEAMSEkACUALQH1gfUB9QH9Af0B9YH1AbUAJAAyYQAADQCFAFWD5QJVAlUCVQJlglUD1QDAAHLhAQARAjUDtYK1A70CtAO1ArWCtQMRAlEANaEAAAEAPQO9gr0CrwAvAa0CpYK9AoECAAE3YQEAAQIZA8OCWQPBAk8Dx4J1AmUDwQIAADmhEABRAX8BP4G/Ab8BvwG/gv8CvwGRAAAAOyEFAhUBMQHDgjkC9QLtAu0C7YLtAs0CkQA7oQACLQE8gMDBPoJWAtaC/4LXwtaC/oLAAIRhQQAdAzUA9YB9ArUCNQJ9gbUBtQI9AiABBOFAAjEC3wLfgv8D3wHfAf+B3wLfAvECQAIF4UEDPQDFAhWBNQBVA1UAVQF1glUAFQOBAAahQQP9ABUDNYB1A/wAQQEpAEmCPQPJAAAACGFJAmkCJQF3gG0CZQJhA/2AdQFtAwUCQAAI4UECXQHRAHuDwQAVAWQBXQJVgk0DxQBAAErhQQIVARUANYB1An0BfQB9gH0A/QF1AMAACyFBASUB/QHlgQEAFQPdABWD1YAdAd0CIQENYXEDzQA9A92BXQHdAXUDX4ElAf0CDQIAAY6hQQAxAcUAMYD1APUA9QD1gdUBhQE9AMAADyFRABUBMQHBgB0AfQH9Ab2BfQG9A70BwAAPYUUANQPxAfuD8QD1A+ECO4EJAPkBSQIAABDhUACSgJKD+sLSgt4D0oLRgvnC1YPQgEAAkmFJAgkBvQAdgF0DXAB9AF0DXYBdAEUDQAASoUEBnQABAauCEQFVABUA0QGLgiECTQIBANphUQIVAwEAo4AhAX0BfAD9AX2A/QJhAcEAG2FAAAkCHQHdgdwD/AHdAJ2D3QHdAckDwQAcoUEAOQB9AHmB/wB7AEEDP4DTADMD0QAAAB0hUIKYgnSCkcFIg0CCPoPqw+qD6oJ+g8CCH6FAABkACwP7gssC3gPLAvsC64LLA9kAAAAhIUkBEwHRAAWAfQB9AP0Af4F9Af0AfQBAAGHhQABNAGEDwYAtA6wALQOhADeCCwH5AUgCJuFAAD0D1QFVgV0BwQAlALeApQP1AKUAoAApoUEDvQBtAi2A/QLtAO0C/QDtge0C/QHBACphQAA+g86AMMN6gMoCKoKrgq/D6oKqgogCKqFBARUAVwJ3gd0AQQM9ANeAFQA1A9UAEAArIWEAJQIRAUGBfQDtA+0AfQDBgVEBZQIlACvhQACdAPUA9YP9A/UD9AP9A/WD1QPdAEAALCFAgiKDf4F2wHeBf4B3gX+Bd8B/gWKBQAAyYW0BLQC9A+2AZQCBADUD/4K3Ar0CtQPAADNhQAA9AT0B/YF9AfwBQQHXAVeBVQHVAQAAM+FAAl0B0QB9A/2A7QG9AYeD/wEFAfUCBAE0IUUBlQGVAPOCiQHBAD0CVQHXgFUD/QJAATVhYoEqgL6D6sDqgECDvoB+wOqA6oJ+g8AAN2FBANcB1wH/gv8C5gLQAc2BxQHdAqEAkQA5IUEDPQDVAn2DwQBdAX0AH4PZAL0BWQJAADlhQAItAXkBQYF9AGwD7QB1AN+A2wFBAUAAOmFIgRqAwIBNwCyD/IKsgqzD6oK6g+iAAAA+4UCACoMSgMLBeIDvgN2D5cPdgO+BeIFAgUHhiQM5AF8Df4BdA3kBAACVAH2D0wBTAYEAAuGRABkC0QI7gVkAnAI9Av2CvQC9Ab0BwAIEYYCCPoHCgRrBWoPagsKC2oLawtqDyoBCgAthgAAAAD+D/8H/gLgB8AC/gP/BT4A/gcAADiGBAD0D/QGfga0BvQLJA7+AH4F/AN0ARQFToYAAAAM8AMQCFAHfgHUAbQHlAi0CLAEEABPhgAAAAz4AwgIKAk+B1wBXAVMCVwNWAMIAFCGAADADzgAiA+oCr4K3ArcCswK3ApICCgAUYYAAAAP8AAQBlAAfgbUCLQKtAiUArAGAABUhgAM+AMICCgJKAs+DWwFbAtMC1wJWAkIAFWGAAz4AwgLqAaoBj4JXAjcC9wI3AtYCggAWoYAAAAP8AAQClAIfg60CLQOlAi0CpAIUABbhgAAgA9wABALUAp+D1QItA6UCrQKMAgAAF6GAAAADPwDBAiUC38HtgO2A7YH5gcsCgAAX4YgAO4EqgSqAyYG8AEYDDgDXwBaB0oEGAJnhgAM+AMYAd4PvA+MCxgI8gCSCJIIkgcAAGuGAAAABPgEiASIBP4HiASIBIgG+AQACAAAcYYABPQFNAU0BfQHNAUsB+wHBAj8AwAMAAZ5hgAA+ASIBP4D+AIABAQEBAT8BwQEBAQABH2GAAAACNwLVAlUCfQHVAVUBVQF3AUACAAIfoYABPgJjgf+B/gGAAgEAPwPJABEAIQAAACAhiAAFAjKDwgEGALwCIgIiAT+B4gEiAX4B4GGAAj4CYgE/gf4DgAIeASCBQwD4AQcCAAIgoYAAPgE/gOOA/gHAAB0AUQBRAl8DMADAACKhgAA+An+B44H+AYACBgI6gwKB4gDeAQICIyGAAD4BIgE/gf4BgAEKAEoAf4PJAEkAQABk4YAAPgEjgf+B/gGAADyCJIIngcAAP4PAACVhogASgjqCVoJTgnqB0oFSgVaB+oHSgxICJyG+AWIBP4HiAT4BBICIgGiCWII/gciAAAAo4YAAPgJiAT+B/gGAAw8AAIOwAkOCHALIAykhiAEIgTSBVYFWgXSB1YFWgVWB9IFIAgAAKqGAAD4CYgE/gf4BgAMJADIAgAC/g8AAQABr4YAAPgJiAT+B4gE+A4ACPwPIgjiDyIIAADAhgAA+A3IBP4D+AoADMgIygj6D8gIyAgACMaGAAT4Bf4HiAT4BgAI/A8kCSQJ/A8ACAAAx4YAAPgE/geIBPAGCADoBwoJjAiICFgIAAbJhgAI+AX+B4gE+AoAAFgARAJTBkQJyAAQAMuGAAASBMoFSgVSBd4HVgVWBVYH1gUSCAAA1IYAAvgCzgP+A0gCMAP+D2IEkgRiBP4PAADZhgAA+Az+B/4H+AYACCQJJAm/DyQJJAkgCNuGAAj4Bf4HiAT4BgAAXgZIAf4PSAFIAgAE5IYAAPgESAT+A3gDIAC4D6YErASwBKAPAADuhgAEFATUBUQFXAXGB0QFXAVEBdQFFAgAAPmGAAj4Bf4HiAT4CgAA5A9kAvQPbALkDwAA/oYABHgE/gN4AwABlAj8B5AMfgKQBVYIAAYAh0AAXAD0BXQFfAX0B3QFfAX0DTQI/AcAAAKHAAj4Cf4Hjgf4ClAASAVuBdQPbAVEBUAECIcACPgF/geIBIgE8A5MCVQF1ANUBVwJQAkShwAA+AX/B/gGAgi+B0II8AsCCv4LIgoACBOH+AWIBP8HiATwBhoP5gUACCQK/gsiCiIKFYcAAPgEjgf+B4gE+AIwDM4DyA9OCHkIAAYXhwAA+AX8B4gEcAKMD1QAVAH0AVQI3A8AABiHAAR8Av8DxAd4DCsC/AEkA/4FAgL+BwAAHIcAABQEpAekBrQGtge0BqwGjAaUBxQIAAAhhwAA+ARIAv4DeAMABtQHXgVUBV4F1AcQADuHAAD4BYgE/gf4CgAA/A88Az4DPAv8BxAAR4cAAPgJ+ASOB/gGAAj8A7QC9Ae0CvwNAARJhwAA+AmOB/4HiAT4BnAAqgL4D6wC+gIAAEyHAAR4Av4DOAOAAP4PkAAkAAgB/g+AAAAATof4CYgE/geIBHgB4AdeBGoFagVqCP4HAABXhwAE+AWOB/4HiAfwCLwK1ArWD9QK/AqACFmHAAj4Bf4HiAR4AsAHvALUB1YB1AdUAdwHYIcAAPgJmAj+B/gKAAD0D1QK1A9UCvQPBABmhwAI+AT+B4gEcAL+D5ICDghgCWIH3ggACHSH+AmIBP4HiAR4AIAHfwKAD/4DEgj+BwAAdocACPgF/gf4BgAAfA1IA/wPaAN8BUgJAACChwAI+AX+B4gGcAT8B1YFPAL4DwQA/AMAAIOHAAj4Bf4HiATwDgQIVAbcAVYJVAlUBwAAjYcEAPwP7ATsAnwJgAd4AIgI/geIBPgGAAiehwAA+ATOA/4DSAIwAX4GqgL+AaoJggcAAJ+HAAT4Av4DyAJ2A34JWgVaBdoBWgV+BQ4JoocAAGIE6AfuBuQG4AfyBugG7gboB3QIAAi6hwAA+AmOB/4HiATwBR4J6g1+DyoBvgsACsCHAAj4Cf4H+AYACJQC9ALuDtQCBANUAgAAxocABPgCSAL+A0gCMAtkCHYH9AF2A3QNAATLhwAE+AX+B4gE+AQAAlwENAl8CTIAWgaQANGHAAj4Bf4H+AYACPQDdAN0A3YP9AMQAgAA8ocAAKALrAqsB6wHPgisA6wKvAesBqAHAAj5h4QEfAQ3Bb4FtgV4B8oHtgWyBboHNggAAPuHAAT8Av8DRAJ+ATsL2g9+A+oHKwdqCwAJDYgACPgF/gfwBnwPPAO8B+ADMAf+AAgDOAQViAAI+AX+B/gCAgA6D0oH3gFaD2oBag9AAB+IAAD4Cf4HiARwAiYPeAt0APoPUAR+AwAMIYgAANQF3AW+B78Ftwk/AJcFrQesBaQFAAAiiAAAqgWeBf4H/gX+Cf8A/gX+B54FqgcgCDuILAAXBN4FQAV2Bf8HfgVwBWQFvwc0CBIAQIgABPgHCAQIBPwHCgQIBPgHCAQIBPgHAARFiAAA+Af8B/oH+AMCABwBIAH+DyABLAEAAEaIAAggCbwEJAS8AKYPfAEkAiQFvAQgCAAATIiIAEgA5A8SAAAAJAAkACQIJAjkDyQAIABNiIgARADzDwgAIgwiAoQBIAgiCOIPIgAAAFOIQABEAPMPCQDIAf8HCADDBRAE8gcSAAAAVIgAAMwA8g8YAIYI9QeUBAAAJAjkDyQAAABXiEAARADyDxkCUALeA1QCVAYABPIHEgAAAFmIAADIAOQPAgBUD3wFdAdkACQAJAjkByAAW4gEAEIA+Q8IAPoD3wLaB/4CAgDyBxIAAABdiAAAJADyDwgAeglaCf4H+gUJBCAA5A8gAGGIAABEAPIPCAn4Ba4D/AOsDfgBAAjkDyAAYogAAIwA4A8cALwHnAeYB7wHvAQAAOQPIABjiIAAiABICMgPKAgaBDwEyACIA0gEKAgACGWIAAAIAYoA6g+YAEgBAAD+DyAAQADAAIAAaIggATQJtAS0B3QEPgT0BDQBtAK0BCAIAABpiAgBiADuD5wAQAkcCOQEFAOEAnQEDAgAAGuICAGIAO4PnABIAQAIiARIBEQCMgIQAQAAbIgIAYgA7g+cAEgBAADQABAJEAj+BxAAAABwiBQBFAV8BVwH3AReBNwEXAFcA3wFFAUQBHeIAAAEAnQCVA5UCfYIVAlUAlQGdAkECQAAgYgAAhAC9AK0DrQJvgS0AbQCtAZ0BRAJAAiEiAQBhQD3D44AZAEADCICogF+AKEDIQQgBIuIkAKIArwKgg6ICcgIjgmYAqoGygrKCqgIjYgAAYwA7A9YAQAA8AcsCSgJ6AsICvgJAASSiAgBiADqD5gAAAj8CSQJJAkkCSQJ/AkACJaICAGIAOoP2AAAAPgPiASIBP8HiASIBPgPnIgAAYoA6g/YAAAESAJIAf4PSAFIAkgEAACriAgBiADKD7gBAAz4A8gISAl+BkgGyAkYCK2IhAKkAqQKlA6MCaYIvAnWAtYG1AXEBbQIsYgAAYgA6g/wACAA/A8CABAH/gCQAxYMAAC0iAgBiADsD5gAAACoALgDrAKoCpgKqAagAMGIAAFUC9QHXgRUAVQDEAz+AhAD0gQUCAAGwojWAtYC3gquDp4JxgSAAZ4CwAbABf4JAAjFiKACrAKQCrwOgAmoBKgBvAKoBqgEqAgAAMaICAGIAO4PnABIAQAELAUgBT4FIAXsDwAAz4gABEQFfA18D3wJ/gl8A3wFfAV8C0QLAAjUiBQA1A90APQHbAVkBWYFzAbUAKQPJAAAANWICAGIAO4PWACIAAABxA+yCIgIsgjED4gB2IiABKwCrAqsDoQJ3gSEAaYCrgasBKQIAADZiAABiADrD9gAgAIqAeoHvgSqBKoEvgcIANyICAEIAc4PuAAAAOgPqAKoAv4PqAKqCuoH3YiQAr4CmAqYDr4JgASoBKgBvgKoBqgEiAjhiAgBiADsD9gAAAB8CVQJVAn8D1QJfAkAAOSIAAGKAOoP2AAADPwDRAC2ApQPlAKUAgAA84gAApwEhQK2DrQJ9gS0AbQCtgaFBJwIAAD4iAgBigDqD9AAgAT8BNQC1A/8D9QB/AKABPmIgAJEAnwBfAf8BP4EfAF8AnwCfAXEBAAA/YgIAr4CnAq+BpwF/ASAAZwCwAbABb4JAAQCiQAAxAD1D2wAAASUBN8HlAQAAP8HIABAAAeJgABIAO4HeAAABT4F/gW8ArwCvAW8BAQEEIkIAYkAyg+4AAABvgeqBKoFqgaqCL4HAAASiSACFAL0AgQOZAl8CT4JfAI8BnwFJAkABCWJAAGIAMwP+AAADvwBdARcATwJ3A8cAQAAKokAAIgB7A/YACAI7AcACPwLVAhUCXwKAAgyiQABlADUB7AAAAT4A+gD7AP4B+gD6AMIAkSJQAXEBfwD7A/8CcYJ/APsBewF/AlECQAAX4kAAIgA7g/cAQAJTAVeAVAPTAFeBVQJEAByiQAFDAV8A34PfAt8CQAJfgP8BfwL4AtACX+JBAD0D5QE1AQ8BBQEFAR8BJQElAT0DwQAgYkAAIIIugiqC/4GqgSqBL4GqgWqBLoIgACGiUQBXAG8D1wA3AjsC/wH/Af8B/wLPAgACIeJAgBeB9YH1g/eB1YHFgz+A7YCtgr+BwIAi4kACAAI/AlUBVQDVAFUAVQHVAn8CQAIAASPiUgISAT8A0gBSAoACPwFVANUD1QJ/AkABJOJAAgMCPwL5AbkBuwC5ALkBuIK+gsCCAAElokIAYgAzg+4AAgJAAj8BVQDVA9UCfwJAASaiQAIOAgKCOwL6AbqAuwC6A7sCwoIOAgABKeJAAg8CPwL/Af8B/wDwAPsB+gL6AsoCAAEqokAAKQErALmD6wCoAj8BVQDVAFUD/wJAASziQAAMAHsB7gH6AeoB/wNVANUAVQH/AkABLqJAAAwCB4I3gvQB9oD2gPYD94LHggwCAAEvYkACD4I7gv+B+4H7gPAA/YH/Av8CzQI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AAAAAPwProsgACQI7A8ABAQCeAiCBQwCgAV4CAQIAAiviyAAJAjkBwgCQAJEAPwPRAAEAPwHAAgABrCLIAAiCOQPCAQAAMQHRAhECEQIRAj8CAAGsosgACII5AcAAogIiAT+A4gAiAD+D4gAgACziyAAJADoDwAEiAKoAKgA/g+oAKgEiAMAALaLEAASBvQBBAWADDoCIgGiCGII/gciACIAuIsgACIA7A8ABLAAjgCIAPgPiACIAIgAAAC5iyAAIgjkBwgCYAD4DwYAgAD+ByAIGAgIBrqLIAAiCOQPCAIgAJAHCAmGCIgIkAggBiAAvIsgACII5AcIBGAAGA6GBWAEBgUYB2AIAAC9iwAAJAjkBwgCAAz8AyQGxAEkAvwHAAgABL6LIAAiCOQHCAIgCqAIXgVCAkIGfgXgCCAIv4sgACIE7AcEAgAICAb4AUoISghICMgHCADAiyAAIgTkBwgCQAlIBEgD/gDIA3gEQAgAAMGLIAAiCOwHCAIACOQPBAgECPwPRAhECAQIxIsAACII7AcEBIACugCCAP4PggCyAIoAAADFiyAAJAjoDwgEAAD8DyQJJAkkCfwPAAgAAMaLIAAiBOwHCAIACHwGRAFEAEQARAF8DgAIyIsgACII7AcIAmACEAAOAPgPKAEoASgBKAHJiyAAIgjkDwgEAAD8DyQAJAHkDyICIgIAAMqLIAAiCOQHCAQAAlAISAkGBcgEUAIQAQAAzYsgACII5AcABgIA6gMqASoB6gkCCP4HAADPiyAAIgTsBwQCIACiD5oEhgSiBKIEngcAANGLIAAkCOgHAAIkAqQCrAKUD7QCrAIkAgAA1YsAACII4gcCBAgASATIBwgC/gAIBwoMCALXiyAAJAjoBwgCoACoAqgCvAioCOgHqACgANqLAAAiDOwDAA74AygAKALICX4EiAfqCAgG3YsAACQI6AcIAiAApA+kCPwIpAikCKIPIADeiwAAIgjsBwAAsg0uA8IE8AkCCv4LIgoCCuGLAAAiAOwPAAD4DxYA1AdUCFwK0AkQCAAE4osgACQI7AcABBAAyAOuAqgK6AsICPgHAADliyAAIgjsDwAEJAG0CKwEZwQkBhQFhAgAAOaLIAAiCOQHAAIIAEoBSgH4D0gBTgEIAQAA54sgACQI6AcAAhgACAEoAe4HqAiICJgEAADriwAAIgjkDwAA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gAT/BJgEmA8YAL+MAAQQBPwF9APsA/AB9AHsA+QD1AUMBAAAwIwAABQIzAvmCvQK7ALgAv4K8gryCx4IAAjDjBAACADcA8QL4AvqA+oD/gvqC+kDKgAAAMSMAAj8DVQFVAH8BUAA+A+sAqgCqAroBwAAx4wQCBII9Av0BuQG9AL2AuwG9Ab0CxQIAADKjAAI/A1UAVQF/AFIAOgJSAR+AogFbAgIBtOMIAAsCOwH/AbsAv4C7AL8AvwG/AcMCAAI24wAABwIzAXuBewF7AHgAfwF7gX8BRwIIADcjAAI/A1UAVQF/AUAAb4C6gmqBKoDvgiAB96MAAAcCMYP9g30DfYF9AX0DfYNxQ8cCAAA4IwACPwFVAVUAfwFIAC0B6QEpgSkBLQHJADijAAIPgj6B/4H+gf6A+AD4gfaB5oHJgggAOOMAAQ6CO4H7gf+B+8D7gP+B+4H7gc+CAIA5IwACPwFVAVUAfwDqAjsBBgH2ga8CbgJEATmjAAI/A1UAfwFAAjUDxQI0AeQBP4DEAwUBuqMIAAcCMwL7Ab6BvgC7gLqBuoG2gsKCAgA7YwABPwHVAFUA/wFAAGkB/4FpAW8BaYHIAD0jAAEeAJYAfwPWAE4AMAL7ArkAvQG7AcACPqMAAD8DVQB/AIICGwF+A9oAfgPbgPoBUAI/IwACPwNVAFUA/wGwA/sAv4C7Av+CuwHIAL9jAAArAh8BPwH/AP+A/wD/AP8B7QEpAQAAAiNAAj8BVQB/AUAAPwP5wrkCvwK5ArnD3wACo0AACgI/g9eDVwFXAV8BV4FXgXsDxwICAgPjQAMggO2CjoHugm7A7oFOgC6B7oPCgQAAB2NAAAACPwJBAQEBAQC9AEEBAQE/AkACAAAHo0ACAAI8AsQCBAEHgLUARQEFAT0BQQIAAAfjSAIEAj4CRQIFgQUAtQBHAQQBPAJAAgAACGNAAAUCNQLVAhUBlwBVARUBFQI1AsUCAAAIo0ACP4JAgT6AwIA/g4AAAgDiAhoCP8HCAAjjRAAFAjcC1wIXARcA14AXARcBNwFFAgAACSNAAAeCMAFQAReAkABZgRaBFoI1gsSACAAJY0ACP4IAgb6Af4MAABwCI4EiAN4BAgIAAAmjQAEfwf5AAEC/wIACP8HIAToACYDIQQAACeNAAAICMQLXghBBkQBTwRUBFQI0gsKCAAAKI0AAPAHDADsCSwELAK8ASoEKgTqBQgIAAApjQAAfA/0AAQC/AAADvwBNAzUAhQD8gQECCqNCAAICNQLVAhSBFoDUgB0BFQE1AUECAgAK40IACgI7AtqCFoESANoAGoEXATEBQgICAAsjQAI/g3yAwIC/gAADCQCIgYqCeIIIQgACC2NAAj8DeQDBAD8DhAAzAEKAcgJCAj4BwAALo0AAPwJBAT0AwQA/A4QAAgEDgQIBAgEOAQvjQAACAj8C2oIagZ+AWoEagRqCP4LCAgAADCNAAAoCLgJuAS4ArgIuAsICP4BCAYOCAgEMY0ACPwIBAb0AfwCAAhQBP4EUAdUCVAJAAQ0jQAI/A30AwQA/AYAAIAP/gSIBIgEiA8AADWNAAAgCPwLdAh0BHQDfgB0BHQE/AUgCAAAN40QAAgI3AtCCEgESANOAFgEagjiCxQAAAA4jQAAAAjcC1IIWwRAA1IATgRiBOIFHggAADmNAAhACN4LdghfBFYDVgBfBFYE1gUWCAAAOo0AABQI1AtOCGQGXAFABFwEVAjUCxwAAAA8jQAE/AL0AQQE/AAABugBCAh+BIgH6ggIBj6NAgg6COoFagR+BGoDagB+AmoE6gU6CAIAP40AAPwN9AMEAPwFwAD4D64CqAKoCugPCABBjQgABAjfBUAEagNqAGoCfgJqBOkFKggAAEKNAAj8BuQBBAT8BAAAyA/WBKQE1ARMD0AAQ40AAPwN5AP8DAAM+AMICEoI6g9ICEgIAABEjRAIEgjUBUAEaAJmA1YATAJUBNQFDAgAAEqNAAD8DeQDBAD8DgAAUANoCOYPaABIBxAES40AAPwN5AP8AAAI1A8UCNQHEAD+AxAMFgZMjQAA/A/0AQQE/AWAANQPfgVUBVgF1A8QAE6NAAj+BfIDAgD+BQAApAlUB/4BFAU0CQAAT40AABwIhgu0CLQEtgK0ALQEtgSFBRwIAABQjQAI/AkEBPQDBAD8DgAAvgDqC6oGqgm+B1SNAAj8B+QBBAT8BQAAqA+kBKYEtASkByAAVo0ACPQElAL+D5QB9AoACPgH1gMcCPQLAAhYjSAELgSeBV4EXgJeA0gAbAJeBJwFJAQkAFqNAAj8DeQD/AAACFoF/A9YAfgPXgX4CUAAW40AAKwIvAj8BbwEvgK8ALwE/AW0BCQJAABejSAALgicC04IfARAA24AXAROBJwFLAgoAGCNAAB+BAID+gACAn4AmAd/BXwFfwX8BwAAYY0AAPwN9AP8DAAA+AcOAOwPzAvIC9APAABijQAM4gO+Cv4H3gw/A/4M3gc+Af4PBgQAAGSNIAKkAaQIJAbkAT4IJAjkDyQApAAgAwACZo2ACSQE5AM+COQHJACACTQEygKIA3gECAhrjYAJJATkAz4I5AekAIAH5AE+COQHJACAA3CNIAgoBKgDKAQoBPwPKAkoCSgJKAkgCAAAdI0QBtQBFAL+A1QEVARQBAAE/gUIBBAEIAR1jRAG1AEUAf4DVARUBAAFzAQwBEwEggUABHaNIAykAyQE/gekCKQIAAgkCPwLJAgkCAAAd40QCNQHFAL+B5QIlAgACOQJJAokCjwKgAmBjRAG1AEUAf4DVARQBAQFUgUiBaQEiAQIBIWNAAjYBxgE/AeYCBAI1AtMCmQKZArcCwAIio0gDKgD/AeoCAAI+AmICAgKfgnICioKAAiLjSAGqAEoAv4DiAQgBBgFVgVUBVwF9AUABJWNIAaoASgC/AOoBQAFXATcBNwF3ATcBAAEmY0gDKgDKAL8B6gIAAj0CzAIvAiQCvQJAAifjQAIpAckAv8HpAgECPQLkAheCZAI9gsACKONFAAUBJ4D9AMQBP4EqgT+BQAE5AUcBQAEqI0QDNQDFAL+B5QIpAjvC14JSgluCN4LAACzjQAAAAg8BKQDJAQkCOQPJAkkCTwJAAgAALSNAAjeBxIE8geeAAAO/AEAAAQA/AAABwAIvo0ACN4HEgTyB54AAAj4DwAI/g9ACEAIAADDjQAI3gfyB5IEngQAACQMIgP+ACIDIgQgCMuNAAieDxII8geeDAAICAf/AEgLSgbKCUgAzI0ABN4HEgTyA14CAAhOBEgD/gBIA0gESAjRjQAE3gcSBPIHngQAAPoHtAj0CgQK/AkABNuNAASeDxIE8geeAAAM+APICX8GSAXYCAgI3Y0ABNwHFAT0A5wCAAD8DxQFFAUUBfQFAATfjQAI3gcSBPIHngAACPwPVAjUAVQGfAUACeGNAASeB/IHkgQOAuAM+AMOCPgHCADoAQAA6I0ABJ4H8gfyB44EIAC4A6gKrAq4CqgGqADqjQAAHgfyB5IEPgz4BxYA1AdUCFwK0AkQBO+NAAjeBxIE8geeBJAAiA/WCKQIvAjED4AA840ACN4H8geeBAAA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dAV0BfwPIASTjwAAfAJGAvQPIAD4D7QC8g+UARgI8AcAAJWPRAB0Ak4C5A9AAhAC9A60Cb4JtAJ0BRAJlo8AAHwBRgH0B0ABFAC0B7QF9gW0BZQHgACZjwAAdAJOAuQPFADuB7QK5A90BIoDeAQACJuPIAAkASwBPAEkAecPJAE0ASQBJAEgAAAAnI8AAEIFXgVWBdYFVgV3D1YF1gVeBQIFAACejwQAkg+SBP4EkgcQAEQBdAHGD3QBRAFAAJ+PAAT8A6QPpAS8BwAAWAFIAc4PaAFIAUAAo48AAEQJVAnHB3QBBAjwBJQC/g+UAvQEAAimjxAIzAfoAUAIEAf+AOAPCABaAcYPaAEAAKiPRABVCcYHdAEACHAG/gEAAFQBxw90AUAAqY9EAFUJxgd0AUAADgjkBwAAVAHHD3QBQACrjwgAWgnsB0ABHATyBIgEAARVAccPdAEAAK2PBADMD1IBegfWANYPAABUAccPdAFEAQAAr48IAFoJ7AdIAUgPawVoBwwAXQHvD0wBAACwjwAAAAz8A0QA1A9UCFQE1AFUAlQFVAlACLGPAACAAn4CIgbqBqoCKgpqCqoG6gJiAwACso8ADPwDbAnsCf4H7AnsBf4H7AXsBfwLQAm5jwAIIgTsAwgEAAgIC8gIPggICggK+AkABLqPQghGBMgHAAQECMQLPAgECgQKBAr8CQAIu49ICFIE1gMEBBAIEAgQCP8LEAgQCBAIAAi8j0IIQgTMBwAIAAqCCWIIPgjACAAJAAoAAL2PAAgkBOgDAAQECAQKBAr0CxQIDAgECAAAvo8gCCIE7AMABAgICAvICD4ISAiICAgLAAjBjyAIJgToAwAEJAgkCCQI/AsiCCIIIggABMKPAAgkBOgDCAQgCCQKJAr8CSQIJAgkCAAAxI8gCCQE6AMABDAECAmsCmgKKAooCggJAADFjyQIJAToBwAEJAgkCPQLJAgECPwJAAqACcePIAgiBOwDAAQICCgIyAgICggK/gkICAgIyI8kCCQE6AcACAQLxAg8CBQIFAoUCvQJBATOjwAIRgzIAwAE/AkECQAI/AsECAQJ/AgAANCPIAgkBOgHAAgQCtQJNAkUCVQJlAkUCgAI0Y9CCEIExAcACAAL/ggSCBII8gsSCBIIAADUjwAIQgTMBwAIAAv+CDIK0goSCdIKMgoCCtiPAAgiBOwDCASACEQIJAj8CwQIJAjECIAI2Y8ACCQE6AcACCgKKAnKCEwIuAgICQgKAADbjyAIIgTsAwAESAhIC/4ISAhICP4LSAhICNyPIAgkBOgHAAgQChQJ9AgUCPQLFAqQCQAA3Y8ABCIE7AMABFQEVARUBP4FVARUBMQFAADejwAIIgTsBwAEFAksCSYJ9AskCSQJBAkAAN+PIAgkBOgDAAQACfwIJAhkCOQIJAk8CgAI5o8ACE4EwAcEBfwEBgj8CwAI/AsECvwLAAjqjwAIJAToBwAI+AtICkgK/gtICkgK+AsAAOuPRAhEBMgHAAQACPgLSApOCkgKSAr4CwAI8I9CCEIEzAcABIgJaAgICP4LCAhqCIoJAAj0j5AI1AS0AwAE/AkECvQKlAr0CgQK/AsAAPePQghGBMgHAAgkC6gIYAj+C2AIqAgkCwAK+Y8ACCQE6AMIBGAICAv6CAwK+AsICOgIAAD9j0IIQgTEAwAE/AlUClYKVQpUClwKwAsACACQQAhCBMwHBAgACv4LKgpqCKoJXgpACgAAAZBCCEIEzAcABEgITgpICfgISglKCkgKAAgCkCAIJgToBwAEFAjUC1QKfApSClIK0gsQCAOQAAhECMgHAAScCEAK/gkACP4JQAqcCoAKBpAACE4MwAMIBOoIjgqICvgJiAiOCOoICAgJkAAIJAjoBwAIIAqsCWgIPgjoCygKKAogCQqQAAgiBOwHAAQiCPoLRggwCv4LAAg4CMAADZAAAJII9AaUBQAI9gsQCF4JEAmUCvILAAgPkAAIJAjoBwAELAgsC9wIXAicCqoKqgkgCBCQAAgiBOwDAAQSBaoIrgpSCuIJUgiKCAAEEpAgBCIE7AMABHQFVwXUBPwFVgRVBdwEAAQUkAAITgTABxAESAlUCFQK8glUCEgJUAkQCBeQAAgkDMgDEAQECHQK1ApUCtQL9AoECgAIGZAAAFQEfALYAwAE+AV4BXwFeAX4BQgEAAQakCAIIgTkAwAE+gmuCK4I+guuCK4K+gkAABuQAAgkBOgHQAguC/QIAAokCvwLJAokCgAAHZAACCYI6AcACEgK/gkICPwLEgjyCxIIAAAekAAA0gi8BpgFAAi8CrQK9Au0CrwKAAoAAB+QQghCBMwHAAh0ClQJ1Aj+C9QIVAl0CgQKIJAACCQI6AcABCAIrAuoCrwKqAqoCyAIAAAikAAIJgTgBwQIlAqSCq8K6guuCqoKCAoQCCOQAggmBOQDAAR8CVwJXAn+C1wJXAl8CQQJLpAACE4IwAcQCJQKVApUCP4LVAl8ChAKAAgxkAAIQgzMAwAE/gkCCOoJegnqCQIK/gkACDKQAAhGCMgHAAQQCP4LqAr8C6oKqAoICgAIOJBCCEQExAcQCHgKVgnWCHQI3AtQCnAKAAE7kCAIJAToAwAEnAhUCnwKVAlcCdQIHAgAADyQJAgoBOgHgAt8BWwN7A9sDWwN/A8ACAAAPpAACCIM4gMIBOgF/Aj8CwsI6ggEDOgPCABCkAAIRgTIAwAEKAluCdgIqArICa4IqAgICUWQQAhEBNgDAAX8CBQI1AnUCdQL9AncCQAIR5AACCQE7AcACP4Lagj+CX4Jagt+DMAPAABKkAAIRgzAAwQF/AgXCuQJDAhGCvQLVAhECEuQAAgiDOQDAAR6CXoJegn6C3oJegl6CQABTZAACCIE7AMABfwI1Au0CPYLtAj0C7wI4AtOkAAIQgjMBwAI4As+COIJegnqCT4I4AsAAE+QAAQiAuwDgALcBTwFvAW8BTwFPAf8BwACU5AgCCQE6AcABAgI+gu+CrgKvgr6CwgIAABUkAAIRgTIAwAE1An0CdQJ3gvUCfQJ1AkQCFWQAAhECMgHAAj8CtwL3AreCtwL/AqICgAIV5AACCIE7AMABO4IagpqCX8IagrqCi4IIARZkJAI9gaQBQAIuA6kDrwO9g+sDqwOpA6ACFyQAADRDLYCEAVCBPoJBgpcCPYLQgjBCgAAXpCQCPMEFAOABH4IAgvyCD4Kfgh1CXUKMAFgkAIIQgjCBwgEfAlcCdwI3gtcCfwJiAoACGOQAghCDMQDEAT8CfwK/Ar+CvwK/AqQCwAIZZAACCQM6AMABEwJfApkCuwLZApiCmoLQABokIAI1ggwBwQG9Al+DVQNRAsQCI4LeAoICmmQAAhGDMgDAAT0CTQI/Al2CfwJNAr0CQAIbZAACBEE9gMABP4Jvgq/Cr4Kvwr+Cx4IAARukAAEJgLoA4ACfAQUBXQEVgZUBXQEFAUAAHKQkAjUBLQHAAb8CQwItAqMCtwLjAq8CgAKdZAACCYI6AcABHwJbgtsCWwJfA3+D3wJBAF3kIAI1AS0AwAF/AjsC/wM7A78D+wMfAkACXiQAQgmBOQDgASuCu4KrgigCO4KrgquCggIepAECEQExAMQBPwN/Av8Cf4J/Av8CxAIAAh/kAAARAzIAwAF/AtUCtwLCAi4COwLtAioCICQAggsDOAHTAb8CX4JXAsQCA4L6AgYCwAIgZCQCNYEsAcACIQL9An+CfQJ9An+CPQLAAiEkAIIRAjEBxAEfgl6Cf4I+gt+CfoJngoQCIqQkAjWBLAHwAj8DfwLfgt8D/wP/AvACAAIj5AAAKQM6AMABPwPVAucC9QL3AvUC9wLAAqRkAAAAADcB1QJVAnUCVQJVAlUCdwJAAQAAJOQAAAUBCQCxAE0AQwCAAD8DwQAdAKMAQAAlZAAAAQA+gfQCtQK2gvQCtQK2gr6CwAIAACXkEAARABEAPwPRABEAAAA/A8EAHQCjAEAAKGQCAgIB/gALggoCOgHAAD8DwQAdAKMAQAAopAACEQO/AFEAEQA/AdEAAAA/A8EAHQCjAGjkCQAJA38AyQJJAn8BwAA/A8EAPQCDAEAAKaQgACkDKQD/wCkAKQAAAD+DwIAegKGAQAAqpAAAAQGNAGkCPwPJAAAAPwPBAB0AowBAACukAAA+AdIAv4DSAL4BwAA/A8EAHQCjAEAAK+QCAD+D0gESARIBP4PAAD8DwQAfAKEAQAAsZAABPwHJAQkAuQDJAIAAPwPBAB0AowBAACzkIQERAQkBPwHJALEAgAA/A8EAHQCjAEAALWQIACiD54EggSiBJ4HAAD+DwYAdgKMAQAAuJAAAv4JIgkiCX4IogsAAP4PAgB6AoYBAAC5kAgAGASUBJMEkgSeBOAP/gMCADoBxgAAALuQEABQAUgDVg7ICVAAAAD8DwQAdAKMAQAAwZAAAMgA+A+sAqgK6AcAAPwPBAD0BAwDAADKkEgEKASoAgwBqAEoAgAA/AcEAHQCjAEAAM6QAAT8B5QClgKUAvwEAAD8DwQAdAKMAQAA0ZBACEoESgP4AEgBTgYAAPwPBAB8AoQBAADTkAAAlgLyApoC0g+SAgYA/A8CAHoChgEAAN2QIACkCCQG/gHkD6QAAAD+DwIAegKGAQAA4ZAKAioB/g+qBKoEvgcAAP4PAgB6AoYBAADokCAAqA+kBKYEpASoDwAA/A8EAHQCjAEAAOuQAAB8AdQBfgFUB3wBAAD8DwQAdAKMAQAA7ZAEAvQC1ArWD9QC9AIAAPwPBAB0AowBAADvkAAApAikBBACzgMQAqQN/g8CADoCxgEAAPSQgAFIAP8PKAHAAP8PKAAAAP4PAgB6AoYB9ZBMCfwJTAn8B0oF+gUAAP4PAgA6AsYBAAD3kJgI3AajAQAE/gdSAn4DAAD+DwIA/gMAAPiQAALwArYC8A++AvACAAD8DwQAdAKMAQAA/ZAAAJQA1A9+BVQFXAXUBwAA/A8EAHwChAECkYAAvAC0C7wKqAq0BrwAAAD8D2QEnAMAAAmREAncBDIDgAD8B5YE/AYAAP4PAgD+AwAAGZEQANcH1QT9BdUFVwTQBwAA/g8CADoBxgAnkSgAGgjaClYJQA2+CUAA/g8CAHoChgEAAC2RAAr0CxYHvAM8C1YL5AP8DwQAdAKMAQAAMJEAACgJ7AaIA74BiALcD4AA/A8EAvwBAABMkQAA+g9+BD4FSgT6DzAAzggICQgI+AcAAE2RAAD6Dz4FOgVOBfoPAADiByIIIgh+CAAGUpEAABkEowMAAPkPSQU/BQkFPwVJBfkHAABXkQAA+g8+BX4F8g/4A4wFcASOBPgPAAAAAF2RAAD6D34FPgVKBfoPAAAkB+QEJASkByAIY5EAAPoPPgV+BfoPAAD+D4gEiAT+DwgAAABlkQAA+g9+BT4FSgX6DwAApAH8D6IAIgMAAGqRAAD6Dz4FfgX6D5gAxA+uCLwIxA9AAAAAbJEAAPoPfgU+BfoP8AD+ByAA/gcgAP8PAABxkUAAwg/UDtAO3g3ADOgM5g3WDtQOzA9EAHWRAAD6D34FHgX6DwAAKgEvCboPbAEqAQAAd5EAAPoPPgV+BfgPPAOqBKgEvgSoBwAAAAB4kQAA+g8+BX4F+g8AASwFmgW4AqwFKAgAAH+RAAD6D34FPgX6DwAA/A9UBNYAVAN8BAAEh5EAAPYPPgV+BfYPAAC8CqwKrg+sArwCBAKJkQAA+g9+BT4F+g8AACQBFAHGDzQBZAEAAYuRAAD6D34EHgX6DwAA5Ad/BWQFfwXkBwAAkpEAAPoPfgU+BUoF8A+eCKoKqg+qCr4KAACckQIA+g9+BD4F8g94CFQH/gDUB/wLAAQAAKuRAABeAPoH/gXuBv4GvAb2B9IH9gdUAAAArJGQALwPmAu+CYANuA28DZwP3A/0C5QPkAC0kQIA+g9+BD4FSgS2D2oI/w3qCv8K6w7+C8eRQARUAlQCRAHMAOQPxABiAXICSgJABAAAyJEAAJYBUgD+B1UAAAb/ASEA4QAhAz8MAATKkQAAKgOiAP4PowCqAKACrgKSD6oCpgIiAsuRBACsAfwPogCoAD4C+gK+AroHvgL6Ai4CzJEAAAAEvgSqBKoEqgT+B6oEqgS+BAAEAADNkQAAEAT0BfQF9AX8B/QF9AXyBfIFEAQAAM6RAAB8CVQJ/AdUBXwBAAgkCPQPLADkAAAAz5EAACAE/Af8B/wH/Af8B/wH/Af8ByAEIADRkRAAsAiQCZgLlgjxD5IIlAiYCpAIMAgAAN2RUAhYC1QI8gdUBEQFAAAgAP4PIAAgAAAA45FQCFgLVAjyB1QERAUQAM4ICAkIDPgDAADnkUAIWAtUCPIHVAYADP4DAAD8BwAA/g8AABWSUAhYCfYHVARUAQAIRAj8D0QIxA98CEAAHpJQCFgLVAjyB1QEWAUGASUJJAkEBfwDAAA0klAIWAtUCPIHVAUQBEgA1w9SAEwE0AcQAESSUAlcCPIHVAREARAETgRIA/4ASANIBEgIcZJQCFwJ8gdUBAAN+AMIAAgH7gQIBIgHAAh0kkAIXglAC2AJXgnQD1YJZA00CVQJRAgAAICSUAhYC1QI8gdUBwAA/g9KCMoBSgZ+CQAIg5JQCFwJ8gdSBAQNZAQ0AywAJgC0DzQIRAaFklAIXAnyB1IEhAT+DwIA6gMqAcII/gcAAJiSWARUBfIHUgREBRACGAGUD+YEnASEDwAArZJQCFwF8gdUBFQBAAioBP4FqAaqCaoIAAazklAIXAX2B0AFEAD8BJIGkAGSD/QIGAgQBLeSQAhQCVwE8gdEBggN9gcQAF4BEAn2BwAA0pIAAFAIXAXyB1QFAABIBa8Fkg+uBaIFQATqklALWAT2B0gEWAUIAOgPqAL+D6gC6g8AAO2SUAlYBVQE8gdUBAABegzMA0gAzA96CAAG/JIAAFALXAjyB1QH/AsMBKQD5AMMC/wHAAAEk1AIWAn2B1QERAUABNgCVgjUD3QATAVABSKTUAhYBfYHVARUAQAIKAmeBRgHWgcqC6gIJpMoBC4F+QMqBioHgAe+AOsPqgCqBL4DAAArk1AIWAlUBPIHRAcABL4E6gOqBqoJvgcAAC+TWAhUCfIHVAQEBSQA/gdkBWQFfgXkBwAAMpNQCFgJ9gdUBAAFogQqAOoPqgEqAr4CoAQ2k0gLXAjyB1QERAEUAFQP1Ah+CNQDVAVACUqTWAhUCfIHVAQEBfQEtAKUAf4PtAH0AgQES5NQCVgI9gdUBQQA4A8+ALIDqgI+CeAHAAB1k0gIXAnyB8QHMAwuA+AEqgb/C6oKvgoICH6TaAhsCWoE+QdqBwIM/giuCv4Prgr9CgAIjJNIBM4E+QdKBewFrQL+D6wA/A+vAvwEAACWk1AIWAhUCfIHVAQACfQLsAq+ArAC9gsACK6TQAhQC1wI8gfUBQAA/AvsCu4C7Ar8CwAK4ZNQCFgIVgnxB1IECg3qCG4HawFuD+oJCAQYlFAIXAXyB1QFAADyC3oLcwvzD3ILfgvyCzWUMAhaCvwHHAd0ALQHvgdUDP4FEAfWCAAGUZRQCFwJ8gcEB34Aqg/uCboPAAlOD0gJSA9wlAgIXAnyB0QFCADoD8QHkgL0D4QCaA8AAH2UUAhcBfIHVA0ACBgI3gXcA9wL3gusCygAiJSYAIYI9Q+UBIQEIAAgACAA/g8gACAAIACJlAAAmACGCPUPlASUBAAABAgECPwHBAAEAJOUAACYAIYI9A+UBKACHABKAIgJCAj4BwAAmZSYAIYA9Q+UBJQEAADyAIIA/giSCJIHAgCdlJgAhgj1D5QEAAToAQgBCAH+BwgJCAnoDZ6UmACGCPUPlASEDIAIOAgABP4DgAEIADAAn5SYAIYI9Q+UBAQE8AGQAJAA/g+QAJAA8AGglLgAhgjlD6QEBADwDxACkAF+AJAJ8A8AAKKUmACGAPUPlAQAAP4PAgIyAfoBAgj+BwAApZS4AIYI5Q+kBKQAAAz8AyQBJAkkCfwPAACmlAAAmACGCPQPlASEDDAIDgboAQgDOAQICKeUmACECPYHlASEAhAATgJICUgJCAz4AwAAqZSYAIYA9Q+UBAQEEAHuAQgJyAsICPgHAACulJgAhgj0D5QEhAwACEIO/glCCEIO/gkACLGUmACGCPUHlAQAAsgISAT+BEgHKgmqCQAEs5SAAKwI6geoBIACEAD8D5AEkASQBPwPEAC7lJgAhgT1B5QElAIEAIAPgAT+BJAEkA8AAL6UmACGCPUPlAQABP4BkgCSAP4PkgCSAP4BwZSYAIYI9Q+UBBQEwADODMgC/gFIAkgEQAjDlJgAhgj1D5QEhAQQAEgBVgJEDcgAEAAAAMWUmACGCPUHlASUAgAAvg+CBIIE/gTADwAA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AAT+AtAI3gfQAPYCAASblgAA/w8ZAO8AbAa3AK4EoAenALgCrgIiAJyWAAD+DwIAOgHGABAC9AL8AvYP/AL0AhACoJYAAP4PMgDOCQQEbAFkDWwJZAtyCeoBAAyjlgAA/g8yAM4AAAnuBZgDvwCYA+oPqAIAAKeWAAD+DzIAzAhABLYHgASqCfgMyAvOCCgJqJYAAP4PMgDMCOIHFATUC+wI7gl8DewPBAiqlgAA/g86AcYIUAS4AvQAEwj0BrgE6AwIALGWAAD+DwIB/gDADfYB8gf6C/IN+QH1DaAItpYQBFQFVAVUAlQK/gdUAVQCVAO8BJAEAAC7lhAIEAl4CXwJeAd4BXwFeAV4B3gJSAgACL6WAAAUBqQB5AAcAyAA/g+oBPoHqASoBAAAwJYAAFAAWADED+AK3grwCvAPxArECtgKEADBlgAG/gFCAPoHAgAiAPoHUgX6B1IFUgUAAMSWCAzoAx4IyAcIBCAD/AeqBKgE/AeqBKgExZYkBrwBZAj8ByQA8A+uBKgE/geqBKgEAADGlggICAV8BV4DXAPcD34BXQNcBVwFRAkAAceWAAAEDvwBrADsD+wK7ArsD+wK7Ar8CgQIzJYAAPAPAAT+BwAE/gcwAv4PqAT6B6gECATPlhAAuASmBLQE7A8gAPgPrgSoBPoHqAQIBNGWJAC0BI4ChA+8AkAEMAD+B0gF/AdKBUgF1ZaAD3wANAe0AjQJ/AcwAPwPqgT0B6gECATWlgAA7gSqBPoDrgLgBjAA/g+oBPoHqASoBNmWAAAICL8EvAS+BbwGiAK+ArwFvgW8BCQE3JYgAKQGlADGD7QCAAD+D6gEqgT6B6gEqATelgQIfAl8BaoDUg04AfwPqgSoBP4HqAQIBOKWgA/0ANQD1gLECPQHIAD+DygF/AcqBQAE45YAAPQJ1gX0A9YF9AUgAP4PqAT8B6oEqATolgQA9A8UAFQBFAD8DxQAVAFUChQI9A8EAOqWGADKCsoKygqKCr4KigrKCsoKyg8YAAAA75YACJgIygjqCcoGngTKBIoG2gnKCJgIAAjwlgAKGAmaBboFCgM+ARoJOgmKBxgBAAIAAPKWAAEMBWUFZQdFBV8FRQVlB2UHBQ0cCQAA85YcDMYDdgh2CX4HRgF2CXYJdglGCVwHAAD2loAAmACaAboFSgXeBcoFWg26C4oBmACAAPeWGADKD8oKygqKCr4PigrKCsoKyg8YAAAA+ZaAAJgA+gf6CuoK/grKCvoLegrKCRgEAAD7lgAAGADaB/oCygLeB9oK+grKCxgIAAYAAP6WAAFYC1wLXAvMBtwC3AJ8C0wLXAcAAAAAAJcAAFgAWg96AUoP3gFaD3oBSglYB0AAAAAElwAAHgAOCK4HhgHeBYYG1gLeCoYHHgAAAAaXAAhMCeYFdgsmCD4NRg32D3YNZg0MDQAAB5cYDNoDegn6B8oF3gXKB/oF+gXKB1gLAAkJlwAADAFmBeYG5gbGB94Gxg7mDuYHTAUAAAqXAAg4CYoLqgmKD74Jig+qD6oJCgs4CwAIDZcAAQwBpg+2C4YL3g+GC7YLpguMCAAAAAAOlxgCWgtKC2oLyg9uD0oPWgf6B0oLWgsYCBOXAAAOAA4I1guuCq4GBgKuBr4K5gsOCAAEFpcAAJgEigK6D4oCPgCKBroBug+KApgEAAQclwAAmAS6AroPugI+AL4H+gX6BfoFyAcAAB6XGADKD/oF+gXKBd4MCgj6C/oFygXYCwAIJ5cAAAAMTAPmD/YBRgMeCsYGdgPmC0wHAAEylxgIyg16CXoPygueAooOegv6CkoPWAIAADiXAABMB+YH9g/GB14DBgz2A/YC5grMBwAAOZcABuwBdQdtBW0FBQcvAuUCpQ+tAu0CoABClwAO7AFlBP0E/QZ1BOcHZQb9BvUG9QQgAEiXAAgMCeYL/gtGCa4PpgnmDU4LtgjkCAAAUpcQABQA/A+8ArwCvgK8ArwKvAr8BxQAEABWlwgC6AIOAugBAAD8D7wCvgK8CrwK/A8UAFmXEADcD9wC3grcDxAAWAlWCfQHXAHwAUAAXJcQCNwH3ALeCtwHAACIAqQK6geiAuoDgABelwABKAEoASgB/g8AAAAA/g8oASgBKAEAAWCXAAQIB3wHXgdcD1wAXgBcD1wHfAcIBwAEYZcADvwBBAQ0B3QHVA8GADQPdAc0B1QHAABilwAA8g8SBPIHXgVSBfIHEgQSBPIPAgAAAGmXAAAEAuQCvgK0AvQPtAK0Ar4C5AIEAgAAdJcEAu4C/A+uAuQCAAIwAP4PAAD+BxAICAZ2lwQA7gKsAvwPrgJAAP4HQgh+CEII/ggABouXAADkAq4C/A/uAgQKIAgkCb8PJAkkCQAAjZcEAO4CrAP+DuQCAABICcYJdAZEBegEQAiRlwQC7gL8D64CZAjgBwQIkAt+CNAIEAsAAJiXBAD+ArQC9A++AkAI9AcQAF4BEAn0BwAAoJcEAv4C9A+0Au4C/AaKA+gP6AGICvgHAACtlwQC7gL8D24A/g98CawH/ASsCPwIBAgAANOX/AKsAq4PrAb8BgAE7AeuBawPrAXsBQgE5pcAAJIAkgCSAJIA/w+SAJIAkgSSBIADAADnl6gAqAD8D6gAqAIAAXQMhAN8CAQI/AcAAOmXAAD0AtQC3g/UAvQCAACoAP4PqACoBIgD7ZcAAFAFUAVQBf4HAAQABP4HqASoBKgEAADzlxAAFADUB1QFVAVWBVQFVAVcBdQHFAAQAPWXIADoB2YFdAXkByAAEAEuBagICAj4BwAA9pcQANwHVgVcBdQHBACwB44EogSiBJ4HAAD7lxAA3AdVBVoF1AcEAPgPVANUA1QD/A8ACP+XlAC+ANUH4Af+B+4HzgfAB94HxgeaAAAAAZgACAQI/AusBqwGrAKsAqwGrAb8CwQIAAACmAQIBAj8DwQAAAj8C6wKrAKsBqwG/AsAAAWYBAEEAfwBBAEECPwHrAasAqwGrAb8CwAIBpgACPwHAAD4AwAA/g8AAPwHrAasAqwK/AsImEgIyAQkBBADBAj8C6wKrAKsAqwK/AsACBCYJAgkCPQPPADkCAAI/AusAqwCrAr8CwAAEZgAABQH9AAUAvQDAAj8B6wGrAKsAvwLAAgTmOgAiAD8D4gE6AIACPQHtAa8ArQK9AsAABeYAA74ASgMvAKoA1gI/AusCqwCrAb8BwAIGJgAAFgA1AdSAMQJDAT8B6wCrAKsBvwPAAAtmAAAfAhMBUwEfAcADPwJrAqsAqwG/AcACDuYEADeBRAEfwIUAZAA/g1WA1YDVgH+BQAEPJgAAHgGWAH8D1gBOAr8CawGrAKsBvwHAAhGmAAEvASsAvwPrAKcCPgJrAqsAqwG/AcACEyYQAxcA1wE3AdcCQAM/A1cCVwJXAn8DQAMTZggAawPtAVWBaQHDAD8B6wGrAKsCvwLAABPmAAM7AM8CK4JLAUkAvwLrAqsAqwG/AcACFSYAAzkAywIpgosBSQA/AusCqwCrAr8CwAIWJgAD/wAfAasAKwP/AEACPwHrAasAvwLAAhbmAQK/AvcCt4C/AsAAPwHrAasAqwG/AsAAF6YAACsBJgC3gGcAogI/AusBqwCrAL8BwAIZ5gADvoBKg+qB9oHgAcCCPoLrgaqAvoHAgxvmAAB/A3aARoJ+gO8AwAJ/AesBqwC/AsACHWYAAAECPQLFAgUBBQC3AEUBBQI9AsECAAAdpgAAAQIBAj8BwQAAAj6CQoE7gMKCPoJAAB3mAAAAAD8AxACEAEACPQFFATcAxQE9AkECHmYBAEEAfwBhAAACPoFCgQKA+4ACgIKBPoFepgADPwDAAD4AwAA/g8AAPwIDAbsAQwC/Ax7mAAESAQmApABAgj6BAoC7gEKAAoC+gQCCH2YAAASBvIBEgDyBwAC+ggKBu4BCgD6DgAAfpj8DwIA+gcKBPoCAAj6BAoG7gEKAPoOAAB/mAAA9ACEAP8PhARgAvoICgbuAQoA+g4ACIGYMAwMAuIJIAjvBxAA+gkKBO4DCgj6CQAAgpgwBAwD4gIAAt4HAAD6DAoC7gEKAPoNAASEmCIAKgjqBzYA4gAACPoECgbuAQoA+g4AAIWYAAjwB5AAngD0AQAI/AkMBOwDDAj8CQAIhpgQAFABTAJqDdAAAAj0BBQG3AEUAPQOAAiHmAAO/AEkDD4D5AYMAPAEFAbcARQA9A4ACIiYAACiCJIIige2BAAM+gkKBO4DCgj6CwAAiphIBFgESAP+AHgDSAjgBBQC3AEUAvQEAACRmCAAuAsgCPwFKAMgCPQJFATcAxQE9AkAAJOYAAAsCKwHvACqBwAE8ggSBt4BEgTyCQAAlpgABM8C1AHUD7IBAAryCBoG1gESBPIFAAiXmAAE/ATUAvwP1AH8AOAJFATcAxQI9AkAAJiYQAxcA1wE3AdcCQAM9AwUC9wIFAr0DAQMnJgACPIHGgGzBKoCEgj6BAoC7gEKAPoOAACdmKwAFAZeBXQFlA4cAPQJFAbcARQA9A0ABKCYBAr8C+wK7gL8CwAA9AkUBNwDFAj0CwAApJgACPwL/Av+C8wLPAPwCAoE7gMKCPoJAAComAAAAA78AQQE7AUsBfwHLAXEDPwHAAgABLGYAA7+AUIE+gNCAv4AAAPYBFYJUAncDQAAxJgEAPQN/AH8B6QP/gdmBPYD+gP6BwQIAATGmEAGygFqAGcG6wFiDP8DYQT9A2EH/wEABs6YAAAADv4BAgQaAqIB4gAaBwIA/gcACAAG0pgoBMoEDgLsAwAK/AcEAvQBBAL8BwAMAADYmHQN1AH8CdQH/APUASQN/AMUBuQB/AcADNuYUAhSBvoBQgBCAPoPQgBCAM4DFAUqCUgF3pgAAAQABAAEAAQABAAEAPwAIAdQCIgIiAbfmAAAEAAQCPgPtAiyCbQCtAb4CZAIEAgAAO+YCATkB9IE0gT0BgAO/gFiDKIFIgPiBAAI8pgIBPQHsgSyBPQGIAAcDIoD+AAIAzgECAj8mBAE/AeyBLIE9AYAAOwDLAHsCQQI/AcAAP2YCAAIBPwHugS6AvQGAAD4A5YE9AQEBPwE/pgQBPwHsgS6BPIGNAToASYA/A8kAOQDAAAFmQQA8g9aCVoF8gkAAIoM+gOIAP8PiQAAAAqZgACUAFwI/g/cCdwJ3AfcBf4NXAiUCAAAEJkQAJAAqAjuD9wLgAO2B9YHlgWuCKIAAAATmQQI8gdxBnUDIQSJBP8DWAAfAvgD2wYQABiZCAjsD1oJVgX0DQQAlAKUCPMHlACEAogEKJkQBPgHtASyBOwGHAD0D5QFlgWUBfwHAABSmQAA8A++BLIE9A5AAGoNegNvASoP+g0oBWWZMAAMCOoPCAQ4AAAO/AEEAAQA/A8ACAAGbZkwAAwIygcYAAAO/AE0DNQCFAPyBBIIAABumXAADAjqDwgEOAIACDAEDgPoAAgDKAQYCHCZIAAUAMoPGAIAAOgDJwAkAPwPJAAkAuQBcZlgABQAyg8YBEAA8AcsCSgJ6AsICvgJAARymTAADAjKBxgCCADiAyoBKgHqCQII/gcAAHWZcAAMCOoPCAQwAAQE/AeUBJQElAL8DwQCdpkgABQIygcYAggIoASuA7gApA/UCJQIAAR6mTAACgjlBwQCCApgCBQEhQOGAwQEdAhABHyZIAAUCMoPCAS4AoEI+geIAIgA/A+LAIAAf5kgABAAzg8YBIAClAj8DxAE/gKQBVYIAAaAmSAAHADKDwgEGACQBpgAlAjyD5QAmAKQBIGZIAAUCMoHGAIACFQJxAVsAkQDwgRaCEAAhZkgABQEygcIAjgA0A9IBQYFRARcBcQPAACGmSAAFATKBxACBAD8B/QHVQVWBWQFDAcAAIuZMAAMCMoHGAKQALgCbgQ8BWwJrAq4AIAAjZkgABQEygcYAwAIdAV2BXQD9AF2A3QFAAiPmTAAjg8oBBgEQAA+D7AK5A+cCoQKvA8AAJKZEAAcAOoHCAFgBN4F/gbeAv4G3gX+BAAAlpkAAAQA9A9XBVQFXAVUBVQFVwX0DwQAAACZmZAAVABUD7QKlAq8CpQKsgrSCtIPUACQAKiZAAC8ArwC/g78D/QP+A72DvIP/g7YAgACrJkACAAM/AFUAVQFVAH8DVQBVAtUCQAHAACzmQAG/gCqB/4CqgoAB/wHEAj+CRAI+AgABsGZAAb+AKoC/gmqC6oHAADWDAgDDgXRBBAIxZkABv4AqgP+C6oOgA3+AyIA4gAiAz4MAADGmQAG/gCqBv4CqgsAB/4PAgSiBXIEigUABdCZAA7+AKoG/g6qCaoHAACKCPoPjAiICAAI0pkABv4Aqgf+AoIKEAfMASoB6AkICPgHAADVmQAAFAjMBeYB5AXsAeAD/gHyA/IFHgMAANuZAAN/ANUDfwNVBcEDHAwkA/8CJAQ8BAAI3ZkABv4Aqgf+A6oPAAAYAPgHjgiICFgIQAb/mQAG/gCqBP4Bqg8AADwHigS4Bq4JIAgAAA6aAAb+AKoD/guKByAApAe0Aq4LNAjUByAAEpoABv4Aqgf+A4oPQACiCWYJ+g9aCeYNIAgTmgAG/gCqA/4GqgoKB+gIJgXyAyQH6AkICBmaAAb+A6oB/gmAD/wH7APsB+oDagX6BwAAMJoADP4Dkgj+B0QA9gXcC9YL3Af2C1QGQAA3mgAO/gCqAv4LqgcAAPQJagnSD2oP5g8gCEWaAAb+BqoB/gmCBwAA/AdUCuwLnAnECwAAVZoABn4H/gKqCQIHqA/6A94F2gf5AKkPAABXmgAG/geqAf4NggNwCLgG9gBUDLgC0AwAAFqaEAg6DP4D+gP6C9oDyAvsA9YLrAssBiQAX5oADv4Aqgf+DgAHfga6AP4PbAAUAywEAABsmgAAAAIEAnQCRAJEAkQCRAp8CEAHwAAAAG6aAAJ6AkIJQgj+BwAAEAyQA34AkAEQBhAIb5oAAnoCQglyCM4HAAD+DwAA/gcAAP4PAABwmgACegJCCkII/gcAAPwHEAj+CQgI+AgABnGaAAB6AkIKQgn+B/gPBAgUC+QIlAkECgAAc5oAAnQCRAlECPwHAABUDIgCiANUBBIIAAB0mgAAegJCCkII/gcAAPgPSABKAEgA+AAAAHaaAAJ0AkQIRAz8AzAISAVIAv4FSAR4CAAAeZoAAnoKQgl6CMYHEADOAykB6AkICPgHAAB7mgAAegJCCkIK/gcAAIgIiQj6D4gIiAgICHyaAAB0AkQJRAn8BwAA6AeKCGwICAgYBgAAfpoAAAQCLAKmAqQCrAKgAr4C8gqyCJ4HAACCmgAADgKqAqoCrgKgAq4CqgLqCI4IgAcAAISaAAJ6CkIJfgjABxAAVAw0AxwAMg9SAEAAhZoAAPoCggr+CIAHEAB/AQAPPgFIAUYBIACGmgACegJCCWII3gdAAEgPtgSkBLQETA9AAIeaAAJyAkIJQgj+BwAIqAS5Am4CCAPIDAAAjJoCAnoBQglCCP4HIACYBSQEpgUIBNAHEACPmgACegJCCkII/gcAACwJqwaJBKgHrgggCJGaAAB0AkQJRAn8BwAApAesAq4LNAj0DyAAl5oCAnoBQgl+CMAH/AOUD9YH1A9UAdwPAACamgACeglCCX4IwAeSCFYJ3gdaBVYH0gcgCKGaAAB6AkIJQgj+BxwN6gF+CSoPqgG+CwAKpJoCAnoBQgh8CuIFvga6Bb4PagPSBS4JAAComgAAYAAgAPwP5AL8AuwC7Ar8DyAAYAAAALiaMAD+D/YC/gr+BzAABAm0BK8CZAIUBcQI0ppgCPwH5AB8CvwHQAC0CnYGUAK2DrQCAADTmjAA/g/+Av4PdABwCNwHBgjkC/wJ7AsACNSaYAz8A3wJ/A8AAHwI7Av+CuwO/g7sC3wA2JoAAAIAwg9eAFYPVwVWBVYHXgBCCMIHAADmmgAAEAS+Bd4FvgK+B4ALZAtqCxQLFAoAAOqaAADQCP4E3gLeCf4H0AWEBdIHqgmqCKAI7poAALAEvgK+Cr4JvgawBoQE0gaqBKoEkAgGmwAAsAS+Ar4PvgI+ALINAAZsBGoGkggQARObAADQCl4G3gfeB/4DzgPkB+oHWgdSCgAAJZsAAP4PAAA+ACoAAAAqAD4AKggACP4HAAAnm/4PAACuB64ApgDwD6YArgSuAwAI/gcAADGbAADsAa4NrAt0B34H9gE2CGgJLgRsAwQAPJsAAAAIfARUAtQBfgBUB1QIVAt8CwAKAAhBmwAAfAxUA/4HVAh8CwAKrAiACP4LQAgABkKboANkAiQBpAEACHwEVAJUAf4HVAl8CwAERJsAAPgHTgL4AwAIfAZUAf4HVghUC3wLAAhFmwAAfA/UAP4HVAt8CgAK6Aj+C2gIqAkABE+bAACsCpwH3ASaB4AAPA5UAf4HVAi8CgAKVJsADPwDBAi0C7QLlgfEA7QHtA+0D5QLAAhamwAIMAj4BVQBVg30AVwFVAlQAfAFAAgAAG+b0AAIALgPvgr8CrwK/Ar8CrgKeA+AAIAArpsQDPgBVg30A1wB4AUJAE4B+A9MAUoBAADomxAM+AFWBfQDXAHwBGQClAiWB5QA9AYAAHycAAAQBPgFVAVWBVQF9AVcBVAF8AUABAAAgZwIAEgA+A/+CvwK/Ar8CvwK+Ar4D0AAAACNnCAI+AlWBfQFXAX0BRAA7AfoCQgJ+AgABJycEAD4BVYF9AVcBfQFAAFKAfgPTgFKAQAApJwQAPgFVgX0BVwF4AE8CFQJ/A9UCXwJAACrnBAA+AFWBfYFXAXgBPwHVAI8APgPBAD8A7icEAD4BVYF9gVcBfQFAAB0A1QI1gdUAHQDxJwQBPgF9gVcBfQFAACcAowLqAq0CrwGgADNnAgA/AL7Aq4CeACSD1YFfwV2BW4F7w8FANacAAF6CTgPfg+4D7oPkA+uDzQPLA9ECEAA3pwQAPgF/gX0BAABqgyYAz4AmAKuD6gCAADlnAAIAAT8AVwBXAVeAV4FXAFcBVwJQAcAAPOcAADgDxwE/AH8BfwD/Av8CQwH/AcACAAG9JwAAPwDBAH8CQAE/AFcCV4DXgtcCVwHQAAonQAA/AGUAPwPlAD4DPwBXAVeA1wLXAcAADudEAgiDqQBBAD8CQQM/AFcBV4DXAtcBwAAXZ0AAJII/gcQBv4N1ADoBVwDXglcC1wHQAC0nUAA7A9cBfYHVAUECPgFXANeBVwLXAdAAPmdAAD8DwIAuguOB8oP/w++B74Hvg8mBgAAH54AAQABfAFEAVQBVgFEAWQBZAlcCMAHAAAgngAACA/+AAgA+AGAADwATgFmCWQI3AcAACGeFAQ0AsQBPAMAAPwChAKWApYKpAicBwAAI54AAPwDBAH8AQAA/AKEApYChAq8CIAHAAAlngAA/AcEBuQFFAUABPwAjAKmCqQInAcAACaeAAA0ACQL5Aj8DwAA/AKMAqYKpAicBwAALZ4AAPwBlAD8D5QA+AB8AowCpgqkCpwHAAAvnkAAUATcB3QGdAbUBl4GVAZ0C9wKUAZAADOeJAISAvoDMwNuAyADLgOyC7oLfgkQBwgANZ4AAvwClgKECLwHAADoB4oIjAhICFgIAAY9ngAAsA+IBKYErAcAAPwChAKWCqQInAcAAD+eEAgmDyAABAL8AQAA/AKMAqYKpAicBwAAQ54AAPwPtAK0ArwKwA18AowCpgqkCpwHAABFngAAFAn8BxAA/gfcCAAK/AKOAqQKnAcAAEmeAADsBwwEyAP/AwoMAAj8Ap4KhAi8BwAASp4AANQHXgVUBV4F1AcAAvwClgqECrwHAABPngAM/gOSCP4P/AeSAP4PeAKeCoQKvAcAAGSeQADsD1wFVgX0B1QFAAD8ApYKhAq8BwAAZp4AAH4JMgteDUwFMgtOCPgCpgK0CpwIgAdwngAAwA88AIQH/AbOB/wH/Ab8CvwKfAYEAH+eAACAD3wAVA90CVQJVgB0B1QJVAl0CQAEl54AAAAO6gGqD+IK+grgAOoH+griCuoKAAifnoAPfAB+D3QEVA9gAWoNmAM+AJgCyg+AAqWeVABUClQJJAWkBp4CpAI0BVQIVAhUAAAApp4gCSwJrAjsBawGvgSsBqwFrAgsCCAIAAC1ngAAlAukBp4EpAcACPoL/gv6CwoK+gsACLieAACcBXwEXgLcBVwAAAxIA/4ASANIBAAIu54ADPwDBACkAfQPpQAGAqQB9A+kACQDAAC8ngAG/gEKADoFmgWqBwMFKgWaBCoGKggAAL2eAAz8AwQAVAr0ClQMBgs0CPQKNA5UCAAAw54ACBQI9Ae+BrwC/AO8ArwGvgb0BxQIAADEngAAEAj0C7QKvgr0A7QCvga0BvQLEAgAAM2eKAGsAKwEXARMAzwKTA9cAqoCqgSoBAAAzp4AAGoBGgW+BKkCiA5IApYCjAREBTwBAADPnqAEmgJaCD4HWgDZBggAwA9+BEgEyAcAANGeAAAACV4FVgFSDf4BUgVWCVIBXgUACQAA0p4AAAANfgFqAWoN/gFqBWoJagF+BQAJAADUngAAfg1mBf4Beg1+BQAAkACIAKYMiAOwANieAA5+AGYF/gNqAX4FAACQD34AkAMWBAAI2Z4AAFwNXAH8AVwFXAEAAcgGPgBIBIoFAAHbnggIBAruC6EDpAvmA6QL7gu2A/QLFAoUAN6eAAx8AWwF/ANkATwDgA+ABP8EiASIDwAA354ADn4AagX+AWYFfgEIBSgJ9ga0BowBgADongAADArkC74DvAv+A7wL/Au+A+QLDAoAAO+eAAx+AWYN/gFqCX4HwAd0BWYFdAXkBwAADp8AAHwJQAd+Ae4PLgDuD34BQAF+AQAPAAATnwQEdAW0BL4EtAfgDWgEqAU+AqgFaAwABCCfAAAAAL4PKgmqAOAPKgiqCioAvgcACAAEO58ACsAL/Av8B/wD/gP8A/wP/APAA8ADAAJKn0wIfAzMA8wCtAKMAvYCvAKsAuwPFAAgAEufAABQADQPlAAkDIwBpg+UBSQAVA8kAEAAUJ9AAEQIRARMAzQAJgAmADQATA9EAEQAQABSnxAA8A/wD5wIsAqQCN4I1ArUCpQI0A8QAGGfAADsB/AH3gb0B9QHAAA4AWYCSA2QACAAYp/wD/wF0AXeBfQPEAAIAPQPdwBoBLADAAB/nwAA8AfwBxwEEAWQBF4ElAQUBRQE1A8QAISfAADeBxAF3gQUBNQHEABIAVYCRA3IAFAAjZ8AAPIPugKzAroK9gcAAO8HqguqCzoKAASQnwAM/AMECOQH1AbUAgYPtAO0D7QP9A8ABJmfEAgQBBAC0Ak+CBAE8AcSCZQIVAhQCBAEnJ8AAOgH+Af+B/wHTAr8C1gL2ApYCsALAACfnwAAEAD4A1QBVgH0B1wJVAlQCfAJAAgABgCsAAAEAgQBhABkABwAAAAAAP4PIAAgAAAAAawAAEQARAEkATQBDAEAAQABfg8QABAAAAAErIAARABEDyQIFAgMCAAIAAj+CRAAEAAAAAesgABEAEQPJAk0CQwJAAkACX4JEAAQAAAACKwgACQApA6kCpQKjAqACoAKvgsIAAgAAAAQrIAARABEDyQJNAkMCQAJAAl+DxAAEAAAABGsQABEAEQPJAo0CgwKAAoACn4PEAAQAAAAEqwAAEQARA9ECjQKDA8AAAAMfgMQBBAIAAATrEAAhAhECCQEFAIMAQACAAT+CBAIAAAAABWsAACEAEQGRAk0CQwJAAkACX4GEAAQAAAAFqwAAEQARAkkCTQFDAMABQAJfgkQABAAAAAZrEAARAAkD6QKlAqMCoAKgAq+ChAAEAAAABqsAACAAEQIRAkkDxwJAAkAD34JEAAQAAAAG6wAACQApACkBJQKzAqACoAKvgQIAAgAAAAcrAABBAGEAGQAHAAAAP4HIAAgAP4PAAAAAB2sgABEAEQBNAEMAQABfgEQARABfg8AAAAAJKwAAEAAJACUDpwKgAq8CogKiAq+CwAAAABArCAAJACkDqQKlAqMCoAKgAq+CxQAFAAAAHCsAAAEAwQBhAB0AAwAIAAgAP4PAAAAAAAAcawAAEAARABEASQBHAEEARABEAF+DwAAAAB0rAAAgABEAEQPJAgcCAQIEAgQCP4JAAAAAHesAACAAEQARA8kCRwJBAkQCRAJfgkAAAAAeKwAAEAAJACkDpQKjAqACpAKkAq+CwAAAACArAAAgABEAEQPJAkcCQQJEAkQCX4PAAAAAIGsAABAAEQARA80CgwKAAoQCn4PAAAAAAAAg6wAAIAARAhECCQEHAIEARACEAT+CAAIAACJrAAAQAAkAKQPlAqMCoAKkAqQCr4KAAAAAIysAAEEAYQARAA8ACAAIAD+BwAA/g8AAAAAkKwAAIQARAAkDxwIEAgQCP4JAAj+CQAAAACcrAAAgABEACQPFAkcCRAJfgkACX4PAAAAAKisAAAEAgQBxAAkAJwAkACQAP4PAAAAAAAAqawAAEAARAAkASQBFAEMASgBKAF+DwAAAACqrAAAQABEASQBJAEUDwwAKAEoAX4PAAAAAKysAACAAIQARA4kCBQITAhICEgI/gkAAAAAsKwAAEAAJACkDqQKlAqMCqgKqAq+CwAAAAC5rAAAQABEAEQPNAoMCigKKAooCn4PAAAAAL2sgABEAEQGJAkUCQwJKAkoCSgJfgYAAAAAwawAAEAARAAkD6QKlAqMCqgKqAq+CgAAAADErAACBAPEACQAnACQAJAA/g8AAP4PAAAAAOCsAAIEAgQCBALkAwQCBAIEAvwCAAIAAAAA4awAAEAARAFEAUQBdAFEAUQBXA9AAAAAAADkrAAAQABED0QIRAh0CEQIRAhcCEAAAAAAAOesAABAAEQPRAlECXQJRAlECVwJQAAAAAAA6KwAACAAog6iCqIKugqiCqIKrgsgAAAAAADwrAAAQABED0QJRAl0CUQJRAlcD0AAAAAAAPGsAABAAEIPQgpCCnIKQgpCCl4PQAAAAAAA86wAAEAIRAhEBEQEdANEBEQEXAhAAAAAAAD1rAAAQABEBkQJRAl0CUQJRAlcBkAAAAAAAPasAABAAEIJQglCBXIDQgVCCV4JQAgAAAAA/KwAAAQCBALEAwQCBAL8AgAA/g9AAEAAAAD9rAAARABEAXQBRAFEAVwBAAF+DxAAEAAAAACtAACEAIQO5AiECIQIvAgACP4LIAAgAAAAEa0AAEQARAZ0CUQJRAlcCQAJfgYQABAAAAAcrYAAhAD0DoQIhAicCAAI/gkQCP4LAAAAADStAAAEAgQCxAMEAgQCfAIAAP4PAAAAAAAASa0AAEQARAZ0CUQJRAlcCQAJfgkABgAAAABQrQAAAAIEAsQDBAIEAsQDBAL8AgACAAAAAGytAABAAEQARABEAMQPRABEAHwAQAAAAAAAba0AACAAJAEkASQB5AEkASQBPA8gAAAAAABwrQAAQABEDkQIRAjECUQIRAh8CEAAAAAAAHOtAAAgACQPJAkkCeQJJAkkCTwJIAAAAAAAdK0AACAAog6iCqIK4gqiCqIKvgsgAAAAAAB1rQAAIACiDqIKIgsiCKIAogC+DyAAAAAAAHatAAAgAKIOogqiCuIB4g+iCL4PIAAAAAAAfa0AACAAIg8iCiIK4goiCiIKPg8gAAAAAAB/rQAAIAgiCCIEIgRiAyIEIgQ+CCAAAAAAAIGtAAAgACIGIgkiCeIJIgkiCT4GIAAAAAAAjK0gACQAJA8kCOQJJAg8CIAI/gsAAAAAAADArQAAQABEAEQAxAdEAHwAQAAAAP4PAAAAANOtIAAkACQI5AkkCCQEPAMABP4JAAgAAAAA3K0AAEAARADED0QARABEAMQPfABAAEAAAADgrQAAQABED0QIxAlECEQIxAl8CEAAAAAAAPitAAAAAgQCBAIEAgQCBAIEAvwCAAIAAAAA+a1AAEABRAFEAUQBRAFEAUQBfA9AAAAAAAD8rQAAQABED0QIRAhECEQIRAh8CEAAAAAAAACuAAAgAKIOogqiCqIKogqiCr4LIAAAAAAAAa4AACAApA6kCqQLJAikAKQAvA8gAAAAAAAIrgAAQABED0QJRAlECUQJRAl8D0AAAAAAAAmuAAAgACQPJAokCiQKJAokCjwPIAAAAAAAC64AAEAIRAhECEQERANEBEQIfAhAAAAAAAANrgAAQABEBkQJRAlECUQJRAl8BkAAAAAAADCuAAIEAgQBhABkABwAAAAAAP4PAAAAAAAANK6AAIQARA4kCDQIDAgACAAI/gkAAAAAAAA4rgAAQAAkAKQOlAqMCoAKgAq+CwAAAAAAAECugABEAEQPJAkUCQwJAAkACX4PAAAAAAAARa6AAIQARAYkCTQJDAkACQAJfgkABgAAAABKrgAAhABECEQJJA8cCQAJAA9+CQAAAAAAAEyuAAAEAeQAHAAAA8QAPAAAAP4PIAAgAAAATq4AAEQAJAEcAUAPJAAcAQABfg8QABAAAABQrgAARAA0DwwIwAgkCBwIAAj+CRAAEAAAAFSuAAAkAJwOhAqgCpQKjAqACr4LCAAIAAAAXK4AAEQAJA8cCUAJJAkcCQAJfg8QABAAAABdrgAAZAAUDwwKQAo0CgwKAAp+DwgACAAAAGGuAABEACQGHAlACSQJHAkACX4GEAAQAAAAZa4gACQAlA+MCoAKtAqMCoAKvgoQABAAAABorgQBxAA8AAADxAA8AAAA/gcgAP4PAAAAALyuAAAEAcQAPAAAA8QAPAAgAP4PAAAAAAAAvq4AAEQANAEMAUAPJAAcARABfg8AAAAAAADNrgAAZAAUD0wKQAokChwKEAp+DwAAAAAAAM+uAABEADQIDARABiQBHAIQBP4IAAgAAAAA0a4AAEQANAYMCUAJJAkcCRAJfgkABgAAAADYrgQBxAA8AAACxAE8ACAA/gcAAP4PAAAAAOiuQAAkABwAAA9kCRwJEAl8CQAJfg8AAAAA9K4AAAQDxAA8AAACxAG8AJAA/g8AAAAAAAAsrwAAAAIEAmQCHALAAwQCBAJ8AgACAAAAAC2vAABAAEIBQgFOAWABQgFCAV4PQAAAAAAANK8AACAAog6qCqYKsAqiCqIKrgsgAAAAAAA8rwAAQABCD1IJTglgCUIJQgleD0AAAAAAAD2vAABAAEIPWgpGCnAKQgpCCl4PQAAAAAAAQq8AAEAAQglCCU4FYANCBUIJXglAAAAAAABDrwAAQABCCVoJRgVwA0IFQgleCUAAAAAAAEmvAABEAFwBQAF0AUQBXAEAAX4PEAAAAAAAZK8AAQQBPAGAAQQBfAEAAP4HQAD+DwAAAAC4rwAARABEAEQAfADAD0QARAB8AEAAAAAAALyvAABAAEQORAh8CMAJRAhECHwIQAAAAAAAwK8AACAAog6iCr4K4AqiCqIKvgsgAAAAAADIrwAAIAAkDyQJPAngCSQJJAk8DyAAAAAAAAywAABEAEQAfADAB0QAfABAAAAA/g8AAAAARLAAAAQCBAKEAnwCAAIEAgQC/AIAAgAAAABIsAAAQABED0QIfAhACEQIRAh8CEAAAAAAAEqwAAAgACQPJAg8ACAFJAukCzwFIAEAAAAATLAAACAAog6iCr4KoAqiCqIKvgsgAAAAAABTsAAAIACiDqIKvgsgACIFogs+CyAFAAAAAFSwAAAgACQPJAk8CSAJJAkkCTwPIAAAAAAAV7AAAEQIRAhECHwEQANEBEQIfAhAAAAAAABdsAAAIACiD6IKvgqgCqIKogq+CiAAAAAAAHywAAAEAeQAHAAAAsQBPAAAAP4PAAAAAAAAjLAAAEQAJA8cCUAJJAkcCQAJfg8AAAAAAACYsAAA/AEAAQABAAEAAQABAAD+DyAAIAAAAJmwAAB8AEABQAFAAUABQAEAAX4PEAAQAAAAmrAAADwAIAEgASAPIAAgAQABfg8QABAAAACcsAAAfABAD0AIQAhACEAIAAj+CRAAEAAAAKCwAAA+AKAOoAqgCqAKoAqACr4LCAAIAAAAobAAAD4AoA6gCqALIAigAIAAvg8IAAgAAACosAAAPAAgDyAJIAkgCSAJAAl8DxAAEAAAAKmwAAA+ACAPIAogCiAKIAoACn4PCAAIAAAAq7AAAHwAQAhACEAEQANABAAE/gkQCBAAAACtsAAAfABABkAJQAlACUAJAAl+BhAAEAAAAK6wAAA8ACAJIAkgBSADIAUACX4JEAAQAAAAr7AAADwAIAkgCSAFoAMgBQAJfAkQCBAAAACxsAAAPgCgD6AKoAqgCqAKgAq+CggACAAAALOwAAA+AKAAoASgCqAKkAqACr4ECAAIAAAAtLAAAPwBAAEAAQABAAD+ByAAIAD+DwAAAAC1sAAAfABAAUABQAEAAX4BEAEQAX4PAAAAAMSwAAB8AEAAQA9ACQAJfgkQCRAJfg8AAAAAxbAAADwAIAAgDyAKAAp8ChAKEAp+DwAAAADHsAAAfABACEAIQAQABH4DEAQQBP4IAAgAAMmwAAB8AEAAQAZACQAJfgkQCRAJfgYAAAAA0LAAAPwBAAEAAQABAAEAAQAA/g+QAJAAAADlsAAAfABABkAJQAlACUAJAAl+BigAKAAAAAixAAD4AQABAAEAASABIAEgACAA/g8AAAAACbEAAHwAQAFAAUABQAFIAQgBCAF+DwAAAAAMsQAAfgBAAEAPQAhACEgICAgICP4JAAAAABCxAAA8ACAAoA6gCqAKqAqICogKvgsAAAAAE7EAADwAoA6gCqALKACoDwgKCAq+DwAAAAAYsQAAfABAAEAPQAlACUgJCAkICX4PAAAAAB2xAAB8AEAGQAlACUAJSAkICQgJfgYAAAAAI7EAADwAoACgBKAKqAqoCogKiAS+AAAAAAAksQAA+AEAAQABIAEgASAA/AcAAP4PAAAAACWxAAB8AEABQAFIAUgBCAF+AQABfg8AAAAAKLEAAHwAQABAD0AIUAgQCPwJAAj8CQAAAAAssQAAPAAgAKAOoAqoCogKvgqACr4LAAAAADexAAB8AEAIQARIBEgCCAF+AgAE/ggACAAAQLEAAPgBAAEAAQABUAFQAVAAUAD+BwAAAABBsQAAfgBAAUABQAFAAVQBFAEUAX4PAAAAAESxAAD+AIAAgA6ACIAI1AgUCBQI/gkAAAAAULEAAH4AQABAD0AJQAlUCRQJFAl+DwAAAABVsQAAfgBABkAJQAlACVQJFAkUCX4GAAAAAHixAAAABHwEQARABMAHQARABEAEAAQAAAAAebEAAEAAXgFQAVABcAFQAVABUA9AAAAAAAB8sQAAgACeDpAIkAjwCJAIkAiQCIAAAAAAAICxAABAANwO0ArQCvAK0ArQCtALQAAAAAAAiLEAAEAAXg9QCVAJcAlQCVAJUA9AAAAAAACLsQAAQAReCFAEUAJwAVACUARQBEAIAAAAAI2xAABAAF4GUAlQCXAJUAlQCVAGQAAAAAAAkrEAAEAAXglQD1AJcAlQCVAPUAlQCUAAAACTsQAAIAA8BTALMAuwCzALMAswBTABIAAAAJSxAAI8AiACIALgAyACIAIAAP4PQABAAAAAzLEAAAACPAIgAuADIAIgAgAA/g8AAAAAAADosQAAAAR8BMAHQARABEAEwAdABEAEAAQAAASyAACAALwAoACgAKAPoACgAKAAgAAAAAAABbIAAEAAXgFQAVAB0AFQAVABUA9AAAAAAAAIsgAAQABeD1AIUAjQCVAIUAhQCEAAAAAAABSyAABAAF4PUAlQCdAJUAlQCVAPQAAAAAAAFbIAAEAAXg9QClAK0ApQClAKUA9AAAAAAABYsgAAgACeAJAAkA+QAJAAAAD+DwAAAAAAAHSyAACAALwAoA+gAKAAoACgD6AAgACAAAAAhLIAAEAAXg/QCVAJUAlQCdAJUA9AAAAAAACQsgAAAAR8BEAEQARABEAEQARABAAEAAQAAJGyAABAAF4BUAFQAVABUAFQAVAPQAAAAAAAlLIAAIAAng6QCJAIkAiQCJAIkAiAAIAAAACYsgAAIAC8DrAKsAqwCrAKsAqwCyAAAAAAAJmyAABAANwO0ArQC1AI0ADQANAPQAAAAAAApbIAAEAAXgZQCVAJUAlQCVAJUAZAAAAAAACmsgAAQAheCVAJUAVQA1AFUAlQCUAIAAAAAKyyAAAAATwBIAEgASABIAEAAP4PAAAAAAAAyLIAAPwBAAEAAQABAAGAAAAA/g8AAAAAAADJsgAAfABAAUABQAFAAUABAAF+DwAAAAAAANCyAAA+ACAAoA6gCqAKoAqACr4LAAAAAAAA2LIAAD4AIA8gCSAJIAkgCQAJfg8AAAAAAADbsgAAfABACEAIQARAA0AEAAT+CQAIAAAAAN2yAAB8AEAGQAlACUAJQAkACX4GAAAAAAAA5LIAAPwBBAEEAQQBBAEAAQAA/g8gACAAAADlsgAAfABEAUQBRAFEAUABAAF+DxAAEAAAAOayAAB8AEQBRAFED0QAQAEAAX4PEAAQAAAA6LIAAHwARA9ECEQIRAhACAAI/gkQABAAAADrsgAAfABED0QJRAlECUAJAAl+CRAAEAAAAOyyAAA8AKQOpAqkCqQKoAqACr4LCAAIAAAA7bIAADwApA6kCqQLJAigAIAAvg8QABAAAADusgAAPACkDqQKpAskAKAPgAi+DxAAEAAAAPSyAAB8AEQPRAlECUQJQAkACX4PEAAQAAAA9bIAAHwARA9ECkQKRApACgAKfg8QABAAAAD3sgAAfABECEQERAREA0AEAAT+CBAIEAAAAPmyAAB8AEQGRAlECUQJQAkACX4GEAAQAAAA/7IAADwApACkBKQKpAqgCoAKvgQIAAgAAAAAswAA/AEEAQQBBAEAAP4HIAAgAP4PAAAAAAGzAAB8AEQBRAFEAQABfgEQARABfg8AAAAABLMAAHwARABED0QIAAj+CRAIEAj+CQAAAAAQswAAfABEAEQPRAkACX4JEAkQCX4PAAAAABOzAAB8AEQIRAhEBAAEfgMQBBAE/ggACAAAVLMAAPwBBAEEAQQBBAEgASAAIAD+DwAAAABVswAAfABEAUQBRAFUAVABEAEQAX4PAAAAAFizAAD8AIQAhA6ECJQIkAgQCBAI/gkAAAAAXLMAAHwARADEDsQKzArICogKvgsAAAAAAABfswAAfADEDsQKxAtUAFAPEAq+DwAAAAAAAGSzAAB8AEQPRAlECVQJUAkQCRAJfg8AAAAAZbMAAHwARABED0QKVApQChAKEAp+DwAAAABnswAAfABECEQERAREAlQBEAIQBP4IAAgAAGmzAAB8AEQGRAlECVQJUAkQCRAJfgYAAAAAbrMAAHwARAlECUQPVAlQCRAPEAl+CQAAAABwswAA/AEEAQQBBAEgASAA/gcAAP4PAAAAAHGzAAB8AEQBRAFUAVABEAF+AQABfg8AAAAAdLMAAHwARABED1QIUAgQCP4JAAj+CQAAAAB4swAAPAAkAKQOrAqoCogKvAqACr4LAAAAAICzAAB8AEQARA9UCVAJEAl+CQAJfg8AAAAAhbMAAHwARABEBlQJUAkQCX4JAAl+BgAAAADEswAAAAR8BEQERATEB0QERAREBAAEAAAAAMWzAABAAF4BUgFSAXIBUgFSAVIPQAAAAAAAyLMAAIAAnA6UCJQI9AiUCJQIlAiAAAAAAADLswAAQABeD1IJUglyCVIJUglSCUAAAAAAAMyzAABAAN4O0grSCvIK0grSCtILQAAAAAAA1LMAAEAAXg9SCVIJcglSCVIJUg9AAAAAAADVswAAQABeD1IKUgpyClIKUgpSD0AAAAAAANezAABACF4EUgRSAnIBUgJSBFIEQAgAAAAA2bMAAEAAXAZUCVQJdAlUCVQJVAZAAAAAAAD8swACfAJEAsQDRAJEAgAA/g9AAP4PAAAAABi0AAJ8AkQCRALEA0QCRAIAAP4PAAAAAAAAHLQAAIAAvA6kCOQIpAikCAAI/gkAAAAAAABQtAAAgAC8AKQApACkD6QApACkAIAAAAAAAFG0AABAAF4BUgFSAdIBUgFSAVIPQAAAAAAAVLQAAIAAvA6kCKQIpAukCKQIpAiAAAAAAABYtAAAQADeDtIK0grSCtIK0grSC0AAAAAAAGC0AABAAF4PUglSCdIJUglSCVIPQAAAAAAAYbQAAEAAXg9SClIK0gpSClIKUg9AAAAAAABltAAAQABcBlQJVAnUCVQJVAlUBkAAAAAAAKS0AACAALwApACkD6QApAAAAP4PAAAAAAAAt7QAAEAAXAhUCNQJVARUAwAE/gkACAAAAADAtAAAgAC8AKQPpACkAKQApA+kAIAAgAAAANy0AAAABHwERAREBEQERAREBEQEAAQABAAA3bQAAEAAXgFSAVIBUgFSAVIBUg9AAAAAAADgtAAAQABeD1IIUghSCFIIUghSCEAAAAAAAOO0AABAAF4PUglSCVIJUglSCVIJQABAAAAA5LQAAEAA3g7SCtIK0grSCtIK0gtAAAAAAADstAAAQABeD1IJUglSCVIJUglSD0AAAAAAAO20AABAAF4PUgpSClIKUgpSClIPQAAAAAAA77QAAEAAXghSBFICUgNSAlIEUgRACAAAAADxtAAAQABeBlIJUglSCVIJUglSBkAAAAAAABS1AAD8AQQBBAEEAQQBAAEAAP4PAAAAAAAAFbUAAHwARAFEAUQBRAFAAQABfg8AAAAAAAAYtQAAfABED0QIRAhECEAIAAj+CQAAAAAAABy1AAA8AKQOpAqkCqQKoAqACr4LAAAAAAAAJLUAAHwARA9ECUQJRAlACQAJfg8AAAAAAAAntQAAfABECEQERAREA0AEAAT+CQAIAAAAACm1AAB8AEQGRAlECUQJQAkACX4JAAYAAAAAKrUAAHwARAlECUQJRAVAAwAFfgkAAAAAAAAwtQAA/AEEAQAA/AEEAQQBAAD+DyAAIAAAADG1AAB8AEQBAAF8AUQBRAEAAX4PEAAAAAAANLUAAHwARA8ACHwIRAhECAAI/gkQAAAAAAA4tQAAPACkDoAKvAqkCqQKgAq+CwgAAAAAAEC1AAB8AEQPAAl8CUQJRAkACX4PEAAAAAAARbUAAHwARAYACXwJRAlECQAJfgYQAAAAAABMtQAA/AEEAQAA/AEEAQAA/gcgAP4PAAAAAFy1AAB8AEQAAA98CUQJAAl+CRAJfg8AAAAAYbUAAHwARAYACXwJRAkACX4JEAl+BgAAAACgtQAA/AEEAQAA/AEEAQQBIAEgAP4PAAAAAKG1AAB8AEQBAAF8AUQBRAFQARABfg8AAAAApLUAAHwARA8ACHwIRAhECFAIEAj+CQAAAACotQAAPACkDoAKvAqkCqwKqAqICr4LAAAAALu1AAA8AKQAgAS8CqQKrAqoCogEvgAAAAAAvLUAAPwBBAEAAPwBBAEgAP4HAAD+DwAAAADMtQAAfABEAAAPfAlECRAJfgkACX4PAAAAABC2AAR8BEQERAREBAAHfAREBEQERAQAAAAAEbYAAEAAXgFSAUABfgFSAVIBUg9AAAAAAACctgAAgAC8AKQApACAD7wApACkAKQAAAAAAKu2IAAgAL4OsgqyC2ABPgWyCzILMgUAAAAAsbYAAEAAXAZUCVQJwAlcCVQJVAZAAAAAAADwtoAAvACkAKQAgA+8AKQApAAAAP4PAAAAACi3AAAABHwERAREBAAEfAREBEQERAQABAAAKbcAAEAAXgFSAVIBQAFeAVIBUg9AAAAAAAAvtwAAQABeD1IJUglACV4JUglSCVIAQAAAADC3AABAAN4O0grSCsAK3grSCtILQAAAAAAAOLcAAEAAXg9SCVIJQAleCVIJUg9AAAAAAAA7twAAQABcCFQEVARAA1wCVARUCFQIAAAAAES3AAF8AUQBRAEAAXwBRAFEAQAA/g8AAAAAYLcAAPwBBAEEAQAA/AEEAQQBAAD+DwAAAAB8twAA5AEkASQBJAE8AQABAAD+DyAAIAAAAH23AAB0AFQBVAFUAVwBQAEAAX4PEAAQAAAAgLcAAHQAVA9UCFQIXAhACAAI/gkQABAAAACEtwAAPACsDqwKrAqsCqAKgAq+CwgACAAAAIy3AAB0AFQPVAlUCVwJQAkACX4PEAAQAAAAjbcAAHQAVA9UClQKXApACgAKfg8QABAAAACRtwAAdABUBlQJVAlcCUAJAAl+BhAAEAAAAJe3AAA6ACoBKgUqC64LIAsAC34FCAAIAAAAmLcAAOQBJAEkATwBAAD+ByAAIAD+DwAAAACZtwAAdABUAVQBXAEAAX4BEAEQAX4PAAAAAJy3AAD0AJQAlA6cCAAI/gkQCBAI/gkAAAAAqLcAAHQAVABUD1wJAAl+CRAJEAl+DwAAAACptwAAdABUAFQPXAoACnwKEAoQCn4PAAAAAKu3AAB0AFQIVARcBAACfgEQAhAE/gQABAAArbcAAHQAVABUBlwJAAl+CRAJEAl+BgAAAAC1twAAdABUAVQBVAFcAUABAAF+DygAKAAAAMm3AAB0AFQGVAlUCVwJQAkACX4GKAAoAAAA7LcAAOQBJAEkASQBPAEAASAA/g8AAAAAAADttwAAdABUAVQBVAFcAUABEAEQAX4PAAAAAPC3AAD0AJQAlA6UCJwIgAgQCBAI/gkAAAAA9LcAADwALACsDqwKrAqgCogKiAq+CwAAAAD8twAAdABUD1QJVAlcCUAJCAkICX4PAAAAAP23AAByAFIPUgpSCl4KQAoICggKfg8AAAAA/7cAAHQAVAhUBFQEXAJAARACEAT+BAAIAAABuAAAdABUBlQJVAlcCUAJEAkQCX4GAAAAAAe4AAA8ACwBLAUsC6wLIAsICwgFfAEAAAAACLgAAOQBJAEkATwBAAEgAP4HAAD+DwAAAAAJuAAAdABUAVQBXAFAARABfgEAAX4PAAAAAAy4AAD0AJQAlA6cCIAIEAj+CQAI/gsAAAAAGLgAAHQAVABUD1wJQAkQCX4JAAl+DwAAAAAZuAAAdABUAFQPXApACggKfAoACn4PAAAAABu4AAB0AFQIVARcBEACEAF+AgAE/gQABAAAHbgAAHQAVABUBlwJQAkQCX4JAAl+BgAAAAAkuAAA5AEkASQBJAE8AQABSAD+DwAAAAAAACW4AAB0AFQBVAFUAVwBQAEIASgBfg8AAAAAKLgAAPQAlACUDpQInAiACCgIKAj+CQAAAAAsuAAAfABMAMwOzArMCuAKhAqUCr4LAAAAADW4AAB0AFQAVA9UClwKQAoICigKfA8AAAAAObgAAHQAVAZUCVQJXAlACQgJKAl+BgAAAABAuAAA5AEkASQBPAEAAJAA/gcAAP4PAAAAAFy4AAAABPQElASUBJQHlASUBJwEAAQAAAAAXbgAAIAAugKqAqoC6gKqAqoCrg6AAAAAAABguAAAgAC6DqoIqgjqCKoIqgiuCIAAAAAAAGS4AABAAFoPWgtaC3oLWgtaC14LQAAAAAAAbLgAAIAAug+qCaoJ6gmqCaoJrg+AAAAAAABtuAAAgAC6DqoKqgrqCqoKqgquDoAAAAAAAG+4AACAALoIqgiqBOoCqgSqCK4IgAAAAAAAcbgAAIAAugaqCaoJ6gmqCaoJrgaAAAAAAACwuAACdAJUAlQC1ANUAlwCAAD+DwAAAAAAAMy4AAAABPQElAeUBJQElASUB5wEAAQAAAAA4bgAAIAAugbqCaoJqgmqCeoJrgaAAAAAAADouAAAAAF6AUoBSgFKD0oBSgFOAQABAAAAAOm4AACAALoCqgKqAqoDqgKqAq4OgAAAAAAA+LgAAEAAeg9qCWoJ6glqCWoJbg9AAAAAAAD5uAAAQAB6D2oKagrqCmoKagpuD0AAAAAAAPu4AABACHoIagRqBOoCagRqBG4IQAgAAAAABLmAALwArACsAKwPrACsAgAC/g8AAAAAAAA8uQAAgAC0ALQAtAe0ALwAAAD+DwAAAAAAAFi5AACAAPoAyg/KAMoAygDKD84AgAAAAAAAWbkAAIAAugKqA6oCqgKqAqoDrg6AAAAAAABcuQAAgAC6DqoIqguqCKoIqguuCIAIgAAAAGC5AABAAFoP2gtaC1oLWgvaC14LQAAAAAAAbbkAAIAAugaqCaoJqgmqCaoJrgaAAAAAAAB0uQAAAAT0BJQElASUBJQElAScBAAEAAAAAHi5AACAALoOqgiqCKoIqgiqCK4IgAAAAAAAfLkAAEAAWg9aC1oLWgtaC1oLXgtAAAAAAACEuQAAgAC6D6oJqgmqCaoJqgmuD4AAAAAAAIe5AACAALoIqgiqBKoCqgSqCK4IgAAAAAAAibkAAIAAugaqCaoJqgmqCaoJrgaAAAAAAACOuQAAQAB6CWoPaglqCWoJag9uCUAAAAAAAKy5AADkASQBJAEkATwBAAEAAP4PAAAAAAAArbkAAHQAVAFUAVQBXAFAAQABfg8AAAAAAACwuQAA9ACUDpQIlAicCIAIAAj+CQAAAAAAALS5AAA8ACwArA6sCqwKoAqACrwLAAAAAAAAvLkAAHQAVA9UCVQJXAlACQAJfg8AAAAAAAC9uQAAdABUD1QKVApcCkAKAAp+DwAAAAAAAL+5AAB0AFQIVARUAlwBQAIABP4EAAgAAAAAwbkAAHQAVAZUCVQJXAlACQAJfgkABgAAAADIuQAA/AEEAQQBBAH8AQAAAAD+DyAAIAAAAMm5AAB8AEQBRAFEAXwBAAEAAX4PEAAQAAAAzLkAAHwARA9ECEQIfAgACAAI/gkQABAAAADOuQAAPAAkDyQIJAE8BQALgAs+BQgBCAAAANC5AAA8AKQOpAqkCrwKgAqACr4LCAAIAAAA0bkAADwApA6kCqQLPAiAAIAAvg8IAAgAAADYuQAAfABED0QJRAl8CQAJAAl+DxAAEAAAANm5AAB8AEQPRApECnwKAAoACn4PCAAIAAAA27kAAHwARAhECEQEfAMABAAE/gkQCBAAAADduQAAfABEBkQJRAl8CQAJAAl+BhAAEAAAAN65AAB8AEQJRAlEBXwDAAUACX4JEAAQAAAA4bkAADwApA+kCqQKvAqACoAKvgoQABAAAADjuQAAPACkAKQEpAq8CoAKgAq+BAgACAAAAOS5AAD8AQQBBAH8AQAA/gcgACAA/g8AAAAA5bkAAHwARAFEAXwBAAF+ARABEAF+DwAAAADouQAAfABEAEQPfAgACP4JEAgQCP4JAAAAAPW5AAB8AEQARA98CgAKfgoQChAKfg8AAAAA97kAAHwARAhECHwEAAR+AxAEEAT+CQAIAAD5uQAAfABEAEQGfAkACX4JEAkQCX4GAAAAAPq5AAB8AEQJRAl8CQAFfgMQBRAJfgkAAAAAOLoAAPwBBAEEAQQB/AEgACAAIAD+DwAAAAA5ugAAfABEAUQBRAF8ARABEAEQAX4PAAAAADy6AAB8AEQARA9ECHwIEAgQCBAI/gkAAAAAQLoAADwAJACkDqQKvAqICogKvgsAAAAAAABIugAAfABED0QJRAl8CRAJEAkQCX4PAAAAAEu6AAB8AEQIRAhEBHwEEAMQBBAI/gkACAAATboAAHwARAZECUQJfAkQCRAJEAl+BgAAAABOugAAfABECEQJRAl8BRADEAUQCX4JAAAAAFS6AAD8AQQBBAH8ASAAIAD+BwAA/g8AAAAAVboAAHwARAFEAXwBEAEQAX4BAAF+DwAAAABYugAAfABEAEQPfAgQCBAI/gkACP4JAAAAAFy6AAA8ACQApA68CogKiAq8CoAKvgsAAAAAZLoAAHwARABED3wJEAkQCX4JAAl+DwAAAABnugAAfABECEQIfAQQBBADfgQACP4JAAgAAGm6AAB8AEQARAZ8CRAJEAl+CQAJfgYAAAAAcLoAAPwBBAEEAQQB/AGQAJAAkAD+DwAAAAB0ugAAfABEAEQPRAh8CCgIKAgoCP4JAAAAAHi6AAA8ACQApA6kCrwKlAqUCr4LAAAAAAAAhboAAHwARAZECUQJfAkoCSgJKAl+BgAAAACHugAAPAAkCSQJJAk8BagDKAV+CQAIAAAAAKi6AAAABHwERAREBMQHRAREBHwEAAQAAAAAqboAAEAAXgFSAVIBcgFSAVIBXg9AAAAAAACsugAAgAC8DqQIpAjkCKQIpAi8CIAAAAAAALC6AABAAN4O0grSCvIK0grSCt4LQAAAAAAAuLoAAEAAXg9SCVIJcglSCVIJXg9AAAAAAAC5ugAAQABeD1IKUgpyClIKUgpeD0AAAAAAALu6AABACF4EUgRSAnIBUgJSBF4EQAgAAAAAvboAAEAAXgZSCVIJcglSCVIJXgZAAAAAAAD8ugACfAJEAkQCxANEAnwCAAD+DwAAAAAAABi7AAAABHwExAdEBEQERATEB3wEAAQAAAAANLsAAIAAvACkAKQApA+kAKQAvACAAAAAAAA1uwAAQABeAVIBUgHSAVIBUgFeD0AAAAAAADa7AABAAF4BUgFSDlIAUgFSAV4PQAAAAAAAOLsAAIAAvA6kCKQIpAukCKQIvAiAAAAAAAA7uwAAQABeD1IJUgnSCVIJUgleCUAAAAAAADy7AABAAN4O0grSCtIK0grSCt4LQAAAAAAARLsAAEAAXg9SCVIJ0glSCVIJXg9AAAAAAABHuwAAQAheCFIIUgTSAlIEUgheCEAIAAAAAFC7AACAALwApACkB6QAvAEAAf4PAAAAAAAAWLsAACAALg8qC2oLKgsuCwALfgsAAAAAAABjuwAAIAA+CPIJMggyBL4CgAT+CQAIAAAAAKS7AACAALwApA+kAKQApACkD7wAgAAAAAAArLsAAEAA3g7SCtIK0grSCtIK3gtAAAAAAADAuwAAAAR8BEQERAREBEQERAR8BAAEAAAAAPi7AAD8AQQBBAEEAfwBAAAAAP4PAAAAAAAA+bsAAHwARAFEAUQBfAEAAQABfg8AAAAAAAD8uwAAfABEAEQPRAh8CAAIAAj+CQAAAAAAAP+7AAB8AEQPRAlECXwJAAkACX4JAAAAAAAAALwAADwApA6kCqQKvAqACoAKvgsAAAAAAAAJvAAAPAAkACQPJAo8CgAKAAp+DwAAAAAAAAy8AAB8CEQERANEBHwIAAQAA34EAAgAAAAADbwAAHwARAZECUQJfAkACQAJfgkABgAAAAAPvAAAPAAkCSQJJAk8BYADAAV+CQAIAAAAABG8AAA8AKQPpAqkCrwKgAqACr4KAAAAAAAAFLwAAPwBIAEgASAB/AEAAAAA/g8gACAAAAAVvAAAfgBIAUgBSAF+AQABAAF+DxAAEAAAABa8AAB+AEgBSAFID34AAAEAAX4PEAAQAAAAGLwAAHwAUA9QCFAIfAgACAAI/gkQABAAAAAbvAAAfgBID0gJSAl+CQAJAAl+CRAAEAAAABy8AAA8AKgOqAqoCrwKgAqACr4LCAAIAAAAHbwAADwAqA6oCqgLPAiAAIAAvg8IAAgAAAAfvAAAPACoDqgKqAs8AAAPAAq+DwgACAAAACS8AAB+AEgPSAlICX4JAAkACX4PEAAQAAAAJbwAAHwASA9ICkgKfAoACgAKfA8QABAAAAApvAAAfgBIBkgJSAl+CQAJAAl+BhAAEAAAAC28AAB8AMgPyArICvwKgAqACr4KCAAIAAAAMLwAAPwBIAEgAfwBAAD+ByAAIAD+DwAAAAAxvAAAfgBIAUgBfgEAAX4BEAEQAX4PAAAAADS8AAB8AFAAUA98CAAI/gkQCBAI/gkAAAAAOLwAADwAKACoDrwKgAq+CogKiAq+CwAAAABAvAAAfgBIAEgPfgkACXwJEAkQCX4PAAAAAEO8AAB+AEgISAh+BAAEfgMQBBAE/gkACAAARbwAAH4ASABIBn4JAAl+CRAJEAl+BgAAAABJvAAAPAAoAKgPvAqACr4KiAqICr4KAAAAAIS8AAD8ASABIAEgAfwBIAAgACAA/g8AAAAAiLwAAHwAUABQD1AIfAgQCBAIEAj+CQAAAACMvAAAPAAoAKgOqAq8CogKiAq+CwAAAAAAAJS8AAB+AEgPSAlICXwJEAkQCRAJfg8AAAAAlbwAAH4ASABID0gKfAoQChAKEAp+DwAAAACXvAAAfgBICEgISAR8BBADEAQQBP4JAAgAAKC8AAD8ASABIAH8ASAAIAD+BwAA/g8AAAAApLwAAHwAUABQD3wIEAgQCP4JAAj+CQAAAACnvAAAfgBIAEgPfAkQCRAJfgkACX4JAAAAAKi8AAA8ACgAqA68CogKiAq+CoAKvgsAAAAAvLwAAPwBIAEgASAB/AGQAJAAkAD+DwAAAAC9vAAAfgBIAUgBSAF8ASgBKAEoAX4PAAAAAMC8AAB8AFAAUA9QCHwIKAgoCCgI/gkAAAAAxLwAAD4AKACoDqgKvAqoCqgKvgsAAAAAAADNvAAAfgBIAEgPSAp8CigKKAooCn4PAAAAANG8AAB+AEgGSAlICXwJKAkoCSgJfgYAAAAA1bwAAHwASADID8gK/AqoCqgKvgoAAAAAAAD0vAAAAAR8BFAEUATQB1AEUAR8BAAEAAAAAPW8AACAAL4BpAGkAeQBpAGkAb4PgAAAAAAA9rwAAEAAXgFUAVQPdABUAVQBXg9AAAAAAAD4vAAAgAC8DqgIqAjoCKgIqAi8CIAAAAAAAPy8AABAAN4O1ArUCvQK1ArUCt4LQAAAAAAABL0AAEAAXg9UCVQJdAlUCVQJXg9AAAAAAAAHvQAAQAReBFQEVAJ0AVQCVAReBEAEAAAAAAm9AABAAF4GVAlUCXQJVAlUCV4GQAAAAAAAJL2AALwIqAToAqgEqAi8CAAG/gQQCBAAAABIvQACfAJIAkgCyANIAnwCAAD+DwAAAAAAAFm9AABAAFwPWAp4ClgKXAoACnwPAAAAAAAAgL0AAIAAvACoAKgAqA+oAKgAvACAAAAAAACBvQAAQAB+AWQBZAHkAWQBZAF+D0AAAAAAAIS9AACAALwOqAioCKgLqAioCLwIgAAAAAAAiL0AAEAA3g7UCtQK1ArUCtQK3gtAAAAAAACJvQAAQABeD1QLVAvUCVQBVAFeD0AAAAAAAJC9AABAAF4PVAlUCdQJVAlUCV4PQAAAAAAAk70AAEAIXghUBFQE1AJUBFQEXghACAAAAACVvQAAQABeBlQJVAnUCVQJVAleBkAAAAAAAJm9AABAAF4PVAtUC9QLVAtUC14LQAAAAAAA1L0AAIAAvACoAKgPqAC8AAAA/A8AAAAAAADwvQAAgAC8AKgPqACoAKgAqA+8AIAAAAAAAAy+AAAABPwEkASQBJAEkASQBPwEAAQAAAAAEL4AAIAAvA6oCKgIqAioCKgIvAiAAAAAAAAUvgAAQADeDtQK1ArUCtQK1AreC0AAAAAAAES+AAD8ASABIAEgAfwBAAAAAP4PAAAAAAAARb4AAH4ASAFIAUgBfgEAAQABfg8AAAAAAABIvgAAfABQD1AIUAh8CAAIAAj+CQAAAAAAAEy+AAA8ACgAqA6oCrwKgAqACr4LAAAAAAAAVL4AAH4ASA9ICUgJfgkACQAJfg8AAAAAAABXvgAAfgBICEgESAR+AwAEAAT+CQAIAAAAAFm+AAB+AEgGSAlICX4JAAkACX4JAAYAAAAAWr4AAH4ASAlICUgJfgUAAwAFfgkAAAAAAABbvgAAPgAoCSgJKAU+BYADAAV+CQAIAAAAAGC+AAD8ASAB/AH4ACAB/AEAAP4PIAAAAAAAYb4AAH4ASAF+AX4BSAF+AQABfg8QAAAAAABovgAAPACoDrwKvAqoCrwKgAq+CwgAAAAAAHW+AAB+AEgGfgl+CUgJfgkACX4GEAAAAAAAfL4AAPwBIAH8AfgAIAH4AP4HIAD+DwAAAACPvgAAfAB8CAAIfARQAnwC/gIQBP4IAAgAAKi+AAB+AEgPfgl+CUgJfgkACX4PKAAAAAAA0L4AAPwBIAH8AfgAIAEgAfwBIAD+DwAAAADUvgAAfABQD3wIfAhQCHwIEAgQCP4JAAAAANe+AAB+AEgPfgl+CUgJfAkQCRAJfgkAAAAACL8AAPwBIAH8AfgAIAEgAfwBkAD+DwAAAAAJvwAAfgBIAX4BPAFIAXwBKAEoAX4PAAAAAFG/AABAAH4PZAp+CmAKfgpkCn4PQAAAAAAAVb8AAEAAfgZkCWQJfgl+CWQJZAZ+AEAAAADMv4AAvACoAKgAvACAD7wAqACoALwAgAAAANC/AACAALwOqAi8CIALvAioCKgIvAAAAAAAWMAABPwEkASQBPwEAAT8BJAEkAT8BAAEAABowAAAQAB+D2QJfglACX4JZAlkD34AQAAAAKzAAAEAAcAAPABAAIAAAAEAAP4PIAAgAAAArcBAAEAAIAEcASABQAFAAQABfg8QABAAAACwwIAAQAAgDx4IIAhACEAIAAj+CRAAEAAAALTAIAAgAJAOjgqQCqAKoAqACr4LCAAIAAAAtsAAACAAsA6OCpALEACgD4AIvg8IAAgAAAC8wEAAQAAgDxwJIAlACUAJAAl+DxAAEAAAAL/AQABACCAIHAQgBEADQAIABP4IEAgQAAAAwcBAAEAAIAYcCSAJQAlACQAJfgYQABAAAADIwAAAAAHAADwAwAEAAP4HIAAgAP4PAAAAAMnAAABAACAAHAFgAQABfgEQARABfg8AAAAAzMAAAMAAIAAcD2AIAAj+CRAIEAj+CQAAAADQwAAAIAAQAI4OsAqACr4KiAqICr4LAAAAANjAAABAACAAHA9gCQAJfAkQCRAJfg8AAAAA3cAAAEAAIAAcBmAJAAl+CRAJEAl+BgAAAADkwAACAAHAADwAwAAAAQACAAD+D5AAkAAAAOzAIAAgAJAOjgqQCqAKoAqACr4LFAAUAAAA9cBAAEAAMA8OCjAKQApACgAKfg8kACQAAAD3wEAAQAggBBwEEAIgAUACAAT+BCgIKAAAABzBAAIAAcAAPADAAAABIAIgACAA/g8AAAAAHcFAAEAAMAEOARABIAFIAQgBCAF+DwAAAAAewUAAQAAwAQ4BEAEgD0AACAEIAX4PAAAAACDBgACAAGAAHA4gCEAIgAgQCBAI/gkAAAAAJMFAACAAEACODpAKoAqgCogKiAq+CwAAAAAswUAAQAAwDw4JEAkgCUgJCAkICX4PAAAAAC3BQABAADAADg8QCmAKSAoICn4PAAAAAAAAL8FAAEAAMAgOBBAEIAJAAQgCCAT+BAAIAAAxwUAAQAAwBg4JEAkgCUgJCAkICX4GAAAAADjBAAAAA4AAfADAAAADIAD+DwAA/g8AAAAAOcEAAEAAMAAOATABQAEIAX4BAAF+DwAAAAA8wQAAgABgABwPYAiACBAI/AkACP4JAAAAAEDBAAAgABAAjg6QCqAKiAq+CoAKvgsAAAAASMEAAEAAMAAODzAJQAkICX4JAAl+DwAAAABLwQAAQAAwBA4EMARAAggBfgIABP4EAAQAAFTBAAIAAcAAPABAAIAACAFIAEgA/g8AAAAAWMGAAEAAYAAcDiAIQAiACCgIKAj+CQAAAAB0wQAAgABgABwPYAiACCgI/gkACP4JAAAAAHjBAABAADAAjg6wCoAKlAq+CoAKvgsAAAAAjMEAAIAEQARABCAEnAcgBEAEQASABAAAAACNwQAAUABQAUgBRAFmAUgBSAFQD1AAAAAAAJDBAACgAKAOkAiICOQIiAiQCKAIoAAAAAAAlMEAAFAA0A7QCsgK5grICtAK0AtQAAAAAACcwQAAUABQD0gJSAlmCUgJSAlQD1AAAAAAAJ3BAABQAFAPSApICmYKSApIClAPUAAAAAAAn8EAAFAIUARIBEQCZgFEAkgEUARQCAAAAAChwQAAUABQBkgJSAlmCUgJSAlQBlAAAAAAAKXBAABQAFAPUAtIC2YLSAtQC1ALUAAAAAAAxMEAACACEALOAxACAAD+DyAAIAD+DwAAAADgwQAAQAJAAiACnAMgAkACAAD+DwAAAAAAAPzBAARABEAEIAcQBAwEMAQgB0AEQAQABAAADcIAAFAASA9oCkQKRgpECmgKSA9QAAAAAAAYwgAAoACgAJAAiACGD4gAkACgAKAAAAAAABnCAABQAFABUAFIAcYBSAFQAVAPUAAAAAAAHMIAAKAAoA6QCJAIjAuQCJAIoAigAAAAAAAfwgAAUABQD1AJSAnGCUgJUAlQCVAAAAAAACDCAABQANAO0ArICsQKyArQCtALUAAAAAAAKMIAAFAAUA9QCUgJxglICVAJUA9QAAAAAAArwgAAUAhQCFAISATGAkgEUAhQCFAIAAAAAC3CAABQAFAGUAlICcYJSAlQCVAGUAAAAAAAL8IAACgIKAUoBSQFogMkBSgFKAUoCAAAAAAywkAAUAlQCVAPSAnGCUgJUA9QCVAJQAAAAFDCAABQAEgAxgdIAFABAAH+BwAA/g8AAAAAWMIAACgAKA9mCygLaAtAC34LAAt+CwAAAABswgAAoACgAJAAjA+QAKAAAAD+DwAAAAAAAHDCQABQAFAPSAjGCUgIUAgACP4JAAAAAAAAfcJAAFAAUA9ICsQKSApQCgAKfg8AAAAAAACIwgAAoACQAJAPiACGAIgAkA+QAKAAAAAAAJDCAAAoAKgO6AqkCqIKpAroCqgLKAAAAAAApMIAAIAEQARABCAEHAQgBEAEQASABAAAAACowgAAoACgDpAIkAiMCJAIkAigCKAAAAAAAKzCAABQANAO0ArICsQKyArQCtALUAAAAAAAtMIAAFAAUA9QCUgJRglICVAJUA9QAAAAAAC1wgAAUABQD1AKSApGCkgKUApQD1AAAAAAALfCAABQCFAEUARIAkYDSAJQBFAEUAgAAAAAucIAAFAAUAZQCUgJRglICVAJUAZQAAAAAADcwgACAAHAADwAwAAAAQABAAD+DwAAAAAAAN3CQAAgADABDgEQASABQAEAAX4PAAAAAAAA4MKAAEAAIAAcDyAIQAhACAAI/gkAAAAAAADjwkAAQAAwDwwJEAkgCUAJAAl+CQAAAAAAAOTCIAAgABAAjg6QCqAKoAqACr4LAAAAAAAA68IAACAAkA6OCpALIAAgBYALPgsABQAAAADswkAAQAAwDwwJMAkgCUAJAAl+DwAAAAAAAO3CQABAADAADA8wCiAKQAoACn4PAAAAAAAA78JAAEAIMAgMBDAEQANABAAE/ggACAAAAADxwkAAQAAgBhwJIAlACUAJAAl+CQAGAAAAAPbCQABAADAIDAkQDyAJQAkAD34JAAAAAAAA+MIAAYABfACAAIABfACAAQAA/g8gAAAAAAD5wkAAIAAcASABYAEcAWABAAF+DxAAAAAAAPzCQABgABwPYAhgCBwIYAgACP4JEAAAAAAAAMMgABAAjg6QCrAKjgqwCoAKvgsIAAAAAAAIw0AAIAAcDyAJYAkcCWAJAAl+DxAAAAAAAA3DQAAgABwGIAlgCRwJYAkACX4GEAAAAAAAE8MgABAAjgCQBJAKzgqQCoAKvgQIAAAAAAApwwAAYAA8BkAJPAlgCQAJfgkQCX4GAAAAAGjDAAKAAXwAgAOAAXwAgAEgAiAA/g8AAAAAacNAADAAHgEgAWABHgEgAUgBCAF+DwAAAABsw4AAQAA8AEAOwAg8CEAIkAgQCP4JAAAAAHDDIAAQAIwOsAqwCowKkAqgCogKvgsAAAAAecNAADAADgAwD2AKHgowCkAKCAp+DwAAAACEwwAAgAH8AAAB/ACAASAA/A8AAP4PAAAAAIjDAADAADwAwA48CMAIEAj8CQAI/gkAAAAAjMMAACAAHACgDpwKoAqICr4KgAq+CwAAAADYwwAAQAQgBBwEIARAByAEHAQgBEAEAAAAAN/DAABQAEgPRglICWgJSAlGCUgJUAAAAAAA4MMAAFAAyA7GCsgK6ArICsYKyAtQAAAAAABkxAAAoACQAI4AkACgD5AAjgCQAKAAAAAAAPDEAACABGAEHARgBIAEYAQcBGAEgAQAAAAA9MQAAKAAkA6MCJAIoAiQCIwIkAigAAAAAAD4xAAAUADQDswKyArQCtgKxArIC1AAAAAAAADFAABQAEgPRglICVAJSAlGCUgPUAAAAAAADMVAAiACHAJgAmACHAIgAkACAAD+DwAAAAAoxQABgAF8AIABgAN8AIAAAAEAAP4PAAAAACnFQAAgABwBIAFgARwBIAFAAQABfg8AAAAALMVAAGAAHA9gCOAIHAhgCEAIAAj+CQAAAAAwxSAAEACODpAKsAqOCpAKoAqACr4LAAAAADnFQAAgABwPIApgChwKIApACgAKfg8AAAAAO8VAACAAHAggCGAEHAQgA0AEAAT+CQAIAAA9xUAAIAAcBiAJYAkcCSAJQAkACX4GAAAAAETFAADwAAgBBAIIAfAAAAAAAP4PIAAgAAAARcUAADgARAFEAUQBOAEAAQABfg8QABAAAABIxQAAOABED0QIJAg4CAAIAAj+CRAAEAAAAEnFAAA4AEQPRAhEDDgIgASAA74EEAgQAAAASsUAADgARA9ECEQBOAUAC4ALPgUIAQgAAABMxQAAHACiDqIKogqcCoAKgAq+CwgACAAAAFPFAAA8AMIOwgrCCzwAAAWACz4FCAAIAAAAVMUAADgARA9ECUQJOAkACQAJfg8QABAAAABVxQAAOABED0QKJAoYCgAKAAp+DwgACAAAAFfFAAA4AEQIRAREBDgDAAIABP4IEAgQAAAAWcUAADgARAZECUQJOAkACQAJfgYQABAAAABexQAAOABICUQJRA84CQAJAA9+CRAAEAAAAGDFAAD4AQQCBAL4AQAA/g8gACAA/g8AAAAAYcUAADgARABEAUQBOAF8ARABEAF+DwAAAABkxQAAOABEAEQPRAg4CP4JEAgQCP4JAAAAAGjFAAAYACQApA6kCpgKvAqICogKvAsAAAAAcMUAADgARABED0QJOAl8CRAJEAl+DwAAAABzxQAAOABECEQIRAQ4An4DEAQQBP4IAAgAAHXFAAA4AEQARAZECTgJfgkQCRAJfgYAAAAAfMUAAPAACAEEAggB8AAAAAAA/g+QAJAAAAB9xQAAOABEAUQBRAE4AQABAAF+DygAKAAAAIDFAAA4AEQPRAhECDgIAAgACP4JSABIAAAAhMUAABwAog6iCqIKnAqACoAKvgsUABQAAACHxQAAPADCDsIKwgs8AAAPAAq+DxQAFAAAAI3FAAA4AEQPRApECjgKAAoACn4PJAAkAAAAj8UAADgARAhEBEQCOAEAAgAE/gQoCCgAAACRxQAAOABEBkQJRAk4CQAJAAl+BigAKAAAAJXFAAA4AMQPxArECrgKgAqACr4KJAAkAAAAl8UAABwAogCiBKIKnAqACoAKvgQUABQAAACYxQAA+AEEAgQC+AEAAP4PkACQAP4PAAAAALTFAADwAAgBBAIIAfAAIAAgACAA/g8AAAAAtcUAADgARABEAUQBKAEQARABEAF+DwAAAAC4xQAAOABEAEQPRAgoCBAIEAgQCP4JAAAAALnFAAA4AEQPRAgkBKgAkAyQA5AEvggAAAAAu8UAADgARABED0QJKAkQCRAJEAl+CQAAAAC8xQAAHAAiAKIOogqUCogKiAq+CwAAAAAAAMTFAAA4AEQPRAlECSgJEAkQCRAJfg8AAAAAxcUAADgARABED0QKKAoQChAKEAp8DwAAAADGxQAAOABED0QKRAooDxAAEAwQA3wEAAgAAMfFAAA4AEQIRAREBCgCEAEQAhAE/ggACAAAycUAADgARAZECUQJKAkQCRAJEAl+BgAAAADKxQAAOABECEQJRAkoBRADEAUQCX4JAAAAAMzFAAA4AEQERAVEBSgFEAUQBRAFfg8AAAAAzsUAADgARAhECUQPKAkQCRAPEAl+CQAAAADQxQAA+AEEAgQC+AEgACAA/g8AAP4PAAAAANHFAAA4AEQARAFEATgBEAF8AQABfg8AAAAA1MUAADgARABED0QIOAgQCP4JAAj+CQAAAADYxQAAGAAkAKQOpAqYCogKvAqACrwLAAAAAODFAAA4AEQARA9ECTgJEAl8CQAJfg8AAAAA48UAADgARAhECEQEOAIQA34EAAT+CAAIAADsxQAA+AAEAQQCBAH4AIgAiACIAP4PAAAAAO3FAAA4AEQBRAFEATgBKAEoASgBfg8AAAAA8MUAADgAKABED0QIOAgoCCgIKAj+CQAAAAD0xQAAHAAiAMIOwgq8CqQKpAq+CwAAAAAAAPfFAAA8AMIOwgrCCzwApA8kCSQJvg8AAAAA/MUAADgARA9ECSQJOAkoCSgJKAl+DwAAAAD9xQAAOABEAEQPRAo8CiQKJAokCn4PAAAAAP/FAAA4AEQIRAREBDgCKAEoAigE/gQACAAAAcYAADgARAZECUQJOAkoCSgJKAl+BgAAAAAGxgAAOABECEQJRA84CSgJKA8oCXwJAAAAAAjGAAD4AQQCDAPwAJAAkAD+DwAA/g8AAAAAEMYAABgAJACkDqQKvAqkCr4KgAq+CwAAAAAZxgAAOABEAEQPJAo8CiQKfgoACn4PAAAAABvGAAA4AEQIRAhEBDgCKAF8AgAE/ggACAAAJMYAAAAEMARIBIQEhAeEBEgEMAQABAAAAAAlxgAAQABcAVIBYgFiAWIBUgFcD0AAAAAAACjGAACAAJwOlAiiCOIIogiUCJwIgAAAAAAALMYAAEAAzA7SCtIK8grSCtIKzAtAAAAAAAAuxgAAQADMDtIK0gtyANIP0gjMD0AAAAAAADPGAABAAMwO0grSC3IAUgVSC0wLQAUAAAAANcYAAEAATA9SClIKcgpSClIKTA9AAAAAAAA3xgAAQABcCFIEYgJiAWICUgRcCEAAAAAAADnGAABAAFwGUgliCWIJYglSCVwGQAAAAAAAO8YAAEAATAlSCVIFcgNSBVIFTAlAAAAAAABAxgAAGAIkAsQDJAIkAhgCAAD+DyAAIAAAAEHGgACcAKIB4gGiAZQBnAEAAX4PEAAQAAAARMaAAJgApA7kCKQIpAiYCAAI/AsgACAAAABRxkAATABSD3IKUgpSCkwKAAp+DxAAEAAAAFXGQABcAGIGYgliCVQJXAkACX4GEAAQAAAAXMYAADgBRAHEAUQBOAD+B0AAQAD+DwAAAABgxgAAmACkAMQOpAiYCAAI/AkgCP4LAAAAAHjGAAIwAkgCRALEA0QCOAIAAP4PAAAAAAAAfMaAAJwAkg6iCOIIogicCAAI/gkAAAAAAACUxgAAAAQ4BMgHRAREBEQEyAc4BAAEAAAAAJXGAACAAJwB4gGiAaIBogHkAZwPgAAAAAAAqcYAAEAATAZyCVIJUglSCXIJTAZAAAAAAACwxgAAgACcAJQAogCiD6IAlACcAIAAAAAAALHGAABAAFwBYgFiAeIBYgFiAVwPQAAAAAAAtMYAAEAAXA9kCGII4gtiCFQIXAhAAAAAAAC4xgAAQADMDtIK0grSCtIK0grMC0AAAAAAAMDGAABAAEwPUglSCdIJUglSCUwPQAAAAAAAw8YAAEAATAhSCFIE0gJSBFIITAhAAAAAAADFxgAAQABcBmIJYgniCWIJYglcBkAAAAAAAMzGgACYAKQApACkB6QAmAEAAf4PAAAAAAAAzcYgACwAMgLyAjICMgKsAoAC/g4AAAAAAADQxkAATABSD1II0glSCAwIgAj+CQAAAAAAANTGIAAsADIPMgtyCzILLAsAC34LAAAAAAAA6MZAAFgAZADkB2QAWAEAAfwHAAD+DwAAAADsxgAASABUDtQIVAjICIAI/AkACP4LAAAAAPDGAAAsADIPcgsyC2wLQAt+CwALfgsAAAAA+cYAACwAMg9yCjIKbApACv4KAAp+DwAAAAAEx4AAmACkAKQApA+kAJgAAAD8DwAAAAAAAAjHQABcAGIPYgjiCWIIXAgACP4JAAAAAAAADMcgACwAsg6yCvIKsgqsCoAKvgsAAAAAAAAXx0AATABSCFII0glSBEwDAAT+CQAIAAAAABnHQABMAFIGUgrSCVIJTAkACX4GAAAAAAAAIMcAAIAAnACiD6IAogCiAKIPnACAAAAAAAAhxwAAQABcAeIBYgFiAWIB4gFcD0AAAAAAACTHAABAAFwOZAjiC2IIYgjiC1wIQAAAAAAAKMcAAEAAzA7SCtIK0grSCtIKzAtAAAAAAAA1xwAAQABMBtIJUglSCVIJ0glMBkAAAAAAADzHAAAABDAESASEBIQEhARIBDAEAAQAAAAAPccAAEAAXAFiAWIBYgFiAWQBXA9AAAAAAABAxwAAgACcDqQIogiiCKIIpAicCIAAAAAAAETHAABAAMwO0grSCtIK0grSCswLQAAAAAAATMcAAEAAXA9iCWIJYgliCWIJXA9AAAAAAABNxwAAQABMD1IKUgpSClIKUgpMD0AAAAAAAFHHAABAAFwGZAliCWIJYglkCVwGQAAAAAAAWMcAAjgCRAJEAkQCRAI4AgAA/g8AAAAAAAB0xwAA8AAIAQQCBAIIAfAAAAD+DwAAAAAAAHXHAAA4AEQBRAFEAUQBOAEAAX4PAAAAAAAAeMcAADgAKABED0QIRAg4CAAI/gkAAAAAAAB8xwAAHAAUAKIOogqcCoAKgAq+CwAAAAAAAH3HAAA4AMQOxArECrgLAAiAALwPAAAAAAAAg8cAABwAog6iCqILHAAABYALPgsABQAAAACExwAAOABED0QJRAkoCTgJAAl+DwAAAAAAAIXHAAA4ACgARA9ECkQKOAoACn4PAAAAAAAAh8cAADgARAhEBEQCRAE4AgAE/ggACAAAAACIxwAAOAhEBEQDRAQoCDAEAAN+BAAIAAAAAInHAAA4AEQGRAlECSgJOAkACX4JAAYAAAAAiscAADgARAhECUQJRAU4AwAFfgkAAAAAAACOxwAAOABECUQJRA8oCTgJAA9+CQAAAAAAAJDHAAIEAcQAPABEAIQABAEAAP4PIAAgAAAAkcdAAEQAJAEcASQBRAFEAQABfg8QABAAAACUx4AARAAkDxwIJAhECEQIAAj+CRAAEAAAAJbHAABEADQPDAgUACQFIAuACz4FCAEIAAAAmMdAACQAlA6MCpQKpAqkCoAKvgsIAAgAAACgx0AARAAkDxwJJAlECUQJAAl+DxAAEAAAAKHHQABEACQPHAokCkQKRAoACn4PEAAQAAAAo8eAAEQIJAgcBCQERANAAgAE/ggQCBAAAAClx4AARAAkBhwJJAlECUQJAAl+BhAAEAAAAKbHQABECCQJHAkkBUQDRAUACX4JEAAQAAAArMcAAAQBxAA8AMQBAAD+ByAAIAD+DwAAAACtxwAARAAkABwBZAEAAX4BEAEQAX4PAAAAALzHAABEACQAHA9kCQAJfgkQCRAJfg8AAAAAwccAAEQAJAAcBmQJAAl+CRAJEAl+BgAAAADIxwACBAHEADwAxAAEAQQCAAD+D5AAkAAAAN3HgABEACQGHAkkCUQJRAkACX4GKAAoAAAAAMgAAgQBxAA8AMQABAEkAiAAIAD+DwAAAAAByEAARAAkARwBJAFEAVQBEAEQAX4PAAAAAATIgABEACQAHA8kCEQIhAgQCBAI/gkAAAAACMhAACQAFACMDpQKoAqoCogKvgsAAAAAAAAKyAAAJACkDpwKpAskAIQPkAi+DwAAAAAAABDIQABEACQPHAkkCUQJVAkQCRAJfg8AAAAAEchAAEQAJAAcDyQKRApQChAKfg8AAAAAAAATyIAARAAkCBwIJAREBEQDEAQQCP4JAAgAABXIgABEACQGHAkkCUQJVAkQCRAJfgYAAAAAFshAAEQAJAkcCSQJRAVUAxAFEAl+CQAAAAAcyAAABAKEAXwAhAAkAyAA/g8AAP4PAAAAAB3IAABEACQAHAEkAUQBEAF+AQABfg8AAAAAIMgAAIQAZAAcDyQIRAgQCP4JAAj+CQAAAAAkyAAAJAAUAIwOlAqgCogKvAqACr4LAAAAACzIAABEACQAHA8kCUQJEAl+CQAJfg8AAAAAL8gAAIQAZAgcCCQERAQQA34EAAj+CQAIAAA4yAACBAHEADwARACEAAQBUABQAP4PAAAAADzIgABEACQAHA8kCEQIjAgoCCgI/gkAAAAAcMgAAIQERAREBCQEnAckBEQERASEBAAAAABxyAAAUABSAVIBSgFmAUoBUgFSD1AAAAAAAHTIAACgAKQOpAiUCMwIlAikCKQIoAAAAAAAeMgAAFAA0g7SCsoK5grKCtIK0gtQAAAAAACAyAAAUABSD1IJSglmCUoJUglSD1AAAAAAAIHIAABQAFIPUgpKCmYKSgpSClIPUAAAAAAAhcgAAFAAVAZUCUwJbAlMCVQJVAZQAAAAAACLyCAAKgEqBSoLKgumCyoLKgsyBTIBIAAAAIzIgAJEAiQCnAMkAkQCRAIAAP4PQABAAAAAxMgAAEACRAIkApwDJAJEAgAA/g8AAAAAAADgyAAEhAREBEQHJAQcBCQERAdEBIQEAAQAAOTIAACgAKQOpAiUCIwIlAjUCJQIpAiAAAAA/MgAAKAApACkAJQAjA+UAKQApACgAAAAAAD9yAAAUABSAVIBSgHGAUoBUgFSD1AAAAAAAADJAACgAKQOpAiUCIwLlAikCKQIoAAAAAAABMkAAFAA0g7SCsoKxgrKCtIK0gtQAAAAAAAMyQAAUABSD1IJSgnGCUoJUglSD1AAAAAAAA3JAABQAFIPUgpKCsYKSgpSClIPUAAAAAAAEckAAFAAVAZUCVQJzAlUCVQJVAZQAAAAAAAYyQAAoACkAJQAjAeUAKQBAAH+DwAAAAAAAFDJAACgAKQAlACMD5QApAAAAP4PAAAAAAAAbMmAAKQApACkD5QAjACUAKQPpACkAIAAAACIyQAAhASEBEQEJAQcBCQERASEBIQEAAAAAInJAABQAFQBVAFUAUwBVAFUAVQPUAAAAAAAjMkAAKAApA6kCJQIjAiUCKQIpAigAAAAAACQyQAAMACyDqoKqgqmCqoKqgqyCzAAAAAAAJjJAABQAFIPUglKCUYJSglSCVIPUAAAAAAAmckAAFAAUg9SCkoKRgpKClIKUg9QAAAAAACdyQAAUABUBlQJVAlMCVQJVAlUBlAAAAAAAMDJAAIEAcQAPADEAAQBBAIAAP4PAAAAAAAAwckAAEAARAAkARwBJAFEAQABfg8AAAAAAADEyQAAgABEACQPHAhkCIQIAAj+CQAAAAAAAMfJQABEACQPHAkkCUQJQAkACX4JAAAAAAAAyMlAACQAFACMDpQKpAqgCoAKvgsAAAAAAADQyQAAQABEDyQJHAkkCUQJAAl+DwAAAAAAANHJAABAAEQAJA8cCiQKRAoACn4PAAAAAAAA08kAAIAARAgkCBwEZANABAAI/gkACAAAAADVyQAAgABEBiQJHAkkCUQJAAl+CQAGAAAAANnJIAAkAJQPjAqUCqQKoAqACr4KAAAAAAAA2skAAEAARAgkCRwPJAlECQAPfgkAAAAAAADcyQABhAF8AIQDgAB8AIQBAAD+DyAAAAAAAN3JQAAkABwBZAFgARwBZAEAAX4PEAAAAAAA58kgABQAjA60CqALHAC0DwAKvg8IAAAAAADxyUAAJAAcBmQJYAkcCWQJAAl+BhAAAAAAAPjJAACEAXwAgAF8AIQBAAD+ByAA/g8AAAAADMoAAGQIPAxAAzwEZAgABH4DEAT+CAAIAABMygAChAF8AIQBgAN8AIQBIAIgAP4PAAAAAE3KQAAkABwBZAEgARwBJAFEARABfg8AAAAAUMqAAEQAPADEDkAIPAhECJQIEAj+CQAAAABUyiAANACcDqQKsAqMCpQKoAqICr4LAAAAAFzKQAAkABwPZAlgCRwJJAlECRAJfg8AAAAAvcoAAFIASgFGAUoBaAFKAUYBSg9SAAAAAADTygAAUgBKCUYFSgVoA0oFRgVKCVIAAAAAAEjLAACkAKQAnACkAKAPpACcAKQApAAAAAAAScsAAFQAVAFMAVQB0AFUAUwBVA9UAAAAAADUywAAhARkBDwERASABEQEPARkBIQEAAAAAAzMAAKEAXwAhAGAA3wAhAEEAgAA/g8AAAAADcxAACQAHAFkASABHAEkAUQBAAF+DwAAAAAQzIAAZAA8DsQIQAg8CGQIhAgACP4JAAAAABzMQAAkABwPJAlgCRwJJAlECQAJfg8AAAAAIsxAACQAHAlkCSAFHAMkBUQFAAl+CQAAAAAozAABCAHIAD4AyAAIAQgBAAD+DyAAIAAAACnMQABEACQBHgEkAUQBRAEAAX4PEAAQAAAALMyAAEQAJA8eCCQIRAhECAAI/gkQABAAAAAuzAAARAA0Dw4IFAEkBSALgAs+BQgBCAAAADDMIAAkAJQOjgqUCqQKpAqACr4LCAAIAAAAOMxAAEQAJA8eCSQJRAlECQAJfg8QABAAAAA7zEAARAgkCB4EJAJEA0QCAAT+CBAIEAAAAD3MgABEACQGHgkkCUQJRAkACX4GEAAQAAAAPsxAAEQIJAkeCSQFRANEBQAJfgkQABAAAABEzAAACAHIAD4AyAEAAP4HIAAgAP4PAAAAAEXMAABEACQAHgFkAQABfgEQARABfg8AAAAATMwAACQAFACODrQKgAq+CogKiAq+CwAAAABUzAAARAAkAB4PZAkACX4JEAkQCX4PAAAAAFnMAABEACQAHgZkCQAJfgkQCRAJfgYAAAAAYMwAAggBiAB+AMgACAEIAgAA/g+QAJAAAABkzIAAhABkDh4IJAhECIQIAAj+CUgISAAAAJjMAAIIAcgAPgDIAAgBKAEgACAA/g8AAAAAmcxAAEQAJAEeASQBRAFUARABEAF+DwAAAACczIAARAAkAB4PJAhECIQIEAgQCP4JAAAAAKDMQAAkACQAng6kCqQKhAqQCr4LAAAAAAAAqMxAAEQAJA8eCSQJRAlUCRAJEAl+DwAAAACpzEAARAAkAB4PJApEClQKEAp+DwAAAAAAAKvMgABEACQIHgQkBEQCRAEQAhAE/gkACAAArcyAAEQAJAYeCSQJRAlUCRAJEAl+BgAAAAC0zAAACAHIAD4AyAAIASAA/gcAAP4PAAAAALzMAABEACQAng6kCoQKkAq+CoAKvgsAAAAA0MwAAggCiAF+AIgACAEYApAA/g8AAAAAAAAIzQAAgASIBEgEKAQ8BygESASIBIAEAAAAAAnNAACgAKQCpAKUAs4ClAKkAqQOoAAAAAAADM0AAKAApA6kCJQIzgiUCKQIpAigAAAAAAAbzQAAoAikCKQIlATOApQEpAikCKAIAAAAAB3NAACgAKQGpAmUCc4JlAmkCaQGoAAAAAAALM0AAFQAVA9OC1QLVAtUCwALfgsQABAAAABczQAAQAJEAiQCngMkAkQCAAD+DwAAAAAAAHjNAASIBEgESAcoBBwEKARIB0gEiAQABAAAlM0AAEABRAEkARQBHg8UASQBRAFAAQAAAACVzQAAUABUAVQBVAHOAVQBVAFUD1AAAAAAAJjNAACgAKQOpAiUCI4LlAikCKQIoAAAAAAAnM0AAGAAZA9UC1QLzgtUC1QLZAtgAAAAAACkzQAAUABUD1QJVAnOCVQJVAlUD1AAAAAAAKXNAABgAGQPVApUCs4KVApUCmQPYAAAAAAAp80AAFAIVAhUBFQEzgJUBFQEVAhQCAAAAACpzQAAUABUBlQJVAnOCVQJVAlUBlAAAAAAAOjNAACgAKQAlACOD5QApAAAAP4PAAAAAAAABM6AAKQApACkD5QAjgCUAKQPpACkAIAAAAAgzgAAgASIBIgESAQ8BEgEiASIBIAEAAAAACHOAABQAFQBVAFUAU4BVAFUAVQPUAAAAAAAMM4AAFAAVA9UCVQJTglUCVQJVA9QAAAAAAA1zgAAUABUBlQJVAlOCVQJVAlUBlAAAAAAAFjOAAAAAggBiAB+AIgBCAIAAP4PAAAAAAAAWc4AAEAARAAkAR4BJAFEAQABfg8AAAAAAABczgAAgABEACQPHggkCMQIAAj+CQAAAAAAAGDOAAAgACQAlA6OCpQKpAqACr4LAAAAAAAAaM5AAEQAJA8kCR4JJAlECQAJfg8AAAAAAABpzgAAQABEACQPHgokCkQKAAp+DwAAAAAAAGvOAABAAEQIJAQeBiQBQAIABP4EAAgAAAAAbc4AAEAARAYkCR4JJAlECQAJfgkABgAAAAB0zgAAJAIkAZQAZAAcAAAAAAD+DyAAIAAAAHXOAABUAFQBNAE0AQwBAAEAAX4PEAAQAAAAeM4QAFQAVA80CBQIDAgACAAI/gkQABAAAAB8zgAAKgCqDqoKmgqGCoAKgAq+CwgACAAAAITOAABUAFQPVAk0CQwJAAkACX4PEAAQAAAAhc4AAFQAVA80CjQKDAoACgAKfg8QABAAAACJzgAAlABUBlQJNAkMCQAJAAl+BhAAEAAAAJDOIAEkAZQAdAAcAAAA/gcgACAA/g8AAAAAlM4AAJAAVAA0DxwIAAj+CRAIEAj+CQAAAACgzgAAkABUADQPDAkACX4JEAkQCX4PAAAAAKHOAACQAFQANA8MCgAKfAoQChAKfg8AAAAAo86QAJQAVAg0CAwEAAJ+AxAEEAT+CQAIAADkzgAAJAIkAaQAZAAcAAAAIAD+DwAAAAAAAOjOAACQAFQAVA88CAwIAAgQCBAI/gkAAAAA7M4AAFAAVAA0DrQKjAqACpAKkAq+CwAAAAD0zgAAkABUAFQPNAkMCQAJEAkQCX4PAAAAAPXOAACQAFQAVA80CgwKAAoQChAKfg8AAAAA984AAJAAVAQ0CDQEDAKAARACEAT+CAAEAAAAzxABJAGUAFQAPAAgACAA/gcAAP4PAAAAAATPAACUAFQANA8cCBAIEAj+CQAI/gkAAAAACM8AAFAAVAA0DpwKkAqQCrwKgAq+CwAAAAAQzwAAkABUADQPHAkQCRAJfgkACX4PAAAAABPPkACUAFQINAQcBBACEAF+AgAE/ggACAAAHM8AACQCJAGkAGQAHACQAJAA/g8AAAAAAABUzwAEJAQkBCQEpAckBCQEJAT8BAAEAAAAAFjPAACAAJQOlAiUCNQIlAiUCLwIgAAAAAAAXM8AAEAAyg7KCsoK6grKCsoK3gtAAAAAAABkzwAAQABKD0oJSglqCUoJSgleD0AAAAAAAGXPAABAAEoPSgpKCmoKSgpKCl4PQAAAAAAAac8AAEAASgZKCUoJaglKCUoJXgZAAAAAAABwzwAAJAIkAqQDJAIkAvwCAAD+D0AAQAAAAIzPEAEkAaQBFAEUAXwBAAD+B0AA/g8AAAAAxM8ABCAEJASkByQEJASkByQE/AQABAAAAADgzwAAgACUAJQAlACUD5QAlAD8AIAAAAAAAOHPAABAAFIBUgFSAdIBUgFSAX4PQAAAAAAA6M8AACAAqg6qCqoK6gqqCqoKvgsgAAAAAAD8z0AAVABUANQHVABUAHwBAAH+DwAAAAAAADTQAABAAFQAVADUB1QAfABAAAAA/g8AAAAANdAAAEAAVABUAdQBVAF8AQABfg8AAAAAAAA40EAAVABUD1QI1AlUCHwIAAj+CQAAAAAAADzQIAAqAKoOqgrqCqoKvgqACr4LAAAAAAAAUNAAAJAAlACUD5QAlACUAJQP/ACAAAAAAABs0AACIAIkAiQCJAIkAiQCJAL8AgACAAAAAHDQAABAAFQPVAhUCFQIVAhUCHwIQAAAAAAAdNAAACAArA6sCqwKrAqsCqwKvAsgAAAAAAB80AAAQABSD1IJUglSCVIJUgl+D0AAAAAAAKTQAAIkAiQBpABkABwAAAAAAP4PAAAAAAAAqNAAAJAAlABUDjQIDAgACAAI/gkAAAAAAACs0EgAKgCqDpoKmgqGCoAKgAq+CwAAAAAAALTQAACQAFQAVA80CQwJAAkACX4PAAAAAAAAudAAAJQAVAZUCTQJDAkACQAJfgkABgAAAADA0AAA/AEkASQBJAEkAQABAAD+DyAAIAAAAMHQAAB8AFQBVAFUAVQBQAEAAX4PEAAQAAAAxNAAAPwAlA6UCJQIlAiACAAI/gkQABAAAADI0AAAPACsDqwKrAqsCqAKgAq+CwgACAAAANDQAAB8AFQPVAlUCVQJQAkACX4PEAAQAAAA0dAAAHwAVA9UClQKVApACgAKfg8QABAAAADT0AAAfABUCFQEVAJUAUACAAT+CBAIEAAAANXQAAB8AFQGVAlUCVQJQAkACX4GEAAQAAAA3NAAAPwBJAEkASQBAAD+ByAAIAD+DwAAAADd0AAAfABUAVQBVAEAAX4BEAEQAX4PAAAAAODQAAB8AFQAVA9UCAAI/gkQCBAI/gkAAAAA5NAAAHwAVADUDtQKgAq8CogKiAq+CwAAAADs0AAAfABUAFQPVAkACXwJEAkQCX4PAAAAAO3QAAB8AFQAVA9UCgAKfAoQChAKfg8AAAAA8dAAAHwAVABUBlQJAAl+CRAJEAl+BgAAAAAw0QAA/AEkASQBJAEkAQABIAAgAP4PAAAAADHRAAB8AFQBVAFUAVQBQAEQARABfg8AAAAANNEAAPwAlACUDpQIlAiACBAIEAj+CQAAAAA40QAAfABUANQO1ArUCsAKiAq+CwAAAAAAAEDRAAB8AFQPVAlUCVQJQAkQCRAJfg8AAAAARdEAAHwAVAZUCVQJVAlACRAJEAl+BgAAAABM0QAA/AEkASQBJAEAASAA/gcAAP4PAAAAAE3RAAB8AFQBVAFUAUABEAF+AQABfg8AAAAAUNEAAPwAlACUDpQIgAgQCP4JAAj+CwAAAABU0QAAfABUANQO1ArACogKvAqACr4LAAAAAFzRAAB8AFQAVA9UCUQJEAl+CQAJfg8AAAAAXdEAAHwAVABUD1QKRAoQCnwKAAp+DwAAAACg0QAAAAT8BJQElASUB5QElASUBAAEAAAAAKHRAACAAL4CqgKqAuoCqgKqAqoOgAAAAAAApNEAAIAAvg6qCKoI6giqCKoIqgiAAAAAAACo0QAAQABeD1oLWgt6C1oLWgtaC0AAAAAAALDRAACAAL4PqgmqCeoJqgmqCaoPgAAAAAAAsdEAAIAAvg6qCqoK6gqqCqoKqg6AAAAAAAC10QAAgAC+BqoJqgnqCaoJqgmqBoAAAAAAAPTRAAAAAnwCVALUA1QCVAIAAP4PAAAAAAAALNIAAAABfAFUAVQBVA9UAVQBVAEAAQAAAAA00gAAQABeD1oLWgvaC1oLWgtaC0AAAAAAADzSAACAAL4PqgmqCaoJqgmqCaoPgAAAAAAAQdIAAIAAvgaqCaoJqgmqCaoJqgaAAAAAAACA0gAAgAC8ALQAtAe0ALQAAAD+DwAAAAAAAJzSAAAAAXwBVA9UAVQBVAFUD1QBAAEAAQAAuNIAAAAE/ASUBJQElASUBJQElAQABAAEAAC50gAAgAC+AqoCqgKqAqoCqgKqDoAAAAAAALzSAACAAL4OqgiqCKoIqgiqCKoIgAAAAAAAv9IAAIAAvg+qCaoJqgmqCaoJqgmAAIAAAADA0gAAQABeD1oLWgtaC1oLWgtaC0AAAAAAAMjSAACAAL4PqgmqCaoJqgmqCaoPgAAAAAAA8NIAAPwBJAEkASQBJAEAAQAA/g8AAAAAAADx0gAAfABUAVQBVAFUAUABAAF+DwAAAAAAAPTSAAB8AFQAVA9UCFQIQAgACP4JAAAAAAAA+NIAADwALACsDqwKrAqgCoAKvgsAAAAAAAAA0wAAfABUD1QJVAlUCUAJAAl+DwAAAAAAAAHTAAB8AFQAVA9UClQKQAoACn4PAAAAAAAABdMAAHwAVAZUCVQJVAlACQAJfgkABgAAAAAM0wAABAH8AQQBBAH8AQQBAAD+DyAAIAAAAA3TAABEAHwBRAFEAXwBRAEAAX4PEAAQAAAADtMAAEQAfAFEAUQPfABEAQABfg8QABAAAAAQ0wAAhAD8DoQIhAj8CIQIAAj+CRAAEAAAABTTAAAkALwOpAqkCrwKpAqACr4LCAAIAAAAHNMAAEQAfA9ECUQJfAlECQAJfg8QABAAAAAd0wAARAB8D0QKRAp8CkQKAAp+DxAAEAAAAB/TAABEAHwIRAREBHwDRAIABP4IEAgQAAAAKNMAAAQB/AEEAfwBAAD+ByAAIAD+DwAAAAAp0wAARAB8AEQBfAEAAX4BEAEQAX4PAAAAACzTAABEAHwARA98CAAI/gkQCBAI/gkAAAAAfNMAAAQB/AEEAQQB/AEEASABIAD+DwAAAAB90wAARAB8AUQBRAF8AUQBUAEQAX4PAAAAAIDTAABEAHwARA9ECHwIRAhQCBAI/gkAAAAAhNMAAEQAfADEDsQK/ArECsAKiAq+CwAAAACM0wAARAB8D0QJRAl8CUQJUAkQCX4PAAAAAJjTAAAEAfwBBAH8AQQBIAD+BwAA/g8AAAAAmdMAAEQAfABEAXwBRAEQAX4BAAF+DwAAAACc0wAARAB8AEQPfAhECBAI/gkACP4JAAAAAKDTAABEAHwAxA78CsAKiAq8CoAKvgsAAAAAqNMAAEQAfABED3wJRAkQCX4JAAl+DwAAAACr0wAARAB8CEQIfAREAhADfgQABP4IAAgAALTTAAAEAfwBBAEEAfwBBAFQAVAA/g8AAAAAuNMAAIQA/ACEDoQI/AioCCgIKAj+CQAAAAC80wAARAB8AMQOxAr8CtgKmAqYCr4LAAAAAMnTAABEAHwGRAlECXwJaAkoCSgJfgYAAAAA0NMAAAQB/AEEAfwBBAFQAP4HAAD+DwAAAADs0wAERAREBHwERATEB0QEfAREBEQEAAQAAO3TgACiAKICvgKiAuICogK+AqIOgAAAAAAA8NMAAIAApA68CKQI5AikCLwIpAikAIAAAAD00wAAQABSD14LUgtyC1ILXgtSC1IAQAAAAPzTAABAAFIPXglSCXIJUgleCVIPQAAAAAAAAdRAAFIAUgZeCVIJcglSCV4JUgZAAAAAAABc1AAERAREBPwHRAREBEQE/AdEBEQEAAQAAHjUgACkAKQAvACkAKQPpAC8AKQApACAAAAAedRAAGIAYgJ+AmIC4gNiAn4CYg5AAAAAAAB81AAAgACkDrwIpAikC6QIvAikCKQAgAAAAIDUAABAAFIPXgtSC9ILUgteC1ILUgBAAAAAiNQAAEAAUg9eCVIJ0glSCV4JUg9AAAAAAACL1EAAUghSCF4EUgTSAlIEXgRSCFIIQAAAAI3UQABSAFIGXglSCdIJUgleCVIGQAAAAAAA6NSAAKQApAC8D6QApACkALwPpACkAIAAAAAE1QAEhASEBPwEhASEBIQE/ASEBIQEAAQAAAjVAACAAKQOvAikCKQIpAi8CKQIpACAAAAADNUAAEAAUg9eC1ILUgtSC14LUgtSAAAAAAAU1QAAQABSD14JUglSCVIJXglSD0AAAAAAADzVAAAEAfwBBAEEAfwBBAEAAP4PAAAAAAAAPdUAAEQAfAFEAUQBfAFEAQABfg8AAAAAAABA1QAAhAD8DoQIhAj8CIQIAAj+CQAAAAAAAETVAAAkALwOpAqkCrwKpAqACr4LAAAAAAAATNUAAEQAfA9ECUQJfAlECQAJfg8AAAAAAABP1QAARAB8CEQERAJ8AUQCAAT+CAAIAAAAAFHVAABEAHwGRAlECXwJRAkACX4JAAYAAAAAWNUIAOgBGAIcAhgC6AEIAAAA/g8gACAAAABZ1QQAdACMAY4BjAF0AQQBAAF+DxAAEAAAAFzVBABkAJQOlgiUCGQIBAgACP4JIAAgAAAAYNUEADQAzA7OCswKtAqECoAKvgsQABAAAABo1QQAdACMD44JjAl0CQQJAAl+DxAAEAAAAGnVBAA0AEwPTgpMCjQKBAoACn4PEAAQAAAAa9UEAGQIlAiWCJQEZAIEBAAI/gkQCBAAAABt1QQAZACUBpYJlAlkCQQJAAl+BhAAEAAAAHTVAADIACgBHAFoAYAA/gdAAEAA/gcAAAAAddUAAGQAlACWAZQBYAF+ARABEAF+DwAAAAB41QAAZACUAJYOlAhkCP4JIAggCP4JAAAAAITVAABkAJQAlg+UCWQJPgkQCRAJfg8AAAAAh9UAAGQAlAiWCJQIZAT+AhAEEAj+CQAIAACJ1QAAZACUAJYGlAlkCT4JEAkQCX4GAAAAAKXVBABkAJQGlgmUCWQJBAkACX4GKAAoAAAAyNUIAMgBKAIsAigCyAEIAEAAQAD+DwAAAADM1QQAZACUAJYOlAhkCAQIIAggCP4JAAAAANjVBAB0AIwPjgmMCXQJBAkQCRAJfg8AAAAA29UEAGQAlAiWCJQEZAQEAxAEEAj+CQAIAADk1QAA6AEYAhwCGALoAQAA/g8AAP4PAAAAAOzVAAA0AEwAzg7MCrQKgAq+CoAKvgsAAAAA9NUAAGQAlACWD5QJdAkQCX4JAAl+DwAAAAAA1ggA6AAYARwCGAHoAAgAoACgAP4PAAAAAAHWBAB0AIwBjgGMAXQBBAFQAVABfg8AAAAABNYEAGQAlACWDpQIZAgECFAIUAj+CQAAAAAI1gQANABMAE4PTAs0CwALKAt+CwAAAAAAABHWBAB0AIwAjg6MCnQKBApQClAKfg8AAAAAFdYEAGQAlAaWCZQJZAkECVAJUAl+BgAAAAAc1gAA6AEYAhwCOAPoAKAA/g8AAP4PAAAAADjWAAAIBGgEmASYBJwHmASYBGgECAQAAAAAOdYAAIQAtALMAswCzgLMAswCtA6EAAAAAAA81gAAhAC0DswIzAjOCMwIzAi0CIQAAAAAAEDWAABEAFQPbAtsC24LbAtsC1QLRAAAAAAASNYAAIQAlA6sCqwK7gqsCqwKlA6EAAAAAABJ1gAAhACUDqwKrAruCqwKrAqUDoQAAAAAAE3WAACEAJQGrAmsCe4JrAmsCZQGhAAAAAAAVNYEAmQClAKWA5QCZAIEAgAA/g9AAEAAAABV1oQAtALMAs4CzAK0AoQCAAL+DhAAEAAAAFjWhAC0AMwOzgjMCLQIhAgACP4JIAAgAAAAXNYAAFQAbA9uC2wLVAtECwALfgsQABAAAABp1oAAlACsBu4JrAmUCYQJAAl+BhAAEAAAAIzWAAAEAmQClAKWA5QCZAIAAP4PAAAAAAAAjdYAAIQAtADMAs4CzAK0AgAC/g4AAAAAAACf1gAAhAC0CMwIzgTMArQEAAT+CQAIAAAAAKHWAACEAJQGrAnuCawJlAkACX4JAAYAAAAAqNYABAgEaASYB5gEnASYBJgHaAQIBAAEAADE1gAABAEkAVQBVAFWD1QBVAEkAQQBAAAAAMjWAACEALQOzAjMCM4JzAjMCLQIhAAAAAAAzNYAAEQAVA9sC2wL7gtsC2wLVAtEAAAAAADU1gAAhACUDqwKrAquC6wKrAqUDoQAAAAAAOjWAABEAFQPbAtuC2wL1AuAC/4LAAAAAAAA/NaAALQAzADOD8wAtAIAAv4PAAD+DwAAAAAA14AAlACsAK4NrAiUCQAJ/gsACP4LAAAAABjXAAAEATQBTAFOD0wBNAEAAP4PAAAAAAAAINdAAEQAVA9sC+4LbAtUCwALfgsAAAAAAAA01wAABAEkAVQPVAFWAVQBVA8kAQQBAAEAAEnXAACEAJQGrAmsCa4JrAmsCZQGhAAAAAAAUNcAAAgE6AQYBRgFHAUYBRgF6AQIBAAAAABR1wAAhAC0AswCzALOAswCzAK0DoQAAAAAAFTXAACEALQOzAjMCM4IzAjMCLQIhAAAAAAAWNcAAEQAVA9sC2wLbgtsC2wLVAtEAAAAAABZ10AARABUD2wLbAtuCGwBbAFUD0QAAAAAAGHXAACEAJQOrAqsCq4KrAqsCpQOhAAAAAAAZdcAAIQAtAbMCcwJzgnMCcwJtAaEAAAAAABp1wAARABUD2wLbAtuC2wLbAtUC0QAAAAAAGzXAAAEAmQClAKWApQCZAIAAP4PAAAAAAAAcNcAAIQAtA7MCM4IzAi0CAAI/gkAAAAAAACI1wgAyAAoARgCHAIYAugBAAD+DwAAAAAAAIzXBABkAJQAlA6WCJQIZAgACP4JAAAAAAAAkNcEADQAzA7MCs4KzAq0CoAKvgsAAAAAAACY1wQAdACMD4wJjgmMCXQJAAl+DwAAAAAAAJnXBAA0AEwATA9OCkwKNAoACn4PAAAAAAAAndcEAGQAlAaUCZYJlAlkCQAJfgkABgAAAAAQ/gAAAAAAAAAAAAAAAAAACAALAAYAAAAAABH+AAAAAAAAAAAAAAAAAAAAAAIABAAIAAAAEv4AAAAAAAAAAAAAAAAAAAAADAASABIADAAT/gAAAAAAAAAAAAAAAAAAAAAMAwgCAAAAABT+AAAAAAAAAAAAAAAAAAAACIwFCAMAAAAAFf4AAAAAAAAAAAAAAAAAAAAAfgMAAgAAAAAW/gAAAAAAAAAAAAAAAAQAAgBCA2ICEgAMABf+gA+ABIACgAKAAYABgAGAAYACgAKABIAPGP4+ACQAKAAoADAAMAAwADAAKAAoACQAPgAZ/gAAAAAAAAAAAABmBkQEAAAAAAAAAAAAADD+AAAAAAAAAAAAAAwDCAIAAAAAAAAAAAAAMf4AAAAAAAAAAAAA/gcAAAAAAAAAAAAAAAAy/gAAAAAAAAAAAADgAAAAAAAAAAAAAAAAADP+/w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAANP6ZCWYGAAAAAAAAAAAAAAAAAAAAAAAAAAA1/gAIAAQABAACAAIAAgACAAIABAAEAAgAADb+AgAEAAQACAAIAAgACAAIAAQABAACAAAAN/4ACAAEAAQABAAEAAIABAAEAAQABAAEAAg4/gIABAAEAAQABAAIAAQABAAEAAQABAACADn+AAgABAACAAIAAgACAAIAAgACAAQACAAAOv4CAAQACAAIAAgACAAIAAgACAAEAAIAAAA7/gAOAAYAAgACAAIAAgACAAIAAgAGAA4AADz+DgAMAAgACAAIAAgACAAIAAgADAAOAAAAPf4ACgAJAAWABIACgAKAAoAEAAUACQAKAAA+/goACgASABQAJAAoACQAFAASAAoACgAAAD/+AAgABAAEAAIAAgABAAIAAgAEAAQACAAAQP4CAAQABAAIAAgAEAAIAAgABAAEAAIAAABB/gAAAAAAAAABAAEAAQABAAEAAQABAAEAD0L+HgAQABAAEAAQABAAEAAQABAAAAAAAAAAQ/4AAAAAAAAAAwADAAMAAwADAAMADwAJAA9E/h4AEgAeABgAGAAYABgAGAAYAAAAAAAAAEX+AAAAAAgAEAAwAHAA4ADAA8AHAAMAAAAARv4AAAAACAAYACgAyAAQAyAEQASAAwAAAABH/gAOAAIAAgACAAIAAgACAAIAAgACAAIADkj+DgAIAAgACAAIAAgACAAIAAgACAAIAA4ASf4AAAAAAgACAAAAAgACAAAAAgACAAAAAABK/gAAAAACAAIAAAACAAAAAgACAAIAAAAAAEv+AgACAAIAAgACAAIAAgACAAIAAgACAAIATP4KAAoACgAKAAYACgAKAAoABgAKAAoACgBN/gAAAAAABAAEAAAABAAEAAAABAAEAAAAAE7+AAAAAAAEAAQAAAAEAAAABAAEAAQAAAAAT/4ABAAIAAgABAAEAAgACAAEAAQACAAIAARQ/gAAAAAAAAAAAAAACgAGAAAAAAAAAAAAAFH+AAAAAAAAAAAAAgAEAAgAAAAAAAAAAAAAUv4AAAAAAAAAAAAAAAAABAAAAAAAAAAAAABU/gAAAAAAAAAAAAAgCgAGAAAAAAAAAAAAAFX+AAAAAAAAAAAAAEAEAAAAAAAAAAAAAAAAVv4AAAAAAAAgABAAEA2QAGAAAAAAAAAAAABX/gAAAAAAAAAAAAAAAPANAAAAAAAAAAAAAFj+AAAAAAAAAAIAAgACAAIAAgACAAIAAAAAWf4AAAAAAAAAAAAAwAMwDAAAAAAAAAAAAABa/gAAAAAAAAAAEAAgDMADAAAAAAAAAAAAAFv+AAAAAAAAAAAAAOAHEAgAAAAAAAAAAAAAXP4AAAAAAAAAABAIYAeAAAAAAAAAAAAAAABd/gAAAAAAAAAAAADgBxAIAAAAAAAAAAAAAF7+AAAAAAAAAAAAABAI4AcAAAAAAAAAAAAAX/4AAAAAAAAAAEAF8APgB1ABAAAAAAAAAABg/gAAAAAAAAAGYAmQCWAGAAYACQAAAAAAAGH+AAAAAAAAAABgADAAYAAAAAAAAAAAAAAAYv4AAAAAAAAAAQABwAcAAQABAAAAAAAAAABj/gAAAAAAAAAAAAEAAQABAAEAAAAAAAAAAGT+AAAAAAAAAACAAIABgAFAAkACAAAAAAAAZf4AAAAAAABAAkACgAGAAQABAAAAAAAAAABm/gAAAAAAAAAAQAJAAkACQAIAAAAAAAAAAGj+AAAAAAAAAAAQAOAAAAcACAAAAAAAAAAAaf4AAAAAAAAAAGACkASYDJAEIAMAAAAAAABq/gAAAADgABAB4AwAA8AAMAeACAAHAAAAAGv+AAAAAMADIASQCVAKUAmQCSACwAEAAAAAAf8AAAAAAAAAAAAA/AYABAAAAAAAAAAAAAAC/wAAAAAAAAAADwAAAAAADwAAAAAAAAAAAAP/AAAAAJAAkAT8A5AAkAT8A5AAkAAAAAAABP8AAAAAAAAYAiQERARGDIQECAMAAAAAAAAF/wAAeACEAIQEeALAATAAyAMkBCAEwAMAAAb/AAAAAIADeAREBKQEGAMAA8AEAAQAAAAAB/8AAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAI/wAAAAAAAAAAAAAAAAAAAADwAQwGAggAAAn/AAACCAwG8AEAAAAAAAAAAAAAAAAAAAAACv8AAAAAEAEQAaAAQAD8B0AAoAAQARABAAAL/wAAQABAAEAAQAD8B0AAQABAAEAAAAAAAAz/AAAAAAAAAAAAAWABwAAAAAAAAAAAAAAADf8AAEAAQABAAEAAQABAAEAAQABAAAAAAAAO/wAAAAAAAAAAAABgAEAAAAAAAAAAAAAAAA//AAgABAACAAGAAEAAIAAQAAgABAACAAAAEP8AAAAAAADwAQgCBAQEBAgC8AEAAAAAAAAR/wAAAAAAAAAEBAQEBPwHAAQABAAAAAAAABL/AAAAAAAACAQIBAQGBAXEBDgEAAAAAAAAE/8AAAAAAAAIAggERAREBKQEuAMAAAAAAAAU/wAAAAAAAIABYAEQAQgB/AcAAQAAAAAAABX/AAAAAAACfAIkBCQEJAREAoQBAAAAAAAAFv8AAAAAAADwAUgCJAQkBCQCyAMAAAAAAAAX/wAAAAAAAAQABACEB2QAHAAEAAAAAAAAABj/AAAAAAAAmANkBEQERAREBLgDAAAAAAAAGf8AAAAAAAB4AoQEhASEBEgC8AEAAAAAAAAa/wAAAAAAAAAAAAAYAxACAAAAAAAAAAAAABv/AAAAAAAAAAAACIwFCAMAAAAAAAAAAAAAHP8AAEAAQACgAKAAEAEQAQgCCAIEBAAAAAAd/wAAoACgAKAAoACgAKAAoACgAKAAAAAAAB7/AAAAAAQECAIIAhABEAGgAKAAQABAAAAAH/8AAAAAAAAIAAQAhAbEBCQAGAAAAAAAAAAg/wAA4AEYAgQE5AgSCZII4ggSBYQAeAAAACH/AAAAAAAEAAPwAIwAjADwAAADAAQAAAAAIv8AAAAAAAD8B0QERAREBEQEuASAAwAAAAAj/wAAAAAAAPABCAIEBAQEBAQEBAgCAAAAACT/AAAAAAAA/AcEBAQEBAQEBAgC8AEAAAAAJf8AAAAAAAD8B0QERAREBEQEBAQAAAAAAAAm/wAAAAAAAAAA/AdEAEQARABEAAQAAAAAACf/AAAAAPAACAMIAgQEBAREBEQEyAMAAAAAKP8AAAAA/AdAAEAAQABAAEAAQAD8BwAAAAAp/wAAAAAAAAQEBAT8BwQEBAQAAAAAAAAAACr/AAAAAAAAAAIABAAEAAT8AwAAAAAAAAAAK/8AAAAAAAD8B0AAIABQAIgBBAIEBAAAAAAs/wAAAAAAAAAA/AcABAAEAAQABAAAAAAAAC3/AAAAAPwHCABwAIADAAHwAAgA/AcAAAAALv8AAAAAAAD8BwgAMABAAIABAAL8BwAAAAAv/wAAAADwAQgCBAQEBAQEBAQIAvABAAAAADD/AAAAAAAA/AeEAIQAhACEAEgAOAAAAAAAMf8AAAAA+AAEAQICAgICBgIKBAn4CAAAAAAy/wAAAAAAAPwHRABEAEQAxABEAzgEAAAAADP/AAAAAAAAGAIkBEQERASEBAgDAAAAAAAANP8AAAAABAAEAAQA/AcEAAQABAAAAAAAAAA1/wAAAAD8AQACAAQABAAEAAQAAvwBAAAAADb/AAAAAAQAOADAAQAGAAbAATgABAAAAAAAN/8MAPABAAaAA3AADAB4AIADAAbwAQwAAAA4/wAAAAAAAAQEDAKwAUAAsAEMAgQEAAAAADn/AAAAAAQAGABgAIAHYAAYAAQAAAAAAAAAOv8AAAAAAAAEBAQHhAREBDQEDAQEBAAAAAA7/wAAAAAAAAAAAAAAAAAAAAAAAP4PAggCCDz/AgAEAAgAEAAgAEAAgAAAAQACAAQACAAAPf8CCAII/g8AAAAAAAAAAAAAAAAAAAAAAAA+/wAAAAAAAAAAAgABAAEAAgAAAAAAAAAAAD//AAgACAAIAAgACAAIAAgACAAIAAgACAAIQP8AAAAAAAAAAAEAAQACAAAAAAAAAAAAAABB/wAAAAAAACADkASQBJAEkALgBwAAAAAAAEL/AAAAAAAA/gcgBBAEEAQgAsABAAAAAAAAQ/8AAAAAAADAASACEAQQBBAEIAIAAAAAAABE/wAAAAAAAMABIAIQBBAEEAL+BwAAAAAAAEX/AAAAAAAAwAGgApAEkASgBOACAAAAAAAARv8AAAAAAAAQABAA/AcSABIAEgAAAAAAAABH/wAAAAAAALgGRAlECUQJPAkEBQAGAAAAAEj/AAAAAAAA/gcgABAAEAAQAOAHAAAAAAAASf8AAAAAAAAAAAAABgDwBwAAAAAAAAAAAABK/wAAAAAAAAAAAAAAAPsPAAAAAAAAAAAAAEv/AAAAAAAAAAD+B4AAwAAgARAGEAQAAAAATP8AAAAAAAAAAAAA/gMABAAEAAQAAAAAAABN/wAA8AcgABAAEAAQAOAHIAAQABAA4AcAAE7/AAAAAAAA8AcgABAAEAAQAOAHAAAAAAAAT/8AAAAAAADAASACEAQQBCACwAEAAAAAAABQ/wAAAAAAAPwPCAEEAQQBiABwAAAAAAAAAFH/AAAAAAAAcACIAAQBBAEEAfwPAAAAAAAAUv8AAAAAAAAAAPAHIAAQABAAEAAAAAAAAABT/wAAAAAAAGACUASQBJAEkAQgAwAAAAAAAFT/AAAAAAAAEAAQAPwDEAQQBBAEAAAAAAAAVf8AAAAAAADwAwAEAAQABAAC8AcAAAAAAABW/wAAAAAQAGAAgAMABIADYAAQAAAAAAAAAFf/AAAQAOABAAaAA2AAMADAAwAGwAEwAAAAWP8AAAAAAAAQBDACwAFAATACEAQAAAAAAABZ/wAAAAAECBgI4AQAA8AAOAAEAAAAAAAAAFr/AAAAAAAAAAQQBpAFUAQwBBAEAAAAAAAAW/8AAAAAAAAAAAAAAAAAAAAAQAC8BwIIAABc/wAAAAAAAAAAAAD/DwAAAAAAAAAAAAAAAF3/AAACCPwHAAAAAAAAAAAAAAAAAAAAAAAAXv9AAEAAIAAgACAAQACAAIAAgABAAEAAAABf/wAAAAAAAAAAAAAAAAAA/AMCDPgBBg4AAGD/AAACCPwHAAD+DwAAAAAAAAAAAAAAAAAAYf8ABgAJAAkABgAAAAAAAAAAAAAAAAAAAABi/wAAAAD+AQIAAgACAAAAAAAAAAAAAAAAAGP/AAgACAAI8A8AAAAAAAAAAAAAAAAAAAAAZP8AAAABAAIABAAAAAAAAAAAAAAAAAAAAABl/wAAAABgAEAAAAAAAAAAAAAAAAAAAAAAAGb/AABICEgMSAO4AAAAAAAAAAAAAAAAAAAAZ/8AABAE0AMQAGAAAAAAAAAAAAAAAAAAAABo/wAAAAGAAMAPMAAAAAAAAAAAAAAAAAAAAGn/AADgADAMIALgAQAAAAAAAAAAAAAAAAAAav8ABCAE4AcgBAAEAAAAAAAAAAAAAAAAAABr/wAAIAGgBPgHIAAAAAAAAAAAAAAAAAAAAGz/AACAAPAAQA/gAAAAAAAAAAAAAAAAAAAAbf8AAAAEIAQgB+AEAAAAAAAAAAAAAAAAAABu/wAAIASgBKAE4A8AAAAAAAAAAAAAAAAAAG//wAAACOAEAALgAQAAAAAAAAAAAAAAAAAAcP8AAEAAQABAAEAAQAAAAAAAAAAAAAAAAABx/wgICA7oAQgAeAAAAAAAAAAAAAAAAAAAAHL/QADAAEAA8A8MAAQAAAAAAAAAAAAAAAAAc/8AAHgADgaIAXgAAAAAAAAAAAAAAAAAAAB0/wgCCAL4AwgCCAIAAAAAAAAAAAAAAAAAAHX/EAKQAVAE/AcQAAAAAAAAAAAAAAAAAAAAdv8QBBAD/AAQBPADAAAAAAAAAAAAAAAAAAB3/yABEAH8AJAPiACAAAAAAAAAAAAAAAAAAHj/AABgABAEDgPIADgAAAAAAAAAAAAAAAAAef/AADwIEAbwARAAAAAAAAAAAAAAAAAAAAB6/wAACAIIAggC+AcAAAAAAAAAAAAAAAAAAHv/EAD8ABAEEAL8ARAAAAAAAAAAAAAAAAAAfP8AACAIRAwYAoABYAAAAAAAAAAAAAAAAAB9/wAAAAwIAogBeAMADAAAAAAAAAAAAAAAAH7/AAAgAPwDEATQBDgEAAAAAAAAAAAAAAAAf/8AAAwAMAQAA+AAHAAAAAAAAAAAAAAAAACA/2AAEAxOAsgBOAEAAAAAAAAAAAAAAAAAAIH/AABICEgM+ANEAEAAAAAAAAAAAAAAAAAAgv84AAAEHAPAADwAAAAAAAAAAAAAAAAAAACD/yAAJAQkBuQBJAAgAAAAAAAAAAAAAAAAAIT/AAAAAPwHQADAAAAAAAAAAAAAAAAAAAAAhf8AABAEEAP+ABAAEAAAAAAAAAAAAAAAAACG/wAAAAIIAggCCAIAAgAAAAAAAAAAAAAAAIf/AAAICEgGyAE4BgAAAAAAAAAAAAAAAAAAiP8AAAgBiADOBzgAiAEAAAAAAAAAAAAAAACJ/wAAAAQAA+AAHAAAAAAAAAAAAAAAAAAAAIr/AATAAzgAAAA4AMAHAAAAAAAAAAAAAAAAi/8AAPwDIAQgBBAEAAAAAAAAAAAAAAAAAACM/wAACAgIBIgDeAAAAAAAAAAAAAAAAAAAAI3/gAFgABAAYACAAQAGAAAAAAAAAAAAAAAAjv8AANABEAT8BxAA0AEAAAAAAAAAAAAAAACP/wAACADIAIgDaAQYAAAAAAAAAAAAAAAAAJD/AAAgASQCSAJIBAAAAAAAAAAAAAAAAAAAkf8AAvADDALAAgAFAAAAAAAAAAAAAAAAAACS/wAEEAPgALgABAEAAAAAAAAAAAAAAAAAAJP/QABIAPgDSARIBGAAAAAAAAAAAAAAAAAAlP8gAPwBEA7QADgAAAAAAAAAAAAAAAAAAACV/wACCAIIAsgDOAIAAAAAAAAAAAAAAAAAAJb/AABIAkgCSAL4BwAAAAAAAAAAAAAAAAAAl/8AACAAJAwkA+QAAAAAAAAAAAAAAAAAAACY/wAAfAAABAAC/AEAAAAAAAAAAAAAAAAAAJn/AAf8AAAA/AcAAoABAAAAAAAAAAAAAAAAmv8AAPwHAAIAAYAAQAAAAAAAAAAAAAAAAACb/wAA+AcIAggC+AcAAAAAAAAAAAAAAAAAAJz/AAB4AAgMCAP4AAAAAAAAAAAAAAAAAAAAnf8AAAQEGAIAAcAAMAAAAAAAAAAAAAAAAACe/wwAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAJ//BAAKAAQAAAAAAAAAAAAAAAAAAAAAAAAAoP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACh/wAAAAAQABAAEAAQABAAEADwAwAAAAAAAKL/AAAQABAAEADwAwAAEAAQABAA8AMAAAAAo/8AAAAAEAAQAPADAAAAA/AAAAEAAgAAAACk/wAAAAD4AQABAAEAAQABAAEAAQAAAAAAAKX/AAAAAPADAAIAAhACEAHwABABEAIAAAAApv8AAAAA8AEAAQAAoAFgAnACoAEAAAAAAACn/wAAAADwARABEAEQARABEAEQAQAAAAAAAKj/AAAAAPABEAEQAQAA8AEQARABAAAAAAAAqf8AAAAAyANIAkgCSAJIAkgCeAIAAAAAAACq/wAAAADQAVABcAEAARAAEADwAQAAAAAAAKv/AAAAANABUAFwAQAA8AEQARAB8AEAAAAArP8AAAAA0AFQAXABAADwASABIAHwAQAAAACt/wAAAADQAVABcAEAAYAAcACAAAABAAAAAK7/AAAAANABUAFwAQAA8AFQAVABEAEAAAAAr/8AAAAA0AFQAXAAAAHwARAB8AEQAQAAAACw/wAAAADQAVABcAEAAJABWAKQAQAAAAAAALH/AAAAAPABEAEQARABEAEQAfABAAAAAAAAsv8AAAAA+AEgASABIAEgASAB+AEAAAAAAACz/wAAAADwAUAB8AEAAPABQAHwAQAAAAAAALT/AAAAAPABQAHwAQABgABwAIAAAAEAAAAAtf8AAAAAAAGAAEAAOABAAIAAAAEAAAAAAAC2/wAAAAKAAXAAgAEAAoAB8AAAAQACAAAAALf/AAAAAOAAEAEIAggCCAIQAeAAAAAAAAAAuP8AAAAACAGIAEgAOABIAIgACAEAAAAAAAC5/wAAAAGIAHgAiAAAAYgAeACIAAABAAAAALr/AAAAABABEAGQAHwAkAAQARABAAAAAAAAu/8AAAAASABIAEgASABIAEgA+AEAAAAAAAC8/wAAAADwAVABUAFQAVABUAFQAQAAAAAAAL3/AAAAARAB8AEQARABEAHwARABAAEAAAAAvv8AAAAAEACQAVACWAJQApABEAAAAAAAAADC/wAAAAAAAAAAAAD8D0AAQAAAAAAAAAAAAMP/AAAAAAAAAAD+ByAA/g8AAAAAAAAAAAAAxP8AAAAAAAAAAP4PkACQAAAAAAAAAAAAAADF/wAAAAAAAAAA/g+QAP4PAAAAAAAAAAAAAMb/AAAAAAAAIAAgACAA/gcAAAAAAAAAAAAAx/8AAAAAAAAgACAA/gcAAP4PAAAAAAAAAADK/wAAAAAAAJAAkACQAP4PAAAAAAAAAAAAAMv/AAAAAAAAkACQAP4PAAD+DwAAAAAAAAAAzP8AAAABAAEAAQAB8AEAAQABAAEAAQAAAADN/wAAAAEAAQAB4AEAAQABAAD8D0AAQAAAAM7/AAAAAQAB4AEAAQABAAD8D0AA/A8AAAAAz/8AAAABAAEAAfABAAEAAQAA/g8AAAAAAADS/wABAAEAAfgBAAEAAQAB+AEAAQABAAAAANP/AAAgACAAIAAgAOAHIAAgACAAIAAAAAAA1P8AAEAAQABAAMAHQABAAEABAAH8DwAAAADV/wAAQABAAMAHQABAAQAB/A8AAP4PAAAAANb/AABAAEAAQADAB0AAQABAAAAA/g8AAAAA1/8gACAAIADgByAAIAAgAOAHIAAgACAAAADa/wAAQABAAEAAQABAAEAAQABAAEAAQAAAANv/AACAAIAAgACAAIAAgACAAAAA/g8AAAAA3P8AAAAAAAAAAAAA/g8AAAAAAAAAAAAAAADg/wAAAAAAAOAAEAEIAvwHCAIQAQABAAAAAOH/AAAAAAAEQAb4BUQERAREBAQECAAAAAAA4v8AACAAIAAgACAAIAAgACAAIADgAQAAAADj/wEAAQABAAEAAQABAAEAAQABAAEAAQABAOT/AAAAAAAAAAAAAL4PAAAAAAAAAAAAAAAA5f8AAAAABACYAeABgAfgAZgBBAAAAAAAAADm/wAARAB4AMAHwANwAHgAwANABvgBRAAAAOj/AAAAAP8PAAAAAAAAAAAAAAAAAAAAAAAA6f9AAOAAUAFAAEAAQAAAAAAAAAAAAAAAAADq/xAACAD+DwgAEAAAAAAAAAAAAAAAAAAAAOv/QABAAEAAUAHgAEAAAAAAAAAAAAAAAAAA7P8AAQAC/g8AAgABAAAAAAAAAAAAAAAAAADt/wAA8ADwAPAA8AAAAAAAAAAAAAAAAAAAAO7/AADgABABEAHgAAAAAAAAAAAAAAAAAAAA"}},"image.getFontForText":{"kind":-3,"retType":"image.Font","parameters":[{"name":"text","type":"string"}],"pyQName":"image.get_font_for_text"},"image.doubledFont":{"kind":-3,"retType":"image.Font","attributes":{"deprecated":"1","hidden":"1"},"parameters":[{"name":"f","type":"image.Font"}],"pyQName":"image.doubled_font"},"image.scaledFont":{"kind":-3,"retType":"image.Font","parameters":[{"name":"f","type":"image.Font"},{"name":"size"}],"pyQName":"image.scaled_font"},"image.font5":{"kind":4,"retType":"image.Font","attributes":{"whenUsed":"true"}},"texteffects":{"kind":5,"retType":""},"texteffects.TextEffectState":{"kind":9,"retType":"texteffects.TextEffectState","extendsTypes":[]},"texteffects.TextEffectState.xOffset":{"kind":2,"retType":"number","isInstance":true,"pyQName":"texteffects.TextEffectState.x_offset"},"texteffects.TextEffectState.yOffset":{"kind":2,"retType":"number","isInstance":true,"pyQName":"texteffects.TextEffectState.y_offset"},"Image.print":{"kind":-1,"attributes":{"helper":"imagePrint"},"parameters":[{"name":"text","type":"string"},{"name":"x"},{"name":"y"},{"name":"color","initializer":"undefined"},{"name":"font","type":"image.Font","initializer":"undefined"},{"name":"offsets","type":"texteffects.TextEffectState[]","initializer":"undefined"}],"isInstance":true},"Image.printCenter":{"kind":-1,"attributes":{"helper":"imagePrintCenter"},"parameters":[{"name":"text","type":"string"},{"name":"y"},{"name":"color","initializer":"undefined"},{"name":"font","type":"image.Font","initializer":"undefined"}],"isInstance":true,"pyQName":"Image.print_center"},"helpers.imagePrintCenter":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"text","type":"string"},{"name":"y"},{"name":"color","initializer":"undefined"},{"name":"font","type":"image.Font","initializer":"undefined"}],"pyQName":"helpers.image_print_center"},"helpers.imagePrint":{"kind":-3,"parameters":[{"name":"img","type":"Image"},{"name":"text","type":"string"},{"name":"x"},{"name":"y"},{"name":"color","initializer":"undefined"},{"name":"font","type":"image.Font","initializer":"undefined"},{"name":"offsets","type":"texteffects.TextEffectState[]","initializer":"undefined"}],"pyQName":"helpers.image_print"},"control.__screen":{"kind":5,"retType":""},"control.__screen.update":{"kind":-3,"parameters":[]},"control.__screen.setupUpdate":{"kind":-3,"parameters":[{"name":"update","type":"() => void","handlerParameters":[]}],"pyQName":"control.__screen.setup_update"},"Image.width":{"kind":2,"retType":"number","attributes":{"property":"true","jsDoc":"Get the width of the image"},"isInstance":true},"Image.height":{"kind":2,"retType":"number","attributes":{"property":"true","jsDoc":"Get the height of the image"},"isInstance":true},"Image.isMono":{"kind":2,"retType":"boolean","attributes":{"property":"true","jsDoc":"True if the image is monochromatic (black and white)"},"isInstance":true,"pyQName":"Image.is_mono"},"Image.copyFrom":{"kind":-1,"attributes":{"jsDoc":"Sets all pixels in the current image from the other image, which has to be of the same size and\nbpp."},"parameters":[{"name":"from","type":"Image"}],"isInstance":true,"pyQName":"Image.copy_from"},"Image.setPixel":{"kind":-1,"attributes":{"paramDefl":{"picture":"picture"},"blockNamespace":"images","group":"Drawing","block":"set %picture=variables_get color at x %x y %y to %c=colorindexpicker","explicitDefaults":["picture"],"help":"images/image/set-pixel","jsDoc":"Set pixel color","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"label","text":" color at x ","style":[]},{"kind":"param","name":"x","ref":false},{"kind":"label","text":" y ","style":[]},{"kind":"param","name":"y","ref":false},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"c","shadowBlockId":"colorindexpicker","ref":false}],"parameters":[{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"param","name":"x","ref":false},{"kind":"param","name":"y","ref":false},{"kind":"param","name":"c","shadowBlockId":"colorindexpicker","ref":false}]}},"parameters":[{"name":"x"},{"name":"y"},{"name":"c"}],"isInstance":true,"pyQName":"Image.set_pixel"},"Image.getPixel":{"kind":-1,"retType":"number","attributes":{"paramDefl":{"picture":"picture"},"blockNamespace":"images","group":"Drawing","block":"%picture=variables_get color at x %x y %y","explicitDefaults":["picture"],"help":"images/image/get-pixel","jsDoc":"Get a pixel color","_def":{"parts":[{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"label","text":" color at x ","style":[]},{"kind":"param","name":"x","ref":false},{"kind":"label","text":" y ","style":[]},{"kind":"param","name":"y","ref":false}],"parameters":[{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"param","name":"x","ref":false},{"kind":"param","name":"y","ref":false}]}},"parameters":[{"name":"x"},{"name":"y"}],"isInstance":true,"pyQName":"Image.get_pixel"},"Image.fill":{"kind":-1,"attributes":{"paramDefl":{"picture":"picture"},"blockNamespace":"images","group":"Drawing","block":"fill %picture=variables_get with %c=colorindexpicker","explicitDefaults":["picture"],"help":"images/image/fill","jsDoc":"Fill entire image with a given color","_def":{"parts":[{"kind":"label","text":"fill ","style":[]},{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"label","text":" with ","style":[]},{"kind":"param","name":"c","shadowBlockId":"colorindexpicker","ref":false}],"parameters":[{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"param","name":"c","shadowBlockId":"colorindexpicker","ref":false}]}},"parameters":[{"name":"c"}],"isInstance":true},"Image.getRows":{"kind":-1,"attributes":{"jsDoc":"Copy row(s) of pixel from image to buffer (8 bit per pixel)."},"parameters":[{"name":"x"},{"name":"dst","type":"Buffer"}],"isInstance":true,"pyQName":"Image.get_rows"},"Image.setRows":{"kind":-1,"attributes":{"jsDoc":"Copy row(s) of pixel from buffer to image."},"parameters":[{"name":"x"},{"name":"src","type":"Buffer"}],"isInstance":true,"pyQName":"Image.set_rows"},"Image.clone":{"kind":-1,"retType":"Image","attributes":{"paramDefl":{"picture":"picture"},"blockNamespace":"images","group":"Create","block":"clone %picture=variables_get","explicitDefaults":["picture"],"help":"images/image/clone","jsDoc":"Return a copy of the current image","_def":{"parts":[{"kind":"label","text":"clone ","style":[]},{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false}],"parameters":[{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false}]}},"parameters":[],"isInstance":true},"Image.flipX":{"kind":-1,"attributes":{"paramDefl":{"picture":"picture"},"blockNamespace":"images","group":"Transformations","block":"flip %picture=variables_get horizontally","explicitDefaults":["picture"],"help":"images/image/flip-x","jsDoc":"Flips (mirrors) pixels horizontally in the current image","_def":{"parts":[{"kind":"label","text":"flip ","style":[]},{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"label","text":" horizontally","style":[]}],"parameters":[{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"Image.flip_x"},"Image.flipY":{"kind":-1,"attributes":{"paramDefl":{"picture":"picture"},"blockNamespace":"images","group":"Transformations","block":"flip %picture=variables_get vertically","explicitDefaults":["picture"],"help":"images/image/flip-y","jsDoc":"Flips (mirrors) pixels vertically in the current image","_def":{"parts":[{"kind":"label","text":"flip ","style":[]},{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"label","text":" vertically","style":[]}],"parameters":[{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"Image.flip_y"},"Image.transposed":{"kind":-1,"retType":"Image","attributes":{"jsDoc":"Returns a transposed image (with X/Y swapped)"},"parameters":[],"isInstance":true},"Image.scroll":{"kind":-1,"attributes":{"blockNamespace":"images","group":"Transformations","help":"images/image/scroll","jsDoc":"Every pixel in image is moved by (dx,dy)"},"parameters":[{"name":"dx"},{"name":"dy"}],"isInstance":true},"Image.doubledX":{"kind":-1,"retType":"Image","attributes":{"jsDoc":"Stretches the image horizontally by 100%"},"parameters":[],"isInstance":true,"pyQName":"Image.doubled_x"},"Image.doubledY":{"kind":-1,"retType":"Image","attributes":{"jsDoc":"Stretches the image vertically by 100%"},"parameters":[],"isInstance":true,"pyQName":"Image.doubled_y"},"Image.replace":{"kind":-1,"attributes":{"paramDefl":{"picture":"picture"},"blockNamespace":"images","group":"Transformations","block":"change color in %picture=variables_get from %from=colorindexpicker to %to=colorindexpicker","explicitDefaults":["picture"],"help":"images/image/replace","jsDoc":"Replaces one color in an image with another","_def":{"parts":[{"kind":"label","text":"change color in ","style":[]},{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"label","text":" from ","style":[]},{"kind":"param","name":"from","shadowBlockId":"colorindexpicker","ref":false},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"to","shadowBlockId":"colorindexpicker","ref":false}],"parameters":[{"kind":"param","name":"picture","shadowBlockId":"variables_get","ref":false},{"kind":"param","name":"from","shadowBlockId":"colorindexpicker","ref":false},{"kind":"param","name":"to","shadowBlockId":"colorindexpicker","ref":false}]}},"parameters":[{"name":"from"},{"name":"to"}],"isInstance":true},"Image.doubled":{"kind":-1,"retType":"Image","attributes":{"jsDoc":"Stretches the image in both directions by 100%"},"parameters":[],"isInstance":true},"Image.drawImage":{"kind":-1,"attributes":{"jsDoc":"Draw given image on the current image"},"parameters":[{"name":"from","type":"Image"},{"name":"x"},{"name":"y"}],"isInstance":true,"pyQName":"Image.draw_image"},"Image.drawTransparentImage":{"kind":-1,"attributes":{"paramDefl":{"this":"picture"},"blockNamespace":"images","blockId":"image_draw_transparent_image","group":"Drawing","block":"$this draw $from at x $x y $y","_shadowOverrides":{"this":"variables_get","from":"screen_image_picker"},"explicitDefaults":["this"],"weight":0,"jsDoc":"Draw given image with transparent background on the current image","_def":{"parts":[{"kind":"param","name":"this","shadowBlockId":"variables_get","ref":true},{"kind":"label","text":" draw ","style":[]},{"kind":"param","name":"from","shadowBlockId":"screen_image_picker","ref":true},{"kind":"label","text":" at x ","style":[]},{"kind":"param","name":"x","ref":true},{"kind":"label","text":" y ","style":[]},{"kind":"param","name":"y","ref":true}],"parameters":[{"kind":"param","name":"this","shadowBlockId":"variables_get","ref":true},{"kind":"param","name":"from","shadowBlockId":"screen_image_picker","ref":true},{"kind":"param","name":"x","ref":true},{"kind":"param","name":"y","ref":true}]}},"parameters":[{"name":"from","type":"Image"},{"name":"x"},{"name":"y"}],"isInstance":true,"pyQName":"Image.draw_transparent_image"},"Image.overlapsWith":{"kind":-1,"retType":"boolean","attributes":{"jsDoc":"Check if the current image \"collides\" with another"},"parameters":[{"name":"other","type":"Image"},{"name":"x"},{"name":"y"}],"isInstance":true,"pyQName":"Image.overlaps_with"},"image.create":{"kind":-3,"retType":"Image","attributes":{"blockNamespace":"images","block":"create image width %width height %height","group":"Create","help":"images/create","jsDoc":"Create new empty (transparent) image","_def":{"parts":[{"kind":"label","text":"create image width ","style":[]},{"kind":"param","name":"width","ref":false},{"kind":"label","text":" height ","style":[]},{"kind":"param","name":"height","ref":false}],"parameters":[{"kind":"param","name":"width","ref":false},{"kind":"param","name":"height","ref":false}]}},"parameters":[{"name":"width"},{"name":"height"}]},"image.ofBuffer":{"kind":-3,"retType":"Image","attributes":{"jsDoc":"Create new image with given content"},"parameters":[{"name":"buf","type":"Buffer"}],"pyQName":"image.of_buffer"},"image.doubledIcon":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"Double the size of an icon"},"parameters":[{"name":"icon","type":"Buffer"}],"pyQName":"image.doubled_icon"},"images":{"kind":5,"retType":"","attributes":{"weight":70,"icon":"","color":"#a5b1c2","advanced":true,"jsDoc":"Image manipulation blocks"}},"images._spriteImage":{"kind":-3,"retType":"Image","attributes":{"blockId":"screen_image_picker","block":"%img","shim":"TD_ID","paramFieldEditor":{"img":"sprite"},"paramFieldEditorOptions":{"img":{"taggedTemplate":"img","decompileIndirectFixedInstances":"true","decompileArgumentAsString":"true","filter":"!tile !dialog !background"}},"weight":100,"group":"Create","duplicateShadowOnDrag":true,"help":"images/sprite-image","_def":{"parts":[{"kind":"param","name":"img","ref":false}],"parameters":[{"kind":"param","name":"img","ref":false}]}},"parameters":[{"name":"img","type":"Image"}],"pyQName":"images._sprite_image"},"images._screenImage":{"kind":-3,"retType":"Image","attributes":{"blockId":"background_image_picker","block":"%img","shim":"TD_ID","paramFieldEditor":{"img":"sprite"},"paramFieldEditorOptions":{"img":{"taggedTemplate":"img","decompileIndirectFixedInstances":"true","decompileArgumentAsString":"true","sizes":"-1,-1","filter":"background"}},"weight":100,"group":"Create","blockHidden":true,"duplicateShadowOnDrag":true,"_def":{"parts":[{"kind":"param","name":"img","ref":false}],"parameters":[{"kind":"param","name":"img","ref":false}]}},"parameters":[{"name":"img","type":"Image"}],"pyQName":"images._screen_image"},"images._tileMapImage":{"kind":-3,"retType":"Image","attributes":{"blockId":"tilemap_image_picker","block":"%img","shim":"TD_ID","paramFieldEditor":{"img":"sprite"},"paramFieldEditorOptions":{"img":{"taggedTemplate":"img","decompileIndirectFixedInstances":"true","sizes":"10,8;16,16;32,32;48,48;64,64;16,32;32,48;32,8;64,8;20,15;40,15"}},"weight":100,"group":"Create","blockHidden":true,"duplicateShadowOnDrag":true,"_def":{"parts":[{"kind":"param","name":"img","ref":false}],"parameters":[{"kind":"param","name":"img","ref":false}]}},"parameters":[{"name":"img","type":"Image"}],"pyQName":"images._tile_map_image"},"images._tileImage":{"kind":-3,"retType":"Image","attributes":{"blockId":"tile_image_picker","block":"%img","shim":"TD_ID","paramFieldEditor":{"img":"sprite"},"paramFieldEditorOptions":{"img":{"taggedTemplate":"img","decompileIndirectFixedInstances":"true","sizes":"16,16;32,32;8,8","filter":"tile"}},"weight":100,"group":"Create","blockHidden":true,"duplicateShadowOnDrag":true,"_def":{"parts":[{"kind":"param","name":"img","ref":false}],"parameters":[{"kind":"param","name":"img","ref":false}]}},"parameters":[{"name":"img","type":"Image"}],"pyQName":"images._tile_image"},"images._tile":{"kind":-3,"retType":"Image","attributes":{"blockId":"tileset_tile_picker","block":"%tile","shim":"TD_ID","paramFieldEditor":{"tile":"tileset"},"paramFieldEditorOptions":{"tile":{"decompileIndirectFixedInstances":"true"}},"weight":10,"blockNamespace":"scene","group":"Tiles","blockHidden":true,"duplicateShadowOnDrag":true,"_def":{"parts":[{"kind":"param","name":"tile","ref":false}],"parameters":[{"kind":"param","name":"tile","ref":false}]}},"parameters":[{"name":"tile","type":"Image"}]},"images._dialogImage":{"kind":-3,"retType":"Image","attributes":{"blockId":"dialog_image_picker","block":"%img","shim":"TD_ID","paramFieldEditor":{"img":"sprite"},"paramFieldEditorOptions":{"img":{"taggedTemplate":"img","decompileIndirectFixedInstances":"true","decompileArgumentAsString":"true","sizes":"15,15;18,18;21,21;24,24;9,9;12,12","filter":"dialog"}},"weight":100,"group":"Create","blockHidden":true,"duplicateShadowOnDrag":true,"_def":{"parts":[{"kind":"param","name":"img","ref":false}],"parameters":[{"kind":"param","name":"img","ref":false}]}},"parameters":[{"name":"img","type":"Image"}],"pyQName":"images._dialog_image"},"images._image":{"kind":-3,"retType":"Image","attributes":{"blockId":"image_picker","block":"$image","shim":"TD_ID","paramFieldEditor":{"image":"sprite"},"paramFieldEditorOptions":{"image":{"taggedTemplate":"img","decompileIndirectFixedInstances":"true","decompileArgumentAsString":"true"}},"weight":0,"group":"Create","deprecated":"true","help":"images/image","paramHelp":{"image":"the image"},"jsDoc":"An image","_def":{"parts":[{"kind":"param","name":"image","ref":true}],"parameters":[{"kind":"param","name":"image","ref":true}]}},"parameters":[{"name":"image","description":"the image","type":"Image"}]},"images.__colorIndexPicker":{"kind":-3,"retType":"number","attributes":{"blockId":"colorindexpicker","block":"%index","blockHidden":true,"shim":"TD_ID","paramFieldEditor":{"index":"colornumber"},"paramFieldEditorOptions":{"index":{"valueMode":"index","decompileLiterals":"true"}},"_def":{"parts":[{"kind":"param","name":"index","ref":false}],"parameters":[{"kind":"param","name":"index","ref":false}]}},"parameters":[{"name":"index"}]},"images.__positionPicker":{"kind":-3,"retType":"number","attributes":{"blockId":"positionPicker","block":"%index","blockHidden":true,"shim":"TD_ID","paramFieldEditor":{"index":"position"},"color":"#ffffff","colorSecondary":"#ffffff","paramFieldEditorOptions":{"index":{"decompileLiterals":"true"}},"jsDoc":"A position picker","_def":{"parts":[{"kind":"param","name":"index","ref":false}],"parameters":[{"kind":"param","name":"index","ref":false}]}},"parameters":[{"name":"index"}]},"img":{"kind":-3,"retType":"Image","attributes":{"shim":"@f4","helper":"image::ofBuffer","blockIdentity":"images._spriteImage","groups":["0.","1#","2T","3t","4N","5n","6G","7g","8","9","aAR","bBP","cCp","dDO","eEY","fFW"],"jsDoc":"Tagged image literal converter"},"parameters":[{"name":"lits","type":"any"},{"name":"args","type":"any[]"}]},"screen":{"kind":4,"retType":"ScreenImage"},"image.setPalette":{"kind":-3,"parameters":[{"name":"buf","type":"Buffer"}],"pyQName":"image.set_palette"},"_screen_internal":{"kind":5,"retType":""},"_screen_internal.getScreenWidth":{"kind":-3,"retType":"number","attributes":{"shim":"TD_ID"},"parameters":[{"name":"defl"}],"pyQName":"_screen_internal.get_screen_width"},"_screen_internal.getScreenHeight":{"kind":-3,"retType":"number","attributes":{"shim":"TD_ID"},"parameters":[{"name":"defl"}],"pyQName":"_screen_internal.get_screen_height"},"Image.mapRect":{"kind":-1,"attributes":{"helper":"imageMapRect","jsDoc":"Replace colors in a rectangle"},"parameters":[{"name":"x"},{"name":"y"},{"name":"w"},{"name":"h"},{"name":"colorMap","type":"Buffer"}],"isInstance":true,"pyQName":"Image.map_rect"},"Image.equals":{"kind":-1,"retType":"boolean","attributes":{"paramDefl":{"this":"picture"},"blockNamespace":"images","group":"Compare","block":"$this is equal to image $other","_shadowOverrides":{"this":"variables_get","other":"screen_image_picker"},"explicitDefaults":["this"],"help":"images/image/equals","jsDoc":"Returns true if the provided image is the same as this image,\notherwise returns false.","_def":{"parts":[{"kind":"param","name":"this","shadowBlockId":"variables_get","ref":true},{"kind":"label","text":" is equal to image ","style":[]},{"kind":"param","name":"other","shadowBlockId":"screen_image_picker","ref":true}],"parameters":[{"kind":"param","name":"this","shadowBlockId":"variables_get","ref":true},{"kind":"param","name":"other","shadowBlockId":"screen_image_picker","ref":true}]}},"parameters":[{"name":"other","type":"Image"}],"isInstance":true},"Image.isStatic":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"Image.is_static"},"Image.revision":{"kind":-1,"retType":"number","parameters":[],"isInstance":true},"settings":{"kind":5,"retType":""},"settings.runNumber":{"kind":-3,"retType":"number","parameters":[],"pyQName":"settings.run_number"},"settings.clear":{"kind":-3,"attributes":{"jsDoc":"Delete all non-system settings."},"parameters":[]},"settings.writeBuffer":{"kind":-3,"attributes":{"jsDoc":"Set named setting to a given buffer."},"parameters":[{"name":"key","type":"string"},{"name":"value","type":"Buffer"}],"pyQName":"settings.write_buffer"},"settings.writeString":{"kind":-3,"attributes":{"jsDoc":"Set named settings to a given string."},"parameters":[{"name":"key","type":"string"},{"name":"value","type":"string"}],"pyQName":"settings.write_string"},"settings.writeJSON":{"kind":-3,"attributes":{"jsDoc":"Set named settings to a given JSON object."},"parameters":[{"name":"key","type":"string"},{"name":"value","type":"any"}],"pyQName":"settings.write_json"},"settings.writeNumber":{"kind":-3,"attributes":{"jsDoc":"Set named settings to a given number."},"parameters":[{"name":"key","type":"string"},{"name":"value"}],"pyQName":"settings.write_number"},"settings.writeNumberArray":{"kind":-3,"attributes":{"jsDoc":"Set named settings to a given array of numbers."},"parameters":[{"name":"key","type":"string"},{"name":"value","type":"number[]"}],"pyQName":"settings.write_number_array"},"settings.readBuffer":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"Read named setting as a buffer. Returns undefined when setting not found."},"parameters":[{"name":"key","type":"string"}],"pyQName":"settings.read_buffer"},"settings.readString":{"kind":-3,"retType":"string","attributes":{"jsDoc":"Read named setting as a string."},"parameters":[{"name":"key","type":"string"}],"pyQName":"settings.read_string"},"settings.readJSON":{"kind":-3,"retType":"any","attributes":{"jsDoc":"Read named setting as a JSON object."},"parameters":[{"name":"key","type":"string"}],"pyQName":"settings.read_json"},"settings.readNumber":{"kind":-3,"retType":"number","attributes":{"jsDoc":"Read named setting as a number."},"parameters":[{"name":"key","type":"string"}],"pyQName":"settings.read_number"},"settings.readNumberArray":{"kind":-3,"retType":"number[]","attributes":{"jsDoc":"Read named setting as a number."},"parameters":[{"name":"key","type":"string"}],"pyQName":"settings.read_number_array"},"settings.list":{"kind":-3,"retType":"string[]","attributes":{"jsDoc":"Return a list of settings starting with a given prefix."},"parameters":[{"name":"prefix","type":"string","initializer":"undefined"}]},"settings.remove":{"kind":-3,"attributes":{"jsDoc":"Remove named setting."},"parameters":[{"name":"key","type":"string"}]},"settings.exists":{"kind":-3,"retType":"boolean","attributes":{"jsDoc":"Check if a named setting exists."},"parameters":[{"name":"key","type":"string"}]},"settings.SecretStore":{"kind":8,"retType":"settings.SecretStore","attributes":{"fixedInstances":"true"},"extendsTypes":[]},"settings.SecretStore.__constructor":{"kind":-3,"parameters":[{"name":"key","type":"string"}],"isInstance":true},"settings.SecretStore.setSecret":{"kind":-1,"parameters":[{"name":"name","type":"string"},{"name":"value","type":"any"}],"isInstance":true,"pyQName":"settings.SecretStore.set_secret"},"settings.SecretStore.updateSecret":{"kind":-1,"parameters":[{"name":"name","type":"string"},{"name":"value","type":"any"}],"isInstance":true,"pyQName":"settings.SecretStore.update_secret"},"settings.SecretStore.readSecret":{"kind":-1,"retType":"any","parameters":[{"name":"name","type":"string"},{"name":"ensure","type":"boolean","initializer":"false"}],"isInstance":true,"pyQName":"settings.SecretStore.read_secret"},"settings.SecretStore.clearSecrets":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"settings.SecretStore.clear_secrets"},"settings.SecretStore.readSecrets":{"kind":-1,"retType":"any","parameters":[],"isInstance":true,"pyQName":"settings.SecretStore.read_secrets"},"settings.deviceSecrets":{"kind":4,"retType":"settings.SecretStore","attributes":{"fixedInstance":"true","whenUsed":"true","block":"device secrets","jsDoc":"Secrets shared by any program on the device","_def":{"parts":[{"kind":"label","text":"device secrets","style":[]}],"parameters":[]}},"pyQName":"settings.device_secrets"},"settings.programSecrets":{"kind":4,"retType":"settings.SecretStore","attributes":{"fixedInstance":"true","whenUsed":"true","block":"program secrets","jsDoc":"Program secrets","_def":{"parts":[{"kind":"label","text":"program secrets","style":[]}],"parameters":[]}},"pyQName":"settings.program_secrets"},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"helpers._promptForText":{"kind":-3,"parameters":[{"name":"maxLength"},{"name":"numbersOnly","type":"boolean"}],"pyQName":"helpers._prompt_for_text"},"helpers._cancelTextPrompt":{"kind":-3,"parameters":[],"pyQName":"helpers._cancel_text_prompt"},"helpers._getTextPromptString":{"kind":-3,"retType":"string","parameters":[],"pyQName":"helpers._get_text_prompt_string"},"helpers._getLocalizedInstructions":{"kind":-3,"retType":"string","parameters":[],"pyQName":"helpers._get_localized_instructions"},"helpers._getTextPromptSelectionStart":{"kind":-3,"retType":"number","parameters":[],"pyQName":"helpers._get_text_prompt_selection_start"},"helpers._getTextPromptSelectionEnd":{"kind":-3,"retType":"number","parameters":[],"pyQName":"helpers._get_text_prompt_selection_end"},"helpers._isSystemKeyboardSupported":{"kind":-3,"retType":"boolean","parameters":[],"pyQName":"helpers._is_system_keyboard_supported"},"forever":{"kind":-3,"attributes":{"help":"loops/forever","weight":100,"afterOnStart":true,"blockNamespace":"loops","blockId":"forever","block":"forever","blockAllowMultiple":"1","paramHelp":{"body":"code to execute"},"jsDoc":"Repeats the code forever in the background. On each iteration, allows other codes to run.","_def":{"parts":[{"kind":"label","text":"forever","style":[]}],"parameters":[]}},"parameters":[{"name":"a","type":"() => void","handlerParameters":[]}]},"basic.forever":{"kind":-3,"parameters":[{"name":"a","type":"() => void","handlerParameters":[]}]},"SpriteLike":{"kind":9,"retType":"SpriteLike","extendsTypes":["SpriteLike"]},"SpriteLike.z":{"kind":2,"retType":"number","isInstance":true},"SpriteLike.id":{"kind":2,"retType":"number","isInstance":true},"SpriteLike.flags":{"kind":2,"retType":"number","isInstance":true},"SpriteLike.__update":{"kind":-1,"parameters":[{"name":"camera","type":"scene.Camera"},{"name":"dt"}],"isInstance":true},"SpriteLike.__draw":{"kind":-1,"parameters":[{"name":"camera","type":"scene.Camera"}],"isInstance":true},"SpriteLike.__serialize":{"kind":-1,"retType":"Buffer","parameters":[{"name":"offset"}],"isInstance":true},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"sprites.BaseSprite":{"kind":8,"retType":"sprites.BaseSprite","extendsTypes":["sprites.BaseSprite","SpriteLike"]},"sprites.BaseSprite.id":{"kind":2,"retType":"number","isInstance":true},"sprites.BaseSprite.__constructor":{"kind":-3,"parameters":[{"name":"z"}],"isInstance":true},"sprites.BaseSprite.__visible":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true},"sprites.BaseSprite.z":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"sprites.BaseSprite.z@set":{"kind":-2,"retType":"number","isInstance":true},"sprites.BaseSprite.__draw":{"kind":-1,"parameters":[{"name":"camera","type":"scene.Camera"}],"isInstance":true},"sprites.BaseSprite.__drawCore":{"kind":-1,"parameters":[{"name":"camera","type":"scene.Camera"}],"isInstance":true},"sprites.BaseSprite.__update":{"kind":-1,"parameters":[{"name":"camera","type":"scene.Camera"},{"name":"dt"}],"isInstance":true},"sprites.BaseSprite.__serialize":{"kind":-1,"retType":"Buffer","parameters":[{"name":"offset"}],"isInstance":true},"KEY_UP":{"kind":4,"retType":"number"},"KEY_DOWN":{"kind":4,"retType":"number"},"INTERNAL_KEY_UP":{"kind":4,"retType":"number"},"INTERNAL_KEY_DOWN":{"kind":4,"retType":"number"},"SYSTEM_KEY_UP":{"kind":4,"retType":"number"},"SYSTEM_KEY_DOWN":{"kind":4,"retType":"number"},"KEY_REPEAT":{"kind":4,"retType":"number"},"SYSTEM_KEY_REPEAT":{"kind":4,"retType":"number"},"controller":{"kind":5,"retType":"","attributes":{"weight":98,"color":"#D54322","icon":"","groups":["Single Player","Multiplayer"],"blockGap":"8","jsDoc":"Access to game controls"}},"controller.A":{"kind":4,"retType":"controller.Button","attributes":{"fixedInstance":"true","whenUsed":"true","block":"{id:controller}A","_def":{"parts":[{"kind":"label","text":"{id:controller}A","style":[]}],"parameters":[]}}},"controller.B":{"kind":4,"retType":"controller.Button","attributes":{"fixedInstance":"true","whenUsed":"true","block":"{id:controller}B","_def":{"parts":[{"kind":"label","text":"{id:controller}B","style":[]}],"parameters":[]}}},"controller.left":{"kind":4,"retType":"controller.Button","attributes":{"fixedInstance":"true","whenUsed":"true","block":"left","_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}}},"controller.up":{"kind":4,"retType":"controller.Button","attributes":{"fixedInstance":"true","whenUsed":"true","block":"up","_def":{"parts":[{"kind":"label","text":"up","style":[]}],"parameters":[]}}},"controller.right":{"kind":4,"retType":"controller.Button","attributes":{"fixedInstance":"true","whenUsed":"true","block":"right","_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}}},"controller.down":{"kind":4,"retType":"controller.Button","attributes":{"fixedInstance":"true","whenUsed":"true","block":"down","_def":{"parts":[{"kind":"label","text":"down","style":[]}],"parameters":[]}}},"controller.menu":{"kind":4,"retType":"controller.Button","attributes":{"fixedInstance":"true","whenUsed":"true","block":"menu","_def":{"parts":[{"kind":"label","text":"menu","style":[]}],"parameters":[]}}},"controller.player2":{"kind":4,"retType":"controller.Controller","attributes":{"fixedInstance":"true","whenUsed":"true","block":"player 2","_def":{"parts":[{"kind":"label","text":"player 2","style":[]}],"parameters":[]}}},"controller.player3":{"kind":4,"retType":"controller.Controller","attributes":{"fixedInstance":"true","whenUsed":"true","block":"player 3","_def":{"parts":[{"kind":"label","text":"player 3","style":[]}],"parameters":[]}}},"controller.player4":{"kind":4,"retType":"controller.Controller","attributes":{"fixedInstance":"true","whenUsed":"true","block":"player 4","_def":{"parts":[{"kind":"label","text":"player 4","style":[]}],"parameters":[]}}},"controller.player1":{"kind":4,"retType":"controller.Controller","attributes":{"fixedInstance":"true","whenUsed":"true","block":"player 1","_def":{"parts":[{"kind":"label","text":"player 1","style":[]}],"parameters":[]}}},"ControllerEvent":{"kind":6,"retType":"ControllerEvent","extendsTypes":["ControllerEvent","Number"]},"ControllerEvent.Connected":{"retType":"ControllerEvent.Connected","attributes":{"block":"connected","_def":{"parts":[{"kind":"label","text":"connected","style":[]}],"parameters":[]}},"extendsTypes":["ControllerEvent.Connected","Number"],"pyQName":"ControllerEvent.CONNECTED"},"ControllerEvent.Disconnected":{"retType":"ControllerEvent.Disconnected","attributes":{"block":"disconnected","_def":{"parts":[{"kind":"label","text":"disconnected","style":[]}],"parameters":[]}},"extendsTypes":["ControllerEvent.Disconnected","Number"],"pyQName":"ControllerEvent.DISCONNECTED"},"controller._player1":{"kind":-3,"retType":"controller.Controller","parameters":[]},"controller.players":{"kind":-3,"retType":"controller.Controller[]","parameters":[]},"controller.ControlledSprite":{"kind":8,"retType":"controller.ControlledSprite","extendsTypes":[]},"controller.ControlledSprite._inputLastFrame":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"controller.ControlledSprite._input_last_frame"},"controller.ControlledSprite.__constructor":{"kind":-3,"parameters":[{"name":"s","type":"Sprite"},{"name":"vx"},{"name":"vy"}],"isInstance":true},"controller._moveSprites":{"kind":-3,"parameters":[],"pyQName":"controller._move_sprites"},"controller.Controller":{"kind":8,"retType":"controller.Controller","attributes":{"fixedInstances":"true"},"extendsTypes":[]},"controller.Controller.playerIndex":{"kind":2,"retType":"number","isInstance":true,"pyQName":"controller.Controller.player_index"},"controller.Controller.buttons":{"kind":2,"retType":"controller.Button[]","isInstance":true},"controller.Controller.analog":{"kind":2,"retType":"boolean","isInstance":true},"controller.Controller.__constructor":{"kind":-3,"parameters":[{"name":"playerIndex"},{"name":"buttons","type":"controller.Button[]"}],"isInstance":true},"controller.Controller._controlledSprites":{"kind":-2,"retType":"controller.ControlledSprite[]","isInstance":true,"isReadOnly":true,"pyQName":"controller.Controller._controlled_sprites"},"controller.Controller._controlledSprites@set":{"kind":-2,"retType":"controller.ControlledSprite[]","isInstance":true,"pyQName":"controller.Controller._controlled_sprites@set"},"controller.Controller.id":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"controller.Controller.dump":{"kind":-1,"parameters":[],"isInstance":true},"controller.Controller.left":{"kind":-2,"retType":"controller.Button","attributes":{"jsDoc":"Get the 'Left' button"},"isInstance":true,"isReadOnly":true},"controller.Controller.right":{"kind":-2,"retType":"controller.Button","attributes":{"jsDoc":"Get the 'Right' button"},"isInstance":true,"isReadOnly":true},"controller.Controller.up":{"kind":-2,"retType":"controller.Button","attributes":{"jsDoc":"Get the 'Up' button"},"isInstance":true,"isReadOnly":true},"controller.Controller.down":{"kind":-2,"retType":"controller.Button","attributes":{"jsDoc":"Get the 'Down' button"},"isInstance":true,"isReadOnly":true},"controller.Controller.A":{"kind":-2,"retType":"controller.Button","attributes":{"jsDoc":"Get the 'A' button"},"isInstance":true,"isReadOnly":true},"controller.Controller.B":{"kind":-2,"retType":"controller.Button","attributes":{"jsDoc":"Get the 'B' button"},"isInstance":true,"isReadOnly":true},"controller.Controller.menu":{"kind":-2,"retType":"controller.Button","attributes":{"jsDoc":"Get the 'Menu' button"},"isInstance":true,"isReadOnly":true},"controller.Controller.moveSprite":{"kind":-1,"attributes":{"paramDefl":{"vx":"100","vy":"100"},"blockId":"ctrlgame_control_sprite","block":"%controller move $sprite=variables_get(mySprite) with buttons||vx $vx vy $vy","weight":100,"expandableArgumentMode":"toggle","explicitDefaults":["vx","vy"],"help":"controller/move-sprite","group":"Multiplayer","_shadowOverrides":{"vx":"spriteSpeedPicker","vy":"spriteSpeedPicker"},"parts":"multiplayer","paramHelp":{"vx":"The velocity used for horizontal movement when left/right is pressed","vy":"The velocity used for vertical movement when up/down is pressed"},"jsDoc":"Control a sprite using the direction buttons from the controller. Note that this will overwrite\nthe current velocity of the sprite whenever a directional button is pressed. To stop controlling\na sprite, pass 0 for vx and vy.\n* @param sprite The Sprite to control","_def":{"parts":[{"kind":"param","name":"controller","ref":false},{"kind":"label","text":" move ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"label","text":" with buttons","style":[]}],"parameters":[{"kind":"param","name":"controller","ref":false},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"}]},"_expandedDef":{"parts":[{"kind":"label","text":"vx ","style":[]},{"kind":"param","name":"vx","shadowBlockId":"spriteSpeedPicker","ref":true},{"kind":"label","text":" vy ","style":[]},{"kind":"param","name":"vy","shadowBlockId":"spriteSpeedPicker","ref":true}],"parameters":[{"kind":"param","name":"vx","shadowBlockId":"spriteSpeedPicker","ref":true},{"kind":"param","name":"vy","shadowBlockId":"spriteSpeedPicker","ref":true}]}},"parameters":[{"name":"sprite","type":"Sprite"},{"name":"vx","description":"The velocity used for horizontal movement when left/right is pressed","initializer":"100","default":"100"},{"name":"vy","description":"The velocity used for vertical movement when up/down is pressed","initializer":"100","default":"100"}],"isInstance":true,"pyQName":"controller.Controller.move_sprite"},"controller.Controller.stopControllingSprite":{"kind":-1,"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true,"pyQName":"controller.Controller.stop_controlling_sprite"},"controller.Controller._moveSpriteInternal":{"kind":-1,"parameters":[{"name":"sprite","type":"Sprite"},{"name":"vx","initializer":"100"},{"name":"vy","initializer":"100"}],"isInstance":true,"pyQName":"controller.Controller._move_sprite_internal"},"controller.Controller.onButtonEvent":{"kind":-1,"attributes":{"weight":99,"blockGap":"8","blockId":"ctrlonbuttonevent","block":"on %controller %button **button** %event","group":"Multiplayer","help":"controller/on-button-event","parts":"multiplayer","jsDoc":"Run some code when a button is pressed, released, or held","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"controller","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"button","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"label","text":"button","style":["bold"]},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"event","ref":false}],"parameters":[{"kind":"param","name":"controller","ref":false},{"kind":"param","name":"button","ref":false},{"kind":"param","name":"event","ref":false}]}},"parameters":[{"name":"btn","type":"ControllerButton","isEnum":true},{"name":"event","type":"ControllerButtonEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"controller.Controller.on_button_event"},"controller.Controller.onEvent":{"kind":-1,"attributes":{"weight":99,"blockGap":"8","blockId":"ctrlonevent","block":"on %controller %event","group":"Multiplayer","help":"controller/on-event","parts":"multiplayer","paramHelp":{"event":"@param handler"},"jsDoc":"Register code run when a controller event occurs","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"controller","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"event","ref":false}],"parameters":[{"kind":"param","name":"controller","ref":false},{"kind":"param","name":"event","ref":false}]}},"parameters":[{"name":"event","description":"@param handler","type":"ControllerEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"controller.Controller.on_event"},"controller.Controller.connected":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true},"controller.Controller.connected@set":{"kind":-2,"retType":"boolean","isInstance":true},"controller.Controller.isPressed":{"kind":-1,"retType":"boolean","attributes":{"weight":96,"blockGap":"8","help":"controller/button/is-pressed","blockId":"ctrlispressed","block":"is %controller %button **button** pressed","group":"Multiplayer","parts":"multiplayer","jsDoc":"Indicates if the button is currently pressed","_def":{"parts":[{"kind":"label","text":"is ","style":[]},{"kind":"param","name":"controller","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"button","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"label","text":"button","style":["bold"]},{"kind":"label","text":" pressed","style":[]}],"parameters":[{"kind":"param","name":"controller","ref":false},{"kind":"param","name":"button","ref":false}]}},"parameters":[{"name":"btn","type":"ControllerButton","isEnum":true}],"isInstance":true,"pyQName":"controller.Controller.is_pressed"},"controller.Controller.dx":{"kind":-1,"retType":"number","attributes":{"paramDefl":{"step":"100"},"weight":50,"blockGap":"8","help":"controller/dx","blockId":"ctrldx","block":"%controller dx (left-right buttons)||scaled by %step","explicitDefaults":["step"],"group":"Multiplayer","parts":"multiplayer","paramHelp":{"step":"the distance, eg: 100"},"jsDoc":"Get the horizontal movement, given the step and state of buttons","_def":{"parts":[{"kind":"param","name":"controller","ref":false},{"kind":"label","text":" dx (left-right buttons)","style":[]}],"parameters":[{"kind":"param","name":"controller","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":"scaled by ","style":[]},{"kind":"param","name":"step","ref":false}],"parameters":[{"kind":"param","name":"step","ref":false}]}},"parameters":[{"name":"step","description":"the distance, eg: 100","initializer":"100","default":"100"}],"isInstance":true},"controller.Controller._dxInternal":{"kind":-1,"retType":"number","parameters":[{"name":"step","initializer":"100"}],"isInstance":true,"pyQName":"controller.Controller._dx_internal"},"controller.Controller.dy":{"kind":-1,"retType":"number","attributes":{"paramDefl":{"step":"100"},"weight":49,"help":"controller/dy","blockId":"ctrldy","block":"%controller dy (up-down buttons)||scaled by %step","explicitDefaults":["step"],"group":"Multiplayer","parts":"multiplayer","paramHelp":{"step":"the distance, eg: 100"},"jsDoc":"Get the vertical movement, given the step and state of buttons","_def":{"parts":[{"kind":"param","name":"controller","ref":false},{"kind":"label","text":" dy (up-down buttons)","style":[]}],"parameters":[{"kind":"param","name":"controller","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":"scaled by ","style":[]},{"kind":"param","name":"step","ref":false}],"parameters":[{"kind":"param","name":"step","ref":false}]}},"parameters":[{"name":"step","description":"the distance, eg: 100","initializer":"100","default":"100"}],"isInstance":true},"controller.Controller._dyInternal":{"kind":-1,"retType":"number","parameters":[{"name":"step","initializer":"100"}],"isInstance":true,"pyQName":"controller.Controller._dy_internal"},"controller.Controller.__preUpdate":{"kind":-1,"parameters":[],"isInstance":true},"controller.Controller.__update":{"kind":-1,"parameters":[{"name":"dtms"}],"isInstance":true},"controller.Controller.serialize":{"kind":-1,"retType":"Buffer","parameters":[{"name":"offset"}],"isInstance":true},"controller.__update":{"kind":-3,"attributes":{"jsDoc":"Called by the game engine to update and/or raise events"},"parameters":[{"name":"dt"}]},"controller.serialize":{"kind":-3,"retType":"Buffer","parameters":[{"name":"offset"}]},"controller.moveSprite":{"kind":-3,"attributes":{"paramDefl":{"vx":"100","vy":"100"},"blockId":"game_control_sprite","block":"move $sprite=variables_get(mySprite) with buttons||vx $vx vy $vy","weight":100,"expandableArgumentMode":"toggle","explicitDefaults":["vx","vy"],"help":"controller/move-sprite","group":"Single Player","_shadowOverrides":{"vx":"spriteSpeedPicker","vy":"spriteSpeedPicker"},"paramHelp":{"vx":"The velocity used for horizontal movement when left/right is pressed","vy":"The velocity used for vertical movement when up/down is pressed"},"jsDoc":"Control a sprite using the direction buttons from the controller. Note that this\ncontrol will take over the vx and vy of the sprite and overwrite any changes\nmade unless a 0 is passed.\n* @param sprite The Sprite to control","_def":{"parts":[{"kind":"label","text":"move ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"label","text":" with buttons","style":[]}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"}]},"_expandedDef":{"parts":[{"kind":"label","text":"vx ","style":[]},{"kind":"param","name":"vx","shadowBlockId":"spriteSpeedPicker","ref":true},{"kind":"label","text":" vy ","style":[]},{"kind":"param","name":"vy","shadowBlockId":"spriteSpeedPicker","ref":true}],"parameters":[{"kind":"param","name":"vx","shadowBlockId":"spriteSpeedPicker","ref":true},{"kind":"param","name":"vy","shadowBlockId":"spriteSpeedPicker","ref":true}]}},"parameters":[{"name":"sprite","type":"Sprite"},{"name":"vx","description":"The velocity used for horizontal movement when left/right is pressed","initializer":"100","default":"100"},{"name":"vy","description":"The velocity used for vertical movement when up/down is pressed","initializer":"100","default":"100"}],"pyQName":"controller.move_sprite"},"controller.dx":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"step":"100"},"weight":50,"blockGap":"8","help":"controller/dx","blockId":"keydx","block":"dx (left-right buttons)||scaled by %step","explicitDefaults":["step"],"group":"Single Player","paramHelp":{"step":"the distance, eg: 100"},"jsDoc":"Get the horizontal movement, given the step and state of buttons","_def":{"parts":[{"kind":"label","text":"dx (left-right buttons)","style":[]}],"parameters":[]},"_expandedDef":{"parts":[{"kind":"label","text":"scaled by ","style":[]},{"kind":"param","name":"step","ref":false}],"parameters":[{"kind":"param","name":"step","ref":false}]}},"parameters":[{"name":"step","description":"the distance, eg: 100","initializer":"100","default":"100"}]},"controller.dy":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"step":"100"},"weight":49,"help":"controller/dy","blockId":"keydy","block":"dy (up-down buttons)||scaled by %step","explicitDefaults":["step"],"group":"Single Player","paramHelp":{"step":"the distance, eg: 100"},"jsDoc":"Get the vertical movement, given the step and state of buttons","_def":{"parts":[{"kind":"label","text":"dy (up-down buttons)","style":[]}],"parameters":[]},"_expandedDef":{"parts":[{"kind":"label","text":"scaled by ","style":[]},{"kind":"param","name":"step","ref":false}],"parameters":[{"kind":"param","name":"step","ref":false}]}},"parameters":[{"name":"step","description":"the distance, eg: 100","initializer":"100","default":"100"}]},"controller.anyButton":{"kind":4,"retType":"controller.Button","attributes":{"fixedInstance":"true","block":"any","_def":{"parts":[{"kind":"label","text":"any","style":[]}],"parameters":[]}},"pyQName":"controller.any_button"},"ControllerButtonEvent":{"kind":6,"retType":"ControllerButtonEvent","extendsTypes":["ControllerButtonEvent","Number"]},"ControllerButtonEvent.Pressed":{"retType":"ControllerButtonEvent","attributes":{"block":"pressed","_def":{"parts":[{"kind":"label","text":"pressed","style":[]}],"parameters":[]}},"extendsTypes":["ControllerButtonEvent.Pressed","Number"],"pyQName":"ControllerButtonEvent.PRESSED"},"ControllerButtonEvent.Released":{"retType":"ControllerButtonEvent","attributes":{"block":"released","_def":{"parts":[{"kind":"label","text":"released","style":[]}],"parameters":[]}},"extendsTypes":["ControllerButtonEvent.Released","Number"],"pyQName":"ControllerButtonEvent.RELEASED"},"ControllerButtonEvent.Repeated":{"retType":"ControllerButtonEvent","attributes":{"block":"repeat","_def":{"parts":[{"kind":"label","text":"repeat","style":[]}],"parameters":[]}},"extendsTypes":["ControllerButtonEvent.Repeated","Number"],"pyQName":"ControllerButtonEvent.REPEATED"},"ControllerButton":{"kind":6,"retType":"ControllerButton","extendsTypes":["ControllerButton","Number"]},"ControllerButton.A":{"retType":"ControllerButton.A","attributes":{"block":"{id:controller}A","_def":{"parts":[{"kind":"label","text":"{id:controller}A","style":[]}],"parameters":[]}},"extendsTypes":["ControllerButton.A","Number"]},"ControllerButton.B":{"retType":"ControllerButton.B","attributes":{"block":"{id:controller}B","_def":{"parts":[{"kind":"label","text":"{id:controller}B","style":[]}],"parameters":[]}},"extendsTypes":["ControllerButton.B","Number"]},"ControllerButton.Left":{"retType":"ControllerButton.Left","attributes":{"block":"left","_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"extendsTypes":["ControllerButton.Left","Number"],"pyQName":"ControllerButton.LEFT"},"ControllerButton.Up":{"retType":"ControllerButton.Up","attributes":{"block":"up","_def":{"parts":[{"kind":"label","text":"up","style":[]}],"parameters":[]}},"extendsTypes":["ControllerButton.Up","Number"],"pyQName":"ControllerButton.UP"},"ControllerButton.Right":{"retType":"ControllerButton.Right","attributes":{"block":"right","_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"extendsTypes":["ControllerButton.Right","Number"],"pyQName":"ControllerButton.RIGHT"},"ControllerButton.Down":{"retType":"ControllerButton.Down","attributes":{"block":"down","_def":{"parts":[{"kind":"label","text":"down","style":[]}],"parameters":[]}},"extendsTypes":["ControllerButton.Down","Number"],"pyQName":"ControllerButton.DOWN"},"controller.ButtonHandler":{"kind":8,"retType":"controller.ButtonHandler","extendsTypes":[]},"controller.ButtonHandler.__constructor":{"kind":-3,"parameters":[{"name":"event"},{"name":"callback","type":"() => void","handlerParameters":[]}],"isInstance":true},"controller.ButtonEventHandlerState":{"kind":8,"retType":"controller.ButtonEventHandlerState","extendsTypes":[]},"controller.ButtonEventHandlerState.__constructor":{"kind":-3,"parameters":[{"name":"id"}],"isInstance":true},"controller.ButtonEventHandlerState.user":{"kind":2,"retType":"controller.ButtonHandler[]","isInstance":true},"controller.ButtonEventHandlerState.system":{"kind":2,"retType":"controller.ButtonHandler[]","isInstance":true},"controller.Button":{"kind":8,"retType":"controller.Button","attributes":{"fixedInstances":"true"},"extendsTypes":[]},"controller.Button._owner":{"kind":2,"retType":"controller.Controller","isInstance":true},"controller.Button.id":{"kind":2,"retType":"number","isInstance":true},"controller.Button.repeatDelay":{"kind":2,"retType":"number","attributes":{"help":"controller/button/repeat-delay"},"isInstance":true,"pyQName":"controller.Button.repeat_delay"},"controller.Button.repeatInterval":{"kind":2,"retType":"number","attributes":{"help":"controller/button/repeat-interval"},"isInstance":true,"pyQName":"controller.Button.repeat_interval"},"controller.Button.toString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"controller.Button.to_string"},"controller.Button.__constructor":{"kind":-3,"parameters":[{"name":"id"},{"name":"configKey"}],"isInstance":true},"controller.Button.onEvent":{"kind":-1,"attributes":{"weight":99,"blockGap":"8","help":"controller/button/on-event","blockId":"keyonevent","block":"on %button **button** %event","group":"Single Player","jsDoc":"Run some code when a button is pressed, released, or held","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"button","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"label","text":"button","style":["bold"]},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"event","ref":false}],"parameters":[{"kind":"param","name":"button","ref":false},{"kind":"param","name":"event","ref":false}]}},"parameters":[{"name":"event","type":"ControllerButtonEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"controller.Button.on_event"},"controller.Button.addEventListener":{"kind":-1,"attributes":{"paramHelp":{"handler":"The code to run when the event triggers"},"jsDoc":"Adds an event handler that will fire whenever the specified event\nis triggered on this button. Handlers added using this method will\nnot conflict with events added via onEvent. The same handler can\nnot be added for the same event more than once.\n* @param event     The event to subscribe to for this button"},"parameters":[{"name":"event","type":"ControllerButtonEvent","isEnum":true},{"name":"handler","description":"The code to run when the event triggers","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"controller.Button.add_event_listener"},"controller.Button.removeEventListener":{"kind":-1,"attributes":{"paramHelp":{"handler":"The handler to remove"},"jsDoc":"Removes an event handler registered with addEventListener.\n* @param event     The event that the handler was registered for"},"parameters":[{"name":"event","type":"ControllerButtonEvent","isEnum":true},{"name":"handler","description":"The handler to remove","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"controller.Button.remove_event_listener"},"controller.Button.pauseUntil":{"kind":-1,"attributes":{"weight":98,"blockGap":"8","help":"controller/button/pause-until","group":"Single Player","jsDoc":"Pauses until a button is pressed or released"},"parameters":[{"name":"event","type":"ControllerButtonEvent","isEnum":true}],"isInstance":true,"pyQName":"controller.Button.pause_until"},"controller.Button.isPressed":{"kind":-1,"retType":"boolean","attributes":{"weight":96,"blockGap":"8","help":"controller/button/is-pressed","blockId":"keyispressed","block":"is %button **button** pressed","group":"Single Player","jsDoc":"Indicates if the button is currently pressed","_def":{"parts":[{"kind":"label","text":"is ","style":[]},{"kind":"param","name":"button","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"label","text":"button","style":["bold"]},{"kind":"label","text":" pressed","style":[]}],"parameters":[{"kind":"param","name":"button","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"controller.Button.is_pressed"},"controller.Button.pressureLevel":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Indicates how hard the button is pressed, 0-512"},"parameters":[],"isInstance":true,"pyQName":"controller.Button.pressure_level"},"controller.Button.setPressed":{"kind":-1,"parameters":[{"name":"pressed","type":"boolean"}],"isInstance":true,"pyQName":"controller.Button.set_pressed"},"controller.Button.__update":{"kind":-1,"parameters":[{"name":"dtms"}],"isInstance":true},"controller.setRepeatDefault":{"kind":-3,"attributes":{"paramDefl":{"delay":"500","interval":"30"},"paramHelp":{"delay":"number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500","interval":"minimum number of milliseconds between calls to the button repeat event, eg: 30"},"jsDoc":"Configures the timing of the on button repeat event for all of the controller buttons"},"parameters":[{"name":"delay","description":"number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500","default":"500"},{"name":"interval","description":"minimum number of milliseconds between calls to the button repeat event, eg: 30","default":"30"}],"pyQName":"controller.set_repeat_default"},"controller.pauseUntilAnyButtonIsPressed":{"kind":-3,"attributes":{"weight":10,"jsDoc":"Pause the program until a button is pressed"},"parameters":[],"pyQName":"controller.pause_until_any_button_is_pressed"},"controller._setUserEventsEnabled":{"kind":-3,"parameters":[{"name":"enabled","type":"boolean"}],"pyQName":"controller._set_user_events_enabled"},"game.Hitbox":{"kind":8,"retType":"game.Hitbox","extendsTypes":[]},"game.Hitbox.hash":{"kind":2,"retType":"number","isInstance":true},"game.Hitbox.parent":{"kind":2,"retType":"Sprite","isInstance":true},"game.Hitbox.ox":{"kind":2,"retType":"Fx8","isInstance":true},"game.Hitbox.oy":{"kind":2,"retType":"Fx8","isInstance":true},"game.Hitbox.width":{"kind":2,"retType":"Fx8","isInstance":true},"game.Hitbox.height":{"kind":2,"retType":"Fx8","isInstance":true},"game.Hitbox.__constructor":{"kind":-3,"parameters":[{"name":"parent","type":"Sprite"},{"name":"width","type":"Fx8"},{"name":"height","type":"Fx8"},{"name":"ox","type":"Fx8"},{"name":"oy","type":"Fx8"}],"isInstance":true},"game.Hitbox.left":{"kind":-2,"retType":"Fx8","isInstance":true,"isReadOnly":true},"game.Hitbox.top":{"kind":-2,"retType":"Fx8","isInstance":true,"isReadOnly":true},"game.Hitbox.right":{"kind":-2,"retType":"Fx8","isInstance":true,"isReadOnly":true},"game.Hitbox.bottom":{"kind":-2,"retType":"Fx8","isInstance":true,"isReadOnly":true},"game.Hitbox.isValid":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"game.Hitbox.is_valid"},"game.Hitbox.contains":{"kind":-1,"retType":"boolean","parameters":[{"name":"x","type":"Fx8"},{"name":"y","type":"Fx8"}],"isInstance":true},"game.Hitbox.updateIfInvalid":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"game.Hitbox.update_if_invalid"},"game.Hitbox.overlapsWith":{"kind":-1,"retType":"boolean","parameters":[{"name":"other","type":"game.Hitbox"}],"isInstance":true,"pyQName":"game.Hitbox.overlaps_with"},"game.calculateHitBox":{"kind":-3,"retType":"game.Hitbox","parameters":[{"name":"s","type":"Sprite"}],"pyQName":"game.calculate_hit_box"},"sprites.RenderText":{"kind":8,"retType":"sprites.RenderText","extendsTypes":[]},"sprites.RenderText.linebreaks":{"kind":2,"retType":"number[]","isInstance":true},"sprites.RenderText.font":{"kind":2,"retType":"image.Font","isInstance":true},"sprites.RenderText.height":{"kind":2,"retType":"number","isInstance":true},"sprites.RenderText.width":{"kind":2,"retType":"number","isInstance":true},"sprites.RenderText.__constructor":{"kind":-3,"parameters":[{"name":"text","type":"string"},{"name":"maxWidth"}],"isInstance":true},"sprites.RenderText.draw":{"kind":-1,"parameters":[{"name":"canvas","type":"Image"},{"name":"left"},{"name":"top"},{"name":"color"},{"name":"lineStart","initializer":"undefined"},{"name":"lineEnd","initializer":"undefined"}],"isInstance":true},"sprites.RenderText.drawLine":{"kind":-1,"parameters":[{"name":"canvas","type":"Image"},{"name":"left"},{"name":"top"},{"name":"lineIndex"},{"name":"color"}],"isInstance":true,"pyQName":"sprites.RenderText.draw_line"},"sprites.RenderText.drawPartial":{"kind":-1,"retType":"boolean","parameters":[{"name":"canvas","type":"Image"},{"name":"left"},{"name":"top"},{"name":"color"},{"name":"lengthToDraw"},{"name":"lineStart","initializer":"undefined"},{"name":"lineEnd","initializer":"undefined"}],"isInstance":true,"pyQName":"sprites.RenderText.draw_partial"},"sprites.RenderText.drawPartialLine":{"kind":-1,"retType":"number","parameters":[{"name":"canvas","type":"Image"},{"name":"left"},{"name":"top"},{"name":"lineIndex"},{"name":"color"},{"name":"currentTextIndex"},{"name":"lengthToDraw"}],"isInstance":true,"pyQName":"sprites.RenderText.draw_partial_line"},"sprites.RenderText.calculatePartialHeight":{"kind":-1,"retType":"number","parameters":[{"name":"startLine"},{"name":"lengthToDraw"}],"isInstance":true,"pyQName":"sprites.RenderText.calculate_partial_height"},"sprites.RenderText.lineHeight":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"sprites.RenderText.line_height"},"sprites.RenderText.setMaxWidth":{"kind":-1,"parameters":[{"name":"maxWidth"}],"isInstance":true,"pyQName":"sprites.RenderText.set_max_width"},"sprites.RenderText.printableCharacters":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"sprites.RenderText.printable_characters"},"sprites.RenderText.lineEnd":{"kind":-1,"retType":"number","parameters":[{"name":"lineIndex"}],"isInstance":true,"pyQName":"sprites.RenderText.line_end"},"sprites.RenderText.lineStart":{"kind":-1,"retType":"number","parameters":[{"name":"lineIndex"}],"isInstance":true,"pyQName":"sprites.RenderText.line_start"},"sprites.RenderText.widthOfLine":{"kind":-1,"retType":"number","parameters":[{"name":"lineIndex"},{"name":"fullTextOffset","initializer":"undefined"}],"isInstance":true,"pyQName":"sprites.RenderText.width_of_line"},"sprites.RenderText.widthOfLines":{"kind":-1,"retType":"number","parameters":[{"name":"lineStartIndex"},{"name":"lineEndIndex"},{"name":"offset","initializer":"undefined"}],"isInstance":true,"pyQName":"sprites.RenderText.width_of_lines"},"sprites.RenderTextAnimation":{"kind":8,"retType":"sprites.RenderTextAnimation","extendsTypes":[]},"sprites.RenderTextAnimation.__constructor":{"kind":-3,"parameters":[{"name":"text","type":"sprites.RenderText"},{"name":"height"}],"isInstance":true},"sprites.RenderTextAnimation.start":{"kind":-1,"parameters":[],"isInstance":true},"sprites.RenderTextAnimation.numPages":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"sprites.RenderTextAnimation.num_pages"},"sprites.RenderTextAnimation.setPauseLength":{"kind":-1,"parameters":[{"name":"millis"}],"isInstance":true,"pyQName":"sprites.RenderTextAnimation.set_pause_length"},"sprites.RenderTextAnimation.setTextSpeed":{"kind":-1,"parameters":[{"name":"charactersPerSecond"}],"isInstance":true,"pyQName":"sprites.RenderTextAnimation.set_text_speed"},"sprites.RenderTextAnimation.currentHeight":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"sprites.RenderTextAnimation.current_height"},"sprites.RenderTextAnimation.currentWidth":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"sprites.RenderTextAnimation.current_width"},"sprites.RenderTextAnimation.currentOffset":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"sprites.RenderTextAnimation.current_offset"},"sprites.RenderTextAnimation.isDone":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"sprites.RenderTextAnimation.is_done"},"sprites.RenderTextAnimation.cancel":{"kind":-1,"parameters":[],"isInstance":true},"sprites.RenderTextAnimation.onCharacterPrinted":{"kind":-1,"parameters":[{"name":"cb","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"sprites.RenderTextAnimation.on_character_printed"},"sprites.RenderTextAnimation.onAnimationEnd":{"kind":-1,"parameters":[{"name":"cb","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"sprites.RenderTextAnimation.on_animation_end"},"sprites.RenderTextAnimation.draw":{"kind":-1,"parameters":[{"name":"canvas","type":"Image"},{"name":"left"},{"name":"top"},{"name":"color"}],"isInstance":true},"sprites.BaseSpriteSayRenderer":{"kind":8,"retType":"sprites.BaseSpriteSayRenderer","extendsTypes":["sprites.BaseSpriteSayRenderer"]},"sprites.BaseSpriteSayRenderer.__constructor":{"kind":-3,"parameters":[{"name":"text","type":"string"},{"name":"fgColor"},{"name":"bgColor"}],"isInstance":true},"sprites.BaseSpriteSayRenderer.draw":{"kind":-1,"parameters":[{"name":"screen","type":"Image"},{"name":"camera","type":"scene.Camera"},{"name":"owner","type":"Sprite"}],"isInstance":true},"sprites.BaseSpriteSayRenderer.update":{"kind":-1,"parameters":[{"name":"dt"},{"name":"camera","type":"scene.Camera"},{"name":"owner","type":"Sprite"}],"isInstance":true},"sprites.BaseSpriteSayRenderer.destroy":{"kind":-1,"parameters":[],"isInstance":true},"sprites.SpriteSayRenderer":{"kind":8,"retType":"sprites.SpriteSayRenderer","extendsTypes":["sprites.SpriteSayRenderer","sprites.BaseSpriteSayRenderer"]},"sprites.SpriteSayRenderer.drawSayFrame":{"kind":-1,"parameters":[{"name":"textLeft"},{"name":"textTop"},{"name":"textWidth"},{"name":"textHeight"},{"name":"speakerX"},{"name":"speakerY"},{"name":"color"},{"name":"canvas","type":"Image"}],"pyQName":"sprites.SpriteSayRenderer.draw_say_frame"},"sprites.SpriteSayRenderer.__constructor":{"kind":-3,"parameters":[{"name":"text","type":"string"},{"name":"fg"},{"name":"bg"},{"name":"animated","type":"boolean"},{"name":"timeOnScreen"}],"isInstance":true},"sprites.SpriteSayRenderer.draw":{"kind":-1,"parameters":[{"name":"screen","type":"Image"},{"name":"camera","type":"scene.Camera"},{"name":"owner","type":"Sprite"}],"isInstance":true},"sprites.LegacySpriteSayRenderer":{"kind":8,"retType":"sprites.LegacySpriteSayRenderer","extendsTypes":["sprites.LegacySpriteSayRenderer","sprites.BaseSpriteSayRenderer"]},"sprites.LegacySpriteSayRenderer.__constructor":{"kind":-3,"parameters":[{"name":"text","type":"string"},{"name":"timeOnScreen"},{"name":"owner","type":"Sprite"},{"name":"fg"},{"name":"bg"}],"isInstance":true},"sprites.LegacySpriteSayRenderer.update":{"kind":-1,"parameters":[{"name":"dt"},{"name":"camera","type":"scene.Camera"},{"name":"owner","type":"Sprite"}],"isInstance":true},"sprites.LegacySpriteSayRenderer.destroy":{"kind":-1,"parameters":[],"isInstance":true},"sprites.FollowingSprite":{"kind":8,"retType":"sprites.FollowingSprite","extendsTypes":[]},"sprites.FollowingSprite.__constructor":{"kind":-3,"parameters":[{"name":"self","type":"Sprite"},{"name":"target","type":"Sprite"},{"name":"rate"},{"name":"turnRate"}],"isInstance":true},"sprites.create":{"kind":-3,"retType":"Sprite","attributes":{"group":"Create","blockId":"spritescreate","block":"sprite %img=screen_image_picker of kind %kind=spritekind","expandableArgumentMode":"toggle","blockSetVariable":"mySprite","weight":100,"help":"sprites/create","paramHelp":{"img":"the image"},"jsDoc":"Create a new sprite from an image","_def":{"parts":[{"kind":"label","text":"sprite ","style":[]},{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false},{"kind":"label","text":" of kind ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false}],"parameters":[{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false}]}},"parameters":[{"name":"img","description":"the image","type":"Image"},{"name":"kind","initializer":"undefined"}]},"sprites.__create":{"kind":-3,"retType":"Sprite","attributes":{"group":"Create","blockId":"spritescreatenoset","block":"sprite %img=screen_image_picker of kind %kind=spritekind","blockAliasFor":"sprites.create","expandableArgumentMode":"toggle","weight":99,"help":"sprites/create","duplicateShadowOnDrag":true,"paramHelp":{"img":"the image"},"jsDoc":"Create a new sprite from an image","_def":{"parts":[{"kind":"label","text":"sprite ","style":[]},{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false},{"kind":"label","text":" of kind ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false}],"parameters":[{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false}]}},"parameters":[{"name":"img","description":"the image","type":"Image"},{"name":"kind","initializer":"undefined"}]},"sprites.destroy":{"kind":-3,"attributes":{"paramDefl":{"sprite":"mySprite"},"group":"Effects","weight":80,"blockId":"spritedestroy2","block":"destroy $sprite || with $effect effect for $duration ms","_shadowOverrides":{"sprite":"variables_get","duration":"timePicker"},"explicitDefaults":["sprite"],"expandableArgumentMode":"toggle","help":"sprites/sprite/destroy","_def":{"parts":[{"kind":"label","text":"destroy ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true},{"kind":"label","text":" ","style":[]}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true}]},"_expandedDef":{"parts":[{"kind":"label","text":" with ","style":[]},{"kind":"param","name":"effect","ref":true},{"kind":"label","text":" effect for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":true},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"effect","ref":true},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":true}]}},"parameters":[{"name":"sprite","type":"Sprite","initializer":"mySprite","default":"mySprite"},{"name":"effect","type":"effects.ParticleEffect","initializer":"undefined"},{"name":"duration","initializer":"undefined"}]},"sprites.allOfKind":{"kind":-3,"retType":"Sprite[]","attributes":{"blockId":"allOfKind","block":"array of sprites of kind %kind=spritekind","weight":87,"help":"sprites/all-of-kind","paramHelp":{"kind":"the target kind"},"jsDoc":"Return an array of all sprites of the given kind.","_def":{"parts":[{"kind":"label","text":"array of sprites of kind ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false}],"parameters":[{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false}]}},"parameters":[{"name":"kind","description":"the target kind"}],"pyQName":"sprites.all_of_kind"},"sprites.destroyAllSpritesOfKind":{"kind":-3,"attributes":{"group":"Effects","weight":79,"help":"sprites/destroy-all-sprites-of-kind","blockId":"sprites_destroy_all_sprites_of_kind","block":"destroy all sprites of kind $kind || with $effect effect for $duration ms","_shadowOverrides":{"kind":"spritekind","duration":"timePicker"},"expandableArgumentMode":"toggle","jsDoc":"Destroys all sprites of the given kind.","_def":{"parts":[{"kind":"label","text":"destroy all sprites of kind ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true},{"kind":"label","text":" ","style":[]}],"parameters":[{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true}]},"_expandedDef":{"parts":[{"kind":"label","text":" with ","style":[]},{"kind":"param","name":"effect","ref":true},{"kind":"label","text":" effect for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":true},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"effect","ref":true},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":true}]}},"parameters":[{"name":"kind"},{"name":"effect","type":"effects.ParticleEffect","initializer":"undefined"},{"name":"duration","initializer":"undefined"}],"pyQName":"sprites.destroy_all_sprites_of_kind"},"sprites.createProjectileFromSide":{"kind":-3,"retType":"Sprite","attributes":{"group":"Projectiles","blockId":"spritescreateprojectilefromside","block":"projectile %img=screen_image_picker from side with vx %vx vy %vy","_shadowOverrides":{"vx":"spriteSpeedPicker","vy":"spriteSpeedPicker"},"weight":99,"help":"sprites/create-projectile-from-side","blockSetVariable":"projectile","inlineInputMode":"inline","jsDoc":"Create a new sprite with a given speed, and place it at the edge of the screen so it moves towards the middle.\nThe sprite auto-destroys when it leaves the screen. You can modify position after it's created.","_def":{"parts":[{"kind":"label","text":"projectile ","style":[]},{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false},{"kind":"label","text":" from side with vx ","style":[]},{"kind":"param","name":"vx","shadowBlockId":"spriteSpeedPicker","ref":false},{"kind":"label","text":" vy ","style":[]},{"kind":"param","name":"vy","shadowBlockId":"spriteSpeedPicker","ref":false}],"parameters":[{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false},{"kind":"param","name":"vx","shadowBlockId":"spriteSpeedPicker","ref":false},{"kind":"param","name":"vy","shadowBlockId":"spriteSpeedPicker","ref":false}]}},"parameters":[{"name":"img","type":"Image"},{"name":"vx"},{"name":"vy"}],"pyQName":"sprites.create_projectile_from_side"},"sprites.createProjectileFromSprite":{"kind":-3,"retType":"Sprite","attributes":{"group":"Projectiles","blockId":"spritescreateprojectilefromsprite","block":"projectile %img=screen_image_picker from %sprite=variables_get(mySprite) with vx %vx vy %vy","_shadowOverrides":{"vx":"spriteSpeedPicker","vy":"spriteSpeedPicker"},"weight":99,"help":"sprites/create-projectile-from-sprite","blockSetVariable":"projectile","inlineInputMode":"inline","jsDoc":"Create a new sprite with a given speed that starts from the location of another sprite.\nThe sprite auto-destroys when it leaves the screen. You can modify position after it's created.","_def":{"parts":[{"kind":"label","text":"projectile ","style":[]},{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false},{"kind":"label","text":" from ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"},{"kind":"label","text":" with vx ","style":[]},{"kind":"param","name":"vx","shadowBlockId":"spriteSpeedPicker","ref":false},{"kind":"label","text":" vy ","style":[]},{"kind":"param","name":"vy","shadowBlockId":"spriteSpeedPicker","ref":false}],"parameters":[{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"},{"kind":"param","name":"vx","shadowBlockId":"spriteSpeedPicker","ref":false},{"kind":"param","name":"vy","shadowBlockId":"spriteSpeedPicker","ref":false}]}},"parameters":[{"name":"img","type":"Image"},{"name":"sprite","type":"Sprite"},{"name":"vx"},{"name":"vy"}],"pyQName":"sprites.create_projectile_from_sprite"},"sprites.createProjectile":{"kind":-3,"retType":"Sprite","attributes":{"group":"Projectiles","blockId":"spritescreateprojectile","block":"projectile %img=screen_image_picker vx %vx vy %vy of kind %kind=spritekind||from sprite %sprite=variables_get(mySprite)","weight":99,"help":"sprites/create-projectile","blockSetVariable":"projectile","inlineInputMode":"inline","expandableArgumentMode":"toggle","deprecated":"true","blockHidden":true,"jsDoc":"Create a new sprite with given speed, and place it at the edge of the screen so it moves towards the middle.\nThe sprite auto-destroys when it leaves the screen. You can modify position after it's created.","_def":{"parts":[{"kind":"label","text":"projectile ","style":[]},{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false},{"kind":"label","text":" vx ","style":[]},{"kind":"param","name":"vx","ref":false},{"kind":"label","text":" vy ","style":[]},{"kind":"param","name":"vy","ref":false},{"kind":"label","text":" of kind ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false}],"parameters":[{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false},{"kind":"param","name":"vx","ref":false},{"kind":"param","name":"vy","ref":false},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":"from sprite ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"}]}},"parameters":[{"name":"img","type":"Image"},{"name":"vx"},{"name":"vy"},{"name":"kind","initializer":"undefined"},{"name":"sprite","type":"Sprite","initializer":"undefined"}],"pyQName":"sprites.create_projectile"},"sprites.Flag":{"kind":6,"retType":"sprites.Flag","extendsTypes":["sprites.Flag","Number"]},"sprites.Flag.None":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.None","Number"],"pyQName":"sprites.Flag.NONE"},"sprites.Flag.Destroyed":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.Destroyed","Number"],"pyQName":"sprites.Flag.DESTROYED"},"sprites.Flag.AutoDestroy":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.AutoDestroy","Number"],"pyQName":"sprites.Flag.AUTO_DESTROY"},"sprites.Flag.StayInScreen":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.StayInScreen","Number"],"pyQName":"sprites.Flag.STAY_IN_SCREEN"},"sprites.Flag.DestroyOnWall":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.DestroyOnWall","Number"],"pyQName":"sprites.Flag.DESTROY_ON_WALL"},"sprites.Flag.BounceOnWall":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.BounceOnWall","Number"],"pyQName":"sprites.Flag.BOUNCE_ON_WALL"},"sprites.Flag.ShowPhysics":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.ShowPhysics","Number"],"pyQName":"sprites.Flag.SHOW_PHYSICS"},"sprites.Flag.Invisible":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.Invisible","Number"],"pyQName":"sprites.Flag.INVISIBLE"},"sprites.Flag.IsClipping":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.IsClipping","Number"],"pyQName":"sprites.Flag.IS_CLIPPING"},"sprites.Flag.RelativeToCamera":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.RelativeToCamera","Number"],"pyQName":"sprites.Flag.RELATIVE_TO_CAMERA"},"sprites.Flag.GhostThroughTiles":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.GhostThroughTiles","Number"],"pyQName":"sprites.Flag.GHOST_THROUGH_TILES"},"sprites.Flag.GhostThroughWalls":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.GhostThroughWalls","Number"],"pyQName":"sprites.Flag.GHOST_THROUGH_WALLS"},"sprites.Flag.GhostThroughSprites":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.GhostThroughSprites","Number"],"pyQName":"sprites.Flag.GHOST_THROUGH_SPRITES"},"sprites.Flag.HitboxOverlaps":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.HitboxOverlaps","Number"],"pyQName":"sprites.Flag.HITBOX_OVERLAPS"},"sprites.Flag.Ghost":{"retType":"sprites.Flag","extendsTypes":["sprites.Flag.Ghost","Number"],"pyQName":"sprites.Flag.GHOST"},"SpriteFlag":{"kind":6,"retType":"SpriteFlag","extendsTypes":["SpriteFlag","Number"]},"SpriteFlag.Ghost":{"retType":"SpriteFlag","attributes":{"block":"ghost","_def":{"parts":[{"kind":"label","text":"ghost","style":[]}],"parameters":[]}},"extendsTypes":["SpriteFlag.Ghost","Number"],"pyQName":"SpriteFlag.GHOST"},"SpriteFlag.AutoDestroy":{"retType":"SpriteFlag","attributes":{"block":"auto destroy","_def":{"parts":[{"kind":"label","text":"auto destroy","style":[]}],"parameters":[]}},"extendsTypes":["SpriteFlag.AutoDestroy","Number"],"pyQName":"SpriteFlag.AUTO_DESTROY"},"SpriteFlag.StayInScreen":{"retType":"SpriteFlag","attributes":{"block":"stay in screen","_def":{"parts":[{"kind":"label","text":"stay in screen","style":[]}],"parameters":[]}},"extendsTypes":["SpriteFlag.StayInScreen","Number"],"pyQName":"SpriteFlag.STAY_IN_SCREEN"},"SpriteFlag.DestroyOnWall":{"retType":"SpriteFlag","attributes":{"block":"destroy on wall","_def":{"parts":[{"kind":"label","text":"destroy on wall","style":[]}],"parameters":[]}},"extendsTypes":["SpriteFlag.DestroyOnWall","Number"],"pyQName":"SpriteFlag.DESTROY_ON_WALL"},"SpriteFlag.BounceOnWall":{"retType":"SpriteFlag","attributes":{"block":"bounce on wall","_def":{"parts":[{"kind":"label","text":"bounce on wall","style":[]}],"parameters":[]}},"extendsTypes":["SpriteFlag.BounceOnWall","Number"],"pyQName":"SpriteFlag.BOUNCE_ON_WALL"},"SpriteFlag.ShowPhysics":{"retType":"SpriteFlag","attributes":{"block":"show physics","_def":{"parts":[{"kind":"label","text":"show physics","style":[]}],"parameters":[]}},"extendsTypes":["SpriteFlag.ShowPhysics","Number"],"pyQName":"SpriteFlag.SHOW_PHYSICS"},"SpriteFlag.Invisible":{"retType":"SpriteFlag","attributes":{"block":"invisible","_def":{"parts":[{"kind":"label","text":"invisible","style":[]}],"parameters":[]}},"extendsTypes":["SpriteFlag.Invisible","Number"],"pyQName":"SpriteFlag.INVISIBLE"},"SpriteFlag.RelativeToCamera":{"retType":"SpriteFlag","attributes":{"block":"relative to camera","_def":{"parts":[{"kind":"label","text":"relative to camera","style":[]}],"parameters":[]}},"extendsTypes":["SpriteFlag.RelativeToCamera","Number"],"pyQName":"SpriteFlag.RELATIVE_TO_CAMERA"},"SpriteFlag.GhostThroughSprites":{"retType":"SpriteFlag","attributes":{"block":"ghost through sprites","_def":{"parts":[{"kind":"label","text":"ghost through sprites","style":[]}],"parameters":[]}},"extendsTypes":["SpriteFlag.GhostThroughSprites","Number"],"pyQName":"SpriteFlag.GHOST_THROUGH_SPRITES"},"SpriteFlag.GhostThroughTiles":{"retType":"SpriteFlag","attributes":{"block":"ghost through tiles","_def":{"parts":[{"kind":"label","text":"ghost through tiles","style":[]}],"parameters":[]}},"extendsTypes":["SpriteFlag.GhostThroughTiles","Number"],"pyQName":"SpriteFlag.GHOST_THROUGH_TILES"},"SpriteFlag.GhostThroughWalls":{"retType":"SpriteFlag","attributes":{"block":"ghost through walls","_def":{"parts":[{"kind":"label","text":"ghost through walls","style":[]}],"parameters":[]}},"extendsTypes":["SpriteFlag.GhostThroughWalls","Number"],"pyQName":"SpriteFlag.GHOST_THROUGH_WALLS"},"TileDirection":{"kind":6,"retType":"TileDirection","extendsTypes":["TileDirection","Number"]},"TileDirection.Left":{"retType":"TileDirection.Left","attributes":{"block":"left","_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"extendsTypes":["TileDirection.Left","Number"],"pyQName":"TileDirection.LEFT"},"TileDirection.Top":{"retType":"TileDirection.Top","attributes":{"block":"top","_def":{"parts":[{"kind":"label","text":"top","style":[]}],"parameters":[]}},"extendsTypes":["TileDirection.Top","Number"],"pyQName":"TileDirection.TOP"},"TileDirection.Right":{"retType":"TileDirection.Right","attributes":{"block":"right","_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"extendsTypes":["TileDirection.Right","Number"],"pyQName":"TileDirection.RIGHT"},"TileDirection.Bottom":{"retType":"TileDirection.Bottom","attributes":{"block":"bottom","_def":{"parts":[{"kind":"label","text":"bottom","style":[]}],"parameters":[]}},"extendsTypes":["TileDirection.Bottom","Number"],"pyQName":"TileDirection.BOTTOM"},"TileDirection.Center":{"retType":"TileDirection.Center","attributes":{"block":"center","_def":{"parts":[{"kind":"label","text":"center","style":[]}],"parameters":[]}},"extendsTypes":["TileDirection.Center","Number"],"pyQName":"TileDirection.CENTER"},"CollisionDirection":{"kind":6,"retType":"CollisionDirection","extendsTypes":["CollisionDirection","Number"]},"CollisionDirection.Left":{"retType":"CollisionDirection.Left","attributes":{"block":"left","_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"extendsTypes":["CollisionDirection.Left","Number"],"pyQName":"CollisionDirection.LEFT"},"CollisionDirection.Top":{"retType":"CollisionDirection.Top","attributes":{"block":"top","_def":{"parts":[{"kind":"label","text":"top","style":[]}],"parameters":[]}},"extendsTypes":["CollisionDirection.Top","Number"],"pyQName":"CollisionDirection.TOP"},"CollisionDirection.Right":{"retType":"CollisionDirection.Right","attributes":{"block":"right","_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"extendsTypes":["CollisionDirection.Right","Number"],"pyQName":"CollisionDirection.RIGHT"},"CollisionDirection.Bottom":{"retType":"CollisionDirection.Bottom","attributes":{"block":"bottom","_def":{"parts":[{"kind":"label","text":"bottom","style":[]}],"parameters":[]}},"extendsTypes":["CollisionDirection.Bottom","Number"],"pyQName":"CollisionDirection.BOTTOM"},"FlipOption":{"kind":6,"retType":"FlipOption","extendsTypes":["FlipOption","Number"]},"FlipOption.None":{"retType":"FlipOption.None","attributes":{"block":"none","_def":{"parts":[{"kind":"label","text":"none","style":[]}],"parameters":[]}},"extendsTypes":["FlipOption.None","Number"],"pyQName":"FlipOption.NONE"},"FlipOption.FlipX":{"retType":"FlipOption.FlipX","attributes":{"block":"flip x","_def":{"parts":[{"kind":"label","text":"flip x","style":[]}],"parameters":[]}},"extendsTypes":["FlipOption.FlipX","Number"],"pyQName":"FlipOption.FLIP_X"},"FlipOption.FlipY":{"retType":"FlipOption.FlipY","attributes":{"block":"flip y","_def":{"parts":[{"kind":"label","text":"flip y","style":[]}],"parameters":[]}},"extendsTypes":["FlipOption.FlipY","Number"],"pyQName":"FlipOption.FLIP_Y"},"FlipOption.FlipXY":{"retType":"FlipOption.FlipXY","attributes":{"block":"flip x+y","_def":{"parts":[{"kind":"label","text":"flip x+y","style":[]}],"parameters":[]}},"extendsTypes":["FlipOption.FlipXY","Number"],"pyQName":"FlipOption.FLIP_XY"},"ScaleDirection":{"kind":6,"retType":"ScaleDirection","extendsTypes":["ScaleDirection","Number"]},"ScaleDirection.Vertically":{"retType":"ScaleDirection","attributes":{"block":"vertically","_def":{"parts":[{"kind":"label","text":"vertically","style":[]}],"parameters":[]}},"extendsTypes":["ScaleDirection.Vertically","Number"],"pyQName":"ScaleDirection.VERTICALLY"},"ScaleDirection.Horizontally":{"retType":"ScaleDirection","attributes":{"block":"horizontally","_def":{"parts":[{"kind":"label","text":"horizontally","style":[]}],"parameters":[]}},"extendsTypes":["ScaleDirection.Horizontally","Number"],"pyQName":"ScaleDirection.HORIZONTALLY"},"ScaleDirection.Uniformly":{"retType":"ScaleDirection","attributes":{"block":"uniformly","_def":{"parts":[{"kind":"label","text":"uniformly","style":[]}],"parameters":[]}},"extendsTypes":["ScaleDirection.Uniformly","Number"],"pyQName":"ScaleDirection.UNIFORMLY"},"ScaleAnchor":{"kind":6,"retType":"ScaleAnchor","extendsTypes":["ScaleAnchor","Number"]},"ScaleAnchor.Middle":{"retType":"ScaleAnchor","attributes":{"block":"middle","_def":{"parts":[{"kind":"label","text":"middle","style":[]}],"parameters":[]}},"extendsTypes":["ScaleAnchor.Middle","Number"],"pyQName":"ScaleAnchor.MIDDLE"},"ScaleAnchor.Top":{"retType":"ScaleAnchor","attributes":{"block":"top","_def":{"parts":[{"kind":"label","text":"top","style":[]}],"parameters":[]}},"extendsTypes":["ScaleAnchor.Top","Number"],"pyQName":"ScaleAnchor.TOP"},"ScaleAnchor.Left":{"retType":"ScaleAnchor","attributes":{"block":"left","_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"extendsTypes":["ScaleAnchor.Left","Number"],"pyQName":"ScaleAnchor.LEFT"},"ScaleAnchor.Right":{"retType":"ScaleAnchor","attributes":{"block":"right","_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"extendsTypes":["ScaleAnchor.Right","Number"],"pyQName":"ScaleAnchor.RIGHT"},"ScaleAnchor.Bottom":{"retType":"ScaleAnchor","attributes":{"block":"bottom","_def":{"parts":[{"kind":"label","text":"bottom","style":[]}],"parameters":[]}},"extendsTypes":["ScaleAnchor.Bottom","Number"],"pyQName":"ScaleAnchor.BOTTOM"},"ScaleAnchor.TopLeft":{"retType":"ScaleAnchor","attributes":{"block":"top left","_def":{"parts":[{"kind":"label","text":"top left","style":[]}],"parameters":[]}},"extendsTypes":["ScaleAnchor.TopLeft","Number"],"pyQName":"ScaleAnchor.TOP_LEFT"},"ScaleAnchor.TopRight":{"retType":"ScaleAnchor","attributes":{"block":"top right","_def":{"parts":[{"kind":"label","text":"top right","style":[]}],"parameters":[]}},"extendsTypes":["ScaleAnchor.TopRight","Number"],"pyQName":"ScaleAnchor.TOP_RIGHT"},"ScaleAnchor.BottomLeft":{"retType":"ScaleAnchor","attributes":{"block":"bottom left","_def":{"parts":[{"kind":"label","text":"bottom left","style":[]}],"parameters":[]}},"extendsTypes":["ScaleAnchor.BottomLeft","Number"],"pyQName":"ScaleAnchor.BOTTOM_LEFT"},"ScaleAnchor.BottomRight":{"retType":"ScaleAnchor","attributes":{"block":"bottom right","_def":{"parts":[{"kind":"label","text":"bottom right","style":[]}],"parameters":[]}},"extendsTypes":["ScaleAnchor.BottomRight","Number"],"pyQName":"ScaleAnchor.BOTTOM_RIGHT"},"Sprite":{"kind":8,"retType":"Sprite","attributes":{"blockNamespace":"sprites","color":"#3B6FEA","blockGap":"8","jsDoc":"A sprite on the screen"},"extendsTypes":["Sprite","sprites.BaseSprite","SpriteLike"]},"Sprite._x":{"kind":2,"retType":"Fx8","isInstance":true},"Sprite._y":{"kind":2,"retType":"Fx8","isInstance":true},"Sprite._vx":{"kind":2,"retType":"Fx8","isInstance":true},"Sprite._vy":{"kind":2,"retType":"Fx8","isInstance":true},"Sprite._ax":{"kind":2,"retType":"Fx8","isInstance":true},"Sprite._ay":{"kind":2,"retType":"Fx8","isInstance":true},"Sprite._fx":{"kind":2,"retType":"Fx8","isInstance":true},"Sprite._fy":{"kind":2,"retType":"Fx8","isInstance":true},"Sprite._sx":{"kind":2,"retType":"Fx8","isInstance":true},"Sprite._sy":{"kind":2,"retType":"Fx8","isInstance":true},"Sprite._width":{"kind":2,"retType":"Fx8","isInstance":true},"Sprite._height":{"kind":2,"retType":"Fx8","isInstance":true},"Sprite.x":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"x","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.x@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"x","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.y":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"y","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.y@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"y","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.vx":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"vx (velocity x)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"vx (velocity x)","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.vx@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"vx (velocity x)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"vx (velocity x)","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.vy":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"vy (velocity y)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"vy (velocity y)","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.vy@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"vy (velocity y)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"vy (velocity y)","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.ax":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"ax (acceleration x)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"ax (acceleration x)","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.ax@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"ax (acceleration x)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"ax (acceleration x)","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.ay":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"ay (acceleration y)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"ay (acceleration y)","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.ay@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"ay (acceleration y)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"ay (acceleration y)","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.fx":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"fx (friction x)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"fx (friction x)","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.fx@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"fx (friction x)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"fx (friction x)","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.fy":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"fy (friction y)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"fy (friction y)","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.fy@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"fy (friction y)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"fy (friction y)","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.sx":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"sx (scale x)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"sx (scale x)","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.sx@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"sx (scale x)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"sx (scale x)","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.sy":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"sy (scale y)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"sy (scale y)","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.sy@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"sy (scale y)","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"sy (scale y)","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.scale":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"scale","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"scale","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.scale@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"scale","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"scale","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.data":{"kind":-2,"retType":"any","attributes":{"jsDoc":"Custom data"},"isInstance":true,"isReadOnly":true},"Sprite.data@set":{"kind":-2,"retType":"any","attributes":{"jsDoc":"Custom data"},"isInstance":true},"Sprite._kind":{"kind":2,"retType":"number","isInstance":true},"Sprite.layer":{"kind":2,"retType":"number","attributes":{"group":"Physics","jsDoc":"A bitset of layer. Each bit is a layer, default is 1."},"isInstance":true},"Sprite._lastX":{"kind":2,"retType":"Fx8","isInstance":true,"pyQName":"Sprite._last_x"},"Sprite._lastY":{"kind":2,"retType":"Fx8","isInstance":true,"pyQName":"Sprite._last_y"},"Sprite._action":{"kind":2,"retType":"number","isInstance":true},"Sprite.lifespan":{"kind":2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"lifespan","jsDoc":"Time to live in milliseconds. The lifespan decreases by 1 on each millisecond\nand the sprite gets destroyed when it reaches 0.","_def":{"parts":[{"kind":"label","text":"lifespan","style":[]}],"parameters":[]}},"isInstance":true},"Sprite._hitbox":{"kind":2,"retType":"game.Hitbox","isInstance":true},"Sprite._overlappers":{"kind":2,"retType":"number[]","isInstance":true},"Sprite._alreadyChecked":{"kind":2,"retType":"number[]","isInstance":true,"pyQName":"Sprite._already_checked"},"Sprite._kindsOverlappedWith":{"kind":2,"retType":"number[]","isInstance":true,"pyQName":"Sprite._kinds_overlapped_with"},"Sprite.flags":{"kind":2,"retType":"number","isInstance":true},"Sprite.__constructor":{"kind":-3,"parameters":[{"name":"img","type":"Image"}],"isInstance":true},"Sprite.__serialize":{"kind":-1,"retType":"Buffer","parameters":[{"name":"offset"}],"isInstance":true},"Sprite.image":{"kind":-2,"retType":"Image","attributes":{"group":"Image","blockId":"spriteimage","block":"%sprite(mySprite) image","weight":8,"help":"sprites/sprite/image","jsDoc":"Gets the current image","_def":{"parts":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" image","style":[]}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"}]}},"isInstance":true,"isReadOnly":true},"Sprite.setImage":{"kind":-1,"attributes":{"group":"Image","blockId":"spritesetimage","block":"set %sprite(mySprite) image to %img=screen_image_picker","weight":7,"help":"sprites/sprite/set-image","jsDoc":"Sets the image on the sprite","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" image to ","style":[]},{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"img","shadowBlockId":"screen_image_picker","ref":false}]}},"parameters":[{"name":"img","type":"Image"}],"isInstance":true,"pyQName":"Sprite.set_image"},"Sprite.calcDimensionalHash":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"Sprite.calc_dimensional_hash"},"Sprite.resetHitbox":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"Sprite.reset_hitbox"},"Sprite.setHitbox":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"Sprite.set_hitbox"},"Sprite.isStatic":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"Sprite.is_static"},"Sprite.__visible":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true},"Sprite.width":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"width","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"width","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.height":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"height","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"height","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.left":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"left","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.left@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"left","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.right":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"right","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.right@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"right","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.top":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"top","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"top","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.top@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"top","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"top","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.bottom":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"bottom","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"bottom","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"Sprite.bottom@set":{"kind":-2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"bottom","callInDebugger":true,"_def":{"parts":[{"kind":"label","text":"bottom","style":[]}],"parameters":[]}},"isInstance":true},"Sprite.kind":{"kind":-1,"retType":"number","attributes":{"group":"Overlaps","blockId":"spritegetkind","block":"%sprite(mySprite) kind","weight":79,"help":"sprites/sprite/kind","jsDoc":"The type of sprite","_def":{"parts":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" kind","style":[]}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"}]}},"parameters":[],"isInstance":true},"Sprite.setKind":{"kind":-1,"attributes":{"group":"Overlaps","blockId":"spritesetkind","block":"set %sprite(mySprite) kind to %kind","_shadowOverrides":{"kind":"spritekind"},"weight":80,"help":"sprites/sprite/set-kind","jsDoc":"The type of sprite","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" kind to ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":false}]}},"parameters":[{"name":"value"}],"isInstance":true,"pyQName":"Sprite.set_kind"},"Sprite.setPosition":{"kind":-1,"attributes":{"group":"Physics","weight":100,"blockId":"spritesetpos","block":"set %sprite(mySprite) position to x %x y %y","help":"sprites/sprite/set-position","_shadowOverrides":{"x":"positionPicker","y":"positionPicker"},"paramHelp":{"x":"horizontal position in pixels","y":"vertical position in pixels"},"jsDoc":"Set the sprite position in pixels starting from the top-left corner of the screen.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" position to x ","style":[]},{"kind":"param","name":"x","shadowBlockId":"positionPicker","ref":false},{"kind":"label","text":" y ","style":[]},{"kind":"param","name":"y","shadowBlockId":"positionPicker","ref":false}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"x","shadowBlockId":"positionPicker","ref":false},{"kind":"param","name":"y","shadowBlockId":"positionPicker","ref":false}]}},"parameters":[{"name":"x","description":"horizontal position in pixels"},{"name":"y","description":"vertical position in pixels"}],"isInstance":true,"pyQName":"Sprite.set_position"},"Sprite.setVelocity":{"kind":-1,"attributes":{"group":"Physics","weight":100,"blockId":"spritesetvel","block":"set %sprite(mySprite) velocity to vx %vx vy %vy","help":"sprites/sprite/set-velocity","_shadowOverrides":{"vx":"spriteSpeedPicker","vy":"spriteSpeedPicker"},"paramHelp":{"vx":"@param vy"},"jsDoc":"Sets the sprite velocity in pixel / sec","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" velocity to vx ","style":[]},{"kind":"param","name":"vx","shadowBlockId":"spriteSpeedPicker","ref":false},{"kind":"label","text":" vy ","style":[]},{"kind":"param","name":"vy","shadowBlockId":"spriteSpeedPicker","ref":false}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"vx","shadowBlockId":"spriteSpeedPicker","ref":false},{"kind":"param","name":"vy","shadowBlockId":"spriteSpeedPicker","ref":false}]}},"parameters":[{"name":"vx","description":"@param vy"},{"name":"vy"}],"isInstance":true,"pyQName":"Sprite.set_velocity"},"Sprite.say":{"kind":-1,"attributes":{"paramDefl":{"text":":)"},"group":"Effects","weight":60,"blockId":"spritesay","block":"%sprite(mySprite) say %text||for %millis ms","_shadowOverrides":{"millis":"timePicker","text":"text"},"inlineInputMode":"inline","deprecated":"true","help":"sprites/sprite/say","paramHelp":{"text":"the text to say, eg: \":)\"","time":"time to keep text on"},"jsDoc":"Deprecated! Use sayText instead.\n* Display a speech bubble with the text, for the given time.","_def":{"parts":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" say ","style":[]},{"kind":"param","name":"text","shadowBlockId":"text","ref":false}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"text","shadowBlockId":"text","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":"for ","style":[]},{"kind":"param","name":"millis","shadowBlockId":"timePicker","ref":false},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"millis","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"text","description":"the text to say, eg: \":)\"","type":"any","default":":)"},{"name":"timeOnScreen","initializer":"undefined"},{"name":"textColor","initializer":"15"},{"name":"textBoxColor","initializer":"1"}],"isInstance":true},"Sprite.sayText":{"kind":-1,"attributes":{"paramDefl":{"this":"mySprite","text":":)"},"group":"Effects","weight":60,"blockId":"spritesaytext","block":"$this say $text||for $timeOnScreen ms with animation $animated","_shadowOverrides":{"timeOnScreen":"timePicker","text":"text","this":"variables_get"},"explicitDefaults":["this"],"inlineInputMode":"inline","help":"sprites/sprite/say","expandableArgumentMode":"toggle","paramHelp":{"text":"the text to say, eg: \":)\"","time":"time to keep text on","animated":"whether to print the text character by character or not"},"jsDoc":"Display a speech bubble with the text, for the given time","_def":{"parts":[{"kind":"param","name":"this","shadowBlockId":"variables_get","ref":true},{"kind":"label","text":" say ","style":[]},{"kind":"param","name":"text","shadowBlockId":"text","ref":true}],"parameters":[{"kind":"param","name":"this","shadowBlockId":"variables_get","ref":true},{"kind":"param","name":"text","shadowBlockId":"text","ref":true}]},"_expandedDef":{"parts":[{"kind":"label","text":"for ","style":[]},{"kind":"param","name":"timeOnScreen","shadowBlockId":"timePicker","ref":true},{"kind":"label","text":" ms with animation ","style":[]},{"kind":"param","name":"animated","ref":true}],"parameters":[{"kind":"param","name":"timeOnScreen","shadowBlockId":"timePicker","ref":true},{"kind":"param","name":"animated","ref":true}]}},"parameters":[{"name":"text","description":"the text to say, eg: \":)\"","type":"any","default":":)"},{"name":"timeOnScreen","initializer":"undefined"},{"name":"animated","description":"whether to print the text character by character or not","type":"boolean","initializer":"false"},{"name":"textColor","initializer":"15"},{"name":"textBoxColor","initializer":"1"}],"isInstance":true,"pyQName":"Sprite.say_text"},"Sprite.startEffect":{"kind":-1,"attributes":{"group":"Effects","weight":90,"blockId":"startEffectOnSprite","block":"%sprite(mySprite) start %effect effect || for %duration=timePicker|ms","help":"sprites/sprite/start-effect","paramHelp":{"effect":"the type of effect to create"},"jsDoc":"Start an effect on this sprite","_def":{"parts":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" start ","style":[]},{"kind":"param","name":"effect","ref":false},{"kind":"label","text":" effect ","style":[]}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"effect","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":" for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"effect","description":"the type of effect to create","type":"effects.ParticleEffect"},{"name":"duration","initializer":"undefined"}],"isInstance":true,"pyQName":"Sprite.start_effect"},"Sprite.isOutOfScreen":{"kind":-1,"retType":"boolean","attributes":{"jsDoc":"Indicates if the sprite is outside the screen"},"parameters":[{"name":"camera","type":"scene.Camera"}],"isInstance":true,"pyQName":"Sprite.is_out_of_screen"},"Sprite.__drawCore":{"kind":-1,"parameters":[{"name":"camera","type":"scene.Camera"}],"isInstance":true},"Sprite.__update":{"kind":-1,"parameters":[{"name":"camera","type":"scene.Camera"},{"name":"dt"}],"isInstance":true},"Sprite.setStayInScreen":{"kind":-1,"attributes":{"paramDefl":{"on":"true"},"group":"Effects","weight":30,"blockId":"spritesetsetstayinscreen","block":"set %sprite(mySprite) stay in screen %on=toggleOnOff","explicitDefaults":["on"],"help":"sprites/sprite/set-stay-in-screen","jsDoc":"Set whether a sprite should be constrained within the screen (on) or not (off)","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" stay in screen ","style":[]},{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}]}},"parameters":[{"name":"on","type":"boolean","initializer":"true","default":"true"}],"isInstance":true,"pyQName":"Sprite.set_stay_in_screen"},"Sprite.setBounceOnWall":{"kind":-1,"attributes":{"paramDefl":{"on":"true"},"group":"Effects","weight":25,"blockId":"spritesetsetbounceonwall","block":"set %sprite(mySprite) bounce on wall %on=toggleOnOff","explicitDefaults":["on"],"help":"sprites/sprite/set-bounce-on-wall","jsDoc":"Set whether a sprite should bounce when it hits a wall (on) or not (off)","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" bounce on wall ","style":[]},{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}]}},"parameters":[{"name":"on","type":"boolean","initializer":"true","default":"true"}],"isInstance":true,"pyQName":"Sprite.set_bounce_on_wall"},"Sprite.setFlag":{"kind":-1,"attributes":{"paramDefl":{"flag":"SpriteFlag.AutoDestroy"},"group":"Effects","weight":10,"blockId":"spritesetsetflag","block":"set %sprite(mySprite) %flag %on=toggleOnOff","explicitDefaults":["flag"],"help":"sprites/sprite/set-flag","jsDoc":"Set a sprite flag","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"flag","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"flag","ref":false},{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":false}]}},"parameters":[{"name":"flag","type":"SpriteFlag","initializer":"SpriteFlag.AutoDestroy","default":"SpriteFlag.AutoDestroy","isEnum":true},{"name":"on","type":"boolean"}],"isInstance":true,"pyQName":"Sprite.set_flag"},"Sprite.overlapsWith":{"kind":-1,"retType":"boolean","attributes":{"group":"Overlaps","blockId":"spriteoverlapswith","block":"%sprite(mySprite) overlaps with %other=variables_get(otherSprite)","help":"sprites/sprite/overlaps-with","weight":90,"paramHelp":{"other":""},"jsDoc":"Check if this sprite overlaps another sprite","_def":{"parts":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" overlaps with ","style":[]},{"kind":"param","name":"other","shadowBlockId":"variables_get","ref":false,"varName":"otherSprite"}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"other","shadowBlockId":"variables_get","ref":false,"varName":"otherSprite"}]}},"parameters":[{"name":"other","type":"Sprite"}],"isInstance":true,"pyQName":"Sprite.overlaps_with"},"Sprite.isHittingTile":{"kind":-1,"retType":"boolean","attributes":{"blockId":"spritehasobstacle","block":"is %sprite(mySprite) hitting wall %direction","blockNamespace":"scene","group":"Locations","blockGap":"24","help":"scene/is-hitting-tile","weight":15,"paramHelp":{"direction":""},"jsDoc":"Check if there is an obstacle in the given direction","_def":{"parts":[{"kind":"label","text":"is ","style":[]},{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" hitting wall ","style":[]},{"kind":"param","name":"direction","ref":false}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"direction","ref":false}]}},"parameters":[{"name":"direction","type":"CollisionDirection","isEnum":true}],"isInstance":true,"pyQName":"Sprite.is_hitting_tile"},"Sprite.tileKindAt":{"kind":-1,"retType":"boolean","attributes":{"blockId":"spritetileat","block":"tile to $direction of $this(mySprite) is $tile","_shadowOverrides":{"tile":"tileset_tile_picker"},"blockNamespace":"scene","group":"Locations","blockGap":"8","help":"scene/tile-kind-at","weight":20,"paramHelp":{"direction":""},"jsDoc":"Get the tile kind in a given direction if any","_def":{"parts":[{"kind":"label","text":"tile to ","style":[]},{"kind":"param","name":"direction","ref":true},{"kind":"label","text":" of ","style":[]},{"kind":"param","name":"this","ref":true,"varName":"mySprite"},{"kind":"label","text":" is ","style":[]},{"kind":"param","name":"tile","shadowBlockId":"tileset_tile_picker","ref":true}],"parameters":[{"kind":"param","name":"direction","ref":true},{"kind":"param","name":"this","ref":true,"varName":"mySprite"},{"kind":"param","name":"tile","shadowBlockId":"tileset_tile_picker","ref":true}]}},"parameters":[{"name":"direction","type":"TileDirection","isEnum":true},{"name":"tile","type":"Image"}],"isInstance":true,"pyQName":"Sprite.tile_kind_at"},"Sprite.tileHitFrom":{"kind":-1,"retType":"number","attributes":{"blockId":"spriteobstacle","block":"%sprite(mySprite) wall hit on %direction","blockNamespace":"scene","group":"Locations","help":"sprites/sprite/tile-hit-from","deprecated":"1","paramHelp":{"direction":""},"jsDoc":"Get the obstacle sprite in a given direction if any","_def":{"parts":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" wall hit on ","style":[]},{"kind":"param","name":"direction","ref":false}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"direction","ref":false}]}},"parameters":[{"name":"direction"}],"isInstance":true,"pyQName":"Sprite.tile_hit_from"},"Sprite.tilemapLocation":{"kind":-1,"retType":"tiles.Location","attributes":{"paramDefl":{"this":"mySprite"},"block":"tilemap location of $this","blockId":"tiles_location_of_sprite","_shadowOverrides":{"this":"variables_get"},"explicitDefaults":["this"],"blockNamespace":"scene","group":"Locations","weight":90,"help":"scene/tilemap-location","jsDoc":"Gets the tilemap location at the center of a sprite","_def":{"parts":[{"kind":"label","text":"tilemap location of ","style":[]},{"kind":"param","name":"this","shadowBlockId":"variables_get","ref":true}],"parameters":[{"kind":"param","name":"this","shadowBlockId":"variables_get","ref":true}]}},"parameters":[],"isInstance":true,"pyQName":"Sprite.tilemap_location"},"Sprite.clearObstacles":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"Sprite.clear_obstacles"},"Sprite.registerObstacle":{"kind":-1,"parameters":[{"name":"direction","type":"CollisionDirection","isEnum":true},{"name":"other","type":"sprites.Obstacle"},{"name":"tm","type":"tiles.TileMap","initializer":"undefined"}],"isInstance":true,"pyQName":"Sprite.register_obstacle"},"Sprite.onDestroyed":{"kind":-1,"attributes":{"group":"Lifecycle","weight":9,"paramHelp":{"handler":""},"jsDoc":"Run code when the sprite is destroyed"},"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"Sprite.on_destroyed"},"Sprite.destroy":{"kind":-1,"attributes":{"group":"Effects","weight":80,"blockId":"spritedestroy","block":"destroy %sprite(mySprite) || with %effect effect for %duration ms","_shadowOverrides":{"duration":"timePicker"},"expandableArgumentMode":"toggle","help":"sprites/sprite/destroy","deprecated":"1","jsDoc":"Destroy the sprite","_def":{"parts":[{"kind":"label","text":"destroy ","style":[]},{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" ","style":[]}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"}]},"_expandedDef":{"parts":[{"kind":"label","text":" with ","style":[]},{"kind":"param","name":"effect","ref":false},{"kind":"label","text":" effect for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"effect","ref":false},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"effect","type":"effects.ParticleEffect","initializer":"undefined"},{"name":"duration","initializer":"undefined"}],"isInstance":true},"Sprite._destroyCore":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"Sprite._destroy_core"},"Sprite.follow":{"kind":-1,"attributes":{"paramDefl":{"speed":"100"},"group":"Physics","weight":10,"blockId":"spriteFollowOtherSprite","block":"set %sprite(myEnemy) follow %target=variables_get(mySprite) || with speed %speed","help":"sprites/sprite/follow","paramHelp":{"speed":"the rate at which this sprite should move, eg: 100","turnRate":"how quickly the sprite should turn while following."},"jsDoc":"Make this sprite follow the target sprite.\n* @param target the sprite this one should follow\n\n\nThe default (400) will cause the sprite to reach max speed after approximately 125 ms when standing still,\nand turn around 180 degrees when at max speed after approximately 250 ms.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sprite","ref":false,"varName":"myEnemy"},{"kind":"label","text":" follow ","style":[]},{"kind":"param","name":"target","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"},{"kind":"label","text":" ","style":[]}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"myEnemy"},{"kind":"param","name":"target","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"}]},"_expandedDef":{"parts":[{"kind":"label","text":" with speed ","style":[]},{"kind":"param","name":"speed","ref":false}],"parameters":[{"kind":"param","name":"speed","ref":false}]}},"parameters":[{"name":"target","type":"Sprite"},{"name":"speed","description":"the rate at which this sprite should move, eg: 100","initializer":"100","default":"100"},{"name":"turnRate","description":"how quickly the sprite should turn while following.","initializer":"400"}],"isInstance":true},"Sprite.setScaleCore":{"kind":-1,"parameters":[{"name":"sx","initializer":"undefined"},{"name":"sy","initializer":"undefined"},{"name":"anchor","type":"ScaleAnchor","initializer":"undefined","isEnum":true},{"name":"proportional","type":"boolean","initializer":"undefined"}],"isInstance":true,"pyQName":"Sprite.set_scale_core"},"Sprite.setScale":{"kind":-1,"attributes":{"paramDefl":{"value":"1","anchor":"ScaleAnchor.Middle"},"blockId":"sprite_set_scale","block":"set %sprite(mySprite) scale to $value anchor $anchor","expandableArgumentMode":"enabled","inlineInputMode":"inline","explicitDefaults":["value","anchor"],"help":"sprites/sprite/set-scale","group":"Scale","weight":90,"_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" scale to ","style":[]},{"kind":"param","name":"value","ref":true},{"kind":"label","text":" anchor ","style":[]},{"kind":"param","name":"anchor","ref":true}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"value","ref":true},{"kind":"param","name":"anchor","ref":true}]}},"parameters":[{"name":"value","initializer":"1","default":"1"},{"name":"anchor","type":"ScaleAnchor","initializer":"ScaleAnchor.Middle","default":"ScaleAnchor.Middle","isEnum":true}],"isInstance":true,"pyQName":"Sprite.set_scale"},"Sprite.changeScale":{"kind":-1,"attributes":{"paramDefl":{"value":"1","anchor":"ScaleAnchor.Middle"},"blockId":"sprite_change_scale","block":"change %sprite(mySprite) scale by $value anchor $anchor","expandableArgumentMode":"enabled","inlineInputMode":"inline","explicitDefaults":["value","anchor"],"help":"sprites/sprite/change-scale","group":"Scale","weight":90,"_def":{"parts":[{"kind":"label","text":"change ","style":[]},{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"label","text":" scale by ","style":[]},{"kind":"param","name":"value","ref":true},{"kind":"label","text":" anchor ","style":[]},{"kind":"param","name":"anchor","ref":true}],"parameters":[{"kind":"param","name":"sprite","ref":false,"varName":"mySprite"},{"kind":"param","name":"value","ref":true},{"kind":"param","name":"anchor","ref":true}]}},"parameters":[{"name":"value","initializer":"1","default":"1"},{"name":"anchor","type":"ScaleAnchor","initializer":"ScaleAnchor.Middle","default":"ScaleAnchor.Middle","isEnum":true}],"isInstance":true,"pyQName":"Sprite.change_scale"},"Sprite.toString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"Sprite.to_string"},"sprites.ExtendableSprite":{"kind":8,"retType":"sprites.ExtendableSprite","attributes":{"jsDoc":"A version of the Sprite class that is easier to extend.\n* Unlike the normal Sprite class, this class will automatically add\nitself to the physics engine and run all sprite created handlers\nin the constructor"},"extendsTypes":["sprites.ExtendableSprite","Sprite","sprites.BaseSprite","SpriteLike"]},"sprites.ExtendableSprite.__constructor":{"kind":-3,"parameters":[{"name":"spriteImage","type":"Image"},{"name":"kind","initializer":"undefined"}],"isInstance":true},"sprites.ExtendableSprite.draw":{"kind":-1,"attributes":{"paramHelp":{"drawTop":"The top position to draw the sprite at (already adjusted for camera)"},"jsDoc":"Override to change how the sprite is drawn to the screen\n* @param drawLeft The left position to draw the sprite at (already adjusted for camera)"},"parameters":[{"name":"drawLeft"},{"name":"drawTop","description":"The top position to draw the sprite at (already adjusted for camera)"}],"isInstance":true},"sprites.ExtendableSprite.update":{"kind":-1,"attributes":{"jsDoc":"Override to add update logic for a sprite. This method runs once per frame\n* @param deltaTimeMillis The time that has elapsed since the last frame in milliseconds"},"parameters":[{"name":"deltaTimeMillis"}],"isInstance":true},"sprites.ExtendableSprite.setDimensions":{"kind":-1,"attributes":{"jsDoc":"Sets the width and height of this sprite. Once set, this will also prevent\nthis width and height from automatically changing whenever scale or the image\nchanges"},"parameters":[{"name":"width"},{"name":"height"}],"isInstance":true,"pyQName":"sprites.ExtendableSprite.set_dimensions"},"sprites.ExtendableSprite.__update":{"kind":-1,"parameters":[{"name":"camera","type":"scene.Camera"},{"name":"dt"}],"isInstance":true},"sprites.ExtendableSprite.setHitbox":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"sprites.ExtendableSprite.set_hitbox"},"Sprite@type":{"kind":9,"retType":"Sprite","extendsTypes":[],"pyQName":"Sprite"},"Sprite.z":{"kind":2,"retType":"number","attributes":{"group":"Physics","blockSetVariable":"mySprite","blockCombine":true,"block":"z (depth)","_def":{"parts":[{"kind":"label","text":"z (depth)","style":[]}],"parameters":[]}},"isInstance":true},"sprites.SpriteMap":{"kind":8,"retType":"sprites.SpriteMap","extendsTypes":[]},"sprites.SpriteMap.filledBuckets":{"kind":2,"retType":"Sprite[][]","isInstance":true,"pyQName":"sprites.SpriteMap.filled_buckets"},"sprites.SpriteMap.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"sprites.SpriteMap.neighbors":{"kind":-1,"retType":"Sprite[]","attributes":{"jsDoc":"Returns a potential list of neighbors"},"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true},"sprites.SpriteMap.overlaps":{"kind":-1,"retType":"Sprite[]","attributes":{"paramHelp":{"sprite":""},"jsDoc":"Gets the overlaping sprites if any"},"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true},"sprites.SpriteMap.draw":{"kind":-1,"parameters":[],"isInstance":true},"sprites.SpriteMap.resizeBuckets":{"kind":-1,"attributes":{"jsDoc":"Recompute hashes for all objects"},"parameters":[{"name":"sprites","type":"Sprite[]"}],"isInstance":true,"pyQName":"sprites.SpriteMap.resize_buckets"},"sprites.SpriteMap.clear":{"kind":-1,"parameters":[],"isInstance":true},"sprites.SpriteMap.insertAABB":{"kind":-1,"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true,"pyQName":"sprites.SpriteMap.insert_aabb"},"sprites.SpriteMap.toString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"sprites.SpriteMap.to_string"},"sprites.onCreated":{"kind":-3,"attributes":{"group":"Lifecycle","draggableParameters":"reporter","weight":97,"blockId":"spritesoncreated","block":"on created $sprite of kind $kind=spritekind","help":"sprites/on-created","paramHelp":{"kind":"@param sprite"},"jsDoc":"Run code when a certain kind of sprite is created","_def":{"parts":[{"kind":"label","text":"on created ","style":[]},{"kind":"param","name":"sprite","ref":true},{"kind":"label","text":" of kind ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true}],"parameters":[{"kind":"param","name":"sprite","ref":true},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true}]}},"parameters":[{"name":"kind","description":"@param sprite"},{"name":"handler","type":"(sprite: Sprite) => void","handlerParameters":[{"name":"sprite","type":"Sprite"}]}],"pyQName":"sprites.on_created"},"sprites.onDestroyed":{"kind":-3,"attributes":{"group":"Lifecycle","weight":96,"draggableParameters":"reporter","blockId":"spritesondestroyed","block":"on destroyed $sprite of kind $kind=spritekind ","help":"sprites/on-destroyed","paramHelp":{"kind":"@param sprite"},"jsDoc":"Run code when a certain kind of sprite is destroyed","_def":{"parts":[{"kind":"label","text":"on destroyed ","style":[]},{"kind":"param","name":"sprite","ref":true},{"kind":"label","text":" of kind ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true},{"kind":"label","text":" ","style":[]}],"parameters":[{"kind":"param","name":"sprite","ref":true},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true}]}},"parameters":[{"name":"kind","description":"@param sprite"},{"name":"handler","type":"(sprite: Sprite) => void","handlerParameters":[{"name":"sprite","type":"Sprite"}]}],"pyQName":"sprites.on_destroyed"},"sprites.onOverlap":{"kind":-3,"attributes":{"group":"Overlaps","weight":100,"draggableParameters":"reporter","blockId":"spritesoverlap","block":"on $sprite of kind $kind=spritekind overlaps $otherSprite of kind $otherKind=spritekind","help":"sprites/on-overlap","blockGap":"8","jsDoc":"Run code when two kinds of sprites overlap","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"sprite","ref":true},{"kind":"label","text":" of kind ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true},{"kind":"label","text":" overlaps ","style":[]},{"kind":"param","name":"otherSprite","ref":true},{"kind":"label","text":" of kind ","style":[]},{"kind":"param","name":"otherKind","shadowBlockId":"spritekind","ref":true}],"parameters":[{"kind":"param","name":"sprite","ref":true},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true},{"kind":"param","name":"otherSprite","ref":true},{"kind":"param","name":"otherKind","shadowBlockId":"spritekind","ref":true}]}},"parameters":[{"name":"kind"},{"name":"otherKind"},{"name":"handler","type":"(sprite: Sprite, otherSprite: Sprite) => void","handlerParameters":[{"name":"sprite","type":"Sprite"},{"name":"otherSprite","type":"Sprite"}]}],"pyQName":"sprites.on_overlap"},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"scene.onOverlapTile":{"kind":-3,"attributes":{"group":"Tilemaps","weight":120,"draggableParameters":"reporter","blockGap":"8","blockId":"spriteshittile","block":"on $sprite of kind $kind=spritekind overlaps $tile at $location","_shadowOverrides":{"tile":"tileset_tile_picker"},"help":"scene/on-overlap-tile","paramHelp":{"kind":"@param tile","handler":""},"jsDoc":"Run code when a certain kind of sprite overlaps a tile","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"sprite","ref":true},{"kind":"label","text":" of kind ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true},{"kind":"label","text":" overlaps ","style":[]},{"kind":"param","name":"tile","shadowBlockId":"tileset_tile_picker","ref":true},{"kind":"label","text":" at ","style":[]},{"kind":"param","name":"location","ref":true}],"parameters":[{"kind":"param","name":"sprite","ref":true},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true},{"kind":"param","name":"tile","shadowBlockId":"tileset_tile_picker","ref":true},{"kind":"param","name":"location","ref":true}]}},"parameters":[{"name":"kind","description":"@param tile"},{"name":"tile","type":"Image"},{"name":"handler","type":"(sprite: Sprite, location: tiles.Location) => void","handlerParameters":[{"name":"sprite","type":"Sprite"},{"name":"location","type":"tiles.Location"}]}],"pyQName":"scene.on_overlap_tile"},"scene.onHitWall":{"kind":-3,"attributes":{"group":"Tilemaps","weight":100,"draggableParameters":"reporter","blockGap":"8","blockId":"spriteshitwall","block":"on $sprite of kind $kind=spritekind hits wall at $location","help":"scene/on-hit-wall","paramHelp":{"kind":"@param handler"},"jsDoc":"Run code when a certain kind of sprite hits a wall","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"sprite","ref":true},{"kind":"label","text":" of kind ","style":[]},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true},{"kind":"label","text":" hits wall at ","style":[]},{"kind":"param","name":"location","ref":true}],"parameters":[{"kind":"param","name":"sprite","ref":true},{"kind":"param","name":"kind","shadowBlockId":"spritekind","ref":true},{"kind":"param","name":"location","ref":true}]}},"parameters":[{"name":"kind","description":"@param handler"},{"name":"handler","type":"(sprite: Sprite, location: tiles.Location) => void","handlerParameters":[{"name":"sprite","type":"Sprite"},{"name":"location","type":"tiles.Location"}]}],"pyQName":"scene.on_hit_wall"},"sprites.SpriteSet":{"kind":8,"retType":"sprites.SpriteSet","extendsTypes":[]},"sprites.SpriteSet.createFromArray":{"kind":-1,"retType":"sprites.SpriteSet","attributes":{"paramHelp":{"sprites":""},"jsDoc":"Create a new set from an array of sprites"},"parameters":[{"name":"sprites","type":"Sprite[]"}],"pyQName":"sprites.SpriteSet.create_from_array"},"sprites.SpriteSet.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"sprites.SpriteSet.length":{"kind":-2,"retType":"number","attributes":{"jsDoc":"Gets the number of sprites in the set"},"isInstance":true,"isReadOnly":true},"sprites.SpriteSet.sprites":{"kind":-1,"retType":"Sprite[]","attributes":{"jsDoc":"Gets the snapshot of the current list of sprites"},"parameters":[],"isInstance":true},"sprites.SpriteSet.add":{"kind":-1,"retType":"boolean","attributes":{"paramHelp":{"sprite":""},"jsDoc":"Adds the sprite, returns true if added; false if the sprite was already in the set"},"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true},"sprites.SpriteSet.addFrom":{"kind":-1,"retType":"boolean","attributes":{"paramHelp":{"oldSet":"@param sprite"},"jsDoc":"Adds sprite and removes from old set. Returns true if sprite was in old set and not in new set."},"parameters":[{"name":"oldSet","description":"@param sprite","type":"sprites.SpriteSet"},{"name":"sprite","type":"Sprite"}],"isInstance":true,"pyQName":"sprites.SpriteSet.add_from"},"sprites.SpriteSet.remove":{"kind":-1,"retType":"boolean","attributes":{"paramHelp":{"sprite":""},"jsDoc":"Removes sprite from set. Returns true if the sprite was in the set"},"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true},"sprites.SpriteSet.contains":{"kind":-1,"retType":"boolean","attributes":{"paramHelp":{"sprite":""},"jsDoc":"Checks if the sprite is part of the set"},"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true},"sprites.SpriteSet.clear":{"kind":-1,"attributes":{"jsDoc":"Removes all the sprites from the set"},"parameters":[],"isInstance":true},"sprites.SpriteSet.pop":{"kind":-1,"retType":"Sprite","attributes":{"jsDoc":"Removes the last sprite in the set"},"parameters":[],"isInstance":true},"sprites.SpriteSet.toString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"sprites.SpriteSet.to_string"},"sprites._spriteKind":{"kind":-3,"retType":"number","attributes":{"shim":"KIND_GET","blockId":"spritekind","block":"$kind","kindNamespace":"SpriteKind","kindMemberName":"kind","kindPromptHint":"e.g. Coin, Fireball, Asteroid...","help":"sprites/sprite-kind","jsDoc":"Gets the \"kind\" of sprite","_def":{"parts":[{"kind":"param","name":"kind","ref":true}],"parameters":[{"kind":"param","name":"kind","ref":true}]}},"parameters":[{"name":"kind"}],"pyQName":"sprites._sprite_kind"},"sprites._spriteType":{"kind":-3,"retType":"number","attributes":{"blockHidden":true,"shim":"ENUM_GET","deprecated":"true","blockId":"spritetype","block":"$kind","enumInitialMembers":["Player","Projectile","Food","Enemy"],"enumName":"SpriteKindLegacy","enumMemberName":"kind","enumPromptHint":"e.g. Coin, Fireball, Asteroid...","jsDoc":"Gets the sprite type","_def":{"parts":[{"kind":"param","name":"kind","ref":true}],"parameters":[{"kind":"param","name":"kind","ref":true}]}},"parameters":[{"name":"kind"}],"pyQName":"sprites._sprite_type"},"SpriteKind":{"kind":5,"retType":""},"SpriteKind.create":{"kind":-3,"retType":"number","parameters":[]},"SpriteKind.Player":{"kind":4,"retType":"number","attributes":{"isKind":"true"},"pyQName":"SpriteKind.player"},"SpriteKind.Projectile":{"kind":4,"retType":"number","attributes":{"isKind":"true"},"pyQName":"SpriteKind.projectile"},"SpriteKind.Food":{"kind":4,"retType":"number","attributes":{"isKind":"true"},"pyQName":"SpriteKind.food"},"SpriteKind.Enemy":{"kind":4,"retType":"number","attributes":{"isKind":"true"},"pyQName":"SpriteKind.enemy"},"performance":{"kind":5,"retType":""},"sprites.Obstacle":{"kind":9,"retType":"sprites.Obstacle","extendsTypes":["sprites.Obstacle"]},"sprites.Obstacle.x":{"kind":2,"retType":"number","isInstance":true},"sprites.Obstacle.y":{"kind":2,"retType":"number","isInstance":true},"sprites.Obstacle.left":{"kind":2,"retType":"number","isInstance":true},"sprites.Obstacle.right":{"kind":2,"retType":"number","isInstance":true},"sprites.Obstacle.top":{"kind":2,"retType":"number","isInstance":true},"sprites.Obstacle.bottom":{"kind":2,"retType":"number","isInstance":true},"sprites.Obstacle.width":{"kind":2,"retType":"number","isInstance":true},"sprites.Obstacle.height":{"kind":2,"retType":"number","isInstance":true},"sprites.Obstacle.layer":{"kind":2,"retType":"number","isInstance":true},"sprites.Obstacle.image":{"kind":2,"retType":"Image","isInstance":true},"sprites.Obstacle.tileIndex":{"kind":2,"retType":"number","isInstance":true,"pyQName":"sprites.Obstacle.tile_index"},"sprites.StaticObstacle":{"kind":8,"retType":"sprites.StaticObstacle","extendsTypes":["sprites.StaticObstacle","sprites.Obstacle"]},"sprites.StaticObstacle.layer":{"kind":2,"retType":"number","isInstance":true},"sprites.StaticObstacle.image":{"kind":2,"retType":"Image","isInstance":true},"sprites.StaticObstacle.tileIndex":{"kind":2,"retType":"number","isInstance":true,"pyQName":"sprites.StaticObstacle.tile_index"},"sprites.StaticObstacle.top":{"kind":2,"retType":"number","isInstance":true},"sprites.StaticObstacle.left":{"kind":2,"retType":"number","isInstance":true},"sprites.StaticObstacle.__constructor":{"kind":-3,"parameters":[{"name":"image","type":"Image"},{"name":"top"},{"name":"left"},{"name":"layer"},{"name":"tileIndex","initializer":"undefined"}],"isInstance":true},"sprites.StaticObstacle.x":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"sprites.StaticObstacle.y":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"sprites.StaticObstacle.height":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"sprites.StaticObstacle.width":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"sprites.StaticObstacle.bottom":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"sprites.StaticObstacle.right":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"PhysicsEngine":{"kind":8,"retType":"PhysicsEngine","extendsTypes":["PhysicsEngine"]},"PhysicsEngine.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"PhysicsEngine.addSprite":{"kind":-1,"attributes":{"paramHelp":{"sprite":""},"jsDoc":"Adds sprite to the physics"},"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true,"pyQName":"PhysicsEngine.add_sprite"},"PhysicsEngine.removeSprite":{"kind":-1,"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true,"pyQName":"PhysicsEngine.remove_sprite"},"PhysicsEngine.moveSprite":{"kind":-1,"attributes":{"jsDoc":"move a single sprite *"},"parameters":[{"name":"s","type":"Sprite"},{"name":"dx","type":"Fx8"},{"name":"dy","type":"Fx8"}],"isInstance":true,"pyQName":"PhysicsEngine.move_sprite"},"PhysicsEngine.draw":{"kind":-1,"parameters":[],"isInstance":true},"PhysicsEngine.move":{"kind":-1,"attributes":{"jsDoc":"Apply physics and collisions to all sprites *"},"parameters":[{"name":"dt"}],"isInstance":true},"PhysicsEngine.setMaxSpeed":{"kind":-1,"parameters":[{"name":"speed"}],"isInstance":true,"pyQName":"PhysicsEngine.set_max_speed"},"PhysicsEngine.overlaps":{"kind":-1,"retType":"Sprite[]","parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true},"MAX_TIME_STEP":{"kind":4,"retType":"number"},"MIN_MOVE_GAP":{"kind":4,"retType":"Fx8"},"SPRITE_NO_TILE_OVERLAPS":{"kind":4,"retType":"number"},"SPRITE_NO_WALL_COLLISION":{"kind":4,"retType":"number"},"SPRITE_NO_SPRITE_OVERLAPS":{"kind":4,"retType":"number"},"MovingSprite":{"kind":8,"retType":"MovingSprite","extendsTypes":[]},"MovingSprite.__constructor":{"kind":-3,"parameters":[{"name":"sprite","type":"Sprite"},{"name":"cachedVx","type":"Fx8"},{"name":"cachedVy","type":"Fx8"},{"name":"dx","type":"Fx8"},{"name":"dy","type":"Fx8"},{"name":"xStep","type":"Fx8"},{"name":"yStep","type":"Fx8"}],"isInstance":true},"ArcadePhysicsEngine":{"kind":8,"retType":"ArcadePhysicsEngine","attributes":{"jsDoc":"A physics engine that does simple AABB bounding box check"},"extendsTypes":["ArcadePhysicsEngine","PhysicsEngine"]},"ArcadePhysicsEngine.__constructor":{"kind":-3,"parameters":[{"name":"maxVelocity","initializer":"500"},{"name":"minSingleStep","initializer":"2"},{"name":"maxSingleStep","initializer":"4"}],"isInstance":true},"ArcadePhysicsEngine.maxSpeed":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"ArcadePhysicsEngine.max_speed"},"ArcadePhysicsEngine.maxSpeed@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"ArcadePhysicsEngine.max_speed@set"},"ArcadePhysicsEngine.minStep":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"ArcadePhysicsEngine.min_step"},"ArcadePhysicsEngine.minStep@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"ArcadePhysicsEngine.min_step@set"},"ArcadePhysicsEngine.maxStep":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"ArcadePhysicsEngine.max_step"},"ArcadePhysicsEngine.maxStep@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"ArcadePhysicsEngine.max_step@set"},"ArcadePhysicsEngine.setMaxSpeed":{"kind":-1,"parameters":[{"name":"v"}],"isInstance":true,"pyQName":"ArcadePhysicsEngine.set_max_speed"},"ArcadePhysicsEngine.addSprite":{"kind":-1,"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true,"pyQName":"ArcadePhysicsEngine.add_sprite"},"ArcadePhysicsEngine.removeSprite":{"kind":-1,"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true,"pyQName":"ArcadePhysicsEngine.remove_sprite"},"ArcadePhysicsEngine.draw":{"kind":-1,"parameters":[],"isInstance":true},"ArcadePhysicsEngine.move":{"kind":-1,"parameters":[{"name":"dt"}],"isInstance":true},"ArcadePhysicsEngine.overlaps":{"kind":-1,"retType":"Sprite[]","attributes":{"paramHelp":{"sprite":"@param layer"},"jsDoc":"Returns sprites that overlap with the given sprite. If type is non-zero, also filter by type."},"parameters":[{"name":"sprite","description":"@param layer","type":"Sprite"}],"isInstance":true},"ArcadePhysicsEngine.moveSprite":{"kind":-1,"attributes":{"jsDoc":"moves a sprite explicitly outside of the normal velocity changes *"},"parameters":[{"name":"s","type":"Sprite"},{"name":"dx","type":"Fx8"},{"name":"dy","type":"Fx8"}],"isInstance":true,"pyQName":"ArcadePhysicsEngine.move_sprite"},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"info.Visibility":{"kind":6,"retType":"info.Visibility","extendsTypes":["info.Visibility","Number"]},"info.Visibility.None":{"retType":"info.Visibility","extendsTypes":["info.Visibility.None","Number"],"pyQName":"info.Visibility.NONE"},"info.Visibility.Countdown":{"retType":"info.Visibility","extendsTypes":["info.Visibility.Countdown","Number"],"pyQName":"info.Visibility.COUNTDOWN"},"info.Visibility.Score":{"retType":"info.Visibility","extendsTypes":["info.Visibility.Score","Number"],"pyQName":"info.Visibility.SCORE"},"info.Visibility.Life":{"retType":"info.Visibility","extendsTypes":["info.Visibility.Life","Number"],"pyQName":"info.Visibility.LIFE"},"info.Visibility.Hud":{"retType":"info.Visibility","extendsTypes":["info.Visibility.Hud","Number"],"pyQName":"info.Visibility.HUD"},"info.Visibility.Multi":{"retType":"info.Visibility","extendsTypes":["info.Visibility.Multi","Number"],"pyQName":"info.Visibility.MULTI"},"info.Visibility.UserHeartImage":{"retType":"info.Visibility","extendsTypes":["info.Visibility.UserHeartImage","Number"],"pyQName":"info.Visibility.USER_HEART_IMAGE"},"info.Visibility._ExplicitlySetScore":{"retType":"info.Visibility","extendsTypes":["info.Visibility._ExplicitlySetScore","Number"],"pyQName":"info.Visibility.__EXPLICITLY_SET_SCORE"},"info.Visibility._ExplicitlySetLife":{"retType":"info.Visibility","extendsTypes":["info.Visibility._ExplicitlySetLife","Number"],"pyQName":"info.Visibility.__EXPLICITLY_SET_LIFE"},"info.PlayerState":{"kind":8,"retType":"info.PlayerState","extendsTypes":[]},"info.PlayerState.score":{"kind":2,"retType":"number","isInstance":true},"info.PlayerState.life":{"kind":2,"retType":"number","isInstance":true},"info.PlayerState.lifeZeroHandler":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"info.PlayerState.life_zero_handler"},"info.PlayerState.scoreReachedHandlers":{"kind":2,"retType":"ScoreReachedHandler[]","isInstance":true,"pyQName":"info.PlayerState.score_reached_handlers"},"info.PlayerState.showScore":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"info.PlayerState.show_score"},"info.PlayerState.showLife":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"info.PlayerState.show_life"},"info.PlayerState.visibility":{"kind":2,"retType":"info.Visibility","isInstance":true},"info.PlayerState.showPlayer":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"info.PlayerState.show_player"},"info.PlayerState.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"info.multiplayerScoring":{"kind":-3,"retType":"boolean","parameters":[],"pyQName":"info.multiplayer_scoring"},"info.playersWithScores":{"kind":-3,"retType":"info.PlayerInfo[]","parameters":[],"pyQName":"info.players_with_scores"},"info.saveAllScores":{"kind":-3,"parameters":[{"name":"scoringType","type":"string"}],"pyQName":"info.save_all_scores"},"info.winningPlayer":{"kind":-3,"retType":"info.PlayerInfo","parameters":[],"pyQName":"info.winning_player"},"info.isBetterScore":{"kind":-3,"retType":"boolean","parameters":[{"name":"newScore"},{"name":"prevScore"}],"pyQName":"info.is_better_score"},"info.saveHighScore":{"kind":-3,"parameters":[],"pyQName":"info.save_high_score"},"info.score":{"kind":-3,"retType":"number","attributes":{"weight":95,"blockGap":"8","blockId":"hudScore","block":"score","help":"info/score","group":"Score","jsDoc":"Get the current score if any","_def":{"parts":[{"kind":"label","text":"score","style":[]}],"parameters":[]}},"parameters":[]},"info.hasScore":{"kind":-3,"retType":"boolean","attributes":{"group":"Score"},"parameters":[],"pyQName":"info.has_score"},"info.highScore":{"kind":-3,"retType":"number","attributes":{"weight":94,"blockId":"highScore","block":"high score","help":"info/high-score","group":"Score","jsDoc":"Get the last recorded high score","_def":{"parts":[{"kind":"label","text":"high score","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"info.high_score"},"info.setScore":{"kind":-3,"attributes":{"weight":93,"blockGap":"8","blockId":"hudsetScore","block":"set score to %value","help":"info/set-score","group":"Score","jsDoc":"Set the score","_def":{"parts":[{"kind":"label","text":"set score to ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value"}],"pyQName":"info.set_score"},"info.changeScoreBy":{"kind":-3,"attributes":{"paramDefl":{"value":"1"},"weight":92,"blockId":"hudChangeScoreBy","block":"change score by %value","help":"info/change-score-by","group":"Score","paramHelp":{"value":"the amount of change, eg: 1"},"jsDoc":"Change the score by the given amount","_def":{"parts":[{"kind":"label","text":"change score by ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","description":"the amount of change, eg: 1","default":"1"}],"pyQName":"info.change_score_by"},"info.life":{"kind":-3,"retType":"number","attributes":{"weight":85,"blockGap":"8","blockId":"hudLife","block":"life","help":"info/life","group":"Life","jsDoc":"Get the number of lives","_def":{"parts":[{"kind":"label","text":"life","style":[]}],"parameters":[]}},"parameters":[]},"info.hasLife":{"kind":-3,"retType":"boolean","attributes":{"group":"Life"},"parameters":[],"pyQName":"info.has_life"},"info.setLife":{"kind":-3,"attributes":{"paramDefl":{"value":"3"},"weight":84,"blockGap":"8","blockId":"hudSetLife","block":"set life to %value","help":"info/set-life","group":"Life","paramHelp":{"value":"the number of lives, eg: 3"},"jsDoc":"Set the number of lives","_def":{"parts":[{"kind":"label","text":"set life to ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","description":"the number of lives, eg: 3","default":"3"}],"pyQName":"info.set_life"},"info.changeLifeBy":{"kind":-3,"attributes":{"paramDefl":{"value":"-1"},"weight":83,"blockId":"hudChangeLifeBy","block":"change life by %value","help":"info/change-life-by","group":"Life","paramHelp":{"value":"the change of lives, eg: -1"},"jsDoc":"Change the lives by the given amount","_def":{"parts":[{"kind":"label","text":"change life by ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","description":"the change of lives, eg: -1","default":"-1"}],"pyQName":"info.change_life_by"},"info.onLifeZero":{"kind":-3,"attributes":{"weight":82,"blockId":"gamelifeevent","block":"on life zero","help":"info/on-life-zero","group":"Life","jsDoc":"Run code when the player's life reaches 0. If this function\nis not called then game.over() is called instead","_def":{"parts":[{"kind":"label","text":"on life zero","style":[]}],"parameters":[]}},"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"info.on_life_zero"},"info.onScore":{"kind":-3,"attributes":{"paramDefl":{"score":"100"},"weight":10,"blockId":"gameonscore","block":"on score $score","explicitDefaults":["score"],"help":"info/on-score","group":"Score","paramHelp":{"handler":"code to run when the score reaches the given value"},"jsDoc":"Runs code once each time the score reaches a given value. This will also\nrun if the score \"passes\" the given value in either direction without ever\nhaving the exact value (e.g. if score is changed by more than 1)\n* @param score the score to fire the event on","_def":{"parts":[{"kind":"label","text":"on score ","style":[]},{"kind":"param","name":"score","ref":true}],"parameters":[{"kind":"param","name":"score","ref":true}]}},"parameters":[{"name":"score","initializer":"100","default":"100"},{"name":"handler","description":"code to run when the score reaches the given value","type":"() => void","handlerParameters":[]}],"pyQName":"info.on_score"},"info.countdown":{"kind":-3,"retType":"number","attributes":{"block":"countdown","blockId":"gamegetcountdown","weight":79,"help":"info/countdown","group":"Countdown","jsDoc":"Get the value of the current count down","_def":{"parts":[{"kind":"label","text":"countdown","style":[]}],"parameters":[]}},"parameters":[]},"info.startCountdown":{"kind":-3,"attributes":{"paramDefl":{"duration":"10"},"blockId":"gamecountdown","block":"start countdown %duration (s)","help":"info/start-countdown","weight":78,"blockGap":"8","group":"Countdown","paramHelp":{"duration":"the duration of the countdown, eg: 10"},"jsDoc":"Start a countdown of the given duration in seconds","_def":{"parts":[{"kind":"label","text":"start countdown ","style":[]},{"kind":"param","name":"duration","ref":false},{"kind":"label","text":" (s)","style":[]}],"parameters":[{"kind":"param","name":"duration","ref":false}]}},"parameters":[{"name":"duration","description":"the duration of the countdown, eg: 10","default":"10"}],"pyQName":"info.start_countdown"},"info.changeCountdownBy":{"kind":-3,"attributes":{"block":"change countdown by $seconds (s)","blockId":"gamechangecountdown","weight":77,"help":"info/change-countdown-by","group":"Countdown","paramHelp":{"seconds":"the number of seconds the countdown should be changed by"},"jsDoc":"Change the running countdown by the given number of seconds","_def":{"parts":[{"kind":"label","text":"change countdown by ","style":[]},{"kind":"param","name":"seconds","ref":true},{"kind":"label","text":" (s)","style":[]}],"parameters":[{"kind":"param","name":"seconds","ref":true}]}},"parameters":[{"name":"seconds","description":"the number of seconds the countdown should be changed by"}],"pyQName":"info.change_countdown_by"},"info.stopCountdown":{"kind":-3,"attributes":{"blockId":"gamestopcountdown","block":"stop countdown","weight":76,"help":"info/stop-countdown","group":"Countdown","jsDoc":"Stop the current countdown and hides the timer display","_def":{"parts":[{"kind":"label","text":"stop countdown","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"info.stop_countdown"},"info.onCountdownEnd":{"kind":-3,"attributes":{"blockId":"gamecountdownevent","block":"on countdown end","weight":75,"help":"info/on-countdown-end","group":"Countdown","jsDoc":"Run code when the countdown reaches 0. If this function\nis not called then game.over() is called instead","_def":{"parts":[{"kind":"label","text":"on countdown end","style":[]}],"parameters":[]}},"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"info.on_countdown_end"},"info.setLifeImage":{"kind":-3,"attributes":{"group":"Life","jsDoc":"Replaces the image used to represent the player's lives. Images\nshould be no larger than 8x8"},"parameters":[{"name":"image","type":"Image"}],"pyQName":"info.set_life_image"},"info.showLife":{"kind":-3,"attributes":{"group":"Life","paramHelp":{"on":"if true, lives are shown; otherwise, lives are hidden"},"jsDoc":"Set whether life should be displayed"},"parameters":[{"name":"on","description":"if true, lives are shown; otherwise, lives are hidden","type":"boolean"}],"pyQName":"info.show_life"},"info.showScore":{"kind":-3,"attributes":{"group":"Score","paramHelp":{"on":"if true, score is shown; otherwise, score is hidden"},"jsDoc":"Set whether score should be displayed"},"parameters":[{"name":"on","description":"if true, score is shown; otherwise, score is hidden","type":"boolean"}],"pyQName":"info.show_score"},"info.showCountdown":{"kind":-3,"attributes":{"group":"Countdown","paramHelp":{"on":"if true, countdown is shown; otherwise, countdown is hidden"},"jsDoc":"Set whether countdown should be displayed"},"parameters":[{"name":"on","description":"if true, countdown is shown; otherwise, countdown is hidden","type":"boolean"}],"pyQName":"info.show_countdown"},"info.setBorderColor":{"kind":-3,"attributes":{"group":"Theme","paramHelp":{"color":"The index of the color (0-15)"},"jsDoc":"Sets the color of the borders around the score, countdown, and life\nelements. Defaults to 3"},"parameters":[{"name":"color","description":"The index of the color (0-15)"}],"pyQName":"info.set_border_color"},"info.setBackgroundColor":{"kind":-3,"attributes":{"group":"Theme","paramHelp":{"color":"The index of the color (0-15)"},"jsDoc":"Sets the color of the background of the score, countdown, and life\nelements. Defaults to 1"},"parameters":[{"name":"color","description":"The index of the color (0-15)"}],"pyQName":"info.set_background_color"},"info.setFontColor":{"kind":-3,"attributes":{"group":"Theme","paramHelp":{"color":"The index of the color (0-15)"},"jsDoc":"Sets the color of the text used in the score, countdown, and life\nelements. Defaults to 3"},"parameters":[{"name":"color","description":"The index of the color (0-15)"}],"pyQName":"info.set_font_color"},"info.borderColor":{"kind":-3,"retType":"number","attributes":{"group":"Theme","jsDoc":"Get the current color of the borders around the score, countdown, and life\nelements"},"parameters":[],"pyQName":"info.border_color"},"info.backgroundColor":{"kind":-3,"retType":"number","attributes":{"group":"Theme","jsDoc":"Get the current color of the background of the score, countdown, and life\nelements"},"parameters":[],"pyQName":"info.background_color"},"info.fontColor":{"kind":-3,"retType":"number","attributes":{"group":"Theme","jsDoc":"Get the current color of the text usded in the score, countdown, and life\nelements"},"parameters":[],"pyQName":"info.font_color"},"info.PlayerInfoImpl":{"kind":8,"retType":"info.PlayerInfoImpl","attributes":{"jsDoc":"Splits the implementation of the player info from the user-facing APIs so that\nwe can reference this internally without causing the \"multiplayer\" part to show\nup in the usedParts array of the user program's compile result. Make sure to\nuse the APIs on this class and not the PlayerInfo to avoid false-positives when\nwe detect if a game is multiplayer or not"},"extendsTypes":[]},"info.PlayerInfoImpl.bg":{"kind":2,"retType":"number","isInstance":true},"info.PlayerInfoImpl.border":{"kind":2,"retType":"number","isInstance":true},"info.PlayerInfoImpl.fc":{"kind":2,"retType":"number","isInstance":true},"info.PlayerInfoImpl.x":{"kind":2,"retType":"number","isInstance":true},"info.PlayerInfoImpl.y":{"kind":2,"retType":"number","isInstance":true},"info.PlayerInfoImpl.left":{"kind":2,"retType":"boolean","isInstance":true},"info.PlayerInfoImpl.up":{"kind":2,"retType":"boolean","isInstance":true},"info.PlayerInfoImpl.__constructor":{"kind":-3,"parameters":[{"name":"player"}],"isInstance":true},"info.PlayerInfoImpl.getState":{"kind":-1,"retType":"info.PlayerState","parameters":[],"isInstance":true,"pyQName":"info.PlayerInfoImpl.get_state"},"info.PlayerInfoImpl.id":{"kind":-1,"retType":"number","parameters":[],"isInstance":true},"info.PlayerInfoImpl.score":{"kind":-1,"retType":"number","parameters":[],"isInstance":true},"info.PlayerInfoImpl.setScore":{"kind":-1,"parameters":[{"name":"value"}],"isInstance":true,"pyQName":"info.PlayerInfoImpl.set_score"},"info.PlayerInfoImpl.changeScoreBy":{"kind":-1,"parameters":[{"name":"value"}],"isInstance":true,"pyQName":"info.PlayerInfoImpl.change_score_by"},"info.PlayerInfoImpl.hasScore":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"info.PlayerInfoImpl.has_score"},"info.PlayerInfoImpl.life":{"kind":-1,"retType":"number","parameters":[],"isInstance":true},"info.PlayerInfoImpl.setLife":{"kind":-1,"parameters":[{"name":"value"}],"isInstance":true,"pyQName":"info.PlayerInfoImpl.set_life"},"info.PlayerInfoImpl.changeLifeBy":{"kind":-1,"parameters":[{"name":"value"}],"isInstance":true,"pyQName":"info.PlayerInfoImpl.change_life_by"},"info.PlayerInfoImpl.hasLife":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"info.PlayerInfoImpl.has_life"},"info.PlayerInfoImpl.onLifeZero":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"info.PlayerInfoImpl.on_life_zero"},"info.PlayerInfoImpl.onScore":{"kind":-1,"parameters":[{"name":"score"},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"info.PlayerInfoImpl.on_score"},"info.PlayerInfoImpl.raiseLifeZero":{"kind":-1,"parameters":[{"name":"gameOver","type":"boolean"}],"isInstance":true,"pyQName":"info.PlayerInfoImpl.raise_life_zero"},"info.PlayerInfo":{"kind":8,"retType":"info.PlayerInfo","attributes":{"fixedInstances":"true","blockGap":"8"},"extendsTypes":[]},"info.PlayerInfo.impl":{"kind":2,"retType":"info.PlayerInfoImpl","isInstance":true},"info.PlayerInfo.__constructor":{"kind":-3,"parameters":[{"name":"player"}],"isInstance":true},"info.PlayerInfo.number":{"kind":-2,"retType":"number","attributes":{"jsDoc":"Returns the one-based number of the player"},"isInstance":true,"isReadOnly":true},"info.PlayerInfo.bg":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"info.PlayerInfo.bg@set":{"kind":-2,"retType":"number","isInstance":true},"info.PlayerInfo.border":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"info.PlayerInfo.border@set":{"kind":-2,"retType":"number","isInstance":true},"info.PlayerInfo.fc":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"info.PlayerInfo.fc@set":{"kind":-2,"retType":"number","isInstance":true},"info.PlayerInfo.showScore":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"info.PlayerInfo.show_score"},"info.PlayerInfo.showScore@set":{"kind":-2,"retType":"boolean","isInstance":true,"pyQName":"info.PlayerInfo.show_score@set"},"info.PlayerInfo.showLife":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"info.PlayerInfo.show_life"},"info.PlayerInfo.showLife@set":{"kind":-2,"retType":"boolean","isInstance":true,"pyQName":"info.PlayerInfo.show_life@set"},"info.PlayerInfo.visibility":{"kind":-2,"retType":"info.Visibility","isInstance":true,"isReadOnly":true},"info.PlayerInfo.visibility@set":{"kind":-2,"retType":"info.Visibility","isInstance":true},"info.PlayerInfo.showPlayer":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"info.PlayerInfo.show_player"},"info.PlayerInfo.showPlayer@set":{"kind":-2,"retType":"boolean","isInstance":true,"pyQName":"info.PlayerInfo.show_player@set"},"info.PlayerInfo.x":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"info.PlayerInfo.x@set":{"kind":-2,"retType":"number","isInstance":true},"info.PlayerInfo.y":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"info.PlayerInfo.y@set":{"kind":-2,"retType":"number","isInstance":true},"info.PlayerInfo.left":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true},"info.PlayerInfo.left@set":{"kind":-2,"retType":"boolean","isInstance":true},"info.PlayerInfo.up":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true},"info.PlayerInfo.up@set":{"kind":-2,"retType":"boolean","isInstance":true},"info.PlayerInfo.getState":{"kind":-1,"retType":"info.PlayerState","parameters":[],"isInstance":true,"pyQName":"info.PlayerInfo.get_state"},"info.PlayerInfo.id":{"kind":-1,"retType":"number","parameters":[],"isInstance":true},"info.PlayerInfo.score":{"kind":-1,"retType":"number","attributes":{"group":"Multiplayer","blockId":"piscore","block":"%player score","help":"info/score","parts":"multiplayer","jsDoc":"Get the player score","_def":{"parts":[{"kind":"param","name":"player","ref":false},{"kind":"label","text":" score","style":[]}],"parameters":[{"kind":"param","name":"player","ref":false}]}},"parameters":[],"isInstance":true},"info.PlayerInfo.setScore":{"kind":-1,"attributes":{"paramDefl":{"value":"0"},"group":"Multiplayer","blockId":"pisetscore","block":"set %player score to %value","explicitDefaults":["value"],"help":"info/set-score","parts":"multiplayer","jsDoc":"Set the player score","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"player","ref":false},{"kind":"label","text":" score to ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"player","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","initializer":"0","default":"0"}],"isInstance":true,"pyQName":"info.PlayerInfo.set_score"},"info.PlayerInfo.changeScoreBy":{"kind":-1,"attributes":{"paramDefl":{"value":"1"},"group":"Multiplayer","blockId":"pichangescore","block":"change %player score by %value","explicitDefaults":["value"],"help":"info/change-score-by","parts":"multiplayer","paramHelp":{"value":""},"jsDoc":"Change the score of a player","_def":{"parts":[{"kind":"label","text":"change ","style":[]},{"kind":"param","name":"player","ref":false},{"kind":"label","text":" score by ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"player","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","initializer":"1","default":"1"}],"isInstance":true,"pyQName":"info.PlayerInfo.change_score_by"},"info.PlayerInfo.hasScore":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"info.PlayerInfo.has_score"},"info.PlayerInfo.life":{"kind":-1,"retType":"number","attributes":{"group":"Multiplayer","blockid":"piflife","block":"%player life","help":"info/life","parts":"multiplayer","jsDoc":"Get the player life","_def":{"parts":[{"kind":"param","name":"player","ref":false},{"kind":"label","text":" life","style":[]}],"parameters":[{"kind":"param","name":"player","ref":false}]}},"parameters":[],"isInstance":true},"info.PlayerInfo.setLife":{"kind":-1,"attributes":{"paramDefl":{"value":"3"},"group":"Multiplayer","blockId":"pisetlife","block":"set %player life to %value","explicitDefaults":["value"],"help":"info/set-life","parts":"multiplayer","jsDoc":"Set the player life","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"player","ref":false},{"kind":"label","text":" life to ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"player","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","initializer":"3","default":"3"}],"isInstance":true,"pyQName":"info.PlayerInfo.set_life"},"info.PlayerInfo.changeLifeBy":{"kind":-1,"attributes":{"paramDefl":{"value":"-1"},"group":"Multiplayer","blockId":"pichangelife","block":"change %player life by %value","explicitDefaults":["value"],"help":"info/change-life-by","parts":"multiplayer","paramHelp":{"value":""},"jsDoc":"Change the life of a player","_def":{"parts":[{"kind":"label","text":"change ","style":[]},{"kind":"param","name":"player","ref":false},{"kind":"label","text":" life by ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"player","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","initializer":"-1","default":"-1"}],"isInstance":true,"pyQName":"info.PlayerInfo.change_life_by"},"info.PlayerInfo.hasLife":{"kind":-1,"retType":"boolean","attributes":{"group":"Multiplayer","blockId":"pihaslife","block":"%player has life","help":"info/has-life","parts":"multiplayer","paramHelp":{"player":"player to check life of"},"jsDoc":"Return true if the given player currently has a value set for health,\nand false otherwise.","_def":{"parts":[{"kind":"param","name":"player","ref":false},{"kind":"label","text":" has life","style":[]}],"parameters":[{"kind":"param","name":"player","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"info.PlayerInfo.has_life"},"info.PlayerInfo.onLifeZero":{"kind":-1,"attributes":{"group":"Multiplayer","blockId":"playerinfoonlifezero","block":"on %player life zero","help":"info/on-life-zero","parts":"multiplayer","paramHelp":{"handler":""},"jsDoc":"Runs code when life reaches zero","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"player","ref":false},{"kind":"label","text":" life zero","style":[]}],"parameters":[{"kind":"param","name":"player","ref":false}]}},"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"info.PlayerInfo.on_life_zero"},"info.PlayerInfo.onScore":{"kind":-1,"attributes":{"paramDefl":{"score":"100"},"blockId":"playerinfoonscore","block":"on $this score $score","explicitDefaults":["score"],"help":"info/on-score","group":"Multiplayer","parts":"multiplayer","paramHelp":{"handler":"code to run when the score reaches the given value"},"jsDoc":"Runs code once each time the score reaches a given value. This will also\nrun if the score \"passes\" the given value in either direction without ever\nhaving the exact value (e.g. if score is changed by more than 1)\n* @param score the score to fire the event on","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"this","ref":true},{"kind":"label","text":" score ","style":[]},{"kind":"param","name":"score","ref":true}],"parameters":[{"kind":"param","name":"this","ref":true},{"kind":"param","name":"score","ref":true}]}},"parameters":[{"name":"score","initializer":"100","default":"100"},{"name":"handler","description":"code to run when the score reaches the given value","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"info.PlayerInfo.on_score"},"info.PlayerInfo.drawPlayer":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"info.PlayerInfo.draw_player"},"info.PlayerInfo.drawScore":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"info.PlayerInfo.draw_score"},"info.PlayerInfo.drawLives":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"info.PlayerInfo.draw_lives"},"info.player2":{"kind":4,"retType":"info.PlayerInfo","attributes":{"fixedInstance":"true","whenUsed":"true","block":"player 2","_def":{"parts":[{"kind":"label","text":"player 2","style":[]}],"parameters":[]}}},"info.player3":{"kind":4,"retType":"info.PlayerInfo","attributes":{"fixedInstance":"true","whenUsed":"true","block":"player 3","_def":{"parts":[{"kind":"label","text":"player 3","style":[]}],"parameters":[]}}},"info.player4":{"kind":4,"retType":"info.PlayerInfo","attributes":{"fixedInstance":"true","whenUsed":"true","block":"player 4","_def":{"parts":[{"kind":"label","text":"player 4","style":[]}],"parameters":[]}}},"info.player1":{"kind":4,"retType":"info.PlayerInfo","attributes":{"fixedInstance":"true","whenUsed":"true","block":"player 1","_def":{"parts":[{"kind":"label","text":"player 1","style":[]}],"parameters":[]}}},"BackgroundAlignment":{"kind":6,"retType":"BackgroundAlignment","extendsTypes":["BackgroundAlignment","Number"]},"BackgroundAlignment.Left":{"retType":"BackgroundAlignment.Left","attributes":{"block":"left","_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"extendsTypes":["BackgroundAlignment.Left","Number"],"pyQName":"BackgroundAlignment.LEFT"},"BackgroundAlignment.Right":{"retType":"BackgroundAlignment.Right","attributes":{"block":"right","_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"extendsTypes":["BackgroundAlignment.Right","Number"],"pyQName":"BackgroundAlignment.RIGHT"},"BackgroundAlignment.Top":{"retType":"BackgroundAlignment.Top","attributes":{"block":"top","_def":{"parts":[{"kind":"label","text":"top","style":[]}],"parameters":[]}},"extendsTypes":["BackgroundAlignment.Top","Number"],"pyQName":"BackgroundAlignment.TOP"},"BackgroundAlignment.Bottom":{"retType":"BackgroundAlignment.Bottom","attributes":{"block":"bottom","_def":{"parts":[{"kind":"label","text":"bottom","style":[]}],"parameters":[]}},"extendsTypes":["BackgroundAlignment.Bottom","Number"],"pyQName":"BackgroundAlignment.BOTTOM"},"BackgroundAlignment.Center":{"retType":"BackgroundAlignment.Center","attributes":{"block":"center","_def":{"parts":[{"kind":"label","text":"center","style":[]}],"parameters":[]}},"extendsTypes":["BackgroundAlignment.Center","Number"],"pyQName":"BackgroundAlignment.CENTER"},"scene.Background":{"kind":8,"retType":"scene.Background","extendsTypes":[]},"scene.Background.color":{"kind":2,"retType":"number","isInstance":true},"scene.Background._image":{"kind":2,"retType":"Image","isInstance":true},"scene.Background.camera":{"kind":2,"retType":"scene.Camera","isInstance":true},"scene.Background.__constructor":{"kind":-3,"parameters":[{"name":"camera","type":"scene.Camera"}],"isInstance":true},"scene.Background.addLayer":{"kind":-1,"retType":"scene.BackgroundLayer","parameters":[{"name":"pic","type":"Image"},{"name":"distance"},{"name":"alignment","type":"BackgroundAlignment","isEnum":true}],"isInstance":true,"pyQName":"scene.Background.add_layer"},"scene.Background.image":{"kind":-2,"retType":"Image","isInstance":true,"isReadOnly":true},"scene.Background.image@set":{"kind":-2,"retType":"Image","isInstance":true},"scene.Background.hasBackgroundImage":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"scene.Background.has_background_image"},"scene.Background.draw":{"kind":-1,"parameters":[],"isInstance":true},"scene.BackgroundLayer":{"kind":8,"retType":"scene.BackgroundLayer","extendsTypes":[]},"scene.BackgroundLayer.distance":{"kind":2,"retType":"number","isInstance":true},"scene.BackgroundLayer.img":{"kind":2,"retType":"Image","isInstance":true},"scene.BackgroundLayer.repeatX":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"scene.BackgroundLayer.repeat_x"},"scene.BackgroundLayer.repeatY":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"scene.BackgroundLayer.repeat_y"},"scene.BackgroundLayer.alignX":{"kind":2,"retType":"BackgroundAlignment","isInstance":true,"pyQName":"scene.BackgroundLayer.align_x"},"scene.BackgroundLayer.alignY":{"kind":2,"retType":"BackgroundAlignment","isInstance":true,"pyQName":"scene.BackgroundLayer.align_y"},"scene.BackgroundLayer.__constructor":{"kind":-3,"parameters":[{"name":"distance"},{"name":"alignment","type":"BackgroundAlignment","isEnum":true},{"name":"img","type":"Image"}],"isInstance":true},"scene.BackgroundLayer.draw":{"kind":-1,"parameters":[{"name":"offsetX"},{"name":"offsetY"}],"isInstance":true},"TileScale":{"kind":6,"retType":"TileScale","extendsTypes":["TileScale","Number"]},"TileScale.Four":{"retType":"TileScale.Four","attributes":{"block":"4x4","_def":{"parts":[{"kind":"label","text":"4x4","style":[]}],"parameters":[]}},"extendsTypes":["TileScale.Four","Number"],"pyQName":"TileScale.FOUR"},"TileScale.Eight":{"retType":"TileScale.Eight","attributes":{"block":"8x8","_def":{"parts":[{"kind":"label","text":"8x8","style":[]}],"parameters":[]}},"extendsTypes":["TileScale.Eight","Number"],"pyQName":"TileScale.EIGHT"},"TileScale.Sixteen":{"retType":"TileScale.Sixteen","attributes":{"block":"16x16","_def":{"parts":[{"kind":"label","text":"16x16","style":[]}],"parameters":[]}},"extendsTypes":["TileScale.Sixteen","Number"],"pyQName":"TileScale.SIXTEEN"},"TileScale.ThirtyTwo":{"retType":"TileScale.ThirtyTwo","attributes":{"block":"32x32","_def":{"parts":[{"kind":"label","text":"32x32","style":[]}],"parameters":[]}},"extendsTypes":["TileScale.ThirtyTwo","Number"],"pyQName":"TileScale.THIRTY_TWO"},"tiles":{"kind":5,"retType":""},"tiles.Location":{"kind":8,"retType":"tiles.Location","attributes":{"blockNamespace":"scene","color":"#401255","jsDoc":"A (col, row) location in the tilemap"},"extendsTypes":[]},"tiles.Location.__constructor":{"kind":-3,"parameters":[{"name":"col"},{"name":"row"},{"name":"map","type":"tiles.TileMap"}],"isInstance":true},"tiles.Location.tileMap":{"kind":-2,"retType":"tiles.TileMap","isInstance":true,"isReadOnly":true,"pyQName":"tiles.Location.tile_map"},"tiles.Location.column":{"kind":-2,"retType":"number","attributes":{"group":"Locations","blockSetVariable":"location","blockCombine":true,"block":"column","weight":100,"_def":{"parts":[{"kind":"label","text":"column","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"tiles.Location.row":{"kind":-2,"retType":"number","attributes":{"group":"Locations","blockSetVariable":"location","blockCombine":true,"block":"row","weight":100,"_def":{"parts":[{"kind":"label","text":"row","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"tiles.Location.x":{"kind":-2,"retType":"number","attributes":{"group":"Locations","blockSetVariable":"location","blockCombine":true,"block":"x","weight":100,"_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"tiles.Location.y":{"kind":-2,"retType":"number","attributes":{"group":"Locations","blockSetVariable":"location","blockCombine":true,"block":"y","weight":100,"_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"tiles.Location.left":{"kind":-2,"retType":"number","attributes":{"group":"Locations","blockSetVariable":"location","blockCombine":true,"block":"left","weight":100,"_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"tiles.Location.top":{"kind":-2,"retType":"number","attributes":{"group":"Locations","blockSetVariable":"location","blockCombine":true,"block":"top","weight":100,"_def":{"parts":[{"kind":"label","text":"top","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"tiles.Location.right":{"kind":-2,"retType":"number","attributes":{"group":"Locations","blockSetVariable":"location","blockCombine":true,"block":"right","weight":100,"_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"tiles.Location.bottom":{"kind":-2,"retType":"number","attributes":{"group":"Locations","blockSetVariable":"location","blockCombine":true,"block":"bottom","weight":100,"_def":{"parts":[{"kind":"label","text":"bottom","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"tiles.Location.tileSet":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"tiles.Location.tile_set"},"tiles.Location.col":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"tiles.Location.isWall":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"tiles.Location.is_wall"},"tiles.Location.getImage":{"kind":-1,"retType":"Image","parameters":[],"isInstance":true,"pyQName":"tiles.Location.get_image"},"tiles.Location.getNeighboringLocation":{"kind":-1,"retType":"tiles.Location","attributes":{"paramDefl":{"this":"location"},"blockId":"tiles_location_get_neighboring_location","block":"tilemap location $direction of $this","explicitDefaults":["this"],"_shadowOverrides":{"this":"variables_get"},"group":"Locations","blockGap":"8","weight":10,"help":"tiles/get-neighboring-location","paramHelp":{"direction":"The direction to fetch the location in"},"jsDoc":"Returns the neighboring location in a specifc direction from a location in a tilemap","_def":{"parts":[{"kind":"label","text":"tilemap location ","style":[]},{"kind":"param","name":"direction","ref":true},{"kind":"label","text":" of ","style":[]},{"kind":"param","name":"this","shadowBlockId":"variables_get","ref":true}],"parameters":[{"kind":"param","name":"direction","ref":true},{"kind":"param","name":"this","shadowBlockId":"variables_get","ref":true}]}},"parameters":[{"name":"direction","description":"The direction to fetch the location in","type":"CollisionDirection","isEnum":true}],"isInstance":true,"pyQName":"tiles.Location.get_neighboring_location"},"tiles.Location.place":{"kind":-1,"attributes":{"paramHelp":{"sprite":""},"jsDoc":"Center the given sprite on this tile"},"parameters":[{"name":"mySprite","type":"Sprite"}],"isInstance":true},"tiles.Location._toTile":{"kind":-1,"retType":"tiles.Tile","parameters":[],"isInstance":true,"pyQName":"tiles.Location._to_tile"},"tiles.Tile":{"kind":8,"retType":"tiles.Tile","attributes":{"blockNamespace":"scene","color":"#401255","blockGap":"8","jsDoc":"DEPRECATED: a tile in the tilemap"},"extendsTypes":[]},"tiles.Tile.__constructor":{"kind":-3,"parameters":[{"name":"col"},{"name":"row"},{"name":"map","type":"tiles.TileMap"}],"isInstance":true},"tiles.Tile.x":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"tiles.Tile.y":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"tiles.Tile.tileSet":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"tiles.Tile.tile_set"},"tiles.Tile.place":{"kind":-1,"attributes":{"blockId":"gameplaceontile","block":"on top of %tile(myTile) place %sprite=variables_get(mySprite)","blockNamespace":"scene","group":"Tilemap Operations","weight":25,"help":"tiles/place","deprecated":"1","paramHelp":{"sprite":""},"jsDoc":"Center the given sprite on this tile","_def":{"parts":[{"kind":"label","text":"on top of ","style":[]},{"kind":"param","name":"tile","ref":false,"varName":"myTile"},{"kind":"label","text":" place ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"}],"parameters":[{"kind":"param","name":"tile","ref":false,"varName":"myTile"},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"}]}},"parameters":[{"name":"mySprite","type":"Sprite"}],"isInstance":true},"tiles.TileMapData":{"kind":8,"retType":"tiles.TileMapData","attributes":{"snippet":"tilemap` `","pySnippet":"tilemap(\"\"\" \"\"\")"},"extendsTypes":[]},"tiles.TileMapData.__constructor":{"kind":-3,"parameters":[{"name":"data","type":"Buffer"},{"name":"layers","type":"Image"},{"name":"tileset","type":"Image[]"},{"name":"scale","type":"TileScale","isEnum":true}],"isInstance":true},"tiles.TileMapData.width":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"tiles.TileMapData.height":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"tiles.TileMapData.scale":{"kind":-2,"retType":"TileScale","isInstance":true,"isReadOnly":true},"tiles.TileMapData.scale@set":{"kind":-2,"retType":"TileScale","isInstance":true},"tiles.TileMapData.getTile":{"kind":-1,"retType":"number","parameters":[{"name":"col"},{"name":"row"}],"isInstance":true,"pyQName":"tiles.TileMapData.get_tile"},"tiles.TileMapData.setTile":{"kind":-1,"parameters":[{"name":"col"},{"name":"row"},{"name":"tile"}],"isInstance":true,"pyQName":"tiles.TileMapData.set_tile"},"tiles.TileMapData.getTileset":{"kind":-1,"retType":"Image[]","parameters":[],"isInstance":true,"pyQName":"tiles.TileMapData.get_tileset"},"tiles.TileMapData.getTileImage":{"kind":-1,"retType":"Image","parameters":[{"name":"index"}],"isInstance":true,"pyQName":"tiles.TileMapData.get_tile_image"},"tiles.TileMapData.setWall":{"kind":-1,"parameters":[{"name":"col"},{"name":"row"},{"name":"on","type":"boolean"}],"isInstance":true,"pyQName":"tiles.TileMapData.set_wall"},"tiles.TileMapData.isWall":{"kind":-1,"retType":"boolean","parameters":[{"name":"col"},{"name":"row"}],"isInstance":true,"pyQName":"tiles.TileMapData.is_wall"},"tiles.TileMapData.isOutsideMap":{"kind":-1,"retType":"boolean","parameters":[{"name":"col"},{"name":"row"}],"isInstance":true,"pyQName":"tiles.TileMapData.is_outside_map"},"tiles.TileMapEvent":{"kind":6,"retType":"tiles.TileMapEvent","extendsTypes":["tiles.TileMapEvent","Number"]},"tiles.TileMapEvent.Loaded":{"retType":"tiles.TileMapEvent.Loaded","extendsTypes":["tiles.TileMapEvent.Loaded","Number"],"pyQName":"tiles.TileMapEvent.LOADED"},"tiles.TileMapEvent.Unloaded":{"retType":"tiles.TileMapEvent.Unloaded","extendsTypes":["tiles.TileMapEvent.Unloaded","Number"],"pyQName":"tiles.TileMapEvent.UNLOADED"},"tiles.TileMapEventHandler":{"kind":8,"retType":"tiles.TileMapEventHandler","extendsTypes":[]},"tiles.TileMapEventHandler.__constructor":{"kind":-3,"parameters":[{"name":"event","type":"tiles.TileMapEvent","isEnum":true},{"name":"callback","type":"(data: tiles.TileMapData) => void","handlerParameters":[{"name":"data","type":"tiles.TileMapData"}]}],"isInstance":true},"tiles.TileMap":{"kind":8,"retType":"tiles.TileMap","extendsTypes":[]},"tiles.TileMap.renderable":{"kind":2,"retType":"scene.Renderable","isInstance":true},"tiles.TileMap.__constructor":{"kind":-3,"parameters":[{"name":"scale","type":"TileScale","initializer":"TileScale.Sixteen","isEnum":true}],"isInstance":true},"tiles.TileMap.scale":{"kind":-2,"retType":"TileScale","isInstance":true,"isReadOnly":true},"tiles.TileMap.scale@set":{"kind":-2,"retType":"TileScale","isInstance":true},"tiles.TileMap.data":{"kind":-2,"retType":"tiles.TileMapData","isInstance":true,"isReadOnly":true},"tiles.TileMap.offsetX":{"kind":-1,"retType":"number","parameters":[{"name":"value"}],"isInstance":true,"pyQName":"tiles.TileMap.offset_x"},"tiles.TileMap.offsetY":{"kind":-1,"retType":"number","parameters":[{"name":"value"}],"isInstance":true,"pyQName":"tiles.TileMap.offset_y"},"tiles.TileMap.areaWidth":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"tiles.TileMap.area_width"},"tiles.TileMap.areaHeight":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"tiles.TileMap.area_height"},"tiles.TileMap.layer":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"tiles.TileMap.layer@set":{"kind":-2,"retType":"number","isInstance":true},"tiles.TileMap.enabled":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true},"tiles.TileMap.setData":{"kind":-1,"parameters":[{"name":"map","type":"tiles.TileMapData"}],"isInstance":true,"pyQName":"tiles.TileMap.set_data"},"tiles.TileMap.getTile":{"kind":-1,"retType":"tiles.Location","parameters":[{"name":"col"},{"name":"row"}],"isInstance":true,"pyQName":"tiles.TileMap.get_tile"},"tiles.TileMap.getTileIndex":{"kind":-1,"retType":"number","parameters":[{"name":"col"},{"name":"row"}],"isInstance":true,"pyQName":"tiles.TileMap.get_tile_index"},"tiles.TileMap.setTileAt":{"kind":-1,"parameters":[{"name":"col"},{"name":"row"},{"name":"index"}],"isInstance":true,"pyQName":"tiles.TileMap.set_tile_at"},"tiles.TileMap.getImageType":{"kind":-1,"retType":"number","parameters":[{"name":"im","type":"Image"}],"isInstance":true,"pyQName":"tiles.TileMap.get_image_type"},"tiles.TileMap.setWallAt":{"kind":-1,"parameters":[{"name":"col"},{"name":"row"},{"name":"on","type":"boolean"}],"isInstance":true,"pyQName":"tiles.TileMap.set_wall_at"},"tiles.TileMap.getTilesByType":{"kind":-1,"retType":"tiles.Location[]","parameters":[{"name":"index"}],"isInstance":true,"pyQName":"tiles.TileMap.get_tiles_by_type"},"tiles.TileMap.sampleTilesByType":{"kind":-1,"retType":"tiles.Location[]","parameters":[{"name":"index"},{"name":"maxCount"}],"isInstance":true,"pyQName":"tiles.TileMap.sample_tiles_by_type"},"tiles.TileMap.isObstacle":{"kind":-1,"retType":"boolean","parameters":[{"name":"col"},{"name":"row"}],"isInstance":true,"pyQName":"tiles.TileMap.is_obstacle"},"tiles.TileMap.getObstacle":{"kind":-1,"retType":"sprites.StaticObstacle","parameters":[{"name":"col"},{"name":"row"}],"isInstance":true,"pyQName":"tiles.TileMap.get_obstacle"},"tiles.TileMap.isOnWall":{"kind":-1,"retType":"boolean","parameters":[{"name":"s","type":"Sprite"}],"isInstance":true,"pyQName":"tiles.TileMap.is_on_wall"},"tiles.TileMap.getTileImage":{"kind":-1,"retType":"Image","parameters":[{"name":"index"}],"isInstance":true,"pyQName":"tiles.TileMap.get_tile_image"},"tiles.TileMap.addEventListener":{"kind":-1,"parameters":[{"name":"event","type":"tiles.TileMapEvent","isEnum":true},{"name":"handler","type":"(data: tiles.TileMapData) => void","handlerParameters":[{"name":"data","type":"tiles.TileMapData"}]}],"isInstance":true,"pyQName":"tiles.TileMap.add_event_listener"},"tiles.TileMap.removeEventListener":{"kind":-1,"parameters":[{"name":"event","type":"tiles.TileMapEvent","isEnum":true},{"name":"handler","type":"(data: tiles.TileMapData) => void","handlerParameters":[{"name":"data","type":"tiles.TileMapData"}]}],"isInstance":true,"pyQName":"tiles.TileMap.remove_event_listener"},"tiles.createTilemap":{"kind":-3,"retType":"tiles.TileMapData","attributes":{"paramDefl":{"scale":"TileScale.Sixteen"},"explicitDefaults":["scale"]},"parameters":[{"name":"data","type":"Buffer"},{"name":"layer","type":"Image"},{"name":"tiles","type":"Image[]"},{"name":"scale","type":"TileScale","initializer":"TileScale.Sixteen","default":"TileScale.Sixteen","isEnum":true}],"pyQName":"tiles.create_tilemap"},"tiles.setTilemap":{"kind":-3,"attributes":{"blockId":"tilemap_editor","block":"set tilemap to $tilemap","weight":200,"blockGap":"8","paramFieldEditor":{"tilemap":"tilemap"},"paramFieldEditorOptions":{"tilemap":{"decompileArgumentAsString":"true","filter":"tile","taggedTemplate":"tilemap"}},"blockNamespace":"scene","duplicateShadowOnDrag":true,"help":"tiles/set-tilemap","deprecated":"1","_def":{"parts":[{"kind":"label","text":"set tilemap to ","style":[]},{"kind":"param","name":"tilemap","ref":true}],"parameters":[{"kind":"param","name":"tilemap","ref":true}]}},"parameters":[{"name":"tilemap","type":"tiles.TileMapData"}],"pyQName":"tiles.set_tilemap"},"tiles.setCurrentTilemap":{"kind":-3,"attributes":{"blockId":"set_current_tilemap","block":"set tilemap to $tilemap","weight":201,"blockGap":"8","_shadowOverrides":{"tilemap":"tiles_tilemap_editor"},"blockNamespace":"scene","group":"Tilemaps","duplicateShadowOnDrag":true,"help":"tiles/set-current-tilemap","jsDoc":"Sets the given tilemap to be the current active tilemap in the game\n* @param tilemap The tilemap to set as the current tilemap","_def":{"parts":[{"kind":"label","text":"set tilemap to ","style":[]},{"kind":"param","name":"tilemap","shadowBlockId":"tiles_tilemap_editor","ref":true}],"parameters":[{"kind":"param","name":"tilemap","shadowBlockId":"tiles_tilemap_editor","ref":true}]}},"parameters":[{"name":"tilemap","type":"tiles.TileMapData"}],"pyQName":"tiles.set_current_tilemap"},"tiles.setTileAt":{"kind":-3,"attributes":{"blockId":"mapsettileat","block":"set $tile at $loc=mapgettile","_shadowOverrides":{"tile":"tileset_tile_picker"},"tile.decompileIndirectFixedInstances":"true","blockNamespace":"scene","group":"Tilemap Operations","blockGap":"8","help":"tiles/set-tile-at","weight":70,"paramHelp":{"loc":"@param tile"},"jsDoc":"Set a location in the map (column, row) to a tile","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"tile","shadowBlockId":"tileset_tile_picker","ref":true},{"kind":"label","text":" at ","style":[]},{"kind":"param","name":"loc","shadowBlockId":"mapgettile","ref":true}],"parameters":[{"kind":"param","name":"tile","shadowBlockId":"tileset_tile_picker","ref":true},{"kind":"param","name":"loc","shadowBlockId":"mapgettile","ref":true}]}},"parameters":[{"name":"loc","description":"@param tile","type":"tiles.Location"},{"name":"tile","type":"Image"}],"pyQName":"tiles.set_tile_at"},"tiles.setWallAt":{"kind":-3,"attributes":{"blockId":"mapsetwallat","block":"set wall $on at $loc","_shadowOverrides":{"on":"toggleOnOff","loc":"mapgettile"},"blockNamespace":"scene","group":"Tilemap Operations","help":"tiles/set-wall-at","weight":60,"paramHelp":{"loc":"@param on"},"jsDoc":"Set or unset a wall at a location in the map (column, row)","_def":{"parts":[{"kind":"label","text":"set wall ","style":[]},{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":true},{"kind":"label","text":" at ","style":[]},{"kind":"param","name":"loc","shadowBlockId":"mapgettile","ref":true}],"parameters":[{"kind":"param","name":"on","shadowBlockId":"toggleOnOff","ref":true},{"kind":"param","name":"loc","shadowBlockId":"mapgettile","ref":true}]}},"parameters":[{"name":"loc","description":"@param on","type":"tiles.Location"},{"name":"on","type":"boolean"}],"pyQName":"tiles.set_wall_at"},"tiles.getTileLocation":{"kind":-3,"retType":"tiles.Location","attributes":{"blockId":"mapgettile","block":"tilemap col $col row $row","blockNamespace":"scene","group":"Locations","weight":100,"blockGap":"8","help":"tiles/get-tile-location","paramHelp":{"col":"@param row"},"jsDoc":"Get the tile position given a column and row in the tilemap","_def":{"parts":[{"kind":"label","text":"tilemap col ","style":[]},{"kind":"param","name":"col","ref":true},{"kind":"label","text":" row ","style":[]},{"kind":"param","name":"row","ref":true}],"parameters":[{"kind":"param","name":"col","ref":true},{"kind":"param","name":"row","ref":true}]}},"parameters":[{"name":"col","description":"@param row"},{"name":"row"}],"pyQName":"tiles.get_tile_location"},"tiles.getTileImage":{"kind":-3,"retType":"Image","attributes":{"paramHelp":{"loc":""},"jsDoc":"Get the image of a tile, given a location in the tilemap"},"parameters":[{"name":"loc","type":"tiles.Location"}],"pyQName":"tiles.get_tile_image"},"tiles.getTileAt":{"kind":-3,"retType":"Image","attributes":{"paramHelp":{"loc":""},"jsDoc":"Get the image of a tile, given a (column, row) in the tilemap"},"parameters":[{"name":"col"},{"name":"row"}],"pyQName":"tiles.get_tile_at"},"tiles.tileAtLocationEquals":{"kind":-3,"retType":"boolean","attributes":{"blockId":"maplocationistile","block":"tile at $location is $tile","_shadowOverrides":{"location":"mapgettile","tile":"tileset_tile_picker"},"tile.decompileIndirectFixedInstances":"true","blockNamespace":"scene","group":"Locations","blockGap":"8","weight":40,"help":"tiles/tile-at-location-equals","paramHelp":{"location":"@param tile"},"jsDoc":"Returns true if the tile at the given location is the same as the given tile;\notherwise returns false","_def":{"parts":[{"kind":"label","text":"tile at ","style":[]},{"kind":"param","name":"location","shadowBlockId":"mapgettile","ref":true},{"kind":"label","text":" is ","style":[]},{"kind":"param","name":"tile","shadowBlockId":"tileset_tile_picker","ref":true}],"parameters":[{"kind":"param","name":"location","shadowBlockId":"mapgettile","ref":true},{"kind":"param","name":"tile","shadowBlockId":"tileset_tile_picker","ref":true}]}},"parameters":[{"name":"location","description":"@param tile","type":"tiles.Location"},{"name":"tile","type":"Image"}],"pyQName":"tiles.tile_at_location_equals"},"tiles.tileAtLocationIsWall":{"kind":-3,"retType":"boolean","attributes":{"blockId":"tiles_tile_at_location_is_wall","block":"tile at $location is wall","_shadowOverrides":{"location":"mapgettile"},"blockNamespace":"scene","group":"Locations","blockGap":"8","weight":30,"help":"tiles/tile-at-location-is-wall","paramHelp":{"location":"The location to check for a wall"},"jsDoc":"Returns true if the tile at the given location is a wall in the current tilemap;\notherwise returns false","_def":{"parts":[{"kind":"label","text":"tile at ","style":[]},{"kind":"param","name":"location","shadowBlockId":"mapgettile","ref":true},{"kind":"label","text":" is wall","style":[]}],"parameters":[{"kind":"param","name":"location","shadowBlockId":"mapgettile","ref":true}]}},"parameters":[{"name":"location","description":"The location to check for a wall","type":"tiles.Location"}],"pyQName":"tiles.tile_at_location_is_wall"},"tiles.tileImageAtLocation":{"kind":-3,"retType":"Image","attributes":{"blockId":"tiles_image_at_location","block":"tile image at $location","_shadowOverrides":{"location":"mapgettile"},"weight":0,"help":"tiles/tile-image-at-location","blockNamespace":"scene","group":"Locations","jsDoc":"Returns the image of the tile at the given location in the current tilemap\n* @param location The location of the image to fetch","_def":{"parts":[{"kind":"label","text":"tile image at ","style":[]},{"kind":"param","name":"location","shadowBlockId":"mapgettile","ref":true}],"parameters":[{"kind":"param","name":"location","shadowBlockId":"mapgettile","ref":true}]}},"parameters":[{"name":"location","type":"tiles.Location"}],"pyQName":"tiles.tile_image_at_location"},"tiles.placeOnTile":{"kind":-3,"attributes":{"blockId":"mapplaceontile","block":"place $sprite=variables_get(mySprite) on top of $loc","_shadowOverrides":{"loc":"mapgettile"},"blockNamespace":"scene","group":"Tilemap Operations","blockGap":"8","help":"tiles/place-on-tile","weight":100,"paramHelp":{"sprite":"@param loc"},"jsDoc":"Center the given sprite on a given location","_def":{"parts":[{"kind":"label","text":"place ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"label","text":" on top of ","style":[]},{"kind":"param","name":"loc","shadowBlockId":"mapgettile","ref":true}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"param","name":"loc","shadowBlockId":"mapgettile","ref":true}]}},"parameters":[{"name":"sprite","description":"@param loc","type":"Sprite"},{"name":"loc","type":"tiles.Location"}],"pyQName":"tiles.place_on_tile"},"tiles.placeOnRandomTile":{"kind":-3,"attributes":{"blockId":"mapplaceonrandomtile","block":"place $sprite=variables_get(mySprite) on top of random $tile","_shadowOverrides":{"tile":"tileset_tile_picker"},"tile.decompileIndirectFixedInstances":"true","blockNamespace":"scene","group":"Tilemap Operations","help":"tiles/place-on-random-tile","weight":90,"paramHelp":{"sprite":"@param tile"},"jsDoc":"Center the given sprite on a random location that is the given type (image)","_def":{"parts":[{"kind":"label","text":"place ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"label","text":" on top of random ","style":[]},{"kind":"param","name":"tile","shadowBlockId":"tileset_tile_picker","ref":true}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"param","name":"tile","shadowBlockId":"tileset_tile_picker","ref":true}]}},"parameters":[{"name":"sprite","description":"@param tile","type":"Sprite"},{"name":"tile","type":"Image"}],"pyQName":"tiles.place_on_random_tile"},"tiles.getTilesByType":{"kind":-3,"retType":"tiles.Location[]","attributes":{"blockId":"mapgettilestype","block":"array of all $tile locations","_shadowOverrides":{"tile":"tileset_tile_picker"},"tile.decompileIndirectFixedInstances":"true","blockNamespace":"scene","group":"Locations","blockGap":"8","help":"tiles/get-tiles-by-type","weight":10,"paramHelp":{"tile":""},"jsDoc":"Get all tiles in the tilemap with the given type (image).","_def":{"parts":[{"kind":"label","text":"array of all ","style":[]},{"kind":"param","name":"tile","shadowBlockId":"tileset_tile_picker","ref":true},{"kind":"label","text":" locations","style":[]}],"parameters":[{"kind":"param","name":"tile","shadowBlockId":"tileset_tile_picker","ref":true}]}},"parameters":[{"name":"tile","type":"Image"}],"pyQName":"tiles.get_tiles_by_type"},"tiles.getRandomTileByType":{"kind":-3,"retType":"tiles.Location","attributes":{"paramHelp":{"tile":"the type of tile to get a random selection of"},"jsDoc":"Get a random tile of the given type"},"parameters":[{"name":"tile","description":"the type of tile to get a random selection of","type":"Image"}],"pyQName":"tiles.get_random_tile_by_type"},"tiles._tilemapEditor":{"kind":-3,"retType":"tiles.TileMapData","attributes":{"blockId":"tiles_tilemap_editor","shim":"TD_ID","weight":200,"blockGap":"8","block":"tilemap $tilemap","paramFieldEditor":{"tilemap":"tilemap"},"paramFieldEditorOptions":{"tilemap":{"decompileArgumentAsString":"true","filter":"tile","taggedTemplate":"tilemap"}},"blockNamespace":"scene","group":"Tilemaps","duplicateShadowOnDrag":true,"help":"tiles/tilemap","jsDoc":"A tilemap","_def":{"parts":[{"kind":"label","text":"tilemap ","style":[]},{"kind":"param","name":"tilemap","ref":true}],"parameters":[{"kind":"param","name":"tilemap","ref":true}]}},"parameters":[{"name":"tilemap","type":"tiles.TileMapData"}],"pyQName":"tiles._tilemap_editor"},"tiles.addEventListener":{"kind":-3,"attributes":{"paramHelp":{"handler":"The code to run when the event triggers"},"jsDoc":"Adds an event handler that will fire whenever the specified event\nis triggered. Unloaded tilemap events will fire before the new tilemap\nis set and loaded events will fire afterwards. The same handler can\nnot be added for the same event more than once.\n* @param event     The event to subscribe to"},"parameters":[{"name":"event","type":"tiles.TileMapEvent","isEnum":true},{"name":"callback","type":"(data: tiles.TileMapData) => void","handlerParameters":[{"name":"data","type":"tiles.TileMapData"}]}],"pyQName":"tiles.add_event_listener"},"tiles.removeEventListener":{"kind":-3,"attributes":{"paramHelp":{"handler":"The handler to remove"},"jsDoc":"Removes an event handler registered with addEventListener.\n* @param event     The event that the handler was registered for"},"parameters":[{"name":"event","type":"tiles.TileMapEvent","isEnum":true},{"name":"callback","type":"(data: tiles.TileMapData) => void","handlerParameters":[{"name":"data","type":"tiles.TileMapData"}]}],"pyQName":"tiles.remove_event_listener"},"scene.Camera":{"kind":8,"retType":"scene.Camera","extendsTypes":[]},"scene.Camera.drawOffsetX":{"kind":2,"retType":"number","isInstance":true,"pyQName":"scene.Camera.draw_offset_x"},"scene.Camera.drawOffsetY":{"kind":2,"retType":"number","isInstance":true,"pyQName":"scene.Camera.draw_offset_y"},"scene.Camera.sprite":{"kind":2,"retType":"Sprite","isInstance":true},"scene.Camera.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"scene.Camera.offsetX":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"scene.Camera.offset_x"},"scene.Camera.offsetX@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"scene.Camera.offset_x@set"},"scene.Camera.offsetY":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"scene.Camera.offset_y"},"scene.Camera.offsetY@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"scene.Camera.offset_y@set"},"scene.Camera.x":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"scene.Camera.y":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"scene.Camera.left":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"scene.Camera.right":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"scene.Camera.top":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"scene.Camera.bottom":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"scene.Camera.shake":{"kind":-1,"parameters":[{"name":"amplitude","initializer":"4"},{"name":"duration","initializer":"1000"}],"isInstance":true},"scene.Camera.isUpdated":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"scene.Camera.is_updated"},"scene.Camera.update":{"kind":-1,"parameters":[],"isInstance":true},"scene.Renderable":{"kind":8,"retType":"scene.Renderable","extendsTypes":["scene.Renderable","sprites.BaseSprite","SpriteLike"]},"scene.Renderable.__constructor":{"kind":-3,"parameters":[{"name":"handler","type":"(target: Image, camera: scene.Camera) => void","handlerParameters":[{"name":"target","type":"Image"},{"name":"camera","type":"scene.Camera"}]},{"name":"shouldBeVisible","type":"() => boolean","handlerParameters":[]},{"name":"z"}],"isInstance":true},"scene.Renderable.__visible":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true},"scene.Renderable.__drawCore":{"kind":-1,"parameters":[{"name":"camera","type":"scene.Camera"}],"isInstance":true},"scene.Renderable.destroy":{"kind":-1,"parameters":[],"isInstance":true},"scene.createRenderable":{"kind":-3,"retType":"scene.Renderable","parameters":[{"name":"z"},{"name":"handler","type":"(target: Image, camera: scene.Camera) => void","handlerParameters":[{"name":"target","type":"Image"},{"name":"camera","type":"scene.Camera"}]},{"name":"shouldBeVisible","type":"() => boolean","initializer":"undefined","handlerParameters":[]}],"pyQName":"scene.create_renderable"},"SparseArray":{"kind":9,"retType":"SparseArray<T>","extendsTypes":[]},"scene.Flag":{"kind":6,"retType":"scene.Flag","extendsTypes":["scene.Flag","Number"]},"scene.Flag.NeedsSorting":{"retType":"scene.Flag","extendsTypes":["scene.Flag.NeedsSorting","Number"],"pyQName":"scene.Flag.NEEDS_SORTING"},"scene.Flag.SeeThrough":{"retType":"scene.Flag","extendsTypes":["scene.Flag.SeeThrough","Number"],"pyQName":"scene.Flag.SEE_THROUGH"},"scene.Flag.IsRendering":{"retType":"scene.Flag","extendsTypes":["scene.Flag.IsRendering","Number"],"pyQName":"scene.Flag.IS_RENDERING"},"scene.SpriteHandler":{"kind":8,"retType":"scene.SpriteHandler","extendsTypes":[]},"scene.SpriteHandler.__constructor":{"kind":-3,"parameters":[{"name":"kind"},{"name":"handler","type":"(sprite: Sprite) => void","handlerParameters":[{"name":"sprite","type":"Sprite"}]}],"isInstance":true},"scene.OverlapHandler":{"kind":8,"retType":"scene.OverlapHandler","extendsTypes":[]},"scene.OverlapHandler.__constructor":{"kind":-3,"parameters":[{"name":"kind"},{"name":"otherKind"},{"name":"handler","type":"(sprite: Sprite, otherSprite: Sprite) => void","handlerParameters":[{"name":"sprite","type":"Sprite"},{"name":"otherSprite","type":"Sprite"}]}],"isInstance":true},"scene.TileWallHandler":{"kind":8,"retType":"scene.TileWallHandler","extendsTypes":[]},"scene.TileWallHandler.__constructor":{"kind":-3,"parameters":[{"name":"spriteKind"},{"name":"handler","type":"(sprite: Sprite, location: tiles.Location) => void","handlerParameters":[{"name":"sprite","type":"Sprite"},{"name":"location","type":"tiles.Location"}]}],"isInstance":true},"scene.TileOverlapHandler":{"kind":8,"retType":"scene.TileOverlapHandler","extendsTypes":[]},"scene.TileOverlapHandler.__constructor":{"kind":-3,"parameters":[{"name":"spriteKind"},{"name":"tileKind","type":"Image"},{"name":"handler","type":"(sprite: Sprite, location: tiles.Location) => void","handlerParameters":[{"name":"sprite","type":"Sprite"},{"name":"location","type":"tiles.Location"}]}],"isInstance":true},"scene.GameForeverHandler":{"kind":8,"retType":"scene.GameForeverHandler","extendsTypes":[]},"scene.GameForeverHandler.lock":{"kind":2,"retType":"boolean","isInstance":true},"scene.GameForeverHandler.__constructor":{"kind":-3,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true},"scene.CONTROLLER_PRIORITY":{"kind":4,"retType":"number"},"scene.UPDATE_CONTROLLER_PRIORITY":{"kind":4,"retType":"number"},"scene.FOLLOW_SPRITE_PRIORITY":{"kind":4,"retType":"number"},"scene.PHYSICS_PRIORITY":{"kind":4,"retType":"number"},"scene.ANIMATION_UPDATE_PRIORITY":{"kind":4,"retType":"number"},"scene.CONTROLLER_SPRITES_PRIORITY":{"kind":4,"retType":"number"},"scene.UPDATE_INTERVAL_PRIORITY":{"kind":4,"retType":"number"},"scene.UPDATE_PRIORITY":{"kind":4,"retType":"number"},"scene.PRE_RENDER_UPDATE_PRIORITY":{"kind":4,"retType":"number"},"scene.RENDER_BACKGROUND_PRIORITY":{"kind":4,"retType":"number"},"scene.RENDER_SPRITES_PRIORITY":{"kind":4,"retType":"number"},"scene.RENDER_DIAGNOSTICS_PRIORITY":{"kind":4,"retType":"number"},"scene.MULTIPLAYER_SCREEN_PRIORITY":{"kind":4,"retType":"number"},"scene.UPDATE_SCREEN_PRIORITY":{"kind":4,"retType":"number"},"scene.MULTIPLAYER_POST_SCREEN_PRIORITY":{"kind":4,"retType":"number"},"scene.ON_PAINT_Z":{"kind":4,"retType":"-20"},"scene.TILE_MAP_Z":{"kind":4,"retType":"-1"},"scene.SPRITE_Z":{"kind":4,"retType":"number"},"scene.ON_SHADE_Z":{"kind":4,"retType":"number"},"scene.HUD_Z":{"kind":4,"retType":"number"},"scene.Scene":{"kind":8,"retType":"scene.Scene","extendsTypes":[]},"scene.Scene.eventContext":{"kind":2,"retType":"control.EventContext","isInstance":true,"pyQName":"scene.Scene.event_context"},"scene.Scene.background":{"kind":2,"retType":"scene.Background","isInstance":true},"scene.Scene.tileMap":{"kind":2,"retType":"tiles.TileMap","isInstance":true,"pyQName":"scene.Scene.tile_map"},"scene.Scene.allSprites":{"kind":2,"retType":"SpriteLike[]","isInstance":true,"pyQName":"scene.Scene.all_sprites"},"scene.Scene.spritesByKind":{"kind":2,"retType":"SparseArray<sprites.SpriteSet>","isInstance":true,"pyQName":"scene.Scene.sprites_by_kind"},"scene.Scene.physicsEngine":{"kind":2,"retType":"PhysicsEngine","isInstance":true,"pyQName":"scene.Scene.physics_engine"},"scene.Scene.camera":{"kind":2,"retType":"scene.Camera","isInstance":true},"scene.Scene.flags":{"kind":2,"retType":"number","isInstance":true},"scene.Scene.destroyedHandlers":{"kind":2,"retType":"scene.SpriteHandler[]","isInstance":true,"pyQName":"scene.Scene.destroyed_handlers"},"scene.Scene.createdHandlers":{"kind":2,"retType":"scene.SpriteHandler[]","isInstance":true,"pyQName":"scene.Scene.created_handlers"},"scene.Scene.overlapHandlers":{"kind":2,"retType":"scene.OverlapHandler[]","isInstance":true,"pyQName":"scene.Scene.overlap_handlers"},"scene.Scene.overlapMap":{"kind":2,"retType":"SparseArray<number[]>","isInstance":true,"pyQName":"scene.Scene.overlap_map"},"scene.Scene.tileOverlapHandlers":{"kind":2,"retType":"scene.TileOverlapHandler[]","isInstance":true,"pyQName":"scene.Scene.tile_overlap_handlers"},"scene.Scene.collisionHandlers":{"kind":2,"retType":"scene.SpriteHandler[][]","isInstance":true,"pyQName":"scene.Scene.collision_handlers"},"scene.Scene.wallCollisionHandlers":{"kind":2,"retType":"scene.TileWallHandler[]","isInstance":true,"pyQName":"scene.Scene.wall_collision_handlers"},"scene.Scene.gameForeverHandlers":{"kind":2,"retType":"scene.GameForeverHandler[]","isInstance":true,"pyQName":"scene.Scene.game_forever_handlers"},"scene.Scene.particleSources":{"kind":2,"retType":"particles.ParticleSource[]","isInstance":true,"pyQName":"scene.Scene.particle_sources"},"scene.Scene.controlledSprites":{"kind":2,"retType":"controller.ControlledSprite[][]","isInstance":true,"pyQName":"scene.Scene.controlled_sprites"},"scene.Scene.controllerConnectionState":{"kind":2,"retType":"boolean[]","isInstance":true,"pyQName":"scene.Scene.controller_connection_state"},"scene.Scene.followingSprites":{"kind":2,"retType":"sprites.FollowingSprite[]","isInstance":true,"pyQName":"scene.Scene.following_sprites"},"scene.Scene.buttonEventHandlers":{"kind":2,"retType":"controller.ButtonEventHandlerState[]","isInstance":true,"pyQName":"scene.Scene.button_event_handlers"},"scene.Scene.initializers":{"kind":2,"retType":"((scene: scene.Scene) => void)[]"},"scene.Scene.__constructor":{"kind":-3,"parameters":[{"name":"eventContext","type":"control.EventContext"},{"name":"previousScene","type":"scene.Scene","initializer":"undefined"}],"isInstance":true},"scene.Scene.init":{"kind":-1,"parameters":[],"isInstance":true},"scene.Scene.data":{"kind":-2,"retType":"any","isInstance":true,"isReadOnly":true},"scene.Scene.millis":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Gets the elapsed time in the scene"},"parameters":[],"isInstance":true},"scene.Scene.addSprite":{"kind":-1,"parameters":[{"name":"sprite","type":"SpriteLike"}],"isInstance":true,"pyQName":"scene.Scene.add_sprite"},"scene.Scene.destroy":{"kind":-1,"parameters":[],"isInstance":true},"scene.Scene.render":{"kind":-1,"attributes":{"jsDoc":"Renders the current frame as an image"},"parameters":[],"isInstance":true},"CameraProperty":{"kind":6,"retType":"CameraProperty","attributes":{"jsDoc":"Control the background, tiles and camera"},"extendsTypes":["CameraProperty","Number"]},"CameraProperty.X":{"retType":"CameraProperty.X","attributes":{"block":"x","_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"extendsTypes":["CameraProperty.X","Number"]},"CameraProperty.Y":{"retType":"CameraProperty.Y","attributes":{"block":"y","_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"extendsTypes":["CameraProperty.Y","Number"]},"CameraProperty.Left":{"retType":"CameraProperty.Left","attributes":{"block":"left","_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"extendsTypes":["CameraProperty.Left","Number"],"pyQName":"CameraProperty.LEFT"},"CameraProperty.Right":{"retType":"CameraProperty.Right","attributes":{"block":"right","_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"extendsTypes":["CameraProperty.Right","Number"],"pyQName":"CameraProperty.RIGHT"},"CameraProperty.Top":{"retType":"CameraProperty.Top","attributes":{"block":"top","_def":{"parts":[{"kind":"label","text":"top","style":[]}],"parameters":[]}},"extendsTypes":["CameraProperty.Top","Number"],"pyQName":"CameraProperty.TOP"},"CameraProperty.Bottom":{"retType":"CameraProperty.Bottom","attributes":{"block":"bottom","_def":{"parts":[{"kind":"label","text":"bottom","style":[]}],"parameters":[]}},"extendsTypes":["CameraProperty.Bottom","Number"],"pyQName":"CameraProperty.BOTTOM"},"scene.screenWidth":{"kind":-3,"retType":"number","attributes":{"blockId":"scenescreenwidth","block":"screen width","group":"Screen","weight":100,"blockGap":"8","help":"scene/screen-width","jsDoc":"Get the width of the screen in pixels","_def":{"parts":[{"kind":"label","text":"screen width","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"scene.screen_width"},"scene.screenHeight":{"kind":-3,"retType":"number","attributes":{"blockId":"scenescreenheight","block":"screen height","group":"Screen","weight":99,"help":"scene/screen-width","jsDoc":"Gets the height of the screen in pixels","_def":{"parts":[{"kind":"label","text":"screen height","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"scene.screen_height"},"scene.setBackgroundColor":{"kind":-3,"attributes":{"group":"Screen","weight":25,"blockId":"gamesetbackgroundcolor","block":"set background color to %color=colorindexpicker","help":"scene/set-background-color","paramHelp":{"color":""},"jsDoc":"Set the game background color","_def":{"parts":[{"kind":"label","text":"set background color to ","style":[]},{"kind":"param","name":"color","shadowBlockId":"colorindexpicker","ref":false}],"parameters":[{"kind":"param","name":"color","shadowBlockId":"colorindexpicker","ref":false}]}},"parameters":[{"name":"color"}],"pyQName":"scene.set_background_color"},"scene.backgroundColor":{"kind":-3,"retType":"number","attributes":{"group":"Screen","weight":22,"blockId":"gamebackgroundcolor","block":"background color","help":"scene/background-color","paramHelp":{"color":""},"jsDoc":"Get the game background color","_def":{"parts":[{"kind":"label","text":"background color","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"scene.background_color"},"scene.setBackgroundImage":{"kind":-3,"attributes":{"group":"Screen","weight":24,"blockId":"gamesetbackgroundimage","block":"set background image to %img=background_image_picker","help":"scene/set-background-image","jsDoc":"Set a picture as the background","_def":{"parts":[{"kind":"label","text":"set background image to ","style":[]},{"kind":"param","name":"img","shadowBlockId":"background_image_picker","ref":false}],"parameters":[{"kind":"param","name":"img","shadowBlockId":"background_image_picker","ref":false}]}},"parameters":[{"name":"img","type":"Image"}],"pyQName":"scene.set_background_image"},"scene.backgroundImage":{"kind":-3,"retType":"Image","attributes":{"weight":22,"group":"Screen","blockId":"gamebackgroundimage","block":"background image","help":"scene/background-image","jsDoc":"Get the current background image","_def":{"parts":[{"kind":"label","text":"background image","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"scene.background_image"},"scene.addBackgroundLayer":{"kind":-3,"attributes":{"paramDefl":{"distance":"10"},"group":"Screen","weight":10,"paramHelp":{"distance":"distance of the layer which determines how fast it moves, eg: 10","img":""},"jsDoc":"Adds a moving background layer"},"parameters":[{"name":"image","type":"Image"},{"name":"distance","description":"distance of the layer which determines how fast it moves, eg: 10","initializer":"undefined","default":"10"},{"name":"alignment","type":"BackgroundAlignment","initializer":"undefined","isEnum":true}],"pyQName":"scene.add_background_layer"},"scene.setTileMapLevel":{"kind":-3,"attributes":{"paramHelp":{"map":"@param scale"},"jsDoc":"Set the map for placing tiles in the scene"},"parameters":[{"name":"map","description":"@param scale","type":"tiles.TileMapData"}],"pyQName":"scene.set_tile_map_level"},"scene.cameraShake":{"kind":-3,"attributes":{"paramDefl":{"amplitude":"4","duration":"500"},"blockId":"camerashake","block":"camera shake by %amplitude pixels for %duration ms","paramMin":{"amplitude":"1"},"paramMax":{"amplitude":"8"},"explicitDefaults":["amplitude","duration"],"_shadowOverrides":{"duration":"timePicker"},"group":"Camera","help":"scene/camera-shake","weight":90,"paramHelp":{"sprite":""},"jsDoc":"Shake the camera","_def":{"parts":[{"kind":"label","text":"camera shake by ","style":[]},{"kind":"param","name":"amplitude","ref":false},{"kind":"label","text":" pixels for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"amplitude","ref":false},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"amplitude","initializer":"4","default":"4","options":{"min":{"value":"1"},"max":{"value":"8"}}},{"name":"duration","initializer":"500","default":"500"}],"pyQName":"scene.camera_shake"},"scene.cameraFollowSprite":{"kind":-3,"attributes":{"blockId":"camerafollow","block":"camera follow sprite %sprite=variables_get(mySprite)","group":"Camera","help":"scene/camera-follow-sprite","weight":100,"paramHelp":{"sprite":""},"jsDoc":"Set the game camera to follow a sprite","_def":{"parts":[{"kind":"label","text":"camera follow sprite ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"}]}},"parameters":[{"name":"sprite","type":"Sprite"}],"pyQName":"scene.camera_follow_sprite"},"scene.centerCameraAt":{"kind":-3,"attributes":{"blockId":"camerapos","block":"center camera at x %x y %y","group":"Camera","help":"scene/center-camera-at","weight":80,"paramHelp":{"sprite":""},"jsDoc":"Moves the camera center to a coordinate position","_def":{"parts":[{"kind":"label","text":"center camera at x ","style":[]},{"kind":"param","name":"x","ref":false},{"kind":"label","text":" y ","style":[]},{"kind":"param","name":"y","ref":false}],"parameters":[{"kind":"param","name":"x","ref":false},{"kind":"param","name":"y","ref":false}]}},"parameters":[{"name":"x"},{"name":"y"}],"pyQName":"scene.center_camera_at"},"scene.cameraLeft":{"kind":-3,"retType":"number","attributes":{"blockId":"cameraleft","block":"camera left","group":"Camera","help":"scene/camera-left","deprecated":"true","jsDoc":"Returns the x coordinate of the camera (the left of the screen)","_def":{"parts":[{"kind":"label","text":"camera left","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"scene.camera_left"},"scene.cameraTop":{"kind":-3,"retType":"number","attributes":{"blockId":"cameratop","block":"camera top","group":"Camera","help":"scene/camera-top","deprecated":"true","jsDoc":"Returns the y coordinate of the camera (the top of the screen)","_def":{"parts":[{"kind":"label","text":"camera top","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"scene.camera_top"},"scene.cameraProperty":{"kind":-3,"retType":"number","attributes":{"blockId":"cameraproperty","block":"camera $property","group":"Camera","help":"scene/camera-property","weight":70,"paramHelp":{"property":"The property to get"},"jsDoc":"Returns the specified camera property","_def":{"parts":[{"kind":"label","text":"camera ","style":[]},{"kind":"param","name":"property","ref":true}],"parameters":[{"kind":"param","name":"property","ref":true}]}},"parameters":[{"name":"property","description":"The property to get","type":"CameraProperty","isEnum":true}],"pyQName":"scene.camera_property"},"DialogLayout":{"kind":6,"retType":"DialogLayout","extendsTypes":["DialogLayout","Number"]},"DialogLayout.Bottom":{"retType":"DialogLayout.Bottom","attributes":{"block":"bottom","_def":{"parts":[{"kind":"label","text":"bottom","style":[]}],"parameters":[]}},"extendsTypes":["DialogLayout.Bottom","Number"],"pyQName":"DialogLayout.BOTTOM"},"DialogLayout.Left":{"retType":"DialogLayout.Left","attributes":{"block":"left","_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"extendsTypes":["DialogLayout.Left","Number"],"pyQName":"DialogLayout.LEFT"},"DialogLayout.Right":{"retType":"DialogLayout.Right","attributes":{"block":"right","_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"extendsTypes":["DialogLayout.Right","Number"],"pyQName":"DialogLayout.RIGHT"},"DialogLayout.Top":{"retType":"DialogLayout.Top","attributes":{"block":"top","_def":{"parts":[{"kind":"label","text":"top","style":[]}],"parameters":[]}},"extendsTypes":["DialogLayout.Top","Number"],"pyQName":"DialogLayout.TOP"},"DialogLayout.Center":{"retType":"DialogLayout.Center","attributes":{"block":"center","_def":{"parts":[{"kind":"label","text":"center","style":[]}],"parameters":[]}},"extendsTypes":["DialogLayout.Center","Number"],"pyQName":"DialogLayout.CENTER"},"DialogLayout.Full":{"retType":"DialogLayout.Full","attributes":{"block":"full screen","_def":{"parts":[{"kind":"label","text":"full screen","style":[]}],"parameters":[]}},"extendsTypes":["DialogLayout.Full","Number"],"pyQName":"DialogLayout.FULL"},"game.BaseDialog":{"kind":8,"retType":"game.BaseDialog","extendsTypes":["game.BaseDialog"]},"game.BaseDialog.image":{"kind":2,"retType":"Image","isInstance":true},"game.BaseDialog.frame":{"kind":2,"retType":"Image","isInstance":true},"game.BaseDialog.cursor":{"kind":2,"retType":"Image","isInstance":true},"game.BaseDialog.columns":{"kind":2,"retType":"number","isInstance":true},"game.BaseDialog.rows":{"kind":2,"retType":"number","isInstance":true},"game.BaseDialog.unit":{"kind":2,"retType":"number","isInstance":true},"game.BaseDialog.innerLeft":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.BaseDialog.inner_left"},"game.BaseDialog.innerTop":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.BaseDialog.inner_top"},"game.BaseDialog.cursorCount":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.BaseDialog.cursor_count"},"game.BaseDialog.font":{"kind":2,"retType":"image.Font","isInstance":true},"game.BaseDialog.textColor":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.BaseDialog.text_color"},"game.BaseDialog.__constructor":{"kind":-3,"parameters":[{"name":"width"},{"name":"height"},{"name":"frame","type":"Image","initializer":"undefined"},{"name":"font","type":"image.Font","initializer":"undefined"},{"name":"cursor","type":"Image","initializer":"undefined"}],"isInstance":true},"game.BaseDialog.resize":{"kind":-1,"parameters":[{"name":"width"},{"name":"height"},{"name":"frame","type":"Image","initializer":"undefined"},{"name":"font","type":"image.Font","initializer":"undefined"},{"name":"cursor","type":"Image","initializer":"undefined"}],"isInstance":true},"game.BaseDialog.update":{"kind":-1,"parameters":[],"isInstance":true},"game.BaseDialog.setText":{"kind":-1,"parameters":[{"name":"rawString","type":"string"}],"isInstance":true,"pyQName":"game.BaseDialog.set_text"},"game.BaseDialog.drawTextCore":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"game.BaseDialog.draw_text_core"},"game.BaseDialog.drawCursorRow":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"game.BaseDialog.draw_cursor_row"},"game.Dialog":{"kind":8,"retType":"game.Dialog","extendsTypes":["game.Dialog","game.BaseDialog"]},"game.Dialog.chunks":{"kind":2,"retType":"string[][]","isInstance":true},"game.Dialog.chunkIndex":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.Dialog.chunk_index"},"game.Dialog.__constructor":{"kind":-3,"parameters":[{"name":"width"},{"name":"height"},{"name":"frame","type":"Image","initializer":"undefined"},{"name":"font","type":"image.Font","initializer":"undefined"},{"name":"cursor","type":"Image","initializer":"undefined"}],"isInstance":true},"game.Dialog.hasNext":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"game.Dialog.has_next"},"game.Dialog.hasPrev":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"game.Dialog.has_prev"},"game.Dialog.nextPage":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"game.Dialog.next_page"},"game.Dialog.prevPage":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"game.Dialog.prev_page"},"game.Dialog.chunkText":{"kind":-1,"retType":"string[][]","parameters":[{"name":"str","type":"string"}],"isInstance":true,"pyQName":"game.Dialog.chunk_text"},"game.Dialog.setText":{"kind":-1,"parameters":[{"name":"rawString","type":"string"}],"isInstance":true,"pyQName":"game.Dialog.set_text"},"game.Dialog.drawTextCore":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"game.Dialog.draw_text_core"},"game.SplashDialog":{"kind":8,"retType":"game.SplashDialog","extendsTypes":["game.SplashDialog","game.BaseDialog"]},"game.SplashDialog.text":{"kind":2,"retType":"string","isInstance":true},"game.SplashDialog.subtext":{"kind":2,"retType":"string","isInstance":true},"game.SplashDialog.timer":{"kind":2,"retType":"number","isInstance":true},"game.SplashDialog.offset":{"kind":2,"retType":"number","isInstance":true},"game.SplashDialog.maxOffset":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.SplashDialog.max_offset"},"game.SplashDialog.maxSubOffset":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.SplashDialog.max_sub_offset"},"game.SplashDialog.__constructor":{"kind":-3,"parameters":[{"name":"width"},{"name":"height"}],"isInstance":true},"game.SplashDialog.setText":{"kind":-1,"parameters":[{"name":"text","type":"string"}],"isInstance":true,"pyQName":"game.SplashDialog.set_text"},"game.SplashDialog.setSubtext":{"kind":-1,"parameters":[{"name":"sub","type":"string"}],"isInstance":true,"pyQName":"game.SplashDialog.set_subtext"},"game.SplashDialog.drawTextCore":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"game.SplashDialog.draw_text_core"},"game.GameOverPlayerScore":{"kind":8,"retType":"game.GameOverPlayerScore","extendsTypes":[]},"game.GameOverPlayerScore.str":{"kind":2,"retType":"string","isInstance":true},"game.GameOverPlayerScore.__constructor":{"kind":-3,"parameters":[{"name":"player"},{"name":"value"},{"name":"winner","type":"boolean"}],"isInstance":true},"game.GameOverDialog":{"kind":8,"retType":"game.GameOverDialog","extendsTypes":["game.GameOverDialog","game.BaseDialog"]},"game.GameOverDialog.isWinCondition":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"game.GameOverDialog.is_win_condition"},"game.GameOverDialog.isJudgedGame":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"game.GameOverDialog.is_judged_game"},"game.GameOverDialog.hasScores":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"game.GameOverDialog.has_scores"},"game.GameOverDialog.hasBestScore":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"game.GameOverDialog.has_best_score"},"game.GameOverDialog.isNewBestScore":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"game.GameOverDialog.is_new_best_score"},"game.GameOverDialog.isMultiplayerGame":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"game.GameOverDialog.is_multiplayer_game"},"game.GameOverDialog.__constructor":{"kind":-3,"parameters":[{"name":"win","type":"boolean"},{"name":"message","type":"string"},{"name":"judged","type":"boolean"},{"name":"scores","type":"game.GameOverPlayerScore[]"},{"name":"bestScore","initializer":"undefined"},{"name":"winnerOverride","initializer":"undefined"}],"isInstance":true},"game.GameOverDialog.displayCursor":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"game.GameOverDialog.display_cursor"},"game.GameOverDialog.update":{"kind":-1,"parameters":[],"isInstance":true},"game.GameOverDialog.drawMessage":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"game.GameOverDialog.draw_message"},"game.GameOverDialog.drawScores":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"game.GameOverDialog.draw_scores"},"game.GameOverDialog.drawBestScore":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"game.GameOverDialog.draw_best_score"},"game.GameOverDialog.drawTextCore":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"game.GameOverDialog.draw_text_core"},"game.showLongText":{"kind":-3,"attributes":{"blockId":"game_show_long_text","group":"Dialogs","block":"show long text %str %layout","_shadowOverrides":{"str":"text"},"help":"game/show-long-text","paramHelp":{"layout":"The layout to use for the dialog box"},"jsDoc":"Show a long text string in a dialog box that will scroll\nusing the \"A\" or \"down\" buttons. The previous section of the\ntext is shown using the \"up\" button. This function\nhalts execution until the last page of text is dismissed.\n* @param str The text to display","_def":{"parts":[{"kind":"label","text":"show long text ","style":[]},{"kind":"param","name":"str","shadowBlockId":"text","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"layout","ref":false}],"parameters":[{"kind":"param","name":"str","shadowBlockId":"text","ref":false},{"kind":"param","name":"layout","ref":false}]}},"parameters":[{"name":"str","type":"any"},{"name":"layout","description":"The layout to use for the dialog box","type":"DialogLayout","isEnum":true}],"pyQName":"game.show_long_text"},"game.setDialogFrame":{"kind":-3,"attributes":{"blockId":"game_dialog_set_frame","group":"Dialogs","block":"set dialog frame to %frame=dialog_image_picker","help":"game/set-dialog-frame","jsDoc":"Change the default dialog frame to a new image. Dialog frames\nare divided into three rows and three columns and are used to define\nthe outer frame of the dialog box.\n* @param frame A square image with a width and height divisible by three","_def":{"parts":[{"kind":"label","text":"set dialog frame to ","style":[]},{"kind":"param","name":"frame","shadowBlockId":"dialog_image_picker","ref":false}],"parameters":[{"kind":"param","name":"frame","shadowBlockId":"dialog_image_picker","ref":false}]}},"parameters":[{"name":"frame","type":"Image"}],"pyQName":"game.set_dialog_frame"},"game.setDialogCursor":{"kind":-3,"attributes":{"blockId":"game_dialog_set_cursor","group":"Dialogs","block":"set dialog cursor to %frame=screen_image_picker","help":"game/set-dialog-cursor","jsDoc":"Change the default image used for the cursor that appears in the\nbottom left of the dialog box.\n* @param cursor The image to use for the cursor","_def":{"parts":[{"kind":"label","text":"set dialog cursor to ","style":[]},{"kind":"param","name":"frame","shadowBlockId":"screen_image_picker","ref":false}],"parameters":[{"kind":"param","name":"frame","shadowBlockId":"screen_image_picker","ref":false}]}},"parameters":[{"name":"cursor","type":"Image"}],"pyQName":"game.set_dialog_cursor"},"game.setDialogTextColor":{"kind":-3,"attributes":{"blockId":"game_dialog_set_text_color","group":"Dialogs","block":"set dialog text color to %color=colorindexpicker","help":"game/set-dialog-text-color","jsDoc":"Change the color for the text in dialog boxes.\n* @param color The index of the color 0-15","_def":{"parts":[{"kind":"label","text":"set dialog text color to ","style":[]},{"kind":"param","name":"color","shadowBlockId":"colorindexpicker","ref":false}],"parameters":[{"kind":"param","name":"color","shadowBlockId":"colorindexpicker","ref":false}]}},"parameters":[{"name":"color"}],"pyQName":"game.set_dialog_text_color"},"game.setDialogFont":{"kind":-3,"attributes":{"deprecated":"true","blockHidden":true},"parameters":[{"name":"font","type":"image.Font"}],"pyQName":"game.set_dialog_font"},"game.splash":{"kind":-3,"attributes":{"weight":90,"help":"game/splash","blockId":"gameSplash","block":"splash %title||%subtitle","_shadowOverrides":{"title":"text","subtitle":"text"},"group":"Prompt","paramHelp":{"title":"@param subtitle"},"jsDoc":"Show a title and an optional subtitle menu","_def":{"parts":[{"kind":"label","text":"splash ","style":[]},{"kind":"param","name":"title","shadowBlockId":"text","ref":false}],"parameters":[{"kind":"param","name":"title","shadowBlockId":"text","ref":false}]},"_expandedDef":{"parts":[{"kind":"param","name":"subtitle","shadowBlockId":"text","ref":false}],"parameters":[{"kind":"param","name":"subtitle","shadowBlockId":"text","ref":false}]}},"parameters":[{"name":"title","description":"@param subtitle","type":"any"},{"name":"subtitle","type":"any","initializer":"undefined"}]},"game.debug":{"kind":4,"retType":"boolean","attributes":{"jsDoc":"Determines if diagnostics are shown"}},"game.stats":{"kind":4,"retType":"boolean"},"game.ScoringType":{"kind":6,"retType":"game.ScoringType","extendsTypes":["game.ScoringType","Number"]},"game.ScoringType.HighScore":{"retType":"game.ScoringType.HighScore","attributes":{"block":"high score","_def":{"parts":[{"kind":"label","text":"high score","style":[]}],"parameters":[]}},"extendsTypes":["game.ScoringType.HighScore","Number"],"pyQName":"game.ScoringType.HIGH_SCORE"},"game.ScoringType.LowScore":{"retType":"game.ScoringType.LowScore","attributes":{"block":"low score","_def":{"parts":[{"kind":"label","text":"low score","style":[]}],"parameters":[]}},"extendsTypes":["game.ScoringType.LowScore","Number"],"pyQName":"game.ScoringType.LOW_SCORE"},"game.ScoringType.None":{"retType":"game.ScoringType.None","attributes":{"block":"none","_def":{"parts":[{"kind":"label","text":"none","style":[]}],"parameters":[]}},"extendsTypes":["game.ScoringType.None","Number"],"pyQName":"game.ScoringType.NONE"},"game.Color":{"kind":6,"retType":"game.Color","attributes":{"jsDoc":"The available colors for Arcade.\nNOTE: If the color palette is changed, these values will change along with it."},"extendsTypes":["game.Color","Number"]},"game.Color.Transparent":{"retType":"game.Color.Transparent","extendsTypes":["game.Color.Transparent","Number"],"pyQName":"game.Color.TRANSPARENT"},"game.Color.White":{"retType":"game.Color.White","extendsTypes":["game.Color.White","Number"],"pyQName":"game.Color.WHITE"},"game.Color.Red":{"retType":"game.Color.Red","extendsTypes":["game.Color.Red","Number"],"pyQName":"game.Color.RED"},"game.Color.Pink":{"retType":"game.Color.Pink","extendsTypes":["game.Color.Pink","Number"],"pyQName":"game.Color.PINK"},"game.Color.Orange":{"retType":"game.Color.Orange","extendsTypes":["game.Color.Orange","Number"],"pyQName":"game.Color.ORANGE"},"game.Color.Yellow":{"retType":"game.Color.Yellow","extendsTypes":["game.Color.Yellow","Number"],"pyQName":"game.Color.YELLOW"},"game.Color.Teal":{"retType":"game.Color.Teal","extendsTypes":["game.Color.Teal","Number"],"pyQName":"game.Color.TEAL"},"game.Color.Green":{"retType":"game.Color.Green","extendsTypes":["game.Color.Green","Number"],"pyQName":"game.Color.GREEN"},"game.Color.Blue":{"retType":"game.Color.Blue","extendsTypes":["game.Color.Blue","Number"],"pyQName":"game.Color.BLUE"},"game.Color.LightBlue":{"retType":"game.Color.LightBlue","extendsTypes":["game.Color.LightBlue","Number"],"pyQName":"game.Color.LIGHT_BLUE"},"game.Color.Purple":{"retType":"game.Color.Purple","extendsTypes":["game.Color.Purple","Number"],"pyQName":"game.Color.PURPLE"},"game.Color.LightPurple":{"retType":"game.Color.LightPurple","extendsTypes":["game.Color.LightPurple","Number"],"pyQName":"game.Color.LIGHT_PURPLE"},"game.Color.DarkPurple":{"retType":"game.Color.DarkPurple","extendsTypes":["game.Color.DarkPurple","Number"],"pyQName":"game.Color.DARK_PURPLE"},"game.Color.Tan":{"retType":"game.Color.Tan","extendsTypes":["game.Color.Tan","Number"],"pyQName":"game.Color.TAN"},"game.Color.Brown":{"retType":"game.Color.Brown","extendsTypes":["game.Color.Brown","Number"],"pyQName":"game.Color.BROWN"},"game.Color.Black":{"retType":"game.Color.Black","extendsTypes":["game.Color.Black","Number"],"pyQName":"game.Color.BLACK"},"game.GameOverConfig":{"kind":8,"retType":"game.GameOverConfig","extendsTypes":[]},"game.GameOverConfig.scoringType":{"kind":2,"retType":"game.ScoringType","isInstance":true,"pyQName":"game.GameOverConfig.scoring_type"},"game.GameOverConfig.winEffect":{"kind":2,"retType":"effects.BackgroundEffect","isInstance":true,"pyQName":"game.GameOverConfig.win_effect"},"game.GameOverConfig.loseEffect":{"kind":2,"retType":"effects.BackgroundEffect","isInstance":true,"pyQName":"game.GameOverConfig.lose_effect"},"game.GameOverConfig.loseSound":{"kind":2,"retType":"music.Playable","isInstance":true,"pyQName":"game.GameOverConfig.lose_sound"},"game.GameOverConfig.winSound":{"kind":2,"retType":"music.Playable","isInstance":true,"pyQName":"game.GameOverConfig.win_sound"},"game.GameOverConfig.loseSoundLooping":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"game.GameOverConfig.lose_sound_looping"},"game.GameOverConfig.winSoundLooping":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"game.GameOverConfig.win_sound_looping"},"game.GameOverConfig.winMessage":{"kind":2,"retType":"string","isInstance":true,"pyQName":"game.GameOverConfig.win_message"},"game.GameOverConfig.winMessageMultiplayer":{"kind":2,"retType":"string","isInstance":true,"pyQName":"game.GameOverConfig.win_message_multiplayer"},"game.GameOverConfig.loseMessage":{"kind":2,"retType":"string","isInstance":true,"pyQName":"game.GameOverConfig.lose_message"},"game.GameOverConfig.effectSetByUser":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"game.GameOverConfig.effect_set_by_user"},"game.GameOverConfig.soundSetByUser":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"game.GameOverConfig.sound_set_by_user"},"game.GameOverConfig.messageSetByUser":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"game.GameOverConfig.message_set_by_user"},"game.GameOverConfig.scoringTypeSetByUser":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"game.GameOverConfig.scoring_type_set_by_user"},"game.GameOverConfig.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"game.GameOverConfig.init":{"kind":-1,"parameters":[],"isInstance":true},"game.GameOverConfig.setScoringType":{"kind":-1,"parameters":[{"name":"type","type":"game.ScoringType","isEnum":true},{"name":"explicit","type":"boolean"}],"isInstance":true,"pyQName":"game.GameOverConfig.set_scoring_type"},"game.GameOverConfig.setEffect":{"kind":-1,"parameters":[{"name":"win","type":"boolean"},{"name":"effect","type":"effects.BackgroundEffect"},{"name":"explicit","type":"boolean"}],"isInstance":true,"pyQName":"game.GameOverConfig.set_effect"},"game.GameOverConfig.getEffect":{"kind":-1,"retType":"effects.BackgroundEffect","parameters":[{"name":"win","type":"boolean"}],"isInstance":true,"pyQName":"game.GameOverConfig.get_effect"},"game.GameOverConfig.setSound":{"kind":-1,"parameters":[{"name":"win","type":"boolean"},{"name":"sound","type":"music.Playable"},{"name":"looping","type":"boolean"},{"name":"explicit","type":"boolean"}],"isInstance":true,"pyQName":"game.GameOverConfig.set_sound"},"game.GameOverConfig.getSound":{"kind":-1,"retType":"music.Playable","parameters":[{"name":"win","type":"boolean"}],"isInstance":true,"pyQName":"game.GameOverConfig.get_sound"},"game.GameOverConfig.getSoundLooping":{"kind":-1,"retType":"boolean","parameters":[{"name":"win","type":"boolean"}],"isInstance":true,"pyQName":"game.GameOverConfig.get_sound_looping"},"game.GameOverConfig.setMessage":{"kind":-1,"parameters":[{"name":"win","type":"boolean"},{"name":"message","type":"string"},{"name":"explicit","type":"boolean"}],"isInstance":true,"pyQName":"game.GameOverConfig.set_message"},"game.GameOverConfig.getMessage":{"kind":-1,"retType":"string","parameters":[{"name":"win","type":"boolean"},{"name":"preferMultiplayer","type":"boolean","initializer":"undefined"}],"isInstance":true,"pyQName":"game.GameOverConfig.get_message"},"game.gameOverConfig":{"kind":4,"retType":"() => game.GameOverConfig","pyQName":"game.game_over_config"},"game.currentScene":{"kind":-3,"retType":"scene.Scene","parameters":[],"pyQName":"game.current_scene"},"game.setWaitAnyButton":{"kind":-3,"parameters":[{"name":"f","type":"() => void","handlerParameters":[]}],"pyQName":"game.set_wait_any_button"},"game.waitAnyButton":{"kind":-3,"parameters":[],"pyQName":"game.wait_any_button"},"game.eventContext":{"kind":-3,"retType":"control.EventContext","parameters":[],"pyQName":"game.event_context"},"game.pushScene":{"kind":-3,"parameters":[],"pyQName":"game.push_scene"},"game.popScene":{"kind":-3,"parameters":[],"pyQName":"game.pop_scene"},"game.showDialog":{"kind":-3,"parameters":[{"name":"title","type":"string"},{"name":"subtitle","type":"string"},{"name":"footer","type":"string","initializer":"undefined"}],"pyQName":"game.show_dialog"},"game.setGameOverEffect":{"kind":-3,"attributes":{"paramDefl":{"effect":"effects.confetti","win":"true"},"blockId":"game_setgameovereffect","block":"use effect $effect for $win","explicitDefaults":["effect","win"],"_shadowOverrides":{"win":"toggleWinLose"},"group":"Game Over","weight":90,"blockGap":"8","help":"game/set-game-over-effect","paramHelp":{"win":"whether the effect should run on a win (true) or lose (false)","effect":""},"jsDoc":"Set the effect that occurs when the game is over","_def":{"parts":[{"kind":"label","text":"use effect ","style":[]},{"kind":"param","name":"effect","ref":true},{"kind":"label","text":" for ","style":[]},{"kind":"param","name":"win","shadowBlockId":"toggleWinLose","ref":true}],"parameters":[{"kind":"param","name":"effect","ref":true},{"kind":"param","name":"win","shadowBlockId":"toggleWinLose","ref":true}]}},"parameters":[{"name":"win","description":"whether the effect should run on a win (true) or lose (false)","type":"boolean","initializer":"true","default":"true"},{"name":"effect","type":"effects.BackgroundEffect","initializer":"effects.confetti","default":"effects.confetti"}],"pyQName":"game.set_game_over_effect"},"game.setGameOverPlayable":{"kind":-3,"attributes":{"paramDefl":{"sound":"music.powerUp","looping":"false","win":"true"},"blockId":"game_setgameoverplayable","block":"use $sound looping $looping for $win","_shadowOverrides":{"sound":"music_melody_playable","looping":"toggleOnOff","win":"toggleWinLose"},"explicitDefaults":["sound","looping","win"],"group":"Game Over","weight":80,"blockGap":"8","help":"game/set-game-over-playable","paramHelp":{"win":"whether the sound should play on a win (true) or lose (false)","effect":""},"jsDoc":"Set the music that occurs when the game is over","_def":{"parts":[{"kind":"label","text":"use ","style":[]},{"kind":"param","name":"sound","shadowBlockId":"music_melody_playable","ref":true},{"kind":"label","text":" looping ","style":[]},{"kind":"param","name":"looping","shadowBlockId":"toggleOnOff","ref":true},{"kind":"label","text":" for ","style":[]},{"kind":"param","name":"win","shadowBlockId":"toggleWinLose","ref":true}],"parameters":[{"kind":"param","name":"sound","shadowBlockId":"music_melody_playable","ref":true},{"kind":"param","name":"looping","shadowBlockId":"toggleOnOff","ref":true},{"kind":"param","name":"win","shadowBlockId":"toggleWinLose","ref":true}]}},"parameters":[{"name":"win","description":"whether the sound should play on a win (true) or lose (false)","type":"boolean","initializer":"true","default":"true"},{"name":"sound","type":"music.Playable","initializer":"music.powerUp","default":"music.powerUp"},{"name":"looping","type":"boolean","initializer":"false","default":"false"}],"pyQName":"game.set_game_over_playable"},"game.setGameOverSound":{"kind":-3,"parameters":[{"name":"win","type":"boolean"},{"name":"sound","type":"music.Melody"}],"pyQName":"game.set_game_over_sound"},"game.setGameOverMessage":{"kind":-3,"attributes":{"paramDefl":{"message":"\"GAME OVER!\"","win":"true"},"blockId":"game_setgameovermessage","block":"use message $message for $win","explicitDefaults":["message","win"],"_shadowOverrides":{"win":"toggleWinLose"},"group":"Game Over","weight":70,"blockGap":"8","help":"game/set-game-over-message","paramHelp":{"win":"whether the message should show on a win (true) or lose (false)","message":""},"jsDoc":"Set the message that displays when the game is over","_def":{"parts":[{"kind":"label","text":"use message ","style":[]},{"kind":"param","name":"message","ref":true},{"kind":"label","text":" for ","style":[]},{"kind":"param","name":"win","shadowBlockId":"toggleWinLose","ref":true}],"parameters":[{"kind":"param","name":"message","ref":true},{"kind":"param","name":"win","shadowBlockId":"toggleWinLose","ref":true}]}},"parameters":[{"name":"win","description":"whether the message should show on a win (true) or lose (false)","type":"boolean","initializer":"true","default":"true"},{"name":"message","type":"string","initializer":"\"GAME OVER!\"","default":"\"GAME OVER!\""}],"pyQName":"game.set_game_over_message"},"game.setGameOverScoringType":{"kind":-3,"attributes":{"paramDefl":{"type":"ScoringType.HighScore"},"blockId":"game_setgameoverscoringtype","block":"use $type as best score","explicitDefaults":["type"],"group":"Game Over","weight":60,"blockGap":"8","help":"game/set-game-over-scoring-type","paramHelp":{"type":"the scoring type"},"jsDoc":"Set the method of judging the best score for the game","_def":{"parts":[{"kind":"label","text":"use ","style":[]},{"kind":"param","name":"type","ref":true},{"kind":"label","text":" as best score","style":[]}],"parameters":[{"kind":"param","name":"type","ref":true}]}},"parameters":[{"name":"type","description":"the scoring type","type":"game.ScoringType","initializer":"ScoringType.HighScore","default":"ScoringType.HighScore","isEnum":true}],"pyQName":"game.set_game_over_scoring_type"},"game.onGameOver":{"kind":-3,"attributes":{"paramHelp":{"handler":""},"jsDoc":"Set the function to call on game over. The 'win' boolean is\npassed to the handler."},"parameters":[{"name":"handler","type":"(win: boolean) => void","handlerParameters":[{"name":"win","type":"boolean"}]}],"pyQName":"game.on_game_over"},"game.over":{"kind":-3,"attributes":{"group":"Gameplay","blockId":"gameOver","block":"game over %win=toggleWinLose || with %effect effect","weight":80,"help":"game/over","deprecated":"true","jsDoc":"Finish the game and display the score","_def":{"parts":[{"kind":"label","text":"game over ","style":[]},{"kind":"param","name":"win","shadowBlockId":"toggleWinLose","ref":false},{"kind":"label","text":" ","style":[]}],"parameters":[{"kind":"param","name":"win","shadowBlockId":"toggleWinLose","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":" with ","style":[]},{"kind":"param","name":"effect","ref":false},{"kind":"label","text":" effect","style":[]}],"parameters":[{"kind":"param","name":"effect","ref":false}]}},"parameters":[{"name":"win","type":"boolean","initializer":"false"},{"name":"effect","type":"effects.BackgroundEffect","initializer":"undefined"}]},"game.gameOver":{"kind":-3,"attributes":{"paramDefl":{"win":"true"},"blockId":"gameOver2","block":"game over $win","_shadowOverrides":{"win":"toggleWinLose"},"explicitDefaults":["win"],"weight":100,"blockGap":"8","help":"game/over","group":"Game Over","_def":{"parts":[{"kind":"label","text":"game over ","style":[]},{"kind":"param","name":"win","shadowBlockId":"toggleWinLose","ref":true}],"parameters":[{"kind":"param","name":"win","shadowBlockId":"toggleWinLose","ref":true}]}},"parameters":[{"name":"win","type":"boolean","initializer":"true","default":"true"}],"pyQName":"game.game_over"},"game.gameOverPlayerWin":{"kind":-3,"parameters":[{"name":"player"}],"pyQName":"game.game_over_player_win"},"game.forever":{"kind":-3,"attributes":{"paramHelp":{"body":"code to execute"},"jsDoc":"Repeats the code forever in the background for this scene.\nOn each iteration, allows other codes to run."},"parameters":[{"name":"action","type":"() => void","handlerParameters":[]}]},"game.onPaint":{"kind":-3,"attributes":{"group":"Gameplay","help":"game/paint","weight":10,"afterOnStart":true,"paramHelp":{"body":"code to execute"},"jsDoc":"Draw on screen before sprites, after background"},"parameters":[{"name":"a","type":"() => void","handlerParameters":[]}],"pyQName":"game.on_paint"},"game.onShade":{"kind":-3,"attributes":{"group":"Gameplay","help":"game/shade","weight":10,"afterOnStart":true,"paramHelp":{"body":"code to execute"},"jsDoc":"Draw on screen after sprites"},"parameters":[{"name":"a","type":"() => void","handlerParameters":[]}],"pyQName":"game.on_shade"},"game.addScenePushHandler":{"kind":-3,"attributes":{"jsDoc":"Register a handler that runs whenever a scene is pushed onto the scene\nstack. Useful for extensions that need to store/restore state as the\nevent context changes. The handler is run AFTER the push operation (i.e.\nafter game.currentScene() has changed)\n* @param handler Code to run when a scene is pushed onto the stack"},"parameters":[{"name":"handler","type":"(oldScene: scene.Scene) => void","handlerParameters":[{"name":"oldScene","type":"scene.Scene"}]}],"pyQName":"game.add_scene_push_handler"},"game.removeScenePushHandler":{"kind":-3,"attributes":{"jsDoc":"Remove a scene push handler. Useful for extensions that need to store/restore state as the\nevent context changes.\n* @param handler The handler to remove"},"parameters":[{"name":"handler","type":"(oldScene: scene.Scene) => void","handlerParameters":[{"name":"oldScene","type":"scene.Scene"}]}],"pyQName":"game.remove_scene_push_handler"},"game.addScenePopHandler":{"kind":-3,"attributes":{"jsDoc":"Register a handler that runs whenever a scene is popped off of the scene\nstack. Useful for extensions that need to store/restore state as the\nevent context changes. The handler is run AFTER the pop operation. (i.e.\nafter game.currentScene() has changed)\n* @param handler Code to run when a scene is removed from the top of the stack"},"parameters":[{"name":"handler","type":"(oldScene: scene.Scene) => void","handlerParameters":[{"name":"oldScene","type":"scene.Scene"}]}],"pyQName":"game.add_scene_pop_handler"},"game.removeScenePopHandler":{"kind":-3,"attributes":{"jsDoc":"Remove a scene pop handler. Useful for extensions that need to store/restore state as the\nevent context changes.\n* @param handler The handler to remove"},"parameters":[{"name":"handler","type":"(oldScene: scene.Scene) => void","handlerParameters":[{"name":"oldScene","type":"scene.Scene"}]}],"pyQName":"game.remove_scene_pop_handler"},"game.onUpdate":{"kind":-3,"attributes":{"group":"Gameplay","help":"game/on-update","weight":100,"afterOnStart":true,"blockId":"gameupdate","block":"on game update","blockAllowMultiple":"1","paramHelp":{"body":"code to execute"},"jsDoc":"Update the position and velocities of sprites","_def":{"parts":[{"kind":"label","text":"on game update","style":[]}],"parameters":[]}},"parameters":[{"name":"a","type":"() => void","handlerParameters":[]}],"pyQName":"game.on_update"},"game.onUpdateInterval":{"kind":-3,"attributes":{"group":"Gameplay","help":"game/on-update-interval","weight":99,"afterOnStart":true,"blockId":"gameinterval","block":"on game update every %period=timePicker ms","blockAllowMultiple":"1","paramHelp":{"body":"code to execute"},"jsDoc":"Run code on an interval of time. This executes before game.onUpdate()","_def":{"parts":[{"kind":"label","text":"on game update every ","style":[]},{"kind":"param","name":"period","shadowBlockId":"timePicker","ref":false},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"period","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"period"},{"name":"a","type":"() => void","handlerParameters":[]}],"pyQName":"game.on_update_interval"},"game.runtime":{"kind":-3,"retType":"number","attributes":{"blockId":"arcade_game_runtime","block":"time since start (ms)","group":"Gameplay","weight":11,"help":"game/runtime","jsDoc":"Returns the time since the game started in milliseconds","_def":{"parts":[{"kind":"label","text":"time since start (ms)","style":[]}],"parameters":[]}},"parameters":[]},"game._KEYBOARD_CHANGE_EVENT":{"kind":4,"retType":"number"},"game._KEYBOARD_ENTER_EVENT":{"kind":4,"retType":"number"},"game._KEYBOARD_CANCEL_EVENT":{"kind":4,"retType":"number"},"game.PromptTheme":{"kind":9,"retType":"game.PromptTheme","extendsTypes":[]},"game.PromptTheme.colorPrompt":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.PromptTheme.color_prompt"},"game.PromptTheme.colorInput":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.PromptTheme.color_input"},"game.PromptTheme.colorInputHighlighted":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.PromptTheme.color_input_highlighted"},"game.PromptTheme.colorInputText":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.PromptTheme.color_input_text"},"game.PromptTheme.colorAlphabet":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.PromptTheme.color_alphabet"},"game.PromptTheme.colorCursor":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.PromptTheme.color_cursor"},"game.PromptTheme.colorBackground":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.PromptTheme.color_background"},"game.PromptTheme.colorBottomBackground":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.PromptTheme.color_bottom_background"},"game.PromptTheme.colorBottomText":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.PromptTheme.color_bottom_text"},"game.askForString":{"kind":-3,"retType":"string","attributes":{"paramDefl":{"message":"","answerLength":"12"},"weight":10,"help":"game/ask-for-string","blockId":"gameaskforstring","block":"ask for string $message || and max length $answerLength use on-screen keyboard $useOnScreenKeyboard","_shadowOverrides":{"message":"text"},"explicitDefaults":["message","answerLength"],"paramMin":{"answerLength":"1"},"paramMax":{"answerLength":"24"},"group":"Prompt","paramHelp":{"message":"The message to display on the text-entry screen","answerLength":"The maximum number of characters the user can enter (1 - 24)","useOnScreenKeyboard":"Force the simulator to use the on-screen keyboard for text entry"},"jsDoc":"Ask the player for a string value.","_def":{"parts":[{"kind":"label","text":"ask for string ","style":[]},{"kind":"param","name":"message","shadowBlockId":"text","ref":true},{"kind":"label","text":" ","style":[]}],"parameters":[{"kind":"param","name":"message","shadowBlockId":"text","ref":true}]},"_expandedDef":{"parts":[{"kind":"label","text":" and max length ","style":[]},{"kind":"param","name":"answerLength","ref":true},{"kind":"label","text":" use on-screen keyboard ","style":[]},{"kind":"param","name":"useOnScreenKeyboard","ref":true}],"parameters":[{"kind":"param","name":"answerLength","ref":true},{"kind":"param","name":"useOnScreenKeyboard","ref":true}]}},"parameters":[{"name":"message","description":"The message to display on the text-entry screen","type":"any","default":""},{"name":"answerLength","description":"The maximum number of characters the user can enter (1 - 24)","initializer":"12","default":"12","options":{"min":{"value":"1"},"max":{"value":"24"}}},{"name":"useOnScreenKeyboard","description":"Force the simulator to use the on-screen keyboard for text entry","type":"boolean","initializer":"false"}],"pyQName":"game.ask_for_string"},"game.Prompt":{"kind":8,"retType":"game.Prompt","extendsTypes":["game.Prompt"]},"game.Prompt.theme":{"kind":2,"retType":"game.PromptTheme","isInstance":true},"game.Prompt.message":{"kind":2,"retType":"string","isInstance":true},"game.Prompt.answerLength":{"kind":2,"retType":"number","isInstance":true,"pyQName":"game.Prompt.answer_length"},"game.Prompt.result":{"kind":2,"retType":"string","isInstance":true},"game.Prompt.__constructor":{"kind":-3,"parameters":[{"name":"theme","type":"game.PromptTheme","initializer":"undefined"}],"isInstance":true},"game.Prompt.show":{"kind":-1,"retType":"string","parameters":[{"name":"message","type":"string"},{"name":"answerLength"},{"name":"useOnScreenKeyboard","type":"boolean","initializer":"false"}],"isInstance":true},"game.askForNumber":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"message":"","answerLength":"6"},"weight":10,"help":"game/ask-for-number","blockId":"gameaskfornumber","block":"ask for number $message || and max length $answerLength use on-screen keyboard $useOnScreenKeyboard","_shadowOverrides":{"message":"text"},"explicitDefaults":["message","answerLength"],"paramMin":{"answerLength":"1"},"paramMax":{"answerLength":"10"},"group":"Prompt","paramHelp":{"message":"The message to display on the text-entry screen","answerLength":"The maximum number of digits the user can enter (1 - 10)","useOnScreenKeyboard":"Force the simulator to use the on-screen keyboard for text entry"},"jsDoc":"Ask the player for a number value.","_def":{"parts":[{"kind":"label","text":"ask for number ","style":[]},{"kind":"param","name":"message","shadowBlockId":"text","ref":true},{"kind":"label","text":" ","style":[]}],"parameters":[{"kind":"param","name":"message","shadowBlockId":"text","ref":true}]},"_expandedDef":{"parts":[{"kind":"label","text":" and max length ","style":[]},{"kind":"param","name":"answerLength","ref":true},{"kind":"label","text":" use on-screen keyboard ","style":[]},{"kind":"param","name":"useOnScreenKeyboard","ref":true}],"parameters":[{"kind":"param","name":"answerLength","ref":true},{"kind":"param","name":"useOnScreenKeyboard","ref":true}]}},"parameters":[{"name":"message","description":"The message to display on the text-entry screen","type":"any","default":""},{"name":"answerLength","description":"The maximum number of digits the user can enter (1 - 10)","initializer":"6","default":"6","options":{"min":{"value":"1"},"max":{"value":"10"}}},{"name":"useOnScreenKeyboard","description":"Force the simulator to use the on-screen keyboard for text entry","type":"boolean","initializer":"false"}],"pyQName":"game.ask_for_number"},"game.NumberPrompt":{"kind":8,"retType":"game.NumberPrompt","extendsTypes":["game.NumberPrompt","game.Prompt"]},"game.NumberPrompt.__constructor":{"kind":-3,"parameters":[{"name":"theme","type":"game.PromptTheme","initializer":"undefined"}],"isInstance":true},"game.ask":{"kind":-3,"retType":"boolean","attributes":{"weight":89,"help":"game/ask","blockId":"gameask","block":"ask %title||%subtitle","_shadowOverrides":{"title":"text","subtitle":"text"},"group":"Prompt","paramHelp":{"title":"@param subtitle"},"jsDoc":"Prompts the user for a boolean question","_def":{"parts":[{"kind":"label","text":"ask ","style":[]},{"kind":"param","name":"title","shadowBlockId":"text","ref":false}],"parameters":[{"kind":"param","name":"title","shadowBlockId":"text","ref":false}]},"_expandedDef":{"parts":[{"kind":"param","name":"subtitle","shadowBlockId":"text","ref":false}],"parameters":[{"kind":"param","name":"subtitle","shadowBlockId":"text","ref":false}]}},"parameters":[{"name":"title","description":"@param subtitle","type":"any"},{"name":"subtitle","type":"any","initializer":"undefined"}]},"Math.percentChance":{"kind":-3,"retType":"boolean","attributes":{"weight":2,"blockId":"percentchance","block":"%percentage|\\% chance","paramMin":{"percentage":"0"},"paramMax":{"percentage":"100;"},"help":"math/percent-chance","paramHelp":{"percentage":"The percentage chance that the returned value will be true from 0 - 100"},"jsDoc":"Returns a random boolean that is true the given percentage of the time.","_def":{"parts":[{"kind":"param","name":"percentage","ref":false},{"kind":"break"},{"kind":"label","text":"% chance","style":[]}],"parameters":[{"kind":"param","name":"percentage","ref":false}]}},"parameters":[{"name":"percentage","description":"The percentage chance that the returned value will be true from 0 - 100","options":{"min":{"value":"0"},"max":{"value":"100;"}}}],"pyQName":"Math.percent_chance"},"Math.pickRandom":{"kind":-3,"retType":"T","attributes":{"weight":1,"paramHelp":{"list":"The list to choose an element from"},"jsDoc":"Returns a random element from the given list"},"parameters":[{"name":"list","description":"The list to choose an element from","type":"T[]"}],"pyQName":"Math.pick_random"},"Math.FastRandom":{"kind":8,"retType":"Math.FastRandom","attributes":{"jsDoc":"Fast, 16 bit, seedable (pseudo) random generator."},"extendsTypes":[]},"Math.FastRandom.seed":{"kind":2,"retType":"number","isInstance":true},"Math.FastRandom.__constructor":{"kind":-3,"attributes":{"paramHelp":{"seed":"[Optional] initial seed between 0x0001 and 0xFFFF."},"jsDoc":"Create a new Fast Random generator"},"parameters":[{"name":"seed","description":"[Optional] initial seed between 0x0001 and 0xFFFF.","initializer":"undefined"}],"isInstance":true},"Math.FastRandom.next":{"kind":-1,"retType":"number","attributes":{"jsDoc":"@returns the next random number between 0x0001 and 0xFFFF inclusive"},"parameters":[],"isInstance":true},"Math.FastRandom.randomRange":{"kind":-1,"retType":"number","attributes":{"paramHelp":{"min":"the minimum value to generate","max":"the maximum value to generate"},"jsDoc":"@returns a random value between min and max (inclusive). If min is greater than or equal to max, returns min."},"parameters":[{"name":"min","description":"the minimum value to generate"},{"name":"max","description":"the maximum value to generate"}],"isInstance":true,"pyQName":"Math.FastRandom.random_range"},"Math.FastRandom.pickRandom":{"kind":-1,"retType":"T","attributes":{"paramHelp":{"list":"The list to choose an element from"},"jsDoc":"Returns a random element from the given list"},"parameters":[{"name":"list","description":"The list to choose an element from","type":"T[]"}],"isInstance":true,"pyQName":"Math.FastRandom.pick_random"},"Math.FastRandom.randomBool":{"kind":-1,"retType":"boolean","attributes":{"jsDoc":"@returns a random boolean value"},"parameters":[],"isInstance":true,"pyQName":"Math.FastRandom.random_bool"},"Math.FastRandom.percentChance":{"kind":-1,"retType":"boolean","attributes":{"paramHelp":{"percent":"the percentage chance that the returned value will be true from 0 - 100"},"jsDoc":"@returns a boolean with approximately the given percent chance to be true or false"},"parameters":[{"name":"percent","description":"the percentage chance that the returned value will be true from 0 - 100"}],"isInstance":true,"pyQName":"Math.FastRandom.percent_chance"},"Math.FastRandom.reset":{"kind":-1,"attributes":{"jsDoc":"Reset the state to the current seed"},"parameters":[],"isInstance":true},"scene.systemMenu":{"kind":5,"retType":""},"scene.systemMenu.CardState":{"kind":6,"retType":"scene.systemMenu.CardState","extendsTypes":["scene.systemMenu.CardState","Number"]},"scene.systemMenu.CardState.Selected":{"retType":"scene.systemMenu.CardState.Selected","extendsTypes":["scene.systemMenu.CardState.Selected","Number"],"pyQName":"scene.systemMenu.CardState.SELECTED"},"scene.systemMenu.CardState.Active":{"retType":"scene.systemMenu.CardState.Active","extendsTypes":["scene.systemMenu.CardState.Active","Number"],"pyQName":"scene.systemMenu.CardState.ACTIVE"},"scene.systemMenu.CardState.None":{"retType":"scene.systemMenu.CardState.None","extendsTypes":["scene.systemMenu.CardState.None","Number"],"pyQName":"scene.systemMenu.CardState.NONE"},"scene.systemMenu.MenuTheme":{"kind":9,"retType":"scene.systemMenu.MenuTheme","extendsTypes":[]},"scene.systemMenu.MenuTheme.cardSpacing":{"kind":2,"retType":"number","isInstance":true,"pyQName":"scene.systemMenu.MenuTheme.card_spacing"},"scene.systemMenu.MenuTheme.cardWidth":{"kind":2,"retType":"number","isInstance":true,"pyQName":"scene.systemMenu.MenuTheme.card_width"},"scene.systemMenu.MenuTheme.cardsPerRow":{"kind":2,"retType":"number","isInstance":true,"pyQName":"scene.systemMenu.MenuTheme.cards_per_row"},"scene.systemMenu.MenuTheme.padding":{"kind":2,"retType":"number","isInstance":true},"scene.systemMenu.MenuTheme.cardsTop":{"kind":2,"retType":"number","isInstance":true,"pyQName":"scene.systemMenu.MenuTheme.cards_top"},"scene.systemMenu.MenuTheme.infoTop":{"kind":2,"retType":"number","isInstance":true,"pyQName":"scene.systemMenu.MenuTheme.info_top"},"scene.systemMenu.MenuTheme.headerText":{"kind":2,"retType":"string","isInstance":true,"pyQName":"scene.systemMenu.MenuTheme.header_text"},"scene.systemMenu.MenuTheme.headerFont":{"kind":2,"retType":"image.Font","isInstance":true,"pyQName":"scene.systemMenu.MenuTheme.header_font"},"scene.systemMenu.MenuTheme.infoFont":{"kind":2,"retType":"image.Font","isInstance":true,"pyQName":"scene.systemMenu.MenuTheme.info_font"},"scene.systemMenu.MenuTheme.selectedCard":{"kind":2,"retType":"Image","isInstance":true,"pyQName":"scene.systemMenu.MenuTheme.selected_card"},"scene.systemMenu.MenuTheme.activeCard":{"kind":2,"retType":"Image","isInstance":true,"pyQName":"scene.systemMenu.MenuTheme.active_card"},"scene.systemMenu.MenuTheme.basicCard":{"kind":2,"retType":"Image","isInstance":true,"pyQName":"scene.systemMenu.MenuTheme.basic_card"},"scene.systemMenu.MenuOption":{"kind":8,"retType":"scene.systemMenu.MenuOption","extendsTypes":[]},"scene.systemMenu.MenuOption.__constructor":{"kind":-3,"parameters":[{"name":"iconImage","type":"Image"},{"name":"getText","type":"() => string","handlerParameters":[]},{"name":"action","type":"() => void","handlerParameters":[]}],"isInstance":true},"scene.systemMenu.MenuOption.show":{"kind":-1,"parameters":[],"isInstance":true},"scene.systemMenu.MenuOption.position":{"kind":-1,"parameters":[{"name":"left"},{"name":"top"}],"isInstance":true},"scene.systemMenu.MenuOption.setOffset":{"kind":-1,"parameters":[{"name":"offset"}],"isInstance":true,"pyQName":"scene.systemMenu.MenuOption.set_offset"},"scene.systemMenu.MenuOption.setTheme":{"kind":-1,"parameters":[{"name":"theme","type":"scene.systemMenu.MenuTheme"}],"isInstance":true,"pyQName":"scene.systemMenu.MenuOption.set_theme"},"scene.systemMenu.MenuOption.setState":{"kind":-1,"parameters":[{"name":"state","type":"scene.systemMenu.CardState","isEnum":true}],"isInstance":true,"pyQName":"scene.systemMenu.MenuOption.set_state"},"scene.systemMenu.MenuOption.dispose":{"kind":-1,"parameters":[],"isInstance":true},"scene.systemMenu.PauseMenu":{"kind":8,"retType":"scene.systemMenu.PauseMenu","extendsTypes":[]},"scene.systemMenu.PauseMenu.__constructor":{"kind":-3,"parameters":[{"name":"generator","type":"() => scene.systemMenu.MenuOption[]","handlerParameters":[]},{"name":"theme","type":"scene.systemMenu.MenuTheme","initializer":"undefined"}],"isInstance":true},"scene.systemMenu.PauseMenu.show":{"kind":-1,"parameters":[],"isInstance":true},"scene.systemMenu.PauseMenu.onUpdate":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"scene.systemMenu.PauseMenu.on_update"},"scene.systemMenu.PauseMenu.setSelection":{"kind":-1,"parameters":[{"name":"selection"}],"isInstance":true,"pyQName":"scene.systemMenu.PauseMenu.set_selection"},"scene.systemMenu.PauseMenu.drawText":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"scene.systemMenu.PauseMenu.draw_text"},"scene.systemMenu.PauseMenu.dispose":{"kind":-1,"parameters":[],"isInstance":true},"scene.systemMenu.closeMenu":{"kind":-3,"parameters":[],"pyQName":"scene.systemMenu.close_menu"},"scene.systemMenu.buildOptionList":{"kind":-3,"retType":"scene.systemMenu.MenuOption[]","parameters":[],"pyQName":"scene.systemMenu.build_option_list"},"scene.systemMenu.buildMenuTheme":{"kind":-3,"retType":"scene.systemMenu.MenuTheme","parameters":[{"name":"cardWidth"},{"name":"cardSpacing"},{"name":"infoFont","type":"image.Font","initializer":"undefined"},{"name":"headerFont","type":"image.Font","initializer":"undefined"}],"pyQName":"scene.systemMenu.build_menu_theme"},"scene.systemMenu.addEntry":{"kind":-3,"parameters":[{"name":"name","type":"() => string","handlerParameters":[]},{"name":"clickHandler","type":"() => void","handlerParameters":[]},{"name":"icon","type":"Image"}],"pyQName":"scene.systemMenu.add_entry"},"scene.systemMenu.register":{"kind":-3,"parameters":[]},"scene.systemMenu.showSystemMenu":{"kind":-3,"parameters":[],"pyQName":"scene.systemMenu.show_system_menu"},"scene.systemMenu.isVisible":{"kind":-3,"retType":"boolean","parameters":[],"pyQName":"scene.systemMenu.is_visible"},"scene.systemMenu.CARD_NORMAL":{"kind":4,"retType":"Image"},"scene.systemMenu.CARD_SELECTED":{"kind":4,"retType":"Image"},"scene.systemMenu.CARD_ACTIVE":{"kind":4,"retType":"Image"},"scene.systemMenu.VOLUME_UP_ICON":{"kind":4,"retType":"Image"},"scene.systemMenu.BRIGHTNESS_DOWN_ICON":{"kind":4,"retType":"Image"},"scene.systemMenu.CLOSE_MENU_ICON":{"kind":4,"retType":"Image"},"scene.systemMenu.VOLUME_DOWN_ICON":{"kind":4,"retType":"Image"},"scene.systemMenu.SLEEP_ICON":{"kind":4,"retType":"Image"},"scene.systemMenu.CONSOLE_ICON":{"kind":4,"retType":"Image"},"scene.systemMenu.BRIGHTNESS_UP_ICON":{"kind":4,"retType":"Image"},"scene.systemMenu.STATS_ICON":{"kind":4,"retType":"Image"},"game.consoleOverlay":{"kind":5,"retType":""},"game.consoleOverlay.isVisible":{"kind":-3,"retType":"boolean","parameters":[],"pyQName":"game.consoleOverlay.is_visible"},"game.consoleOverlay.clear":{"kind":-3,"parameters":[]},"game.consoleOverlay.setVisible":{"kind":-3,"parameters":[{"name":"value","type":"boolean"},{"name":"col","initializer":"undefined"}],"pyQName":"game.consoleOverlay.set_visible"},"game.consoleOverlay.draw":{"kind":-3,"parameters":[]},"__internal.__spriteSpeedPicker":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"speed":"50"},"blockId":"spriteSpeedPicker","block":"%speed","shim":"TD_ID","paramFieldEditor":{"speed":"speed"},"colorSecondary":"#FFFFFF","weight":0,"blockHidden":true,"paramFieldEditorOptions":{"speed":{"decompileLiterals":"1","format":"{0}pix/s"}},"paramHelp":{"speed":"the speed, eg: 50"},"jsDoc":"A speed picker","_def":{"parts":[{"kind":"param","name":"speed","ref":false}],"parameters":[{"kind":"param","name":"speed","ref":false}]}},"parameters":[{"name":"speed","description":"the speed, eg: 50","default":"50"}]},"__internal.__accSpeedPicker":{"kind":-3,"retType":"number","attributes":{"blockId":"spriteAccPicker","block":"%acceleration","shim":"TD_ID","paramFieldEditor":{"speed":"speed"},"colorSecondary":"#FFFFFF","weight":0,"blockHidden":true,"paramFieldEditorOptions":{"speed":{"decompileLiterals":"1","format":"{0}pix/s²"}},"paramHelp":{"acceleration":"the acceleration in pixel/sec^2"},"jsDoc":"A sprite acceleration picker","_def":{"parts":[{"kind":"param","name":"acceleration","ref":false}],"parameters":[{"kind":"param","name":"acceleration","ref":false}]}},"parameters":[{"name":"acceleration","description":"the acceleration in pixel/sec^2"}]},"particles":{"kind":5,"retType":""},"particles.Particle":{"kind":8,"retType":"particles.Particle","attributes":{"maxBgInstances":"200","jsDoc":"A single particle"},"extendsTypes":[]},"particles.Particle._x":{"kind":2,"retType":"Fx8","isInstance":true},"particles.Particle._y":{"kind":2,"retType":"Fx8","isInstance":true},"particles.Particle.vx":{"kind":2,"retType":"Fx8","isInstance":true},"particles.Particle.vy":{"kind":2,"retType":"Fx8","isInstance":true},"particles.Particle.lifespan":{"kind":2,"retType":"number","isInstance":true},"particles.Particle.next":{"kind":2,"retType":"particles.Particle","isInstance":true},"particles.Particle.data":{"kind":2,"retType":"number","isInstance":true},"particles.Particle.color":{"kind":2,"retType":"number","isInstance":true},"particles.ParticleAnchor":{"kind":9,"retType":"particles.ParticleAnchor","attributes":{"jsDoc":"An anchor for a Particle to originate from"},"extendsTypes":[]},"particles.ParticleAnchor.x":{"kind":2,"retType":"number","isInstance":true},"particles.ParticleAnchor.y":{"kind":2,"retType":"number","isInstance":true},"particles.ParticleAnchor.vx":{"kind":2,"retType":"number","isInstance":true},"particles.ParticleAnchor.vy":{"kind":2,"retType":"number","isInstance":true},"particles.ParticleAnchor.width":{"kind":2,"retType":"number","isInstance":true},"particles.ParticleAnchor.height":{"kind":2,"retType":"number","isInstance":true},"particles.ParticleAnchor.image":{"kind":2,"retType":"Image","isInstance":true},"particles.ParticleAnchor.flags":{"kind":2,"retType":"number","isInstance":true},"particles.ParticleAnchor.setImage":{"kind":2,"retType":"(i: Image) => void","isInstance":true,"pyQName":"particles.ParticleAnchor.set_image"},"particles.ParticleSource":{"kind":8,"retType":"particles.ParticleSource","attributes":{"jsDoc":"A source of particles"},"extendsTypes":["particles.ParticleSource","sprites.BaseSprite","SpriteLike"]},"particles.ParticleSource.priority":{"kind":2,"retType":"number","attributes":{"jsDoc":"A relative ranking of this sources priority\nWhen necessary, a source with a lower priority will\nbe culled before a source with a higher priority."},"isInstance":true},"particles.ParticleSource._dt":{"kind":2,"retType":"number","isInstance":true},"particles.ParticleSource.anchor":{"kind":2,"retType":"particles.ParticleAnchor","attributes":{"jsDoc":"The anchor this source is currently attached to"},"isInstance":true},"particles.ParticleSource.lifespan":{"kind":2,"retType":"number","attributes":{"jsDoc":"Time to live in milliseconds. The lifespan decreases by 1 on each millisecond\nand the source gets destroyed when it reaches 0."},"isInstance":true},"particles.ParticleSource.__constructor":{"kind":-3,"attributes":{"paramHelp":{"anchor":"to emit particles from","particlesPerSecond":"rate at which particles are emitted","factory":"[optional] factory to generate particles with; otherwise,"}},"parameters":[{"name":"anchor","description":"to emit particles from","type":"particles.ParticleAnchor"},{"name":"particlesPerSecond","description":"rate at which particles are emitted"},{"name":"factory","description":"[optional] factory to generate particles with; otherwise,","type":"particles.ParticleFactory","initializer":"undefined"}],"isInstance":true},"particles.ParticleSource.__draw":{"kind":-1,"parameters":[{"name":"camera","type":"scene.Camera"}],"isInstance":true},"particles.ParticleSource._update":{"kind":-1,"parameters":[{"name":"dt"}],"isInstance":true},"particles.ParticleSource._prune":{"kind":-1,"parameters":[],"isInstance":true},"particles.ParticleSource.setAcceleration":{"kind":-1,"attributes":{"jsDoc":"Sets the acceleration applied to the particles"},"parameters":[{"name":"ax"},{"name":"ay"}],"isInstance":true,"pyQName":"particles.ParticleSource.set_acceleration"},"particles.ParticleSource.setEnabled":{"kind":-1,"attributes":{"paramHelp":{"on":""},"jsDoc":"Enables or disables particles"},"parameters":[{"name":"on","type":"boolean"}],"isInstance":true,"pyQName":"particles.ParticleSource.set_enabled"},"particles.ParticleSource.setRelativeToCamera":{"kind":-1,"attributes":{"paramHelp":{"on":""},"jsDoc":"Sets whether the particle source is drawn relative to the camera or not"},"parameters":[{"name":"on","type":"boolean"}],"isInstance":true,"pyQName":"particles.ParticleSource.set_relative_to_camera"},"particles.ParticleSource.enabled":{"kind":-2,"retType":"boolean","attributes":{"jsDoc":"Set whether this source is currently enabled (emitting particles) or not"},"isInstance":true,"isReadOnly":true},"particles.ParticleSource.enabled@set":{"kind":-2,"retType":"boolean","attributes":{"jsDoc":"Set whether this source is currently enabled (emitting particles) or not"},"isInstance":true},"particles.ParticleSource.destroy":{"kind":-1,"attributes":{"jsDoc":"Destroy the source"},"parameters":[],"isInstance":true},"particles.ParticleSource.clear":{"kind":-1,"attributes":{"jsDoc":"Clear all particles emitted from this source"},"parameters":[],"isInstance":true},"particles.ParticleSource.setAnchor":{"kind":-1,"attributes":{"paramHelp":{"anchor":""},"jsDoc":"Set a anchor for particles to be emitted from"},"parameters":[{"name":"anchor","type":"particles.ParticleAnchor"}],"isInstance":true,"pyQName":"particles.ParticleSource.set_anchor"},"particles.ParticleSource.setRate":{"kind":-1,"attributes":{"paramHelp":{"particlesPerSecond":""},"jsDoc":"Sets the number of particle created per second"},"parameters":[{"name":"particlesPerSecond"}],"isInstance":true,"pyQName":"particles.ParticleSource.set_rate"},"particles.ParticleSource.factory":{"kind":-2,"retType":"particles.ParticleFactory","isInstance":true,"isReadOnly":true},"particles.ParticleSource.setFactory":{"kind":-1,"attributes":{"paramHelp":{"factory":""},"jsDoc":"Sets the particle factory"},"parameters":[{"name":"factory","type":"particles.ParticleFactory"}],"isInstance":true,"pyQName":"particles.ParticleSource.set_factory"},"particles.defaultFactory":{"kind":4,"retType":"particles.SprayFactory","attributes":{"whenUsed":"true"},"pyQName":"particles.default_factory"},"particles.createParticleSource":{"kind":-3,"retType":"particles.ParticleSource","attributes":{"paramHelp":{"sprite":"@param particlesPerSecond number of particles created per second"},"jsDoc":"Creates a new source of particles attached to a sprite"},"parameters":[{"name":"sprite","description":"@param particlesPerSecond number of particles created per second","type":"Sprite"},{"name":"particlesPerSecond"}],"pyQName":"particles.create_particle_source"},"particles.FireSource":{"kind":8,"retType":"particles.FireSource","attributes":{"jsDoc":"A source of particles where particles will occasionally change speed based off of each other"},"extendsTypes":["particles.FireSource","particles.ParticleSource","sprites.BaseSprite","SpriteLike"]},"particles.FireSource.__constructor":{"kind":-3,"parameters":[{"name":"anchor","type":"particles.ParticleAnchor"},{"name":"particlesPerSecond"},{"name":"factory","type":"particles.ParticleFactory","initializer":"undefined"}],"isInstance":true},"particles.FireSource.updateParticle":{"kind":-1,"parameters":[{"name":"p","type":"particles.Particle"},{"name":"fixedDt","type":"Fx8"}],"isInstance":true,"pyQName":"particles.FireSource.update_particle"},"particles.BubbleSource":{"kind":8,"retType":"particles.BubbleSource","attributes":{"jsDoc":"A source of particles where the particles oscillate horizontally, and occasionally change\nbetween a given number of defined states"},"extendsTypes":["particles.BubbleSource","particles.ParticleSource","sprites.BaseSprite","SpriteLike"]},"particles.BubbleSource.stateChangePercentage":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.BubbleSource.state_change_percentage"},"particles.BubbleSource.oscillationPercentage":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.BubbleSource.oscillation_percentage"},"particles.BubbleSource.__constructor":{"kind":-3,"parameters":[{"name":"anchor","type":"particles.ParticleAnchor"},{"name":"particlesPerSecond"},{"name":"maxState"},{"name":"factory","type":"particles.ParticleFactory","initializer":"undefined"}],"isInstance":true},"particles.BubbleSource.updateParticle":{"kind":-1,"parameters":[{"name":"p","type":"particles.Particle"},{"name":"fixedDt","type":"Fx8"}],"isInstance":true,"pyQName":"particles.BubbleSource.update_particle"},"particles.clearAll":{"kind":-3,"parameters":[],"pyQName":"particles.clear_all"},"particles.disableAll":{"kind":-3,"attributes":{"jsDoc":"Stop all particle sources from creating any new particles"},"parameters":[],"pyQName":"particles.disable_all"},"particles.enableAll":{"kind":-3,"attributes":{"jsDoc":"Allow all particle sources to create any new particles"},"parameters":[],"pyQName":"particles.enable_all"},"particles.cacheSin":{"kind":-3,"retType":"Fx8[]","attributes":{"paramHelp":{"slices":"number of cached sin values to make"},"jsDoc":"@returns array of cached sin values between 0 and 360 degrees"},"parameters":[{"name":"slices","description":"number of cached sin values to make"}],"pyQName":"particles.cache_sin"},"particles.cacheCos":{"kind":-3,"retType":"Fx8[]","attributes":{"paramHelp":{"slices":"number of cached cos values to make"},"jsDoc":"@returns array of cached cos values between 0 and 360 degrees"},"parameters":[{"name":"slices","description":"number of cached cos values to make"}],"pyQName":"particles.cache_cos"},"particles.ParticleFactory":{"kind":8,"retType":"particles.ParticleFactory","attributes":{"jsDoc":"A factory for generating particles"},"extendsTypes":["particles.ParticleFactory"]},"particles.ParticleFactory.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"particles.ParticleFactory.createParticle":{"kind":-1,"retType":"particles.Particle","attributes":{"paramHelp":{"anchor":""},"jsDoc":"Generate a particle at the position of the given anchor"},"parameters":[{"name":"anchor","type":"particles.ParticleAnchor"}],"isInstance":true,"pyQName":"particles.ParticleFactory.create_particle"},"particles.ParticleFactory.drawParticle":{"kind":-1,"attributes":{"paramHelp":{"particle":"@param x ","y":""},"jsDoc":"Draw the given particle at the given location"},"parameters":[{"name":"particle","description":"@param x ","type":"particles.Particle"},{"name":"x","type":"Fx8"},{"name":"y","type":"Fx8"}],"isInstance":true,"pyQName":"particles.ParticleFactory.draw_particle"},"particles.SprayFactory":{"kind":8,"retType":"particles.SprayFactory","attributes":{"jsDoc":"A factory for creating a spray of particles"},"extendsTypes":["particles.SprayFactory","particles.ParticleFactory"]},"particles.SprayFactory.__constructor":{"kind":-3,"parameters":[{"name":"speed"},{"name":"centerDegrees"},{"name":"arcDegrees"}],"isInstance":true},"particles.SprayFactory.createParticle":{"kind":-1,"retType":"particles.Particle","parameters":[{"name":"anchor","type":"particles.ParticleAnchor"}],"isInstance":true,"pyQName":"particles.SprayFactory.create_particle"},"particles.SprayFactory.drawParticle":{"kind":-1,"parameters":[{"name":"particle","type":"particles.Particle"},{"name":"x","type":"Fx8"},{"name":"y","type":"Fx8"}],"isInstance":true,"pyQName":"particles.SprayFactory.draw_particle"},"particles.SprayFactory.setSpeed":{"kind":-1,"parameters":[{"name":"pixelsPerSecond"}],"isInstance":true,"pyQName":"particles.SprayFactory.set_speed"},"particles.SprayFactory.setDirection":{"kind":-1,"parameters":[{"name":"centerDegrees"},{"name":"arcDegrees"}],"isInstance":true,"pyQName":"particles.SprayFactory.set_direction"},"particles.AreaFactory":{"kind":8,"retType":"particles.AreaFactory","attributes":{"jsDoc":"A factory for creating particles within rectangular area"},"extendsTypes":["particles.AreaFactory","particles.SprayFactory","particles.ParticleFactory"]},"particles.AreaFactory.xRange":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.AreaFactory.x_range"},"particles.AreaFactory.yRange":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.AreaFactory.y_range"},"particles.AreaFactory.minLifespan":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.AreaFactory.min_lifespan"},"particles.AreaFactory.maxLifespan":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.AreaFactory.max_lifespan"},"particles.AreaFactory.__constructor":{"kind":-3,"parameters":[{"name":"xRange"},{"name":"yRange"},{"name":"minLifespan","initializer":"undefined"},{"name":"maxLifespan","initializer":"undefined"}],"isInstance":true},"particles.AreaFactory.createParticle":{"kind":-1,"retType":"particles.Particle","parameters":[{"name":"anchor","type":"particles.ParticleAnchor"}],"isInstance":true,"pyQName":"particles.AreaFactory.create_particle"},"particles.AreaFactory.drawParticle":{"kind":-1,"parameters":[{"name":"p","type":"particles.Particle"},{"name":"x","type":"Fx8"},{"name":"y","type":"Fx8"}],"isInstance":true,"pyQName":"particles.AreaFactory.draw_particle"},"particles.TrailFactory":{"kind":8,"retType":"particles.TrailFactory","attributes":{"jsDoc":"A factory for creating a trail that is emitted by sprites."},"extendsTypes":["particles.TrailFactory","particles.ParticleFactory"]},"particles.TrailFactory.minLifespan":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.TrailFactory.min_lifespan"},"particles.TrailFactory.maxLifespan":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.TrailFactory.max_lifespan"},"particles.TrailFactory.xRange":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.TrailFactory.x_range"},"particles.TrailFactory.yRange":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.TrailFactory.y_range"},"particles.TrailFactory.__constructor":{"kind":-3,"parameters":[{"name":"sprite","type":"particles.ParticleAnchor"},{"name":"minLifespan"},{"name":"maxLifespan"}],"isInstance":true},"particles.TrailFactory.createParticle":{"kind":-1,"retType":"particles.Particle","parameters":[{"name":"anchor","type":"particles.ParticleAnchor"}],"isInstance":true,"pyQName":"particles.TrailFactory.create_particle"},"particles.TrailFactory.drawParticle":{"kind":-1,"parameters":[{"name":"p","type":"particles.Particle"},{"name":"x","type":"Fx8"},{"name":"y","type":"Fx8"}],"isInstance":true,"pyQName":"particles.TrailFactory.draw_particle"},"particles.ShapeFactory":{"kind":8,"retType":"particles.ShapeFactory","attributes":{"jsDoc":"A factory for creating particles with the provided shapes fall down the screen.\n* Any pixels assigned to 0xF (black) in the provided shape will be replaced with a\nrandom color for each particle."},"extendsTypes":["particles.ShapeFactory","particles.AreaFactory","particles.SprayFactory","particles.ParticleFactory"]},"particles.ShapeFactory.__constructor":{"kind":-3,"parameters":[{"name":"xRange"},{"name":"yRange"},{"name":"source","type":"Image"}],"isInstance":true},"particles.ShapeFactory.addShape":{"kind":-1,"attributes":{"paramHelp":{"shape":""},"jsDoc":"Add another possible shape for a particle to display as"},"parameters":[{"name":"shape","type":"Image"}],"isInstance":true,"pyQName":"particles.ShapeFactory.add_shape"},"particles.ShapeFactory.drawParticle":{"kind":-1,"parameters":[{"name":"p","type":"particles.Particle"},{"name":"x","type":"Fx8"},{"name":"y","type":"Fx8"}],"isInstance":true,"pyQName":"particles.ShapeFactory.draw_particle"},"particles.ShapeFactory.createParticle":{"kind":-1,"retType":"particles.Particle","parameters":[{"name":"anchor","type":"particles.ParticleAnchor"}],"isInstance":true,"pyQName":"particles.ShapeFactory.create_particle"},"particles.ConfettiFactory":{"kind":8,"retType":"particles.ConfettiFactory","extendsTypes":["particles.ConfettiFactory","particles.ShapeFactory","particles.AreaFactory","particles.SprayFactory","particles.ParticleFactory"]},"particles.ConfettiFactory.__constructor":{"kind":-3,"parameters":[{"name":"xRange"},{"name":"yRange"}],"isInstance":true},"particles.FireFactory":{"kind":8,"retType":"particles.FireFactory","extendsTypes":["particles.FireFactory","particles.ParticleFactory"]},"particles.FireFactory.__constructor":{"kind":-3,"parameters":[{"name":"radius"}],"isInstance":true},"particles.FireFactory.createParticle":{"kind":-1,"retType":"particles.Particle","parameters":[{"name":"anchor","type":"particles.ParticleAnchor"}],"isInstance":true,"pyQName":"particles.FireFactory.create_particle"},"particles.FireFactory.drawParticle":{"kind":-1,"parameters":[{"name":"p","type":"particles.Particle"},{"name":"x","type":"Fx8"},{"name":"y","type":"Fx8"}],"isInstance":true,"pyQName":"particles.FireFactory.draw_particle"},"particles.RadialFactory":{"kind":8,"retType":"particles.RadialFactory","extendsTypes":["particles.RadialFactory","particles.ParticleFactory"]},"particles.RadialFactory.__constructor":{"kind":-3,"parameters":[{"name":"radius"},{"name":"speed"},{"name":"spread"},{"name":"colors","type":"number[]","initializer":"undefined"}],"isInstance":true},"particles.RadialFactory.createParticle":{"kind":-1,"retType":"particles.Particle","parameters":[{"name":"anchor","type":"particles.ParticleAnchor"}],"isInstance":true,"pyQName":"particles.RadialFactory.create_particle"},"particles.RadialFactory.drawParticle":{"kind":-1,"parameters":[{"name":"p","type":"particles.Particle"},{"name":"x","type":"Fx8"},{"name":"y","type":"Fx8"}],"isInstance":true,"pyQName":"particles.RadialFactory.draw_particle"},"particles.RadialFactory.setRadius":{"kind":-1,"parameters":[{"name":"r"}],"isInstance":true,"pyQName":"particles.RadialFactory.set_radius"},"particles.RadialFactory.setSpeed":{"kind":-1,"parameters":[{"name":"s"}],"isInstance":true,"pyQName":"particles.RadialFactory.set_speed"},"particles.RadialFactory.setSpread":{"kind":-1,"parameters":[{"name":"s"}],"isInstance":true,"pyQName":"particles.RadialFactory.set_spread"},"particles.AshFactory":{"kind":8,"retType":"particles.AshFactory","extendsTypes":["particles.AshFactory","particles.AreaFactory","particles.SprayFactory","particles.ParticleFactory"]},"particles.AshFactory.__constructor":{"kind":-3,"parameters":[{"name":"anchor","type":"particles.ParticleAnchor"},{"name":"updateImage","type":"boolean","initializer":"undefined"},{"name":"percentKept","initializer":"20"}],"isInstance":true},"particles.AshFactory.createParticle":{"kind":-1,"retType":"particles.Particle","parameters":[{"name":"anchor","type":"particles.ParticleAnchor"}],"isInstance":true,"pyQName":"particles.AshFactory.create_particle"},"particles.AshFactory.drawParticle":{"kind":-1,"parameters":[{"name":"p","type":"particles.Particle"},{"name":"x","type":"Fx8"},{"name":"y","type":"Fx8"}],"isInstance":true,"pyQName":"particles.AshFactory.draw_particle"},"particles.BubbleFactory":{"kind":8,"retType":"particles.BubbleFactory","extendsTypes":["particles.BubbleFactory","particles.ParticleFactory"]},"particles.BubbleFactory.minLifespan":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.BubbleFactory.min_lifespan"},"particles.BubbleFactory.maxLifespan":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.BubbleFactory.max_lifespan"},"particles.BubbleFactory.xRange":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.BubbleFactory.x_range"},"particles.BubbleFactory.yRange":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.BubbleFactory.y_range"},"particles.BubbleFactory.__constructor":{"kind":-3,"parameters":[{"name":"sprite","type":"particles.ParticleAnchor"},{"name":"minLifespan"},{"name":"maxLifespan"}],"isInstance":true},"particles.BubbleFactory.stateCount":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"particles.BubbleFactory.state_count"},"particles.BubbleFactory.createParticle":{"kind":-1,"retType":"particles.Particle","parameters":[{"name":"anchor","type":"particles.ParticleAnchor"}],"isInstance":true,"pyQName":"particles.BubbleFactory.create_particle"},"particles.BubbleFactory.drawParticle":{"kind":-1,"parameters":[{"name":"p","type":"particles.Particle"},{"name":"x","type":"Fx8"},{"name":"y","type":"Fx8"}],"isInstance":true,"pyQName":"particles.BubbleFactory.draw_particle"},"particles.StarFactory":{"kind":8,"retType":"particles.StarFactory","extendsTypes":["particles.StarFactory","particles.ParticleFactory"]},"particles.StarFactory.minRate":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.StarFactory.min_rate"},"particles.StarFactory.maxRate":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.StarFactory.max_rate"},"particles.StarFactory.images":{"kind":2,"retType":"Image[]","isInstance":true},"particles.StarFactory.__constructor":{"kind":-3,"parameters":[{"name":"possibleColors","type":"number[]","initializer":"undefined"},{"name":"minRate","initializer":"15"},{"name":"maxRate","initializer":"25"}],"isInstance":true},"particles.StarFactory.createParticle":{"kind":-1,"retType":"particles.Particle","parameters":[{"name":"anchor","type":"particles.ParticleAnchor"}],"isInstance":true,"pyQName":"particles.StarFactory.create_particle"},"particles.StarFactory.drawParticle":{"kind":-1,"parameters":[{"name":"p","type":"particles.Particle"},{"name":"x","type":"Fx8"},{"name":"y","type":"Fx8"}],"isInstance":true,"pyQName":"particles.StarFactory.draw_particle"},"particles.CloudFactory":{"kind":8,"retType":"particles.CloudFactory","extendsTypes":["particles.CloudFactory","particles.ParticleFactory"]},"particles.CloudFactory.minRate":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.CloudFactory.min_rate"},"particles.CloudFactory.maxRate":{"kind":2,"retType":"number","isInstance":true,"pyQName":"particles.CloudFactory.max_rate"},"particles.CloudFactory.clouds":{"kind":2,"retType":"Image[]","isInstance":true},"particles.CloudFactory.camera":{"kind":2,"retType":"scene.Camera","isInstance":true},"particles.CloudFactory.__constructor":{"kind":-3,"parameters":[{"name":"minRate","initializer":"8"},{"name":"maxRate","initializer":"12"}],"isInstance":true},"particles.CloudFactory.createParticle":{"kind":-1,"retType":"particles.Particle","parameters":[{"name":"anchor","type":"particles.ParticleAnchor"}],"isInstance":true,"pyQName":"particles.CloudFactory.create_particle"},"particles.CloudFactory.drawParticle":{"kind":-1,"parameters":[{"name":"p","type":"particles.Particle"},{"name":"x","type":"Fx8"},{"name":"y","type":"Fx8"}],"isInstance":true,"pyQName":"particles.CloudFactory.draw_particle"},"effects":{"kind":5,"retType":""},"effects.BackgroundEffect":{"kind":9,"retType":"effects.BackgroundEffect","attributes":{"fixedInstances":"true"},"extendsTypes":["effects.BackgroundEffect"]},"effects.BackgroundEffect.startScreenEffect":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"effects.BackgroundEffect.start_screen_effect"},"effects.ParticleEffect":{"kind":8,"retType":"effects.ParticleEffect","attributes":{"fixedInstances":"true"},"extendsTypes":["effects.ParticleEffect"]},"effects.ParticleEffect.__constructor":{"kind":-3,"parameters":[{"name":"defaultParticlesPerSecond"},{"name":"defaultLifespan"},{"name":"sourceFactory","type":"(anchor: particles.ParticleAnchor, particlesPerSecond: number) => particles.ParticleSource","handlerParameters":[{"name":"anchor","type":"particles.ParticleAnchor"},{"name":"particlesPerSecond","type":"number"}]}],"isInstance":true},"effects.ParticleEffect.start":{"kind":-1,"attributes":{"paramHelp":{"anchor":"@param duration","particlesPerSecond":""},"jsDoc":"Attaches a new particle animation to the sprite or anchor for a short period of time"},"parameters":[{"name":"anchor","description":"@param duration","type":"particles.ParticleAnchor"},{"name":"duration","initializer":"undefined"},{"name":"particlesPerSecond","initializer":"undefined"},{"name":"relativeToCamera","type":"boolean","initializer":"undefined"}],"isInstance":true},"effects.ParticleEffect.destroy":{"kind":-1,"attributes":{"paramHelp":{"sprite":"@param duration how long the sprite will remain on the screen. If set to 0 or undefined,","particlesPerSecond":""},"jsDoc":"Destroy the provided sprite with an effect\n\nuses the default rate for this effect."},"parameters":[{"name":"anchor","type":"Sprite"},{"name":"duration","initializer":"undefined"},{"name":"particlesPerSecond","initializer":"undefined"}],"isInstance":true},"effects.ScreenEffect":{"kind":8,"retType":"effects.ScreenEffect","attributes":{"fixedInstances":"true"},"extendsTypes":["effects.ScreenEffect","effects.ParticleEffect","effects.BackgroundEffect"]},"effects.ScreenEffect.__constructor":{"kind":-3,"parameters":[{"name":"anchorDefault"},{"name":"sceneDefault"},{"name":"defaultLifespan"},{"name":"sourceFactory","type":"(anchor: particles.ParticleAnchor, particlesPerSecond: number) => particles.ParticleSource","handlerParameters":[{"name":"anchor","type":"particles.ParticleAnchor"},{"name":"particlesPerSecond","type":"number"}]}],"isInstance":true},"effects.ScreenEffect.startScreenEffect":{"kind":-1,"attributes":{"blockId":"particlesStartScreenAnimation","block":"start screen %effect effect || for %duration ms","_shadowOverrides":{"duration":"timePicker"},"blockNamespace":"scene","group":"Effects","blockGap":"8","weight":90,"help":"effects/start-screen-effect","paramHelp":{"particlesPerSecond":"@param duration"},"jsDoc":"Creates a new effect that occurs over the entire screen","_def":{"parts":[{"kind":"label","text":"start screen ","style":[]},{"kind":"param","name":"effect","ref":false},{"kind":"label","text":" effect ","style":[]}],"parameters":[{"kind":"param","name":"effect","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":" for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"duration","initializer":"undefined"},{"name":"particlesPerSecond","description":"@param duration","initializer":"undefined"}],"isInstance":true,"pyQName":"effects.ScreenEffect.start_screen_effect"},"effects.ScreenEffect.endScreenEffect":{"kind":-1,"attributes":{"blockId":"particlesEndScreenAnimation","block":"end screen %effect effect","blockNamespace":"scene","group":"Effects","blockGap":"8","weight":80,"help":"effects/end-screen-effect","paramHelp":{"particlesPerSecond":""},"jsDoc":"If this effect is currently occurring as a full screen effect, stop producing particles and end the effect","_def":{"parts":[{"kind":"label","text":"end screen ","style":[]},{"kind":"param","name":"effect","ref":false},{"kind":"label","text":" effect","style":[]}],"parameters":[{"kind":"param","name":"effect","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"effects.ScreenEffect.end_screen_effect"},"effects.clearParticles":{"kind":-3,"attributes":{"blockId":"particlesclearparticles","block":"clear effects on %anchor=variables_get(mySprite)","blockNamespace":"sprites","group":"Effects","weight":89,"help":"effects/clear-particles","paramHelp":{"anchor":"the anchor to remove effects from"},"jsDoc":"Removes all effects attached to the given anchor","_def":{"parts":[{"kind":"label","text":"clear effects on ","style":[]},{"kind":"param","name":"anchor","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"}],"parameters":[{"kind":"param","name":"anchor","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"}]}},"parameters":[{"name":"anchor","description":"the anchor to remove effects from","type":"Sprite | particles.ParticleAnchor"}],"pyQName":"effects.clear_particles"},"effects.spray":{"kind":4,"retType":"effects.ParticleEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"spray","_def":{"parts":[{"kind":"label","text":"spray","style":[]}],"parameters":[]}}},"effects.trail":{"kind":4,"retType":"effects.ParticleEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"trail","_def":{"parts":[{"kind":"label","text":"trail","style":[]}],"parameters":[]}}},"effects.fountain":{"kind":4,"retType":"effects.ParticleEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"fountain","_def":{"parts":[{"kind":"label","text":"fountain","style":[]}],"parameters":[]}}},"effects.confetti":{"kind":4,"retType":"effects.ScreenEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"confetti","_def":{"parts":[{"kind":"label","text":"confetti","style":[]}],"parameters":[]}}},"effects.hearts":{"kind":4,"retType":"effects.ScreenEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"hearts","_def":{"parts":[{"kind":"label","text":"hearts","style":[]}],"parameters":[]}}},"effects.smiles":{"kind":4,"retType":"effects.ScreenEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"smiles","_def":{"parts":[{"kind":"label","text":"smiles","style":[]}],"parameters":[]}}},"effects.rings":{"kind":4,"retType":"effects.ParticleEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"rings","_def":{"parts":[{"kind":"label","text":"rings","style":[]}],"parameters":[]}}},"effects.fire":{"kind":4,"retType":"effects.ParticleEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"fire","_def":{"parts":[{"kind":"label","text":"fire","style":[]}],"parameters":[]}}},"effects.warmRadial":{"kind":4,"retType":"effects.ParticleEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"warm radial","_def":{"parts":[{"kind":"label","text":"warm radial","style":[]}],"parameters":[]}},"pyQName":"effects.warm_radial"},"effects.coolRadial":{"kind":4,"retType":"effects.ParticleEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"cool radial","_def":{"parts":[{"kind":"label","text":"cool radial","style":[]}],"parameters":[]}},"pyQName":"effects.cool_radial"},"effects.halo":{"kind":4,"retType":"effects.ParticleEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"halo","_def":{"parts":[{"kind":"label","text":"halo","style":[]}],"parameters":[]}}},"effects.ashes":{"kind":4,"retType":"effects.ParticleEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"ashes","_def":{"parts":[{"kind":"label","text":"ashes","style":[]}],"parameters":[]}}},"effects.disintegrate":{"kind":4,"retType":"effects.ParticleEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"disintegrate","_def":{"parts":[{"kind":"label","text":"disintegrate","style":[]}],"parameters":[]}}},"effects.blizzard":{"kind":4,"retType":"effects.ScreenEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"blizzard","_def":{"parts":[{"kind":"label","text":"blizzard","style":[]}],"parameters":[]}}},"effects.bubbles":{"kind":4,"retType":"effects.ScreenEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"bubbles","_def":{"parts":[{"kind":"label","text":"bubbles","style":[]}],"parameters":[]}}},"effects.starField":{"kind":4,"retType":"effects.ScreenEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"star field","_def":{"parts":[{"kind":"label","text":"star field","style":[]}],"parameters":[]}},"pyQName":"effects.star_field"},"effects.clouds":{"kind":4,"retType":"effects.ScreenEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"clouds","_def":{"parts":[{"kind":"label","text":"clouds","style":[]}],"parameters":[]}}},"effects.none":{"kind":4,"retType":"effects.ScreenEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"none","_def":{"parts":[{"kind":"label","text":"none","style":[]}],"parameters":[]}}},"effects.ImageEffect":{"kind":8,"retType":"effects.ImageEffect","attributes":{"fixedInstances":"true"},"extendsTypes":["effects.ImageEffect","effects.BackgroundEffect"]},"effects.ImageEffect.__constructor":{"kind":-3,"parameters":[{"name":"defaultRate"},{"name":"effectFactory","type":"(image: Image, fastRandom?: Math.FastRandom) => void","handlerParameters":[{"name":"image","type":"Image"},{"name":"fastRandom","type":"Math.FastRandom"}]}],"isInstance":true},"effects.ImageEffect.applyTo":{"kind":-1,"attributes":{"paramHelp":{"sprite":""},"jsDoc":"Apply this effect to the image of the current sprite"},"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true,"pyQName":"effects.ImageEffect.apply_to"},"effects.ImageEffect.change":{"kind":-1,"attributes":{"paramHelp":{"input":""},"jsDoc":"Change the given image with this effect"},"parameters":[{"name":"input","type":"Image"}],"isInstance":true},"effects.ImageEffect.startScreenEffect":{"kind":-1,"attributes":{"paramHelp":{"times":"number of times effect should occur","delay":"delay between instances of the effect"},"jsDoc":"Make this effect occur repeatedly on the background image"},"parameters":[{"name":"times","description":"number of times effect should occur","initializer":"undefined"},{"name":"delay","description":"delay between instances of the effect","initializer":"undefined"}],"isInstance":true,"pyQName":"effects.ImageEffect.start_screen_effect"},"effects.dissolve":{"kind":4,"retType":"effects.ImageEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"dissolve","_def":{"parts":[{"kind":"label","text":"dissolve","style":[]}],"parameters":[]}}},"effects.melt":{"kind":4,"retType":"effects.ImageEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"melt","_def":{"parts":[{"kind":"label","text":"melt","style":[]}],"parameters":[]}}},"effects.slash":{"kind":4,"retType":"effects.ImageEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"slash","_def":{"parts":[{"kind":"label","text":"slash","style":[]}],"parameters":[]}}},"effects.splatter":{"kind":4,"retType":"effects.ImageEffect","attributes":{"fixedInstance":"true","whenUsed":"true","block":"splatter","_def":{"parts":[{"kind":"label","text":"splatter","style":[]}],"parameters":[]}}},"texteffects.TextEffectKind":{"kind":6,"retType":"texteffects.TextEffectKind","extendsTypes":["texteffects.TextEffectKind","Number"]},"texteffects.TextEffectKind.None":{"retType":"texteffects.TextEffectKind.None","attributes":{"block":"none","_def":{"parts":[{"kind":"label","text":"none","style":[]}],"parameters":[]}},"extendsTypes":["texteffects.TextEffectKind.None","Number"],"pyQName":"texteffects.TextEffectKind.NONE"},"texteffects.TextEffectKind.Shake":{"retType":"texteffects.TextEffectKind.Shake","attributes":{"block":"shake","_def":{"parts":[{"kind":"label","text":"shake","style":[]}],"parameters":[]}},"extendsTypes":["texteffects.TextEffectKind.Shake","Number"],"pyQName":"texteffects.TextEffectKind.SHAKE"},"texteffects.TextEffectKind.Wave":{"retType":"texteffects.TextEffectKind.Wave","attributes":{"block":"wave","_def":{"parts":[{"kind":"label","text":"wave","style":[]}],"parameters":[]}},"extendsTypes":["texteffects.TextEffectKind.Wave","Number"],"pyQName":"texteffects.TextEffectKind.WAVE"},"texteffects.getTextEffect":{"kind":-3,"retType":"texteffects.TextEffect","parameters":[{"name":"e","type":"texteffects.TextEffectKind","isEnum":true}],"pyQName":"texteffects.get_text_effect"},"texteffects.TextEffect":{"kind":8,"retType":"texteffects.TextEffect","attributes":{"fixedInstances":"true"},"extendsTypes":[]},"texteffects.TextEffect.getState":{"kind":2,"retType":"(index?: number, state?: texteffects.TextEffectState) => texteffects.TextEffectState","isInstance":true,"pyQName":"texteffects.TextEffect.get_state"},"texteffects.TextEffect.__constructor":{"kind":-3,"parameters":[{"name":"getState","type":"(index?: number, state?: texteffects.TextEffectState) => texteffects.TextEffectState","handlerParameters":[{"name":"index","type":"number"},{"name":"state","type":"texteffects.TextEffectState"}]}],"isInstance":true},"texteffects.shake":{"kind":4,"retType":"texteffects.TextEffect","attributes":{"fixedInstance":"true","whenUsed":"true"}},"texteffects.wave":{"kind":4,"retType":"texteffects.TextEffect","attributes":{"fixedInstance":"true","whenUsed":"true"}},"texteffects.TextSprite":{"kind":8,"retType":"texteffects.TextSprite","attributes":{"jsDoc":"A text sprite on the screen"},"extendsTypes":[]},"texteffects.TextSprite._str":{"kind":2,"retType":"string","isInstance":true},"texteffects.TextSprite._font":{"kind":2,"retType":"image.Font","isInstance":true},"texteffects.TextSprite._color":{"kind":2,"retType":"number","isInstance":true},"texteffects.TextSprite._effect":{"kind":2,"retType":"texteffects.TextEffect","isInstance":true},"texteffects.TextSprite._state":{"kind":2,"retType":"texteffects.TextEffectState[]","isInstance":true},"texteffects.TextSprite.color":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"texteffects.TextSprite.state":{"kind":-2,"retType":"texteffects.TextEffectState[]","isInstance":true,"isReadOnly":true},"texteffects.TextSprite.__constructor":{"kind":-3,"parameters":[{"name":"str","type":"string"},{"name":"font","type":"image.Font"},{"name":"color"},{"name":"effect","type":"texteffects.TextEffect","initializer":"undefined"}],"isInstance":true},"texteffects.TextSprite.updateState":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"texteffects.TextSprite.update_state"},"texteffects.TextSprite.draw":{"kind":-1,"parameters":[{"name":"image","type":"Image"},{"name":"x"},{"name":"y"},{"name":"start","initializer":"undefined"},{"name":"length","initializer":"undefined"}],"isInstance":true},"tilemap":{"kind":-3,"retType":"tiles.TileMapData","attributes":{"helper":"getTilemapByName","pyConvertToTaggedTemplate":"true","blockIdentity":"tiles._tilemapEditor"},"parameters":[{"name":"lits","type":"any"},{"name":"args","type":"any[]"}]},"tilemap8":{"kind":-3,"retType":"tiles.TileMapData","attributes":{"helper":"getTilemapByName","pyConvertToTaggedTemplate":"true"},"parameters":[{"name":"lits","type":"any"},{"name":"args","type":"any[]"}]},"tilemap16":{"kind":-3,"retType":"tiles.TileMapData","attributes":{"helper":"getTilemapByName","pyConvertToTaggedTemplate":"true"},"parameters":[{"name":"lits","type":"any"},{"name":"args","type":"any[]"}]},"tilemap32":{"kind":-3,"retType":"tiles.TileMapData","attributes":{"helper":"getTilemapByName","pyConvertToTaggedTemplate":"true"},"parameters":[{"name":"lits","type":"any"},{"name":"args","type":"any[]"}]},"tilemap4":{"kind":-3,"retType":"tiles.TileMapData","attributes":{"helper":"getTilemapByName","pyConvertToTaggedTemplate":"true"},"parameters":[{"name":"lits","type":"any"},{"name":"args","type":"any[]"}]},"assets":{"kind":5,"retType":""},"assets.tilemap":{"kind":-3,"retType":"tiles.TileMapData","attributes":{"helper":"getTilemapByName","pyConvertToTaggedTemplate":"true","blockIdentity":"tiles._tilemapEditor"},"parameters":[{"name":"lits","type":"any"},{"name":"args","type":"any[]"}]},"assets.image":{"kind":-3,"retType":"Image","attributes":{"helper":"getImageByName","pyConvertToTaggedTemplate":"true","blockIdentity":"images._spriteImage"},"parameters":[{"name":"lits","type":"any"},{"name":"args","type":"any[]"}]},"assets.tile":{"kind":-3,"retType":"Image","attributes":{"helper":"getTileByName","pyConvertToTaggedTemplate":"true","blockIdentity":"images._tile"},"parameters":[{"name":"lits","type":"any"},{"name":"args","type":"any[]"}]},"assets.animation":{"kind":-3,"retType":"Image[]","attributes":{"helper":"getAnimationByName","pyConvertToTaggedTemplate":"true","blockIdentity":"animation._animationFrames"},"parameters":[{"name":"lits","type":"any"},{"name":"args","type":"any[]"}]},"assets.song":{"kind":-3,"retType":"Buffer","attributes":{"helper":"getSongByName","pyConvertToTaggedTemplate":"true","blockIdentity":"music._songFieldEditor"},"parameters":[{"name":"lits","type":"any"},{"name":"args","type":"any[]"}]},"helpers._registerFactory":{"kind":-3,"parameters":[{"name":"kind","type":"string"},{"name":"factory","type":"(name: string) => any","handlerParameters":[{"name":"name","type":"string"}]}],"pyQName":"helpers._register_factory"},"helpers._getFactoryInstance":{"kind":-3,"retType":"any","parameters":[{"name":"kind","type":"string"},{"name":"name","type":"string"}],"pyQName":"helpers._get_factory_instance"},"helpers.registerTilemapFactory":{"kind":-3,"parameters":[{"name":"factory","type":"helpers.TilemapFactory"}],"pyQName":"helpers.register_tilemap_factory"},"helpers.getTilemapByName":{"kind":-3,"retType":"any","parameters":[{"name":"name","type":"string"}],"pyQName":"helpers.get_tilemap_by_name"},"helpers.getImageByName":{"kind":-3,"retType":"any","parameters":[{"name":"name","type":"string"}],"pyQName":"helpers.get_image_by_name"},"helpers.getAnimationByName":{"kind":-3,"retType":"any","parameters":[{"name":"name","type":"string"}],"pyQName":"helpers.get_animation_by_name"},"helpers.getTileByName":{"kind":-3,"retType":"any","parameters":[{"name":"name","type":"string"}],"pyQName":"helpers.get_tile_by_name"},"helpers.getSongByName":{"kind":-3,"retType":"any","parameters":[{"name":"name","type":"string"}],"pyQName":"helpers.get_song_by_name"},"animation":{"kind":5,"retType":"","attributes":{"color":"#03AA74","weight":5,"icon":"","block":"Animation","groups":["Animate","Advanced"],"_def":{"parts":[{"kind":"label","text":"Animation","style":[]}],"parameters":[]}}},"animation.Point":{"kind":8,"retType":"animation.Point","extendsTypes":[]},"animation.Point.x":{"kind":2,"retType":"number","isInstance":true},"animation.Point.y":{"kind":2,"retType":"number","isInstance":true},"animation.Point.__constructor":{"kind":-3,"parameters":[{"name":"x"},{"name":"y"}],"isInstance":true},"animation.PathPreset":{"kind":8,"retType":"animation.PathPreset","attributes":{"fixedInstances":"true","blockId":"animation_path","block":"path %pathString","_def":{"parts":[{"kind":"label","text":"path ","style":[]},{"kind":"param","name":"pathString","ref":false}],"parameters":[{"kind":"param","name":"pathString","ref":false}]}},"extendsTypes":[]},"animation.PathPreset.__constructor":{"kind":-3,"parameters":[{"name":"pathString","type":"string"}],"isInstance":true},"animation.Path":{"kind":8,"retType":"animation.Path","extendsTypes":[]},"animation.Path.length":{"kind":2,"retType":"number","isInstance":true},"animation.Path.__constructor":{"kind":-3,"parameters":[{"name":"path","type":"string"}],"isInstance":true},"animation.Path.reset":{"kind":-1,"parameters":[],"isInstance":true},"animation.Path.run":{"kind":-1,"retType":"boolean","parameters":[{"name":"interval"},{"name":"target","type":"Sprite"},{"name":"runningTime"}],"isInstance":true},"animation.SpriteAnimation":{"kind":8,"retType":"animation.SpriteAnimation","extendsTypes":["animation.SpriteAnimation"]},"animation.SpriteAnimation.__constructor":{"kind":-3,"parameters":[{"name":"sprite","type":"Sprite"},{"name":"loop","type":"boolean"}],"isInstance":true},"animation.SpriteAnimation.init":{"kind":-1,"parameters":[],"isInstance":true},"animation.SpriteAnimation.update":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true},"animation.ImageAnimation":{"kind":8,"retType":"animation.ImageAnimation","extendsTypes":["animation.ImageAnimation","animation.SpriteAnimation"]},"animation.ImageAnimation.__constructor":{"kind":-3,"parameters":[{"name":"sprite","type":"Sprite"},{"name":"frames","type":"Image[]"},{"name":"frameInterval"},{"name":"loop","type":"boolean","initializer":"undefined"}],"isInstance":true},"animation.ImageAnimation.update":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true},"animation.MovementAnimation":{"kind":8,"retType":"animation.MovementAnimation","extendsTypes":["animation.MovementAnimation","animation.SpriteAnimation"]},"animation.MovementAnimation.__constructor":{"kind":-3,"parameters":[{"name":"sprite","type":"Sprite"},{"name":"path","type":"animation.Path"},{"name":"nodeInterval"},{"name":"loop","type":"boolean","initializer":"undefined"}],"isInstance":true},"animation.MovementAnimation.update":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true},"animation.runImageAnimation":{"kind":-3,"attributes":{"paramDefl":{"frameInterval":"500"},"blockId":"run_image_animation","block":"animate $sprite=variables_get(mySprite) frames $frames=animation_editor interval (ms) $frameInterval=timePicker loop $loop=toggleOnOff","group":"Animate","weight":100,"help":"animation/run-image-animation","paramHelp":{"frames":"the frames to animate through","sprite":"the sprite to animate on","frameInterval":"the time between changes, eg: 500"},"jsDoc":"Create and run an image animation on a sprite","_def":{"parts":[{"kind":"label","text":"animate ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"label","text":" frames ","style":[]},{"kind":"param","name":"frames","shadowBlockId":"animation_editor","ref":true},{"kind":"label","text":" interval (ms) ","style":[]},{"kind":"param","name":"frameInterval","shadowBlockId":"timePicker","ref":true},{"kind":"label","text":" loop ","style":[]},{"kind":"param","name":"loop","shadowBlockId":"toggleOnOff","ref":true}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"param","name":"frames","shadowBlockId":"animation_editor","ref":true},{"kind":"param","name":"frameInterval","shadowBlockId":"timePicker","ref":true},{"kind":"param","name":"loop","shadowBlockId":"toggleOnOff","ref":true}]}},"parameters":[{"name":"sprite","description":"the sprite to animate on","type":"Sprite"},{"name":"frames","description":"the frames to animate through","type":"Image[]"},{"name":"frameInterval","description":"the time between changes, eg: 500","initializer":"undefined","default":"500"},{"name":"loop","type":"boolean","initializer":"undefined"}],"pyQName":"animation.run_image_animation"},"animation.runMovementAnimation":{"kind":-3,"attributes":{"paramDefl":{"duration":"2000"},"blockId":"run_movement_animation","block":"animate $sprite=variables_get(mySprite) with $pathString=animation_path for (ms) $duration=timePicker loop $loop=toggleOnOff","explicitDefaults":["duration"],"weight":80,"group":"Animate","help":"animation/run-movement-animation","paramHelp":{"sprite":"the sprite to move","pathString":"the SVG path to animate","duration":"how long the animation should play for, eg: 500"},"jsDoc":"Create and run a movement animation on a sprite","_def":{"parts":[{"kind":"label","text":"animate ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"label","text":" with ","style":[]},{"kind":"param","name":"pathString","shadowBlockId":"animation_path","ref":true},{"kind":"label","text":" for (ms) ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":true},{"kind":"label","text":" loop ","style":[]},{"kind":"param","name":"loop","shadowBlockId":"toggleOnOff","ref":true}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"param","name":"pathString","shadowBlockId":"animation_path","ref":true},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":true},{"kind":"param","name":"loop","shadowBlockId":"toggleOnOff","ref":true}]}},"parameters":[{"name":"sprite","description":"the sprite to move","type":"Sprite"},{"name":"pathString","description":"the SVG path to animate","type":"string"},{"name":"duration","description":"how long the animation should play for, eg: 500","initializer":"2000","default":"2000"},{"name":"loop","type":"boolean","initializer":"undefined"}],"pyQName":"animation.run_movement_animation"},"animation.AnimationTypes":{"kind":6,"retType":"animation.AnimationTypes","extendsTypes":["animation.AnimationTypes","Number"]},"animation.AnimationTypes.All":{"retType":"animation.AnimationTypes.All","attributes":{"block":"all","_def":{"parts":[{"kind":"label","text":"all","style":[]}],"parameters":[]}},"extendsTypes":["animation.AnimationTypes.All","Number"],"pyQName":"animation.AnimationTypes.ALL"},"animation.AnimationTypes.ImageAnimation":{"retType":"animation.AnimationTypes.ImageAnimation","attributes":{"block":"frame","_def":{"parts":[{"kind":"label","text":"frame","style":[]}],"parameters":[]}},"extendsTypes":["animation.AnimationTypes.ImageAnimation","Number"],"pyQName":"animation.AnimationTypes.IMAGE_ANIMATION"},"animation.AnimationTypes.MovementAnimation":{"retType":"animation.AnimationTypes.MovementAnimation","attributes":{"block":"path","_def":{"parts":[{"kind":"label","text":"path","style":[]}],"parameters":[]}},"extendsTypes":["animation.AnimationTypes.MovementAnimation","Number"],"pyQName":"animation.AnimationTypes.MOVEMENT_ANIMATION"},"animation.stopAnimation":{"kind":-3,"attributes":{"blockId":"stop_animations","block":"stop %type animations on %sprite=variables_get(mySprite)","group":"Animate","weight":60,"help":"animation/stop-animation","paramHelp":{"type":"the animation type to stop","sprite":"the sprite to filter animations by"},"jsDoc":"Stop one type or all animations (simple and looping) on a sprite","_def":{"parts":[{"kind":"label","text":"stop ","style":[]},{"kind":"param","name":"type","ref":false},{"kind":"label","text":" animations on ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"}],"parameters":[{"kind":"param","name":"type","ref":false},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":false,"varName":"mySprite"}]}},"parameters":[{"name":"type","description":"the animation type to stop","type":"animation.AnimationTypes","isEnum":true},{"name":"sprite","description":"the sprite to filter animations by","type":"Sprite"}],"pyQName":"animation.stop_animation"},"animation.flyToCenter":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"fly to center","_def":{"parts":[{"kind":"label","text":"fly to center","style":[]}],"parameters":[]}},"pyQName":"animation.fly_to_center"},"animation.shake":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"shake","_def":{"parts":[{"kind":"label","text":"shake","style":[]}],"parameters":[]}}},"animation.bounceRight":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"bounce (right)","_def":{"parts":[{"kind":"label","text":"bounce (right)","style":[]}],"parameters":[]}},"pyQName":"animation.bounce_right"},"animation.bounceLeft":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"bounce (left)","_def":{"parts":[{"kind":"label","text":"bounce (left)","style":[]}],"parameters":[]}},"pyQName":"animation.bounce_left"},"animation.parachuteRight":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"parachute (right)","_def":{"parts":[{"kind":"label","text":"parachute (right)","style":[]}],"parameters":[]}},"pyQName":"animation.parachute_right"},"animation.parachuteLeft":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"parachute (left)","_def":{"parts":[{"kind":"label","text":"parachute (left)","style":[]}],"parameters":[]}},"pyQName":"animation.parachute_left"},"animation.easeRight":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"ease (right)","_def":{"parts":[{"kind":"label","text":"ease (right)","style":[]}],"parameters":[]}},"pyQName":"animation.ease_right"},"animation.easeLeft":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"ease (left)","_def":{"parts":[{"kind":"label","text":"ease (left)","style":[]}],"parameters":[]}},"pyQName":"animation.ease_left"},"animation.easeDown":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"ease (down)","_def":{"parts":[{"kind":"label","text":"ease (down)","style":[]}],"parameters":[]}},"pyQName":"animation.ease_down"},"animation.easeUp":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"ease (up)","_def":{"parts":[{"kind":"label","text":"ease (up)","style":[]}],"parameters":[]}},"pyQName":"animation.ease_up"},"animation.waveRight":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"wave (right)","_def":{"parts":[{"kind":"label","text":"wave (right)","style":[]}],"parameters":[]}},"pyQName":"animation.wave_right"},"animation.waveLeft":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"wave (left)","_def":{"parts":[{"kind":"label","text":"wave (left)","style":[]}],"parameters":[]}},"pyQName":"animation.wave_left"},"animation.bobbing":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"bobbing (in place)","_def":{"parts":[{"kind":"label","text":"bobbing (in place)","style":[]}],"parameters":[]}}},"animation.bobbingRight":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"bobbing (right)","_def":{"parts":[{"kind":"label","text":"bobbing (right)","style":[]}],"parameters":[]}},"pyQName":"animation.bobbing_right"},"animation.bobbingLeft":{"kind":4,"retType":"animation.PathPreset","attributes":{"fixedInstance":"true","whenUsed":"true","block":"bobbing (left)","_def":{"parts":[{"kind":"label","text":"bobbing (left)","style":[]}],"parameters":[]}},"pyQName":"animation.bobbing_left"},"animation.animationPresets":{"kind":-3,"retType":"string","attributes":{"blockId":"animation_path","block":"%animationPath","group":"Animate","blockHidden":true,"paramHelp":{"animationPath":"The preset path"},"jsDoc":"Generates a path string for preset animation","_def":{"parts":[{"kind":"param","name":"animationPath","ref":false}],"parameters":[{"kind":"param","name":"animationPath","ref":false}]}},"parameters":[{"name":"animationPath","description":"The preset path","type":"animation.PathPreset"}],"pyQName":"animation.animation_presets"},"animation._animationFrames":{"kind":-3,"retType":"Image[]","attributes":{"blockId":"animation_editor","block":"%frames","shim":"TD_ID","paramFieldEditor":{"frames":"animation"},"paramFieldEditorOptions":{"frames":{"decompileLiterals":"true","filter":"!tile !dialog !background"}},"weight":40,"group":"Animate","duplicateShadowOnDrag":true,"help":"animation/animation-frames","_def":{"parts":[{"kind":"param","name":"frames","ref":false}],"parameters":[{"kind":"param","name":"frames","ref":false}]}},"parameters":[{"name":"frames","type":"Image[]"}],"pyQName":"animation._animation_frames"},"multiplayer":{"kind":5,"retType":""},"multiplayer.init":{"kind":-3,"parameters":[]},"multiplayer.initServer":{"kind":-3,"parameters":[],"pyQName":"multiplayer.init_server"},"multiplayer.initPlayerConnectionListeners":{"kind":-3,"parameters":[],"pyQName":"multiplayer.init_player_connection_listeners"},"mp":{"kind":5,"retType":""},"mp.postPresenceIcon":{"kind":-3,"parameters":[{"name":"slot"},{"name":"im","type":"Image"},{"name":"implicit","type":"boolean","initializer":"undefined"}],"pyQName":"mp.post_presence_icon"},"mp.postReactionIcon":{"kind":-3,"parameters":[{"name":"slot"},{"name":"im","type":"Image"},{"name":"implicit","type":"boolean","initializer":"undefined"}],"pyQName":"mp.post_reaction_icon"},"keymap":{"kind":5,"retType":""},"keymap.setPlayerKeys":{"kind":-3,"attributes":{"paramHelp":{"player":"The player number. 1 = Player1, etc.","up":"The key code for 'up'.","down":"The key code for 'down'","left":"The key code for 'left'","right":"The key code for 'right'","A":"The key code for 'A'","B":"The key code for 'B'"},"jsDoc":"Sets the keyboard input map for the given player."},"parameters":[{"name":"player","description":"The player number. 1 = Player1, etc."},{"name":"up","description":"The key code for 'up'.","type":"keymap.KeyCode","isEnum":true},{"name":"down","description":"The key code for 'down'","type":"keymap.KeyCode","isEnum":true},{"name":"left","description":"The key code for 'left'","type":"keymap.KeyCode","isEnum":true},{"name":"right","description":"The key code for 'right'","type":"keymap.KeyCode","isEnum":true},{"name":"A","description":"The key code for 'A'","type":"keymap.KeyCode","isEnum":true},{"name":"B","description":"The key code for 'B'","type":"keymap.KeyCode","isEnum":true}],"pyQName":"keymap.set_player_keys"},"keymap.setSystemKeys":{"kind":-3,"attributes":{"paramHelp":{"screenshot":"The key code for 'screenshot'","gif":"The key code for 'gif'","menu":"The key code for 'menu'","reset":"The key code for 'reset'"},"jsDoc":"Sets the keyboard input map for system keys."},"parameters":[{"name":"screenshot","description":"The key code for 'screenshot'","type":"keymap.KeyCode","isEnum":true},{"name":"gif","description":"The key code for 'gif'","type":"keymap.KeyCode","isEnum":true},{"name":"menu","description":"The key code for 'menu'","type":"keymap.KeyCode","isEnum":true},{"name":"reset","description":"The key code for 'reset'","type":"keymap.KeyCode","isEnum":true}],"pyQName":"keymap.set_system_keys"},"keymap.KeyCode":{"kind":6,"retType":"keymap.KeyCode","attributes":{"jsDoc":"Key codes"},"extendsTypes":["keymap.KeyCode","Number"]},"keymap.KeyCode.None":{"retType":"keymap.KeyCode.None","extendsTypes":["keymap.KeyCode.None","Number"],"pyQName":"keymap.KeyCode.NONE"},"keymap.KeyCode.Backspace":{"retType":"keymap.KeyCode.Backspace","extendsTypes":["keymap.KeyCode.Backspace","Number"],"pyQName":"keymap.KeyCode.BACKSPACE"},"keymap.KeyCode.Tab":{"retType":"keymap.KeyCode.Tab","extendsTypes":["keymap.KeyCode.Tab","Number"],"pyQName":"keymap.KeyCode.TAB"},"keymap.KeyCode.Enter":{"retType":"keymap.KeyCode.Enter","extendsTypes":["keymap.KeyCode.Enter","Number"],"pyQName":"keymap.KeyCode.ENTER"},"keymap.KeyCode.Shift":{"retType":"keymap.KeyCode.Shift","extendsTypes":["keymap.KeyCode.Shift","Number"],"pyQName":"keymap.KeyCode.SHIFT"},"keymap.KeyCode.Ctrl":{"retType":"keymap.KeyCode.Ctrl","extendsTypes":["keymap.KeyCode.Ctrl","Number"],"pyQName":"keymap.KeyCode.CTRL"},"keymap.KeyCode.Alt":{"retType":"keymap.KeyCode.Alt","extendsTypes":["keymap.KeyCode.Alt","Number"],"pyQName":"keymap.KeyCode.ALT"},"keymap.KeyCode.PauseBreak":{"retType":"keymap.KeyCode.PauseBreak","extendsTypes":["keymap.KeyCode.PauseBreak","Number"],"pyQName":"keymap.KeyCode.PAUSE_BREAK"},"keymap.KeyCode.CapsLock":{"retType":"keymap.KeyCode.CapsLock","extendsTypes":["keymap.KeyCode.CapsLock","Number"],"pyQName":"keymap.KeyCode.CAPS_LOCK"},"keymap.KeyCode.Escape":{"retType":"keymap.KeyCode.Escape","extendsTypes":["keymap.KeyCode.Escape","Number"],"pyQName":"keymap.KeyCode.ESCAPE"},"keymap.KeyCode.Space":{"retType":"keymap.KeyCode.Space","extendsTypes":["keymap.KeyCode.Space","Number"],"pyQName":"keymap.KeyCode.SPACE"},"keymap.KeyCode.PageUp":{"retType":"keymap.KeyCode.PageUp","extendsTypes":["keymap.KeyCode.PageUp","Number"],"pyQName":"keymap.KeyCode.PAGE_UP"},"keymap.KeyCode.PageDown":{"retType":"keymap.KeyCode.PageDown","extendsTypes":["keymap.KeyCode.PageDown","Number"],"pyQName":"keymap.KeyCode.PAGE_DOWN"},"keymap.KeyCode.End":{"retType":"keymap.KeyCode.End","extendsTypes":["keymap.KeyCode.End","Number"],"pyQName":"keymap.KeyCode.END"},"keymap.KeyCode.Home":{"retType":"keymap.KeyCode.Home","extendsTypes":["keymap.KeyCode.Home","Number"],"pyQName":"keymap.KeyCode.HOME"},"keymap.KeyCode.LeftArrow":{"retType":"keymap.KeyCode.LeftArrow","extendsTypes":["keymap.KeyCode.LeftArrow","Number"],"pyQName":"keymap.KeyCode.LEFT_ARROW"},"keymap.KeyCode.UpArrow":{"retType":"keymap.KeyCode.UpArrow","extendsTypes":["keymap.KeyCode.UpArrow","Number"],"pyQName":"keymap.KeyCode.UP_ARROW"},"keymap.KeyCode.RightArrow":{"retType":"keymap.KeyCode.RightArrow","extendsTypes":["keymap.KeyCode.RightArrow","Number"],"pyQName":"keymap.KeyCode.RIGHT_ARROW"},"keymap.KeyCode.DownArrow":{"retType":"keymap.KeyCode.DownArrow","extendsTypes":["keymap.KeyCode.DownArrow","Number"],"pyQName":"keymap.KeyCode.DOWN_ARROW"},"keymap.KeyCode.Insert":{"retType":"keymap.KeyCode.Insert","extendsTypes":["keymap.KeyCode.Insert","Number"],"pyQName":"keymap.KeyCode.INSERT"},"keymap.KeyCode.Delete":{"retType":"keymap.KeyCode.Delete","extendsTypes":["keymap.KeyCode.Delete","Number"],"pyQName":"keymap.KeyCode.DELETE"},"keymap.KeyCode.Zero":{"retType":"keymap.KeyCode.Zero","extendsTypes":["keymap.KeyCode.Zero","Number"],"pyQName":"keymap.KeyCode.ZERO"},"keymap.KeyCode.One":{"retType":"keymap.KeyCode.One","extendsTypes":["keymap.KeyCode.One","Number"],"pyQName":"keymap.KeyCode.ONE"},"keymap.KeyCode.Two":{"retType":"keymap.KeyCode.Two","extendsTypes":["keymap.KeyCode.Two","Number"],"pyQName":"keymap.KeyCode.TWO"},"keymap.KeyCode.Three":{"retType":"keymap.KeyCode.Three","extendsTypes":["keymap.KeyCode.Three","Number"],"pyQName":"keymap.KeyCode.THREE"},"keymap.KeyCode.Four":{"retType":"keymap.KeyCode.Four","extendsTypes":["keymap.KeyCode.Four","Number"],"pyQName":"keymap.KeyCode.FOUR"},"keymap.KeyCode.Five":{"retType":"keymap.KeyCode.Five","extendsTypes":["keymap.KeyCode.Five","Number"],"pyQName":"keymap.KeyCode.FIVE"},"keymap.KeyCode.Six":{"retType":"keymap.KeyCode.Six","extendsTypes":["keymap.KeyCode.Six","Number"],"pyQName":"keymap.KeyCode.SIX"},"keymap.KeyCode.Seven":{"retType":"keymap.KeyCode.Seven","extendsTypes":["keymap.KeyCode.Seven","Number"],"pyQName":"keymap.KeyCode.SEVEN"},"keymap.KeyCode.Eight":{"retType":"keymap.KeyCode.Eight","extendsTypes":["keymap.KeyCode.Eight","Number"],"pyQName":"keymap.KeyCode.EIGHT"},"keymap.KeyCode.Nine":{"retType":"keymap.KeyCode.Nine","extendsTypes":["keymap.KeyCode.Nine","Number"],"pyQName":"keymap.KeyCode.NINE"},"keymap.KeyCode.A":{"retType":"keymap.KeyCode.A","extendsTypes":["keymap.KeyCode.A","Number"]},"keymap.KeyCode.B":{"retType":"keymap.KeyCode.B","extendsTypes":["keymap.KeyCode.B","Number"]},"keymap.KeyCode.C":{"retType":"keymap.KeyCode.C","extendsTypes":["keymap.KeyCode.C","Number"]},"keymap.KeyCode.D":{"retType":"keymap.KeyCode.D","extendsTypes":["keymap.KeyCode.D","Number"]},"keymap.KeyCode.E":{"retType":"keymap.KeyCode.E","extendsTypes":["keymap.KeyCode.E","Number"]},"keymap.KeyCode.F":{"retType":"keymap.KeyCode.F","extendsTypes":["keymap.KeyCode.F","Number"]},"keymap.KeyCode.G":{"retType":"keymap.KeyCode.G","extendsTypes":["keymap.KeyCode.G","Number"]},"keymap.KeyCode.H":{"retType":"keymap.KeyCode.H","extendsTypes":["keymap.KeyCode.H","Number"]},"keymap.KeyCode.I":{"retType":"keymap.KeyCode.I","extendsTypes":["keymap.KeyCode.I","Number"]},"keymap.KeyCode.J":{"retType":"keymap.KeyCode.J","extendsTypes":["keymap.KeyCode.J","Number"]},"keymap.KeyCode.K":{"retType":"keymap.KeyCode.K","extendsTypes":["keymap.KeyCode.K","Number"]},"keymap.KeyCode.L":{"retType":"keymap.KeyCode.L","extendsTypes":["keymap.KeyCode.L","Number"]},"keymap.KeyCode.M":{"retType":"keymap.KeyCode.M","extendsTypes":["keymap.KeyCode.M","Number"]},"keymap.KeyCode.N":{"retType":"keymap.KeyCode.N","extendsTypes":["keymap.KeyCode.N","Number"]},"keymap.KeyCode.O":{"retType":"keymap.KeyCode.O","extendsTypes":["keymap.KeyCode.O","Number"]},"keymap.KeyCode.P":{"retType":"keymap.KeyCode.P","extendsTypes":["keymap.KeyCode.P","Number"]},"keymap.KeyCode.Q":{"retType":"keymap.KeyCode.Q","extendsTypes":["keymap.KeyCode.Q","Number"]},"keymap.KeyCode.R":{"retType":"keymap.KeyCode.R","extendsTypes":["keymap.KeyCode.R","Number"]},"keymap.KeyCode.S":{"retType":"keymap.KeyCode.S","extendsTypes":["keymap.KeyCode.S","Number"]},"keymap.KeyCode.T":{"retType":"keymap.KeyCode.T","extendsTypes":["keymap.KeyCode.T","Number"]},"keymap.KeyCode.U":{"retType":"keymap.KeyCode.U","extendsTypes":["keymap.KeyCode.U","Number"]},"keymap.KeyCode.V":{"retType":"keymap.KeyCode.V","extendsTypes":["keymap.KeyCode.V","Number"]},"keymap.KeyCode.W":{"retType":"keymap.KeyCode.W","extendsTypes":["keymap.KeyCode.W","Number"]},"keymap.KeyCode.X":{"retType":"keymap.KeyCode.X","extendsTypes":["keymap.KeyCode.X","Number"]},"keymap.KeyCode.Y":{"retType":"keymap.KeyCode.Y","extendsTypes":["keymap.KeyCode.Y","Number"]},"keymap.KeyCode.Z":{"retType":"keymap.KeyCode.Z","extendsTypes":["keymap.KeyCode.Z","Number"]},"keymap.KeyCode.LeftWindowsKey":{"retType":"keymap.KeyCode.LeftWindowsKey","extendsTypes":["keymap.KeyCode.LeftWindowsKey","Number"],"pyQName":"keymap.KeyCode.LEFT_WINDOWS_KEY"},"keymap.KeyCode.RightWindowsKey":{"retType":"keymap.KeyCode.RightWindowsKey","extendsTypes":["keymap.KeyCode.RightWindowsKey","Number"],"pyQName":"keymap.KeyCode.RIGHT_WINDOWS_KEY"},"keymap.KeyCode.Numpad0":{"retType":"keymap.KeyCode.Numpad0","extendsTypes":["keymap.KeyCode.Numpad0","Number"],"pyQName":"keymap.KeyCode.NUMPAD0"},"keymap.KeyCode.Numpad1":{"retType":"keymap.KeyCode.Numpad1","extendsTypes":["keymap.KeyCode.Numpad1","Number"],"pyQName":"keymap.KeyCode.NUMPAD1"},"keymap.KeyCode.Numpad2":{"retType":"keymap.KeyCode.Numpad2","extendsTypes":["keymap.KeyCode.Numpad2","Number"],"pyQName":"keymap.KeyCode.NUMPAD2"},"keymap.KeyCode.Numpad3":{"retType":"keymap.KeyCode.Numpad3","extendsTypes":["keymap.KeyCode.Numpad3","Number"],"pyQName":"keymap.KeyCode.NUMPAD3"},"keymap.KeyCode.Numpad4":{"retType":"keymap.KeyCode.Numpad4","extendsTypes":["keymap.KeyCode.Numpad4","Number"],"pyQName":"keymap.KeyCode.NUMPAD4"},"keymap.KeyCode.Numpad5":{"retType":"keymap.KeyCode.Numpad5","extendsTypes":["keymap.KeyCode.Numpad5","Number"],"pyQName":"keymap.KeyCode.NUMPAD5"},"keymap.KeyCode.Numpad6":{"retType":"keymap.KeyCode.Numpad6","extendsTypes":["keymap.KeyCode.Numpad6","Number"],"pyQName":"keymap.KeyCode.NUMPAD6"},"keymap.KeyCode.Numpad7":{"retType":"keymap.KeyCode.Numpad7","extendsTypes":["keymap.KeyCode.Numpad7","Number"],"pyQName":"keymap.KeyCode.NUMPAD7"},"keymap.KeyCode.Numpad8":{"retType":"keymap.KeyCode.Numpad8","extendsTypes":["keymap.KeyCode.Numpad8","Number"],"pyQName":"keymap.KeyCode.NUMPAD8"},"keymap.KeyCode.Numpad9":{"retType":"keymap.KeyCode.Numpad9","extendsTypes":["keymap.KeyCode.Numpad9","Number"],"pyQName":"keymap.KeyCode.NUMPAD9"},"keymap.KeyCode.Multiply":{"retType":"keymap.KeyCode.Multiply","extendsTypes":["keymap.KeyCode.Multiply","Number"],"pyQName":"keymap.KeyCode.MULTIPLY"},"keymap.KeyCode.Add":{"retType":"keymap.KeyCode.Add","extendsTypes":["keymap.KeyCode.Add","Number"],"pyQName":"keymap.KeyCode.ADD"},"keymap.KeyCode.Subtract":{"retType":"keymap.KeyCode.Subtract","extendsTypes":["keymap.KeyCode.Subtract","Number"],"pyQName":"keymap.KeyCode.SUBTRACT"},"keymap.KeyCode.DecimalPoint":{"retType":"keymap.KeyCode.DecimalPoint","extendsTypes":["keymap.KeyCode.DecimalPoint","Number"],"pyQName":"keymap.KeyCode.DECIMAL_POINT"},"keymap.KeyCode.Divide":{"retType":"keymap.KeyCode.Divide","extendsTypes":["keymap.KeyCode.Divide","Number"],"pyQName":"keymap.KeyCode.DIVIDE"},"keymap.KeyCode.F1":{"retType":"keymap.KeyCode.F1","extendsTypes":["keymap.KeyCode.F1","Number"]},"keymap.KeyCode.F2":{"retType":"keymap.KeyCode.F2","extendsTypes":["keymap.KeyCode.F2","Number"]},"keymap.KeyCode.F3":{"retType":"keymap.KeyCode.F3","extendsTypes":["keymap.KeyCode.F3","Number"]},"keymap.KeyCode.F4":{"retType":"keymap.KeyCode.F4","extendsTypes":["keymap.KeyCode.F4","Number"]},"keymap.KeyCode.F5":{"retType":"keymap.KeyCode.F5","extendsTypes":["keymap.KeyCode.F5","Number"]},"keymap.KeyCode.F6":{"retType":"keymap.KeyCode.F6","extendsTypes":["keymap.KeyCode.F6","Number"]},"keymap.KeyCode.F7":{"retType":"keymap.KeyCode.F7","extendsTypes":["keymap.KeyCode.F7","Number"]},"keymap.KeyCode.F8":{"retType":"keymap.KeyCode.F8","extendsTypes":["keymap.KeyCode.F8","Number"]},"keymap.KeyCode.F9":{"retType":"keymap.KeyCode.F9","extendsTypes":["keymap.KeyCode.F9","Number"]},"keymap.KeyCode.F10":{"retType":"keymap.KeyCode.F10","extendsTypes":["keymap.KeyCode.F10","Number"]},"keymap.KeyCode.F11":{"retType":"keymap.KeyCode.F11","extendsTypes":["keymap.KeyCode.F11","Number"]},"keymap.KeyCode.F12":{"retType":"keymap.KeyCode.F12","extendsTypes":["keymap.KeyCode.F12","Number"]},"keymap.KeyCode.NumLock":{"retType":"keymap.KeyCode.NumLock","extendsTypes":["keymap.KeyCode.NumLock","Number"],"pyQName":"keymap.KeyCode.NUM_LOCK"},"keymap.KeyCode.ScrollLock":{"retType":"keymap.KeyCode.ScrollLock","extendsTypes":["keymap.KeyCode.ScrollLock","Number"],"pyQName":"keymap.KeyCode.SCROLL_LOCK"},"keymap.KeyCode.SemiColon":{"retType":"keymap.KeyCode.SemiColon","extendsTypes":["keymap.KeyCode.SemiColon","Number"],"pyQName":"keymap.KeyCode.SEMI_COLON"},"keymap.KeyCode.Equals":{"retType":"keymap.KeyCode.Equals","extendsTypes":["keymap.KeyCode.Equals","Number"],"pyQName":"keymap.KeyCode.EQUALS"},"keymap.KeyCode.Comma":{"retType":"keymap.KeyCode.Comma","extendsTypes":["keymap.KeyCode.Comma","Number"],"pyQName":"keymap.KeyCode.COMMA"},"keymap.KeyCode.Dash":{"retType":"keymap.KeyCode.Dash","extendsTypes":["keymap.KeyCode.Dash","Number"],"pyQName":"keymap.KeyCode.DASH"},"keymap.KeyCode.Period":{"retType":"keymap.KeyCode.Period","extendsTypes":["keymap.KeyCode.Period","Number"],"pyQName":"keymap.KeyCode.PERIOD"},"keymap.KeyCode.ForwardSlash":{"retType":"keymap.KeyCode.ForwardSlash","extendsTypes":["keymap.KeyCode.ForwardSlash","Number"],"pyQName":"keymap.KeyCode.FORWARD_SLASH"},"keymap.KeyCode.Tilde":{"retType":"keymap.KeyCode.Tilde","extendsTypes":["keymap.KeyCode.Tilde","Number"],"pyQName":"keymap.KeyCode.TILDE"},"keymap.KeyCode.OpenBracket":{"retType":"keymap.KeyCode.OpenBracket","extendsTypes":["keymap.KeyCode.OpenBracket","Number"],"pyQName":"keymap.KeyCode.OPEN_BRACKET"},"keymap.KeyCode.ClosedBracket":{"retType":"keymap.KeyCode.ClosedBracket","extendsTypes":["keymap.KeyCode.ClosedBracket","Number"],"pyQName":"keymap.KeyCode.CLOSED_BRACKET"},"keymap.KeyCode.SingleQuote":{"retType":"keymap.KeyCode.SingleQuote","extendsTypes":["keymap.KeyCode.SingleQuote","Number"],"pyQName":"keymap.KeyCode.SINGLE_QUOTE"},"keymap.KeyCode.MouseLeftButton":{"retType":"keymap.KeyCode.MouseLeftButton","extendsTypes":["keymap.KeyCode.MouseLeftButton","Number"],"pyQName":"keymap.KeyCode.MOUSE_LEFT_BUTTON"},"keymap.KeyCode.MouseRightButton":{"retType":"keymap.KeyCode.MouseRightButton","extendsTypes":["keymap.KeyCode.MouseRightButton","Number"],"pyQName":"keymap.KeyCode.MOUSE_RIGHT_BUTTON"},"keymap.KeyCode.MouseCenterButton":{"retType":"keymap.KeyCode.MouseCenterButton","extendsTypes":["keymap.KeyCode.MouseCenterButton","Number"],"pyQName":"keymap.KeyCode.MOUSE_CENTER_BUTTON"},"pins.LED":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true"}},"pins.SDA":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true"}},"pins.SCL":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true"}},"pins.SCK":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true"}},"pins.MISO":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true"}},"pins.MOSI":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true"}},"pins.RX":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true"}},"pins.TX":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true"}},"config":{"kind":5,"retType":""},"config.DISPLAY_WIDTH":{"kind":4,"retType":"number"},"config.DISPLAY_HEIGHT":{"kind":4,"retType":"number"},"game.reset":{"kind":-3,"attributes":{"blockId":"arcade_game_reset","block":"reset game","group":"Gameplay","weight":10,"help":"game/reset","jsDoc":"Reset the current game. This is usually equivalent to pressing\nthe reset button to restart the current program","_def":{"parts":[{"kind":"label","text":"reset game","style":[]}],"parameters":[]}},"parameters":[]},"player":{"kind":5,"retType":"","attributes":{"color":"#B09EFF"}},"sprites.background":{"kind":5,"retType":""},"sprites.background.autumn":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAADd3d3d3d3d3T3TPTMzMzMzMzMzOzNERDQzMzMzMzMzMzMz0zPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3TMzMzMzMzMzM7u7u7tEREQzMzMzMzMzMzMz093d3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzOzu7s7M0NERES7uzMzMzMzMzMzM93d3d3d3d3d3T1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzO7M7M7M0NEREQ0M7s7MzMzMzMzM9Pd3d3d3d3dPbNERERERERERERERERERETd3d3d3d3d3TMzM7O7u7s7s7szM0M0RDQzM7O7MzMzMzO7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3TMzMzMzM7szMzMzMzM0RDMzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zMzMzszszMzMzMzMzRDQzM7O7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zM9OzO0MzNDMzM0MzQ7S7u7u7u7u7uzMzs7vT3T2zu7u7u7tERERERERERERERERERETd3d3d3d3d3d0z09MzM0RDMzMzM0O0S7S7u7u7OzMzMzMzu7szM93d3bO7u7tLRERERERERERERERERETd3d3d3d3d3d3d0909MzRDMzMzM0NEQzSzMzMzMzMzMzMzuzMzM93d3d09s7tLRERERERERERERERERETd3d3d3d3d3d3d3d3d3TNEMzMzMzNEM7O7MzMzQzMzM7O7OzMz093d3d3d3T1LRERERERERERERERERETd3d3d3d3d3d3d3d3d3T1EQzQzMzNDM7MzMzNDQ7O7u7szMz0z3d3d3d3d3d1NRERERERERERERERERETd3d3d3b27u7vd3d3d3UNERDNEMzMzMzMzMzNENDMzM7szM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d3b3T3d3UNEREM0MzMzMzMzM0NENESzuzszM9MzM93d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d293T3TTUNENDMzMzMzMzMzM0NEQzQzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dPdPd2zPTQ0REQzQzMzMzMzMzMzNERDMzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3d3TPduzMzRERERDM0MzMzMzMzM0NERDMzMzMzM9M93d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dMzPdszMzRERENEM0MzMzu7s7M0NERDQzMzMzM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d09MzPTMzszREREM0MzMzMzMzO7M0NERDQzMzMz0z0zM93d3d3d3d1NRERERERERERERERERETd3d3dPdMzMzMzMzMzRERERDMzMzMzMzOzOzNERDMzMzMzMzPd3d3d3d3d3d1NRERERERERERERERERETd3d3dMzMzMzMzMzNDRERERDOzu7u7u7u7uztENDMzMzM9M9Pd3d3d3d3d3d1DRERERERERERERERERETd3d09MzMzMzMzMzNDREREQzQzMzMzMzO7u0tERDQzMzPdMzPd3d3d3d3d3d1DRERERERERERERERERETd3T09MzMzMzMzMzNDRERENDMzMzMzMzMzs7tEMzMzMzPTM9Pd3d3d3d3d3bNLRERERERERERERERERETd3T0zMzMzMzMzMzNDRERENDMzMzMzMzMzMzNENDMzMzMzM93d3d3d3d09u7tLRERERERERERERERERETd3d09M90zMzMzNDNDREQ0MzMzMzMzMzMzMzOzuzszMzOzu7u7u7u7u7u7u7tLRERERERERERERERERETd3d3dPdMzMzMzNDMzNES0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDQzM0S0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDMzQ0M0MzMzu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDNDMzQzQ0MzMzszszs7S7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDRDM7Q0QzMzOzOzMzM0QzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3d1NRLQ7M0QztLs7MzM0Q0QzMzMzM7O7OzMzu7u7u7u7u7u7u0tERERERERERERERERERETd3d3d3d3d3d1NNLvdM0MzRDMzM0M0Q0QzMzOzu7u7MzM9M93d3d3d3d09s0tERERERERERERERERERETd3d3d3d3d3d3dtNvdMzMzQzMzM0Q0RLu7u7u7uzszMzPTMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d29u9PdMzMzMzMzM0RDRDS7u7s7MzszMzPTPTPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dvbu73d3dM90zMzMzMzRDNDMzMzMzszMzMzMzMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zMzMzMzNEREMzMzOzOzMzMzMzM9M93d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d2zuzszMzNEREQzM7O7MzMzMzMzMzMz3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zM7O7MzNERDQzMzMzMzMzMzMz3TPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d0z0zMz0zMzOzMzNERDMzMzMzMzMzMzPTPTPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d093TMzMzMzMzOzOzNERDQzMzMzMzMzMzMzMzPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3T3TPTMzMzMzMzMzOzNERDQzMzMzMzMzMzMz0zPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3TMzMzMzMzMzM7u7u7tEREQzMzMzMzMzMzMz093d3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzOzu7s7M0NERES7uzMzMzMzMzMzM93d3d3d3d3d3T1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzO7M7M7M0NEREQ0M7s7MzMzMzMzM9Pd3d3d3d3dPbNERERERERERERERERERETd3d3d3d3d3TMzM7O7u7s7s7szM0M0RDQzM7O7MzMzMzO7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3TMzMzMzM7szMzMzMzM0RDMzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zMzMzszszMzMzMzMzRDQzM7O7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zM9OzO0MzNDMzM0MzQ7S7u7u7u7u7uzMzs7vT3T2zu7u7u7tERERERERERERERERERETd3d3d3d3d3d0z09MzM0RDMzMzM0O0S7S7u7u7OzMzMzMzu7szM93d3bO7u7tLRERERERERERERERERETd3d3d3d3d3d3d0909MzRDMzMzM0NEQzSzMzMzMzMzMzMzuzMzM93d3d09s7tLRERERERERERERERERETd3d3d3d3d3d3d3d3d3TNEMzMzMzNEM7O7MzMzQzMzM7O7OzMz093d3d3d3T1LRERERERERERERERERETd3d3d3d3d3d3d3d3d3T1EQzQzMzNDM7MzMzNDQ7O7u7szMz0z3d3d3d3d3d1NRERERERERERERERERETd3d3d3b27u7vd3d3d3UNERDNEMzMzMzMzMzNENDMzM7szM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d3b3T3d3UNEREM0MzMzMzMzM0NENESzuzszM9MzM93d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d293T3TTUNENDMzMzMzMzMzM0NEQzQzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dPdPd2zPTQ0REQzQzMzMzMzMzMzNERDMzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3d3TPduzMzRERERDM0MzMzMzMzM0NERDMzMzMzM9M93d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dMzPdszMzRERENEM0MzMzu7s7M0NERDQzMzMzM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d09MzPTMzszREREM0MzMzMzMzO7M0NERDQzMzMz0z0zM93d3d3d3d1NRERERERERERERERERETd3d3dPdMzMzMzMzMzRERERDMzMzMzMzOzOzNERDMzMzMzMzPd3d3d3d3d3d1NRERERERERERERERERETd3d3dMzMzMzMzMzNDRERERDOzu7u7u7u7uztENDMzMzM9M9Pd3d3d3d3d3d1DRERERERERERERERERETd3d09MzMzMzMzMzNDREREQzQzMzMzMzO7u0tERDQzMzPdMzPd3d3d3d3d3d1DRERERERERERERERERETd3T09MzMzMzMzMzNDRERENDMzMzMzMzMzs7tEMzMzMzPTM9Pd3d3d3d3d3bNLRERERERERERERERERETd3T0zMzMzMzMzMzNDRERENDMzMzMzMzMzMzNENDMzMzMzM93d3d3d3d09u7tLRERERERERERERERERETd3d09M90zMzMzNDNDREQ0MzMzMzMzMzMzMzOzuzszMzOzu7u7u7u7u7u7u7tLRERERERERERERERERETd3d3dPdMzMzMzNDMzNES0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDQzM0S0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDMzQ0M0MzMzu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDNDMzQzQ0MzMzszszs7S7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDRDM7Q0QzMzOzOzMzM0QzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3d1NRLQ7M0QztLs7MzM0Q0QzMzMzM7O7OzMzu7u7u7u7u7u7u0tERERERERERERERERERETd3d3d3d3d3d1NNLvdM0MzRDMzM0M0Q0QzMzOzu7u7MzM9M93d3d3d3d09s0tERERERERERERERERERETd3d3d3d3d3d3dtNvdMzMzQzMzM0Q0RLu7u7u7uzszMzPTMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d29u9PdMzMzMzMzM0RDRDS7u7s7MzszMzPTPTPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dvbu73d3dM90zMzMzMzRDNDMzMzMzszMzMzMzMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zMzMzMzNEREMzMzOzOzMzMzMzM9M93d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d2zuzszMzNEREQzM7O7MzMzMzMzMzMz3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zM7O7MzNERDQzMzMzMzMzMzMz3TPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d0z0zMz0zMzOzMzNERDMzMzMzMzMzMzPTPTPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d093TMzMzMzMzOzOzNERDQzMzMzMzMzMzMzMzPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3T3TPTMzMzMzMzMzOzNERDQzMzMzMzMzMzMz0zPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3TMzMzMzMzMzM7u7u7tEREQzMzMzMzMzMzMz093d3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzOzu7s7M0NERES7uzMzMzMzMzMzM93d3d3d3d3d3T1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzO7M7M7M0NEREQ0M7s7MzMzMzMzM9Pd3d3d3d3dPbNERERERERERERERERERETd3d3d3d3d3TMzM7O7u7s7s7szM0M0RDQzM7O7MzMzMzO7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3TMzMzMzM7szMzMzMzM0RDMzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zMzMzszszMzMzMzMzRDQzM7O7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zM9OzO0MzNDMzM0MzQ7S7u7u7u7u7uzMzs7vT3T2zu7u7u7tERERERERERERERERERETd3d3d3d3d3d0z09MzM0RDMzMzM0O0S7S7u7u7OzMzMzMzu7szM93d3bO7u7tLRERERERERERERERERETd3d3d3d3d3d3d0909MzRDMzMzM0NEQzSzMzMzMzMzMzMzuzMzM93d3d09s7tLRERERERERERERERERETd3d3d3d3d3d3d3d3d3TNEMzMzMzNEM7O7MzMzQzMzM7O7OzMz093d3d3d3T1LRERERERERERERERERETd3d3d3d3d3d3d3d3d3T1EQzQzMzNDM7MzMzNDQ7O7u7szMz0z3d3d3d3d3d1NRERERERERERERERERETd3d3d3b27u7vd3d3d3UNERDNEMzMzMzMzMzNENDMzM7szM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d3b3T3d3UNEREM0MzMzMzMzM0NENESzuzszM9MzM93d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d293T3TTUNENDMzMzMzMzMzM0NEQzQzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dPdPd2zPTQ0REQzQzMzMzMzMzMzNERDMzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3d3TPduzMzRERERDM0MzMzMzMzM0NERDMzMzMzM9M93d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dMzPdszMzRERENEM0MzMzu7s7M0NERDQzMzMzM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d09MzPTMzszREREM0MzMzMzMzO7M0NERDQzMzMz0z0zM93d3d3d3d1NRERERERERERERERERETd3d3dPdMzMzMzMzMzRERERDMzMzMzMzOzOzNERDMzMzMzMzPd3d3d3d3d3d1NRERERERERERERERERETd3d3dMzMzMzMzMzNDRERERDOzu7u7u7u7uztENDMzMzM9M9Pd3d3d3d3d3d1DRERERERERERERERERETd3d09MzMzMzMzMzNDREREQzQzMzMzMzO7u0tERDQzMzPdMzPd3d3d3d3d3d1DRERERERERERERERERETd3T09MzMzMzMzMzNDRERENDMzMzMzMzMzs7tEMzMzMzPTM9Pd3d3d3d3d3bNLRERERERERERERERERETd3T0zMzMzMzMzMzNDRERENDMzMzMzMzMzMzNENDMzMzMzM93d3d3d3d09u7tLRERERERERERERERERETd3d09M90zMzMzNDNDREQ0MzMzMzMzMzMzMzOzuzszMzOzu7u7u7u7u7u7u7tLRERERERERERERERERETd3d3dPdMzMzMzNDMzNES0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDQzM0S0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDMzQ0M0MzMzu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDNDMzQzQ0MzMzszszs7S7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDRDM7Q0QzMzOzOzMzM0QzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3d1NRLQ7M0QztLs7MzM0Q0QzMzMzM7O7OzMzu7u7u7u7u7u7u0tERERERERERERERERERETd3d3d3d3d3d1NNLvdM0MzRDMzM0M0Q0QzMzOzu7u7MzM9M93d3d3d3d09s0tERERERERERERERERERETd3d3d3d3d3d3dtNvdMzMzQzMzM0Q0RLu7u7u7uzszMzPTMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d29u9PdMzMzMzMzM0RDRDS7u7s7MzszMzPTPTPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dvbu73d3dM90zMzMzMzRDNDMzMzMzszMzMzMzMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zMzMzMzNEREMzMzOzOzMzMzMzM9M93d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d2zuzszMzNEREQzM7O7MzMzMzMzMzMz3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zM7O7MzNERDQzMzMzMzMzMzMz3TPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d0z0zMz0zMzOzMzNERDMzMzMzMzMzMzPTPTPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d093TMzMzMzMzOzOzNERDQzMzMzMzMzMzMzMzPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3T3TPTMzMzMzMzMzOzNERDQzMzMzMzMzMzMz0zPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3TMzMzMzMzMzM7u7u7tEREQzMzMzMzMzMzMz093d3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzOzu7s7M0NERES7uzMzMzMzMzMzM93d3d3d3d3d3T1ERERERERERERERERERETd3d3d3d3dPTMzMzMzMzO7M7M7M0NEREQ0M7s7MzMzMzMzM9Pd3d3d3d3dPbNERERERERERERERERERETd3d3d3d3d3TMzM7O7u7s7s7szM0M0RDQzM7O7MzMzMzO7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3TMzMzMzM7szMzMzMzM0RDMzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zMzMzszszMzMzMzMzRDQzM7O7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3T0zM9OzO0MzNDMzM0MzQ7S7u7u7u7u7uzMzs7vT3T2zu7u7u7tERERERERERERERERERETd3d3d3d3d3d0z09MzM0RDMzMzM0O0S7S7u7u7OzMzMzMzu7szM93d3bO7u7tLRERERERERERERERERETd3d3d3d3d3d3d0909MzRDMzMzM0NEQzSzMzMzMzMzMzMzuzMzM93d3d09s7tLRERERERERERERERERETd3d3d3d3d3d3d3d3d3TNEMzMzMzNEM7O7MzMzQzMzM7O7OzMz093d3d3d3T1LRERERERERERERERERETd3d3d3d3d3d3d3d3d3T1EQzQzMzNDM7MzMzNDQ7O7u7szMz0z3d3d3d3d3d1NRERERERERERERERERETd3d3d3b27u7vd3d3d3UNERDNEMzMzMzMzMzNENDMzM7szM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d3b3T3d3UNEREM0MzMzMzMzM0NENESzuzszM9MzM93d3d3d3d1NRERERERERERERERERETd3d3d3d3d3d293T3TTUNENDMzMzMzMzMzM0NEQzQzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dPdPd2zPTQ0REQzQzMzMzMzMzMzNERDMzMzMzMzMz3d3d3d3d3d1NRERERERERERERERERETd3d3d3d3d3TPduzMzRERERDM0MzMzMzMzM0NERDMzMzMzM9M93d3d3d3d3d1NRERERERERERERERERETd3d3d3d3dMzPdszMzRERENEM0MzMzu7s7M0NERDQzMzMzM90z093d3d3d3d1NRERERERERERERERERETd3d3d3d09MzPTMzszREREM0MzMzMzMzO7M0NERDQzMzMz0z0zM93d3d3d3d1NRERERERERERERERERETd3d3dPdMzMzMzMzMzRERERDMzMzMzMzOzOzNERDMzMzMzMzPd3d3d3d3d3d1NRERERERERERERERERETd3d3dMzMzMzMzMzNDRERERDOzu7u7u7u7uztENDMzMzM9M9Pd3d3d3d3d3d1DRERERERERERERERERETd3d09MzMzMzMzMzNDREREQzQzMzMzMzO7u0tERDQzMzPdMzPd3d3d3d3d3d1DRERERERERERERERERETd3T09MzMzMzMzMzNDRERENDMzMzMzMzMzs7tEMzMzMzPTM9Pd3d3d3d3d3bNLRERERERERERERERERETd3T0zMzMzMzMzMzNDRERENDMzMzMzMzMzMzNENDMzMzMzM93d3d3d3d09u7tLRERERERERERERERERETd3d09M90zMzMzNDNDREQ0MzMzMzMzMzMzMzOzuzszMzOzu7u7u7u7u7u7u7tLRERERERERERERERERETd3d3dPdMzMzMzNDMzNES0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDQzM0S0u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dMzNDRDMzQ0M0MzMzu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDNDMzQzQ0MzMzszszs7S7u7u7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3dPTNDRDM7Q0QzMzOzOzMzM0QzMzO7u7u7u7u7u7u7u7u7u7u7u7tERERERERERERERERERETd3d3d3d3d3d1NRLQ7M0QztLs7MzM0Q0QzMzMzM7O7OzMzu7u7u7u7u7u7u0tERERERERERERERERERETd3d3d3d3d3d1NNLvdM0MzRDMzM0M0Q0QzMzOzu7u7MzM9M93d3d3d3d09s0tERERERERERERERERERETd3d3d3d3d3d3dtNvdMzMzQzMzM0Q0RLu7u7u7uzszMzPTMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d29u9PdMzMzMzMzM0RDRDS7u7s7MzszMzPTPTPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3dvbu73d3dM90zMzMzMzRDNDMzMzMzszMzMzMzMzPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zMzMzMzNEREMzMzOzOzMzMzMzM9M93d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d2zuzszMzNEREQzM7O7MzMzMzMzMzMz3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d3d3d3d0zM7O7MzNERDQzMzMzMzMzMzMz3TPT3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d3d0z0zMz0zMzOzMzNERDMzMzMzMzMzMzPTPTPd3d3d3d3d3U1ERERERERERERERERERETd3d3d3d3d3d093TMzMzMzMzOzOzNERDQzMzMzMzMzMzMzMzPT3d3d3d3d3U1EREREREREREREREREREQ="}},"sprites.background.cityscape":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAACZmZmZmZmZmZmZmZmZERERERER3d3d3d3d3d3d3b27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmREZERERERER0d3d3d3d3d3d3bu7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERER3dHR3d3d3d3d3bu9u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERER3d3d3d3d3d3d3b29u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERERERHR3d3d3d3d3bu7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmREREREREREREREREbG7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkRERERERERERHR3b3bu7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERERERHR3b3bu7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRERERERERHRHdEd3b27u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERHR3d3d3b27u7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERHRHd0d3b27u7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERER3d3d3b27u7u7u7u7u7u7u7t7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRkRGRERERERERER3dHd3b27vdvbu7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERkRERERERERERHdHd3b27u7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERERERER3dHd3d3d3d3d3bu7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERERERER3dHd3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZkRERERERERERERER3d3d3d3d3d27u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkRERkREREREREREd3d3d3d3d3d3d3bu729u7u7u7t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREZERERERERER0d3d3d3d3d3d3d3bu729u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkRERERERERERER3d0d0d3d3d3d3d27u7u9u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkRERERERERERER3R0d3d3d3d3d3d273bu9u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZGRERERERERERERER3d3d3d3d3d3d3d27u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERER0R0d3d3d3d3d3d3dvbu7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZEREREREREREREREREREREdHd3d3d3bu7u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERERERERERER3d3dvbu7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERERERERERER3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZGRERERERERERERERERER3d3d0d3d3d3d3d27u7u92727u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkRERERERERERERERHR3d3d3d3d3d3d3b27u7vdu717d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREREREREREREREdHd3d3d3d3d3d3d3d3du7vdu727d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERERERERERHR3d3d3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERERERERERER3d3d3d3d3d3d3b27u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREREREREREREREREREdHd3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkRERERERERERERERERERHR3d3d3d3d3d3du7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZERERERERERERERERERERERERsbvbu7u9u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZEREZEREREREREREREdHd3d3dvbu7u7u7u7u7u7t3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZEZEREREREREREREREdHd3d3dvbu7u7u7u7u7vdt7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZkRERERERERERERERHd3d3dvbvbu7u9u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZkREREREREREREREdHd3d3dvbu7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmREREREREREREREREdEd3d3d3d29u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZGREREREREREREREREREd3d3d3d3d3d3du7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZGREREREREREREREREdHd3d3d3d3d3d3du7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERHd3d3d3d3d3bu7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERHd0d3d3d3d3bvb27u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZkRkZkRERHd0d3d3d3du7vbu7u7vbu7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRERERHd3d3d3d3du7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERHd3d3d3d3du7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERHd3d3d3d3d3bu7u7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRGRERHd3d3d3d3d3bu7u7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRHdHd3R0d3d3d3d3d3d3d3dvbu7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmRHd3d3d3d3d3d3d3d3d3d3dvbu7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGREREREREdHd3d3d3d3d3d3d3d3dvbt7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERERERHR3d3d3d29u7u7u7u7u7t7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERHR3d3d3d3d3d29u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmRERERHR0R0d3d29u7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmRERERHR0R0d3bu7u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZERERERHR3d29u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZERERERHRHdG9u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZERERERHR3d3du7u7u7u7u7u7u7u7u7t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZEREREREREd3d3bu7u7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmREZEREREdHd3d3d3d29u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRGZEREREd3d3d3d3d3d3d29u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERERERHR3d3d3d3du7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERERERHR3d0d3RG929u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERERERHd3d0d0R29u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRERERERERERERER0d0d0R3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkRERERERERERHR3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERERERHd3d3d3d3d3d3d3d3du7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERERERHR3d3d3d3d3d27u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERERERER0d3d3d29u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkRGREREd3d0d0d3d3d3d27u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGREREd3d3d3d3d3d3d27vbu9u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGREREd3d3d3d3d3dHd2xu7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGREREd3d0d0d3d3d3d2927u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmREREd3d3d3d3d3d3d29u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkRERER3d3d3d3d3d293bu7u7u7u7t3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkRERERERER0d3d3d2927u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkRERERERER0d3d3d29u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3dvbu7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdHd0dHd3d3d3d3dvbu7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZ0d3d0d3dHd3d3d3du7u7u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d29u729u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d29u7vbu7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZEdHd3d3d3d3d3d3du729u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmREZEdHd3d3d3d3d3d3d3d3d3bu7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGREREREREREREREREd3d3d3d3d29u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGREREREREREREREREd3d3d3d3d29u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGREREREREREREREREREREd3d3bu7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRERERERERER3d3d3d3d3d27u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkRERERERER3d3d3d3d3bu7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERER3d3d3d3d3d3d3bu7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmREREdHd3d3d3d3d3d3d3d29u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRER3d3d3d3d3d3d3d3d3d3d3bu7u7u7u7t7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRER3d3d3d3d3d3d3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRER0d3d3d3d3d3d3d3d3d3d3d3d3d3du7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRkRGREREdHd3d3d3d3d3d3d3d3d3d29u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERkRERERER3d3d3d3d3d3d3d3d3bu927u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERERERER3d3d3d3d3d3d3b27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERERERER0d3d3d3d3d3d3b29u7u7u7t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZkRERERERERERERER3dHR3d3d3d3d3bu9u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkRERkRERERERERERER3d3d3d3d3d3d3bu7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREZERERERERERERERERHR3d3d3d3d3bu7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkRERERERERERERERERERHR3b27u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREREREREREREREREREREREbG7u7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZGRERERERERERERERERERERHR3b3bu7u7u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERERERER3d3d3b27u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERERERHR3d3d3b3bu727u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERERERHRHd0d3b27u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERERERERERERERERERER3d3d3b27vbvbu7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZGRERERERERERERERERER3dHd3b27vdvbu7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkRERERERERERERERER3d3d3b27u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkRERERERERERERERERHdHd3b27u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERERERERERER3dHd3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERERERERERER3d3d3d3d3d27u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREREREREREREREd3d3d3d3d3d3d3bu729u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkREREREREREREREd3d3d3d3d3d3d3bu729u7u7u7t3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZERERERERERER0d3d3d3d3d3d3d27u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZEREZERERERER3R0d3d3d3d3d3d273bu9u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZEZERERERERER3d3d0d3d3d3d3d27u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZkRERERERER0R0d3d3d3d3d3d27u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZkREREREREREREREdHd3d3d3bu7u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERERERERERER3d3d3bu7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZGRERERERERERERERERER3d3d3d3d3d3du7u9u727u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZGREREREREREREREREdHd3d3d3d3d3d27u7u92727d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmRERERERERERERHR3d3d3d3d3d3d3d27u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmREREREREREREdHd3d3d3d3d3d3d3d3du7vdu727u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZkRkZkREREREdHd3d3d3d3d3d3d3d27u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRERERERERER3d3d3d3d3d3d3b27u73dvbt7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGREREREREREREdHd3d3d3d3d3d27u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERERERERERHR3d3d3d3d3d29u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRGRERERERERERERERER0b27u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERERERER3d3dvbu7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmREREREREdEd3dHdvbu7u7u7u7u7vbt7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERERERHd3d3dvbu7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGREREREREREd3d3dvbu7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGREREREREdEd3d3d3b27u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmREREREREdHd3d3d3d29u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmREREREREdHd3d3d3d3d3d3du7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZERHd3d3d3d3d3d3d3d3d3d3du7u7u7t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZERHd3d3d3d3d3bu7u7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZERHd0d3d3d3d3bu7u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZERHd3d3d3d3du7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmREZERHd0R3d3d29u7u72729u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRGZERHd3d3d3d3d3bu7u7u7vbvbu7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERHdHd3d0d3d3bu7u7u7u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERHdHd3R0d3d3bu7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGRERERHd3d3d3d3d3d3d3d3d3d3dvbu7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRERERHd3d3d3d3d3d3d3d3d3d3d3d27u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkRERERERERERHR3d3d3d29u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERHR3d3d3d3d3d29u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERHR0R0d3d29u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkRERERERHR0R0d3bu7u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkRGRERERHR3d29u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERHRHdG9u7u7u7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERHR3d29u7u7u7u7u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGRERERHR3d3d3bu7u7u7u7u7u7u7u7t3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmREREdHd3d3d3d29u7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkREdHd3d3d3d29u7u7u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkRERERERER0d0d3R29u7u7u7u7u7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkRERERERHR3d0d3RG9u7u7u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkRERERERHR3d3d3d29u7u7u7u7u7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3c="}},"sprites.background.cityscape2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAACZmZmZ0d3dHBGxuxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G70bsbu7y8u7u7u7u7u7u7u7u7vLvbu7u7uZmZmZEd3RHBGxuxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7y8y7u7u7u7u7u7u7u7vLu7u7u7uZmZmZEd3RHMy8uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebvbu7zMy7u7u7u7u7u7u7u7u7vLu7u7uZmZmZ0d3dHNy9u9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7HbvbvLvMu7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0dHRHNy9uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7EbvbvLu7u8u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7EbsbvLu7u8u7u7u7u7u7u7u7u7u7u7u7uZmZkR0d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7vLu7u7u7u7u7u7u7u7u7u7u7u7uZmZnR3d3dHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZnR3d3dHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZkRERERHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZmRndHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZERHdHNy9uxu9u7u7u7u7u7u7G727u7u7u7u7u7u727Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0d3dHMy8u9u9u8u7u7u7u7u7G7G7u7u7u7u7u7u7273bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZEd3dHBGxu9u9u7y7u7u7u7u7G7G7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0R3dHBGxuxu9u9y7u7u7u7u7G7G7u7u7u7u7u7u7G70bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0d3dHMy8uxuxu9y7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZERHdHNy9u9uxu7y7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbu7u7u7u7u7u7u7uZmZmZmRkRHNy9u9u9u8u7u7u7u7u72727u7u7u7u7u7u7G7Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmZmZmRndHNy9uxu9u7u7u7u7u7u7u727u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7uZmZmZERHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0dHRHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0dHRHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0dHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHMy8uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHBGxuxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmRkR0d3dHBGxu9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmRHd3d3dHMy8u9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u8u7uZGdHd3d3dHNy9u9u9u7u7u7u7u7u7u7u7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u8u7uZGd3dHd3dHNy9u9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZGd0d3d3dHNy9uxu9u7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7vLu7uZGd3d3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7vLu7uZGdEd3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7vLvLuZmREREdHdHNy9uxuxu7u7u7u7u7u727u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7vLy7uZmZmZGRHRHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7vLzLuZmZmZERHRHNy9uxuxu7u7u7u7u7u7G727u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7vbsbu7u7u7u7vLy7uZmZmZ0d0dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7vbvbu7u7u7u7vLu7yZmZkR0d3dHMy8uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7270bsbu7u7u7u7u7vLu7vbu7u7u7u7u8u7yZmZnR3d3dHBGxuxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G70bsbu7u7u7u7vLu7u7u7u7u7u7u7u7u7uZmZkR0d3dHBGxuxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7vLvbu7u7u7u7u7u7u7u7uZmZmZ0d3dHMy8uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebvbu7u7u7u7vLvbu7u7u7u7u7u7u7u7uZmZmZEdHdHNy9u9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Hbvbu7u7u7u7vLu7u7u7u7u7u7u7u7u7uZmZmZGRHdHNy9uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7vLu7u7u7u7u7u7u7u7uZmZmZGRERHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGd0dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGd3dHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGdHdHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGd3dHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGd3RHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGdHRHNy9uxu9u7u7u7u7u7u7G727u7u7u7u7u7u727Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7sZEREREdHdHMy8u9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u7273bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7sZ3d3d3d3dHBGxu9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7sZ3dHd3d3dHBGxuxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G70bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7sZ3dHd3d3dHMy8uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7sZ3d3d3d3dHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbu7u7u7u7u7u7u7sZ3d3d3d3dHNy9u9u9u7u7u7u7u7u72727u7u7u7u7u7u7G7Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxu9u7u7u7u7u7u7u727u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZ3R3dEd3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZEREREdHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZERHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZEd3RHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZEd3RHMy8uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3RHBGxuxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0dHRHBGxu9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZmZ0d3dHMy8u9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZkREdHdHNy9u9u9u7u7u7u7u7u7u7u7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmRnR3d3dHNy9u9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmRnd3d3dHNy9uxu9u7u7u7u7u7u7u7u7u7u8u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7uZmRkRERHdHNy9uxuxu7u7u7u7u7u7u7u7u8u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZmRHdHNy9uxuxu7u7u7u7u7u7u7u7u8u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZmdHdHNy9uxuxu7u7u7u7u7u727u7u8u8u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZmRERHNy9uxuxu7u7u7u7u7u72727u7vLu7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZmRHdHNy9uxuxu7u7u7u7u7u7G727u7vLvLu7u7u7G7Ebsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZmZmdHdHNy9uxuxu7u7u7u7u7u7G7G7u7u8vLu7u7u727Ebsbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmZmZmRHdHMy8uxuxu7u7u7u7u7u7G7G7u8vLvLu7u7u7270bsbu7u7u7u7u7u7u7vbu7u7u7u7u7u7uZmRkRERERHBGxuxuxu7u7u7u7u7u7G7G7u8u8vLu7u7u7G70bsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRndHd3RHBGxuxuxu7u7u7u7u7u7G7G7u8u7vLu7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRnd3d3dHMy8uxu9u7u7u7u7u7u7G7G7u8u7y7u7u7u7G7Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRnd3d3dHNy9u9u9u7u7u7u7u7u7G7G7u7y7u7u7u7u7G7Hbvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRndHd3RHNy9uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRnd3d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRkR0d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZEdHdHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmREREdHdHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmdHd3d3dHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZEdHd0d3dHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZ0d3d0dHdHNy9uxu9u7u7u7u7u7u7G727u7u7u7u7u7u727Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZ0d3d3d3dHMy8u9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u7273bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZ0d3d3d3dHBGxu9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZEdHd3d3dHBGxuxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G70bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmdHd3d3dHMy8uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRERERERHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbu7u7u7u7u7u7u7uZmZmZmZnRHNy9u9u9u7u7u7u7u7u72727u7u7u7u7u7u7G7Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmZmZERERHNy9uxu9u7u7u7u7u7u7u727u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZkR0d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmRER3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u8u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZEdHd3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7y7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxuxu7y7u7u7u7u7u7u7u7u7u9y7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxuxu7y7u7u7u7u7u7u7u7u7u9y7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZ0d3d3d3dHNy9uxuxu7y7u7u7u7u7u7u7u7u7u7y7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZEdHd3d3dHMy8uxuxu7y7u7u7u7u7u7u7u7u7u8u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmRER3d3dHBGxuxuxu8u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZkR0d3dHBGxu9uxu8y7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZmZEd3dHMy8u9uxu7y8u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZmZ0R3dHNy9u9u9y7u7u7u7u7u7u7u7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmZmZ0d3dHNy9u9uxy7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZmZERHdHNy9uxu9y7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7uZmZmZmRndHNy9uxuxy7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZmRkRHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZERHdHNy9uxuxu7u7u7u7u7u727u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZ0d3dHNy9uxuxu7u7u7u7u7u7G727u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7uZmZmZ0dHRHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmZmZ0d3dHMy8uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7270bsbu7u7u7u7u7u7u7vbu7u7u7u7u7u7uZmZmZ0d3dHBGxuxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0d3dHBGxuxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0dHdHMy8uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZ0d3dHNy9u9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Hbvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRkR0d3dHNy9uxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRnd3d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmRHd3d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZGdHd3d3dHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZGd0d3d3dHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZGd3dHd3dHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZGdEd3d3dHNy9uxuxu7u7u7u7u7u727G7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmREREdHdHNy9uxu9u7u7u7u7u7u7G727u7u7u7u7u7u727Ebvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGRHRHMy8u9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u7273bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZGRHRHBGxu9u9u7u7u7u7u7u7G7G7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZmZEdHdHBGxuxu9u7u7u7u7u7u7G7G7u7u7u7u7u7u7G70bvbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZkR0d3dHMy8uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7u7u7u7u7u7u7u7u7uZmZnR3d3dHNy9u9uxu7u7u7u7u7u727G7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbu7u7u7u7u7u7u7uZmZnR3d3dHNy9u9u9u7u7u7u7u7u72727u7u7u7u7u7u7G7Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7uZmZkR0d3dHNy9uxu9u7u7u7u7u7u7u727u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7uZmZmZEdHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGRHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZmRkRHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u727Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGRHRHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGd3RHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGdHdHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGdHRHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7270bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGd3RHMy8uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7uZmZmZGd3dHBGxuxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZEREREdHdHBGxu9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7sZ3d3d3d3dHMy8u9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9u9u9u7u7u7u7u7u7u7u7u7u7u7u7u7u727Hbvbu7u7u7u7u7u7vbvbu7u7u7u7u7u7sZ3dHd3d3dHNy9u9uxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Hbsbu7u7u7u7u7u7vbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxu9u7u7u7u7u7u7u7u7u7u7u7u7u7u7G7Ebvbu7u7u7u7u7u7sbvbu7u7u7u7u7u7sZ3dEd3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7G70bsbu7u7u7u7u7u7sbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxuxu7u7u7u7u7u7u7u7u7u7u7u7u7u7270bsbu7u8u7u7u7u7sbsbu7u7u7u7u7u7sZ3R3dHd3dHNy9uxuxu7u7u7u7u7u727u7u7u7u7u7u7u7270bsbu7u8u7u7u7u7sbsbu7u7u7u7u7u7sZ3R3dEd3dHNy9uxuxu7u7u7u7u7u72727u7u7u7u7u7u7G70bsbu7u7y7u7u7u7sbsbu7u7u7u7u7u7sZ3d3d3d3dHNy9uxuxu7u7u7u7u7u7G727u7u7u7u7u7u7G7Ebsbu7u7y7u7u7u7vbsbu7u7u7vLu7u7sZ3d3d3d3dHNy9uxuxu7u7u7u7u7u7G7G7u7u7u7u7u7u727Ebsbu7u7y7u7u7u7vbvbu7u7vLu7u7u7sZERER0d3dHMy8u9uxu7u7u7u7u7u7G7G7u7u7u7u7u7u7273bsbu7y7y7u7u7u7u7vbu7u7vLvbu7u7s="}},"sprites.background.desert":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAAAzMzMzMzMzMxERMzMzM2N3d3d3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMx0RMzMzM2N3d3d3d3d3d3d3M93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzExERMzMzM2N3d3d3d3d3d3d3N93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTERERMzMzM2N2d3d3d3d3d3d3N9Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRERERMzMzMzNmd3d3d3d3d3d3N9Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzM9MRERERMzMzMzMzZnd3d3d3d3d3Mz3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRERERMzMzMzMzM2ZmZnd3d3d30z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRERERMzMzMzMzMzNjZmZmZmY2093T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzM9MRERERM2ZmZmZmZmZmZmZmZmY23d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRERERZnZ3d3d3d3d3d3d3d2cz3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzPTERFhdnd3d3d3d3d3d3d3dzfT3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzHRFmd3d3d3d3d3d3d3d3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzERF2d3d3d3d3d3d3d3d3dzPd3d09093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzERF2d3d3d3d3d3d3d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzExF2d3d3d3d3d3d3d3d3N9Pd3d3dM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMx1md3d3d3d3d3d3d3d3N93d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxNhdnd3d3d3d3d3d3dnNt3d3d3dPdPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERZnZ3d3d3d3d3d2dmN93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERM2ZmZmZ3Z2ZmZmZ3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERMzMzM2N3ZzMzZnd3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxMRMzMzM2N3ZzNjdnd3N93d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMTMzMzZmZ3ZzNjd3d3N9Pd3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzMzMTMzNjdnd3ZzNmd3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNTVTMzMzMTMzN2d3d3ZzN2d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzMzPTMzN2d3d3ZjN2d3d3dzPd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzNjdndnNjN2d3d3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzZmY2MzN2d3d3dzfT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzN2d3d3d3fT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzN2d3d3d3cz3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzN2d3d3d3c33T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzNmd3d3d3c33dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzNjd3d3d3c309Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzNTMzMzMzMzNjdnd3d3d309Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNTVTUzMzMzMzMzZnd3d3d3M93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNVVTMzMzMzY2ZmZmZ3d3d3M93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNTVTUzMzNjZmZmZmZmd3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzNTMzMzNmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMz0zMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzEzMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzHTMzMzMzM2NmZmZmZmZmZmZmM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTETMzMzMzM2NmZmZmZmZmZmZmNt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRETMzMzMzMzNmZmZmZmZmZmZmNtPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRETMzMzMzMzNjZmZmZmZmZmZmNtPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTETMzMzMzMzMzM2NmZmZmZmZmMz3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzPTETMzMzMzMzMzMzMzM2Z3d3dn0z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRETMzMzMzMzMzMzMzY3Z3d3c3093T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRETMzMzMzMzMzMzMzY3d3d3c33d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxERETMzMzMzMzMzMzMzY3d3d3cz3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxERETMzMzM1MzMzMzMzdnd3dzfT3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxERETMzM1NVMzMzMzMzdnd3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRETMzMzM1MzMzMzMzdnd3dzPd3d09093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMdETMzMzMzMzMzMzMzdnd3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTETMzMzMzMzMzMzMzdnd3N9Pd3d3dM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzHTMzMzMzMzMzMzMzZnd3N93d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzEzMzMzMzZmZmZmYzY3d3N93d3d3dPdPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMz0zMzMzNjd3d3d2c2Y3Z3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzNjd3d3d3dmM2Z3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzZmZmZndnM2NmNt3d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzM3ZnMzNmNt3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzM3ZnZmZmNtPd3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNmZmZmZmZmZnZ3d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzM2N2d3d3d3d3d3d3d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzM3Z3d3d3d3d3d3d3d3d3dzPd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzM3Z3d3d3d3d3d3d3d3d3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzM2Z3d3d3d3d3d3d3d3d3dzfT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNTVTUzM2Nmd3d3d3d3d3d3d3d3d3fT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNVVTMzMzNjZmZmZmZmZmZ3d2ZmZmYz3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNTVTUzMzMzMzMzMzMzM2N2d2ZmZmY23T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzMzMzMzMzMzMzM2Z2d2ZmZmY23dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzNjZnd3d2ZmZmY209Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzN2d3d3Z2ZmZmZm09Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzNmd3dmZmZmZmZmM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzNjZmZmZmZmZmZmM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzM2NmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzPTMzMzMzMzM2NmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMTMzMzMzNjZmZ3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxMRMzMzMzNmd3d3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERMzMzM2N2d3d3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERMzMzM2N3d3d3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMx0RMzMzM2N3d3d3d3d3d3d3M93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzExERMzMzM2N3d3d3d3d3d3d3N93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTERERMzMzM2N2d3d3d3d3d3d3N9Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRERERMzMzMzNmd3d3d3d3d3d3N9Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzM9MRERERMzMzMzMzZnd3d3d3d3d3Mz3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRERERMzMzMzMzM2ZmZnd3d3d30z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRERERMzMzMzMzMzNjZmZmZmY2093T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzM9MRERERM2ZmZmZmZmZmZmZmZmY23d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRERERZnZ3d3d3d3d3d3d3d2cz3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzPTERFhdnd3d3d3d3d3d3d3dzfT3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzHRFmd3d3d3d3d3d3d3d3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzERF2d3d3d3d3d3d3d3d3dzPd3d09093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzERF2d3d3d3d3d3d3d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzExF2d3d3d3d3d3d3d3d3N9Pd3d3dM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMx1md3d3d3d3d3d3d3d3N93d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxNhdnd3d3d3d3d3d3dnNt3d3d3dPdPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERZnZ3d3d3d3d3d2dmN93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERM2ZmZmZ3Z2ZmZmZ3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERMzMzM2N3ZzMzZnd3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxMRMzMzM2N3ZzNjdnd3N93d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMTMzMzZmZ3ZzNjd3d3N9Pd3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzMzMTMzNjdnd3ZzNmd3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNTVTMzMzMTMzN2d3d3ZzN2d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzMzPTMzN2d3d3ZjN2d3d3dzPd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzNjdndnNjN2d3d3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzZmY2MzN2d3d3dzfT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzN2d3d3d3fT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzN2d3d3d3cz3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzN2d3d3d3c33T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzNmd3d3d3c33dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzNjd3d3d3c309Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzNTMzMzMzMzNjdnd3d3d309Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNTVTUzMzMzMzMzZnd3d3d3M93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNVVTMzMzMzY2ZmZmZ3d3d3M93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNTVTUzMzNjZmZmZmZmd3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzNTMzMzNmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMz0zMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzEzMzMzMzM2NmZmZmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzHTMzMzMzM2NmZmZmZmZmZmZmM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTETMzMzMzM2NmZmZmZmZmZmZmNt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRETMzMzMzMzNmZmZmZmZmZmZmNtPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRETMzMzMzMzNjZmZmZmZmZmZmNtPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTETMzMzMzMzMzM2NmZmZmZmZmMz3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzPTETMzMzMzMzMzMzMzM2Z3d3dn0z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMRETMzMzMzMzMzMzMzY3Z3d3c3093T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRETMzMzMzMzMzMzMzY3d3d3c33d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxERETMzMzMzMzMzMzMzY3d3d3cz3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxERETMzMzM1MzMzMzMzdnd3dzfT3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxERETMzM1NVMzMzMzMzdnd3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMxMRETMzMzM1MzMzMzMzdnd3dzPd3d09093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMdETMzMzMzMzMzMzMzdnd3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMTETMzMzMzMzMzMzMzdnd3N9Pd3d3dM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzHTMzMzMzMzMzMzMzZnd3N93d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzEzMzMzMzZmZmZmYzY3d3N93d3d3dPdPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMz0zMzMzNjd3d3d2c2Y3Z3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzNjd3d3d3dmM2Z3N93d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzZmZmZndnM2NmNt3d3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzM3ZnMzNmNt3d3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzM3ZnZmZmNtPd3d3dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzNmZmZmZmZmZnZ3d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzM2N2d3d3d3d3d3d3d3d3d9Pd3d3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzM3Z3d3d3d3d3d3d3d3d3dzPd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzM3Z3d3d3d3d3d3d3d3d3dzfd3d093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzM2Z3d3d3d3d3d3d3d3d3dzfT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNTVTUzM2Nmd3d3d3d3d3d3d3d3d3fT3d3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNVVTMzMzNjZmZmZmZmZmZ3d2ZmZmYz3T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzNTVTUzMzMzMzMzMzMzM2N2d2ZmZmY23T3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzNTMzMzMzMzMzMzMzM2Z2d2ZmZmY23dPd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzNjZnd3d2ZmZmY209Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzN2d3d3Z2ZmZmZm09Pd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzNmd3dmZmZmZmZmM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzNjZmZmZmZmZmZmM93d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzM2NmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzPTMzMzMzMzM2NmZmZmZmZm093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMzMTMzMzMzNjZmZ3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxMRMzMzMzNmd3d3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0zMzMzMzMzMxERMzMzM2N2d3d3d3d3d3d3093d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0="}},"sprites.background.forest1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAAAREREREREREREREREREREREdHd3d2ZmZmZmZmZmZmZmZlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERER3d3d3d2dmZmZmZmZmZmZmZZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREdHd3d3d3d2dmZmZmZmZmZaWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3d3dmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3dnZmZmZmZaWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREdHd3d3d3d3d3d3d3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZlpmZlmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d3ZmZlmlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1plpZmZplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1pZmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbd1tZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbW1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3W1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d1m1mZmZmZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3WZm1mZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3Wbd1mmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d1tmZmWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d2dmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d3d3d3d2ZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3d3Z2ZmWZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3d3ZlpaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dnWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d2dmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREd3d3d2dmZmZmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3d2ZmZmZmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3ZmZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3ZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERHR3d3d3ZmZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHR3ZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER3ZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZmZZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3d2ZmZmZmZmZmZmZmZlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERER3d3d3d2dmZmZmZmZmZmZmZZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREdHd3d3d3d2dmZmZmZmZmZaWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3d3dmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3dnZmZmZmZaWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREdHd3d3d3d3d3d3d3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZlpmZlmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d3ZmZlmlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1plpZmZplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1pZmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbd1tZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbW1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3W1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d1m1mZmZmZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3WZm1mZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3Wbd1mmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d1tmZmWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d2dmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d3d3d3d2ZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3d3Z2ZmWZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3d3ZlpaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dnWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d2dmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREd3d3d2dmZmZmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3d2ZmZmZmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3ZmZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3ZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERHR3d3d3ZmZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHR3ZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER3ZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZmZZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3d2ZmZmZmZmZmZmZmZlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERER3d3d3d2dmZmZmZmZmZmZmZZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREdHd3d3d3d2dmZmZmZmZmZaWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3d3dmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3dnZmZmZmZaWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREdHd3d3d3d3d3d3d3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZlpmZlmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d3ZmZlmlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1plpZmZplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1pZmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbd1tZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbW1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3W1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d1m1mZmZmZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3WZm1mZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3Wbd1mmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d1tmZmWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d2dmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d3d3d3d2ZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3d3Z2ZmWZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3d3ZlpaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dnWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d2dmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREd3d3d2dmZmZmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3d2ZmZmZmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3ZmZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3ZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERHR3d3d3ZmZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHR3ZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER3ZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZmZZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3d2ZmZmZmZmZmZmZmZlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERER3d3d3d2dmZmZmZmZmZmZmZZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREdHd3d3d3d2dmZmZmZmZmZaWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3d3dmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3dnZmZmZmZaWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREdHd3d3d3d3d3d3d3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREd3d3d3d3d3d3d3d3Z2ZlpmZlmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d3ZmZlmlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1plpZmZplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER0d3d3d3d3d3d3d3d1pZmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbd1tZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dbW1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3dZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3W1mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d1m1mZmZmZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3WZm1mZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3Wbd1mmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d1tmZmWaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERHR3d3d3d3d3d3d3d3d3d2dmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERER3d3d3d3d3d3d3d3d3d2ZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERHR3d3d3d3d3d3d3Z2ZmWZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3d3ZlpaWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dnWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d3dmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER0d2dmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREd3d3d2dmZmZmZmZlmZpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3d2ZmZmZmZmZmWlplmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3Z2ZmZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERER0d3d3d3d3ZmZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREd3d3d3d3ZmZmZmZmZmZmZmZmZZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERHR3d3d3ZmZmZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHR3ZmZmZmZmZmZmWlpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERER3ZmZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYRERERERERERERERERERERERHd3ZmZmZmZmZmZZmlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYREREREREREREREREREREREdHd3Z2ZmZmZmZmZmZmZmWlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmY="}},"sprites.background.forest2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAAB3d3d3d3d3d3d3d2ZmZmZmZra7u7u7u7vbmZmZmdndmZmZ3d3d3ZmZmdnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZmu7u7u7u7m5nZ3d2ZmZnd3d3d3d2dmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmtru7u7u7u5mZmZmZmdndmZmZmZndnZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dndmZmZmZmZmZt1p2ZmZmZmZndmZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dnd2ZmZmZmZmbd3d3dnZmZmZnZ3ZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZm3W3d3d3d2dmZmZ3ZmZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmZm2d3d3d3d3d2dmZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmlpmZmdmdmd3dnZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZpmZmdmZmdnd3d3d3d2ZmZmZmZmZmZmZmZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZmaWaZmZmZ2ZmZnd3d3d3d3d3d3d3d3d3d3d3ZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmaZmZmZ3Z2ZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmbbZt3dmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZma71pmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2Z2a2m5mZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZ3ZmZmu2aZmZmZmZmZ2d2ZmZmZmZmZmd3d3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmZmu7ubmZmZmZmZ3Z2ZmZmZmZmZmZmZmd3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmtru7m5mZmZnd3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmmZm7u5mZ2d3d3ZmZmZmZmZmZmZmZmZmZmd3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2Z2ZmlpmZu7vd3d3dmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZ2ZmZt3d3bvb3ZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZnZmbWZt3d3bm725mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmbZ3Z2ZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmaZmZmZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2ZmmWaZmZm9u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3b27u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmaZmd2du5uZmZmZmZmZmZmZmZmZmZmZmbu7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZrtrZpbZ3Z2Zu7uZmZmZmZmZu7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd7a7u9ZmmZmZububmZmZmbm7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd2e7u7u7u5uZububmZmZu7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dndndmtru7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmZra7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmaWubu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmZmmZm5u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZpaZmZmZubu7u7u7u7u7u7u7u7uZmZmZmdm7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZmZmaZmZmZmZmZmZmZubu7u7uZmZmZmZmZmdndvbu7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZplpmZmZmZmZm5u7ubmZmZmZmZmZmZmdnd3d27u7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZm1t3dnZmZu7u7u5uZmZmZmZmZmZmZmdnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmZmZmmZmZ2d29u7u7m5mZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmmZmZmZm7u9ndmZmZmZmZmZmZmd3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZndmZmZmZmZmlpmZmbm7m5nZ3Z2ZmZmZmZmZ3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZmZmZpm7u7u7mZmZmd2ZmZmZmZnZ3d3dndnd3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZra7u7u7u7vbmZmZmdndmZmZ3d3d3ZmZmdnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZmu7u7u7u7m5nZ3d2ZmZnd3d3d3d2dmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmtru7u7u7u5mZmZmZmdndmZmZmZndnZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dndmZmZmZmZmZt1p2ZmZmZmZndmZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dnd2ZmZmZmZmbd3d3dnZmZmZnZ3ZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZm3W3d3d3d2dmZmZ3ZmZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmZm2d3d3d3d3d2dmZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmlpmZmdmdmd3dnZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZpmZmdmZmdnd3d3d3d2ZmZmZmZmZmZmZmZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZmaWaZmZmZ2ZmZnd3d3d3d3d3d3d3d3d3d3d3ZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmaZmZmZ3Z2ZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmabZt3dmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZma71pmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2Z2a2m5mZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZ3ZmZmu2aZmZmZmZmZ2d2ZmZmZmZmZmd3d3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmZmu7ubmZmZmZmZ3Z2ZmZmZmZmZmZmZmd3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmtru7m5mZmZnd3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmmZm7u5mZ2d3d3ZmZmZmZmZmZmZmZmZmZmd3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2Z2ZmlpmZu7vd3d3dmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZ2ZmZt3d3bvb3ZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZnZmaWZt3d3bm725mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmaZ3Z2ZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmaZmZmZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2ZmmWaZmZm9u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3b27u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmaZmd2du5uZmZmZmZmZmZmZmZmZmZmZmbu7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZrtrZpbZ3Z2Zu7uZmZmZmZmZu7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd7a7u9ZmmZmZububmZmZmbm7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd2e7u7u7u5uZububmZmZu7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dndndmtru7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmZra7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmaWubu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmZmmZm5u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZpaZmZmZubu7u7u7u7u7u7u7u7uZmZmZmdm7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZmZmaZmZmZmZmZmZmZubu7u7uZmZmZmZmZmdndvbu7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZplpmZmZmZmZm5u7ubmZmZmZmZmZmZmdnd3d27u7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZm1t3dnZmZu7u7u5uZmZmZmZmZmZmZmdnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmZmZmmZmZ2d29u7u7m5mZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmmZmZmZm7u9ndmZmZmZmZmZmZmd3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZndmZmZmZmZmlpmZmbm7m5nZ3Z2ZmZmZmZmZ3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZmZmZpm7u7u7mZmZmd2ZmZmZmZnZ3d3dndnd3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZra7u7u7u7vbmZmZmdndmZmZ3d3d3ZmZmdnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZmu7u7u7u7m5nZ3d2ZmZnd3d3d3d2dmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmtru7u7u7u5mZmZmZmdndmZmZmZndnZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dndmZmZmZmZmZt1p2ZmZmZmZndmZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dnd2ZmZmZmZmbd3d3dnZmZmZnZ3ZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZm3W3d3d3d2dmZmZ3ZmZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmZm2d3d3d3d3d2dmZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmlpmZmdmdmd3dnZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZpmZmdmZmdnd3d3d3d2ZmZmZmZmZmZmZmZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZmaWaZmZmZ2ZmZnd3d3d3d3d3d3d3d3d3d3d3ZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmaZmZmZ3Z2ZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmabZt3dmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZma71pmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2Z2a2m5mZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZ3ZmZmu2aZmZmZmZmZ2d2ZmZmZmZmZmd3d3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmZmu7ubmZmZmZmZ3Z2ZmZmZmZmZmZmZmd3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmtru7m5mZmZnd3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmmZm7u5mZ2d3d3ZmZmZmZmZmZmZmZmZmZmd3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2Z2ZmlpmZu7vd3d3dmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZ2ZmZt3d3bvb3ZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZnZmaWZt3d3bm725mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmaZ3Z2ZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmaZmZmZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2ZmmWaZmZm9u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3b27u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmaZmd2du5uZmZmZmZmZmZmZmZmZmZmZmbu7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZrtrZpbZ3Z2Zu7uZmZmZmZmZu7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd7a7u9ZmmZmZububmZmZmbm7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd2e7u7u7u5uZububmZmZu7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dndndmtru7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmZra7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmaWubu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmZmmZm5u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZpaZmZmZubu7u7u7u7u7u7u7u7uZmZmZmdm7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZmZmaZmZmZmZmZmZmZubu7u7uZmZmZmZmZmdndvbu7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZplpmZmZmZmZm5u7ubmZmZmZmZmZmZmdnd3d27u7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZm1t3dnZmZu7u7u5uZmZmZmZmZmZmZmdnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmZmZmmZmZ2d29u7u7m5mZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmmZmZmZm7u9ndmZmZmZmZmZmZmd3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZndmZmZmZmZmlpmZmbm7m5nZ3Z2ZmZmZmZmZ3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZmZmZpm7u7u7mZmZmd2ZmZmZmZnZ3d3dndnd3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZra7u7u7u7vbmZmZmdndmZmZ3d3d3ZmZmdnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZmu7u7u7u7m5nZ3d2ZmZnd3d3d3d2dmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmtru7u7u7u5mZmZmZmdndmZmZmZndnZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dndmZmZmZmZmZt1p2ZmZmZmZndmZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3dnd2ZmZmZmZmbd3d3dnZmZmZnZ3ZmZmZmZmZmZmZmZmZnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZm3W3d3d3d2dmZmZ3ZmZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmZm2d3d3d3d3d2dmZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmlpmZmdmdmd3dnZmZ3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZpmZmdmZmdnd3d3d3d2ZmZmZmZmZmZmZmZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZmaWaZmZmZ2ZmZnd3d3d3d3d3d3d3d3d3d3d3ZmZ3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3dmZmaZmZmZ3Z2ZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmabZt3dmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZma71pmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2Z2a2m5mZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZ3ZmZmu2aZmZmZmZmZ2d2ZmZmZmZmZmd3d3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmZmu7ubmZmZmZmZ3Z2ZmZmZmZmZmZmZmd3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmtru7m5mZmZnd3Z2ZmZmZmZmZmZmZmZnZ3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmmZm7u5mZ2d3d3ZmZmZmZmZmZmZmZmZmZmd3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2Z2ZmlpmZu7vd3d3dmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2dmZ2ZmZt3d3bvb3ZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZnZmaWZt3d3bm725mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmaZ3Z2ZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmaZmZmZmZm7u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmd2ZmmWaZmZm9u5mZmZmZmZmZmZmZmZmZmZmZmZnZ3b27u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3Z2ZmZmaZmd2du5uZmZmZmZmZmZmZmZmZmZmZmbu7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZrtrZpbZ3Z2Zu7uZmZmZmZmZu7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd7a7u9ZmmZmZububmZmZmbm7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnd2e7u7u7u5uZububmZmZu7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dndndmtru7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZmZmZra7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmaWubu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d2ZmZmZmmZm5u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZpaZmZmZubu7u7u7u7u7u7u7u7uZmZmZmdm7u7u7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dnZmZmZmaZmZmZmZmZmZmZubu7u7uZmZmZmZmZmdndvbu7u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZplpmZmZmZmZm5u7ubmZmZmZmZmZmZmdnd3d27u7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2d3ZmZmZmZm1t3dnZmZu7u7u5uZmZmZmZmZmZmZmdnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2Z2ZmZmZmZmmZmZ2d29u7u7m5mZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmmZmZmZm7u9ndmZmZmZmZmZmZmd3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3ZndmZmZmZmZmlpmZmbm7m5nZ3Z2ZmZmZmZmZ3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3Z3ZnZmZmZmZmZpm7u7u7mZmZmd2ZmZmZmZnZ3d3dndnd3d3d3d3dd3d3d3d3d3d3d3c="}},"sprites.background.fossils":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAACZmZmZmZmZmWlmdnd3t7u77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u//////////////+ZmZmZmZmZmWl2d2dmtrvrvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/7///////////+ZmZmZmZmZmXZ3ZmZmtr7rvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/+7/7///////////+ZmZmZmZmZaWZmZmZ3trvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZl2Z2Z2t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZlmd2dmtru+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v//////////////+ZmZmZmZmZaZmZZnd3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaZaZmWZ3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaWeZaWZmtrvr7u7u7u7u7v7/7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmXZmZmZ3t7vr7u7u7u7u7v697+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmWl3Znd3tuu77u677u7u/r/d7+7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u///u//////////+ZmZmZmZlplpl2dndmtru76+677u7u/t3d/+7u7u7u7u7u7u7u7u7u7u7u7u7+/+7u/v/u//////////+ZmZmZmZlpZ5Zpd2Zmtru7u+7u7u7u/tvd++/u7u7u7u7u7u7u7u7u/+///////f/u7v////////////+ZmZmZmZmZdmdmZ3Z3t7u7u+7u7u7u/v//3f/u7u7u7u7u7u7u7u7uv/+/v/vfvf3u7v////////////+ZmZmZmZmZaXdnZmZ3t7vrvuvu6+7u7u7+3/v/7+7u7u7u7u7u7v7/v/u7v//du/3/7/7//v////////+ZmZmZmZmZmWZ3d3d3t7vrvuvu7u7u7u7u/9297+7u7u7u7u7u7v7d//v7/////73d7/7///////////+ZmZmZmZmZmZlmZnd3tru7u+vu7u7u7u7u/t3d7+7u7u7u7u7u7v/b/fv7393/37v9//////////////+ZmZmZmZmZmZmZZnd3t7u7u+7u7u7u7u7u/t377+7u7u7u7u7u7t+7/f//u9v939u92/////////////+ZmZmZmZmZmZlmd3dmtru7u+677u7u7u7u/tvv7u7u7u7u7u7+/9+9/d/dvdv9/9+73f/u//////////+ZmZmZmZmZmWZ3Z2Z2t7u+6+677u7u7u7u/v/v7u7u7u7u7u7+3fv9//+73bv97v/f+//u//////////+ZmZmZmZmZaXdnZmZ3tru77u7u7u7u7u7u7u7u7u7u7u7u////3/v9/t29273/7u7///////////////+ZmZmZmZmZaWZmdmZntrvr7u7u7u7u7u7u7u7u7u7u7u7+393///3//7vdu/3u7u7+v93///////////+ZmZmZmZmZmWlmdmdmtrvr6+7u7u7u7u7u7u7u7u7u7u7/3d39/v/b3b3bvf3u7u7+3d3///////////+ZmZmZmZmZmWZmZndntrvu7u7u7u7u7u7u7u7u7u7u7v7f3d29////393b/f3u7u7//d/d//////////+ZmZmZmZmZmXZnZmZ3t7vu7u7u7u7u7u7u7u7u7u7u7v/d3d3d3e/u/937/f3u7u7//f/d/f////////+ZmZmZmZmZmWl3Z2Zmu7vu7u7u7u7u7u7u7u7u7u7u7t/d/93b3f3u/t///f3u7u7/3f/d3f////////+ZmZmZmZmZmZlmd3d3t7vu7u7u7u7u7u7u7u7u7u7u/t/9/9/b3f3v7t///f3u7u7/393d3f////////+ZmZmZmZmZmZlpZnd3t7vr7rvu7u7u7u7u7u7u7u7u/t3//9/b3d3v7t///f/u7u6//97d3f////////+ZmZmZmZmZmWl2d2dmtrvr7rvu7u7u7u7u7u7u7u7u/t3//9+73d3v7v///e7u7v/fu9/d/f////////+ZmZmZmZmZmXZ3ZmZ3t+u77u7u7u7u7u7u7u7u7u7u/t3//92/3d3/7u7+/+7u/9/dvf////////////+ZmZmZmZmZaXdmZnd3t7u76+7u7u7u7u7u7u7u7u7u/t393/3/3d39/v/v7u7u3939//////////////+ZmZmZmZmZaWZmdmdmtrvrvu7r7u7u7u7u7u7u7u7u/t3d3f3+3d39/t3v7u7u3/3/7////f////////+ZmZmZmZmZmZlpdmZmu7vrvu7u7u7u7u7u7u7u7u7u/t3/3f3+3d39/t3v7u7uv/v+7//f/f////////+ZmZmZmZmZZmZmZmZ3t7u7u+vu7u7u7u7u7u7u7u7u/v3/3f/+3939/tvv7u7uv/3v7v7f//////////+ZmZmZmZmZdndmZnZntru7u+u+6+7u7u7u7u7u7u7u/v3/3e/u/9397t//7u7u393/7v6/+/////////+ZmZmZmZmZaXZ3Z2Zmtru+u+u+6+7u7u7u7u7u7u7u/v3/3f/u/9397t/97u7u/9397/6//f////////+ZmZmZmZmZmWl2d3dmtru7u+vu7u7u7u7u7u7u7u7u/v3f3f3u393/7t/9/v/u/v/d7/7f/f////////+ZmZmZmWZmZmZmZnd3t7u7u+7u7u7u7u7u7u7u7u7u/93d/f/u393v7t/9//3u7v7/7//d//////////+ZmZmZmWZ3d3d3d3d3t7vru+7r7u7u7u7u7u7u7u7u393d3e/u393v7r+73/3u////7v+7//////////+ZmZmZmZlmZnZ3d3d3u7u76+7u7u7u7u7u7u7u7u7u39/d++/u393v/ru93f//3/3v/v/d//////////+ZmZmZmZmZmWlmdnd3t7u77u7u7u7u7u7u7u7u7u7u3//d/+/u/9vv/r29+//f3f/u/9/9//////////+ZmZmZmZmZmWl2d2dmtrvrvuvu7u7u7u7u7u7u7u7u3/3d3e/u393v/r3b3f/d/e/+/7v///////////+ZmZmZmZmZmXZ3ZmZmtr7rvuvu7u7u7u7u7u7u7u7u3929/+/u/9vv/t3/////////373///////////+ZmZmZmZmZaWZmZmZ3trvu7u7u7u7u7u7u7u7u7u7u393d3e/u3/3v/t/97v7////du93///////////+ZmZmZmZmZmZl2Z2Z2t7vu7u7u7u7u7u7u7u7u7u7u/t3//+/u///u7v//7v7d3bvbvf////////////+ZmZmZmZmZmZlmd2dmtru+7u7u7u7u7u7u7u7u7u7u/v/v7u7u7u7u7u7u7v7/2/3///////////////+ZmZmZmZmZaZmZZnd3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////////+ZmZmZmZmZaZaZmWZ3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaWeZaWZmtrvr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmXZmZmZ3t7vr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmWl3Znd3tuu77u677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u///u//////////+ZmZmZmZlplpl2dndmtru76+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v/u//////////+ZmZmZmZlpZ5Zpd2Zmtru7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v////////////+ZmZmZmZmZdmdmZ3Z3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v///9v9//////+ZmZmZmZmZaXdnZmZ3t7vrvuvu6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/7//t29//////+ZmZmZmZmZmWZ3d3d3t7vrvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/7//93d/f////+ZmZmZmZmZmZlmZnd3tru7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7//9vd/f////+ZmZmZmZmZmZmZZnd3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v///9vd+/////+ZmZmZmZmZmZlmd3dmtru7u+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v/u/93///////+ZmZmZmZmZmWZ3Z2Z2t7u+6+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v/v/uv93///////+ZmZmZmZmZaXdnZmZ3tru77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u////373///////+ZmZmZmZmZaWZmdmZntrvr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+////2/3///////+ZmZmZmZmZmWlmdmdmtrvr6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+/v//3fv///////+ZmZmZmZmZmWZmZndntrvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7//7+93f////////+ZmZmZmZmZmXZnZmZ3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7//9/dvf////////+ZmZmZmZmZmWl3Z2Zmu7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7//7/d3f////////+ZmZmZmZmZmZlmd3d3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7////f3f////////+ZmZmZmZmZmZlpZnd3t7vr7rvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+/+6/vf////////+ZmZmZmZmZmWl2d2dmtrvr7rvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+/+7///////////+ZmZmZmZmZmXZ3ZmZ3t+u77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u//////////////+ZmZmZmZmZaXdmZnd3t7u76+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v////////////+ZmZmZmZmZaWZmdmdmtrvrvu7r7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7//+//////////+ZmZmZmZmZmZlpdmZmu7vrvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/////////////+ZmZmZmZmZZmZmZmZ3t7u7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7///////////+ZmZmZmZmZdndmZnZntru7u+u+6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7v/v////////+ZmZmZmZmZaXZ3Z2Zmtru+u+u+6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7v7v/v////////+ZmZmZmZmZmWl2d3dmtru7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7///////////+ZmZmZmWZmZmZmZnd3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v////////////+ZmZmZmWZ3d3d3d3d3t7vru+7r7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7v/+//////////+ZmZmZmZlmZnZ3d3d3u7u76+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v////////////+ZmZmZmZmZmWlmdnd3t7u77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u//////////////+ZmZmZmZmZmWl2d2dmtrvrvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/7///////////+ZmZmZmZmZmXZ3ZmZmtr7rvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/+7/7///////////+ZmZmZmZmZaWZmZmZ3trvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZl2Z2Z2t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZlmd2dmtru+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v//////////////+ZmZmZmZmZaZmZZnd3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaZaZmWZ3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaWeZaWZmtrvr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmXZmZmZ3t7vr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmWl3Znd3tuu77u677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u///u//////////+ZmZmZmZlplpl2dndmtru76+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v/u//////////+ZmZmZmZlpZ5Zpd2Zmtru7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u///u7v////////////+ZmZmZmZmZdmdmZ3Z3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uv/3u7v////////////+ZmZmZmZmZaXdnZmZ3t7vrvuvu6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u373/7/7//v////////+ZmZmZmZmZmWZ3d3d3t7vrvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+39397/7///////////+ZmZmZmZmZmZlmZnd3tru7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7/29377v7///////////+ZmZmZmZmZmZmZZnd3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7f/f//7v////////////+ZmZmZmZmZmZlmd3dmtru7u+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v/d/+7u7v/u//////////+ZmZmZmZmZmWZ3Z2Z2t7u+6+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/t/97+7v/v/u//////////+ZmZmZmZmZaXdnZmZ3tru77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7//9v/7u7u//////////////+ZmZmZmZmZaWZmdmZntrvr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u6/3f3v7u7+//////////////+ZmZmZmZmZmWlmdmdmtrvr6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7f3f3u7u7+/v////////////+ZmZmZmZmZmWZmZndntrvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7/2/3u7u7///////////////+ZmZmZmZmZmXZnZmZ3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u3/vu7u7///////////////+ZmZmZmZmZmWl3Z2Zmu7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u///u7u7///////////////+ZmZmZmZmZmZlmd3d3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZlpZnd3t7vr7rvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+/+7///////////+ZmZmZmZmZmWl2d2dmtrvr7rvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+/+7///////////+ZmZmZmZmZmXZ3ZmZ3t+u77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u//////////////+ZmZmZmZmZaXdmZnd3t7u76+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v////////////+ZmZmZmZmZaWZmdmdmtrvrvu7r7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7//+//////////+ZmZmZmZmZmZlpdmZmu7vrvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/////////////+ZmZmZmZmZZmZmZmZ3t7u7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7///////////+ZmZmZmZmZdndmZnZntru7u+u+6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7v/v////////+ZmZmZmZmZaXZ3Z2Zmtru+u+u+6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7v7v/v////////+ZmZmZmZmZmWl2d3dmtru7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7///////////+ZmZmZmWZmZmZmZnd3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v////////////+ZmZmZmWZ3d3d3d3d3t7vru+7r7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7v/+//////////+ZmZmZmZlmZnZ3d3d3u7u76+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v////////////+ZmZmZmZmZmWlmdnd3t7u77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u//////////////+ZmZmZmZmZmWl2d2dmtrvrvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/7///////////+ZmZmZmZmZmXZ3ZmZmtr7rvuvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/+7/7///////////+ZmZmZmZmZaWZmZmZ3trvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZl2Z2Z2t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZmZlmd2dmtru+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v//////////////+ZmZmZmZmZaZmZZnd3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaZaZmWZ3t7vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7///////////////+ZmZmZmZmZaWeZaWZmtrvr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmXZmZmZ3t7vr7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+//////////////+ZmZmZmZmZmWl3Znd3tuu77u677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u///u//////////+ZmZmZmZlplpl2dndmtru76+677u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u///v//////////+ZmZmZmZlpZ5Zpd2Zmtru7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uv73///////////+ZmZmZmZmZdmdmZ3Z3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7/393///////////+ZmZmZmZmZaXdnZmZ3t7vrvuvu6+7u7u7//+7u7u7u7u7u7u7u7u7u7u7u7u7u7u6/3d3//v////////+ZmZmZmZmZmWZ3d3d3t7vrvuvu7u7u7u7f++7u7u7u7u7u7u7u7u7u7u7u7u7u7u7f3b3///////////+ZmZmZmZmZmZlmZnd3tru7u+vu7u7u7v/b/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u6/vd3///////////+ZmZmZmZmZmZmZZnd3t7u7u+7u7u7u7t/d/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7//937//////////+ZmZmZmZmZmZlmd3dmtru7u+677u7u7r/d/e/u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/tv9//////////+ZmZmZmZmZmWZ3Z2Z2t7u+6+677u7u7v//2//u7u7u7u7u7u7u7u7u7u7u7u7u7u7v/t+9//////////+ZmZmZmZmZaXdnZmZ3tru77u7u7u7u7u7+3/3v7u7u7u7u7u7u7u7u7u7u7u7u7u7u/7/d//////////+ZmZmZmZmZaWZmdmZntrvr7u7u7u7u7u7u/93/7u7u7u7u7u7u7u7u7u7u7u7u7u7+///d//////////+ZmZmZmZmZmWlmdmdmtrvr6+7u7u7u7u7u/t/9///u7u7u7u7u7u7u7u7u7u7u7u7+/v/b3fv///////+ZmZmZmZmZmWZmZndntrvu7u7u7u7u7u7u7v/b3fvu7u7u7u7u7u7u7u7u7u7u7u7////b3f3///////+ZmZmZmZmZmXZnZmZ3t7vu7u7u7u7u7u7u7v7f3f3u7u7u7u7u7u7u7u7u7u7u7u7////d3f3///////+ZmZmZmZmZmWl3Z2Zmu7vu7u7u7u7u7u7u7u7fvf/u7u7u7u7u7u7u7u7u7u7u7u7////dvf////////+ZmZmZmZmZmZlmd3d3t7vu7u7u7u7u7u7u7u6//e7u7u7u7u7u7u7u7u7u7u7u7u7////b/f////////+ZmZmZmZmZmZlpZnd3t7vr7rvu7u7u7u7u7u7//+7u7u7u7u7u7u7u7u7u7u7u7u7+//7///////////+ZmZmZmZmZmWl2d2dmtrvr7rvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+/+7///////////+ZmZmZmZmZmXZ3ZmZ3t+u77u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7u//////////////+ZmZmZmZmZaXdmZnd3t7u76+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v////////////+ZmZmZmZmZaWZmdmdmtrvrvu7r7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7//+//////////+ZmZmZmZmZmZlpdmZmu7vrvu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7/////////////+ZmZmZmZmZZmZmZmZ3t7u7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7///////////+ZmZmZmZmZdndmZnZntru7u+u+6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7v/v////////+ZmZmZmZmZaXZ3Z2Zmtru+u+u+6+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7v7v/v////////+ZmZmZmZmZmWl2d3dmtru7u+vu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7///////////+ZmZmZmWZmZmZmZnd3t7u7u+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v////////////+ZmZmZmWZ3d3d3d3d3t7vru+7r7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+7v/+//////////+ZmZmZmZlmZnZ3d3d3t7u76+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v////////////8="}},"sprites.background.lanterns":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAACIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIVYWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIaIiIiIiIiIiIiIiIiIiIiGiIiIWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIaIaIiIiIiIiIiIiIiIiIiGhmiIiIiIiIiIiIiFiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiIiIiIZoiIiIiIiIiIiIiIiIiIiIiGiIiIiIiIiIiIiFhViIiIiIiIiIiIiIiIiIiIiIi4i4iIiIiIiIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaFWFiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhViIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFiIiIWIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiFWIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVYiIiIiIWFWIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGhVhYiIiIiIVVWIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIhohoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVYiIiIiIWFWIiIiIiIiIiIiIiIiIuIuIiIiIiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiFWIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiGaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIWIiIiIiIiIiIiIiIiIi4iIiIiIiIiIaIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIhohoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIWIiIiIiIiIiIiIWIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIVYWIiIiIiIiIiFWIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIWIiIiIiIiIiIiFVVhYiIiIiIiIiIiIiIiIiLiIiIiIiIiIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIVVVViIiIiIiIiIiIiIiIiLiIiIiIiIhmZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhVVVWFiIiIiIiIiIiIiIiIiLuIiIiIiGaGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIVVVViIiIiIiIiIiIiIiIiIuIiIiIZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFVVhYiIiIiIiIiIiIiIuLWIiGhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFWIiIiIiIiIiIiIiIiIi1W1W2WIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIWIiIiIiIiIiIiIiIi4i1VVVYWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4aFVVVYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiIiIiIiIiIiIiIhmVVVVtYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhVhYiIiIiIiFiIiIiIiIiIaGaLW1VVVYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFVVVYWIiIiIiIiIiIiIiGZmhruIiFtVVYWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhVhYiIiIiIiIiIiIhoZoiIiIuIiFi1W4WIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhVVYiIiIiIiIiIZmaGiIiIuIiIiFiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFiIiIiIiIiIiIiIiIiIiIi4iIiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi7iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIi4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYhYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVVWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhVVYWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIWFVVVYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhVVYWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVVWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYhYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiLiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4i4iIZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu4iIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIuIiIhoZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiGaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIhoZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIaGaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIuIiIiIiIhmhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLuIiIiIiIhoZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIaIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiGaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4i4iIiIiIiIhmhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIhoZoiIW4uIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIZoaIWLWLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIaGaIWLVVVVVVVVVVtYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiGaIW7WIiIiIiIi4VYWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiGhWu4W1iIiIiIiIW7WIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIhWu7VVVVVVVVVVVVWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIiIhVu4W1iIiIiIiIWFWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLiIiIiIiIiIi1VYWIiIiIiIiIWLW1W4uIiIiIiIiIiIiIiIiIiIiIiIiIiIi7u7u7u7u7u7tbu1u7tVVVVVVVVVVVVbVbVYWIiIiIiIiIWLVVW1VVVVW7u4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi7iIiIiIiIiIi1VYWIiIiIiIiIWLW1W4uIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIiIhVW2W1iIiIiIiIWFWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4i4iIiIiIiIhYu7VVVVVVVVVVVVWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIiIiIiIhYu2W1iIiIiIiIW7WIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiIiIi4tYiIiIiIi4iIiIiIiIiIu4VmiIiIiIi4VYWIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVYhmiIiIiIiIiIiIVbuIiIiIu4iIiIiIiIiIW7VVVVVVVVVVtYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIZoiIiIiIiIiIVVtVVVVVVVVVi4iIiIiIWLVrhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGhmiIiIiIi4VYuIiIiIuIhbVYiIiIiIW4uIZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZoaIiIi1W1iLiIiIuIu4VYuIiIiIiIiIZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGhmhoi1W1tVVVVVVVVVVYWIiIiIiIiIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZla1W1iLiIiIiIuIVYWIiIiIiIiIaIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhbVYaIiIiIiIuIVVu7tYiIiIiIiIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIhVVVVVVVVVVbtVVWZmhoiIiLuIVVu1VVVVVbW7i2aIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYhYiIiIiIiIiIiIiIiFhbVYiIZmaGiLiIVVu7tYiIiIiIiGaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVVWIiIiIiIiIiIiIiFi1VViLiGhmZraIVYWIiIiIiIiIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhVVYWIiIiIiIiIiIiIiIi1W1tVVVVVVVVVVYWIiIiIiIiIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIWFVVVYiIiIiIiIiIiIiIiIi1W1iLiIiIiLi2VYuIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFhVVYWIiIiIiIiIiIiIiIi4W4iIiIiIiIhbVWZmiIiIiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVVWIiIiIiIiIiIiIiIi4VVtVVVVVVVVVi4hmZoiIiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYhYiIiIiIiIiIiIiIiIiIVbuIiIiIiIiLiIhba2aGiIiIiIhmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiIiIiIiIiIi4tYiIiIiIiIiLiIhYtWtmhoiIiIhoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi7iIhYtVVVVVVVVVW1hoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiFiIiIiIiIiIiIiIiIiIiIiIiIiIi4iIhbtYiIiGaIiLhVhYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhViIiIiIiIiIiIiIiIiIiIiIiIiIi4iFi7hbWIiGhmiIhbtYiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIiIhVWFWIiIiIiIiIiIiIiIiIiIiIiIi4iFi7tVVVVVVVVVVVVYiIiIiIiIiIiIiIiIiIiIhVhYiIiIiIiFhVVYWIiIiIiIiIiIiIiIiIiIiIiIi4iFW7hbWIiIiIaIZYVYiIiIiIiIiIiIiIiIiIiIhYiIiIiIiIWFVVVYiIiIiIiIiIiIiIiIiIiIiIiIiIiLVVhYiIiIiIiGZWtbVbi4iIiIiIiIiIiIiIiIiIiIiIiIhYVVVVhYi7u7u7u1u7W7u1VVVVVVVVVVVVtVtVhYiIiIiIiIhWtVVbVVVVVbu7iIiIiIiIiIiIiIiIiIiIWFVVVYiIiIiIiIiIiIiIiIiIiIiIiIiIi7VVhYiIiIiIiIhYtbVbi4iIiIiIiIiIiIhoiIiIiIiIiIiIiFhVVYWIiIiIiIiIiIiIiIiIiIiIiIiIi1VbhbWIiIiIiIhYVYiIiIiIiIiIiIiIiIhmZoaIiIiIiIiIiIhVWFWIiIiIiIiIiIiIiIiIiIiIiIiIi1i7tVVVVVVVVVVVVWaIiIiIiIiIiIiIiGZmZoiIiIWIiIiIiIhViIiIiIiIiIiIiIiIiIiIiIiIiIiIi1i7hbWIiIiIiIhbtWiGiIiIiIiIiIiIiGhmZoiIiFWIiIiIiIiFiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4i7hYiIiIiIiLhVhYiGiIiIiIiIiIiIiIhmZoaIiFVVhYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu4hbtVVVVVVVVVW1iIhoiIiIiIiIiIiIiIiGiIiIVVVViIiIiIiIiFiIiIiIiIiIiIiIiIiIiIiIiIiIu4hYtYuIiIiIiIiIiIiIhoiIiIiIiIiIiIiIiIhVVVWFiIiIiIiIiFWIiIiIiIiIiIiIiIiIiIiIiIiIuIhbi4iIiIiIiIiIiIiIZoiIiIiIiIiIiIiIiIiIVVVViIiIiIiIiFiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIaIaIiIiIiIiIiIiIiIiIiFVVhYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIaIiIiIiIiIiIiIiIiIiFWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIWIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiGiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIiIiIiIiIiIiIiIiIiIiIiGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIg="}},"sprites.background.lilypads":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAACZmZmZmZmZmXlmZmZ3d3d3d3d3d2bW3d19l5mZmZmZmZmZmZmZmZmZeWZmZnd3d3d3d3d3Ztbd3X2XmZmZmZmZmZmZmZlmZmZ3d3d3d3d3d2dm3d19l5mZmZmZmZmZmZmZmZmZmWZmZnd3d3d3d3d3Z2bd3X2XmZmZmZmZmZmZmZlpZnZ3d3d3d3d3d2dm3d19l5mZmZmZmZmZmZmZmZmZmWlmdnd3d3d3d3d3Z2bd3X2XmZmZmZmZmZmZmZmZZ3Z3d3d3d3d3d2dm3d19l5mZmZmZmZmZmZmZmZmZmZlndnd3d3d3d3d3Z2bd3X2XmZmZmZmZmZmZmZmZmXl3d3d3d3d3d2dm3d3dl5mZmZmZmZmZmZmZmZmZmZmZeXd3d3d3d3d3Z2bd3d2XmZmZmZmZmZmZmdndmXd3d3d3d3d3d2dm1919mZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2bX3X2ZmZmZmZmZmZmZmdkR3Xd3d3d3d3d3d2dmd92XmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2Z33ZeZmZmZmZmZmZmZmdkR0X0Rd3d9d3d3d2dmd3eZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2Z3d5mZmZmZmZmZmZmZmZkdEX0Rd9d9d3d3d2dmd5mZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2Z3mZmZmZmZmZmZ2d3d3ZkdEd0Rcd3dd3d3d2dmmZmZmZmZmZmZmZmZmZmZmZmZmZmZdnd3d3d3d3d3Z2aZmZmZmZmZmZmZ2RER0d3dEdERcd3dd3d3d2dmmZmZmZmZmZmZmZmZmZmZmZl5l5mZZmZ3d3d3d3d3Z2aZmZmZmZmZmZmZ2REREdHdHdERcd3dd3d3d2dmmZmZmZmZmZmZmZmZmZmZmdndfZeZmXlmd3d3d3d3Z2aZmZmZmZmZmZmZ2R0RERHdHdERcd13fXd3d2dmmZmZmZmZtnuZmZmZmZmZmd3d3XeZmZl5ZnZ3d3d3Z2aZmZmZmZmZmZmZmd0RERHR3REdcX0X0Xd3d2dmmZmZmZlmd7Z7mZmZmZmZ2d3d3X2XmZmZaXZ3d3d3Z2aZmZmZmWaZmZmZ2d0dERER3REd0XcR0Xd3d2dmmZmZmWlmZne7m5mZmZmZ3d3d3d13mZmZaXd3d3d3Z2aZmZmZaWaZmZmZ2d3dHRER3R0d3RcR0Xd3d2dmmZmZmWZmZna3u5mZmZmZ3d3d3d13mZmZaXd3d3d3Z2aZmZmZZmabmZnd3d3d3RHd3R0dfRERfXd3d2dmmZmZaWZmZmZ3u5uZmZnZ3d3d3d19l5mZdnd3d3d3Z2aZmZlpZmZ7mZkdERHd3R0d3d3d3RERfXd3d2Z2mZmZZmZmZmZ2tnuZmZnZ3d3d3d19l5mZdnd3d3d3ZnaZmZlmZma7mZkdERER0d0dEd3dHRHRd3d3d2aWmZmZZmZmZmZ2Z7uZmZnd3d3d3d19l5lpd3d3d3d3ZpaZmZlmZma7l5ndEREREdHdEdHdHRF9d3d3d2aWmZmZa2ZmZmZmZ7uXmZnd3d3d3d19l5lpd3d3d3d3ZpaZmZlrZma7m5nZ3R0REdHdERHd3d3dd3d3Z2aXmZmZZ2ZmZmZmZrubmZnd3d3d3d19l5l2d3d3d3dnZpeZmZlnZma7e5nZHdEdEV1VHREd3RHRfXd3Z2aZmZmZaWZmZmZmZrt7mdnd3d3d3d19l5l2d3d3d3dnZpmZmZlpZma2u5ndEREREd1VHdER3RER0Xd3ZnaZmZmZeWZmZmZmZra7mdnd3d3d3d19l2l3d3d3d3dmdpmZmZl5Zma2u5kdERER0V1V1dER0REREX13ZpaZmZmZmWtmZmZmZra7mdnd3d3d3d19l2l3d3d3191mlpmZmZmZa2a2u5nd3R0R0VVVVd0R0R0REdFnZpeZmZmZmWlmZmZmZra7mdnd3d3d3d19l3Z3d3d31xHdd3eZmZmZaWa2u5kdEREREV1V1dER0d0REdFmZpmZmbl7mblmZmZmZra7mdnd3d3d3d19l3Z3d3d31xHRfRGXuX2ZuWa2u5ndEREREd1dFdER3d3dEdFmlpmZmWm7l5lmZmZmZra7mdnd3d3d3d19l9d3d3d3Zx0RfRGX2b2XmWa2u5nZHRER0d1VEREd3d3d3W1mmZmZmWlmu5dnZmZmZra7mdnd3d3X3d19l9nd3d3dZh0R3RFx3d27l2e2u5nZ3RER3d3dERHd3XHXZ2aWmZmZmWlmtrtnZmZmZra7mdnd3d3X3d19l3nXERHR3d0R0RFx3d22u2e2u5nZ3d0R0d3dEdHdHRFnZmaZmZmZmWlmZrZrZmZmZra7mdnd3d133d19l5nXERER0d0d0RFx3d1mtmu7u5nZ3R0R0d0dEd3dHRFxZpeZmZmZmWlmZmZmZmZmZru7mdnd3d131919l5nZHREREd0d0RFx3XdtZmZ3ZnbZ3RER3d0d0R3dHRHRmZmZmZmZmWlmZmZmZmZmd3dmdtnd3d131919l5mZ3REREdHdER1xfRfRZmZ3Z2bWHRHd3RHR3R0d3RERnZmZmZmZmWlmZmZmZmZ2d3dnZtbd3d19d919l5nZ3R0RERHdER3RdxHRZmZ3d2dm3d3dHRER3REd3RERnZmZmZmZmWlmZmZmZmZ3d3d3Z2bd3d19d913mZnZ3d0dERHdHR3dFxHRZmZ3d3dm1t0dERHR3REd0RcRnZmZmZmZmWlmZmZmZnZ3d3d3d2bW3d19d9d3md3d3d3dEd3dHR19ERFtZmZ3d3dn1t0RERHdHdEd0XcRnZmZmZmZmXlmZmZmZnd3d3d3d2fW3d19d9d3mR0REd3dHR3d3d3dERFtZmZ3d3dn1h0REdHdHdER0X0XnZmZmZmZmZlmZmZmZnd3d3d3d2dm3d3dd3mXmR0RERHR3R0R3d0dEdFmZmZ3d3d31hEREd3dEdER0d3XmZmZmZmZmZlmZmZmdnd3d3d3d3dm3d3dd5mZmd0RERER0d0R0d0dEW1mZmZ3d3d31hER3d3dEd0Rcd2XmZmZmZmZmZlnZmZmdnd3d3d3d3dm1t3dd5mZmdndHRER0d0REd3d3d1mZmZ3d3d31t3d3XcdEd0Rd92XmZmZmZmZmZlpZmZmd3d3d3d3d3dm1t3dd5eZmdkd0R0RXVUdER3dEdFtZmZ3d3d3Ztbd3d0REd0Rl9eXmZmZmZmZmZl5ZmZmd3d3d3d3d3dm1t3dfZeZmd0RERER3VUd0RHdERHRZmZ3d3d3Z2bd3d0R0d1xl3eXmZmZmZmZmZmZZmZmd3d3d3d3d3dnZt3dfZeZmR0RERHRXVXV0RHRERERbWZ3d3d3Z2bd3d0R3Zl9mXmZmZmZmZmZmZmZaWZ2d3d3d3d3d3dnZt3dfZeZmd3dHRHRVVVV3RHRHRER0XZ3d3d3Z2bd3d3RnZmZmZmZmZmZmZmZmZmZmWd2d3d3d3d3d3dnZt3dfZeZmR0RERERXVXV0RHR3RER0XZ3d3d3Z2bd3d3dmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3dnZt3d3ZeZmd0RERER3V0V0RHd3d0R0Xl3d3d3Z2bX3X2ZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3dnZtfdfZmZmdkdERHR3VURER3d3d3dnXd3d3d3Z2Z33ZeZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3dnZnfdl5mZmdndERHd3d0REd3dcZeZmXd3d3d3Z2Z3d5mZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3dnZnd3mZmZmZnZ3RHR3d0R0d0dEZeZmXd3d3d3Z2Z3mZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3dnZneZmZmZmZnZHRHR3R0R3d0dEXGZmXd3d3d3Z2aZmZmZmZmZmZmZmZmZmZmZmZmZmZl2d3d3d3d3d3dnZpmZmZmZmZndERHd3R3RHd0dEdGZmXZ3d3d3Z2aZmZmZmZmZmZmZmZmZmZmZmXmXmZlmZnd3d3d3d3dnZpmZmZmZmZkdEd3dEdHdHR3dERGdmWZ3d3d3Z2aZmZmZmZmZmZmZmZmZmZmZ2d19l5mZeWZ3d3d3d3dnZpmZmZmZmZnd3d0dERHdER3dERGdmZl3d3d3Z2aZmZmZmZm2e5mZmZmZmZmZ3d3dd5mZmXlmdnd3d3dnZpmZmZmZmbZ72R0REdHdER3RFxF9mZl3d3d3Z2aZmZmZmWZ3tnuZmZmZmZnZ3d3dfZeZmZlpdnd3d3dnZpmZmZmZZne23REREd0d0R3RdxF9l5l3d3d3Z2aZmZmZaWZmd7ubmZmZmZnd3d3d3XeZmZlpd3d3d3dnZpmZmZlpZmbXHRER0d0d0RHRfRfdd5l3d3d3Z2aZmZmZZmZmdre7mZmZmZnd3d3d3XeZmZlpd3d3d3dnZpmZmZlmZmbWERER3d0R0RHR3dfdd5l3d3d3Z2aZmZlpZmZmZne7m5mZmdnd3d3d3X2XmZl2d3d3d3dnZpmZmWlmZmbWERHd3d0R3RFx3dfdfZd3d3d3ZnaZmZlmZmZmZna2e5mZmdnd3d3d3X2XmZl2d3d3d3dmdpmZmWZmZmbW3d3dmR0R3RF33dfdfZd3d3d3ZpaZmZlmZmZmZnZnu5mZmd3d3d3d3X2XmWl3d3d3d3dmlpmZmWZmZmZmdme72RER3RHX19fdfZd3d3d3ZpaZmZlrZmZmZmZnu5eZmd3d3d3d3X2XmWl3d3d3d3dmlpmZmWtmZmZmZme71xHR3XHXd9fdfZd3d3dnZpeZmZlnZmZmZmZmu5uZmd3d3d3d3X2XmXZ3d3d3d2dml5mZmWdmZmZmZma72xHd3X3dfd3dfZd3d3dnZpmZmZlpZmZmZmZmu3uZ2d3d3d3d3X2XmXZ3d3d3d2dmmZmZmWlmZmZmZma729Hd3d3d3d3dfZd3d3dmdpmZmZl5ZmZmZmZmtruZ2d3d3d3d3X2XaXd3d3d3d2Z2mZmZmXlmZmZmZma2u93Z3d3d3d3dfZd3d3dmlpmZmZmZa2ZmZmZmtruZ2d3d3d3d3X2XaXd3d3d3d2aWmZmZmZlrZmZmZma2u5nZ3d3d3d3dfZd3d2dml5mZmZmZaWZmZmZmtruZ2d3d3d3d3X2Xdnd3d3d3Z2aXmZmZmZlpZmZmZma2u5nZ3d3d3d3dfZd3d2ZmmZmZuXuZuWZmZmZmtruZ2d3d3d3d3X2Xdnd3d3d3ZmaZmZm5e5m5ZmZmZma2u5nZ3d3d3d3dfZd3Z2aWmZmZabuXmWZmZmZmtruZ2d3d3d3d3X2X13d3d3dnZpaZmZlpu5eZZmZmZma2u5nZ3d3d3d3dfZd9ZmaZmZmZaWa7l2dmZmZmtruZ2d3d3dfd3X2X2d13131mZpmZmZlpZruXZ2ZmZma2u5nZ3d3d193dfZdnZpaZmZmZaWa2u2dmZmZmtruZ2d3d3dfd3X2Xedfd3WdmlpmZmZlpZra7Z2ZmZma2u5nZ3d3d193dfZdmZpmZmZmZaWZmtmtmZmZmtruZ2d3d3Xfd3X2XmXd3Z2ZmmZmZmZlpZma2a2ZmZma2u5nZ3d3dd93dfZdml5mZmZmZaWZmZmZmZmZmu7uZ2d3d3XfX3X2XmZlmZmaXmZmZmZlpZmZmZmZmZma7u5nZ3d3dd9fdfZeZmZmZmZmZaWZmZmZmZmZ3d2Z22d3d3XfX3X2XmZmZmZmZmZmZmZlpZmZmZmZmZnd3ZnbZ3d3dd9fdfZeZmZmZmZmZaWZmZmZmZnZ3d2dm1t3d3X133X2XmZmZmZmZmZmZmZlpZmZmZmZmdnd3Z2bW3d3dfXfdfZeZmZmZmZmZaWZmZmZmZnd3d3dnZt3d3X133XeZmZmZmZmZmZmZmZlpZmZmZmZmd3d3d2dm3d3dfXfdd5mZmZmZmZmZaWZmZmZmdnd3d3d3Ztbd3X1313eZmZmZmZmZmZmZmZlpZmZmZmZ2d3d3d3dm1t3dfXfXd5mZmZmZmZmZeWZmZmZmd3d3d3d3Z9bd3X1313eZmZmZmZmZmZmZmZl5ZmZmZmZ3d3d3d3dn1t3dfXfXd5mZmZmZmZmZmWZmZmZmd3d3d3d3Z2bd3d13eZeZmZmZmZmZmZmZmZmZZmZmZmZ3d3d3d3dnZt3d3Xd5l5mZmZmZmZmZmWZmZmZ2d3d3d3d3d2bd3d13mZmZmZmZmZmZmZmZmZmZZmZmZnZ3d3d3d3d3Zt3d3XeZmZmZmZmZmZmZmWdmZmZ2d3d3d3d3d2bW3d13mZmZmZmZmZmZmZmZmZmZZ2ZmZnZ3d3d3d3d3Ztbd3XeZmZmZmZmZmZmZmWlmZmZ3d3d3d3d3d2bW3d13l5mZmZmZmZmZmZmZmZmZaWZmZnd3d3d3d3d3Ztbd3XeXmZmZmZmZmZmZmXlmZmZ3d3d3d3d3d2bW3d19l5mZmZmZmZmZmZmZmZmZeWZmZnd3d3d3d3d3Ztbd3X2XmZmZmZmZmZmZmZlmZmZ3d3d3d3d3d2dm3d19l5mZmZmZmZmZmZmZmZmZmWZmZnd3d3d3d3d3Z2bd3X2XmZmZmZmZmZmZmZlpZnZ3d3d3d3d3d2dm3d19l5mZmZmZmZmZmZmZmZmZmWlmdnd3d3d3d3d3Z2bd3X2XmZmZmZmZmZmZmZmZZ3Z3d3d3d3d3d2dm3d19l5mZmZmZmZmZmZmZmZmZmZlndnd3d3d3d3d3Z2bd3X2XmZmZmZmZmZmZmZmZmXl3d3d3d3d3d2dm3d3dl5mZmZmZmZmZmZmZmZmZmZmZeXd3d3d3d3d3Z2bd3d2XmZmZmZmZmZmZmZmZmXd3d3d3d3d3d2dm1919mZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2bX3X2ZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d2dmd92XmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2Z33ZeZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d2dmd3eZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2Z3d5mZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d2dmd5mZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3Z2Z3mZmZmZmZmZmZmZmZmZmZmXZ3d3d3d3d3d2dmmZmZmZmZmZmZmZmZmZmZmZmZmZmZdnd3d3d3d3d3Z2aZmZmZmZmZmZmZmZmZeZeZmWZmd3d3d3d3d2dmmZmZmZmZmZmZmZmZmZmZmZl5l5mZZmZ3d3d3d3d3Z2aZmZmZmZmZmZmZmZnZ3X2XmZl5Znd3d3d3d2dmmZmZmZmZmZmZmZmZmZmZmdndfZeZmXlmd3d3d3d3Z2aZmZmZmZmZmZmZmZnd3d13mZmZeWZ2d3d3d2dmmZmZmZmZtnuZmZmZmZmZmd3d3XeZmZl5ZnZ3d3d3Z2aZmZmZmZmZmZmZmdnd3d19l5mZmWl2d3d3d2dmmZmZmZlmd7Z7mZmZmZmZ2d3d3X2XmZmZaXZ3d3d3Z2aZmZmZmWaZmZmZmd3d3d3dd5mZmWl3d3d3d2dmmZmZmWlmZne7m5mZmZmZ3d3d3d13mZmZaXd3d3d3Z2aZmZmZaWaZmZmZmd3d3d3dd5mZmWl3d3d3d2dmmZmZmWZmZna3u5mZmZmZ3d3d3d13mZmZaXd3d3d3Z2aZmZmZZmabmZmZ2d3d3d3dfZeZmXZ3d3d3d2dmmZmZaWZmZmZ3u5uZmZnZ3d3d3d19l5mZdnd3d3d3Z2aZmZlpZmZ7mZmZ2d3d3d3dfZeZmXZ3d3d3d2Z2mZmZZmZmZmZ2tnuZmZnZ3d3d3d19l5mZdnd3d3d3ZnaZmZlmZma7mZmZ3d3d3d3dfZeZaXd3d3d3d2aWmZmZZmZmZmZ2Z7uZmZnd3d3d3d19l5lpd3d3d3d3ZpaZmZlmZma7l5mZ3d3d3d3dfZeZaXd3d3d3d2aWmZmZa2ZmZmZmZ7uXmZnd3d3d3d19l5lpd3d3d3d3ZpaZmZlrZma7m5mZ3d3d3d3dfZeZdnd3d3d3Z2aXmZmZZ2ZmZmZmZrubmZnd3d3d3d19l5l2d3d3d3dnZpeZmZlnZma7e5nZ3d3d3d3dfZeZdnd3d3d3Z2aZmZmZaWZmZmZmZrt7mdnd3d3d3d19l5l2d3d3d3dnZpmZmZlpZma2u5nZ3d3d3d3dfZdpd3d3d3d3ZnaZmZmZeWZmZmZmZra7mdnd3d3d3d19l2l3d3d3d3dmdpmZmZl5Zma2u5nZ3d3d3d3dfZdpd3d3d3d3ZpaZmZmZmWtmZmZmZra7mdnd3d3d3d19l2l3d3d3d3dmlpmZmZmZa2a2u5nZ3d3d3d3dfZd2d3d3d3dnZpeZmZmZmWlmZmZmZra7mdnd3d3d3d19l3Z3d3d3d2dml5mZmZmZaWa2u5nZ3d3d3d3dfZd2d3d3d3fWbZmZmbl7mblmZmZmZra7mdnd3d3d3d19l3Z3d3d3d2ZmmZmZuXuZuWa2u5nZ3d3d3d3dfZfXd3d3d2cd3ZmZmWm7l5lmZmZmZra7mdnd3d3d3d19l9d3d3d3Z2aWmZmZabuXmWa2u5nZ3d3d193dfZfZ3XfXfWYd0Z3Zl2lnu5dnZmZmZra7mdnd3d3X3d19l9ndd9d9ZmaZmZmZaWa7l2e2u5nZ3d3d193dfZd5193dZ2YdEd0dd3l3trtnZmZmZra7mdnd3d3X3d19l3nX3d1nZpaZmZmZaWa2u2e2u5nZ3d3dd93dfZeZd3dnZmYdEdEdcXl9ZrZrZmZmZra7mdnd3d133d19l5l3d2dmZpmZmZmZaWZmtmu7u5nZ3d3dd9fdfZeZmd3d3Z3ZEdEdcdd9ZmZmZmZmZru7mdnd3d131919l5mZZmZml5mZmZmZaWZmZmZ3ZnbZ3d3dd9fdfZeZmR0R0d3dHdEdEdd9ZmZmZmZmd3dmdtnd3d131919l5mZmZmZmZmZmZmZaWZmZmZ3Z2bW3d3dfXfdfZeZmR0REdHdHREdEd19bWZmZmZ2d3dnZtbd3d19d919l5mZmZmZmZmZmZmZaWZmZmZ3d2dm3d3dfXfdd5mZmd0RERHd3REdEd130WZmZmZ3d3d3Z2bd3d19d913mZmZmZmZmZmZmZmZaWZmZmZ3d3dm1t3dfXfXd5mZmdkdERHR3RHdEX0X0WZmZnZ3d3d3d2bW3d19d9d3mZmZmZmZmZmZmZmZaWZmZmZ3d3dn1t3dfXfXd5mZmZndERER3R3REX0R0WZmZnd3d3d3d2fW3d19d9d3mZmZmZmZmZmZmZmZeWZmZmZ3d3dnZt3d3Xd5l5mZ2d3d3RER0R3R0R0R0WZmZnd3d3d3d2dm3d3dd3mXmZmZmZmZmZmZmZmZmWZmZmZ3d3d3Zt3d3XeZmZmZ2RHR3R0R3d3R0R0R0WZmdnd3d3d3d3dm3d3dd5mZmZmZmZmZmZmZmZmZmWZmZmZ3d3d3Ztbd3XeZmZmZ2R0R0d3dEd3R3RERbWZmdnd3d3d3d3dm1t3dd5mZmZmZmZmZmZmZmZmZmWdmZmZ3d3d3Ztbd3XeXmZmZmd0REd3dEdHd3RERZ2Zmd3d3d3d3d3dm1t3dd5eZmZmZmZmZmZmZmZmZmWlmZmZ3d3d3Ztbd3X2XmZmZmd0dEd3dHRHd3RFxZmZmd3d3d3d3d3dm1t3dfZeZmZmZmZmZmZmZmZmZmXlmZmZ3d3d3Z2bd3X2XmZmZ3R0R0d3dHRHR3R13ZmZmd3d3d3d3d3dnZt3dfZeZmZmZmZmZmZmZmZmZmZlmZmZ3d3d3Z2bd3X2XmZmZ3REREd1dFRHR0d3d3d12d3d3d3d3d3dnZt3dfZeZmZmZmZmZmZmZmZmZmZlpZnZ3d3d3Z2bd3X2XmZnZHREREdHdVREd0d3dHRF9d3d3d3d3d3dnZt3dfZeZmZmZmZmZmZmZmZmZmZmZZ3Z3d3d3Z2bd3d2XmZnZEREREdFVVR0dEd0dERF9d3d3d3d3d3dnZt3d3ZeZmZmZmZmZmZmZmZmZmZmZmXl3d3d3Z2bX3X2ZmZnZ3d0REV1VVdUdEd0RERF9d3d3d3d3d3dnZtfdfZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3Z2Z33ZeZmZnZEREREd1VVR0dER0REdF3d3d3d3d3d3dnZnfdl5mZmZmZmZmZmZmZmZmZmZmZmXd3d3d3Z2Z3d5mZmZnZHREREdFd1REd0R0REZ13d3d3d3d3d3dnZnd3mZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3Z2Z3mZmZmZmZ3RHdEdFV1RHR0R0R3Zl3d3d3d3d3d3dnZneZmZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3Z2aZmZmZmZmZ3d0RERHdHRHR3d3dnZl2d3d3d3d3d3dnZpmZmZmZmZmZmZmZmZmZmZmZmZmZmXZ3d3d3Z2aZmZmZmZnZHRERERHdHRHd3RHRmZlmZnd3d3d3d3dnZpmZmZmZmZmZmZmZmZmZmZmZeZeZmWZ3d3d3Z2aZmZmZmZnZEREREd3dEdHd3RERnZmZeWZ3d3d3d3dnZpmZmZmZmZmZmZmZmZmZmZnZ3X2XmZl3d3d3Z2aZmZmZmZnWERHR3d3R0d3d3R0R0ZmZmXlmdnd3d3dnZpmZmZmZmbZ7mZmZmZmZmZnd3d13mZl3d3d3Z2aZmZmZmWbX3d3d3R3R3d3R0RcR0ZeZmZlpdnd3d3dnZpmZmZmZZne2e5mZmZmZmdnd3d19l5l3d3d3Z2aZmZmZaWZmd93d3RER0d3R0X0REX2ZmZlpd3d3d3dnZpmZmZlpZmZ3u5uZmZmZmd3d3d3dd5l3d3d3Z2aZmZmZZmZmdt3dERER0R3REX0XEX2ZmZlpd3d3d3dnZpmZmZlmZmZ2t7uZmZmZmd3d3d3dd5l3d3d3Z2aZmZlpZmZmZtcdERER3R3REdd3EX2XmZl2d3d3d3dnZpmZmWlmZmZmd7ubmZmZ2d3d3d3dfZd3d3d3ZnaZmZlmZmZmZt0RERHR3REdEdd9132XmZl2d3d3d3dmdpmZmWZmZmZmdrZ7mZmZ2d3d3d3dfZd3d3d3ZpaZmZlmZmZmZh0RERHd3REdEdfd3X2XmWl3d3d3d3dmlpmZmWZmZmZmdme7mZmZ3d3d3d3dfZd3d3d3ZpaZmZlrZmZmZh0REd3dHREdEdfd3X2XmWl3d3d3d3dmlpmZmWtmZmZmZme7l5mZ3d3d3d3dfZd3d3dnZpeZmZlnZmZmZt3d3Z3ZEdEdEdfd3X2XmXZ3d3d3d2dml5mZmWdmZmZmZma7m5mZ3d3d3d3dfZd3d3dnZpmZmZlpZmZmZmZmu3vZEdEXcd3d3X2XmXZ3d3d3d2dmmZmZmWlmZmZmZma7e5nZ3d3d3d3dfZd3d3dmdpmZmZl5ZmZmZmZmtrsdEd0Xcd3d3X2XaXd3d3d3d2Z2mZmZmXlmZmZmZma2u5nZ3d3d3d3dfZd3d3dmlpmZmZmZa2ZmZmZmtrsd0d13193d3X2XaXd3d3d3d2aWmZmZmZlrZmZmZma2u5nZ3d3d3d3dfZd3d2dml5mZmZmZaWZmZmZmtrvd3d3d3d3d3X2Xdnd3d3d3Z2aXmZmZmZlpZmZmZma2u5nZ3d3d3d3dfZd3d2ZmmZmZuXuZuWZmZmZmtruZ2d3d3d3d3X2Xdnd3d3d3ZmaZmZm5e5m5ZmZmZma2u5nZ3d3d3d3dfZd3Z2aWmZmZabuXmWZmZmZmtruZ2d3d3d3d3X2X13d3d3dnZpaZmZlpu5eZZmZmZma2u5nZ3d3d3d3dfZd9ZmaZmZmZaWa7l2dmZmZmtruZ2d3d3dfd3X2X2d13131mZpmZmZlpZruXZ2ZmZma2u5nZ3d3d193dfZdnZpaZmZmZaWa2u2dmZmZmtruZ2d3d3dfd3X2Xedfd3WdmlpmZmZlpZra7Z2ZmZma2u5nZ3d3d193dfZdmZpmZmZmZaWZmtmtmZmZmtruZ2d3d3Xfd3X2XmXd3Z2ZmmZmZmZlpZma2a2ZmZma2u5nZ3d3dd93dfZdml5mZmZmZaWZmZmZmZmZmu7uZ2d3d3XfX3X2XmZlmZmaXmZmZmZlpZmZmZmZmZma7u5nZ3d3dd9fdfZeZmZmZmZmZaWZmZmZmZmZ3d2Z22d3d3XfX3X2XmZmZmZmZmZmZmZlpZmZmZmZmZnd3ZnbZ3d3dd9fdfZeZmZmZmZmZaWZmZmZmZnZ3d2dm1t3d3X133X2XmZmZmZmZmZmZmZlpZmZmZmZmdnd3Z2bW3d3dfXfdfZeZmZmZmZmZaWZmZmZmZnd3d3dnZt3d3X133XeZmZmZmZmZmZmZmZlpZmZmZmZmd3d3d2dm3d3dfXfdd5mZmZmZmZmZaWZmZmZmdnd3d3d3Ztbd3X1313eZmZmZmZmZmZmZmZlpZmZmZmZ2d3d3d3dm1t3dfXfXd5mZmZmZmZmZeWZmZmZmd3d3d3d3Z9bd3X1313eZmZmZmZmZmZmZmZl5ZmZmZmZ3d3d3d3dn1t3dfXfXd5mZmZmZmZmZmWZmZmZmd3d3d3d3Z2bd3d13eZeZmZmZmZmZmZmZmZmZZmZmZmZ3d3d3d3dnZt3d3Xd5l5mZmZmZmZmZmWZmZmZ2d3d3d3d3d2bd3d13mZmZmZmZmZmZmZmZmZmZZmZmZnZ3d3d3d3d3Zt3d3XeZmZmZmZmZmZmZmWdmZmZ2d3d3d3d3d2bW3d13mZmZmZmZmZmZmZmZmZmZZ2ZmZnZ3d3d3d3d3Ztbd3XeZmZmZmZmZmZmZmWlmZmZ3d3d3d3d3d2bW3d13l5mZmZmZmZmZmZmZmZmZaWZmZnd3d3d3d3d3Ztbd3XeXmZk="}},"sprites.background.lunarnewyear":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAADd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3aqqqqra3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dqioiIiKi2t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3NLCIiIiIiwt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1dVd3d3d3d3d3d3d3d3d3d3d3MIiJEREQkItzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dVVXdVdXd3d3d3d3d3d3d3d3d3c0sIlRVRUREJMLd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1dVVXVXdXd3d3d3d3d3d3d3d3d3cwiQlUkIiJCRMTc3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1VVVVVXVXd3d3d3d3d3d3d3d3d3SwiVCQiIiIiQkTc3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1VVd1VXVXd3d3d3d3d3d3d3d3dTSRCJCIiIiIiIkLc3d0RERERERERERHR3d3d3d3d3d3d3d3d3d3d3d1V1V1VXVXd3d3d3d3d3d3d3d3dVE1CIiIiIiIiIkIcERERERERERERERERERHd3d3d3d3d3d3d3d3d3d1V1V3VXVXd3d3d3d3d3d3d3d3dVEUiIiIiQkREJCLCEREREREREREREREREREREdHd3d3d3d3d3d3d3d1V1d3dVVXd3d3d3d3d3d3d3d3dVFUiIkJERERERCTCEREREREREREREREREREREREREd3d3d3d3d3d3d1dVd1dVVXd3d3d3d3d3d3d3d3dVFUiQkQkIiIiIkLCFBERERERERERERERERERERERERER3d3d3d3d3d3dXVVVVVXd3d3d3d3d3d3d3d1NVFUiRCIiIiIiIiLERBEREREREREREREREREREREREREREdHd3d3d3VXVXVVVVVXd3d3d3d3d3d3d3d1N1FUiIiIiIiIiIiLCREREEUFEREREREQRERERERERERERERHd3d3dVVVV3VVVVVXd3d3d3d3d3d3d3d1URFUiIiIiIiIiIiLCRNTV091dVVVVVUURERERERERERERERER3d1dVVVV3VVVVVXdTURERERERERERERUTVUiIiIiIiIiIiLERVRVQzRd1d1NREQRERERERERERERERER0d1VVVVV1VVVVVXdXVVVVVVVVVVVVVVUTVUiIiIiIiIiQkTERdTV091dVVVVVd0UERERERERERERERER0V1VVVVV1V1VVVXdTURERERERERERERURFVCVVVVVURERCTCRUREREREREREREQUERERERERERERERER0V1VVVVV1V1VVVXd3d3d3d3d3d3d3d1N1FUiIiIiIiIiIiLCTRERERERERERERERERERERERERERERER0V1V1d1V1V1VVVXd3d3d3d3d3d3d3d1NVFUiIiIiIiIiIiLCFBERERERERERERERERERERERERERERER3VVV3d1d1VVVVVXd3d3d3d3d3d3d3d3dVFUiIiIiIiIiIiLCERERERERERERERERERERERERERERERER3VXVXdVd3VVVVVXd3d3d3d3d3d3d3d3dVFUiIiIiIiIiIiLEERERERERERERERERERERERERERERERER3VXVXdVV3VVVVVXd3d3d3d3d3d3d3d3dVEUiQiQiIiIiIkTEERERERERERERERERERERERERERERERER3VVV3VXVXVVVVVXd3d3d3d3d3d3d3d3dVE0iIkREREREREQcERERERERERERERERERERERERERERERER3VVV3d3dVVXV3V3d3d3d3d3d3d3d3d3dTSRCIiJCREREJEIcERERERERERERERERERERERERERERERER3VVV1d1dVVXdVV3d3d3d3d3d3d3d3d2tqixCRSIiIiIiIkQcERERERERERERERERERERERERERERERER3VVVVVVVVVVdVd3d3d3d3d3d3d3d3a2qIswiVFUkIiIiRMIcERERERERERERERERERERERERERERERER0VVVVVVVVdVdVd3d3d3d3d3d3d3d3cwiIsIsIlRVRUREJMIRERERERERERERERERERERERERERERERER0V1VVVVVVdVdVd3d3d3d3d3d3d3dzSwiQkTMIiJCREQkIhwRERERERERERERERERERERERERERERERER0V1VVVVVVdXdVdXd3d3d3d3d3d3dzCJCRETELCIiIiIiwhEREREREREREREREREREREREREREREREREREd1VVVVVVVXdVdXd3d3d3d3d3d3NLCJEJCIiqioiIiKiGhEREREREREREREREREREREREREREREREREREdFd3d1dVVXVVdXd3d3d3d3d3d3NIkIkIiIiIqqqqqoaERERERERERERERERERERERERERERERERERERERHd3d3dVVVVVdXd3d3d3d3d3d1EIkQiIiIiIiIixBwRERERERERERERERERERERERERERERERERERERERHR3VXVXVVVVdXd3d3d3d3d3U3VJCQiIiIiIiIixBERERERERERERERERERERERERERERERERERERERERHRVVVVXVVVVdXd3d3d3d3d3U1VJCIiIiJEREQiIhwRERERERERERERERERERERERERERERERERERERERFdVVVV3VVVVdXd3d3d3d3d3U1VJSIiREREREREIhwRERERERERERERERERERERERERERERERERERERERFdVdVV3VVVVdXd3d3d3d3d3U1VJSJERCIiIiIiJEwRERERERERERERERERERERERERERERERERERERERFdVd1V3VVVVdXd3d3d3d3d3URVJUIkIiIiIiIiQkwUERERERERERERERERERERERERERERERERERERERFdVd1V3VVVVdXd3d3d3d3d3URdJSIiIiIiIiIiIkxEREREREREREREFBERERERERERERERERERERERERFdVd3dXVVVVdXd3d3d3d3dTUVUJSIiIiIiIiIiIkxEXT3d3VVVVVVVFBERERERERERERERERERERERERFdVdXdVVVVVdXdTURERERERNVUJSIiIiIiIiIiQlxEVTVE01Xd3UREFBERERERERERERERERERERERERHdVVVVVVVVVdXdXVVVVVVVRdVUJSIiIiIiIiJERFxEXT3d3VVVVVXVTRERERERERERERERERERERERERHRVVVVVVVVVdXdTUREREREREVUJUREREREREREIlxERERERERERERERBERERERERERERERERERERERERHRXVVVVVVVVdXd3d3d3d3d3URdJSIiIiIiIiIiItwUERERERERERERERERERERERERERERERERERERERHd3d1VVVVVVdXd3d3d3d3d3URVJSIiIiIiIiIiIkwRERERERERERERERERERERERERERERERERERERERHd3d1VVVVVVdXd3d3d3d3d3U1VJSIiIiIiIiIiIhwRERERERERERERERERERERERERERERERERERERERFd3V1VXVVVVdXd3d3d3d3d3U1VJSIiIiIiIiIiQhwREREREREREREREREREREREREREREREREREREREdFd3V1V1V1VVVXd3d3d3d3d3U1VJCJEIiIiIiJCRBwREREREREREREREREREREREREREREREREREREREdFV3V1VVd1VVVXd3d3d3d3d3U3VJCJCRERERERExBEREREREREREREREREREREREREREREREREREREREdFV3V1VVdVdVVXd3d3d3d3d3d1EIiQiIkREREQixBEREREREREREREREREREREREREREREREREREREREdFV3d1VVdVdVVXd3d3d3d3d3d3NIkQiIiIiIiJCxBEREREREREREREREREREREREREREREREREREREREd1V3d1dVd1VVVXd3d3d3d3d3d3NLCIkIiIiIkIkzBERERERERERERERERERERERERERERERERERERER0d1V3d3d3V1VVVXd3d3d3d3d3d1VzCJCREREREQiHBERERERERERERERERERERERERERERERERERERHR3d1V3d3d3V1VVdXd3d3d3d3d3V1VxSwiIkRERCLCERERERERERERERERERERERERERERERERERERERHd3d1V1d3d3V1VVdXd3d3d3d3d3V1VVcwiIiIiIiIcEREREREREREREREREREREREREREREREREREREdFdVdVdVd3d3V1VVdXd3d3d3d3d3V1VVaWqIiIiIqoREREREREREREREREREREREREREREREREREREREdFVVVVdVVVV1V1VVdXd3d3d3d3d3d1VVVWtqqqqqhEREREREREREREREREREREREREREREREREREREREd1VVVVdVVVV1d1dVdXd3d3d3d1dVdVdVVXdHREREREREREREREREREREREREREREREREREREREREREREV1V1V1dVVVV1d1dVdXd3d3d3d1VVVXdVVXdEREREREREREREREREREREREREREREREREREREREREREREV1V1dVdVVVV1d1dVdXd3d3d3V1V1VXdVVXdEREREREREREREREREREREREREREREREREREREREREREREV1V1d1dVVVV1d1dVdXd3d3d3V1V1VXVVVXdEREREREREREREREREREREREREREREREREREREREREREREV1VVd1VVVVV1d3dVdXd3d3d3V1V3VXdVVXdEREREREREREREREREREREREREREREREREREREREREREREV1VVVVVVVVV1d3dVdXd3d3d3V1V1d1dVVXVEREREREREREREREREREREREREREREREREREREREREREREV1VVVVVVVVV1d3dXdXd3d3d3V1VVV1VVVXVEREREREREREREREREREREREREREREREREREREREREREREV1VVVVVVVVV1d3dXdXd3d3d3V1VVVVVVVXVEREREREREREREREREREREREREREREREREREREREREREREdFV1d3dXVVV1d3dXdXd3d3d3d1VVVVVVVXVEREREREREREREREREREREREREREREREREREREREREREREdFd3VVV3VVV1d3dXdXd3d3d3d3V3VVVVVXdERERERERERERERERERERERERERERERERERERERERERERERHdXVVV1VVV1d3dXd3d3d3d3d3d3V1VVVXdERERERERERERERERERERERERERERERERERERERERERERERHRXVVV1VVV1d3dXd3d3d3d3V1VVd1VVVXdERERERERERERERERERERERERERERERERERERERERERERERERXVXV3VVV1d3dXd3d3d3d3VVVVdVVVVXdERERERERERERERERERERERERERERERERERERERERERERERER3VVVXVVV1d3dXd3d3d3dXVVVVdVVVVXdERERERERERERERERERERERERERERERERERERERERERERERER0VVVVVVV1d3dXd3d3d3dVVXVXdVdVVXVERERERERERERERERERERERERERERERERERERERERERERERER0V1VVVVV1d3d3d3d3d1dVVVdXdVdVVXVEREREREREREREREREREREREREREREREREREREREREREREREREd3dXVVV1d3d3d3d3d1dVdVdVdVdVVXVEREREREREREREREREREREREREREREREREREREREREREREREREdHdVVVV1d3d3d3d3d1dVdVVVdVdVVXVERERERERERERERERERERERERERERERERERERERERERERERERERHdVVVV1d3d3d3d3d1dVdVdVdVdVVXVERERERERERERERERERERERERERERERERERERERERERERERERERHRVVVV1d3d3d3d3d1dVVXd3d1VVVXVERERERERERERERERERERERERERERERERERERERERERERERERERHRVVVV1d3d3d3d3d1dVVXV3VVVVVXVERERERERERERERERERERERERERERERERERERERERERERERERERERXVVV1d3d3d3d3d1dVVVVVVVVVVXVERERERERERERERERERERERERERERERERERERERERERERERERERER3dVV1d3d3d3d3d1dVVVVVVVVVVXVERERERERERERERERERERERERERERERERERERERERERERERERERER3d1V1d3d3d3d3d3dVVVVVVVVVVXVERERERERERERERERERERERERERERERERERERERERERERERERERER0d1V1d3d3d3d3d3dXVVVVVVVVVXVEREREREREREREREREREREREREREREREREREREREREREREREREREREV1V1d3d3d3d3d3d3VVVVVVVVVXVEREREREREREREREREREREREREREREREREREREREREREREREREREREV1V1d3d3d3d3d3d3dXd3V1VVVXVEREREREREREREREREREREREREREREREREREREREREREREREREREREdFV1d3d3d3d3d3d3d1VVd1VVVXVEREREREREREREREREREREREREREREREREREREREREREREREREREREdFV1d3d3d3d3d3d3V1VVd1VVVXVEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd1d3d3d3d3d3d3VXVVdVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd1d3d3d3d3d3d3VXdVdVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd1d3d3d3d3d3d3dVdVdVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd1d3d3d3d3d3d3dVdVd1VVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd1d3d3d3d3d3d3VXd3V1VVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd1d3d3d3d3d3d3VVVVVVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd3d3d3d3d3d3d3VVVVVVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd3d3d3d3d3d3d3V1VVVVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHd3d3d3d3d3d3d3d1VVVVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdHdQ0RE3d3d3d3d3d1dVVVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREdEzXVVNu+7d3d3d3d3dVVVVVVXdERERERERERERERERERERERERERERERERERERERERERERERERERERETFdVVVVNDPd3d3d3d3dXVVVVVXdEREREREREREREREREREREREREREREREREREREREREREREREREREREVPV3d1VTTPd3d3d3d3d3d1dVVXdEdERERERERERERERERERERERERERERERERERERERERERERERERERMVXd3d1d1dXd3d3d3d3d3d1dVVXdEdERERERERERERERERERERERERERERERERERERERERERERERERERMdVV1VVd1VXd3d3d3d3d3d3dVVXdEdERERERERERERERERERERERERERERERERERERERERERERERERERM9VV1VVd1V3d3d3d3d3d3d1dVVXdEdERERERERERERERERERERERERERERERERERERERERERERERERERU11V1VXV1d3d3d3d3d3d3d1dVVXdEd0RERERERERERERERERERERERERERERERERERERERERETFERBQRU11V1VXVVV3d3d3d3d3d3d1dVVXdEd0RERERERERERERERERERERERERERERERERERERERERMdNV1bQ7U11V3VXVVV3d3d3d3d3d3d1dVVXdEd0dERERERERERERERERERERERERERERERERERERERER01VVVUUzXd3dM1XVVV3d3d3d3d3d3d3dVVXdHd0dERERERERERERERERERERERERERERERERERERERExVd3dXdU01V01PVPdVV3d3d3d3d3d3d3dVVXdHd0dERERERERERERERERERERERERERERERERERERERFT1d3d3VU91VXV3VPdVd3d3d3d3d3d3d3dVVXdHV0dERERERERERERERERERERERERERERERERERERERFTXVVd1VU91VXV3dPdXd3d3d3d3d3d3d3d1VXdHV0dERERERERERERERERERERERERERERERERERERETFTXVVd1VU91VXd3VPVXV3d3d3d3d3d3d3d3dXd3V0dERERERERERERERERERERERERERERERERERERETHVVVVdVV091VXd3VNVXV3d3d3d3d3d3d3d3dXd3V0dERERERERERERERERERERERERERERERERERERETHVVVVdVV011VU9PVNVXV3d3d3d3d3d3d3d3dXd3V0dERERERERERERERERERERERERERERERERERERETPVVdVdVV01VV3dM11VXd3d3d3d3d3d3d3d3dXd3V3VEREREREREREREREREREREREREREREREREREREdPV3T1TVV01Xd3d3V1VXV3d3d3d3d3d3d3d3dXd3V3VEREREREREREREREREREREREREREREREREREREVPdVdMz1V3VVF1VVV1VXV3d3d3d3d3d3d3d3dXdXVXVEREREREREREREREREREREREREREREREREREREVNdVd091V3VVF1VVV3VVVXd3d3d3d3d3d3d3dXdXVXVEREREREREREREREREREREREREREREREREREREVNdVd093d3VVNVVVV3d1T3d3d3d3d3d3d3d3dXdVVXVEREREREREREREREREREREREREREREREREREREVNd1d09Vd3VNdVd1d1d1TXd3d3d3d3d3d3d3dXdVVXVEREREREREREREREREREREREREREREREREREREVNd1d09VdXVNVXd3d1VXTXd3d3d3d3d3d3d3d3dXVXVEREREREREREREREREREREREREREREREREREREVNd1dMzVdXV1dRVVVXVM7vd3d3d3d3d3d3d3d1V3VXVEREREREREREREREREREREREREREREREREREREVPV1T3TVdXVXU1UVbU7MzPd3d3d3d3d3d3d3V1V1VXVEREREREREREREREREREREREREREREREREREREdPV3d3dVdXVVd1NRLu7u7vd3d3d3d3d3d3d3VVV1V3VEREREREREREREREREREREREREREREREREREREUHVVVXVVdXVVd3j3d3d3d3d3d3d3d3d3d3dXVXV1V3VEREREREREREREREREREREREREREREREREREREUHVVVXVVV1VNURE1N3d3d3d3d3d3d3d3d3dXVXd1V3VEREREREREREREREREREREREREREREREREREREUFVXVXV1V0901XVtOve3d3d3d3d3d3d3d3dXVVd3VXVERERERERERERERERERERERERERERERERERERERFT3VXd3VXTVVVVRTPj7t3d3d3d3d3d3d3dXVXdXVXVHRERERERERERERERERERERERERERERERERERERFT1d3dXTVV3d1d1TQzRNTd3d3d3d3d3d3dXVVVVVXVHRERERERERERERERERERERERERERERERERERERFBXVVVVVPV3d3dVV3dQ9Td3d3d3d3d3d3d3VVVVVXVHRERERERERERERERERERERERERERERERERERERERRFVVu1NdVV3VVV3VTdTd3d3d3d3d3d3d3d3dXVXVHREREREREREREREREREREREREREREREREREREREREUS0O1NdVV3VVd3VvUvd3d3d3d3d3d3d3d1d3VXVHRERERERERERERERERERERERERERERERERERERERERERMdVVVV1VXd09M+vd3d3d3d3d3d3d3d1V1VXV3RERERERERERERERERERERERERERERERERERERERERERMdVVVV1VXdXV3T3d3d3d3d3d3d3d3d1V1VXV3RERERERERERERERERERERERERERERERERERERERERERM9VV1V1VXdVV3T3d3d3d3d3d3d3d3d1V1VXV3R0RERERERERERERERERERERERERERERERERERERERER09XdPVNVXdVV3d3d3d3d3d3d3d3d3d1d3VXV3d0RERERERERERERERERERERERERERERERERERERERERU91V0zPVXdU1Q7vd3d3d3d3d3d3d3d1dVVXV3d0dERERERERERERERERERERERERERERERERERERERERU11V3T3VXdXdTbTd3d3d3d3d3d3d3d3dVVXV3d3dERERERERERERERERERERERERERERERERERERERERU11V3T3d3dVd3d3d3d3d3d3d3d3d3d3dXVXV3d3dHRERERERERERERERERERERERERERERERERERERERU13V3T1V3dVV3d3d3d3d3d3d3d3d3d3d3VXV3d3d3R0RERERERERERERERERERERERERERERERERERERU13V3T1V1dVV3U3d3d3d3d3d3d3d3d3d3V3V3d3d3d0dERERERERERERERERERERERERERERERERERERU13V0zNV1dXVM0Td3d3d3d3d3d3d3d3d3V3V3d3d3d3d3RERERERERERERERERERERERERERERERERERU9XVPdNV1dVd3U3d3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d0dERERERERERERERERERERERERERERERER09Xd3d1V1dVV3U3d3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d3d3R0RERERERERERERERERERERERERERERTdVVVdVV1dVV3ePd3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d3d3d3dHRERERERERERERERERERERER0d3dTdVVVdVVXVXVPe7d3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d3d3d3d3d3d3RERERERERERERHd3d3d3d3dTVVdVdXVXd0zu97d3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3VPdVd3dVV0zs9Pd3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3VPV3d1d1VUzu93d3d3d3d3d3d3d3d3d3V3V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3U1dVVVVPbO7O93d3d3d3d3d3d3d3d3d3d3V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1EVVW7MzOz3d3d3d3d3d3d3d3d3d3d3d3V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dRLS7u7s73d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0="}},"sprites.background.moon":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAAD/////////////////////////zLy7uzvDzLy73d3d3TPd0727293d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////P////8//////zLy7u7vDzLu73d3dPTPdMz27093d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7szzLu73d3dPTPdPd2z3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP///////////8/M/v/////////z7y7u7u7u7sz3d3dPTPdPdMz3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7u7uzsz3d3dPTPd3TPT3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP/////////////P///////////z7y7u7u7uzsz3d3dPTPd3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP//////8///////////////8z/z7y7u7u7uzsz3d3dPTPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8z/z7y7O7y7uzsz3d3d3TPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7O8y7u7vT3d3d3dPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7w8y7u7vb3d3d3d3d3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////P//////z7y7w8u8u7vb3d3d3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////Py///////zLy7w8u8u7vb3T3T3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////////8///////P//////zMy7w8u8u7vT3TOz3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP///////////////////////zPzMy7w8u8u7vT3TO7093d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8u8u7vdPdO7293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8y7M7vdPT27293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8///////////////MzMy7O8y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////8/L///////////8///MzMy8O7y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP/////////////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////MzMy8u7u7u7vdPb27O93d3TMz3d3d3TM9MzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27O93dPdOz093d3TPdMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dPd27293d3TPdPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dMz27293d3T3TPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7s7vd3dO7093d0727O93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+8/P///////8/MzMy8w7u7u7vd3TOz3d3d0727u93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+7+////////8/MzMw8w7y7u7vd3T3T3d093bO7u93d3T3T3TMzMzMzMzMzMzMzMzMzMzP///////////+8/P///8///8/MzMw7vLy7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7u7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7y7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7y7szzLvd3d3d3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7u7vDzLvTPdvd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP/////////z//////////////MzLy7uzvDzLzTM7vd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzvMy7zb07vd3d093bu7u93d3d3d3TMzMzMzMzMzMzMzMzMzMzP//////////////8/L///P///MzLy7uzu8y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLy7w7Pbvd3d093bu7u93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLzLy7Pdvd3d0907O7O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////8////////////////zLy7uzvLzLy73d3d3dPd0727O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////zLy7uzvDzLy73d3d3TPd0727293d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////P////8//////zLy7u7vDzLu73d3dPTPdMz27093d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7szzLu73d3dPTPdPd2z3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP///////////8/M/v/////////z7y7u7u7u7sz3d3dPTPdPdMz3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7u7uzsz3d3dPTPd3TPT3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP/////////////P///////////z7y7u7u7uzsz3d3dPTPd3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP//////8///////////////8z/z7y7u7u7uzsz3d3dPTPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8z/z7y7O7y7uzsz3d3d3TPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7O8y7u7vT3d3d3dPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7w8y7u7vb3d3d3d3d3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////P//////z7y7w8u8u7vb3d3d3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////Py///////zLy7w8u8u7vb3T3T3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////////8///////P//////zMy7w8u8u7vT3TOz3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP///////////////////////zPzMy7w8u8u7vT3TO7093d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8u8u7vdPdO7293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8y7M7vdPT27293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8///////////////MzMy7O8y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////8/L///////////8///MzMy8O7y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP/////////////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////MzMy8u7u7u7vdPb27O93d3TMz3d3d3TM9MzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27O93dPdOz093d3TPdMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dPd27293d3TPdPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dMz27293d3T3TPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7s7vd3dO7093d0727O93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+8/P///////8/MzMy8w7u7u7vd3TOz3d3d0727u93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+7+////////8/MzMw8w7y7u7vd3T3T3d093bO7u93d3T3T3TMzMzMzMzMzMzMzMzMzMzP///////////+8/P///8///8/MzMw7vLy7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7u7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7y7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7y7szzLvd3d3d3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7u7vDzLvTPdvd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP/////////z//////////////MzLy7uzvDzLzTM7vd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzvMy7zb07vd3d093bu7u93d3d3d3TMzMzMzMzMzMzMzMzMzMzP//////////////8/L///P///MzLy7uzu8y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLy7w7Pbvd3d093bu7u93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLzLy7Pdvd3d0907O7O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////8////////////////zLy7uzvLzLy73d3d3dPd0727O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////zLy7uzvDzLy73d3d3TPd0727293d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////P////8//////zLy7u7vDzLu73d3dPTPdMz27093d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7szzLu73d3dPTPdPd2z3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP///////////8/M/v/////////z7y7u7u7u7sz3d3dPTPdPdMz3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7u7uzsz3d3dPTPd3TPT3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP/////////////P///////////z7y7u7u7uzsz3d3dPTPd3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP//////8///////////////8z/z7y7u7u7uzsz3d3dPTPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8z/z7y7O7y7uzsz3d3d3TPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7O8y7u7vT3d3d3dPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7w8y7u7vb3d3d3d3d3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////P//////z7y7w8u8u7vb3d3d3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////Py///////zLy7w8u8u7vb3T3T3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////////8///////P//////zMy7w8u8u7vT3TOz3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP///////////////////////zPzMy7w8u8u7vT3TO7093d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8u8u7vdPdO7293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8y7M7vdPT27293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8///////////////MzMy7O8y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////8/L///////////8///MzMy8O7y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP/////////////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////MzMy8u7u7u7vdPb27O93d3TMz3d3d3TM9MzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27O93dPdOz093d3TPdMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dPd27293d3TPdPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dMz27293d3T3TPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7s7vd3dO7093d0727O93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+8/P///////8/MzMy8w7u7u7vd3TOz3d3d0727u93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+7+////////8/MzMw8w7y7u7vd3T3T3d093bO7u93d3T3T3TMzMzMzMzMzMzMzMzMzMzP///////////+8/P///8///8/MzMw7vLy7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7u7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7y7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7y7szzLvd3d3d3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7u7vDzLvTPdvd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP/////////z//////////////MzLy7uzvDzLzTM7vd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzvMy7zb07vd3d093bu7u93d3d3d3TMzMzMzMzMzMzMzMzMzMzP//////////////8/L///P///MzLy7uzu8y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLy7w7Pbvd3d093bu7u93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLzLy7Pdvd3d0907O7O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////8////////////////zLy7uzvLzLy73d3d3dPd0727O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////zLy7uzvDzLy73d3d3TPd0727293d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////P////8//////zLy7u7vDzLu73d3dPTPdMz27093d3d3dMzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7szzLu73d3dPTPdPd2z3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP///////////8/M/v/////////z7y7u7u7u7sz3d3dPTPdPdMz3d3d3d09MzMzMzMzMzMzMzMzMzMzMzP/////////////O7P/////////z7y7u7u7uzsz3d3dPTPd3TPT3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP/////////////P///////////z7y7u7u7uzsz3d3dPTPd3d3d3d3d3d0zMzMzMzMzMzMzMzMzMzMzMzP//////8///////////////8z/z7y7u7u7uzsz3d3dPTPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8z/z7y7O7y7uzsz3d3d3TPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7O8y7u7vT3d3d3dPd3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP/////////////////////////z7y7w8y7u7vb3d3d3d3d3d3d3d3d3T0zMzMzMzMzMzMzMzMzMzMzMzP//////////////////P//////z7y7w8u8u7vb3d3d3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////Py///////zLy7w8u8u7vb3T3T3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////////8///////P//////zMy7w8u8u7vT3TOz3d3d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP///////////////////////zPzMy7w8u8u7vT3TO7093d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8u8u7vdPdO7293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzMy7s8y7M7vdPT27293d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8///////////////MzMy7O8y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP//////8/L///////////8///MzMy8O7y7M7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////8////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP/////////////z/z////////MzMy8u7u7u7vdPb27O93d3d3d3d3d3TMzMzMzMzMzMzMzMzMzMzMzMzP////////////////////////MzMy8u7u7u7vdPb27O93d3TMz3d3d3TM9MzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27O93dPdOz093d3TPdMzMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dPd27293d3TPdPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7u7vdPb27293dMz27293d3T3TPTMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy8u7u7s7vd3dO7093d0727O93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+8/P///////8/MzMy8w7u7u7vd3TOz3d3d0727u93d3T3TPTMzMzMzMzMzMzMzMzMzMzP///////////+7+////////8/MzMw8w7y7u7vd3T3T3d093bO7u93d3T3T3TMzMzMzMzMzMzMzMzMzMzP///////////+8/P///8///8/MzMw7vLy7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7u7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMw7y7y7u7vd3d3d3d093bu7u93d3d0z3TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7y7szzLvd3d3d3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP//////////////////////8/MzMy7u7vDzLvTPdvd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP/////////z//////////////MzLy7uzvDzLzTM7vd3d093bu7u93d3d093TMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzvMy7zb07vd3d093bu7u93d3d3d3TMzMzMzMzMzMzMzMzMzMzP//////////////8/L///P///MzLy7uzu8y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////8///////MzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzu7y7zb07vd3d093bu7u93d3d3dPTMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLy7w7Pbvd3d093bu7u93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////////////////////PzLy7uzvLzLy7Pdvd3d0907O7O93d3d3dMzMzMzMzMzMzMzMzMzMzMzP////////8////////////////zLy7uzvLzLy73d3d3dPd0727O93d3d3dMzMzMzMzMzMzMzMzMzMzMzM="}},"sprites.background.snowynight":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAACIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdhmRmZmZERERERERkRkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdpmRmZmZERERERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmdpkRmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIaGZmZml5kZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIhoZmZmZmZmmZmZmZmZGRERERERERGZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIhmZmaGZ2mZmZmZmZmRERFmFhERaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIgzM4iIiIiIiGhoaGaWmZmZmZmZmRZhFmZhFmaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIiIiIaGaXmZmZmZmZZhZmZmZmFmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIiIiIiIaGaXmZmZmZmWZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGaZmZmWlmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZaWZmZmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZmWmWZmlmZmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZaZmWlmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZmZkZZmZmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlpFmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlplmlmYWYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiIiJiZmZmZmZkZkZkZkRkWEWERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI3Y2IiIiIiJiZmZmZmZkRkZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiGhpaZmZmZmZkRmZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmiGZpaZmZmZmRkRmZkZmRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZpaZmZmZmRmRmZkZGRERERGRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZpaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIhoiIiIiIiIiIiIZoaJaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZmZGZmZmZEREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZGZmZmZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZmZmZaZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZnaZmZmZGZmWlmYWERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIaIiGZnaZmWlpaZZmlmYZERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIaIiIiIiIiIiIaIaGZmaZZmZmZmZmZmYRERERERkRERERERERERERERERERERERERERGIiIhohoiIiIiIloaIiIiIiIhoaGZmZmaZkZZpZmZmZpYRERERkRERERERERERERERERERERERERERERGIiIhohoiIiIiIaIiIiIiIiGZoZmZmZmaXkZlpGWZmZhkRERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmaXkZmZmWlpZhERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIZohmZmZmaWEZmZmZlpmRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiGZoZmaWGZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZ2GZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhoiIiIiIhoZmZmmRGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmlxGZmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIhoZmZmdxmRmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdhmRmZmZERERERERkRkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdpmRmZmZERERERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmdpkRmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIaGZmZml5kZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIhoZmZmZmZmmZmZmZmZGRERERERERGZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIhmZmaGZ2mZmZmZmZmRERFmFhERaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIgzM4iIiIiIiGhoaGaWmZmZmZmZmRZhFmZhFmaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIiIiIaGaXmZmZmZmZZhZmZmZmFmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIiIiIiIaGaXmZmZmZmWZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGaZmZmWlmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZaWZmZmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZmWmWZmlmZmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZaZmWlmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZmZkZZmZmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlpFmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlplmlmYWYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiIiJiZmZmZmZkZkZkZkRkWEWERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI3Y2IiIiIiJiZmZmZmZkRkZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiGhpaZmZmZmZkRmZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmiGZpaZmZmZmRkRmZkZmRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZpaZmZmZmRmRmZkZGRERERGRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZpaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIhoiIiIiIiIiIiIZoaJaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZmZGZmZmZEREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZGZmZmZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZmZmZaZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZnaZmZmZGZmWlmYWERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIaIiGZnaZmWlpaZZmlmYZERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIaIiIiIiIiIiIaIaGZmaZZmZmZmZmZmYRERERERkRERERERERERERERERERERERERERGIiIhohoiIiIiIloaIiIiIiIhoaGZmZmaZkZZpZmZmZpYRERERkRERERERERERERERERERERERERERERGIiIhohoiIiIiIaIiIiIiIiGZoZmZmZmaXkZlpGWZmZhkRERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmaXkZmZmWlpZhERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIZohmZmZmaWEZmZmZlpmRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiGZoZmaWGZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZ2GZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhoiIiIiIhoZmZmmRGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmlxGZmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIhoZmZmdxmRmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdhmRmZmZERERERERkRkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdpmRmZmZERERERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmdpkRmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIaGZmZml5kZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIhoZmZmZmZmmZmZmZmZGRERERERERGZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIhmZmaGZ2mZmZmZmZmRERFmFhERaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIgzM4iIiIiIiGhoaGaWmZmZmZmZmRZhFmZhFmaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIiIiIaGaXmZmZmZmZZhZmZmZmFmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIiIiIiIaGaXmZmZmZmWZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGaZmZmWlmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZaWZmZmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZmWmWZmlmZmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZaZmWlmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZmZkZZmZmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlpFmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlplmlmYWYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiIiJiZmZmZmZkZkZkZkRkWEWERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI3Y2IiIiIiJiZmZmZmZkRkZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiGhpaZmZmZmZkRmZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmiGZpaZmZmZmRkRmZkZmRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZpaZmZmZmRmRmZkZGRERERGRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZpaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIhoiIiIiIiIiIiIZoaJaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZmZGZmZmZEREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZGZmZmZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZmZmZaZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZnaZmZmZGZmWlmYWERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIaIiGZnaZmWlpaZZmlmYZERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIaIiIiIiIiIiIaIaGZmaZZmZmZmZmZmYRERERERkRERERERERERERERERERERERERERGIiIhohoiIiIiIloaIiIiIiIhoaGZmZmaZkZZpZmZmZpYRERERkRERERERERERERERERERERERERERERGIiIhohoiIiIiIaIiIiIiIiGZoZmZmZmaXkZlpGWZmZhkRERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmaXkZmZmWlpZhERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIZohmZmZmaWEZmZmZlpmRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiGZoZmaWGZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZ2GZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhoiIiIiIhoZmZmmRGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmlxGZmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIhoZmZmdxmRmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdhmRmZmZERERERERkRkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmdpmRmZmZERERERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmdpkRmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZEREREREREZkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZmZmlpkZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIaGZmZml5kZmZmZGREREREREZEZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIhoZmZmZmZmmZmZmZmZGRERERERERGZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIhmZmaGZ2mZmZmZmZmRERFmFhERaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIgzM4iIiIiIiGhoaGaWmZmZmZmZmRZhFmZhFmaZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIM4OIiIiIiIiIaGaXmZmZmZmZZhZmZmZmFmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIg4iIiIiIiIiIaGaXmZmZmZmWZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiGaZmZmWlmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZaWZmZmZmZmZmZmZmZmaWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiHaZmWmWZmlmZmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZaZmWlmZmZmZmZmYWERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZmZkZZmZmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlpFmZmZmYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJiZmZmZmZkZkZlplmlmYWYRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiIiJiZmZmZmZkZkZkZkRkWEWERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI3Y2IiIiIiJiZmZmZmZkRkZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiI2IiIiIiGhpaZmZmZmZkRmZkZkRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmiGZpaZmZmZmRkRmZkZmRERERERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZpaZmZmZmRmRmZkZGRERERGRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZpaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIhoiIiIiIiIiIiIZoaJaZmZmZmRGZmZmZGREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZmZGZmZmZEREREREZERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZGZmZmZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIaJaZmZmZGZmZmZaZEREREZERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZnaZmZmZGZmWlmYWERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIaIiGZnaZmWlpaZZmlmYZERERERkRERERERERERERERERERERERERERGIiIiIiIiIiIiIaIiIiIiIiIiIaIaGZmaZZmZmZmZmZmYRERERERkRERERERERERERERERERERERERERGIiIhohoiIiIiIloaIiIiIiIhoaGZmZmaZkZZpZmZmZpYRERERkRERERERERERERERERERERERERERERGIiIhohoiIiIiIaIiIiIiIiGZoZmZmZmaXkZlpGWZmZhkRERERkRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmaXkZmZmWlpZhERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIZohmZmZmaWEZmZmZlpmRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiGZoZmaWGZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZ2GZGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIhoiIiIiIhoZmZmmRGZmZmZGRERERERGRERERERERERERERERERERERERERERGIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmlxGZmZmZERERERERkRERERERERERERERERERERERERERERGIiIiIiIhoiIiIiIiIiIiIiIiIiIhoZmZmdxmRmZmZERERERERkRERERERERERERERERERERERERERERE="}},"sprites.background.stage":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAAAuIu4i4u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiIiIuLuLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIuIi4u7u7u7u7u7u7u7u7u7u7u4i7u4iIiIiIiLi7u7uLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuIuIi4u7u7u7u7u7u7u4u4u7u7iLu7iIiIiIiIu7uIiLiLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLuIuIy4u7u7u7u7u7u7i4i7u7uIu7uIiIiIiLi7i4iIiLiLiLu7u7u7u7u7u7uLiIiIiIiIiIiIiIiIiLuIuI+Iu7u7u7u7u7uIiLu7i4i7u4iIiIiIuIuIiIiIuLuLiIuIiIiIiIiIiLi7u7uIiIiIiIiIiIiIiLiIuIuI+7u7u7u7u4iIu7uLiLu7iIiIiIi7iIiIiIi4u7uIuLu7u7uLiIiIiIiIiIiIiIiIu7u7u4iIiLiLuIuI+7u7u7u7iIi7u4iIu7uIiIiIiIiIiIiIiIi7u4uIu7u7u7u7u7uLiIiIiIiIuLuLiIiIu7u7u7iLuIuM+7u7u7uIiLu7iIi7u4iIiIiIiIiIiIyIyLu7u4i4u7uIiIi7u7u7u7uLiIiIiIi7u7uLiIiIuIiLiIuM+7u7i4iIu4uIiLi7iIiIiIiIiIiIiIzIu7uLiLi7v/v7u4iIiIi7u7u7u4uIiIiIiLi7u4u4u4i7iIuMu7uLiLi7iIiIuIuIiIiIiIiIiIiIjMj7iLu7u7u///////u7iIiIiIiIu7u7iIiIiIiIiLu7rsi7iIuMuIuIuIiIiIi4iIiIiIiIiIiIiIiMjMiIu7u////////////7+4uIiIiIiIiIu4iIiIiIiIi4rsi7iIuMuMiIiIiIiIiIiIiIiIiIiIiIiIiMyIi4u7+///////////////v7i4iIiIiIiIiIiIiIiIi4rsi7iIuMuMiIiIiIiIiIiIiIiIiIiIiIiIzIyIi7u7//////////////////+7uIiLi7iIiIiIiIiIi7rsi4iIiMuMiIiIiIiIiIiIiIiIiIiIiIjIzIiLi7v/////////////////////r7iIiIu4uIiIiIiIivrsi4iIiMuMiIiIiIiIiIiIiIiIiIiIiIjMiMuLu/v////////////////////+76+4uIiLi7iIiIiLivrsi4iIiMuMiIiIiIiIiIiIiIiIiIiIiMyMyI+7u//////////////////////+/u7vuLiIiIu4iIuLuu7si4iIiMuMiIiIiIiIiIiIiIiIiIiIyIyIz4u7+//////////////////////+/u7u77i4iIiLu7u67u7si4iIiMuMiIiIiIiIiIiIiIiIiIiIzIjMj7v7///////////////////////+/u7u7u+4uIiIi7r67u7si4iIiMuMiIiIiIiIiIiIiIiIiIjIiPjPu7v////////////////////////+7u7u7u7vuLiIi7ru7u7si4iIiMuMiIiIiIiIiIiIi7iIiIiLiM+Pu/v////////////////////////+7u7u7u7u77u7uvru7u7si4iIiMuMiIiIiIiIiIiLiIiIiIuI+I+7+/////////////////////////7+7u7u7u7u7u+67u7u7u7si4iIiMuIiIiIiIiIiIuIuIiIi4j4z7u7///////////////////////////+7u7u7u7u7u7u7u7u7u7si4iIiMuIiIiIiIiIi4i4iIiLi7jPj7v7///////////////////////////+7u7u7u7u7u7u7u7u7u7siIiIiIuIiIiIiIiLi7iIiIiLuPjPu/v////////////////////////////+/u7u7u7u7u7u7u7u7u7siIiIiIuIiIiIiIuLuIiIiIu4+M+7u//////////////////////////////+/u7u7u7u7u7u7u7u7u7siIiIiIuIuIiIi4u4uIiIi4u4z4+7+//////////////////////////////+/u7u7u7u7u7u7u7u7u7siIiIiIuIuIiLi7i4iIiIi7j4z7v7///////////////////////////////+/u7u7u7u7u7u7u7u7u7siIiIiIuLiIiLuLiIiIiLuPjPu7v////////////////////////////////+/u7u7u7u7u7u7u7u7u7siIi4iIuLi7u7uIiIiIuLuM+Pu/v////////////////////////////////+7u7u7u7u7u7u7u7u7u7siIi4iIuLi7u4iIiIi4u4y4+7+/////////////////////////////////7+7u7u7u7u7u7u7u7u7u7si4i4iIuLi7iIiIiIi7j4j7u7//////////////////////////////////7+7u7u7u7u7u7u7u7u7u7si4i7iIu4i7iIiIiLuLiPu7v///////////////////////////////////7+7u7u7u7u7u7u7u7u7u7si4iLiIu4i7iIiIuLuIuLu/v//////////////////////////7+7u7u7///+7u7u7u7u7u7u7u7u7u7si4iLiIi4i7iIi4u4i4u7+////////////////////////7+7u7u7u/v////+7u7u7u7u7u7u7u7u7u7si7iLuIi4i7u7u7iLi7v7/////////////////////7+7u7u7u7v////////+7u7u7u7u7u7u7u7u7u7siLiIuIu4i7u/uIuLu/v///////////////////+7u7u7u7v////////////+7u7u7u7u7u7u7u7u7u7siLiIu4u4i4u8iIu7u/////////////////+7u7u7u7v////////////////+7u7u7u7u7u7u7u7u7u7viLuIu4u4i4u8i7u7//////////////+7u7u7u7v///////////////////767u7u7u9vdvbu7u7u7u7viIuIi4uIi4i/u/v///////////+7u7u7u7v/////////////////v7u7u7r67u7u7293d3b27u7u7u7vuIu4i4uIi4u/+/////////+7u7u7u/v//////////////7+7u7u7u7u7u7u67u7u73d3d3d27u7u7u7suIi4i7uIi4v///////+/u/v/////////////////u7u7u7u7u7u7u7u7u7u67u7vb3d3d3d29u7u7u7si4i4i7uIi4v//////////////////////7+7u7u7u///v7u7u7u7u7u7u7u67u7vd3d3d3d3du7u7u7si4i7iLuIi4v//////////////////7u7u7u7u/v//7u7u7u7u7u7u7u7u7u67u7vd3d3d3d3du7u7u7si7iLiLiIi4v/////////////v7u7u7u7u/v//7+7u7u7u7u7u7u7u7u7u7u67u9vd3d3d3d3dvbu7u7vi7iLiLiIi8v/////////v7u7u7u7u/v//7+7u7u7u7u7u7u7u7u7u7u7u7r67u9vd3d3d3d3dvbu7u7vuLiLuLiIi/v/////v7u7u7u7u/v//7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u67u93d3d3d3d3d3bu7u7vuLiLuLiIi/v/u7u7u7u7u///v7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uIuK+u93d3d3d3d3d3bu7u7vi7uLuLuIi/u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uLiIiIuK+293d3d3d3d3d3b27u7si7u7uLu4i7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7i4iIiIi7u67293d3d3d3d3d3b27u7si4u7uIu4i7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u4uIiIiIu7u7u67293d3d3d3d3d3b27u7siIu8uIi7i7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uLiIiIuLu7u7u7u673d3d3d3d3d3d3d27u7suIvIu4i7y7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7iIiIiLi7u7u7u7u7uK73d3d3d3d3d3d3d27u7vuIuIv4i7y7u7u7u7u7u7u7u7u7u7u7u7u7u7u7i4iIiIi7u7u7u7u7u4iIuK+3d3d3d3d3d3d3d27u7viLiLv4iL+7u7u7u7u7u7u7u7u7u7u7u7u7u4uIiIi7u7u7u7u7u7uLiIiIiLe3d3d3d3d3d3d3d29u7si7iL+7iLv7u7u7u7u7u7u7u7u7u7u7u7uIiIi7u7u7u7u7u7u7u4iIiIiIiLe3d3d3d3d3d3d3d29u7si7iLy7iLv7u7u7u7u7u7u7u7u7u7u7i7i7u7u7u7u7u7u7u7uIiIiIiIiIiLe3d3d3d3d3d3d3d29u7si4i7yL/Lu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uLiIiIiIiIiIiIuLe3d3d3d3d3d3d3d29u7si4i7iL//u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uLiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3du7siIi4i/+/u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7iIiIiIiIiIiIiIi4u7u7r7d3d3d3d3d3d3d3d3du7siIu4i/u7u7u7u7u7u7u7u7u7u7u7u7u7u7iIiIiIiIiIiIuLu7u7u7u7uIuLd3d3d3d3d3d3d3d3du7suIu4i8u7u7u7u7u7u7u7u7u7u7u7u7iIiIiIiIiIi4u7u7u7u7u4iIiIiIuLe3d3d3d3d3d3d3d3du7suIuIi8u/u7u7u7u7u7u7u7u7u7iIiIiIiIiIi7u7u7u7u7iIiIiIiIiIiIuLe3d3d3d3d3d3d3d3du7suIuIi4u/u7u7u7u7u7u7uIiIiIiIiIiLu7u7u7u7u7iIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3du7vuIuIi4u/u7u7u7u4uIiIiIiIiIuLu7u7u7u7uLiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbvuIuIuIu/u7u7uLiIiIiIi4u7u7u7u7u7uIiIiIiIiIiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3dvbviIuIuIu/u7u7u7u7u7u7u7u7u7u4iIiIiIiIiIiIiIiIiIiLi7u7u7u7u7t7d3d3d3d3d3d3d3d3dvbviLuIuIu/u7u7u7u7u7u7u7i4iIiIiIiIiIiIiIiIi4u7u7u7u7u7u7i4iIt7d3d3d3d3d3d3d3d3dvbviLuIuIu/u7u7u7i4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3dvbsiLiIuIv7u7i4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3dvbsi7iIuIv7u7i4iIiIiIiIi7u7u7u7uIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi7iIuIvLu7u7u7u7u7u7u7u4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi7iIuIvLu7u7u7i4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi7iIuIvIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsi4iIiIvLuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsi4iIiMvLuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIt7d3d3d3d3d3d3d3d3dvbsi4iIiMvLuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsi4iIiMvLuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi4iIiMvLuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi4iIjMvLuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi4iIjMvLuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7e3d3d3d3d3d3d3d3dvbsi4iIjMvLuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsi4iIjMvLuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsi4jIjMvPuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7e3d3d3d3d3d3d3d3dvbsiIjIjMvPuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsiIjIjMvPuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsiIjIjMvPuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsiIjIjMvPuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsiIjIjMvPuLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIt7d3d3d3d3d3d3d3d3dvbsiIj4jMvPuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsiIj4iMvPuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIu7d3d3d3d3d3d3d3d3dvbsi4j4iMvPuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi4j7iMvIuIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi4jLiM+/u7u7u7u4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3dvbsi4jPiM+/u7i4iIiLu7u7u7u7u7u7u7iIiIiIiIiIiIiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3dvbsi7jPuM+/uLiIiIiIiIiIiIiIi4u7u7u7u7u7uIiIiIiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3dvbsiLiMuI+/u7iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLu7u7u7u7u7u7u7t7d3d3d3d3d3d3d3d3dvbsiLiMu4+/u7u7u7iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiLu7u7u7t7d3d3d3d3d3d3d3d3dvbviLuM+4+/u7u7u7u7u7iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLd3d3d3d3d3d3d3d3du7viIuMy8+/u7u7u7u7u7u7u7u7uIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3du7vuIu4y8u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiIiIiIiIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3du7suMi4y/u7u7u7uLiIi4u7u7u7u7u7u7u7u7u7u7u7u7i4iIiIiIiIiIiIiIuLe3d3d3d3d3d3d3d3du7si4i4j/+/u7u7u7u7uIiIiIiIi4u7u7u7u7u7u7u7u7u7u7u7u7u7u7u4iIuLe3d3d3d3d3d3d3d3du7si4i7jL//u7u7u7u7u7u7uIiIiIiIiIiLi7u7u7u7u7u7u7u7u7u7u7u7u7uLd3d3d3d3d3d3d3d3du7si7iLyL/Lu7u7u7u7u7u7u7u7u7iIiIiIiIiIiIiLi7u7u7u7u7u7u7u7u7r7b3d3d3d3d3d3d3d29u7vi7iLy7iLv7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiIiIiIiIuLu7u7u7u7u7u7b3d3d3d3d3d3d3d29u7viLiL+7iLv7u7u7u7u7u7u7u7u7u7u7u7u7u7u7i4iIiIiIiIiIiLi7u7u7u7b3d3d3d3d3d3d3d29u7vuLiLv4iL+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiIiIiIiIu7b3d3d3d3d3d3d3d29u7vuIuIv4i7y7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u4u7u7u7u7u7iIiIiIiIiK+3d3d3d3d3d3d3d27u7vuIv4u4i7y7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uLiIiIu7u7u7u7u4iIiK+3d3d3d3d3d3d3d27u7suIu/uIi7i7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiLu7u7u7uK+3d3d3d3d3d3d3d27u7si4i7uIu4i7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiLi7uK7293d3d3d3d3d3b27u7si7iLiLu4i7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIuK7293d3d3d3d3d3b27u7vi7i7iLuIi/v//7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uIu67293d3d3d3d3d3b27u7vu4i7iLiIi/v//////7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u67u93d3d3d3d3d3bu7u7suIi4j7iIi/v/////////v7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u6+u93d3d3d3d3d3bu7u7siIu4y7iIi8v/////////////u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u6+u9vd3d3d3d3dvbu7u7suIu4y4iIi4v///////////+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u67u9vd3d3d3d3dvbu7u7suIuIy4uIi4v/////////////v7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7r67u7vd3d3d3d3du7u7u7suIuIy4+4i4v///////////////+/u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u67u7vd3d3d3d3du7u7u7vuIuIy4+4i4v//////////////////7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u67u7vb3d3d3d29u7u7u7vuIuIuI+4i4u/+////////////////////7u7u7u7u7u7u7u7u7u7u7u7u7u67u7u73d3d3d27u7u7u7viIuIuM+4i4i/u/v///////+/u7v//////////7u7u7u7u7u7u7u7u7u7u7u67u7u7293d3b27u7u7u7viLuIuM+4i4u8i7u7//////////+7u7u7/////////7u7u7u7u7u7u7u7u7u67u7u7u9vdvbu7u7u7u7viLuIuM+4i4u8iIj7u////////////7+7u7v7////////v7u7u7u7u7u7u7r67u7u7u7u7u7u7u7u7u7siLiIuM+4i7u/uIuIz/v/////////////v7u7u7v///////+/u7v7u7u7u7r67u7u7u7u7u7u7u7u7u7si7iIuM+4i7u7u7iLiM/7////////////////u7u7u/v///////////+7u/v+7u7u7u7u7u7u7u7u7u7si7iIuM+Ii7iIi4u4iMjP+/////////////////+/u7u7u///////////v/v+7u7u7u7u7u7u7u7u7u7si7iIuM+Ii7iIiIuLuIjPj/v//////////////////7+7u7u7///////////+7u7u7u7u7u7u7u7u7u7si7iIuM+Ii7iIiIiLuLiIz4///////////////////////7u7u7v////////+7u7u7u7u7u7u7u7u7u7si4iIiM+Li7iIiIiIi7i4yM+7////////////////////////u7u7+//////+7u7u7u7u7u7u7u7u7u7si4iIiM+Li7u4iIiIi4u4iMjP+/////////////////////////+7u/v///7+7u7u7u7u7u7u7u7u7u7si4iIiM+Li7u7uIiIiIuLuIjPj/v///////////////////////////////7+7u7u7u7u7u7u7u7u7u7si4iIiM+LiIiLuLiIiIiLuLjIz7v///////////////////////////////7+7u7u7u7u7u7u7u7u7u7si4iIiM+IuIiLi7i4iIiIi7i4yM/7///////////////////////////////+7u7u7u7u7u7u7u7u7u7si4iIiI+IuIiIi4u4uIiIi4u4iM+P+//////////////////////////////+/u7u7u7u7u7u7u7u7u7si4iIiI+IiIiIiIuLuIiIiIu4uMjPu//////////////////////////////+/u7u7u7u7u7u7u7u7u7si4iIiI+IiIiIiIiLi7iIiIiLuLjIz/v////////////////////////////+/u7u7u7u7u7u7u7u7u7si4iIiIuIiIiIiIiIi4i4iIiLi7iIz4/7///////////////////////////+/u7u7u7u7u7u7u7u7u7si4iIiIuIiIiIiIiIiIuIuIiIi4i4iM+7///////////////////////////+/u7u7u7u7u7u7u7u7u7siIiIiIuIiIiIiIiIiIiLiIiIiIuIuMuP+//////////////////////////+7u7u7u7u7u+67u7u7u7siIiIiIuIiIiIiIiIiIiIi7iIiIjPiIjLj/v////////////////////////+7u7u7u7u77u7uvru7u7siIiIiIuIiIiIiIiIiIiIiIiIiIiIzLiIz7v///////////////////////7+7u7u7u7vuLiIi7ru7u7siIiIiIuIiIiIiIiIiIiIiIiIiIiIiMyMi7v7///////////////////////+7u7u7u+4uIiIi7r67u7siIiIiIuIiIiIiIiIiIiIiIiIiIiIiIjMj4u7+//////////////////////+7u7u77i4iIiLu7u67u7siIi4iIuIiIiIiIiIiIiIiIiIiIiIiIiIzI+7u//////////////////////+/u7vuLiIiIu4iIuLuu7siIi4iIuIiIiIiIiIiIiIiIiIiIiIiIiIiM+Pu/v////////////////////+/6+4uIiLi7iIiIiLivrsi4i4iIuIiIiIiIiIiIiIiIiIiIiIiIiIiIjPj7v/////////////////////v7iIiIu4uIiIiIiIivrsi4i7iIu4iIiIiIiIiIiIiIiIiIiIiIiIiIiIz4+7//////////////////+7uIiLi7iIiIiIiIiIi7rsi4iLiIu4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiM+7+///////////////v7i4iIiIiIiIiIiIiIiIi4rsi4iLiIu4uIuIiIiIi4iIiIiIiIiIiIiIiIiIiIjPu////////////7+4uIiIiIiIiIu4iIiIiIiIi4rsi7iLuIu7uLiLi7iIiIuIuIiIiIiIiIiIiIiIi7iLu7u7u///////u7iIiIiIiIu7u7iIiIiIiIiLu7rsiLiIuIu7u7i4iIu4uIiLi7iIiIiIiIiIiIiIiIu7uLiLi7v/v7u4iIiIi7u7u7u4uIiIiIiLi7u4u4u4iLiIu4u7u7u7uIiLu7iIi7u4iIiIiIiIiIiIiIiLu7u4i4u7uIiIi7u7u7u7uLiIiIiIi7u7uLiIiIuLiLuIu4u7u7u7u7iIi7u4iIu7uIiIiIiIiIiIiIiIi7u4uIu7u7u7u7u7uLiIiIiIiIuLuLiIiIu7u7u7iIuIi4u7u7u7u7u4iIu7uLiLu7iIiIiIi7iIiIiIi4u7uIuLu7u7uLiIiIiIiIiIiIiIiIu7u7u4iIiLuIu4i4u7u7u7u7u7uIiLu7i4i7u4iIiIiIuIuIiIiIuLuLiIuIiIiIiIiIiLi7u7uIiIiIiIiIiIiIiIuIi4i7u7u7u7u7u7u7i4i7u7uIu7uIiIiIiLi7i4iIiLiLiLu7u7u7u7u7u7uLiIiIiIiIiIiIiIiIiIi4i4i7u7u7u7u7u7u7u4u4u7u7iLu7iIiIiIiIu7uIiLiLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi4i7i7u7u7u7u7u7u7u7u7u7u7u4i7u4iIiIiIiLi7u7uLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi7iLi7u7u7u7u7u7u7u7u7u7u7u7u7u7uIiIiIiIiIuLuLiLiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI="}},"sprites.background.starryclouds":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAAAzMzMzMzMzMxExOlWlERERERExk5mZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzExERoaU6ERERERERM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMzMzHRERMRoRERGqGqGqM5OZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMzEREREREREaFVqqpVM5M5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzMzEREREREREaFVpVpVpZMzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzPTHREREREREaFVVVVVpTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPdHREREREREaFVVVVVpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMx0R3RERkREREaFTVVVVo5qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMz0xERER0RmRkREapTVVVVM6qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzExERERERkRERoVVZVVVVVaWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzHREREREREREROlVVVVVVVVWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzERERERERERERWlVVVVVVVZkzMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERoao6VVU1M5k5k5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERERGhU1WlM5mZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzHRERERERERERERERWlWjM5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzExERERERERERERERoaWqWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREzMzMz0xERERGjEREREREREaqTWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMx0REREzGhERERkREaGZmZmZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMdERFapToRkZkRERE6mZmZmZkzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREaFTVaURERkRERGqqpOZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREVNVVTMREREREaFTM5qZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREaFTVaURERERETpVNZqZMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMxMRERFapToRERERoVpVNZqZM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREREzGhERqqqqqlVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGRGZEREREREREREREREzMzMzMzMRERGjERGhU1WjOlVVpZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZERERGREREREREREREREzMzMzMzPT3RERERGhVVVVVVVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzHRERERGhVVVVVVVVNao6M5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzERERERGhWlVVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzPTERERERERqlVVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTERERERERoTpVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTEREZERERETpVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEZGZEREREVqZVVVVVVWjk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEREZERERoVOZVVVVVaM6mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZM5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPTERERERERoVVVM1VVVZOZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzERERMRoRoVWlqlNVM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzHRERoaU6Eaqqo1o1k5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMz0xExOlWlEREREaqTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzMx2hVVUzERERETGTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzMxExOlWlERERERE5k5mZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzExERoaU6ERERETGZM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMzMzHRERMRoRERGqOqOqM5OZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMzEREREREREaFVqqpVM5M5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzMzEREREREREaFVpVpVpZMzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzPTHREREREREaFVVVVVpTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPdHREREREREaFVVVVVpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMx0R3RERkREREaFTVVVVo5qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMz0xERER0RmRkREapTVVVVM6qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzExERERERkRERoVVZVVVVVaWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzHREREREREREROlVVVVVVVVWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzERERERERERERWlVVVVVVVZkzMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERoao6VVU1M5k5k5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERERGhU1WlM5mZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzHRERERERERERERExWlWjM5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzExERERERERERERERoaWqWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREzMzMz0xERERGjEREREREREaqTWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMx0REREzGhERERkREaGZmZmZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMdERFapToRkZkRERE6mZmZmZkzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREaFTVaURERkRERGqqpOZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREVNVVTMREREREaFTM5qZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREaFTVaURERERETpVNZqZMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMxMRERFapToRERERoVpVNZqZM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREREzGhERqqqqqlVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGRGZEREREREREREREREzMzMzMzMRERGjERGhU1WjOlVVpZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZERERGREREREREREREREzMzMzMzPT3RERERGhVVVVVVVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzHRERERGhVVVVVVVVNao6M5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzERERERGhWlVVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzPTERERERERqlVVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTERERERERoTpVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTEREZERERETpVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEZGZEREREVqZVVVVVVWjk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEREZERERoVOZVVVVVaM6mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZM5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPTERERERERoVVVM1VVVZOZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzERERMRoRoVWlqlNVM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzHRERoaU6EaqqoVo1k5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMz0xExOlWlEREREaqTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzMx2hVVUzERERERGTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzMxExOlWlERERERE5k5mZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzExERoaU6ERERERGZM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMzMzHRERMRoRERGqGqGqM5OZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMzEREREREREaFVqqpVM5M5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzMzEREREREREaFVpVpVpZMzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzPTHREREREREaFVVVVVpTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPdHREREREREaFVVVVVpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMx0R3RERkREREaFTVVVVo5qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMz0xERER0RmRkREapTVVVVM6qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzExERERERkRERoVVZVVVVVaWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzHREREREREREROlVVVVVVVVWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzERERERERERERWlVVVVVVVZkzMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERoao6VVU1M5k5k5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERERGhU1WlM5mZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzHRERERERERERERExWlWjM5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzExERERERERERERERo6WqWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREzMzMz0xERERGjEREREREREaqTWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMx0REREzGhERERkREaGZmZmZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMdERFapToRkZkRERE6mZmZmZkzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREaFTVaURERkRERGqqpOZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREVNVVTMREREREaFTM5qZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREaFTVaURERERETpVNZqZMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMxMRERFapToRERERoVpVNZqZM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREREzGhERqqqqqlVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGRGZEREREREREREREREzMzMzMzMRERGjERGhU1WjOlVVpZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZERERGREREREREREREREzMzMzMzPT3RERERGhVVVVVVVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzHRERERGhVVVVVVVVNao6M5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzERERERGhWlVVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzPTERERERERqlVVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTERERERERoTpVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTEREZERERETpVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEZGZEREREVqZVVVVVVWjk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEREZERERoVOZVVVVVaM6mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZM5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPTERERERERoVVVM1VVVZOZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzERERMRoRoVWlqlNVM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzHRERoaU6EaqqoVo1k5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMz0xExOlWlEREREaqTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzMx2hVVUzERERERGTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzMxExOlWlERERERExk5mZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzExERoaU6ERERERGRM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMzMzHRERMRoRERGqGqGqM5OZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMzEREREREREaFVqqpVM5M5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzMzEREREREREaFVpVpVpZMzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMzPTHREREREREaFVVVVVpTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPdHREREREREaFVVVVVpZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMx0R3RERkREREaFTVVVVo5qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMz0xERER0RmRkREapTVVVVM6qZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzExERERERkRERoVVZVVVVVaWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzHREREREREREROlVVVVVVVVWamZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzERERERERERERWlVVVVVVVZkzMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERoao6VVU1M5k5k5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzERERERERERERETGjU1WlM5mZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzHRERERERERERERExWlWjM5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzExERERERERERERERoaWqWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREzMzMz0xERERGjEREREREREaqTWZWZmTOTmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREzMzMzMx0REREzGhERERkREaGZmZmZmTkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMzMdERFapToRkZkRERE6mZmZmZkzk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREaFTVaURERkRERGqqpOZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREVNVVTMREREREaFTM5qZmZk5k5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREzMzMzMxMREaFTVaURERERETpVNZqZMzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzMxMRERFapToRERERoVpVNZqZM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREzMzMzM9MREREzGhERqqqqqlVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGRGZEREREREREREREREzMzMzMzMRERGjERGhU1WjOlVVpZqZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZERERGREREREREREREREzMzMzMzPT3RERERGhVVVVVVVVpaozk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzHRERERGhVVVVVVVVNao6M5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMzERERERGhWlVVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzPTERERERERqlVVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTERERERERoTpVVVVVVVVVNZOZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREREREREREREREREREzMzMzMzMTEREZERERETpVVVVVVVVVM5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEZGZEREREVqZVVVVVVWjk5mZmZmZmZmZmZmZmZmZmZmZmZmZmZkZEREREREREREREREREREzMzMzMzMTEREZERERoVOZVVVVVaM6mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMTERERERERoVVVVVVVVZM5MzMzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREREREREREREREREzMzMzMzPTERERERERoVVVM1VVVZOZM5kzmZmZmZmZmZmZmZmZmZmZmZmZmZmZmREREREREREREREREREzMzMzMzMzERERMRoRoVWlqlNVM5OZmZkzmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzHRERoaU6EaqqoVo1k5mZmTmTmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMz0xExOlWlEREREaqTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGREREREREREREREREREzMzMzMzMzMx2hVVUzERERERGTmZmZmTOZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRERERERERERERERERE="}},"sprites.food":{"kind":5,"retType":""},"sprites.food.smallBurger":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAO4OiO7uAADsu+t3xusOwExEuy5mvg7AREVE7nLoy7xERETrYsjLTERERORizMRMREVE5HLsxEtERETkcujES0VEVORy6ORLRERE5GLs5EtERETkYuzku1REROtyzOSwRFRE7mLo5LBLRLQuxr4OAOxL63bM6w4AAOwOiO7uAA=="},"pyQName":"sprites.food.small_burger"},"sprites.food.smallApple":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMDMzAwAAADA7O7u7gIAAOzu7u7uLgAA7u4iIuLuAuDuLiIiIuIC4O4iIiIiIi7g7i4iIiIiLs7MLCIiIiLkfGcsIiIiIuR37iIiIiIi5ODiRCIiIkLi4CJVJCIiQg4ALlQkIiIkDgAuIiIiROIAAOAuIiLiDgAAAODu7g4AAA=="},"pyQName":"sprites.food.small_apple"},"sprites.food.smallLemon":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABEC7DMzAAAAFS0S91EzAAAVFVdRdVEDABAVVVVVdXEAEBRVVVFVUQMVFVVVV1FTQxUEVVV1VVEy1QRVVVV3UTEVFFVVVVNRMRUVVVVVU1ExEAVVVVV1UTLQBVRVVVVTcsAVBFVVVVdtABAVRVVVVW1AABEVVVFXUQAAABERMtMBA=="},"pyQName":"sprites.food.small_lemon"},"sprites.food.smallDrumstick":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAIiIiAAAAACCyuysCAAAAskREtOsAAABCREREuw4AAEtERES7DgAAS0RERLTrAABLTUREtOQAAEtNRES05AAAS9RERLvrAACwRE1Eu+4AAAC7RLTr7gAAAAC77u6+ywwAAAAAANsRwQAAAAAAsNHLAAAAAACw0QwAAAAAAAC7AA=="},"pyQName":"sprites.food.small_drumstick"},"sprites.food.smallHam":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAiIu4OAAAAItPd3eMAACATMTPTPQ4AMtE9MzMT4yATM9MzMxPjIN0zExEz0eMyMTMxE93d4zIxMxExMx3jMj3TMzMzE+My3T0zMzMd6yDTMTMzHbHu4DITERE9u+4A7jszu7vr7gAAvkRERO4OAACwS0S07gAAAAC77u4AAA=="},"pyQName":"sprites.food.small_ham"},"sprites.food.smallPizza":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAC7RAAAAAAAu11NAAAAALsjU00AAAC7XSJSTQAAu11XI10EALA9MlVV1QS7SyUiVVfVBEu7NTJVVUUAS7RVVSNTTQBLtFRXIlJNALBES1UjU00AAEvkVFXVBAAAsETuVd0EAAAAS+Te7QAAAACw5O5OAAAAAADu7gQAAA=="},"pyQName":"sprites.food.small_pizza"},"sprites.food.smallDonut":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAC7q6oAAAAAuzMzow4AALAzMzMz6gAA2z0zMzPqDrDdMzMzM7oOsD0zszPTug7bPTOqM9NKDtszozoz00oO2zOjMzOtRA47MzszM61EDjozMzPTSrQOOjMzM61E5ACgMzPdSkTuAKA6M6pE5A4AAKqqRETuAAAAALu77gAAAA=="},"pyQName":"sprites.food.small_donut"},"sprites.food.smallCake":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAALC7u7sLAAAAsLM9MwsAAAA7s9XTCwAAADuz1VOzAACwM71VU70AALAzvVVTtQAAOzO9XTM1CwA7Mz1bPdULsO4z01s1VQvgIz7TWzVVC+siPtNaNVWzO+4z09o9Vb07MzPT2r3dvbA6M93avd2tAKA6Pdq9O6sAAKCqqqqqCg=="},"pyQName":"sprites.food.small_cake"},"sprites.food.smallIceCream":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAEREAAAAM0tEXVUEADARvdTdVUUA0xERvVVdRTDdHRHRW9VFExHRERG91QQTEREdEbHdBNsREdER0dsEM90R0RERSwDT0R0RERFLAB0RHREdEb0AHRHRER0RPQATHRERHdEDABMzG9E7MwAAMDEwMwsAAAAAMwAAAAAAAA=="},"pyQName":"sprites.food.small_ice_cream"},"sprites.food.smallStrawberry":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADu7u7uDgAA7iIiIu7OAOAiREQk4s4ALkJFIiLuwgAuRCIiIiLOAC4kIkIi4s6AKGJmJiIkzGbod3cmIiLOYIZ3ZyJC4gwAZncmQuLuDABgZyIiIu4MAHZ3Zy7izgBgZ2h35+4MAIAIhnZ3zAAAAACAYGYGAAAAAAAAAAAAAA=="},"pyQName":"sprites.food.small_strawberry"},"sprites.food.smallCherries":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAODuDAAAAAAALiLCAAAAAOBC4i4MAAAA4CXi7uIAAADgJCLiwgAAAOAiIuLCAAAAyC4iIu4AAABoLCLizswAAGjI7C4i4gxghwDgQiLuzmCHAOAlIu7CdggA4CQi4sJ2iGbIIiLiwnZ2d2YsIu7CdoiIiMgiIgyGCAAAAO7MAA=="},"pyQName":"sprites.food.small_cherries"},"sprites.food.smallTaco":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADg7u5OAAAA4E5VVVUEAABeVczsTkUA4GWGzszuRABeImfoVVXl4GQiZ1VFVeXgZYdYRVVV5E52hlVVRVUOXiJWVFRV5QBeIlRVVVXkAF5nVVRFVQ4A4EZVVVXlAADgRlVFVeQAAABORVVVDgAAAOBUVeUAAAAAAEBEBAAAAA=="},"pyQName":"sprites.food.small_taco"},"sprites.food.bigBurger":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAAO7/AID4//8PAAAAAAAAAO67y+94h75rxg8AAAAAAO5mZrb7dmf/vmb8AAAAAOBrtmZmuy9i+P9t9gAAAAC+tru7ZrbsYob/3WsPAADAu7tEtGtm+yJ2/t+0DwAAvERbS0S0Zvsidu7fvfsAAExEtERERGbGInf/T037AMBERERERERrtixn/+9N6wDARERERLRLZLYsh+//TbsPwERLRERbS7S2LPbu/k20D0y0tUREu0S0tiyG7/5NtA9MtEtERERERLssZu/+TbQPTERERERERES7LHbn/020D0xEREREREREuyx35/9NtA9MRERERERERLQsd+buTUQPRkREu0RERES0LHfm701EDEa7RFtLREREtCx35u9NRAxGW0u0RERERLQsd+juTUQMRrRERERERES0LGfo7k1EDEZEREREtEtEtCxm7v5NRAxgRERLRLS1RLQsZu/+TUQOYES0tUREu0S0LHb//k1EDmBEREtEREREtCx37v9N5AAARkRERERERMQiZ+5PTeQAAEZEtEtERET0Ivfu3kvkAACwRLS1REREy3L37t5EDgAAAEtEu0RERCxi/++9RA4AAABgRERERLQsZv++S+QAAAAAAOZERLT7dob/u2TuAAAAAAAA7rvL73hnvmbmDgAAAAAAAADu/wCI+P/vDgAAAA=="},"pyQName":"sprites.food.big_burger"},"sprites.food.bigDrumstick":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAIiIiAgAAAAAAAAAAAAAAIru7uyICAAAAAAAAAAAAILu7u7u74gAAAAAAAAAAAEJEu0S0u+sOAAAAAAAAACBERERLRLvrDgAAAAAAAABCRERERES0u+4AAAAAAAAAQkREREREtLvuAAAAAAAAsEREREREtES77g4AAAAAALBERERERLRLu+sOAAAAAACwRERERES0u7vrDgAAAAAAS0RERERERLS76w4AAAAAAEtERERERES7tCsOAAAAAABLTUREREREu0Qr4gAAAAAAS91ERERERERLKyIAAAAAAEvdREREREREu7siDgAAAABL1E1ERERERLu7Kw4AAAAAsNRNRERERES0RLsCAAAAALBE3URERERERES06wAAAAAAS0RNRERERES7tOsAAAAAAOBLREREREREtLvrAAAAAAAAvru7RERERLS76wAAAAAAAOC+u0tEtEREu+4AAAAAAAAA4O67RLtLtLvOAAAAAAAAAAAA7u7uu7vu2wwAAAAAAAAAAAAAAO7uzt3NAAAAAAAAAAAAAAAAAADb0cvMAAAAAAAAAAAAAAAAsBERvQwAAAAAAAAAAAAAAAAbEREMAAAAAAAAAAAAAAAAG9EdDAAAAAAAAAAAAAAAANvRywAAAAAAAAAAAAAAAAC7EQwAAAAAAAAAAAAAAAAAsMwAAA=="},"pyQName":"sprites.food.big_drumstick"},"sprites.food.bigHam":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAACAiIiLu7u4AAAAAAAAAACAy3RERERE97gAAAAAAACAyHTEzMzMz3T0OAAAAAAAyER0zMzMzMzPd4wAAAAAgEz3T0TMzMzMz0z0OAAAAMjEzM93dPTMzMzMdDgAAINMxMzMzMz0zMzMzE+0AADIdMzMzMzPdHTEzMxPhAADSMTMzMzMz3dEdMzMTvQ4g0zMzMzMzMxM93TEzHTMOINMzMzMzMzMTM9PR09EzDjIdMzMzMzMz3TETPd3TPQ4yET0zMzMz090d0Tsz09EPMhHRPTMzMz0zM7szMzPRDzLRHT3T3d0zMzMzMzMzEQ8y0dPd3TMzMzMzMzMzMzEPshMz0z0zMzMzMzMzM9OxD77TPdM9MzMzMzMzMzPd4w7uMzEzMzMzMzMzMzMz3fsO4DsTMzMzMzMzMzMz3bP+AODuO90zMzMzMzMzHT37/wAA7u473d3d3d0dET3r//4AAODu7rvTERER0bNm/+8PAAAA4E5Eu7tmZmtmu+7vDwAAAABORLRGtES0u+vu/wAAAAAA4E5ERmRGtGvm6w8AAAAAAADuRERGtERmu+sAAAAAAAAA4E5ERmRGu7sOAAAAAAAAAADgTmRGtLvuAAAAAAAAAAAAAOBOS2TmAAAAAAAAAAAAAAAAvmbmDgAAAAAAAAAAAAAAAODuDgAAAAAAAA=="},"pyQName":"sprites.food.big_ham"},"sprites.food.bigPizza":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAAAAAAAAAAAAAu0REAAAAAAAAAAAAAAAAu10VQQAAAAAAAAAAAAAAS11V0eUAAAAAAAAAAAAARtRdXUHlAAAAAAAAAAAAa4dV1R1dBAAAAAAAAAAAu22HJS4dVA4AAAAAAAAAu11VViLiUlQOAAAAAAAAS+Qu1SUiIt7UTQAAAAAAuz0i4tIlIyLeTe4AAAAAQF0lIiJeJTMi3uUAAAAAsFRVJSMiXlUi4tPlAAAAAEtd1SUzIl5V5T5dBADg7k5dVdVVIuJTVVVVVAQA60vrVFXVVu0+VdVVFdQOAL5DtN5VbYfdVVXVXRVUDgC+NENLVWWHXVVV1V1BRQAAuzQzRN1VVlVVVdVWQUUAALtLM0PUVVVV7lJlh9XlAABLu0QzRF1VJSIuZYcR7QQAu7REM7RUVSIi4lUW0d1NALBLSzNDu1UyIuJV0VTkTgAAu0QzQ7vUMiPiVUFdDgAAALBLRENETi0iPlVN5QAAAAAAvkQ0tOvU7lMV1OQAAAAAAOBLRETrvt1VUdTtAAAAAAAAu0REtE7d1UXU5AAAAAAAALBLRETr1NVFTQ4AAAAAAAAAu0REu0tE1O0OAAAAAAAAAOBOtLvr1E3uAAAAAAAAAAAA7kS0u+7k7gAAAAAAAAAAAODuu+vu7g4AAAAAAAAAAAAA6+7u7u4AAAAAAA=="},"pyQName":"sprites.food.big_pizza"},"sprites.food.bigTaco":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAAAAAAO7u7u7uAAAAAAAAAAAA4O5UVVVVRO4AAAAAAAAA4E5V5e7/5O5UDgAAAAAAQE5VVUTu/+7+TuUAAAAAAERmVuTu5P7v7u/lAAAAAEBVdkbu7u7//v/vVA4AAABUZXdITv7+/v//714OAABAJXJ35k7+//7v/+5ODgAATjJzRIf+/+/uVFVVRQ4A4EQickV35u5UVdXd3d0OAE6GLn5FduZU1U3dVVXdDgBud3dXZGZe1V1VVdVF3Q7gdER3VnTm1V1VVVVVVe0A4HVFZ0Z3Xl1V1VVdVdXtAE5lRWdn59XVVVVUVV3VDgBeZUV3Il5dVVVVVVVVRQ4AXnZEJzNUXVVVVVVFVe0AAG53dybi1VVVVdVVVd0OAABuInfnQtVVXVVV1dVNDgAALjNyZ15dVVVVVVXd7QAAAO4ucmdUXUVV1VXV3Q4AAAAg4mJn1V1V1VVVRe0AAAAA4HZn5tVdVVVV1d3tAAAAAAB4d+bVVVXVVVXdDgAAAAAAeHfm3dVVXV3d7QAAAAAAAGB2591VVd3d3eQAAAAAAABgZ+bdVVXd1N0OAAAAAAAAgHeG3dRV3d3tAAAAAAAAAACIhtTdVdXdDgAAAAAAAAAAAIjY3V3U7QAAAAAAAAAAAAAAQNTd3Q4AAAAAAAAAAAAAAABE7u4AAAAAAAAAAA=="},"pyQName":"sprites.food.big_taco"},"sprites.food.bigCake":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAALC7u7u7u7u7AAAAAAAAAACws1vVO1NVvQAAAAAAAAAA2zNbVbVT3bUAAAAAAAAAsNM9W1W1U1VdCwAAAAAAALDdPVtVNVNVVQsAAAAAAACwPT07VVXTVdULAAAAAAAAOz09u1VVO13VCwAAAAAAsNszPbNVVTtdVb0AAAAAALDTMz2zVVU7VVW9AAAAAACwPTPTs1VVM1VVtQAAAAAA2zMz071VVTVVXbUAAAAAANszM9O9VVU1U1VVCwAAALA9MzPTM1NVvVNVXQsAAACwMzMz0zNbVb1TVV0LAAAAuzMzMzM9W1W1U1VdCwAAADszMzMzPVvVNdtVVbUAALAzMzMzM91bVVXbXVW1AAC7MzMzMzPd21XVO13VtQAAOzMzMzMzPdtV1TtVVbUAADsj7jszMz3bXd07Vd3VC7AzMiK+MzM9u93VM1Xd1QuwM+4i4jMzPaNd1b1d3dULOzPuIuIzMz2jXdW93V1VCzs97iLiMzPdo91dvdvd1b070y4ivjMz06PdXb3b3VW9sDPt7jszM9Oj3d29291VvQCrO90zMzMzvdvdvdvd3a0AAKrT3d0zMz3b3T3b3V2rAAAAqjPd3d3ds93du921owAAAACqOtPdPbO7u7u7M6sAAAAAAKCqO7O7uzMzM7MKAAAAAAAAAKqqqqqqqqqqAA=="},"pyQName":"sprites.food.big_cake"},"sprites.food.bigDonut":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAAAAAu6qqqgAAAAAAAAAAAACwu9Pd3bPuAAAAAAAAAACwO93dbd09uu4AAAAAAAAAO91jNnY4PavrDgAAAAAAsNMzmzh2ONO7uu4AAAAAADs9Y4kzdjjTs7q+DgAAALAzM2M4M2Y70z2r6w4AAAA7NDMzMzMzMzPdo+vrAACwQyUzMzMzMzMjM73q6wAAO0MlMzMzMzMzVDI9uusAADtDNDMzs7szM1QyPbu7DrAzMzPTs6q7MzNE06O0tA6wMzMzPTujOiMzMzNKtLQOYDYz070zqjNCPjMzSrREDmuHM9OzozozQj4zs0q7RA5rhzPTO6ozMyMzM6NEs0QOa4cz0zu6MzMzM9OrRLPkADs2MzO7OzMzM2bdSjRD5AA7MzMzuzMzM2OJPUo0S+QAOzMzMzMzMzOWOD1KNEQOADszMzMzYzgzhjOtRLNEDgCwhjNEM2OHMzPTo0RD5AAAoJY4VDIzdjjTPUo0S+QAAKBjiVQyM2M2M6NEtEQOAAAAOmYjMyMzM6tKREvkAAAAADozMzNCPqtKRLREDgAAAACgMzMzQr5KRERL5AAAAAAAoLrT3SOzRES7RA4AAAAAAACqqqq6S7S7ROQAAAAAAAAA4O5LRLTuS+QOAAAAAAAAAADg7u7uu+sOAAAAAAAAAAAAAADu7u4OAAAAAAAAAA=="},"pyQName":"sprites.food.big_donut"},"sprites.food.bigIceCream":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAAAAAAAAAAABERAAAAAAAAAAAAABARERE1V0EAAAAAAAwszMA1N1EVVXdRQAAAACwE9ERS93dVVRV1V0EAAAAOx3REd27XVVFVVXdRQAAANsd0R3R3VtVVVRV1U0AADMzHREdEd2xVVVFVVVNALPd3RMR3RHdEVtVVVRVRTDbEdHREdER3R2xVVVF1UWw3RERHR0RHdEd0VtVRd0EsN0REdHREdER3RFbVdXUBDDRHRHR0R0RHRHdsVXV1AQTER0R0dHdEdERMT1b1U0AExHREREd3RMR3REzW91NABMR0R0RHd09Ed0dMdvdTQATERHdEdHR3RMR3dGz3U0A273b0R3REd3TEd0Rs90EADvbERPdER3RPRHdHb1NAACwHRE90R3dET0d0R0xBAAAMBHd3RMd0R3dE9Ed0QMAABvREdET0RHd3dPRHREDAAAbHRER3REd0d0z0R0RAwAA0xEREd0RHdHdPdEd0QMAABMR3d3dEd0R3T3RHT0AAAAT0R0R3R3REd093REzAAAAE9ET3d0d0RHdvd0xAwAAANMR093dE9HR3bM7AwAAAAAwET3TPRPRMd27AAAAAAAAMBExuzsR3T09CwAAAAAAAAATEbMAM90zuwAAAAAAAAAAMB3RCwC7uwAAAAAAAAAAAAAzuwAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.food.big_ice_cream"},"sprites.food.plate":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"food","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQxABgAAAAAAAAAsLu7CwAAAAAAAACw2xERvQsAAAAAAADbEREREb0AAAAAALAdEREREdELAAAAANsRERERERG9AAAAABsRERERERGxAAAAsB0REd0dERHRCwAAsBER3dHdERERCwAA2xHREd3dHRERvQAAGxHd0d3d3RERvQAAGxEd0d3d3R0RsQCwHdEd3RER3RsR0QuwEdERHRER0dsR0QuwEdHRHREREb0REQuwER3REREREb0dEQvbER3dEREREdEbEQvbER3dEREREdEbEb0b0REdEREREREbEb0b0REdERERERHbEb0b0REdERERERG7EbEb0REdERERERG7EbEb0REdERERERG9EbEb0REdERERERG9EbEb0REdERERERG9EbEb0REdERERERG9EbEb0REdERERERG9EbEb0REdERERERG9EbEb0REdERERERG9EbEb0REdERERERHdEbEb0REdERERERHdEbEb0REdERERERHdEb0bER0dEREREREdEb3bER3dEREREdEdEb3bER3dEREREdEdEQuwER3REREREd0dEQuwEdHRHREREb0REQuwEdERHRER0b0R0QuwHdEd3RER3dsR0QsAGxEd0d3d3RsRsQAAGxHd0d3dvR0RvQAA2xHREd3d2xERvQAAsBERHdG7HRERCwAAsB0REd0dERHRCwAAABsRERERERGxAAAAANsRERERERG9AAAAALAdEREREdELAAAAAADbEREREb0AAAAAAACw2xERvQsAAAAAAAAAsLu7CwAAAAA="}},"sprites.duck":{"kind":5,"retType":""},"sprites.duck.duck1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAsMsMAAAAsAuw3csAAACwvdvd3QwAALBVvdzdywAAsFtVzd3NAAC7tVXF3c0AsFtVW7XdzQCwVdXRW9XNALBVFf9VVc0Au1X1v1RVxQC1VVVFVFXFALVV1URUVbUAC1tFRFRVuwAAsPtMVNULAAAAALC0uwAAAAAAAAsAAA=="}},"sprites.duck.duck2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAsMsMAAAAsAuw3csAAACwvdvd3QwAALBVvdzdywAAsFtVzd3NAAC7tVXF3c0AsFtVW7XdzQCwVdXRW9XNALBVFf9VVc0Au1X1v1RVxbC1VVVFVFXFULtV1URUVbWwAFtFRFRVuwAAsPtMVNULAAAAAEC7uwAAAAAAsAAAAA=="}},"sprites.duck.duck3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAu8sMAAAAAAC93csAAAAAAN3c3QwAAAAAXcXdywAAsLtb1dzNAAC7VVtV3M0AsFtVvVXbzQCw1dFVvdXNALAV/1VVVc2wu/W/RVVVxVu8VdVEVVXFtbBV3URVVbULANtERFVVuwAA8ExEW9ULAAAAALSwuwAAAAAACwAAAA=="}},"sprites.duck.duck4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAMsMCwAAAACw3bsLAAAAANvdWwwAAACw3b1dzAAAu9vdW7XMALBbVdVbzc0Au1VVVdvczQBbHV1Vxd3NAFvxX1VVVc2wW/9LVVVVxVtb1URVVVXFtVvdRFVVVbULsEREVVVVuwAATLRbVdULAABAC7C7uwAAALAAAAAAAA=="}},"sprites.duck.duck5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAsMy8AAAAAADbvbsAAAAAANu9xQAAAACw3dvFAAAAu9u9VcsMALBbVb3V3AwAu1VVtc3dzQBbHV1V3N3NAFvxX1VVVc2wW/9LVVVVxVtb1URVVVXFtVvdRFVVVbULsEREVVVVuwAATLRbVdULAABAC7C7uwAAALAAAAAAAA=="}},"sprites.duck.duck6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAu8wAAAAAALC9vQwAAAAAsN3czQAAAACwXcW9DAAAu9tb1dwMALBbVVtV3AwAu1VVvVXbDABbHV1Vvd0MAFvxX1VV1QywW/9bVFVVDFtbVU1UVVUMtVvVTVRVVQsLsE1EVFW1CwAAz0S0Vb0AAAAAQAu7CwAAAACwAAAAAA=="}},"sprites.duck.duckHurt":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAMsMAAAAsAuw3csAAACwvdvd3QwAALBVvdzdywAAu1tVzd3NALBbtVXF3c0Au1VVW7XdzQBbW1vVW9XNAFu8XFVVVc27W/VLVVVVxVVb1URVVVXFu1vdRFVVVbUAsEREVVVVuwAATLRbVdULAABAC7C7uwAAALAAAAAAAA=="},"pyQName":"sprites.duck.duck_hurt"},"sprites.duck.log1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAABgZwAAAAAAAAAAAAB2ZwAAALDL7O7Mz2B3hgAAANvd++7uzv936O4AsL27ve/u7s5m7u4A27u92+/u7u5udmcA29vb2/vu7u5ud+ewvb29vf3u7u7uZ+6wvb29vc3u7u7uhu6wvb29vc3u7u7uhu6wvb29vc3u7u7uZ+4A29vb28vu7u5ud+cA27u92+zu7u5ud2cAsL27vezu7u5uhu4AANvdy+7u7u5mhuwAALDL7A4AAGB3Z/4AAAAAAAAAAAB2Zw4AAAAAAAAAAABgZwAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.duck.log2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAABgAAAAAAAAAAAAAAAHYGAAAAAGBnAAAAAAAAAAAAAABgdwYAAAAAdmcAAAAAALvM7s78DHZnCAAAAGB3hgAAAACw3b3v7u78f4fu7u7M/3fu7gAAANu72/vu7u5s5u7u7u7uZu7uAACwvdu7/e7u7u5md+bu7u5udmcAALC9vb297+7u7nZ37u7u7m535wAA29vb29vv7u7ufubu7u7u7mfuAADb29vb2+zu7u5u6O7u7u7uh+4AANvb29vb7O7u7m7o7u7u7u6H7gAA29vb29vs7u7ufubu7u7u7mfuAACwvb29vezu7u52d+7u7u5ud+YAALC927vN7u7u7nZ35u7u7m53ZwAAANu728vu7u7uZuju7u7ubobOAAAAsN297O7u7m5myO7O/P92hu4AAAAAu8zuAAAAdnfm////bndnAAAAAAAAAAAAAABgd+YAAAAAdmcAAAAAAAAAAAAAAAB2BgAAAABgZwAAAAAAAAAAAAAAAGAAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.duck.log3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAABgAAAAAAAABgAAAAAAAAAAAAAAAABgZwAAAAAAdgYAAAAAYGcAAAAAAAAAAAAAAAAAdmcAAAAAYHcGAAAAAHZnAAAAAAAAsMvs7szPYHeGAAAAAHZnCAAAAGB3hgAAAAAAANvd++7uzv936O7uzvx/5+7u7u7uZ87MAAAAALC9u73v7u7OZu7u7u7ububu7u7u7mbu7gAAAADbu73b7+7u7m52Z+7u7u5md/bM7O5ud2cAAAAA29vb2/vu7u5ud+fu7u7udnfu7u7ubnfnAAAAsL29vb397u7u7mfu7u7u7n7m7u7u7u5n7gAAALC9vb29ze7u7u6G7u7u7u5+6O7u7u7uh+4AAACwvb29vc3u7u7uhu7u7u7ufuju7u7u7ofuAAAAsL29vb3N7u7u7mfu7u7u7n7m7u7u7u5n7gAAAADb29vby+7u7m535+7u7u52Z+7u7u5ud+YAAAAA27u92+zu7u5ud2fu7u7udnfm7u7ufndnAAAAALC9u73s7u7ubobu7u7u7mbozPz/zG6G7gAAAAAA293L7u7u7maG7O7M/29n6O7u7u5mhu4AAAAAALDL7A4AAGB3Z/7//+92dwYAAABgd2cAAAAAAAAAAAAAAAAAdmcOAAAAYHcGAAAAAHZnAAAAAAAAAAAAAAAAAGBnAAAAAAB2BgAAAABgZwAAAAAAAAAAAAAAAAAABgAAAAAAYAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.duck.log4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAGAAAAAABgAAAAAAAABgAAAAAAAAAAAAAAdgYAAAAAYGcAAAAAAHYGAAAAAGBnAAAAAAAAAAAAAGB3BgAAAAB2ZwAAAABgdwYAAAAAdmcAAAAAu8zuzvwMdmcIAAAAYHeGAAAAAHZnCAAAAGB3hgAAALDdve/u7vx/h+7u7sz/d+7u7u7ufubMzP///2fMzAAA27vb++7u7mzm7u7u7u5m7u7u7u5u5u7uzMzMZszMALC927v97u7u7mZ35u7u7m52Z8/M7u52d+bMzMx8d2cAsL29vb3v7u7udnfu7u7ubnfn7u7u7nZ37s7OzGx3xwDb29vb2+/u7u5+5u7u7u7uZ+7u7u7ufubu7u7MzGfMANvb29vb7O7u7m7o7u7u7u6H7u7u7u5+6O7u7szMh8wA29vb29vs7u7ubuju7u7u7ofu7u7u7n7o7u7MzsyHzADb29vb2+zu7u5+5u7u7u7uZ+7u7u7ufubuzszMzGfMALC9vb297O7u7nZ37u7u7m535u7u7u52Z+7u7s5sd8YAsL3bu83u7u7udnfm7u7ubndn7u7u7nd35szMznx3ZwAA27vby+7u7u5m6O7u7u5uhs7M/8/sZujuzszMbIbMAACw3b3s7u7ubmbI7s78/3aG7u7u7m5m6O7uzPxmhv8AAAC7zO4AAAB2d+b///9ud2cAAAAAdncGAAAAYHdnAAAAAAAAAAAAAGB35gAAAAB2ZwAAAABgdwYAAAAAdmcAAAAAAAAAAAAAAHYGAAAAAGBnAAAAAAB2BgAAAABgZwAAAAAAAAAAAAAAYAAAAAAAAAYAAAAAAGAAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.duck.log5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAdgYAAAAAAGB3BgAAAAAAdmcIAAAAAAB+5szu7u6+AG7m7u7u7u4L7nZ37u7u7r7udnfu7u7u7u5+5u7u7u7u7n7o7u7u7u7ufuju7u7u7u5+5u7u7u7u7nZn7u7u7u7ud3fu7u7uvuxm6O7u7u4Lbmbo7u7uvgB2dwYAAAAAAGB3BgAAAAAAAHYGAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.duck.log6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAABgAAAAAAAAAAdgYAAAAAYGcAAAAAAAAAYHcGAAAAAHZnAAAAAAAAAHZnCAAAAGB3hgAAAAAAAAB/5+7u7u7uZ87s7u7uCwAAbubu7u7u7mbu7u7u7r4AAO5md/bM7O5ud+fu7u7uCwDudnfu7u7ubnfn7u7u7g4A7n7m7u7u7u5n7u7u7u4OAO5+6O7u7u7uh+7u7u7uDgDufuju7u7u7ofu7u7u7g4A7n7m7u7u7u5n7u7u7u4OAO52Z+7u7u5ud+bu7u7uDgDudnfm7u7ufnfn7u7u7gsA7mbozPz/zG6G7u7u7r4AAG9n6O7u7u5mhu7u7u4LAAB2dwYAAABgd2cAAAAAAAAAYHcGAAAAAHZnAAAAAAAAAAB2BgAAAABgZwAAAAAAAAAAYAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.duck.log7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAYAAAAAAGAAAAAAAAAAAAAAdgYAAAAAYGcAAAAAAHYGAAAAAAAAAABgdwYAAAAAdmcAAAAAYHcGAAAAAAAAAAB2ZwgAAABgd4YAAAAAdmcIAAAAAAAAAAB/5+7u7u7/d+7u7u7ufubM7u7uvgAAAABu5u7u7u7uZu7u7u7ububu7u7u7gsAAADuZnfm7u7ubnZnz8zu7nZ37u7u7r4AAADudnfu7u7ubnfn7u7u7nZ37u7u7u4AAADufubu7u7u7mfu7u7u7n7m7u7u7u4AAADufuju7u7u7ofu7u7u7n7o7u7u7u4AAADufuju7u7u7ofu7u7u7n7o7u7u7u4AAADufubu7u7u7mfu7u7u7n7m7u7u7u4AAADudmfu7u7ubnfm7u7u7nZn7u7u7u4AAADudnfm7u7ubndn7u7u7nd37u7u7r4AAADuZujs7u7ubobOzP/P7Gbo7u7u7gsAAABvZ+juzvz/dobu7u7ubmbo7u7uvgAAAAB2d+b///9ud2cAAAAAdncGAAAAAAAAAABgd+YAAAAAdmcAAAAAYHcGAAAAAAAAAAAAdgYAAAAAYGcAAAAAAHYGAAAAAAAAAAAAYAAAAAAAAAYAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.duck.log8":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAAAAABgAAAAAAYAAAAAAAAAYAAAAAAAAAdgYAAAAAYGcAAAAAAHYGAAAAAGBnAAAAAAAAYHcGAAAAAHZnAAAAAGB3BgAAAAB2ZwAAAAAAAHZnCAAAAGB3hgAAAAB2ZwgAAABgd4YAAAAAAAB/h+7u7sz/d+7u7u7+f+fu7u7u7mfO7O7u7gsAbObu7u7u7mbu7u7u7m7m7u7u7u5m7u7u7u6+AO5md+bu7u5udmfu7u7uZnf2zOzubnfn7u7u7gvudnfu7u7ubnfn7u7u7nZ37u7u7m535+7u7u4O7n7m7u7u7u5n7u7u7u5+5u7u7u7uZ+7u7u7uDu5u6O7u7u7uh+7u7u7ufuju7u7u7ofu7u7u7g7ubuju7u7u7ofu7u7u7n7o7u7u7u6H7u7u7u4O7n7m7u7u7u5n7u7u7u5+5u7u7u7uZ+7u7u7uDu52d+7u7u5ud+bu7u7udmfu7u7ubnfm7u7u7g7udnfm7u7ubndn7u7u7nZ35u7u7n535+7u7u4L7mbo7u7u7m6Gzu7u7u5m6Mz8/8xuhu7u7u6+AG5myO7O/P92hu7uzP9vZ+ju7u7uZobu7u7uCwB2d+b///9ud2f+///vdncGAAAAYHdnAAAAAAAAYHfmAAAAAHZnDgAAAGB3BgAAAAB2ZwAAAAAAAAB2BgAAAABgZwAAAAAAdgYAAAAAYGcAAAAAAAAAYAAAAAAAAAYAAAAAAGAAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.duck.tree":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQkACkAAAAAAAAAAAAAAAAAgIYAAAAAAAAAAAAAAAAAAAAAAAAAAAAIgIaIBgAAAAAAAAAAAAAAAAAAAAAAAICGaIZmhgAAAAAAAAAAAAAAAAAAAAAAAICGZmhmiIgAAAAAAAAAAAAAAAAAAABgAGZmZ2aGaGYIAAAAAAAAAAAAAAAAAAB2CGh2Z2aIZoYIAAAAAAAAAAAAAAAAAIB3hmh2ZmZoZoiICAAAAAAAAAAAAAAAAIZndmdmdmZmhmhmCAAAAAAAAAAAAGAAYGdmd2dmd2dmZmaGiAAAAAAAAAAAAHYGaGdmd2Znd2ZmZmaIhgAAAAAAAAAAAHiHdmZnZ3ZnZmZmZoZohgAAAAAAAABgCGhndnZnZndnZnZmZmZmhgAAAAAAAABghnZmZnZnZndmZndnZmZmiAAAAAAAAACAZnZmZnZmZmZ2ZndmZmaIiAAAAAAAAACAhndmZmd2Z3Z3dmZmZmZmhg4AAAAAAACAeHd3ZmZ3Z3d3ZnZ3ZmZmZujM/w8AAABod3dnZnZ3ZndmZnd3ZmZmiOjuzg8AAAB2d3dmZmZmZnZ3ZmZmZmaGiO7u7gwAAACAdnd3Zndndnd3ZndnZmZmhuj/7w4AAACAaHdmZnd3d3dnZndndndmhgjA7A4AAABgeHZ2ZnZ3dnd3ZmZmdmdmhgDszgwAAAAAeIZ2Z2Z3Znd3dmdmZmZmyO7OAAAAAAAAZmhoZ2Zmd3dmdndmZmaG6AwAAAAAAAAAiGiGZ2dmd3dmZmZ2d2dmiAAAAAAAAAAAAGCIeGdmd3dmZ2Zmd2dmZggAAAAAAAAAAAAAYIdnd2dmd2ZmdmdmhgAAAAAAAAAAAAAAAIZ2dmdmd2d3ZmaGCAAAAAAAAAAAAAAAAAB4Z2d3dmd3ZmZmCAAAAAAAAAAAAAAAAABgZ2Z3ZmZ2ZmaGCAAAAAAAAAAAAAAAAAAAhmd2ZnZmZoYIAAAAAAAAAAAAAAAAAAAAgHdmZnZmZoYAAAAAAAAAAAAAAAAAAAAAAHZmZmZmZoYAAAAAAAAAAAAAAAAAAAAAAIBohmZmiAgAAAAAAAAAAAAAAAAAAAAAAACACGhmCAAAAAAAAAAAAAAAAAAAAAAAAAAAAICGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIAAAAAAAAAAAAAAA="}},"sprites.castle":{"kind":5,"retType":""},"sprites.castle.heroFrontAttack1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAA//D/AAAAAAAAAP//79+7DwAAAAAA8P/+7t+7/AAAAAAA/+/yT9+7/AAAAAAA/y7/G9+7/w8AAADwLy7v//3/9A8AAADwIi7v1E0i9QAAAADwIi7v1E0i9QAAAADwLy7v/00i9A8AAAAA/y7/G+0i9A8AAAAA/+/yT+7/DwAAAAAA8O/+7v7UBAAAAAAAAP//7w9OBAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.hero_front_attack1"},"sprites.castle.heroFrontAttack2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAP//AAAAAAAAAAAA/73LDwAAAAAAAP//7///DwAAAAAA8P/+7v4EAAAAAAAA/+/yT+7//8DMAAAA/y7/G+0i9N/NAADwLy7v/00i9N0MAADwIi7v1E3C3M0AAADwIi7v1E3C3QwAAADwLy7v/+3OzA8AAAAA/y7/G9Tt9A8AAAAA/+/yT97t/wAAAAAA8O/+7k8OAAAAAAAAAP//7+8AAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.hero_front_attack2"},"sprites.castle.heroFrontAttack3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAP//AAAAAAAAAAAA/73LDwAAAAAAAPD/////DwAAAAAAAP/v/u7vBAAAAAAAAP/v8k/+/wAAAAAA8C/i8hsk9A8AAAAA8CLi4v8t9A8AAAAALyLi4tQt9Q8AAAAALyLi4tQt9Q/AAAAA8CLi4v8t9A7MzMwA8C/i8hv03+0cEREAAP/v8k9O1O3MzMwAAP/v/u7v7g7AAAAAAPD///8OAAAAAAAAAADw/w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.hero_front_attack3"},"sprites.castle.heroFrontAttack4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAP//AAAAAAAAAADw/73LDwAAAAAA8P//7///DwAAAAAA/+/v7v4EAAAAAADw/y7/T+7//wAAAADw7/K/2+0i9A8AAAD/4vL+300i9A8AAAAv4vJO1E0i9QAAAAAv4vJO1E0i9QAAAAD/4vL+300i9A8AAADw7/K/2+Qi9A8AAADw/y7/T+7//wAAAAAA/+7v7k5BAAAAAAAA8P//7/9OAAAAAAAAAADw/9/tAAAAAAAAAAAAAN7tAAAAAAAAAAAAwMwOAAAAAAAAAAAAwM0AAAAAAAAAAAAA3M0AAAAAAAAAAADA3QwAAAAAAAAAAADczQAAAAAAAAAAAADcDAAAAAAAAAAAAADMAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.hero_front_attack4"},"sprites.castle.heroSideAttackLeft1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMwAAAAAAAAAAAAAwN0MAAAAAAAAAAAAANzNAAAAAAAAAAAAAMDdzAAAAAAAAAAAAP/czQ4AAAAAAAAA/y7PzO0AAAAAAADw4uLv3u3/AAAAAAAv4vJO7URSDwAAAAD/4vJO3U5eDwAAAADv7/L+3yRC/wAAAADv/v6/0SRC/wAAAADv/i7vRC5C/wAAAADv7i9P7S5CDwAAAADw7i9P5P//AAAAAADw7+/v7g8AAAAAAAAA/////gAAAAAAAAAAAAD/DwAAAAAAAAA="},"pyQName":"sprites.castle.hero_side_attack_left1"},"sprites.castle.heroSideAttackLeft2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAwAAAAAAAAAAAAA3AwAAAAAAAAAAAAAwM0AAAAAAAAAAAAAwN0MAAAAAAAAAAAAANzMAAAAAAAAAAAAANzNAAAAAAAAAAAAAMDMAAAAAAAAAAD//+DdDgAAAAAAAP8u7+/dDgAAAAAA8O/i7/5ODgAAAAAA8OLyTt1ODgAAAAAAL+LyTt3i/wAAAADwIuLy/t9S/wAAAADw7/7+v9tCDwAAAADw7/7+v9tCDwAAAAAA7/4u70RCDwAAAAAA7+4vT+1C/wAAAAAA7+4vT+RC/wAAAAAA8O7v7+7//wAAAAAA8O////4AAAAAAAAAAP//7w8AAAAAAAAAAADw/wAAAAAAAAA="},"pyQName":"sprites.castle.hero_side_attack_left2"},"sprites.castle.heroSideAttackLeft3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAMANAAAAAAAAAAAAAMDNAAAAAAAAAAAAAMDNAAAAAAAAAAAAAMDNAAAAAAAAAAAAAMDNAAAAAAAAAPD/D8zMDAAAAAAA8O/y/uAOAAAAAAAA/y7+7t7tAAAAAADwLy7v1N7tAAAAAADwIi7v1O3kDwAAAAAv/y7v/+3k/wAAAAD/7u//uy3+/wAAAADw7u/yTiT0DwAAAADw7v7y1C70DwAAAADw7v7yRC70/wAAAAAA7/7+7v7//wAAAAAA//7/7w8A/wAAAAAA8P///gAAAAAAAAAAAAD/DwAAAAAAAAA="},"pyQName":"sprites.castle.hero_side_attack_left3"},"sprites.castle.heroSideAttackLeft4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMwAAAAAAP//AAAA3M0AAAAA/y7vDwDA3QwAAADw4uLv/s/czQAAAAAv4vJO3c7dDAAAAAD/4vJO3cTMDwAAAADv7/L+3yRC/wAAAADv/v6/0SRC/wAAAADv/i7vRO5P/wAAAADv7i9P7d1ODwAAAADw7i9P5N3+AAAAAADw7+/v7v8AAAAAAAAA/////gAAAAAAAAAAAAD/DwAAAAAAAAA="},"pyQName":"sprites.castle.hero_side_attack_left4"},"sprites.castle.heroSideAttackRight4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAD/DwAAAAAAAAAA/////gAAAAAAAADw7+/v7v8AAAAAAADw7i9P5N3+AAAAAADv7i9P7d1ODwAAAADv/i7vRO5P/wAAAADv/v6/0SRC/wAAAADv7/L+3yRC/wAAAAD/4vJO3cTMDwAAAAAv4vJO3c7dDAAAAADw4uLv/s/czQAAAAAA/y7vDwDA3QwAAAAAAP//AAAA3M0AAAAAAAAAAAAAwMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.hero_side_attack_right4"},"sprites.castle.heroSideAttackRight3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAD/DwAAAAAAAAAA8P///gAAAAAAAAAA//7/7w8A/wAAAAAA7/7+7v7//wAAAADw7v7yRC70/wAAAADw7v7y1C70DwAAAADw7u/yTiT0DwAAAAD/7u//uy3+/wAAAAAv/y7v/+3k/wAAAADwIi7v1O3kDwAAAADwLy7v1N7tAAAAAAAA/y7+7t7tAAAAAAAA8O/y/uAOAAAAAAAAAPD/D8zMDAAAAAAAAAAAAMDNAAAAAAAAAAAAAMDNAAAAAAAAAAAAAMDNAAAAAAAAAAAAAMDNAAAAAAAAAAAAAMANAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.hero_side_attack_right3"},"sprites.castle.heroSideAttackRight2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAADw/wAAAAAAAAAAAP//7w8AAAAAAAAA8O////4AAAAAAAAA8O7v7+7//wAAAAAA7+4vT+RC/wAAAAAA7+4vT+1C/wAAAAAA7/4u70RCDwAAAADw7/7+v9tCDwAAAADw7/7+v9tCDwAAAADwIuLy/t9S/wAAAAAAL+LyTt3i/wAAAAAA8OLyTt1ODgAAAAAA8O/i7/5ODgAAAAAAAP8u7+/dDgAAAAAAAAD//+DdDgAAAAAAAAAAAMDMAAAAAAAAAAAAANzNAAAAAAAAAAAAANzMAAAAAAAAAAAAwN0MAAAAAAAAAAAAwM0AAAAAAAAAAAAA3AwAAAAAAAAAAAAAzAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.hero_side_attack_right2"},"sprites.castle.heroSideAttackRight1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAADw/wAAAAAAAAAA8P//7w8AAAAAAAAA//7+7v4AAAAAAAAA7/7yRP7/DwAAAADw7v7y1O4i9AAAAADw7u/yTuQi9A8AAADw7u//G00i9A8AAADw/i7v/00i9A8AAADwLy7v1O3k9QAAAADwIi7v1E4k9QAAAAAALy7+7t3+DwAAAAAA8O/yzNwOAAAAAAAAAPDP3ewAAAAAAAAAAADczQwAAAAAAAAAAMDdDAAAAAAAAAAAANzNAAAAAAAAAAAAAMwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.hero_side_attack_right1"},"sprites.castle.heroWalkFront1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAPAPAAAAAPD///7gRAAA/+/v7k9NAPD/Lv/k/v8A8O/yv9EuQv//4vL+3yRC/y/i8k7dJFIPL+LyTt0kUg//4vL+3yRC//Dv8r/RLkL/8P8u/+T+/wAA/+7v7k9NAADw///+4EQAAAAA8A8AAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_front1"},"sprites.castle.heroWalkFront2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAP8AAAAAAAD////wDgAA8P/+7u8EAAD/7/JP/v//AP8u/xskQv/wLy7v/y1C//AiLu/ULVIP8CIu79QtUg/wLy7v/+3+DwD/Lv8b1O0PAP/v8k/e7QAA8O/+7k8OAAAA////7gAAAAAA/wAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_front2"},"sprites.castle.heroWalkFront3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAPAPAAAAAPD///7gRAAA/+/v7k9NAPD/Lv/k/v8A8O/yv9EuQv//4vL+3yRC/y/i8k7dJFIPL+LyTt0kUg//4vL+3yRC//Dv8r/RLkL/8P8u/+T+/wAA/+7v7k9NAADw///+4EQAAAAA8A8AAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_front3"},"sprites.castle.heroWalkFront4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAP8AAAAAAAD////uAAAA8O/+7k8OAAD/7/JP3u0AAP8u/xvU7Q/wLy7v/+3+D/AiLu/ULVIP8CIu79QtUg/wLy7v/y1C/wD/Lv8bJEL/AP/v8k/+//8A8P/+7u8EAAAA////8A4AAAAA/wAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_front4"},"sprites.castle.heroWalkBack1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAPAPAAAAAPD///7gRAAA/+/v7k9NAPD+Lv/v/v8A8P7yIu/+Qv/v/i7y7v5C/+8v8u7u/kIP7y/y7u7+Qg/v/i7y7v5C//D+8iLv/kL/8P4u/+7+/wAA/+/v7k9NAADw///+4EQAAAAA8A8AAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_back1"},"sprites.castle.heroWalkBack2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAADwDwAAAADw//8PAAAA8P/+7v5ODgDv7/Ly7v//AO8vL//uL//w7u/y7+4v//D+Iu/u7i8P8P4i7+7uLw/w7u8v8u4vDwDvLyLv7u8OAO/v/+7u3w4A8P/+7v7UBAAA8P//D04AAAAAAPAPAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_back2"},"sprites.castle.heroWalkBack3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAPAPAAAAAPD///7gRAAA/+/v7k9NAPD+Lv/v/v8A8P7yIu/+Qv/v/i7y7v5C/+8v8u7u/kIP7y/y7u7+Qg/v/i7y7v5C//D+8iLv/kL/8P4u/+7+/wAA/+/v7k9NAADw///+4EQAAAAA8A8AAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_back3"},"sprites.castle.heroWalkBack4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAADwDwAAAADw//8PTgAA8P/+7v7UBADv7//u7t8OAO8vIu/u7w7w7u8v8u4vD/D+Iu/u7i8P8P4i7+7uLw/w7u/y7+4v/wDvLy//7i//AO/v8vLu//8A8P/+7v5ODgAA8P//DwAAAAAAAPAPAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_back4"},"sprites.castle.heroWalkShieldFront1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAPAP/w8AAPD///69+wAA/+/v/r3LD/D/Lv/0vcsP8O/yv/G9+///4vL+3/9P/y/i8k7dJFIPL+LyTt0kUg//4vL+3yRC//Dv8r/RLkL/8P8u/+T+/wAA/+7v7k9NAADw///+4EQAAAAA8A8AAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_front1"},"sprites.castle.heroWalkShieldFront2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAP//AAAAAP/wvcsPAAD//////w8A8P/+7u8EAAD/7/JP/v//AP8u/xskQv/wLy7v/y1C//AiLu/ULVIP8CIu79QtUg/wLy7v/+3+DwD/Lv8b1O0PAP/v8k/e7QAA8O/+7k8OAAAA////7gAAAAAA/wAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_front2"},"sprites.castle.heroWalkShieldFront3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAP8AAAAAAAD////+/wAA8O/+7t+7DwD/7/JP37v8AP8u/xvfu/zwLy7v/9+7D/AiLu/U/f8P8CIu79QtUg/wLy7v/y1C/wD/Lv8bJEL/AP/v8k/+//8A8P/+7u8EAAAA////8A4AAAAA/wAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_front3"},"sprites.castle.heroWalkShieldFront4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAP8AAAAAAAD////uAAAA8O/+7k8OAAD/7/JP3u0AAP8u/xvU7Q/wLy7v/+3+D/AiLu/ULVIP8CIu79QtUg/wLy7v/y1C/wD/Lv8bJEL/AP/v8k/+//8A8P/+7u8EAAAA//////8PAAAA//C9yw8AAAAAAP//AA=="},"pyQName":"sprites.castle.hero_walk_shield_front4"},"sprites.castle.heroWalkShieldBack1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAPAPAAAAAPD///7gRAAA/+/v7k9NAPD+Lv/v/v8A8P7yIu/+Qv/v/i7y7v5C/+8v8u7u/kIP7y/y7u7+Qg/v/i7y7v5C//D+8iLv/kL/8P4u/+7+/wAA/+/v7k9NAADw///+4EQAAAAA8A8AAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_back1"},"sprites.castle.heroWalkShieldBack2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAA8A8AAAAA8P//DwAAAPD//u7+Tg4A7+/y8u7//wDvLy//7i//8O7v8u/uL//w/iLv7u4vD/D+Iu/u7i8P8O7vL/LuLw8A7y8i7+7vDgDv7//u7t8OAPD//u7+1AQAAPD/////DwAAAADwvcsPAAAAAAD//wAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_back2"},"sprites.castle.heroWalkShieldBack3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADwDwAAAADw///+4EQAAP/v7+5PTQDw/i7/7/7/APD+8iLv/kL/7/4u8u7+Qv/vL/Lu7v5CD+8v8u7u/kIP7/4u8u7+Qv/w/vIi7/5C//D+Lv/u/v8AAP/v7+5PTQAA8P///uBEAAAAAPAPAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_back3"},"sprites.castle.heroWalkShieldBack4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAA8P////8PAPD//u7+1AQA7+//7u7fDgDvLyLv7u8O8O7vL/LuLw/w/iLv7u4vD/D+Iu/u7i8P8O7v8u/uL/8A7y8v/+4v/wDv7/Ly7v//APD//u7+Tg4AAPD//w8AAAAAAADwDwAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_back4"},"sprites.castle.heroWalkShieldSideLeft1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAA8P8PAAAAAPDv8v4A8A8ALy7+7v////AiLu/U7VL/8C8u79RNUv/w/i7v/+3+D/Du7/8b3u0P8O7v8k7e7Q/w7v7y1E7+/wDv/vJE/v//AP/+/u4O8A8A8P//7w8AAAAAAPD/AAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_side_left1"},"sprites.castle.heroWalkShieldSideLeft2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAADw/wAAAAD//9+7DwAA/y7v37v7APDi4u/+7/4AL+LyTt3e7Q//4vJO3d7tD+/v8v7fTv7/7/7+v9EkQv/v/i7vRC5C/+/uL0/tLkIP8O4vT+T//gDw7+/v7g8AAAD////+AAAAAAAA/w8AAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_side_left2"},"sprites.castle.heroWalkShieldSideLeft3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAADw/w8AAAAA8O/y/gDwDwAvLv7u////8CIu79TtUv/wLy7v1E1S//D+Lu//7f4P8O7v/xve7Q/w7u/yTt7tD/Du/vLUTv7/AO/+8kT+//8A//7+7g7wDwDw///vDwAAAAAA8P8AAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_side_left3"},"sprites.castle.heroWalkShieldSideLeft4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAA/w8AAADw//+9+wAA8O/y/r27DwAvLv7u/+7/8CIu79Tt3f7wLy7v1O3d/vD+Lu//7eQP8O7v/xtNQg/w7u/yTuRCD/Du/vLU7kL/AO/+8kT+//8A//7+7g7wDwDw///vDwAAAAAA8P8AAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_side_left4"},"sprites.castle.heroWalkShieldSideRight4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAPD/AAAAAPD//+8PAAAA//7+7g7wDwDv/vJE/v//8O7+8tTuQv/w7u/yTuRCD/Du7/8bTUIP8P4u7//t5A/wLy7v1O3d/vAiLu/U7d3+AC8u/u7/7v8A8O/y/r27DwAA8P//vfsAAAAAAAD/DwAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_side_right4"},"sprites.castle.heroWalkShieldSideRight3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAPD/AAAAAPD//+8PAAAA//7+7g7wDwDv/vJE/v//8O7+8tRO/v/w7u/yTt7tD/Du7/8b3u0P8P4u7//t/g/wLy7v1E1S//AiLu/U7VL/AC8u/u7///8A8O/y/gDwDwAA8P8PAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_side_right3"},"sprites.castle.heroWalkShieldSideRight2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAP8PAAAAAP////4AAADw7+/v7g8AAPDuL0/k//4A7+4vT+0uQg/v/i7vRC5C/+/+/r/RJEL/7+/y/t9O/v//4vJO3d7tDy/i8k7d3u0P8OLi7/7v/gAA/y7v37v7AAAA///fuw8AAAAAAPD/AAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_side_right2"},"sprites.castle.heroWalkShieldSideRight1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAPD/AAAAAPD//+8PAAAA//7+7g7wDwDv/vJE/v//8O7+8tRO/v/w7u/yTt7tD/Du7/8b3u0P8P4u7//t/g/wLy7v1E1S//AiLu/U7VL/AC8u/u7///8A8O/y/gDwDwAA8P8PAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_shield_side_right1"},"sprites.castle.heroWalkSideLeft1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAA//8AAAAAAP8u7w8AAADw4uLv/v//AC/i8k7dLlIP/+LyTt0kUg/v7/L+3yRC/+/+/r/R5P7/7/4u70Te7f/v7i9P7d7tD/DuL0/kT/4A8O/v7+4PAAAA/////gAAAAAAAP8PAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_side_left1"},"sprites.castle.heroWalkSideLeft2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAA8P8PAAAAAPDv8v4A8A8ALy7+7v////AiLu/U7VL/8C8u79RNUv/w/i7v/+3+D/Du7/8b3u0P8O7v8k7e7Q/w7v7y1E7+/wDv/vJE/v//AP/+/u4O8A8A8P//7w8AAAAAAPD/AAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_side_left2"},"sprites.castle.heroWalkSideLeft3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAA//8AAAAAAP8u7w8AAADw4uLv/v//AC/i8k7dLlIP/+LyTt0kUg/v7/L+3yRC/+/+/r/R5P7/7/4u70Te7f/v7i9P7d7tD/DuL0/kT/4A8O/v7+4PAAAA/////gAAAAAAAP8PAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_side_left3"},"sprites.castle.heroWalkSideLeft4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAA8P8PAAAAAPDv8v4A8A8ALy7+7v////AiLu/U7VL/8C8u79RNUv/w/i7v/01CD/Du7/8bTUIP8O7v8k7k/g/w7v7y1N7t/wDv/vJE3u3/AP/+/u5O/g8A8P//7w8AAAAAAPD/AAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_side_left4"},"sprites.castle.heroWalkSideRight4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAA8P//7w8AAAD//v7uTv4PAO/+8kTe7f/w7v7y1N7t//Du7/JO5P4P8O7v/xtNQg/w/i7v/01CD/AvLu/UTVL/8CIu79TtUv8ALy7+7v///wDw7/L+APAPAADw/w8AAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_side_right4"},"sprites.castle.heroWalkSideRight3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/w8AAAAA/////gAAAPDv7+/uDwAA8O4vT+RP/gDv7i9P7d7tD+/+Lu9E3u3/7/7+v9Hk/v/v7/L+3yRC///i8k7dJFIPL+LyTt0uUg/w4uLv/v//AAD/Lu8PAAAAAAD//wAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_side_right3"},"sprites.castle.heroWalkSideRight2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAA8P//7w8AAAD//v7uDvAPAO/+8kT+///w7v7y1E7+//Du7/JO3u0P8O7v/xve7Q/w/i7v/+3+D/AvLu/UTVL/8CIu79TtUv8ALy7+7v///wDw7/L+APAPAADw/w8AAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_side_right2"},"sprites.castle.heroWalkSideRight1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/w8AAAAA/////gAAAPDv7+/uDwAA8O4vT+RP/gDv7i9P7d7tD+/+Lu9E3u3/7/7+v9Hk/v/v7/L+3yRC///i8k7dJFIPL+LyTt0uUg/w4uLv/v//AAD/Lu8PAAAAAAD//wAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.hero_walk_side_right1"},"sprites.castle.houseRed":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"buildings","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQwADAAAAAAAABARkRGREZERkRGRGxmZmZmxswAAAAAAADAbMZsxmzGbMZsxkxmZmZmZsYMAAAAAADAZsZmxmbGZsZmxkxsZmZmZmbGAAAAAAAiLiLiIiIuIuIiwkzL5u7u7m5mDAAAAAAiLiLiIiIuIuIiYkzEJN7d3W1EZAAAACDu7u7u7u7u7u7ubEzEJN7P/WzkTgYAACAuIuIiIi4i4iIibEzEJN7P/WzkTmQAACAuIuIiIi4i4iIiZkzEJN7d3W3kTs4AAO7u7u7u7u7u7u7OxkbEJN7P/WxERM4AAC4i4iIiLiLiIiLOxkbEJN7P/WzkTs4AAC4i4iIiLiLiIiJuxkbEJN7d3W3kTmQA4O7u7u7u7u7u7u5sbEbE5O7u7m7kTmQAICLiIiIuIuIiIuJsTEbERERERERERGQAICLiIiIuIuIiIuJmTGbMzMzMzMzMzMwA4u7u7u7u7u7u7s5mRsbbEWFmZmZmZmYAIuIiIi4iIi4iIs7GtEwUYWZmZmZmZmYAIuIiIi4iIi4iIm7GxEth5v7/7+7+/+8g7u7u7u7u7u7u7mxmxERhTkREREREREQg4iIi4iIi4iIi4mxMZERh7u7u7u7u7u4g4iIi4iIi4iIi4mZMZERhTkT/TkRERETu7u7u7u7u7u7uzmZGZERhTuT/TkRERETiIiIuIuIiIi4izsZEZERh7v7/7u7u7u7u7u7u7u7u7u7ubsZEZERhTvT/TkREREQiIiIiIiIiIiIiYsZEZERhTvT/TkREREQiIiIiIiIiIiIiYsZEZERh7v7/7u7u7u7u7u7u7u7u7u7ubsZEZERhTvT/TkREREQiLiIuIuIiIi4izsZEZERhTvT/TkRERETu7u7u7u7u7u7uzmZGZERh7u7/7v7/7u4g4iIi4iIi4iIi4mZMZERhTkT/TuRPT0Qg4iIi4iIi4iIi4mxMZERhTkTkTuRPT0Qg7u7u7u7u7u7u7mxmxERh7u7u7u7/7u4AIuIiIi4iIi4iIm7GxEth5u7u7u7u7u4AIuIiIi4iIi4iIs7GtEwUYWZmZmZmZmYA4u7u7u7u7u7u7s5mRsbbEWFmZmZmZmYAICLiIiIuIuIiIuJmTGbMzMzMzMzMzMwAICLiIiIuIuIiIuJsTEbERERERERERGQA4O7u7u7u7u7u7u5sbEbE5O7u7m7kTmQAAC4i4iIiLiLiIiJuxkbEJN7d3W3kTmQAAC4i4iIiLiLiIiLOxkbEJN7P/WzkTs4AAO7u7u7u7u7u7u7OxkbEJN7P/WxERM4AACAuIuIiIi4i4iIiZkzEJN7d3W3kTs4AACAuIuIiIi4i4iIibEzEJN7P/WzkTmQAACDu7u7u7u7u7u7ubEzEJN7P/WzkTgYAAAAiLiLiIiIuIuIiYkzEJN7d3W1EZAAAAAAiLiLiIiIuIuIiwkzL5u7u7m5mDAAAAADAZsZmxmbGZsZmxkxsZmZmZmbGAAAAAADAbMZsxmzGbMZsxkxmZmZmZsYMAAAAAABARkRGREZERkRGRGxmZmZmxswAAAA="},"pyQName":"sprites.castle.house_red"},"sprites.castle.houseBlue":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"buildings","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQwADAAAAAAAADQ293b3dvd293b3by7u7u7y8wAAAAAAADAvMu8y7zLvMu8y9y7u7u7u8sMAAAAAADAu8u7y7vLu8u7y9y8u7u7u7vLAAAAAACqqKqKqqqoqoqqytzLi4iIiLi7DAAAAACqqKqKqqqoqoqqutzNrTgzM7PdvQAAAKCIiIiIiIiIiIiIvNzNrTjP87y92wsAAKCoqoqqqqiqiqqqvNzNrTjP87y9270AAKCoqoqqqqiqiqqqu9zNrTgzM7O928sAAIiIiIiIiIiIiIjIy9vNrTjP87zd3csAAKiqiqqqqKqKqqrIy9vNrTjP87y928sAAKiqiqqqqKqKqqq4y9vNrTgzM7O9270AgIiIiIiIiIiIiIi8vNvNjYiIiLi9270AoKqKqqqoqoqqqoq83NvN3d3d3d3d3b0AoKqKqqqoqoqqqoq73LvMzMzMzMzMzMwAioiIiIiIiIiIiMi728vbEbG7u7u7u7sAqoqqqqiqqqiqqsjLvdwdsbu7u7u7u7sAqoqqqqiqqqiqqrjLzdux6/7/7+7+/++giIiIiIiIiIiIiLy7zd2xPjMzMzMzMzOgiqqqiqqqiqqqirzcvd2xvrvrvru7u7ugiqqqiqqqiqqqirvcvd2xPjP/PjMzMzOIiIiIiIiIiIiIyLvbvd2xPuP/PjMzMzOKqqqoqoqqqqiqyMvdvd2xvvv/vru7u7uIiIiIiIiIiIiIuMvdvd2xPvP/PjMzMzOqqqqqqqqqqqqqusvdvd2xPvP/PjMzMzOqqqqqqqqqqqqqusvdvd2xvvv/vru7u7uIiIiIiIiIiIiIuMvdvd2xPvP/PjMzMzOqqKqoqoqqqqiqyMvdvd2xPvP/PjMzMzOIiIiIiIiIiIiIyLvbvd2xvuv/vvv/u7ugiqqqiqqqiqqqirvcvd2xPjP/PuM/PzOgiqqqiqqqiqqqirzcvd2xPjPjPuM/PzOgiIiIiIiIiIiIiLy7zd2xvru7u+v/vrsAqoqqqqiqqqiqqrjLzdux6+7u7u7u7u4AqoqqqqiqqqiqqsjLvdwdsbu7u7u7u7sAioiIiIiIiIiIiMi728vbEbG7u7u7u7sAoKqKqqqoqoqqqoq73LvMzMzMzMzMzMwAoKqKqqqoqoqqqoq83NvN3d3d3d3d3b0AgIiIiIiIiIiIiIi8vNvNjYiIiLi9270AAKiqiqqqqKqKqqq4y9vNrTgzM7O9270AAKiqiqqqqKqKqqrIy9vNrTjP87y928sAAIiIiIiIiIiIiIjIy9vNrTjP87zd3csAAKCoqoqqqqiqiqqqu9zNrTgzM7O928sAAKCoqoqqqqiqiqqqvNzNrTjP87y9270AAKCIiIiIiIiIiIiIvNzNrTjP87y92wsAAACqqKqKqqqoqoqqutzNrTgzM7PdvQAAAACqqKqKqqqoqoqqytzLi4iIiLi7DAAAAADAu8u7y7vLu8u7y9y8u7u7u7vLAAAAAADAvMu8y7zLvMu8y9y7u7u7u8sMAAAAAADQ293b3dvd293b3by7u7u7y8wAAAA="},"pyQName":"sprites.castle.house_blue"},"sprites.castle.princessFront0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAADwAAAAAAAA/2//AAAA8P9mZt//DwAfZv/23T8P8GH23T/zM/9VZf8//TVT/1Bi3939UzMPVWXf3f1TMw/wYf8//TVT//AW9t0/8zP/AG9h//bdPw8A8P9mZt//DwAAAP9v/wAAAAAAAPAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess_front0"},"sprites.castle.princessFront1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAADwAAAAAAAA/28PAAAA8P9mZv//AAAfZv/20/0P8GH23T/zPw9VZf8//TVTD1Bi3939UzMPVWXf3f1TMw/wYf8//TVT//AW9t0/8zP/AG9h//b9Pw8A8P9mZt//DwAAAP9v/wAAAAAAAPAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess_front1"},"sprites.castle.princessFront2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAADwAAAAAAAA/2//AAAA8P9mZt//DwAfZv/2/T8P8GH23T/zM/9VZf8//TVT/1Bi3939UzMPVWXf3f1TMw/wYf8//TVTD/AW9t0/8z8PAG9h//bT/Q8A8P9mZv//AAAAAP9vDwAAAAAAAPAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess_front2"},"sprites.castle.princessLeft0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P//AAAAAABv1t0P//AP8Gb2P/01Pw9VYtbd/TNT81BlZtZd8z/zVRVmZj/f/f/wZmFm///fDwBvFmZmD/AAAPD//28PAAAAAABvbw8AAAAAAPDwAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess_left0"},"sprites.castle.princessLeft1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8PAAAAAPBm3f3wD/8Ab2b/09/9/1AlZt3d3/3/AFVmZt3T/fNQVWFm9tPf8wBvFmb2/1P/APBmYWb/P/8AAP////bwAAAAAPD29gAAAAAAAA8PAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess_left1"},"sprites.castle.princessLeft2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8PAAAAAPBm3f3wDw8Ab2b/01/z81AlZt3dPzPzAFVmZt0zU/NQVWFm9tP/8wBvFmb23/3/APBmYWb//QAAAP////YPAAAAAPD29gAAAAAAAA8PAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess_left2"},"sprites.castle.princessBack0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAPAAAAAAAA8PbwAAAA8P//9t8PAABvZmb23f8P8BZmZj/1P/NQFmZm9jM181UWZmb2M1PzVWZmZvYzU/NQFmZm9jM18/BmZmY/9T/zAG9mZvbd/w8A8P//9t8PAAAAAPD28AAAAAAAAA8AAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess_back0"},"sprites.castle.princessBack1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAG8PAAAAAP//b/8AAADwZmZm3/8PAG9hZvbzMw8AZWFmZj8181BlYWZmP1PzUGVmZmY/Uw8AZWFmZj8/DwBvZmb21f0AAPBmZmbf/QAAAP//b/8PAAAAAABvDwAAAAAAAPAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess_back1"},"sprites.castle.princessBack2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAG8PAAAAAP//b/8PAADwZmZm3/0AAG9hZvbV/QAAZWFmZj8/D1BlYWZmP1MPUGVmZmY/U/MAZWFmZj818wBvZmb28zMPAPBmZmbf/w8AAP//b/8AAAAAAABvDwAAAAAAAPAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess_back2"},"sprites.castle.princess2Front":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAA8A8AAAAA8P//+wAAAPA/s7vr7gAAvzOzu+/0D/A+4//+/7wPX+Szv0G/3fFPRTP+T969/VRF4+5E3t2xVEXj7kTevb1PRTP+T97d8V/ks79Bv7398D7j//7/vA8AvzOzu+/0DwDwP7O76+4AAADw///7AAAAAAAA8A8AAA=="},"pyQName":"sprites.castle.princess2_front"},"sprites.castle.princess2WalkFront1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAA/wAAAAAA8P+/DwAAAADvs7v7DwAA8Dszu0v+DwDvM/7vTuQP8EU++xtO5PHwVDTj/+Te/U9VNO5O1N3xT1U07k7Uvb3wVDTj/9TdsfBFPvsbtL3xAO8z/u//vA8A8Dszu+v0DwAA77O7++4AAADw/78PAAAAAAAA/wAAAA=="},"pyQName":"sprites.castle.princess2_walk_front1"},"sprites.castle.princess2WalkFront2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAA8A8AAAAA8P//+wAAAPA/s7vr7gAAvzOzu+/0D/A+4//+/7wPX+Szv0G/3fFPRTP+T969/VRF4+5E3t2xVEXj7kTevb1PRTP+T97d8V/ks79Bv7398D7j//7/vA8AvzOzu+/0DwDwP7O76+4AAADw///7AAAAAAAA8A8AAA=="},"pyQName":"sprites.castle.princess2_walk_front2"},"sprites.castle.princess2WalkFront3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAA/wAAAAAA8P+/DwAAAADvs7v77gAA8Dszu+v0DwDvM/7v/7wP8EU++xu0vfHwVDTj/9TdsU9VNO5O1L29T1U07k7U3fHwVDTj/+Te/fBFPvsbTuTxAO8z/u9O5A8A8Dszu0v+DwAA77O7+w8AAADw/78PAAAAAAAA/wAAAA=="},"pyQName":"sprites.castle.princess2_walk_front3"},"sprites.castle.princess2Back":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAA8A8AAAAA8P/P+wAAAPA/u7vL7gAAvzOzu8v0D/A+MzO7u7wPXzMzM7u73/FPMzMzu7u//VQzMzO7u9+xVDMzM7u7v71PMzMzu7vf8V8zMzO7u7/98D4zM7u7vA8AvzOzu8v0DwDwP7u7y+4AAADw/8/7AAAAAAAA8A8AAA=="},"pyQName":"sprites.castle.princess2_back"},"sprites.castle.princess2WalkBack1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAA8P8AAAAAAP/P+w8AAAD/u7u7DAAA8Duzu7v8DwDvMzO7u7wP8DUzM7u7v/HwNDMzu7vfsUA1MzO7u7+9QDUzM7u73/HwNDMzu7vf/fA1MzO7u+/+AO8zM7u7Tw4A8Duzu8tODwAA/7u7/OwAAAAA//8PAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess2_walk_back1"},"sprites.castle.princess2WalkBack2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAA8A8AAAAA8P/P+wAAAPA/u7vL7gAAvzOzu8v0D/A+MzO7u7wPXzMzM7u73/FPMzMzu7u//VQzMzO7u9+xVDMzM7u7v71PMzMzu7vf8V8zMzO7u7/98D4zM7u7vA8AvzOzu8v0DwDwP7u7y+4AAADw/8/7AAAAAAAA8A8AAA=="},"pyQName":"sprites.castle.princess2_walk_back2"},"sprites.castle.princess2WalkBack3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAP//DwAAAAD/u7v87AAA8Duzu8tODwDvMzO7u08O8DUzM7u77/7wNDMzu7vf/UA1MzO7u9/xQDUzM7u7v73wNDMzu7vfsfA1MzO7u7/xAO8zM7u7vA8A8Duzu7v8DwAA/7u7uwwAAAAA/8/7DwAAAAAA8P8AAA=="},"pyQName":"sprites.castle.princess2_walk_back3"},"sprites.castle.princess2Left1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAA8P8AAAAA8P8/Mw8A8A9P5TPj/v+/D1RF4+5E3t3xVEXj7kTevf1PRTP+T97dsV/ks79B7769/z7j//5P5PG/MzOzu0/k/fAzM7O7+74P8Dszs7u7/w8AvzOzu7sPAADw////+wAAAAAAAPAPAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess2_left1"},"sprites.castle.princess2Left2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAA8P8AAAAAAP8/Mw8A8A/wVD4z7v/f+0BVNO5O1N39QFU07k7U3fHwVDTj/9S9vfBFPvsb5L6x8O8z/u9P5P3wOzMzu0vk/QA/MzO7u7/7AL8zM7u7vw8A8Dszu7v/AAAA//+/+wAAAAAAAP8PAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess2_left2"},"sprites.castle.princess2Right1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAADwDwAAAPD////7AAAAvzOzu7sPAPA7M7O7u/8P8DMzs7v7vg+/MzOzu0/k/f8+4//+T+TxX+Szv0Hvvr1PRTP+T97dsVRF4+5E3r39VEXj7kTe3fFP5TPj/v+/D/D/PzMPAPAPAADw/wAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess2_right1"},"sprites.castle.princess2Right2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAD/DwAAAAD//7/7AAAA8Dszu7v/AAC/MzO7u78PAD8zM7u7v/vwOzMzu0vk/fDvM/7vT+T98EU++xvkvrHwVDTj/9S9vUBVNO5O1N3xQFU07k7U3f3wVD4z7v/f+wD/PzMPAPAPAADw/wAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.castle.princess2_right2"},"sprites.castle.rock0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAzMwAAAAAAMzLywwAAAAA3Lu8zAAAAMzcvbzMAMDMu7zdzMwAvN27y93LzADc3d2728vMDNvd3bvby7wM293du9u7vMvb3d2929u8y7Dd3b3b27zLANvdvb3bvMsA2927vb27DACwu7u7zbsMAAAA293MywAAAACwy7wLAA=="}},"sprites.castle.rock1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAMDMAAAAAADLvMwMAAAAsNvLywwAAAC73c3LDACwy8zdzcvMALDdzN3Nzcuw293L27vNy7Dd3bvb28vLsN3d27vdzMvb3d3b27u8y9vdvb27vLvL2727zcu8u8vbvdvLzLy7DLDbvczMu8sMAADLzLzLzAAAAAAAzMwMAA=="}},"sprites.castle.rock2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADADLALAMALALvM27sAuwyw3cvbzQDdDLDdy7DNANsLsN27sMsAsADL27sAvAAAsN3MDAAAuwCw3csMALC9AMu7y7wL272wzLzMwAzbzbu9zAC7zNvL293LsL3Lu8zbvcuw3cu7vNu9y7Ddu8sLsLsMALsLuwAAAAAAsAAAAA=="}},"sprites.castle.saplingOak":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADMDAAAAAAAzMbMDAAAAMBmZszMAAAAwGZnbMYAAABsdmdm9gwAAGx3dmf8TwDAZndnZ2b8DsBnV3fGZvzuwHd3Z2fM/O7AVWdmZ/bPAGBVd2dn/AzgAHZ1Z2bG7wQAxnZWZ8YPAADAbHbG/AAAAADMZsYMAAAAAMDMzAAAAA=="},"pyQName":"sprites.castle.sapling_oak"},"sprites.castle.saplingPine":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADMAAAAAAAAYMfMDAAAAABsx3wMAAAAYGxndwwAAMDMx2ZmzAAOwMZnbGZ35g7AfHfHdsfvAGxVd2xm9u7uXFV3Zmb/7u7AfHVnd8fuAGDHZ2Z3d+wOYGbHd2fMAA4AYMx3dwwAAAAAZmd8DAAAAABgZ8YMAAAAAABmAAAAAA=="},"pyQName":"sprites.castle.sapling_pine"},"sprites.castle.shrub":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAGZgZgwAAAAAZsx2xmwAAGB2bHfMZgYAYHVsd1x3ZgDMdWZnVnVmwMZVZmx3ZcZmZ3ZnzGZmDHZVZ8bMfFdmdld1xsx8V2dmZ1ZlzGZmZsDGVWdsd2UMAMx1ZmdWdcYAYHdsd1x3ZgBgdmx3zGYGAAB2xnbGbAAAAGZgZgwAAA=="}},"sprites.castle.skellyFront":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAAAAAAAAAAwLEAAAAAAAAA//8PH/sAAAAAAAD/3b38H7EAAAAAAPAbEd29H/sAAAAAAPAREb0czPEPAAAAAB8REfEfvf8PAAAAAB8REdER+///AAAAAB8REdERsf//AAAAAB8REfEf+///AAAAAPAREb0czbEPAAAAAPAbEd29H/sAAAAAAAD/3b38H7EAAAAAAAAA//8PH/sAAAAAAAAAAAAAz7EAAAAAAAAAAAAA8P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_front"},"sprites.castle.skellyWalkFront1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAAAAAAAAAAwLEAAAAAAAAA//8PH/sAAAAAAAD/3b38H7EAAAAAAPAbEd29H/sAAAAAAPAREb0czPEPAAAAAB8REfEfvf//AAAAAB8REdER+///AAAAAB8REdERsf//AAAAAB8REfEf+/8PAAAAAPAREb0cHPsAAAAAAPAbEd39sQ8AAAAAAAD/3b38EQsAAAAAAAAA////sQ8AAAAAAAAAAADwHAsAAAAAAAAAAAAA/w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_walk_front1"},"sprites.castle.skellyWalkFront2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAAAAAAAAAAwLEAAAAAAAAA//8PH/sAAAAAAAD/3b38H7EAAAAAAPAbEd29H/sAAAAAAPAREb0czPEPAAAAAB8REfEfvf8PAAAAAB8REdER+///AAAAAB8REdERsf//AAAAAB8REfEf+///AAAAAPAREb0czbEPAAAAAPAbEd29H/sAAAAAAAD/3b38H7EAAAAAAAAA//8PH/sAAAAAAAAAAAAAz7EAAAAAAAAAAAAA8P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_walk_front2"},"sprites.castle.skellyWalkFront3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/w8AAAAAAAAAAADwHAsAAAAAAAAA////sQ8AAAAAAAD/3b38EQsAAAAAAPAbEd39sQ8AAAAAAPAREb0czPsAAAAAAB8REfEfvf8PAAAAAB8REdER+///AAAAAB8REdERsf//AAAAAB8REfEf+///AAAAAPAREb0czfEPAAAAAPAbEd29H/sAAAAAAAD/3b38H7EAAAAAAAAA//8PH/sAAAAAAAAAAAAAwLEAAAAAAAAAAAAA8P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_walk_front3"},"sprites.castle.skellyAttackFront1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAAAAAAAAAAwLEAAAAAAAAAAAAAH/sAAAAAAAAAAAAAH7EPAAAAAAAAAADwH/vMDwAAAAAAAAC/zPHP/w8AAAAAAAAf0cux//8PAAAAAPAREfHR+///AAAAAPARERGx////DwAAAPARERER+///DwAAAPAREfGx////DwAAAAAfEc0R/c+xDwAAAAC/Ed37/x/7AAAAAADwH93LDx+xAAAAAAAA8P//AB/7AAAAAAAAAAAAAM+xAAAAAAAAAAAAAPD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_attack_front1"},"sprites.castle.skellyAttackFront2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHB3dwAAAAAAAAAAAAcAd/f/AAAAAAAAAAAAcMfRDwAAAAAA8P///7/8AAAAAADw393dyx/RDwAAAAC/ERHR3b/8AAAAAAAfERHRy8vRDwAAAPARERER//3/AAAAAPARERERHfv/AAAAAPARERERHfH/AAAAAPARERER//v/AAAAAAAfERHRy/3/AAAAAAC/ERHR3f8PAAAAAADw393dyw8AAAAAAAAA8P///wwAAAAAAAAAAADwvA8AAAAAAAAAAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_attack_front2"},"sprites.castle.skellyAttackFront3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAA//8AAM8PAAAAAAD/3c3/AL8PAAAAAPAbEdH7/x8LAAAAAPAREdG8/L8PAAAAAB8RERHf+88PAAAAAB8RERGx//8AAAAAAB8RERER+/8AAAAAAB8RERG///8AAAAAAPAREdHc/f8AAAAAAPAbEdH7/w8AAAAAAAD/0c3/AAAAAAAAAAAA///7AAAAAAAAAAAAAPD7AAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_attack_front3"},"sprites.castle.skellyAttackFront4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAAAA//8AABwPAAAAAAD/3cv/8LsPAAAAAPAb0d37/xELAAAAAPAREb28/LsPAAAAAB8REfEf/RwPAAAAAB8REdER+/8AAAAAAB8REdER8f8AAAAAAB8REfEf+/8AAAAAAPAREb28/f8AAAAAAPAb0d3L/w8AAAAAAAD/3b3/+wAAAAAAAAAA//+/ywAAAAAAAAAAAADP+wAAAAAAAAAAAADwDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_attack_front4"},"sprites.castle.skellyWalkLeft1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8PAAAAAAAAAAD/3d37/wAAAAAAAPAbEREdsQ8AAAAAAPAREdEd+/8AAAAAAB8REfEfwbEPAAAAAB8REb0cH/sPAAAAAB8REd0dH7H/AAAAAB8REd27H/v/AAAAAPAR0d27v///AAAAAPDb3d3L////AAAAAAD/3b38AAD/AAAAAAAA//8PAPAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_walk_left1"},"sprites.castle.skellyAttackLeft1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////DwAAAAAAAAD/3RuxDwAAAAAAAPAbERH7DwAAAAAAAPARERGx//8AAAAAAB8RER/7//8PAAAAAB8R0RzN////AAAAAB8R0b3/////AAAAAB8REf/M////AAAAAL8RwbHP////AAAAAPARH/vPD/D/AAAAAPAbH7H/AAD/AAAAAAD/H/sPAAD/AAAAAAAAv/8AAPAPAAAAAAAA8A8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_attack_left1"},"sprites.castle.skellyAttackLeft2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8AAAAAAAAAAAAAz9EPAAAAAADw////v/sAAAAAAPDf3d29H9EPAAAAAL8RERHRv/0AAAAAAB8REdHdvAwAAAAA8BEREdH/vA8AAAAA8BER0d3L/f8AAAAA8BER0d3dzf8AAAAA8BER0d29+/8PAAAAAB8R3d27//8PAAAAAL/d3d3L//8PAAAAAPDb3b3///8PAAAAAAD///8PAP8PAAAAAAAAAAAAAPAPAAAAAAAAAAAAAPAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_attack_left2"},"sprites.castle.skellyWalkLeft2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw/wAAAAAAAAAA//+/sQ8AAAAAAAD/3R0R+w8AAAAAAPAbERERsQ//AAAAAB8REREf+w+xAAAAAB8REd0c/Q/7AAAAAB8REd29//+xAAAAAB8REd3d/P/7AAAAAB8R0d3d////AAAAAPAR3d3d////AAAAAPDb3d29////AAAAAAC/3d398P//AAAAAADw//8PAPD/AAAAAAAAAAAAAP8PAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_walk_left2"},"sprites.castle.skellyWalkRight1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAP8PAAAAAADw//8PAPD/AAAAAAC/3d398P//AAAAAPDb3d29////AAAAAPAR3d3d////AAAAAB8R0d3d////AAAAAB8REd3d/P/7AAAAAB8REd29//+xAAAAAB8REd0c/Q/7AAAAAB8REREf+w+xAAAAAPAbERERsQ//AAAAAAD/3R0R+w8AAAAAAAAA//+/sQ8AAAAAAAAAAADw/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_walk_right1"},"sprites.castle.skellyAttackRight1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAPAAAAAAAAAAAAAAAPAPAAAAAAD///8PAP8PAAAAAPDb3b3///8PAAAAAL/d3d3L//8PAAAAAB8R3d27//8PAAAA8BER0d29+/8PAAAA8BER0d3dzf8AAAAA8BER0d3L/f8AAAAA8BEREdH/vA8AAAAAAB8REdHdvAwAAAAAAL8RERHRv/0AAAAAAPDf3d29H9EPAAAAAADw////v/sAAAAAAAAAAAAAz9EPAAAAAAAAAAAA8P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_attack_right1"},"sprites.castle.skellyAttackRight2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8A8AAAAAAAAAAAAAv/8AAPAPAAAAAAD/H/sPAAD/AAAAAPAbH7H/AAD/AAAAAPARH/vPD/D/AAAAAL8RwbHP////AAAAAB8REf/M////AAAAAB8R0b3/////AAAAAB8R0RzN////AAAAAB8RER/7//8PAAAAAPARERGx//8AAAAAAPAbERH7DwAAAAAAAAD/3RuxDwAAAAAAAAAA////DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_attack_right2"},"sprites.castle.skellyWalkRight2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8PAPAPAAAAAAD/3b38AAD/AAAAAPDb3d3L////AAAAAPAR0d27v///AAAAAB8REd27H/v/AAAAAB8REd0dH7H/AAAAAB8REb0cH/sPAAAAAB8REfEfwbEPAAAAAPAREdEd+/8AAAAAAPAbEREdsQ8AAAAAAAD/3d37/wAAAAAAAAAA//8PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.castle.skelly_walk_right2"},"sprites.castle.tileGrass2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB1d3d3d3d3d3d30XZ3F3Z3dTcRY3dxcVd3EXbRdxd2d3cRdtF3d3d3dzcRY3d3d3d3d9F2F3Z3d3d3d3dxcXd3d3d3dxd2d3d3V2V3d3d3d3d3d1d1F213d3d3VXYTMXZ3YXdnF2EXfRcXd3cXYRd9d2F3d3cTMXZ3d3d3dxdtdw=="},"pyQName":"sprites.castle.tile_grass2"},"sprites.castle.tilePath1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB3d3d3d3d3d3dndmd21nZmd3dm3W3dbd131t3d3d3d3Wfd3d3d3d3bd9bd3d3d3d131t29293d3WfW3b3b3d3dZ93d3d3d3d1n3d3d3d3d3XfW3d3dHdHdZ93d3dEd0d131t3d3d3d3Xfd293d3d3dZ9fd3d3R3d131t3d3d3d2w=="},"pyQName":"sprites.castle.tile_path1"},"sprites.castle.tilePath2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABn3d3d3d3d3WfdHdHd3d3dd9Yd0d293d1n193d3d3d3XfXHd3d3d3dZ9bd3d3d3d13Z93dvd3d3Wfd3d3d3d3RZ93d3d3d3d3X3d3d3d3d3WfXHd3d3d3dd9bd3d2929133d3d3b3b3WfW3d3d3d3dd2fd3R3d3R131t3d3d3d3Q=="},"pyQName":"sprites.castle.tile_path2"},"sprites.castle.tilePath3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADX3d3R3d3d3Wfd3d3d3d3dd9bd3d3d3d1n1t3dvdvd3Wfd2929293dd93d3d3d3dt31t3d3d3d3XfW3d3d3d3dZ9bd0d3d3d3X3d3d293d3WfdEd3d3dHdd9YR3d3d3d1n3d3d1t3d3XfWbd1n3Wbdd2d2ZndmZ213d3d3d3d3dw=="},"pyQName":"sprites.castle.tile_path3"},"sprites.castle.tileGrass1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB3d3d3d3d3d3d2d3d3d3d3V2V3d3d3d3d3VXZ3d1V2d1V3d3d3d3d3V3V3d3d3d3d3V3V3d3d3d3dVdnd3d3d3d2V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1dld3d3d3d3d3d3d1d3d3d3d3d3d3d3d3d3d3d3dw=="},"pyQName":"sprites.castle.tile_grass1"},"sprites.castle.tilePath4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB3d3d3d3d3d2dnd2d21nZ2Zmdm3W3dbdbd1tbd3b3d1t3d3d3d3d3d3d3d3d3d3d0R3d3d3d3d3RHdvd3d3d3d3d3d3d0d3dvd3d3d3RHR3d3R3d3dHd3d3d3d3d3d3d3d3d3du93d3d3d3d273d3d3d3d3d3d3d3d3d3R3d3dHQ=="},"pyQName":"sprites.castle.tile_path4"},"sprites.castle.tilePath5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADd3d3d3R3R3d3d3d3dHdHd3d3b3d3d3d0d0d3d3d3d3R3R3d3d3d3d3d3d3dvd3d3d3d3d3d0d3d3d3d3d3d3d3d3d3d3d3d3d3bvd3d3d3d3du93d3d3d3d3d3d3d3d3d3d3d3d3b3b3d3d3d3d3d3d3d3d3d3b3d3d3d3d3d3Q=="},"pyQName":"sprites.castle.tile_path5"},"sprites.castle.tilePath6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADd3d3d0d3d3d0d3d3d3d3d3RHR3d3d3dHdHd3d3d3d3d3d3d29293d3d3d3b3b3d3d3d3d3d3d3d3d3d3d3d3d3b3d3d3d3d3d3d3d3d3d3d3d3d3d3dvd3d3d0d3d3d3d3d3dbd3d3d3W3WZ91m3WZmdtZ3Z2bWd3d3d3d3d3dw=="},"pyQName":"sprites.castle.tile_path6"},"sprites.castle.tileGrass3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB1d3d3d3d3d3d3d3d3d3d3dXdnd1d3d1d3d1V2d3d3d3d3V2V3d3d3d1d1d3d3d3d3d1V3d3d3d3d3d1V3d3d3d3dXZXd3dXd3d1d2d3dVd3d3d3d3V1d3d3d3d3dVdnd3d3V3d2V3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3VQ=="},"pyQName":"sprites.castle.tile_grass3"},"sprites.castle.tilePath7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB3d3d3d3d3d9Z2ZndmZ3Z33Wbddt3WbXfd3d1t3d3ddt3d3d2922133d3d3b3b3XbdHd3d3d3dfd3d3d3d3W123d3d3d3dbXfd3d3d3d1td90R3d3d3d133RHd3dvd3Xbd3d3d3d1tdt3d3d3dEW133d3d3d0R3Xbd3d3b3d3dfQ=="},"pyQName":"sprites.castle.tile_path7"},"sprites.castle.tilePath8":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADd3d3d3d1td9Hd3dHd3XZ33d3d3d3dbXbd3d3d3dvdd93d3d3d3W133d3du93dfXbd29273d3dfd3d3d3d3d123d3d3d3d3Xbd3d3d3d12d93d3d3d3W123d3d3d3RfXfdEd3d3d19dt0R3d3d3W133d3dvd3d3Xbd3d3d3d3ddg=="},"pyQName":"sprites.castle.tile_path8"},"sprites.castle.tilePath9":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC93d3d3d1td93d3R3R3X123d3dHdG93Xfd3d3d3d1td93d3d3d3d123dHd3d3dbXfd3d3d3d3ddt3d3d3R3d123d3d3d3dbXbd3bvd3d1td93du93d3W133d3d3d0d3Xbd3d3d3d1td93W3dbdZnd3ZmdtZ3Zndnd3d3d3d3d3dw=="},"pyQName":"sprites.castle.tile_path9"},"sprites.castle.tileDarkGrass1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABnZmZmZmZmZmZmZmZmZmZmZ2aGZnZmZnZmZndoZmZmZmZmdodmZmZmZnZnZmZmZmZmZndmZmZmZmZmZndmZmZmZmZ2h2ZmZ2ZmZnZoZmZ3ZmZmZmZmdnZmZmZmZmZ3aGZmZmdmZodmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdw=="},"pyQName":"sprites.castle.tile_dark_grass1"},"sprites.castle.tileDarkGrass2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABnZmZmZmZmZmZm0WhmFmhmZzYRg2ZhYXZmEWjRZhZoZmYRaNFmZmZmZjYRg2ZmZmZmZtFoFmhmZmZmZmZhYWZmZmZmZhZoZmZmdodmZmZmZmZmZnZnFo1mZmZmd2gTMWhmgWaGFoEWbRYWZmYWgRZtZoFmZmYTMWhmZmZmZhaNZg=="},"pyQName":"sprites.castle.tile_dark_grass2"},"sprites.castle.tileDarkGrass3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABmZmZmZmZmZmZoZmZmZmZmdodmZmZmZmZmd2hmZndoZndmZmZmZmZmdmdmZmZmZmZmdmdmZmZmZmZ3aGZmZmZmZodmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnaHZmZmZmZmZmZmZnZmZmZmZmZmZmZmZmZmZmZmZg=="},"pyQName":"sprites.castle.tile_dark_grass3"},"sprites.castle.treePine":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAAAAAwAwAAAAAAAAAAAAAAAAAYMbGDAAAAAAAAAAAAAAAAGBnZgwAAAAAAAAAAAAAAABsZ3ZmbAAAAAAAAAAAAADAzGd3ZswAAAAAAAAAAADAbMdmd3bHAAAAAAAAAAAAfHxnxmd2xgYAAAAAAAAAAHZmZ8dmZ8wMAAAAAAAAAMx2ZnbHZsZmzAAAAAAAAGDHzGx2bMdmdswAAAAAAABsx3xsZnbHZnfHAPAAAABgbGd3bGZ3xmZmbAzwAADAzMdmZsxmZmZmZnYM7wAAwMZnbGZ3ZnZnbGZ3Z+8PAMB8d8d2x2Z3d2xmd8fu/g9sVXdsZmx3d8ZmZsZs7u7+XFV3ZmZ2d2dsZmZnZu7+D8B8dWd3Z3d3d2Z2d2fuDwBgx2dmd3d2d2dmd3dn7w8AYGbHVWdsd3fGdmZ2BuAOAABgzFd3fHd3x3Z3bAbwAAAAAGZlfHZ3dmdmd8cAAAAAAABgZ2Z2d2ZnZnbHAAAAAAAAAGZ3dnbHbHfGZgAAAAAAAAAAdnZmx2Z3dwwAAAAAAAAAAHZ2Z3ZnZncMAAAAAAAAAABgZnx3d2xnAAAAAAAAAAAAAGB2Z3fMZgAAAAAAAAAAAAAAZnd2xmwAAAAAAAAAAAAAAGBnbMYAAAAAAAAAAAAAAABgZsbGAAAAAAAAAAAAAAAAAGAGAAAAAAAAAA=="},"pyQName":"sprites.castle.tree_pine"},"sprites.castle.treeOak":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAABsDMxgwAAAAAAAAAAAAAYGbMbMZsDAAAAAAAAAAAAGBmdmfGZwwAAAAAAAAAAABmZndmdmfMDAAAAAAAAAAAZndmZmfGxswMAAAAAAAAZnZ3ZnZnZsZmDAAAAAAAYHd2Z2d2dnd2x8wAAAAAAGB3ZnZnZnZnd8bMDAAAAABgZnd3Z3dmZsZszAwAAAAAZnZ3d3Z3dmdmd8YAAA4AYHd2d3d3d3d3dmfMDAAOAGB3dnd3d3d3Z2bGZswADgBgd3d3dXd3d3Z3ZmbG8P4AZld1V3V3d2Z3Z2bGzO/+AGZXVVd3d3dnd2Z3Zsbu/wB2d1V3d3d3d2ZmdmfM7v4PdndXVVV3d3dnZmbGzO7u7mB3VXdVdXd3Z3Z3Zszu7g5gV1VXd3d3ZmZmd2fG7v8AAHZ3V3V3d2d3Z8bMzP4PAGB3d1d1d3d3dndmzMzgDgBgd3d3dXdnZmZmZsYMAO4AYHd2d3d3Z3dmZ8bMDADgAGBmd3d3d2d3Z3dmzAAAAAAAYHd2d3Z3dmd2ZswMAAAAAGBndndnd2ZmZmzGDAAAAAAAZmZ2Z2Z3Z2bGzAAAAAAAAHZ2Z2dmdmdsxgwAAAAAAAB2dndmZ2ZmzMYMAAAAAAAAYGBmZnfGxswMAAAAAAAAAAAAZmB2xszMDAAAAAAAAAAAAGDAbMYMAAAAAAAAAA=="},"pyQName":"sprites.castle.tree_oak"},"sprites.castle.treeSmallPine":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABgAAAAAAAAAAADAzAAAAAAAAAAAwMxsxwwAAAAAAGDMbGd8d8YAAAAAAMxnfHdnd8cMAAAAzGx2xnfHd2YMAADAxmZ2x3bGdmfMAA5sZ2x2d3ZndnfG4A5cd3Z2Z3Z3dmfM7u52dXZ3Z3ZndmbG7u5mZ3Z2d3ZmdmfG4A7AZsd2Z3dndnfMAA4AbMx3Zndnd2cMAAAAAGxnfHdmd2YMAAAAAMDGbGd2d8cAAAAAAAAAwGx2ZwwAAAAAAAAAAABmxgAAAAA="},"pyQName":"sprites.castle.tree_small_pine"},"sprites.builtin":{"kind":5,"retType":""},"sprites.builtin.angelFish0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAD/AAAAAAAAwP0AAAAAAMDM/QAAAADAzNz9AAAAzBzR3fEAAMC7EREREQ8AXLsRERwRD8BVuxsREREPwFW7u7sRsfXAVRsRERG79cBVuxGxu1v1wFW1ERERW/XAXMXMW/tf9QBcxQBbu/D/AMAMAFxVDAAAAAAAzMwMAA=="},"pyQName":"sprites.builtin.angel_fish0"},"sprites.builtin.angelFish1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAPAPAAAAAAAA3A8AAAAAAMDcDwAAAADMzN3xAAAAzBHdHfEAAMAbEREREQ8AXBsRwRERDwBcuxsREREPwFW7u7sRsfXAVRsREbG79cBVuxGxu7v1wFW1ERERW/XAVcXMW/tf9QBcxQBbC/D/AMAMwFXFAAAAAADAzMwAAA=="},"pyQName":"sprites.builtin.angel_fish1"},"sprites.builtin.angelFish2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAA/AAAAAAAAADcDwAAAAAAwNwPAAAAAMzM3fEAAADMEd0dEQ8AALwRERERDwDAtRHBERHxAMC1GxEREVEPwLW7uxsRWw9ctREREbtbD1y1GxG7u1UPXFUbERGxVQ9cVcy8tf//D8xVDLu1AAAAwMzAVcUAAAAAAMDMzAAAAA=="},"pyQName":"sprites.builtin.angel_fish2"},"sprites.builtin.angelFish3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAP8AAAAAAADA/QAAAAAAAMz9AAAAAMDM3B0PAADAHNHdEQ8AALwRERER8QDAtRERHBHxAMC1uxEREfEAXLW7uxsRWw9ctREREbtbD1y1GxG7u1sPXFUbERGxVQ9cVcy8tf9VD8BVDLC1AP8PAMwAXFUMAAAAAADMzAwAAA=="},"pyQName":"sprites.builtin.angel_fish3"},"sprites.builtin.aquaticBackground":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAACZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3dfXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d19d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3Xd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3X13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d13d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3dd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3c="},"pyQName":"sprites.builtin.aquatic_background"},"sprites.builtin.bed0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABgAAAAAAADw///////MDAAAy/xvxrvb3d29zQ+w3btrtrvd3d3bzfvbvczMvDMRERHbzfvbG83dPNMRERHdzQ/cGxvROxMREdHdzQvcGxsROxMREbHdzQvcGxsROxMREbHdzQvcGxsROxMREbHdzQvcGxsROxMREbHdzQvcGxvROxMREdHdzQsbG83dPNMRERHdzQ/bvczMvDMRERHbzfuw3btrtrvd3d3bzfsAy/xvxrvb3d29zQ8AAADw///////PDAA="}},"sprites.builtin.bed1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABgAAAAAAADw///////MDAAAy/xvxrvb3d29zQ+w3bvMtrvd3d3bzfvbvbzdvDMRERHbzfvbG9vRO9MRERHdzQ/cGxsROxMREdHdzQvcGxsROxMREbHdzQvcGxsROxMREbHdzQvcGxsROxMREbHdzQvcGxsROxMREbHdzQvcGxsROxMREdHdzQsbG9vRO9MRERHdzQ/bvbzdvDMRERHbzfuw3bvMvLvd3d3bzfsAy/xvxrvb3d29zQ8AAADw///////PDAA="}},"sprites.builtin.bed2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABgAAAAAAADw///////MDAAAy8xvxrvb3d3LzA+w3btrvLvd3b3dy/vbvbvMvDMREdu9zPvbu8vdPNMREdu7zA/cuxzROxMREdy7zAvcuxwROxMREdy7zAvcuxwROxMREdy7zAvcuxwROxMREdy7zAvcuxwROxMREdy7zAvcuxzROxMREdy7zAsbu8vdPNMRERu7zA/bvbvMvDMREdu9zPuw3btrvLvd3b3dy/sAy8xvxrvb3d3LzA8AAADw///////PDAA="}},"sprites.builtin.bigButtonPress0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"electronics","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8////DwAAAAAAAAAAAADAzIyIZvb/AAAAAABmiIiIyLu7zMxs9g8AAABmZoiIiIjMu8vMzGz/AABgdnd3mXlmxry7zMzM9gAAZnd3d3eZZ2bMu8zMzMwPAHZ3d3d3l2lmxrvLzMzMD2B2d3d3iHd5Zsa8y8zMzPxgd3eXiYh3mWZmvLvMzMz8Znd3mYZod5dnZsy9zMzM/HZ3l2mGdneXaWbM3czMzPx2d5lmiHd3l2lmzN3MzMz7dndphoh5d5dpZszdvLu7+3aXZmiIeXeXaWbM3by7u/t2l4Z3iHl3l2lmzN28u7v7dpeGd4h5d5dpZszdu7u7+3aXZmiIeXeXaWbM3bu7u/t2d2mGiHl3l2lmzN27u7v7dncZYYh3d5dpZszdu7u7+3Z3F2GGdneXaWbM3bu7u/tmd3eZhmh3l2dmzN27u7v7YHd3l4mId5lmZrzdu7u7+2B2d3d3iHdxZsYc0bu7u/sAdnd3d3cXYWbGG9Hb3d0PAGZ3d3d3GWdmzB2x3d29DwBgdnd3mXlmxrzdvbu7+wAAAGZmiIiIiMzb3czMzP8AAAAAZoiIiMi73cvMzPwPAAAAAAAAAADAzMzMzPz/AAAAAAAAAAAAAPz///8PAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.builtin.big_button_press0"},"sprites.builtin.bigButtonPress1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"electronics","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8////DwAAAAAAAAAAAADAzIyIZvb/AAAAAAAAAICIyLu7zMxs9g8AAAAAAICIiIjMu8vMzGz/AAAAAACIZmZmyLy7zMzM9gAAAACAeGZmZobMu8zMzMwPAAAAgGdmZndmyLvLzMzMDwAAAIhnZnaHaMi8y8zMzPwAAAB4ZmZ3iGiGvLvMzMz8AACAeGZ2h4hmhsy9zMzM/AAAgGdmd4hoZobM3czMzPwAAIBndoeIaGaGzN3MzMz7AACAZ3aIiHhmhszdvLu7+wAAgGeHiIZ4ZobM3by7u/sAAIBnh3iHeGaGzN28u7v7AACAZ4d4h3hmhszdu7u7+wAAgGeHiIZ4ZobM3bu7u/sAAIBndoiIeGaGzN27u7v7AACAZ3aZiGhmhszdu7u7+wAAgGdmmYhoZobM3bu7u/sAAIB4ZnaHiGaGzN27u7v7AAAAeGZmd4hohrwRu7u7+wAAAIhnZnaHaMgcEbu7u/sAAACAZ2Zmd2bIG9Hb3d0PAAAAgHhmZmaGzN293d29DwAAAACIZ2ZmyLzdvbu7+wAAAAAAgIiIiMzb3czMzP8AAAAAAACAiMi73cvMzPwPAAAAAAAAAADAzMzMzPz/AAAAAAAAAAAAAPz///8PAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.builtin.big_button_press1"},"sprites.builtin.brick":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADdHd0d3R3dHRER3R0REd0d3R3dHd0d3R3dHd0d3R3dHd0d3R3dHd0d3R0REd0dERHdHd0d3R3dHd0d3R3dHd0d3R3dHd0d3R0REd0dERHdHd0d3R3dHd0d3R3dHd0d3R3dHd0d3R3dHd0dERHdHRER3R3dHd0d3R3dHd0d3R3dHQ=="}},"sprites.builtin.cat0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOAA4AAADOzO/+DwAAAN472937//8A3r3T3y3b/QDA3d39Ld0PAADf3d0r3Q8AAL/d3Svd/wDA3d39Ld39AN69098tvQ8A3jvb3bLdDwDOzO/+v9v9AAAAAADw+/8AAAAA+//9AAAAAADf3fsAAAAAAPv/DwAA"}},"sprites.builtin.cat1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOAA4AAADgzPzu/wAAAOC9s929/w8A4N07/d3S/QAA3N3d39L7AADw3d290v0AAPDb3b3S/wAA3N3d39IPAODdO/3d0g8A4L2z3S3d/QDgzPzuv/v/AAAAALD//QAAAAAA8N37AAAAAACw/w8AAAAAAAAAAAAA"}},"sprites.builtin.cat2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOAA4AAADgzPzu/wAAAOC9s929/wAA4N07/d3SDwAA3N3d39L9AADw3d290vsAAPDb3b3S/QAA3N3d39L/AODdO/3d0v0A4L2z3S3d/wDgzPzuv/sAAAAAAADw+wAAAAAAsP/9AAAAAADw3fsAAAAAALD/DwAA"}},"sprites.builtin.clam0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAMD/AAAAAAAA3LwMAAAAAMDTPPsAAAAAwLPM+wAAAAC8O83zAAAAALwzzfMAAAAAPLO8+wAAAAC8O83zAAAAADwzzfMAAAAAPLO8+wAAAAC8M83zAAAAALw7zfMAAAAAwLPM+wAAAADA0zz7AAAAAADcvAwAAAAAAMD/AA=="}},"sprites.builtin.clam1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAM8MAMD/AAD8PPMAPLMMwDvLvM/zPPvAw8u8y//M+/DDvMzL/7/zv8vMzPz/v/O8u8vMmIn/+zzMzMw5k7/zPMzMzBmTv/O8u8vMmIn/+7/LzMz8/7/z8MO8zMv/v/PAw8u8y//M+8A7y7zP8zz7APw88wA8swwAAM8MAMD/AA=="}},"sprites.builtin.clam2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAM8MAMD/AAD8PPMAPLMMwDvLvM/zPPvAw8u8y//M+/DDvMzL/7/zv8vMzPz/v/O8u8vM/P//+zzMzMz8/7/zPMzMzPz/v/O8u8vM/P//+7/LzMz8/7/z8MO8zMv/v/PAw8u8y//M+8A7y7zP8zz7APw88wA8swwAAM8MAMD/AA=="}},"sprites.builtin.clownFish0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAA/w8AAAAAAMBE9AAAAAAATEREDwAAAMBEREQPAAAATET0RPQAAMDcRERE/QAAzEQRERFEDwDMRETExEQPwM1ERMRETw/AzURERP9PD8DNTURERMTNwN0cTUTU3M0AzMwREf2/zQAAAMz0/8wMAADARET0AAAAAMDM//8AAA=="},"pyQName":"sprites.builtin.clown_fish0"},"sprites.builtin.clownFish1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAP8AAAAAAADMRA8AAAAAwERE9AAAAABMRET0AAAAwERERPQAAADcRERP1A8AzERBRERBD8DNRBQREUQPwM1ERExMRA/AzURETPRED8DNTUT0/8QMwN0cRERE3AwAzMwREf3bDAAAAMz0/8wAAAAAwEREDwAAAADA/P8PAA=="},"pyQName":"sprites.builtin.clown_fish1"},"sprites.builtin.clownFish2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADw/wAAAAAAAExEDwAAAADARET0AAAAAExERPQAAADARERPRA8AAMxNRETUDwDATBQREUH0AMBMRBRMTPQA3ExExERM9ADcTET0/0T0ANzcRERERNwM3M3RRETN3QzAzBwR0f/bDAAAzPT/D8wAAMBERPQAAAAAwPz//wAAAA=="},"pyQName":"sprites.builtin.clown_fish2"},"sprites.builtin.clownFish3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADw/wAAAAAAAExEDwAAAADARET0AAAAAExET0QPAAAATERERP0AAMAcREQU9AAAwEQREUFEDwDMRETExEQPAMxEREzERA/AzURE/09ED8DNTURERMTNwN0cTUTU3M3A3cwREf2/zQDMzP/0D8AMAABMRPQAAAAAAPz//wAAAA=="},"pyQName":"sprites.builtin.clown_fish3"},"sprites.builtin.coin0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIAAgAAAAAu8wAsFXVD1s90/1bUxX9W1MV/Vsd0f2wVd0PALvMAA=="}},"sprites.builtin.coin1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIAAgAAAAAu8wAsFVVD1s90/1bUxX9Wx3R/bBV3Q8Au8wAAAAAAA=="}},"sprites.builtin.coin2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIAAgAAAAAAAAAALvMALBVVQ9bPRP9WxHR/bBV3Q8Au8wAAAAAAA=="}},"sprites.builtin.coin3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIAAgAAAAAAAAAAAAAALC7ywxbUd3zW1Hd87C7ywwAAAAAAAAAAA=="}},"sprites.builtin.coin4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIAAgAAAAAAAAAALvMALBV3Q9bEdH9Wz0T/bBVVQ8Au8wAAAAAAA=="}},"sprites.builtin.coin5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIAAgAAAAAAAAAALvMALBV3Q9bHdH9W1MV/Vs90/2wVVUPALvMAA=="}},"sprites.builtin.computer0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"electronics","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAwMzMzMzMzAAc3d3dERHLABzNu7sb3csAHM29u9sdywAczbu7Gx3LABzNu7sb3csAHM27u9sdywAczbu7Gx3LABzNu7sb3csAHM27u9sdywAczbu7Gx3LABzNu7sb3csAHN3d3RERywDAzMzMzMzMAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.builtin.computer1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"electronics","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAMDMzAC7u7u7vBHLsNHd3d3L3csbsczMzMsdy9vBZmbGyx3L28HWZsbL3cvbwWZmxssdy9vBZmbGyx3L28FmZsbL3cvbwWZmxssdy9vBZmbGyx3LG7HMzMzL3cuw0d3d3csdywC7u7u7vBHLAAAAAADAzMwAAAAAAAAAAA=="}},"sprites.builtin.console":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"electronics","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQKAAgAAACwy8wMGxERyxsREcsbERHLu93dzbvd3c0bERHLGxERyxsREcuwu8sM"}},"sprites.builtin.coral0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADAzADMAAAAAMAzDDwMAMwAADzDPAzAMwzAbDM2xsA2xjwzMzNmADzDM2bMNjPMM2bMNsPMNjxjZsZsM8xmwMzMzDM2xmwAAGzDPDMzZsDMzDMzZmZjwDNjPMbMNjMAbDPGzDwzxsw2M2bGMzYMPDPMzMxjPAzAzAAAwAzMAA=="}},"sprites.builtin.coral1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADAzADMAAAAAMAzDDwMAMwAADzDPAzAMwzAbDM2xsA2xjwzMzNmADzDM2bMNjPMM2bMNsPMNjxjZsZsM8xmwMzMzDM2xmwAAGzDPDMzZsDMzDMzzGbDwDNjzMw2zMwAbDM8wzzDZsw2M2YzxmNmPDPMzGwzM8bAzMxsM2PMzA=="}},"sprites.builtin.coral2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAADw2w2zGzMDMPGPMPGPMwDPMM8bMM8YAPMY8M2Y2ZgDMY2wzM2ZmzDNmPMNsNsw8Y8YzPMPDzMDMbMZsM8xmAADAzDM2xmwAAGzDPDMzZsDMzDMzZmZjwDNjPMbMNjMAbDPGzDwzxsw2M2bGMzYMPDPMzMxjPAzAzAAAwAzMAA=="}},"sprites.builtin.coral3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADAzADMAAAAAMAzDDwMAMwAADzDPAzAMwzAbDM2xsA2xjwzMzNmADzDM2bMNjPMM2bMNsPMNjxjZsZsM8xmwMzMzDM2xmwAAGzDPDMzZsDMzDMzzGbDwDNjzMw2zMwAbDM8wzzDZsw2M2YzxmNmPDPMzGwzM8bAzMxsM2PMzA=="}},"sprites.builtin.coral4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAADw2w2zGzMDMPGPMPGPMwDPMM8bMM8YAPMY8M2Y2ZgDMY2wzM2ZmzDNmPMNsNsw8Y8YzPMPDzMDMbMZsM8xmAADAzDM2xmwAAGzDPDMzZsDMzDMzzGbDwDNjzMw2zMwAbDM8wzzDZsw2M2YzxmNmPDPMzGwzM8bAzMxsM2PMzA=="}},"sprites.builtin.coral5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAADw2w2zGzMDMPGPMPGPMwDPMM8bMM8YAPMY8M2Y2ZgDMY2wzM2ZmzDNmPMNsNsw8Y8YzPMPDzMDMbMZsM8xmAADAzDM2xmwAAGzDPDMzZsDMzDMzZmZjwDNjPMbMNjMAbDPGzDwzxsw2M2bGMzYMPDPMzMxjPAzAzAAAwAzMAA=="}},"sprites.builtin.couchFront0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAADMzMzMDADMzNvdvcwMwN3d293du8y83bvLzMy7vNy9u7zd3bu83L273N3du8zcvbvc3d27DNy9u9zd3bsM3L273N3duwzcvbvc3d27DNy9u9zd3bsM3L273N3duwzcvbvc3d27DNy9u9zd3bsM3L273N3duwzcvbvc3d27DNy9u9zd3bsM3L273N3duwzcvbvc3d27zNy9u7zd3bu8vN27y8zMu7zA3d3b3d27zADMzNvdvcwMAAAAzMzMzAw="},"pyQName":"sprites.builtin.couch_front0"},"sprites.builtin.couchFront1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAADMzMzMDADMzFNVNcwMwFVVU1VVM8zcVTPDzMwzvFw1MzxVVTO8XDUzXFVVM8xcNTNcVVUzDFw1M1xVVTMMXDUzXFVVMwxcNTNcVVUzDFw1M1xVVTMMXDUzXFVVMwxcNTNcVVUzDFw1M1xVVTMMXDUzXFVVMwxcNTNcVVUzDFw1M1xVVTMMXDUzXFVVMwxcNTNcVVUzzFw1MzxVVTO83FUzw8zMM7zAVVVTVVUzzADMzFNVNcwMAAAAzMzMzAw="},"pyQName":"sprites.builtin.couch_front1"},"sprites.builtin.couchSide0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQPABgAAAAAzMzMzMzMzMzMzADAu7u7u7u7u7u7u8zc3d3d3d3d3bu7u7zc3d3d3d3d3bu7u7zc3d3d3d3dvbu7u8y8u7u7u7u7u7u7uwzAzMzMzMzMzMzMzAwAvL3c3d3d3by9uwwA3L3c3d3d3dy9uwwA3L3c3d3d3dy9uwwA3L3c3d3d3dy9u8wA3L283d3d3dy9u7wA3LvLu7u7u9y7u7wAwLvLzMzMzMy7u8wAAMzMAAAAAADMzAw="},"pyQName":"sprites.builtin.couch_side0"},"sprites.builtin.couchSide1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQPABgAAAAAzMzMzMzMzMzMzADAMzMzMzMzMzMzM8xcVVVVVVVVVTMzM7xcVVVVVVVVVTMzM7xcVVVVVVVVNTMzM8w8MzMzMzMzMzMzMwzAzMzMzMzMzMzMzAwAPDVcVVVVVTw1MwwAXDVcVVVVVVw1MwwAXDVcVVVVVVw1MwwAXDVcVVVVVVw1M8wAXDU8VVVVVVw1M7wAXDPDMzMzM1wzM7wAwDPDzMzMzMwzM8wAAMzMAAAAAADMzAw="},"pyQName":"sprites.builtin.couch_side1"},"sprites.builtin.couchSide2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQPABgAAAAAzMzMzMzMzMzMzADAZmZmZmZmZmZmZsx8d3d3d3d3d2ZmZrx8d3d3d3d3d2ZmZrx8d3d3d3d3Z2ZmZsxsZmZmZmZmZmZmZgzAzMzMzMzMzMzMzAwAbGd8d3d3d2xnZgwAfGd8d3d3d3xnZgwAfGd8d3d3d3xnZgwAfGd8d3d3d3xnZswAfGdsd3d3d3xnZrwAfGbGZmZmZnxmZrwAwGbGzMzMzMxmZswAAMzMAAAAAADMzAw="},"pyQName":"sprites.builtin.couch_side2"},"sprites.builtin.crowd0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8a2bM/P/MzMz2bMb8bGZmb2Zmb/xmZmZvZmZvzGZmZs/2bMxsZmZm/2zGd2dmZmb//3xvZ2ZmZv//d3dnZmZm/8x3d2dmZmbMzHxvZ2ZmZsz8z3dnZmZmzL+9zGxmZmbMzN3LbGZmZs/8z7tsZmZm/9zdvGtmZmbPzdvNa2ZmZg=="}},"sprites.builtin.crowd1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADf3c3ba2ZmZt/dzdtrZmZmz83bzWtmZmb/3N28a2ZmZsz/z7tsZmZmzM/d/G9mZmbMv73/b2ZmZvz///9vZmZm/7wz+2xmZmbP+zyzbGZmZr+7MzxsZmZmv7szPGxmZmbP+zyzzGZmZv+8M9v9ZmZmz/zPvfxsZmbMzL/d/f/MzA=="}},"sprites.builtin.crowd2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzL/d/f/MzM/8/738bGZm/8+73/1mZmb/vM/LzGZmZv+7u89rZmZm/7u7z2tmZmb/vM+7bGZmZv/Pu8tvZmZm/3v7/29mZmb/f7f8b2ZmZv//tstvZmZmz3fHvG9mZmZ8b3e8bGZmZnd3vLdrZmZmd3e8t2tmZmZ8b3fLbGZmZg=="}},"sprites.builtin.crowd3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADPd7edaWZmZv//3MtpZmZm///bnWlmZma8u9udaWZmZsu83MtpZmZmu7vLnWlmZma7u8v8b2ZmZsu8zPxvZmZmvGtmzGxmZmbM9mzGbGZmZm9mZm9sZmZmb2Zmb2xmZmbP9mzMzGZmZv9sxnf3ZmZm//98b/dsZmb//3d39//MzA=="}},"sprites.builtin.crowd4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAD/zHd39//MzMzMfG/3bGZmzPzPd/dmZmbMv73MzGZmZszM3ctsZmZmz/zPu2xmZmb/3N28a2ZmZs/N281rZmZm393N22tmZmbf3c3ba2ZmZs/N281rZmZm/9zdvGtmZmbM/8+7bGZmZszP3fxvZmZmzL+9/29mZmb8////b2ZmZg=="}},"sprites.builtin.crowd5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAD/vDP7bGZmZs/7PLNsZmZmv7szPGxmZma/uzM8bGZmZs/7PLNsZmZm/7wz221mZmbP/M+9bGZmZszMv91tZmZmzMy/3W1mZmbP/P+9bGZmZv/Pu99tZmZm/7zPy2xmZmb/u7vPy2ZmZv+7u8/7ZmZm/7zPu/xsZmb/z7vL///MzA=="}},"sprites.builtin.crowd6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAD/e/v////MzP9/t/z/bGZm//+2y/9mZmbPd8e8z2ZmZnxvd7xsZmZmd3e8t2tmZmZ3d7y3a2ZmZnxvd8tsZmZmz3e3nWlmZmb//9zLaWZmZv//251pZmZmvLvbnWlmZmbLvNzLaWZmZru7y51pZmZmu7vL/G9mZmbLvMz8b2ZmZg=="}},"sprites.builtin.crowd7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8a2bMbGZmZsz2bMZsZmZmb2Zmb2xmZmZvZmZvbGZmZs/2bMxsZmZm/2zGd2dmZmb//3xvZ2ZmZv//d3dnZmZm/8x3d2dmZmbMzHxvZ2ZmZsz8z3dnZmZmzL+9zGxmZmbMzN3LzGZmZs/8z7v8ZmZm/9zdvPtsZmbPzdvN+//MzA=="}},"sprites.builtin.crowd8":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADf3c3b+//MzN/dzdv7bGZmz83bzftmZmb/3N28y2ZmZsz/z7tsZmZmzM/d/G9mZmbMv73/b2ZmZvz///9vZmZm/7wz+2xmZmbP+zyzbGZmZr+7MzxsZmZmv7szPGxmZmbP+zyzbGZmZv+8M9ttZmZmz/zPvWxmZmbMzL/dbWZmZg=="}},"sprites.builtin.crowd9":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzL/dbWZmZs/8/71sZmZm/8+7321mZmb/vM/LbGZmZv+7u89rZmZm/7u7z2tmZmb/vM+7bGZmZv/Pu8tvZmZm/3v7/29mZmb/f7f8b2ZmZv//tstvZmZmz3fHvG9mZmZ8b3e8zGZmZnd3vLf7ZmZmd3e8t/tsZmZ8b3fL/P/MzA=="}},"sprites.builtin.dog0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQAA4AAAAARA4AAAAAAEBV5QAAAAAAVFXk/g8AAABURVRV9P//AFRFVV9lVPUA4FVVVWVVDwAAXlVFb1UPAABeVUVvVf8A4FVVVWVV9QBURVVfZUUPAFRFVFVGVQ8AVFXk/k9U9QBAVeUA8PT/AABEDgBf9QAAAAAA8FUPAAAAAADw/wAAAA=="}},"sprites.builtin.dog1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQAA4AAAAAQOQAAAAAAABUVQ4AAAAAQFVF7g8AAABAVURVRf//AEBVVPVVVvUAAF5VVVVW9AAA4FVV9Fb1AADgVVX0Vv8AAF5VVVVWDwBAVVT1VVYPAEBVRFVlVPUAQFVF7v/0/wAAVFUO8PQAAABA5ABf9QAAAAAAAP8PAAAAAAAAAAAAAA=="}},"sprites.builtin.dog2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQAA4AAAAAQOQAAAAAAABUVQ4AAAAAQFVF7g8AAABAVURVRf8AAEBVVPVVVg8AAF5VVVVW9QAA4FVV9Fb0AADgVVX0VvUAAF5VVVVW/wBAVVT1VVb1AEBVRFVlVP8AQFVF7v9P/wAAVFUO8FUPAABA5ABf9QAAAAAAAP8PAAAAAAAAAAAAAA=="}},"sprites.builtin.field0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAREREREREREXd3d3d3d3d3d3d3d3d3d3d3EXF3d3d3d3d3d3d3d3d3d3d3d3d3d3d3EXF3d3d3d3d3d3d3d3d3d3d3d3d3d3d3EXF3d3d3d3d3d3d3d3d3d3d3d3d3d3d3EXF3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dw=="}},"sprites.builtin.field1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAREREREREREWZmZmZmZmZmZmZmZmZmZmZmEWFmZmZmZmZmZmZmZmZmZmZmZmZmZmZmEWFmZmZmZmZmZmZmZmZmZmZmZmZmZmZmEWFmZmZmZmZmZmZmZmZmZmZmZmZmZmZmEWFmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZg=="}},"sprites.builtin.fieldGoal":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQAEAAAAAAAAAAAAAAAAAAAACwu7u7u7u7u7u7u7u7y8wMAAAAAAAAAAAAAAAAAAAAsBsRERERERERERERERHR3c0AAAAAAAAAAAAAAAAAALDb3RERERERERERERER0d3dywAAAAAAAAAAAAAAAACw293LzMzMzLu7u7u7u7vd3csLAAAAAAAAAAAAAAAAsNvdywsAAAAAvAwAAACw293LCwAAAAAAAAAAAAAAALDb3csLAAAAAAC8DAAAsNvdywsAAAAAAAAAAAAAAACw293LCwAAAAAAALzMALDb3csLAAAAAAAAAAAAAAAAsNvdywsAAAAAAAAAwMu8293LCwAAAAAAAAAAAAAAALDb3csLAAAAAAAAAADAvNzdywsAAAAAAAAAAAAAAACw293LCwAAAAAAAAAAAMDc3csLAADMzMzMzIxoAAAAsNvdywsAAAAAAAAAAACw293LCwAAwNu9u7u7u7sGALDb3csLAAAAAAAAAAAAsNvdy7v8/////9y7u7u7u2vA3N3LCwAAAAAAAAAAAMDc3csLzLvLzMz837u7u7u7a7zLywsAAAAAAAAAAAAAvMvLCwAAzP/////cu7u7u7trvMsLAAAAAAAAAAAAAAC8ywsAAAAAAADA2727u7u7uwbADAAAAAAAAAAAAAAAAMAMAAAAAAAAAADMzMzMzIxoAA=="},"pyQName":"sprites.builtin.field_goal"},"sprites.builtin.football1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIAAYAAAAAxgAAYBEMANa7ywBGscsARkHLAEZEzQBgHQwAAMYAAA=="}},"sprites.builtin.football2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIAAYAAAAAxgAAYL0MABa0ywBGFMsARhTEAEZEwQBg1AwAAMYAAA=="}},"sprites.builtin.football3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIAAYAAAAAxgAAYB0MANa0ywBGRMEARkTBAEZExABg3QwAAMYAAA=="}},"sprites.builtin.football4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIAAYAAAAAxgAAYL0MANa0ywDWRMsARkTEAEZEzQBg3QwAAMYAAA=="}},"sprites.builtin.football6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIAAYAAAAAxgAAYL0MANa0ywAWRMsAFkTEAEZEzQBg0QwAAMYAAA=="}},"sprites.builtin.football7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIAAYAAAAAAAAAYMwAANa7DABGscsARkHLAEZEvQCw1LEAALsMAA=="}},"sprites.builtin.footballPlayer0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADgvgAAAAAAAO4eDwAAAO7uLhL/D+4gIuIu0v7/7iIiIt/t0v3uIiIi/i/S/e8iIuIiLiL+/9Ii8hvuIg7/IiL+H+z+D/AuIv8fzPAPAODu/x8M0A0AAAC8vQDQDQAAAMzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.builtin.football_player0"},"sprites.builtin.footballPlayer1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAD/DwAAAAAAAP8PAAAAAO77/wAAAADg7vEPAADg7u4i8f8AACIi7iL9/wAgIiLy3d797iAiIuL/0u3uICIiLuL+AO4gLSK/4Q4A4CAi4v/BDAAA4CLy/8EAAAAA7v7/wQAAAAAAwNsLAAAAAADAzAwAAAAAAAAAAAAAAA=="},"pyQName":"sprites.builtin.football_player1"},"sprites.builtin.footballPlayer2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAADuDgAAAADuC+4OAAAA4O7x7wAAAADgItH9AADg7u4i3v0AACIi/t0u/gAgIiLi/yL+/yAiIiLuIv7/ICIiLuL+AP8gLSK/4f4P8CAi4v/B/A8A4CLy/8HQDQAA7v7/wdANAAAAwNsLAAAAAADAzAwAAAAAAAAAAAAAAA=="},"pyQName":"sprites.builtin.football_player2"},"sprites.builtin.footballPlayer3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO4LAAAAAADg7vEAAAAAAOAi8Q/uAODu7iL9/+4AIiL+3d797iAiIuL/0v3vICIiIu4i/v8gIiIu4i7+8CAtIr/h/g8AICLi/8HcDQDgIvL/wdANAADu/v/BAAAAAADA2wsAAAAAAMDMDAAAAA=="},"pyQName":"sprites.builtin.football_player3"},"sprites.builtin.footballPlayer4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADgvgAAAAAAAO4eDwAAAO7uLhL/D/8gIuIu0v7//yIiIt/t3v3/IiIi/u/e/f4iIuIizu7+7tIi8utMRAzuIiL+/xtEDOAuIv//FEQMAODu//9EtAwAAAC8vczMDQAAAMzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.builtin.football_player4"},"sprites.builtin.footballPlayer5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAD/DwAAAAAAAP8PAAAAAO77/wAAAADg7vEPAADg7u4i8f8AACIi7iL7/wAgIiLyvd797iAiIuLP3P3uICIi7kxEzO4gLSL/G0TM4CAi4v8URMwA4CLy/0S0DAAA7v7/zMwAAAAAwNsLAAAAAADAzAwAAAAAAAAAAAAAAA=="},"pyQName":"sprites.builtin.football_player5"},"sprites.builtin.footballPlayer6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAADuDgAAAADuC+4OAAAA4O7x7wAAAADgIvH/AADg7u4i+/8AACIi/r3e/QAgIiLiz9z9/yAiIuJMRMz/ICIi/htEzP8gLSL/FETM8CAi4v9EtAwA4CLy/8zMDQAA7v7/wdANAAAAwNsLAAAAAADAzAwAAAAAAAAAAAAAAA=="},"pyQName":"sprites.builtin.football_player6"},"sprites.builtin.footballPlayer7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"sports people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO4LAAAAAADg7vEAAAAAAOAi8Q/uAODu7iL9/+4AIiL+3f7/7iAiIuL//v/vICIiIu7e/f8gIiIuwtz98CAtIu9MRMwAICLi/xtEzADgIvL/FETMAADu/v9EtAwAAADA28zMAAAAAMDMDAAAAA=="},"pyQName":"sprites.builtin.football_player7"},"sprites.builtin.forestBackground":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAACZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd2ZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd2Z3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2Zmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmdmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmdmdnd3Znd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmd3Z3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmd3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmdmZ3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZ2Znd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZndmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZnZ2dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZ2dmd2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZnd2d3d2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmd3d3d3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZnd3Z3dndnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZnZmd3ZnZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmdmZnZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZndmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnZnd2Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3Z3d3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZndnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3Znd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZndnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZndnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZndmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ2dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3Z2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3Znd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2ZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2Znd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2Znd2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnd2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2dnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdmd3Znd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3ZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnZ3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdmZ2Z3Z3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2ZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0="},"pyQName":"sprites.builtin.forest_background"},"sprites.builtin.forestBat0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAA//8PwPwPAPDP/8+8u/sA//zPu7Ecuw/PzDyzu/u7+88AzLu7+7v7AADAvLv7u/sAADyzsRy7+wAAzLu7u7v7AADAzLu7u/sAAP+/vLu7/AD/vLvMu8sP8LzLzMz//wDAy7vMDMAMAL/LvMsAAAwAv8zMDAAAAADPAAAAAAAAAA=="},"pyQName":"sprites.builtin.forest_bat0"},"sprites.builtin.forestBat1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADw/w/A/A8AAPD/z7y7+wAA/8y7G8uxDwDPPLO7u7/7AM/Au7u7v/sAAMC8u7u/+wAAPLMby7H7AADMu7u7u/sAAMDMvLu7+wAA8P+7vLv8AADwu8u8yw8AAL/LzPz/AAAAvLzLzAwAAPC7zLsMDAAA8MvMzAAAAADwDAAAAAAAAA=="},"pyQName":"sprites.builtin.forest_bat1"},"sprites.builtin.forestBat2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMDM/8AMAADAzLu7z8wAwLy7sRz7zAzAM7u7+7vPDAC8u7v7uw8MAMy7u/u7DwDAM7uxHLsPAMC8u7u7uw8AAMy7u/zPDwAAzLv8zMsMAADA///Lu8wAAAD//8u8ywAAAAD/y8zLDAAAAAAAAMwMAAAAAAAAwAwAAAAAAAAADA=="},"pyQName":"sprites.builtin.forest_bat2"},"sprites.builtin.forestBat3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADwz/wPwPwPAP/8///Mu/sAzwz/z7uxHA8PAMA8s7v7+wAAwMy7u/v7AAAAzLy7+/sAAMA8s7Ec+wAAwLy7u7v7AAD/z7u7u/sA/7+7vLu7/PC8y8zMu8sPwMu7zMz//wC/y7zLDMwAAL/MzAwAwAAAzwAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.builtin.forest_bat3"},"sprites.builtin.forestBat4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAA//8PwPwPAPDP/8+8+/8A//zPG7ERIg/PzDyzu/8i+88AzLu7/yL7AADAvLsRIvsAADwTsfy/+wAAzLu7u7v7AADAzLu7u/sAAP+/vLu7/AD/vLvMu8sP8LzLzMz//wDAy7vMDMAMAL/LvMsAAAwAv8zMDAAAAADPAAAAAAAAAA=="},"pyQName":"sprites.builtin.forest_bat4"},"sprites.builtin.forestBat5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADw///MzP8AAPD/z7z7/w8A/8y8sREv8gDPPLO7/y8iD8/Mu7v/LyIPAMC8uxEvIg8APLOx/P+yDwDMu7u7u7sPAMDMvLu7uw8A8P+7vLvLDwDwu8u8u/wAAL/LzPz/DwAAvLzLzMwAAPC7zLsMwAAA8MvMzAAAAADwDAAAAAAAAA=="},"pyQName":"sprites.builtin.forest_bat5"},"sprites.builtin.forestBat6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAPDM/P8AAAAAz7z7/w8AAPC8sREv8gAAPLO7/y8iDwDMu7v/LyIPAMC8uxEvIg8APLOx/P+yDwDMu7u7u/sPAMC8u8v//A8AwLzLz7zMDwAA/P+/vMsMAADw/7/MuwwAAADwv8y8zAAAAAAAwMDMAAAAAAAAAMwAAAAAAAAAwA=="},"pyQName":"sprites.builtin.forest_bat6"},"sprites.builtin.forestBat7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADwz/wPwPwPAP/8///MsfsAzwz/z7uxHA8PAMA8s7v7+wAAwMy7u/v7AAAAzLy7+/sAAMA8s7Ec+wAAwLy7sbv7AAD/z7u7u/sA/7+7vLu7/PC8y8zMu8sPwMu7zMz//wC/y7zLDMwAAL/MzAwAwAAAzwAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.builtin.forest_bat7"},"sprites.builtin.forestFlowers0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIABAAAAAAALC7zAAAAAAAG9HRDAAAAAAbMxFsZogAAD1V3XeGhwAAPVXdZniHAAAbMxEMeGcAABvR0Qx4BgAAsLvMAGYA"},"pyQName":"sprites.builtin.forest_flowers0"},"sprites.builtin.forestFlowers1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIABAAAAAAAMDMzAAAAAAAzDYzDAAAAMA8bDZjZogAwDY/ZnOGhwDA9jZjY3iHAABsMzMGeGcAAMDMzAB4BgAAAAAAAGYA"},"pyQName":"sprites.builtin.forest_flowers1"},"sprites.builtin.forestFlowers2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIABAAAAAAAACGAAAAAGCIAGaIiAAAdncIYHh3CAB3iIaAd4iGYIcAaHiHAGh4CGCIdwiIgHcAZgiIAGYIiACIAAAAYAgA"},"pyQName":"sprites.builtin.forest_flowers2"},"sprites.builtin.forestLargeMushroom0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgABAAAAAAAADMDAAAAAAAwLzLDAAAAADAu7sMAAAAALy7u8sAAADAu929ywAAALwT0d3LAAAAOxER3bsMALA7ERHduwwAsDMREdG7DACwMxERsbsMADszExGzuwywOzEzM7O7DLsbETMzM7u8uxsRMzMzu7zbGxEzMzO7vN0bETMzM7vc3TsxMzMRuxzROzMzExG9HBE7MzMTEb28ETszMxMRvbzbOzMzM9G7DLs7MzMzs7sMsLAzETOzuwwAsBMRMbO7DACwGxERu7sMAAAbERG7uwwAANsR0bvLAAAAsN3du8sAAAAA2727ywAAAADAu7sMAAAAAMC8ywwAAAAAAMwMAAAA"},"pyQName":"sprites.builtin.forest_large_mushroom0"},"sprites.builtin.forestLargeMushroom1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgABAAAAAAAAAAwMwAAAAAAAC8ywwAAAAAwLu7zAAAAAC8u7vLAAAAwLvdvcsAAAC8E9HduwwAADsREd27DACwOxER3bsMALAzERHRuwwAsDMREbG7DAA7MxMRs7u8ADsxMzOzu7wAGxEzMzO7vAAbETMzM7vcABsRMzMzu9wAGxEzMzO73AA7MTMzEbvcADszMxMRvRwAOzMzExG9HAA7MzMTEb3cADszMzPRu7wAOzMzM7O7vACwMxEzs7sMALATETGzuwwAsBsREbu7DAAAGxERu7sMAADbEdG7uwwAALDd3bvLAAAAANu9u8sAAAAAwLu7zAAAAAAAvMsMAAAAAADAzAAA"},"pyQName":"sprites.builtin.forest_large_mushroom1"},"sprites.builtin.forestMonkey0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMDMAAAAAADA3M0PAAAAAN/tzf0AAADw/e/N/fD/D+/d3c397979793d3P3+v/3v/d/d/f7//O/e3d3u7t797+7u7u7+v/3w7u7u7+7++wD/vfvv7v77APDdzfDu7v0AAM8MAO/+/wAAAPD//w8AAAAA7+7+AAAAAAD//w8AAA=="},"pyQName":"sprites.builtin.forest_monkey0"},"sprites.builtin.forestMonkey1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMDMAPD/AADA3M3/3/0AAN/tzf3f+wDw/e/N/f//AO/d3c393/0A793d3P3e+wDv/d/d/v7/AO/e3e3u7v4A7+7u7u7+/wDw7u7u7+7+DwD/37vv7v78AADf3fzu/v0AAPDMAO/u/QAAAAD/////AAAA8O7+AAAAAADw/w8AAA=="},"pyQName":"sprites.builtin.forest_monkey1"},"sprites.builtin.forestMonkey2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMDMAADwDwDA3N0PAN/9AN/d3vzw3v3w3f/e/PC//O/d3d3879/9793dzf3+3v3v3f/d/u7O/e/e3e3u7v//7+7u7u7+/wDw7u7u7+7/AADfu//v7v4PAN/dDPDu/vwA8MwAAO/+/QAAAP///7/9AADw7u4P8A8AAPD//wAAAA=="},"pyQName":"sprites.builtin.forest_monkey2"},"sprites.builtin.forestMonkey3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMDMAAAAAADA3N0PAAAAAN/d7f0A8A/w3f3v/QDf/e/d3d39/979793d3dz+v/zv3v3f7e7f/e/u3d3u7t797+7u7u7uzv3w7u7u7+78//C9+//v7v0P8N3NAPC+/QAAzwwAAP8PAAAA8P///w8AAADw7u4PAAAAAAD//wAAAA=="},"pyQName":"sprites.builtin.forest_monkey3"},"sprites.builtin.forestMonkey4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMDMAAAAAADA3M0PAPAPAN/tzf0Av/3w/e/N/fDe/e/d3c397/7/793d3P3v3/3v/d/d/v6+/e/e3e3u7v7/7+7u7u7uv/3w7u7u7/6+/QD/vfvv7v77APDdzfDu7v4AAM8MAP///wAAAAAAAPD/AAAAAADv7v8AAAAAAP//Dw=="},"pyQName":"sprites.builtin.forest_monkey4"},"sprites.builtin.forestMonkey5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMDMAAAAAADA3M0PAPAPAN/tzf0Av/3w/e/N/fDe/e/d3c397/7/793d3P3v3/3v/d/d/v6+/e/e3e3u7v7/7+7u7u7uv/3w7u7u7/6+/QD/vfvv7v77APDdzfDu7v4AAM8MAP///wAAAAAAAPD/AAAAAADv7v8AAAAAAP//Dw=="},"pyQName":"sprites.builtin.forest_monkey5"},"sprites.builtin.forestMonkey6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMDMAAAAAADA3M0PAP8PAN/tzf3///3w/e/N7d/9/e/d3c3tv/3/793d3O3///7v/d/d/u/+/u/e3e3+7u/+7+7u7u7+v/3w7u7u7/6+/QD/vfvv7v77APDdzfDu7v4AAM8MAP///wAAAAAAAPD/AAAAAADv7v8AAAAAAP//Dw=="},"pyQName":"sprites.builtin.forest_monkey6"},"sprites.builtin.forestMonkey7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAzAwAAPD/APDNzQAAv/0A/93cDPDf/fD93tz97/7/793e3P3u7v7v3d3c/e7u/u/9zd3t7v7/7/3d3e7uv/3v3t3t/u6//fDu7u7v/v/7AP/d/e/+//8A8P3/7v///wAA/9v/7+7/AADw3Q///w8AAAD/DwAAAA=="},"pyQName":"sprites.builtin.forest_monkey7"},"sprites.builtin.forestMonkey8":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAzAwAAPD/APDdzQAAv/0A383dDPDf/fD93dz97/7/7/3e3P3u7v/v3d7c/e7u/+/d3dzt7v7/7/3N3e7uv/3v/d3d/u6//fDe3e3v/v/7AP/u/u/+//8A8P3/7////wAA/7/97+7/AAAA3/3//w8AAAD//wAAAA=="},"pyQName":"sprites.builtin.forest_monkey8"},"sprites.builtin.forestMonkey9":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADA/P8AAAAAANzf/f//AAD/7d/9v/0A8N3t/f/f/QDv3d3t/v7/AO/d3/zu7/4A793f/e7//gDv3t397/7/AO/u7u7vvv0A8O7u7u++/QAA/73r///7AADw3f3///8AAADPDADw/wAAAAAA8O7+AAAAAADw/w8AAAAAAAAAAA=="},"pyQName":"sprites.builtin.forest_monkey9"},"sprites.builtin.forestMonkey10":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMDMAAAAAAAA3P3/AP//AP/t/dv/v/3w3e393e/e/e/d3f3/7/7/7/3f3O/+7v/v3d3d/+7v/u/e3d3+7v/+7+7u7v7uv/3w7u7u7u+//QD/vfvu///7APDdzf////8AAM/8AAD//wAAAAAA7+7/AAAAAAD//w8AAAAAAAAAAA=="},"pyQName":"sprites.builtin.forest_monkey10"},"sprites.builtin.forestMushroomPatch":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAACwzAAAAAAAALu7DAAAAACwEbvLAAAAsBsRs8sAAAA7EzGzuwwAsDMzM9G7DLuwMzMT0b28EbAzMxPRvRzRsBMxM9G73N2wExEzs7vcvQAbETO7u7y7ADsRM9u9CwAAsDOz3c0AAAAAu7vdywwAAADAu8u7DAAAAADLvN3LAAAAAAC73cu7AAAAsDO7u9wAAACwM7O73AAAALARs7u8AAAAsBHTvQwAAAAAO9O9DAAAAADAu8sAAAAAAADMDAA="},"pyQName":"sprites.builtin.forest_mushroom_patch"},"sprites.builtin.forestScenery0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADMzMzMzAAAzLvLzMvMAMC7zLvMu8wAvLvLvMy7zMC8u7u8zLzMwNvdu7zMzMy8u9u9vMzMzLzdu728vLvM3N3d28zMvMvc3d3bzL3My9zd3du83cvL3N3du9zdzcvA3b3L3N3NywC8u8zc3b3LAMDMzLzdvMwAAAAAwLzLzA=="},"pyQName":"sprites.builtin.forest_scenery0"},"sprites.builtin.forestScenery1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAD/7gDg/////+/uANu9/v/v7u6wu9vt7u7u7rDdvb3u/+7/27293e7u/v/b29vb/v7//9vb29vu7u7u29vb2+7/7v/b29vb7u/v7tu9vd3u/u/usN29ve7u7u6wu9vt7v//7gDbve7u7v//AODu/v/u/v8AAAAAAO/u/w=="},"pyQName":"sprites.builtin.forest_scenery1"},"sprites.builtin.forestScenery2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMDMDAAAAAAAzLvLAAAAAMDcvbsMAAAAvBG9uwwAALA7ETG7ywAAsDMRM73LALs7MzMT3cu72zszMxPRyxHdOzMzM7HLERE7ETMzs8u7EbARMRG7y7C7sBsxEb3LAAAAvDPRvQwAAADAvNu9DAAAAADMu8sAAAAAAMDMDAAAAA=="},"pyQName":"sprites.builtin.forest_scenery2"},"sprites.builtin.forestScenery3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAzAwAAAAAAMC7ywAAAAAAvL27DAAAAMAb0bsMAAAAuxMRs8sAAAA7EzHTy7sAsDMzM9HN2wCwMzMzEc3dALAzMzMTyxEAsBMxMzPLEQAAGxETscu7AAC7ERPRywAAAMA7E90MAAAAAMy73QwAAAAAwLvLAAAAAAAAzAwAAA=="},"pyQName":"sprites.builtin.forest_scenery3"},"sprites.builtin.forestSnake0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAMD/AADA/A8AHGEPAGx398AXEcbAd2x3fxcRwWx39ncsEhHBfHdmd3x3EcF8d2Z3fGcWwXx39md8/GbBfHdsx2fPbMFsd3d3x8xmxsB3d3f2ZmbGAGx3Z39nZvYAwPz/d2fGDwAAAMB3xv8AAAAAAHwMAAAAAAAAwAwAAA=="},"pyQName":"sprites.builtin.forest_snake0"},"sprites.builtin.forestSnake1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAwPwPAAAAAABsd/cAzMwAwHdsd88WYQxsd/Z3bBcRxnx3ZncsFxHBfHdmd3wSEcF8d/ZnfHcRwXx3bMd3ZxbBbHd3d/dsZsHAd3d3xs9mxwBsd2fPZmbGAMD8/3xnZsYAAAAAfGdmzAAAAAB8x8wMAAAAAMDHAAAAAAAAAMwAAA=="},"pyQName":"sprites.builtin.forest_snake1"},"sprites.builtin.forestSnake2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAPz/AAAAAADAF2EPAMD8D3wREfYAbHf2fBER8cB3h/9/ERHBbGwXIXIXEcF89vcvcncRwXxm9y9yZ2bBfGYXIXL3ZsZ89mf/d89sxnxsd3fHzGbGbHd3d8ZmZsbAdndnf2dmDADM/P98Z8wAAAAAAMDHAAAAAAAAAMwAAA=="},"pyQName":"sprites.builtin.forest_snake2"},"sprites.builtin.forestSnake3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAwP//AAAAAAB8EWYPAAAAwBcREfYAwPzPFxER8QB8Z2YXERHBwHf4/3cREcH8dhEichcRwfx2/yJyZ2bGbHb/InL3ZsZsdhEics9sxvx29v/HzGbG/HZ3d8dmZsZ8d3d3f2dmDMB2d2d8Z8wAAMz8/8DHAAAAAAAAAMwAAA=="},"pyQName":"sprites.builtin.forest_snake3"},"sprites.builtin.forestSnake4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAwP//AAAAAAB8EWYPAAAAwBcREfYAwPzPFxER8QB8Z2YXERHBwHf4/3cREcH8dhEichcRwfx2/yJyZ2bGbHb/InL3ZsZsdhEics9sxvx29v/HzGbG/HZ3d8dmZsZ8d3d3f2dmDMB2d2d8Z8wAAMz8/8DHAAAAAAAAAMwAAA=="},"pyQName":"sprites.builtin.forest_snake4"},"sprites.builtin.forestSnake5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAMz/AAAAAADAdnfMAAAAAHzHbMEAAADAdmf8zAAAAMB3Z2bPAAAAwHdnZs8AAADAd2f8wQAAAMB3x2zMAADMzHZ3d8cAwGxmfHd3xgDAd2bMdnfPAHx3ZmbM/8YAfMfMZmZmxgB8DMBmZmYMAGwMAMxmZgwAzAAAwMzMAA=="},"pyQName":"sprites.builtin.forest_snake5"},"sprites.builtin.forestSnake6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAwPwPAAAAAABsd/fMAAAAwHfMdsEAAABsd8Z/zAAAAHx3ZnbPAAAAfHdmds8AAAB8d8Z/wQAAAHx3zHbMAMzMbHd3d8fAbGbMd3d3xsB3ZsZsd2fPfHdmZsb8/8Z8x8xmZmZmxnwMwGxmZmYMbAwAzGxmxgzMAAAAzMwMAA=="},"pyQName":"sprites.builtin.forest_snake6"},"sprites.builtin.forestSnake7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAwPwPAAAAAABsd/fMAAAAwHfMdsEAAABsd8Z/zAAAAHx3ZnbPAAAAfHdmds8AAAB8d8Z/wQAAAHx3zHbMAMzMbHd3d8fAbGbMd3d3xsB3ZsZsd2fPfHdmZsb8/8Z8x8xmZmZmxnwMwGxmZmYMbAwAzGxmxgzMAAAAzMwMAA=="},"pyQName":"sprites.builtin.forest_snake7"},"sprites.builtin.forestTiles0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAYGaIZogIAGB2d3aHZvgAYHdnd2aGZg92d3d3d2fm/nZ3d3d3Zuj+dnd3d2dmhv52d3d3dndmhnZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aG+HZ3d3d3Zmb/dnd3d3Znhv92d3d3Z4aI+GB3Z3dnZogPYHZ3dodm+AAAYGaIZogIAA=="},"pyQName":"sprites.builtin.forest_tiles0"},"sprites.builtin.forestTiles1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAYGaIZoiI+GB2d3aHZujuYHdnd2aGZu52d3d3d2fm7nZ3d3d3ZujuZnd3d2dmhv5mdnd3dndmhmZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3dnhu52d3d3ZoaI6GZ3d3d3ZojuZnZ3d2dm5u5md3d3d2aG/w=="},"pyQName":"sprites.builtin.forest_tiles1"},"sprites.builtin.forestTiles2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2d3d3d2eI+HZ3d3d2d+judnd3d2dmZu52d3d3d2fm7nZ3d3d3ZujuZnd3d2dmhv5mdnd3dndmhmZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3dnhu52d3d3ZoaI6GZ3d3d3ZojuZnZ3d2dm5u5md3d3d2aG/w=="},"pyQName":"sprites.builtin.forest_tiles2"},"sprites.builtin.forestTiles3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2d3d3d2eI+HZ3d3d2d+judnd3d2dmZu52d3d3d2fm7nZ3d3d3ZujuZnd3d2dmhv5mdnd3dndmhmZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3Znhu52d3d3Z4aI6GB3Z3dnZojuYHZ3dodm6O4AYGaIZoiI/w=="},"pyQName":"sprites.builtin.forest_tiles3"},"sprites.builtin.forestTiles4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAYGaIZoiI+GB2d3aHZujuYHdnd2aGZu5md3d3d2fm7nZ3d3d3Zujudnd3d2dmhv52d3d3dndmhnZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3Znhu5md3d3Z4aI6GB3Z3dnZojuYHZ3dodm6O4AYGaIZoiI/w=="},"pyQName":"sprites.builtin.forest_tiles4"},"sprites.builtin.forestTiles5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADv/u7/7v/v/v//7u/u/u/+/u7v7+7+/+/+7v//7v//7v////7////u/v/////////u7////////+7//////////v/////////u/v///////+/+/////////u/////////+//////////7+////////7+7////////v7v///////w=="},"pyQName":"sprites.builtin.forest_tiles5"},"sprites.builtin.forestTiles6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADv/v///////////////////u7////////+7v///////////////////v/////////u7////////+7//////////v/////////u/v///////+/+/////////u/////////+//////////7+////////7+7////////v7v///////w=="},"pyQName":"sprites.builtin.forest_tiles6"},"sprites.builtin.forestTiles7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADv/v///////////////////u7////////+7v///////////////////v/////////u7////////+7//////////v/////////u/u///////+/+/////////u/v/v//7/7+/+/+///u7v7u///u/+7u7+7//u7v7/7v/u/u/v///w=="},"pyQName":"sprites.builtin.forest_tiles7"},"sprites.builtin.forestTiles8":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAvru7u/4PAOC7u7u7vv4Avru7u7vrvg++u7u7u+6+/ru7u7u7vuv+u7u7u+u+++67u7u76+7+/ru7u7vru+7/u7u7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/++u7u7u+vr/767u7u76+4P4Lu7u7vr6wAAvru7u74PAA=="},"pyQName":"sprites.builtin.forest_tiles8"},"sprites.builtin.forestTiles9":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADv/u7/7v/v/v//7u/u/u/+/v/v7+7+/+/+7v//7v//7v/u///////u/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////w=="},"pyQName":"sprites.builtin.forest_tiles9"},"sprites.builtin.forestTiles10":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAD//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////w=="},"pyQName":"sprites.builtin.forest_tiles10"},"sprites.builtin.forestTiles11":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAD//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/+////7/7/7+7////u7u//7v/u/+7u7v7/7+7v7/7u/v7v/v///w=="},"pyQName":"sprites.builtin.forest_tiles11"},"sprites.builtin.forestTiles12":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAvru7u777/+C7u7u7vu7/vru7u7vrvv6+u7u7u+6+/ru7u7u7vuvuu7u7u+u+++67u7u76+7+/ru7u7vru+7/u7u7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/++u7u7u+vr/767u7u76+7/4Lu7u7vr6/8Avru7u777/w=="},"pyQName":"sprites.builtin.forest_tiles12"},"sprites.builtin.forestTiles13":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADv/u7/7/4PAP//7u/+//8P/v/v7/7u7w/+7v///+7////u/////+7/////////7v/////////v/v///////+/+/////////////////////v///////////////////////////////////////////////////////////////w=="},"pyQName":"sprites.builtin.forest_tiles13"},"sprites.builtin.forestTiles14":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAD///////8PAP////////8P/////////w////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8P/////////w////////8PAA=="},"pyQName":"sprites.builtin.forest_tiles14"},"sprites.builtin.forestTiles15":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAD//////////////////////////////////////////////////////////////////////////v///////////////////v/////////v/v///////+/+/+/+///v////7+7////u/+//7v/u/+4P7v7/7+7+/w/u/v7v7v4PAA=="},"pyQName":"sprites.builtin.forest_tiles15"},"sprites.builtin.forestTiles16":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC+u7u7u777/7u7u3u7vu7/a7a7d7trZv57Z3u3t3Zn/mt3Zna3d+bua3d3d2dmhv5mdnd3dndmhmZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3dnhu52d3d3ZoaI6GZ3d3d3ZojuZnZ3d2dm5u5md3d3d2aG/w=="},"pyQName":"sprites.builtin.forest_tiles16"},"sprites.builtin.forestTiles17":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADv/g8AAAAAAP///w8AAAAA/u7vDwAAAAD+7v//AAAAAP//7v8AAAAA/v/u/wAAAADu7+/+AAAAAO7/7/4AAAAA/v///wAAAADu/v/+AAAAAO/+//8AAAAA/u///wAAAAD+////AAAAAP7+//8AAAAA7+7//wAAAADv7v//AAAAAA=="},"pyQName":"sprites.builtin.forest_tiles17"},"sprites.builtin.forestTiles18":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADv/v//AAAAAP////8AAAAA/u7//wAAAAD+7v//AAAAAP////8AAAAA/v///wAAAADu7///AAAAAO7///8AAAAA/v///wAAAADu/v//AAAAAO/+//8AAAAA/u///wAAAAD+////AAAAAP7+//8AAAAA7+7//wAAAADv7v//AAAAAA=="},"pyQName":"sprites.builtin.forest_tiles18"},"sprites.builtin.forestTiles19":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADv/v//AAAAAP////8AAAAA/u7//wAAAAD+7v//AAAAAP////8AAAAA/v///wAAAADu7//+AAAAAO7///8AAAAA/v/+/wAAAADu/u/+AAAAAO/+7/4AAAAA/u///wAAAAD+/+7/AAAAAP7+7g8AAAAA7+7/DwAAAADv7g8AAAAAAA=="},"pyQName":"sprites.builtin.forest_tiles19"},"sprites.builtin.forestTiles20":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2d3d3d2eI+HZ3d3d2d+j/dnd3d2dmZv52d3d3d2eG/nZ3d3d3ZujuZnd3d2dmhu5mdnd3dndmhmZ3d3d3Z2b/dnd3d3dmiPh2d3d3Z2aGiGZ3d3d3dmf+a3d2Z3Znd/9rZ3tnZoaI+Lu7e3t2Z4j/vru7e2d36//uu7u7Z777/w=="},"pyQName":"sprites.builtin.forest_tiles20"},"sprites.builtin.forestTiles21":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAYGaIZogIAGB2d3aHZvgAYHdnd2aGZg92d3d3d2f2/3Z3d3d3Zvj/Znd3d2dmhv9mdnd3dndm9mZ3d3d3Z2b+dnd3d3dmiOh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3dnhu52d3d3ZoaI+GZ3d3d3Zoj/ZnZ3d2dm9v9md3d3d2aG/w=="},"pyQName":"sprites.builtin.forest_tiles21"},"sprites.builtin.forestTiles22":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2d3d3d2eI+HZ3d3d2d+judnd3d2dmZu52d3d3d2fm7nZ3d3d3ZujuZnd3d2dmhv5mdnd3dndmhmZ3d3d3Z2b/dnd3d3dmiPh2d3d3Z2aGiHZ3d3d3Zmbudnd3d3dnhu52d3d3ZoaI6GZ3d3d3ZojuZnZ3d2dm5v5md3d3d2aG/w=="},"pyQName":"sprites.builtin.forest_tiles22"},"sprites.builtin.forestTiles23":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2d3d3d2eI+HZ3d3d2d+judnd3d2dmZu52d3d3d2fm7nZ3d3d3ZujuZnd3d2dmhv5mdnd3dndmhmZ3d3d3Z2budnd3d3dmiOh2d3d3Z2aG+HZ3d3d3Zmb/dnd3d3Znhv92d3d3Z4aI+GB3Z3dnZogPYHZ3dodm+AAAYGaIZogIAA=="},"pyQName":"sprites.builtin.forest_tiles23"},"sprites.builtin.forestTiles24":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAA4L67u777/+C+u7u7vu7/4Lu7u7vrvv6+u7u7u+6+/ru7u7u7vuvuu7u7u+u+++6+u7u76+7+/u67u7vru+7/vru7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/+7u7u7u+vr/7u7u7u76+7/vru7u7vr6//uu7u7u777/w=="},"pyQName":"sprites.builtin.forest_tiles24"},"sprites.builtin.forestTiles25":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC+u7u7u777/7u7u7u7vu7/u7u7u7vrvv67u7u7u+6+/ru7u7u7vuvuu7u7u+u+++6+u7u76+7+/u67u7vru+7/vru7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/+7u7u7u+vr/7u7u7u76+7/vru7u7vr6//uu7u7u777/w=="},"pyQName":"sprites.builtin.forest_tiles25"},"sprites.builtin.forestTiles26":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC+u7u7u777/7u7u7u7vu7/u7u7u7vrvv67u7u7u+6+/ru7u7u7vuvuu7u7u+u+++6+u7u76+7+/u67u7vru+7/vru7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/++u7u7u+vr/+C7u7u76+7/4L67u7vr6/8A4Lu7u777/w=="},"pyQName":"sprites.builtin.forest_tiles26"},"sprites.builtin.forestTiles27":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAA4L67u/4PAOC+u7u7vu4A4Lu7u7vrvg6+u7u7u+6+/ru7u7u7vuv+u7u7u+u++/6+u7u76+7+/u67u7vru+7/vru7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/+7u7u7u+vr/7u7u7u76+7/vru7u7vr6//uu7u7u777/w=="},"pyQName":"sprites.builtin.forest_tiles27"},"sprites.builtin.forestTiles28":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC+u7u7u777/7u7u7u7vu7/u7u7u7vrvv67u7u7u+6+/ru7u7u7vuvuu7u7u+u+++6+u7u76+7+/u67u7vru+7/vru7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/+7u7u7u+vr/7u7u7u76+7/vru7u7vr6//uu7u7u777/w=="},"pyQName":"sprites.builtin.forest_tiles28"},"sprites.builtin.forestTiles29":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC+u7u7u777/7u7u7u7vu7/u7u7u7vrvv67u7u7u+6+/ru7u7u7vuvuu7u7u+u+++6+u7u76+7+/u67u7vru+7/vru7u7u7/v+7u7u7u7vv/ru7u7u77u/+u7u7u7vu+/++u7u7u+vr/+C7u7u76+4P4L67u7vr6wAA4Lu7u/4PAA=="},"pyQName":"sprites.builtin.forest_tiles29"},"sprites.builtin.forestTree0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYACgAAAAAAAAAAAAAAAAAAACACACIAAAAAAAAAAAAAAAAAICIAGiIiIYAAAAAAAAAAAAAAAAAaIiIZohohggAAAAAAAAAAAAAAIBmaGiGiGZmCAAAAAAAAAAAiICIaIZmhoiGZmYIAAAAAAAAgIiGaIZmZmaGaIaGZogAAAAAAABoaIZmiGZmZmiGiIiGZggAAAAAAGhmiIhohmZmZoiGaGaGCAAAAACAZmZohmiIZmaGaIZmZogIAP8AgGhmZmaIiGhmZoZmiGZmZob/7gCIZmZmhmiGiGZmiIiIiGhmiO7+gGZmZmaGZohoZmZmhoiIZobo7u6AZmZmZoaIiGZmZmaIiGZmZuju/wCIZmZmZoiIiGhmiIaIaGZmhu7+AIBoZmZohohoZmaGZoiIZmaG/+4AAIBmZoiIaIhmZmZohmZmhggA/wAAAGhmaIZohmZmhoiIaGaGCAAAAAAAaGiGZohmZmZmiGZohmYIAAAAAACAiIaIiGZmZmiGaGZmiAgAAAAAAAAAiACIaGZmhoiIaGYIAAAAAAAAAAAAAACAaGiGaIZmZggAAAAAAAAAAAAAAACAhmaIZmiGCAAAAAAAAAAAAAAAAACIaAiIiIYAAAAAAAAAAAAAAAAAAACACACACAAAAAA="},"pyQName":"sprites.builtin.forest_tree0"},"sprites.builtin.forestTree1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYACgAAAAAAAAAAAAAAAAAAACACACIAAAAAAAAAAAAAAAAAICIAGiIiIcAAAAAAAAAAAAAAAAAeGiIZmh4hwgAAAAAAAAAAAAAAIB3ZmiGiHd2CAAAAAAAAAAAiICIeHd2h4iGaHcIAAAAAAAAAICGaIZ2Z3eHaIaId4gAAAAAAABgaIZmiHd3d2aGiHiHZggAAAAAAHZmiIhohnZnZoiGeHaHCAAAAACAd3ZohmiId3eHaIZod4gIAP8AAGhnd2aIiGh3d4ZmiHZndob/7gBmd3dnhmiGiHZniIiIiGh3iO7+YHd3d3eHZohod3dmhoiId4fo7u5gd3d3d4aIiHZ3Z2aIiHZ3Z+ju/wBmd3dnZoiIiGh3iIaIeHdmhu7+AABoZ3dohohod3eHZoiIdmaG/+4AAIB3doiIaIh3d2dohnd3hwgA/wAAAHZmaIZohnZnhoiIeHaHCAAAAAAAYGiGZoh3d3dmiGZ4h2YIAAAAAAAAgIaIiHZnd2aGaGZ3iAgAAAAAAAAAiACIaHd2h4iIaHcIAAAAAAAAAAAAAAAAeGeGaIZ3dggAAAAAAAAAAAAAAACAh2aIZniHCAAAAAAAAAAAAAAAAACIaAiIiIcAAAAAAAAAAAAAAAAAAACACACACAAAAAA="},"pyQName":"sprites.builtin.forest_tree1"},"sprites.builtin.forestTree2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYACgAAAAAAAAAAAAAAAAAAADwDwD/AAAAAAAAAAAAAAAAAPD/AI////YAAAAAAAAAAAAAAAAAb4//iI9v9g8AAAAAAAAAAAAAAPBmiI/4/2ZoDwAAAAAAAAAA//D/b2Zo9v/4j2YPAAAAAAAAAPD4j/hohmb2j/j/Zv8AAAAAAACAj/iI/2ZmZoj4/2/2iA8AAAAAAGiI//+P+GiGiP/4b2j2DwAAAADwZmiP+I//Zmb2j/iPZv8PAP8AAI+GZoj//49mZviI/2iGaPj/7gCIZmaG+I/4/2iG/////49m/+7+gGZmZmb2iP+PZmaI+P//Zvbv7u6AZmZmZvj//2hmhoj//2hmhu/u/wCIZmaGiP///49m//j/b2aI+O7+AACPhmaP+P+PZmb2iP//aIj4/+4AAPBmaP//j/9mZoaP+GZm9g8A/wAAAGiIj/iP+GiG+P//b2j2DwAAAAAAgI/4iP9mZmaI/4hv9ogPAAAAAAAA8Pj//2iGZoj4j4hm/w8AAAAAAAAA/wD/j2Zo9v//j2YPAAAAAAAAAAAAAAAAaIb4j/hmaA8AAAAAAAAAAAAAAACA9oj/iG/2DwAAAAAAAAAAAAAAAAD/jw////YAAAAAAAAAAAAAAAAAAADwDwDwDwAAAAA="},"pyQName":"sprites.builtin.forest_tree2"},"sprites.builtin.forestTree3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYACgAAAAAAAAAAAAAAAAAAADwDwD/AAAAAAAAAAAAAAAAAPD/AI////gAAAAAAAAAAAAAAAAAj///iP+P+A8AAAAAAAAAAAAAAPCIj4/4/4iIDwAAAAAAAAAA//D/j/iI+P/4iIgPAAAAAAAA8P/4j/iIiIj4j/j4iP8AAAAAAACPj/iI/4iIiI/4///4iA8AAAAAAI+I//+P+IiIiP/4j4j4DwAAAADwiIiP+I//iIj4j/iIiP8PAP8A8I+IiIj//4+IiPiI/4iIiPj/7gD/iIiI+I/4/4iI/////4+I/+7+8IiIiIj4iP+PiIiI+P//iPjv7u7wiIiIiPj//4iIiIj//4iIiO/u/wD/iIiIiP///4+I//j/j4iI+O7+APCPiIiP+P+PiIj4iP//iIj4/+4AAPCIiP//j/+IiIiP+IiI+A8A/wAAAI+Ij/iP+IiI+P//j4j4DwAAAAAAj4/4iP+IiIiI/4iP+IgPAAAAAADw//j//4iIiI/4j4iI/w8AAAAAAAAA/wD/j4iI+P//j4gPAAAAAAAAAAAAAADwj4/4j/iIiA8AAAAAAAAAAAAAAADw+Ij/iI/4DwAAAAAAAAAAAAAAAAD/jw////gAAAAAAAAAAAAAAAAAAADwDwDwDwAAAAA="},"pyQName":"sprites.builtin.forest_tree3"},"sprites.builtin.forestTreeGroup0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYACgAAAAAAAAAAAAAAAAAAADwDwD/AAAAAAAAAAAAAAAAAPD/AI////gAAAAAAAAAAAAAAAAAj///iP+P+A8AAAAAAAAAAAAAAPCIj4/4/4iIDwAAAAAAAAAA//D/j/iI+P/4iIgPAAAAAAAA8P/4j/iIiIj4j/j4iP8AAAAAAACPj/iI/4iIiI/4///4iA8AAAAAAI+I//+P+IiIiP/4j4j4DwAAAADwiIiP+I//iIj4j/iIiP8PAP8A8I+IiIj//4+IiPiI/4iIiPj/7gD/iIiI+I/4/4iI/////4+I/+7+8IiIiIj4iP+PiIiI+P//iPjv7u7wiIiIiPj//4iIiIiP+IiIiO/u/wD/iIiIiP///4+I/2iIiIaI+O7+APCPiIiP+P+PaIiIZohohoj4/+4AAPCIiP//j49maGiGiGZm+A8A/wAAAI+IiIiIaIZmhoiGZmb4DwAAAAAAj4iGaIZmZmaGaIaGZogPAAAAAABoaIZmiGZmZmiGiIiGZggAAAAAAGhmiIhohmZmZoiGaGaGCAAAAACAZmZohmiIZmaGaIZmZogIAP8AgGhmZmaIiGhmZoZmiGZmZob/7gCIZmZmhmiGiGZmiIiIiGhmiO7+gGZmZmaGZohoZmZmhoiIZobo7u4="},"pyQName":"sprites.builtin.forest_tree_group0"},"sprites.builtin.forestTreeGroup1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYACgAAACAZmZmZoaIiGZmZmaIiGZmZuju/wCIZmZmZoiIiGhmiIaIaGZmhu7+AIBoZmZohohoZmaGZoiIZmaG/+4AAIBmZoiIaIhmZmZohmZmhggA/wAAAGhmaIZohmZmhoiIaGaGCAAAAAAAaGiGZohmZmZmiGZohmYIAAAAAACPiIaIiGZmZmiGaGZmiAgAAAAAAI+IiP+IaGZmhoiIaGb4DwAAAADwiIiP+I+PaGiGaIZmZvgPAP8A8I+IiIj//4+IhmaIZmiGiPj/7gD/iIiI+I/4/4iIaPiIiIaI/+7+8IiIiIj4iP+PiIiI+P+PiPjv7u7wiIiIiPj//4iIiIiP+IiIiO/u/wD/iIiIiP///4+I/2iIiIaI+O7+APCPiIiP+P+PaIiIZohohoj4/+4AAPCIiP//j49maGiGiGZm+A8A/wAAAI+IiIiIaIZmhoiGZmb4DwAAAAAAj4iGaIZmZmaGaIaGZogPAAAAAABoaIZmiGZmZmiGiIiGZggAAAAAAGhmiIhohmZmZoiGaGaGCAAAAACAZmZohmiIZmaGaIZmZogIAP8AgGhmZmaIiGhmZoZmiGZmZob/7gCIZmZmhmiGiGZmiIiIiGhmiO7+gGZmZmaGZohoZmZmhoiIZobo7u4="},"pyQName":"sprites.builtin.forest_tree_group1"},"sprites.builtin.forestTreeGroup2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYACgAAACAZmZmZoaIiGZmZmaIiGZmZuju/wCIZmZmZoiIiGhmiIaIaGZmhu7+AIBoZmZohohoZmaGZoiIZmaG/+4AAIBmZoiIaIhmZmZohmZmhggA/wAAAGhmaIZohmZmhoiIaGaGCAAAAAAAaGiGZohmZmZmiGZohmYIAAAAAACPiIaIiGZmZmiGaGZmiAgAAAAAAI+IiP+IaGZmhoiIaGb4DwAAAADwiIiP+I+PaGiGaIZmZvgPAP8A8I+IiIj//4+IhmaIZmiGiPj/7gD/iIiI+I/4/4iIaPiIiIaI/+7+8IiIiIj4iP+PiIiI+P+PiPjv7u7wiIiIiPj//4iIiIj//4iIiO/u/wD/iIiIiP///4+I//j/j4iI+O7+APCPiIiP+P+PiIj4iP//iIj4/+4AAPCIiP//j/+IiIiP+IiI+A8A/wAAAI+Ij/iP+IiI+P//j4j4DwAAAAAAj4/4iP+IiIiI/4iP+IgPAAAAAADw//j//4iIiI/4j4iI/w8AAAAAAAAA/wD/j4iI+P//j4gPAAAAAAAAAAAAAADwj4/4j/iIiA8AAAAAAAAAAAAAAADw+Ij/iI/4DwAAAAAAAAAAAAAAAAD/jw////gAAAAAAAAAAAAAAAAAAADwDwDwDwAAAAA="},"pyQName":"sprites.builtin.forest_tree_group2"},"sprites.builtin.forestTreeGroup3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYACgAAAAAAAAAAAAAAAAAAACACACIAAAAAAAAAAAAAAAAAICIAGiIiIYAAAAAAAAAAAAAAAAAaIiIZohohggAAAAAAAAAAAAAAIBmaGiGiGZmCAAAAAAAAAAAiICIaIZmhoiGZmYIAAAAAAAAgIiGaIZmZmaGaIaGZogAAAAAAABoaIZmiGZmZmiGiIiGZggAAAAAAGhmiIhohmZmZoiGaGaGCAAAAACAZmZohmiIZmaGaIZmZogIAP8AgGhmZmaIiGhmZoZmiGZmZob/7gCIZmZmhmiGiGZmiIiIiGhmiO7+gGZmZmaGZohoZmZmhoiIZobo7u6AZmZmZoaIiGZmZmaIiGZmZuju/wCIZmZmZoiIiGhmiIaIaGZmhu7+AIBoZmZohohoZmaGZoiIZmaG/+4AAIBmZoiIaIhmZmZohmZmhggA/wAAAGhmaIZohmZmhoiIaGaGCAAAAAAAaGiGZohmZmZmiGZohmYIAAAAAACPiIaIiGZmZmiGaGZmiAgAAAAAAI+IiP+IaGZmhoiIaGb4DwAAAADwiIiP+I+PaGiGaIZmZvgPAP8A8I+IiIj//4+IhmaIZmiGiPj/7gD/iIiI+I/4/4iIaPiIiIaI/+7+8IiIiIj4iP+PiIiI+P+PiPjv7u4="},"pyQName":"sprites.builtin.forest_tree_group3"},"sprites.builtin.forestTreeGroup4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYACgAAADwiIiIiPj//4iIiIiP+IiIiO/u/wD/iIiIiP///4+I/2iIiIaI+O7+APCPiIiP+P+PaIiIZohohoj4/+4AAPCIiP//j49maGiGiGZm+A8A/wAAAI+IiIiIaIZmhoiGZmb4DwAAAAAAj4iGaIZmZmaGaIaGZogPAAAAAABoaIZmiGZmZmiGiIiGZggAAAAAAGhmiIhohmZmZoiGaGaGCAAAAACAZmZohmiIZmaGaIZmZogIAP8AgGhmZmaIiGhmZoZmiGZmZob/7gCIZmZmhmiGiGZmiIiIiGhmiO7+gGZmZmaGZohoZmZmhoiIZobo7u6AZmZmZoaIiGZmZmaIiGZmZuju/wCIZmZmZoiIiGhmiIaIaGZmhu7+AIBoZmZohohoZmaGZoiIZmaG/+4AAIBmZoiIaIhmZmZohmZmhggA/wAAAGhmaIZohmZmhoiIaGaGCAAAAAAAaGiGZohmZmZmiGZohmYIAAAAAACAiIaIiGZmZmiGaGZmiAgAAAAAAAAAiACIaGZmhoiIaGYIAAAAAAAAAAAAAACAaGiGaIZmZggAAAAAAAAAAAAAAACAhmaIZmiGCAAAAAAAAAAAAAAAAACIaAiIiIYAAAAAAAAAAAAAAAAAAACACACACAAAAAA="},"pyQName":"sprites.builtin.forest_tree_group4"},"sprites.builtin.furnitureRug":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgABgAAAAAu7u7u7u7u7u7uwAwOzs7Ozs7Ozs7OwvTPTs7Ozs7Ozs73QvbPd3d3d3d3d093bsz0z0zMzMzMzPdM7O73TMzMzMzMzPTvbszPTMzMzMzMzMzPbO7PdMzMzPTMzMzvbszPTMzMzMzMzMzPbO7PTMzMzMzMzMzvbszPTMzMzMzMzMzPbO7PTMz0zMzM9MzvbszPTMzMzMzMzMzPbO7PTMzMzMzMzMzvbszPTMzMzMzMzMzPbO7PdMzMzPTMzMzvbszPTMzMzMzMzMzPbO7PTMzMzMzMzMzvbszPTMzMzMzMzMzPbO7PTMz0zMzMzMzvbszPTMzMzMzM9MzPbO7PTMzMzMzMzMzvbszPTMzMzMzMzMzPbO7PdMzMzPTMzMzvbszPTMzMzMzMzMzPbO7PTMzMzMzMzMzvbsz3TMzMzMzMzPTPbO70z0zMzMzMzPds7vTPd3d3d3d3d093bPbPTs7Ozs7Ozs73QswOzs7Ozs7Ozs7OwsAu7u7u7u7u7u7uwA="},"pyQName":"sprites.builtin.furniture_rug"},"sprites.builtin.furnitureTable1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgABgAAAAAzMzMzMzMzMzMAACwvd293b3dvb27DADcvd293T3dvd27zAzcvd093T3dvd27vMPcPd093T3dvd27vMPc3d3d3d3dvd27zAzc3d3d3d3dvd27DADc3d3d3d3dPd27DADcPd3d3d3dPd27DADcPd093T3dPd27DADc3d293d3dPd27DADcPd293b3dPd27DADc3d093T3dPd27DADc3d093d3dPd27DADc3d3d3d3d3d27DADc3d093d3d3d27DADcPd093d3d3d27DADcPd3d3d3d3d27DADcPd3d3d3dPd27DADcPd093d3dPd27DADc3d093d3dPd27DADc3d3d3T3d3d27DADc3d3d3T3dPd27DADc3d3d3T3d3d27DADcPd093T3d3d27DADc3d093T3d3d27DADcPd093d3d3d27zAzcPd093d3dPd27vMPcPd093d3dPd27vMPcvd293T3dvd27zAywvd293b3dvb27DAAAzMzMzMzMzMzMAAA="},"pyQName":"sprites.builtin.furniture_table1"},"sprites.builtin.furnitureTable2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgABgAAAAAzMzMzMzMzMwMAACwMzMzMzMzuzvDAAA8MzMzMzMzs7vLzAw8ExERERExM7u7vMM8ETMzMzMRM7vDvMM8MTMzMzMTM7vDzAw8MTMzMzMTM7vDDAA8MTMzMzMTM7u7DAA8MTMzMzMTM7s7DAA8MTMzMzMTM7s7DAA8MTMzMzMTM7u7DAA8MTMzMzMTM7vDDAA8MTMzMzMTM7vDDAA8MTMzMzMTM7vDDAA8MTMzMzMTM7u7DAA8MTMzMzMTM7s7DAA8MTMzMzMTM7s7DAA8MTMzMzMTM7u7DAA8MTMzMzMTM7vDDAA8MTMzMzMTM7vDDAA8MTMzMzMTM7vDDAA8MTMzMzMTM7u7DAA8MTMzMzMTM7s7DAA8MTMzMzMTM7s7DAA8MTMzMzMTM7u7DAA8MTMzMzMTM7vDDAA8MTMzMzMTM7vDzAw8ETMzMzMRM7vDvMM8ExERERExM7u7vMM8MzMzMzMzs7vLzAwAMzMzMzMzuzvDAAAAzMzMzMzMzMwMAAA="},"pyQName":"sprites.builtin.furniture_table2"},"sprites.builtin.hermitCrabAttack0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8zAwAAPu/wFVUxQDA9V/LRVXFAMBVVVW0VcUAAMw8VUXLxQDAZsZTRUTMAGzMPFVFy8XAxlVVVURVxcDD9V+8u1XFwDP8z8O1VcXAMzNmw1XEDGwzM2MzzEwEPDYzYzOzxMzAPDNjM7NVxQDAM8wzDMvMAADMzMwAAAA="},"pyQName":"sprites.builtin.hermit_crab_attack0"},"sprites.builtin.hermitCrabAttack1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDMDAAAsPsPXFXEAADA9b/MVcUAAMBVVcVVxQAAzMxcxcVMAMBmZjzFTEQAbGbMXMXFTAA8w1VVxVXFADzD9c/LVcUAPDP8P8xVxcA2MzM2XEXMwGMzMzbDzMQAzDMzNjNbxQAAPMM8w7DMAADAzMwMAAA="},"pyQName":"sprites.builtin.hermit_crab_attack1"},"sprites.builtin.hermitCrabAttack2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/M8AAAAAwMz1X8wAAABcxVVVxQwAwFVVzDxVzADAVVXFzFXFAMzFzMw8VcXAxkzEVVVVxcDDxcz1X0zEwMNVVfzPxMzAw1VVxUzEDGwzXFVFVcwMPDbDzMzMxMzAPDMzNsNVxQDAM8M8w8zMAADMzMwMAAA="},"pyQName":"sprites.builtin.hermit_crab_attack2"},"sprites.builtin.hermitCrabAttack3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwz8wAAADAzPxfVcwAAFxVXFVVxQzAVVXFzDxVzMBVVcXMzFXFwMXMzMw8VcXATERcVVVVxcDFzPxfVUzEwFVV9c/MxMzAVVVVzEzEDMBcVVVUVcwMbMPMzMzMxMw8NjNjM8NVxcA8M8wzw8zMAMzMzMwMAAA="},"pyQName":"sprites.builtin.hermit_crab_attack3"},"sprites.builtin.hermitCrabAttack4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAAAAAAAAzAAAAAAAAMDFAAAAAAAAW8UAAAAAAABbzAAAAAAAAMvFAAAAAAAAW8UAAAAAwP9bxQAAAABc/1vFAAAAAFxVW8UAAAAAwMxbxQAAAMzMzEXEAADAZszMxcUAAMBmXFXFxQAAbGZc/8XFAAA8Zsb/zMQAADxjZmbDzAAAPDNmNjPMAMA2M2MzwwwAwGMzYzNDzAAAzDNjM1PFAADAM8wzw8wAAADMzMwMAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.builtin.hermit_crab_attack4"},"sprites.builtin.hermitCrabAttack5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwAAAAAAADMxQAAAAAAsFXMAAAAAACwy8UAALD7D7BVxQAAwPW/vFXFAADAVVW0VcUAAMzMU7VbxQDAZmY8RUvEAGxmzFxFXMXAZsZVVbRVzMAzxvVfzMUMwDNj/M/DzADAMzNmM8PMAGwzM2Mzw8wAPDYzYzOzxMzAPDNjM7NVxQDAM8wzDMvMAADMzMwAAAA="},"pyQName":"sprites.builtin.hermit_crab_attack5"},"sprites.builtin.hermitCrabAwaken0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAMwMAAAAAADAY8YAAAAAADzMbAwAAAAAPMzMxgAAAMA8zMzMAAAAbMbDzMwAAMBmZjzGzAAAbGZmxmbMAABsZmZmzMwAADwzZmZmxgAAPDNjZjbDAAA8MzNmM8MAwGYzM2MzwwDAYzMzYzPGAADMMzPMYwwAAADMzMzMAA=="},"pyQName":"sprites.builtin.hermit_crab_awaken0"},"sprites.builtin.hermitCrabAwaken1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAMDMDAAAAAAAbFzEAAAAAMDDXMUAAAAAwMNMxQAAAMDMw8zMAAAAbGY8zMUAAMBmZsZcxQAAwGZmxlzFAADAY2ZmTMwAAMAzZmbGxgAAwDNjZmPGAABsMzM2Y8YAADw2MzbDDAAAwDwzNsMAAAAAbDNswwAAAADAzMwMAA=="},"pyQName":"sprites.builtin.hermit_crab_awaken1"},"sprites.builtin.hermitCrabAwaken2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAACw/wDMDAAAAFz/y1TFAAAAXFVFVcUAAADMzEVVxQAAwDzMU8TFAABsPMxcRMwAwGbGw1PExQBsZsbMVVTFADxjXFVFVcUAPDNc/8xVxQA8M8P/w8QMwDYzMzYzTATAYzMzNjPLzADMMzM2M1vFAAA8wzzDwMwAAMDMzAwAAA=="},"pyQName":"sprites.builtin.hermit_crab_awaken2"},"sprites.builtin.hermitCrabAwaken3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAwMvMDAD/u7tcRVXFwP9Vu1xUVcXAVVVVRVtVxQDMVVVVtMzFwGbMM1VERMzAzFVVVbTMxcBVVVVFVFXFwP9VzLtbVcUw/8wzXFtVxcAzYzZcRcwMbDMzM8PMRAQ8NjNjM7PEzMA8M2Mzs1XFAMAzzDMMy8wAAMzMzAAAAA=="},"pyQName":"sprites.builtin.hermit_crab_awaken3"},"sprites.builtin.hermitCrabAwaken4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAMDLDAAAAPwPXFXFAADA9b9cVMUAAMBVVUVbxQAAAMxTVcTFAADAZjxVRMwAAGzMU1XExQDAxlVVRVTFAMDD9c+7W8UAwDP8P1xbxQDAM2M2XMUMAGwzMzbDTAQAPDYzNjPLzADAPDM2M1vFAADAwzzDwMwAAADMzAwAAA=="},"pyQName":"sprites.builtin.hermit_crab_awaken4"},"sprites.builtin.hermitCrabAwaken5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAALzMDAAA+7/AVVTFAMD1X8tFVcUAwFVVVbRVxQAAzDxVRcvFAMBmxlNFRMwAbMw8VUXLxcDGVVVVRFXFwMP1X7y7VcXAM/zPw7VVxcAzM2bDVcQMbDMzYzPMTAQ8NjNjM7PEzMA8M2Mzs1XFAMAzzDMMy8wAAMzMzAAAAA=="},"pyQName":"sprites.builtin.hermit_crab_awaken5"},"sprites.builtin.hermitCrabWalk0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAA+78AwMwMAMD1X8tcVMUAwFVVVbREzAAAzDxVRcvFAMBmxlNFVcUAbMw8VbRVxcDGVVW1u1XFwMP1X8xVxMzAM/zPw8VMBMAzM2YzzEQEbDMzYzOzRAQ8NjNjM7PEDMA8M2Mzs1UMAMAzzDMMywwAAMzMzAAAAA=="},"pyQName":"sprites.builtin.hermit_crab_walk0"},"sprites.builtin.hermitCrabWalk1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAALD7DwAAAAAAwPW/zMwAAADAVVVFxQAAAMDMXFVbDAAAbGY8VUTMAMBmzFxFxMUAbMZVVURbxQBsw/XPvFvFADwz/D9cVcUAPDNjNlzMzMA2MzM2w8sMwGMzMzYzWwwAzDMzNjPMDAAAPMM8wwAAAADAzMwMAAAAAAAAAAAAAA=="},"pyQName":"sprites.builtin.hermit_crab_walk1"},"sprites.builtin.hermitCrabWalk2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAsPsPwMwAAADA9b9MVQwAAMBVVUVVDAAAwMxcVVvMAABsZjxVRMwAwGbMXEVExABsxlVVRUTMAGzD9c+7y8UAPDP8z7VVxQA8M2PGVVXFwDYzMzbMVcXAYzMzNjPLzADMMzM2M7zMAAA8wzzDAAAAAMDMzAwAAA=="},"pyQName":"sprites.builtin.hermit_crab_walk2"},"sprites.builtin.hermitCrabWalk3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAALzMDAAA+7/AVVTFAMD1X8tFVcUAwFVVVbRVxQAAzDxVRcvFAMBmxlNFRMwAbMw8VUTExMDGVVVFzFwMwMP1X8xVVQzAM/zPw1VVDMAzM2YzXFUMbDMzYzOzzAw8NjNjM8PLzMA8M2Mzw1vFAMAzzDMMsMwAAMzMzAAAAA=="},"pyQName":"sprites.builtin.hermit_crab_walk3"},"sprites.builtin.largeOceanRock":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYAA4AAAAAAAC7zMwAAAAAu93du8wAALDd3d29ywAA29273b3LALDbvTPd3bsAsN29M93duwA8szsz2727ADwzMzM7M7sAvD0zMzMzvAC80zMzM8u7ALw7MzPDu7sAwDMzM7y7ywDAM9MzvLvMADAzzD2zy8wAAMC7O7PdywAAAMzM2929AAAAAMDd3b0AAAAAwN3dvQAAAACw3d28AAAAAADbzbsAAAAAAMy8ywAAAAAAwLzMAAAAAAAAzMwAAAAAAADAzAA="},"pyQName":"sprites.builtin.large_ocean_rock"},"sprites.builtin.largeShelf":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAADAzMzMzMz///////+83d29zLvb3d3d3f3c3d3d+8zM/MzMzP/c3d3d+8zM+8zMu//c3d3d+zPD+8zMu//c3d3d+zPD/WbG3f/c3d3d+8zM/czM3f/c3d3d+2bG/TPD3f/c3d3d+8zM/TPD3f/c3d3d+0TE/czM3f/c3d3d+0TE/UTM3f/c3d3d+8zM/czM3f/c3d3d+zPM/WbG3f/c3d3d+8zM/czM3f/c3d3d+3fH/UTE3f/c3d3d+8zM/UTE3f/c3d3d+2bG/czM3f/c3d3d+2bG/TPM3f/c3d3d+8zM/czM3f/c3d3d+zPD+3fHu//c3d3d+8zM+8zMu//c3d3d+8zM/MzMzP+83d29zLvb3d3d3f3AzMzMzMz///////8="},"pyQName":"sprites.builtin.large_shelf"},"sprites.builtin.mediumOceanRock":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAMDMzAAAAADMvMzMAAAAzL28y8wAAMzM28vLzADAu83cy8zMANu927zLzMyw3d3bu8u8zLDd3du7zLzL293d3My7vLvb3d3MzLy9u9vdvczdu727293N3N29zbu73cvc3b3NvLDMzNzdzc3MAADMzN3Ly8wAAADAzMzMzA=="},"pyQName":"sprites.builtin.medium_ocean_rock"},"sprites.builtin.oceanDepths0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADAvLu7u8vMAMy7u7u7y8wMvLu7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/7u7u7u7y8v8vLu7u7vM+//Mu7u7y7z8/w=="},"pyQName":"sprites.builtin.ocean_depths0"},"sprites.builtin.oceanDepths1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8u7u7u8vM/7u7u7u7y8z8u7u7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/7u7u7u7y8v8vLu7u7vM+//Mu7u7y7z8/w=="},"pyQName":"sprites.builtin.ocean_depths1"},"sprites.builtin.oceanDepths2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8u7u7u8vM/7u7u7u7y8z8u7u7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/Ly7u7u7y8v8zLu7u7vM+w/AvLu7y7z8AA=="},"pyQName":"sprites.builtin.ocean_depths2"},"sprites.builtin.oceanDepths3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADAvLu7u8vMAMy7u7u7y8wMvLu7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/Ly7u7u7y8v8zLu7u7vM+w/MvLu7y7z8AA=="},"pyQName":"sprites.builtin.ocean_depths3"},"sprites.builtin.oceanDepths4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADAvLu7u8vM/8y7u7u7y8z8vLu7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/7u7u7u7y8v8vLu7u7vM+//Mu7u7y7z8/w=="},"pyQName":"sprites.builtin.ocean_depths4"},"sprites.builtin.oceanDepths5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8u7u7u8vM/7u7u7u7y8z8u7u7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/7u7u7u7y8v8vLu7u7vM+//Mu7u7y7z8/w=="},"pyQName":"sprites.builtin.ocean_depths5"},"sprites.builtin.oceanDepths6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8u7u7u8vM/7u7u7u7y8z8u7u7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/Ly7u7u7y8v8zLu7u7vM+//AvLu7y7z8/w=="},"pyQName":"sprites.builtin.ocean_depths6"},"sprites.builtin.oceanDepths7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADAvLu7u8vM/8y7u7u7y8z8vLu7u7vL/P+7u7u7y7v8/7u7u7vLvPz/u7u7u8vMzP+8u7u7u8zM/My7u7u7y//8vLu7u8vL//+7u7u7y8z8/7u7u7u7vPz/u7u7u7u7+/+7u7u7u7vL/Ly7u7u7y8v8zLu7u7vM+//AvLu7y7z8/w=="},"pyQName":"sprites.builtin.ocean_depths7"},"sprites.builtin.oceanDepths8":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAD/////AAAAAP////8PAAAA//////8AAAD//////w8AAP//////DwAA//////8PAAD//////w8AAP//////DwAA////////AAD/////////AP////////8P/////////w///////////////////////////////////////////w=="},"pyQName":"sprites.builtin.ocean_depths8"},"sprites.builtin.oceanDepths9":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAD/////////////////////////////////////////D/////////8P/////////w//////////AP////////8A/////////wD/////////AP////////8A/////////w///////////////////////////////////////////w=="},"pyQName":"sprites.builtin.ocean_depths9"},"sprites.builtin.oceanDepths10":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAD/////////////////////////////////////////D/////////8P/////////w//////////D/////////8A////////DwD///////8AAP//////DwAA//////8PAAD//////w8AAP//////AAAA/////w8AAAD/////AAAAAA=="},"pyQName":"sprites.builtin.ocean_depths10"},"sprites.builtin.oceanDepths11":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAD/////AAAAAP//////AAAA//////8PAAD///////8AAP///////w8A////////DwD///////8PAP///////w8A////////DwD///////8PAP///////w8A////////DwD///////8AAP//////DwAA//////8AAAD/////AAAAAA=="},"pyQName":"sprites.builtin.ocean_depths11"},"sprites.builtin.oceanSand0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAMLO7y8zMAAAz3d0zM7sMMNPdPT3Du8yw3d09M8O7y9vd3T07w7vL293d3TM9vMw73d3TPTPDzDvd3d29083MM93dPT3TvczT3R3dMzO7y9Pd3T09w7vL293dPTPDu8uw3d09O8O7zDDT3d0zPbzMADPd0z0zwwwAMLu7y8zMAA=="},"pyQName":"sprites.builtin.ocean_sand0"},"sprites.builtin.oceanSand1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAMLO7y8zMAAAz3dPLvMsMMNPdM8O7u8yw3d2zw7u7zDvd3T09vMvMO9093TPDy8w73d3d283LzDPd0dPTvbvM093d3TO8u8vT3d09Pby7y9Pd3d0zw7vM293d3bPDy8zb3d3dMz3MzDvd3dM9M8PMO93d3b3Tzcwz3d09PdO9zA=="},"pyQName":"sprites.builtin.ocean_sand1"},"sprites.builtin.oceanSand2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADT3R3dMzO7y9Pd3T09w7vL093dPTPDu8vb3d09O8O7zNvd3d0zPbzMO93d0z0zw8w73d3dvdPNzDPdHT09083M093d3TMzu8zT3d09PcO7zNPd3T0zw7vL293dPTvDu8vb3d3dMz28zDvd3dM9M8PMO93d3b3Tzcwz3d09PdO9zA=="},"pyQName":"sprites.builtin.ocean_sand2"},"sprites.builtin.oceanSand3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADT3R3dMzO7y9Pd3T09w7vL093dPTPDu8vb3d09O8O7zNvd3d3TPczMO93dPd0zw8w73d3d3dvNzDPd3d3T083M093d0T0zu8zT3d3d07O7zNPd3bPDu7vLO93d08O7u8uw3d093by7yzDT3b3dvLvMADPdMzPMywwAMLu7y8zMAA=="},"pyQName":"sprites.builtin.ocean_sand3"},"sprites.builtin.oceanSand4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAMLO7y8zMzAAz3d0zM7u7MNPdPT3Du7uw3d09M8O7u9vd3T07w7u7293d3TM9vLs73d3TPTPDuzvd3d290827M93dPT3TvbvT3R3dMzO7u9Pd3T09w7u7293dPTPDu7uw3d09O8O7uzDT3d0zPby7ADPd0z0zw7sAMLu7y8zMuw=="},"pyQName":"sprites.builtin.ocean_sand4"},"sprites.builtin.oceanSand5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAMLO7y8zMzAAz3dPLvLu7MNPdM8O7u7uw3d2zw7u7uzvd3T09vLu7O9093TPDu7s73d3d2827uzPd0dPTvbu7093d3TOzu7vT3d09Pby7u9Pd3d0zw7u7293d3bPDu7vb3d3dMz28uzvd3dM9M8O7O93d3b3Tzbsz3d09PdO9uw=="},"pyQName":"sprites.builtin.ocean_sand5"},"sprites.builtin.oceanSand6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADT3R3dMzO7u9Pd3T09w7u7093dPTPDu7vb3d09O8O7u9vd3d0zPby7O93d0z0zw7s73d3dvdPNuzPdHT090727093d3TMzu7vT3d09PcO7u9Pd3T0zw7u7293dPTvDu7vb3d3dMz28uzvd3dM9M8O7O93d3b3Tzbsz3d09PdO9uw=="},"pyQName":"sprites.builtin.ocean_sand6"},"sprites.builtin.oceanSand7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADT3R3dMzO7u9Pd3T09w7u7093dPTPDu7vb3d09O8O7u9vd3d3TPby7O93dPd0zw7s73d3d3dvNuzPd3d3T0727093d0T0zu7vT3d3d07O7u9Pd3bPDu7u7O93d08O7u7uw3d093by7uzDT3b3dvLu7ADPdMzPMu7sAMLu7y8zMzA=="},"pyQName":"sprites.builtin.ocean_sand7"},"sprites.builtin.oceanSand8":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMvMvMzMzMzMvMu8zMzMzMu8zMzMzMzMy8y8zMzMzMzMzLzMzMzMzMzMzLzMzMzMzLzLvMzMzMzLvMvMzMzMzMvMzMzMzMzMzMzMzMzMzMzMvLzLzMzMzMu7vMu8zMzMy7u8zLzMzMzLu8zMzMzMzMy7zMzMzMzMzMy8zMzMzMzA=="},"pyQName":"sprites.builtin.ocean_sand8"},"sprites.builtin.oceanSand9":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMvMvMzMzMzMvMu8zMzMzMu8zMzMzMzMy8y8zMzMzMzMzLzMzMzMzMzMzLzMzMzMzLzLvMzMzMzLvMvMzMzMzMvMzMzMzMzMzMzMzMzMzMzMvLzLzMzMzMu7vMu8zMzMy7u8zLzMzMzLu8zMzMzMzMy7zMzMzMzMzMy8zMzMzMzA=="},"pyQName":"sprites.builtin.ocean_sand9"},"sprites.builtin.oceanSand10":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7vMvMzMzMzLvMu8zMzMzMu8zMzMzMzMy8y8zMzMzMzMzLzMzMzMzMzMzLzMzMzMzLzLvMzMzMzLvMvMzMzMzMvMzMzMzMzMzMzMzMzMzMzMvLzLzMzMzMu7vMu8zMzMy7u8zLzMzMzLu8zMzMzMzMy7zMzMzMzMzMy8zMzMzMzA=="},"pyQName":"sprites.builtin.ocean_sand10"},"sprites.builtin.oceanSand11":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7vMvMzMzMzLvMu8zMzMzMu8zMzMzMzMy8y8zMzMzMzMzLzMzMzMzMzMzLzMzMzMzLzLvMzMzMzLvMvMzMzMzMvMzMzMzMzMzMzMzMzMzMzMvLzLzMzMzMu7vMu8zMzMy7u8zLzMzMzLu8zMzMzMzMy8zMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.builtin.ocean_sand11"},"sprites.builtin.oceanSand12":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMAAAAAAAAAMzMAAAAAAAAzMwMAAAAAADMzMwAAAAAAMzMzAwAAAAAzMzMDAAAAADMzMzMAAAAAMzMzMwAAAAAzMzMzAAAAADMzMzMAAAAAMzMzMwAAAAAzMzMDAAAAADMzMwAAAAAAMzMDAAAAAAAzAwAAAAAAADMAAAAAAAAAA=="},"pyQName":"sprites.builtin.ocean_sand12"},"sprites.builtin.oceanSand13":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMAAAAAMzMzMwMAAAAzMzMzMwAAADMzMzMzAwAAMzMzMzMDAAAzMzMzMwMAADMzMzMzAwAAMzMzMzMDAAAzMzMzMzMAADMzMzMzMzMAMzMzMzMzMwMzMzMzMzMzAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.builtin.ocean_sand13"},"sprites.builtin.oceanSand14":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMDMzMzMzMzMwMzMzMzMzMzAzMzMzMzMzMAMzMzMzMzMwAzMzMzMzMzADMzMzMzMzMAMzMzMzMzMwAzMzMzMzMzAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.builtin.ocean_sand14"},"sprites.builtin.oceanSand15":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMDMzMzMzMzMwMzMzMzMzMzAzMzMzMzMzMDMzMzMzMzMwAzMzMzMzMDADMzMzMzMwAAMzMzMzMDAAAzMzMzMwMAADMzMzMzAwAAMzMzMzMAAAAzMzMzAwAAADMzMzMAAAAAA=="},"pyQName":"sprites.builtin.ocean_sand15"},"sprites.builtin.pedestal":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAsMzMDAAAAAAAAAAAAAAAALsREcsAAAAAAAAAAAAAsMwcsRuxDAAAAADAzMwAANsRHLu7EQwAAAAAvBGxALDdERzbuxEMAAAAwNsRsQDb3REc3N0RDADAzMzdEbGw3d0RHLzdzQAAvB3N3RGx293dEdzBy8zMzLwb0dsRsdvd3RHcsd27u7u7uxHbEbHb3d0RHB3b3d3d3b0R2xGx293dERwdvdG7u7u7G7ERsdvd3RHc0bERu93d3RuxEbHb3d0RvNHRGxEREREbsRGx293dEbwdHRvb3d3dG7ERsdvd3RG8Gx0bu93d3RuxEbHb3d0RvBsdGxEREREbsRGx293dEbwbHRsRERERG7ERsdvd3RG8Gx0bu93d3RuxEbHb3d0RvB0dG9vd3d0bsRGx293dEbzR0RsRERERG7ERsdvd3RHc0bERu93d3RuxEbHb3d0RHB290bu7u7sbsRGx293dERwd293d3d29EdsRsdvd3RHcsd27u7u7uxHbEbHb3d0R3MHLzMzMvBvR2xGxsN3dERy83c0AALwdzd0RsQDb3REc3N0RDADAzMzdEbEAsN0RHNu7EQwAAADA2xGxAADbERy7uxEMAAAAALwRsQAAsMwcsRuxDAAAAADAzMwAAAAAuxERywAAAAAAAAAAAAAAALDMzAwAAAAAAAAAAA=="}},"sprites.builtin.seaweed0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGaIiAAAAAAAAAAAAAAAAAAAAAAAiAAAYFV3dwgAAAAAAAAAAAAAAAAAAAAAaAgAVmdmdocAAAAAAAAAAAAAAAAAAAAAgIaIZ1d3Z3YAAAAAAAAAAAAAAAAAAAAAAGhmdmWId2cAAAAAAAAAAAAAAAAAAAAAAIB2VYhoZogAAAAAAAAAAAAAAAAAAAAAAABghmZmhgAAAAAAAAAAAAAAAAAAAAAAAAAAAIiICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.builtin.seaweed1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIiIAAAAAAAAAAAAAAAAAAAAAAAAAAAAiHd3iAAAAAAAAAAAAAAAAAAAAAAAAACAZmZmdwgAAAAAAAAAAAAAAIiIiAAAAABohoh2docAAAAAAAAAAAAAiFd1d4gAAIBmCABoZ2cAAAAAAAAAAACAd3dVZncIAICIAIiIZ3YAAAAAAAAAAAB4d4iId2aHAAAAgIiIdmYAAAAAAAAAAIBmiAAAiHdmCAAAaIiIeHcAAAAAAAAAAICGAAAAAGhmhoiIhohohnYAAAAAAAAAAGgIAAAAAICIaGZmiIZmiIgAAAAAAAAAAGgIAAAAAGh3Z2hmZniHZogAAAAAAAAAAIgAAAAAgHdndmWIaHd2hgAAAAAAAAAAAAAAAAAAeIZoZ1d1d2Z3CAAAAAAAAAAAAAAAAACAhwgAeHVmZneHAAAAAAAAAAAAAAAAAACACAAAgFZ1d4cIAAAAAAAAAAAAAAAAAAAAAAAAAGCGiAgAAAA="}},"sprites.builtin.seaweed2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQADAAAAAAAAAAAAAAAAAAAAAAgIiIiIgAAAAAAAAAAAAAAAAAAAAAAABoaGZmd3eGCAAAAAAAAAAAAAAAAAAAAGh3hoiIaGZ3hwgAAAAAAAAAAAAAAAAAgHeGaGZ2d2dmd4YAAACIAAAAAAAAAABgdmZmZoiIaHdnZncIAABoCAAAAAAAAABWZXeGiAAAiGh3ZnaHAACAhgAAAAAAAGZVdocIAACId2Z4d2Z3CAAAaIgAAACAaHdmVQYAAIh3ZmaGdmd2hwAAgGaIiIhod2ZVZgAAgHdmh4hmaHdmd4gAAIhmZnZ3d3dmAAAAeGZnCABoiHhnZncAAACIZmZmhmYAAACIZ2cIgAaAiIh3Z2YAAAAAiIiICAAAAIhohggAgGcAiHhmd4cAAAAAAAAAAAAAAAAAAAAAAHhmVWeIZoYAAAAAAAAAAAAAAAAAAAAAAIB3ZohmZggAAAAAAAAAAAAAAAAAAAAAAAB4V3VmiAAAAAAAAAAAAAAAAAAAAAAAAACAaGaIAAA="}},"sprites.builtin.shark0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgABAAAAAAAADw/wAAAAAAAPC7DwAAAAAAv7z7AAAAAPC7u8EPAAAA8LsbwfwAAAC/uxvBwQAAAL+7ETPDAAAAv7sRE8wAAAC/+x/MEQwAAL/7HxwRDAD8vLsREREMwMy8vBsR/AzAzczLvLu7D9y9vLy7u9v83Lu8y7u7u/2/y7y7u8u/+8//v7u7zMz7/wDPu8vMzfwAAPDMzMzdDAAA8MzMzM0AAADwzMy8zQAAAADPzNwMAAAAAM/MvAwAAAAA8M/8AAAAAADMv/wAAAAAwN27vA8AAADAu8u8+wAAALy7/8+7DwAAvPwA8L8PAADMAAAA8A8AAAAAAAAAAAAAAAAAAAAA"}},"sprites.builtin.shark1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgABAAAAAAAAD/DwAAAAAAAL/7AAAAAADwy7sPAAAAAPC7G/wAAAAAv7sRzA8AAAC/uxEc8wAAAL+7ETPzAAAAv7sRExwMAAC/+x/MEQwAAL/7HxwRDADwvLsREREMAMy8vLsR/AzAzbzLvLu7D9y9vLy7u9v73Lu8y7y7u/2/y7y7u8u/+7//v7u7zP37/wDPu8vM3f8AAPDMzMzdDAAA8MzMzM0AAADwzMy8zQAAAADPzNwMAAAAAM/MvAwAAAAA8MzMAAAAAADwzA8AAAAAAPzLDwAAAADA3bsPAAAAANy9y/sAAAAAvLvMuw8AAMC7+/+8+wAAwMsPAP/7AADADAAAAP8A"}},"sprites.builtin.shark2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgABAAAAAAAAD/DwAAAAAA8Lz7AAAAAADwy7sPAAAAAM+7EfwAAAAAv7sRzA8AAAC/uxEc8wAAAL+7ETPzAAAAv/sfExwMAAC/+x/MEQwAAL+7GxsRDADwvLsbEREMAMy8vLsR/AzAy7zLvLvbD8C9vLvLu7v93L28y7y7vPvfy7y7u8vM+7//v7u7zM37/w/Pu8vM3f8AAPDMzMzdDAAA8MzMzL0MAADwzMy8zQAAAADPzNzLAAAAAM/MvAwAAAAA8MzPAAAAAAD8yw8AAAAAzN27DwAAAMDdy7z7AAAAvLv/z7sPAAC8/ADwvw8AAMwAAADwDwAAAAAAAAAAAAAAAAAAAAAA"}},"sprites.builtin.shark3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgABAAAAAAAAD/DwAAAAAAAL/7AAAAAADwy7sPAAAAAPC7G/wAAAAAv7sRzA8AAAC/uxEc8wAAAL+7ETPzAAAAv7sRExwMAAC/+x/MEQwAAL/7HxwRDADwvLsREREMAMy8vLsR/AzAzbzLvLu7D9y9vLy7u9v73Lu8y7y7u/2/y7y7u8u/+7//v7u7zP37/wDPu8vM3f8AAPDMzMzdDAAA8MzMzM0AAADwzMy8zQAAAADPzNwMAAAAAM/MvAwAAAAA8MzMAAAAAADwzA8AAAAAAPzLDwAAAADA3bsPAAAAANy9y/sAAAAAvLvMuw8AAMC7+/+8+wAAwMsPAP/7AADADAAAAP8A"}},"sprites.builtin.sharkAttack0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQkABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8PAAAAAAAAv/sAAAAAAPDLuw8AAAAA8Lsb/AAAAAC/uxHMDwAAAL+7ERzzAAAAv7sRM/MAAAC/uxETHAwAAL/7H8wRDAAAv/sfHBEMAPC8uxEREQwAzLy8uxH8DMDNvMu8u7sP3L28vLu72/vcu7zLvLu7/b/LvLu7y7/7v/+/u7vM/fv/AM+7y8zd/wAA8MzMzN0MAADwzMzMzQAAAPDMzLzNAAAAAM/M3AwAAAAAz8y8DAAAAADwzMwAAAAAAPDMDwAAAAAA/MsPAAAAAMDduw8AAAAA3L3L+wAAAAC8u8y7DwAAwLv7/7z7AADAyw8A//sAAMAMAAAA/wA="},"pyQName":"sprites.builtin.shark_attack0"},"sprites.builtin.sharkAttack1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQkABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwuw8AAAAAAL+8+wAAAAAAv7vBDwAAAAC/G8H8AAAA8LsbwTEPAADwuxsxMw8AAPC7GzHBwQAA8Lv/wRzBAADwu/8RHMEAAPC7uxEREQwAzLu8uxH8DMDNu8u8u7sP3L28vLu72/vcu7zLvLu7/b/LvLu7y7/7v/+/u7vM/fv/AM+7y8zd/wAA8MzMzN0MAADwzMzMzQAAAPDMzLzNAAAAAM/M3AwAAAAAz8y8DAAAAADwzMwAAAAAAPDMDwAAAAAAwMsPAAAAAADcvfsAAAAAwN27vA8AAADAu8u8+wAAAMC7/8+7DwAAwMsA8L8PAADADAAA8A8="},"pyQName":"sprites.builtin.shark_attack1"},"sprites.builtin.sharkAttack2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQkABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw/wAAAAAAAL+7/wAAAAAAvxvB/wAAAAC/HMwRDwAAAL8RHBHBAAAAvxEzEREMAAC/ERMREQwAAL8bwRERwQAAv/8RERHxAAC//7sbwfwAwP27u7u7uw/czbu8u7vb+9y7vMu8u7v9v8u8vLvLv/u//7/LvMz9+/8Az7vLzN3/AADPzMzM3QwAAM/MzMzdDAAA8MzMvM0AAADwzMzczQAAAADPzLwMAAAAAPDMzwAAAAAAwMsPAAAAAADcvfsAAAAAwN27vA8AAADAu8u8+wAAAMC7/8+7DwAAwMsA8L8PAADADAAA8A8="},"pyQName":"sprites.builtin.shark_attack2"},"sprites.builtin.sharkAttack3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQkABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAPC7Gw8AzAAA8LvBDMwcDADwG8HBMxEMAPAbwTwzE8EA8BvBMRMcwQDwuxE8zBHBAPD7HxEREfEA8Pu/uxvB/ADwu7u7u7u7D8C/y7u7u9v7vL+7zLu7u/28v8u7u8u/+7/7u8y7zP37v//Mu8vM3f//AM/MzMzdDAAAz8zMzN0MAADwzMy8zQAAAADPzLwMAAAAAPDMzwAAAAAAwMsPAAAAAADAvfsPAAAAANy9zPsAAAAA3MvMuw8AAAC8zP+8+wAAALwMAP/7AAAAzAAAAP8="},"pyQName":"sprites.builtin.shark_attack3"},"sprites.builtin.sharkAttack4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQkABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPD//wAAAAAAv7vxDwDMDAC/G8zMzMzBAL8RHDwzE8EAvxHMMzMzEQy/ERwzM8ERDL8bwcPMHBEMv/sfEREREQ/w+7+7G8H8D/C7u7u7u7sPwLvLu7u72/u8v7vMu7u7/by/y7u7y7/7v/u7zLvM/fu//8y7y8zd//8Az8zMzN0MAADPzMzM3QwAAPDMzLzNAAAAAM/MvAwAAAAA8MzPAAAAAADAvfsPAAAAANy9zPsAAAAA3MvMuw8AAAC8zP+8+wAAALwMAP/7AAAAzAAAAP8="},"pyQName":"sprites.builtin.shark_attack4"},"sprites.builtin.sharkAttack5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQkABAAAAAAAAAAAAAAAAAAAADw/wAAAAAAAL/7DwAAAADwy7sPAAAAAPC7u8EAAAAAv7sbwQAAAAC/uxvBAAAA8Lu7G8EAAADwu7sbwQwAAPC7u//BDAAA8Lu7/8EMAADwu7v/EQwAAPC7u7sRDAAAwMu8uxsMAADcu8vMuw8AwN3Lu7vb+wDAvbvMu7v9APC7u7u7vPsA8Lu7u7u8+wDw+7u7y/z7APAPvLvM3P8AAADPzMzcDAAAAM/MzLwMAAAAz8zMywAAAADwzMzLAAAAAPDMzMsAAAAAAM+8DAAAAAAAz8wMAAAAAADP/AAAAAAAALz8AAAAAADA3bsPAAAAANy9y/sAAAAAvLvM+wAAAAC8+/+8DwAAALwMAL8PAAAAzAAA8A8="},"pyQName":"sprites.builtin.shark_attack5"},"sprites.builtin.smallOceanRock":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQIAAgAAAAAzMzMwLvLzLy9vbzc3du73N29zdzdvc3A3bvLAMzMzA=="},"pyQName":"sprites.builtin.small_ocean_rock"},"sprites.builtin.smallShelf0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABgAAADAzMzMzMz///////+83d3dvbu7u7u7u/vc3d3du83MvM3MvP/c3d3du727vL27vP/c3d3du727vL27vP/c3d3du727vL27vP/c3d3du828vM28vP/c3d3du73NvL3NvP/c3d3du73NvL3NvP/c3d3du828vM28vP/c3d3du727vL27vP/c3d3du727vL27vP/c3d3du727vL27vP/c3d3du83MvM3MvP+83d3dvbu7u7u7u/vAzMzMzMz///////8="},"pyQName":"sprites.builtin.small_shelf0"},"sprites.builtin.smallShelf1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABgAAADAzMzMzMz///////+8d3d3Z2ZmZmZmZvZ8d3d3ZsfMbMfMbP98d3d3ZmdmbGdmbP98d3d3ZmdmbGdmbP98d3d3ZmdmbGdmbP98d3d3ZsdsbMdsbP98d3d3ZmfNbGfNbP98d3d3ZmfNbGfNbP98d3d3ZsdsbMdsbP98d3d3ZmdmbGdmbP98d3d3ZmdmbGdmbP98d3d3ZmdmbGdmbP98d3d3ZsfMbMfMbP+8d3d3Z2ZmZmZmZvbAzMzMzMz///////8="},"pyQName":"sprites.builtin.small_shelf1"},"sprites.builtin.smallShelf2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"furniture","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABgAAADAzMzMzMz///////+83d29zLvb3d3d3f3c3d3d+8zM/MzMzP/c3d3d+0TE+8zMu//c3d3d+0TE+0TMu//c3d3d+8zM/czM3f/c3d3d+3fH/UTE3f/c3d3d+8zM/UTE3f/c3d3d+2bG/czM3f/c3d3d+2bG/TPM3f/c3d3d+8zM/czM3f/c3d3d+zPD+3fHu//c3d3d+8zM+8zMu//c3d3d+8zM/MzMzP+83d29zLvb3d3d3f3AzMzMzMz///////8="},"pyQName":"sprites.builtin.small_shelf2"},"sprites.builtin.tv":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"electronics","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABYAAAAAAAAAAADw/////wAAu7u7u7vMu7u7+wCwEd3d3d3Ly8y8/wAbEc3MzNzL27u8/wAbEWxmZsbL27u8/wAbEWzRZsbL27u8/wAbEWxtZsbL27u8/wAbEWxmZsbL27u8/wAbEWxmZsbL27u8/wAbEWxmZsbL27u8/wAbEWxmZsbL27u8/wAbEWxmZsbL27u8/wAbEc3MzNzL27u8/wCwEd3d3d3L28y8/wAAu7u7u7vMu7u7+wAAAAAAAADw/////wA="}},"sprites.builtin.villager1WalkFront1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAADw/wAAAAAAAP////8P4EQA///D//9OTQD/z8P89P//APA7zLzRvmP/z8zM9N80Y//PzExE3TRjD8/MTETdNGMPz8zM9N80Y//wO8y80b5j///Pw/z0//wA///D//9OTQD/////D+BEAPD/AAAAAAAA"},"pyQName":"sprites.builtin.villager1_walk_front1"},"sprites.builtin.villager1WalkFront2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAA/w8AAAAAAPD/////8A4A8P8//P/vBADw/zzMT////wC/w8wb/Wv/8MzMTP+9Y//wzMxE1L1jD/DMzETUvWMP8MzMTP/t/g8Av8PMG9TtD/D/PMxP3u0A8P8//P9PDgDw/////+4AAAD/DwAAAAAA"},"pyQName":"sprites.builtin.villager1_walk_front2"},"sprites.builtin.villager1WalkFront3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAA/w8AAAAAAPD/////7gAA8P8//P9PDgDw/zzMT97tAAC/w8wb1O0P8MzMTP/t/g/wzMxE1L1jD/DMzETUvWMP8MzMTP+9a/8Av8PMG/1u//D/PMxP////8P8//P/vBADw//////AOAAD/DwAAAAAA"},"pyQName":"sprites.builtin.villager1_walk_front3"},"sprites.builtin.villager1WalkBack1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAADw/wAAAAAAAP////8P4EQA///D//9OTQD/z8P8////APA7zMz//2P/z8zMzP//Y//PzMzM//9jD8/MzMz//2MPz8zMzP//Y//wO8zM//9j///Pw/z///wA///D//9OTQD/////D+BEAPD/AAAAAAAA"},"pyQName":"sprites.builtin.villager1_walk_back1"},"sprites.builtin.villager1WalkBack2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAA/w8AAAAAAPD/////AAAA8P8//P/vTg7w/zzM/P///wC/w8z8/z//8MzMzPz/P//wzMzM/P8/D/DMzMz8/z8P8MzMzPz/Pw8Av8PM///vDvD/PMz//98O8P8////v1ATw/////wBOAAD/DwAAAAAA"},"pyQName":"sprites.builtin.villager1_walk_back2"},"sprites.builtin.villager1WalkBack3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAA/w8AAAAAAPD/////AE4A8P8////v1ATw/zzM///fDgC/w8z//+8O8MzMzPz/Pw/wzMzM/P8/D/DMzMz8/z8P8MzMzPz/P/8Av8PM/P8///D/PMz8////8P8//P/vTg7w/////wAAAAD/DwAAAAAA"},"pyQName":"sprites.builtin.villager1_walk_back3"},"sprites.builtin.villager1WalkLeft1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAAAAAAAAAAAAAA//8AAAAAAP/M/w8AAADwzMzu////AP/MTETdPmMPz8zMRN00Yw/PzMz83zRj/8/MzLzR5P7/z8zM/ETe7f/wO8xP/d7tD//P80/0T/4A///z//8AAAD/////AAAAAPD/AAAAAAAA"},"pyQName":"sprites.builtin.villager1_walk_left1"},"sprites.builtin.villager1WalkLeft2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAAAAAAAAAAAAAA8P8PAAAAAPDP/P8A8A8Az8zM//////DPzETU7WP/8MzMTNRNY//wzMzM/+3+D/DMzMwb3u0P8MzMzE/e7Q8Av8P81E/+//D/PP9E////8P8///8P8A/w////DwAAAAD/DwAAAAAA"},"pyQName":"sprites.builtin.villager1_walk_left2"},"sprites.builtin.villager1WalkLeft3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAAAAAAAAAAAAAA8P8PAAAAAPDP/P8A8A8Az8zMz/////DPzETU7WP/8MzMTNRNY//wzMzM/01jD/DMzMwbTWMP8MzMzE/k/g8Av8P81N/t//D/PP9E3+3/8P8///9P/g/w/////wAAAAD/DwAAAAAA"},"pyQName":"sprites.builtin.villager1_walk_left3"},"sprites.builtin.villager1WalkRight1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAA/w8AAAAAAPD/////AAAA8P8///9P/g/w/zz/RN/t/wC/w/zU3+3/8MzMzE/k/g/wzMzMG01jD/DMzMz/TWMP8MzMTNRNY//wz8xE1O1j/wDPzMzP////APDP/P8A8A8AAPD/DwAAAAAAAAAAAAAA"},"pyQName":"sprites.builtin.villager1_walk_right1"},"sprites.builtin.villager1WalkRight2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAA/w8AAAAAAPD///8PAAAA8P8///8P8A/w/zz/RP///wC/w/zUT/7/8MzMzE/e7Q/wzMzMG97tD/DMzMz/7f4P8MzMTNRNY//wz8xE1O1j/wDPzMz/////APDP/P8A8A8AAPD/DwAAAAAAAAAAAAAA"},"pyQName":"sprites.builtin.villager1_walk_right2"},"sprites.builtin.villager1WalkRight3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAADw/wAAAAAAAP////8AAAAA///z//8AAAD/z/NP9E/+APA7zE/93u0Pz8zM/ETe7f/PzMy80eT+/8/MzPzfNGP/z8zMRN00Yw//zExE3T5jD/DMzO7///8AAP/M/w8AAAAAAP//AAAAAAAAAAAAAAAA"},"pyQName":"sprites.builtin.villager1_walk_right3"},"sprites.builtin.villager2WalkFront1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQNABAAAAAA8M//APDuAAD/z///7+QA8P/P/+T//wDw//y/Qb9n//////9Pfmf/////7kR+Zw//z+/uRH5nD//M7/9Pfmf/8P//v0G/Z//w///85P//AAD/z/z/7+QAAMDM/wDw7gAAAAAAAAAAAA=="},"pyQName":"sprites.builtin.villager2_walk_front1"},"sprites.builtin.villager2WalkFront2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQNABAAAAAAAP8AAAAAAAAA//z/8A4AAPD//P/vBAAA///8T/7//wD/z/8btGf/8P////90Z//w///vTnRnD/D//O5OdGcP8M/8/v/kbg8A////G07kDwD//89PTuQAAPD/zP9PDgAAAMz8/+4AAA=="},"pyQName":"sprites.builtin.villager2_walk_front2"},"sprites.builtin.villager2WalkFront3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQNABAAAAAAAMz8/+4AAADw/8z/Tw4AAP//z09O5AAA////G07kD/DP/P7/5G4P8P/87k50Zw/w///vTnRnD/D/////dGf/AP/P/xu0Z/8A///8T/7//wDw//z/7wQAAAD//P/wDgAAAP8AAAAAAA=="},"pyQName":"sprites.builtin.villager2_walk_front3"},"sprites.builtin.villager2WalkBack1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQNABAAAAAA8P//D/DuAAD/////7+QA8M/8/////wDwzPz///9n/8/M//z//2f/z8zM/P//Zw/PzMz8//9nD8/MzP///2f/8Mz8/P//Z//wz8z8///8AAD/zP//7+QAAPD//w/w7gAAAAAAAAAAAA=="},"pyQName":"sprites.builtin.villager2_walk_back1"},"sprites.builtin.villager2WalkBack2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQNABAAAAAAAP8AAAAAAADwz///AAAAAPDM///vTg4A/8z////P/wDPzP///3//8Mz8zP//f//wzMzM//9/D/DMzPz//38P8MzMzP//fw8Az8zP///vDwD/zMz//08OAPDP/P//Tg4AAP///wDvAA=="},"pyQName":"sprites.builtin.villager2_walk_back2"},"sprites.builtin.villager2WalkBack3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQNABAAAAAAAPAPAAAAAAAA//8PAO8AAPD//P//Tg4A/8/8//9PDgDPzPz//+8P8MzM//z/fw/wzMzM/P9/D/DMzMz//38P8MzMzP//f/8Az8z8/P9//wD/zMz//8//APDP/P/vTg4AAP///wAAAA=="},"pyQName":"sprites.builtin.villager2_walk_back3"},"sprites.builtin.villager2WalkLeft1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQNABAAAAAAAP8AAAAAAAAA/w8AAAAAAP/8/wAAAADw//z/////APDP/+5Ef2cP//zv7kR+Zw//////T35n/////L9B7v7//8/8/+5O5P/////v9E7kD/D/z+/+7/4A8P/M//8AAAAA8P//AAAAAA=="},"pyQName":"sprites.builtin.villager2_walk_left1"},"sprites.builtin.villager2WalkLeft2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQNABAAAAAAAPAPAAAAAAAA//8AAAAAAPDP//8A8A8A/8////////D//O9O9Gf/8M//7k7kZ//w/////+T+D/D/z/8bTuQP8P/M/+9O5A/w////Tu/+/wD///zu////AP/P/P8P8A8AAP//DwAAAA=="},"pyQName":"sprites.builtin.villager2_walk_left2"},"sprites.builtin.villager2WalkLeft3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQNABAAAAAAAPAPAAAAAAAA//8PAAAAAPDP//8A8A8A/8////////D//O9O9Gf/8M//7k7kZ//w/////+RnD/D/z/8b5GcP8P/M/+/u/g/w////Tk/k/wD///zuT+T/AP/P/P9P/g8AAP///wAAAA=="},"pyQName":"sprites.builtin.villager2_walk_left3"},"sprites.builtin.villager2WalkRight1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQNABAAAAAAAP///wAAAAD/z/z/T/4PAP///O5P5P/w////Tk/k//D/zP/v7v4P8P/P/xvkZw/w/////+RnD/DP/+5O5Gf/8P/87070Z/8A/8///////wDwz///APAPAAD//w8AAAAAAPAPAAAAAA=="},"pyQName":"sprites.builtin.villager2_walk_right1"},"sprites.builtin.villager2WalkRight2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQNABAAAAAAAP//DwAAAAD/z/z/D/APAP///O7////w////Tu/+//D/zP/vTuQP8P/P/xtO5A/w/////+T+D/DP/+5O5Gf/8P/87070Z/8A/8///////wDwz///APAPAAD//wAAAAAAAPAPAAAAAA=="},"pyQName":"sprites.builtin.villager2_walk_right2"},"sprites.builtin.villager2WalkRight3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQNABAAAAAA8P//AAAAAPD/zP//AAAA8P/P7/7v/gD////v9E7kD//P/P/uTuT////8v0Hu/v//////T35n///87+5EfmcP8M//7kR/Zw/w//z/////AAD//P8AAAAAAAD/DwAAAAAAAP8AAAAAAA=="},"pyQName":"sprites.builtin.villager2_walk_right3"},"sprites.builtin.villager3WalkFront1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQMABAAAAAA8P//D+BEAAD//0T+T00A8P//TuT//wDw/kT03b5h/+9ORPTdFGH/7+5ERL0UYQ/v7k5EvRRhD+/u7vTdFGH/8P7v9N2+Yf/w//9O5P//AAD//0T+T00AAPD//w/gRAA="},"pyQName":"sprites.builtin.villager3_walk_front1"},"sprites.builtin.villager3WalkFront2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQMABAAAAAA8P////AOAAD//0/k/wQAAP//70T+///w709E3+1r//DuRETfTWH/8O5ORNRLYQ/w7u5E1EthD/Du7k7fTf4P8O//Tt/U7Q8A///vRN7tAAD//0/kTw4AAPD////uAAA="},"pyQName":"sprites.builtin.villager3_walk_front2"},"sprites.builtin.villager3WalkFront3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQMABAAAAAA8P///+4AAAD//0/kTw4AAP//70Te7QDw709E39TtD/DuRETfTf4P8O5ORNRLYQ/w7u5E1EthD/Du7k7fTWH/8O//Tt/ta/8A///vRP7//wD//0/k/wQAAPD////wDgA="},"pyQName":"sprites.builtin.villager3_walk_front3"},"sprites.builtin.villager3WalkBack1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQMABAAAAAA8P//D+BEAAD/////Tk0A8O7//////wDw/u7//79t/+/u7v7/v23/7+7u/v+/bQ/v7u7+/79tD+/u7v7/v23/8O7u//+/bf/w7/7////8AAD/7v//Tk0AAPD//w/gRAA="},"pyQName":"sprites.builtin.villager3_walk_back1"},"sprites.builtin.villager3WalkBack2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQMABAAAAAAAP///wAAAADw/v//70QOAO/+/v////8A7+/u///b//Du7u7//9v/8O7u7v//2w/w7u7u///bD/Du7v7//9sPAO/u/v//7w4A/+7////eDgDw7/7/79QEAAD///8ATgA="},"pyQName":"sprites.builtin.villager3_walk_back2"},"sprites.builtin.villager3WalkBack3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQMABAAAAAAAP///wBOAADw////79QEAO/+////3g4A7+/////vDvDu7v7//9sP8O7u7v//2w/w7u7u///bD/Du7u7//9v/AO/u7v//2/8A/+7//////wDw7/7/70QOAAD///8AAAA="},"pyQName":"sprites.builtin.villager3_walk_back3"},"sprites.builtin.villager3WalkLeft1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQMABAAAAAA8P//AAAAAADv7v8PAAAA8O7u7v///wDv7kREvR5hD+/uTkS9FGEP7+7u9N0UYf/v7u703eT+/+/u70RE3u3/8P7/7/3e7Q/w//9P9E/+AAD/////AAAAAPD//wAAAAA="},"pyQName":"sprites.builtin.villager3_walk_left1"},"sprites.builtin.villager3WalkLeft2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQMABAAAAAAAP//AAAAAADw7v4PAPAPAO/u7v7////w7k5E1Oth//Du7kTUS2H/8O7uTt/t/g/w7u5O397tD/Du/k5E3u0P8O///95P/v8A////RP///wD/////D/APAPD//w8AAAA="},"pyQName":"sprites.builtin.villager3_walk_left2"},"sprites.builtin.villager3WalkLeft3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQMABAAAAAAAP//AAAAAADw7v4PAPAPAO/u7v7////w7k5E1Oth//Du7kTUS2H/8O7uTt9NYQ/w7u5O301hD/Du/k5E5P4P8O///97f7f8A////RN/t/wD/////T/4PAPD///8AAAA="},"pyQName":"sprites.builtin.villager3_walk_left3"},"sprites.builtin.villager3WalkRight1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQMABAAAAAA8P///wAAAAD/////T/4PAP///0Tf7f/w7///3t/t//Du/k5E5P4P8O7uTt9NYQ/w7u5O301hD/Du7kTUS2H/8O5ORNTrYf8A7+7u/v///wDw7v4PAPAPAAD//wAAAAA="},"pyQName":"sprites.builtin.villager3_walk_right1"},"sprites.builtin.villager3WalkRight2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQMABAAAAAA8P//DwAAAAD/////D/APAP///0T////w7///3k/+//Du/k5E3u0P8O7uTt/e7Q/w7u5O3+3+D/Du7kTUS2H/8O5ORNTrYf8A7+7u/v///wDw7v4PAPAPAAD//wAAAAA="},"pyQName":"sprites.builtin.villager3_walk_right2"},"sprites.builtin.villager3WalkRight3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQMABAAAAAA8P//AAAAAAD/////AAAA8P//T/RP/gDw/v/v/d7tD+/u70RE3u3/7+7u9N3k/v/v7u703RRh/+/uTkS9FGEP7+5ERL0eYQ/w7u7u////AADv7v8PAAAAAPD//wAAAAA="},"pyQName":"sprites.builtin.villager3_walk_right3"},"sprites.builtin.villager4WalkFront1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAAAPD/DwAAAADwX7X770QAAF9VtbtO/Q/wVVX89P+8D/BVtbzRbjnzX1VN9N+UuftfVUtE3ZQ5s19VS0TdlLm7X1VN9N+UOfPwVbW80W658/BVVfz0/7wPAF9VtbtO/Q8A8F+1++9EAAAA8P8PAAAA"},"pyQName":"sprites.builtin.villager4_walk_front1"},"sprites.builtin.villager4WalkFront2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAAAMD//wwAAAAAv1W7z+4AAPBVVbvrxAwAX1XF78+8DABfVcsbbbnD8FXVRP+dObPwVbVE1J25u/BVtUTUnbnD8FXVRP9NtMsAX1XLG9TtwwBfVcXv1O0MAPBVVbvbxAwAAL9Vu88MAAAAwP//DAAA"},"pyQName":"sprites.builtin.villager4_walk_front2"},"sprites.builtin.villager4WalkFront3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAAAMD//wwAAAAAv1W7zwwAAPBVVbvbxAwAX1XF79TtDABfVcsb1O3D8FXVRP9NtMvwVbVE1J25w/BVtUTUnbm78FXVRP+dObMAX1XLG225wwBfVcXvz7wMAPBVVbvrxAwAAL9Vu8/uAAAAwP//DAAA"},"pyQName":"sprites.builtin.villager4_walk_front3"},"sprites.builtin.villager4WalkBack1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAAAPD//w8AAADwv7u7z0QAAN9VtbvL/Q/wXVVVu7u8D/BVVVW9uz/zX1VVVbW7v/tfVVVVtbs/s19VVVW1u7+7X1VVVbW7P/PwVVVVvbu/+/BdVVW7u7wPAN9VtbvL/Q8A8L+7u89EAAAA8P//AAAA"},"pyQName":"sprites.builtin.villager4_walk_back1"},"sprites.builtin.villager4WalkBack2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAAAPD///8EAAAA3727y00AAPBVVbu7xAwAX1VVtbu/DABfVVW1u7/D8FVVVbW7P7PwVVVVtbu/u/BVVVW1uz/D8FVVVb27v8sAX1VVu7tPywC/Vb27u9wEAPC7u7vL1A4AAP+7u89MAAAAAP//DAAA"},"pyQName":"sprites.builtin.villager4_walk_back2"},"sprites.builtin.villager4WalkBack3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAAAAD//wwAAAAA/7u7z0wAAPC7u7vL1A4Av1W9u7vcBABfVVW7u0/L8FVVVb27v8vwVVVVtbs/w/BVVVW1u7+78FVVVbW7P7MAX1VVtbu/wwBfVVW1u78MAPBVVbu7xAwAAN+9u8tNAAAA8P///wQA"},"pyQName":"sprites.builtin.villager4_walk_back3"},"sprites.builtin.villager4WalkLeft1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAA8P//AAAAAPBfVfUPAPAP8FXV+///Pw9fVUtE3ZQ5819VTUTdlLn7X1W1xNyUObNcVVW80e6+u1xVVcxO3u3zXFVVtfve7fvwVVVVu0S+D/BVVVW7+/8PAF9VVbv7AAAAwFy1uwwAAAAA8P/MAAAA"},"pyQName":"sprites.builtin.villager4_walk_left1"},"sprites.builtin.villager4WalkLeft2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAAAP//AAAAAAD/VVUPAMAMAF9Vvf/MvMPwVbVE1E25y/BV1UTUTbnD8FVVS8xNubvAVVXFG+2+s8BVVcXs3u3DwFVVVbve7cMAX1VVtUu+ywBfVVW1u7wMAPBVVbW7zAAAAFxVu8sAAAAAwP/PDAAA"},"pyQName":"sprites.builtin.villager4_walk_left2"},"sprites.builtin.villager4WalkRight1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAAAPD/zAAAAADAXLW7DAAAAF9VVbv7AADwVVVVu/v/D/BVVVW7RL4PXFVVtfve7ftcVVXMTt7t81xVVbzR7r67X1W1xNyUObNfVU1E3ZS5+19VS0TdlDnz8FXV+///Pw/wX1X1DwDwDwDw//8AAAAA"},"pyQName":"sprites.builtin.villager4_walk_right1"},"sprites.builtin.villager4WalkRight2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQOABAAAAAAAMD/zwwAAAAAXFW7ywAAAPBVVbW7zAAAX1VVtbu8DABfVVW1S77LwFVVVbve7cPAVVXF7N7tw8BVVcUb7b6z8FVVS8xNubvwVdVE1E25w/BVtUTUTbnLAF9Vvf/MvMMA/1VVDwDADAAA//8AAAAA"},"pyQName":"sprites.builtin.villager4_walk_right2"},"sprites.dialog":{"kind":5,"retType":""},"sprites.dialog.bones":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwRCAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAD/DwAAAAAAAP8PAAAA8P8AAAAAAAAAAAAAAADfvQ8AAAAAAPDb+wAAAAAA8Nv7AAAAv90PAAAAAAAAAAAAAPC/3f8A/w8A///d/QAAAAD//939AADwu90PAAAAAAAAAAAAAPDd3d3/3f//273dvf/////bvd29////3d0PAAAAAAAAAAAAAPDdzNvd3d/d3b3b3d3d3d3dvdvd3d393d39AAD/DwAAAAAAAAD/3bvd+9/d3bvd3d3d3d3du93d3d3d///dD/Dd/w8AAAAAAADw3cvc/f7/273dvf/////bvd29///f3f/f/f/d2w8AAAAAAADw3d38/+7u3/3b++7u7u7f/dv77u7+/+//3d3c3Q8AAAAAAADf3d3v7u7u////7+7u7u7////v7u7u7u7+3d3cvQ8AAAAAAPDd///v7u7u7u7u7u7u7u7u7u7u7u7u7u7+3bvb/wAAAAAA/9/97+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+3bzdDwAAAADw3d3/7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7+z9z9AAAAAADw3d3/7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/t39AAAAAADwu93f7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/r3dDwAAAAAAv93f7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v/dDwAAAAAA8P/d7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v7/DwAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/9u9DwAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u393dDwAAAAAA/9u97+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u373dDwAAAADw293d++7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/7u7/wAAAADw3d3d/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uv93bvQ8AAADw273d++7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u393d3Q8AAAAA/7u7/+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uv93dvQ8AAAAA8N3b/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/tu9/wAAAAAA8N3d/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAA8Nu9/+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/9u9DwAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u393dDwAAAAAA/9u97+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u373dDwAAAADw293d++7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/7u7/wAAAADw3d3d/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uv93bvQ8AAADw273d++7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u393d3Q8AAAAA/7u7/+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uv93dvQ8AAAAA8N3b/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/tu9/wAAAAAA8N3d/e7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAA8Nu9/+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAAAN/97u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7t/9AAAAAAAA8P/v7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/t3/DwAAAAAA8N3/7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v3d+wAAAAAA8N3b7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v3duw8AAAAAAN/d7+7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/v/d3Q8AAAAAAN/N/O/u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7v/d3Q8AAAAA8N3L3e/u7u7u7u7u7u7u7u7u7u7u7u7u7u7u/t/9/wAAAAAA/7273e/u7u7u7u7u7u7u7u7u7u7u7u7u7v7//90PAAAAAADw283d3e/u7u7u7v7////u7u7u/v///+7u7v7d3f0AAAAAAADw3c3d3f/+/+/u7r+93/3u7u7uv73f/e7u/8/d3Q8AAAAAAADwvd3/3/3/3f3//9vd273/////293bvf/v38283Q8AAAAAAADw/90P8N3//93d3d3du93d3d3d3d273d39v9273f8AAAAAAAAA8P8AAN/d3d/d3d29293d3d3d3b3b3d393d29zN0PAAAAAAAAAAAAAPDd3f///9vd273/////293bvf//3f/d3d0PAAAAAAAAAAAAAPDduw8AAN/d//8AAAAA393//wDw/wD/3fsPAAAAAAAAAAAAAPDd+wAAAL+9DwAAAAAAv70PAAAAAADw2/0AAAAAAAAAAAAAAAD/DwAAAPD/AAAAAAAA8P8AAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.dialog.cityscape":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQwADAAAACZmZmZmZmZmZmZmZmZmZmZmZmZmd3d3QCZmZmZmZmZmZmZmZmZmZmZ2d3d3d3d3Q2ZmZmZmRGZmZmZERGZGRGR3R0dHR0d3d2ZGRGRGRGREZEZERGRERER0d3d3d3d3d2ZERERGRERERERERERERERERERERER3d2ZEREREREREREREREREREREREREdHd3d2ZERERERERERERERERERERERHR3d3d3d2ZERERERERERERERERERERERHd0dHR3d2ZGRERERERERERERERERERERHd3d3d3d2ZGRERERERERERERERERERERHd0dHR3d2ZmRERERERERERERERERERERHR3d3d3d2ZGREREREREREREREREREREREREdHd3d2ZEREREREREREREREREREREREREdHd3d2ZEREREREREREREREREREREdHd3d3d3d2ZGREREREREREREREREREREd3R0dHR3d2ZmREREREREREREREREREREd3R0dHR3d2ZGREREREREREREREREREREdHR0dHR3d2ZEREREREREREREREREREREdHd3d3d3d2ZERERERERERERERERERERERERERHd3d2ZERERERERERERERERERERERER3d3d3d2ZERERERERERERERERERERERER3d3d3d2ZGRERERERERERERERERERERERERHd3d2ZmRERERERERERERERERERERHd3d3d3d2ZGRERERERERERERERERERERHd0R3d0d2ZERERERERERERERERERERERHd3d3d3d2ZERERERERERERERERERERERHdHd3RHd2ZERERERERERERERERERERERHd3d3d3d2ZEREREREREREREREREREREREREdHd3d2ZGREREREREREREREREREREREREdHd3d2ZmREREREREREREREREREREdHd3d3d3d2ZmREREREREREREREREREREdHR0dHR3d2ZGREREREREREREREREREREdHR0dHR3d2ZGREREREREREREREREREREdHR0dHR3d2ZGREREREREREREREREREREdHd3d3d3d2ZmRERERERERERERERERERERER0d3d3d2ZGRERERERERERERERERERERER0d3d3d2ZERERERERERERERERERERERHd3d3d3d2ZERERERERERERERERERER3d0d3R3dHd2ZGRERERERERERERERERER3d3dHd0d3d2ZmRkREREREREREREREREREdHd3d3d3d2ZmRERERERERERERERERERERER3d3d3d2ZGRERERERERERERERERERERER3d3d3d2ZGRERERERERERERERERERERERHR0dHd2ZGREREREREREREREREREREd3dHR0dHd2ZGRERERkRkRERERkREZEZEd3dHR0dHd2ZmRERmZkRmRkRkZkREZmZEdHd3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3Q2ZmZmZmZmZmZmZmZmZmZmZmZmZ2d3d3QA="}},"sprites.dialog.desert":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwRCAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzYwYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzZgcAAAAwMxMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzMzNjZjYzdgcAAAAwMzMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzMzN2d2YzdgcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzMzNmZmczdgcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzZmczZgcAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzY2ZmZmdmZgYAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzdnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzY2ZmZ2ZmZgYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzM3Z3ZzNjdgcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2ZmNjNmdwcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2dwcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N2dwcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N3dwcAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N2dwcAAAAwMxMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2dwcAAAAwMzMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzM2NmZjZmdwcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzM2N3d2ZjdgcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzMzNmdmdmZgYAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzY2Zmdnd3dwcAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzY2ZmZnZmZgYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzZndmZgYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNjd2dmdgcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNjZjZmdwcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2dwcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N2dwcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N3dwcAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N2dwcAAAAwMxMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2dwcAAAAwMzMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzM2NmZjZmdwcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzM2N3d2ZjdgcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzMzNmdmdmZgYAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzY2Zmdnd3dwcAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzY2ZmZnZmZgYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzZndmZgYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNjd2dmdgcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNjZjZmdwcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2dwcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N2dwcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N3dwcAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM2N2dwcAAAAwMxMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2dwcAAAAwMzMxMzEzMzMzMzMzMzMzMzMzMzMzMzMzM2ZmNjNmdwcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzM3Z3ZzNjdgcAAAAwMzMzEzEzMzMzMzMzMzMzMzMzMzMzMzMzY2ZmZ2ZmZgYAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMzMzEzMzMzMzMzMzMzMzMzMzMzMzMzdnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzZnd3d3d3dwcAAAAwMzMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzY2ZmZmdmZgYAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzZmczZgcAAAAwMxMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNmZmczdgcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN2d2YzdgcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNjZjYzdgcAAAAwERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzZgcAAAAwExExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzYwYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.dialog.frogs":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwRCAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZmYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGBmBgAAAAAAYGZmd90GYGZmBgAAAABmZmYGAAAAAGZmBgAAYHbXbQAAAAAAhmg3c9ZtZpmZZgYAAGaWmZlmBgAAZpaZZgaIdjNn3QYAAAAAeHc3c9ZtmZmZmWYAYJaZmZmZZgBglpmZmYZ3dzNn3QYAAACAd4h3d9ZtmZmZmWlmZpmZmZmZaWZmmZmZmXiHeHdn3QYAAACAd4h3Z91tmZmZmZmZmZmZmZmZmZmZmZmZmXiHeHfW3QYAAACAd3d31t1tmZmZmZmZmZmZmZmZmZmZmZmZmXh3d2fd3QYAAAAAeHd31t1tmZmZmZmZmZmZmZmZmZmZmZmZmYl3d2fd3QYAAAAAeHd31t1tmZmZmZmZmZmZmZmZmZmZmZmZmYl3d2fd3QYAAACAd3d31t1tmZmZmZmZmZmZmZmZmZmZmZmZmXh3d2fd3QYAAACAd4h3Z91tmZmZmZmZmZmZmZmZmZmZmZmZmXiHeHfW3QYAAACAd4h3d9ZtmZmZmZmZmZmZmZmZmZmZmZmZmXiHeHdn3QYAAAAAeHc3c9ZtmZmZmZmZmZmZmZmZmZmZmZmZmYl3dzNn3QYAAAAAgGg3c9ZtmZmZmZmZmZmZmZmZmZmZmZmZmZmIdjNn3QYAAAAAZplmd92WmZmZmZmZmZmZmZmZmZmZmZmZmZmZaXbXbQAAAAAAlplpZmaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmWZmZgAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAZpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAYJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZgAAAAAAYJaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZBgAAAAAAAGaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlpBgAAAAAAAGCZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlmAAAAAAAAAGCZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkGAAAAAAAAAGCZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkGAAAAAAAAAGaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkGAAAAAAAAYJaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlmAAAAAAAAYJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlpBgAAAAAAZpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZBgAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZgAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAZpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAYJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZgAAAAAAYJaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZBgAAAAAAAGaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlpBgAAAAAAAGCZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlmAAAAAAAAAGCZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkGAAAAAAAAAGCZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkGAAAAAAAAAGaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkGAAAAAAAAYJaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlmAAAAAAAAYJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlpBgAAAAAAZpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZBgAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZZgAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZaQAAAAAAlplpZmaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmWZmZgAAAAAAZplmd92WmZmZmZmZmZmZmZmZmZmZmZmZmZmZaXbXbQAAAAAAgGg3c9ZtmZmZmZmZmZmZmZmZmZmZmZmZmZmIdjNn3QYAAAAAeHc3c9ZtmZmZmZmZmZmZmZmZmZmZmZmZmYl3dzNn3QYAAACAd4h3d9ZtmZmZmZmZmZmZmZmZmZmZmZmZmXiHeHdn3QYAAACAd4h3Z91tmZmZmZmZmZmZmZmZmZmZmZmZmXiHeHfW3QYAAACAd3d31t1tmZmZmZmZmZmZmZmZmZmZmZmZmXh3d2fd3QYAAAAAeHd31t1tmZmZmZmZmZmZmZmZmZmZmZmZmYl3d2fd3QYAAAAAeHd31t1tmZmZmZmZmZmZmZmZmZmZmZmZmYl3d2fd3QYAAACAd3d31t1tmZmZmZmZmZmZmZmZmZmZmZmZmXh3d2fd3QYAAACAd4h3Z91tmZmZmZmZmZmZmZmZmZmZmZmZmXiHeHfW3QYAAACAd4h3d9ZtmZmZmWZmlpmZmZmZZmaWmZmZmXiHeHdn3QYAAAAAeHc3c9ZtmZmZaQYAZpmZmZlpBgBmmZmZmYZ3dzNn3QYAAAAAhmg3c9ZtZplpZgAAYGaZmWlmAABgZpmZZgaIdjNn3QYAAAAAYGZmd90GYGZmAAAAAGBmZmYAAAAAYGZmBgAAYHbXbQAAAAAAAABgZmYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGZmBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.dialog.hugeLeaf":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQwADAAAACIiAAAiAAAiAgAgAiIAACICACACAAAiIhod4iAZwiAdoYAaIdnCIB2hgBohwCId4Z4dmeId4doZ2eId4d3h2hnZ4h3h4h2Z4d4Z3eGZ3d4Z3d4Z2dnd3hnd3hnZ2h3doeAd3hmd3Z4Z3d4dmd3dnhnd3h2Z2aHdwiAdodmdmZoZ2dodoZ2ZmhnZ2h2hmZ4ZwgAaGZoaGeIhoaIZ4hoZ4iGhmhniIZmhgAAgGaGiIiIiIiIiIiIiIiIiIiIiGiGiIiAaIaIZmZmZmZmZmZmZmZmZmZmZoh2d4d4d2eIZmZmZmZmZmZmZmZmZmZmZmh3doZoZ3eGZmZmZmZmZmZmZmZmZmZmZnhmdwiAd2aHZmZmZmZmZmZmZmZmZmZmZmh2hwAAeGeGZmZmZmZmZmZmZmZmZmZmZoiIiAAAiIiIZmZmZmZmZmZmZmZmZmZmZoh2ZwiAdmeIZmZmZmZmZmZmZmZmZmZmZmh3d4Zod3eGZmZmZmZmZmZmZmZmZmZmZohmZod4ZmaIZmZmZmZmZmZmZmZmZmZmZmh3d4Zod3eGZmZmZmZmZmZmZmZmZmZmZoh2ZwiAdmeIZmZmZmZmZmZmZmZmZmZmZoiIiAAAiIiIZmZmZmZmZmZmZmZmZmZmZmh2hwAAeGeGZmZmZmZmZmZmZmZmZmZmZnhmdwiAd2aHZmZmZmZmZmZmZmZmZmZmZmh3doZoZ3eGZmZmZmZmZmZmZmZmZmZmZoh2d4d4d2eIZmZmZmZmZmZmZmZmZmZmZohohgiAaIaIZmZmZmZmZmZmZmZmZmZmZoh2d4d4d2eIZmZmZmZmZmZmZmZmZmZmZmh3doZoZ3eGZmZmZmZmZmZmZmZmZmZmZnhmdwiAd2aHZmZmZmZmZmZmZmZmZmZmZmh2hwAAeGeGZmZmZmZmZmZmZmZmZmZmZoiIiAAAiIiIZmZmZmZmZmZmZmZmZmZmZoh2ZwiAdmeIZmZmZmZmZmZmZmZmZmZmZmh3d4Zod3eGZmZmZmZmZmZmZmZmZmZmZohmZod4ZmaIZmZmZmZmZmZmZmZmZmZmZmh3d4Zod3eGZmZmZmZmZmZmZmZmZmZmZoh2ZwiAdmeIZmZmZmZmZmZmZmZmZmZmZoiIiAAAiIiIZmZmZmZmZmZmZmZmZmZmZmh2hwAAeGeGZmZmZmZmZmZmZmZmZmZmZnhmdwiAd2aHZmZmZmZmZmZmZmZmZmZmZmh3doZoZ3eGZmZmZmZmZmZmZmZmZmZmZoh2d4d4d2eIZmZmZmZmZmZmZmZmZmZmZohohgiIiGiGiIiIiIiIiIiIiIiIiIiIiGhmCAAAaGZoiHaGaGiIdoaIdoZoaIh2hoZmhgCAdodmaGeGdnaGZmdoZ4Z2doZmZ2Z4ZwiAd3hmdmeHd3aHZ3d2Z4d3dodnd2aHdwh4Z3eGdnaHd3aHd3Z2dod3dod3dmh3dod4dmeIeHeIdnaGeHd4d4h2doZ4d4h2Z4dod4gAeIYAaGcIgHZ4hgBoZwiAdgiId4aIiAAAgAgAgIgAAIiACACAiAAAiAAAiIg="},"pyQName":"sprites.dialog.huge_leaf"},"sprites.dialog.largeShell":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQqACoAAAAAzMwMADMDAAAzAwAAMwMAwMzMAAAAAADAMzvDMJk5ADCZOQAwmTkAPLMzDAAAAAA8O7M7nJmZM5OZmTOTmZnGszuzwwAAAAA8szM7nBGRmZkRkZmZEZHJszM7wwAAAAC8MzuzHJkZmRmZGZkZmRnJO7MzywAAAAA8O7O7vJmZEZGZmRGRmZnLuzuzwwAAAAA8u7PbsRERmRkREZkZEREbvTu7wwAAAADAM7sdGxERERERERERERGx0bszDAAAAAAAzMyxERERERERERERERERG8zMAAAAAAAAk7kbERERERERERERERERsRuZAwAAAAAwmZEREREREREREREREREREZmROQAAAACTGZkREREREREREREREREREZmROQAAAACTGZkREREREREREREREREREZmROQAAAACTGZkRERERERERERERERERERmZAwAAAAAwmZERERERERERERERERERkZE5AAAAAAAAkxkZERERERERERERERERkZE5AAAAAAAAkxkZERERERERERERERERkZE5AAAAAAAAkxkZERERERERERERERERERmZAwAAAAAwmZEREREREREREREREREREZmROQAAAACTGZkREREREREREREREREREZmROQAAAACTGZkREREREREREREREREREZmROQAAAACTGZkRERERERERERERERERERmZAwAAAAAwmZERERERERERERERERERkZE5AAAAAAAAkxkZERERERERERERERERkZE5AAAAAAAAkxkZERERERERERERERERkZE5AAAAAAAAkxkZERERERERERERERERERmZAwAAAAAwmZEREREREREREREREREREZmROQAAAACTGZkREREREREREREREREREZmROQAAAACTGZkREREREREREREREREREZmROQAAAACTGZkRERERERERERERERERERmZAwAAAAAwmbEbERERERERERERERERsZs5AAAAAAAAzMyxERERERERERERERERG8zMAAAAAADAM7sdGxERERERERERERGx0bszDAAAAAA8u7PbsRERkZkREZGZEREbvTu7wwAAAAA8O7O7vJmZGRGZmRkRmZnLuzuzwwAAAAC8MzuznJGZkZmRmZGZkZnBO7MzywAAAAA8szM7nBkRmZkZEZmZGRHJszM7wwAAAAA8O7M7PJmZOTOZmTkzmZnJszuzwwAAAADAMzvDAJOZAwCTmQMAk5kDPLMzDAAAAAAAzMwMADAzAAAwMwAAMDMAwMzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.dialog.large_shell"},"sprites.dialog.largeStar":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQqACoAAAAAsMsAAAAAAAAAAAAAAAAAALDLAAAAAAAAXLvMALC7uwCwu7sAsLu7AFy7zAAAAADAW1W1u7vdvbu73b27u929y1tVtQAAAABcVVW7EdvdGxHb3RsR2927XFVVuwAAAABcVVW7EbG9ERGxvRERsb3bXFVVuwAAAADAW1W1ERHdHRER3R0REd0RwVtVtQAAAAAAXLvMEdER0RHREdER0REREVy7zAAAAAAAu8sREREREREREREREREREb3LAAAAAACwvdsREREREREREREREREREd29AAAAAACw3dsRERERERERERERERERERG9AAAAAACw3d0RERERERERERERERERERGxAAAAAACw2xsdERERERERERERERERERGxAAAAAAAAuxERERERERERERERERERERG7AAAAAAAAGxERERERERERERERERER0bG9CwAAAAAAGxEREREREREREREREREREd3dCwAAAACwGxEdEREREREREREREREREb3dCwAAAACwvdERERERERERERERERERER3bCwAAAACw3dsRERERERERERERERER0RGxCwAAAACw3d0RERERERERERERERERERGxAAAAAACw2xsdERERERERERERERERERGxAAAAAAAAuxERERERERERERERERERERG7AAAAAAAAGxERERERERERERERERER0bG9CwAAAAAAGxEREREREREREREREREREd3dCwAAAACwGxEdEREREREREREREREREb3dCwAAAACwvdERERERERERERERERERER3bCwAAAACw3dsRERERERERERERERER0RGxCwAAAACw3d0RERERERERERERERERERGxAAAAAACw2xsdERERERERERERERERERGxAAAAAAAAuxERERERERERERERERERERG7AAAAAAAAGxERERERERERERERERER0bG9CwAAAAAAGxEREREREREREREREREREd3dCwAAAAAA2xEdEREREREREREREREREb3dCwAAAAAAu8sdEREREREREREREREREb3LCwAAAAAAXLvMEREREREREREREREREVy7zAAAAADAW1W1HREdER0RHREdER0RzVtVtQAAAABcVVW73d0REdHdERHR3RERXFVVuwAAAABcVVW7vdsbERHbGxER2xsRXFVVuwAAAADAW1W1u929EbHdvRGx3b0RzVtVtQAAAAAAXLvM2927u9vdu7vb3bu7u1y7zAAAAAAAsMsAsLsLALu7CwC7uwsAALDLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.dialog.large_star"},"sprites.dialog.mediumStar":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQhACEAAAAAsMsAAAAAAAAAAAAAsMsAAAAAAABcu8wAsLu7ALC7uwBcu8wAAAAAwFtVtbu73b27u929y1tVtQAAAABcVVW7EdvdGxHb3btcVVW7AAAAAFxVVbsRsb0REbG921xVVbsAAAAAwFtVtRER3R0REd0RwVtVtQAAAAAAXLvMEdER0RHRERERXLvMAAAAAAC7yxERERERERERERG9ywAAAAAAsL3dERERERERERERER3bCwAAAACw3dsRERERERERERHREbELAAAAALDd3RERERERERERERERsQAAAAAAsNsbHRERERERERERERGxAAAAAAAAuxEREREREREREREREbsAAAAAAAAbEREREREREREREdGxvQsAAAAAABsREREREREREREREd3dCwAAAACwGxEdERERERERERERvd0LAAAAALC90REREREREREREREd2wsAAAAAsN3bERERERERERER0RGxCwAAAACw3d0REREREREREREREbEAAAAAALDbGx0RERERERERERERsQAAAAAAALsRERERERERERERERG7AAAAAAAAGxERERERERERERHRsb0LAAAAAAAbERERERERERERERHd3QsAAAAAANsRHREREREREREREb3dCwAAAAAAu8sdERERERERERERvcsLAAAAAABcu8wRERERERERERFcu8wAAAAAwFtVtR0RHREdER0RzVtVtQAAAABcVVW70d0REdHdERFcVVW7AAAAAFxVVbsR2xsREdsbEVxVVbsAAAAAwFtVtbHdvRGx3b0RzVtVtQAAAAAAXLvM2927u9vdu7u7XLvMAAAAAACwywC7uwsAu7sLAACwywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.dialog.medium_star"},"sprites.dialog.mediumShell":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQhACEAAAAAzMwMADMDAAAzAwDAzMwAAAAAAMAzO8MwmTkAMJk5ADyzMwwAAAAAPDuzO5yZmTOTmZnGszuzwwAAAAA8szM7nBGRmZkRkcmzMzvDAAAAALwzO7McmRmZGZkZyTuzM8sAAAAAPDuzu7yZmRGRmZnLuzuzwwAAAAA8u7PbsRERmRkRERu9O7vDAAAAAMAzux0bERERERERsdG7MwwAAAAAAMzMsRERERERERERG8zMAAAAAAAAk7kbERERERERERGxG5kDAAAAADCZkRERERERERERERGZkTkAAAAAkxmZEREREREREREREZmROQAAAACTGZkRERERERERERERmZE5AAAAAJMZmREREREREREREREZmQMAAAAAMJmRERERERERERERkZE5AAAAAAAAkxkZERERERERERGRkTkAAAAAAACTGRkREREREREREZGROQAAAAAAAJMZGRERERERERERERmZAwAAAAAwmZERERERERERERERmZE5AAAAAJMZmRERERERERERERGZkTkAAAAAkxmZEREREREREREREZmROQAAAACTGZkRERERERERERERGZkDAAAAADCZsRsREREREREREbGbOQAAAAAAAMzMsRERERERERERG8zMAAAAAADAM7sdGxEREREREbHRuzMMAAAAADy7s9uxERGRmRERG707u8MAAAAAPDuzu7yZmRkRmZnLuzuzwwAAAAC8MzuznJGZkZmRmcE7szPLAAAAADyzMzucGRGZmRkRybMzO8MAAAAAPDuzOzyZmTkzmZnJszuzwwAAAADAMzvDAJOZAwCTmQM8szMMAAAAAADMzAwAMDMAADAzAMDMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.dialog.medium_shell"},"sprites.dialog.mediumLeaf0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQhACEAAACIiAAAiAAAiAgAgAgAAIiIAAAAAGh3iIBnCIB2hgBohwCId4YAAAAAeHZniHeHaGdniHeHiHZnhwAAAAB4Z3eGZ3d4Z3d4Z2dod3aHAAAAAIB3eGZ3dnhnd3h2Z2aHdwgAAAAAgHaHZnZmaGdnaHaGZnhnCAAAAAAAaGZoaGeIhoZoZ4iGZoYAAAAAAACAZoaIiIiIiIiIiGiGiIgAAAAAgGiGiGZmZmZmZmZmiHZ3hwAAAAB4d2eIZmZmZmZmZmZod3aGAAAAAGhnd4ZmZmZmZmZmZnhmdwgAAAAAgHdmh2ZmZmZmZmZmaHaHAAAAAAAAeGeGZmZmZmZmZmaIiIgAAAAAAACIiIhmZmZmZmZmZoh2ZwgAAAAAgHZniGZmZmZmZmZmaHd3hgAAAABod3eGZmZmZmZmZmaIZmaHAAAAAHhmZohmZmZmZmZmZmh3d4YAAAAAaHd3hmZmZmZmZmZmiHZnCAAAAACAdmeIZmZmZmZmZmaIiIgAAAAAAACIiIhmZmZmZmZmZmh2hwAAAAAAAHhnhmZmZmZmZmZmeGZ3CAAAAACAd2aHZmZmZmZmZmZod3aGAAAAAGhnd4ZmZmZmZmZmZoh2d4cAAAAAeHdniGZmZmZmZmZmiGiGCAAAAACIiGiGiIiIiIiIiIhoZggAAAAAAABoZmiIdoZoaIh2hoZmhgAAAAAAgHaHZmhnhnZ2hmZnZnhnCAAAAACAd3hmdmeHd3aHZ3dmh3cIAAAAAHhnd4Z2dod3dod3dmh3docAAAAAeHZniHh3iHZ2hnh3iHZnhwAAAABod4gAeIYAaGcIgHYIiHeGAAAAAIiIAACACACAiAAAiAAAiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.dialog.medium_leaf0"},"sprites.dialog.mediumLeaf1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQhACEAAACIiAgAiIiIiIiIiIgAAIiIAAAAAHh3hoh4d3h3eHd4d4iIdocAAAAAeHd3iHZ2eHZ2dnh2hnZ3hwAAAABoZ3eGZ3Z2Zmd2dmZnd3aHAAAAAIh3doZnd3ZnZ3d2Z2dnd4YAAAAAgHZnhmdnaHdnZ2h3h3Z3CAAAAACAaIaIiIiIiIiIiIiIZoYIAAAAAIh2d4hmZmZmZmZmZoiIiIgAAAAAeGd2aGZmZmZmZmZmhndniAAAAAB4ZndoZmZmZmZmZmaGZnaHAAAAAHh3Z2hmZmZmZmZmZoZ3ZocAAAAAiGiGaGZmZmZmZmZmhnZ3hwAAAAB4d2doZmZmZmZmZmaGaIaIAAAAAHhmd2hmZmZmZmZmZoZ2d4cAAAAAeGdmaGZmZmZmZmZmhndmhwAAAACIdndoZmZmZmZmZmaGZ3aHAAAAAHhndmhmZmZmZmZmZoZ3Z4gAAAAAeGZ3aGZmZmZmZmZmhmZ2hwAAAAB4d2doZmZmZmZmZmaGd2aHAAAAAIhohmhmZmZmZmZmZoZ2d4cAAAAAeHdnaGZmZmZmZmZmhmiGiAAAAAB4ZndoZmZmZmZmZmaGdneHAAAAAHhnZmhmZmZmZmZmZoZ3ZocAAAAAgHZ3aGZmZmZmZmZmhmd2hwAAAACAiIiIZmZmZmZmZmaId2cIAAAAAIBoZoiIiIiIiIiIiIhohggAAAAAgHdneHeGdnZ3hnZ2aHZnCAAAAABod3Z2dmd3dnZnd3ZoZ3cIAAAAAHhnd3ZmZ2d2Zmdndmh3doYAAAAAeHdnaGeHZ2dnh2dniHd3hwAAAAB4Z4iId4d3h3eHd4eIaHeHAAAAAIiIAACIiIiIiIiIiACAiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.dialog.medium_leaf1"},"sprites.dialog.pineday":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQwADAAAAARERERERERERERERERERERERERERERmZkRkZmZmZmZmZmZmZmZmZmZmZmWaZmWZpYRmZmZmZmZmZmZmZmZmZmZmZlmaWZmZpYRmZmZmZmZmZmZmZmZmZmZaWZmZmZmZpaRmZmZmZmZmZmZmZmZmZmZmWlplmaWZpaRmZmZmZmZmZmZmZmZmZmZmZmZlmaZZpaRmZmZmZmZmZmZmZmZmZmZmZmZmZmZlpYRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZYRmZmZmZmZmZmZmZmZmZmZmZmZmZlpaZYRkZmZmZmZmZmZmZmZmZmZmZmZmZlmZpYRkZmZmZmZmZmZmZmZmZmZmZmZaWZmZpYRkZmZmZmZmZmZmZmZmZmZmZlpaWZmZpYRmZmZmZmZmZmZmZmZmZmZmWZmZmZmZpYRmZmZmZmZmZmZmZmZmZmZmWlpaWZmZpYRmZmZmZmZmZmZmZmZmZmZmZmZaZmWZpYRmZmZmZmZmZmZmZmZmZmZmZmZmZmZZpYRkZmZmZmZmZmZmZmZmZmZmZmZmZmZZpYRkZmZmZmZmZmZmZmZmZmZmZmZmZZmZpYRmZmZmZmZmZmZmZmZmZmZmZlpZmZmZpYRmZmZmZmZmZmZmZmZmZmZmZmZaWZmZpaRmZmZmZmZmZmZmZmZmZmZmZmZmZZmZpaRmZmZmZmZmZmZmZmZmZmZmZmZmZmZZpaRmZmZmZmZmZmZmZmZmZmZmZmZmZmZZpYRmZmZmZmZmZmZmZmZmZmZmZmZmZmZZpYRmZmZmZmZmZmZmZmZmZmZmZmZmZlpZpYRkZmZmZmZmZmZmZmZmZmZmZmZmZZmZpYRkZmZmZmZmZmZmZmZmZmZmZmZZmZmZpYRkZmZmZmZmZmZmZmZmZmZmZlmZmZmZpYRmZmZmZmZmZmZmZmZmZmZmZmZlpZmZpYRmZmZmZmZmZmZmZmZmZmZmZmZmZaWZpYRmZmZmZmZmZmZmZmZmZmZmZmZmZmZZpYRmZmZmZmZmZmZmZmZmZmZmZmZmZmZZpYRkZmZmZmZmZmZmZmZmZmZmZmZmZZmZpYRkZmZmZmZmZmZmZmZmZmZmZlpmWZmZpYRmZmZmZmZmZmZmZmZmZmZmWZmZmZmZpYRmZmZmZmZmZmZmZmZmZmZmZmWZmlmZpaRmZmZmZmZmZmZmZmZmZmZmZmZaZlpZpaRmZmZmZmZmZmZmZmZmZmZmZmZmZlmZpaRmZmZmZmZmZmZmZmZmZmZmZmZmZlmZpYRmZmZmZmZmZmZmZmZmZmZmZmZlmZmZpYRmZmZmZmZmZmZmZmZmZmZmZZmZmZmZpYRkZmZmZmZmZmZmZmZmZmZaWZmZmZmZpYRkZmZmZmZmZmZmZmZmZmZmZmWlmZmZpYRkZmZmZmZmZmZmZmZmZmZmZmZmWlmZpYRmZmZmZmZmZmZmZmZmZmZmZlpaWZmZpYRmZmZmZmZmZmZmZmZmZmZmWlmZmZmZpYRmZmZmZmZmZmZmZmZmZmZmZmZaWlmZpYRERERERERERERERERERERERERERGZmZk="}},"sprites.dialog.pinenight":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQwADAAAACZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiYiIiIiIiIiIiIiIiIiIiIiGaIiGZpaZiIiIiIiIiIiIiIiIiIiIiIhmaGZmZpaZiIiIiIiIiIiIiIiIiIiIaGZmZmZmZpaJiIiIiIiIiIiIiIiIiIiIiGhohmaGZpaJiIiIiIiIiIiIiIiIiIiIiIiIhmaIZpaJiIiIiIiIiIiIiIiIiIiIiIiIiIiIhpaZiIiIiIiIiIiIiIiIiIiIiIiIiIiIiJaZiIiIiIiIiIiIiIiIiIiIiIiIiIhoaJaZiYiIiIiIiIiIiIiIiIiIiIiIiIhmZpaZiYiIiIiIiIiIiIiIiIiIiIiIaGZmZpaZiYiIiIiIiIiIiIiIiIiIiIhoaGZmZpaZiIiIiIiIiIiIiIiIiIiIiGZmZmZmZpaZiIiIiIiIiIiIiIiIiIiIiGhoaGZmZpaZiIiIiIiIiIiIiIiIiIiIiIiIaIiGZpaZiIiIiIiIiIiIiIiIiIiIiIiIiIiIZpaZiYiIiIiIiIiIiIiIiIiIiIiIiIiIZpaZiYiIiIiIiIiIiIiIiIiIiIiIiIZmZpaZiIiIiIiIiIiIiIiIiIiIiIhoZmZmZpaZiIiIiIiIiIiIiIiIiIiIiIiIaGZmZpaJiIiIiIiIiIiIiIiIiIiIiIiIiIZmZpaJiIiIiIiIiIiIiIiIiIiIiIiIiIiIZpaJiIiIiIiIiIiIiIiIiIiIiIiIiIiIZpaZiIiIiIiIiIiIiIiIiIiIiIiIiIiIZpaZiIiIiIiIiIiIiIiIiIiIiIiIiIhoZpaZiYiIiIiIiIiIiIiIiIiIiIiIiIZmZpaZiYiIiIiIiIiIiIiIiIiIiIiIZmZmZpaZiYiIiIiIiIiIiIiIiIiIiIhmZmZmZpaZiIiIiIiIiIiIiIiIiIiIiIiIhoZmZpaZiIiIiIiIiIiIiIiIiIiIiIiIiIaGZpaZiIiIiIiIiIiIiIiIiIiIiIiIiIiIZpaZiIiIiIiIiIiIiIiIiIiIiIiIiIiIZpaZiYiIiIiIiIiIiIiIiIiIiIiIiIZmZpaZiYiIiIiIiIiIiIiIiIiIiIhoiGZmZpaZiIiIiIiIiIiIiIiIiIiIiGZmZmZmZpaZiIiIiIiIiIiIiIiIiIiIiIiGZmhmZpaJiIiIiIiIiIiIiIiIiIiIiIiIaIhoZpaJiIiIiIiIiIiIiIiIiIiIiIiIiIhmZpaJiIiIiIiIiIiIiIiIiIiIiIiIiIhmZpaZiIiIiIiIiIiIiIiIiIiIiIiIhmZmZpaZiIiIiIiIiIiIiIiIiIiIiIZmZmZmZpaZiYiIiIiIiIiIiIiIiIiIaGZmZmZmZpaZiYiIiIiIiIiIiIiIiIiIiIiGhmZmZpaZiYiIiIiIiIiIiIiIiIiIiIiIiGhmZpaZiIiIiIiIiIiIiIiIiIiIiIhoaGZmZpaZiIiIiIiIiIiIiIiIiIiIiGhmZmZmZpaZiIiIiIiIiIiIiIiIiIiIiIiIaGhmZpaZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZk="}},"sprites.dialog.smallIndustrial0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAzu7u7u7u7u7u7u8vTMzMzMzMzMzMzs8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTPTMzMzMzMzMzM8zTMzMzMzMzMzMzs8wzu7u7u7u7u7u7u8s="},"pyQName":"sprites.dialog.small_industrial0"},"sprites.dialog.smallIndustrial1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAzM7u7u7u7u7u7u7vTPTMzMzMzMzMzs7vTM7s7MzMzMzO7O7vTMz07MzMzMzM9O7vTMz07MzMzMzM9O7vTM7s7MzMzMzO7O7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTMzMzMzMzMzMzM7vTM7s7MzMzMzO7O7vTMz07MzMzMzM9O7vTMz07MzMzMzM9O7vTM7s7MzMzMzO7O7vTPTMzMzMzMzMzs7szM7u7u7u7u7u7u7s="},"pyQName":"sprites.dialog.small_industrial1"},"sprites.dialog.smallBlue0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAmZmZmZmZmZmZmQCQaWZmZmZmZmZmlgmZZmZmZmZmZmZmZplpZmZmZmZmZmZmZpZpFhERERERERERYZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpEREREREREREREZZpFhERERERERERYZZpZmZmZmZmZmZmZpaZZmZmZmZmZmZmZpmQaWZmZmZmZmZmlgkAmZmZmZmZmZmZmQA="},"pyQName":"sprites.dialog.small_blue0"},"sprites.dialog.smallBlue1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAZmZmZmZmZmZmZgBglpmZmZmZmZmZaQZmmZmZmZmZmZmZmWaWmZmZmZmZmZmZmWmWGRERERERERERkWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWEREREREREREREWmWGRERERERERERkWmWmZmZmZmZmZmZmWlmmZmZmZmZmZmZmWZglpmZmZmZmZmZaQYAZmZmZmZmZmZmZgA="},"pyQName":"sprites.dialog.small_blue1"},"sprites.dialog.smallDefault":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAu7u7u7u7u7u7uwCwHRERERERERERvQvb0bu7u7u7u7u70bsbvR0RERERERHRG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbuxERERERERERG7sbvR0RERERERHRG7vb0bu7u7u7u7u70buwHRERERERERERvQsAu7u7u7u7u7u7uwA="},"pyQName":"sprites.dialog.small_default"},"sprites.dialog.smallSwirlyWhite":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAu7u7u7u7u7u7uwCwuxG7EbsRuxG7EQsbG7EbsRuxG7Ebsbsbsbu7u7u7u7u7G7u7sRsRERERERGxG7G7uxERERERERERu7EbuxERERERERERu7sbsRERERERERERG7u7sRERERERERERG7G7uxERERERERERu7EbuxERERERERERu7sbsRERERERERERG7u7sRERERERERERG7G7uxERERERERERu7EbuxERERERERERu7sbsRERERERERERG7u7sRERERERERERG7G7uxERERERERERu7EbuxERERERERERu7sbsRsRERERERGxG7u7sbu7u7u7u7u7G7G7G7EbsRuxG7EbsbGwEbsRuxG7EbsRuwsAu7u7u7u7u7u7uwA="},"pyQName":"sprites.dialog.small_swirly_white"},"sprites.dialog.smallSwirlyPurple":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAqrqruqu6q7qrqgCw3bu63brdut263Qrb3a3brdut263b3a3b3b2ruqu6q7rb3a263RsRERERERGx3auruxERERERERERq7vbuhERERERERERu7rarRERERERERER2qu6rRERERERERER2q2ruxERERERERERq73buhERERERERERu7rarRERERERERER2qu6rRERERERERER2q2ruxERERERERERq73buhERERERERERu7rarRERERERERER2qu6rRERERERERER2q2ruxERERERERERq727uhERERERERERu7q73RsRERERERGx3avb3b2ruqu6q7rb3a3b3b3avdq92r3a3a2w3avdq92r3au73QoAqrqruqu6q7qrqgA="},"pyQName":"sprites.dialog.small_swirly_purple"},"sprites.dialog.smallDialogLeftThin":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAMDMzMzMzMwAAMAAwNsREREREdHLAMsA3BERERERERHRvMHAHRERERERERERHcGwEREREREREREREcvcERERERERERER0QwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQwcEREREREREREREQzcERERERERERER0QywERERERERERERsQDAHRERERERERERzQAA3BERERERERHRDAAAwNsREREREdHLAAAAAMDMzMzMzMwAAAA="},"pyQName":"sprites.dialog.small_dialog_left_thin"},"sprites.dialog.smallDialogLeftThick":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAMDMzMzMzMwMAMwAwNsREREREb3MsM0A3BERERERERHNHM3AHRERERERERHREcywERERERERERER0czcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQzcERERERERERERzQywERERERERERERywDAHRERERERERHRzAAA3BERERERERHNDAAAwNsREREREb3MAAAAAMDMzMzMzMwAAAA="},"pyQName":"sprites.dialog.small_dialog_left_thick"},"sprites.dialog.smallDialogCenterThin":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAMDMzMzMzAwAAAAAwNsREREREb0MAAAA3BERERERERHNAADAHRERERERERHRDACwERERERERERERCwDcERERERERERERzQAcERERERERERERwQAcERERERERERERwQAcERERERERERERwQAcERERERERERERzQAcERERERERERERsQwcEREREREREREREcEcERERERERERERsQwcERERERERERERzQAcERERERERERERwQAcERERERERERERwQAcERERERERERERwQAcERERERERERERwQDcERERERERERERzQCwERERERERERERCwDAHRERERERERHRDAAA3BERERERERHNAAAAwNsREREREb0MAAAAAMDMzMzMzAwAAAA="},"pyQName":"sprites.dialog.small_dialog_center_thin"},"sprites.dialog.smallDialogcenterThick":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAMDMzMzMzMwAAAAAwNsREREREb3MAAAA3BERERERERHNDADAHRERERERERHRzACwERERERERERERywDcERERERERERERzQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERzQwcERERERERERERsQwcEREREREREREREcEcERERERERERERsQwcERERERERERERzQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQwcERERERERERERwQzcERERERERERERzQywERERERERERERywDAHRERERERERHRzAAA3BERERERERHNDAAAwNsREREREb3MAAAAAMDMzMzMzMwAAAA="},"pyQName":"sprites.dialog.small_dialogcenter_thick"},"sprites.dialog.starryclouds":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dialog","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwRCAEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCqAAAAAAAA3d0AAAAAAADd3QAAAAAAMAMAAAAzAAAAAAAAAFqjADAzAwDQERHd3d0NANAREd3d3Q0AMDkAADBTCgAAAAAAqlM1qjo5OdAdERHRHRHR3R0REdEdEdENk5kzqjpVCgAAAAAwVVVVVTqZOdMREREREZER3RERERERkRE9mZk5WlVVowAAAAAwU1VVpZOZmRMREREREZkZERERERERmRkxk5kzM1VVVQoAAAAAM1VVozOZORERVREREZERERFVERERkRERk5MzM1VVNQoAAAAAoFVVpTGTMxERVRERERERERFVERERERERMTMTWlVVowoAAAAAoDVTpREzExERERERERERERERERERERERERERWjVVCgAAAAAAoDqjqhERERERERERERERERERERERERERGRERqqpaCgAAAAAAMDMTERERkREREREREREREREREREREREREVEVETGjCgAAAAAAMDkzEVUREREREREREREREREREREREREREVEVETM5MwAAAAAAk5k5EVURERERERERERERERERERERERERERERMZOZOQAAAAAwmZkzERERERERERERERERERERERERERERERERMZmZMwAAAAAwk5k5ERERERERERERERERERERERERERERERERMZOZOQAAAAAAMDkTkRERERERERERERERERERERERERERERGRETM5AwAAAAAAADMREREREREREREREREREREREREREREREREREREzAAAAAAAA0B0RERERERERERERERERERERERERERERERERERHRDQAAAAAA0BERERERERERERERERERERERERERERERERERERERDQAAAAAAHZERERERERERERERERERERERERERERERERERERER0QAAAAAAHZkZEREREREREREREREREREREREREREREREREVUREQ0AAAAAHZEREREREREREREREREREREREREREREREREREVUREQ0AAAAAHREREREREREREREREREREREREREREREREREREREREQ0AAAAA3REREREREREREREREREREREREREREREREREREREREQ0AAAAA3RERERERERERERERERERERERERERERERERERERER0QAAAAAAHRERERERERERERERERERERERERERERERERERERER3QAAAADQERERERERERERERERERERERERERERERERERERERER3QAAAADQERERERERERERERERERERERERERERERERERERERER0QAAAADQERFVEREREREREREREREREREREREREREREREREREZ0QAAAADQERFVEREREREREREREREREREREREREREREREREZGZ0QAAAAAAHREREREREREREREREREREREREREREREREREREREZ0QAAAAAA0BERERERERERERERERERERERERERERERERERERERDQAAAAAA0B0RERERERERERERERERERERERERERERERERERHRDQAAAAAA0B0RERERERERERERERERERERERERERERERERERHRDQAAAAAA0BERERERERERERERERERERERERERERERERERERERDQAAAAAAHZERERERERERERERERERERERERERERERERERERER0QAAAAAAHZkZEREREREREREREREREREREREREREREREREVUREQ0AAAAAHZEREREREREREREREREREREREREREREREREREVUREQ0AAAAAHREREREREREREREREREREREREREREREREREREREREQ0AAAAA3REREREREREREREREREREREREREREREREREREREREQ0AAAAA3RERERERERERERERERERERERERERERERERERERER0QAAAAAAHRERERERERERERERERERERERERERERERERERERER3QAAAADQERERERERERERERERERERERERERERERERERERERER3QAAAADQERERERERERERERERERERERERERERERERERERERER0QAAAADQERFVEREREREREREREREREREREREREREREREREREZ0QAAAADQERFVEREREREREREREREREREREREREREREREREZGZ0QAAAAAAHREREREREREREREREREREREREREREREREREREREZ0QAAAAAA0BERERERERERERERERERERERERERERERERERERERDQAAAAAA0B0RERERERERERERERERERERERERERERERERERHRDQAAAAAAADMREREREREREREREREREREREREREREREREREREzAAAAAAAAMJMzERkRERERERERERERERERERERERERERERGTGTAwAAAAAAk5k5ExEREREREREREREREREREREREREREREREZOZOQMAAAAAM5mZExERERERERERERERERERERERERERERERETOZmQMAAAAAk5k5ExERERERERERERERERERERERERERERFVEZOZOQAAAAAAM5MzEVEVERERERERERERERERERERERERERFVETOTAwAAAAAAoDoTEVEVERERERERERERERERERERERERGRERETEzAwAAAAAAoKWqqhERkRERERERERERERERERERERERERERqjqjCgAAAAAAoFVTpRERERERERERERERERERERERERERMTMRWjVTCgAAAACgOlVVpTEzExEREREREVURERERERERVRERMzkTWlVVCgAAAACgU1VVMzM5ORERGREREVUREREZERERVRERk5kzOlVVMwAAAACgVVVVMzOZORORmREREREREZGZERERERExmZk5WlVVNQMAAAAAOlVVpZOZmdMRGRERERER3REZERERERE9k5mjVVVVVQMAAAAAoFWjqjOZOdAdEdEdERHR3R0R0R0REdENk5OjqlM1qgAAAAAAoDUDAACTAwDQ3d3dERENANDd3d0REQ0AMDMDADqlAAAAAAAAADMAAAAwAwAAAAAA3d0AAAAAAADd3QAAAAAAAKoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.dungeon":{"kind":5,"retType":""},"sprites.dungeon.buttonOrange":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile electronics","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7u7u7u7u7u8u7u7u7u7u8u05ERN1EvLvrRERERE3Eu0tERERE1MS7S0RERETUxLtLRERERNTEu0tERERE1MS7S0RERETUxLtLRERERNTEu0tERERE1MS7S0RERETUxLvrRERERE3Eu7tORETdRLy7y7u7u7u7u7y7u7u7u7u7uw=="},"pyQName":"sprites.dungeon.button_orange"},"sprites.dungeon.buttonOrangeDepressed":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile electronics","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7u7u7u7u7u8u7u7u7u7u8u+tERNRNvLu7TkRERNTEu7tERERERM27u0REREREzbu7RERERETNu7tERERERM27u0REREREzbu7RERERETNu7tERERERM27u0REREREzbu7TkRERNTEu7vrRETUTby7y7u7u7u7u7y7u7u7u7u7uw=="},"pyQName":"sprites.dungeon.button_orange_depressed"},"sprites.dungeon.buttonTeal":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile electronics","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7u7u7u7u7u8u7u7u7u7u8u2xmZplmvLvLZmZmZmnGu2tmZmZmlsa7a2ZmZmaWxrtrZmZmZpbGu2tmZmZmlsa7a2ZmZmaWxrtrZmZmZpbGu2tmZmZmlsa7a2ZmZmaWxrvLZmZmZmnGu7tsZmaZZry7y7u7u7u7u7y7u7u7u7u7uw=="},"pyQName":"sprites.dungeon.button_teal"},"sprites.dungeon.buttonTealDepressed":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile electronics","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7u7u7u7u7u8u7u7u7u7u8u8tmZpZpvLu7bGZmZpbGu7tmZmZmZsm7u2ZmZmZmybu7ZmZmZmbJu7tmZmZmZsm7u2ZmZmZmybu7ZmZmZmbJu7tmZmZmZsm7u2ZmZmZmybu7bGZmZpbGu7vLZmaWaby7y7u7u7u7u7y7u7u7u7u7uw=="},"pyQName":"sprites.dungeon.button_teal_depressed"},"sprites.dungeon.buttonPink":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile electronics","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7u7u7u7u7u8u7u7u7u7u8uzozMxEzvLurMzMzMzHDuzszMzMzE8O7OzMzMzMTw7s7MzMzMxPDuzszMzMzE8O7OzMzMzMTw7s7MzMzMxPDuzszMzMzE8O7OzMzMzMTw7urMzMzMzHDu7s6MzMRM7y7y7u7u7u7u7y7u7u7u7u7uw=="},"pyQName":"sprites.dungeon.button_pink"},"sprites.dungeon.buttonPinkDepressed":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile electronics","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7u7u7u7u7u8u7u7u7u7u8u6szMxMxvLu7OjMzMxPDu7szMzMzM8G7uzMzMzMzwbu7MzMzMzPBu7szMzMzM8G7uzMzMzMzwbu7MzMzMzPBu7szMzMzM8G7uzMzMzMzwbu7OjMzMxPDu7urMzMTMby7y7u7u7u7u7y7u7u7u7u7uw=="},"pyQName":"sprites.dungeon.button_pink_depressed"},"sprites.dungeon.chestClosed":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAu7u7y7y7C7Du7u677M6760Tk7rvs7rtLRETuu+zuC0tERO677O4LS0RE7rvs7gtLRETuu8vuC0tERO7NvO4LS0RE7s287gtLRETuu8vuC0tERO677O4LS0RE7rvs7gtLRETuu+zuC+tE5O677O67sO7u7rvszrsAu7u7y7y7Cw=="},"pyQName":"sprites.dungeon.chest_closed"},"sprites.dungeon.chestOpen":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAACwuwu7u7u7C+vuu8zM6867S+S7zMzr7rtLRLvMzOvuC0tEu8zM6+4LS0S7zMzr7gtLRLvLzOvuC0tEzbzM6+4LS0TNvMzr7gtLRLvLzOvuC0tEu8zM6+4LS0S7zMzr7gtLRLvMzOvuC0vku8zM6+67S+67zMzrzruwuwu7u7u7Cw=="},"pyQName":"sprites.dungeon.chest_open"},"sprites.dungeon.collectibleInsignia":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABmZmZmZmZmZpaZZpmZZplplmmWyZxplmmWZplpzJlmaWaWmWacmWlmZpmZZpmZmWaWyZmWZmaZaZbMnJaZZsZplmxmmWnJzGmWmWZmaZmcaWaZmZlmmZlmZpaZyWaZaWaWZpnMlplmaZZplsmcaZZplplmmZlmmWlmZmZmZmZmZg=="},"pyQName":"sprites.dungeon.collectible_insignia"},"sprites.dungeon.collectibleRedCrystal":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAEREAAAAAAA0MyREAAAAMDMzMyIEAAA0MzMzI0IAADQzIyIzQgBANDMiIiIiBEBFIiJEJCIEQEUiQkREIgRARCJCREQiBABEEUJEREIAAEQRRUQkQgAAQFRVREIEAAAARERERAAAAAAAREQAAAAAAAAAAAAAAA=="},"pyQName":"sprites.dungeon.collectible_red_crystal"},"sprites.dungeon.collectibleBlueCrystal":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"?tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAGZmAAAAAAB2d4ZmAAAAcHd3d4gGAAB2d3d3h2gAAHZ3h4h3aABgdneIiIiIBmBliIhmhogGYGWIaGZmiAZgZohoZmaIBgBmEWhmZmgAAGYRZWaGaAAAYFZVZmgGAAAAZmZmZgAAAAAAZmYAAAAAAAAAAAAAAA=="},"pyQName":"sprites.dungeon.collectible_blue_crystal"},"sprites.dungeon.darkGroundNorthWest0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzLy7u7u7u7u7vMzMzMzMzMy8zMzMzMy8zLzMzMzMzMzMvMzMzLzMzMy8zLzMzMzMzLzMzMzMzMzLvMzMzMzMzMy8zMzMzMzMzLzMzMzMzMzMvMy8zLzMzMy8zMzMzMzMzLzMzMzMzLzMvMzMzMzMzMy8zMzMzMzMzA=="},"pyQName":"sprites.dungeon.dark_ground_north_west0"},"sprites.dungeon.darkGroundNorth":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8zMzMzMzMzLzMzLzMzMzMvLzMzMzMvMy8zMzMzMzMzLzMzMzMzMzMvMzMzLzMzMy8zLzMzMzMzLzMzMzMzMzLvMzMzMzMzMy8zMzMzMzMzLzMzMzMzMzMvMy8zLzMzMy8zMzMzMzMzLzMzMzMzLzMvMzMzMzMzMy8zMzMzMzMzA=="},"pyQName":"sprites.dungeon.dark_ground_north"},"sprites.dungeon.darkGroundNorthEast0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8zMzMzMzMzLzMzLzMzMzMvLzMzMzMvMy8zMzMzMzMzLzMzMzMzMzMvMzMzLzMzMy8zLzMzMzMzLzMzMzMzMzLvMzMzMzMzMy8zMzMzMzMzLzMzMzMzMzMvMy8zLzMzMy8zMzMzMzMzLzMzMzMzMzMvLu7u7u7u7vMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.dark_ground_north_east0"},"sprites.dungeon.darkGroundNorthWest1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzLzMzMzMzMvMzMzMvMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzMzMvMzMzMzMzLvMzMzMzMzMyw=="},"pyQName":"sprites.dungeon.dark_ground_north_west1"},"sprites.dungeon.darkGroundWest":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzLu7u7u7u7u7zMzMzMzMzMzMvMzMzMy8zMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzLzMvMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.dark_ground_west"},"sprites.dungeon.darkGroundCenter":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzLzMzMzMzMvMzMzMvMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzLzMvMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.dark_ground_center"},"sprites.dungeon.darkGroundEast":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzLzMzMzMzMvMzMzMvMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzMzMu7u7u7u7u7vMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.dark_ground_east"},"sprites.dungeon.darkGroundNorthEast1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMy8zMzLzMzMy7zMvMzMzMy8zMzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzLzMvMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.dark_ground_north_east1"},"sprites.dungeon.darkGroundSouthWest0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzLu7u7u7u7vLzMzMzMzMzMvMy8zMzMzMy8zMzMzMzMzLzMzMzLzMzMvMzLzMzMzMy8zMzMzMzMzLzMzMzMzMy8u8zMzMzMzMy8zMzMzMzMzLzMy8zLzMzMvMzMzMzMzMy8zMzMzMzMzLvMzMzMzMzMvMzMzMzMzMyw=="},"pyQName":"sprites.dungeon.dark_ground_south_west0"},"sprites.dungeon.darkGroundSouth":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMy8zMzLzMzMzLzMvMzMzMzMvMzMzMzMzMy8zMzMzMzMzLzMzMzLzMzMvMzLzMzMzMy8zMzMzMzMzLzMzMzMzMy8u8zMzMzMzMy8zMzMzMzMzLzMy8zLzMzMvMzMzMzMzMy8zMzMzMzMzLvMzMzMzMy8vMzMzMzMzMyw=="},"pyQName":"sprites.dungeon.dark_ground_south"},"sprites.dungeon.darkGroundSouthEast0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMy8zMzLzMzMzLzMvMzMzMzMvMzMzMzMzMy8zMzMzMzMzLzMzMzLzMzMvMzLzMzMzMy8zMzMzMzMzLzMzMzMzMy8u8zMzMzMzMy8zMzMzMzMzLzMy8zLzMzMvMzMzMzMzMy8zMzMzMzMzLu7u7u7u7u8vMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.dark_ground_south_east0"},"sprites.dungeon.darkGroundSouthEast1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8zMzMzMzMzLvMzLzMzMzMzMzMzMzMvMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzLzMvMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.dark_ground_south_east1"},"sprites.dungeon.darkGroundSouthWest1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzLzMzMzMzMvMzMzMvMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzLzMzMzMzMzMzMzMzMzLzMzMzMzMzMy8zMzMzMzMzMzMzMzMzMzMzMy8zLzMzMzMzMzMzMzMzMzMzMzMzLzMu8zMzMzMzMy8zMzMzMzMzA=="},"pyQName":"sprites.dungeon.dark_ground_south_west1"},"sprites.dungeon.doorClosedWest":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8u7u7u7u7y7y7u7u7u7vL3N3d3d3d3c3c3d3d3d3dzczMzMzMzMzMvLvP//z8u8vcvc///Pzbzdy9z//8/NvN3L3P//z8283cvc///PzbzbzLz//8/LzL3L3Pz//8283cvc/P//zbzdy9z8///NvN3L3Pz//8283KrM/P//zKrA=="},"pyQName":"sprites.dungeon.door_closed_west"},"sprites.dungeon.doorClosedSouth":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADKzMzMzMzMzNzdvd3dy9273N293d3L3bu6u8u7u8vdu///////z927zMzMzMzM3bv//////8/du8zM/P//z927///PzMzM3bv//////8/du8zMzMzMzN27///////P3bu6u8u7u8vdu9zdvd3dy9273N293d3L3bvKzMzMzMzMzA=="},"pyQName":"sprites.dungeon.door_closed_south"},"sprites.dungeon.doorClosedNorth":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMrLvdvN3d293Nu9283d3b3c273by7u7y7q7vd/P//////u93MzMzMzMy73fz//////7vdzMzM/P//u938///PzMy73fz//////7vdzMzMzMzMu938//////+73by7u7y7q7vdvN3d293Nu9283d3b3c3MzMzMzMzMrA=="},"pyQName":"sprites.dungeon.door_closed_north"},"sprites.dungeon.doorClosedEast":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADKrM///PzKrNy9z//8/NvN3L3P//z8283cvc///Pzbzdy9z//8/NvNvMvPz//8vMvcvc/P//zbzdy9z8///NvN3L3Pz//8283cvc/P//zbzby7z8///LvLzMzMzMzMzMzc3d3d3d3dzdzd3d3d3d3NvLu7u7u7u8u8u7u7u7u7yw=="},"pyQName":"sprites.dungeon.door_closed_east"},"sprites.dungeon.doorOpenWest":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8u7u7u7u7y7y7u7u7u7vL3N3d3d3d3c3c3d3d3d3dzczMzMzMzMzMvLv/////u8vcvf/////bzdy9/////9vN3L3/////283cvf/////bzbzL/////7zL3L3/////283cvc/8///bzdy9///M/NvN3L3M/M/M283KrMzMzMzKrA=="},"pyQName":"sprites.dungeon.door_open_west"},"sprites.dungeon.doorOpenSouth":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADKzMzMzMzMzNzdvd3dy9273N293d3L3bu6u8u7u8vdu8z/////z927zM/////P3bvMz////8/du/z/////z927/Pz////P3bvM/P///8/du8z8////z927zP/////P3bu6u8u7u8vdu9zdvd3dy9273N293d3L3bvKzMzMzMzMzA=="},"pyQName":"sprites.dungeon.door_open_south"},"sprites.dungeon.doorOpenNorth":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMrLvdvN3d293Nu9283d3b3c273by7u7y7q7vd/P/////Mu938////z8y73fz////PzLvd/P///8/Pu938/////8+73fz////8zLvd/P////zMu938/////8y73by7u7y7q7vdvN3d293Nu9283d3b3c3MzMzMzMzMrA=="},"pyQName":"sprites.dungeon.door_open_north"},"sprites.dungeon.doorOpenEast":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADKrMzMzMzKrNy9zPzPzNvN3L3PzP//283cvf//z/zbzdy9/////9vNvMv/////vMvcvf/////bzdy9/////9vN3L3/////283cvf/////bzby7/////7vLzMzMzMzMzMzc3d3d3d3dzdzd3d3d3d3NvLu7u7u7u8u8u7u7u7u7yw=="},"pyQName":"sprites.dungeon.door_open_east"},"sprites.dungeon.doorLockedWest":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8u7u7u7u7y7y7u7u7u7vL3N3d3d3d3c3c3d3d3d3dzczMzMzMzMzMvMu7u7u7vMvczbu7u7vczdzNtFu1S9zN3M3rtVu+3M3czetURb7czbzLtPVUS7zL3M275ES73M3czbtO5LvczdzNu+u+u9zN3M27u7u73M3KzMzMzMzMrA=="},"pyQName":"sprites.dungeon.door_locked_west"},"sprites.dungeon.doorLockedSouth":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADKzMzMzMzMzNzdvd3dy9273N293d3L3bvMzMzMzMzdu7y7S7u0y927vLu77rvL3bu861RUu8vdu7xO/rW1y927vE5EtbXL3bu861RUu8vdu7y7u+67y927vLtLu7TL3bvMzMzMzMzdu9zdvd3dy9273N293d3L3bvKzMzMzMzMzA=="},"pyQName":"sprites.dungeon.door_locked_south"},"sprites.dungeon.doorLockedNorth":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMrLvdvN3d293Nu9283d3b3c273czMzMzMzLvdvEu7tLvLu928u+67u8u73by7RUW+y7vdvFtbROTLu928W1vv5Mu73by7RUW+y7vdvLvuu7vLu928S7u0u8u73czMzMzMzLvdvN3d293Nu9283d3b3c3MzMzMzMzMrA=="},"pyQName":"sprites.dungeon.door_locked_north"},"sprites.dungeon.doorLockedEast":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADKzMzMzMzMrNzNu7u7u9zN3M2767673M3czbtO5LvczdzNu0ROu9zNvMu0RV9LvMvczetURb7czdzN67VbvtzN3M20W7VL3M3czbu7u7vczbzLu7u7u7zLzMzMzMzMzMzc3d3d3d3dzdzd3d3d3d3NvLu7u7u7u8u8u7u7u7u7yw=="},"pyQName":"sprites.dungeon.door_locked_east"},"sprites.dungeon.floorLight0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAdERGxHRERsdHd3b3R3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d3d0d3d3bu7u+27u7vtHRERsR0REdHR3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d290d3d3dHd3b27u7vtu7u77Q=="},"pyQName":"sprites.dungeon.floor_light0"},"sprites.dungeon.floorLight1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAdERGxHRERsdHd3b3R3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d290d3dvdHdvbvR3d3d0d27u7u7u+27u7vtHRERsR0REbHR3d290d3dvdHdvbvR3d290d27u9Hd3b3RHd290d3dvdEb3b3R3d29sd3d3dHd3b27u7vtu7u77Q=="},"pyQName":"sprites.dungeon.floor_light1"},"sprites.dungeon.floorLight2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAdERERERERsdHd3d3d3d290d3d3d3d3b3R3d3d3d3dvdHd3d3d3d290d3d3d3d3b3R3d3d3d3dvdHd3d3d3d290d3d3d3d3b3R3d3d3d3dvdHd3d3d3d290d3d3d3d3b3R3d3d3d3dvdHd3d3d3d290d3d3d3d3b27u7u7u7u7uw=="},"pyQName":"sprites.dungeon.floor_light2"},"sprites.dungeon.floorLightMoss":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAdERGxHRERsdHd3bbR3d290d3dZtHd3b3R3W290d3dvdHd3b3R3d290d3dvd3d3b3R1t1t293d3btrtr3m7rvtHRERYWa+EdHR3d29Ft3dvdHd3W3R3d290d3dvdHd3bvR3d290d27vdHd3b3R3d290d3d3dG93b27u7vtu7u77Q=="},"pyQName":"sprites.dungeon.floor_light_moss"},"sprites.dungeon.floorLight3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAdERGxzMzMzNHd3b3MzMzM0d3dvcwcEczR3d29EdHdy9Hd3b0c3d3L0d3dvczd3cvR3d3tzMzdvbu7287MzNy9HRGxy8zMzL3R3b0cwczMy9HdvdEdwczM0d3L3N3dvczR3cvM3N29zNHdy8zM3MvM0b3MzMzMzMy7u8zMzMzMzA=="},"pyQName":"sprites.dungeon.floor_light3"},"sprites.dungeon.floorLight4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAdERGxu7u7u9Hd3b0dERGx0d3dvdHd3b3R3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d3d0d3dvbu7u+3R3bvbHRERsbu7Ee3R3d29HdHd3dHd3b3R3d290d3dvdHd3b3R3d290d3dvdHd3b3R3d290d3d3dHd3b27u7vtu7u77Q=="},"pyQName":"sprites.dungeon.floor_light4"},"sprites.dungeon.floorLight5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAdERERERERsdHd3d3d3d290d3d3d3d3b3R3d3d3d3dvdHd3d3d3d29293d3d3d3bux293d3d27u9G9u93dvRux0d3d270b0b3R3d29G9HdvdHd3d293d290d3d3b3d3b3R3d3d3dvdvdHd3d3d29290d3d3d293b27u7u7u7u7uw=="},"pyQName":"sprites.dungeon.floor_light5"},"sprites.dungeon.floorMixed":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADb3d3NHRERwb27u8vR3d3Nvbu7y9Hd3c29u7vL0d3dzb27u8vR3d3Nvbu7y9Hd3c29u7u70d3d3czMzKvMzMytHRERwdvd3b3R3d3Nvbu7y9Hd3c29u7vL0d3dzb27u8vR3d3Nvbu7y9Hd3c29u7vL0d3d3b27u8vMzMytzMzMqw=="},"pyQName":"sprites.dungeon.floor_mixed"},"sprites.dungeon.floorDark0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADb3d3N293dzb27u8u9u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7u7vbu7u8zMzKvMzMyr293dzdvd3b29u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7vLvbu7u727u8vMzMyrzMzMqw=="},"pyQName":"sprites.dungeon.floor_dark0"},"sprites.dungeon.floorDark1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADb3d3N293dzb27u8u9u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7vLvbu7y727y8y9u7u7vbvMzMzMzKvMzMyr293dzdvd3c29u7vLvbu7y727y8y9u7vLvbvMzL27u8u927vLvbu7y73cu8u9u7vLzbu7u727u8vMzMyrzMzMqw=="},"pyQName":"sprites.dungeon.floor_dark1"},"sprites.dungeon.floorDark2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADb3d3d3d3dzb27u7u7u7vLvbu7u7u7u8u9u7u7u7u7y727u7u7u7vLvbu7u7u7u8u9u7u7u7u7y727u7u7u7vLvbu7u7u7u8u9u7u7u7u7y727u7u7u7vLvbu7u7u7u8u9u7u7u7u7y727u7u7u7vLvbu7u7u7u8vMzMzMzMzMrA=="},"pyQName":"sprites.dungeon.floor_dark2"},"sprites.dungeon.floorDarkDiamond":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADb3d3N3N3dzb27u9zNu7vLvbvLvbu8u8u9u9y7u8u7y73Lvbu7u7zLvdy7u7u7y8vNvbu7u7u7vNy7u7u7u7vL3Lu7u7u7u9zNu7u7u7vLzb28u7u7u9zLvcu7u7vLvcu9u7y7u9y7y727y7vLvbvLvbu7vNy7u8vMzMzLzczMrA=="},"pyQName":"sprites.dungeon.floor_dark_diamond"},"sprites.dungeon.floorDark3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADb3d3NzMzMzL27u8vMzMzMvbu7y8zc3cy9u7vL3b27zL27u8vcu7vMvbu7y8y7u8y9u7urzMy7y8zMvMrMzLzL293NzMzMzMu9u8vczczMzL27y73bzczMvbvMvLu7y8y9u8zMvLvLzL27zMzMvMzMvcvMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.floor_dark3"},"sprites.dungeon.floorDark4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADb3d3NzMzMzL27u8vb3d3Nvbu7y727u8u9u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7u7vbu7y8zMzKu9u8y8293dzczM3au9u7vL2727u727u8u9u7vLvbu7y727u8u9u7vLvbu7y727u8u9u7vLvbu7u727u8vMzMyrzMzMqw=="},"pyQName":"sprites.dungeon.floor_dark4"},"sprites.dungeon.floorDark5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADb3d3d3d3dzb27u7u7u7vLvbu7u7u7u8u9u7u7u7u7y727u7u7u7vLvLu7u7u7u8zNvLu7u7vMzL3LzLu7y9zNvbu7vMvcvcu9u7vL3L27y727u7vLu7vLvbu7u8u7u8u9u7u7u7y7y727u7u7vLvLvbu7u7vLu8vMzMzMzMzMrA=="},"pyQName":"sprites.dungeon.floor_dark5"},"sprites.dungeon.greenOuterNorthWest":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADPZmZmxmxmZvx8d3d3fHd3xsx3d3fMd3d2zGxmZsZmZnbHzMzMzMzMdmfMfHd3d8Z2Z8zMZmZmzHZnbMzMzMzMdmd8xsxmZmZ8Z3zGzGxmZnxnfMbGzMzMzGd8xmbMbGbMbHzGZszMzHbMfMZmbMxmdmdsxmZszM92Z8zGZmxs/A=="},"pyQName":"sprites.dungeon.green_outer_north_west"},"sprites.dungeon.greenOuterNorth0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2Z8zMZsxszHZnbMxmbGzMdmd8xmZszMx8ZnzGzGzMzMzMfMbGbGzMdmd8xmZsbMx2Z3zGZmxszHZnbMZmzGzMdmfMzGbMbMx2Z2zMZmxszHZnfMZmbMzMfGd8xmZszMzMzHzGzGxszHbHfMZmbGzMdmd8xmZsbMx2Z2zGZsxszA=="},"pyQName":"sprites.dungeon.green_outer_north0"},"sprites.dungeon.greenOuterNorth1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2Z8zMZsxszHZnbMZmzGzMdmd8xmbMzMx8ZnzGxszMzMzMfMbMzGzMdmZ8xmzMbMx2Z2zGbMZszHZnbMxsxmzMdmfMzGbGbMx2Z2zMZsxszHZnfMZmbMzMfGd8xmZszMzMzHzGzGxszHbHfMZmbGzMdmd8xmZsbMx2Z2zGZsxszA=="},"pyQName":"sprites.dungeon.green_outer_north1"},"sprites.dungeon.greenOuterNorthEast":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2Z8zMZmxs/HZnbMxmbGzPdmd8xmZszGx2Z3zGZszMzHbMfMZmzGxmzGx8xsbMzMx8Z3zGzGxmZnZnfMbMZmZmdmd8zMzMzMx2Z8zMZmZmZnZnzGx3d3fGdsfMzMzMzMx2zGxmZmbGZsbMd3d3d8x3/Hx3d3fHfHfPZmZmxsxsZg=="},"pyQName":"sprites.dungeon.green_outer_north_east"},"sprites.dungeon.greenOuterWest0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABmxmxmZsZsZnfHd3d3x3d3d8d3d3fHdndmzGZmZsZmZszMzMzMzMzMdnd3xnZ3d8ZmZmbMZmZmzMzMzMzMzMzMZsZmZmZmbGZmxmZmZsZsZszMzMzMzMzMbGZmxmxmZsbMzMzMzMzMzGZmzGZmZsxmzMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.green_outer_west0"},"sprites.dungeon.greenInnerNorthWest":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMzMxmZmbMZmbMzMzMzMzMzMzGZmZmZmbGzMbGzMzMzMzMxsZmZmZsZszGzHZmZmxmzMbMZsfMzMzMxsZmzGZmZszGxmZsd3dnzMbGbGx3zMzMzMbMbMfMZszMxmZsx2Z3zMbGZszGdnfMxsxmzMx2Zw=="},"pyQName":"sprites.dungeon.green_inner_north_west"},"sprites.dungeon.greenInnerNorthEast":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMxsxmbMZ2Z8zGxmZsx3Z3zMbGZmzHbHfMxsbMbMdsZszMxmZsd8zMzMzGZmx3d8bMxsZmzGZmzMzGxmbHzMzMzMbGdmZmbGbMxsZmZsZsZszGxszMzMzMzMZmxmxmZsbMzMzMzMzMzMzMZmZmZsxmzMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.green_inner_north_east"},"sprites.dungeon.greenOuterEast0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMZsxmZmbMZmbMzMzMzMzMzGxmZsZsZmbGzMzMzMzMzMxmxmxmZmZsZmbGZmZmZmxmzMzMzMzMzMzMZmZmzGZmZmx3d2dsd3dnzMzMzMzMzMxmZmxmZmbMZndnfHd3d3x3d3d8d3d3fHdmxmxmZsZsZg=="},"pyQName":"sprites.dungeon.green_outer_east0"},"sprites.dungeon.greenOuterWest1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABmxmxmZsZsZnfHd3d3x3d3d8d3d3fGdndmzGZmZsZmZszMzMzMzMzMdnd3xmZ3d8ZmZmbMbGZmxszMzMzMzMzMZsZmZszMZmZmxmZmZsZsZszMzGxmzMzMbGZmzMzMzMzMzMzMzMzMzGZmzGZmZsxmzMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.green_outer_west1"},"sprites.dungeon.greenInnerSouthWest":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMZsxmZmZmzMzMzMzMzMzMzGxmZsZsZmzMzMzMzMxsbMxmxmxmZmxszGbGZmZnbGzMzMzMfGZsbMzMZmbMZmxszGx3d8ZmbMzMzMx3xmZszMxmxnzGzGxszHfGfMZmbGzMd2d8xmZsbMx2Z2zGZsxszA=="},"pyQName":"sprites.dungeon.green_inner_south_west"},"sprites.dungeon.greenInnerSouthEast":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2Z8zMZsxszHdnbMxmbGzMd2Z8xmZszMxmzHzGzGzMzMzMd8bGbGzMdnd3xmZsbMxmZmbMZmxszMzMzHxmzGzMZsZmZmfMbMxmxmZmZmxszMzMzMzMbGzMbGZmZmZmbMzMzMzMzMzMzGZmzGZmZszMzMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.green_inner_south_east"},"sprites.dungeon.greenOuterEast1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMZsxmZmbMZmbMzMzMzMzMzMzMzMzMZmbGzMzMZsbMzMxmxmxmZmZsZmZmzMxmZmxmzMzMzMzMzMxsZmbGzGZmZmx3d2Zsd3dnzMzMzMzMzMxmZmxmZmbMZndnbHd3d3x3d3d8d3d3fHdmxmxmZsZsZg=="},"pyQName":"sprites.dungeon.green_outer_east1"},"sprites.dungeon.greenOuterSouthEast":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABmxsxsZmZm/HfHfHd3d8fPd8x3d3d3zGxmbGZmZsbMZ8zMzMzMzHxnbHd3d8bMdmdmZmZmzMx2Z8zMzMzMx3ZnZmZmzGzHdmdmZsbMbMd2x8zMzGxsx8bMZsbMZmzHzGfMzMxmbMd2Z8bMxmZsx3Zn/MbGZszGdmfPxsZmzMx2Zw=="},"pyQName":"sprites.dungeon.green_outer_south_east"},"sprites.dungeon.greenOuterSouth0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMxsxmbMZ2Z8zGxmZsx3ZnzMbGZmzHfGfMxsbMbMfMzMzMxmZsx3bHzMzGZmzHdmfMxsxmzMZ2Z8zGbGbMzHZnzMZsxszGdmfMxmzGbMZ2Z8zGzMZsx2ZnzMbMzGzHzMzMzMxsbMdmx8zMzGZsx3ZnzMbMZmzGdmfMxsxmzMx2Zw=="},"pyQName":"sprites.dungeon.green_outer_south0"},"sprites.dungeon.greenOuterSouth1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMxsxmbMZ2Z8zGxmZsx3ZnzMbGZmzHfGfMxsbMbMfMzMzMxmZsx3bHzMzGZmzHdmfMxsZmzMZ2Z8zGzGbMzHZnzMbMZmzGdmfMxsZmbMd2Z8zGxmZsx3ZnzMbGbGzHzMzMzMbMbMdmx8zMxmZsx3ZnzMbGZszGdmfMxsxmzMx2Zw=="},"pyQName":"sprites.dungeon.green_outer_south1"},"sprites.dungeon.greenOuterSouthWest":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADPxsZmbMx2Z/zMxmZsxnZnZszGZmzHzGfMzMxmbMfGzGbGzGZsx3bMzMzMbGzHdsdmZsbMbMd2x2ZmZsxsx3ZnzMzMzMzGdmfMZmZmzMx2Z2x3d3fHzHZnzMzMzMzMfGdmZmxmZsbMZ3d3zHd3d8xsd3fHd3d3x89mZsZsZmZm/A=="},"pyQName":"sprites.dungeon.green_outer_south_west"},"sprites.dungeon.greenOuterNorth2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2Z8zMZsxszHZndsxmbGzMdnd2x2dszMx8d3Znd2zMzMxmdnd3Z2zMdnd2Z3dmbMx2d3dEbGZszHZ3RBXkbGzMdndHFeRsbMx2d3dEZGZszHZ3dnd3ZszMfHd2d3dnzMzMZnZnd2ZszHbHdmdnbGzMdmd8Z2ZsbMx2Z2zGZsxszA=="},"pyQName":"sprites.dungeon.green_outer_north2"},"sprites.dungeon.greenOuterEast2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMZsxmZmbMZmbMzMzMzMzMzGxmZmZmZmbGzMxnxmx2xsxmdnfmbndnZmZ3d0xEd3dmzGxnFEF3ZsbMd3dURXd3Z3x3d0d0d3dnbGZmR3dmZsxmd3Z3d3fGZnd3dnd3d3Z3d3d8d3d3fHdmxmxmZsZsZg=="},"pyQName":"sprites.dungeon.green_outer_east2"},"sprites.dungeon.greenOuterSouth2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMxsxmbMZ2Z8zGxmZ2x3ZnzMbGdnZnfGfMxmZ3dmdmzMzMdnd3Z3fHzMxmd3dnd2fMxmZGRHd3Z8zGxk5RdHdnzMbGTlFEd2fMxmbGRHd3Z8zGZnd2Z3dnzMZ2d3dnZszMzMZ3dmd3x8zMxnZ8Z3dnzMbGZsxndmfMxsxmzMx2Zw=="},"pyQName":"sprites.dungeon.green_outer_south2"},"sprites.dungeon.greenOuterWest2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABmxmxmZsZsZnfHd3d3x3d3d2d3d3dnd3dmbHd3d2d3ZsxmZnd0ZmbGdnd3R3R3d8d2d3dURXd3zGxmdxRBdsbMZnd3RMR3d2ZmdnfmbndnZsxsZ8ZsdszMbGZmZmZmZsbMzMzMzMzMzGZmzGZmZsxmzMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.green_outer_west2"},"sprites.dungeon.greenSwitchUp":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2Z8zMZsxszHZnbMxmbGzMdmd8xmZszMx8ZnzGzGzMzMzMzMzMzGzMdmfdvbu7y8x2Z828u7vLzHZnTcTMzMvMdmdN1M3My8x2Z929u7vLzHZn3b27u8vMfGfMzMzMzMzMzHzGzGxszHbHfMZmbGzMdmd8xmZsbMx2Z2zGZsxszA=="},"pyQName":"sprites.dungeon.green_switch_up"},"sprites.dungeon.greenSwitchDown":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2Z8zMZsxszHZnbMxmbGzMdmd8xmZszMx8ZnzGzGzMzMzMzMzMzGzMdmfdvbu7y8x2Z929u7vMzHZn3b3M3UTMdmfdvczMRMx2Z929u7vLzHZn3b27u8vMfGfMzMzMzMzMzHzGzGxszHbHfMZmbGzMdmd8xmZsbMx2Z2zGZsxszA=="},"pyQName":"sprites.dungeon.green_switch_down"},"sprites.dungeon.hazardWater":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAACMaJaWmZmZmYxolpaZmZmZjIhmlpmZmZmMhmaWmZmZmYyGZpmZmZmZjGZmmZmZmZmMaGaZmZmZmYxolpaZmZmZjGiWlpmZmZmMZpaWmZmZmYxmlpmZmZmZjIZmmZmZmZmMhmaZmZmZmYyIZpmZmZmZjIiWmZmZmZmMaJaZmZmZmQ=="},"pyQName":"sprites.dungeon.hazard_water"},"sprites.dungeon.hazardLava0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABVJERCRVREREUiREJVVVVVJCIiVEVFVVUiJERVRCJURCJCVEQiQiJFIkRFJCIkJEUiVEUiJEIiRUJUJCIiIkJFREUkIiIiQkVCRSJEIiRCRUJFIkQiIlJFQlVEIiJCVCRCRVVFRFRVJERVRFVVVUQiVEREVEVVJEJVRCJCRVQkQg=="},"pyQName":"sprites.dungeon.hazard_lava0"},"sprites.dungeon.hazardLava1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABFJEJCRVRFREQiIiJEQlVVREIiIkRCRFVFIiJEJCJCVUVERFQkQkJFVERUVSQiQkVUVVVVRCJURURERFVFQlREJCJCRFVEVCQiIkIkVFVVJCJERCJCVUUiIlREQkJVJCREVUUiQkVCQkRVRSJERSIkRFVEIlRFIkJURSRCVFVERA=="},"pyQName":"sprites.dungeon.hazard_lava1"},"sprites.dungeon.hazardHole":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8z////////7zP////////vPz////////M/Pz//////8z8/P//////zPz8//////+8/////////7zP////////vM////////+8z////////8z/////////zPz////////M/Pz//////8z8/P//////zP/////////cz////////w=="},"pyQName":"sprites.dungeon.hazard_hole"},"sprites.dungeon.hazardSpike":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzM3My7u7u7u7sRzLu7u7u7HRHMvLu7uxsREcy8u7vbERERzMy7uxERERHMzLsdEREREczMGxERERERzMwbERERERHMzLsdEREREczMu7sRERERzLy7u9sRERHMvLu7uxsREcy7u7u7ux0RzLu7u7u7uxG8u7u7u7u72w=="},"pyQName":"sprites.dungeon.hazard_spike"},"sprites.dungeon.purpleOuterNorthWest":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADPqqqqyqyqqvw8MzMzPDMzyswzMzPMMzM6zKyqqsqqqjrDzMzMzMzMOqPMPDMzM8o6o8zMqqqqzDqjrMzMzMzMOqM8ysyqqqo8ozzKzKyqqjyjPMrKzMzMzKM8yqrMrKrMrDzKqszMzDrMPMqqrMyqOqOsyqqszM86o8zKqqys/A=="},"pyQName":"sprites.dungeon.purple_outer_north_west"},"sprites.dungeon.purpleOuterNorth0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAA6o8zMqsyszDqjrMyqrKzMOqM8yqqszMw8qjzKzKzMzMzMPMrKrKzMOqM8yqqsrMw6ozzKqqyszDqjrMqqzKzMOqPMzKrMrMw6o6zMqqyszDqjPMqqrMzMPKM8yqqszMzMzDzKzKyszDrDPMqqrKzMOqM8yqqsrMw6o6zKqsyszA=="},"pyQName":"sprites.dungeon.purple_outer_north0"},"sprites.dungeon.purpleOuterNorth1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAA6o8zMqsyszDqjrMqqzKzMOqM8yqrMzMw8qjzKyszMzMzMPMrMzKzMOqo8yqzMrMw6o6zKrMqszDqjrMysyqzMOqPMzKrKrMw6o6zMqsyszDqjPMqqrMzMPKM8yqqszMzMzDzKzKyszDrDPMqqrKzMOqM8yqqsrMw6o6zKqsyszA=="},"pyQName":"sprites.dungeon.purple_outer_north1"},"sprites.dungeon.purpleOuterNorthEast":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAA6o8zMqqys/DqjrMyqrKzPOqM8yqqszKw6ozzKqszMzDrMPMqqzKyqzKw8ysrMzMw8ozzKzKyqqjqjPMrMqqqqOqM8zMzMzMw6o8zMqqqqqjqjzKwzMzPKOsPMzMzMzMw6zKyqqqrKqsrMMzMzM8wz/DwzMzPDPDPPqqqqysysqg=="},"pyQName":"sprites.dungeon.purple_outer_north_east"},"sprites.dungeon.purpleOuterWest0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAACqyqyqqsqsqjPDMzMzwzMzM8MzMzPDOjOqzKqqqsqqqszMzMzMzMzMOjMzyjozM8qqqqrMqqqqzMzMzMzMzMzMqsqqqqqqrKqqyqqqqsqsqszMzMzMzMzMrKqqyqyqqsrMzMzMzMzMzKqqzKqqqsyqzMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.purple_outer_west0"},"sprites.dungeon.purpleInnerNorthWest":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMzMyqqqrMqqrMzMzMzMzMzMzKqqqqqqrKzMrKzMzMzMzMysqqqqqsqszKzDqqqqyqzMrMqsPMzMzMysqqzKqqqszKyqqsMzOjzMrKrKwzzMzMzMrMrMPMqszMyqqsw6ozzMrKqszKOjPMysyqzMw6ow=="},"pyQName":"sprites.dungeon.purple_inner_north_west"},"sprites.dungeon.purpleInnerNorthEast":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMysyqrMo6o8zKyqqswzozzMrKqqzDrDPMysrMrMOsqszMyqqsM8zMzMzKqqwzM8rMysqqzKqqzMzKyqrDzMzMzMrKOqqqrKrMysqqqsqsqszKyszMzMzMzMqqyqyqqsrMzMzMzMzMzMzMqqqqqsyqzMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.purple_inner_north_east"},"sprites.dungeon.purpleOuterEast0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMqsyqqqrMqqrMzMzMzMzMzMzMzMzMqqrKzMzMqsrMzMyqyqyqqqqsqqqqzMyqqqyqzMzMzMzMzMysqqrKzKqqqqwzM6qsMzOjzMzMzMzMzMyqqqyqqqrMqjOjrDMzMzwzMzM8MzMzPDOqyqyqqsqsqg=="},"pyQName":"sprites.dungeon.purple_outer_east0"},"sprites.dungeon.purpleOuterWest1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAACqyqyqqsqsqjPDMzMzwzMzM8MzMzPKOjOqzKqqqsqqqszMzMzMzMzMOjMzyqozM8qqqqrMrKqqyszMzMzMzMzMqsqqqszMqqqqyqqqqsqsqszMzKyqzMzMrKqqzMzMzMzMzMzMzMzMzKqqzKqqqsyqzMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.purple_outer_west1"},"sprites.dungeon.purpleInnerSouthWest":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMqsyqqqqqzMzMzMzMzMzMzKyqqsqsqqzMzMzMzMysrMyqyqyqqqyszKrKqqqjrKzMzMzMPKqsrMzMqqrMqqyszKwzM8qqrMzMzMwzyqqszMyqyjzKzKyszDPKPMqqrKzMM6M8yqqsrMw6o6zKqsyszA=="},"pyQName":"sprites.dungeon.purple_inner_south_west"},"sprites.dungeon.purpleInnerSouthEast":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAA6o8zMqsyszDOjrMyqrKzMM6o8yqqszMyqzDzKzKzMzMzMM8rKrKzMOjMzyqqsrMyqqqrMqqyszMzMzDyqzKzMqsqqqqPMrMyqyqqqqqyszMzMzMzMrKzMrKqqqqqqrMzMzMzMzMzMzKqqzKqqqszMzMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.purple_inner_south_east"},"sprites.dungeon.purpleOuterEast1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMqsyqqqrMqqrMzMzMzMzMzKyqqsqsqqrKzMzMzMzMzMyqyqyqqqqsqqrKqqqqqqyqzMzMzMzMzMzMqqqqzKqqqqwzM6OsMzOjzMzMzMzMzMyqqqyqqqrMqjOjPDMzMzwzMzM8MzMzPDOqyqyqqsqsqg=="},"pyQName":"sprites.dungeon.purple_outer_east1"},"sprites.dungeon.purpleOuterSouthEast":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAACqysysqqqq/DPDPDMzM8PPM8wzMzMzzKyqrKqqqsrMo8zMzMzMzDyjrDMzM8rMOqOqqqqqzMw6o8zMzMzMwzqjqqqqzKzDOqOqqsrMrMM6w8zMzKysw8rMqsrMqqzDzKPMzMyqrMM6o8rMyqqswzqj/MrKqszKOqPPysqqzMw6ow=="},"pyQName":"sprites.dungeon.purple_outer_south_east"},"sprites.dungeon.purpleOuterSouth0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMysyqrMo6o8zKyqqswzqjzMrKqqzDPKPMysrMrMPMzMzMyqqswzrDzMzKqqzDOqPMysyqzMo6o8zKrKrMzDqjzMqsyszKOqPMyqzKrMo6o8zKzMqsw6qjzMrMzKzDzMzMzMysrMOqw8zMzKqswzqjzMrMqqzKOqPMysyqzMw6ow=="},"pyQName":"sprites.dungeon.purple_outer_south0"},"sprites.dungeon.purpleOuterSouth1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMysyqrMo6o8zKyqqswzqjzMrKqqzDPKPMysrMrMPMzMzMyqqswzrDzMzKqqzDOqPMysqqzMo6o8zKzKrMzDqjzMrMqqzKOqPMysqqrMM6o8zKyqqswzqjzMrKrKzDzMzMzMrMrMOqw8zMyqqswzqjzMrKqszKOqPMysyqzMw6ow=="},"pyQName":"sprites.dungeon.purple_outer_south1"},"sprites.dungeon.purpleOuterSouthWest":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADPysqqrMw6o/zMyqqsyjqjqszKqqzDzKPMzMyqrMPKzKrKzKqswzrMzMzMrKzDOsOqqsrMrMM6w6qqqsyswzqjzMzMzMzKOqPMqqqqzMw6o6wzMzPDzDqjzMzMzMzMPKOqqqyqqsrMozMzzDMzM8ysMzPDMzMzw8+qqsqsqqqq/A=="},"pyQName":"sprites.dungeon.purple_outer_south_west"},"sprites.dungeon.purpleOuterNorth2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAA6o8zMqsyszDqjOsyqrKzMOjM6w6OszMw8MzqjM6zMzMyqOjMzo6zMOjM6ozOqrMw6MzNErKqszDozRBXkrKzMOjNDFeSsrMw6MzNEpKqszDozOjMzqszMPDM6MzOjzMzMqjqjM6qszDrDOqOjrKzMOqM8o6qsrMw6o6zKqsyszA=="},"pyQName":"sprites.dungeon.purple_outer_north2"},"sprites.dungeon.purpleOuterEast2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzMzMzMzMqsyqqqrMqqrMzMzMzMzMzKyqqqqqqqrKzMyjyqw6ysyqOjPqrjOjqqozM0xEMzOqzKyjFEEzqsrMMzNURTMzozwzM0M0MzOjrKqqQzOqqsyqMzozMzPKqjMzOjMzMzozMzM8MzMzPDOqyqyqqsqsqg=="},"pyQName":"sprites.dungeon.purple_outer_east2"},"sprites.dungeon.purpleOuterSouth2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMysyqrMo6o8zKyqo6wzqjzMrKOjqjPKPMyqozOqOqzMzMOjMzozPDzMyqMzOjM6PMyqpKRDMzo8zKyk5RNDOjzMrKTlFEM6PMyqrKRDMzo8zKqjM6ozOjzMo6MzOjqszMzMozOqMzw8zMyjo8ozOjzMrKqsyjOqPMysyqzMw6ow=="},"pyQName":"sprites.dungeon.purple_outer_south2"},"sprites.dungeon.purpleOuterWest2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAACqyqyqqsqsqjPDMzMzwzMzM6MzMzOjMzOqrDMzM6MzqsyqqjM0qqrKOjMzQzQzM8M6MzNURTMzzKyqMxRBOsrMqjMzRMQzM6qqOjPqrjOjqsyso8qsOszMrKqqqqqqqsrMzMzMzMzMzKqqzKqqqsyqzMzMzMzMzMzMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.purple_outer_west2"},"sprites.dungeon.purpleSwitchUp":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAA6o8zMqsyszDqjrMyqrKzMOqM8yqqszMw8qjzKzKzMzMzMzMzMzKzMOqPdvbu7y8w6o828u7vLzDqjTcTMzMvMOqNN1M3My8w6o929u7vLzDqj3b27u8vMPKPMzMzMzMzMzDzKzKyszDrDPMqqrKzMOqM8yqqsrMw6o6zKqsyszA=="},"pyQName":"sprites.dungeon.purple_switch_up"},"sprites.dungeon.purpleSwitchDown":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAA6o8zMqsyszDqjrMyqrKzMOqM8yqqszMw8qjzKzKzMzMzMzMzMzKzMOqPdvbu7y8w6o929u7vMzDqj3b3M3UTMOqPdvczMRMw6o929u7vLzDqj3b27u8vMPKPMzMzMzMzMzDzKzKyszDrDPMqqrKzMOqM8yqqsrMw6o6zKqsyszA=="},"pyQName":"sprites.dungeon.purple_switch_down"},"sprites.dungeon.stairWest":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADdzMzMzMzM3d28u7u7u8vd3dvd3d3dvd3dzMzMzMzM3d28u7u7u8vd3dvd3d3dvd3dzMzMzMzM3d28u7u7u8vd3dvd3d3dvd3dzMzMzMzM3d28u7u7u8vd3dvd3d3dvd3dzMzMzMzM3d28u7u7u8vdu9vd3d3dvbvMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.stair_west"},"sprites.dungeon.stairSouth":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC83d3d3d3d3bzd3d3d3d3dvMzLvMzLvMzcy73cy73cy9zLvdzLvdzL3Mu93Mu93Mvcy73cy73cy9zLvdzLvdzL3Mu93Mu93Mvcy73cy73cy9zLvdzLvdzL3Mu93Mu93Mvcy73cy73cy7zMy7zMy7zMvN3d3d3d3d283d3d3d3d3Q=="},"pyQName":"sprites.dungeon.stair_south"},"sprites.dungeon.stairNorth":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADd3d3d3d3dy93d3d3d3d3LzMu8zMu8zMu8zdu8zdu8zbzN27zN27zNvM3bvM3bvM28zdu8zdu8zbzN27zN27zNvM3bvM3bvM28zdu8zdu8zbzN27zN27zNvM3bvM3bvM28zdu8zdu8zczLvMzLvMzL3d3d3d3d3cvd3d3d3d3dyw=="},"pyQName":"sprites.dungeon.stair_north"},"sprites.dungeon.stairEast":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzLvb3d3d3b273by7u7u7y93dzMzMzMzM3d3b3d3d3b3d3by7u7u7y93dzMzMzMzM3d3b3d3d3b3d3by7u7u7y93dzMzMzMzM3d3b3d3d3b3d3by7u7u7y93dzMzMzMzM3d3b3d3d3b3d3by7u7u7y93dzMzMzMzM3Q=="},"pyQName":"sprites.dungeon.stair_east"},"sprites.dungeon.stairLarge":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzMzMzMy7u7u9zMzMzLu7u73MzMzMu7u7vczMzMy7u7u9zMzMzMzMvLvMzLu7u9u7u8zMu7u727u7zMy7u7vbu7vMzLu7u9u7u8zMzMzMu7u7vLu7u9u7u7u8u7u727u7u7y7u7vbu7u7vLu7u9u7u7vMzMzMzMzMzA=="},"pyQName":"sprites.dungeon.stair_large"},"sprites.dungeon.stairLadder":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADu7u7u7u7u7kNOREREQ+7uQ+7u7u5DzuxDTj7kQ0PO7ENOPuRDQ87sQ04+5ENDzuxDTj7kQ0PO7ENOPuRDQ87sQ04+5ENDzuxDTj7kQ0PO7ENOPuRDQ87sQ04+5ENDzuxDTj7kQ0PO7EPu7u7uQ87sQ05ERERD7u7u7u7u7u7u7g=="},"pyQName":"sprites.dungeon.stair_ladder"},"sprites.dungeon.statueLight":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQACAAAAAAAAAAAAAAAAAAOzMzOxHLAAAAAAAAAAAAsBEREbEzswAAAAAAAAAAALARERGxM7MAAAAAAAAAEwCwMRMRETOzAAAAAAAwM7MAsBMxEREzswAAAAC7u8s8MzMzERMRs7MAETM7M8w8EREREREzEbOzEDOxEzEzERERETMzMxGzsxATETszERERMTMzMzMRs7MQEzETERMREREREREzEbOzAAAQMRsxERERERERMxGzswAAABExEQATERExMxMRM7MAAAAAAAAAAAATETMTETOzAAAAAAAAAAAAsDMTEbEzswAAAAAAAAAAALARERGxM7MAAAAAAAAAAAAAOzMzOxHL"},"pyQName":"sprites.dungeon.statue_light"},"sprites.dungeon.statueDark":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"dungeon","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQACAAAAAAAAAAAAAAAAAAvLu7vN38AAAAAAAAAAAAwN3d3c27ywAAAAAAAAAAAMDd3d3Nu8sAAAAAAAAA2wDAvdvd3bvLAAAAAACwu8sAwNu93d27ywAAAADMzPy/u7u73dvdy8sA3bu8u/+/3d3d3d273cvL0LvN27273d3d3bu7u93Ly9Db3by73d3dvbu7u7vdy8vQ273b3dvd3d3d3d273cvLAADQvdy93d3d3d3du93LywAAAN293QDb3d29u9vdu8sAAAAAAAAAAADb3bvb3bvLAAAAAAAAAAAAwLvb3c27ywAAAAAAAAAAAMDd3d3Nu8sAAAAAAAAAAAAAvLu7vN38"},"pyQName":"sprites.dungeon.statue_dark"},"sprites.space":{"kind":5,"retType":""},"sprites.space.spaceSmallAsteroid0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8DAAAAAAAwLvLAAAAAAC6+68MAAAAwKurr8wAAADA+r/LDAAAAMDKv7oMAAAAAKCqvwAAAAAAwKysAAAAAAAAzAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.space.space_small_asteroid0"},"sprites.space.spaceSmallAsteroid1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAzAAAAAAAwKq7CwAAAACguqurAAAAAKD/y68AAAAArP+qvwAAAACsy7+6AAAAAAC6vMoAAAAAAAC7DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.space.space_small_asteroid1"},"sprites.space.spaceSmallAsteroid2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMwAAAAAAMCquwsAAAAAoLqrqwAAAACg/8uvAAAAAKz/qr8AAAAArMu/ugAAAAAAurzKAAAAAAAAuwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.space.space_small_asteroid2"},"sprites.space.spaceSmallAsteroid3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvMsAAAAAAMD8uwsAAAAAoP/6ugAAAACguru/AAAAAKz7v8wAAAAAwKuvDAAAAAAArMoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.space.space_small_asteroid3"},"sprites.space.spaceAsteroid0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMisygAAAAAAzPqoCgAAAMDMyo/MAAAAzLyrrMrMAADM/6uqussMAPj/uMqsu8yA+P+6zP+6ysD/j6vM/7/LwMyszMr6b8vMqszMrKpmzPyvysyqu6bMiP+qzPy4ygzA/6zM/8/LAMDMqPz/z8YAAMzM/I9szAAAwMzMrMoAAA=="},"pyQName":"sprites.space.space_asteroid0"},"sprites.space.spaceAsteroid1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAwMzMAAAAAADMqrsMAAAAAKyPvAsAAAAAzPqvCwAAAADMqqqqvMsAAMysyqu7uwwAwMz6vMy6CgDMqoq/yrvGAIzPqrqqasYA/M/Mqrxmy8D8zMyqvMoMwMyqzIirAADA/6qMqAAAAMD8r8zMAAAAAMyvzAwAAAAAwMzMAAAAAA=="},"pyQName":"sprites.space.space_asteroid1"},"sprites.space.spaceSmallAsteroid4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwKoMAAAAAADA/7sAAAAAALz7uwwAAAAAy7uqCwAAAAD6q/8LAAAAAKz6rwAAAAAAwMwMAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.space.space_small_asteroid4"},"sprites.space.spaceSmallAsteroid5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADKAAAAAAAAvKqrAAAAAAD6z/8KAAAAwP+7/wsAAADAu7q7CwAAAADM+78MAAAAAMD6ugwAAAAAALyrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.space.space_small_asteroid5"},"sprites.space.spaceRedShip":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAzAAAAAAAAMDMAAAAAAAAzMwAAAAAAADPzAAAAAAA4M/MAAAAAADs78wAAAAA7izs7szMz+8uLCzu3b0vL0QuLiIAAAAA7k4uIgAAAAAA7i8iAAAAAADgTyQAAAAAAAAuQgAAAAAAAO4iAAAAAAAA4O4AAAAAAAAA7g=="},"pyQName":"sprites.space.space_red_ship"},"sprites.space.spaceAsteroid2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADAzAwAAAAAAKyqzAAAAMDM/K/LDAAAzMz8z7oMAMD/qsz/uswMwPyvyv+6uwvA/K/MzLqsu8D6rKysu8xqzKq6u2y2zGrMqsq6Zru7xsyq/2+7q7rLzMz/vLvKugzAqv+6u8vLAACsqrqquwwAAMCqzKqqAAAAAMzMzAAAAA=="},"pyQName":"sprites.space.space_asteroid2"},"sprites.space.spaceAsteroid3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADMzMwAAADMzMysqgwAwKyqrLqMqwDAuoyqy/+8DLDL/6yGz7wMsPr/zGrKvAyw/I/MzLy8DKz7yMzMrLsLzLqqqqr6v8usqrvLr/+8u6q6u/yvyrq7rLu7/7y8u8vAvLvKvMy7DACsu7vLzLoMAACqvLvLzAAAAACsygAAAA=="},"pyQName":"sprites.space.space_asteroid3"},"sprites.space.spaceAsteroid4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAzLq7CgAArArArLqrAMC8q6rKrKYArKq7qrvMuwDKrLuqu6rLoPzMpsy6uwqs/2/6zGqrDKz6qvuvtqoAzKqqu6zKDADA+sy6qwsAAMD6z6q6ywAAAKz/rLrGAAAAwKrKrKsAAAAAzP/PywAAAADA/6oMAAAAAMDMzAAAAA=="},"pyQName":"sprites.space.space_asteroid4"},"sprites.space.spaceOrangeShip":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAA7gAAAAAAAODuAAAAAAAA7u4AAAAAAADv7gAAAAAA4O/uAAAAAADsL+4AAAAA7kwsIszMz+9OTEwi3b1PT1VCQkQAAAAAIlJCRAAAAAAAIk9EAAAAAAAgX0UAAAAAAABCVAAAAAAAACJEAAAAAAAAICIAAAAAAAAAIg=="},"pyQName":"sprites.space.space_orange_ship"},"sprites.space.spacePinkShip":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAiAAAAAAAAICIAAAAAAAAiIgAAAAAAACPiAAAAAAAgI+IAAAAAACMr4gAAAAAiDysqszMz484PDyq3b0/PxE6OjMAAAAAqho6MwAAAAAAqj8zAAAAAACgHzEAAAAAAAA6EwAAAAAAAKozAAAAAAAAoKoAAAAAAAAAqg=="},"pyQName":"sprites.space.space_pink_ship"},"sprites.space.spaceBlueShip":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAiAAAAAAAAICIAAAAAAAAiIgAAAAAAACPiAAAAAAAgI+IAAAAAACMj4gAAAAAiGyMiMzMz49obGyI3b1vb5lobmYAAAAAiJhuZgAAAAAAiG9mAAAAAACAn2kAAAAAAABolgAAAAAAAIhmAAAAAAAAgIgAAAAAAAAAiA=="},"pyQName":"sprites.space.space_blue_ship"},"sprites.space.spaceGreenShip":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"space","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAiAAAAAAAAICIAAAAAAAAiIgAAAAAAACPiAAAAAAAgI+IAAAAAACMb4gAAAAAiHxsZszMz494fHxm3b1/f1V2dncAAAAAZlZ2dwAAAAAAZn93AAAAAABgX3UAAAAAAAB2VwAAAAAAAGZ3AAAAAAAAYGYAAAAAAAAAZg=="},"pyQName":"sprites.space.space_green_ship"},"sprites.vehicle":{"kind":5,"retType":""},"sprites.vehicle.carRedLeft":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAA0CIi7Q4AAAAtItLtDgAAACIi0uLuAAAgRCQi7v4PAMLMK+7u/w8gzLzu8u7/DyAi4r7i7/8PICLku+L+/gAgIuS74v7uACAi5Lvy/+4AICLk7u7u/gAgIuS74u7/DyBE5Lvi7v8PAMIsvuLu/w8AIMzi7u7/AA=="},"pyQName":"sprites.vehicle.car_red_left"},"sprites.vehicle.carRedRight":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAIiLu7g4AACDM4u7u/wAAwiy+4u7/DyBE5Lvi7v8PICLku+Lu/w8gIuTu7u7+ACAi5Lvy/+4AICLku+L+7gAgIuS74v7+ACAi4r7i7/8PIMy87vLu/w8Awswr7u7/DwAgRCQi7v4PAAAiItLi7gAAAC0i0u0OAA=="},"pyQName":"sprites.vehicle.car_red_right"},"sprites.vehicle.carRedBack":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4P//7u7/DwAiIiIi4u7/4MwiwuzuLf4uQkQkzuveDi4iIkK86+4OLCIiQrzr7g4sIiIivOvuDi4iIiK86+4OLiIiIs7r3g7gzCzC7O4t/gAiIiIi4u7/AOD//+7u/w8AAAAAAAAAAA=="},"pyQName":"sprites.vehicle.car_red_back"},"sprites.vehicle.carRedFront":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOD/7/4PAAAAIuIi7i4PAMLMzCxL3eIgQkQkskzSLSAkIiLLTCIiICQiIstMIiIgIiIiy0wiIiAiIiLLTCIiICIiIrJM0i0AwszMLEvd4gAAIuIi7i4PAADg/+/+/wAAAAAAAAAAAA=="},"pyQName":"sprites.vehicle.car_red_front"},"sprites.vehicle.carBlueLeft":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAA0GZmjQgAAABtZtaNCAAAAGZm1oaIAABgmWlmiPgPAMbMa4iI/w9gzLyI9oj/D2BmhriGj/8PYGaJu4b4+ABgZom7hviIAGBmibv2/4gAYGaJiIiI+ABgZom7hoj/D2CZibuGiP8PAMZsuIaI/w8AYMyGiIj/AA=="},"pyQName":"sprites.vehicle.car_blue_left"},"sprites.vehicle.carBlueRight":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAZmaIiAgAAGDMhoiI/wAAxmy4hoj/D2CZibuGiP8PYGaJu4aI/w9gZomIiIj4AGBmibv2/4gAYGaJu4b4iABgZom7hvj4AGBmhriGj/8PYMy8iPaI/w8AxsxriIj/DwBgmWlmiPgPAABmZtaGiAAAAG1m1o0IAA=="},"pyQName":"sprites.vehicle.car_blue_right"},"sprites.vehicle.carBlueBack":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP//iIj/DwBmZmZmhoj/gMxmxoyIbfholplpyIvYCGhmZpa8i4gIbGZmlryLiAhsZmZmvIuICGhmZma8i4gIaGZmZsiL2AiAzGzGjIht+ABmZmZmhoj/AID//4iI/w8AAAAAAAAAAA=="},"pyQName":"sprites.vehicle.car_blue_back"},"sprites.vehicle.carBlueFront":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAID/j/gPAAAAZoZmiGgPAMbMzGyb3YZglplptpzWbWBpZmbLnGZmYGlmZsucZmZgZmZmy5xmZmBmZmbLnGZmYGZmZrac1m0AxszMbJvdhgAAZoZmiGgPAACA/4/4/wAAAAAAAAAAAA=="},"pyQName":"sprites.vehicle.car_blue_front"},"sprites.vehicle.carPinkLeft":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAA0DMzrQoAAAA9M9OtCgAAADMz06OqAAAw3T0zqvoPAMPMO6qq/w8wzLyq86r/DzAzo7qjr/8PMDOtu6P6+gAwM627o/qqADAzrbvz/6oAMDOtqqqq+gAwM627o6r/DzDdrbujqv8PAMM8uqOq/w8AMMyjqqr/AA=="},"pyQName":"sprites.vehicle.car_pink_left"},"sprites.vehicle.carPinkRight":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAMzOqqgoAADDMo6qq/wAAwzy6o6r/DzDdrbujqv8PMDOtu6Oq/w8wM62qqqr6ADAzrbvz/6oAMDOtu6P6qgAwM627o/r6ADAzo7qjr/8PMMy8qvOq/w8Aw8w7qqr/DwAw3T0zqvoPAAAzM9OjqgAAAD0z060KAA=="},"pyQName":"sprites.vehicle.car_pink_right"},"sprites.vehicle.carPinkBack":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoP//qqr/DwAzMzMzo6r/oMwzw6yqPfo60909yqvaCjozM9O8q6oKPDMz07yrqgo8MzMzvKuqCjozMzO8q6oKOjMzM8qr2gqgzDzDrKo9+gAzMzMzo6r/AKD//6qq/w8AAAAAAAAAAA=="},"pyQName":"sprites.vehicle.car_pink_back"},"sprites.vehicle.carPinkFront":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKD/r/oPAAAAM6MzqjoPAMPMzDzb3aMw0909s9zTPTA9MzPL3DMzMD0zM8vcMzMwMzMzy9wzMzAzMzPL3DMzMDMzM7Pc0z0Aw8zMPNvdowAAM6MzqjoPAACg/6/6/wAAAAAAAAAAAA=="},"pyQName":"sprites.vehicle.car_pink_front"},"sprites.vehicle.car20":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAACIiIiIAAAAgGZmOIgIAABoZoYziAgAAGhmhoOIDwCImZmJiPi7gJiZmYuI+LyAdneGuIb4/Ghmd4e7hogPaGZ2h7uGiAhoZmaHu4aICGhmZoeIiIgPaGZmh7uG+LuAdneGuIb4vAC4mZmLiPj8AICbmbmIiA8AAIiIiIiIAA=="}},"sprites.vehicle.car21":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAACIiIiIAAAAgGZmOIgIAABoZoYziAgAAGhmhoOIDwCImZmJiPjPgJiZmYuI+L+AdneGuIb4u2h2d4e7hogPaHZ3h7uGiAhoZneHu4aICGhmdoeIiIgPaGZmh7uG+M+AdneGuIb4vwC4mZmLiPi7AICbmbmIiA8AAIiIiIiIAA=="}},"sprites.vehicle.car22":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAACIiIiIAAAAgGZmOIgIAABoZoYziAgAAGhmhoOIDwCImZmJiPj8gJiZmYuI+PuAdneGuIb4+2hmdoe7hogPaGZmh7uGiAhoZmaHu4aICGh2Z4eIiIgPaHZ3h7uG+PyAdneGuIb4+wC4mZmLiPj7AICbmbmIiA8AAIiIiIiIAA=="}},"sprites.vehicle.car23":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAACIiIiIAAAAgGZmOIgIAABoZoYziAgAAGhmhoOIDwCImZmJiPjLgJiZmYuI+PuAdneGuIb4/Ghmdoe7hogPaGZmh7uGiAhoZmaHu4aICGhmZoeIiIgPaGZmh7uG+MuAdneGuIb4+wC4mZmLiPj8AICbmbmIiA8AAIiIiIiIAA=="}},"sprites.vehicle.car30":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADu7u7uAAAA4CIiPu4OAAAuIuIz7g4AAC4i4uPuDwDumZnp7v674J6Zmevu/rzgQkTivuL+/C4iROS74u4PLiJC5Lvi7g4uIiLku+LuDi4iIuTu7u4PLiIi5Lvi/rvgQkTivuL+vAC+mZnr7v78AOCbmbnu7g8AAO7u7u7uAA=="}},"sprites.vehicle.car31":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADu7u7uAAAA4CIiPu4OAAAuIuIz7g4AAC4i4uPuDwDumZnp7v7P4J6Zmevu/r/gQkTivuL+uy5CROS74u4PLkJE5Lvi7g4uIkTku+LuDi4iQuTu7u4PLiIi5Lvi/s/gQkTivuL+vwC+mZnr7v67AOCbmbnu7g8AAO7u7u7uAA=="}},"sprites.vehicle.car32":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADu7u7uAAAA4CIiPu4OAAAuIuIz7g4AAC4i4uPuDwDumZnp7v784J6Zmevu/vvgQkTivuL++y4iQuS74u4PLiIi5Lvi7g4uIiLku+LuDi5CJOTu7u4PLkJE5Lvi/vzgQkTivuL++wC+mZnr7v77AOCbmbnu7g8AAO7u7u7uAA=="}},"sprites.vehicle.car33":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADu7u7uAAAA4CIiPu4OAAAuIuIz7g4AAC4i4uPuDwDumZnp7v7L4J6Zmevu/vvgQkTivuL+/C4iQuS74u4PLiIi5Lvi7g4uIiLku+LuDi4iIuTu7u4PLiIi5Lvi/svgQkTivuL++wC+mZnr7v78AOCbmbnu7g8AAO7u7u7uAA=="}},"sprites.vehicle.plane0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAADADwAAAAAAACzyAAAAAADAIiIPAAAAAJwrIg8AAP/Ambki8gAA/8+bGSLyAAAvL7QRIvIAAC9MJBEi8gAAz0wikSLyAADPTCKbIvL/APAsIiIi8sIPAC8iIiL8zPwALyIiQv8v8gAvIiJM9P//AMAiwiJE//8AwCLCIkL8/wDALMIiIvIPAMwswiwi8gDATCTC/CLyAMxEIswPL/IATCTywg/A/AD8/88iDwAAAAAAACwPAAAAAAAA8A8AAAA="}},"sprites.vehicle.plane1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAADADwAAAAAAACzyAAAAAADAIiIPAAAAAJwrIg8AAP/AmSki8gAA/8+buSLyAAAvL5QRIvIAAC9MtBEi8gAAz0wikSLyAADPTCKZIvL/APAsIiIi8sIPAC8iIiL8zPwALyIiQv8v8gAvIiJM9P//AMAiwkJE//8AwCLCIkT8/wDALMIiQvIPAMwswiwi8gDATCTC/CLyAMxEIswPL/IATCTywg/A/AD8/88iDwAAAAAAACwPAAAAAAAA8A8AAAA="}},"sprites.vehicle.plane2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAADADwAAAAAAACzyAAAAAADAIiIPAAD/AJwrIg8AAP/PmSsi8gAAL8+ZISLyAAAvLxshIvIAAM9MEiEi8gAAz0wSKSLyAADwTLIpIvL/APAsIiIi8sIPAC8iIiLMzA8ALyLCJP8iDwAvIixE//8PAMAiLEL8/w8AwCIsQvT/DwDALMwixP8AAEwszCLCAADARCLMLMIAAEwkIvwswgAATCIv8swMAAD8/yzyAAAAAAAAwPIAAAAAAAAA/wAAAAA="}},"sprites.vehicle.plane3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAADADwAAAAAAACzyAAAAAADAIiIPAAD/AJwrIg8AAP/Pmbki8gAAL8+bGSLyAAAvL7QRIvIAAM9MJBEi8gAAz0wikSLyAAD/TCKbIvL/APAsIiIi8sIPAC8iIiL8zPwALyIiQv8v8gAvIiJM9P//AMAiwiJE//8AwCLCIkL8/wDALMIiIvIPAMwswiwi8gDATCTC/CLyAMxEIswPL/IATCTywg/A/AD8/88iDwAAAAAAACwPAAAAAAAA8A8AAAA="}},"sprites.vehicle.plane4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAADADwAAAAAAACzyAAAAAADAIiIPAAAAAJwrIg8AAP/Ambki8gAA/8+bGSLyAAAvL0IZIfIAAC8sRBIh8gAAzywkEinyAADPLCSyKfL/APAsIiIi8sIPAC8iIiL8zMwALyIiIvT/IgAvIiLCRP//AMAiIixC9P8AwCwiLCLE/wDALCIsIiIPAMAsIswiIg8AwETC/C8iDwBMJML8/yIPwETyL/zAzA/w/88s8gAAAAAAAMzyAAAAAAAA8P8AAAA="}},"sprites.vehicle.plane5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"transportation","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAADADwAAAAAAACzyAAAAAADAIiIPAAAAAJwrIg8AAP/Ambki8gAA/8+bGSLyAAAvL0IRIvIAAM8iRBIh8gAAzywkEinyAADPLCSyKfL/APAsIiIi8sIPAC8iIiL8zMwALyIiIvT/IgAvIiLCRP//AMAiIixC9P8AwCwiLCLE/wDALCIsIiIPAMAsIswiIg8AwETC/C8iDwBMJML8/yIPwETyL/zAzA/w/88s8gAAAAAAAMzyAAAAAAAA8P8AAAA="}},"sprites.vehicle.roadTurn1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAwMzMzMzMzAC8u7u7u7u7wLvd3d3d3d2827u7u7u7u7y9u7u7u7u7vL27u7u7u7u8vbu7u7u7u7y9u7u7vbu7vL27uxvRu7u8vbu7EbG7u7y9u9sRu7u7vL27u727u7u8vbu7u7u7u7y9u7u7u7vdvL27u7u727u8vbu7u7vbyw=="},"pyQName":"sprites.vehicle.road_turn1"},"sprites.vehicle.roadTurn2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8vbu7u7vby7y9u7u7u9u7vL27u7u7u928vbu7u7u7u7y9u7u9u7u7vL272xG7u7u8vbu7EbG7u7y9u7sb0bu7vL27u7u9u7u8vbu7u7u7u7y9u7u7u7u7vL27u7u7u7u827u7u7u7u8C73d3d3d3dALy7u7u7u7sAwMzMzMzMzA=="},"pyQName":"sprites.vehicle.road_turn2"},"sprites.vehicle.roadIntersection1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7vbu7u7vby9u7u7u7u9vLvbu7u7u728u7u7u7u7vby7u7u7u7u9vLu7u7u7u728u7u7u7u7vby7u7u7u7u9vLu7u7u7u728u7u7u7u7vby7u7u7u7u9vLu7u7u7u728u7u7u7u7vby727u7u7u9vL27u7u7u728u7vbu7u7vbyw=="},"pyQName":"sprites.vehicle.road_intersection1"},"sprites.vehicle.roadIntersection2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzLu7u7u7u7u73d3d3d3d3d27u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u727u7u7u7vb27u7u7u7u727vbu7u7vbuw=="},"pyQName":"sprites.vehicle.road_intersection2"},"sprites.vehicle.roadTurn3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMwMALu7u7u7u8sA3d3d3d3duwy7u7u7u7u9y7u7u7u7u9vLu7u7u7u728u7u7u7u7vby7u727u7u9vLu7sdsbu728u7uxsRu7vby7u7uxG9u9vLu7u727u728u7u7u7u7vby927u7u7u9vLu727u7u728u8vbu7u7vbyw=="},"pyQName":"sprites.vehicle.road_turn3"},"sprites.vehicle.roadTurn4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8vbu7u7vby7u9u7u7u9vL3bu7u7u728u7u7u7u7vby7u7u9u7u9vLu7u7Eb2728u7uxsRu7vby7u7HbG7u9vLu7vbu7u728u7u7u7u7vby7u7u7u7u9vLu7u7u7u728u7u7u7u7u9y93d3d3d3bsMu7u7u7u7ywDMzMzMzMwMAA=="},"pyQName":"sprites.vehicle.road_turn4"},"sprites.vehicle.roadIntersection3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8vbu7u7vbu7y9u7u7u7u9vL27u7u7u9u8vbu7u7u7u7y9u7u7u7u7vL27u7u7u7u8vbu7u7u7u7y9u7u7u7u7vL27u7u7u7u8vbu7u7u7u7y9u7u7u7u7vL27u7u7u7u8vbu7u7u7u7y9u7u7u7vbvL27u7u7u728vbu7u7vbuw=="},"pyQName":"sprites.vehicle.road_intersection3"},"sprites.vehicle.roadIntersection4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7vbu7u7vbu9u7u7u7u7u9vbu7u7u7u9u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u93d3d3d3d3du7u7u7u7u7vMzMzMzMzMzA=="},"pyQName":"sprites.vehicle.road_intersection4"},"sprites.vehicle.roadVertical":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAADMzMzMzMzMzLu7u7u7u7u73d3d3d3d3d27u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u9sREbvbERG7GxHRuxsR0bu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u93d3d3d3d3du7u7u7u7u7vMzMzMzMzMzA=="},"pyQName":"sprites.vehicle.road_vertical"},"sprites.vehicle.roadHorizontal":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC8vbu7u7vby7y9uxu9u9vLvL27G7G728u8vbsbsbvby7y9uxuxu9vLvL2727G728u8vbu7u7vby7y9u7u7u9vLvL27u7u728u8vbsbvbvby7y9uxuxu9vLvL27G7G728u8vbsbsbvby7y9u9uxu9vLvL27u7u728u8vbu7u7vbyw=="},"pyQName":"sprites.vehicle.road_horizontal"},"sprites.projectile":{"kind":5,"retType":""},"sprites.projectile.bubble1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAALC7uwsAAACwm5lVtQsAALvZPTNdvQCwm92ZPTPVC7DZmZmZM1MLm5mZmZk507WbmZmZmdkztZuZmZmZmTO1m5mZmZmZM7WbmRGRmZkztZuZEZGZmVO1sJkRkZnZXQuwm5kZmd21CwC7mZnZXbsAALCbmZm5CwAAALC7uwsAAA=="}},"sprites.projectile.bubble2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAACwuwCwuwAAAJuzAFu1AAAAG7kAG7W7AACwu7u7u1ULAACwWbW7VQsAAJs9U7tRC7C7m5lTu7sAm7kbkZ0LAAAbuRuRubu7ALALsLu7kzkLAAC7C7AZkQsAsDkLsBmRCwCwmQsAkzkLALCRCwCwuwAAALsAAAAAAA=="}},"sprites.projectile.bubble3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAACwCwAAAAAAAFu1AAAAAAu7VbUAAACwuZldCwAAALDZPbkAAAAAsJ05swAAAACwmZmzAAAAALCZmbMAAAAAuxGZvQAAALCZEZm9AAAAsJGdmbsLAAAAu5vZm7MAAAAA272buQAAAACbuRu5AAAAABu5sAsAAAAAsAsAAA=="}},"sprites.projectile.bubble4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"aquatic","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAAAAAAAAARAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAQAQAAAAAAABABAAAAAAAAAAAAAAAAABARAAAAAAAAEBEAEAAAAAAQEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.projectile.drop1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAiMyMAACAiMxERMQIAEBERERERAgAgIjMRETECAAAAIDIzIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.projectile.drop2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAgAAAAAAMBEDAAAAAAASEQEAAAAAABMRIQAAAAAAExEhAAAAAAATESEAAAAAABMRIQAAAAAAExEhAAAAAAASEQMAAAAAADARAwAAAAAAACACAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.projectile.drop3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAEQkAgAAAABE1VUtIAAAQF3VVUUiAgBAVRVR1SICAEQdEdHdJCQAVBVRFVEtJABUFVERUUUkAFTVVRFRRSQA1N0RVVVNJABAXREV0S0kAEBdVR3RJAIAQFRVXVUkAgBARNRdRQAAAAAARCQCAAAAAAAAAAAAAA=="}},"sprites.projectile.drop4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAACBCALsLAAAiQkSw3QsAAEJURdvdvQIgVV1F27uxIkJV3QTbu9EkQl1VBNu700RCVFUkIrIRRFLVVU1EtBFEUlXVVUS0PURCVdVVIrLRREJU1Q3bu90kQkRdBdu7ESQgVFRF27uxIiBEVEXb3b0CICJERLDdCwAAIEJEALsLAA=="}},"sprites.projectile.drop5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAALDMAAAAuwsA270MALDdC7Dd3QwA290LsMzbywDbvQCwvNvNALsLANAMsM0AAAAA0AuwzQAAAADQCwDNuwAAANALAMu7ALAL0AsAAAAAsAvQvAAMAAAAALDMuwwAALsAsM3cDACw3Quw3d0MALDdCwDbzQwAALsAALDMDA=="}},"sprites.projectile.explosion1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAgAAAAAAAFQlAAAAAAAAVCUAAAAAAABAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.projectile.explosion2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAIAAAAAAAAAJAIABAAAAABAJUIEAAAAANBVRQAAAAAAVFUEAAAAAEBVVQIAAAAARERUJAAAAAAAAEBEAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.projectile.explosion3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAADMDAEQERAREMD1D1URVREUAU11VNVVdBAAwVRXR3U0AAEAdFVE1RAAAVBFRVVVNBABUEVFV1U0EAEAdVdXdTQQAQFURVT1EAADUFRFV3UMAANQdEd1VTQBATVRd1VVNBERERFTVRAREAAAAREQAAEAAAAAAAAAAAA=="}},"sprites.projectile.explosion4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAsAu7uwsAAAAbMRGxvQAAABvRHd3dCwCw09Gz290LABvRuwCwPQsAG7EAAAA7vQCwvQAAALC9ABu9AAAA270AG7EAAAA7vQAbvQAAsDO9ALAdu7DbvQsAABvdu929AAAAux0R07MAAAAAG9G9CwAAAACwuwsAAA=="}},"sprites.projectile.firework1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwMAAAAAAAAyMwAAAAAAABIRIzIAAAAAExERMQAAADMRERExAAAwERERESMAADARERERIwAAADMREREhAAAAABMRETEAAAAAEhEjMgAAAAAyMwAAAAAAADADAAAAAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.projectile.firework2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAIAAAAAAAATMQAAAAAAIBERAgAAAAAgERECAAAAAAATMQAAAAAAACACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.projectile.firework3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAADADAAAAAAAAMDEAAAAAADMwMQAwAwAAEzMxABMDAAAwISEwMQAAAAATMRIDAAAzMzMRMSIzMxMRERERERExMDMTETEzMwMAIBISEwMAAAAwMRMjMQAAABMDEwITAwAAMwATAzADAAAAABMDAAAAAAAAEwMAAAAAAAAzAAAAAA=="}},"sprites.projectile.firework4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAADAzAAAzAzADExEDMBEDEzETEQISEQMTISAhAhIxACAiIAIAIgIAAAAAAAAgAgAAAAAAADIxADMjAAAgEREDExECAAASMQMwIwIAACACAAAAADAAAAAAACMCEgIiAgAwETIRMRIxADARMhExEhEDMDMAEwMwEQMAAAAzADAzAA=="}},"sprites.projectile.firework5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAADMAAAAAAAAwAwAAAAAAAAAAADMAAAAAAAAwAwAAADMAAAAAAAAwAwAAAAAAAAAAAAAAAAAAAAAAADAzAAAAMAMAAAAAAAAAAAAAAAAAMwAAAAAAAAAwAwAAAAAAAAAAMAMAAAAAAAAAMzADAAAAAAAAADMAAAAAAAAAAA=="}},"sprites.projectile.flash1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAACwvQAAAAAAAMDNAAAAAAAAwMUAAAAAAADc1QwAAACwzF1VzbwAANtdVVVV3QsAsMxdVc28AAAAANzVDAAAAAAAwMUAAAAAAADAzQAAAAAAALC9AAAAAAAAAAsAAAAAAAAAAAAAAA=="}},"sprites.projectile.flash2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsL0AAAAAAAC8vQwAAAAAu1xVvAsAAABbVVFVCwAAAFxVUVXMAAC7VRURVbULAN0VERER1Q0Au1UVEVW1CwDAXFVRVcwAAABbVVFVCwAAALtcVbwLAAAAALy9DAAAAAAAsL0AAAAAAAAAAAAAAA=="}},"sprites.projectile.flash3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAABEAEBEAEAAAERAREREAAAAAEREREQEAEBAREREREQAAEBERERERAAAREREREREBABEREREREQEAERERERERAQAQEREREREAABAREREREQAAABEREREBAAAAEBEREQAAAAAAEBEAAAEAAAAAAAAAAA=="}},"sprites.projectile.heart1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAPD//w8AAAAA/zMz/wAAAAA/MzPzDwAAAD8zMzP/AAAAPzMzs/sPAAD/MzO7u/8AAPA/M7u7+wAA/zMzu7v/AAA/EzGz+w8AAD8TMTP/AAAAPzMz8w8AAAD/MzP/AAAAAPD//w8AAAAAAAAAAAAAAA=="}},"sprites.projectile.heart2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAD///8PAAAA8D8zM/8AAADwMzMz8w8AAPAzMzMz/wAA8DMzM7v7DwDwMzOzu7v/APA/M7u7u/sPAP8zu7u7uw/wPzO7u7v7D/AzEbG7u/8A8DMRMbv7DwDwMxExM/8AAPAzMzPzDwAA8D8zM/8AAAAA////DwAAAA=="}},"sprites.projectile.heart3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8PAAAAAADwM/MPAAAAAPAzM/8AAAAA8DOz+w8AAAAAP7O7DwAAAPAzs/sPAAAA8BMz/wAAAADwM/MPAAAAAAD/DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.projectile.heart4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAsMu8ywAAAADbMRMxDAAAsB0RExHNAACwEREdER0LALAR0TMdEbEAsBHBABsRMwzA080AwNEdywDcEQwA3BGxABwRDAA7EbHAM80AsDMdy7AdzQAcEd0MsBERPR0RwwCwERHRHRELAMATEdHTsQAAADwRPbMMAAAAwLvLzAAAAA=="}},"sprites.projectile.heart5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAwAwAAAAAAADAxAAAAMAMAABEDAAAzMQAwMQAAABMRAzADAAAAMBExAAAwMQATEQMAAAARAzMxAAAAMDEAMAMAAAAAAAAAAAAAAAAAAAAwAwAzAwAAABMxABMxAAAAMBEDMBEDAAATMQATMQAAADADADMDAAAAAAAAAAAAAA=="}},"sprites.projectile.laser1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgEzECAAAAACATMQIAAAAAIBMxAgAAAAAgEzECAAAAACATMQIAAAAAIBMxAgAAAAAgEzECAAAAACATMQIAAAAAIBMxAgAAAAAgEzECAAAAACATMQIAAAAAIBMxAgAAAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.projectile.laser2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDEAAAAAAAAwMQAAAAAAADIhAAAAAAAAMiEAAAAAAAATMQIAAAAAIBMRAgAAAAAgEREDAAAAABIRESEAAAAAEhERIQAAAAASEREhAAAAABIRESEAAAAAIBERAgAAAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.projectile.laser3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICEAAAAAAAAgIQAAAAAAACAhAAAAAAAQERERAAAAEDEzMzMRAAAxADAxADABAAEAMjECAAEAMwAyMQIwAwAwIzMxIzMAAAAiEREhAgAAABIRERECAAAAMxERMQMAAAAwMzMzAAAAAAAAAAAAAA=="}},"sprites.projectile.laser4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwMAAAAAAAAAADADAAAzAAAAADMAMAMAAAAAMAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzADAAAAADADADMAAAAAMwAAMAMAAAAAAAAAADAzAAAAAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.projectile.star1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAACwuwAAAAAAALDVy8zMAAAAsNW9W8UAAAC7VV1VzQAAsFtVVdXNAABbVVVV1QwAsF1VVVW1DAAAWxVRVdUMAACwG1FV1c0AAAC7VV1VzQAAALDVvVvFAAAAsNXLzMwAAACwuwAAAAAAAAAAAAAAAA=="}},"sprites.projectile.star2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAALC7AAAAAAAAsNULAAAAAACw1b3MzAwAALBVvVtVDACwu1VVVdUMALtVVVVVvQywXVVVVVXLANtVVVVV1csA21VVVVXVywCwXRURVVXLAAC7FRFVVb0MALDbEVVV1QwAALBVvVtVDAAAsNW9zMwMAACw1QsAAAAAALC7AAAAAA=="}},"sprites.projectile.star3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7AAAAAAAAAFvLzAwAAAAAW71VDAAAALBVVd0MAAAAW1VVzQAAAABbEVXNAAAAALARVd0MAAAAAFu9VQwAAAAAW8vMDAAAAAC7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.projectile.star4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAALC7CwAAAAAAsB2xALsAAACwERHM3bsAAMARERsRsQCw3B3RHRGxABsRzdzdEb2wERHLvNvdDNARwQzAEbEM293NDLARsQvAHRHMuxvduwAcEdsR2xG9ALDR3RHdEbEAABwRvdsRsQAAHBHNvB29AACwEcwAu7sAALC7AAAAAA=="}},"sprites.projectile.star5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAsAAAAACwAABbuwAAAFu7u1W1CwAAW1u1W7u1u7BVVQu7W1W1W1W1C7BVVbu7VVW7AFtVtbBbW7UAsLW7AFu7uwC7CwAAuwAAsLULAAAAsAC7VbUAAABbu1VVuwAAsFW1u1W1AAAAW7uwtQsAAACwAAC7AAAAAAAAAAAAAA=="}},"sprites.kaiju":{"kind":5,"retType":""},"sprites.kaiju.egg":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsLvMDAAAALDbvdvLAACwGxEz290MALARETPd3csAGxETEdG7zQAbERER0bvNABszERHR3c0AGzMTEbPbzQCwMRMxs9vLALAbETG73QwAALDb3d3LAAAAALC7zAwAAAAAAAAAAAAAAAAAAAAAAA=="}},"sprites.kaiju.eggRolling":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQVABUAAAAAsLvMzMwAAAAAAAAAu9u7u83MDAAAAACwGzEzu9vdzAwAAAC7ETEzM7vd3cwAAAC7ETEzM7Pd3c0MAAAbEREzMxPd3d3MAAAbERERERHd3d3NDAAbERERERHR3bvLDAAbERERERHRvbu7DAAbETMRERHRvbu7DAAbETMRERHRvbu7DAC7ERERERHR3bvbDACwERERERHR3d3dDACwERERMxPR3d3dDACwGxExMzPd3d3dDAAA2xExM7Pb3d3NDAAAuxExs7vbvdvNAAAAsNvdu7vdvdvMAAAAALvd3d3d3c0MAAAAALC73d3dzcwAAAAAAACwu8vMzAAAAAA="},"pyQName":"sprites.kaiju.egg_rolling"},"sprites.kaiju.kaijuBabyLarge":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQfAB4AAAAAAAAAAAAAAADAzMwAAAAAAAAAAAAAAAAAANzNDAAAAAAAAAAAAAAAAADA3cwAAAAAAAAAAAAAAAAAwN3NAAAAAAAAAAAAAAAAAMDdzQwAAAAAAAAAAAAAAADM3d0MAAAAAAAAAAAAAAAA3N3dDAAAAAAAAMzMzMzMzN3d3QwAAAAAAMxVVdXd3d3d3d0MAAAAAFxVVVVV1d3d3b27zAwAAMBVVVVVVVXd3d273c3MAABcVVVVVVVV1d3dXVVVxQDAVbW8VVVVVVXdXVVVVcUAwFXFzFVVVVVV1V1VVVXFAFxVFby1VVVVVVVVVVVVxQBcVVVVVVtVVVVVVVVVVcUAXFVVVVVbVVVdVVVVVVXFAFxVVVVVvFVVXVVVVVW7xQBcVVVVxcNVVVtV1VXFzMUAXFVVVREzVbVbVVW92wzMAFxVVVXMM1VcVV1V3d0MAABcVVVVzDPFVVVdVd3NDAAAXFVbxcxTxVVVW1XdzQAAAMBVVcu8XcVVu1VV3cwMAADAVbvb3V3FvFtV1c3cDAAAANzd3d3dVVVVVdXM3QwAAADAzMy73VVVVdXNvL0MAAAAAMDcvbtcVVXNzNzNAAAAAADA3d3MwMzMzADcDAAAAAAAwN29DAAAAAAAzAAAAAAAAADMzAAAAAAAAAAAAAAA"},"pyQName":"sprites.kaiju.kaiju_baby_large"},"sprites.kaiju.kaijuBabyWalk0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMzMDAAAAADAVcW1wAwAAFxVtVO8DMwAXFW1U7vMvMBVVRVTy8y8wFVVtVVczLzAVfFVVVXMzMBV/1VVtd3bAFxVVVW7XVUAXFVVVd1dVQDAVVXd3b27AABcVd3d3cwAAMDc3d3dDAAAAMDMzN0MAAAAAADczQAAAAAAAMAMAA=="},"pyQName":"sprites.kaiju.kaiju_baby_walk0"},"sprites.kaiju.kaijuBabyWalk1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAwMzMAAAAAABcxVUMzAAAwFW1M8XLAADAVbUztcsAAFxVFTO1zAzMXFW1VcXFzLxc8VVVW8XcvFz/VVVV21u8XFVVVbXbVczAVVVV1d21DABcVdXd3bsMAMBV1d3dzQAAAMzd3d3NAAAAAMzM3M0AAAAAAADcDAAAAAAAAMwAAA=="},"pyQName":"sprites.kaiju.kaiju_baby_walk1"},"sprites.kaiju.kaijuBabyWalk2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAwMzMAAAAAABcxVUMzAAAwFW1U8XLAADAVbVTtcsAAFxVFVO1zMzMXFW1VcXF3Lxc8VVVW8VbvFz/VVVV21W8XFVVVbXbtczAVVVV1d27DABcVdXd3c0MAMBV1d3dzQAAAMzd3d3NAAAAAMzM3AwAAAAAAADcDAAAAAAAAMwAAA=="},"pyQName":"sprites.kaiju.kaiju_baby_walk2"},"sprites.kaiju.kaijuBabyWalk3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAwMzMAAAAAABcxVUMzAAAwFW1U8XLAADAVbVTtcsMAFxVFVO1zMwMXFW1VcXFtcxc8VVVW7VVvFz/VVVVu1u8XFVVVbXbtbzAVVVV1d21zABcVdXd3c0AAMBV1d3dzQAAAMzd3d3NAAAAAMzM3M0AAAAAAADMzQAAAAAAAMDMAA=="},"pyQName":"sprites.kaiju.kaiju_baby_walk3"},"sprites.kaiju.kaijuBabyWalk4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMzMDAAAAADAVcy1wAwAAFxVO1O8DAAAXFU7U7vMzMBVVbFTy8zLwFVVu1VczMzAVfFVVVXM3MBV/1VVtd1bAFxVVVW7XVUAXFVVVd1dtQDAVVXd3b3LAABcVd3d3QwAAMDc3d3dDAAAAMDMzN0MAAAAAADAzQAAAAAAAMDMAA=="},"pyQName":"sprites.kaiju.kaiju_baby_walk4"},"sprites.kaiju.kaijuBabyWalk5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMzMDAAAAADAVcW1wAwAAFxVtVO8DMwAXFW1U7vMy8BVVRVTy8zLwFVVtVVczMzAVfFVVVXMzMBV/1VVtd3cAFxVVVW7XVUAXFVVVd1dVQDAVVXd3b3LAABcVd3d3QwAAMDc3d3dDAAAAMDMzM0AAAAAAADAzQAAAAAAAMAMAA=="},"pyQName":"sprites.kaiju.kaiju_baby_walk5"},"sprites.kaiju.kaijuMomAttack0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAMAMAAAAAAAAAAAAAMDNAAAAAAAAAAAAzMDdDAAAAAAAAMAMzMzdDAAAAAAAAMAMzLzdzQAAAADADAC83d3dzQAAAADAzLvd3d3dvQwAAMwAvFXV3d3duwwAAMwMW1XV3d29y8wAAMy8VVXd3d3du80AAMBbVdXdu93V3c0AzMBVVdXdVVtV3cUAzMxVVVXdVcVV1cUAzFxVVVXdW7VV1cUAwFxVVVXVu1W8zM0AAFxVX1XVvVW8y8wAAFxV/7VVvcy73AwAAFxV8bVbvbvL3QwAAFxVVRWzxczM3AwAAMBVVTUzxc0AwAwAAMBV1bUzxQwAwAwAAABcVbVVxQAAAAAAAADAVcXMDAAAAAAAAAAAzAwAAAAAAAA="},"pyQName":"sprites.kaiju.kaiju_mom_attack0"},"sprites.kaiju.kaijuMomAttack1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAADMAAAAAAAAAAAAAADcDAAAAAAAwAzAAMDdDAAAAMAMwMzADMzdzQAAAMDMAMzLzLzdzQAAAADMu93d3d3dzQAAzAy7VdXd3d3dvQwAzLxVVVXd3d3duwwAwFtVVd273d29y8zMwFVV1b1V293du83MXFVV1d1VtV3V3c3MXFVV3d1VVVtV3cXAVVXVVd3LVbVV1cXAVfVVVbW7XMVV1cXAVfVfVbW7y7y7zM3AVRVfVbW7u7u7y8zAVVVVXdW7u7u72wwAXFVVtV28u7u73AwAXFVdtVW8u7u73AwAwFVVtVXMu7vLzAwAAFxVtcUAzMwMwAwAAMDMzAwAAMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.kaiju.kaiju_mom_attack1"},"sprites.kaiju.kaijuMomAttack2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAzAAAAAAAAAAAAADAzQAAAAAAwAzAAADczQAAAMAMwMzADMzbzQAAAMDMAMzLzLzdzQAAzAy7VdXd3d3dzQAAzLxVVVXd3d3dvQwAwFtVVd3d3d3duwzMwFVV1b273d29y8zMXFVV3d1V293du83MXFXVXdVVtV3V3c3AVbXVVVVVVVtV3cXAVcVVVVXLVbVV1cXAVcVVVVW7XMVV1cXAVVVcVVW7y7y7zM3AVVVVXdW7u7u7y8wAXFVV1V27u7u72wwAXFVdtVW8u7u73AwAwFVVtVW8u7u73AwAAFxVtcW8u7u7zAwAAMDMzAzAu7vLwAwAAAAAAAAAzMwMAAAAAAAAAAAAAMwAAAAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.kaiju.kaiju_mom_attack2"},"sprites.kaiju.kaijuMomAttack3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAMzMAAAAAAAAAAAAwN3NDAAAAAAAAAAAwNzdDAAAAAAAAAAMzLzdzQAAAAAAAADMzNzdzQAAAAAAzADA293dvQwAAAAAzLzb3d3dvQwAAMAMwFtV3d3duwwAAMDMsFVV3d29y8wAAMDMW1XV3d3du80AAAC8VVXd3btd3c0AwAxcVVXd3VVb3cUAwMxcVVXV3VW11cUAwMxVVVXV3Vu11cUAAMxVtVVVVbtVzM0AAMBVxVW1W7VVzMwAAMBVxVW7u1vL3AwAAMBVVVy7u7tV2wwAAMBVVVWxuzNT3AwAAABcVVU7MzNTzAwAAABcVV07MzNTDAAAAADAVVVbVVXFAAAAAAAAXFXMzMwMAAAAAAAAwMwAAAAAAAA="},"pyQName":"sprites.kaiju.kaiju_mom_attack3"},"sprites.kaiju.kaijuMomAttack4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAMzMAAAAAAAAAAAAwN3NDAAAAAAAAAAAwNzdDAAAAAAAAAAMzLzdzQAAAAAAAADMzNzdzQAAAAAAzADA293dvQwAAAAAzLzb3d3dvQwAAMAMwFtV3d3duwwAAMDMsFVV3d29y8wAAMDMW1XV3d3du80AAAC8VVXd3btd3c0AwAxcVVXd3VVb3cUAwMxcVVXV3VW11cUAwMxVVVXV3Vu11cUAAMxVtVVVVbtVzM0AAMBVxVW1W7VVzMwAAMBVxVW7u1XL2wwAAMBVVVy7u1u12wwAAMBVVVWxOzPF3AwAAABcVVU7MzPFwAwAAABcVV07MzPFAAAAAADAVVVbVVUMAAAAAAAAXFXMzMwAAAAAAAAAwMwAAAAAAAA="},"pyQName":"sprites.kaiju.kaiju_mom_attack4"},"sprites.kaiju.kaijuMomAttack5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAMzMAAAAAAAAAAAAwN3NDAAAAAAAAAAAwNzdDAAAAAAAAAAMzLzdzQAAAAAAAADMzNzdzQAAAAAAzADA293dvQwAAAAAzLzb3d3dvQwAAMAMwFtV3d3duwwAAMDMsFVV3d29y8wAAMDMW1XV3d3du80AAAC8VVXd3btd3c0AwAxcVVXd3VVb3cUAwMxcVVXV3VW11cUAwMxVVVXV3Vu11cUAAMxVtVVV3btVzM0AAMBVxVVVVb1VzMwAAMBVxVW7W1XL2wwAAMBVVVy7u1W73QwAAMBVVVWxM1PM3AwAAABcVVU7M1MMwAwAAABcVV07M1MMAAAAAADAVVVbVcUAAAAAAAAAXFXMzAwAAAAAAAAAwMwAAAAAAAA="},"pyQName":"sprites.kaiju.kaiju_mom_attack5"},"sprites.kaiju.kaijuMomLarge":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwRNAEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMzMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzLxb1d3NzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMzMzLtVVVXV3c0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMBVu1tVVVVVVd3dzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW1VVVVVVVVXV3c0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALtbVVVVVVVV1d3dDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu7u7VVVVVdXd3cwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu7tbVVXV3d3NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsFVV1d3dzQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALBbVdXd3d0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW1Xd3d3dDADMDAAAAAAAAAAAAAAAAAAAAAAAAADAzAAAAAAAAAAAAFvV3d3d3QzAzAwAAAAAAAAAAAAAAAAAAAAAAAAAwFUMAAAAAAAAAADb3d3d3d3MwN0MAAAAAAAAAAAAAAAAAAAAAADMDLxVywAAAAAAAAAA293d3d3dzNzdDAAAAAAAAAAAAAAAAAAAAADAVbW9VbsMAAAAAAAAsNvd3d3dzczV3QwAAAAAAAAAAAAAAAAAAAAAwFW1vVu7DAAAAAAAALDd3d3NzMxd1czMDAAAAAAAAAAAAAAAAAAAwMzbtVW7VcwAAAAAAAC73d3MzMzdXcXc3QwAAAAAAAAAAAAAAAAAAFxVu7tVVVXNzAAAAAAA3N3MXFXV3V3F3c0AAAAAAAC7zMwMAAAAAABcVbXdVVVV3c0MAAAAwNzNXFVVVd1d1d0MAAAAAAC7W1VVxQwAAAAAvLu73btVVd3dzAAAAMy7XFVVVVXdXVXNDAAAAACwW1VVVVXFDAAAAMzb3bu1VVXd3c0MAMDMu1VVVVVV3V1VzQwAAAAAu1VVVVVVVcUAAADA3N1btVXV3b27y8zMvFtVVVVVVd3dVc0MAAAAsFtVVVW1y8xVzAAAAMDdW7VV3b3b3d3du7tdVVVVVdXd3d3MDAAAALBVVbtV28zMXMUMAAAAzFVbVbtbVVXd3d27VVVVVVXV3d3d3c0AAAC7VVVVtdy9zMxVzAAAAMDM3btbVVVVVV3dvVVVVVVV3d3d3d3MAAAAW1VVVcXMzMzMXMXMzMwAwLtbVVVVVVVV1d1VVVVVVd3d3c3MzAAAAFtVVVXFzMzMzNy121W1DMC7VVVVVVVVVVXdVVVVVVXV3d3NDAAAAABbVVVVxczMzMzMVVVVVcXMVVVVVVVVVVXV3V1VVVVV1d3dzQAAAAAAW1VVVcXMzMzMzDwzEVPV291VVVVVVVVVVd3dVVXdVd3d3cwAAAAAAFtVVVXFzMzMzMwzMzMzVdvd3VVVVVVV1V1d1d3d3d3d3d3MAAAAAABbVVVVVczMzMw8MzMzE1G73d1VVVVVVdVdXdXd3d3d3d3NDAAAAAAAW1VVVVXMzMzMOzMzMzNTu93dXVVVVVVVVdXV3d3d3d3dzQAAAAAAAFtVVVVVy8zMzDMzMzMzU7vd3V1VVVVVVVXV3d3d3d3d3cwAAAAAAABbVVW7VcXMzMwzs7szE1G73d1dVVVVVVVV1d3d3d3d3c0MAAAAAAAAW1VVvVW1zMzMszszMzNTu93dXVVVVVVVVVXV3d3d3d3LDAAAAAAAAFtVVVVVFRHBzMwzMzMzVdvd3V1VVVVVVVVV1d3d3d29ywAAAAAAAABbVVVVVVURy8w8M7O7W9Xb3d1dVVVVVVXVVdXd3d3dvc0AAAAAAAAAW1VVVVVVy8zMMzMTEVW13d3dVVVVVVVV1VXV3d3d3d3NAAAAAAAAAFtVVVVVVcXMzDMzMxFV3d3dXVVVVVVVVVXV3d3d3d3dzQAAAAAAAABbVVVVVVVVu8wzMzNT1d3dXVVVVVVVVVVV1VXd3d3d3c0AAAAAAAAAW1VVVVVVVRHBOzOzVd1VVVVVVVVVVVVVVd1V3d3d3d3NAAAAAAAAALtVVVVVVVUVyzwzW9VdVVVVVVVVVVVVVVXd3d3d3d3dzQAAAAAAAAC7VVVVVVVVVczMzFXdVVVVVVVVVVVVVVVV3d3d3d3d3c0AAAAAAAAAsFVVVctdVVXMzFzVXVVVVVVVVVVVVVVdVdXd3d3d3d3NDAAAAAAAALBVVVXMXFVVzLxV3VVVVVVVVVVVVVVVVV3V3d3d3d3dzQwAAAAAAACwW1VVzFtVVcxVVVVVVVVVVVVVVVVVVVVd3d3d3d3d3b0MAAAAAAAAAFtVVRxbVVVbVVVVVVVVVVVVVVVVVVXV3d3d3d3d3d27zAAAAAAAAAC7VVXFXFW7VVVVVVVVVcxbVVVVVVVV3d3d3d3d3b27u8sAAAAAAAAAsFVVVVVVW1VVVVVVVVVcu1VVVVVV1dXd3d3d3d3d3bvLAAAAAAAAALBbVVVVVVVVVVVVVVVVXLVbVVVVVV3V3d3d3d3d3d3duwwAAAAAAAAAXFVVVVVVVVVVVVXFzMxVzFxV1dVV3d3d3d3d3d3d3d3MAAAAAAAAAMxVVVVVVVVVVVVVxbXLVVXMXF3d3d3d3d3d3d3d3d3dzQwAAAAAAMDLXFVVVVVVVVVVVcVVu9VdVczc3d3d3d3d3d3d3d3d3d0MAAAAAACwy8xVVVVVVVVVVVXFXLXd3V1VzNzd3d3d3d3d3d3d3d3dzAAAAAAAu8zMXFVVVVVVVVVVVVy1u93dVVXM3N3d3d3d3d3d3d3d3c0AAAAAAMvMzMxVVVVVVVVVVVVcu8Xdu1VVVczd3d3d3VXd3d3d3d3NAAAAAADMDADAXFVVVVVVVVVVzFvFvVtbVVXF3d3d3d1V3d3V3d3dzQAAAAAAAAAAwMxVVVVVVVVVVc1Vtb1VW9VVxdzd3V3VXVVVXd3d3c0MAAAAAAAAAMDM3FXVVVVVXdXNXbW7VdvdVVXc3d1VXVVVVVXd3d3NzAAAAAAAAADAu8zd3VXdVd3dzVtVu1XVXVVVzN3d1V1VVVVV1d3d3c0AAAAAAAAAwMvMzN3dXVXd3d28VVVVVVVVVcXd3d1VVVVVVVXd3d3NDAAAAAAAALzLzMzM3V3V3d3dzVVVVVVVVVXF3d3dVVVVVVVV3d3dzQwAAAAAAAC8zMwAwMzc3d3d3d3MVVVVVVVVxd3d3VVVVVVVVdXd3c0MAAAAAAAAzAwAAMDMzNzd3d3dzcxVVVVVVc3d3d1VVVVVVVVV3VXdzAAAAAAAAAAAAADAy8zMzN3d3d2921VVVVXN3d3bXVVVVVVVVV1V3c0AAAAAAAAAAAAAsMvMzMzMzNvd3btdVVXVzd3du11VVVVVVVVdVdzNAAAAAAAAAAAAALDMzMwAzMzMzN273VVV3c3du7vbVVVVVVVVXdXMzQAAAAAAAAAAAADAzAAAAMzMzMDcvd3d3d3MzMzMzFxVVVVVVV3VzcwAAAAAAAAAAAAAAAAAAADAzAwAzN3d3d3NzMzMAADMXFVVVdVd1d0MAAAAAAAAAAAAAAAAAAAAwMwAAADM3d3NzADMDAAAAMzMVdXdXdXdDAAAAAAAAAAAAAAAAAAAAMAMAAAAwMzMzAwAwAAAAAAAwMzMzFzF3cwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzczdzNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAzNzMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADc3QwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwN0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAwAAA=="},"pyQName":"sprites.kaiju.kaiju_mom_large"},"sprites.kaiju.kaijuMomWalk0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAMDMAAAAAAAAAAAAAMC9DAAAAAAAAAAAzMDdDAAAAAAAAMAMzMzdywAAAAAAAADMzLzdzQAAAADAzAC83d3dzQAAAADAzLvd3d3dvQwAAMwAvFXV3d3duwwAAMwMW1XV3d3du8wAAMC8VVXd3d3dvdsAAMBbVdXdu91V3d0AzMBVVVXdVdtV1V0AzMxVVVXdVcVdVV0AwFxVVVXdW7XbVVsAwFxVVVXVvVW8y9wAAFxVX1XVvVW8y8wAAFxV/7Vbvcy73AwAAFxV8bVbvbvL3QwAAFxVVRWzxczM2wwAAMBVVTUzxc0AvAwAAMBV1bUzxQwAzAwAAABcVbVVxQAAAAAAAADAVcXMDAAAAAAAAAAAzAwAAAAAAAA="},"pyQName":"sprites.kaiju.kaiju_mom_walk0"},"sprites.kaiju.kaijuMomWalk1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAMAMAAAAAAAAAAAAAMDNAAAAAAAAAAAAzMDdDAAAAAAAAMAMzMzdDAAAAAAAAMAMzLzdzQAAAADADAC83d3dzQAAAADAzLvd3d3dvQwAAMwAvFXV3d3duwwAAMwMW1XV3d29y8wAAMy8VVXd3d3du80AAMBbVdXdu93V3c0AzMBVVdXdVVtV3cUAzMxVVVXdVcVV1cUAzFxVVVXdW7VV1cUAwFxVVVXVu1W8zM0AAFxVX1XVvVW8y8wAAFxV/7VVvcy73AwAAFxV8bVbvbvL3QwAAFxVVRWzxczM3AwAAMBVVTUzxc0AwAwAAMBV1bUzxQwAwAwAAABcVbVVxQAAAAAAAADAVcXMDAAAAAAAAAAAzAwAAAAAAAA="},"pyQName":"sprites.kaiju.kaiju_mom_walk1"},"sprites.kaiju.kaijuMomWalk2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAADMAAAAAAAAAAAAAMDcDAAAAAAAAAAAAMDdDAAAAAAAAADAzLzdzQAAAAAAwMwAzNzdzQAAAADMAMy83d3dzQwAAADMvNvd3d3dvQwAAADMW1Xd3d29uwwAwMywVVXV3d29uwwAwMxbVdXd3d29uwwAwLxVVd29293du80AAFxVVd1d213V3c3AzFxVVd1dxV1V3cXAzFVVVdVdxdtV1cUAzFVVVVW9VbxdtcUAwFVfVVW9Vby7y80AwFX/tVW1Vby73AwAwFXxtbvVu7vM3AwAwFVVVTFbzMzMwAwAAFxVVTNTzFzFwAwAAFxVXTtTDFwMAAAAAMBVVVvFAMwAAAAAAABcVcwMAAAAAAAAAADAzAAAAAAAAAA="},"pyQName":"sprites.kaiju.kaiju_mom_walk2"},"sprites.kaiju.kaijuMomWalk3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMAAAAAAAAAAAAANy9DAAAAAAAAADAzMzdywAAAAAAwMwAzNzdzQAAAADMAMy83d3dzQwAAADMvNvd3d3dvQwAAADMW1Xd3d29uwwAwMywVVXV3d29uwwAwMxbVdXd3d29uwwAwLxVVd292929uwwAAFxVVd1d293duwzAzFxVVd1dxV3V3QzAzFVVVdVdxV1VXcUAzFVVVVW9VdzVVcUAwFVfVVW9VbxdVcUAwFX/tVW1VbxcVQwAwFXxtbvVu7tcxQAAwFVVVTFbzMzMAAAAAFxVVTNTzFzFAAAAAFxVXTtTDFwMAAAAAMBVVVvFAMwAAAAAAABcVcwMAAAAAAAAAADAzAAAAAAAAAA="},"pyQName":"sprites.kaiju.kaiju_mom_walk3"},"sprites.kaiju.kaijuMomWalk4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMAAAAAAAAAAAAwN29DAAAAAAAAADAzNzdywAAAAAAwMwAzLzdzQAAAADMAMy83d3dzQwAAADMvNvd3d3dvQwAAADMW1Xd3d29uwwAwMywVVXV3d29uwwAwMxbVdXd3d29uwwAwLxVVd292929uwwAAFxVVd1dxd3dvcvAzFxVVd1dxd1V1c3AzFVVVdVdVdtV1VUAzFVVVVW9Vbzd1VUAwFVfVVW9VbzbXVUAwFX/tVW1Vby7XFUAwFXxtbvVu7vLXMUAwFVVVTFbzMzMzAwAAFxVVTNTzFzFAAAAAFxVXTtTDFwMAAAAAMBVVVvFAMwAAAAAAABcVcwMAAAAAAAAAADAzAAAAAAAAAA="},"pyQName":"sprites.kaiju.kaiju_mom_walk4"},"sprites.kaiju.kaijuMomWalk5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMzMAAAAAAAAAAAAzN3LDAAAAAAAAMwAzNy9DAAAAAAAAMwMzNzdzAAAAADMAMC83d3dzQAAAADMvNvd3d3dvQwAAADAW1Xd3d3duwwAwMywVVXV3d3duwwAwMxbVdXd3d3duwwAALxVVd29291VvcsAAFxVVd1dtd1V1d3AzFxVVdVdVdxdVV3AzFVVVdW9W8XbVV0AzFVVVVXdW8W7W10AwFX1VVXdW8W7y1sAwFX1X1vVy7y7zNwAwFUVX7vVu7vMDMAAwFVVVTFbzMy8DAAAAFxVVTNTzFXMAAAAAFxVXTtTzMUAAAAAAMBVVVtVzAwAAAAAAABcVczMAAAAAAAAAADAzAAAAAAAAAA="},"pyQName":"sprites.kaiju.kaiju_mom_walk5"},"sprites.swamp":{"kind":5,"retType":""},"sprites.swamp.mushroomBackLeft0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAwPz/AAAAAADMu7vM/wAAALy7u8vdDAAAu7u7u9zN/7Abu7u7y93csBG7u7vL3dywMTO7u7vc3LAzM7O7u9z/OzMzs7u7y/s7MzMzG7HLCzszMzMbscsLOxMxM7u7ywuwGzGzu7v7AAC7y7u7u/sAAAAAvLu7/wAAAADA/P8PAA=="},"pyQName":"sprites.swamp.mushroom_back_left0"},"sprites.swamp.mushroomBackLeft1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMz/DwAAAADAu7vL/A8AAMC7u7vczQAAsLu7u8vdDAAbsbu7y93NABuxu7u73M0AGzO7u7vczQA7MzO7u8v9sDMzM7u7y7ywMzMzEzG7vLAzMzMTMbsMsBMRM7O7uwwAuxGzu7u7DwCwu7y7u8sPAAAAwLu7/A8AAAAAzP//AA=="},"pyQName":"sprites.swamp.mushroom_back_left1"},"sprites.swamp.mushroomBackLeft2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMz/DwAAAADAvLvL/A8AAMC7u7vczf8AsLu7u8vd/AC7sbu7u9zNABuxu7u73M0AGzOzu7vLzQA7MzO7u8v9sDMzM7u7u7ywMzMzsxG7vLAzMzOzEbu8sDMRM7O7u/wAuxEzu7u7DwCwu7y7u7sPAAAAwLu7+w8AAAAAzP//AA=="},"pyQName":"sprites.swamp.mushroom_back_left2"},"sprites.swamp.mushroomBackLeft3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAwPz/AAAAAADMvLvM/wD/AMy7u7vc/N8AvLu7u8vN27Abu7u7y93csBG7u7u73LywETOzu7vc/LAzM7O7u8sPOzMzM7u7yww7MzMzOxHL/zszMzM7Ecu7OzMRM7u7y7uwGxEzu7v7vwC7y7y7u/v/AAAAzLu7/wAAAADA/P8PAA=="},"pyQName":"sprites.swamp.mushroom_back_left3"},"sprites.swamp.mushroomBackRight0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADA/P8PAAAAALy7u/8AALvLu7u7+wCwGzGzu7v7ADsTMTO7u8sLOzMzMxuxyws7MzMzG7HLCzszM7O7u8v7sDMzs7u73P+wMTO7u7vc3LARu7u7y93csBu7u7vL3dwAu7u7u9zN/wC8u7vL3QwAAMy7u8z/AAAAwPz/AAAAAA=="},"pyQName":"sprites.swamp.mushroom_back_right0"},"sprites.swamp.mushroomBackRight1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAzP//AAAAAMC7u/wPALC7vLu7yw8AuxGzu7u7D7ATETOzu7sMsDMzMxMxuwywMzMzEzG7vLAzMzO7u8u8ADszM7u7y/0AGzO7u7vczQAbsbu7u9zNABuxu7vL3c0AsLu7u8vdDADAu7u73M0AAMC7u8v8DwAAAMz/DwAAAA=="},"pyQName":"sprites.swamp.mushroom_back_right1"},"sprites.swamp.mushroomBackRight2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAzP//AAAAAMC7u/sPALC7vLu7uw8AuxEzu7u7D7AzETOzu7v8sDMzM7MRu7ywMzMzsxG7vLAzMzO7u7u8ADszM7u7y/0AGzOzu7vLzQAbsbu7u9zNALuxu7u73M0AsLu7u8vd/ADAu7u73M3/AMC8u8v8DwAAAMz/DwAAAA=="},"pyQName":"sprites.swamp.mushroom_back_right2"},"sprites.swamp.mushroomBackRight3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADA/P8PAAAAAMy7u/8AALvLvLu7+/+wGxEzu7v7vzszETO7u8u7OzMzMzsRy7s7MzMzOxHL/zszMzO7u8sMsDMzs7u7yw+wETOzu7vc/LARu7u7u9y8sBu7u7vL3dwAvLu7u8vN2wDMu7u73PzfAMy8u8z/AP8AwPz/AAAAAA=="},"pyQName":"sprites.swamp.mushroom_back_right3"},"sprites.swamp.mushroomFrontLeft0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAwPz/AAAAAADMu7vM/wAAALyzzNvdDAAAO8O83b3N/7Abw9zMvd2/sBHD3d293buwMcPd3d3du7Azs93d3Lv/OzMz2829vfs7MzPb3f3dCzszM7Pd/dsLOxMxs8vM/wuwGzEzzMz7AAC7yzPDzPsAAAAAvDO7/wAAAADA/P8PAA=="},"pyQName":"sprites.swamp.mushroom_front_left0"},"sprites.swamp.mushroomFrontLeft1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMz/DwAAAADAvLvL/A8AAMA8y9zdzQAAsDPM3d3bDAC7MbzN3NvNABsx3N3du/sAGzHc3d3buwA7M9vdzd+9sDMz293cv72wMzOz3d39v7AzM7Pb3c0MsDMRMbvLzAwAuxExs8y8DwCwu8wzw7wPAAAAwDuz+w8AAAAAzP//AA=="},"pyQName":"sprites.swamp.mushroom_front_left1"},"sprites.swamp.mushroomFrontLeft2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAMz/DwAAAADAvLvL/A8AAMA8y7zdzf8AsDPM29zb+wAbMczd3Nv9ABsx3N3d280AOzHc3d3dzQA7M9vdzd27sDMzs93NvduwMzOz3d393bAzMzPb3f3dsDMTMbvMzP8AuxMxw8y8DwCwu8wzzLwPAAAAwDuz+w8AAAAAzP//AA=="},"pyQName":"sprites.swamp.mushroom_front_left2"},"sprites.swamp.mushroomFrontLeft3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAwPz/AAAAAADMu7vM/wD/ADyzzLzd/L8AO8PM3b39u7Abw9zMvd27sBHD29293f+wMTPb3d3d/7AzM9vd3N0MOzMz283dzQw7MzOz3d3NuzszM7Pd3bvdOxMxM8vM/N2wGzEzzMz72wC7yzPDzPv/AAAAPDO7/wAAAADA/P8PAA=="},"pyQName":"sprites.swamp.mushroom_front_left3"},"sprites.swamp.mushroomFrontRight0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADA/P8PAAAAALwzu/8AALvLM8PM+wCwGzEzzMz7ADsTMbPLzP8LOzMzs9392ws7MzPb3f3dCzszM9vNvb37sDOz3d3cu/+wMcPd3d3du7ARw93dvd27sBvD3My93b8AO8O83b3N/wC8s8zb3QwAAMy7u8z/AAAAwPz/AAAAAA=="},"pyQName":"sprites.swamp.mushroom_front_right0"},"sprites.swamp.mushroomFrontRight1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAzP//AAAAAMA7s/sPALC7zDPDvA8AuxExs8y8D7AzETG7y8wMsDMzs9vdzQywMzOz3d39v7AzM9vd3L+9ADsz293N370AGzHc3d3buwAbMdzd3bv7ALsxvM3c280AsDPM3d3bDADAPMvc3c0AAMC8u8v8DwAAAMz/DwAAAA=="},"pyQName":"sprites.swamp.mushroom_front_right1"},"sprites.swamp.mushroomFrontRight2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAzP//AAAAAMA7s/sPALC7zDPMvA8AuxMxw8y8D7AzEzG7zMz/sDMzM9vd/d2wMzOz3d393bAzM7Pdzb3bADsz293N3bsAOzHc3d3dzQAbMdzd3dvNABsxzN3c2/0AsDPM29zb+wDAPMu83c3/AMC8u8v8DwAAAMz/DwAAAA=="},"pyQName":"sprites.swamp.mushroom_front_right2"},"sprites.swamp.mushroomFrontRight3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAADA/P8PAAAAADwzu/8AALvLM8PM+/+wGzEzzMz72zsTMTPLzPzdOzMzs93du907MzOz3d3NuzszM9vN3c0MsDMz293c3QywMTPb3d3d/7ARw9vdvd3/sBvD3My93bsAO8PM3b39uwA8s8y83fy/AMy7u8z/AP8AwPz/AAAAAA=="},"pyQName":"sprites.swamp.mushroom_front_right3"},"sprites.swamp.swampTile0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAACAiAAAAAAAAIBnCAAAAAAAAHiHAACAiIiIaHeIiIB3hoiIdndmAGh3d2dmhogAgIh2d3d3ZgAAgIhohohoAICIdnd3ZmYAiHd3ZmZmZoh3d4Zod4eIiIiIiHdniIgAAABoZ4hmZgAAiHiGeGdmAABoiIh3iIgAAIBmeIdoZg=="},"pyQName":"sprites.swamp.swamp_tile0"},"sprites.swamp.swampTile1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAABoeIiIiAAAAIhoaGaIAAAAiIiIZoiAiIiIiHeIiIB3hoiIdndmAGh3d2dmhogAgIh2d3d3ZgAAgIhohohoAICIdnd3ZmYAiHd3ZmZmZoh3d4Zod4eIiIiIiHdniIgAAABoZ4hmZgAAiHiGeGdmAABoiIh3iIgAAIBmeIdoZg=="},"pyQName":"sprites.swamp.swamp_tile1"},"sprites.swamp.swampTile2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAABoeIiIiAAAAIhoaGaIAAAAiIiIZoiAiIiIiHeIiIB3hoiIdmdmAGh3d2dmhogAgIh2d3d3ZgAAgIhohohoAICIdnd3ZmYAiHd3ZmZmZoh3d4Zod4eIiIiIiHdniIgAAABoZ4hmZgAAAHiGeGdmAAAAiIh3iIgAAAAAgIgAAA=="},"pyQName":"sprites.swamp.swamp_tile2"},"sprites.swamp.swampTile3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAACAiAAAAAAAAIBnCAAAAAAAAHiHAACAiIiIaHeIiIB3hoiIdndmAGh3d2dmhogAgIh2d3d3ZgAAgIhohohoAICIdnd3ZmYAiHd3ZmZmZoh3d4Zod4eIiIiIiHdniIgAAABoZ4hmZgAAAHiGeIeIAAAAiIh3CAAAAAAAiIgAAA=="},"pyQName":"sprites.swamp.swamp_tile3"},"sprites.swamp.swampTile4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAACIqAAAAAAAiKiqqgAAAICIqqqqCgAAiKiqqqqqAACIqqqqqqoAgKiqqqqqqgqAqKqqqqqqCoioqqqqqqoKiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqg=="},"pyQName":"sprites.swamp.swamp_tile4"},"sprites.swamp.swampTile5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAACIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKiqqqqqqgqAqKqqqqqqCoCoqqqqqqoKAIiqqqqqqgAAiKiqqqqqAACAiKqqqgoAAACIqKqqAAAAAACIqAAAAA=="},"pyQName":"sprites.swamp.swamp_tile5"},"sprites.swamp.swampTile6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAACqqgAAAAAAqqqqAAAAAKqqqqoAAACgqqqqqgAAAKiqqqqqAACAqqqqqqoAAIiqqqqqqgCAqKqqqqqqAICoqqqqqqoAiKqqqqqqqgCIqqqqqqqqgKiqqqqqqqqAqKqqqqqqqoCoqqqqqqqqgKiqqqqqqqqIqKqqqqqqqg=="},"pyQName":"sprites.swamp.swamp_tile6"},"sprites.swamp.swampTile7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAACIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqoiqqqqqqqqqiKqqqqqqqqqIqqqqqqqqqg=="},"pyQName":"sprites.swamp.swamp_tile7"},"sprites.swamp.swampTile8":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAACIqKqqqqqqqoCoqqqqqqqqgKiqqqqqqqqAqKqqqqqqqoCoqqqqqqqqAIiqqqqqqqoAiKqqqqqqqgCAqKqqqqqqAICoqqqqqqoAAIiqqqqqqgAAgKqqqqqqAAAAqKqqqqoAAACgqqqqqgAAAACqqqqqAAAAAACqqqoAAAAAAACqqg=="},"pyQName":"sprites.swamp.swamp_tile8"},"sprites.swamp.swampTile9":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAACqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqg=="},"pyQName":"sprites.swamp.swamp_tile9"},"sprites.swamp.swampTile10":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAC7uwAAAAAAu7u7AAAAALu7u7sAAACwu7u7uwAAALu7u7u7AACwu7u7u7sAALu7u7u7uwCwu7u7u7u7ALC7u7u7u7sAu7u7u7u7uwC7u7u7u7u7sLu7u7u7u7uwu7u7u7u7u7C7u7u7u7u7sLu7u7u7u7u7u7u7u7u7uw=="},"pyQName":"sprites.swamp.swamp_tile10"},"sprites.swamp.swampTile11":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7u7u7u7u7u7C7u7u7u7u7sLu7u7u7u7uwu7u7u7u7u7C7u7u7u7u7ALu7u7u7u7sAu7u7u7u7uwCwu7u7u7u7ALC7u7u7u7sAALu7u7u7uwAAsLu7u7u7AAAAu7u7u7sAAACwu7u7uwAAAAC7u7u7AAAAAAC7u7sAAAAAAAC7uw=="},"pyQName":"sprites.swamp.swamp_tile11"},"sprites.swamp.swampTile12":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAACqqgAAAAAAAKqqqgAAAAAAqqqqqgAAAACqqqqqCgAAAKqqqqqqAAAAqqqqqqoKAACqqqqqqqoAAKqqqqqqqgoAqqqqqqqqCgCqqqqqqqqqAKqqqqqqqqoAqqqqqqqqqgqqqqqqqqqqCqqqqqqqqqoKqqqqqqqqqgqqqqqqqqqqqg=="},"pyQName":"sprites.swamp.swamp_tile12"},"sprites.swamp.swampTile13":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAACqqqqqqqqqqqqqqqqqqqqqqqqqqqqKqKqqM6OqqoqoqjqjOqo6g4iqM6qqozqDiKoToaqjqoiIqhOhqqOqiIiqOqM6qqqIiKqqM6OqqoiIqqqqqjqjiIiqqqqqozqIiKqqqqqjOoqoqqqqqjqjiqiqqqqqqqqqqqqqqqqqqqqqqg=="},"pyQName":"sprites.swamp.swamp_tile13"},"sprites.swamp.swampTile14":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAACqqqqqqqqqqqqqqqqqqqoKqqqqqqqqqgqqqqqqqqqqCqqqqqqqqqoKqqqqqqqqqgCqqqqqqqqqAKqqqqqqqgoAqqqqqqqqCgCqqqqqqqoAAKqqqqqqCgAAqqqqqqoAAACqqqqqCgAAAKqqqqoAAAAAqqqqAAAAAACqqgAAAAAAAA=="},"pyQName":"sprites.swamp.swamp_tile14"},"sprites.swamp.swampTile15":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAC7uwAAAAAAu7u7uwAAALC7u7u7CwAAu7u7u7u7AAC7u7u7u7sAsLu7u7u7uwuwu7u7u7u7C7C7u7u7u7sLu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uw=="},"pyQName":"sprites.swamp.swamp_tile15"},"sprites.swamp.swampTile16":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7uw=="},"pyQName":"sprites.swamp.swamp_tile16"},"sprites.swamp.swampTile17":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7sLu7u7u7uwuwu7u7u7u7C7C7u7u7u7sLALu7u7u7uwAAu7u7u7u7AACwu7u7uwsAAAC7u7u7AAAAAAC7uwAAAA=="},"pyQName":"sprites.swamp.swamp_tile17"},"sprites.swamp.swampTile18":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7uwAAAAAAALu7uwAAAAAAu7u7uwAAAAC7u7u7CwAAALu7u7u7AAAAu7u7u7sLAAC7u7u7u7sAALu7u7u7uwsAu7u7u7u7CwC7u7u7u7u7ALu7u7u7u7sAu7u7u7u7uwu7u7u7u7u7C7u7u7u7u7sLu7u7u7u7uwu7u7u7u7u7uw=="},"pyQName":"sprites.swamp.swamp_tile18"},"sprites.swamp.swampTile19":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._tile","tags":"tile forest swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAC7u7u7u7u7u7u7u7u7u7sLu7u7u7u7uwu7u7u7u7u7C7u7u7u7u7sLu7u7u7u7uwC7u7u7u7u7ALu7u7u7uwsAu7u7u7u7CwC7u7u7u7sAALu7u7u7CwAAu7u7u7sAAAC7u7u7CwAAALu7u7sAAAAAu7u7AAAAAAC7uwAAAAAAAA=="},"pyQName":"sprites.swamp.swamp_tile19"},"sprites.swamp.swampTree1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAAAAAMD/DwDwzwAAAAAAALy8/ADwywAAAAAAAAzAy///+wAAAMD/DwDA293d/QAAALzM/M+73d29+wAAwAzA/Nzbvbvd+w8AAAAA/73dzLvb3Q8AAAAA39vNzP+83M2wzADA3NvL3A+8zM0Au8zMvd0M3A+8y/8AwL27270A2w/A+wAAANzd3Qyw+wAA/wAAAMDMzACwDwAA8AAAAAAAAAAAAAAAAAA="},"pyQName":"sprites.swamp.swamp_tree1"},"sprites.swamp.swampTree2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAAADw/w8AAAAAAAAAAAAAAADAbGb2DwAAAAAAAAAAAAAAbGZm9v8AAAAAAAAAAAAAwGZmd3f/DwAAAAAAAAAAAGxmd3d3Zw8AwAwAAAAAAMDMZnd3d2f2ALwMAAAAAADMzMZsd3dm9sDMDMwAAAAAfMfMzHd3ZvbAu8zNAAAAwHdmd8x2d3dmzMy8ywAAAMB3dndndnd3Z7zL3csAAAB8d3d3Z3Z3d3c8s9v9AAAAfGd2d2Z2d3d3PN0z+wAAAHxmdndmdnd3d9zdPfMAAMBndmZ3Z3Z3d2fb3d37AADAZ3dmd3dmd3dm2929ywAAwGd3Z3d3ZndnZtvdu90MAMBnd2d3d2Z3Z2bb3ds9wwDAZ3dmd3dmd3dm293TPc0AwGd2Zndndnd3Z9vdM70MAAB8ZnZ3ZnZ3d3fc3T37AAAAfGd2d2Z2d3d3PN0z8wAAAHx3l3lndnd3dzwz2/0AAADAd5aZZ3Z3d2e8y937AAAAwHxmmcx2d3dmzMy8ywAAAAB8x8zMdndm9sy7zM0AAAAAbMzGbHd3ZvbAzAzMAAAAAMDMdpd5d2f2ALwMAAAAAAAAbHaXmXf3DwDADAAAAAAAAMBmd5l3/w8AAAAAAAAAAAAAbGZmZv8AAAAAAAAAAAAAAMBsZmYPAAAAAAAAAAAAAAAA8P//AAAAAAAAAA=="},"pyQName":"sprites.swamp.swamp_tree2"},"sprites.swamp.swampTree3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAAADw/w8AAAAAAAAAAAAAAADwj4j4DwAAAAAAAAAAAAAAj4iI+P8AAAAAAAAAAAAA8IiIZmb/DwAAAAAAAAAAAI+IZmZmhg8A8A8AAAAAAPD/iGZmZob4AO8PAAAAAAD///iPZmaI+PD/D/8AAAAAb/b//2ZmiPjw7v/7AAAA8GaIZv9oZmaI///v/gAAAPBmaGaGaGZmhu/+u/4AAABvZmZmhmhmZmbv7r77AAAAb4ZoZohoZmZm77vu/gAAAG+IaGaIaGZmZr+76/4AAPCGaIhmhmhmZoa+u7v+AADwhmaIZmaIZmaIvrvrzgAA8IZmhmZmiGaGiL677rsMAPCGZoZmZohmhoi+u77r/gDwhmaIZmaIZmaIvru+6/sA8IZoiGaGaGZmhr677usPAABviGhmiGhmZma/u+v+AAAAb4ZoZohoZmZm77vu/gAAAG9mdmeGaGZmZu/uvvsAAADwZnh3hmhmZobv/rv+AAAA8G+Id/9oZmaI///v/gAAAABv9v//aGaI+P/u//sAAAAAj//4j2ZmiPjw/w//AAAAAPD/aHZnZob4AO8PAAAAAAAAj2h2d2b2DwDwDwAAAAAAAPCIZndm/w8AAAAAAAAAAAAAj4iIiP8AAAAAAAAAAAAAAPCPiIgPAAAAAAAAAAAAAAAA8P//AAAAAAAAAA=="},"pyQName":"sprites.swamp.swamp_tree3"},"sprites.swamp.witchBack0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7/P8A7gAAwFv1/+/rAADMVVX/7/8MAMy7Vf//W/vMXLVb//9V9VxVVVv//1v1vFVVW///W/XAXLVb//9V9QDMu1X//1v7ALxVVf///AwAwFv1/+/rAADAu///AO4AAADMAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_back0"},"sprites.swamp.witchBack1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8+/8PAAAAALxV///uAADAW1X1/7sMAMC8W/X/vv4AwFW79f/u/gBcVbX1/7/1wFVVtfX/v/XAzFW79f9f9QDAvFv1/1/1AMBcVfX/+/UAALxV///rDwAAvMv/D+4AAADADAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_back1"},"sprites.swamp.witchBack2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7//8A7gAAwFv1/+/rAAC8VVX/7/wMAMy7Vf//W/vAXLVb//9V9bxVVVv//1v1XFVVW///W/XMXLVb//9V9QDMu1X//1v7AMxVVf/v/wwAwFv1/+/rAADAu/z/AO4AAADMAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_back2"},"sprites.swamp.witchBack3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8y/8P7gAAALxV///rDwDAXFX1//v1AMC8W/X/X/XAzFW79f9e9cBVVbX1/771AFxVtfX/vvUAwFW79f/u/gDAvFv1777+AMBbVfXvuwwAALxV///uAAAAvPv/DwAAAADADAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_back3"},"sprites.swamp.witchForward0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7//8A7gAAwFv1/+/rAAC8VVX/7/wMAMy7VRv7W/vAXLVb/+tV9bxVVVu+61v1XFVVW77rW/XMXLVb/+tV9QDMu1Ub+1v7AMxVVf/v/wwAwFv1/+/rAADAu/z/AO4AAADMAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_forward0"},"sprites.swamp.witchForward1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8y/8P7gAAALxV///rDwDAXFX1//v1AMC8W7WxX/XAzFW79b9e9cBVVbXlu771AFxVteW7vvUAwFW79e/u/gDAvFu14bv+AMBbVfXvuwwAALxV///uAAAAvPv/DwAAAADADAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_forward1"},"sprites.swamp.witchForward2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7/P8A7gAAwFv1/+/rAADMVVX/7/8MAMy7VRv7W/vMXLVb/+tV9VxVVVu+61v1vFVVW77rW/XAXLVb/+tV9QDMu1Ub+1v7ALxVVf/v/AwAwFv1/+/rAADAu///AO4AAADMAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_forward2"},"sprites.swamp.witchForward3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8+/8PAAAAALxV///uAADAW1X177sMAMC8W7Xhu/4AwFW79e/u/gBcVbXlu771wFVVteW7vvXAzFW79b9e9QDAvFu1sV/1AMBcVfX/+/UAALxV///rDwAAvMv/D+4AAADADAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_forward3"},"sprites.swamp.witchLeft0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7DAAAAAAAwFv1AAAAAADMVVX/D/AMAMy7Ve77X/vAVbVbvutV9VxVVVu+61v1zFVVW//rW/UAXLVbG+vu9QDMu1W++7v+ALxVVf7vuw4AwFv1/+/uAADAu///AAAAAADMAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_left0"},"sprites.swamp.witchLeft1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8ywAAAAAAALxVDwAAAADAXFX1//AMAMC8W+W+X/UAXFW75bu+9cBcVbXlu771wFVVtfW/7vUAzFW7teG7/gDAvFvl67v+AMBbVeX/7g8AALxV//8PAAAAvPv/DwAAAADADAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_left1"},"sprites.swamp.witchLeft2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7DAAAAAAAwFv1AAAAAADMVVX/D/AMAMy7Ve77X/vAVbVbvutV9VxVVVu+61v1zFVVW//rW/UAXLVbG+vu9QDMu1W++7v+ALxVVf7vuw4AwFv1/+/uAADAu///AAAAAADMAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_left2"},"sprites.swamp.witchLeft3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8ywAAAAAAALxVDwAAAADAXFX1//AMAMC8W+W+X/UAXFW75bte9cBcVbXlu771wFVVtfW/vvUAzFW7tbG+9QDAvFvlu+7+AMBbVeX/uw4AALxV//+7DgAAvPv/D+4AAADADAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_left3"},"sprites.swamp.witchRight0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7//8AAAAAwFv1/+/uAAC8VVX+77sOAMy7Vb77u/4AXLVbG+vu9cxVVVv/61v1XFVVW77rW/XAVbVbvutV9QDMu1Xu+1/7AMxVVf8P8AwAwFv1AAAAAADAuwwAAAAAAADMAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_right0"},"sprites.swamp.witchRight1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8+/8PAAAAALxV//8PAADAW1Xl/+4PAMC8W+Xru/4AzFW7teG7/sBVVbX1v+71wFxVteW7vvUAXFW75bu+9QDAvFvlvl/1AMBcVfX/8AwAALxVDwAAAAAAvMsAAAAAAADADAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_right1"},"sprites.swamp.witchRight2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAzAAAAAAAAMC7//8AAAAAwFv1/+/uAAC8VVX+77sOAMy7Vb77u/4AXLVbG+vu9cxVVVv/61v1XFVVW77rW/XAVbVbvutV9QDMu1Xu+1/7AMxVVf8P8AwAwFv1AAAAAADAuwwAAAAAAADMAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_right2"},"sprites.swamp.witchRight3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"people swamp","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAAAAAAAAAAAAAwAwAAAAAAAC8+/8P7gAAALxV//+7DgDAW1Xl/7sOAMC8W+W77v4AzFW7tbG+9cBVVbX1v771wFxVteW7vvUAXFW75bte9QDAvFvlvl/1AMBcVfX/8AwAALxVDwAAAAAAvMsAAAAAAADADAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.swamp.witch_right3"},"sprites.skillmap":{"kind":5,"retType":""},"sprites.skillmap.akita":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQhACgAAADLzMzMzMzMzMzMzMwAAAAAAAAAAJuZmZmZmZmZmZmZuf8AAAAAAAAAm7k7k5mZmZmZmZmZ+Q8AAAAAAAC7mbszmZmZmZmZGRER+w8AAAD/D7CbmZn5n8GcmRkRERGx+////7sPALuZmfkfEZyZERERERG7u7u7uw8AwJuZmRkRsZkREREREbu7u7v7DwDAnJkZEfGxmxERERER8f///w8AAMCcmRER/zGzERERERHxAAAAAAAAwJuZERH/MbMZEREREfEAAADw/wC7mZmZER/BnJkRERERsf///5/5sJuZmfkfEcGZmZkREZGZmZmZmfm7mbsz+Z+RnJmZmZmZmZmZmZmZzJu5O5OZmZmZmZmZmZmZmZnMzMwMm5mZmZmZubuZmZmZmZmZzAAAAAC7zMzMzMzMzJmZmZmZmckAAAAAAAAAAAAAAADAm5mZmZmZyQAAAAAAAAAAAAAAAACbmZmZmZnBAAAAAAAAAAAAAAAAAJyZmZmZGcEAAAAAAAAAAAAAAAAAnJmZmZkZwQAAAAAAAAAAAAAAAACcmZmZmRnB/wDwDwAAAAAAAADMzJyZmZmZGcG7/78PAAAAAAAAwJm5m5mZmZkZwbu7uw8AAAAAAACcmdGbmZmZmRnB/7+7DwAAAAAAsJkZ0Z2ZmZmZmcEA8P8AAAAAAACwmRG9m5mZmZmZucwAAAAAAAAAALCZEb27mZmZmZmZyQwAAAAAAAAAsJkR0buZmZmZmZmZzADAzAAAAACwmRkREZuZmZmZmZnJzJzJAAAAALCZmRGRmZmZmZmZmZmZm8kAAAAAAJuZmZmZzMzMzMycmZmZyQAAAAAAu5mZmckMAAAAAMDMzMwMAAAAAAAAu8vMDAAAAAAAAAAAAAA="}},"sprites.skillmap.bridge":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYACsAAADg7v/v7v/v7v/v7v/v7v/v7v///+8AAADu3e7u3e7u3e7u3e7u3e7u3e677u4OAADeu+3eu+3eu+3eu+3eu+3eu+2+6+4OAADeu+3eu+3eu+3eu+3eu+3eu+3+++4PAADu3e7u3e7u3e7u3e7u3e7u3e7+++4PAADg7v7/7v7v7v7v7v7v7v7v7v7//v8AAAAA4Lv+v+v/u/6/6/+7/r/r/7v+bwYAAAAA4Lvuv+v+u+6/6/677r/r/rvubwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvrvrvuu+u+u+6767677rvrbwYAAAAA4Lvuv+v+u+6/6/677r/r/rvubwYAAAAA4Lv+v+v/u/6/6/+7/r/r/7v+bwYAAADg7v//7v/v7v/v7v/v7v/v7v///+8AAADu3e7u3e7u3e7u3e7u3e7u3e677u4OAADeu+3eu+3eu+3eu+3eu+3eu+2+6+4OAADeu+3eu+3eu+3eu+3eu+3eu+3+++4PAADu3e7u3e7u3e7u3e7u3e7u3e7+++4PAADg7v7v7v7v7v7v7v7v7v7v7v7//v8AAAA="}},"sprites.skillmap.button":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQPABAAAAAAAAAAzMzMAABmzMzczcwMYHaXaca9vAxgd3dpxt28y3Z3iJdm3LzLdod4l2bcu8t2iHiXZty7y3Z4eJdm3LvLdoh4l2bcu8t2h3iXZty7y3Z3iJdm3LzLYHd3acbdvMtgdpdpxr28DABmzMzczcwMAAAAAMzMzAA="}},"sprites.skillmap.cloud":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQYABAAAAAAAAAAwMwAAAAAALDb3cwAAAAAG9HdywAAALAREb27DAAAsBHR3b0MAACwER0R3QwAu9sRERHRzbAbEREREdHNsBERERER0c0bERERERHdyxsRERER0b3LGxERERER3csbERERERHdzbAREREREdHNsNsRERER0c0A290RERHdzQDbERER0d3NABsRERHR2wwAGxERERG9DACwEdEREc0AAAC7GxERzQAAAAAbEdEMAAAAALARzQwAAAAAAMsMAAA="}},"sprites.skillmap.decoration0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzMzMAAAAAAAAAADAPMvDDAAAAAAAAADAM8MzDHUAAAAAAADAzMw7DHBnZgYAAADMw8s7DHAGAGYAAAA8vMPMDGcAAAAAAADMw8vDdwYAAAAAAADAzDPDYAYAAAAAAAAAAMzMYAAAAAAAAAAAAAAAZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.decoration1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcHAAcHcAYAAAAAAAcHcAd3YAZwcGAAAAx2Z3bHZmB2YHAAAAcMd2d3ZnBwAAAAAAfGd3d+duAAAAAABwx2d3ZnZ+DgAAAABwbGd2d2Zn53AGAAAAZ2x8d253ZnAAAAAAYHdnbuZm5gYAAAAAx3dndnfu7gAAAAAAZ2bHd2d37wAAAAAAcGd253Z2fwAAAAAAx3dnZ2f+Z3AHAAAAwGZ3d3cGAAYGAAAAcHx2d2Z3AAAAAAAAAHcHdwd3BgAAAAAAAAAAAAAAcAYHAAAAAAAAAAAAAGAAAAA="}},"sprites.skillmap.decoration2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAJAJAAAAAAAAAAAAAJmZAAAAAAAAAAAAAJCZCQAAAAAAAAAAAJmZAAAAAAAAAAAAAJAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQCQAAAAAAAAAAAACZmQAAAAAAAAAAAJCZmQkAAAAAAAAAAACZmZkAAAAAAAAAAACQmZkJAAAAAAAAAACQmZkJAAAAAAAAAACZmZkAAAAAkAAAAJCZmQkAAAAAmQkAAACZmQAAAAAAkJkAAACQCQAAAAAAmQkAAAAAAAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.decoration3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAiIgIAAAAAAAAAACIiIiIAAAAAAAAAICIiIiICAAAAAAAAICIiIiIiAAAAAAAAICIiIiIiAgAAAAAAICIiIiIiIgAAAAAAACIiIiIiIgIAAAAAACAiIiIiIiICAAAAACIiIiIiIgIAAAAAICIiIiIiIgAAAAAAICIiIiIiAgAAAAAAICIiIiIiAAAAAAAAICIiIiICAAAAAAAAACIiIiIAAAAAAAAAACAiIgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.decoration4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwuwAAAAAAAAAAAADb3QsAAAAAAAAAALDd3b0AAAAAAAAAALDd3b0LAAAAAAAAALDd3d28AAAAAAAAAADb3b3MCwAAAAAAAACw3bvMvAAAAAAAAADbvcvMCwAAAAAAALDdu8y8AAAAAAAAALC9y8wLAAAAAAAAALDMzLwAAAAAAAAAAADLzAsAAAAAAAAAAACwuwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.decoration5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAAAAAAAAAAAAAQE4EcAAAAAAAAAAAQE50cAYAAAAAAAAAQE4EdwYAAAAAAAAAAEQAcAYAAAAAAAAAAAAAAGcAAAAAAABEAAAAAGAAAAAAAEBOBHB3d2YAAAAAAEBOdHdnBgAAAAAAAEBOBABmAAAAAAAAAABEAHAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.decoration6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMwAAAAAAAAAAAAAzMwMAAAAAAAAAAAAzMzMAAAAAAAAAAAAwMzMDAAAAAAAAAAAAMzMzAAAAAAAAAAAwMzMDAAAAAAAAAAAzMzMAAAAAAAAAAAAzMwMAAAAAAAAAAAAwMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.decoration7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIgAAAAAAAAAAAAAyIwIAAAAAAAAAAAAiIiIAAAAAAAAAAAAgIiICAAAAAAAAAAAAIiIiAAAAAAAAAAAgIrICAAAAAAAAAAAiIisAAAAAAAAAAAAiIgIAAAAAAAAAAAAgIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.decoration8":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwuwAAAAAAAAAAAAAbEQsAAAAAAAAAALAREbEAAAAAAAAAALARERELAAAAAAAAAAAbERGxAAAAAAAAAACwERERCwAAAAAAAAAbERGxAAAAAAAAALARERELAAAAAAAAALAREbEAAAAAAAAAAAAbEQsAAAAAAAAAAACwuwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.decoration9":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAzAAAAAAAAAAAAADMzAwAAAAAAAAAAMBMRMwAAAAAAAAAAMBERMQMAAAAAAAAAMBERETMAAAAAAAAAMBMRETEDAAAAAAAAADMREREzAAAAAAAAMBMRETEDAAAAAAAAMBERETMAAAAAAAAAMBERMQMAAAAAAAAAMBMRMwAAAAAAAAAAADMzAwAAAAAAAAAAADAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.decoration10":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3AAAAAAAAAAAADQ19BwAAAAAAAAAA0N0ABwAAAAAAAAAA3dVtd3cAAAAAAAAA0N0AcGcAAAAAAAAADQ0NdwYAAAAAAAAAAABwZwAAAAAAAAAAAABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.decoration11":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADg7g4AAAAAAAAAAAAAPu4AAAAAAAAAAADg7s53d3cGAAAAAAAA7swAcHcGAAAAAADgzgxwd2YAAAAAAAAAAAB3ZwAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.decoration12":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsLAAAAAAAAAACwu7sMAAAAAAAAAAC7u8sAAHAAAAAAALC7vAwAAHcAAAAAALC7DABwdwAAAAAAAAC7dwB3AAAAAAAAAAAHu3sAAAAAAAAAAAC7u7u7DAAAAAAAALC7u8vLd3cAAAAAAAC7u8sHAAAAAAAAAAC3fAcAAAAAAAAAAHAAB3AHAAAAAAAAAHC7ywBwBwAAAAAAALC7uwwAcAAAAAAAAAC7u8vLAHcAAAAAAACwu7u7AAAAAAAAAAAAAACwAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.decoration13":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAHFnZwAAAAAAAAAGEB13ZwAAAAAAAABwd3F3dwcAAAAAABDHd3fGdwYAAAAAANFxdmd3dwcAAAAAYBd3d2Z3ZwcAAAAAYHd3Zxd3dwYAAAAAEHdnZ9FxdwcAAAAA0XF3Zhd3ZwYAAAAAEHd8dnbHdwYAAAAAAHd3d2d3dwYAAAAAAGYXd3ZndwcAAAAAAHbRcXd3dgYAAAAAAHAXd3cXdwcAAAAAAAB3d3fRcQYAAAAAAAAAZ3wXdwYAAAAAAAAAcHd2ZgAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.decoration14":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAmQAAAAAAAAAAAACQkXkAAAAAAAAAAAAAmQAAAAAAAAAAAAAAAAAHAAAAAAAAAJAJAAcAAAAAAAAAAJmRd3cAAAAAAAAAAJAJcAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAACZAHAAAAAAAAAAAJCReXcAAAAAAAAAAACZAHAAAAAAAAAAAAAAAAAAAAAAAAAAAACQCQAHAAAAAAAAAACZkXcAAAAAAAAAAACQCQcAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.fans":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwRTAFAAAAAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAfEfEPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ERERDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwHxEREf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/xERzBz7DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8RwRy82/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfscERvN39AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH7HLEdzd/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+xuxHM3f0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfEbsREdv9/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/xERERGxEfH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAfERERsRER//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/xERERERERHx/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAfERERERER0f3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////ERERERHd/f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8RERER0d3MzBH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw/xEREdG9zBwR8Q8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPD/ERHRuxsRERH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8RuxERERER8Q8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADw/xERERERERH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPD//////xER8f8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/HxERERHMERH//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwHxHMvBERERy7EREREf////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA/xERzLyxGxHBERERERERERH///8AAAAAAAAAAAAAAAAAAAAAAAAAAB8REREREcE7ExwREREWFhERERERAAAAAAAAAAAAAAAAAAAAAAAAAPAfERERERHBMxO8GxFhZmYRZmYWEQAAAAAAAAAAAAAAAAAAAAAAAADwERERERERwTMTwbsRERYWERYWEREAAAAAAAAAAAAAAAAAAAAAAAAA8BEREREREbsREcGxG2FmZhEWFhERAAAAAAAAAAAAAAAAAAAAAAAAAPARERERERERERHBEdsRFhYREREREQAAAAAAAAAAAAAAAAAAAAAAAADwEREREcHMGxERwRHbHREREWFmZhEAAAAAAAAAAAAAAAAAAAAAAAAA8BERERHBzBsREcER290RERFhYRERAAAAAAAAAAAAAAAAAAAAAAAAAPARERERERERERHBsdvdZhFhEWZmEQAAAAAAAAAAAAAAAAAAAAAAAADwERERERERERERwbvdbWZmZhEREREAAAAAAAAAAAAAAAAAAAAAAAAA8BwREREREREREbzb3d0dEWERZmYRAAAAAAAAAAAAAAAAAAAAAAAAAPAcERERERERERHc3d3d3RERERYREQAAAAAAAAAAAAAAAAAAAAAAAAD/zBERERERERHxzN3d3d0RERFhZhEAAAAAAAAAAADw//////8AAADw380cERERERER///f3b27u7sbERERAAAAAAAAAADw/xERERHx/wAA/93dzBwRERER/w/w/9273R0Ru7sREQAAAAAAAAAA/xEREREREfEP8L+7283MzP///w8AAP+/293dERERuxEAAAAAAAAA8B/BzBsRERER//+7EREREcz//w8AAADw/93d3REREbERAAAAAAAAAPARwcwbGxEREcG8EREREREREf///wAAAP/f3d0RERGxuwAAAAAAAAD/EREREcERERHBHBERERERERER8f///////93dERERsREAAAAAAAAAHxERERHBHBERERwRERERERERERERERGxu//cHREREbsRAAAAAAAAAB8RERERwcwcEREcERERYWEREWZmFhERsbvLzBEREREbEQAAAAAAAAAfEREREcE8MxERHBEREWZmFhEWFhEREbG7u8vMERGxGxEAAAAAAAAAHxERERHBMzMREbwbERFhYRERFhYRERGxu7u7y8wRzBERAAAAAAAAAB8RzLwRyzMTEREcsRERZmYWERERERERsbu7u7vLzMzMEQAAAADwDwAfEcy8sRsRERERHLEREWFhERFmZhYREbG7u7u7u7vLzMwAAP//H/8AHxERERERERERERyxERERERERFhYRERG7u7u7u7u7u8vMAPAfwRzxAP8REREREREREcERGxEREREREWFmFhERu7u7u7u7u7u7zAD/ERHM8QDwERERERERERHMuxERYRYRFhEREREREbu7u7u7u8zMzMzwHxERzPwA8B8RERERERHMHBEREWZmZhZhZmYRERG7u8zMzMzMzBER/xEREcz9AAD/ERERERHMHBEREREREREWYRERERGxu8zM3dzdzRwRER8RERHc/QAA8P8RERHMHBERERERERERERFmZhERsczc3d3b3cwREREfERHB3P0AAADw////vBERERERERHBzMzMzMwREcvc3d3du80cERERHxERwd39AAAAAAAA/xG7ERERERHBzBERERHBzBHMEREREb3MERERER8Ru8vd/QAAAAAA8B8REbsRERERzBERMxMREcHMHBERERHBHBEREcEfEbvL3fwPAAAAAP8RERERGxERERwRETMzERERzBERwczMzBERERHMHxHb3c0c/w8AAPAfEREREbEREcERERExMxMREcERERwRERERERHBHB8Rsd3NERH///+/ERERERHx///PERERMzMRERHBHBHMERERERHBzBH/EREREREREbu7vRsRERER////HxERETMTsRERERwRwcwcERHBzBER8P8fERERERER0d27ERER8Q8A8B8REREREREcEREcERHBHBERwREREQDw/x8RERERERHdvRsREf8AAPAfERERERERHBERHBERzMwREcEREREAAAD/HxERERER3d27EfEPAADwHxERERERERwRERwRzBHBHBHMERERAAAAAP8fEREREd3d/R//AAAA8B8RETMTEREcEREczBEREcwRHBEREQAAAAAA/x8REdHd3f//DwAAAPAfEREzMxG7ERERHBwRERHBzBwREREAAAAAAAD//xHd3f0PAAAAAADwHxERMTMTERERERzMEREREcwRERERAAAAAAAAAPD/////AAAAAAAAAP8RETMzEREREcEcwRwRERHMEREREQAAAAAAAAAAAAAAAAAAAAAAAAD/EREzExERERHBERHMERERwREREREAAAAAAAAAAAAAAAAAAAAAAAAA8B8RERERERERzBERwRwREcEcERERAAAAAAAAAAAAAAAAAAAAAAAAAAD/ERERERERwdwRwcwcERERHBEREQAAAAAAAAAAAAAAAAAAAAAAAAAA8P8RERERwczdEcwREREREcwREREAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////fvbscERERERHBERERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPD///8P37sRwczMzBERwRwREQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/dEREREcEREREcEREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3R0RERHBHBERzBERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8N8dERERERwREcEREQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3REREbEcERHB/xEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8P8RERG7zBEREfz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//xGx280RERHMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//u93NERERwQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///dzRwREfEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//90cERHxAA=="}},"sprites.skillmap.islandTile0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAAAYGZmZmZmZgBmd3d3d3d3YHZ3d3d3d3dgd3d3d3d3d2Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3dw=="},"pyQName":"sprites.skillmap.island_tile0"},"sprites.skillmap.islandTile1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3dw=="},"pyQName":"sprites.skillmap.island_tile1"},"sprites.skillmap.islandTile2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3dnd3d3d3d3d2d3d3d3d3d3Z3d3d3d3d3Znd3d3d3d3dgd3d3d3d3d2B2d3d3d3d3AGZ3d3d3d3cAYGZmZmZmZg=="},"pyQName":"sprites.skillmap.island_tile2"},"sprites.skillmap.islandTile3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABmZmZmZmZmZnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dw=="},"pyQName":"sprites.skillmap.island_tile3"},"sprites.skillmap.islandTile4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dw=="},"pyQName":"sprites.skillmap.island_tile4"},"sprites.skillmap.islandTile5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dmZmZmZmZmZg=="},"pyQName":"sprites.skillmap.island_tile5"},"sprites.skillmap.islandTile6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAABmzMzMvLsAAHd3Z2a2uwsAd3d3Zma9uwB3d3dnZt29AHd3d2fd3R0Ad3d3d2bdHQF3d3d3Z9bdAXd3d3dn1t0dd3d3d9bd3R13d3d3Z93dHXd3d3dn1t0dd3d3d2bW3RF3d3dnZtYdAXd3d3d31h0Bd3d3d2bWHQB3d3d3Z9YdAA=="},"pyQName":"sprites.skillmap.island_tile6"},"sprites.skillmap.islandTile7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB3d3d3Z9YdAHd3d2fW3R0Bd3d3d2bdHQF3d3d3Z9bdEXd3d3dn1t0dd3d3d2fW3R13d3d3Zt3dHXd3d3dn1t0dd3d3d2fW3R13d3d3Z9bdHXd3d3dn3d0Rd3d3d9bdHQF3d3dnZtYdAXd3d3dn1h0Ad3d3d2bWHQB3d3d3Z9YdAA=="},"pyQName":"sprites.skillmap.island_tile7"},"sprites.skillmap.islandTile8":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"tile misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQQABAAAAB3d3d3Z9YdAHd3d3dm1h0Ad3d3d3fWHQF3d3dnZtYdAXd3d3dm1t0Rd3d3d2fW3R13d3d3Z93dHXd3d3fW3d0dd3d3d2fW3R13d3d3Z9bdAXd3d3dm3R0Bd3d3Z93dHQB3d3dnZt29AHd3d2ZmvbsAd3dnZra7CwBmzMzMvLsAAA=="},"pyQName":"sprites.skillmap.island_tile8"},"sprites.skillmap.kaijuIcon":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQsACgAAAAAAAAAAAAAvLu7u7vLzLwLAAAAAAAAAAAAAMDc3d3dvcy7uwsAAAAAAAAAAAAAzNy93dvNvLu7CwAAAAAAAAAAAMDM3L3d2827u7sLAAAAAAAAAAAAwMzc3d3dzby7uwsAAAAAAAAAAADAzNy93d27zLu7CwAAAAAAAAAAAMDM3L3d3bvLu7sLAAAAAAAAAAAAwMzc3d3Mu7vb3Q0AAAAAAAAAAADAzNzdzdzd3d3dDQAAAAAAzMzMzMzMzMzM3d3d3d0NAAAAAMC83d3d3d3d3d3d3d3d3Q0AAAAAzLvd273d3dvbvd3b273dDQAAAAC8u93bvd3d29u93dvbvd0NAAAAALy73d3d3d3d3d3d3d3d3Q0AAAAAvLvdvd3b29vb2927u7u7CwAAAAC8u9293dvb29vbzdvd3d0NAAAAAMy73d3d3d3d3d3M3dvb2w0AAAAAwLzd3d3d3d3dzczd3d3dDQAAAAAAzMzMzMy8u7u7zN3b29sNAAAAAAAAAMDM3N3d3d3L293d3Q0AAAAAAAAAwMzc3d3d3d27zLy7CwAAAAAAAAC8zNy92729281VxcwMAAAAAAAAALzL3N3d3d3dXFW1VcUAAAAAAAAAzLvcvdu73ctV1bUzxQwAzAwAAADA3N3d3d3dzVVVNTPFzQC8DAAAAADc3d3d3btcVVUVs8XMzNsMAAAAAMDMzLvb3VxV8bVbvbvL3QwAAAAAAADAzMy8XFX/tVu9zLvcDAAAAAAAAMDMvLtcVV9V1b1VvMvMAAAAAAAAwMy7y1xVVVXVvVW8y9wAAAAAAAAAzLvLXFVVVd1btdtVWwAAAAAAAADAvMzMVVVV3VXFXVVdAAAAAAAAAAAAzMBVVVXdVdtV1V0AAAAAAAAAAAAAwFtV1d273VXd3QAAAAAAAAAAAADAvFVV3d3d3b3bAAAAAAAAAAAAAMwMW1XV3d3du8wAAAAAAAAAAAAAzAC8VdXd3d27DAAAAAAAAAAAAAAAwMy73d3d3b0MAAAAAAAAAAAAAADAzAC83d3dzQAAAAAAAAAAAAAAAAAAAMzMvN3NAAAAAAAAAAAAAAAAAADADMzM3csAAAAAAAAAAAAAAAAAAAAAzMDdDAAAAAAAAAAAAAAAAAAAAAAAwL0MAAAAAAAAAAAAAAAAAAAAAADAzAAA"},"pyQName":"sprites.skillmap.kaiju_icon"},"sprites.skillmap.mailboxIcon":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADADAAAAAAAAAAAAAAAAAAAvM0AAAAAAAAAAAAAAAAAwLvbDAAAAAAAAAAAAAAAALy7u80AAAAAAAAAAAAAAMC7u7vNAAAAAAAAAAAAAAC8u7u7zWa7AAAAAPD/z8zMvLu7u81n3QAAAAD/u7u7u7+7u9v9Z90AAADwv8zMzPzPu7vd/2fdAAAA8LzMzMz8/7vb/X9n3QAAALy8zMzM//+83f93t90AAAC83MzMzP//3/1/d9bdAADA29vNzPz//8//d2e23QAAwNu93cv8////f3d3Z90AALy73bvdu7u7/3d2d2fdAAC8u9vdy8zMzG93Zne33QDAu7u72929u/vMzGxn1t3g7u7uzMy7y7z7u7trd7bdICIiItzNu8y7z8zMbHe32yDiu7vbvbvMuw9gd2Z3Zt0g4ru7u7vLvPsAZnd2Z2bdIOK8u7u7y7z7YHZ3d3dn3QAAzLu7u8y7DwBgd3dmZt0AAMC8u8vMuw8AZnd3Z9bdAAAAwMzM//8AYHd3d3dm3QAAAAAAAAAAAGBmd2dmxrsAAAAAAAAAAAAAZnd3Zsy7AAAAAAAAAAAAAGB3Z8a8CwAAAAAAAAAAAAAAdmbMuwAAAAAAAAAAAAAAAGDMvAsAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.skillmap.mailbox_icon"},"sprites.skillmap.pigeon":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwRDAEYAAAAAAAAAAAAAzAzAzAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3M3M3cwMAMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzN29293MwM0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwNzdu93dvN0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzdvd3dvd3NzAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDc3d3dvdvd28wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADM3N3d3dvd280MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzNzd3d3dvd3MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzdu9vdvd3NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMC8u9vd3d29zAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADM3bvd3d2928wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADA3bu92929280AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADA3b27u9293c0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADA3d3dvd3d3csAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADA3d3du93d3csMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADA3d3du93dvdsMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADA3d3du7vb3d0MAAAAAAAAAAAAu7sLAAAAAAAAAAAAAAAAAAAA3N3d3b3b3b0MAAAAAAAAALu7ERELAAAAAAAAAAAAAAAAAAAAzN3d3d3b3bsMAAAAAACwuxERERELAAAAAAAAAAAAAAAAAAAAwN3d3d3b3d3MAAAAsLsbERERERG7AAAAAAAAAAAAAAAAAAAAwN3d3b273d3LAAAAsBERERERERGxAAAAAAAAAAAAAAAAAADA////3b273b0LAAAAsN0RERERERGxAAAAAAAAAAAAAAAAAMwcsbv73d29u7sAAAAAsNHdERERERGxAAAAAAAAAAAAAAAAwLwbsbvf3d29ywwAAAAAsBHRHRERERGxAAAAAAAAAAAAAAAAwLsbEfvd3czMzMwAAAAAsBER3RERERGxAAAAAAAAAAAAAAAAvLu7G8vMzLxm1s0MAAAAsBER0d0RERGxAAAAAAAAAAAAAAAAvLu7y8y7u7trNt3MAAAAsBEREdEdERERCwAAAAAAAAAAAAAAvLu7u7u7u7trZtPNDADAzBwRERHdERERCwAAAAAAAAAAAAAAvLu7u7u7u7u7ZtPdvADMM7MRERHRHRERCwAAAAAAAAAAAAAAvLv/u7u7u7u7ZtPdvcszw8wRERERHRERCwAAAAAAAAAAAAAAvLv/u7u7u7trZtPdvcszM7MRERHRHRERCwAAAAAAAAAAAAAAvLu7u7u7u7trNtPd3cszw8wRERHdERERCwAAAAAAAAAAAAAAwLu7u7u7u7trNt3d3c0zM8MREREdERERCwAAAAAAAAAAAAAAwLy7u7u7u7tr1t3d3d08w8wREdEdERERuwAAAAAAAAAAAAAAAMy8u7u7u7tm1t3d3d3NMxsREd0RERERsQAAAAAAAAAAAAAAAADMu7u7a2Zm093d3d29zBER0R0RERERsQAAAAAAAAAAAAAAAADAvLu7a2Y23d3d3d3NzBwR3RERERERsQAAAAAAAAAAAAAAAAAAvLtmZjPd3d3d3b3MM7PRHRERERERsQAAAAAAAAAAAAAAAAAAzGZmNtPd3d3dvcszw8zdERERERERsQAAAAAAAAAAAAAAAAAAwMw7M93d3d3du80zM7MdERERERERsQAAAAAAAAAAAAAAAAAAwN29293d3d3du80zw8wRERERERERsQAAAAAAAAAAAAAAAAAA3N29293d3d3du80zM8MRERER3d3dvQAAAAAAAAAAAAAAAAAA3N27u9vd3d3du908w8wR3d3d3d27uwAAAAAAAAAAAAAAAADA3b3b3d3MzNzd3d3NM9vd3b27u7sAAAAAAAAAAAAAAAAAAADA3b3b3d0MAMDM3d3dzLu7uwsAAAAAAAAAAAAAAAAAAMzMDADM3b3du8sMAADAzN3d3b3MAAAAAAAAAAAAAAAAAAAAwN29y8zb3b3b3bsMAAAAzN3dzLsMAAAAAAAAAAAAAAAAAAAA3N3d3d3d3d3b3b0MAAAAwN3dzcwMAAAAAAAAAAAAAAAAAADA3d3d3d3d3b3b3d0MAAAAwN3du8wAAAAAAAAAAAAAAAAAAADc3d3d3d3du7vbvd0MAAAAwN3MuwwAAAAAAAAAAAAAAAAAAMDc3d3d3d3du93dvdsMAAAAwLvMzAAAAAAAAAAAAAAAAAAAAMDd3d3d3d3d293d3bsMAAAAwLwMAAAAAAAAAAAAAAAAAAAAAMzd3d3du9u929273b0MAAAAAMwMAAAAAAAAAAAAAAAAAAAAANzdu93du7u73d3d280AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwNu9u9u9293d3d3dvQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzLu73bu73d3d3d273QwAAAAAAAAAAAAAAAAAAAAAAAAAAADA3N3d3d3d3d3dvd292wwAAAAAAAAAAAAAAAAAAAAAAAAAAMDM3d3d3d3d3d3d3dvdywwAAAAAAAAAAAAAAAAAAAAAAAAAwMzd3dvd3d3d3d293b3dywAAAAAAAAAAAAAAAAAAAAAAAADAzN3dvdvd3d3d3d293b3bzAAAAAAAAAAAAAAAAAAAAAAAAADM3d3du93d3d3d3dvd273MDAAAAAAAAAAAAAAAAAAAAAAAAADMzLy73d3bvd3b3bvd28wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzc3b3dvd3b3bvdywAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDMvNvd293b3bvNDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwN293c3czczMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMzMzQzczAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADMzADMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.pigeonIcon":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"animals","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAALwPAAAAAAAAAAAAAAAAAAC8DwDAzMwAAAAAAAAAAADAvQ/wz93dzAAAAAAAAAAAwN3//2bT3c0MAAAAAAAAALzbvbtr1t3dzMwAAAAAAAC8u7u7uzbd3c0zAAAAAAAAvLu7u7s23d3NMwAAAAAAALz7v7u7Nt3dvcMAAAAAAAC8+7+7uzbd3d3LAAAAAAAAwLu7u2vW3d3dOwAAAAAAAAD/v7tms7vdzTMAAAAAAAAAAP+/Zt29283DAAAAAAAAAAAA/9Pd3bu9wwAAAAAAAAAAAPDd3d293TwAAAAAAAAAAADw3d3du937AAAAAAAAAAAAANzdvbvd+wAAAAAAAAAAAADc3bvN3f8AAAAAAAAAAAAAwL3bzb0PAAAAAAAAAAAAAADM3c29DwAAAAAAAAAAAAAAwN3N+wAAAAAAAAAAAAAAAAC8y/wAAAAAAAAAAAAAAAAAwLv8AAAAAAAAAAAAAAAAAAC8DwAAAAAAAAAAAAAAAAAAvA8AAAAAAAAAAAAAAAAAAMwPAAAAAAAAAAAAAAAAAADADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.skillmap.pigeon_icon"},"sprites.skillmap.potion0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwuwsAAAAAAADADAC7u8sAAAAAAADL/Lu7u8sAAAAAAADL/L+7u8sAAAAAAADADAC7u8sAAAAAAAAAAACwuwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABARAAAAAAAAAAAAABERAQAAAAAAADgAEBEROQAAAAAAADkAEREROQAAAAAAADuTEREROQAAAAAAADuzEREROQAAAAAAADuAEREROQAAAAAAADgAEBEROQAAAAAAAAAAABERAQAAAAAAAAAAABARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDd3Q0AAAAAAABd0N3d3d0EAAAAAABd1N3d3d0EAAAAAABV1N3d3d0EAAAAAABV0N3d3d0EAAAAAAAAANDd3Q0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3AJmZmQkAAAAAAAB5lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3lpmZmXkAAAAAAAB3AJmZmQkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion4":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAPgAAAAAAAAACJmZmfgAAAAAAAAA+JmZmfgAAAAAAACI+JmZmfgAAAAAAACI+JmZmfgAAAAAAACI+JmZmfgAAAAAAAAA+JmZmfgAAAAAAAAACJmZmfgAAAAAAAAACAAAAPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion5":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwzAwAAAAAAADADAC7zMwAAAAAAADL/Lu7zPwAAAAAAADL/L+7zPwAAAAAAADADAC7zPwAAAAAAAAAAACwzA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion6":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA7gAAAAAAAAAAAABE7g4AAAAAAADgAEBE7u4AAAAAAADkAERE7s4AAAAAAADuTERE7s4AAAAAAADuzERE7s4AAAAAAADuAERE7s4AAAAAAADgAEBE7swAAAAAAAAAAABEzgwAAAAAAAAAAABAzgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion7":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANDdVQUAAAAAAABd0N3dVVUEAAAAAABd1N3dVVUEAAAAAABV1N3dVVUEAAAAAABV0N3dVVUEAAAAAAAAANDdVQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion8":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3AJl5dwcAAAAAAAB5lpl5d3cAAAAAAAB3lpl5d2cAAAAAAAB3lpl5d2cAAAAAAAB3lpl5d2cAAAAAAAB3lpl5d2cAAAAAAAB3lpl5d2cAAAAAAAB3lpl5d2cAAAAAAAB3lpl5d2cAAAAAAAB3AJl5ZwYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion9":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAPgAAAAAAAAACJmZiPgAAAAAAAAA+JmZiPgAAAAAAACI+JmZiPgAAAAAAACI+JmZiPgAAAAAAACI+JmZiPgAAAAAAAAA+JmZiPgAAAAAAAAACJmZiPgAAAAAAAAACAAAAPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion10":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAzAwAAAAAAADADAC8y8wAAAAAAADL/My8zPwAAAAAAADL/M/MzPwAAAAAAADADADMzPwAAAAAAAAAAADAzA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion11":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADg7gAAAAAAAAAAAADu7g4AAAAAAADgAOBO7u4AAAAAAADkAO7k7s4AAAAAAADu7E7u7s4AAAAAAADuzO7u7s4AAAAAAADuAO7u7s4AAAAAAADgAODu7swAAAAAAAAAAADuzgwAAAAAAAAAAADgzgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion12":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBdVQUAAAAAAABdUNVVVVUEAAAAAABdVF1VVVUEAAAAAABVVFVVVVUEAAAAAABVUFVVVVUEAAAAAAAAAFBVVQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion13":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3AHd3dwcAAAAAAAB5dpd5d3cAAAAAAAB3dnl3d2cAAAAAAAB3dnd3d2cAAAAAAAB3dnd3d2cAAAAAAAB3dnd3d2cAAAAAAAB3dnd3d2cAAAAAAAB3dnd3d2cAAAAAAAB3dnd3d2cAAAAAAAB3AHd3ZwYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.potion14":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAPgAAAAAAAAACIiIiPgAAAAAAAAA+JiJiPgAAAAAAACI+JiIiPgAAAAAAACI+IiIiPgAAAAAAACI+IiIiPgAAAAAAAAA+IiIiPgAAAAAAAAACIiIiPgAAAAAAAAACAAAAPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}},"sprites.skillmap.seasonalTree0":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAPAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAPAADwDwAAAAAAAAAAAAAACAAACAAAAAAAAAAA8AAAiP8AAAgAAAAAAAAAAIAA8PD4AAAIAAAAAAAAAAD4AAAAj/8ACAAAAAAAAAAADwAAAPD4APgAAAAAAAAAAA8AAAAA+A+PAAAAAAAAAPAIAAAAAPAP8AgAAAAAAACADwAAAADw+PAPAAAAAAAAgPDwCP8PAP+PDwAAAAAAAPAPAI+I+A/wjw8AAAAAAACPDwAAAP/////4AAAAAACAiA8AAAAA////iPgAAADwiP8AAPj/AAD//4+IiIiIiIgPAAAAAIgP8P//j4iIiPj//w8AAP+A+A/////////////4AP8AAP//j///////////DwAAAAAAiP///////////wAAAADwiPj/+P8PAAAA8P8PAADwiP8P8PgPAAAAAADw/wAA/wgAAP//AAAAAAAA8PAA8A8AAPD4AAAAAAAAAAD/APAAAAD/DwAAAAAAAAAADwDw8ACA+AAAAAAAAAAAAPAAD/CPj/8AAAAAAAAAAADwAA8A8P8PAAAAAAAAAAAA8AAAAADwAAAAAAAAAAAAAPAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="},"pyQName":"sprites.skillmap.seasonal_tree0"},"sprites.skillmap.seasonalTree1":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAHUAAAAAUAUAAAAAAAAAAADlUAdQVQUAAAAAAAAAAFAFUAd3V3UFVQAAAAAAAAAAAEd3d1d3d1UHAAAAAAAAUHVVZwdVB3dXAAAAAAAA4Fd3R1UGd3d3AHB1AAAAAOBVV3B3d3V3d3BwBwAAAADgUAB3V3RVfndwBwAAAAAADlB1dXd1V35wdwcAAAAAAA4AdnZ3dwd3B3cHAAAAAOAOUFV3d3Z3dncHBwAAAADgDnd3dndXV3d1d3cHAAAA4OB1dHdXdmV3d3cABwAAAEQEd2dndXd1d3cHVwAAAABEDnBgV3Z3d2Z3d1cAAABA5A5Qd1d2d3d3d1d3BgDgTu4AAGZndnd3d3dndkZERO4OAAB2d3Z2d2Z2d+fm5u7u7g51d3d3d3d3d2Z25+7u7s7sV2d3ZnZ353d3ZubuzszsDlB3Z2dWZWZmxmXnxuzOzAAAZ3d2d3d3d8dXAAAA4MwMd3ZmZXd3d2dnB2AAAADA7AB2Z3Z2d3Z2ZnYHAAAA4OwAZ2x2V3dndncHAAAAAMDucHd3d3d3dmdmBwYAAAAADHBld2d3V2Z2dgcAAAAAAMBQfmZnZ2d3d3dmAAAAAADAd3d2dnZmBmdgZwAAAAAA4Ad3d2fHBwdndmcAAAAAAOAAdwBnZmcHAGYGAAAAAAAAAABwAHdnAAYAAAAAAAAAAA=="},"pyQName":"sprites.skillmap.seasonal_tree1"},"sprites.skillmap.seasonalTree2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAHkAAHAAkAkAAAAAAAAAAADpkAeQmQkAAAAAAAAAAJAJkAd3kzkDmQAAAAAAAAAAE0czN5cXc5kHAAAAAAAAkDOZEzeZN3eXAAAAAAAA4Jd3R5kGd3dzAHB5AAAAAOCZl3B3d3l3d3BwBwAAAADgkAB3l3SZfndwBwAAAAAADpB5c3dzl35wNwEAAAAAAA4ANnFzdwd3B3cDAAAAAOAOkDk3d3Z3dncHBwAAAADgDnd3NneXlzN5c3cHAAAA4OB5dHeXdmkTd3cABwAAAEQEdzdnmXd5c3cHlwkAAABEDnAQlxZzd2Z3d5cJAABA5A6Qd5d2d3d3d5d3BgDgTu4AAGZndnd3d3djdkZERO4OAAB2d3Z2d2Y2Mefm5u7u7g55d3d3F3N3d2Z25+7u7s7sl2dzZjZ353d3ZubuzszsDpA3YWeWaWZmw2nnxuzOzAAAZ3d2d3d3N8GXAAAA4MwMd3ZmaTdzd2dnA2AAAADA7AB2Z3Y2d3Z2ZnEHAAAA4OwAZ2x2F3dndncHAAAAAMDucHd3dzN3dmdmBwYAAAAADHBpd2d3l2Z2NgcAAAAAAMCQPmFnZ5N3dxdjAAAAAADAdzdzdnZhBmdgZwAAAAAA4Ad3d2fHBwdndmcAAAAAAOAAdwBnZmcHAGYGAAAAAAAAAABwAHdnAAYAAAAAAAAAAA=="},"pyQName":"sprites.skillmap.seasonal_tree2"},"sprites.skillmap.seasonalTree3":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"forest","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAOAAAHAAAAAAAAAAAAAAAABFBABARFAFAAAAAAAAAABE1VAFRFVFRAAAAAAAAABABVAFRFRFBUUAAAAAAAAAQAAHVVRFRERVBAAAAAAA4EREVWUFRQREVAQAAAAAAOBER+VVBkTeQAB0dQAAAADgVUREVEQFRARCRAcAAAAADlBEVUVcRE4kQgQAAAAAAA5QRAVVVEXeQEQCAAAAAOAOQERWVUAFIAREIgIAAADgDlRAVQRA5SYiIiQiAAAA4ODkRVZUREQkQiJEIgIAAN0EBU5UVERlJCREAiQCAADdDkVlREUiRSTUDVQiAgDQ7Q5AQCdCJEQm3t1UAgLg3u0AUCUiIkIkIi7SRCLS3e4OAAAiAEIiQiQiZEbu7u7u7g4AIkRGJiJmTkTuLubu7s7sRSJERCIkRM5iRu7uzszsDlRiAmYmRORCRG7uzuzOzABQQgQkUmVmJuLu7g4A4MwMAO7uIiIiIiLiAg4AAADA7AAuIiIiIiLi4uDgAAAA4OzucCcmJiIm5u7u4AAAAMDuDmIsJtIiYibi7g4AAAAADC4iIiItIiZu5g4GAAAAAMDuZeJiwlJm4u7iDgAAAADAUA7mYGJiLuIuIg4AAAAA4CIiJu5y4gIiIu4OAAAAAOAC4u7uIuIO7uLuAAAAAAAAAOIA4uZuB+4uBgAAAAAAAA=="},"pyQName":"sprites.skillmap.seasonal_tree3"},"sprites.skillmap.stageIcon":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQgACAAAAAAAAAAAAAAAAAAAADuzswAAAAA////AADuDgDuLr7LDAAA8O8i8v//4vL/LiK+y8wAAP/u7iLvLuLyIi7ivsvMAPDv7uIu7y4u4i4uIr7LzAD/7u4uLu7uIvIuLuK+y8zw7+7uLv7uLiLy/y8ivsvM/+7u7i7+LiIu/v//Lr7LzO/u7u7i/y7iIv///++7y8zv7u7u/u/uLvL//7+7u8vM7+7u7iL+L+L//++7vbvLzO/u7u4i4v///+/u2927y8zv7u7u7iL+/+/u7tvdu8vM7+7u7uIu8u/u7u7d3b3LzO/u7u4uLuLu7u7u3d29y8zv7u7uLi7i7u7u7t3dvcvM7+7u7i4u4u7u7u7d3b3LzO/u7u4uLuLu7u7u3d29y8zv7u7u4i7y7+7u7t3dvcvM7+7u7u4i/v/v7u7b3bvLzO/u7u4i4v///+/u2927y8zv7u7uIv4v4v//77u9u8vM7+7u7v7v7i7y//+/u7vLzO/u7u7i/y7iIv///++7y8z/7u7uLv4uIi7+//8uvsvM8O/u7i7+7i4i8v8vIr7LzAD/7u4uLu7uIvIuLuK+y8wA8O/u4i7vLi7iLi4ivsvMAAD/7u4i7y7i8iIu4r7LzAAA8O8i8v/v4vL/LiK+y8wAAAD///8AAO4OAO4uvssMAAAAAAAAAAAAAAAA7s7MAA=="},"pyQName":"sprites.skillmap.stage_icon"},"sprites.skillmap.writer":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQ/ADcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA293d3d3d3d0NAAAAAAAAAAAAAAAAAAAAAAAAANvd3d3d3d3dDQAAAAAAAAAAAAAAAAAAAAAAAADb3d3d3d3d3Q0AAAAAAAAAAAAAAAAAAAAAAAAA293d3d3d3d0NAAAAAAAAAAAAAAAAAAAAAAAAANvd3d3d3d3dDQAAAAAAAAAAAAAAAAAAAAAAAADb3d3d3d3d3Q0AAAAAAAAAAAAAAAAAAAAAAMzM3N3d3d3d3d0NAAAAAAAAAAAAAAAAAAAAAMzMzMzd3d3d3d3dDQAAAAAAAAAAAAAAAAAAAMAcERHB3N3d3d3d3Q0AAAAAAAAAAAAAAAAAAADMEREREdzd3d3d3d0NAAAAAAAAAAAAAAAAAADAHBGxuxHB3b273d3dDQAAAAAAAAAAAAAAAAAAzB0RsRsRwd29sd3d3Q0AAAAAAAAAAAAAAAAAwBwdEbsREcHcGxHb3d0NAAAAAAAAAAAAAAAAAMwR0REbEbG7zBsR293dDQAAAAAAAAAAAAAAAMwcERHdG7EbEcwREbHd3Q0AAAAAAAAAAAAAAMAcERER0Ru7ERHBERGx3d0NAAAAAAAAAAAAAADMERERERG7GxERERwREdvdDQAAAAAAAAAAAAAAHBERERHRvRsRERHMERHb3Q0AAAAAAAAAAAAAwBwRERER3b0bERERwRERsd0NAAAAAAAAAAAAAMAdEUFERNTdvBEREcEREbHdDQAAAADAzMzMAADM3R1BVVVFRMS7ERHBERER2w0AAADMzMzMzMzMHBHdTUREVVVVvBsRwREREdsNAADMzBERERGxuxsRERERQURERBS7EcwRERGxDQDAHBERERERERG7EREREREREREcscscERERsQ0AzBERERERERsRsRsRERERERERzMHMEREREbENwBwREREREREcERG7EREREREREcHMERERERHbDcARERERERERzBwRsRERERERERGxvRERERGx3Q3MEREREREREcwcEbEbERERERERsb0RERER290NHBERERERERHMERERGxEREREREbHdGxERsd3dDRwRERERERERERERERsRERERERGx3RsREdvd3Q0cERERERERERERsRHbHRERERERsd0bEbHd3d0NHBEREREREREREREbGx0REREREbHdvRHb3d3dDRwRERERERERERERGxvRERERERGx3b2x3d3d3Q0cERERERERERERERsb0RERERERsdu9293d3d0NHBERERERERsREREbG9ERERERERHb3d3d3d3dDRwREREREREcERGxERvRERERERER293d3d3d3Q3MERERERERzByxG7G7u7sREREREdvd3d3d3d0NwBEREREREcwcERGxuxuxGxERERHb3d3d3d3dDcAcERERERHMERERG7ERERsRERER293d3d3d3Q0AzBERERERERERzBERuxGxGxEREdvd3d3d3d0NAMAcERERERERwRwREbEREbsRERHb3d3d3d3dDQAAzBwREREREcERERGxERGxGxER293d3d3d3Q0AAADMzBwREcHMEbG7sREREbsdEdvd3d3d3d0NAAAAAMDMzMzMzBGxuxsRERGx293b3d3d3d3dDQAAAAAAAAAAAMAcEREREREREczd293d3d3d3Q0AAAAAAAAAAAAAzBEREbsRERHB3Nvd3d3d3d0NAAAAAAAAAAAAAMAcsbu7GxEREczc3d3d3d3dDQAAAAAAAAAAAAAAzLsREbsRERHB3N3d3d3d3Q0AAAAAAAAAAAAAAMwRERGxGxEREczd3d3d3d0NAAAAAAAAAAAAAAAcEREREbsRERHB3N3d3d3dDQAAAAAAAAAAAAAAzBERERGxERERwdzd3d3d3Q0AAAAAAAAAAAAAAMAcERER0RsRERHc3d3d3d0NAAAAAAAAAAAAAAAAzBEREdEdERER3N3d3d3dDQAAAAAAAAAAAAAAAMDMHBHRHREREdzd3d3d3Q0AAAAAAAAAAAAAAAAAAMwcER0REcHc3d3d3d0NAAAAAAAAAAAAAAAAAAAAzMzRERHM3d3d3d3dDQAAAAAAAAAAAAAAAAAAAADAzBzBvN3d3d3d3Q0AAAAAAAAAAAAAAAAAAAAAAMDMzLDd3d3d3d0NAAAAAAAAAAAAAAAAAAAAAAAAAACw3d3d3d3dDQAAAAAAAAAAAAAAAAAAAAAAAAAAsN3d3d3d3Q0AAAAAAAAAAAAAAAAAAAAAAAAAALDd3d3d3d0NAAAAAAAAAAAAAAAAAAAAAAAAAACw3d3d3d3dDQAAAAAAAAAAAAAAAAAAAAAAAAAAsN3d3d3d3Q0="}},"storySprites":{"kind":5,"retType":""},"storySprites.mistletoe":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"misc","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwQbABgAAAAAAAAAAAAAzAAAAAAAAAAAAAfAzHzMDgAAAAAAcMfAzHzsDgAAAAAAcMfMzMzsDgAAAAAAd8zMzMwMAAAAAAAAfMzMzMzMAAAAAADAIs7MzMzMAAAAAAAg3SLMzO4AAAAAAAAgJCLM7A4AAAAAAAAgIuLM7A4AAAAAAAAAIsLsDgAAAAAAAAAAzNLifgfMAAAAAMwi7NMid8fMAADAx94jLiIizMzMzABwdzIkIiIizMzMzAB3xy4iwiLCzMzMzAB3zCzizOzOzMzMzAzMzMzMzOzOzMzMzAzMzMzM7M7u7szMzAwAzMzM7A7g7s7u7szAzMzM7A4AAOzu7szAzMzM7A4AAAAAAADAzMzMzM4AAAAAAAAAzMzM7M4AAAAAAAAAAMzM7A4AAAAAAAAAAADA7AAAAAAAAAAAAAAAzAAAAAAAAAA="}},"storySprites.halloween":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAAD//////////////////////////////////////////////////////////4iYiYiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iYiYiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iYiYiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iYiYiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iYhoiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iYhoiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iYhoiIiIiIiIiIiIiIiIj/////////////////////////////////X/X//////////////////////4iWhoiIiIiIiIiIiIiIiIj/////////////////////////////////X/Vf9f///////////////////4iWhoiIiIiIiIiIiIiIiIj///////////////////////////////9fVVVV/////////////////////4ibiIiIiIiIiIiIiIiIiIj/////////////////////////////////VVX1/////////////////////4iZiIiIiIiIiIiIiIiIiIj/////////////////////////////////X1X1/////////////////////4iZiIiIiIiIiIiIiIiIiIj/////////////////////////////////Xl9V/////////////////////4iZiIiIiIiIiIiIiIiIiIj////////////////////////////////////l/////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iZiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4hoiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iIiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iIiIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////////////////4iIiIiIiIiIiIiIiIiIiIj///////////////////////////////////////////////////9ERERERMSIiIiIiIiIiIiIiIiIiIj/////////////////////////////////////////////////REREREREREREiIiIiIiIiIiIiIiIiIj///////////////////////////////////////////////9ERERERERERERERIiIiIiIiIiIiIiIiIj//////////////////////////////////////////////05ERERERERERERERESIiIiIiIiIiIiIiIj/////////////////////////////////////////////T0REREREREREROTu7k6EiIiIiIiIiIiIiIj///////////////////////////////////////////9PRERERERERETu7u7u7u7ujIiIiIiIiIiIiIj///////////////////////////////////////////9ERERERERE5O7u7kREROTu7oiIiIiIiIiIiIj//////////////////////////////////////////09ERERERETu7u5ERERERERE5I6IiIiIiIiIiIj//////////////////////////////////////////0RERERERO7uTkRERERERERERISIiIiIiIiIiIj/////////////////////////////////////////T0RERERE7u5ERERERERERERERISIiIiIiIiIiIj/////////////////////////////////////////RERERETu7kRERERERERERERERESIiIiIiIiIiIj/////////////////////////////////////////RERERO7uRERERERERERERERERESEiIiIiIiIiIj///////////////////////////////////////9PRERE5O5ERERERERERERERERERESEiIiIiIiIiIj///////////////////////////////////////9ORERE7k5ERERERERERERERERERETkiIiIiIiIiIj///////////////////////////////////////9ERETkTkREREREREREREREREREREREiIiIiIiIiIj///////////////////////////////////////9ERETuREREREREREREREREREREREREiIiIiIiIiIj//////////////////////////////////////09EROROREREREREREREREREREREREREjoiIiIiIiIj//////////////////////////////////////09ERO5EREREREREREREREREREREREREhIiIiIiIiIj//////////////////////////////////////05E5E5EREREREREREREREREREREREREhI+IiIiIiIj/////////////////////////////////////7+VE7k5ERERERERERERERERERERERERE9P+IiIiIiIj/////////////////////////////////////7+Xu7kRERERERERERERERETu7u7u7u5E5P+IiIiIiIj/////////////////////////////////////70XuTkRERERERFRERERE7u7u7k7k7u7u7v+IiIiIiIj/////////////////////////////////////T+TuREREREREFFVFRO7u7lVFRERERETu7v+MiIiIiIj/////////////////////////////////////T+TuRERERETUEVXk7u5ORBFVRERERERE5P+PiIiIiIj/////////////////////////////////////T+TuREREREQRUeXu7kRERB1RRURERERE5P+PiIiIiIj/////////////////////////////////////TuTuTkRERBQRVeVORERERBRRVUVERERE5P+PiIiIiIj/////////////////////////////////////RO7kTkRERB5RVUVEREREREQRVVVERERE5P/PiIiIiIj/////////////////////////////////////RO5E7kRE7t7dVVVEREREREQdVVVFRERE5P7/iIiIiIj/////////////////////////////////////5E5E5E7u7k7dXVVNREREREQUUVVVRERE5P7/iIiIiIj////////////////////////////////////P7k5E5O7uRETU3d1NRERERETUUVVVRURE5P7PiIiIiIj////////////////////////////////////P7ERE7u5ERERE1N1NRERERERERFXVvURE5P7/iIiIiIj////////////////////////////////vVf/M7ETu7u5EREREREREREREVEVERFXV3URE5P7/iIiIiIj///////////////////////////////9fVfXMTOTuRO5EREREREREREQU0U1ERFXVRERE5P7/iIiIiIj///////////////////////////////9ex8zMzO5ORO5ERERERERERBQR3U1EVFXVRERE5P7/iIiIiIj///////////////////////////////9VzMzMzE5ERO5ERERERERERBFR1U1EVFVRRERE5P7/iIiIiIj//////////////////////////////+91zMzM7ERERO5ERERERERERBFV1U1EVFURXURE5P7/iIiIiIj//////////////////////////////1/FzMzMzERE5E5ERERERERERN1d1U1EVFURXURE5P7/iIiIiIj//////////////////////////////1/FzMzM7k5E5E5ERERERERERNTd3U1EFFXRTURE5P7/iIiIiIj//////////////////////////////1XMzMzM7O5O5E5ERERERERERETU3U1EFFXVTURE5P7/iIiIiIj//////////////////////////////3zMzMzMzO7u7kRERERENFRFRERE1E1EFFXVS0RE5P7/iIiIiIj//////////////////////////////8/MzMzM7kTu7k5EREREEVVERERERERERFXV3URE5P7/iIiIiIj//////////////////////////////8/8/8/M7E5E5O5OREQdUVVFRERERERERFXVvURE5P7/iIiIiIj//////////////////////////////8/8///P7O5E5O7u7tQRVVVFRERERERERFXdRERE5P7/iIiIiIj//////////////////////////////8z//P//zO5E5E7k7h5RVURERERERERUVd1NRERE5P//iIiIiIj//+///////////////////////////8///P//T+Tu5E5ERN5dVe5ERERERERV3d1ERERE5P//iIiIiIj//1X////////////////////////////P/Mz/70TuTk5ERETdVeTu7kRERETU3U1ERETk7v//iIiIiIj//1VU9f///////////////////////////8z//0Tk7k5ERETbXVXu7u7u7t7d7e7u7u7u7v//iIiIiIj/X1VV/v//////////////////////////////70Tk7k5ERES03V1NROTu7t297u7u7u5O7v//iIiIiIj//1VV/v///////////////////////////////0RE7u5ERERE1N1NRERE1N1ERERERERE7v//iIiIiIj//1Vf9f///////////////////////////////05E7u5ORERERNRLRERERERERERERERE/v//iIiIiIj//////////////////////////////////////+7kTuTuRERERERERERERERERERERETk/v/PiIiIiIj//////////////////////////////////////+/uTkTk7kRERERERERERERERERERETk/v/PiIiIiIj////////////////////////////////////////uRERE7u5ERERERERERERERERERETk/v+PiIiIiIj///////////////////////////////////////9ERERERO7uRERERERERERERERERETu//+PiIiIiIj///////////////////////////////////////9PRERERETu7kRERERERERERERERETu//+PiIiIiIj///////////////////////////////////////9PRERERERE7u5OREREREREREREROTu//+PiIiIiIj///////////////////////////////////////9PRERERERERO7uTkREREREREREROT+//+PiIiIiIj/////////////////////////////////////////RERERERERETk7u5ORERERERERO7+//+PiIiIiIj/////////////////////////////////////////RERERERERERE5O7u7kRERETk7u7///+PiIiIiIj/////////////////////////////////////////T0RERERERERERETk7u7u7u7u7u7///+PiIiIiIj/////////////////////////////////////////T0RERERERERERERERETu7u5O7v7///+PiIiIiIj//////////////////////////////////////////0RERERERERERERERERERETk7v////+PiIiIiIj//////////////////////////////////////////09ERERERERERERERERERETkzv////+PiIiIiIj///////////////////////////////////////////9ERERERERERERERERERETu/v////+PiIiIiIj/////////////////////////////////////////////REREREREREREREREROTu//////+PiIiIiIj/////////////////////////////////////////////70RERERERERERERE5O7+//////+MiIiIiIj//////////////////////////////////////////////+9ERERERERERETk7u7///////+IiIiIiIj///////////////////////////////////////////////9PRERERERERO7u7o7///////+IiIiIiIj/////////////////////////////////////////////////TkRERERE7u7u7oz///////+IiIiIaIn/////////////////////////////////////////////////7+7u7u7u7u7ujIj///////+IiIiImIn////////////////////////////////////////////////////v7u7u7s6IiIj4//////+IiIiImIn/////////////////////////////////////////////////////////z4iIiIj4//////+IiIiImIn/////////////////////////////////////////////////////////z4iIiIj4/////4+IiIiImIn/////////////////////////////////////////////////////////z4iIiIjI/////4+IiIiImIn/////////////////////////////////////////////////////////z4iIiIiI+P//z4iIiIiImIn/////////////////////////////////////////////////////////z4iIiIiI+P//j4iIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiPz/iIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiPiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////z4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////X/Vf////////////////////j4iIiIiIiIiIiIiIiIiImIn/////////////////////////////////X/VV////////////////////j4iIiIiIiIiIiIiIiIiImIb/////////////////////////////////VFVV////////////////////j4iIiIiIiIiIiIiIiIiImIb///////////////////////////////9fVVX1////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////X1X1////////////////////j4iIiIiIiIiIiIiIiIiImIb/////////////////////////////////X/RV////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////T/9e////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIlob/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIm4j/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImYj/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImYj/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImYj/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiImYj/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIiIj/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIiIj/////////////////////////////////////////////////////////j4iIiIiIiIiIiIiIiIiIiIg="}},"storySprites.holiday":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAACZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmeuZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmembmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnrmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ7p7umZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme7umZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnunpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme6ZmZmZmZmZmZmZGRERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmRkREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmenumZmZmZmZGREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnumZmZmZmZERERERERERGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnrnpmZmZmZERERERERERERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn/mZmZmZmZmZmZmZnp7hEREZkZGxEREREREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn/n5mZ/J+ZmZmZmZkZ7u4REREeuxEREREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn//5mZv/uZmZmZ6e4R4R4RMe7i7hERERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmf///7/5v/uZmZmZIuIeERER7iIiuxERERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ+f+7///y//8RERGxIiLiERHhLiIishsRERERERERERGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ+f+7+/8u//8RERQhIiIiHu4uIiIisRsRERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ+f+/u/wv//8RERQRIiIi4iIiIiIishsRERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ////u/sv/x8RERQfsSIiIiIiIiISsbsRERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ//////8v/x/xTxQRESviLiIiIiIiErERERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8v/x/xTxTxEe4i4i4iIu7u7rERERERERERERGBiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8v/x8RQRQRESIiIi7i7h4REbERERERERERERFhiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8v/x8RQRTxESIiIhIREREREbEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8i/x8RERERESIiIuIe/xHxHLEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5///////y/x/xHBHxEe4iIi7u7i4dEbEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ/////y/y/x/xHxEREeLu7i4iIuLu7i4SERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSL//xEREREfESIiIiIiIiIiErEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn//xERERERISIi4iIiIiIiIiIiERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn/nxERERERIiIi7iIiIiIiIuIRERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn/mZkREZEiIiLi7e7u7u4iIrIRERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkiIiIeEREREeEuIiISERERERERERGGiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkpIh4RvhERERHh7u4RERERERERERGIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR7h4RERERGxEREREREREREYGIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ7hEREZG7HREREREREREREYiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnpnhERmZm7EREREREREREREYiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnunpmZmZmZERERERERERERgYiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnumZmZmZmZGRERERERERERiIiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmRERERERERGBiIiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmZkREREREZGJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme6ZmZmZmZmZmZmZmZmZmZmJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme6ZmZmZmZmZmZmZmZmZmZmJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZmZmZmZmZmZmZmZmZmZmJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZyZmZmZmZmZmZmZmZmZmZmJiIiImJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnp7pmZmZmZmZmZmZmZmZmZmZmJiIiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnu7pmZmZmZmZmZmZmZmZmZmZmZiIiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmemenpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmemZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZuZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiIiIiIiImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmIiIiIiIiZmZmZiIiIiIiImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmIiIiIiIiZmZmZmZmZiIiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJiJmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiYiZmZmZmZmJmYmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmZiYmZmZmZmZmZiIiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiZiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYaZiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmWmIiIiZmZmZiIiIiIiImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmIiIiIiIiYmYiZiIiImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmYmYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmZmYiZmZmZmZmZmYiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmYaZiZmZmZmZmZiYiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmIiJmZmZmZmZmZiJmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJmZmZmZmZmZmJmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiJmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiIiIiIiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmIiIiIiIiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmYmYmZmZmZmZmZmYmImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmZmYiZmZmZmZmJmYmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYmYmZiZmZmZmZmYmYmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmIhpmZmZmZmZmImYmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJmZmZmZmZmJiIiImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmGlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYiYmZmZmZmYmZmZiJmZmZmZmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmZmZmYmZmZiZiZmZmJyJyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJmZmYmYmZmZmYiIiIiYzMzH7JmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiIiIiIiZmZmZiZiZmXeczMzH7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJmZmZmZmZmJiJmZmXfMzMzM7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmImZmZmZmZmZmImZmZecfMzMzMm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYaYmZmZmZmZmZmZmZmZycfMzMzMlpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZiJiJK+LMzMzMnJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJiJ0i3CzOyemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJiZQiLCzO6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmZiJIiLOzO6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmJmJiJ6CLM7puZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmIiIySwt7nfJnJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmWkszj4tcnfMnJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZfOw94iIiwszMzJyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZdydDIiIiwszMzJyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5d+YiIiwizMzMzJyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZl5x8wizsbuzMzMzLyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnJzMzMzMzuzMzMzMyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnJzMzMzO687s7MzMyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyczMzO6Z7u7s7s6cmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZy8zMzO6ZmWnu7s6cmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZzMzMzO6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZzMzMzOycmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyczMzO6cmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmbnMzO6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZzL6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZyZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZk="}},"storySprites.holiday2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAACZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmeuZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmembmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnrmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ7p7umZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme7umZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnunpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme6ZmZmZmZmZmZmZGRERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmRkREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmenumZmZmZmZGREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnumZmZmZmZERERERERERGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnrnpmZmZmZERERERERERERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn/mZmZmZmZmZmZmZnp7hEREZkZGxEREREREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn/n5mZ/J+ZmZmZmZkZ7u4REREeuxEREREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn//5mZv/uZmZmZ6e4R4R4RMe7i7hERERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmf///7/5v/uZmZmZIuIeERER7iIiuxERERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ+f+7///y//8RERGxIiLiERHhLiIishsRERERERERERGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ+f+7+/8u//8RERQhIiIiHu4uIiIisRsRERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ+f+/u/wv//8RERQRIiIi4iIiIiIishsRERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ////u/sv/x8RERQfsSIiIiIiIiISsbsRERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ//////8v/x/xTxQRESviLiIiIiIiErERERERERERERGBmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8v/x/xTxTxEe4i4i4iIu7u7rERERERERERERGBiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8v/x8RQRQRESIiIi7i7h4REbERERERERERERFhiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8v/x8RQRTxESIiIhIREREREbEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5//////8i/x8RERERESIiIuIe/xHxHLEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn5///////y/x/xHBHxEe4iIi7u7i4dEbEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ/////y/y/x/xHxEREeLu7i4iIuLu7i4SERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSL//xEREREfESIiIiIiIiIiErEbERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn//xERERERISIi4iIiIiIiIiIiERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmfn/nxERERERIiIi7iIiIiIiIuIRERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZn/mZkREZEiIiLi7e7u7u4iIrIRERERERERERGBiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkiIiIeEREREeEuIiISERERERERERGGiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkpIh4RvhERERHh7u4RERERERERERGIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR7h4RERERGxEREREREREREYGIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ7hEREZG7HREREREREREREYiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnpnhERmZm7EREREREREREREYiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnunpmZmZmZERERERERERERgYiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnumZmZmZmZGRERERERERERiIiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmRERERERERGBiIiIiJiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmememZmZmZmZmZkREREREZGJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme6ZmZmZmZmZmZmZmZmZmZmJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZme6ZmZmZmZmZmZmZmZmZmZmJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZmZmZmZmZmZmZmZmZmZmJiIiIiJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZyZmZmZmZmZmZmZmZmZmZmJiIiImJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnp7pmZmZmZmZmZmZmZmZmZmZmJiIiYmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnu7pmZmZmZmZmZmZmZmZmZmZmZiIiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmemenpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmemZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ6ZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZuZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZk="}},"storySprites.birthday":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAAB3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIid3d3d3d3d3d3d3d3d3d3IiIiInd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiInJ3d3d3d3d3d3d3dyIiIiIiIiJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3JyIiIiIiIiJyd3d3d3d3d3d3IiIiIiIiIiJyd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3IiISESEiIiIicnd3d3d3d3cnEiEiIiIiIiIid3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIREiIiIhEiInd3d3d3d3ciESEiIiIiIiIicnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIiIiIiIhIhInJ3d3d3d3ciIiIiIiIiIiIicnd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiIiIiIiIiIRIiJ3d3d3dyciIiIiIiIiIiIiInd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiIiIiIiIiIiIiJyd3d3dyciIiIiIiIiIiIiInd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIid3d3dyIhIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIid3d3dxIhIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIicnd3dyIiIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiInd3dyIiIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiInd3dyIiIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiInJ3dyIiIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiInJ3dyIiIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiIiJ3dyIiIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiIiJ3dyciIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiIiIiIiIiIiIiIiIiJ3dyciIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIiIiIiIiIiIiIiIiJyd3ciIiIiIiIiIiIiInJ3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIiIiIiIiIiIiIiIiJyd3ciIiIiIiIiIiIiInd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3IiIiIiIiIiIiIiIiIiJyd3cnIiIiIiIiIiIiInd3d3e7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3JyIiIiIiIiIiIiIiIiJyd3d3IiIiIiIiIiIiIne3u7u7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiJyd3d3JyIiIiIiIiIiIru7u3d3d7e7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIiIiIRESIiIiIid3d3dyIiIiIiIiIisrt3d3d3d3d3u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3JyIiIiIiESEiIiIid3d3d3ciIiIiIiIisnd3d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiIiIiIiIiIid3d3d3cnIiIiIiIicnd3d3d3d3d3d7d7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIicrd3d3d3IiIiIiIicnd3d3d3d3d3d3e7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIisrt7d3d3JyIiIiIicnd3d3d3d3d3d3e3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eyu3t3d3d3tysiIiIicnd3d3d3d3d3d3e3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7u7t3d3e7u3siIiIicnd3d3d3d3d3d3d3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7u7u7u7u7e3cnIiIicnd3d3d3d3d3d3d3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7e3e7u7t3d3d3IiIicnd3d3d3d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiIicnd3d3d3d3d3d3d3d3d3JyIucre7u3d3d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiJ3d3d3d3d3d3d3d3d3dycit7u7u7t3d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3IiISESEiIiIid3d3d3d3d3d3d3d3d3u7u7t3d7t3d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiISISIiIiIiInd3d3d3d3d3d3d3dye7e3d3d7d7d3d3d3d3d3t3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiISIiIiIiIiIiJ3d3d3d3d3d3d3dycicnd3d3d7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyciEiIiIiIiIiIiIiJyd3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyciISIiIiIiIiIiIiIicnd3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dycSIiIiIiIiIiIiIiIiInd3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiIiIiIiIiIiJ3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiIiIiIiIiIiJyd3d3d3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiIiIiIiIiIiIicncid3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiIiIiIiIiIiIiInIid3d3d3d3d3d3d3e7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiIiIiIiIiIiIiIrsid3d3d3d3d3d3d3d7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiIiIiIiIiIiIiIrsid3d3d3d3d3d3d7d7d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiIiIiIrsid3d3d3d3d3d3d7d7d3d3d3d3d3t3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiIiIicrt3d3d3d3d3d3d3d7d7d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIiIiIiIiIiIiJyd3t3d3d3d3d3d3d3d7d3d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3ciIiIiIiIiIiIiIiIiIiJ3t3t3d3d3d3d3d3d3d7t3d3d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIiIiIiIiIiIiIiInd3d7t3d3d3d3d3d3d3d7t3d3d3d3d3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cnIiIiIiIiIiIiIiIid3d3d7t3d3d3d3d3d3d3t3t3d3d3d3d3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3IiIiIiIiIiIiIiJ3d3d3d7d7d3d3d3d3d3d3t3t3d3d3d3d3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyIiIiIiIiIiInd3d3d3d3e7e3d3d3d3d3d3t3d3d3d3d3d3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dyciIiIiIiIid3d3d3d3d3e3u7t3d3d3d3d3u3d3d3d3d3d3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3IiIiInd3d3d3d3d3d3d3t7u7u7t3d3d3u3d3d3d3d3e3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3u7u7u7u7u7u7u7u7d3e3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3e3d3u7u7u7u3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3e3d3d3d3t7u7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d3e7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d3e7t7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d3d7d7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d7d7d3e7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d7d7d3e3e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d7d7d3d3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d7d3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d3d3d3d3d3d7t3d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d3d3d3d3d3d7t3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d3d3d7t3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d3d3d3t3d3d3d7d7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d3d3t3t3d3d3d7d7cXd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d3d3t3u3EREREREREbt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d3d3d3d3d3txuxGxERERERu7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3txsRuxsREREREbF7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3txERsRsREREREbF7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3GxERsRsREREREbF7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3GxEREbsRERERERG7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3GxEREbsbERERERG7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3e3d3d3d3u7sREbEbERERERGxe3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3u3u3GxERu7u7EREbERERERGxe3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3t7uxuxERERG7ERG7ERERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxcRuxERERG7GxGxGxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxcRuxERERERGxGxGxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxcRsRsRERERuxERGxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0d3dxERsRsRERERuxERuxERERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0d0d9EdsRsRERERuxsRuxERERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dHRHdF3d0dERsRERERsRsRsRERERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dHVNVF3d0dEbsRERERsRsRsRERERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d9fXdxERERsRERERsRsRsRERERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxEREbsREREREbsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dERBER0bsREREREbsRERsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dEVd3d3bsREREREbsRERsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3F9Hd3bEREREREbsRERsREREREXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dHd3190REbEREREREbsREbsREREREXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dHRFXd3d0dEbEbEREREbsRERsREREREXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3RFTdF9EREbEbEREREbsRERsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3FxEREbEREREREbEREbsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3FxEREbEbEREREbEREbsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dU1d3d3bEbEREREbEREbsREREREXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dU1d3d3bEREREREbERERsREREREXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3R3R33d0dHbEREREREbERERsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3R1XV3d0dEbsREREREbsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1d1d9EdEbsREREREbsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxEREbsREREREbsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxERsRsREREREbsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxERsRsRERERsRsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxEdsRsRERERsRsRsRsRERERsXt3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d0RF3d0duxERERERuxsRsRsRERERu3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d1R13dcduxERERERuxERuxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxexGxERERGxGxERuxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dxexGxERERG7GxERuxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3exGxERERG7ERGxGxERERERu3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3ERERG7EbERGxGxERERGxe3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3EbsRERGxGxERERGxe3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ERERERG7ERERERGxe3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3EREREbEbERERERG7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3EREREbsRERERERG7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3ERERsRsREREREbF7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3FxGxuxEREREREbF7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3F7G7GxEREREREbt3u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7cbERERERERsXt3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cRERERERERu3d3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3e3d3d3d3t3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3u3d3d3d3t3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3t3t3d3d3d3t3t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d7t3t7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t7d3d3d7t3t7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7e3d3d7e7u7u7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3u7t3u7u7u7u7u3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3t7u7u7u7u3e3u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7u7u3d3d7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7u7u3d3d7e7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3u7t3d3e7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3e7t7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e3e3e7e3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3u3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3t3t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3e7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7d7d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7t3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3c="}},"storySprites.world":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////n5mZmZm5mZn5//////////////////////////////////////////////////////////////////+ZmZmZu+u73buZmfn/////////////////////////////////////////////////////////////n5mZmbu9u7u7u7ubmZb5//////////////////////////////////////////////////////////+fmZ2Zubu7u7u7u7vbnZlpmf///////////////////////////////////////////////////////5+ZmZ2Zudu7u7u7u7u7u7uZafn/////////////////////////////////////////////////////n92dmZmZmbu7u7u7u7u7u7uZmZb5////////////////////////////////////////////////////2d2ZmZmZmbm7vMvMvLu7u7u7mZmW///////////////////////////////////////////////////fu5mZmZmZZma7vMvMvLvLvLu725Zpmf///////////////////////////////////////////////9+7u5mZZmZmZmbmu8vMu8y7vMu7u+vMafn//////////////////////////////////////////////727nZmZZmadbWZmzMzMu8y7zMu8zLvMnJb/////////////////////////////////////////////n7u725mZmZnd3ZmZxszMzMzMzMzMzLvLzGn5////////////////////////////////////////////vbu73Wlmltnd3WZmZszMzMzMzMzMzMzMy5yW///////////////////////////////////////////fu5u7bWZmZmbW3ZaZmcnMzMzMzMzMzMzMvMxs+f////////////////////////////////////////+/u9m7bZZmZpZp3WZmlsnMzMzMvMyZZsaWmczMlv////////////////////////////////////////+9m5ndZmaWmWZmZmZmlpnMzLy7zGZmZmZmaZZsafn//////////////////////////////////////9+7mZndZpaZZmZmZmZmZpnGvLtmZplmZmZpZmZmlvn//////////////////////////////////////7+bmdZtZmZmZmaWaWZmZmZmu2ZmZmaWZmaZZmlmZpb//////////////////////////////////////72badaZZmZmZmZmZmZmZmZmZmZmZrZtZmZmZpZmZmb/////////////////////////////////////392ZZtlmZmaWaWZmZmZmZmZmZmZmZrZrZmZmZmaZZpn5////////////////////////////////////351pZmZmZmZmZmZmZmZmZmZmZmZmZma7bWZmZmaZaZaW////////////////////////////////////aWlmZmZmZmZmZmZmZmZmhmhmZmZmZma7a2ZmZmZmmZaZ////////////////////////////////////mWaWZmZmZmZm3WaIaIhmhmiIaGaIaIa4u21mZpZmZplp////////////////////////////////////1m1mZmZmZmaGaGaIaIiGaIaIaGaIZoaIvWtmZmZpZmaZ+f////////////////////////////////+f1m1pZmZohmiIaGZoiIiIaIiIiIiIiIaIbdtmZmZtbWaW+f////////////////////////////////+f3WZmZoZoiGhmhoiIiIiIiIiIhoiIiIiI2L1rZtZtbWaWlv////////////////////////////////+fvWtmZohoaGaIiIiIiIiIiIiGiIiIZoaIiLa7bWbdbWZmkf/////////////////////////////////Zu9ZtZmaGiIiIZoaIaGaGiIiGiIiIiIiIiIi722bdZmZmEf/////////////////////////////////Zu71miIZohohoZmaGiIiIZoiIiIiIiIiIiIiIu92IaGZmZv////////////////////////////////+9a7uIiIiIiIiIhoiIiIiGiIiIiIiIiIiIiGZmtt2IZmZmEfn///////////////////////////////+9a22IiIiIiIi4u7u9i4iIiIiIiIiIiGaIiIiIiIiIiIaIEfn//////////////////////////////5+7ZmaGiIiIiLi73d29u4uIiIiIiIiIiIiIiIaIiIiIiIiIGPn//////////////////////////////5/dFoiGiGiIhrjb3d27u7uIiIiIiIiIiIiIiIhoiIhmZoiIFvn//////////////////////////////99tiIiIiIaIiLjdu729u7uIiIiIiIiIiIiIZohoZohoiIaIZpb//////////////////////////////59miIiIiIiIuNvdu7u9u7uLiI2IiIiIiIiIiGhoZoZoZogYEZb//////////////////////////////5+GiGiIiLuI2N3d27u7u7uL2I2IiIiIiIiIiIiIiGZoiIiIGJH//////////////////////////////7+BEYiIuLuI2N3bvdu7u7uL2I2IiIiIiIiIiIiIiIhoiIgRGJH//////////////////////////////7+GgYiIzMuI3d27vbu7u7uLiN2NiIiIiIiIiIiIiIhoiIiBEZb//////////////////////////////78YiIjIy7uI3d27u7u7u7uOiNuNiIiIiIiIiIiIiIiIiIiIgZb//////////////////////////////78bgYjMu4u43b27u7u7u7uL2LvdiIiIiIiIiIiIiIiIiIiIEZb//////////////////////////////78ciIjMjIi43bvdvbu7u7uIvbuNiIiIiIiIiIiIiIiIiIiIGJb//////////////////////////////8/MHIjMi4jYvbu7u7u7u7uIuLuNiIiIiIiIiIiIiIiIiIiIGJn////////////////////////////////MjMi8joi73du7u7u7u7uI2L2LiIiIiIiIiIiIiIiIiIiIaPn////////////////////////////////MjMi8iIi4vdu7u7u7u7uLiIiNiIiIiIiIiIiIiIiIiIiIaPn////////////////////////////////MHMi8i4jovbu7u7u7u7u7joiNiIiIiIiIiIiIiIiIiIiIZvn////////////////////////////////MjMjMi4i43b27u7u7u7u7u4yIiIiIiIiIiIiIiIiIiIiIYf/////////////////////////////////JzMjMu4i43ru7u7u7u7u7u7uIiIiIiIiIiIiIiIiIiIgYkf////////////////////////////////+/y8iMvIyIyLu7u7u7u7u7u7u7uLu7u7uMiIiIiIiIiIiIlv////////////////////////////////+fy8y8u7yIyLu7u7u7u7u7u7u7u7u7u7u8u4uIiIiIiBaB9v////////////////////////////////+fzMzMvMyIyLy7u7u7u7u7u7u7u7u7u7u7u7uLiIiIiBho+f//////////////////////////////////yczMvIiIyLy7u7u7u7u7u7u7u7u7u8u8zLy7iIiIiIho+f//////////////////////////////////uczMjIiIyLy7u7u7u7u7u7u7y8y8zMy8zLuLiIiIiIho////////////////////////////////////78zMjIiI2Ly8u7u7u8vMzLu7y8zLzMzMzMyMiIiIiIiW////////////////////////////////////n8zMjLuIiMzMzMy8zMzMzLvMzMzMzMzMzMyIiIiIiIj2/////////////////////////////////////8nMi8iMiMy8zMzMy7vMzMzMzMzMzMzMzMyIiIjYjWj5/////////////////////////////////////8nMi8iMuMvMzMzMzMzMzMzMzMzMzMzMzIiIiLjbiJb//////////////////////////////////////5/MvIuIiMjMzMy8zMzMzMzMzMzMzMzMiIiIiLiOaJb////////////////////////////////////////GzLu864vMzMzMzMzMzMzMzMzMzMyMiIiIiIiIaPn////////////////////////////////////////JzMzMvLuIzMzMzMzMzMzMzMzMzIiIiIiIiIiIlv////////////////////////////////////////+fy4jMzMuLyMzMzMzMzMzMzMzMjIiIiIiIiIho9v//////////////////////////////////////////yYyIy8y7iMjMzMzMzMzMzMzMiIiIiIiIiIhm+f//////////////////////////////////////////z2zIu8zMi4jMzMzMzMzMzIiIiIiIiIiIiGiW/////////////////////////////////////////////8yGvLzMu4iIzMzMzMyIiIiIiLi7iIiIiGb5/////////////////////////////////////////////59svLjMzIuIzMzM64iIiIiIiLvMiIiIaJb////////////////////////////////////////////////JvIvIzLuIyMzMu4iIiIjI3N3IiJholv////////////////////////////////////////////////+fzLuIzLyIiMyMiIiIiIjI3IiIiL2b+f//////////////////////////////////////////////////n7uLyMyIiIiIiIiIiIiIiIiIiGaW/////////////////////////////////////////////////////8nMiMyIiIiIiIiIiIiIiIiIZpb///////////////////////////////////////////////////////9pZoaIiIiIiIiIiIiIiIholvn/////////////////////////////////////////////////////////aWaGiIiIiIiIiIiIiGiW+f///////////////////////////////////////////////////////////5lmhoiIiIi7iIhoZpb///////////////////////////////////////////////////////////////+fmWZmZma7a2aW+f///////////////////////////////////////////////////////////////////5+ZmZmZmfn///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8="}},"storySprites.field":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAACZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmcyZzJx5d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZzMzHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZzJnMnHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZyZmczJnHl5d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnJOckzfJd5d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmdkdkZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnMMzMzeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZGd0dEZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZM1Mzd3d3d3d3p3p3d3d3d3d3d3d3d3d3d3eZmZmZmZmZ3R0RERGZmZmZmZmZmZmZmZmZmZmZmZmZmZk5M1Uzd3d3d3d3p3p3d3d3d3d3d3d3d3d3d3eZmZmZmZkZ3REREbGbmZmZmZmZmZmZmZmZmZmZmZmZmZk5M1Mzc3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHREREbEbmZmZmZmZmZmZmZmZmZmZmZmZmZmZMzMzk5l3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZPDMzmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZPJOZzHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmczJnHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmczMfKd6d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmcmXd6d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZHRERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmcmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRER3RERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZeXd3d3p3d3d3d3d3d3d3d3d3d3d3d3eZmZmZERER0RERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmTmTd8l3d3p3d3d3d6d3d3d3d3d3d3d3d3eZmZkZERERERERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZk5MzOTd3d3d3d3d3d3d6d3d3d3d3d3d3d3d3eZmZkZEREREREREbGbmZmZmZmZmZmZmZmZmZmZmZmZmZk5MzMzmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZnZEREREREREbGbmZmZmZmZmZmZmZmZmZmZmZmZmZkzMzUzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZndEREREREREbGbmZmZmZmZmZmZmZmZmZmZmZmZmZkzU1Uzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZndEREREREREREbmZmZmZmZmZmZmZmZmZmZmZmZmTkzMzUzd5d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZnZERERERERERG7mZmZmZmZkZmZmZmZmZmZmZmZmZk5MzMzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZnZHRERERERERG7kZmZmZkREZGZmZmZmZmZmZmZmZkzMzMznHd3d3d3p3d3d3d3d3d3d3d3d3d3d3eZmZmZ3d0dERERERG7kZmZmRkRERGZmZmZmZmZmZmZmZmZOTOTmZl3d3d3p3d3d3d3d3d3d3d3d3d3d3eZmZmZmd3dERERERG7kZmZmdkREbGbmZmZmZmZmZmZmZmZOTmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERG7mZmZmdkREbGbmZmZmZmZmZmZmZmZmcmZmcx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRkRERHdEbEbmZmZmdkREbGbmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdERERHd3b2bmZmZmdkRERGbmZmZmZmZmZmZmZmZmZmZmXenend3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmd0RERER3b2ZmZmZmdERERGbmZmZmZmZmZmZmZmZmZnJnJl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmd0REREREZuZmZmZGd0RERGbmZmZmZmZmZmZmZmZmczJnKZ3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmd0REREREZuZmZmZGd0REbGbmZmZmZmZmZmZmZmZmcyZqap3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdkRERERsZuZmZmZEdEREbGbmZmZmZmZmZmZmZmZmZmZqad3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdkRERERsZuZmZmZHdEREbGbmZmZmZmZmZmZmZmZmZmceXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdndERERsZuZmZnZHREREbuZmZmZmZmZmZmZmZmZmcmcmXl3d3d3p3p3d3d3d3d3d3d3d3d3d3eZmZmZmdndERERERuZmZnZHREREbuZmZmZmZmZmZmZmZmZmcmZyXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdndERERERuZmZnZHREREbuZmZmZmZmZmZmZmZmZmZmZmXx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZndEREREZuZmZnZHREREbuZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZndERERsZuZmZnZHREREbuZmZmZmZmZmZmZmZmZmZmZeXd3p3p3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZkZERERsZuZmZnZEREREbGZmZmZmZmZmZmZmZmZmZnJfHd3p3p3d3d3d6p3d3d3d3d3d3d3d3eZmZmZmZmZERERu5mZmZnZHREREbGZmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3p3d3d3d3d3d3d3d3eZmZmZmZmZGRERkZmZmZnZHREREbGbmZmZmZmZmZmZmZmZmZmcmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZnZHREREbGbmZmZmZmZmZmZmZmZyZyZmXd3d3d3qnd3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkZ3REREb2ZmZmZmZmZmZmZmZmZyZyZeXd3d3d3qnd3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkR3REREb2ZmZmZmZmZmZmZmZmZmZmZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZkR0R0REbGZmZmZmZmZmZmZmZmZmZmZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkd0R0REbGZmZmZmZmZmZmZmZmZmZmZqXp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkdEREREbGZmZmZmZmZmZmZmZmZmZmZqnp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkdEREREbGZmZmZmZmZmZmZmZmZmZmcmXp3d6p3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkREREREbuZmZmZmZmZmZmZmZmZyZmcmXp3d3p3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkREREREbuZmZmZmZmZmZmZmZmZyZmZeXp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkREREREbuZmZmZmZmZmZmZmZmZyZmZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkdEREREbuZmZmZmZmZmZmZmZmZmZmZyXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdndEREREbuZmZmZmZmZmZmZmZmZmTMzeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdndEREREbuZmZmZmZmZmZmZmZmZmTMzk3l3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkdEREREbuZmZmZmZmZmZmZmZmZMzMzeXd3end3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REREREbuZmZmZmZmZmZmZmZk5M1Uzc3enqnd3p3p3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REREREbuZmZmZmZmZmZmZmZk5MzUzM3d3d3d3d3p3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REREREbuZmZmZmZmZmZmZmZmZMzMzc3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REREREbGZmZmZmZmZmZmZmZmZMzMzc3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0RERHdEbGZmZmZmZmZmZmZmZmZOTOZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkRERHd3b2ZmZmZmZmZmZmZmZmZmZnJeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkdERER3bGbmZmZmZmZmZmZmZmZmZmZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkdEREREbGbmZmZmZmZmZmZmZmZyZnJmXd3d3d3d3d3p3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZndEREREbGbmZmZmZmZmZmZmZmZyZnJnHl3d6d3d3d3p3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZndEREREbGbmZmZmZmZmZmZmZmZmZmZmcl3d6d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZnZHREREbGbmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZ3R0REbGbmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZEREREbGbmZmZmZmZmZmZmZmZmZnMycx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZEREREbGbmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZGREREbGbmZmZmZmZmZmZmZmZmcyZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZGREREbGbmZmZmZmZmZmZmZmZmZzJnHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmdndHZGZmZmZGREREbGbmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmd0dERGZmZmZGREREbGbmZmZmZmZmZmZmZmZmZyZyXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZ2d0RERG7mZmZ2R0REbGbmZmZmZmZmZmZmZmZmcyZzHl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZ2R0RERG7mZmZ2R0REbGbmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnR0RERERG7mZmZmR0REbGbmZmZmZmZmZmZmZmZmZmZmXd3d3d6d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdnd3R0RERG7mZmZmd0RERGbmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ2d0dER0RERG7mZmZmdkdERGZmZmZmZmZmZmZmZmZmZmZmXmnd3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ2R0RERERERG7mZmZmZndHZGZmZmZmZmZmZmZmZmZmZnMmXynd3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ3RERERERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnMmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ3RERERERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ3RERERERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZeXd3d3d3d3end3d3d3d3d3d3d3d3d3eZmZmZ3RERERERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3ene3d3d3d3d3d3d3d3d3eZmZmZ3RERERERERG7mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ3REREd0RERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZzHl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZ3R0R0d0RERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmcmcmXp3d3enend3d3d3d3d3d3d3d3d3d3eZmZkZ0RER0RERERERu5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmcrKZ3d3end3d3d3d3d3d3d3d3d3d3d3eZmRkRERERERERERERu5mZmZmZmZmZmZmZmZmZmZmZmZmZmZnJrKp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmRkRERERERERERERsZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmRERERERERERERERsZuZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXd3end3d3d3d3d3d3d3d3d3d3d3d3eZmRERERERERERERERsZuZmZmZmZmZmZmZmZmZmZmZmZmZmcyZeXd3qnd3d3d3d3d3d3d3d3d3d3d3d3eZmRERERERERERERERsZuZmZmZmZmZmZmZmZmZmZmZmZmZmZnJzHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmRERERERERERERERsZuZmZmZmZmZmZmZmZmZmZmZmZmZmZnMmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmR0RERERERERERERsZuZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmd0RERERERERERERsZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmd0RERERERERERERu5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZfHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmdkdERERERERERERu5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmcfHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmdkdERERERER0d3dvZmZmZmZmZmZmZmZmZmZmZmZmZmZyZyZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZnd3RERERER0d3dm5mZmZmZmZmZmZmZmZmZmZmZmZmZyZycyXeqd3d3d3d3d3d3d3d3d3d3d3d3d3eZmZnZ3R0RERERERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmceXeqd3d3d3p3d3d3d3d3d3d3d3d3d3eZmZmZGRERERERERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3p3p3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRERERERERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmRnRHRERERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmcyZZqZ3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZndHRERERGxm5mZmZmZmZmZmZmZmZmZmZmZmZmZmZnMmal3d3d6d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdkdERERERGxmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnMeXd3d3d6d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdkdERERERGxmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmdkdERERERGxmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZndERER0R2RmZmZmZmZmZmZmZmZmZmZmZmZmZmZycyZyXx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZndHRHR3RGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZyZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZnZ3d3dnZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZyZeXd3d3d3d3d3p3d3d3d3d3d3d3d3d3eZmZmZmZmZ2d2dmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmceXd3d3d3d3d3p3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmdkREZmZmZmZmZmZmZmZmZmZmZmZmZmcyXx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REZGZmZmZmZmZmZmZmZmZmZmZmZnMyXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REbGbmZmZmZmZmZmZmZmZmZmZmZmZead6d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmR0REbGbmZmZmZmZmZmZmZmZmZmZmZmZqal6d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmR0REbGbmZmZmZmZmZmZmZmZmZmZmcmcqXp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZ2R0REbGZmZmZmZmZmZmZmZmZmZmZmcnMmaZ3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmR0REbGZmZmZmZmZmZmZmZmZmZmZmcnMyax3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmR0REbGZmZmZmZmZmZmZmZmZmZmZmcmcmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REbGZmZmZmZmZmZmZmZmZmTmTM5mZmXd3d3end3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REbGZmZmZmZmZmZmZmZmZmTkzMzl3l3l3d3end3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmd0REbGZmZmZmZmZmZmZmZmZmTkzMzNzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZGdEdEbGZmZmZmZmZmZmZmZmZmZkzVTNzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZEdEdEbGbmZmZmZmZmZmZmZmZmTlTVTNzd3l3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZnZHREREbGbmZmZmZmZmZmZmZmZmTkzNTN3l3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZndEREREbGbmZmZmZmZmZmZmZmZmTM5MzNzmXd3d3d3d3d3d3d6d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZndERERERGbmZmZmZmZmZmZmZmZmTkzMzOZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZndERERERGbmZmZmZmZmZmZmZmZmZmTM8mceXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZndERERERGbmZmZmZmZmZmZmZmZmZmZmcnMzHx3qnd3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZndEREREbGbmZmZmZmZmZmZmZmZmZmZmZmZzHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRnREREREbGbmZmZmZmZmZmZmZmZmZmZmZmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRHRHREREbGbmZmZmZmZmZmZmZmZmZmZmZmZmXx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRHRHREREbGbmZmZmZmZmZmZmZmZmZmZmcmZmXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGREREREREb2bmZmZmZmZmZmZmZmZmZmZmczMmXd3d3d3d3p3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZGREREREREb2bmZmZmZmZmZmZmZmZmZmZmcnMzHl3d3d3d6p3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZ2RERERER3b2ZmZmZmZmZmZmZmZmZmZmZmZmZmXl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZ2R0RERER3b2ZmZmZmZmZmZmZmZmZmZmZmZmZmZl3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZ2R0REREREb2ZmZmZmZmZmZmZmZmZmZmZmZmZmZx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZ2R0REREREbGZmZmZmZmZmZmZmZmZmZmZmZnJnHd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmd0REREREbGZmZmZmZmZmZmZmZmZmZmZmZnJnKp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmd0dEREREbGZmZmZmZmZmZmZmZmZmZk5kzOZeXd3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmdndHREREbGZmZmZmZmZmZmZmZmZmZkzMzOTeap6d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZndHREREbGZmZmZmZmZmZmZmZmZmZkzMzOTmXp3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkREREREbGbmZmZmZmZmZmZmZmZmTMzUzOTd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkREREREbGbmZmZmZmZmZmZmZmZmTMzVTVzd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkREREREbGbmZmZmZmZmZmZmZmZmZmzVTOTd5d3d6d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRkREREREbGZmZmZmZmZmZmZmZmZmTkzM8Mzd5x3d6d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRndEREREbuZmZmZmZmZmZmZmZmZmZk5M8ycmXx3d3d3d3d3end3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmRndERER3ZGZmZmZmZmZmZmZmZmZmZmZM8mcmZl8d3d3d3d3end3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZnRERHRHZmZmZmZmZmZmZmZmZmZmZmZmcnMzMl8d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZnR3d3dEZmZmZmZmZmZmZmZmZmZmcnJzMzMzHx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZkZ3d0dmZmZmZmZmZmZmZmZmZmZmcnMzMycmXx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZGZmZmZmZmZmZmZmZmZmZmZmcnJyczMzJx5d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmczJzHx3d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmcmcmcyZmcl8d3d3d3d3d3d3d3d3d3d3d3d3d3eZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnMmZmZmZl5d3d3d3d3d3d3d3d3d3d3d3d3d3c="}},"storySprites.valentines":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAAAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMx0RETEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxERERE9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRERE9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MREdEzMzMzMzMzMzMzMzMz0z0zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRETMzMzMzMzMzMzMzMzMzHTEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRMTMzMzMzMzMzMzMzMzMzETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPdMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM5kzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM5kzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz07mZOTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTMTMzk5mZMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzHT0RETEzk5mZmTMzMzMzMzMzMzMzMzMzMzMzMzMzMzPRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdERGx2xEzk5mZ2TMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRuxGxux0RkdkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM90RuxsRERERmT0zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzERERGxERERHRmTEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTEdsRERERERGR2RERPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTsdsRERERERGdGdER0TMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTsR0RERERERGZEdG7ETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMd0REREREREZHZERG7ETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMREREREREREZEZERG9ETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxHREREREREZkRERHRETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxHREREREREZkRERERETEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxPRERERERERkdkRERHRG9EzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRERERERERkRkRERERuxEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRHREREdHZnR0RERER2xEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxGxERERGZmRERERERHTEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRGxERERGRmR0REREREREzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRvRERERERnRkRERERuxEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRsR0RERERERERERERux0zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzETMzMzMzMzMzMzMzMxEREdERERERERERERERuxEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzETMzMzMzMzMzMzMzMxG7HdERERERERERERERHdEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMREREREREREREREREREREREdEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRERERERERERERERERERER3REzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxG9HRERERERERERERERERERsRs9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9G7ERERERERERERERERERERsRs9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxEbERERERERERERERERERER0REzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMx0REREREREREREREREREREREREzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzExERERERERERERERERERERERERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzEdERERERERERERERERERERERERvRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTEbsREREREREREREREREREREREbERMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPT0dsRERERkZkdEREREREREREREbERMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzEdEREREREZmZEREREREREREREbEdMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzExEREREREZmZGREREREREREREdEdMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxERERERkdmRHRERERERERERERERMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzExERERERmRkREREREREREREREbsRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzE7ERERHRmRERERERERERERHRsRvRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzE70bERGRGRERERERERERHb0bERExMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzExHdERGZEREREREREdG7G7EdEdEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxERHZGZERERERER0RG7HRERMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMR250ZERERERHRuxGxERMxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRu5kRERERERGxuxER0TMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTkRkRERERvRsRuxEdMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTmRERu7sRuxsRETEzMzMzMzMzOTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM5mZmTMRvR0RsRHdETMzMzMzMzM5mTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM52ZOTMTERHdEREzMzMzMzMzMzOZmTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM5mZmTkzHTEz0z0zMzMzMzMzk5mZmTMzMzMzMzMzMzMzMzMTPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM5mZmTMzMzMzMzMzMzMzMzMzM5mZ2TMzMzMzMzMzMzMzMzMdMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzk5mZMzMzMzMzMzMzMzMzMzMzMzOZOTMzMzMzMzMzMzMzMzMRPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzk5kzMzMzMzMzMzMzMzMzMzMzMzOTOdM9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxERmRERPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9HRHdmd0b0RHRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTMzMzMzMzMzMzMzMzMzMzMxEREbu7m7m7ERERPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdPTMzMzMzMzMzMzMzMzMzE9HbISIi0rkiHbsbMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRMzMzMzMzMzMzMzMzMzMzE70rIiIiIpkiIiLb0RHRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzHbsiIiIiIpspIiIiERERMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdES0iIiIiIpIpIiIis7vbEd09MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRESMiIiIiIiKZIiIiIiK7HRERPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxOyIiIiIiIiKZIiIiIiIiG73b0TMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxO9KyIiIiIiIiKbKyIiIiIiIrK7ER0RMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxO9IiIiIiIiIiKSKSIiIiIiIiKyHRHdETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxO9IiIiIiIiIiKSKSIiIiIiIiIiErG7GzEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxIiIiIiIiIiKyuSIiIiIiIiIiIiK729EzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRIiIiIiIiIiIimSIiIiIiIiIiIiIiuxERMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxEtIiIiIiIiIpK7mSIiIiIiIiIiIiIiIjMdMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz07ErIiIiIiIiIpKZmZkpIiIiIiIiIiIiIiLbMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz07ErIiIiIiIiIiK725ktIiIiIiIiIiIiIiLbMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz09ErIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIdPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxG9IiIiIiIiIiIiIiIiIiIiIiIiIiIiIhLRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhI9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhsxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxO9IiIiIiIiIiIiIiIiIiIiIiIiIiIiIhs9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxKyIiIiIiIiIiIiIiIiIiIiIiIiIishEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9PRKyIiIiIiIiIiIiIiIiIiIiIiIiIiE9EzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRvSIiIiIiIiIiIiIiIiIiIiIiIiIiETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTESEiIiIiIiIiIiIiIiIiIiIiIiIiHTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzHbEiIiIiIiIiIiIiIiIiIiIiIiKyHTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzE727IiIiIiIiIiIiIiIiIiIiIiKyETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdETMzMzMzMzMzMzMzE7G7uysiIiIiIiIiIiIiIiIiIiIR0TMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRETEzMzMzMzMzMzMz0xHdHREhIiIiIiIiIiIiIiIiIjIRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMREREzMzMzMzMzMzMzMxMREREtIiIiIiIiIiIiIiIiItLRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRERExMzMzMzMzMzMzMzPTEbsiIiIiIiIiIiIiIiIiIrLRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTERERMzMzMzMzMzMzMzMTsSsiIiIiIiIiIiIiIiIiIrvRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRERERMzMzMzMzMzMzMzMTsSsiIiIiIiIiIiIiIiIiIhsxMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRERExMzMzMzMzMzMzMzPT0SIiIiIiIiIiIiIiIiIi0hE9MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMREREzMzMzMzMzMzMzMzMz0SIiIiIiIiIiIiIiIiIiEjEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdETMzMzMzMzMzMzMzMzMT0SIiIiIiIiIiItsrIiIi0jEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRLSIiIiIiIiKSmZmZKyIi2zEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9PRKyIiIiIiIiKSuZmyIiIi2zEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxKyIiIiIiIiIiIpkiIiIiHTEzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxOxKyIiIiIiIiIiIpIpIiISETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRKyIiIiIiIiIiIpK5IiISMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdLSIiIiIiIiIiIiKZIiIbMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPTsSIiIiIiIiIiIiKbKyIbMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTsSIiIiIiIiIiIiKSKbIbMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMduyIiIiIiIiIiIiKymdMRPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRuysiIiIiIiIiIiIimRHRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMRu+0iIiIiIiIiIiIiktkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMdEREiIiIiIiIiIiKym9kzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz3RErIiIiIiIiIjK7HZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxG7MyIiIiIiIh0REZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMx0RESEiIiIiuxHdPZM5M5kzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMd3bErsru7G9EzM5OZk5kzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz09G7HRHdET0zMzOZmZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxERER0R0TMzM9OZmZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MRPTMzMzMzM5mZmZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzk5mZmZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzk5mZmZkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM5OZmdkzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz0zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM9MdMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMdPTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTMzMzMzMzMzMzMzMzMzMzMxMRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMx0RMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxERMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMx0RMTMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzExERETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzHRERETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzHRERETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzExHRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMTETMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzPRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMxMRMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM="}},"storySprites.lake":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAABmZmZmZmZmZmZmZtEdEbG7u7u7uxHMERHMzMzMZmZmZmZmZmbmZu5uZmbuZuZu5maIiIiIiIiIiIiIiOhmZmZmZmZmZmZmZt0dEbG7u7u7EcHMERHMzMzMbGZmZmbmbmbmZm5mZmbmZmZmZoaIiIiIiIiIiIiIiOhmZmZmZmZmZmZmZt0dEbG7u7sREcHMHMHMzMzMbGZmZmZuZmZuZmZm5m5mZmZm5oaIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFt0dEbG7uxsREcEcEczMzMzMZuZmZmZmZmZmbmbmZmZmZuZmboaIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtEdERG7uxsREc0REcHMzMzMbG5mZm5mZmaIaGhoZmZmZmZmZoaIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd0dERG7uxERwRwREcHMzMzMZmZmZmZm7oiIiIhmZmZmZmbmZoiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd3dERG7uxERzBwREczMzMzMZmZmZmbmhoiIiIhm6GZuZmZuhoiIiIiIiIiIiIiIiIhmZmZmZmZmZmYWEdHdEbu7uxERwRwRwczMzMzMZm5uZm5mhoiIiIiIaGZmZmZmiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYWEdHdEbu7GxERERERzMzMzMzMZmZmZm5miIiIiIiIZmZmZmZmiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYWERHdEbu7uxERERERwcHMzMzMbG5mZmaGiIiIiIiIaGZmZuZmiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYWERHdHbG7GxERERERERHMzMzMZmZmZmaOiIiIiIiIiOhm5m6GiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYWEdHdHbG7GxERERERERHMzMzMbG5m5maIiIiIiIiIiGZmZmaGiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmbWEd3dHbG7uxEREREREcHMzMzMZm5mZuaIiIiIiIiIZmZmZmaGiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd3d3RG7uxERERERwczMzMzMZmZuZuaIiIiIiIiIiGhmZoaIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd3d3RG7uxERERERzBzMzMzMZmbuZoaIiIiIiIiIiIiIZoaIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtHd3RG7uxERERERERERzMzMZmZuZo6IiIiIiIiIiIiIZoiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtHd3R2xuxsRERERzMzMzMzMbG5mZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFhHd3R2xuxERERERwczMzMzMZmZmboaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3d0RuxERERERERHMzMzMZmZmbo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3d2xuxsRERERERHBzMzMZuZmZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3d27u7sREREREcwRzMzMbGZmZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3d29u7sRERERzMzMzMzMbGZmZoiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d29u7sRERERzMzMzMzMZmZm5oiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d29u7sREREREczMzMzMZmbmiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d29u7sbEcEREczMzMzM7GaGiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d29u7sbEREREcHMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d29u7sbERERERHMzMxsZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d27u7sbERERERHMzMxsZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZtbR3d27u7u7ERERERzBzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZtbd3d27u7u7HBEREcwRzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhbR3d27u7sbwRERHMwczMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZh3d3d27u7u7wREREcHMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZh3d3b27u7u7ERwREcHMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3b27u7u7ERzBEcHMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3b27u7u7EcwRHBHMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3R2xu7u7EcwRwRHMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3Ruxu7u7EcEcwczMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHd3Ruxu7u7G8HMEczMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZhHdvRGxu7u7y8zMEczMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm1hHdHRG7u7u7y8zMEczMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm1tHdHRG7u7u7zMzMHMHMzMzMbIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtHdGxG7u7u7wczMHMHMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtHdERERu7u7wczMHMHMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtHdEbERu7u7wczMzMHMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtG9ERGxu7u7wczMzMzMzMxs5o6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtEdERG7u7u7wczMzMzMzMzM5o6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmFtEdERG7u7vLwczMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm3d0dEbG7u7vLEczMzMzMzMzMbIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmHd0dEbG7u7sbEcHMzMzMzMzMbIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd0REbG7u7sbEcHMzMzMzMzMbIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd0RERG7u7sREcHMzMzMzMzMbIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd0RERG7u7sREcHMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmEd0REbG7u7sREcHMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm3d0REbG7uxsREczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm3R0REbu7uxsREczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm3R0REbu7uxsREczMzMzMzMzMbI6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZm3R0REbu7uxsREczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmbW0R0REbu7uxsREczMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0R0REbu7uxsREczMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0REREbu7uxsREczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0REREbG7uxsREczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0RERsRG7uxsREczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0RERsbG7uxsRzMzMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0RERsbu7uxsRzMzMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0REREbu7u7sRwczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0REREbG7u7sbwczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0REREbG7u7sbwczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYW0R0REbG7u7u7wczMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmbZ3R0REbG7u7u7wczMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYR3R0REbG7u7u7EczMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYR3d0REbG7u7u7HMzMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmYR3d0RERG7u7u7G8HMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhbR3d0RERG7u7u7G8HMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhYR0d0RERG7u7u7G8HMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhYR0d0dERG7u7u7y8HMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhYR0d0dG7G7u7u7u8HMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhYR0d0dEbG7u7u7u8HMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhYR0d0dERG7u7u7u8zMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhYR0d3dERG7u7u7u8zMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZh0R0d3dERGxu7u7u8zMzMzMzMzMbI6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZh0R0d3dHRGxu7u7u8zMzMzMzMzMbIaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhER0d3dHbERu7u7u8zMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZhER0d3dHRERu7u7u8vMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmFhEd0d3dHRG7u7u7u8vMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmFhER0d3d3RGxu7u7u8vMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmFhER0d3d3RGxu7u7u8vMzMzMzMzMZoaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmFhER0d3d3Ruxu7u7u8vMzMzMzMzM5o6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmER0R0d3d3Ruxu7u7u8vMzMzMzMzM5o6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmER0R0d3d3Ruxu7u7u8zMzMzMzMxs5oaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZm0R0R0d3d3R2xu7u7u8zMzMzMzMxs5oaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZm0REREd3d3R2xu7u7u8zMzMzMzMxs5o6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYW0REREd3d3b27u7u7u8zMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYW0REREd3d3b27u7u7u8zMzMzMzMxs5oaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYWEREREd3d3d27u7u7u8zMzMzMzMzM5oaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYdEREdEdHd3d27u7u7u8zMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYREREdEdHd3d27u7u7y8zMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYRERHdEdHd3d27u7u7EczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZtYRERHdERHd3d27u7u7EczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhYRERHdERHd3d27u7u7EczMzMzMzMzMZo6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhYRERHdERHd3d29u7u7EczMzMzMzMzMZoeIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZh0RERERERHR3d29u7u7EczMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhERERER0R3R3d29u7u7EczMzMzMzMzMZu6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhERERER3R3R3d29u7u7wcHMzMzMzMzMZu6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZm1hERERER3d3R3d29u7sbwcHMzMzMzMzMZm6GiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZm1hERERHR3d0R3d29u7sbEcHMzMzMzMzMZm6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmFhERERHd3d0R3d3du7sbEcHMzMzMzMxs5maIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmFhERERHd3d0R3d3du7sbEcHMzMzMzMxs5u6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmERERERHd3d0R3d3du7sREcHMzMzMzMxs5maIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmbWERERERHd3d0d3d3du7sREczMzMzMzMxs5maIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWERERERHR3d0d0d3du7sREczMzMzMzMxs5u6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWERERERHd3d3d3d3du7sREczMzMzMzMzMZu6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWEREREdHd3d3d3d3du7sREczMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWERERERHd3d3d3d29u7sRwczMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYRERERERHd3d3d3d29u7scwczMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYdERERERHd3d3d3d29u7sczMzMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYdEREREdHd3d3d3d29u7vMzMzMzMzMzMzM5maIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYdERERERHd3d3d3d29u8vMwczMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWERERER3d3d3d3d29u8vMzMzMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWERERERHd3d3d3d29u8vMzMzMzMzMzMzM5maIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmYWERERERHd3d3d3d29u8vMzMzMzMzMzMzMZu6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmEREREdHd3d3d3d29u8vMzMzMzMzMzMzMZu6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmEREREdHd3d3d3d29u8vMzMzMzMzMzMzM5u6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmFhEREdHd3d3d3d27u8vMzMzMzMzMzMzM5m6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmFhEREdHd3d3d3d27u8zMzMzMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhEREdHd3d3d3d27u8zBzMzMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhEREdHd3d3d3b27uxzBzMzMzMzMzMzMZu6IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhEREd3d3d3d3b27uxzBwczMzMzMzMzMZuaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhYREd3d3d3d3b27uxzBEczMzMzMzMxsZuaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZhYRHdHd3d3d3b27uxEcwczMzMzMzMzMZuaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYRERHd0d3d3bu7uxERwczMzMzMzMzMZmaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYREREdEd3d3bu7yxERwczMzMzMzMzM5uaIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmYRER0REd3d3bu7yxERzMzMzMzMzMzMZuaIiIiIiIiIiIiIiIhohoaIiIiIiIiIiIiIiIiIiIhmZmZmZmYRER0R0d3dvbu7yxEczMzMzMzMzMzMZuaIiIiIiIiIiIiIiGhmZo6IiIiIiIiIiIiIiIiIiIhmZmZmZmYRERER0d3dvbu7yxERzMzMzMzMzMzMbGaGiIiIiIiIiIiIiIhoaIaIiIiIiIiIiIiIiIiIiIhmZmZmZmYRERER0d3dvbu7GxERzMzMzMzMzMzM7G6IiIiIiIiIiIiIiGhmZoaIiIiIiIiIiIiIiIiIiIhmZmZmZmYREREd3d3dvbu7GxERzMHMzMzMzMxsZmaIiIiIiIiIiIiIiGZubmaIiIiIiIiIiIiIiIiIiIhmZmZmZmYREREd3d3du7u7HMHBHBHMzMzMzMzMZmaIiIiIiIiIiIiIaOZm7maIiIiIiIiIiIiIiIiIiIhmZmZmZmYd0RER3d3du7u7HBERERHBzMzMzMzMZmaIiIiIiIiIiIiIaOZmZmaIiIiIiIiIiIiIiIiIiIhmZmZmZmYW0dER3d3du7u7ERERwRHMzMzMzMzMZmaIiIiIiIiIiIiIaOZmZm6IiIiIiIiIiIiIiIiIiIhmZmZmZmYWEdER3d29u7u7ERwRERHMzMzMzMxmZmaIiIiIiIiIiIhmZmbuZm6IiIiIiIiIiIiIiIiIiIhmZmZmZmYWEdER3d29u7vLERHBEcHMzMzMzMxsZmaIiIiIiIiIiIiIZmbm7m6OiIiIiIiIiIiIiIiIiIhmZmZmZmYWEdER3d29u7sbEREcEczMzMzMzMzMZmaOiIiIiIiIiIiIZmZm5maGiIiIiIiIiIiIiIiIiIhmZmZmZmbWEdHR3d27u7sbEcERwczMzMzMzMzMZmaGiIiIiIiIiIiIaGZm5maGiIiIiIiIiIiIiIiIiIhmZmZmZmbWERHR3d27u7sRERERzMzMzMzMzMzM5maGiIiIiIiIiIiIZmZmZm6GiIiIiIiIiIiIiIiIiIhmZmZmZmbWERHR3d27u7sRERERzMzMzMzMzMzM5u5miIiIiIiIiIiIZmbuZu5miIiIiIiIiIiIiIiIiIhmZmZmZmZmHRHR3b27uxsRERHBzMzMzMzMzMzM5u5miIiIiIiIiIiI7uZmbuZmiIiIiIiIiIiIiIiIiIhmZmZmZmZm3dHd3b27uxsRERHMzMzMzMzMzMxs5m5mhoiIiIiIiIho5mZmZuZmiIiIiIiIiIiIiIiIiIhmZmZmZmZm3dHd3bG7uxERERHMHMzMzMzMzMzMZu5m5oiIiIiIiIhmZmZmZmZmiIiIiIiIiIiIiIiIiIhmZmZmZmZm3dHd3RG7uxERERHMEcHMzMzMzMzMZm5mZmaIiIiIiIhoZmbuZmZmiIiIiIiIiIiIiIiIiIhmZmZmZmZm3dHdHbG7uxEREcEcEczMzMzMzMzMZmbmZoaIiIiIiIh4ZmZmbmZuiIiIiIiIiIiIiIiIiIhmZmZmZmZm3dHdHbG7uxEREcERzMzMzMzMzMzMZmZmboaIiIiIiIhm5mZm5mbuiIiIiIiIiIiIiIiIiIhmZmZmZmZm1tHdEbG7uxERERHBzMzMzMzMzMzM5uZmZoaIiIiIiIhmZmZmZuZmiIiIiIiIiIiIiIiIiIhmZmZmZmZm1tEdEbu7uxERERHMHMHMzMzMzMzMZuZmZoaIiIiIaGZmbmZm5u5miIiIiIiIiIiIiIiIiIhmZmZmZmZm1t0REbu7GxEREcEcEcHMzMzMzMzMZm5m5maIiIiIaGZmbmZmZuZmjoiIiIiIiIiIiIiIiIhmZmZmZmZm1t0Rsbu7GxEREREREcHMzMzMzMzMZm5mZmaGiIiIiGZmbmZmbmZuhoiIiIiIiIiIiIiIiIhmZmZmZmZm1h0Rsbu7GxEREREREcHMzMzMzMzMZmZuZmZmiIiI6OZmZmZmZmZuhoiIiIiIiIiIiIiIiIhmZmZmZmZm3R0Rsbu7GxEREREREcHMzMzMzMzMbGZmbm5miIiIaObmZmZmbmZmhoiIiIiIiIiIiIiIiIhmZmZmZmZm3RERsbu7ERERHBERwczMzMzMzMzMZmZmZmZmZmbmZm5mZmZmZmZmZoiIiIiIiIiIiIiIiIhmZmZmZmZm3RERsbu7ERERERERzMzMzMzMzMzMZmZmZmZmZmZm5mZmZmZmZmZmZoiIiIiIiIiIiIiIiIhmZmZmZmZmHRERu7u7GxEREcHMzMzMzMzMzMzMZmbubuZmbmZm5mZmZmZmbmZmboaIiIiIiIiIiIiIiIg="}},"storySprites.ocean":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAAD4////////////////j/iPiP9mZmZmZmZmZmZmZmZmZpmZmWZmZmaGZmZmZmZmZmZmZmZmZmZmZmZmZmb/////////////////iP+I/4+IZmZmZmZmZmZmZmZmlmZmmWlmxszMZmZmZmZmZmZmZmZmZmZmZmZmZsz///////////////j/+I/4/4iI+P//b2ZmZmZmZmZmZszMzGxmzMzMbGZmZmZmZmbGbGbGzGbGzMzMzMz///////////////+P+I/4/4iIiIj4/////29mZmZmxszMzMzGzMzMzGbMzMzMzMzMzMzMzMzMzMzMzMz///////////////+I+Ij/j4iIiIiI//////9mZmZmzMzMzMzMvLvMzMzMzMzMzMzMzMzMzMzMzMzMzMz//////////////4/4j/j/iIiIiIiIiP9mZv//ZmZmzMzMzMzMvLvMzMzMzMzMzMzMzMzMzMzMzMzMzMz///////////+P/4j/j/+PiIiIiIiIiGhmZvb///9mxry7u7vMzMvMzMzMzMzMzMzMzMzMzMzMzMzMzMz////////////4j4j/iP+PiIiIiIiIiIhmZvb///9vxry7u7u7u8vMzMzMzMzMzMzMzMzMzMzMzMzMzMz/////////////iPiP+P+IiIiIiIiIiIiIaP///29mZmZmvLu7u7vMzMzMzMzMzMzMzMzMzMzMzMzMzMz/////////////j/+P/4+IiIiIiIiIiIiI+P///2ZmZmZmZmZmvLvMzMzMzMzMzMbMbGbGxsxsZmbGzMz/////////////iP///4iIiIiIiIiIiIiIiP//iIhmZmZmZmbGvLvMzMzMZmZmZmZmZmZmZmZmZmbGzMz/////////////+P/4/4iIiIiIiIiIiIiIiIj/ZmaGiGhmZmbMvMvMzMxsZEZEZGZmZmZmZmZmZmbGzMz/////////+P+P/4//j4iIiIiIiIiIiIiIiIiIZmZm/4iIZmbMzMzMzMxERERERGZmZmZmZmZmZmbGzMz///////+P///4j/iPiIiIiIiIiIiIiIiIiIiIZmZm/////2/MzMzMzMxERERERGZmZmZmZmZmZmbGzMz////////4/4//j/+IiIiIiIiIiIiIiIiIiIiIiPj2//////+8y8zMzGxERCJERGZmZmZmZmZmZmZmzMz//////4////j/iI+IiIiIiIiIiIiIiIiIiIiIiIj/j29mZma2y8xmZmZERCJERGRmZmZmZmZmZmZmZmb///////j/j/iP+I+IiIiIiIiIiIiIiIiIiIiIiIj4/2ZmZmZmZmZmZmZGJEJERERmZmZmZmZmZmZmZmb/////j///iPiI/4iIiIiIiIiIiIiIiIiIiIiI/4+I+P9mZmZmZmZmZmZGRERERERVZmZmZmZmZmZmZmb///////+IiI/4j4iIiIiIiIiIiIiIiIiIiIj4//9mZvj/ZmZmZmZmVVVFRCRCRERVVWZmZmZmZmZmZmb///////+I+IiIiIiIiIiIiIiIiIiIiIiIiIiI//9mZmaI/2ZmZohVVVVVREREIkRmVVVlZmZmZlVVVWb/////////iIiIiIiIiIiIiIiIiIiIiIiIiIj4//9vZmZmhoj/9lVlZmZmRUREQlVlZlZVVVVVVVVVxsz///+P+P+IiIiIiIiIiIiIiIiIiIiIiIiIiIhvZmZmZmZmZvZvZlVmZmZmRkREVFVlZmZmVVVVZmZmxsz///+I/4+IiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmZmZmZmb2ZmZmZmZmZkREZmZmZmZmZplmZmZmzMz//4///4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIb2ZmZmZmZmaGaGZmZmZmxkzEZmZmZmZmZmZpZmbGzMz///j/j4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiP+PZmZmZmaGZmZmZmZmzMzMZmZmZmZmZmZmZmbMzMz/iP//iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiPj/j2hmZmZmZmbGzGbGvMzMZmZmZmZmZmZmZmbMzMyI//+Pj4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4j4j/b2ZmZmbMzMzMu8vMZmZmZmZmZmZmZsbMzMz4/4/4iPiPiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiPj///9mZsbMzMzMvMvMzMzMZmZmZmZmZsbMzMz///j4j/+IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiP////b8bMzMzMzMzMzMzMzMxmZmZmZsbMzMz/j4//j4+IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj/+G9mZs+8y7zLzMzMzMzMzMzMzMzMzMzMzMz///j/+I+IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4/2ZmZva8u7u7y8zMzMzMzMzMzMzMzMzMzMz/iP+P/4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI/29mZmbGy7u7u8zMzMzMzMzMzMzMzMzMzMyP+P//j4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI////b2ZmZma2u8zMzMzMzMzMzMzMzMzMzMyImf//iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiPj//29mZma8u8zMzMzMu7vMzMzMzMzMzMz4n/mPiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P9vZma8u8zMzMxsu7u7y8zMzMzMzMz//5mJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiPj/b8a8u8zMzMxsZra2u8zMvMvMzMyf+YiZiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj//8+8y8zMzMxsZmZmZszMvLvMzMz/mYmYiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj//8/MzMzMzMzMZmZmZmbMvLvMzMyPmImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj////MvLvMzMzMZmZmZmbGzLvLzMyIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4j//GvLvMzMxsZmZmZmZmzLzLzGaJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmj2ZmzMxsZmZmZmZmxry7bGaJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhmZmZmZmZmZmZmZlZmZmZmZmZmZmaYiIiJiIiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmZmZmZmZmZlZVVWZmZmZmZsaIiYiZiIiImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmZmZmZmZmZWVVVVZmZmzMyImIiYiYiIiImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiPj/b2ZmZmZmZmZmmUVEVUa0zMyZiImImYmIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P9mZmZmZmZmZmaWZkREVEREy8yZiYiImImIiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+G9mZmZmZmZmZmZmZkRERERExMyZmYiYiJmIiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI/49mZmZmZmZmZmZmZkREIkREZGaZmYmIiYmJiIiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P///2ZmZlVVZmZmZkQkRERERGaZmZmZmYmYiYiImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiPj/ZmZWVVVmZmZmZkYiIkRERGSZiJmJmJmImYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIZlVVZWZmZmbMbEZEJEJERGSZiZiJiJmJmImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhYVVVlZmZmZszMzExEJEJERMuZmYiZiJiJiJmIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P//ZmZmZszMzMxERCRCRMyImYmYiYiZiJiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI/4iIZmZmZszMzMxMRERERMyZmJmImYiYiYiZiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4j/iIaGZmZry7zMzMzERExMyZiZmJmImImYiYiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4Zmb/ZmZmZry7u8zMzEZExsyYmZiZiJmImImImYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZmb2ZmZmzMbMu8vMzGZmxsyImYmZiZiJmJmImZmJiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhvZmZmZmbMzMzMu8zMzMzMZsyImImYmYiZiJmJmJmZiIiZiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhvZmZmZmbMzMzMzMzMzMzMzMyIiJmImYmYiZiZmJmJiYiYiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIhoZv9oZsbMzMzMzMzMzMzMzMyIiJiJmJmImYiZmZmJmIiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI/////8a8y8zMzMzMzMzMzMyJiIiZiJmJmImYmZmYiImImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P///2+8y8zMzMy8u8zMzMyYiImYiZiJiImImYmIiZiIiImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P+PiIjIu8zMzMy8u7y7y8yJiZiImYiZiJiImJmIiZiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI//+PiGhmu8zMzMzGzLy7u8yZmIiJmYmYiZiJiJmJmIiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI////j2ZmZszLzPb/Zma7u8yZiYmYmJmImYiZiJiZiImIiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI////j2ZmZry7zIb2aGZmZviZmYiYiZmJmImYiYiZiImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI+P/4/2Zm+MbLzGZmZmZmZmaZmYmImZiZiJmImYmYiZiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiP/4/2/2/2/MZmZmZmZmZmaZmZmImImZiZiJmImYmYiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI/4//9vZmZmZmZmZmZmZWaZmZmJmJmYiYiJmJmIiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4iI/4//9vZmZmZmZmZlVVVWaZiZmZiJmZmYiYiJmJiImYiImIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4iI//X2VmZmZmZmZmZmZmZmaZmZmZiJiImYmYmZmJiJiIiZiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4iIj/X1VVVVVVVWVmZmZmZmaZmZmYiZiJmJmImZmZiIiIiJiIiImIiIiIiIiIiIiIiIiIiIiIiIiIiIj4iIj/X/VfVVVVVWVmZmb4ZmaZmWmZmYiZiJmJmJmZiYiJmJmIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4iIj//4j/ZmZmZmZmZmZmZmaZmZmZmYmYiJmZiImYiYiYmZmJiJiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4iIj/iIj/aGZm9mZmZmZmZmaZmZmZmJmYiZiZiImYmYiImYmIiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIj4+Ij/iIj/iG//////b2ZmZmaZmZmZmZmJiZiZiZiImYmImYmYiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIj4+Ij//4j/iI//j///j/9mZmaZmZmZmZmZmIiZmYiImZmImJmIiYiYiIiIiIiIiIiIiIiIiIiIiIiIiIiI+Ij/iIj/iI//////j///ZmaZmZmZmYmZmYiZmYiJmJmImJmImYiYiYiIiIiIiIiIiIiIiIiIiIiIiIiI+Ij/+Pj//4//////j/9v9v+ZmZmZmZmZmYmYmYmJmJmZiJmJmIiIiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIj/+Pj//4//////j/9vZvaZmZmZmZmZmYmYmZmZiJmZiJmJmImImYiIiIiIiIiIiIiIiIiIiIiIiIiIiIj/+Pj//4//////j///ZmaZmZmZmZmZmZmZmZmZiZiZiZiZmIiImIiIiIiIiIiIiIiIiIiIiIiIiIiI+Ij///j//4//////////ZmaZmZmZmZmZmZmZmJmZiZiZmYiZiImImImIiIiIiIiIiIiIiIiIiIiIiIiI+Ij/j/j/+Pj/////////b2aZmZmZiZmZmZmZiZmZmYiZmYiZiImIiImIiIiIiIiIiIiIiIiIiIiIiIiIiI//iPj/+Pj/////j////2aZmZmZmZmZmZmZiZiZmYiZmYmYiZiIiJiIiIiIiIiIiIiIiIiIiIiIiIiIiI//iPj4+Pj/////iP////+ZmZmZmZmJmZmZmZiZmImYmYmYiZiJiJiIiIiIiIiIiIiIiIiIiIiIiIiPiI//iPiI//j/////iP////+ZmZmZmZmZmYmZmYmZiImYmZmImZiJiIiJiIiIiIiIiIiIiIiIiIiIiIiPiI/4iPiI/2hm////iP+P//+ZmZmZmZmZmJmYmYmZiJmImZmImYiZiIiJiIiIiIiIiIiIiIiIiIiIiIiP/4+IiPiI/2b2////+P+P//+ZmZmZmZmYmZmZmYmYiZiImZmJmYiYiIiIiIiIiIiIiIiIiIiIiIiIiIiIj4/4+PiIb2b2///4+P+P//+ZmZmZmZmZiZmJmZmYiZiJmJmJmYmIiIiYiIiIiIiIiIiIiIiIiIiIiIj4j4j4+P/4b2b////4+P+P//+ZmZmZmZmJmZmZmZmYmZiJmJmJmImIiIiIiIiIiIiIiIiIiIiIiIiIiIj4j4j4////Zmb///////+P//+ZmZmZmZmZmZiZmJmJmYiZmZmJmJmIiIiIiIiIiIiIiIiIiIiIiIiIiIj4j4j4//9vZvb///j/+P+P//+ZmZmZmZmZlpmZmZmJmYiZiJmZiJmIiIiIiIiIiIiIiIiIiIiIiIiIiPj4j4j4+P9mZvb///j///9vZmaZmZmZmZmZmYmZiZmZmImYiJmZiJmIiIiIiIiIiIiIiIiIiIiIiIiIiPj4/4j4+G9mZvb///j//29mZmaZmZmZmZmZmZmZiZmZmImYiZiZiZmJiIiIiIiIiIiIiIiIiIiIiIiIiPj4/4j4+GZmZvb//2b/aGZmZmaZmZmZmZmZmZmYmZiZiZmYiZiZiZiJiIiIiIiIiIiIiIiIiIiIiIiIiPj4j4j4b2ZmZvb/b2ZmZmZmZmaZmZmZmZmZmZmZmZiZiZmImYiZiZiZiIiIiIiIiIiIiIiIiIiIiIiIiPj4j4j4b2ZmZvZvZmZmZmZmZmaZmZmZmZmZmZmJmZiZiZiImYiZmZiZiIiIiIiIiIiIiIiIiIiIiIiIiPj4j4j4ZmZmVVVlZmZmZmZmZmaZmZmZmZmZmZmZmZiZiZiJmYmZmYiZiYmIiIiIiIiIiIiIiIiIiIiIiPj4j4j/ZmZmVVVVZmZmZmZmZmaZmZmZmZmZmZmZmImYiZiJmImYmZmZmYmIiIiIiIiIiIiIiIiIiIiIiPj/b2ZvZmZmZmZmZmZmZmZmZmaZmZmZmZmZmZmZmYmZmYiZmImYmZmZmYmIiImIiIiIiIiIiIiIiIiIiP9mZmZmZmZmZmZmVmVmZmZmZmaZmZmZmZmZmZmZmZmYmYiZmJmIiZiZmYmIiImIiIiIiIiIiIiIiIiIb2ZmZmZmZmZmZmZmVWVmZmZmZmaZmZmZmZmZmZmZmZmImYiZiZmIiZiZiJmIiIiIiIiIiIiIiIiIiIiIZmZmZlZVZmZmZlVmZmZmZmZmZmaZmZmZmZmZmZmZmZmJmYmYiZmJmYiZiIiIiJiIiIiIiIiIiIiIiIj4ZmZmZlVVVVVVZVVpZmZmZmZmZmaZmZmZmZmZmZmZmJmJmImYiZmJmIiZiImIiJiIiIiIiIiIiIiIiIj4ZmZmZmZVZlZllZlZVWVmZmZmZmaZmZmZmZmZmZmZiZmZmJmYmZiJmImZiYmIiIiIiIiIiIiIiIiIiIj4ZmZmZmZmZmZmZplVVWZmZmZmZmaZmZmZmZmZmZmZiZmZmJmImZiZmImYiZiIiIiIiIiIiIiIiIiIiIj4ZmZmZmZmZmZmZplpZmZmZmZmZmaZmZmZmZmZmZmZmZiZiJmJmZmZiImYiZiIiIiJiIiIiIiIiIiIiIhoZv//b8bMbGZmZplpZmZmZmZmZmaZmZmZmZmZmZmZmZiZiZmJmYmZiJmIiZiIiIiJiIiIiIiIiIiI+P//9v9vZszMzMxmlplpzMzMZmZsZmaZmZmZmZmZmZmZmZmZiJmJmYmZiZmImZiJiIiJiIiIiIiIiIiIb2Zm9m9mZszLzMxslpnGzLvLbMzMzGaZmZmZmZmZmZmZmZmZiZiZmJmZiZiJmIiJiIiYiIiIiIiIiIhoZmZmZmZmZry7zMzMZsy8u7vLzMzMzGyZmZmZmZmZmZmZmZmZiZiZmJmYiZiJmIiZiIiYiIiIiIiIiIhvZmZmZmZmZry7zMzMzMu8u7vMzMzMzMyZmZmZmZmZmZmZmZmZmYiZmZmYmZmJmJmZiIiYiIiIiIiIiPhmZv//b/ZmZsbMu8zMvLu8y8zMzMzMzMyZmZmZmZmZmZmZmZmZmYiZiZmZmZmZiJmZiIiYiIiIiIiIiPhv//+P/29mZmZmu8zMvLvMzMzMxszMzMyZmZmZmZmZmZmZmZmZmYiZmZmJmZmZiImYiYiIiIiIiIiIiIj/j4j4/2ZmZmbGzMzMzMzMbMxsZszMzMyZmZmZmZmZmZmZmZmZmYiYmZmJmZmZiYmYiYiIiIiIiIiIiIiPiPj//2ZmZmbMzMzMzMzMbGZmZmbMzMyZmZmZmZmZmZmZmZmZmYmYmZmZmZmZmYmYiYiIiIiIiIiIiIiIiP//b2ZmZma8y8zMzMzMZmZmZmbGzMyZmZmZmZmZmZmZmZmZmYiImZmZmJmZmZmYiIiIiIiIiIiIiIiI+P//aGZmZma8y8zMzGxGRGZmZmZmzMyZmZmZmZmZmZmZmZmZmYmImZmZmJmZiZmIiIiIiIiIiIiIiIj4/4//b2ZmZmbGzMzMZmZERGRmZmZmzMyZmZmZmZmZmZmZmZmZmZmIiZmZmZmZiJmIiYiIiIiIiIiIiIj//4j4j2hmZmbGzMxmZmZERERkZmZmzMyZmZmZmZmZmZmZmZmZmZmYmZmZmZmZiZiIiYiIiIiIiIiIiPj/iIj4/2ZmZmZmZmZmZiZCREREZmbGzMyZmZmZmZmZmZmZmZmZiZmYmZmZmYmZiZiJiYiIiIiIiIiIiPj/iIiIb2ZmhmZmZmb2ZiRCREJEZLa7zMyZmZmZmZmZmZmZmZmZmZmYmZmZmYmYiZiJiYiIiIiIiIiIiPj/j4j/b2ZvZmZmZmb2ZkREREJEZLu7zMyZmZmZmZmZmZmZmZmZmZmZmZmZmYmYmYiJmIiIiIiIiIiIiIj4j4j/ZmaGZmZmZmZmRiREQkREvLvLzMyZmZmZmZmZmZmZmZmZmZiZmYmZmZmImYiJmIiIiIiIiIiIiIiI/4hvZmZmZmhmZmZmJiIikkTEu7vMzMyZmZmZmZmZmZmZmZmZmZiJmZmZmZmImYiJmIiImIiIiIiIiIiI/4hmZmZmhmZmZmZmJiJCRJS8u8zMzMyZmZmZmZmZmZmZmZmZmZiJmZmZmZmImImJmIiImIiIiIiIiGZmZmZmZmZmhmZmZmZmRkQkRES8u8zMzGyZmZmZmZmZmZmZmZmZmZmJmZmZmZmJmYmYmIiIiIiIiIiIaGZmZmZmZmZmZmZmZmZmRkQkRES8y8zMzMyZmZmZmZmZmZmZmZmZmZmJmZmZmZmJmYmYiIiIiImIiIiIiGZmZmZmZmZmZmZmZmZmRkRERES8u8zMzMyZmZmZmZmZmZmZmZmZmYmJmZmZmZmJmZmYiIiIiImIiIiIiIhoZmZmZmZmZmZmZmZmZkRERGS8y8zMzMyZmZmZmZmZmZmZmZmZmYmZmZmZmZmJmZmIiIiIiImIiIiIiIiI/4+IZmZmZmZmZmZmZmZmZmbGzMzMzMyZmZmZmZmZmZmZmZmZmYmZmZiZmZmZmZmIiIiIiIiIiIiIiIiI+I9mZmZmlpmZaWZmZmZmZmhmzMzMzMyZmZmZmZmZmZmZmZmZmZmZmZiZmYmZmZmImYiIiIiIiIiIiIj4/29mb2ZmlpmZmWZmZmZmZmZmzMzMzMyZmZmZmZmZmZmZmZmZmZmZmZiZmYmZiZmJmYiIiJiIiIiIiIj//2b/ZmZmZpaZmWZmZmZmZmZozMzMzMyZmZmZmZmZmZmZmZmZmZmYmYiZmYmZiZmZmYiIiJiIiIiIiIj//2aGZmZmZmaZmWlmZmZmZoZmxszMzMyZmZmZmZmZmZmZmZmZmZmYmYiZmYmZiZmZmYiIiJiIiP//j2ZmZmb2ZmZmZmaZmWZmZmZmZmZmZszMzMyZmZmZmZmZmZmZmZmZmJmYmYiZmYmZmZmJmYiIiIiI+P9vZmZmZmb2ZmhmZmZZVWVmZmZmZmZmZsbMzMyZmZmZmZmZmZmZmZmZmZmYmYiZmYmZmZmJmIiIiIiI+P9mZmZmZmZmZmZmZlVVVVVVZmZmZmZmZmbMzMyZmZmZmZmZmZmZmZmZmZmYmYmZmYmYmYiJmYiIiIiI+PhvZvZvZmZmtrtsZlVmZmZVVWVmZmZmZmZmxsyZmZmZmZmZmZmZmZmZmZmJmYmZiYmYmYiJmYiIiIiI+P//j/9mZmZmu7vLZmZmZmZmV1VVVWVmZmZmZsyZmZmZmZmZmZmZmZmZmZmZmYmYmYmZmYiJmYiIiIiI+P////9mZmbGu8vMbGZmZmZmZmZWVWZmZmZmZsyZmZmZmZmZmZmZmZmZmZmZmYmYmYmZmYiJmYiIiIiIiP///29mZma2y8zMbGZmZmZmZmZmZmZmzGxmZsyZmZmZmZmZmZmZmZmZmZmZmYmYmYmZmYiJmYiImIiIiP///29mZma2u8zMzGZmZmZmZmZmZmbGzMxmxsyZmZmZmZmZmZmZmZmZmZmZmYmYmYmJmYiJmYiImIiIiIj/b2ZmZma2y8zMzGxmZmZmZmZmZmbGzMzMzMyZmZmZmZmZmZmZmZmZmZmZmYmYmZmJmImImYiImIiIiPj/b2ZmZmZmzMzMzMxsZmZmZmZmZpnMu8zMzMyZmZmZmZmZmZmZmZmZmZmZmYmYmZmJmImIiYiImIiI+P//aGZmZkRmZszMzMzMiGZmZmZmZpnMu8zMzMyZmZmZmZmZmZmZmZmZmZmZmYmYmZmJmImIiYiImPj///9vZmZmRERkZsbMzMzMZmZmZmZmZpa8u8zMzMyZmZmZmZmZmZmZmZmZmZmZmYmYmZmZmImIiYiImP////9mZmZmRETEzMbMzMzMZmbMzMzMzMy8u8zMzMyZmZmZmZmZmZmZmZmZmZmZmYmYmZmIiImIiYj/n////2hmZkREJCJEu7vMzMzMzMzMzMzMzMy8u8zMzMyZmZmZmZmZmZmZmZmZmZmZmYmYmZmIiImIiYj/b/j/j2ZmRkREJES0u7vMzMzMzMzMzMzMzMy7zMzMzMyZmZmZmZmZmZmZmZmZmZmJmYmYmZmIiImZiYj///9oZmZmRkQiIkRExMzMzMzMzMzMzMzMzMy7y8zMzMyZmZmZmZmZmZmZmZmZmZmImYmYmYmIiYiZifiP+GZmZmZmRkQiQkRExMzMzMzMzMzMzGZcVVW1y8zMzMyZmZmZmZmZmZmZmZmZmZmImYmYmYmIiYiZifiPZmZmZmZmZkQiIkRExMy7y8xVVVVsVlVVVVVVZsbMzMyZmZmZmZmZmZmZmZmZmZmImYmYmYmZiYiZifhmZmZmZmZmZklEQkRExFVVVVVVVVVVVVVmZmZmZmbMzMyZmZmZmZmZmZmZmZmZmZmImYmYmYmZiZiZiW9mZmZmZmZmZkREIkREzFtVVVVmzMxWZWZmZma2bGbGzMyZmZmZmZmZmZmZmZmZmZmImYmYmYmZiZiZiW9mZmZmZmZmZkREImZmtrtsZmZmZmZmZmZmZmZmxmxmzMyZmZmZmZmZmZmZmZmZmZmImZmYmYmZiZiZiW9mZmZmZmZmZkREZGZmxrvMzGxVZmZmZmZmZmZmZmZmZsyZmZmZmZmZmZmZmZmZmZmImZmYmYmZiZiZ+WZohmZmZmZmZkREZGZmZszMzFVVZmZmZmZmZrZrZmZmZsyZmZmZmZmZmZmZmZmZmZmImZmYmZmZiZiZ+WZmZmZmZmZmZkZEZmZmZsbMVlVmZmZmZmZmZsbLzMzMzMyZmZmZmZmZmZmZmZmZmZmImZmYmZmZmZiZ+WhmZoZoZmZmZmZmZmaGaGZmWGZmiGZmZmZmZsbMzMzMzIg="}},"storySprites.sky":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAACZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR0d3d3ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRnR3d3d3d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGdHdEREREd2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEd0REREREd2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZ3R0REREREd2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnR3RERERER0R2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRnRHRERERER0R2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRndEREREdHd3RGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdEdEREREdHdHRGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGdEdERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGdERERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEd0RERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEd0RERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEd0RERERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEd0RERERERER0d2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZER0RERERERHR3d2dmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZEd0REREREdHd3RHdmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGd0REREREd0dERHdmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGd0RERER0d0RERHdmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGd0RERER3R0REdEdmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGd0RERER3REREd3RnZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdERERER3RERERHR3ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdEdERER3RERERER3Z2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdEdERER3RERERER0Z2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRndERER0R0REREREd2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRndHRER0R0REREREdFVVVVVVVVVVZSZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkR3REREd0RERFRVVVVVVVVRERUVfKdmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdnd3REREd0REVVVVUVEREREREREJPLvmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd0dEREREdFdVVVFREREREREREREIpnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ2d0REREREVVVVUREREREREREREQkkpnpnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3RERERERVVVFREREREREREREREQimZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERERFVVURERERERERERERERCSSmZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZndEREREVFVRERERERERERERERERCSSmZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZndERERUVVERERERERERERERERERCKSmZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdkdERERVUVEREREREREREREREREJCKSmZmZ7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmdEdERFRVUREREREREREREREREREJCKSmZmZ7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd0RERFVRUREREREREREREREREREIiKSmZmZ7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmd0REVFFREREREREREREREREREREIiKSmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGd0REVVEREREREREREREREREREREIiIimZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGR0RUUVEREREREREREREREREREQkIiIimZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGR0RVUREREREREREREREREREJCIiIiIimZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGR1RVURERERERERERERERCIiIiIiIiIikpmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGR1RRUREREREREREREQkIiIiREREIiIikpmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGd1VRERERERERERERCIiIkREREREIiIikpmZ6Z6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGVFFREREREREREREIiJCREREREREIiIi4pmZ6Z6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZGVFFRERERERERCQiIkREREREREREIiIi7p6ZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVEREREREREJCJCREREREREREREIiIimZ6ZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVEREREREREIkJEREREREREREREIiIimZ6ZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWUVEREREREQiQkREREREREREREREJCIimemZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWURERERERCIiREREREREREREREREJCKSmemZme6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZVUREREREJCJEREREREREREREREREJCKSmemZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZVUREREREIkJEREREREREREREREREJCKZmZmememZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZRUREREQkQkRERERERERERERERERERCKZmZmememZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZRURERCQiRERERERERERERERERERERCKZmZnpmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZRERERCJCRERERERERERERERERERERCKZmZnpmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlVREREJCJERERERERERERERERERERERCSZmZnpnumemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlVREREIkJERERERERERERERERERERERESZmZmZnpmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlVREQkIkRERERERERERERERERERERERESUmZmZnpmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVlFREQkQkRERERERERERERERERERERERESUmZmZ6ZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVlFREQiREREREREREREREREREREREREREREmZmZ6ZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVlFRCRCREREREREREREREREREREREREREREkZmZ6ZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVERCJERERERERERFRVVVVVVVVVVVVVRURElJmZ6Z7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVEJCJERERERERVVVVVVVVVRERVVVVVVVVFRJmZmZ7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVEJEJEREREVFVVVURERERERERERERERFVVRZmZme7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVEIkRERERVVVVERERERERERERERERERERERf6VmenpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVUkQkREVFVVRERERERERERERERERERERERERP/umenpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmUUkQkRUVUVERERERERERERERERERERERERE1JmZ7umenpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmUUiRFRVRUREREREREREREREREREREREREQU0Z2Z6Z7unpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWUUiVFVFREREREREREREREREREREREREREQR0Z2Zme7pnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWSVSVUVERERERERERERERERERERERERERBER0ZmZmZnunpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmUVSRUREREREREREREREREREREREREREJBER0ZmZmZnp7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVVREREREREREREREREREREREREREREJBER0ZmZmZmZ7p6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVVEREREREREREREREREREREREREREREIhER3ZmZmZnu7p6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVUiREREREREREREREREREREREREREQkIhER3ZmZmeme6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVQiQkREREREREREREREREREREREREQkIhER3ZmZmZ6Z7pmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSQlIkREREREREREREREREREREREREQiIhER3ZmZ6ZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJFIkJEREREREREREREREREREREREQiIhIR3ZmZnpmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJVRCJEREREREREREREREREREREREQiIhIRnZnpmZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJVRCQiREREREREREREREREREREREQiIhIRnZmemZnpnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJURUQiQkRERERERERERERERERERCQiIhLRnemZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJURUREIiJERERERERERERERERERCQiIhLR7ZWZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJEVUREJCIiRERERERERERERERERCQiIiLRnpmZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJEVUREREQiIkJERERERERERERERCQiIiLunZmZmZnumZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlEVEVEREREIiIiRERERERERERERCQiIiLfnZmZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRFVERERERCQiIkJERERERERERCQiIhLRnZmZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRFVEREREREREIiIiQkRERERERCQiIhHRnZmZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRFRFREREREREREQiIiIiQkRERCQiIhHRnZmZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRERVRERERERERERERCIiIiIiQiQiIhHRnZmZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRERVRURERERERERERERERCQiIiIiIhER3ZmZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkiRERURURERERERERERERERERERCIiIhERkZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkiREREVURERERERERERERERERERCQiEhERkZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkiREREVEVEREREREREREREREREREQiEhERkZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkpQkREVFVEREREREREREREREREREQiEhEREZmZmemZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkpQkRERFVFREREREREREREREREREQiEhEREZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZIkRERFRVREREREREREREREREREQiEhEREZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZIkRERERURUREREREREREREREREQkEhEREZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZKUJEREREVUREREREREREREREREQkEhEREZmZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJEREREVEVEREREREREREREREREIhEREZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSJERERERFVFREREREREREREREREIhEREZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRERERFRVREREREREREREREREJBEREZmZ6ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmSlCRERERERUVUREREREREREREREJBIREZmZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkiREREREREVUVEREREREREREREJBIREZGZnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZktQkREREREVFVFRERERERERERERETR3d2dnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZktQkRERERERFRVRURERERERERERETUHdHdnpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRIkRERERERERUVUVEREREREREREREERHtnZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRIUJEREREREREVFVVREREREREREREERHhnZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRESJERERERERERFRVVUVEREREREREFBHu3ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRES1CREREREREREREVFVVRURERERERBHu3ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREd0iREJERERERERERERVVVVFRERERBTu35mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREREhIkJERERERERERERERFVVVUVERETx35mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRERHRIkIkREREREREREREREREVVVVVUUi0Z2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRERHdESIiRERERERERERERERERERVVSUi0Z2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREdEdESkiQkRERERERERERERERERERCIU0Z2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREd0dEZkpIiIiREREREREREREREREJEIR0Z2ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZ0d0REZmZKSJCJCJEREJEREREREREIhQREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZ0R0REZmZmSkiIkJEJCJEREREREQkQhEREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZ3REREZmZmZkpIiIiIkQkIkREREQiFBERkZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZ3RERkZmZmZmZmSIiIiIiQiQiQiRCERERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdIiIiIiIiRCQSERGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdEREhIiIiIiIUERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdEREREREiItIREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdEREREREREd0REZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdEREREREREd0REZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdERERERERER0REZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmdkdERHRERER0R0REZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmRndEdHdHRERER0REZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmZkREd0d3REREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnZHRERkZmZmZmZmZkR0R0R3REREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRERkZmZmZmZmZkZ0R0R3REREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRERkZmZmZmZmZkZERER3REREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRERkZmZmZmZmZkZERER3REREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRERkZmZmZmZmZkZERER3REREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRERkZmZmZmZmZkZERHRHREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRnRHRERkZmZmZmZmZmZERHRHREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRnRERERkZmZmZmZmZmZERHdEREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkRERERkZmZmZmZmZmZGRHdEREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkRERERkZmZmZmZmZmZGREdEREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkREd0dkZmZmZmZmZmZGdEdEREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkR0d3dkZmZmZmZmZmZmdEdEREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmRkR3RHdkZmZmZmZmZmZmdEdEREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRHRkZmZmZmZmZmZmdEREREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZnRHRERkZmZmZmZmZmZmdEREREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRHRERkZmZmZmZmZmZmdEREREREREREZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRHRERkZmZmZmZmZmZmd0REREREREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR3RERkZmZmZmZmZmZmd0RERERERERkZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR3RERmZmZmZmZmZmZmdERERERERERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR3RERmZmZmZmZmZmZmdERERERERGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR3RGRmZmZmZmZmZmZmdERERERERGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkR3RGZmZmZmZmZmZmZmdEdEREREZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkRERGZmZmZmZmZmZmZmdkdERERkZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREZGZmZmZmZmZmZmZmZndERERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkREZmZmZmZmZmZmZmZmZndHRERmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkZkZmZmZmZmZmZmZmZmZnZ3RGRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ3ZGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZk="}},"storySprites.castle":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAACZmZmZmZmZmWlpZpmZmWZmZrtLREREREREREZERO/b7//////fu7u7y828u7u7zN27u7u7zMy7vL3b3dSZmZmZmZmZmZmZmZmZmWZmZmZLRERERERERDRERP/+///////fvbu7y727u7vb3by7u7u7zMzM3L3U1N2ZmZmZmZmZmZlpmZmZmWZmZmZGS0RERERERERERP/////////Pvbu7vLu7u7u7zbu7u7u7zMzM3Ovb3d2ZmZmZmZmZmZmZmZmZmWlmZmZLRkRERERERERE5O7////////P3bvL3Lu7u8y9y7u7u7vLzMzM3OvU3d2ZmZmZmZmZmWmZmZmZmWlmZmZmS7RERERERNTd6/7////////P383L3LvMu9y8zLu7u7vLzMzM3O0z3d2ZmZmZmZmZmZmZlpmZaWZmZmZmRGRGZEZERNTt7v//////////vMvL3LvMu9u7vLu7u7vLzMzMzE3d292ZmZmZmZmZmZmZmZmZaWZmZma7u2ZmRGRERNTt7+/+////////u8vL3LzMy9u7zLu7u7vLzMzMvLTd3d2ZmZmZmZmZmZmZmZmZmWZmZma7RLRrRERERN3d/t/9////////z8vLvLzMy9u7zLvMu7vLzMzMvETU3d2ZmZmZmZmZmZmZmZmWmWZmZrtGS0RERETU3d3r7u///////////8vMu7vMy9y7y7vMy7u7zMzMvEvU3dSZmZmZmZmZmZmZmZmWaWZmZmZERERERETU3d206+7////////8/8y8u7vMy7y7u7u8u7u7zMvMvETd3d2ZmZmZmZmZmZmZmZlpmWZmZrtLS0RERETU3dPd7v7//////////8zMu7vMy7y7u7u7u7u7zMvMvERL3USZmZmZmZmZmZmZmZmZaWZmZmZrRkRERERE3d1N5P7//////////8zMu7vMy7y7u7u7u7u7zMvMu0vU3USZmZmZmZmZmZmZmZmZZpZmZrtGS0RERERE3d1N3f7/////////z8zMu7u8y7y7u8u8u7u7y7vMu0Td3USZmZmZmZmZmZmZmZmZZplmZrZERERE//9E3UQ9RP7/////////z8zMvLu8u8y7u8u7u7u7y7vMu0Td3d2ZmZmZmZmZmZmZmZmZmZlmZmZLRGRGRP//3dRN6///////////z7zLzLu8u8y7u8u7u7u7y8zMS0Td3d2ZmZmZmZmZmZmZmZlmmWlmZmZrRGRGRNTzT93tTv//////////zLzLzLu8u8y7u8u7u7u7y8zMS9Td3dSZmZmZmZmZmZmZmZlpmWZmZra2RGRGRNRL/f//////////////zLvMzLu7u8y7u8u7u7u7y8zMS9RN3d2ZmZmZmZmZaZaZmZmZZmZmZmZmS0Rk1P/////9///////////PzMzMzLu7u8y7u8u7u7u7y8y8u0RERN2ZmZmZmZmZaZmZmZmZmWlm3d29ZGZERN80REb9RP7////////PzMzMy7y7u8u7u8u7u7u7y8y8S9vd3TSZmZmZmZmZmZlpmWlplplmvcvLS0tERDQ09P/fRP/////////MzMu8u8y7u8u7u8u7u7u7y8y8uzTU3d2ZmZmZmZmZmZmZaZlplmm2vcvLzExkRkv//9/dRP///////8/MzMy8zMy7u8u7u8y7u7u7y8y8uzTU3d2ZmZmZmZmZmZmZmZlmmWmZu8u7vMxERkT/RNRERP7////Pv8vMzMy7zMu8u8u8u8y8u7u7u8y8u9Td3d2ZmZmZmZmZmZmZmZmWmZlmu8u7vMvM3d3Nu8vMzMzMzMzMzLy8u8y8y7u7u8u8vMy8u7u728y8S9tN1N2ZmZmZmZmZmZmZaZmZlpmZ+7+7vLzMvby7u7vMzMzMzMzMzLvMu8y8y7zMu8vMzMy8u7u728y8S9Td3d2ZmZmZmZmWaZmZmZmZlpmZ2fu7vLzMu8y7vLu7y7u7u8vMvLvMy8zMy7zMy8vMzMy8u7u728y7u9Td3d2ZmZmZmZlmZpmZmZmZaZmZvcvLvLvMu7u7vMy8zMu8y8zMvLvLvMvMzLy8y8zLzMy8u7u728y7u9Td3d2ZmZmZmZlmlpmZmZmZmZmWvcu7vLvMy7y7u7u7u8u8u7y7y7y7vMvMzMy8y7zLzLu8u7u727y7S9Td3d2ZmZmZmZmZmZlpmZmZmZaZ3cvLzLzMy7y7u7u7u7u7u7u7y8u8zMvMvMy8y7zMzLu7u7u7y7y7u9Td3d2ZmZmZmZmZmZmZmZmZmWmZvcvLvLzMu7vMu8zMzMy7y7y7vMvMy8vMzMy7y7zMzLu7u7u7zby7S9Pd3d2ZmZmZmZmZlpmZmZmZmWlptsvLvLvMu7vLy8zMzMy7zLy7vLu7y8vMzMy7y7zMzLvMu7u7zby7u9Td3d2ZmZmZmZmZmWmWmZmZmZmZubu7vLvMu8y7y7zMzMy7zLu7u8u8u8vMvMy8zLzMvMvMu7u7zby7u+Tb3d2ZmZmZmZmZmWmWmZmZmZmZuba7vMvMu7y7y8zMzMy7u7vMu7u8u8vMzMy8zMzMvMzMu7u7y7y7S0Td3d2ZmZmZmZmZmWmWZpmZmZmZvcvLvMzMzLzLvMzMzMy7u7vLvLu7u8vMu8u8zMzMvMy8u7u7y7y7S93U3U2ZmZmZmZmZmWmWZpmZmZmZvcvMvMzdu7vLvLu7u7vMu7vLvLu8y8zMy8zMzMzMvMy7u7u7y7zrTt3d3d2ZmZmZmZmZmZmZub2ZmZm5u8u7zEzdy8y7u7u7u7vMu8u8u8u8zMvMy8zMzMzMvMy7u7u7y7zLTt3d3d2ZmZmZmZmZmZlm3cuZmZlpubvLvPS9zMzMu7y7vLu8u8y7u8u8vMy7y8zMzLzMu8zMy7y7y7vM3N3d3d2ZmZmZmZmZmcndvMvMu7uZa0ZERP+9zETMu8zLvLy7u8u7u7u7u8y7y8zMzLzMy8zMy7u7y7vM3N3d3d2ZmZmZmZmZ2d3MvMzMu8tsS0RERE+7zMS7u7zLu7y7y8zMzMzMzLzMy8zMzMzMy7zMy7u7u7vMS93dTd2ZmZmZmZnZ3cvLvMy8zMu8uUtES2S7zMy7u7vLu7vMzMzMzMzMzLzMy8zMzLzMy7zMy7u7u7u8S93d092ZmZmZmd29y8zLvMy8u8vMzLu7zMzMzMy7u7vLu8zMzMzMzMzMzLzMy8zMzMzMy8y8y7u7u8u83d3d3d2ZmZmZ3b3Mu7zLu8y8u8zMzLu8y8zMzLvMy7zLy8y7u7u7u7u7u7vMy8zMzMzMzMy8y7u7u8vcRNTd3d2ZmZmZzczMzMzMu8y8vMzMu8u8u7u7y7u7y7y7zMzMzMzMzMzMzLzMy8y8zMzMzMy8y7u7u8u7S93d3d2ZmZmZubvMzLzLu8y8vMzMu7u7u7y7y8u8u7vLvLu7u7u7u7u7u7vMy8y7zMzMzMy8y7u7u8y73d3d3d2ZmZmZmbnMy8zLu8y8u8vMu8u7u7y7u8u8u7vLzMzMzMzMzMzMzLzMy8y7zMzMzMy8y7u7u8y73d3d3d2ZmZmZmZm5u8vLvMzMu8vMu8u7u7u7u7u7y7zMu7u7u7u7u7u7u7vMy8zLzMzMzMy8y7y7u8y7u93d3d2ZmZmZmZmZucvMvMzMu8vMy7zMzMzMy7u7y7zMzMzMzMzMzMzMzLzMy8zLzMzMzMy8y7y7u7y7S93d3d2ZmZmZmZmZmcnMvMvMu8u8z8zMzMzMzMzMy7vMu7u7u7u7u7u7u7vMy8zLzMzMzMzMy7y7y7y73d3d3d2ZmZmZmZmZmWm7vMvMu7tp27vLzERE3by7u7vLzMzMzMzMzMzMzLzMy8zMzMzMzMzMy7y7y7y7O93d3d2ZmZmZmZmZmZmZu7tmZmb227vLTERENL27u7u7zLy7u7u7u7u7u7vLu8vMzMzMzMzMzLy7y7y7u93d3d2ZmZmZmZmZmZmZtrtmZmZm3bzMRES01MzLu8y7y8zMzMzMzMzMzMzMzMy8zMzMzLzMzLy7y7u7293d1N2ZmZmZmZmZmZmZmWZmZmZmvbvM+0+03czLvMy7u8zMzMzMzMzMzMzMzMzMzMzMy8zMzLu7zMu7093d1N2ZmZmZmZmZaZlpZmZmZmZmvbvMRE9E3czMvMy7y7y7y8zMzMzMzMzMzMzMzLzMvMzMzLu7zMy7293dRN2ZmZmZmZmZlpmZZmZmZmZmvczLTETdT8y7u7u7y8y7u7u7y8u7u7vMzMzMzMzMvMzMzLu7zMy71N3d3d2ZmZmZmZmZmdnd3W1mZmZmu7vL7LT//8zLu8u8u7u7u8u7zMy8u7vLzMzMzMzMvMzMzLu7zMy71N3d3d2ZmZmZmZmZmdnLu7zLZmZmtru7zNzd/czLu8u8u7vMu8u7zMu7y8zLzMzMzMzMvMzMzLu7vMy71N3d3d2ZmZmZmZmWmdnLzMzMa2Zmtry7u7y7u8zMvMzMzLzLu7u7u7u7u7vMzMzMzMzMvMzMzLu7vMy73d3d3d2ZmZmZmZmZmdnNy7zMu93Ntsy8u7u7u8zLy8zMzMzLvLvLvLu7u7vLzMzMy8zMvMzMzLvLvLy73dTd3d2ZmZmZmZmZmdm7u7u7y8zMy8zMy8zMzMy7y7zMzMzLvLzLvLu8u7vLzMzMy8zLvMzMzLvLzLy73d3d3d2ZmZmZmZmZmZmZmcu8zMy7u7u7u8vMzLzMy8zMzMy7u8zLvMu8u8vMvMvMy8zLvMy8zLu7y7y7RN3U3d2ZmZmZmZmZmZnZ3c28y7y7vLu7vLu7y7vMu8zMzMy7u8y7u8u8u8vMvMzMy8zLvMy8zLu7y7y7RN091N2ZmZmZmZmZmWndvMy8y7y7vLu7u7u7y7y8u7u7u7u7zLu7u8u7u8vMzMzMy8zLzMy8zLu7y7y7RN3d3d2ZmZmZmZmZmZnNvLy8y7y8u8y7u8u8y8u8y7y8y8y7y7y7vLu7u8zMzMzMy8zLzMy8zLu7y7y7293d3d2ZmZmZmZmZmZnJvLu8zLzMu8zLvLu7y7u8zLy8vMy7u8y7vLu7u8zMzMzMy8zLzMy8zLu7y7u7293d3d2ZmZmZmZmZmZmZacvMzLzLu7vLvLu7u8u8u7vLvLu7zLvLvLu7zMzMzMy8zMzMzMy8zLu7y7u7293d3d2ZmZmZmZmZmZnZ3czMy8zLu7vLzMzMzMzMzMzMzMzLzLvLu7u7zMzMzMy8zMzMzMy8zLu7y7u700vd3d2ZmZmZmZmZmdndu7zMu8zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMy8zLu7zMu81N3d3d2ZmZmZmZmZmbnNvMzMu2Zmy0xERPRP1N3d3d3dTd3d/8zMzMzMzMzMzMzMzMzLzMy8zLu7u7u8RE1E3d2ZmZmZmZmZmbnLy7zLa2Zma7tERPRP1N3d1P3/Td3d/8/MzMzMzLzMzMzMzMzMzMy8zLu7u8vMS93d3d2ZmZmZmZmZmbm7y7zLZmZmZrtERET/1E3dTf//393d/f/PvMzMzMzMzMzMzMzMzMu8zLu7u8zM293d3d2ZmZmZmZmZaZlpZmZmZmZmtmZGRERP1D3d3f3d////////zMzMzMzMvMzMzMzMzMu7zLu7u8zM3d3d3d2ZmZmZmZmZmZlpZmZmZmZmtmtERERk1E1N3d3d///9////zLzMzMzMzMzMzMzMzMy7zLvLu8zL3U3d3d2ZmZmZmZmZmZmZmWaZZmZmtrRERGRmTdRN3d3d3d3d/f//zLvMzMzMzMzMvMzMzMzMvLvLu8zL293d3d2ZmZmZmZmZmZlpmWlmZmZmtrS0tkRE3d3d3d3d3d3d////z7y7zMzLzMzMzMzMzMzMu7vLu8zL293d3d2ZmZmZmZmZmZaZmWZmZmZmtrS0RkRE1N3d3d3d3d3d////z8y7y8y8zMzMzLzMzMzMu7vLu7y73N3d3d2ZmZmZmZmZmZmZmWaWZmZmtkZLRERGNN3d3d3d3U39///////MzMzLzMzMzMzMzMzMu7vLu7y7u93d3d2ZmZmZmZmZmZmZmZmWZmZmZkZLRERETfRP3d3d3f///////8/My8zMzMzMy7zMzMy8vLvLvLy7NN3d3d2ZmZmZmZmZmWmZmZaWaWZmZka0RERmS/3//////////////7/My8zMzMzMy7zMzMy7zLvLzLy7NN3d3d2ZmZmZmZmZmZaZmZaZaWZmZra7ZERENN3//////////////8/MzMzMzMzLzLzMzMy8zLvLzLy7293d3d2ZmZmZmZmZmZmZmZmZZmb2Zma2REZE9P///////////////8/MzMzMzMzLzLzMzMy8zLvLy7y7293d3d2ZmZmZmZmZmZlpmWlmlmb2/2/////////f3d3//////////8/LzMzMzMzMzLzMzMy8zLvMy7y7S9Td3d2ZmZmZmZmZmZmZaWaWZmZmZma2S0T0/9/d1N3d3d3////////MzMzMzLzMzLzLzMy8vLvMy7y7RNTd3d2ZmZmZmZmZmZmZaWaWaWZmlma2S0T0P9tN3d3d3d39///////PzMzMzMzMvLvMzMy8u7vMy7y7RN3d3d2ZmZmZmZmZmZmZmWlmmWZmZmZr9v9PRN3d3d3d3d3d///////PzMzMzMzLvMvMzMy8u8u8y7y7S9Td3d2ZmZmZmZmZmZmZmWlmZmZmZmb//09ERN3d3dTd3d3d///////PzMzMzMzMzMvMzMy8u8u8y7u720TU3d2ZmZmZmZmZmZmZmWlmZmZmZmZmtkRLRN3d3d3dTd3d/f/////My8zMzLzMzMzMzMy7u8u8y7u7003U3d2ZmZmZmZmZmZmZmZmZlmZmZmZmu0ZERP3/3d3dTdTd/f////+8y8zMzMzMzMzMzMy7u8y8y7u71N3d3d2ZmZmZmZmZmZmZmZaWZmZmZmZmu2u7tNT/393d3d1N/P////+8y8zMzMzMvMzMzMy7u8y8zLu7RN3d3d2ZmZmZmZmZmZmZmWaWZmZmZmZmu2tLtN3d///d3d3d/P/////Pz8y8zMzMzMzMzMy7u8y7y7u7RN3d3d2ZmZmZmZmZmZmZmZaZaWZmZmZmtru7a91N3f//3d27/f//////zMzLzMzMzMzMzMy7u8y7u7u7O93d3dSZmZmZmZmWmWlpmWaZaWZmZmZmtrtru9Pd3d3////////////Pu8zLzMzMzMvMzMy7u8y7u7u7RN3dTd2ZmZmZmZmZmZmZmZmWaWZmZmZmZkZr1t3d3f//////////////v8y7vMzMzMzMvMy7u8y7u7u7RNTd3d2ZmZmZmZmZmZmZmZmZZmZmZmZmZrZrSz3dTd/d3f//////////vLy7vMy8zMzMvMy7u8y7u7u7RNTd3d2ZmZmZmZmZmZmZmZmZZmZmZmZmZmZr1tvd3d3d3d39////////v7y7vMzMzMzMvMy7u8y7u7u7RN3d1N2ZmZmZmZmZmZmWmWmWmWZmZmZmZmZmlt3d3d3d3d3d/f//////z8y7zMzMzMzMvMy7u8y7u7u7RN3d3d2ZmZmZmZmZmZmZmWmWaWZmZmZmZrZmZt3d3d3d3d3d+////////7y7y8zMzMvMvMy7u7y7u7u7RN3d3d2ZmZmZmZmZmZmZmWmZaWZmZmZmZmZmZt3d3d3d3b3b/f///////8+8y8zMzMvMvMy7u7y7u7u7S93d3d2ZmZmZmZmZmZmZmZmWaWZmZmZmZma7RN3d3d3U3d3c/f///////8+8zMzMzMvMzLy7u7y7u7u7RN3d3d2ZmZmZmZmZmZmZmZaZmWZmZmZmZrb0T7vd3d3d/////////////7/MzMvMzMvMzLy7u7y7u7u769vd3d2WmZmZmZmZmZmZmZmZZmZmZmZmZmv/T93d3f3//////////////8/MzMvMvMu7zLy7y7y7u7u7Tt3d3d2WmZmZmZmZmZlpmZlpZmZmZmZm9v9vRNTU3f3f3d3d/f///////8/LvLu7y7y7zLy7y7y7u7u75NTd3d2WmZmZmZmZmZmZmWlmZmZmZmZm9rtERNTU3d3d3U3d9P///////8/LvLu7y7y7zLy7y7y7u7vLRN3d3d2WmZmZmZmZmZmZmZmZmZZmZmZm9ktkRNbU1t3d3d3d/////////8+7u7u7y7y7zLy7y7y7u7vLTt3d3d2WmZmZmZmZmZmZaZaZaWZmZmZm9r+01N3d293d3d39///////////LzLu7y7y7y7y7y7y7u7vM7NPd3d2WmZmZmZmZmZmZmZlpZmZmZmZmZv9P1N3d3d3d3d3///////////+7zLu7y7y7y7y7y7y7u7vMzN3d3d2ZmZmZmZmZmZmZmZmZlmZmZmZmZv////////////////////////+/y7y8y7y7y7y7y7y7u7vMvN3d3d2ZmZmZmZmZmZmZmZlplmZmZmZmZmb///////////////////////+8y8y8u8y7y7y7y7y7u7vMzNPd3d2ZmZmZmZmZmZmZmZmZaWZmZmZmZrZE//////////////////////+8y8y8y8u8y7y7y7y7u8vM7NTU3d2WmZmZmZmZmZmZmZmZaWZmZmZmZrb0//////////////////////+8y8y8y8u7y7y7y7y7u8vM7Nvd3d2ZmZmZmZmZmZmZmZmZaWZmZmZmZrb/T0Td//////////////////+8y8y8zMy7y7y7y7y8u8vM7DPdTd2ZmZmZmZmZmZmZaZmZmWZmZv////9vbWTd3d3d3f3///////////+8u8u7zMy7y7y7y8y8u8vLzNvd3d2ZmZmZmZmZmZmZaZmZmWZmZvZvZva2PdTd3d3d3d39///////////M28u7zLy7zLy7y8y8u8vLzNvd3d2ZmZmZmZmZmZmZmZmZmWZmZmZmZm9G201NRN3d3d3////////////Pvcu7zLy7zLy7y8y8u8vLzN3d3d2ZmZmZmZmZmZmZmZmZaWZmZmZm/2ZLS0RLRN3d///////////////Pu8y7y7zLzLy7u8y8u8vMzL3U3d2ZmZmZmZmZmZmZZpaZZmZmZmb2b2a7u0S0tN39///////////////Pu8y7y7zLzLy7u8y8u8zMvL3U3d2ZaZmZmZmZmZmZZpZplmlmZmZmZma21NtNRN3d3f3////////////Pu7y7y7vLzLy7u8y8u8zMzLxN1E2ZmZmZmZmZmZmZZplpaWZmZmZmZmZmRE3d1N3d3f//////////////zLy7zLvMzLy7u8y7u8zMzNzd3U2ZmZmZmZmZmZmZlplpZmZmZmZmZmZm1N3d3d3d3f//////////////z7y7zLvMy7y7u8y7u8zMzLzd3d2ZmZmZmZmZmZmZmZZplmZmZmZmtmZm293d3d3/////////////////zLy7u7vMy7y7u8y7u8zMzLzd3d2ZmZmZmZmZmZmZaZmZaWZmZmZmZmZmZt3d1N3d////////////////zLy7u7vMzLy7u8y7u8vMzNzd3d2ZmZmZmZmZlpmZZpaZaWZmZmZmZmZm293d3d3/////////////////zLu7u7vMzMy7u8y7u7vLzNzd3d2ZmZmZmZmZmZmZlmmZaWZmZmZmZmZm9v//3f3/////////////////z7y7u8u8zMy7u8y7u7vLzNvdTdSZmZmZmZmZmZlplpmZlmZmZmZmZmb/////////////////////////z7y7u8u8zMy7u8y7u7vLzLvd3d2ZmZmZmZmZmZlmmZmZmWZmZmZmZmZva9Td/f//////////////////vMzLu8y7zMu8u8y7u7vLzLzd3d2ZmZmZmZmZmZlpaZaZaWZmZmZmZmZmZpbW3f3////////////////Pu8zLu8y8u8u8u8y7u7vLzLzb3d2ZmZmZmZmZaZlmlmlmZmZmZmZmZmZma9bW3f3/////////////////u7vMu8y8u8u8u7u7u7vMzLzd3d2ZmZmZmZmZmZlmZpZpZmZmZmZmZma7a9nd3f/////////////////Pu7vMu8y8u7u8u7u7u7vMzLzb3d2ZmWmZmZmZmZmZmZmZaWb2ZmZmZmZG3d3d/f/////////////////Pu7vMvMzMu7u8u7u7u7vMzLzd3d2ZmZmZmZmZmZmZmZlpaWb2/2ZmZmZL+//////////////////////Mu7vMzMzMu7u8u7u7u7u7zMzd3d2ZaZmZmZmZmZmZmWmWZmZm/2ZmZru7vd39////////////////////u7vLzMzMu7vMu7u7u7u7zLzd3d2ZmZaZmZmZmZmZmZaWZmZm9m9mZkZkS/3//////////////////8/MvLu7zMzMu7vMu7u7u7u7zMzd3d2ZmZmZmZmZmZmZmZmZ////ZvZvtkZL8////////////////////8/MvMy7zMvMu7vMu7u7u7u7zMzb3d2ZmWmZmZmZmZmZmWn/b2b2/2b/v0T////////////////////////MzMy8zMzMu7u7u7u7u7u7zMzd3d2ZmZmZmZmZmZmZmWmfaWZm9m/////////////////////////PzP/MzMy8y8y7u8vMu7u7u7u7zLzb3d2ZmZmZmZmZmZmZlmlmZmZmZv/////////////////////////cvbzLzMy8y8y7u8vMu7u7u7vLzLw73d2ZmZmZmZmZmZmZmZmZZmZmZmZmZkT//////////////////8y9u7vLvMy8y8y8u8vMu7u7u7vLzLs93d2ZmZmZmZmZmZmZmZaZZmZmZmZmS/T//////////////////9y8u8y7u8u8u8y8u8vMu7u7u7vLvLtN3d2ZmZmZmZmZmZmZmZZpZmZmZmZma////////////////////7u7y7zLu8u8u8y8u8vMu7u7u7vLvLvd092ZmZmZmWmZlpmZmZZpZmb/Zma2////////////////////z7u7vLvLvMu8u8u8u8vMu7u7u7vLzLu9292ZmZmZmZmZmZmZaZZpZmb/////////////////////////z8y7zMzLvMvMu8u8u7vMvLu7u7vLzLtL3d2ZmZmZmZmZmWmZZpZmaWZmZv/2/////////////////////MzMzMzLvMvMu7vMu7vMvLu7u7vLzLvb1N2ZmZmZmZmZmZmZaZZpZmZm9m/2////////////////////zMzMzMzMvLvMu7vMu7vMvLu7u7u7zLs7Td2ZmZmZmZmZmWmZZpZpZmZmZmb////////////////////fzMzMzMzMvLvMu7vMu7vMu7u7u7u7zLvb3d2ZmZmZmZmZmZmWmWZmZmZmZvb///////////////////+/u8y7u8vMu7vLu7vLu7u8u7u7u7vLzLvbTd2ZmZmZmZmZmZlplmZmZmZmZv/////////////////////Mu7u7u7u7u7u7u7u7u7u8u7u7u7vLzLtLRN2ZmZmZmZmZmZlpmWlmZmZmZv/////////////////////MvLu7u7vLu7u7u7u7u7u8u7u7u7vLzLu73d2ZmZmZmZmZmZZpmWZmZmZm9v/////////////////////LvLu7u7vMu7u7u7u7u7vMvLu7u7vLzLu73d2ZmZmZmZmZmZZpmWZmZmZm9v///////////////////8/MvLu7u8y8u7u7u7u7u7vMvLu7u7vLzLvb3d2ZmZmZmZmZmZmZZmZmZmZm/////////////////////9+7y7u7y8y7u7u7y7u7u7vMu7u7u7vLy7tL3d2ZmZmZmZmZaZZpZmZmZmb2/////////////////////9y7y7vLzLu7y7vLzLy7u7vMu7u7u7vLy7xL1N2ZmZmZmZmZmWmWlmZmZmb2////////////////////z7+7y8zLu8u8zLzMy7y7u7vMu7u7u7vLy7y7RN2ZmZmZmWmZmZlpmWZmZmb/////////////////////z7y7y8y8zMzMvMzMu7u7u7vMu7u7u7vMy7w71ESZmZmZmZmZmZmZlmZmZvb/////////////////////38vMu8vMzMy7u8zMu7u7u7vMu7u7u7vMy7zb1N2ZmZmZmZmZlpaZZmZmZv//////////////////////v8zMvMvMzMy7u8vMy7y7u7vMu7u7y7zMy7zbRN2ZmZaZmZmZmZmZZmZm9v//////////////////////v8vMzMzLzLu7u8vMy7y7u7vMu7u7y7zMu7u7RN2ZmZaZaWZpmZlpZmZm9v//////////////////393Mu7vMzLzLzLu7u8vMzLy7u7vMu7u7zLvMu7u71N2ZaZaZmZaZmZmZZmZm///////////////////PzMzMu7u7u7u7y7y7vLvMzLu7u7vMu7u7zMy8u7vM3d2ZaWZmmZmWmZmZaWb2////////////////z8zMzMzMv7vLu7u7u8zLvLu7zLu7u7vMu7u7vMy8u7u83d2ZmWaZmZmZmZmZaWb2///////////////MzMzMzMzMvMvMvMy7u8zMvLu7y7u7u7vMu7vLzMy8u7u73d2ZmWaZmZmZZpaZaWb/////////////z8zMzMzMzMzMvMvMzMy8u7zMu7vLvLu7u7vMu7vLzMy8u7u73d2ZmZmZmWmZlmaZZmb/////////////zMzMzMzMzM/MzMvMzMzMzMy8u7vLzLy7u7vMu7vLzMy8u7u73d0="}},"storySprites.castle2":{"kind":4,"retType":"Image","attributes":{"fixedInstance":"true","jres":"true","blockIdentity":"images._image","tags":"background","whenUsed":true,"jresURL":"data:image/x-mkcd-f4;base64,hwSgAHgAAAD///////////////z//////8/d3d3d3d3d3d3d3d3d27u7u9vd3b3d3dvd273MzMzMzMzMzMzM//////////zM/f/////P////////z8zd3d3d3d3d3d3d3b29u7u7u93b3d3b3d3d3b3MzMzMzMzMzMz8/P////////+//P/////P3/38/9/MvN3d3d3d3d3d3d3d3d27u7u7293d3b3d3d3d3b3My8zMzMzMzMz//////////////P//////3P///8y8u93d3d3d3d3d3d3d3d29u7u73d3b3d3d3d283d3Ly8zMzMzMzMzM/////////////P//////////z7zd3d3d3d3d3d3d3d3d3d29u7vb3d3d3d3b3d3d3d3dy8zMzMzMzMzM///////////////////b///Pu93d3d3d3d3d3d3d3d3d3d27u7vb3d3d3d3d3d3d3d3dy8zMzMzMzMzM////////z//7///P///P/M/b3d3d3d3d3d3d3d3d3d3d3d29u7vb3d293d3d3d3d3d29u8zMzMzMzMz////////M/P///9+9/8+/vcvd3d3d3d3d3d3d3d3d3d3d3du9u7vd3d3d3d3d3d3d3d3dzcvMzMzMzPz////////L/////9/939z/v9zb3d3d3d0dEd3d3d3d3d3d3du7u9vd3d3d3d3d3d3d3d3dvczMzMzMzMz////////8/9zL/c/N/M+8u93R3d3d0REREd0dEd3d3d3d3d27u9vd3d3d3b3d3d3d3d3dvczMzMzMzMz////////8/73/+//Lz9vd3R3R0REdERERERHR3d3d3d3d3b27u7vd3d3d3d3d3dzd3b3dvcvMzMzMzPz//////////9z////P3d3d3REREREREREREREREd3d3d3d3b27u7vd3d3d3d3dvd3d3d3d3bvMzMzMzPz//////////93////f3d3dEREREREREREREREREd3d3d3d3b27u7vb3d3b27vbzL3d3d3d3cvMzMzMzPz////////P/8///N/b3d0RERERERERERERERERu7vd3d3d3b27u7vb3d3dvbvb3d3d3d3d3bzMzMzMzPz/////////+////9zd3REREREREREREREREREREbu73d3d3bu7u7vb3d3bu7vb3d3d3d3d3cvMzMzMzMz/////////v/3/z9vdHREREREREREREREREREREd29293d3bu7u7vbu9u9u7vb3d3d3d3d3czMzMy8zP//////////3///3N3dERERERERERERERERERERERERsbu7u7u7u7vbu727u7vc3d3d3d3dvczMzMzMzP/////////////P3N0REREREREREREREREREREREbu7u7u9u7u7u7vbu9u7u7u83b3d3d3dy8zMzMzMzPz///////////3b3d0RERERERERERERERERERERERsRERG93b27u7u7u7u7u8vMvd3d3d3NzMzMzMzM/P///////////8zb3REREREREREREREREczMzBwRERERvbsb0b27u7u7u7u7y8y8293d3dvdzczMzMzMzP/////P//+//9zdHRERERERERERERERwczMzMwRERG7uxsdEb27u7u7u7vMzMzM29vd3d3dvczMzMzMzPz////////83d3dHRERERERERERERERwcwczMwcERG70R0R0b27u7u7u8zMzMzMzLzM3d3dzczMzMzM/8z////////f3d0dERER0RERERERERERwcwRzMzMzMzMzMzMzMzMvMzMzMzMzMzMvLvd3d3dzMzMzMzM/Nz/////3//b3d0dERERERERERERERERscvMzMzMzMzMzMzMzMzMzMzMzMzMzMzMvNvd3b3NzMzMzMzM/P/////////d3d0dEREREREREREREREREbHMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzLvd3d3NzMzMzMy8/P/////////d3R0RERERERERERERERERwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzd3dy9zMzMzMzMzP/////////d3R0RERERERERERERERERwcwcy8zMzMzMzMzMzMzMzMzMzMzMzMzMzLvd3cu7zMzMzMzby//////////d3RERERERERERERERERERwcwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzNvdvdu9zMzMzLzdvfz8///////dHRERERER0REREREREREREczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNvdu93NzMzMzLzd3cy////8///dHRERERERERERERERERERERHMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzL3b3NzMzMzLvd3f3M///8///dERERERERERERERERERERERHMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNu93d29zMzMzMvd3d38/9////8dEREREREREREREREREREREczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMvLvb2929y8zMvN3d3d3Ny/////8dERERERERERERERERERERwcwRzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNvb3d3LzMzMvN3d3d3d/P//z/8dERERERERERERERERERERwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN3b2927zMzMzLzb3d3d+////78dERERERERERERwcwRERERwczMzMy7y9HMzMzMzMzMzMzMzMzMzMzMzN3dvNu7zMzMzLvb3d3d+/////8RERERERERERERzMwRERERwczMzMG8zNHMzMzMzMzMzMzMzMzMzMzMvN29y7vMzMzMzMy73d3dzf////8RERERERERERHMzMzMzMwRERERHMvMzLHMzMzMzMzMzMzMzMzMzMzMvNu93b3LzMzMzLzb3d3d3bz///8REREREREREczMzMzMzMwcEREREcu7y83MzMzMzMzMzMzMzMzMzMzMu93b293MzMzMzLzd3d3dzf////8RERERERHMzMzMzMwcwczMEREREcG7zMHMzMzMzMzMzMzMzMzMzMzMvN3d293MzMzMzLzd3d3d/b////8RERERwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMu93d3b3MzMzMzLvb3d3d/f////8RERERzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzN3d3c3MzMzMzLzb3d3d+///v78RERERzMzMzMzMzMwcwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMy8y9vd3c28zMzMzMzb293LzP////8RERERwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzc3b3d3b3LzMzMzMy73LzNu/////8REREREcHMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzd3d3Nu8vMzMzMzLy9u8y8zP3///8RERERERHBzMzMzMzczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzLzLvd3d3cvMzMzMzLy73Mzd/b/9//8RERERERERwczMzMwcwczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNy93d293c3MzMzMzMzcvb29y8////8REREREREREcHMzMzMzMwcy8zMHBEREc3MzMzMzMzMzMzMzMzMzNu73d3d3b3MzMzMzMzc3d3du/39/P8RERERERERERHBzMzMzMwRzMzMEREREcHMzMzMzMzMzMzMzMzMzNvN3d3d3b3MzMzMzMy83d3dy7/8//8RERERERERERERzMwRERGxzLscERERER3LzMzMzMzMzMzMzMzMvN3d2929zc3MzMzMzMy83d3dzPz///8RERERERERERERzMwRERERzLscEREREdHMzMzMzMzMzMzMzMzMvL3dvd3d3bvMzMzMzMy83d3d+/////8RERERERERERERERERERERzMwcsRsREdHMzMzMzMzMzMzMzMzMu73d273cvbvMzMzMzMy827vdzf////8RERERERERERERERERERERzMwcERsREdHMzMzMzMzLzMzMzMy8y929vN3cvbvMzMzMzMzM293dy///3/8RERERERERERERERERERERzMvMERERG9HMzMzMzMzMzMzMzMy8293d3d3d3cvMzMzMzMzMy9vdvf/f/f8RERERERERERERERERERERzLvMERG7u7vMzMzMzMzMzMzMzMzM293d3d3dvbvMzMzMzMzM3N3d3fzd/P8REREREREREcHMzMzMERERwbvMHBERscvMzMzMzMzMzMzMzMy7293d3d3dvczMzMzMzMzMvN3d3cz9//8REREREREREcHMzMzMHBERwczMzMzMzMzMzMzMzMzMzMzMzMzM293d3d3dvczMzMzMzMzMzNvd3c3P//8REREREREREcHMEczMzBEREczMzMzMzMzMzMzMzMzMzMzMzMzMvdvd3c3dvczMzMzMzMzMvN3d3c3///8RERERERERERHMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMy83d3d3d3by8zMzMzMzMzM3N3d3b28/f8REREREREREREREczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMy7vdvd3dvdy8zMzMzMzMzM293d3c3//f8dEREREREREREREczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMy8zd3d3d3dy8zMzMzMzMzM293d3b3///8dERERERERERHBzMzMzMzMzMzMzMzMzMzMzMzMzLzMzMzMzMy73d3d3d29u8zMzMzMzMzM293d3c38//8dERERERERERHMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzb3d3d3d3Nu8zMzMzMzMzM3N3d3b38//8dERERERERERHBzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzLy93d3d3d29y8zMzMzMzMzM3d3d3d38///dEREREREREREREczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzLvby9vd3d29zMzMzMzMzMzb3d3d3d38/7/dHREREREREREREczMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzc3d3N3d29y8zMzMzMzMy83d3d3d3////dHR0RERERERERzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzNvd3d3d3d3dy8zMzMzMzMzd3d3d3d3//8/d3R0REREREcHMHMzMzBwREREREbHLzMzbvMsbHbEdu8vMzNvd3d293d3Mu8zMzMzMzLzd3d3d3d37///d3R0dHREREcHMHMzMHBEREREREbEbEREREbG7ERERu7vLvNvd3d3d3d29y8zMzMzMzLzd3d3d3d39///d3d0REREREcHMzMzMERERERERERG7EREdEbu7GxERsbvLzNzd3d3d3d3dvMzMzMzMzLzd3d3d3d37///d3d0REREREREREREREREREREREREbEREREbERu7u7u7u7zMvd3d3d3b3dzczMzMzMzNzd293d3d37///d3d0d0RERERERERERERERERERERERERERERERu7uxu7u7zN3d3b3b3d3du8zMzMzMzNvd3d3d3d37z8/d3d3d3RERERERERERERERERERERsRERGx3R0RERERsbu7u73d3d3d3d3du8zMzMzMzN3d3d3d3d39///d3R3d3R0REREREREREREREREREREREREREREdERERu7u7u93d3d3d3d3dvczMzMzMzNvd3d3d3d39///d3d3d3R0RERERERERERERERERERERERERERERERERu7u7u93d3d3d3d3dvczMzMzMvLvd3d3d3d39///d3d3d3R0RERERERERERERERERERERERERERERERGxu7u7vd293d3d3d3NvczMzMzMzLvd3d3d3d38///d3d3d3R0REREREREREREREREREREREbEbEREREbu7u7u7u9293d3d3du8vczMzMzMzNvb3d3d3c3P+//d3d3d3dEREREREREREREREREREREREbG7u7u7u7u7u7u72729293d3dzdu8zMzMzMzN293d3d3c39///d3d3d3d0dERERERERERERERERERERERG7u7u7u7u7u7u73b3d3d3d3d3dvczMzMzMvN3d3d3d3c3////d3d3d3d0dERERERERERGxERERERERsbu7u7u7u7u7u7u7u93d3d3d3N3dzczMzMzMvN3c3d3d3c3////d3d3d3d0dERERERERERGxuxu7u7u7u7sb0d27u7u7u7u73d3d3d3b293dy8zMzMzMvN3b3d3d3fv////d3d3d3d3dHR0RERERERERERERERGxuxsd0d3R3d27u7u73d3dvd3d3dzdvLzMzMzMvLvd3d3d3f3//P/d3d3d3d3d3dERERERERERERER0d292xHd3d3d3d29u7vb3d3d3d3c3d3dzczMzMzMvN3c3d3dvfz/+//d3d3d3d3d3d3RERERERERERERsbvb3d3d3d3d3d3du7vb3bvd3d3b3d3dvcvMzMzMvM3c3d3du/z////d3d3d3d3d3d3dERERERERER27uxvR3d3d3d3d3d3du7vb3b3d3d3d3d3dvczMzMzM283b3d3du//////d3d3d3d3d3d3d3RER3d3R3d3dHd3d3d3d3d3dHd3dvbvb3d3dvd3d3d3dvczMzMzM3N3d3d3dzP/////d3d3d3d3d3d3d3d3dHd3d3d3d3d3d3b273d3d3d3dvbvb3d3d3d3d3d3d3cvMzMzM293d3d29/P/////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d27293d3d3dvbvb293d3d3d3b3dvczMzMy83bvd3d3d/////8/d3d3d3d3d3d3d3d3d3d3d3d0d0d0R3d3du7vd3d3dvbvb3d3d3d293d3dvcvMzMzM3d3d3d3d///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3bu73d3dvbvb3d3d3d3d3d3dvcvMzMzM3d3d3d39///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d27u7u7u7vd3d3b3dvd3d3dvczMzMzM3d3d3d3L///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3bu7u7u7u7vd3d3d3dvd3d3d3czMzMy73d3d3d3M///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvd3bu7u9vd293d3dvd3d3d3cvMzMy83d3d3d3M///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d29u9vd3d3d3d3d293d3c3MzMzL293d3d3L/////P/d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvdvb3d3d3d3d3d3d3cvMzLzL293d3d27///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvd3d3d3d3d3d3d3d3bvLzMzM3N3d3d38///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvdvd3b3dvd3d3b3d3b3MzMzM293d3d3M///////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvdvd3d3d3d3d3d3d3b3My8zM293d3d37///////d3d3d3d3d3d3d3d3d3d3d3d3d3d29293d3d3du7u7u9vd3d3d3d3d3d3d293MzMy8u93d3d38///////d3d3d3d3d3d3d3d3d3d3d3d3d3d27293d3b27u7u7u93d3d3d3d3d3d3d3d3MzMy8vd3d3d37///////d3d3d3d3d3d3d3d3d3d3d3d3dvbvb3d3d3b3b3d3dvdvd3d3d3b3d3d3d3d3LzMzMu93d3d37///////d3d3d3d3d3d3d3d3d3d3d3d3dvd3d3d3d3d3d3d3dvd3d3d3d3d3d3d3d3d3NzMzMvN3d3d37///////d3d3d3d3d3d3d3d3d3d3d3d3dvd3d3d3d3d3d3d3du73d3d3d3b3d3d3d3d3LzMzMvN3d3d3N///////d3d3d3d3d3d3d3d3d3d3d3d3dvdvd3d3d3d3d3d29u93b3d3d3d3d3d3d3d3NzMzMvN3d3d27/P/////d3d3d3d3d3d3d3d3d3d3d3d3d3bvb3d3d3d3d3d27u93d3d3d3d3d3d3d3d3NzMzM3N3d3d3L+//////d3d3d3d3d3d3d3d3d3d3d3d3d3bu7u7u7u7u7u7u7u9vd3d3d3d3d3d293d3NzMzM293d3d37z/z////d3d3d3d3d3d3d3d3d3d3d3d3d3d27u7u7u7u7u7u73d3d3d3d3d3d3d3d3d3LzMzM293d3d393//////d3d3d3d3d3d3d3d3d3d3d3d3d3d3du7u7u7u7u7u73d3d3d3d3d3d3d3d3d3NzMy83d3d3d37v//////d3d3d3d3d3d3d3d3d3d3d3d3d3d29u7u7u7u7u7u7293d3d3d3d3dvdzd3d3LzMy73d3d3d3P///////d3d3d3d3d3d3d3d3d3d3d3d3d3d27293du7u7u7vb293d3d3d3d3dvdzd3d3LzMy7zd3d3d3////////d3d3d3d3d3d3d3d3d3d3d3bu7u7vb3d3d3d3d3b3d3d3d3d3d3d3d3d3d3d3LzMu73dzd3b3///z////d3d3d3d3d3d3d3d3d3d3d3b3b3b3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3b3MzLzb3dzd3c3N///////d3d3d3d3d3d3d3d3d3d3d3d3d3dvd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3b3MzLvd293d3fv////////d3d3d3d3d3d3d3d3d3d3d3d3du93d3d3d3d3du93d3d3d3d3d3d3d3d3d3b3MzN3d3d3dvfz////////d3d3d3d3d3d3d3d3d3d3d3d29293d3d3d3d29u9vd3d3d3d3d3d3d3d3d3b27vN3d3d3dzP/////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cvM293d3d3d/f/////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvd3d3d3b3d3d3d3d3d3cvM293d3d3N/////f/////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3cvcvL3d3d3d38///////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d27293d3d3d3dvd3d3d3d3dvcu73b3d3d3L2//////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d293dvd3d3d3d3d3d3d3dvbvb3d3d3b3////////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d27293d3d3d3d3d3d3d3d3dvbvd3d3d3c39//3/z//////d3d3d3d3d3d3d3d3d3d3d3d3d3d3dvbu73b27u93d3d3d3d3d3d3d3d3d3d3d3d3dvfz/z93/3P/////d3d3d3d3d3d3d3d3d3d3d3d3d3d27u7u7u7u7293d3d3d3d3d3d3d3d3d3d3d3bu7zP/////P/8/////d3d3d3d3d3d3d3d3d3d3d3d3d3d3b3d3dvbu7293d3d3d3d3d3d3d3d3d3cvbu8zM///////P3//////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3b27293d3d3d3d3d3d3dvcvMzMz////P///////////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3b27293d3b3d3d3d3d3d/N3///z//////f/////////////d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3bu73b3d3d3d3d3d3b38//3////////8//////////////vd3d3d3d3d3d3d3d3d3d293d3d3d3d3d3dvbu7293d3d3d3d3d3fz///////3/////////v//P///////d3d3d3d3d3d3d3d3d3d29u93d3d3dvbu7u7u7293d3d3d3d29zP////////3//////f/////8///////d3d3d3d3d3d3d3d3d3d3du93d3d3d3d29u7u7293d293dvcv8z/y/zf//y//9///////////////////d3d3d3d3d3d3d3d3d3d3dvdvd3d3d3b27u7u7293d3d3dzb///////////c///////////////8/////d3d3d3d3d3d3d3d3du7u73b3b3d3dvbu7u7u7u93d3b273Nz/////////vP///////////8///8//v/vd3d3d3d3d3d3d3d272929u9272927u7u7u7u7u93d3b3d////////////////////////////////3//d3d3d3d3d3d3d3d3b3d3dvdu7u7u7u7u7u7u7u93dvbz9///////////////////////////////////d3d3d3d3d3d3d3d3d3d3d3bu7u7u7u7u7u7u7u93dy/z/3P/////////////////////////////////d3d3d3d3d3d3d3d3d3d3d3d3d3d27u7u7u7u7u929/P/c/f///8/////////////////////////7///d3d3d3d3d3d3d3d3d3d3d3d3d3b27u7u7u7u7u929/L/7z/z////////////////////P//////////3d3d3d3d3d3d3d3d3d3d3d3d3d3bu7u7u7u7u7u727/9//3/////////////////////+/2/3////////d3d3d3d3d3d3d3d3d3d273d3du7u7u7u7u7u7u73M/f+9//////////z/////////////z/3////////d3d3d3d3d3d3d3d3d3d27u7u7u7u7u7u7u7u7zM3f/f/P///////////////P////////z//////////d3d3d3d3d3d3d3d3d3d3d3bu9u7u7u7u7u8v8///////////////////P/Pv///z//////////////9zb3N3d3d3d3d3d3d3d3d3dvdu9u7u7u7u7u8z///////////////////////v///v//8///////P///93/393d3d3d3d3d3d3d3d3d3d27u7vLy8vMy//8/////////7/////////////////////////d/P///93Pz93d3d3d3d3d3d3d3d3d3b27u7vMy/z//Pz///////////////////////////////////+9//////zMzNvb3d3d3d3d3d3d3d3d3bu7u8u7/Pz////////////////////////////////////////////////d+8vN3N3b3d3d3d3d3d3d3bu7y8zL//////////////////////////////////////////////////+9///M/9zM3d3d3d3d3d3dvbvMzPv8//////////////////////z//////////////////7///////////8//z//Pzd27293d3du7vfzM/P//////////z////////////////////////////////////////////////////NvMzMvdvbvMv////////////////////////8//////////////////////////////////////////v////8+8zP/Pz//////////////////////////////////////////////////////////////////8////z/z//////////////////////////////////////////////////////P//////////3///////////z73N/P///////////////////////////////////////P//////////+/////////////3///////3////7/////////////////////////////////8/////////////////P/P///////P/8v8//////z////////////////////////////////////P/P/////////////////////////////8/////////////////////////////////////////////////c/8/8/////////////////////////8/8/////////////////////////////////////////////////////8z//////////////////////P/////7/////////////////////////////////////////////f/P/8z//////////////////////////L///////////////////////////////////////////8////////z//////////////////////////f////////////////////////////////zP/////////7/N/////////////////////////////////P///////////////8/////////////////////////////9/////////////////////////////////////////////////////////////////////////////////////8//////////z/////////////8="}}}},"sha":"abc552e6e5ac25cca0eceac7e9998d22071f9f230179cb87ca70ae202d11bb23"},"libs/edge-connector":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"pins.P0":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P0 on the edge connector"}},"pins.P1":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P1 on the edge connector"}},"pins.P2":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P2 on the edge connector"}},"pins.P3":{"kind":4,"retType":"AnalogInPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P3 on the edge connector"}},"pins.P4":{"kind":4,"retType":"AnalogInPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P3 on the edge connector"}},"pins.P5":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P5 on the edge connector"}},"pins.P6":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P6 on the edge connector"}},"pins.P7":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P7 on the edge connector"}},"pins.P8":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P8 on the edge connector"}},"pins.P9":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P9 on the edge connector"}},"pins.P10":{"kind":4,"retType":"AnalogInPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P10 on the edge connector"}},"pins.P11":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P11 on the edge connector"}},"pins.P12":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P12 on the edge connector"}},"pins.P13":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P13 on the edge connector"}},"pins.P14":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P14 on the edge connector"}},"pins.P15":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P15 on the edge connector"}},"pins.P16":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P16 on the edge connector"}},"pins.P19":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P19 on the edge connector"}},"pins.P20":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P20 on the edge connector"}},"pins.P21":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P21 on the edge connector"}},"pins.P22":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P22 on the edge connector"}},"pins.P23":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P23 on the edge connector"}},"pins.P24":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P24 on the edge connector"}},"pins.P25":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P25 on the edge connector"}},"pins.P26":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P26 on the edge connector"}},"pins.P27":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P27 on the edge connector"}},"pins.P28":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P28 on the edge connector"}},"pins.P29":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P29 on the edge connector"}},"pins.P30":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P30 on the edge connector"}},"pins.P31":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P31 on the edge connector"}},"DigitalPin":{"kind":6,"retType":"DigitalPin","extendsTypes":["DigitalPin","Number"]},"DigitalPin.P0":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P0","Number"]},"DigitalPin.P1":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P1","Number"]},"DigitalPin.P2":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P2","Number"]},"DigitalPin.P3":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P3","Number"]},"DigitalPin.P4":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P4","Number"]},"DigitalPin.P5":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P5","Number"]},"DigitalPin.P6":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P6","Number"]},"DigitalPin.P7":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P7","Number"]},"DigitalPin.P8":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P8","Number"]},"DigitalPin.P9":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P9","Number"]},"DigitalPin.P10":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P10","Number"]},"DigitalPin.P11":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P11","Number"]},"DigitalPin.P12":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P12","Number"]},"DigitalPin.P13":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P13","Number"]},"DigitalPin.P14":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P14","Number"]},"DigitalPin.P15":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P15","Number"]},"DigitalPin.P16":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P16","Number"]},"DigitalPin.P19":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P19","Number"]},"DigitalPin.P20":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P20","Number"]},"AnalogPin":{"kind":6,"retType":"AnalogPin","extendsTypes":["AnalogPin","Number"]},"AnalogPin.P0":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P0","Number"]},"AnalogPin.P1":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P1","Number"]},"AnalogPin.P2":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P2","Number"]},"AnalogPin.P3":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P3","Number"]},"AnalogPin.P4":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P4","Number"]},"AnalogPin.P10":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P10","Number"]},"AnalogPin.P5":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P5","Number"]},"AnalogPin.P6":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P6","Number"]},"AnalogPin.P7":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P7","Number"]},"AnalogPin.P8":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P8","Number"]},"AnalogPin.P9":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P9","Number"]},"AnalogPin.P11":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P11","Number"]},"AnalogPin.P12":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P12","Number"]},"AnalogPin.P13":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P13","Number"]},"AnalogPin.P14":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P14","Number"]},"AnalogPin.P15":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P15","Number"]},"AnalogPin.P16":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P16","Number"]},"AnalogPin.P19":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P19","Number"]},"AnalogPin.P20":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P20","Number"]},"pins.setPull":{"kind":-3,"attributes":{"deprecated":"1","paramHelp":{"pin":"@param mode "},"jsDoc":"Sets the pin pull"},"parameters":[{"name":"pin","description":"@param mode ","type":"DigitalPin","isEnum":true},{"name":"mode","type":"PinPullMode","isEnum":true}],"pyQName":"pins.set_pull"},"pins.digitalWritePin":{"kind":-3,"attributes":{"deprecated":"1","paramHelp":{"pin":"@param value "},"jsDoc":"Sets the digital pin status"},"parameters":[{"name":"pin","description":"@param value ","type":"DigitalPin","isEnum":true},{"name":"value"}],"pyQName":"pins.digital_write_pin"},"pins.digitalReadPin":{"kind":-3,"retType":"number","attributes":{"deprecated":"1","paramHelp":{"pin":""},"jsDoc":"Reads the pin status"},"parameters":[{"name":"pin","type":"DigitalPin","isEnum":true}],"pyQName":"pins.digital_read_pin"},"pins.analogWritePin":{"kind":-3,"attributes":{"deprecated":"1","paramHelp":{"pin":"@param value "},"jsDoc":"Sets the digital pin status"},"parameters":[{"name":"pin","description":"@param value ","type":"AnalogPin","isEnum":true},{"name":"value"}],"pyQName":"pins.analog_write_pin"},"pins.analogReadPin":{"kind":-3,"retType":"number","attributes":{"deprecated":"1","paramHelp":{"pin":""},"jsDoc":"Reads the pin status"},"parameters":[{"name":"pin","type":"AnalogPin","isEnum":true}],"pyQName":"pins.analog_read_pin"},"pins.onPulsed":{"kind":-3,"attributes":{"deprecated":"1","jsDoc":"Make this pin a digital input, and create events where the timestamp is the duration\nthat this pin was either ``high`` or ``low``."},"parameters":[{"name":"pin","type":"DigitalPin","isEnum":true},{"name":"pulse","type":"PulseValue","isEnum":true},{"name":"body","type":"() => void","handlerParameters":[]}],"pyQName":"pins.on_pulsed"},"pins.onEvent":{"kind":-3,"attributes":{"deprecated":"1","jsDoc":"Register code to run when a pin event occurs."},"parameters":[{"name":"pin","type":"DigitalPin","isEnum":true},{"name":"event","type":"PinEvent","isEnum":true},{"name":"body","type":"() => void","handlerParameters":[]}],"pyQName":"pins.on_event"},"pins.pulseIn":{"kind":-3,"retType":"number","attributes":{"deprecated":"1","paramHelp":{"name":"the pin which measures the pulse","value":"the value of the pulse (default high)","maximum":"duration in micro-seconds"},"jsDoc":"Return the duration of a pulse in microseconds"},"parameters":[{"name":"pin","type":"DigitalPin","isEnum":true},{"name":"value","description":"the value of the pulse (default high)","type":"PulseValue","isEnum":true},{"name":"maxDuration","initializer":"undefined"}],"pyQName":"pins.pulse_in"},"pins.map":{"kind":-3,"retType":"number","parameters":[{"name":"value"},{"name":"fromLow"},{"name":"fromHigh"},{"name":"toLow"},{"name":"toHigh"}]}}},"sha":"5c45027dd0a5a1c803bea29a689a95307d7cab5b3681e9e6886698bb2b935996"},"libs/esp32":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"net":{"kind":5,"retType":"","attributes":{"weight":1,"advanced":true,"icon":"","color":"#8446cf","jsDoc":"Networking, WiFi, web requests"}},"net.ControllerEvent":{"kind":6,"retType":"net.ControllerEvent","extendsTypes":["net.ControllerEvent","Number"]},"net.ControllerEvent.NewScan":{"retType":"net.ControllerEvent.NewScan","extendsTypes":["net.ControllerEvent.NewScan","Number"],"pyQName":"net.ControllerEvent.NEW_SCAN"},"net.ControllerEvent.GotIP":{"retType":"net.ControllerEvent.GotIP","extendsTypes":["net.ControllerEvent.GotIP","Number"],"pyQName":"net.ControllerEvent.GOT_IP"},"net.ControllerEvent.LostIP":{"retType":"net.ControllerEvent.LostIP","extendsTypes":["net.ControllerEvent.LostIP","Number"],"pyQName":"net.ControllerEvent.LOST_IP"},"net.ControllerEvent.NoScannedNetworks":{"retType":"net.ControllerEvent.NoScannedNetworks","extendsTypes":["net.ControllerEvent.NoScannedNetworks","Number"],"pyQName":"net.ControllerEvent.NO_SCANNED_NETWORKS"},"net.ControllerEvent.NoKnownNetworks":{"retType":"net.ControllerEvent.NoKnownNetworks","extendsTypes":["net.ControllerEvent.NoKnownNetworks","Number"],"pyQName":"net.ControllerEvent.NO_KNOWN_NETWORKS"},"net.ControllerEvent.Connecting":{"retType":"net.ControllerEvent.Connecting","extendsTypes":["net.ControllerEvent.Connecting","Number"],"pyQName":"net.ControllerEvent.CONNECTING"},"net.ControllerEvent.ConnectionFailed":{"retType":"net.ControllerEvent.ConnectionFailed","extendsTypes":["net.ControllerEvent.ConnectionFailed","Number"],"pyQName":"net.ControllerEvent.CONNECTION_FAILED"},"net.ControllerEvent.LoginServerStarted":{"retType":"net.ControllerEvent.LoginServerStarted","extendsTypes":["net.ControllerEvent.LoginServerStarted","Number"],"pyQName":"net.ControllerEvent.LOGIN_SERVER_STARTED"},"net.Controller":{"kind":8,"retType":"net.Controller","extendsTypes":["net.Controller"]},"net.Controller.eventID":{"kind":2,"retType":"number","isInstance":true,"pyQName":"net.Controller.event_id"},"net.Controller.onConnectSSIDFailed":{"kind":2,"retType":"(ssid: string) => void","isInstance":true,"pyQName":"net.Controller.on_connect_ssid_failed"},"net.Controller.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"net.Controller.onEvent":{"kind":-1,"parameters":[{"name":"ev","type":"net.ControllerEvent","isEnum":true},{"name":"h","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Controller.on_event"},"net.Controller.scanNetworks":{"kind":-1,"retType":"net.AccessPoint[]","parameters":[],"isInstance":true,"pyQName":"net.Controller.scan_networks"},"net.Controller.startLoginServer":{"kind":-1,"parameters":[{"name":"hostName","type":"string"}],"isInstance":true,"pyQName":"net.Controller.start_login_server"},"net.Controller.isLoginServerEnabled":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"net.Controller.is_login_server_enabled"},"net.Controller.socket":{"kind":-1,"retType":"number","parameters":[],"isInstance":true},"net.Controller.socketConnect":{"kind":-1,"retType":"boolean","parameters":[{"name":"socket_num"},{"name":"dest","type":"string | Buffer"},{"name":"port"},{"name":"conn_mode","initializer":"TCP_MODE"}],"isInstance":true,"pyQName":"net.Controller.socket_connect"},"net.Controller.socketWrite":{"kind":-1,"parameters":[{"name":"socket_num"},{"name":"buffer","type":"Buffer"}],"isInstance":true,"pyQName":"net.Controller.socket_write"},"net.Controller.socketAvailable":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.socket_available"},"net.Controller.socketRead":{"kind":-1,"retType":"Buffer","parameters":[{"name":"socket_num"},{"name":"size"}],"isInstance":true,"pyQName":"net.Controller.socket_read"},"net.Controller.socketClose":{"kind":-1,"parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.socket_close"},"net.Controller.hostbyName":{"kind":-1,"retType":"Buffer","parameters":[{"name":"hostname","type":"string"}],"isInstance":true,"pyQName":"net.Controller.hostby_name"},"net.Controller.isIdle":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.is_idle"},"net.Controller.isConnected":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.is_connected"},"net.Controller.connectAP":{"kind":-1,"retType":"boolean","parameters":[{"name":"bssid","type":"string"},{"name":"password","type":"string"}],"isInstance":true,"pyQName":"net.Controller.connect_ap"},"net.Controller.disconnectAP":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"net.Controller.disconnect_ap"},"net.Controller.lastScanResults":{"kind":2,"retType":"net.AccessPoint[]","isInstance":true,"pyQName":"net.Controller.last_scan_results"},"net.Controller.autoconnect":{"kind":-1,"parameters":[],"isInstance":true},"net.Controller.disconnect":{"kind":-1,"parameters":[],"isInstance":true},"net.Controller.connect":{"kind":-1,"retType":"boolean","parameters":[{"name":"timeout_ms","initializer":"undefined"}],"isInstance":true},"net.Controller.ssid":{"kind":-2,"retType":"string","isInstance":true,"isReadOnly":true},"net.Controller.rssi":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"net.Controller.MACaddress":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.ma_caddress"},"net.Controller.IPaddress":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.ipaddress"},"net.Controller.ping":{"kind":-1,"retType":"number","parameters":[{"name":"dest","type":"string"},{"name":"ttl","initializer":"250"}],"isInstance":true},"net.Controller.dataAvailableSrc":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.data_available_src"},"net.Controller.dataAvailableValue":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.data_available_value"},"net.SOCK_STREAM":{"kind":4,"retType":"number"},"net.AF_INET":{"kind":4,"retType":"number"},"net.MAX_PACKET":{"kind":4,"retType":"number"},"net.TCP_MODE":{"kind":4,"retType":"number"},"net.UDP_MODE":{"kind":4,"retType":"number"},"net.TLS_MODE":{"kind":4,"retType":"number"},"net.ControllerSocket":{"kind":8,"retType":"net.ControllerSocket","extendsTypes":["net.ControllerSocket","net.Socket"]},"net.ControllerSocket._buffer":{"kind":2,"retType":"Buffer","isInstance":true},"net.ControllerSocket._socknum":{"kind":2,"retType":"number","isInstance":true},"net.ControllerSocket._timeout":{"kind":2,"retType":"number","isInstance":true},"net.ControllerSocket._closed":{"kind":2,"retType":"boolean","isInstance":true},"net.ControllerSocket._openHandler":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"net.ControllerSocket._open_handler"},"net.ControllerSocket._closeHandler":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"net.ControllerSocket._close_handler"},"net.ControllerSocket._errorHandler":{"kind":2,"retType":"(msg: string) => void","isInstance":true,"pyQName":"net.ControllerSocket._error_handler"},"net.ControllerSocket._messageHandler":{"kind":2,"retType":"(data: Buffer) => void","isInstance":true,"pyQName":"net.ControllerSocket._message_handler"},"net.ControllerSocket.__constructor":{"kind":-3,"attributes":{"jsDoc":"A simplified implementation of the Python 'socket' class, for connecting\nthrough an interface to a remote device"},"parameters":[{"name":"controller","type":"net.Controller"},{"name":"host","type":"string | Buffer"},{"name":"port"},{"name":"conntype","initializer":"null"}],"isInstance":true},"net.ControllerSocket.connect":{"kind":-1,"attributes":{"jsDoc":"Connect the socket to the 'address' (which can be 32bit packed IP or\na hostname string). 'conntype' is an extra that may indicate SSL or not,\ndepending on the underlying interface"},"parameters":[],"isInstance":true},"net.ControllerSocket.send":{"kind":-1,"attributes":{"jsDoc":"Send some data to the socket"},"parameters":[{"name":"data","type":"string | Buffer"}],"isInstance":true},"net.ControllerSocket.onOpen":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_open"},"net.ControllerSocket.onClose":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_close"},"net.ControllerSocket.onError":{"kind":-1,"parameters":[{"name":"handler","type":"(msg: string) => void","handlerParameters":[{"name":"msg","type":"string"}]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_error"},"net.ControllerSocket.onMessage":{"kind":-1,"parameters":[{"name":"handler","type":"(data: Buffer) => void","handlerParameters":[{"name":"data","type":"Buffer"}]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_message"},"net.ControllerSocket.readLine":{"kind":-1,"retType":"string","attributes":{"jsDoc":"Attempt to return as many bytes as we can up to but not including '\\r\\n'"},"parameters":[],"isInstance":true,"pyQName":"net.ControllerSocket.read_line"},"net.ControllerSocket.read":{"kind":-1,"retType":"Buffer","attributes":{"jsDoc":"Read up to 'size' bytes from the socket, this may be buffered internally! If 'size' isn't specified, return everything in the buffer."},"parameters":[{"name":"size","initializer":"0"}],"isInstance":true},"net.ControllerSocket.setTimeout":{"kind":-1,"attributes":{"jsDoc":"Set the read timeout for sockets, if value is 0 it will block"},"parameters":[{"name":"value"}],"isInstance":true,"pyQName":"net.ControllerSocket.set_timeout"},"net.ControllerSocket.close":{"kind":-1,"attributes":{"jsDoc":"Close the socket, after reading whatever remains"},"parameters":[],"isInstance":true},"net.logPriority":{"kind":4,"retType":"ConsolePriority","attributes":{"jsDoc":"Default priority of net log messages"},"pyQName":"net.log_priority"},"net.log":{"kind":-3,"parameters":[{"name":"msg","type":"string"}]},"net.debug":{"kind":-3,"parameters":[{"name":"msg","type":"string"}]},"net.fail":{"kind":-3,"parameters":[{"name":"reason","type":"string"}]},"net.monotonic":{"kind":-3,"retType":"number","parameters":[]},"net.WifiAPFlags":{"kind":6,"retType":"net.WifiAPFlags","extendsTypes":["net.WifiAPFlags","Number"]},"net.WifiAPFlags.HasPassword":{"retType":"net.WifiAPFlags.HasPassword","extendsTypes":["net.WifiAPFlags.HasPassword","Number"],"pyQName":"net.WifiAPFlags.HAS_PASSWORD"},"net.WifiAPFlags.WPS":{"retType":"net.WifiAPFlags.WPS","extendsTypes":["net.WifiAPFlags.WPS","Number"]},"net.WifiAPFlags.HasSecondaryChannelAbove":{"retType":"net.WifiAPFlags.HasSecondaryChannelAbove","extendsTypes":["net.WifiAPFlags.HasSecondaryChannelAbove","Number"],"pyQName":"net.WifiAPFlags.HAS_SECONDARY_CHANNEL_ABOVE"},"net.WifiAPFlags.HasSecondaryChannelBelow":{"retType":"net.WifiAPFlags.HasSecondaryChannelBelow","extendsTypes":["net.WifiAPFlags.HasSecondaryChannelBelow","Number"],"pyQName":"net.WifiAPFlags.HAS_SECONDARY_CHANNEL_BELOW"},"net.WifiAPFlags.IEEE_802_11B":{"retType":"net.WifiAPFlags.IEEE_802_11B","extendsTypes":["net.WifiAPFlags.IEEE_802_11B","Number"]},"net.WifiAPFlags.IEEE_802_11A":{"retType":"net.WifiAPFlags.IEEE_802_11A","extendsTypes":["net.WifiAPFlags.IEEE_802_11A","Number"]},"net.WifiAPFlags.IEEE_802_11G":{"retType":"net.WifiAPFlags.IEEE_802_11G","extendsTypes":["net.WifiAPFlags.IEEE_802_11G","Number"]},"net.WifiAPFlags.IEEE_802_11N":{"retType":"net.WifiAPFlags.IEEE_802_11N","extendsTypes":["net.WifiAPFlags.IEEE_802_11N","Number"]},"net.WifiAPFlags.IEEE_802_11AC":{"retType":"net.WifiAPFlags.IEEE_802_11AC","extendsTypes":["net.WifiAPFlags.IEEE_802_11AC","Number"]},"net.WifiAPFlags.IEEE_802_11AX":{"retType":"net.WifiAPFlags.IEEE_802_11AX","extendsTypes":["net.WifiAPFlags.IEEE_802_11AX","Number"]},"net.WifiAPFlags.IEEE_802_LongRange":{"retType":"net.WifiAPFlags.IEEE_802_LongRange","extendsTypes":["net.WifiAPFlags.IEEE_802_LongRange","Number"],"pyQName":"net.WifiAPFlags.IEEE_802_LONGRANGE"},"net.AccessPoint":{"kind":8,"retType":"net.AccessPoint","extendsTypes":[]},"net.AccessPoint.flags":{"kind":2,"retType":"net.WifiAPFlags","isInstance":true},"net.AccessPoint.rssi":{"kind":2,"retType":"number","isInstance":true},"net.AccessPoint.bssid":{"kind":2,"retType":"Buffer","isInstance":true},"net.AccessPoint.channel":{"kind":2,"retType":"number","isInstance":true},"net.AccessPoint.__constructor":{"kind":-3,"parameters":[{"name":"ssid","type":"string"}],"isInstance":true},"net.AccessPoint.fromBuffer":{"kind":-1,"retType":"net.AccessPoint","parameters":[{"name":"buf","type":"Buffer"}],"pyQName":"net.AccessPoint.from_buffer"},"net.AccessPoint.toBuffer":{"kind":-1,"retType":"Buffer","parameters":[],"isInstance":true,"pyQName":"net.AccessPoint.to_buffer"},"net.Socket":{"kind":9,"retType":"net.Socket","extendsTypes":["net.Socket"]},"net.Socket.connect":{"kind":-1,"parameters":[],"isInstance":true},"net.Socket.send":{"kind":-1,"parameters":[{"name":"data","type":"string | Buffer"}],"isInstance":true},"net.Socket.read":{"kind":-1,"retType":"Buffer","parameters":[{"name":"contentLength"}],"isInstance":true},"net.Socket.close":{"kind":-1,"parameters":[],"isInstance":true},"net.Socket.onOpen":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Socket.on_open"},"net.Socket.onClose":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Socket.on_close"},"net.Socket.onError":{"kind":-1,"parameters":[{"name":"handler","type":"(msg: string) => void","handlerParameters":[{"name":"msg","type":"string"}]}],"isInstance":true,"pyQName":"net.Socket.on_error"},"net.Socket.onMessage":{"kind":-1,"parameters":[{"name":"handler","type":"(data: Buffer) => void","handlerParameters":[{"name":"data","type":"Buffer"}]}],"isInstance":true,"pyQName":"net.Socket.on_message"},"net.Socket.setTimeout":{"kind":-1,"parameters":[{"name":"millis"}],"isInstance":true,"pyQName":"net.Socket.set_timeout"},"net.Socket.readLine":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"net.Socket.read_line"},"net.Net":{"kind":8,"retType":"net.Net","extendsTypes":[]},"net.Net.__constructor":{"kind":-3,"parameters":[{"name":"factory","type":"() => net.Controller","handlerParameters":[]}],"isInstance":true},"net.Net.instance":{"kind":2,"retType":"net.Net"},"net.Net.controller":{"kind":-2,"retType":"net.Controller","isInstance":true,"isReadOnly":true},"net.Net.scanNetworks":{"kind":-1,"retType":"net.AccessPoint[]","attributes":{"jsDoc":"Scan for APs"},"parameters":[],"isInstance":true,"pyQName":"net.Net.scan_networks"},"net.Net.createSocket":{"kind":-1,"retType":"net.Socket","parameters":[{"name":"host","type":"string"},{"name":"port"},{"name":"secure","type":"boolean"}],"isInstance":true,"pyQName":"net.Net.create_socket"},"net.Net.hostByName":{"kind":-1,"retType":"string","parameters":[{"name":"host","type":"string"}],"isInstance":true,"pyQName":"net.Net.host_by_name"},"net.instance":{"kind":-3,"retType":"net.Net","attributes":{"jsDoc":"Gets the current Net instance"},"parameters":[]},"net.knownAccessPoints":{"kind":-3,"retType":"StringMap","attributes":{"jsDoc":"Gets the map of SSID -> password pairs"},"parameters":[],"pyQName":"net.known_access_points"},"net.clearAccessPoint":{"kind":-3,"parameters":[{"name":"ssid","type":"string"}],"pyQName":"net.clear_access_point"},"net.updateAccessPoint":{"kind":-3,"parameters":[{"name":"ssid","type":"string"},{"name":"password","type":"string"}],"pyQName":"net.update_access_point"},"net.setAccessPointPriority":{"kind":-3,"parameters":[{"name":"ssid","type":"string"},{"name":"pri"}],"pyQName":"net.set_access_point_priority"},"net.accessPointPriorities":{"kind":-3,"retType":"any","parameters":[],"pyQName":"net.access_point_priorities"},"net.clearAccessPoints":{"kind":-3,"parameters":[],"pyQName":"net.clear_access_points"},"net.urlencode":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"}]},"net.urldecode":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"}]},"net.ping":{"kind":-3,"retType":"number","attributes":{"blockId":"netping","block":"net ping $dest","paramHelp":{"dest":"host name","ttl":""},"jsDoc":"Pings a web site","_def":{"parts":[{"kind":"label","text":"net ping ","style":[]},{"kind":"param","name":"dest","ref":true}],"parameters":[{"kind":"param","name":"dest","ref":true}]}},"parameters":[{"name":"dest","description":"host name","type":"string"},{"name":"ttl","initializer":"250"}]},"net.Response":{"kind":8,"retType":"net.Response","extendsTypes":[]},"net.Response._cached":{"kind":2,"retType":"Buffer","isInstance":true},"net.Response.status_code":{"kind":2,"retType":"number","isInstance":true},"net.Response.reason":{"kind":2,"retType":"string","isInstance":true},"net.Response._read_so_far":{"kind":2,"retType":"number","isInstance":true},"net.Response.headers":{"kind":2,"retType":"StringMap","isInstance":true},"net.Response.__constructor":{"kind":-3,"attributes":{"jsDoc":"The response from a request, contains all the headers/content"},"parameters":[{"name":"socket","type":"net.Socket"}],"isInstance":true},"net.Response.close":{"kind":-1,"attributes":{"jsDoc":"Close, delete and collect the response data"},"parameters":[],"isInstance":true},"net.Response.content":{"kind":-2,"retType":"Buffer","attributes":{"jsDoc":"The HTTP content direct from the socket, as bytes"},"isInstance":true,"isReadOnly":true},"net.Response.text":{"kind":-2,"retType":"string","attributes":{"jsDoc":"The HTTP content, encoded into a string according to the HTTP header encoding"},"isInstance":true,"isReadOnly":true},"net.Response.json":{"kind":-2,"retType":"any","isInstance":true,"isReadOnly":true},"net.Response.toString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"net.Response.to_string"},"net.RequestOptions":{"kind":9,"retType":"net.RequestOptions","extendsTypes":[]},"net.RequestOptions.data":{"kind":2,"retType":"string | Buffer","isInstance":true},"net.RequestOptions.json":{"kind":2,"retType":"any","isInstance":true},"net.RequestOptions.headers":{"kind":2,"retType":"StringMap","isInstance":true},"net.RequestOptions.stream":{"kind":2,"retType":"boolean","isInstance":true},"net.RequestOptions.timeout":{"kind":2,"retType":"number","isInstance":true},"net.dataAsBuffer":{"kind":-3,"retType":"Buffer","parameters":[{"name":"data","type":"string | Buffer"}],"pyQName":"net.data_as_buffer"},"net.request":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Perform an HTTP request to the given url which we will parse to determine\nwhether to use SSL ('https://') or not. We can also send some provided 'data'\nor a json dictionary which we will stringify. 'headers' is optional HTTP headers\nsent along. 'stream' will determine if we buffer everything, or whether to only\nread only when requested"},"parameters":[{"name":"method","type":"string"},{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.head":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP HEAD request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.get":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP GET request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.getString":{"kind":-3,"retType":"string","attributes":{"blockId":"netgetstring","block":"get string $url","jsDoc":"Send HTTP GET request and return text","_def":{"parts":[{"kind":"label","text":"get string ","style":[]},{"kind":"param","name":"url","ref":true}],"parameters":[{"kind":"param","name":"url","ref":true}]}},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}],"pyQName":"net.get_string"},"net.getJSON":{"kind":-3,"retType":"any","attributes":{"blockId":"netgetjson","block":"get json $url","jsDoc":"Send HTTP GET request and return JSON","_def":{"parts":[{"kind":"label","text":"get json ","style":[]},{"kind":"param","name":"url","ref":true}],"parameters":[{"kind":"param","name":"url","ref":true}]}},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}],"pyQName":"net.get_json"},"net.post":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP POST request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.patch":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP PATCH request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.put":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP PUT request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.del":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP DELETE request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"esp32":{"kind":5,"retType":""},"esp32.SOCKET_CLOSED":{"kind":4,"retType":"number"},"esp32.SOCKET_LISTEN":{"kind":4,"retType":"number"},"esp32.SOCKET_SYN_SENT":{"kind":4,"retType":"number"},"esp32.SOCKET_SYN_RCVD":{"kind":4,"retType":"number"},"esp32.SOCKET_ESTABLISHED":{"kind":4,"retType":"number"},"esp32.SOCKET_FIN_WAIT_1":{"kind":4,"retType":"number"},"esp32.SOCKET_FIN_WAIT_2":{"kind":4,"retType":"number"},"esp32.SOCKET_CLOSE_WAIT":{"kind":4,"retType":"number"},"esp32.SOCKET_CLOSING":{"kind":4,"retType":"number"},"esp32.SOCKET_LAST_ACK":{"kind":4,"retType":"number"},"esp32.SOCKET_TIME_WAIT":{"kind":4,"retType":"number"},"esp32.WL_NO_SHIELD":{"kind":4,"retType":"number"},"esp32.WL_NO_MODULE":{"kind":4,"retType":"number"},"esp32.WL_IDLE_STATUS":{"kind":4,"retType":"number"},"esp32.WL_NO_SSID_AVAIL":{"kind":4,"retType":"number"},"esp32.WL_SCAN_COMPLETED":{"kind":4,"retType":"number"},"esp32.WL_CONNECTED":{"kind":4,"retType":"number"},"esp32.WL_CONNECT_FAILED":{"kind":4,"retType":"number"},"esp32.WL_CONNECTION_LOST":{"kind":4,"retType":"number"},"esp32.WL_DISCONNECTED":{"kind":4,"retType":"number"},"esp32.WL_AP_LISTENING":{"kind":4,"retType":"number"},"esp32.WL_AP_CONNECTED":{"kind":4,"retType":"number"},"esp32.WL_AP_FAILED":{"kind":4,"retType":"number"},"esp32.NinaController":{"kind":8,"retType":"esp32.NinaController","extendsTypes":["esp32.NinaController","net.Controller"]},"esp32.NinaController.wasConnected":{"kind":2,"retType":"boolean","isInstance":true,"pyQName":"esp32.NinaController.was_connected"},"esp32.NinaController.__constructor":{"kind":-3,"parameters":[{"name":"_spi","type":"SPI"},{"name":"_cs","type":"DigitalInOutPin"},{"name":"_busy","type":"DigitalInOutPin"},{"name":"_reset","type":"DigitalInOutPin"},{"name":"_gpio0","type":"DigitalInOutPin","initializer":"null"}],"isInstance":true},"esp32.NinaController.reset":{"kind":-1,"attributes":{"jsDoc":"Hard reset the ESP32 using the reset pin"},"parameters":[],"isInstance":true},"esp32.NinaController.status":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"esp32.NinaController.firmwareVersion":{"kind":-2,"retType":"string","attributes":{"jsDoc":"A string of the firmware version on the ESP32"},"isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.firmware_version"},"esp32.NinaController.MACaddress":{"kind":-2,"retType":"Buffer","attributes":{"jsDoc":"A bytearray containing the MAC address of the ESP32"},"isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.ma_caddress"},"esp32.NinaController.wifiSetNetwork":{"kind":-1,"attributes":{"jsDoc":"Tells the ESP32 to set the access point to the given ssid"},"parameters":[{"name":"ssid","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.wifi_set_network"},"esp32.NinaController.wifiSetPassphrase":{"kind":-1,"attributes":{"jsDoc":"Sets the desired access point ssid and passphrase"},"parameters":[{"name":"ssid","type":"string"},{"name":"passphrase","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.wifi_set_passphrase"},"esp32.NinaController.wifiSetEntidentity":{"kind":-1,"attributes":{"jsDoc":"Sets the WPA2 Enterprise anonymous identity"},"parameters":[{"name":"ident","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.wifi_set_entidentity"},"esp32.NinaController.wifiSetEntusername":{"kind":-1,"attributes":{"jsDoc":"Sets the desired WPA2 Enterprise username"},"parameters":[{"name":"username","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.wifi_set_entusername"},"esp32.NinaController.wifiSetEntpassword":{"kind":-1,"attributes":{"jsDoc":"Sets the desired WPA2 Enterprise password"},"parameters":[{"name":"password","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.wifi_set_entpassword"},"esp32.NinaController.wifiSetEntenable":{"kind":-1,"attributes":{"jsDoc":"Enables WPA2 Enterprise mode"},"parameters":[],"isInstance":true,"pyQName":"esp32.NinaController.wifi_set_entenable"},"esp32.NinaController.ssidBuffer":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.ssid_buffer"},"esp32.NinaController.ssid":{"kind":-2,"retType":"string","isInstance":true,"isReadOnly":true},"esp32.NinaController.rssi":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"esp32.NinaController.networkData":{"kind":-2,"retType":"any","isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.network_data"},"esp32.NinaController.ipAddress":{"kind":-2,"retType":"string","isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.ip_address"},"esp32.NinaController.isConnected":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.is_connected"},"esp32.NinaController.isIdle":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"esp32.NinaController.is_idle"},"esp32.NinaController.connectAP":{"kind":-1,"retType":"boolean","attributes":{"jsDoc":"Connect to an access point with given name and password.\nWill retry up to 10 times and return on success"},"parameters":[{"name":"ssid","type":"string"},{"name":"password","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.connect_ap"},"esp32.NinaController.hostbyName":{"kind":-1,"retType":"Buffer","attributes":{"jsDoc":"Convert a hostname to a packed 4-byte IP address. Returns\na 4 bytearray"},"parameters":[{"name":"hostname","type":"string"}],"isInstance":true,"pyQName":"esp32.NinaController.hostby_name"},"esp32.NinaController.ping":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Ping a destination IP address or hostname, with a max time-to-live\n(ttl). Returns a millisecond timing value"},"parameters":[{"name":"dest","type":"string"},{"name":"ttl","initializer":"250"}],"isInstance":true},"esp32.NinaController.socket":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Request a socket from the ESP32, will allocate and return a number that\ncan then be passed to the other socket commands"},"parameters":[],"isInstance":true},"esp32.NinaController.socketOpen":{"kind":-1,"attributes":{"jsDoc":"Open a socket to a destination IP address or hostname\nusing the ESP32's internal reference number. By default we use\n'conn_mode' TCP_MODE but can also use UDP_MODE or TLS_MODE\n(dest must be hostname for TLS_MODE!)"},"parameters":[{"name":"socket_num"},{"name":"dest","type":"string | Buffer"},{"name":"port"},{"name":"conn_mode","initializer":"net.TCP_MODE"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_open"},"esp32.NinaController.socketStatus":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Get the socket connection status, can be SOCKET_CLOSED, SOCKET_LISTEN,\nSOCKET_SYN_SENT, SOCKET_SYN_RCVD, SOCKET_ESTABLISHED, SOCKET_FIN_WAIT_1,\nSOCKET_FIN_WAIT_2, SOCKET_CLOSE_WAIT, SOCKET_CLOSING, SOCKET_LAST_ACK, or\nSOCKET_TIME_WAIT"},"parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_status"},"esp32.NinaController.socket_connected":{"kind":-1,"retType":"boolean","attributes":{"jsDoc":"Test if a socket is connected to the destination, returns boolean true/false"},"parameters":[{"name":"socket_num"}],"isInstance":true},"esp32.NinaController.socketWrite":{"kind":-1,"attributes":{"jsDoc":"Write the bytearray buffer to a socket"},"parameters":[{"name":"socket_num"},{"name":"buffer","type":"Buffer"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_write"},"esp32.NinaController.socketAvailable":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Determine how many bytes are waiting to be read on the socket"},"parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_available"},"esp32.NinaController.socketRead":{"kind":-1,"retType":"Buffer","attributes":{"jsDoc":"Read up to 'size' bytes from the socket number. Returns a bytearray"},"parameters":[{"name":"socket_num"},{"name":"size"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_read"},"esp32.NinaController.socketConnect":{"kind":-1,"retType":"boolean","attributes":{"jsDoc":"Open and verify we connected a socket to a destination IP address or hostname\nusing the ESP32's internal reference number. By default we use\n'conn_mode' TCP_MODE but can also use UDP_MODE or TLS_MODE (dest must\nbe hostname for TLS_MODE!)"},"parameters":[{"name":"socket_num"},{"name":"dest","type":"string | Buffer"},{"name":"port"},{"name":"conn_mode","initializer":"net.TCP_MODE"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_connect"},"esp32.NinaController.socketClose":{"kind":-1,"attributes":{"jsDoc":"Close a socket using the ESP32's internal reference number"},"parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"esp32.NinaController.socket_close"},"esp32.NinaController.setESPdebug":{"kind":-1,"attributes":{"jsDoc":"Enable/disable debug mode on the ESP32. Debug messages will be\nwritten to the ESP32's UART."},"parameters":[{"name":"enabled","type":"boolean"}],"isInstance":true,"pyQName":"esp32.NinaController.set_es_pdebug"},"esp32.NinaController.getTemperature":{"kind":-1,"retType":"number","parameters":[],"isInstance":true,"pyQName":"esp32.NinaController.get_temperature"},"esp32.NinaController.setPinMode":{"kind":-1,"attributes":{"jsDoc":"Set the io mode for a GPIO pin.\n:param int pin: ESP32 GPIO pin to set.\n:param value: direction for pin, digitalio.Direction or integer (0=input, 1=output)."},"parameters":[{"name":"pin"},{"name":"pin_mode"}],"isInstance":true,"pyQName":"esp32.NinaController.set_pin_mode"},"esp32.NinaController.setDigitalWrite":{"kind":-1,"attributes":{"jsDoc":"Set the digital output value of pin.\n:param int pin: ESP32 GPIO pin to write to.\n:param bool value: Value for the pin."},"parameters":[{"name":"pin"},{"name":"value"}],"isInstance":true,"pyQName":"esp32.NinaController.set_digital_write"},"esp32.NinaController.setAnalogWrite":{"kind":-1,"attributes":{"jsDoc":"Set the analog output value of pin, using PWM.\n:param int pin: ESP32 GPIO pin to write to.\n:param float value: 0=off 1.0=full on"},"parameters":[{"name":"pin"},{"name":"analog_value"}],"isInstance":true,"pyQName":"esp32.NinaController.set_analog_write"},"esp32.flashDevice":{"kind":-3,"parameters":[],"pyQName":"esp32.flash_device"}}},"sha":"4f6e6432ee7c33c2d5125fd24b8029b6d2879e020bb358b570500808c20da4c7"},"libs/f4prj":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":"","attributes":{"jsDoc":"These shims are for enabling system keyboard support in text/number prompts."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"texteffects":{"kind":5,"retType":""},"delay":{"kind":4,"retType":"number"},"screen":{"kind":4,"retType":"ScreenImage","attributes":{"whenUsed":"true"}},"_screen_internal.createScreen":{"kind":-3,"retType":"ScreenImage","parameters":[],"pyQName":"_screen_internal.create_screen"}}},"sha":"60e72920653d57476df998518b9aa75c74100f6cf5260c89b8602116a15402ae"},"libs/feather":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"basic":{"kind":5,"retType":""},"pins.A0":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.A1":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.A2":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.A3":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.A4":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.A5":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.D0":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.D1":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.D4":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.D5":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.D6":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.D9":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.D10":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.D11":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.D12":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.D13":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.D2":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}},"pins.D3":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true"}}}},"sha":"9d3cf0e07e8aecaa8b9244021a25ffbbac3025ba02cf93b44dc254427cc68028"},"libs/game":{"apis":{"byQName":{}},"sha":"24153182be5d9bb4ef1a5aec9249a9c8947a5536f169144f480e6d850b71be9f"},"libs/game---light":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"texteffects":{"kind":5,"retType":""},"scene":{"kind":5,"retType":""},"scene.systemMenu":{"kind":5,"retType":""},"power":{"kind":5,"retType":""},"power.poke":{"kind":-3,"parameters":[]},"scene.SCREEN_CLEAR_PRIORITY":{"kind":4,"retType":"number"},"Scene":{"kind":8,"retType":"Scene","extendsTypes":[]},"Scene.millis":{"kind":-1,"retType":"number","parameters":[],"isInstance":true},"Scene.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"Scene.buttonEventHandlers":{"kind":2,"retType":"controller.ButtonEventHandlerState[]","isInstance":true,"pyQName":"Scene.button_event_handlers"},"game":{"kind":5,"retType":"","attributes":{"jsDoc":"Game transitions and dialog"}},"game.currentScene":{"kind":-3,"retType":"Scene","parameters":[],"pyQName":"game.current_scene"},"controller.Controller":{"kind":8,"retType":"controller.Controller","extendsTypes":[]},"controller.Controller.__constructor":{"kind":-3,"parameters":[{"name":"no"},{"name":"v","type":"any"}],"isInstance":true},"controller.Controller.connected":{"kind":2,"retType":"boolean","isInstance":true}}},"sha":"51a425110262fa016ff99d4a76e599483f900c4fd6615b48ca8c624cfcd13f0f"},"libs/hw":{"apis":{"byQName":{}},"sha":"79d7e3be2e587144d827d61a8392f34af8235ea6a93902c2c80d49ada5ee1174"},"libs/hw---n3":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":"","attributes":{"jsDoc":"These shims are for enabling system keyboard support in text/number prompts."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"texteffects":{"kind":5,"retType":""},"delay":{"kind":4,"retType":"number"},"screen":{"kind":4,"retType":"ScreenImage","attributes":{"whenUsed":"true"}},"_screen_internal.createScreen":{"kind":-3,"retType":"ScreenImage","parameters":[],"pyQName":"_screen_internal.create_screen"},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"config.PIN_BTNMX_LATCH":{"kind":4,"retType":"DAL.DEVICE_ID_RADIO"},"config.PIN_BTNMX_CLOCK":{"kind":4,"retType":"DAL.DEVICE_ID_JACDAC_CONTROL_SERVICE"},"config.PIN_BTNMX_DATA":{"kind":4,"retType":"DAL.Transmitting"},"config.PIN_BTN_LEFT":{"kind":4,"retType":"number"},"config.PIN_BTN_UP":{"kind":4,"retType":"number"},"config.PIN_BTN_DOWN":{"kind":4,"retType":"number"},"config.PIN_BTN_RIGHT":{"kind":4,"retType":"number"},"config.PIN_BTN_A":{"kind":4,"retType":"number"},"config.PIN_BTN_B":{"kind":4,"retType":"number"},"config.PIN_BTN_MENU":{"kind":4,"retType":"number"},"config.PIN_JACK_SND":{"kind":4,"retType":"DAL.Receiving"},"config.PIN_DISPLAY_SCK":{"kind":4,"retType":"DAL.DEVICE_ID_LIGHT_SENSOR"},"config.PIN_DISPLAY_MOSI":{"kind":4,"retType":"DAL.DEVICE_ID_GESTURE"},"config.PIN_DISPLAY_MISO":{"kind":4,"retType":"DAL.Transmitting"},"config.PIN_DISPLAY_BL":{"kind":4,"retType":"DAL.DEVICE_ID_GYROSCOPE"},"config.PIN_DISPLAY_DC":{"kind":4,"retType":"DAL.DEVICE_ID_RADIO_DATA_READY"},"config.PIN_DISPLAY_RST":{"kind":4,"retType":"DAL.KEY_5"},"config.PIN_JACK_TX":{"kind":4,"retType":"DAL.DEVICE_ID_SERIAL"},"config.DISPLAY_DELAY":{"kind":4,"retType":"number"},"config.DISPLAY_TYPE":{"kind":4,"retType":"number"},"config.DISPLAY_CFG0":{"kind":4,"retType":"number"},"config.DISPLAY_CFG1":{"kind":4,"retType":"number"},"config.DISPLAY_CFG2":{"kind":4,"retType":"number"},"config.PIN_P0":{"kind":4,"retType":"DAL.Error"},"config.PIN_P1":{"kind":4,"retType":"DAL.Unknown"},"config.PIN_P2":{"kind":4,"retType":"DAL.DEVICE_ID_BUTTON_RESET"}}},"sha":"6378a65f8be847247609e46f6c7aa3baca87b3c78d370950d519097eecde4c83"},"libs/hw---n4":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":"","attributes":{"jsDoc":"These shims are for enabling system keyboard support in text/number prompts."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"texteffects":{"kind":5,"retType":""},"delay":{"kind":4,"retType":"number"},"screen":{"kind":4,"retType":"ScreenImage","attributes":{"whenUsed":"true"}},"_screen_internal.createScreen":{"kind":-3,"retType":"ScreenImage","parameters":[],"pyQName":"_screen_internal.create_screen"},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}}}},"sha":"0e0b0f6e80b0e58ce633aa4ac42f652b2a417f36d938f6ef725674cc56c90710"},"libs/hw---rpi":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":"","attributes":{"jsDoc":"These shims are for enabling system keyboard support in text/number prompts."}},"pins":{"kind":5,"retType":""},"input":{"kind":5,"retType":"","attributes":{"color":"#B4009E","weight":98,"icon":"","groups":["other","More"],"jsDoc":"Respond to and read data from buttons and sensors.\n\nEvents and data from sensors."}},"control.raiseEvent":{"kind":-3,"attributes":{"weight":21,"blockGap":"12","blockId":"control_raise_event","block":"raise event|from %src|with value %value","blockExternalInputs":"1","help":"control/raise-event","inlineInputMode":"external","paramHelp":{"src":"ID of the Component that generated the event","value":"Component specific code indicating the cause of the event.","mode":"optional definition of how the event should be processed after construction."},"jsDoc":"Announce that an event happened to registered handlers.","_def":{"parts":[{"kind":"label","text":"raise event","style":[]},{"kind":"break"},{"kind":"label","text":"from ","style":[]},{"kind":"param","name":"src","ref":false},{"kind":"break"},{"kind":"label","text":"with value ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"src","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"src","description":"ID of the Component that generated the event"},{"name":"value","description":"Component specific code indicating the cause of the event."}],"pyQName":"control.raise_event"},"control.dmesg":{"kind":-3,"attributes":{"jsDoc":"Write data to DMESG debugging buffer."},"parameters":[{"name":"s","type":"string"}]},"serial":{"kind":5,"retType":"","attributes":{"weight":2,"color":"#002050","icon":"","advanced":true,"blockGap":"8","groups":["Write","Read","Events","Configuration"],"jsDoc":"Reading and writing data over a serial connection."}},"serial.writeDmesg":{"kind":-3,"attributes":{"jsDoc":"Send DMESG debug buffer over serial."},"parameters":[],"pyQName":"serial.write_dmesg"},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"texteffects":{"kind":5,"retType":""},"images":{"kind":5,"retType":"","attributes":{"weight":70,"icon":"","color":"#a5b1c2","advanced":true,"jsDoc":"Image manipulation blocks"}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"controller":{"kind":5,"retType":"","attributes":{"weight":98,"color":"#D54322","icon":"","groups":["Single Player","Multiplayer"],"blockGap":"8","jsDoc":"Access to game controls"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"controller.ControllerSceneState":{"kind":9,"retType":"controller.ControllerSceneState","extendsTypes":[]},"controller.ControllerSceneState.lastGesture":{"kind":2,"retType":"ControllerGesture","isInstance":true,"pyQName":"controller.ControllerSceneState.last_gesture"},"controller.ControllerSceneState.gestureHandlers":{"kind":2,"retType":"any","isInstance":true,"pyQName":"controller.ControllerSceneState.gesture_handlers"},"controller.ControllerSceneState.lastCustomGesture":{"kind":2,"retType":"number","isInstance":true,"pyQName":"controller.ControllerSceneState.last_custom_gesture"},"controller.ControllerSceneState.customGestureHandlers":{"kind":2,"retType":"any","isInstance":true,"pyQName":"controller.ControllerSceneState.custom_gesture_handlers"},"controller.ControllerSceneState.lastLightCondition":{"kind":2,"retType":"ControllerLightCondition","isInstance":true,"pyQName":"controller.ControllerSceneState.last_light_condition"},"controller.ControllerSceneState.lightHandlers":{"kind":2,"retType":"any","isInstance":true,"pyQName":"controller.ControllerSceneState.light_handlers"},"controller.CustomGestureHandler":{"kind":9,"retType":"controller.CustomGestureHandler","extendsTypes":[]},"controller.CustomGestureHandler.update":{"kind":2,"retType":"() => boolean","isInstance":true},"controller.CustomGestureHandler.handler":{"kind":2,"retType":"() => void","isInstance":true},"controller.sceneState":{"kind":-3,"retType":"controller.ControllerSceneState","parameters":[],"pyQName":"controller.scene_state"},"controller.vibrate":{"kind":-3,"attributes":{"blockId":"ctrlvibrate","block":"vibrate $millis ms","_shadowOverrides":{"millis":"timePicker"},"group":"Extras","paramHelp":{"millis":""},"jsDoc":"Vibrates the controller for the given duration (in milli seconds)","_def":{"parts":[{"kind":"label","text":"vibrate ","style":[]},{"kind":"param","name":"millis","shadowBlockId":"timePicker","ref":true},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"millis","shadowBlockId":"timePicker","ref":true}]}},"parameters":[{"name":"millis"}]},"ControllerGesture":{"kind":6,"retType":"ControllerGesture","extendsTypes":["ControllerGesture","Number"]},"ControllerGesture.Shake":{"retType":"ControllerGesture.Shake","attributes":{"block":"shake","jsDoc":"Shake gesture","_def":{"parts":[{"kind":"label","text":"shake","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.Shake","Number"],"pyQName":"ControllerGesture.SHAKE"},"ControllerGesture.TiltUp":{"retType":"ControllerGesture.TiltUp","attributes":{"block":"tilt up","jsDoc":"Raised when the device tilts up","_def":{"parts":[{"kind":"label","text":"tilt up","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltUp","Number"],"pyQName":"ControllerGesture.TILT_UP"},"ControllerGesture.TiltDown":{"retType":"ControllerGesture.TiltDown","attributes":{"block":"tilt down","jsDoc":"Raised when the device tilts down","_def":{"parts":[{"kind":"label","text":"tilt down","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltDown","Number"],"pyQName":"ControllerGesture.TILT_DOWN"},"ControllerGesture.TiltLeft":{"retType":"ControllerGesture.TiltLeft","attributes":{"block":"tilt left","jsDoc":"Raised when the screen is pointing left","_def":{"parts":[{"kind":"label","text":"tilt left","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltLeft","Number"],"pyQName":"ControllerGesture.TILT_LEFT"},"ControllerGesture.TiltRight":{"retType":"ControllerGesture.TiltRight","attributes":{"block":"tilt right","jsDoc":"Raised when the screen is pointing right","_def":{"parts":[{"kind":"label","text":"tilt right","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltRight","Number"],"pyQName":"ControllerGesture.TILT_RIGHT"},"ControllerGesture.ScreenUp":{"retType":"ControllerGesture.ScreenUp","attributes":{"block":"screen up","jsDoc":"Raised when the screen faces up","_def":{"parts":[{"kind":"label","text":"screen up","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.ScreenUp","Number"],"pyQName":"ControllerGesture.SCREEN_UP"},"ControllerGesture.ScreenDown":{"retType":"ControllerGesture.ScreenDown","attributes":{"block":"screen down","jsDoc":"Raised when the screen is pointing up and the board is horizontal","_def":{"parts":[{"kind":"label","text":"screen down","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.ScreenDown","Number"],"pyQName":"ControllerGesture.SCREEN_DOWN"},"ControllerGesture.TwoG":{"retType":"ControllerGesture.TwoG","attributes":{"block":"2g (step)","jsDoc":"Raised when a 2G shock is detected","_def":{"parts":[{"kind":"label","text":"2g (step)","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TwoG","Number"],"pyQName":"ControllerGesture.TWO_G"},"ControllerGesture.ThreeG":{"retType":"ControllerGesture.ThreeG","attributes":{"block":"3g","jsDoc":"Raised when a 3G shock is detected","_def":{"parts":[{"kind":"label","text":"3g","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.ThreeG","Number"],"pyQName":"ControllerGesture.THREE_G"},"ControllerGesture.SixG":{"retType":"ControllerGesture.SixG","attributes":{"block":"6g","jsDoc":"Raised when a 6G shock is detected","_def":{"parts":[{"kind":"label","text":"6g","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.SixG","Number"],"pyQName":"ControllerGesture.SIX_G"},"ControllerGesture.EightG":{"retType":"ControllerGesture.EightG","attributes":{"block":"8g","jsDoc":"Raised when a 8G shock is detected","_def":{"parts":[{"kind":"label","text":"8g","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.EightG","Number"],"pyQName":"ControllerGesture.EIGHT_G"},"ControllerDimension":{"kind":6,"retType":"ControllerDimension","extendsTypes":["ControllerDimension","Number"]},"ControllerDimension.X":{"retType":"ControllerDimension.X","attributes":{"block":"x","_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.X","Number"]},"ControllerDimension.Y":{"retType":"ControllerDimension.Y","attributes":{"block":"y","_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.Y","Number"]},"ControllerDimension.Z":{"retType":"ControllerDimension.Z","attributes":{"block":"z","_def":{"parts":[{"kind":"label","text":"z","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.Z","Number"]},"ControllerDimension.Strength":{"retType":"ControllerDimension.Strength","attributes":{"block":"strength","_def":{"parts":[{"kind":"label","text":"strength","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.Strength","Number"],"pyQName":"ControllerDimension.STRENGTH"},"controller.onGesture":{"kind":-3,"attributes":{"blockId":"ctrlongesture","block":"on |%NAME","parts":"accelerometer","paramFieldEditor":{"gesture":"gridpicker"},"paramFieldEditorOptions":{"gesture":{"width":"220","columns":"3"}},"group":"Extras","paramHelp":{"gesture":"the type of gesture to track","body":"code to run when gesture is raised"},"jsDoc":"Do something when a gesture happens (like shaking the board).","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"gesture","description":"the type of gesture to track","type":"ControllerGesture","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.on_gesture"},"controller.onCustomGesture":{"kind":-3,"attributes":{"paramHelp":{"id":"@param update","handler":""},"jsDoc":"Register a custom gesture for the controller"},"parameters":[{"name":"id","description":"@param update"},{"name":"update","type":"() => boolean","handlerParameters":[]},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.on_custom_gesture"},"controller.acceleration":{"kind":-3,"retType":"number","attributes":{"blockId":"ctrlaccelerationvalue","block":"acceleration (mg)|%NAME","parts":"accelerometer","paramFieldEditor":{"dimension":"gridpicker"},"paramFieldEditorOptions":{"dimension":{"width":"180","columns":"2"}},"group":"Extras","paramHelp":{"dimension":"the axis along which the acceleration if measured"},"jsDoc":"Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\nx=0, y=0 and z=-1023)","_def":{"parts":[{"kind":"label","text":"acceleration (mg)","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"dimension","description":"the axis along which the acceleration if measured","type":"ControllerDimension","isEnum":true}]},"ControllerLightCondition":{"kind":6,"retType":"ControllerLightCondition","extendsTypes":["ControllerLightCondition","Number"]},"ControllerLightCondition.Dark":{"retType":"ControllerLightCondition.Dark","attributes":{"block":"dark","_def":{"parts":[{"kind":"label","text":"dark","style":[]}],"parameters":[]}},"extendsTypes":["ControllerLightCondition.Dark","Number"],"pyQName":"ControllerLightCondition.DARK"},"ControllerLightCondition.Bright":{"retType":"ControllerLightCondition.Bright","attributes":{"block":"bright","_def":{"parts":[{"kind":"label","text":"bright","style":[]}],"parameters":[]}},"extendsTypes":["ControllerLightCondition.Bright","Number"],"pyQName":"ControllerLightCondition.BRIGHT"},"controller.lightLevel":{"kind":-3,"retType":"number","attributes":{"blockId":"ctrllightlevel","block":"light level","parts":"lightsensor","weight":30,"blockGap":"8","group":"Extras","jsDoc":"Read the light level applied to the LED screen in a range from 0 (dark) to 255 (bright).","_def":{"parts":[{"kind":"label","text":"light level","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"controller.light_level"},"controller.onLightConditionChanged":{"kind":-3,"attributes":{"blockId":"ctrlonlightcondition","block":"on light %condition","parts":"lightsensor","weight":84,"blockGap":"12","group":"Extras","paramHelp":{"condition":"the condition that event triggers on"},"jsDoc":"Register an event that runs when light conditions (darker or brighter) change.","_def":{"parts":[{"kind":"label","text":"on light ","style":[]},{"kind":"param","name":"condition","ref":false}],"parameters":[{"kind":"param","name":"condition","ref":false}]}},"parameters":[{"name":"condition","description":"the condition that event triggers on","type":"ControllerLightCondition","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.on_light_condition_changed"},"ControllerTemperatureUnit":{"kind":6,"retType":"ControllerTemperatureUnit","extendsTypes":["ControllerTemperatureUnit","Number"]},"ControllerTemperatureUnit.Celsius":{"retType":"ControllerTemperatureUnit.Celsius","attributes":{"block":"°C","_def":{"parts":[{"kind":"label","text":"°C","style":[]}],"parameters":[]}},"extendsTypes":["ControllerTemperatureUnit.Celsius","Number"],"pyQName":"ControllerTemperatureUnit.CELSIUS"},"ControllerTemperatureUnit.Fahrenheit":{"retType":"ControllerTemperatureUnit.Fahrenheit","attributes":{"block":"°F","_def":{"parts":[{"kind":"label","text":"°F","style":[]}],"parameters":[]}},"extendsTypes":["ControllerTemperatureUnit.Fahrenheit","Number"],"pyQName":"ControllerTemperatureUnit.FAHRENHEIT"},"controller.temperature":{"kind":-3,"retType":"number","attributes":{"blockId":"ctrltemperature","block":"temperature in %unit","parts":"thermometer","weight":26,"group":"Extras","jsDoc":"Get the temperature in Celsius or Fahrenheit degrees.","_def":{"parts":[{"kind":"label","text":"temperature in ","style":[]},{"kind":"param","name":"unit","ref":false}],"parameters":[{"kind":"param","name":"unit","ref":false}]}},"parameters":[{"name":"unit","type":"ControllerTemperatureUnit","isEnum":true}]},"controller.configureRepeatEventDefaults":{"kind":-3,"attributes":{"paramDefl":{"delay":"500","interval":"30"},"blockId":"repeatDefaultDelayInterval","block":"set button repeat delay $delay ms interval $interval ms","weight":10,"group":"Single Player","paramHelp":{"delay":"number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500","interval":"minimum number of milliseconds between calls to the button repeat event, eg: 30"},"jsDoc":"Configures the timing of the on button repeat event for all of the controller buttons","_def":{"parts":[{"kind":"label","text":"set button repeat delay ","style":[]},{"kind":"param","name":"delay","ref":true},{"kind":"label","text":" ms interval ","style":[]},{"kind":"param","name":"interval","ref":true},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"delay","ref":true},{"kind":"param","name":"interval","ref":true}]}},"parameters":[{"name":"delay","description":"number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500","default":"500"},{"name":"interval","description":"minimum number of milliseconds between calls to the button repeat event, eg: 30","default":"30"}],"pyQName":"controller.configure_repeat_event_defaults"},"controller.startLightPulse":{"kind":-3,"attributes":{"blockId":"ctrllightpulse","block":"start light pulse %rgb=colorNumberPicker|for %duration=timePicker|ms","weight":80,"blockGap":"8","group":"Extras","paramHelp":{"rgb":"RGB color of the LED"},"jsDoc":"Shows a color pulse","_def":{"parts":[{"kind":"label","text":"start light pulse ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"break"},{"kind":"label","text":"for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"rgb","description":"RGB color of the LED"},{"name":"duration"}],"pyQName":"controller.start_light_pulse"},"light":{"kind":5,"retType":"","attributes":{"advanced":true}},"controller.crankPosition":{"kind":-3,"retType":"number","attributes":{"blockId":"controller_crank_position","block":"crank position","weight":29,"blockGap":"8","group":"Extras","jsDoc":"Gets the current position of the crank.","_def":{"parts":[{"kind":"label","text":"crank position","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"controller.crank_position"},"controller.__internal":{"kind":5,"retType":""},"controller.__internal.onGesture":{"kind":-3,"parameters":[{"name":"gesture","type":"ControllerGesture","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.__internal.on_gesture"},"controller.__internal.onCustomGesture":{"kind":-3,"parameters":[{"name":"id"},{"name":"update","type":"() => boolean","handlerParameters":[]},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.__internal.on_custom_gesture"},"controller.__internal.acceleration":{"kind":-3,"retType":"number","parameters":[{"name":"dimension","type":"ControllerDimension","isEnum":true}]},"controller.__internal.crankPosition":{"kind":-3,"retType":"number","parameters":[],"pyQName":"controller.__internal.crank_position"},"controller.__internal.startLightPulse":{"kind":-3,"parameters":[{"name":"rgb"},{"name":"duration"}],"pyQName":"controller.__internal.start_light_pulse"},"controller.__internal.lightLevel":{"kind":-3,"retType":"number","parameters":[],"pyQName":"controller.__internal.light_level"},"controller.__internal.onLightConditionChanged":{"kind":-3,"parameters":[{"name":"condition","type":"ControllerLightCondition","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.__internal.on_light_condition_changed"},"controller.__internal.temperature":{"kind":-3,"retType":"number","parameters":[{"name":"unit","type":"ControllerTemperatureUnit","isEnum":true}]},"controller.__internal.vibrate":{"kind":-3,"parameters":[{"name":"millis"}]},"serial.device":{"kind":-3,"retType":"serial.Serial","parameters":[]},"serial.NEW_LINE":{"kind":4,"retType":"string"},"serial.NEW_LINE_DELIMITER":{"kind":4,"retType":"Delimiters"},"serial.Serial":{"kind":8,"retType":"serial.Serial","extendsTypes":[]},"serial.Serial.serialDevice":{"kind":2,"retType":"SerialDevice","isInstance":true,"pyQName":"serial.Serial.serial_device"},"serial.Serial.decoder":{"kind":2,"retType":"UTF8Decoder","isInstance":true},"serial.Serial.__constructor":{"kind":-3,"parameters":[{"name":"serialDevice","type":"SerialDevice"}],"isInstance":true},"serial.Serial.readString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"serial.Serial.read_string"},"serial.Serial.readLine":{"kind":-1,"retType":"string","parameters":[{"name":"timeOut","initializer":"undefined"}],"isInstance":true,"pyQName":"serial.Serial.read_line"},"serial.Serial.readUntil":{"kind":-1,"retType":"string","parameters":[{"name":"delimiter","type":"Delimiters","isEnum":true},{"name":"timeOut","initializer":"undefined"}],"isInstance":true,"pyQName":"serial.Serial.read_until"},"serial.Serial.writeString":{"kind":-1,"parameters":[{"name":"text","type":"string"}],"isInstance":true,"pyQName":"serial.Serial.write_string"},"serial.Serial.writeLine":{"kind":-1,"parameters":[{"name":"text","type":"string"}],"isInstance":true,"pyQName":"serial.Serial.write_line"},"serial.readString":{"kind":-3,"retType":"string","attributes":{"help":"serial/read-string","blockId":"serial_read_string","block":"serial|read string","weight":18,"group":"Read","jsDoc":"Read the buffered received data as a string","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read string","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.read_string"},"serial.readLine":{"kind":-3,"retType":"string","attributes":{"help":"serial/read-line","blockId":"serial_read_line","block":"serial|read line","weight":20,"blockGap":"8","group":"Read","jsDoc":"Read a line of text from the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read line","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.read_line"},"serial.readUntil":{"kind":-3,"retType":"string","attributes":{"help":"serial/read-until","blockId":"serial_read_until","block":"serial|read until %delimiter=serial_delimiter_conv","weight":19,"group":"Read","paramHelp":{"delimiter":"text delimiter that separates each text chunk"},"jsDoc":"Read a line of text from the serial port and return the buffer when the delimiter is met.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read until ","style":[]},{"kind":"param","name":"delimiter","shadowBlockId":"serial_delimiter_conv","ref":false}],"parameters":[{"kind":"param","name":"delimiter","shadowBlockId":"serial_delimiter_conv","ref":false}]}},"parameters":[{"name":"delimiter","description":"text delimiter that separates each text chunk","type":"Delimiters","isEnum":true},{"name":"timeOut","initializer":"undefined"}],"pyQName":"serial.read_until"},"serial.writeString":{"kind":-3,"attributes":{"help":"serial/write-string","weight":87,"blockId":"serial_writestring","block":"serial|write string %text","group":"Write","jsDoc":"Write some text to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write string ","style":[]},{"kind":"param","name":"text","ref":false}],"parameters":[{"kind":"param","name":"text","ref":false}]}},"parameters":[{"name":"text","type":"string"}],"pyQName":"serial.write_string"},"serial.writeLine":{"kind":-3,"attributes":{"weight":90,"help":"serial/write-line","blockGap":"8","blockId":"serial_writeline","block":"serial|write line %text","group":"Write","paramHelp":{"value":"to send over serial"},"jsDoc":"Write a line of text to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write line ","style":[]},{"kind":"param","name":"text","ref":false}],"parameters":[{"kind":"param","name":"text","ref":false}]}},"parameters":[{"name":"text","type":"string"}],"pyQName":"serial.write_line"},"serial.writeNumber":{"kind":-3,"attributes":{"help":"serial/write-number","weight":89,"blockGap":"8","blockId":"serial_writenumber","block":"serial|write number %value","group":"Write","jsDoc":"Write a number to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write number ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value"}],"pyQName":"serial.write_number"},"serial.writeValue":{"kind":-3,"attributes":{"paramDefl":{"name":"x"},"weight":88,"blockGap":"8","help":"serial/write-value","blockId":"serial_writevalue","block":"serial|write value %name|= %value","group":"Write","paramHelp":{"name":"name of the value stream, eg: \"x\"","value":"to write"},"jsDoc":"Write a name:value pair as a line of text to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write value ","style":[]},{"kind":"param","name":"name","ref":false},{"kind":"break"},{"kind":"label","text":"= ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"name","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"name","description":"name of the value stream, eg: \"x\"","type":"string","default":"x"},{"name":"value","description":"to write"}],"pyQName":"serial.write_value"},"serial.setRxBufferSize":{"kind":-3,"attributes":{"help":"serial/set-rx-buffer-size","blockId":"serialsetrxbuffersize","block":"serial set rx buffer size to $size","weight":10,"group":"Configuration","jsDoc":"Sets the size of the RX buffer in bytes","_def":{"parts":[{"kind":"label","text":"serial set rx buffer size to ","style":[]},{"kind":"param","name":"size","ref":true}],"parameters":[{"kind":"param","name":"size","ref":true}]}},"parameters":[{"name":"size"}],"pyQName":"serial.set_rx_buffer_size"},"serial.setTxBufferSize":{"kind":-3,"attributes":{"help":"serial/set-tx-buffer-size","blockId":"serialsettxbuffersize","block":"serial set tx buffer size to $size","weight":9,"group":"Configuration","jsDoc":"Sets the size of the TX buffer in bytes","_def":{"parts":[{"kind":"label","text":"serial set tx buffer size to ","style":[]},{"kind":"param","name":"size","ref":true}],"parameters":[{"kind":"param","name":"size","ref":true}]}},"parameters":[{"name":"size"}],"pyQName":"serial.set_tx_buffer_size"},"serial.read":{"kind":-3,"retType":"number","attributes":{"Group":"Read","jsDoc":"Reads a single byte from the serial receive buffer. Negative if error, 0 if no data."},"parameters":[]},"serial.readBuffer":{"kind":-3,"retType":"Buffer","attributes":{"help":"serial/read-buffer","blockId":"serial_read_buffer","block":"serial|read buffer","weight":17,"group":"Read","jsDoc":"Read the buffered received data as a buffer","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read buffer","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.read_buffer"},"serial.writeBuffer":{"kind":-3,"attributes":{"help":"serial/write-buffer","weight":6,"blockId":"serial_writebuffer","block":"serial|write buffer %buffer","group":"Write","jsDoc":"Send a buffer across the serial connection.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write buffer ","style":[]},{"kind":"param","name":"buffer","ref":false}],"parameters":[{"kind":"param","name":"buffer","ref":false}]}},"parameters":[{"name":"buffer","type":"Buffer"}],"pyQName":"serial.write_buffer"},"serial.setBaudRate":{"kind":-3,"attributes":{"weight":10,"blockId":"serial_setbaudrate","block":"serial|set baud rate %rate","blockGap":"8","inlineInputMode":"inline","help":"serial/set-baud-rate","group":"Configuration","jsDoc":"Set the baud rate of the serial port","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"set baud rate ","style":[]},{"kind":"param","name":"rate","ref":false}],"parameters":[{"kind":"param","name":"rate","ref":false}]}},"parameters":[{"name":"rate","type":"BaudRate","isEnum":true}],"pyQName":"serial.set_baud_rate"},"serial.attachToConsole":{"kind":-3,"attributes":{"blockId":"serialsendtoconsole","block":"serial attach to console","group":"Configuration","help":"serial/attach-to-console","jsDoc":"Send console messages through the TX, RX pins","_def":{"parts":[{"kind":"label","text":"serial attach to console","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.attach_to_console"},"serial.onEvent":{"kind":-3,"attributes":{"weight":9,"help":"serial/on-event","blockId":"serial_onevent","block":"serial on %event","blockGap":"8","group":"Events","jsDoc":"Registers code when serial events happen","_def":{"parts":[{"kind":"label","text":"serial on ","style":[]},{"kind":"param","name":"event","ref":false}],"parameters":[{"kind":"param","name":"event","ref":false}]}},"parameters":[{"name":"event","type":"SerialEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"serial.on_event"},"serial.onDelimiterReceived":{"kind":-3,"attributes":{"weight":10,"help":"serial/on-delimiter-received","blockId":"serial_ondelimiter","block":"serial on delimiter $delimiter received","blockGap":"8","group":"Events","jsDoc":"Registers code when a delimiter is received","_def":{"parts":[{"kind":"label","text":"serial on delimiter ","style":[]},{"kind":"param","name":"delimiter","ref":true},{"kind":"label","text":" received","style":[]}],"parameters":[{"kind":"param","name":"delimiter","ref":true}]}},"parameters":[{"name":"delimiter","type":"Delimiters","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"serial.on_delimiter_received"},"serial.delimiters":{"kind":-3,"retType":"string","attributes":{"blockId":"serial_delimiter_conv","block":"%del","weight":1,"blockHidden":true,"hidden":"true","jsDoc":"Return the corresponding delimiter string","_def":{"parts":[{"kind":"param","name":"del","ref":false}],"parameters":[{"kind":"param","name":"del","ref":false}]}},"parameters":[{"name":"del","type":"Delimiters","isEnum":true}]},"BaudRate":{"kind":6,"retType":"BaudRate","extendsTypes":["BaudRate","Number"]},"BaudRate.BaudRate115200":{"retType":"BaudRate.BaudRate115200","attributes":{"block":"115200","_def":{"parts":[{"kind":"label","text":"115200","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate115200","Number"],"pyQName":"BaudRate.BAUD_RATE115200"},"BaudRate.BaudRate57600":{"retType":"BaudRate.BaudRate57600","attributes":{"block":"57600","_def":{"parts":[{"kind":"label","text":"57600","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate57600","Number"],"pyQName":"BaudRate.BAUD_RATE57600"},"BaudRate.BaudRate38400":{"retType":"BaudRate.BaudRate38400","attributes":{"block":"38400","_def":{"parts":[{"kind":"label","text":"38400","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate38400","Number"],"pyQName":"BaudRate.BAUD_RATE38400"},"BaudRate.BaudRate31250":{"retType":"BaudRate.BaudRate31250","attributes":{"block":"31250","_def":{"parts":[{"kind":"label","text":"31250","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate31250","Number"],"pyQName":"BaudRate.BAUD_RATE31250"},"BaudRate.BaudRate28800":{"retType":"BaudRate.BaudRate28800","attributes":{"block":"28800","_def":{"parts":[{"kind":"label","text":"28800","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate28800","Number"],"pyQName":"BaudRate.BAUD_RATE28800"},"BaudRate.BaudRate19200":{"retType":"BaudRate.BaudRate19200","attributes":{"block":"19200","_def":{"parts":[{"kind":"label","text":"19200","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate19200","Number"],"pyQName":"BaudRate.BAUD_RATE19200"},"BaudRate.BaudRate14400":{"retType":"BaudRate.BaudRate14400","attributes":{"block":"14400","_def":{"parts":[{"kind":"label","text":"14400","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate14400","Number"],"pyQName":"BaudRate.BAUD_RATE14400"},"BaudRate.BaudRate9600":{"retType":"BaudRate.BaudRate9600","attributes":{"block":"9600","_def":{"parts":[{"kind":"label","text":"9600","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate9600","Number"],"pyQName":"BaudRate.BAUD_RATE9600"},"BaudRate.BaudRate4800":{"retType":"BaudRate.BaudRate4800","attributes":{"block":"4800","_def":{"parts":[{"kind":"label","text":"4800","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate4800","Number"],"pyQName":"BaudRate.BAUD_RATE4800"},"BaudRate.BaudRate2400":{"retType":"BaudRate.BaudRate2400","attributes":{"block":"2400","_def":{"parts":[{"kind":"label","text":"2400","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate2400","Number"],"pyQName":"BaudRate.BAUD_RATE2400"},"BaudRate.BaudRate1200":{"retType":"BaudRate.BaudRate1200","attributes":{"block":"1200","_def":{"parts":[{"kind":"label","text":"1200","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate1200","Number"],"pyQName":"BaudRate.BAUD_RATE1200"},"BaudRate.BaudRate300":{"retType":"BaudRate.BaudRate300","attributes":{"block":"300","_def":{"parts":[{"kind":"label","text":"300","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate300","Number"],"pyQName":"BaudRate.BAUD_RATE300"},"SerialEvent":{"kind":6,"retType":"SerialEvent","extendsTypes":["SerialEvent","Number"]},"SerialEvent.DataReceived":{"retType":"SerialEvent.DataReceived","attributes":{"block":"data received","_def":{"parts":[{"kind":"label","text":"data received","style":[]}],"parameters":[]}},"extendsTypes":["SerialEvent.DataReceived","Number"],"pyQName":"SerialEvent.DATA_RECEIVED"},"SerialEvent.RxBufferFull":{"retType":"SerialEvent.RxBufferFull","attributes":{"block":"rx buffer full","_def":{"parts":[{"kind":"label","text":"rx buffer full","style":[]}],"parameters":[]}},"extendsTypes":["SerialEvent.RxBufferFull","Number"],"pyQName":"SerialEvent.RX_BUFFER_FULL"},"Delimiters":{"kind":6,"retType":"Delimiters","extendsTypes":["Delimiters","Number"]},"Delimiters.NewLine":{"retType":"Delimiters.NewLine","attributes":{"block":"new line (\n)","_def":{"parts":[{"kind":"label","text":"new line (\n)","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.NewLine","Number"],"pyQName":"Delimiters.NEW_LINE"},"Delimiters.Comma":{"retType":"Delimiters.Comma","attributes":{"block":",","_def":{"parts":[{"kind":"label","text":",","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Comma","Number"],"pyQName":"Delimiters.COMMA"},"Delimiters.Dollar":{"retType":"Delimiters.Dollar","attributes":{"block":"$","_def":{"parts":[{"kind":"param","name":"","ref":true}],"parameters":[{"kind":"param","name":"","ref":true}]}},"extendsTypes":["Delimiters.Dollar","Number"],"pyQName":"Delimiters.DOLLAR"},"Delimiters.Colon":{"retType":"Delimiters.Colon","attributes":{"block":":","_def":{"parts":[{"kind":"label","text":":","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Colon","Number"],"pyQName":"Delimiters.COLON"},"Delimiters.Fullstop":{"retType":"Delimiters.Fullstop","attributes":{"block":".","_def":{"parts":[{"kind":"label","text":".","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Fullstop","Number"],"pyQName":"Delimiters.FULLSTOP"},"Delimiters.Hash":{"retType":"Delimiters.Hash","attributes":{"block":"#","_def":{"parts":[{"kind":"label","text":"#","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Hash","Number"],"pyQName":"Delimiters.HASH"},"Delimiters.CarriageReturn":{"retType":"Delimiters.CarriageReturn","attributes":{"block":"carriage return (\r)","_def":{"parts":[{"kind":"label","text":"carriage return (\r)","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.CarriageReturn","Number"],"pyQName":"Delimiters.CARRIAGE_RETURN"},"Delimiters.Space":{"retType":"Delimiters.Space","attributes":{"block":"space","_def":{"parts":[{"kind":"label","text":"space","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Space","Number"],"pyQName":"Delimiters.SPACE"},"Delimiters.Tab":{"retType":"Delimiters.Tab","attributes":{"block":"tab (\t)","_def":{"parts":[{"kind":"label","text":"tab (\t)","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Tab","Number"],"pyQName":"Delimiters.TAB"},"Delimiters.Pipe":{"retType":"Delimiters.Pipe","attributes":{"block":"|","_def":{"parts":[{"kind":"break"}],"parameters":[]}},"extendsTypes":["Delimiters.Pipe","Number"],"pyQName":"Delimiters.PIPE"},"Delimiters.SemiColon":{"retType":"Delimiters.SemiColon","attributes":{"block":";","_def":{"parts":[{"kind":"label","text":";","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.SemiColon","Number"],"pyQName":"Delimiters.SEMI_COLON"},"serial.internalCreateSerialDevice":{"kind":-3,"retType":"SerialDevice","attributes":{"jsDoc":"Opens a Serial communication driver"},"parameters":[{"name":"id"}],"pyQName":"serial.internal_create_serial_device"},"SerialDevice":{"kind":9,"retType":"SerialDevice","extendsTypes":[]},"SerialDevice.setRxBufferSize":{"kind":-1,"attributes":{"jsDoc":"Sets the size of the RX buffer in bytes"},"parameters":[{"name":"size"}],"isInstance":true,"pyQName":"SerialDevice.set_rx_buffer_size"},"SerialDevice.setTxBufferSize":{"kind":-1,"attributes":{"jsDoc":"Sets the size of the TX buffer in bytes"},"parameters":[{"name":"size"}],"isInstance":true,"pyQName":"SerialDevice.set_tx_buffer_size"},"SerialDevice.setBaudRate":{"kind":-1,"attributes":{"jsDoc":"Set the baud rate of the serial port"},"parameters":[{"name":"rate","type":"BaudRate","isEnum":true}],"isInstance":true,"pyQName":"SerialDevice.set_baud_rate"},"SerialDevice.read":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Reads a single byte from the serial receive buffer. Negative if error, 0 if no data."},"parameters":[],"isInstance":true},"SerialDevice.readBuffer":{"kind":-1,"retType":"Buffer","attributes":{"jsDoc":"Read the buffered received data as a buffer"},"parameters":[],"isInstance":true,"pyQName":"SerialDevice.read_buffer"},"SerialDevice.writeBuffer":{"kind":-1,"attributes":{"jsDoc":"Send a buffer across the serial connection."},"parameters":[{"name":"buffer","type":"Buffer"}],"isInstance":true,"pyQName":"SerialDevice.write_buffer"},"SerialDevice.onEvent":{"kind":-1,"attributes":{"jsDoc":"Register code when a serial event occurs"},"parameters":[{"name":"event","type":"SerialEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"SerialDevice.on_event"},"SerialDevice.onDelimiterReceived":{"kind":-1,"attributes":{"jsDoc":"Registers code when a delimiter is received"},"parameters":[{"name":"delimiter","type":"Delimiters","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"SerialDevice.on_delimiter_received"},"Key":{"kind":6,"retType":"Key","extendsTypes":["Key","Number"]},"Key.LEFT":{"retType":"Key.LEFT","extendsTypes":["Key.LEFT","Number"]},"Key.UP":{"retType":"Key.UP","extendsTypes":["Key.UP","Number"]},"Key.RIGHT":{"retType":"Key.RIGHT","extendsTypes":["Key.RIGHT","Number"]},"Key.DOWN":{"retType":"Key.DOWN","extendsTypes":["Key.DOWN","Number"]},"Key.A":{"retType":"Key.A","extendsTypes":["Key.A","Number"]},"Key.B":{"retType":"Key.B","extendsTypes":["Key.B","Number"]},"Key.MENU":{"retType":"Key.MENU","extendsTypes":["Key.MENU","Number"]},"Key.LEFT2":{"retType":"Key.LEFT2","extendsTypes":["Key.LEFT2","Number"]},"Key.UP2":{"retType":"Key.UP2","extendsTypes":["Key.UP2","Number"]},"Key.RIGHT2":{"retType":"Key.RIGHT2","extendsTypes":["Key.RIGHT2","Number"]},"Key.DOWN2":{"retType":"Key.DOWN2","extendsTypes":["Key.DOWN2","Number"]},"Key.A2":{"retType":"Key.A2","extendsTypes":["Key.A2","Number"]},"Key.B2":{"retType":"Key.B2","extendsTypes":["Key.B2","Number"]},"Key.RESET":{"retType":"Key.RESET","extendsTypes":["Key.RESET","Number"]},"Key.EXIT":{"retType":"Key.EXIT","extendsTypes":["Key.EXIT","Number"]},"control.runProgram":{"kind":-3,"attributes":{"jsDoc":"Run specified user program."},"parameters":[{"name":"prog","type":"string"}],"pyQName":"control.run_program"},"control.deleteProgram":{"kind":-3,"attributes":{"jsDoc":"Deletes a user program"},"parameters":[{"name":"prog","type":"string"}],"pyQName":"control.delete_program"},"control.programList":{"kind":-3,"retType":"string[]","parameters":[],"pyQName":"control.program_list"}}},"sha":"1100aa65485df50c762d6acb7e5f0309eb4fe9458a514395382802e11168ea41"},"libs/hw---samd51":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":"","attributes":{"jsDoc":"These shims are for enabling system keyboard support in text/number prompts."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"texteffects":{"kind":5,"retType":""},"delay":{"kind":4,"retType":"number"},"screen":{"kind":4,"retType":"ScreenImage","attributes":{"whenUsed":"true"}},"_screen_internal.createScreen":{"kind":-3,"retType":"ScreenImage","parameters":[],"pyQName":"_screen_internal.create_screen"},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}}}},"sha":"df9e4727818ce9cf59ab5af588ef980b403d5457a4b412fb65909149f1a80209"},"libs/hw---stm32f401":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":"","attributes":{"jsDoc":"These shims are for enabling system keyboard support in text/number prompts."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"texteffects":{"kind":5,"retType":""},"delay":{"kind":4,"retType":"number"},"screen":{"kind":4,"retType":"ScreenImage","attributes":{"whenUsed":"true"}},"_screen_internal.createScreen":{"kind":-3,"retType":"ScreenImage","parameters":[],"pyQName":"_screen_internal.create_screen"},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}}}},"sha":"e1e12db4a5888b798f7796e2c09bb715d61c66e958c055031f1d1b798c08d050"},"libs/hw---rp2040":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":"","attributes":{"jsDoc":"These shims are for enabling system keyboard support in text/number prompts."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"texteffects":{"kind":5,"retType":""},"delay":{"kind":4,"retType":"number"},"screen":{"kind":4,"retType":"ScreenImage","attributes":{"whenUsed":"true"}},"_screen_internal.createScreen":{"kind":-3,"retType":"ScreenImage","parameters":[],"pyQName":"_screen_internal.create_screen"},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}}}},"sha":"2b39607359cc2d7749457b2f82636010edbb0adf97403411c3be422d6ecc2e3f"},"libs/hw---vm":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":"","attributes":{"jsDoc":"These shims are for enabling system keyboard support in text/number prompts."}},"pins":{"kind":5,"retType":""},"control.raiseEvent":{"kind":-3,"attributes":{"weight":21,"blockGap":"12","blockId":"control_raise_event","block":"raise event|from %src|with value %value","blockExternalInputs":"1","help":"control/raise-event","inlineInputMode":"external","paramHelp":{"src":"ID of the Component that generated the event","value":"Component specific code indicating the cause of the event.","mode":"optional definition of how the event should be processed after construction."},"jsDoc":"Announce that an event happened to registered handlers.","_def":{"parts":[{"kind":"label","text":"raise event","style":[]},{"kind":"break"},{"kind":"label","text":"from ","style":[]},{"kind":"param","name":"src","ref":false},{"kind":"break"},{"kind":"label","text":"with value ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"src","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"src","description":"ID of the Component that generated the event"},{"name":"value","description":"Component specific code indicating the cause of the event."}],"pyQName":"control.raise_event"},"control.dmesg":{"kind":-3,"attributes":{"jsDoc":"Write data to DMESG debugging buffer."},"parameters":[{"name":"s","type":"string"}]},"serial":{"kind":5,"retType":""},"serial.writeDmesg":{"kind":-3,"attributes":{"jsDoc":"Send DMESG debug buffer over serial."},"parameters":[],"pyQName":"serial.write_dmesg"},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"texteffects":{"kind":5,"retType":""},"images":{"kind":5,"retType":"","attributes":{"weight":70,"icon":"","color":"#a5b1c2","advanced":true,"jsDoc":"Image manipulation blocks"}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"Key":{"kind":6,"retType":"Key","extendsTypes":["Key","Number"]},"Key.KEY_LEFT":{"retType":"Key.KEY_LEFT","extendsTypes":["Key.KEY_LEFT","Number"]},"Key.KEY_UP":{"retType":"Key.KEY_UP","extendsTypes":["Key.KEY_UP","Number"]},"Key.KEY_RIGHT":{"retType":"Key.KEY_RIGHT","extendsTypes":["Key.KEY_RIGHT","Number"]},"Key.KEY_DOWN":{"retType":"Key.KEY_DOWN","extendsTypes":["Key.KEY_DOWN","Number"]},"Key.KEY_A":{"retType":"Key.KEY_A","extendsTypes":["Key.KEY_A","Number"]},"Key.KEY_B":{"retType":"Key.KEY_B","extendsTypes":["Key.KEY_B","Number"]},"Key.KEY_MENU":{"retType":"Key.KEY_MENU","extendsTypes":["Key.KEY_MENU","Number"]},"Key.KEY_RESET":{"retType":"Key.KEY_RESET","extendsTypes":["Key.KEY_RESET","Number"]},"Key.KEY_EXIT":{"retType":"Key.KEY_EXIT","extendsTypes":["Key.KEY_EXIT","Number"]},"control.runProgram":{"kind":-3,"attributes":{"jsDoc":"Run specified user program."},"parameters":[{"name":"prog","type":"string"}],"pyQName":"control.run_program"}}},"sha":"5734170b7a6a69d696ce9e62da9db3ae02659f7001cf16adc3828f78cc038a45"},"libs/keyboard":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"keyboard":{"kind":5,"retType":"","attributes":{"icon":"","color":"#303030","jsDoc":"Keyboard emulation"}},"keyboard.__flush":{"kind":-3,"attributes":{"hidden":"1"},"parameters":[]},"keyboard.__type":{"kind":-3,"attributes":{"hidden":"1"},"parameters":[{"name":"text","type":"string"}]},"keyboard.__key":{"kind":-3,"attributes":{"hidden":"1"},"parameters":[{"name":"ckey"},{"name":"event","type":"KeyboardKeyEvent","isEnum":true}]},"keyboard.__mediaKey":{"kind":-3,"attributes":{"hidden":"1"},"parameters":[{"name":"key"},{"name":"event","type":"KeyboardKeyEvent","isEnum":true}]},"keyboard.__functionKey":{"kind":-3,"attributes":{"hidden":"1"},"parameters":[{"name":"key"},{"name":"event","type":"KeyboardKeyEvent","isEnum":true}]},"keyboard.__modifierKey":{"kind":-3,"attributes":{"hidden":"1"},"parameters":[{"name":"modifier"},{"name":"event","type":"KeyboardKeyEvent","isEnum":true}]},"KeyboardKeyEvent":{"kind":6,"retType":"KeyboardKeyEvent","extendsTypes":["KeyboardKeyEvent","Number"]},"KeyboardKeyEvent.Press":{"retType":"KeyboardKeyEvent.Press","attributes":{"block":"press","_def":{"parts":[{"kind":"label","text":"press","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardKeyEvent.Press","Number"],"pyQName":"KeyboardKeyEvent.PRESS"},"KeyboardKeyEvent.Up":{"retType":"KeyboardKeyEvent.Up","attributes":{"block":"up","_def":{"parts":[{"kind":"label","text":"up","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardKeyEvent.Up","Number"],"pyQName":"KeyboardKeyEvent.UP"},"KeyboardKeyEvent.Down":{"retType":"KeyboardKeyEvent.Down","attributes":{"block":"down","_def":{"parts":[{"kind":"label","text":"down","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardKeyEvent.Down","Number"],"pyQName":"KeyboardKeyEvent.DOWN"},"KeyboardMediaKey":{"kind":6,"retType":"KeyboardMediaKey","extendsTypes":["KeyboardMediaKey","Number"]},"KeyboardMediaKey.Mute":{"retType":"KeyboardMediaKey.Mute","attributes":{"block":"mute","_def":{"parts":[{"kind":"label","text":"mute","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.Mute","Number"],"pyQName":"KeyboardMediaKey.MUTE"},"KeyboardMediaKey.VolumeUp":{"retType":"KeyboardMediaKey.VolumeUp","attributes":{"block":"volume up","_def":{"parts":[{"kind":"label","text":"volume up","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.VolumeUp","Number"],"pyQName":"KeyboardMediaKey.VOLUME_UP"},"KeyboardMediaKey.VolumeDown":{"retType":"KeyboardMediaKey.VolumeDown","attributes":{"block":"volume down","_def":{"parts":[{"kind":"label","text":"volume down","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.VolumeDown","Number"],"pyQName":"KeyboardMediaKey.VOLUME_DOWN"},"KeyboardMediaKey.PlayPause":{"retType":"KeyboardMediaKey.PlayPause","attributes":{"block":"play pause","_def":{"parts":[{"kind":"label","text":"play pause","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.PlayPause","Number"],"pyQName":"KeyboardMediaKey.PLAY_PAUSE"},"KeyboardMediaKey.Stop":{"retType":"KeyboardMediaKey.Stop","attributes":{"block":"stop","_def":{"parts":[{"kind":"label","text":"stop","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.Stop","Number"],"pyQName":"KeyboardMediaKey.STOP"},"KeyboardMediaKey.PreviousTrack":{"retType":"KeyboardMediaKey.PreviousTrack","attributes":{"block":"previous track","_def":{"parts":[{"kind":"label","text":"previous track","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.PreviousTrack","Number"],"pyQName":"KeyboardMediaKey.PREVIOUS_TRACK"},"KeyboardMediaKey.NextTrack":{"retType":"KeyboardMediaKey.NextTrack","attributes":{"block":"next track","_def":{"parts":[{"kind":"label","text":"next track","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.NextTrack","Number"],"pyQName":"KeyboardMediaKey.NEXT_TRACK"},"KeyboardMediaKey.Mail":{"retType":"KeyboardMediaKey.Mail","attributes":{"block":"mail","_def":{"parts":[{"kind":"label","text":"mail","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.Mail","Number"],"pyQName":"KeyboardMediaKey.MAIL"},"KeyboardMediaKey.Calculator":{"retType":"KeyboardMediaKey.Calculator","attributes":{"block":"calculator","_def":{"parts":[{"kind":"label","text":"calculator","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.Calculator","Number"],"pyQName":"KeyboardMediaKey.CALCULATOR"},"KeyboardMediaKey.WebSearch":{"retType":"KeyboardMediaKey.WebSearch","attributes":{"block":"web search","_def":{"parts":[{"kind":"label","text":"web search","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.WebSearch","Number"],"pyQName":"KeyboardMediaKey.WEB_SEARCH"},"KeyboardMediaKey.WebHome":{"retType":"KeyboardMediaKey.WebHome","attributes":{"block":"web home","_def":{"parts":[{"kind":"label","text":"web home","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.WebHome","Number"],"pyQName":"KeyboardMediaKey.WEB_HOME"},"KeyboardMediaKey.WebFavourites":{"retType":"KeyboardMediaKey.WebFavourites","attributes":{"block":"web favourites","_def":{"parts":[{"kind":"label","text":"web favourites","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.WebFavourites","Number"],"pyQName":"KeyboardMediaKey.WEB_FAVOURITES"},"KeyboardMediaKey.WebRefresh":{"retType":"KeyboardMediaKey.WebRefresh","attributes":{"block":"web refresh","_def":{"parts":[{"kind":"label","text":"web refresh","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.WebRefresh","Number"],"pyQName":"KeyboardMediaKey.WEB_REFRESH"},"KeyboardMediaKey.WebStop":{"retType":"KeyboardMediaKey.WebStop","attributes":{"block":"web stop","_def":{"parts":[{"kind":"label","text":"web stop","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.WebStop","Number"],"pyQName":"KeyboardMediaKey.WEB_STOP"},"KeyboardMediaKey.WebForward":{"retType":"KeyboardMediaKey.WebForward","attributes":{"block":"web forward","_def":{"parts":[{"kind":"label","text":"web forward","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.WebForward","Number"],"pyQName":"KeyboardMediaKey.WEB_FORWARD"},"KeyboardMediaKey.WebBack":{"retType":"KeyboardMediaKey.WebBack","attributes":{"block":"web back","_def":{"parts":[{"kind":"label","text":"web back","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardMediaKey.WebBack","Number"],"pyQName":"KeyboardMediaKey.WEB_BACK"},"KeyboardFunctionKey":{"kind":6,"retType":"KeyboardFunctionKey","extendsTypes":["KeyboardFunctionKey","Number"]},"KeyboardFunctionKey.F1Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F1","_def":{"parts":[{"kind":"label","text":"F1","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F1Key","Number"],"pyQName":"KeyboardFunctionKey.F1_KEY"},"KeyboardFunctionKey.F2Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F2","_def":{"parts":[{"kind":"label","text":"F2","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F2Key","Number"],"pyQName":"KeyboardFunctionKey.F2_KEY"},"KeyboardFunctionKey.F3Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F3","_def":{"parts":[{"kind":"label","text":"F3","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F3Key","Number"],"pyQName":"KeyboardFunctionKey.F3_KEY"},"KeyboardFunctionKey.F4Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F4","_def":{"parts":[{"kind":"label","text":"F4","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F4Key","Number"],"pyQName":"KeyboardFunctionKey.F4_KEY"},"KeyboardFunctionKey.F5Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F5","_def":{"parts":[{"kind":"label","text":"F5","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F5Key","Number"],"pyQName":"KeyboardFunctionKey.F5_KEY"},"KeyboardFunctionKey.F6Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F6","_def":{"parts":[{"kind":"label","text":"F6","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F6Key","Number"],"pyQName":"KeyboardFunctionKey.F6_KEY"},"KeyboardFunctionKey.F7Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F7","_def":{"parts":[{"kind":"label","text":"F7","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F7Key","Number"],"pyQName":"KeyboardFunctionKey.F7_KEY"},"KeyboardFunctionKey.F8Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F8","_def":{"parts":[{"kind":"label","text":"F8","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F8Key","Number"],"pyQName":"KeyboardFunctionKey.F8_KEY"},"KeyboardFunctionKey.F9Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F9","_def":{"parts":[{"kind":"label","text":"F9","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F9Key","Number"],"pyQName":"KeyboardFunctionKey.F9_KEY"},"KeyboardFunctionKey.F10Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F0","_def":{"parts":[{"kind":"label","text":"F0","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F10Key","Number"],"pyQName":"KeyboardFunctionKey.F10_KEY"},"KeyboardFunctionKey.F11Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F11","_def":{"parts":[{"kind":"label","text":"F11","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F11Key","Number"],"pyQName":"KeyboardFunctionKey.F11_KEY"},"KeyboardFunctionKey.F12Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F12","_def":{"parts":[{"kind":"label","text":"F12","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F12Key","Number"],"pyQName":"KeyboardFunctionKey.F12_KEY"},"KeyboardFunctionKey.F13Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F13","_def":{"parts":[{"kind":"label","text":"F13","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F13Key","Number"],"pyQName":"KeyboardFunctionKey.F13_KEY"},"KeyboardFunctionKey.F14Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F14","_def":{"parts":[{"kind":"label","text":"F14","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F14Key","Number"],"pyQName":"KeyboardFunctionKey.F14_KEY"},"KeyboardFunctionKey.F15Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F15","_def":{"parts":[{"kind":"label","text":"F15","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F15Key","Number"],"pyQName":"KeyboardFunctionKey.F15_KEY"},"KeyboardFunctionKey.F16Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F16","_def":{"parts":[{"kind":"label","text":"F16","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F16Key","Number"],"pyQName":"KeyboardFunctionKey.F16_KEY"},"KeyboardFunctionKey.F17Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F17","_def":{"parts":[{"kind":"label","text":"F17","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F17Key","Number"],"pyQName":"KeyboardFunctionKey.F17_KEY"},"KeyboardFunctionKey.F18Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F18","_def":{"parts":[{"kind":"label","text":"F18","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F18Key","Number"],"pyQName":"KeyboardFunctionKey.F18_KEY"},"KeyboardFunctionKey.F19Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F19","_def":{"parts":[{"kind":"label","text":"F19","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F19Key","Number"],"pyQName":"KeyboardFunctionKey.F19_KEY"},"KeyboardFunctionKey.F20Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F20","_def":{"parts":[{"kind":"label","text":"F20","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F20Key","Number"],"pyQName":"KeyboardFunctionKey.F20_KEY"},"KeyboardFunctionKey.F21Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F21","_def":{"parts":[{"kind":"label","text":"F21","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F21Key","Number"],"pyQName":"KeyboardFunctionKey.F21_KEY"},"KeyboardFunctionKey.F22Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F22","_def":{"parts":[{"kind":"label","text":"F22","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F22Key","Number"],"pyQName":"KeyboardFunctionKey.F22_KEY"},"KeyboardFunctionKey.F23Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F23","_def":{"parts":[{"kind":"label","text":"F23","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F23Key","Number"],"pyQName":"KeyboardFunctionKey.F23_KEY"},"KeyboardFunctionKey.F24Key":{"retType":"KeyboardFunctionKey","attributes":{"block":"F24","_def":{"parts":[{"kind":"label","text":"F24","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.F24Key","Number"],"pyQName":"KeyboardFunctionKey.F24_KEY"},"KeyboardFunctionKey.Enter":{"retType":"KeyboardFunctionKey","attributes":{"block":"enter","_def":{"parts":[{"kind":"label","text":"enter","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Enter","Number"],"pyQName":"KeyboardFunctionKey.ENTER"},"KeyboardFunctionKey.Esc":{"retType":"KeyboardFunctionKey","attributes":{"block":"esc","_def":{"parts":[{"kind":"label","text":"esc","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Esc","Number"],"pyQName":"KeyboardFunctionKey.ESC"},"KeyboardFunctionKey.Backspace":{"retType":"KeyboardFunctionKey","attributes":{"block":"backspace","_def":{"parts":[{"kind":"label","text":"backspace","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Backspace","Number"],"pyQName":"KeyboardFunctionKey.BACKSPACE"},"KeyboardFunctionKey.Tab":{"retType":"KeyboardFunctionKey","attributes":{"block":"tab","_def":{"parts":[{"kind":"label","text":"tab","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Tab","Number"],"pyQName":"KeyboardFunctionKey.TAB"},"KeyboardFunctionKey.CapsLock":{"retType":"KeyboardFunctionKey","attributes":{"block":"caps lock","_def":{"parts":[{"kind":"label","text":"caps lock","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.CapsLock","Number"],"pyQName":"KeyboardFunctionKey.CAPS_LOCK"},"KeyboardFunctionKey.NumLock":{"retType":"KeyboardFunctionKey","attributes":{"block":"num lock","_def":{"parts":[{"kind":"label","text":"num lock","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.NumLock","Number"],"pyQName":"KeyboardFunctionKey.NUM_LOCK"},"KeyboardFunctionKey.KeypadSlash":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad /","_def":{"parts":[{"kind":"label","text":"keypad /","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.KeypadSlash","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD_SLASH"},"KeyboardFunctionKey.KeypadAsterisk":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad *","_def":{"parts":[{"kind":"label","text":"keypad *","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.KeypadAsterisk","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD_ASTERISK"},"KeyboardFunctionKey.KeypadMinus":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad -","_def":{"parts":[{"kind":"label","text":"keypad -","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.KeypadMinus","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD_MINUS"},"KeyboardFunctionKey.KeypadPlus":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad +","_def":{"parts":[{"kind":"label","text":"keypad +","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.KeypadPlus","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD_PLUS"},"KeyboardFunctionKey.KeypadEnter":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad enter","_def":{"parts":[{"kind":"label","text":"keypad enter","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.KeypadEnter","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD_ENTER"},"KeyboardFunctionKey.Keypad1":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad 1","_def":{"parts":[{"kind":"label","text":"keypad 1","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Keypad1","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD1"},"KeyboardFunctionKey.Keypad2":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad 2","_def":{"parts":[{"kind":"label","text":"keypad 2","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Keypad2","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD2"},"KeyboardFunctionKey.Keypad3":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad 3","_def":{"parts":[{"kind":"label","text":"keypad 3","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Keypad3","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD3"},"KeyboardFunctionKey.Keypad4":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad 4","_def":{"parts":[{"kind":"label","text":"keypad 4","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Keypad4","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD4"},"KeyboardFunctionKey.Keypad5":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad 5","_def":{"parts":[{"kind":"label","text":"keypad 5","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Keypad5","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD5"},"KeyboardFunctionKey.Keypad6":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad 6","_def":{"parts":[{"kind":"label","text":"keypad 6","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Keypad6","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD6"},"KeyboardFunctionKey.Keypad7":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad 7","_def":{"parts":[{"kind":"label","text":"keypad 7","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Keypad7","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD7"},"KeyboardFunctionKey.Keypad8":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad 8","_def":{"parts":[{"kind":"label","text":"keypad 8","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Keypad8","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD8"},"KeyboardFunctionKey.Keypad9":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad 9","_def":{"parts":[{"kind":"label","text":"keypad 9","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Keypad9","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD9"},"KeyboardFunctionKey.Keypad0":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad 0","_def":{"parts":[{"kind":"label","text":"keypad 0","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Keypad0","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD0"},"KeyboardFunctionKey.KeypadDot":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad .","_def":{"parts":[{"kind":"label","text":"keypad .","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.KeypadDot","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD_DOT"},"KeyboardFunctionKey.Compose":{"retType":"KeyboardFunctionKey","attributes":{"block":"compose","_def":{"parts":[{"kind":"label","text":"compose","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Compose","Number"],"pyQName":"KeyboardFunctionKey.COMPOSE"},"KeyboardFunctionKey.Power":{"retType":"KeyboardFunctionKey","attributes":{"block":"power","_def":{"parts":[{"kind":"label","text":"power","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Power","Number"],"pyQName":"KeyboardFunctionKey.POWER"},"KeyboardFunctionKey.KeypadEqual":{"retType":"KeyboardFunctionKey","attributes":{"block":"=","_def":{"parts":[{"kind":"label","text":"=","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.KeypadEqual","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD_EQUAL"},"KeyboardFunctionKey.Open":{"retType":"KeyboardFunctionKey","attributes":{"block":"open","_def":{"parts":[{"kind":"label","text":"open","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Open","Number"],"pyQName":"KeyboardFunctionKey.OPEN"},"KeyboardFunctionKey.Help":{"retType":"KeyboardFunctionKey","attributes":{"block":"help","_def":{"parts":[{"kind":"label","text":"help","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Help","Number"],"pyQName":"KeyboardFunctionKey.HELP"},"KeyboardFunctionKey.Props":{"retType":"KeyboardFunctionKey","attributes":{"block":"props","_def":{"parts":[{"kind":"label","text":"props","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Props","Number"],"pyQName":"KeyboardFunctionKey.PROPS"},"KeyboardFunctionKey.Front":{"retType":"KeyboardFunctionKey","attributes":{"block":"front","_def":{"parts":[{"kind":"label","text":"front","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Front","Number"],"pyQName":"KeyboardFunctionKey.FRONT"},"KeyboardFunctionKey.Stop":{"retType":"KeyboardFunctionKey","attributes":{"block":"stop","_def":{"parts":[{"kind":"label","text":"stop","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Stop","Number"],"pyQName":"KeyboardFunctionKey.STOP"},"KeyboardFunctionKey.Again":{"retType":"KeyboardFunctionKey","attributes":{"block":"again","_def":{"parts":[{"kind":"label","text":"again","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Again","Number"],"pyQName":"KeyboardFunctionKey.AGAIN"},"KeyboardFunctionKey.Undo":{"retType":"KeyboardFunctionKey","attributes":{"block":"undo","_def":{"parts":[{"kind":"label","text":"undo","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Undo","Number"],"pyQName":"KeyboardFunctionKey.UNDO"},"KeyboardFunctionKey.Cut":{"retType":"KeyboardFunctionKey","attributes":{"block":"cut","_def":{"parts":[{"kind":"label","text":"cut","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Cut","Number"],"pyQName":"KeyboardFunctionKey.CUT"},"KeyboardFunctionKey.Copy":{"retType":"KeyboardFunctionKey","attributes":{"block":"copy","_def":{"parts":[{"kind":"label","text":"copy","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Copy","Number"],"pyQName":"KeyboardFunctionKey.COPY"},"KeyboardFunctionKey.Paste":{"retType":"KeyboardFunctionKey","attributes":{"block":"paste","_def":{"parts":[{"kind":"label","text":"paste","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Paste","Number"],"pyQName":"KeyboardFunctionKey.PASTE"},"KeyboardFunctionKey.Find":{"retType":"KeyboardFunctionKey","attributes":{"block":"find","_def":{"parts":[{"kind":"label","text":"find","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Find","Number"],"pyQName":"KeyboardFunctionKey.FIND"},"KeyboardFunctionKey.Mute":{"retType":"KeyboardFunctionKey","attributes":{"block":"mute","_def":{"parts":[{"kind":"label","text":"mute","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Mute","Number"],"pyQName":"KeyboardFunctionKey.MUTE"},"KeyboardFunctionKey.VolumeUp":{"retType":"KeyboardFunctionKey","attributes":{"block":"volume up","_def":{"parts":[{"kind":"label","text":"volume up","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.VolumeUp","Number"],"pyQName":"KeyboardFunctionKey.VOLUME_UP"},"KeyboardFunctionKey.VolumeDown":{"retType":"KeyboardFunctionKey","attributes":{"block":"volume down","_def":{"parts":[{"kind":"label","text":"volume down","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.VolumeDown","Number"],"pyQName":"KeyboardFunctionKey.VOLUME_DOWN"},"KeyboardFunctionKey.KeypadComma":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad ,","_def":{"parts":[{"kind":"label","text":"keypad ,","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.KeypadComma","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD_COMMA"},"KeyboardFunctionKey.KeypadJumpComma":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad jump comma","_def":{"parts":[{"kind":"label","text":"keypad jump comma","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.KeypadJumpComma","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD_JUMP_COMMA"},"KeyboardFunctionKey.KeypadLeftParenthesis":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad (","_def":{"parts":[{"kind":"label","text":"keypad (","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.KeypadLeftParenthesis","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD_LEFT_PARENTHESIS"},"KeyboardFunctionKey.KeypadRightParenthesis":{"retType":"KeyboardFunctionKey","attributes":{"block":"keypad )","_def":{"parts":[{"kind":"label","text":"keypad )","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.KeypadRightParenthesis","Number"],"pyQName":"KeyboardFunctionKey.KEYPAD_RIGHT_PARENTHESIS"},"KeyboardFunctionKey.PrintScreen":{"retType":"KeyboardFunctionKey","attributes":{"block":"print screen","_def":{"parts":[{"kind":"label","text":"print screen","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.PrintScreen","Number"],"pyQName":"KeyboardFunctionKey.PRINT_SCREEN"},"KeyboardFunctionKey.ScrollLock":{"retType":"KeyboardFunctionKey","attributes":{"block":"scroll lock","_def":{"parts":[{"kind":"label","text":"scroll lock","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.ScrollLock","Number"],"pyQName":"KeyboardFunctionKey.SCROLL_LOCK"},"KeyboardFunctionKey.Pause":{"retType":"KeyboardFunctionKey","attributes":{"block":"pause","_def":{"parts":[{"kind":"label","text":"pause","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Pause","Number"],"pyQName":"KeyboardFunctionKey.PAUSE"},"KeyboardFunctionKey.Insert":{"retType":"KeyboardFunctionKey","attributes":{"block":"insert","_def":{"parts":[{"kind":"label","text":"insert","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Insert","Number"],"pyQName":"KeyboardFunctionKey.INSERT"},"KeyboardFunctionKey.Home":{"retType":"KeyboardFunctionKey","attributes":{"block":"home","_def":{"parts":[{"kind":"label","text":"home","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.Home","Number"],"pyQName":"KeyboardFunctionKey.HOME"},"KeyboardFunctionKey.PageUp":{"retType":"KeyboardFunctionKey","attributes":{"block":"page up","_def":{"parts":[{"kind":"label","text":"page up","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.PageUp","Number"],"pyQName":"KeyboardFunctionKey.PAGE_UP"},"KeyboardFunctionKey.DeleteForward":{"retType":"KeyboardFunctionKey","attributes":{"block":"delete","_def":{"parts":[{"kind":"label","text":"delete","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.DeleteForward","Number"],"pyQName":"KeyboardFunctionKey.DELETE_FORWARD"},"KeyboardFunctionKey.End":{"retType":"KeyboardFunctionKey","attributes":{"block":"end","_def":{"parts":[{"kind":"label","text":"end","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.End","Number"],"pyQName":"KeyboardFunctionKey.END"},"KeyboardFunctionKey.PageDown":{"retType":"KeyboardFunctionKey","attributes":{"block":"page down","_def":{"parts":[{"kind":"label","text":"page down","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.PageDown","Number"],"pyQName":"KeyboardFunctionKey.PAGE_DOWN"},"KeyboardFunctionKey.RightArrow":{"retType":"KeyboardFunctionKey","attributes":{"block":"right arrow","_def":{"parts":[{"kind":"label","text":"right arrow","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.RightArrow","Number"],"pyQName":"KeyboardFunctionKey.RIGHT_ARROW"},"KeyboardFunctionKey.LeftArrow":{"retType":"KeyboardFunctionKey","attributes":{"block":"left arrow","_def":{"parts":[{"kind":"label","text":"left arrow","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.LeftArrow","Number"],"pyQName":"KeyboardFunctionKey.LEFT_ARROW"},"KeyboardFunctionKey.DownArrow":{"retType":"KeyboardFunctionKey","attributes":{"block":"down arrow","_def":{"parts":[{"kind":"label","text":"down arrow","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.DownArrow","Number"],"pyQName":"KeyboardFunctionKey.DOWN_ARROW"},"KeyboardFunctionKey.UpArrow":{"retType":"KeyboardFunctionKey","attributes":{"block":"up arrow","_def":{"parts":[{"kind":"label","text":"up arrow","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardFunctionKey.UpArrow","Number"],"pyQName":"KeyboardFunctionKey.UP_ARROW"},"KeyboardModifierKey":{"kind":6,"retType":"KeyboardModifierKey","extendsTypes":["KeyboardModifierKey","Number"]},"KeyboardModifierKey.Control":{"retType":"KeyboardModifierKey","attributes":{"block":"Ctrl","_def":{"parts":[{"kind":"label","text":"Ctrl","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.Control","Number"],"pyQName":"KeyboardModifierKey.CONTROL"},"KeyboardModifierKey.Shift":{"retType":"KeyboardModifierKey","attributes":{"block":"Shift","_def":{"parts":[{"kind":"label","text":"Shift","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.Shift","Number"],"pyQName":"KeyboardModifierKey.SHIFT"},"KeyboardModifierKey.Alt":{"retType":"KeyboardModifierKey","attributes":{"block":"Alt","_def":{"parts":[{"kind":"label","text":"Alt","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.Alt","Number"],"pyQName":"KeyboardModifierKey.ALT"},"KeyboardModifierKey.Meta":{"retType":"KeyboardModifierKey","attributes":{"block":"Command","_def":{"parts":[{"kind":"label","text":"Command","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.Meta","Number"],"pyQName":"KeyboardModifierKey.META"},"KeyboardModifierKey.ControlShift":{"retType":"KeyboardModifierKey","attributes":{"block":"Ctrl+Shift","_def":{"parts":[{"kind":"label","text":"Ctrl+Shift","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.ControlShift","Number"],"pyQName":"KeyboardModifierKey.CONTROL_SHIFT"},"KeyboardModifierKey.ControlAlt":{"retType":"KeyboardModifierKey","attributes":{"block":"Ctrl+Alt","_def":{"parts":[{"kind":"label","text":"Ctrl+Alt","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.ControlAlt","Number"],"pyQName":"KeyboardModifierKey.CONTROL_ALT"},"KeyboardModifierKey.ShiftAlt":{"retType":"KeyboardModifierKey","attributes":{"block":"Shift+Alt","_def":{"parts":[{"kind":"label","text":"Shift+Alt","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.ShiftAlt","Number"],"pyQName":"KeyboardModifierKey.SHIFT_ALT"},"KeyboardModifierKey.ControlCommand":{"retType":"KeyboardModifierKey","attributes":{"block":"Ctrl+Cmd","_def":{"parts":[{"kind":"label","text":"Ctrl+Cmd","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.ControlCommand","Number"],"pyQName":"KeyboardModifierKey.CONTROL_COMMAND"},"KeyboardModifierKey.ShiftCommand":{"retType":"KeyboardModifierKey","attributes":{"block":"Ctrl+Cmd","_def":{"parts":[{"kind":"label","text":"Ctrl+Cmd","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.ShiftCommand","Number"],"pyQName":"KeyboardModifierKey.SHIFT_COMMAND"},"KeyboardModifierKey.AltCommand":{"retType":"KeyboardModifierKey","attributes":{"block":"Alt+Cmd","_def":{"parts":[{"kind":"label","text":"Alt+Cmd","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.AltCommand","Number"],"pyQName":"KeyboardModifierKey.ALT_COMMAND"},"KeyboardModifierKey.ControlShiftAlt":{"retType":"KeyboardModifierKey","attributes":{"block":"Ctrl+Shift+Alt","_def":{"parts":[{"kind":"label","text":"Ctrl+Shift+Alt","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.ControlShiftAlt","Number"],"pyQName":"KeyboardModifierKey.CONTROL_SHIFT_ALT"},"KeyboardModifierKey.ControlCommandShiftAlt":{"retType":"KeyboardModifierKey","attributes":{"block":"Ctrl+Cmd+Shift+Alt","_def":{"parts":[{"kind":"label","text":"Ctrl+Cmd+Shift+Alt","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.ControlCommandShiftAlt","Number"],"pyQName":"KeyboardModifierKey.CONTROL_COMMAND_SHIFT_ALT"},"KeyboardModifierKey.RightControl":{"retType":"KeyboardModifierKey","attributes":{"block":"Right Ctrl","_def":{"parts":[{"kind":"label","text":"Right Ctrl","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.RightControl","Number"],"pyQName":"KeyboardModifierKey.RIGHT_CONTROL"},"KeyboardModifierKey.RightShift":{"retType":"KeyboardModifierKey","attributes":{"block":"Right Shift","_def":{"parts":[{"kind":"label","text":"Right Shift","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.RightShift","Number"],"pyQName":"KeyboardModifierKey.RIGHT_SHIFT"},"KeyboardModifierKey.RightAlt":{"retType":"KeyboardModifierKey","attributes":{"block":"Right Alt","_def":{"parts":[{"kind":"label","text":"Right Alt","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.RightAlt","Number"],"pyQName":"KeyboardModifierKey.RIGHT_ALT"},"KeyboardModifierKey.RightMeta":{"retType":"KeyboardModifierKey","attributes":{"block":"Right Command","_def":{"parts":[{"kind":"label","text":"Right Command","style":[]}],"parameters":[]}},"extendsTypes":["KeyboardModifierKey.RightMeta","Number"],"pyQName":"KeyboardModifierKey.RIGHT_META"},"keyboard.type":{"kind":-3,"attributes":{"blockId":"keyboardType","block":"keyboard type $text||with $modifiers","blockGap":"8","weight":100,"paramShadowOptions":{"text":{"toString":"true"}},"help":"keyboard/type","jsDoc":"Send a sequence of keystrokes to the keyboard","_def":{"parts":[{"kind":"label","text":"keyboard type ","style":[]},{"kind":"param","name":"text","ref":true}],"parameters":[{"kind":"param","name":"text","ref":true}]},"_expandedDef":{"parts":[{"kind":"label","text":"with ","style":[]},{"kind":"param","name":"modifiers","ref":true}],"parameters":[{"kind":"param","name":"modifiers","ref":true}]}},"parameters":[{"name":"text","type":"string"},{"name":"modifiers","type":"KeyboardModifierKey","initializer":"undefined","isEnum":true}]},"keyboard.key":{"kind":-3,"attributes":{"blockId":"keyboardStandardKey","block":"keyboard key %key|%event","blockGap":"8","weight":99,"help":"keyboard/key","jsDoc":"Send a key command","_def":{"parts":[{"kind":"label","text":"keyboard key ","style":[]},{"kind":"param","name":"key","ref":false},{"kind":"break"},{"kind":"param","name":"event","ref":false}],"parameters":[{"kind":"param","name":"key","ref":false},{"kind":"param","name":"event","ref":false}]}},"parameters":[{"name":"key","type":"string"},{"name":"event","type":"KeyboardKeyEvent","isEnum":true}]},"keyboard.mediaKey":{"kind":-3,"attributes":{"blockId":"keyboardMediaKey","block":"keyboard media %key|%event","blockGap":"8","help":"keyboard/media-key","jsDoc":"Send a media key command","_def":{"parts":[{"kind":"label","text":"keyboard media ","style":[]},{"kind":"param","name":"key","ref":false},{"kind":"break"},{"kind":"param","name":"event","ref":false}],"parameters":[{"kind":"param","name":"key","ref":false},{"kind":"param","name":"event","ref":false}]}},"parameters":[{"name":"key","type":"KeyboardMediaKey","isEnum":true},{"name":"event","type":"KeyboardKeyEvent","isEnum":true}],"pyQName":"keyboard.media_key"},"keyboard.functionKey":{"kind":-3,"attributes":{"blockId":"keyboardFunctionKey","block":"keyboard function %key|%event","blockGap":"8","help":"keyboard/function-key","jsDoc":"Send a function key command","_def":{"parts":[{"kind":"label","text":"keyboard function ","style":[]},{"kind":"param","name":"key","ref":false},{"kind":"break"},{"kind":"param","name":"event","ref":false}],"parameters":[{"kind":"param","name":"key","ref":false},{"kind":"param","name":"event","ref":false}]}},"parameters":[{"name":"key","type":"KeyboardFunctionKey","isEnum":true},{"name":"event","type":"KeyboardKeyEvent","isEnum":true}],"pyQName":"keyboard.function_key"},"keyboard.modifierKey":{"kind":-3,"attributes":{"blockId":"keyboardModiferKey","block":"keyboard modifier %key|%event","blockGap":"8","help":"keyboard/modifier-key","jsDoc":"Send a modifier key command","_def":{"parts":[{"kind":"label","text":"keyboard modifier ","style":[]},{"kind":"param","name":"key","ref":false},{"kind":"break"},{"kind":"param","name":"event","ref":false}],"parameters":[{"kind":"param","name":"key","ref":false},{"kind":"param","name":"event","ref":false}]}},"parameters":[{"name":"key","type":"KeyboardModifierKey","isEnum":true},{"name":"event","type":"KeyboardKeyEvent","isEnum":true}],"pyQName":"keyboard.modifier_key"},"keyboard.clearAllKeys":{"kind":-3,"attributes":{"blockId":"keyboardClear","block":"keyboard clear all","blockGap":"8","help":"keyboard/clear-all-keys","weight":10,"jsDoc":"Send up commands for any remaning down keys","_def":{"parts":[{"kind":"label","text":"keyboard clear all","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"keyboard.clear_all_keys"}}},"sha":"ea786b95c35d24b04c15f05a01971530681aaaf83249e6fc64b0a5273cb4a125"},"libs/light":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"light":{"kind":5,"retType":"","attributes":{"weight":97,"color":"#0078d7","icon":"","groups":["other","Color","Photon","More"],"blockGap":"8","jsDoc":"Functions to operate colored LEDs."}},"Colors":{"kind":6,"retType":"Colors","attributes":{"jsDoc":"Well known colors"},"extendsTypes":["Colors","Number"]},"Colors.Red":{"retType":"Colors.Red","attributes":{"block":"red","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"red","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Red","Number"],"pyQName":"Colors.RED"},"Colors.Orange":{"retType":"Colors.Orange","attributes":{"block":"orange","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"orange","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Orange","Number"],"pyQName":"Colors.ORANGE"},"Colors.Yellow":{"retType":"Colors.Yellow","attributes":{"block":"yellow","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"yellow","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Yellow","Number"],"pyQName":"Colors.YELLOW"},"Colors.Green":{"retType":"Colors.Green","attributes":{"block":"green","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"green","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Green","Number"],"pyQName":"Colors.GREEN"},"Colors.Blue":{"retType":"Colors.Blue","attributes":{"block":"blue","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"blue","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Blue","Number"],"pyQName":"Colors.BLUE"},"Colors.Indigo":{"retType":"Colors.Indigo","attributes":{"block":"indigo","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"indigo","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Indigo","Number"],"pyQName":"Colors.INDIGO"},"Colors.Violet":{"retType":"Colors.Violet","attributes":{"block":"violet","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"violet","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Violet","Number"],"pyQName":"Colors.VIOLET"},"Colors.Purple":{"retType":"Colors.Purple","attributes":{"block":"purple","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"purple","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Purple","Number"],"pyQName":"Colors.PURPLE"},"Colors.Pink":{"retType":"Colors.Pink","attributes":{"block":"pink","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"pink","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Pink","Number"],"pyQName":"Colors.PINK"},"Colors.White":{"retType":"Colors.White","attributes":{"block":"white","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"white","style":[]}],"parameters":[]}},"extendsTypes":["Colors.White","Number"],"pyQName":"Colors.WHITE"},"Colors.Black":{"retType":"Colors.Black","attributes":{"block":"black","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"black","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Black","Number"],"pyQName":"Colors.BLACK"},"ColorHues":{"kind":6,"retType":"ColorHues","attributes":{"jsDoc":"Well known color hues"},"extendsTypes":["ColorHues","Number"]},"ColorHues.Red":{"retType":"ColorHues.Red","attributes":{"block":"red","_def":{"parts":[{"kind":"label","text":"red","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Red","Number"],"pyQName":"ColorHues.RED"},"ColorHues.Orange":{"retType":"ColorHues.Orange","attributes":{"block":"orange","_def":{"parts":[{"kind":"label","text":"orange","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Orange","Number"],"pyQName":"ColorHues.ORANGE"},"ColorHues.Yellow":{"retType":"ColorHues.Yellow","attributes":{"block":"yellow","_def":{"parts":[{"kind":"label","text":"yellow","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Yellow","Number"],"pyQName":"ColorHues.YELLOW"},"ColorHues.Green":{"retType":"ColorHues.Green","attributes":{"block":"green","_def":{"parts":[{"kind":"label","text":"green","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Green","Number"],"pyQName":"ColorHues.GREEN"},"ColorHues.Aqua":{"retType":"ColorHues.Aqua","attributes":{"block":"aqua","_def":{"parts":[{"kind":"label","text":"aqua","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Aqua","Number"],"pyQName":"ColorHues.AQUA"},"ColorHues.Blue":{"retType":"ColorHues.Blue","attributes":{"block":"blue","_def":{"parts":[{"kind":"label","text":"blue","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Blue","Number"],"pyQName":"ColorHues.BLUE"},"ColorHues.Purple":{"retType":"ColorHues.Purple","attributes":{"block":"purple","_def":{"parts":[{"kind":"label","text":"purple","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Purple","Number"],"pyQName":"ColorHues.PURPLE"},"ColorHues.Magenta":{"retType":"ColorHues.Magenta","attributes":{"block":"magenta","_def":{"parts":[{"kind":"label","text":"magenta","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Magenta","Number"],"pyQName":"ColorHues.MAGENTA"},"ColorHues.Pink":{"retType":"ColorHues.Pink","attributes":{"block":"pink","_def":{"parts":[{"kind":"label","text":"pink","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Pink","Number"],"pyQName":"ColorHues.PINK"},"color":{"kind":5,"retType":"","attributes":{"advanced":true,"jsDoc":"Color manipulation"}},"color.rgb":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"red":"255","green":"255","blue":"255"},"blockId":"colorsrgb","block":"red %red|green %green|blue %blue","paramMin":{"red":"0","green":"0","blue":"0"},"paramMax":{"red":"255","green":"255","blue":"255"},"help":"colors/rgb","weight":19,"blockGap":"8","blockHidden":true,"paramHelp":{"red":"value of the red channel between 0 and 255. eg: 255","green":"value of the green channel between 0 and 255. eg: 255","blue":"value of the blue channel between 0 and 255. eg: 255"},"jsDoc":"Converts red, green, blue channels into a RGB color","_def":{"parts":[{"kind":"label","text":"red ","style":[]},{"kind":"param","name":"red","ref":false},{"kind":"break"},{"kind":"label","text":"green ","style":[]},{"kind":"param","name":"green","ref":false},{"kind":"break"},{"kind":"label","text":"blue ","style":[]},{"kind":"param","name":"blue","ref":false}],"parameters":[{"kind":"param","name":"red","ref":false},{"kind":"param","name":"green","ref":false},{"kind":"param","name":"blue","ref":false}]}},"parameters":[{"name":"red","description":"value of the red channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"green","description":"value of the green channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"blue","description":"value of the blue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.argb":{"kind":-3,"retType":"number","parameters":[{"name":"alpha"},{"name":"red"},{"name":"green"},{"name":"blue"}]},"color.wellKnown":{"kind":-3,"retType":"number","attributes":{"blockId":"colorscolors","block":"%color","help":"colors/well-known","shim":"TD_ID","weight":20,"blockGap":"8","blockHidden":true,"jsDoc":"Get the RGB value of a known color","_def":{"parts":[{"kind":"param","name":"color","ref":false}],"parameters":[{"kind":"param","name":"color","ref":false}]}},"parameters":[{"name":"color","type":"Colors","isEnum":true}],"pyQName":"color.well_known"},"color.hsv":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"hue":"255","sat":"255","val":"255"},"blockId":"colorshsv","block":"hue %hue|sat %sat|val %val","paramMin":{"hue":"0","sat":"0","val":"0"},"paramMax":{"hue":"255","sat":"255","val":"255"},"help":"colors/hsv","weight":17,"blockHidden":true,"paramHelp":{"hue":"value of the hue channel between 0 and 255. eg: 255","sat":"value of the saturation channel between 0 and 255. eg: 255","val":"value of the value channel between 0 and 255. eg: 255"},"jsDoc":"Convert an HSV (hue, saturation, value) color to RGB","_def":{"parts":[{"kind":"label","text":"hue ","style":[]},{"kind":"param","name":"hue","ref":false},{"kind":"break"},{"kind":"label","text":"sat ","style":[]},{"kind":"param","name":"sat","ref":false},{"kind":"break"},{"kind":"label","text":"val ","style":[]},{"kind":"param","name":"val","ref":false}],"parameters":[{"kind":"param","name":"hue","ref":false},{"kind":"param","name":"sat","ref":false},{"kind":"param","name":"val","ref":false}]}},"parameters":[{"name":"hue","description":"value of the hue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"sat","description":"value of the saturation channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"val","description":"value of the value channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.fade":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"brightness":"128"},"blockId":"colorsfade","block":"fade %color=neopixel_colors|by %brightness","paramMin":{"brightness":"0"},"paramMax":{"brightness":"255"},"help":"light/fade","group":"Color","weight":18,"blockGap":"8","blockHidden":true,"paramHelp":{"color":"color to fade","brightness":"the amount of brightness to apply to the color, eg: 128"},"jsDoc":"Fade the color by the brightness","_def":{"parts":[{"kind":"label","text":"fade ","style":[]},{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"break"},{"kind":"label","text":"by ","style":[]},{"kind":"param","name":"brightness","ref":false}],"parameters":[{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"param","name":"brightness","ref":false}]}},"parameters":[{"name":"color","description":"color to fade"},{"name":"brightness","description":"the amount of brightness to apply to the color, eg: 128","default":"128","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.blend":{"kind":-3,"retType":"number","parameters":[{"name":"color"},{"name":"alpha"},{"name":"otherColor"}]},"color.gradient":{"kind":-3,"retType":"color.ColorBuffer","parameters":[{"name":"startColor"},{"name":"endColor"},{"name":"steps"}]},"color.unpackR":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_r"},"color.unpackG":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_g"},"color.unpackB":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_b"},"color.parseColor":{"kind":-3,"retType":"number","parameters":[{"name":"color","type":"string"}],"pyQName":"color.parse_color"},"color.ColorBufferLayout":{"kind":6,"retType":"color.ColorBufferLayout","extendsTypes":["color.ColorBufferLayout","Number"]},"color.ColorBufferLayout.RGB":{"retType":"color.ColorBufferLayout.RGB","attributes":{"jsDoc":"24bit RGB color"},"extendsTypes":["color.ColorBufferLayout.RGB","Number"]},"color.ColorBufferLayout.ARGB":{"retType":"color.ColorBufferLayout.ARGB","attributes":{"jsDoc":"32bit RGB color with alpha"},"extendsTypes":["color.ColorBufferLayout.ARGB","Number"]},"color.ColorBuffer":{"kind":8,"retType":"color.ColorBuffer","attributes":{"jsDoc":"A buffer of colors"},"extendsTypes":[]},"color.ColorBuffer.layout":{"kind":2,"retType":"color.ColorBufferLayout","isInstance":true},"color.ColorBuffer.buf":{"kind":2,"retType":"Buffer","isInstance":true},"color.ColorBuffer.__constructor":{"kind":-3,"parameters":[{"name":"length"},{"name":"layout","type":"color.ColorBufferLayout","initializer":"undefined","isEnum":true}],"isInstance":true},"color.ColorBuffer.fromBuffer":{"kind":-1,"retType":"color.ColorBuffer","parameters":[{"name":"buffer","type":"Buffer"},{"name":"layout","type":"color.ColorBufferLayout","isEnum":true}],"pyQName":"color.ColorBuffer.from_buffer"},"color.ColorBuffer.stride":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"color.ColorBuffer.length":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"color.ColorBuffer.color":{"kind":-1,"retType":"number","parameters":[{"name":"index"}],"isInstance":true},"color.ColorBuffer.setColor":{"kind":-1,"parameters":[{"name":"index"},{"name":"color"}],"isInstance":true,"pyQName":"color.ColorBuffer.set_color"},"color.ColorBuffer.slice":{"kind":-1,"retType":"color.ColorBuffer","parameters":[{"name":"start","initializer":"undefined"},{"name":"length","initializer":"undefined"}],"isInstance":true},"color.ColorBuffer.write":{"kind":-1,"attributes":{"paramHelp":{"dstOffset":"@param src"},"jsDoc":"Writes the content of the src color buffer starting at the start dstOffset in the current buffer"},"parameters":[{"name":"dstOffset","description":"@param src"},{"name":"src","type":"color.ColorBuffer"}],"isInstance":true},"color.createBuffer":{"kind":-3,"retType":"color.ColorBuffer","attributes":{"jsDoc":"Converts an array of colors into a color buffer"},"parameters":[{"name":"colors","type":"number[]"},{"name":"layout","type":"color.ColorBufferLayout","initializer":"undefined","isEnum":true}],"pyQName":"color.create_buffer"},"NeoPixelMode":{"kind":6,"retType":"NeoPixelMode","attributes":{"jsDoc":"Different modes for RGB or RGB+W NeoPixel strips"},"extendsTypes":["NeoPixelMode","Number"]},"NeoPixelMode.RGB":{"retType":"NeoPixelMode.RGB","attributes":{"block":"RGB (GRB format)","_def":{"parts":[{"kind":"label","text":"RGB (GRB format)","style":[]}],"parameters":[]}},"extendsTypes":["NeoPixelMode.RGB","Number"]},"NeoPixelMode.RGBW":{"retType":"NeoPixelMode.RGBW","attributes":{"block":"RGB+W","_def":{"parts":[{"kind":"label","text":"RGB+W","style":[]}],"parameters":[]}},"extendsTypes":["NeoPixelMode.RGBW","Number"]},"NeoPixelMode.RGB_RGB":{"retType":"NeoPixelMode.RGB_RGB","attributes":{"block":"RGB (RGB format)","_def":{"parts":[{"kind":"label","text":"RGB (RGB format)","style":[]}],"parameters":[]}},"extendsTypes":["NeoPixelMode.RGB_RGB","Number"]},"NeoPixelMode.APA102":{"retType":"NeoPixelMode.APA102","attributes":{"block":"APA102","_def":{"parts":[{"kind":"label","text":"APA102","style":[]}],"parameters":[]}},"extendsTypes":["NeoPixelMode.APA102","Number"]},"LightMove":{"kind":6,"retType":"LightMove","extendsTypes":["LightMove","Number"]},"LightMove.Rotate":{"retType":"LightMove.Rotate","attributes":{"block":"rotate","_def":{"parts":[{"kind":"label","text":"rotate","style":[]}],"parameters":[]}},"extendsTypes":["LightMove.Rotate","Number"],"pyQName":"LightMove.ROTATE"},"LightMove.Shift":{"retType":"LightMove.Shift","attributes":{"block":"shift","_def":{"parts":[{"kind":"label","text":"shift","style":[]}],"parameters":[]}},"extendsTypes":["LightMove.Shift","Number"],"pyQName":"LightMove.SHIFT"},"PhotonMode":{"kind":6,"retType":"PhotonMode","attributes":{"jsDoc":"A determines the mode of the photon"},"extendsTypes":["PhotonMode","Number"]},"PhotonMode.PenUp":{"retType":"PhotonMode.PenUp","attributes":{"block":"pen up","_def":{"parts":[{"kind":"label","text":"pen up","style":[]}],"parameters":[]}},"extendsTypes":["PhotonMode.PenUp","Number"],"pyQName":"PhotonMode.PEN_UP"},"PhotonMode.PenDown":{"retType":"PhotonMode.PenDown","attributes":{"block":"pen down","_def":{"parts":[{"kind":"label","text":"pen down","style":[]}],"parameters":[]}},"extendsTypes":["PhotonMode.PenDown","Number"],"pyQName":"PhotonMode.PEN_DOWN"},"PhotonMode.Eraser":{"retType":"PhotonMode.Eraser","attributes":{"block":"eraser","_def":{"parts":[{"kind":"label","text":"eraser","style":[]}],"parameters":[]}},"extendsTypes":["PhotonMode.Eraser","Number"],"pyQName":"PhotonMode.ERASER"},"PhotonMode.Off":{"retType":"PhotonMode.Off","attributes":{"block":"off","_def":{"parts":[{"kind":"label","text":"off","style":[]}],"parameters":[]}},"extendsTypes":["PhotonMode.Off","Number"],"pyQName":"PhotonMode.OFF"},"LightAnimation":{"kind":6,"retType":"LightAnimation","extendsTypes":["LightAnimation","Number"]},"LightAnimation.Rainbow":{"retType":"LightAnimation.Rainbow","attributes":{"blockImage":"1","block":"rainbow","_def":{"parts":[{"kind":"label","text":"rainbow","style":[]}],"parameters":[]}},"extendsTypes":["LightAnimation.Rainbow","Number"],"pyQName":"LightAnimation.RAINBOW"},"LightAnimation.RunningLights":{"retType":"LightAnimation.RunningLights","attributes":{"blockImage":"1","block":"running lights","_def":{"parts":[{"kind":"label","text":"running lights","style":[]}],"parameters":[]}},"extendsTypes":["LightAnimation.RunningLights","Number"],"pyQName":"LightAnimation.RUNNING_LIGHTS"},"LightAnimation.Comet":{"retType":"LightAnimation.Comet","attributes":{"blockImage":"1","block":"comet","_def":{"parts":[{"kind":"label","text":"comet","style":[]}],"parameters":[]}},"extendsTypes":["LightAnimation.Comet","Number"],"pyQName":"LightAnimation.COMET"},"LightAnimation.Sparkle":{"retType":"LightAnimation.Sparkle","attributes":{"blockImage":"1","block":"sparkle","_def":{"parts":[{"kind":"label","text":"sparkle","style":[]}],"parameters":[]}},"extendsTypes":["LightAnimation.Sparkle","Number"],"pyQName":"LightAnimation.SPARKLE"},"LightAnimation.TheaterChase":{"retType":"LightAnimation.TheaterChase","attributes":{"blockImage":"1","block":"theater chase","_def":{"parts":[{"kind":"label","text":"theater chase","style":[]}],"parameters":[]}},"extendsTypes":["LightAnimation.TheaterChase","Number"],"pyQName":"LightAnimation.THEATER_CHASE"},"LightAnimation.ColorWipe":{"retType":"LightAnimation.ColorWipe","attributes":{"blockImage":"1","block":"color wipe","_def":{"parts":[{"kind":"label","text":"color wipe","style":[]}],"parameters":[]}},"extendsTypes":["LightAnimation.ColorWipe","Number"],"pyQName":"LightAnimation.COLOR_WIPE"},"light.NeoPixelStrip":{"kind":8,"retType":"light.NeoPixelStrip","attributes":{"jsDoc":"A NeoPixel strip"},"extendsTypes":[]},"light.NeoPixelStrip._parent":{"kind":2,"retType":"light.NeoPixelStrip","isInstance":true},"light.NeoPixelStrip._dataPin":{"kind":2,"retType":"DigitalInOutPin","isInstance":true,"pyQName":"light.NeoPixelStrip._data_pin"},"light.NeoPixelStrip._clkPin":{"kind":2,"retType":"DigitalInOutPin","isInstance":true,"pyQName":"light.NeoPixelStrip._clk_pin"},"light.NeoPixelStrip._buf":{"kind":2,"retType":"Buffer","isInstance":true},"light.NeoPixelStrip._brightnessBuf":{"kind":2,"retType":"Buffer","isInstance":true,"pyQName":"light.NeoPixelStrip._brightness_buf"},"light.NeoPixelStrip._sendBuf":{"kind":2,"retType":"Buffer","isInstance":true,"pyQName":"light.NeoPixelStrip._send_buf"},"light.NeoPixelStrip._brightness":{"kind":2,"retType":"number","isInstance":true},"light.NeoPixelStrip._start":{"kind":2,"retType":"number","isInstance":true},"light.NeoPixelStrip._length":{"kind":2,"retType":"number","isInstance":true},"light.NeoPixelStrip._mode":{"kind":2,"retType":"NeoPixelMode","isInstance":true},"light.NeoPixelStrip._buffered":{"kind":2,"retType":"boolean","isInstance":true},"light.NeoPixelStrip._animationQueue":{"kind":2,"retType":"control.AnimationQueue","isInstance":true,"pyQName":"light.NeoPixelStrip._animation_queue"},"light.NeoPixelStrip._barGraphHigh":{"kind":2,"retType":"number","isInstance":true,"pyQName":"light.NeoPixelStrip._bar_graph_high"},"light.NeoPixelStrip._barGraphHighLast":{"kind":2,"retType":"number","isInstance":true,"pyQName":"light.NeoPixelStrip._bar_graph_high_last"},"light.NeoPixelStrip._photonMode":{"kind":2,"retType":"number","isInstance":true,"pyQName":"light.NeoPixelStrip._photon_mode"},"light.NeoPixelStrip._photonPos":{"kind":2,"retType":"number","isInstance":true,"pyQName":"light.NeoPixelStrip._photon_pos"},"light.NeoPixelStrip._photonDir":{"kind":2,"retType":"number","isInstance":true,"pyQName":"light.NeoPixelStrip._photon_dir"},"light.NeoPixelStrip._photonPenColor":{"kind":2,"retType":"number","isInstance":true,"pyQName":"light.NeoPixelStrip._photon_pen_color"},"light.NeoPixelStrip._lastAnimation":{"kind":2,"retType":"light.NeoPixelAnimation","isInstance":true,"pyQName":"light.NeoPixelStrip._last_animation"},"light.NeoPixelStrip._lastAnimationRenderer":{"kind":2,"retType":"() => boolean","isInstance":true,"pyQName":"light.NeoPixelStrip._last_animation_renderer"},"light.NeoPixelStrip._transitionPlayer":{"kind":2,"retType":"light.BrightnessTransitionPlayer","isInstance":true,"pyQName":"light.NeoPixelStrip._transition_player"},"light.NeoPixelStrip.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"light.NeoPixelStrip.buf":{"kind":-2,"retType":"Buffer","attributes":{"jsDoc":"Gets the underlying color buffer for the entire strip"},"isInstance":true,"isReadOnly":true},"light.NeoPixelStrip.brightnessBuf":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"light.NeoPixelStrip.brightness_buf"},"light.NeoPixelStrip.mode":{"kind":-2,"retType":"NeoPixelMode","attributes":{"jsDoc":"Gets the LED data layout mode"},"isInstance":true,"isReadOnly":true},"light.NeoPixelStrip.setAll":{"kind":-1,"attributes":{"blockId":"light_set_strip_color","block":"set %strip all pixels to %rgb=colorNumberPicker","help":"light/neopixelstrip/set-all","weight":80,"blockGap":"8","advanced":true,"paramHelp":{"rgb":"RGB color of the LED"},"jsDoc":"Set all of the pixels on the strip to one RGB color.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" all pixels to ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"rgb","description":"RGB color of the LED"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_all"},"light.NeoPixelStrip.setGradient":{"kind":-1,"attributes":{"blockId":"lightsetgradient","block":"set %strip gradient from %startColor=colorNumberPicker to %endColor=colorNumberPicker","weight":79,"blockGap":"8","group":"More","advanced":true,"paramHelp":{"startColor":"the start color","endColor":"the end color"},"jsDoc":"Sets a gradient between two colors","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" gradient from ","style":[]},{"kind":"param","name":"startColor","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"endColor","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"startColor","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"param","name":"endColor","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"startColor","description":"the start color"},{"name":"endColor","description":"the end color"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_gradient"},"light.NeoPixelStrip.graph":{"kind":-1,"attributes":{"blockId":"light_show_bar_graph","block":"%strip|graph %value||up to %high","icon":"","help":"light/neopixelstrip/graph","weight":70,"blockGap":"8","advanced":true,"paramHelp":{"value":"current value to plot","high":"maximum value, 0 to autoscale"},"jsDoc":"Display a vertical bar graph based on the `value` and `high` value.\nIf `high` is 0, the chart gets adjusted automatically.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"graph ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"value","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":"up to ","style":[]},{"kind":"param","name":"high","ref":false}],"parameters":[{"kind":"param","name":"high","ref":false}]}},"parameters":[{"name":"value","description":"current value to plot"},{"name":"high","description":"maximum value, 0 to autoscale","initializer":"undefined"}],"isInstance":true},"light.NeoPixelStrip.setPixelColor":{"kind":-1,"attributes":{"blockId":"light_set_pixel_color","block":"set %strip pixel color at %pixeloffset|to %rgb=colorNumberPicker","help":"light/neopixelstrip/set-pixel-color","weight":79,"blockGap":"8","group":"More","advanced":true,"paramHelp":{"pixeloffset":"position of the NeoPixel in the strip","color":"RGB color of the LED"},"jsDoc":"Set the pixel to a given color.\nYou need to call ``show`` to make the changes visible.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" pixel color at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the NeoPixel in the strip"},{"name":"c"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_pixel_color"},"light.NeoPixelStrip.pixelColor":{"kind":-1,"retType":"number","attributes":{"blockId":"light_get_pixel_color","block":"%strip|pixel color at %pixeloffset","help":"light/neopixelstrip/pixel-color","weight":9,"blockGap":"8","group":"More","advanced":true,"paramHelp":{"pixeloffset":"position of the NeoPixel in the strip"},"jsDoc":"Gets the pixel color.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"pixel color at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"pixeloffset","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the NeoPixel in the strip"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.pixel_color"},"light.NeoPixelStrip.setPixelWhiteLED":{"kind":-1,"attributes":{"blockId":"light_set_pixel_white_led","block":"set %strip pixel white LED at %pixeloffset|to %white","help":"light/neopixelstrip/set-pixel-white-led","weight":5,"blockGap":"8","group":"More","advanced":true,"paramHelp":{"pixeloffset":"position of the LED in the strip","white":"brightness of the white LED"},"jsDoc":"Set the white brightness of a pixel in a NeoPixel strip of RGB+W LEDs.\nThis only works for RGB+W NeoPixels.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" pixel white LED at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"white","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"param","name":"white","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the LED in the strip"},{"name":"white","description":"brightness of the white LED"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_pixel_white_led"},"light.NeoPixelStrip.show":{"kind":-1,"attributes":{"blockId":"light_show","block":"%strip|show","help":"light/neopixelstrip/show","weight":86,"blockGap":"8","group":"More","advanced":true,"jsDoc":"Make the strip show all the new changes for the pixels.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"show","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false}]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.clear":{"kind":-1,"attributes":{"blockId":"light_clear","block":"%strip|clear","help":"light/neopixelstrip/clear","weight":85,"blockGap":"8","group":"More","advanced":true,"jsDoc":"Turn off all pixel LEDs.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"clear","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false}]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.length":{"kind":-1,"retType":"number","attributes":{"blockId":"light_length","block":"%strip|length","help":"light/neopixelstrip/length","weight":8,"blockGap":"8","group":"More","advanced":true,"jsDoc":"Get the number of pixels on the strip","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"length","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false}]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.setBrightness":{"kind":-1,"attributes":{"paramDefl":{"brightness":"20"},"blockId":"light_set_brightness","block":"set %strip brightness %brightness","paramMin":{"brightness":"0"},"paramMax":{"brightness":"255"},"help":"light/neopixelstrip/set-brightness","weight":2,"blockGap":"8","advanced":true,"paramHelp":{"brightness":"a measure of LED brightness in 0-255. eg: 20"},"jsDoc":"Set the brightness of the strip. This flag only applies to future operation.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" brightness ","style":[]},{"kind":"param","name":"brightness","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"brightness","ref":false}]}},"parameters":[{"name":"brightness","description":"a measure of LED brightness in 0-255. eg: 20","default":"20","options":{"min":{"value":"0"},"max":{"value":"255"}}}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_brightness"},"light.NeoPixelStrip.setPixelBrightness":{"kind":-1,"attributes":{"paramHelp":{"index":"@param brightness "},"jsDoc":"Sets an individual pixel brightness"},"parameters":[{"name":"index","description":"@param brightness "},{"name":"brightness"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_pixel_brightness"},"light.NeoPixelStrip.brightness":{"kind":-1,"retType":"number","attributes":{"blockId":"light_get_brightness","block":"%strip|brightness","help":"light/neopixelstrip/brightness","parts":"neopixel","weight":7,"blockGap":"8","group":"More","advanced":true,"jsDoc":"Get the brightness of the pixel strip.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"brightness","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false}]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.range":{"kind":-1,"retType":"light.NeoPixelStrip","attributes":{"paramDefl":{"length":"4"},"blockId":"light_range","block":"%strip|range from %start|with %length|pixels","help":"light/neopixelstrip/range","weight":99,"blockGap":"30","blockSetVariable":"strip","advanced":true,"paramHelp":{"start":"offset in the NeoPixel strip to start the range","length":"number of pixels in the range, eg: 4"},"jsDoc":"Create a range of pixels.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"range from ","style":[]},{"kind":"param","name":"start","ref":false},{"kind":"break"},{"kind":"label","text":"with ","style":[]},{"kind":"param","name":"length","ref":false},{"kind":"break"},{"kind":"label","text":"pixels","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"start","ref":false},{"kind":"param","name":"length","ref":false}]}},"parameters":[{"name":"start","description":"offset in the NeoPixel strip to start the range"},{"name":"length","description":"number of pixels in the range, eg: 4","default":"4"}],"isInstance":true},"light.NeoPixelStrip.move":{"kind":-1,"attributes":{"paramDefl":{"offset":"1"},"blockId":"light_move_pixels","block":"%strip|%kind=MoveKind|by %offset","help":"light/neopixelstrip/move","weight":87,"blockGap":"8","group":"More","advanced":true,"paramHelp":{"offset":"number of pixels to shift forward, eg: 1"},"jsDoc":"Shift LEDs forward and clear with zeros.\nYou need to call ``show`` to make the changes visible.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"param","name":"kind","shadowBlockId":"MoveKind","ref":false},{"kind":"break"},{"kind":"label","text":"by ","style":[]},{"kind":"param","name":"offset","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"kind","shadowBlockId":"MoveKind","ref":false},{"kind":"param","name":"offset","ref":false}]}},"parameters":[{"name":"kind","type":"LightMove","isEnum":true},{"name":"offset","description":"number of pixels to shift forward, eg: 1","initializer":"1","default":"1"}],"isInstance":true},"light.NeoPixelStrip.initPhoton":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"light.NeoPixelStrip.init_photon"},"light.NeoPixelStrip.photonForward":{"kind":-1,"attributes":{"paramDefl":{"steps":"1"},"blockId":"light_photon_fd","block":"%strip|photon forward by %steps","help":"light/neopixelstrip/photon-forward","weight":41,"blockGap":"8","group":"Photon","advanced":true,"paramHelp":{"steps":"number of steps (lights) to move, eg: 1"},"jsDoc":"Move a photon effect along the pixel strip by a number of steps.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"photon forward by ","style":[]},{"kind":"param","name":"steps","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"steps","ref":false}]}},"parameters":[{"name":"steps","description":"number of steps (lights) to move, eg: 1","default":"1"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.photon_forward"},"light.NeoPixelStrip.photonFlip":{"kind":-1,"attributes":{"blockId":"light_photon_flip","block":"%strip|photon flip","help":"light/neopixelstrip/photon-flip","weight":40,"blockGap":"8","group":"Photon","advanced":true,"jsDoc":"Switch the direction of the photon pulse.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"photon flip","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"light.NeoPixelStrip.photon_flip"},"light.NeoPixelStrip.setPhotonPosition":{"kind":-1,"attributes":{"blockId":"light_photon_set_position","block":"%strip|photon set position %index","help":"light/neopixelstrip/set-photon-position","weight":39,"blockGap":"8","group":"Photon","advanced":true,"paramHelp":{"index":"index of the light, if out of bound, the index is wrapped"},"jsDoc":"Sets the photon position to a given light index","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"photon set position ","style":[]},{"kind":"param","name":"index","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"index","ref":false}]}},"parameters":[{"name":"index","description":"index of the light, if out of bound, the index is wrapped"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_photon_position"},"light.NeoPixelStrip.setPhotonPenColor":{"kind":-1,"attributes":{"blockId":"light_photon_set_pen_color","block":"%strip=variables_get|photon set pen color %color=colorNumberPicker","help":"light/neopixelstrip/set-photon-pen-color","weight":38,"blockGap":"8","group":"Photon","advanced":true,"paramHelp":{"color":"the color of the photon"},"jsDoc":"Set the photon color.","_def":{"parts":[{"kind":"param","name":"strip","shadowBlockId":"variables_get","ref":false},{"kind":"break"},{"kind":"label","text":"photon set pen color ","style":[]},{"kind":"param","name":"color","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"strip","shadowBlockId":"variables_get","ref":false},{"kind":"param","name":"color","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"color","description":"the color of the photon"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_photon_pen_color"},"light.NeoPixelStrip.setPhotonPenHue":{"kind":-1,"attributes":{"blockId":"light_photon_set_pen_hue","block":"%strip=variables_get|photon set pen hue %hue=colorWheelHsvPicker","help":"light/neopixelstrip/set-photon-pen-hue","weight":39,"blockGap":"8","group":"Photon","advanced":true,"paramHelp":{"hue":"the hue of the photon color"},"jsDoc":"Sets the photon hue.","_def":{"parts":[{"kind":"param","name":"strip","shadowBlockId":"variables_get","ref":false},{"kind":"break"},{"kind":"label","text":"photon set pen hue ","style":[]},{"kind":"param","name":"hue","shadowBlockId":"colorWheelHsvPicker","ref":false}],"parameters":[{"kind":"param","name":"strip","shadowBlockId":"variables_get","ref":false},{"kind":"param","name":"hue","shadowBlockId":"colorWheelHsvPicker","ref":false}]}},"parameters":[{"name":"hue","description":"the hue of the photon color"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_photon_pen_hue"},"light.NeoPixelStrip.setPhotonColor":{"kind":-1,"attributes":{"deprecated":"1","blockHidden":true,"group":"Photon","advanced":true},"parameters":[{"name":"hue"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_photon_color"},"light.NeoPixelStrip.setPhotonMode":{"kind":-1,"attributes":{"blockId":"light_photon_set_photon","block":"%strip|photon %mode","help":"light/neopixelstrip/set-photon-mode","weight":38,"group":"Photon","advanced":true,"paramHelp":{"mode":"the desired mode"},"jsDoc":"Set the photon mode to pen up, pen down, or eraser.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"photon ","style":[]},{"kind":"param","name":"mode","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"mode","ref":false}]}},"parameters":[{"name":"mode","description":"the desired mode","type":"PhotonMode","isEnum":true}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_photon_mode"},"light.NeoPixelStrip.startBrightnessTransition":{"kind":-1,"attributes":{"paramHelp":{"transition":"@param duration "},"jsDoc":"Starts a brightness transition on the strip (and cancels any other running transition)"},"parameters":[{"name":"startBrightness"},{"name":"endBrightness"},{"name":"duration"},{"name":"repeat","initializer":"undefined"},{"name":"yoyo","type":"boolean","initializer":"undefined"},{"name":"transition","description":"@param duration ","type":"light.BrightnessTransition","initializer":"undefined"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.start_brightness_transition"},"light.NeoPixelStrip.stopBrightnessTransition":{"kind":-1,"attributes":{"jsDoc":"Stops any running brightness transition"},"parameters":[],"isInstance":true,"pyQName":"light.NeoPixelStrip.stop_brightness_transition"},"light.NeoPixelStrip.showAnimation":{"kind":-1,"attributes":{"paramDefl":{"duration":"500"},"blockId":"light_show_animation","block":"%strip|show animation %animation=light_animation_picker|for %duration=timePicker|ms","help":"light/neopixelstrip/show-animation","weight":90,"blockGap":"8","advanced":true,"paramHelp":{"animation":"the animation to run","duration":"the duration to run in milliseconds, eg: 500"},"jsDoc":"Show an animation or queue an animation in the animation queue","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"show animation ","style":[]},{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"break"},{"kind":"label","text":"for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"animation","description":"the animation to run","type":"light.NeoPixelAnimation"},{"name":"duration","description":"the duration to run in milliseconds, eg: 500","default":"500"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.show_animation"},"light.NeoPixelStrip.showAnimationFrame":{"kind":-1,"attributes":{"blockId":"light_show_animation_frame","block":"%strip|show frame of %animation=light_animation_picker|animation","help":"light/neopixelstrip/show-animation-frame","weight":87,"blockGap":"8","group":"More","advanced":true,"paramHelp":{"animation":"the animation to run"},"jsDoc":"Show a single animation frame.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"show frame of ","style":[]},{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"break"},{"kind":"label","text":"animation","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false}]}},"parameters":[{"name":"animation","description":"the animation to run","type":"light.NeoPixelAnimation"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.show_animation_frame"},"light.NeoPixelStrip.showColors":{"kind":-1,"attributes":{"jsDoc":"Renders a pattern of colors on the strip"},"parameters":[{"name":"leds","type":"string"},{"name":"interval","initializer":"400"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.show_colors"},"light.NeoPixelStrip.stopAllAnimations":{"kind":-1,"attributes":{"blockId":"light_stop_all_animations","block":"%strip|stop all animations","help":"light/neopixelstrip/stop-all-animations","weight":85,"blockGap":"8","group":"More","advanced":true,"jsDoc":"Stop the current animation and any other animations ready to show.","_def":{"parts":[{"kind":"param","name":"strip","ref":false},{"kind":"break"},{"kind":"label","text":"stop all animations","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false}]}},"parameters":[],"isInstance":true,"pyQName":"light.NeoPixelStrip.stop_all_animations"},"light.NeoPixelStrip.setBuffered":{"kind":-1,"attributes":{"blockId":"light_set_buffered","block":"set %strip buffered  %on","help":"light/neopixelstrip/set-buffered","weight":86,"blockGap":"8","group":"Configuration","advanced":true,"paramHelp":{"on":"call show whenever a light is modified"},"jsDoc":"Enables or disables automatically calling show when a change is made","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" buffered  ","style":[]},{"kind":"param","name":"on","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"on","ref":false}]}},"parameters":[{"name":"on","description":"call show whenever a light is modified","type":"boolean"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_buffered"},"light.NeoPixelStrip.buffered":{"kind":-1,"retType":"boolean","attributes":{"weight":85,"blockGap":"8","group":"Configuration","advanced":true,"jsDoc":"Gets a value indicated if the changes are buffered"},"parameters":[],"isInstance":true},"light.NeoPixelStrip.setMode":{"kind":-1,"attributes":{"blockId":"light_set_mode","block":"set %strip mode to %mode","help":"light/neopixelstrip/set-mode","weight":1,"blockGap":"8","group":"Configuration","advanced":true,"paramHelp":{"mode":"the kind of color encoding required by the programmable lights"},"jsDoc":"Sets the color mode and clears the colors.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" mode to ","style":[]},{"kind":"param","name":"mode","ref":false}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"mode","ref":false}]}},"parameters":[{"name":"mode","description":"the kind of color encoding required by the programmable lights","type":"NeoPixelMode","isEnum":true}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_mode"},"light.NeoPixelStrip.setLength":{"kind":-1,"attributes":{"blockId":"light_set_length","block":"set %strip length to %length pixels","weight":1,"blockGap":"8","_shadowOverrides":{"length":"lightLengthPicker"},"group":"Configuration","advanced":true,"paramHelp":{"numleds":""},"jsDoc":"Sets the number of LEDs on a strip","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"strip","ref":false},{"kind":"label","text":" length to ","style":[]},{"kind":"param","name":"length","shadowBlockId":"lightLengthPicker","ref":false},{"kind":"label","text":" pixels","style":[]}],"parameters":[{"kind":"param","name":"strip","ref":false},{"kind":"param","name":"length","shadowBlockId":"lightLengthPicker","ref":false}]}},"parameters":[{"name":"numleds"}],"isInstance":true,"pyQName":"light.NeoPixelStrip.set_length"},"light.NeoPixelStrip.__setAll":{"kind":-1,"attributes":{"blockId":"neopixel_set_strip_color","block":"set all pixels to %rgb=colorNumberPicker","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"rgb":"RGB color of the LED"},"jsDoc":"Set all of the pixels on the strip to one RGB color.","_def":{"parts":[{"kind":"label","text":"set all pixels to ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"rgb","description":"RGB color of the LED"}],"isInstance":true},"light.NeoPixelStrip.__graph":{"kind":-1,"attributes":{"blockId":"neopixel_show_bar_graph","block":"graph %value |up to %high","icon":"","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"value":"current value to plot","high":"maximum value, 0 to autoscale"},"jsDoc":"Display a vertical bar graph based on the `value` and `high` value.\nIf `high` is 0, the chart gets adjusted automatically.","_def":{"parts":[{"kind":"label","text":"graph ","style":[]},{"kind":"param","name":"value","ref":false},{"kind":"label","text":" ","style":[]},{"kind":"break"},{"kind":"label","text":"up to ","style":[]},{"kind":"param","name":"high","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false},{"kind":"param","name":"high","ref":false}]}},"parameters":[{"name":"value","description":"current value to plot"},{"name":"high","description":"maximum value, 0 to autoscale"}],"isInstance":true},"light.NeoPixelStrip.__setPixelColor":{"kind":-1,"attributes":{"blockId":"neopixel_set_pixel_color","block":"set pixel color at %pixeloffset|to %rgb=colorNumberPicker","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"pixeloffset":"position of the NeoPixel in the strip","color":"RGB color of the LED"},"jsDoc":"Set the pixel to a given color.\nYou need to call ``show`` to make the changes visible.","_def":{"parts":[{"kind":"label","text":"set pixel color at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"pixeloffset","ref":false},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the NeoPixel in the strip"},{"name":"color","description":"RGB color of the LED"}],"isInstance":true},"light.NeoPixelStrip.__pixelColor":{"kind":-1,"retType":"number","attributes":{"blockId":"neopixel_get_pixel_color","block":"pixel color at %pixeloffset","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"pixeloffset":"position of the NeoPixel in the strip"},"jsDoc":"Gets the pixel color.","_def":{"parts":[{"kind":"label","text":"pixel color at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false}],"parameters":[{"kind":"param","name":"pixeloffset","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the NeoPixel in the strip"}],"isInstance":true},"light.NeoPixelStrip.__setPixelWhiteLED":{"kind":-1,"attributes":{"blockId":"neopixel_set_pixel_white_led","block":"set pixel white LED at %pixeloffset|to %white","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"pixeloffset":"position of the LED in the strip","white":"brightness of the white LED"},"jsDoc":"Set the white brightness of a pixel in a NeoPixel strip of RGB+W LEDs.\nThis only works for RGB+W NeoPixels.","_def":{"parts":[{"kind":"label","text":"set pixel white LED at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"white","ref":false}],"parameters":[{"kind":"param","name":"pixeloffset","ref":false},{"kind":"param","name":"white","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the LED in the strip"},{"name":"white","description":"brightness of the white LED"}],"isInstance":true},"light.NeoPixelStrip.__show":{"kind":-1,"attributes":{"blockId":"neopixel_show","block":"show","deprecated":"1","defaultInstance":"light.pixels","jsDoc":"Make the strip show all the new changes for the pixels.","_def":{"parts":[{"kind":"label","text":"show","style":[]}],"parameters":[]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.__clear":{"kind":-1,"attributes":{"blockId":"neopixel_clear","block":"clear","deprecated":"1","defaultInstance":"light.pixels","jsDoc":"Turn off all pixel LEDs.","_def":{"parts":[{"kind":"label","text":"clear","style":[]}],"parameters":[]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.__length":{"kind":-1,"retType":"number","attributes":{"blockId":"neopixel_length","block":"length","deprecated":"1","defaultInstance":"light.pixels","jsDoc":"Get the number of pixels on the strip","_def":{"parts":[{"kind":"label","text":"length","style":[]}],"parameters":[]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.__setBrightness":{"kind":-1,"attributes":{"paramDefl":{"brightness":"20"},"blockId":"neopixel_set_brightness","block":"set brightness %brightness","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"brightness":"a measure of LED brightness in 0-255. eg: 20"},"jsDoc":"Set the brightness of the strip. This flag only applies to future operation.","_def":{"parts":[{"kind":"label","text":"set brightness ","style":[]},{"kind":"param","name":"brightness","ref":false}],"parameters":[{"kind":"param","name":"brightness","ref":false}]}},"parameters":[{"name":"brightness","description":"a measure of LED brightness in 0-255. eg: 20","default":"20"}],"isInstance":true},"light.NeoPixelStrip.__brightness":{"kind":-1,"retType":"number","attributes":{"blockId":"neopixel_get_brightness","block":"brightness","deprecated":"1","defaultInstance":"light.pixels","jsDoc":"Get the brightness of the pixel strip.","_def":{"parts":[{"kind":"label","text":"brightness","style":[]}],"parameters":[]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.__range":{"kind":-1,"retType":"light.NeoPixelStrip","attributes":{"paramDefl":{"length":"4"},"blockId":"neopixel_range","block":"range from %start|with %length|pixels","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"start":"offset in the NeoPixel strip to start the range","length":"number of pixels in the range. eg: 4"},"jsDoc":"Create a range of pixels.","_def":{"parts":[{"kind":"label","text":"range from ","style":[]},{"kind":"param","name":"start","ref":false},{"kind":"break"},{"kind":"label","text":"with ","style":[]},{"kind":"param","name":"length","ref":false},{"kind":"break"},{"kind":"label","text":"pixels","style":[]}],"parameters":[{"kind":"param","name":"start","ref":false},{"kind":"param","name":"length","ref":false}]}},"parameters":[{"name":"start","description":"offset in the NeoPixel strip to start the range"},{"name":"length","description":"number of pixels in the range. eg: 4","default":"4"}],"isInstance":true},"light.NeoPixelStrip.__move":{"kind":-1,"attributes":{"paramDefl":{"offset":"1"},"blockId":"neopixel_move_pixels","block":"%kind=MoveKind|by %offset","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"offset":"number of pixels to shift forward, eg: 1"},"jsDoc":"Shift LEDs forward and clear with zeros.\nYou need to call ``show`` to make the changes visible.","_def":{"parts":[{"kind":"param","name":"kind","shadowBlockId":"MoveKind","ref":false},{"kind":"break"},{"kind":"label","text":"by ","style":[]},{"kind":"param","name":"offset","ref":false}],"parameters":[{"kind":"param","name":"kind","shadowBlockId":"MoveKind","ref":false},{"kind":"param","name":"offset","ref":false}]}},"parameters":[{"name":"kind","type":"LightMove","isEnum":true},{"name":"offset","description":"number of pixels to shift forward, eg: 1","initializer":"1","default":"1"}],"isInstance":true},"light.NeoPixelStrip.__photonForward":{"kind":-1,"attributes":{"paramDefl":{"steps":"1"},"blockId":"neophoton_fd","block":"photon forward by %steps","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"steps":"number of steps (lights) to move, eg: 1"},"jsDoc":"Move a photon effect along the pixel strip by a number of steps.","_def":{"parts":[{"kind":"label","text":"photon forward by ","style":[]},{"kind":"param","name":"steps","ref":false}],"parameters":[{"kind":"param","name":"steps","ref":false}]}},"parameters":[{"name":"steps","description":"number of steps (lights) to move, eg: 1","default":"1"}],"isInstance":true},"light.NeoPixelStrip.__photonFlip":{"kind":-1,"attributes":{"blockId":"neophoton_flip","block":"photon flip","deprecated":"1","defaultInstance":"light.pixels","jsDoc":"Switch the direction of the photon pulse.","_def":{"parts":[{"kind":"label","text":"photon flip","style":[]}],"parameters":[]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.__setPhotonColor":{"kind":-1,"attributes":{"blockId":"neophoton_set_color","block":"photon set pen color %color","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"color":"the color of the photon"},"jsDoc":"Set the photon color.","_def":{"parts":[{"kind":"label","text":"photon set pen color ","style":[]},{"kind":"param","name":"color","ref":false}],"parameters":[{"kind":"param","name":"color","ref":false}]}},"parameters":[{"name":"color","description":"the color of the photon"}],"isInstance":true},"light.NeoPixelStrip.__setPhotonMode":{"kind":-1,"attributes":{"blockId":"neophoton_set_photon","block":"photon %mode","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"mode":"the desired mode"},"jsDoc":"Set the photon mode to pen up, pen down, or eraser.","_def":{"parts":[{"kind":"label","text":"photon ","style":[]},{"kind":"param","name":"mode","ref":false}],"parameters":[{"kind":"param","name":"mode","ref":false}]}},"parameters":[{"name":"mode","description":"the desired mode","type":"PhotonMode","isEnum":true}],"isInstance":true},"light.NeoPixelStrip.__showAnimation":{"kind":-1,"attributes":{"paramDefl":{"duration":"500"},"blockId":"neopixel_show_animation","block":"show %animation=light_animation|animation for %duration=timePicker|ms","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"animation":"the animation to run","duration":"the duration to run in milliseconds, eg: 500"},"jsDoc":"Show an animation or queue an animation in the animation queue","_def":{"parts":[{"kind":"label","text":"show ","style":[]},{"kind":"param","name":"animation","shadowBlockId":"light_animation","ref":false},{"kind":"break"},{"kind":"label","text":"animation for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"animation","shadowBlockId":"light_animation","ref":false},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"animation","description":"the animation to run","type":"light.NeoPixelAnimation"},{"name":"duration","description":"the duration to run in milliseconds, eg: 500","default":"500"}],"isInstance":true},"light.NeoPixelStrip.__showAnimationFrame":{"kind":-1,"attributes":{"blockId":"neopixel_show_animation_frame","block":"show animation frame %animation=light_animation","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"animation":"the animation to run"},"jsDoc":"Show a single animation frame","_def":{"parts":[{"kind":"label","text":"show animation frame ","style":[]},{"kind":"param","name":"animation","shadowBlockId":"light_animation","ref":false}],"parameters":[{"kind":"param","name":"animation","shadowBlockId":"light_animation","ref":false}]}},"parameters":[{"name":"animation","description":"the animation to run","type":"light.NeoPixelAnimation"}],"isInstance":true},"light.NeoPixelStrip.__stopAllAnimations":{"kind":-1,"attributes":{"blockId":"neopixel_stop_all_animations","block":"stop all animations","deprecated":"1","defaultInstance":"light.pixels","jsDoc":"Stop the current animation and any other animations ready to show.","_def":{"parts":[{"kind":"label","text":"stop all animations","style":[]}],"parameters":[]}},"parameters":[],"isInstance":true},"light.NeoPixelStrip.__setBuffered":{"kind":-1,"attributes":{"blockId":"neopixel_set_buffered","block":"set buffered  %on","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"on":"call show whenever a light is modified"},"jsDoc":"Enables or disables automatically calling show when a change is made","_def":{"parts":[{"kind":"label","text":"set buffered  ","style":[]},{"kind":"param","name":"on","ref":false}],"parameters":[{"kind":"param","name":"on","ref":false}]}},"parameters":[{"name":"on","description":"call show whenever a light is modified","type":"boolean"}],"isInstance":true},"light.NeoPixelStrip.__setMode":{"kind":-1,"attributes":{"blockId":"neopixel_set_mode","block":"set mode %mode","deprecated":"1","defaultInstance":"light.pixels","paramHelp":{"mode":"the kind of color encoding required by the programmable lights"},"jsDoc":"Sets the color mode and clears the colors.","_def":{"parts":[{"kind":"label","text":"set mode ","style":[]},{"kind":"param","name":"mode","ref":false}],"parameters":[{"kind":"param","name":"mode","ref":false}]}},"parameters":[{"name":"mode","description":"the kind of color encoding required by the programmable lights","type":"NeoPixelMode","isEnum":true}],"isInstance":true},"light.createNeoPixelStrip":{"kind":-3,"retType":"light.NeoPixelStrip","attributes":{"blockId":"neopixel_create","block":"create WS2812 strip|pin %pin|with %numleds pixels","help":"light/create-neo-pixel-strip","trackArgs":[0,2],"parts":"neopixel","weight":100,"blockSetVariable":"strip","advanced":true,"blockHidden":true,"jsDoc":"Creates a strip of colored LEDs (WS2812b)","_def":{"parts":[{"kind":"label","text":"create WS2812 strip","style":[]},{"kind":"break"},{"kind":"label","text":"pin ","style":[]},{"kind":"param","name":"pin","ref":false},{"kind":"break"},{"kind":"label","text":"with ","style":[]},{"kind":"param","name":"numleds","ref":false},{"kind":"label","text":" pixels","style":[]}],"parameters":[{"kind":"param","name":"pin","ref":false},{"kind":"param","name":"numleds","ref":false}]}},"parameters":[{"name":"pin","type":"DigitalInOutPin"},{"name":"numleds","initializer":"10"},{"name":"mode","type":"NeoPixelMode","initializer":"undefined","isEnum":true}],"pyQName":"light.create_neo_pixel_strip"},"light.rgb":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"red":"255","green":"255","blue":"255"},"blockId":"neopixel_rgb","block":"red %red|green %green|blue %blue","paramMin":{"red":"0","green":"0","blue":"0"},"paramMax":{"red":"255","green":"255","blue":"255"},"help":"light/rgb","group":"Color","weight":19,"blockGap":"8","paramHelp":{"red":"value of the red channel between 0 and 255. eg: 255","green":"value of the green channel between 0 and 255. eg: 255","blue":"value of the blue channel between 0 and 255. eg: 255"},"jsDoc":"Converts red, green, blue channels into a RGB color","_def":{"parts":[{"kind":"label","text":"red ","style":[]},{"kind":"param","name":"red","ref":false},{"kind":"break"},{"kind":"label","text":"green ","style":[]},{"kind":"param","name":"green","ref":false},{"kind":"break"},{"kind":"label","text":"blue ","style":[]},{"kind":"param","name":"blue","ref":false}],"parameters":[{"kind":"param","name":"red","ref":false},{"kind":"param","name":"green","ref":false},{"kind":"param","name":"blue","ref":false}]}},"parameters":[{"name":"red","description":"value of the red channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"green","description":"value of the green channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"blue","description":"value of the blue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"light.colors":{"kind":-3,"retType":"number","attributes":{"blockId":"neopixel_colors","block":"%color","help":"light/colors","shim":"TD_ID","group":"Color","weight":20,"blockGap":"8","jsDoc":"Get the RGB value of a known color","_def":{"parts":[{"kind":"param","name":"color","ref":false}],"parameters":[{"kind":"param","name":"color","ref":false}]}},"parameters":[{"name":"color","type":"Colors","isEnum":true}]},"light.hsv":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"hue":"255","sat":"255","val":"255"},"blockId":"neopixel_hsv","block":"hue %hue|sat %sat|val %val","paramMin":{"hue":"0","sat":"0","val":"0"},"paramMax":{"hue":"255","sat":"255","val":"255"},"help":"light/hsv","group":"Color","weight":17,"paramHelp":{"hue":"value of the hue channel between 0 and 255. eg: 255","sat":"value of the saturation channel between 0 and 255. eg: 255","val":"value of the value channel between 0 and 255. eg: 255"},"jsDoc":"Convert an HSV (hue, saturation, value) color to RGB","_def":{"parts":[{"kind":"label","text":"hue ","style":[]},{"kind":"param","name":"hue","ref":false},{"kind":"break"},{"kind":"label","text":"sat ","style":[]},{"kind":"param","name":"sat","ref":false},{"kind":"break"},{"kind":"label","text":"val ","style":[]},{"kind":"param","name":"val","ref":false}],"parameters":[{"kind":"param","name":"hue","ref":false},{"kind":"param","name":"sat","ref":false},{"kind":"param","name":"val","ref":false}]}},"parameters":[{"name":"hue","description":"value of the hue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"sat","description":"value of the saturation channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"val","description":"value of the value channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"light.fade":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"brightness":"128"},"blockId":"neopixel_fade","block":"fade %color=neopixel_colors|by %brightness","paramMin":{"brightness":"0"},"paramMax":{"brightness":"255"},"help":"light/fade","group":"Color","weight":18,"blockGap":"8","blockHidden":true,"deprecated":"true","paramHelp":{"color":"color to fade","brightness":"the amount of brightness to apply to the color, eg: 128"},"jsDoc":"Use color.fade instead","_def":{"parts":[{"kind":"label","text":"fade ","style":[]},{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"break"},{"kind":"label","text":"by ","style":[]},{"kind":"param","name":"brightness","ref":false}],"parameters":[{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"param","name":"brightness","ref":false}]}},"parameters":[{"name":"c"},{"name":"brightness","description":"the amount of brightness to apply to the color, eg: 128","default":"128","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"light.NeoPixelAnimation":{"kind":8,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstances":"true","jsDoc":"An animation of a NeoPixel"},"extendsTypes":["light.NeoPixelAnimation"]},"light.NeoPixelAnimation.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"light.NeoPixelAnimation.createRenderer":{"kind":-1,"retType":"() => boolean","attributes":{"paramHelp":{"strip":"the strip to execute on"},"jsDoc":"Creates an animator instance"},"parameters":[{"name":"strip","description":"the strip to execute on","type":"light.NeoPixelStrip"}],"isInstance":true,"pyQName":"light.NeoPixelAnimation.create_renderer"},"light.RainbowCycleAnimation":{"kind":8,"retType":"light.RainbowCycleAnimation","extendsTypes":["light.RainbowCycleAnimation","light.NeoPixelAnimation"]},"light.RainbowCycleAnimation.delay":{"kind":2,"retType":"number","isInstance":true},"light.RainbowCycleAnimation.__constructor":{"kind":-3,"parameters":[{"name":"delay"}],"isInstance":true},"light.RainbowCycleAnimation.createRenderer":{"kind":-1,"retType":"() => boolean","parameters":[{"name":"strip","type":"light.NeoPixelStrip"}],"isInstance":true,"pyQName":"light.RainbowCycleAnimation.create_renderer"},"light.rainbowAnimation":{"kind":4,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstance":"true","block":"rainbow","whenUsed":true,"jres":"true","blockIdentity":"light._animationPicker","_def":{"parts":[{"kind":"label","text":"rainbow","style":[]}],"parameters":[]}},"pyQName":"light.rainbow_animation"},"light.RunningLightsAnimation":{"kind":8,"retType":"light.RunningLightsAnimation","extendsTypes":["light.RunningLightsAnimation","light.NeoPixelAnimation"]},"light.RunningLightsAnimation.red":{"kind":2,"retType":"number","isInstance":true},"light.RunningLightsAnimation.green":{"kind":2,"retType":"number","isInstance":true},"light.RunningLightsAnimation.blue":{"kind":2,"retType":"number","isInstance":true},"light.RunningLightsAnimation.delay":{"kind":2,"retType":"number","isInstance":true},"light.RunningLightsAnimation.__constructor":{"kind":-3,"parameters":[{"name":"red"},{"name":"green"},{"name":"blue"},{"name":"delay"}],"isInstance":true},"light.RunningLightsAnimation.createRenderer":{"kind":-1,"retType":"() => boolean","parameters":[{"name":"strip","type":"light.NeoPixelStrip"}],"isInstance":true,"pyQName":"light.RunningLightsAnimation.create_renderer"},"light.runningLightsAnimation":{"kind":4,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstance":"true","block":"running lights","jres":"true","blockIdentity":"light._animationPicker","whenUsed":true,"_def":{"parts":[{"kind":"label","text":"running lights","style":[]}],"parameters":[]}},"pyQName":"light.running_lights_animation"},"light.cometAnimation":{"kind":4,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstance":"true","block":"comet","jres":"true","blockIdentity":"light._animationPicker","whenUsed":true,"_def":{"parts":[{"kind":"label","text":"comet","style":[]}],"parameters":[]}},"pyQName":"light.comet_animation"},"light.SparkleAnimation":{"kind":8,"retType":"light.SparkleAnimation","extendsTypes":["light.SparkleAnimation","light.NeoPixelAnimation"]},"light.SparkleAnimation.rgb":{"kind":2,"retType":"number","isInstance":true},"light.SparkleAnimation.delay":{"kind":2,"retType":"number","isInstance":true},"light.SparkleAnimation.__constructor":{"kind":-3,"parameters":[{"name":"red"},{"name":"green"},{"name":"blue"},{"name":"delay"}],"isInstance":true},"light.SparkleAnimation.createRenderer":{"kind":-1,"retType":"() => boolean","parameters":[{"name":"strip","type":"light.NeoPixelStrip"}],"isInstance":true,"pyQName":"light.SparkleAnimation.create_renderer"},"light.sparkleAnimation":{"kind":4,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstance":"true","block":"sparkle","jres":"true","blockIdentity":"light._animationPicker","whenUsed":true,"_def":{"parts":[{"kind":"label","text":"sparkle","style":[]}],"parameters":[]}},"pyQName":"light.sparkle_animation"},"light.colorWipeAnimation":{"kind":4,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstance":"true","block":"color wipe","jres":"true","blockIdentity":"light._animationPicker","whenUsed":true,"_def":{"parts":[{"kind":"label","text":"color wipe","style":[]}],"parameters":[]}},"pyQName":"light.color_wipe_animation"},"light.theaterChaseAnimation":{"kind":4,"retType":"light.NeoPixelAnimation","attributes":{"fixedInstance":"true","block":"theater chase","jres":"true","blockIdentity":"light._animationPicker","whenUsed":true,"_def":{"parts":[{"kind":"label","text":"theater chase","style":[]}],"parameters":[]}},"pyQName":"light.theater_chase_animation"},"light._animationPicker":{"kind":-3,"retType":"light.NeoPixelAnimation","attributes":{"blockId":"light_animation_picker","block":"%animation","shim":"TD_ID","paramFieldEditor":{"animation":"imagedropdown"},"paramFieldEditorOptions":{"animation":{"columns":"3"}},"weight":0,"group":"More","paramHelp":{"animation":"The animation type"},"jsDoc":"An animation that can be shown on a light strip","_def":{"parts":[{"kind":"param","name":"animation","ref":false}],"parameters":[{"kind":"param","name":"animation","ref":false}]}},"parameters":[{"name":"animation","description":"The animation type","type":"light.NeoPixelAnimation"}],"pyQName":"light._animation_picker"},"light.__lengthPicker":{"kind":-3,"retType":"number","attributes":{"blockId":"lightLengthPicker","block":"%pixels","blockHidden":true,"shim":"TD_ID","colorSecondary":"#FFFFFF","paramFieldEditor":{"pixels":"numberdropdown"},"paramFieldEditorOptions":{"pixels":{"decompileLiterals":"true","data":"[[\"7\", 7], [\"8\", 8], [\"12\", 12], [\"16\", 16], [\"24\", 24], [\"30\", 30], [\"60\", 60], [\"64\", 64], [\"90\", 90], [\"120\", 120], [\"144\", 144]]"}},"paramHelp":{"pixels":"number of LEDs"},"jsDoc":"Get the light length picker","_def":{"parts":[{"kind":"param","name":"pixels","ref":false}],"parameters":[{"kind":"param","name":"pixels","ref":false}]}},"parameters":[{"name":"pixels","description":"number of LEDs"}]},"easing":{"kind":5,"retType":""},"easing.linear":{"kind":-3,"retType":"number","parameters":[{"name":"t"}]},"easing.inQuad":{"kind":-3,"retType":"number","parameters":[{"name":"t"}],"pyQName":"easing.in_quad"},"easing.outQuad":{"kind":-3,"retType":"number","parameters":[{"name":"t"}],"pyQName":"easing.out_quad"},"easing.inOutQuad":{"kind":-3,"retType":"number","parameters":[{"name":"t"}],"pyQName":"easing.in_out_quad"},"easing.inCubic":{"kind":-3,"retType":"number","parameters":[{"name":"t"}],"pyQName":"easing.in_cubic"},"easing.outCubic":{"kind":-3,"retType":"number","parameters":[{"name":"t"}],"pyQName":"easing.out_cubic"},"easing.inOutCubic":{"kind":-3,"retType":"number","parameters":[{"name":"t"}],"pyQName":"easing.in_out_cubic"},"light.BrightnessTransition":{"kind":8,"retType":"light.BrightnessTransition","extendsTypes":["light.BrightnessTransition"]},"light.BrightnessTransition.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"light.BrightnessTransition.apply":{"kind":-1,"parameters":[{"name":"strip","type":"light.NeoPixelStrip"},{"name":"t"},{"name":"start"},{"name":"end"}],"isInstance":true},"light.EasingBrightnessTransition":{"kind":8,"retType":"light.EasingBrightnessTransition","extendsTypes":["light.EasingBrightnessTransition","light.BrightnessTransition"]},"light.EasingBrightnessTransition.__constructor":{"kind":-3,"parameters":[{"name":"timeEasing","type":"(t: number) => number","handlerParameters":[{"name":"t","type":"number"}]},{"name":"spatialEasing","type":"(t: number) => number","initializer":"undefined","handlerParameters":[{"name":"t","type":"number"}]}],"isInstance":true},"light.EasingBrightnessTransition.apply":{"kind":-1,"parameters":[{"name":"strip","type":"light.NeoPixelStrip"},{"name":"t"},{"name":"start"},{"name":"end"}],"isInstance":true},"light.BrightnessTransitionPlayer":{"kind":8,"retType":"light.BrightnessTransitionPlayer","extendsTypes":[]},"light.BrightnessTransitionPlayer.__constructor":{"kind":-3,"parameters":[{"name":"transition","type":"light.BrightnessTransition"},{"name":"startBrightness"},{"name":"endBrightness"},{"name":"duration"},{"name":"repeat"},{"name":"yoyo","type":"boolean"}],"isInstance":true},"light.BrightnessTransitionPlayer.update":{"kind":-1,"retType":"boolean","parameters":[{"name":"strip","type":"light.NeoPixelStrip"}],"isInstance":true},"light.createStrip":{"kind":-3,"retType":"light.NeoPixelStrip","attributes":{"paramDefl":{"numleds":"30","mode":"NeoPixelMode.RGB_GRB"},"blockId":"neopixel_create_strip","block":"create WS2812 strip on %pin with %numleds pixels","help":"light/create-strip","weight":100,"blockSetVariable":"strip","trackArgs":[0,2],"parts":"neopixel","advanced":true,"paramHelp":{"pin":"the pin where the strip is connected.","numleds":"number of leds in the strip, eg: 30","mode":"the light encoding mode for different LED strips, eg: NeoPixelMode.RGB_GRB"},"jsDoc":"Create a new programmable light strip.","_def":{"parts":[{"kind":"label","text":"create WS2812 strip on ","style":[]},{"kind":"param","name":"pin","ref":false},{"kind":"label","text":" with ","style":[]},{"kind":"param","name":"numleds","ref":false},{"kind":"label","text":" pixels","style":[]}],"parameters":[{"kind":"param","name":"pin","ref":false},{"kind":"param","name":"numleds","ref":false}]}},"parameters":[{"name":"pin","description":"the pin where the strip is connected.","type":"DigitalInOutPin","initializer":"null"},{"name":"numleds","description":"number of leds in the strip, eg: 30","initializer":"30","default":"30"},{"name":"mode","description":"the light encoding mode for different LED strips, eg: NeoPixelMode.RGB_GRB","type":"NeoPixelMode","initializer":"NeoPixelMode.RGB","default":"NeoPixelMode.RGB_GRB","isEnum":true}],"pyQName":"light.create_strip"},"light.createAPA102Strip":{"kind":-3,"retType":"light.NeoPixelStrip","attributes":{"blockId":"light_create_dotstar","block":"create APA102 strip|data %data|clock %clk|with %numleds pixels","help":"light/create-apa102-strip","trackArgs":[0,1,2],"parts":"dotstar","weight":100,"blockSetVariable":"strip","advanced":true,"jsDoc":"Creates a strip of colored LEDs (APA102)","_def":{"parts":[{"kind":"label","text":"create APA102 strip","style":[]},{"kind":"break"},{"kind":"label","text":"data ","style":[]},{"kind":"param","name":"data","ref":false},{"kind":"break"},{"kind":"label","text":"clock ","style":[]},{"kind":"param","name":"clk","ref":false},{"kind":"break"},{"kind":"label","text":"with ","style":[]},{"kind":"param","name":"numleds","ref":false},{"kind":"label","text":" pixels","style":[]}],"parameters":[{"kind":"param","name":"data","ref":false},{"kind":"param","name":"clk","ref":false},{"kind":"param","name":"numleds","ref":false}]}},"parameters":[{"name":"dataPin","type":"DigitalInOutPin"},{"name":"clkPin","type":"DigitalInOutPin"},{"name":"numleds"}],"pyQName":"light.create_apa102_strip"},"light.defaultStrip":{"kind":-3,"retType":"light.NeoPixelStrip","attributes":{"help":"light/default-strip","blockId":"neopixel_default_strip","block":"default strip","weight":110,"blockGap":"8","advanced":true,"parts":"pixels","jsDoc":"Gets the default light strip","_def":{"parts":[{"kind":"label","text":"default strip","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"light.default_strip"},"light.onboardStrip":{"kind":-3,"retType":"light.NeoPixelStrip","attributes":{"help":"light/onboard-strip","blockId":"neopixel_onboard_strip","block":"onboard strip","weight":111,"blockGap":"8","advanced":true,"jsDoc":"Get the onboard light strip.","_def":{"parts":[{"kind":"label","text":"onboard strip","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"light.onboard_strip"},"light.pixels":{"kind":4,"retType":"light.NeoPixelStrip","attributes":{"whenUsed":"true","jsDoc":"Gets the default external light strip"}},"light.setAll":{"kind":-3,"attributes":{"blockId":"builtin_neopixel_set_strip_color","block":"set all pixels to %rgb=colorNumberPicker","help":"light/set-all","weight":79,"blockGap":"8","paramHelp":{"rgb":"RGB color of the LED"},"jsDoc":"Set all of the pixels on the strip to one RGB color.","_def":{"parts":[{"kind":"label","text":"set all pixels to ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"rgb","description":"RGB color of the LED"}],"pyQName":"light.set_all"},"light.setGradient":{"kind":-3,"attributes":{"blockId":"builtinlightsetgradient","block":"set gradient from %startRgb=colorNumberPicker to %endRgb=colorNumberPicker","weight":78,"blockGap":"8","blockHidden":true,"paramHelp":{"startColor":"the start color","endColor":"the end color"},"jsDoc":"Sets a gradient between two colors","_def":{"parts":[{"kind":"label","text":"set gradient from ","style":[]},{"kind":"param","name":"startRgb","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"endRgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"startRgb","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"param","name":"endRgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"startRgb"},{"name":"endRgb"}],"pyQName":"light.set_gradient"},"light.clear":{"kind":-3,"attributes":{"blockId":"builtin_neopixel_clear","block":"clear","parts":"neopixel","help":"light/clear","group":"More","weight":9,"blockGap":"8","jsDoc":"Turn off all pixel LEDs on the onboard strip.","_def":{"parts":[{"kind":"label","text":"clear","style":[]}],"parameters":[]}},"parameters":[]},"light.graph":{"kind":-3,"attributes":{"blockId":"builtin_neopixel_show_bar_graph","block":"graph %value||up to %high","icon":"","help":"light/graph","blockGap":"8","weight":10,"paramHelp":{"value":"current value to plot","high":"maximum value, 0 to autoscale"},"jsDoc":"Display a vertical bar graph based on the `value` and `high` value.\nIf `high` is 0, the chart gets adjusted automatically.","_def":{"parts":[{"kind":"label","text":"graph ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]},"_expandedDef":{"parts":[{"kind":"label","text":"up to ","style":[]},{"kind":"param","name":"high","ref":false}],"parameters":[{"kind":"param","name":"high","ref":false}]}},"parameters":[{"name":"value","description":"current value to plot"},{"name":"high","description":"maximum value, 0 to autoscale","initializer":"undefined"}]},"light.setPixelColor":{"kind":-3,"attributes":{"blockId":"builtin_neopixel_set_pixel_color","block":"set pixel color at %pixeloffset|to %rgb=colorNumberPicker","help":"light/set-pixel-color","group":"More","weight":89,"blockGap":"8","paramHelp":{"pixeloffset":"position of the NeoPixel in the strip","color":"RGB color of the LED"},"jsDoc":"Set the pixel to a given color.","_def":{"parts":[{"kind":"label","text":"set pixel color at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false},{"kind":"break"},{"kind":"label","text":"to ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}],"parameters":[{"kind":"param","name":"pixeloffset","ref":false},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the NeoPixel in the strip"},{"name":"color","description":"RGB color of the LED"}],"pyQName":"light.set_pixel_color"},"light.pixelColor":{"kind":-3,"retType":"number","attributes":{"blockId":"builtin_neopixel_pixel_color","block":"pixel color at %pixeloffset","help":"light/pixel-color","group":"More","weight":88,"paramHelp":{"pixeloffset":"position of the NeoPixel in the strip"},"jsDoc":"Gets the pixel color at a given offset.","_def":{"parts":[{"kind":"label","text":"pixel color at ","style":[]},{"kind":"param","name":"pixeloffset","ref":false}],"parameters":[{"kind":"param","name":"pixeloffset","ref":false}]}},"parameters":[{"name":"pixeloffset","description":"position of the NeoPixel in the strip"}],"pyQName":"light.pixel_color"},"light.setBrightness":{"kind":-3,"attributes":{"paramDefl":{"brightness":"20"},"blockId":"builtin_neopixel_set_brightness","block":"set brightness %brightness","paramMin":{"brightness":"0"},"paramMax":{"brightness":"255"},"help":"light/set-brightness","weight":2,"blockGap":"8","paramHelp":{"brightness":"a measure of LED brightness in 0-255. eg: 20"},"jsDoc":"Set the brightness of the strip. This flag only applies to future operation.","_def":{"parts":[{"kind":"label","text":"set brightness ","style":[]},{"kind":"param","name":"brightness","ref":false}],"parameters":[{"kind":"param","name":"brightness","ref":false}]}},"parameters":[{"name":"brightness","description":"a measure of LED brightness in 0-255. eg: 20","default":"20","options":{"min":{"value":"0"},"max":{"value":"255"}}}],"pyQName":"light.set_brightness"},"light.photonForward":{"kind":-3,"attributes":{"paramDefl":{"steps":"1"},"blockId":"builtin_neophoton_fd","block":"photon forward by %steps","help":"light/photon-forward","group":"Photon","weight":41,"blockGap":"8","paramHelp":{"steps":"number of steps (lights) to move, eg: 1"},"jsDoc":"Move a photon effect along the pixel strip by a number of steps.","_def":{"parts":[{"kind":"label","text":"photon forward by ","style":[]},{"kind":"param","name":"steps","ref":false}],"parameters":[{"kind":"param","name":"steps","ref":false}]}},"parameters":[{"name":"steps","description":"number of steps (lights) to move, eg: 1","default":"1"}],"pyQName":"light.photon_forward"},"light.photonFlip":{"kind":-3,"attributes":{"blockId":"builtin_neophoton_flip","block":"photon flip","help":"light/photon-flip","parts":"neopixel","group":"Photon","weight":40,"blockGap":"8","jsDoc":"Switch the direction of the photon pulse.","_def":{"parts":[{"kind":"label","text":"photon flip","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"light.photon_flip"},"light.setPhotonPosition":{"kind":-3,"attributes":{"blockId":"builtin_light_photon_set_position","block":"photon set position %index","help":"light/set-photon-position","parts":"neopixel","group":"Photon","weight":39,"blockGap":"8","paramHelp":{"index":"index of the light, if out of bound, the index is wrapped"},"jsDoc":"Sets the photon position to a given light index","_def":{"parts":[{"kind":"label","text":"photon set position ","style":[]},{"kind":"param","name":"index","ref":false}],"parameters":[{"kind":"param","name":"index","ref":false}]}},"parameters":[{"name":"index","description":"index of the light, if out of bound, the index is wrapped"}],"pyQName":"light.set_photon_position"},"light.setPhotonPenHue":{"kind":-3,"attributes":{"blockId":"builtin_neophoton_set_pen_hue","block":"photon set pen hue %hue=colorWheelHsvPicker","help":"light/set-photon-pen-hue","group":"Photon","weight":39,"blockGap":"8","paramHelp":{"hue":"the color hue of the photon"},"jsDoc":"Set the photon color hue.","_def":{"parts":[{"kind":"label","text":"photon set pen hue ","style":[]},{"kind":"param","name":"hue","shadowBlockId":"colorWheelHsvPicker","ref":false}],"parameters":[{"kind":"param","name":"hue","shadowBlockId":"colorWheelHsvPicker","ref":false}]}},"parameters":[{"name":"hue","description":"the color hue of the photon"}],"pyQName":"light.set_photon_pen_hue"},"light.setPhotonMode":{"kind":-3,"attributes":{"blockId":"builtin_neophoton_set_photon","block":"photon %mode","help":"light/set-photon-mode","group":"Photon","weight":38,"paramHelp":{"mode":"the desired mode"},"jsDoc":"Set the photon mode to pen up, pen down, or eraser.","_def":{"parts":[{"kind":"label","text":"photon ","style":[]},{"kind":"param","name":"mode","ref":false}],"parameters":[{"kind":"param","name":"mode","ref":false}]}},"parameters":[{"name":"mode","description":"the desired mode","type":"PhotonMode","isEnum":true}],"pyQName":"light.set_photon_mode"},"light.showAnimation":{"kind":-3,"attributes":{"paramDefl":{"animation":"light.rainbowAnimation","duration":"500"},"blockId":"builtin_neopixel_show_animation","block":"show animation %animation=light_animation_picker|for %duration=timePicker|ms","help":"light/show-animation","blockGap":"8","weight":81,"paramHelp":{"animation":"the animation to run, eg: light.rainbowAnimation","duration":"the duration to run in milliseconds, eg: 500"},"jsDoc":"Show an animation or queue an animation in the animation queue","_def":{"parts":[{"kind":"label","text":"show animation ","style":[]},{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"break"},{"kind":"label","text":"for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"animation","description":"the animation to run, eg: light.rainbowAnimation","type":"light.NeoPixelAnimation","default":"light.rainbowAnimation"},{"name":"duration","description":"the duration to run in milliseconds, eg: 500","default":"500"}],"pyQName":"light.show_animation"},"light.showAnimationFrame":{"kind":-3,"attributes":{"paramDefl":{"animation":"light.rainbowAnimation"},"blockId":"builtin_neopixel_show_animation_frame","block":"show frame of %animation=light_animation_picker|animation","help":"light/show-animation-frame","group":"More","weight":24,"blockGap":"8","paramHelp":{"animation":"the animation to run, eg: light.rainbowAnimation"},"jsDoc":"Show a single animation frame","_def":{"parts":[{"kind":"label","text":"show frame of ","style":[]},{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false},{"kind":"break"},{"kind":"label","text":"animation","style":[]}],"parameters":[{"kind":"param","name":"animation","shadowBlockId":"light_animation_picker","ref":false}]}},"parameters":[{"name":"animation","description":"the animation to run, eg: light.rainbowAnimation","type":"light.NeoPixelAnimation","default":"light.rainbowAnimation"}],"pyQName":"light.show_animation_frame"},"light.stopAllAnimations":{"kind":-3,"attributes":{"blockId":"builtin_neopixel_stop_all_animations","block":"stop all animations","help":"light/stop-all-animations","group":"More","weight":23,"jsDoc":"Stop the current animation and any other animations ready to show.","_def":{"parts":[{"kind":"label","text":"stop all animations","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"light.stop_all_animations"},"light.animation":{"kind":-3,"retType":"light.NeoPixelAnimation","attributes":{"paramFieldEditor":{"kind":"imagedropdown"},"paramFieldEditorOptions":{"kind":{"columns":"3"}},"blockGap":"8","blockId":"light_animation","block":"%kind","group":"More","weight":25,"help":"light/animation","blockHidden":true,"deprecated":"1","paramHelp":{"kind":"the type of animation"},"jsDoc":"Creates a builtin animation","_def":{"parts":[{"kind":"param","name":"kind","ref":false}],"parameters":[{"kind":"param","name":"kind","ref":false}]}},"parameters":[{"name":"kind","description":"the type of animation","type":"LightAnimation","isEnum":true}]},"light.range":{"kind":-3,"retType":"light.NeoPixelStrip","attributes":{"paramDefl":{"length":"4"},"blockId":"lightstrip_range","block":"range from %start|with %length|pixels","weight":1,"paramHelp":{"start":"offset in the NeoPixel strip to start the range","length":"number of pixels in the range, eg: 4"},"jsDoc":"Create a range of pixels.","_def":{"parts":[{"kind":"label","text":"range from ","style":[]},{"kind":"param","name":"start","ref":false},{"kind":"break"},{"kind":"label","text":"with ","style":[]},{"kind":"param","name":"length","ref":false},{"kind":"break"},{"kind":"label","text":"pixels","style":[]}],"parameters":[{"kind":"param","name":"start","ref":false},{"kind":"param","name":"length","ref":false}]}},"parameters":[{"name":"start","description":"offset in the NeoPixel strip to start the range"},{"name":"length","description":"number of pixels in the range, eg: 4","default":"4"}]},"light.setLength":{"kind":-3,"attributes":{"paramDefl":{"numleds":"30"},"blockId":"lightds_setlength","block":"set pixels length to %numleds pixels","explicitDefaults":["numleds"],"_shadowOverrides":{"numleds":"lightLengthPicker"},"weight":0,"jsDoc":"Sets the number of LEDS on the default light strip","_def":{"parts":[{"kind":"label","text":"set pixels length to ","style":[]},{"kind":"param","name":"numleds","shadowBlockId":"lightLengthPicker","ref":false},{"kind":"label","text":" pixels","style":[]}],"parameters":[{"kind":"param","name":"numleds","shadowBlockId":"lightLengthPicker","ref":false}]}},"parameters":[{"name":"numleds","initializer":"30","default":"30"}],"pyQName":"light.set_length"},"light.setMode":{"kind":-3,"attributes":{"blockId":"lightds_setmode","block":"set default strip mode to %mode","weight":0,"jsDoc":"Sets the type of RGB light on the default strip","_def":{"parts":[{"kind":"label","text":"set default strip mode to ","style":[]},{"kind":"param","name":"mode","ref":false}],"parameters":[{"kind":"param","name":"mode","ref":false}]}},"parameters":[{"name":"mode","type":"NeoPixelMode","isEnum":true}],"pyQName":"light.set_mode"}}},"sha":"6b0a955317ad387903e08e8ca6da921c189cc913141bfc5dd5856235874455bf"},"libs/lightsensor":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"input":{"kind":5,"retType":"","attributes":{"color":"#B4009E","weight":98,"icon":"","groups":["other","More"],"jsDoc":"Respond to and read data from buttons and sensors.\n\nEvents and data from sensors."}},"basic":{"kind":5,"retType":""},"input.onLightConditionChanged":{"kind":-3,"attributes":{"help":"input/on-light-condition-changed","blockId":"input_on_light_condition_changed","block":"on light %condition","parts":"lightsensor","weight":84,"blockGap":"12","paramHelp":{"condition":"the condition that event triggers on"},"jsDoc":"Register an event that runs when light conditions (darker or brighter) change.","_def":{"parts":[{"kind":"label","text":"on light ","style":[]},{"kind":"param","name":"condition","ref":false}],"parameters":[{"kind":"param","name":"condition","ref":false}]}},"parameters":[{"name":"condition","description":"the condition that event triggers on","type":"LightCondition","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"input.on_light_condition_changed"},"input.lightLevel":{"kind":-3,"retType":"number","attributes":{"help":"input/light-level","blockId":"device_get_light_level","block":"light level","parts":"lightsensor","weight":30,"blockGap":"8","jsDoc":"Read the light level applied to the LED screen in a range from 0 (dark) to 255 (bright).","_def":{"parts":[{"kind":"label","text":"light level","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"input.light_level"},"input.setLightThreshold":{"kind":-3,"attributes":{"help":"input/set-light-threshold","blockId":"lightsensor_set_threshold","block":"set %condition| light threshold to %value","parts":"lightsensor","paramMin":{"value":"1"},"paramMax":{"value":"255"},"group":"More","weight":13,"blockGap":"8","jsDoc":"Set the threshold value for the light condition event.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"condition","ref":false},{"kind":"break"},{"kind":"label","text":" light threshold to ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"condition","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"condition","type":"LightCondition","isEnum":true},{"name":"value","options":{"min":{"value":"1"},"max":{"value":"255"}}}],"pyQName":"input.set_light_threshold"},"LightCondition":{"kind":6,"retType":"LightCondition","extendsTypes":["LightCondition","Number"]},"LightCondition.Dark":{"retType":"LightCondition.Dark","attributes":{"block":"dark","_def":{"parts":[{"kind":"label","text":"dark","style":[]}],"parameters":[]}},"extendsTypes":["LightCondition.Dark","Number"],"pyQName":"LightCondition.DARK"},"LightCondition.Bright":{"retType":"LightCondition.Bright","attributes":{"block":"bright","_def":{"parts":[{"kind":"label","text":"bright","style":[]}],"parameters":[]}},"extendsTypes":["LightCondition.Bright","Number"],"pyQName":"LightCondition.BRIGHT"}}},"sha":"c696b759f05df0173b254add5cdfb5cd4992883f103a76be59a2065a704f3a36"},"libs/microphone":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"input":{"kind":5,"retType":"","attributes":{"color":"#B4009E","weight":98,"icon":"","groups":["other","More"],"jsDoc":"Respond to and read data from buttons and sensors.\n\nEvents and data from sensors."}},"basic":{"kind":5,"retType":""},"LoudnessCondition":{"kind":6,"retType":"LoudnessCondition","extendsTypes":["LoudnessCondition","Number"]},"LoudnessCondition.Quiet":{"retType":"LoudnessCondition.Quiet","attributes":{"block":"quiet","_def":{"parts":[{"kind":"label","text":"quiet","style":[]}],"parameters":[]}},"extendsTypes":["LoudnessCondition.Quiet","Number"],"pyQName":"LoudnessCondition.QUIET"},"LoudnessCondition.Loud":{"retType":"LoudnessCondition.Loud","attributes":{"block":"loud","_def":{"parts":[{"kind":"label","text":"loud","style":[]}],"parameters":[]}},"extendsTypes":["LoudnessCondition.Loud","Number"],"pyQName":"LoudnessCondition.LOUD"},"input.onLoudSound":{"kind":-3,"attributes":{"help":"input/on-loud-sound","blockId":"input_on_loud_sound","block":"on loud sound","parts":"microphone","weight":88,"blockGap":"12","jsDoc":"Registers an event that runs when a loud sound is detected","_def":{"parts":[{"kind":"label","text":"on loud sound","style":[]}],"parameters":[]}},"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"input.on_loud_sound"},"input.soundLevel":{"kind":-3,"retType":"number","attributes":{"help":"input/sound-level","blockId":"device_get_sound_level","block":"sound level","parts":"microphone","weight":34,"blockGap":"8","jsDoc":"Reads the loudness through the microphone from 0 (silent) to 255 (loud)","_def":{"parts":[{"kind":"label","text":"sound level","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"input.sound_level"},"input.setLoudSoundThreshold":{"kind":-3,"attributes":{"help":"input/set-loud-sound-threshold","blockId":"input_set_loud_sound_threshold","block":"set loud sound threshold %value","parts":"microphone","paramMin":{"value":"1"},"paramMax":{"value":"255"},"group":"More","weight":14,"blockGap":"8","jsDoc":"Sets the minimum threshold for a loud sound","_def":{"parts":[{"kind":"label","text":"set loud sound threshold ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value","options":{"min":{"value":"1"},"max":{"value":"255"}}}],"pyQName":"input.set_loud_sound_threshold"}}},"sha":"f7bfb6ba5c6c1b1a75f42c7569fbfaf013a8c4c03221a11e0f6201bc3ce47358"},"libs/mixer":{"apis":{"byQName":{}},"sha":"342b9fd35af2339078aae907c9a57d213ca2d89efc39854f1b509dce5bebc52a"},"libs/mixer---ext":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}}}},"sha":"342b9fd35af2339078aae907c9a57d213ca2d89efc39854f1b509dce5bebc52a"},"libs/mixer---linux":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}}}},"sha":"4fcd1b8e77f31d99f82db375408ab35946dd952b49e224fd0691966f5af340a0"},"libs/mixer---none":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}}}},"sha":"342b9fd35af2339078aae907c9a57d213ca2d89efc39854f1b509dce5bebc52a"},"libs/mixer---nrf52":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}}}},"sha":"342b9fd35af2339078aae907c9a57d213ca2d89efc39854f1b509dce5bebc52a"},"libs/mixer---samd":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}}}},"sha":"342b9fd35af2339078aae907c9a57d213ca2d89efc39854f1b509dce5bebc52a"},"libs/mixer---stm32":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}}}},"sha":"342b9fd35af2339078aae907c9a57d213ca2d89efc39854f1b509dce5bebc52a"},"libs/mixer---rp2040":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}}}},"sha":"342b9fd35af2339078aae907c9a57d213ca2d89efc39854f1b509dce5bebc52a"},"libs/mouse":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"mouse":{"kind":5,"retType":"","attributes":{"icon":"","color":"#303030","jsDoc":"Mouse emulation"}},"mouse.setButton":{"kind":-3,"attributes":{"help":"mouse/set-button","blockId":"mouseSetButton","block":"mouse button %index|%down=toggleDownUp","jsDoc":"Set the mouse button state to up or down","_def":{"parts":[{"kind":"label","text":"mouse button ","style":[]},{"kind":"param","name":"index","ref":false},{"kind":"break"},{"kind":"param","name":"down","shadowBlockId":"toggleDownUp","ref":false}],"parameters":[{"kind":"param","name":"index","ref":false},{"kind":"param","name":"down","shadowBlockId":"toggleDownUp","ref":false}]}},"parameters":[{"name":"button","type":"MouseButton","isEnum":true},{"name":"down","type":"boolean"}],"pyQName":"mouse.set_button"},"mouse.move":{"kind":-3,"attributes":{"help":"mouse/move","blockId":"mouseMove","block":"mouse move x %x|y %y","paramMin":{"x":"-128","y":"-128"},"paramMax":{"x":"127","y":"127"},"jsDoc":"Move the mouse in the X and Y direction","_def":{"parts":[{"kind":"label","text":"mouse move x ","style":[]},{"kind":"param","name":"x","ref":false},{"kind":"break"},{"kind":"label","text":"y ","style":[]},{"kind":"param","name":"y","ref":false}],"parameters":[{"kind":"param","name":"x","ref":false},{"kind":"param","name":"y","ref":false}]}},"parameters":[{"name":"x","options":{"min":{"value":"-128"},"max":{"value":"127"}}},{"name":"y","options":{"min":{"value":"-128"},"max":{"value":"127"}}}]},"mouse.turnWheel":{"kind":-3,"attributes":{"help":"mouse/turn-wheel","blockId":"mouseWheel","block":"mouse turn wheel %w","paramMin":{"w":"-128"},"paramMax":{"w":"127"},"jsDoc":"Turn the mouse wheel","_def":{"parts":[{"kind":"label","text":"mouse turn wheel ","style":[]},{"kind":"param","name":"w","ref":false}],"parameters":[{"kind":"param","name":"w","ref":false}]}},"parameters":[{"name":"w","options":{"min":{"value":"-128"},"max":{"value":"127"}}}],"pyQName":"mouse.turn_wheel"},"MouseButton":{"kind":6,"retType":"MouseButton","extendsTypes":["MouseButton","Number"]},"MouseButton.Left":{"retType":"MouseButton.Left","attributes":{"block":"left","enumval":"1","_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"extendsTypes":["MouseButton.Left","Number"],"pyQName":"MouseButton.LEFT"},"MouseButton.Right":{"retType":"MouseButton.Right","attributes":{"block":"right","enumval":"2","_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"extendsTypes":["MouseButton.Right","Number"],"pyQName":"MouseButton.RIGHT"},"MouseButton.Middle":{"retType":"MouseButton.Middle","attributes":{"block":"middle","enumval":"4","_def":{"parts":[{"kind":"label","text":"middle","style":[]}],"parameters":[]}},"extendsTypes":["MouseButton.Middle","Number"],"pyQName":"MouseButton.MIDDLE"},"mouse.click":{"kind":-3,"attributes":{"help":"mouse/click","blockId":"mouseClick","block":"mouse click button $button","weight":100,"paramHelp":{"button":"the button to click"},"jsDoc":"Generates a mouse click","_def":{"parts":[{"kind":"label","text":"mouse click button ","style":[]},{"kind":"param","name":"button","ref":true}],"parameters":[{"kind":"param","name":"button","ref":true}]}},"parameters":[{"name":"button","description":"the button to click","type":"MouseButton","isEnum":true}]}}},"sha":"07a3c4583f41730b6702f60f3b0f6f00cdf3f3dda04b09c3d6cdf405700ac370"},"libs/mqtt":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"net":{"kind":5,"retType":"","attributes":{"weight":1,"advanced":true,"icon":"","color":"#8446cf","jsDoc":"Networking, WiFi, web requests"}},"net.ControllerEvent":{"kind":6,"retType":"net.ControllerEvent","extendsTypes":["net.ControllerEvent","Number"]},"net.ControllerEvent.NewScan":{"retType":"net.ControllerEvent.NewScan","extendsTypes":["net.ControllerEvent.NewScan","Number"],"pyQName":"net.ControllerEvent.NEW_SCAN"},"net.ControllerEvent.GotIP":{"retType":"net.ControllerEvent.GotIP","extendsTypes":["net.ControllerEvent.GotIP","Number"],"pyQName":"net.ControllerEvent.GOT_IP"},"net.ControllerEvent.LostIP":{"retType":"net.ControllerEvent.LostIP","extendsTypes":["net.ControllerEvent.LostIP","Number"],"pyQName":"net.ControllerEvent.LOST_IP"},"net.ControllerEvent.NoScannedNetworks":{"retType":"net.ControllerEvent.NoScannedNetworks","extendsTypes":["net.ControllerEvent.NoScannedNetworks","Number"],"pyQName":"net.ControllerEvent.NO_SCANNED_NETWORKS"},"net.ControllerEvent.NoKnownNetworks":{"retType":"net.ControllerEvent.NoKnownNetworks","extendsTypes":["net.ControllerEvent.NoKnownNetworks","Number"],"pyQName":"net.ControllerEvent.NO_KNOWN_NETWORKS"},"net.ControllerEvent.Connecting":{"retType":"net.ControllerEvent.Connecting","extendsTypes":["net.ControllerEvent.Connecting","Number"],"pyQName":"net.ControllerEvent.CONNECTING"},"net.ControllerEvent.ConnectionFailed":{"retType":"net.ControllerEvent.ConnectionFailed","extendsTypes":["net.ControllerEvent.ConnectionFailed","Number"],"pyQName":"net.ControllerEvent.CONNECTION_FAILED"},"net.ControllerEvent.LoginServerStarted":{"retType":"net.ControllerEvent.LoginServerStarted","extendsTypes":["net.ControllerEvent.LoginServerStarted","Number"],"pyQName":"net.ControllerEvent.LOGIN_SERVER_STARTED"},"net.Controller":{"kind":8,"retType":"net.Controller","extendsTypes":[]},"net.Controller.eventID":{"kind":2,"retType":"number","isInstance":true,"pyQName":"net.Controller.event_id"},"net.Controller.onConnectSSIDFailed":{"kind":2,"retType":"(ssid: string) => void","isInstance":true,"pyQName":"net.Controller.on_connect_ssid_failed"},"net.Controller.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"net.Controller.onEvent":{"kind":-1,"parameters":[{"name":"ev","type":"net.ControllerEvent","isEnum":true},{"name":"h","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Controller.on_event"},"net.Controller.scanNetworks":{"kind":-1,"retType":"net.AccessPoint[]","parameters":[],"isInstance":true,"pyQName":"net.Controller.scan_networks"},"net.Controller.startLoginServer":{"kind":-1,"parameters":[{"name":"hostName","type":"string"}],"isInstance":true,"pyQName":"net.Controller.start_login_server"},"net.Controller.isLoginServerEnabled":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"net.Controller.is_login_server_enabled"},"net.Controller.socket":{"kind":-1,"retType":"number","parameters":[],"isInstance":true},"net.Controller.socketConnect":{"kind":-1,"retType":"boolean","parameters":[{"name":"socket_num"},{"name":"dest","type":"string | Buffer"},{"name":"port"},{"name":"conn_mode","initializer":"TCP_MODE"}],"isInstance":true,"pyQName":"net.Controller.socket_connect"},"net.Controller.socketWrite":{"kind":-1,"parameters":[{"name":"socket_num"},{"name":"buffer","type":"Buffer"}],"isInstance":true,"pyQName":"net.Controller.socket_write"},"net.Controller.socketAvailable":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.socket_available"},"net.Controller.socketRead":{"kind":-1,"retType":"Buffer","parameters":[{"name":"socket_num"},{"name":"size"}],"isInstance":true,"pyQName":"net.Controller.socket_read"},"net.Controller.socketClose":{"kind":-1,"parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.socket_close"},"net.Controller.hostbyName":{"kind":-1,"retType":"Buffer","parameters":[{"name":"hostname","type":"string"}],"isInstance":true,"pyQName":"net.Controller.hostby_name"},"net.Controller.isIdle":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.is_idle"},"net.Controller.isConnected":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.is_connected"},"net.Controller.connectAP":{"kind":-1,"retType":"boolean","parameters":[{"name":"bssid","type":"string"},{"name":"password","type":"string"}],"isInstance":true,"pyQName":"net.Controller.connect_ap"},"net.Controller.disconnectAP":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"net.Controller.disconnect_ap"},"net.Controller.lastScanResults":{"kind":2,"retType":"net.AccessPoint[]","isInstance":true,"pyQName":"net.Controller.last_scan_results"},"net.Controller.autoconnect":{"kind":-1,"parameters":[],"isInstance":true},"net.Controller.disconnect":{"kind":-1,"parameters":[],"isInstance":true},"net.Controller.connect":{"kind":-1,"retType":"boolean","parameters":[{"name":"timeout_ms","initializer":"undefined"}],"isInstance":true},"net.Controller.ssid":{"kind":-2,"retType":"string","isInstance":true,"isReadOnly":true},"net.Controller.rssi":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"net.Controller.MACaddress":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.ma_caddress"},"net.Controller.IPaddress":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.ipaddress"},"net.Controller.ping":{"kind":-1,"retType":"number","parameters":[{"name":"dest","type":"string"},{"name":"ttl","initializer":"250"}],"isInstance":true},"net.Controller.dataAvailableSrc":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.data_available_src"},"net.Controller.dataAvailableValue":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.data_available_value"},"net.SOCK_STREAM":{"kind":4,"retType":"number"},"net.AF_INET":{"kind":4,"retType":"number"},"net.MAX_PACKET":{"kind":4,"retType":"number"},"net.TCP_MODE":{"kind":4,"retType":"number"},"net.UDP_MODE":{"kind":4,"retType":"number"},"net.TLS_MODE":{"kind":4,"retType":"number"},"net.ControllerSocket":{"kind":8,"retType":"net.ControllerSocket","extendsTypes":["net.ControllerSocket","net.Socket"]},"net.ControllerSocket._buffer":{"kind":2,"retType":"Buffer","isInstance":true},"net.ControllerSocket._socknum":{"kind":2,"retType":"number","isInstance":true},"net.ControllerSocket._timeout":{"kind":2,"retType":"number","isInstance":true},"net.ControllerSocket._closed":{"kind":2,"retType":"boolean","isInstance":true},"net.ControllerSocket._openHandler":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"net.ControllerSocket._open_handler"},"net.ControllerSocket._closeHandler":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"net.ControllerSocket._close_handler"},"net.ControllerSocket._errorHandler":{"kind":2,"retType":"(msg: string) => void","isInstance":true,"pyQName":"net.ControllerSocket._error_handler"},"net.ControllerSocket._messageHandler":{"kind":2,"retType":"(data: Buffer) => void","isInstance":true,"pyQName":"net.ControllerSocket._message_handler"},"net.ControllerSocket.__constructor":{"kind":-3,"attributes":{"jsDoc":"A simplified implementation of the Python 'socket' class, for connecting\nthrough an interface to a remote device"},"parameters":[{"name":"controller","type":"net.Controller"},{"name":"host","type":"string | Buffer"},{"name":"port"},{"name":"conntype","initializer":"null"}],"isInstance":true},"net.ControllerSocket.connect":{"kind":-1,"attributes":{"jsDoc":"Connect the socket to the 'address' (which can be 32bit packed IP or\na hostname string). 'conntype' is an extra that may indicate SSL or not,\ndepending on the underlying interface"},"parameters":[],"isInstance":true},"net.ControllerSocket.send":{"kind":-1,"attributes":{"jsDoc":"Send some data to the socket"},"parameters":[{"name":"data","type":"string | Buffer"}],"isInstance":true},"net.ControllerSocket.onOpen":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_open"},"net.ControllerSocket.onClose":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_close"},"net.ControllerSocket.onError":{"kind":-1,"parameters":[{"name":"handler","type":"(msg: string) => void","handlerParameters":[{"name":"msg","type":"string"}]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_error"},"net.ControllerSocket.onMessage":{"kind":-1,"parameters":[{"name":"handler","type":"(data: Buffer) => void","handlerParameters":[{"name":"data","type":"Buffer"}]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_message"},"net.ControllerSocket.readLine":{"kind":-1,"retType":"string","attributes":{"jsDoc":"Attempt to return as many bytes as we can up to but not including '\\r\\n'"},"parameters":[],"isInstance":true,"pyQName":"net.ControllerSocket.read_line"},"net.ControllerSocket.read":{"kind":-1,"retType":"Buffer","attributes":{"jsDoc":"Read up to 'size' bytes from the socket, this may be buffered internally! If 'size' isn't specified, return everything in the buffer."},"parameters":[{"name":"size","initializer":"0"}],"isInstance":true},"net.ControllerSocket.setTimeout":{"kind":-1,"attributes":{"jsDoc":"Set the read timeout for sockets, if value is 0 it will block"},"parameters":[{"name":"value"}],"isInstance":true,"pyQName":"net.ControllerSocket.set_timeout"},"net.ControllerSocket.close":{"kind":-1,"attributes":{"jsDoc":"Close the socket, after reading whatever remains"},"parameters":[],"isInstance":true},"net.logPriority":{"kind":4,"retType":"ConsolePriority","attributes":{"jsDoc":"Default priority of net log messages"},"pyQName":"net.log_priority"},"net.log":{"kind":-3,"parameters":[{"name":"msg","type":"string"}]},"net.debug":{"kind":-3,"parameters":[{"name":"msg","type":"string"}]},"net.fail":{"kind":-3,"parameters":[{"name":"reason","type":"string"}]},"net.monotonic":{"kind":-3,"retType":"number","parameters":[]},"net.WifiAPFlags":{"kind":6,"retType":"net.WifiAPFlags","extendsTypes":["net.WifiAPFlags","Number"]},"net.WifiAPFlags.HasPassword":{"retType":"net.WifiAPFlags.HasPassword","extendsTypes":["net.WifiAPFlags.HasPassword","Number"],"pyQName":"net.WifiAPFlags.HAS_PASSWORD"},"net.WifiAPFlags.WPS":{"retType":"net.WifiAPFlags.WPS","extendsTypes":["net.WifiAPFlags.WPS","Number"]},"net.WifiAPFlags.HasSecondaryChannelAbove":{"retType":"net.WifiAPFlags.HasSecondaryChannelAbove","extendsTypes":["net.WifiAPFlags.HasSecondaryChannelAbove","Number"],"pyQName":"net.WifiAPFlags.HAS_SECONDARY_CHANNEL_ABOVE"},"net.WifiAPFlags.HasSecondaryChannelBelow":{"retType":"net.WifiAPFlags.HasSecondaryChannelBelow","extendsTypes":["net.WifiAPFlags.HasSecondaryChannelBelow","Number"],"pyQName":"net.WifiAPFlags.HAS_SECONDARY_CHANNEL_BELOW"},"net.WifiAPFlags.IEEE_802_11B":{"retType":"net.WifiAPFlags.IEEE_802_11B","extendsTypes":["net.WifiAPFlags.IEEE_802_11B","Number"]},"net.WifiAPFlags.IEEE_802_11A":{"retType":"net.WifiAPFlags.IEEE_802_11A","extendsTypes":["net.WifiAPFlags.IEEE_802_11A","Number"]},"net.WifiAPFlags.IEEE_802_11G":{"retType":"net.WifiAPFlags.IEEE_802_11G","extendsTypes":["net.WifiAPFlags.IEEE_802_11G","Number"]},"net.WifiAPFlags.IEEE_802_11N":{"retType":"net.WifiAPFlags.IEEE_802_11N","extendsTypes":["net.WifiAPFlags.IEEE_802_11N","Number"]},"net.WifiAPFlags.IEEE_802_11AC":{"retType":"net.WifiAPFlags.IEEE_802_11AC","extendsTypes":["net.WifiAPFlags.IEEE_802_11AC","Number"]},"net.WifiAPFlags.IEEE_802_11AX":{"retType":"net.WifiAPFlags.IEEE_802_11AX","extendsTypes":["net.WifiAPFlags.IEEE_802_11AX","Number"]},"net.WifiAPFlags.IEEE_802_LongRange":{"retType":"net.WifiAPFlags.IEEE_802_LongRange","extendsTypes":["net.WifiAPFlags.IEEE_802_LongRange","Number"],"pyQName":"net.WifiAPFlags.IEEE_802_LONGRANGE"},"net.AccessPoint":{"kind":8,"retType":"net.AccessPoint","extendsTypes":[]},"net.AccessPoint.flags":{"kind":2,"retType":"net.WifiAPFlags","isInstance":true},"net.AccessPoint.rssi":{"kind":2,"retType":"number","isInstance":true},"net.AccessPoint.bssid":{"kind":2,"retType":"Buffer","isInstance":true},"net.AccessPoint.channel":{"kind":2,"retType":"number","isInstance":true},"net.AccessPoint.__constructor":{"kind":-3,"parameters":[{"name":"ssid","type":"string"}],"isInstance":true},"net.AccessPoint.fromBuffer":{"kind":-1,"retType":"net.AccessPoint","parameters":[{"name":"buf","type":"Buffer"}],"pyQName":"net.AccessPoint.from_buffer"},"net.AccessPoint.toBuffer":{"kind":-1,"retType":"Buffer","parameters":[],"isInstance":true,"pyQName":"net.AccessPoint.to_buffer"},"net.Socket":{"kind":9,"retType":"net.Socket","extendsTypes":["net.Socket"]},"net.Socket.connect":{"kind":-1,"parameters":[],"isInstance":true},"net.Socket.send":{"kind":-1,"parameters":[{"name":"data","type":"string | Buffer"}],"isInstance":true},"net.Socket.read":{"kind":-1,"retType":"Buffer","parameters":[{"name":"contentLength"}],"isInstance":true},"net.Socket.close":{"kind":-1,"parameters":[],"isInstance":true},"net.Socket.onOpen":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Socket.on_open"},"net.Socket.onClose":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Socket.on_close"},"net.Socket.onError":{"kind":-1,"parameters":[{"name":"handler","type":"(msg: string) => void","handlerParameters":[{"name":"msg","type":"string"}]}],"isInstance":true,"pyQName":"net.Socket.on_error"},"net.Socket.onMessage":{"kind":-1,"parameters":[{"name":"handler","type":"(data: Buffer) => void","handlerParameters":[{"name":"data","type":"Buffer"}]}],"isInstance":true,"pyQName":"net.Socket.on_message"},"net.Socket.setTimeout":{"kind":-1,"parameters":[{"name":"millis"}],"isInstance":true,"pyQName":"net.Socket.set_timeout"},"net.Socket.readLine":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"net.Socket.read_line"},"net.Net":{"kind":8,"retType":"net.Net","extendsTypes":[]},"net.Net.__constructor":{"kind":-3,"parameters":[{"name":"factory","type":"() => net.Controller","handlerParameters":[]}],"isInstance":true},"net.Net.instance":{"kind":2,"retType":"net.Net"},"net.Net.controller":{"kind":-2,"retType":"net.Controller","isInstance":true,"isReadOnly":true},"net.Net.scanNetworks":{"kind":-1,"retType":"net.AccessPoint[]","attributes":{"jsDoc":"Scan for APs"},"parameters":[],"isInstance":true,"pyQName":"net.Net.scan_networks"},"net.Net.createSocket":{"kind":-1,"retType":"net.Socket","parameters":[{"name":"host","type":"string"},{"name":"port"},{"name":"secure","type":"boolean"}],"isInstance":true,"pyQName":"net.Net.create_socket"},"net.Net.hostByName":{"kind":-1,"retType":"string","parameters":[{"name":"host","type":"string"}],"isInstance":true,"pyQName":"net.Net.host_by_name"},"net.instance":{"kind":-3,"retType":"net.Net","attributes":{"jsDoc":"Gets the current Net instance"},"parameters":[]},"net.knownAccessPoints":{"kind":-3,"retType":"StringMap","attributes":{"jsDoc":"Gets the map of SSID -> password pairs"},"parameters":[],"pyQName":"net.known_access_points"},"net.clearAccessPoint":{"kind":-3,"parameters":[{"name":"ssid","type":"string"}],"pyQName":"net.clear_access_point"},"net.updateAccessPoint":{"kind":-3,"parameters":[{"name":"ssid","type":"string"},{"name":"password","type":"string"}],"pyQName":"net.update_access_point"},"net.setAccessPointPriority":{"kind":-3,"parameters":[{"name":"ssid","type":"string"},{"name":"pri"}],"pyQName":"net.set_access_point_priority"},"net.accessPointPriorities":{"kind":-3,"retType":"any","parameters":[],"pyQName":"net.access_point_priorities"},"net.clearAccessPoints":{"kind":-3,"parameters":[],"pyQName":"net.clear_access_points"},"net.urlencode":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"}]},"net.urldecode":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"}]},"net.ping":{"kind":-3,"retType":"number","attributes":{"blockId":"netping","block":"net ping $dest","paramHelp":{"dest":"host name","ttl":""},"jsDoc":"Pings a web site","_def":{"parts":[{"kind":"label","text":"net ping ","style":[]},{"kind":"param","name":"dest","ref":true}],"parameters":[{"kind":"param","name":"dest","ref":true}]}},"parameters":[{"name":"dest","description":"host name","type":"string"},{"name":"ttl","initializer":"250"}]},"net.Response":{"kind":8,"retType":"net.Response","extendsTypes":[]},"net.Response._cached":{"kind":2,"retType":"Buffer","isInstance":true},"net.Response.status_code":{"kind":2,"retType":"number","isInstance":true},"net.Response.reason":{"kind":2,"retType":"string","isInstance":true},"net.Response._read_so_far":{"kind":2,"retType":"number","isInstance":true},"net.Response.headers":{"kind":2,"retType":"StringMap","isInstance":true},"net.Response.__constructor":{"kind":-3,"attributes":{"jsDoc":"The response from a request, contains all the headers/content"},"parameters":[{"name":"socket","type":"net.Socket"}],"isInstance":true},"net.Response.close":{"kind":-1,"attributes":{"jsDoc":"Close, delete and collect the response data"},"parameters":[],"isInstance":true},"net.Response.content":{"kind":-2,"retType":"Buffer","attributes":{"jsDoc":"The HTTP content direct from the socket, as bytes"},"isInstance":true,"isReadOnly":true},"net.Response.text":{"kind":-2,"retType":"string","attributes":{"jsDoc":"The HTTP content, encoded into a string according to the HTTP header encoding"},"isInstance":true,"isReadOnly":true},"net.Response.json":{"kind":-2,"retType":"any","isInstance":true,"isReadOnly":true},"net.Response.toString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"net.Response.to_string"},"net.RequestOptions":{"kind":9,"retType":"net.RequestOptions","extendsTypes":[]},"net.RequestOptions.data":{"kind":2,"retType":"string | Buffer","isInstance":true},"net.RequestOptions.json":{"kind":2,"retType":"any","isInstance":true},"net.RequestOptions.headers":{"kind":2,"retType":"StringMap","isInstance":true},"net.RequestOptions.stream":{"kind":2,"retType":"boolean","isInstance":true},"net.RequestOptions.timeout":{"kind":2,"retType":"number","isInstance":true},"net.dataAsBuffer":{"kind":-3,"retType":"Buffer","parameters":[{"name":"data","type":"string | Buffer"}],"pyQName":"net.data_as_buffer"},"net.request":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Perform an HTTP request to the given url which we will parse to determine\nwhether to use SSL ('https://') or not. We can also send some provided 'data'\nor a json dictionary which we will stringify. 'headers' is optional HTTP headers\nsent along. 'stream' will determine if we buffer everything, or whether to only\nread only when requested"},"parameters":[{"name":"method","type":"string"},{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.head":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP HEAD request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.get":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP GET request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.getString":{"kind":-3,"retType":"string","attributes":{"blockId":"netgetstring","block":"get string $url","jsDoc":"Send HTTP GET request and return text","_def":{"parts":[{"kind":"label","text":"get string ","style":[]},{"kind":"param","name":"url","ref":true}],"parameters":[{"kind":"param","name":"url","ref":true}]}},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}],"pyQName":"net.get_string"},"net.getJSON":{"kind":-3,"retType":"any","attributes":{"blockId":"netgetjson","block":"get json $url","jsDoc":"Send HTTP GET request and return JSON","_def":{"parts":[{"kind":"label","text":"get json ","style":[]},{"kind":"param","name":"url","ref":true}],"parameters":[{"kind":"param","name":"url","ref":true}]}},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}],"pyQName":"net.get_json"},"net.post":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP POST request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.patch":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP PATCH request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.put":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP PUT request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.del":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP DELETE request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"mqtt":{"kind":5,"retType":""},"mqtt.ConnectFlags":{"kind":6,"retType":"mqtt.ConnectFlags","attributes":{"jsDoc":"Connect flags\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc385349229"},"extendsTypes":["mqtt.ConnectFlags","Number"]},"mqtt.ConnectFlags.UserName":{"retType":"mqtt.ConnectFlags.UserName","extendsTypes":["mqtt.ConnectFlags.UserName","Number"],"pyQName":"mqtt.ConnectFlags.USER_NAME"},"mqtt.ConnectFlags.Password":{"retType":"mqtt.ConnectFlags.Password","extendsTypes":["mqtt.ConnectFlags.Password","Number"],"pyQName":"mqtt.ConnectFlags.PASSWORD"},"mqtt.ConnectFlags.WillRetain":{"retType":"mqtt.ConnectFlags.WillRetain","extendsTypes":["mqtt.ConnectFlags.WillRetain","Number"],"pyQName":"mqtt.ConnectFlags.WILL_RETAIN"},"mqtt.ConnectFlags.WillQoS2":{"retType":"mqtt.ConnectFlags.WillQoS2","extendsTypes":["mqtt.ConnectFlags.WillQoS2","Number"],"pyQName":"mqtt.ConnectFlags.WILL_QO_S2"},"mqtt.ConnectFlags.WillQoS1":{"retType":"mqtt.ConnectFlags.WillQoS1","extendsTypes":["mqtt.ConnectFlags.WillQoS1","Number"],"pyQName":"mqtt.ConnectFlags.WILL_QO_S1"},"mqtt.ConnectFlags.Will":{"retType":"mqtt.ConnectFlags.Will","extendsTypes":["mqtt.ConnectFlags.Will","Number"],"pyQName":"mqtt.ConnectFlags.WILL"},"mqtt.ConnectFlags.CleanSession":{"retType":"mqtt.ConnectFlags.CleanSession","extendsTypes":["mqtt.ConnectFlags.CleanSession","Number"],"pyQName":"mqtt.ConnectFlags.CLEAN_SESSION"},"mqtt.ConnectReturnCode":{"kind":6,"retType":"mqtt.ConnectReturnCode","attributes":{"jsDoc":"Connect Return code\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc385349256"},"extendsTypes":["mqtt.ConnectReturnCode","Number"]},"mqtt.ConnectReturnCode.Unknown":{"retType":"mqtt.ConnectReturnCode.Unknown","extendsTypes":["mqtt.ConnectReturnCode.Unknown","Number"],"pyQName":"mqtt.ConnectReturnCode.UNKNOWN"},"mqtt.ConnectReturnCode.Accepted":{"retType":"mqtt.ConnectReturnCode.Accepted","extendsTypes":["mqtt.ConnectReturnCode.Accepted","Number"],"pyQName":"mqtt.ConnectReturnCode.ACCEPTED"},"mqtt.ConnectReturnCode.UnacceptableProtocolVersion":{"retType":"mqtt.ConnectReturnCode.UnacceptableProtocolVersion","extendsTypes":["mqtt.ConnectReturnCode.UnacceptableProtocolVersion","Number"],"pyQName":"mqtt.ConnectReturnCode.UNACCEPTABLE_PROTOCOL_VERSION"},"mqtt.ConnectReturnCode.IdentifierRejected":{"retType":"mqtt.ConnectReturnCode.IdentifierRejected","extendsTypes":["mqtt.ConnectReturnCode.IdentifierRejected","Number"],"pyQName":"mqtt.ConnectReturnCode.IDENTIFIER_REJECTED"},"mqtt.ConnectReturnCode.ServerUnavailable":{"retType":"mqtt.ConnectReturnCode.ServerUnavailable","extendsTypes":["mqtt.ConnectReturnCode.ServerUnavailable","Number"],"pyQName":"mqtt.ConnectReturnCode.SERVER_UNAVAILABLE"},"mqtt.ConnectReturnCode.BadUserNameOrPassword":{"retType":"mqtt.ConnectReturnCode.BadUserNameOrPassword","extendsTypes":["mqtt.ConnectReturnCode.BadUserNameOrPassword","Number"],"pyQName":"mqtt.ConnectReturnCode.BAD_USER_NAME_OR_PASSWORD"},"mqtt.ConnectReturnCode.NotAuthorized":{"retType":"mqtt.ConnectReturnCode.NotAuthorized","extendsTypes":["mqtt.ConnectReturnCode.NotAuthorized","Number"],"pyQName":"mqtt.ConnectReturnCode.NOT_AUTHORIZED"},"mqtt.IMessage":{"kind":9,"retType":"mqtt.IMessage","attributes":{"jsDoc":"A message received in a Publish packet."},"extendsTypes":[]},"mqtt.IMessage.pid":{"kind":2,"retType":"number","isInstance":true},"mqtt.IMessage.topic":{"kind":2,"retType":"string","isInstance":true},"mqtt.IMessage.content":{"kind":2,"retType":"Buffer","isInstance":true},"mqtt.IMessage.qos":{"kind":2,"retType":"number","isInstance":true},"mqtt.IMessage.retain":{"kind":2,"retType":"number","isInstance":true},"mqtt.ControlPacketType":{"kind":6,"retType":"mqtt.ControlPacketType","attributes":{"jsDoc":"MQTT Control Packet type\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc353481061"},"extendsTypes":["mqtt.ControlPacketType","Number"]},"mqtt.ControlPacketType.Connect":{"retType":"mqtt.ControlPacketType.Connect","extendsTypes":["mqtt.ControlPacketType.Connect","Number"],"pyQName":"mqtt.ControlPacketType.CONNECT"},"mqtt.ControlPacketType.ConnAck":{"retType":"mqtt.ControlPacketType.ConnAck","extendsTypes":["mqtt.ControlPacketType.ConnAck","Number"],"pyQName":"mqtt.ControlPacketType.CONN_ACK"},"mqtt.ControlPacketType.Publish":{"retType":"mqtt.ControlPacketType.Publish","extendsTypes":["mqtt.ControlPacketType.Publish","Number"],"pyQName":"mqtt.ControlPacketType.PUBLISH"},"mqtt.ControlPacketType.PubAck":{"retType":"mqtt.ControlPacketType.PubAck","extendsTypes":["mqtt.ControlPacketType.PubAck","Number"],"pyQName":"mqtt.ControlPacketType.PUB_ACK"},"mqtt.ControlPacketType.Subscribe":{"retType":"mqtt.ControlPacketType.Subscribe","extendsTypes":["mqtt.ControlPacketType.Subscribe","Number"],"pyQName":"mqtt.ControlPacketType.SUBSCRIBE"},"mqtt.ControlPacketType.SubAck":{"retType":"mqtt.ControlPacketType.SubAck","extendsTypes":["mqtt.ControlPacketType.SubAck","Number"],"pyQName":"mqtt.ControlPacketType.SUB_ACK"},"mqtt.ControlPacketType.Unsubscribe":{"retType":"mqtt.ControlPacketType.Unsubscribe","extendsTypes":["mqtt.ControlPacketType.Unsubscribe","Number"],"pyQName":"mqtt.ControlPacketType.UNSUBSCRIBE"},"mqtt.ControlPacketType.UnsubAck":{"retType":"mqtt.ControlPacketType.UnsubAck","extendsTypes":["mqtt.ControlPacketType.UnsubAck","Number"],"pyQName":"mqtt.ControlPacketType.UNSUB_ACK"},"mqtt.ControlPacketType.PingReq":{"retType":"mqtt.ControlPacketType.PingReq","extendsTypes":["mqtt.ControlPacketType.PingReq","Number"],"pyQName":"mqtt.ControlPacketType.PING_REQ"},"mqtt.ControlPacketType.PingResp":{"retType":"mqtt.ControlPacketType.PingResp","extendsTypes":["mqtt.ControlPacketType.PingResp","Number"],"pyQName":"mqtt.ControlPacketType.PING_RESP"},"mqtt.ControlPacketType.Disconnect":{"retType":"mqtt.ControlPacketType.Disconnect","extendsTypes":["mqtt.ControlPacketType.Disconnect","Number"],"pyQName":"mqtt.ControlPacketType.DISCONNECT"},"mqtt.Constants":{"kind":6,"retType":"mqtt.Constants","attributes":{"jsDoc":"Optimization, the TypeScript compiler replaces the constant enums."},"extendsTypes":["mqtt.Constants","Number"]},"mqtt.Constants.PingInterval":{"retType":"mqtt.Constants.PingInterval","extendsTypes":["mqtt.Constants.PingInterval","Number"],"pyQName":"mqtt.Constants.PING_INTERVAL"},"mqtt.Constants.WatchDogInterval":{"retType":"mqtt.Constants.WatchDogInterval","extendsTypes":["mqtt.Constants.WatchDogInterval","Number"],"pyQName":"mqtt.Constants.WATCH_DOG_INTERVAL"},"mqtt.Constants.DefaultQos":{"retType":"mqtt.Constants.DefaultQos","extendsTypes":["mqtt.Constants.DefaultQos","Number"],"pyQName":"mqtt.Constants.DEFAULT_QOS"},"mqtt.Constants.Uninitialized":{"retType":"mqtt.Constants.Uninitialized","extendsTypes":["mqtt.Constants.Uninitialized","Number"],"pyQName":"mqtt.Constants.UNINITIALIZED"},"mqtt.Constants.FixedPackedId":{"retType":"mqtt.Constants.FixedPackedId","extendsTypes":["mqtt.Constants.FixedPackedId","Number"],"pyQName":"mqtt.Constants.FIXED_PACKED_ID"},"mqtt.Constants.KeepAlive":{"retType":"mqtt.Constants.KeepAlive","extendsTypes":["mqtt.Constants.KeepAlive","Number"],"pyQName":"mqtt.Constants.KEEP_ALIVE"},"mqtt.IConnectionOptions":{"kind":9,"retType":"mqtt.IConnectionOptions","attributes":{"jsDoc":"The options used to connect to the MQTT broker."},"extendsTypes":[]},"mqtt.IConnectionOptions.host":{"kind":2,"retType":"string","isInstance":true},"mqtt.IConnectionOptions.port":{"kind":2,"retType":"number","isInstance":true},"mqtt.IConnectionOptions.username":{"kind":2,"retType":"string","isInstance":true},"mqtt.IConnectionOptions.password":{"kind":2,"retType":"string","isInstance":true},"mqtt.IConnectionOptions.clientId":{"kind":2,"retType":"string","isInstance":true,"pyQName":"mqtt.IConnectionOptions.client_id"},"mqtt.IConnectionOptions.will":{"kind":2,"retType":"mqtt.IConnectionOptionsWill","isInstance":true},"mqtt.IConnectionOptionsWill":{"kind":9,"retType":"mqtt.IConnectionOptionsWill","extendsTypes":[]},"mqtt.IConnectionOptionsWill.topic":{"kind":2,"retType":"string","isInstance":true},"mqtt.IConnectionOptionsWill.message":{"kind":2,"retType":"string","isInstance":true},"mqtt.IConnectionOptionsWill.qos":{"kind":2,"retType":"number","isInstance":true},"mqtt.IConnectionOptionsWill.retain":{"kind":2,"retType":"boolean","isInstance":true},"mqtt.Protocol":{"kind":5,"retType":"","attributes":{"jsDoc":"The specifics of the MQTT protocol."}},"mqtt.Protocol.createConnect":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"CONNECT - Client requests a connection to a Server\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718028"},"parameters":[{"name":"options","type":"mqtt.IConnectionOptions"}],"pyQName":"mqtt.Protocol.create_connect"},"mqtt.Protocol.createPingReq":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"PINGREQ - PING request\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800454"},"parameters":[],"pyQName":"mqtt.Protocol.create_ping_req"},"mqtt.Protocol.createPublishHeader":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"PUBLISH - Publish message header - doesn't include \"payload\"\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800410"},"parameters":[{"name":"topic","type":"string"},{"name":"payloadSize"},{"name":"qos"},{"name":"retained","type":"boolean"}],"pyQName":"mqtt.Protocol.create_publish_header"},"mqtt.Protocol.parsePublish":{"kind":-3,"retType":"mqtt.IMessage","parameters":[{"name":"cmd"},{"name":"payload","type":"Buffer"}],"pyQName":"mqtt.Protocol.parse_publish"},"mqtt.Protocol.createPubAck":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"PUBACK - Publish acknowledgement\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800416"},"parameters":[{"name":"pid"}],"pyQName":"mqtt.Protocol.create_pub_ack"},"mqtt.Protocol.createSubscribe":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"SUBSCRIBE - Subscribe to topics\nhttp://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800436"},"parameters":[{"name":"topic","type":"string"},{"name":"qos"}],"pyQName":"mqtt.Protocol.create_subscribe"},"mqtt.EventEmitter":{"kind":8,"retType":"mqtt.EventEmitter","extendsTypes":["mqtt.EventEmitter"]},"mqtt.EventEmitter.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"mqtt.EventEmitter.on":{"kind":-1,"parameters":[{"name":"event","type":"string"},{"name":"listener","type":"mqtt.EventHandler"}],"isInstance":true},"mqtt.Status":{"kind":6,"retType":"mqtt.Status","extendsTypes":["mqtt.Status","Number"]},"mqtt.Status.Disconnected":{"retType":"mqtt.Status.Disconnected","extendsTypes":["mqtt.Status.Disconnected","Number"],"pyQName":"mqtt.Status.DISCONNECTED"},"mqtt.Status.Connecting":{"retType":"mqtt.Status.Connecting","extendsTypes":["mqtt.Status.Connecting","Number"],"pyQName":"mqtt.Status.CONNECTING"},"mqtt.Status.Connected":{"retType":"mqtt.Status.Connected","extendsTypes":["mqtt.Status.Connected","Number"],"pyQName":"mqtt.Status.CONNECTED"},"mqtt.Status.Sending":{"retType":"mqtt.Status.Sending","extendsTypes":["mqtt.Status.Sending","Number"],"pyQName":"mqtt.Status.SENDING"},"mqtt.Client":{"kind":8,"retType":"mqtt.Client","extendsTypes":["mqtt.Client","mqtt.EventEmitter"]},"mqtt.Client.logPriority":{"kind":2,"retType":"ConsolePriority","isInstance":true,"pyQName":"mqtt.Client.log_priority"},"mqtt.Client.tracePriority":{"kind":2,"retType":"ConsolePriority","isInstance":true,"pyQName":"mqtt.Client.trace_priority"},"mqtt.Client.opt":{"kind":2,"retType":"mqtt.IConnectionOptions","isInstance":true},"mqtt.Client.status":{"kind":2,"retType":"mqtt.Status","isInstance":true},"mqtt.Client.connected":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true},"mqtt.Client.__constructor":{"kind":-3,"parameters":[{"name":"opt","type":"mqtt.IConnectionOptions"}],"isInstance":true},"mqtt.Client.disconnect":{"kind":-1,"parameters":[],"isInstance":true},"mqtt.Client.connect":{"kind":-1,"parameters":[],"isInstance":true},"mqtt.Client.publish":{"kind":-1,"parameters":[{"name":"topic","type":"string"},{"name":"message","type":"string | Buffer","initializer":"undefined"},{"name":"qos","initializer":"Constants.DefaultQos"},{"name":"retained","type":"boolean","initializer":"false"}],"isInstance":true},"mqtt.Client.startPublish":{"kind":-1,"retType":"boolean","parameters":[{"name":"topic","type":"string"},{"name":"messageLen"},{"name":"qos","initializer":"Constants.DefaultQos"},{"name":"retained","type":"boolean","initializer":"false"}],"isInstance":true,"pyQName":"mqtt.Client.start_publish"},"mqtt.Client.continuePublish":{"kind":-1,"parameters":[{"name":"data","type":"Buffer"}],"isInstance":true,"pyQName":"mqtt.Client.continue_publish"},"mqtt.Client.finishPublish":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"mqtt.Client.finish_publish"},"mqtt.Client.subscribe":{"kind":-1,"parameters":[{"name":"topic","type":"string"},{"name":"handler","type":"(msg: mqtt.IMessage) => void","initializer":"undefined","handlerParameters":[{"name":"msg","type":"mqtt.IMessage"}]},{"name":"qos","initializer":"Constants.DefaultQos"}],"isInstance":true},"mqtt.Client.awaitUpdate":{"kind":-1,"retType":"() => mqtt.IMessage","parameters":[{"name":"topic","type":"string"},{"name":"qos","initializer":"Constants.DefaultQos"}],"isInstance":true,"pyQName":"mqtt.Client.await_update"}}},"sha":"bdf12d96d9984bbf157985acf0304062c4f1a44b72bb2065db7eef0c8cf4c601"},"libs/multiplayer":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"mp":{"kind":5,"retType":"","attributes":{"color":"#207a77","weight":96,"icon":"","blockGap":"8","block":"Multiplayer","groups":["Player","Controller","Info","Game","Utility"],"_def":{"parts":[{"kind":"label","text":"Multiplayer","style":[]}],"parameters":[]}}},"mp._multiplayerState":{"kind":-3,"retType":"number","attributes":{"shim":"KIND_GET","blockId":"mp_multiplayerstate","block":"$kind","kindNamespace":"MultiplayerState","kindMemberName":"value","kindPromptHint":"e.g. Cooldown, Speed, Attack...","blockHidden":true,"help":"multiplayer/multiplayer-state","jsDoc":"A type of state to get for a player","_def":{"parts":[{"kind":"param","name":"kind","ref":true}],"parameters":[{"kind":"param","name":"kind","ref":true}]}},"parameters":[{"name":"kind"}],"pyQName":"mp._multiplayer_state"},"mp._indicatorForPlayer":{"kind":-3,"retType":"Image","parameters":[{"name":"player"},{"name":"direction"}],"pyQName":"mp._indicator_for_player"},"mp.PlayerNumber":{"kind":6,"retType":"mp.PlayerNumber","extendsTypes":["mp.PlayerNumber","Number"]},"mp.PlayerNumber.One":{"retType":"mp.PlayerNumber.One","attributes":{"block":"1","_def":{"parts":[{"kind":"label","text":"1","style":[]}],"parameters":[]}},"extendsTypes":["mp.PlayerNumber.One","Number"],"pyQName":"mp.PlayerNumber.ONE"},"mp.PlayerNumber.Two":{"retType":"mp.PlayerNumber.Two","attributes":{"block":"2","_def":{"parts":[{"kind":"label","text":"2","style":[]}],"parameters":[]}},"extendsTypes":["mp.PlayerNumber.Two","Number"],"pyQName":"mp.PlayerNumber.TWO"},"mp.PlayerNumber.Three":{"retType":"mp.PlayerNumber.Three","attributes":{"block":"3","_def":{"parts":[{"kind":"label","text":"3","style":[]}],"parameters":[]}},"extendsTypes":["mp.PlayerNumber.Three","Number"],"pyQName":"mp.PlayerNumber.THREE"},"mp.PlayerNumber.Four":{"retType":"mp.PlayerNumber.Four","attributes":{"block":"4","_def":{"parts":[{"kind":"label","text":"4","style":[]}],"parameters":[]}},"extendsTypes":["mp.PlayerNumber.Four","Number"],"pyQName":"mp.PlayerNumber.FOUR"},"mp.PlayerProperty":{"kind":6,"retType":"mp.PlayerProperty","extendsTypes":["mp.PlayerProperty","Number"]},"mp.PlayerProperty.Index":{"retType":"mp.PlayerProperty.Index","attributes":{"block":"index","_def":{"parts":[{"kind":"label","text":"index","style":[]}],"parameters":[]}},"extendsTypes":["mp.PlayerProperty.Index","Number"],"pyQName":"mp.PlayerProperty.INDEX"},"mp.PlayerProperty.Number":{"retType":"mp.PlayerProperty.Number","attributes":{"block":"number","_def":{"parts":[{"kind":"label","text":"number","style":[]}],"parameters":[]}},"extendsTypes":["mp.PlayerProperty.Number","Number"],"pyQName":"mp.PlayerProperty.NUMBER"},"mp.MultiplayerButton":{"kind":6,"retType":"mp.MultiplayerButton","extendsTypes":["mp.MultiplayerButton","Number"]},"mp.MultiplayerButton.A":{"retType":"mp.MultiplayerButton.A","attributes":{"block":"A","_def":{"parts":[{"kind":"label","text":"A","style":[]}],"parameters":[]}},"extendsTypes":["mp.MultiplayerButton.A","Number"]},"mp.MultiplayerButton.B":{"retType":"mp.MultiplayerButton.B","attributes":{"block":"B","_def":{"parts":[{"kind":"label","text":"B","style":[]}],"parameters":[]}},"extendsTypes":["mp.MultiplayerButton.B","Number"]},"mp.MultiplayerButton.Up":{"retType":"mp.MultiplayerButton.Up","attributes":{"block":"up","_def":{"parts":[{"kind":"label","text":"up","style":[]}],"parameters":[]}},"extendsTypes":["mp.MultiplayerButton.Up","Number"],"pyQName":"mp.MultiplayerButton.UP"},"mp.MultiplayerButton.Right":{"retType":"mp.MultiplayerButton.Right","attributes":{"block":"right","_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"extendsTypes":["mp.MultiplayerButton.Right","Number"],"pyQName":"mp.MultiplayerButton.RIGHT"},"mp.MultiplayerButton.Down":{"retType":"mp.MultiplayerButton.Down","attributes":{"block":"down","_def":{"parts":[{"kind":"label","text":"down","style":[]}],"parameters":[]}},"extendsTypes":["mp.MultiplayerButton.Down","Number"],"pyQName":"mp.MultiplayerButton.DOWN"},"mp.MultiplayerButton.Left":{"retType":"mp.MultiplayerButton.Left","attributes":{"block":"left","_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"extendsTypes":["mp.MultiplayerButton.Left","Number"],"pyQName":"mp.MultiplayerButton.LEFT"},"mp.Player":{"kind":8,"retType":"mp.Player","attributes":{"jsDoc":"A player in the game"},"extendsTypes":[]},"mp.Player._sprite":{"kind":2,"retType":"Sprite","isInstance":true},"mp.Player._state":{"kind":2,"retType":"StateEntry[]","isInstance":true},"mp.Player._index":{"kind":2,"retType":"number","isInstance":true},"mp.Player._data":{"kind":2,"retType":"any","isInstance":true},"mp.Player._mwb":{"kind":2,"retType":"boolean","isInstance":true},"mp.Player._vx":{"kind":2,"retType":"number","isInstance":true},"mp.Player._vy":{"kind":2,"retType":"number","isInstance":true},"mp.Player.__constructor":{"kind":-3,"parameters":[{"name":"index"}],"isInstance":true},"mp.Player.index":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"mp.Player.number":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"mp.Player.data":{"kind":-2,"retType":"any","isInstance":true,"isReadOnly":true},"mp.Player.data@set":{"kind":-2,"retType":"any","isInstance":true},"mp.Player.getProperty":{"kind":-1,"retType":"number","parameters":[{"name":"prop","type":"mp.PlayerProperty","isEnum":true}],"isInstance":true,"pyQName":"mp.Player.get_property"},"mp.Player.getSprite":{"kind":-1,"retType":"Sprite","parameters":[],"isInstance":true,"pyQName":"mp.Player.get_sprite"},"mp.Player.setSprite":{"kind":-1,"parameters":[{"name":"sprite","type":"Sprite"}],"isInstance":true,"pyQName":"mp.Player.set_sprite"},"mp.Player.moveWithButtons":{"kind":-1,"parameters":[{"name":"vx","initializer":"undefined"},{"name":"vy","initializer":"undefined"}],"isInstance":true,"pyQName":"mp.Player.move_with_buttons"},"mp.Player.getState":{"kind":-1,"retType":"number","parameters":[{"name":"key"}],"isInstance":true,"pyQName":"mp.Player.get_state"},"mp.Player.setState":{"kind":-1,"parameters":[{"name":"key"},{"name":"val"}],"isInstance":true,"pyQName":"mp.Player.set_state"},"mp.Player._setState":{"kind":-1,"parameters":[{"name":"key"},{"name":"val"}],"isInstance":true,"pyQName":"mp.Player._set_state"},"mp.Player._getState":{"kind":-1,"retType":"number","parameters":[{"name":"key"}],"isInstance":true,"pyQName":"mp.Player._get_state"},"mp.Player._getInfo":{"kind":-1,"retType":"info.PlayerInfo","parameters":[],"isInstance":true,"pyQName":"mp.Player._get_info"},"mp.Player._getController":{"kind":-1,"retType":"controller.Controller","parameters":[],"isInstance":true,"pyQName":"mp.Player._get_controller"},"mp.Player._lookupOrCreateState":{"kind":-1,"retType":"StateEntry","parameters":[{"name":"key"}],"isInstance":true,"pyQName":"mp.Player._lookup_or_create_state"},"mp._mpstate":{"kind":-3,"retType":"MPState","parameters":[]},"mp.getPlayerSprite":{"kind":-3,"retType":"Sprite","attributes":{"blockId":"mp_getPlayerSprite","block":"$player sprite","_shadowOverrides":{"player":"mp_playerSelector"},"group":"Player","weight":80,"blockGap":"8","help":"multiplayer/get-player-sprite","parts":"multiplayer","paramHelp":{"player":"The player to get the sprite of"},"jsDoc":"Gets the sprite of the player\n\n@returns The sprite of the player, or undefined if the player has no assigned sprite","_def":{"parts":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"label","text":" sprite","style":[]}],"parameters":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true}]}},"parameters":[{"name":"player","description":"The player to get the sprite of","type":"mp.Player"}],"pyQName":"mp.get_player_sprite"},"mp.setPlayerSprite":{"kind":-3,"attributes":{"blockId":"mp_setPlayerSprite","block":"set $player sprite to $sprite","_shadowOverrides":{"player":"mp_playerSelector","sprite":"spritescreatenoset"},"group":"Player","weight":120,"blockGap":"8","help":"multiplayer/set-player-sprite","parts":"multiplayer","paramHelp":{"player":"The player to set the sprite for","sprite":"The sprite to set"},"jsDoc":"Sets the sprite of the player","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"label","text":" sprite to ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"spritescreatenoset","ref":true}],"parameters":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"param","name":"sprite","shadowBlockId":"spritescreatenoset","ref":true}]}},"parameters":[{"name":"player","description":"The player to set the sprite for","type":"mp.Player"},{"name":"sprite","description":"The sprite to set","type":"Sprite"}],"pyQName":"mp.set_player_sprite"},"mp.playerSelector":{"kind":-3,"retType":"mp.Player","attributes":{"blockId":"mp_playerSelector","block":"player $number","group":"Player","weight":100,"blockGap":"8","help":"multiplayer/player-selector","parts":"multiplayer","paramHelp":{"number":"The player number"},"jsDoc":"Selects one of the players by number\n\n@returns The player","_def":{"parts":[{"kind":"label","text":"player ","style":[]},{"kind":"param","name":"number","ref":true}],"parameters":[{"kind":"param","name":"number","ref":true}]}},"parameters":[{"name":"number","description":"The player number","type":"mp.PlayerNumber","isEnum":true}],"pyQName":"mp.player_selector"},"mp.allPlayers":{"kind":-3,"retType":"mp.Player[]","attributes":{"blockId":"mp_allPlayers","block":"array of all players","group":"Player","weight":90,"blockGap":"8","help":"multiplayer/get-all-players","parts":"multiplayer","jsDoc":"Returns an array of all players","_def":{"parts":[{"kind":"label","text":"array of all players","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"mp.all_players"},"mp.getPlayerBySprite":{"kind":-3,"retType":"mp.Player","attributes":{"paramDefl":{"sprite":"mySprite"},"blockId":"mp_getPlayerBySprite","block":"$sprite player","_shadowOverrides":{"sprite":"variables_get"},"explicitDefaults":["sprite"],"group":"Player","weight":70,"blockGap":"8","help":"multiplayer/get-player-by-sprite","parts":"multiplayer","paramHelp":{"sprite":"the sprite"},"jsDoc":"Gets the player the sprite is assigned to\n\n@returns Player, or undefined if not found","_def":{"parts":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true},{"kind":"label","text":" player","style":[]}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true}]}},"parameters":[{"name":"sprite","description":"the sprite","type":"Sprite","initializer":"mySprite","default":"mySprite"}],"pyQName":"mp.get_player_by_sprite"},"mp.moveWithButtons":{"kind":-3,"attributes":{"paramDefl":{"vx":"100","vy":"100"},"blockId":"mp_moveWithButtons","block":"move $player with buttons||vx $vx vy $vy","_shadowOverrides":{"player":"mp_playerSelector","vx":"spriteSpeedPicker","vy":"spriteSpeedPicker"},"explicitDefaults":["vx","vy"],"expandableArgumentMode":"toggle","inlineInputMode":"inline","group":"Controller","weight":100,"blockGap":"8","help":"multiplayer/move-with-buttons","parts":"multiplayer","paramHelp":{"player":"The player to control","vx":"The horizontal velocity of the sprite (optional)","vy":"The vertical velocity of the sprite (optional)"},"jsDoc":"Control a player's sprite with directional buttons","_def":{"parts":[{"kind":"label","text":"move ","style":[]},{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"label","text":" with buttons","style":[]}],"parameters":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true}]},"_expandedDef":{"parts":[{"kind":"label","text":"vx ","style":[]},{"kind":"param","name":"vx","shadowBlockId":"spriteSpeedPicker","ref":true},{"kind":"label","text":" vy ","style":[]},{"kind":"param","name":"vy","shadowBlockId":"spriteSpeedPicker","ref":true}],"parameters":[{"kind":"param","name":"vx","shadowBlockId":"spriteSpeedPicker","ref":true},{"kind":"param","name":"vy","shadowBlockId":"spriteSpeedPicker","ref":true}]}},"parameters":[{"name":"player","description":"The player to control","type":"mp.Player"},{"name":"vx","description":"The horizontal velocity of the sprite (optional)","initializer":"100","default":"100"},{"name":"vy","description":"The vertical velocity of the sprite (optional)","initializer":"100","default":"100"}],"pyQName":"mp.move_with_buttons"},"mp.onButtonEvent":{"kind":-3,"attributes":{"blockId":"mp_onButtonEvent","block":"on $button button $event for $player","draggableParameters":"reporter","group":"Controller","weight":90,"blockGap":"8","help":"multiplayer/on-button-event","parts":"multiplayer","paramHelp":{"button":"The button to listen for","event":"The event to listen for (pressed, released, or held)","handler":"The code to run when the button is pressed, released, or held"},"jsDoc":"Runs code when a button on any controller is pressed, released, or held","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"button","ref":true},{"kind":"label","text":" button ","style":[]},{"kind":"param","name":"event","ref":true},{"kind":"label","text":" for ","style":[]},{"kind":"param","name":"player","ref":true}],"parameters":[{"kind":"param","name":"button","ref":true},{"kind":"param","name":"event","ref":true},{"kind":"param","name":"player","ref":true}]}},"parameters":[{"name":"button","description":"The button to listen for","type":"mp.MultiplayerButton","isEnum":true},{"name":"event","description":"The event to listen for (pressed, released, or held)","type":"ControllerButtonEvent","isEnum":true},{"name":"handler","description":"The code to run when the button is pressed, released, or held","type":"(player: mp.Player) => void","handlerParameters":[{"name":"player","type":"mp.Player"}]}],"pyQName":"mp.on_button_event"},"mp.isButtonPressed":{"kind":-3,"retType":"boolean","attributes":{"blockId":"mp_isButtonPressed","block":"is $player $button button pressed","_shadowOverrides":{"player":"mp_playerSelector"},"group":"Controller","weight":80,"blockGap":"8","help":"multiplayer/is-button-pressed","parts":"multiplayer","paramHelp":{"player":"The player to query","button":"The button to query"},"jsDoc":"Queries the state of a button on a controller\n\n\n@returns true if the button is pressed","_def":{"parts":[{"kind":"label","text":"is ","style":[]},{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"button","ref":true},{"kind":"label","text":" button pressed","style":[]}],"parameters":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"param","name":"button","ref":true}]}},"parameters":[{"name":"player","description":"The player to query","type":"mp.Player"},{"name":"button","description":"The button to query","type":"mp.MultiplayerButton","isEnum":true}],"pyQName":"mp.is_button_pressed"},"mp.onControllerEvent":{"kind":-3,"attributes":{"blockId":"mp_onControllerEvent","block":"on $player $event","draggableParameters":"reporter","group":"Controller","weight":70,"blockGap":"8","help":"multiplayer/on-controller-event","parts":"multiplayer","paramHelp":{"event":"The event to listen for (controller connected or disconnected)","handler":"Code to run when the event is raised"},"jsDoc":"Runs code when a controller is connected or disconnected","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"player","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"event","ref":true}],"parameters":[{"kind":"param","name":"player","ref":true},{"kind":"param","name":"event","ref":true}]}},"parameters":[{"name":"event","description":"The event to listen for (controller connected or disconnected)","type":"ControllerEvent","isEnum":true},{"name":"handler","description":"Code to run when the event is raised","type":"(player: mp.Player) => void","handlerParameters":[{"name":"player","type":"mp.Player"}]}],"pyQName":"mp.on_controller_event"},"mp.isConnected":{"kind":-3,"retType":"boolean","attributes":{"blockId":"mp_isConnected","block":"$player connected","_shadowOverrides":{"player":"mp_playerSelector"},"group":"Controller","weight":60,"blockGap":"8","help":"multiplayer/is-connected","parts":"multiplayer","paramHelp":{"player":"The player to query"},"jsDoc":"Queries the connected state of the player\n\n@returns true if the player is connected","_def":{"parts":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"label","text":" connected","style":[]}],"parameters":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true}]}},"parameters":[{"name":"player","description":"The player to query","type":"mp.Player"}],"pyQName":"mp.is_connected"},"mp.getPlayerState":{"kind":-3,"retType":"number","attributes":{"blockId":"mp_getPlayerState","block":"$player $state","_shadowOverrides":{"player":"mp_playerSelector","state":"mp_multiplayerstate"},"group":"Info","weight":100,"blockGap":"8","help":"multiplayer/get-player-state","parts":"multiplayer","paramHelp":{"player":"The player to get the state for","state":"The state to get"},"jsDoc":"Gets the value of the specified player state\n\n\n@returns The value of the state","_def":{"parts":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"state","shadowBlockId":"mp_multiplayerstate","ref":true}],"parameters":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"param","name":"state","shadowBlockId":"mp_multiplayerstate","ref":true}]}},"parameters":[{"name":"player","description":"The player to get the state for","type":"mp.Player"},{"name":"state","description":"The state to get"}],"pyQName":"mp.get_player_state"},"mp.setPlayerState":{"kind":-3,"attributes":{"blockId":"mp_setPlayerState","block":"set $player $state to $value","_shadowOverrides":{"player":"mp_playerSelector","state":"mp_multiplayerstate"},"group":"Info","weight":90,"blockGap":"8","help":"multiplayer/set-player-state","parts":"multiplayer","paramHelp":{"player":"The player to set the state for","state":"The state to set","value":"The value to set the state to"},"jsDoc":"Sets the value of the specified player state","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"state","shadowBlockId":"mp_multiplayerstate","ref":true},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"value","ref":true}],"parameters":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"param","name":"state","shadowBlockId":"mp_multiplayerstate","ref":true},{"kind":"param","name":"value","ref":true}]}},"parameters":[{"name":"player","description":"The player to set the state for","type":"mp.Player"},{"name":"state","description":"The state to set"},{"name":"value","description":"The value to set the state to"}],"pyQName":"mp.set_player_state"},"mp.changePlayerStateBy":{"kind":-3,"attributes":{"paramDefl":{"delta":"1"},"blockId":"mp_changePlayerStateBy","block":"change $player $state by $delta","_shadowOverrides":{"player":"mp_playerSelector","state":"mp_multiplayerstate"},"explicitDefaults":["delta"],"group":"Info","weight":80,"blockGap":"8","help":"multiplayer/change-player-state-by","parts":"multiplayer","paramHelp":{"player":"The player to change the state for","state":"The state to change","delta":"The amount to change the state by"},"jsDoc":"Changes the value of the specified player state","_def":{"parts":[{"kind":"label","text":"change ","style":[]},{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"state","shadowBlockId":"mp_multiplayerstate","ref":true},{"kind":"label","text":" by ","style":[]},{"kind":"param","name":"delta","ref":true}],"parameters":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"param","name":"state","shadowBlockId":"mp_multiplayerstate","ref":true},{"kind":"param","name":"delta","ref":true}]}},"parameters":[{"name":"player","description":"The player to change the state for","type":"mp.Player"},{"name":"state","description":"The state to change"},{"name":"delta","description":"The amount to change the state by","initializer":"1","default":"1"}],"pyQName":"mp.change_player_state_by"},"mp.getPlayerProperty":{"kind":-3,"retType":"number","attributes":{"blockId":"mp_getPlayerProperty","block":"$player $prop","_shadowOverrides":{"player":"mp_playerSelector"},"group":"Info","weight":100,"blockGap":"8","help":"multiplayer/get-player-property","parts":"multiplayer","paramHelp":{"player":"The player to get the property of","prop":"The property to get"},"jsDoc":"Gets a property of the player\n\n\n@returns The value of the property","_def":{"parts":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"prop","ref":true}],"parameters":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"param","name":"prop","ref":true}]}},"parameters":[{"name":"player","description":"The player to get the property of","type":"mp.Player"},{"name":"prop","description":"The property to get","type":"mp.PlayerProperty","isEnum":true}],"pyQName":"mp.get_player_property"},"mp.onScore":{"kind":-3,"attributes":{"paramDefl":{"score":"100"},"blockId":"mp_onScore","block":"on score $score for $player","explicitDefaults":["score"],"draggableParameters":"reporter","group":"Info","weight":70,"blockGap":"8","help":"multiplayer/on-score","parts":"multiplayer","paramHelp":{"score":"The score to check for, eg: 100","handler":"The code to run when the score is reached"},"jsDoc":"Runs code once each time a player's score reaches a given value.","_def":{"parts":[{"kind":"label","text":"on score ","style":[]},{"kind":"param","name":"score","ref":true},{"kind":"label","text":" for ","style":[]},{"kind":"param","name":"player","ref":true}],"parameters":[{"kind":"param","name":"score","ref":true},{"kind":"param","name":"player","ref":true}]}},"parameters":[{"name":"score","description":"The score to check for, eg: 100","initializer":"100","default":"100"},{"name":"handler","description":"The code to run when the score is reached","type":"(player: mp.Player) => void","handlerParameters":[{"name":"player","type":"mp.Player"}]}],"pyQName":"mp.on_score"},"mp.onLifeZero":{"kind":-3,"attributes":{"blockId":"mp_onLifeZero","block":"on life zero for $player","draggableParameters":"reporter","group":"Info","weight":60,"blockGap":"8","help":"multiplayer/on-life-zero","parts":"multiplayer","paramHelp":{"handler":"The code to run when the lives reach zero"},"jsDoc":"Runs code when a player's number of lives reaches zero","_def":{"parts":[{"kind":"label","text":"on life zero for ","style":[]},{"kind":"param","name":"player","ref":true}],"parameters":[{"kind":"param","name":"player","ref":true}]}},"parameters":[{"name":"handler","description":"The code to run when the lives reach zero","type":"(player: mp.Player) => void","handlerParameters":[{"name":"player","type":"mp.Player"}]}],"pyQName":"mp.on_life_zero"},"mp.gameOverPlayerWin":{"kind":-3,"attributes":{"blockId":"mp_gameOverPlayerWin","block":"game over $player wins","_shadowOverrides":{"player":"mp_playerSelector"},"group":"Game","weight":100,"blockGap":"8","help":"multiplayer/game-over-player-win","parts":"multiplayer","_def":{"parts":[{"kind":"label","text":"game over ","style":[]},{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true},{"kind":"label","text":" wins","style":[]}],"parameters":[{"kind":"param","name":"player","shadowBlockId":"mp_playerSelector","ref":true}]}},"parameters":[{"name":"player","type":"mp.Player"}],"pyQName":"mp.game_over_player_win"},"mp.getPlayerByNumber":{"kind":-3,"retType":"mp.Player","attributes":{"paramDefl":{"number":"number"},"blockId":"mp_getPlayerByNumber","block":"player $number","_shadowOverrides":{"number":"variables_get"},"explicitDefaults":["number"],"group":"Utility","weight":80,"blockGap":"8","help":"multiplayer/get-player-by-number","parts":"multiplayer","paramHelp":{"number":"The one-based number of the player"},"jsDoc":"Gets the player by number\n\n@returns Player, or undefined if not found","_def":{"parts":[{"kind":"label","text":"player ","style":[]},{"kind":"param","name":"number","shadowBlockId":"variables_get","ref":true}],"parameters":[{"kind":"param","name":"number","shadowBlockId":"variables_get","ref":true}]}},"parameters":[{"name":"number","description":"The one-based number of the player","initializer":"number","default":"number"}],"pyQName":"mp.get_player_by_number"},"mp.getPlayerByIndex":{"kind":-3,"retType":"mp.Player","attributes":{"paramDefl":{"index":"index"},"blockId":"mp_getPlayerByIndex","block":"player at $index","_shadowOverrides":{"index":"variables_get"},"explicitDefaults":["index"],"group":"Utility","weight":80,"blockGap":"8","help":"multiplayer/get-player-by-index","parts":"multiplayer","paramHelp":{"index":"The zero-based index of the player"},"jsDoc":"Gets the player by index\n\n@returns Player, or undefined if not found","_def":{"parts":[{"kind":"label","text":"player at ","style":[]},{"kind":"param","name":"index","shadowBlockId":"variables_get","ref":true}],"parameters":[{"kind":"param","name":"index","shadowBlockId":"variables_get","ref":true}]}},"parameters":[{"name":"index","description":"The zero-based index of the player","initializer":"index","default":"index"}],"pyQName":"mp.get_player_by_index"},"mp.setPlayerIndicatorsVisible":{"kind":-3,"attributes":{"paramDefl":{"visible":"true"},"blockId":"mp_setPlayerIndicatorsVisible","block":"set player indicators $visible","_shadowOverrides":{"visible":"toggleOnOff"},"explicitDefaults":["visible"],"group":"Utility","weight":100,"blockGap":"8","help":"multiplayer/set-player-indicators-visible","parts":"multiplayer","paramHelp":{"visible":"indicator visibility"},"jsDoc":"Turns player indicators on or off","_def":{"parts":[{"kind":"label","text":"set player indicators ","style":[]},{"kind":"param","name":"visible","shadowBlockId":"toggleOnOff","ref":true}],"parameters":[{"kind":"param","name":"visible","shadowBlockId":"toggleOnOff","ref":true}]}},"parameters":[{"name":"visible","description":"indicator visibility","type":"boolean","initializer":"true","default":"true"}],"pyQName":"mp.set_player_indicators_visible"},"MultiplayerState":{"kind":5,"retType":""},"MultiplayerState.create":{"kind":-3,"retType":"number","parameters":[]},"MultiplayerState.score":{"kind":4,"retType":"number","attributes":{"isKind":"true"}},"MultiplayerState.life":{"kind":4,"retType":"number","attributes":{"isKind":"true"}}}},"sha":"ecf537417bc79f83870c2aa86e33ea3139c902b93938906617c960b15b5c77c0"},"libs/net":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"net":{"kind":5,"retType":"","attributes":{"weight":1,"advanced":true,"icon":"","color":"#8446cf","jsDoc":"Networking, WiFi, web requests"}},"net.ControllerEvent":{"kind":6,"retType":"net.ControllerEvent","extendsTypes":["net.ControllerEvent","Number"]},"net.ControllerEvent.NewScan":{"retType":"net.ControllerEvent.NewScan","extendsTypes":["net.ControllerEvent.NewScan","Number"],"pyQName":"net.ControllerEvent.NEW_SCAN"},"net.ControllerEvent.GotIP":{"retType":"net.ControllerEvent.GotIP","extendsTypes":["net.ControllerEvent.GotIP","Number"],"pyQName":"net.ControllerEvent.GOT_IP"},"net.ControllerEvent.LostIP":{"retType":"net.ControllerEvent.LostIP","extendsTypes":["net.ControllerEvent.LostIP","Number"],"pyQName":"net.ControllerEvent.LOST_IP"},"net.ControllerEvent.NoScannedNetworks":{"retType":"net.ControllerEvent.NoScannedNetworks","extendsTypes":["net.ControllerEvent.NoScannedNetworks","Number"],"pyQName":"net.ControllerEvent.NO_SCANNED_NETWORKS"},"net.ControllerEvent.NoKnownNetworks":{"retType":"net.ControllerEvent.NoKnownNetworks","extendsTypes":["net.ControllerEvent.NoKnownNetworks","Number"],"pyQName":"net.ControllerEvent.NO_KNOWN_NETWORKS"},"net.ControllerEvent.Connecting":{"retType":"net.ControllerEvent.Connecting","extendsTypes":["net.ControllerEvent.Connecting","Number"],"pyQName":"net.ControllerEvent.CONNECTING"},"net.ControllerEvent.ConnectionFailed":{"retType":"net.ControllerEvent.ConnectionFailed","extendsTypes":["net.ControllerEvent.ConnectionFailed","Number"],"pyQName":"net.ControllerEvent.CONNECTION_FAILED"},"net.ControllerEvent.LoginServerStarted":{"retType":"net.ControllerEvent.LoginServerStarted","extendsTypes":["net.ControllerEvent.LoginServerStarted","Number"],"pyQName":"net.ControllerEvent.LOGIN_SERVER_STARTED"},"net.Controller":{"kind":8,"retType":"net.Controller","extendsTypes":[]},"net.Controller.eventID":{"kind":2,"retType":"number","isInstance":true,"pyQName":"net.Controller.event_id"},"net.Controller.onConnectSSIDFailed":{"kind":2,"retType":"(ssid: string) => void","isInstance":true,"pyQName":"net.Controller.on_connect_ssid_failed"},"net.Controller.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"net.Controller.onEvent":{"kind":-1,"parameters":[{"name":"ev","type":"net.ControllerEvent","isEnum":true},{"name":"h","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Controller.on_event"},"net.Controller.scanNetworks":{"kind":-1,"retType":"net.AccessPoint[]","parameters":[],"isInstance":true,"pyQName":"net.Controller.scan_networks"},"net.Controller.startLoginServer":{"kind":-1,"parameters":[{"name":"hostName","type":"string"}],"isInstance":true,"pyQName":"net.Controller.start_login_server"},"net.Controller.isLoginServerEnabled":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"net.Controller.is_login_server_enabled"},"net.Controller.socket":{"kind":-1,"retType":"number","parameters":[],"isInstance":true},"net.Controller.socketConnect":{"kind":-1,"retType":"boolean","parameters":[{"name":"socket_num"},{"name":"dest","type":"string | Buffer"},{"name":"port"},{"name":"conn_mode","initializer":"TCP_MODE"}],"isInstance":true,"pyQName":"net.Controller.socket_connect"},"net.Controller.socketWrite":{"kind":-1,"parameters":[{"name":"socket_num"},{"name":"buffer","type":"Buffer"}],"isInstance":true,"pyQName":"net.Controller.socket_write"},"net.Controller.socketAvailable":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.socket_available"},"net.Controller.socketRead":{"kind":-1,"retType":"Buffer","parameters":[{"name":"socket_num"},{"name":"size"}],"isInstance":true,"pyQName":"net.Controller.socket_read"},"net.Controller.socketClose":{"kind":-1,"parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.socket_close"},"net.Controller.hostbyName":{"kind":-1,"retType":"Buffer","parameters":[{"name":"hostname","type":"string"}],"isInstance":true,"pyQName":"net.Controller.hostby_name"},"net.Controller.isIdle":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.is_idle"},"net.Controller.isConnected":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.is_connected"},"net.Controller.connectAP":{"kind":-1,"retType":"boolean","parameters":[{"name":"bssid","type":"string"},{"name":"password","type":"string"}],"isInstance":true,"pyQName":"net.Controller.connect_ap"},"net.Controller.disconnectAP":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"net.Controller.disconnect_ap"},"net.Controller.lastScanResults":{"kind":2,"retType":"net.AccessPoint[]","isInstance":true,"pyQName":"net.Controller.last_scan_results"},"net.Controller.autoconnect":{"kind":-1,"parameters":[],"isInstance":true},"net.Controller.disconnect":{"kind":-1,"parameters":[],"isInstance":true},"net.Controller.connect":{"kind":-1,"retType":"boolean","parameters":[{"name":"timeout_ms","initializer":"undefined"}],"isInstance":true},"net.Controller.ssid":{"kind":-2,"retType":"string","isInstance":true,"isReadOnly":true},"net.Controller.rssi":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"net.Controller.MACaddress":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.ma_caddress"},"net.Controller.IPaddress":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.ipaddress"},"net.Controller.ping":{"kind":-1,"retType":"number","parameters":[{"name":"dest","type":"string"},{"name":"ttl","initializer":"250"}],"isInstance":true},"net.Controller.dataAvailableSrc":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.data_available_src"},"net.Controller.dataAvailableValue":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.data_available_value"},"net.SOCK_STREAM":{"kind":4,"retType":"number"},"net.AF_INET":{"kind":4,"retType":"number"},"net.MAX_PACKET":{"kind":4,"retType":"number"},"net.TCP_MODE":{"kind":4,"retType":"number"},"net.UDP_MODE":{"kind":4,"retType":"number"},"net.TLS_MODE":{"kind":4,"retType":"number"},"net.ControllerSocket":{"kind":8,"retType":"net.ControllerSocket","extendsTypes":["net.ControllerSocket","net.Socket"]},"net.ControllerSocket._buffer":{"kind":2,"retType":"Buffer","isInstance":true},"net.ControllerSocket._socknum":{"kind":2,"retType":"number","isInstance":true},"net.ControllerSocket._timeout":{"kind":2,"retType":"number","isInstance":true},"net.ControllerSocket._closed":{"kind":2,"retType":"boolean","isInstance":true},"net.ControllerSocket._openHandler":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"net.ControllerSocket._open_handler"},"net.ControllerSocket._closeHandler":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"net.ControllerSocket._close_handler"},"net.ControllerSocket._errorHandler":{"kind":2,"retType":"(msg: string) => void","isInstance":true,"pyQName":"net.ControllerSocket._error_handler"},"net.ControllerSocket._messageHandler":{"kind":2,"retType":"(data: Buffer) => void","isInstance":true,"pyQName":"net.ControllerSocket._message_handler"},"net.ControllerSocket.__constructor":{"kind":-3,"attributes":{"jsDoc":"A simplified implementation of the Python 'socket' class, for connecting\nthrough an interface to a remote device"},"parameters":[{"name":"controller","type":"net.Controller"},{"name":"host","type":"string | Buffer"},{"name":"port"},{"name":"conntype","initializer":"null"}],"isInstance":true},"net.ControllerSocket.connect":{"kind":-1,"attributes":{"jsDoc":"Connect the socket to the 'address' (which can be 32bit packed IP or\na hostname string). 'conntype' is an extra that may indicate SSL or not,\ndepending on the underlying interface"},"parameters":[],"isInstance":true},"net.ControllerSocket.send":{"kind":-1,"attributes":{"jsDoc":"Send some data to the socket"},"parameters":[{"name":"data","type":"string | Buffer"}],"isInstance":true},"net.ControllerSocket.onOpen":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_open"},"net.ControllerSocket.onClose":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_close"},"net.ControllerSocket.onError":{"kind":-1,"parameters":[{"name":"handler","type":"(msg: string) => void","handlerParameters":[{"name":"msg","type":"string"}]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_error"},"net.ControllerSocket.onMessage":{"kind":-1,"parameters":[{"name":"handler","type":"(data: Buffer) => void","handlerParameters":[{"name":"data","type":"Buffer"}]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_message"},"net.ControllerSocket.readLine":{"kind":-1,"retType":"string","attributes":{"jsDoc":"Attempt to return as many bytes as we can up to but not including '\\r\\n'"},"parameters":[],"isInstance":true,"pyQName":"net.ControllerSocket.read_line"},"net.ControllerSocket.read":{"kind":-1,"retType":"Buffer","attributes":{"jsDoc":"Read up to 'size' bytes from the socket, this may be buffered internally! If 'size' isn't specified, return everything in the buffer."},"parameters":[{"name":"size","initializer":"0"}],"isInstance":true},"net.ControllerSocket.setTimeout":{"kind":-1,"attributes":{"jsDoc":"Set the read timeout for sockets, if value is 0 it will block"},"parameters":[{"name":"value"}],"isInstance":true,"pyQName":"net.ControllerSocket.set_timeout"},"net.ControllerSocket.close":{"kind":-1,"attributes":{"jsDoc":"Close the socket, after reading whatever remains"},"parameters":[],"isInstance":true},"net.logPriority":{"kind":4,"retType":"ConsolePriority","attributes":{"jsDoc":"Default priority of net log messages"},"pyQName":"net.log_priority"},"net.log":{"kind":-3,"parameters":[{"name":"msg","type":"string"}]},"net.debug":{"kind":-3,"parameters":[{"name":"msg","type":"string"}]},"net.fail":{"kind":-3,"parameters":[{"name":"reason","type":"string"}]},"net.monotonic":{"kind":-3,"retType":"number","parameters":[]},"net.WifiAPFlags":{"kind":6,"retType":"net.WifiAPFlags","extendsTypes":["net.WifiAPFlags","Number"]},"net.WifiAPFlags.HasPassword":{"retType":"net.WifiAPFlags.HasPassword","extendsTypes":["net.WifiAPFlags.HasPassword","Number"],"pyQName":"net.WifiAPFlags.HAS_PASSWORD"},"net.WifiAPFlags.WPS":{"retType":"net.WifiAPFlags.WPS","extendsTypes":["net.WifiAPFlags.WPS","Number"]},"net.WifiAPFlags.HasSecondaryChannelAbove":{"retType":"net.WifiAPFlags.HasSecondaryChannelAbove","extendsTypes":["net.WifiAPFlags.HasSecondaryChannelAbove","Number"],"pyQName":"net.WifiAPFlags.HAS_SECONDARY_CHANNEL_ABOVE"},"net.WifiAPFlags.HasSecondaryChannelBelow":{"retType":"net.WifiAPFlags.HasSecondaryChannelBelow","extendsTypes":["net.WifiAPFlags.HasSecondaryChannelBelow","Number"],"pyQName":"net.WifiAPFlags.HAS_SECONDARY_CHANNEL_BELOW"},"net.WifiAPFlags.IEEE_802_11B":{"retType":"net.WifiAPFlags.IEEE_802_11B","extendsTypes":["net.WifiAPFlags.IEEE_802_11B","Number"]},"net.WifiAPFlags.IEEE_802_11A":{"retType":"net.WifiAPFlags.IEEE_802_11A","extendsTypes":["net.WifiAPFlags.IEEE_802_11A","Number"]},"net.WifiAPFlags.IEEE_802_11G":{"retType":"net.WifiAPFlags.IEEE_802_11G","extendsTypes":["net.WifiAPFlags.IEEE_802_11G","Number"]},"net.WifiAPFlags.IEEE_802_11N":{"retType":"net.WifiAPFlags.IEEE_802_11N","extendsTypes":["net.WifiAPFlags.IEEE_802_11N","Number"]},"net.WifiAPFlags.IEEE_802_11AC":{"retType":"net.WifiAPFlags.IEEE_802_11AC","extendsTypes":["net.WifiAPFlags.IEEE_802_11AC","Number"]},"net.WifiAPFlags.IEEE_802_11AX":{"retType":"net.WifiAPFlags.IEEE_802_11AX","extendsTypes":["net.WifiAPFlags.IEEE_802_11AX","Number"]},"net.WifiAPFlags.IEEE_802_LongRange":{"retType":"net.WifiAPFlags.IEEE_802_LongRange","extendsTypes":["net.WifiAPFlags.IEEE_802_LongRange","Number"],"pyQName":"net.WifiAPFlags.IEEE_802_LONGRANGE"},"net.AccessPoint":{"kind":8,"retType":"net.AccessPoint","extendsTypes":[]},"net.AccessPoint.flags":{"kind":2,"retType":"net.WifiAPFlags","isInstance":true},"net.AccessPoint.rssi":{"kind":2,"retType":"number","isInstance":true},"net.AccessPoint.bssid":{"kind":2,"retType":"Buffer","isInstance":true},"net.AccessPoint.channel":{"kind":2,"retType":"number","isInstance":true},"net.AccessPoint.__constructor":{"kind":-3,"parameters":[{"name":"ssid","type":"string"}],"isInstance":true},"net.AccessPoint.fromBuffer":{"kind":-1,"retType":"net.AccessPoint","parameters":[{"name":"buf","type":"Buffer"}],"pyQName":"net.AccessPoint.from_buffer"},"net.AccessPoint.toBuffer":{"kind":-1,"retType":"Buffer","parameters":[],"isInstance":true,"pyQName":"net.AccessPoint.to_buffer"},"net.Socket":{"kind":9,"retType":"net.Socket","extendsTypes":["net.Socket"]},"net.Socket.connect":{"kind":-1,"parameters":[],"isInstance":true},"net.Socket.send":{"kind":-1,"parameters":[{"name":"data","type":"string | Buffer"}],"isInstance":true},"net.Socket.read":{"kind":-1,"retType":"Buffer","parameters":[{"name":"contentLength"}],"isInstance":true},"net.Socket.close":{"kind":-1,"parameters":[],"isInstance":true},"net.Socket.onOpen":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Socket.on_open"},"net.Socket.onClose":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Socket.on_close"},"net.Socket.onError":{"kind":-1,"parameters":[{"name":"handler","type":"(msg: string) => void","handlerParameters":[{"name":"msg","type":"string"}]}],"isInstance":true,"pyQName":"net.Socket.on_error"},"net.Socket.onMessage":{"kind":-1,"parameters":[{"name":"handler","type":"(data: Buffer) => void","handlerParameters":[{"name":"data","type":"Buffer"}]}],"isInstance":true,"pyQName":"net.Socket.on_message"},"net.Socket.setTimeout":{"kind":-1,"parameters":[{"name":"millis"}],"isInstance":true,"pyQName":"net.Socket.set_timeout"},"net.Socket.readLine":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"net.Socket.read_line"},"net.Net":{"kind":8,"retType":"net.Net","extendsTypes":[]},"net.Net.__constructor":{"kind":-3,"parameters":[{"name":"factory","type":"() => net.Controller","handlerParameters":[]}],"isInstance":true},"net.Net.instance":{"kind":2,"retType":"net.Net"},"net.Net.controller":{"kind":-2,"retType":"net.Controller","isInstance":true,"isReadOnly":true},"net.Net.scanNetworks":{"kind":-1,"retType":"net.AccessPoint[]","attributes":{"jsDoc":"Scan for APs"},"parameters":[],"isInstance":true,"pyQName":"net.Net.scan_networks"},"net.Net.createSocket":{"kind":-1,"retType":"net.Socket","parameters":[{"name":"host","type":"string"},{"name":"port"},{"name":"secure","type":"boolean"}],"isInstance":true,"pyQName":"net.Net.create_socket"},"net.Net.hostByName":{"kind":-1,"retType":"string","parameters":[{"name":"host","type":"string"}],"isInstance":true,"pyQName":"net.Net.host_by_name"},"net.instance":{"kind":-3,"retType":"net.Net","attributes":{"jsDoc":"Gets the current Net instance"},"parameters":[]},"net.knownAccessPoints":{"kind":-3,"retType":"StringMap","attributes":{"jsDoc":"Gets the map of SSID -> password pairs"},"parameters":[],"pyQName":"net.known_access_points"},"net.clearAccessPoint":{"kind":-3,"parameters":[{"name":"ssid","type":"string"}],"pyQName":"net.clear_access_point"},"net.updateAccessPoint":{"kind":-3,"parameters":[{"name":"ssid","type":"string"},{"name":"password","type":"string"}],"pyQName":"net.update_access_point"},"net.setAccessPointPriority":{"kind":-3,"parameters":[{"name":"ssid","type":"string"},{"name":"pri"}],"pyQName":"net.set_access_point_priority"},"net.accessPointPriorities":{"kind":-3,"retType":"any","parameters":[],"pyQName":"net.access_point_priorities"},"net.clearAccessPoints":{"kind":-3,"parameters":[],"pyQName":"net.clear_access_points"},"net.urlencode":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"}]},"net.urldecode":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"}]},"net.ping":{"kind":-3,"retType":"number","attributes":{"blockId":"netping","block":"net ping $dest","paramHelp":{"dest":"host name","ttl":""},"jsDoc":"Pings a web site","_def":{"parts":[{"kind":"label","text":"net ping ","style":[]},{"kind":"param","name":"dest","ref":true}],"parameters":[{"kind":"param","name":"dest","ref":true}]}},"parameters":[{"name":"dest","description":"host name","type":"string"},{"name":"ttl","initializer":"250"}]},"net.Response":{"kind":8,"retType":"net.Response","extendsTypes":[]},"net.Response._cached":{"kind":2,"retType":"Buffer","isInstance":true},"net.Response.status_code":{"kind":2,"retType":"number","isInstance":true},"net.Response.reason":{"kind":2,"retType":"string","isInstance":true},"net.Response._read_so_far":{"kind":2,"retType":"number","isInstance":true},"net.Response.headers":{"kind":2,"retType":"StringMap","isInstance":true},"net.Response.__constructor":{"kind":-3,"attributes":{"jsDoc":"The response from a request, contains all the headers/content"},"parameters":[{"name":"socket","type":"net.Socket"}],"isInstance":true},"net.Response.close":{"kind":-1,"attributes":{"jsDoc":"Close, delete and collect the response data"},"parameters":[],"isInstance":true},"net.Response.content":{"kind":-2,"retType":"Buffer","attributes":{"jsDoc":"The HTTP content direct from the socket, as bytes"},"isInstance":true,"isReadOnly":true},"net.Response.text":{"kind":-2,"retType":"string","attributes":{"jsDoc":"The HTTP content, encoded into a string according to the HTTP header encoding"},"isInstance":true,"isReadOnly":true},"net.Response.json":{"kind":-2,"retType":"any","isInstance":true,"isReadOnly":true},"net.Response.toString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"net.Response.to_string"},"net.RequestOptions":{"kind":9,"retType":"net.RequestOptions","extendsTypes":[]},"net.RequestOptions.data":{"kind":2,"retType":"string | Buffer","isInstance":true},"net.RequestOptions.json":{"kind":2,"retType":"any","isInstance":true},"net.RequestOptions.headers":{"kind":2,"retType":"StringMap","isInstance":true},"net.RequestOptions.stream":{"kind":2,"retType":"boolean","isInstance":true},"net.RequestOptions.timeout":{"kind":2,"retType":"number","isInstance":true},"net.dataAsBuffer":{"kind":-3,"retType":"Buffer","parameters":[{"name":"data","type":"string | Buffer"}],"pyQName":"net.data_as_buffer"},"net.request":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Perform an HTTP request to the given url which we will parse to determine\nwhether to use SSL ('https://') or not. We can also send some provided 'data'\nor a json dictionary which we will stringify. 'headers' is optional HTTP headers\nsent along. 'stream' will determine if we buffer everything, or whether to only\nread only when requested"},"parameters":[{"name":"method","type":"string"},{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.head":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP HEAD request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.get":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP GET request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.getString":{"kind":-3,"retType":"string","attributes":{"blockId":"netgetstring","block":"get string $url","jsDoc":"Send HTTP GET request and return text","_def":{"parts":[{"kind":"label","text":"get string ","style":[]},{"kind":"param","name":"url","ref":true}],"parameters":[{"kind":"param","name":"url","ref":true}]}},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}],"pyQName":"net.get_string"},"net.getJSON":{"kind":-3,"retType":"any","attributes":{"blockId":"netgetjson","block":"get json $url","jsDoc":"Send HTTP GET request and return JSON","_def":{"parts":[{"kind":"label","text":"get json ","style":[]},{"kind":"param","name":"url","ref":true}],"parameters":[{"kind":"param","name":"url","ref":true}]}},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}],"pyQName":"net.get_json"},"net.post":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP POST request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.patch":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP PATCH request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.put":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP PUT request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.del":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP DELETE request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]}}},"sha":"3250a66d8de311d0314e5360935a209c78b1f50b0b7ff50abe0d2b1ce0112013"},"libs/net-game":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"net":{"kind":5,"retType":"","attributes":{"weight":1,"advanced":true,"icon":"","color":"#8446cf","jsDoc":"Networking, WiFi, web requests"}},"net.ControllerEvent":{"kind":6,"retType":"net.ControllerEvent","extendsTypes":["net.ControllerEvent","Number"]},"net.ControllerEvent.NewScan":{"retType":"net.ControllerEvent.NewScan","extendsTypes":["net.ControllerEvent.NewScan","Number"],"pyQName":"net.ControllerEvent.NEW_SCAN"},"net.ControllerEvent.GotIP":{"retType":"net.ControllerEvent.GotIP","extendsTypes":["net.ControllerEvent.GotIP","Number"],"pyQName":"net.ControllerEvent.GOT_IP"},"net.ControllerEvent.LostIP":{"retType":"net.ControllerEvent.LostIP","extendsTypes":["net.ControllerEvent.LostIP","Number"],"pyQName":"net.ControllerEvent.LOST_IP"},"net.ControllerEvent.NoScannedNetworks":{"retType":"net.ControllerEvent.NoScannedNetworks","extendsTypes":["net.ControllerEvent.NoScannedNetworks","Number"],"pyQName":"net.ControllerEvent.NO_SCANNED_NETWORKS"},"net.ControllerEvent.NoKnownNetworks":{"retType":"net.ControllerEvent.NoKnownNetworks","extendsTypes":["net.ControllerEvent.NoKnownNetworks","Number"],"pyQName":"net.ControllerEvent.NO_KNOWN_NETWORKS"},"net.ControllerEvent.Connecting":{"retType":"net.ControllerEvent.Connecting","extendsTypes":["net.ControllerEvent.Connecting","Number"],"pyQName":"net.ControllerEvent.CONNECTING"},"net.ControllerEvent.ConnectionFailed":{"retType":"net.ControllerEvent.ConnectionFailed","extendsTypes":["net.ControllerEvent.ConnectionFailed","Number"],"pyQName":"net.ControllerEvent.CONNECTION_FAILED"},"net.ControllerEvent.LoginServerStarted":{"retType":"net.ControllerEvent.LoginServerStarted","extendsTypes":["net.ControllerEvent.LoginServerStarted","Number"],"pyQName":"net.ControllerEvent.LOGIN_SERVER_STARTED"},"net.Controller":{"kind":8,"retType":"net.Controller","extendsTypes":[]},"net.Controller.eventID":{"kind":2,"retType":"number","isInstance":true,"pyQName":"net.Controller.event_id"},"net.Controller.onConnectSSIDFailed":{"kind":2,"retType":"(ssid: string) => void","isInstance":true,"pyQName":"net.Controller.on_connect_ssid_failed"},"net.Controller.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"net.Controller.onEvent":{"kind":-1,"parameters":[{"name":"ev","type":"net.ControllerEvent","isEnum":true},{"name":"h","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Controller.on_event"},"net.Controller.scanNetworks":{"kind":-1,"retType":"net.AccessPoint[]","parameters":[],"isInstance":true,"pyQName":"net.Controller.scan_networks"},"net.Controller.startLoginServer":{"kind":-1,"parameters":[{"name":"hostName","type":"string"}],"isInstance":true,"pyQName":"net.Controller.start_login_server"},"net.Controller.isLoginServerEnabled":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"net.Controller.is_login_server_enabled"},"net.Controller.socket":{"kind":-1,"retType":"number","parameters":[],"isInstance":true},"net.Controller.socketConnect":{"kind":-1,"retType":"boolean","parameters":[{"name":"socket_num"},{"name":"dest","type":"string | Buffer"},{"name":"port"},{"name":"conn_mode","initializer":"TCP_MODE"}],"isInstance":true,"pyQName":"net.Controller.socket_connect"},"net.Controller.socketWrite":{"kind":-1,"parameters":[{"name":"socket_num"},{"name":"buffer","type":"Buffer"}],"isInstance":true,"pyQName":"net.Controller.socket_write"},"net.Controller.socketAvailable":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.socket_available"},"net.Controller.socketRead":{"kind":-1,"retType":"Buffer","parameters":[{"name":"socket_num"},{"name":"size"}],"isInstance":true,"pyQName":"net.Controller.socket_read"},"net.Controller.socketClose":{"kind":-1,"parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.socket_close"},"net.Controller.hostbyName":{"kind":-1,"retType":"Buffer","parameters":[{"name":"hostname","type":"string"}],"isInstance":true,"pyQName":"net.Controller.hostby_name"},"net.Controller.isIdle":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.is_idle"},"net.Controller.isConnected":{"kind":-2,"retType":"boolean","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.is_connected"},"net.Controller.connectAP":{"kind":-1,"retType":"boolean","parameters":[{"name":"bssid","type":"string"},{"name":"password","type":"string"}],"isInstance":true,"pyQName":"net.Controller.connect_ap"},"net.Controller.disconnectAP":{"kind":-1,"parameters":[],"isInstance":true,"pyQName":"net.Controller.disconnect_ap"},"net.Controller.lastScanResults":{"kind":2,"retType":"net.AccessPoint[]","isInstance":true,"pyQName":"net.Controller.last_scan_results"},"net.Controller.autoconnect":{"kind":-1,"parameters":[],"isInstance":true},"net.Controller.disconnect":{"kind":-1,"parameters":[],"isInstance":true},"net.Controller.connect":{"kind":-1,"retType":"boolean","parameters":[{"name":"timeout_ms","initializer":"undefined"}],"isInstance":true},"net.Controller.ssid":{"kind":-2,"retType":"string","isInstance":true,"isReadOnly":true},"net.Controller.rssi":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"net.Controller.MACaddress":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.ma_caddress"},"net.Controller.IPaddress":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"net.Controller.ipaddress"},"net.Controller.ping":{"kind":-1,"retType":"number","parameters":[{"name":"dest","type":"string"},{"name":"ttl","initializer":"250"}],"isInstance":true},"net.Controller.dataAvailableSrc":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.data_available_src"},"net.Controller.dataAvailableValue":{"kind":-1,"retType":"number","parameters":[{"name":"socket_num"}],"isInstance":true,"pyQName":"net.Controller.data_available_value"},"net.SOCK_STREAM":{"kind":4,"retType":"number"},"net.AF_INET":{"kind":4,"retType":"number"},"net.MAX_PACKET":{"kind":4,"retType":"number"},"net.TCP_MODE":{"kind":4,"retType":"number"},"net.UDP_MODE":{"kind":4,"retType":"number"},"net.TLS_MODE":{"kind":4,"retType":"number"},"net.ControllerSocket":{"kind":8,"retType":"net.ControllerSocket","extendsTypes":["net.ControllerSocket","net.Socket"]},"net.ControllerSocket._buffer":{"kind":2,"retType":"Buffer","isInstance":true},"net.ControllerSocket._socknum":{"kind":2,"retType":"number","isInstance":true},"net.ControllerSocket._timeout":{"kind":2,"retType":"number","isInstance":true},"net.ControllerSocket._closed":{"kind":2,"retType":"boolean","isInstance":true},"net.ControllerSocket._openHandler":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"net.ControllerSocket._open_handler"},"net.ControllerSocket._closeHandler":{"kind":2,"retType":"() => void","isInstance":true,"pyQName":"net.ControllerSocket._close_handler"},"net.ControllerSocket._errorHandler":{"kind":2,"retType":"(msg: string) => void","isInstance":true,"pyQName":"net.ControllerSocket._error_handler"},"net.ControllerSocket._messageHandler":{"kind":2,"retType":"(data: Buffer) => void","isInstance":true,"pyQName":"net.ControllerSocket._message_handler"},"net.ControllerSocket.__constructor":{"kind":-3,"attributes":{"jsDoc":"A simplified implementation of the Python 'socket' class, for connecting\nthrough an interface to a remote device"},"parameters":[{"name":"controller","type":"net.Controller"},{"name":"host","type":"string | Buffer"},{"name":"port"},{"name":"conntype","initializer":"null"}],"isInstance":true},"net.ControllerSocket.connect":{"kind":-1,"attributes":{"jsDoc":"Connect the socket to the 'address' (which can be 32bit packed IP or\na hostname string). 'conntype' is an extra that may indicate SSL or not,\ndepending on the underlying interface"},"parameters":[],"isInstance":true},"net.ControllerSocket.send":{"kind":-1,"attributes":{"jsDoc":"Send some data to the socket"},"parameters":[{"name":"data","type":"string | Buffer"}],"isInstance":true},"net.ControllerSocket.onOpen":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_open"},"net.ControllerSocket.onClose":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_close"},"net.ControllerSocket.onError":{"kind":-1,"parameters":[{"name":"handler","type":"(msg: string) => void","handlerParameters":[{"name":"msg","type":"string"}]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_error"},"net.ControllerSocket.onMessage":{"kind":-1,"parameters":[{"name":"handler","type":"(data: Buffer) => void","handlerParameters":[{"name":"data","type":"Buffer"}]}],"isInstance":true,"pyQName":"net.ControllerSocket.on_message"},"net.ControllerSocket.readLine":{"kind":-1,"retType":"string","attributes":{"jsDoc":"Attempt to return as many bytes as we can up to but not including '\\r\\n'"},"parameters":[],"isInstance":true,"pyQName":"net.ControllerSocket.read_line"},"net.ControllerSocket.read":{"kind":-1,"retType":"Buffer","attributes":{"jsDoc":"Read up to 'size' bytes from the socket, this may be buffered internally! If 'size' isn't specified, return everything in the buffer."},"parameters":[{"name":"size","initializer":"0"}],"isInstance":true},"net.ControllerSocket.setTimeout":{"kind":-1,"attributes":{"jsDoc":"Set the read timeout for sockets, if value is 0 it will block"},"parameters":[{"name":"value"}],"isInstance":true,"pyQName":"net.ControllerSocket.set_timeout"},"net.ControllerSocket.close":{"kind":-1,"attributes":{"jsDoc":"Close the socket, after reading whatever remains"},"parameters":[],"isInstance":true},"net.logPriority":{"kind":4,"retType":"ConsolePriority","attributes":{"jsDoc":"Default priority of net log messages"},"pyQName":"net.log_priority"},"net.log":{"kind":-3,"parameters":[{"name":"msg","type":"string"}]},"net.debug":{"kind":-3,"parameters":[{"name":"msg","type":"string"}]},"net.fail":{"kind":-3,"parameters":[{"name":"reason","type":"string"}]},"net.monotonic":{"kind":-3,"retType":"number","parameters":[]},"net.WifiAPFlags":{"kind":6,"retType":"net.WifiAPFlags","extendsTypes":["net.WifiAPFlags","Number"]},"net.WifiAPFlags.HasPassword":{"retType":"net.WifiAPFlags.HasPassword","extendsTypes":["net.WifiAPFlags.HasPassword","Number"],"pyQName":"net.WifiAPFlags.HAS_PASSWORD"},"net.WifiAPFlags.WPS":{"retType":"net.WifiAPFlags.WPS","extendsTypes":["net.WifiAPFlags.WPS","Number"]},"net.WifiAPFlags.HasSecondaryChannelAbove":{"retType":"net.WifiAPFlags.HasSecondaryChannelAbove","extendsTypes":["net.WifiAPFlags.HasSecondaryChannelAbove","Number"],"pyQName":"net.WifiAPFlags.HAS_SECONDARY_CHANNEL_ABOVE"},"net.WifiAPFlags.HasSecondaryChannelBelow":{"retType":"net.WifiAPFlags.HasSecondaryChannelBelow","extendsTypes":["net.WifiAPFlags.HasSecondaryChannelBelow","Number"],"pyQName":"net.WifiAPFlags.HAS_SECONDARY_CHANNEL_BELOW"},"net.WifiAPFlags.IEEE_802_11B":{"retType":"net.WifiAPFlags.IEEE_802_11B","extendsTypes":["net.WifiAPFlags.IEEE_802_11B","Number"]},"net.WifiAPFlags.IEEE_802_11A":{"retType":"net.WifiAPFlags.IEEE_802_11A","extendsTypes":["net.WifiAPFlags.IEEE_802_11A","Number"]},"net.WifiAPFlags.IEEE_802_11G":{"retType":"net.WifiAPFlags.IEEE_802_11G","extendsTypes":["net.WifiAPFlags.IEEE_802_11G","Number"]},"net.WifiAPFlags.IEEE_802_11N":{"retType":"net.WifiAPFlags.IEEE_802_11N","extendsTypes":["net.WifiAPFlags.IEEE_802_11N","Number"]},"net.WifiAPFlags.IEEE_802_11AC":{"retType":"net.WifiAPFlags.IEEE_802_11AC","extendsTypes":["net.WifiAPFlags.IEEE_802_11AC","Number"]},"net.WifiAPFlags.IEEE_802_11AX":{"retType":"net.WifiAPFlags.IEEE_802_11AX","extendsTypes":["net.WifiAPFlags.IEEE_802_11AX","Number"]},"net.WifiAPFlags.IEEE_802_LongRange":{"retType":"net.WifiAPFlags.IEEE_802_LongRange","extendsTypes":["net.WifiAPFlags.IEEE_802_LongRange","Number"],"pyQName":"net.WifiAPFlags.IEEE_802_LONGRANGE"},"net.AccessPoint":{"kind":8,"retType":"net.AccessPoint","extendsTypes":[]},"net.AccessPoint.flags":{"kind":2,"retType":"net.WifiAPFlags","isInstance":true},"net.AccessPoint.rssi":{"kind":2,"retType":"number","isInstance":true},"net.AccessPoint.bssid":{"kind":2,"retType":"Buffer","isInstance":true},"net.AccessPoint.channel":{"kind":2,"retType":"number","isInstance":true},"net.AccessPoint.__constructor":{"kind":-3,"parameters":[{"name":"ssid","type":"string"}],"isInstance":true},"net.AccessPoint.fromBuffer":{"kind":-1,"retType":"net.AccessPoint","parameters":[{"name":"buf","type":"Buffer"}],"pyQName":"net.AccessPoint.from_buffer"},"net.AccessPoint.toBuffer":{"kind":-1,"retType":"Buffer","parameters":[],"isInstance":true,"pyQName":"net.AccessPoint.to_buffer"},"net.Socket":{"kind":9,"retType":"net.Socket","extendsTypes":["net.Socket"]},"net.Socket.connect":{"kind":-1,"parameters":[],"isInstance":true},"net.Socket.send":{"kind":-1,"parameters":[{"name":"data","type":"string | Buffer"}],"isInstance":true},"net.Socket.read":{"kind":-1,"retType":"Buffer","parameters":[{"name":"contentLength"}],"isInstance":true},"net.Socket.close":{"kind":-1,"parameters":[],"isInstance":true},"net.Socket.onOpen":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Socket.on_open"},"net.Socket.onClose":{"kind":-1,"parameters":[{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"net.Socket.on_close"},"net.Socket.onError":{"kind":-1,"parameters":[{"name":"handler","type":"(msg: string) => void","handlerParameters":[{"name":"msg","type":"string"}]}],"isInstance":true,"pyQName":"net.Socket.on_error"},"net.Socket.onMessage":{"kind":-1,"parameters":[{"name":"handler","type":"(data: Buffer) => void","handlerParameters":[{"name":"data","type":"Buffer"}]}],"isInstance":true,"pyQName":"net.Socket.on_message"},"net.Socket.setTimeout":{"kind":-1,"parameters":[{"name":"millis"}],"isInstance":true,"pyQName":"net.Socket.set_timeout"},"net.Socket.readLine":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"net.Socket.read_line"},"net.Net":{"kind":8,"retType":"net.Net","extendsTypes":[]},"net.Net.__constructor":{"kind":-3,"parameters":[{"name":"factory","type":"() => net.Controller","handlerParameters":[]}],"isInstance":true},"net.Net.instance":{"kind":2,"retType":"net.Net"},"net.Net.controller":{"kind":-2,"retType":"net.Controller","isInstance":true,"isReadOnly":true},"net.Net.scanNetworks":{"kind":-1,"retType":"net.AccessPoint[]","attributes":{"jsDoc":"Scan for APs"},"parameters":[],"isInstance":true,"pyQName":"net.Net.scan_networks"},"net.Net.createSocket":{"kind":-1,"retType":"net.Socket","parameters":[{"name":"host","type":"string"},{"name":"port"},{"name":"secure","type":"boolean"}],"isInstance":true,"pyQName":"net.Net.create_socket"},"net.Net.hostByName":{"kind":-1,"retType":"string","parameters":[{"name":"host","type":"string"}],"isInstance":true,"pyQName":"net.Net.host_by_name"},"net.instance":{"kind":-3,"retType":"net.Net","attributes":{"jsDoc":"Gets the current Net instance"},"parameters":[]},"net.knownAccessPoints":{"kind":-3,"retType":"StringMap","attributes":{"jsDoc":"Gets the map of SSID -> password pairs"},"parameters":[],"pyQName":"net.known_access_points"},"net.clearAccessPoint":{"kind":-3,"parameters":[{"name":"ssid","type":"string"}],"pyQName":"net.clear_access_point"},"net.updateAccessPoint":{"kind":-3,"parameters":[{"name":"ssid","type":"string"},{"name":"password","type":"string"}],"pyQName":"net.update_access_point"},"net.setAccessPointPriority":{"kind":-3,"parameters":[{"name":"ssid","type":"string"},{"name":"pri"}],"pyQName":"net.set_access_point_priority"},"net.accessPointPriorities":{"kind":-3,"retType":"any","parameters":[],"pyQName":"net.access_point_priorities"},"net.clearAccessPoints":{"kind":-3,"parameters":[],"pyQName":"net.clear_access_points"},"net.urlencode":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"}]},"net.urldecode":{"kind":-3,"retType":"string","parameters":[{"name":"s","type":"string"}]},"net.ping":{"kind":-3,"retType":"number","attributes":{"blockId":"netping","block":"net ping $dest","paramHelp":{"dest":"host name","ttl":""},"jsDoc":"Pings a web site","_def":{"parts":[{"kind":"label","text":"net ping ","style":[]},{"kind":"param","name":"dest","ref":true}],"parameters":[{"kind":"param","name":"dest","ref":true}]}},"parameters":[{"name":"dest","description":"host name","type":"string"},{"name":"ttl","initializer":"250"}]},"net.Response":{"kind":8,"retType":"net.Response","extendsTypes":[]},"net.Response._cached":{"kind":2,"retType":"Buffer","isInstance":true},"net.Response.status_code":{"kind":2,"retType":"number","isInstance":true},"net.Response.reason":{"kind":2,"retType":"string","isInstance":true},"net.Response._read_so_far":{"kind":2,"retType":"number","isInstance":true},"net.Response.headers":{"kind":2,"retType":"StringMap","isInstance":true},"net.Response.__constructor":{"kind":-3,"attributes":{"jsDoc":"The response from a request, contains all the headers/content"},"parameters":[{"name":"socket","type":"net.Socket"}],"isInstance":true},"net.Response.close":{"kind":-1,"attributes":{"jsDoc":"Close, delete and collect the response data"},"parameters":[],"isInstance":true},"net.Response.content":{"kind":-2,"retType":"Buffer","attributes":{"jsDoc":"The HTTP content direct from the socket, as bytes"},"isInstance":true,"isReadOnly":true},"net.Response.text":{"kind":-2,"retType":"string","attributes":{"jsDoc":"The HTTP content, encoded into a string according to the HTTP header encoding"},"isInstance":true,"isReadOnly":true},"net.Response.json":{"kind":-2,"retType":"any","isInstance":true,"isReadOnly":true},"net.Response.toString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"net.Response.to_string"},"net.RequestOptions":{"kind":9,"retType":"net.RequestOptions","extendsTypes":[]},"net.RequestOptions.data":{"kind":2,"retType":"string | Buffer","isInstance":true},"net.RequestOptions.json":{"kind":2,"retType":"any","isInstance":true},"net.RequestOptions.headers":{"kind":2,"retType":"StringMap","isInstance":true},"net.RequestOptions.stream":{"kind":2,"retType":"boolean","isInstance":true},"net.RequestOptions.timeout":{"kind":2,"retType":"number","isInstance":true},"net.dataAsBuffer":{"kind":-3,"retType":"Buffer","parameters":[{"name":"data","type":"string | Buffer"}],"pyQName":"net.data_as_buffer"},"net.request":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Perform an HTTP request to the given url which we will parse to determine\nwhether to use SSL ('https://') or not. We can also send some provided 'data'\nor a json dictionary which we will stringify. 'headers' is optional HTTP headers\nsent along. 'stream' will determine if we buffer everything, or whether to only\nread only when requested"},"parameters":[{"name":"method","type":"string"},{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.head":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP HEAD request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.get":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP GET request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.getString":{"kind":-3,"retType":"string","attributes":{"blockId":"netgetstring","block":"get string $url","jsDoc":"Send HTTP GET request and return text","_def":{"parts":[{"kind":"label","text":"get string ","style":[]},{"kind":"param","name":"url","ref":true}],"parameters":[{"kind":"param","name":"url","ref":true}]}},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}],"pyQName":"net.get_string"},"net.getJSON":{"kind":-3,"retType":"any","attributes":{"blockId":"netgetjson","block":"get json $url","jsDoc":"Send HTTP GET request and return JSON","_def":{"parts":[{"kind":"label","text":"get json ","style":[]},{"kind":"param","name":"url","ref":true}],"parameters":[{"kind":"param","name":"url","ref":true}]}},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}],"pyQName":"net.get_json"},"net.post":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP POST request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.patch":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP PATCH request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.put":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP PUT request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]},"net.del":{"kind":-3,"retType":"net.Response","attributes":{"jsDoc":"Send HTTP DELETE request"},"parameters":[{"name":"url","type":"string"},{"name":"options","type":"net.RequestOptions","initializer":"undefined"}]}}},"sha":"242ffe2eb44c5d2e5eb255b2dabc6407d444e0c588093a38469299994aa21be0"},"libs/palette":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"Colors":{"kind":6,"retType":"Colors","attributes":{"jsDoc":"Well known colors"},"extendsTypes":["Colors","Number"]},"Colors.Red":{"retType":"Colors.Red","attributes":{"block":"red","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"red","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Red","Number"],"pyQName":"Colors.RED"},"Colors.Orange":{"retType":"Colors.Orange","attributes":{"block":"orange","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"orange","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Orange","Number"],"pyQName":"Colors.ORANGE"},"Colors.Yellow":{"retType":"Colors.Yellow","attributes":{"block":"yellow","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"yellow","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Yellow","Number"],"pyQName":"Colors.YELLOW"},"Colors.Green":{"retType":"Colors.Green","attributes":{"block":"green","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"green","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Green","Number"],"pyQName":"Colors.GREEN"},"Colors.Blue":{"retType":"Colors.Blue","attributes":{"block":"blue","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"blue","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Blue","Number"],"pyQName":"Colors.BLUE"},"Colors.Indigo":{"retType":"Colors.Indigo","attributes":{"block":"indigo","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"indigo","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Indigo","Number"],"pyQName":"Colors.INDIGO"},"Colors.Violet":{"retType":"Colors.Violet","attributes":{"block":"violet","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"violet","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Violet","Number"],"pyQName":"Colors.VIOLET"},"Colors.Purple":{"retType":"Colors.Purple","attributes":{"block":"purple","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"purple","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Purple","Number"],"pyQName":"Colors.PURPLE"},"Colors.Pink":{"retType":"Colors.Pink","attributes":{"block":"pink","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"pink","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Pink","Number"],"pyQName":"Colors.PINK"},"Colors.White":{"retType":"Colors.White","attributes":{"block":"white","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"white","style":[]}],"parameters":[]}},"extendsTypes":["Colors.White","Number"],"pyQName":"Colors.WHITE"},"Colors.Black":{"retType":"Colors.Black","attributes":{"block":"black","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"black","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Black","Number"],"pyQName":"Colors.BLACK"},"ColorHues":{"kind":6,"retType":"ColorHues","attributes":{"jsDoc":"Well known color hues"},"extendsTypes":["ColorHues","Number"]},"ColorHues.Red":{"retType":"ColorHues.Red","attributes":{"block":"red","_def":{"parts":[{"kind":"label","text":"red","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Red","Number"],"pyQName":"ColorHues.RED"},"ColorHues.Orange":{"retType":"ColorHues.Orange","attributes":{"block":"orange","_def":{"parts":[{"kind":"label","text":"orange","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Orange","Number"],"pyQName":"ColorHues.ORANGE"},"ColorHues.Yellow":{"retType":"ColorHues.Yellow","attributes":{"block":"yellow","_def":{"parts":[{"kind":"label","text":"yellow","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Yellow","Number"],"pyQName":"ColorHues.YELLOW"},"ColorHues.Green":{"retType":"ColorHues.Green","attributes":{"block":"green","_def":{"parts":[{"kind":"label","text":"green","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Green","Number"],"pyQName":"ColorHues.GREEN"},"ColorHues.Aqua":{"retType":"ColorHues.Aqua","attributes":{"block":"aqua","_def":{"parts":[{"kind":"label","text":"aqua","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Aqua","Number"],"pyQName":"ColorHues.AQUA"},"ColorHues.Blue":{"retType":"ColorHues.Blue","attributes":{"block":"blue","_def":{"parts":[{"kind":"label","text":"blue","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Blue","Number"],"pyQName":"ColorHues.BLUE"},"ColorHues.Purple":{"retType":"ColorHues.Purple","attributes":{"block":"purple","_def":{"parts":[{"kind":"label","text":"purple","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Purple","Number"],"pyQName":"ColorHues.PURPLE"},"ColorHues.Magenta":{"retType":"ColorHues.Magenta","attributes":{"block":"magenta","_def":{"parts":[{"kind":"label","text":"magenta","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Magenta","Number"],"pyQName":"ColorHues.MAGENTA"},"ColorHues.Pink":{"retType":"ColorHues.Pink","attributes":{"block":"pink","_def":{"parts":[{"kind":"label","text":"pink","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Pink","Number"],"pyQName":"ColorHues.PINK"},"color":{"kind":5,"retType":"","attributes":{"advanced":true,"jsDoc":"Color manipulation"}},"color.rgb":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"red":"255","green":"255","blue":"255"},"blockId":"colorsrgb","block":"red %red|green %green|blue %blue","paramMin":{"red":"0","green":"0","blue":"0"},"paramMax":{"red":"255","green":"255","blue":"255"},"help":"colors/rgb","weight":19,"blockGap":"8","blockHidden":true,"paramHelp":{"red":"value of the red channel between 0 and 255. eg: 255","green":"value of the green channel between 0 and 255. eg: 255","blue":"value of the blue channel between 0 and 255. eg: 255"},"jsDoc":"Converts red, green, blue channels into a RGB color","_def":{"parts":[{"kind":"label","text":"red ","style":[]},{"kind":"param","name":"red","ref":false},{"kind":"break"},{"kind":"label","text":"green ","style":[]},{"kind":"param","name":"green","ref":false},{"kind":"break"},{"kind":"label","text":"blue ","style":[]},{"kind":"param","name":"blue","ref":false}],"parameters":[{"kind":"param","name":"red","ref":false},{"kind":"param","name":"green","ref":false},{"kind":"param","name":"blue","ref":false}]}},"parameters":[{"name":"red","description":"value of the red channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"green","description":"value of the green channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"blue","description":"value of the blue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.argb":{"kind":-3,"retType":"number","parameters":[{"name":"alpha"},{"name":"red"},{"name":"green"},{"name":"blue"}]},"color.wellKnown":{"kind":-3,"retType":"number","attributes":{"blockId":"colorscolors","block":"%color","help":"colors/well-known","shim":"TD_ID","weight":20,"blockGap":"8","blockHidden":true,"jsDoc":"Get the RGB value of a known color","_def":{"parts":[{"kind":"param","name":"color","ref":false}],"parameters":[{"kind":"param","name":"color","ref":false}]}},"parameters":[{"name":"color","type":"Colors","isEnum":true}],"pyQName":"color.well_known"},"color.hsv":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"hue":"255","sat":"255","val":"255"},"blockId":"colorshsv","block":"hue %hue|sat %sat|val %val","paramMin":{"hue":"0","sat":"0","val":"0"},"paramMax":{"hue":"255","sat":"255","val":"255"},"help":"colors/hsv","weight":17,"blockHidden":true,"paramHelp":{"hue":"value of the hue channel between 0 and 255. eg: 255","sat":"value of the saturation channel between 0 and 255. eg: 255","val":"value of the value channel between 0 and 255. eg: 255"},"jsDoc":"Convert an HSV (hue, saturation, value) color to RGB","_def":{"parts":[{"kind":"label","text":"hue ","style":[]},{"kind":"param","name":"hue","ref":false},{"kind":"break"},{"kind":"label","text":"sat ","style":[]},{"kind":"param","name":"sat","ref":false},{"kind":"break"},{"kind":"label","text":"val ","style":[]},{"kind":"param","name":"val","ref":false}],"parameters":[{"kind":"param","name":"hue","ref":false},{"kind":"param","name":"sat","ref":false},{"kind":"param","name":"val","ref":false}]}},"parameters":[{"name":"hue","description":"value of the hue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"sat","description":"value of the saturation channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"val","description":"value of the value channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.fade":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"brightness":"128"},"blockId":"colorsfade","block":"fade %color=neopixel_colors|by %brightness","paramMin":{"brightness":"0"},"paramMax":{"brightness":"255"},"help":"light/fade","group":"Color","weight":18,"blockGap":"8","blockHidden":true,"paramHelp":{"color":"color to fade","brightness":"the amount of brightness to apply to the color, eg: 128"},"jsDoc":"Fade the color by the brightness","_def":{"parts":[{"kind":"label","text":"fade ","style":[]},{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"break"},{"kind":"label","text":"by ","style":[]},{"kind":"param","name":"brightness","ref":false}],"parameters":[{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"param","name":"brightness","ref":false}]}},"parameters":[{"name":"color","description":"color to fade"},{"name":"brightness","description":"the amount of brightness to apply to the color, eg: 128","default":"128","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.blend":{"kind":-3,"retType":"number","parameters":[{"name":"color"},{"name":"alpha"},{"name":"otherColor"}]},"color.gradient":{"kind":-3,"retType":"color.ColorBuffer","parameters":[{"name":"startColor"},{"name":"endColor"},{"name":"steps"}]},"color.unpackR":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_r"},"color.unpackG":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_g"},"color.unpackB":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_b"},"color.parseColor":{"kind":-3,"retType":"number","parameters":[{"name":"color","type":"string"}],"pyQName":"color.parse_color"},"color.ColorBufferLayout":{"kind":6,"retType":"color.ColorBufferLayout","extendsTypes":["color.ColorBufferLayout","Number"]},"color.ColorBufferLayout.RGB":{"retType":"color.ColorBufferLayout.RGB","attributes":{"jsDoc":"24bit RGB color"},"extendsTypes":["color.ColorBufferLayout.RGB","Number"]},"color.ColorBufferLayout.ARGB":{"retType":"color.ColorBufferLayout.ARGB","attributes":{"jsDoc":"32bit RGB color with alpha"},"extendsTypes":["color.ColorBufferLayout.ARGB","Number"]},"color.ColorBuffer":{"kind":8,"retType":"color.ColorBuffer","attributes":{"jsDoc":"A buffer of colors"},"extendsTypes":[]},"color.ColorBuffer.layout":{"kind":2,"retType":"color.ColorBufferLayout","isInstance":true},"color.ColorBuffer.buf":{"kind":2,"retType":"Buffer","isInstance":true},"color.ColorBuffer.__constructor":{"kind":-3,"parameters":[{"name":"length"},{"name":"layout","type":"color.ColorBufferLayout","initializer":"undefined","isEnum":true}],"isInstance":true},"color.ColorBuffer.fromBuffer":{"kind":-1,"retType":"color.ColorBuffer","parameters":[{"name":"buffer","type":"Buffer"},{"name":"layout","type":"color.ColorBufferLayout","isEnum":true}],"pyQName":"color.ColorBuffer.from_buffer"},"color.ColorBuffer.stride":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"color.ColorBuffer.length":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"color.ColorBuffer.color":{"kind":-1,"retType":"number","parameters":[{"name":"index"}],"isInstance":true},"color.ColorBuffer.setColor":{"kind":-1,"parameters":[{"name":"index"},{"name":"color"}],"isInstance":true,"pyQName":"color.ColorBuffer.set_color"},"color.ColorBuffer.slice":{"kind":-1,"retType":"color.ColorBuffer","parameters":[{"name":"start","initializer":"undefined"},{"name":"length","initializer":"undefined"}],"isInstance":true},"color.ColorBuffer.write":{"kind":-1,"attributes":{"paramHelp":{"dstOffset":"@param src"},"jsDoc":"Writes the content of the src color buffer starting at the start dstOffset in the current buffer"},"parameters":[{"name":"dstOffset","description":"@param src"},{"name":"src","type":"color.ColorBuffer"}],"isInstance":true},"color.createBuffer":{"kind":-3,"retType":"color.ColorBuffer","attributes":{"jsDoc":"Converts an array of colors into a color buffer"},"parameters":[{"name":"colors","type":"number[]"},{"name":"layout","type":"color.ColorBufferLayout","initializer":"undefined","isEnum":true}],"pyQName":"color.create_buffer"},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"palette":{"kind":5,"retType":"","attributes":{"jsDoc":"Update the current scene palette"}},"palette.defaultPalette":{"kind":-3,"retType":"color.ColorBuffer","attributes":{"jsDoc":"Returns a clone of the default palette"},"parameters":[],"pyQName":"palette.default_palette"},"palette.setColors":{"kind":-3,"attributes":{"paramHelp":{"pOffset":"The offset to start copying from the palette"},"jsDoc":"Dynamically set all or part of the game's current palette\n* @param palette The colors to set"},"parameters":[{"name":"palette","type":"color.ColorBuffer"},{"name":"pOffset","description":"The offset to start copying from the palette","initializer":"0"}],"pyQName":"palette.set_colors"},"palette.getCurrentColors":{"kind":-3,"retType":"color.ColorBuffer","attributes":{"jsDoc":"Get the palette that is currently being used"},"parameters":[],"pyQName":"palette.get_current_colors"},"palette.reset":{"kind":-3,"attributes":{"jsDoc":"Reset to default palette"},"parameters":[]}}},"sha":"7d28294f27e026e5355dc0b51b88b4cf298ab5b9bbb7af197f4bc3c625942882"},"libs/power":{"apis":{"byQName":{}},"sha":"282d26e9b27337444d78fa58e259850bf4b5ed9f68c3bb7710f6822b51bcb93f"},"libs/radio":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"radio":{"kind":5,"retType":"","attributes":{"color":"#E3008C","weight":96,"icon":"","groups":["Group","Broadcast","Send","Receive"],"jsDoc":"Communicate data using radio packets"}},"radio.off":{"kind":-3,"attributes":{"help":"radio/off","jsDoc":"Disables the radio for use as a multipoint sender/receiver.\nDisabling radio will help conserve battery power when it is not in use."},"parameters":[]},"radio.on":{"kind":-3,"attributes":{"help":"radio/on","jsDoc":"Initialises the radio for use as a multipoint sender/receiver\nOnly useful when the radio.off() is used beforehand."},"parameters":[]},"radio.raiseEvent":{"kind":-3,"attributes":{"blockId":"radioRaiseEvent","block":"radio raise event|from source %src=control_event_source_id|with value %value=control_event_value_id","blockExternalInputs":"1","advanced":true,"weight":1,"help":"radio/raise-event","inlineInputMode":"external","jsDoc":"Sends an event over radio to neigboring devices","_def":{"parts":[{"kind":"label","text":"radio raise event","style":[]},{"kind":"break"},{"kind":"label","text":"from source ","style":[]},{"kind":"param","name":"src","shadowBlockId":"control_event_source_id","ref":false},{"kind":"break"},{"kind":"label","text":"with value ","style":[]},{"kind":"param","name":"value","shadowBlockId":"control_event_value_id","ref":false}],"parameters":[{"kind":"param","name":"src","shadowBlockId":"control_event_source_id","ref":false},{"kind":"param","name":"value","shadowBlockId":"control_event_value_id","ref":false}]}},"parameters":[{"name":"src"},{"name":"value"}],"pyQName":"radio.raise_event"},"radio.readRawPacket":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"Internal use only. Takes the next packet from the radio queue and returns its contents + RSSI in a Buffer.\n@returns NULL if no packet available"},"parameters":[],"pyQName":"radio.read_raw_packet"},"radio.sendRawPacket":{"kind":-3,"attributes":{"callingConvention":1,"async":"true","jsDoc":"Internal use only. Sends a raw packet through the radio (assumes RSSI appened to packet)"},"parameters":[{"name":"msg","type":"Buffer"}],"pyQName":"radio.send_raw_packet"},"radio.onDataReceived":{"kind":-3,"attributes":{"help":"radio/on-data-received","weight":0,"blockId":"radio_datagram_received_event","block":"radio on data received","blockGap":"8","deprecated":"true","blockHidden":true,"jsDoc":"Used internally by the library.","_def":{"parts":[{"kind":"label","text":"radio on data received","style":[]}],"parameters":[]}},"parameters":[{"name":"body","type":"() => void","handlerParameters":[]}],"pyQName":"radio.on_data_received"},"radio.setGroup":{"kind":-3,"attributes":{"paramDefl":{"id":"1"},"help":"radio/set-group","weight":100,"blockId":"radio_set_group","block":"radio set group %ID","paramMin":{"id":"0"},"paramMax":{"id":"255"},"group":"Group","paramHelp":{"id":"the group id between ``0`` and ``255``, eg: 1"},"jsDoc":"Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time.","_def":{"parts":[{"kind":"label","text":"radio set group ","style":[]},{"kind":"param","name":"ID","ref":false}],"parameters":[{"kind":"param","name":"ID","ref":false}]}},"parameters":[{"name":"id","description":"the group id between ``0`` and ``255``, eg: 1","default":"1","options":{"min":{"value":"0"},"max":{"value":"255"}}}],"pyQName":"radio.set_group"},"radio.setTransmitPower":{"kind":-3,"attributes":{"paramDefl":{"power":"7"},"help":"radio/set-transmit-power","weight":9,"blockGap":"8","blockId":"radio_set_transmit_power","block":"radio set transmit power %power","paramMin":{"power":"0"},"paramMax":{"power":"7"},"advanced":true,"paramHelp":{"power":"a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7"},"jsDoc":"Change the output power level of the transmitter to the given value.","_def":{"parts":[{"kind":"label","text":"radio set transmit power ","style":[]},{"kind":"param","name":"power","ref":false}],"parameters":[{"kind":"param","name":"power","ref":false}]}},"parameters":[{"name":"power","description":"a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7","default":"7","options":{"min":{"value":"0"},"max":{"value":"7"}}}],"pyQName":"radio.set_transmit_power"},"radio.setFrequencyBand":{"kind":-3,"attributes":{"help":"radio/set-frequency-band","weight":8,"blockGap":"8","blockId":"radio_set_frequency_band","block":"radio set frequency band %band","paramMin":{"band":"0"},"paramMax":{"band":"83"},"advanced":true,"paramHelp":{"band":"a frequency band in the range 0 - 83. Each step is 1MHz wide, based at 2400MHz."},"jsDoc":"Change the transmission and reception band of the radio to the given channel","_def":{"parts":[{"kind":"label","text":"radio set frequency band ","style":[]},{"kind":"param","name":"band","ref":false}],"parameters":[{"kind":"param","name":"band","ref":false}]}},"parameters":[{"name":"band","description":"a frequency band in the range 0 - 83. Each step is 1MHz wide, based at 2400MHz.","options":{"min":{"value":"0"},"max":{"value":"83"}}}],"pyQName":"radio.set_frequency_band"},"RadioPacketProperty":{"kind":6,"retType":"RadioPacketProperty","extendsTypes":["RadioPacketProperty","Number"]},"RadioPacketProperty.SignalStrength":{"retType":"RadioPacketProperty.SignalStrength","attributes":{"blockIdentity":"radio._packetProperty","block":"signal strength","_def":{"parts":[{"kind":"label","text":"signal strength","style":[]}],"parameters":[]}},"extendsTypes":["RadioPacketProperty.SignalStrength","Number"],"pyQName":"RadioPacketProperty.SIGNAL_STRENGTH"},"RadioPacketProperty.Time":{"retType":"RadioPacketProperty.Time","attributes":{"blockIdentity":"radio._packetProperty","block":"time","_def":{"parts":[{"kind":"label","text":"time","style":[]}],"parameters":[]}},"extendsTypes":["RadioPacketProperty.Time","Number"],"pyQName":"RadioPacketProperty.TIME"},"RadioPacketProperty.SerialNumber":{"retType":"RadioPacketProperty.SerialNumber","attributes":{"block":"serial number","blockIdentity":"radio._packetProperty","_def":{"parts":[{"kind":"label","text":"serial number","style":[]}],"parameters":[]}},"extendsTypes":["RadioPacketProperty.SerialNumber","Number"],"pyQName":"RadioPacketProperty.SERIAL_NUMBER"},"radio.PACKET_TYPE_NUMBER":{"kind":4,"retType":"number"},"radio.PACKET_TYPE_VALUE":{"kind":4,"retType":"number"},"radio.PACKET_TYPE_STRING":{"kind":4,"retType":"number"},"radio.PACKET_TYPE_BUFFER":{"kind":4,"retType":"number"},"radio.PACKET_TYPE_DOUBLE":{"kind":4,"retType":"number"},"radio.PACKET_TYPE_DOUBLE_VALUE":{"kind":4,"retType":"number"},"radio.lastPacket":{"kind":4,"retType":"radio.RadioPacket","pyQName":"radio.last_packet"},"radio.onReceivedNumber":{"kind":-3,"attributes":{"help":"radio/on-received-number","blockId":"radio_on_number_drag","block":"on radio received","blockGap":"16","useLoc":"radio.onDataPacketReceived","draggableParameters":"reporter","group":"Receive","weight":20,"jsDoc":"Registers code to run when the radio receives a number.","_def":{"parts":[{"kind":"label","text":"on radio received","style":[]}],"parameters":[]}},"parameters":[{"name":"cb","type":"(receivedNumber: number) => void","handlerParameters":[{"name":"receivedNumber","type":"number"}]}],"pyQName":"radio.on_received_number"},"radio.onReceivedValue":{"kind":-3,"attributes":{"help":"radio/on-received-value","blockId":"radio_on_value_drag","block":"on radio received","blockGap":"16","useLoc":"radio.onDataPacketReceived","draggableParameters":"reporter","group":"Receive","weight":19,"jsDoc":"Registers code to run when the radio receives a key value pair.","_def":{"parts":[{"kind":"label","text":"on radio received","style":[]}],"parameters":[]}},"parameters":[{"name":"cb","type":"(name: string, value: number) => void","handlerParameters":[{"name":"name","type":"string"},{"name":"value","type":"number"}]}],"pyQName":"radio.on_received_value"},"radio.onReceivedString":{"kind":-3,"attributes":{"help":"radio/on-received-string","blockId":"radio_on_string_drag","block":"on radio received","blockGap":"16","useLoc":"radio.onDataPacketReceived","draggableParameters":"reporter","group":"Receive","weight":18,"jsDoc":"Registers code to run when the radio receives a string.","_def":{"parts":[{"kind":"label","text":"on radio received","style":[]}],"parameters":[]}},"parameters":[{"name":"cb","type":"(receivedString: string) => void","handlerParameters":[{"name":"receivedString","type":"string"}]}],"pyQName":"radio.on_received_string"},"radio.onReceivedBuffer":{"kind":-3,"attributes":{"help":"radio/on-received-buffer","blockHidden":true,"blockId":"radio_on_buffer_drag","block":"on radio received","blockGap":"16","useLoc":"radio.onDataPacketReceived","draggableParameters":"reporter","jsDoc":"Registers code to run when the radio receives a buffer.","_def":{"parts":[{"kind":"label","text":"on radio received","style":[]}],"parameters":[]}},"parameters":[{"name":"cb","type":"(receivedBuffer: Buffer) => void","handlerParameters":[{"name":"receivedBuffer","type":"Buffer"}]}],"pyQName":"radio.on_received_buffer"},"radio.receivedPacket":{"kind":-3,"retType":"number","attributes":{"help":"radio/received-packet","blockGap":"16","blockId":"radio_received_packet","block":"received packet %type=radio_packet_property","group":"Receive","weight":16,"paramHelp":{"type":"the type of property to retrieve from the last packet"},"jsDoc":"Returns properties of the last radio packet received.","_def":{"parts":[{"kind":"label","text":"received packet ","style":[]},{"kind":"param","name":"type","shadowBlockId":"radio_packet_property","ref":false}],"parameters":[{"kind":"param","name":"type","shadowBlockId":"radio_packet_property","ref":false}]}},"parameters":[{"name":"type","description":"the type of property to retrieve from the last packet"}],"pyQName":"radio.received_packet"},"radio._packetProperty":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"type":"PacketProperty.time"},"blockId":"radio_packet_property","block":"%note","shim":"TD_ID","blockHidden":true,"paramHelp":{"type":"the packet property type, eg: PacketProperty.time"},"jsDoc":"Gets a packet property.","_def":{"parts":[{"kind":"param","name":"note","ref":false}],"parameters":[{"kind":"param","name":"note","ref":false}]}},"parameters":[{"name":"type","description":"the packet property type, eg: PacketProperty.time","type":"RadioPacketProperty","default":"PacketProperty.time","isEnum":true}],"pyQName":"radio._packet_property"},"radio.RadioPacket":{"kind":8,"retType":"radio.RadioPacket","extendsTypes":[]},"radio.RadioPacket.getPacket":{"kind":-1,"retType":"radio.RadioPacket","parameters":[{"name":"data","type":"Buffer"}],"pyQName":"radio.RadioPacket.get_packet"},"radio.RadioPacket.mkPacket":{"kind":-1,"retType":"radio.RadioPacket","parameters":[{"name":"packetType"}],"pyQName":"radio.RadioPacket.mk_packet"},"radio.RadioPacket.signal":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"radio.RadioPacket.packetType":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"radio.RadioPacket.packet_type"},"radio.RadioPacket.time":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"radio.RadioPacket.time@set":{"kind":-2,"retType":"number","isInstance":true},"radio.RadioPacket.serial":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"radio.RadioPacket.serial@set":{"kind":-2,"retType":"number","isInstance":true},"radio.RadioPacket.stringPayload":{"kind":-2,"retType":"string","isInstance":true,"isReadOnly":true,"pyQName":"radio.RadioPacket.string_payload"},"radio.RadioPacket.stringPayload@set":{"kind":-2,"retType":"string","isInstance":true,"pyQName":"radio.RadioPacket.string_payload@set"},"radio.RadioPacket.numberPayload":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"radio.RadioPacket.number_payload"},"radio.RadioPacket.numberPayload@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"radio.RadioPacket.number_payload@set"},"radio.RadioPacket.bufferPayload":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"radio.RadioPacket.buffer_payload"},"radio.RadioPacket.bufferPayload@set":{"kind":-2,"retType":"Buffer","isInstance":true,"pyQName":"radio.RadioPacket.buffer_payload@set"},"radio.RadioPacket.hasString":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"radio.RadioPacket.has_string"},"radio.RadioPacket.hasNumber":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"radio.RadioPacket.has_number"},"radio.sendNumber":{"kind":-3,"attributes":{"help":"radio/send-number","weight":60,"blockId":"radio_datagram_send","block":"radio send number %value","blockGap":"8","group":"Send","jsDoc":"Broadcasts a number over radio to any connected micro:bit in the group.","_def":{"parts":[{"kind":"label","text":"radio send number ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value"}],"pyQName":"radio.send_number"},"radio.sendValue":{"kind":-3,"attributes":{"paramDefl":{"name":"name"},"help":"radio/send-value","weight":59,"blockId":"radio_datagram_send_value","block":"radio send|value %name|= %value","blockGap":"8","group":"Send","paramHelp":{"name":"the field name (max 8 characters), eg: \"name\"","value":"the numeric value"},"jsDoc":"Broadcasts a name / value pair along with the device serial number\nand running time to any connected micro:bit in the group. The name can\ninclude no more than 8 characters.","_def":{"parts":[{"kind":"label","text":"radio send","style":[]},{"kind":"break"},{"kind":"label","text":"value ","style":[]},{"kind":"param","name":"name","ref":false},{"kind":"break"},{"kind":"label","text":"= ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"name","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"name","description":"the field name (max 8 characters), eg: \"name\"","type":"string","default":"name"},{"name":"value","description":"the numeric value"}],"pyQName":"radio.send_value"},"radio.sendString":{"kind":-3,"attributes":{"help":"radio/send-string","weight":58,"blockId":"radio_datagram_send_string","block":"radio send string %msg","paramShadowOptions":{"msg":{"toString":"true"}},"group":"Send","jsDoc":"Broadcasts a string along with the device serial number\nand running time to any connected micro:bit in the group.","_def":{"parts":[{"kind":"label","text":"radio send string ","style":[]},{"kind":"param","name":"msg","ref":false}],"parameters":[{"kind":"param","name":"msg","ref":false}]}},"parameters":[{"name":"value","type":"string","options":{"fieldEditorOptions":{"value":{"toString":"true"}}}}],"pyQName":"radio.send_string"},"radio.sendBuffer":{"kind":-3,"attributes":{"help":"radio/send-buffer","weight":57,"advanced":true,"jsDoc":"Broadcasts a buffer (up to 19 bytes long) along with the device serial number\nand running time to any connected micro:bit in the group."},"parameters":[{"name":"msg","type":"Buffer"}],"pyQName":"radio.send_buffer"},"radio.setTransmitSerialNumber":{"kind":-3,"attributes":{"paramDefl":{"transmit":"true"},"help":"radio/set-transmit-serial-number","weight":8,"blockGap":"8","blockId":"radio_set_transmit_serial_number","block":"radio set transmit serial number %transmit","advanced":true,"paramHelp":{"transmit":"value indicating if the serial number is transmitted, eg: true"},"jsDoc":"Set the radio to transmit the serial number in each message.","_def":{"parts":[{"kind":"label","text":"radio set transmit serial number ","style":[]},{"kind":"param","name":"transmit","ref":false}],"parameters":[{"kind":"param","name":"transmit","ref":false}]}},"parameters":[{"name":"transmit","description":"value indicating if the serial number is transmitted, eg: true","type":"boolean","default":"true"}],"pyQName":"radio.set_transmit_serial_number"}}},"sha":"7e8eccca4b1d073e633b3efba6c2968e4140f429a6dac248d468ba95b470daad"},"libs/radio-broadcast":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"radio":{"kind":5,"retType":"","attributes":{"color":"#E3008C","weight":96,"icon":"","groups":["Group","Broadcast","Send","Receive"],"jsDoc":"Communicate data using radio packets"}},"radio.off":{"kind":-3,"attributes":{"help":"radio/off","jsDoc":"Disables the radio for use as a multipoint sender/receiver.\nDisabling radio will help conserve battery power when it is not in use."},"parameters":[]},"radio.on":{"kind":-3,"attributes":{"help":"radio/on","jsDoc":"Initialises the radio for use as a multipoint sender/receiver\nOnly useful when the radio.off() is used beforehand."},"parameters":[]},"radio.raiseEvent":{"kind":-3,"attributes":{"blockId":"radioRaiseEvent","block":"radio raise event|from source %src=control_event_source_id|with value %value=control_event_value_id","blockExternalInputs":"1","advanced":true,"weight":1,"help":"radio/raise-event","inlineInputMode":"external","jsDoc":"Sends an event over radio to neigboring devices","_def":{"parts":[{"kind":"label","text":"radio raise event","style":[]},{"kind":"break"},{"kind":"label","text":"from source ","style":[]},{"kind":"param","name":"src","shadowBlockId":"control_event_source_id","ref":false},{"kind":"break"},{"kind":"label","text":"with value ","style":[]},{"kind":"param","name":"value","shadowBlockId":"control_event_value_id","ref":false}],"parameters":[{"kind":"param","name":"src","shadowBlockId":"control_event_source_id","ref":false},{"kind":"param","name":"value","shadowBlockId":"control_event_value_id","ref":false}]}},"parameters":[{"name":"src"},{"name":"value"}],"pyQName":"radio.raise_event"},"radio.readRawPacket":{"kind":-3,"retType":"Buffer","attributes":{"jsDoc":"Internal use only. Takes the next packet from the radio queue and returns its contents + RSSI in a Buffer.\n@returns NULL if no packet available"},"parameters":[],"pyQName":"radio.read_raw_packet"},"radio.sendRawPacket":{"kind":-3,"attributes":{"callingConvention":1,"async":"true","jsDoc":"Internal use only. Sends a raw packet through the radio (assumes RSSI appened to packet)"},"parameters":[{"name":"msg","type":"Buffer"}],"pyQName":"radio.send_raw_packet"},"radio.onDataReceived":{"kind":-3,"attributes":{"help":"radio/on-data-received","weight":0,"blockId":"radio_datagram_received_event","block":"radio on data received","blockGap":"8","deprecated":"true","blockHidden":true,"jsDoc":"Used internally by the library.","_def":{"parts":[{"kind":"label","text":"radio on data received","style":[]}],"parameters":[]}},"parameters":[{"name":"body","type":"() => void","handlerParameters":[]}],"pyQName":"radio.on_data_received"},"radio.setGroup":{"kind":-3,"attributes":{"paramDefl":{"id":"1"},"help":"radio/set-group","weight":100,"blockId":"radio_set_group","block":"radio set group %ID","paramMin":{"id":"0"},"paramMax":{"id":"255"},"group":"Group","paramHelp":{"id":"the group id between ``0`` and ``255``, eg: 1"},"jsDoc":"Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time.","_def":{"parts":[{"kind":"label","text":"radio set group ","style":[]},{"kind":"param","name":"ID","ref":false}],"parameters":[{"kind":"param","name":"ID","ref":false}]}},"parameters":[{"name":"id","description":"the group id between ``0`` and ``255``, eg: 1","default":"1","options":{"min":{"value":"0"},"max":{"value":"255"}}}],"pyQName":"radio.set_group"},"radio.setTransmitPower":{"kind":-3,"attributes":{"paramDefl":{"power":"7"},"help":"radio/set-transmit-power","weight":9,"blockGap":"8","blockId":"radio_set_transmit_power","block":"radio set transmit power %power","paramMin":{"power":"0"},"paramMax":{"power":"7"},"advanced":true,"paramHelp":{"power":"a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7"},"jsDoc":"Change the output power level of the transmitter to the given value.","_def":{"parts":[{"kind":"label","text":"radio set transmit power ","style":[]},{"kind":"param","name":"power","ref":false}],"parameters":[{"kind":"param","name":"power","ref":false}]}},"parameters":[{"name":"power","description":"a value in the range 0..7, where 0 is the lowest power and 7 is the highest. eg: 7","default":"7","options":{"min":{"value":"0"},"max":{"value":"7"}}}],"pyQName":"radio.set_transmit_power"},"radio.setFrequencyBand":{"kind":-3,"attributes":{"help":"radio/set-frequency-band","weight":8,"blockGap":"8","blockId":"radio_set_frequency_band","block":"radio set frequency band %band","paramMin":{"band":"0"},"paramMax":{"band":"83"},"advanced":true,"paramHelp":{"band":"a frequency band in the range 0 - 83. Each step is 1MHz wide, based at 2400MHz."},"jsDoc":"Change the transmission and reception band of the radio to the given channel","_def":{"parts":[{"kind":"label","text":"radio set frequency band ","style":[]},{"kind":"param","name":"band","ref":false}],"parameters":[{"kind":"param","name":"band","ref":false}]}},"parameters":[{"name":"band","description":"a frequency band in the range 0 - 83. Each step is 1MHz wide, based at 2400MHz.","options":{"min":{"value":"0"},"max":{"value":"83"}}}],"pyQName":"radio.set_frequency_band"},"RadioPacketProperty":{"kind":6,"retType":"RadioPacketProperty","extendsTypes":["RadioPacketProperty","Number"]},"RadioPacketProperty.SignalStrength":{"retType":"RadioPacketProperty.SignalStrength","attributes":{"blockIdentity":"radio._packetProperty","block":"signal strength","_def":{"parts":[{"kind":"label","text":"signal strength","style":[]}],"parameters":[]}},"extendsTypes":["RadioPacketProperty.SignalStrength","Number"],"pyQName":"RadioPacketProperty.SIGNAL_STRENGTH"},"RadioPacketProperty.Time":{"retType":"RadioPacketProperty.Time","attributes":{"blockIdentity":"radio._packetProperty","block":"time","_def":{"parts":[{"kind":"label","text":"time","style":[]}],"parameters":[]}},"extendsTypes":["RadioPacketProperty.Time","Number"],"pyQName":"RadioPacketProperty.TIME"},"RadioPacketProperty.SerialNumber":{"retType":"RadioPacketProperty.SerialNumber","attributes":{"block":"serial number","blockIdentity":"radio._packetProperty","_def":{"parts":[{"kind":"label","text":"serial number","style":[]}],"parameters":[]}},"extendsTypes":["RadioPacketProperty.SerialNumber","Number"],"pyQName":"RadioPacketProperty.SERIAL_NUMBER"},"radio.PACKET_TYPE_NUMBER":{"kind":4,"retType":"number"},"radio.PACKET_TYPE_VALUE":{"kind":4,"retType":"number"},"radio.PACKET_TYPE_STRING":{"kind":4,"retType":"number"},"radio.PACKET_TYPE_BUFFER":{"kind":4,"retType":"number"},"radio.PACKET_TYPE_DOUBLE":{"kind":4,"retType":"number"},"radio.PACKET_TYPE_DOUBLE_VALUE":{"kind":4,"retType":"number"},"radio.lastPacket":{"kind":4,"retType":"radio.RadioPacket","pyQName":"radio.last_packet"},"radio.onReceivedNumber":{"kind":-3,"attributes":{"help":"radio/on-received-number","blockId":"radio_on_number_drag","block":"on radio received","blockGap":"16","useLoc":"radio.onDataPacketReceived","draggableParameters":"reporter","group":"Receive","weight":20,"jsDoc":"Registers code to run when the radio receives a number.","_def":{"parts":[{"kind":"label","text":"on radio received","style":[]}],"parameters":[]}},"parameters":[{"name":"cb","type":"(receivedNumber: number) => void","handlerParameters":[{"name":"receivedNumber","type":"number"}]}],"pyQName":"radio.on_received_number"},"radio.onReceivedValue":{"kind":-3,"attributes":{"help":"radio/on-received-value","blockId":"radio_on_value_drag","block":"on radio received","blockGap":"16","useLoc":"radio.onDataPacketReceived","draggableParameters":"reporter","group":"Receive","weight":19,"jsDoc":"Registers code to run when the radio receives a key value pair.","_def":{"parts":[{"kind":"label","text":"on radio received","style":[]}],"parameters":[]}},"parameters":[{"name":"cb","type":"(name: string, value: number) => void","handlerParameters":[{"name":"name","type":"string"},{"name":"value","type":"number"}]}],"pyQName":"radio.on_received_value"},"radio.onReceivedString":{"kind":-3,"attributes":{"help":"radio/on-received-string","blockId":"radio_on_string_drag","block":"on radio received","blockGap":"16","useLoc":"radio.onDataPacketReceived","draggableParameters":"reporter","group":"Receive","weight":18,"jsDoc":"Registers code to run when the radio receives a string.","_def":{"parts":[{"kind":"label","text":"on radio received","style":[]}],"parameters":[]}},"parameters":[{"name":"cb","type":"(receivedString: string) => void","handlerParameters":[{"name":"receivedString","type":"string"}]}],"pyQName":"radio.on_received_string"},"radio.onReceivedBuffer":{"kind":-3,"attributes":{"help":"radio/on-received-buffer","blockHidden":true,"blockId":"radio_on_buffer_drag","block":"on radio received","blockGap":"16","useLoc":"radio.onDataPacketReceived","draggableParameters":"reporter","jsDoc":"Registers code to run when the radio receives a buffer.","_def":{"parts":[{"kind":"label","text":"on radio received","style":[]}],"parameters":[]}},"parameters":[{"name":"cb","type":"(receivedBuffer: Buffer) => void","handlerParameters":[{"name":"receivedBuffer","type":"Buffer"}]}],"pyQName":"radio.on_received_buffer"},"radio.receivedPacket":{"kind":-3,"retType":"number","attributes":{"help":"radio/received-packet","blockGap":"16","blockId":"radio_received_packet","block":"received packet %type=radio_packet_property","group":"Receive","weight":16,"paramHelp":{"type":"the type of property to retrieve from the last packet"},"jsDoc":"Returns properties of the last radio packet received.","_def":{"parts":[{"kind":"label","text":"received packet ","style":[]},{"kind":"param","name":"type","shadowBlockId":"radio_packet_property","ref":false}],"parameters":[{"kind":"param","name":"type","shadowBlockId":"radio_packet_property","ref":false}]}},"parameters":[{"name":"type","description":"the type of property to retrieve from the last packet"}],"pyQName":"radio.received_packet"},"radio._packetProperty":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"type":"PacketProperty.time"},"blockId":"radio_packet_property","block":"%note","shim":"TD_ID","blockHidden":true,"paramHelp":{"type":"the packet property type, eg: PacketProperty.time"},"jsDoc":"Gets a packet property.","_def":{"parts":[{"kind":"param","name":"note","ref":false}],"parameters":[{"kind":"param","name":"note","ref":false}]}},"parameters":[{"name":"type","description":"the packet property type, eg: PacketProperty.time","type":"RadioPacketProperty","default":"PacketProperty.time","isEnum":true}],"pyQName":"radio._packet_property"},"radio.RadioPacket":{"kind":8,"retType":"radio.RadioPacket","extendsTypes":[]},"radio.RadioPacket.getPacket":{"kind":-1,"retType":"radio.RadioPacket","parameters":[{"name":"data","type":"Buffer"}],"pyQName":"radio.RadioPacket.get_packet"},"radio.RadioPacket.mkPacket":{"kind":-1,"retType":"radio.RadioPacket","parameters":[{"name":"packetType"}],"pyQName":"radio.RadioPacket.mk_packet"},"radio.RadioPacket.signal":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"radio.RadioPacket.packetType":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"radio.RadioPacket.packet_type"},"radio.RadioPacket.time":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"radio.RadioPacket.time@set":{"kind":-2,"retType":"number","isInstance":true},"radio.RadioPacket.serial":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"radio.RadioPacket.serial@set":{"kind":-2,"retType":"number","isInstance":true},"radio.RadioPacket.stringPayload":{"kind":-2,"retType":"string","isInstance":true,"isReadOnly":true,"pyQName":"radio.RadioPacket.string_payload"},"radio.RadioPacket.stringPayload@set":{"kind":-2,"retType":"string","isInstance":true,"pyQName":"radio.RadioPacket.string_payload@set"},"radio.RadioPacket.numberPayload":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true,"pyQName":"radio.RadioPacket.number_payload"},"radio.RadioPacket.numberPayload@set":{"kind":-2,"retType":"number","isInstance":true,"pyQName":"radio.RadioPacket.number_payload@set"},"radio.RadioPacket.bufferPayload":{"kind":-2,"retType":"Buffer","isInstance":true,"isReadOnly":true,"pyQName":"radio.RadioPacket.buffer_payload"},"radio.RadioPacket.bufferPayload@set":{"kind":-2,"retType":"Buffer","isInstance":true,"pyQName":"radio.RadioPacket.buffer_payload@set"},"radio.RadioPacket.hasString":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"radio.RadioPacket.has_string"},"radio.RadioPacket.hasNumber":{"kind":-1,"retType":"boolean","parameters":[],"isInstance":true,"pyQName":"radio.RadioPacket.has_number"},"radio.sendNumber":{"kind":-3,"attributes":{"help":"radio/send-number","weight":60,"blockId":"radio_datagram_send","block":"radio send number %value","blockGap":"8","group":"Send","jsDoc":"Broadcasts a number over radio to any connected micro:bit in the group.","_def":{"parts":[{"kind":"label","text":"radio send number ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value"}],"pyQName":"radio.send_number"},"radio.sendValue":{"kind":-3,"attributes":{"paramDefl":{"name":"name"},"help":"radio/send-value","weight":59,"blockId":"radio_datagram_send_value","block":"radio send|value %name|= %value","blockGap":"8","group":"Send","paramHelp":{"name":"the field name (max 8 characters), eg: \"name\"","value":"the numeric value"},"jsDoc":"Broadcasts a name / value pair along with the device serial number\nand running time to any connected micro:bit in the group. The name can\ninclude no more than 8 characters.","_def":{"parts":[{"kind":"label","text":"radio send","style":[]},{"kind":"break"},{"kind":"label","text":"value ","style":[]},{"kind":"param","name":"name","ref":false},{"kind":"break"},{"kind":"label","text":"= ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"name","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"name","description":"the field name (max 8 characters), eg: \"name\"","type":"string","default":"name"},{"name":"value","description":"the numeric value"}],"pyQName":"radio.send_value"},"radio.sendString":{"kind":-3,"attributes":{"help":"radio/send-string","weight":58,"blockId":"radio_datagram_send_string","block":"radio send string %msg","paramShadowOptions":{"msg":{"toString":"true"}},"group":"Send","jsDoc":"Broadcasts a string along with the device serial number\nand running time to any connected micro:bit in the group.","_def":{"parts":[{"kind":"label","text":"radio send string ","style":[]},{"kind":"param","name":"msg","ref":false}],"parameters":[{"kind":"param","name":"msg","ref":false}]}},"parameters":[{"name":"value","type":"string","options":{"fieldEditorOptions":{"value":{"toString":"true"}}}}],"pyQName":"radio.send_string"},"radio.sendBuffer":{"kind":-3,"attributes":{"help":"radio/send-buffer","weight":57,"advanced":true,"jsDoc":"Broadcasts a buffer (up to 19 bytes long) along with the device serial number\nand running time to any connected micro:bit in the group."},"parameters":[{"name":"msg","type":"Buffer"}],"pyQName":"radio.send_buffer"},"radio.setTransmitSerialNumber":{"kind":-3,"attributes":{"paramDefl":{"transmit":"true"},"help":"radio/set-transmit-serial-number","weight":8,"blockGap":"8","blockId":"radio_set_transmit_serial_number","block":"radio set transmit serial number %transmit","advanced":true,"paramHelp":{"transmit":"value indicating if the serial number is transmitted, eg: true"},"jsDoc":"Set the radio to transmit the serial number in each message.","_def":{"parts":[{"kind":"label","text":"radio set transmit serial number ","style":[]},{"kind":"param","name":"transmit","ref":false}],"parameters":[{"kind":"param","name":"transmit","ref":false}]}},"parameters":[{"name":"transmit","description":"value indicating if the serial number is transmitted, eg: true","type":"boolean","default":"true"}],"pyQName":"radio.set_transmit_serial_number"},"radio.__message":{"kind":-3,"retType":"number","attributes":{"blockHidden":true,"shim":"ENUM_GET","blockId":"radioMessageCode","block":"$msg","enumInitialMembers":["message1"],"enumName":"RadioMessage","enumMemberName":"msg","enumPromptHint":"e.g. Start, Stop, Jump...","enumIsHash":true,"jsDoc":"Gets the message code","_def":{"parts":[{"kind":"param","name":"msg","ref":true}],"parameters":[{"kind":"param","name":"msg","ref":true}]}},"parameters":[{"name":"msg"}]},"radio.sendMessage":{"kind":-3,"attributes":{"blockId":"radioBroadcastMessage","block":"radio send $msg","_shadowOverrides":{"msg":"radioMessageCode"},"draggableParameters":"true","weight":200,"blockGap":"8","help":"radio/send-message","group":"Broadcast","paramHelp":{"msg":""},"jsDoc":"Broadcasts a message over radio","_def":{"parts":[{"kind":"label","text":"radio send ","style":[]},{"kind":"param","name":"msg","shadowBlockId":"radioMessageCode","ref":true}],"parameters":[{"kind":"param","name":"msg","shadowBlockId":"radioMessageCode","ref":true}]}},"parameters":[{"name":"msg"}],"pyQName":"radio.send_message"},"radio.onReceivedMessage":{"kind":-3,"attributes":{"blockId":"radioOnMessageReceived","block":"on radio $msg received","_shadowOverrides":{"msg":"radioMessageCode"},"draggableParameters":"true","weight":199,"help":"radio/on-received-message","group":"Broadcast","paramHelp":{"msg":"@param handler "},"jsDoc":"Registers code to run for a particular message","_def":{"parts":[{"kind":"label","text":"on radio ","style":[]},{"kind":"param","name":"msg","shadowBlockId":"radioMessageCode","ref":true},{"kind":"label","text":" received","style":[]}],"parameters":[{"kind":"param","name":"msg","shadowBlockId":"radioMessageCode","ref":true}]}},"parameters":[{"name":"msg","description":"@param handler "},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"radio.on_received_message"}}},"sha":"f5c25a606d477799338a5e3d452ed2dff2e32536973f4632cd8bba8ce8ded47d"},"libs/rotary-encoder":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"encoders":{"kind":5,"retType":"","attributes":{"color":"#03AA74","weight":87,"icon":"","jsDoc":"Rotary and other encoders\n\nRotary encoders"}},"encoders.createRotaryEncoder":{"kind":-3,"retType":"RotaryEncoder","attributes":{"weight":99,"jsDoc":"Create a new rotary encoder connected to given pins"},"parameters":[{"name":"pinA","type":"DigitalInOutPin"},{"name":"pinB","type":"DigitalInOutPin"}],"pyQName":"encoders.create_rotary_encoder"},"RotaryEncoder":{"kind":9,"retType":"RotaryEncoder","attributes":{"noRefCounting":"true","fixedInstances":"true"},"extendsTypes":[]},"RotaryEncoder.onChanged":{"kind":-1,"attributes":{"blockNamespace":"encoders","blockId":"rotaryencoderonchaned","block":"on %this changed","weight":80,"blockGap":"8","jsDoc":"Do something when a rotary encoder changes position","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"this","ref":false},{"kind":"label","text":" changed","style":[]}],"parameters":[{"kind":"param","name":"this","ref":false}]}},"parameters":[{"name":"body","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"RotaryEncoder.on_changed"},"RotaryEncoder.position":{"kind":-1,"retType":"number","attributes":{"blockNamespace":"encoders","blockId":"rotaryencoderposition","block":"%this position","weight":79,"blockGap":"8","jsDoc":"Get current encoder position.","_def":{"parts":[{"kind":"param","name":"this","ref":false},{"kind":"label","text":" position","style":[]}],"parameters":[{"kind":"param","name":"this","ref":false}]}},"parameters":[],"isInstance":true},"encoders.defaultEncoder":{"kind":4,"retType":"RotaryEncoder","attributes":{"block":"encoder","fixedInstance":"true","whenUsed":"true","jsDoc":"Gets the default rotary encoder if any","_def":{"parts":[{"kind":"label","text":"encoder","style":[]}],"parameters":[]}},"pyQName":"encoders.default_encoder"}}},"sha":"fb6ac2a0e4b0af50d7320ba80f95b2be2cf242e65f4a8bdec5fdb30ad2414cd7"},"libs/rpiprj":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":"","attributes":{"jsDoc":"These shims are for enabling system keyboard support in text/number prompts."}},"pins":{"kind":5,"retType":""},"input":{"kind":5,"retType":"","attributes":{"color":"#B4009E","weight":98,"icon":"","groups":["other","More"],"jsDoc":"Respond to and read data from buttons and sensors.\n\nEvents and data from sensors."}},"control.raiseEvent":{"kind":-3,"attributes":{"weight":21,"blockGap":"12","blockId":"control_raise_event","block":"raise event|from %src|with value %value","blockExternalInputs":"1","help":"control/raise-event","inlineInputMode":"external","paramHelp":{"src":"ID of the Component that generated the event","value":"Component specific code indicating the cause of the event.","mode":"optional definition of how the event should be processed after construction."},"jsDoc":"Announce that an event happened to registered handlers.","_def":{"parts":[{"kind":"label","text":"raise event","style":[]},{"kind":"break"},{"kind":"label","text":"from ","style":[]},{"kind":"param","name":"src","ref":false},{"kind":"break"},{"kind":"label","text":"with value ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"src","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"src","description":"ID of the Component that generated the event"},{"name":"value","description":"Component specific code indicating the cause of the event."}],"pyQName":"control.raise_event"},"control.dmesg":{"kind":-3,"attributes":{"jsDoc":"Write data to DMESG debugging buffer."},"parameters":[{"name":"s","type":"string"}]},"serial":{"kind":5,"retType":"","attributes":{"weight":2,"color":"#002050","icon":"","advanced":true,"blockGap":"8","groups":["Write","Read","Events","Configuration"],"jsDoc":"Reading and writing data over a serial connection."}},"serial.writeDmesg":{"kind":-3,"attributes":{"jsDoc":"Send DMESG debug buffer over serial."},"parameters":[],"pyQName":"serial.write_dmesg"},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"texteffects":{"kind":5,"retType":""},"images":{"kind":5,"retType":"","attributes":{"weight":70,"icon":"","color":"#a5b1c2","advanced":true,"jsDoc":"Image manipulation blocks"}},"controller":{"kind":5,"retType":"","attributes":{"weight":98,"color":"#D54322","icon":"","groups":["Single Player","Multiplayer"],"blockGap":"8","jsDoc":"Access to game controls"}},"controller.ControllerSceneState":{"kind":9,"retType":"controller.ControllerSceneState","extendsTypes":[]},"controller.ControllerSceneState.lastGesture":{"kind":2,"retType":"ControllerGesture","isInstance":true,"pyQName":"controller.ControllerSceneState.last_gesture"},"controller.ControllerSceneState.gestureHandlers":{"kind":2,"retType":"any","isInstance":true,"pyQName":"controller.ControllerSceneState.gesture_handlers"},"controller.ControllerSceneState.lastCustomGesture":{"kind":2,"retType":"number","isInstance":true,"pyQName":"controller.ControllerSceneState.last_custom_gesture"},"controller.ControllerSceneState.customGestureHandlers":{"kind":2,"retType":"any","isInstance":true,"pyQName":"controller.ControllerSceneState.custom_gesture_handlers"},"controller.ControllerSceneState.lastLightCondition":{"kind":2,"retType":"ControllerLightCondition","isInstance":true,"pyQName":"controller.ControllerSceneState.last_light_condition"},"controller.ControllerSceneState.lightHandlers":{"kind":2,"retType":"any","isInstance":true,"pyQName":"controller.ControllerSceneState.light_handlers"},"controller.CustomGestureHandler":{"kind":9,"retType":"controller.CustomGestureHandler","extendsTypes":[]},"controller.CustomGestureHandler.update":{"kind":2,"retType":"() => boolean","isInstance":true},"controller.CustomGestureHandler.handler":{"kind":2,"retType":"() => void","isInstance":true},"controller.sceneState":{"kind":-3,"retType":"controller.ControllerSceneState","parameters":[],"pyQName":"controller.scene_state"},"controller.vibrate":{"kind":-3,"attributes":{"blockId":"ctrlvibrate","block":"vibrate $millis ms","_shadowOverrides":{"millis":"timePicker"},"group":"Extras","paramHelp":{"millis":""},"jsDoc":"Vibrates the controller for the given duration (in milli seconds)","_def":{"parts":[{"kind":"label","text":"vibrate ","style":[]},{"kind":"param","name":"millis","shadowBlockId":"timePicker","ref":true},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"millis","shadowBlockId":"timePicker","ref":true}]}},"parameters":[{"name":"millis"}]},"ControllerGesture":{"kind":6,"retType":"ControllerGesture","extendsTypes":["ControllerGesture","Number"]},"ControllerGesture.Shake":{"retType":"ControllerGesture.Shake","attributes":{"block":"shake","jsDoc":"Shake gesture","_def":{"parts":[{"kind":"label","text":"shake","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.Shake","Number"],"pyQName":"ControllerGesture.SHAKE"},"ControllerGesture.TiltUp":{"retType":"ControllerGesture.TiltUp","attributes":{"block":"tilt up","jsDoc":"Raised when the device tilts up","_def":{"parts":[{"kind":"label","text":"tilt up","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltUp","Number"],"pyQName":"ControllerGesture.TILT_UP"},"ControllerGesture.TiltDown":{"retType":"ControllerGesture.TiltDown","attributes":{"block":"tilt down","jsDoc":"Raised when the device tilts down","_def":{"parts":[{"kind":"label","text":"tilt down","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltDown","Number"],"pyQName":"ControllerGesture.TILT_DOWN"},"ControllerGesture.TiltLeft":{"retType":"ControllerGesture.TiltLeft","attributes":{"block":"tilt left","jsDoc":"Raised when the screen is pointing left","_def":{"parts":[{"kind":"label","text":"tilt left","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltLeft","Number"],"pyQName":"ControllerGesture.TILT_LEFT"},"ControllerGesture.TiltRight":{"retType":"ControllerGesture.TiltRight","attributes":{"block":"tilt right","jsDoc":"Raised when the screen is pointing right","_def":{"parts":[{"kind":"label","text":"tilt right","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TiltRight","Number"],"pyQName":"ControllerGesture.TILT_RIGHT"},"ControllerGesture.ScreenUp":{"retType":"ControllerGesture.ScreenUp","attributes":{"block":"screen up","jsDoc":"Raised when the screen faces up","_def":{"parts":[{"kind":"label","text":"screen up","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.ScreenUp","Number"],"pyQName":"ControllerGesture.SCREEN_UP"},"ControllerGesture.ScreenDown":{"retType":"ControllerGesture.ScreenDown","attributes":{"block":"screen down","jsDoc":"Raised when the screen is pointing up and the board is horizontal","_def":{"parts":[{"kind":"label","text":"screen down","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.ScreenDown","Number"],"pyQName":"ControllerGesture.SCREEN_DOWN"},"ControllerGesture.TwoG":{"retType":"ControllerGesture.TwoG","attributes":{"block":"2g (step)","jsDoc":"Raised when a 2G shock is detected","_def":{"parts":[{"kind":"label","text":"2g (step)","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.TwoG","Number"],"pyQName":"ControllerGesture.TWO_G"},"ControllerGesture.ThreeG":{"retType":"ControllerGesture.ThreeG","attributes":{"block":"3g","jsDoc":"Raised when a 3G shock is detected","_def":{"parts":[{"kind":"label","text":"3g","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.ThreeG","Number"],"pyQName":"ControllerGesture.THREE_G"},"ControllerGesture.SixG":{"retType":"ControllerGesture.SixG","attributes":{"block":"6g","jsDoc":"Raised when a 6G shock is detected","_def":{"parts":[{"kind":"label","text":"6g","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.SixG","Number"],"pyQName":"ControllerGesture.SIX_G"},"ControllerGesture.EightG":{"retType":"ControllerGesture.EightG","attributes":{"block":"8g","jsDoc":"Raised when a 8G shock is detected","_def":{"parts":[{"kind":"label","text":"8g","style":[]}],"parameters":[]}},"extendsTypes":["ControllerGesture.EightG","Number"],"pyQName":"ControllerGesture.EIGHT_G"},"ControllerDimension":{"kind":6,"retType":"ControllerDimension","extendsTypes":["ControllerDimension","Number"]},"ControllerDimension.X":{"retType":"ControllerDimension.X","attributes":{"block":"x","_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.X","Number"]},"ControllerDimension.Y":{"retType":"ControllerDimension.Y","attributes":{"block":"y","_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.Y","Number"]},"ControllerDimension.Z":{"retType":"ControllerDimension.Z","attributes":{"block":"z","_def":{"parts":[{"kind":"label","text":"z","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.Z","Number"]},"ControllerDimension.Strength":{"retType":"ControllerDimension.Strength","attributes":{"block":"strength","_def":{"parts":[{"kind":"label","text":"strength","style":[]}],"parameters":[]}},"extendsTypes":["ControllerDimension.Strength","Number"],"pyQName":"ControllerDimension.STRENGTH"},"controller.onGesture":{"kind":-3,"attributes":{"blockId":"ctrlongesture","block":"on |%NAME","parts":"accelerometer","paramFieldEditor":{"gesture":"gridpicker"},"paramFieldEditorOptions":{"gesture":{"width":"220","columns":"3"}},"group":"Extras","paramHelp":{"gesture":"the type of gesture to track","body":"code to run when gesture is raised"},"jsDoc":"Do something when a gesture happens (like shaking the board).","_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"gesture","description":"the type of gesture to track","type":"ControllerGesture","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.on_gesture"},"controller.onCustomGesture":{"kind":-3,"attributes":{"paramHelp":{"id":"@param update","handler":""},"jsDoc":"Register a custom gesture for the controller"},"parameters":[{"name":"id","description":"@param update"},{"name":"update","type":"() => boolean","handlerParameters":[]},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.on_custom_gesture"},"controller.acceleration":{"kind":-3,"retType":"number","attributes":{"blockId":"ctrlaccelerationvalue","block":"acceleration (mg)|%NAME","parts":"accelerometer","paramFieldEditor":{"dimension":"gridpicker"},"paramFieldEditorOptions":{"dimension":{"width":"180","columns":"2"}},"group":"Extras","paramHelp":{"dimension":"the axis along which the acceleration if measured"},"jsDoc":"Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up,\nx=0, y=0 and z=-1023)","_def":{"parts":[{"kind":"label","text":"acceleration (mg)","style":[]},{"kind":"break"},{"kind":"param","name":"NAME","ref":false}],"parameters":[{"kind":"param","name":"NAME","ref":false}]}},"parameters":[{"name":"dimension","description":"the axis along which the acceleration if measured","type":"ControllerDimension","isEnum":true}]},"ControllerLightCondition":{"kind":6,"retType":"ControllerLightCondition","extendsTypes":["ControllerLightCondition","Number"]},"ControllerLightCondition.Dark":{"retType":"ControllerLightCondition.Dark","attributes":{"block":"dark","_def":{"parts":[{"kind":"label","text":"dark","style":[]}],"parameters":[]}},"extendsTypes":["ControllerLightCondition.Dark","Number"],"pyQName":"ControllerLightCondition.DARK"},"ControllerLightCondition.Bright":{"retType":"ControllerLightCondition.Bright","attributes":{"block":"bright","_def":{"parts":[{"kind":"label","text":"bright","style":[]}],"parameters":[]}},"extendsTypes":["ControllerLightCondition.Bright","Number"],"pyQName":"ControllerLightCondition.BRIGHT"},"controller.lightLevel":{"kind":-3,"retType":"number","attributes":{"blockId":"ctrllightlevel","block":"light level","parts":"lightsensor","weight":30,"blockGap":"8","group":"Extras","jsDoc":"Read the light level applied to the LED screen in a range from 0 (dark) to 255 (bright).","_def":{"parts":[{"kind":"label","text":"light level","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"controller.light_level"},"controller.onLightConditionChanged":{"kind":-3,"attributes":{"blockId":"ctrlonlightcondition","block":"on light %condition","parts":"lightsensor","weight":84,"blockGap":"12","group":"Extras","paramHelp":{"condition":"the condition that event triggers on"},"jsDoc":"Register an event that runs when light conditions (darker or brighter) change.","_def":{"parts":[{"kind":"label","text":"on light ","style":[]},{"kind":"param","name":"condition","ref":false}],"parameters":[{"kind":"param","name":"condition","ref":false}]}},"parameters":[{"name":"condition","description":"the condition that event triggers on","type":"ControllerLightCondition","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.on_light_condition_changed"},"ControllerTemperatureUnit":{"kind":6,"retType":"ControllerTemperatureUnit","extendsTypes":["ControllerTemperatureUnit","Number"]},"ControllerTemperatureUnit.Celsius":{"retType":"ControllerTemperatureUnit.Celsius","attributes":{"block":"°C","_def":{"parts":[{"kind":"label","text":"°C","style":[]}],"parameters":[]}},"extendsTypes":["ControllerTemperatureUnit.Celsius","Number"],"pyQName":"ControllerTemperatureUnit.CELSIUS"},"ControllerTemperatureUnit.Fahrenheit":{"retType":"ControllerTemperatureUnit.Fahrenheit","attributes":{"block":"°F","_def":{"parts":[{"kind":"label","text":"°F","style":[]}],"parameters":[]}},"extendsTypes":["ControllerTemperatureUnit.Fahrenheit","Number"],"pyQName":"ControllerTemperatureUnit.FAHRENHEIT"},"controller.temperature":{"kind":-3,"retType":"number","attributes":{"blockId":"ctrltemperature","block":"temperature in %unit","parts":"thermometer","weight":26,"group":"Extras","jsDoc":"Get the temperature in Celsius or Fahrenheit degrees.","_def":{"parts":[{"kind":"label","text":"temperature in ","style":[]},{"kind":"param","name":"unit","ref":false}],"parameters":[{"kind":"param","name":"unit","ref":false}]}},"parameters":[{"name":"unit","type":"ControllerTemperatureUnit","isEnum":true}]},"controller.configureRepeatEventDefaults":{"kind":-3,"attributes":{"paramDefl":{"delay":"500","interval":"30"},"blockId":"repeatDefaultDelayInterval","block":"set button repeat delay $delay ms interval $interval ms","weight":10,"group":"Single Player","paramHelp":{"delay":"number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500","interval":"minimum number of milliseconds between calls to the button repeat event, eg: 30"},"jsDoc":"Configures the timing of the on button repeat event for all of the controller buttons","_def":{"parts":[{"kind":"label","text":"set button repeat delay ","style":[]},{"kind":"param","name":"delay","ref":true},{"kind":"label","text":" ms interval ","style":[]},{"kind":"param","name":"interval","ref":true},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"delay","ref":true},{"kind":"param","name":"interval","ref":true}]}},"parameters":[{"name":"delay","description":"number of milliseconds from when the button is pressed to when the repeat event starts firing, eg: 500","default":"500"},{"name":"interval","description":"minimum number of milliseconds between calls to the button repeat event, eg: 30","default":"30"}],"pyQName":"controller.configure_repeat_event_defaults"},"controller.startLightPulse":{"kind":-3,"attributes":{"blockId":"ctrllightpulse","block":"start light pulse %rgb=colorNumberPicker|for %duration=timePicker|ms","weight":80,"blockGap":"8","group":"Extras","paramHelp":{"rgb":"RGB color of the LED"},"jsDoc":"Shows a color pulse","_def":{"parts":[{"kind":"label","text":"start light pulse ","style":[]},{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"break"},{"kind":"label","text":"for ","style":[]},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false},{"kind":"break"},{"kind":"label","text":"ms","style":[]}],"parameters":[{"kind":"param","name":"rgb","shadowBlockId":"colorNumberPicker","ref":false},{"kind":"param","name":"duration","shadowBlockId":"timePicker","ref":false}]}},"parameters":[{"name":"rgb","description":"RGB color of the LED"},{"name":"duration"}],"pyQName":"controller.start_light_pulse"},"light":{"kind":5,"retType":"","attributes":{"advanced":true}},"controller.crankPosition":{"kind":-3,"retType":"number","attributes":{"blockId":"controller_crank_position","block":"crank position","weight":29,"blockGap":"8","group":"Extras","jsDoc":"Gets the current position of the crank.","_def":{"parts":[{"kind":"label","text":"crank position","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"controller.crank_position"},"controller.__internal":{"kind":5,"retType":""},"controller.__internal.onGesture":{"kind":-3,"parameters":[{"name":"gesture","type":"ControllerGesture","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.__internal.on_gesture"},"controller.__internal.onCustomGesture":{"kind":-3,"parameters":[{"name":"id"},{"name":"update","type":"() => boolean","handlerParameters":[]},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.__internal.on_custom_gesture"},"controller.__internal.acceleration":{"kind":-3,"retType":"number","parameters":[{"name":"dimension","type":"ControllerDimension","isEnum":true}]},"controller.__internal.crankPosition":{"kind":-3,"retType":"number","parameters":[],"pyQName":"controller.__internal.crank_position"},"controller.__internal.startLightPulse":{"kind":-3,"parameters":[{"name":"rgb"},{"name":"duration"}],"pyQName":"controller.__internal.start_light_pulse"},"controller.__internal.lightLevel":{"kind":-3,"retType":"number","parameters":[],"pyQName":"controller.__internal.light_level"},"controller.__internal.onLightConditionChanged":{"kind":-3,"parameters":[{"name":"condition","type":"ControllerLightCondition","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"controller.__internal.on_light_condition_changed"},"controller.__internal.temperature":{"kind":-3,"retType":"number","parameters":[{"name":"unit","type":"ControllerTemperatureUnit","isEnum":true}]},"controller.__internal.vibrate":{"kind":-3,"parameters":[{"name":"millis"}]},"serial.device":{"kind":-3,"retType":"serial.Serial","parameters":[]},"serial.NEW_LINE":{"kind":4,"retType":"string"},"serial.NEW_LINE_DELIMITER":{"kind":4,"retType":"Delimiters"},"serial.Serial":{"kind":8,"retType":"serial.Serial","extendsTypes":[]},"serial.Serial.serialDevice":{"kind":2,"retType":"SerialDevice","isInstance":true,"pyQName":"serial.Serial.serial_device"},"serial.Serial.decoder":{"kind":2,"retType":"UTF8Decoder","isInstance":true},"serial.Serial.__constructor":{"kind":-3,"parameters":[{"name":"serialDevice","type":"SerialDevice"}],"isInstance":true},"serial.Serial.readString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"serial.Serial.read_string"},"serial.Serial.readLine":{"kind":-1,"retType":"string","parameters":[{"name":"timeOut","initializer":"undefined"}],"isInstance":true,"pyQName":"serial.Serial.read_line"},"serial.Serial.readUntil":{"kind":-1,"retType":"string","parameters":[{"name":"delimiter","type":"Delimiters","isEnum":true},{"name":"timeOut","initializer":"undefined"}],"isInstance":true,"pyQName":"serial.Serial.read_until"},"serial.Serial.writeString":{"kind":-1,"parameters":[{"name":"text","type":"string"}],"isInstance":true,"pyQName":"serial.Serial.write_string"},"serial.Serial.writeLine":{"kind":-1,"parameters":[{"name":"text","type":"string"}],"isInstance":true,"pyQName":"serial.Serial.write_line"},"serial.readString":{"kind":-3,"retType":"string","attributes":{"help":"serial/read-string","blockId":"serial_read_string","block":"serial|read string","weight":18,"group":"Read","jsDoc":"Read the buffered received data as a string","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read string","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.read_string"},"serial.readLine":{"kind":-3,"retType":"string","attributes":{"help":"serial/read-line","blockId":"serial_read_line","block":"serial|read line","weight":20,"blockGap":"8","group":"Read","jsDoc":"Read a line of text from the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read line","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.read_line"},"serial.readUntil":{"kind":-3,"retType":"string","attributes":{"help":"serial/read-until","blockId":"serial_read_until","block":"serial|read until %delimiter=serial_delimiter_conv","weight":19,"group":"Read","paramHelp":{"delimiter":"text delimiter that separates each text chunk"},"jsDoc":"Read a line of text from the serial port and return the buffer when the delimiter is met.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read until ","style":[]},{"kind":"param","name":"delimiter","shadowBlockId":"serial_delimiter_conv","ref":false}],"parameters":[{"kind":"param","name":"delimiter","shadowBlockId":"serial_delimiter_conv","ref":false}]}},"parameters":[{"name":"delimiter","description":"text delimiter that separates each text chunk","type":"Delimiters","isEnum":true},{"name":"timeOut","initializer":"undefined"}],"pyQName":"serial.read_until"},"serial.writeString":{"kind":-3,"attributes":{"help":"serial/write-string","weight":87,"blockId":"serial_writestring","block":"serial|write string %text","group":"Write","jsDoc":"Write some text to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write string ","style":[]},{"kind":"param","name":"text","ref":false}],"parameters":[{"kind":"param","name":"text","ref":false}]}},"parameters":[{"name":"text","type":"string"}],"pyQName":"serial.write_string"},"serial.writeLine":{"kind":-3,"attributes":{"weight":90,"help":"serial/write-line","blockGap":"8","blockId":"serial_writeline","block":"serial|write line %text","group":"Write","paramHelp":{"value":"to send over serial"},"jsDoc":"Write a line of text to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write line ","style":[]},{"kind":"param","name":"text","ref":false}],"parameters":[{"kind":"param","name":"text","ref":false}]}},"parameters":[{"name":"text","type":"string"}],"pyQName":"serial.write_line"},"serial.writeNumber":{"kind":-3,"attributes":{"help":"serial/write-number","weight":89,"blockGap":"8","blockId":"serial_writenumber","block":"serial|write number %value","group":"Write","jsDoc":"Write a number to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write number ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value"}],"pyQName":"serial.write_number"},"serial.writeValue":{"kind":-3,"attributes":{"paramDefl":{"name":"x"},"weight":88,"blockGap":"8","help":"serial/write-value","blockId":"serial_writevalue","block":"serial|write value %name|= %value","group":"Write","paramHelp":{"name":"name of the value stream, eg: \"x\"","value":"to write"},"jsDoc":"Write a name:value pair as a line of text to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write value ","style":[]},{"kind":"param","name":"name","ref":false},{"kind":"break"},{"kind":"label","text":"= ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"name","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"name","description":"name of the value stream, eg: \"x\"","type":"string","default":"x"},{"name":"value","description":"to write"}],"pyQName":"serial.write_value"},"serial.setRxBufferSize":{"kind":-3,"attributes":{"help":"serial/set-rx-buffer-size","blockId":"serialsetrxbuffersize","block":"serial set rx buffer size to $size","weight":10,"group":"Configuration","jsDoc":"Sets the size of the RX buffer in bytes","_def":{"parts":[{"kind":"label","text":"serial set rx buffer size to ","style":[]},{"kind":"param","name":"size","ref":true}],"parameters":[{"kind":"param","name":"size","ref":true}]}},"parameters":[{"name":"size"}],"pyQName":"serial.set_rx_buffer_size"},"serial.setTxBufferSize":{"kind":-3,"attributes":{"help":"serial/set-tx-buffer-size","blockId":"serialsettxbuffersize","block":"serial set tx buffer size to $size","weight":9,"group":"Configuration","jsDoc":"Sets the size of the TX buffer in bytes","_def":{"parts":[{"kind":"label","text":"serial set tx buffer size to ","style":[]},{"kind":"param","name":"size","ref":true}],"parameters":[{"kind":"param","name":"size","ref":true}]}},"parameters":[{"name":"size"}],"pyQName":"serial.set_tx_buffer_size"},"serial.read":{"kind":-3,"retType":"number","attributes":{"Group":"Read","jsDoc":"Reads a single byte from the serial receive buffer. Negative if error, 0 if no data."},"parameters":[]},"serial.readBuffer":{"kind":-3,"retType":"Buffer","attributes":{"help":"serial/read-buffer","blockId":"serial_read_buffer","block":"serial|read buffer","weight":17,"group":"Read","jsDoc":"Read the buffered received data as a buffer","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read buffer","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.read_buffer"},"serial.writeBuffer":{"kind":-3,"attributes":{"help":"serial/write-buffer","weight":6,"blockId":"serial_writebuffer","block":"serial|write buffer %buffer","group":"Write","jsDoc":"Send a buffer across the serial connection.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write buffer ","style":[]},{"kind":"param","name":"buffer","ref":false}],"parameters":[{"kind":"param","name":"buffer","ref":false}]}},"parameters":[{"name":"buffer","type":"Buffer"}],"pyQName":"serial.write_buffer"},"serial.setBaudRate":{"kind":-3,"attributes":{"weight":10,"blockId":"serial_setbaudrate","block":"serial|set baud rate %rate","blockGap":"8","inlineInputMode":"inline","help":"serial/set-baud-rate","group":"Configuration","jsDoc":"Set the baud rate of the serial port","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"set baud rate ","style":[]},{"kind":"param","name":"rate","ref":false}],"parameters":[{"kind":"param","name":"rate","ref":false}]}},"parameters":[{"name":"rate","type":"BaudRate","isEnum":true}],"pyQName":"serial.set_baud_rate"},"serial.attachToConsole":{"kind":-3,"attributes":{"blockId":"serialsendtoconsole","block":"serial attach to console","group":"Configuration","help":"serial/attach-to-console","jsDoc":"Send console messages through the TX, RX pins","_def":{"parts":[{"kind":"label","text":"serial attach to console","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.attach_to_console"},"serial.onEvent":{"kind":-3,"attributes":{"weight":9,"help":"serial/on-event","blockId":"serial_onevent","block":"serial on %event","blockGap":"8","group":"Events","jsDoc":"Registers code when serial events happen","_def":{"parts":[{"kind":"label","text":"serial on ","style":[]},{"kind":"param","name":"event","ref":false}],"parameters":[{"kind":"param","name":"event","ref":false}]}},"parameters":[{"name":"event","type":"SerialEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"serial.on_event"},"serial.onDelimiterReceived":{"kind":-3,"attributes":{"weight":10,"help":"serial/on-delimiter-received","blockId":"serial_ondelimiter","block":"serial on delimiter $delimiter received","blockGap":"8","group":"Events","jsDoc":"Registers code when a delimiter is received","_def":{"parts":[{"kind":"label","text":"serial on delimiter ","style":[]},{"kind":"param","name":"delimiter","ref":true},{"kind":"label","text":" received","style":[]}],"parameters":[{"kind":"param","name":"delimiter","ref":true}]}},"parameters":[{"name":"delimiter","type":"Delimiters","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"serial.on_delimiter_received"},"serial.delimiters":{"kind":-3,"retType":"string","attributes":{"blockId":"serial_delimiter_conv","block":"%del","weight":1,"blockHidden":true,"hidden":"true","jsDoc":"Return the corresponding delimiter string","_def":{"parts":[{"kind":"param","name":"del","ref":false}],"parameters":[{"kind":"param","name":"del","ref":false}]}},"parameters":[{"name":"del","type":"Delimiters","isEnum":true}]},"BaudRate":{"kind":6,"retType":"BaudRate","extendsTypes":["BaudRate","Number"]},"BaudRate.BaudRate115200":{"retType":"BaudRate.BaudRate115200","attributes":{"block":"115200","_def":{"parts":[{"kind":"label","text":"115200","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate115200","Number"],"pyQName":"BaudRate.BAUD_RATE115200"},"BaudRate.BaudRate57600":{"retType":"BaudRate.BaudRate57600","attributes":{"block":"57600","_def":{"parts":[{"kind":"label","text":"57600","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate57600","Number"],"pyQName":"BaudRate.BAUD_RATE57600"},"BaudRate.BaudRate38400":{"retType":"BaudRate.BaudRate38400","attributes":{"block":"38400","_def":{"parts":[{"kind":"label","text":"38400","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate38400","Number"],"pyQName":"BaudRate.BAUD_RATE38400"},"BaudRate.BaudRate31250":{"retType":"BaudRate.BaudRate31250","attributes":{"block":"31250","_def":{"parts":[{"kind":"label","text":"31250","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate31250","Number"],"pyQName":"BaudRate.BAUD_RATE31250"},"BaudRate.BaudRate28800":{"retType":"BaudRate.BaudRate28800","attributes":{"block":"28800","_def":{"parts":[{"kind":"label","text":"28800","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate28800","Number"],"pyQName":"BaudRate.BAUD_RATE28800"},"BaudRate.BaudRate19200":{"retType":"BaudRate.BaudRate19200","attributes":{"block":"19200","_def":{"parts":[{"kind":"label","text":"19200","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate19200","Number"],"pyQName":"BaudRate.BAUD_RATE19200"},"BaudRate.BaudRate14400":{"retType":"BaudRate.BaudRate14400","attributes":{"block":"14400","_def":{"parts":[{"kind":"label","text":"14400","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate14400","Number"],"pyQName":"BaudRate.BAUD_RATE14400"},"BaudRate.BaudRate9600":{"retType":"BaudRate.BaudRate9600","attributes":{"block":"9600","_def":{"parts":[{"kind":"label","text":"9600","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate9600","Number"],"pyQName":"BaudRate.BAUD_RATE9600"},"BaudRate.BaudRate4800":{"retType":"BaudRate.BaudRate4800","attributes":{"block":"4800","_def":{"parts":[{"kind":"label","text":"4800","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate4800","Number"],"pyQName":"BaudRate.BAUD_RATE4800"},"BaudRate.BaudRate2400":{"retType":"BaudRate.BaudRate2400","attributes":{"block":"2400","_def":{"parts":[{"kind":"label","text":"2400","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate2400","Number"],"pyQName":"BaudRate.BAUD_RATE2400"},"BaudRate.BaudRate1200":{"retType":"BaudRate.BaudRate1200","attributes":{"block":"1200","_def":{"parts":[{"kind":"label","text":"1200","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate1200","Number"],"pyQName":"BaudRate.BAUD_RATE1200"},"BaudRate.BaudRate300":{"retType":"BaudRate.BaudRate300","attributes":{"block":"300","_def":{"parts":[{"kind":"label","text":"300","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate300","Number"],"pyQName":"BaudRate.BAUD_RATE300"},"SerialEvent":{"kind":6,"retType":"SerialEvent","extendsTypes":["SerialEvent","Number"]},"SerialEvent.DataReceived":{"retType":"SerialEvent.DataReceived","attributes":{"block":"data received","_def":{"parts":[{"kind":"label","text":"data received","style":[]}],"parameters":[]}},"extendsTypes":["SerialEvent.DataReceived","Number"],"pyQName":"SerialEvent.DATA_RECEIVED"},"SerialEvent.RxBufferFull":{"retType":"SerialEvent.RxBufferFull","attributes":{"block":"rx buffer full","_def":{"parts":[{"kind":"label","text":"rx buffer full","style":[]}],"parameters":[]}},"extendsTypes":["SerialEvent.RxBufferFull","Number"],"pyQName":"SerialEvent.RX_BUFFER_FULL"},"Delimiters":{"kind":6,"retType":"Delimiters","extendsTypes":["Delimiters","Number"]},"Delimiters.NewLine":{"retType":"Delimiters.NewLine","attributes":{"block":"new line (\n)","_def":{"parts":[{"kind":"label","text":"new line (\n)","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.NewLine","Number"],"pyQName":"Delimiters.NEW_LINE"},"Delimiters.Comma":{"retType":"Delimiters.Comma","attributes":{"block":",","_def":{"parts":[{"kind":"label","text":",","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Comma","Number"],"pyQName":"Delimiters.COMMA"},"Delimiters.Dollar":{"retType":"Delimiters.Dollar","attributes":{"block":"$","_def":{"parts":[{"kind":"param","name":"","ref":true}],"parameters":[{"kind":"param","name":"","ref":true}]}},"extendsTypes":["Delimiters.Dollar","Number"],"pyQName":"Delimiters.DOLLAR"},"Delimiters.Colon":{"retType":"Delimiters.Colon","attributes":{"block":":","_def":{"parts":[{"kind":"label","text":":","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Colon","Number"],"pyQName":"Delimiters.COLON"},"Delimiters.Fullstop":{"retType":"Delimiters.Fullstop","attributes":{"block":".","_def":{"parts":[{"kind":"label","text":".","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Fullstop","Number"],"pyQName":"Delimiters.FULLSTOP"},"Delimiters.Hash":{"retType":"Delimiters.Hash","attributes":{"block":"#","_def":{"parts":[{"kind":"label","text":"#","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Hash","Number"],"pyQName":"Delimiters.HASH"},"Delimiters.CarriageReturn":{"retType":"Delimiters.CarriageReturn","attributes":{"block":"carriage return (\r)","_def":{"parts":[{"kind":"label","text":"carriage return (\r)","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.CarriageReturn","Number"],"pyQName":"Delimiters.CARRIAGE_RETURN"},"Delimiters.Space":{"retType":"Delimiters.Space","attributes":{"block":"space","_def":{"parts":[{"kind":"label","text":"space","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Space","Number"],"pyQName":"Delimiters.SPACE"},"Delimiters.Tab":{"retType":"Delimiters.Tab","attributes":{"block":"tab (\t)","_def":{"parts":[{"kind":"label","text":"tab (\t)","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Tab","Number"],"pyQName":"Delimiters.TAB"},"Delimiters.Pipe":{"retType":"Delimiters.Pipe","attributes":{"block":"|","_def":{"parts":[{"kind":"break"}],"parameters":[]}},"extendsTypes":["Delimiters.Pipe","Number"],"pyQName":"Delimiters.PIPE"},"Delimiters.SemiColon":{"retType":"Delimiters.SemiColon","attributes":{"block":";","_def":{"parts":[{"kind":"label","text":";","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.SemiColon","Number"],"pyQName":"Delimiters.SEMI_COLON"},"serial.internalCreateSerialDevice":{"kind":-3,"retType":"SerialDevice","attributes":{"jsDoc":"Opens a Serial communication driver"},"parameters":[{"name":"id"}],"pyQName":"serial.internal_create_serial_device"},"SerialDevice":{"kind":9,"retType":"SerialDevice","extendsTypes":[]},"SerialDevice.setRxBufferSize":{"kind":-1,"attributes":{"jsDoc":"Sets the size of the RX buffer in bytes"},"parameters":[{"name":"size"}],"isInstance":true,"pyQName":"SerialDevice.set_rx_buffer_size"},"SerialDevice.setTxBufferSize":{"kind":-1,"attributes":{"jsDoc":"Sets the size of the TX buffer in bytes"},"parameters":[{"name":"size"}],"isInstance":true,"pyQName":"SerialDevice.set_tx_buffer_size"},"SerialDevice.setBaudRate":{"kind":-1,"attributes":{"jsDoc":"Set the baud rate of the serial port"},"parameters":[{"name":"rate","type":"BaudRate","isEnum":true}],"isInstance":true,"pyQName":"SerialDevice.set_baud_rate"},"SerialDevice.read":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Reads a single byte from the serial receive buffer. Negative if error, 0 if no data."},"parameters":[],"isInstance":true},"SerialDevice.readBuffer":{"kind":-1,"retType":"Buffer","attributes":{"jsDoc":"Read the buffered received data as a buffer"},"parameters":[],"isInstance":true,"pyQName":"SerialDevice.read_buffer"},"SerialDevice.writeBuffer":{"kind":-1,"attributes":{"jsDoc":"Send a buffer across the serial connection."},"parameters":[{"name":"buffer","type":"Buffer"}],"isInstance":true,"pyQName":"SerialDevice.write_buffer"},"SerialDevice.onEvent":{"kind":-1,"attributes":{"jsDoc":"Register code when a serial event occurs"},"parameters":[{"name":"event","type":"SerialEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"SerialDevice.on_event"},"SerialDevice.onDelimiterReceived":{"kind":-1,"attributes":{"jsDoc":"Registers code when a delimiter is received"},"parameters":[{"name":"delimiter","type":"Delimiters","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"SerialDevice.on_delimiter_received"},"Key":{"kind":6,"retType":"Key","extendsTypes":["Key","Number"]},"Key.LEFT":{"retType":"Key.LEFT","extendsTypes":["Key.LEFT","Number"]},"Key.UP":{"retType":"Key.UP","extendsTypes":["Key.UP","Number"]},"Key.RIGHT":{"retType":"Key.RIGHT","extendsTypes":["Key.RIGHT","Number"]},"Key.DOWN":{"retType":"Key.DOWN","extendsTypes":["Key.DOWN","Number"]},"Key.A":{"retType":"Key.A","extendsTypes":["Key.A","Number"]},"Key.B":{"retType":"Key.B","extendsTypes":["Key.B","Number"]},"Key.MENU":{"retType":"Key.MENU","extendsTypes":["Key.MENU","Number"]},"Key.LEFT2":{"retType":"Key.LEFT2","extendsTypes":["Key.LEFT2","Number"]},"Key.UP2":{"retType":"Key.UP2","extendsTypes":["Key.UP2","Number"]},"Key.RIGHT2":{"retType":"Key.RIGHT2","extendsTypes":["Key.RIGHT2","Number"]},"Key.DOWN2":{"retType":"Key.DOWN2","extendsTypes":["Key.DOWN2","Number"]},"Key.A2":{"retType":"Key.A2","extendsTypes":["Key.A2","Number"]},"Key.B2":{"retType":"Key.B2","extendsTypes":["Key.B2","Number"]},"Key.RESET":{"retType":"Key.RESET","extendsTypes":["Key.RESET","Number"]},"Key.EXIT":{"retType":"Key.EXIT","extendsTypes":["Key.EXIT","Number"]},"control.runProgram":{"kind":-3,"attributes":{"jsDoc":"Run specified user program."},"parameters":[{"name":"prog","type":"string"}],"pyQName":"control.run_program"},"control.deleteProgram":{"kind":-3,"attributes":{"jsDoc":"Deletes a user program"},"parameters":[{"name":"prog","type":"string"}],"pyQName":"control.delete_program"},"control.programList":{"kind":-3,"retType":"string[]","parameters":[],"pyQName":"control.program_list"}}},"sha":"02897bc14700eb33b3cee87cde00700288e96c4850a5be7aacb95839b91cc305"},"libs/screen":{"apis":{"byQName":{}},"sha":"8be39fd71caab0faa050b789d64850767b38f50a9be2f4558b13bd2c80876552"},"libs/screen---ext":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"texteffects":{"kind":5,"retType":""},"images":{"kind":5,"retType":"","attributes":{"weight":70,"icon":"","color":"#a5b1c2","advanced":true,"jsDoc":"Image manipulation blocks"}}}},"sha":"eba84084f0c170b8fe00078282b868c000e8d2e057bafaee0c6f57da950d6735"},"libs/screen---linux":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"texteffects":{"kind":5,"retType":""},"images":{"kind":5,"retType":"","attributes":{"weight":70,"icon":"","color":"#a5b1c2","advanced":true,"jsDoc":"Image manipulation blocks"}}}},"sha":"eba84084f0c170b8fe00078282b868c000e8d2e057bafaee0c6f57da950d6735"},"libs/screen---st7735":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"texteffects":{"kind":5,"retType":""},"delay":{"kind":4,"retType":"number"},"screen":{"kind":4,"retType":"ScreenImage","attributes":{"whenUsed":"true"}},"_screen_internal.createScreen":{"kind":-3,"retType":"ScreenImage","parameters":[],"pyQName":"_screen_internal.create_screen"}}},"sha":"024c07aa89f98a47fca5ef2f3d37d055814fbe0195ede6e3479e58a9fadfa33c"},"libs/serial":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"serial":{"kind":5,"retType":"","attributes":{"weight":2,"color":"#002050","icon":"","advanced":true,"blockGap":"8","groups":["Write","Read","Events","Configuration"],"jsDoc":"Reading and writing data over a serial connection."}},"serial.createSerial":{"kind":-3,"retType":"serial.Serial","attributes":{"help":"serial/create-serial","parts":"serial","paramHelp":{"tx":"@param rx ","id":""},"jsDoc":"Creates a serial comm device"},"parameters":[{"name":"tx","description":"@param rx ","type":"DigitalInOutPin"},{"name":"rx","type":"DigitalInOutPin"},{"name":"id","initializer":"undefined"}],"pyQName":"serial.create_serial"},"serial.device":{"kind":-3,"retType":"serial.Serial","parameters":[]},"serial.redirect":{"kind":-3,"attributes":{"weight":10,"help":"serial/redirect","blockId":"serial_redirect","block":"serial|redirect to|TX %tx|RX %rx at rate %rate","paramFieldEditor":{"tx":"gridpicker","rx":"gridpicker"},"paramFieldEditorOptions":{"tx":{"columns":"3","tooltips":"false"},"rx":{"columns":"3","tooltips":"false"}},"blockGap":"8","inlineInputMode":"inline","group":"Configuration","paramHelp":{"tx":"the new transmission pin","rx":"the new reception pin","rate":"the new baud rate"},"jsDoc":"Set the serial input and output to use pins instead of the USB connection.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"redirect to","style":[]},{"kind":"break"},{"kind":"label","text":"TX ","style":[]},{"kind":"param","name":"tx","ref":false},{"kind":"break"},{"kind":"label","text":"RX ","style":[]},{"kind":"param","name":"rx","ref":false},{"kind":"label","text":" at rate ","style":[]},{"kind":"param","name":"rate","ref":false}],"parameters":[{"kind":"param","name":"tx","ref":false},{"kind":"param","name":"rx","ref":false},{"kind":"param","name":"rate","ref":false}]}},"parameters":[{"name":"tx","description":"the new transmission pin","type":"DigitalInOutPin"},{"name":"rx","description":"the new reception pin","type":"DigitalInOutPin"},{"name":"rate","description":"the new baud rate","type":"BaudRate","isEnum":true}]},"serial.NEW_LINE":{"kind":4,"retType":"string"},"serial.NEW_LINE_DELIMITER":{"kind":4,"retType":"Delimiters"},"serial.Serial":{"kind":8,"retType":"serial.Serial","extendsTypes":[]},"serial.Serial.serialDevice":{"kind":2,"retType":"SerialDevice","isInstance":true,"pyQName":"serial.Serial.serial_device"},"serial.Serial.decoder":{"kind":2,"retType":"UTF8Decoder","isInstance":true},"serial.Serial.__constructor":{"kind":-3,"parameters":[{"name":"serialDevice","type":"SerialDevice"}],"isInstance":true},"serial.Serial.readString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"serial.Serial.read_string"},"serial.Serial.readLine":{"kind":-1,"retType":"string","parameters":[{"name":"timeOut","initializer":"undefined"}],"isInstance":true,"pyQName":"serial.Serial.read_line"},"serial.Serial.readUntil":{"kind":-1,"retType":"string","parameters":[{"name":"delimiter","type":"Delimiters","isEnum":true},{"name":"timeOut","initializer":"undefined"}],"isInstance":true,"pyQName":"serial.Serial.read_until"},"serial.Serial.writeString":{"kind":-1,"parameters":[{"name":"text","type":"string"}],"isInstance":true,"pyQName":"serial.Serial.write_string"},"serial.Serial.writeLine":{"kind":-1,"parameters":[{"name":"text","type":"string"}],"isInstance":true,"pyQName":"serial.Serial.write_line"},"serial.readString":{"kind":-3,"retType":"string","attributes":{"help":"serial/read-string","blockId":"serial_read_string","block":"serial|read string","weight":18,"group":"Read","jsDoc":"Read the buffered received data as a string","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read string","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.read_string"},"serial.readLine":{"kind":-3,"retType":"string","attributes":{"help":"serial/read-line","blockId":"serial_read_line","block":"serial|read line","weight":20,"blockGap":"8","group":"Read","jsDoc":"Read a line of text from the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read line","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.read_line"},"serial.readUntil":{"kind":-3,"retType":"string","attributes":{"help":"serial/read-until","blockId":"serial_read_until","block":"serial|read until %delimiter=serial_delimiter_conv","weight":19,"group":"Read","paramHelp":{"delimiter":"text delimiter that separates each text chunk"},"jsDoc":"Read a line of text from the serial port and return the buffer when the delimiter is met.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read until ","style":[]},{"kind":"param","name":"delimiter","shadowBlockId":"serial_delimiter_conv","ref":false}],"parameters":[{"kind":"param","name":"delimiter","shadowBlockId":"serial_delimiter_conv","ref":false}]}},"parameters":[{"name":"delimiter","description":"text delimiter that separates each text chunk","type":"Delimiters","isEnum":true},{"name":"timeOut","initializer":"undefined"}],"pyQName":"serial.read_until"},"serial.writeString":{"kind":-3,"attributes":{"help":"serial/write-string","weight":87,"blockId":"serial_writestring","block":"serial|write string %text","group":"Write","jsDoc":"Write some text to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write string ","style":[]},{"kind":"param","name":"text","ref":false}],"parameters":[{"kind":"param","name":"text","ref":false}]}},"parameters":[{"name":"text","type":"string"}],"pyQName":"serial.write_string"},"serial.writeLine":{"kind":-3,"attributes":{"weight":90,"help":"serial/write-line","blockGap":"8","blockId":"serial_writeline","block":"serial|write line %text","group":"Write","paramHelp":{"value":"to send over serial"},"jsDoc":"Write a line of text to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write line ","style":[]},{"kind":"param","name":"text","ref":false}],"parameters":[{"kind":"param","name":"text","ref":false}]}},"parameters":[{"name":"text","type":"string"}],"pyQName":"serial.write_line"},"serial.writeNumber":{"kind":-3,"attributes":{"help":"serial/write-number","weight":89,"blockGap":"8","blockId":"serial_writenumber","block":"serial|write number %value","group":"Write","jsDoc":"Write a number to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write number ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value"}],"pyQName":"serial.write_number"},"serial.writeValue":{"kind":-3,"attributes":{"paramDefl":{"name":"x"},"weight":88,"blockGap":"8","help":"serial/write-value","blockId":"serial_writevalue","block":"serial|write value %name|= %value","group":"Write","paramHelp":{"name":"name of the value stream, eg: \"x\"","value":"to write"},"jsDoc":"Write a name:value pair as a line of text to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write value ","style":[]},{"kind":"param","name":"name","ref":false},{"kind":"break"},{"kind":"label","text":"= ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"name","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"name","description":"name of the value stream, eg: \"x\"","type":"string","default":"x"},{"name":"value","description":"to write"}],"pyQName":"serial.write_value"},"serial.setRxBufferSize":{"kind":-3,"attributes":{"help":"serial/set-rx-buffer-size","blockId":"serialsetrxbuffersize","block":"serial set rx buffer size to $size","weight":10,"group":"Configuration","jsDoc":"Sets the size of the RX buffer in bytes","_def":{"parts":[{"kind":"label","text":"serial set rx buffer size to ","style":[]},{"kind":"param","name":"size","ref":true}],"parameters":[{"kind":"param","name":"size","ref":true}]}},"parameters":[{"name":"size"}],"pyQName":"serial.set_rx_buffer_size"},"serial.setTxBufferSize":{"kind":-3,"attributes":{"help":"serial/set-tx-buffer-size","blockId":"serialsettxbuffersize","block":"serial set tx buffer size to $size","weight":9,"group":"Configuration","jsDoc":"Sets the size of the TX buffer in bytes","_def":{"parts":[{"kind":"label","text":"serial set tx buffer size to ","style":[]},{"kind":"param","name":"size","ref":true}],"parameters":[{"kind":"param","name":"size","ref":true}]}},"parameters":[{"name":"size"}],"pyQName":"serial.set_tx_buffer_size"},"serial.read":{"kind":-3,"retType":"number","attributes":{"Group":"Read","jsDoc":"Reads a single byte from the serial receive buffer. Negative if error, 0 if no data."},"parameters":[]},"serial.readBuffer":{"kind":-3,"retType":"Buffer","attributes":{"help":"serial/read-buffer","blockId":"serial_read_buffer","block":"serial|read buffer","weight":17,"group":"Read","jsDoc":"Read the buffered received data as a buffer","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read buffer","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.read_buffer"},"serial.writeBuffer":{"kind":-3,"attributes":{"help":"serial/write-buffer","weight":6,"blockId":"serial_writebuffer","block":"serial|write buffer %buffer","group":"Write","jsDoc":"Send a buffer across the serial connection.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write buffer ","style":[]},{"kind":"param","name":"buffer","ref":false}],"parameters":[{"kind":"param","name":"buffer","ref":false}]}},"parameters":[{"name":"buffer","type":"Buffer"}],"pyQName":"serial.write_buffer"},"serial.setBaudRate":{"kind":-3,"attributes":{"weight":10,"blockId":"serial_setbaudrate","block":"serial|set baud rate %rate","blockGap":"8","inlineInputMode":"inline","help":"serial/set-baud-rate","group":"Configuration","jsDoc":"Set the baud rate of the serial port","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"set baud rate ","style":[]},{"kind":"param","name":"rate","ref":false}],"parameters":[{"kind":"param","name":"rate","ref":false}]}},"parameters":[{"name":"rate","type":"BaudRate","isEnum":true}],"pyQName":"serial.set_baud_rate"},"serial.attachToConsole":{"kind":-3,"attributes":{"blockId":"serialsendtoconsole","block":"serial attach to console","group":"Configuration","help":"serial/attach-to-console","jsDoc":"Send console messages through the TX, RX pins","_def":{"parts":[{"kind":"label","text":"serial attach to console","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.attach_to_console"},"serial.onEvent":{"kind":-3,"attributes":{"weight":9,"help":"serial/on-event","blockId":"serial_onevent","block":"serial on %event","blockGap":"8","group":"Events","jsDoc":"Registers code when serial events happen","_def":{"parts":[{"kind":"label","text":"serial on ","style":[]},{"kind":"param","name":"event","ref":false}],"parameters":[{"kind":"param","name":"event","ref":false}]}},"parameters":[{"name":"event","type":"SerialEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"serial.on_event"},"serial.onDelimiterReceived":{"kind":-3,"attributes":{"weight":10,"help":"serial/on-delimiter-received","blockId":"serial_ondelimiter","block":"serial on delimiter $delimiter received","blockGap":"8","group":"Events","jsDoc":"Registers code when a delimiter is received","_def":{"parts":[{"kind":"label","text":"serial on delimiter ","style":[]},{"kind":"param","name":"delimiter","ref":true},{"kind":"label","text":" received","style":[]}],"parameters":[{"kind":"param","name":"delimiter","ref":true}]}},"parameters":[{"name":"delimiter","type":"Delimiters","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"serial.on_delimiter_received"},"serial.delimiters":{"kind":-3,"retType":"string","attributes":{"blockId":"serial_delimiter_conv","block":"%del","weight":1,"blockHidden":true,"hidden":"true","jsDoc":"Return the corresponding delimiter string","_def":{"parts":[{"kind":"param","name":"del","ref":false}],"parameters":[{"kind":"param","name":"del","ref":false}]}},"parameters":[{"name":"del","type":"Delimiters","isEnum":true}]},"BaudRate":{"kind":6,"retType":"BaudRate","extendsTypes":["BaudRate","Number"]},"BaudRate.BaudRate115200":{"retType":"BaudRate.BaudRate115200","attributes":{"block":"115200","_def":{"parts":[{"kind":"label","text":"115200","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate115200","Number"],"pyQName":"BaudRate.BAUD_RATE115200"},"BaudRate.BaudRate57600":{"retType":"BaudRate.BaudRate57600","attributes":{"block":"57600","_def":{"parts":[{"kind":"label","text":"57600","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate57600","Number"],"pyQName":"BaudRate.BAUD_RATE57600"},"BaudRate.BaudRate38400":{"retType":"BaudRate.BaudRate38400","attributes":{"block":"38400","_def":{"parts":[{"kind":"label","text":"38400","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate38400","Number"],"pyQName":"BaudRate.BAUD_RATE38400"},"BaudRate.BaudRate31250":{"retType":"BaudRate.BaudRate31250","attributes":{"block":"31250","_def":{"parts":[{"kind":"label","text":"31250","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate31250","Number"],"pyQName":"BaudRate.BAUD_RATE31250"},"BaudRate.BaudRate28800":{"retType":"BaudRate.BaudRate28800","attributes":{"block":"28800","_def":{"parts":[{"kind":"label","text":"28800","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate28800","Number"],"pyQName":"BaudRate.BAUD_RATE28800"},"BaudRate.BaudRate19200":{"retType":"BaudRate.BaudRate19200","attributes":{"block":"19200","_def":{"parts":[{"kind":"label","text":"19200","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate19200","Number"],"pyQName":"BaudRate.BAUD_RATE19200"},"BaudRate.BaudRate14400":{"retType":"BaudRate.BaudRate14400","attributes":{"block":"14400","_def":{"parts":[{"kind":"label","text":"14400","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate14400","Number"],"pyQName":"BaudRate.BAUD_RATE14400"},"BaudRate.BaudRate9600":{"retType":"BaudRate.BaudRate9600","attributes":{"block":"9600","_def":{"parts":[{"kind":"label","text":"9600","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate9600","Number"],"pyQName":"BaudRate.BAUD_RATE9600"},"BaudRate.BaudRate4800":{"retType":"BaudRate.BaudRate4800","attributes":{"block":"4800","_def":{"parts":[{"kind":"label","text":"4800","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate4800","Number"],"pyQName":"BaudRate.BAUD_RATE4800"},"BaudRate.BaudRate2400":{"retType":"BaudRate.BaudRate2400","attributes":{"block":"2400","_def":{"parts":[{"kind":"label","text":"2400","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate2400","Number"],"pyQName":"BaudRate.BAUD_RATE2400"},"BaudRate.BaudRate1200":{"retType":"BaudRate.BaudRate1200","attributes":{"block":"1200","_def":{"parts":[{"kind":"label","text":"1200","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate1200","Number"],"pyQName":"BaudRate.BAUD_RATE1200"},"BaudRate.BaudRate300":{"retType":"BaudRate.BaudRate300","attributes":{"block":"300","_def":{"parts":[{"kind":"label","text":"300","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate300","Number"],"pyQName":"BaudRate.BAUD_RATE300"},"SerialEvent":{"kind":6,"retType":"SerialEvent","extendsTypes":["SerialEvent","Number"]},"SerialEvent.DataReceived":{"retType":"SerialEvent.DataReceived","attributes":{"block":"data received","_def":{"parts":[{"kind":"label","text":"data received","style":[]}],"parameters":[]}},"extendsTypes":["SerialEvent.DataReceived","Number"],"pyQName":"SerialEvent.DATA_RECEIVED"},"SerialEvent.RxBufferFull":{"retType":"SerialEvent.RxBufferFull","attributes":{"block":"rx buffer full","_def":{"parts":[{"kind":"label","text":"rx buffer full","style":[]}],"parameters":[]}},"extendsTypes":["SerialEvent.RxBufferFull","Number"],"pyQName":"SerialEvent.RX_BUFFER_FULL"},"Delimiters":{"kind":6,"retType":"Delimiters","extendsTypes":["Delimiters","Number"]},"Delimiters.NewLine":{"retType":"Delimiters.NewLine","attributes":{"block":"new line (\n)","_def":{"parts":[{"kind":"label","text":"new line (\n)","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.NewLine","Number"],"pyQName":"Delimiters.NEW_LINE"},"Delimiters.Comma":{"retType":"Delimiters.Comma","attributes":{"block":",","_def":{"parts":[{"kind":"label","text":",","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Comma","Number"],"pyQName":"Delimiters.COMMA"},"Delimiters.Dollar":{"retType":"Delimiters.Dollar","attributes":{"block":"$","_def":{"parts":[{"kind":"param","name":"","ref":true}],"parameters":[{"kind":"param","name":"","ref":true}]}},"extendsTypes":["Delimiters.Dollar","Number"],"pyQName":"Delimiters.DOLLAR"},"Delimiters.Colon":{"retType":"Delimiters.Colon","attributes":{"block":":","_def":{"parts":[{"kind":"label","text":":","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Colon","Number"],"pyQName":"Delimiters.COLON"},"Delimiters.Fullstop":{"retType":"Delimiters.Fullstop","attributes":{"block":".","_def":{"parts":[{"kind":"label","text":".","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Fullstop","Number"],"pyQName":"Delimiters.FULLSTOP"},"Delimiters.Hash":{"retType":"Delimiters.Hash","attributes":{"block":"#","_def":{"parts":[{"kind":"label","text":"#","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Hash","Number"],"pyQName":"Delimiters.HASH"},"Delimiters.CarriageReturn":{"retType":"Delimiters.CarriageReturn","attributes":{"block":"carriage return (\r)","_def":{"parts":[{"kind":"label","text":"carriage return (\r)","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.CarriageReturn","Number"],"pyQName":"Delimiters.CARRIAGE_RETURN"},"Delimiters.Space":{"retType":"Delimiters.Space","attributes":{"block":"space","_def":{"parts":[{"kind":"label","text":"space","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Space","Number"],"pyQName":"Delimiters.SPACE"},"Delimiters.Tab":{"retType":"Delimiters.Tab","attributes":{"block":"tab (\t)","_def":{"parts":[{"kind":"label","text":"tab (\t)","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Tab","Number"],"pyQName":"Delimiters.TAB"},"Delimiters.Pipe":{"retType":"Delimiters.Pipe","attributes":{"block":"|","_def":{"parts":[{"kind":"break"}],"parameters":[]}},"extendsTypes":["Delimiters.Pipe","Number"],"pyQName":"Delimiters.PIPE"},"Delimiters.SemiColon":{"retType":"Delimiters.SemiColon","attributes":{"block":";","_def":{"parts":[{"kind":"label","text":";","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.SemiColon","Number"],"pyQName":"Delimiters.SEMI_COLON"},"serial.internalCreateSerialDevice":{"kind":-3,"retType":"SerialDevice","attributes":{"jsDoc":"Opens a Serial communication driver"},"parameters":[{"name":"tx","type":"DigitalInOutPin"},{"name":"rx","type":"DigitalInOutPin"},{"name":"id"}],"pyQName":"serial.internal_create_serial_device"},"SerialDevice":{"kind":9,"retType":"SerialDevice","extendsTypes":[]},"SerialDevice.redirect":{"kind":-1,"parameters":[{"name":"tx","type":"DigitalInOutPin"},{"name":"rx","type":"DigitalInOutPin"},{"name":"rate","type":"BaudRate","isEnum":true}],"isInstance":true},"SerialDevice.setRxBufferSize":{"kind":-1,"attributes":{"jsDoc":"Sets the size of the RX buffer in bytes"},"parameters":[{"name":"size"}],"isInstance":true,"pyQName":"SerialDevice.set_rx_buffer_size"},"SerialDevice.setTxBufferSize":{"kind":-1,"attributes":{"jsDoc":"Sets the size of the TX buffer in bytes"},"parameters":[{"name":"size"}],"isInstance":true,"pyQName":"SerialDevice.set_tx_buffer_size"},"SerialDevice.setBaudRate":{"kind":-1,"attributes":{"jsDoc":"Set the baud rate of the serial port"},"parameters":[{"name":"rate","type":"BaudRate","isEnum":true}],"isInstance":true,"pyQName":"SerialDevice.set_baud_rate"},"SerialDevice.read":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Reads a single byte from the serial receive buffer. Negative if error, 0 if no data."},"parameters":[],"isInstance":true},"SerialDevice.readBuffer":{"kind":-1,"retType":"Buffer","attributes":{"jsDoc":"Read the buffered received data as a buffer"},"parameters":[],"isInstance":true,"pyQName":"SerialDevice.read_buffer"},"SerialDevice.writeBuffer":{"kind":-1,"attributes":{"jsDoc":"Send a buffer across the serial connection."},"parameters":[{"name":"buffer","type":"Buffer"}],"isInstance":true,"pyQName":"SerialDevice.write_buffer"},"SerialDevice.onEvent":{"kind":-1,"attributes":{"jsDoc":"Register code when a serial event occurs"},"parameters":[{"name":"event","type":"SerialEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"SerialDevice.on_event"},"SerialDevice.onDelimiterReceived":{"kind":-1,"attributes":{"jsDoc":"Registers code when a delimiter is received"},"parameters":[{"name":"delimiter","type":"Delimiters","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"SerialDevice.on_delimiter_received"}}},"sha":"9875d3b2f46a56197322e947d997ccdd65e81bf334d364a54784c996fd9efa09"},"libs/serial---linux":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"serial":{"kind":5,"retType":"","attributes":{"weight":2,"color":"#002050","icon":"","advanced":true,"blockGap":"8","groups":["Write","Read","Events","Configuration"],"jsDoc":"Reading and writing data over a serial connection."}},"serial.device":{"kind":-3,"retType":"serial.Serial","parameters":[]},"serial.NEW_LINE":{"kind":4,"retType":"string"},"serial.NEW_LINE_DELIMITER":{"kind":4,"retType":"Delimiters"},"serial.Serial":{"kind":8,"retType":"serial.Serial","extendsTypes":[]},"serial.Serial.serialDevice":{"kind":2,"retType":"SerialDevice","isInstance":true,"pyQName":"serial.Serial.serial_device"},"serial.Serial.decoder":{"kind":2,"retType":"UTF8Decoder","isInstance":true},"serial.Serial.__constructor":{"kind":-3,"parameters":[{"name":"serialDevice","type":"SerialDevice"}],"isInstance":true},"serial.Serial.readString":{"kind":-1,"retType":"string","parameters":[],"isInstance":true,"pyQName":"serial.Serial.read_string"},"serial.Serial.readLine":{"kind":-1,"retType":"string","parameters":[{"name":"timeOut","initializer":"undefined"}],"isInstance":true,"pyQName":"serial.Serial.read_line"},"serial.Serial.readUntil":{"kind":-1,"retType":"string","parameters":[{"name":"delimiter","type":"Delimiters","isEnum":true},{"name":"timeOut","initializer":"undefined"}],"isInstance":true,"pyQName":"serial.Serial.read_until"},"serial.Serial.writeString":{"kind":-1,"parameters":[{"name":"text","type":"string"}],"isInstance":true,"pyQName":"serial.Serial.write_string"},"serial.Serial.writeLine":{"kind":-1,"parameters":[{"name":"text","type":"string"}],"isInstance":true,"pyQName":"serial.Serial.write_line"},"serial.readString":{"kind":-3,"retType":"string","attributes":{"help":"serial/read-string","blockId":"serial_read_string","block":"serial|read string","weight":18,"group":"Read","jsDoc":"Read the buffered received data as a string","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read string","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.read_string"},"serial.readLine":{"kind":-3,"retType":"string","attributes":{"help":"serial/read-line","blockId":"serial_read_line","block":"serial|read line","weight":20,"blockGap":"8","group":"Read","jsDoc":"Read a line of text from the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read line","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.read_line"},"serial.readUntil":{"kind":-3,"retType":"string","attributes":{"help":"serial/read-until","blockId":"serial_read_until","block":"serial|read until %delimiter=serial_delimiter_conv","weight":19,"group":"Read","paramHelp":{"delimiter":"text delimiter that separates each text chunk"},"jsDoc":"Read a line of text from the serial port and return the buffer when the delimiter is met.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read until ","style":[]},{"kind":"param","name":"delimiter","shadowBlockId":"serial_delimiter_conv","ref":false}],"parameters":[{"kind":"param","name":"delimiter","shadowBlockId":"serial_delimiter_conv","ref":false}]}},"parameters":[{"name":"delimiter","description":"text delimiter that separates each text chunk","type":"Delimiters","isEnum":true},{"name":"timeOut","initializer":"undefined"}],"pyQName":"serial.read_until"},"serial.writeString":{"kind":-3,"attributes":{"help":"serial/write-string","weight":87,"blockId":"serial_writestring","block":"serial|write string %text","group":"Write","jsDoc":"Write some text to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write string ","style":[]},{"kind":"param","name":"text","ref":false}],"parameters":[{"kind":"param","name":"text","ref":false}]}},"parameters":[{"name":"text","type":"string"}],"pyQName":"serial.write_string"},"serial.writeLine":{"kind":-3,"attributes":{"weight":90,"help":"serial/write-line","blockGap":"8","blockId":"serial_writeline","block":"serial|write line %text","group":"Write","paramHelp":{"value":"to send over serial"},"jsDoc":"Write a line of text to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write line ","style":[]},{"kind":"param","name":"text","ref":false}],"parameters":[{"kind":"param","name":"text","ref":false}]}},"parameters":[{"name":"text","type":"string"}],"pyQName":"serial.write_line"},"serial.writeNumber":{"kind":-3,"attributes":{"help":"serial/write-number","weight":89,"blockGap":"8","blockId":"serial_writenumber","block":"serial|write number %value","group":"Write","jsDoc":"Write a number to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write number ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"value"}],"pyQName":"serial.write_number"},"serial.writeValue":{"kind":-3,"attributes":{"paramDefl":{"name":"x"},"weight":88,"blockGap":"8","help":"serial/write-value","blockId":"serial_writevalue","block":"serial|write value %name|= %value","group":"Write","paramHelp":{"name":"name of the value stream, eg: \"x\"","value":"to write"},"jsDoc":"Write a name:value pair as a line of text to the serial port.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write value ","style":[]},{"kind":"param","name":"name","ref":false},{"kind":"break"},{"kind":"label","text":"= ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"name","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"name","description":"name of the value stream, eg: \"x\"","type":"string","default":"x"},{"name":"value","description":"to write"}],"pyQName":"serial.write_value"},"serial.setRxBufferSize":{"kind":-3,"attributes":{"help":"serial/set-rx-buffer-size","blockId":"serialsetrxbuffersize","block":"serial set rx buffer size to $size","weight":10,"group":"Configuration","jsDoc":"Sets the size of the RX buffer in bytes","_def":{"parts":[{"kind":"label","text":"serial set rx buffer size to ","style":[]},{"kind":"param","name":"size","ref":true}],"parameters":[{"kind":"param","name":"size","ref":true}]}},"parameters":[{"name":"size"}],"pyQName":"serial.set_rx_buffer_size"},"serial.setTxBufferSize":{"kind":-3,"attributes":{"help":"serial/set-tx-buffer-size","blockId":"serialsettxbuffersize","block":"serial set tx buffer size to $size","weight":9,"group":"Configuration","jsDoc":"Sets the size of the TX buffer in bytes","_def":{"parts":[{"kind":"label","text":"serial set tx buffer size to ","style":[]},{"kind":"param","name":"size","ref":true}],"parameters":[{"kind":"param","name":"size","ref":true}]}},"parameters":[{"name":"size"}],"pyQName":"serial.set_tx_buffer_size"},"serial.read":{"kind":-3,"retType":"number","attributes":{"Group":"Read","jsDoc":"Reads a single byte from the serial receive buffer. Negative if error, 0 if no data."},"parameters":[]},"serial.readBuffer":{"kind":-3,"retType":"Buffer","attributes":{"help":"serial/read-buffer","blockId":"serial_read_buffer","block":"serial|read buffer","weight":17,"group":"Read","jsDoc":"Read the buffered received data as a buffer","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"read buffer","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.read_buffer"},"serial.writeBuffer":{"kind":-3,"attributes":{"help":"serial/write-buffer","weight":6,"blockId":"serial_writebuffer","block":"serial|write buffer %buffer","group":"Write","jsDoc":"Send a buffer across the serial connection.","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"write buffer ","style":[]},{"kind":"param","name":"buffer","ref":false}],"parameters":[{"kind":"param","name":"buffer","ref":false}]}},"parameters":[{"name":"buffer","type":"Buffer"}],"pyQName":"serial.write_buffer"},"serial.setBaudRate":{"kind":-3,"attributes":{"weight":10,"blockId":"serial_setbaudrate","block":"serial|set baud rate %rate","blockGap":"8","inlineInputMode":"inline","help":"serial/set-baud-rate","group":"Configuration","jsDoc":"Set the baud rate of the serial port","_def":{"parts":[{"kind":"label","text":"serial","style":[]},{"kind":"break"},{"kind":"label","text":"set baud rate ","style":[]},{"kind":"param","name":"rate","ref":false}],"parameters":[{"kind":"param","name":"rate","ref":false}]}},"parameters":[{"name":"rate","type":"BaudRate","isEnum":true}],"pyQName":"serial.set_baud_rate"},"serial.attachToConsole":{"kind":-3,"attributes":{"blockId":"serialsendtoconsole","block":"serial attach to console","group":"Configuration","help":"serial/attach-to-console","jsDoc":"Send console messages through the TX, RX pins","_def":{"parts":[{"kind":"label","text":"serial attach to console","style":[]}],"parameters":[]}},"parameters":[],"pyQName":"serial.attach_to_console"},"serial.onEvent":{"kind":-3,"attributes":{"weight":9,"help":"serial/on-event","blockId":"serial_onevent","block":"serial on %event","blockGap":"8","group":"Events","jsDoc":"Registers code when serial events happen","_def":{"parts":[{"kind":"label","text":"serial on ","style":[]},{"kind":"param","name":"event","ref":false}],"parameters":[{"kind":"param","name":"event","ref":false}]}},"parameters":[{"name":"event","type":"SerialEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"serial.on_event"},"serial.onDelimiterReceived":{"kind":-3,"attributes":{"weight":10,"help":"serial/on-delimiter-received","blockId":"serial_ondelimiter","block":"serial on delimiter $delimiter received","blockGap":"8","group":"Events","jsDoc":"Registers code when a delimiter is received","_def":{"parts":[{"kind":"label","text":"serial on delimiter ","style":[]},{"kind":"param","name":"delimiter","ref":true},{"kind":"label","text":" received","style":[]}],"parameters":[{"kind":"param","name":"delimiter","ref":true}]}},"parameters":[{"name":"delimiter","type":"Delimiters","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"serial.on_delimiter_received"},"serial.delimiters":{"kind":-3,"retType":"string","attributes":{"blockId":"serial_delimiter_conv","block":"%del","weight":1,"blockHidden":true,"hidden":"true","jsDoc":"Return the corresponding delimiter string","_def":{"parts":[{"kind":"param","name":"del","ref":false}],"parameters":[{"kind":"param","name":"del","ref":false}]}},"parameters":[{"name":"del","type":"Delimiters","isEnum":true}]},"BaudRate":{"kind":6,"retType":"BaudRate","extendsTypes":["BaudRate","Number"]},"BaudRate.BaudRate115200":{"retType":"BaudRate.BaudRate115200","attributes":{"block":"115200","_def":{"parts":[{"kind":"label","text":"115200","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate115200","Number"],"pyQName":"BaudRate.BAUD_RATE115200"},"BaudRate.BaudRate57600":{"retType":"BaudRate.BaudRate57600","attributes":{"block":"57600","_def":{"parts":[{"kind":"label","text":"57600","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate57600","Number"],"pyQName":"BaudRate.BAUD_RATE57600"},"BaudRate.BaudRate38400":{"retType":"BaudRate.BaudRate38400","attributes":{"block":"38400","_def":{"parts":[{"kind":"label","text":"38400","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate38400","Number"],"pyQName":"BaudRate.BAUD_RATE38400"},"BaudRate.BaudRate31250":{"retType":"BaudRate.BaudRate31250","attributes":{"block":"31250","_def":{"parts":[{"kind":"label","text":"31250","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate31250","Number"],"pyQName":"BaudRate.BAUD_RATE31250"},"BaudRate.BaudRate28800":{"retType":"BaudRate.BaudRate28800","attributes":{"block":"28800","_def":{"parts":[{"kind":"label","text":"28800","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate28800","Number"],"pyQName":"BaudRate.BAUD_RATE28800"},"BaudRate.BaudRate19200":{"retType":"BaudRate.BaudRate19200","attributes":{"block":"19200","_def":{"parts":[{"kind":"label","text":"19200","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate19200","Number"],"pyQName":"BaudRate.BAUD_RATE19200"},"BaudRate.BaudRate14400":{"retType":"BaudRate.BaudRate14400","attributes":{"block":"14400","_def":{"parts":[{"kind":"label","text":"14400","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate14400","Number"],"pyQName":"BaudRate.BAUD_RATE14400"},"BaudRate.BaudRate9600":{"retType":"BaudRate.BaudRate9600","attributes":{"block":"9600","_def":{"parts":[{"kind":"label","text":"9600","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate9600","Number"],"pyQName":"BaudRate.BAUD_RATE9600"},"BaudRate.BaudRate4800":{"retType":"BaudRate.BaudRate4800","attributes":{"block":"4800","_def":{"parts":[{"kind":"label","text":"4800","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate4800","Number"],"pyQName":"BaudRate.BAUD_RATE4800"},"BaudRate.BaudRate2400":{"retType":"BaudRate.BaudRate2400","attributes":{"block":"2400","_def":{"parts":[{"kind":"label","text":"2400","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate2400","Number"],"pyQName":"BaudRate.BAUD_RATE2400"},"BaudRate.BaudRate1200":{"retType":"BaudRate.BaudRate1200","attributes":{"block":"1200","_def":{"parts":[{"kind":"label","text":"1200","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate1200","Number"],"pyQName":"BaudRate.BAUD_RATE1200"},"BaudRate.BaudRate300":{"retType":"BaudRate.BaudRate300","attributes":{"block":"300","_def":{"parts":[{"kind":"label","text":"300","style":[]}],"parameters":[]}},"extendsTypes":["BaudRate.BaudRate300","Number"],"pyQName":"BaudRate.BAUD_RATE300"},"SerialEvent":{"kind":6,"retType":"SerialEvent","extendsTypes":["SerialEvent","Number"]},"SerialEvent.DataReceived":{"retType":"SerialEvent.DataReceived","attributes":{"block":"data received","_def":{"parts":[{"kind":"label","text":"data received","style":[]}],"parameters":[]}},"extendsTypes":["SerialEvent.DataReceived","Number"],"pyQName":"SerialEvent.DATA_RECEIVED"},"SerialEvent.RxBufferFull":{"retType":"SerialEvent.RxBufferFull","attributes":{"block":"rx buffer full","_def":{"parts":[{"kind":"label","text":"rx buffer full","style":[]}],"parameters":[]}},"extendsTypes":["SerialEvent.RxBufferFull","Number"],"pyQName":"SerialEvent.RX_BUFFER_FULL"},"Delimiters":{"kind":6,"retType":"Delimiters","extendsTypes":["Delimiters","Number"]},"Delimiters.NewLine":{"retType":"Delimiters.NewLine","attributes":{"block":"new line (\n)","_def":{"parts":[{"kind":"label","text":"new line (\n)","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.NewLine","Number"],"pyQName":"Delimiters.NEW_LINE"},"Delimiters.Comma":{"retType":"Delimiters.Comma","attributes":{"block":",","_def":{"parts":[{"kind":"label","text":",","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Comma","Number"],"pyQName":"Delimiters.COMMA"},"Delimiters.Dollar":{"retType":"Delimiters.Dollar","attributes":{"block":"$","_def":{"parts":[{"kind":"param","name":"","ref":true}],"parameters":[{"kind":"param","name":"","ref":true}]}},"extendsTypes":["Delimiters.Dollar","Number"],"pyQName":"Delimiters.DOLLAR"},"Delimiters.Colon":{"retType":"Delimiters.Colon","attributes":{"block":":","_def":{"parts":[{"kind":"label","text":":","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Colon","Number"],"pyQName":"Delimiters.COLON"},"Delimiters.Fullstop":{"retType":"Delimiters.Fullstop","attributes":{"block":".","_def":{"parts":[{"kind":"label","text":".","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Fullstop","Number"],"pyQName":"Delimiters.FULLSTOP"},"Delimiters.Hash":{"retType":"Delimiters.Hash","attributes":{"block":"#","_def":{"parts":[{"kind":"label","text":"#","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Hash","Number"],"pyQName":"Delimiters.HASH"},"Delimiters.CarriageReturn":{"retType":"Delimiters.CarriageReturn","attributes":{"block":"carriage return (\r)","_def":{"parts":[{"kind":"label","text":"carriage return (\r)","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.CarriageReturn","Number"],"pyQName":"Delimiters.CARRIAGE_RETURN"},"Delimiters.Space":{"retType":"Delimiters.Space","attributes":{"block":"space","_def":{"parts":[{"kind":"label","text":"space","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Space","Number"],"pyQName":"Delimiters.SPACE"},"Delimiters.Tab":{"retType":"Delimiters.Tab","attributes":{"block":"tab (\t)","_def":{"parts":[{"kind":"label","text":"tab (\t)","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.Tab","Number"],"pyQName":"Delimiters.TAB"},"Delimiters.Pipe":{"retType":"Delimiters.Pipe","attributes":{"block":"|","_def":{"parts":[{"kind":"break"}],"parameters":[]}},"extendsTypes":["Delimiters.Pipe","Number"],"pyQName":"Delimiters.PIPE"},"Delimiters.SemiColon":{"retType":"Delimiters.SemiColon","attributes":{"block":";","_def":{"parts":[{"kind":"label","text":";","style":[]}],"parameters":[]}},"extendsTypes":["Delimiters.SemiColon","Number"],"pyQName":"Delimiters.SEMI_COLON"},"serial.internalCreateSerialDevice":{"kind":-3,"retType":"SerialDevice","attributes":{"jsDoc":"Opens a Serial communication driver"},"parameters":[{"name":"id"}],"pyQName":"serial.internal_create_serial_device"},"SerialDevice":{"kind":9,"retType":"SerialDevice","extendsTypes":[]},"SerialDevice.setRxBufferSize":{"kind":-1,"attributes":{"jsDoc":"Sets the size of the RX buffer in bytes"},"parameters":[{"name":"size"}],"isInstance":true,"pyQName":"SerialDevice.set_rx_buffer_size"},"SerialDevice.setTxBufferSize":{"kind":-1,"attributes":{"jsDoc":"Sets the size of the TX buffer in bytes"},"parameters":[{"name":"size"}],"isInstance":true,"pyQName":"SerialDevice.set_tx_buffer_size"},"SerialDevice.setBaudRate":{"kind":-1,"attributes":{"jsDoc":"Set the baud rate of the serial port"},"parameters":[{"name":"rate","type":"BaudRate","isEnum":true}],"isInstance":true,"pyQName":"SerialDevice.set_baud_rate"},"SerialDevice.read":{"kind":-1,"retType":"number","attributes":{"jsDoc":"Reads a single byte from the serial receive buffer. Negative if error, 0 if no data."},"parameters":[],"isInstance":true},"SerialDevice.readBuffer":{"kind":-1,"retType":"Buffer","attributes":{"jsDoc":"Read the buffered received data as a buffer"},"parameters":[],"isInstance":true,"pyQName":"SerialDevice.read_buffer"},"SerialDevice.writeBuffer":{"kind":-1,"attributes":{"jsDoc":"Send a buffer across the serial connection."},"parameters":[{"name":"buffer","type":"Buffer"}],"isInstance":true,"pyQName":"SerialDevice.write_buffer"},"SerialDevice.onEvent":{"kind":-1,"attributes":{"jsDoc":"Register code when a serial event occurs"},"parameters":[{"name":"event","type":"SerialEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"SerialDevice.on_event"},"SerialDevice.onDelimiterReceived":{"kind":-1,"attributes":{"jsDoc":"Registers code when a delimiter is received"},"parameters":[{"name":"delimiter","type":"Delimiters","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"SerialDevice.on_delimiter_received"}}},"sha":"ea0ff45c6cd4147c672c403f4720010823c16c31dfe0a0cec75373b08ca4d41b"},"libs/servo":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"servos":{"kind":5,"retType":"","attributes":{"color":"#03AA74","weight":88,"icon":"","blockGap":"8","groups":["Positional","Continuous","Configuration"],"jsDoc":"Servos\n\nControl micro servos"}},"pins.P0":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P0 on the edge connector"}},"pins.P1":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P1 on the edge connector"}},"pins.P2":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P2 on the edge connector"}},"pins.P3":{"kind":4,"retType":"AnalogInPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P3 on the edge connector"}},"pins.P4":{"kind":4,"retType":"AnalogInPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P3 on the edge connector"}},"pins.P5":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P5 on the edge connector"}},"pins.P6":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P6 on the edge connector"}},"pins.P7":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P7 on the edge connector"}},"pins.P8":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P8 on the edge connector"}},"pins.P9":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P9 on the edge connector"}},"pins.P10":{"kind":4,"retType":"AnalogInPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P10 on the edge connector"}},"pins.P11":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P11 on the edge connector"}},"pins.P12":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P12 on the edge connector"}},"pins.P13":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P13 on the edge connector"}},"pins.P14":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P14 on the edge connector"}},"pins.P15":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P15 on the edge connector"}},"pins.P16":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P16 on the edge connector"}},"pins.P19":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P19 on the edge connector"}},"pins.P20":{"kind":4,"retType":"DigitalInOutPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P20 on the edge connector"}},"pins.P21":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P21 on the edge connector"}},"pins.P22":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P22 on the edge connector"}},"pins.P23":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P23 on the edge connector"}},"pins.P24":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P24 on the edge connector"}},"pins.P25":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P25 on the edge connector"}},"pins.P26":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P26 on the edge connector"}},"pins.P27":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P27 on the edge connector"}},"pins.P28":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P28 on the edge connector"}},"pins.P29":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P29 on the edge connector"}},"pins.P30":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P30 on the edge connector"}},"pins.P31":{"kind":4,"retType":"PwmPin","attributes":{"fixedInstance":"true","jsDoc":"Pin P31 on the edge connector"}},"DigitalPin":{"kind":6,"retType":"DigitalPin","extendsTypes":["DigitalPin","Number"]},"DigitalPin.P0":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P0","Number"]},"DigitalPin.P1":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P1","Number"]},"DigitalPin.P2":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P2","Number"]},"DigitalPin.P3":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P3","Number"]},"DigitalPin.P4":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P4","Number"]},"DigitalPin.P5":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P5","Number"]},"DigitalPin.P6":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P6","Number"]},"DigitalPin.P7":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P7","Number"]},"DigitalPin.P8":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P8","Number"]},"DigitalPin.P9":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P9","Number"]},"DigitalPin.P10":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P10","Number"]},"DigitalPin.P11":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P11","Number"]},"DigitalPin.P12":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P12","Number"]},"DigitalPin.P13":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P13","Number"]},"DigitalPin.P14":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P14","Number"]},"DigitalPin.P15":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P15","Number"]},"DigitalPin.P16":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P16","Number"]},"DigitalPin.P19":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P19","Number"]},"DigitalPin.P20":{"retType":"DigitalPin","extendsTypes":["DigitalPin.P20","Number"]},"AnalogPin":{"kind":6,"retType":"AnalogPin","extendsTypes":["AnalogPin","Number"]},"AnalogPin.P0":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P0","Number"]},"AnalogPin.P1":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P1","Number"]},"AnalogPin.P2":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P2","Number"]},"AnalogPin.P3":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P3","Number"]},"AnalogPin.P4":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P4","Number"]},"AnalogPin.P10":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P10","Number"]},"AnalogPin.P5":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P5","Number"]},"AnalogPin.P6":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P6","Number"]},"AnalogPin.P7":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P7","Number"]},"AnalogPin.P8":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P8","Number"]},"AnalogPin.P9":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P9","Number"]},"AnalogPin.P11":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P11","Number"]},"AnalogPin.P12":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P12","Number"]},"AnalogPin.P13":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P13","Number"]},"AnalogPin.P14":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P14","Number"]},"AnalogPin.P15":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P15","Number"]},"AnalogPin.P16":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P16","Number"]},"AnalogPin.P19":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P19","Number"]},"AnalogPin.P20":{"retType":"AnalogPin","extendsTypes":["AnalogPin.P20","Number"]},"pins.setPull":{"kind":-3,"attributes":{"deprecated":"1","paramHelp":{"pin":"@param mode "},"jsDoc":"Sets the pin pull"},"parameters":[{"name":"pin","description":"@param mode ","type":"DigitalPin","isEnum":true},{"name":"mode","type":"PinPullMode","isEnum":true}],"pyQName":"pins.set_pull"},"pins.digitalWritePin":{"kind":-3,"attributes":{"deprecated":"1","paramHelp":{"pin":"@param value "},"jsDoc":"Sets the digital pin status"},"parameters":[{"name":"pin","description":"@param value ","type":"DigitalPin","isEnum":true},{"name":"value"}],"pyQName":"pins.digital_write_pin"},"pins.digitalReadPin":{"kind":-3,"retType":"number","attributes":{"deprecated":"1","paramHelp":{"pin":""},"jsDoc":"Reads the pin status"},"parameters":[{"name":"pin","type":"DigitalPin","isEnum":true}],"pyQName":"pins.digital_read_pin"},"pins.analogWritePin":{"kind":-3,"attributes":{"deprecated":"1","paramHelp":{"pin":"@param value "},"jsDoc":"Sets the digital pin status"},"parameters":[{"name":"pin","description":"@param value ","type":"AnalogPin","isEnum":true},{"name":"value"}],"pyQName":"pins.analog_write_pin"},"pins.analogReadPin":{"kind":-3,"retType":"number","attributes":{"deprecated":"1","paramHelp":{"pin":""},"jsDoc":"Reads the pin status"},"parameters":[{"name":"pin","type":"AnalogPin","isEnum":true}],"pyQName":"pins.analog_read_pin"},"pins.onPulsed":{"kind":-3,"attributes":{"deprecated":"1","jsDoc":"Make this pin a digital input, and create events where the timestamp is the duration\nthat this pin was either ``high`` or ``low``."},"parameters":[{"name":"pin","type":"DigitalPin","isEnum":true},{"name":"pulse","type":"PulseValue","isEnum":true},{"name":"body","type":"() => void","handlerParameters":[]}],"pyQName":"pins.on_pulsed"},"pins.onEvent":{"kind":-3,"attributes":{"deprecated":"1","jsDoc":"Register code to run when a pin event occurs."},"parameters":[{"name":"pin","type":"DigitalPin","isEnum":true},{"name":"event","type":"PinEvent","isEnum":true},{"name":"body","type":"() => void","handlerParameters":[]}],"pyQName":"pins.on_event"},"pins.pulseIn":{"kind":-3,"retType":"number","attributes":{"deprecated":"1","paramHelp":{"name":"the pin which measures the pulse","value":"the value of the pulse (default high)","maximum":"duration in micro-seconds"},"jsDoc":"Return the duration of a pulse in microseconds"},"parameters":[{"name":"pin","type":"DigitalPin","isEnum":true},{"name":"value","description":"the value of the pulse (default high)","type":"PulseValue","isEnum":true},{"name":"maxDuration","initializer":"undefined"}],"pyQName":"pins.pulse_in"},"pins.map":{"kind":-3,"retType":"number","parameters":[{"name":"value"},{"name":"fromLow"},{"name":"fromHigh"},{"name":"toLow"},{"name":"toHigh"}]},"servos.Servo":{"kind":8,"retType":"servos.Servo","attributes":{"fixedInstances":"true"},"extendsTypes":["servos.Servo"]},"servos.Servo.__constructor":{"kind":-3,"parameters":[],"isInstance":true},"servos.Servo.setAngle":{"kind":-1,"attributes":{"paramDefl":{"degrees":"90"},"weight":100,"help":"servos/set-angle","blockId":"servoservosetangle","block":"set %servo angle to %degrees=protractorPicker °","explicitDefaults":["degrees"],"paramFieldEditor":{"servo":"gridpicker"},"paramFieldEditorOptions":{"servo":{"width":"220","columns":"2"}},"blockGap":"8","parts":"microservo","trackArgs":[0],"group":"Positional","jsDoc":"Set the servo angle","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"servo","ref":false},{"kind":"label","text":" angle to ","style":[]},{"kind":"param","name":"degrees","shadowBlockId":"protractorPicker","ref":false},{"kind":"label","text":" °","style":[]}],"parameters":[{"kind":"param","name":"servo","ref":false},{"kind":"param","name":"degrees","shadowBlockId":"protractorPicker","ref":false}]}},"parameters":[{"name":"degrees","initializer":"90","default":"90"}],"isInstance":true,"pyQName":"servos.Servo.set_angle"},"servos.Servo.angle":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"servos.Servo.run":{"kind":-1,"attributes":{"weight":99,"help":"servos/run","blockId":"servoservorun","block":"continuous %servo run at %speed=speedPicker \\%","paramFieldEditor":{"servo":"gridpicker"},"paramFieldEditorOptions":{"servo":{"width":"220","columns":"2"}},"parts":"microservo","trackArgs":[0],"group":"Continuous","blockGap":"8","paramHelp":{"speed":"the throttle of the motor from -100% to 100%"},"jsDoc":"Set the throttle on a continuous servo","_def":{"parts":[{"kind":"label","text":"continuous ","style":[]},{"kind":"param","name":"servo","ref":false},{"kind":"label","text":" run at ","style":[]},{"kind":"param","name":"speed","shadowBlockId":"speedPicker","ref":false},{"kind":"label","text":" %","style":[]}],"parameters":[{"kind":"param","name":"servo","ref":false},{"kind":"param","name":"speed","shadowBlockId":"speedPicker","ref":false}]}},"parameters":[{"name":"speed","description":"the throttle of the motor from -100% to 100%"}],"isInstance":true},"servos.Servo.setPulse":{"kind":-1,"attributes":{"paramDefl":{"micros":"1500"},"weight":10,"help":"servos/set-pulse","blockId":"servoservosetpulse","block":"set %servo pulse to %micros μs","paramMin":{"micros":"500"},"paramMax":{"micros":"2500"},"explicitDefaults":["micros"],"paramFieldEditor":{"servo":"gridpicker"},"paramFieldEditorOptions":{"servo":{"width":"220","columns":"2"}},"parts":"microservo","trackArgs":[0],"group":"Configuration","blockGap":"8","paramHelp":{"micros":"the width of the pulse in microseconds"},"jsDoc":"Set the pulse width to the servo in microseconds","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"servo","ref":false},{"kind":"label","text":" pulse to ","style":[]},{"kind":"param","name":"micros","ref":false},{"kind":"label","text":" μs","style":[]}],"parameters":[{"kind":"param","name":"servo","ref":false},{"kind":"param","name":"micros","ref":false}]}},"parameters":[{"name":"micros","description":"the width of the pulse in microseconds","initializer":"1500","default":"1500","options":{"min":{"value":"500"},"max":{"value":"2500"}}}],"isInstance":true,"pyQName":"servos.Servo.set_pulse"},"servos.Servo.stop":{"kind":-1,"attributes":{"weight":10,"help":"servos/stop","blockId":"servoservostop","block":"stop %servo","paramFieldEditor":{"servo":"gridpicker"},"paramFieldEditorOptions":{"servo":{"width":"220","columns":"2"}},"parts":"microservo","trackArgs":[0],"group":"Continuous","blockGap":"8","jsDoc":"Stop sending commands to the servo so that its rotation will stop at the current position.","_def":{"parts":[{"kind":"label","text":"stop ","style":[]},{"kind":"param","name":"servo","ref":false}],"parameters":[{"kind":"param","name":"servo","ref":false}]}},"parameters":[],"isInstance":true},"servos.Servo.minAngle":{"kind":-2,"retType":"number","attributes":{"jsDoc":"Gets the minimum angle for the servo"},"isInstance":true,"isReadOnly":true,"pyQName":"servos.Servo.min_angle"},"servos.Servo.maxAngle":{"kind":-2,"retType":"number","attributes":{"jsDoc":"Gets the maximum angle for the servo"},"isInstance":true,"isReadOnly":true,"pyQName":"servos.Servo.max_angle"},"servos.Servo.setRange":{"kind":-1,"attributes":{"paramDefl":{"maxAngle":"180"},"help":"servos/set-range","blockId":"servosetrange","block":"set %servo range from %minAngle to %maxAngle","paramMin":{"minAngle":"0","maxAngle":"90"},"paramMax":{"minAngle":"90","maxAngle":"180"},"explicitDefaults":["maxAngle"],"paramFieldEditor":{"servo":"gridpicker"},"paramFieldEditorOptions":{"servo":{"width":"220","columns":"2"}},"parts":"microservo","trackArgs":[0],"group":"Configuration","blockGap":"8","paramHelp":{"minAngle":"the minimum angle from 0 to 90","maxAngle":"the maximum angle from 90 to 180"},"jsDoc":"Set the possible rotation range angles for the servo between 0 and 180","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"servo","ref":false},{"kind":"label","text":" range from ","style":[]},{"kind":"param","name":"minAngle","ref":false},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"maxAngle","ref":false}],"parameters":[{"kind":"param","name":"servo","ref":false},{"kind":"param","name":"minAngle","ref":false},{"kind":"param","name":"maxAngle","ref":false}]}},"parameters":[{"name":"minAngle","description":"the minimum angle from 0 to 90","options":{"min":{"value":"0"},"max":{"value":"90"}}},{"name":"maxAngle","description":"the maximum angle from 90 to 180","initializer":"180","default":"180","options":{"min":{"value":"90"},"max":{"value":"180"}}}],"isInstance":true,"pyQName":"servos.Servo.set_range"},"servos.Servo.setStopOnNeutral":{"kind":-1,"attributes":{"help":"servos/set-stop-on-neutral","blockId":"servostoponneutral","block":"set %servo stop on neutral %enabled","_shadowOverrides":{"enabled":"toggleOnOff"},"group":"Configuration","blockGap":"8","paramFieldEditor":{"servo":"gridpicker"},"paramFieldEditorOptions":{"servo":{"width":"220","columns":"2"}},"paramHelp":{"on":"true to enable this mode"},"jsDoc":"Set a servo stop mode so it will stop when the rotation angle is in the neutral position, 90 degrees.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"servo","ref":false},{"kind":"label","text":" stop on neutral ","style":[]},{"kind":"param","name":"enabled","shadowBlockId":"toggleOnOff","ref":false}],"parameters":[{"kind":"param","name":"servo","ref":false},{"kind":"param","name":"enabled","shadowBlockId":"toggleOnOff","ref":false}]}},"parameters":[{"name":"enabled","type":"boolean"}],"isInstance":true,"pyQName":"servos.Servo.set_stop_on_neutral"},"servos.PinServo":{"kind":8,"retType":"servos.PinServo","extendsTypes":["servos.PinServo","servos.Servo"]},"servos.PinServo.__constructor":{"kind":-3,"parameters":[{"name":"pin","type":"PwmOnlyPin"}],"isInstance":true},"servos.P0":{"kind":4,"retType":"servos.PinServo","attributes":{"block":"servo P0","fixedInstance":"true","whenUsed":"true","_def":{"parts":[{"kind":"label","text":"servo P0","style":[]}],"parameters":[]}}},"servos.P1":{"kind":4,"retType":"servos.PinServo","attributes":{"block":"servo P1","fixedInstance":"true","whenUsed":"true","_def":{"parts":[{"kind":"label","text":"servo P1","style":[]}],"parameters":[]}}},"servos.P2":{"kind":4,"retType":"servos.PinServo","attributes":{"block":"servo P2","fixedInstance":"true","whenUsed":"true","_def":{"parts":[{"kind":"label","text":"servo P2","style":[]}],"parameters":[]}}}}},"sha":"28e3ae5610f79d15f9aa43b4c5868a16e62173a4689d281e6077208c51424794"},"libs/settings":{"apis":{"byQName":{}},"sha":"f17e136d04cf9fcdfedada4771621905847296f405689758e0d407d891b25f70"},"libs/settings---files":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""}}},"sha":"24a3978ca39cd1cbfc54326ef162da2960a56913aa97a052428bebd8916a8f5c"},"libs/sevenseg":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"SegmentStyle":{"kind":6,"retType":"SegmentStyle","extendsTypes":["SegmentStyle","Number"]},"SegmentStyle.Blank":{"retType":"SegmentStyle.Blank","attributes":{"block":"blank","_def":{"parts":[{"kind":"label","text":"blank","style":[]}],"parameters":[]}},"extendsTypes":["SegmentStyle.Blank","Number"],"pyQName":"SegmentStyle.BLANK"},"SegmentStyle.Thin":{"retType":"SegmentStyle.Thin","attributes":{"block":"thin","_def":{"parts":[{"kind":"label","text":"thin","style":[]}],"parameters":[]}},"extendsTypes":["SegmentStyle.Thin","Number"],"pyQName":"SegmentStyle.THIN"},"SegmentStyle.Narrow":{"retType":"SegmentStyle.Narrow","attributes":{"block":"narrow","_def":{"parts":[{"kind":"label","text":"narrow","style":[]}],"parameters":[]}},"extendsTypes":["SegmentStyle.Narrow","Number"],"pyQName":"SegmentStyle.NARROW"},"SegmentStyle.Medium":{"retType":"SegmentStyle.Medium","attributes":{"block":"medium","_def":{"parts":[{"kind":"label","text":"medium","style":[]}],"parameters":[]}},"extendsTypes":["SegmentStyle.Medium","Number"],"pyQName":"SegmentStyle.MEDIUM"},"SegmentStyle.Thick":{"retType":"SegmentStyle.Thick","attributes":{"block":"thick","_def":{"parts":[{"kind":"label","text":"thick","style":[]}],"parameters":[]}},"extendsTypes":["SegmentStyle.Thick","Number"],"pyQName":"SegmentStyle.THICK"},"DigitRadix":{"kind":6,"retType":"DigitRadix","extendsTypes":["DigitRadix","Number"]},"DigitRadix.Decimal":{"retType":"DigitRadix.Decimal","attributes":{"block":"decimal","_def":{"parts":[{"kind":"label","text":"decimal","style":[]}],"parameters":[]}},"extendsTypes":["DigitRadix.Decimal","Number"],"pyQName":"DigitRadix.DECIMAL"},"DigitRadix.Hex":{"retType":"DigitRadix.Hex","attributes":{"block":"hex","_def":{"parts":[{"kind":"label","text":"hex","style":[]}],"parameters":[]}},"extendsTypes":["DigitRadix.Hex","Number"],"pyQName":"DigitRadix.HEX"},"DigitRadix.Octal":{"retType":"DigitRadix.Octal","attributes":{"block":"octal","_def":{"parts":[{"kind":"label","text":"octal","style":[]}],"parameters":[]}},"extendsTypes":["DigitRadix.Octal","Number"],"pyQName":"DigitRadix.OCTAL"},"DigitRadix.Alpha":{"retType":"DigitRadix.Alpha","attributes":{"block":"alpha","_def":{"parts":[{"kind":"label","text":"alpha","style":[]}],"parameters":[]}},"extendsTypes":["DigitRadix.Alpha","Number"],"pyQName":"DigitRadix.ALPHA"},"SegmentScale":{"kind":6,"retType":"SegmentScale","extendsTypes":["SegmentScale","Number"]},"SegmentScale.Full":{"retType":"SegmentScale.Full","attributes":{"block":"full","_def":{"parts":[{"kind":"label","text":"full","style":[]}],"parameters":[]}},"extendsTypes":["SegmentScale.Full","Number"],"pyQName":"SegmentScale.FULL"},"SegmentScale.Half":{"retType":"SegmentScale.Half","attributes":{"block":"half","_def":{"parts":[{"kind":"label","text":"half","style":[]}],"parameters":[]}},"extendsTypes":["SegmentScale.Half","Number"],"pyQName":"SegmentScale.HALF"},"SegmentCharacter":{"kind":6,"retType":"SegmentCharacter","extendsTypes":["SegmentCharacter","Number"]},"SegmentCharacter.ZERO":{"retType":"SegmentCharacter.ZERO","attributes":{"block":"0","_def":{"parts":[{"kind":"label","text":"0","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.ZERO","Number"]},"SegmentCharacter.ONE":{"retType":"SegmentCharacter.ONE","attributes":{"block":"1","_def":{"parts":[{"kind":"label","text":"1","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.ONE","Number"]},"SegmentCharacter.TWO":{"retType":"SegmentCharacter.TWO","attributes":{"block":"2","_def":{"parts":[{"kind":"label","text":"2","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.TWO","Number"]},"SegmentCharacter.THREE":{"retType":"SegmentCharacter.THREE","attributes":{"block":"3","_def":{"parts":[{"kind":"label","text":"3","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.THREE","Number"]},"SegmentCharacter.FOUR":{"retType":"SegmentCharacter.FOUR","attributes":{"block":"4","_def":{"parts":[{"kind":"label","text":"4","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.FOUR","Number"]},"SegmentCharacter.FIVE":{"retType":"SegmentCharacter.FIVE","attributes":{"block":"5","_def":{"parts":[{"kind":"label","text":"5","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.FIVE","Number"]},"SegmentCharacter.SIX":{"retType":"SegmentCharacter.SIX","attributes":{"block":"6","_def":{"parts":[{"kind":"label","text":"6","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.SIX","Number"]},"SegmentCharacter.SEVEN":{"retType":"SegmentCharacter.SEVEN","attributes":{"block":"7","_def":{"parts":[{"kind":"label","text":"7","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.SEVEN","Number"]},"SegmentCharacter.EIGHT":{"retType":"SegmentCharacter.EIGHT","attributes":{"block":"8","_def":{"parts":[{"kind":"label","text":"8","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.EIGHT","Number"]},"SegmentCharacter.NINE":{"retType":"SegmentCharacter.NINE","attributes":{"block":"9","_def":{"parts":[{"kind":"label","text":"9","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.NINE","Number"]},"SegmentCharacter.A":{"retType":"SegmentCharacter.A","attributes":{"block":"A","_def":{"parts":[{"kind":"label","text":"A","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.A","Number"]},"SegmentCharacter.B":{"retType":"SegmentCharacter.B","attributes":{"block":"B","_def":{"parts":[{"kind":"label","text":"B","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.B","Number"]},"SegmentCharacter.C":{"retType":"SegmentCharacter.C","attributes":{"block":"C","_def":{"parts":[{"kind":"label","text":"C","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.C","Number"]},"SegmentCharacter.D":{"retType":"SegmentCharacter.D","attributes":{"block":"D","_def":{"parts":[{"kind":"label","text":"D","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.D","Number"]},"SegmentCharacter.E":{"retType":"SegmentCharacter.E","attributes":{"block":"E","_def":{"parts":[{"kind":"label","text":"E","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.E","Number"]},"SegmentCharacter.F":{"retType":"SegmentCharacter.F","attributes":{"block":"F","_def":{"parts":[{"kind":"label","text":"F","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.F","Number"]},"SegmentCharacter.H":{"retType":"SegmentCharacter.H","attributes":{"block":"H","_def":{"parts":[{"kind":"label","text":"H","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.H","Number"]},"SegmentCharacter.J":{"retType":"SegmentCharacter.J","attributes":{"block":"J","_def":{"parts":[{"kind":"label","text":"J","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.J","Number"]},"SegmentCharacter.L":{"retType":"SegmentCharacter.L","attributes":{"block":"L","_def":{"parts":[{"kind":"label","text":"L","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.L","Number"]},"SegmentCharacter.o":{"retType":"SegmentCharacter.o","attributes":{"block":"o","_def":{"parts":[{"kind":"label","text":"o","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.o","Number"],"pyQName":"SegmentCharacter.O"},"SegmentCharacter.P":{"retType":"SegmentCharacter.P","attributes":{"block":"P","_def":{"parts":[{"kind":"label","text":"P","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.P","Number"]},"SegmentCharacter.r":{"retType":"SegmentCharacter.r","attributes":{"block":"r","_def":{"parts":[{"kind":"label","text":"r","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.r","Number"],"pyQName":"SegmentCharacter.R"},"SegmentCharacter.U":{"retType":"SegmentCharacter.U","attributes":{"block":"U","_def":{"parts":[{"kind":"label","text":"U","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.U","Number"]},"SegmentCharacter.Y":{"retType":"SegmentCharacter.Y","attributes":{"block":"Y","_def":{"parts":[{"kind":"label","text":"Y","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.Y","Number"]},"SegmentCharacter.Hyphen":{"retType":"SegmentCharacter.Hyphen","attributes":{"block":"-","_def":{"parts":[{"kind":"label","text":"-","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.Hyphen","Number"],"pyQName":"SegmentCharacter.HYPHEN"},"SegmentCharacter.Degree":{"retType":"SegmentCharacter.Degree","attributes":{"block":"°","_def":{"parts":[{"kind":"label","text":"°","style":[]}],"parameters":[]}},"extendsTypes":["SegmentCharacter.Degree","Number"],"pyQName":"SegmentCharacter.DEGREE"},"sevenseg":{"kind":5,"retType":"","attributes":{"icon":"","color":"#4682B4","blockGap":"8","groups":["Create","Counter","Digits"],"jsDoc":"Seven segment display digits and gizmos"}},"sevenseg.drawSegment":{"kind":-3,"parameters":[{"name":"digit","type":"Image"},{"name":"segment","type":"Buffer"},{"name":"thickness","type":"SegmentStyle","isEnum":true},{"name":"color"}],"pyQName":"sevenseg.draw_segment"},"sevenseg.drawDigit":{"kind":-3,"parameters":[{"name":"digit","type":"Image"},{"name":"value"},{"name":"thickness","type":"SegmentStyle","isEnum":true},{"name":"scale","type":"SegmentScale","isEnum":true},{"name":"color"}],"pyQName":"sevenseg.draw_digit"},"sevenseg.createDigit":{"kind":-3,"retType":"SevenSegDigit","attributes":{"paramDefl":{"value":"0","thickness":"SegmentStyle.Thick"},"group":"Create","blockId":"sevenseg_create","block":"seven segment digit || of %thickness with value %value","expandableArgumentMode":"toggle","blockSetVariable":"myDigit","paramMin":{"value":"0"},"paramMax":{"value":"9"},"explicitDefaults":["value"],"weight":99,"help":"sevenseg/create-digit","paramHelp":{"thickness":"the width of the segments, eg: SegmentStyle.Thick","value":"optional initial display value, eg: 0"},"jsDoc":"Create a seven segment display digit","_def":{"parts":[{"kind":"label","text":"seven segment digit ","style":[]}],"parameters":[]},"_expandedDef":{"parts":[{"kind":"label","text":" of ","style":[]},{"kind":"param","name":"thickness","ref":false},{"kind":"label","text":" with value ","style":[]},{"kind":"param","name":"value","ref":false}],"parameters":[{"kind":"param","name":"thickness","ref":false},{"kind":"param","name":"value","ref":false}]}},"parameters":[{"name":"thickness","description":"the width of the segments, eg: SegmentStyle.Thick","type":"SegmentStyle","initializer":"SegmentStyle.Thick","default":"SegmentStyle.Thick","isEnum":true},{"name":"value","description":"optional initial display value, eg: 0","initializer":"0","default":"0","options":{"min":{"value":"0"},"max":{"value":"9"}}}],"pyQName":"sevenseg.create_digit"},"sevenseg.createCounter":{"kind":-3,"retType":"DigitCounter","attributes":{"paramDefl":{"numDigits":"1","thickness":"SegmentStyle.Thick","scale":"SegmentScale.Full"},"group":"Create","blockId":"sevenseg_createcounter","block":"counter || of %thickness segments at %scale size with %numDigits digits","expandableArgumentMode":"toggle","blockSetVariable":"myCounter","paramMin":{"numDigits":"1"},"paramMax":{"numDigits":"5"},"explicitDefaults":["numDigits"],"weight":100,"help":"sevenseg/create-counter","paramHelp":{"thickness":"the width of the segments, eg: SegmentStyle.Thick","scale":"the size of the segments, eg: SegmentScale.Full","numDigits":"the number of digits displayed, eg: 1"},"jsDoc":"Create a seven segment counter display","_def":{"parts":[{"kind":"label","text":"counter ","style":[]}],"parameters":[]},"_expandedDef":{"parts":[{"kind":"label","text":" of ","style":[]},{"kind":"param","name":"thickness","ref":false},{"kind":"label","text":" segments at ","style":[]},{"kind":"param","name":"scale","ref":false},{"kind":"label","text":" size with ","style":[]},{"kind":"param","name":"numDigits","ref":false},{"kind":"label","text":" digits","style":[]}],"parameters":[{"kind":"param","name":"thickness","ref":false},{"kind":"param","name":"scale","ref":false},{"kind":"param","name":"numDigits","ref":false}]}},"parameters":[{"name":"thickness","description":"the width of the segments, eg: SegmentStyle.Thick","type":"SegmentStyle","initializer":"SegmentStyle.Thick","default":"SegmentStyle.Thick","isEnum":true},{"name":"scale","description":"the size of the segments, eg: SegmentScale.Full","type":"SegmentScale","initializer":"SegmentScale.Full","default":"SegmentScale.Full","isEnum":true},{"name":"numDigits","description":"the number of digits displayed, eg: 1","initializer":"1","default":"1","options":{"min":{"value":"1"},"max":{"value":"5"}}}],"pyQName":"sevenseg.create_counter"},"SevenSegDigit":{"kind":8,"retType":"SevenSegDigit","attributes":{"blockNamespace":"sevenseg","color":"#4682B4","blockGap":"8"},"extendsTypes":[]},"SevenSegDigit.__constructor":{"kind":-3,"parameters":[{"name":"thickness","type":"SegmentStyle","initializer":"SegmentStyle.Thick","isEnum":true},{"name":"value","initializer":"0"}],"isInstance":true},"SevenSegDigit.setDigitAlpha":{"kind":-1,"attributes":{"paramDefl":{"alphaChar":"0"},"group":"Digits","blockId":"sevenseg_setalpha","block":"set %sevenseg(myDigit) display value to %alphaChar","weight":40,"paramHelp":{"alphaChar":"the display value, eg: \"0\""},"jsDoc":"Set the display value to a digit character: '0'- '9'","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sevenseg","ref":false,"varName":"myDigit"},{"kind":"label","text":" display value to ","style":[]},{"kind":"param","name":"alphaChar","ref":false}],"parameters":[{"kind":"param","name":"sevenseg","ref":false,"varName":"myDigit"},{"kind":"param","name":"alphaChar","ref":false}]}},"parameters":[{"name":"alphaChar","description":"the display value, eg: \"0\"","type":"SegmentCharacter","default":"0","isEnum":true}],"isInstance":true,"pyQName":"SevenSegDigit.set_digit_alpha"},"SevenSegDigit.value":{"kind":-2,"retType":"number","attributes":{"group":"Digits","blockSetVariable":"myDigit","blockCombine":true,"block":"value","weight":90,"_def":{"parts":[{"kind":"label","text":"value","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"SevenSegDigit.value@set":{"kind":-2,"retType":"number","attributes":{"group":"Digits","blockSetVariable":"myDigit","blockCombine":true,"block":"value","weight":90,"_def":{"parts":[{"kind":"label","text":"value","style":[]}],"parameters":[]}},"isInstance":true},"SevenSegDigit.setDigitColor":{"kind":-1,"attributes":{"paramDefl":{"color":"2"},"group":"Digits","blockId":"sevenseg_setcolor","block":"set %sevenseg(myDigit) display color to %color=colorindexpicker","weight":35,"help":"sevenseg/sevensegdigit/set-digit-color","paramHelp":{"color":"of the digit display, eg: 2"},"jsDoc":"Set the display digit color","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sevenseg","ref":false,"varName":"myDigit"},{"kind":"label","text":" display color to ","style":[]},{"kind":"param","name":"color","shadowBlockId":"colorindexpicker","ref":false}],"parameters":[{"kind":"param","name":"sevenseg","ref":false,"varName":"myDigit"},{"kind":"param","name":"color","shadowBlockId":"colorindexpicker","ref":false}]}},"parameters":[{"name":"color","description":"of the digit display, eg: 2","default":"2"}],"isInstance":true,"pyQName":"SevenSegDigit.set_digit_color"},"SevenSegDigit.x":{"kind":-2,"retType":"number","attributes":{"group":"Digits","blockSetVariable":"myDigit","blockCombine":true,"block":"x","_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"SevenSegDigit.x@set":{"kind":-2,"retType":"number","attributes":{"group":"Digits","blockSetVariable":"myDigit","blockCombine":true,"block":"x","_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"isInstance":true},"SevenSegDigit.y":{"kind":-2,"retType":"number","attributes":{"group":"Digits","blockSetVariable":"myDigit","blockCombine":true,"block":"y","_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"SevenSegDigit.y@set":{"kind":-2,"retType":"number","attributes":{"group":"Digits","blockSetVariable":"myDigit","blockCombine":true,"block":"y","_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"isInstance":true},"SevenSegDigit.width":{"kind":-2,"retType":"number","attributes":{"group":"Digits","blockSetVariable":"myDigit","blockCombine":true,"block":"width","_def":{"parts":[{"kind":"label","text":"width","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"SevenSegDigit.height":{"kind":-2,"retType":"number","attributes":{"group":"Digits","blockSetVariable":"myDigit","blockCombine":true,"block":"height","_def":{"parts":[{"kind":"label","text":"height","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"SevenSegDigit.setRadix":{"kind":-1,"attributes":{"paramDefl":{"radix":"DigitRadix.Decimal"},"blockId":"sevenseg_setradix","block":"set display radix of %sevenseg(myDigit) to %radix","group":"Digits","weight":30,"help":"sevenseg/sevensegdigit/set-radix","paramHelp":{"radix":"of the digit display, eg: DigitRadix.Decimal"},"jsDoc":"Set the display radix of the digit","_def":{"parts":[{"kind":"label","text":"set display radix of ","style":[]},{"kind":"param","name":"sevenseg","ref":false,"varName":"myDigit"},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"radix","ref":false}],"parameters":[{"kind":"param","name":"sevenseg","ref":false,"varName":"myDigit"},{"kind":"param","name":"radix","ref":false}]}},"parameters":[{"name":"radix","description":"of the digit display, eg: DigitRadix.Decimal","type":"DigitRadix","default":"DigitRadix.Decimal","isEnum":true}],"isInstance":true,"pyQName":"SevenSegDigit.set_radix"},"SevenSegDigit.setScale":{"kind":-1,"attributes":{"paramDefl":{"scale":"SegmentScale.Full"},"group":"Digits","blockId":"sevenseg_setdigitscale","block":"set %sevenseg(myDigit) to %scale size","weight":25,"help":"sevenseg/sevensegdigit/set-scale","paramHelp":{"scale":"of the digit display, eg: SegmentScale.Full"},"jsDoc":"Set the display digit size","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sevenseg","ref":false,"varName":"myDigit"},{"kind":"label","text":" to ","style":[]},{"kind":"param","name":"scale","ref":false},{"kind":"label","text":" size","style":[]}],"parameters":[{"kind":"param","name":"sevenseg","ref":false,"varName":"myDigit"},{"kind":"param","name":"scale","ref":false}]}},"parameters":[{"name":"scale","description":"of the digit display, eg: SegmentScale.Full","type":"SegmentScale","default":"SegmentScale.Full","isEnum":true}],"isInstance":true,"pyQName":"SevenSegDigit.set_scale"},"DigitCounter":{"kind":8,"retType":"DigitCounter","attributes":{"blockNamespace":"sevenseg","color":"#4682B4","blockGap":"8"},"extendsTypes":[]},"DigitCounter.__constructor":{"kind":-3,"parameters":[{"name":"thickness","type":"SegmentStyle","initializer":"SegmentStyle.Thick","isEnum":true},{"name":"scale","type":"SegmentScale","initializer":"SegmentScale.Full","isEnum":true},{"name":"numDigits","initializer":"3"}],"isInstance":true},"DigitCounter.addDigit":{"kind":-1,"attributes":{"jsDoc":"Add a digit to the counter"},"parameters":[],"isInstance":true,"pyQName":"DigitCounter.add_digit"},"DigitCounter.count":{"kind":-2,"retType":"number","attributes":{"group":"Counter","blockSetVariable":"myCounter","blockCombine":true,"block":"count","_def":{"parts":[{"kind":"label","text":"count","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"DigitCounter.count@set":{"kind":-2,"retType":"number","attributes":{"group":"Counter","blockSetVariable":"myCounter","blockCombine":true,"block":"count","_def":{"parts":[{"kind":"label","text":"count","style":[]}],"parameters":[]}},"isInstance":true},"DigitCounter.setDigitColor":{"kind":-1,"attributes":{"paramDefl":{"color":"2"},"group":"Counter","blockId":"sevenseg_setcountercolor","block":"set %sevenseg(myCounter) display color to %color=colorindexpicker","weight":86,"help":"sevenseg/digitcounter/set-digit-color","paramHelp":{"color":"of the digit display, eg: 2"},"jsDoc":"Set the counter display digit color","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sevenseg","ref":false,"varName":"myCounter"},{"kind":"label","text":" display color to ","style":[]},{"kind":"param","name":"color","shadowBlockId":"colorindexpicker","ref":false}],"parameters":[{"kind":"param","name":"sevenseg","ref":false,"varName":"myCounter"},{"kind":"param","name":"color","shadowBlockId":"colorindexpicker","ref":false}]}},"parameters":[{"name":"color","description":"of the digit display, eg: 2","default":"2"}],"isInstance":true,"pyQName":"DigitCounter.set_digit_color"},"DigitCounter.x":{"kind":-2,"retType":"number","attributes":{"group":"Counter","blockSetVariable":"myCounter","blockCombine":true,"block":"x","_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"DigitCounter.x@set":{"kind":-2,"retType":"number","attributes":{"group":"Counter","blockSetVariable":"myCounter","blockCombine":true,"block":"x","_def":{"parts":[{"kind":"label","text":"x","style":[]}],"parameters":[]}},"isInstance":true},"DigitCounter.y":{"kind":-2,"retType":"number","attributes":{"group":"Counter","blockSetVariable":"myCounter","blockCombine":true,"block":"y","_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"isInstance":true,"isReadOnly":true},"DigitCounter.y@set":{"kind":-2,"retType":"number","attributes":{"group":"Counter","blockSetVariable":"myCounter","blockCombine":true,"block":"y","_def":{"parts":[{"kind":"label","text":"y","style":[]}],"parameters":[]}},"isInstance":true}}},"sha":"0b70941e0db6454dcebd07bb9ab5b630ac3fcbe4ac06d6b0628f4af52b656746"},"libs/shader":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"texteffects":{"kind":5,"retType":""},"helpers.mapImage":{"kind":-3,"parameters":[{"name":"toShade","type":"Image"},{"name":"shadeLevels","type":"Image"},{"name":"x"},{"name":"y"},{"name":"m","type":"Buffer"}],"pyQName":"helpers.map_image"},"helpers.mergeImage":{"kind":-3,"parameters":[{"name":"dst","type":"Image"},{"name":"src","type":"Image"},{"name":"x"},{"name":"y"}],"pyQName":"helpers.merge_image"},"Shader":{"kind":9,"retType":"Shader","extendsTypes":[]}}},"sha":"bb5b87fd8b23d024940a185568d9c0504fc4e7911fafb9513cd820025d8808f2"},"libs/sprite-scaling":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"scaling":{"kind":5,"retType":"","attributes":{"color":"#95078E","weight":99,"icon":""}},"scaling.scaleToPercent":{"kind":-3,"attributes":{"paramDefl":{"value":"150","direction":"ScaleDirection.Uniformly","anchor":"ScaleAnchor.Middle"},"blockId":"sprite_scale_to_percent_ex","block":"set $sprite=variables_get(mySprite) scale to $value percent $direction anchor $anchor","expandableArgumentMode":"enabled","inlineInputMode":"inline","explicitDefaults":["value","direction","anchor"],"help":"sprites/scaling/scale-to-percent","paramHelp":{"sprite":"to scale to a percentage of its original size","value":"that is the percentage to scale the sprite, eg: 150","direction":"from the sprite anchor point, eg: ScaleDirection.Uniformly"},"jsDoc":"Scale a sprite to a percentage of its original size.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"label","text":" scale to ","style":[]},{"kind":"param","name":"value","ref":true},{"kind":"label","text":" percent ","style":[]},{"kind":"param","name":"direction","ref":true},{"kind":"label","text":" anchor ","style":[]},{"kind":"param","name":"anchor","ref":true}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"param","name":"value","ref":true},{"kind":"param","name":"direction","ref":true},{"kind":"param","name":"anchor","ref":true}]}},"parameters":[{"name":"sprite","description":"to scale to a percentage of its original size","type":"Sprite"},{"name":"value","description":"that is the percentage to scale the sprite, eg: 150","initializer":"150","default":"150"},{"name":"direction","description":"from the sprite anchor point, eg: ScaleDirection.Uniformly","type":"ScaleDirection","initializer":"ScaleDirection.Uniformly","default":"ScaleDirection.Uniformly","isEnum":true},{"name":"anchor","type":"ScaleAnchor","initializer":"ScaleAnchor.Middle","default":"ScaleAnchor.Middle","isEnum":true}],"pyQName":"scaling.scale_to_percent"},"scaling.scaleByPercent":{"kind":-3,"attributes":{"paramDefl":{"value":"50","direction":"ScaleDirection.Uniformly","anchor":"ScaleAnchor.Middle"},"blockId":"sprite_scale_by_percent_ex","block":"change $sprite=variables_get(mySprite) scale by $value percent $direction anchor $anchor","expandableArgumentMode":"enabled","inlineInputMode":"inline","explicitDefaults":["value","direction","anchor"],"help":"sprites/scaling/scale-by-percent","paramHelp":{"sprite":"to scale to a percentage of its original size","value":"that is the percentage to scale the sprite by, eg: 50","direction":"from the sprite anchor point, eg: ScaleDirection.Uniformly"},"jsDoc":"Scale a sprite by a percentage of its original size.","_def":{"parts":[{"kind":"label","text":"change ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"label","text":" scale by ","style":[]},{"kind":"param","name":"value","ref":true},{"kind":"label","text":" percent ","style":[]},{"kind":"param","name":"direction","ref":true},{"kind":"label","text":" anchor ","style":[]},{"kind":"param","name":"anchor","ref":true}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"param","name":"value","ref":true},{"kind":"param","name":"direction","ref":true},{"kind":"param","name":"anchor","ref":true}]}},"parameters":[{"name":"sprite","description":"to scale to a percentage of its original size","type":"Sprite"},{"name":"value","description":"that is the percentage to scale the sprite by, eg: 50","initializer":"50","default":"50"},{"name":"direction","description":"from the sprite anchor point, eg: ScaleDirection.Uniformly","type":"ScaleDirection","initializer":"ScaleDirection.Uniformly","default":"ScaleDirection.Uniformly","isEnum":true},{"name":"anchor","type":"ScaleAnchor","initializer":"ScaleAnchor.Middle","default":"ScaleAnchor.Middle","isEnum":true}],"pyQName":"scaling.scale_by_percent"},"scaling.scaleToPixels":{"kind":-3,"attributes":{"paramDefl":{"value":"32","direction":"ScaleDirection.Horizontally","anchor":"ScaleAnchor.Middle","proportional":"0"},"blockId":"sprite_scale_to_pixels_ex","block":"set $sprite=variables_get(mySprite) scale to $value pixels $direction anchor $anchor || proportional $proportional","expandableArgumentMode":"enabled","inlineInputMode":"inline","explicitDefaults":["value","direction","anchor","proportional"],"help":"sprites/scaling/scale-to-pixels","paramHelp":{"sprite":"to scale to new pixel size","value":"that is the number of pixels to scale the sprite to, eg: 32","direction":"from the sprite anchor point, eg: ScaleDirection.Horizontally"},"jsDoc":"Scale a sprite to a number of pixels.","_def":{"parts":[{"kind":"label","text":"set ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"label","text":" scale to ","style":[]},{"kind":"param","name":"value","ref":true},{"kind":"label","text":" pixels ","style":[]},{"kind":"param","name":"direction","ref":true},{"kind":"label","text":" anchor ","style":[]},{"kind":"param","name":"anchor","ref":true},{"kind":"label","text":" ","style":[]}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"param","name":"value","ref":true},{"kind":"param","name":"direction","ref":true},{"kind":"param","name":"anchor","ref":true}]},"_expandedDef":{"parts":[{"kind":"label","text":" proportional ","style":[]},{"kind":"param","name":"proportional","ref":true}],"parameters":[{"kind":"param","name":"proportional","ref":true}]}},"parameters":[{"name":"sprite","description":"to scale to new pixel size","type":"Sprite"},{"name":"value","description":"that is the number of pixels to scale the sprite to, eg: 32","initializer":"32","default":"32"},{"name":"direction","description":"from the sprite anchor point, eg: ScaleDirection.Horizontally","type":"ScaleDirection","initializer":"ScaleDirection.Horizontally","default":"ScaleDirection.Horizontally","isEnum":true},{"name":"anchor","type":"ScaleAnchor","initializer":"ScaleAnchor.Middle","default":"ScaleAnchor.Middle","isEnum":true},{"name":"proportional","type":"boolean","initializer":"0","default":"0"}],"pyQName":"scaling.scale_to_pixels"},"scaling.scaleByPixels":{"kind":-3,"attributes":{"paramDefl":{"value":"10","direction":"ScaleDirection.Horizontally","anchor":"ScaleAnchor.Middle","proportional":"0"},"blockId":"sprite_scale_by_pixels_ex","block":"change $sprite=variables_get(mySprite) scale by $value pixels $direction anchor $anchor || proportional $proportional","expandableArgumentMode":"enabled","inlineInputMode":"inline","explicitDefaults":["value","direction","anchor","proportional"],"help":"sprites/scaling/scale-by-pixels","paramHelp":{"sprite":"to scale to new pixel size","value":"that is the number of pixels to scale the sprite by, eg: 10","direction":"from the sprite anchor point, eg: ScaleDirection.Horizontally"},"jsDoc":"Scale a sprite by a number of pixels.","_def":{"parts":[{"kind":"label","text":"change ","style":[]},{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"label","text":" scale by ","style":[]},{"kind":"param","name":"value","ref":true},{"kind":"label","text":" pixels ","style":[]},{"kind":"param","name":"direction","ref":true},{"kind":"label","text":" anchor ","style":[]},{"kind":"param","name":"anchor","ref":true},{"kind":"label","text":" ","style":[]}],"parameters":[{"kind":"param","name":"sprite","shadowBlockId":"variables_get","ref":true,"varName":"mySprite"},{"kind":"param","name":"value","ref":true},{"kind":"param","name":"direction","ref":true},{"kind":"param","name":"anchor","ref":true}]},"_expandedDef":{"parts":[{"kind":"label","text":" proportional ","style":[]},{"kind":"param","name":"proportional","ref":true}],"parameters":[{"kind":"param","name":"proportional","ref":true}]}},"parameters":[{"name":"sprite","description":"to scale to new pixel size","type":"Sprite"},{"name":"value","description":"that is the number of pixels to scale the sprite by, eg: 10","initializer":"10","default":"10"},{"name":"direction","description":"from the sprite anchor point, eg: ScaleDirection.Horizontally","type":"ScaleDirection","initializer":"ScaleDirection.Horizontally","default":"ScaleDirection.Horizontally","isEnum":true},{"name":"anchor","type":"ScaleAnchor","initializer":"ScaleAnchor.Middle","default":"ScaleAnchor.Middle","isEnum":true},{"name":"proportional","type":"boolean","initializer":"0","default":"0"}],"pyQName":"scaling.scale_by_pixels"}}},"sha":"df11749e4868297d64fd57f7fa582ea0a598455c09c4187829edde04910fdcfb"},"libs/storyboard":{"apis":{"byQName":{"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"Colors":{"kind":6,"retType":"Colors","attributes":{"jsDoc":"Well known colors"},"extendsTypes":["Colors","Number"]},"Colors.Red":{"retType":"Colors.Red","attributes":{"block":"red","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"red","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Red","Number"],"pyQName":"Colors.RED"},"Colors.Orange":{"retType":"Colors.Orange","attributes":{"block":"orange","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"orange","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Orange","Number"],"pyQName":"Colors.ORANGE"},"Colors.Yellow":{"retType":"Colors.Yellow","attributes":{"block":"yellow","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"yellow","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Yellow","Number"],"pyQName":"Colors.YELLOW"},"Colors.Green":{"retType":"Colors.Green","attributes":{"block":"green","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"green","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Green","Number"],"pyQName":"Colors.GREEN"},"Colors.Blue":{"retType":"Colors.Blue","attributes":{"block":"blue","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"blue","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Blue","Number"],"pyQName":"Colors.BLUE"},"Colors.Indigo":{"retType":"Colors.Indigo","attributes":{"block":"indigo","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"indigo","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Indigo","Number"],"pyQName":"Colors.INDIGO"},"Colors.Violet":{"retType":"Colors.Violet","attributes":{"block":"violet","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"violet","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Violet","Number"],"pyQName":"Colors.VIOLET"},"Colors.Purple":{"retType":"Colors.Purple","attributes":{"block":"purple","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"purple","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Purple","Number"],"pyQName":"Colors.PURPLE"},"Colors.Pink":{"retType":"Colors.Pink","attributes":{"block":"pink","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"pink","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Pink","Number"],"pyQName":"Colors.PINK"},"Colors.White":{"retType":"Colors.White","attributes":{"block":"white","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"white","style":[]}],"parameters":[]}},"extendsTypes":["Colors.White","Number"],"pyQName":"Colors.WHITE"},"Colors.Black":{"retType":"Colors.Black","attributes":{"block":"black","blockIdentity":"color.wellKnown","_def":{"parts":[{"kind":"label","text":"black","style":[]}],"parameters":[]}},"extendsTypes":["Colors.Black","Number"],"pyQName":"Colors.BLACK"},"ColorHues":{"kind":6,"retType":"ColorHues","attributes":{"jsDoc":"Well known color hues"},"extendsTypes":["ColorHues","Number"]},"ColorHues.Red":{"retType":"ColorHues.Red","attributes":{"block":"red","_def":{"parts":[{"kind":"label","text":"red","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Red","Number"],"pyQName":"ColorHues.RED"},"ColorHues.Orange":{"retType":"ColorHues.Orange","attributes":{"block":"orange","_def":{"parts":[{"kind":"label","text":"orange","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Orange","Number"],"pyQName":"ColorHues.ORANGE"},"ColorHues.Yellow":{"retType":"ColorHues.Yellow","attributes":{"block":"yellow","_def":{"parts":[{"kind":"label","text":"yellow","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Yellow","Number"],"pyQName":"ColorHues.YELLOW"},"ColorHues.Green":{"retType":"ColorHues.Green","attributes":{"block":"green","_def":{"parts":[{"kind":"label","text":"green","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Green","Number"],"pyQName":"ColorHues.GREEN"},"ColorHues.Aqua":{"retType":"ColorHues.Aqua","attributes":{"block":"aqua","_def":{"parts":[{"kind":"label","text":"aqua","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Aqua","Number"],"pyQName":"ColorHues.AQUA"},"ColorHues.Blue":{"retType":"ColorHues.Blue","attributes":{"block":"blue","_def":{"parts":[{"kind":"label","text":"blue","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Blue","Number"],"pyQName":"ColorHues.BLUE"},"ColorHues.Purple":{"retType":"ColorHues.Purple","attributes":{"block":"purple","_def":{"parts":[{"kind":"label","text":"purple","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Purple","Number"],"pyQName":"ColorHues.PURPLE"},"ColorHues.Magenta":{"retType":"ColorHues.Magenta","attributes":{"block":"magenta","_def":{"parts":[{"kind":"label","text":"magenta","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Magenta","Number"],"pyQName":"ColorHues.MAGENTA"},"ColorHues.Pink":{"retType":"ColorHues.Pink","attributes":{"block":"pink","_def":{"parts":[{"kind":"label","text":"pink","style":[]}],"parameters":[]}},"extendsTypes":["ColorHues.Pink","Number"],"pyQName":"ColorHues.PINK"},"color":{"kind":5,"retType":"","attributes":{"advanced":true,"jsDoc":"Color manipulation"}},"color.rgb":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"red":"255","green":"255","blue":"255"},"blockId":"colorsrgb","block":"red %red|green %green|blue %blue","paramMin":{"red":"0","green":"0","blue":"0"},"paramMax":{"red":"255","green":"255","blue":"255"},"help":"colors/rgb","weight":19,"blockGap":"8","blockHidden":true,"paramHelp":{"red":"value of the red channel between 0 and 255. eg: 255","green":"value of the green channel between 0 and 255. eg: 255","blue":"value of the blue channel between 0 and 255. eg: 255"},"jsDoc":"Converts red, green, blue channels into a RGB color","_def":{"parts":[{"kind":"label","text":"red ","style":[]},{"kind":"param","name":"red","ref":false},{"kind":"break"},{"kind":"label","text":"green ","style":[]},{"kind":"param","name":"green","ref":false},{"kind":"break"},{"kind":"label","text":"blue ","style":[]},{"kind":"param","name":"blue","ref":false}],"parameters":[{"kind":"param","name":"red","ref":false},{"kind":"param","name":"green","ref":false},{"kind":"param","name":"blue","ref":false}]}},"parameters":[{"name":"red","description":"value of the red channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"green","description":"value of the green channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"blue","description":"value of the blue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.argb":{"kind":-3,"retType":"number","parameters":[{"name":"alpha"},{"name":"red"},{"name":"green"},{"name":"blue"}]},"color.wellKnown":{"kind":-3,"retType":"number","attributes":{"blockId":"colorscolors","block":"%color","help":"colors/well-known","shim":"TD_ID","weight":20,"blockGap":"8","blockHidden":true,"jsDoc":"Get the RGB value of a known color","_def":{"parts":[{"kind":"param","name":"color","ref":false}],"parameters":[{"kind":"param","name":"color","ref":false}]}},"parameters":[{"name":"color","type":"Colors","isEnum":true}],"pyQName":"color.well_known"},"color.hsv":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"hue":"255","sat":"255","val":"255"},"blockId":"colorshsv","block":"hue %hue|sat %sat|val %val","paramMin":{"hue":"0","sat":"0","val":"0"},"paramMax":{"hue":"255","sat":"255","val":"255"},"help":"colors/hsv","weight":17,"blockHidden":true,"paramHelp":{"hue":"value of the hue channel between 0 and 255. eg: 255","sat":"value of the saturation channel between 0 and 255. eg: 255","val":"value of the value channel between 0 and 255. eg: 255"},"jsDoc":"Convert an HSV (hue, saturation, value) color to RGB","_def":{"parts":[{"kind":"label","text":"hue ","style":[]},{"kind":"param","name":"hue","ref":false},{"kind":"break"},{"kind":"label","text":"sat ","style":[]},{"kind":"param","name":"sat","ref":false},{"kind":"break"},{"kind":"label","text":"val ","style":[]},{"kind":"param","name":"val","ref":false}],"parameters":[{"kind":"param","name":"hue","ref":false},{"kind":"param","name":"sat","ref":false},{"kind":"param","name":"val","ref":false}]}},"parameters":[{"name":"hue","description":"value of the hue channel between 0 and 255. eg: 255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"sat","description":"value of the saturation channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}},{"name":"val","description":"value of the value channel between 0 and 255. eg: 255","initializer":"255","default":"255","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.fade":{"kind":-3,"retType":"number","attributes":{"paramDefl":{"brightness":"128"},"blockId":"colorsfade","block":"fade %color=neopixel_colors|by %brightness","paramMin":{"brightness":"0"},"paramMax":{"brightness":"255"},"help":"light/fade","group":"Color","weight":18,"blockGap":"8","blockHidden":true,"paramHelp":{"color":"color to fade","brightness":"the amount of brightness to apply to the color, eg: 128"},"jsDoc":"Fade the color by the brightness","_def":{"parts":[{"kind":"label","text":"fade ","style":[]},{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"break"},{"kind":"label","text":"by ","style":[]},{"kind":"param","name":"brightness","ref":false}],"parameters":[{"kind":"param","name":"color","shadowBlockId":"neopixel_colors","ref":false},{"kind":"param","name":"brightness","ref":false}]}},"parameters":[{"name":"color","description":"color to fade"},{"name":"brightness","description":"the amount of brightness to apply to the color, eg: 128","default":"128","options":{"min":{"value":"0"},"max":{"value":"255"}}}]},"color.blend":{"kind":-3,"retType":"number","parameters":[{"name":"color"},{"name":"alpha"},{"name":"otherColor"}]},"color.gradient":{"kind":-3,"retType":"color.ColorBuffer","parameters":[{"name":"startColor"},{"name":"endColor"},{"name":"steps"}]},"color.unpackR":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_r"},"color.unpackG":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_g"},"color.unpackB":{"kind":-3,"retType":"number","parameters":[{"name":"rgb"}],"pyQName":"color.unpack_b"},"color.parseColor":{"kind":-3,"retType":"number","parameters":[{"name":"color","type":"string"}],"pyQName":"color.parse_color"},"color.ColorBufferLayout":{"kind":6,"retType":"color.ColorBufferLayout","extendsTypes":["color.ColorBufferLayout","Number"]},"color.ColorBufferLayout.RGB":{"retType":"color.ColorBufferLayout.RGB","attributes":{"jsDoc":"24bit RGB color"},"extendsTypes":["color.ColorBufferLayout.RGB","Number"]},"color.ColorBufferLayout.ARGB":{"retType":"color.ColorBufferLayout.ARGB","attributes":{"jsDoc":"32bit RGB color with alpha"},"extendsTypes":["color.ColorBufferLayout.ARGB","Number"]},"color.ColorBuffer":{"kind":8,"retType":"color.ColorBuffer","attributes":{"jsDoc":"A buffer of colors"},"extendsTypes":[]},"color.ColorBuffer.layout":{"kind":2,"retType":"color.ColorBufferLayout","isInstance":true},"color.ColorBuffer.buf":{"kind":2,"retType":"Buffer","isInstance":true},"color.ColorBuffer.__constructor":{"kind":-3,"parameters":[{"name":"length"},{"name":"layout","type":"color.ColorBufferLayout","initializer":"undefined","isEnum":true}],"isInstance":true},"color.ColorBuffer.fromBuffer":{"kind":-1,"retType":"color.ColorBuffer","parameters":[{"name":"buffer","type":"Buffer"},{"name":"layout","type":"color.ColorBufferLayout","isEnum":true}],"pyQName":"color.ColorBuffer.from_buffer"},"color.ColorBuffer.stride":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"color.ColorBuffer.length":{"kind":-2,"retType":"number","isInstance":true,"isReadOnly":true},"color.ColorBuffer.color":{"kind":-1,"retType":"number","parameters":[{"name":"index"}],"isInstance":true},"color.ColorBuffer.setColor":{"kind":-1,"parameters":[{"name":"index"},{"name":"color"}],"isInstance":true,"pyQName":"color.ColorBuffer.set_color"},"color.ColorBuffer.slice":{"kind":-1,"retType":"color.ColorBuffer","parameters":[{"name":"start","initializer":"undefined"},{"name":"length","initializer":"undefined"}],"isInstance":true},"color.ColorBuffer.write":{"kind":-1,"attributes":{"paramHelp":{"dstOffset":"@param src"},"jsDoc":"Writes the content of the src color buffer starting at the start dstOffset in the current buffer"},"parameters":[{"name":"dstOffset","description":"@param src"},{"name":"src","type":"color.ColorBuffer"}],"isInstance":true},"color.createBuffer":{"kind":-3,"retType":"color.ColorBuffer","attributes":{"jsDoc":"Converts an array of colors into a color buffer"},"parameters":[{"name":"colors","type":"number[]"},{"name":"layout","type":"color.ColorBufferLayout","initializer":"undefined","isEnum":true}],"pyQName":"color.create_buffer"},"music":{"kind":5,"retType":"","attributes":{"color":"#E30FC0","weight":90,"icon":"","blockGap":"8","groups":["Songs","Sounds","Tone","Volume","Tempo"],"jsDoc":"Generation of music tones."}},"game":{"kind":5,"retType":"","attributes":{"color":"#8854d0","weight":97,"icon":"","blockGap":"8","groups":["Gameplay","Game Over","Prompt","Dialogs"],"jsDoc":"Game transitions and dialog"}},"sprites":{"kind":5,"retType":"","attributes":{"weight":99,"color":"#4B7BEC","icon":"","groups":["Create","Physics","Effects","Projectiles","Overlaps","Lifecycle"],"jsDoc":"Sprites on screen"}},"scene":{"kind":5,"retType":"","attributes":{"weight":88,"color":"#4b6584","icon":"","groups":["Screen","Camera","Effects","Tilemaps","Tilemap Operations","Locations"],"blockGap":"8","jsDoc":"Control the background, tiles and camera"}},"info":{"kind":5,"retType":"","attributes":{"color":"#cf6a87","weight":80,"icon":"","blockGap":"8","groups":["Score","Life","Countdown","Multiplayer"],"jsDoc":"Head-up display"}},"palette":{"kind":5,"retType":"","attributes":{"jsDoc":"Update the current scene palette"}},"palette.defaultPalette":{"kind":-3,"retType":"color.ColorBuffer","attributes":{"jsDoc":"Returns a clone of the default palette"},"parameters":[],"pyQName":"palette.default_palette"},"palette.setColors":{"kind":-3,"attributes":{"paramHelp":{"pOffset":"The offset to start copying from the palette"},"jsDoc":"Dynamically set all or part of the game's current palette\n* @param palette The colors to set"},"parameters":[{"name":"palette","type":"color.ColorBuffer"},{"name":"pOffset","description":"The offset to start copying from the palette","initializer":"0"}],"pyQName":"palette.set_colors"},"palette.getCurrentColors":{"kind":-3,"retType":"color.ColorBuffer","attributes":{"jsDoc":"Get the palette that is currently being used"},"parameters":[],"pyQName":"palette.get_current_colors"},"palette.reset":{"kind":-3,"attributes":{"jsDoc":"Reset to default palette"},"parameters":[]},"storyboard":{"kind":5,"retType":"","attributes":{"icon":"","weight":87,"color":"#401255","jsDoc":"A manager of scenes"}},"storyboard.FrameOptions":{"kind":9,"retType":"storyboard.FrameOptions","extendsTypes":[]},"storyboard.FrameOptions.background":{"kind":2,"retType":"number","isInstance":true},"storyboard.Frame":{"kind":8,"retType":"storyboard.Frame","extendsTypes":[]},"storyboard.Frame.start":{"kind":2,"retType":"() => void","isInstance":true},"storyboard.Frame.options":{"kind":2,"retType":"storyboard.FrameOptions","isInstance":true},"storyboard.Frame.__constructor":{"kind":-3,"parameters":[{"name":"start","type":"() => void","handlerParameters":[]},{"name":"options","type":"storyboard.FrameOptions"}],"isInstance":true},"storyboard.BootSequence":{"kind":8,"retType":"storyboard.BootSequence","attributes":{"fixedInstances":"true"},"extendsTypes":[]},"storyboard.BootSequence.start":{"kind":2,"retType":"(done: () => void) => void","isInstance":true},"storyboard.BootSequence.background":{"kind":2,"retType":"number","isInstance":true},"storyboard.BootSequence.__constructor":{"kind":-3,"parameters":[{"name":"start","type":"(done: () => void) => void","handlerParameters":[{"name":"done","type":"() => void"}]},{"name":"background"}],"isInstance":true},"storyboard.BootSequence.register":{"kind":-1,"attributes":{"block":"storyboard register %boot| boot sequence","blockId":"storyboardregister","jsDoc":"Registers the boot sequence","_def":{"parts":[{"kind":"label","text":"storyboard register ","style":[]},{"kind":"param","name":"boot","ref":false},{"kind":"break"},{"kind":"label","text":" boot sequence","style":[]}],"parameters":[{"kind":"param","name":"boot","ref":false}]}},"parameters":[],"isInstance":true},"storyboard.registerScene":{"kind":-3,"attributes":{"paramHelp":{"name":"@param scene "},"jsDoc":"Registers a scene"},"parameters":[{"name":"name","description":"@param scene ","type":"string"},{"name":"start","type":"() => void","handlerParameters":[]},{"name":"options","type":"storyboard.FrameOptions","initializer":"undefined"}],"pyQName":"storyboard.register_scene"},"storyboard.start":{"kind":-3,"attributes":{"block":"storyboard start at $name","blockId":"storyboardstart","paramHelp":{"name":""},"jsDoc":"Starts the story board by running boot sequences then entering a scene","_def":{"parts":[{"kind":"label","text":"storyboard start at ","style":[]},{"kind":"param","name":"name","ref":true}],"parameters":[{"kind":"param","name":"name","ref":true}]}},"parameters":[{"name":"name","type":"string","initializer":"undefined"}]},"storyboard.replace":{"kind":-3,"attributes":{"block":"storyboard replace scene $name","blockId":"storyboardreplace","paramHelp":{"name":""},"jsDoc":"Replace the current scene with the given scene","_def":{"parts":[{"kind":"label","text":"storyboard replace scene ","style":[]},{"kind":"param","name":"name","ref":true}],"parameters":[{"kind":"param","name":"name","ref":true}]}},"parameters":[{"name":"name","type":"string"}]},"storyboard.push":{"kind":-3,"attributes":{"block":"storyboard push scene $name","blockId":"storyboardpush","paramHelp":{"name":""},"jsDoc":"Transition to a registered scene","_def":{"parts":[{"kind":"label","text":"storyboard push scene ","style":[]},{"kind":"param","name":"name","ref":true}],"parameters":[{"kind":"param","name":"name","ref":true}]}},"parameters":[{"name":"name","type":"string"}]},"storyboard.pop":{"kind":-3,"attributes":{"block":"storyboard pop frame","blockId":"storyboardpop","jsDoc":"Stops the current scene and restart the previous scene","_def":{"parts":[{"kind":"label","text":"storyboard pop frame","style":[]}],"parameters":[]}},"parameters":[]},"storyboard.loaderBootSequence":{"kind":4,"retType":"storyboard.BootSequence","attributes":{"block":"loader","fixedInstance":"true","whenUsed":"true","jsDoc":"Default boot sequence","_def":{"parts":[{"kind":"label","text":"loader","style":[]}],"parameters":[]}},"pyQName":"storyboard.loader_boot_sequence"}}},"sha":"5bf7022db014e5fdad7a38e9a8d72ab8370c802ca554951f9b560b8ed1eda67e"},"libs/template":{"apis":{"byQName":{}},"sha":"b6f2043e9a677e8e06e2702466e573f80b22417e74b1bb4d3abab223162915c6"},"libs/thermometer":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"input":{"kind":5,"retType":"","attributes":{"color":"#B4009E","weight":98,"icon":"","groups":["other","More"],"jsDoc":"Respond to and read data from buttons and sensors.\n\nEvents and data from sensors."}},"basic":{"kind":5,"retType":""},"input.onTemperatureConditionChanged":{"kind":-3,"attributes":{"paramDefl":{"temperature":"15"},"blockId":"input_on_temperature_condition_changed","block":"on temperature %condition|at %temperature|%unit","parts":"thermometer","help":"input/on-temperature-condition-changed","blockExternalInputs":"0","group":"More","weight":76,"inlineInputMode":"external","paramHelp":{"condition":"the condition, hot or cold, the event triggers on","temperature":"the temperature at which this event happens, eg: 15","unit":"the unit of the temperature"},"jsDoc":"Run some code when the temperature changes from hot to cold, or from cold to hot.","_def":{"parts":[{"kind":"label","text":"on temperature ","style":[]},{"kind":"param","name":"condition","ref":false},{"kind":"break"},{"kind":"label","text":"at ","style":[]},{"kind":"param","name":"temperature","ref":false},{"kind":"break"},{"kind":"param","name":"unit","ref":false}],"parameters":[{"kind":"param","name":"condition","ref":false},{"kind":"param","name":"temperature","ref":false},{"kind":"param","name":"unit","ref":false}]}},"parameters":[{"name":"condition","description":"the condition, hot or cold, the event triggers on","type":"TemperatureCondition","isEnum":true},{"name":"temperature","description":"the temperature at which this event happens, eg: 15","default":"15"},{"name":"unit","description":"the unit of the temperature","type":"TemperatureUnit","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"input.on_temperature_condition_changed"},"input.temperature":{"kind":-3,"retType":"number","attributes":{"help":"input/temperature","blockId":"device_temperature","block":"temperature in %unit","parts":"thermometer","weight":26,"jsDoc":"Get the temperature in Celsius or Fahrenheit degrees.","_def":{"parts":[{"kind":"label","text":"temperature in ","style":[]},{"kind":"param","name":"unit","ref":false}],"parameters":[{"kind":"param","name":"unit","ref":false}]}},"parameters":[{"name":"unit","type":"TemperatureUnit","isEnum":true}]},"TemperatureCondition":{"kind":6,"retType":"TemperatureCondition","extendsTypes":["TemperatureCondition","Number"]},"TemperatureCondition.Hot":{"retType":"TemperatureCondition.Hot","attributes":{"block":"hot","_def":{"parts":[{"kind":"label","text":"hot","style":[]}],"parameters":[]}},"extendsTypes":["TemperatureCondition.Hot","Number"],"pyQName":"TemperatureCondition.HOT"},"TemperatureCondition.Cold":{"retType":"TemperatureCondition.Cold","attributes":{"block":"cold","_def":{"parts":[{"kind":"label","text":"cold","style":[]}],"parameters":[]}},"extendsTypes":["TemperatureCondition.Cold","Number"],"pyQName":"TemperatureCondition.COLD"},"TemperatureUnit":{"kind":6,"retType":"TemperatureUnit","extendsTypes":["TemperatureUnit","Number"]},"TemperatureUnit.Celsius":{"retType":"TemperatureUnit.Celsius","attributes":{"block":"°C","_def":{"parts":[{"kind":"label","text":"°C","style":[]}],"parameters":[]}},"extendsTypes":["TemperatureUnit.Celsius","Number"],"pyQName":"TemperatureUnit.CELSIUS"},"TemperatureUnit.Fahrenheit":{"retType":"TemperatureUnit.Fahrenheit","attributes":{"block":"°F","_def":{"parts":[{"kind":"label","text":"°F","style":[]}],"parameters":[]}},"extendsTypes":["TemperatureUnit.Fahrenheit","Number"],"pyQName":"TemperatureUnit.FAHRENHEIT"}}},"sha":"af93c81ca3226f4d8d1ff761a1d0a2405778da595114e9e5c16fc7107fe5a1b3"},"libs/browser-events":{"apis":{"byQName":{"Math":{"kind":5,"retType":"","attributes":{"jsDoc":"More complex operations with numbers."}},"control":{"kind":5,"retType":"","attributes":{"weight":90,"color":"#FF5722","icon":"","advanced":true,"jsDoc":"Program controls and events."}},"helpers":{"kind":5,"retType":""},"__internal":{"kind":5,"retType":"","attributes":{"blockHidden":true}},"pins":{"kind":5,"retType":"","attributes":{"color":"#A80000","weight":85,"icon":"","advanced":true,"groups":["other","Servo","i2c"],"jsDoc":"Control currents in Pins for analog/digital signals, servos, i2c, ..."}},"basic":{"kind":5,"retType":""},"browserEvents":{"kind":5,"retType":"","attributes":{"icon":"","color":"#9c1355","block":"Browser Events","_def":{"parts":[{"kind":"label","text":"Browser Events","style":[]}],"parameters":[]}}},"browserEvents.Event":{"kind":6,"retType":"browserEvents.Event","extendsTypes":["browserEvents.Event","Number"]},"browserEvents.Event.PointerDown":{"retType":"browserEvents.Event.PointerDown","attributes":{"block":"pointer down","_def":{"parts":[{"kind":"label","text":"pointer down","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.Event.PointerDown","Number"],"pyQName":"browserEvents.Event.POINTER_DOWN"},"browserEvents.Event.PointerUp":{"retType":"browserEvents.Event.PointerUp","attributes":{"block":"pointer up","_def":{"parts":[{"kind":"label","text":"pointer up","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.Event.PointerUp","Number"],"pyQName":"browserEvents.Event.POINTER_UP"},"browserEvents.Event.PointerMove":{"retType":"browserEvents.Event.PointerMove","attributes":{"block":"pointer move","_def":{"parts":[{"kind":"label","text":"pointer move","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.Event.PointerMove","Number"],"pyQName":"browserEvents.Event.POINTER_MOVE"},"browserEvents.Event.PointerLeave":{"retType":"browserEvents.Event.PointerLeave","attributes":{"block":"pointer leave","_def":{"parts":[{"kind":"label","text":"pointer leave","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.Event.PointerLeave","Number"],"pyQName":"browserEvents.Event.POINTER_LEAVE"},"browserEvents.Event.PointerEnter":{"retType":"browserEvents.Event.PointerEnter","attributes":{"block":"pointer enter","_def":{"parts":[{"kind":"label","text":"pointer enter","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.Event.PointerEnter","Number"],"pyQName":"browserEvents.Event.POINTER_ENTER"},"browserEvents.Event.PointerCancel":{"retType":"browserEvents.Event.PointerCancel","attributes":{"block":"pointer cancel","_def":{"parts":[{"kind":"label","text":"pointer cancel","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.Event.PointerCancel","Number"],"pyQName":"browserEvents.Event.POINTER_CANCEL"},"browserEvents.Event.PointerOver":{"retType":"browserEvents.Event.PointerOver","attributes":{"block":"pointer over","_def":{"parts":[{"kind":"label","text":"pointer over","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.Event.PointerOver","Number"],"pyQName":"browserEvents.Event.POINTER_OVER"},"browserEvents.Event.PointerOut":{"retType":"browserEvents.Event.PointerOut","attributes":{"block":"pointer out","_def":{"parts":[{"kind":"label","text":"pointer out","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.Event.PointerOut","Number"],"pyQName":"browserEvents.Event.POINTER_OUT"},"browserEvents.Event.Wheel":{"retType":"browserEvents.Event.Wheel","attributes":{"block":"wheel","_def":{"parts":[{"kind":"label","text":"wheel","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.Event.Wheel","Number"],"pyQName":"browserEvents.Event.WHEEL"},"browserEvents.Event.KeyDown":{"retType":"browserEvents.Event.KeyDown","attributes":{"block":"key down","_def":{"parts":[{"kind":"label","text":"key down","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.Event.KeyDown","Number"],"pyQName":"browserEvents.Event.KEY_DOWN"},"browserEvents.Event.KeyUp":{"retType":"browserEvents.Event.KeyUp","attributes":{"block":"key up","_def":{"parts":[{"kind":"label","text":"key up","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.Event.KeyUp","Number"],"pyQName":"browserEvents.Event.KEY_UP"},"browserEvents.MouseButtonId":{"kind":6,"retType":"browserEvents.MouseButtonId","extendsTypes":["browserEvents.MouseButtonId","Number"]},"browserEvents.MouseButtonId.Left":{"retType":"browserEvents.MouseButtonId.Left","attributes":{"block":"left","_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.MouseButtonId.Left","Number"],"pyQName":"browserEvents.MouseButtonId.LEFT"},"browserEvents.MouseButtonId.Right":{"retType":"browserEvents.MouseButtonId.Right","attributes":{"block":"right","_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.MouseButtonId.Right","Number"],"pyQName":"browserEvents.MouseButtonId.RIGHT"},"browserEvents.MouseButtonId.Wheel":{"retType":"browserEvents.MouseButtonId.Wheel","attributes":{"block":"wheel","_def":{"parts":[{"kind":"label","text":"wheel","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.MouseButtonId.Wheel","Number"],"pyQName":"browserEvents.MouseButtonId.WHEEL"},"browserEvents.MouseButtonId.Back":{"retType":"browserEvents.MouseButtonId.Back","attributes":{"block":"back","_def":{"parts":[{"kind":"label","text":"back","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.MouseButtonId.Back","Number"],"pyQName":"browserEvents.MouseButtonId.BACK"},"browserEvents.MouseButtonId.Forward":{"retType":"browserEvents.MouseButtonId.Forward","attributes":{"block":"forward","_def":{"parts":[{"kind":"label","text":"forward","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.MouseButtonId.Forward","Number"],"pyQName":"browserEvents.MouseButtonId.FORWARD"},"browserEvents.MouseButtonEvent":{"kind":6,"retType":"browserEvents.MouseButtonEvent","extendsTypes":["browserEvents.MouseButtonEvent","Number"]},"browserEvents.MouseButtonEvent.Pressed":{"retType":"browserEvents.MouseButtonEvent","attributes":{"block":"pressed","_def":{"parts":[{"kind":"label","text":"pressed","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.MouseButtonEvent.Pressed","Number"],"pyQName":"browserEvents.MouseButtonEvent.PRESSED"},"browserEvents.MouseButtonEvent.Released":{"retType":"browserEvents.MouseButtonEvent","attributes":{"block":"released","_def":{"parts":[{"kind":"label","text":"released","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.MouseButtonEvent.Released","Number"],"pyQName":"browserEvents.MouseButtonEvent.RELEASED"},"browserEvents.MouseButton":{"kind":8,"retType":"browserEvents.MouseButton","attributes":{"fixedInstances":"true"},"extendsTypes":[]},"browserEvents.MouseButton.__constructor":{"kind":-3,"parameters":[{"name":"id"}],"isInstance":true},"browserEvents.MouseButton.setPressed":{"kind":-1,"parameters":[{"name":"pressed","type":"boolean"}],"isInstance":true,"pyQName":"browserEvents.MouseButton.set_pressed"},"browserEvents.MouseButton.onEvent":{"kind":-1,"attributes":{"blockId":"browserEvents_mouseButton_onEvent","block":"on $this mouse button $event $x $y","draggableParameters":"reporter","group":"Mouse","weight":50,"_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"this","ref":true},{"kind":"label","text":" mouse button ","style":[]},{"kind":"param","name":"event","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"x","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"y","ref":true}],"parameters":[{"kind":"param","name":"this","ref":true},{"kind":"param","name":"event","ref":true},{"kind":"param","name":"x","ref":true},{"kind":"param","name":"y","ref":true}]}},"parameters":[{"name":"event","type":"browserEvents.MouseButtonEvent","isEnum":true},{"name":"handler","type":"(x: number, y: number) => void","handlerParameters":[{"name":"x","type":"number"},{"name":"y","type":"number"}]}],"isInstance":true,"pyQName":"browserEvents.MouseButton.on_event"},"browserEvents.MouseButton.isPressed":{"kind":-1,"retType":"boolean","attributes":{"blockId":"browserEvents_mouseButton_isPressed","block":"is $this mouse button pressed","group":"Mouse","weight":40,"_def":{"parts":[{"kind":"label","text":"is ","style":[]},{"kind":"param","name":"this","ref":true},{"kind":"label","text":" mouse button pressed","style":[]}],"parameters":[{"kind":"param","name":"this","ref":true}]}},"parameters":[],"isInstance":true,"pyQName":"browserEvents.MouseButton.is_pressed"},"browserEvents.MouseButton.pauseUntil":{"kind":-1,"attributes":{"blockId":"browserEvents_mouseButton_pauseUntil","block":"pause until $this mouse button is $event","group":"Mouse","weight":30,"_def":{"parts":[{"kind":"label","text":"pause until ","style":[]},{"kind":"param","name":"this","ref":true},{"kind":"label","text":" mouse button is ","style":[]},{"kind":"param","name":"event","ref":true}],"parameters":[{"kind":"param","name":"this","ref":true},{"kind":"param","name":"event","ref":true}]}},"parameters":[{"name":"event","type":"browserEvents.MouseButtonEvent","isEnum":true}],"isInstance":true,"pyQName":"browserEvents.MouseButton.pause_until"},"browserEvents.MouseButton.addEventListener":{"kind":-1,"parameters":[{"name":"event","type":"browserEvents.MouseButtonEvent","isEnum":true},{"name":"handler","type":"(x: number, y: number) => void","handlerParameters":[{"name":"x","type":"number"},{"name":"y","type":"number"}]}],"isInstance":true,"pyQName":"browserEvents.MouseButton.add_event_listener"},"browserEvents.MouseButton.removeEventListener":{"kind":-1,"parameters":[{"name":"event","type":"browserEvents.MouseButtonEvent","isEnum":true},{"name":"handler","type":"(x: number, y: number) => void","handlerParameters":[{"name":"x","type":"number"},{"name":"y","type":"number"}]}],"isInstance":true,"pyQName":"browserEvents.MouseButton.remove_event_listener"},"browserEvents._SceneButtonHandlers":{"kind":8,"retType":"browserEvents._SceneButtonHandlers<U>","extendsTypes":[]},"browserEvents._SceneButtonHandlers.__constructor":{"kind":-3,"parameters":[{"name":"id"},{"name":"invokeHandler","type":"(handler: U) => void","handlerParameters":[{"name":"handler","type":"U"}]}],"isInstance":true},"browserEvents._SceneButtonHandlers.onEvent":{"kind":-1,"parameters":[{"name":"event"},{"name":"handler","type":"U"}],"isInstance":true,"pyQName":"browserEvents._SceneButtonHandlers.on_event"},"browserEvents._SceneButtonHandlers.addEventListener":{"kind":-1,"parameters":[{"name":"event"},{"name":"handler","type":"U"}],"isInstance":true,"pyQName":"browserEvents._SceneButtonHandlers.add_event_listener"},"browserEvents._SceneButtonHandlers.removeEventListener":{"kind":-1,"parameters":[{"name":"event"},{"name":"handler","type":"U"}],"isInstance":true,"pyQName":"browserEvents._SceneButtonHandlers.remove_event_listener"},"browserEvents.onEvent":{"kind":-3,"attributes":{"blockId":"browserEvents_onEvent","block":"on browser event $event","draggableParameters":"reporter","group":"Mouse","weight":10,"_def":{"parts":[{"kind":"label","text":"on browser event ","style":[]},{"kind":"param","name":"event","ref":true}],"parameters":[{"kind":"param","name":"event","ref":true}]}},"parameters":[{"name":"event","type":"browserEvents.Event","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"pyQName":"browserEvents.on_event"},"browserEvents.onMouseMove":{"kind":-3,"attributes":{"blockId":"browserEvents_onMouseMove","block":"on mouse move $x $y","draggableParameters":"reporter","group":"Mouse","weight":100,"_def":{"parts":[{"kind":"label","text":"on mouse move ","style":[]},{"kind":"param","name":"x","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"y","ref":true}],"parameters":[{"kind":"param","name":"x","ref":true},{"kind":"param","name":"y","ref":true}]}},"parameters":[{"name":"handler","type":"(x: number, y: number) => void","handlerParameters":[{"name":"x","type":"number"},{"name":"y","type":"number"}]}],"pyQName":"browserEvents.on_mouse_move"},"browserEvents.onWheel":{"kind":-3,"attributes":{"blockId":"browserEvents_onWheel","block":"on mouse wheel $dx $dy $dz","draggableParameters":"reporter","group":"Mouse","weight":20,"_def":{"parts":[{"kind":"label","text":"on mouse wheel ","style":[]},{"kind":"param","name":"dx","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"dy","ref":true},{"kind":"label","text":" ","style":[]},{"kind":"param","name":"dz","ref":true}],"parameters":[{"kind":"param","name":"dx","ref":true},{"kind":"param","name":"dy","ref":true},{"kind":"param","name":"dz","ref":true}]}},"parameters":[{"name":"handler","type":"(dx: number, dy: number, dz: number) => void","handlerParameters":[{"name":"dx","type":"number"},{"name":"dy","type":"number"},{"name":"dz","type":"number"}]}],"pyQName":"browserEvents.on_wheel"},"browserEvents.setCursorVisible":{"kind":-3,"attributes":{"blockId":"browserEvents_setCursorVisible","block":"set cursor visible $visible","group":"Mouse","weight":0,"_def":{"parts":[{"kind":"label","text":"set cursor visible ","style":[]},{"kind":"param","name":"visible","ref":true}],"parameters":[{"kind":"param","name":"visible","ref":true}]}},"parameters":[{"name":"visible","type":"boolean"}],"pyQName":"browserEvents.set_cursor_visible"},"browserEvents.MouseLeft":{"kind":4,"retType":"browserEvents.MouseButton","attributes":{"fixedInstance":"true","whenUsed":"true","block":"left","_def":{"parts":[{"kind":"label","text":"left","style":[]}],"parameters":[]}},"pyQName":"browserEvents.mouse_left"},"browserEvents.MouseRight":{"kind":4,"retType":"browserEvents.MouseButton","attributes":{"fixedInstance":"true","whenUsed":"true","block":"right","_def":{"parts":[{"kind":"label","text":"right","style":[]}],"parameters":[]}},"pyQName":"browserEvents.mouse_right"},"browserEvents.MouseWheel":{"kind":4,"retType":"browserEvents.MouseButton","attributes":{"fixedInstance":"true","whenUsed":"true","block":"wheel","_def":{"parts":[{"kind":"label","text":"wheel","style":[]}],"parameters":[]}},"pyQName":"browserEvents.mouse_wheel"},"browserEvents.MouseBack":{"kind":4,"retType":"browserEvents.MouseButton","attributes":{"fixedInstance":"true","whenUsed":"true","block":"back","_def":{"parts":[{"kind":"label","text":"back","style":[]}],"parameters":[]}},"pyQName":"browserEvents.mouse_back"},"browserEvents.MouseForward":{"kind":4,"retType":"browserEvents.MouseButton","attributes":{"fixedInstance":"true","whenUsed":"true","block":"forward","_def":{"parts":[{"kind":"label","text":"forward","style":[]}],"parameters":[]}},"pyQName":"browserEvents.mouse_forward"},"browserEvents.MouseAny":{"kind":4,"retType":"browserEvents.MouseButton","attributes":{"fixedInstance":"true","whenUsed":"true","block":"any","_def":{"parts":[{"kind":"label","text":"any","style":[]}],"parameters":[]}},"pyQName":"browserEvents.mouse_any"},"browserEvents.Key":{"kind":6,"retType":"browserEvents.Key","extendsTypes":["browserEvents.Key","Number"]},"browserEvents.Key.Zero":{"retType":"browserEvents.Key.Zero","extendsTypes":["browserEvents.Key.Zero","Number"],"pyQName":"browserEvents.Key.ZERO"},"browserEvents.Key.One":{"retType":"browserEvents.Key.One","extendsTypes":["browserEvents.Key.One","Number"],"pyQName":"browserEvents.Key.ONE"},"browserEvents.Key.Two":{"retType":"browserEvents.Key.Two","extendsTypes":["browserEvents.Key.Two","Number"],"pyQName":"browserEvents.Key.TWO"},"browserEvents.Key.Three":{"retType":"browserEvents.Key.Three","extendsTypes":["browserEvents.Key.Three","Number"],"pyQName":"browserEvents.Key.THREE"},"browserEvents.Key.Four":{"retType":"browserEvents.Key.Four","extendsTypes":["browserEvents.Key.Four","Number"],"pyQName":"browserEvents.Key.FOUR"},"browserEvents.Key.Five":{"retType":"browserEvents.Key.Five","extendsTypes":["browserEvents.Key.Five","Number"],"pyQName":"browserEvents.Key.FIVE"},"browserEvents.Key.Six":{"retType":"browserEvents.Key.Six","extendsTypes":["browserEvents.Key.Six","Number"],"pyQName":"browserEvents.Key.SIX"},"browserEvents.Key.Seven":{"retType":"browserEvents.Key.Seven","extendsTypes":["browserEvents.Key.Seven","Number"],"pyQName":"browserEvents.Key.SEVEN"},"browserEvents.Key.Eight":{"retType":"browserEvents.Key.Eight","extendsTypes":["browserEvents.Key.Eight","Number"],"pyQName":"browserEvents.Key.EIGHT"},"browserEvents.Key.Nine":{"retType":"browserEvents.Key.Nine","extendsTypes":["browserEvents.Key.Nine","Number"],"pyQName":"browserEvents.Key.NINE"},"browserEvents.Key.BackTick":{"retType":"browserEvents.Key.BackTick","extendsTypes":["browserEvents.Key.BackTick","Number"],"pyQName":"browserEvents.Key.BACK_TICK"},"browserEvents.Key.Hyphen":{"retType":"browserEvents.Key.Hyphen","extendsTypes":["browserEvents.Key.Hyphen","Number"],"pyQName":"browserEvents.Key.HYPHEN"},"browserEvents.Key.Equals":{"retType":"browserEvents.Key.Equals","extendsTypes":["browserEvents.Key.Equals","Number"],"pyQName":"browserEvents.Key.EQUALS"},"browserEvents.Key.Q":{"retType":"browserEvents.Key.Q","extendsTypes":["browserEvents.Key.Q","Number"]},"browserEvents.Key.W":{"retType":"browserEvents.Key.W","extendsTypes":["browserEvents.Key.W","Number"]},"browserEvents.Key.E":{"retType":"browserEvents.Key.E","extendsTypes":["browserEvents.Key.E","Number"]},"browserEvents.Key.R":{"retType":"browserEvents.Key.R","extendsTypes":["browserEvents.Key.R","Number"]},"browserEvents.Key.T":{"retType":"browserEvents.Key.T","extendsTypes":["browserEvents.Key.T","Number"]},"browserEvents.Key.Y":{"retType":"browserEvents.Key.Y","extendsTypes":["browserEvents.Key.Y","Number"]},"browserEvents.Key.U":{"retType":"browserEvents.Key.U","extendsTypes":["browserEvents.Key.U","Number"]},"browserEvents.Key.I":{"retType":"browserEvents.Key.I","extendsTypes":["browserEvents.Key.I","Number"]},"browserEvents.Key.O":{"retType":"browserEvents.Key.O","extendsTypes":["browserEvents.Key.O","Number"]},"browserEvents.Key.P":{"retType":"browserEvents.Key.P","extendsTypes":["browserEvents.Key.P","Number"]},"browserEvents.Key.OpenBracket":{"retType":"browserEvents.Key.OpenBracket","extendsTypes":["browserEvents.Key.OpenBracket","Number"],"pyQName":"browserEvents.Key.OPEN_BRACKET"},"browserEvents.Key.CloseBracket":{"retType":"browserEvents.Key.CloseBracket","extendsTypes":["browserEvents.Key.CloseBracket","Number"],"pyQName":"browserEvents.Key.CLOSE_BRACKET"},"browserEvents.Key.BackSlash":{"retType":"browserEvents.Key.BackSlash","extendsTypes":["browserEvents.Key.BackSlash","Number"],"pyQName":"browserEvents.Key.BACK_SLASH"},"browserEvents.Key.A":{"retType":"browserEvents.Key.A","extendsTypes":["browserEvents.Key.A","Number"]},"browserEvents.Key.S":{"retType":"browserEvents.Key.S","extendsTypes":["browserEvents.Key.S","Number"]},"browserEvents.Key.D":{"retType":"browserEvents.Key.D","extendsTypes":["browserEvents.Key.D","Number"]},"browserEvents.Key.F":{"retType":"browserEvents.Key.F","extendsTypes":["browserEvents.Key.F","Number"]},"browserEvents.Key.G":{"retType":"browserEvents.Key.G","extendsTypes":["browserEvents.Key.G","Number"]},"browserEvents.Key.H":{"retType":"browserEvents.Key.H","extendsTypes":["browserEvents.Key.H","Number"]},"browserEvents.Key.Space":{"retType":"browserEvents.Key.Space","extendsTypes":["browserEvents.Key.Space","Number"],"pyQName":"browserEvents.Key.SPACE"},"browserEvents.Key.PageUp":{"retType":"browserEvents.Key.PageUp","extendsTypes":["browserEvents.Key.PageUp","Number"],"pyQName":"browserEvents.Key.PAGE_UP"},"browserEvents.Key.J":{"retType":"browserEvents.Key.J","extendsTypes":["browserEvents.Key.J","Number"]},"browserEvents.Key.K":{"retType":"browserEvents.Key.K","extendsTypes":["browserEvents.Key.K","Number"]},"browserEvents.Key.L":{"retType":"browserEvents.Key.L","extendsTypes":["browserEvents.Key.L","Number"]},"browserEvents.Key.SemiColon":{"retType":"browserEvents.Key.SemiColon","extendsTypes":["browserEvents.Key.SemiColon","Number"],"pyQName":"browserEvents.Key.SEMI_COLON"},"browserEvents.Key.Apostrophe":{"retType":"browserEvents.Key.Apostrophe","extendsTypes":["browserEvents.Key.Apostrophe","Number"],"pyQName":"browserEvents.Key.APOSTROPHE"},"browserEvents.Key.Z":{"retType":"browserEvents.Key.Z","extendsTypes":["browserEvents.Key.Z","Number"]},"browserEvents.Key.X":{"retType":"browserEvents.Key.X","extendsTypes":["browserEvents.Key.X","Number"]},"browserEvents.Key.C":{"retType":"browserEvents.Key.C","extendsTypes":["browserEvents.Key.C","Number"]},"browserEvents.Key.V":{"retType":"browserEvents.Key.V","extendsTypes":["browserEvents.Key.V","Number"]},"browserEvents.Key.B":{"retType":"browserEvents.Key.B","extendsTypes":["browserEvents.Key.B","Number"]},"browserEvents.Key.N":{"retType":"browserEvents.Key.N","extendsTypes":["browserEvents.Key.N","Number"]},"browserEvents.Key.M":{"retType":"browserEvents.Key.M","extendsTypes":["browserEvents.Key.M","Number"]},"browserEvents.Key.Comma":{"retType":"browserEvents.Key.Comma","extendsTypes":["browserEvents.Key.Comma","Number"],"pyQName":"browserEvents.Key.COMMA"},"browserEvents.Key.Period":{"retType":"browserEvents.Key.Period","extendsTypes":["browserEvents.Key.Period","Number"],"pyQName":"browserEvents.Key.PERIOD"},"browserEvents.Key.ForwardSlash":{"retType":"browserEvents.Key.ForwardSlash","extendsTypes":["browserEvents.Key.ForwardSlash","Number"],"pyQName":"browserEvents.Key.FORWARD_SLASH"},"browserEvents.Key.Shift":{"retType":"browserEvents.Key.Shift","extendsTypes":["browserEvents.Key.Shift","Number"],"pyQName":"browserEvents.Key.SHIFT"},"browserEvents.Key.Enter":{"retType":"browserEvents.Key.Enter","extendsTypes":["browserEvents.Key.Enter","Number"],"pyQName":"browserEvents.Key.ENTER"},"browserEvents.Key.CapsLock":{"retType":"browserEvents.Key.CapsLock","extendsTypes":["browserEvents.Key.CapsLock","Number"],"pyQName":"browserEvents.Key.CAPS_LOCK"},"browserEvents.Key.Tab":{"retType":"browserEvents.Key.Tab","extendsTypes":["browserEvents.Key.Tab","Number"],"pyQName":"browserEvents.Key.TAB"},"browserEvents.Key.Control":{"retType":"browserEvents.Key.Control","extendsTypes":["browserEvents.Key.Control","Number"],"pyQName":"browserEvents.Key.CONTROL"},"browserEvents.Key.Meta":{"retType":"browserEvents.Key.Meta","extendsTypes":["browserEvents.Key.Meta","Number"],"pyQName":"browserEvents.Key.META"},"browserEvents.Key.Alt":{"retType":"browserEvents.Key.Alt","extendsTypes":["browserEvents.Key.Alt","Number"],"pyQName":"browserEvents.Key.ALT"},"browserEvents.Key.ArrowUp":{"retType":"browserEvents.Key.ArrowUp","extendsTypes":["browserEvents.Key.ArrowUp","Number"],"pyQName":"browserEvents.Key.ARROW_UP"},"browserEvents.Key.ArrowDown":{"retType":"browserEvents.Key.ArrowDown","extendsTypes":["browserEvents.Key.ArrowDown","Number"],"pyQName":"browserEvents.Key.ARROW_DOWN"},"browserEvents.Key.ArrowLeft":{"retType":"browserEvents.Key.ArrowLeft","extendsTypes":["browserEvents.Key.ArrowLeft","Number"],"pyQName":"browserEvents.Key.ARROW_LEFT"},"browserEvents.Key.ArrowRight":{"retType":"browserEvents.Key.ArrowRight","extendsTypes":["browserEvents.Key.ArrowRight","Number"],"pyQName":"browserEvents.Key.ARROW_RIGHT"},"browserEvents.Key.PageDown":{"retType":"browserEvents.Key.PageDown","extendsTypes":["browserEvents.Key.PageDown","Number"],"pyQName":"browserEvents.Key.PAGE_DOWN"},"browserEvents.Key.End":{"retType":"browserEvents.Key.End","extendsTypes":["browserEvents.Key.End","Number"],"pyQName":"browserEvents.Key.END"},"browserEvents.Key.Home":{"retType":"browserEvents.Key.Home","extendsTypes":["browserEvents.Key.Home","Number"],"pyQName":"browserEvents.Key.HOME"},"browserEvents.Key.LeftShift":{"retType":"browserEvents.Key.LeftShift","extendsTypes":["browserEvents.Key.LeftShift","Number"],"pyQName":"browserEvents.Key.LEFT_SHIFT"},"browserEvents.Key.RightShift":{"retType":"browserEvents.Key.RightShift","extendsTypes":["browserEvents.Key.RightShift","Number"],"pyQName":"browserEvents.Key.RIGHT_SHIFT"},"browserEvents.Key.LeftControl":{"retType":"browserEvents.Key.LeftControl","extendsTypes":["browserEvents.Key.LeftControl","Number"],"pyQName":"browserEvents.Key.LEFT_CONTROL"},"browserEvents.Key.RightControl":{"retType":"browserEvents.Key.RightControl","extendsTypes":["browserEvents.Key.RightControl","Number"],"pyQName":"browserEvents.Key.RIGHT_CONTROL"},"browserEvents.Key.Backspace":{"retType":"browserEvents.Key.Backspace","extendsTypes":["browserEvents.Key.Backspace","Number"],"pyQName":"browserEvents.Key.BACKSPACE"},"browserEvents.Key.Delete":{"retType":"browserEvents.Key.Delete","extendsTypes":["browserEvents.Key.Delete","Number"],"pyQName":"browserEvents.Key.DELETE"},"browserEvents.KeyEvent":{"kind":6,"retType":"browserEvents.KeyEvent","extendsTypes":["browserEvents.KeyEvent","Number"]},"browserEvents.KeyEvent.Pressed":{"retType":"browserEvents.KeyEvent.Pressed","attributes":{"block":"pressed","_def":{"parts":[{"kind":"label","text":"pressed","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.KeyEvent.Pressed","Number"],"pyQName":"browserEvents.KeyEvent.PRESSED"},"browserEvents.KeyEvent.Released":{"retType":"browserEvents.KeyEvent.Released","attributes":{"block":"released","_def":{"parts":[{"kind":"label","text":"released","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.KeyEvent.Released","Number"],"pyQName":"browserEvents.KeyEvent.RELEASED"},"browserEvents.KeyEvent.Repeat":{"retType":"browserEvents.KeyEvent.Repeat","attributes":{"block":"repeat","_def":{"parts":[{"kind":"label","text":"repeat","style":[]}],"parameters":[]}},"extendsTypes":["browserEvents.KeyEvent.Repeat","Number"],"pyQName":"browserEvents.KeyEvent.REPEAT"},"browserEvents.keyToString":{"kind":-3,"retType":"\"[\" | \"Q\" | \"W\" | \"E\" | \"R\" | \"T\" | \"Y\" | \"U\" | \"I\" | \"O\" | \"P\" | \"]\" | \"\\\\\" | \"A\" | \"S\" | \"D\" | ...","parameters":[{"name":"key","type":"browserEvents.Key","isEnum":true}],"pyQName":"browserEvents.key_to_string"},"browserEvents.KeyButton":{"kind":8,"retType":"browserEvents.KeyButton","attributes":{"fixedInstances":"true"},"extendsTypes":[]},"browserEvents.KeyButton.repeatDelay":{"kind":2,"retType":"number","isInstance":true,"pyQName":"browserEvents.KeyButton.repeat_delay"},"browserEvents.KeyButton.repeatInterval":{"kind":2,"retType":"number","isInstance":true,"pyQName":"browserEvents.KeyButton.repeat_interval"},"browserEvents.KeyButton.__constructor":{"kind":-3,"parameters":[{"name":"id"}],"isInstance":true},"browserEvents.KeyButton.setPressed":{"kind":-1,"parameters":[{"name":"pressed","type":"boolean"}],"isInstance":true,"pyQName":"browserEvents.KeyButton.set_pressed"},"browserEvents.KeyButton.onEvent":{"kind":-1,"attributes":{"blockId":"browserEvents_key_onEvent","block":"on $this key $event","group":"Keyboard","weight":100,"_def":{"parts":[{"kind":"label","text":"on ","style":[]},{"kind":"param","name":"this","ref":true},{"kind":"label","text":" key ","style":[]},{"kind":"param","name":"event","ref":true}],"parameters":[{"kind":"param","name":"this","ref":true},{"kind":"param","name":"event","ref":true}]}},"parameters":[{"name":"event","type":"browserEvents.KeyEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"browserEvents.KeyButton.on_event"},"browserEvents.KeyButton.isPressed":{"kind":-1,"retType":"boolean","attributes":{"blockId":"browserEvents_key_isPressed","block":"is $this key pressed","group":"Keyboard","weight":90,"_def":{"parts":[{"kind":"label","text":"is ","style":[]},{"kind":"param","name":"this","ref":true},{"kind":"label","text":" key pressed","style":[]}],"parameters":[{"kind":"param","name":"this","ref":true}]}},"parameters":[],"isInstance":true,"pyQName":"browserEvents.KeyButton.is_pressed"},"browserEvents.KeyButton.pauseUntil":{"kind":-1,"attributes":{"blockId":"browserEvents_key_pauseUntil","block":"pause until $this key is $event","group":"Keyboard","weight":80,"_def":{"parts":[{"kind":"label","text":"pause until ","style":[]},{"kind":"param","name":"this","ref":true},{"kind":"label","text":" key is ","style":[]},{"kind":"param","name":"event","ref":true}],"parameters":[{"kind":"param","name":"this","ref":true},{"kind":"param","name":"event","ref":true}]}},"parameters":[{"name":"event","type":"browserEvents.KeyEvent","isEnum":true}],"isInstance":true,"pyQName":"browserEvents.KeyButton.pause_until"},"browserEvents.KeyButton.addEventListener":{"kind":-1,"parameters":[{"name":"event","type":"browserEvents.KeyEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"browserEvents.KeyButton.add_event_listener"},"browserEvents.KeyButton.removeEventListener":{"kind":-1,"parameters":[{"name":"event","type":"browserEvents.KeyEvent","isEnum":true},{"name":"handler","type":"() => void","handlerParameters":[]}],"isInstance":true,"pyQName":"browserEvents.KeyButton.remove_event_listener"},"browserEvents.KeyButton.__update":{"kind":-1,"parameters":[],"isInstance":true},"browserEvents.KeyButton.__registerUpdate":{"kind":-1,"parameters":[],"isInstance":true},"browserEvents.A":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.B":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.C":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.D":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.E":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.F":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.G":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.H":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.I":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.J":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.K":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.L":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.M":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.N":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.O":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.P":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.Q":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.R":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.S":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.T":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.U":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.V":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.W":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.X":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.Y":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.Z":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"}},"browserEvents.Zero":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.zero"},"browserEvents.One":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.one"},"browserEvents.Two":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.two"},"browserEvents.Three":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.three"},"browserEvents.Four":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.four"},"browserEvents.Five":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.five"},"browserEvents.Six":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.six"},"browserEvents.Seven":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.seven"},"browserEvents.Eight":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.eight"},"browserEvents.Nine":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.nine"},"browserEvents.Shift":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.shift"},"browserEvents.Enter":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.enter"},"browserEvents.CapsLock":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.caps_lock"},"browserEvents.Tab":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.tab"},"browserEvents.Control":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.control"},"browserEvents.Meta":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.meta"},"browserEvents.Alt":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.alt"},"browserEvents.ArrowUp":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.arrow_up"},"browserEvents.ArrowDown":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.arrow_down"},"browserEvents.ArrowLeft":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.arrow_left"},"browserEvents.ArrowRight":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.arrow_right"},"browserEvents.BackTick":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.back_tick"},"browserEvents.Hyphen":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.hyphen"},"browserEvents.Equals":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.equals"},"browserEvents.OpenBracket":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.open_bracket"},"browserEvents.CloseBracket":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.close_bracket"},"browserEvents.BackSlash":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.back_slash"},"browserEvents.Space":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.space"},"browserEvents.PageUp":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.page_up"},"browserEvents.SemiColon":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.semi_colon"},"browserEvents.Apostrophe":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.apostrophe"},"browserEvents.Comma":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.comma"},"browserEvents.Period":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.period"},"browserEvents.ForwardSlash":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.forward_slash"},"browserEvents.PageDown":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.page_down"},"browserEvents.End":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.end"},"browserEvents.Home":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.home"},"browserEvents.LeftShift":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.left_shift"},"browserEvents.RightShift":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.right_shift"},"browserEvents.LeftControl":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.left_control"},"browserEvents.RightControl":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.right_control"},"browserEvents.Backspace":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.backspace"},"browserEvents.Delete":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.delete"},"browserEvents.Any":{"kind":4,"retType":"browserEvents.KeyButton","attributes":{"fixedInstance":"true","whenUsed":"true"},"pyQName":"browserEvents.any"},"browserEvents.setKeyboardRepeatDefault":{"kind":-3,"attributes":{"paramDefl":{"delay":"500","interval":"30"},"blockId":"browser_events_setKeyboardRepeatDefault","block":"set keyboard repeat delay $delay ms interval $interval ms","explicitDefaults":["delay","interval"],"group":"Keyboard","weight":0,"_def":{"parts":[{"kind":"label","text":"set keyboard repeat delay ","style":[]},{"kind":"param","name":"delay","ref":true},{"kind":"label","text":" ms interval ","style":[]},{"kind":"param","name":"interval","ref":true},{"kind":"label","text":" ms","style":[]}],"parameters":[{"kind":"param","name":"delay","ref":true},{"kind":"param","name":"interval","ref":true}]}},"parameters":[{"name":"delay","initializer":"500","default":"500"},{"name":"interval","initializer":"30","default":"30"}],"pyQName":"browserEvents.set_keyboard_repeat_default"},"browserEvents.mouseX":{"kind":-3,"retType":"number","parameters":[],"pyQName":"browserEvents.mouse_x"},"browserEvents.mouseY":{"kind":-3,"retType":"number","parameters":[],"pyQName":"browserEvents.mouse_y"},"browserEvents.wheelDx":{"kind":-3,"retType":"number","parameters":[],"pyQName":"browserEvents.wheel_dx"},"browserEvents.wheelDy":{"kind":-3,"retType":"number","parameters":[],"pyQName":"browserEvents.wheel_dy"},"browserEvents.wheelDz":{"kind":-3,"retType":"number","parameters":[],"pyQName":"browserEvents.wheel_dz"},"browserEvents._setCursorVisible":{"kind":-3,"parameters":[{"name":"visible","type":"boolean"}],"pyQName":"browserEvents._set_cursor_visible"},"browserEvents.currentTime":{"kind":-3,"retType":"number","parameters":[],"pyQName":"browserEvents.current_time"},"browserEvents.getYear":{"kind":-3,"retType":"number","parameters":[{"name":"time"}],"pyQName":"browserEvents.get_year"},"browserEvents.getMonth":{"kind":-3,"retType":"number","parameters":[{"name":"time"}],"pyQName":"browserEvents.get_month"},"browserEvents.getDayOfMonth":{"kind":-3,"retType":"number","parameters":[{"name":"time"}],"pyQName":"browserEvents.get_day_of_month"},"browserEvents.getDayOfWeek":{"kind":-3,"retType":"number","parameters":[{"name":"time"}],"pyQName":"browserEvents.get_day_of_week"},"browserEvents.getHours":{"kind":-3,"retType":"number","parameters":[{"name":"time"}],"pyQName":"browserEvents.get_hours"},"browserEvents.getMinutes":{"kind":-3,"retType":"number","parameters":[{"name":"time"}],"pyQName":"browserEvents.get_minutes"},"browserEvents.getSeconds":{"kind":-3,"retType":"number","parameters":[{"name":"time"}],"pyQName":"browserEvents.get_seconds"}}},"sha":"cb75f5faebbf3f6be630acad1c34314d4c8598d2eda1a4ed12b1177509a0466c"},"libs/blocksprj":{"apis":{"byQName":{}},"sha":"5b0abd8b6265b16a37717431c05102baf2e8c8ba48faa2f12ac94e3b5d2972be"}}}