<commit_before>module.exports = function(skill, info, bot, message, db) {
    bot.api.users.info({user: message.user}, (error, response) => {
    let {name, real_name} = response.user;

    var userData = message.text.match(/\<(.*?)\>/g);

    console.log('messaage text: ' + message.text);
    console.log('userdata' + userData);
  if (userData) {
    // if there is a user named send ze hugs!
    //for (var i = 0, len = userData.length; i < len; i++) {
        //FU(userData[i].replace(/[^\w\s]/gi, ''));
        //console.log('userdate[i]' + userData[i]);
        //console.log('userdate[i]' + userData[i].replace(/[^\w\s]/gi, ''));
    //}
    //console.log(userData);
    bot.api.users.info({user: userData[0]}, (error, response) => {let {challengedName, challengedReal_name} = response.user;
       bot.reply(message,'Let\'s rumble ' + challengedReal_name);
    })

    //bot.reply(message,'Let\'s rumble' + userData[0].replace(/[^\w\s]/gi, ''));
  } else {
    bot.reply(message, 'You didn\'t challenge anyone you chicken shit! :chicken: :poop:');
  }

function FU(user) {
    //DM some shade!
    bot.api.im.open({ user: user }, function (err, response) {
      if (err) {
        return console.log(err)
      }
    var fuckArray = [
    'https://giphy.com/gifs/cheezburger-olympics-U7P2vnWfPkIQ8',
    'https://giphy.com/gifs/louis-ck-middle-finger-fuck-you-Qd71uU3LzyxXO'
    ];
    var randomFuck = Math.floor(Math.random()* fuckArray.length);

    var dmChannel = response.channel.id
    bot.say({channel: dmChannel, text: 'Someone is throwing shade your way... :middle_finger:'})
    bot.say({channel: dmChannel, text: fuckArray[randomFuck]})
    })

}

})

  var gameEngine = require('./Rock-Paper-Spock');

    bot.api.users.info({user: message.user}, (error, response) => {
        //bot.reply(message, 'Rock Paper Scissors (lizard, spock, spiderman, batman, wizard, glock?)');
    })

  var instance = new gameEngine(gameEngine.DefaultRules);
  instance.addPlayer({id: 1, sign: "spock"});
  instance.addPlayer({id: 2, sign: "rock"});
  instance.addPlayer({id: 3, sign: "spock"});
  instance.addPlayer(4, "rock").addPlayer(5, "paper");
  instance.play();
  console.log(instance.winner);
  //note players that won-lost, add support for W-L records
  //bot.reply(message, 'test successful. maybe code something more useful next time?');
};
<commit_msg>Update RockPaperScissors.js<commit_after>module.exports = function(skill, info, bot, message, db) {
    bot.api.users.info({user: message.user}, (error, response) => {
    let {name, real_name} = response.user;

    var userData = message.text.match(/\<(.*?)\>/g);

    console.log('messaage text: ' + message.text);
    console.log('userdata' + userData);
  if (userData) {
    // if there is a user named send ze hugs!
    //for (var i = 0, len = userData.length; i < len; i++) {
        //FU(userData[i].replace(/[^\w\s]/gi, ''));
        //console.log('userdate[i]' + userData[i]);
        //console.log('userdate[i]' + userData[i].replace(/[^\w\s]/gi, ''));
    //}
    //console.log(userData);
    bot.api.users.info({user: userData[0].replace(/[^\w\s]/gi, '')}, (error, response) => {let {challengedName, challengedReal_name} = response.user;
       bot.reply(message,'Let\'s rumble ' + challengedReal_name);
    })

    //bot.reply(message,'Let\'s rumble' + userData[0].replace(/[^\w\s]/gi, ''));
  } else {
    bot.reply(message, 'You didn\'t challenge anyone you chicken shit! :chicken: :poop:');
  }

function FU(user) {
    //DM some shade!
    bot.api.im.open({ user: user }, function (err, response) {
      if (err) {
        return console.log(err)
      }
    var fuckArray = [
    'https://giphy.com/gifs/cheezburger-olympics-U7P2vnWfPkIQ8',
    'https://giphy.com/gifs/louis-ck-middle-finger-fuck-you-Qd71uU3LzyxXO'
    ];
    var randomFuck = Math.floor(Math.random()* fuckArray.length);

    var dmChannel = response.channel.id
    bot.say({channel: dmChannel, text: 'Someone is throwing shade your way... :middle_finger:'})
    bot.say({channel: dmChannel, text: fuckArray[randomFuck]})
    })

}

})

  var gameEngine = require('./Rock-Paper-Spock');

    bot.api.users.info({user: message.user}, (error, response) => {
        //bot.reply(message, 'Rock Paper Scissors (lizard, spock, spiderman, batman, wizard, glock?)');
    })

  var instance = new gameEngine(gameEngine.DefaultRules);
  instance.addPlayer({id: 1, sign: "spock"});
  instance.addPlayer({id: 2, sign: "rock"});
  instance.addPlayer({id: 3, sign: "spock"});
  instance.addPlayer(4, "rock").addPlayer(5, "paper");
  instance.play();
  console.log(instance.winner);
  //note players that won-lost, add support for W-L records
  //bot.reply(message, 'test successful. maybe code something more useful next time?');
};
<|endoftext|>


<commit_before>'use strict';

var vows = require('vows');
var assert = require('assert');
var EventEmitter = require('events').EventEmitter;
var _ = require('lodash');
var $28 = new (require('../lib/28.js').$28)('http://portal.28.io/api');

var email = 'w+test@28.io';

vows.describe('API Tests').addBatch({
    'Test Login': {
        'login with wrong password': {
            topic: function(){
                var promise = new EventEmitter();
                $28.login(email, 'foobar1')
                .then(function(result){
                    promise.emit('success', result);
                }, function(result){
                    promise.emit('error', result.body);
                });
                return promise;
            },
            'Should have a wrong password error': function(error, success){
                assert.equal(success, undefined, 'Shouldn\'t be a success.');
                assert.equal(error.code, 'errors:wrong-password', 'Wrong password');
            }
        },
        'login with correct password': {
            topic: function(){
                var promise = new EventEmitter();
                $28.login(email, 'foobar')
                .then(function(result){
                    promise.emit('success', result.body);
                }, function(result){
                    promise.emit('error', result.body);
                });
                return promise;
            },
            'Should have access tokens': function(error, session){
                assert.equal(error, undefined, 'Shouldn\'t be an error.');
                assert.equal(session.access_token !== undefined, true, 'Should have access token');
            },
            'Refresh tokens': {
                topic: function(session){
                    var promise = new EventEmitter();
                    $28.refreshTokens(email, session.refresh_token)
                    .then(function(result){
                        promise.emit('success', result.body);
                    }, function(result){
                        promise.emit('error', result.body);
                    });
                    return promise;
                },
                'Should get new session': function(error, session){
                    assert.equal(error, undefined, 'Shouldn\'t be an error.');
                    assert.equal(session.access_token !== undefined, true, 'Should have access token');
                }
            },
            'Invalid Refresh tokens': {
                topic: function(session){
                    var promise = new EventEmitter();
                    $28.refreshTokens(email, '123')
                    .then(function(result){
                        promise.emit('success', result.body);
                    }, function(result){
                        promise.emit('error', result.body);
                    });
                    return promise;
                },
                'Shouldn\'t get new session': function(error, session){
                    assert.equal(session, undefined, 'Shouldn\'t be a success.');
                    assert.equal(error.code, 'errors:invalid-token', 'Invalid tokens');
                }
            },
            'Upload (1)': {
                topic: function(session){
                    var promise = new EventEmitter();
                    var projectName = 'vows-project';
                    var projectToken = session.project_tokens['project_' + projectName];
                    if(!projectToken) {
                        throw new Error('project not found ' + projectName);
                    }
                    var projectPath = 'tests/test_project';
                    var overwrite = 0, deleteOrphaned = true, simulate = false;
                    $28
                    .upload(projectName, projectToken, projectPath, overwrite, deleteOrphaned, simulate, function(list){ return list; })
                    .then(function(success){
                        promise.emit('success', success);
                    })
                    .catch(function(error){
                        promise.emit('error', error);
                    });
                    return promise;
                },
                'Upload shouldn\'t succeed': function(error, success){
                    assert.equal(success, undefined);
                    assert.equal(_.isObject(error), true);
                }
            },
            'Upload (2)': {
                topic: function(session){
                    var promise = new EventEmitter();
                    var projectName = 'vows-project';
                    var projectToken = session.project_tokens['project_' + projectName];
                    if(!projectToken) {
                        throw new Error('project not found ' + projectName);
                    }
                    var projectPath = 'tests/test_project2';
                    var overwrite = 0, deleteOrphaned = true, simulate = false;
                    $28
                        .upload('http://vows-project.28.io/v1', projectToken, projectPath, overwrite, deleteOrphaned, simulate, function(list){ return list; })
                        .then(function(success){
                            promise.emit('success', success);
                        })
                        .catch(function(error){
                            promise.emit('error', error);
                        });
                    return promise;
                },
                'Upload should succeed': function(error, success){
                    assert.equal(error, undefined);
                    assert.equal(success !== undefined, true);
                }
            }
        }
    }
}).export(module);<commit_msg>:wrench:<commit_after>'use strict';

var vows = require('vows');
var assert = require('assert');
var EventEmitter = require('events').EventEmitter;
var _ = require('lodash');
var $28 = new (require('../lib/28.js').$28)('http://portal.28.io/api');

var email = 'w+test@28.io';

vows.describe('API Tests').addBatch({
    'Test Login': {
        'login with wrong password': {
            topic: function(){
                var promise = new EventEmitter();
                $28.login(email, 'foobar1')
                .then(function(result){
                    promise.emit('success', result);
                }, function(result){
                    promise.emit('error', result.body);
                });
                return promise;
            },
            'Should have a wrong password error': function(error, success){
                assert.equal(success, undefined, 'Shouldn\'t be a success.');
                assert.equal(error.code, 'errors:wrong-password', 'Wrong password');
            }
        },
        'login with correct password': {
            topic: function(){
                var promise = new EventEmitter();
                $28.login(email, 'foobar')
                .then(function(result){
                    promise.emit('success', result.body);
                }, function(result){
                    promise.emit('error', result.body);
                });
                return promise;
            },
            'Should have access tokens': function(error, session){
                assert.equal(error, undefined, 'Shouldn\'t be an error.');
                assert.equal(session.access_token !== undefined, true, 'Should have access token');
            },
            'Refresh tokens': {
                topic: function(session){
                    var promise = new EventEmitter();
                    $28.refreshTokens(email, session.refresh_token)
                    .then(function(result){
                        promise.emit('success', result.body);
                    }, function(result){
                        promise.emit('error', result.body);
                    });
                    return promise;
                },
                'Should get new session': function(error, session){
                    assert.equal(error, undefined, 'Shouldn\'t be an error.');
                    assert.equal(session.access_token !== undefined, true, 'Should have access token');
                }
            },
            'Invalid Refresh tokens': {
                topic: function(session){
                    var promise = new EventEmitter();
                    $28.refreshTokens(email, '123')
                    .then(function(result){
                        promise.emit('success', result.body);
                    }, function(result){
                        promise.emit('error', result.body);
                    });
                    return promise;
                },
                'Shouldn\'t get new session': function(error, session){
                    assert.equal(session, undefined, 'Shouldn\'t be a success.');
                    assert.equal(error.code, 'errors:invalid-token', 'Invalid tokens');
                }
            },
            'Upload (1)': {
                topic: function(session){
                    var promise = new EventEmitter();
                    var projectName = 'vows-project';
                    var projectToken = session.project_tokens['project_' + projectName];
                    if(!projectToken) {
                        throw new Error('project not found ' + projectName);
                    }
                    var projectPath = 'tests/test_project';
                    var overwrite = 0, deleteOrphaned = true, simulate = false;
                    $28
                    .upload(projectName, projectToken, projectPath, overwrite, deleteOrphaned, simulate, function(list){ return list; })
                    .then(function(success){
                        promise.emit('success', success);
                    })
                    .catch(function(error){
                        promise.emit('error', error);
                    });
                    return promise;
                },
                'Upload shouldn\'t succeed': function(error, success){
                    assert.equal(success, undefined);
                    assert.equal(_.isObject(error), true);
                }
            },
            'Upload (2)': {
                topic: function(session){
                    var promise = new EventEmitter();
                    var projectName = 'vows-project2';
                    var projectToken = session.project_tokens['project_' + projectName];
                    if(!projectToken) {
                        throw new Error('project not found ' + projectName);
                    }
                    var projectPath = 'tests/test_project2';
                    var overwrite = 0, deleteOrphaned = true, simulate = false;
                    $28
                        .upload('http://vows-project2.28.io/v1', projectToken, projectPath, overwrite, deleteOrphaned, simulate, function(list){ return list; })
                        .then(function(success){
                            promise.emit('success', success);
                        })
                        .catch(function(error){
                            promise.emit('error', error);
                        });
                    return promise;
                },
                'Upload should succeed': function(error, success){
                    assert.equal(error, undefined);
                    assert.equal(success !== undefined, true);
                }
            }
        }
    }
}).export(module);
<|endoftext|>


<commit_before>/**
	@fileoverview AlaSQL JavaScript SQL library
	@see http://github.com/agershun/alasql
*/

/**
	Callback from statement
	@callback statement-callback
	@param {object} data Result data
*/

/**
	UMD envelope for AlaSQL
*/

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define([], factory);
    } else if (typeof exports === 'object') {
    	/** alasql main function */
        module.exports = factory();
    } else {
        root.alasql = factory();
    }
}(this, function () {

/**
	AlaSQL - Main Alasql class
 	@function
 	@param {string|function|object} sql - SQL-statement or data object for fuent interface
 	@param {object} params - SQL parameters
 	@param {function} cb - callback function
 	@param {object} scope - Scope for nested queries
 	@return {any} - Result data object

	@example
 Standard sync call:
    alasql('CREATE TABLE one');
 Query:
 	var res = alasql('SELECT * FROM one');
 Call with parameters:
 	var res = alasql('SELECT * FROM ?',[data]);
 Standard async call with callback function:
 	alasql('SELECT * FROM ?',[data],function(res){
		console.log(data);
 	});
 Call with scope for subquery (to pass common values):
    var scope = {one:{a:2,b;20}}
    alasql('SELECT * FROM ? two WHERE two.a = one.a',[data],null,scope);
 Call for fluent interface with data object:
    alasql(data).Where(function(x){return x.a == 10}).exec();
 Call for fluent interface without data object:
    alasql().From(data).Where(function(x){return x.a == 10}).exec();
 */

var alasql = function alasql(sql, params, cb, scope) {
	if(typeof importScripts !== 'function' && alasql.webworker) {
		var id = alasql.lastid++;
		alasql.buffer[id] = cb;
		alasql.webworker.postMessage({id:id,sql:sql,params:params});
	} else {
		if(arguments.length === 0) {
			// Without arguments - Fluent interface
			return new yy.Select({
				columns:[new yy.Column({columnid:'*'})],
				from: [new yy.ParamValue({param:0})]
			});
		} else if (arguments.length === 1 && typeof sql === "object" && sql instanceof Array) {
			// One argument data object - fluent interface
				var select = new yy.Select({
					columns:[new yy.Column({columnid:'*'})],
					from: [new yy.ParamValue({param:0})]
				});
				select.preparams = [sql];
				return select;
		} else {
			// Standard interface
			// alasql('#sql');
			if(typeof sql === 'string' && sql[0]==='#' && typeof document === "object") {
				sql = document.querySelector(sql).textContent;
			} else if(typeof sql === 'object' && sql instanceof HTMElement) {
				sql = sql.textContent;
			} else if(typeof sql === 'function') {
				// to run multiline functions
				sql = sql.toString().slice(14,-3);
			}
			// Run SQL
			return alasql.exec(sql, params, cb, scope);
		}
	}
};

/**
	Current version of alasql
 	@constant {string}
*/
alasql.version = 'PACKAGE_VERSION_NUMBER';

/**
	Debug flag
	@type {boolean}
*/
alasql.debug = undefined; // Initial debug variable

/**
	Get path of alasql.js
	@function
	@todo Rewrite and simplify the code. Review, is this function is required separately
*/
function getAlaSQLPath() {
	/** type {string} Path to alasql library and plugins */
	alasql.path = '';

	if (typeof importScripts === 'function') {
		alasql.path = '';
		/** @todo Check how to get path in worker */
	} else if(typeof exports !== 'undefined') {
		alasql.path = __dirname;

	} else if(typeof Meteor === 'object' && Meteor.isClient) {
		alasql.path = '/packages/dist/';

	} else if(typeof Meteor === 'object' && Meteor.isServer) {
		alasql.path = 'assets/packages/dist/';

	} else if(typeof document !== 'undefined') {
		var sc = document.getElementsByTagName('script');

		for(var i=0;i<sc.length;i++) {
			if (sc[i].src.substr(-16).toLowerCase() === 'alasql-worker.js') {
				alasql.path = sc[i].src.substr(0,sc[i].src.length-16);
				break;

			} else if (sc[i].src.substr(-20).toLowerCase() === 'alasql-worker.min.js') {
				alasql.path = sc[i].src.substr(0,sc[i].src.length-20);
				break;

			} else if (sc[i].src.substr(-9).toLowerCase() === 'alasql.js') {
				alasql.path = sc[i].src.substr(0,sc[i].src.length-9);
				break;

			} else if (sc[i].src.substr(-13).toLowerCase() === 'alasql.min.js') {
				alasql.path = sc[i].src.substr(0,sc[i].src.length-13);
				break;
			}
		}
	}
}

getAlaSQLPath();

<commit_msg>Small misspelling<commit_after>/**
	@fileoverview AlaSQL JavaScript SQL library
	@see http://github.com/agershun/alasql
*/

/**
	Callback from statement
	@callback statement-callback
	@param {object} data Result data
*/

/**
	UMD envelope for AlaSQL
*/

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define([], factory);
    } else if (typeof exports === 'object') {
    	/** alasql main function */
        module.exports = factory();
    } else {
        root.alasql = factory();
    }
}(this, function () {

/**
	AlaSQL - Main Alasql class
 	@function
 	@param {string|function|object} sql - SQL-statement or data object for fuent interface
 	@param {object} params - SQL parameters
 	@param {function} cb - callback function
 	@param {object} scope - Scope for nested queries
 	@return {any} - Result data object

	@example
 Standard sync call:
    alasql('CREATE TABLE one');
 Query:
 	var res = alasql('SELECT * FROM one');
 Call with parameters:
 	var res = alasql('SELECT * FROM ?',[data]);
 Standard async call with callback function:
 	alasql('SELECT * FROM ?',[data],function(res){
		console.log(data);
 	});
 Call with scope for subquery (to pass common values):
    var scope = {one:{a:2,b;20}}
    alasql('SELECT * FROM ? two WHERE two.a = one.a',[data],null,scope);
 Call for fluent interface with data object:
    alasql(data).Where(function(x){return x.a == 10}).exec();
 Call for fluent interface without data object:
    alasql().From(data).Where(function(x){return x.a == 10}).exec();
 */

var alasql = function alasql(sql, params, cb, scope) {
	if(typeof importScripts !== 'function' && alasql.webworker) {
		var id = alasql.lastid++;
		alasql.buffer[id] = cb;
		alasql.webworker.postMessage({id:id,sql:sql,params:params});
	} else {
		if(arguments.length === 0) {
			// Without arguments - Fluent interface
			return new yy.Select({
				columns:[new yy.Column({columnid:'*'})],
				from: [new yy.ParamValue({param:0})]
			});
		} else if (arguments.length === 1 && typeof sql === "object" && sql instanceof Array) {
			// One argument data object - fluent interface
				var select = new yy.Select({
					columns:[new yy.Column({columnid:'*'})],
					from: [new yy.ParamValue({param:0})]
				});
				select.preparams = [sql];
				return select;
		} else {
			// Standard interface
			// alasql('#sql');
			if(typeof sql === 'string' && sql[0]==='#' && typeof document === "object") {
				sql = document.querySelector(sql).textContent;
			} else if(typeof sql === 'object' && sql instanceof HTMLElement) {
				sql = sql.textContent;
			} else if(typeof sql === 'function') {
				// to run multiline functions
				sql = sql.toString().slice(14,-3);
			}
			// Run SQL
			return alasql.exec(sql, params, cb, scope);
		}
	}
};

/**
	Current version of alasql
 	@constant {string}
*/
alasql.version = 'PACKAGE_VERSION_NUMBER';

/**
	Debug flag
	@type {boolean}
*/
alasql.debug = undefined; // Initial debug variable

/**
	Get path of alasql.js
	@function
	@todo Rewrite and simplify the code. Review, is this function is required separately
*/
function getAlaSQLPath() {
	/** type {string} Path to alasql library and plugins */
	alasql.path = '';

	if (typeof importScripts === 'function') {
		alasql.path = '';
		/** @todo Check how to get path in worker */
	} else if(typeof exports !== 'undefined') {
		alasql.path = __dirname;

	} else if(typeof Meteor === 'object' && Meteor.isClient) {
		alasql.path = '/packages/dist/';

	} else if(typeof Meteor === 'object' && Meteor.isServer) {
		alasql.path = 'assets/packages/dist/';

	} else if(typeof document !== 'undefined') {
		var sc = document.getElementsByTagName('script');

		for(var i=0;i<sc.length;i++) {
			if (sc[i].src.substr(-16).toLowerCase() === 'alasql-worker.js') {
				alasql.path = sc[i].src.substr(0,sc[i].src.length-16);
				break;

			} else if (sc[i].src.substr(-20).toLowerCase() === 'alasql-worker.min.js') {
				alasql.path = sc[i].src.substr(0,sc[i].src.length-20);
				break;

			} else if (sc[i].src.substr(-9).toLowerCase() === 'alasql.js') {
				alasql.path = sc[i].src.substr(0,sc[i].src.length-9);
				break;

			} else if (sc[i].src.substr(-13).toLowerCase() === 'alasql.min.js') {
				alasql.path = sc[i].src.substr(0,sc[i].src.length-13);
				break;
			}
		}
	}
}

getAlaSQLPath();

<|endoftext|>


<commit_before>var should = require('should');
var render = require('./util').render;

describe('compiler', function() {
    it('should compile templates', function() {
        var s = render('Hello world');
        s.should.equal('Hello world');

        s = render('Hello world, {{ name }}',
                   { name: 'James' });
        s.should.equal('Hello world, James');

        s = render('Hello world, {{name}}{{suffix}}, how are you',
                   { name: 'James',
                     suffix: ' Long'});
        s.should.equal('Hello world, James Long, how are you');
    });

    it('should escape newlines', function() {
        render('foo\\nbar').should.equal('foo\\nbar');
    });

    it('should compile references', function() {
        var s = render('{{ foo.bar }}',
                       { foo: { bar: 'baz' }});
        s.should.equal('baz');

        s = render('{{ foo["bar"] }}',
                   { foo: { bar: 'baz' }});
        s.should.equal('baz');
    });

    it('should compile function calls', function() {
        var s = render('{{ foo("msg") }}',
                       { foo: function(str) { return str + 'hi'; }});
        s.should.equal('msghi');
    });

    it('should compile if blocks', function() {
        var tmpl = ('Give me some {% if hungry %}pizza' +
                    '{% else %}water{% endif %}');

        var s = render(tmpl, { hungry: true });
        s.should.equal('Give me some pizza');

        s = render(tmpl, { hungry: false });
        s.should.equal('Give me some water');

        s = render('{% if not hungry %}good{% endif %}',
                   { hungry: false });
        s.should.equal('good');

        s = render('{% if hungry and like_pizza %}good{% endif %}',
            { hungry: true, like_pizza: true });
        s.should.equal('good');

        s = render('{% if hungry or like_pizza %}good{% endif %}',
            { hungry: false, like_pizza: true });
        s.should.equal('good');

        s = render('{% if (hungry or like_pizza) and anchovies %}good{% endif %}',
            { hungry: false, like_pizza: true, anchovies: true });
        s.should.equal('good');

        s = render('{% if food == "pizza" %}pizza{% endif %}' +
                   '{% if food =="beer" %}beer{% endif %}',
                  { food: 'beer' });
        s.should.equal('beer');
    });

    it('should compile for blocks', function() {
        var s = render('{% for i in arr %}{{ i }}{% endfor %}',
                       { arr: [1, 2, 3, 4, 5] });
        s.should.equal('12345');

        s = render('{% for item in arr | batch(2) %}{{ item[0] }}{% endfor %}',
                   { arr: ['a', 'b', 'c', 'd'] });
        s.should.equal('ac');

        s = render('{% for k, v in { one: 1, two: 2 } %}' +
                   '-{{ k }}:{{ v }}-{% endfor %}');
        s.should.equal('-one:1--two:2-');

        s = render('{% for i in [7,3,6] %}{{ loop.index }}{% endfor %}');
        s.should.equal('123');

        s = render('{% for i in [7,3,6] %}{{ loop.index0 }}{% endfor %}');
        s.should.equal('012');

        s = render('{% for i in [7,3,6] %}{{ loop.revindex }}{% endfor %}');
        s.should.equal('321');

        s = render('{% for i in [7,3,6] %}{{ loop.revindex0 }}{% endfor %}');
        s.should.equal('210');

        s = render('{% for i in [7,3,6] %}{% if loop.first %}{{ i }}{% endif %}{% endfor %}');
        s.should.equal('7');

        s = render('{% for i in [7,3,6] %}{% if loop.last %}{{ i }}{% endif %}{% endfor %}');
        s.should.equal('6');

        s = render('{% for i in [7,3,6] %}{{ loop.length }}{% endfor %}');
        s.should.equal('333');
    });

    it('should compile operators', function() {
        render('{{ 3 + 4 - 5 * 6 / 10 }}').should.equal('4');
        render('{{ 4**5 }}').should.equal('1024');
        render('{{ 9//5 }}').should.equal('1');
        render('{{ 9%5 }}').should.equal('4');
        render('{{ -5 }}').should.equal('-5');

        render('{% if 3 < 4 %}yes{% endif %}').should.equal('yes');
        render('{% if 3 > 4 %}yes{% endif %}').should.equal('');
        render('{% if 9 >= 10 %}yes{% endif %}').should.equal('');
        render('{% if 10 >= 10 %}yes{% endif %}').should.equal('yes');
        render('{% if 9 <= 10 %}yes{% endif %}').should.equal('yes');
        render('{% if 10 <= 10 %}yes{% endif %}').should.equal('yes');
        render('{% if 11 <= 10 %}yes{% endif %}').should.equal('');

        render('{% if 10 != 10 %}yes{% endif %}').should.equal('');
        render('{% if 10 == 10 %}yes{% endif %}').should.equal('yes');

        render('{% if foo(20) > bar %}yes{% endif %}',
               { foo: function(n) { return n - 1; },
                 bar: 15 })
            .should.equal('yes');
    });

    it('should compile macros', function() {
        var s = render('{% macro foo() %}This is a macro{% endmacro %}' +
                       '{{ foo() }}');
        s.should.equal('This is a macro');

        s = render('{% macro foo(x, y) %}{{ y }}{% endmacro %}' +
                   '{{ foo(1) }}');
        s.should.equal('undefined');

        s = render('{% macro foo(x, y) %}{{ y }}{% endmacro %}' +
                   '{{ foo(1, 2) }}');
        s.should.equal('2');

        s = render('{% macro foo(x, y, z=5) %}{{ y }}{% endmacro %}' +
                   '{{ foo(1, 2) }}');
        s.should.equal('2');

        s = render('{% macro foo(x, y, z=5) %}{{ z }}{% endmacro %}' +
                   '{{ foo(1, 2) }}');
        s.should.equal('5');

        s = render('{% macro foo(x, y, z=5) %}{{ y }}{% endmacro %}' +
                   '{{ foo(1, y=2) }}');
        s.should.equal('2');

        s = render('{% macro foo(x, y, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{{ foo(x=1, y=2) }}');
        s.should.equal('125');

        s = render('{% macro foo(x, y, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{{ foo(x=1, y=2, z=3) }}');
        s.should.equal('123');

        s = render('{% macro foo(x, y=2, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{{ foo(1, z=3) }}');
        s.should.equal('123');

        s = render('{% macro foo(x, y=2, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{{ foo(1) }}');
        s.should.equal('125');

        s = render('{% macro foo(x, y=2, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{{ foo(1, 10, 20) }}');
        s.should.equal('11020');

        s = render('{% extends "base.html" %}' +
                   '{% macro foo(x, y=2, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{% block block1 %}' +
                   '{{ foo(1) }}' +
                   '{% endblock %}');
        s.should.equal('Foo125BazFizzle');

        s = render('{% block bar %}' +
                   '{% macro foo(x, y=2, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{% endblock %}' +
                   '{% block baz %}' +
                   '{{ foo(1) }}' +
                   '{% endblock %}');
        s.should.equal('125');
    });

    it('should import templates', function() {
        var s = render('{% import "import.html" as imp %}' +
                       '{{ imp.foo() }} {{ imp.bar }}');
        s.should.equal("Here's a macro baz");

        s = render('{% from "import.html" import foo as baz, bar %}' +
                       '{{ bar }} {{ baz() }}');
        s.should.equal("baz Here's a macro");

        s = render('{% for i in [1,2] %}' +
                   'start: {{ num }}' +
                   '{% from "import.html" import bar as num %}' +
                   'end: {{ num }}' +
                   '{% endfor %}' +
                   'final: {{ num }}');
        // TODO: Should the for loop create a new frame for each
        // iteration? As it is, `num` is set on all iterations after
        // the first one sets it
        s.should.equal('start: end: bazstart: bazend: bazfinal: ');
    });

    it('should inherit templates', function() {
        var s = render('{% extends "base.html" %}');
        s.should.equal('FooBarBazFizzle');

        s = render('hola {% extends "base.html" %} hizzle mumble');
        s.should.equal('FooBarBazFizzle');

        s = render('{% extends "base.html" %}' +
                   '{% block block1 %}BAR{% endblock %}');
        s.should.equal('FooBARBazFizzle');

        s = render('{% extends "base.html" %}' +
                   '{% block block1 %}BAR{% endblock %}' +
                   '{% block block2 %}BAZ{% endblock %}');
        s.should.equal('FooBARBAZFizzle');

        s = render('hola {% extends tmpl %} hizzle mumble',
                   { tmpl: 'base.html' });
        s.should.equal('FooBarBazFizzle');
    });

    it('should render parent blocks with super()', function() {
        var s = render('{% extends "base.html" %}' +
                       '{% block block1 %}{{ super() }}BAR{% endblock %}');
        s.should.equal('FooBarBARBazFizzle');
    });

    it('should include templates', function() {
        var s = render('hello world {% include "include.html" %}');
        s.should.equal('hello world FooInclude ');

        s = render('hello world {% include "include.html" %}',
                  { name: 'james' });
        s.should.equal('hello world FooInclude james');

        s = render('hello world {% include tmpl %}',
                  { name: 'thedude', tmpl: "include.html" });
        s.should.equal('hello world FooInclude thedude');
    });

    it('should maintain nested scopes', function() {
        var s = render('{% for i in [1,2] %}' +
                       '{% for i in [3,4] %}{{ i }}{% endfor %}' +
                       '{{ i }}{% endfor %}');
        s.should.equal('341342');
    });

    it('should allow blocks in for loops', function() {
        var s = render('{% extends "base2.html" %}' +
                       '{% block item %}hello{{ item }}{% endblock %}');
        s.should.equal('hello1hello2');
    });

    it('should make includes inherit scope', function() {
        var s = render('{% for item in [1,2] %}' +
                       '{% include "item.html" %}' +
                       '{% endfor %}');
        s.should.equal('showing 1showing 2');
    });

    it('should compile a set block', function() {
        var s = render('{% set username = "foo" %}{{ username }}',
                       { username: 'james' });
        s.should.equal('foo');

        s = render('{% set x, y = "foo" %}{{ x }}{{ y }}');
        s.should.equal('foofoo');

        s = render('{% for i in [1] %}{% set foo=1 %}{% endfor %}{{ foo }}',
                   { foo: 2 });
        s.should.equal('2');

        s = render('{% include "set.html" %}{{ foo }}',
                   { foo: 'bar' });
        s.should.equal('bar');
    });

    it('should throw errors', function() {
        (function() {
            render('{% from "import.html" import boozle %}');
        }).should.throw(/cannot import 'boozle'/);
    });
});
<commit_msg>add tests for #14<commit_after>var should = require('should');
var render = require('./util').render;

describe('compiler', function() {
    it('should compile templates', function() {
        var s = render('Hello world');
        s.should.equal('Hello world');

        s = render('Hello world, {{ name }}',
                   { name: 'James' });
        s.should.equal('Hello world, James');

        s = render('Hello world, {{name}}{{suffix}}, how are you',
                   { name: 'James',
                     suffix: ' Long'});
        s.should.equal('Hello world, James Long, how are you');
    });

    it('should escape newlines', function() {
        render('foo\\nbar').should.equal('foo\\nbar');
    });

    it('should compile references', function() {
        var s = render('{{ foo.bar }}',
                       { foo: { bar: 'baz' }});
        s.should.equal('baz');

        s = render('{{ foo["bar"] }}',
                   { foo: { bar: 'baz' }});
        s.should.equal('baz');
    });

    it('should fail silently on undefined values', function() {
        var s = render('{{ foo }}');
        s.should.equal('');

        var s = render('{{ foo.bar }}');
        console.log(s);
        s.should.equal('');

        var s = render('{{ foo.bar.baz }}');
        s.should.equal('');

        var s = render('{{ foo.bar.baz["biz"].mumble }}');
        s.should.equal('');
    });

    it('should not treat falsy values the same as undefined', function() {
        var s = render('{{ foo }}', {foo: 0});
        s.should.equal('0');

        var s = render('{{ foo }}', {foo: false});
        s.should.equal('false');

        var s = render('{{ foo }}', {foo: null});
        s.should.equal('null');
    });

    it('should compile function calls', function() {
        var s = render('{{ foo("msg") }}',
                       { foo: function(str) { return str + 'hi'; }});
        s.should.equal('msghi');
    });

    it('should compile if blocks', function() {
        var tmpl = ('Give me some {% if hungry %}pizza' +
                    '{% else %}water{% endif %}');

        var s = render(tmpl, { hungry: true });
        s.should.equal('Give me some pizza');

        s = render(tmpl, { hungry: false });
        s.should.equal('Give me some water');

        s = render('{% if not hungry %}good{% endif %}',
                   { hungry: false });
        s.should.equal('good');

        s = render('{% if hungry and like_pizza %}good{% endif %}',
            { hungry: true, like_pizza: true });
        s.should.equal('good');

        s = render('{% if hungry or like_pizza %}good{% endif %}',
            { hungry: false, like_pizza: true });
        s.should.equal('good');

        s = render('{% if (hungry or like_pizza) and anchovies %}good{% endif %}',
            { hungry: false, like_pizza: true, anchovies: true });
        s.should.equal('good');

        s = render('{% if food == "pizza" %}pizza{% endif %}' +
                   '{% if food =="beer" %}beer{% endif %}',
                  { food: 'beer' });
        s.should.equal('beer');
    });

    it('should compile for blocks', function() {
        var s = render('{% for i in arr %}{{ i }}{% endfor %}',
                       { arr: [1, 2, 3, 4, 5] });
        s.should.equal('12345');

        s = render('{% for item in arr | batch(2) %}{{ item[0] }}{% endfor %}',
                   { arr: ['a', 'b', 'c', 'd'] });
        s.should.equal('ac');

        s = render('{% for k, v in { one: 1, two: 2 } %}' +
                   '-{{ k }}:{{ v }}-{% endfor %}');
        s.should.equal('-one:1--two:2-');

        s = render('{% for i in [7,3,6] %}{{ loop.index }}{% endfor %}');
        s.should.equal('123');

        s = render('{% for i in [7,3,6] %}{{ loop.index0 }}{% endfor %}');
        s.should.equal('012');

        s = render('{% for i in [7,3,6] %}{{ loop.revindex }}{% endfor %}');
        s.should.equal('321');

        s = render('{% for i in [7,3,6] %}{{ loop.revindex0 }}{% endfor %}');
        s.should.equal('210');

        s = render('{% for i in [7,3,6] %}{% if loop.first %}{{ i }}{% endif %}{% endfor %}');
        s.should.equal('7');

        s = render('{% for i in [7,3,6] %}{% if loop.last %}{{ i }}{% endif %}{% endfor %}');
        s.should.equal('6');

        s = render('{% for i in [7,3,6] %}{{ loop.length }}{% endfor %}');
        s.should.equal('333');
    });

    it('should compile operators', function() {
        render('{{ 3 + 4 - 5 * 6 / 10 }}').should.equal('4');
        render('{{ 4**5 }}').should.equal('1024');
        render('{{ 9//5 }}').should.equal('1');
        render('{{ 9%5 }}').should.equal('4');
        render('{{ -5 }}').should.equal('-5');

        render('{% if 3 < 4 %}yes{% endif %}').should.equal('yes');
        render('{% if 3 > 4 %}yes{% endif %}').should.equal('');
        render('{% if 9 >= 10 %}yes{% endif %}').should.equal('');
        render('{% if 10 >= 10 %}yes{% endif %}').should.equal('yes');
        render('{% if 9 <= 10 %}yes{% endif %}').should.equal('yes');
        render('{% if 10 <= 10 %}yes{% endif %}').should.equal('yes');
        render('{% if 11 <= 10 %}yes{% endif %}').should.equal('');

        render('{% if 10 != 10 %}yes{% endif %}').should.equal('');
        render('{% if 10 == 10 %}yes{% endif %}').should.equal('yes');

        render('{% if foo(20) > bar %}yes{% endif %}',
               { foo: function(n) { return n - 1; },
                 bar: 15 })
            .should.equal('yes');
    });

    it('should compile macros', function() {
        var s = render('{% macro foo() %}This is a macro{% endmacro %}' +
                       '{{ foo() }}');
        s.should.equal('This is a macro');

        s = render('{% macro foo(x, y) %}{{ y }}{% endmacro %}' +
                   '{{ foo(1) }}');
        s.should.equal('undefined');

        s = render('{% macro foo(x, y) %}{{ y }}{% endmacro %}' +
                   '{{ foo(1, 2) }}');
        s.should.equal('2');

        s = render('{% macro foo(x, y, z=5) %}{{ y }}{% endmacro %}' +
                   '{{ foo(1, 2) }}');
        s.should.equal('2');

        s = render('{% macro foo(x, y, z=5) %}{{ z }}{% endmacro %}' +
                   '{{ foo(1, 2) }}');
        s.should.equal('5');

        s = render('{% macro foo(x, y, z=5) %}{{ y }}{% endmacro %}' +
                   '{{ foo(1, y=2) }}');
        s.should.equal('2');

        s = render('{% macro foo(x, y, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{{ foo(x=1, y=2) }}');
        s.should.equal('125');

        s = render('{% macro foo(x, y, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{{ foo(x=1, y=2, z=3) }}');
        s.should.equal('123');

        s = render('{% macro foo(x, y=2, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{{ foo(1, z=3) }}');
        s.should.equal('123');

        s = render('{% macro foo(x, y=2, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{{ foo(1) }}');
        s.should.equal('125');

        s = render('{% macro foo(x, y=2, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{{ foo(1, 10, 20) }}');
        s.should.equal('11020');

        s = render('{% extends "base.html" %}' +
                   '{% macro foo(x, y=2, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{% block block1 %}' +
                   '{{ foo(1) }}' +
                   '{% endblock %}');
        s.should.equal('Foo125BazFizzle');

        s = render('{% block bar %}' +
                   '{% macro foo(x, y=2, z=5) %}{{ x }}{{ y }}{{ z }}' +
                   '{% endmacro %}' +
                   '{% endblock %}' +
                   '{% block baz %}' +
                   '{{ foo(1) }}' +
                   '{% endblock %}');
        s.should.equal('125');
    });

    it('should import templates', function() {
        var s = render('{% import "import.html" as imp %}' +
                       '{{ imp.foo() }} {{ imp.bar }}');
        s.should.equal("Here's a macro baz");

        s = render('{% from "import.html" import foo as baz, bar %}' +
                       '{{ bar }} {{ baz() }}');
        s.should.equal("baz Here's a macro");

        s = render('{% for i in [1,2] %}' +
                   'start: {{ num }}' +
                   '{% from "import.html" import bar as num %}' +
                   'end: {{ num }}' +
                   '{% endfor %}' +
                   'final: {{ num }}');
        // TODO: Should the for loop create a new frame for each
        // iteration? As it is, `num` is set on all iterations after
        // the first one sets it
        s.should.equal('start: end: bazstart: bazend: bazfinal: ');
    });

    it('should inherit templates', function() {
        var s = render('{% extends "base.html" %}');
        s.should.equal('FooBarBazFizzle');

        s = render('hola {% extends "base.html" %} hizzle mumble');
        s.should.equal('FooBarBazFizzle');

        s = render('{% extends "base.html" %}' +
                   '{% block block1 %}BAR{% endblock %}');
        s.should.equal('FooBARBazFizzle');

        s = render('{% extends "base.html" %}' +
                   '{% block block1 %}BAR{% endblock %}' +
                   '{% block block2 %}BAZ{% endblock %}');
        s.should.equal('FooBARBAZFizzle');

        s = render('hola {% extends tmpl %} hizzle mumble',
                   { tmpl: 'base.html' });
        s.should.equal('FooBarBazFizzle');
    });

    it('should render parent blocks with super()', function() {
        var s = render('{% extends "base.html" %}' +
                       '{% block block1 %}{{ super() }}BAR{% endblock %}');
        s.should.equal('FooBarBARBazFizzle');
    });

    it('should include templates', function() {
        var s = render('hello world {% include "include.html" %}');
        s.should.equal('hello world FooInclude ');

        s = render('hello world {% include "include.html" %}',
                  { name: 'james' });
        s.should.equal('hello world FooInclude james');

        s = render('hello world {% include tmpl %}',
                  { name: 'thedude', tmpl: "include.html" });
        s.should.equal('hello world FooInclude thedude');
    });

    it('should maintain nested scopes', function() {
        var s = render('{% for i in [1,2] %}' +
                       '{% for i in [3,4] %}{{ i }}{% endfor %}' +
                       '{{ i }}{% endfor %}');
        s.should.equal('341342');
    });

    it('should allow blocks in for loops', function() {
        var s = render('{% extends "base2.html" %}' +
                       '{% block item %}hello{{ item }}{% endblock %}');
        s.should.equal('hello1hello2');
    });

    it('should make includes inherit scope', function() {
        var s = render('{% for item in [1,2] %}' +
                       '{% include "item.html" %}' +
                       '{% endfor %}');
        s.should.equal('showing 1showing 2');
    });

    it('should compile a set block', function() {
        var s = render('{% set username = "foo" %}{{ username }}',
                       { username: 'james' });
        s.should.equal('foo');

        s = render('{% set x, y = "foo" %}{{ x }}{{ y }}');
        s.should.equal('foofoo');

        s = render('{% for i in [1] %}{% set foo=1 %}{% endfor %}{{ foo }}',
                   { foo: 2 });
        s.should.equal('2');

        s = render('{% include "set.html" %}{{ foo }}',
                   { foo: 'bar' });
        s.should.equal('bar');
    });

    it('should throw errors', function() {
        (function() {
            render('{% from "import.html" import boozle %}');
        }).should.throw(/cannot import 'boozle'/);
    });
});
<|endoftext|>


<commit_before>import Count from 'countup.js';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import warning from 'warning';

class CountUp extends Component {
  static propTypes = {
    decimal: PropTypes.string,
    decimals: PropTypes.number,
    delay: PropTypes.number,
    easingFn: PropTypes.func,
    end: PropTypes.number.isRequired,
    formattingFn: PropTypes.func,
    onEnd: PropTypes.func,
    onStart: PropTypes.func,
    prefix: PropTypes.string,
    redraw: PropTypes.bool,
    separator: PropTypes.string,
    start: PropTypes.number,
    suffix: PropTypes.string,
    style: PropTypes.object,
    useEasing: PropTypes.bool,
  };

  componentDidMount() {
    const { autostart, delay } = this.props;
    this.instance = this.createInstance();

    if (autostart || delay === 0) this.start();

    if (delay) setTimeout(this.start, delay * 1000);
  }

  shouldComponentUpdate(nextProps) {
    const hasCertainPropsChanged =
      this.props.duration !== nextProps.duration ||
      this.props.end !== nextProps.end ||
      this.props.start !== nextProps.start;

    return this.props.redraw || hasCertainPropsChanged;
  }

  componentDidUpdate(prevProps) {
    // If duration or start has changed, there's no way to update the duration
    // or start value. So we need to re-create the CountUp instance in order to
    // restart it.
    if (
      this.props.duration !== prevProps.duration ||
      this.props.start !== prevProps.start
    ) {
      this.instance = this.createInstance();
      this.start();
    }

    // Only end value has changed, so reset and and re-animate with the updated
    // end value.
    if (this.props.end !== prevProps.end) {
      this.instance.reset();
      this.instance.update(this.props.end);
    }
  }

  createInstance = () => {
    // Warn when user didn't use containerRef at all
    warning(
      this.containerRef.current &&
        this.containerRef.current instanceof HTMLElement,
      `Couldn't find attached element to hook the CountUp instance into! Try to attach "containerRef" from the render prop to a an HTMLElement, eg. <span ref={containerRef} />.`,
    );

    const {
      decimal,
      decimals,
      duration,
      easingFn,
      end,
      formattingFn,
      prefix,
      separator,
      start,
      suffix,
      useEasing,
    } = this.props;

    return new Count(
      this.containerRef.current,
      start,
      end,
      decimals,
      duration,
      {
        decimal,
        easingFn,
        formattingFn,
        separator,
        prefix,
        suffix,
        useEasing,
        useGrouping: !!separator,
      },
    );
  };

  pauseResume = (...args) => {
    const { onPauseResume } = this.props;

    if (typeof onPauseResume === 'function') onPauseResume(this);

    this.instance.pauseResume(...args);
  };

  reset = (...args) => {
    const { onReset } = this.props;

    if (typeof onReset === 'function') onReset(this);

    this.instance.reset(...args);
  };

  restart = () => {
    this.reset();
    this.start();
  };

  start = () => {
    const { onEnd, onStart } = this.props;
    const { pauseResume, reset, restart: start, update } = this;

    this.instance.start(
      typeof onEnd === 'function'
        ? () => onEnd({ pauseResume, reset, start, update })
        : undefined,
    );
    if (typeof onStart === 'function')
      onStart({ pauseResume, reset, start, update });
  };

  update = (...args) => {
    const { onUpdate } = this.props;

    if (typeof onUpdate === 'function') onUpdate(this);
  };

  containerRef = React.createRef();

  render() {
    const { children, className, style } = this.props;
    const { containerRef, pauseResume, reset, restart, update } = this;

    if (typeof children === 'function') {
      return children({
        countUpRef: containerRef,
        pauseResume,
        reset,
        start: restart,
        update,
      });
    }

    return ;
  }
}

CountUp.defaultProps = {
  decimal: '.',
  decimals: 0,
  delay: null,
  duration: null,
  easingFn: null,
  formattingFn: null,
  onEnd: null,
  onPauseResume: null,
  onReset: null,
  onStart: null,
  onUpdate: null,
  prefix: '',
  separator: '',
  start: 0,
  suffix: '',
  redraw: true,
  style: undefined,
  useEasing: true,
};

export default CountUp;
<commit_msg>Simplify<commit_after>import Count from 'countup.js';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import warning from 'warning';

class CountUp extends Component {
  static propTypes = {
    decimal: PropTypes.string,
    decimals: PropTypes.number,
    delay: PropTypes.number,
    easingFn: PropTypes.func,
    end: PropTypes.number.isRequired,
    formattingFn: PropTypes.func,
    onEnd: PropTypes.func,
    onStart: PropTypes.func,
    prefix: PropTypes.string,
    redraw: PropTypes.bool,
    separator: PropTypes.string,
    start: PropTypes.number,
    suffix: PropTypes.string,
    style: PropTypes.object,
    useEasing: PropTypes.bool,
  };

  componentDidMount() {
    const { autostart, delay } = this.props;
    this.instance = this.createInstance();

    if (typeof children !== 'function' || autostart || delay === 0)
      this.start();

    if (delay) setTimeout(this.start, delay * 1000);
  }

  shouldComponentUpdate(nextProps) {
    const hasCertainPropsChanged =
      this.props.duration !== nextProps.duration ||
      this.props.end !== nextProps.end ||
      this.props.start !== nextProps.start;

    return this.props.redraw || hasCertainPropsChanged;
  }

  componentDidUpdate(prevProps) {
    // If duration or start has changed, there's no way to update the duration
    // or start value. So we need to re-create the CountUp instance in order to
    // restart it.
    if (
      this.props.duration !== prevProps.duration ||
      this.props.start !== prevProps.start
    ) {
      this.instance = this.createInstance();
      this.start();
    }

    // Only end value has changed, so reset and and re-animate with the updated
    // end value.
    if (this.props.end !== prevProps.end) {
      this.instance.reset();
      this.instance.update(this.props.end);
    }
  }

  createInstance = () => {
    // Warn when user didn't use containerRef at all
    warning(
      this.containerRef.current &&
        this.containerRef.current instanceof HTMLElement,
      `Couldn't find attached element to hook the CountUp instance into! Try to attach "containerRef" from the render prop to a an HTMLElement, eg. <span ref={containerRef} />.`,
    );

    const {
      decimal,
      decimals,
      duration,
      easingFn,
      end,
      formattingFn,
      prefix,
      separator,
      start,
      suffix,
      useEasing,
    } = this.props;

    return new Count(
      this.containerRef.current,
      start,
      end,
      decimals,
      duration,
      {
        decimal,
        easingFn,
        formattingFn,
        separator,
        prefix,
        suffix,
        useEasing,
        useGrouping: !!separator,
      },
    );
  };

  pauseResume = () => {
    const { reset, restart: start, update } = this;
    const { onPauseResume } = this.props;

    this.instance.pauseResume();

    onPauseResume({ reset, start, update });
  };

  reset = () => {
    const { pauseResume, restart: start, update } = this;
    const { onReset } = this.props;

    this.instance.reset();

    onReset({ pauseResume, start, update });
  };

  restart = () => {
    this.reset();
    this.start();
  };

  start = () => {
    const { pauseResume, reset, restart: start, update } = this;
    const { onEnd, onStart } = this.props;

    this.instance.start(() => onEnd({ pauseResume, reset, start, update }));

    onStart({ pauseResume, reset, update });
  };

  update = (...args) => {
    const { pauseResume, reset, restart: start } = this;
    const { onUpdate } = this.props;

    this.instance.update(...args);

    onUpdate({ pauseResume, reset, start });
  };

  containerRef = React.createRef();

  render() {
    const { children, className, style } = this.props;
    const { containerRef, pauseResume, reset, restart, update } = this;

    if (typeof children === 'function') {
      return children({
        countUpRef: containerRef,
        pauseResume,
        reset,
        start: restart,
        update,
      });
    }

    return ;
  }
}

CountUp.defaultProps = {
  decimal: '.',
  decimals: 0,
  delay: 2,
  duration: null,
  easingFn: null,
  formattingFn: null,
  onEnd: () => {},
  onPauseResume: () => {},
  onReset: () => {},
  onStart: () => {},
  onUpdate: () => {},
  prefix: '',
  separator: '',
  start: 0,
  suffix: '',
  redraw: true,
  style: undefined,
  useEasing: true,
};

export default CountUp;
<|endoftext|>


<commit_before>function Display(canvas) {
  this.cvs = canvas;
  this.ctx = canvas.getContext('2d');

  this.width = this.cvs.width = this._WIDTH;
  this.height = this.cvs.height = this._HEIGHT;

  this.data = this.ctx.createImageData(this.width, this.height);
  this.uint32 = new Uint32Array(this.data.data.buffer);
};

Display.prototype._WIDTH = 256;
Display.prototype._HEIGHT = 240;

Display.prototype.renderPixel = function(x, y, c) {
  var index = y * this.width + x;
  this.uint32[index] = c;
};

Display.prototype.updateScreen = function() {
  this.ctx.putImageData(this.data, 0, 0);
};
<commit_msg>Clean up Display.js<commit_after>/**
 *
 */
function Display(canvas) {
  this.ctx = canvas.getContext('2d');

  this.width = canvas.width = 256;
  this.height = canvas.height = 240;

  this.data = this.ctx.createImageData(this.width, this.height);
  this.uint32 = new Uint32Array(this.data.data.buffer);
}

Object.assign(Display.prototype, {
  isDisplay: true,

  renderPixel: function(x, y, c) {
    var index = y * this.width + x;
    this.uint32[index] = c;
  },

  updateScreen: function() {
    this.ctx.putImageData(this.data, 0, 0);
  }
});
<|endoftext|>


<commit_before>/* ===========================================================
 * bootstrap-tooltip.js v2.3.2
 * http://twitter.github.com/bootstrap/javascript.html#tooltips
 * Inspired by the original jQuery.tipsy by Jason Frame
 * ===========================================================
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

!function ($) {

  "use strict"; // jshint ;_;

 /* TOOLTIP PUBLIC CLASS DEFINITION
  * =============================== */

  var Tooltip = function (element, options) {
    this.init('tooltip', element, options)
  }

  Tooltip.prototype = {

    constructor: Tooltip

  , init: function (type, element, options) {
      var eventIn
        , eventOut
        , triggers
        , trigger
        , i

      this.type = type
      this.$element = $(element)
      this.options = this.getOptions(options)
      this.enabled = true

      triggers = this.options.trigger.split(' ')

      for (i = triggers.length; i--;) {
        trigger = triggers[i]
        if (trigger == 'click') {
          this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
        } else if (trigger != 'manual') {
          eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
          eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
          this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
          this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
        }
      }

      this.options.selector ?
        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
        this.fixTitle()
    }

  , getOptions: function (options) {
      options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)

      if (options.delay && typeof options.delay == 'number') {
        options.delay = {
          show: options.delay
        , hide: options.delay
        }
      }

      return options
    }

  , enter: function (e) {
      var defaults = $.fn[this.type].defaults
        , options = {}
        , self

      this._options && $.each(this._options, function (key, value) {
        if (defaults[key] != value) options[key] = value
      }, this)

      self = $(e.currentTarget)[this.type](options).data(this.type)

      if (!self.options.delay || !self.options.delay.show) return self.show()

      clearTimeout(this.timeout)
      self.hoverState = 'in'
      this.timeout = setTimeout(function() {
        if (self.hoverState == 'in') self.show()
      }, self.options.delay.show)
    }

  , leave: function (e) {
      var self = $(e.currentTarget)[this.type](this._options).data(this.type)

      if (this.timeout) clearTimeout(this.timeout)
      if (!self.options.delay || !self.options.delay.hide) return self.hide()

      self.hoverState = 'out'
      this.timeout = setTimeout(function() {
        if (self.hoverState == 'out') self.hide()
      }, self.options.delay.hide)
    }

  , show: function () {
      var $tip
        , pos
        , actualWidth
        , actualHeight
        , placement
        , tp
        , e = $.Event('show')

      if (this.hasContent() && this.enabled) {
        this.$element.trigger(e)
        if (e.isDefaultPrevented()) return
        $tip = this.tip()
        this.setContent()

        if (this.options.animation) {
          $tip.addClass('fade')
        }

        placement = typeof this.options.placement == 'function' ?
          this.options.placement.call(this, $tip[0], this.$element[0]) :
          this.options.placement

        $tip
          .detach()
          .css({ top: 0, left: 0, display: 'block' })

        this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)

        pos = this.getPosition()

        actualWidth = $tip[0].offsetWidth
        actualHeight = $tip[0].offsetHeight

        switch (placement) {
          case 'bottom':
            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'top':
            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'left':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
            break
          case 'right':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
            break
        }

        this.applyPlacement(tp, placement)
        this.$element.trigger('shown')
      }
    }

  , applyPlacement: function(offset, placement){
      var $tip = this.tip()
        , width = $tip[0].offsetWidth
        , height = $tip[0].offsetHeight
        , actualWidth
        , actualHeight
        , delta
        , replace

      $tip
        .offset(offset)
        .addClass(placement)
        .addClass('in')

      actualWidth = $tip[0].offsetWidth
      actualHeight = $tip[0].offsetHeight

      if (placement == 'top' && actualHeight != height) {
        offset.top = offset.top + height - actualHeight
        replace = true
      }

      if (placement == 'bottom' || placement == 'top') {
        delta = 0

        if (offset.left < 0){
          delta = offset.left * -2
          offset.left = 0
          $tip.offset(offset)
          actualWidth = $tip[0].offsetWidth
          actualHeight = $tip[0].offsetHeight
        }

        this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
      } else {
        this.replaceArrow(actualHeight - height, actualHeight, 'top')
      }

      if (replace) $tip.offset(offset)
    }

  , replaceArrow: function(delta, dimension, position){
      this
        .arrow()
        .css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
    }

  , setContent: function () {
      var $tip = this.tip()
        , title = this.getTitle()

      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
      $tip.removeClass('fade in top bottom left right')
    }

  , hide: function () {
      var that = this
        , $tip = this.tip()
        , e = $.Event('hide')

      this.$element.trigger(e)
      if (e.isDefaultPrevented()) return

      $tip.removeClass('in')

      function removeWithAnimation() {
        var timeout = setTimeout(function () {
          $tip.off($.support.transition.end).detach()
        }, 500)

        $tip.one($.support.transition.end, function () {
          clearTimeout(timeout)
          $tip.detach()
        })
      }

      $.support.transition && this.$tip.hasClass('fade') ?
        removeWithAnimation() :
        $tip.detach()

      this.$element.trigger('hidden')

      return this
    }

  , fixTitle: function () {
      var $e = this.$element
      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
        $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
      }
    }

  , hasContent: function () {
      return this.getTitle()
    }

  , getPosition: function () {
      var el = this.$element[0]
      return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
        width: el.offsetWidth
      , height: el.offsetHeight
      }, this.$element.offset())
    }

  , getTitle: function () {
      var title
        , $e = this.$element
        , o = this.options

      title = $e.attr('data-original-title')
        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)

      return title
    }

  , tip: function () {
      return this.$tip = this.$tip || $(this.options.template)
    }

  , arrow: function(){
      return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
    }

  , validate: function () {
      if (!this.$element[0].parentNode) {
        this.hide()
        this.$element = null
        this.options = null
      }
    }

  , enable: function () {
      this.enabled = true
    }

  , disable: function () {
      this.enabled = false
    }

  , toggleEnabled: function () {
      this.enabled = !this.enabled
    }

  , toggle: function (e) {
      var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this
      self.tip().hasClass('in') ? self.hide() : self.show()
    }

  , destroy: function () {
      this.hide().$element.off('.' + this.type).removeData(this.type)
    }

  }

 /* TOOLTIP PLUGIN DEFINITION
  * ========================= */

  var old = $.fn.tooltip

  $.fn.tooltip = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('tooltip')
        , options = typeof option == 'object' && option
      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.tooltip.Constructor = Tooltip

  $.fn.tooltip.defaults = {
    animation: true
  , placement: 'top'
  , selector: false
  , template: '

'
  , trigger: 'hover focus'
  , title: ''
  , delay: 0
  , html: false
  , container: false
  }

 /* TOOLTIP NO CONFLICT
  * =================== */

  $.fn.tooltip.noConflict = function () {
    $.fn.tooltip = old
    return this
  }

}(window.jQuery);
<commit_msg>update twitter js script comment<commit_after>/* ===========================================================
 * bootstrap-tooltip.js v2.3.2
 * http://getbootstrap.com/2.3.2/javascript.html#tooltips
 * Inspired by the original jQuery.tipsy by Jason Frame
 * ===========================================================
 * Copyright 2013 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

!function ($) {

  "use strict"; // jshint ;_;

 /* TOOLTIP PUBLIC CLASS DEFINITION
  * =============================== */

  var Tooltip = function (element, options) {
    this.init('tooltip', element, options)
  }

  Tooltip.prototype = {

    constructor: Tooltip

  , init: function (type, element, options) {
      var eventIn
        , eventOut
        , triggers
        , trigger
        , i

      this.type = type
      this.$element = $(element)
      this.options = this.getOptions(options)
      this.enabled = true

      triggers = this.options.trigger.split(' ')

      for (i = triggers.length; i--;) {
        trigger = triggers[i]
        if (trigger == 'click') {
          this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
        } else if (trigger != 'manual') {
          eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
          eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
          this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
          this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
        }
      }

      this.options.selector ?
        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
        this.fixTitle()
    }

  , getOptions: function (options) {
      options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)

      if (options.delay && typeof options.delay == 'number') {
        options.delay = {
          show: options.delay
        , hide: options.delay
        }
      }

      return options
    }

  , enter: function (e) {
      var defaults = $.fn[this.type].defaults
        , options = {}
        , self

      this._options && $.each(this._options, function (key, value) {
        if (defaults[key] != value) options[key] = value
      }, this)

      self = $(e.currentTarget)[this.type](options).data(this.type)

      if (!self.options.delay || !self.options.delay.show) return self.show()

      clearTimeout(this.timeout)
      self.hoverState = 'in'
      this.timeout = setTimeout(function() {
        if (self.hoverState == 'in') self.show()
      }, self.options.delay.show)
    }

  , leave: function (e) {
      var self = $(e.currentTarget)[this.type](this._options).data(this.type)

      if (this.timeout) clearTimeout(this.timeout)
      if (!self.options.delay || !self.options.delay.hide) return self.hide()

      self.hoverState = 'out'
      this.timeout = setTimeout(function() {
        if (self.hoverState == 'out') self.hide()
      }, self.options.delay.hide)
    }

  , show: function () {
      var $tip
        , pos
        , actualWidth
        , actualHeight
        , placement
        , tp
        , e = $.Event('show')

      if (this.hasContent() && this.enabled) {
        this.$element.trigger(e)
        if (e.isDefaultPrevented()) return
        $tip = this.tip()
        this.setContent()

        if (this.options.animation) {
          $tip.addClass('fade')
        }

        placement = typeof this.options.placement == 'function' ?
          this.options.placement.call(this, $tip[0], this.$element[0]) :
          this.options.placement

        $tip
          .detach()
          .css({ top: 0, left: 0, display: 'block' })

        this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)

        pos = this.getPosition()

        actualWidth = $tip[0].offsetWidth
        actualHeight = $tip[0].offsetHeight

        switch (placement) {
          case 'bottom':
            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'top':
            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'left':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
            break
          case 'right':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
            break
        }

        this.applyPlacement(tp, placement)
        this.$element.trigger('shown')
      }
    }

  , applyPlacement: function(offset, placement){
      var $tip = this.tip()
        , width = $tip[0].offsetWidth
        , height = $tip[0].offsetHeight
        , actualWidth
        , actualHeight
        , delta
        , replace

      $tip
        .offset(offset)
        .addClass(placement)
        .addClass('in')

      actualWidth = $tip[0].offsetWidth
      actualHeight = $tip[0].offsetHeight

      if (placement == 'top' && actualHeight != height) {
        offset.top = offset.top + height - actualHeight
        replace = true
      }

      if (placement == 'bottom' || placement == 'top') {
        delta = 0

        if (offset.left < 0){
          delta = offset.left * -2
          offset.left = 0
          $tip.offset(offset)
          actualWidth = $tip[0].offsetWidth
          actualHeight = $tip[0].offsetHeight
        }

        this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
      } else {
        this.replaceArrow(actualHeight - height, actualHeight, 'top')
      }

      if (replace) $tip.offset(offset)
    }

  , replaceArrow: function(delta, dimension, position){
      this
        .arrow()
        .css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
    }

  , setContent: function () {
      var $tip = this.tip()
        , title = this.getTitle()

      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
      $tip.removeClass('fade in top bottom left right')
    }

  , hide: function () {
      var that = this
        , $tip = this.tip()
        , e = $.Event('hide')

      this.$element.trigger(e)
      if (e.isDefaultPrevented()) return

      $tip.removeClass('in')

      function removeWithAnimation() {
        var timeout = setTimeout(function () {
          $tip.off($.support.transition.end).detach()
        }, 500)

        $tip.one($.support.transition.end, function () {
          clearTimeout(timeout)
          $tip.detach()
        })
      }

      $.support.transition && this.$tip.hasClass('fade') ?
        removeWithAnimation() :
        $tip.detach()

      this.$element.trigger('hidden')

      return this
    }

  , fixTitle: function () {
      var $e = this.$element
      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
        $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
      }
    }

  , hasContent: function () {
      return this.getTitle()
    }

  , getPosition: function () {
      var el = this.$element[0]
      return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
        width: el.offsetWidth
      , height: el.offsetHeight
      }, this.$element.offset())
    }

  , getTitle: function () {
      var title
        , $e = this.$element
        , o = this.options

      title = $e.attr('data-original-title')
        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)

      return title
    }

  , tip: function () {
      return this.$tip = this.$tip || $(this.options.template)
    }

  , arrow: function(){
      return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
    }

  , validate: function () {
      if (!this.$element[0].parentNode) {
        this.hide()
        this.$element = null
        this.options = null
      }
    }

  , enable: function () {
      this.enabled = true
    }

  , disable: function () {
      this.enabled = false
    }

  , toggleEnabled: function () {
      this.enabled = !this.enabled
    }

  , toggle: function (e) {
      var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this
      self.tip().hasClass('in') ? self.hide() : self.show()
    }

  , destroy: function () {
      this.hide().$element.off('.' + this.type).removeData(this.type)
    }

  }

 /* TOOLTIP PLUGIN DEFINITION
  * ========================= */

  var old = $.fn.tooltip

  $.fn.tooltip = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('tooltip')
        , options = typeof option == 'object' && option
      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.tooltip.Constructor = Tooltip

  $.fn.tooltip.defaults = {
    animation: true
  , placement: 'top'
  , selector: false
  , template: '

'
  , trigger: 'hover focus'
  , title: ''
  , delay: 0
  , html: false
  , container: false
  }

 /* TOOLTIP NO CONFLICT
  * =================== */

  $.fn.tooltip.noConflict = function () {
    $.fn.tooltip = old
    return this
  }

}(window.jQuery);
<|endoftext|>


<commit_before>var Fluxxor = require('fluxxor');
var Immutable = require('immutable');
var Cursor = require('immutable/contrib/cursor');

var BATCH_SIZE = 300;
var EMIT_INTERVAL = 300;

var constants = {
  ADD_LOG: 'ADD_LOG',
  ADD_RESOURCE: 'ADD_RESOURCE',
  ADD_ERROR: 'ADD_ERROR',
  SET_RESOURCE_RUNNING: 'SET_RESOURCE_RUNNING',
  SET_RESOURCE_ERRORED: 'SET_RESOURCE_ERRORED',
  TOGGLE_RESOURCE_LOGS: 'TOGGLE_RESOURCE_LOGS',
}

function LogsModel() {
  this.carriageReturned = false;
  this.lines = Immutable.fromJS([[[]]]);
  this.batchCursor = Cursor.from(this.lines, function(newLines) {
    this.lines = newLines;
  }.bind(this));
  this.linesCursor = this.batchCursor.last();
  this.carriage = 0;

  this.addLog = function(line) {
    var sequence = ansiparse(line);

    for (var i = 0; i < sequence.length; i++) {
      if (sequence[i].cr) {
        this.carriage = 0;
      } else if (sequence[i].linebreak) {
        this.pushLine(Immutable.List())
        this.refreshCursor();
        this.carriage = 0;
        this.changed = true;
      } else if (sequence[i].text) {
        var textLen = sequence[i].text.length;
        var carriage = this.carriage;
        var cursor = this.cursor.update(function(line) {
          return line.slice(carriage);
        });
        this.cursor = this.cursor.update(function(line) {
          return line.slice(0, carriage);
        });
        this.pushSequence(sequence[i]);
        this.carriage++;

        cursor.forEach(function(e, i) {
          if(e.text.length >= textLen) {
            e.text = e.text.substr(textLen);
            textLen -= e.text.length;
            this.pushSequence(e);
            return false;
          }
        }, this);

        this.refreshLineCursor();
        this.changed = true;
      }
    };
  };

  this.addError = function(message) {
    this.pushLine(Immutable.List())
    this.refreshCursor();
    this.pushSequence({
      text: message,
      error: true,
    });
    this.refreshLineCursor();
    this.carriageReturned = false;
    this.changed = true;
  };

  this.refreshLineCursor = function() {
    this.linesCursor = this.linesCursor.set(this.linesCursor.count() - 1, this.cursor);
  };

  this.refreshCursor = function() {
    this.cursor = this.linesCursor.last();
  };

  this.pushLine = function(line) {
    if (this.linesCursor.count() >= BATCH_SIZE) {
      this.batchCursor = this.batchCursor.set(this.batchCursor.count() - 1, this.linesCursor);
      this.batchCursor = this.batchCursor.update(function(batches) {
        return batches.push(Immutable.List.of(line));
      });
      this.linesCursor = this.batchCursor.last();
    } else {
      this.linesCursor = this.linesCursor.update(function(lines) {
        return lines.push(line);
      });
    }
  };

  this.pushSequence = function(sequence) {
    this.cursor = this.cursor.update(function(line) {
      return line.push(sequence);
    });
  };

  this.refreshCursor();
  this.changed = false;
}

var LogStore = Fluxxor.createStore({
  initialize: function() {
    this.logs = {};
    this.bindActions(
      constants.ADD_LOG, this.onAddLog,
      constants.ADD_ERROR, this.onAddError
    );
    setInterval(this.emitEvents.bind(this), EMIT_INTERVAL);
  },

  getLogs: function(type) {
    if (this.logs[type] === undefined) {
      this.logs[type] = new LogsModel();
    }
    return this.logs[type];
  },

  onAddLog: function(data) {
    this.getLogs(data.type).addLog(data.line);
  },

  onAddError: function(data) {
    this.getLogs(data.type).addError(data.line);
  },

  emitEvents: function() {
    var shouldEmit = false;

    for (var k in this.logs) {
      if (this.logs.hasOwnProperty(k)) {
        if (this.logs[k].changed) {
          shouldEmit = true;
          break;
        }
      }
    }

    if (shouldEmit) {
      this.emit("change");

      for (var k in this.logs) {
        if (this.logs.hasOwnProperty(k)) {
          this.logs[k].changed = false
        }
      }
    }
  },

  getState: function() {
    var state = {};
    for (var k in this.logs) {
      if (this.logs.hasOwnProperty(k)) {
        state[k] = this.logs[k].lines;
      }
    }
    return Immutable.fromJS(state);
  },
});

var ResourceStore = Fluxxor.createStore({
  initialize: function() {
    this.resources = {};
    this.bindActions(
      constants.ADD_RESOURCE, this.onAddResource,
      constants.SET_RESOURCE_RUNNING, this.onSetResourceRunning,
      constants.SET_RESOURCE_ERRORED, this.onSetResourceErrored,
      constants.TOGGLE_RESOURCE_LOGS, this.onToggleResourceLogs
    );
  },

  addResource: function(type, resource) {
    if (this.resources[type] === undefined) {
      this.resources[type] = Immutable.Map();
    }
    resource.kind = type;
    var newResource = Immutable.fromJS(resource);
    if (this.resources[type].has(resource.name)) {
      newResource = this.resources[type].get(resource.name).merge(newResource);
    }
    this.setResource(type, resource.name, newResource);
    this.emit("change");
    return this.resources[type].get(resource.name);
  },

  updateResource: function(type, name, attributes) {
    attributes.name = name;
    this.addResource(type, attributes);
  },

  setResource: function(type, name, resource) {
    this.resources[type] = this.resources[type].set(name, resource);
  },

  onAddResource: function(data) {
    this.addResource(data.type, data.resource);
  },

  onSetResourceRunning: function(data) {
    this.updateResource(data.type, data.name, { running: data.value });
  },

  onSetResourceErrored: function(data) {
    this.updateResource(data.type, data.name, { errored: data.value });
  },

  onToggleResourceLogs: function(data) {
    var resource = this.resources[data.type].get(data.name);
    this.updateResource(data.type, data.name, { showLogs: !resource.get('showLogs') });
  },

  getState: function() {
    return Immutable.fromJS(this.resources);
  },
});

var actions = {
  addLog: function(type, line) {
    this.dispatch(constants.ADD_LOG, { type: type, line: line });
  },

  addError: function(type, line) {
    this.dispatch(constants.ADD_ERROR, { type: type, line: line });
  },

  addResource: function(type, resource) {
    this.dispatch(constants.ADD_RESOURCE, { type: type, resource: resource });
  },

  setResourceRunning: function(type, name, value) {
    this.dispatch(constants.SET_RESOURCE_RUNNING, { type: type, name: name, value: value });
  },

  setResourceErrored: function(type, name, value) {
    this.dispatch(constants.SET_RESOURCE_ERRORED, { type: type, name: name, value: value });
  },

  toggleResourceLogs: function(type, name) {
    this.dispatch(constants.TOGGLE_RESOURCE_LOGS, { type: type, name: name });
  },
}

var stores = {
  LogStore: new LogStore(),
  ResourceStore: new ResourceStore(),
};

module.exports = new Fluxxor.Flux(stores, actions);
<commit_msg>Add linebreak when parsing output<commit_after>var Fluxxor = require('fluxxor');
var Immutable = require('immutable');
var Cursor = require('immutable/contrib/cursor');

var BATCH_SIZE = 300;
var EMIT_INTERVAL = 300;

var constants = {
  ADD_LOG: 'ADD_LOG',
  ADD_RESOURCE: 'ADD_RESOURCE',
  ADD_ERROR: 'ADD_ERROR',
  SET_RESOURCE_RUNNING: 'SET_RESOURCE_RUNNING',
  SET_RESOURCE_ERRORED: 'SET_RESOURCE_ERRORED',
  TOGGLE_RESOURCE_LOGS: 'TOGGLE_RESOURCE_LOGS',
}

function LogsModel() {
  this.carriageReturned = false;
  this.lines = Immutable.fromJS([[[]]]);
  this.batchCursor = Cursor.from(this.lines, function(newLines) {
    this.lines = newLines;
  }.bind(this));
  this.linesCursor = this.batchCursor.last();
  this.carriage = 0;

  this.addLog = function(line) {
    var sequence = ansiparse(line);

    for (var i = 0; i < sequence.length; i++) {
      if (sequence[i].cr) {
        this.carriage = 0;
      } else if (sequence[i].linebreak) {
        this.pushLine(Immutable.List.of(sequence[i]))
        this.refreshCursor();
        this.carriage = 0;
        this.changed = true;
      } else if (sequence[i].text) {
        var textLen = sequence[i].text.length;
        var carriage = this.carriage;
        var cursor = this.cursor.update(function(line) {
          return line.slice(carriage);
        });
        this.cursor = this.cursor.update(function(line) {
          return line.slice(0, carriage);
        });
        this.pushSequence(sequence[i]);
        this.carriage++;

        cursor.forEach(function(e, i) {
          if(e.text.length >= textLen) {
            e.text = e.text.substr(textLen);
            textLen -= e.text.length;
            this.pushSequence(e);
            return false;
          }
        }, this);

        this.refreshLineCursor();
        this.changed = true;
      }
    };
  };

  this.addError = function(message) {
    this.pushLine(Immutable.List())
    this.refreshCursor();
    this.pushSequence({
      text: message,
      error: true,
    });
    this.refreshLineCursor();
    this.carriageReturned = false;
    this.changed = true;
  };

  this.refreshLineCursor = function() {
    this.linesCursor = this.linesCursor.set(this.linesCursor.count() - 1, this.cursor);
  };

  this.refreshCursor = function() {
    this.cursor = this.linesCursor.last();
  };

  this.pushLine = function(line) {
    if (this.linesCursor.count() >= BATCH_SIZE) {
      this.batchCursor = this.batchCursor.set(this.batchCursor.count() - 1, this.linesCursor);
      this.batchCursor = this.batchCursor.update(function(batches) {
        return batches.push(Immutable.List.of(line));
      });
      this.linesCursor = this.batchCursor.last();
    } else {
      this.linesCursor = this.linesCursor.update(function(lines) {
        return lines.push(line);
      });
    }
  };

  this.pushSequence = function(sequence) {
    this.cursor = this.cursor.update(function(line) {
      return line.push(sequence);
    });
  };

  this.refreshCursor();
  this.changed = false;
}

var LogStore = Fluxxor.createStore({
  initialize: function() {
    this.logs = {};
    this.bindActions(
      constants.ADD_LOG, this.onAddLog,
      constants.ADD_ERROR, this.onAddError
    );
    setInterval(this.emitEvents.bind(this), EMIT_INTERVAL);
  },

  getLogs: function(type) {
    if (this.logs[type] === undefined) {
      this.logs[type] = new LogsModel();
    }
    return this.logs[type];
  },

  onAddLog: function(data) {
    this.getLogs(data.type).addLog(data.line);
  },

  onAddError: function(data) {
    this.getLogs(data.type).addError(data.line);
  },

  emitEvents: function() {
    var shouldEmit = false;

    for (var k in this.logs) {
      if (this.logs.hasOwnProperty(k)) {
        if (this.logs[k].changed) {
          shouldEmit = true;
          break;
        }
      }
    }

    if (shouldEmit) {
      this.emit("change");

      for (var k in this.logs) {
        if (this.logs.hasOwnProperty(k)) {
          this.logs[k].changed = false
        }
      }
    }
  },

  getState: function() {
    var state = {};
    for (var k in this.logs) {
      if (this.logs.hasOwnProperty(k)) {
        state[k] = this.logs[k].lines;
      }
    }
    return Immutable.fromJS(state);
  },
});

var ResourceStore = Fluxxor.createStore({
  initialize: function() {
    this.resources = {};
    this.bindActions(
      constants.ADD_RESOURCE, this.onAddResource,
      constants.SET_RESOURCE_RUNNING, this.onSetResourceRunning,
      constants.SET_RESOURCE_ERRORED, this.onSetResourceErrored,
      constants.TOGGLE_RESOURCE_LOGS, this.onToggleResourceLogs
    );
  },

  addResource: function(type, resource) {
    if (this.resources[type] === undefined) {
      this.resources[type] = Immutable.Map();
    }
    resource.kind = type;
    var newResource = Immutable.fromJS(resource);
    if (this.resources[type].has(resource.name)) {
      newResource = this.resources[type].get(resource.name).merge(newResource);
    }
    this.setResource(type, resource.name, newResource);
    this.emit("change");
    return this.resources[type].get(resource.name);
  },

  updateResource: function(type, name, attributes) {
    attributes.name = name;
    this.addResource(type, attributes);
  },

  setResource: function(type, name, resource) {
    this.resources[type] = this.resources[type].set(name, resource);
  },

  onAddResource: function(data) {
    this.addResource(data.type, data.resource);
  },

  onSetResourceRunning: function(data) {
    this.updateResource(data.type, data.name, { running: data.value });
  },

  onSetResourceErrored: function(data) {
    this.updateResource(data.type, data.name, { errored: data.value });
  },

  onToggleResourceLogs: function(data) {
    var resource = this.resources[data.type].get(data.name);
    this.updateResource(data.type, data.name, { showLogs: !resource.get('showLogs') });
  },

  getState: function() {
    return Immutable.fromJS(this.resources);
  },
});

var actions = {
  addLog: function(type, line) {
    this.dispatch(constants.ADD_LOG, { type: type, line: line });
  },

  addError: function(type, line) {
    this.dispatch(constants.ADD_ERROR, { type: type, line: line });
  },

  addResource: function(type, resource) {
    this.dispatch(constants.ADD_RESOURCE, { type: type, resource: resource });
  },

  setResourceRunning: function(type, name, value) {
    this.dispatch(constants.SET_RESOURCE_RUNNING, { type: type, name: name, value: value });
  },

  setResourceErrored: function(type, name, value) {
    this.dispatch(constants.SET_RESOURCE_ERRORED, { type: type, name: name, value: value });
  },

  toggleResourceLogs: function(type, name) {
    this.dispatch(constants.TOGGLE_RESOURCE_LOGS, { type: type, name: name });
  },
}

var stores = {
  LogStore: new LogStore(),
  ResourceStore: new ResourceStore(),
};

module.exports = new Fluxxor.Flux(stores, actions);
<|endoftext|>


<commit_before>$(document).ready(function() {

  var shiftKeyIsPressed = false;

  var scrollToDiff = function(type) {
    var
      scrollPosition = $(document).scrollTop(),
      nextPos = 0,
      currentPosition = 0,
      margin = 100
      ;
    $(".added, .deleted").each(function() {
        currentPosition = $(this).offset().top;
        if (
            (type == 'bottom' && currentPosition  > (scrollPosition + margin))
            || (type == 'top' && currentPosition  < (scrollPosition + margin))
        ) {
          nextPos = currentPosition;
          return false;
        }
    });
    if (nextPos > 0) {
      var position = nextPos - margin;
      $(document).scrollTop(position);
    }
  };

  var changeFile = function(selector) {
    var location = $(selector).click().first().attr('href');
    if (typeof location != 'undefined') {
      window.location = location;
    }
  };

  $(document)
    .keydown(function(e) {
      if (e.target.type == 'textarea')
      {
        return true;
      }
      var code = e.keyCode || e.which;
      switch (code) {
        case 16: //shift
          shiftKeyIsPressed = true;
          break;
        case 75: //k
          scrollToDiff('top');
          break;
        case 74: //j
          scrollToDiff('bottom');
          break;
        case 72: //h
          changeFile('a.previous');
          break;
        case 76: //l
          changeFile('a.next');
          break;
      }
    })
    .keyup(function(e) {
      var code = e.keyCode || e.which
      if (code == '16') { //shift
        shiftKeyIsPressed = false;
      }
    })
  ;

  $('#window').mousewheel(function(event, delta, deltaX, deltaY) {
      if(shiftKeyIsPressed) {
        event.preventDefault();
        this.scrollLeft -= (delta * 120);
      }
    })
  ;
});
<commit_msg>adds a shortcut to validate/invalidate file<commit_after>$(document).ready(function() {

  var shiftKeyIsPressed = false;

  var scrollToDiff = function(type) {
    var
      scrollPosition = $(document).scrollTop(),
      nextPos = 0,
      currentPosition = 0,
      margin = 100
      ;
    $(".added, .deleted").each(function() {
        currentPosition = $(this).offset().top;
        if (
            (type == 'bottom' && currentPosition  > (scrollPosition + margin))
            || (type == 'top' && currentPosition  < (scrollPosition + margin))
        ) {
          nextPos = currentPosition;
          return false;
        }
    });
    if (nextPos > 0) {
      var position = nextPos - margin;
      $(document).scrollTop(position);
    }
  };

  var changeFile = function(selector) {
    var location = $(selector).click().first().attr('href');
    if (typeof location != 'undefined') {
      window.location = location;
    }
  };

  var changeStatus = function (selector) {
    $(selector).click();
  };

  $(document)
    .keydown(function(e) {
      if (e.target.type == 'textarea')
      {
        return true;
      }
      var code = e.keyCode || e.which;
      switch (code) {
        case 16: //shift
          shiftKeyIsPressed = true;
          break;
        case 75: //k
          scrollToDiff('top');
          break;
        case 74: //j
          scrollToDiff('bottom');
          break;
        case 72: //h
          changeFile('a.previous');
          break;
        case 76: //l
          changeFile('a.next');
          break;
        case 73: //i
          //invalid file
          changeStatus('a.invalidate');
          break;
        case 79: //o
          //valid file
          changeStatus('a.validate');
          break;

      }
    })
    .keyup(function(e) {
      var code = e.keyCode || e.which
      if (code == '16') { //shift
        shiftKeyIsPressed = false;
      }
    })
  ;

  $('#window').mousewheel(function(event, delta, deltaX, deltaY) {
      if(shiftKeyIsPressed) {
        event.preventDefault();
        this.scrollLeft -= (delta * 120);
      }
    })
  ;
});
<|endoftext|>