<commit_before>
/*jslint node: true */
'use strict';

var dotenv  = require ( 'dotenv'   ).config(),
    Promise = require ( 'bluebird' ),
    postal  = require ( 'postal'   ),
    chalk   = require ( 'chalk'    );

// ////////////////////////////////////////////////////////////////////////////
//
// central_relay, in-memory message bus
//
//

module.exports = function ( )
{
    var vm = this || {};

    vm._service_name = 'central_relay';

    vm.api =
    {
        ctor         : ctor,

        service_name : service_name,

        subscribe    : subscribe,
        publish      : publish
    };

    function ctor ( )
    {
        return new Promise ( function ( resolve, reject )
        {
            var retval = false;

            console.log ( chalk.green ( 'on the line :', service_name ( ) ) );

            // ////////////////////////////////////////////////////////////////

            service_init ( );

            // ////////////////////////////////////////////////////////////////

            retval = true;

            resolve ( retval );

        } );

    }

    function service_name ( )
    {
        return vm._service_name;
    }

    function service_init ( )
    {
        if ( ! vm.instanceof_postal )
        {
            vm.instanceof_postal = postal.channel ( vm._service_name );
        }
    }

    function subscribe ( message_topic, message_handler )
    {
        service_init ( );

        var subscription =
        {
            channel  : vm._service_name,
            topic    : message_topic,
            callback : message_handler
        };

        return vm.instanceof_postal.subscribe ( subscription );
    }

    function publish ( message_topic, message_content )
    {
        var envelope =
        {
            channel  : vm._service_name,
            topic    : message_topic,
            data     : message_content
        };

        vm.instanceof_postal.publish ( envelope );
    }

    return vm.api;
};
<commit_msg>annotated central_relay code blocks<commit_after>
/*jslint node: true */
'use strict';

var dotenv  = require ( 'dotenv'   ).config(),
    Promise = require ( 'bluebird' ),
    postal  = require ( 'postal'   ),
    chalk   = require ( 'chalk'    );

// ////////////////////////////////////////////////////////////////////////////
//
// central_relay, in-memory message bus
//
//

module.exports = function ( )
{
    var vm = this || {};

    vm._service_name = 'central_relay';

    vm.api =
    {
        ctor         : ctor,

        service_name : service_name,

        subscribe    : subscribe,
        publish      : publish
    };

    function ctor ( )
    {
        return new Promise ( function ( resolve, reject )
        {
            var retval = false;

            // ////////////////////////////////////////////////////////////////
            //
            // framework resources
            //
            // { none }

            console.log ( chalk.green ( 'on the line :', service_name ( ) ) );

            // ////////////////////////////////////////////////////////////////
            //
            // instance setup

            service_init ( );

            // ////////////////////////////////////////////////////////////////
            //
            // subscriptions
            //
            // { none }

            retval = true;

            resolve ( retval );

        } );

    }

    function service_name ( )
    {
        return vm._service_name;
    }

    function service_init ( )
    {
        if ( ! vm.instanceof_postal )
        {
            vm.instanceof_postal = postal.channel ( vm._service_name );
        }
    }

    function subscribe ( message_topic, message_handler )
    {
        service_init ( );

        var subscription =
        {
            channel  : vm._service_name,
            topic    : message_topic,
            callback : message_handler
        };

        return vm.instanceof_postal.subscribe ( subscription );
    }

    function publish ( message_topic, message_content )
    {
        var envelope =
        {
            channel  : vm._service_name,
            topic    : message_topic,
            data     : message_content
        };

        vm.instanceof_postal.publish ( envelope );
    }

    return vm.api;
};
<|endoftext|>


<commit_before>var gulp = require('gulp');
var sass = require('gulp-sass');
var nunjucks = require('gulp-nunjucks-html');
var spritesmith = require('gulp.spritesmith');
var merge = require('merge-stream');
var sourcemaps = require('gulp-sourcemaps');
var cleanCSS = require('gulp-clean-css');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var webserver = require('gulp-webserver');
var argv = require('yargs').argv;
var gulpif = require('gulp-if');
var browserify = require("browserify");
var source = require('vinyl-source-stream');
var tsify = require("tsify");
var buffer = require('vinyl-buffer');

var settings = {
	build: {
		prod: argv.production || argv.prod,
		version: parseInt(Math.random() * 10000000) + "-" + parseInt(Math.random() * 10000000)
	}
}

console.log('Production mode: ', settings.build.prod);

gulp.task('styles', ['sprite'], function () {
	return gulp.src([
		'./m/_scss/**/*.scss'
	])
		.pipe(sass().on('error', sass.logError))
		.pipe(gulpif(!settings.build.prod, sourcemaps.init()))
		.pipe(cleanCSS())
		.pipe(gulpif(!settings.build.prod, sourcemaps.write()))
		.pipe(gulp.dest('./m/css'));
});

gulp.task('html', function () {
	return gulp.src('./m/_templates/*.html')
		.pipe(nunjucks({
			searchPaths: ['./m/_templates'],
			tags: {
				blockStart: '<%',
				blockEnd: '%>',
				variableStart: '<$',
				variableEnd: '$>',
				commentStart: '<#',
				commentEnd: '#>'
			}
		}))
		.pipe(gulp.dest('./'));
});

gulp.task('ts', function () {
	// return tsProject.src()
	// 	.pipe(tsProject())
	// 	.js.pipe(gulp.dest("dist"));

	return browserify({
		basedir: './m/_tsapp',
		debug: false,
		entries: ['app.ts'],
		cache: {},
		packageCache: {}
	})
		.plugin(tsify)
		.bundle()
		.pipe(source('app.min.js'))
		.pipe(buffer())
		.pipe(gulpif(!settings.build.prod, sourcemaps.init()))
		.pipe(gulpif(settings.build.prod, uglify()))
		.pipe(gulpif(!settings.build.prod, sourcemaps.write('./')))
		.pipe(gulp.dest("./m/js"));
});

gulp.task('js-pre', function () {
	return gulp.src([
		'./m/_vendor/jquery/dist/jquery.min.js',
		'./m/_vendor/bootstrap-sass/assets/javascripts/bootstrap.min.js',
		'./m/_vendor/helix.jquery.equal-heights/src/jquery.equal-heights.js',
		'./m/_vendor/underscore/underscore-min.js',
		'./m/js/app/pre/**/*.js'
	])
		.pipe(gulpif(!settings.build.prod, sourcemaps.init()))
		.pipe(concat('pre.min.js'))
		.pipe(gulpif(settings.build.prod, uglify()))
		.pipe(gulpif(!settings.build.prod, sourcemaps.write('./')))
		.pipe(gulp.dest('./m/js/'));
});

gulp.task('js-post', function () {
	return gulp.src([
		'./m/js/app/post/**/*.js',
	])
		.pipe(gulpif(!settings.build.prod, sourcemaps.init()))
		.pipe(concat('post.min.js'))
		.pipe(gulpif(settings.build.prod, uglify()))
		.pipe(gulpif(!settings.build.prod, sourcemaps.write('./')))
		.pipe(gulp.dest('./m/js/'));
});

gulp.task('js', ['ts', 'js-pre', 'js-post'], function () { });

gulp.task('sprite', function () {
	var spriteData = gulp.src('./m/i/_spritesource/**/*.png')
		.pipe(spritesmith({
			padding: 15,
			imgName: 'sprite.png',
			imgPath: '../i/sprite.png?' + settings.build.version,
			cssName: '_sprites.scss',
			retinaSrcFilter: ['./m/i/_spritesource/**/*@2x.png'],
			retinaImgName: 'sprite@2x.png',
			retinaImgPath: '../i/sprite@2x.png?' + settings.build.version,
		}));

	var imgStream = spriteData.img
		.pipe(gulp.dest('./m/i/'));

	var cssStream = spriteData.css
		.pipe(gulp.dest('./m/_scss/'));

	return merge(imgStream, cssStream);
});

gulp.task('webserver', ['default'], function () {
	gulp.src('./')
		.pipe(webserver({
			livereload: {
				enable: true,
				filter: function (fileName) {
					if (fileName.match(/.map$/)) {
						return false;
					} else {
						return true;
					}
				}
			},
			directoryListing: true,
			open: true
		}));
});

gulp.task('process', ['styles', 'html', 'js'], function () { });

gulp.task('default', ['process'], function () {
	gulp.watch('./m/_scss/**/*', ['styles']);
	gulp.watch('./m/_templates/**/*', ['html']);
	gulp.watch('./m/i/_spritesource/**/*', ['sprite']);
	gulp.watch('./m/_vendor/**/*', ['js']);
	gulp.watch('./m/js/app/**/*', ['js']);
});
<commit_msg>update gulpfile.js<commit_after>var gulp = require('gulp');
var sass = require('gulp-sass');
var nunjucks = require('gulp-nunjucks-html');
var spritesmith = require('gulp.spritesmith');
var merge = require('merge-stream');
var sourcemaps = require('gulp-sourcemaps');
var cleanCSS = require('gulp-clean-css');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var webserver = require('gulp-webserver');
var argv = require('yargs').argv;
var gulpif = require('gulp-if');
var browserify = require("browserify");
var source = require('vinyl-source-stream');
var tsify = require("tsify");
var buffer = require('vinyl-buffer');
var urlAdjuster = require('gulp-css-url-adjuster');

var settings = {
	build: {
		prod: argv.production || argv.prod,
		version: parseInt(Math.random() * 10000000) + "-" + parseInt(Math.random() * 10000000)
	}
}

console.log('Production mode: ', settings.build.prod);

gulp.task('styles', ['sprite'], function () {
	return gulp.src([
		'./m/_scss/**/*.scss'
	])
		.pipe(sass().on('error', sass.logError))
		.pipe(concat('site.min.css'))
		.pipe(urlAdjuster({
			prepend: '',
		    append: '',
		    replace:  ['../fonts/','../f/'],
		}))
		.pipe(gulpif(!settings.build.prod, sourcemaps.init()))
		.pipe(cleanCSS())
		.pipe(gulpif(!settings.build.prod, sourcemaps.write()))
		.pipe(gulp.dest('./m/css'));
});

gulp.task('html', function () {
	return gulp.src('./m/_templates/*.html')
		.pipe(nunjucks({
			searchPaths: ['./m/_templates'],
			tags: {
				blockStart: '<%',
				blockEnd: '%>',
				variableStart: '<$',
				variableEnd: '$>',
				commentStart: '<#',
				commentEnd: '#>'
			}
		}))
		.pipe(gulp.dest('./'));
});

gulp.task('ts', function () {
	// return tsProject.src()
	// 	.pipe(tsProject())
	// 	.js.pipe(gulp.dest("dist"));

	return browserify({
		basedir: './m/_tsapp',
		debug: false,
		entries: ['app.ts'],
		cache: {},
		packageCache: {}
	})
		.plugin(tsify)
		.bundle()
		.pipe(source('app.min.js'))
		.pipe(buffer())
		.pipe(gulpif(!settings.build.prod, sourcemaps.init()))
		.pipe(gulpif(settings.build.prod, uglify()))
		.pipe(gulpif(!settings.build.prod, sourcemaps.write('./')))
		.pipe(gulp.dest("./m/js"));
});

gulp.task('webfonts', function() {
	return gulp.src([
	])
	.pipe(gulp.dest('./m/f/'));
});

gulp.task('js-pre', function () {
	return gulp.src([
		'./m/_vendor/jquery/dist/jquery.min.js',
		'./m/_vendor/bootstrap-sass/assets/javascripts/bootstrap.min.js',
		'./m/_vendor/helix.jquery.equal-heights/src/jquery.equal-heights.js',
		'./m/_vendor/underscore/underscore-min.js',
		'./m/js/app/pre/**/*.js'
	])
		.pipe(gulpif(!settings.build.prod, sourcemaps.init()))
		.pipe(concat('pre.min.js'))
		.pipe(gulpif(settings.build.prod, uglify()))
		.pipe(gulpif(!settings.build.prod, sourcemaps.write('./')))
		.pipe(gulp.dest('./m/js/'));
});

gulp.task('js-post', function () {
	return gulp.src([
		'./m/js/app/post/**/*.js',
	])
		.pipe(gulpif(!settings.build.prod, sourcemaps.init()))
		.pipe(concat('post.min.js'))
		.pipe(gulpif(settings.build.prod, uglify()))
		.pipe(gulpif(!settings.build.prod, sourcemaps.write('./')))
		.pipe(gulp.dest('./m/js/'));
});

gulp.task('js', ['ts', 'js-pre', 'js-post'], function () { });

gulp.task('sprite', function () {
	var spriteData = gulp.src('./m/i/_spritesource/**/*.png')
		.pipe(spritesmith({
			padding: 15,
			imgName: 'sprite.png',
			imgPath: '../i/sprite.png?' + settings.build.version,
			cssName: '_sprites.scss',
			retinaSrcFilter: ['./m/i/_spritesource/**/*@2x.png'],
			retinaImgName: 'sprite@2x.png',
			retinaImgPath: '../i/sprite@2x.png?' + settings.build.version,
		}));

	var imgStream = spriteData.img
		.pipe(gulp.dest('./m/i/'));

	var cssStream = spriteData.css
		.pipe(gulp.dest('./m/_scss/'));

	return merge(imgStream, cssStream);
});

gulp.task('webserver', ['default'], function () {
	gulp.src('./')
		.pipe(webserver({
			livereload: {
				enable: true,
				filter: function (fileName) {
					if (fileName.match(/.map$/)) {
						return false;
					} else {
						return true;
					}
				}
			},
			directoryListing: true,
			open: true
		}));
});

gulp.task('process', ['webfonts', 'styles', 'html', 'js'], function () { });

gulp.task('default', ['process'], function () {
	gulp.watch('./m/_scss/**/*', ['styles']);
	gulp.watch('./m/_templates/**/*', ['html']);
	gulp.watch('./m/i/_spritesource/**/*', ['sprite']);
	gulp.watch('./m/_vendor/**/*', ['js']);
	gulp.watch('./m/js/app/**/*', ['js']);
});
<|endoftext|>


<commit_before>/**
 * Connector module with possibility to set callback for publisher that
 * can be accessed by all subscribers.
 *
 * Created by Serhii Maksymchuk from Ubrainians for imCode
 * 09.11.16
 */
(function (Imcms) {
    var publishers = [];

    /**
     * Publisher that holds subscribers and callback for them
     * @param publisherName
     * @constructor
     */
    var Publisher = function (publisherName) {
        this.name = publisherName;
    };
    Publisher.prototype = {
        subscribers: [],
        addSubscriber: function (subscriber) {
            this.subscribers.push(subscriber);
        },
        unSubscribe: function (subscriber) {
            this.subscribers.remove(subscriber);
        },
        callback: function () {
        }
    };

    Imcms.CallbackConnector = {
        createPublisher: function (publisherName) {
            publishers.push(new Publisher(publisherName));
        },
        getPublisher: function (publisherName) {
            return publishers.find(function (publisher) {
                return (publisher.name === publisherName);
            })
        },
        /**
         * Set callback for all subscribers if such exists, else call it
         * @param publisherName
         * @param callback
         */
        setCallbackOrCall: function (publisherName, callback) {
            var publisher = Imcms.CallbackConnector.getPublisher(publisherName);
            (publisher && publisher.subscribers.length)
                ? publisher.callback = callback
                : callback();
        }
    }
})(Imcms);
<commit_msg>IMCMS-188 - Minor texteditor bug: - Connector module improvement.<commit_after>/**
 * Connector module with possibility to set callback for publisher that
 * can be accessed by all subscribers.
 *
 * Created by Serhii Maksymchuk from Ubrainians for imCode
 * 09.11.16
 */
(function (Imcms) {
    var publishers = [];

    /**
     * Publisher that holds subscribers and callback for them
     * @param publisherName
     * @constructor
     */
    var Publisher = function (publisherName) {
        this.name = publisherName;
    };
    Publisher.prototype = {
        subscribers: [],
        addSubscriber: function (subscriber) {
            this.subscribers.push(subscriber);
        },
        unSubscribe: function (subscriber) {
            this.subscribers.remove(subscriber);
        },
        hasSubscriber: function (subscriber) {
            return ~(this.subscribers.indexOf(subscriber));
        },
        callback: function () {
        }
    };

    Imcms.CallbackConnector = {
        createPublisher: function (publisherName) {
            publishers.push(new Publisher(publisherName));
        },
        getPublisher: function (publisherName) {
            return publishers.find(function (publisher) {
                return (publisher.name === publisherName);
            })
        },
        /**
         * Set callback for all subscribers if such exists, else call it
         * @param publisherName
         * @param callback
         */
        setCallbackOrCall: function (publisherName, callback) {
            var publisher = Imcms.CallbackConnector.getPublisher(publisherName);
            (publisher && publisher.subscribers.length)
                ? publisher.callback = callback
                : callback();
        }
    }
})(Imcms);
<|endoftext|>


<commit_before>
/**
 * TODO: Replace this with something better. It's too agressive.
 * TODO: Expose port number on conflict.
 */

// process.on('uncaughtException', function(err){
//   if(err){
//     if(err.code == "EADDRINUSE"){
//       console.log('#===========================================================')
//       console.log('# Harp')
//       console.log('#===========================================================')
//       console.log('# It appears you already have a server')
//       console.log('# listening on this port. You will first')
//       console.log('# have to stop that server to get Harp')
//       console.log('# to listen on this port.')
//       console.log('#===========================================================')
//       process.exit()
//     }else if(err.code == "EACCES"){
//       console.log('#===========================================================')
//       console.log('# Harp')
//       console.log('#===========================================================')
//       console.log('# You need root access to run this command. try `sudo`')
//       console.log('#===========================================================')
//       process.exit()
//     }else{
//       throw err
//     }
//   }
// })

/**
 * TODO: Remove `mkdirp`. Use `fs-extra` instead.
 */

var path        = require("path")
var fs          = require("fs")
var pkg         = require('../package.json')
var fse         = require("fs-extra")
var polymer     = require('terraform')
var mkdirp      = fse.mkdirp
var helpers     = require("./helpers")
var async       = require("async")
var connect     = require("connect")
var middleware  = require("./middleware")
var mime        = require('mime')

/**
 * Server
 *
 * Host a single Harp Application.
 *
 */

exports.server = function(dirPath, options, callback){
  connect.createServer(
    middleware.regProjectFinder(dirPath),
    middleware.setup,
    middleware.static,
    middleware.poly,
    middleware.process,
    middleware.staticNotFound,
    middleware.dynamicNotFound,
    middleware.devFallbackNotFound
  ).listen(options.port || 9966, callback)
}

/**
 * Multihost
 *
 * Host a single Harp Application.
 *
 */

exports.multihost = function(dirPath, options, callback){
  connect.createServer(
    middleware.notMultihostURL,
    middleware.index(dirPath),
    middleware.hostProjectFinder(dirPath),
    middleware.setup,
    middleware.static,
    middleware.poly,
    middleware.process,
    middleware.staticNotFound,
    middleware.dynamicNotFound,
    middleware.devFallbackNotFound
  ).listen(options.port || 9966, callback)
}

/**
 * Mount
 *
 * Offer the asset pipeline as connect middleware
 *
 */

exports.mount = function(mountPoint, root){

  if(!root){
    root = mountPoint
    mountPoint = null
  }else{
    var rx = new RegExp("^" + mountPoint)
  }

  var finder = middleware.regProjectFinder(root)

  return function(req, rsp, next){

    if(rx){
      if(!req.url.match(rx)) return next()
      var originalUrl = req.url
      req.url         = req.url.replace(rx, "/")
    }

    finder(req, rsp, function(){
      middleware.setup(req, rsp, function(){
        middleware.static(req, rsp, function(){
          middleware.poly(req, rsp, function(){
            middleware.process(req, rsp, function(){
              middleware.process(req, rsp, function(){
                if(originalUrl) req.url = originalUrl
                next()
              })
            })
          })
        })
      })
    })
  }
}

/**
 * Pipeline
 *
 * Offer the asset pipeline as connect middleware
 *
 */

exports.pipeline = function(root){
  var publicPath = path.resolve(root)
  var poly = polymer.root(publicPath)

  return function(req, rsp, next){
    var normalizedPath  = helpers.normalizeUrl(req.url)
    var priorityList    = polymer.helpers.buildPriorityList(normalizedPath)
    var sourceFile      = polymer.helpers.findFirstFile(publicPath, priorityList)

    if(!sourceFile) return next()

    poly.render(sourceFile, function(error, body){
      if(error){
        console.log(error)
        next()
      }else{
        if(!body) return next() // 404

        var outputType = polymer.helpers.outputType(sourceFile)
        var mimeType   = helpers.mimeType(outputType)
        var charset    = mime.charsets.lookup(mimeType)
        rsp.statusCode = 200
        rsp.setHeader('Content-Type', mimeType + (charset ? '; charset=' + charset : ''))
        rsp.setHeader('Content-Length', body.length)
        rsp.end(body)
      }
    })

  }

}

/**
 * Compile
 *
 * Compiles Single Harp Application.
 *
 */

exports.compile = function(projectPath, outputPath, callback){

  /**
   * Both projectPath and outputPath are optional
   */

  if(!callback){
    callback   = outputPath
    outputPath = "www"
  }

  if(!outputPath){
    outputPath = "www"
  }

  /**
   * Setup all the paths and collect all the data
   */

  try{
    outputPath = path.resolve(projectPath, outputPath)
    var setup  = helpers.setup(projectPath, "production")
    var poly   = polymer.root(setup.publicPath, setup.config.globals)
  }catch(err){
    return callback(err)
  }

  /**
   * Protect the user (as much as possible) from compiling up the tree
   * resulting in the project deleting its own source code.
   */

  if(!helpers.willAllow(projectPath, outputPath)){
    return callback({
      type: "Invalid Output Path",
      message: "Output path cannot be greater then one level up from project path and must be in directory starting with `_` (underscore).",
      projectPath: projectPath,
      outputPath: outputPath
    })
  }

  /**
   * Compile and save file
   */

  var compileFile = function(file, done){
    poly.render(file, function(error, body){
      if(error){
        done(error)
      }else{
        if(body){
          var dest = path.resolve(outputPath, polymer.helpers.outputPath(file))
          mkdirp(path.dirname(dest), function(err){
            fs.writeFile(dest, body, done)
          })
        }else{
          done()
        }
      }
    })

  }

  /**
   * Copy File
   *
   * TODO: reference ignore extensions from a terraform helper.
   */
  var copyFile = function(file, done){
    var ext = path.extname(file)
    if(!polymer.helpers.shouldIgnore(file) && [".jade", ".ejs", ".md", ".styl", ".less", ".coffee"].indexOf(ext) === -1){
      var localPath = path.resolve(outputPath, file)
      mkdirp(path.dirname(localPath), function(err){
        fse.copy(path.resolve(setup.publicPath, file), localPath, done)
      })
    }else{
      done()
    }
  }

  /**
   * Scan dir, Compile Less and Jade, Copy the others
   */

  helpers.prime(outputPath, { ignore: projectPath }, function(err){
    if(err) console.log(err)

    helpers.ls(setup.publicPath, function(err, results){
      async.eachLimit(results, 72, compileFile, function(err){
        if(err){
          callback(err)
        }else{
          async.eachLimit(results, 72, copyFile, function(err){
            setup.config['harp_version'] = pkg.version
            delete setup.config.globals
            callback(null, setup.config)
          })
        }
      })
    })
  })

}

<commit_msg>uses fse over mdirp<commit_after>
/**
 * TODO: Remove `mkdirp`. Use `fs-extra` instead.
 */

var path        = require("path")
var fs          = require("fs")
var pkg         = require('../package.json')
var fse         = require("fs-extra")
var polymer     = require('terraform')
var helpers     = require("./helpers")
var async       = require("async")
var connect     = require("connect")
var middleware  = require("./middleware")
var mime        = require('mime')

/**
 * Server
 *
 * Host a single Harp Application.
 *
 */

exports.server = function(dirPath, options, callback){
  connect.createServer(
    middleware.regProjectFinder(dirPath),
    middleware.setup,
    middleware.static,
    middleware.poly,
    middleware.process,
    middleware.staticNotFound,
    middleware.dynamicNotFound,
    middleware.devFallbackNotFound
  ).listen(options.port || 9966, callback)
}

/**
 * Multihost
 *
 * Host a single Harp Application.
 *
 */

exports.multihost = function(dirPath, options, callback){
  connect.createServer(
    middleware.notMultihostURL,
    middleware.index(dirPath),
    middleware.hostProjectFinder(dirPath),
    middleware.setup,
    middleware.static,
    middleware.poly,
    middleware.process,
    middleware.staticNotFound,
    middleware.dynamicNotFound,
    middleware.devFallbackNotFound
  ).listen(options.port || 9966, callback)
}

/**
 * Mount
 *
 * Offer the asset pipeline as connect middleware
 *
 */

exports.mount = function(mountPoint, root){

  if(!root){
    root = mountPoint
    mountPoint = null
  }else{
    var rx = new RegExp("^" + mountPoint)
  }

  var finder = middleware.regProjectFinder(root)

  return function(req, rsp, next){

    if(rx){
      if(!req.url.match(rx)) return next()
      var originalUrl = req.url
      req.url         = req.url.replace(rx, "/")
    }

    finder(req, rsp, function(){
      middleware.setup(req, rsp, function(){
        middleware.static(req, rsp, function(){
          middleware.poly(req, rsp, function(){
            middleware.process(req, rsp, function(){
              middleware.process(req, rsp, function(){
                if(originalUrl) req.url = originalUrl
                next()
              })
            })
          })
        })
      })
    })
  }
}

/**
 * Pipeline
 *
 * Offer the asset pipeline as connect middleware
 *
 */

exports.pipeline = function(root){
  var publicPath = path.resolve(root)
  var poly = polymer.root(publicPath)

  return function(req, rsp, next){
    var normalizedPath  = helpers.normalizeUrl(req.url)
    var priorityList    = polymer.helpers.buildPriorityList(normalizedPath)
    var sourceFile      = polymer.helpers.findFirstFile(publicPath, priorityList)

    if(!sourceFile) return next()

    poly.render(sourceFile, function(error, body){
      if(error){
        console.log(error)
        next()
      }else{
        if(!body) return next() // 404

        var outputType = polymer.helpers.outputType(sourceFile)
        var mimeType   = helpers.mimeType(outputType)
        var charset    = mime.charsets.lookup(mimeType)
        rsp.statusCode = 200
        rsp.setHeader('Content-Type', mimeType + (charset ? '; charset=' + charset : ''))
        rsp.setHeader('Content-Length', body.length)
        rsp.end(body)
      }
    })

  }

}

/**
 * Compile
 *
 * Compiles Single Harp Application.
 *
 */

exports.compile = function(projectPath, outputPath, callback){

  /**
   * Both projectPath and outputPath are optional
   */

  if(!callback){
    callback   = outputPath
    outputPath = "www"
  }

  if(!outputPath){
    outputPath = "www"
  }

  /**
   * Setup all the paths and collect all the data
   */

  try{
    outputPath = path.resolve(projectPath, outputPath)
    var setup  = helpers.setup(projectPath, "production")
    var poly   = polymer.root(setup.publicPath, setup.config.globals)
  }catch(err){
    return callback(err)
  }

  /**
   * Protect the user (as much as possible) from compiling up the tree
   * resulting in the project deleting its own source code.
   */

  if(!helpers.willAllow(projectPath, outputPath)){
    return callback({
      type: "Invalid Output Path",
      message: "Output path cannot be greater then one level up from project path and must be in directory starting with `_` (underscore).",
      projectPath: projectPath,
      outputPath: outputPath
    })
  }

  /**
   * Compile and save file
   */

  var compileFile = function(file, done){
    poly.render(file, function(error, body){
      if(error){
        done(error)
      }else{
        if(body){
          var dest = path.resolve(outputPath, polymer.helpers.outputPath(file))
          fse.mkdirp(path.dirname(dest), function(err){
            fs.writeFile(dest, body, done)
          })
        }else{
          done()
        }
      }
    })

  }

  /**
   * Copy File
   *
   * TODO: reference ignore extensions from a terraform helper.
   */
  var copyFile = function(file, done){
    var ext = path.extname(file)
    if(!polymer.helpers.shouldIgnore(file) && [".jade", ".ejs", ".md", ".styl", ".less", ".coffee"].indexOf(ext) === -1){
      var localPath = path.resolve(outputPath, file)
      fse.mkdirp(path.dirname(localPath), function(err){
        fse.copy(path.resolve(setup.publicPath, file), localPath, done)
      })
    }else{
      done()
    }
  }

  /**
   * Scan dir, Compile Less and Jade, Copy the others
   */

  helpers.prime(outputPath, { ignore: projectPath }, function(err){
    if(err) console.log(err)

    helpers.ls(setup.publicPath, function(err, results){
      async.eachLimit(results, 72, compileFile, function(err){
        if(err){
          callback(err)
        }else{
          async.eachLimit(results, 72, copyFile, function(err){
            setup.config['harp_version'] = pkg.version
            delete setup.config.globals
            callback(null, setup.config)
          })
        }
      })
    })
  })

}

<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */

var integration = require('@segment/analytics.js-integration');
var foldl = require('@ndhoule/foldl');
var each = require('@ndhoule/each');
var reject = require('reject');
var dateformat = require('dateformat');
var Track = require('segmentio-facade').Track;

/**
 * Expose `Facebook Pixel`.
 */

var FacebookPixel = module.exports = integration('Facebook Pixel')
  .global('fbq')
  .option('pixelId', '')
  .option('agent', 'seg')
  .option('initWithExistingTraits', false)
  .mapping('standardEvents')
  .mapping('legacyEvents')
  .tag('<script src="//connect.facebook.net/en_US/fbevents.js">');

/**
 * Initialize Facebook Pixel.
 *
 * @param {Facade} page
 */

FacebookPixel.prototype.initialize = function() {
  window._fbq = function() {
    if (window.fbq.callMethod) {
      window.fbq.callMethod.apply(window.fbq, arguments);
    } else {
      window.fbq.queue.push(arguments);
    }
  };

  window.fbq = window.fbq || window._fbq;
  window.fbq.push = window.fbq;
  window.fbq.loaded = true;
  window.fbq.disablePushState = true; // disables automatic pageview tracking
  window.fbq.agent = this.options.agent;
  window.fbq.version = '2.0';
  window.fbq.queue = [];
  this.load(this.ready);
  if (this.options.initWithExistingTraits) {
    var traits = formatTraits(this.analytics);
    window.fbq('init', this.options.pixelId, traits);
  } else {
    window.fbq('init', this.options.pixelId);
  }
};

/**
 * Has the Facebook Pixel library been loaded yet?
 *
 * @return {Boolean}
 */

FacebookPixel.prototype.loaded = function() {
  return !!(window.fbq && window.fbq.callMethod);
};

/**
 * Trigger a page view.
 *
 * @param {Facade} identify
 */

FacebookPixel.prototype.page = function() {
  window.fbq('track', 'PageView');
};

/**
 * Track an event.
 *
 * @param {Facade} track
 */

FacebookPixel.prototype.track = function(track) {
  var event = track.event();
  var revenue = formatRevenue(track.revenue());

  var payload = foldl(function(acc, val, key) {
    if (key === 'revenue') {
      acc.value = revenue;
      return acc;
    }

    acc[key] = val;
    return acc;
  }, {}, track.properties());

  var standard = this.standardEvents(event);
  var legacy = this.legacyEvents(event);

  // non-mapped events get sent as "custom events" with full
  // tranformed payload
  if (![].concat(standard, legacy).length) {
    window.fbq('trackCustom', event, payload);
    return;
  }

  // standard conversion events, mapped to one of 9 standard events
  // "Purchase" requires a currency parameter; default to USD
  // send full transformed payload
  each(function(event) {
    if (event === 'Purchase') payload.currency = payload.currency || 'USD';
    window.fbq('track', event, payload);
  }, standard);

  // legacy conversion events — mapped to specific "pixelId"s
  // send only currency and value
  each(function(event) {
    window.fbq('track', event, {
      currency: track.currency(),
      value: revenue
    });
  }, legacy);
};

/**
 * Product List Viewed.
 *
 * @api private
 * @param {Track} track category
 */

FacebookPixel.prototype.productListViewed = function(track) {
  window.fbq('track', 'ViewContent', {
    content_ids: [track.category() || ''],
    content_type: 'product_group'
  });

  // fall through for mapped legacy conversions
  each(function(event) {
    window.fbq('track', event, {
      currency: track.currency(),
      value: formatRevenue(track.revenue())
    });
  }, this.legacyEvents(track.event()));
};

/**
 * Product viewed.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.productViewed = function(track) {
  window.fbq('track', 'ViewContent', {
    content_ids: [track.productId() || track.id() || track.sku() || ''],
    content_type: 'product',
    content_name: track.name() || '',
    content_category: track.category() || '',
    currency: track.currency(),
    value: formatRevenue(track.price())
  });

  // fall through for mapped legacy conversions
  each(function(event) {
    window.fbq('track', event, {
      currency: track.currency(),
      value: formatRevenue(track.revenue())
    });
  }, this.legacyEvents(track.event()));
};

/**
 * Product added.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.productAdded = function(track) {
  window.fbq('track', 'AddToCart', {
    content_ids: [track.productId() || track.id() || track.sku() || ''],
    content_type: 'product',
    content_name: track.name() || '',
    content_category: track.category() || '',
    currency: track.currency(),
    value: formatRevenue(track.price())
  });

  // fall through for mapped legacy conversions
  each(function(event) {
    window.fbq('track', event, {
      currency: track.currency(),
      value: formatRevenue(track.revenue())
    });
  }, this.legacyEvents(track.event()));
};

/**
 * Order Completed.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.orderCompleted = function(track) {
  var content_ids = foldl(function(acc, product) {
    var item = new Track({ properties: product });
    var key = item.productId() || item.id() || item.sku();
    if (key) acc.push(key);
    return acc;
  }, [], track.products() || []);

  var revenue = formatRevenue(track.revenue());

  window.fbq('track', 'Purchase', {
    content_ids: content_ids,
    content_type: 'product',
    currency: track.currency(),
    value: revenue
  });

  // fall through for mapped legacy conversions
  each(function(event) {
    window.fbq('track', event, {
      currency: track.currency(),
      value: formatRevenue(track.revenue())
    });
  }, this.legacyEvents(track.event()));
};

/**
 * Get Revenue Formatted Correctly for FB.
 *
 * @api private
 * @param {Track} track
 */

function formatRevenue(revenue) {
  return Number(revenue || 0).toFixed(2);
}

/**
 * Get Traits Formatted Correctly for FB.
 *
 * https://developers.facebook.com/docs/facebook-pixel/pixel-with-ads/conversion-tracking#advanced_match
 *
 * @api private
 */

function formatTraits(analytics) {
  var traits = analytics && analytics.user().traits();
  if (!traits) return {};
  var firstName;
  var lastName;
  // Check for firstName property
  // else check for name
  if (traits.firstName) {
    firstName = traits.firstName;
    lastName = traits.lastName;
  } else {
    var nameArray = traits.name && traits.name.toLowerCase().split(' ') || [];
    firstName = nameArray.shift();
    lastName = nameArray.pop();
  }
  var gender = traits.gender && traits.gender.slice(0,1).toLowerCase();
  var birthday = traits.birthday && dateformat(traits.birthday, 'yyyymmdd');
  var address = traits.address || {};
  var city = address.city && address.city.split(' ').join('').toLowerCase();
  var state = address.state && address.state.toLowerCase();
  var postalCode = address.postalCode;
  return reject({
    em: traits.email,
    fn: firstName,
    ln: lastName,
    ph: traits.phone,
    ge: gender,
    db: birthday,
    ct: city,
    st: state,
    zp: postalCode
  });
}
<commit_msg>update to facade function<commit_after>'use strict';

/**
 * Module dependencies.
 */

var integration = require('@segment/analytics.js-integration');
var foldl = require('@ndhoule/foldl');
var each = require('@ndhoule/each');
var reject = require('reject');
var dateformat = require('dateformat');
var Track = require('segmentio-facade').Track;

/**
 * Expose `Facebook Pixel`.
 */

var FacebookPixel = module.exports = integration('Facebook Pixel')
  .global('fbq')
  .option('pixelId', '')
  .option('agent', 'seg')
  .option('initWithExistingTraits', false)
  .mapping('standardEvents')
  .mapping('legacyEvents')
  .tag('<script src="//connect.facebook.net/en_US/fbevents.js">');

/**
 * Initialize Facebook Pixel.
 *
 * @param {Facade} page
 */

FacebookPixel.prototype.initialize = function() {
  window._fbq = function() {
    if (window.fbq.callMethod) {
      window.fbq.callMethod.apply(window.fbq, arguments);
    } else {
      window.fbq.queue.push(arguments);
    }
  };

  window.fbq = window.fbq || window._fbq;
  window.fbq.push = window.fbq;
  window.fbq.loaded = true;
  window.fbq.disablePushState = true; // disables automatic pageview tracking
  window.fbq.agent = this.options.agent;
  window.fbq.version = '2.0';
  window.fbq.queue = [];
  this.load(this.ready);
  if (this.options.initWithExistingTraits) {
    var traits = formatTraits(this.analytics);
    window.fbq('init', this.options.pixelId, traits);
  } else {
    window.fbq('init', this.options.pixelId);
  }
};

/**
 * Has the Facebook Pixel library been loaded yet?
 *
 * @return {Boolean}
 */

FacebookPixel.prototype.loaded = function() {
  return !!(window.fbq && window.fbq.callMethod);
};

/**
 * Trigger a page view.
 *
 * @param {Facade} identify
 */

FacebookPixel.prototype.page = function() {
  window.fbq('track', 'PageView');
};

/**
 * Track an event.
 *
 * @param {Facade} track
 */

FacebookPixel.prototype.track = function(track) {
  var event = track.event();
  var revenue = formatRevenue(track.revenue());

  var payload = foldl(function(acc, val, key) {
    if (key === 'revenue') {
      acc.value = revenue;
      return acc;
    }

    acc[key] = val;
    return acc;
  }, {}, track.properties());

  var standard = this.standardEvents(event);
  var legacy = this.legacyEvents(event);

  // non-mapped events get sent as "custom events" with full
  // tranformed payload
  if (![].concat(standard, legacy).length) {
    window.fbq('trackCustom', event, payload);
    return;
  }

  // standard conversion events, mapped to one of 9 standard events
  // "Purchase" requires a currency parameter;
  // send full transformed payload
  each(function(event) {
    if (event === 'Purchase') payload.currency = track.currency(); // defaults to 'USD'
    window.fbq('track', event, payload);
  }, standard);

  // legacy conversion events — mapped to specific "pixelId"s
  // send only currency and value
  each(function(event) {
    window.fbq('track', event, {
      currency: track.currency(),
      value: revenue
    });
  }, legacy);
};

/**
 * Product List Viewed.
 *
 * @api private
 * @param {Track} track category
 */

FacebookPixel.prototype.productListViewed = function(track) {
  window.fbq('track', 'ViewContent', {
    content_ids: [track.category() || ''],
    content_type: 'product_group'
  });

  // fall through for mapped legacy conversions
  each(function(event) {
    window.fbq('track', event, {
      currency: track.currency(),
      value: formatRevenue(track.revenue())
    });
  }, this.legacyEvents(track.event()));
};

/**
 * Product viewed.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.productViewed = function(track) {
  window.fbq('track', 'ViewContent', {
    content_ids: [track.productId() || track.id() || track.sku() || ''],
    content_type: 'product',
    content_name: track.name() || '',
    content_category: track.category() || '',
    currency: track.currency(),
    value: formatRevenue(track.price())
  });

  // fall through for mapped legacy conversions
  each(function(event) {
    window.fbq('track', event, {
      currency: track.currency(),
      value: formatRevenue(track.revenue())
    });
  }, this.legacyEvents(track.event()));
};

/**
 * Product added.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.productAdded = function(track) {
  window.fbq('track', 'AddToCart', {
    content_ids: [track.productId() || track.id() || track.sku() || ''],
    content_type: 'product',
    content_name: track.name() || '',
    content_category: track.category() || '',
    currency: track.currency(),
    value: formatRevenue(track.price())
  });

  // fall through for mapped legacy conversions
  each(function(event) {
    window.fbq('track', event, {
      currency: track.currency(),
      value: formatRevenue(track.revenue())
    });
  }, this.legacyEvents(track.event()));
};

/**
 * Order Completed.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.orderCompleted = function(track) {
  var content_ids = foldl(function(acc, product) {
    var item = new Track({ properties: product });
    var key = item.productId() || item.id() || item.sku();
    if (key) acc.push(key);
    return acc;
  }, [], track.products() || []);

  var revenue = formatRevenue(track.revenue());

  window.fbq('track', 'Purchase', {
    content_ids: content_ids,
    content_type: 'product',
    currency: track.currency(),
    value: revenue
  });

  // fall through for mapped legacy conversions
  each(function(event) {
    window.fbq('track', event, {
      currency: track.currency(),
      value: formatRevenue(track.revenue())
    });
  }, this.legacyEvents(track.event()));
};

/**
 * Get Revenue Formatted Correctly for FB.
 *
 * @api private
 * @param {Track} track
 */

function formatRevenue(revenue) {
  return Number(revenue || 0).toFixed(2);
}

/**
 * Get Traits Formatted Correctly for FB.
 *
 * https://developers.facebook.com/docs/facebook-pixel/pixel-with-ads/conversion-tracking#advanced_match
 *
 * @api private
 */

function formatTraits(analytics) {
  var traits = analytics && analytics.user().traits();
  if (!traits) return {};
  var firstName;
  var lastName;
  // Check for firstName property
  // else check for name
  if (traits.firstName) {
    firstName = traits.firstName;
    lastName = traits.lastName;
  } else {
    var nameArray = traits.name && traits.name.toLowerCase().split(' ') || [];
    firstName = nameArray.shift();
    lastName = nameArray.pop();
  }
  var gender = traits.gender && traits.gender.slice(0,1).toLowerCase();
  var birthday = traits.birthday && dateformat(traits.birthday, 'yyyymmdd');
  var address = traits.address || {};
  var city = address.city && address.city.split(' ').join('').toLowerCase();
  var state = address.state && address.state.toLowerCase();
  var postalCode = address.postalCode;
  return reject({
    em: traits.email,
    fn: firstName,
    ln: lastName,
    ph: traits.phone,
    ge: gender,
    db: birthday,
    ct: city,
    st: state,
    zp: postalCode
  });
}
<|endoftext|>


<commit_before>// Copy user data from extension to bbs.sgamer.com.

for (var i = 0; i < localStorage.length; i++) {
    var key = localStorage.key(i);
    var value = localStorage.getItem(key);
    chrome.tabs.executeScript(null, {code: "localStorage.setItem('" + key + "', '" + value + "');"});
}

// Hide medals.

var hideMedals = document.getElementById("hideMedals");
var hideMedalsChecked = localStorage.getItem("hideMedals");
if(hideMedalsChecked == "true") {
    hideMedals.setAttribute("checked", "");
}
else {
    hideMedals.removeAttribute("checked");
}
$("#hideMedals").click(function() {
    var temp;
    if(hideMedals.hasAttribute("checked")) {
        temp = "false";
        hideMedals.removeAttribute("checked");
    }
    else {
        temp = "true";
        hideMedals.setAttribute("checked", "");
    }
    localStorage.setItem("hideMedals", temp);
});

// Hide signature.

var hideSignature = document.getElementById("hideSignature");
var hideSignatureChecked = localStorage.getItem("hideSignature");
if(hideSignatureChecked == "true") {
    hideSignature.setAttribute("checked", "");
}
else {
    hideSignature.removeAttribute("checked");
}
$("#hideSignature").click(function() {
    var temp;
    if(hideSignature.hasAttribute("checked")) {
        temp = "false";
        hideSignature.removeAttribute("checked");
    }
    else {
        temp = "true";
        hideSignature.setAttribute("checked", "");
    }
    localStorage.setItem("hideSignature", temp);
});

// Block specific user groups.

var blockUserGroups = document.getElementById("blockUserGroups");
var blockUserGroupsChecked = localStorage.getItem("blockUserGroups");
var userGroups = document.getElementById("userGroups");
var userGroupsSelected = localStorage.getItem("userGroups");
// null == 0
if(Number(userGroupsSelected) >= 0 && Number(userGroupsSelected) <= 6) {
    $("option", userGroups)[Number(userGroupsSelected)].selected = true;
}
if(blockUserGroupsChecked == "true") {
    blockUserGroups.checked = true;
    userGroups.disabled = false;
}
else {
    blockUserGroups.checked = false;
    userGroups.disabled = true;
}
// blockUserGroups.checked will modify automatically.
$("#blockUserGroups").click(function() {
    var temp;
    if(blockUserGroups.checked) {
        temp = "true";
        userGroups.disabled = false;
    }
    else {
        temp = "false";
        userGroups.disabled = true;
    }
    localStorage.setItem("blockUserGroups", temp);
});

$("#userGroups").change(function() {
    localStorage.setItem("userGroups", userGroups.selectedIndex);
});
<commit_msg>Remove copy user data from ext to webpage<commit_after>// Hide medals.
var hideMedals = document.getElementById("hideMedals");
var hideMedalsChecked = localStorage.getItem("hideMedals");
if(hideMedalsChecked == "true") {
    hideMedals.setAttribute("checked", "");
}
else {
    hideMedals.removeAttribute("checked");
}
$("#hideMedals").click(function() {
    var temp;
    if(hideMedals.hasAttribute("checked")) {
        temp = "false";
        hideMedals.removeAttribute("checked");
    }
    else {
        temp = "true";
        hideMedals.setAttribute("checked", "");
    }
    localStorage.setItem("hideMedals", temp);
});

// Hide signature.
var hideSignature = document.getElementById("hideSignature");
var hideSignatureChecked = localStorage.getItem("hideSignature");
if(hideSignatureChecked == "true") {
    hideSignature.setAttribute("checked", "");
}
else {
    hideSignature.removeAttribute("checked");
}
$("#hideSignature").click(function() {
    var temp;
    if(hideSignature.hasAttribute("checked")) {
        temp = "false";
        hideSignature.removeAttribute("checked");
    }
    else {
        temp = "true";
        hideSignature.setAttribute("checked", "");
    }
    localStorage.setItem("hideSignature", temp);
});

// Block specific user groups.
var blockUserGroups = document.getElementById("blockUserGroups");
var blockUserGroupsChecked = localStorage.getItem("blockUserGroups");
var userGroups = document.getElementById("userGroups");
var userGroupsSelected = localStorage.getItem("userGroups");
// null == 0
if(Number(userGroupsSelected) >= 0 && Number(userGroupsSelected) <= 6) {
    $("option", userGroups)[Number(userGroupsSelected)].selected = true;
}
if(blockUserGroupsChecked == "true") {
    blockUserGroups.checked = true;
    userGroups.disabled = false;
}
else {
    blockUserGroups.checked = false;
    userGroups.disabled = true;
}
// blockUserGroups.checked will modify automatically.
$("#blockUserGroups").click(function() {
    var temp;
    if(blockUserGroups.checked) {
        temp = "true";
        userGroups.disabled = false;
    }
    else {
        temp = "false";
        userGroups.disabled = true;
    }
    localStorage.setItem("blockUserGroups", temp);
});

$("#userGroups").change(function() {
    localStorage.setItem("userGroups", userGroups.selectedIndex);
});
<|endoftext|>


<commit_before>var es = require('event-stream');

var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require("babelify");
var through = require('through2');

var concat = require('gulp-concat');
var sourcemaps = require('gulp-sourcemaps');
var addsrc = require('gulp-add-src');
var iife = require("gulp-iife");
var runSequence = require('run-sequence');
var bowerFiles = require('bower-files')();
var uglify = require('gulp-uglify');
var sass = require('gulp-sass');
var mocha = require('gulp-spawn-mocha');
var eslint = require('gulp-eslint');

var gulpUtils = require('./lib/shared/gulp-utils');

gulp.task('default', function(callback) {
  return runSequence('clean', 'lint', 'test', 'css', 'templates', 'build', callback);
});

gulp.task('watch', ['watchJS', 'watchTemplates', 'watchCSS']);

gulp.task('watchJS', function() {
  gulp.watch(['src/**/*.js', 'bower_components/**/*.js', 'index.html'], ['lint', 'build']);
});

gulp.task('watchTests', function watchTests() {
  gulp.watch(['src/**/*.js', 'test/**/*.js'], ['lint', 'test']);
});

gulp.task('watchTemplates', function() {
  gulp.watch(['templates/**/*.html'], ['templates']);
});

gulp.task('watchCSS', function() {
  gulp.watch(['styles/**/*.scss'], ['css']);
});

gulp.task('build', function build(callback) {
  return runSequence('build-dependencies', 'build-app', 'build-index', callback);
});

gulp.task('build-app', function buildDependencies() {
  var browserified = through.obj(function (file, enc, next){
    browserify(file.path, {
      debug: true
    }).transform(babelify).bundle(function(err, res){
      // assumes file.contents is a Buffer
      debugger;
      file.contents = res;
      next(null, file);
    });
  });

  return gulp.src(['src/**/*.js'])
    .pipe(sourcemaps.init())
    .pipe(iife({useStrict: false}))
    .pipe(browserified)
    .pipe(concat('app.js'))
    .pipe(uglify())
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(gulpUtils.getDistPath()));
});

gulp.task('build-dependencies', function buildApp() {
  return gulp.src(bowerFiles.ext('js').files)
    .pipe(sourcemaps.init())
    .pipe(concat('dependencies.js'))
    .pipe(uglify())
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(gulpUtils.getDistPath()));
});

gulp.task('build-index', function buildIndex() {
  return gulp.src('index.html')
    .pipe(gulp.dest(gulpUtils.getDistPath()));
});

gulp.task('templates', function templates() {
  return gulp.src('templates/**/*.html')
    .pipe(gulp.dest(gulpUtils.getDistPath('templates')));
});

gulp.task('css', function buildCSS() {
  return gulp.src('styles/app.scss')
    .pipe(sourcemaps.init())
    .pipe(sass().on('error', sass.logError))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(gulpUtils.getDistPath('css')));
});

gulp.task('clean', function clean(callback) {
  gulpUtils.removeDistFiles(callback);
});

gulp.task('lint', function lint() {
  return gulp.src(["src/**/*.js", "test/**/*.js"])
    .pipe(eslint('lib/shared/.eslintrc'))
    .pipe(eslint.format())
    .pipe(eslint.failOnError());
});

gulp.task('test', function test() {
  return gulp.src('test/**/*-test.js', {read: false})
    .pipe(mocha({
      reporter: process.env.TRAVIS ? 'spec' : 'nyan',
      compilers: 'js:babel/register'
    }));
});
<commit_msg>Added lib to browserify paths so that dependencies resolve easily. Made error throwing explicit so debugging is easy.<commit_after>var es = require('event-stream');

var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require("babelify");
var through = require('through2');

var concat = require('gulp-concat');
var sourcemaps = require('gulp-sourcemaps');
var addsrc = require('gulp-add-src');
var iife = require("gulp-iife");
var runSequence = require('run-sequence');
var bowerFiles = require('bower-files')();
var uglify = require('gulp-uglify');
var sass = require('gulp-sass');
var mocha = require('gulp-spawn-mocha');
var eslint = require('gulp-eslint');

var gulpUtils = require('./lib/shared/gulp-utils');

gulp.task('default', function(callback) {
  return runSequence('clean', 'lint', 'test', 'css', 'templates', 'build', callback);
});

gulp.task('watch', ['watchJS', 'watchTemplates', 'watchCSS']);

gulp.task('watchJS', function() {
  gulp.watch(['src/**/*.js', 'bower_components/**/*.js', 'index.html'], ['lint', 'build']);
});

gulp.task('watchTests', function watchTests() {
  gulp.watch(['src/**/*.js', 'test/**/*.js'], ['lint', 'test']);
});

gulp.task('watchTemplates', function() {
  gulp.watch(['templates/**/*.html'], ['templates']);
});

gulp.task('watchCSS', function() {
  gulp.watch(['styles/**/*.scss'], ['css']);
});

gulp.task('build', function build(callback) {
  return runSequence('build-dependencies', 'build-app', 'build-index', callback);
});

gulp.task('build-app', function buildDependencies() {
  var browserified = through.obj(function (file, enc, next){
    browserify(file.path, {
      debug: true,
      paths: ['./lib']
    }).transform(babelify).bundle(function(err, res){
      // assumes file.contents is a Buffer
      if (err) {
        throw new Error(err);
      }
      file.contents = res;
      next(null, file);
    });
  });

  return gulp.src(['src/**/*.js'])
    .pipe(sourcemaps.init())
    .pipe(iife({useStrict: false}))
    .pipe(browserified)
    .pipe(concat('app.js'))
    .pipe(uglify())
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(gulpUtils.getDistPath()));
});

gulp.task('build-dependencies', function buildApp() {
  return gulp.src(bowerFiles.ext('js').files)
    .pipe(sourcemaps.init())
    .pipe(concat('dependencies.js'))
    .pipe(uglify())
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(gulpUtils.getDistPath()));
});

gulp.task('build-index', function buildIndex() {
  return gulp.src('index.html')
    .pipe(gulp.dest(gulpUtils.getDistPath()));
});

gulp.task('templates', function templates() {
  return gulp.src('templates/**/*.html')
    .pipe(gulp.dest(gulpUtils.getDistPath('templates')));
});

gulp.task('css', function buildCSS() {
  return gulp.src('styles/app.scss')
    .pipe(sourcemaps.init())
    .pipe(sass().on('error', sass.logError))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(gulpUtils.getDistPath('css')));
});

gulp.task('clean', function clean(callback) {
  gulpUtils.removeDistFiles(callback);
});

gulp.task('lint', function lint() {
  return gulp.src(["src/**/*.js", "test/**/*.js"])
    .pipe(eslint('lib/shared/.eslintrc'))
    .pipe(eslint.format())
    .pipe(eslint.failOnError());
});

gulp.task('test', function test() {
  return gulp.src('test/**/*-test.js', {read: false})
    .pipe(mocha({
      reporter: process.env.TRAVIS ? 'spec' : 'nyan',
      compilers: 'js:babel/register'
    }));
});
<|endoftext|>


<commit_before>// @flow

/* ::
import type MariaSQL from 'mariasql';
*/

const searchguardClient = require('../../clients/searchguardClient');
const kibanaClient = require('../../clients/kibanaClient');
const logger = require('../../logger');
const projectHelpers = require('../project/helpers');
const R = require('ramda');

const SearchguardOperations = (sqlClient /* : MariaSQL */, GroupModel) => ({
  syncGroup: async (groupName, groupProjectIDs) => {
    const groupProjectNames = [];
    // groupProjectIDs is a comma separated string of IDs, split it up and remove any entries with `''`
    const groupProjectIDsArray = groupProjectIDs.split(',').filter(groupProjectID => groupProjectID !== '');

    // Load project name by ID and add to groupProjectNames array
    for (const groupProjectID of groupProjectIDsArray) {
      const project = await projectHelpers(sqlClient).getProjectById(groupProjectID);
      const projectName = project.name;
      // Within elasticsearch we don't support any special characters, except dashes, convert all special characters to them and make it lowercase
      const openshiftProjectNameStyle = projectName
        .toLocaleLowerCase()
        .replace(/[^0-9a-z-]/g, '-');
      groupProjectNames.push(openshiftProjectNameStyle);
    }

    const groupProjectPermissions = {
      body: {
        indices: {},
        tenants: {
          [groupName]: 'RW',
        },
      },
    };

    // If this group has no projects assigned, we create a fake project as SearchGuard needs at least one indicies permission to work.
    if (groupProjectIDsArray.length === 0) {
      groupProjectPermissions.body.indices[`${groupName}-has-no-project`] = { '*': ['READ'] };
    } else {
      // inject project permissions into permission array
      groupProjectNames.forEach(projectName => groupProjectPermissions.body.indices[`*-${projectName}-*`] = { '*': ['READ'] });
    }

    try {
      // Create a new SearchGuard Role for this Group with read permissions for all Projects assigned to this group
      await searchguardClient.put(`roles/${groupName}`, groupProjectPermissions);
      logger.debug(`${groupName}: Created SearchGuard role "${groupName}"`);
    } catch (err) {
      logger.error(`SearchGuard create role error: ${err}`);
      throw new Error(`SearchGuard create role error: ${err}`);
    }

    // Create or Update the lagoon_all_access role which has access to all tenants (all groups)
    const groups = await GroupModel.loadAllGroups();
    const groupNames = R.pluck('name', groups);

    const tenants = R.reduce(
      (acc, elem) => {
        acc[elem] = 'RW';
        return acc;
      },
      { admin_tenant: 'RW' },
      groupNames,
    );

    try {
      await searchguardClient.put('roles/lagoon_all_access', {
        body: {
          cluster: ['UNLIMITED'],
          indices: {
            '*': {
              '*': ['UNLIMITED'],
            },
          },
          tenants,
        },
      });
      logger.info(`${groupName}: Created/Updated lagoon_all_access role in SearchGuard`);
    } catch (err) {
      logger.error(`SearchGuard Error while creating lagoon_all_access role: ${err}`);
      throw new Error(
        `SearchGuard Error while creating lagoon_all_access role: ${err}`,
      );
    }

    // Create index-patterns for this group
    // @TODO Remove index-patterns that are not used anymore? like when a project is removed from the group?
    const indexPatterns = [];
    indexPatterns.push('application-logs-*', 'router-logs-*', 'container-logs-*', 'lagoon-logs-*');

    groupProjectNames.forEach(projectName => indexPatterns.push(
      `application-logs-${projectName}-*`,
      `router-logs-${projectName}-*`,
      `container-logs-${projectName}-*`,
      `lagoon-logs-${projectName}-*`,
    ));

    for (const indexPattern of indexPatterns) {
      try {
        await kibanaClient.post(`saved_objects/index-pattern/${indexPattern}`, {
          body: {
            attributes: {
              title: `${indexPattern}`,
              timeFieldName: '@timestamp',
            },
          },
          headers: {
            sgtenant: groupName,
          },
        });
        logger.debug(`${groupName}: Created index-pattern "${indexPattern}"`);
      } catch (err) {
        // 409 Errors are expected and mean that there is already an index-pattern with that name defined, we ignore them
        if (err.statusCode !== 409) {
          logger.error(
            `Kibana Error during setup of index pattern "${indexPattern}": ${err}`,
          );
          // Don't fail if we have Kibana Errors, as they are "non-critical"
        } else {
          logger.debug(`${groupName}: index-pattern "${indexPattern}" already existing`);
        }
      }
    }

    try {
      const currentSettings = await kibanaClient.get('kibana/settings', {
        headers: {
          sgtenant: groupName,
        },
      });

      const defaultIndexPattern = 'container-logs-*';

      // Define a default Index if there is none yet
      if (!('defaultIndex' in currentSettings.body.settings)) {
        await kibanaClient.post('kibana/settings', {
          body: {
            changes: {
              defaultIndex: defaultIndexPattern,
              'telemetry:optIn': false, // also opt out of telemetry from xpack
            },
          },
          headers: {
            sgtenant: groupName,
          },
        });
        logger.debug(
          `${groupName}: Configured default index for tenant "${
            groupName
          }" to  "${defaultIndexPattern}"`,
        );
      } else {
        logger.debug(
          `${groupName}: Configured default index for tenant "${
            groupName
          }" was already set to "${
            currentSettings.body.settings.defaultIndex.userValue
          }"`,
        );
      }
    } catch (err) {
      logger.error(`Kibana Error during config of default Index: ${err}`);
      // Don't fail if we have Kibana Errors, as they are "non-critical"
    }
  },
  deleteGroup: async (groupName) => {
    // delete groups that have no Projects assigned to them
    try {
      await searchguardClient.delete(`roles/${groupName}`);
      logger.debug(`${groupName}: SearchGuard Role "${groupName}" deleted`);
    } catch (err) {
      // 404 Errors are expected and mean that the role does not exist
      if (err.statusCode !== 404) {
        logger.error(
          `SearchGuard Error during deletion of role "${groupName}": ${err}`,
        );
      } else {
        logger.debug(`SearchGuard Role "${groupName}" did not exist, skipping deletion`);
      }
    }
  },
});

module.exports = { SearchguardOperations };
<commit_msg>kibana api correct usage<commit_after>// @flow

/* ::
import type MariaSQL from 'mariasql';
*/

const searchguardClient = require('../../clients/searchguardClient');
const kibanaClient = require('../../clients/kibanaClient');
const logger = require('../../logger');
const projectHelpers = require('../project/helpers');
const R = require('ramda');

const SearchguardOperations = (sqlClient /* : MariaSQL */, GroupModel) => ({
  syncGroup: async (groupName, groupProjectIDs) => {
    const groupProjectNames = [];
    // groupProjectIDs is a comma separated string of IDs, split it up and remove any entries with `''`
    const groupProjectIDsArray = groupProjectIDs.split(',').filter(groupProjectID => groupProjectID !== '');

    // Load project name by ID and add to groupProjectNames array
    for (const groupProjectID of groupProjectIDsArray) {
      const project = await projectHelpers(sqlClient).getProjectById(groupProjectID);
      const projectName = project.name;
      // Within elasticsearch we don't support any special characters, except dashes, convert all special characters to them and make it lowercase
      const openshiftProjectNameStyle = projectName
        .toLocaleLowerCase()
        .replace(/[^0-9a-z-]/g, '-');
      groupProjectNames.push(openshiftProjectNameStyle);
    }

    const groupProjectPermissions = {
      body: {
        indices: {},
        tenants: {
          [groupName]: 'RW',
        },
      },
    };

    // If this group has no projects assigned, we create a fake project as SearchGuard needs at least one indicies permission to work.
    if (groupProjectIDsArray.length === 0) {
      groupProjectPermissions.body.indices[`${groupName}-has-no-project`] = { '*': ['READ'] };
    } else {
      // inject project permissions into permission array
      groupProjectNames.forEach(projectName => groupProjectPermissions.body.indices[`*-${projectName}-*`] = { '*': ['READ'] });
    }

    try {
      // Create a new SearchGuard Role for this Group with read permissions for all Projects assigned to this group
      await searchguardClient.put(`roles/${groupName}`, groupProjectPermissions);
      logger.debug(`${groupName}: Created SearchGuard role "${groupName}"`);
    } catch (err) {
      logger.error(`SearchGuard create role error: ${err}`);
      throw new Error(`SearchGuard create role error: ${err}`);
    }

    // Create or Update the lagoon_all_access role which has access to all tenants (all groups)
    const groups = await GroupModel.loadAllGroups();
    const groupNames = R.pluck('name', groups);

    const tenants = R.reduce(
      (acc, elem) => {
        acc[elem] = 'RW';
        return acc;
      },
      { admin_tenant: 'RW' },
      groupNames,
    );

    try {
      await searchguardClient.put('roles/lagoon_all_access', {
        body: {
          cluster: ['UNLIMITED'],
          indices: {
            '*': {
              '*': ['UNLIMITED'],
            },
          },
          tenants,
        },
      });
      logger.info(`${groupName}: Created/Updated lagoon_all_access role in SearchGuard`);
    } catch (err) {
      logger.error(`SearchGuard Error while creating lagoon_all_access role: ${err}`);
      throw new Error(
        `SearchGuard Error while creating lagoon_all_access role: ${err}`,
      );
    }

    // Create index-patterns for this group
    // @TODO Remove index-patterns that are not used anymore? like when a project is removed from the group?
    const indexPatterns = [];
    indexPatterns.push('application-logs-*', 'router-logs-*', 'container-logs-*', 'lagoon-logs-*');

    groupProjectNames.forEach(projectName => indexPatterns.push(
      `application-logs-${projectName}-*`,
      `router-logs-${projectName}-*`,
      `container-logs-${projectName}-*`,
      `lagoon-logs-${projectName}-*`,
    ));

    for (const indexPattern of indexPatterns) {
      try {
        await kibanaClient.post(`saved_objects/index-pattern`, {
          body: {
            attributes: {
              title: `${indexPattern}`,
              timeFieldName: '@timestamp',
            },
          },
          headers: {
            sgtenant: groupName,
          },
        });
        logger.debug(`${groupName}: Created index-pattern "${indexPattern}"`);
      } catch (err) {
        // 409 Errors are expected and mean that there is already an index-pattern with that name defined, we ignore them
        if (err.statusCode !== 409) {
          logger.error(
            `Kibana Error during setup of index pattern "${indexPattern}": ${err}`,
          );
          // Don't fail if we have Kibana Errors, as they are "non-critical"
        } else {
          logger.debug(`${groupName}: index-pattern "${indexPattern}" already existing`);
        }
      }
    }

    try {
      const currentSettings = await kibanaClient.get('kibana/settings', {
        headers: {
          sgtenant: groupName,
        },
      });

      const defaultIndexPattern = 'container-logs-*';

      // Define a default Index if there is none yet
      if (!('defaultIndex' in currentSettings.body.settings)) {
        await kibanaClient.post('kibana/settings', {
          body: {
            changes: {
              defaultIndex: defaultIndexPattern,
              'telemetry:optIn': false, // also opt out of telemetry from xpack
            },
          },
          headers: {
            sgtenant: groupName,
          },
        });
        logger.debug(
          `${groupName}: Configured default index for tenant "${
            groupName
          }" to  "${defaultIndexPattern}"`,
        );
      } else {
        logger.debug(
          `${groupName}: Configured default index for tenant "${
            groupName
          }" was already set to "${
            currentSettings.body.settings.defaultIndex.userValue
          }"`,
        );
      }
    } catch (err) {
      logger.error(`Kibana Error during config of default Index: ${err}`);
      // Don't fail if we have Kibana Errors, as they are "non-critical"
    }
  },
  deleteGroup: async (groupName) => {
    // delete groups that have no Projects assigned to them
    try {
      await searchguardClient.delete(`roles/${groupName}`);
      logger.debug(`${groupName}: SearchGuard Role "${groupName}" deleted`);
    } catch (err) {
      // 404 Errors are expected and mean that the role does not exist
      if (err.statusCode !== 404) {
        logger.error(
          `SearchGuard Error during deletion of role "${groupName}": ${err}`,
        );
      } else {
        logger.debug(`SearchGuard Role "${groupName}" did not exist, skipping deletion`);
      }
    }
  },
});

module.exports = { SearchguardOperations };
<|endoftext|>


<commit_before>'use strict';

var http = require('http');
var https = require('https');

function RpcClient(opts) {
  opts = opts || {};
  this.host = opts.host || '127.0.0.1';
  this.port = opts.port || 8332;
  this.user = opts.user || 'user';
  this.pass = opts.pass || 'pass';
  this.protocol = opts.protocol === 'http' ? http : https;
  this.batchedCalls = null;
  this.disableAgent  = opts.disableAgent || false;

  var isRejectUnauthorized = typeof opts.rejectUnauthorized !== 'undefined';
  this.rejectUnauthorized = isRejectUnauthorized ? opts.rejectUnauthorized : true;

  if(RpcClient.config.log) {
    this.log = RpcClient.config.log;
  } else {
    this.log = RpcClient.loggers[RpcClient.config.logger || 'normal'];
  }

}

var cl = console.log.bind(console);

var noop = function() {};

RpcClient.loggers = {
  none: {info: noop, warn: noop, err: noop, debug: noop},
  normal: {info: cl, warn: cl, err: cl, debug: noop},
  debug: {info: cl, warn: cl, err: cl, debug: cl}
};

RpcClient.config = {
  logger: 'normal' // none, normal, debug
};

function rpc(request, callback) {

  var self = this;
  request = JSON.stringify(request);
  var auth = new Buffer(self.user + ':' + self.pass).toString('base64');

  var options = {
    host: self.host,
    path: '/',
    method: 'POST',
    port: self.port,
    rejectUnauthorized: self.rejectUnauthorized,
    agent: self.disableAgent ? false : undefined
  };

  if (self.httpOptions) {
    for (var k in self.httpOptions) {
      options[k] = self.httpOptions[k];
    }
  }

  var called = false;

  var errorMessage = 'Bitcoin Core JSON-RPC: host=' + self.host + ' port=' + self.port + ': ';

  var req = this.protocol.request(options, function(res) {

    var buf = '';
    res.on('data', function(data) {
      buf += data;
    });

    res.on('end', function() {

      if (called) {
        return;
      }
      called = true;

      if (res.statusCode === 401) {
        callback(new Error(errorMessage + 'Connection Rejected: 401 Unnauthorized'));
        return;
      }
      if (res.statusCode === 403) {
        callback(new Error(errorMessage + 'Connection Rejected: 403 Forbidden'));
        return;
      }

      var parsedBuf;
      try {
        parsedBuf = JSON.parse(buf);
      } catch(e) {
        self.log.err(e.stack);
        self.log.err(buf);
        self.log.err('HTTP Status code:' + res.statusCode);
        var err = new Error(errorMessage + 'Error Parsing JSON: ' + e.message);
        callback(err);
        return;
      }

      callback(parsedBuf.error, parsedBuf);

    });
  });

  req.on('error', function(e) {
    var err = new Error(errorMessage + 'Request Error: ' + e.message);
    if (!called) {
      called = true;
      if (!callback) {
        self.log.err(err);
      }
      callback(err);
    }
  });

  req.setHeader('Content-Length', request.length);
  req.setHeader('Content-Type', 'application/json');
  req.setHeader('Authorization', 'Basic ' + auth);
  req.write(request);
  req.end();
}

RpcClient.prototype.batch = function(batchCallback, resultCallback) {
  this.batchedCalls = [];
  batchCallback();
  rpc.call(this, this.batchedCalls, resultCallback);
  this.batchedCalls = null;
};

RpcClient.callspec = {
  addMultiSigAddress: '',
  addNode: '',
  backupWallet: '',
  createMultiSig: '',
  createRawTransaction: '',
  decodeRawTransaction: '',
  dumpPrivKey: '',
  encryptWallet: '',
  estimateFee: 'int',
  estimatePriority: 'int',
  generate: 'int',
  getAccount: '',
  getAccountAddress: 'str',
  getAddedNodeInfo: '',
  getAddressMempool: 'obj',
  getAddressUtxos: 'obj',
  getAddressBalance: 'obj',
  getAddressDeltas: 'obj',
  getAddressTxids: 'obj',
  getAddressesByAccount: '',
  getBalance: 'str int',
  getBestBlockHash: '',
  getBlock: 'str bool',
  getBlockchainInfo: '',
  getBlockCount: '',
  getBlockHashes: 'int int',
  getBlockHash: 'int',
  getBlockHeader: 'str',
  getBlockNumber: '',
  getBlockTemplate: '',
  getConnectionCount: '',
  getChainTips: '',
  getDifficulty: '',
  getGenerate: '',
  getHashesPerSec: '',
  getInfo: '',
  getMemoryPool: '',
  getMemPoolInfo: '',
  getMiningInfo: '',
  getNewAddress: '',
  getPeerInfo: '',
  getRawMemPool: '',
  getRawTransaction: 'str int',
  getReceivedByAccount: 'str int',
  getReceivedByAddress: 'str int',
  getSpentInfo: 'obj',
  getTransaction: '',
  getTxOut: 'str int bool',
  getTxOutSetInfo: '',
  getWork: '',
  help: '',
  importAddress: 'str str bool',
  importPrivKey: 'str str bool',
  invalidateBlock: 'str',
  keyPoolRefill: '',
  listAccounts: 'int',
  listAddressGroupings: '',
  listReceivedByAccount: 'int bool',
  listReceivedByAddress: 'int bool',
  listSinceBlock: 'str int',
  listTransactions: 'str int int',
  listUnspent: 'int int',
  listLockUnspent: 'bool',
  lockUnspent: '',
  move: 'str str float int str',
  prioritiseTransaction: 'str float int',
  sendFrom: 'str str float int str str',
  sendMany: 'str obj int str',  //not sure this is will work
  sendRawTransaction: 'str',
  sendToAddress: 'str float str str',
  setAccount: '',
  setGenerate: 'bool int',
  setTxFee: 'float',
  signMessage: '',
  signRawTransaction: '',
  stop: '',
  submitBlock: '',
  validateAddress: '',
  verifyMessage: '',
  walletLock: '',
  walletPassPhrase: 'string int',
  walletPassphraseChange: '',
};

var slice = function(arr, start, end) {
  return Array.prototype.slice.call(arr, start, end);
};

function generateRPCMethods(constructor, apiCalls, rpc) {

  function createRPCMethod(methodName, argMap) {
    return function() {

      var limit = arguments.length - 1;

      if (this.batchedCalls) {
        limit = arguments.length;
      }

      for (var i = 0; i < limit; i++) {
        if(argMap[i]) {
          arguments[i] = argMap[i](arguments[i]);
        }
      }

      if (this.batchedCalls) {
        this.batchedCalls.push({
          jsonrpc: '2.0',
          method: methodName,
          params: slice(arguments),
          id: getRandomId()
        });
      } else {
        rpc.call(this, {
          method: methodName,
          params: slice(arguments, 0, arguments.length - 1),
          id: getRandomId()
        }, arguments[arguments.length - 1]);
      }

    };
  };

  var types = {
    str: function(arg) {
      return arg.toString();
    },
    int: function(arg) {
      return parseFloat(arg);
    },
    float: function(arg) {
      return parseFloat(arg);
    },
    bool: function(arg) {
      return (arg === true || arg == '1' || arg == 'true' || arg.toString().toLowerCase() == 'true');
    },
    obj: function(arg) {
      if(typeof arg === 'string') {
        return JSON.parse(arg);
      }
      return arg;
    }
  };

  for(var k in apiCalls) {
    var spec = apiCalls[k].split(' ');
    for (var i = 0; i < spec.length; i++) {
      if(types[spec[i]]) {
        spec[i] = types[spec[i]];
      } else {
        spec[i] = types.str;
      }
    }
    var methodName = k.toLowerCase();
    constructor.prototype[k] = createRPCMethod(methodName, spec);
    constructor.prototype[methodName] = constructor.prototype[k];
  }

}

function getRandomId() {
  return parseInt(Math.random() * 100000);
}

generateRPCMethods(RpcClient, RpcClient.callspec, rpc);

module.exports = RpcClient;
<commit_msg>remove impossible branch<commit_after>'use strict';

var http = require('http');
var https = require('https');

function RpcClient(opts) {
  opts = opts || {};
  this.host = opts.host || '127.0.0.1';
  this.port = opts.port || 8332;
  this.user = opts.user || 'user';
  this.pass = opts.pass || 'pass';
  this.protocol = opts.protocol === 'http' ? http : https;
  this.batchedCalls = null;
  this.disableAgent  = opts.disableAgent || false;

  var isRejectUnauthorized = typeof opts.rejectUnauthorized !== 'undefined';
  this.rejectUnauthorized = isRejectUnauthorized ? opts.rejectUnauthorized : true;

  if(RpcClient.config.log) {
    this.log = RpcClient.config.log;
  } else {
    this.log = RpcClient.loggers[RpcClient.config.logger || 'normal'];
  }

}

var cl = console.log.bind(console);

var noop = function() {};

RpcClient.loggers = {
  none: {info: noop, warn: noop, err: noop, debug: noop},
  normal: {info: cl, warn: cl, err: cl, debug: noop},
  debug: {info: cl, warn: cl, err: cl, debug: cl}
};

RpcClient.config = {
  logger: 'normal' // none, normal, debug
};

function rpc(request, callback) {

  var self = this;
  request = JSON.stringify(request);
  var auth = new Buffer(self.user + ':' + self.pass).toString('base64');

  var options = {
    host: self.host,
    path: '/',
    method: 'POST',
    port: self.port,
    rejectUnauthorized: self.rejectUnauthorized,
    agent: self.disableAgent ? false : undefined
  };

  if (self.httpOptions) {
    for (var k in self.httpOptions) {
      options[k] = self.httpOptions[k];
    }
  }

  var called = false;

  var errorMessage = 'Bitcoin Core JSON-RPC: host=' + self.host + ' port=' + self.port + ': ';

  var req = this.protocol.request(options, function(res) {

    var buf = '';
    res.on('data', function(data) {
      buf += data;
    });

    res.on('end', function() {

      if (called) {
        return;
      }
      called = true;

      if (res.statusCode === 401) {
        callback(new Error(errorMessage + 'Connection Rejected: 401 Unnauthorized'));
        return;
      }
      if (res.statusCode === 403) {
        callback(new Error(errorMessage + 'Connection Rejected: 403 Forbidden'));
        return;
      }

      var parsedBuf;
      try {
        parsedBuf = JSON.parse(buf);
      } catch(e) {
        self.log.err(e.stack);
        self.log.err(buf);
        self.log.err('HTTP Status code:' + res.statusCode);
        var err = new Error(errorMessage + 'Error Parsing JSON: ' + e.message);
        callback(err);
        return;
      }

      callback(parsedBuf.error, parsedBuf);

    });
  });

  req.on('error', function(e) {
    var err = new Error(errorMessage + 'Request Error: ' + e.message);
    if (!called) {
      called = true;
      callback(err);
    }
  });

  req.setHeader('Content-Length', request.length);
  req.setHeader('Content-Type', 'application/json');
  req.setHeader('Authorization', 'Basic ' + auth);
  req.write(request);
  req.end();
}

RpcClient.prototype.batch = function(batchCallback, resultCallback) {
  this.batchedCalls = [];
  batchCallback();
  rpc.call(this, this.batchedCalls, resultCallback);
  this.batchedCalls = null;
};

RpcClient.callspec = {
  addMultiSigAddress: '',
  addNode: '',
  backupWallet: '',
  createMultiSig: '',
  createRawTransaction: '',
  decodeRawTransaction: '',
  dumpPrivKey: '',
  encryptWallet: '',
  estimateFee: 'int',
  estimatePriority: 'int',
  generate: 'int',
  getAccount: '',
  getAccountAddress: 'str',
  getAddedNodeInfo: '',
  getAddressMempool: 'obj',
  getAddressUtxos: 'obj',
  getAddressBalance: 'obj',
  getAddressDeltas: 'obj',
  getAddressTxids: 'obj',
  getAddressesByAccount: '',
  getBalance: 'str int',
  getBestBlockHash: '',
  getBlock: 'str bool',
  getBlockchainInfo: '',
  getBlockCount: '',
  getBlockHashes: 'int int',
  getBlockHash: 'int',
  getBlockHeader: 'str',
  getBlockNumber: '',
  getBlockTemplate: '',
  getConnectionCount: '',
  getChainTips: '',
  getDifficulty: '',
  getGenerate: '',
  getHashesPerSec: '',
  getInfo: '',
  getMemoryPool: '',
  getMemPoolInfo: '',
  getMiningInfo: '',
  getNewAddress: '',
  getPeerInfo: '',
  getRawMemPool: '',
  getRawTransaction: 'str int',
  getReceivedByAccount: 'str int',
  getReceivedByAddress: 'str int',
  getSpentInfo: 'obj',
  getTransaction: '',
  getTxOut: 'str int bool',
  getTxOutSetInfo: '',
  getWork: '',
  help: '',
  importAddress: 'str str bool',
  importPrivKey: 'str str bool',
  invalidateBlock: 'str',
  keyPoolRefill: '',
  listAccounts: 'int',
  listAddressGroupings: '',
  listReceivedByAccount: 'int bool',
  listReceivedByAddress: 'int bool',
  listSinceBlock: 'str int',
  listTransactions: 'str int int',
  listUnspent: 'int int',
  listLockUnspent: 'bool',
  lockUnspent: '',
  move: 'str str float int str',
  prioritiseTransaction: 'str float int',
  sendFrom: 'str str float int str str',
  sendMany: 'str obj int str',  //not sure this is will work
  sendRawTransaction: 'str',
  sendToAddress: 'str float str str',
  setAccount: '',
  setGenerate: 'bool int',
  setTxFee: 'float',
  signMessage: '',
  signRawTransaction: '',
  stop: '',
  submitBlock: '',
  validateAddress: '',
  verifyMessage: '',
  walletLock: '',
  walletPassPhrase: 'string int',
  walletPassphraseChange: '',
};

var slice = function(arr, start, end) {
  return Array.prototype.slice.call(arr, start, end);
};

function generateRPCMethods(constructor, apiCalls, rpc) {

  function createRPCMethod(methodName, argMap) {
    return function() {

      var limit = arguments.length - 1;

      if (this.batchedCalls) {
        limit = arguments.length;
      }

      for (var i = 0; i < limit; i++) {
        if(argMap[i]) {
          arguments[i] = argMap[i](arguments[i]);
        }
      }

      if (this.batchedCalls) {
        this.batchedCalls.push({
          jsonrpc: '2.0',
          method: methodName,
          params: slice(arguments),
          id: getRandomId()
        });
      } else {
        rpc.call(this, {
          method: methodName,
          params: slice(arguments, 0, arguments.length - 1),
          id: getRandomId()
        }, arguments[arguments.length - 1]);
      }

    };
  };

  var types = {
    str: function(arg) {
      return arg.toString();
    },
    int: function(arg) {
      return parseFloat(arg);
    },
    float: function(arg) {
      return parseFloat(arg);
    },
    bool: function(arg) {
      return (arg === true || arg == '1' || arg == 'true' || arg.toString().toLowerCase() == 'true');
    },
    obj: function(arg) {
      if(typeof arg === 'string') {
        return JSON.parse(arg);
      }
      return arg;
    }
  };

  for(var k in apiCalls) {
    var spec = apiCalls[k].split(' ');
    for (var i = 0; i < spec.length; i++) {
      if(types[spec[i]]) {
        spec[i] = types[spec[i]];
      } else {
        spec[i] = types.str;
      }
    }
    var methodName = k.toLowerCase();
    constructor.prototype[k] = createRPCMethod(methodName, spec);
    constructor.prototype[methodName] = constructor.prototype[k];
  }

}

function getRandomId() {
  return parseInt(Math.random() * 100000);
}

generateRPCMethods(RpcClient, RpcClient.callspec, rpc);

module.exports = RpcClient;
<|endoftext|>


<commit_before>window.onload = function () {
    // Get container elements
    var containers = [
        document.getElementById('currentCurator'),
        document.getElementById('nextCurator'),
        document.getElementById('followingCurator')
    ];
    var successive = document.getElementById('successiveCurators');
    var alertClose = document.getElementById('alert-close');

    // Get file path, add time-stamp to prevent caching
    var filePath = 'https://scratchtools.tk/fpc/api/v2/json/?u=' + new Date().getTime();

    // Init http request
    var xmlHttp = new XMLHttpRequest();

    xmlHttp.ontimeout = function() {
        console.log('Timeout');
        error();
    };

    xmlHttp.onerror = function() {
        console.log('Error');
        error();
    };

    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
            try {
                downloaded(JSON.parse(xmlHttp.responseText));
            } catch(e) {
                if (e instanceof SyntaxError) {
                    error();
                    console.log('Bad JSON syntax');
                } else {
                    throw e;
                }
            }
        }
    };

    xmlHttp.open('GET', filePath, true);
    xmlHttp.timeout = 5000;

    // Send http request
    xmlHttp.send(null);

    // Interpret downloaded data
    function downloaded(result) {
        // Check response was successful
        if (result['response']['code'] === 0) {

            // Load current, next and following curators
            for (var i = 0; i < 3; i++) {

                // Get container parent
                var parent = containers[i].parentElement;

                // Display week range

                var date = document.createElement('span');

                date.className = 'date';
                date.innerHTML =
                        formatDate(new Date(result['curators'][i]['start'])) +
                        ' - ' +
                        formatDate(new Date(result['curators'][i]['end']));

                parent.insertBefore(
                        date,
                        parent.childNodes[0]
                );

                // Load curator

                // Check curator is known

                if (result['curators'][i]['user']) {
                    // Curator is known

                    // Check if FPC is confirmed

                    if (result['curators'][i]['confirmed']) {
                        // FPC was confirmed

                        containers[i].innerHTML = '@' + result['curators'][i]['user'];
                        containers[i].className = '';

                        parent.className = 'box shadow-box hover';
                        parent.title = '@' + result['curators'][i]['user'];
                        parent.href = result['curators'][i]['suggest_url'];
                    } else {
                        // FPC not confirmed

                        containers[i].innerHTML = '@' + result['curators'][i]['user'] + ' (TBC)';
                        containers[i].className = 'gray';

                        parent.title = 'This FPC has not yet been confirmed';
                    }
                } else {
                    // Curator not known

                    containers[i].innerHTML = 'Unknown';

                    parent.title = 'The FPC during this period is currently unknown';
                }
            }

            // Check if there are successive curators

            if (result['curators'].length > 3) {
                // There are successive curators

                // For each successive curator
                for (var i = 3; i < result['curators'].length; i++) {
                    // Add date
                    successive.innerHTML += 'Start - End';

                    // Check if curator has been suggested
                    if (result['curators'][i]['user']) {
                        // Curator has been suggested

                        // Check if curator is confirmed

                        if (result['curators'][i]['confirmed']) {
                            // Curator is confirmed

                            successive.innerHTML +=
                                    '@' +
                                    result['curators'][i]['user'] + '';
                        } else {
                            // Curator isn't confirmed, so display TBC label
                            // and add no link

                            successive.innerHTML +=
                                    '@' +
                                    result['curators'][i]['user'] +
                                    ' (TBC)';
                        }
                    } else {
                        // No known FPC for this period

                        // Display unknown message
                        successive.innerHTML +=
                                'Unknown';
                    }
                }

                // Show container for successive curators
                document.getElementById('successiveContainer').className = 'box shadow-box hover';
            }

            // Show notice
            if (result['message']) {
                document.getElementById('alert-text').innerHTML = result['message'];
                document.getElementById('alert').className = 'box';
            }
        } else {
            error();
            console.log(
                    'Error: code ' +
                    result['response']['code'] +
                    ' - ' +
                    result['response']['description']
            );
        }
    }

    // Display error messages in every container
    function error() {
        // TODO: on error, hide containers and show separate div
        containers[0].innerHTML = 'Error';
        containers[1].innerHTML = 'Error';
        containers[2].innerHTML = 'Error';
    }

    // Makes a date human readable
    // Uses browser language to match users prefrences
    function formatDate(d) {
        return d.toLocaleString(navigator.language, {
            day: 'numeric',
            month: 'short'
        });
    }

    // Add close button click event
    alertClose.onclick = function() {
        document.getElementById('alert').className = 'hidden';
    };
};<commit_msg>Add successive dates<commit_after>window.onload = function () {
    // Get container elements
    var containers = [
        document.getElementById('currentCurator'),
        document.getElementById('nextCurator'),
        document.getElementById('followingCurator')
    ];
    var successive = document.getElementById('successiveCurators');
    var alertClose = document.getElementById('alert-close');

    // Get file path, add time-stamp to prevent caching
    var filePath = 'https://scratchtools.tk/fpc/api/v2/json/?u=' + new Date().getTime();

    // Init http request
    var xmlHttp = new XMLHttpRequest();

    xmlHttp.ontimeout = function() {
        console.log('Timeout');
        error();
    };

    xmlHttp.onerror = function() {
        console.log('Error');
        error();
    };

    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
            try {
                downloaded(JSON.parse(xmlHttp.responseText));
            } catch(e) {
                if (e instanceof SyntaxError) {
                    error();
                    console.log('Bad JSON syntax');
                } else {
                    throw e;
                }
            }
        }
    };

    xmlHttp.open('GET', filePath, true);
    xmlHttp.timeout = 5000;

    // Send http request
    xmlHttp.send(null);

    // Interpret downloaded data
    function downloaded(result) {
        // Check response was successful
        if (result['response']['code'] === 0) {

            // Load current, next and following curators
            for (var i = 0; i < 3; i++) {

                // Get container parent
                var parent = containers[i].parentElement;

                // Display week range

                var date = document.createElement('span');

                date.className = 'date';
                date.innerHTML =
                        formatDate(new Date(result['curators'][i]['start'])) +
                        ' - ' +
                        formatDate(new Date(result['curators'][i]['end']));

                parent.insertBefore(
                        date,
                        parent.childNodes[0]
                );

                // Load curator

                // Check curator is known

                if (result['curators'][i]['user']) {
                    // Curator is known

                    // Check if FPC is confirmed

                    if (result['curators'][i]['confirmed']) {
                        // FPC was confirmed

                        containers[i].innerHTML = '@' + result['curators'][i]['user'];
                        containers[i].className = '';

                        parent.className = 'box shadow-box hover';
                        parent.title = '@' + result['curators'][i]['user'];
                        parent.href = result['curators'][i]['suggest_url'];
                    } else {
                        // FPC not confirmed

                        containers[i].innerHTML = '@' + result['curators'][i]['user'] + ' (TBC)';
                        containers[i].className = 'gray';

                        parent.title = 'This FPC has not yet been confirmed';
                    }
                } else {
                    // Curator not known

                    containers[i].innerHTML = 'Unknown';

                    parent.title = 'The FPC during this period is currently unknown';
                }
            }

            // Check if there are successive curators

            if (result['curators'].length > 3) {
                // There are successive curators

                // For each successive curator
                for (var i = 3; i < result['curators'].length; i++) {
                    // Add date
                    successive.innerHTML +=
                            '' +
                            formatDate(new Date(result['curators'][i]['start'])) +
                            ' - ' +
                            formatDate(new Date(result['curators'][i]['end'])) +
                            '';

                    // Check if curator has been suggested
                    if (result['curators'][i]['user']) {
                        // Curator has been suggested

                        // Check if curator is confirmed

                        if (result['curators'][i]['confirmed']) {
                            // Curator is confirmed

                            successive.innerHTML +=
                                    '@' +
                                    result['curators'][i]['user'] + '';
                        } else {
                            // Curator isn't confirmed, so display TBC label
                            // and add no link

                            successive.innerHTML +=
                                    '@' +
                                    result['curators'][i]['user'] +
                                    ' (TBC)';
                        }
                    } else {
                        // No known FPC for this period

                        // Display unknown message
                        successive.innerHTML +=
                                'Unknown';
                    }
                }

                // Show container for successive curators
                document.getElementById('successiveContainer').className = 'box shadow-box hover';
            }

            // Show notice
            if (result['message']) {
                document.getElementById('alert-text').innerHTML = result['message'];
                document.getElementById('alert').className = 'box';
            }
        } else {
            error();
            console.log(
                    'Error: code ' +
                    result['response']['code'] +
                    ' - ' +
                    result['response']['description']
            );
        }
    }

    // Display error messages in every container
    function error() {
        // TODO: on error, hide containers and show separate div
        containers[0].innerHTML = 'Error';
        containers[1].innerHTML = 'Error';
        containers[2].innerHTML = 'Error';
    }

    // Makes a date human readable
    // Uses browser language to match users prefrences
    function formatDate(d) {
        return d.toLocaleString(navigator.language, {
            day: 'numeric',
            month: 'short'
        });
    }

    // Add close button click event
    alertClose.onclick = function() {
        document.getElementById('alert').className = 'hidden';
    };
};<|endoftext|>


<commit_before>var gulp = require('gulp');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var typescript = require('gulp-typescript');
var archiver = require('archiver');
var fs = require('fs');
var path = require('path');
var pkg = require('./package.json');
var webserver = require('gulp-webserver');

// compile sass and concatenate to single css file in build dir
gulp.task('convert-sass', function() {

	return gulp.src('src/scss/app.scss')
	  	.pipe(sass({includePaths: [
			'node_modules/bootstrap/scss/',
			'node_modules/mdi/scss/'
		], precision: 8}))
	  	.pipe(concat(pkg.name + '.css'))
	    .pipe(gulp.dest('src/css'));
});

function watch() {
    gulp.watch('src/scss/**/*.scss', ['convert-sass']);
}

gulp.task('webserver-watch', function() {
	gulp.src('./') // Yes, ./ is right. While developing, for convenience reasons
                   // e2e tests should run against the base dir,
                   // instead the dist dir. Only in ci the dist has to be tested.
        .pipe(webserver({
			fallback: 'index.html',
			port: 8083
		}));
	watch();
});

const tscConfig = require('./tsconfig.json');
gulp.task('compile',['convert-sass'], function () {
    // fonts
    gulp.src([
            'node_modules/mdi/fonts/**/*',
            'node_modules/bootstrap-sass/assets/fonts/**/*'
        ])
        .pipe(gulp.dest('fonts'));

    // sources
    gulp
        .src('*.ts')
        .pipe(typescript(tscConfig.compilerOptions))
        .pipe(gulp.dest('./'));

    gulp
		.src('demo/app/**/*.ts')
		.pipe(typescript(tscConfig.compilerOptions))
		.pipe(gulp.dest('demo/app/'));

    gulp
        .src('src/app/**/*.ts')
        .pipe(typescript(tscConfig.compilerOptions))
        .pipe(gulp.dest('src/app/'));

	// test sources
    return gulp
		.src('src/test/**/*.ts')
		.pipe(typescript(tscConfig.compilerOptions))
		.pipe(gulp.dest('src/test/'));
});

<commit_msg>Remove obsolete comment.<commit_after>var gulp = require('gulp');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var typescript = require('gulp-typescript');
var archiver = require('archiver');
var fs = require('fs');
var path = require('path');
var pkg = require('./package.json');
var webserver = require('gulp-webserver');

// compile sass and concatenate to single css file in build dir
gulp.task('convert-sass', function() {

	return gulp.src('src/scss/app.scss')
	  	.pipe(sass({includePaths: [
			'node_modules/bootstrap/scss/',
			'node_modules/mdi/scss/'
		], precision: 8}))
	  	.pipe(concat(pkg.name + '.css'))
	    .pipe(gulp.dest('src/css'));
});

function watch() {
    gulp.watch('src/scss/**/*.scss', ['convert-sass']);
}

gulp.task('webserver-watch', function() {
	gulp.src('./')
        .pipe(webserver({
			fallback: 'index.html',
			port: 8083
		}));
	watch();
});

const tscConfig = require('./tsconfig.json');
gulp.task('compile',['convert-sass'], function () {
    // fonts
    gulp.src([
            'node_modules/mdi/fonts/**/*',
            'node_modules/bootstrap-sass/assets/fonts/**/*'
        ])
        .pipe(gulp.dest('fonts'));

    // sources
    gulp
        .src('*.ts')
        .pipe(typescript(tscConfig.compilerOptions))
        .pipe(gulp.dest('./'));

    gulp
		.src('demo/app/**/*.ts')
		.pipe(typescript(tscConfig.compilerOptions))
		.pipe(gulp.dest('demo/app/'));

    gulp
        .src('src/app/**/*.ts')
        .pipe(typescript(tscConfig.compilerOptions))
        .pipe(gulp.dest('src/app/'));

	// test sources
    return gulp
		.src('src/test/**/*.ts')
		.pipe(typescript(tscConfig.compilerOptions))
		.pipe(gulp.dest('src/test/'));
});

<|endoftext|>