<commit_before>var url = require('url');
var path = require('path');
var util = require('util');
var vm = require('vm');
var fs = require('fs');

var jsbase = __dirname + '/';
var compilemachine = require(jsbase + 'compile.js');

module.exports = JSSPCoreInit;

function getenvobj(req)
{
	var urlparse = url.parse(req.url,true);
	var filename = urlparse.pathname;
	if( (!filename)||('/'==filename) ) filename = 'index.jssp';
	filename = path.normalize('/'+filename); //delete .. in filename

	var env = {};
	env['JSSP_SELF']      = filename;
	env['SCRIPT_FILENAME']= filename;
	env['REMOTE_ADDR']    = req.socket.remoteAddress;
	env['REMOTE_PORT']    = req.socket.remotePort;
	env['SERVER_ADDR']    = req.socket.localAddress;
	env['SERVER_PORT']    = req.socket.localPort;
	env['SERVER_PROTOCOL']= req.httpVersion;
	env['REQUEST_METHOD'] = req.method;
	env['QUERY_STRING']   = req.url;

	env['HTTP_HOST']      = req.headers['host'];
	env['HTTP_USER_AGENT']= req.headers['user-agent'];
	env['HTTP_ACCEPT']    = req.headers['accept'];
	env['HTTP_CONNECTION']= req.headers['connection'];
	env['HTTP_REFERER']   = req.headers['referer'];
	env['HTTP_ACCEPT_CHARSET'] = req.headers['accept-charset'];
	env['HTTP_ACCEPT_ENCODING']= req.headers['accept-encoding'];
	env['HTTP_ACCEPT_LANGUAGE']= req.headers['accept-language'];
	env['CONTENT_LENGTH'] = req.headers['content-length'];
	env['CONTENT_TYPE']   = req.headers['content-type'];
	return env;
}

function PHPInit(jssp,req,res,postobj,fileobj,code,filename)
{
	var urlobj  = url.parse(req.url,true);
	jssp.$_GET  = urlobj.query;
	jssp.$_POST = postobj;
	jssp.$_FILE = fileobj;
	jssp.$_SERVER = getenvobj(req);
	jssp.$_ENV = jssp.ENV;

	jssp.echo = function(str)
	{
		if(typeof str === "function") str = jssp.func2str(str); else
		if(typeof str === "undefined") str = ''; else
		if(Buffer.isBuffer(str)) str = str; else
		if(typeof str !== "string")   str = ''+str;
		jssp.output(str);
	}
	jssp.exit = function(str)
	{
		jssp.internalexit(str);
	}

	jssp.includecache = false;
	jssp.include = function(filename)
	{
		filename = path.normalize('/'+filename); //delete .. in filename
		filename = path.resolve(jssp.__dirname,'./'+filename);

		var code = jssp.codebyname(filename);
		if(code.stack) throw code;

		var oldfilename;
		var oldcode;
		function push()
		{
			oldfilename      = jssp.__filename;
			oldcode          = jssp.__code;
			jssp.__filename  = filename;
			jssp.__dirname   = path.dirname(filename);
			jssp.__code      = code;
			jssp.__codename  = filename+'.js';
		}
		function pop()
		{
			jssp.__filename  = oldfilename;
			jssp.__dirname   = path.dirname(oldfilename);
			jssp.__code      = oldcode;
			jssp.__codename  = oldfilename+'.js';
		}

		var flag = jssp.includecache;
		var htmlpop;
		if(flag) { htmlpop = jssp.html.pop() }
		else { jssp.htmlstack.push(jssp.html); jssp.html=[]; }

		jssp.arraypush(push);
		var oldrunnext = jssp.runnext;
		jssp.runnext = function(){};
		push();jssp.EvalCode(jssp,code);pop();
		jssp.runnext = oldrunnext;
		jssp.arraypush(pop);

		if(flag) { jssp.arraypush(htmlpop) }
		else { jssp.arraypush(function(){ jssp.html = jssp.htmlstack.pop() }) }

		jssp.includecache = true;
	}
	jssp.set_time_limit = function(timeout)
	{
		jssp.setmaxtimer(timeout);
	}
	jssp.header = function(name,value,responsecode)
	{
		res.setHeader(name,value);
		if(responsecode) res.statusCode = responsecode;
	}
	jssp.headers_sent = function()
	{
		return res.headersSent;
	}

	var ssesid;
	jssp.internal_session_newid = function()
	{
		var obj = {};
		obj.sessobj = {};
		obj.ssesid  = process.hrtime().join('-')+'-'+Math.random()*1000000000000000000;
		obj.time    = process.hrtime();
		obj.id      = setInterval(function()
		{
			if(process.hrtime(obj.time)[0]>24*60) jssp.session_destroy();
		},5*60*1000);

		res.setHeader('Set-Cookie','JSSPSESSID='+obj.ssesid);

		jssp.SESSIONS[obj.ssesid] = obj;
		return obj.ssesid;
	}
	jssp.session_start = function()
	{
		if(!ssesid) ssesid = splitsessionid(req.headers['cookie']);
		if(!ssesid) ssesid = jssp.internal_session_newid();

		obj = jssp.SESSIONS[ssesid];
		if(!obj) ssesid  = jssp.internal_session_newid();	//ssesid invalid
		if(!obj) obj = jssp.SESSIONS[ssesid];

		obj.time = process.hrtime();
		return obj.sessobj;
	}
	jssp.session_id = function()
	{
		return ssesid;
	}
	jssp.session_destroy = function()
	{
		var obj = jssp.SESSIONS[ssesid];
		if(!obj) return;
		clearInterval(obj.id);
		jssp.session_unset();
		delete jssp.SESSIONS[ssesid];
		ssesid = undefined;
	}
	jssp.session_unset = function()
	{
		var obj = jssp.SESSIONS[ssesid];
		if(!obj) return;
		var sessobj = obj.sessobj;
		for(var key in sessobj) delete sessobj[key];
	}
}

function JSSPInit(jssp,req,res,postobj,fileobj,code,filename)
{
	jssp.arraypush = function(cb)
	{
		jssp.html.push(cb);
	}
	jssp.func2str = function(cb)
	{
		var str = cb.toString();
		var list= str.split('\n');

		list.shift();list.pop(); //delete first and last line

		//delete comment flag '//' before every line
		for(var i=0;i<list.length;i++) list[i]=list[i].substring(2);

		str = list.join('\n');
		return str;
	}

	jssp.require = function(name)
	{
		var obj;

		if(name==='fs') obj = require('./fakefs.js')(jssp); else
		if(name==='net') obj = require('./fakenet.js')(jssp); else
		if(name==='http') obj = require('./fakehttp.js')(jssp); else
		if(name==='child_process') obj = require('./fakecp.js')(jssp); else

		if( (name==='string_decoder')||(name==='crypto')||(name==='os')||
			(name==='path')||(name==='url')||(name==='util')||(name==='querystring') )
		{
			obj = require(name);
		}
		return obj;
	}
	jssp.setTimeout = function(cb,timeout)
	{
		var newcb = function()
		{
			cb();
			jssp.objectdel(timer);
		}
		var timer = setTimeout(newcb,timeout);
		timer.jsspclose = function(){ clearTimeout(timer); };
		jssp.objectadd(timer);
		return timer;
	}
	jssp.clearTimeout = function(timer)
	{
		jssp.objectdel(timer);
		return clearTimeout(timer);
	}
	jssp.setInterval = function(cb,timeout)
	{
		var newcb = function()
		{
			cb();
			jssp.objectdel(timer);
		}
		var timer = setInterval(newcb,timeout);
		timer.jsspclose = function(){ clearTimeout(timer); };
		jssp.objectadd(timer);
		return timer;
	}
	jssp.clearInterval = function(timer)
	{
		jssp.objectdel(timer);
		return clearInterval(timer);
	}

}

function JSSPCoreInit(options,req,res,postobj,fileobj,code,filename)
{
	var jssp = {};
	jssp.vm              = vm;
	jssp.EvalCode        = undefined;
	jssp.BASE            = options.BASE;
	jssp.ENV             = options.ENV;
	jssp.EXT             = options.EXT;
	jssp.SESSIONS        = options.SESSIONS;
	jssp.codebyname      = options.codebyname;

	jssp.html = [];
	jssp.htmlstack = [];

	jssp.__filename    = filename;
	jssp.__dirname     = path.dirname(filename);
	jssp.__code        = code;
	jssp.__codename    = filename+'.js';
	jssp.module        = {"exports":{}};
	jssp.Buffer        = Buffer;

	var objectset  = new Set();
	jssp.objectset = objectset;
	jssp.objectadd = function(obj){ objectset.add(obj); }
	jssp.objectdel = function(obj){ objectset.delete(obj); jssp.runnext(); }
	jssp.objecthas = function(obj){ return objectset.has(obj); }

	jssp.running = true;
	jssp.runnext = function()
	{
		if(!jssp.running) return;
		ticktime = undefined;
		if(objectset.size>0){ return; }

		if(jssp.html.length)
		{
			jssp.domainobj.run(function()
			{
				do{ jssp.html.shift().call(); jssp.includecache=false; }
				while( (0==objectset.size)&&(jssp.html.length>0) )
				jssp.output();	//flush cache
				process.nextTick(jssp.runnext);
			});
		}
		else
		{
			jssp.internalexit();
		}
	}

	jssp.outputcache = '';
	jssp.output = function(str,isend)
	{
		if(!str) str = '';
		if(jssp.includecache)
		{
			var last = jssp.html.pop();
			var fn = function(){ jssp.output(str) }
			jssp.html.push(fn);
			jssp.html.push(last);
		}
		else
		{
			if( (str)&&(!isend) ) { jssp.outputcache += str;return; }

			str += jssp.outputcache;
			jssp.domainobj.run(function()
			{
				if(isend) { if(str) { res.end(str) } else { res.end() } }
				else      { if(str) { res.write(str) } }
			});
		}
	}

	jssp.internalexit = function(str)
	{
		if(!jssp.running) return;
		jssp.running = false;

		if(maxtimer) clearTimeout(maxtimer);
		objectset.forEach(function(obj){ obj.jsspclose() });

		jssp.output(str,true);
	}

	var domainobj = require('domain').create();
	domainobj.on("error",function(e){ jssp.internalexit(jssp.errorformat(e)); });
	jssp.domainobj = domainobj;

	var  T = {};
	jssp.T = T;
	jssp.render = function(name,value){ T[name] = value; }

	var tickcount = 0;
	var ticktime  = undefined;
	jssp.tick = function()
	{
		tickcount++;
		if( (tickcount)&&(0==tickcount%102400) )
		{
			if(!ticktime) ticktime=process.hrtime();
			if(process.hrtime(ticktime)[0]*1000>=options.TICKTIME)
			throw new Error('EXCEED TICKTIME');
		}
	}

	var maxtimer = undefined;
	jssp.setmaxtimer = function(timeout)
	{
		if(maxtimer) clearTimeout(maxtimer);
		maxtimer = setTimeout(function()
		{
			maxtimer = undefined;
			var str = 'EXCEED EXECTIME: ' + jssp.__codename + '\n';
			objectset.forEach(function(obj){ str+=util.inspect(obj,{depth:0}) });
			jssp.internalexit(jssp.errorformat(str));
		},timeout);
	}
	jssp.setmaxtimer(options.EXECTIME);

	jssp.errorformat = function(e)
	{
		return codeerrorformat(e,jssp.__code,jssp.__codename);
	}
	jssp.domaincreate = function()
	{
		var d = require('domain').create();
		d.on("error",function(e){ jssp.internalexit(jssp.errorformat(e)); });
		return d;
	}
	jssp.init = function()
	{
		PHPInit(jssp,req,res,postobj,fileobj,code,filename);
		JSSPInit(jssp,req,res,postobj,fileobj,code,filename);
	}
	jssp.init();

	return jssp;
}

function codeerrorformat(e,code,codename)
{
	var str;
	if(e.stack)
	{
		str = e.stack;
		str = 'ERROR IN FILE: ' + codename + '\n\n' + str;
	}
	else str = e.toString();

	var re = new RegExp('evalmachine.<anonymous>','g');
	str = str.replace(re,'evalmachine.anonymous');
	var re = new RegExp('<anonymous>','g');
	str = str.replace(re,codename);

	//format code
	var c = code;
	var list = c.split('\n');
	for(var i=0;i<list.length;i++)
	{
		var line = ('00000'+(i+1)).slice(-4) + ' ';
		list[i] = line + list[i];
	}
	c = list.join('\n');
	str = str + '\n\n'
	     +'------------CODE BEGIN------------'
	     +'\n'+ c + '\n'
	     +'------------CODE END------------';

	str = str.replace(/\&/g,'&amp');
	str = str.replace(/\</g,'<');
	return '

\n'+str+'
';
}

function splitsessionid(cookie)
{
	cookie = cookie + ';';
	var id  = undefined;
	var index  = cookie.indexOf('JSSPSESSID=');
	if(index>=0)
	{
		id = cookie.slice(index+11);
		index  = id.indexOf(';');
		id = id.slice(0,index);
	}
	return id;
}
<commit_msg>Clear cache after output<commit_after>var url = require('url');
var path = require('path');
var util = require('util');
var vm = require('vm');
var fs = require('fs');

var jsbase = __dirname + '/';
var compilemachine = require(jsbase + 'compile.js');

module.exports = JSSPCoreInit;

function getenvobj(req)
{
	var urlparse = url.parse(req.url,true);
	var filename = urlparse.pathname;
	if( (!filename)||('/'==filename) ) filename = 'index.jssp';
	filename = path.normalize('/'+filename); //delete .. in filename

	var env = {};
	env['JSSP_SELF']      = filename;
	env['SCRIPT_FILENAME']= filename;
	env['REMOTE_ADDR']    = req.socket.remoteAddress;
	env['REMOTE_PORT']    = req.socket.remotePort;
	env['SERVER_ADDR']    = req.socket.localAddress;
	env['SERVER_PORT']    = req.socket.localPort;
	env['SERVER_PROTOCOL']= req.httpVersion;
	env['REQUEST_METHOD'] = req.method;
	env['QUERY_STRING']   = req.url;

	env['HTTP_HOST']      = req.headers['host'];
	env['HTTP_USER_AGENT']= req.headers['user-agent'];
	env['HTTP_ACCEPT']    = req.headers['accept'];
	env['HTTP_CONNECTION']= req.headers['connection'];
	env['HTTP_REFERER']   = req.headers['referer'];
	env['HTTP_ACCEPT_CHARSET'] = req.headers['accept-charset'];
	env['HTTP_ACCEPT_ENCODING']= req.headers['accept-encoding'];
	env['HTTP_ACCEPT_LANGUAGE']= req.headers['accept-language'];
	env['CONTENT_LENGTH'] = req.headers['content-length'];
	env['CONTENT_TYPE']   = req.headers['content-type'];
	return env;
}

function PHPInit(jssp,req,res,postobj,fileobj,code,filename)
{
	var urlobj  = url.parse(req.url,true);
	jssp.$_GET  = urlobj.query;
	jssp.$_POST = postobj;
	jssp.$_FILE = fileobj;
	jssp.$_SERVER = getenvobj(req);
	jssp.$_ENV = jssp.ENV;

	jssp.echo = function(str)
	{
		if(typeof str === "function") str = jssp.func2str(str); else
		if(typeof str === "undefined") str = ''; else
		if(Buffer.isBuffer(str)) str = str; else
		if(typeof str !== "string")   str = ''+str;
		jssp.output(str);
	}
	jssp.exit = function(str)
	{
		jssp.internalexit(str);
	}

	jssp.includecache = false;
	jssp.include = function(filename)
	{
		filename = path.normalize('/'+filename); //delete .. in filename
		filename = path.resolve(jssp.__dirname,'./'+filename);

		var code = jssp.codebyname(filename);
		if(code.stack) throw code;

		var oldfilename;
		var oldcode;
		function push()
		{
			oldfilename      = jssp.__filename;
			oldcode          = jssp.__code;
			jssp.__filename  = filename;
			jssp.__dirname   = path.dirname(filename);
			jssp.__code      = code;
			jssp.__codename  = filename+'.js';
		}
		function pop()
		{
			jssp.__filename  = oldfilename;
			jssp.__dirname   = path.dirname(oldfilename);
			jssp.__code      = oldcode;
			jssp.__codename  = oldfilename+'.js';
		}

		var flag = jssp.includecache;
		var htmlpop;
		if(flag) { htmlpop = jssp.html.pop() }
		else { jssp.htmlstack.push(jssp.html); jssp.html=[]; }

		jssp.arraypush(push);
		var oldrunnext = jssp.runnext;
		jssp.runnext = function(){};
		push();jssp.EvalCode(jssp,code);pop();
		jssp.runnext = oldrunnext;
		jssp.arraypush(pop);

		if(flag) { jssp.arraypush(htmlpop) }
		else { jssp.arraypush(function(){ jssp.html = jssp.htmlstack.pop() }) }

		jssp.includecache = true;
	}
	jssp.set_time_limit = function(timeout)
	{
		jssp.setmaxtimer(timeout);
	}
	jssp.header = function(name,value,responsecode)
	{
		res.setHeader(name,value);
		if(responsecode) res.statusCode = responsecode;
	}
	jssp.headers_sent = function()
	{
		return res.headersSent;
	}

	var ssesid;
	jssp.internal_session_newid = function()
	{
		var obj = {};
		obj.sessobj = {};
		obj.ssesid  = process.hrtime().join('-')+'-'+Math.random()*1000000000000000000;
		obj.time    = process.hrtime();
		obj.id      = setInterval(function()
		{
			if(process.hrtime(obj.time)[0]>24*60) jssp.session_destroy();
		},5*60*1000);

		res.setHeader('Set-Cookie','JSSPSESSID='+obj.ssesid);

		jssp.SESSIONS[obj.ssesid] = obj;
		return obj.ssesid;
	}
	jssp.session_start = function()
	{
		if(!ssesid) ssesid = splitsessionid(req.headers['cookie']);
		if(!ssesid) ssesid = jssp.internal_session_newid();

		obj = jssp.SESSIONS[ssesid];
		if(!obj) ssesid  = jssp.internal_session_newid();	//ssesid invalid
		if(!obj) obj = jssp.SESSIONS[ssesid];

		obj.time = process.hrtime();
		return obj.sessobj;
	}
	jssp.session_id = function()
	{
		return ssesid;
	}
	jssp.session_destroy = function()
	{
		var obj = jssp.SESSIONS[ssesid];
		if(!obj) return;
		clearInterval(obj.id);
		jssp.session_unset();
		delete jssp.SESSIONS[ssesid];
		ssesid = undefined;
	}
	jssp.session_unset = function()
	{
		var obj = jssp.SESSIONS[ssesid];
		if(!obj) return;
		var sessobj = obj.sessobj;
		for(var key in sessobj) delete sessobj[key];
	}
}

function JSSPInit(jssp,req,res,postobj,fileobj,code,filename)
{
	jssp.arraypush = function(cb)
	{
		jssp.html.push(cb);
	}
	jssp.func2str = function(cb)
	{
		var str = cb.toString();
		var list= str.split('\n');

		list.shift();list.pop(); //delete first and last line

		//delete comment flag '//' before every line
		for(var i=0;i<list.length;i++) list[i]=list[i].substring(2);

		str = list.join('\n');
		return str;
	}

	jssp.require = function(name)
	{
		var obj;

		if(name==='fs') obj = require('./fakefs.js')(jssp); else
		if(name==='net') obj = require('./fakenet.js')(jssp); else
		if(name==='http') obj = require('./fakehttp.js')(jssp); else
		if(name==='child_process') obj = require('./fakecp.js')(jssp); else

		if( (name==='string_decoder')||(name==='crypto')||(name==='os')||
			(name==='path')||(name==='url')||(name==='util')||(name==='querystring') )
		{
			obj = require(name);
		}
		return obj;
	}
	jssp.setTimeout = function(cb,timeout)
	{
		var newcb = function()
		{
			cb();
			jssp.objectdel(timer);
		}
		var timer = setTimeout(newcb,timeout);
		timer.jsspclose = function(){ clearTimeout(timer); };
		jssp.objectadd(timer);
		return timer;
	}
	jssp.clearTimeout = function(timer)
	{
		jssp.objectdel(timer);
		return clearTimeout(timer);
	}
	jssp.setInterval = function(cb,timeout)
	{
		var newcb = function()
		{
			cb();
			jssp.objectdel(timer);
		}
		var timer = setInterval(newcb,timeout);
		timer.jsspclose = function(){ clearTimeout(timer); };
		jssp.objectadd(timer);
		return timer;
	}
	jssp.clearInterval = function(timer)
	{
		jssp.objectdel(timer);
		return clearInterval(timer);
	}

}

function JSSPCoreInit(options,req,res,postobj,fileobj,code,filename)
{
	var jssp = {};
	jssp.vm              = vm;
	jssp.EvalCode        = undefined;
	jssp.BASE            = options.BASE;
	jssp.ENV             = options.ENV;
	jssp.EXT             = options.EXT;
	jssp.SESSIONS        = options.SESSIONS;
	jssp.codebyname      = options.codebyname;

	jssp.html = [];
	jssp.htmlstack = [];

	jssp.__filename    = filename;
	jssp.__dirname     = path.dirname(filename);
	jssp.__code        = code;
	jssp.__codename    = filename+'.js';
	jssp.module        = {"exports":{}};
	jssp.Buffer        = Buffer;

	var objectset  = new Set();
	jssp.objectset = objectset;
	jssp.objectadd = function(obj){ objectset.add(obj); }
	jssp.objectdel = function(obj){ objectset.delete(obj); jssp.runnext(); }
	jssp.objecthas = function(obj){ return objectset.has(obj); }

	jssp.running = true;
	jssp.runnext = function()
	{
		if(!jssp.running) return;
		ticktime = undefined;
		if(objectset.size>0){ return; }

		if(jssp.html.length)
		{
			jssp.domainobj.run(function()
			{
				do{ jssp.html.shift().call(); jssp.includecache=false; }
				while( (0==objectset.size)&&(jssp.html.length>0) )
				jssp.output();	//flush cache
				process.nextTick(jssp.runnext);
			});
		}
		else
		{
			jssp.internalexit();
		}
	}

	jssp.outputcache = '';
	jssp.output = function(str,isend)
	{
		if(!str) str = '';
		if(jssp.includecache)
		{
			var last = jssp.html.pop();
			var fn = function(){ jssp.output(str) }
			jssp.html.push(fn);
			jssp.html.push(last);
		}
		else
		{
			if( (str)&&(!isend) ) { jssp.outputcache += str;return; }

			str+=jssp.outputcache; jssp.outputcache='';
			jssp.domainobj.run(function()
			{
				if(isend) { if(str) { res.end(str) } else { res.end() } }
				else      { if(str) { res.write(str) } }
			});
		}
	}

	jssp.internalexit = function(str)
	{
		if(!jssp.running) return;
		jssp.running = false;

		if(maxtimer) clearTimeout(maxtimer);
		objectset.forEach(function(obj){ obj.jsspclose() });

		jssp.output(str,true);
	}

	var domainobj = require('domain').create();
	domainobj.on("error",function(e){ jssp.internalexit(jssp.errorformat(e)); });
	jssp.domainobj = domainobj;

	var  T = {};
	jssp.T = T;
	jssp.render = function(name,value){ T[name] = value; }

	var tickcount = 0;
	var ticktime  = undefined;
	jssp.tick = function()
	{
		tickcount++;
		if( (tickcount)&&(0==tickcount%102400) )
		{
			if(!ticktime) ticktime=process.hrtime();
			if(process.hrtime(ticktime)[0]*1000>=options.TICKTIME)
			throw new Error('EXCEED TICKTIME');
		}
	}

	var maxtimer = undefined;
	jssp.setmaxtimer = function(timeout)
	{
		if(maxtimer) clearTimeout(maxtimer);
		maxtimer = setTimeout(function()
		{
			maxtimer = undefined;
			var str = 'EXCEED EXECTIME: ' + jssp.__codename + '\n';
			objectset.forEach(function(obj){ str+=util.inspect(obj,{depth:0}) });
			jssp.internalexit(jssp.errorformat(str));
		},timeout);
	}
	jssp.setmaxtimer(options.EXECTIME);

	jssp.errorformat = function(e)
	{
		return codeerrorformat(e,jssp.__code,jssp.__codename);
	}
	jssp.domaincreate = function()
	{
		var d = require('domain').create();
		d.on("error",function(e){ jssp.internalexit(jssp.errorformat(e)); });
		return d;
	}
	jssp.init = function()
	{
		PHPInit(jssp,req,res,postobj,fileobj,code,filename);
		JSSPInit(jssp,req,res,postobj,fileobj,code,filename);
	}
	jssp.init();

	return jssp;
}

function codeerrorformat(e,code,codename)
{
	var str;
	if(e.stack)
	{
		str = e.stack;
		str = 'ERROR IN FILE: ' + codename + '\n\n' + str;
	}
	else str = e.toString();

	var re = new RegExp('evalmachine.<anonymous>','g');
	str = str.replace(re,'evalmachine.anonymous');
	var re = new RegExp('<anonymous>','g');
	str = str.replace(re,codename);

	//format code
	var c = code;
	var list = c.split('\n');
	for(var i=0;i<list.length;i++)
	{
		var line = ('00000'+(i+1)).slice(-4) + ' ';
		list[i] = line + list[i];
	}
	c = list.join('\n');
	str = str + '\n\n'
	     +'------------CODE BEGIN------------'
	     +'\n'+ c + '\n'
	     +'------------CODE END------------';

	str = str.replace(/\&/g,'&amp');
	str = str.replace(/\</g,'<');
	return '

\n'+str+'
';
}

function splitsessionid(cookie)
{
	cookie = cookie + ';';
	var id  = undefined;
	var index  = cookie.indexOf('JSSPSESSID=');
	if(index>=0)
	{
		id = cookie.slice(index+11);
		index  = id.indexOf(';');
		id = id.slice(0,index);
	}
	return id;
}
<|endoftext|>


<commit_before>angular.module('prx.player', ['ngPlayerHater', 'angulartics', 'prx.bus'])
.run(function (Bus, $analytics) {
  var category = 'Audio Player';

  Bus.on('audioPlayer.stop', function () {
    $analytics.eventTrack('Stop', {
      category: category,
      label: this.story.id
    });
  }).on('audioPlayer.resume', function () {
    $analytics.eventTrack('Resume', {
      category: category,
      label: this.story.id
    });
  }).on('audioPlayer.pause', function () {
    $analytics.eventTrack('Pause', {
      category: category,
      label: this.story.id
    });
  }).on('audioPlayer.play', function () {
    $analytics.eventTrack('Play', {
      category: category,
      label: this.story.id
    });
  }).on('audioPlayer.listen', function (audioFile, duration, startTime) {
    $analytics.eventTrack('Listen', {
      category: category,
      label: this.story.id,
      pieceId: this.story.id,
      audioFileId: audioFile.id,
      value: duration,
      duration: duration,
      startedAt: startTime,
      noninteraction: true
    });
  });
})
.factory('prxSoundFactory', function (smSound) {
  function SoundFactory (options) {
    var sound = smSound.createList(options.audioFiles, {
      onfinish: function () {
        if (angular.isFunction(sound.onfinish)) {
          sound.onfinish();
        }
      }
    });
    sound.producer = options.producer;
    sound.story = options.story;

    return sound;
  }

  return SoundFactory;
})
.service('prxPlayer', function (Bus) {
  return {
    $lastHeartbeat: 0,
    play: function (sound) {
      if (!sound || this.nowPlaying == sound && this.nowPlaying.paused) {
        return this.resume();
      } else if (this.nowPlaying != sound) {
        this.stop();
        this.nowPlaying = sound;
        this.nowPlaying.onfinish = angular.bind(this, this.stop);
        Bus.emit('audioPlayer.play', this.nowPlaying);
        return sound.play();
      }
    },
    sendHeartbeat: function (force) {
      if (this.nowPlaying) {
        var position = Math.round(this.nowPlaying.position / 1000);
        if (force || (position - this.$lastHeartbeat) >= 15) {
          var seconds = position - this.$lastHeartbeat;
          Bus.emit('audioPlayer.listen', this.nowPlaying, seconds, this.$lastHeartbeat);
          this.$lastHeartbeat = position;
        }
      }
    },
    pause: function () {
      if (!this.nowPlaying.paused) {
        Bus.emit('audioPlayer.pause', this.nowPlaying);
        this.sendHeartbeat(true);
        return this.nowPlaying.pause();
      }
    },
    resume: function () {
      if (this.nowPlaying) {
        Bus.emit('audioPlayer.resume', this.nowPlaying);
        this.nowPlaying.resume();
      }
    },
    progress: function () {
      if (!this.nowPlaying) {
        return 0;
      }
      this.sendHeartbeat();
      return Math.round(this.nowPlaying.position /
        this.nowPlaying.story.duration) / 10 + '%';
    },
    stop: function () {
      if (this.nowPlaying) {
        this.nowPlaying.onfinish = undefined;
        this.sendHeartbeat(true);
        this.nowPlaying.stop();
        this.$lastHeartbeat = 0;
        Bus.emit('audioPlayer.stop', this.nowPlaying);
        this.nowPlaying = undefined;
      }
    }
  };
})
.directive('prxGlobalPlayer', function () {
  return {
    restrict: 'E',
    replace: true,
    controller: 'GlobalPlayerCtrl',
    controllerAs: 'player',
    templateUrl: 'player/global_player.html'
  };
})
.directive('prxPlayer', function ($controller, prxSoundFactory) {
  return {
    restrict: 'E',
    replace: true,
    templateUrl: 'player/player.html',
    controller: 'PlayerCtrl',
    controllerAs: 'player',
    link: function (scope, elem, attrs, ctrl) {
      scope.$watch(attrs.sound, angular.bind(ctrl, ctrl.setSound));
    }
  };
})
.directive('prxPlayerButton', function ($controller, prxSoundFactory) {
  return {
    restrict: 'E',
    replace: true,
    scope: true,
    require: '^?prxPlayer',
    templateUrl: 'player/button.html',
    link: function (scope, elem, attrs, ctrl) {
      if (!ctrl) {
        ctrl = $controller('PlayerCtrl', {$scope: scope});
        scope.$parent.$watch(attrs.sound, angular.bind(ctrl, ctrl.setSound));
      }
      scope.player = ctrl;
    }
  };
})
.controller('PlayerCtrl', function (prxPlayer) {
  this.setSound = function (newSound) {
    this.sound = newSound;
  };

  this.pause = function () {
    if (this.sound == prxPlayer.nowPlaying) {
      prxPlayer.pause();
    }
  };

  this.play = function () {
    prxPlayer.play(this.sound);
  };

  this.toggle = function () {
    if (this.sound && this.sound.paused) {
      this.play();
    } else {
      this.pause();
    }
  };

  this.active = function () {
    return this.sound && (!this.sound.paused || this.sound.position > 0);
  };

  this.progress = function () {
    return this.sound && Math.round((this.sound.position || 0) /
      this.duration()) / 10;
  };

  this.duration = function () {
    return (this.sound && this.sound.story.duration) || 1;
  };

  this.scrubToPercent = function (percent) {
    return this.setPosition(this.duration() * percent * 10);
  };

  this.setPosition = function (position) {
    if (prxPlayer.nowPlaying == this.sound) {
      prxPlayer.sendHeartbeat(true);
    }
    this.sound.setPosition(position);
  };
})
.directive('prxPlayerScrubber', function () {
  return {
    restrict: 'A',
    scope: {'prxPlayerScrubber': '&'},
    link: function (scope, elem, attrs) {
      elem.bind('click', click);

      elem.children().css('pointer-events', 'none');

      scope.$on('$destroy', function () {
        elem.unbind('click', click);
      });

      function click (event) {
        scope.prxPlayerScrubber({percentage: (event.offsetX || event.layerX) * 100 / event.target.offsetWidth});
      }
    }
  };
})
.filter('timeCode', function () {
  var zero = timeCode(0);

  function dd(num) {
    if (num < 10) {
      return '0' + num;
    }
    return num;
  }

  function timeCode(time, fmt) {
    if (typeof fmt === 'undefined') {
      fmt = 'long';
    }

    var hours, minutes, seconds;
    if (isNaN(time)) {
      return zero;
    } else {
      time = ~~(time / 1000);
    }
    hours = ~~(time / 3600);
    minutes = ~~((time % 3600) / 60);
    seconds = ~~(time % 60);

    if (fmt == 'long' || hours) {
      return [hours, ":", dd(minutes), ":", dd(seconds)].join('');
    } else {
      return [minutes, ":", dd(seconds)].join('');
    }
  }

  return timeCode;
})
.controller('GlobalPlayerCtrl', function (prxPlayer) {
  this.global = prxPlayer;
})
.directive('prxPlayerWaveform', function ($window, $timeout) {
  return {
    restrict: 'E',
    scope: true,
    templateUrl: 'player/waveform.html',
    replace: true,
    link: function (scope, elem, attrs) {
      var active = false, animated = false, currentSound, timeout, ctx = elem[0].getContext('2d');

      function scheduleWaveform () {
        if (!timeout) {
          timeout = $timeout(generateWaveform, 500);
        }
      }

      function generateWaveform () {
        var count = Math.floor(elem[0].offsetWidth / 5);
        if (count || !animated) {
          elem[0].width = elem[0].offsetWidth * 2;
          elem[0].height = elem[0].offsetHeight * 2;
          if (elem[0].currentStyle) {
            ctx.strokeStyle = elem[0].currentStyle['border-color'];
          } else if (window.getComputedStyle) {
            var style = window.getComputedStyle(elem[0], null);
            ctx.strokeStyle = style['borderRightColor'] || style.getPropertyValue('border-color');
          }

          ctx.lineWidth = 6;

          var points = [];
          var perBar = (currentSound.$waveform.length - 1) / count;
          var i = perBar / 2, x, start;

          do {
            start = Math.min(i, currentSound.$waveform.length - 1);
            if (start == ~~start) {
              points.push(currentSound.$waveform[start]);
            } else if (start < currentSound.$waveform.length - 1) {
              x = start - ~~start;
              points.push(currentSound.$waveform[~~start] * (1 - x) + currentSound.$waveform[~~start+1] * (x));
            }

            i += perBar;
          } while (i <= currentSound.$waveform.length - 1);

          if (!animated && window.requestAnimationFrame) {
            animateIn(points, ctx, elem[0].height, elem[0].width).then(function () {
              timeout = undefined;
            });
          } else {
            angular.forEach(points, function (point, index) {
              ctx.beginPath();
              ctx.moveTo(10 * index + 5, elem[0].height);
              ctx.lineTo(10 * index + 5, (100-point) / 100 * elem[0].height);
              ctx.stroke();
            });
            timeout = undefined;
          }
        }
      }

      function animateIn(points, ctx, height, width) {
        animated = ~~new Date();
        animate();
        function animate() {
          var time = Math.pow(Math.min((~~new Date() - animated) / 200, 1) - 1, 3) + 1;
          ctx.clearRect(0, 0, width, height);
          angular.forEach(points, function (point, index) {
            ctx.beginPath();
            ctx.moveTo(10 * index + 5, height);
            ctx.lineTo(10 * index + 5, Math.max(100 - point * time, 1) / 100 * height);
            ctx.stroke();
          });
          if (time < 1) {
            window.requestAnimationFrame(animate);
          }
        }
        return $timeout(angular.noop, 210);
      }

      scope.$watch(attrs.sound, function (sound) {
        currentSound = sound;
        if (sound && !sound.$waveform) {
          sound.$waveform = [];

          for (var i=0; i < 15; i+= 0.3) {
            sound.$waveform.push(Math.sin(i) * 49 + 51);
          }
        }
        if (!active) {
          active = true;
          scheduleWaveform();
          angular.element($window).on('resize', scheduleWaveform);
        }
      });

      scope.$on('$destroy', function () {
        angular.element($window).off('resize', scheduleWaveform);
      });
    }
  };
});
<commit_msg>animate in better<commit_after>angular.module('prx.player', ['ngPlayerHater', 'angulartics', 'prx.bus'])
.run(function (Bus, $analytics) {
  var category = 'Audio Player';

  Bus.on('audioPlayer.stop', function () {
    $analytics.eventTrack('Stop', {
      category: category,
      label: this.story.id
    });
  }).on('audioPlayer.resume', function () {
    $analytics.eventTrack('Resume', {
      category: category,
      label: this.story.id
    });
  }).on('audioPlayer.pause', function () {
    $analytics.eventTrack('Pause', {
      category: category,
      label: this.story.id
    });
  }).on('audioPlayer.play', function () {
    $analytics.eventTrack('Play', {
      category: category,
      label: this.story.id
    });
  }).on('audioPlayer.listen', function (audioFile, duration, startTime) {
    $analytics.eventTrack('Listen', {
      category: category,
      label: this.story.id,
      pieceId: this.story.id,
      audioFileId: audioFile.id,
      value: duration,
      duration: duration,
      startedAt: startTime,
      noninteraction: true
    });
  });
})
.factory('prxSoundFactory', function (smSound) {
  function SoundFactory (options) {
    var sound = smSound.createList(options.audioFiles, {
      onfinish: function () {
        if (angular.isFunction(sound.onfinish)) {
          sound.onfinish();
        }
      }
    });
    sound.producer = options.producer;
    sound.story = options.story;

    return sound;
  }

  return SoundFactory;
})
.service('prxPlayer', function (Bus) {
  return {
    $lastHeartbeat: 0,
    play: function (sound) {
      if (!sound || this.nowPlaying == sound && this.nowPlaying.paused) {
        return this.resume();
      } else if (this.nowPlaying != sound) {
        this.stop();
        this.nowPlaying = sound;
        this.nowPlaying.onfinish = angular.bind(this, this.stop);
        Bus.emit('audioPlayer.play', this.nowPlaying);
        return sound.play();
      }
    },
    sendHeartbeat: function (force) {
      if (this.nowPlaying) {
        var position = Math.round(this.nowPlaying.position / 1000);
        if (force || (position - this.$lastHeartbeat) >= 15) {
          var seconds = position - this.$lastHeartbeat;
          Bus.emit('audioPlayer.listen', this.nowPlaying, seconds, this.$lastHeartbeat);
          this.$lastHeartbeat = position;
        }
      }
    },
    pause: function () {
      if (!this.nowPlaying.paused) {
        Bus.emit('audioPlayer.pause', this.nowPlaying);
        this.sendHeartbeat(true);
        return this.nowPlaying.pause();
      }
    },
    resume: function () {
      if (this.nowPlaying) {
        Bus.emit('audioPlayer.resume', this.nowPlaying);
        this.nowPlaying.resume();
      }
    },
    progress: function () {
      if (!this.nowPlaying) {
        return 0;
      }
      this.sendHeartbeat();
      return Math.round(this.nowPlaying.position /
        this.nowPlaying.story.duration) / 10 + '%';
    },
    stop: function () {
      if (this.nowPlaying) {
        this.nowPlaying.onfinish = undefined;
        this.sendHeartbeat(true);
        this.nowPlaying.stop();
        this.$lastHeartbeat = 0;
        Bus.emit('audioPlayer.stop', this.nowPlaying);
        this.nowPlaying = undefined;
      }
    }
  };
})
.directive('prxGlobalPlayer', function () {
  return {
    restrict: 'E',
    replace: true,
    controller: 'GlobalPlayerCtrl',
    controllerAs: 'player',
    templateUrl: 'player/global_player.html'
  };
})
.directive('prxPlayer', function ($controller, prxSoundFactory) {
  return {
    restrict: 'E',
    replace: true,
    templateUrl: 'player/player.html',
    controller: 'PlayerCtrl',
    controllerAs: 'player',
    link: function (scope, elem, attrs, ctrl) {
      scope.$watch(attrs.sound, angular.bind(ctrl, ctrl.setSound));
    }
  };
})
.directive('prxPlayerButton', function ($controller, prxSoundFactory) {
  return {
    restrict: 'E',
    replace: true,
    scope: true,
    require: '^?prxPlayer',
    templateUrl: 'player/button.html',
    link: function (scope, elem, attrs, ctrl) {
      if (!ctrl) {
        ctrl = $controller('PlayerCtrl', {$scope: scope});
        scope.$parent.$watch(attrs.sound, angular.bind(ctrl, ctrl.setSound));
      }
      scope.player = ctrl;
    }
  };
})
.controller('PlayerCtrl', function (prxPlayer) {
  this.setSound = function (newSound) {
    this.sound = newSound;
  };

  this.pause = function () {
    if (this.sound == prxPlayer.nowPlaying) {
      prxPlayer.pause();
    }
  };

  this.play = function () {
    prxPlayer.play(this.sound);
  };

  this.toggle = function () {
    if (this.sound && this.sound.paused) {
      this.play();
    } else {
      this.pause();
    }
  };

  this.active = function () {
    return this.sound && (!this.sound.paused || this.sound.position > 0);
  };

  this.progress = function () {
    return this.sound && Math.round((this.sound.position || 0) /
      this.duration()) / 10;
  };

  this.duration = function () {
    return (this.sound && this.sound.story.duration) || 1;
  };

  this.scrubToPercent = function (percent) {
    return this.setPosition(this.duration() * percent * 10);
  };

  this.setPosition = function (position) {
    if (prxPlayer.nowPlaying == this.sound) {
      prxPlayer.sendHeartbeat(true);
    }
    this.sound.setPosition(position);
  };
})
.directive('prxPlayerScrubber', function () {
  return {
    restrict: 'A',
    scope: {'prxPlayerScrubber': '&'},
    link: function (scope, elem, attrs) {
      elem.bind('click', click);

      elem.children().css('pointer-events', 'none');

      scope.$on('$destroy', function () {
        elem.unbind('click', click);
      });

      function click (event) {
        scope.prxPlayerScrubber({percentage: (event.offsetX || event.layerX) * 100 / event.target.offsetWidth});
      }
    }
  };
})
.filter('timeCode', function () {
  var zero = timeCode(0);

  function dd(num) {
    if (num < 10) {
      return '0' + num;
    }
    return num;
  }

  function timeCode(time, fmt) {
    if (typeof fmt === 'undefined') {
      fmt = 'long';
    }

    var hours, minutes, seconds;
    if (isNaN(time)) {
      return zero;
    } else {
      time = ~~(time / 1000);
    }
    hours = ~~(time / 3600);
    minutes = ~~((time % 3600) / 60);
    seconds = ~~(time % 60);

    if (fmt == 'long' || hours) {
      return [hours, ":", dd(minutes), ":", dd(seconds)].join('');
    } else {
      return [minutes, ":", dd(seconds)].join('');
    }
  }

  return timeCode;
})
.controller('GlobalPlayerCtrl', function (prxPlayer) {
  this.global = prxPlayer;
})
.directive('prxPlayerWaveform', function ($window, $timeout) {
  return {
    restrict: 'E',
    scope: true,
    templateUrl: 'player/waveform.html',
    replace: true,
    link: function (scope, elem, attrs) {
      var active = false, animated = false, currentSound, timeout, ctx = elem[0].getContext('2d');

      function scheduleWaveform () {
        if (!timeout) {
          timeout = $timeout(generateWaveform, 500);
        }
      }

      function generateWaveform () {
        var count = Math.floor(elem[0].offsetWidth / 5);
        if (count || !animated) {
          elem[0].width = elem[0].offsetWidth * 2;
          elem[0].height = elem[0].offsetHeight * 2;
          if (elem[0].currentStyle) {
            ctx.strokeStyle = elem[0].currentStyle['border-color'];
          } else if (window.getComputedStyle) {
            var style = window.getComputedStyle(elem[0], null);
            ctx.strokeStyle = style['borderRightColor'] || style.getPropertyValue('border-color');
          }

          ctx.lineWidth = 6;

          var points = [];
          var perBar = (currentSound.$waveform.length - 1) / count;
          var i = perBar / 2, x, start;

          do {
            start = Math.min(i, currentSound.$waveform.length - 1);
            if (start == ~~start) {
              points.push(currentSound.$waveform[start]);
            } else if (start < currentSound.$waveform.length - 1) {
              x = start - ~~start;
              points.push(currentSound.$waveform[~~start] * (1 - x) + currentSound.$waveform[~~start+1] * (x));
            }

            i += perBar;
          } while (i <= currentSound.$waveform.length - 1);

          if (!animated && window.requestAnimationFrame) {
            animateIn(points, ctx, elem[0].height, elem[0].width).then(function () {
              timeout = undefined;
            });
          } else {
            angular.forEach(points, function (point, index) {
              ctx.beginPath();
              ctx.moveTo(10 * index + 5, elem[0].height);
              ctx.lineTo(10 * index + 5, (100-point) / 100 * elem[0].height);
              ctx.stroke();
            });
            timeout = undefined;
          }
        }
      }

      function animateIn(points, ctx, height, width) {
        animated = ~~new Date();
        animate();
        function animate() {
          var time = Math.pow(Math.min((~~new Date() - animated) / 500, 1) - 1, 3) + 1;
          ctx.clearRect(0, 0, width, height);
          angular.forEach(points, function (point, index) {
            ctx.beginPath();
            ctx.moveTo(10 * index + 5, height);
            ctx.lineTo(10 * index + 5, Math.max(100 - point * time + (point * index/points.length * (1 - Math.pow(time, 3))), 1) / 100 * height);
            ctx.stroke();
          });
          if (time < 1) {
            window.requestAnimationFrame(animate);
          }
        }
        return $timeout(angular.noop, 510);
      }

      scope.$watch(attrs.sound, function (sound) {
        currentSound = sound;
        if (sound && !sound.$waveform) {
          sound.$waveform = [];

          for (var i=0; i < 15; i+= 0.3) {
            sound.$waveform.push(Math.sin(i) * 49 + 51);
          }
        }
        if (!active) {
          active = true;
          scheduleWaveform();
          angular.element($window).on('resize', scheduleWaveform);
        }
      });

      scope.$on('$destroy', function () {
        angular.element($window).off('resize', scheduleWaveform);
      });
    }
  };
});
<|endoftext|>


<commit_before>/*
    // tabs.js widget for creating and displaying tabs

    // Instantiation
    // optional: content, active, removable
    // you can make all tabs or individual tabs removable

        var tabs = $('#ele').tabs();

        //or

        var tabs = $('#ele').tabs({tabs: [
                                {name: 'tab1', content: 'foo text or html', active: true},
                                {name: 'tab2', content: 'text or html 2', removable: true}
                                ]
                              });

    // Add a new tab
    // optional: content, active

        tabs.addTab({name: 'tab3', content: 'new content'})

    // Retrieve a tab button
    // (useful for adding events or other stuff)

        var mytab = tabs.tab('tab1')

    // Add content to existing tab
    // (useful for ajax/event stuff)

        tabs.tab({name: 'tab3', content: 'blah blah blah'})

    // manually show a tab
    // Tab panes are shown when clicked automatically.
    // This is a programmatic way of showing a tab.

        tabs.showTab('tab_name');
*/

(function( $, undefined ) {

    $.KBWidget({
        name: "kbTabs",
        version: "1.0.0",
        init: function(options) {
            this._super(options);
            var container = this.$elem;
            var self = this;

            var tabs = $('
');
            var tab_contents = $('
');
            container.append(tabs, tab_contents);

            // adds a single tab and content
            this.addTab = function(p, animate) {
                // if tab exists, don't add
                if ( tabs.find('a[data-id="'+p.name+'"]').length > 0) {
                    return;
                }

                // tab
                var tab = $('
');
                var tab_link = $(''+p.name+'');

                // animate by sliding tab up
                if (animate) {
                    tab.append(tab_link).hide();
                    tabs.append(tab);
                    tab.toggle('slide', {direction: 'down', duration: 'fast'});
                } else {
                    tab.append(tab_link)
                    tabs.append(tab);
                }

                // add close button if needed
                if (p.removable || options.removable) {
                    var rm_btn = $('');
                    tab_link.append(rm_btn);

                    rm_btn.click(function(e) {
                        self.rmTab(p.name)
                    })
                }

                // add content pane
                console.log('adding:', p.name, p.active)
                var c = $('
')
                c.append((p.content ? p.content : ''))
                tab_contents.append(c);

                tab.click(function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    var id = $(this).find('a').data('id');
                    self.showTab(id);
                })
                //events();

                return p.content;
            }

            // remove tab and tab content
            this.rmTab = function(name) {
                var tab = tabs.find('a[data-id="'+name+'"]').parent('li');
                var tab_content = tab_contents.children('[data-id="'+name+'"]')

                // show the next or prev tab
                if (tab.next().length > 0) {
                    var id = tab.next().children('a').data('id');
                } else {
                    var id = tab.prev().children('a').data('id');
                }

                // remove the tab
                tab.remove();
                tab_content.remove();
            }

            // returns tab
            this.tab = function(name) {
                return tabs.children('[data-id="'+name+'"]');
            }

            // returns content of tab
            this.tabContent = function(name) {
                return tab_contents.children('[data-id="'+name+'"]');
            }

            // adds content to existing tab pane; useful for ajax
            this.addContent = function(p) {
                var c = tab_contents.children('[data-id="'+p.name+'"]')
                c.append((p.content ? p.content : ''));

                return c;
            }

            // highlights tab and shows content
            this.showTab = function(id) {
                tabs.children('li').removeClass('active');
                tab_contents.children('.tab-pane').removeClass('active');

                tabs.find('a[data-id="'+id+'"]').parent().addClass('active');
                tab_contents.children('[data-id="'+id+'"]').addClass('active');
            }

            // if tabs are supplied, add them
            if (options.tabs) {
                for (var i in options.tabs) {
                    this.addTab(options.tabs[i], false)
                }
            }

            // events for showing tabs
            function events() {
                tabs.find('a').unbind('click')
                tabs.find('a').click(function (e) {
                    e.preventDefault();
                    e.stopPropagation();

                    // show tab and content
                    var id = $(this).data('id');
                    self.showTab(id);
                })
            }

            return this;
        },
    });
}( jQuery ) );
<commit_msg>old code<commit_after>/*
    // tabs.js widget for creating and displaying tabs

    // Instantiation
    // optional: content, active, removable
    // you can make all tabs or individual tabs removable

        var tabs = $('#ele').tabs();

        //or

        var tabs = $('#ele').tabs({tabs: [
                                {name: 'tab1', content: 'foo text or html', active: true},
                                {name: 'tab2', content: 'text or html 2', removable: true}
                                ]
                              });

    // Add a new tab
    // optional: content, active

        tabs.addTab({name: 'tab3', content: 'new content'})

    // Retrieve a tab button
    // (useful for adding events or other stuff)

        var mytab = tabs.tab('tab1')

    // Add content to existing tab
    // (useful for ajax/event stuff)

        tabs.tab({name: 'tab3', content: 'blah blah blah'})

    // manually show a tab
    // Tab panes are shown when clicked automatically.
    // This is a programmatic way of showing a tab.

        tabs.showTab('tab_name');
*/

(function( $, undefined ) {

    $.KBWidget({
        name: "kbTabs",
        version: "1.0.0",
        init: function(options) {
            this._super(options);
            var container = this.$elem;
            var self = this;

            var tabs = $('
');
            var tab_contents = $('
');
            container.append(tabs, tab_contents);

            // adds a single tab and content
            this.addTab = function(p, animate) {
                // if tab exists, don't add
                if ( tabs.find('a[data-id="'+p.name+'"]').length > 0) {
                    return;
                }

                // tab
                var tab = $('
');
                var tab_link = $(''+p.name+'');

                // animate by sliding tab up
                if (animate) {
                    tab.append(tab_link).hide();
                    tabs.append(tab);
                    tab.toggle('slide', {direction: 'down', duration: 'fast'});
                } else {
                    tab.append(tab_link)
                    tabs.append(tab);
                }

                // add close button if needed
                if (p.removable || options.removable) {
                    var rm_btn = $('');
                    tab_link.append(rm_btn);

                    rm_btn.click(function(e) {
                        self.rmTab(p.name)
                    })
                }

                // add content pane
                console.log('adding:', p.name, p.active)
                var c = $('
')
                c.append((p.content ? p.content : ''))
                tab_contents.append(c);

                tab.click(function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    var id = $(this).find('a').data('id');
                    self.showTab(id);
                })

                return p.content;
            }

            // remove tab and tab content
            this.rmTab = function(name) {
                var tab = tabs.find('a[data-id="'+name+'"]').parent('li');
                var tab_content = tab_contents.children('[data-id="'+name+'"]')

                // show the next or prev tab
                if (tab.next().length > 0) {
                    var id = tab.next().children('a').data('id');
                } else {
                    var id = tab.prev().children('a').data('id');
                }

                // remove the tab
                tab.remove();
                tab_content.remove();
            }

            // returns tab
            this.tab = function(name) {
                return tabs.children('[data-id="'+name+'"]');
            }

            // returns content of tab
            this.tabContent = function(name) {
                return tab_contents.children('[data-id="'+name+'"]');
            }

            // adds content to existing tab pane; useful for ajax
            this.addContent = function(p) {
                var c = tab_contents.children('[data-id="'+p.name+'"]')
                c.append((p.content ? p.content : ''));

                return c;
            }

            // highlights tab and shows content
            this.showTab = function(id) {
                tabs.children('li').removeClass('active');
                tab_contents.children('.tab-pane').removeClass('active');

                tabs.find('a[data-id="'+id+'"]').parent().addClass('active');
                tab_contents.children('[data-id="'+id+'"]').addClass('active');
            }

            // if tabs are supplied, add them
            if (options.tabs) {
                for (var i in options.tabs) {
                    this.addTab(options.tabs[i], false)
                }
            }

            return this;
        },
    });
}( jQuery ) );
<|endoftext|>


<commit_before>/**
 * @constructor
 * @param {o} o Orchestrate object
 * @param {Object} branchConfig
 * @returns {Chain}
 */
function Chain (o, branchConfig) {
	this.steps = [];
	this.branchConfig = branchConfig;
	this.o = o;
	this.currentIndex = -1;
};

/**
 * Registers a new step
 * @param {Object} config
 * @param {Callback} callback
 * @returns {undefined}
 */
Chain.prototype.addStep = function (config, callback) {
	this.steps.push({
		config: config,
		callback: callback
	});
};

/**
 * Executes next step
 * @param {o} o Orechstrate object
 * @param {Chain} chain
 * @param {mixed} value
 * @returns {mixed}
 */
Chain.prototype.next = function (o, chain, value) {
	var nextIndex = this.currentIndex + 1;

	// check if next index exists
	if (nextIndex < this.steps.length) {
		return this.executeStepAt(nextIndex, o, chain, value);
	}
};

/**
 * Executes step
 * @param {Number} stepIndex
 * @param {o} o Orechstrate object
 * @param {Chain} chain
 * @param {mixed} value
 * @returns {undefined}
 */
Chain.prototype.executeStepAt = function (stepIndex, o, chain, value) {
	// validate step exists
	if (typeof this.steps[stepIndex] === undefined) {
		throw new Error('stepIndex: ' + stepIndex + ' does not exist on chain');
	}

	// rebind o if its undefined
	if (o === undefined) {
		o = this.o;
	}

	// bind "this" chain if its undefined
	if (chain === undefined) {
		chain = this;
	}

	// if there's a default value config, apply it
	if (value === undefined && this.steps[stepIndex].config.defaultValue !== undefined) {
		value = this.steps[stepIndex].config.defaultValue;
	}

	// set pointer
	this.currentIndex = stepIndex;

	// invoke method (with config)
	this.steps[stepIndex].callback(o, chain, value, this.steps[stepIndex].config);
};

// chain factory
module.exports = function (o, branchConfig) {
	return new Chain(o, branchConfig);
};<commit_msg>fixed default config check exception if no config obj is present<commit_after>/**
 * @constructor
 * @param {o} o Orchestrate object
 * @param {Object} branchConfig
 * @returns {Chain}
 */
function Chain (o, branchConfig) {
	this.steps = [];
	this.branchConfig = branchConfig;
	this.o = o;
	this.currentIndex = -1;
};

/**
 * Registers a new step
 * @param {Object} config
 * @param {Callback} callback
 * @returns {undefined}
 */
Chain.prototype.addStep = function (config, callback) {
	this.steps.push({
		config: config,
		callback: callback
	});
};

/**
 * Executes next step
 * @param {o} o Orechstrate object
 * @param {Chain} chain
 * @param {mixed} value
 * @returns {mixed}
 */
Chain.prototype.next = function (o, chain, value) {
	var nextIndex = this.currentIndex + 1;

	// check if next index exists
	if (nextIndex < this.steps.length) {
		return this.executeStepAt(nextIndex, o, chain, value);
	}
};

/**
 * Executes step
 * @param {Number} stepIndex
 * @param {o} o Orechstrate object
 * @param {Chain} chain
 * @param {mixed} value
 * @returns {undefined}
 */
Chain.prototype.executeStepAt = function (stepIndex, o, chain, value) {
	// validate step exists
	if (typeof this.steps[stepIndex] === undefined) {
		throw new Error('stepIndex: ' + stepIndex + ' does not exist on chain');
	}

	// rebind o if its undefined
	if (o === undefined) {
		o = this.o;
	}

	// bind "this" chain if its undefined
	if (chain === undefined) {
		chain = this;
	}

	// if there's a default value config, apply it
	if (
			value === undefined &&
			this.steps[stepIndex].config !== undefined &&
			this.steps[stepIndex].config.defaultValue !== undefined
	) {
		value = this.steps[stepIndex].config.defaultValue;
	}

	// set pointer
	this.currentIndex = stepIndex;

	// invoke method (with config)
	this.steps[stepIndex].callback(o, chain, value, this.steps[stepIndex].config);
};

// chain factory
module.exports = function (o, branchConfig) {
	return new Chain(o, branchConfig);
};<|endoftext|>


<commit_before>/**
 * DIRECTIVES
 *
 * Miscellaneous directives go in this file.
 */

var module = angular.module('directives', ['popup']);

/**
 * Inline edit
 */
module.directive('inlineEdit', function () {
  var previewTemplate = '{{model}}';
  var editTemplate = '<input ng-show="mode" ng-model="model" />';

  return {
    restrict: 'E',
    scope: {
      model: '=',
      mode: '='
    },
    template: previewTemplate + editTemplate
  };
});

/*
 * Defines the rp-if tag. This removes/adds an element from the dom depending on a condition
 * Originally created by @tigbro, for the @jquery-mobile-angular-adapter
 * https://github.com/tigbro/jquery-mobile-angular-adapter
 */
module.directive('rpIf', [function () {
  return {
    transclude: 'element',
    priority: 1000,
    terminal: true,
    restrict: 'A',
    compile: function (element, attr, linker) {
      return function (scope, iterStartElement, attr) {
        iterStartElement[0].doNotMove = true;
        var expression = attr.rpIf;
        var lastElement;
        var lastScope;
        scope.$watch(expression, function (newValue) {
          if (lastElement) {
            lastElement.remove();
            lastElement = null;
          }
          if (lastScope) {
            lastScope.$destroy();
            lastScope = null;
          }
          if (newValue) {
            lastScope = scope.$new();
            linker(lastScope, function (clone) {
              lastElement = clone;
              iterStartElement.after(clone);
            });
          }
          // Note: need to be parent() as jquery cannot trigger events on comments
          // (angular creates a comment node when using transclusion, as ng-repeat does).
          iterStartElement.parent().trigger("$childrenChanged");
        });
      };
    }
  };
}]);

/**
 * Group of validation errors for a form field.
 *
 * @example
 *   <input name=send_destination ng-model=recipient>
 *

 *
This field is required.

 *
{{recipient}} is a valid destination.

 *

 */
var RP_ERRORS = 'rp-errors';
module.directive('rpErrors', [function () {
  return {
    restrict: 'EA',
    compile: function (el, attr, linker) {
      var fieldName = attr.rpErrors || attr.on,
          errs = {};

      el.data(RP_ERRORS, errs);
      return function (scope, el) {
        var formController = el.inheritedData('$formController');
        var formName = formController.$name,
            selectedTransclude,
            selectedElement,
            selectedScope;

        function updateErrorTransclude() {
          var field = formController[fieldName],
              $error = field.$error;

          if (selectedElement) {
            selectedScope.$destroy();
            selectedElement.remove();
            selectedElement = selectedScope = null;
          }

          // Pristine fields should show neither success nor failure messages
          if (field.$pristine) return;

          // Find any error messages defined for current errors
          selectedTransclude = false;
          $.each(errs, function (validator, transclude) {
            if (validator.length <= 1) return;
            if ($error[validator.slice(1)]) {
              selectedTransclude = transclude;
              return false;
            }
          });

          // Show message for valid fields
          if (!selectedTransclude && errs['+'] && field.$valid) {
            selectedTransclude = errs['+'];
          }

          // Generic message for invalid fields when there is no specific msg
          if (!selectedTransclude && errs['?'] && field.$invalid) {
            selectedTransclude = errs['?'];
          }

          if (selectedTransclude) {
            scope.$eval(attr.change);
            selectedScope = scope.$new();
            selectedTransclude(selectedScope, function(errElement) {
              selectedElement = errElement;
              el.append(errElement);
            });
          }
        }

        scope.$watch(formName+'.'+fieldName+'.$error', updateErrorTransclude, true);
        scope.$watch(formName+'.'+fieldName+'.$pristine', updateErrorTransclude);
      };
    }
  };
}]);

/**
 * Error message for validator failure.
 *
 * Use this directive within a rp-errors block to show a message for a specific
 * validation failing.
 *
 * @example
 *

 *
This field is required.

 *

 */
module.directive('rpErrorOn', [function () {
  return {
    transclude: 'element',
    priority: 500,
    compile: function (element, attrs, transclude) {
      var errs = element.inheritedData(RP_ERRORS);
      if (!errs) return;
      errs['!' + attrs.rpErrorOn] = transclude;
    }
  };
}]);

/**
 * Message for no matched validator failures.
 *
 * Use this directive within a rp-errors block to show a message if the field is
 * invalid, but there was no error message defined for any of the failing
 * validators.
 *
 * @example
 *

 *
This field is required.

 *
Invalid value.

 *

 */
module.directive('rpErrorUnknown', [function () {
  return {
    transclude: 'element',
    priority: 500,
    compile: function (element, attrs, transclude) {
      var errs = element.inheritedData(RP_ERRORS);
      if (!errs) return;
      errs['?'] = transclude;
    }
  };
}]);

/**
 * Message for field valid.
 *
 * Use this directive within a rp-errors block to show a message if the field is
 * valid.
 */
module.directive('rpErrorValid', [function () {
  return {
    transclude: 'element',
    priority: 500,
    compile: function (element, attrs, transclude) {
      var errs = element.inheritedData(RP_ERRORS);
      if (!errs) return;
      errs['+'] = transclude;
    }
  };
}]);

module.directive('rpConfirm', ['rpPopup', function (popup) {
  return {
    restrict: 'E',
    link: function postLink(scope, element, attrs) {
      // Could have custom or bootstrap modal options here
      var popupOptions = {};
      element.find('a,button').click(function()
      {
        popup.confirm(attrs["title"], attrs["actionText"],
            attrs["actionButtonText"], attrs["actionFunction"], attrs["actionButtonCss"],
            attrs["cancelButtonText"], attrs["cancelFunction"], attrs["cancelButtonCss"],
            scope, popupOptions);
      });
    }
  };
}]);

/*
 * Adds download functionality to an element.
 */
module.directive('rpDownload', [function () {
  return {
    restrict: 'A',
    scope: {
      data: '=rpDownload',
      filename: '@rpDownloadFilename'
    },
    compile: function (element, attr, linker) {
      return function (scope, element, attr) {
        var trigger = element.find('[rp-download-trigger]');
        if (!trigger.length) trigger = element;

        element.css('position', 'relative');

        setImmediate(function () {
          var width = trigger.innerWidth();
          var height = trigger.innerHeight();
          var offsetTrigger = trigger.offset();
          var offsetElement = element.offset();
          var topOffset = offsetTrigger.top - offsetElement.top;
          var leftOffset = offsetTrigger.left - offsetElement.left;
          var dl = Downloadify.create(element[0], {
            filename: function () {
              return scope.filename;
            },
            data: function () {
              return scope.data;
            },
            transparent: true,
            swf: 'swf/downloadify.swf',
            downloadImage: 'img/transparent_l.gif',
            width: width,
            height: height,
            append: true
          });

          var id = dl.flashContainer.id;
          $('#'+id).css({
            position: 'absolute',
            top: topOffset + 'px',
            left: leftOffset + 'px'
          });
        });
      };
    }
  };
}]);

/**
 * Tooltips
 */
module.directive('rpTooltip', [function () {
  return function (scope, element, attr) {
    attr.$observe('rpTooltip', function(value) {
      $(element).tooltip('destroy');
      $(element).tooltip({'title':value});
    });
  };
}]);

/**
 * Popovers
 */
module.directive('rpPopover', [function () {
  return function (scope, element, attr) {
    console.log(attr);
    $(element).popover({
      html: true,
      placement: attr.rpPopoverPlacement,
      title: attr.rpPopoverTitle
      // TODO also use rpPopoverContent attribute (there's a bug with this)
    });
  };
}]);

module.directive('rpAutofill', ['$parse', function ($parse) {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function ($scope, element, attr, ctrl) {
      if (!ctrl) return;

      $scope.$watch(attr.rpAutofill, function (value) {
        if (value) {
          element.val(value);
          ctrl.$setViewValue(value);
          $scope.$eval(attr.rpAutofillOn);
        }
      }, true);
    }
  };
}]);
<commit_msg>Remove console log from rpPopover directive<commit_after>/**
 * DIRECTIVES
 *
 * Miscellaneous directives go in this file.
 */

var module = angular.module('directives', ['popup']);

/**
 * Inline edit
 */
module.directive('inlineEdit', function () {
  var previewTemplate = '{{model}}';
  var editTemplate = '<input ng-show="mode" ng-model="model" />';

  return {
    restrict: 'E',
    scope: {
      model: '=',
      mode: '='
    },
    template: previewTemplate + editTemplate
  };
});

/*
 * Defines the rp-if tag. This removes/adds an element from the dom depending on a condition
 * Originally created by @tigbro, for the @jquery-mobile-angular-adapter
 * https://github.com/tigbro/jquery-mobile-angular-adapter
 */
module.directive('rpIf', [function () {
  return {
    transclude: 'element',
    priority: 1000,
    terminal: true,
    restrict: 'A',
    compile: function (element, attr, linker) {
      return function (scope, iterStartElement, attr) {
        iterStartElement[0].doNotMove = true;
        var expression = attr.rpIf;
        var lastElement;
        var lastScope;
        scope.$watch(expression, function (newValue) {
          if (lastElement) {
            lastElement.remove();
            lastElement = null;
          }
          if (lastScope) {
            lastScope.$destroy();
            lastScope = null;
          }
          if (newValue) {
            lastScope = scope.$new();
            linker(lastScope, function (clone) {
              lastElement = clone;
              iterStartElement.after(clone);
            });
          }
          // Note: need to be parent() as jquery cannot trigger events on comments
          // (angular creates a comment node when using transclusion, as ng-repeat does).
          iterStartElement.parent().trigger("$childrenChanged");
        });
      };
    }
  };
}]);

/**
 * Group of validation errors for a form field.
 *
 * @example
 *   <input name=send_destination ng-model=recipient>
 *

 *
This field is required.

 *
{{recipient}} is a valid destination.

 *

 */
var RP_ERRORS = 'rp-errors';
module.directive('rpErrors', [function () {
  return {
    restrict: 'EA',
    compile: function (el, attr, linker) {
      var fieldName = attr.rpErrors || attr.on,
          errs = {};

      el.data(RP_ERRORS, errs);
      return function (scope, el) {
        var formController = el.inheritedData('$formController');
        var formName = formController.$name,
            selectedTransclude,
            selectedElement,
            selectedScope;

        function updateErrorTransclude() {
          var field = formController[fieldName],
              $error = field.$error;

          if (selectedElement) {
            selectedScope.$destroy();
            selectedElement.remove();
            selectedElement = selectedScope = null;
          }

          // Pristine fields should show neither success nor failure messages
          if (field.$pristine) return;

          // Find any error messages defined for current errors
          selectedTransclude = false;
          $.each(errs, function (validator, transclude) {
            if (validator.length <= 1) return;
            if ($error[validator.slice(1)]) {
              selectedTransclude = transclude;
              return false;
            }
          });

          // Show message for valid fields
          if (!selectedTransclude && errs['+'] && field.$valid) {
            selectedTransclude = errs['+'];
          }

          // Generic message for invalid fields when there is no specific msg
          if (!selectedTransclude && errs['?'] && field.$invalid) {
            selectedTransclude = errs['?'];
          }

          if (selectedTransclude) {
            scope.$eval(attr.change);
            selectedScope = scope.$new();
            selectedTransclude(selectedScope, function(errElement) {
              selectedElement = errElement;
              el.append(errElement);
            });
          }
        }

        scope.$watch(formName+'.'+fieldName+'.$error', updateErrorTransclude, true);
        scope.$watch(formName+'.'+fieldName+'.$pristine', updateErrorTransclude);
      };
    }
  };
}]);

/**
 * Error message for validator failure.
 *
 * Use this directive within a rp-errors block to show a message for a specific
 * validation failing.
 *
 * @example
 *

 *
This field is required.

 *

 */
module.directive('rpErrorOn', [function () {
  return {
    transclude: 'element',
    priority: 500,
    compile: function (element, attrs, transclude) {
      var errs = element.inheritedData(RP_ERRORS);
      if (!errs) return;
      errs['!' + attrs.rpErrorOn] = transclude;
    }
  };
}]);

/**
 * Message for no matched validator failures.
 *
 * Use this directive within a rp-errors block to show a message if the field is
 * invalid, but there was no error message defined for any of the failing
 * validators.
 *
 * @example
 *

 *
This field is required.

 *
Invalid value.

 *

 */
module.directive('rpErrorUnknown', [function () {
  return {
    transclude: 'element',
    priority: 500,
    compile: function (element, attrs, transclude) {
      var errs = element.inheritedData(RP_ERRORS);
      if (!errs) return;
      errs['?'] = transclude;
    }
  };
}]);

/**
 * Message for field valid.
 *
 * Use this directive within a rp-errors block to show a message if the field is
 * valid.
 */
module.directive('rpErrorValid', [function () {
  return {
    transclude: 'element',
    priority: 500,
    compile: function (element, attrs, transclude) {
      var errs = element.inheritedData(RP_ERRORS);
      if (!errs) return;
      errs['+'] = transclude;
    }
  };
}]);

module.directive('rpConfirm', ['rpPopup', function (popup) {
  return {
    restrict: 'E',
    link: function postLink(scope, element, attrs) {
      // Could have custom or bootstrap modal options here
      var popupOptions = {};
      element.find('a,button').click(function()
      {
        popup.confirm(attrs["title"], attrs["actionText"],
            attrs["actionButtonText"], attrs["actionFunction"], attrs["actionButtonCss"],
            attrs["cancelButtonText"], attrs["cancelFunction"], attrs["cancelButtonCss"],
            scope, popupOptions);
      });
    }
  };
}]);

/*
 * Adds download functionality to an element.
 */
module.directive('rpDownload', [function () {
  return {
    restrict: 'A',
    scope: {
      data: '=rpDownload',
      filename: '@rpDownloadFilename'
    },
    compile: function (element, attr, linker) {
      return function (scope, element, attr) {
        var trigger = element.find('[rp-download-trigger]');
        if (!trigger.length) trigger = element;

        element.css('position', 'relative');

        setImmediate(function () {
          var width = trigger.innerWidth();
          var height = trigger.innerHeight();
          var offsetTrigger = trigger.offset();
          var offsetElement = element.offset();
          var topOffset = offsetTrigger.top - offsetElement.top;
          var leftOffset = offsetTrigger.left - offsetElement.left;
          var dl = Downloadify.create(element[0], {
            filename: function () {
              return scope.filename;
            },
            data: function () {
              return scope.data;
            },
            transparent: true,
            swf: 'swf/downloadify.swf',
            downloadImage: 'img/transparent_l.gif',
            width: width,
            height: height,
            append: true
          });

          var id = dl.flashContainer.id;
          $('#'+id).css({
            position: 'absolute',
            top: topOffset + 'px',
            left: leftOffset + 'px'
          });
        });
      };
    }
  };
}]);

/**
 * Tooltips
 */
module.directive('rpTooltip', [function () {
  return function (scope, element, attr) {
    attr.$observe('rpTooltip', function(value) {
      $(element).tooltip('destroy');
      $(element).tooltip({'title':value});
    });
  };
}]);

/**
 * Popovers
 */
module.directive('rpPopover', [function () {
  return function (scope, element, attr) {
    $(element).popover({
      html: true,
      placement: attr.rpPopoverPlacement,
      title: attr.rpPopoverTitle
      // TODO also use rpPopoverContent attribute (there's a bug with this)
    });
  };
}]);

module.directive('rpAutofill', ['$parse', function ($parse) {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function ($scope, element, attr, ctrl) {
      if (!ctrl) return;

      $scope.$watch(attr.rpAutofill, function (value) {
        if (value) {
          element.val(value);
          ctrl.$setViewValue(value);
          $scope.$eval(attr.rpAutofillOn);
        }
      }, true);
    }
  };
}]);
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import Hr from '../../components/Hr';

class DecisionTransitMethod extends PureComponent {
  renderHasBus() {
    return (

          We'll be sending a bus to {this.props.applicationForm.school.name}!

          Join the Facebook event{' '}

            here
          {' '}
          to stay up to date!

    );
  }

  renderHasCar() {
    return (

          Sadly we won't be able to send a bus to{' '}
          {this.props.applicationForm.school.name}.

          However, if you're willing to get here by your own means, we'd love to
          have you!.

            Please note that we will not be providing any form of travel
            reimbursements.

    );
  }

  renderHasFeet() {
    return (

        Well, you have it easy! BoilerMake will be happening in Hicks
        Undergraduate Library on campus.

    );
  }

  render() {
    return (

Getting to BoilerMake

        {this.props.method === 'bus' ? this.renderHasBus() : null}
        {this.props.method === 'car' ? this.renderHasCar() : null}
        {this.props.method === 'walk' ? this.renderHasFeet() : null}

    );
  }
}

export default DecisionTransitMethod;
<commit_msg>Fixes bus school FB events<commit_after>import React, { PureComponent } from 'react';
import Hr from '../../components/Hr';

class DecisionTransitMethod extends PureComponent {
  renderFBEvent() {
    const school = this.props.applicationForm.school.name;

    if (school === 'Illinois Institute of Technology') {
      return (

          Join the Facebook event
          here
          to stay up to date!

      );
    } else if (school === 'University of Illinois-Urbana-Champaign') {
      return (

          Join the Facebook event
          here
          to stay up to date!

      );
    } else {
      return null;
    }
  }

  renderHasBus() {
    const school = this.props.applicationForm.school.name;
    return (

We'll be sending a bus to {school}!

        {this.renderFBEvent()}

    );
  }

  renderHasCar() {
    return (

          Sadly we won't be able to send a bus to{' '}
          {this.props.applicationForm.school.name}.

          However, if you're willing to get here by your own means, we'd love to
          have you!.

            Please note that we will not be providing any form of travel
            reimbursements.

    );
  }

  renderHasFeet() {
    return (

        Well, you have it easy! BoilerMake will be happening in Hicks
        Undergraduate Library on campus.

    );
  }

  render() {
    return (

Getting to BoilerMake

        {this.props.method === 'bus' ? this.renderHasBus() : null}
        {this.props.method === 'car' ? this.renderHasCar() : null}
        {this.props.method === 'walk' ? this.renderHasFeet() : null}

    );
  }
}

export default DecisionTransitMethod;
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var gutil  = require('gulp-util');
var lazypipe = require('lazypipe');
var uglify = require('gulp-uglify');
var htmlmin = require('gulp-htmlmin');
var rev = require('gulp-rev');
var mocha = require('gulp-mocha');
var gettext = require('gulp-angular-gettext');
var buffer = require('gulp-buffer');
var browserify = require('browserify');
var karma = require('karma');
var path = require('path');

var _ = require('lodash');
var source = require('vinyl-source-stream');
var transformTools = require('browserify-transform-tools');
var jsLibs = require('./server/assets').libs();

// add Kibana's grunt tasks
// blocked on https://github.com/gratimax/gulp-grunt/issues/3
// for now you'll have to manually build Kibana
//require('gulp-grunt')(gulp, {
//  base: __dirname + '/kibana',
//  prefix: 'kibana-'
//});

// TODO use gulp-changed

// TODO get livereload working with https://github.com/mollerse/gulp-embedlr

var notBowerComponents = '!public/bower_components/**/*';

var paths = {
  scripts: ['public/**/*.js', notBowerComponents],
  styles: ['public/styles/main.less'], // other styles are loaded from main
  partials: ['public/**/*.html', notBowerComponents],
  html: 'views/**/*.html',
  indexHtml: 'views/index.html',
  serverTests: 'test/server/**/test-*.js',
  clientTests: 'test/client/**/test-*.js',
  imagesDest: 'dist/public/images',
  bowerComponents: 'public/bower_components',
  nodeModules: 'node_modules'
};

var fontExtensions = ['.eot', '.svg', '.ttf', '.woff'];

// build CSS for production
gulp.task('styles', function () {
  var less = require('gulp-less');
  var autoprefixer = require('gulp-autoprefixer');
  var minifycss = require('gulp-minify-css');

  return gulp.src(paths.styles)
    .pipe(less({
      paths: [paths.bowerComponents, paths.nodeModules]
    }))
    .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
    .pipe(minifycss())
    .pipe(rev())
    .pipe(gulp.dest('dist/public/styles'));
});

gulp.task('fonts', function () {
  return gulp.src(fontExtensions.map(function (ext) {
      return 'public/fonts/**/*' + ext;
    }))
    .pipe(gulp.dest('dist/public/fonts'));
});

gulp.task('jshint', function () {
  var jshint = require('gulp-jshint');

  return gulp.src(paths.scripts)
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(jshint.reporter('fail'));
});

// minifies partials and converts them to a JS string that can be `require`d
gulp.task('partials', function () {
  var replace = require('gulp-replace');
  var header = require('gulp-header');
  var footer = require('gulp-footer');

  return gulp.src(paths.partials)
    .pipe(htmlmin({
      collapseWhitespace: true,
      collapseBooleanAttributes: true,
      removeComments: true,
      removeAttributeQuotes: false,
      removeRedundantAttributes: true,
      removeEmptyAttributes: true,
      removeOptionalTags: false // removing is probably a bad idea with partial docs
    }))
    // inspired by https://github.com/visionmedia/node-string-to-js/blob/master/index.js
    .pipe(replace(/"/g, '\\"'))
    .pipe(replace(/\r\n|\r|\n/g, '\\n'))

    // wrap HTML in module
    .pipe(header('module.exports = "'))
    .pipe(footer('";'))

    .pipe(gulp.dest('.tmp/public/')); // write to .tmp so they can be read by browserify
});

/**
 * Task to build 3rd-party JavaScript libraries.
 */
gulp.task('libs', function () {
  var bundle = browserify();
  jsLibs.forEach(function (lib) {
    bundle.require(lib);
  });

  return bundle
    .bundle()
    .pipe(source('libs.js'))
    .pipe(buffer())// gulp-rev doesn't like streams, so convert to buffer
    .pipe(uglify({
      preserveComments: 'some' // preserve license headers
    }))
    .pipe(rev())
    .pipe(gulp.dest('dist/public/scripts/'));
});

gulp.task('scripts', ['jshint', 'partials', 'libs'], function () {
  var ngmin = require('gulp-ngmin');

  // transform that replaces references to `require`d partials with their minified versions in .tmp,
  // e.g. a call to require('../partials/foo.html') in public/scripts would be replaced by
  // require('../../.tmp/public/partials/foo.html')
  var minifyPartials = transformTools.makeRequireTransform('partialTransform',
    {evaluateArguments: true},
    function (args, opts, cb) {
      var file = args[0];
      if (path.extname(file) !== '.html') {
        cb();
        return;
      }

      var referrerDir = path.dirname(opts.file); // directory of file that has the require() call
      var tmp = path.join(__dirname, '.tmp');
      var tmpResource = path.resolve(referrerDir, file).replace(__dirname, tmp); // path to required tmp resource
      var relativePath = path.relative(referrerDir, tmpResource).replace(/\\/g, '/');

      cb(null, 'require("' + relativePath + '")');
    });

  var appBundle = browserify()
    .add(__dirname + '/public/scripts/app.js')
    .transform(minifyPartials);

  jsLibs.forEach(function (lib) {
    appBundle.external(lib);
  });

  return appBundle
    .bundle()
    .pipe(source('app.js')) // convert stream of text to stream of Vinyl objects for gulp
    .pipe(buffer())// ngmin, et al. don't like streams, so convert to buffer
    .pipe(ngmin())
    .pipe(uglify({
      preserveComments: 'some' // preserve license headers
    }))
    .pipe(rev())
    .pipe(gulp.dest('dist/public/scripts'));
});

var imageminTransform = function () {
  var imagemin = require('gulp-imagemin');

  return imagemin({
    optimizationLevel: 3,
    progressive: true,
    interlaced: true
  });
};

// Minifying JPGs, PNGs, and GIFs requires native libs which can be annoying to install on Windows, so
// they're all optional dependencies (see https://github.com/kevva/image-min). If the package isn't installed,
// we don't do the minification.

gulp.task('jpgs', function () {
  var pipeline = gulp.src(['public/images/**/*.jpg', 'public/images/**/*.jpeg']);

  // jpegtran-bin can be annoying on Windows, so make it optional
  var canJpeg = (function () {
    try {
      require.resolve('jpegtran-bin');
      return true;
    } catch (e) {
      return false;
    }
  })();
  if (canJpeg) {
    pipeline = pipeline.pipe(imageminTransform());
  } else {
    console.warn('jpegtran-bin not installed. Not minifying jpgs');
  }

  return pipeline.pipe(gulp.dest(paths.imagesDest));
});

gulp.task('pngs', function () {
  var pipeline = gulp.src(['public/images/**/*.png']);
  var canPng = (function () {
    try {
      require.resolve('pngquant-bin');
      return true;
    } catch (e) {
      return false;
    }
  })();
  if (canPng) {
    pipeline = pipeline.pipe(imageminTransform());
  } else {
    console.warn('pngquant-bin not installed. Not minifying pngs');
  }

  return pipeline.pipe(gulp.dest(paths.imagesDest));
});

gulp.task('gifs', function () {
  var pipeline = gulp.src(['public/images/**/*.gif']);
  var canPng = (function () {
    try {
      require.resolve('gifsicle');
      return true;
    } catch (e) {
      return false;
    }
  })();
  if (canPng) {
    pipeline = pipeline.pipe(imageminTransform());
  } else {
    console.warn('gifsicle not installed. Not minifying gifs');
  }

  return pipeline.pipe(gulp.dest(paths.imagesDest));
});

gulp.task('svgs', function () {
  var svgmin = require('gulp-svgmin');

  return gulp.src('public/images/**/*.svg')
    .pipe(svgmin())
    .pipe(gulp.dest('dist/public/images'));
});

gulp.task('images', ['jpgs', 'pngs', 'gifs', 'svgs'], function () {
  return gulp.src('public/images/*.ico')
    .pipe(gulp.dest('dist/public/images'));
});

// Although we do a lot of processing in middleware, this task is still useful to replace references to resources
// with references to revved versions.
gulp.task('inject', ['styles', 'scripts'], function () {
  var inject = require('gulp-inject');
  var fs = require('fs');
  var glob = require('glob');

  var getLatestFile = function (path) {
    var maxFile = '';
    var maxTime = -1;

    // this I/O should probably be async and in a stream instead, but this is a lot easier
    glob.sync(path)
      .forEach(function (file) {
        var mtime = fs.statSync(file).mtime.getTime();
        if (mtime > maxTime) {
          maxTime = mtime;
          maxFile = file;
        }
      });

    return maxFile;
  };

  return gulp.src(paths.indexHtml)
    .pipe(inject(gulp.src(getLatestFile('dist/public/styles/*.css'), {read: false}), {
      ignorePath: '/dist'
    }))
    .pipe(inject(gulp.src(getLatestFile('dist/public/scripts/libs-*.js'), {read: false}), {
      starttag: '<!-- inject:libs:{{ext}} -->',
      ignorePath: '/dist'
    }))
    .pipe(inject(gulp.src(getLatestFile('dist/public/scripts/app-*.js'), {read: false}), {
      ignorePath: '/dist'
    }))
    .pipe(gulp.dest('dist/views'));
});

gulp.task('html', ['inject'], function () {
  return gulp.src(['views/**/*.html', '!' + paths.indexHtml, 'dist/views/**/*.html'])
    .pipe(htmlmin({
      collapseWhitespace: true,
      collapseBooleanAttributes: true,
      removeComments: true,
      removeAttributeQuotes: false,
      removeRedundantAttributes: true,
      useShortDoctype: true, // enforces what we already do
      removeEmptyAttributes: true,
      removeOptionalTags: true
    }))
    .pipe(gulp.dest('dist/views'));
});

//gulp.task('watch', function () {
//  // TODO get this working when manually rebuilding gets annoying enough
//});

gulp.task('pot', function () {
  gulp.src(paths.partials.concat(paths.scripts))
    .pipe(gettext.extract('fracas.pot', {
      postProcess: function (po) {
        po.items.forEach(function (item) {
          item.references = item.references.map(function (ref) {
            return path.relative(path.join(__dirname, 'po'), ref)
              .replace(/\\/g, '/'); // replace any Windows-style paths
          });
        });
      }
    }))
    .pipe(gulp.dest('po/'));
});

gulp.task('translations', function () {
  gulp.src('po/*.po')
    .pipe(gettext.compile({
      format: 'json'
    }))
    .pipe(gulp.dest('dist/public/translations/'));
});

gulp.task('clean', function () {
  // recommended over gulp-clean, see https://github.com/peter-vilja/gulp-clean/pull/3
  var rimraf = require('gulp-rimraf');

  return gulp.src(['dist', '.tmp'], {read: false})
    .pipe(rimraf());
});

gulp.task('build', ['images', 'fonts', 'html', 'pot', 'translations'/*, 'kibana-build'*/]);

gulp.task('server', ['build'], function (callback) {
  var fork = require('child_process').fork;
  var open = require('open');
  var env = _.clone(process.env);
  env.NODE_ENV = 'production';

  var child = fork(__dirname + '/server.js', [], {
    env: env
  });
  child.on('message', function (m) {
    if (m.started) {
      gutil.log('Opening ' + m.url);
      open(m.url);
    }
  });
  child.on('error', callback);
  child.on('exit', function () {
    callback(null);
  });
});

var mochaTransform = lazypipe()
  .pipe(function () {
    return mocha({
      ui: 'bdd',
      reporter: 'nyan'
    });
  });

// if we want integration tests, we can split this into server-unit-tests and server-integration tests
gulp.task('server-tests', function () {
  return gulp.src(paths.serverTests, {read: false})
    .pipe(mochaTransform());
});

// these are unit tests, integration/e2e tests would use Protractor as the test runner
gulp.task('client-tests', function (cb) {
  // FIXME this doesn't work
  karma.server.start({configFile: __dirname + '/test/client/karma.conf.js'}, function () {
    cb(null);
  });
});

gulp.task('tests', ['server-tests']);

gulp.task('migrations', function (done) {
  var importData = require('./server/codex/import');
  var strategy = require('./server/codex/import/db');
  importData(strategy, done);
});

gulp.task('heroku', ['build']);

gulp.task('default', ['build']);
<commit_msg>Don't generate POT during normal builds<commit_after>'use strict';

var gulp = require('gulp');
var gutil  = require('gulp-util');
var lazypipe = require('lazypipe');
var uglify = require('gulp-uglify');
var htmlmin = require('gulp-htmlmin');
var rev = require('gulp-rev');
var mocha = require('gulp-mocha');
var gettext = require('gulp-angular-gettext');
var buffer = require('gulp-buffer');
var browserify = require('browserify');
var karma = require('karma');
var path = require('path');

var _ = require('lodash');
var source = require('vinyl-source-stream');
var transformTools = require('browserify-transform-tools');
var jsLibs = require('./server/assets').libs();

// add Kibana's grunt tasks
// blocked on https://github.com/gratimax/gulp-grunt/issues/3
// for now you'll have to manually build Kibana
//require('gulp-grunt')(gulp, {
//  base: __dirname + '/kibana',
//  prefix: 'kibana-'
//});

// TODO use gulp-changed

// TODO get livereload working with https://github.com/mollerse/gulp-embedlr

var notBowerComponents = '!public/bower_components/**/*';

var paths = {
  scripts: ['public/**/*.js', notBowerComponents],
  styles: ['public/styles/main.less'], // other styles are loaded from main
  partials: ['public/**/*.html', notBowerComponents],
  html: 'views/**/*.html',
  indexHtml: 'views/index.html',
  serverTests: 'test/server/**/test-*.js',
  clientTests: 'test/client/**/test-*.js',
  imagesDest: 'dist/public/images',
  bowerComponents: 'public/bower_components',
  nodeModules: 'node_modules'
};

var fontExtensions = ['.eot', '.svg', '.ttf', '.woff'];

// build CSS for production
gulp.task('styles', function () {
  var less = require('gulp-less');
  var autoprefixer = require('gulp-autoprefixer');
  var minifycss = require('gulp-minify-css');

  return gulp.src(paths.styles)
    .pipe(less({
      paths: [paths.bowerComponents, paths.nodeModules]
    }))
    .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
    .pipe(minifycss())
    .pipe(rev())
    .pipe(gulp.dest('dist/public/styles'));
});

gulp.task('fonts', function () {
  return gulp.src(fontExtensions.map(function (ext) {
      return 'public/fonts/**/*' + ext;
    }))
    .pipe(gulp.dest('dist/public/fonts'));
});

gulp.task('jshint', function () {
  var jshint = require('gulp-jshint');

  return gulp.src(paths.scripts)
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'))
    .pipe(jshint.reporter('fail'));
});

// minifies partials and converts them to a JS string that can be `require`d
gulp.task('partials', function () {
  var replace = require('gulp-replace');
  var header = require('gulp-header');
  var footer = require('gulp-footer');

  return gulp.src(paths.partials)
    .pipe(htmlmin({
      collapseWhitespace: true,
      collapseBooleanAttributes: true,
      removeComments: true,
      removeAttributeQuotes: false,
      removeRedundantAttributes: true,
      removeEmptyAttributes: true,
      removeOptionalTags: false // removing is probably a bad idea with partial docs
    }))
    // inspired by https://github.com/visionmedia/node-string-to-js/blob/master/index.js
    .pipe(replace(/"/g, '\\"'))
    .pipe(replace(/\r\n|\r|\n/g, '\\n'))

    // wrap HTML in module
    .pipe(header('module.exports = "'))
    .pipe(footer('";'))

    .pipe(gulp.dest('.tmp/public/')); // write to .tmp so they can be read by browserify
});

/**
 * Task to build 3rd-party JavaScript libraries.
 */
gulp.task('libs', function () {
  var bundle = browserify();
  jsLibs.forEach(function (lib) {
    bundle.require(lib);
  });

  return bundle
    .bundle()
    .pipe(source('libs.js'))
    .pipe(buffer())// gulp-rev doesn't like streams, so convert to buffer
    .pipe(uglify({
      preserveComments: 'some' // preserve license headers
    }))
    .pipe(rev())
    .pipe(gulp.dest('dist/public/scripts/'));
});

gulp.task('scripts', ['jshint', 'partials', 'libs'], function () {
  var ngmin = require('gulp-ngmin');

  // transform that replaces references to `require`d partials with their minified versions in .tmp,
  // e.g. a call to require('../partials/foo.html') in public/scripts would be replaced by
  // require('../../.tmp/public/partials/foo.html')
  var minifyPartials = transformTools.makeRequireTransform('partialTransform',
    {evaluateArguments: true},
    function (args, opts, cb) {
      var file = args[0];
      if (path.extname(file) !== '.html') {
        cb();
        return;
      }

      var referrerDir = path.dirname(opts.file); // directory of file that has the require() call
      var tmp = path.join(__dirname, '.tmp');
      var tmpResource = path.resolve(referrerDir, file).replace(__dirname, tmp); // path to required tmp resource
      var relativePath = path.relative(referrerDir, tmpResource).replace(/\\/g, '/');

      cb(null, 'require("' + relativePath + '")');
    });

  var appBundle = browserify()
    .add(__dirname + '/public/scripts/app.js')
    .transform(minifyPartials);

  jsLibs.forEach(function (lib) {
    appBundle.external(lib);
  });

  return appBundle
    .bundle()
    .pipe(source('app.js')) // convert stream of text to stream of Vinyl objects for gulp
    .pipe(buffer())// ngmin, et al. don't like streams, so convert to buffer
    .pipe(ngmin())
    .pipe(uglify({
      preserveComments: 'some' // preserve license headers
    }))
    .pipe(rev())
    .pipe(gulp.dest('dist/public/scripts'));
});

var imageminTransform = function () {
  var imagemin = require('gulp-imagemin');

  return imagemin({
    optimizationLevel: 3,
    progressive: true,
    interlaced: true
  });
};

// Minifying JPGs, PNGs, and GIFs requires native libs which can be annoying to install on Windows, so
// they're all optional dependencies (see https://github.com/kevva/image-min). If the package isn't installed,
// we don't do the minification.

gulp.task('jpgs', function () {
  var pipeline = gulp.src(['public/images/**/*.jpg', 'public/images/**/*.jpeg']);

  // jpegtran-bin can be annoying on Windows, so make it optional
  var canJpeg = (function () {
    try {
      require.resolve('jpegtran-bin');
      return true;
    } catch (e) {
      return false;
    }
  })();
  if (canJpeg) {
    pipeline = pipeline.pipe(imageminTransform());
  } else {
    console.warn('jpegtran-bin not installed. Not minifying jpgs');
  }

  return pipeline.pipe(gulp.dest(paths.imagesDest));
});

gulp.task('pngs', function () {
  var pipeline = gulp.src(['public/images/**/*.png']);
  var canPng = (function () {
    try {
      require.resolve('pngquant-bin');
      return true;
    } catch (e) {
      return false;
    }
  })();
  if (canPng) {
    pipeline = pipeline.pipe(imageminTransform());
  } else {
    console.warn('pngquant-bin not installed. Not minifying pngs');
  }

  return pipeline.pipe(gulp.dest(paths.imagesDest));
});

gulp.task('gifs', function () {
  var pipeline = gulp.src(['public/images/**/*.gif']);
  var canPng = (function () {
    try {
      require.resolve('gifsicle');
      return true;
    } catch (e) {
      return false;
    }
  })();
  if (canPng) {
    pipeline = pipeline.pipe(imageminTransform());
  } else {
    console.warn('gifsicle not installed. Not minifying gifs');
  }

  return pipeline.pipe(gulp.dest(paths.imagesDest));
});

gulp.task('svgs', function () {
  var svgmin = require('gulp-svgmin');

  return gulp.src('public/images/**/*.svg')
    .pipe(svgmin())
    .pipe(gulp.dest('dist/public/images'));
});

gulp.task('images', ['jpgs', 'pngs', 'gifs', 'svgs'], function () {
  return gulp.src('public/images/*.ico')
    .pipe(gulp.dest('dist/public/images'));
});

// Although we do a lot of processing in middleware, this task is still useful to replace references to resources
// with references to revved versions.
gulp.task('inject', ['styles', 'scripts'], function () {
  var inject = require('gulp-inject');
  var fs = require('fs');
  var glob = require('glob');

  var getLatestFile = function (path) {
    var maxFile = '';
    var maxTime = -1;

    // this I/O should probably be async and in a stream instead, but this is a lot easier
    glob.sync(path)
      .forEach(function (file) {
        var mtime = fs.statSync(file).mtime.getTime();
        if (mtime > maxTime) {
          maxTime = mtime;
          maxFile = file;
        }
      });

    return maxFile;
  };

  return gulp.src(paths.indexHtml)
    .pipe(inject(gulp.src(getLatestFile('dist/public/styles/*.css'), {read: false}), {
      ignorePath: '/dist'
    }))
    .pipe(inject(gulp.src(getLatestFile('dist/public/scripts/libs-*.js'), {read: false}), {
      starttag: '<!-- inject:libs:{{ext}} -->',
      ignorePath: '/dist'
    }))
    .pipe(inject(gulp.src(getLatestFile('dist/public/scripts/app-*.js'), {read: false}), {
      ignorePath: '/dist'
    }))
    .pipe(gulp.dest('dist/views'));
});

gulp.task('html', ['inject'], function () {
  return gulp.src(['views/**/*.html', '!' + paths.indexHtml, 'dist/views/**/*.html'])
    .pipe(htmlmin({
      collapseWhitespace: true,
      collapseBooleanAttributes: true,
      removeComments: true,
      removeAttributeQuotes: false,
      removeRedundantAttributes: true,
      useShortDoctype: true, // enforces what we already do
      removeEmptyAttributes: true,
      removeOptionalTags: true
    }))
    .pipe(gulp.dest('dist/views'));
});

//gulp.task('watch', function () {
//  // TODO get this working when manually rebuilding gets annoying enough
//});

gulp.task('pot', function () {
  gulp.src(paths.partials.concat(paths.scripts))
    .pipe(gettext.extract('fracas.pot', {
      postProcess: function (po) {
        po.items.forEach(function (item) {
          item.references = item.references.map(function (ref) {
            return path.relative(path.join(__dirname, 'po'), ref)
              .replace(/\\/g, '/'); // replace any Windows-style paths
          });
        });
      }
    }))
    .pipe(gulp.dest('po/'));
});

gulp.task('translations', function () {
  gulp.src('po/*.po')
    .pipe(gettext.compile({
      format: 'json'
    }))
    .pipe(gulp.dest('dist/public/translations/'));
});

gulp.task('clean', function () {
  // recommended over gulp-clean, see https://github.com/peter-vilja/gulp-clean/pull/3
  var rimraf = require('gulp-rimraf');

  return gulp.src(['dist', '.tmp'], {read: false})
    .pipe(rimraf());
});

gulp.task('build', ['images', 'fonts', 'html', 'translations']);

gulp.task('server', ['build'], function (callback) {
  var fork = require('child_process').fork;
  var open = require('open');
  var env = _.clone(process.env);
  env.NODE_ENV = 'production';

  var child = fork(__dirname + '/server.js', [], {
    env: env
  });
  child.on('message', function (m) {
    if (m.started) {
      gutil.log('Opening ' + m.url);
      open(m.url);
    }
  });
  child.on('error', callback);
  child.on('exit', function () {
    callback(null);
  });
});

var mochaTransform = lazypipe()
  .pipe(function () {
    return mocha({
      ui: 'bdd',
      reporter: 'nyan'
    });
  });

// if we want integration tests, we can split this into server-unit-tests and server-integration tests
gulp.task('server-tests', function () {
  return gulp.src(paths.serverTests, {read: false})
    .pipe(mochaTransform());
});

// these are unit tests, integration/e2e tests would use Protractor as the test runner
gulp.task('client-tests', function (cb) {
  // FIXME this doesn't work
  karma.server.start({configFile: __dirname + '/test/client/karma.conf.js'}, function () {
    cb(null);
  });
});

gulp.task('tests', ['server-tests']);

gulp.task('migrations', function (done) {
  var importData = require('./server/codex/import');
  var strategy = require('./server/codex/import/db');
  importData(strategy, done);
});

gulp.task('heroku', ['build']);

gulp.task('default', ['build']);
<|endoftext|>