<commit_before>/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence Sematext Agent for OS Metrics is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */
'use strict'
var util = require('util')
var SpmAgent = require('spm-agent')
var Agent = SpmAgent.Agent
var config = SpmAgent.Config
var logger = SpmAgent.Logger
var os = require('os')
var cluster = require('cluster')
var linux = require('./linuxMetrics.js')
var lastValues = {}

function formatArray (a) {
  if (a instanceof Array) {
    if (a.length === 0) {
      return ''
    } else {
      return a.join('\t')
    }
  } else {
    return a + ''
  }
}
function calcDiff (name, value) {
  var diff = 0
  if (!lastValues[name]) {
    lastValues[name] = Number(value)
  }
  diff = value - lastValues[name]
  lastValues[name] = value
  return diff
}
/**
 * This module generates Linux-OS Metrics. Names are compatible with collectd. SpmSender uses collectd format for OS Metrics
 * @returns {Agent}
 */
module.exports = function () {
  var linuxAgent = new Agent({
    // osnet    1457010656149    lo    0    0
    _formatLine: function (metric) {
      var now = (new Date().getTime()).toFixed(0)
      var line = null
      if (metric.sct === 'OS' && /collectd/.test(metric.name)) {
        line = this.collectdFormatLine(metric)
      } else {
        if (metric.sct === 'OS') {
          // new OS metric format
          if (metric.filters instanceof Array) {
            line = util.format('%d\t%s\t%d\t%s\t%s', now, metric.name, metric.ts, formatArray(metric.filters), formatArray(metric.value))
          } else {
            line = util.format('%d\t%s\t%d\t%s', now, metric.name, metric.ts, formatArray(metric.value))
          }
          logger.log(line)
        } else {
          line = util.format('%d\t%s\t%d\t%s\t%s', now, (metric.type || this.defaultType) + '-' + metric.name, metric.ts, formatArray(metric.filters), formatArray(metric.value))
          logger.log(line)
        }
      }
      return line
    },
    start: function (agent) {
      this.isLinux = (os.platform() === 'linux')
      this.formatLine = this._formatLine.bind(agent)
      this.agent = agent
      var cpuLastValues = {}
      os.cpus().forEach(function (cpu, i) {
        cpuLastValues[i] = {idle: 0, user: 0, sys: 0, irq: 0, nice: 0, wait: 0, softirq: 0, stolen: 0}
      })
      // var cpuProperties = ['user', 'nice', 'irq', 'sys', 'idle', 'wait', 'softirq', 'stolen']
      var cpuProperties = ['user', 'nice', 'irq', 'system', 'idle', 'iowait', 'softirq', 'steal']
      if (cluster.isMaster || process.env.NODE_APP_INSTANCE === 0 || process.env.SPM_MASTER_MODE === 1) {
        var timerId = setInterval(function () {
          var time = Date.now()
          var load = os.loadavg()
          var loadAvg1min = 0
          if (load && load.length > 0) {
            loadAvg1min = load[0]
          }
          agent.addMetrics({ts: time, type: 'os', name: 'oslo', filters: '', value: [loadAvg1min], sct: 'OS'})
          if (this.isLinux) {
            linux.networkStats(function (data) {
              if (data) {
                data.forEach(function (netStat) {
                  if (netStat.bytes && netStat.Interface) {
                    agent.addMetrics({ ts: time, name: 'osnet', filters: [netStat.Interface || 'unknown'],
                      value: [calcDiff(netStat.Interface + 'tx', Number(netStat.bytes.Transmit)),
                        calcDiff(netStat.Interface + 'rx', Number(netStat.bytes.Receive))],
                      sct: 'OS'
                    })
                  }
                })
              }
            })
            linux.df(function dfMetrics (err, data) {
              if (err) {
                return logger.error('Error in df() for disk-usage metrics:' + err)
              }
              if (data && data.length > 0) {
                data.forEach(function (disk) {
                  if (/\/dev\/.+/i.test(disk.filesystem)) {
                    var dev = disk.filesystem.split('/')[2]
                    agent.addMetrics({ ts: time, name: 'osdf', filters: [dev],
                      value: [disk.available * 1024, disk.used * 1024],
                      sct: 'OS'
                    })
                  }
                })
              }
            })
            linux.vmstat(function (err, vmstat) {
              SpmAgent.Logger.debug('vmstat ', vmstat)
              if (err) {
                SpmAgent.Logger.error('error calling vmstat ' + err)
                return
              }
              linux.vmstatS(function (err, vmstats) {
                if (err) {
                  SpmAgent.Logger.error('error calling vmstat ' + err)
                  return
                }
                agent.addMetrics({
                  ts: time,
                  type: 'os',
                  name: 'osmem',
                  filters: '',
                  value: [vmstats.memory.used * 1024,
                    vmstats.memory.free * 1024,
                    vmstat.cache * 1024,
                    vmstats.memory.buffer * 1024,
                    vmstat.swapd * 1024,
                    vmstat.si,
                    vmstat.so],
                  sct: 'OS'
                })
                if (vmstats.disks) {
                  try {
                    vmstats.disks.forEach(function (disk) {
                      agent.addMetrics({
                        ts: time,
                        type: 'os',
                        name: 'osdio',
                        filters: [disk.device],
                        value: [(calcDiff(disk.device + 'sectors_read', disk.sectors_read) * 512),
                          (calcDiff(disk.device + 'sectors_written', disk.sectors_written) * 512)],
                        sct: 'OS'
                      })
                    })
                  } catch (diskInfoErr) {
                    console.log(diskInfoErr)
                  }
                }
                var cpuTotal = 0
                var i = 0
                cpuProperties.forEach(function (property) {
                  // console.log ('CPU ' + property + ' ' + vmstats.cpu [property])
                  if (isNaN(Number(cpuLastValues[i][property]))) {
                    cpuLastValues[i][property] = 0
                  }
                  cpuLastValues[i][property] = Number(vmstats.cpu[property]) - Number(cpuLastValues[i][property])
                  cpuTotal = Number(cpuTotal) + Number(cpuLastValues[i][property])
                })
                agent.addMetrics({
                  ts: time,
                  type: 'os',
                  name: 'oscpu',
                  filters: '',
                  value: [(cpuLastValues[i].user / cpuTotal) * 100,
                    (cpuLastValues[i].nice / cpuTotal) * 100,
                    (cpuLastValues[i].system / cpuTotal) * 100,
                    (cpuLastValues[i].idle / cpuTotal) * 100,
                    (cpuLastValues[i].iowait / cpuTotal) * 100,
                    (cpuLastValues[i].irq / cpuTotal) * 100,
                    (cpuLastValues[i].softirq / cpuTotal) * 100,
                    (cpuLastValues[i].steal / cpuTotal) * 100],
                  sct: 'OS'
                })
              })
            })
          }
        }.bind(this), config.collectionInterval || 30000)
        if (timerId.unref) {
          timerId.unref()
        }
      }
    }
  }
  )
  return linuxAgent
}
<commit_msg>fix mem and cpu metrics<commit_after>/*
 * @copyright Copyright (c) Sematext Group, Inc. - All Rights Reserved
 *
 * @licence Sematext Agent for OS Metrics is free-to-use, proprietary software.
 * THIS IS PROPRIETARY SOURCE CODE OF Sematext Group, Inc. (Sematext)
 * This source code may not be copied, reverse engineered, or altered for any purpose.
 * This source code is to be used exclusively by users and customers of Sematext.
 * Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
 */
'use strict'
var util = require('util')
var SpmAgent = require('spm-agent')
var Agent = SpmAgent.Agent
var config = SpmAgent.Config
var logger = SpmAgent.Logger
var os = require('os')
var cluster = require('cluster')
var linux = require('./linuxMetrics.js')
var lastValues = {}

function formatArray (a) {
  if (a instanceof Array) {
    if (a.length === 0) {
      return ''
    } else {
      return a.join('\t')
    }
  } else {
    return a + ''
  }
}
function calcDiff (name, value) {
  var diff = 0
  if (!lastValues[name]) {
    lastValues[name] = Number(value)
  }
  diff = value - lastValues[name]
  lastValues[name] = value
  return diff
}
/**
 * This module generates Linux-OS Metrics. Names are compatible with collectd. SpmSender uses collectd format for OS Metrics
 * @returns {Agent}
 */
module.exports = function () {
  var linuxAgent = new Agent({
    // osnet    1457010656149    lo    0    0
    _formatLine: function (metric) {
      var now = (new Date().getTime()).toFixed(0)
      var line = null
      if (metric.sct === 'OS' && /collectd/.test(metric.name)) {
        line = this.collectdFormatLine(metric)
      } else {
        if (metric.sct === 'OS') {
          // new OS metric format
          if (metric.filters instanceof Array) {
            line = util.format('%d\t%s\t%d\t%s\t%s', now, metric.name, metric.ts, formatArray(metric.filters), formatArray(metric.value))
          } else {
            line = util.format('%d\t%s\t%d\t%s', now, metric.name, metric.ts, formatArray(metric.value))
          }
          logger.log(line)
        } else {
          line = util.format('%d\t%s\t%d\t%s\t%s', now, (metric.type || this.defaultType) + '-' + metric.name, metric.ts, formatArray(metric.filters), formatArray(metric.value))
          logger.log(line)
        }
      }
      return line
    },
    start: function (agent) {
      this.isLinux = (os.platform() === 'linux')
      this.formatLine = this._formatLine.bind(agent)
      this.agent = agent
      var cpuLastValues = {}
      os.cpus().forEach(function (cpu, i) {
        cpuLastValues[i] = {idle: 0, user: 0, sys: 0, irq: 0, nice: 0, wait: 0, softirq: 0, stolen: 0}
      })
      // var cpuProperties = ['user', 'nice', 'irq', 'sys', 'idle', 'wait', 'softirq', 'stolen']
      var cpuProperties = ['user', 'nice', 'irq', 'system', 'idle', 'iowait', 'softirq', 'steal']
      if (cluster.isMaster || process.env.NODE_APP_INSTANCE === 0 || process.env.SPM_MASTER_MODE === 1) {
        var timerId = setInterval(function () {
          var time = Date.now()
          var load = os.loadavg()
          var loadAvg1min = 0
          if (load && load.length > 0) {
            loadAvg1min = load[0]
          }
          agent.addMetrics({ts: time, type: 'os', name: 'oslo', filters: '', value: [loadAvg1min], sct: 'OS'})
          if (this.isLinux) {
            linux.networkStats(function (data) {
              if (data) {
                data.forEach(function (netStat) {
                  if (netStat.bytes && netStat.Interface) {
                    agent.addMetrics({ ts: time, name: 'osnet', filters: [netStat.Interface || 'unknown'],
                      value: [calcDiff(netStat.Interface + 'tx', Number(netStat.bytes.Transmit)),
                        calcDiff(netStat.Interface + 'rx', Number(netStat.bytes.Receive))],
                      sct: 'OS'
                    })
                  }
                })
              }
            })
            linux.df(function dfMetrics (err, data) {
              if (err) {
                return logger.error('Error in df() for disk-usage metrics:' + err)
              }
              if (data && data.length > 0) {
                data.forEach(function (disk) {
                  if (/\/dev\/.+/i.test(disk.filesystem)) {
                    var dev = disk.filesystem.split('/')[2]
                    agent.addMetrics({ ts: time, name: 'osdf', filters: [dev],
                      value: [disk.available * 1024, disk.used * 1024],
                      sct: 'OS'
                    })
                  }
                })
              }
            })
            linux.vmstat(function (err, vmstat) {
              SpmAgent.Logger.debug('vmstat ', vmstat)
              if (err) {
                SpmAgent.Logger.error('error calling vmstat ' + err)
                return
              }
              linux.vmstatS(function (err, vmstats) {
                if (err) {
                  SpmAgent.Logger.error('error calling vmstat ' + err)
                  return
                }
                agent.addMetrics({
                  ts: time,
                  type: 'os',
                  name: 'osmem',
                  filters: '',
                  value: [vmstats.memory.used * 1024,
                    vmstats.memory.free * 1024,
                    vmstats.memory.cache * 1024,
                    vmstats.memory.buffer * 1024,
                    vmstat.swapd * 1024,
                    vmstat.si,
                    vmstat.so],
                  sct: 'OS'
                })
                if (vmstats.disks) {
                  try {
                    vmstats.disks.forEach(function (disk) {
                      agent.addMetrics({
                        ts: time,
                        type: 'os',
                        name: 'osdio',
                        filters: [disk.device],
                        value: [(calcDiff(disk.device + 'sectors_read', disk.sectors_read) * 512),
                          (calcDiff(disk.device + 'sectors_written', disk.sectors_written) * 512)],
                        sct: 'OS'
                      })
                    })
                  } catch (diskInfoErr) {
                    console.log(diskInfoErr)
                  }
                }
                var cpuTotal = 0
                var i = 0
                cpuProperties.forEach(function (property) {
                  // console.log ('CPU ' + property + ' ' + vmstats.cpu [property])
                  if (isNaN(Number(cpuLastValues[i][property]))) {
                    cpuLastValues[i][property] = 0
                  }
                  cpuLastValues[i][property] = Number(vmstats.cpu[property]) - Number(cpuLastValues[i][property])
                  cpuTotal = Number(cpuTotal) + Number(cpuLastValues[i][property])
                })
                agent.addMetrics({
                  ts: time,
                  type: 'os',
                  name: 'oscpu',
                  filters: '',
                  value: [(cpuLastValues[i].user / cpuTotal) * 100,
                    (cpuLastValues[i].nice / cpuTotal) * 100,
                    (cpuLastValues[i].system / cpuTotal) * 100,
                    (cpuLastValues[i].idle / cpuTotal) * 100,
                    (cpuLastValues[i].iowait / cpuTotal) * 100,
                    (cpuLastValues[i].irq / cpuTotal) * 100,
                    (cpuLastValues[i].softirq / cpuTotal) * 100,
                    (cpuLastValues[i].steal / cpuTotal) * 100],
                  sct: 'OS'
                })
              })
            })
          }
        }.bind(this), config.collectionInterval || 30000)
        if (timerId.unref) {
          timerId.unref()
        }
      }
    }
  }
  )
  return linuxAgent
}
<|endoftext|>


<commit_before>var express = require('express');
var playsApp = require('radio-plays');
var streamManager = require('stream-data');
var logfmt = require("logfmt");
var app = express();
var http = require('http');
var moment = require('moment');
var googleapis = require('googleapis');
var pg = require('pg');
var google_tokens = null;

var plays = playsApp({
	source: 'Spinitron',
	spinitron: {
		station: process.env.SPIN_STATION,
		userid: process.env.SPIN_USERID,
		secret: process.env.SPIN_SECRET
	},
	maxAge: Number(process.env.CACHE_TIME || 15000)
});

var OAuth2 = googleapis.auth.OAuth2;
var auth = new OAuth2(
	process.env.GOOGLE_CLIENT_ID,
	process.env.GOOGLE_CLIENT_SECRET,
	process.env.GOOGLE_REDIRECT_URL
);
googleapis.options({ auth: auth });
var calendar = googleapis.calendar('v3');

var schedule = {
	timestamp: 0,
	events: {},
	current: {},
	v3: {}
};

var isStale = function(timestamp) {
	diff = new Date() - timestamp;
	if (diff > 15000) {
		return true;
	}
	return false;
}

var processGCalV3 = function (response) {
	var events = response.items;
	var newEvents = [];
	var now = moment();
	for (i in events) {
		var e = {
			title: events[i].summary,
			content: '',
			startTime: events[i].start.dateTime,
			endTime: events[i].end.dateTime
		}

		var startMoment = moment(e.startTime);
		var endMoment = moment(e.endTime);

		if (startMoment.isBefore(now) && now.isBefore(endMoment)) {
			schedule.current = e;
		}
		newEvents.push(e);
	}
	schedule.events = newEvents;
	schedule.timestamp = new Date();
}

var getSchedule = function() {
	if (isStale(schedule.timestamp)) {
		console.log('Fetching new calendar');

		schedule.events = [];
		schedule.timestamp = new Date();
		calendar.events.list({
			'calendarId': process.env.SCHEDULE_ID,
			'singleEvents': true,
			'orderBy': 'startTime',
			'timeMin': schedule.timestamp.toISOString()
			//'timeMin': schedule.timestamp
		}, function (err, response) {
			if (!err) {
				processGCalV3(response);
			} else {
				console.log("Got calendar error: ", err);
			}
		});
	}
}

var streams = streamManager({});

app.use(logfmt.requestLogger());

pg.connect(process.env.DATABASE_URL, function(err, client) {
  if(err) {
    return console.error('could not connect to postgres', err);
  }
  client.query('CREATE TABLE IF NOT EXISTS tokens (\
  	ID INT PRIMARY KEY NOT NULL,\
  	REFRESH TEXT NOT NULL,\
  	ACCESS TEXT NOT NULL)', function(err, result) {
    if(err) {
      return console.error('error running query', err);
    }
    client.end();
  });

  client.query('SELECT * FROM tokens', function(err, result) {
    if(err) {
      return console.error('error running token query', err);
    }
    if (result.rows.length > 0) {
		google_tokens = {
			access_token = result.rows[0].ACCESS,
			refresh_token = result.rows[0].REFRESH
		}
		auth.setCredentials(google_tokens);
		getSchedule();
    }
    client.end();
  });
});

app.get('/nowplaying', function(req, res){
	res.jsonp(plays.recentPlays(1)[0]);
});

app.get('/recentplays/:num', function(req, res){
	res.jsonp(plays.recentPlays(Number(req.params.num)));
});

app.get('/streams', function(req, res){
	res.jsonp(streams.streams());
});

app.get('/schedule', function(req, res){
	getSchedule();
	res.jsonp(schedule);
});

app.get('/api_auth', function(req, res){
	if (google_tokens == null) {
		var url = auth.generateAuthUrl({
		  access_type: 'offline',
		  scope: process.env.GOOGLE_SCOPE
		});
		res.redirect(url);
	} else {
		// We've already authenticated.
		res.redirect('/schedule');
	}
});

app.get(process.env.GOOGLE_REDIRECT_PATH, function(req, res){
	auth.getToken(req.query.code, function(err, tokens) {

		if(!err) {
			auth.setCredentials(tokens);
			google_tokens = tokens;

			// Save tokens to database
			pg.connect(process.env.DATABASE_URL, function(err, client) {
				if(err) {
					return console.error('could not connect to postgres', err);
				}

				client.query('TRUNCATE TABLE tokens', function(err, result) {
					if(err) {
						return console.error('error truncating token table', err);
					}
					client.end();
				});
				client.query('INSERT INTO tokens (ACCESS, REFRESH) VALUES($1, $2)',
				[tokens.access_token, tokens.refresh_token], function(err, result) {
					if(err) {
						return console.error('error saving tokens', err);
					}
					client.end();
				});
			});

			res.redirect('/schedule');
		} else {
			console.error('error getting auth tokens', err);
		}
	});
});

var port = Number(process.env.PORT || 3000);
var server = app.listen(port, function() {
    console.log('Listening on port %d', server.address().port);
});
<commit_msg>Fix typo.<commit_after>var express = require('express');
var playsApp = require('radio-plays');
var streamManager = require('stream-data');
var logfmt = require("logfmt");
var app = express();
var http = require('http');
var moment = require('moment');
var googleapis = require('googleapis');
var pg = require('pg');
var google_tokens = null;

var plays = playsApp({
	source: 'Spinitron',
	spinitron: {
		station: process.env.SPIN_STATION,
		userid: process.env.SPIN_USERID,
		secret: process.env.SPIN_SECRET
	},
	maxAge: Number(process.env.CACHE_TIME || 15000)
});

var OAuth2 = googleapis.auth.OAuth2;
var auth = new OAuth2(
	process.env.GOOGLE_CLIENT_ID,
	process.env.GOOGLE_CLIENT_SECRET,
	process.env.GOOGLE_REDIRECT_URL
);
googleapis.options({ auth: auth });
var calendar = googleapis.calendar('v3');

var schedule = {
	timestamp: 0,
	events: {},
	current: {},
	v3: {}
};

var isStale = function(timestamp) {
	diff = new Date() - timestamp;
	if (diff > 15000) {
		return true;
	}
	return false;
}

var processGCalV3 = function (response) {
	var events = response.items;
	var newEvents = [];
	var now = moment();
	for (i in events) {
		var e = {
			title: events[i].summary,
			content: '',
			startTime: events[i].start.dateTime,
			endTime: events[i].end.dateTime
		}

		var startMoment = moment(e.startTime);
		var endMoment = moment(e.endTime);

		if (startMoment.isBefore(now) && now.isBefore(endMoment)) {
			schedule.current = e;
		}
		newEvents.push(e);
	}
	schedule.events = newEvents;
	schedule.timestamp = new Date();
}

var getSchedule = function() {
	if (isStale(schedule.timestamp)) {
		console.log('Fetching new calendar');

		schedule.events = [];
		schedule.timestamp = new Date();
		calendar.events.list({
			'calendarId': process.env.SCHEDULE_ID,
			'singleEvents': true,
			'orderBy': 'startTime',
			'timeMin': schedule.timestamp.toISOString()
			//'timeMin': schedule.timestamp
		}, function (err, response) {
			if (!err) {
				processGCalV3(response);
			} else {
				console.log("Got calendar error: ", err);
			}
		});
	}
}

var streams = streamManager({});

app.use(logfmt.requestLogger());

pg.connect(process.env.DATABASE_URL, function(err, client) {
  if(err) {
    return console.error('could not connect to postgres', err);
  }
  client.query('CREATE TABLE IF NOT EXISTS tokens (\
  	ID INT PRIMARY KEY NOT NULL,\
  	REFRESH TEXT NOT NULL,\
  	ACCESS TEXT NOT NULL)', function(err, result) {
    if(err) {
      return console.error('error running query', err);
    }
    client.end();
  });

  client.query('SELECT * FROM tokens', function(err, result) {
    if(err) {
      return console.error('error running token query', err);
    }
    if (result.rows.length > 0) {
		google_tokens = {
			access_token: result.rows[0].ACCESS,
			refresh_token: result.rows[0].REFRESH
		}
		auth.setCredentials(google_tokens);
		getSchedule();
    }
    client.end();
  });
});

app.get('/nowplaying', function(req, res){
	res.jsonp(plays.recentPlays(1)[0]);
});

app.get('/recentplays/:num', function(req, res){
	res.jsonp(plays.recentPlays(Number(req.params.num)));
});

app.get('/streams', function(req, res){
	res.jsonp(streams.streams());
});

app.get('/schedule', function(req, res){
	getSchedule();
	res.jsonp(schedule);
});

app.get('/api_auth', function(req, res){
	if (google_tokens == null) {
		var url = auth.generateAuthUrl({
		  access_type: 'offline',
		  scope: process.env.GOOGLE_SCOPE
		});
		res.redirect(url);
	} else {
		// We've already authenticated.
		res.redirect('/schedule');
	}
});

app.get(process.env.GOOGLE_REDIRECT_PATH, function(req, res){
	auth.getToken(req.query.code, function(err, tokens) {

		if(!err) {
			auth.setCredentials(tokens);
			google_tokens = tokens;

			// Save tokens to database
			pg.connect(process.env.DATABASE_URL, function(err, client) {
				if(err) {
					return console.error('could not connect to postgres', err);
				}

				client.query('TRUNCATE TABLE tokens', function(err, result) {
					if(err) {
						return console.error('error truncating token table', err);
					}
					client.end();
				});
				client.query('INSERT INTO tokens (ACCESS, REFRESH) VALUES($1, $2)',
				[tokens.access_token, tokens.refresh_token], function(err, result) {
					if(err) {
						return console.error('error saving tokens', err);
					}
					client.end();
				});
			});

			res.redirect('/schedule');
		} else {
			console.error('error getting auth tokens', err);
		}
	});
});

var port = Number(process.env.PORT || 3000);
var server = app.listen(port, function() {
    console.log('Listening on port %d', server.address().port);
});
<|endoftext|>


<commit_before>var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var cors = require('cors')

var routes = require('./routes/index');
var mapStateRouter = require('./routes/mapstate');
var errors = require('./routes/errors');
var conf = require('./conf/config');

var app = express();

var server = app.listen(3001, function () {
  var host = server.address().address
  var port = server.address().port

  console.log('Origo server listening at http://%s:%s', host, port)
});

//Workaround to set __dirname properly when using node-windows
process.chdir(__dirname);

var handlebars = require('express-handlebars')
    .create({defaultLayout: 'main'});
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
app.set('views', path.join(__dirname, 'views'));

// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(bodyParser.json({limit: '5mb'}));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
if (conf['cors']) {
  var configOptions = Object.assign({}, conf['cors']);
  var corsOptions = {};
  // Configures the Access-Control-Allow-Origin CORS header.
  if ('origin' in configOptions) {
    corsOptions['origin'] = configOptions.origin;
  }
  // Configures the Access-Control-Allow-Methods CORS header.
  if ('methods' in configOptions) {
    corsOptions['methods'] = configOptions.methods;
  }
  // Configures the Access-Control-Allow-Headers CORS header.
  if ('headers' in configOptions) {
    corsOptions['allowedHeaders'] = configOptions.headers;
  }
  // Configures the Access-Control-Allow-Credentials CORS header.
  if ('credentials' in configOptions) {
    corsOptions['credentials'] = configOptions.credentials;
  }
  // Some legacy browsers (IE11, various SmartTVs) choke on 204
  if ('optionsSuccessStatus' in configOptions) {
    corsOptions['optionsSuccessStatus'] = configOptions.optionsSuccessStatus;
  }
  app.use(cors(corsOptions));
}

app.use('/origoserver/', routes);
app.use('/mapstate', mapStateRouter);
app.use(errors);

module.exports = app;
<commit_msg>Set Express json limit<commit_after>var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var cors = require('cors')

var routes = require('./routes/index');
var mapStateRouter = require('./routes/mapstate');
var errors = require('./routes/errors');
var conf = require('./conf/config');

var app = express();

var server = app.listen(3001, function () {
  var host = server.address().address
  var port = server.address().port

  console.log('Origo server listening at http://%s:%s', host, port)
});

//Workaround to set __dirname properly when using node-windows
process.chdir(__dirname);

var handlebars = require('express-handlebars')
    .create({defaultLayout: 'main'});
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
app.set('views', path.join(__dirname, 'views'));

// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(bodyParser.json({limit: "5mb"}));
app.use(bodyParser.urlencoded({limit: "5mb", extended: true, parameterLimit:50000}));
app.use(express.json({limit: '5mb'}));
app.use(express.urlencoded({limit: '5mb', extended: true, parameterLimit:50000}));
app.use(express.static(path.join(__dirname, 'public')));
if (conf['cors']) {
  var configOptions = Object.assign({}, conf['cors']);
  var corsOptions = {};
  // Configures the Access-Control-Allow-Origin CORS header.
  if ('origin' in configOptions) {
    corsOptions['origin'] = configOptions.origin;
  }
  // Configures the Access-Control-Allow-Methods CORS header.
  if ('methods' in configOptions) {
    corsOptions['methods'] = configOptions.methods;
  }
  // Configures the Access-Control-Allow-Headers CORS header.
  if ('headers' in configOptions) {
    corsOptions['allowedHeaders'] = configOptions.headers;
  }
  // Configures the Access-Control-Allow-Credentials CORS header.
  if ('credentials' in configOptions) {
    corsOptions['credentials'] = configOptions.credentials;
  }
  // Some legacy browsers (IE11, various SmartTVs) choke on 204
  if ('optionsSuccessStatus' in configOptions) {
    corsOptions['optionsSuccessStatus'] = configOptions.optionsSuccessStatus;
  }
  app.use(cors(corsOptions));
}

app.use('/origoserver/', routes);
app.use('/mapstate', mapStateRouter);
app.use(errors);

module.exports = app;
<|endoftext|>


<commit_before>// This software is free software. See AUTHORS and LICENSE for more
// information on the copying conditions.

function drawCompliance(title, result) { // XXX Very naive impl.
    var html = "
" + title + "

";
    for (var i = 0; i < result.length; ++i) {
        html += "
";
        html += result[i][0];
        html += "	";
        html += result[i][1];
        html += "	";
        html += result[i][2];
        html += "	";
        html += result[i][3];
        html += "
";
    }
    html += "
";
    jQuery("#university").html(html);
}

function getUniversity(universityId, callback) {
    jQuery.get({
        url: "/id/eprint/" + universityId,
        success: callback
    });
    return false;
}

function parseUrl(url) { // See https://gist.github.com/jlong/2428561
    var parser = document.createElement('a');
    parser.href = url;
    return parser;
}

function doClick(title, eprintid) {
    getUniversity(eprintid, function (result) {
        drawCompliance(title, result);
    });
}

function drawSearchResult(result) {
    var html = "
";
    for (var i = 0; i < result.length; ++i) {
        html += "
";
        html += ''
            + result[i].title + "";
        html += "
";
    }
    html += "
";
    jQuery("#search-result").html(html);
    jQuery("#university").html("");
}

function searchUniversity(terms, cb) {
    jQuery.get({
        url: "/cgi/search/simple?output=JSON&q=" + encodeURIComponent(terms),
        success: cb
    });
}

jQuery("load", function () {
    jQuery("#search").click(function () {
        searchUniversity(jQuery("#search-terms").val(), drawSearchResult);
    });
});
<commit_msg>Make sure we quote input<commit_after>// This software is free software. See AUTHORS and LICENSE for more
// information on the copying conditions.

function escapeHtml(unsafe) { // See http://stackoverflow.com/questions/6234773
    unsafe = unsafe + "";
    return unsafe
         .replace(/&/g, "&")
         .replace(/</g, "<")
         .replace(/>/g, ">")
         .replace(/"/g, """)
         .replace(/'/g, "'");
}

function drawCompliance(title, result) {
    var html = "
" + escapeHtml(title) + "

";
    for (var i = 0; i < result.length; ++i) {
        html += "
";
        html += escapeHtml(result[i][0]);
        html += "	";
        html += escapeHtml(result[i][1]);
        html += "	";
        html += escapeHtml(result[i][2]);
        html += "	";
        html += escapeHtml(result[i][3]);
        html += "
";
    }
    html += "
";
    jQuery("#university").html(html);
}

function getUniversity(universityId, callback) {
    jQuery.get({
        url: "/id/eprint/" + universityId,
        success: callback
    });
    return false;
}

function parseUrl(url) { // See https://gist.github.com/jlong/2428561
    var parser = document.createElement('a');
    parser.href = url;
    return parser;
}

function doClick(title, eprintid) {
    getUniversity(eprintid, function (result) {
        drawCompliance(title, result);
    });
}

function drawSearchResult(result) {
    var html = "
";
    for (var i = 0; i < result.length; ++i) {
        html += "
";
        html += '';
        html += "
";
    }
    html += "
";
    jQuery("#search-result").html(html);
    jQuery("#university").html("");
    for (i = 0; i < result.length; ++i) {
        jQuery("#result-" + i).text(result[i].title);
        jQuery("#result-" + i).attr("eprintid", result[i].eprintid);
        jQuery("#result-" + i).click(function () {
            console.log(this);
            doClick(jQuery(this).text(), jQuery(this).attr("eprintid"));
        });
    }
}

function searchUniversity(terms, cb) {
    jQuery.get({
        url: "/cgi/search/simple?output=JSON&q=" + encodeURIComponent(terms),
        success: cb
    });
}

jQuery("load", function () {
    jQuery("#search").click(function () {
        searchUniversity(jQuery("#search-terms").val(), drawSearchResult);
    });
});
<|endoftext|>


<commit_before>var http = require('http');

http.createServer(function (request, response) {
    response.writeHead(200, {'Content-Type': 'text/plain'});
    response.end('Hello World\n');
}).listen(8080);

console.log('Server started');<commit_msg>newcommit<commit_after>var http = require('http');

http.createServer(function (request, response) {
    response.writeHead(800, {'Content-Type': 'text/plain'});
    response.end('Hello World new test\n');
}).listen(8080);

console.log('Server started');<|endoftext|>


<commit_before>'use strict';

var chai = require('chai');
var expect = chai.expect;

//var http = require('http');
var Biskviit = require('../lib/biskviit');

chai.config.includeStack = true;

describe('Biskviit Unit Tests', function() {
    var biskviit;

    beforeEach(function() {
        biskviit = new Biskviit();
    });

    describe('#getPath', function() {

        it('should return root path', function() {
            expect(biskviit.getPath('/')).to.equal('/');
            expect(biskviit.getPath('')).to.equal('/');
            expect(biskviit.getPath('/index.php')).to.equal('/');
        });

        it('should return without file', function() {
            expect(biskviit.getPath('/path/to/file')).to.equal('/path/to/');
        });

    });

    describe('#isExpired', function() {
        it('should match expired cookie', function() {
            expect(biskviit.isExpired({
                name: 'a',
                value: 'b',
                expires: new Date(Date.now() + 10000)
            })).to.be.false;

            expect(biskviit.isExpired({
                name: 'a',
                value: '',
                expires: new Date(Date.now() + 10000)
            })).to.be.true;

            expect(biskviit.isExpired({
                name: 'a',
                value: 'b',
                expires: new Date(Date.now() - 10000)
            })).to.be.true;
        });
    });

    describe('#compare', function() {
        it('should match similar cookies', function() {
            expect(biskviit.compare({
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            }, {
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            })).to.be.true;

            expect(biskviit.compare({
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            }, {
                name: 'yyy',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            })).to.be.false;

            expect(biskviit.compare({
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            }, {
                name: 'zzz',
                path: '/amp',
                domain: 'example.com',
                secure: false,
                httponly: false
            })).to.be.false;

            expect(biskviit.compare({
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            }, {
                name: 'zzz',
                path: '/',
                domain: 'examples.com',
                secure: false,
                httponly: false
            })).to.be.false;

            expect(biskviit.compare({
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            }, {
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: true,
                httponly: false
            })).to.be.false;
        });
    });

    describe('#add', function() {
        it('should append new cookie', function() {
            expect(biskviit.cookies.length).to.equal(0);
            biskviit.add({
                name: 'zzz',
                value: 'abc',
                path: '/',
                expires: new Date(Date.now() + 10000),
                domain: 'example.com',
                secure: false,
                httponly: false
            });
            expect(biskviit.cookies.length).to.equal(1);
            expect(biskviit.cookies[0].name).to.equal('zzz');
            expect(biskviit.cookies[0].value).to.equal('abc');
        });

        it('should update existing cookie', function() {
            expect(biskviit.cookies.length).to.equal(0);
            biskviit.add({
                name: 'zzz',
                value: 'abc',
                path: '/',
                expires: new Date(Date.now() + 10000),
                domain: 'example.com',
                secure: false,
                httponly: false
            });
            biskviit.add({
                name: 'zzz',
                value: 'def',
                path: '/',
                expires: new Date(Date.now() + 10000),
                domain: 'example.com',
                secure: false,
                httponly: false
            });
            expect(biskviit.cookies.length).to.equal(1);
            expect(biskviit.cookies[0].name).to.equal('zzz');
            expect(biskviit.cookies[0].value).to.equal('def');
        });
    });

    describe('#match', function() {
        it('should check if a cookie matches particular domain and path', function() {
            var cookie = {
                name: 'zzz',
                value: 'abc',
                path: '/def/',
                expires: new Date(Date.now() + 10000),
                domain: 'example.com',
                secure: false,
                httponly: false
            };
            expect(biskviit.match(cookie, 'http://example.com/def/')).to.be.true;
            expect(biskviit.match(cookie, 'http://example.com/bef/')).to.be.false;
        });

        it('should check if a cookie matches particular domain and path', function() {
            var cookie = {
                name: 'zzz',
                value: 'abc',
                path: '/def',
                expires: new Date(Date.now() + 10000),
                domain: 'example.com',
                secure: false,
                httponly: false
            };
            expect(biskviit.match(cookie, 'http://example.com/def/')).to.be.true;
            expect(biskviit.match(cookie, 'http://example.com/bef/')).to.be.false;
        });

        it('should check if a cookie is secure', function() {
            var cookie = {
                name: 'zzz',
                value: 'abc',
                path: '/def/',
                expires: new Date(Date.now() + 10000),
                domain: 'example.com',
                secure: true,
                httponly: false
            };
            expect(biskviit.match(cookie, 'https://example.com/def/')).to.be.true;
            expect(biskviit.match(cookie, 'http://example.com/def/')).to.be.false;
        });
    });

    describe('#parse', function() {
        it('should parse Set-Cookie value', function() {

            expect(biskviit.parse('theme=plain')).to.deep.equal({
                name: 'theme',
                value: 'plain'
            });

            expect(biskviit.parse('SSID=Ap4P….GTEq; Domain=foo.com; Path=/; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly')).to.deep.equal({
                name: 'ssid',
                value: 'Ap4P….GTEq',
                domain: '.foo.com',
                path: '/',
                httponly: true,
                secure: true,
                expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
            });

        });

        it('should ignore invalid expire header', function() {
            expect(biskviit.parse('theme=plain; Expires=Wed, 13 Jan 2021 22:23:01 GMT')).to.deep.equal({
                name: 'theme',
                value: 'plain',
                expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
            });

            expect(biskviit.parse('theme=plain; Expires=ZZZZZZZZ GMT')).to.deep.equal({
                name: 'theme',
                value: 'plain'
            });
        });
    });

    describe('Listing', function() {
        beforeEach(function() {
            biskviit.cookies = [{
                name: 'ssid1',
                value: 'Ap4P….GTEq1',
                domain: '.foo.com',
                path: '/',
                httponly: true,
                secure: true,
                expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
            }, {
                name: 'ssid2',
                value: 'Ap4P….GTEq2',
                domain: '.foo.com',
                path: '/',
                httponly: true,
                secure: true,
                expires: new Date('Wed, 13 Jan 1900 22:23:01 GMT')
            }, {
                name: 'ssid3',
                value: 'Ap4P….GTEq3',
                domain: 'foo.com',
                path: '/',
                httponly: true,
                secure: true,
                expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
            }, {
                name: 'ssid4',
                value: 'Ap4P….GTEq4',
                domain: 'www.foo.com',
                path: '/',
                httponly: true,
                secure: true,
                expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
            }, {
                name: 'ssid5',
                value: 'Ap4P….GTEq5',
                domain: 'broo.com',
                path: '/',
                httponly: true,
                secure: true,
                expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
            }];
        });

        describe('#list', function() {
            it('should return matching cookies for an URL', function() {
                expect(biskviit.list('https://www.foo.com')).to.deep.equal([{
                    name: 'ssid1',
                    value: 'Ap4P….GTEq1',
                    domain: '.foo.com',
                    path: '/',
                    httponly: true,
                    secure: true,
                    expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
                }, {
                    name: 'ssid4',
                    value: 'Ap4P….GTEq4',
                    domain: 'www.foo.com',
                    path: '/',
                    httponly: true,
                    secure: true,
                    expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
                }]);
            });
        });

        describe('#get', function() {
            it('should return matching cookies for an URL', function() {
                expect(biskviit.get('https://www.foo.com')).to.equal('ssid1=Ap4P….GTEq1; ssid4=Ap4P….GTEq4');
            });
        });
    });

    describe('#set', function() {
        it('should set cookie', function() {
            // short
            biskviit.set('theme=plain', 'https://foo.com/');
            // long
            biskviit.set('SSID=Ap4P….GTEq; Domain=foo.com; Path=/test; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly', 'https://foo.com/');
            // subdomains
            biskviit.set('SSID=Ap4P….GTEq; Domain=.foo.com; Path=/; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly', 'https://www.foo.com/');
            // invalid cors
            biskviit.set('invalid_1=cors; domain=example.com', 'https://foo.com/');
            biskviit.set('invalid_2=cors; domain=www.foo.com', 'https://foo.com/');
            // invalid date
            biskviit.set('invalid_3=date; Expires=zzzz', 'https://foo.com/');

            // should not be added
            biskviit.set('expired_1=date; Expires=1999-01-01 01:01:01 GMT', 'https://foo.com/');

            expect(biskviit.cookies.map(function(cookie) {
                delete cookie.expires;
                return cookie;
            })).to.deep.equal([{
                name: 'theme',
                value: 'plain',
                domain: 'foo.com',
                path: '/'
            }, {
                name: 'ssid',
                value: 'Ap4P….GTEq',
                domain: 'foo.com',
                path: '/test',
                secure: true,
                httponly: true
            }, {
                name: 'ssid',
                value: 'Ap4P….GTEq',
                domain: 'www.foo.com',
                path: '/',
                secure: true,
                httponly: true
            }, {
                name: 'invalid_1',
                value: 'cors',
                domain: 'foo.com',
                path: '/'
            }, {
                name: 'invalid_2',
                value: 'cors',
                domain: 'foo.com',
                path: '/'
            }, {
                name: 'invalid_3',
                value: 'date',
                domain: 'foo.com',
                path: '/'
            }]);
        });
    });

});<commit_msg>Updated tests<commit_after>'use strict';

var chai = require('chai');
var expect = chai.expect;

//var http = require('http');
var Biskviit = require('../lib/biskviit');

chai.config.includeStack = true;

describe('Biskviit Unit Tests', function() {
    var biskviit;

    beforeEach(function() {
        biskviit = new Biskviit();
    });

    describe('#getPath', function() {

        it('should return root path', function() {
            expect(biskviit.getPath('/')).to.equal('/');
            expect(biskviit.getPath('')).to.equal('/');
            expect(biskviit.getPath('/index.php')).to.equal('/');
        });

        it('should return without file', function() {
            expect(biskviit.getPath('/path/to/file')).to.equal('/path/to/');
        });

    });

    describe('#isExpired', function() {
        it('should match expired cookie', function() {
            expect(biskviit.isExpired({
                name: 'a',
                value: 'b',
                expires: new Date(Date.now() + 10000)
            })).to.be.false;

            expect(biskviit.isExpired({
                name: 'a',
                value: '',
                expires: new Date(Date.now() + 10000)
            })).to.be.true;

            expect(biskviit.isExpired({
                name: 'a',
                value: 'b',
                expires: new Date(Date.now() - 10000)
            })).to.be.true;
        });
    });

    describe('#compare', function() {
        it('should match similar cookies', function() {
            expect(biskviit.compare({
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            }, {
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            })).to.be.true;

            expect(biskviit.compare({
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            }, {
                name: 'yyy',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            })).to.be.false;

            expect(biskviit.compare({
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            }, {
                name: 'zzz',
                path: '/amp',
                domain: 'example.com',
                secure: false,
                httponly: false
            })).to.be.false;

            expect(biskviit.compare({
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            }, {
                name: 'zzz',
                path: '/',
                domain: 'examples.com',
                secure: false,
                httponly: false
            })).to.be.false;

            expect(biskviit.compare({
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: false,
                httponly: false
            }, {
                name: 'zzz',
                path: '/',
                domain: 'example.com',
                secure: true,
                httponly: false
            })).to.be.false;
        });
    });

    describe('#add', function() {
        it('should append new cookie', function() {
            expect(biskviit.cookies.length).to.equal(0);
            biskviit.add({
                name: 'zzz',
                value: 'abc',
                path: '/',
                expires: new Date(Date.now() + 10000),
                domain: 'example.com',
                secure: false,
                httponly: false
            });
            expect(biskviit.cookies.length).to.equal(1);
            expect(biskviit.cookies[0].name).to.equal('zzz');
            expect(biskviit.cookies[0].value).to.equal('abc');
        });

        it('should update existing cookie', function() {
            expect(biskviit.cookies.length).to.equal(0);
            biskviit.add({
                name: 'zzz',
                value: 'abc',
                path: '/',
                expires: new Date(Date.now() + 10000),
                domain: 'example.com',
                secure: false,
                httponly: false
            });
            biskviit.add({
                name: 'zzz',
                value: 'def',
                path: '/',
                expires: new Date(Date.now() + 10000),
                domain: 'example.com',
                secure: false,
                httponly: false
            });
            expect(biskviit.cookies.length).to.equal(1);
            expect(biskviit.cookies[0].name).to.equal('zzz');
            expect(biskviit.cookies[0].value).to.equal('def');
        });
    });

    describe('#match', function() {
        it('should check if a cookie matches particular domain and path', function() {
            var cookie = {
                name: 'zzz',
                value: 'abc',
                path: '/def/',
                expires: new Date(Date.now() + 10000),
                domain: 'example.com',
                secure: false,
                httponly: false
            };
            expect(biskviit.match(cookie, 'http://example.com/def/')).to.be.true;
            expect(biskviit.match(cookie, 'http://example.com/bef/')).to.be.false;
        });

        it('should check if a cookie matches particular domain and path', function() {
            var cookie = {
                name: 'zzz',
                value: 'abc',
                path: '/def',
                expires: new Date(Date.now() + 10000),
                domain: 'example.com',
                secure: false,
                httponly: false
            };
            expect(biskviit.match(cookie, 'http://example.com/def/')).to.be.true;
            expect(biskviit.match(cookie, 'http://example.com/bef/')).to.be.false;
        });

        it('should check if a cookie is secure', function() {
            var cookie = {
                name: 'zzz',
                value: 'abc',
                path: '/def/',
                expires: new Date(Date.now() + 10000),
                domain: 'example.com',
                secure: true,
                httponly: false
            };
            expect(biskviit.match(cookie, 'https://example.com/def/')).to.be.true;
            expect(biskviit.match(cookie, 'http://example.com/def/')).to.be.false;
        });
    });

    describe('#parse', function() {
        it('should parse Set-Cookie value', function() {

            expect(biskviit.parse('theme=plain')).to.deep.equal({
                name: 'theme',
                value: 'plain'
            });

            expect(biskviit.parse('SSID=Ap4P….GTEq; Domain=foo.com; Path=/; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly')).to.deep.equal({
                name: 'ssid',
                value: 'Ap4P….GTEq',
                domain: '.foo.com',
                path: '/',
                httponly: true,
                secure: true,
                expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
            });

        });

        it('should ignore invalid expire header', function() {
            expect(biskviit.parse('theme=plain; Expires=Wed, 13 Jan 2021 22:23:01 GMT')).to.deep.equal({
                name: 'theme',
                value: 'plain',
                expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
            });

            expect(biskviit.parse('theme=plain; Expires=ZZZZZZZZ GMT')).to.deep.equal({
                name: 'theme',
                value: 'plain'
            });
        });
    });

    describe('Listing', function() {
        beforeEach(function() {
            biskviit.cookies = [{
                name: 'ssid1',
                value: 'Ap4P….GTEq1',
                domain: '.foo.com',
                path: '/',
                httponly: true,
                secure: true,
                expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
            }, {
                name: 'ssid2',
                value: 'Ap4P….GTEq2',
                domain: '.foo.com',
                path: '/',
                httponly: true,
                secure: true,
                expires: new Date('Wed, 13 Jan 1900 22:23:01 GMT')
            }, {
                name: 'ssid3',
                value: 'Ap4P….GTEq3',
                domain: 'foo.com',
                path: '/',
                httponly: true,
                secure: true,
                expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
            }, {
                name: 'ssid4',
                value: 'Ap4P….GTEq4',
                domain: 'www.foo.com',
                path: '/',
                httponly: true,
                secure: true,
                expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
            }, {
                name: 'ssid5',
                value: 'Ap4P….GTEq5',
                domain: 'broo.com',
                path: '/',
                httponly: true,
                secure: true,
                expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
            }];
        });

        describe('#list', function() {
            it('should return matching cookies for an URL', function() {
                expect(biskviit.list('https://www.foo.com')).to.deep.equal([{
                    name: 'ssid1',
                    value: 'Ap4P….GTEq1',
                    domain: '.foo.com',
                    path: '/',
                    httponly: true,
                    secure: true,
                    expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
                }, {
                    name: 'ssid4',
                    value: 'Ap4P….GTEq4',
                    domain: 'www.foo.com',
                    path: '/',
                    httponly: true,
                    secure: true,
                    expires: new Date('Wed, 13 Jan 2021 22:23:01 GMT')
                }]);
            });
        });

        describe('#get', function() {
            it('should return matching cookies for an URL', function() {
                expect(biskviit.get('https://www.foo.com')).to.equal('ssid1=Ap4P….GTEq1; ssid4=Ap4P….GTEq4');
            });
        });
    });

    describe('#set', function() {
        it('should set cookie', function() {
            // short
            biskviit.set('theme=plain', 'https://foo.com/');
            // long
            biskviit.set('SSID=Ap4P….GTEq; Domain=foo.com; Path=/test; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly', 'https://foo.com/');
            // subdomains
            biskviit.set('SSID=Ap4P….GTEq; Domain=.foo.com; Path=/; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly', 'https://www.foo.com/');
            // invalid cors
            biskviit.set('invalid_1=cors; domain=example.com', 'https://foo.com/');
            biskviit.set('invalid_2=cors; domain=www.foo.com', 'https://foo.com/');
            // invalid date
            biskviit.set('invalid_3=date; Expires=zzzz', 'https://foo.com/');
            // invalid tld
            biskviit.set('invalid_4=cors; domain=.co.uk', 'https://foo.co.uk/');
            // should not be added
            biskviit.set('expired_1=date; Expires=1999-01-01 01:01:01 GMT', 'https://foo.com/');

            expect(biskviit.cookies.map(function(cookie) {
                delete cookie.expires;
                return cookie;
            })).to.deep.equal([{
                name: 'theme',
                value: 'plain',
                domain: 'foo.com',
                path: '/'
            }, {
                name: 'ssid',
                value: 'Ap4P….GTEq',
                domain: 'foo.com',
                path: '/test',
                secure: true,
                httponly: true
            }, {
                name: 'ssid',
                value: 'Ap4P….GTEq',
                domain: 'www.foo.com',
                path: '/',
                secure: true,
                httponly: true
            }, {
                name: 'invalid_1',
                value: 'cors',
                domain: 'foo.com',
                path: '/'
            }, {
                name: 'invalid_2',
                value: 'cors',
                domain: 'foo.com',
                path: '/'
            }, {
                name: 'invalid_3',
                value: 'date',
                domain: 'foo.com',
                path: '/'
            }, {
                name: 'invalid_4',
                value: 'cors',
                domain: 'foo.co.uk',
                path: '/'
            }]);
        });
    });

});<|endoftext|>


<commit_before>/*
 * MelonJS Game Engine
 * Copyright (C) 2011 - 2015, Olivier Biot, Jason Oster, Aaron McLeod
 * http://www.melonjs.org
 *
 */

(function () {

    /**
     * a Generic Body Object

     * @class
     * @extends me.Rect
     * @memberOf me
     * @constructor
     * @param {me.Entity} entity the parent entity
     * @param {me.Polygon[]|me.Line[]|me.Ellipse[]} [shapes] the initial list of shapes
     */
    me.Body = me.Rect.extend(
    /** @scope me.Body.prototype */
    {
        /** @ignore */
        init : function (entity, shapes) {

            /**
             * reference to the parent entity
             * @ignore
             */
            this.entity = entity;

            /**
             * The collision shapes of the entity

             * @ignore
             * @type {me.Polygon[]|me.Line[]|me.Ellipse[]}
             * @name shapes
             * @memberOf me.Body
             */
            this.shapes = [];

            /**
             * The body collision mask, that defines what should collide with what.

             * (by default will collide with all entities)
             * @ignore
             * @type Number
             * @default me.collision.types.ALL_OBJECT
             * @name collisionMask
             * @see me.collision.types
             * @memberOf me.Body
             */
            this.collisionMask = me.collision.types.ALL_OBJECT;

            /**
             * define the collision type of the body for collision filtering
             * @public
             * @type Number
             * @default me.collision.types.ENEMY_OBJECT
             * @name collisionType
             * @see me.collision.types
             * @memberOf me.Body
             * @example
             * // set the entity body collision type
             * myEntity.body.collisionType = me.collision.types.PLAYER_OBJECT;
             */
            this.collisionType = me.collision.types.ENEMY_OBJECT;

            /**
             * entity current velocity

             * @public
             * @type me.Vector2d
             * @default <0,0>
             * @name vel
             * @memberOf me.Body
             */
            if (typeof(this.vel) === "undefined") {
                this.vel = new me.Vector2d();
            }
            this.vel.set(0, 0);

            /**
             * entity current acceleration

             * @public
             * @type me.Vector2d
             * @default <0,0>
             * @name accel
             * @memberOf me.Body
             */
            if (typeof(this.accel) === "undefined") {
                this.accel = new me.Vector2d();
            }
            this.accel.set(0, 0);

            /**
             * entity current friction

             * @public
             * @type me.Vector2d
             * @default <0,0>
             * @name friction
             * @memberOf me.Body
             */
            if (typeof(this.friction) === "undefined") {
                this.friction = new me.Vector2d();
            }
            this.friction.set(0, 0);

            /**
             * max velocity (to limit entity velocity)

             * @public
             * @type me.Vector2d
             * @default <1000,1000>
             * @name maxVel
             * @memberOf me.Body
             */
            if (typeof(this.maxVel) === "undefined") {
                this.maxVel = new me.Vector2d();
            }
            this.maxVel.set(1000, 1000);

            /**
             * Default gravity value of the entity

             * to be set to 0 for RPG, shooter, etc...

             * Note: Gravity can also globally be defined through me.sys.gravity
             * @public
             * @see me.sys.gravity
             * @type Number
             * @default 0.98
             * @name gravity
             * @memberOf me.Body
             */
            this.gravity = typeof(me.sys.gravity) !== "undefined" ? me.sys.gravity : 0.98;

            /**
             * falling state of the object

             * true if the object is falling

             * false if the object is standing on something

             * @readonly
             * @public
             * @type Boolean
             * @default false
             * @name falling
             * @memberOf me.Body
             */
            this.falling = false;

            /**
             * jumping state of the object

             * equal true if the entity is jumping

             * @readonly
             * @public
             * @type Boolean
             * @default false
             * @name jumping
             * @memberOf me.Body
             */
            this.jumping = false;

            // call the super constructor
            this._super(
                me.Rect,
                // bounds the body by default
                // to the parent entity
                "init", [
                    0,
                    0,
                    entity.width,
                    entity.height
                ]
            );

            // parses the given shapes array and add them
            for (var s = 0; s < shapes.length; s++) {
                this.addShape(shapes[s].clone(), true);
            }
        },

        /**
         * add a collision shape to this entity

         * (note: me.Rect objects will be converted to me.Polygon before being added)
         * @name addShape
         * @memberOf me.Body
         * @public
         * @function
         * @param {me.Rect|me.Polygon|me.Line|me.Ellipse} shape a shape object
         * @return {Number} the shape array length
         */
        addShape : function (shape, batchInsert) {
            this.shapes.push(shape);

            if (batchInsert !== true) {
                // update the body bounds to take in account the added shape
                this.updateBounds();
            }

            // return the length of the shape list
            return this.shapes.length;
        },

        /**
         * add collision shapes based on the given PhysicsEditor JSON object
         * @name addShapesFromJSON
         * @memberOf me.Body
         * @public
         * @function
         * @param {Object} json a JSON object as exported from the PhysicsEditor tool
         * @param {String} id the shape identifier within the given the json object
         * @param {String} [scale=1] the desired scale of the body (physic-body-editor only)
         * @see https://www.codeandweb.com/physicseditor
         * @return {Number} the shape array length
         */
        addShapesFromJSON : function (json, id, scale) {
            var data;
            scale = scale || 1;

            // identify the json format
            if (typeof(json.rigidBodies) === "undefined") {
                // Physic Editor Format (https://www.codeandweb.com/physicseditor)
                data = json[id];

                if (typeof(data) === "undefined") {
                    throw new me.Body.Error("Identifier (" + id + ") undefined for the given PhysicsEditor JSON object)");
                }

                // go through all shapes and add them to the body
                for (var i = 0; i < data.length; i++) {
                    var points = [];
                    for (var s = 0; s < data[i].shape.length; s += 2) {
                        points.push(new me.Vector2d(data[i].shape[s], data[i].shape[s + 1]));
                    }
                    this.addShape(new me.Polygon(0, 0, points));
                }
            } else {
                // Physic Body Editor Format (http://www.aurelienribon.com/blog/projects/physics-body-editor/)
                json.rigidBodies.forEach(function (shape) {
                    if (shape.name === id) {
                        data = shape;
                        // how to stop a forEach loop?
                    }
                });

                if (typeof(data) === "undefined") {
                    throw new me.Body.Error("Identifier (" + id + ") undefined for the given PhysicsEditor JSON object)");
                }

                // the shape origin point
                // top-left origin in the editor is (0,1)
                var origin = new me.Vector2d(data.origin.x, 1.0 - data.origin.y).scale(scale);

                var self = this;
                // parse all polygons
                data.polygons.forEach(function (poly) {
                    var points = [];
                    poly.forEach(function (point) {
                        // top-left origin in the editor is (0,1)
                        points.push(new me.Vector2d(point.x, 1.0 - point.y).scale(scale).sub(origin));
                    });
                    self.addShape(new me.Polygon(0, 0, points));
                });
                // parse all circles
                data.circles.forEach(function (circle) {
                    self.addShape(new me.Ellipse(
                        circle.cx * scale,
                        (1.0 - circle.cy) * scale,
                        circle.r * 2 * scale,
                        circle.r * 2 * scale
                    ).translate(-origin.x, -origin.y));
                });
            }

            // update the body bounds to take in account the added shapes
            this.updateBounds();

            // return the length of the shape list
            return this.shapes.length;
        },

        /**
         * return the collision shape at the given index
         * @name getShape
         * @memberOf me.Body
         * @public
         * @function
         * @param {Number} [index=0] the shape object at the specified index
         * @return {me.Polygon|me.Line|me.Ellipse} shape a shape object
         */
        getShape : function (index) {
            return this.shapes[index || 0];
        },

        /**
         * remove the specified shape from the body shape list
         * @name removeShape
         * @memberOf me.Body
         * @public
         * @function
         * @param {me.Polygon|me.Line|me.Ellipse} shape a shape object
         * @return {Number} the shape array length
         */
        removeShape : function (shape) {
            this.shapes.remove(shape);

            // update the body bounds to take in account the removed shape
            this.updateBounds();

            // return the length of the shape list
            return this.shapes.length;
        },

        /**
         * remove the shape at the given index from the body shape list
         * @name removeShapeAt
         * @memberOf me.Body
         * @public
         * @function
         * @param {Number} index the shape object at the specified index
         * @return {Number} the shape array length
         */
        removeShapeAt : function (index) {
            return this.removeShape(this.getShape(index));
        },

        /**
         * By default all entities are able to collide with all other entities,

         * but it's also possible to specificy 'collision filters' to provide a finer

         * control over which entities can collide with each other.
         * @name setCollisionMask
         * @memberOf me.Body
         * @public
         * @function
         * @see me.collision.types
         * @param {Number} bitmask the collision mask
         * @example
         * // filter collision detection with collision shapes, enemies and collectables
         * myEntity.body.setCollisionMask(me.collision.types.WORLD_SHAPE | me.collision.types.ENEMY_OBJECT | me.collision.types.COLLECTABLE_OBJECT);
         * ...
         * // disable collision detection with all other objects
         * myEntity.body.setCollisionMask(me.collision.types.NO_OBJECT);
         */
        setCollisionMask : function (bitmask) {
            this.collisionMask = bitmask;
        },

        /**
         * the built-in function to solve the collision response
         * @protected
         * @name respondToCollision
         * @memberOf me.Body
         * @function
         * @param {me.collision.ResponseObject} response the collision response object
         */
        respondToCollision: function (response) {
            // the overlap vector
            var overlap = response.overlapV;

            // FIXME: Respond proportionally to object mass

            // Move out of the other object shape
            this.entity.pos.sub(overlap);

            // adjust velocity
            if (overlap.x !== 0) {
                this.vel.x = ~~(0.5 + this.vel.x - overlap.x) || 0;
            }
            if (overlap.y !== 0) {
                this.vel.y = ~~(0.5 + this.vel.y - overlap.y) || 0;

                // cancel the falling an jumping flags if necessary
                this.falling = overlap.y >= 1;
                this.jumping = overlap.y <= -1;
            }
        },

        /**
         * update the body bounding rect (private)
         * the body rect size is here used to cache the total bounding rect
         * @private
         * @name updateBounds
         * @memberOf me.Body
         * @function
         */
        updateBounds : function () {
            if (this.shapes.length > 0) {
                // reset the rect with default values
                var _bounds = this.shapes[0].getBounds();
                this.pos.setV(_bounds.pos);
                this.resize(_bounds.width, _bounds.height);

                for (var i = 1 ; i < this.shapes.length; i++) {
                    this.union(this.shapes[i].getBounds());
                }
            }

            // update the parent entity bounds
            this.entity.onBodyUpdate(this.pos, this.width, this.height);

            return this;
        },

        /**
         * set the entity default velocity

         * note : velocity is by default limited to the same value, see
         * setMaxVelocity if needed

         * @name setVelocity
         * @memberOf me.Body
         * @function
         * @param {Number} x velocity on x axis
         * @param {Number} y velocity on y axis
         * @protected
         */
        setVelocity : function (x, y) {
            this.accel.x = x !== 0 ? x : this.accel.x;
            this.accel.y = y !== 0 ? y : this.accel.y;

            // limit by default to the same max value
            this.setMaxVelocity(x, y);
        },

        /**
         * cap the entity velocity to the specified value

         * @name setMaxVelocity
         * @memberOf me.Body
         * @function
         * @param {Number} x max velocity on x axis
         * @param {Number} y max velocity on y axis
         * @protected
         */
        setMaxVelocity : function (x, y) {
            this.maxVel.x = x;
            this.maxVel.y = y;
        },

        /**
         * set the entity default friction

         * @name setFriction
         * @memberOf me.Body
         * @function
         * @param {Number} x horizontal friction
         * @param {Number} y vertical friction
         * @protected
         */
        setFriction : function (x, y) {
            this.friction.x = x || 0;
            this.friction.y = y || 0;
        },

        /**
         * compute the new velocity value
         * @ignore
         */
        computeVelocity : function (vel) {

            // apply gravity (if any)
            if (this.gravity) {
                // apply a constant gravity (if not on a ladder)
                vel.y += this.gravity * me.timer.tick;

                // check if falling / jumping
                this.falling = (vel.y > 0);
                this.jumping = (this.falling ? false : this.jumping);
            }

            // apply friction
            if (this.friction.x) {
                vel.x = me.utils.applyFriction(vel.x, this.friction.x);
            }
            if (this.friction.y) {
                vel.y = me.utils.applyFriction(vel.y, this.friction.y);
            }

            // cap velocity
            if (vel.y !== 0) {
                vel.y = vel.y.clamp(-this.maxVel.y, this.maxVel.y);
            }
            if (vel.x !== 0) {
                vel.x = vel.x.clamp(-this.maxVel.x, this.maxVel.x);
            }
        },

        /**
         * update the body position
         * @name update
         * @memberOf me.Body
         * @function
         * @return {boolean} true if resulting velocity is different than 0
         */
        update : function (/* dt */) {
            // update the velocity
            this.computeVelocity(this.vel);

            // update player entity position
            this.entity.pos.add(this.vel);

            // returns true if vel is different from 0
            return (this.vel.x !== 0 || this.vel.y !== 0);
        },

        /**
         * Destroy function

         * @ignore
         */
        destroy : function () {
            this.entity = null;
            this.shapes = [];
        }
    });

    /**
     * Base class for Body exception handling.
     * @name Error
     * @class
     * @memberOf me.Body
     * @constructor
     * @param {String} msg Error message.
     */
    me.Body.Error = me.Error.extend({
        init : function (msg) {
            this._super(me.Error, "init", [ msg ]);
            this.name = "me.Body.Error";
        }
    });
})();
<commit_msg>[#643] fixed an issue with bouding box when rotating rectangle object<commit_after>/*
 * MelonJS Game Engine
 * Copyright (C) 2011 - 2015, Olivier Biot, Jason Oster, Aaron McLeod
 * http://www.melonjs.org
 *
 */

(function () {

    /**
     * a Generic Body Object

     * @class
     * @extends me.Rect
     * @memberOf me
     * @constructor
     * @param {me.Entity} entity the parent entity
     * @param {me.Polygon[]|me.Line[]|me.Ellipse[]} [shapes] the initial list of shapes
     */
    me.Body = me.Rect.extend(
    /** @scope me.Body.prototype */
    {
        /** @ignore */
        init : function (entity, shapes) {

            /**
             * reference to the parent entity
             * @ignore
             */
            this.entity = entity;

            /**
             * The collision shapes of the entity

             * @ignore
             * @type {me.Polygon[]|me.Line[]|me.Ellipse[]}
             * @name shapes
             * @memberOf me.Body
             */
            this.shapes = [];

            /**
             * The body collision mask, that defines what should collide with what.

             * (by default will collide with all entities)
             * @ignore
             * @type Number
             * @default me.collision.types.ALL_OBJECT
             * @name collisionMask
             * @see me.collision.types
             * @memberOf me.Body
             */
            this.collisionMask = me.collision.types.ALL_OBJECT;

            /**
             * define the collision type of the body for collision filtering
             * @public
             * @type Number
             * @default me.collision.types.ENEMY_OBJECT
             * @name collisionType
             * @see me.collision.types
             * @memberOf me.Body
             * @example
             * // set the entity body collision type
             * myEntity.body.collisionType = me.collision.types.PLAYER_OBJECT;
             */
            this.collisionType = me.collision.types.ENEMY_OBJECT;

            /**
             * entity current velocity

             * @public
             * @type me.Vector2d
             * @default <0,0>
             * @name vel
             * @memberOf me.Body
             */
            if (typeof(this.vel) === "undefined") {
                this.vel = new me.Vector2d();
            }
            this.vel.set(0, 0);

            /**
             * entity current acceleration

             * @public
             * @type me.Vector2d
             * @default <0,0>
             * @name accel
             * @memberOf me.Body
             */
            if (typeof(this.accel) === "undefined") {
                this.accel = new me.Vector2d();
            }
            this.accel.set(0, 0);

            /**
             * entity current friction

             * @public
             * @type me.Vector2d
             * @default <0,0>
             * @name friction
             * @memberOf me.Body
             */
            if (typeof(this.friction) === "undefined") {
                this.friction = new me.Vector2d();
            }
            this.friction.set(0, 0);

            /**
             * max velocity (to limit entity velocity)

             * @public
             * @type me.Vector2d
             * @default <1000,1000>
             * @name maxVel
             * @memberOf me.Body
             */
            if (typeof(this.maxVel) === "undefined") {
                this.maxVel = new me.Vector2d();
            }
            this.maxVel.set(1000, 1000);

            /**
             * Default gravity value of the entity

             * to be set to 0 for RPG, shooter, etc...

             * Note: Gravity can also globally be defined through me.sys.gravity
             * @public
             * @see me.sys.gravity
             * @type Number
             * @default 0.98
             * @name gravity
             * @memberOf me.Body
             */
            this.gravity = typeof(me.sys.gravity) !== "undefined" ? me.sys.gravity : 0.98;

            /**
             * falling state of the object

             * true if the object is falling

             * false if the object is standing on something

             * @readonly
             * @public
             * @type Boolean
             * @default false
             * @name falling
             * @memberOf me.Body
             */
            this.falling = false;

            /**
             * jumping state of the object

             * equal true if the entity is jumping

             * @readonly
             * @public
             * @type Boolean
             * @default false
             * @name jumping
             * @memberOf me.Body
             */
            this.jumping = false;

            // call the super constructor
            this._super(
                me.Rect,
                // bounds the body by default
                // to the parent entity
                "init", [
                    0,
                    0,
                    entity.width,
                    entity.height
                ]
            );

            // parses the given shapes array and add them
            for (var s = 0; s < shapes.length; s++) {
                this.addShape(shapes[s].clone(), true);
            }
        },

        /**
         * add a collision shape to this entity

         * (note: me.Rect objects will be converted to me.Polygon before being added)
         * @name addShape
         * @memberOf me.Body
         * @public
         * @function
         * @param {me.Rect|me.Polygon|me.Line|me.Ellipse} shape a shape object
         * @return {Number} the shape array length
         */
        addShape : function (shape, batchInsert) {
            if (shape instanceof me.Rect) {
                this.shapes.push(shape.toPolygon());
            } else {
                // else polygon or circle
                this.shapes.push(shape);
            }

            if (batchInsert !== true) {
                // update the body bounds to take in account the added shape
                this.updateBounds();
            }

            // return the length of the shape list
            return this.shapes.length;
        },

        /**
         * add collision shapes based on the given PhysicsEditor JSON object
         * @name addShapesFromJSON
         * @memberOf me.Body
         * @public
         * @function
         * @param {Object} json a JSON object as exported from the PhysicsEditor tool
         * @param {String} id the shape identifier within the given the json object
         * @param {String} [scale=1] the desired scale of the body (physic-body-editor only)
         * @see https://www.codeandweb.com/physicseditor
         * @return {Number} the shape array length
         */
        addShapesFromJSON : function (json, id, scale) {
            var data;
            scale = scale || 1;

            // identify the json format
            if (typeof(json.rigidBodies) === "undefined") {
                // Physic Editor Format (https://www.codeandweb.com/physicseditor)
                data = json[id];

                if (typeof(data) === "undefined") {
                    throw new me.Body.Error("Identifier (" + id + ") undefined for the given PhysicsEditor JSON object)");
                }

                // go through all shapes and add them to the body
                for (var i = 0; i < data.length; i++) {
                    var points = [];
                    for (var s = 0; s < data[i].shape.length; s += 2) {
                        points.push(new me.Vector2d(data[i].shape[s], data[i].shape[s + 1]));
                    }
                    this.addShape(new me.Polygon(0, 0, points));
                }
            } else {
                // Physic Body Editor Format (http://www.aurelienribon.com/blog/projects/physics-body-editor/)
                json.rigidBodies.forEach(function (shape) {
                    if (shape.name === id) {
                        data = shape;
                        // how to stop a forEach loop?
                    }
                });

                if (typeof(data) === "undefined") {
                    throw new me.Body.Error("Identifier (" + id + ") undefined for the given PhysicsEditor JSON object)");
                }

                // the shape origin point
                // top-left origin in the editor is (0,1)
                var origin = new me.Vector2d(data.origin.x, 1.0 - data.origin.y).scale(scale);

                var self = this;
                // parse all polygons
                data.polygons.forEach(function (poly) {
                    var points = [];
                    poly.forEach(function (point) {
                        // top-left origin in the editor is (0,1)
                        points.push(new me.Vector2d(point.x, 1.0 - point.y).scale(scale).sub(origin));
                    });
                    self.addShape(new me.Polygon(0, 0, points));
                });
                // parse all circles
                data.circles.forEach(function (circle) {
                    self.addShape(new me.Ellipse(
                        circle.cx * scale,
                        (1.0 - circle.cy) * scale,
                        circle.r * 2 * scale,
                        circle.r * 2 * scale
                    ).translate(-origin.x, -origin.y));
                });
            }

            // update the body bounds to take in account the added shapes
            this.updateBounds();

            // return the length of the shape list
            return this.shapes.length;
        },

        /**
         * return the collision shape at the given index
         * @name getShape
         * @memberOf me.Body
         * @public
         * @function
         * @param {Number} [index=0] the shape object at the specified index
         * @return {me.Polygon|me.Line|me.Ellipse} shape a shape object
         */
        getShape : function (index) {
            return this.shapes[index || 0];
        },

        /**
         * remove the specified shape from the body shape list
         * @name removeShape
         * @memberOf me.Body
         * @public
         * @function
         * @param {me.Polygon|me.Line|me.Ellipse} shape a shape object
         * @return {Number} the shape array length
         */
        removeShape : function (shape) {
            this.shapes.remove(shape);

            // update the body bounds to take in account the removed shape
            this.updateBounds();

            // return the length of the shape list
            return this.shapes.length;
        },

        /**
         * remove the shape at the given index from the body shape list
         * @name removeShapeAt
         * @memberOf me.Body
         * @public
         * @function
         * @param {Number} index the shape object at the specified index
         * @return {Number} the shape array length
         */
        removeShapeAt : function (index) {
            return this.removeShape(this.getShape(index));
        },

        /**
         * By default all entities are able to collide with all other entities,

         * but it's also possible to specificy 'collision filters' to provide a finer

         * control over which entities can collide with each other.
         * @name setCollisionMask
         * @memberOf me.Body
         * @public
         * @function
         * @see me.collision.types
         * @param {Number} bitmask the collision mask
         * @example
         * // filter collision detection with collision shapes, enemies and collectables
         * myEntity.body.setCollisionMask(me.collision.types.WORLD_SHAPE | me.collision.types.ENEMY_OBJECT | me.collision.types.COLLECTABLE_OBJECT);
         * ...
         * // disable collision detection with all other objects
         * myEntity.body.setCollisionMask(me.collision.types.NO_OBJECT);
         */
        setCollisionMask : function (bitmask) {
            this.collisionMask = bitmask;
        },

        /**
         * the built-in function to solve the collision response
         * @protected
         * @name respondToCollision
         * @memberOf me.Body
         * @function
         * @param {me.collision.ResponseObject} response the collision response object
         */
        respondToCollision: function (response) {
            // the overlap vector
            var overlap = response.overlapV;

            // FIXME: Respond proportionally to object mass

            // Move out of the other object shape
            this.entity.pos.sub(overlap);

            // adjust velocity
            if (overlap.x !== 0) {
                this.vel.x = ~~(0.5 + this.vel.x - overlap.x) || 0;
            }
            if (overlap.y !== 0) {
                this.vel.y = ~~(0.5 + this.vel.y - overlap.y) || 0;

                // cancel the falling an jumping flags if necessary
                this.falling = overlap.y >= 1;
                this.jumping = overlap.y <= -1;
            }
        },

        /**
         * update the body bounding rect (private)
         * the body rect size is here used to cache the total bounding rect
         * @private
         * @name updateBounds
         * @memberOf me.Body
         * @function
         */
        updateBounds : function () {
            if (this.shapes.length > 0) {
                // reset the rect with default values
                var _bounds = this.shapes[0].getBounds();
                this.pos.setV(_bounds.pos);
                this.resize(_bounds.width, _bounds.height);

                for (var i = 1 ; i < this.shapes.length; i++) {
                    this.union(this.shapes[i].getBounds());
                }
            }

            // update the parent entity bounds
            this.entity.onBodyUpdate(this.pos, this.width, this.height);

            return this;
        },

        /**
         * set the entity default velocity

         * note : velocity is by default limited to the same value, see
         * setMaxVelocity if needed

         * @name setVelocity
         * @memberOf me.Body
         * @function
         * @param {Number} x velocity on x axis
         * @param {Number} y velocity on y axis
         * @protected
         */
        setVelocity : function (x, y) {
            this.accel.x = x !== 0 ? x : this.accel.x;
            this.accel.y = y !== 0 ? y : this.accel.y;

            // limit by default to the same max value
            this.setMaxVelocity(x, y);
        },

        /**
         * cap the entity velocity to the specified value

         * @name setMaxVelocity
         * @memberOf me.Body
         * @function
         * @param {Number} x max velocity on x axis
         * @param {Number} y max velocity on y axis
         * @protected
         */
        setMaxVelocity : function (x, y) {
            this.maxVel.x = x;
            this.maxVel.y = y;
        },

        /**
         * set the entity default friction

         * @name setFriction
         * @memberOf me.Body
         * @function
         * @param {Number} x horizontal friction
         * @param {Number} y vertical friction
         * @protected
         */
        setFriction : function (x, y) {
            this.friction.x = x || 0;
            this.friction.y = y || 0;
        },

        /**
         * compute the new velocity value
         * @ignore
         */
        computeVelocity : function (vel) {

            // apply gravity (if any)
            if (this.gravity) {
                // apply a constant gravity (if not on a ladder)
                vel.y += this.gravity * me.timer.tick;

                // check if falling / jumping
                this.falling = (vel.y > 0);
                this.jumping = (this.falling ? false : this.jumping);
            }

            // apply friction
            if (this.friction.x) {
                vel.x = me.utils.applyFriction(vel.x, this.friction.x);
            }
            if (this.friction.y) {
                vel.y = me.utils.applyFriction(vel.y, this.friction.y);
            }

            // cap velocity
            if (vel.y !== 0) {
                vel.y = vel.y.clamp(-this.maxVel.y, this.maxVel.y);
            }
            if (vel.x !== 0) {
                vel.x = vel.x.clamp(-this.maxVel.x, this.maxVel.x);
            }
        },

        /**
         * update the body position
         * @name update
         * @memberOf me.Body
         * @function
         * @return {boolean} true if resulting velocity is different than 0
         */
        update : function (/* dt */) {
            // update the velocity
            this.computeVelocity(this.vel);

            // update player entity position
            this.entity.pos.add(this.vel);

            // returns true if vel is different from 0
            return (this.vel.x !== 0 || this.vel.y !== 0);
        },

        /**
         * Destroy function

         * @ignore
         */
        destroy : function () {
            this.entity = null;
            this.shapes = [];
        }
    });

    /**
     * Base class for Body exception handling.
     * @name Error
     * @class
     * @memberOf me.Body
     * @constructor
     * @param {String} msg Error message.
     */
    me.Body.Error = me.Error.extend({
        init : function (msg) {
            this._super(me.Error, "init", [ msg ]);
            this.name = "me.Body.Error";
        }
    });
})();
<|endoftext|>


<commit_before>/**
 * Angular.js plugin
 *
 * Provides an $exceptionHandler for Angular.js
 */
;(function(Raven, angular) {
'use strict';

// quit if angular isn't on the page
if (!angular) {
    return;
}

function ngRavenProvider($provide) {
    $provide.decorator('$exceptionHandler', [
        'RavenConfig', '$delegate',
        ngRavenExceptionHandler
    ]);
}

function ngRavenExceptionHandler(RavenConfig, $delegate) {
    if (!RavenConfig)
        throw new Error('RavenConfig must be set before using this');

    Raven.config(RavenConfig.dsn, RavenConfig.config).install();
    return function angularExceptionHandler(ex, cause) {
        $delegate(ex, cause);
        Raven.captureException(ex, {extra: {cause: cause}});
    };
}

angular.module('ngRaven', [])
    .config(['$provide', ngRavenProvider])
    .value('Raven', Raven);

})(window.Raven, window.angular);
<commit_msg>Set Raven.debug using angular RavenConfig<commit_after>/**
 * Angular.js plugin
 *
 * Provides an $exceptionHandler for Angular.js
 */
;(function(Raven, angular) {
'use strict';

// quit if angular isn't on the page
if (!angular) {
    return;
}

function ngRavenProvider($provide) {
    $provide.decorator('$exceptionHandler', [
        'RavenConfig', '$delegate',
        ngRavenExceptionHandler
    ]);
}

function ngRavenExceptionHandler(RavenConfig, $delegate) {
    if (!RavenConfig)
        throw new Error('RavenConfig must be set before using this');

    if (RavenConfig.debug !== void 0) {
      Raven.debug = RavenConfig.debug;
    }

    Raven.config(RavenConfig.dsn, RavenConfig.config).install();
    return function angularExceptionHandler(ex, cause) {
        $delegate(ex, cause);
        Raven.captureException(ex, {extra: {cause: cause}});
    };
}

angular.module('ngRaven', [])
    .config(['$provide', ngRavenProvider])
    .value('Raven', Raven);

})(window.Raven, window.angular);
<|endoftext|>


<commit_before>import { router, pathMatchRegexp } from 'utils'
import { loginUser } from 'api'

export default {
  namespace: 'login',

  state: {},

  effects: {
    *login({ payload }, { put, call, select }) {
      const data = yield call(loginUser, payload)
      const { locationQuery } = yield select(_ => _.app)
      if (data.success) {
        const { from } = locationQuery
        yield put({ type: 'app/query' })
        if (!pathMatchRegexp('/login', from)) {
          router.push(from)
        } else {
          router.push('/dashboard')
        }
      } else {
        throw data
      }
    },
  },
}
<commit_msg>fix login with wrong path<commit_after>import { router, pathMatchRegexp } from 'utils'
import { loginUser } from 'api'

export default {
  namespace: 'login',

  state: {},

  effects: {
    *login({ payload }, { put, call, select }) {
      const data = yield call(loginUser, payload)
      const { locationQuery } = yield select(_ => _.app)
      if (data.success) {
        const { from } = locationQuery
        yield put({ type: 'app/query' })
        if (!pathMatchRegexp('/login', from)) {
          if (from === '/') router.push('/dashboard')
          else router.push(from)
        } else {
          router.push('/dashboard')
        }
      } else {
        throw data
      }
    },
  },
}
<|endoftext|>