<commit_before>//orangePeeler by Michael Leonffu
var MongoClient = require('mongodb').MongoClient
//var configDB = require('./../config/database.js')
//ObjectId = require('mongodb').ObjectID

//var juicyCalculator = require('./juicyCalculator')

//orangePeeler can be best described by a metafore..
//juicyCalculator processess oranges into juicyData
//orangePeeler males sure to clean and sort the differnt
//oranges before processing them into juicyData in order to achive best quality juicyData

function teamInfluencePeeler(pickedOranges, peeledOranges){
	//This make sure to find the oranges that are important for calculating OPR; schedule and matchdata
	console.log('[START]-teamInfluencePeeler')

	// {
	// 	teamsScore: [
	// 		{
	// 			teams:[123,123], Team numbers
	// 			score:123, score these teams got
	// 			marginalScore:123 marginal score these teams got
	// 		}
	// 	],
	// 	teamList:[123,123,123,] Team numbers unique list
	// }

	var pickedOrange = pickedOranges[0]
	//If threre are no errors then:

	var peeledOffensiveOranges = {
		labels: pickedOrange.teamsList.sort(),
		juice: [],
		result: []
	}
	var peeledMarginalOranges = {
		labels: pickedOrange.teamsList.sort(),
		juice: [],
		result: []
	}

	var peelerTimer = new Date()

	for (var i = pickedOrange.teamsScore.length - 1; i >= 0; i--) {
		peeledOffensiveOranges.result.push([pickedOrange.teamsScore[i].score])
		peeledOffensiveOranges.juice[i] = []
		for (var j = peeledOffensiveOranges.labels.length - 1; j >= 0; j--) {
			peeledOffensiveOranges.juice[i][j] = pickedOrange.teamsScore[i].teams[0] == peeledOffensiveOranges.labels[j] || pickedOrange.teamsScore[i].teams[1] == peeledOffensiveOranges.labels[j]?1:0
		}
	}
	peeledOffensiveOranges.result.reverse() //It's backwards?

	for (var i = pickedOrange.teamsScore.length - 1; i >= 0; i--) {
		peeledMarginalOranges.result.push([pickedOrange.teamsScore[i].marginalScore])
		peeledMarginalOranges.juice[i] = []
		for (var j = peeledMarginalOranges.labels.length - 1; j >= 0; j--) {
			peeledMarginalOranges.juice[i][j] = pickedOrange.teamsScore[i].teams[0] == peeledMarginalOranges.labels[j] || pickedOrange.teamsScore[i].teams[1] == peeledMarginalOranges.labels[j]?1:0
		}
	}
	peeledMarginalOranges.result.reverse() //It's backwards?

	// returns it as
	// {
	// 	labels:[],
	// 	juice:[
	// 		[],
	// 		[]
	// 	],
	// 	result:[
	// 		[],
	// 		[]
	// 	]
	// }

	console.log('Operation teamInfluencePeeler time(Milliseconds):',new Date(new Date()-peelerTimer).getMilliseconds())
	console.log('[DONE]-teamInfluencePeeler')
	peeledOranges(peeledOffensiveOranges, peeledMarginalOranges)

}

var teamMarginalInfluencePeeler = function(pickedOranges, peeledOranges){
		//This make sure to find the oranges that are important for calculating OPR; schedule and matchdata
	console.log('[START]-teamMarginalInfluencePeeler')

	// {
	// 	teamsScore: [
	// 		{
	// 			teams:[123,123], Team numbers
	// 			marginalScore:123 marginal score these teams got
	// 		}
	// 	],
	// 	teamList:[123,123,123,] Team numbers unique list
	// }

	var pickedOrange = pickedOranges[0]
	//If threre are no errors then:
	var peeledOrange = {
		labels: pickedOrange.teamsList.sort(),
		juice: [],
		result: []
	}

	var peelerTimer = new Date()

	for (var i = pickedOrange.teamsScore.length - 1; i >= 0; i--) {
		peeledOrange.result.push([pickedOrange.teamsScore[i].marginalScore])
		peeledOrange.juice[i] = []
		for (var j = peeledOrange.labels.length - 1; j >= 0; j--) {
			peeledOrange.juice[i][j] = pickedOrange.teamsScore[i].teams[0] == peeledOrange.labels[j] || pickedOrange.teamsScore[i].teams[1] == peeledOrange.labels[j]?1:0
		}
	}
	peeledOrange.result.reverse() //It's backwards?

	// returns it as
	// {
	// 	labels:[],
	// 	juice:[
	// 		[],
	// 		[]
	// 	],
	// 	result:[
	// 		[],
	// 		[]
	// 	]
	// }

	console.log('Operation teamMarginalInfluencePeeler time(Milliseconds):',new Date(new Date()-peelerTimer).getMilliseconds())
	console.log('[DONE]-teamMarginalInfluencePeeler')
	peeledOranges(peeledOrange)
}

module.exports = {
	teamInfluencePeeler: teamInfluencePeeler
}

// To use in another file:
// var orangePeeler = require('./orangePeeler')
// orangePeeler(pickedOranges, peeledOranges)
// Where peeledOranges is the callback function returning a json<commit_msg>Peeler update<commit_after>//orangePeeler by Michael Leonffu
//var MongoClient = require('mongodb').MongoClient
//var configDB = require('./../config/database.js')
//ObjectId = require('mongodb').ObjectID

//var juicyCalculator = require('./juicyCalculator')

//orangePeeler can be best described by a metafore..
//juicyCalculator processess oranges into juicyData
//orangePeeler males sure to clean and sort the differnt
//oranges before processing them into juicyData in order to achive best quality juicyData

function teamInfluencePeeler(pickedOranges, peeledOranges){
	//This make sure to find the oranges that are important for calculating OPR; schedule and matchdata
	console.log('[START]-teamInfluencePeeler')

	// {
	// 	teamsScore: [
	// 		{
	// 			teams:[123,123], Team numbers
	// 			score:123, score these teams got
	// 			marginalScore:123 marginal score these teams got
	// 		}
	// 	],
	// 	teamList:[123,123,123,] Team numbers unique list
	// }

	var pickedOrange = pickedOranges[0]
	//If threre are no errors then:

	var peeledOffensiveOranges = {
		labels: pickedOrange.teamsList.sort(),
		juice: [],
		result: []
	}
	var peeledMarginalOranges = {
		labels: pickedOrange.teamsList.sort(),
		juice: [],
		result: []
	}

	var peelerTimer = new Date()

	for (var i = pickedOrange.teamsScore.length - 1; i >= 0; i--) {
		peeledOffensiveOranges.result.push([pickedOrange.teamsScore[i].score])
		peeledOffensiveOranges.juice[i] = []
		for (var j = peeledOffensiveOranges.labels.length - 1; j >= 0; j--) {
			peeledOffensiveOranges.juice[i][j] = pickedOrange.teamsScore[i].teams[0] == peeledOffensiveOranges.labels[j] || pickedOrange.teamsScore[i].teams[1] == peeledOffensiveOranges.labels[j]?1:0
		}
	}
	peeledOffensiveOranges.result.reverse() //It's backwards?

	for (var i = pickedOrange.teamsScore.length - 1; i >= 0; i--) {
		peeledMarginalOranges.result.push([pickedOrange.teamsScore[i].marginalScore])
		peeledMarginalOranges.juice[i] = []
		for (var j = peeledMarginalOranges.labels.length - 1; j >= 0; j--) {
			peeledMarginalOranges.juice[i][j] = pickedOrange.teamsScore[i].teams[0] == peeledMarginalOranges.labels[j] || pickedOrange.teamsScore[i].teams[1] == peeledMarginalOranges.labels[j]?1:0
		}
	}
	peeledMarginalOranges.result.reverse() //It's backwards?

	// returns it as
	// {
	// 	labels:[],
	// 	juice:[
	// 		[],
	// 		[]
	// 	],
	// 	result:[
	// 		[],
	// 		[]
	// 	]
	// }

	console.log('Operation teamInfluencePeeler time(Milliseconds):',new Date(new Date()-peelerTimer).getMilliseconds())
	console.log('[DONE]-teamInfluencePeeler')
	peeledOranges(peeledOffensiveOranges, peeledMarginalOranges)

}

var teamMarginalInfluencePeeler = function(pickedOranges, peeledOranges){
		//This make sure to find the oranges that are important for calculating OPR; schedule and matchdata
	console.log('[START]-teamMarginalInfluencePeeler')

	// {
	// 	teamsScore: [
	// 		{
	// 			teams:[123,123], Team numbers
	// 			marginalScore:123 marginal score these teams got
	// 		}
	// 	],
	// 	teamList:[123,123,123,] Team numbers unique list
	// }

	var pickedOrange = pickedOranges[0]
	//If threre are no errors then:
	var peeledOrange = {
		labels: pickedOrange.teamsList.sort(),
		juice: [],
		result: []
	}

	var peelerTimer = new Date()

	for (var i = pickedOrange.teamsScore.length - 1; i >= 0; i--) {
		peeledOrange.result.push([pickedOrange.teamsScore[i].marginalScore])
		peeledOrange.juice[i] = []
		for (var j = peeledOrange.labels.length - 1; j >= 0; j--) {
			peeledOrange.juice[i][j] = pickedOrange.teamsScore[i].teams[0] == peeledOrange.labels[j] || pickedOrange.teamsScore[i].teams[1] == peeledOrange.labels[j]?1:0
		}
	}
	peeledOrange.result.reverse() //It's backwards?

	// returns it as
	// {
	// 	labels:[],
	// 	juice:[
	// 		[],
	// 		[]
	// 	],
	// 	result:[
	// 		[],
	// 		[]
	// 	]
	// }

	console.log('Operation teamMarginalInfluencePeeler time(Milliseconds):',new Date(new Date()-peelerTimer).getMilliseconds())
	console.log('[DONE]-teamMarginalInfluencePeeler')
	peeledOranges(peeledOrange)
}

module.exports = {
	teamInfluencePeeler: teamInfluencePeeler
}

// To use in another file:
// var orangePeeler = require('./orangePeeler')
// orangePeeler(pickedOranges, peeledOranges)
// Where peeledOranges is the callback function returning a json<|endoftext|>


<commit_before>app.directive('keosuComments', function(){
	return {
		restrict : 'E',
		scope : {
			objectId: '=objectId',
			objectName: '=objectName',
			enableComments: '=enableComments'
		},
		templateUrl : 'plugins/keosu-comments/templates/default.html',
		controller : ['$scope','$http', function ($scope, $http) {

			$scope.$watch('objectId', function() {
				$scope.myinit();
        	});

			$scope.myinit = function() {
				$http.get('data/globalParam.json').success(function(data){
					$scope.host = data.host;
					$scope.commentListAction();
				});
			}

			$scope.commentListAction = function() {
				$http.get($scope.host+'service/gadget/comment/'+$scope.objectName+'/'+$scope.objectId).success(function(data){
					$scope.comments = data.comments;
					$scope.connect = data.connect;
				});
			};

			$scope.commentAddAction = function() {
				var data = "message="+$scope.messageComment;
				$scope.messageComment = "";
				$http.post($scope.host+'service/gadget/comment/'+$scope.objectName+'/'+$scope.objectId,data).success(function(data){
					$scope.comments = data.comments;
					$scope.connect = data.connect;
				});
			};
		}]
	};
});
<commit_msg>remove the useless request when you post a comment<commit_after>app.directive('keosuComments', function(){
	return {
		restrict : 'E',
		scope : {
			objectId: '=objectId',
			objectName: '=objectName',
			enableComments: '=enableComments'
		},
		templateUrl : 'plugins/keosu-comments/templates/default.html',
		controller : ['$scope','$http', function ($scope, $http) {

			$scope.$watch('objectId', function() {
				$scope.myinit();
        	});

			$scope.myinit = function() {
				$http.get('data/globalParam.json').success(function(data){
					$scope.host = data.host;
					$scope.commentListAction();
				});
			}

			$scope.commentListAction = function() {
				if ($scope.objectId) {
					$http.get($scope.host+'service/gadget/comment/'+$scope.objectName+'/'+$scope.objectId).success(function(data){
						$scope.comments = data.comments;
						$scope.connect = data.connect;
					});
				}
			};

			$scope.commentAddAction = function() {
				var data = "message="+$scope.messageComment;
				$scope.messageComment = "";
				if (data != "message=") {//check if the commentaire is not empty
					$http.post($scope.host+'service/gadget/comment/'+$scope.objectName+'/'+$scope.objectId,data).success(function(data){
						$scope.comments = data.comments;
						$scope.connect = data.connect;
					});
				};
			};
		}]
	};
});
<|endoftext|>


<commit_before>'use strict';

// core
var path = require('path');
// npm
var async = require('async');
var cheerio = require('cheerio');
var mongoose = require('mongoose');
var request = require('request');
// wuw
var utils = require('./wuw_utils');

// how many weeks should we parse?
var weeksToParse = 3;

// mongodb
var mongohost='localhost:27017';
var mongodb=process.env.WUWDB || 'wuw';
var mongoConnection='mongodb://' + mongohost + '/' + mongodb;

// running as module or standalone?
var standalone = !module.parent;
var scriptName = path.basename(module.filename, path.extname(module.filename));

// parsing
var parse = function(html, cb) {
    // create models from our schemas
    var Dish = require('./models/model_dish');

    // init cheerio with our html
    var $ = cheerio.load(html);
    var fullWeek = $('div.print-content div.view div.view-content div.item-list ul').children();

    // parse each week of food
    async.each(fullWeek, function(dayPlan, daycb) {

        var curDate = $(dayPlan).find('span.date-day-numeric').html().trim();
        var curDateArr = curDate.split('.');
        var intDate = curDateArr[1] + '/' + curDateArr[0] + '/' + curDateArr[2];

        var i = 0;
        async.each($(dayPlan).find('td.speiseangebotbody'), function(e, dishcb) {

            // split main dishes from the side dishes & sweets
            if(i !== 6 && i !== 7) {

                // create dish from our Model
                var curDish = new Dish();
                curDish.dishName = $(e).find('span.name').text();
                curDish.shortCat = i;
                curDish.date = Date.parse(intDate);

                var additiveNumber = $(e).find('span.additive_number');

                // get the price
                var prices = $(e).first().contents().filter(function() {
                    return this.type === 'text';
                }).text().trim().split(' / ');

                // if prices exists, split to internal and external
                if(prices.length === 2) {
                    curDish.priceInternal = prices[0].replace(',', '.');
                    curDish.priceExternal = prices[1].replace(',', '.');
                }

                // prepare attributes, allergens & additives
                if(additiveNumber) {
                    $(additiveNumber).each(function(i, e) {
                        // split to single strings/numbers
                        var adds = $(e).html().split(',');
                        // allergens
                        if(i === 0) {
                            adds.forEach(function(add) {
                                curDish.shortAllerg.push(add);
                            });
                        // additives
                        } else if(i === 1) {
                            adds.forEach(function(add) {
                                curDish.shortAdd.push(add);
                            });
                        }
                    });
                }

                // save to database
                curDish.save(dishcb);

            // side dishes & sweets
            // } else if (i === 6 || i === 7) {
            //     console.log($(e));
            } else {
                dishcb();
            }

            i++;
        }, function(){
            // day done
            daycb();
        });

    }, function() {
        // week done
        cb();
    });
};

// get the calendar week
Object.defineProperty(Date.prototype, 'getWeek', {
    value: function() {
        var determinedate = new Date();
        determinedate.setFullYear(this.getFullYear(), this.getMonth(), this.getDate());
        var D = determinedate.getDay();
        if(D === 0) { D = 7; }
        determinedate.setDate(determinedate.getDate() + (4 - D));
        var YN = determinedate.getFullYear();
        var ZBDoCY = Math.floor((determinedate.getTime() - new Date(YN, 0, 1, -6)) / 86400000);
        var WN = 1 + Math.floor(ZBDoCY / 7);
        return WN;
    }
});

// create urls including the calendar week which we want to parse
var createUrls = function() {
    var urls = [];
    for(var i = 0; i < weeksToParse; i++) {
        // get date to parse
        var today = new Date();
        var currentWeek = (today.getWeek() + i) % 53;
        var currentYear = today.getFullYear();
        // assemble datestring & url
        var currWeek = currentYear + '-W' + currentWeek;
        var url = 'https://www.studierendenwerk-stuttgart.de/print/gastronomie/speiseangebot/' + currWeek;
        urls.push(url);
    }
    return urls;
};

var startParser = function() {
    // connect to mongodb (if not already)
    if(mongoose.connection.readyState === 0) {
        mongoose.connect(mongoConnection);
    }

    // create model from our schema (needed for drop)
    var Dish = require('./models/model_dish');

    // create the urls to parse
    var urls = createUrls();

    console.log('[' + (new Date()) + '] ' + scriptName + ': started with { weeksToParse: ' + weeksToParse + ' }');
    // simple progress display if run as standalone
    if (standalone) { process.stdout.write(' '); }

    // drop current collection to get a fresh result
    mongoose.connection.collections.dishes.drop(function(err) {
        if(err) { console.log(err); }

        // parse every url (max. 5 parallel, dont fuck the studentenwerk)
        async.eachLimit(urls, 5, function(url, cb) {
            request(url, function(error, response, html) {
                if(!error) {
                    // parse html with all dishes for choosen date
                    parse(html, function() {
                        // simple progress display if run as standalone
                        if (standalone) { process.stdout.write(' *'); }
                        cb();
                    });
                }
            });
        }, function() {
            // disconnect mongodb if run as standalone
            if (standalone) {
                process.stdout.write('\n');
                mongoose.disconnect();
            }

            console.log('[' + (new Date()) + '] ' + scriptName + ': completed successfully');
        });
    });
};

// immediately start parsing if run as standalone
if (standalone) { startParser(); }

module.exports = { startParser: startParser, parse: parse };
<commit_msg>fix mensa parsing<commit_after>'use strict';

// core
var path = require('path');
// npm
var async = require('async');
var cheerio = require('cheerio');
var mongoose = require('mongoose');
var request = require('request');
// wuw
var utils = require('./wuw_utils');

// how many weeks should we parse?
var weeksToParse = 3;

// mongodb
var mongohost='localhost:27017';
var mongodb=process.env.WUWDB || 'wuw';
var mongoConnection='mongodb://' + mongohost + '/' + mongodb;

// running as module or standalone?
var standalone = !module.parent;
var scriptName = path.basename(module.filename, path.extname(module.filename));

// parsing
var parse = function(html, cb) {
    // create models from our schemas
    var Dish = require('./models/model_dish');

    // init cheerio with our html
    var $ = cheerio.load(html);
    var fullWeek = $('div.print-content div.view div.view-content div.item-list ul').children();

    // parse each week of food
    async.each(fullWeek, function(dayPlan, daycb) {

        var curDate = $(dayPlan).find('span.date-day-numeric').html().trim();
        var curDateArr = curDate.split('.');
        var intDate = curDateArr[1] + '/' + curDateArr[0] + '/' + curDateArr[2];

        var i = 0;
        async.each($(dayPlan).find('td.speiseangebotbody'), function(e, dishcb) {

            // split main dishes from the side dishes & sweets
            if(i !== 6 && i !== 7) {

                // create dish from our Model
                var curDish = new Dish();
                curDish.dishName = $(e).find('span.name').text();
                curDish.shortCat = i;
                curDish.date = Date.parse(intDate);

                var additiveNumber = $(e).find('span.additive_number');

                // get the price
                var prices = $(e).first().contents().filter(function() {
                    return this.type === 'text';
                }).text().trim().split('€: ');
                prices = prices[1].trim();
                prices = prices.split(" / ");

                // if prices exists, split to internal and external
                if (prices.length === 2) {
                    curDish.priceInternal = prices[0].replace(',', '.');
                    curDish.priceExternal = prices[1].replace(',', '.');
                }

                // prepare attributes, allergens & additives
                if(additiveNumber) {
                    $(additiveNumber).each(function(i, e) {
                        // split to single strings/numbers
                        var adds = $(e).html().split(',');
                        // allergens
                        if(i === 0) {
                            adds.forEach(function(add) {
                                curDish.shortAllerg.push(add);
                            });
                        // additives
                        } else if(i === 1) {
                            adds.forEach(function(add) {
                                curDish.shortAdd.push(add);
                            });
                        }
                    });
                }

                // save to database
                curDish.save(function (err, dish, numAffected) {
                    if (err) {
                        console.log(err);
                    }
                    dishcb();
                });

            // side dishes & sweets
            // } else if (i === 6 || i === 7) {
            //     console.log($(e));
            } else {
                dishcb();
            }

            i++;
        }, function(){
            // day done
            daycb();
        });

    }, function() {
        // week done
        cb();
    });
};

// get the calendar week
Object.defineProperty(Date.prototype, 'getWeek', {
    value: function() {
        var determinedate = new Date();
        determinedate.setFullYear(this.getFullYear(), this.getMonth(), this.getDate());
        var D = determinedate.getDay();
        if(D === 0) { D = 7; }
        determinedate.setDate(determinedate.getDate() + (4 - D));
        var YN = determinedate.getFullYear();
        var ZBDoCY = Math.floor((determinedate.getTime() - new Date(YN, 0, 1, -6)) / 86400000);
        var WN = 1 + Math.floor(ZBDoCY / 7);
        return WN;
    }
});

// create urls including the calendar week which we want to parse
var createUrls = function() {
    var urls = [];
    for(var i = 0; i < weeksToParse; i++) {
        // get date to parse
        var today = new Date();
        var currentWeek = (today.getWeek() + i) % 53;
        var currentYear = today.getFullYear();
        // assemble datestring & url
        var currWeek = currentYear + '-W' + currentWeek;
        var url = 'https://www.studierendenwerk-stuttgart.de/print/gastronomie/speiseangebot/' + currWeek;
        urls.push(url);
    }
    return urls;
};

var startParser = function() {
    // connect to mongodb (if not already)
    if(mongoose.connection.readyState === 0) {
        mongoose.connect(mongoConnection);
    }

    // create model from our schema (needed for drop)
    var Dish = require('./models/model_dish');

    // create the urls to parse
    var urls = createUrls();

    console.log('[' + (new Date()) + '] ' + scriptName + ': started with { weeksToParse: ' + weeksToParse + ' }');
    // simple progress display if run as standalone
    if (standalone) { process.stdout.write(' '); }

    // drop current collection to get a fresh result
    mongoose.connection.collections.dishes.drop(function(err) {
        if(err) { console.log(err); }

        // parse every url (max. 5 parallel, dont fuck the studentenwerk)
        async.eachLimit(urls, 5, function(url, cb) {
            request(url, function(error, response, html) {
                if(!error) {
                    // parse html with all dishes for choosen date
                    parse(html, function() {
                        // simple progress display if run as standalone
                        if (standalone) { process.stdout.write(' *'); }
                        cb();
                    });
                }
            });
        }, function() {
            // disconnect mongodb if run as standalone
            if (standalone) {
                process.stdout.write('\n');
                mongoose.disconnect();
            }

            console.log('[' + (new Date()) + '] ' + scriptName + ': completed successfully');
        });
    });
};

// immediately start parsing if run as standalone
if (standalone) { startParser(); }

module.exports = { startParser: startParser, parse: parse };
<|endoftext|>


<commit_before>import {Router} from 'express'
import models from '../models';

export default () => {
	let app = Router({mergeParams: true})

	app.get('/new', (req, res) => {
		models.Serfs.findAll().then((serfs) => {
			res.render('tasks/new', {serfs})
		})
	})

	app.get('/:id', (req, res) => {
		models.Task.find(req.params.id).then((task) => {
			res.render('tasks/show', {task})
		})
	})
	app.post('/', (req, res) => {
		// models.Task.create(req.body.task).then((task) => {
			console.log(req.params)
			models.User.find(req.params.userId).then((user) => {
				console.log(user)
				user.createTask(req.body).then((task) => {
					res.redirect('/users/' + req.params.userId + "/tasks/" + task.id);
				})
			})
		// })
	})
	return app
}<commit_msg>Cleanup console logs<commit_after>import {Router} from 'express'
import models from '../models';

export default () => {
	let app = Router({mergeParams: true})

	app.get('/new', (req, res) => {
		models.Serfs.findAll().then((serfs) => {
			res.render('tasks/new', {serfs})
		})
	})

	app.get('/:id', (req, res) => {
		models.Task.find(req.params.id).then((task) => {
			res.render('tasks/show', {task})
		})
	})
	app.post('/', (req, res) => {
		// models.Task.create(req.body.task).then((task) => {
			models.User.find(req.params.userId).then((user) => {
				console.log(user)
				user.createTask(req.body).then((task) => {
					res.redirect('/users/' + req.params.userId + "/tasks/" + task.id);
				})
			})
		// })
	})
	return app
}<|endoftext|>


<commit_before>// Use the hidden-source-map option when you don't want the source maps to be
// publicly available on the servers, only to the error reporting
const withSourceMaps = require('@zeit/next-source-maps')()

// Use the SentryWebpack plugin to upload the source maps during build step
const SentryWebpackPlugin = require('@sentry/webpack-plugin')
const {
  NEXT_PUBLIC_SENTRY_DSN: SENTRY_DSN,
  SENTRY_ORG,
  SENTRY_PROJECT,
  SENTRY_AUTH_TOKEN,
  NODE_ENV,
} = process.env

process.env.SENTRY_DSN = SENTRY_DSN

module.exports = withSourceMaps({
  webpack: (config, options) => {
    // In `pages/_app.js`, Sentry is imported from @sentry/node. While
    // @sentry/browser will run in a Node.js environment, @sentry/node will use
    // Node.js-only APIs to catch even more unhandled exceptions.
    //
    // This works well when Next.js is SSRing your page on a server with
    // Node.js, but it is not what we want when your client-side bundle is being
    // executed by a browser.
    //
    // Luckily, Next.js will call this webpack function twice, once for the
    // server and once for the client. Read more:
    // https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config
    //
    // So ask Webpack to replace @sentry/node imports with @sentry/browser when
    // building the browser's bundle
    if (!options.isServer) {
      config.resolve.alias['@sentry/node'] = '@sentry/browser'
    }

    // When all the Sentry configuration env variables are available/configured
    // The Sentry webpack plugin gets pushed to the webpack plugins to build
    // and upload the source maps to sentry.
    // This is an alternative to manually uploading the source maps
    // Note: This is disabled in development mode.
    if (
      SENTRY_DSN &&
      SENTRY_ORG &&
      SENTRY_PROJECT &&
      SENTRY_AUTH_TOKEN &&
      NODE_ENV === 'production'
    ) {
      config.plugins.push(
        new SentryWebpackPlugin({
          include: '.next',
          ignore: ['node_modules'],
          urlPrefix: '~/_next',
          release: options.buildId,
        })
      )
    }

    return config
  },
})
<commit_msg>Correct order of packages in Sentry example explanation (#15334)<commit_after>// Use the hidden-source-map option when you don't want the source maps to be
// publicly available on the servers, only to the error reporting
const withSourceMaps = require('@zeit/next-source-maps')()

// Use the SentryWebpack plugin to upload the source maps during build step
const SentryWebpackPlugin = require('@sentry/webpack-plugin')
const {
  NEXT_PUBLIC_SENTRY_DSN: SENTRY_DSN,
  SENTRY_ORG,
  SENTRY_PROJECT,
  SENTRY_AUTH_TOKEN,
  NODE_ENV,
} = process.env

process.env.SENTRY_DSN = SENTRY_DSN

module.exports = withSourceMaps({
  webpack: (config, options) => {
    // In `pages/_app.js`, Sentry is imported from @sentry/browser. While
    // @sentry/node will run in a Node.js environment. @sentry/node will use
    // Node.js-only APIs to catch even more unhandled exceptions.
    //
    // This works well when Next.js is SSRing your page on a server with
    // Node.js, but it is not what we want when your client-side bundle is being
    // executed by a browser.
    //
    // Luckily, Next.js will call this webpack function twice, once for the
    // server and once for the client. Read more:
    // https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config
    //
    // So ask Webpack to replace @sentry/node imports with @sentry/browser when
    // building the browser's bundle
    if (!options.isServer) {
      config.resolve.alias['@sentry/node'] = '@sentry/browser'
    }

    // When all the Sentry configuration env variables are available/configured
    // The Sentry webpack plugin gets pushed to the webpack plugins to build
    // and upload the source maps to sentry.
    // This is an alternative to manually uploading the source maps
    // Note: This is disabled in development mode.
    if (
      SENTRY_DSN &&
      SENTRY_ORG &&
      SENTRY_PROJECT &&
      SENTRY_AUTH_TOKEN &&
      NODE_ENV === 'production'
    ) {
      config.plugins.push(
        new SentryWebpackPlugin({
          include: '.next',
          ignore: ['node_modules'],
          urlPrefix: '~/_next',
          release: options.buildId,
        })
      )
    }

    return config
  },
})
<|endoftext|>


<commit_before>"use strict";

var weap = function(resource) {
    var d = resource.data;
    var out = {};
    out.name = resource.name;
    out.id = resource.id;

    out.reload = d.getInt16(0);
    out.duration = d.getInt16(2);
    out.armorDamage = d.getInt16(4);
    out.shieldDamage = d.getInt16(6);

    out.guidanceN = d.getInt16(8);

    switch (out.guidanceN) {
    case -1:
	out.guidance = 'unguided';
	break;
    case 0:
	out.guidance = 'beam';
        break;
    case 1:
	out.guidance = 'guided';
        break;
    case 3:
	out.guidance = 'beam turret';
        break;
    case 4:
	out.guidance = 'turret';
        break;
    case 5:
	out.guidance = 'freefall bomb';
        break;
    case 6:
	out.guidance = 'rocket';
        break;
    case 7:
	out.guidance = 'front quadrant';
        break;
    case 8:
	out.guidance = 'rear quadrant';
        break;
    case 9:
	out.guidance = 'point defence';
        break;
    case 10:
	out.guidance = 'point defence beam';
        break;
    case 99:
	out.guidance = 'bay';
        break;
    }

    var conditionalOffset = function (n,off){
	if (n >=0){
	    return n+off;
	}else{
	    return n;
	}
    }

    out.speed = d.getInt16(10);

    out.ammoType = conditionalOffset(d.getInt16(12),128);

    out.graphic = conditionalOffset(d.getInt16(14),3000);

    out.accuracy = d.getInt16(16);
    out.firesAtFixedAngle = out.accuracy < 0;
    out.accuracy = Math.abs(out.accuracy);

    out.sound = conditionalOffset(d.getInt16(18),200);

    out.impact = d.getInt16(20);

    out.explosion = conditionalOffset(d.getInt16(22),128);
    out.explosion128sparks = out.explosion >= 1128;
    if (out.explosion >= 1128){
	out.explosion -= 1000;
    }

    out.proxRadius = d.getInt16(24);

    out.blastRadius = d.getInt16(26);

    out.flags = d.getUint16(28);
    //flags
    out.spinShots = (out.flags & 0x1)>0;
    if (out.flags & 0x2){
        out.fireGroup = "secondary";
    }else{
	out.fireGroup = "primary";
    }
    out.startSpinningOnFirstFrame = (out.flags & 0x4)>0;
    out.dontFireAtFastShips = (out.flags & 0x8)>0;
    out.loopSound = (out.flags & 0x10)>0;
    out.passThroughShields = (out.flags & 0x20)>0;
    out.fireSimultaneously = (out.flags & 0x40)>0;
    out.vulnerableToPD = (out.flags & 0x80)==0;//NB: inverted
    out.hitsFiringShip = (out.flags & 0x100)==0;//NB: inverted
    out.smallCicnSmoke = (out.flags & 0x200)>0;
    out.bigCicnSmoke = (out.flags & 0x400)>0;
    out.persistentCicnSmoke = (out.flags & 0x800)>0;

    out.turretBlindSpots = {};
    out.turretBlindSpots.front = (out.flags & 0x1000)>0;
    out.turretBlindSpots.side = (out.flags & 0x2000)>0;
    out.turretBlindSpots.back = (out.flags & 0x4000)>0;
    out.flak = (out.flags & 0x8000)>0;
    //endflags

    out.guidedFlags = d.getInt16(30);
    //seeker
    out.passOverAsteroids = (out.guidedFlags & 0x1)>0;
    out.decoyedByAsteroids = (out.guidedFlags & 0x2)>0;
    out.confusedByInterference = (out.guidedFlags & 0x8)>0;
    out.turnsAwayIfJammed = (out.guidedFlags & 0x10)>0;
    out.cantFireWhileIonized = (out.guidedFlags & 0x20)>0;
    out.loseLockIfNotAhead = (out.guidedFlags & 0x4000)>0;
    out.attackParentIfJammed = (out.guidedFlags & 0x8000)>0;
    //endseeker

    out.cicnSmoke = conditionalOffset(d.getInt16(32)*8,1000);
    if (out.cicnSmoke >= 0){
	var tmp = [];
	for (var i = out.cicnSmoke; i < out.cicnSmoke+8; i++) {
	    tmp.push(i);
	}
	out.cicnSmoke = tmp;
    }else{
	out.cicnSmoke = false;
    }

    out.decay = d.getInt16(34);

    var getColor32 = function(n) {
/*	c =+ (255-d.getInt8(n))<<24;//a inverted 'cause nova has it as 0
	c =+ d.getInt8(n+1)<<16;//r
	c =+ d.getInt8(n+2)<<8;//g
	c =+ d.getInt8(n+3);//b*/
	var aCorrection = 0xff000000-d.getInt8(n)*0x02000000;//times 2 bc newa - a = max - 2a when newa = max - a
	return d.getUint32(n) + aCorrection; // fix alpha
    }

    out.trailParticles = {};
    out.trailParticles.number = d.getInt16(36);
    out.trailParticles.velocity = d.getInt16(38);
    out.trailParticles.lifeMin = d.getInt16(40);
    out.trailParticles.lifeMax = d.getInt16(42);
    out.trailParticles.color = getColor32(44);

    out.beamLength = d.getInt16(48);
    out.beamWidth = d.getInt16(50);
    out.spinRate = d.getInt16(50);
    out.coronaFalloff = d.getInt16(52);
    out.beamColor = getColor32(54);
    out.coronaColor = getColor32(58);
    out.beamLightningDensity = d.getInt16(110);
    out.beamLightningAmplitude = d.getInt16(112);

    out.proxSafety = d.getInt16(70);

    out.flags2 = d.getInt16(72);
    //flags2
    out.spinBeforeProxSafety = (out.flags2 & 0x1)==0;// NB: inverted
    out.spinStopOnLastFrame = (out.flags2 & 0x2)>0;
    out.proxIgnoreAsteroids = (out.flags2 & 0x4)>0;
    out.proxHitAll = (out.flags2 & 0x8)>0 || (out.guidance != "guided");

    out.submunitions = [];
    if (d.getInt16(64) >=0) {
	out.submunitions[0] = {};
	out.submunitions[0].count = d.getInt16(62);
	out.submunitions[0].type = d.getInt16(64);
	out.submunitions[0].theta = d.getInt16(66);
	out.submunitions[0].limit = d.getInt16(68);
	out.submunitions[0].fireAtNearest = (out.flags2 & 0x10)>0;
	out.submunitions[0].subIfExpire = (out.flags2 & 0x20)==0;// NB: inverted
    }

    out.showAmmo = (out.flags2 & 0x40)==0;// NB: inverted
    out.fireOnlyIfKeyCarried = (out.flags2 & 0x80)>0;
    out.npcCantUse = (out.flags2 & 0x100)>0;
    out.useFiringAnimation = (out.flags2 & 0x200)>0;
    out.planetType = (out.flags2 & 0x400)>0;
    out.hideIfNoAmmo = (out.flags2 & 0x800)>0;
    out.disableOnly = (out.flags2 & 0x1000)>0;
    out.beamUnderShip = (out.flags2 & 0x2000)>0;
    out.fireWhileCloaked = (out.flags2 & 0x4000)>0;
    out.asteroidMiner = (out.flags2 & 0x8000)>0;
    //endflags2

    out.ionization = d.getInt16(74);

    out.hitParticles = {};
    out.hitParticles.number = d.getInt16(76);
    out.hitParticles.life = d.getInt16(78);
    out.hitParticles.velocity = d.getInt16(80);
    out.hitParticles.color = getColor32(82);

    out.recoil = d.getInt16(86);

    out.exitTypeN = d.getInt16(88);
    var exitLoc = '';
    switch (out.exitTypeN) {
    case -1:
	exitLoc = "center";
	break;
    case 0:
	exitLoc = "gun";
	break;
    case 1:
	exitLoc = "turret";
	break;
    case 2:
	exitLoc = "guided";
	break;
    case 3:
	exitLoc = "beam";
	break;
    }

    out.exitType = exitLoc;

    out.burstCount = d.getInt16(90);

    out.burstReload = d.getInt16(92);

    out.jam = {};
    out.jamVuln = [];
    out.jam.IR = d.getInt16(94);
    out.jam.radar = d.getInt16(96);
    out.jam.ethricWake = d.getInt16(98);
    out.jam.gravametric = d.getInt16(100);

    out.jamVuln[0] = out.jam.IR;
    out.jamVuln[1] = out.jam.radar;
    out.jamVuln[2] = out.jam.ethricWake;
    out.jamVuln[3] = out.jam.gravametric;

    out.flags3 = d.getInt16(102);
    //flags3
    out.oneAmmoPerBurst = (out.flags3 & 0x1)>0;
    out.translucent = (out.flags3 & 0x2)>0;
    out.cantFireUntilShotExpires = (out.flags3 & 0x4)>0;
    out.firesFromClosestToTarget = (out.flags3 & 0x10)>0;
    out.exclusive = (out.flags3 & 0x20)>0;
    //endflags3

    out.durability = d.getInt16(104);

    out.turnRate = d.getInt16(106);

    out.maxAmmo = d.getInt16(108);

    //lightning density and amplitude take 110 and 112

    out.ionizeColor = getColor32(114);

    out.count = d.getInt16(118);

    out.recoil = d.getInt16(120);

    return out;
};

module.exports = weap;
<commit_msg>weap parser is done<commit_after>"use strict";

var weap = function(resource) {
    var d = resource.data;
    var out = {};
    out.name = resource.name;
    out.id = resource.id;

    out.reload = d.getInt16(0);
    out.duration = d.getInt16(2);
    out.armorDamage = d.getInt16(4);
    out.shieldDamage = d.getInt16(6);

    out.guidanceN = d.getInt16(8);

    switch (out.guidanceN) {
    case -1:
	out.guidance = 'unguided';
	break;
    case 0:
	out.guidance = 'beam';
        break;
    case 1:
	out.guidance = 'guided';
        break;
    case 3:
	out.guidance = 'beam turret';
        break;
    case 4:
	out.guidance = 'turret';
        break;
    case 5:
	out.guidance = 'freefall bomb';
        break;
    case 6:
	out.guidance = 'rocket';
        break;
    case 7:
	out.guidance = 'front quadrant';
        break;
    case 8:
	out.guidance = 'rear quadrant';
        break;
    case 9:
	out.guidance = 'point defence';
        break;
    case 10:
	out.guidance = 'point defence beam';
        break;
    case 99:
	out.guidance = 'bay';
        break;
    }

    var conditionalOffset = function (n,off){
	if (n >=0){
	    return n+off;
	}else{
	    return n;
	}
    }

    out.speed = d.getInt16(10);

    out.ammoType = conditionalOffset(d.getInt16(12),128);

    out.graphic = conditionalOffset(d.getInt16(14),3000);

    out.accuracy = d.getInt16(16);
    out.firesAtFixedAngle = out.accuracy < 0;
    out.accuracy = Math.abs(out.accuracy);

    out.sound = conditionalOffset(d.getInt16(18),200);

    out.impact = d.getInt16(20);

    out.explosion = conditionalOffset(d.getInt16(22),128);
    out.explosion128sparks = out.explosion >= 1128;
    if (out.explosion >= 1128){
	out.explosion -= 1000;
    }

    out.proxRadius = d.getInt16(24);

    out.blastRadius = d.getInt16(26);

    out.flags = d.getUint16(28);
    //flags
    out.spinShots = (out.flags & 0x1)>0;
    if (out.flags & 0x2){
        out.fireGroup = "secondary";
    }else{
	out.fireGroup = "primary";
    }
    out.startSpinningOnFirstFrame = (out.flags & 0x4)>0;
    out.dontFireAtFastShips = (out.flags & 0x8)>0;
    out.loopSound = (out.flags & 0x10)>0;
    out.passThroughShields = (out.flags & 0x20)>0;
    out.fireSimultaneously = (out.flags & 0x40)>0;
    out.vulnerableToPD = (out.flags & 0x80)==0;//NB: inverted
    out.hitsFiringShip = (out.flags & 0x100)==0;//NB: inverted
    out.smallCicnSmoke = (out.flags & 0x200)>0;
    out.bigCicnSmoke = (out.flags & 0x400)>0;
    out.persistentCicnSmoke = (out.flags & 0x800)>0;

    out.turretBlindSpots = {};
    out.turretBlindSpots.front = (out.flags & 0x1000)>0;
    out.turretBlindSpots.side = (out.flags & 0x2000)>0;
    out.turretBlindSpots.back = (out.flags & 0x4000)>0;
    out.flak = (out.flags & 0x8000)>0;
    //endflags

    out.guidedFlags = d.getInt16(30);
    //seeker
    out.passOverAsteroids = (out.guidedFlags & 0x1)>0;
    out.decoyedByAsteroids = (out.guidedFlags & 0x2)>0;
    out.confusedByInterference = (out.guidedFlags & 0x8)>0;
    out.turnsAwayIfJammed = (out.guidedFlags & 0x10)>0;
    out.cantFireWhileIonized = (out.guidedFlags & 0x20)>0;
    out.loseLockIfNotAhead = (out.guidedFlags & 0x4000)>0;
    out.attackParentIfJammed = (out.guidedFlags & 0x8000)>0;
    //endseeker

    out.cicnSmoke = conditionalOffset(d.getInt16(32)*8,1000);
    if (out.cicnSmoke >= 0){
	var tmp = [];
	for (var i = out.cicnSmoke; i < out.cicnSmoke+8; i++) {
	    tmp.push(i);
	}
	out.cicnSmoke = tmp;
    }else{
	out.cicnSmoke = false;
    }

    out.decay = d.getInt16(34);

    var getColor32 = function(n) {
/*	c =+ (255-d.getInt8(n))<<24;//a inverted 'cause nova has it as 0
	c =+ d.getInt8(n+1)<<16;//r
	c =+ d.getInt8(n+2)<<8;//g
	c =+ d.getInt8(n+3);//b*/
	var aCorrection = 0xff000000-d.getInt8(n)*0x02000000;//times 2 bc newa - a = max - 2a when newa = max - a
	return d.getUint32(n) + aCorrection; // fix alpha
    }

    out.trailParticles = {};
    out.trailParticles.number = d.getInt16(36);
    out.trailParticles.velocity = d.getInt16(38);
    out.trailParticles.lifeMin = d.getInt16(40);
    out.trailParticles.lifeMax = d.getInt16(42);
    out.trailParticles.color = getColor32(44);

    out.beamLength = d.getInt16(48);
    out.beamWidth = d.getInt16(50);
    out.spinRate = d.getInt16(50);
    out.coronaFalloff = d.getInt16(52);
    out.beamColor = getColor32(54);
    out.coronaColor = getColor32(58);
    out.lightningDensity = d.getInt16(110);
    out.lightningAmplitude = d.getInt16(112);

    out.proxSafety = d.getInt16(70);

    out.flags2 = d.getInt16(72);
    //flags2
    out.spinBeforeProxSafety = (out.flags2 & 0x1)==0;// NB: inverted
    out.spinStopOnLastFrame = (out.flags2 & 0x2)>0;
    out.proxIgnoreAsteroids = (out.flags2 & 0x4)>0;
    out.proxHitAll = (out.flags2 & 0x8)>0 || (out.guidance != "guided");

    out.submunitions = [];
    if (d.getInt16(64) >=0) {
	out.submunitions[0] = {};
	out.submunitions[0].count = d.getInt16(62);
	out.submunitions[0].type = d.getInt16(64);
	out.submunitions[0].theta = d.getInt16(66);
	out.submunitions[0].limit = d.getInt16(68);
	out.submunitions[0].fireAtNearest = (out.flags2 & 0x10)>0;
	out.submunitions[0].subIfExpire = (out.flags2 & 0x20)==0;// NB: inverted
    }

    out.showAmmo = (out.flags2 & 0x40)==0;// NB: inverted
    out.fireOnlyIfKeyCarried = (out.flags2 & 0x80)>0;
    out.npcCantUse = (out.flags2 & 0x100)>0;
    out.useFiringAnimation = (out.flags2 & 0x200)>0;
    out.planetType = (out.flags2 & 0x400)>0;
    out.hideIfNoAmmo = (out.flags2 & 0x800)>0;
    out.disableOnly = (out.flags2 & 0x1000)>0;
    out.beamUnderShip = (out.flags2 & 0x2000)>0;
    out.fireWhileCloaked = (out.flags2 & 0x4000)>0;
    out.asteroidMiner = (out.flags2 & 0x8000)>0;
    //endflags2

    out.ionization = d.getInt16(74);

    out.hitParticles = {};
    out.hitParticles.number = d.getInt16(76);
    out.hitParticles.life = d.getInt16(78);
    out.hitParticles.velocity = d.getInt16(80);
    out.hitParticles.color = getColor32(82);

    out.recoil = d.getInt16(86);
    if (out.recoil == -1)
	out.recoil = 0;

    out.exitTypeN = d.getInt16(88);
    var exitLoc = '';
    switch (out.exitTypeN) {
    case -1:
	exitLoc = "center";
	break;
    case 0:
	exitLoc = "gun";
	break;
    case 1:
	exitLoc = "turret";
	break;
    case 2:
	exitLoc = "guided";
	break;
    case 3:
	exitLoc = "beam";
	break;
    }

    out.exitType = exitLoc;

    out.burstCount = d.getInt16(90);

    out.burstReload = d.getInt16(92);

    out.jam = {};
    out.jamVuln = [];
    out.jam.IR = d.getInt16(94);
    out.jam.radar = d.getInt16(96);
    out.jam.ethricWake = d.getInt16(98);
    out.jam.gravametric = d.getInt16(100);

    out.jamVuln[0] = out.jam.IR;
    out.jamVuln[1] = out.jam.radar;
    out.jamVuln[2] = out.jam.ethricWake;
    out.jamVuln[3] = out.jam.gravametric;

    out.flags3 = d.getInt16(102);
    //flags3
    out.oneAmmoPerBurst = (out.flags3 & 0x1)>0;
    out.translucent = (out.flags3 & 0x2)>0;
    out.cantFireUntilShotExpires = (out.flags3 & 0x4)>0;
    out.firesFromClosestToTarget = (out.flags3 & 0x10)>0;
    out.exclusive = (out.flags3 & 0x20)>0;
    //endflags3

    out.durability = d.getInt16(104);

    out.turnRate = d.getInt16(106);

    out.maxAmmo = d.getInt16(108);

    //lightning density and amplitude take 110 and 112

    out.ionizeColor = getColor32(114);

    out.count = d.getInt16(118);

    return out;
};

module.exports = weap;
<|endoftext|>


<commit_before>const got = require('got');

const db = require('../db.js');

// Get trips.
async function getTrips(req, res) {

	const id = req.query['id'];

	try {

		const trips = await db.query(`
			SELECT TIME_TO_SEC(time) AS time, short_name, long_name, wheelchair, route.type, route.region, trip_id FROM stops AS stop
				JOIN stop_times ON stop_id = id
				JOIN trips AS trip ON trip.id = trip_id
				JOIN routes AS route ON route.id = route_id
			WHERE
				stop.id = ?
				AND time BETWEEN CURTIME() AND ADDTIME(CURTIME(), '01:00:00')
				AND service_id IN (
					SELECT service_id FROM services
					WHERE
						CURDATE() BETWEEN start AND end
						AND SUBSTR(days, WEEKDAY(CURDATE()) + 1, 1) = '1'
						AND service_id NOT IN (
							SELECT service_id FROM service_Exceptions WHERE type = 0 AND date = CURDATE()
						)
					UNION
						SELECT service_id FROM service_exceptions WHERE type = 1 AND date = CURDATE()
				)
			ORDER BY time
		`, [ id ]);

		res.send(trips);

	} catch (ex) {
		res.code(500).send(ex);
	}

}

module.exports = (fastify, opts, next) => {
	fastify.get('/trips', getTrips);
	next();
};
<commit_msg>Change returned trip fields (api)<commit_after>const got = require('got');

const db = require('../db.js');

// Get trips.
async function getTrips(req, res) {

	const id = req.query['id'];

	try {

		const trips = await db.query(`
			SELECT TIME_TO_SEC(time) AS time, route.name, terminus, wheelchair, route.type, route.region FROM stops AS stop
				JOIN stop_times ON stop_id = id
				JOIN trips AS trip ON trip.id = trip_id
				JOIN routes AS route ON route.id = route_id
			WHERE
				stop.id = ?
				AND time BETWEEN CURTIME() AND ADDTIME(CURTIME(), '01:00:00')
				AND service_id IN (
					SELECT service_id FROM services
					WHERE
						CURDATE() BETWEEN start AND end
						AND SUBSTR(days, WEEKDAY(CURDATE()) + 1, 1) = '1'
						AND service_id NOT IN (
							SELECT service_id FROM service_Exceptions WHERE type = 0 AND date = CURDATE()
						)
					UNION
						SELECT service_id FROM service_exceptions WHERE type = 1 AND date = CURDATE()
				)
			ORDER BY time
		`, [ id ]);

		const data = (await got(`https://transport.tallinn.ee/siri-stop-departures.php?stopid=${id}`)).body;

		console.log(data);

		res.send(trips);

	} catch (ex) {
		res.code(500).send(ex);
	}

}

module.exports = (fastify, opts, next) => {
	fastify.get('/trips', getTrips);
	next();
};
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import Loader from 'react-loader';
import StickyAlert from '../utils/StickyAlert';
import AudioForm from '../forms/Audio';

let stickyContainer;

const Audio = ({ t, loaded, stickyStyle, stickyContent, ...rest }) => (

 stickyContainer = el}>

{t('Audio')}

      {t('Cette page permet de gérer la partie audio de recalbox.')}

    <StickyAlert bsStyle={stickyStyle} container={stickyContainer}>
      {stickyContent}
    </StickyAlert>

    <Loader loaded={loaded}>
      <AudioForm {...rest} />
    </Loader>

);

Audio.propTypes = {
  t: PropTypes.func.isRequired,
  loaded: PropTypes.bool.isRequired,
  saving: PropTypes.bool.isRequired,
  stickyStyle: PropTypes.string,
  stickyContent: PropTypes.string,
};

export default translate()(Audio);
<commit_msg>[Client] Remove useless PropType<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import Loader from 'react-loader';
import StickyAlert from '../utils/StickyAlert';
import AudioForm from '../forms/Audio';

let stickyContainer;

const Audio = ({ t, loaded, stickyStyle, stickyContent, ...rest }) => (

 stickyContainer = el}>

{t('Audio')}

      {t('Cette page permet de gérer la partie audio de recalbox.')}

    <StickyAlert bsStyle={stickyStyle} container={stickyContainer}>
      {stickyContent}
    </StickyAlert>

    <Loader loaded={loaded}>
      <AudioForm {...rest} />
    </Loader>

);

Audio.propTypes = {
  t: PropTypes.func.isRequired,
  loaded: PropTypes.bool.isRequired,
  stickyStyle: PropTypes.string,
  stickyContent: PropTypes.string,
};

export default translate()(Audio);
<|endoftext|>


<commit_before>/**
 * Created by petermares on 14/03/2016.
 */

module.exports = ComboBoostPowerup;

function ComboBoostPowerup(config) {
    this.comboThreshold = config.comboThreshold;
    this.buyOnce = config.comboThreshold;

    this.onTick = function(clickEngine) {
        clickEngine.
    }
}<commit_msg>Added the comboboost powerup<commit_after>/**
 * Created by petermares on 14/03/2016.
 */

module.exports = ComboBoostPowerup;

function ComboBoostPowerup(config) {
    this.comboThreshold = config.comboThreshold;
    this.buyOnce = config.comboThreshold;

    this.onTick = function(clickEngine) {
        clickEngine.setComboClickThreshold(this.comboThreshold);
    }
}<|endoftext|>


<commit_before>import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';

const BIDDER_CODE = 'gjirafa';
const ENDPOINT_URL = 'https://central.gjirafa.com/bid';
const DIMENSION_SEPARATOR = 'x';
const SIZE_SEPARATOR = ';';

export const spec = {
  code: BIDDER_CODE,
  supportedMediaTypes: [BANNER, VIDEO],
  /**
   * Determines whether or not the given bid request is valid.
   *
   * @param {BidRequest} bid The bid params to validate.
   * @return boolean True if this is a valid bid, and false otherwise.
   */
  isBidRequestValid: function (bid) {
    return !!(bid.params.propertyId && bid.params.placementId);
  },
  /**
   * Make a server request from the list of BidRequests.
   *
   * @param {validBidRequests[]} - an array of bids
   * @return ServerRequest Info describing the request to the server.
   */
  buildRequests: function (validBidRequests, bidderRequest) {
    let propertyId = '';
    let pageViewGuid = '';
    let storageId = '';
    let bidderRequestId = '';
    let url = '';
    let contents = [];
    let data = {};

    let placements = validBidRequests.map(bidRequest => {
      if (!propertyId) { propertyId = bidRequest.params.propertyId; }
      if (!pageViewGuid && bidRequest.params) { pageViewGuid = bidRequest.params.pageViewGuid || ''; }
      if (!storageId && bidRequest.params) { storageId = bidRequest.params.storageId || ''; }
      if (!bidderRequestId) { bidderRequestId = bidRequest.bidderRequestId; }
      if (!url && bidderRequest) { url = bidderRequest.refererInfo.referer; }
      if (!contents.length && bidRequest.params.contents && bidRequest.params.contents.length) { contents = bidRequest.params.contents; }
      if (Object.keys(data).length === 0 && bidRequest.params.data && Object.keys(bidRequest.params.data).length !== 0) { data = bidRequest.params.data; }

      let adUnitId = bidRequest.adUnitCode;
      let placementId = bidRequest.params.placementId;
      let sizes = generateSizeParam(bidRequest.sizes);

      return {
        sizes: sizes,
        adUnitId: adUnitId,
        placementId: placementId,
        bidid: bidRequest.bidId,
        count: bidRequest.params.count,
        skipTime: bidRequest.params.skipTime
      };
    });

    let body = {
      propertyId: propertyId,
      pageViewGuid: pageViewGuid,
      storageId: storageId,
      url: url,
      requestid: bidderRequestId,
      placements: placements,
      contents: contents,
      data: data
    }

    return [{
      method: 'POST',
      url: ENDPOINT_URL,
      data: body
    }];
  },
  /**
   * Unpack the response from the server into a list of bids.
   *
   * @param {ServerResponse} serverResponse A successful response from the server.
   * @return {Bid[]} An array of bids which were nested inside the server.
   */
  interpretResponse: function (serverResponse) {
    const responses = serverResponse.body;
    const bidResponses = [];
    for (var i = 0; i < responses.length; i++) {
      const bidResponse = {
        requestId: responses[i].BidId,
        cpm: responses[i].CPM,
        width: responses[i].Width,
        height: responses[i].Height,
        creativeId: responses[i].CreativeId,
        currency: responses[i].Currency,
        netRevenue: responses[i].NetRevenue,
        ttl: responses[i].TTL,
        referrer: responses[i].Referrer,
        ad: responses[i].Ad,
        vastUrl: responses[i].VastUrl,
        mediaType: responses[i].MediaType,
        meta: {
          advertiserDomains: Array.isArray(responses[i].ADomain) ? responses[i].ADomain : []
        }
      };
      bidResponses.push(bidResponse);
    }
    return bidResponses;
  }
}

/**
* Generate size param for bid request using sizes array
*
* @param {Array} sizes Possible sizes for the ad unit.
* @return {string} Processed sizes param to be used for the bid request.
*/
function generateSizeParam(sizes) {
  return sizes.map(size => size.join(DIMENSION_SEPARATOR)).join(SIZE_SEPARATOR);
}

registerBidder(spec);
<commit_msg>gjirafa Bid Adapter: add biskoID and segmeents (#7409)<commit_after>import { registerBidder } from '../src/adapters/bidderFactory.js';
import { getStorageManager } from '../src/storageManager.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';

const BIDDER_CODE = 'gjirafa';
const ENDPOINT_URL = 'https://central.gjirafa.com/bid';
const DIMENSION_SEPARATOR = 'x';
const SIZE_SEPARATOR = ';';
const BISKO_ID = 'biskoId';
const STORAGE_ID = 'bisko-sid';
const SEGMENTS = 'biskoSegments';
const storage = getStorageManager();

export const spec = {
  code: BIDDER_CODE,
  supportedMediaTypes: [BANNER, VIDEO],
  /**
   * Determines whether or not the given bid request is valid.
   *
   * @param {BidRequest} bid The bid params to validate.
   * @return boolean True if this is a valid bid, and false otherwise.
   */
  isBidRequestValid: function (bid) {
    return !!(bid.params.propertyId && bid.params.placementId);
  },
  /**
   * Make a server request from the list of BidRequests.
   *
   * @param {validBidRequests[]} - an array of bids
   * @return ServerRequest Info describing the request to the server.
   */
  buildRequests: function (validBidRequests, bidderRequest) {
    const storageId = storage.localStorageIsEnabled() ? storage.getDataFromLocalStorage(STORAGE_ID) || '' : '';
    const biskoId = storage.localStorageIsEnabled() ? storage.getDataFromLocalStorage(BISKO_ID) || '' : '';
    const segments = storage.localStorageIsEnabled() ? JSON.parse(storage.getDataFromLocalStorage(SEGMENTS)) || [] : [];

    let propertyId = '';
    let pageViewGuid = '';
    let bidderRequestId = '';
    let url = '';
    let contents = [];
    let data = {};

    let placements = validBidRequests.map(bidRequest => {
      if (!propertyId) { propertyId = bidRequest.params.propertyId; }
      if (!pageViewGuid && bidRequest.params) { pageViewGuid = bidRequest.params.pageViewGuid || ''; }
      if (!bidderRequestId) { bidderRequestId = bidRequest.bidderRequestId; }
      if (!url && bidderRequest) { url = bidderRequest.refererInfo.referer; }
      if (!contents.length && bidRequest.params.contents && bidRequest.params.contents.length) { contents = bidRequest.params.contents; }
      if (Object.keys(data).length === 0 && bidRequest.params.data && Object.keys(bidRequest.params.data).length !== 0) { data = bidRequest.params.data; }

      let adUnitId = bidRequest.adUnitCode;
      let placementId = bidRequest.params.placementId;
      let sizes = generateSizeParam(bidRequest.sizes);

      return {
        sizes: sizes,
        adUnitId: adUnitId,
        placementId: placementId,
        bidid: bidRequest.bidId,
        count: bidRequest.params.count,
        skipTime: bidRequest.params.skipTime
      };
    });

    let body = {
      propertyId: propertyId,
      pageViewGuid: pageViewGuid,
      storageId: storageId,
      biskoId: biskoId,
      segments: segments,
      url: url,
      requestid: bidderRequestId,
      placements: placements,
      contents: contents,
      data: data
    }

    return [{
      method: 'POST',
      url: ENDPOINT_URL,
      data: body
    }];
  },
  /**
   * Unpack the response from the server into a list of bids.
   *
   * @param {ServerResponse} serverResponse A successful response from the server.
   * @return {Bid[]} An array of bids which were nested inside the server.
   */
  interpretResponse: function (serverResponse) {
    const responses = serverResponse.body;
    const bidResponses = [];
    for (var i = 0; i < responses.length; i++) {
      const bidResponse = {
        requestId: responses[i].BidId,
        cpm: responses[i].CPM,
        width: responses[i].Width,
        height: responses[i].Height,
        creativeId: responses[i].CreativeId,
        currency: responses[i].Currency,
        netRevenue: responses[i].NetRevenue,
        ttl: responses[i].TTL,
        referrer: responses[i].Referrer,
        ad: responses[i].Ad,
        vastUrl: responses[i].VastUrl,
        mediaType: responses[i].MediaType,
        meta: {
          advertiserDomains: Array.isArray(responses[i].ADomain) ? responses[i].ADomain : []
        }
      };
      bidResponses.push(bidResponse);
    }
    return bidResponses;
  }
}

/**
* Generate size param for bid request using sizes array
*
* @param {Array} sizes Possible sizes for the ad unit.
* @return {string} Processed sizes param to be used for the bid request.
*/
function generateSizeParam(sizes) {
  return sizes.map(size => size.join(DIMENSION_SEPARATOR)).join(SIZE_SEPARATOR);
}

registerBidder(spec);
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

var _ = require('lodash');
var async = require('async');
var http = require('http');
var phantom = require('node-phantom-simple');
var gm = require('gm');
var url = require('url');
var fs = require('fs');

var defaultOptions = {
	imageWidth: 240,
	imageHeight: 240,
	imageFormat: 'jpg',
	browserWidth: 1024,
	browserHeight: 1024,
	gravity: 'North',
	trim: false,
};

var MAX_PARALLELL_JOBS = (process.env['MAX_PARALLELL_JOBS'] ? parseInt(process.env['MAX_PARALLELL_JOBS']) : 3);
var VERBOSE_LOGGING = (process.env['VERBOSE_LOGGING'] === 'false' ? false : true);
var requestsBeingProcessed = 0;
var requestQueue = [];
var workingOnQueue = false;

var formatImage = function(imageData, imageOptions, callback){
	var imageBuffer = new Buffer(imageData, 'base64');
	// GraphicsMagick options: see http://aheckmann.github.io/gm/docs.html
	var imageObj = gm(imageBuffer, 'image.' + imageOptions.imageFormat)
		.gravity(imageOptions.gravity)
		.resize(imageOptions.imageWidth, imageOptions.imageHeight, '^')
		.crop(imageOptions.imageWidth, imageOptions.imageHeight);
	if (imageOptions.trim) {
		imageObj.trim();
	}
	imageObj.toBuffer(imageOptions.imageFormat.toUpperCase(), callback);
}

// Take URL, deliver image buffer
var renderUrlToImage = function (url, imageOptions, callback) {
	var lastTime = Date.now();

	var logTimestamp = function (msg) {
		if (VERBOSE_LOGGING)
			console.log('%s: %s (%d)', msg, url, (Date.now() - lastTime));
		lastTime = Date.now();
	};

	var thePhantomInstance;
	async.waterfall([
		// Init PhantomJS every request - saves RAM?
		phantom.create,
		// Create page
		function (ph, cbWaterfall) {
			logTimestamp('Create page');
			thePhantomInstance = ph;
			thePhantomInstance.createPage(cbWaterfall, {parameters: {'ignore-ssl-errors': 'yes'}});
		},
		// Open URL
		function (page, cbWaterfall) {
			logTimestamp('Open URL');
			page.set('resourceTimeout', 3000); // 3 seconds
			page.set('viewportSize', {
				width: imageOptions.browserWidth,
				height: imageOptions.browserHeight
			});
			page.open(url, function (err, status) {
				cbWaterfall(err, page);
			});
		},
		// Render page to image
		function (page, cbWaterfall) {
			logTimestamp('Render page');
			var renderImageFormat;
			if (imageOptions.imageFormat === 'jpg') {
				renderImageFormat = 'JPEG';
			}
			else if (imageOptions.imageFormat) {
				renderImageFormat = imageOptions.imageFormat.toUpperCase();
			}
			else {
				renderImageFormat = 'PNG';
			}
			page.renderBase64(renderImageFormat, cbWaterfall);
		},
		// Format image
		function (imageData, cbWaterfall) {
			logTimestamp('Format image');
			formatImage(imageData, imageOptions, cbWaterfall);
		},
	],
	function (err, results) {
		thePhantomInstance.exit();
		callback(err, results);
	});
};

// Save image to disk
var saveImageBufferToDisk = function (fileName, imageBuffer, callback) {
	console.log('Saving to disk:', fileName);
	fs.writeFile(fileName, imageBuffer, 'binary', callback);
};

// Take a request object and work on it
var processHTTPRequest = function (req, res, callback) {
	var pageURL = req.url.slice(1);
	var imageOptions = _.merge({}, defaultOptions);
	_.merge(imageOptions, url.parse(req.url, true).query);

	if (pageURL.indexOf('http') === -1) {
		// No URL
		if (callback) callback('Not valid URL');
	}
	else {
		requestsBeingProcessed++;
		console.log('Working on: %s (total %d)', pageURL, requestsBeingProcessed);
		renderUrlToImage(pageURL, imageOptions, function (err, imageBuffer) {
			requestsBeingProcessed--;
			console.log('Done with: %s (total %d)', pageURL, requestsBeingProcessed);
			if (!err) {
				res.writeHead(200, {
					'Content-Type': 'image/' + imageOptions.imageFormat,
					'Content-Length': imageBuffer.length,
					'Cache-Control': 'public, max-age=31536000'});
				res.end(imageBuffer);
			}
			else {
				console.log('Image render error:', err);
				if (res.send)
					res.send(500);
				else
					res.end();
			}
			if (callback) callback(err);
		});
	}

};

// Take a request object and work on it
var addToRequestQueue = function (req, res) {
	requestQueue.push({ req: req, res: res });
	// Start working on queue if not doing it already
	if (!workingOnQueue) {
		workingOnQueue = true;
		// While: 1) there is spare capacity, and 2) there is work in the queue
		async.whilst(
			function () { return requestsBeingProcessed < MAX_PARALLELL_JOBS && requestQueue.length > 0; },
			function (callback) {
				console.log('Working on: %d, in queue: %d', requestsBeingProcessed, requestQueue.length);
				var firstRequest = requestQueue.shift();
				processHTTPRequest(firstRequest.req, firstRequest.res);
				callback(null);
			},
			function (err, results) {
				console.log('Done. Working on: %d, in queue: %d', requestsBeingProcessed, requestQueue.length);
				workingOnQueue = false;
			}
		);
	}
}

// Process the incoming request if not already processing
// Else put into queue
var onIncomingHTTPRequest = function (req, res) {
	console.log('Incoming request:', req.url);
	if (requestsBeingProcessed < MAX_PARALLELL_JOBS) {
		processHTTPRequest(req, res); // Process immediately
	}
	else {
		addToRequestQueue(req, res); // Add to queue
	}
};

var processCommandLine = function () {
	var imageOptions = _.merge({}, defaultOptions);
	async.waterfall([
			// Process arguments
			function (cbWaterfall) {
				for (var i = 2; i < process.argv.length; i++) {
					var arg = process.argv[i];
					if (arg.indexOf('http') !== -1) {
						imageOptions.url = arg;
					}
					else if (arg.indexOf('=') !== -1) {
						var param = arg.split('=');
						imageOptions[param[0]] = param[1];
					}
					else if (arg.indexOf('.') !== -1) {
						imageOptions.fileName = arg;
					}
				};
				imageOptions.fileName = imageOptions.fileName || 'screenshot.' + imageOptions.imageFormat;
				cbWaterfall(null, imageOptions);
			},
			// Render page
			function (imageOptions, cbWaterfall) {
				console.log('Render URL to image', imageOptions);
				renderUrlToImage(imageOptions.url, imageOptions, cbWaterfall);
			},
			// Save to disk
			function (imageBuffer, cbWaterfall) {
				saveImageBufferToDisk(imageOptions.fileName, imageBuffer, cbWaterfall);
			},
		]
	);
};

// Start server
var startWebServer = function () {
	var serverPort = process.env.PORT || 1337;
	var server = http.createServer(onIncomingHTTPRequest);

	server.listen(serverPort, function () {
		console.log('Screenshooter service running on http://localhost:' + serverPort);
	});
};

// Main loop
if (process.argv.length >= 3) {
	// Run as command line
	processCommandLine();
}
else {
	// Else web server
	startWebServer();
}<commit_msg>Error renderImageFormat<commit_after>#!/usr/bin/env node

'use strict';

var _ = require('lodash');
var async = require('async');
var http = require('http');
var phantom = require('node-phantom-simple');
var gm = require('gm');
var url = require('url');
var fs = require('fs');

var defaultOptions = {
	imageWidth: 240,
	imageHeight: 240,
	imageFormat: 'jpg',
	browserWidth: 1024,
	browserHeight: 1024,
	gravity: 'North',
	trim: false,
};

var MAX_PARALLELL_JOBS = (process.env['MAX_PARALLELL_JOBS'] ? parseInt(process.env['MAX_PARALLELL_JOBS']) : 3);
var VERBOSE_LOGGING = (process.env['VERBOSE_LOGGING'] === 'false' ? false : true);
var requestsBeingProcessed = 0;
var requestQueue = [];
var workingOnQueue = false;

var formatImage = function(imageData, imageOptions, callback){
	var imageBuffer = new Buffer(imageData, 'base64');
	// GraphicsMagick options: see http://aheckmann.github.io/gm/docs.html
	var imageObj = gm(imageBuffer, 'image.' + imageOptions.imageFormat)
		.gravity(imageOptions.gravity)
		.resize(imageOptions.imageWidth, imageOptions.imageHeight, '^')
		.crop(imageOptions.imageWidth, imageOptions.imageHeight);
	if (imageOptions.trim) {
		imageObj.trim();
	}
	imageObj.toBuffer(imageOptions.imageFormat.toUpperCase(), callback);
}

// Take URL, deliver image buffer
var renderUrlToImage = function (url, imageOptions, callback) {
	var lastTime = Date.now();

	var logTimestamp = function (msg) {
		if (VERBOSE_LOGGING)
			console.log('%s: %s (%d)', msg, url, (Date.now() - lastTime));
		lastTime = Date.now();
	};

	var thePhantomInstance;
	async.waterfall([
		// Init PhantomJS every request - saves RAM?
		phantom.create,
		// Create page
		function (ph, cbWaterfall) {
			logTimestamp('Create page');
			thePhantomInstance = ph;
			thePhantomInstance.createPage(cbWaterfall, {parameters: {'ignore-ssl-errors': 'yes'}});
		},
		// Open URL
		function (page, cbWaterfall) {
			logTimestamp('Open URL');
			page.set('resourceTimeout', 3000); // 3 seconds
			page.set('viewportSize', {
				width: imageOptions.browserWidth,
				height: imageOptions.browserHeight
			});
			page.open(url, function (err, status) {
				cbWaterfall(err, page);
			});
		},
		// Render page to image
		function (page, cbWaterfall) {
			logTimestamp('Render page');
			try {
				var renderImageFormat;
				if (imageOptions.imageFormat === 'jpg') {
					renderImageFormat = 'JPEG';
				}
				else if (imageOptions.imageFormat) {
					renderImageFormat = imageOptions.imageFormat.toUpperCase();
				}
				else {
					renderImageFormat = 'PNG';
				}
				page.renderBase64(renderImageFormat, cbWaterfall);
			}
			catch (err) {
				console.log('Error renderImageFormat', err, imageOptions);
				cbWaterfall(err);
			}
		},
		// Format image
		function (imageData, cbWaterfall) {
			logTimestamp('Format image');
			formatImage(imageData, imageOptions, cbWaterfall);
		},
	],
	function (err, results) {
		thePhantomInstance.exit();
		callback(err, results);
	});
};

// Save image to disk
var saveImageBufferToDisk = function (fileName, imageBuffer, callback) {
	console.log('Saving to disk:', fileName);
	fs.writeFile(fileName, imageBuffer, 'binary', callback);
};

// Take a request object and work on it
var processHTTPRequest = function (req, res, callback) {
	var pageURL = req.url.slice(1);
	var imageOptions = _.merge({}, defaultOptions);
	_.merge(imageOptions, url.parse(req.url, true).query);

	if (pageURL.indexOf('http') === -1) {
		// No URL
		if (callback) callback('Not valid URL');
	}
	else {
		requestsBeingProcessed++;
		console.log('Working on: %s (total %d)', pageURL, requestsBeingProcessed);
		renderUrlToImage(pageURL, imageOptions, function (err, imageBuffer) {
			requestsBeingProcessed--;
			console.log('Done with: %s (total %d)', pageURL, requestsBeingProcessed);
			if (!err) {
				res.writeHead(200, {
					'Content-Type': 'image/' + imageOptions.imageFormat,
					'Content-Length': imageBuffer.length,
					'Cache-Control': 'public, max-age=31536000'});
				res.end(imageBuffer);
			}
			else {
				console.log('Image render error:', err);
				if (res.send)
					res.send(500);
				else
					res.end();
			}
			if (callback) callback(err);
		});
	}

};

// Take a request object and work on it
var addToRequestQueue = function (req, res) {
	requestQueue.push({ req: req, res: res });
	// Start working on queue if not doing it already
	if (!workingOnQueue) {
		workingOnQueue = true;
		// While: 1) there is spare capacity, and 2) there is work in the queue
		async.whilst(
			function () { return requestsBeingProcessed < MAX_PARALLELL_JOBS && requestQueue.length > 0; },
			function (callback) {
				console.log('Working on: %d, in queue: %d', requestsBeingProcessed, requestQueue.length);
				var firstRequest = requestQueue.shift();
				processHTTPRequest(firstRequest.req, firstRequest.res);
				callback(null);
			},
			function (err, results) {
				console.log('Done. Working on: %d, in queue: %d', requestsBeingProcessed, requestQueue.length);
				workingOnQueue = false;
			}
		);
	}
}

// Process the incoming request if not already processing
// Else put into queue
var onIncomingHTTPRequest = function (req, res) {
	console.log('Incoming request:', req.url);
	if (requestsBeingProcessed < MAX_PARALLELL_JOBS) {
		processHTTPRequest(req, res); // Process immediately
	}
	else {
		addToRequestQueue(req, res); // Add to queue
	}
};

var processCommandLine = function () {
	var imageOptions = _.merge({}, defaultOptions);
	async.waterfall([
			// Process arguments
			function (cbWaterfall) {
				for (var i = 2; i < process.argv.length; i++) {
					var arg = process.argv[i];
					if (arg.indexOf('http') !== -1) {
						imageOptions.url = arg;
					}
					else if (arg.indexOf('=') !== -1) {
						var param = arg.split('=');
						imageOptions[param[0]] = param[1];
					}
					else if (arg.indexOf('.') !== -1) {
						imageOptions.fileName = arg;
					}
				};
				imageOptions.fileName = imageOptions.fileName || 'screenshot.' + imageOptions.imageFormat;
				cbWaterfall(null, imageOptions);
			},
			// Render page
			function (imageOptions, cbWaterfall) {
				console.log('Render URL to image', imageOptions);
				renderUrlToImage(imageOptions.url, imageOptions, cbWaterfall);
			},
			// Save to disk
			function (imageBuffer, cbWaterfall) {
				saveImageBufferToDisk(imageOptions.fileName, imageBuffer, cbWaterfall);
			},
		]
	);
};

// Start server
var startWebServer = function () {
	var serverPort = process.env.PORT || 1337;
	var server = http.createServer(onIncomingHTTPRequest);

	server.listen(serverPort, function () {
		console.log('Screenshooter service running on http://localhost:' + serverPort);
	});
};

// Main loop
if (process.argv.length >= 3) {
	// Run as command line
	processCommandLine();
}
else {
	// Else web server
	startWebServer();
}<|endoftext|>


<commit_before>function epicDetailsController ($scope, $http, $q, $location) {
	var notStartedNames = ["To Do", "Open"];

    $scope.contextPath = jQuery('meta[name="ajs-context-path"]').attr('content');
    $scope.key = $location.search().epic;
    $scope.epicName = '';
    $scope.fullStories = []; // the full list of stories
    $scope.stories = []; // the list of stories in the current date range
    $scope.notStarted = 0;
    $scope.inProgress = 0;
    $scope.done = 0;
	$scope.averageTime = 0;

    $scope.workType = 1;

    $scope.$watch('workType', function() {
    	$scope.refresh();
    });

    $scope.points = [[]];

    //map from constant name to custom field name
    var fieldMap = {
        'Epic Name': null,
        'Story Points': null
    };

    var epicQuery = $scope.contextPath + '/rest/api/2/';
    var storiesQuery = $scope.contextPath + '/rest/api/2/search?jql=';

    if($scope.key.indexOf('-') != -1) {
        epicQuery += 'issue';
        storiesQuery += '"Epic Link"=' + $scope.key;
    }
    else {
        epicQuery += 'project';
        storiesQuery += 'project=' + $scope.key + ' and "Epic Link" is empty and issuetype not in (Epic, Sub-task)';
    }

    epicQuery += '/' + $scope.key;
    storiesQuery += ' order by resolutiondate desc';

    $q.all([
        $http.get(epicQuery),
        $http.get(storiesQuery),
        $http.get($scope.contextPath + '/rest/api/2/field')
    ]).then(function(results) {
        var epic = results[0].data;
        var stories = results[1].data;
        var fields = results[2].data;

        //get the rest of the stories if there are more
        var maxResults = stories.maxResults;
        var total = stories.total;

        if(maxResults < total) {
            var requests = [];
            for(var i = maxResults; i < total; i += maxResults) {
                requests.push($http.get(storiesQuery + '&startAt=' + i));
            }

            $q.all(requests).then(function(results) {
                //add the new stories to the list
                angular.forEach(results, function(e, i) {
                    $scope.fullStories = $scope.fullStories.concat(e.data.issues);
                    $scope.stories = $scope.stories.concat(e.data.issues);
                });

                //refresh the display
                $scope.refresh();
            });
        }

        //setup field map
        angular.forEach(fieldMap, function(value, key) {
            angular.forEach(fields, function(elem, index) {
                if(key === elem.name) {
                    fieldMap[key] = elem.id;
                }
            });
        });

        if($scope.key.indexOf('-') != -1) {
            $scope.epicName = getField(epic.fields, 'Epic Name');
        }
        else {
            $scope.epicName = 'Other stories (' + epic.name + ')';
        }

        $scope.fullStories = stories.issues;
        $scope.stories = $scope.fullStories;

		var completedStories = 0;

    	var sumTime = 0;

    	angular.forEach($scope.stories, function(story, index) {

    		if(story.fields.resolutiondate !== null) {

    			completedStories++;

    			completedTime = Date.parse(story.fields.resolutiondate) - Date.parse(story.fields.created);

    			sumTime+= completedTime;

            }

        });

		if(completedStories !== 0){

        	$scope.averageTime = (sumTime/(completedStories*3600000)).toFixed(2);

        } else{

        	$scope.averageTime = 0;

        }

        $scope.refresh();

    });

    function getField(data, field) {
        return data[fieldMap[field]];
    }

    // count the number of not started, in progress, and done stories
    function countStories(stories) {
        $scope.notStarted = 0;
        $scope.inProgress = 0;
        $scope.done = 0;

    	angular.forEach(stories, function(story, index) {
    		var resolution = story.fields.resolutiondate;
    		if (resolution !== undefined && resolution !== null) {
    			$scope.done += getValue(story);
    		} else if (jQuery.inArray(story.fields.status.name, notStartedNames) != -1) {
    			$scope.notStarted += getValue(story);
    		} else {
    			$scope.inProgress += getValue(story);
    		}
    	});
    }

    // creates a list of (date, number) pairs
    function getProgressList(stories) {
        var list = [];

        angular.forEach(stories, function(story, index) {
            var value = getValue(story);
            list.push({
                date: Date.parse(story.fields.created),
                number: value
            });

            var resolution = story.fields.resolutiondate;
            if(resolution !== undefined && resolution !== null) {
                list.push({
                    date: Date.parse(story.fields.resolutiondate),
                    number: -value
                });
            }
        });

        list.push({
            date: new Date().getTime(),
            number: 0
        });

        return list;
    }

    // get the value of the story based on which work type is selected
    function getValue(story) {
        switch($scope.workType) {
        case 1:
            return 1;
        case 2:
            var points = getField(story.fields, 'Story Points');
            return (points !== undefined && points !== null) ? points : 0;
        case 3:
            var resolution = story.fields.resolutiondate;
            var time = story.fields.aggregateprogress.total;

            if(resolution !== undefined && resolution !== null) {
                time = story.fields.aggregateprogress.progress;
            }

            return (time / 3600);
        }
    }

    // format the given number for display
    $scope.format = function(number) {
    	if ($scope.workType == 3) {
    		return number.toFixed(2);
    	}
    	return number;
    };

    // update the story counts and chart points
    $scope.refresh = function() {
    	countStories($scope.stories);

    	// update points using full story list, so graph doesn't shrink
        var points = getProgressList($scope.fullStories);
        points.sort(function(a, b) {
            return a.date - b.date;
        });
        $scope.points = [[]];
        var runningTotal = 0;
        angular.forEach(points, function(elem, index) {
            runningTotal += elem.number;
            $scope.points[0].push([elem.date, runningTotal]);
        });
    };

    //nicely format the date string
    $scope.doneDate = function(date) {
        if(date !== undefined && date !== null) {
            return new Date(Date.parse(date)).toLocaleString();
        }
        else {
            return 'unresolved';
        }
    };
}

// Directive for creating charts
// Creates a chart with an overview chart for selecting time ranges
function chartDirective() {
    return {
        restrict: 'E',
        template: "

" +
        		  "

",
        link: function(scope, elem, attrs) {
            var chart = null;
            var overview = null;

            var opts = {
                xaxis: {
                    ticks: function(axis) {
                        var min = axis.min;
                        var step = Math.floor((axis.max - axis.min) / 4);

                        var ticks = [];

                        for(var i = 0; i < 5; i++) {
                            ticks.push(min);
                            min += step;
                        }
                        return ticks;
                    },
                    tickFormatter: function(val, axis) {
                        var range = axis.max - axis.min;
                        var day = 1000 * 60 * 60 * 24;

                        var date = new Date(val);

                        if(range >= 4 * day) {
                            return date.toLocaleDateString() + '
 ';//hack to force using up som whitespace
                        }
                        else if(range >= day) {
                            return date.toLocaleDateString() + '
' + date.toLocaleTimeString();
                        }
                        else {
                            return date.toLocaleTimeString() + '
 ';
                        }
                    }

                },
                yaxis: {
                    minTickSize: 1,
                    tickFormatter: function(val, axis) {
                        return Math.floor(parseFloat(val));
                    }
                },
                selection: {
    				mode: "x"
    			},
                series: {
                    lines: {
                        steps: true
                    }
                }
            };

            var overviewOpts = {
            	series: {
        			lines: {
                        steps: true,
        				show: true,
        				lineWidth: 1
        			},
        			shadowSize: 0
       			},
       			xaxis: {
       				ticks: [],
       				mode: "time"
        		},
        		yaxis: {
        			ticks: [],
       				min: 0,
       				autoscaleMargin: 0.1
       			},
        		selection: {
        			mode: "x"
       			}
            };

            scope.$watch(attrs.ngModel, function(v) {
                if(!chart) {
                	var chartElem = jQuery('#chart');
                	var overviewElem = jQuery('#overview');

                    chart = jQuery.plot(chartElem, v, opts);
                    overview = jQuery.plot(overviewElem, v, overviewOpts);
                    chartElem.show();
                    overviewElem.show();
                    elem.show();
                }
                else {

                    chart.setData(v);
                    chart.setupGrid();
                    chart.draw();
                    overview.setData(v);
                    overview.setupGrid();
                    overview.draw();
                }
            });

            jQuery("#chart").bind("plotselected", function (event, ranges) {

    			// do the zooming
    			jQuery.each(chart.getXAxes(), function(_, axis) {
    				var opts = axis.options;
    				opts.min = ranges.xaxis.from;
    				opts.max = ranges.xaxis.to;
    				zoom(opts.min, opts.max);
    			});
    			chart.setupGrid();
    			chart.draw();
    			chart.clearSelection();

    			// don't fire event on the overview to prevent eternal loop

    			overview.setSelection(ranges, true);
    		});
    		jQuery("#overview").bind("plotselected", function (event, ranges) {
    			chart.setSelection(ranges);
    		});

    		// zoom to the given minimum and maximum millisecond values
    		// update the current data to be a subset between the values
    		function zoom(min, max) {
    			scope.stories = [];
    			angular.forEach(scope.fullStories, function(story, index) {
    				var created = Date.parse(story.fields.created);
    				var resolved = story.fields.resolutiondate !== null ? Date.parse(story.fields.resolutiondate) : null;
    				if (created <= max && (resolved === null || resolved >= min)) {
    					scope.stories.push(story);
    				}
    			});
    			// refresh the page, wrap in apply so that page updates
    			scope.$apply(function() {
    				scope.refresh();
    			});
    		}
        }
    };
}

<commit_msg>put the average time function into refresh<commit_after>function epicDetailsController ($scope, $http, $q, $location) {
	var notStartedNames = ["To Do", "Open"];

    $scope.contextPath = jQuery('meta[name="ajs-context-path"]').attr('content');
    $scope.key = $location.search().epic;
    $scope.epicName = '';
    $scope.fullStories = []; // the full list of stories
    $scope.stories = []; // the list of stories in the current date range
    $scope.notStarted = 0;
    $scope.inProgress = 0;
    $scope.done = 0;
	$scope.averageTime = 0;

    $scope.workType = 1;

    $scope.$watch('workType', function() {
    	$scope.refresh();
    });

    $scope.points = [[]];

    //map from constant name to custom field name
    var fieldMap = {
        'Epic Name': null,
        'Story Points': null
    };

    var epicQuery = $scope.contextPath + '/rest/api/2/';
    var storiesQuery = $scope.contextPath + '/rest/api/2/search?jql=';

    if($scope.key.indexOf('-') != -1) {
        epicQuery += 'issue';
        storiesQuery += '"Epic Link"=' + $scope.key;
    }
    else {
        epicQuery += 'project';
        storiesQuery += 'project=' + $scope.key + ' and "Epic Link" is empty and issuetype not in (Epic, Sub-task)';
    }

    epicQuery += '/' + $scope.key;
    storiesQuery += ' order by resolutiondate desc';

    $q.all([
        $http.get(epicQuery),
        $http.get(storiesQuery),
        $http.get($scope.contextPath + '/rest/api/2/field')
    ]).then(function(results) {
        var epic = results[0].data;
        var stories = results[1].data;
        var fields = results[2].data;

        //get the rest of the stories if there are more
        var maxResults = stories.maxResults;
        var total = stories.total;

        if(maxResults < total) {
            var requests = [];
            for(var i = maxResults; i < total; i += maxResults) {
                requests.push($http.get(storiesQuery + '&startAt=' + i));
            }

            $q.all(requests).then(function(results) {
                //add the new stories to the list
                angular.forEach(results, function(e, i) {
                    $scope.fullStories = $scope.fullStories.concat(e.data.issues);
                    $scope.stories = $scope.stories.concat(e.data.issues);
                });

                //refresh the display
                $scope.refresh();
            });
        }

        //setup field map
        angular.forEach(fieldMap, function(value, key) {
            angular.forEach(fields, function(elem, index) {
                if(key === elem.name) {
                    fieldMap[key] = elem.id;
                }
            });
        });

        if($scope.key.indexOf('-') != -1) {
            $scope.epicName = getField(epic.fields, 'Epic Name');
        }
        else {
            $scope.epicName = 'Other stories (' + epic.name + ')';
        }

        $scope.fullStories = stories.issues;
        $scope.stories = $scope.fullStories;

        $scope.refresh();

    });

    function getField(data, field) {
        return data[fieldMap[field]];
    }

    // count the number of not started, in progress, and done stories
    function countStories(stories) {
        $scope.notStarted = 0;
        $scope.inProgress = 0;
        $scope.done = 0;

    	angular.forEach(stories, function(story, index) {
    		var resolution = story.fields.resolutiondate;
    		if (resolution !== undefined && resolution !== null) {
    			$scope.done += getValue(story);
    		} else if (jQuery.inArray(story.fields.status.name, notStartedNames) != -1) {
    			$scope.notStarted += getValue(story);
    		} else {
    			$scope.inProgress += getValue(story);
    		}
    	});
    }

    // creates a list of (date, number) pairs
    function getProgressList(stories) {
        var list = [];

        angular.forEach(stories, function(story, index) {
            var value = getValue(story);
            list.push({
                date: Date.parse(story.fields.created),
                number: value
            });

            var resolution = story.fields.resolutiondate;
            if(resolution !== undefined && resolution !== null) {
                list.push({
                    date: Date.parse(story.fields.resolutiondate),
                    number: -value
                });
            }
        });

        list.push({
            date: new Date().getTime(),
            number: 0
        });

        return list;
    }

    // get the value of the story based on which work type is selected
    function getValue(story) {
        switch($scope.workType) {
        case 1:
            return 1;
        case 2:
            var points = getField(story.fields, 'Story Points');
            return (points !== undefined && points !== null) ? points : 0;
        case 3:
            var resolution = story.fields.resolutiondate;
            var time = story.fields.aggregateprogress.total;

            if(resolution !== undefined && resolution !== null) {
                time = story.fields.aggregateprogress.progress;
            }

            return (time / 3600);
        }
    }

    function getAverageTime(stories) {

    	var completedStories = 0;
    	var sumTime = 0;

    	angular.forEach(stories, function(story, index) {
    		if(story.fields.resolutiondate !== null) {
    			completedStories++;
    			completedTime = Date.parse(story.fields.resolutiondate) - Date.parse(story.fields.created);
    			sumTime+= completedTime;
            }
        });

		if(completedStories !== 0){
        	$scope.averageTime = (sumTime/(completedStories*3600000)).toFixed(2);
        } else{
        	$scope.averageTime = 0;
        }
    }

    // format the given number for display
    $scope.format = function(number) {
    	if ($scope.workType == 3) {
    		return number.toFixed(2);
    	}
    	return number;
    };

    // update the story counts and chart points
    $scope.refresh = function() {
    	countStories($scope.stories);
    	getAverageTime($scope.stories);

    	// update points using full story list, so graph doesn't shrink
        var points = getProgressList($scope.fullStories);
        points.sort(function(a, b) {
            return a.date - b.date;
        });
        $scope.points = [[]];
        var runningTotal = 0;
        angular.forEach(points, function(elem, index) {
            runningTotal += elem.number;
            $scope.points[0].push([elem.date, runningTotal]);
        });
    };

    //nicely format the date string
    $scope.doneDate = function(date) {
        if(date !== undefined && date !== null) {
            return new Date(Date.parse(date)).toLocaleString();
        }
        else {
            return 'unresolved';
        }
    };
}

// Directive for creating charts
// Creates a chart with an overview chart for selecting time ranges
function chartDirective() {
    return {
        restrict: 'E',
        template: "

" +
        		  "

",
        link: function(scope, elem, attrs) {
            var chart = null;
            var overview = null;

            var opts = {
                xaxis: {
                    ticks: function(axis) {
                        var min = axis.min;
                        var step = Math.floor((axis.max - axis.min) / 4);

                        var ticks = [];

                        for(var i = 0; i < 5; i++) {
                            ticks.push(min);
                            min += step;
                        }
                        return ticks;
                    },
                    tickFormatter: function(val, axis) {
                        var range = axis.max - axis.min;
                        var day = 1000 * 60 * 60 * 24;

                        var date = new Date(val);

                        if(range >= 4 * day) {
                            return date.toLocaleDateString() + '
 ';//hack to force using up som whitespace
                        }
                        else if(range >= day) {
                            return date.toLocaleDateString() + '
' + date.toLocaleTimeString();
                        }
                        else {
                            return date.toLocaleTimeString() + '
 ';
                        }
                    }

                },
                yaxis: {
                    minTickSize: 1,
                    tickFormatter: function(val, axis) {
                        return Math.floor(parseFloat(val));
                    }
                },
                selection: {
    				mode: "x"
    			},
                series: {
                    lines: {
                        steps: true
                    }
                }
            };

            var overviewOpts = {
            	series: {
        			lines: {
                        steps: true,
        				show: true,
        				lineWidth: 1
        			},
        			shadowSize: 0
       			},
       			xaxis: {
       				ticks: [],
       				mode: "time"
        		},
        		yaxis: {
        			ticks: [],
       				min: 0,
       				autoscaleMargin: 0.1
       			},
        		selection: {
        			mode: "x"
       			}
            };

            scope.$watch(attrs.ngModel, function(v) {
                if(!chart) {
                	var chartElem = jQuery('#chart');
                	var overviewElem = jQuery('#overview');

                    chart = jQuery.plot(chartElem, v, opts);
                    overview = jQuery.plot(overviewElem, v, overviewOpts);
                    chartElem.show();
                    overviewElem.show();
                    elem.show();
                }
                else {

                    chart.setData(v);
                    chart.setupGrid();
                    chart.draw();
                    overview.setData(v);
                    overview.setupGrid();
                    overview.draw();
                }
            });

            jQuery("#chart").bind("plotselected", function (event, ranges) {

    			// do the zooming
    			jQuery.each(chart.getXAxes(), function(_, axis) {
    				var opts = axis.options;
    				opts.min = ranges.xaxis.from;
    				opts.max = ranges.xaxis.to;
    				zoom(opts.min, opts.max);
    			});
    			chart.setupGrid();
    			chart.draw();
    			chart.clearSelection();

    			// don't fire event on the overview to prevent eternal loop

    			overview.setSelection(ranges, true);
    		});
    		jQuery("#overview").bind("plotselected", function (event, ranges) {
    			chart.setSelection(ranges);
    		});

    		// zoom to the given minimum and maximum millisecond values
    		// update the current data to be a subset between the values
    		function zoom(min, max) {
    			scope.stories = [];
    			angular.forEach(scope.fullStories, function(story, index) {
    				var created = Date.parse(story.fields.created);
    				var resolved = story.fields.resolutiondate !== null ? Date.parse(story.fields.resolutiondate) : null;
    				if (created <= max && (resolved === null || resolved >= min)) {
    					scope.stories.push(story);
    				}
    			});
    			// refresh the page, wrap in apply so that page updates
    			scope.$apply(function() {
    				scope.refresh();
    			});
    		}
        }
    };
}

<|endoftext|>