namespace pxt . perf { export declare let perfReportLogged ; export declare function report ( ) ; export declare function recordMilestone ( msg , time ? ) ; export declare function measureStart ( name ) ; export declare function measureEnd ( name ) ; } ( function ( ) { if ( ! pxt . perf . report ) pxt . perf . report = ( ) => { } ; if ( ! pxt . perf . recordMilestone ) pxt . perf . recordMilestone = ( ) => { } ; if ( ! pxt . perf . measureStart ) pxt . perf . measureStart = ( ) => { } ; if ( ! pxt . perf . measureEnd ) pxt . perf . measureEnd = ( ) => { } ; } ) ( ) ; namespace pxt { export import U = pxtc . Util ; export import Util = pxtc . Util ; export interface TCPIO { onData : ( v : Uint8Array ) => void ; onError : ( e : Error ) => void ; connectAsync ( ) : Promise < void > ; sendPacketAsync ( pkt ) : Promise < void > ; error ( msg ) : any ; disconnectAsync ( ) : Promise < void > ; } export let mkTCPSocket ; let savedAppTarget ; let savedSwitches = { } ; export function setAppTarget ( trg ) { appTarget = trg || < TargetBundle > { } ; patchAppTarget ( ) ; savedAppTarget = U . cloneTargetBundle ( appTarget ) ; } let apiInfo ; export function setBundledApiInfo ( inf ) { for ( const pkgName of Object . keys ( inf ) ) { const byQName = inf [ pkgName ] . apis . byQName ; for ( const apiName of Object . keys ( byQName ) ) { const sym = byQName [ apiName ] ; const lastDot = apiName . lastIndexOf ( "." ) ; const pyQName = sym . pyQName ; const newsym = byQName [ apiName ] = { kind : Math . abs ( sym . kind || 7 ) , qName : apiName , namespace : apiName . slice ( 0 , lastDot < 0 ? 0 : lastDot ) , name : apiName . slice ( lastDot + 1 ) , pyQName : pyQName , pyName : pyQName ? pyQName . slice ( pyQName . lastIndexOf ( "." ) + 1 ) : undefined , fileName : "" , attributes : sym . attributes || ( { } as any ) , retType : sym . retType || "void" , parameters : sym . parameters ? sym . parameters . map ( p => ( { name : p . name , description : p . description || "" , type : p . type || "number" , initializer : p . initializer , default : p . default , options : p . options || { } , isEnum : ! ! p . isEnum , handlerParameters : p . handlerParameters } ) ) : null , extendsTypes : sym . extendsTypes , snippet : sym . kind && sym . kind < 0 ? null as any : undefined , isInstance : ! ! sym . isInstance , isReadOnly : ! ! sym . isReadOnly , } ; const attr = newsym . attributes ; if ( ! attr . paramDefl ) attr . paramDefl = { } ; if ( ! attr . callingConvention ) attr . callingConvention = 0 ; if ( ! attr . paramHelp ) attr . paramHelp = { } ; if ( ! attr . jsDoc ) attr . jsDoc = "" ; attr . _name = newsym . name . replace ( /@.*/ , "" ) ; } } apiInfo = inf ; } export function getBundledApiInfo ( ) { return apiInfo ; } export function savedAppTheme ( ) { return savedAppTarget ? savedAppTarget . appTheme : undefined ; } export function setCompileSwitch ( name , value ) { if ( /^csv-/ . test ( name ) ) { pxt . setAppTargetVariant ( name . replace ( /^csv-*/ , "" ) ) ; } else if ( appTarget ) { ( savedSwitches as any ) [ name ] = value ; U . jsonCopyFrom ( appTarget . compile . switches , savedSwitches ) ; U . jsonCopyFrom ( savedAppTarget . compile . switches , savedSwitches ) ; } } export function setCompileSwitches ( names ) { if ( ! names ) return ; for ( let s of names . split ( /[\s,;:]+/ ) ) { if ( ! s ) continue ; if ( s [ 0 ] == "-" ) { setCompileSwitch ( s . slice ( 1 ) , false ) ; } else { setCompileSwitch ( s , true ) ; } } } let _bundledcoresvgs ; export function bundledSvg ( id ) { if ( ! id ) return undefined ; let res = _bundledcoresvgs && _bundledcoresvgs [ id ] ; if ( res ) return res ; if ( ! appTarget . simulator || ! appTarget . simulator . dynamicBoardDefinition ) return undefined ; if ( ! _bundledcoresvgs ) _bundledcoresvgs = { } ; const files = pxt . appTarget . bundledpkgs [ id ] ; if ( ! files ) return undefined ; const pxtjson = JSON . parse ( files [ "pxt.json" ] ) ; if ( pxtjson . core && files [ "board.json" ] ) { const boardjson = JSON . parse ( files [ "board.json" ] ) as pxsim . BoardDefinition ; if ( boardjson && boardjson . visual && ( < pxsim . BoardImageDefinition > boardjson . visual ) . image ) { let boardimg = ( < pxsim . BoardImageDefinition > boardjson . visual ) . image ; if ( /^pkg:\/\// . test ( boardimg ) ) boardimg = files [ boardimg . slice ( 6 ) ] ; _bundledcoresvgs [ id ] = `data:image/svg+xml;base64,${ ts . pxtc . encodeBase64 ( pxt . Util . toUTF8 ( boardimg ) ) }` ; } } return _bundledcoresvgs [ id ] ; } function patchAppTarget ( ) { let comp = appTarget . compile ; if ( ! comp ) comp = appTarget . compile = { isNative : false , hasHex : false , switches : { } } ; if ( comp . hasHex ) { if ( ! comp . nativeType ) comp . nativeType = pxtc . NATIVE_TYPE_THUMB ; } if ( ! comp . switches ) comp . switches = { } ; if ( comp . nativeType == pxtc . NATIVE_TYPE_VM ) comp . sourceMap = true ; U . jsonCopyFrom ( comp . switches , savedSwitches ) ; comp . jsRefCounting = false ; if ( ! comp . useUF2 && ! comp . useELF && comp . noSourceInFlash == undefined ) comp . noSourceInFlash = true ; if ( comp . utf8 === undefined ) comp . utf8 = true ; if ( ! appTarget . appTheme ) appTarget . appTheme = { } ; if ( ! appTarget . appTheme . embedUrl ) appTarget . appTheme . embedUrl = appTarget . appTheme . homeUrl ; let cs = appTarget . compileService ; if ( cs ) { if ( cs . yottaTarget && ! cs . yottaBinary ) cs . yottaBinary = "pxt-microbit-app-combined.hex" ; } const theme = appTarget . appTheme ; if ( theme ) { Object . keys ( theme as any as Map < string > ) . filter ( k => /(logo|hero)$/i . test ( k ) && /^@cdnUrl@/ . test ( ( theme as any ) [ k ] ) ) . forEach ( k => ( theme as any ) [ k ] = pxt . BrowserUtils . patchCdn ( ( theme as any ) [ k ] ) ) ; } const sim = appTarget . simulator ; if ( sim && sim . boardDefinition && sim . boardDefinition . visual ) { let boardDef = sim . boardDefinition . visual as pxsim . BoardImageDefinition ; if ( boardDef . image ) { boardDef . image = pxt . BrowserUtils . patchCdn ( boardDef . image ) ; if ( boardDef . outlineImage ) boardDef . outlineImage = pxt . BrowserUtils . patchCdn ( boardDef . outlineImage ) ; } } Object . keys ( appTarget . bundledpkgs ) . forEach ( pkgid => { const res = appTarget . bundledpkgs [ pkgid ] ; const config = JSON . parse ( res [ pxt . CONFIG_NAME ] ) as pxt . PackageConfig ; if ( config . icon ) config . icon = pxt . BrowserUtils . patchCdn ( config . icon ) ; res [ pxt . CONFIG_NAME ] = pxt . Package . stringifyConfig ( config ) ; } ) ; if ( typeof window !== 'undefined' ) { const queryVariants = { "lockededitor=1" : { appTheme : { lockedEditor : true } } , "hidemenu=1" : { appTheme : { hideMenuBar : true } } } ; if ( appTarget . queryVariants ) Util . jsonCopyFrom ( queryVariants , appTarget . queryVariants ) ; const href = window . location . href ; Object . keys ( queryVariants ) . forEach ( queryRegex => { const regex = new RegExp ( queryRegex , "i" ) ; const match = regex . exec ( href ) ; if ( match ) { let v = queryVariants [ queryRegex ] ; if ( v ) { U . jsonMergeFrom ( appTarget , v ) ; } } } ) ; } } export function reloadAppTargetVariant ( temporary = false ) { pxt . perf . measureStart ( "reloadAppTargetVariant" ) ; const curr = temporary ? "" : JSON . stringify ( appTarget ) ; appTarget = U . cloneTargetBundle ( savedAppTarget ) ; if ( appTargetVariant ) { const v = appTarget . variants && appTarget . variants [ appTargetVariant ] ; if ( v ) U . jsonMergeFrom ( appTarget , v ) ; else U . userError ( lf ( "Variant '{0}' not defined in pxtarget.json" , appTargetVariant ) ) ; } patchAppTarget ( ) ; if ( ! temporary && onAppTargetChanged && curr != JSON . stringify ( appTarget ) ) onAppTargetChanged ( ) ; pxt . perf . measureEnd ( "reloadAppTargetVariant" ) ; } export function setAppTargetVariant ( variant , opts = { } ) { pxt . debug ( `app variant: ${ variant }` ) ; if ( ! opts . force && ( appTargetVariant === variant || ( ! appTargetVariant && ! variant ) ) ) return ; appTargetVariant = variant ; reloadAppTargetVariant ( opts . temporary ) ; } export let onAppTargetChanged ; export function setHwVariant ( variant , name ? ) { variant = variant . replace ( /.*---/ , "" ) ; if ( /^[\w\-]+$/ . test ( variant ) ) { hwVariant = variant ; hwName = name || variant ; } else { hwVariant = null ; hwName = null ; } pxt . debug ( `hwVariant: ${ hwVariant } (${ hwName })` ) ; } export function hasHwVariants ( ) { return ! ! pxt . appTarget . variants && Object . keys ( pxt . appTarget . bundledpkgs ) . some ( pkg => /^hw---/ . test ( pkg ) ) ; } export function getHwVariants ( ) { if ( ! pxt . appTarget . variants ) return [ ] ; let hws = Object . keys ( pxt . appTarget . bundledpkgs ) . filter ( pkg => /^hw---/ . test ( pkg ) ) ; return hws . map ( pkg => JSON . parse ( pxt . appTarget . bundledpkgs [ pkg ] [ CONFIG_NAME ] ) ) . filter ( ( cfg ) => { if ( pxt . appTarget . appTheme . experimentalHw ) return true ; return ! cfg . experimentalHw ; } ) ; } export interface PxtOptions { debug ? : boolean ; light ? : boolean ; wsPort ? : number ; } export let options = { } ; export let debug = typeof console !== "undefined" && ! ! console . debug ? ( msg ) => { if ( pxt . options . debug ) console . debug ( msg ) ; } : ( ) => { } ; export let log = typeof console !== "undefined" && ! ! console . log ? ( msg ) => { console . log ( msg ) ; } : ( ) => { } ; export let reportException = function ( e , d ) { if ( console ) { console . error ( e ) ; if ( d ) { try { console . log ( d ) ; } catch ( e ) { } } } } ; export let reportError = function ( cat , msg , data ) { if ( console ) { console . error ( `${ cat }: ${ msg }` ) ; if ( data ) { try { pxt . log ( JSON . stringify ( data , null , 2 ) ) ; } catch ( e ) { } } } } ; export interface WebConfig { relprefix : string ; workerjs : string ; monacoworkerjs : string ; gifworkerjs : string ; serviceworkerjs : string ; typeScriptWorkerJs : string ; pxtVersion : string ; pxtRelId : string ; pxtCdnUrl : string ; commitCdnUrl : string ; blobCdnUrl : string ; cdnUrl : string ; targetUrl : string ; targetVersion : string ; targetRelId : string ; targetId : string ; simUrl : string ; simserviceworkerUrl : string ; simworkerconfigUrl : string ; partsUrl ? : string ; runUrl ? : string ; docsUrl ? : string ; multiUrl ? : string ; asseteditorUrl ? : string ; skillmapUrl ? : string ; isStatic ? : boolean ; verprefix ? : string ; } export function localWebConfig ( ) { let r = { relprefix : "/--" , workerjs : "/worker.js" , monacoworkerjs : "/monacoworker.js" , gifworkerjs : "/gifjs/gif.worker.js" , serviceworkerjs : "/serviceworker.js" , typeScriptWorkerJs : "/tsworker.js" , pxtVersion : "local" , pxtRelId : "localRelId" , pxtCdnUrl : "/cdn/" , commitCdnUrl : "/cdn/" , blobCdnUrl : "/blb/" , cdnUrl : "/cdn/" , targetUrl : "" , targetVersion : "local" , targetRelId : "" , targetId : appTarget ? appTarget . id : "" , simUrl : "/sim/simulator.html" , simserviceworkerUrl : "/simulatorserviceworker.js" , simworkerconfigUrl : "/sim/workerConfig.js" , partsUrl : "/sim/siminstructions.html" } ; return r ; } export let webConfig ; export function getOnlineCdnUrl ( ) { if ( ! webConfig ) return null ; let m = /^(https:\/\/[^\/]+)/ . exec ( webConfig . commitCdnUrl ) ; if ( m ) return m [ 1 ] ; else return null ; } export function setupWebConfig ( cfg ) { if ( cfg ) webConfig = cfg ; else if ( ! webConfig ) webConfig = localWebConfig ( ) ; } export interface Host { readFile ( pkg , filename , skipAdditionalFiles ? ) : string ; writeFile ( pkg , filename , contents , force ? ) : void ; downloadPackageAsync ( pkg , deps ? ) : Promise < void > ; getHexInfoAsync ( extInfo ) : Promise < pxtc . HexInfo > ; cacheStoreAsync ( id , val ) : Promise < void > ; cacheGetAsync ( id ) : Promise < string > ; } export interface FsFile { name : string ; mtime : number ; content ? : string ; prevContent ? : string ; } export interface FsPkg { path : string ; config : pxt . PackageConfig ; header : pxt . workspace . Header ; files : FsFile [ ] ; icon ? : string ; isDeleted ? : boolean ; } export interface FsPkgs { pkgs : FsPkg [ ] ; } export interface ICompilationOptions { } export function getEmbeddedScript ( id ) { return U . lookup ( appTarget . bundledpkgs || { } , id ) ; } let _targetConfigPromise = undefined ; export function targetConfigAsync ( ) { if ( ! _targetConfigPromise ) _targetConfigPromise = Cloud . downloadTargetConfigAsync ( ) . then ( js => { return js || { } ; } , err => { return { } ; } ) ; return _targetConfigPromise ; } export function packagesConfigAsync ( ) { return targetConfigAsync ( ) . then ( config => config ? config . packages : undefined ) ; } export const CONFIG_NAME = "pxt.json" ; export const SIMSTATE_JSON = ".simstate.json" ; export const SERIAL_EDITOR_FILE = "serial.txt" ; export const README_FILE = "README.md" ; export const GITIGNORE_FILE = ".gitignore" ; export const ASSETS_FILE = "assets.json" ; export const CLOUD_ID = "pxt/" ; export const BLOCKS_PROJECT_NAME = "blocksprj" ; export const JAVASCRIPT_PROJECT_NAME = "tsprj" ; export const PYTHON_PROJECT_NAME = "pyprj" ; export const MAIN_BLOCKS = "main.blocks" ; export const MAIN_TS = "main.ts" ; export const MAIN_PY = "main.py" ; export const DEFAULT_GROUP_NAME = "other" ; export const TILEMAP_CODE = "tilemap.g.ts" ; export const TILEMAP_JRES = "tilemap.g.jres" ; export const IMAGES_CODE = "images.g.ts" ; export const IMAGES_JRES = "images.g.jres" ; export const TUTORIAL_CODE_START = "_onCodeStart.ts" ; export const TUTORIAL_CODE_STOP = "_onCodeStop.ts" ; export const TUTORIAL_INFO_FILE = "tutorial-info-cache.json" ; export const TUTORIAL_CUSTOM_TS = "tutorial.custom.ts" ; export const BREAKPOINT_TABLET = 991 ; export function outputName ( trg = null ) { if ( ! trg ) trg = appTarget . compile ; if ( trg . nativeType == ts . pxtc . NATIVE_TYPE_VM ) { if ( trg . useESP ) return trg . useUF2 ? ts . pxtc . BINARY_UF2 : ts . pxtc . BINARY_ESP ; else return ts . pxtc . BINARY_PXT64 ; } else if ( trg . useUF2 && ! trg . switches . rawELF ) return ts . pxtc . BINARY_UF2 ; else if ( trg . useELF ) return ts . pxtc . BINARY_ELF ; else return ts . pxtc . BINARY_HEX ; } export function isOutputText ( trg = null ) { return outputName ( trg ) == ts . pxtc . BINARY_HEX ; } }