Input: Form and send request to API service [CODESPLIT] function sendRequest ( path , method , data , useToken , callback ) { var headers = { } headers [ 'Content-Type' ] = 'application/json' ; headers [ 'Content-Length' ] = Buffer . byteLength ( JSON . stringify ( data ) ) ; if ( useToken && TOKEN . length ) { headers [ 'Authorization' ] = 'Bearer ' + TOKEN ; } if ( method === undefined ) { method = 'POST' ; } if ( useToken === undefined ) { useToken = false ; } var options = { //uri: API_URL, path : '/' + path , port : 443 , hostname : API_URL , method : method , headers : headers , } ; var req = https . request ( options , function ( response ) { var str = '' ; response . on ( 'data' , function ( chunk ) { if ( response . statusCode == 401 ) { getToken ( ) ; sendRequest ( path , method , data , true , callback ) ; } else { str += chunk ; } } ) ; response . on ( 'end' , function ( ) { if ( response . statusCode != 401 ) { try { var answer = JSON . parse ( str ) ; } catch ( ex ) { var answer = returnError ( ) ; } callback ( answer ) ; } } ) ; } ) ; req . write ( JSON . stringify ( data ) ) ; req . end ( ) ; }


Input: Get token and store it [CODESPLIT] function getToken ( ) { var data = { grant_type : 'client_credentials' , client_id : API_USER_ID , client_secret : API_SECRET } sendRequest ( 'oauth/access_token' , 'POST' , data , false , saveToken ) ; function saveToken ( data ) { TOKEN = data . access_token ; var hashName = md5 ( API_USER_ID + '::' + API_SECRET ) ; fs . writeFileSync ( TOKEN_STORAGE + hashName , TOKEN ) ; } }


Input: Form error object [CODESPLIT] function returnError ( message ) { var data = { is_error : 1 } ; if ( message !== undefined && message . length ) { data [ 'message' ] = message } return data ; }


Input: Create address book [CODESPLIT] function createAddressBook ( callback , bookName ) { if ( ( bookName === undefined ) || ( ! bookName . length ) ) { return callback ( returnError ( "Empty book name" ) ) ; } var data = { bookName : bookName } ; sendRequest ( 'addressbooks' , 'POST' , data , true , callback ) ; }


Input: Edit address book name [CODESPLIT] function editAddressBook ( callback , id , bookName ) { if ( ( id === undefined ) || ( bookName === undefined ) || ( ! bookName . length ) ) { return callback ( returnError ( "Empty book name or book id" ) ) ; } var data = { name : bookName } ; sendRequest ( 'addressbooks/' + id , 'PUT' , data , true , callback ) ; }


Input: Remove address book [CODESPLIT] function removeAddressBook ( callback , id ) { if ( id === undefined ) { return callback ( returnError ( 'Empty book id' ) ) ; } sendRequest ( 'addressbooks/' + id , 'DELETE' , { } , true , callback ) ; }


Input: Get information about book [CODESPLIT] function getBookInfo ( callback , id ) { if ( id === undefined ) { return callback ( returnError ( 'Empty book id' ) ) ; } sendRequest ( 'addressbooks/' + id , 'GET' , { } , true , callback ) ; }


Input: List email addresses from book [CODESPLIT] function getEmailsFromBook ( callback , id ) { if ( id === undefined ) { return callback ( returnError ( 'Empty book id' ) ) ; } sendRequest ( 'addressbooks/' + id + '/emails' , 'GET' , { } , true , callback ) ; }


Input: Add new emails to address book [CODESPLIT] function addEmails ( callback , id , emails ) { if ( ( id === undefined ) || ( emails === undefined ) || ( ! emails . length ) ) { return callback ( returnError ( "Empty email or book id" ) ) ; } var data = { emails : serialize ( emails ) } ; sendRequest ( 'addressbooks/' + id + '/emails' , 'POST' , data , true , callback ) ; }


Input: Get information about email address from book [CODESPLIT] function getEmailInfo ( callback , id , email ) { if ( ( id === undefined ) || ( email === undefined ) || ( ! email . length ) ) { return callback ( returnError ( "Empty email or book id" ) ) ; } sendRequest ( 'addressbooks/' + id + '/emails/' + email , 'GET' , { } , true , callback ) ; }


Input: Get cost of campaign based on address book [CODESPLIT] function campaignCost ( callback , id ) { if ( id === undefined ) { return callback ( returnError ( 'Empty book id' ) ) ; } sendRequest ( 'addressbooks/' + id + '/cost' , 'GET' , { } , true , callback ) ; }


Input: Get list of campaigns [CODESPLIT] function listCampaigns ( callback , limit , offset ) { var data = { } if ( limit === undefined ) { limit = null ; } else { data [ 'limit' ] = limit ; } if ( offset === undefined ) { offset = null ; } else { data [ 'offset' ] = offset ; } sendRequest ( 'campaigns' , 'GET' , data , true , callback ) ; }


Input: Get information about campaign [CODESPLIT] function getCampaignInfo ( callback , id ) { if ( id === undefined ) { return callback ( returnError ( 'Empty book id' ) ) ; } sendRequest ( 'campaigns/' + id , 'GET' , { } , true , callback ) ; }


Input: Get campaign statistic by countries [CODESPLIT] function campaignStatByCountries ( callback , id ) { if ( id === undefined ) { return callback ( returnError ( 'Empty book id' ) ) ; } sendRequest ( 'campaigns/' + id + '/countries' , 'GET' , { } , true , callback ) ; }


Input: Get campaign statistic by referrals [CODESPLIT] function campaignStatByReferrals ( callback , id ) { if ( id === undefined ) { return callback ( returnError ( 'Empty book id' ) ) ; } sendRequest ( 'campaigns/' + id + '/referrals' , 'GET' , { } , true , callback ) ; }


Input: Create new campaign [CODESPLIT] function createCampaign ( callback , senderName , senderEmail , subject , body , bookId , name , attachments ) { if ( ( senderName === undefined ) || ( ! senderName . length ) || ( senderEmail === undefined ) || ( ! senderEmail . length ) || ( subject === undefined ) || ( ! subject . length ) || ( body === undefined ) || ( ! body . length ) || ( bookId === undefined ) ) { return callback ( returnError ( 'Not all data.' ) ) ; } if ( name === undefined ) { name = '' ; } if ( attachments === undefined ) { attachments = '' ; } if ( attachments . length ) { attachments = serialize ( attachments ) ; } var data = { sender_name : senderName , sender_email : senderEmail , //subject: encodeURIComponent(subject), //subject: urlencode(subject), subject : subject , body : base64 ( body ) , list_id : bookId , name : name , attachments : attachments } sendRequest ( 'campaigns' , 'POST' , data , true , callback ) ; }


Input: Cancel campaign [CODESPLIT] function cancelCampaign ( callback , id ) { if ( id === undefined ) { return callback ( returnError ( 'Empty campaign id' ) ) ; } sendRequest ( 'campaigns/' + id , 'DELETE' , { } , true , callback ) ; }


Input: Add new sender [CODESPLIT] function addSender ( callback , senderName , senderEmail ) { if ( ( senderEmail === undefined ) || ( ! senderEmail . length ) || ( senderName === undefined ) || ( ! senderName . length ) ) { return callback ( returnError ( 'Empty sender name or email' ) ) ; } var data = { email : senderEmail , name : senderName } sendRequest ( 'senders' , 'POST' , data , true , callback ) ; }


Input: Remove sender [CODESPLIT] function removeSender ( callback , senderEmail ) { if ( ( senderEmail === undefined ) || ( ! senderEmail . length ) ) { return callback ( returnError ( 'Empty email' ) ) ; } var data = { email : senderEmail } sendRequest ( 'senders' , 'DELETE' , data , true , callback ) ; }


Input: Activate sender using code [CODESPLIT] function activateSender ( callback , senderEmail , code ) { if ( ( senderEmail === undefined ) || ( ! senderEmail . length ) || ( code === undefined ) || ( ! code . length ) ) { return callback ( returnError ( 'Empty email or activation code' ) ) ; } var data = { code : code } sendRequest ( 'senders/' + senderEmail + '/code' , 'POST' , data , true , callback ) ; }


Input: Request mail with activation code [CODESPLIT] function getSenderActivationMail ( callback , senderEmail ) { if ( ( senderEmail === undefined ) || ( ! senderEmail . length ) ) { return callback ( returnError ( 'Empty email' ) ) ; } sendRequest ( 'senders/' + senderEmail + '/code' , 'GET' , { } , true , callback ) ; }


Input: Get global information about email [CODESPLIT] function getEmailGlobalInfo ( callback , email ) { if ( ( email === undefined ) || ( ! email . length ) ) { return callback ( returnError ( 'Empty email' ) ) ; } sendRequest ( 'emails/' + email , 'GET' , { } , true , callback ) ; }


Input: Remove email from all books [CODESPLIT] function removeEmailFromAllBooks ( callback , email ) { if ( ( email === undefined ) || ( ! email . length ) ) { return callback ( returnError ( 'Empty email' ) ) ; } sendRequest ( 'emails/' + email , 'DELETE' , { } , true , callback ) ; }


Input: Get email statistic by all campaigns [CODESPLIT] function emailStatByCampaigns ( callback , email ) { if ( ( email === undefined ) || ( ! email . length ) ) { return callback ( returnError ( 'Empty email' ) ) ; } sendRequest ( 'emails/' + email + '/campaigns' , 'GET' , { } , true , callback ) ; }


Input: Add email to blacklist [CODESPLIT] function addToBlackList ( callback , emails , comment ) { if ( ( emails === undefined ) || ( ! emails . length ) ) { return callback ( returnError ( 'Empty email' ) ) ; } if ( comment === undefined ) { comment = '' ; } var data = { emails : base64 ( emails ) , comment : comment } sendRequest ( 'blacklist' , 'POST' , data , true , callback ) ; }


Input: Remove emails from blacklist [CODESPLIT] function removeFromBlackList ( callback , emails ) { if ( ( emails === undefined ) || ( ! emails . length ) ) { return callback ( returnError ( 'Empty emails' ) ) ; } var data = { emails : base64 ( emails ) , } sendRequest ( 'blacklist' , 'DELETE' , data , true , callback ) ; }


Input: Get balance [CODESPLIT] function getBalance ( callback , currency ) { if ( currency === undefined ) { var url = 'balance' ; } else { var url = 'balance/' + currency . toUpperCase ( ) ; } sendRequest ( url , 'GET' , { } , true , callback ) ; }


Input: SMTP : get list of emails [CODESPLIT] function smtpListEmails ( callback , limit , offset , fromDate , toDate , sender , recipient ) { if ( limit === undefined ) { limit = 0 ; } if ( offset === undefined ) { offset = 0 ; } if ( fromDate === undefined ) { fromDate = '' ; } if ( toDate === undefined ) { toDate = '' ; } if ( sender === undefined ) { sender = '' ; } if ( recipient === undefined ) { recipient = '' ; } var data = { limit : limit , offset : offset , from : fromDate , to : toDate , sender : sender , recipient : recipient } sendRequest ( 'smtp/emails' , 'GET' , data , true , callback ) ; }


Input: Get information about email by id [CODESPLIT] function smtpGetEmailInfoById ( callback , id ) { if ( ( id === undefined ) || ( ! id . length ) ) { return callback ( returnError ( 'Empty id' ) ) ; } sendRequest ( 'smtp/emails/' + id , 'GET' , { } , true , callback ) ; }


Input: SMTP : add emails to unsubscribe list [CODESPLIT] function smtpUnsubscribeEmails ( callback , emails ) { if ( emails === undefined ) { return callback ( returnError ( 'Empty emails' ) ) ; } var data = { emails : serialize ( emails ) } sendRequest ( 'smtp/unsubscribe' , 'POST' , data , true , callback ) ; }


Input: SMTP : add new domain [CODESPLIT] function smtpAddDomain ( callback , email ) { if ( ( email === undefined ) || ( ! email . length ) ) { return callback ( returnError ( 'Empty email' ) ) ; } var data = { email : email } sendRequest ( 'smtp/domains' , 'POST' , data , true , callback ) ; }


Input: SMTP : verify domain [CODESPLIT] function smtpVerifyDomain ( callback , email ) { if ( ( email === undefined ) || ( ! email . length ) ) { return callback ( returnError ( 'Empty email' ) ) ; } sendRequest ( 'smtp/domains/' + email , 'GET' , { } , true , callback ) ; }


Input: SMTP : send mail [CODESPLIT] function smtpSendMail ( callback , email ) { if ( email === undefined ) { return callback ( returnError ( 'Empty email data' ) ) ; } email [ 'html' ] = base64 ( email [ 'html' ] ) ; var data = { email : serialize ( email ) } ; sendRequest ( 'smtp/emails' , 'POST' , data , true , callback ) ; }


Input: parse options [CODESPLIT] function getOpt ( resHtml , outputPath ) { if ( commandLine . minifyall ) { console . log ( '' ) ; console . log ( 'minify all. Process may take a few minutes with large file.' ) ; console . log ( '' ) ; minifyFile ( resHtml , outputPath ) ; } else { console . log ( '' ) ; console . log ( 'Output file name : ' + outputPath ) ; console . log ( '' ) ; writeFile ( resHtml , outputPath ) ; } }


Input: minify the result [CODESPLIT] function minifyFile ( resHtml , outputPath ) { var resHtml = minify ( resHtml , opt , function ( err ) { if ( err ) { console . error ( 'error will processing file.' ) ; } } ) ; console . log ( '' ) ; console . log ( 'Output file name : ' + outputPath ) ; console . log ( '' ) ; writeFile ( resHtml , outputPath ) ; }


Input: write result to file [CODESPLIT] function writeFile ( resHtml , outputPath ) { fs . writeFile ( outputPath , resHtml , function ( err ) { if ( err ) { console . log ( '' ) ; console . log ( 'File error: ' + err + '. Exit.' ) ; } else { console . log ( '' ) ; console . log ( 'All done. Exit.' . green ) ; } } ) ; }


Input: TODO : If extends other interfaces then concatenate schemas from those order sets precedence ( first is overrides ) . Then superimpose given schema on top of these . [CODESPLIT] function ( params ) { // Schema defines fields and can be used for validation and form generation (optional) this . schema = params . schema ; // The name of the interface, this should be unique this . name = params . name ; // Additional properties that aren't exposed as form data, in the future this might be  // used to check that objects fulfill the implementation this . members = params . members ; this . interfaceId = uuid . v4 ( ) ; // console.log("[SCHEMA] Created interface [" + this.name + "] with id: " + this.interfaceId); }


Input: / * [CODESPLIT] function AdapterRegistryException ( message , context ) { this . message = message ; this . name = "AdapterRegistryException" ; this . context = context ; this . stack = ( new Error ( ) ) . stack ; }


Input: Create a cookie instance . [CODESPLIT] function Cookie ( options ) { this . options = options || { } ; this . options . expires = typeof this . options . expires === 'number' ? this . options . expires : 30 ; this . options . path = this . options . path !== undefined ? this . options . path : '/' ; this . options . secure = typeof this . options . secure === 'boolean' ? this . options . secure : false ; }


Input: Set a cookie value . [CODESPLIT] function set ( key , value , options ) { options = options || this . options ; var days = parseInt ( options . expires || - 1 ) ; if ( value !== undefined && typeof value !== 'function' ) { var t = new Date ( ) ; t . setDate ( ( t . getDate ( ) + days ) ) ; var res = ( document . cookie = [ this . encode ( key ) , '=' , this . stringify ( value ) , // use expires attribute, max-age is not supported by IE options . expires ? '; expires=' + t . toUTCString ( ) : '' , options . path ? '; path=' + options . path : '' , options . domain ? '; domain=' + options . domain : '' , options . secure ? '; secure' : '' ] . join ( '' ) ) ; return res ; } }


Input: Get a cookie value . [CODESPLIT] function get ( key , value ) { var i , parts , name , cookie ; var result = key ? undefined : { } ; /* istanbul ignore next */ var cookies = ( document . cookie || '' ) . split ( '; ' ) ; for ( i = 0 ; i < cookies . length ; i ++ ) { parts = cookies [ i ] . split ( '=' ) ; name = this . decode ( parts . shift ( ) ) ; cookie = parts . join ( '=' ) ; if ( key && key === name ) { // if second argument (value) is a function it's a converter result = this . read ( cookie , value ) ; break ; } // prevent storing a cookie that we couldn't decode if ( ! key && ( cookie = this . read ( cookie ) ) !== undefined ) { result [ name ] = cookie ; } } return result ; }


Input: Delete a cookie value . [CODESPLIT] function del ( key , options ) { if ( ! options ) { options = { } ; for ( var z in this . options ) { options [ z ] = this . options [ z ] ; } } options . expires = - 1 ; this . set ( key , '' , options ) ; }


Input: Clear all stored cookies optionally keeping the keys in the except array . [CODESPLIT] function clear ( except , options ) { var keys = this . get ( ) , z ; except = except || [ ] ; for ( z in keys ) { if ( ~ except . indexOf ( z ) ) { continue ; } this . del ( z , options ) ; } }


Input: Curry a binary function . [CODESPLIT] function curry2 ( fn , self ) { var out = function ( ) { if ( arguments . length === 0 ) return out return arguments . length > 1 ? fn . apply ( self , arguments ) : bind . call ( fn , self , arguments [ 0 ] ) } out . uncurry = function uncurry ( ) { return fn } return out }


Input: / * list can be either [[ x y ] [ x y ]] or [ x y ] [CODESPLIT] function createTouchList ( target , list ) { if ( Array . isArray ( list ) && list [ 0 ] && ! Array . isArray ( list [ 0 ] ) ) { list = [ list ] ; } list = list . map ( function ( entry , index ) { var x = entry [ 0 ] ; var y = entry [ 1 ] ; var id = entry [ 2 ] || index ; return createTouch ( x , y , target , id ) ; } ) ; return document . createTouchList . apply ( document , list ) ; }


Input: http : // stackoverflow . com / questions / 7056026 / variation - of - e - touches - e - targettouches - and - e - changedtouches [CODESPLIT] function initTouchEvent ( touchEvent , type , touches ) { var touch1 = touches [ 0 ] ; return touchEvent . initTouchEvent ( //touches touches , //targetTouches touches , //changedTouches touches , //type type , //view window , //screenX touch1 . screenX , //screenY touch1 . screenY , //clientX touch1 . clientX , //clientY touch1 . clientY , //ctrlKey false , //altKey false , //shiftKey false , //metaKey false ) ; }


Input: @public @memberOf { app . Unit } @method [CODESPLIT] function ( ) { if ( _ . isObject ( this . cache ) ) { return this . cache ; } if ( _ . has ( this . app . caches , this . cache ) ) { return this . app . caches [ this . cache ] ; } throw new errors . NoSuchCacheError ( f ( 'You should define app.caches[%j] interface' , this . cache ) ) ; }


Input: -- Utils -- Shortcut for creating an icon button within a viewer . [CODESPLIT] function createIconButton ( viewerElm , css , eventType ) { const buttonElm = $ . create ( 'div' , { 'class' : css } ) $ . listen ( buttonElm , { 'click' : ( event ) => { event . preventDefault ( ) if ( event . buttons === 0 ) { $ . dispatch ( viewerElm , eventType ) } } } ) return buttonElm }


Input:
@class Context [CODESPLIT] function Context ( params , logger ) { /**
     * @public
     * @memberOf {Context}
     * @property
     * @type {Object}
     * */ this . params = params ; /**
     * @public
     * @memberOf {Context}
     * @property
     * @type {Object}
     * */ this . result = new Obus ( ) ; /**
     * @public
     * @memberOf {Context}
     * @property
     * @type {Object}
     * */ this . errors = new Obus ( ) ; /**
     * @public
     * @memberOf {Context}
     * @property
     * @type {Logger}
     * */ this . logger = logger ; }


Input: * END : Utility Functions ** * START : Classes used by compiled templates ** [CODESPLIT] function ContextStack ( dict , tpl ) { this [ cache_stack ] = [ ] ; this . tpl = tpl ; this . push ( util . global ) ; if ( tpl . fallback !== U ) { this . hasFallback = true ; this . fallback = tpl . fallback ; } switch ( util . ntype ( dict ) ) { case 'object' : this . push ( dict ) ; break ; case 'array' : dict [ fn_var . dict ] ? dict . map ( this . push , this ) : this . push ( dict ) ; break ; default : ! util . exists ( dict ) || this . push ( dict ) ; } }


Input: * END : Classes used by compiled templates ** * START : create template methods ** [CODESPLIT] function aggregatetNonEmpty ( res , str ) { util . empty ( str ) || res . push ( str ) ; return res ; }


Input:
@class Track [CODESPLIT] function Track ( app , logger ) { /**
     * @public
     * @memberOf {Track}
     * @property
     * @type {String}
     * */ this . id = this . _createId ( ) ; /**
     * TODO Deprecate?
     *
     * @public
     * @memberOf {Track}
     * @property
     * @type {Logger}
     * */ this . logger = logger ; /**
     * @public
     * @memberOf {Track}
     * @property
     * @type {Object}
     * */ this . params = { } ; /**
     * @protected
     * @memberOf {Track}
     * @property
     * @type {Core}
     * */ this . _app = app ; /**
     * @public
     * @memberOf {Track}
     * @property
     * @type {Object}
     * */ this . calls = { } ; /**
     * @protected
     * @memberOf {Track}
     * @property
     * @type {Boolean}
     * */ this . _isFlushed = false ; }


Input: Clone behaviour for gallery items used when creating a helper for the purpose of sorting . [CODESPLIT] function cloneGalleryItem ( inst , element ) { // Clone the element const clone = element . cloneNode ( true ) // Remove id attribute to avoid unwanted duplicates clone . removeAttribute ( 'id' ) // Add a helper class clone . classList . add ( 'mh-gallery-item--sort-helper' ) return clone }


Input:
@class FistError @extends Error [CODESPLIT] function FistError ( code , msg ) { var err = new Error ( f ( '(%s) %s' , code , msg ) ) ; err . name = this . name ; Error . captureStackTrace ( err , this . constructor ) ; /**
     * @public
     * @memberOf {FistError}
     * @property
     * @type {String}
     * */ this . code = code ; /**
     * @public
     * @memberOf {FistError}
     * @property
     * @type {String}
     * */ this . message = err . message ; /**
     * @public
     * @memberOf {FistError}
     * @property
     * @type {String}
     * */ this . stack = err . stack ; }


Input:
@class Connect @extends Track [CODESPLIT] function Connect ( app , logger , req , res ) { /**
     * @public
     * @memberOf {Connect}
     * @property
     * @type {IncomingMessage}
     * */ this . req = req ; /**
     * @public
     * @memberOf {Connect}
     * @property
     * @type {ServerResponse}
     * */ this . res = res ; //  TODO give connect and track same signature Track . call ( this , app , logger ) ; /**
     * @public
     * @memberOf {Connect}
     * @property
     * @type {String}
     * */ this . route = null ; /**
     * @public
     * @memberOf {Connect}
     * @property
     * @type {Array<String>}
     * */ this . matches = [ ] ; /**
     * @public
     * @memberOf {Connect}
     * @property
     * @type {Number}
     * */ this . routeIndex = - 1 ; /**
     * @private
     * @memberOf {Connect}
     * @property
     * @type {Object}
     * */ this . _url = null ; }


Input: upload or update file function [CODESPLIT] function ( localFilePath ) { let contentType = mime . lookup ( localFilePath ) ; let standerFilePath = localFilePath . replace ( / \\ / g , '/' ) ; fs . readFile ( localFilePath , function ( readFileErr , fileData ) { if ( readFileErr ) { throw readFileErr ; } const putConfig = { Bucket : bucket . Name , Body : fileData , Key : standerFilePath , ContentType : contentType , AccessControlAllowOrigin : options . AccessControlAllowOrigin || '*' , CacheControl : options . CacheControl || 'no-cache' , Expires : options . Expires || null } ; if ( options . contentEncoding ) { putConfig . ContentEncoding = options . contentEncoding ; } oss . putObject ( putConfig , function ( putObjectErr ) { if ( putObjectErr ) { console . error ( 'error:' , putObjectErr ) ; return putObjectErr ; } console . log ( 'upload success: ' + localFilePath ) ; if ( bucketPaths . indexOf ( standerFilePath ) === - 1 ) { bucketPaths . push ( standerFilePath ) ; } if ( localPaths . indexOf ( standerFilePath ) === - 1 ) { localPaths . push ( standerFilePath ) ; } //refresh cdn if ( options . oss . autoRefreshCDN && cdn ) { if ( options . cdn . refreshQuota < 1 ) { console . error ( 'There is no refresh cdn url quota today.' ) ; return ; } let cdnDomain = '' ; if ( / ^http / . test ( options . cdn . domain ) ) { cdnDomain = options . cdn . domain . replace ( / ^https?:?\/?\/? / , '' ) ; options . cdn . secure === undefined && ( options . cdn . secure = / ^https / . test ( options . cdn . domein ) ) ; } else { cdnDomain = options . cdn . domain ; } let cdnObjectPath = url . format ( { protocol : options . oss . secure ? 'https' : 'http' , hostname : cdnDomain , pathname : standerFilePath } ) ; options . debug && console . log ( 'Refreshing CDN file: ' , cdnObjectPath ) ; cdn . refreshObjectCaches ( { ObjectType : 'File' , ObjectPath : cdnObjectPath } , function ( refreshCDNErr ) { if ( refreshCDNErr ) { console . error ( 'refresh cdn error: ' , refreshCDNErr ) ; } else { options . cdn . refreshQuota -- ; console . log ( 'Refresh cdn file success: ' , cdnObjectPath ) ; } } ) ; } } ) ; } ) ; }


Input: delete bucket file function [CODESPLIT] function ( filePath ) { let standerPath = filePath . replace ( / \\ / g , '/' ) ; oss . deleteObject ( { Bucket : bucket . Name , Key : standerPath } , function ( err ) { if ( err ) { console . log ( 'error:' , err ) ; return err ; } let bucketIndex = bucketPaths . indexOf ( standerPath ) ; if ( bucketIndex !== - 1 ) { bucketPaths . splice ( bucketIndex , 1 ) ; } let localIndex = localPaths . indexOf ( standerPath ) ; if ( localIndex !== - 1 ) { localPaths . splice ( localIndex , 1 ) ; } console . log ( 'delete success:' + standerPath ) ; } ) ; }


Input:
@class Runtime @extends Context [CODESPLIT] function Runtime ( unit , track , parent , args , done ) { // Create lite context to provide an interface to check execution parameters var context = new Context . Lite ( ) . // add default context params addParams ( unit . params ) . // add track's params addParams ( track . params ) . // add local args addParams ( args ) ; /**
     * Runtime identity is a part of cacheKey and memorization key
     *
     * @public
     * @memberOf {Runtime}
     * @property
     * @type {String}
     * */ this . identity = unit . identify ( track , context ) ; /**
     * Invoking unit
     *
     * @public
     * @memberOf {Runtime}
     * @property
     * @type {Unit}
     * */ this . unit = unit ; /**
     * Request handling runtime
     *
     * @public
     * @memberOf {Runtime}
     * @property
     * @type {Track}
     * */ this . track = track ; /**
     * The dependant Runtime
     *
     * @public
     * @memberOf {Runtime}
     * @property
     * @type {Runtime}
     * */ this . parent = parent ; /**
     * Finish listener
     *
     * @public
     * @memberOf {Runtime}
     * @property
     * @type {Function}
     * */ this . done = done ; /**
     * The number of dependencies remaining to resolve
     *
     * @public
     * @memberOf {Runtime}
     * @property
     * @type {Number}
     * */ this . pathsLeft = 0 ; /**
     * The array of dependency identities
     *
     * @public
     * @memberOf {Runtime}
     * @property
     * @type {Array}
     * */ this . keys = [ ] ; /**
     * @public
     * @memberOf {Runtime}
     * @property
     * @type {Date}
     * */ this . creationDate = 0 ; /**
     * @public
     * @memberOf {Runtime}
     * @property
     * @type {*}
     * */ this . value = undefined ; /**
     * The status of current runtime
     *
     * @public
     * @memberOf {Runtime}
     * @property
     * @type {Number}
     * */ this . statusBits = 0 ; /**
     * Runtime context
     *
     * @public
     * @memberOf {Runtime}
     * @property
     * @type {Context}
     * */ this . context = context ; /**
     * @public
     * @memberOf {Runtime}
     * @property
     * @type {Array<Runtime>}
     * */ this . listeners = [ ] ; /**
     * @public
     * @memberOf {Runtime}
     * @property
     * @type {String}
     * */ this . cacheKey = unit . app . params . name ; }


Input: Setup and return dispatch function . The dispatch function will call the relevant action handler . [CODESPLIT] function setupDispatch ( { actions : actionHandlers = { } , schemas = { } , services = { } , middlewares = [ ] , identOptions = { } } ) { const getService = setupGetService ( schemas , services ) let dispatch = async ( action ) => { debug ( 'Dispatch: %o' , action ) return handleAction ( action , { schemas , services , dispatch , identOptions , getService } , actionHandlers ) } if ( middlewares . length > 0 ) { dispatch = compose ( ... middlewares ) ( dispatch ) } return dispatch }


Input: Get next time for a schedule . Will never return the current time even if it is valid for the schedule unless allowNow is true . [CODESPLIT] function nextSchedule ( schedule , allowNow = false ) { if ( schedule ) { try { const dates = later . schedule ( schedule ) . next ( 2 ) return nextDate ( dates , allowNow ) } catch ( error ) { throw TypeError ( 'Invalid schedule definition' ) } } return null }


Input: Delete several items from a service based on the given payload . [CODESPLIT] async function deleteFn ( action , { getService } = { } ) { debug ( 'Action: DELETE' ) const { type , id , service : serviceId , endpoint } = action . payload const service = ( typeof getService === 'function' ) ? getService ( type , serviceId ) : null if ( ! service ) { return createUnknownServiceError ( type , serviceId , 'DELETE' ) } const data = prepareData ( action . payload ) if ( data . length === 0 ) { return createError ( ` ${ service . id } ` , 'noaction' ) } const endpointDebug = ( endpoint ) ? ` ${ endpoint } ` : ` ${ type } ${ id } ` debug ( 'DELETE: Delete from service \'%s\' at %s.' , service . id , endpointDebug ) const { response } = await service . send ( appendToAction ( action , { data } ) ) return ( response . status === 'ok' ) ? { status : 'ok' } : response }


Input: Normalize and map a request to an action and map and serialize its response . [CODESPLIT] async function request ( action , { getService , dispatch } ) { debug ( 'Action: REQUEST' ) const { type , service : serviceId = null , endpoint } = action . payload const service = getService ( type , serviceId ) if ( ! service ) { return createUnknownServiceError ( type , serviceId , 'GET' ) } const endpointDebug = ( endpoint ) ? ` ${ endpoint } ` : ` ${ type } ` debug ( 'REQUEST: Fetch from service %s at %s' , service . id , endpointDebug ) const { response } = await service . receive ( action , dispatch ) return response }


Input: Get an ident item from service based on the meta . ident object on the action . [CODESPLIT] async function getIdent ( { payload , meta } , { getService , identOptions = { } } ) { if ( ! meta . ident ) { return createError ( 'GET_IDENT: The request has no ident' , 'noaction' ) } const { type } = identOptions if ( ! type ) { return createError ( 'GET_IDENT: Integreat is not set up with authentication' , 'noaction' ) } const service = getService ( type ) if ( ! service ) { return createUnknownServiceError ( type , null , 'GET_IDENT' ) } const propKeys = preparePropKeys ( identOptions . props ) const params = prepareParams ( meta . ident , propKeys ) if ( ! params ) { return createError ( 'GET_IDENT: The request has no ident with id or withToken' , 'noaction' ) } const { response } = await service . send ( { type : 'GET' , payload : { type , ... params } , meta : { ident : { root : true } } } ) return prepareResponse ( response , payload , propKeys ) }


Input:
Return an Integreat instance with a dispatch method . Use the dispatch method for sending actions to services for retrieving typed items and updating data . [CODESPLIT] function integreat ( { schemas : typeDefs , services : serviceDefs , mappings = [ ] , auths : authDefs = [ ] , ident : identOptions = { } } , { adapters = { } , authenticators = { } , filters = { } , transformers = { } , actions = { } } = { } , middlewares = [ ] ) { if ( ! serviceDefs || ! typeDefs ) { throw new TypeError ( 'Call integreat with at least services and schemas' ) } // Merge custom actions with built-in actions actions = { ... builtinActions , ... actions } // Setup schemas object from type defs const schemas = R . compose ( R . indexBy ( R . prop ( 'id' ) ) , R . map ( schema ) ) ( typeDefs ) const pluralTypes = Object . keys ( schemas ) . reduce ( ( plurals , type ) => ( { ... plurals , [ schemas [ type ] . plural ] : type } ) , { } ) // Setup auths object from auth defs const auths = authDefs . reduce ( ( auths , def ) => ( def ) ? { ... auths , [ def . id ] : { authenticator : authenticators [ def && def . authenticator ] , options : def . options , authentication : null } } : auths , { } ) // Setup services object from service defs. const services = R . compose ( R . indexBy ( R . prop ( 'id' ) ) , R . map ( createService ( { adapters , auths , transformers , schemas , setupMapping : setupMapping ( { filters , transformers , schemas , mappings } ) } ) ) ) ( serviceDefs ) // Return Integreat instance return { version , schemas , services , identType : identOptions . type , /**
     * Function for dispatching actions to Integreat. Will be run through the
     * chain of middlewares before the relevant action handler is called.
     * @param {Object} action - The action to dispatch
     * @returns {Promise} Promise of result object
     */ dispatch : setupDispatch ( { actions , services , schemas , middlewares , identOptions } ) , /**
     * Adds the `listener` function to the service's emitter for events with the
     * given `eventName` name.
     */ on ( eventName , serviceId , listener ) { const service = services [ serviceId ] if ( service && service . on ) { service . on ( eventName , listener ) } } , /**
     * Return schema type from its plural form.
     */ typeFromPlural ( plural ) { return pluralTypes [ plural ] } } }


Input: Create a queuable action from a schedule definition . [CODESPLIT] function scheduleToAction ( def ) { if ( ! def ) { return null } const id = def . id || null const schedule = parseSchedule ( def . schedule ) const nextTime = nextSchedule ( schedule , true ) return { ... def . action , meta : { id , schedule , queue : ( nextTime ) ? nextTime . getTime ( ) : true } } }


Input: Authorize data in Integreat s internal data format according to the setting of the relevant schema ( s ) . The provided access object may be coming from authorizeRequest () and if this is refused already this method will refuse right away . [CODESPLIT] function authorizeItem ( item , access , { schemas , action , requireAuth } ) { const { ident , status } = access if ( status === 'refused' ) { return false } if ( ! item || ( ident && ident . root ) ) { return true } const schema = schemas [ item . type ] const scheme = getScheme ( schema , action ) return authorizeWithScheme ( item , scheme , ident , requireAuth ) }


Input: Get several items from a service based on the given action object . [CODESPLIT] async function get ( action , { getService } = { } ) { const { type , service : serviceId = null , onlyMappedValues = false , endpoint } = action . payload const service = ( typeof getService === 'function' ) ? getService ( type , serviceId ) : null if ( ! service ) { return createUnknownServiceError ( type , serviceId , 'GET' ) } const id = getIdFromPayload ( action . payload ) // Do individual gets for array of ids, if there is no collection scoped endpoint if ( Array . isArray ( id ) && ! hasCollectionEndpoint ( service . endpoints ) ) { return getIndividualItems ( id , action , getService ) } const endpointDebug = ( endpoint ) ? ` ${ endpoint } ` : ` ${ type } ${ id } ` debug ( 'GET: Fetch from service %s at %s' , service . id , endpointDebug ) const { response } = await service . send ( appendToAction ( action , { id , onlyMappedValues } ) ) return response }


Input: Send the request with the adapter and return the response . Will serialize any data in the request and normalize any data in the response . The access object on the request must have status granted and will be returned on the response object . [CODESPLIT] function sendRequest ( { adapter , serviceId } ) { return async ( { request , response , connection } ) => { if ( response ) { return response } try { response = await adapter . send ( request , connection ) return { ... response , access : request . access } } catch ( error ) { return createError ( ` ${ serviceId } ${ error } ` ) } } }


Input:
Create a schema with the given id and service . [CODESPLIT] function schema ( { id , plural , service , attributes : attrDefs , relationships : relDefs , access , internal = false } ) { const attributes = { ... expandFields ( attrDefs || { } ) , id : { type : 'string' } , type : { type : 'string' } , createdAt : { type : 'date' } , updatedAt : { type : 'date' } } const relationships = expandFields ( relDefs || { } ) const defaultAttrs = prepareDefaultAttrs ( attributes , attrDefs ) const defaultRels = prepareDefaultRels ( relationships , relDefs ) const castFn = cast ( { id , attributes , relationships , defaultAttrs , defaultRels } ) return { id , plural : plural || ` ${ id } ` , service , internal , attributes , relationships , access , /**
     * Will cast the given data according to the type. Attributes will be
     * coerced to the right format, relationships will be expanded to
     * relationship objects, and object properties will be moved from
     * `attributes` or be set with defaults.
     * @param {Object} data - The data to cast
     * @param {boolean} onlyMappedValues - Will use defaults if true
     * @returns {Object} Returned data in the format expected from the schema
     */ cast ( data , { onlyMappedValues = false } = { } ) { return mapAny ( ( data ) => castFn ( data , { onlyMappedValues } ) , data ) } , /**
     * Will create a query object for a relationship, given the relationship id
     * and a data item to get field values from.
     *
     * If the relationship is set up with a query definition object, each prop
     * of this object references field ids in the given data item. The returned
     * query object will have these ids replaced with actual field values.
     *
     * @param {string} relId - The id of a relationship
     * @param {Object} data - A data item to get field values from.
     * @returns {Object} Query object
     */ castQueryParams ( relId , data ) { return castQueryParams ( relId , data , { relationships } ) } } }


Input:
Return item mapper object with fromService and toService . [CODESPLIT] function mapping ( { filters , transformers , schemas = { } , mappings : mappingsArr = [ ] } = { } ) { const mappings = mappingsArr . reduce ( ( mappings , def ) => ( { ... mappings , [ def . id ] : def } ) , { } ) const createPipelineFn = createPipeline ( filters , transformers , schemas , mappings ) return ( mapping , overrideType ) => { const { id , type , schema , pipeline } = createPipelineFn ( mapping , overrideType ) if ( ! pipeline ) { return null } const mapper = mapTransform ( [ fwd ( 'data' ) , ... pipeline , rev ( set ( 'data' ) ) ] ) return { id , type , schema , /**
       * Map data from a service with attributes and relationships.
       * @param {Object} data - The service item to map from
       * @param {Object} options - onlyMappedValues
       * @returns {Object} Target item
       */ fromService ( data , { onlyMappedValues = true } = { } ) { return data ? ensureArray ( ( onlyMappedValues ) ? mapper . onlyMappedValues ( data ) : mapper ( data ) ) : [ ] } , /**
       * Map data to a service with attributes and relationships.
       * @param {Object} data - The data item to map
       * @param {Object} target - Optional object to map to data on
       * @returns {Object} Mapped data
       */ toService ( data , target = null ) { const mapped = mapper . rev . onlyMappedValues ( data ) return ( ( target ? Array . isArray ( target ) ? [ ... target ] . concat ( mapped ) : mergeDeepWith ( concatOrRight , target , mapped ) : mapped ) || null ) } } } }


Input: Map the data going _to_ the service . Everything is handled by the mappings but this method make sure that the right types are mapped . [CODESPLIT] function mapFromService ( ) { return ( { response , request , responseMapper , mappings } ) => { if ( response . status !== 'ok' ) { return response } const type = request . params . type || Object . keys ( mappings ) const { onlyMappedValues , unmapped = false } = request . params if ( unmapped ) { return response } const { data , status = response . status , error , paging , params } = mapWithEndpoint ( responseMapper , response , request . action ) if ( status !== 'ok' ) { return removeDataProp ( { ... response , status , error } ) } const mapType = ( type ) => ( mappings [ type ] ) ? mappings [ type ] . fromService ( { ... request , data } , { onlyMappedValues } ) : [ ] return { ... response , status , ... ( ( paging ) ? { paging } : { } ) , ... ( ( params ) ? { params } : { } ) , data : ( data ) ? flatten ( mapAny ( mapType , type ) ) : undefined } } }


Input: this emits the data events on the watcher emitter for all fds [CODESPLIT] function ( tailInfo ) { var z = this ; if ( tailInfo ) { z . q . push ( tailInfo ) ; } var ti ; //for all changed fds fire readStream for ( var i = 0 ; i < z . q . length ; ++ i ) { ti = z . q [ i ] ; if ( ti . reading ) { //still reading file continue ; } if ( ! z . tails [ ti . stat . ino ] ) { //remove timed out file tail from q z . q . splice ( i , 1 ) ; -- i ; continue ; } //truncated if ( ti . stat . size < ti . pos ) { ti . pos = 0 ; } var len = ti . stat . size - ti . pos ; //remove from queue because im doing this work. z . q . splice ( i , 1 ) ; -- i ; z . readTail ( ti , len ) ; } }


Input: return the total line buffer length from all active tails [CODESPLIT] function ( ) { var z = this ; var l = 0 ; Object . keys ( z . tails ) . forEach ( function ( k ) { l += ( z . tails [ k ] . buf || '' ) . length ; } ) ; return l ; }


Input: Prepare pipeline by replacing keys with functions or function objects from the collection object and remove anything that is not functions or function objects . [CODESPLIT] function preparePipeline ( pipeline , collection = { } ) { pipeline = [ ] . concat ( pipeline ) const replaceWithFunction = ( key ) => ( typeof key === 'string' ) ? collection [ key ] : key const isFunctionOrObject = ( obj ) => obj && [ 'function' , 'object' ] . includes ( typeof obj ) return pipeline . map ( replaceWithFunction ) . filter ( isFunctionOrObject ) }


Input: Prepare reverse pipeline by either running the revPipeline through the regular preparePipeline () or – if revPipeline is not set - pick . rev () functions from the fwdPipeline . [CODESPLIT] function prepareRevPipeline ( revPipeline , fwdPipeline , collection ) { return ( revPipeline ) ? preparePipeline ( revPipeline , collection ) : fwdPipeline . map ( ( fn ) => ( fn . rev ) ? fn . rev : null ) . filter ( Boolean ) }


Input: Cast query params according to type [CODESPLIT] function castQueryParams ( relId , data , { relationships } ) { const relationship = relationships [ relId ] if ( ! relationship . query ) { return { } } return Object . keys ( relationship . query ) . reduce ( ( params , key ) => { const value = getField ( data , relationship . query [ key ] ) if ( value === undefined ) { throw new TypeError ( 'Missing value for query param' ) } return { ... params , [ key ] : value } } , { } ) }


Input:
Set up Integreat queue interface . [CODESPLIT] function setupQueue ( queue ) { let dispatch = null let subscribed = false return { queue , /**
     * Set dispatch function to use for dequeuing
     */ setDispatch ( dispatchFn ) { dispatch = dispatchFn if ( ! subscribed && typeof dispatch === 'function' ) { queue . subscribe ( dispatch ) subscribed = true } } , /**
     * Middleware interface for Integreat. Will push queuable actions to queue,
     * and pass the rest on to the next() function.
     *
     * @param {function} next - The next middleware
     * @returns {Object} A response object
     */ middleware ( next ) { return middleware ( next , queue ) } , /**
     * Schedule actions from the given defs.
     * Actions are enqueued with a timestamp, and are ran at the
     * set time.
     * @param {array} defs - An array of schedule definitions
     * @returns {array} Array of returned responses
     */ async schedule ( defs ) { return schedule ( defs , queue ) } } }


Input: Get metadata for a service based on the given action object . [CODESPLIT] async function getMeta ( { payload , meta } , { getService } ) { debug ( 'Action: GET_META' ) const { service : serviceId , endpoint , keys } = payload const id = ` ${ serviceId } ` const service = getService ( null , serviceId ) if ( ! service ) { debug ( ` ${ serviceId } ` ) return createError ( ` ${ serviceId } ` ) } const type = service . meta const metaService = getService ( type ) if ( ! metaService ) { return createError ( ` ${ service . id } ${ service . meta } ` ) } const endpointDebug = ( endpoint ) ? ` ${ endpoint } ` : ` ${ type } ${ id } ` debug ( 'GET_META: Get meta %s for service \'%s\' on service \'%s\' at %s' , keys , service . id , metaService . id , endpointDebug ) const { response } = await metaService . send ( { type : 'GET' , payload : { keys , type , id , endpoint } , meta : { ident : meta . ident } } ) if ( response . status === 'ok' ) { const { data } = response const meta = prepareMeta ( keys , data [ 0 ] . attributes ) return { ... response , data : { service : serviceId , meta } } } else { return response } }


Input: Set several items to a service based on the given action object . [CODESPLIT] async function set ( action , { getService , schemas } ) { debug ( 'Action: SET' ) const { service : serviceId , data , endpoint , onlyMappedValues = true } = action . payload const type = extractType ( action , data ) const id = extractId ( data ) const service = getService ( type , serviceId ) if ( ! service ) { return createUnknownServiceError ( type , serviceId , 'SET' ) } const endpointDebug = ( endpoint ) ? ` ${ endpoint } ` : '' debug ( 'SET: Send to service %s %s' , service . id , endpointDebug ) const { response , authorizedRequestData } = await service . send ( appendToAction ( action , { id , type , onlyMappedValues } ) ) return mergeRequestAndResponseData ( response , authorizedRequestData ) }


Input: Cast item [CODESPLIT] function cast ( { id , attributes , relationships , defaultAttrs , defaultRels } ) { return ( data , { onlyMappedValues } ) => { if ( ! data ) { return undefined } const attrs = castAttributes ( data . attributes , attributes , ( onlyMappedValues ) ? { } : { ... defaultAttrs } ) if ( ! onlyMappedValues ) { setDates ( attrs ) } const rels = castRelationships ( data . relationships , relationships , ( onlyMappedValues ) ? { } : { ... defaultRels } ) const castId = data . id || attrs . id || uuid ( ) delete attrs . id const casted = { id : castId , type : id , attributes : attrs , relationships : rels } if ( data . isNew ) { casted . isNew = true } if ( data . isDeleted ) { casted . isDeleted = true } return casted } }


Input: Set metadata on a service based on the given action object . [CODESPLIT] async function setMeta ( { payload , meta } , { getService } ) { debug ( 'Action: SET_META' ) const { service : serviceId , meta : metaAttrs , endpoint } = payload const id = ` ${ serviceId } ` const service = getService ( null , serviceId ) if ( ! service ) { debug ( ` ${ serviceId } ` ) return createError ( ` ${ serviceId } ` ) } const type = service . meta const metaService = getService ( type ) if ( ! metaService ) { debug ( ` ${ service . id } ${ service . meta } ` ) return { status : 'noaction' } } const endpointDebug = ( endpoint ) ? ` ${ endpoint } ` : ` ${ type } ${ id } ` debug ( 'SET_META: Send metadata %o for service \'%s\' on service \'%s\' %s' , metaAttrs , service . id , metaService . id , endpointDebug ) const data = { id , type , attributes : metaAttrs } const { response } = await metaService . send ( { type : 'SET' , payload : { keys : Object . keys ( metaAttrs ) , type , id , data , endpoint , onlyMappedValues : true } , meta : { ident : meta . ident } } ) return response }


Input: Converts a group of specifications into JSON Schema . [CODESPLIT] function exportToJSONSchema ( expSpecifications , baseSchemaURL , baseTypeURL , flat = false ) { const namespaceResults = { } ; const endOfTypeURL = baseTypeURL [ baseTypeURL . length - 1 ] ; if ( endOfTypeURL !== '#' && endOfTypeURL !== '/' ) { baseTypeURL += '/' ; } for ( const ns of expSpecifications . namespaces . all ) { const lastLogger = logger ; logger = logger . child ( { shrId : ns . namespace } ) ; try { logger . debug ( 'Exporting namespace.' ) ; if ( flat ) { const { schemaId , schema } = flatNamespaceToSchema ( ns , expSpecifications . dataElements , baseSchemaURL , baseTypeURL ) ; namespaceResults [ schemaId ] = schema ; } else { const { schemaId , schema } = namespaceToSchema ( ns , expSpecifications . dataElements , baseSchemaURL , baseTypeURL ) ; namespaceResults [ schemaId ] = schema ; } logger . debug ( 'Finished exporting namespace.' ) ; } finally { logger = lastLogger ; } } return namespaceResults ; }


Input: Converts a namespace into a JSON Schema . [CODESPLIT] function namespaceToSchema ( ns , dataElementsSpecs , baseSchemaURL , baseTypeURL ) { const dataElements = dataElementsSpecs . byNamespace ( ns . namespace ) ; const schemaId = ` ${ baseSchemaURL } ${ namespaceToURLPathSegment ( ns . namespace ) } ` ; let schema = { $schema : 'http://json-schema.org/draft-04/schema#' , id : schemaId , title : "TODO: Figure out what the title should be." , definitions : { } } ; const entryRef = makeRef ( new Identifier ( 'shr.base' , 'Entry' ) , ns , baseSchemaURL ) ; if ( ns . description ) { schema . description = ns . description ; } const nonEntryEntryTypeField = { $ref : makeRef ( new Identifier ( 'shr.base' , 'EntryType' ) , ns , baseSchemaURL ) } ; const defs = dataElements . sort ( function ( l , r ) { return l . identifier . name . localeCompare ( r . identifier . name ) ; } ) ; const entryRefs = [ ] ; for ( const def of defs ) { const lastLogger = logger ; logger = logger . child ( { shrId : def . identifier . fqn } ) ; try { logger . debug ( 'Exporting element' ) ; let schemaDef = { type : 'object' , properties : { } } ; let wholeDef = schemaDef ; const tbdParentDescriptions = [ ] ; let requiredProperties = [ ] ; let needsEntryType = false ; if ( def . isEntry || def . basedOn . length ) { wholeDef = { allOf : [ ] } ; let hasEntryParent = false ; for ( const supertypeId of def . basedOn ) { if ( supertypeId instanceof TBD ) { if ( supertypeId . text ) { tbdParentDescriptions . push ( supertypeId . text ) ; } else { tbdParentDescriptions . push ( 'TBD' ) ; } } else { const parent = dataElementsSpecs . findByIdentifier ( supertypeId ) ; if ( ! parent ) { logger . error ( 'Could not find definition for %s which is a supertype of %s' , supertypeId , def ) ; } else { hasEntryParent = hasEntryParent || parent . isEntry ; } wholeDef . allOf . push ( { $ref : makeRef ( supertypeId , ns , baseSchemaURL ) } ) ; } } if ( def . isEntry && ( ! hasEntryParent ) ) { wholeDef . allOf . splice ( 0 , 0 , { $ref : entryRef } ) ; } wholeDef . allOf . push ( schemaDef ) ; } else { needsEntryType = true ; } const tbdFieldDescriptions = [ ] ; if ( def . value ) { if ( def . value . inheritance !== INHERITED ) { let { value , required , tbd } = convertDefinition ( def . value , dataElementsSpecs , ns , baseSchemaURL , baseTypeURL ) ; if ( required ) { requiredProperties . push ( 'Value' ) ; } schemaDef . properties . Value = value ; if ( tbd ) { schemaDef . properties . Value . description = def . value . text ? ( 'TBD: ' + def . value . text ) : tbdValueToString ( def . value ) ; } } } if ( def . fields . length ) { const fieldNameMap = { } ; const clashingNames = { } ; for ( const field of def . fields ) { if ( ! ( field instanceof TBD ) ) { if ( ! isValidField ( field ) ) { continue ; } else if ( field . inheritance === INHERITED ) { if ( fieldNameMap [ field . identifier . name ] ) { logger . error ( ` ` , fieldNameMap [ field . identifier . name ] . fqn , field . identifier . fqn ) ; clashingNames [ field . identifier . name ] = true ; } else { fieldNameMap [ field . identifier . name ] = field . identifier ; } continue ; } if ( fieldNameMap [ field . identifier . name ] ) { logger . error ( ` ` , fieldNameMap [ field . identifier . name ] . fqn , field . identifier . fqn ) ; clashingNames [ field . identifier . name ] = true ; continue ; } else { fieldNameMap [ field . identifier . name ] = field . identifier ; } } const card = field . effectiveCard ; if ( card && card . isZeroedOut ) { continue ; } let { value , required , tbd } = convertDefinition ( field , dataElementsSpecs , ns , baseSchemaURL , baseTypeURL ) ; if ( tbd ) { tbdFieldDescriptions . push ( tbdValueToString ( field ) ) ; continue ; } if ( field . identifier . fqn === 'shr.base.EntryType' ) { needsEntryType = false ; } schemaDef . properties [ field . identifier . name ] = value ; if ( required ) { requiredProperties . push ( field . identifier . name ) ; } } for ( const clashingName in clashingNames ) { delete schemaDef . properties [ clashingName ] ; } requiredProperties = requiredProperties . filter ( propName => ! ( propName in clashingNames ) ) ; } else if ( ! def . value ) { schemaDef . type = 'object' ; schemaDef . description = 'Empty DataElement?' ; } let descriptionList = [ ] ; if ( def . description ) { descriptionList . push ( def . description ) ; } if ( def . concepts . length ) { wholeDef . concepts = def . concepts . map ( ( concept ) => makeConceptEntry ( concept ) ) ; } if ( tbdParentDescriptions . length ) { tbdParentDescriptions [ 0 ] = 'TBD Parents: ' + tbdParentDescriptions [ 0 ] ; descriptionList = descriptionList . concat ( tbdParentDescriptions ) ; } if ( tbdFieldDescriptions . length ) { tbdFieldDescriptions [ 0 ] = 'TBD Fields: ' + tbdFieldDescriptions [ 0 ] ; descriptionList = descriptionList . concat ( tbdFieldDescriptions ) ; } if ( descriptionList . length ) { wholeDef . description = descriptionList . join ( '\n' ) ; } if ( needsEntryType ) { schemaDef . properties [ 'EntryType' ] = nonEntryEntryTypeField ; if ( def . identifier . fqn !== 'shr.base.EntryType' ) { requiredProperties . push ( 'EntryType' ) ; } } if ( requiredProperties . length ) { schemaDef . required = requiredProperties ; } schema . definitions [ def . identifier . name ] = wholeDef ; if ( def . isEntry && ( ! def . isAbstract ) ) { entryRefs . push ( { $ref : makeRef ( def . identifier , ns , baseSchemaURL ) } ) ; } } finally { logger = lastLogger ; } } if ( entryRefs . length ) { schema . type = 'object' ; schema . anyOf = entryRefs ; } return { schemaId , schema } ; }


Input: Converts a namespace into a flat JSON Schema . [CODESPLIT] function flatNamespaceToSchema ( ns , dataElementsSpecs , baseSchemaURL , baseTypeURL ) { const dataElements = dataElementsSpecs . byNamespace ( ns . namespace ) ; const schemaId = ` ${ baseSchemaURL } ${ namespaceToURLPathSegment ( ns . namespace ) } ` ; let schema = { $schema : 'http://json-schema.org/draft-04/schema#' , id : schemaId , title : "TODO: Figure out what the title should be." , definitions : { } } ; const expandedEntry = makeExpandedEntryDefinitions ( ns , baseSchemaURL ) ; if ( ns . description ) { schema . description = ns . description ; } const defs = dataElements . sort ( function ( l , r ) { return l . identifier . name . localeCompare ( r . identifier . name ) ; } ) ; const entryRefs = [ ] ; for ( const def of defs ) { let schemaDef = { type : 'object' , properties : { } } ; let wholeDef = schemaDef ; const tbdParentDescriptions = [ ] ; let requiredProperties = [ ] ; if ( def . isEntry ) { requiredProperties = expandedEntry . required . slice ( ) ; } const tbdFieldDescriptions = [ ] ; if ( def . value ) { let { value , required , tbd } = convertDefinition ( def . value , dataElementsSpecs , ns , baseSchemaURL , baseTypeURL ) ; if ( required ) { requiredProperties . push ( 'Value' ) ; } schemaDef . properties . Value = value ; if ( tbd ) { schemaDef . properties . Value . description = def . value . text ? ( 'TBD: ' + def . value . text ) : tbdValueToString ( def . value ) ; } } if ( def . fields . length ) { for ( const field of def . fields ) { if ( ! ( field instanceof TBD ) && ! isValidField ( field ) ) { continue ; } const card = field . effectiveCard ; if ( card && card . isZeroedOut ) { continue ; } let { value , required , tbd } = convertDefinition ( field , dataElementsSpecs , ns , baseSchemaURL , baseTypeURL ) ; if ( tbd ) { tbdFieldDescriptions . push ( tbdValueToString ( field ) ) ; continue ; } const fieldName = field . identifier . name ; schemaDef . properties [ fieldName ] = value ; if ( required && ( requiredProperties . indexOf ( fieldName ) === - 1 ) ) { requiredProperties . push ( fieldName ) ; } } if ( def . isEntry ) { for ( const name in expandedEntry . properties ) { if ( ! ( name in schemaDef . properties ) ) { schemaDef . properties [ name ] = expandedEntry . properties [ name ] ; } } } } else if ( ! def . value ) { schemaDef . type = 'object' ; schemaDef . description = 'Empty DataElement?' ; } let descriptionList = [ ] ; if ( def . description ) { descriptionList . push ( def . description ) ; } if ( def . concepts . length ) { wholeDef . concepts = def . concepts . map ( ( concept ) => makeConceptEntry ( concept ) ) ; } if ( tbdParentDescriptions . length ) { tbdParentDescriptions [ 0 ] = 'TBD Parents: ' + tbdParentDescriptions [ 0 ] ; descriptionList = descriptionList . concat ( tbdParentDescriptions ) ; } if ( tbdFieldDescriptions . length ) { tbdFieldDescriptions [ 0 ] = 'TBD Fields: ' + tbdFieldDescriptions [ 0 ] ; descriptionList = descriptionList . concat ( tbdFieldDescriptions ) ; } if ( descriptionList . length ) { wholeDef . description = descriptionList . join ( '\n' ) ; } if ( requiredProperties . length ) { schemaDef . required = requiredProperties ; } schema . definitions [ def . identifier . name ] = wholeDef ; if ( def . isEntry && ( ! def . isAbstract ) ) { entryRefs . push ( { $ref : makeRef ( def . identifier , ns , baseSchemaURL ) } ) ; } } if ( entryRefs . length ) { schema . type = 'object' ; schema . anyOf = entryRefs ; } return { schemaId , schema } ; }


Input: Create a JSON Schema reference to the specified type . [CODESPLIT] function makeRef ( id , enclosingNamespace , baseSchemaURL ) { if ( id . namespace === enclosingNamespace . namespace ) { return '#/definitions/' + id . name ; } else { return makeShrDefinitionURL ( id , baseSchemaURL ) ; } }


Input: Translates a constraint path into a valid path for the JSON Schema . [CODESPLIT] function extractConstraintPath ( constraint , valueDef , dataElementSpecs ) { if ( constraint . onValue ) { return extractUnnormalizedConstraintPath ( constraint , valueDef , dataElementSpecs ) ; } else if ( constraint . path . length > 0 && constraint . path [ constraint . path . length - 1 ] . isValueKeyWord ) { // Essentially the same as above, when onValue is never checked again, so just chop it off // treat it like above.  TODO: Determine if this is really the right approach. const simpleConstraint = constraint . clone ( ) ; simpleConstraint . path = simpleConstraint . path . slice ( 0 , simpleConstraint . path . length - 1 ) ; return extractUnnormalizedConstraintPath ( simpleConstraint , valueDef , dataElementSpecs ) ; } if ( ! constraint . hasPath ( ) ) { return { path : [ ] } ; } let currentDef = dataElementSpecs . findByIdentifier ( valueDef . effectiveIdentifier ) ; const normalizedPath = [ ] ; let target = null ; for ( let i = 0 ; i < constraint . path . length ; i += 1 ) { const pathId = constraint . path [ i ] ; target = null ; if ( pathId . namespace === PRIMITIVE_NS ) { if ( i !== constraint . path . length - 1 ) { logger . error ( 'Encountered a constraint path containing a primitive %s at index %d that was not the leaf: %s' , pathId , i , constraint . toString ( ) ) ; return { } ; } if ( ! currentDef . value ) { logger . error ( 'Encountered a constraint path with a primitive leaf %s on an element that lacked a value: %s' , pathId , constraint . toString ( ) ) ; return { } ; } if ( currentDef . value instanceof ChoiceValue ) { target = findOptionInChoice ( currentDef . value , pathId , dataElementSpecs ) ; if ( ! target ) { logger . error ( 'Encountered a constraint path with a primitive leaf %s on an element with a mismatched value: %s on valueDef %s' , pathId , constraint . toString ( ) , valueDef . toString ( ) ) ; return { } ; } } else if ( ! pathId . equals ( currentDef . value . identifier ) ) { logger . error ( 'Encountered a constraint path with a primitive leaf %s on an element with a mismatched value: %s on valueDef %s' , pathId , constraint . toString ( ) , valueDef . toString ( ) ) ; return { } ; } else { target = currentDef . value ; } normalizedPath . push ( 'Value' ) ; } else { const newDef = dataElementSpecs . findByIdentifier ( pathId ) ; if ( ! newDef ) { logger . error ( 'Cannot resolve element definition for %s on constraint %s. ERROR_CODE:12029' , pathId , constraint . toString ( ) ) ; return { } ; } // See if the current definition has a value of the specified type. if ( currentDef . value ) { if ( currentDef . value instanceof ChoiceValue ) { target = findOptionInChoice ( currentDef . value , pathId , dataElementSpecs ) ; } else if ( pathId . equals ( currentDef . value . identifier ) || checkHasBaseType ( currentDef . value . identifier , pathId , dataElementSpecs ) ) { target = currentDef . value ; normalizedPath . push ( 'Value' ) ; } } if ( ! target ) { if ( ! currentDef . fields || ! currentDef . fields . length ) { logger . error ( 'Element %s lacked any fields or a value that matched %s as part of constraint %s' , currentDef . identifier . fqn , pathId , constraint . toString ( ) ) ; return { } ; } else { target = currentDef . fields . find ( ( field ) => pathId . equals ( field . identifier ) ) ; if ( ! target ) { // It's possible that the field is actually defined as an "includes type" constraint on a list. // In this case, do nothing, because right now there isn't a valid way to represent further constraints // on includesType elements in the schema. if ( valueDef . constraintsFilter . includesType . constraints . some ( c => c . isA . equals ( pathId ) ) ) { logger . warn ( 'Cannot enforce constraint %s on Element %s since %s refers to an type introduced by an "includesType" constraint' , constraint . toString ( ) , currentDef . identifier . fqn , pathId ) ; } else { logger . error ( 'Element %s lacked a field or a value that matched %s as part of constraint %s' , currentDef . identifier . fqn , pathId , constraint . toString ( ) ) ; } return { } ; } normalizedPath . push ( pathId . name ) ; } } currentDef = newDef ; } } return { path : normalizedPath , target } ; }


Input: Converts a concept into a code entry for the schema . ( Codes are also represented as Concepts in the object model . ) [CODESPLIT] function makeConceptEntry ( concept ) { if ( concept instanceof TBD ) { const ret = { code : 'TBD' , codeSystem : 'urn:tbd' } ; if ( concept . text ) { ret . displayText = concept . text ; } return ret ; } else { const ret = { code : concept . code , codeSystem : concept . system } ; if ( concept . display ) { ret . displayText = concept . display ; } return ret ; } }


Input: Determine if a value or one of its ancestors is or was a list . [CODESPLIT] function isOrWasAList ( value ) { if ( value . card . isList ) { return true ; } const cardConstraints = value . constraintsFilter . own . card . constraints ; return cardConstraints . some ( ( oneCard ) => oneCard . isList ) ; }


Input: Searches the aggregate options of a choice for the specified option . [CODESPLIT] function findOptionInChoice ( choice , optionId , dataElementSpecs ) { // First look for a direct match for ( const option of choice . aggregateOptions ) { if ( optionId . equals ( option . identifier ) ) { return option ; } } // Then look for a match on one of the selected options's base types // E.g., if choice has Quantity but selected option is IntegerQuantity for ( const option of choice . aggregateOptions ) { if ( checkHasBaseType ( optionId , option . identifier , dataElementSpecs ) ) { return option ; } } return null ; }


Input: stealing from shr - expand Determine if a type supports a code constraint . [CODESPLIT] function supportsCodeConstraint ( identifier , dataElementSpecs ) { if ( CODE . equals ( identifier ) || checkHasBaseType ( identifier , new Identifier ( 'shr.core' , 'Coding' ) , dataElementSpecs ) || checkHasBaseType ( identifier , new Identifier ( 'shr.core' , 'CodeableConcept' ) , dataElementSpecs ) ) { return true ; } const element = dataElementSpecs . findByIdentifier ( identifier ) ; if ( element . value ) { if ( element . value instanceof IdentifiableValue ) { return CODE . equals ( element . value . identifier ) || checkHasBaseType ( element . value . identifier , new Identifier ( 'shr.core' , 'Coding' ) , dataElementSpecs ) || checkHasBaseType ( element . value . identifier , new Identifier ( 'shr.core' , 'CodeableConcept' ) , dataElementSpecs ) ; } else if ( element . value instanceof ChoiceValue ) { for ( const value of element . value . aggregateOptions ) { if ( value instanceof IdentifiableValue ) { if ( CODE . equals ( value . identifier ) || checkHasBaseType ( value . identifier , new Identifier ( 'shr.core' , 'Coding' ) , dataElementSpecs ) || checkHasBaseType ( value . identifier , new Identifier ( 'shr.core' , 'CodeableConcept' ) , dataElementSpecs ) ) { return true ; } } } } } return false ; }


Input: Action to delete expired items . [CODESPLIT] async function expire ( { payload , meta = { } } , { dispatch } ) { const { service } = payload const { ident } = meta if ( ! service ) { return createError ( ` ` ) } if ( ! payload . endpoint ) { return createError ( ` ${ service } ` ) } if ( ! payload . type ) { return createError ( ` ${ service } ` ) } const response = await getExpired ( payload , ident , dispatch ) return deleteExpired ( response , service , ident , dispatch ) }


Input: All Operations implement the same Interface : [CODESPLIT] function Set ( target , attribute , value ) { this . type = 'Set' this . target = target this . attribute = attribute this . value = value this . hasEffect = true // Can become effectless upon transformation }


Input: Name operation [CODESPLIT] function Name ( name , action , val ) { this . type = 'Name' this . name = name this . action = action this . value = val }


Input: Utility functions [CODESPLIT] function parseCell ( cell ) { var match = cell . match ( / ([a-z]+)([0-9]+) / i ) if ( ! match ) throw new Error ( 'invalid cell id ' + cell ) return [ column . fromStr ( match [ 1 ] ) , parseInt ( match [ 2 ] ) ] }


Input: Transforms a range against an array of ops [CODESPLIT] function transformRange ( range , ops ) { var rangeComps = range . split ( ':' ) , newRange var start = rangeComps [ 0 ] ops . forEach ( op => start = transformRangeAnchor ( start , op , /*isStart:*/ true ) ) var end = rangeComps [ 1 ] ops . forEach ( op => end = transformRangeAnchor ( end , op , /*isStart:*/ false ) ) if ( start === end ) return start return start + ':' + end }


Input: Transforms a range anchor taking into account whether it s the start or end [CODESPLIT] function transformRangeAnchor ( target , op , isStart ) { var thisCell = parseCell ( target ) if ( op instanceof InsertCol ) { var otherCell = parseCell ( op . newCol ) if ( otherCell [ 0 ] <= thisCell [ 0 ] ) return column . fromInt ( thisCell [ 0 ] + 1 ) + thisCell [ 1 ] } else if ( op instanceof DeleteCol ) { var otherCell = parseCell ( op . col ) if ( otherCell [ 0 ] < thisCell [ 0 ] ) return column . fromInt ( thisCell [ 0 ] - 1 ) + thisCell [ 1 ] if ( otherCell [ 0 ] === thisCell [ 0 ] ) { // Spreadsheet selection is different from text selection: // While text selection ends in the first *not* selected char ( "foo| |bar" => 3,4) // ... spreadsheet selection ends in the last selected cell. Thus we need to // differentiate between start and end. Shame on those who didn't think about this! if ( ! isStart ) return column . fromInt ( thisCell [ 0 ] - 1 ) + thisCell [ 1 ] } } else if ( op instanceof InsertRow ) { var otherCell = parseCell ( op . newRow ) if ( otherCell [ 1 ] <= thisCell [ 1 ] ) return column . fromInt ( thisCell [ 0 ] ) + ( thisCell [ 1 ] + 1 ) } else if ( op instanceof DeleteRow ) { var otherCell = parseCell ( op . col ) if ( otherCell [ 1 ] < thisCell [ 1 ] ) return column . fromInt ( thisCell [ 0 ] ) + ( thisCell [ 1 ] - 1 ) if ( otherCell [ 1 ] === thisCell [ 1 ] ) { if ( ! isStart ) return column . fromInt ( thisCell [ 0 ] ) + ( thisCell [ 1 ] - 1 ) } } // If nothing has returned already then this anchor doesn't change return target }


Input: Return the first matching endpoint from an array of endpoints that has already been sortert with higher specificity first . Type should match before scope which should match before action but the order here is taken care of by the required sorting . [CODESPLIT] function matchEndpoint ( endpoints ) { return ( { type , payload , meta } ) => endpoints . find ( ( endpoint ) => matchId ( endpoint , { type , payload } ) && matchType ( endpoint , { type , payload } ) && matchScope ( endpoint , { type , payload } ) && matchAction ( endpoint , { type , payload } ) && matchParams ( endpoint , { type , payload } ) && matchFilters ( endpoint , { type , payload , meta } ) ) }


Input: Create an action object . [CODESPLIT] function createAction ( type , payload = { } , meta ) { if ( ! type ) { return null } const action = { type , payload } if ( meta ) { action . meta = meta } return action }


Input: Authorize the request according to the setting on the relevant schema . Sets the access object with status property specifying whether access is granted or refused and returns the request . [CODESPLIT] function authorizeRequest ( { schemas } ) { return ( { request } ) => { const { access = { } , params = { } , action } = request const { ident = null } = access if ( ident && ident . root ) { return authItemsAndWrap ( request , { status : 'granted' , ident , scheme : 'root' } , schemas ) } if ( ! params . type ) { return authItemsAndWrap ( request , { status : 'granted' , ident , scheme : null } , schemas ) } const requireAuth = ! ! request . auth const schema = schemas [ params . type ] const scheme = getScheme ( schema , action ) const status = ( doAuth ( scheme , ident , requireAuth ) ) ? 'granted' : 'refused' return authItemsAndWrap ( request , { status , ident , scheme } , schemas ) } }


Input: Complete missing props and allow only expected props on the request object . [CODESPLIT] function requestFromAction ( { type : action , payload , meta = { } } , { endpoint , schemas = { } } = { } ) { const { data , ... params } = payload const { ident = null } = meta const typePlural = getPluralType ( params . type , schemas ) return { action , params , data , endpoint : ( endpoint && endpoint . options ) || null , access : { ident } , meta : { typePlural } } }


Input: Get service from type or service id . [CODESPLIT] function getService ( schemas , services ) { return ( type , service ) => { if ( ! service && schemas [ type ] ) { service = schemas [ type ] . service } return services [ service ] || null } }


Input: Action to sync from one service to another . [CODESPLIT] async function sync ( { payload , meta = { } } , { dispatch } ) { debug ( 'Action: SYNC' ) const fromParams = await generateFromParams ( payload , meta , dispatch ) const toParams = generateToParams ( payload , fromParams ) const lastSyncedAt = new Date ( ) const results = await Promise . all ( fromParams . map ( getFromService ( dispatch , payload . type , meta ) ) ) if ( results . some ( ( result ) => result . status !== 'ok' ) ) { return ( results . length === 1 ) ? results [ 0 ] : createError ( makeErrorString ( results ) ) } const data = flatten ( results . map ( ( result ) => result . data ) ) . filter ( Boolean ) if ( data . length === 0 && payload . syncNoData !== true ) { return createError ( ` ${ fromParams [ 0 ] . service } ` , 'noaction' ) } return Promise . all ( [ ... createSetMetas ( fromParams , lastSyncedAt , meta . ident , dispatch ) , dispatch ( action ( 'SET' , { data , ... toParams } , { ... meta , queue : true } ) ) ] ) . then ( ( responses ) => { return { status : 'ok' , data : responses } } ) }


Input:
Task api that configures and loads gulp tasks . [CODESPLIT] function ( gulp , cwd , config ) { if ( util . isNullOrUndefined ( gulp ) ) { throw 'gulp must be defined' ; } /**
   * Configuration options that will be injected into every gulp task.
   *
   * @type {Object}
   */ this . _config = config || { } , /**
   * Current working directory that path calculations should be relative to.
   *
   * @type {String}
   */ this . _cwd = cwd || __dirname ; /**
   * Actual path of this file relative to the defined working directory.
   *
   * @type {String}
   */ this . _root = path . relative ( this . _cwd , __dirname ) ; /**
   * Gulp instance. All tasks get injected the same gulp instances.
   *
   * @type {Gulp}
   */ this . _gulp = gulp ; }


Input: black white and gray ( buggy? ) are not included [CODESPLIT] function ( ) { this . _colors = [ 'red' , 'green' , 'yellow' , 'blue' , 'magenta' , 'cyan' , 'white' , 'black' ] this . _colors_num = this . _colors . length this . _backgrounds = [ ] for ( var i = 0 ; i < this . _colors_num ; i ++ ) { this . _backgrounds [ i ] = 'bg' + this . _colors [ i ] . charAt ( 0 ) . toUpperCase ( ) + this . _colors [ i ] . slice ( 1 ) } this . _skip = [ 'black' , 'white' , 'bgBlack' , 'bgWhite' ] this . _skip_num = this . _skip . length - 1 this . _next = 0 this . _prev = - 1 this . options = { color_space : false , gap : 1 , space_color : null } this . wrapper = { bg : this . ponyfy ( true ) , r : this . ponyfy ( ) , add : this . addorskip ( 'add' ) , skip : this . addorskip ( 'skip' ) , options : ( opts ) => { for ( let i in options ) { if ( opts [ i ] ) { this . options [ i ] = opts [ i ] continue } for ( let j in opts ) { if ( options [ i ] . alias && ~ options [ i ] . alias . indexOf ( j ) ) { this . options [ i ] = opts [ j ] break } } } return this . wrapper } , colors : ( ) => this . colors ( ) , reset : ( ) => { this . _skip = [ 'black' , 'white' , 'bgBlack' , 'bgWhite' ] return this . wrapper } , _colors : this . _colors , _backgrounds : this . _backgrounds } return this . wrapper }


Input: wrapper to pass bg [CODESPLIT] function ( bg ) { bg = bg ? bg : false return ( ... args ) => { return this . output ( args . join ( ' ' ) , this . colors ( bg ) ) } }


Input: Babel external helper module injector . [CODESPLIT] function ( browserify , name , source ) { if ( utility . isNullOrUndefined ( browserify ) ) { throw 'browserify must be defined.' ; } if ( ! utility . isNonEmptyString ( name ) ) { throw 'name must be defined.' ; } if ( utility . isNullOrUndefined ( source ) ) { throw 'source must be defined.' ; } this . _browserify = browserify ; this . _name = name ; this . _source = source ; this . _hasModule = false ; this . _hasResolver = false ; }


Input: Strategy constructor . [CODESPLIT] function Strategy ( options , verify ) { options = options || { } ; if ( ! options . baseURI ) { throw new TypeError ( 'EveSeatStrategy requires a baseURI option' ) ; } // Remove trailing slash if provided options . baseURI = options . baseURI . replace ( / \/$ / , '' ) ; options . authorizationURL = options . baseURI + '/oauth2/authorize' ; options . tokenURL = options . baseURI + '/oauth2/token' ; this . _userProfileURL = options . baseURI + '/oauth2/profile' ; OAuth2Strategy . call ( this , options , verify ) ; this . name = 'eveseat' ; }


Input: Map the data coming _from_ the service . Everything is handled by the mappings but this method make sure that the right types are mapped . [CODESPLIT] function mapToService ( ) { return ( { request , requestMapper , mappings } ) => { const data = mapData ( request . data , request , mappings ) return { ... request , data : applyEndpointMapper ( data , request , requestMapper ) } } }


Input:
Router - allows client - > router - > server ( or client - > router< - client ) connectivity . This class is meant to help when a server is unable to handle maximum number of connections . [CODESPLIT] function Router ( options ) { var self = this ; self . frontend = new Server ( { port : options . port , auth : options . auth || options . secret , certificates : options . certificates , routing : true } ) // connect to relay destination
 if ( options . client ) { self . backend = new Client ( { address : options . client . address , auth : options . client . auth || options . client . secret || options . auth || options . secret , certificates : options . certificates || options . client . certificates , //node: options.node,
 designation : 'router' , routes : self . frontend . streams } ) } else if ( options . server ) { self . backend = new Server ( { port : options . server . port , auth : options . server . auth || options . server . secret || options . auth || options . secret , certificates : options . certificates || options . server . certificates , routes : self . frontend . streams } ) } else throw new Error ( "iris-rpc::Router() requires client or server" ) self . frontend . on ( 'connect' , function ( address , uuid , stream ) { self . backend . dispatch ( { op : 'rpc::online' , uuid : uuid } ) ; } ) self . frontend . on ( 'disconnect' , function ( uuid , stream ) { self . backend . dispatch ( { op : 'rpc::offline' , uuid : uuid } ) ; } ) self . backend . on ( 'connect' , function ( address , uuid , stream ) { self . frontend . dispatch ( { op : 'rpc::online' , uuid : uuid } ) ; } ) self . backend . on ( 'disconnect' , function ( uuid , stream ) { self . frontend . dispatch ( { op : 'rpc::offline' , uuid : uuid } ) ; } ) self . frontend . digest ( function ( msg , uuid , stream ) { msg . _r = { uuid : uuid , designation : stream . designation , uuid : stream . uuid } self . backend . dispatch ( msg ) ; } ) self . backend . digest ( function ( msg , uuid ) { self . frontend . dispatch ( msg . _uuid , msg ) ; } ) }


Input: Process messages from Facebook Messenger . [CODESPLIT] async function processMessengerBody ( body , context ) { const allMessages = getAllMessages ( body ) if ( ! allMessages || ! allMessages . length ) return false context = context || { } for ( let message of allMessages ) { message = _ . cloneDeep ( message ) const messageContext = Object . assign ( { } , context ) try { for ( let plugin of middleware ) { await plugin ( message , messageContext ) } } catch ( error ) { const logError = ( messageContext . log && messageContext . log . error instanceof Function ) ? messageContext . log . error : console . error logError ( 'Error running middleware' , error ) } } return true }


Input: Create a function for mapping app properties onto the given prop namespace . [CODESPLIT] function create ( prop ) { if ( typeof prop !== 'string' ) { throw new Error ( 'expected the first argument to be a string.' ) ; } return function ( app ) { if ( this . isRegistered ( 'base-' + prop ) ) return ; // map config var config = utils . mapper ( app ) // store/data . map ( 'store' , store ( app . store ) ) . map ( 'data' ) // options . map ( 'enable' ) . map ( 'disable' ) . map ( 'option' ) . alias ( 'options' , 'option' ) // get/set . map ( 'set' ) . map ( 'del' ) // Expose `prop` (config) on the instance app . define ( prop , proxy ( config ) ) ; // Expose `process` on app[prop] app [ prop ] . process = config . process ; } ; function store ( app ) { if ( ! app ) return { } ; var mapper = utils . mapper ( app ) ; app . define ( prop , proxy ( mapper ) ) ; return mapper ; } }


Input: Proxy to support app . config as a function or object with methods allowing the user to do either of the following : [CODESPLIT] function proxy ( config ) { function fn ( key , val ) { if ( typeof val === 'string' ) { config . alias . apply ( config , arguments ) ; return config ; } if ( typeof key === 'string' ) { config . map . apply ( config , arguments ) ; return config ; } if ( ! utils . isObject ( key ) ) { throw new TypeError ( 'expected key to be a string or object' ) ; } for ( var prop in key ) { fn ( prop , key [ prop ] ) ; } return config ; } fn . __proto__ = config ; return fn ; }


Input: Private functions [CODESPLIT] function ( proto , parentProto ) { proto . _initHooks = [ ] ; proto . _destroyHooks = [ ] ; // add method for calling all init hooks proto . callInitHooks = function ( ) { if ( this . _initHooksCalled ) { return ; } if ( parentProto ) { parentProto . callInitHooks . call ( this ) ; } this . _initHooksCalled = true ; for ( var i = 0 , len = proto . _initHooks . length ; i < len ; i ++ ) { proto . _initHooks [ i ] . call ( this ) ; } } ; // add method for calling all destroy hooks proto . callDestroyHooks = function ( ) { if ( this . _destroyHooksCalled ) { return ; } if ( parentProto . callDestroyHooks ) { parentProto . callDestroyHooks . call ( this ) ; } this . _destroyHooksCalled = true ; for ( var i = 0 , len = proto . _destroyHooks . length ; i < len ; i ++ ) { proto . _destroyHooks [ i ] . call ( this ) ; } } ; }


Input: Collects features and bind them to the node density [CODESPLIT] function ElementMatrix ( top ) { CommanalityMatrix . call ( this , top ) ; this . row ( ' ' ) ; this . collum ( ' ' ) ; this . classlist = top . root . classlist ; }


Input: node - s3 - encode - url [CODESPLIT] function publicS3URI ( string ) { return encodeURIComponent ( string ) . replace ( / %20 / img , '+' ) . replace ( / %2F / img , '/' ) . replace ( / \" / img , "%22" ) . replace ( / \# / img , "%23" ) . replace ( / \$ / img , "%24" ) . replace ( / \& / img , "%26" ) . replace ( / \' / img , "%27" ) . replace ( / \( / img , "%28" ) . replace ( / \) / img , "%29" ) . replace ( / \, / img , "%2C" ) . replace ( / \: / img , "%3A" ) . replace ( / \; / img , "%3B" ) . replace ( / \= / img , "%3D" ) . replace ( / \? / img , "%3F" ) . replace ( / \@ / img , "%40" ) ; }


Input: parse a string in the format topic [ : data ] where data is valid JSON [CODESPLIT] function parsePayload ( message ) { const messageParts = message && message . match ( / ^([^:]+)(?::(.*))? / ) if ( ! messageParts ) return { topic : undefined , data : undefined } const topic = messageParts [ 1 ] let data = messageParts [ 2 ] if ( data ) { try { data = JSON . parse ( data ) } catch ( error ) { data = undefined } } return { topic , data } }


Input: Save expected file [CODESPLIT] function ( done ) { fs . writeFile ( path . resolve ( __dirname , '../../test/reallife/expected/' + item . key + '.json' ) , JSON . stringify ( { 'title' : item . title , 'text' : item . text } , null , '\t' ) + '\n' , done ) ; }


Input: Save source file [CODESPLIT] function ( done ) { fs . writeFile ( path . resolve ( __dirname , '../../test/reallife/source/' + item . key + '.html' ) , SOURCES [ item . key ] , done ) ; }


Input: Save labeled flag [CODESPLIT] function ( done ) { datamap [ item . index ] . labeled = true ; fs . writeFile ( path . resolve ( __dirname , '../../test/reallife/datamap.json' ) , JSON . stringify ( datamap , null , '\t' ) + '\n' , done ) ; }


Input: A secret little gem you can use to print out the subtree : ) [CODESPLIT] function attrStringify ( attr ) { var names = Object . keys ( attr ) ; var str = '' ; for ( var i = 0 , l = names . length ; i < l ; i ++ ) { str += names [ i ] + '="' + attr [ names [ i ] ] . slice ( 0 , 20 ) + ( attr [ names [ i ] ] . length > 20 ? '...' : '' ) + '" ' ; } return str ; }


Input: Transform tree to nlcst . [CODESPLIT] function toNLCST ( tree , file , Parser ) { var parser var location var results var doc // Warn for invalid parameters. if ( ! tree || ! tree . type ) { throw new Error ( 'hast-util-to-nlcst expected node' ) } if ( ! file || ! file . messages ) { throw new Error ( 'hast-util-to-nlcst expected file' ) } // Construct parser. if ( ! Parser ) { throw new Error ( 'hast-util-to-nlcst expected parser' ) } if ( ! position . start ( tree ) . line || ! position . start ( tree ) . column ) { throw new Error ( 'hast-util-to-nlcst expected position on nodes' ) } location = vfileLocation ( file ) doc = String ( file ) parser = 'parse' in Parser ? Parser : new Parser ( ) // Transform HAST into NLCST tokens, and pass these into `parser.parse` to // insert sentences, paragraphs where needed. results = [ ] find ( tree ) return { type : 'RootNode' , children : results , position : { start : location . toPosition ( 0 ) , end : location . toPosition ( doc . length ) } } function find ( node ) { var children = node . children if ( node . type === 'root' ) { findAll ( children ) } else if ( is ( node ) && ! ignored ( node ) ) { if ( is ( node , EXPLICIT ) ) { // Explicit paragraph. add ( node ) } else if ( is ( node , FLOW_ACCEPTING ) ) { // Slightly simplified version of: // https://html.spec.whatwg.org/#paragraphs implicit ( flattenAll ( children ) ) } else { // Dig deeper. findAll ( children ) } } } function findAll ( children ) { var length = children . length var index = - 1 while ( ++ index < length ) { find ( children [ index ] ) } } function flatten ( node ) { if ( is ( node , [ 'a' , 'ins' , 'del' , 'map' ] ) ) { return flattenAll ( node . children ) } return node } function flattenAll ( children ) { var results = [ ] var length = children . length var index = - 1 while ( ++ index < length ) { results = results . concat ( flatten ( children [ index ] ) ) } return results } function add ( node ) { var result = ( 'length' in node ? all : one ) ( node ) if ( result . length !== 0 ) { results . push ( parser . tokenizeParagraph ( result ) ) } } function implicit ( children ) { var length = children . length + 1 var index = - 1 var viable = false var start = - 1 var child while ( ++ index < length ) { child = children [ index ] if ( child && phrasing ( child ) ) { if ( start === - 1 ) { start = index } if ( ! viable && ! embedded ( child ) && ! whitespace ( child ) ) { viable = true } } else if ( child && start === - 1 ) { find ( child ) start = index + 1 } else { ; ( viable ? add : findAll ) ( children . slice ( start , index ) ) if ( child ) { find ( child ) } viable = false start = - 1 } } } // Convert `node` (hast) to nlcst. function one ( node ) { var type = node . type var tagName = type === 'element' ? node . tagName : null var change var replacement if ( type === 'text' ) { change = true replacement = parser . tokenize ( node . value ) } else if ( tagName === 'wbr' ) { change = true replacement = [ parser . tokenizeWhiteSpace ( ' ' ) ] } else if ( tagName === 'br' ) { change = true replacement = [ parser . tokenizeWhiteSpace ( '\n' ) ] } else if ( sourced ( node ) ) { change = true replacement = [ parser . tokenizeSource ( textContent ( node ) ) ] } else if ( type === 'root' || ! ignored ( node ) ) { replacement = all ( node . children ) } else { return } if ( ! change ) { return replacement } return patch ( replacement , location , location . toOffset ( position . start ( node ) ) ) } // Convert all `children` (HAST) to NLCST. function all ( children ) { var length = children && children . length var index = - 1 var result = [ ] var child while ( ++ index < length ) { child = one ( children [ index ] ) if ( child ) { result = result . concat ( child ) } } return result } // Patch a position on each node in `nodes`.  `offset` is the offset in // `file` this run of content starts at. // // Note that NLCST nodes are concrete, meaning that their starting and ending // positions can be inferred from their content. function patch ( nodes , location , offset ) { var length = nodes . length var index = - 1 var start = offset var children var node var end while ( ++ index < length ) { node = nodes [ index ] children = node . children if ( children ) { patch ( children , location , start ) } end = start + toString ( node ) . length node . position = { start : location . toPosition ( start ) , end : location . toPosition ( end ) } start = end } return nodes } }


Input: Convert node ( hast ) to nlcst . [CODESPLIT] function one ( node ) { var type = node . type var tagName = type === 'element' ? node . tagName : null var change var replacement if ( type === 'text' ) { change = true replacement = parser . tokenize ( node . value ) } else if ( tagName === 'wbr' ) { change = true replacement = [ parser . tokenizeWhiteSpace ( ' ' ) ] } else if ( tagName === 'br' ) { change = true replacement = [ parser . tokenizeWhiteSpace ( '\n' ) ] } else if ( sourced ( node ) ) { change = true replacement = [ parser . tokenizeSource ( textContent ( node ) ) ] } else if ( type === 'root' || ! ignored ( node ) ) { replacement = all ( node . children ) } else { return } if ( ! change ) { return replacement } return patch ( replacement , location , location . toOffset ( position . start ( node ) ) ) }


Input: Convert all children ( HAST ) to NLCST . [CODESPLIT] function all ( children ) { var length = children && children . length var index = - 1 var result = [ ] var child while ( ++ index < length ) { child = one ( children [ index ] ) if ( child ) { result = result . concat ( child ) } } return result }


Input: Associations [CODESPLIT] function ( source , target , alias , type ) { if ( Util . isnt . Class ( source ) || Util . isnt . Class ( target ) || Util . isnt . String ( alias ) || ! alias || Association . types . indexOf ( type ) === - 1 ) { return false ; } this . id = Util . uniqId ( ) ; this . source = source ; this . target = target ; this . alias = Util . String . capitalize ( alias ) ; this . type = type ; return this . complete ( ) ; }


Input: Node General abstaction between all node types The rule is that this should contain the most obviouse implementation [CODESPLIT] function Node ( type , parent ) { this . type = type ; this . parent = parent ; this . root = parent ? parent . root : this ; this . identifyer = parent ? ( ++ parent . root . _counter ) : 0 ; // The specific constructor will set another value if necessary this . _textLength = 0 ; this . tags = 0 ; this . density = - 1 ; this . children = [ ] ; this . _text = '' ; this . _textCompiled = false ; this . _noneStyleText = '' ; this . _noneStyleTextCompiled = false ; this . blocky = false ; this . blockyChildren = false ; this . inTree = true ; }


Input: TextNode has a parent and a text containter [CODESPLIT] function TextNode ( parent , text ) { Node . call ( this , 'text' , parent ) ; // A text node has no children instead it has a text container this . children = null ; this . _text = text ; this . _noneStyleText = text ; }


Input: ElementNode has a parent tagname and attributes [CODESPLIT] function ElementNode ( parent , tagname , attributes ) { Node . call ( this , 'element' , parent ) ; // Since this is an element there will minimum one tag this . tags = ( tagname === 'br' || tagname === 'wbr' ) ? 0 : 1 ; // Element nodes also has a tagname and an attribute collection this . tagname = tagname ; this . attr = attributes ; this . classes = attributes . hasOwnProperty ( 'class' ) ? attributes [ 'class' ] . trim ( ) . split ( WHITE_SPACE ) : [ ] ; // Add node to the classlist this . root . classlist . addNode ( this ) ; this . _blockySelfCache = domHelpers . BLOCK_ELEMENTS . hasOwnProperty ( tagname ) ; this . _countTagnames = { } ; }


Input: extended class with the new prototype [CODESPLIT] function ( ) { var r ; // Recall as new if new isn't provided :) if ( Util . isnt . instanceof ( NewClass , this ) ) { return ClassUtil . construct ( NewClass , arguments ) ; } // call the constructor if ( Util . is . Function ( this . initialize ) ) { r = this . initialize . apply ( this , arguments ) ; } // call all constructor hooks this . callInitHooks ( ) ; return typeof r != 'undefined' ? r : this ; }


Input: Distribute content to the cssfiles object [CODESPLIT] function distribute ( filename , content ) { content = content ; fs . appendFile ( filename , content + "\n" ) ; log ( rulecount + ': Append to ' + filename + ' -> ' + content ) ; }


Input: Detect weather a selector should be extracted or not [CODESPLIT] function detectTakeout ( selectors ) { var properties = { takeout : false } ; options . takeout . forEach ( function ( takeout ) { selectors . forEach ( function ( selector ) { if ( selector . indexOf ( takeout . ruleprefix ) === 0 ) { properties . takeout = true ; properties . filename = takeout . filename ; } } ) ; } ) ; return properties ; }


Input: This function is made by the following requirements : x > 5 y = 1 f ( x ) = a * sqrt ( x ) + b * x^2 + c f ( 2 ) = 0 . 2 f ( 5 ) = 1 f ( 5 ) = 0 [CODESPLIT] function wordcountScore ( x ) { if ( x > 5 ) return 1 ; else return Math . min ( 1 , 2.27 * Math . sqrt ( x ) - 0.0507 * Math . pow ( x , 2 ) - 2.808 ) ; }


Input: This function is made by the following requirements : x > 5 y = 1 f ( x ) = a * sqrt ( x ) + b * x^2 + c f ( 0 ) = 0 . 2 f ( 5 ) = 1 f ( 5 ) = 0 [CODESPLIT] function linebreakScore ( x ) { if ( x > 5 ) return 1 ; else return Math . min ( 1 , 0.477 * Math . sqrt ( x ) - 0.0106 * Math . pow ( x , 2 ) + 0.2 ) ; }


Input: This function is made by the following requirements : : x < 0 . 01 y = 0 . 5 : x > 0 . 1 y = 1 : f ( x ) otherwise The f ( x ) polynomium is made so it follows : : f ( 0 . 01 ) = 0 . 5 : f ( 0 . 01 ) = 0 : f ( 0 . 1 ) = 1 : f ( 0 . 1 ) = 0 [CODESPLIT] function adjustLiklihood ( x ) { if ( x < 0.01 ) return 0.5 ; else if ( x > 0.1 ) return 1 ; else return Math . min ( 1 , - 1371 * Math . pow ( x , 3 ) + 226 * Math . pow ( x , 2 ) - 4.11 * x + 0.52 ) ; }


Input: create tuple that [CODESPLIT] function parseLineByLine ( text ) { var lines = text . trim ( ) . split ( "\n" ) ; var bookmarks = lines . splice ( 0 , lines . length * 3 / 4 ) ; return { bookmarks : bookmarks , lines : lines } ; }


Input: The exposed API used in all . js [CODESPLIT] function CommonalityInterface ( MatrixConstructor , top ) { this . top = top ; this . length = null ; this . matrix = null ; this . MatrixConstructor = MatrixConstructor ; }


Input: Some abstact API for the commanality matrix [CODESPLIT] function CommanalityMatrix ( classlist ) { // space will identify a text node and/or an element node without any classnames this . rowKeys = { } ; this . rowNames = [ ] ; this . collumKeys = { } ; this . collumNames = [ ] ; this . nodeMatrix = [ ] ; this . summaryMatrix = [ ] ; this . dim = [ 0 , 0 ] ; this . bestIndex = [ - 1 , - 1 ] ; this . _bestNodes = { } ; }


Input: Extend the rows or the collums [CODESPLIT] function arrayVector ( size ) { var vec = new Array ( size ) ; for ( var i = 0 ; i < size ; i ++ ) vec [ i ] = [ ] ; return vec ; }


Input: Builds and attribute matching function complexity is for uncomfirmed performace sake [CODESPLIT] function buildAttributeMatcher ( match ) { var keys = Object . keys ( match ) ; var jskey , i , l ; var transform = '' ; var bool = '' ; transform = 'transform = {\n' ; for ( i = 0 , l = keys . length ; i < l ; i ++ ) { jskey = JSON . stringify ( keys [ i ] ) ; transform += '  ' + jskey + ': attr.hasOwnProperty(' + jskey + ') ? attr[' + jskey + '].toLowerCase() : false' ; if ( i !== l - 1 ) transform += ',' ; transform += '\n' ; } transform += '};\n' ; bool = 'return !!(' ; for ( i = 0 , l = keys . length ; i < l ; i ++ ) { jskey = JSON . stringify ( keys [ i ] ) ; if ( i > 0 ) bool += '    ||    ' ; bool += ' ( transform[' + jskey + ']' ; if ( Array . isArray ( match [ keys [ i ] ] ) ) { bool += ' && ( ' ; for ( var j = 0 , s = match [ keys [ i ] ] . length ; j < s ; j ++ ) { if ( j > 0 ) bool += ' || ' ; if ( typeof match [ keys [ i ] ] [ j ] === 'string' ) { bool += 'transform[' + jskey + '] === \'' + match [ keys [ i ] ] [ j ] . toLowerCase ( ) + '\'' ; } else if ( util . isRegExp ( match [ keys [ i ] ] [ j ] ) ) { bool += 'match[' + jskey + '][' + j + '].test(transform[' + jskey + '])' ; } } bool += ' )' ; } bool += ' ) \n' ; } bool += '         );' ; var anonymous = new Function ( 'attr' , 'match' , transform + '\n' + bool ) ; return function ( attr ) { return anonymous ( attr , match ) ; } ; }


Input: Checks if container a is a container of b [CODESPLIT] function containerOf ( a , b ) { while ( b = b . parent ) { if ( a === b ) return true ; } return false ; }


Input: Find the common parent of a and b [CODESPLIT] function commonParent ( a , b ) { if ( a === b ) { return a ; } else if ( containerOf ( a , b ) ) { return a ; } else if ( containerOf ( b , a ) ) { return b ; } else { // This will happen at some point, since the root is a container of // everything while ( b = b . parent ) { if ( containerOf ( b , a ) ) return b ; } } }


Input: Parse style attribute intro object [CODESPLIT] function styleParser ( style ) { style = style || '' ; var tokens = style . trim ( ) . split ( / \s*(?:;|:)\s* / ) ; var output = { } ; for ( var i = 1 , l = tokens . length ; i < l ; i += 2 ) { output [ tokens [ i - 1 ] ] = tokens [ i ] ; } return output ; }


Input: Calculate the tree distance between a and b [CODESPLIT] function treeDistance ( a , b ) { if ( a === b ) return 0 ; var parent = commonParent ( a , b ) ; var aParent = a ; var aCount = 0 ; var bParent = b ; var bCount = 0 ; if ( parent !== a ) { while ( parent !== aParent . parent ) { aCount += 1 ; aParent = aParent . parent ; } } else { bCount += 1 ; } if ( parent !== b ) { while ( parent !== bParent . parent ) { bCount += 1 ; bParent = bParent . parent ; } } else { aCount += 1 ; } var abCount = 0 ; if ( parent !== a && parent !== b ) { abCount = Math . abs ( parent . children . indexOf ( aParent ) - parent . children . indexOf ( bParent ) ) ; } return aCount + bCount + abCount ; }


Input: module [CODESPLIT] function ( casper , pos ) { this . _pos = pos || { timestamp : Date . now ( ) , coords : { longitude : 0 , latitude : 0 , accuracy : 0 } } ; this . _casper = casper ; }


Input: Create a new Lexer for the given file and options . [CODESPLIT] function Lexer ( file , options ) { this . options = utils . extend ( { } , options ) ; this . file = file ; this . regex = new RegexCache ( ) ; this . names = [ ] ; this . ast = { tags : { } , type : 'root' , name : 'root' , nodes : [ ] } ; this . unknown = { tags : [ ] , blocks : [ ] } ; this . known = { tags : [ 'extends' , 'layout' ] , blocks : [ 'block' ] } ; this . delimiters = { variable : [ '{{' , '}}' ] , block : [ '{%' , '%}' ] , es6 : [ '${' , '}' ] , } ; this . tokens = [ this . ast ] ; this . errors = [ ] ; this . stack = [ ] ; this . stash = [ ] ; this . lexers = { } ; this . fns = [ ] ; }