declare let __startCPUProfiler ; declare let __stopCPUProfiler ; export function uptime ( ) { return global . android ? ( < any > org ) . nativescript . Process . getUpTime ( ) : ( < any > global ) . __tns_uptime ( ) ; } export function log ( message , ... optionalParams ) { if ( ( < any > global ) . __nslog ) { ( < any > global ) . __nslog ( 'CONSOLE LOG: ' + message ) ; } console . log ( message , ... optionalParams ) ; } export type InstrumentationMode = 'counters' | 'timeline' | 'lifecycle' ; export interface TimerInfo { totalTime : number ; lastTime ? : number ; count : number ; currentStart : number ; /**
     * Counts the number of entry and exits a function had.
     */ runCount : number ; } const timers = { } ; const anyGlobal = < any > global ; const profileNames = [ ] ; export const time = ( < any > global ) . __time || Date . now ; export function start ( name ) { let info = timers [ name ] ; if ( info ) { info . currentStart = time ( ) ; info . runCount ++ ; } else { info = { totalTime : 0 , count : 0 , currentStart : time ( ) , runCount : 1 , } ; timers [ name ] = info ; profileNames . push ( name ) ; } } export function stop ( name ) { const info = timers [ name ] ; if ( ! info ) { throw new Error ( `No timer started: ${ name }` ) ; } if ( info . runCount ) { info . runCount -- ; if ( info . runCount ) { info . count ++ ; } else { info . lastTime = time ( ) - info . currentStart ; info . totalTime += info . lastTime ; info . count ++ ; info . currentStart = 0 ; } } else { throw new Error ( `Timer ${ name } paused more times than started.` ) ; } return info ; } export function timer ( name ) { return timers [ name ] ; } export function print ( name ) { const info = timers [ name ] ; if ( ! info ) { throw new Error ( `No timer started: ${ name }` ) ; } console . log ( `---- [${ name }] STOP total: ${ info . totalTime } count:${ info . count }` ) ; return info ; } export function isRunning ( name ) { const info = timers [ name ] ; return ! ! ( info && info . runCount ) ; } function countersProfileFunctionFactory < F extends Function > ( fn , name , type = MemberType . Instance ) { profileNames . push ( name ) ; return < any > function ( ) { start ( name ) ; try { return fn . apply ( this , arguments ) ; } finally { stop ( name ) ; } } ; } function timelineProfileFunctionFactory < F extends Function > ( fn , name , type = MemberType . Instance ) { return type === MemberType . Instance ? < any > function ( ) { const start = time ( ) ; try { return fn . apply ( this , arguments ) ; } finally { const end = time ( ) ; console . log ( `Timeline: Modules: ${ name } ${ this }  (${ start }ms. - ${ end }ms.)` ) ; } } : function ( ) { const start = time ( ) ; try { return fn . apply ( this , arguments ) ; } finally { const end = time ( ) ; console . log ( `Timeline: Modules: ${ name }  (${ start }ms. - ${ end }ms.)` ) ; } } ; } const enum MemberType { Static , Instance } export enum Level { none , lifecycle , timeline } let tracingLevel = Level . none ; let profileFunctionFactory ; export function enable ( mode = 'counters' ) { profileFunctionFactory = mode && { counters : countersProfileFunctionFactory , timeline : timelineProfileFunctionFactory , } [ mode ] ; tracingLevel = { lifecycle : Level . lifecycle , timeline : Level . timeline , } [ mode ] || Level . none ; } try { const appConfig = require ( '~/package.json' ) ; if ( appConfig && appConfig . profiling ) { enable ( appConfig . profiling ) ; } } catch ( e1 ) { try { console . log ( 'Profiling startup failed to figure out defaults from package.json, error: ' + e1 ) ; } catch ( e2 ) { } } export function disable ( ) { profileFunctionFactory = undefined ; } function profileFunction < F extends Function > ( fn , customName ? ) { return profileFunctionFactory ( fn , customName || fn . name ) ; } const profileMethodUnnamed = ( target , key , descriptor ) => { if ( descriptor === undefined ) { descriptor = Object . getOwnPropertyDescriptor ( target , key ) ; } const originalMethod = descriptor . value ; let className = '' ; if ( target && target . constructor && target . constructor . name ) { className = target . constructor . name + '.' ; } const name = className + key ; descriptor . value = profileFunctionFactory ( originalMethod , name , MemberType . Instance ) ; return descriptor ; } ; const profileStaticMethodUnnamed = ( ctor , key , descriptor ) => { if ( descriptor === undefined ) { descriptor = Object . getOwnPropertyDescriptor ( ctor , key ) ; } const originalMethod = descriptor . value ; let className = '' ; if ( ctor && ctor . name ) { className = ctor . name + '.' ; } const name = className + key ; descriptor . value = profileFunctionFactory ( originalMethod , name , MemberType . Static ) ; return descriptor ; } ; function profileMethodNamed ( name ) { return ( target , key , descriptor ) => { if ( descriptor === undefined ) { descriptor = Object . getOwnPropertyDescriptor ( target , key ) ; } const originalMethod = descriptor . value ; descriptor . value = profileFunctionFactory ( originalMethod , name ) ; return descriptor ; } ; } const voidMethodDecorator = ( ) => { } ; export function profile ( nameFnOrTarget ? , fnOrKey ? , descriptor ? , attrs ? ) { if ( typeof nameFnOrTarget === 'object' && ( typeof fnOrKey === 'string' || typeof fnOrKey === 'symbol' ) ) { if ( ! profileFunctionFactory ) { return ; } return profileMethodUnnamed ( nameFnOrTarget , fnOrKey , descriptor ) ; } else if ( typeof nameFnOrTarget === 'function' && ( typeof fnOrKey === 'string' || typeof fnOrKey === 'symbol' ) ) { if ( ! profileFunctionFactory ) { return ; } return profileStaticMethodUnnamed ( nameFnOrTarget , fnOrKey , descriptor ) ; } else if ( typeof nameFnOrTarget === 'string' && typeof fnOrKey === 'function' ) { if ( ! profileFunctionFactory ) { return fnOrKey ; } return profileFunction ( fnOrKey , nameFnOrTarget ) ; } else if ( typeof nameFnOrTarget === 'function' ) { if ( ! profileFunctionFactory ) { return nameFnOrTarget ; } return profileFunction ( nameFnOrTarget ) ; } else if ( typeof nameFnOrTarget === 'string' ) { if ( ! profileFunctionFactory ) { return voidMethodDecorator ; } return profileMethodNamed ( nameFnOrTarget ) ; } else { if ( ! profileFunctionFactory ) { return voidMethodDecorator ; } return profileMethodUnnamed ; } } export function dumpProfiles ( ) { profileNames . forEach ( function ( name ) { const info = timers [ name ] ; if ( info ) { console . log ( '---- [' + name + '] STOP total: ' + info . totalTime + ' count:' + info . count ) ; } else { console . log ( '---- [' + name + '] Never called' ) ; } } ) ; } export function resetProfiles ( ) { profileNames . forEach ( function ( name ) { const info = timers [ name ] ; if ( info ) { if ( info . runCount ) { console . log ( '---- timer with name [' + name + "] is currently running and won't be reset" ) ; } else { timers [ name ] = undefined ; } } } ) ; } export function startCPUProfile ( name ) { if ( anyGlobal . android ) { __startCPUProfiler ( name ) ; } } export function stopCPUProfile ( name ) { if ( anyGlobal . android ) { __stopCPUProfiler ( name ) ; } } export function level ( ) { return tracingLevel ; } export function trace ( message , start , end ) { log ( `Timeline: Modules: ${ message }  (${ start }ms. - ${ end }ms.)` ) ; }