Input: / * Will get JSON of the form : { isEnabled : 1 isVisible : 1 frame : {{ 0 0 } { 375 667 }} children : [ { isEnabled : 1 isVisible : 1 frame : {{ 0 0 } { 375 667 }} children : [] rect : { x : 0 y : 0 width : 375 height : 667 } value : null label : null type : Other name : null rawIdentifier : null } rect : { origin : { x : 0 y : 0 } size : { width : 375 height : 667 } } value : null label : UICatalog type : Application name : UICatalog rawIdentifier : null } [CODESPLIT] function getTreeForXML ( srcTree ) { function getTree ( element , elementIndex , parentPath ) { let curPath = ` ${ parentPath } ${ elementIndex } ` ; let rect = element . rect || { } ; let subtree = { '@' : { type : ` ${ element . type } ` , enabled : parseInt ( element . isEnabled , 10 ) === 1 , visible : parseInt ( element . isVisible , 10 ) === 1 , x : rect . x , y : rect . y , width : rect . width , height : rect . height , } , '>' : [ ] } ; if ( element . name !== null ) { subtree [ '@' ] . name = element . name ; } if ( element . label !== null ) { subtree [ '@' ] . label = element . label ; } if ( element . value !== null ) { subtree [ '@' ] . value = element . value ; } for ( let i = 0 ; i < ( element . children || [ ] ) . length ; i ++ ) { subtree [ '>' ] . push ( getTree ( element . children [ i ] , i , curPath ) ) ; } return { [ ` ${ element . type } ` ] : subtree } ; } let tree = getTree ( srcTree , 0 , '' ) ; return tree ; }


Input: Parses the actual path and the bundle identifier from the given path string [CODESPLIT] async function parseContainerPath ( remotePath , containerRootSupplier ) { const match = CONTAINER_PATH_PATTERN . exec ( remotePath ) ; if ( ! match ) { log . errorAndThrow ( ` ` + ` ${ CONTAINER_PATH_MARKER } ` + ` ${ remotePath } ` ) ; } let [ , bundleId , relativePath ] = match ; let containerType = null ; const typeSeparatorPos = bundleId . indexOf ( CONTAINER_TYPE_SEPARATOR ) ; // We only consider container type exists if its length is greater than zero // not counting the colon if ( typeSeparatorPos > 0 && typeSeparatorPos < bundleId . length - 1 ) { containerType = bundleId . substring ( typeSeparatorPos + 1 ) ; log . debug ( ` ${ containerType } ` ) ; bundleId = bundleId . substring ( 0 , typeSeparatorPos ) ; } const containerRoot = _ . isFunction ( containerRootSupplier ) ? await containerRootSupplier ( bundleId , containerType ) : containerRootSupplier ; const resultPath = path . posix . resolve ( containerRoot , relativePath ) ; verifyIsSubPath ( resultPath , containerRoot ) ; return [ bundleId , resultPath ] ; }


Input: Save the given base64 data chunk as a binary file on the Simulator under test . [CODESPLIT] async function pushFileToSimulator ( device , remotePath , base64Data ) { const buffer = Buffer . from ( base64Data , 'base64' ) ; if ( CONTAINER_PATH_PATTERN . test ( remotePath ) ) { const [ bundleId , dstPath ] = await parseContainerPath ( remotePath , async ( appBundle , containerType ) => await getAppContainer ( device . udid , appBundle , null , containerType ) ) ; log . info ( ` ${ bundleId } ${ remotePath } ` + ` ${ dstPath } ` ) ; if ( ! await fs . exists ( path . dirname ( dstPath ) ) ) { log . debug ( ` ${ path . dirname ( dstPath ) } ` ) ; await mkdirp ( path . dirname ( dstPath ) ) ; } await fs . writeFile ( dstPath , buffer ) ; return ; } const dstFolder = await tempDir . openDir ( ) ; const dstPath = path . resolve ( dstFolder , path . basename ( remotePath ) ) ; try { await fs . writeFile ( dstPath , buffer ) ; await addMedia ( device . udid , dstPath ) ; } finally { await fs . rimraf ( dstFolder ) ; } }


Input: Save the given base64 data chunk as a binary file on the device under test . ifuse / osxfuse should be installed and configured on the target machine in order for this function to work properly . Read https : // github . com / libimobiledevice / ifuse and https : // github . com / osxfuse / osxfuse / wiki / FAQ for more details . [CODESPLIT] async function pushFileToRealDevice ( device , remotePath , base64Data ) { await verifyIFusePresence ( ) ; const mntRoot = await tempDir . openDir ( ) ; let isUnmountSuccessful = true ; try { let dstPath = path . resolve ( mntRoot , remotePath ) ; let ifuseArgs = [ '-u' , device . udid , mntRoot ] ; if ( CONTAINER_PATH_PATTERN . test ( remotePath ) ) { const [ bundleId , pathInContainer ] = await parseContainerPath ( remotePath , mntRoot ) ; dstPath = pathInContainer ; log . info ( ` ${ bundleId } ${ remotePath } ` + ` ${ dstPath } ` ) ; ifuseArgs = [ '-u' , device . udid , '--container' , bundleId , mntRoot ] ; } else { verifyIsSubPath ( dstPath , mntRoot ) ; } await mountDevice ( device , ifuseArgs ) ; isUnmountSuccessful = false ; try { if ( ! await fs . exists ( path . dirname ( dstPath ) ) ) { log . debug ( ` ${ path . dirname ( dstPath ) } ` ) ; await mkdirp ( path . dirname ( dstPath ) ) ; } await fs . writeFile ( dstPath , Buffer . from ( base64Data , 'base64' ) ) ; } finally { await exec ( 'umount' , [ mntRoot ] ) ; isUnmountSuccessful = true ; } } finally { if ( isUnmountSuccessful ) { await fs . rimraf ( mntRoot ) ; } else { log . warn ( ` ${ mntRoot } ` ) ; } } }


Input: Get the content of given file or folder from iOS Simulator and return it as base - 64 encoded string . Folder content is recursively packed into a zip archive . [CODESPLIT] async function pullFromSimulator ( device , remotePath , isFile ) { let pathOnServer ; if ( CONTAINER_PATH_PATTERN . test ( remotePath ) ) { const [ bundleId , dstPath ] = await parseContainerPath ( remotePath , async ( appBundle , containerType ) => await getAppContainer ( device . udid , appBundle , null , containerType ) ) ; log . info ( ` ${ bundleId } ${ remotePath } ` + ` ${ dstPath } ` ) ; pathOnServer = dstPath ; } else { const simRoot = device . getDir ( ) ; pathOnServer = path . posix . join ( simRoot , remotePath ) ; verifyIsSubPath ( pathOnServer , simRoot ) ; log . info ( ` ${ pathOnServer } ` ) ; } if ( ! await fs . exists ( pathOnServer ) ) { log . errorAndThrow ( ` ${ isFile ? 'file' : 'folder' } ${ pathOnServer } ` ) ; } const buffer = isFile ? await fs . readFile ( pathOnServer ) : await zip . toInMemoryZip ( pathOnServer ) ; return Buffer . from ( buffer ) . toString ( 'base64' ) ; }


Input: Get the content of given file or folder from the real device under test and return it as base - 64 encoded string . Folder content is recursively packed into a zip archive . [CODESPLIT] async function pullFromRealDevice ( device , remotePath , isFile ) { await verifyIFusePresence ( ) ; const mntRoot = await tempDir . openDir ( ) ; let isUnmountSuccessful = true ; try { let dstPath = path . resolve ( mntRoot , remotePath ) ; let ifuseArgs = [ '-u' , device . udid , mntRoot ] ; if ( CONTAINER_PATH_PATTERN . test ( remotePath ) ) { const [ bundleId , pathInContainer ] = await parseContainerPath ( remotePath , mntRoot ) ; dstPath = pathInContainer ; log . info ( ` ${ bundleId } ${ remotePath } ` + ` ${ dstPath } ` ) ; ifuseArgs = [ '-u' , device . udid , '--container' , bundleId , mntRoot ] ; } else { verifyIsSubPath ( dstPath , mntRoot ) ; } await mountDevice ( device , ifuseArgs ) ; isUnmountSuccessful = false ; try { if ( ! await fs . exists ( dstPath ) ) { log . errorAndThrow ( ` ${ isFile ? 'file' : 'folder' } ${ dstPath } ` ) ; } const buffer = isFile ? await fs . readFile ( dstPath ) : await zip . toInMemoryZip ( dstPath ) ; return Buffer . from ( buffer ) . toString ( 'base64' ) ; } finally { await exec ( 'umount' , [ mntRoot ] ) ; isUnmountSuccessful = true ; } } finally { if ( isUnmountSuccessful ) { await fs . rimraf ( mntRoot ) ; } else { log . warn ( ` ${ mntRoot } ` ) ; } } }


Input: Capability set by a user [CODESPLIT] async function createSim ( caps , platform = PLATFORM_NAME_IOS ) { const appiumTestDeviceName = ` ${ UUID . create ( ) . toString ( ) . toUpperCase ( ) } ${ caps . deviceName } ` ; const udid = await createDevice ( appiumTestDeviceName , caps . deviceName , caps . platformVersion , { platform } ) ; return await getSimulator ( udid ) ; }


Input: Get a simulator which is already running . [CODESPLIT] async function getExistingSim ( opts ) { const devices = await getDevices ( opts . platformVersion ) ; const appiumTestDeviceName = ` ${ opts . deviceName } ` ; let appiumTestDevice ; for ( const device of _ . values ( devices ) ) { if ( device . name === opts . deviceName ) { return await getSimulator ( device . udid ) ; } if ( device . name === appiumTestDeviceName ) { appiumTestDevice = device ; } } if ( appiumTestDevice ) { log . warn ( ` ${ opts . deviceName } ${ appiumTestDevice . name } ${ appiumTestDevice . udid } ` ) ; return await getSimulator ( appiumTestDevice . udid ) ; } return null ; }


Input: ***************************************************************** Lifecycle [CODESPLIT] function ( ) { const el = this . el ; this . velocityCtrl = null ; this . velocity = new THREE . Vector3 ( ) ; this . heading = new THREE . Quaternion ( ) ; // Navigation this . navGroup = null ; this . navNode = null ; if ( el . sceneEl . hasLoaded ) { this . injectControls ( ) ; } else { el . sceneEl . addEventListener ( 'loaded' , this . injectControls . bind ( this ) ) ; } }


Input: ***************************************************************** Movement [CODESPLIT] function ( ) { const data = this . data ; if ( data . enabled ) { for ( let i = 0 , l = data . controls . length ; i < l ; i ++ ) { const control = this . el . components [ data . controls [ i ] + COMPONENT_SUFFIX ] ; if ( control && control . isVelocityActive ( ) ) { this . velocityCtrl = control ; return ; } } this . velocityCtrl = null ; } }


Input: physics [CODESPLIT] function parsePhysicsModel ( xml ) { var data = { name : xml . getAttribute ( 'name' ) || '' , rigidBodies : { } } ; for ( var i = 0 ; i < xml . childNodes . length ; i ++ ) { var child = xml . childNodes [ i ] ; if ( child . nodeType !== 1 ) continue ; switch ( child . nodeName ) { case 'rigid_body' : data . rigidBodies [ child . getAttribute ( 'name' ) ] = { } ; parsePhysicsRigidBody ( child , data . rigidBodies [ child . getAttribute ( 'name' ) ] ) ; break ; } } library . physicsModels [ xml . getAttribute ( 'id' ) ] = data ; }


Input: nodes [CODESPLIT] function prepareNodes ( xml ) { var elements = xml . getElementsByTagName ( 'node' ) ; // ensure all node elements have id attributes for ( var i = 0 ; i < elements . length ; i ++ ) { var element = elements [ i ] ; if ( element . hasAttribute ( 'id' ) === false ) { element . setAttribute ( 'id' , generateId ( ) ) ; } } }


Input: visual scenes [CODESPLIT] function parseVisualScene ( xml ) { var data = { name : xml . getAttribute ( 'name' ) , children : [ ] } ; prepareNodes ( xml ) ; var elements = getElementsByTagName ( xml , 'node' ) ; for ( var i = 0 ; i < elements . length ; i ++ ) { data . children . push ( parseNode ( elements [ i ] ) ) ; } library . visualScenes [ xml . getAttribute ( 'id' ) ] = data ; }


Input: Update list of entities to test for collision . [CODESPLIT] function ( ) { const data = this . data ; let objectEls ; // Push entities into list of els to intersect. if ( data . objects ) { objectEls = this . el . sceneEl . querySelectorAll ( data . objects ) ; } else { // If objects not defined, intersect with everything. objectEls = this . el . sceneEl . children ; } // Convert from NodeList to Array this . els = Array . prototype . slice . call ( objectEls ) ; }


Input: Bounding sphere collision detection [CODESPLIT] function intersect ( el ) { let radius , mesh , distance , extent ; if ( ! el . isEntity ) { return ; } mesh = el . getObject3D ( 'mesh' ) ; if ( ! mesh ) { return ; } box . setFromObject ( mesh ) . getSize ( size ) ; extent = Math . max ( size . x , size . y , size . z ) / 2 ; radius = Math . sqrt ( 2 * extent * extent ) ; box . getCenter ( meshPosition ) ; if ( ! radius ) { return ; } distance = position . distanceTo ( meshPosition ) ; if ( distance < radius + colliderRadius ) { collisions . push ( el ) ; distanceMap . set ( el , distance ) ; } }


Input: ***************************************************************** Lifecycle [CODESPLIT] function ( ) { this . system = this . el . sceneEl . systems . physics ; this . system . addComponent ( this ) ; const el = this . el , data = this . data , position = ( new CANNON . Vec3 ( ) ) . copy ( el . object3D . getWorldPosition ( new THREE . Vector3 ( ) ) ) ; this . body = new CANNON . Body ( { material : this . system . getMaterial ( 'staticMaterial' ) , position : position , mass : data . mass , linearDamping : data . linearDamping , fixedRotation : true } ) ; this . body . addShape ( new CANNON . Sphere ( data . radius ) , new CANNON . Vec3 ( 0 , data . radius , 0 ) ) ; this . body . el = this . el ; this . el . body = this . body ; this . system . addBody ( this . body ) ; if ( el . hasAttribute ( 'wasd-controls' ) ) { console . warn ( '[kinematic-body] Not compatible with wasd-controls, use movement-controls.' ) ; } }


Input: ***************************************************************** Update Checks CANNON . World for collisions and attempts to apply them to the element automatically in a player - friendly way . [CODESPLIT] function ( t , dt ) { if ( ! dt ) return ; const el = this . el ; const data = this . data const body = this . body ; if ( ! data . enableJumps ) body . velocity . set ( 0 , 0 , 0 ) ; body . position . copy ( el . getAttribute ( 'position' ) ) ; }


Input: When walking on complex surfaces ( trimeshes borders between two shapes ) the collision normals returned for the player sphere can be very inconsistent . To address this raycast straight down find the collision normal and return whichever normal is more vertical . [CODESPLIT] function ( groundBody , groundNormal ) { let ray , hitNormal , vFrom = this . body . position , vTo = this . body . position . clone ( ) ; ray = new CANNON . Ray ( vFrom , vTo ) ; ray . _updateDirection ( ) ; // TODO - Report bug. ray . intersectBody ( groundBody ) ; if ( ! ray . hasHit ) return groundNormal ; // Compare ABS, in case we're projecting against the inside of the face. hitNormal = ray . result . hitNormalWorld ; return Math . abs ( hitNormal . y ) > Math . abs ( groundNormal . y ) ? hitNormal : groundNormal ; }


Input: ***************************************************************** Core Called once when component is attached . Generally for initial setup . [CODESPLIT] function ( ) { const scene = this . el . sceneEl ; this . prevTime = window . performance . now ( ) ; // Button state this . buttons = { } ; // Rotation const rotation = this . el . object3D . rotation ; this . pitch = new THREE . Object3D ( ) ; this . pitch . rotation . x = THREE . Math . degToRad ( rotation . x ) ; this . yaw = new THREE . Object3D ( ) ; this . yaw . position . y = 10 ; this . yaw . rotation . y = THREE . Math . degToRad ( rotation . y ) ; this . yaw . add ( this . pitch ) ; scene . addBehavior ( this ) ; }


Input: ***************************************************************** Movement [CODESPLIT] function ( ) { if ( ! this . data . enabled || ! this . isConnected ( ) ) return false ; const dpad = this . getDpad ( ) , joystick0 = this . getJoystick ( 0 ) , inputX = dpad . x || joystick0 . x , inputY = dpad . y || joystick0 . y ; return Math . abs ( inputX ) > JOYSTICK_EPS || Math . abs ( inputY ) > JOYSTICK_EPS ; }


Input: ***************************************************************** Rotation [CODESPLIT] function ( ) { if ( ! this . data . enabled || ! this . isConnected ( ) ) return false ; const joystick1 = this . getJoystick ( 1 ) ; return Math . abs ( joystick1 . x ) > JOYSTICK_EPS || Math . abs ( joystick1 . y ) > JOYSTICK_EPS ; }


Input: Returns the state of the given joystick ( 0 or 1 ) as a THREE . Vector2 . [CODESPLIT] function ( index ) { const gamepad = this . getGamepad ( ) ; switch ( index ) { case 0 : return new THREE . Vector2 ( gamepad . axes [ 0 ] , gamepad . axes [ 1 ] ) ; case 1 : return new THREE . Vector2 ( gamepad . axes [ 2 ] , gamepad . axes [ 3 ] ) ; default : throw new Error ( 'Unexpected joystick index "%d".' , index ) ; } }


Input: Returns the state of the dpad as a THREE . Vector2 . [CODESPLIT] function ( ) { const gamepad = this . getGamepad ( ) ; if ( ! gamepad . buttons [ GamepadButton . DPAD_RIGHT ] ) { return new THREE . Vector2 ( ) ; } return new THREE . Vector2 ( ( gamepad . buttons [ GamepadButton . DPAD_RIGHT ] . pressed ? 1 : 0 ) + ( gamepad . buttons [ GamepadButton . DPAD_LEFT ] . pressed ? - 1 : 0 ) , ( gamepad . buttons [ GamepadButton . DPAD_UP ] . pressed ? - 1 : 0 ) + ( gamepad . buttons [ GamepadButton . DPAD_DOWN ] . pressed ? 1 : 0 ) ) ; }


Input: Use play () instead of init () because component mappings – unavailable as dependencies – are not guaranteed to have parsed when this component is initialized . [CODESPLIT] function ( ) { const el = this . el , data = this . data ; let material = el . components . material ; const geometry = new THREE . PlaneGeometry ( data . width , data . depth , data . density , data . density ) ; geometry . mergeVertices ( ) ; this . waves = [ ] ; for ( let v , i = 0 , l = geometry . vertices . length ; i < l ; i ++ ) { v = geometry . vertices [ i ] ; this . waves . push ( { z : v . z , ang : Math . random ( ) * Math . PI * 2 , amp : data . amplitude + Math . random ( ) * data . amplitudeVariance , speed : ( data . speed + Math . random ( ) * data . speedVariance ) / 1000 // radians / frame } ) ; } if ( ! material ) { material = { } ; material . material = new THREE . MeshPhongMaterial ( { color : data . color , transparent : data . opacity < 1 , opacity : data . opacity , shading : THREE . FlatShading , } ) ; } this . mesh = new THREE . Mesh ( geometry , material . material ) ; el . setObject3D ( 'mesh' , this . mesh ) ; }


Input: Make a URLSearchParams instance [CODESPLIT] function URLSearchParamsPolyfill ( search ) { search = search || "" ; // support construct object with another URLSearchParams instance if ( search instanceof URLSearchParams || search instanceof URLSearchParamsPolyfill ) { search = search . toString ( ) ; } this [ __URLSearchParams__ ] = parseToDict ( search ) ; }


Input: / --- API [CODESPLIT] function LDAPResult ( options ) { options = options || { } ; assert . object ( options ) ; assert . optionalNumber ( options . status ) ; assert . optionalString ( options . matchedDN ) ; assert . optionalString ( options . errorMessage ) ; assert . optionalArrayOfString ( options . referrals ) ; LDAPMessage . call ( this , options ) ; this . status = options . status || 0 ; // LDAP SUCCESS this . matchedDN = options . matchedDN || '' ; this . errorMessage = options . errorMessage || '' ; this . referrals = options . referrals || [ ] ; this . connection = options . connection || null ; }


Input: / --- API [CODESPLIT] function BindResponse ( options ) { options = options || { } ; assert . object ( options ) ; options . protocolOp = Protocol . LDAP_REP_BIND ; LDAPResult . call ( this , options ) ; }


Input: / --- API [CODESPLIT] function Change ( options ) { if ( options ) { assert . object ( options ) ; assert . optionalString ( options . operation ) ; } else { options = { } ; } this . _modification = false ; this . operation = options . operation || options . type || 'add' ; this . modification = options . modification || { } ; }


Input: / --- API [CODESPLIT] function DeleteResponse ( options ) { options = options || { } ; assert . object ( options ) ; options . protocolOp = Protocol . LDAP_REP_DELETE ; LDAPResult . call ( this , options ) ; }


Input: / --- API [CODESPLIT] function Control ( options ) { assert . optionalObject ( options ) ; options = options || { } ; assert . optionalString ( options . type ) ; assert . optionalBool ( options . criticality ) ; if ( options . value ) { assert . buffer ( options . value ) ; } this . type = options . type || '' ; this . criticality = options . critical || options . criticality || false ; this . value = options . value || null ; }


Input: / --- API [CODESPLIT] function UnbindRequest ( options ) { options = options || { } ; assert . object ( options ) ; options . protocolOp = Protocol . LDAP_REQ_UNBIND ; LDAPMessage . call ( this , options ) ; }


Input: / --- API [CODESPLIT] function SearchResponse ( options ) { options = options || { } ; assert . object ( options ) ; options . protocolOp = Protocol . LDAP_REP_SEARCH ; LDAPResult . call ( this , options ) ; this . attributes = options . attributes ? options . attributes . slice ( ) : [ ] ; this . notAttributes = [ ] ; this . sentEntries = 0 ; }


Input: / --- API [CODESPLIT] function ModifyResponse ( options ) { options = options || { } ; assert . object ( options ) ; options . protocolOp = Protocol . LDAP_REP_MODIFY ; LDAPResult . call ( this , options ) ; }


Input: Queue to contain LDAP requests . [CODESPLIT] function RequestQueue ( opts ) { if ( ! opts || typeof ( opts ) !== 'object' ) { opts = { } ; } this . size = ( opts . size > 0 ) ? opts . size : Infinity ; this . timeout = ( opts . timeout > 0 ) ? opts . timeout : 0 ; this . _queue = [ ] ; this . _timer = null ; this . _frozen = false ; }


Input: Track message callback by messageID . [CODESPLIT] function MessageTracker ( opts ) { assert . object ( opts ) ; assert . string ( opts . id ) ; assert . object ( opts . parser ) ; this . id = opts . id ; this . _msgid = 0 ; this . _messages = { } ; this . _abandoned = { } ; this . parser = opts . parser ; var self = this ; this . __defineGetter__ ( 'pending' , function ( ) { return Object . keys ( self . _messages ) ; } ) ; }


Input: Is ( comp > = ref ) according to sliding window [CODESPLIT] function geWindow ( ref , comp ) { var max = ref + ( MAX_MSGID / 2 ) ; var min = ref ; if ( max >= MAX_MSGID ) { // Handle roll-over max = max - MAX_MSGID - 1 ; return ( ( comp <= max ) || ( comp >= min ) ) ; } else { return ( ( comp <= max ) && ( comp >= min ) ) ; } }


Input: / --- API Constructs a new client . [CODESPLIT] function Client ( options ) { assert . ok ( options ) ; EventEmitter . call ( this , options ) ; var self = this ; var _url ; if ( options . url ) _url = url . parse ( options . url ) ; this . host = _url ? _url . hostname : undefined ; this . port = _url ? _url . port : false ; this . secure = _url ? _url . secure : false ; this . url = _url ; this . tlsOptions = options . tlsOptions ; this . socketPath = options . socketPath || false ; this . log = options . log . child ( { clazz : 'Client' } , true ) ; this . timeout = parseInt ( ( options . timeout || 0 ) , 10 ) ; this . connectTimeout = parseInt ( ( options . connectTimeout || 0 ) , 10 ) ; this . idleTimeout = parseInt ( ( options . idleTimeout || 0 ) , 10 ) ; if ( options . reconnect ) { // Fall back to defaults if options.reconnect === true var rOpts = ( typeof ( options . reconnect ) === 'object' ) ? options . reconnect : { } ; this . reconnect = { initialDelay : parseInt ( rOpts . initialDelay || 100 , 10 ) , maxDelay : parseInt ( rOpts . maxDelay || 10000 , 10 ) , failAfter : parseInt ( rOpts . failAfter , 10 ) || Infinity } ; } this . strictDN = ( options . strictDN !== undefined ) ? options . strictDN : true ; this . queue = new RequestQueue ( { size : parseInt ( ( options . queueSize || 0 ) , 10 ) , timeout : parseInt ( ( options . queueTimeout || 0 ) , 10 ) } ) ; if ( options . queueDisable ) { this . queue . freeze ( ) ; } // Implicitly configure setup action to bind the client if bindDN and // bindCredentials are passed in.  This will more closely mimic PooledClient // auto-login behavior. if ( options . bindDN !== undefined && options . bindCredentials !== undefined ) { this . on ( 'setup' , function ( clt , cb ) { clt . bind ( options . bindDN , options . bindCredentials , function ( err ) { if ( err ) { self . emit ( 'error' , err ) ; } cb ( err ) ; } ) ; } ) ; } this . _socket = null ; this . connected = false ; this . connect ( ) ; }


Input: Establish basic socket connection [CODESPLIT] function connectSocket ( cb ) { cb = once ( cb ) ; function onResult ( err , res ) { if ( err ) { if ( self . connectTimer ) { clearTimeout ( self . connectTimer ) ; self . connectTimer = null ; } self . emit ( 'connectError' , err ) ; } cb ( err , res ) ; } function onConnect ( ) { if ( self . connectTimer ) { clearTimeout ( self . connectTimer ) ; self . connectTimer = null ; } socket . removeAllListeners ( 'error' ) . removeAllListeners ( 'connect' ) . removeAllListeners ( 'secureConnect' ) ; tracker . id = nextClientId ( ) + '__' + tracker . id ; self . log = self . log . child ( { ldap_id : tracker . id } , true ) ; // Move on to client setup setupClient ( cb ) ; } var port = ( self . port || self . socketPath ) ; if ( self . secure ) { socket = tls . connect ( port , self . host , self . tlsOptions ) ; socket . once ( 'secureConnect' , onConnect ) ; } else { socket = net . connect ( port , self . host ) ; socket . once ( 'connect' , onConnect ) ; } socket . once ( 'error' , onResult ) ; initSocket ( ) ; // Setup connection timeout handling, if desired if ( self . connectTimeout ) { self . connectTimer = setTimeout ( function onConnectTimeout ( ) { if ( ! socket || ! socket . readable || ! socket . writeable ) { socket . destroy ( ) ; self . _socket = null ; onResult ( new ConnectionError ( 'connection timeout' ) ) ; } } , self . connectTimeout ) ; } }


Input: Initialize socket events and LDAP parser . [CODESPLIT] function initSocket ( ) { tracker = new MessageTracker ( { id : self . url ? self . url . href : self . socketPath , parser : new Parser ( { log : log } ) } ) ; // This won't be set on TLS. So. Very. Annoying. if ( typeof ( socket . setKeepAlive ) !== 'function' ) { socket . setKeepAlive = function setKeepAlive ( enable , delay ) { return socket . socket ? socket . socket . setKeepAlive ( enable , delay ) : false ; } ; } socket . on ( 'data' , function onData ( data ) { if ( log . trace ( ) ) log . trace ( 'data event: %s' , util . inspect ( data ) ) ; tracker . parser . write ( data ) ; } ) ; // The "router" tracker . parser . on ( 'message' , function onMessage ( message ) { message . connection = self . _socket ; var callback = tracker . fetch ( message . messageID ) ; if ( ! callback ) { log . error ( { message : message . json } , 'unsolicited message' ) ; return false ; } return callback ( message ) ; } ) ; tracker . parser . on ( 'error' , function onParseError ( err ) { self . emit ( 'error' , new VError ( err , 'Parser error for %s' , tracker . id ) ) ; self . connected = false ; socket . end ( ) ; } ) ; }


Input: After connect register socket event handlers and run any setup actions [CODESPLIT] function setupClient ( cb ) { cb = once ( cb ) ; // Indicate failure if anything goes awry during setup function bail ( err ) { socket . destroy ( ) ; cb ( err || new Error ( 'client error during setup' ) ) ; } // Work around lack of close event on tls.socket in node < 0.11 ( ( socket . socket ) ? socket . socket : socket ) . once ( 'close' , bail ) ; socket . once ( 'error' , bail ) ; socket . once ( 'end' , bail ) ; socket . once ( 'timeout' , bail ) ; self . _socket = socket ; self . _tracker = tracker ; // Run any requested setup (such as automatically performing a bind) on // socket before signalling successful connection. // This setup needs to bypass the request queue since all other activity is // blocked until the connection is considered fully established post-setup. // Only allow bind/search/starttls for now. var basicClient = { bind : function bindBypass ( name , credentials , controls , callback ) { return self . bind ( name , credentials , controls , callback , true ) ; } , search : function searchBypass ( base , options , controls , callback ) { return self . search ( base , options , controls , callback , true ) ; } , starttls : function starttlsBypass ( options , controls , callback ) { return self . starttls ( options , controls , callback , true ) ; } , unbind : self . unbind . bind ( self ) } ; vasync . forEachPipeline ( { func : function ( f , callback ) { f ( basicClient , callback ) ; } , inputs : self . listeners ( 'setup' ) } , function ( err , res ) { if ( err ) { self . emit ( 'setupError' , err ) ; } cb ( err ) ; } ) ; }


Input: Wire up official event handlers after successful connect / setup [CODESPLIT] function postSetup ( ) { socket . removeAllListeners ( 'error' ) . removeAllListeners ( 'close' ) . removeAllListeners ( 'end' ) . removeAllListeners ( 'timeout' ) ; // Work around lack of close event on tls.socket in node < 0.11 ( ( socket . socket ) ? socket . socket : socket ) . once ( 'close' , self . _onClose . bind ( self ) ) ; socket . on ( 'end' , function onEnd ( ) { if ( log . trace ( ) ) log . trace ( 'end event' ) ; self . emit ( 'end' ) ; socket . end ( ) ; } ) ; socket . on ( 'error' , function onSocketError ( err ) { if ( log . trace ( ) ) log . trace ( { err : err } , 'error event: %s' , new Error ( ) . stack ) ; self . emit ( 'error' , err ) ; socket . destroy ( ) ; } ) ; socket . on ( 'timeout' , function onTimeout ( ) { if ( log . trace ( ) ) log . trace ( 'timeout event' ) ; self . emit ( 'socketTimeout' ) ; socket . end ( ) ; } ) ; }


Input: / --- API [CODESPLIT] function SearchEntry ( options ) { options = options || { } ; assert . object ( options ) ; lassert . optionalStringDN ( options . objectName ) ; options . protocolOp = Protocol . LDAP_REP_SEARCH_ENTRY ; LDAPMessage . call ( this , options ) ; this . objectName = options . objectName || null ; this . setAttributes ( options . attributes || [ ] ) ; }


Input: / --- API [CODESPLIT] function Attribute ( options ) { if ( options ) { if ( typeof ( options ) !== 'object' ) throw new TypeError ( 'options must be an object' ) ; if ( options . type && typeof ( options . type ) !== 'string' ) throw new TypeError ( 'options.type must be a string' ) ; } else { options = { } ; } this . type = options . type || '' ; this . _vals = [ ] ; if ( options . vals !== undefined && options . vals !== null ) this . vals = options . vals ; }


Input: / --- API [CODESPLIT] function SearchRequest ( options ) { options = options || { } ; assert . object ( options ) ; options . protocolOp = Protocol . LDAP_REQ_SEARCH ; LDAPMessage . call ( this , options ) ; if ( options . baseObject !== undefined ) { this . baseObject = options . baseObject ; } else { this . baseObject = dn . parse ( '' ) ; } this . scope = options . scope || 'base' ; this . derefAliases = options . derefAliases || Protocol . NEVER_DEREF_ALIASES ; this . sizeLimit = options . sizeLimit || 0 ; this . timeLimit = options . timeLimit || 0 ; this . typesOnly = options . typesOnly || false ; this . filter = options . filter || null ; this . attributes = options . attributes ? options . attributes . slice ( 0 ) : [ ] ; }


Input: / --- Helpers [CODESPLIT] function mergeFunctionArgs ( argv , start , end ) { assert . ok ( argv ) ; if ( ! start ) start = 0 ; if ( ! end ) end = argv . length ; var handlers = [ ] ; for ( var i = start ; i < end ; i ++ ) { if ( argv [ i ] instanceof Array ) { var arr = argv [ i ] ; for ( var j = 0 ; j < arr . length ; j ++ ) { if ( ! ( arr [ j ] instanceof Function ) ) { throw new TypeError ( 'Invalid argument type: ' + typeof ( arr [ j ] ) ) ; } handlers . push ( arr [ j ] ) ; } } else if ( argv [ i ] instanceof Function ) { handlers . push ( argv [ i ] ) ; } else { throw new TypeError ( 'Invalid argument type: ' + typeof ( argv [ i ] ) ) ; } } return handlers ; }


Input: / --- API Constructs a new server that you can call . listen () on in the various forms node supports . You need to first assign some handlers to the various LDAP operations however . [CODESPLIT] function Server ( options ) { if ( options ) { if ( typeof ( options ) !== 'object' ) throw new TypeError ( 'options (object) required' ) ; if ( typeof ( options . log ) !== 'object' ) throw new TypeError ( 'options.log must be an object' ) ; if ( options . certificate || options . key ) { if ( ! ( options . certificate && options . key ) || ( typeof ( options . certificate ) !== 'string' && ! Buffer . isBuffer ( options . certificate ) ) || ( typeof ( options . key ) !== 'string' && ! Buffer . isBuffer ( options . key ) ) ) { throw new TypeError ( 'options.certificate and options.key ' + '(string or buffer) are both required for TLS' ) ; } } } else { options = { } ; } var self = this ; EventEmitter . call ( this , options ) ; this . _chain = [ ] ; this . log = options . log ; this . strictDN = ( options . strictDN !== undefined ) ? options . strictDN : true ; var log = this . log ; function setupConnection ( c ) { assert . ok ( c ) ; if ( c . type === 'unix' ) { c . remoteAddress = self . server . path ; c . remotePort = c . fd ; } else if ( c . socket ) { // TLS c . remoteAddress = c . socket . remoteAddress ; c . remotePort = c . socket . remotePort ; } var rdn = new dn . RDN ( { cn : 'anonymous' } ) ; c . ldap = { id : c . remoteAddress + ':' + c . remotePort , config : options , _bindDN : new DN ( [ rdn ] ) } ; c . addListener ( 'timeout' , function ( ) { log . trace ( '%s timed out' , c . ldap . id ) ; c . destroy ( ) ; } ) ; c . addListener ( 'end' , function ( ) { log . trace ( '%s shutdown' , c . ldap . id ) ; } ) ; c . addListener ( 'error' , function ( err ) { log . warn ( '%s unexpected connection error' , c . ldap . id , err ) ; self . emit ( 'clientError' , err ) ; c . destroy ( ) ; } ) ; c . addListener ( 'close' , function ( had_err ) { log . trace ( '%s close; had_err=%j' , c . ldap . id , had_err ) ; c . end ( ) ; } ) ; c . ldap . __defineGetter__ ( 'bindDN' , function ( ) { return c . ldap . _bindDN ; } ) ; c . ldap . __defineSetter__ ( 'bindDN' , function ( val ) { if ( ! ( val instanceof DN ) ) throw new TypeError ( 'DN required' ) ; c . ldap . _bindDN = val ; return val ; } ) ; return c ; } function newConnection ( c ) { setupConnection ( c ) ; log . trace ( 'new connection from %s' , c . ldap . id ) ; dtrace . fire ( 'server-connection' , function ( ) { return [ c . remoteAddress ] ; } ) ; c . parser = new Parser ( { log : options . log } ) ; c . parser . on ( 'message' , function ( req ) { req . connection = c ; req . logId = c . ldap . id + '::' + req . messageID ; req . startTime = new Date ( ) . getTime ( ) ; if ( log . debug ( ) ) log . debug ( '%s: message received: req=%j' , c . ldap . id , req . json ) ; var res = getResponse ( req ) ; if ( ! res ) { log . warn ( 'Unimplemented server method: %s' , req . type ) ; c . destroy ( ) ; return false ; } // parse string DNs for routing/etc try { switch ( req . protocolOp ) { case Protocol . LDAP_REQ_BIND : req . name = dn . parse ( req . name ) ; break ; case Protocol . LDAP_REQ_ADD : case Protocol . LDAP_REQ_COMPARE : case Protocol . LDAP_REQ_DELETE : req . entry = dn . parse ( req . entry ) ; break ; case Protocol . LDAP_REQ_MODIFY : req . object = dn . parse ( req . object ) ; break ; case Protocol . LDAP_REQ_MODRDN : req . entry = dn . parse ( req . entry ) ; // TODO: handle newRdn/Superior break ; case Protocol . LDAP_REQ_SEARCH : req . baseObject = dn . parse ( req . baseObject ) ; break ; default : break ; } } catch ( e ) { if ( self . strictDN ) { return res . end ( errors . LDAP_INVALID_DN_SYNTAX ) ; } } res . connection = c ; res . logId = req . logId ; res . requestDN = req . dn ; var chain = self . _getHandlerChain ( req , res ) ; var i = 0 ; return function ( err ) { function sendError ( err ) { res . status = err . code || errors . LDAP_OPERATIONS_ERROR ; res . matchedDN = req . suffix ? req . suffix . toString ( ) : '' ; res . errorMessage = err . message || '' ; return res . end ( ) ; } function after ( ) { if ( ! self . _postChain || ! self . _postChain . length ) return ; function next ( ) { } // stub out next for the post chain self . _postChain . forEach ( function ( c ) { c . call ( self , req , res , next ) ; } ) ; } if ( err ) { log . trace ( '%s sending error: %s' , req . logId , err . stack || err ) ; self . emit ( 'clientError' , err ) ; sendError ( err ) ; return after ( ) ; } try { var next = arguments . callee ; if ( chain . handlers [ i ] ) return chain . handlers [ i ++ ] . call ( chain . backend , req , res , next ) ; if ( req . protocolOp === Protocol . LDAP_REQ_BIND && res . status === 0 ) c . ldap . bindDN = req . dn ; return after ( ) ; } catch ( e ) { if ( ! e . stack ) e . stack = e . toString ( ) ; log . error ( '%s uncaught exception: %s' , req . logId , e . stack ) ; return sendError ( new errors . OperationsError ( e . message ) ) ; } } ( ) ; } ) ; c . parser . on ( 'error' , function ( err , message ) { self . emit ( 'error' , new VError ( err , 'Parser error for %s' , c . ldap . id ) ) ; if ( ! message ) return c . destroy ( ) ; var res = getResponse ( message ) ; if ( ! res ) return c . destroy ( ) ; res . status = 0x02 ; // protocol error res . errorMessage = err . toString ( ) ; return c . end ( res . toBer ( ) ) ; } ) ; c . on ( 'data' , function ( data ) { if ( log . trace ( ) ) log . trace ( 'data on %s: %s' , c . ldap . id , util . inspect ( data ) ) ; c . parser . write ( data ) ; } ) ; } // end newConnection this . routes = { } ; if ( ( options . cert || options . certificate ) && options . key ) { options . cert = options . cert || options . certificate ; this . server = tls . createServer ( options , newConnection ) ; } else { this . server = net . createServer ( newConnection ) ; } this . server . log = options . log ; this . server . ldap = { config : options } ; this . server . on ( 'close' , function ( ) { self . emit ( 'close' ) ; } ) ; this . server . on ( 'error' , function ( err ) { self . emit ( 'error' , err ) ; } ) ; }


Input: / --- Helpers Copied from mcavage / node - assert - plus [CODESPLIT] function _assert ( arg , type , name ) { name = name || type ; throw new assert . AssertionError ( { message : util . format ( '%s (%s) required' , name , type ) , actual : typeof ( arg ) , expected : type , operator : '===' , stackStartFunction : _assert . caller } ) ; }


Input: / --- API [CODESPLIT] function AddResponse ( options ) { options = options || { } ; assert . object ( options ) ; options . protocolOp = Protocol . LDAP_REP_ADD ; LDAPResult . call ( this , options ) ; }


Input: / --- API [CODESPLIT] function Parser ( options ) { assert . object ( options ) ; assert . object ( options . log ) ; EventEmitter . call ( this ) ; this . buffer = null ; this . log = options . log ; }


Input: / --- API [CODESPLIT] function ModifyRequest ( options ) { options = options || { } ; assert . object ( options ) ; lassert . optionalStringDN ( options . object ) ; lassert . optionalArrayOfAttribute ( options . attributes ) ; options . protocolOp = Protocol . LDAP_REQ_MODIFY ; LDAPMessage . call ( this , options ) ; this . object = options . object || null ; this . changes = options . changes ? options . changes . slice ( 0 ) : [ ] ; }


Input: / --- API [CODESPLIT] function ServerSideSortingRequestControl ( options ) { assert . optionalObject ( options ) ; options = options || { } ; options . type = ServerSideSortingRequestControl . OID ; if ( options . value ) { if ( Buffer . isBuffer ( options . value ) ) { this . parse ( options . value ) ; } else if ( Array . isArray ( options . value ) ) { assert . arrayOfObject ( options . value , 'options.value must be Objects' ) ; for ( var i = 0 ; i < options . value . length ; i ++ ) { if ( ! options . value [ i ] . hasOwnProperty ( 'attributeType' ) ) { throw new Error ( 'Missing required key: attributeType' ) ; } } this . _value = options . value ; } else if ( typeof ( options . value ) === 'object' ) { if ( ! options . value . hasOwnProperty ( 'attributeType' ) ) { throw new Error ( 'Missing required key: attributeType' ) ; } this . _value = [ options . value ] ; } else { throw new TypeError ( 'options.value must be a Buffer, Array or Object' ) ; } options . value = null ; } Control . call ( this , options ) ; }


Input: / --- Error Base class [CODESPLIT] function LDAPError ( message , dn , caller ) { if ( Error . captureStackTrace ) Error . captureStackTrace ( this , caller || LDAPError ) ; this . lde_message = message ; this . lde_dn = dn ; }


Input: / --- API Ok so there s really no such thing as an unbind response but to make the framework not suck I just made this up and have it stubbed so it s not such a one - off . [CODESPLIT] function UnbindResponse ( options ) { options = options || { } ; assert . object ( options ) ; options . protocolOp = 0 ; LDAPMessage . call ( this , options ) ; }


Input: / --- API [CODESPLIT] function ExtendedRequest ( options ) { options = options || { } ; assert . object ( options ) ; assert . optionalString ( options . requestName ) ; if ( options . requestValue && ! ( Buffer . isBuffer ( options . requestValue ) || typeof ( options . requestValue ) === 'string' ) ) { throw new TypeError ( 'options.requestValue must be a buffer or a string' ) ; } options . protocolOp = Protocol . LDAP_REQ_EXTENSION ; LDAPMessage . call ( this , options ) ; this . requestName = options . requestName || '' ; this . requestValue = options . requestValue ; }


Input: / --- Internal Parsers / * A filter looks like this coming in : Filter :: = CHOICE { and [ 0 ] SET OF Filter or [ 1 ] SET OF Filter not [ 2 ] Filter equalityMatch [ 3 ] AttributeValueAssertion substrings [ 4 ] SubstringFilter greaterOrEqual [ 5 ] AttributeValueAssertion lessOrEqual [ 6 ] AttributeValueAssertion present [ 7 ] AttributeType approxMatch [ 8 ] AttributeValueAssertion extensibleMatch [ 9 ] MatchingRuleAssertion -- v3 only } [CODESPLIT] function _parse ( ber ) { assert . ok ( ber ) ; function parseSet ( f ) { var end = ber . offset + ber . length ; while ( ber . offset < end ) f . addFilter ( _parse ( ber ) ) ; } var f ; var type = ber . readSequence ( ) ; switch ( type ) { case Protocol . FILTER_AND : f = new AndFilter ( ) ; parseSet ( f ) ; break ; case Protocol . FILTER_APPROX : f = new ApproximateFilter ( ) ; f . parse ( ber ) ; break ; case Protocol . FILTER_EQUALITY : f = new EqualityFilter ( ) ; f . parse ( ber ) ; return f ; case Protocol . FILTER_EXT : f = new ExtensibleFilter ( ) ; f . parse ( ber ) ; return f ; case Protocol . FILTER_GE : f = new GreaterThanEqualsFilter ( ) ; f . parse ( ber ) ; return f ; case Protocol . FILTER_LE : f = new LessThanEqualsFilter ( ) ; f . parse ( ber ) ; return f ; case Protocol . FILTER_NOT : var _f = _parse ( ber ) ; f = new NotFilter ( { filter : _f } ) ; break ; case Protocol . FILTER_OR : f = new OrFilter ( ) ; parseSet ( f ) ; break ; case Protocol . FILTER_PRESENT : f = new PresenceFilter ( ) ; f . parse ( ber ) ; break ; case Protocol . FILTER_SUBSTRINGS : f = new SubstringFilter ( ) ; f . parse ( ber ) ; break ; default : throw new Error ( 'Invalid search filter type: 0x' + type . toString ( 16 ) ) ; } assert . ok ( f ) ; return f ; }


Input: / --- API [CODESPLIT] function SearchReference ( options ) { options = options || { } ; assert . object ( options ) ; options . protocolOp = Protocol . LDAP_REP_SEARCH_REF ; LDAPMessage . call ( this , options ) ; this . uris = options . uris || [ ] ; }


Input: / --- API [CODESPLIT] function ExtendedResponse ( options ) { options = options || { } ; assert . object ( options ) ; assert . optionalString ( options . responseName ) ; assert . optionalString ( options . responsevalue ) ; this . responseName = options . responseName || undefined ; this . responseValue = options . responseValue || undefined ; options . protocolOp = Protocol . LDAP_REP_EXTENSION ; LDAPResult . call ( this , options ) ; }


Input: / --- API [CODESPLIT] function CompareResponse ( options ) { options = options || { } ; assert . object ( options ) ; options . protocolOp = Protocol . LDAP_REP_COMPARE ; LDAPResult . call ( this , options ) ; }


Input: / --- API [CODESPLIT] function ModifyDNRequest ( options ) { options = options || { } ; assert . object ( options ) ; assert . optionalBool ( options . deleteOldRdn ) ; lassert . optionalStringDN ( options . entry ) ; lassert . optionalDN ( options . newRdn ) ; lassert . optionalDN ( options . newSuperior ) ; options . protocolOp = Protocol . LDAP_REQ_MODRDN ; LDAPMessage . call ( this , options ) ; this . entry = options . entry || null ; this . newRdn = options . newRdn || null ; this . deleteOldRdn = options . deleteOldRdn || true ; this . newSuperior = options . newSuperior || null ; }


Input: / --- API [CODESPLIT] function AbandonRequest ( options ) { options = options || { } ; assert . object ( options ) ; assert . optionalNumber ( options . abandonID ) ; options . protocolOp = Protocol . LDAP_REQ_ABANDON ; LDAPMessage . call ( this , options ) ; this . abandonID = options . abandonID || 0 ; }


Input: / --- Shared handlers [CODESPLIT] function authorize ( req , res , next ) { /* Any user may search after bind, only cn=root has full power */ var isSearch = ( req instanceof ldap . SearchRequest ) ; if ( ! req . connection . ldap . bindDN . equals ( 'cn=root' ) && ! isSearch ) return next ( new ldap . InsufficientAccessRightsError ( ) ) ; return next ( ) ; }


Input: / --- Helpers [CODESPLIT] function invalidDN ( name ) { var e = new Error ( ) ; e . name = 'InvalidDistinguishedNameError' ; e . message = name ; return e ; }


Input: / --- API [CODESPLIT] function RDN ( obj ) { var self = this ; this . attrs = { } ; if ( obj ) { Object . keys ( obj ) . forEach ( function ( k ) { self . set ( k , obj [ k ] ) ; } ) ; } }


Input: Thank you OpenJDK! [CODESPLIT] function parse ( name ) { if ( typeof ( name ) !== 'string' ) throw new TypeError ( 'name (string) required' ) ; var cur = 0 ; var len = name . length ; function parseRdn ( ) { var rdn = new RDN ( ) ; var order = 0 ; rdn . spLead = trim ( ) ; while ( cur < len ) { var opts = { order : order } ; var attr = parseAttrType ( ) ; trim ( ) ; if ( cur >= len || name [ cur ++ ] !== '=' ) throw invalidDN ( name ) ; trim ( ) ; // Parameters about RDN value are set in 'opts' by parseAttrValue var value = parseAttrValue ( opts ) ; rdn . set ( attr , value , opts ) ; rdn . spTrail = trim ( ) ; if ( cur >= len || name [ cur ] !== '+' ) break ; ++ cur ; ++ order ; } return rdn ; } function trim ( ) { var count = 0 ; while ( ( cur < len ) && isWhitespace ( name [ cur ] ) ) { ++ cur ; count ++ ; } return count ; } function parseAttrType ( ) { var beg = cur ; while ( cur < len ) { var c = name [ cur ] ; if ( isAlphaNumeric ( c ) || c == '.' || c == '-' || c == ' ' ) { ++ cur ; } else { break ; } } // Back out any trailing spaces. while ( ( cur > beg ) && ( name [ cur - 1 ] == ' ' ) ) -- cur ; if ( beg == cur ) throw invalidDN ( name ) ; return name . slice ( beg , cur ) ; } function parseAttrValue ( opts ) { if ( cur < len && name [ cur ] == '#' ) { opts . binary = true ; return parseBinaryAttrValue ( ) ; } else if ( cur < len && name [ cur ] == '"' ) { opts . quoted = true ; return parseQuotedAttrValue ( ) ; } else { return parseStringAttrValue ( ) ; } } function parseBinaryAttrValue ( ) { var beg = cur ++ ; while ( cur < len && isAlphaNumeric ( name [ cur ] ) ) ++ cur ; return name . slice ( beg , cur ) ; } function parseQuotedAttrValue ( ) { var str = '' ; ++ cur ; // Consume the first quote while ( ( cur < len ) && name [ cur ] != '"' ) { if ( name [ cur ] === '\\' ) cur ++ ; str += name [ cur ++ ] ; } if ( cur ++ >= len ) // no closing quote throw invalidDN ( name ) ; return str ; } function parseStringAttrValue ( ) { var beg = cur ; var str = '' ; var esc = - 1 ; while ( ( cur < len ) && ! atTerminator ( ) ) { if ( name [ cur ] === '\\' ) { // Consume the backslash and mark its place just in case it's escaping // whitespace which needs to be preserved. esc = cur ++ ; } if ( cur === len ) // backslash followed by nothing throw invalidDN ( name ) ; str += name [ cur ++ ] ; } // Trim off (unescaped) trailing whitespace and rewind cursor to the end of // the AttrValue to record whitespace length. for ( ; cur > beg ; cur -- ) { if ( ! isWhitespace ( name [ cur - 1 ] ) || ( esc === ( cur - 1 ) ) ) break ; } return str . slice ( 0 , cur - beg ) ; } function atTerminator ( ) { return ( cur < len && ( name [ cur ] === ',' || name [ cur ] === ';' || name [ cur ] === '+' ) ) ; } var rdns = [ ] ; // Short-circuit for empty DNs if ( len === 0 ) return new DN ( rdns ) ; rdns . push ( parseRdn ( ) ) ; while ( cur < len ) { if ( name [ cur ] === ',' || name [ cur ] === ';' ) { ++ cur ; rdns . push ( parseRdn ( ) ) ; } else { throw invalidDN ( name ) ; } } return new DN ( rdns ) ; }


Input: / --- API Handler object for paged search operations . [CODESPLIT] function SearchPager ( opts ) { assert . object ( opts ) ; assert . func ( opts . callback ) ; assert . number ( opts . pageSize ) ; EventEmitter . call ( this , { } ) ; this . callback = opts . callback ; this . controls = opts . controls ; this . pageSize = opts . pageSize ; this . pagePause = opts . pagePause ; this . controls . forEach ( function ( control ) { if ( control . type === PagedControl . OID ) { // The point of using SearchPager is not having to do this. // Toss an error if the pagedResultsControl is present throw new Error ( 'redundant pagedResultControl' ) ; } } ) ; this . finished = false ; this . started = false ; var emitter = new EventEmitter ( ) ; emitter . on ( 'searchEntry' , this . emit . bind ( this , 'searchEntry' ) ) ; emitter . on ( 'end' , this . _onEnd . bind ( this ) ) ; emitter . on ( 'error' , this . _onError . bind ( this ) ) ; this . childEmitter = emitter ; }


Input: / --- API [CODESPLIT] function ModifyDNResponse ( options ) { options = options || { } ; assert . object ( options ) ; options . protocolOp = Protocol . LDAP_REP_MODRDN ; LDAPResult . call ( this , options ) ; }


Input: / --- API [CODESPLIT] function DeleteRequest ( options ) { options = options || { } ; assert . object ( options ) ; lassert . optionalStringDN ( options . entry ) ; options . protocolOp = Protocol . LDAP_REQ_DELETE ; LDAPMessage . call ( this , options ) ; this . entry = options . entry || null ; }


Input: / --- API [CODESPLIT] function AddRequest ( options ) { options = options || { } ; assert . object ( options ) ; lassert . optionalStringDN ( options . entry ) ; lassert . optionalArrayOfAttribute ( options . attributes ) ; options . protocolOp = Protocol . LDAP_REQ_ADD ; LDAPMessage . call ( this , options ) ; this . entry = options . entry || null ; this . attributes = options . attributes ? options . attributes . slice ( 0 ) : [ ] ; }


Input: / --- Functions [CODESPLIT] function xor ( ) { var b = false ; for ( var i = 0 ; i < arguments . length ; i ++ ) { if ( arguments [ i ] && ! b ) { b = true ; } else if ( arguments [ i ] && b ) { return false ; } } return b ; }


Input: / --- API [CODESPLIT] function CompareRequest ( options ) { options = options || { } ; assert . object ( options ) ; assert . optionalString ( options . attribute ) ; assert . optionalString ( options . value ) ; lassert . optionalStringDN ( options . entry ) ; options . protocolOp = Protocol . LDAP_REQ_COMPARE ; LDAPMessage . call ( this , options ) ; this . entry = options . entry || null ; this . attribute = options . attribute || '' ; this . value = options . value || '' ; }


Input: / --- API [CODESPLIT] function BindRequest ( options ) { options = options || { } ; assert . object ( options ) ; options . protocolOp = Protocol . LDAP_REQ_BIND ; LDAPMessage . call ( this , options ) ; this . version = options . version || 0x03 ; this . name = options . name || null ; this . authentication = options . authentication || LDAP_BIND_SIMPLE ; this . credentials = options . credentials || '' ; }


Input: / --- API [CODESPLIT] function AbandonResponse ( options ) { options = options || { } ; assert . object ( options ) ; options . protocolOp = 0 ; LDAPMessage . call ( this , options ) ; }


Input: / --- API [CODESPLIT] function PagedResultsControl ( options ) { assert . optionalObject ( options ) ; options = options || { } ; options . type = PagedResultsControl . OID ; if ( options . value ) { if ( Buffer . isBuffer ( options . value ) ) { this . parse ( options . value ) ; } else if ( typeof ( options . value ) === 'object' ) { this . _value = options . value ; } else { throw new TypeError ( 'options.value must be a Buffer or Object' ) ; } options . value = null ; } Control . call ( this , options ) ; }


Input: / --- API [CODESPLIT] function isFilter ( filter ) { if ( ! filter || typeof ( filter ) !== 'object' ) { return false ; } // Do our best to duck-type it if ( typeof ( filter . toBer ) === 'function' && typeof ( filter . matches ) === 'function' && TYPES [ filter . type ] !== undefined ) { return true ; } return false ; }


Input: / --- API LDAPMessage structure . [CODESPLIT] function LDAPMessage ( options ) { assert . object ( options ) ; this . messageID = options . messageID || 0 ; this . protocolOp = options . protocolOp || undefined ; this . controls = options . controls ? options . controls . slice ( 0 ) : [ ] ; this . log = options . log ; }


Input: Perform an A * Search on a graph given a start and end node . [CODESPLIT] function ( graph , start , end , options ) { graph . cleanDirty ( ) ; options = options || { } ; var heuristic = options . heuristic || astar . heuristics . manhattan ; var closest = options . closest || false ; var openHeap = getHeap ( ) ; var closestNode = start ; // set the start node to be the closest if required start . h = heuristic ( start , end ) ; graph . markDirty ( start ) ; openHeap . push ( start ) ; while ( openHeap . size ( ) > 0 ) { // Grab the lowest f(x) to process next.  Heap keeps this sorted for us. var currentNode = openHeap . pop ( ) ; // End case -- result has been found, return the traced path. if ( currentNode === end ) { return pathTo ( currentNode ) ; } // Normal case -- move currentNode from open to closed, process each of its neighbors. currentNode . closed = true ; // Find all neighbors for the current node. var neighbors = graph . neighbors ( currentNode ) ; for ( var i = 0 , il = neighbors . length ; i < il ; ++ i ) { var neighbor = neighbors [ i ] ; if ( neighbor . closed || neighbor . isWall ( ) ) { // Not a valid node to process, skip to next neighbor. continue ; } // The g score is the shortest distance from start to current node. // We need to check if the path we have arrived at this neighbor is the shortest one we have seen yet. var gScore = currentNode . g + neighbor . getCost ( currentNode ) ; var beenVisited = neighbor . visited ; if ( ! beenVisited || gScore < neighbor . g ) { // Found an optimal (so far) path to this node.  Take score for node to see how good it is. neighbor . visited = true ; neighbor . parent = currentNode ; neighbor . h = neighbor . h || heuristic ( neighbor , end ) ; neighbor . g = gScore ; neighbor . f = neighbor . g + neighbor . h ; graph . markDirty ( neighbor ) ; if ( closest ) { // If the neighbour is closer than the current closestNode or if it's equally close but has // a cheaper path than the current closest node then it becomes the closest node if ( neighbor . h < closestNode . h || ( neighbor . h === closestNode . h && neighbor . g < closestNode . g ) ) { closestNode = neighbor ; } } if ( ! beenVisited ) { // Pushing to heap will put it in proper place based on the 'f' value. openHeap . push ( neighbor ) ; } else { // Already seen the node, but since it has been rescored we need to reorder it in the heap openHeap . rescoreElement ( neighbor ) ; } } } } if ( closest ) { return pathTo ( closestNode ) ; } // No result was found - empty array signifies failure to find path. return [ ] ; }


Input: A graph memory structure [CODESPLIT] function Graph ( gridIn , options ) { options = options || { } ; this . nodes = [ ] ; this . diagonal = ! ! options . diagonal ; this . grid = [ ] ; for ( var x = 0 ; x < gridIn . length ; x ++ ) { this . grid [ x ] = [ ] ; for ( var y = 0 , row = gridIn [ x ] ; y < row . length ; y ++ ) { var node = new GridNode ( x , y , row [ y ] ) ; this . grid [ x ] [ y ] = node ; this . nodes . push ( node ) ; } } this . init ( ) ; }


Input: will add start class if final [CODESPLIT] function ( path , i ) { if ( i >= path . length ) { // finished removing path, set start positions return setStartClass ( path , i ) ; } elementFromNode ( path [ i ] ) . removeClass ( css . active ) ; setTimeout ( function ( ) { removeClass ( path , i + 1 ) ; } , timeout * path [ i ] . getCost ( ) ) ; }


Input: / * ! Register virtuals for this model [CODESPLIT] function ( model , schema ) { debug ( 'applying virtuals' ) ; for ( const i in schema . virtuals ) { schema . virtuals [ i ] . applyVirtuals ( model ) ; } }


Input: / * ! Register methods for this model [CODESPLIT] function ( model , schema ) { debug ( 'applying methods' ) ; for ( const i in schema . methods ) { model . prototype [ i ] = schema . methods [ i ] ; } }


Input: / * ! Register statics for this model [CODESPLIT] function ( model , schema ) { debug ( 'applying statics' ) ; for ( const i in schema . statics ) { model [ i ] = schema . statics [ i ] . bind ( model ) ; } }


Input: determine the set of operations to be executed [CODESPLIT] function Operations ( ) { this . ifNotExistsSet = { } ; this . SET = { } ; this . ADD = { } ; this . REMOVE = { } ; this . LISTAPPEND = { } ; this . addIfNotExistsSet = function ( name , item ) { this . ifNotExistsSet [ name ] = item ; } ; this . addSet = function ( name , item ) { if ( schema . hashKey . name !== name && ( schema . rangeKey || { } ) . name !== name ) { this . SET [ name ] = item ; } } ; this . addListAppend = function ( name , item ) { if ( schema . hashKey . name !== name && ( schema . rangeKey || { } ) . name !== name ) { this . LISTAPPEND [ name ] = item ; } } ; this . addAdd = function ( name , item ) { if ( schema . hashKey . name !== name && ( schema . rangeKey || { } ) . name !== name ) { this . ADD [ name ] = item ; } } ; this . addRemove = function ( name , item ) { if ( schema . hashKey . name !== name && ( schema . rangeKey || { } ) . name !== name ) { this . REMOVE [ name ] = item ; } } ; this . getUpdateExpression = function ( getUpdateReq ) { let attrCount = 0 ; let updateExpression = '' ; let attrName ; let valName ; let name ; let item ; const setExpressions = [ ] ; for ( name in this . ifNotExistsSet ) { item = this . ifNotExistsSet [ name ] ; attrName = ` ${ attrCount } ` ; valName = ` ${ attrCount } ` ; getUpdateReq . ExpressionAttributeNames [ attrName ] = name ; getUpdateReq . ExpressionAttributeValues [ valName ] = item ; setExpressions . push ( ` ${ attrName } ${ attrName } ${ valName } ` ) ; attrCount += 1 ; } for ( name in this . SET ) { item = this . SET [ name ] ; attrName = ` ${ attrCount } ` ; valName = ` ${ attrCount } ` ; getUpdateReq . ExpressionAttributeNames [ attrName ] = name ; getUpdateReq . ExpressionAttributeValues [ valName ] = item ; setExpressions . push ( ` ${ attrName } ${ valName } ` ) ; attrCount += 1 ; } for ( name in this . LISTAPPEND ) { item = this . LISTAPPEND [ name ] ; attrName = ` ${ attrCount } ` ; valName = ` ${ attrCount } ` ; getUpdateReq . ExpressionAttributeNames [ attrName ] = name ; getUpdateReq . ExpressionAttributeValues [ valName ] = item ; setExpressions . push ( ` ${ attrName } ${ attrName } ${ valName } ` ) ; attrCount += 1 ; } if ( setExpressions . length > 0 ) { updateExpression += ` ${ setExpressions . join ( ',' ) } ` ; } const addExpressions = [ ] ; for ( name in this . ADD ) { item = this . ADD [ name ] ; attrName = ` ${ attrCount } ` ; valName = ` ${ attrCount } ` ; getUpdateReq . ExpressionAttributeNames [ attrName ] = name ; getUpdateReq . ExpressionAttributeValues [ valName ] = item ; addExpressions . push ( ` ${ attrName } ${ valName } ` ) ; attrCount += 1 ; } if ( addExpressions . length > 0 ) { updateExpression += ` ${ addExpressions . join ( ',' ) } ` ; } const removeExpressions = [ ] ; for ( name in this . REMOVE ) { item = this . REMOVE [ name ] ; attrName = ` ${ attrCount } ` ; getUpdateReq . ExpressionAttributeNames [ attrName ] = name ; removeExpressions . push ( attrName ) ; attrCount += 1 ; } if ( removeExpressions . length > 0 ) { updateExpression += ` ${ removeExpressions . join ( ',' ) } ` ; } getUpdateReq . UpdateExpression = updateExpression ; } ; }


Input: / * Converts DynamoDB document types ( Map and List ) to dynamoose attribute definition map and ist types [CODESPLIT] function createAttrDefFromDynamo ( dynamoAttribute ) { let dynamoType ; const attrDef = { 'type' : module . exports . lookupType ( dynamoAttribute ) } ; if ( attrDef . type === Object ) { attrDef . type = 'map' ; for ( dynamoType in dynamoAttribute ) { attrDef . map = { } ; for ( const subAttrName in dynamoAttribute [ dynamoType ] ) { attrDef . map [ subAttrName ] = createAttrDefFromDynamo ( dynamoAttribute [ dynamoType ] [ subAttrName ] ) ; } } } else if ( attrDef . type === Array ) { attrDef . type = 'list' ; for ( dynamoType in dynamoAttribute ) { attrDef . list = dynamoAttribute [ dynamoType ] . map ( createAttrDefFromDynamo ) ; } } return attrDef ; }


Input: Private method [CODESPLIT] function parseAnchorOption ( anchor ) { let horizontal = anchor . match ( / left|center|right / gi ) || [ ] ; horizontal = horizontal . length === 0 ? 'left' : horizontal [ 0 ] ; let vertical = anchor . match ( / baseline|top|bottom|middle / gi ) || [ ] ; vertical = vertical . length === 0 ? 'baseline' : vertical [ 0 ] ; return { horizontal , vertical } ; }


Input: Iterates through array by index and performs the callback on each element of array until the callback returns a truthy value then returns that value . If no such value is found the callback is applied to each element of array and undefined is returned . [CODESPLIT] function forEach ( array , callback ) { if ( array ) { for ( var i = 0 , len = array . length ; i < len ; i ++ ) { var result = callback ( array [ i ] , i ) ; if ( result ) { return result ; } } } return undefined ; }


Input: Performs a binary search finding the index at which value occurs in array . If no such index is found returns the 2 s - complement of first index at which number [ index ] exceeds number . [CODESPLIT] function binarySearch ( array , value ) { var low = 0 ; var high = array . length - 1 ; while ( low <= high ) { var middle = low + ( ( high - low ) >> 1 ) ; var midValue = array [ middle ] ; if ( midValue === value ) { return middle ; } else if ( midValue > value ) { high = middle - 1 ; } else { low = middle + 1 ; } } return ~ low ; }


Input: Creates a map from the elements of an array . [CODESPLIT] function arrayToMap ( array , makeKey ) { var result = { } ; forEach ( array , function ( value ) { result [ makeKey ( value ) ] = value ; } ) ; return result ; }


Input: Returns length of path root ( i . e . length of / x : / // server / share / file : /// user / files ) [CODESPLIT] function getRootLength ( path ) { if ( path . charCodeAt ( 0 ) === 47 /* slash */ ) { if ( path . charCodeAt ( 1 ) !== 47 /* slash */ ) return 1 ; var p1 = path . indexOf ( "/" , 2 ) ; if ( p1 < 0 ) return 2 ; var p2 = path . indexOf ( "/" , p1 + 1 ) ; if ( p2 < 0 ) return p1 + 1 ; return p2 + 1 ; } if ( path . charCodeAt ( 1 ) === 58 /* colon */ ) { if ( path . charCodeAt ( 2 ) === 47 /* slash */ ) return 3 ; return 2 ; } // Per RFC 1738 'file' URI schema has the shape file://<host>/<path> // if <host> is omitted then it is assumed that host value is 'localhost', // however slash after the omitted <host> is not removed. // file:///folder1/file1 - this is a correct URI // file://folder2/file2 - this is an incorrect URI if ( path . lastIndexOf ( "file:///" , 0 ) === 0 ) { return "file:///" . length ; } var idx = path . indexOf ( "://" ) ; if ( idx !== - 1 ) { return idx + "://" . length ; } return 0 ; }


Input: average async stat takes about 30 microseconds set chunk size to do 30 files in < 1 millisecond [CODESPLIT] function createWatchedFileSet ( interval , chunkSize ) { if ( interval === void 0 ) { interval = 2500 ; } if ( chunkSize === void 0 ) { chunkSize = 30 ; } var watchedFiles = [ ] ; var nextFileToCheck = 0 ; var watchTimer ; function getModifiedTime ( fileName ) { return _fs . statSync ( fileName ) . mtime ; } function poll ( checkedIndex ) { var watchedFile = watchedFiles [ checkedIndex ] ; if ( ! watchedFile ) { return ; } _fs . stat ( watchedFile . fileName , function ( err , stats ) { if ( err ) { watchedFile . callback ( watchedFile . fileName ) ; } else if ( watchedFile . mtime . getTime ( ) !== stats . mtime . getTime ( ) ) { watchedFile . mtime = getModifiedTime ( watchedFile . fileName ) ; watchedFile . callback ( watchedFile . fileName , watchedFile . mtime . getTime ( ) === 0 ) ; } } ) ; } // this implementation uses polling and // stat due to inconsistencies of fs.watch // and efficiency of stat on modern filesystems function startWatchTimer ( ) { watchTimer = setInterval ( function ( ) { var count = 0 ; var nextToCheck = nextFileToCheck ; var firstCheck = - 1 ; while ( ( count < chunkSize ) && ( nextToCheck !== firstCheck ) ) { poll ( nextToCheck ) ; if ( firstCheck < 0 ) { firstCheck = nextToCheck ; } nextToCheck ++ ; if ( nextToCheck === watchedFiles . length ) { nextToCheck = 0 ; } count ++ ; } nextFileToCheck = nextToCheck ; } , interval ) ; } function addFile ( fileName , callback ) { var file = { fileName : fileName , callback : callback , mtime : getModifiedTime ( fileName ) } ; watchedFiles . push ( file ) ; if ( watchedFiles . length === 1 ) { startWatchTimer ( ) ; } return file ; } function removeFile ( file ) { watchedFiles = ts . copyListRemovingItem ( file , watchedFiles ) ; } return { getModifiedTime : getModifiedTime , poll : poll , startWatchTimer : startWatchTimer , addFile : addFile , removeFile : removeFile } ; }


Input: this implementation uses polling and stat due to inconsistencies of fs . watch and efficiency of stat on modern filesystems [CODESPLIT] function startWatchTimer ( ) { watchTimer = setInterval ( function ( ) { var count = 0 ; var nextToCheck = nextFileToCheck ; var firstCheck = - 1 ; while ( ( count < chunkSize ) && ( nextToCheck !== firstCheck ) ) { poll ( nextToCheck ) ; if ( firstCheck < 0 ) { firstCheck = nextToCheck ; } nextToCheck ++ ; if ( nextToCheck === watchedFiles . length ) { nextToCheck = 0 ; } count ++ ; } nextFileToCheck = nextToCheck ; } , interval ) ; }


Input: / * [CODESPLIT] function isUnicodeIdentifierStart ( code , languageVersion ) { return languageVersion >= 1 /* ES5 */ ? lookupInUnicodeMap ( code , unicodeES5IdentifierStart ) : lookupInUnicodeMap ( code , unicodeES3IdentifierStart ) ; }


Input: / * [CODESPLIT] function computeLineStarts ( text ) { var result = new Array ( ) ; var pos = 0 ; var lineStart = 0 ; while ( pos < text . length ) { var ch = text . charCodeAt ( pos ++ ) ; switch ( ch ) { case 13 /* carriageReturn */ : if ( text . charCodeAt ( pos ) === 10 /* lineFeed */ ) { pos ++ ; } case 10 /* lineFeed */ : result . push ( lineStart ) ; lineStart = pos ; break ; default : if ( ch > 127 /* maxAsciiCharacter */ && isLineBreak ( ch ) ) { result . push ( lineStart ) ; lineStart = pos ; } break ; } } result . push ( lineStart ) ; return result ; }


Input: / * [CODESPLIT] function computePositionOfLineAndCharacter ( lineStarts , line , character ) { ts . Debug . assert ( line >= 0 && line < lineStarts . length ) ; return lineStarts [ line ] + character ; }


Input: / * [CODESPLIT] function computeLineAndCharacterOfPosition ( lineStarts , position ) { var lineNumber = ts . binarySearch ( lineStarts , position ) ; if ( lineNumber < 0 ) { // If the actual position was not found, // the binary search returns the 2's-complement of the next line start // e.g. if the line starts at [5, 10, 23, 80] and the position requested was 20 // then the search will return -2. // // We want the index of the previous line start, so we subtract 1. // Review 2's-complement if this is confusing. lineNumber = ~ lineNumber - 1 ; ts . Debug . assert ( lineNumber !== - 1 , "position cannot precede the beginning of the file" ) ; } return { line : lineNumber , character : position - lineStarts [ lineNumber ] } ; }


Input:
Creates a scanner over a ( possibly unspecified ) range of a piece of text . [CODESPLIT] function createScanner ( languageVersion , skipTrivia , languageVariant , text , onError , start , length ) { if ( languageVariant === void 0 ) { languageVariant = 0 /* Standard */ ; } // Current position (end position of text of current token) var pos ; // end of text var end ; // Start position of whitespace before current token var startPos ; // Start position of text of current token var tokenPos ; var token ; var tokenValue ; var precedingLineBreak ; var hasExtendedUnicodeEscape ; var tokenIsUnterminated ; setText ( text , start , length ) ; return { getStartPos : function ( ) { return startPos ; } , getTextPos : function ( ) { return pos ; } , getToken : function ( ) { return token ; } , getTokenPos : function ( ) { return tokenPos ; } , getTokenText : function ( ) { return text . substring ( tokenPos , pos ) ; } , getTokenValue : function ( ) { return tokenValue ; } , hasExtendedUnicodeEscape : function ( ) { return hasExtendedUnicodeEscape ; } , hasPrecedingLineBreak : function ( ) { return precedingLineBreak ; } , isIdentifier : function ( ) { return token === 69 /* Identifier */ || token > 105 /* LastReservedWord */ ; } , isReservedWord : function ( ) { return token >= 70 /* FirstReservedWord */ && token <= 105 /* LastReservedWord */ ; } , isUnterminated : function ( ) { return tokenIsUnterminated ; } , reScanGreaterToken : reScanGreaterToken , reScanSlashToken : reScanSlashToken , reScanTemplateToken : reScanTemplateToken , scanJsxIdentifier : scanJsxIdentifier , reScanJsxToken : reScanJsxToken , scanJsxToken : scanJsxToken , scan : scan , setText : setText , setScriptTarget : setScriptTarget , setLanguageVariant : setLanguageVariant , setOnError : setOnError , setTextPos : setTextPos , tryScan : tryScan , lookAhead : lookAhead } ; function error ( message , length ) { if ( onError ) { onError ( message , length || 0 ) ; } } function scanNumber ( ) { var start = pos ; while ( isDigit ( text . charCodeAt ( pos ) ) ) pos ++ ; if ( text . charCodeAt ( pos ) === 46 /* dot */ ) { pos ++ ; while ( isDigit ( text . charCodeAt ( pos ) ) ) pos ++ ; } var end = pos ; if ( text . charCodeAt ( pos ) === 69 /* E */ || text . charCodeAt ( pos ) === 101 /* e */ ) { pos ++ ; if ( text . charCodeAt ( pos ) === 43 /* plus */ || text . charCodeAt ( pos ) === 45 /* minus */ ) pos ++ ; if ( isDigit ( text . charCodeAt ( pos ) ) ) { pos ++ ; while ( isDigit ( text . charCodeAt ( pos ) ) ) pos ++ ; end = pos ; } else { error ( ts . Diagnostics . Digit_expected ) ; } } return + ( text . substring ( start , end ) ) ; } function scanOctalDigits ( ) { var start = pos ; while ( isOctalDigit ( text . charCodeAt ( pos ) ) ) { pos ++ ; } return + ( text . substring ( start , pos ) ) ; } /**
         * Scans the given number of hexadecimal digits in the text,
         * returning -1 if the given number is unavailable.
         */ function scanExactNumberOfHexDigits ( count ) { return scanHexDigits ( /*minCount*/ count , /*scanAsManyAsPossible*/ false ) ; } /**
         * Scans as many hexadecimal digits as are available in the text,
         * returning -1 if the given number of digits was unavailable.
         */ function scanMinimumNumberOfHexDigits ( count ) { return scanHexDigits ( /*minCount*/ count , /*scanAsManyAsPossible*/ true ) ; } function scanHexDigits ( minCount , scanAsManyAsPossible ) { var digits = 0 ; var value = 0 ; while ( digits < minCount || scanAsManyAsPossible ) { var ch = text . charCodeAt ( pos ) ; if ( ch >= 48 /* _0 */ && ch <= 57 /* _9 */ ) { value = value * 16 + ch - 48 /* _0 */ ; } else if ( ch >= 65 /* A */ && ch <= 70 /* F */ ) { value = value * 16 + ch - 65 /* A */ + 10 ; } else if ( ch >= 97 /* a */ && ch <= 102 /* f */ ) { value = value * 16 + ch - 97 /* a */ + 10 ; } else { break ; } pos ++ ; digits ++ ; } if ( digits < minCount ) { value = - 1 ; } return value ; } function scanString ( ) { var quote = text . charCodeAt ( pos ++ ) ; var result = "" ; var start = pos ; while ( true ) { if ( pos >= end ) { result += text . substring ( start , pos ) ; tokenIsUnterminated = true ; error ( ts . Diagnostics . Unterminated_string_literal ) ; break ; } var ch = text . charCodeAt ( pos ) ; if ( ch === quote ) { result += text . substring ( start , pos ) ; pos ++ ; break ; } if ( ch === 92 /* backslash */ ) { result += text . substring ( start , pos ) ; result += scanEscapeSequence ( ) ; start = pos ; continue ; } if ( isLineBreak ( ch ) ) { result += text . substring ( start , pos ) ; tokenIsUnterminated = true ; error ( ts . Diagnostics . Unterminated_string_literal ) ; break ; } pos ++ ; } return result ; } /**
         * Sets the current 'tokenValue' and returns a NoSubstitutionTemplateLiteral or
         * a literal component of a TemplateExpression.
         */ function scanTemplateAndSetTokenValue ( ) { var startedWithBacktick = text . charCodeAt ( pos ) === 96 /* backtick */ ; pos ++ ; var start = pos ; var contents = "" ; var resultingToken ; while ( true ) { if ( pos >= end ) { contents += text . substring ( start , pos ) ; tokenIsUnterminated = true ; error ( ts . Diagnostics . Unterminated_template_literal ) ; resultingToken = startedWithBacktick ? 11 /* NoSubstitutionTemplateLiteral */ : 14 /* TemplateTail */ ; break ; } var currChar = text . charCodeAt ( pos ) ; // '`' if ( currChar === 96 /* backtick */ ) { contents += text . substring ( start , pos ) ; pos ++ ; resultingToken = startedWithBacktick ? 11 /* NoSubstitutionTemplateLiteral */ : 14 /* TemplateTail */ ; break ; } // '${' if ( currChar === 36 /* $ */ && pos + 1 < end && text . charCodeAt ( pos + 1 ) === 123 /* openBrace */ ) { contents += text . substring ( start , pos ) ; pos += 2 ; resultingToken = startedWithBacktick ? 12 /* TemplateHead */ : 13 /* TemplateMiddle */ ; break ; } // Escape character if ( currChar === 92 /* backslash */ ) { contents += text . substring ( start , pos ) ; contents += scanEscapeSequence ( ) ; start = pos ; continue ; } // Speculated ECMAScript 6 Spec 11.8.6.1: // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for Template Values if ( currChar === 13 /* carriageReturn */ ) { contents += text . substring ( start , pos ) ; pos ++ ; if ( pos < end && text . charCodeAt ( pos ) === 10 /* lineFeed */ ) { pos ++ ; } contents += "\n" ; start = pos ; continue ; } pos ++ ; } ts . Debug . assert ( resultingToken !== undefined ) ; tokenValue = contents ; return resultingToken ; } function scanEscapeSequence ( ) { pos ++ ; if ( pos >= end ) { error ( ts . Diagnostics . Unexpected_end_of_text ) ; return "" ; } var ch = text . charCodeAt ( pos ++ ) ; switch ( ch ) { case 48 /* _0 */ : return "\0" ; case 98 /* b */ : return "\b" ; case 116 /* t */ : return "\t" ; case 110 /* n */ : return "\n" ; case 118 /* v */ : return "\v" ; case 102 /* f */ : return "\f" ; case 114 /* r */ : return "\r" ; case 39 /* singleQuote */ : return "\'" ; case 34 /* doubleQuote */ : return "\"" ; case 117 /* u */ : // '\u{DDDDDDDD}' if ( pos < end && text . charCodeAt ( pos ) === 123 /* openBrace */ ) { hasExtendedUnicodeEscape = true ; pos ++ ; return scanExtendedUnicodeEscape ( ) ; } // '\uDDDD' return scanHexadecimalEscape ( /*numDigits*/ 4 ) ; case 120 /* x */ : // '\xDD' return scanHexadecimalEscape ( /*numDigits*/ 2 ) ; // when encountering a LineContinuation (i.e. a backslash and a line terminator sequence), // the line terminator is interpreted to be "the empty code unit sequence". case 13 /* carriageReturn */ : if ( pos < end && text . charCodeAt ( pos ) === 10 /* lineFeed */ ) { pos ++ ; } // fall through case 10 /* lineFeed */ : case 8232 /* lineSeparator */ : case 8233 /* paragraphSeparator */ : return "" ; default : return String . fromCharCode ( ch ) ; } } function scanHexadecimalEscape ( numDigits ) { var escapedValue = scanExactNumberOfHexDigits ( numDigits ) ; if ( escapedValue >= 0 ) { return String . fromCharCode ( escapedValue ) ; } else { error ( ts . Diagnostics . Hexadecimal_digit_expected ) ; return "" ; } } function scanExtendedUnicodeEscape ( ) { var escapedValue = scanMinimumNumberOfHexDigits ( 1 ) ; var isInvalidExtendedEscape = false ; // Validate the value of the digit if ( escapedValue < 0 ) { error ( ts . Diagnostics . Hexadecimal_digit_expected ) ; isInvalidExtendedEscape = true ; } else if ( escapedValue > 0x10FFFF ) { error ( ts . Diagnostics . An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive ) ; isInvalidExtendedEscape = true ; } if ( pos >= end ) { error ( ts . Diagnostics . Unexpected_end_of_text ) ; isInvalidExtendedEscape = true ; } else if ( text . charCodeAt ( pos ) === 125 /* closeBrace */ ) { // Only swallow the following character up if it's a '}'. pos ++ ; } else { error ( ts . Diagnostics . Unterminated_Unicode_escape_sequence ) ; isInvalidExtendedEscape = true ; } if ( isInvalidExtendedEscape ) { return "" ; } return utf16EncodeAsString ( escapedValue ) ; } // Derived from the 10.1.1 UTF16Encoding of the ES6 Spec. function utf16EncodeAsString ( codePoint ) { ts . Debug . assert ( 0x0 <= codePoint && codePoint <= 0x10FFFF ) ; if ( codePoint <= 65535 ) { return String . fromCharCode ( codePoint ) ; } var codeUnit1 = Math . floor ( ( codePoint - 65536 ) / 1024 ) + 0xD800 ; var codeUnit2 = ( ( codePoint - 65536 ) % 1024 ) + 0xDC00 ; return String . fromCharCode ( codeUnit1 , codeUnit2 ) ; } // Current character is known to be a backslash. Check for Unicode escape of the form '\uXXXX' // and return code point value if valid Unicode escape is found. Otherwise return -1. function peekUnicodeEscape ( ) { if ( pos + 5 < end && text . charCodeAt ( pos + 1 ) === 117 /* u */ ) { var start_1 = pos ; pos += 2 ; var value = scanExactNumberOfHexDigits ( 4 ) ; pos = start_1 ; return value ; } return - 1 ; } function scanIdentifierParts ( ) { var result = "" ; var start = pos ; while ( pos < end ) { var ch = text . charCodeAt ( pos ) ; if ( isIdentifierPart ( ch , languageVersion ) ) { pos ++ ; } else if ( ch === 92 /* backslash */ ) { ch = peekUnicodeEscape ( ) ; if ( ! ( ch >= 0 && isIdentifierPart ( ch , languageVersion ) ) ) { break ; } result += text . substring ( start , pos ) ; result += String . fromCharCode ( ch ) ; // Valid Unicode escape is always six characters pos += 6 ; start = pos ; } else { break ; } } result += text . substring ( start , pos ) ; return result ; } function getIdentifierToken ( ) { // Reserved words are between 2 and 11 characters long and start with a lowercase letter var len = tokenValue . length ; if ( len >= 2 && len <= 11 ) { var ch = tokenValue . charCodeAt ( 0 ) ; if ( ch >= 97 /* a */ && ch <= 122 /* z */ && hasOwnProperty . call ( textToToken , tokenValue ) ) { return token = textToToken [ tokenValue ] ; } } return token = 69 /* Identifier */ ; } function scanBinaryOrOctalDigits ( base ) { ts . Debug . assert ( base !== 2 || base !== 8 , "Expected either base 2 or base 8" ) ; var value = 0 ; // For counting number of digits; Valid binaryIntegerLiteral must have at least one binary digit following B or b. // Similarly valid octalIntegerLiteral must have at least one octal digit following o or O. var numberOfDigits = 0 ; while ( true ) { var ch = text . charCodeAt ( pos ) ; var valueOfCh = ch - 48 /* _0 */ ; if ( ! isDigit ( ch ) || valueOfCh >= base ) { break ; } value = value * base + valueOfCh ; pos ++ ; numberOfDigits ++ ; } // Invalid binaryIntegerLiteral or octalIntegerLiteral if ( numberOfDigits === 0 ) { return - 1 ; } return value ; } function scan ( ) { startPos = pos ; hasExtendedUnicodeEscape = false ; precedingLineBreak = false ; tokenIsUnterminated = false ; while ( true ) { tokenPos = pos ; if ( pos >= end ) { return token = 1 /* EndOfFileToken */ ; } var ch = text . charCodeAt ( pos ) ; // Special handling for shebang if ( ch === 35 /* hash */ && pos === 0 && isShebangTrivia ( text , pos ) ) { pos = scanShebangTrivia ( text , pos ) ; if ( skipTrivia ) { continue ; } else { return token = 6 /* ShebangTrivia */ ; } } switch ( ch ) { case 10 /* lineFeed */ : case 13 /* carriageReturn */ : precedingLineBreak = true ; if ( skipTrivia ) { pos ++ ; continue ; } else { if ( ch === 13 /* carriageReturn */ && pos + 1 < end && text . charCodeAt ( pos + 1 ) === 10 /* lineFeed */ ) { // consume both CR and LF pos += 2 ; } else { pos ++ ; } return token = 4 /* NewLineTrivia */ ; } case 9 /* tab */ : case 11 /* verticalTab */ : case 12 /* formFeed */ : case 32 /* space */ : if ( skipTrivia ) { pos ++ ; continue ; } else { while ( pos < end && isWhiteSpace ( text . charCodeAt ( pos ) ) ) { pos ++ ; } return token = 5 /* WhitespaceTrivia */ ; } case 33 /* exclamation */ : if ( text . charCodeAt ( pos + 1 ) === 61 /* equals */ ) { if ( text . charCodeAt ( pos + 2 ) === 61 /* equals */ ) { return pos += 3 , token = 33 /* ExclamationEqualsEqualsToken */ ; } return pos += 2 , token = 31 /* ExclamationEqualsToken */ ; } return pos ++ , token = 49 /* ExclamationToken */ ; case 34 /* doubleQuote */ : case 39 /* singleQuote */ : tokenValue = scanString ( ) ; return token = 9 /* StringLiteral */ ; case 96 /* backtick */ : return token = scanTemplateAndSetTokenValue ( ) ; case 37 /* percent */ : if ( text . charCodeAt ( pos + 1 ) === 61 /* equals */ ) { return pos += 2 , token = 62 /* PercentEqualsToken */ ; } return pos ++ , token = 40 /* PercentToken */ ; case 38 /* ampersand */ : if ( text . charCodeAt ( pos + 1 ) === 38 /* ampersand */ ) { return pos += 2 , token = 51 /* AmpersandAmpersandToken */ ; } if ( text . charCodeAt ( pos + 1 ) === 61 /* equals */ ) { return pos += 2 , token = 66 /* AmpersandEqualsToken */ ; } return pos ++ , token = 46 /* AmpersandToken */ ; case 40 /* openParen */ : return pos ++ , token = 17 /* OpenParenToken */ ; case 41 /* closeParen */ : return pos ++ , token = 18 /* CloseParenToken */ ; case 42 /* asterisk */ : if ( text . charCodeAt ( pos + 1 ) === 61 /* equals */ ) { return pos += 2 , token = 59 /* AsteriskEqualsToken */ ; } if ( text . charCodeAt ( pos + 1 ) === 42 /* asterisk */ ) { if ( text . charCodeAt ( pos + 2 ) === 61 /* equals */ ) { return pos += 3 , token = 60 /* AsteriskAsteriskEqualsToken */ ; } return pos += 2 , token = 38 /* AsteriskAsteriskToken */ ; } return pos ++ , token = 37 /* AsteriskToken */ ; case 43 /* plus */ : if ( text . charCodeAt ( pos + 1 ) === 43 /* plus */ ) { return pos += 2 , token = 41 /* PlusPlusToken */ ; } if ( text . charCodeAt ( pos + 1 ) === 61 /* equals */ ) { return pos += 2 , token = 57 /* PlusEqualsToken */ ; } return pos ++ , token = 35 /* PlusToken */ ; case 44 /* comma */ : return pos ++ , token = 24 /* CommaToken */ ; case 45 /* minus */ : if ( text . charCodeAt ( pos + 1 ) === 45 /* minus */ ) { return pos += 2 , token = 42 /* MinusMinusToken */ ; } if ( text . charCodeAt ( pos + 1 ) === 61 /* equals */ ) { return pos += 2 , token = 58 /* MinusEqualsToken */ ; } return pos ++ , token = 36 /* MinusToken */ ; case 46 /* dot */ : if ( isDigit ( text . charCodeAt ( pos + 1 ) ) ) { tokenValue = "" + scanNumber ( ) ; return token = 8 /* NumericLiteral */ ; } if ( text . charCodeAt ( pos + 1 ) === 46 /* dot */ && text . charCodeAt ( pos + 2 ) === 46 /* dot */ ) { return pos += 3 , token = 22 /* DotDotDotToken */ ; } return pos ++ , token = 21 /* DotToken */ ; case 47 /* slash */ : // Single-line comment if ( text . charCodeAt ( pos + 1 ) === 47 /* slash */ ) { pos += 2 ; while ( pos < end ) { if ( isLineBreak ( text . charCodeAt ( pos ) ) ) { break ; } pos ++ ; } if ( skipTrivia ) { continue ; } else { return token = 2 /* SingleLineCommentTrivia */ ; } } // Multi-line comment if ( text . charCodeAt ( pos + 1 ) === 42 /* asterisk */ ) { pos += 2 ; var commentClosed = false ; while ( pos < end ) { var ch_2 = text . charCodeAt ( pos ) ; if ( ch_2 === 42 /* asterisk */ && text . charCodeAt ( pos + 1 ) === 47 /* slash */ ) { pos += 2 ; commentClosed = true ; break ; } if ( isLineBreak ( ch_2 ) ) { precedingLineBreak = true ; } pos ++ ; } if ( ! commentClosed ) { error ( ts . Diagnostics . Asterisk_Slash_expected ) ; } if ( skipTrivia ) { continue ; } else { tokenIsUnterminated = ! commentClosed ; return token = 3 /* MultiLineCommentTrivia */ ; } } if ( text . charCodeAt ( pos + 1 ) === 61 /* equals */ ) { return pos += 2 , token = 61 /* SlashEqualsToken */ ; } return pos ++ , token = 39 /* SlashToken */ ; case 48 /* _0 */ : if ( pos + 2 < end && ( text . charCodeAt ( pos + 1 ) === 88 /* X */ || text . charCodeAt ( pos + 1 ) === 120 /* x */ ) ) { pos += 2 ; var value = scanMinimumNumberOfHexDigits ( 1 ) ; if ( value < 0 ) { error ( ts . Diagnostics . Hexadecimal_digit_expected ) ; value = 0 ; } tokenValue = "" + value ; return token = 8 /* NumericLiteral */ ; } else if ( pos + 2 < end && ( text . charCodeAt ( pos + 1 ) === 66 /* B */ || text . charCodeAt ( pos + 1 ) === 98 /* b */ ) ) { pos += 2 ; var value = scanBinaryOrOctalDigits ( /* base */ 2 ) ; if ( value < 0 ) { error ( ts . Diagnostics . Binary_digit_expected ) ; value = 0 ; } tokenValue = "" + value ; return token = 8 /* NumericLiteral */ ; } else if ( pos + 2 < end && ( text . charCodeAt ( pos + 1 ) === 79 /* O */ || text . charCodeAt ( pos + 1 ) === 111 /* o */ ) ) { pos += 2 ; var value = scanBinaryOrOctalDigits ( /* base */ 8 ) ; if ( value < 0 ) { error ( ts . Diagnostics . Octal_digit_expected ) ; value = 0 ; } tokenValue = "" + value ; return token = 8 /* NumericLiteral */ ; } // Try to parse as an octal if ( pos + 1 < end && isOctalDigit ( text . charCodeAt ( pos + 1 ) ) ) { tokenValue = "" + scanOctalDigits ( ) ; return token = 8 /* NumericLiteral */ ; } // This fall-through is a deviation from the EcmaScript grammar. The grammar says that a leading zero // can only be followed by an octal digit, a dot, or the end of the number literal. However, we are being // permissive and allowing decimal digits of the form 08* and 09* (which many browsers also do). case 49 /* _1 */ : case 50 /* _2 */ : case 51 /* _3 */ : case 52 /* _4 */ : case 53 /* _5 */ : case 54 /* _6 */ : case 55 /* _7 */ : case 56 /* _8 */ : case 57 /* _9 */ : tokenValue = "" + scanNumber ( ) ; return token = 8 /* NumericLiteral */ ; case 58 /* colon */ : return pos ++ , token = 54 /* ColonToken */ ; case 59 /* semicolon */ : return pos ++ , token = 23 /* SemicolonToken */ ; case 60 /* lessThan */ : if ( isConflictMarkerTrivia ( text , pos ) ) { pos = scanConflictMarkerTrivia ( text , pos , error ) ; if ( skipTrivia ) { continue ; } else { return token = 7 /* ConflictMarkerTrivia */ ; } } if ( text . charCodeAt ( pos + 1 ) === 60 /* lessThan */ ) { if ( text . charCodeAt ( pos + 2 ) === 61 /* equals */ ) { return pos += 3 , token = 63 /* LessThanLessThanEqualsToken */ ; } return pos += 2 , token = 43 /* LessThanLessThanToken */ ; } if ( text . charCodeAt ( pos + 1 ) === 61 /* equals */ ) { return pos += 2 , token = 28 /* LessThanEqualsToken */ ; } if ( languageVariant === 1 /* JSX */ && text . charCodeAt ( pos + 1 ) === 47 /* slash */ && text . charCodeAt ( pos + 2 ) !== 42 /* asterisk */ ) { return pos += 2 , token = 26 /* LessThanSlashToken */ ; } return pos ++ , token = 25 /* LessThanToken */ ; case 61 /* equals */ : if ( isConflictMarkerTrivia ( text , pos ) ) { pos = scanConflictMarkerTrivia ( text , pos , error ) ; if ( skipTrivia ) { continue ; } else { return token = 7 /* ConflictMarkerTrivia */ ; } } if ( text . charCodeAt ( pos + 1 ) === 61 /* equals */ ) { if ( text . charCodeAt ( pos + 2 ) === 61 /* equals */ ) { return pos += 3 , token = 32 /* EqualsEqualsEqualsToken */ ; } return pos += 2 , token = 30 /* EqualsEqualsToken */ ; } if ( text . charCodeAt ( pos + 1 ) === 62 /* greaterThan */ ) { return pos += 2 , token = 34 /* EqualsGreaterThanToken */ ; } return pos ++ , token = 56 /* EqualsToken */ ; case 62 /* greaterThan */ : if ( isConflictMarkerTrivia ( text , pos ) ) { pos = scanConflictMarkerTrivia ( text , pos , error ) ; if ( skipTrivia ) { continue ; } else { return token = 7 /* ConflictMarkerTrivia */ ; } } return pos ++ , token = 27 /* GreaterThanToken */ ; case 63 /* question */ : return pos ++ , token = 53 /* QuestionToken */ ; case 91 /* openBracket */ : return pos ++ , token = 19 /* OpenBracketToken */ ; case 93 /* closeBracket */ : return pos ++ , token = 20 /* CloseBracketToken */ ; case 94 /* caret */ : if ( text . charCodeAt ( pos + 1 ) === 61 /* equals */ ) { return pos += 2 , token = 68 /* CaretEqualsToken */ ; } return pos ++ , token = 48 /* CaretToken */ ; case 123 /* openBrace */ : return pos ++ , token = 15 /* OpenBraceToken */ ; case 124 /* bar */ : if ( text . charCodeAt ( pos + 1 ) === 124 /* bar */ ) { return pos += 2 , token = 52 /* BarBarToken */ ; } if ( text . charCodeAt ( pos + 1 ) === 61 /* equals */ ) { return pos += 2 , token = 67 /* BarEqualsToken */ ; } return pos ++ , token = 47 /* BarToken */ ; case 125 /* closeBrace */ : return pos ++ , token = 16 /* CloseBraceToken */ ; case 126 /* tilde */ : return pos ++ , token = 50 /* TildeToken */ ; case 64 /* at */ : return pos ++ , token = 55 /* AtToken */ ; case 92 /* backslash */ : var cookedChar = peekUnicodeEscape ( ) ; if ( cookedChar >= 0 && isIdentifierStart ( cookedChar , languageVersion ) ) { pos += 6 ; tokenValue = String . fromCharCode ( cookedChar ) + scanIdentifierParts ( ) ; return token = getIdentifierToken ( ) ; } error ( ts . Diagnostics . Invalid_character ) ; return pos ++ , token = 0 /* Unknown */ ; default : if ( isIdentifierStart ( ch , languageVersion ) ) { pos ++ ; while ( pos < end && isIdentifierPart ( ch = text . charCodeAt ( pos ) , languageVersion ) ) pos ++ ; tokenValue = text . substring ( tokenPos , pos ) ; if ( ch === 92 /* backslash */ ) { tokenValue += scanIdentifierParts ( ) ; } return token = getIdentifierToken ( ) ; } else if ( isWhiteSpace ( ch ) ) { pos ++ ; continue ; } else if ( isLineBreak ( ch ) ) { precedingLineBreak = true ; pos ++ ; continue ; } error ( ts . Diagnostics . Invalid_character ) ; return pos ++ , token = 0 /* Unknown */ ; } } } function reScanGreaterToken ( ) { if ( token === 27 /* GreaterThanToken */ ) { if ( text . charCodeAt ( pos ) === 62 /* greaterThan */ ) { if ( text . charCodeAt ( pos + 1 ) === 62 /* greaterThan */ ) { if ( text . charCodeAt ( pos + 2 ) === 61 /* equals */ ) { return pos += 3 , token = 65 /* GreaterThanGreaterThanGreaterThanEqualsToken */ ; } return pos += 2 , token = 45 /* GreaterThanGreaterThanGreaterThanToken */ ; } if ( text . charCodeAt ( pos + 1 ) === 61 /* equals */ ) { return pos += 2 , token = 64 /* GreaterThanGreaterThanEqualsToken */ ; } return pos ++ , token = 44 /* GreaterThanGreaterThanToken */ ; } if ( text . charCodeAt ( pos ) === 61 /* equals */ ) { return pos ++ , token = 29 /* GreaterThanEqualsToken */ ; } } return token ; } function reScanSlashToken ( ) { if ( token === 39 /* SlashToken */ || token === 61 /* SlashEqualsToken */ ) { var p = tokenPos + 1 ; var inEscape = false ; var inCharacterClass = false ; while ( true ) { // If we reach the end of a file, or hit a newline, then this is an unterminated // regex.  Report error and return what we have so far. if ( p >= end ) { tokenIsUnterminated = true ; error ( ts . Diagnostics . Unterminated_regular_expression_literal ) ; break ; } var ch = text . charCodeAt ( p ) ; if ( isLineBreak ( ch ) ) { tokenIsUnterminated = true ; error ( ts . Diagnostics . Unterminated_regular_expression_literal ) ; break ; } if ( inEscape ) { // Parsing an escape character; // reset the flag and just advance to the next char. inEscape = false ; } else if ( ch === 47 /* slash */ && ! inCharacterClass ) { // A slash within a character class is permissible, // but in general it signals the end of the regexp literal. p ++ ; break ; } else if ( ch === 91 /* openBracket */ ) { inCharacterClass = true ; } else if ( ch === 92 /* backslash */ ) { inEscape = true ; } else if ( ch === 93 /* closeBracket */ ) { inCharacterClass = false ; } p ++ ; } while ( p < end && isIdentifierPart ( text . charCodeAt ( p ) , languageVersion ) ) { p ++ ; } pos = p ; tokenValue = text . substring ( tokenPos , pos ) ; token = 10 /* RegularExpressionLiteral */ ; } return token ; } /**
         * Unconditionally back up and scan a template expression portion.
         */ function reScanTemplateToken ( ) { ts . Debug . assert ( token === 16 /* CloseBraceToken */ , "'reScanTemplateToken' should only be called on a '}'" ) ; pos = tokenPos ; return token = scanTemplateAndSetTokenValue ( ) ; } function reScanJsxToken ( ) { pos = tokenPos = startPos ; return token = scanJsxToken ( ) ; } function scanJsxToken ( ) { startPos = tokenPos = pos ; if ( pos >= end ) { return token = 1 /* EndOfFileToken */ ; } var char = text . charCodeAt ( pos ) ; if ( char === 60 /* lessThan */ ) { if ( text . charCodeAt ( pos + 1 ) === 47 /* slash */ ) { pos += 2 ; return token = 26 /* LessThanSlashToken */ ; } pos ++ ; return token = 25 /* LessThanToken */ ; } if ( char === 123 /* openBrace */ ) { pos ++ ; return token = 15 /* OpenBraceToken */ ; } while ( pos < end ) { pos ++ ; char = text . charCodeAt ( pos ) ; if ( ( char === 123 /* openBrace */ ) || ( char === 60 /* lessThan */ ) ) { break ; } } return token = 236 /* JsxText */ ; } // Scans a JSX identifier; these differ from normal identifiers in that // they allow dashes function scanJsxIdentifier ( ) { if ( tokenIsIdentifierOrKeyword ( token ) ) { var firstCharPosition = pos ; while ( pos < end ) { var ch = text . charCodeAt ( pos ) ; if ( ch === 45 /* minus */ || ( ( firstCharPosition === pos ) ? isIdentifierStart ( ch , languageVersion ) : isIdentifierPart ( ch , languageVersion ) ) ) { pos ++ ; } else { break ; } } tokenValue += text . substr ( firstCharPosition , pos - firstCharPosition ) ; } return token ; } function speculationHelper ( callback , isLookahead ) { var savePos = pos ; var saveStartPos = startPos ; var saveTokenPos = tokenPos ; var saveToken = token ; var saveTokenValue = tokenValue ; var savePrecedingLineBreak = precedingLineBreak ; var result = callback ( ) ; // If our callback returned something 'falsy' or we're just looking ahead, // then unconditionally restore us to where we were. if ( ! result || isLookahead ) { pos = savePos ; startPos = saveStartPos ; tokenPos = saveTokenPos ; token = saveToken ; tokenValue = saveTokenValue ; precedingLineBreak = savePrecedingLineBreak ; } return result ; } function lookAhead ( callback ) { return speculationHelper ( callback , /*isLookahead:*/ true ) ; } function tryScan ( callback ) { return speculationHelper ( callback , /*isLookahead:*/ false ) ; } function setText ( newText , start , length ) { text = newText || "" ; end = length === undefined ? text . length : start + length ; setTextPos ( start || 0 ) ; } function setOnError ( errorCallback ) { onError = errorCallback ; } function setScriptTarget ( scriptTarget ) { languageVersion = scriptTarget ; } function setLanguageVariant ( variant ) { languageVariant = variant ; } function setTextPos ( textPos ) { ts . Debug . assert ( textPos >= 0 ) ; pos = textPos ; startPos = textPos ; tokenPos = textPos ; token = 0 /* Unknown */ ; precedingLineBreak = false ; tokenValue = undefined ; hasExtendedUnicodeEscape = false ; tokenIsUnterminated = false ; } }


Input: Sets the current tokenValue and returns a NoSubstitutionTemplateLiteral or a literal component of a TemplateExpression . [CODESPLIT] function scanTemplateAndSetTokenValue ( ) { var startedWithBacktick = text . charCodeAt ( pos ) === 96 /* backtick */ ; pos ++ ; var start = pos ; var contents = "" ; var resultingToken ; while ( true ) { if ( pos >= end ) { contents += text . substring ( start , pos ) ; tokenIsUnterminated = true ; error ( ts . Diagnostics . Unterminated_template_literal ) ; resultingToken = startedWithBacktick ? 11 /* NoSubstitutionTemplateLiteral */ : 14 /* TemplateTail */ ; break ; } var currChar = text . charCodeAt ( pos ) ; // '`' if ( currChar === 96 /* backtick */ ) { contents += text . substring ( start , pos ) ; pos ++ ; resultingToken = startedWithBacktick ? 11 /* NoSubstitutionTemplateLiteral */ : 14 /* TemplateTail */ ; break ; } // '${' if ( currChar === 36 /* $ */ && pos + 1 < end && text . charCodeAt ( pos + 1 ) === 123 /* openBrace */ ) { contents += text . substring ( start , pos ) ; pos += 2 ; resultingToken = startedWithBacktick ? 12 /* TemplateHead */ : 13 /* TemplateMiddle */ ; break ; } // Escape character if ( currChar === 92 /* backslash */ ) { contents += text . substring ( start , pos ) ; contents += scanEscapeSequence ( ) ; start = pos ; continue ; } // Speculated ECMAScript 6 Spec 11.8.6.1: // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for Template Values if ( currChar === 13 /* carriageReturn */ ) { contents += text . substring ( start , pos ) ; pos ++ ; if ( pos < end && text . charCodeAt ( pos ) === 10 /* lineFeed */ ) { pos ++ ; } contents += "\n" ; start = pos ; continue ; } pos ++ ; } ts . Debug . assert ( resultingToken !== undefined ) ; tokenValue = contents ; return resultingToken ; }


Input: Derived from the 10 . 1 . 1 UTF16Encoding of the ES6 Spec . [CODESPLIT] function utf16EncodeAsString ( codePoint ) { ts . Debug . assert ( 0x0 <= codePoint && codePoint <= 0x10FFFF ) ; if ( codePoint <= 65535 ) { return String . fromCharCode ( codePoint ) ; } var codeUnit1 = Math . floor ( ( codePoint - 65536 ) / 1024 ) + 0xD800 ; var codeUnit2 = ( ( codePoint - 65536 ) % 1024 ) + 0xDC00 ; return String . fromCharCode ( codeUnit1 , codeUnit2 ) ; }


Input: Current character is known to be a backslash . Check for Unicode escape of the form \ uXXXX and return code point value if valid Unicode escape is found . Otherwise return - 1 . [CODESPLIT] function peekUnicodeEscape ( ) { if ( pos + 5 < end && text . charCodeAt ( pos + 1 ) === 117 /* u */ ) { var start_1 = pos ; pos += 2 ; var value = scanExactNumberOfHexDigits ( 4 ) ; pos = start_1 ; return value ; } return - 1 ; }


Input: Scans a JSX identifier ; these differ from normal identifiers in that they allow dashes [CODESPLIT] function scanJsxIdentifier ( ) { if ( tokenIsIdentifierOrKeyword ( token ) ) { var firstCharPosition = pos ; while ( pos < end ) { var ch = text . charCodeAt ( pos ) ; if ( ch === 45 /* minus */ || ( ( firstCharPosition === pos ) ? isIdentifierStart ( ch , languageVersion ) : isIdentifierPart ( ch , languageVersion ) ) ) { pos ++ ; } else { break ; } } tokenValue += text . substr ( firstCharPosition , pos - firstCharPosition ) ; } return token ; }


Input: Should not be called on a declaration with a computed property name unless it is a well known Symbol . [CODESPLIT] function getDeclarationName ( node ) { if ( node . name ) { if ( node . kind === 218 /* ModuleDeclaration */ && node . name . kind === 9 /* StringLiteral */ ) { return "\"" + node . name . text + "\"" ; } if ( node . name . kind === 136 /* ComputedPropertyName */ ) { var nameExpression = node . name . expression ; ts . Debug . assert ( ts . isWellKnownSymbolSyntactically ( nameExpression ) ) ; return ts . getPropertyNameForKnownSymbolName ( nameExpression . name . text ) ; } return node . name . text ; } switch ( node . kind ) { case 144 /* Constructor */ : return "__constructor" ; case 152 /* FunctionType */ : case 147 /* CallSignature */ : return "__call" ; case 153 /* ConstructorType */ : case 148 /* ConstructSignature */ : return "__new" ; case 149 /* IndexSignature */ : return "__index" ; case 228 /* ExportDeclaration */ : return "__export" ; case 227 /* ExportAssignment */ : return node . isExportEquals ? "export=" : "default" ; case 213 /* FunctionDeclaration */ : case 214 /* ClassDeclaration */ : return node . flags & 1024 /* Default */ ? "default" : undefined ; } }