function(type) {
    var cached = this.regex.createClose(type);
    var file = this.file;
    var lexer = this;

    return function() {
      var pos = lexer.position();
      var m = lexer.match(cached.strict);
      if (!m) return;

      var block = lexer.tokens.pop();
      if (typeof block === 'undefined' || block.type !== type) {
        throw new Error(`missing opening ${type}`);
      }

      if (block.name === 'body') {
        lexer.ast.isLayout = true;
        file.ast.isLayout = true;
      }

      var nodes = block.nodes;
      Object.defineProperty(file.ast.blocks, block.name, {
        configurable: true,
        set: function(val) {
          nodes = val;
        },
        get: function() {
          return nodes;
        }
      });

      Object.defineProperty(block, 'nodes', {
        configurable: true,
        set: function(val) {
          nodes = val;
        },
        get: function() {
          return nodes;
        }
      });

      var tok = pos({
        known: block.known,
        type: `${type}.close`,
        val: m[0].trim()
      });

      utils.define(block, 'position', tok.position);
      utils.define(tok, 'parent', block);
      block.nodes.push(tok);
      return block;
    };
  }

function ( type ) { var cached = this . regex . createClose ( type ) ; var file = this . file ; var lexer = this ; return function ( ) { var pos = lexer . position ( ) ; var m = lexer . match ( cached . strict ) ; if ( ! m ) return ; var block = lexer . tokens . pop ( ) ; if ( typeof block === 'undefined' || block . type !== type ) { throw new Error ( ` ${ type } ` ) ; } if ( block . name === 'body' ) { lexer . ast . isLayout = true ; file . ast . isLayout = true ; } var nodes = block . nodes ; Object . defineProperty ( file . ast . blocks , block . name , { configurable : true , set : function ( val ) { nodes = val ; } , get : function ( ) { return nodes ; } } ) ; Object . defineProperty ( block , 'nodes' , { configurable : true , set : function ( val ) { nodes = val ; } , get : function ( ) { return nodes ; } } ) ; var tok = pos ( { known : block . known , type : ` ${ type } ` , val : m [ 0 ] . trim ( ) } ) ; utils . define ( block , 'position' , tok . position ) ; utils . define ( tok , 'parent' , block ) ; block . nodes . push ( tok ) ; return block ; } ; }

Create a closing tag lexer for block `name`.
@param {String} `name`
@return {Function}

Create a closing tag lexer for block name .


function(type) {
    this.file.ast.blocks[type] = this.file.ast.blocks[type] || {};
    this.addLexer(this.captureOpen(type));
    this.addLexer(this.captureClose(type));
    return this;
  }

function ( type ) { this . file . ast . blocks [ type ] = this . file . ast . blocks [ type ] || { } ; this . addLexer ( this . captureOpen ( type ) ) ; this . addLexer ( this . captureClose ( type ) ) ; return this ; }

Create a block lexer with opening and closing tags for the given `name`.
@param {String} `name`
@return {Function}

Create a block lexer with opening and closing tags for the given name .


function(file, prop) {
    return this.createNode(prop, file[prop], `{% ${prop} "${file[prop]}" %}`, this.position());
  }

function ( file , prop ) { return this . createNode ( prop , file [ prop ] , ` ${ prop } ${ file [ prop ] } ` , this . position ( ) ) ; }


function(str, len) {
    var lines = str.match(/\n/g);
    if (lines) this.lineno += lines.length;
    var i = str.lastIndexOf('\n');
    this.column = ~i ? len - i : this.column + len;
    this.lexed += str;
    this.consume(str, len);
  }

function ( str , len ) { var lines = str . match ( / \n / g ) ; if ( lines ) this . lineno += lines . length ; var i = str . lastIndexOf ( '\n' ) ; this . column = ~ i ? len - i : this . column + len ; this . lexed += str ; this . consume ( str , len ) ; }

Update lineno and column based on `str`.


function() {
    var len = this.fns.length;
    var idx = -1;
    while (++idx < len) {
      this.fns[idx].call(this);
      if (!this.input) {
        break;
      }
    }
  }

function ( ) { var len = this . fns . length ; var idx = - 1 ; while ( ++ idx < len ) { this . fns [ idx ] . call ( this ) ; if ( ! this . input ) { break ; } } }

Run lexers to advance the curson position


function() {
    while (this.input) {
      var prev = this.input;
      this.advance();
      if (this.input && prev === this.input) {
        throw new Error(`no lexers registered for: "${this.input.substr(0, 10)}"`);
      }
    }
  }

function ( ) { while ( this . input ) { var prev = this . input ; this . advance ( ) ; if ( this . input && prev === this . input ) { throw new Error ( ` ${ this . input . substr ( 0 , 10 ) } ` ) ; } } }


function(file) {
    debug('lexing <%s>', this.file.path);
    if (file) this.file = file;
    this.init();
    while (this.input) this.next();
    return this.ast;
  }

function
(
file
)
{
debug
(
'lexing <%s>'
,
this
.
file
.
path
)
;
if
(
file
)
this
.
file
=
file
;
this
.
init
(
)
;
while
(
this
.
input
)
this
.
next
(
)
;
return
this
.
ast
;
}

Tokenize the given string.
@return {Array}


function notifyHook(e) {

    message_count++;

    var message;

    if (!options.enabled) {
      return;
    }

    if (!e) {
      return;
    }

    if (e && e.length === 1) {
      e = e[0];
    }

    if (/Task .* failed\./.test(e.message)) {
      message = e.message;
    } else if (e.message && e.stack) {
      message = exception(e);
    } else {
      message = e + '';
    }

    if (message_count > 0 && message === 'Aborted due to warnings.') {
      // skip unhelpful message because there was probably another one that was more helpful
      return;
    }

    // shorten message by removing full path
    // TODO - make a global replace
    message = message.replace(cwd, '').replace('\x07', '');

    return notify({
      title:    options.title + (grunt.task.current.nameArgs ? ' ' + grunt.task.current.nameArgs : ''),
      message:  message
    });
  }

Hook for showing the automatic message
@param e Exception or message
@returns {*}


function() {
    if (this._initialized && this._isPaused) {
      return false;
    }

    this._isPaused = true;
    raf.cancel(this._requestID);

    this._pauseTime = now();
    this._onPause();

    return true;
  }

function ( ) { if ( this . _initialized && this . _isPaused ) { return false ; } this . _isPaused = true ; raf . cancel ( this . _requestID ) ; this . _pauseTime = now ( ) ; this . _onPause ( ) ; return true ; }


function() {
    if (this._initialized && !this._isPaused) {
      return false;
    }

    var pauseDuration;

    this._isPaused = false;
    this._prevTime = now();

    pauseDuration = this._prevTime - this._pauseTime;
    this._onResume(pauseDuration);

    this._requestID = raf.request(this._tick);

    return true;
  }

function ( ) { if ( this . _initialized && ! this . _isPaused ) { return false ; } var pauseDuration ; this . _isPaused = false ; this . _prevTime = now ( ) ; pauseDuration = this . _prevTime - this . _pauseTime ; this . _onResume ( pauseDuration ) ; this . _requestID = raf . request ( this . _tick ) ; return true ; }


function mktmpdir(prefixSuffix, tmpdir, callback, onend) {
  if ('function' == typeof prefixSuffix) {
    onend = tmpdir;
    callback = prefixSuffix;
    tmpdir = null;
    prefixSuffix = null;
  } else if ('function' == typeof tmpdir) {
    onend = callback;
    callback = tmpdir;
    tmpdir = null;
  }

  prefixSuffix = prefixSuffix || 'd';
  onend = onend || function() {};

  tmpname.create(prefixSuffix, tmpdir, function(err, path, next) {
    if (err) return callback(err);

    fs.mkdir(path, 0700, next);
  }, function(err, path) {
    if (err) return callback(err);

    callback(null, path, function(err) {
      if (!path) return onend(err);

      rimraf(path, function(_err) {
        onend(err || _err, path);
      });
    });
  });
}

function mktmpdir ( prefixSuffix , tmpdir , callback , onend ) { if ( 'function' == typeof prefixSuffix ) { onend = tmpdir ; callback = prefixSuffix ; tmpdir = null ; prefixSuffix = null ; } else if ( 'function' == typeof tmpdir ) { onend = callback ; callback = tmpdir ; tmpdir = null ; } prefixSuffix = prefixSuffix || 'd' ; onend = onend || function ( ) { } ; tmpname . create ( prefixSuffix , tmpdir , function ( err , path , next ) { if ( err ) return callback ( err ) ; fs . mkdir ( path , 0700 , next ) ; } , function ( err , path ) { if ( err ) return callback ( err ) ; callback ( null , path , function ( err ) { if ( ! path ) return onend ( err ) ; rimraf ( path , function ( _err ) { onend ( err || _err , path ) ; } ) ; } ) ; } ) ; }

Creates a temporary directory.

The directory is created with 0700 permission.
Application should not change the permission to make the temporary directory accessible from other users.

The prefix and suffix of the name of the directory is specified by
the optional first argument, prefixSuffix.
- If it is not specified or null, "d" is used as the prefix and no suffix is used.
- If it is a string, it is used as the prefix and no suffix is used.
- If it is an array, first element is used as the prefix and second element is used as a suffix.

mktmpdir(function(err, dir) { dir is ".../d..." });
mktmpdir('foo', function(err, dir) { dir is ".../foo..." });
mktmpdir(['foo', 'bar'], function(err, dir) { dir is ".../foo...bar" });

The directory is created under os.tmpdir() or
the optional second argument tmpdir if non-null value is given.

mktmpdir(function(err, dir) { dir is os.tmpdir() + "/d..." });
mktmpdir(null, '/var/tmp', function(err, dir) { dir is "/var/tmp/d..." });

If a callback is invoked,
the path of the directory and its contents are removed.

mktmpdir(function(err, dir, done) {
if (err) throw err;
// use the directory...
fs.open(dir + '/foo', 'w', function(err, fd) {
done(err);
});
}, function(err) {
// the directory has been removed.
});

If a callback is not invoked, mktmpdir doesn't remove the directory.

mktmpdir(function(err, dir) {
if (err) throw err;
// use the directory...
fs.open(dir + '/foo', 'w', function(err, fd) {
// remove the directory.
exec('rm -rf ' + dir);
});
});

@param {String|Array} prefix, or an array including prefix and suffix.
@param {String} base tmpdir
@param {Function} callback
@param {Function} onend
@api public


function copyString(buffer, length, offsetBegin, offsetEnd) {
  if (length > 2048) {
    return buffer.toString('utf-8', offsetBegin, offsetEnd);
  }

  var string = '';
  while(offsetBegin < offsetEnd) {
    string += String.fromCharCode(buffer[offsetBegin++]);
  }
  return string;
}

function copyString ( buffer , length , offsetBegin , offsetEnd ) { if ( length > 2048 ) { return buffer . toString ( 'utf-8' , offsetBegin , offsetEnd ) ; } var string = '' ; while ( offsetBegin < offsetEnd ) { string += String . fromCharCode ( buffer [ offsetBegin ++ ] ) ; } return string ; }


function parseSimpleString(parser) {
  var offset = parser.offset;
  var length = parser.buffer.length;
  var string = '';

  while (offset < length) {
    var c1 = parser.buffer[offset++];
    if (c1 === 13) {
      var c2 = parser.buffer[offset++];
      if (c2 === 10) {
        parser.offset = offset;
        return string;
      }
      string += String.fromCharCode(c1) + String.fromCharCode(c2);
      continue;
    }
    string += String.fromCharCode(c1);
  }
  return undefined;
}

function parseSimpleString ( parser ) { var offset = parser . offset ; var length = parser . buffer . length ; var string = '' ; while ( offset < length ) { var c1 = parser . buffer [ offset ++ ] ; if ( c1 === 13 ) { var c2 = parser . buffer [ offset ++ ] ; if ( c2 === 10 ) { parser . offset = offset ; return string ; } string += String . fromCharCode ( c1 ) + String . fromCharCode ( c2 ) ; continue ; } string += String . fromCharCode ( c1 ) ; } return undefined ; }


function getBaseConfig(isProd) {
  // get library details from JSON config
  const libraryEntryPoint = path.join('src', LIBRARY_DESC.entry);

  // generate webpack base config
  return {
    entry: [
      // "babel-polyfill",
      path.join(__dirname, libraryEntryPoint),
    ],
    output: {
      devtoolLineToLine: true,
      pathinfo: true,
    },
    module: {
      preLoaders: [
        {
          test: /\.js$/,
          exclude: /(node_modules|bower_components)/,
          loader: "eslint-loader",
        },
      ],
      loaders: [
        {
          exclude: /(node_modules|bower_components)/,
          loader: "babel-loader",
          plugins: [
            "transform-runtime",
          ],
          query: {
            presets: [
              "es2015",
              "stage-0",
              "stage-1",
              "stage-2",
            ],
            cacheDirectory: false,
          },
          test: /\.js$/,
        },
      ],
    },
    eslint: {
      configFile: './.eslintrc',
    },
    resolve: {
      root: path.resolve('./src'),
      extensions: ['', '.js'],
    },
    devtool: isProd ? "source-map"/* null*/ : "source-map"/* '#eval-source-map'*/,
    debug: !isProd,
    plugins: isProd ? [
      new webpack.DefinePlugin({ 'process.env': { NODE_ENV: '"production"' } }),
      new UglifyJsPlugin({
        compress: { warnings: true },
        minimize: true,
        sourceMap: true,
      }),
      // Prod plugins here
    ] : [
      new webpack.DefinePlugin({ 'process.env': { NODE_ENV: '"development"' } }),
      new UglifyJsPlugin({
        compress: { warnings: true },
        minimize: true,
        sourceMap: true,
      }),
      // Dev plugins here
    ],
  };
}

function
getBaseConfig
(
isProd
)
{
// get library details from JSON config
const
libraryEntryPoint
=
path
.
join
(
'src'
,
LIBRARY_DESC
.
entry
)
;
// generate webpack base config
return
{
entry
:
[
// "babel-polyfill",
path
.
join
(
__dirname
,
libraryEntryPoint
)
,
]
,
output
:
{
devtoolLineToLine
:
true
,
pathinfo
:
true
,
}
,
module
:
{
preLoaders
:
[
{
test
:
/
\.js$
/
,
exclude
:
/
(node_modules|bower_components)
/
,
loader
:
"eslint-loader"
,
}
,
]
,
loaders
:
[
{
exclude
:
/
(node_modules|bower_components)
/
,
loader
:
"babel-loader"
,
plugins
:
[
"transform-runtime"
,
]
,
query
:
{
presets
:
[
"es2015"
,
"stage-0"
,
"stage-1"
,
"stage-2"
,
]
,
cacheDirectory
:
false
,
}
,
test
:
/
\.js$
/
,
}
,
]
,
}
,
eslint
:
{
configFile
:
'./.eslintrc'
,
}
,
resolve
:
{
root
:
path
.
resolve
(
'./src'
)
,
extensions
:
[
''
,
'.js'
]
,
}
,
devtool
:
isProd
"source-map"
/* null*/
:
"source-map"
/* '#eval-source-map'*/
,
debug
:
!
isProd
,
plugins
:
isProd
[
new
webpack
.
DefinePlugin
(
{
'process.env'
:
{
NODE_ENV
:
'"production"'
}
}
)
,
new
UglifyJsPlugin
(
{
compress
:
{
warnings
:
true
}
,
minimize
:
true
,
sourceMap
:
true
,
}
)
,
// Prod plugins here
]
:
[
new
webpack
.
DefinePlugin
(
{
'process.env'
:
{
NODE_ENV
:
'"development"'
}
}
)
,
new
UglifyJsPlugin
(
{
compress
:
{
warnings
:
true
}
,
minimize
:
true
,
sourceMap
:
true
,
}
)
,
// Dev plugins here
]
,
}
;
}

Build base config
@param  {Boolean} isProd [description]
@return {[type]}         [description]


function postNotification(options, cb) {

  options.title = removeColor(options.title);
  options.message = removeColor(options.message);

  if (!options.message) {
    return cb && cb(!options.message && 'Message is required');
  }

  if (!notifyPlatform) {
    notifyPlatform = choosePlatform();
  }

  function resetPreviousTimer(newMessage) {
    previousMessage = newMessage;
    clearTimeout(previousMessageTimer);
    previousMessageTimer = setTimeout(function(){previousMessage = false;}, previousMessageTimeoutMS);
  }

  if (options.message === previousMessage) {
    resetPreviousTimer(options.message);
    if (typeof cb === 'function') {
            cb(err);
          }
    return;
  }

  resetPreviousTimer(options.message);

  options.debug = debug(notifyPlatform.name); //for debug logging

  return notifyPlatform.notify(options, function(err){
      if (err) {
        options.debug({
          return_code: err
        });
      }
      if (typeof cb === 'function') {
        cb(err);
      }
    });
}

function
postNotification
(
options
,
cb
)
{
options
.
title
=
removeColor
(
options
.
title
)
;
options
.
message
=
removeColor
(
options
.
message
)
;
if
(
!
options
.
message
)
{
return
cb
&&
cb
(
!
options
.
message
&&
'Message is required'
)
;
}
if
(
!
notifyPlatform
)
{
notifyPlatform
=
choosePlatform
(
)
;
}
function
resetPreviousTimer
(
newMessage
)
{
previousMessage
=
newMessage
;
clearTimeout
(
previousMessageTimer
)
;
previousMessageTimer
=
setTimeout
(
function
(
)
{
previousMessage
=
false
;
}
,
previousMessageTimeoutMS
)
;
}
if
(
options
.
message
===
previousMessage
)
{
resetPreviousTimer
(
options
.
message
)
;
if
(
typeof
cb
===
'function'
)
{
cb
(
err
)
;
}
return
;
}
resetPreviousTimer
(
options
.
message
)
;
options
.
debug
=
debug
(
notifyPlatform
.
name
)
;
//for debug logging
return
notifyPlatform
.
notify
(
options
,
function
(
err
)
{
if
(
err
)
{
options
.
debug
(
{
return_code
:
err
}
)
;
}
if
(
typeof
cb
===
'function'
)
{
cb
(
err
)
;
}
}
)
;
}

Public function to notify
@param options - options.message is the only required value. title is recommended. subtitle is going overboard.
@param [cb] - optional callback. function(err, stdout, stderr)


function generateUsername(base) {
    base = base.toLowerCase();
    var entries = [];
    var finalName;
    return userDB.allDocs({startkey: base, endkey: base + '\uffff', include_docs: false})
      .then(function(results){
        if(results.rows.length === 0) {
          return BPromise.resolve(base);
        }
        for(var i=0; i<results.rows.length; i++) {
          entries.push(results.rows[i].id);
        }
        if(entries.indexOf(base) === -1) {
          return BPromise.resolve(base);
        }
        var num = 0;
        while(!finalName) {
          num++;
          if(entries.indexOf(base+num) === -1) {
            finalName = base + num;
          }
        }
        return BPromise.resolve(finalName);
      });
  }

function generateUsername ( base ) { base = base . toLowerCase ( ) ; var entries = [ ] ; var finalName ; return userDB . allDocs ( { startkey : base , endkey : base + '\uffff' , include_docs : false } ) . then ( function ( results ) { if ( results . rows . length === 0 ) { return BPromise . resolve ( base ) ; } for ( var i = 0 ; i < results . rows . length ; i ++ ) { entries . push ( results . rows [ i ] . id ) ; } if ( entries . indexOf ( base ) === - 1 ) { return BPromise . resolve ( base ) ; } var num = 0 ; while ( ! finalName ) { num ++ ; if ( entries . indexOf ( base + num ) === - 1 ) { finalName = base + num ; } } return BPromise . resolve ( finalName ) ; } ) ; }

Adds numbers to a base name until it finds a unique database key


function linkSuccess(req, res, next) {
    var provider = getProvider(req.path);
    var result = {
      error: null,
      session: null,
      link: provider
    };
    var template;
    if(config.getItem('testMode.oauthTest')) {
      template = fs.readFileSync(path.join(__dirname, '../templates/oauth/auth-callback-test.ejs'), 'utf8');
    } else {
      template = fs.readFileSync(path.join(__dirname, '../templates/oauth/auth-callback.ejs'), 'utf8');
    }
    var html = ejs.render(template, result);
    res.status(200).send(html);
  }

Called after an account has been succesfully linked


function linkTokenSuccess(req, res, next) {
    var provider = getProviderToken(req.path);
    res.status(200).json({
      ok: true,
      success: util.capitalizeFirstLetter(provider) + ' successfully linked',
      provider: provider
    });
  }

function
linkTokenSuccess
(
req
,
res
,
next
)
{
var
provider
=
getProviderToken
(
req
.
path
)
;
res
.
status
(
200
)
.
json
(
{
ok
:
true
,
success
:
util
.
capitalizeFirstLetter
(
provider
)
+
' successfully linked'
,
provider
:
provider
}
)
;
}

Called after an account has been succesfully linked using access_token provider


function oauthErrorHandler(err,req,res,next) {
    var template;
    if(config.getItem('testMode.oauthTest')) {
      template = fs.readFileSync(path.join(__dirname, '../templates/oauth/auth-callback-test.ejs'), 'utf8');
    } else {
      template = fs.readFileSync(path.join(__dirname, '../templates/oauth/auth-callback.ejs'), 'utf8');
    }
    var html = ejs.render(template, {error: err.message, session: null, link: null});
    console.error(err);
    if(err.stack) {
      console.error(err.stack);
    }
    res.status(400).send(html);
  }


function tokenAuthErrorHandler(err,req,res,next) {
    var status;
    if(req.user && req.user._id) {
      status = 403;
    } else {
      status = 401;
    }
    console.error(err);
    if(err.stack) {
      console.error(err.stack);
      delete err.stack;
    }
    res.status(status).json(err);
  }

function tokenAuthErrorHandler ( err , req , res , next ) { var status ; if ( req . user && req . user . _id ) { status = 403 ; } else { status = 401 ; } console . error ( err ) ; if ( err . stack ) { console . error ( err . stack ) ; delete err . stack ; } res . status ( status ) . json ( err ) ; }

Handles errors if authentication from access_token provider fails


function registerProvider(provider, configFunction) {
    provider = provider.toLowerCase();
    var configRef = 'providers.' + provider;
    if (config.getItem(configRef + '.credentials')) {
      var credentials = config.getItem(configRef + '.credentials');
      credentials.passReqToCallback = true;
      var options = config.getItem(configRef + '.options') || {};
      configFunction.call(null, credentials, passport, authHandler);
      router.get('/' + provider, passportCallback(provider, options, 'login'));
      router.get('/' + provider + '/callback', passportCallback(provider, options, 'login'), initSession, oauthErrorHandler);
      if(!config.getItem('security.disableLinkAccounts')) {
        router.get('/link/' + provider, passport.authenticate('bearer', {session: false}), passportCallback(provider, options, 'link'));
        router.get('/link/' + provider + '/callback', passport.authenticate('bearer', {session: false}),
          passportCallback(provider, options, 'link'), linkSuccess, oauthErrorHandler);
      }
      console.log(provider + ' loaded.');
    }
  }

function
registerProvider
(
provider
,
configFunction
)
{
provider
=
provider
.
toLowerCase
(
)
;
var
configRef
=
'providers.'
+
provider
;
if
(
config
.
getItem
(
configRef
+
'.credentials'
)
)
{
var
credentials
=
config
.
getItem
(
configRef
+
'.credentials'
)
;
credentials
.
passReqToCallback
=
true
;
var
options
=
config
.
getItem
(
configRef
+
'.options'
)
||
{
}
;
configFunction
.
call
(
,
credentials
,
passport
,
authHandler
)
;
router
.
get
(
'/'
+
provider
,
passportCallback
(
provider
,
options
,
'login'
)
)
;
router
.
get
(
'/'
+
provider
+
'/callback'
,
passportCallback
(
provider
,
options
,
'login'
)
,
initSession
,
oauthErrorHandler
)
;
if
(
!
config
.
getItem
(
'security.disableLinkAccounts'
)
)
{
router
.
get
(
'/link/'
+
provider
,
passport
.
authenticate
(
'bearer'
,
{
session
:
false
}
)
,
passportCallback
(
provider
,
options
,
'link'
)
)
;
router
.
get
(
'/link/'
+
provider
+
'/callback'
,
passport
.
authenticate
(
'bearer'
,
{
session
:
false
}
)
,
passportCallback
(
provider
,
options
,
'link'
)
,
linkSuccess
,
oauthErrorHandler
)
;
}
console
.
log
(
provider
+
' loaded.'
)
;
}
}

Framework to register OAuth providers with passport


function registerOAuth2 (providerName, Strategy) {
    registerProvider(providerName, function (credentials, passport, authHandler) {
      passport.use(new Strategy(credentials,
        function (req, accessToken, refreshToken, profile, done) {
          authHandler(req, providerName, {accessToken: accessToken, refreshToken: refreshToken}, profile)
            .asCallback(done);
        }
      ));
    });
  }

function registerOAuth2 ( providerName , Strategy ) { registerProvider ( providerName , function ( credentials , passport , authHandler ) { passport . use ( new Strategy ( credentials , function ( req , accessToken , refreshToken , profile , done ) { authHandler ( req , providerName , { accessToken : accessToken , refreshToken : refreshToken } , profile ) . asCallback ( done ) ; } ) ) ; } ) ; }

A shortcut to register OAuth2 providers that follow the exact accessToken, refreshToken pattern.

A shortcut to register OAuth2 providers that follow the exact accessToken refreshToken pattern .


function registerTokenProvider (providerName, Strategy) {
    providerName = providerName.toLowerCase();
    var configRef = 'providers.' + providerName;
    if (config.getItem(configRef + '.credentials')) {
      var credentials = config.getItem(configRef + '.credentials');
      credentials.passReqToCallback = true;
      var options = config.getItem(configRef + '.options') || {};
      // Configure the Passport Strategy
      passport.use(providerName + '-token', new Strategy(credentials,
        function (req, accessToken, refreshToken, profile, done) {
          authHandler(req, providerName, {accessToken: accessToken, refreshToken: refreshToken}, profile)
            .asCallback(done);
        }));
      router.post('/' + providerName + '/token', passportTokenCallback(providerName, options), initTokenSession, tokenAuthErrorHandler);
      if(!config.getItem('security.disableLinkAccounts')) {
        router.post('/link/' + providerName + '/token', passport.authenticate('bearer', {session: false}),
          passportTokenCallback(providerName, options), linkTokenSuccess, tokenAuthErrorHandler);
      }
      console.log(providerName + '-token loaded.');
    }
  }

function
registerTokenProvider
(
providerName
,
Strategy
)
{
providerName
=
providerName
.
toLowerCase
(
)
;
var
configRef
=
'providers.'
+
providerName
;
if
(
config
.
getItem
(
configRef
+
'.credentials'
)
)
{
var
credentials
=
config
.
getItem
(
configRef
+
'.credentials'
)
;
credentials
.
passReqToCallback
=
true
;
var
options
=
config
.
getItem
(
configRef
+
'.options'
)
||
{
}
;
// Configure the Passport Strategy
passport
.
use
(
providerName
+
'-token'
,
new
Strategy
(
credentials
,
function
(
req
,
accessToken
,
refreshToken
,
profile
,
done
)
{
authHandler
(
req
,
providerName
,
{
accessToken
:
accessToken
,
refreshToken
:
refreshToken
}
,
profile
)
.
asCallback
(
done
)
;
}
)
)
;
router
.
post
(
'/'
+
providerName
+
'/token'
,
passportTokenCallback
(
providerName
,
options
)
,
initTokenSession
,
tokenAuthErrorHandler
)
;
if
(
!
config
.
getItem
(
'security.disableLinkAccounts'
)
)
{
router
.
post
(
'/link/'
+
providerName
+
'/token'
,
passport
.
authenticate
(
'bearer'
,
{
session
:
false
}
)
,
passportTokenCallback
(
providerName
,
options
)
,
linkTokenSuccess
,
tokenAuthErrorHandler
)
;
}
console
.
log
(
providerName
+
'-token loaded.'
)
;
}
}

Registers a provider that accepts an access_token directly from the client, skipping the popup window and callback This is for supporting Cordova, native IOS and Android apps, as well as other devices

Registers a provider that accepts an access_token directly from the client skipping the popup window and callback This is for supporting Cordova native IOS and Android apps as well as other devices


function authHandler(req, provider, auth, profile) {
    if(req.user && req.user._id && req.user.key) {
      return user.linkSocial(req.user._id, provider, auth, profile, req);
    } else {
      return user.socialAuth(provider, auth, profile, req);
    }
  }

function authHandler ( req , provider , auth , profile ) { if ( req . user && req . user . _id && req . user . key ) { return user . linkSocial ( req . user . _id , provider , auth , profile , req ) ; } else { return user . socialAuth ( provider , auth , profile , req ) ; } }

This is called after a user has successfully authenticated with a provider If a user is authenticated with a bearer token we will link an account, otherwise log in auth is an object containing 'access_token' and optionally 'refresh_token'

This is called after a user has successfully authenticated with a provider If a user is authenticated with a bearer token we will link an account otherwise log in auth is an object containing access_token and optionally refresh_token


function passportCallback(provider, options, operation) {
    return function(req, res, next) {
      var theOptions = extend({}, options);
      if(provider === 'linkedin') {
        theOptions.state = true;
      }
      var accessToken = req.query.bearer_token || req.query.state;
      if(accessToken && (stateRequired.indexOf(provider) > -1 || config.getItem('providers.' + provider + '.stateRequired') === true)) {
        theOptions.state = accessToken;
      }
      theOptions.callbackURL = getLinkCallbackURLs(provider, req, operation, accessToken);
      theOptions.session = false;
      passport.authenticate(provider, theOptions)(req, res, next);
    };
  }

function passportCallback ( provider , options , operation ) { return function ( req , res , next ) { var theOptions = extend ( { } , options ) ; if ( provider === 'linkedin' ) { theOptions . state = true ; } var accessToken = req . query . bearer_token || req . query . state ; if ( accessToken && ( stateRequired . indexOf ( provider ) > - 1 || config . getItem ( 'providers.' + provider + '.stateRequired' ) === true ) ) { theOptions . state = accessToken ; } theOptions . callbackURL = getLinkCallbackURLs ( provider , req , operation , accessToken ) ; theOptions . session = false ; passport . authenticate ( provider , theOptions ) ( req , res , next ) ; } ; }

Configures the passport.authenticate for the given provider, passing in options Operation is 'login' or 'link'

Configures the passport . authenticate for the given provider passing in options Operation is login or link


function passportTokenCallback(provider, options) {
    return function(req, res, next) {
      var theOptions = extend({}, options);
      theOptions.session = false;
      passport.authenticate(provider + '-token', theOptions)(req, res, next);
    };
  }

function passportTokenCallback ( provider , options ) { return function ( req , res , next ) { var theOptions = extend ( { } , options ) ; theOptions . session = false ; passport . authenticate ( provider + '-token' , theOptions ) ( req , res , next ) ; } ; }

Configures the passport.authenticate for the given access_token provider, passing in options

Configures the passport . authenticate for the given access_token provider passing in options


function getProvider(pathname) {
    var items = pathname.split('/');
    var index = items.indexOf('callback');
    if(index > 0) {
      return items[index-1];
    }
  }

function getProvider ( pathname ) { var items = pathname . split ( '/' ) ; var index = items . indexOf ( 'callback' ) ; if ( index > 0 ) { return items [ index - 1 ] ; } }

Gets the provider name from a callback path


function getProviderToken(pathname) {
    var items = pathname.split('/');
    var index = items.indexOf('token');
    if(index > 0) {
      return items[index-1];
    }
  }

function getProviderToken ( pathname ) { var items = pathname . split ( '/' ) ; var index = items . indexOf ( 'token' ) ; if ( index > 0 ) { return items [ index - 1 ] ; } }

Gets the provider name from a callback path for access_token strategy


function requireRole(requiredRole) {
    return function(req, res, next) {
      if(!req.user) {
        return next(superloginError);
      }
      var roles = req.user.roles;
      if(!roles || !roles.length || roles.indexOf(requiredRole) === -1) {
        res.status(forbiddenError.status);
        res.json(forbiddenError);
      } else {
        next();
      }
    };
  }

function requireRole ( requiredRole ) { return function ( req , res , next ) { if ( ! req . user ) { return next ( superloginError ) ; } var roles = req . user . roles ; if ( ! roles || ! roles . length || roles . indexOf ( requiredRole ) === - 1 ) { res . status ( forbiddenError . status ) ; res . json ( forbiddenError ) ; } else { next ( ) ; } } ; }

Requires that the user have the specified role


function() {
    var foundLayer = null;
    $.each(projectedTiles, function (layerName, layer) {
      if (map.hasLayer(layer)) {
        foundLayer = layer;
      }
    });
    return foundLayer;
  }

function ( ) { var foundLayer = null ; $ . each ( projectedTiles , function ( layerName , layer ) { if ( map . hasLayer ( layer ) ) { foundLayer = layer ; } } ) ; return foundLayer ; }


function (crs, options) {
    switch(crs) {
      case "EPSG:3857":
      return L.CRS.EPSG3857;
      case "EPSG:3395":
      return L.CRS.EPSG3395;
      case "EPSG:4326":
      return L.CRS.EPSG4326;
      default:
        return this._defineMapCRS(crs, options);
    }
  }

function ( crs , options ) { switch ( crs ) { case "EPSG:3857" : return L . CRS . EPSG3857 ; case "EPSG:3395" : return L . CRS . EPSG3395 ; case "EPSG:4326" : return L . CRS . EPSG4326 ; default : return this . _defineMapCRS ( crs , options ) ; } }

Use default CRS classes for common codes, fallback to custom for all other codes.

Use default CRS classes for common codes fallback to custom for all other codes .


function (group) {
    var map = this;

    if (group.eachLayer) {
      group.eachLayer(function (layer) {
        map._updateAllLayers(layer);
      });
    } else {
      if (group.redraw) {
        group.redraw();
      } else if (group.update) {
        group.update();
      } else {
        console.log("Don't know how to update", group);
      }
    }
  }

function
(
group
)
{
var
map
=
this
;
if
(
group
.
eachLayer
)
{
group
.
eachLayer
(
function
(
layer
)
{
map
.
_updateAllLayers
(
layer
)
;
}
)
;
}
else
{
if
(
group
.
redraw
)
{
group
.
redraw
(
)
;
}
else
if
(
group
.
update
)
{
group
.
update
(
)
;
}
else
{
console
.
log
(
"Don't know how to update"
,
group
)
;
}
}
}

This recurses through all the map's layers to update layer positions after their positions moved.

This recurses through all the map s layers to update layer positions after their positions moved .


function (layersArray) {
    var fg = this._featureGroup,
      npg = this._nonPointGroup,
      chunked = this.options.chunkedLoading,
      chunkInterval = this.options.chunkInterval,
      chunkProgress = this.options.chunkProgress,
      newMarkers, i, l, m;

    if (this._map) {
      var offset = 0,
        started = (new Date()).getTime();
      var process = L.bind(function () {
        var start = (new Date()).getTime();
        for (; offset < layersArray.length; offset++) {
          if (chunked && offset % 200 === 0) {
            // every couple hundred markers, instrument the time elapsed since processing started:
            var elapsed = (new Date()).getTime() - start;
            if (elapsed > chunkInterval) {
              break; // been working too hard, time to take a break :-)
            }
          }

          m = layersArray[offset];

          //Not point data, can't be clustered
          if (!m.getLatLng) {
            npg.addLayer(m);
            continue;
          }

          if (this.hasLayer(m)) {
            continue;
          }

          this._addLayer(m, this._maxZoom);

          //If we just made a cluster of size 2 then we need to remove the other marker from the map (if it is) or we never will
          if (m.__parent) {
            if (m.__parent.getChildCount() === 2) {
              var markers = m.__parent.getAllChildMarkers(),
                otherMarker = markers[0] === m ? markers[1] : markers[0];
              fg.removeLayer(otherMarker);
            }
          }
        }

        if (chunkProgress) {
          // report progress and time elapsed:
          chunkProgress(offset, layersArray.length, (new Date()).getTime() - started);
        }

        if (offset === layersArray.length) {
          //Update the icons of all those visible clusters that were affected
          this._featureGroup.eachLayer(function (c) {
            if (c instanceof L.MarkerCluster && c._iconNeedsUpdate) {
              c._updateIcon();
            }
          });

          this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);
        } else {
          setTimeout(process, this.options.chunkDelay);
        }
      }, this);

      process();
    } else {
      newMarkers = [];
      for (i = 0, l = layersArray.length; i < l; i++) {
        m = layersArray[i];

        //Not point data, can't be clustered
        if (!m.getLatLng) {
          npg.addLayer(m);
          continue;
        }

        if (this.hasLayer(m)) {
          continue;
        }

        newMarkers.push(m);
      }
      this._needsClustering = this._needsClustering.concat(newMarkers);
    }
    return this;
  }

Takes an array of markers and adds them in bulk


function (layersArray) {
    var i, l, m,
      fg = this._featureGroup,
      npg = this._nonPointGroup;

    if (!this._map) {
      for (i = 0, l = layersArray.length; i < l; i++) {
        m = layersArray[i];
        this._arraySplice(this._needsClustering, m);
        npg.removeLayer(m);
      }
      return this;
    }

    for (i = 0, l = layersArray.length; i < l; i++) {
      m = layersArray[i];

      if (!m.__parent) {
        npg.removeLayer(m);
        continue;
      }

      this._removeLayer(m, true, true);

      if (fg.hasLayer(m)) {
        fg.removeLayer(m);
        if (m.setOpacity) {
          m.setOpacity(1);
        }
      }
    }

    //Fix up the clusters and markers on the map
    this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);

    fg.eachLayer(function (c) {
      if (c instanceof L.MarkerCluster) {
        c._updateIcon();
      }
    });

    return this;
  }

Takes an array of markers and removes them in bulk


function () {
    var bounds = new L.LatLngBounds();

    if (this._topClusterLevel) {
      bounds.extend(this._topClusterLevel._bounds);
    }

    for (var i = this._needsClustering.length - 1; i >= 0; i--) {
      bounds.extend(this._needsClustering[i].getLatLng());
    }

    bounds.extend(this._nonPointGroup.getBounds());

    return bounds;
  }

function ( ) { var bounds = new L . LatLngBounds ( ) ; if ( this . _topClusterLevel ) { bounds . extend ( this . _topClusterLevel . _bounds ) ; } for ( var i = this . _needsClustering . length - 1 ; i >= 0 ; i -- ) { bounds . extend ( this . _needsClustering [ i ] . getLatLng ( ) ) ; } bounds . extend ( this . _nonPointGroup . getBounds ( ) ) ; return bounds ; }

Override FeatureGroup.getBounds as it doesn't work

Override FeatureGroup . getBounds as it doesn t work


function (method, context) {
    var markers = this._needsClustering.slice(),
      i;

    if (this._topClusterLevel) {
      this._topClusterLevel.getAllChildMarkers(markers);
    }

    for (i = markers.length - 1; i >= 0; i--) {
      method.call(context, markers[i]);
    }

    this._nonPointGroup.eachLayer(method, context);
  }

function ( method , context ) { var markers = this . _needsClustering . slice ( ) , i ; if ( this . _topClusterLevel ) { this . _topClusterLevel . getAllChildMarkers ( markers ) ; } for ( i = markers . length - 1 ; i >= 0 ; i -- ) { method . call ( context , markers [ i ] ) ; } this . _nonPointGroup . eachLayer ( method , context ) ; }


function (layer) {
    if (!layer) {
      return false;
    }

    var i, anArray = this._needsClustering;

    for (i = anArray.length - 1; i >= 0; i--) {
      if (anArray[i] === layer) {
        return true;
      }
    }

    anArray = this._needsRemoving;
    for (i = anArray.length - 1; i >= 0; i--) {
      if (anArray[i] === layer) {
        return false;
      }
    }

    return !!(layer.__parent && layer.__parent._group === this) || this._nonPointGroup.hasLayer(layer);
  }

function ( layer ) { if ( ! layer ) { return false ; } var i , anArray = this . _needsClustering ; for ( i = anArray . length - 1 ; i >= 0 ; i -- ) { if ( anArray [ i ] === layer ) { return true ; } } anArray = this . _needsRemoving ; for ( i = anArray . length - 1 ; i >= 0 ; i -- ) { if ( anArray [ i ] === layer ) { return false ; } } return ! ! ( layer . __parent && layer . __parent . _group === this ) || this . _nonPointGroup . hasLayer ( layer ) ; }

Returns true if the given layer is in this MarkerClusterGroup


function (map) {
    this._map = map;
    var i, l, layer;

    if (!isFinite(this._map.getMaxZoom())) {
      throw "Map has no maxZoom specified";
    }

    this._featureGroup.onAdd(map);
    this._nonPointGroup.onAdd(map);

    if (!this._gridClusters) {
      this._generateInitialClusters();
    }

    for (i = 0, l = this._needsRemoving.length; i < l; i++) {
      layer = this._needsRemoving[i];
      this._removeLayer(layer, true);
    }
    this._needsRemoving = [];

    //Remember the current zoom level and bounds
    this._zoom = this._map.getZoom();
    this._currentShownBounds = this._getExpandedVisibleBounds();

    this._map.on('zoomend', this._zoomEnd, this);
    this._map.on('moveend', this._moveEnd, this);

    if (this._spiderfierOnAdd) { //TODO FIXME: Not sure how to have spiderfier add something on here nicely
      this._spiderfierOnAdd();
    }

    this._bindEvents();

    //Actually add our markers to the map:
    l = this._needsClustering;
    this._needsClustering = [];
    this.addLayers(l);
  }


function (map) {
    map.off('zoomend', this._zoomEnd, this);
    map.off('moveend', this._moveEnd, this);

    this._unbindEvents();

    //In case we are in a cluster animation
    this._map._mapPane.className = this._map._mapPane.className.replace(' leaflet-cluster-anim', '');

    if (this._spiderfierOnRemove) { //TODO FIXME: Not sure how to have spiderfier add something on here nicely
      this._spiderfierOnRemove();
    }

    //Clean up all the layers we added to the map
    this._hideCoverage();
    this._featureGroup.onRemove(map);
    this._nonPointGroup.onRemove(map);

    this._featureGroup.clearLayers();

    this._map = null;
  }


function (anArray, obj) {
    for (var i = anArray.length - 1; i >= 0; i--) {
      if (anArray[i] === obj) {
        anArray.splice(i, 1);
        return true;
      }
    }
  }

function ( anArray , obj ) { for ( var i = anArray . length - 1 ; i >= 0 ; i -- ) { if ( anArray [ i ] === obj ) { anArray . splice ( i , 1 ) ; return true ; } } }

Remove the given object from the given array


function (layer, newCluster) {
    if (newCluster === layer) {
      this._featureGroup.addLayer(layer);
    } else if (newCluster._childCount === 2) {
      newCluster._addToMap();

      var markers = newCluster.getAllChildMarkers();
      this._featureGroup.removeLayer(markers[0]);
      this._featureGroup.removeLayer(markers[1]);
    } else {
      newCluster._updateIcon();
    }
  }

function ( layer , newCluster ) { if ( newCluster === layer ) { this . _featureGroup . addLayer ( layer ) ; } else if ( newCluster . _childCount === 2 ) { newCluster . _addToMap ( ) ; var markers = newCluster . getAllChildMarkers ( ) ; this . _featureGroup . removeLayer ( markers [ 0 ] ) ; this . _featureGroup . removeLayer ( markers [ 1 ] ) ; } else { newCluster . _updateIcon ( ) ; } }


function (storageArray) {
    storageArray = storageArray || [];

    for (var i = this._childClusters.length - 1; i >= 0; i--) {
      this._childClusters[i].getAllChildMarkers(storageArray);
    }

    for (var j = this._markers.length - 1; j >= 0; j--) {
      storageArray.push(this._markers[j]);
    }

    return storageArray;
  }

function ( storageArray ) { storageArray = storageArray || [ ] ; for ( var i = this . _childClusters . length - 1 ; i >= 0 ; i -- ) { this . _childClusters [ i ] . getAllChildMarkers ( storageArray ) ; } for ( var j = this . _markers . length - 1 ; j >= 0 ; j -- ) { storageArray . push ( this . _markers [ j ] ) ; } return storageArray ; }

Recursively retrieve all child markers of this cluster


function () {
    var childClusters = this._childClusters.slice(),
      map = this._group._map,
      boundsZoom = map.getBoundsZoom(this._bounds),
      zoom = this._zoom + 1,
      mapZoom = map.getZoom(),
      i;

    //calculate how far we need to zoom down to see all of the markers
    while (childClusters.length > 0 && boundsZoom > zoom) {
      zoom++;
      var newClusters = [];
      for (i = 0; i < childClusters.length; i++) {
        newClusters = newClusters.concat(childClusters[i]._childClusters);
      }
      childClusters = newClusters;
    }

    if (boundsZoom > zoom) {
      this._group._map.setView(this._latlng, zoom);
    } else if (boundsZoom <= mapZoom) { //If fitBounds wouldn't zoom us down, zoom us down instead
      this._group._map.setView(this._latlng, mapZoom + 1);
    } else {
      this._group._map.fitBounds(this._bounds);
    }
  }

Zoom to the minimum of showing all of the child markers, or the extents of this cluster

Zoom to the minimum of showing all of the child markers or the extents of this cluster


function (marker) {
    var addedCount,
        addedLatLng = marker._wLatLng || marker._latlng;

    if (marker instanceof L.MarkerCluster) {
      this._bounds.extend(marker._bounds);
      addedCount = marker._childCount;
    } else {
      this._bounds.extend(addedLatLng);
      addedCount = 1;
    }

    if (!this._cLatLng) {
      // when clustering, take position of the first point as the cluster center
      this._cLatLng = marker._cLatLng || addedLatLng;
    }

    // when showing clusters, take weighted average of all points as cluster center
    var totalCount = this._childCount + addedCount;

    //Calculate weighted latlng for display
    if (!this._wLatLng) {
      this._latlng = this._wLatLng = new L.LatLng(addedLatLng.lat, addedLatLng.lng);
    } else {
      this._wLatLng.lat = (addedLatLng.lat * addedCount + this._wLatLng.lat * this._childCount) / totalCount;
      this._wLatLng.lng = (addedLatLng.lng * addedCount + this._wLatLng.lng * this._childCount) / totalCount;
    }
  }

Expand our bounds and tell our parent to


function () {
    if (this._group._spiderfied === this || this._group._inZoomAnimation) {
      return;
    }

    var childMarkers = this.getAllChildMarkers(),
      group = this._group,
      map = group._map,
      center = map.latLngToLayerPoint(this._latlng),
      positions;

    this._group._unspiderfy();
    this._group._spiderfied = this;

    //TODO Maybe: childMarkers order by distance to center

    if (childMarkers.length >= this._circleSpiralSwitchover) {
      positions = this._generatePointsSpiral(childMarkers.length, center);
    } else {
      center.y += 10; //Otherwise circles look wrong
      positions = this._generatePointsCircle(childMarkers.length, center);
    }

    this._animationSpiderfy(childMarkers, positions);
  }

show spiral instead of circle from this marker count upwards. 0 -> always spiral; Infinity -> always circle

show spiral instead of circle from this marker count upwards . 0 - > always spiral ; Infinity - > always circle


function (childMarkers, positions) {
    var group = this._group,
      map = group._map,
      fg = group._featureGroup,
      i, m, leg, newPos;

    for (i = childMarkers.length - 1; i >= 0; i--) {
      newPos = map.layerPointToLatLng(positions[i]);
      m = childMarkers[i];

      m._preSpiderfyLatlng = m._latlng;
      m.setLatLng(newPos);
      if (m.setZIndexOffset) {
        m.setZIndexOffset(1000000); //Make these appear on top of EVERYTHING
      }

      fg.addLayer(m);

      leg = new L.Polyline([this._latlng, newPos], { weight: 1.5, color: '#222' });
      map.addLayer(leg);
      m._spiderLeg = leg;
    }
    this.setOpacity(0.3);
    group.fire('spiderfied');
  }


function (layer) {
    if (layer._spiderLeg) {
      this._featureGroup.removeLayer(layer);

      layer.setOpacity(1);
      //Position will be fixed up immediately in _animationUnspiderfy
      layer.setZIndexOffset(0);

      this._map.removeLayer(layer._spiderLeg);
      delete layer._spiderLeg;
    }
  }

If the given layer is currently being spiderfied then we unspiderfy it so it isn't on the map anymore etc

If the given layer is currently being spiderfied then we unspiderfy it so it isn t on the map anymore etc


function addToMap(location, map) {
    var marker = L.marker(location.coordinates);
    marker.addTo(map);
  }

function addToMap ( location , map ) { var marker = L . marker ( location . coordinates ) ; marker . addTo ( map ) ; }

Have to create a separate marker for each map else weirdness happens


function interpolate (path, data) {
  return path.replace(/:(\w+)/g, function (match, param) {
    return data[param]
  })
}

function interpolate ( path , data ) { return path . replace ( / :(\w+) / g , function ( match , param ) { return data [ param ] } ) }

Interpolate the page path with pagination variables.

@param  {String} path
@param  {Object} data
@return {String}

Interpolate the page path with pagination variables .


function createPagesUtility (pages, index) {
  return function getPages (number) {
    var offset = Math.floor(number / 2)
    var start, end

    if (index + offset >= pages.length) {
      start = Math.max(0, pages.length - number)
      end = pages.length
    } else {
      start = Math.max(0, index - offset)
      end = Math.min(start + number, pages.length)
    }

    return pages.slice(start, end)
  }
}

function createPagesUtility ( pages , index ) { return function getPages ( number ) { var offset = Math . floor ( number / 2 ) var start , end if ( index + offset >= pages . length ) { start = Math . max ( 0 , pages . length - number ) end = pages . length } else { start = Math . max ( 0 , index - offset ) end = Math . min ( start + number , pages . length ) } return pages . slice ( start , end ) } }

Create a "get pages" utility for people to use when rendering.

@param  {Array}    pages
@param  {number}   index
@return {Function}

Create a get pages utility for people to use when rendering .


function() {
        var templates = { data: {} };

        var stringTemplateSource = function(template) {
            this.text = function(value) {
                if (arguments.length === 0) {
                    return templates[template];
                }
                templates[template] = value;
            };
        };

        var templateEngine = new ko.nativeTemplateEngine();
        templateEngine.makeTemplateSource = function(template) {
            return new stringTemplateSource(template);
        };

        templateEngine.addTemplate = function(key, value) {
            templates[key] = value;
        };

        return templateEngine;
    }

function ( ) { var templates = { data : { } } ; var stringTemplateSource = function ( template ) { this . text = function ( value ) { if ( arguments . length === 0 ) { return templates [ template ] ; } templates [ template ] = value ; } ; } ; var templateEngine = new ko . nativeTemplateEngine ( ) ; templateEngine . makeTemplateSource = function ( template ) { return new stringTemplateSource ( template ) ; } ; templateEngine . addTemplate = function ( key , value ) { templates [ key ] = value ; } ; return templateEngine ; }

helper engine that can use a template from a string


function Job(collection, data) {
    this.collection = collection;

    if (data) {
        // Convert plain object to JobData type
        data.__proto__ = JobData.prototype;
        this.data = data;
    } else {
        this.data = new JobData();
    }
}

function
Job
(
collection
,
data
)
{
this
.
collection
=
collection
;
if
(
data
)
{
// Convert plain object to JobData type
data
.
__proto__
=
JobData
.
prototype
;
this
.
data
=
data
;
}
else
{
this
.
data
=
new
JobData
(
)
;
}
}

Job retry specification
@typedef {Object} Job~Attempts
@property {string} strategy - Name of {@link Worker~strategyCallback} to use on retry
@property {number} count - total number of attempts so far
@property {number} delay - a delay constant for use in determining a delay.  In default linear strategy, this will be the delay between attempts

@constructor
@param {string} collection - The collection to save the job to
@param {Object} data - The Job data


function Worker(queues, options) {
    options || (options = {});

    this.empty = 0;
    this.queues = queues || [];
    this.interval = options.interval || 5000;

    this.callbacks = options.callbacks || {};
    this.strategies = options.strategies || {};
    this.universal = options.universal || false;

    // Default retry strategies
    this.strategies.linear || (this.strategies.linear = linear);
    this.strategies.exponential || (this.strategies.exponential = exponential);

    // This worker will only process jobs of this priority or higher
    this.minPriority = options.minPriority;

}

Options for a new worker
@typedef {Object} Worker~Options
@property {Number} interval - the polling interval for the worker. Note: The worker will process jobs, one at a time, as fast as possible while queues have waiting jobs
@property {Worker~Strategies} strategies - {@link Worker~Strategies} for retrying jobs
@property {Worker~Callbacks} callbacks - Map of {@link Worker~Callback} for processing jobs
@property {Number} minPriority - The lowest job priority the worker will process

@constructor
@param {string[]} queues - an array of queue names that this worker will listen for
@param {Worker~Options} options - {@link Worker~Options} Options object


function handleDragEvents(e) {
    e.stopPropagation();
    e.preventDefault();
    return this.emit(e.type, e);
  }

function handleDragEvents ( e ) { e . stopPropagation ( ) ; e . preventDefault ( ) ; return this . emit ( e . type , e ) ; }


function(value) {
            if(value != value || value === 0) {
                for(var i = this.length; i-- && !is(this[i], value);){}
            } else {
                i = [].indexOf.call(this, value);
            }
            return i;
        }

function ( value ) { if ( value != value || value === 0 ) { for ( var i = this . length ; i -- && ! is ( this [ i ] , value ) ; ) { } } else { i = [ ] . indexOf . call ( this , value ) ; } return i ; }

More reliable indexOf, courtesy of @WebReflection


function Tor(child, port, dir) {
  this.process = child;
  this.port    = port;
  this.dir     = dir;
}

function Tor ( child , port , dir ) { this . process = child ; this . port = port ; this . dir = dir ; }

A wrapper for the tor process containing its ChildProcess, port number
and data directory.

@param {ChildProcess} child
@param {int}          port
@param {string}       dir

A wrapper for the tor process containing its ChildProcess port number and data directory .


function getIncluded() {
  var args = config.files().included || getDefaultArgs() ||
              getPackageJsonArgs() || getBowerJsonArgs() || [];
  return _expandGlobs(args);
}

function getIncluded ( ) { var args = config . files ( ) . included || getDefaultArgs ( ) || getPackageJsonArgs ( ) || getBowerJsonArgs ( ) || [ ] ; return _expandGlobs ( args ) ; }

Returns an Array containing the included locations.

Returns an Array containing the included locations .


function getDefaultArgs() {
  var results = [];
  DEFAULT_PATHS.forEach(function(dir) {
    if( fs.existsSync(dir) ) results.push(dir);
  });
  return results.length == 0 ? null : results;
}

function getDefaultArgs ( ) { var results = [ ] ; DEFAULT_PATHS . forEach ( function ( dir ) { if ( fs . existsSync ( dir ) ) results . push ( dir ) ; } ) ; return results . length == 0 ? null : results ; }


function getPackageJsonArgs() {
  var results = [];
  var config = _loadJson('package.json');
  if( config.main ) results = results.concat(getMainFieldAsArray(config.main));
  if( config.files ) results = results.concat(config.files);
  return results.length == 0 ? null : results.filter(_uniqfilter);
}

function getPackageJsonArgs ( ) { var results = [ ] ; var config = _loadJson ( 'package.json' ) ; if ( config . main ) results = results . concat ( getMainFieldAsArray ( config . main ) ) ; if ( config . files ) results = results . concat ( config . files ) ; return results . length == 0 ? null : results . filter ( _uniqfilter ) ; }

Checks package . json for possible paths


function getBowerJsonArgs() {
  var results = [];
  var config = _loadJson('bower.json');
  if( config.main ) results = results.concat(getMainFieldAsArray(config.main));
  return results.length == 0 ? null : results.filter(_uniqfilter);
}

function getBowerJsonArgs ( ) { var results = [ ] ; var config = _loadJson ( 'bower.json' ) ; if ( config . main ) results = results . concat ( getMainFieldAsArray ( config . main ) ) ; return results . length == 0 ? null : results . filter ( _uniqfilter ) ; }


function getMainFieldAsArray(main) {
  if( main.constructor === Array ) {
    return main;
  } else {
    if( fs.existsSync(main) ) {
      return [main];
    } else if( fs.existsSync(main+'.js') ) {
      return [main+'.js'];
    } else {
      return [];
    }
  }
}

function getMainFieldAsArray ( main ) { if ( main . constructor === Array ) { return main ; } else { if ( fs . existsSync ( main ) ) { return [ main ] ; } else if ( fs . existsSync ( main + '.js' ) ) { return [ main + '.js' ] ; } else { return [ ] ; } } }

Returns an Array of the files mentioned in a 'main' field
If the value is noted without '.js' at the end, it is appended.

Returns an Array of the files mentioned in a main field If the value is noted without . js at the end it is appended .


function TorAgent(opts) {
  if (!(this instanceof TorAgent)) {
    return new TorAgent();
  }

  http.Agent.call(this, opts);

  this.socksHost   = opts.socksHost || 'localhost';
  this.socksPort   = opts.socksPort || 9050;
  this.defaultPort = 80;

  // Used when invoking TorAgent.create
  this.tor = opts.tor;

  // Prevent protocol check, wrap destroy
  this.protocol = null;
  this.defaultDestroy = this.destroy;
  this.destroy = this.destroyWrapper;
}

function
TorAgent
(
opts
)
{
if
(
!
(
this
instanceof
TorAgent
)
)
{
return
new
TorAgent
(
)
;
}
http
.
Agent
.
call
(
this
,
opts
)
;
this
.
socksHost
=
opts
.
socksHost
||
'localhost'
;
this
.
socksPort
=
opts
.
socksPort
||
9050
;
this
.
defaultPort
=
80
;
// Used when invoking TorAgent.create
this
.
tor
=
opts
.
tor
;
// Prevent protocol check, wrap destroy
this
.
protocol
=
;
this
.
defaultDestroy
=
this
.
destroy
;
this
.
destroy
=
this
.
destroyWrapper
;
}

An HTTP Agent for proxying requests through Tor using SOCKS5.

@param {object} opts

An HTTP Agent for proxying requests through Tor using SOCKS5 .


function run(inch_args, options) {
  var callback = function(filename) {
      LocalInch.run(inch_args || ['suggest'], filename, noop);
    }

  if( options.dry_run ) callback = noop;
  retriever.run(PathExtractor.extractPaths(inch_args), callback);
}

function run ( inch_args , options ) { var callback = function ( filename ) { LocalInch . run ( inch_args || [ 'suggest' ] , filename , noop ) ; } if ( options . dry_run ) callback = noop ; retriever . run ( PathExtractor . extractPaths ( inch_args ) , callback ) ; }


function shutdown(addr, b) {
	    if(addr<0 || addr>=maxDevices)
			throw 'address out of range';

	    if(b)
			spiTransfer(addr, OP_SHUTDOWN,0);
	    else
			spiTransfer(addr, OP_SHUTDOWN,1);
	}

function
shutdown
(
addr
,
b
)
{
if
(
addr
<
0
||
addr
>=
maxDevices
)
throw
'address out of range'
;
if
(
b
)
spiTransfer
(
addr
,
OP_SHUTDOWN
,
0
)
;
else
spiTransfer
(
addr
,
OP_SHUTDOWN
,
1
)
;
}

shutdown puts it into power saving sleep mode. call with false to wake it up.

shutdown puts it into power saving sleep mode . call with false to wake it up .


function setScanLimit(addr, limit) {
	    if(addr<0 || addr>=maxDevices)
			return;

		//console.log("OP_SCANLIMIT");
	    if(limit>=0 && limit<8)
	    	spiTransfer(addr, OP_SCANLIMIT,limit);
	}

function setScanLimit ( addr , limit ) { if ( addr < 0 || addr >= maxDevices ) return ; //console.log("OP_SCANLIMIT"); if ( limit >= 0 && limit < 8 ) spiTransfer ( addr , OP_SCANLIMIT , limit ) ; }

sets the number of pixels per row, pretty much always 8 for most devices.

sets the number of pixels per row pretty much always 8 for most devices .


function setBrightness(addr, intensity) {
	    if(addr<0 || addr>=maxDevices)
			return;
	 	if (typeof intensity == 'undefined') return;

		intensity = constrain(intensity, 0, 15);

		spiTransfer(addr, OP_INTENSITY,intensity);

	}

function setBrightness ( addr , intensity ) { if ( addr < 0 || addr >= maxDevices ) return ; if ( typeof intensity == 'undefined' ) return ; intensity = constrain ( intensity , 0 , 15 ) ; spiTransfer ( addr , OP_INTENSITY , intensity ) ; }

sets the brightness of the LEDs, 0 to 15


function clearDisplay(addr) {
	    if(addr<0 || addr>=maxDevices)
			throw 'address out of range';

	    var offset;

	    offset=addr*8;
	    for(var i=0;i<8;i++) {
			status[offset+i]=0;
			spiTransfer(addr, i+1,status[offset+i]);
	    }
	}

function
clearDisplay
(
addr
)
{
if
(
addr
<
0
||
addr
>=
maxDevices
)
throw
'address out of range'
;
var
offset
;
offset
=
addr
*
8
;
for
(
var
i
=
0
;
i
<
8
;
i
++
)
{
status
[
offset
+
i
]
=
0
;
spiTransfer
(
addr
,
i
+
1
,
status
[
offset
+
i
]
)
;
}
}


function showNumber(addr, num, decimalplaces, mindigits, leftjustified, pos, dontclear) {

	    if(addr<0 || addr>=maxDevices)
			throw 'address out of range';

		num = formatNumber(num, decimalplaces, mindigits);

		// internally, pos is 0 on the right, so we set defaults, and convert
		if(typeof pos === 'undefined') {
			if(leftjustified) {
				pos = 7;
			} else {
				pos = 0;
			}
		} else pos = 7-pos;

		// get rid of the decimal place but remember where it was
		var decimalplace;
		if(num.indexOf('.')<0) decimalplace = -1;
		else {
			decimalplace = num.length - num.indexOf('.') -1;
			num = num.split('.').join('');
		}
		if(leftjustified) {
			pos-=(num.length-1);
		}

		for(var i = 0; i<8; i++) {
			var offset = i+pos;
			var char = num.charAt(num.length-1-i);

			if((offset<8 && offset>=0) && (!dontclear || char!=''))
			{
				if(char=='-') setChar(addr, offset, char, i>0 && i==decimalplace);
				else setDigit(addr, offset, parseInt(char), i>0 && i==decimalplace);
			}
		}

	}

pos is passed in as 0 to 7, 0 on the left, 7 on the right

pos is passed in as 0 to 7 0 on the left 7 on the right


function getExampleCode(comment) {
  var expectedResult = comment.expectedResult;
  var isAsync = comment.isAsync;
  var testCase = comment.testCase;

  if(isAsync) {
    return '\nfunction cb(err, result) {' +
      'if(err) return done(err);' +
      'result.should.eql(' + expectedResult + ');' +
      'done();' +
    '}\n' +
    'var returnValue = ' + testCase + ';' +
    'if(returnValue && returnValue.then && typeof returnValue.then === \'function\') {' +
      'returnValue.then(cb.bind(null, null), cb);' +
    '}';
  } else {
    return '(' + testCase + ').should.eql(' + expectedResult + ');';
  }
}

Compiles down an `example`. Async examples call an imaginary `done` function
once they're done.

@param {Object} comment
@param {String} comment.testCase
@param {String} comment.expectedResult
@param {Boolean} comment.isAsync
@return {String}

Compiles down an example . Async examples call an imaginary done function once they re done .


function (options) {
    "use strict";
    if ((options.setter && options.setter.indexOf('.') > -1) || (options.getter && options.getter.indexOf('.') > -1)) {
        throw new Error('Getter (' + options.getter + ') and setter (' + options.setter + ') methods cannot be nested, so they cannot contain dot(.)');
    }

    this.options = Joi.attempt(options, optionsSchema);
    this.locales = this.getAvailableLocales();
    this.default = this.options.default || this.locales[0];
    //this.callback   = this.getCallback(this.options.callback);
}

Class to implement inner working of plugin.
@param {PluginOptions} options     - Plugin configuration options.
@constructor
@private

Class to implement inner working of plugin .


function fileExists(path, shouldBeDir) {
    "use strict";
    try {
        var lstat = fs.lstatSync(path);
        if (shouldBeDir && lstat.isDirectory()) {
            return true;
        }
        if (!shouldBeDir && lstat.isFile()) {
            return true;
        }
    } catch (err) {
        return false;
    }
    return false;
}

function
fileExists
(
path
,
shouldBeDir
)
{
"use strict"
;
try
{
var
lstat
=
fs
.
lstatSync
(
path
)
;
if
(
shouldBeDir
&&
lstat
.
isDirectory
(
)
)
{
return
true
;
}
if
(
!
shouldBeDir
&&
lstat
.
isFile
(
)
)
{
return
true
;
}
}
catch
(
err
)
{
return
false
;
}
return
false
;
}

Checks synchroniously if given file or directory exists. Returns true or false.
@param {string}  path        - Path of the file or directory.
@param {boolean} shouldBeDir - Whether given path should be directory.
@returns {boolean}
@private

Checks synchroniously if given file or directory exists . Returns true or false .


async function (server, options) {
        try {
            var internal = new Internal(options);
        } catch (err) {
            throw new Boom(err);
        }

        /**
         * @module exposed
         * @description
         * Exposed functions and attributes are listed under exposed name.
         * To access those attributes `request.server.plugins['hapi-locale']` can be used.
         * @example
         * var locales = request.server.plugins['hapi-locale'].getLocales(); // ['tr_TR', 'en_US'] etc.
         */

        /**
         * Returns all available locales as an array.
         * @name getLocales
         * @function
         * @returns {Array.<string>}    - Array of locales.
         * @example
         * var locales = request.server.plugins['hapi-locale'].getLocales(); // ['tr_TR', 'en_US'] etc.
         */
        server.expose('getLocales', function getLocales() {
            return internal.locales;
        });

        /**
         * Returns default locale.
         * @name getDefaultLocale
         * @function
         * @returns {string}    - Default locale
         */
        server.expose('getDefaultLocale', function getDefaultLocale() {
            return internal.default;
        });

        /**
         * Returns requested language.
         * @name getLocale
         * @function
         * @param {Object}      request - Hapi.js request object
         * @returns {string}    Locale
         */
        server.expose('getLocale', function getLocale(request) {
            try {
                return lodash.get(request, internal.options.getter)();
            } catch (err) {
                return null;
            }
        });

        server.ext(internal.options.onEvent, internal.processRequest, {bind: internal});
    }

Hapi plugin function which adds i18n support to request and response objects.
@param {Object}          server      - Hapi server object
@param {PluginOptions}   options     - Plugin configuration options.

Hapi plugin function which adds i18n support to request and response objects .


function (currDeps, loc) {
      loc.deps = loc.deps || [];
      var covered = []; // only cover unique paths once to avoid stack overflow
      currDeps.forEach(function (obj) {
        if (covered.indexOf(obj.path) < 0) {
          covered.push(obj.path); // cover unique paths only once per level

          var key = obj.name
            , isRelative = (['\\', '/', '.'].indexOf(key[0]) >= 0)
            , notCovered = notCoveredInArray(loc.deps, key)
            , isRecorded = (!isRelative || opts.showLocal) && notCovered
            , res = isRecorded ? { name: key } : loc;

          if (isRecorded) {
            // NB: !isRecorded => only inspect the file for recorded deps
            res.path = obj.path;
            loc.deps.push(res);
          }

          // recurse (!isRecorded => keep adding to previous location)
          traverse(lookup[obj.path] || [], res);
        }
      });
    }

build a dependency tree from the flat mdeps list by recursing


function (ms, cycles) {
  var removed = {};

  cycles.forEach(function (c) {
    var last = c[c.length-1]; // last id in cycle
    //console.log('will try to trim from', last, ms[last]);

    // need to find a dependency in the cycle
    var depsInCycle = ms[last].filter(function (deps) {
      return deps.path && c.indexOf(deps.path) >= 0;
    });
    if (!depsInCycle.length) {
      throw new Error("logic fail2"); // last thing in a cycle should have deps
    }
    var depToRemove = depsInCycle[0].path;
    //console.log('deps in cycle', depsInCycle);

    for (var i = 0; i < ms[last].length; i += 1) {
      var dep = ms[last][i];
      if (dep.path && dep.path === depToRemove) {
        //console.log('removing', depToRemove);
        removed[last] = dep.name;
        ms[last].splice(i, 1);
      }
    }
    //console.log('after remove', ms[last]);
  });

  return removed;
}

given a modules array with cycles - trim dependencies in each cycle


function(options) {
  // Validate options
  assert(options,         "options are required");
  assert(options.name,    "Series must be named");
  options = _.defaults({}, options, {
    columns:              {},
    additionalColumns:    null
  });

  // Store options
  this._options = options;
}

function
(
options
)
{
// Validate options
assert
(
options
,
"options are required"
)
;
assert
(
options
.
name
,
"Series must be named"
)
;
options
=
_
.
defaults
(
{
}
,
options
,
{
columns
:
{
}
,
additionalColumns
:
}
)
;
// Store options
this
.
_options
=
options
;
}

Create a times series that you can report to.

options:
{
// Name of the series in influxdb
name:               'ResponseTimes',

// Required columns
columns: {
method:           stats.types.String,
duration:         stats.types.Number,
custom:           stats.types.Any
},

// Type of additional columns if they are allowed (defaults `null`)
additionalColumns:  stats.types.String
}

Create a times series that you can report to .


function whenRead (args) {
    let value = getValue(args)
    if (value && typeof value.then === 'function') {
      value.then((val) => whenTest(args, val)).catch((error) => {
        console.error(`${action.displayName} caught an error whilst getting a value to test`, error)
      })
    } else {
      whenTest(args, value)
    }
  }

function whenRead ( args ) { let value = getValue ( args ) if ( value && typeof value . then === 'function' ) { value . then ( ( val ) => whenTest ( args , val ) ) . catch ( ( error ) => { console . error ( ` ${ action . displayName } ` , error ) } ) } else { whenTest ( args , value ) } }


function findAndDelete(target, value) {
    if (!isIterable(target))
        return false;
    if (isArray(target)) {
        for (let i = 0; i < target.length; i++) {
            if (deep_equal_1.default(target[i], value)) {
                target.splice(i, 1);
                return true;
            }
        }
    }
    else if (isObject(target)) {
        const keys = Object.keys(target);
        for (let i = 0; i < keys.length; i++) {
            if (deep_equal_1.default(target[keys[i]], value)) {
                delete target[keys[i]];
                return true;
            }
        }
    }
    return false;
}

function findAndDelete ( target , value ) { if ( ! isIterable ( target ) ) return false ; if ( isArray ( target ) ) { for ( let i = 0 ; i < target . length ; i ++ ) { if ( deep_equal_1 . default ( target [ i ] , value ) ) { target . splice ( i , 1 ) ; return true ; } } } else if ( isObject ( target ) ) { const keys = Object . keys ( target ) ; for ( let i = 0 ; i < keys . length ; i ++ ) { if ( deep_equal_1 . default ( target [ keys [ i ] ] , value ) ) { delete target [ keys [ i ] ] ; return true ; } } } return false ; }

Finds and deletes first encounter of value in target
@param target
@param value
@returns true if an element has been deleted, otherwise - false


function findAndDeleteAll(target, value) {
    let flag = false;
    while (findAndDelete(target, value)) {
        flag = true;
    }
    return flag;
}

function findAndDeleteAll ( target , value ) { let flag = false ; while ( findAndDelete ( target , value ) ) { flag = true ; } return flag ; }

Finds and deletes all encounters of value in target
@param target
@param value
@returns true if anything has been deleted, otherwise - false


function(options) {
  assert(options,                   "options are required");
  assert(options.connectionString,  "options.connectionString is missing");
  assert(url.parse(options.connectionString).protocol === 'https:' ||
         options.allowHTTP, "InfluxDB connectionString must use HTTPS!");
  options = _.defaults({}, options, {
    maxDelay:             60 * 5,
    maxPendingPoints:     250
  });
  this._options           = options;
  this._pendingPoints     = {};
  this._nbPendingPoints   = 0;
  this._flushTimeout = setTimeout(
    this.flush.bind(this, true),
    options.maxDelay * 1000
  );
}

Create an Influx Database Connection

options:
{
// Connection string for
connectionString:  '<protocol>://<user>:<pwd>@<host>:<port>/db/<database>',

// Max submission delay
maxDelay:          60 * 5, // 5 minutes

// Maximum number of pending points before writing
maxPendingPoints:  250,

// Allow the connection string to use HTTP instead of HTTPS, this option
// is just to prevent accidental deployments with HTTP instead of HTTPS
// (there is no reason not to use HTTPS).
allowHTTP:         false
}


function(handler, options) {
  assert(handler instanceof Function, "A handler must be provided");
  assert(options,                     "options required");
  assert(options.drain,               "options.drain is required");
  assert(options.component,           "options.component is required");

  // Create a reporter
  var reporter = series.HandlerReports.reporter(options.drain);

  // Wrap handler and let that be it
  return function(message) {
    // Create most of the point
    var point = {
      component:      options.component,
      duration:       undefined,
      exchange:       message.exchange || '',
      redelivered:    (message.redelivered ? 'true' : 'false'),
      error:          'false'
    };

    // Start timer
    var start = process.hrtime();

    // Handle the message
    return Promise.resolve(handler(message)).then(function() {
      // Get duration
      var d = process.hrtime(start);

      // Convert to milliseconds
      point.duration = d[0] * 1000 + (d[1] / 1000000);

      // Send point to reporter
      reporter(point);
    }, function(err) {
      // Get duration
      var d = process.hrtime(start);

      // Convert to milliseconds
      point.duration = d[0] * 1000 + (d[1] / 1000000);

      // Flag and error
      point.error = 'true';

      // Send point to reporter
      reporter(point);

      // Re-throw the error
      throw err;
    });
  };
}

function
(
handler
,
options
)
{
assert
(
handler
instanceof
Function
,
"A handler must be provided"
)
;
assert
(
options
,
"options required"
)
;
assert
(
options
.
drain
,
"options.drain is required"
)
;
assert
(
options
.
component
,
"options.component is required"
)
;
// Create a reporter
var
reporter
=
series
.
HandlerReports
.
reporter
(
options
.
drain
)
;
// Wrap handler and let that be it
return
function
(
message
)
{
// Create most of the point
var
point
=
{
component
:
options
.
component
,
duration
:
undefined
,
exchange
:
message
.
exchange
||
''
,
redelivered
:
(
message
.
redelivered
'true'
:
'false'
)
,
error
:
'false'
}
;
// Start timer
var
start
=
process
.
hrtime
(
)
;
// Handle the message
return
Promise
.
resolve
(
handler
(
message
)
)
.
then
(
function
(
)
{
// Get duration
var
d
=
process
.
hrtime
(
start
)
;
// Convert to milliseconds
point
.
duration
=
d
[
0
]
*
1000
+
(
d
[
1
]
/
1000000
)
;
// Send point to reporter
reporter
(
point
)
;
}
,
function
(
err
)
{
// Get duration
var
d
=
process
.
hrtime
(
start
)
;
// Convert to milliseconds
point
.
duration
=
d
[
0
]
*
1000
+
(
d
[
1
]
/
1000000
)
;
// Flag and error
point
.
error
=
'true'
;
// Send point to reporter
reporter
(
point
)
;
// Re-throw the error
throw
err
;
}
)
;
}
;
}

Create a handler timer for AMQP messages received through
taskcluster-client. Please note, that this relies on that messages format.

options:
{
drain:        new Influx(...),  // Place to send events
component:    'queue'           // Identifier for taskcluster component
}

Create a handler timer for AMQP messages received through taskcluster - client . Please note that this relies on that messages format .


function(options) {
  // Validate options
  assert(options,           "Options are required");
  assert(options.drain,     "A drain for the measurements must be provided!");
  assert(options.component, "A component must be specified");
  assert(options.process,   "A process name must be specified");

  // Provide default options
  options = _.defaults({}, options, {
    interval:         60
  });

  // Clear reporting if already started
  if (_processUsageReportingInterval) {
    debug("WARNING: startProcessUsageReporting() already started!");
    clearInterval(_processUsageReportingInterval);
    _processUsageReportingInterval = null;
  }

  // Lazy load the usage monitor module
  var usage = require('usage');

  // Create reporter
  var reporter = series.UsageReports.reporter(options.drain);

  // Set interval to report usage at interval
  _processUsageReportingInterval = setInterval(function() {
    // Lookup usage for the current process
    usage.lookup(process.pid, {keepHistory: true}, function(err, result) {
      // Check for error
      if (err) {
        debug("Failed to get usage statistics, err: %s, %j",
              err, err, err.stack);
        return;
      }

      // Report usage
      reporter({
        component:      options.component,
        process:        options.process,
        cpu:            result.cpu,
        memory:         result.memory
      });
    });
  }, options.interval * 1000);
}

Monitor CPU and memory for this instance.

options: {
drain:        new Influx(...), // Place to send the pings
interval:     60,              // Report every 1 minute
component:    'queue',         // Identifier for the taskcluster component
process:      'server'         // Process name
}

Note, this is global in the current process.

Monitor CPU and memory for this instance .


function(options) {
  options = _.defaults({}, options || {}, {
    tags:   {},
    drain:  undefined
  });
  assert(options.drain,                     "options.drain is required");
  assert(typeof options.tags === 'object',  "options.tags is required");
  assert(_.intersection(
    _.keys(options.tags), series.APIClientCalls.columns()
  ).length === 0, "Can't used reserved tag names!");

  // Create a reporter
  return series.APIClientCalls.reporter(options.drain, options.tags);
}

function
(
options
)
{
options
=
_
.
defaults
(
{
}
,
options
||
{
}
,
{
tags
:
{
}
,
drain
:
undefined
}
)
;
assert
(
options
.
drain
,
"options.drain is required"
)
;
assert
(
typeof
options
.
tags
===
'object'
,
"options.tags is required"
)
;
assert
(
_
.
intersection
(
_
.
keys
(
options
.
tags
)
,
series
.
APIClientCalls
.
columns
(
)
)
.
length
===
0
,
"Can't used reserved tag names!"
)
;
// Create a reporter
return
series
.
APIClientCalls
.
reporter
(
options
.
drain
,
options
.
tags
)
;
}

Create a stats handler for taskcluster-client clients which takes an option
`stats` as function that will be call after an API call.

options:
{
tags: {                         // Tags as key/value (both strings)
component: 'queue',           // Component identifier
process:   'web'              // Process identifier
// Common tags that are good to use includes:
//     component, process, provisionerId, workerType
},
drain:        new Influx(...),  // Place to send events
}

Create a stats handler for taskcluster - client clients which takes an option stats as function that will be call after an API call .


function buildOptions (options) {
  var result = [];

  var keys = Object.keys(options);

  keys.forEach(function (key) {
    var props = options[key];

    // convert short to long form
    if (is.string(props)) {
      props = {
        type: props
      };
    }

    // all names of an option
    // aliases come first
    // full name comes last
    var name = [
      format('--%s', dasherize(key))
    ];

    // accept both string and array
    var aliases = props.alias || props.aliases || [];

    if (is.not.array(aliases)) {
      aliases = [aliases];
    }

    // aliases are prefixed with "-"
    aliases.forEach(function (alias) {
      alias = format('-%s', alias);

      name.unshift(alias);
    });

    result.push([
      name.join(', '),
      props.desc || ''
    ]);
  });

  return table(result);
}

function
buildOptions
(
options
)
{
var
result
=
[
]
;
var
keys
=
Object
.
keys
(
options
)
;
keys
.
forEach
(
function
(
key
)
{
var
props
=
options
[
key
]
;
// convert short to long form
if
(
is
.
string
(
props
)
)
{
props
=
{
type
:
props
}
;
}
// all names of an option
// aliases come first
// full name comes last
var
name
=
[
format
(
'--%s'
,
dasherize
(
key
)
)
]
;
// accept both string and array
var
aliases
=
props
.
alias
||
props
.
aliases
||
[
]
;
if
(
is
.
not
.
array
(
aliases
)
)
{
aliases
=
[
aliases
]
;
}
// aliases are prefixed with "-"
aliases
.
forEach
(
function
(
alias
)
{
alias
=
format
(
'-%s'
,
alias
)
;
name
.
unshift
(
alias
)
;
}
)
;
result
.
push
(
[
name
.
join
(
', '
)
,
props
.
desc
||
''
]
)
;
}
)
;
return
table
(
result
)
;
}


function buildCommands (commands) {
  var result = [];

  commands.forEach(function (command) {
    result.push([
      command.name,
      command.desc || ''
    ]);
  });

  return table(result);
}

function buildCommands ( commands ) { var result = [ ] ; commands . forEach ( function ( command ) { result . push ( [ command . name , command . desc || '' ] ) ; } ) ; return table ( result ) ; }


function Router(options) {
	const logPrefix = topLogPrefix + 'Router() - ';
	const that      = this;

	let defaultRouteFound = false;

	that.options = options || {};

	if (! that.options.paths) {
		that.options.paths = {
			'controller': {
				'path': 'controllers',
				'exts': 'js'
			},
			'static': {
				'path': 'public',
				'exts': false
			},
			'template': {
				'path': 'public/templates',
				'exts': ['tmpl', 'tmp', 'ejs', 'pug']
			}
		};
	}

	if (! that.options.routes)   that.options.routes   = [];
	if (! that.options.basePath) that.options.basePath = process.cwd();

	if (! that.options.log) {
		const lUtils = new LUtils();

		that.options.log = new lUtils.Log();
	}

	for (const key of Object.keys(that.options.paths)) {
		if (! Array.isArray(that.options.paths[key].exts) && that.options.paths[key].exts !== false) {
			that.options.paths[key].exts = [that.options.paths[key].exts];
		}
	}

	if (! that.options.lfs) {
		that.options.lfs = new Lfs({'basePath': that.options.basePath, 'log': that.options.log});
	}

	for (let i = 0; that.options.routes[i] !== undefined; i ++) {
		if (that.options.routes[i].regex === '^/$') {
			defaultRouteFound = true;
			break;
		}
	}

	// We should always have a default route, so if none exists, create one
	if (defaultRouteFound === false) {
		that.options.routes.push({
			'regex':          '^/$',
			'controllerPath': 'default.js',
			'templatePath':   'default.tmpl'
		});
	}

	for (const key of Object.keys(that.options)) {
		that[key] = that.options[key];
	}

	that.log.debug(logPrefix + 'Instantiated with options: ' + JSON.stringify(that.options));
}

Module main constructor

@param {obj} options - {
'paths':           {
'controller': {
'path': 'controllers',
'exts': 'js'
},
'static': {
'path': 'public',
'exts': false
},
'template': {
'path': 'public/templates',
'exts': ['tmpl', 'tmp', 'ejs', 'pug']
}
},
'routes':   [],
'basePath': process.cwd(),
'log':      log object,
'lfs':      larvitfs instance
}


function getDefaultPortByProtocol (rawProtocol) {
  // port-numbers expect no trailing colon
  const protocol = rawProtocol.endsWith(':')
    ? rawProtocol.slice(0, -1)
    : rawProtocol

  // e.g. mailto has no port associated
  // example return value:
  // { port: 80, protocol: 'tcp', description: 'World Wide Web HTTP' }
  const portByProtocol = portNumbers.getPort(protocol)

  return portByProtocol
    ? Promise.resolve(String(portByProtocol.port))
    : Promise.reject(new Error('Has no port'))
}

Helper method to look up port by protocol.

@private
@param {string} rawProtocol - Protocol as returned by url, i.e. with :
@returns {Promise<string|Error>}
Associated port with protocol.
Or an Error if the validation failed (e.g. mailto:).

Helper method to look up port by protocol .


function clearScripts(node){
      var rslt = {};
      for(var key in node){
        var val = node[key];
        if(_.isString(val)){
          if(val.trim()) rslt[key] = "...";
        }
        else{
          var childScripts = clearScripts(val);
          if(!_.isEmpty(childScripts)) rslt[key] = childScripts;
        }
      }
      return rslt;
    }

function clearScripts ( node ) { var rslt = { } ; for ( var key in node ) { var val = node [ key ] ; if ( _ . isString ( val ) ) { if ( val . trim ( ) ) rslt [ key ] = "..." ; } else { var childScripts = clearScripts ( val ) ; if ( ! _ . isEmpty ( childScripts ) ) rslt [ key ] = childScripts ; } } return rslt ; }

Replace scripts with "..." and prune empty scripts

Replace scripts with ... and prune empty scripts


function(obj, array){
    if(!Array.prototype.indexOf){
      for(var i=0; i<array.length; i++){
          if(array[i]===obj){
              return i;
          }
      }
      return -1;
    }
    else {
      return array.indexOf(obj);
    }
  }

function ( obj , array ) { if ( ! Array . prototype . indexOf ) { for ( var i = 0 ; i < array . length ; i ++ ) { if ( array [ i ] === obj ) { return i ; } } return - 1 ; } else { return array . indexOf ( obj ) ; } }


function getElementValues(nodeList, initialScope) {
    const valueList = []

    for (let i = 0; i < nodeList.length; ++i) {
        const elementNode = nodeList[i]

        if (elementNode == null) {
            valueList.length = i + 1
        } else if (elementNode.type === "SpreadElement") {
            const argument = getStaticValueR(elementNode.argument, initialScope)
            if (argument == null) {
                return null
            }
            valueList.push(...argument.value)
        } else {
            const element = getStaticValueR(elementNode, initialScope)
            if (element == null) {
                return null
            }
            valueList.push(element.value)
        }
    }

    return valueList
}

function getElementValues ( nodeList , initialScope ) { const valueList = [ ] for ( let i = 0 ; i < nodeList . length ; ++ i ) { const elementNode = nodeList [ i ] if ( elementNode == null ) { valueList . length = i + 1 } else if ( elementNode . type === "SpreadElement" ) { const argument = getStaticValueR ( elementNode . argument , initialScope ) if ( argument == null ) { return null } valueList . push ( ... argument . value ) } else { const element = getStaticValueR ( elementNode , initialScope ) if ( element == null ) { return null } valueList . push ( element . value ) } } return valueList }

Get the element values of a given node list.
@param {Node[]} nodeList The node list to get values.
@param {Scope|undefined} initialScope The initial scope to find variables.
@returns {any[]|null} The value list if all nodes are constant. Otherwise, null.

Get the element values of a given node list .


function getStaticValueR(node, initialScope) {
    if (node != null && Object.hasOwnProperty.call(operations, node.type)) {
        return operations[node.type](node, initialScope)
    }
    return null
}

function getStaticValueR ( node , initialScope ) { if ( node != null && Object . hasOwnProperty . call ( operations , node . type ) ) { return operations [ node . type ] ( node , initialScope ) } return null }

Get the value of a given node if it's a static value.
@param {Node} node The node to get.
@param {Scope|undefined} initialScope The scope to start finding variable.
@returns {{value:any}|null} The static value of the node, or `null`.

Get the value of a given node if it s a static value .


function isModifiedGlobal(variable) {
    return (
        variable == null ||
        variable.defs.length !== 0 ||
        variable.references.some(r => r.isWrite())
    )
}

function isModifiedGlobal ( variable ) { return ( variable == null || variable . defs . length !== 0 || variable . references . some ( r => r . isWrite ( ) ) ) }

Check whether a given variable is modified or not.
@param {Variable} variable The variable to check.
@returns {boolean} `true` if the variable is modified.

Check whether a given variable is modified or not .


function config(ext) {
    return {
        input: "src/index.js",
        output: {
            file: `index${ext}`,
            format: ext === ".mjs" ? "es" : "cjs",
            sourcemap: true,
            sourcemapFile: `index${ext}.map`,
            strict: true,
            banner: `/*! @author Toru Nagashima <https://github.com/mysticatea> */`,
        },
        plugins: [sourcemaps()],
        external: Object.keys(require("./package.json").dependencies),
    }
}

function config ( ext ) { return { input : "src/index.js" , output : { file : ` ${ ext } ` , format : ext === ".mjs" ? "es" : "cjs" , sourcemap : true , sourcemapFile : ` ${ ext } ` , strict : true , banner : ` ` , } , plugins : [ sourcemaps ( ) ] , external : Object . keys ( require ( "./package.json" ) . dependencies ) , } }

Define the output configuration.
@param {string} ext The extension for generated files.
@returns {object} The output configuration


function isEscaped(str, index) {
    let escaped = false
    for (let i = index - 1; i >= 0 && str.charCodeAt(i) === 0x5c; --i) {
        escaped = !escaped
    }
    return escaped
}

function isEscaped ( str , index ) { let escaped = false for ( let i = index - 1 ; i >= 0 && str . charCodeAt ( i ) === 0x5c ; -- i ) { escaped = ! escaped } return escaped }

Check whether a given character is escaped or not.
@param {string} str The string to check.
@param {number} index The location of the character to check.
@returns {boolean} `true` if the character is escaped.

Check whether a given character is escaped or not .


function replaceS(matcher, str, replacement) {
    const chunks = []
    let index = 0

    /** @type {RegExpExecArray} */
    let match = null

    /**
     * @param {string} key The placeholder.
     * @returns {string} The replaced string.
     */
    function replacer(key) {
        switch (key) {
            case "$$":
                return "$"
            case "$&":
                return match[0]
            case "$`":
                return str.slice(0, match.index)
            case "$'":
                return str.slice(match.index + match[0].length)
            default: {
                const i = key.slice(1)
                if (i in match) {
                    return match[i]
                }
                return key
            }
        }
    }

    for (match of matcher.execAll(str)) {
        chunks.push(str.slice(index, match.index))
        chunks.push(replacement.replace(placeholder, replacer))
        index = match.index + match[0].length
    }
    chunks.push(str.slice(index))

    return chunks.join("")
}

Replace a given string by a given matcher.
@param {PatternMatcher} matcher The pattern matcher.
@param {string} str The string to be replaced.
@param {string} replacement The new substring to replace each matched part.
@returns {string} The replaced string.

Replace a given string by a given matcher .


function replaceF(matcher, str, replace) {
    const chunks = []
    let index = 0

    for (const match of matcher.execAll(str)) {
        chunks.push(str.slice(index, match.index))
        chunks.push(String(replace(...match, match.index, match.input)))
        index = match.index + match[0].length
    }
    chunks.push(str.slice(index))

    return chunks.join("")
}

function replaceF ( matcher , str , replace ) { const chunks = [ ] let index = 0 for ( const match of matcher . execAll ( str ) ) { chunks . push ( str . slice ( index , match . index ) ) chunks . push ( String ( replace ( ... match , match . index , match . input ) ) ) index = match . index + match [ 0 ] . length } chunks . push ( str . slice ( index ) ) return chunks . join ( "" ) }

eslint-disable-next-line valid-jsdoc
Replace a given string by a given matcher.
@param {PatternMatcher} matcher The pattern matcher.
@param {string} str The string to be replaced.
@param {(...strs[])=>string} replace The function to replace each matched part.
@returns {string} The replaced string.

eslint - disable - next - line valid - jsdoc Replace a given string by a given matcher .


function send(msg) {
    switch(ps.readyState) {
      case 0: // CONNECTING
        setTimeout(function () { send(msg); }, 1000);
        break;
      case 2: // CLOSING
      case 3: // CLOSED
        _event('dev', 'pubsub - reconnect: send() - closing/closed state');
        connect();
        setTimeout(function () { send(msg); }, 2000);
        break;
      case 1: // OPEN
        try {
          ps.send(msg);
        } catch (err) {
          console.error(err);
          setTimeout(function () { send(msg); }, 1500);
        }
        break;
      default:
        break;
		}
  }

this provides some preventative error handling because the pubsub edge seems to be unstable


function parseMessage(data) {
    switch (data.topic) {
      // https://dev.twitch.tv/docs/v5/guides/PubSub/
      case 'channel-bits-events-v1.' + state.channel_id:
        bits();
        break;
      // https://discuss.dev.twitch.tv/t/in-line-broadcaster-chat-mod-logs/7281/12
      case 'chat_moderator_actions.' + state.id + '.' + state.id:
        moderation();
        break;
      case 'whispers.' + state.id:
        whisper();
        break;
      // case 'channel-subscribe-events-v1.' + state.channel_id:
      //   sub();
      //   break;
      default:
        break;
    }

    function bits() {
      let bits = JSON.parse(data.message);
      _event('bits', bits);
    }

    function moderation() {
      let moderation = JSON.parse(data.message).data;
      _event('moderation', moderation);
    }

    function whisper() {
      let message = JSON.parse(data.message).data_object;
      // TODO: figure out why some whispers are dropped...
      // _event('whisper', message);
    }

    // function sub() {
    //   // TODO: https://discuss.dev.twitch.tv/t/subscriptions-beta-changes/10023
    // }

  }

data is message.data, so it should have msg.topic and msg.message

data is message . data so it should have msg . topic and msg . message


function JWT(secret, options) {
    this.token = '';
    this.payload = {};
    this.secret = secret;
    this.options = options;
    this.valid = false;
    this.expired = false;
    this.stale = true;
}

function JWT ( secret , options ) { this . token = '' ; this . payload = { } ; this . secret = secret ; this . options = options ; this . valid = false ; this . expired = false ; this . stale = true ; }

JWT - Class representing a JSON Web Token, it's payload, and it's status
@param string secret The secret to sign / verify with
@param object options The jwt-express options

JWT - Class representing a JSON Web Token it s payload and it s status


function(payload) {
        payload.stales = Date.now() + this.options.stales;

        this.payload = payload;
        this.token = utils.sign(this.payload, this.secret, this.options.signOptions);
        this.valid = true;
        this.expired = false;
        this.stale = false;

        return this;
    }

function ( payload ) { payload . stales = Date . now ( ) + this . options . stales ; this . payload = payload ; this . token = utils . sign ( this . payload , this . secret , this . options . signOptions ) ; this . valid = true ; this . expired = false ; this . stale = false ; return this ; }

sign - generate a new token from the payload
@param object payload The payload to sign
@return this


function(res) {
        if (this.options.cookies) {
            res.cookie(this.options.cookie, this.token, this.options.cookieOptions);
        }

        return this;
    }

function ( res ) { if ( this . options . cookies ) { res . cookie ( this . options . cookie , this . token , this . options . cookieOptions ) ; } return this ; }

store - stores the JWT in the cookie
@param object res The Express HTTP Response object
@return this


function() {
        return {
            token: this.token,
            payload: this.payload,
            valid: this.valid,
            expired: this.expired,
            stale: this.stale
        };
    }

function ( ) { return { token : this . token , payload : this . payload , valid : this . valid , expired : this . expired , stale : this . stale } ; }

toJSON - this function is called when the jwt is passed through JSON.stringify
we don't want the secret or options to be stringified
@return object

toJSON - this function is called when the jwt is passed through JSON . stringify we don t want the secret or options to be stringified


function(token) {
        this.token = token || '';

        try {
            this.payload = utils.verify(this.token, this.secret, this.options.verifyOptions);
            this.valid = true;
        } catch (err) {
            this.payload = utils.decode(this.token) || {};
            if (err.name == 'TokenExpiredError') {
                this.expired = true;
            }
        }

        if (this.valid && !this.options.verify(this)) {
            this.valid = false;
        }

        if (this.payload.stales && Date.now() <= this.payload.stales) {
            this.stale = false;
        }

        return this;
    }

function ( token ) { this . token = token || '' ; try { this . payload = utils . verify ( this . token , this . secret , this . options . verifyOptions ) ; this . valid = true ; } catch ( err ) { this . payload = utils . decode ( this . token ) || { } ; if ( err . name == 'TokenExpiredError' ) { this . expired = true ; } } if ( this . valid && ! this . options . verify ( this ) ) { this . valid = false ; } if ( this . payload . stales && Date . now ( ) <= this . payload . stales ) { this . stale = false ; } return this ; }

verify - verifies the JWT's token
@param string token The token to verify
@return this