Input: Creates all the task definition to configure dest based on origin and the opts . [CODESPLIT] function generateConfigureTasks ( planner , origin , dest , opts ) { _ . forIn ( dest . topology . containers , function ( container ) { var addSubTask = { cmd : 'add' , id : container . id , parent : container . containedBy } ; var startSubTask = { cmd : 'start' , id : container . id , parent : container . containedBy } ; var linkSubTask = { cmd : 'link' , id : container . id , parent : container . containedBy } ; var configureOp = { preconditions : containerStatus ( container , 'detached' ) , subTasks : [ addSubTask , startSubTask , linkSubTask ] } ; var configureNop = { preconditions : containerStatus ( container , 'started' ) , subTasks : [ { cmd : 'nop' } ] } ; var addPreconditions = containerStatus ( container , 'detached' ) ; var linkPreconditions = containerStatus ( container , { started : true , running : false } ) ; var oldContainer = origin . topology . containers [ container . id ] ; if ( oldContainer ) { // let's detach all removed containers oldContainer . contains . filter ( function ( contained ) { return container . contains . indexOf ( contained ) === - 1 && ! dest . topology . containers [ contained ] ; } ) . map ( function ( contained ) { // the current contained is NOT included in the dest status // so we detach it return { cmd : 'detach' , id : contained } ; } ) . reduce ( function ( list , op ) { list . push ( op ) ; return list ; } , configureNop . subTasks ) ; } // the children container must be configured before linking container . contains . forEach ( function ( contained ) { var oldContained = origin . topology . containers [ contained ] ; linkPreconditions = _ . merge ( linkPreconditions , containerStatus ( { id : contained , containedBy : container . id } , 'running' ) ) ; // we need to add those before the link if ( oldContained && oldContained . containedBy !== container . id ) { configureOp . subTasks . splice ( configureOp . subTasks . length - 1 , 0 , { cmd : 'detach' , id : contained } ) ; configureNop . subTasks . push ( { cmd : 'detach' , id : contained } ) ; } configureOp . subTasks . splice ( configureOp . subTasks . length - 1 , 0 , { cmd : 'configure' , id : contained } ) ; configureNop . subTasks . push ( { cmd : 'configure' , id : contained } ) ; } ) ; if ( opts . mode === 'safe' && oldContainer && oldContainer . containedBy !== container . containedBy ) { // we should unlink the parent before doing anything // and link back after allParentsIds ( origin , container ) . forEach ( function ( id ) { var op = configureOp ; var nop = configureNop ; op . subTasks . unshift ( { cmd : 'unlink' , id : id , parent : origin . topology . containers [ id ] . containedBy } ) ; nop . subTasks . unshift ( { cmd : 'unlink' , id : id , parent : origin . topology . containers [ id ] . containedBy } ) ; op . subTasks . push ( { cmd : 'link' , id : id , parent : origin . topology . containers [ id ] . containedBy } ) ; nop . subTasks . push ( { cmd : 'link' , id : id , parent : origin . topology . containers [ id ] . containedBy } ) ; } ) ; } if ( opts . mode === 'safe' && configureNop . subTasks . length > 1 && container . containedBy !== container . id ) { configureNop . subTasks . unshift ( { cmd : 'unlink' , id : container . id , parent : container . containedBy } ) ; configureNop . subTasks . push ( { cmd : 'link' , id : container . id , parent : container . containedBy } ) ; } // if a container is already running, there is nothing to do planner . addTask ( { cmd : 'configure' , id : container . id } , configureNop ) ; // real configure task planner . addTask ( { cmd : 'configure' , id : container . id } , configureOp ) ; planner . addTask ( addSubTask , { preconditions : addPreconditions , effects : containerStatus ( container , 'added' ) } ) ; planner . addTask ( startSubTask , { preconditions : containerStatus ( container , 'added' ) , effects : containerStatus ( container , 'started' ) } ) ; planner . addTask ( linkSubTask , { preconditions : containerStatus ( container , 'running' ) , subTasks : [ { cmd : 'nop' } ] } ) ; planner . addTask ( linkSubTask , { preconditions : linkPreconditions , effects : containerStatus ( container , 'running' ) } ) ; } ) ; }


Input: @module lib / allParentsIds Returns all parents of the passed container minus the root . [CODESPLIT] function allParentsIds ( context , container , parents ) { var isLeaf = parents === undefined ; parents = parents || [ ] ; // doing this before pushing skips the root if ( ! container . containedBy || container . containedBy === container . id ) { return parents ; } if ( ! isLeaf ) { parents . push ( container . id ) ; } // let's order them by tree order return allParentsIds ( context , context . topology . containers [ container . containedBy ] , parents ) ; }


Input: Creates a container status to be used as a precondition [CODESPLIT] function containerStatus ( original , status , parent ) { var state = { topology : { containers : { } } } ; var container = { id : original . id } ; if ( parent === null ) { // nothing to do } else if ( parent !== undefined ) { container . containedBy = parent ; } else { container . containedBy = original . containedBy ; } if ( typeof status === 'string' ) { switch ( status ) { case 'detached' : container . added = false ; container . started = false ; container . running = false ; break ; case 'added' : container . added = true ; break ; case 'started' : container . started = true ; break ; case 'running' : container . running = true ; break ; default : throw new Error ( 'unknown state' ) ; } } else { _ . forIn ( status , function ( value , key ) { container [ key ] = value ; } ) ; } if ( container . added === false ) { delete container . containedBy ; } state . topology . containers [ container . id ] = container ; return state ; }


Input: ------------------------------ CONSTRUCTOR ---------------------------------- [CODESPLIT] function ( opt ) { EventEmitter . call ( this ) ; opt = opt || { } ; // the id of the service that the node will provide this . _service = opt . service || 'unnamedService' ; // cluster which the node belongs to this . _cluster = opt . cluster || 'defaultCluster' ; // id of the node this . _id = opt . id || uuid . v4 ( ) ; // port in which the node will be publishing messages this . _pubPort = opt . port ; // if port is not defined, a free one is used // interface in which the node will bind this . _address = opt . address || '0.0.0.0' ; // status flags this . _inCluster = false ; this . _advertising = false ; // used to store information about the other nodes in the cluster this . _clusterTopology = { } ; // pub and sub sockets this . _pub = null ; this . _sub = null ; // mdns advertiser/browser this . _ad = null ; this . _browser = null ; // information that is used to advertise the service this . _adInfo = null ; }


Input: Update information about directory s content with lstat . [CODESPLIT] async function lstatFiles ( dirPath , dirContent ) { const readFiles = dirContent . map ( async ( relativePath ) => { const path = join ( dirPath , relativePath ) const ls = await makePromise ( lstat , path ) return { lstat : ls , path , relativePath , } } ) const res = await Promise . all ( readFiles ) return res }


Input: Read a directory and return its structure as an object . Only Files Directories and Symlinks are included! [CODESPLIT] async function readDirStructure ( dirPath ) { if ( ! dirPath ) { throw new Error ( 'Please specify a path to the directory' ) } const ls = await makePromise ( lstat , dirPath ) if ( ! ls . isDirectory ( ) ) { const err = new Error ( 'Path is not a directory' ) err . code = 'ENOTDIR' throw err } const dir = /** @type {!Array<string>} */ ( await makePromise ( readdir , dirPath ) ) const lsr = await lstatFiles ( dirPath , dir ) const directories = lsr . filter ( isDirectory ) // reduce at once const notDirectories = lsr . filter ( isNotDirectory ) const files = notDirectories . reduce ( ( acc , current ) => { const type = getType ( current ) return { ... acc , [ current . relativePath ] : { type , } , } } , { } ) const dirs = await directories . reduce ( async ( acc , { path , relativePath } ) => { const res = await acc const structure = await readDirStructure ( path ) return { ... res , [ relativePath ] : structure , } } , { } ) const content = { ... files , ... dirs , } return { content , type : 'Directory' , } }


Input: / * input [ Any ] [CODESPLIT] function parsePolicies ( input ) { var type = typeof input ; if ( type === 'object' ) { for ( var i in input ) { input [ i ] = this . parsePolicies ( input [ i ] ) ; } return input ; } if ( type === 'string' ) { var parsedString = esprima . parse ( input ) . body [ 0 ] . expression ; return this . parseEsprima ( parsedString ) ; } return input ; }


Input: / * input [ Esprima Object ] fromFactory [ Boolean ] set to true the result will be interpreted by a factory [CODESPLIT] function parseEsprima ( input , fromFactory ) { var type = input . type ; if ( type === esprimaType . value ) { return input . value ; } if ( type === esprimaType . policy ) { var policyName = input . name ; if ( fromFactory ) { return require ( sails . config . paths . policies + '/' + policyName ) ; } return policyName ; } if ( type === esprimaType . factory ) { var factoryName = input . callee . name ; try { var factory = require ( sails . config . paths . policyFactories + '/' + factoryName ) ; } catch ( e ) { return require ( sails . config . paths . policies + '/' + factoryName ) ; } var args = input . arguments . map ( function ( arg ) { return this . parseEsprima ( arg , true ) ; } , this ) ; return factory . apply ( this , args ) ; } throw new Error ( 'esprima type unhandled: ' + type ) ; }


Input: Function converts dataset property name someValue to data - some - value . [CODESPLIT] function propertyNameToAttribute ( name ) { var result = name . replace ( / ([A-Z]) / g , function ( match , letter ) { return '-' + letter . toLowerCase ( ) ; } ) ; return 'data-' + result ; }


Input: Generate the configure and detach commands for all root elements . [CODESPLIT] function generateCommands ( origin , dest ) { var destCmds = _ . chain ( dest . topology . containers ) . values ( ) . filter ( function ( container ) { return container . containedBy === container . id || ! container . containedBy ; } ) . map ( function ( container ) { return { cmd : 'configure' , id : container . id } ; } ) . value ( ) ; var originCmds = _ . chain ( origin . topology . containers ) . values ( ) . map ( function ( container ) { if ( ! dest . topology . containers [ container . id ] ) { return { cmd : 'detach' , id : container . id } ; } return null ; } ) . filter ( function ( container ) { return container !== null ; } ) . value ( ) ; return destCmds . concat ( originCmds ) ; }


Input: / * istanbul ignore next [CODESPLIT] function class_1 ( ) { var args = [ ] ; for ( var _i = 0 ; _i < arguments . length ; _i ++ ) { args [ _i ] = arguments [ _i ] ; } var _this = _super . apply ( this , args [ 0 ] . injector . args ( Class ) ) || this ; var params = args [ 0 ] ; _this . _injector = params . injector ; _this . _store = params . store ; _this . _aggregates = params . aggregates ; _this . _viewHandlers = params . viewHandlers ; _this . _logger = _this . _injector . get ( Logger ) ; return _this ; }


Input: Because req . param () was deprecated . [CODESPLIT] function _param ( req , key , _default ) { var src = req . params [ key ] ; if ( src === undefined ) { src = req . body [ key ] ; } if ( src === undefined ) { src = req . query [ key ] ; } if ( src === undefined ) { src = _default ; } return src ; }


Input: > Initialize Limon with input and options . Both are completely optional . You can pass plugins and tokens to options . [CODESPLIT] function Limon ( input , options ) { if ( ! ( this instanceof Limon ) ) { return new Limon ( input , options ) } lazy . use ( this , { fn : function ( app , opts ) { app . options = lazy . utils . extend ( app . options , opts ) } } ) this . defaults ( input , options ) this . use ( lazy . plugin . prevNext ( ) ) }


Input: / * converts between json and xlsx - only the first worksheet gets converted - cells are merged as a visual convenience but they hold no special meaning [CODESPLIT] function colLetterToNumber ( letters ) { var number = 0 , i = 0 ; for ( i = 0 ; i < letters . length ; i += 1 ) { //number += (letters.length - i - 1) * (letters.charCodeAt(i) - 64); number += Math . pow ( 26 , i ) * ( letters . charCodeAt ( letters . length - i - 1 ) - 64 ) ; } return number ; }


Input: Creates a new planner [CODESPLIT] function planner ( origin , dest , opts ) { var tasks = new TaskPlanner ( ) ; var cmds = generateCommands ( origin , dest ) ; var state = _ . cloneDeep ( origin ) ; var result ; opts = xtend ( defaults , opts ) ; assert ( opts . mode === 'quick' || opts . mode === 'safe' , 'unknown mode' ) ; tasks . addTask ( { cmd : 'nop' } , { } ) ; generateDetachTasks ( tasks , origin , opts ) ; generateDetachTasks ( tasks , dest , opts ) ; // needed because of safe mode generateConfigureTasks ( tasks , origin , dest , opts ) ; _ . forIn ( state . topology . containers , function ( container ) { container . running = true ; container . started = true ; container . added = true ; } ) ; _ . forIn ( dest . topology . containers , function ( container ) { var containers = state . topology . containers ; if ( ! containers [ container . id ] ) { containers [ container . id ] = { id : container . id , containedBy : container . containedBy , running : false , started : false , added : false } ; } } ) ; result = cmds . reduce ( function ( acc , cmd ) { var plan = tasks . plan ( state , cmd ) ; if ( ! plan ) { throw new Error ( 'unable to generate ' + cmd . cmd + ' for id ' + cmd . id ) ; } return acc . concat ( plan ) ; } , [ ] ) . filter ( function ( cmd ) { return cmd && cmd . cmd !== 'nop' ; } ) ; if ( ! opts . noLinkUnlinkRemove ) { result = linkFilter ( result ) ; } return result ; }


Input: Non - destructive replacement . The block is commented out by adding an opening / * and closing * / . It does not account for internal block comments! [CODESPLIT] function replaceBlocks ( file , blocks ) { blocks . forEach ( block => { const index = file . search ( block [ 0 ] ) ; if ( index > - 1 ) { // Don't comment out blocks that have already been processed if ( file . substring ( index - 3 , index ) !== "/* " ) { file = file . replace ( block [ 0 ] , "/* $1 */\n" + block [ 1 ] ) ; } } else { maybeCompatible = false ; console . log ( ` ${ block [ 0 ] . toString ( ) } ` ) ; } } ) ; return file ; }


Input: @module lib / linkUnlinkFilter Removes consequent link / unlink ( or unlink / link ) commands with the same id [CODESPLIT] function linkUnlinkFilter ( list ) { var skipNext ; var needsFiltering = true ; function doFilter ( cmd , i , cmds ) { if ( skipNext ) { skipNext = false ; return false ; } if ( ! cmds [ i + 1 ] ) { return true ; } if ( cmds [ i + 1 ] . id !== cmd . id ) { return true ; } var unlinkLink = ( cmd . cmd === 'unlink' && cmds [ i + 1 ] . cmd === 'link' ) ; var linkUnlink = ( cmd . cmd === 'link' && cmds [ i + 1 ] . cmd === 'unlink' ) ; if ( linkUnlink || unlinkLink ) { needsFiltering = true ; skipNext = true ; return false ; } return true ; } while ( needsFiltering ) { needsFiltering = false ; skipNext = false ; list = list . filter ( doFilter ) ; } return list ; }


Input: Success call [CODESPLIT] function ( branchName ) { var storyId = extractStoryId ( branchName ) , commandString ; argv . message = '"' + getHumanReadableStoryId ( storyId ) + ' - ' + argv . message + '"' ; commandString = compileCommandString ( 'git' ) ; return executeCommand ( commandString ) . fail ( function ( failure ) { if ( ! sjl . empty ( failure ) ) { log ( failure ) ; } } ) ; }


Input: Instantiates a new pixel strip which is the collection of LEDs . Resolves this strip within a Promise . See : https : // github . com / ajfisher / node - pixel#strip [CODESPLIT] function ( ) { return new Promise ( function ( resolve , reject ) { board . on ( 'ready' , function ( ) { var strip = new pixel . Strip ( { data : 6 , length : 12 , board : this , controller : "FIRMATA" } ) ; strip . on ( 'ready' , function ( ) { resolve ( strip ) ; } ) ; } ) ; } ) ; }


Input: Set the strip to a loading pattern . Triggered when the tests have started . [CODESPLIT] function ( strip ) { if ( ! strip ) { console . log ( messagingTexts . noStrip ) ; } if ( ! ( strip instanceof pixel . Strip ) ) { console . log ( messagingTexts . wrongStrip ) ; } pattern . reset ( strip , interval ) ; interval = pattern . domino ( strip , 'white' ) ; }


Input: Flash the strip with green lights indicating tests were successful . [CODESPLIT] function ( strip ) { if ( ! strip ) { console . log ( messagingTexts . noStrip ) ; } if ( ! ( strip instanceof pixel . Strip ) ) { console . log ( messagingTexts . wrongStrip ) ; } pattern . reset ( strip , interval ) ; setTimeout ( function ( ) { pattern . flash ( strip , 'green' , 2 ) ; } , 10 ) ; }


Input: Function return copy of element and if request deep copy of element [CODESPLIT] function cloneAnyNode ( element , deep ) { switch ( element . nodeType ) { case _Node2 [ 'default' ] . DOCUMENT_FRAGMENT_NODE : return cloneDocumentFragment ( element , deep ) ; case _Node2 [ 'default' ] . ELEMENT_NODE : return cloneElementNode ( element , deep ) ; case _Node2 [ 'default' ] . TEXT_NODE : return cloneTextNode ( element ) ; default : throw new _DOMException2 [ 'default' ] ( _DOMException2 [ 'default' ] . DATA_CLONE_ERR ) ; } }


Input: / private methods /// [CODESPLIT] function tryInit ( ) { if ( ! processors . length ) { var processorsPath = path . resolve ( __dirname , "processor" ) ; var files = fs . readdirSync ( processorsPath ) ; for ( var i = 0 ; i < files . length ; ++ i ) { var processor = require ( path . resolve ( processorsPath , files [ i ] ) ) ; //processor.name = processor.name || files[i]; if ( processor . priority ) processors . unshift ( processor ) ; else processors . push ( processor ) ; processorIndex [ processor . name ] = processor ; } } }


Input: Function return copy of element and if request deep copy of element [CODESPLIT] function cloneAnyNode ( element , deep ) { switch ( element . nodeType ) { case Node . DOCUMENT_FRAGMENT_NODE : return cloneDocumentFragment ( element , deep ) ; case Node . ELEMENT_NODE : return cloneElementNode ( element , deep ) ; case Node . TEXT_NODE : return cloneTextNode ( element ) ; default : throw new DOMException ( DOMException . DATA_CLONE_ERR ) ; } }


Input: / * istanbul ignore next [CODESPLIT] function class_1 ( ) { var args = [ ] ; for ( var _i = 0 ; _i < arguments . length ; _i ++ ) { args [ _i ] = arguments [ _i ] ; } var _this = _super . apply ( this , args [ 0 ] . injector . args ( Class ) ) || this ; var params = args [ 0 ] ; _this . _injector = params . injector ; _this . _store = params . store ; _this . _transports = params . transports ; _this . _aggregate = params . aggregate ; _this . _logger = _this . _injector . get ( Logger ) ; return _this ; }


Input: @param { Element } element @param { Object } rules @return { boolean } [CODESPLIT] function processRules ( element , rules ) { if ( rules . type === 'selectors' ) { return processSelectors ( element , rules . selectors ) ; } else if ( rules . type === 'ruleSet' ) { return processRule ( element , rules . rule ) ; } }


Input: Scopes the url to the tournament or flight [CODESPLIT] function scopeUrl ( options , inst ) { options = _ . extend ( _ . clone ( options || { } ) , inst ) if ( ! options . venue_id ) throw new Error ( 'venue_id required to make subvenue api calls' ) return ngin . Venue . urlRoot ( ) + '/' + options . venue_id + '/subvenues' }


Input: project config [CODESPLIT] function fetchConfig ( filename ) { var data ; filename = path . resolve ( filename ) ; try { data = fs . readFileSync ( filename , 'utf-8' ) ; } catch ( e ) { console . error ( 'Config read error: ' + e ) ; process . exit ( 2 ) ; } try { data = JSON . parse ( data ) ; } catch ( e ) { console . error ( 'Config parse error: ' + e ) ; process . exit ( 2 ) ; } return { filename : filename , path : path . dirname ( filename ) , data : data } ; }


Input: Router ====== constructor ----------- create a router ### optional arguments ** routes ** : routes to add [CODESPLIT] function Router ( routes ) { this . _routes = [ ] ; this . _not_found = null ; this . _not_found_path = '/404' ; if ( arguments . length === 1 ) { this . addRoutes ( routes ) ; } }


Input: http : // www . eq - 3 . de / Downloads / eq3 / download%20bereich / hm_web_ui_doku / HM_XmlRpc_API . pdf http : // www . eq - 3 . de / Downloads / eq3 / download%20bereich / hm_web_ui_doku / HMIP_XmlRpc_API_Addendum . pdf [CODESPLIT] function Hmif ( config , status , log ) { if ( ! ( this instanceof Hmif ) ) return new Hmif ( config , status , log ) ; if ( ! log ) { log = { } ; log . debug = log . info = log . warn = log . error = log . setLevel = function ( ) { } ; } var that = this ; this . status = status ; this . status . homematic = { interfaces : { } } ; if ( ! config ) return ; this . config = config ; log . info ( pkg . name + ' ' + pkg . version + ' starting' ) ; this . _iface = { } ; this . _values = { } ; this . _paramsetDescriptions = pjson . load ( 'paramsetDescriptions.json' ) || { } ; this . _names = { } ; var xmlrpcServer ; var binrpcServer ; function meta ( params ) { var iface = params [ 0 ] ; var address = params [ 1 ] ; var datapoint = params [ 2 ] ; var value = params [ 3 ] ; var dev = that . _iface [ iface ] . devices [ address ] ; var ident = paramsetIdent ( dev , 'VALUES' ) ; var desc = that . _paramsetDescriptions [ ident ] [ datapoint ] ; var meta = { } ; if ( address . indexOf ( ':' ) !== - 1 ) { meta . channelName = that . _names [ address ] ; meta . deviceName = that . _names [ address . replace ( / :[0-9]+$ / , '' ) ] ; } else { meta . deviceName = that . _names [ address . replace ( / :[0-9]+$ / , '' ) ] ; } if ( desc . TYPE === 'ENUM' ) meta . enumValue = desc . VALUE_LIST [ value ] ; return meta ; } function paramsetIdent ( dev , paramset ) { var ident = '' ; if ( dev . PARENT_TYPE ) ident = ident + dev . PARENT_TYPE + '/' ; ident = ident + dev . TYPE ; if ( dev . SUBTYPE ) ident = ident + '/' + dev . SUBTYPE ; ident = ident + '/' + dev . VERSION + '/' + paramset ; return ident ; } function getParamsetDescriptions ( iface ) { var calls = [ ] ; var requests = [ ] ; Object . keys ( that . _iface [ iface ] . devices ) . forEach ( function ( address ) { var dev = that . _iface [ iface ] . devices [ address ] ; dev . PARAMSETS . forEach ( function ( paramset ) { var ident = paramsetIdent ( dev , paramset ) ; if ( ( ! that . _paramsetDescriptions [ ident ] ) && ( requests . indexOf ( ident ) === - 1 ) ) { requests . push ( ident ) ; calls . push ( function ( cb ) { log . debug ( 'getParamsetDescription' , ident ) ; that . _iface [ iface ] . rpc . methodCall ( 'getParamsetDescription' , [ dev . ADDRESS , paramset ] , function ( err , res ) { if ( ! err ) { that . _paramsetDescriptions [ ident ] = res ; } else { log . error ( err ) ; } cb ( ) ; } ) ; } ) ; } } ) } ) ; async . series ( calls , function ( ) { log . debug ( 'getParamsetDescriptions' , iface , 'done' ) ; pjson . save ( 'paramsetDescriptions.json' , that . _paramsetDescriptions ) ; } ) ; } this . methods = { 'system.multicall' : function multicall ( err , params , callback ) { log . debug ( 'rpc < system.multicall' , err , '(' + params [ 0 ] . length + ')' ) ; var res = [ ] ; params [ 0 ] . forEach ( function ( c ) { that . methods . event ( null , c . params ) ; res . push ( '' ) ; } ) ; log . debug ( 're  >' , null , res ) ; callback ( null , res ) ; } , 'system.listMethods' : function listMethods ( err , params , callback ) { log . debug ( 'rpc < system.listMethods' , err , params ) ; log . debug ( 're  >' , null , JSON . stringify ( Object . keys ( that . methods ) ) ) ; callback ( null , Object . keys ( that . methods ) ) ; } , 'event' : function event ( err , params , callback ) { log . debug ( 'rpc < event' , err , params ) ; that . _iface [ params [ 0 ] ] . lastEvent = ( new Date ( ) ) . getTime ( ) ; if ( params [ 1 ] === 'CENTRAL' && params [ 2 ] === 'PONG' ) return ; if ( ! that . _values [ params [ 0 ] ] [ params [ 1 ] ] ) { that . _values [ params [ 0 ] ] [ params [ 1 ] ] = { } ; } if ( params [ 3 ] !== that . _values [ params [ 0 ] ] [ params [ 1 ] ] [ params [ 2 ] ] ) { log . debug ( 'rpc < change' , err , params , that . _names [ params [ 1 ] ] ) ; //if (params[1].indexOf(':') === -1) { that . emit ( 'change' , params , meta ( params ) ) ; //} else { //    that.emit('change', params, meta(params)); //} } that . _values [ params [ 0 ] ] [ params [ 1 ] ] [ params [ 2 ] ] = params [ 3 ] ; if ( params [ 1 ] . indexOf ( ':' ) === - 1 ) { that . emit ( 'rpc' , 'event' , params , meta ( params ) ) ; } else { that . emit ( 'rpc' , 'event' , params , meta ( params ) ) ; } if ( typeof callback === 'function' ) { log . debug ( 're  >' , null , JSON . stringify ( '' ) ) ; callback ( null , '' ) ; } } , 'listDevices' : function listDevices ( err , params , callback ) { log . debug ( 'rpc < listDevices' , err , params ) ; var re = [ ] ; Object . keys ( that . _iface [ params [ 0 ] ] . devices ) . forEach ( function ( d ) { var dev = that . _iface [ params [ 0 ] ] . devices [ d ] ; if ( that . _iface [ params [ 0 ] ] . type === 'hmip' ) { re . push ( { 'ADDRESS' : dev . ADDRESS , 'VERSION' : dev . VERSION } ) ; } else { re . push ( { 'ADDRESS' : dev . ADDRESS , 'VERSION' : dev . VERSION } ) ; } } ) ; log . debug ( 're  >' , null , re . length ) ; callback ( null , re ) ; } , 'newDevices' : function newDevices ( err , params , callback ) { log . debug ( 'rpc < newDevices' , err , params [ 0 ] , params [ 1 ] ) ; //.length); that . emit ( 'rpc' , 'newDevices' , params ) ; params [ 1 ] . forEach ( function ( dev ) { that . _iface [ params [ 0 ] ] . devices [ dev . ADDRESS ] = dev ; } ) ; pjson . save ( that . _iface [ params [ 0 ] ] . host + '-' + that . _iface [ params [ 0 ] ] . port + '-devices.json' , that . _iface [ params [ 0 ] ] . devices ) ; log . debug ( 're  >' , null , JSON . stringify ( '' ) ) ; callback ( null , '' ) ; getParamsetDescriptions ( params [ 0 ] ) ; } , 'deleteDevices' : function deleteDevices ( err , params , callback ) { log . debug ( 'rpc < deleteDevices' , err , params [ 0 ] , params [ 1 ] . length ) ; params [ 1 ] . forEach ( function ( dev ) { delete that . _iface [ params [ 0 ] ] . devices [ dev . ADDRESS ] ; } ) ; pjson . save ( that . _iface [ params [ 0 ] ] . host + '-' + that . _iface [ params [ 0 ] ] . port + '-devices.json' , that . _iface [ params [ 0 ] ] . devices ) ; that . emit ( 'rpc' , 'deleteDevices' , params ) ; log . debug ( 're  >' , null , JSON . stringify ( '' ) ) ; callback ( null , '' ) ; } } ; function getRegaNames ( ) { log . debug ( 'rega > reganames.fn' ) ; that . regaFile ( 'regascripts/reganames.fn' , function ( err , res ) { if ( ! err ) { that . _names = res ; log . debug ( 'rega < ' + Object . keys ( res ) . length ) ; } else { log . error ( err ) ; } } ) ; } function createClients ( callback ) { if ( ! that . config . type ) return ; switch ( that . config . type . toLowerCase ( ) ) { case 'ccu' : case 'ccu2' : getRegaNames ( ) ; createBinrpcServer ( ) ; createInterface ( 'rf' , that . config . address , 2001 , 'rf' , 'binrpc' , 90000 ) ; checkservice ( that . config . address , 2000 , function ( err ) { if ( ! err ) createInterface ( 'wired' , that . config . address , 2000 , 'wired' , 'binrpc' , 90000 ) ; } ) ; checkservice ( that . config . address , 2010 , function ( err ) { createXmlrpcServer ( ) ; if ( ! err ) createInterface ( 'hmip' , that . config . address , 2010 , 'hmip' , 'xmlrpc' , 0 ) ; } ) ; checkservice ( that . config . address , 8701 , function ( err ) { if ( ! err ) createInterface ( 'cux' , that . config . address , 8701 , 'cux' , 'binrpc' , 0 ) ; } ) ; break ; case 'hmipserver' : case 'hmip' : that . _names = pjson . load ( this . config . address + '-names.json' ) || { } ; createXmlrpcServer ( ) ; createInterface ( that . config . type , that . config . address , that . config . port || 2010 , 'hmip' , 'xmlrpc' , 0 ) ; break ; case 'hs485d' : case 'wired' : that . _names = pjson . load ( this . config . address + '-names.json' ) || { } ; if ( that . config . protocol === 'binrpc' ) { createBinrpcServer ( ) ; } else { createXmlrpcServer ( ) ; } createInterface ( that . config . type , that . config . address , that . config . port || 2000 , 'wired' , that . config . protocol , that . config . iface . checkEventTime ) ; break ; case 'rfd' : case 'rf' : that . _names = pjson . load ( this . config . address + '-names.json' ) || { } ; if ( that . config . protocol === 'binrpc' ) { createBinrpcServer ( ) ; } else { createXmlrpcServer ( ) ; } createInterface ( that . config . type , that . config . address , that . config . port || 2001 , 'rf' , that . config . protocol , that . config . iface . checkEventTime ) ; break ; case 'cuxd' : case 'cux' : that . _names = pjson . load ( this . config . address + '-names.json' ) || { } ; createBinrpcServer ( ) ; createInterface ( that . config . type , that . config . address , that . config . port || 8701 , 'cux' , 'binrpc' , that . config . iface . checkEventTime ) ; break ; default : log . error ( 'unknown interface type ' + that . config . interfaces [ i ] . type + ' for ' ) } setTimeout ( callback , 2500 ) ; } function createInterface ( id , host , port , type , protocol , checkEventTime ) { log . debug ( 'creating interface' , id , host + ':' + port ) ; that . _iface [ id ] = { init : false , host : host , port : port , protocol : protocol , type : type , devices : pjson . load ( host + '-' + port + '-devices.json' ) || { } , values : { } , lastEvent : ( new Date ( ) ) . getTime ( ) , checkEventTime : ( typeof checkEventTime === 'undefined' ? 30000 : checkEventTime ) } ; that . status . homematic . interfaces [ id ] = { init : false , host : host , port : port , protocol : protocol , type : type , checkEventTime : ( typeof checkEventTime === 'undefined' ? 30000 : checkEventTime ) } ; that . _values [ id ] = { } ; switch ( protocol ) { case 'binrpc' : case 'xmlrpc_bin' : log . debug ( 'binrpc.createClient' , host + ':' + port ) ; that . _iface [ id ] . rpc = binrpc . createClient ( { host : host , port : port } ) ; break ; default : log . debug ( 'xmlrpc.createClient' , host + ':' + port ) ; that . _iface [ id ] . rpc = xmlrpc . createClient ( { host : host , port : port , path : '/' } ) ; break ; } } function getIfaceInfos ( callback ) { var calls = [ ] ; Object . keys ( that . _iface ) . forEach ( function ( i ) { var url = 'http://' + that . config . listenAddress + ':' + that . config . listenPort ; log . debug ( 'rpc >' , i , 'system.listMethods' , JSON . stringify ( [ ] ) ) ; calls . push ( function ( cb ) { that . _iface [ i ] . rpc . methodCall ( 'system.listMethods' , [ ] , function ( err , res ) { log . debug ( 're  <' , i , err , JSON . stringify ( res ) ) ; that . _iface [ i ] . methods = res ; if ( res . indexOf ( 'getVersion' ) !== - 1 ) { log . debug ( 'rpc >' , i , 'getVersion' , [ ] ) ; that . _iface [ i ] . rpc . methodCall ( 'getVersion' , [ ] , function ( err , res ) { log . debug ( 're  <' , i , err , JSON . stringify ( res ) ) ; that . _iface [ i ] . version = res ; cb ( ) ; } ) ; } else { cb ( ) ; } } ) ; } ) ; } ) ; async . series ( calls , callback ) ; } function subscribe ( callback ) { var calls = [ ] ; Object . keys ( that . _iface ) . forEach ( function ( i ) { var url = 'http://' + that . config . listenAddress + ':' + that . config . listenPort ; var params = [ url , i ] ; calls . push ( function ( cb ) { log . debug ( 'rpc >' , i , 'init' , params ) ; that . _iface [ i ] . rpc . methodCall ( 'init' , params , function ( err , res ) { log . debug ( 're  <' , i , err , JSON . stringify ( res ) ) ; if ( ! err ) { log . info ( 'init succesful ' + i + ' (' + that . _iface [ i ] . host + ':' + that . _iface [ i ] . port + ')' ) ; that . status . homematic . interfaces [ i ] . init = true ; } checkEvents ( i ) ; cb ( ) ; } ) ; } ) ; } ) ; async . series ( calls , callback ) ; } function checkEvents ( iface ) { if ( ! that . _iface [ iface ] . checkEventTime ) { log . warn ( 'no checkEventTime for ' + iface ) ; that . status . homematic . interfaces [ iface ] . checkEventTime = null ; return ; } that . status . homematic . interfaces [ iface ] . checkEventTime = that . _iface [ iface ] . checkEventTime ; that . _iface [ iface ] . checkEventInterval = setInterval ( function ( ) { var now = ( new Date ( ) ) . getTime ( ) ; var le = that . _iface [ iface ] . lastEvent ; var elapsed = now - le ; log . debug ( 'checkEvents' , now , le , elapsed ) ; if ( elapsed > ( 2 * that . _iface [ iface ] . checkEventTime ) ) { that . status . homematic . interfaces [ iface ] . init = false ; var url = 'http://' + that . config . listenAddress + ':' + that . config . listenPort ; var params = [ url , iface ] ; log . debug ( 'rpc >' , iface , 'init' , params ) ; that . _iface [ iface ] . rpc . methodCall ( 'init' , params , function ( err , res ) { that . _iface [ iface ] . lastEvent = ( new Date ( ) ) . getTime ( ) ; log . debug ( 're  <' , iface , err , JSON . stringify ( res ) ) ; } ) ; } else if ( ( now - that . _iface [ iface ] . lastEvent ) > that . _iface [ iface ] . checkEventTime ) { if ( that . _iface [ iface ] . methods . indexOf ( 'ping' ) !== - 1 ) { log . debug ( 'rpc >' , iface , 'ping' , [ iface ] ) ; that . _iface [ iface ] . rpc . methodCall ( 'ping' , [ iface ] , function ( err , res ) { log . debug ( 're  <' , iface , err , JSON . stringify ( res ) ) ; } ) ; } else { // how to provoke event without ping? } } } , ( that . _iface [ iface ] . checkEventTime / 2 ) ) ; } function createXmlrpcServer ( ) { xmlrpcServer = xmlrpc . createServer ( { host : that . config . listenAddress , port : that . config . listenPort } ) ; log . info ( 'xmlrpc server listening on ' + that . config . listenAddress + ':' + that . config . listenPort ) ; xmlrpcServer . on ( 'NotFound' , function ( method , params ) { log . warn ( 'rpc < Method ' + method + ' does not exist' , params ) ; } ) ; that . status . homematic . xmlrpcServer = true ; that . status . homematic . xmlrpcServerPort = that . config . listenPort ; that . status . homematic . xmlrpcServerAddress = that . config . listenAddress ; createHandlers ( xmlrpcServer ) ; } function createBinrpcServer ( ) { binrpcServer = binrpc . createServer ( { host : that . config . listenAddress , port : that . config . listenPortBin } ) ; log . info ( 'binrpc server listening on ' + that . config . listenAddress + ':' + that . config . listenPortBin ) ; that . status . homematic . binrpcServer = true ; that . status . homematic . binrpcServerPort = that . config . listenPort ; that . status . homematic . binrpcServerAddress = that . config . listenAddress ; createHandlers ( binrpcServer ) ; } function createHandlers ( server ) { Object . keys ( that . methods ) . forEach ( function ( m ) { server . on ( m , that . methods [ m ] ) ; } ) ; } this . rpc = function rpc ( iface , method , params , callback ) { this . _iface [ iface ] . rpc . methodCall ( method , params , function ( err , res ) { if ( typeof callback === 'function' ) callback ( err , res ) ; } ) ; } ; this . rega = function rega ( script , callback ) { var post_options = { host : this . config . address , port : '8181' , path : '/rega.exe' , method : 'POST' , headers : { 'Content-Type' : 'application/x-www-form-urlencoded' , 'Content-Length' : script . length } } ; var post_req = http . request ( post_options , function ( res ) { var data = '' ; res . setEncoding ( 'utf8' ) ; res . on ( 'data' , function ( chunk ) { data += chunk . toString ( ) ; } ) ; res . on ( 'end' , function ( ) { var pos = data . lastIndexOf ( "<xml>" ) ; var stdout = unescape ( data . substring ( 0 , pos ) ) ; try { var result = stdout ; callback ( null , result ) ; } catch ( e ) { callback ( e ) } } ) ; } ) ; post_req . on ( 'error' , function ( e ) { callback ( e ) ; } ) ; post_req . write ( script ) ; post_req . end ( ) ; } ; this . regaFile = function regaFile ( file , callback ) { var that = this ; fs . readFile ( path . join ( __dirname , file ) , 'utf8' , function ( err , script ) { if ( err ) { callback ( err ) ; return false ; } that . rega ( script , function ( err , res ) { if ( ! err ) { try { callback ( null , JSON . parse ( res ) ) ; } catch ( e ) { callback ( e ) ; } } else { callback ( err ) ; } } ) ; } ) ; } ; this . _findIface = function findIface ( address ) { for ( var i in this . _iface ) { for ( var a in this . _iface [ i ] . devices ) { if ( a === address ) return i ; } } } ; this . setValue = function rpc ( address , datapoint , value , callback ) { var iface = this . _findIface ( address ) ; if ( ! iface ) { callback ( new Error ( 'no suitable interface found for address ' + address ) ) ; } else { this . _iface [ iface ] . rpc . methodCall ( 'setValue' , [ address , datapoint , value ] , function ( err , res ) { if ( typeof callback === 'function' ) callback ( err , res ) ; } ) ; } } ; this . unsubscribe = function unsubscribe ( callback ) { var that = this ; var calls = [ ] ; if ( that . _iface ) { Object . keys ( that . _iface ) . forEach ( function ( i ) { var url = 'http://' + that . config . listenAddress + ':' + that . config . listenPort ; var params = [ url , '' ] ; log . debug ( 'rpc >' , i , 'init' , params ) ; calls . push ( function ( cb ) { that . _iface [ i ] . rpc . methodCall ( 'init' , params , function ( err , res ) { log . debug ( 're  <' , i , err , JSON . stringify ( res ) ) ; cb ( ) ; } ) ; } ) ; } ) ; async . series ( calls , callback ) ; } else { callback ( ) ; } } ; createClients ( function ( ) { getIfaceInfos ( function ( ) { log . debug ( 'getIfaces done' ) ; subscribe ( function ( ) { log . debug ( 'subscriptions done' ) ; } ) ; } ) ; } ) ; }


Input: Creates a new resource . [CODESPLIT] function create ( parent , baseUrl , params , callback ) { parent . getClient ( ) . post ( baseUrl , params , function ( err , definition , response ) { if ( err ) return callback ( err ) ; callback ( null , new this ( parent , definition ) ) ; } . bind ( this ) ) ; }


Input: Register Loader of different Language [CODESPLIT] function register ( type , lang , handler ) { if ( Array . isArray ( lang ) ) { lang . forEach ( ( v ) => store [ type ] . langs [ v ] = handler ) ; return ; } store [ type ] . langs [ lang ] = handler ; }


Input:
Require extension vue hook [CODESPLIT] function loader ( module , filePath ) { let content = fs . readFileSync ( filePath , 'utf8' ) ; let moduleId = ` ${ hash ( filePath ) } ` ; let vueTemplate = '' ; let vueComponent = compiler . parseComponent ( stripBom ( content ) ) ; let script = vueComponent . script ; let styles = vueComponent . styles ; let template = vueComponent . template ; let scoped = styles . some ( ( { attrs } ) => attrs . scoped ) ; [ ] . concat ( script , template , styles ) . forEach ( ( tag , index ) => { if ( tag ) { let type = tag . type ; let content = tag . content ; let lang = tag . attrs . lang || store [ type ] . defaults ; let handler = store [ type ] . langs [ lang ] ; if ( handler ) { content = handler ( content , filePath , index , module ) ; } switch ( type ) { case 'style' : if ( browserEnv ) { /**
                         * Only in Browser Environment, append style to head
                         */ if ( tag . attrs . scoped ) { let ast = css . parse ( content ) ; ast . stylesheet . rules . forEach ( ( rule ) => { rule . selectors = rule . selectors . map ( ( selector ) => { let [ patterns ] = cssWhat ( selector ) ; let index = patterns . length - 1 ; for ( ; index >= 0 ; index -- ) { let { type } = patterns [ index ] ; if ( type !== 'pseudo' && type !== 'pseudo-element' ) { break ; } } patterns . splice ( index + 1 , 0 , { value : '' , name : moduleId , action : 'exists' , type : 'attribute' , ignoreCase : false , } ) ; return cssWhat . stringify ( [ patterns ] ) ; } ) ; } ) ; content = css . stringify ( ast ) ; } let style = document . createElement ( 'style' ) ; style . innerHTML = content ; store . style . exports . call ( module . exports , style , { index , styles , filePath , } ) ; } break ; case 'script' : module . _compile ( content , filePath ) ; break ; case 'template' : if ( browserEnv ) { /**
                         * Only in Browser Environment, set Attribute for each element
                         */ if ( scoped ) { let div = document . createElement ( 'div' ) ; div . innerHTML = content ; let root = div . firstElementChild ; let walk = function walk ( element , handler ) { handler ( element ) ; let children = element . children || [ ] ; [ ] . forEach . call ( children , ( child ) => { walk ( child , handler ) ; } ) ; } ; walk ( root , ( element ) => { element . setAttribute ( moduleId , '' ) ; } ) ; content = div . innerHTML ; } } vueTemplate = content ; break ; } } } ) ; module . exports . vueComponent = vueComponent ; module . exports . template = vueTemplate ; }


Input: WMURL . addCacheBustingKeyword ( url : URLString keyword : String = t ) : URLString --- implements ------------------------------------------ [CODESPLIT] function WMURL_isValid ( url , // @arg URLString|URLStringArray - absolute/relative url(s) canonical ) { // @arg Boolean = false - TBD // @ret Boolean // @desc validate URL //{@dev $valid ( typeof url === "string" || Array . isArray ( url ) , WMURL_isValid , "url" ) ; //}@dev var urls = Array . isArray ( url ) ? url : [ url ] ; for ( var i = 0 , iz = urls . length ; i < iz ; ++ i ) { if ( ! _parse ( urls [ i ] , true ) ) { return false ; } } return true ; }


Input: } [CODESPLIT] function _parseQuery ( _ , key , value ) { var encodedKey = global [ "encodeURIComponent" ] ( key ) , encodedValue = global [ "encodeURIComponent" ] ( value ) ; if ( rv [ encodedKey ] ) { if ( Array . isArray ( rv [ encodedKey ] ) ) { rv [ encodedKey ] . push ( encodedValue ) ; } else { rv [ encodedKey ] = [ rv [ encodedKey ] , encodedValue ] ; } } else { rv [ encodedKey ] = encodedValue ; } return "" ; }


Input: generator to add callbacks to a bucked and possible fire them [CODESPLIT] function ( kind , promisesDfd ) { return function ( ) { // operate on this unless we forced a deferred to work on var dfd = promisesDfd || this ; var fnSet = [ ] . slice . call ( arguments ) ; // as long as this is a progress handler or the state isn't reached add it // otherwise call it right now if ( kind === 'progress' || dfd . state === 'pending' ) { dfd [ kind + 's' ] . push ( fnSet ) ; } else { callSet . call ( dfd , fnSet , this [ kind + 'Args' ] ) ; } // if we forced a promiseDfd, return the promise if ( promisesDfd ) { return dfd . promise ; } // otherwise return the root deferred like normal return dfd ; } ; }


Input: call a callback set [CODESPLIT] function ( set , args ) { // nothing to see here folks if ( set . length < 1 ) { return ; } // the args to call with var apply = [ ] ; // we passed inline arguments if ( set . length > 1 ) { for ( var i = 1 ; i < set . length ; i ++ ) { // is it one of those cool perform.arg(X) thingies? // if not, just put the passed args in there if ( set [ i ] instanceof Argument ) { apply [ i ] = args [ set [ i ] . num ] ; } else { apply [ i ] = set [ i ] ; } apply = apply . slice ( 1 ) ; } } else { apply = args ; } // actually call the fn with the appropriate args set [ 0 ] . apply ( this , apply ) ; }


Input: call all the callback sets in a callback bucket [CODESPLIT] function ( kind , args ) { var bucket = this [ kind + 's' ] ; for ( var i = 0 ; i < bucket . length ; i ++ ) { callSet . call ( this , bucket [ i ] , args ) ; } }


Input: promise generator - psuedo read - only [CODESPLIT] function ( ) { var dfd = this ; // since people might be used to .promise() var promise = function ( ) { return promise ; } ; promise . done = stackNFire ( 'done' , dfd ) ; promise . fail = stackNFire ( 'fail' , dfd ) ; promise . progress = stackNFire ( 'progress' , dfd ) ; promise . state = dfd . state ; return promise ; }


Input: pass judgement onto thy deferred [CODESPLIT] function ( kind ) { return function ( ) { if ( this . state === 'pending' ) { if ( kind !== 'progress' ) { this [ kind + 'Args' ] = arguments ; this . state = this . promise . state = kind ; } callSets . call ( this , kind , arguments ) ; } return this ; } ; }


Input: the heart of the beast [CODESPLIT] function ( ) { this . dones = [ ] ; this . doneArgs = [ ] ; this . fails = [ ] ; this . failArgs = [ ] ; this . pendings = [ ] ; this . pendingArgs = [ ] ; this . state = 'pending' ; // expose the promise this . promise = iPromise . call ( this ) ; }


Input: upon any action on the dependencies check the resolution [CODESPLIT] function ( performer ) { // everything checks out var state = performer . state ; // everything resolved if ( state . allCount === 0 ) { var args = [ ] ; for ( var i = 0 ; i < performer . args . length ; i ++ ) { args = args . concat ( [ ] . concat ( performer . args [ i ] . args ) ) ; } // either fail/done are 0 or something went wrong if ( state . targetCount === 0 ) { performer . _dfd . resolve . apply ( performer . _dfd , args ) ; } else { performer . _dfd . reject . apply ( performer . _dfd , args ) ; } } }


Input: / * Define a relaxed toposort which does not check for ( or worry about ) cyclic dependencies . [CODESPLIT] function toposort ( dependencies ) { var sorted = [ ] , visited = { } ; function visit ( key ) { if ( ! visited [ key ] ) { visited [ key ] = true ; if ( ! dependencies [ key ] ) { throw new Error ( 'A dependency is given which is not defined' + key ) ; } dependencies [ key ] . dependencies . forEach ( visit ) ; sorted . push ( key ) ; } } for ( var key in dependencies ) { visit ( key ) ; } return sorted ; }


Input: Bolty main class [CODESPLIT] function ( schema ) { this . _decoders = decoders ; this . _encoders = encoders ; this . _schemas = { } ; // Allow to pass the fields direclty if ( Object . keys ( schema ) . join ( ',' ) !== 'name,fields' ) { schema = { name : '_auto-' + new Date ( ) . getTime ( ) , fields : schema } ; } this . _schema = schema ; this . _fieldIndex = Object . keys ( schema . fields ) ; this . _schemas [ schema . name ] = schema ; }


Input: Make a functional CSS rule [CODESPLIT] function ( selector , properties , value ) { let rule = postcss . rule ( { selector : selector } ) let decls = _ . map ( properties , function ( property ) { return postcss . decl ( { prop : property , value : value } ) } ) rule . append ( decls ) return rule }


Input: Generate a complete set of responsive spacing helpers [CODESPLIT] function ( breakpoints , spacingScale ) { return _ . map ( breakpoints , function ( breakpointValue , breakpointKey ) { let mediaQuery = postcss . atRule ( { name : 'media' , params : breakpointValue , } ) let rules = _ . flatMap ( spacingScale , function ( scaleValue , scaleKey ) { return _ . map ( helpers , function ( helperValues , helperKey ) { return makeFunctionalRule ( ` ${ breakpointKey } ${ helperKey } ${ scaleKey } ` , helperValues , scaleValue ) } ) } ) return mediaQuery . append ( rules ) } ) }


Input: 断言 val 的数据类型是否为 type 对应的数据类型 [CODESPLIT] function _assertDataType ( type , val ) { var dataType ; if ( val === UNDEFINED ) { dataType = OBJECT_UNDEFINED ; } else if ( val === NULL ) { dataType = OBJECT_NULL ; } else { dataType = _toString . call ( val ) ; } var lowerCaseType = dataType . replace ( DATA_TYPE_REPLACE_REX , '' ) . toLowerCase ( ) ; return lowerCaseType === type ; }


Input: ### Function branchMatching Returns the branch matching a dispatch value . :: A [ branch A ] - > maybe ( branch A ) [CODESPLIT] function branchMatching ( value , branches ) { var i = branches . length while ( i -- ) if ( equal ( value , branches [ i ] . condition ) ) return branches [ i ] return { condition : null , code : null } }


Input: ### Function method Constructs a multi - method . :: ( A ... - > B ) - > method [CODESPLIT] function method ( dispatch ) { var branches = [ ] var baseline = function ( a ) { throw noBranchFor ( a ) } var dispatchTable = new DispatchTable ( ) dispatch = dispatch || identity return makeMethod ( function ( ) { var value = dispatch . apply ( null , arguments ) var branch = dispatchTable . getBranch ( value ) . code || branchMatching ( value , branches ) . code || baseline return branch . apply ( null , arguments ) } ) // #### Function makeMethod // // Adds modification methods to a multi-method. // // :: method -> method function makeMethod ( f ) { f . when = when f . fallback = fallback f . remove = remove f . clone = clone return f } // ### Function when // // Adds a branch to a multi-method. // // :: @method => A, (B... -> C) -> method function when ( condition , f ) { if ( branchMatching ( condition , branches ) . code ) throw ambiguousBranch ( condition ) branches . push ( { condition : condition , code : f } ) dispatchTable . add ( condition , f ) return this } // ### Function fallback // // Adds a baseline branch, which is evaluated if no other branches // match a given dispatch value. // // :: @method => (A... -> B) -> method function fallback ( f ) { baseline = f return this } // ### Function remove // // Removes a branch from the multi-method. // // :: @method => A -> method function remove ( condition ) { branches = branches . filter ( function ( a ) { return ! equal ( condition , a . condition ) } ) return this } // ### Function clone // // Creates a new multi-method that fallsback to this one. // // :: @method => Unit -> method function clone ( ) { var instance = method ( dispatch ) instance . fallback ( this ) return instance } }


Input: #### Function makeMethod Adds modification methods to a multi - method . :: method - > method [CODESPLIT] function makeMethod ( f ) { f . when = when f . fallback = fallback f . remove = remove f . clone = clone return f }


Input: ### Function when Adds a branch to a multi - method . :: [CODESPLIT] function when ( condition , f ) { if ( branchMatching ( condition , branches ) . code ) throw ambiguousBranch ( condition ) branches . push ( { condition : condition , code : f } ) dispatchTable . add ( condition , f ) return this }


Input: ### Function remove Removes a branch from the multi - method . :: [CODESPLIT] function remove ( condition ) { branches = branches . filter ( function ( a ) { return ! equal ( condition , a . condition ) } ) return this }


Input: Allows a resource to be deleted . [CODESPLIT] function destroy ( callback ) { this . getClient ( ) . destroy ( this . definition . _links . self . href , function ( err , definition , response ) { if ( err ) return callback ( err ) ; callback ( ) ; } . bind ( this ) ) ; }


Input: Returns current config [CODESPLIT] function load_config ( ) { let config = { } ; if ( fs . existsSync ( pgrunner_config_file ) ) { config = JSON . parse ( fs . readFileSync ( pgrunner_config_file , { 'encoding' : 'utf8' } ) ) ; if ( argv . v ) { debug . log ( 'Loaded from ' , pgrunner_config_file ) ; } } if ( ! is . array ( config . servers ) ) { config . servers = [ ] ; } return config ; }


Input: Save current config [CODESPLIT] function save_config ( config ) { fs . writeFileSync ( pgrunner_config_file , JSON . stringify ( config , null , 2 ) , { 'encoding' : 'utf8' } ) ; if ( argv . v ) { debug . log ( 'Saved to ' , pgrunner_config_file ) ; } }


Input: Strip argv [CODESPLIT] function strip_argv ( a ) { let o = { } ; return Object . keys ( a ) . filter ( k => k !== '_' ) . map ( k => { o [ k ] = a [ k ] ; } ) ; }


Input: Strip keys [CODESPLIT] function strip_server_opts ( old_opts ) { debug . assert ( old_opts ) . is ( 'object' ) ; let opts = { } ; [ 'pgconfig' , 'host' , 'port' , 'user' , 'database' ] . forEach ( key => { if ( old_opts [ key ] !== undefined ) { opts [ key ] = old_opts [ key ] ; } } ) ; return opts ; }


Input: Returns server options [CODESPLIT] function get_server_opts ( opts ) { debug . assert ( opts ) . is ( 'object' ) ; debug . assert ( opts . settings ) . is ( 'object' ) ; return { 'dbconfig' : opts . dbconfig , 'host' : opts . settings . host , 'port' : opts . settings . port , 'user' : opts . settings . user , 'database' : opts . settings . database } ; }


Input: 校验参数 val 是否为 JSON 对象 [CODESPLIT] function _isJSON ( val ) { if ( ! _isString ( val ) ) { return false ; } try { // @TODO // 引用: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse // JSON support, 在 ECMAScript 5.1 定义, 在 JavaScript 1.7 实现 var jsonObj = JSON . parse ( val ) ; return _isPlainObject ( jsonObj ) ; } catch ( e ) { return false ; } }


Input: fn returns true / false to callback [CODESPLIT] function custom ( fn ) { return function ( req , res , next ) { fn ( req , function ( result ) { if ( result === true ) { return next ( ) ; } next ( new ErrorUnauthorized ( 'Authentication Failed' ) ) ; } ) ; } ; }


Input: Also allow multiple users / methods [CODESPLIT] function http_basic ( username , password ) { return function ( req , res , next ) { var credentials = basic_auth ( req ) ; if ( credentials !== undefined ) { if ( credentials . name && credentials . name === username ) { if ( credentials . pass && credentials . pass === password ) { return next ( ) ; } } } res . set ( 'WWW-Authenticate' , 'Basic' ) ; next ( new ErrorUnauthorized ( 'Authentication Failed' ) ) ; } ; }


Input: API data resource on local IndexedDB [CODESPLIT] function getResources ( domains ) { return store . getResources ( ) . then ( rsrcs => { return rsrcs . filter ( e => domains . includes ( e . domain ) ) ; } ) ; }


Input: / * The BaseController is deliberatly not an ES6 class . This is because ES6 classes don t play nice with CoffeeScript classes . ES6 classes may only be constructed with the new keyword while CoffeeScript classes when extending another class construct their parent by explicitely calling the parent constructor . This means that CoffeeScript classes cannot extend ES6 classes . [CODESPLIT] function BaseController ( context ) { Object . defineProperties ( this , { body : { enumerable : true , get ( ) { return context . body ; } , set ( val ) { context . body = val ; } , } , context : { enumerable : true , get ( ) { return context ; } , } , response : { enumerable : true , get ( ) { return context . response ; } , } , request : { enumerable : true , get ( ) { return context . request ; } , } , query : { enumerable : true , get ( ) { return context . query ; } , } , } ) ; }


Input: Note : must declare params as optional . [CODESPLIT] function packRanges ( fromIndex , toIndex , bucketThreshold , sparseIterationThreshold , getOwnPropertyNamesThreshold ) { var ownPropertyNames = null ; var consecutiveRange = ( toIndex - fromIndex >= sparseIterationThreshold ) && ArrayBuffer . isView ( this ) ; var skipGetOwnPropertyNames = consecutiveRange && ( toIndex - fromIndex >= getOwnPropertyNamesThreshold ) ; function * arrayIndexes ( object ) { if ( toIndex - fromIndex < sparseIterationThreshold ) { for ( var i = fromIndex ; i <= toIndex ; ++ i ) { if ( i in object ) yield i ; } } else { ownPropertyNames = ownPropertyNames || Object . getOwnPropertyNames ( object ) ; for ( var i = 0 ; i < ownPropertyNames . length ; ++ i ) { var name = ownPropertyNames [ i ] ; var index = name >>> 0 ; if ( ( "" + index ) === name && fromIndex <= index && index <= toIndex ) yield index ; } } } var count = 0 ; if ( consecutiveRange ) { count = toIndex - fromIndex + 1 ; } else { for ( var i of arrayIndexes ( this ) ) ++ count ; } var bucketSize = count ; if ( count <= bucketThreshold ) bucketSize = count ; else bucketSize = Math . pow ( bucketThreshold , Math . ceil ( Math . log ( count ) / Math . log ( bucketThreshold ) ) - 1 ) ; var ranges = [ ] ; if ( consecutiveRange ) { for ( var i = fromIndex ; i <= toIndex ; i += bucketSize ) { var groupStart = i ; var groupEnd = groupStart + bucketSize - 1 ; if ( groupEnd > toIndex ) groupEnd = toIndex ; ranges . push ( [ groupStart , groupEnd , groupEnd - groupStart + 1 ] ) ; } } else { count = 0 ; var groupStart = - 1 ; var groupEnd = 0 ; for ( var i of arrayIndexes ( this ) ) { if ( groupStart === - 1 ) groupStart = i ; groupEnd = i ; if ( ++ count === bucketSize ) { ranges . push ( [ groupStart , groupEnd , count ] ) ; count = 0 ; groupStart = - 1 ; } } if ( count > 0 ) ranges . push ( [ groupStart , groupEnd , count ] ) ; } return { ranges : ranges , skipGetOwnPropertyNames : skipGetOwnPropertyNames } ; }


Input: format a parsed object into a url string [CODESPLIT] function urlFormat ( obj ) { // ensure it's an object, and not a string url. // If it's an obj, this is a no-op. // this way, you can call url_format() on strings // to clean up potentially wonky urls. if ( isString ( obj ) ) { obj = urlParse ( obj ) ; } else if ( ! isObject ( obj ) || isNull ( obj ) ) { throw new TypeError ( 'Parameter "urlObj" must be an object, not ' + isNull ( obj ) ? 'null' : typeof obj ) ; } else if ( ! ( obj instanceof Url ) ) { return Url . prototype . format . call ( obj ) ; } else { return obj . format ( ) ; } }


Input: writelnColor ( msg color mgs2 color2 .. msgN colorN ) writeln msg in color [CODESPLIT] function writelnColor ( ) { for ( var i = 0 ; i < arguments . length ; i = i + 2 ) grunt . log . write ( arguments [ i ] [ arguments [ i + 1 ] ] ) ; grunt . log . writeln ( '' ) ; }


Input: @param { object } ray - Object that looks like { start : { x : number y : number } end : { x : number y : number } } [CODESPLIT] function rayVsCircle ( ray , circle ) { var rayStart = new Vec2 ( ray . start ) ; if ( circleContainsPoint ( circle . position , circle . radius , ray . start ) ) { return rayStart ; } var intersections = rayLineVsCircle ( ray , circle ) ; if ( intersections . length ) { return rayStart . nearest ( intersections . filter ( within ( ray ) ) ) ; } else { return null ; } }


Input: Treats ray like an infinite line see where it intersects circle . [CODESPLIT] function rayLineVsCircle ( ray , circle ) { var rayLine = new Line2 ( ray . start . x , ray . start . y , ray . end . x , ray . end . y ) ; return rayLine . intersectCircle ( circle . position , circle . radius ) ; }


Input: Scopes the url to the tournament league or flight [CODESPLIT] function scopeUrl ( options , inst ) { options = _ . extend ( _ . clone ( options || { } ) , inst ) if ( typeof options !== 'object' && ( ! options . tournament_id || ! options . flight_id ) ) throw new Error ( 'tournament_id or flight_id required to make tibreak preference api calls' ) var url = '' if ( options . tournament_id ) { url += ngin . Tournament . urlRoot ( ) + '/' + options . tournament_id } else if ( options . flight_id ) { url += ngin . Flight . urlRoot ( ) + '/' + options . flight_id } return url + TiebreakPreference . urlRoot ( ) }


Input: Fetch is used by Tournament and list is being used by Flight . Can those be consolidated? [CODESPLIT] function ( options , callback ) { var url = scopeUrl ( options , this ) return Super . fetch . call ( this , url , options , callback ) }


Input: JSON RPC library entry point [CODESPLIT] function ( module , debug ) { this . debug = debug || false ; this . jsonrpc = "2.0" ; // check & load the methods in module this . methods = module ; if ( handy . getType ( module ) == 'string' ) { this . methods = require ( module ) ; } if ( this . debug ) { logger . debug ( 'Loaded with methods:' + _ . functions ( this . methods ) ) ; } }


Input: returns the function parameters [CODESPLIT] function _getParamNames ( func ) { var funStr = func . toString ( ) ; return funStr . slice ( funStr . indexOf ( '(' ) + 1 , funStr . indexOf ( ')' ) ) . match ( / ([^\s,]+) / g ) ; }


Input: Get only changed properties as a hash . [CODESPLIT] function _getChangedProperties ( ) { var retVal = { } , key ; for ( key in this . _changed ) { retVal [ key ] = this . _changed [ key ] ; } return retVal ; }


Input: Allows a resource to be updated . [CODESPLIT] function update ( properties , callback ) { if ( typeof properties == 'function' ) { callback = properties ; properties = { } ; } var key , changed ; var exceptions = [ 'addresses_update_action' , 'emails_update_action' , 'phone_numbers_update_action' ] ; for ( key in properties ) { if ( 'set' + inflection . camelize ( key ) in this ) { this [ 'set' + inflection . camelize ( key ) ] ( properties [ key ] ) ; } else if ( exceptions . indexOf ( key ) != - 1 ) { this . _changed [ key ] = properties [ key ] ; } } changed = this . _getChangedProperties ( ) ; this . getClient ( ) . patch ( this . definition . _links . self . href , changed , function ( err , definition , response ) { if ( err ) return callback ( err ) ; this . definition = definition ; this . _setup ( ) ; callback ( null , this ) ; } . bind ( this ) ) ; }


Input: --- implements ------------------------------------------ [CODESPLIT] function DataType_Uint8Array_clone ( source , // @arg Uint8Array begin , // @arg Integer = 0 - begin offset end ) { // @arg Integer = source.length - end offset // @ret Uint8Array // @desc make clone (not reference) //{@dev $valid ( $type ( source , "Uint8Array" ) , DataType_Uint8Array_clone , "source" ) ; $valid ( $type ( begin , "Integer|omit" ) , DataType_Uint8Array_clone , "begin" ) ; $valid ( $type ( end , "Integer|omit" ) , DataType_Uint8Array_clone , "end" ) ; //}@dev if ( end !== undefined ) { return new Uint8Array ( source . buffer . slice ( begin , end ) ) ; } return new Uint8Array ( source . buffer . slice ( begin || 0 ) ) ; }


Input: By class name [CODESPLIT] function byClass ( c ) { c = classnames ( c ) if ( / ^\. / . test ( c ) ) { throw new Error ( 'No need to "." on start' ) } return bySelector ( ` ${ c } ` ) }


Input: Called automatically by JsDoc Toolkit . [CODESPLIT] function publish ( symbolSet ) { publish . conf = { // trailing slash expected for dirs ext : ".html" , outDir : JSDOC . opt . d || SYS . pwd + "../out/jsdoc/" , templatesDir : JSDOC . opt . t || SYS . pwd + "../templates/jsdoc/" , staticDir : "static/" , symbolsDir : "symbols/" , srcDir : "symbols/src/" , cssDir : "css/" , fontsDir : "css/fonts/" , jsDir : "javascript/" , templateName : "Codeview" , templateVersion : "1.2" , templateLink : "http://www.thebrightlines.com/2010/05/06/new-template-for-jsdoctoolkit-codeview/" } ; // is source output is suppressed, just display the links to the source file if ( JSDOC . opt . s && defined ( Link ) && Link . prototype . _makeSrcLink ) { Link . prototype . _makeSrcLink = function ( srcFilePath ) { return "<" + srcFilePath + ">" ; } } // create the folders and subfolders to hold the output IO . mkPath ( ( publish . conf . outDir + publish . conf . cssDir ) ) ; IO . mkPath ( ( publish . conf . outDir + publish . conf . fontsDir ) ) ; IO . mkPath ( ( publish . conf . outDir + publish . conf . jsDir ) ) ; IO . mkPath ( ( publish . conf . outDir + "symbols/src" ) . split ( "/" ) ) ; // used to allow Link to check the details of things being linked to Link . symbolSet = symbolSet ; // create the required templates try { var classTemplate = new JSDOC . JsPlate ( publish . conf . templatesDir + "class.tmpl" ) ; } catch ( e ) { print ( "Couldn't create the required templates: " + e ) ; quit ( ) ; } // some utility filters function hasNoParent ( $ ) { return ( $ . memberOf == "" ) } function isaFile ( $ ) { return ( $ . is ( "FILE" ) ) } function isaClass ( $ ) { return ( ( $ . is ( "CONSTRUCTOR" ) || $ . isNamespace ) && ( $ . alias != "_global_" || ! JSDOC . opt . D . noGlobal ) ) } // get an array version of the symbolset, useful for filtering var symbols = symbolSet . toArray ( ) ; // create the hilited source code files var files = JSDOC . opt . srcFiles ; for ( var i = 0 , l = files . length ; i < l ; i ++ ) { var file = files [ i ] ; var srcDir = publish . conf . outDir + publish . conf . srcDir ; makeSrcFile ( file , srcDir ) ; } // get a list of all the classes in the symbolset publish . classes = symbols . filter ( isaClass ) . sort ( makeSortby ( "alias" ) ) ; // create a filemap in which outfiles must be to be named uniquely, ignoring case if ( JSDOC . opt . u ) { var filemapCounts = { } ; Link . filemap = { } ; for ( var i = 0 , l = publish . classes . length ; i < l ; i ++ ) { var lcAlias = publish . classes [ i ] . alias . toLowerCase ( ) ; if ( ! filemapCounts [ lcAlias ] ) filemapCounts [ lcAlias ] = 1 ; else filemapCounts [ lcAlias ] ++ ; Link . filemap [ publish . classes [ i ] . alias ] = ( filemapCounts [ lcAlias ] > 1 ) ? lcAlias + "_" + filemapCounts [ lcAlias ] : lcAlias ; } } // create each of the class pages for ( var i = 0 , l = publish . classes . length ; i < l ; i ++ ) { var symbol = publish . classes [ i ] ; symbol . events = symbol . getEvents ( ) ; // 1 order matters symbol . methods = symbol . getMethods ( ) ; // 2 var output = "" ; output = classTemplate . process ( symbol ) ; IO . saveFile ( publish . conf . outDir + publish . conf . symbolsDir , ( ( JSDOC . opt . u ) ? Link . filemap [ symbol . alias ] : symbol . alias ) + publish . conf . ext , output ) ; } // create the class index page try { var classesindexTemplate = new JSDOC . JsPlate ( publish . conf . templatesDir + "allclasses.tmpl" ) ; } catch ( e ) { print ( e . message ) ; quit ( ) ; } var classesIndex = classesindexTemplate . process ( publish . classes ) ; IO . saveFile ( publish . conf . outDir , ( JSDOC . opt . D . index == "files" ? "allclasses" : "index" ) + publish . conf . ext , classesIndex ) ; classesindexTemplate = classesIndex = classes = null ; // create the file index page try { var fileindexTemplate = new JSDOC . JsPlate ( publish . conf . templatesDir + "allfiles.tmpl" ) ; } catch ( e ) { print ( e . message ) ; quit ( ) ; } var documentedFiles = symbols . filter ( isaFile ) ; // files that have file-level docs var allFiles = [ ] ; // not all files have file-level docs, but we need to list every one for ( var i = 0 ; i < files . length ; i ++ ) { allFiles . push ( new JSDOC . Symbol ( files [ i ] , [ ] , "FILE" , new JSDOC . DocComment ( "/** */" ) ) ) ; } for ( var i = 0 ; i < documentedFiles . length ; i ++ ) { var offset = files . indexOf ( documentedFiles [ i ] . alias ) ; allFiles [ offset ] = documentedFiles [ i ] ; } allFiles = allFiles . sort ( makeSortby ( "name" ) ) ; // output the file index page var filesIndex = fileindexTemplate . process ( allFiles ) ; IO . saveFile ( publish . conf . outDir , ( JSDOC . opt . D . index == "files" ? "index" : "files" ) + publish . conf . ext , filesIndex ) ; fileindexTemplate = filesIndex = files = null ; // copy static files IO . copyFile ( publish . conf . templatesDir + "/" + publish . conf . cssDir + "all.css" , publish . conf . outDir + "/" + publish . conf . cssDir ) ; IO . copyFile ( publish . conf . templatesDir + "/" + publish . conf . cssDir + "screen.css" , publish . conf . outDir + "/" + publish . conf . cssDir ) ; IO . copyFile ( publish . conf . templatesDir + "/" + publish . conf . cssDir + "handheld.css" , publish . conf . outDir + "/" + publish . conf . cssDir ) ; IO . copyFile ( publish . conf . templatesDir + "/" + publish . conf . jsDir + "all.js" , publish . conf . outDir + "/" + publish . conf . jsDir ) ; IO . copyFile ( publish . conf . templatesDir + "/" + publish . conf . jsDir + "html5.js" , publish . conf . outDir + "/" + publish . conf . jsDir ) ; IO . copyFile ( publish . conf . templatesDir + "/" + publish . conf . fontsDir + "mplus-1m-regular-webfont.eot" , publish . conf . outDir + "/" + publish . conf . fontsDir ) ; IO . copyFile ( publish . conf . templatesDir + "/" + publish . conf . fontsDir + "mplus-1m-regular-webfont.svg" , publish . conf . outDir + "/" + publish . conf . fontsDir ) ; IO . copyFile ( publish . conf . templatesDir + "/" + publish . conf . fontsDir + "mplus-1m-regular-webfont.ttf" , publish . conf . outDir + "/" + publish . conf . fontsDir ) ; IO . copyFile ( publish . conf . templatesDir + "/" + publish . conf . fontsDir + "mplus-1m-regular-webfont.woff" , publish . conf . outDir + "/" + publish . conf . fontsDir ) ; IO . copyFile ( publish . conf . templatesDir + "/" + publish . conf . fontsDir + "mplus-1m-bold-webfont.eot" , publish . conf . outDir + "/" + publish . conf . fontsDir ) ; IO . copyFile ( publish . conf . templatesDir + "/" + publish . conf . fontsDir + "mplus-1m-bold-webfont.svg" , publish . conf . outDir + "/" + publish . conf . fontsDir ) ; IO . copyFile ( publish . conf . templatesDir + "/" + publish . conf . fontsDir + "mplus-1m-bold-webfont.ttf" , publish . conf . outDir + "/" + publish . conf . fontsDir ) ; IO . copyFile ( publish . conf . templatesDir + "/" + publish . conf . fontsDir + "mplus-1m-bold-webfont.woff" , publish . conf . outDir + "/" + publish . conf . fontsDir ) ; }


Input: Include a sub - template in the current template specifying a data object [CODESPLIT] function subtemplate ( template , data ) { try { return new JSDOC . JsPlate ( publish . conf . templatesDir + template ) . process ( data ) ; } catch ( e ) { print ( e . message ) ; quit ( ) ; } }


Input: Build output for displaying function parameters . [CODESPLIT] function makeSignature ( params ) { if ( ! params ) return "()" ; var signature = "(" + params . filter ( function ( $ ) { return ! / \w+\.\w+ / . test ( $ . name ) ; } ) . map ( function ( $ ) { var name = $ . isOptional ? '[' + $ . name + ']' : $ . name ; return name ; } ) . join ( ", " ) + ")" ; return signature ; }


Input: Find symbol { [CODESPLIT] function resolveLinks ( str , from ) { str = str . replace ( / \{@link ([^}]+)\} / gi , function ( match , symbolName ) { symbolName = symbolName . trim ( ) ; var index = symbolName . indexOf ( ' ' ) ; if ( index > 0 ) { var label = symbolName . substring ( index + 1 ) ; symbolName = symbolName . substring ( 0 , index ) ; return new Link ( ) . toSymbol ( symbolName ) . withText ( label ) ; } else { return new Link ( ) . toSymbol ( symbolName ) ; } } ) ; return str ; }


Input: GameDefaults Class [CODESPLIT] function formatQuery ( options ) { var requiredParams if ( options && typeof options !== 'function' ) { options . query = requiredParams = _ . pick ( _ . extend ( { } , options , options . query ) , 'tournament_id' , 'league_id' , 'flight_id' , 'division_id' ) } if ( _ . isEmpty ( requiredParams ) ) throw new Error ( 'tournament_id, league_id, flight_id or division_id are required.' ) }


Input: Approach the desired contrast ratio by modifying the given component from the given starting value . [CODESPLIT] function approach ( index , x , onAxis ) { while ( 0 <= x && x <= 1 ) { candidateHSVA [ index ] = x ; WebInspector . Color . hsva2rgba ( candidateHSVA , candidateRGBA ) ; WebInspector . Color . blendColors ( candidateRGBA , bgRGBA , blendedRGBA ) ; var fgLuminance = WebInspector . Color . luminance ( blendedRGBA ) ; var dLuminance = fgLuminance - desiredLuminance ; if ( Math . abs ( dLuminance ) < ( onAxis ? epsilon / 10 : epsilon ) ) return x ; else x += ( index === V ? - dLuminance : dLuminance ) ; } return null ; }


Input: Get data [CODESPLIT] function colorControlInput ( id ) { const data = { id : id , column : d3form . optionData ( ` ${ id } ` ) } ; const preset = d3form . optionData ( ` ${ id } ` ) ; if ( preset . scale . scale === 'ordinal' ) { data . scale = preset . scale ; return data ; } data . scale = { scale : d3form . value ( ` ${ id } ` ) , domain : [ d3form . value ( ` ${ id } ` ) , d3form . value ( ` ${ id } ` ) ] , unknown : '#696969' } ; const range = [ d3form . value ( ` ${ id } ` ) ] ; if ( d3form . checked ( ` ${ id } ` ) ) { range . push ( d3form . value ( ` ${ id } ` ) ) ; } range . push ( d3form . value ( ` ${ id } ` ) ) ; data . scale . range = range ; return data ; }


Input: Update DOM attributes [CODESPLIT] function updateNodeColor ( data ) { d3 . selectAll ( '.node' ) . select ( '.node-symbol' ) . style ( 'fill' , d => d3scale . scaleFunction ( data . scale ) ( d [ data . column . key ] ) ) ; }


Input: Generate controlBox elements [CODESPLIT] function mainControlBox ( ) { d3 . select ( '#show-struct' ) . on ( 'change' , function ( ) { const data = nodeContentInput ( ) ; d3 . select ( '#main-control' ) . datum ( data ) ; updateNodeStructure ( data ) ; } ) . dispatch ( 'change' ) ; }


Input: Bootstraps the setup of the graph . [CODESPLIT] function bootstrap ( ) { // Hook up controllers $ ( '.control-zoom button' ) . on ( 'click' , onControlZoomClicked ) ; $ ( '.control-level input' ) . on ( 'change' , onControlLevelChanged ) ; $ ( '.control-deps input' ) . on ( 'click' , onControlDepsClicked ) ; $ ( '.control-links input' ) . on ( 'click' , onControlLinksClicked ) ; $ ( '.control-menu li' ) . on ( 'click' , onControlMenuClicked ) ; $ ( '#contextpopup li[data-action]' ) . on ( 'click' , onNodeContextMenuClick ) ; // Gather current level and scope from template values. appOptions . currentLevel = parseInt ( $ ( '.control-level input' ) . val ( ) ) ; appOptions . currentScope = $ ( '.control-deps input:radio[name=dep]:checked' ) . val ( ) ; zoom = d3 . behavior . zoom ( ) ; zoom . scaleExtent ( [ minScaleExtent , maxScaleExtent ] ) ; zoom . on ( 'zoom' , onZoomChanged ) ; graphWidth = window . innerWidth ; graphHeight = window . innerHeight ; d3 . select ( window ) . on ( 'resize' , onResize ) ; // Setup layout layout = d3 . layout . force ( ) . gravity ( .05 ) . charge ( - 300 ) . linkDistance ( 80 ) . size ( [ graphWidth , graphHeight ] ) . on ( 'tick' , onTick ) ; // Setup drag callbacks for nodes. If a node is clicked and dragged it becomes fixed. layout . drag ( ) . on ( 'dragstart' , function ( targetNode ) { d3 . event . sourceEvent . stopPropagation ( ) ; d3 . select ( this ) . classed ( 'dragging' , true ) . classed ( 'fixed' , targetNode . fixed = true ) ; detectAllNodesFixed ( ) ; } ) . on ( 'drag' , function ( targetNode ) { d3 . select ( this ) . attr ( 'cx' , targetNode . x = d3 . event . x ) . attr ( 'cy' , targetNode . y = d3 . event . y ) ; } ) . on ( 'dragend' , function ( ) { d3 . select ( this ) . classed ( 'dragging' , false ) ; } ) ; // Setup graph d3 . select ( '.graph' ) . append ( 'svg' ) . attr ( 'transform' , 'rotate(0)' ) . on ( 'contextmenu' , function ( ) { d3 . event . preventDefault ( ) ; } ) . attr ( 'pointer-events' , 'all' ) . call ( zoom ) . on ( 'dblclick.zoom' , null ) ; // Markers Def d3 . select ( '.graph svg' ) . append ( 'defs' ) . selectAll ( 'marker' ) . data ( [ 'regular' ] ) . enter ( ) . append ( 'marker' ) . attr ( 'id' , String ) . attr ( 'viewBox' , '0 -5 10 10' ) . attr ( 'refX' , 15 ) . attr ( 'refY' , - 1.5 ) . attr ( 'markerWidth' , 6 ) . attr ( 'markerHeight' , 6 ) . attr ( 'orient' , 'auto' ) . append ( 'path' ) . attr ( 'd' , 'M0,-5L10,0L0,5' ) ; // Top level SVGGElement for dragging / centering graph graph = d3 . select ( '.graph svg' ) . append ( getSVG ( 'g' ) ) . attr ( 'width' , graphWidth ) . attr ( 'height' , graphHeight ) . attr ( 'transform' , 'translate(' + zoom . translate ( ) + ')' + ' scale(' + zoom . scale ( ) + ')' ) ; // Initialize tablesorter $ ( '#nodeTable' ) . tablesorter ( { widgets : [ 'stickyHeaders' ] , widgetOptions : { stickyHeaders_filteredToTop : true , stickyHeaders_cloneId : '-sticky' , stickyHeaders_attachTo : '.control-table-inner' } , sortMultiSortKey : '' } ) ; updateAll ( ) ; // Center graph w/ zoom fit w/ 1 second transition applied after 4 seconds delay for debounce. centerGraph ( zoomFit , 1000 , 4000 ) ; }


Input: Centers the graph . All parameters can be either a number or a function evaluated for a number result . [CODESPLIT] function centerGraph ( newScale , duration , delay ) { if ( typeof delay === 'function' ) { delay = delay . call ( this ) ; } delay = typeof delay === 'number' ? delay : 0 ; setTimeout ( function ( ) { if ( typeof newScale === 'function' ) { newScale = newScale . call ( this ) ; } if ( typeof duration === 'function' ) { duration = duration . call ( this ) ; } newScale = typeof newScale === 'number' ? newScale : zoom . scale ( ) ; duration = typeof duration === 'number' ? duration : 200 ; if ( typeof newScale !== 'number' ) { throw new TypeError ( "centerGraph error: 'newScale' is not a 'number'." ) ; } if ( typeof duration !== 'number' ) { throw new TypeError ( "centerGraph error: 'duration' is not a 'number'." ) ; } var bounds = graph . node ( ) . getBBox ( ) ; var centerSVGX = ( graphWidth * newScale / 2 ) ; var centerSVGY = ( graphHeight * newScale / 2 ) ; var centerGraphX = ( bounds . x * newScale ) + ( bounds . width * newScale / 2 ) ; var centerGraphY = ( bounds . y * newScale ) + ( bounds . height * newScale / 2 ) ; // Translate var centerTranslate = [ ( graphWidth / 2 ) - centerSVGX + ( centerSVGX - centerGraphX ) , ( graphHeight / 2 ) - centerSVGY + ( centerSVGY - centerGraphY ) ] ; // Store values zoom . translate ( centerTranslate ) . scale ( newScale ) ; // Render transition graph . transition ( ) . duration ( duration ) . attr ( 'transform' , 'translate(' + zoom . translate ( ) + ')' + ' scale(' + zoom . scale ( ) + ')' ) ; // Hides any existing node context menu. hideNodeContextMenu ( ) ; } , delay ) ; }


Input: Helper function to determin if all nodes are fixed . This is run after any node is dragged and set to fixed . [CODESPLIT] function detectAllNodesFixed ( ) { if ( data ) { var currentNodesFixed = data . allNodesFixed ; var allNodesFixed = true ; data . nodes . forEach ( function ( node ) { if ( ! node . fixed ) { allNodesFixed = false ; } } ) ; data . allNodesFixed = allNodesFixed ; if ( currentNodesFixed !== allNodesFixed ) { updateMenuUI ( ) ; } // Update freeze / unfreeze menu option. } }


Input: Fades and unfades connected nodes to a given targetNode . [CODESPLIT] function fadeRelatedNodes ( targetNode , selected , nodes , links ) { var opacity = selected ? 0.1 : 1 ; var elm = findElementByNode ( 'circle' , targetNode ) ; // Highlight circle elm . classed ( 'selected' , opacity < 1 ) ; // Clean links $ ( 'path.link' ) . removeAttr ( 'data-show' ) ; // Traverse all nodes and set `dimmed` class to nodes that are dimmed / not connected in addition to setting // fill and stroke opacity. nodes . style ( 'stroke-opacity' , function ( otherNode ) { var thisOpacity = isConnected ( targetNode , otherNode ) ? 1 : opacity ; this . setAttribute ( 'fill-opacity' , thisOpacity ) ; this . setAttribute ( 'stroke-opacity' , thisOpacity ) ; // Depending on opacity add or remove 'dimmed' class. this . classList [ thisOpacity === 1 ? 'remove' : 'add' ] ( 'dimmed' ) ; return thisOpacity ; } ) ; // Traverse all links and set `data-show` and `marker-end` for connected links given the `targetNode`. links . style ( 'stroke-opacity' , function ( otherNode ) { if ( otherNode . source === targetNode ) { // Highlight target / sources of the link var elmNodes = graph . selectAll ( '.' + formatClassName ( 'node' , otherNode . target ) ) ; elmNodes . attr ( 'fill-opacity' , 1 ) ; elmNodes . attr ( 'stroke-opacity' , 1 ) ; elmNodes . classed ( 'dimmed' , false ) ; // Highlight arrows var elmCurrentLink = $ ( 'path.link[data-source=' + otherNode . source . index + ']' ) ; elmCurrentLink . attr ( 'data-show' , true ) ; elmCurrentLink . attr ( 'marker-end' , 'url(#regular)' ) ; return 1 ; } else { return opacity ; } } ) ; // Modify all links that have not had 'data-show' added above. var elmAllLinks = $ ( 'path.link:not([data-show])' ) ; elmAllLinks . attr ( 'marker-end' , opacity === 1 ? 'url(#regular)' : '' ) ; }


Input: A helper to select a given SVG element from given node data . [CODESPLIT] function findElementByNode ( prefix , node ) { var selector = '.' + formatClassName ( prefix , node ) ; return graph . select ( selector ) ; }


Input: Pass in the element and the screen coordinates are returned . [CODESPLIT] function getElementCoords ( element ) { var ctm = element . getCTM ( ) ; return { x : ctm . e + element . getAttribute ( 'cx' ) * ctm . a , y : ctm . f + element . getAttribute ( 'cy' ) * ctm . d } ; }


Input: Gets a recycled SVG element from the pool svgElementMap or creates a new element for the given type . Any data specified by D3 will be copied to the element . Returns a function which is evaluated by D3 . [CODESPLIT] function getSVG ( elementType ) { var returnVal ; var svgElement ; var cached ; switch ( elementType ) { case 'circle' : case 'g' : case 'path' : case 'text' : returnVal = function ( data ) { svgElement = svgElementMap [ elementType ] . pop ( ) ; cached = svgElement != null ; svgElement = svgElement != null ? svgElement : document . createElementNS ( 'http://www.w3.org/2000/svg' , elementType ) ; // Copy data to SVG element. if ( typeof data === 'object' ) { for ( var key in data ) { svgElement . setAttribute ( key , data [ key ] ) ; } } return svgElement ; } ; break ; default : throw new TypeError ( 'getSVG error: unknown elementType.' ) ; } return returnVal ; }


Input: Hides the node context menu if visible and removes any node highlighting . If an event is supplied it is checked against any existing context menu and is ignored if the context menu is within the parent hierarchy . [CODESPLIT] function hideNodeContextMenu ( event ) { // Provide an early out if there is no selected context node. if ( typeof selectedContextNode === 'undefined' ) { return ; } var contextMenuButton = $ ( '#context-menu' ) ; var popupmenu = $ ( '#contextpopup .mdl-menu__container' ) ; // If an event is defined then make sure it isn't targeting the context menu. if ( event ) { event . preventDefault ( ) ; // Picked element is not the menu if ( ! $ ( event . target ) . parents ( '#contextpopup' ) . length > 0 ) { // Hide menu if currently visible if ( popupmenu . hasClass ( 'is-visible' ) ) { contextMenuButton . click ( ) ; } fadeRelatedNodes ( selectedContextNode , false , nodes , links ) ; selectedContextNode = undefined ; } } else // No event defined so always close context menu and remove node highlighting. { // Hide menu if currently visible if ( popupmenu . hasClass ( 'is-visible' ) ) { contextMenuButton . click ( ) ; } fadeRelatedNodes ( selectedContextNode , false , nodes , links ) ; selectedContextNode = undefined ; } }


Input: Checks if a target node is connected to another given node by checking index or the linkedByIndex map . [CODESPLIT] function isConnected ( targetNode , otherNode ) { return targetNode . index === otherNode . index || linkedByIndex [ targetNode . index + ',' + otherNode . index ] ; }


Input: Handles responding to the dependencies radio group . [CODESPLIT] function onControlDepsClicked ( ) { // Do nothing if scope has not changed if ( this . value === appOptions . currentScope ) { return ; } // If max depth is set to sticky and current level is equal max level of old scope then set max level for // the new scope. if ( appOptions . maxDepthSticky && appOptions . currentLevel === dataPackageMap [ appOptions . currentScope ] . maxLevel ) { appOptions . currentLevel = dataPackageMap [ this . value ] . maxLevel } appOptions . currentScope = this . value ; var maxLevel = dataPackageMap [ appOptions . currentScope ] . maxLevel ; // Adjust current level if it is greater than max level for current scope. if ( appOptions . currentLevel > maxLevel ) { appOptions . currentLevel = maxLevel ; } // Update control level UI based on current and max level for given scope. $ ( '.control-level input' ) . attr ( { max : maxLevel } ) ; $ ( '.control-level input' ) . val ( appOptions . currentLevel ) ; $ ( '.control-level label' ) . html ( appOptions . currentLevel ) ; // Redraw graph data updateAll ( { redrawOnly : true } ) ; // Center graph w/ zoom fit w/ 1 second transition applied after a potential 2 seconds delay for debounce. centerGraph ( zoomFit , 1000 , data . allNodesFixed ? 0 : 2000 ) ; }


Input: Handles responding to the level slider . [CODESPLIT] function onControlLevelChanged ( ) { appOptions . currentLevel = parseInt ( this . value ) ; $ ( '.control-level input' ) . val ( appOptions . currentLevel ) ; $ ( '.control-level label' ) . html ( appOptions . currentLevel ) ; // Redraw graph data updateAll ( { redrawOnly : true } ) ; // Center graph w/ zoom fit w/ 1 second transition applied after a potential 2 seconds delay for debounce. centerGraph ( zoomFit , 1000 , data . allNodesFixed ? 0 : 2000 ) ; }


Input: Handles responding to overflow menu selections . [CODESPLIT] function onControlMenuClicked ( ) { switch ( $ ( this ) . data ( 'action' ) ) { case 'toggleFreezeAllNodes' : setNodesFixed ( ! data . allNodesFixed ) ; break ; case 'showFullNames' : appOptions . showFullNames = ! appOptions . showFullNames ; updateAll ( { redrawOnly : true } ) ; break ; case 'showTableView' : appOptions . showTableView = ! appOptions . showTableView ; $ ( '.control-table' ) . toggleClass ( 'hidden' , ! appOptions . showTableView ) ; updateTableUIExtent ( ) ; break ; case 'maxDepthSticky' : appOptions . maxDepthSticky = ! appOptions . maxDepthSticky ; break ; } // Defer updating menu UI until menu is hidden. setTimeout ( updateMenuUI , 200 ) ; }


Input: Handles a context click on a table row showing the related node context menu . [CODESPLIT] function onControlTableRowContextClick ( node , event ) { event . preventDefault ( ) ; // Prevents default browser context menu from showing. onNodeContextClick ( node , { x : event . pageX , y : event . pageY } ) ; }


Input: Handles a context click on a table row showing the related node context menu . Defers to onNodeMouseOverOut . [CODESPLIT] function onControlTableRowMouseOver ( nodes , links , node , enter ) { // Hide the node context menu if currently showing when a new table row / node is moused over. if ( node !== selectedContextNode ) { hideNodeContextMenu ( event ) ; } onNodeMouseOverOut ( nodes , links , enter , node ) ; }


Input: Handles clicks on zoom control buttons and invokes centerGraph with new scale value . [CODESPLIT] function onControlZoomClicked ( ) { var newScale = 1 ; var scalePercentile = 0.20 ; // Add or subtract scale percentile from current scale value. switch ( $ ( this ) . data ( 'action' ) ) { case 'zoom_in' : newScale = Math . max ( Math . min ( zoom . scale ( ) * ( 1 + scalePercentile ) , maxScaleExtent ) , minScaleExtent ) ; break ; case 'zoom_out' : newScale = Math . max ( zoom . scale ( ) * ( 1 - scalePercentile ) , minScaleExtent ) ; break ; case 'zoom_all_out' : newScale = zoomFit ( ) ; break ; } centerGraph ( newScale ) ; }


Input: Handles clicks on the node context menu invoking any active actions . [CODESPLIT] function onNodeContextMenuClick ( ) { // When a context menu is selected remove node highlighting. hideNodeContextMenu ( ) ; console . log ( '!! action: ' + $ ( this ) . data ( 'action' ) + '; link: ' + $ ( this ) . data ( 'link' ) ) ; switch ( $ ( this ) . data ( 'action' ) ) { case 'openLink' : var link = $ ( this ) . data ( 'link' ) ; if ( typeof link === 'string' ) { window . open ( link , '_blank' , 'location=yes,menubar=yes,scrollbars=yes,status=yes' ) ; } break ; } }


Input: Shows the node context menu [CODESPLIT] function onNodeContextClick ( targetNode , coords ) { // Hides any existing node context menu. hideNodeContextMenu ( ) ; if ( typeof coords !== 'object' ) { coords = getElementCoords ( this ) ; } var popupmenu = $ ( '#contextpopup .mdl-menu__container' ) ; var packageData = targetNode . packageData ; var packageLink , packageType , scmLink , scmType ; if ( packageData ) { if ( packageData . packageLink ) { packageLink = packageData . packageLink . link ; packageType = packageData . packageLink . type ; // Create proper name for package type. switch ( packageType ) { case 'npm' : packageType = 'NPM' ; break ; } } if ( packageData . scmLink ) { scmLink = packageData . scmLink . link ; scmType = packageData . scmLink . type ; // Create proper name for SCM type. switch ( scmType ) { case 'github' : scmType = 'Github' ; break ; } } } // Populate data for the context menu. popupmenu . find ( 'li' ) . each ( function ( index ) { var liTarget = $ ( this ) ; switch ( index ) { case 0 : if ( scmLink && scmType ) { liTarget . text ( 'Open on ' + scmType ) ; liTarget . data ( 'link' , scmLink ) ; liTarget . removeClass ( 'hidden' ) ; } else { liTarget . addClass ( 'hidden' ) ; } break ; case 1 : if ( packageLink && packageType ) { liTarget . text ( 'Open on ' + packageType ) ; liTarget . data ( 'link' , packageLink ) ; liTarget . removeClass ( 'hidden' ) ; } else { liTarget . addClass ( 'hidden' ) ; } break ; case 2 : if ( packageData && packageData . version ) { liTarget . text ( 'Version: ' + packageData . version ) ; liTarget . removeClass ( 'hidden' ) ; } else { liTarget . addClass ( 'hidden' ) ; } break ; } } ) ; // Wrapping in a 100ms timeout allows MDL to draw animation when showing a context menu after one has been hidden. setTimeout ( function ( ) { // Assign new selected context node and highlight related nodes. selectedContextNode = targetNode ; fadeRelatedNodes ( selectedContextNode , true , nodes , links ) ; // For MDL a programmatic click of the hidden context menu. var contextMenuButton = $ ( "#context-menu" ) ; contextMenuButton . click ( ) ; // Necessary to defer reposition of the context menu. setTimeout ( function ( ) { popupmenu . parent ( ) . css ( { position : 'relative' } ) ; popupmenu . css ( { left : coords . x , top : coords . y , position : 'absolute' } ) ; } , 0 ) ; } , 100 ) ; }


Input: Handles a mouse down action on a graph node . Hides any showing context menu . For left clicks the selected node becomes the drag target and related nodes are faded . Any other mouse button is ignored . [CODESPLIT] function onNodeMouseDown ( nodes , links , targetNode ) { hideNodeContextMenu ( ) ; // Only select / drag nodes with left clicked otherwise stop propagation of event. if ( d3 . event . button === 0 ) { selectedDragNode = targetNode ; // Select / highlight related nodes or remove attributes based on enter state. fadeRelatedNodes ( targetNode , true , nodes , links ) ; } else { d3 . event . stopPropagation ( ) ; } }


Input: Handles fading related nodes to the given targetNode if there is no currently selected node . [CODESPLIT] function onNodeMouseOverOut ( nodes , links , enter , targetNode ) { // If there is an existing selected node then exit early. if ( isNodeSelected ( ) ) { return ; } // Select / highlight related nodes or remove attributes based on enter state. fadeRelatedNodes ( targetNode , enter , nodes , links ) ; }


Input: Handles the window resize event . [CODESPLIT] function onResize ( ) { // Update graph parameters. graphWidth = window . innerWidth ; graphHeight = window . innerHeight ; graph . attr ( 'width' , graphWidth ) . attr ( 'height' , graphHeight ) ; layout . size ( [ graphWidth , graphHeight ] ) . resume ( ) ; updateMenuUI ( ) ; updateTableUIExtent ( ) ; // Hides any existing node context menu. hideNodeContextMenu ( ) ; centerGraph ( zoomFit , 1000 , data . allNodesFixed ? 0 : 2000 ) ; }


Input: D3 tick handler for the forced graph layout . [CODESPLIT] function onTick ( ) { nodes . attr ( 'cx' , function ( node ) { return node . x ; } ) . attr ( 'cy' , function ( node ) { return node . y ; } ) . attr ( 'transform' , function ( node ) { return 'translate(' + node . x + ',' + node . y + ')' ; } ) ; // Pull data from data.nodes array. Provides a curve to the links. links . attr ( 'd' , function ( link ) { var sourceX = data . nodes [ link . source . index ] . x ; var sourceY = data . nodes [ link . source . index ] . y ; var targetX = data . nodes [ link . target . index ] . x ; var targetY = data . nodes [ link . target . index ] . y ; var dx = targetX - sourceX , dy = targetY - sourceY , dr = Math . sqrt ( dx * dx + dy * dy ) ; return 'M' + sourceX + ',' + sourceY + 'A' + dr + ',' + dr + ' 0 0,1 ' + targetX + ',' + targetY ; } ) ; }


Input: Handles the D3 zoom / scale event . [CODESPLIT] function onZoomChanged ( ) { var newScale = Math . max ( d3 . event . scale , minScaleExtent ) ; zoom . scale ( newScale ) ; graph . attr ( 'transform' , 'translate(' + d3 . event . translate + ')' + ' scale(' + newScale + ')' ) ; }


Input: Recycles all SVG elements above the top level SVGGElement defining the graph . [CODESPLIT] function recycleGraph ( ) { var childNodes = graph . selectAll ( 'g > *' ) . remove ( ) ; if ( ! Array . isArray ( childNodes ) && ! Array . isArray ( childNodes [ '0' ] ) ) { return ; } // Get the child nodes group from selection. childNodes = childNodes [ '0' ] ; for ( var cntr = 0 ; cntr < childNodes . length ; cntr ++ ) { var childNode = childNodes [ cntr ] ; if ( childNode instanceof SVGPathElement ) { svgElementMap [ 'path' ] . push ( childNode ) ; } else if ( childNode instanceof SVGCircleElement ) { svgElementMap [ 'circle' ] . push ( childNode ) ; } else if ( childNode instanceof SVGTextElement ) { svgElementMap [ 'text' ] . push ( childNode ) ; } else if ( childNode instanceof SVGGElement ) { childNode . removeAttribute ( 'transform' ) ; // Must remove current transform. svgElementMap [ 'g' ] . push ( childNode ) ; } } }


Input: Renders the graph after recycling any nodes above the top level g SVGGElement . [CODESPLIT] function renderGraph ( options ) { options = typeof options === 'object' ? options : { } ; options . redrawOnly = typeof options . redrawOnly === 'boolean' ? options . redrawOnly : false ; // Recycle all SVG elements above the first SVGGElement. recycleGraph ( ) ; // Lines // Note: on second render link.source / target will be an object instead of a number. links = graph . append ( getSVG ( 'g' ) ) . selectAll ( 'line' ) . data ( data . links ) . enter ( ) . append ( getSVG ( 'path' ) ) . attr ( 'class' , 'link' ) . attr ( 'marker-end' , function ( ) { return 'url(#regular)' ; } ) . attr ( 'data-source' , function ( link ) { return typeof link . source === 'number' ? link . source : link . source . index ; } ) . attr ( 'data-target' , function ( link ) { return typeof link . target === 'number' ? link . target : link . target . index ; } ) ; // Nodes nodes = graph . append ( getSVG ( 'g' ) ) . selectAll ( 'node' ) . data ( data . nodes ) . enter ( ) . append ( getSVG ( 'g' ) ) . call ( layout . drag ) . attr ( 'class' , 'node' ) ; // Circles nodes . attr ( 'class' , function ( node ) { return formatClassName ( 'node' , node ) ; } ) ; nodes . append ( getSVG ( 'circle' ) ) . attr ( 'id' , function ( node ) { return formatClassName ( 'id' , node ) ; } ) . attr ( 'class' , function ( node ) { return formatClassName ( 'circle' , node ) + ' ' + node . packageData . jspmType ; } ) . attr ( 'r' , circleRadius ) . on ( 'contextmenu' , onNodeContextClick ) . on ( 'mousedown' , onNodeMouseDown . bind ( this , nodes , links ) ) . on ( 'mouseover' , onNodeMouseOverOut . bind ( this , nodes , links , true ) ) . on ( 'mouseout' , onNodeMouseOverOut . bind ( this , nodes , links , false ) ) . on ( 'dblclick.zoom' , function ( node ) // Centers view on node. { d3 . event . stopPropagation ( ) ; var dcx = ( window . innerWidth / 2 - node . x * zoom . scale ( ) ) ; var dcy = ( window . innerHeight / 2 - node . y * zoom . scale ( ) ) ; zoom . translate ( [ dcx , dcy ] ) ; graph . transition ( ) . duration ( 500 ) . attr ( 'transform' , 'translate(' + dcx + ',' + dcy + ')scale(' + zoom . scale ( ) + ')' ) ; } ) ; // A copy of the text with a thick white stroke for legibility. nodes . append ( getSVG ( 'text' ) ) . attr ( 'x' , 15 ) . attr ( 'y' , '.31em' ) . attr ( 'class' , function ( node ) { return 'shadow ' + formatClassName ( 'text' , node ) ; } ) . text ( function ( node ) { return ( appOptions . showFullNames ? node . packageData . actualPackageName : node . packageData . packageName ) + ' (' + node . minLevel + ')' ; } ) ; nodes . append ( getSVG ( 'text' ) ) . attr ( 'class' , function ( node ) { return node . packageData . isAlias ? 'isAliased ' : '' + formatClassName ( 'text' , node ) ; } ) . attr ( 'x' , 15 ) . attr ( 'y' , '.31em' ) . text ( function ( node ) { return ( appOptions . showFullNames ? node . packageData . actualPackageName : node . packageData . packageName ) + ' (' + node . minLevel + ')' ; } ) ; // Set the force layout nodes / links and start the bounce. layout . nodes ( data . nodes ) ; layout . links ( data . links ) ; layout . start ( ) ; linkedByIndex = { } ; // Build linked index data . links . forEach ( function ( node ) { linkedByIndex [ node . source . index + ',' + node . target . index ] = true ; } ) ; // Set a low alpha to provide minimal bounce when just redrawing. if ( options . redrawOnly ) { layout . alpha ( 0.01 ) ; } }


Input: Reverses all graph links . [CODESPLIT] function reverseGraphLinks ( ) { for ( var key in dataPackageMap ) { var graphData = dataPackageMap [ key ] ; graphData . links . forEach ( function ( link ) { var linkSource = link . source ; link . source = link . target ; link . target = linkSource ; } ) ; } }


Input: Sets all nodes fixed ( freeze ) or unfixed ( unfreeze ) . [CODESPLIT] function setNodesFixed ( fixed ) { // Resets any fixed node state. if ( nodes ) { nodes . each ( function ( node ) { d3 . select ( this ) . classed ( 'fixed' , node . fixed = fixed ) ; } ) ; } // Copy existing sim data to any package scope that contains the same node ID. for ( var key in dataPackageMap ) { dataPackageMap [ key ] . nodes . forEach ( function ( node ) { node . fixed = fixed ; } ) ; } if ( data ) { data . allNodesFixed = fixed ; } }


Input: Filters graph data based on current app option parameters : currentScope and currentLevel . [CODESPLIT] function updateGraphData ( ) { // Copy existing data / node parameters to new filtered data; if ( data ) { var existingNodeSimMap = { } ; // Collect existing simulation data. data . nodes . forEach ( function ( node ) { existingNodeSimMap [ node . id ] = { weight : node . weight , x : node . x , y : node . y , px : node . px , py : node . py , fixed : node . fixed ? node . fixed : false } ; } ) ; // Copy existing sim data to any package scope that contains the same node ID. for ( var mapKey in dataPackageMap ) { var graphData = dataPackageMap [ mapKey ] ; graphData . nodes . forEach ( function ( node ) { if ( existingNodeSimMap [ node . id ] ) { for ( var key in existingNodeSimMap [ node . id ] ) { node [ key ] = existingNodeSimMap [ node . id ] [ key ] ; } } } ) ; } } var allNodesFixed = true ; // Set new data data = { directed : dataPackageMap [ appOptions . currentScope ] . directed , multigraph : dataPackageMap [ appOptions . currentScope ] . multigraph , graph : dataPackageMap [ appOptions . currentScope ] . graph , links : dataPackageMap [ appOptions . currentScope ] . links . filter ( function ( link ) { return link . minLevel <= appOptions . currentLevel ; } ) , nodes : dataPackageMap [ appOptions . currentScope ] . nodes . filter ( function ( node ) { if ( typeof node . fixed === 'undefined' || node . fixed === false ) { allNodesFixed = false ; } return node . minLevel <= appOptions . currentLevel ; } ) } ; data . allNodesFixed = allNodesFixed ; }


Input: Provides handling of changing menu text & material icons based on current state . [CODESPLIT] function updateMenuUI ( ) { if ( data ) { $ ( '.control-menu li[data-action=toggleFreezeAllNodes]' ) . html ( data . allNodesFixed ? 'Unfreeze nodes' : 'Freeze nodes' ) ; } appMenuToggleOptions . forEach ( function ( key ) { var icon = appOptions [ key ] ? 'check_box' : 'check_box_outline_blank' ; $ ( '.control-menu li[data-action=' + key + '] i' ) . html ( icon ) ; } ) ; }