<commit_before>$(function() {

    $('#side-menu').metisMenu();

});

//Loads the correct sidebar on window load,
//collapses the sidebar on window resize.
// Sets the min-height of #page-wrapper to window size
$(function() {
    $(window).bind("load resize", function() {
        var topOffset = 50;
        var width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width;
        if (width < 768) {
            $('div.navbar-collapse').addClass('collapse');
            topOffset = 100; // 2-row-menu
        } else {
            $('div.navbar-collapse').removeClass('collapse');
        }

        var height = ((this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height) - 1;
        height = height - topOffset;
        if (height < 1) height = 1;
        if (height > topOffset) {
            $("#page-wrapper").css("min-height", (height) + "px");
        }
    });

    var url = window.location;
    var element = $('ul.nav a').filter(function() {
        return this.href == url;
    }).addClass('active').parent().parent().addClass('in').parent();
    if (element.is('li')) {
        element.addClass('active');
    }
});
<commit_msg>add tools<commit_after>$(function() {

    $('#side-menu').metisMenu();

});

//Loads the correct sidebar on window load,
//collapses the sidebar on window resize.
// Sets the min-height of #page-wrapper to window size
$(function() {
    $(window).bind("load resize", function() {
        var topOffset = 50;
        var width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width;
        if (width < 768) {
            $('div.navbar-collapse').addClass('collapse');
            topOffset = 100; // 2-row-menu
        } else {
            $('div.navbar-collapse').removeClass('collapse');
        }

        var height = ((this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height) - 1;
        height = height - topOffset;
        if (height < 1) height = 1;
        if (height > topOffset) {
            $("#page-wrapper").css("min-height", (height) + "px");
        }
    });

    var url = window.location;
    var element = $('ul.nav a').filter(function() {
        return this.href == url;
    }).addClass('active').parent().parent().addClass('in').parent();
    if (element.is('li')) {
        element.addClass('active');
    }
});

var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "//hm.baidu.com/hm.js?eb8e497b3383518a5c42758a16b4007f";
  var s = document.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(hm, s);
})();

var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cspan id='cnzz_stat_icon_1258731748'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s95.cnzz.com/z_stat.php%3Fid%3D1258731748' type='text/javascript'%3E%3C/script%3E"));

(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-67825764-3', 'auto');
ga('send', 'pageview');
<|endoftext|>


<commit_before>/**
 * phantomjs script for printing presentations to PDF.
 *
 * Example:
 * phantomjs print-pdf.js "http://revealjs.com?print-pdf" reveal-demo.pdf
 *
 * @author Manuel Bieh (https://github.com/manuelbieh)
 * @author Hakim El Hattab (https://github.com/hakimel)
 * @author Manuel Riezebosch (https://github.com/riezebosch)
 */

// html2pdf.js
var system = require( 'system' );

var probePage = new WebPage();
var printPage = new WebPage();

var inputFile = system.args[1] || 'index.html?print-pdf';
var outputFile = system.args[2] || 'slides.pdf';

if( outputFile.match( /\.pdf$/gi ) === null ) {
	outputFile += '.pdf';
}

console.log( 'Export PDF: Reading reveal.js config [1/4]' );

probePage.open( inputFile, function( status ) {

	console.log( 'Export PDF: Preparing print layout [2/4]' );

	var config = probePage.evaluate( function() {
		return Reveal.getConfig();
	} );

	if( config ) {

		printPage.paperSize = {
			width: Math.floor( config.width * ( 1 + config.margin ) ),
			height: Math.floor( config.height * ( 1 + config.margin ) ),
			border: 0
		};

		printPage.open( inputFile, function( status ) {
			console.log( 'Export PDF: Preparing pdf [3/4]')
			printPage.evaluate( function() {
				Reveal.isReady() ? window.callPhantom() : Reveal.on( 'pdf-ready', window.callPhantom );
			} );
		} );

		printPage.onCallback = function( data ) {
			// For some reason we need to "jump the queue" for syntax highlighting to work.
			// See: http://stackoverflow.com/a/3580132/129269
			setTimeout( function() {
				console.log( 'Export PDF: Writing file [4/4]' );
				printPage.render( outputFile );
				console.log( 'Export PDF: Finished successfully!' );
				phantom.exit();
			}, 0 );
		};
	}
	else {

		console.log( 'Export PDF: Unable to read reveal.js config. Make sure the input address points to a reveal.js page.' );
		phantom.exit( 1 );

	}
} );
<commit_msg>removed phantomjs-based print-pdf plugin<commit_after><|endoftext|>


<commit_before>/**
	Lightweight component for freeflow MVC in Enyo, with separate-but-linked views/controllers.

	Genally, the enyo.View controls should contain UI controls and basic UI logic, with a separate
	corresponding controller object (which should be a subkind of enyo.Component) for data processing
	and manipulation. Views can be within eachother and placed anywhere, like any other component,
	however keep in mind each view requires a specified controller kind.

	All top-level view events will bubble to the controller before continuing upwards in the
	component tree. Additionally, event handlers can reference the controller directly. For example:

		enyo.kind({
			name:"MainView",
			kind: enyo.View,
			controllerKind: "MainController",
			components:[
				{kind:"Button", content:"Tap me", ontap:"controller.buttonTapped"}
			]
		});

	In that example, MainController's `buttonTapped` function would be called as the event handler.
	Furthermore, the controller will execute `reflow()` and `rendered()` functions on view reflow/render,
	if those functions have been implemented.

	The controller has a `view` property set which references the corresponding view, and similarly,
	the view has a `controller` property set which references the corresponding controller. Furthermore,
	as views/controllers are created, they are accessable from enyo.stage.* for cross-access.

	For example, if we created an enyo.View subkind called enyo.MainView, with a declared controllerKind
	of enyo.MainController, and included it in an	app's component block like:

		{name:"main", kind:enyo.MainView}

	Then the controller is accessable from `enyo.stage.main`, and the view instance is accessable
	from `enyo.stage.main.view.
*/

//* @protected
// Remove Enyo 2.3+ definition of View = Control, to define a more complex View
enyo.View = undefined;

//* @public
enyo.kind({
	name:"enyo.View",
	kind:"enyo.Control",
	//* Used to specific the kind of controller to be used for the view
	controllerKind: undefined,
	//* @protected
	create: function() {
		this.inherited(arguments);
		this.controller = this.createComponent({kind:this.controllerKind}, {view:this});
		enyo.stage = enyo.stage || {};
		enyo.stage[this.name] = {
			controller: this.controller,
			view: this
		};
	},
	dispatchEvent: function() {
		// Override dispatchEvent, so when any events bubble up to the point of the View,
		// rather than dispatching to the View, it'll attempt dispatching to the Controller first,
		// afterwards carrying on to the view and upwards in the chain.
		return this.controller.dispatchEvent.apply(this.controller, arguments) || this.inherited(arguments);
	},
	rendered: function() {
		this.inherited(arguments);
		this.controller && this.controller.rendered && this.controller.rendered();
	},
	reflow: function() {
		this.inherited(arguments);
		this.controller && this.controller.reflow && this.controller.reflow();
	}
});

(function() {
    // Helper function to modify the dispatch request parameters to be forwarded to the event to a controller.
    var modifiedDispatch = function(view, name, event, sender) {
        name = name.replace("controller.", "");
        event.delegate && (event.delegate = {owner:view.controller});
        return view.dispatchEvent(name, event, sender);
    };
    // Overrides the built-in enyo.Component dispatch and dispatchEvent functions so they reroute event
    // handlers with "controller." prefix to the appropriate controller component.
    var updateDispatchForControllerKeyword = function(fnName) {
        var origFn = enyo.Component.prototype[fnName];
        enyo.Component.prototype[fnName] = function(name, event, sender) {
            if(name.indexOf("controller.")==0) {
                if(this.controller) {
                    return modifiedDispatch(this, name, event, sender);
                } else if(this==enyo.master){
                    for(c=sender; c!=enyo.master; c=c.owner) {
                        if(c.controller) {
                            return modifiedDispatch(c, name, event, sender);
                        }
                    }
                }
                return origFn.apply(this, arguments);
            } else {
                return origFn.apply(this, arguments);
            }
        };
    }
    updateDispatchForControllerKeyword("dispatch");
    updateDispatchForControllerKeyword("dispatchEvent");
})();
<commit_msg>Updated documentation<commit_after>/**
	Lightweight component for freeflow MVC in Enyo, with separate-but-linked views/controllers.

	Genally, the enyo.View controls should contain UI controls and basic UI logic, with a separate
	corresponding controller object (which should be a subkind of enyo.Component) for data processing
	and manipulation. Views can be within eachother and placed anywhere, like any other component,
	however keep in mind each view requires a specified controller kind.

	All top-level view events will bubble to the controller before continuing upwards in the
	component tree. Additionally, event handlers can reference the controller directly. For example:

		enyo.kind({
			name:"MainView",
			kind: enyo.View,
			controllerKind: "MainController",
			components:[
				{kind:"Button", content:"Tap me", ontap:"controller.buttonTapped"}
			]
		});

	In that example, MainController's `buttonTapped` function would be called as the event handler.
	Furthermore, the controller will execute `reflow()` and `rendered()` functions on view reflow/render,
	if those functions have been implemented.

	The controller has a `view` property set which references the corresponding view, and similarly,
	the view has a `controller` property set which references the corresponding controller. Furthermore,
	as views/controllers are created, they are accessable from enyo.stage.* for cross-access.

	For example, if we created an enyo.View subkind called enyo.MainView, with a declared controllerKind
	of enyo.MainController, and included it in an	app's component block like:

		{name:"main", kind:enyo.MainView}

	Then the controller is accessable from `enyo.stage.main`, and the view instance is accessable
	from `enyo.stage.main.view.
*/

//* @protected
//* Remove Enyo 2.3+ definition of View = Control, to define a more complex View
enyo.View = undefined;

//* @public
enyo.kind({
	name:"enyo.View",
	kind:"enyo.Control",
	//* Used to specific the kind of controller to be used for the view
	controllerKind: undefined,
	//* @protected
	create: function() {
		this.inherited(arguments);
		this.controller = this.createComponent({kind:this.controllerKind}, {view:this});
		enyo.stage = enyo.stage || {};
		enyo.stage[this.name] = this.controller;
	},
	dispatchEvent: function() {
		// Override dispatchEvent, so when any events bubble up to the point of the View,
		// rather than dispatching to the View, it'll attempt dispatching to the Controller first,
		// afterwards carrying on to the view and upwards in the chain.
		return this.controller.dispatchEvent.apply(this.controller, arguments) || this.inherited(arguments);
	},
	rendered: function() {
		this.inherited(arguments);
		this.controller && this.controller.rendered && this.controller.rendered();
	},
	reflow: function() {
		this.inherited(arguments);
		this.controller && this.controller.reflow && this.controller.reflow();
	}
});

(function() {
    // Helper function to modify the dispatch request parameters to be forwarded to the event to a controller.
    var modifiedDispatch = function(view, name, event, sender) {
        name = name.replace("controller.", "");
        event.delegate && (event.delegate = {owner:view.controller});
        return view.dispatchEvent(name, event, sender);
    };
    // Overrides the built-in enyo.Component dispatch and dispatchEvent functions so they reroute event
    // handlers with "controller." prefix to the appropriate controller component.
    var updateDispatchForControllerKeyword = function(fnName) {
        var origFn = enyo.Component.prototype[fnName];
        enyo.Component.prototype[fnName] = function(name, event, sender) {
            if(name.indexOf("controller.")==0) {
                if(this.controller) {
                    return modifiedDispatch(this, name, event, sender);
                } else if(this==enyo.master){
                    for(c=sender; c!=enyo.master; c=c.owner) {
                        if(c.controller) {
                            return modifiedDispatch(c, name, event, sender);
                        }
                    }
                }
                return origFn.apply(this, arguments);
            } else {
                return origFn.apply(this, arguments);
            }
        };
    }
    updateDispatchForControllerKeyword("dispatch");
    updateDispatchForControllerKeyword("dispatchEvent");
})();
<|endoftext|>


<commit_before>const Discord = require('discord.js');
const config = require('./config.json')

const client = new Discord.Client();

const prefix = config.prefix;

client.on('ready', () => {
	console.log('PuyoBot active!');
	client.user.setGame("Puyo Puyo!! 20th Anniversary!");
});

client.login(config.token);

client.on('message', message =>
{
	if (message.content.startsWith(prefix + "r1"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Rule 1:")
		  .setColor(0xFF0000)
		  .setDescription("**Moderation is done at our discretion.** That means you could very well be moderated for something that someone else wasn't. This is not an excuse to violate the rules. That being said, we are not able to monitor every message sent on the server, so please report inappropriate behavior if you see it. We're here to help, so don't be afraid to come to us.\n\n**How to report an issue:** \n**Pinging:** You can request immediate attention to a problem currently happening in any of our channels by pinging the **@Moderators** role. We advise pinging this role as a whole, so in the event that a specific Admin or Moderator isn’t available at the time, others may be able to handle it. \n**DMing**: For situations that require discretion, or can be handled over time, DMing is a better method. You are free to message any Admin or Moderator with your concerns, but please refrain from messaging all of us. We will help you as soon as we are able to!");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: rule 1 specified. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "r2"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Rule 2:")
		  .setColor(0xFF0000)
		  .setDescription("**Be excellent to each other.** This Discord is a joint effort across the entire Puyo community, and brings together people of many different creeds and upbringings, ages and backgrounds. Please treat everybody with respect. Trolling, inflammatory or derogatory comments, discrimination of any kind, hate speech, and personal attacks are not permitted. **Unacceptable content includes (but is not limited to)** use of autism/retard as a derogatory term, triggered jokes, gender jokes (including the use of ‘trap’ to describe a person), and racist terms.");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: rule 2 specified. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "r3"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Rule 3:")
		  .setColor(0xFF0000)
		  .setDescription("**Keep it safe for work.** Explicit content, such as sexualized, violent, or otherwise disturbing imagery or language, as well as unwelcome advances, are strictly prohibited. As it is against Discord’s TOS to post such content on their platform, it is also against the rules of our server. Violating this rule is likely to be an immediate permanent ban. Not knowing the rules is not an excuse.");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: rule 3 specified. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "r4"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Rule 4:")
			.setColor(0xFF0000)
			.setDescription("**Do not link to pirated material or discussions about where to pirate material.** Discussion about piracy, such as in the context of game emulation, is allowed. ");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: rule 4 specified. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "r5"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Rule 5:")
			.setColor(0xFF0000)
			.setDescription("**Repost artwork with a link to original source.** If the art is not yours, a link source must be given. If you cannot find a source, do not repost! If an artist requires permission to repost, ask! For a full guide on how to source, get permission for reposting, templates for asking permission from non-English speakers, and what to do in the event you are/are not given permission, please refer to this document: https://docs.google.com/document/d/1XLchLr0S7WUNNet8LLHSS7eVqvcj1PI2cg47jtKuZqM/edit");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: rule 4 specified. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "WAZZUP"))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/7uneviX.gif");
		message.channel.send(em);  //NB: GIFs don't work as embeds
		console.log('response from', message.author.username, 'sent: WAZZUP! at', getDateTime());
	}

	if (message.content.startsWith(prefix + "CarbunclePop"))
	{
		em = new Discord.RichEmbed();
		em.setImage("https://imgur.com/WrJmrmY.gif");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: Ready? Go! at', getDateTime());
	}

	if (message.content.startsWith(prefix + "yuintensifies"))
	{
		em = new discord.RichEmbed();
		em.setImage("http://imgur.com/qeMQywX.gif");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: YU RANG intensifies! at', getDateTime());
	}

	if (message.content.startsWith(prefix + "notpuyo"))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/tf1Ycna.jpg");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: "Wait, what?" at', getDateTime());
	}

	if (message.content.startsWith(prefix + "freakout"))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/Kl61MLn.gif");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: BWAHHHHH! at', getDateTime());
	}

	if (message.content.startsWith(prefix + "DracoPraying"))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/w4FeIqZ.png");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: Draco Praying. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "AAAAAAA"))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/LdrIBUYjpg");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: [screams internally]! at', getDateTime());
	}

	if (message.content.startsWith(prefix + 'badman'))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/vER4TMz.jpg")
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: YOU\'RE A BAD MAN! at', getDateTime());
	}

	if (message.content.startsWith(prefix + "thegirlwiththefunnyhat"))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/6mBanRD.jpg")
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: So who\'s the girl with the funny hat? at', getDateTime());
	}

	if (message.content.startsWith(prefix + 'help'))
	{
		em = new Discord.RichEmbed();
		em.setTitle("HELP!  Puyobot Command List")
		  .setColor(0x00FF00)
			.setDescription(".r1 \n.r2 \n.r3 \n.botrule \n.help \n.sauce \n.meme \n.request \n.ver \n.currentTime")
		message.reply("check your DMs!");
		message.member.send(em);
		console.log('response from', message.author.username, 'sent: Requested the bot list. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "meme"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Get your freshest memes here:")
		  .setColor(0xFFFF00)
		  .setDescription(".WAZZUP \n.notpuyo \n.freakout \n.AAAAAAA \n.yuintensifies \n.DracoPraying \n.CarbunclePop \n.thegirlwiththefunnyhat \n.badman");
		message.reply("check your DMs!");
		message.member.send(em);
		console.log('response from', message.author.username, 'sent: asked for memes. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "ver"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Puyobot release candidate version 1.70")
 		   .setColor(0x215F88)
	 		 .setDescription("Changes made:")
			 .addField("total code rewrite:", "I changed everything from code blocks to embeds, making bot usage cleaner and bot maintenance more... fasionable", false)
			 .addField("Code beautification:", "the code now looks easier on the eyes, and now you can actually see what's going on", false)
			 .addField("File restructure:", "You now need a config.json file with prefix and your bot token as described in this guide: https://www.gitbook.com/book/anidiotsguide/discord-js-bot-guide", false)
			 .addField("As always, code is now pushed to github after being released.  You can find it here:" ," https://github.com/NostalgiaNinja/Puyobot", false)
			 .setFooter("Puyobot ver. 1.70 made by Nostalgia Ninja");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: Version history. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "currentTime"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Current Bot Server Time (GMT+2.00 - South African Standard Time)")
		  .setColor(0x00FF00)
			.setDescription(getDateTime());
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: requested for current system date time on server');
	}
});

function getDateTime() {

	var date  = new Date();

	var hour = date.getHours();
	hour = (hour < 10 ? "0" : "") + hour;

	var minut = date.getMinutes();
	min = (minut < 10 ? "0" : "") + minut;

	var sec = date.getSeconds();
	sec = (sec < 10 ? "0" : "") + sec;

	var year = date.getFullYear();

	var month = date.getMonth() + 1;
	month = (month < 10 ? "0" : "") + month;

	var day = date.getDate();
	day = (day < 10 ? "0" : "") + day;

	return year + "/" + month + "/" + day + " - " + hour + ":" + minut + ":" + sec;
}
<commit_msg>Smart prefix detection + minor bugfixes<commit_after>const Discord = require('discord.js');
const config = require('./config.json')

const client = new Discord.Client();

const prefix = config.prefix;

client.on('ready', () => {
	console.log('PuyoBot active!');
	client.user.setGame("Puyo Puyo!! 20th Anniversary!");
});

client.login(config.token);

client.on('message', message =>
{
	if (message.content.startsWith(prefix + "r1"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Rule 1:")
		  .setColor(0xFF0000)
		  .setDescription("**Moderation is done at our discretion.** That means you could very well be moderated for something that someone else wasn't. This is not an excuse to violate the rules. That being said, we are not able to monitor every message sent on the server, so please report inappropriate behavior if you see it. We're here to help, so don't be afraid to come to us.\n\n**How to report an issue:** \n**Pinging:** You can request immediate attention to a problem currently happening in any of our channels by pinging the **@Moderators** role. We advise pinging this role as a whole, so in the event that a specific Admin or Moderator isn’t available at the time, others may be able to handle it. \n**DMing**: For situations that require discretion, or can be handled over time, DMing is a better method. You are free to message any Admin or Moderator with your concerns, but please refrain from messaging all of us. We will help you as soon as we are able to!");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: rule 1 specified. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "r2"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Rule 2:")
		  .setColor(0xFF0000)
		  .setDescription("**Be excellent to each other.** This Discord is a joint effort across the entire Puyo community, and brings together people of many different creeds and upbringings, ages and backgrounds. Please treat everybody with respect. Trolling, inflammatory or derogatory comments, discrimination of any kind, hate speech, and personal attacks are not permitted. **Unacceptable content includes (but is not limited to)** use of autism/retard as a derogatory term, triggered jokes, gender jokes (including the use of ‘trap’ to describe a person), and racist terms.");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: rule 2 specified. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "r3"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Rule 3:")
		  .setColor(0xFF0000)
		  .setDescription("**Keep it safe for work.** Explicit content, such as sexualized, violent, or otherwise disturbing imagery or language, as well as unwelcome advances, are strictly prohibited. As it is against Discord’s TOS to post such content on their platform, it is also against the rules of our server. Violating this rule is likely to be an immediate permanent ban. Not knowing the rules is not an excuse.");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: rule 3 specified. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "r4"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Rule 4:")
			.setColor(0xFF0000)
			.setDescription("**Do not link to pirated material or discussions about where to pirate material.** Discussion about piracy, such as in the context of game emulation, is allowed. ");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: rule 4 specified. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "r5"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Rule 5:")
			.setColor(0xFF0000)
			.setDescription("**Repost artwork with a link to original source.** If the art is not yours, a link source must be given. If you cannot find a source, do not repost! If an artist requires permission to repost, ask! For a full guide on how to source, get permission for reposting, templates for asking permission from non-English speakers, and what to do in the event you are/are not given permission, please refer to this document: https://docs.google.com/document/d/1XLchLr0S7WUNNet8LLHSS7eVqvcj1PI2cg47jtKuZqM/edit");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: rule 4 specified. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "WAZZUP"))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/7uneviX.gif");
		message.channel.send(em);  //NB: GIFs don't work as embeds
		console.log('response from', message.author.username, 'sent: WAZZUP! at', getDateTime());
	}

	if (message.content.startsWith(prefix + "CarbunclePop"))
	{
		em = new Discord.RichEmbed();
		em.setImage("https://imgur.com/WrJmrmY.gif");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: Ready? Go! at', getDateTime());
	}

	if (message.content.startsWith(prefix + "yuintensifies"))
	{
		em = new discord.RichEmbed();
		em.setImage("http://imgur.com/qeMQywX.gif");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: YU RANG intensifies! at', getDateTime());
	}

	if (message.content.startsWith(prefix + "notpuyo"))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/tf1Ycna.jpg");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: "Wait, what?" at', getDateTime());
	}

	if (message.content.startsWith(prefix + "freakout"))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/Kl61MLn.gif");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: BWAHHHHH! at', getDateTime());
	}

	if (message.content.startsWith(prefix + "DracoPraying"))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/w4FeIqZ.png");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: Draco Praying. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "AAAAAAA"))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/LdrIBUYjpg");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: [screams internally]! at', getDateTime());
	}

	if (message.content.startsWith(prefix + 'badman'))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/vER4TMz.jpg")
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: YOU\'RE A BAD MAN! at', getDateTime());
	}

	if (message.content.startsWith(prefix + "thegirlwiththefunnyhat"))
	{
		em = new Discord.RichEmbed();
		em.setImage("http://imgur.com/6mBanRD.jpg")
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: So who\'s the girl with the funny hat? at', getDateTime());
	}

	if (message.content.startsWith(prefix + 'help'))
	{
		em = new Discord.RichEmbed();
		try
		{
				em.setTitle("HELP!  Puyobot Command List")
		  		.setColor(0x00FF00)
					.setDescription(prefix + "r1\n" +
													prefix + "r2\n" +
													prefix + "r3\n" +
													prefix + "r4\n" +
													prefix + "r5\n" +
													prefix + "help\n" +
													prefix + "meme\n" +
													prefix + "ver\n" +
													prefix + "currentTime");
				message.reply("check your DMs!");
				message.member.send(em);
		}
		catch (e)
		{
				em.setTitle("Error!")
					.setColor(0xFF0000)
					.setDescription(e);
				message.channel.send("Cannot send message: Error details as follows:/n" + em + "\n ping NN immediately!");
		}
		console.log('response from', message.author.username, 'sent: Requested the bot list. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "meme"))
	{
		em = new Discord.RichEmbed();
		try
		{
			em.setTitle("Get your freshest memes here:")
		  	.setColor(0xFFFF00)
				.setDescription(prefix + "WAZZUP\n" +
												prefix + "notpuyo\n" +
												prefix + "AAAAAAA\n" +
												prefix + "freakout\n" +
												prefix + "yuintensifies\n" +
												prefix + "DracoPraying\n" +
												prefix + "CarbunclePop\n" +
												prefix + "thegirlwiththefunnyhat\n" +
												prefix + "badman");
			message.reply("check your DMs!");
			message.member.send(em);
		}
		catch (e)
		{
			em.setTitle("Error!")
				.setColor(0xFF0000)
				.setDescription(e)
			message.channel.send("Cannot send message: Error details as follows:/n" + em + "\n ping NN immediately!");
		}
		console.log('response from', message.author.username, 'sent: asked for memes. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "ver"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Puyobot release candidate version 1.70")
 		   .setColor(0x215F88)
	 		 .setDescription("Changes made:")
			 .addField("total code rewrite:", "I changed everything from code blocks to embeds, making bot usage cleaner and bot maintenance more... fashionable", false)
			 .addField("Code beautification:", "the code now looks easier on the eyes, and now you can actually see what's going on", false)
			 .addField("File restructure:", "You now need a config.json file with prefix and your bot token as described in this guide: https://www.gitbook.com/book/anidiotsguide/discord-js-bot-guide", false)
			 .addField("As always, code is now pushed to github after being released.  You can find it here:" ," https://github.com/NostalgiaNinja/Puyobot", false)
			 .addField("Smart Prefix Detection:", "If someone else hosts the bot the help will propogate with the correct prefix.", false)
			 .setFooter("Puyobot ver. 1.70 made by Nostalgia Ninja");
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: Version history. at', getDateTime());
	}

	if (message.content.startsWith(prefix + "currentTime"))
	{
		em = new Discord.RichEmbed();
		em.setTitle("Current Bot Server Time (GMT+2.00 - South African Standard Time)")
		  .setColor(0x00FF00)
			.setDescription(getDateTime());
		message.channel.send(em);
		console.log('response from', message.author.username, 'sent: requested for current system date time on server');
	}
});

function getDateTime() {

	var date  = new Date();

	var hour = date.getHours();
	hour = (hour < 10 ? "0" : "") + hour;

	var minut = date.getMinutes();
	min = (minut < 10 ? "0" : "") + minut;

	var sec = date.getSeconds();
	sec = (sec < 10 ? "0" : "") + sec;

	var year = date.getFullYear();

	var month = date.getMonth() + 1;
	month = (month < 10 ? "0" : "") + month;

	var day = date.getDate();
	day = (day < 10 ? "0" : "") + day;

	return year + "/" + month + "/" + day + " - " + hour + ":" + minut + ":" + sec;
}
<|endoftext|>


<commit_before>var Game = require('./game');
var Player = require('./player');
var mongoose = require('mongoose');
var User = mongoose.model('User');

var avatars = require(__dirname + '/../../app/controllers/avatars.js').all();
// Valid characters to generate random private game IDs
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";

module.exports = function(io) {

  var game;
  var allGames = {};
  var gamesNeedingPlayers = [];
  var gameID = 0;

  io.sockets.on('connection', function (socket) {
    console.log(socket.id +  ' Connected');
    socket.emit('id', {id: socket.id});

    socket.on('pickCards', function(data) {
      console.log(socket.id,"picked",data);
      if (allGames[socket.gameID]) {
        allGames[socket.gameID].pickCards(data.cards,socket.id);
      } else {
        console.log('Received pickCard from',socket.id, 'but game does not appear to exist!');
      }
    });

    socket.on('pickWinning', function(data) {
      if (allGames[socket.gameID]) {
        allGames[socket.gameID].pickWinning(data.card,socket.id);
      } else {
        console.log('Received pickWinning from',socket.id, 'but game does not appear to exist!');
      }
    });

    socket.on('joinGame', function(data) {
      joinGame(socket,data);
    });

    socket.on('startGame', function() {
      if (allGames[socket.gameID]) {
        var thisGame = allGames[socket.gameID];
        console.log('comparing',thisGame.players[0].socket.id,'with',socket.id);
        if (thisGame.players.length >= thisGame.playerMinLimit) {
          thisGame.prepareGame();
          thisGame.sendNotification('The game has begun!');
        }
      }
    });

    socket.on('joinNewGame', function(data) {
      exitGame(socket);
      joinGame(socket,data);
    });

    socket.on('createGameWithFriends', function() {
      createGameWithFriends(socket);
    });

    socket.on('leaveGame', function() {
      socket.leave(socket.gameID);
      exitGame(socket);
    });

    socket.on('disconnect', function(){
      console.log('Rooms on Disconnect ', io.sockets.manager.rooms);
      exitGame(socket);
    });
  });

  var joinGame = function(socket,data) {
    var player = new Player(socket);
    player.userID = data.userID;
    if (data.userID !== 'unauthenticated') {
      User.findOne({
        _id: data.userID
      }).exec(function(err, user) {
        if (err) {
          console.log('err',err);
          return err; // Hopefully this never happens.
        }
        if (!user) {
          // If the user's ID isn't found (rare)
          player.username = 'Guest';
          player.avatar = avatars[Math.floor(Math.random()*4)+12];
        } else {
          player.username = user.name;
          player.avatar = user.avatar || avatars[Math.floor(Math.random()*4)+12];
        }
        getGame(player,socket,data.room);
      });
    } else {
      // If the user isn't authenticated (guest)
      player.username = 'Guest';
      player.avatar = avatars[Math.floor(Math.random()*4)+12];
      getGame(player,socket,data.room);
    }
  };

  var getGame = function(player,socket,requestedGameId) {
    console.log(socket.id,'is requesting room',requestedGameId);
    if (requestedGameId.length && allGames[requestedGameId]) {
      console.log('Room',requestedGameId,'is valid');
      var game = allGames[requestedGameId];
      if (game.state === 'awaiting players') {
        // Put player into the requested game
        console.log('Allowing player to join',requestedGameId);
        game.players.push(player);
        socket.join(game.gameID);
        socket.gameID = game.gameID;
        game.assignPlayerColors();
        game.sendUpdate();
        game.sendNotification(player.username+' has joined the game!');
        if (game.players.length >= game.playerMaxLimit) {
          gamesNeedingPlayers.shift();
          game.prepareGame();
        }
      } else {
        // TODO: Send an error message back to this user saying the game has already started
      }
    } else {
      // Put players into the general queue
      console.log('Redirecting player',socket.id,'to general queue');
      fireGame(player,socket);
    }

  };

  var fireGame = function(player,socket) {
    var game;
    if (gamesNeedingPlayers.length <= 0) {
      gameID += 1;
      var gameIDStr = gameID.toString();
      game = new Game(gameIDStr, io);
      game.players.push(player);
      allGames[gameID] = game;
      gamesNeedingPlayers.push(game);
      socket.join(game.gameID);
      socket.gameID = game.gameID;
      console.log('Create new Game',game.gameID);
      game.assignPlayerColors();
      game.sendUpdate();
    } else {
      game = gamesNeedingPlayers[0];
      game.players.push(player);
      socket.join(game.gameID);
      socket.gameID = game.gameID;
      game.assignPlayerColors();
      game.sendUpdate();
      game.sendNotification(player.username+' has joined the game!');
      if (game.players.length >= game.playerMaxLimit) {
        gamesNeedingPlayers.shift();
        game.prepareGame();
      }
    }
  };

  var createGameWithFriends = function(socket) {
    var isUniqueRoom = false;
    var uniqueRoom = '';

    if (allGames[socket.gameID]) {
      // Get player object before we take this player out of the existing game.
      var existingGame = allGames[socket.gameID];
      var player = existingGame.getPlayer(socket.id);

      if (Object.keys(player).length !== 0) {
        exitGame(socket);
        // Generate a random 6-character game ID
        while (!isUniqueRoom) {
          uniqueRoom = '';
          for (var i = 0; i < 6; i++) {
            uniqueRoom += chars[Math.floor(Math.random()*chars.length)];
          }
          if (!allGames[uniqueRoom]) {
            isUniqueRoom = true;
          }
        }
        console.log('Created unique game',uniqueRoom);
        var game = new Game(uniqueRoom,io);
        game.players.push(player);
        allGames[uniqueRoom] = game;
        socket.join(game.gameID);
        socket.gameID = game.gameID;
        game.assignPlayerColors();
        game.sendUpdate();
      }
    }
  };

  var exitGame = function(socket) {
    if (allGames[socket.gameID]) { // Make sure game exists
      var game = allGames[socket.gameID];
      if (game.state === 'awaiting players' ||
        game.players.length-1 >= game.playerMinLimit) {
        game.removePlayer(socket.id);
      } else {
        game.stateDissolveGame();
        for (var j = 0; j < game.players.length; j++) {
          game.players[j].socket.leave(socket.gameID);
        }
        game.killGame();
        delete allGames[socket.gameID];
      }
    }
  };

};
<commit_msg>Prevent the same socket from joining the same game due to URL rewrite<commit_after>var Game = require('./game');
var Player = require('./player');
var mongoose = require('mongoose');
var User = mongoose.model('User');

var avatars = require(__dirname + '/../../app/controllers/avatars.js').all();
// Valid characters to use to generate random private game IDs
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";

module.exports = function(io) {

  var game;
  var allGames = {};
  var gamesNeedingPlayers = [];
  var gameID = 0;

  io.sockets.on('connection', function (socket) {
    console.log(socket.id +  ' Connected');
    socket.emit('id', {id: socket.id});

    socket.on('pickCards', function(data) {
      console.log(socket.id,"picked",data);
      if (allGames[socket.gameID]) {
        allGames[socket.gameID].pickCards(data.cards,socket.id);
      } else {
        console.log('Received pickCard from',socket.id, 'but game does not appear to exist!');
      }
    });

    socket.on('pickWinning', function(data) {
      if (allGames[socket.gameID]) {
        allGames[socket.gameID].pickWinning(data.card,socket.id);
      } else {
        console.log('Received pickWinning from',socket.id, 'but game does not appear to exist!');
      }
    });

    socket.on('joinGame', function(data) {
      joinGame(socket,data);
    });

    socket.on('startGame', function() {
      if (allGames[socket.gameID]) {
        var thisGame = allGames[socket.gameID];
        console.log('comparing',thisGame.players[0].socket.id,'with',socket.id);
        if (thisGame.players.length >= thisGame.playerMinLimit) {
          thisGame.prepareGame();
          thisGame.sendNotification('The game has begun!');
        }
      }
    });

    socket.on('joinNewGame', function(data) {
      exitGame(socket);
      joinGame(socket,data);
    });

    socket.on('createGameWithFriends', function() {
      createGameWithFriends(socket);
    });

    socket.on('leaveGame', function() {
      socket.leave(socket.gameID);
      exitGame(socket);
    });

    socket.on('disconnect', function(){
      console.log('Rooms on Disconnect ', io.sockets.manager.rooms);
      exitGame(socket);
    });
  });

  var joinGame = function(socket,data) {
    var player = new Player(socket);
    player.userID = data.userID;
    if (data.userID !== 'unauthenticated') {
      User.findOne({
        _id: data.userID
      }).exec(function(err, user) {
        if (err) {
          console.log('err',err);
          return err; // Hopefully this never happens.
        }
        if (!user) {
          // If the user's ID isn't found (rare)
          player.username = 'Guest';
          player.avatar = avatars[Math.floor(Math.random()*4)+12];
        } else {
          player.username = user.name;
          player.avatar = user.avatar || avatars[Math.floor(Math.random()*4)+12];
        }
        getGame(player,socket,data.room);
      });
    } else {
      // If the user isn't authenticated (guest)
      player.username = 'Guest';
      player.avatar = avatars[Math.floor(Math.random()*4)+12];
      getGame(player,socket,data.room);
    }
  };

  var getGame = function(player,socket,requestedGameId) {
    console.log(socket.id,'is requesting room',requestedGameId);
    if (requestedGameId.length && allGames[requestedGameId]) {
      console.log('Room',requestedGameId,'is valid');
      var game = allGames[requestedGameId];
      if (game.state === 'awaiting players' && game.players[0].socket.id !== socket.id) {
        // Put player into the requested game
        console.log('Allowing player to join',requestedGameId);
        game.players.push(player);
        socket.join(game.gameID);
        socket.gameID = game.gameID;
        game.assignPlayerColors();
        game.sendUpdate();
        game.sendNotification(player.username+' has joined the game!');
        if (game.players.length >= game.playerMaxLimit) {
          gamesNeedingPlayers.shift();
          game.prepareGame();
        }
      } else {
        // TODO: Send an error message back to this user saying the game has already started
      }
    } else {
      // Put players into the general queue
      console.log('Redirecting player',socket.id,'to general queue');
      fireGame(player,socket);
    }

  };

  var fireGame = function(player,socket) {
    var game;
    if (gamesNeedingPlayers.length <= 0) {
      gameID += 1;
      var gameIDStr = gameID.toString();
      game = new Game(gameIDStr, io);
      game.players.push(player);
      allGames[gameID] = game;
      gamesNeedingPlayers.push(game);
      socket.join(game.gameID);
      socket.gameID = game.gameID;
      console.log('Create new Game',game.gameID);
      game.assignPlayerColors();
      game.sendUpdate();
    } else {
      game = gamesNeedingPlayers[0];
      game.players.push(player);
      socket.join(game.gameID);
      socket.gameID = game.gameID;
      game.assignPlayerColors();
      game.sendUpdate();
      game.sendNotification(player.username+' has joined the game!');
      if (game.players.length >= game.playerMaxLimit) {
        gamesNeedingPlayers.shift();
        game.prepareGame();
      }
    }
  };

  var createGameWithFriends = function(socket) {
    var isUniqueRoom = false;
    var uniqueRoom = '';

    if (allGames[socket.gameID]) {
      // Get player object before we take this player out of the existing game.
      var existingGame = allGames[socket.gameID];
      var player = existingGame.getPlayer(socket.id);

      if (Object.keys(player).length !== 0) {
        exitGame(socket);
        // Generate a random 6-character game ID
        while (!isUniqueRoom) {
          uniqueRoom = '';
          for (var i = 0; i < 6; i++) {
            uniqueRoom += chars[Math.floor(Math.random()*chars.length)];
          }
          if (!allGames[uniqueRoom]) {
            isUniqueRoom = true;
          }
        }
        console.log('Created unique game',uniqueRoom);
        var game = new Game(uniqueRoom,io);
        game.players.push(player);
        allGames[uniqueRoom] = game;
        socket.join(game.gameID);
        socket.gameID = game.gameID;
        game.assignPlayerColors();
        game.sendUpdate();
      }
    }
  };

  var exitGame = function(socket) {
    if (allGames[socket.gameID]) { // Make sure game exists
      var game = allGames[socket.gameID];
      if (game.state === 'awaiting players' ||
        game.players.length-1 >= game.playerMinLimit) {
        game.removePlayer(socket.id);
      } else {
        game.stateDissolveGame();
        for (var j = 0; j < game.players.length; j++) {
          game.players[j].socket.leave(socket.gameID);
        }
        game.killGame();
        delete allGames[socket.gameID];
      }
    }
  };

};
<|endoftext|>


<commit_before>ace.define("ace/snippets/soy_template",["require","exports","module"], function(require, exports, module) {
"use strict";

exports.snippetText =undefined;
exports.scope = "soy_template";

});
<commit_msg>Update public/libs/bower_components/ace-builds/src-noconflict/snippets/soy_template.js<commit_after><|endoftext|>


<commit_before>var layout = (function () {
    var map = null;

    return {
        initMap : function () {
            var mapDet = {
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };

            map = new google.maps.Map(document.getElementById('transitMap'), mapDet);
            return map;
        },

        initMarker : function (coords, hoverText) {
            hoverText = (typeof hoverText == 'undefined') ? 'Marker' : hoverText;
            var markerPos = new google.maps.LatLng(coords[0], coords[1]);

            var markerIcon = {
                path: google.maps.SymbolPath.CIRCLE,
                fillColor: 'black',
                fillOpacity: 0.8,
                scale: 4
            };

            var marker = {
                position: markerPos,
                title: hoverText,
                icon: markerIcon
            };

            marker = new google.maps.Marker(marker);
            return marker;
        },

        moveMarkers : function (markerSet, interval) {
            interval = (typeof interval == 'undefined') ? 1000 : interval;
            var transition = setInterval(
                    function () {
                        for (var counter = 0; counter < markerSet.length; counter++) {
                            for (var i = 0; i < markerSet.length; i++) {
                                var curPos = new google.maps.LatLng(markerSet[i].coordSet[counter][0],
                                    markerSet[i].coordSet[counter][1]);
                                markerSet[i].marker.position = curPos;
                                markerSet[i].marker.setMap(map);
                            }
                        }
                    },
                    interval);
        },

        constructMarkerSet : function (markers) {
            var markerSet = new Array();
            for (var counter = 0; counter < markers.length; counter++) {
                var markerObj = layout.initMarker(markers[counter].coords[0], markers[counter].hoverText);
                var coordList = markers[counter].coords.slice(1);

                markerSet.push({
                    marker: markerObj,
                    coordSet: coordList
                });
            }
            return markerSet;
        },

        overlayKml : function (kmlUrl) {
            var kmlOptions = {
                map: map
            };
            var kmlLayer = new google.maps.KmlLayer(kmlUrl, kmlOptions);
        },

        init : function (kmlUrl, markerList, interval) {
            google.maps.event.addDomListener(window, 'load',
                    function () {
                        map = layout.initMap();
                        layout.overlayKml(kmlUrl);
                        var markerSet = layout.constructMarkerSet(markerList);
                        layout.moveMarkers(markerSet, interval);
                    });
        }
    };
})();

var processRoute = (function () {
    return {
        parseXml : function (xmlUrl) {
            $.ajax({
                url: xmlUrl,
                dataType: 'xml',
                success : function (data) {
                    var xmlNode = $('Document', data);
                    var lines = new Array();
                    var points = {};

                    xmlNode.find('Placemark > LineString > coordinates').each(function () {
                        var simPts = utils.trim($(this).text()).split(' ');
                        var grpPts = new Array();
                        for (eachPt in simPts) {
                            grpPts.push(utils.strip(simPts[eachPt]).split(','));
                        }
                        lines.push(grpPts);
                    });

                    xmlNode.find('Point').each(function () {
                        var parentTag = $(this).closest('Placemark');
                        points[parentTag.find('name').text()] = utils.strip(parentTag.find('Point').text()).split(',');
                    });
                },
                error : function (data) {
                    console.log('Error');
                }
            });
        }
    };
})();

var utils = (function () {
    return {
        strip : function (string) {
            return string.replace(/\s+/g, '').replace(/\n/g, '');
        },

        trim : function (string) {
            return string.replace(/^\s+|\s+$/g, '');
        },

        // Reimplemented from http://www.movable-type.co.uk/scripts/latlong.html
        haversine : function (sourceCoords, targetCoords) {
            var R = 6371; // km

            /** Converts numeric degrees to radians */
            if (typeof(Number.prototype.toRad) === "undefined") {
              Number.prototype.toRad = function() {
                return this * Math.PI / 180;
              }
            }

            var dLat = (targetCoords[0] - sourceCoords[0]).toRad();
            var dLon = (targetCoords[1] - sourceCoords[1]).toRad();
            var lat1 = sourceCoords[0].toRad();
            var lat2 = targetCoords[0].toRad();

            var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
            var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
            var d = R * c;
            return d;
        },

        percentDist : function (sourceCoords, targetCoords, percentage) {
            var newCoords = new Array();
            var ratio = percentage / 100;
            newCoords[0] = (1 - ratio) * sourceCoords[0] + ratio * targetCoords[0];
            newCoords[1] = (1 - ratio) * sourceCoords[1] + ratio * targetCoords[1];
            return newCoords;
        },

        percentInRange : function (lower, upper, target) {
            return ((target - lower) / (upper - lower)) * 100;
        },

        pointsBetweenStops: function (route, start, end) {
            return route.slice(route.indexOf(start), route.indexOf(end));
        },

        hashOfPercentDists : function (points) {
            var start = points[0];
            var routeLength = points.length;
            var end = points[routeLength - 1];
            var distanceHash = {
                0 : points[0]
            };
            var totalDist = 0;

            for (var x = 0; x < routeLength - 1; x++) {
                totalDist += utils.haversine(points[x], points[x + 1]);
                distanceHash[totalDist] = points[x + 1];
            }

            return distanceHash;
        }
    };
})();
<commit_msg>Return percentages as hash keys instead of distances<commit_after>var layout = (function () {
    var map = null;

    return {
        initMap : function () {
            var mapDet = {
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };

            map = new google.maps.Map(document.getElementById('transitMap'), mapDet);
            return map;
        },

        initMarker : function (coords, hoverText) {
            hoverText = (typeof hoverText == 'undefined') ? 'Marker' : hoverText;
            var markerPos = new google.maps.LatLng(coords[0], coords[1]);

            var markerIcon = {
                path: google.maps.SymbolPath.CIRCLE,
                fillColor: 'black',
                fillOpacity: 0.8,
                scale: 4
            };

            var marker = {
                position: markerPos,
                title: hoverText,
                icon: markerIcon
            };

            marker = new google.maps.Marker(marker);
            return marker;
        },

        moveMarkers : function (markerSet, interval) {
            interval = (typeof interval == 'undefined') ? 1000 : interval;
            var transition = setInterval(
                    function () {
                        for (var counter = 0; counter < markerSet.length; counter++) {
                            for (var i = 0; i < markerSet.length; i++) {
                                var curPos = new google.maps.LatLng(markerSet[i].coordSet[counter][0],
                                    markerSet[i].coordSet[counter][1]);
                                markerSet[i].marker.position = curPos;
                                markerSet[i].marker.setMap(map);
                            }
                        }
                    },
                    interval);
        },

        constructMarkerSet : function (markers) {
            var markerSet = new Array();
            for (var counter = 0; counter < markers.length; counter++) {
                var markerObj = layout.initMarker(markers[counter].coords[0], markers[counter].hoverText);
                var coordList = markers[counter].coords.slice(1);

                markerSet.push({
                    marker: markerObj,
                    coordSet: coordList
                });
            }
            return markerSet;
        },

        overlayKml : function (kmlUrl) {
            var kmlOptions = {
                map: map
            };
            var kmlLayer = new google.maps.KmlLayer(kmlUrl, kmlOptions);
        },

        init : function (kmlUrl, markerList, interval) {
            google.maps.event.addDomListener(window, 'load',
                    function () {
                        map = layout.initMap();
                        layout.overlayKml(kmlUrl);
                        var markerSet = layout.constructMarkerSet(markerList);
                        layout.moveMarkers(markerSet, interval);
                    });
        }
    };
})();

var processRoute = (function () {
    return {
        parseXml : function (xmlUrl) {
            $.ajax({
                url: xmlUrl,
                dataType: 'xml',
                success : function (data) {
                    var xmlNode = $('Document', data);
                    var lines = new Array();
                    var points = {};

                    xmlNode.find('Placemark > LineString > coordinates').each(function () {
                        var simPts = utils.trim($(this).text()).split(' ');
                        var grpPts = new Array();
                        for (eachPt in simPts) {
                            grpPts.push(utils.strip(simPts[eachPt]).split(','));
                        }
                        lines.push(grpPts);
                    });

                    xmlNode.find('Point').each(function () {
                        var parentTag = $(this).closest('Placemark');
                        points[parentTag.find('name').text()] = utils.strip(parentTag.find('Point').text()).split(',');
                    });
                },
                error : function (data) {
                    console.log('Error');
                }
            });
        }
    };
})();

var utils = (function () {
    return {
        strip : function (string) {
            return string.replace(/\s+/g, '').replace(/\n/g, '');
        },

        trim : function (string) {
            return string.replace(/^\s+|\s+$/g, '');
        },

        // Reimplemented from http://www.movable-type.co.uk/scripts/latlong.html
        haversine : function (sourceCoords, targetCoords) {
            var R = 6371; // km

            /** Converts numeric degrees to radians */
            if (typeof(Number.prototype.toRad) === "undefined") {
              Number.prototype.toRad = function() {
                return this * Math.PI / 180;
              }
            }

            var dLat = (targetCoords[0] - sourceCoords[0]).toRad();
            var dLon = (targetCoords[1] - sourceCoords[1]).toRad();
            var lat1 = sourceCoords[0].toRad();
            var lat2 = targetCoords[0].toRad();

            var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
            var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
            var d = R * c;
            return d;
        },

        percentDist : function (sourceCoords, targetCoords, percentage) {
            var newCoords = new Array();
            var ratio = percentage / 100;
            newCoords[0] = (1 - ratio) * sourceCoords[0] + ratio * targetCoords[0];
            newCoords[1] = (1 - ratio) * sourceCoords[1] + ratio * targetCoords[1];
            return newCoords;
        },

        percentInRange : function (lower, upper, target) {
            return ((target - lower) / (upper - lower)) * 100;
        },

        pointsBetweenStops: function (route, start, end) {
            return route.slice(route.indexOf(start), route.indexOf(end));
        },

        hashOfPercentDists : function (points) {
            var start = points[0];
            var routeLength = points.length;
            var end = points[routeLength - 1];
            var distanceHash = {
                0 : points[0]
            };
            var distances = new Array();
            var totalDist = 0;

            for (var x = 0; x < routeLength - 1; x++) {
                totalDist += utils.haversine(points[x], points[x + 1]);
                distances.push(totalDist);
            }

            for (var x = 0; x < distances.length; x++) {
                distanceHash[utils.percentInRange(0, totalDist, distances[x])] = points[x + 1];
            }

            return distanceHash;
        }
    };
})();
<|endoftext|>


<commit_before><commit_msg>Wrote basic interface<commit_after>/*
    Given a set of search parameters, do a call to the Yelp API
    and return the resulting Food Picker JS object.
*/
var fpObj = yelpAccess(limit, radius, latitude, longitude) {
    return 0;
};

/*
    Given a Food Picker JS object, generate a binary decision tree
    that contains the questions being used by Food Picker.
*/
var questionTree = genQuestions(fpObj) {
    return 0;
};<|endoftext|>


<commit_before>import {Mongo} from 'meteor/mongo';
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
import {SchemaHelpers} from '../schema_helpers.js';
import {Auth} from '../auth.js';
import {Util} from '../util.js';
import {ChangeTracker} from '../change_tracker/change_tracker.js';
import {NodeTypes} from '../node/node_types.js';

import {CodeModules} from '../code_module/code_module.js';
import {Datastores} from '../datastore/datastore.js';
import {DatastoreCategories} from '../datastore/datastore_catagories.js';
import {DatastoreDataTypes} from '../datastore/datastore_data_type.js';
import {ProjectCodeModuleTypes} from './project_code_module_types.js';
import {Nodes} from '../node/node.js';
import {Projects} from './project.js';

/**
 * User Project Versions
 */
export const ProjectVersion = new SimpleSchema({
  projectId: {
    type: String,
    denyUpdate: true
  },
  version: {
    type: String
  },
  active: {
    type: Boolean,
    defaultValue: true
  },
  // Standard tracking fields
  dateCreated: {
    type: Date,
    autoValue: SchemaHelpers.autoValueDateCreated,
    denyUpdate: true
  },
  createdBy: {
    type: String,
    autoValue: SchemaHelpers.autoValueCreatedBy,
    denyUpdate: true
  },
  dateModified: {
    type: Date,
    autoValue: SchemaHelpers.autoValueDateModified
  },
  modifiedBy: {
    type: String,
    autoValue: SchemaHelpers.autoValueModifiedBy
  }
});
export const ProjectVersions = new Mongo.Collection("project_versions");
ProjectVersions.attachSchema(ProjectVersion);
ProjectVersions.deny({
  insert: Auth.denyAlways,
  update(userId, doc) {
    var user = Meteor.users.findOne(userId);
    if(userId && user && doc && doc._id){
      return !user.hasAdminAccess(doc._id);
    }
    return true;
  },
  remove: Auth.denyAlways,
  fetch: ['projectId']
});
ProjectVersions.allow(Auth.ruleSets.allow.ifAuthenticated);
ChangeTracker.TrackChanges(ProjectVersions, "project_versions");

if(Meteor.isServer) {
  /**
   * Create a code module for this project version
   * @param projectVersion
   * @param type
   * @returns {*}
   */
  ProjectVersions.createCodeModule = function (projectVersion, type) {
    console.log("ProjectVersions.createCodeModule:", projectVersion._id, type);
    var name;
    switch (type){
      case ProjectCodeModuleTypes.global:
        name = projectVersion.project().title;
        break;
      case ProjectCodeModuleTypes.test:
        name = "Test";
        break;
      default:
        console.error("ProjectVersions.createCodeModule requires a known type:", type);
        return;
    }
    return CodeModules.insert({
      name: Util.wordsToCamel(name),
      projectId: projectVersion.projectId,
      projectVersionId: projectVersion._id,
      parentId: projectVersion._id,
      parentCollectionName: 'ProjectVersions',
      type: type,
      language: projectVersion.project().automationLanguage,
      modifiedBy: projectVersion.createdBy,
      createdBy: projectVersion.createdBy
    });
  };

  /**
   * Create a datastore for this project version server config data
   * @param projectVersion
   * @returns {*}
   */
  ProjectVersions.createServerConfigDatastore = function (projectVersion) {
    return Datastores.insert({
      title: projectVersion.project().title + " Server Config",
      projectId: projectVersion.projectId,
      projectVersionId: projectVersion._id,
      parentId: projectVersion._id,
      parentCollectionName: 'ProjectVersions',
      category: DatastoreCategories.serverConfig,
      modifiedBy: projectVersion.createdBy,
      createdBy: projectVersion.createdBy
    });
  };

  /**
   * Observe changes to the nodes to automatically pick up user type changes
   * Synchronize the changes to the data store representing that type
   */
  ProjectVersions.after.insert(function (userId, projectVersion) {
    // Create a new code module for this project version
    try {
      projectVersion.checkCodeModules();
    } catch(e) {
      console.error("ProjectVersions.after.insert: projectVersion.checkCodeModules failed,", e);
    }
  });
  ProjectVersions.after.update(function (userId, projectVersion, changedFields) {
    if(_.contains(changedFields, "title")){
      // update the code module title
      CodeModules.update({
        projectVersionId: projectVersion._id,
        parentId: projectVersion._id,
        type: ProjectCodeModuleTypes.global
      }, {
        $set: {
          name: Util.wordsToCamel(projectVersion.title)
        }
      });
    }
  });
}

/**
 * Helpers
 */
ProjectVersions.helpers({
  project () {
    return Projects.findOne(this.projectId)
  },
  userTypes () {
    return Nodes.find({projectVersionId: this._id, type: NodeTypes.userType}, {sort: {title: 1}});
  },
  platforms () {
    return Nodes.find({projectVersionId: this._id, type: NodeTypes.platform}, {sort: {title: 1}});
  },
  dataTypes(){
    DatastoreDataTypes.find({projectVersionId: this._id}, {sort: {title: 1}});
  },
  codeModule(type){
    if(type !== undefined){
      let projectVersion = this,
          codeModule = CodeModules.findOne({projectVersionId: projectVersion._id, parentId: projectVersion._id, type: type});
      if(codeModule){
        return codeModule;
      } else {
        let codeModuleId;
        if(Meteor.isServer) {
          codeModuleId = ProjectVersions.createCodeModule(projectVersion, type);
        } else {
          codeModuleId = Meteor.call("createVersionCodeModule", projectVersion.projectId, projectVersion._id, type);
        }
        return CodeModules.findOne({_id: codeModuleId});
      }
    } else {
      console.error("ProjectVersions.codeModule: type is required");
    }
  },
  globalCodeModule () {
    return this.codeModule(ProjectCodeModuleTypes.global)
  },
  testCodeModule () {
    return this.codeModule(ProjectCodeModuleTypes.test)
  },
  checkCodeModules () {
    console.log("ProjectVersions.checkCodeModules:", this._id);

    // Make sure there is a code module for each user type
    this.userTypes().forEach((userType) => { userType.codeModule() });

    // Make sure the project has the right code modules
    this.globalCodeModule();
    this.testCodeModule();
  },
  serverConfigDatastore () {
    let projectVersion = this,
        dataStore = Datastores.findOne({projectVersionId: projectVersion._id, parentId: projectVersion._id, category: DatastoreCategories.serverConfig});
    if(dataStore){
      return dataStore;
    } else {
      let dataStoreId;

      if(Meteor.isServer) {
        dataStoreId = ProjectVersions.createServerConfigDatastore(projectVersion);
      } else {
        dataStoreId = Meteor.call("createVersionServerConfigDatastore", projectVersion.projectId, projectVersion._id);
      }
      return Datastores.findOne({_id: dataStoreId});
    }
  }
});<commit_msg>Code formatting cleanup<commit_after>import { Mongo } from 'meteor/mongo';
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
import { SchemaHelpers } from '../schema_helpers.js';
import { Auth } from '../auth.js';
import { Util } from '../util.js';
import { ChangeTracker } from '../change_tracker/change_tracker.js';
import { NodeTypes } from '../nodes/node_types.js';
import { CodeModules } from '../code_module/code_module.js';
import { Datastores } from '../datastore/datastore.js';
import { DatastoreCategories } from '../datastore/datastore_catagories.js';
import { DatastoreDataTypes } from '../datastore/datastore_data_type.js';
import { ProjectCodeModuleTypes } from './project_code_module_types.js';
import { Nodes } from '../nodes/nodes.js';
import { Projects } from './project.js';

/**
 * User Project Versions
 */
export const ProjectVersion  = new SimpleSchema({
  projectId   : {
    type      : String,
    denyUpdate: true
  },
  version     : {
    type: String
  },
  active      : {
    type        : Boolean,
    defaultValue: true
  },
  // Standard tracking fields
  dateCreated : {
    type      : Date,
    autoValue : SchemaHelpers.autoValueDateCreated,
    denyUpdate: true
  },
  createdBy   : {
    type      : String,
    autoValue : SchemaHelpers.autoValueCreatedBy,
    denyUpdate: true
  },
  dateModified: {
    type     : Date,
    autoValue: SchemaHelpers.autoValueDateModified
  },
  modifiedBy  : {
    type     : String,
    autoValue: SchemaHelpers.autoValueModifiedBy
  }
});
export const ProjectVersions = new Mongo.Collection("project_versions");
ProjectVersions.attachSchema(ProjectVersion);
ProjectVersions.deny({
  insert: Auth.denyAlways,
  update(userId, doc) {
    var user = Meteor.users.findOne(userId);
    if (userId && user && doc && doc._id) {
      return !user.hasAdminAccess(doc._id);
    }
    return true;
  },
  remove: Auth.denyAlways,
  fetch : [ 'projectId' ]
});
ProjectVersions.allow(Auth.ruleSets.allow.ifAuthenticated);
ChangeTracker.TrackChanges(ProjectVersions, "project_versions");

if (Meteor.isServer) {
  /**
   * Create a code module for this project version
   * @param projectVersion
   * @param type
   * @returns {*}
   */
  ProjectVersions.createCodeModule = function (projectVersion, type) {
    console.log("ProjectVersions.createCodeModule:", projectVersion._id, type);
    var name;
    switch (type) {
      case ProjectCodeModuleTypes.global:
        name = projectVersion.project().title;
        break;
      case ProjectCodeModuleTypes.test:
        name = "Test";
        break;
      default:
        console.error("ProjectVersions.createCodeModule requires a known type:", type);
        return;
    }
    return CodeModules.insert({
      name                : Util.wordsToCamel(name),
      projectId           : projectVersion.projectId,
      projectVersionId    : projectVersion._id,
      parentId            : projectVersion._id,
      parentCollectionName: 'ProjectVersions',
      type                : type,
      language            : projectVersion.project().automationLanguage,
      modifiedBy          : projectVersion.createdBy,
      createdBy           : projectVersion.createdBy
    });
  };

  /**
   * Create a datastore for this project version server config data
   * @param projectVersion
   * @returns {*}
   */
  ProjectVersions.createServerConfigDatastore = function (projectVersion) {
    return Datastores.insert({
      title               : projectVersion.project().title + " Server Config",
      projectId           : projectVersion.projectId,
      projectVersionId    : projectVersion._id,
      parentId            : projectVersion._id,
      parentCollectionName: 'ProjectVersions',
      category            : DatastoreCategories.serverConfig,
      modifiedBy          : projectVersion.createdBy,
      createdBy           : projectVersion.createdBy
    });
  };

  /**
   * Observe changes to the nodes to automatically pick up user type changes
   * Synchronize the changes to the data store representing that type
   */
  ProjectVersions.after.insert(function (userId, projectVersion) {
    // Create a new code module for this project version
    try {
      projectVersion.checkCodeModules();
    } catch (e) {
      console.error("ProjectVersions.after.insert: projectVersion.checkCodeModules failed,", e);
    }
  });
  ProjectVersions.after.update(function (userId, projectVersion, changedFields) {
    if (_.contains(changedFields, "title")) {
      // update the code module title
      CodeModules.update({
        projectVersionId: projectVersion._id,
        parentId        : projectVersion._id,
        type            : ProjectCodeModuleTypes.global
      }, {
        $set: {
          name: Util.wordsToCamel(projectVersion.title)
        }
      });
    }
  });
}

/**
 * Helpers
 */
ProjectVersions.helpers({
  project () {
    return Projects.findOne(this.projectId)
  },
  userTypes () {
    return Nodes.find({ projectVersionId: this._id, type: NodeTypes.userType }, { sort: { title: 1 } });
  },
  platforms () {
    return Nodes.find({ projectVersionId: this._id, type: NodeTypes.platform }, { sort: { title: 1 } });
  },
  dataTypes(){
    DatastoreDataTypes.find({ projectVersionId: this._id }, { sort: { title: 1 } });
  },
  codeModule(type){
    if (type !== undefined) {
      let projectVersion = this,
          codeModule     = CodeModules.findOne({
            projectVersionId: projectVersion._id,
            parentId: projectVersion._id,
            type: type
          });
      if (codeModule) {
        return codeModule;
      } else {
        let codeModuleId;
        if (Meteor.isServer) {
          codeModuleId = ProjectVersions.createCodeModule(projectVersion, type);
        } else {
          codeModuleId = Meteor.call("createVersionCodeModule", projectVersion.projectId, projectVersion._id, type);
        }
        return CodeModules.findOne({ _id: codeModuleId });
      }
    } else {
      console.error("ProjectVersions.codeModule: type is required");
    }
  },
  globalCodeModule () {
    return this.codeModule(ProjectCodeModuleTypes.global)
  },
  testCodeModule () {
    return this.codeModule(ProjectCodeModuleTypes.test)
  },
  checkCodeModules () {
    console.log("ProjectVersions.checkCodeModules:", this._id);

    // Make sure there is a code module for each user type
    this.userTypes().forEach((userType) => {
      userType.codeModule()
    });

    // Make sure the project has the right code modules
    this.globalCodeModule();
    this.testCodeModule();
  },
  serverConfigDatastore () {
    let projectVersion = this,
        dataStore      = Datastores.findOne({
          projectVersionId: projectVersion._id,
          parentId: projectVersion._id,
          category: DatastoreCategories.serverConfig
        });
    if (dataStore) {
      return dataStore;
    } else {
      let dataStoreId;

      if (Meteor.isServer) {
        dataStoreId = ProjectVersions.createServerConfigDatastore(projectVersion);
      } else {
        dataStoreId = Meteor.call("createVersionServerConfigDatastore", projectVersion.projectId, projectVersion._id);
      }
      return Datastores.findOne({ _id: dataStoreId });
    }
  }
});<|endoftext|>


<commit_before>import api from './api';

var token = '';
var user = '';
var form = document.getElementById('loginForm');
var login = document.getElementById('login');

function get_token() {
  user = form.elements["user"].value;
  api('POST', user + '/tokens', function() {
    if ((hash = JSON.parse(this.responseText).token)) {
      form.style.display = 'none';
      localStorage.token = hash;
      localStorage.user = user;
      window.location.pathname = user;
    } else {
      alert('Please type them out again');
    }
  }, "user=" + user + "&password=" + form.elements["password"].value);
  return false;
}

login.onclick = get_token;

window.onbeforeunload = function() {
  api('DELETE');
};
<commit_msg>remove unused variable<commit_after>import api from './api';

var user = '';
var form = document.getElementById('loginForm');
var login = document.getElementById('login');

function get_token() {
  user = form.elements["user"].value;
  api('POST', user + '/tokens', function() {
    if ((hash = JSON.parse(this.responseText).token)) {
      form.style.display = 'none';
      localStorage.token = hash;
      localStorage.user = user;
      window.location.pathname = user;
    } else {
      alert('Please type them out again');
    }
  }, "user=" + user + "&password=" + form.elements["password"].value);
  return false;
}

login.onclick = get_token;

window.onbeforeunload = function() {
  api('DELETE');
};
<|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var oop = require("../../lib/oop");
var Behaviour = require("../behaviour").Behaviour;
var TokenIterator = require("../../token_iterator").TokenIterator;

function is(token, type) {
    return token.type.lastIndexOf(type + ".xml") > -1;
}

var XmlBehaviour = function () {

    this.add("string_dquotes", "insertion", function (state, action, editor, session, text) {
        if (text == '"' || text == "'") {
            var quote = text;
            var selected = session.doc.getTextRange(editor.getSelectionRange());
            if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) {
                return {
                    text: quote + selected + quote,
                    selection: false
                };
            }

            var cursor = editor.getCursorPosition();
            var line = session.doc.getLine(cursor.row);
            var rightChar = line.substring(cursor.column, cursor.column + 1);
            var iterator = new TokenIterator(session, cursor.row, cursor.column);
            var token = iterator.getCurrentToken();

            if (rightChar == quote && (is(token, "attribute-value") || is(token, "string"))) {
                // Ignore input and move right one if we're typing over the closing quote.
                return {
                    text: "",
                    selection: [1, 1]
                };
            }

            if (!token)
                token = iterator.stepBackward();

            if (!token)
                return;

            while (is(token, "tag-whitespace") || is(token, "whitespace")) {
                token = iterator.stepBackward();
            }
            var rightSpace = !rightChar || rightChar.match(/\s/);
            if (is(token, "attribute-equals") && (rightSpace || rightChar == '>') || (is(token, "decl-attribute-equals") && (rightSpace || rightChar == '?'))) {
                return {
                    text: quote + quote,
                    selection: [1, 1]
                };
            }
        }
    });

    this.add("string_dquotes", "deletion", function(state, action, editor, session, range) {
        var selected = session.doc.getTextRange(range);
        if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
            var line = session.doc.getLine(range.start.row);
            var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
            if (rightChar == selected) {
                range.end.column++;
                return range;
            }
        }
    });

    this.add("autoclosing", "insertion", function (state, action, editor, session, text) {
        if (text == '>') {
            var position = editor.getCursorPosition();
            var iterator = new TokenIterator(session, position.row, position.column);
            var token = iterator.getCurrentToken() || iterator.stepBackward();

            // exit if we're not in a tag
            if (!token || !(is(token, "tag-name") || is(token, "tag-whitespace") || is(token, "attribute-name") || is(token, "attribute-equals") || is(token, "attribute-value")))
                return;

            // exit if we're inside of a quoted attribute value
            if (is(token, "reference.attribute-value"))
                return;
            if (is(token, "attribute-value")) {
                var firstChar = token.value.charAt(0);
                if (firstChar == '"' || firstChar == "'") {
                    var lastChar = token.value.charAt(token.value.length - 1);
                    var tokenEnd = iterator.getCurrentTokenColumn() + token.value.length;
                    if (tokenEnd > position.column || tokenEnd == position.column && firstChar != lastChar)
                        return;
                }
            }

            // find tag name
            while (!is(token, "tag-name")) {
                token = iterator.stepBackward();
            }

            var tokenRow = iterator.getCurrentTokenRow();
            var tokenColumn = iterator.getCurrentTokenColumn();

            // exit if the tag is ending
            if (is(iterator.stepBackward(), "end-tag-open"))
                return;

            var element = token.value;
            if (tokenRow == position.row)
                element = element.substring(0, position.column - tokenColumn);

            if (this.voidElements.hasOwnProperty(element.toLowerCase()))
                 return;

            return {
               text: '>' + '</' + element + '>',
               selection: [1, 1]
            };
        }
    });

    this.add('autoindent', 'insertion', function (state, action, editor, session, text) {
        if (text == "\n") {
            var cursor = editor.getCursorPosition();
            var line = session.getLine(cursor.row);
            var iterator = new TokenIterator(session, cursor.row, cursor.column);
            var token = iterator.getCurrentToken();

            if (token && token.type.indexOf('tag-close') !== -1) {
                //get tag name
                while (token && token.type.indexOf('tag-name') === -1) {
                    token = iterator.stepBackward();
                }

                var single_tags = ['!doctype','area','base','br','hr','input','img','link','meta'];

                if (token && token.value && single_tags.indexOf(token.value) === -1) {
                    var nextToken = session.getTokenAt(cursor.row, cursor.column+1);
                    var next_indent = this.$getIndent(line);
                    var indent = next_indent + session.getTabString();

                    if (nextToken && nextToken.value === '</') {
                        return {
                            text: '\n' + indent + '\n' + next_indent,
                            selection: [1, indent.length, 1, indent.length]
                        };
                    }else{
                        return {
                            text: '\n' + indent
                        };
                    }
                }
            }
        }
    });

};

oop.inherits(XmlBehaviour, Behaviour);

exports.XmlBehaviour = XmlBehaviour;
});
<commit_msg>don't indent after closing tag<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var oop = require("../../lib/oop");
var Behaviour = require("../behaviour").Behaviour;
var TokenIterator = require("../../token_iterator").TokenIterator;

function is(token, type) {
    return token.type.lastIndexOf(type + ".xml") > -1;
}

var XmlBehaviour = function () {

    this.add("string_dquotes", "insertion", function (state, action, editor, session, text) {
        if (text == '"' || text == "'") {
            var quote = text;
            var selected = session.doc.getTextRange(editor.getSelectionRange());
            if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) {
                return {
                    text: quote + selected + quote,
                    selection: false
                };
            }

            var cursor = editor.getCursorPosition();
            var line = session.doc.getLine(cursor.row);
            var rightChar = line.substring(cursor.column, cursor.column + 1);
            var iterator = new TokenIterator(session, cursor.row, cursor.column);
            var token = iterator.getCurrentToken();

            if (rightChar == quote && (is(token, "attribute-value") || is(token, "string"))) {
                // Ignore input and move right one if we're typing over the closing quote.
                return {
                    text: "",
                    selection: [1, 1]
                };
            }

            if (!token)
                token = iterator.stepBackward();

            if (!token)
                return;

            while (is(token, "tag-whitespace") || is(token, "whitespace")) {
                token = iterator.stepBackward();
            }
            var rightSpace = !rightChar || rightChar.match(/\s/);
            if (is(token, "attribute-equals") && (rightSpace || rightChar == '>') || (is(token, "decl-attribute-equals") && (rightSpace || rightChar == '?'))) {
                return {
                    text: quote + quote,
                    selection: [1, 1]
                };
            }
        }
    });

    this.add("string_dquotes", "deletion", function(state, action, editor, session, range) {
        var selected = session.doc.getTextRange(range);
        if (!range.isMultiLine() && (selected == '"' || selected == "'")) {
            var line = session.doc.getLine(range.start.row);
            var rightChar = line.substring(range.start.column + 1, range.start.column + 2);
            if (rightChar == selected) {
                range.end.column++;
                return range;
            }
        }
    });

    this.add("autoclosing", "insertion", function (state, action, editor, session, text) {
        if (text == '>') {
            var position = editor.getCursorPosition();
            var iterator = new TokenIterator(session, position.row, position.column);
            var token = iterator.getCurrentToken() || iterator.stepBackward();

            // exit if we're not in a tag
            if (!token || !(is(token, "tag-name") || is(token, "tag-whitespace") || is(token, "attribute-name") || is(token, "attribute-equals") || is(token, "attribute-value")))
                return;

            // exit if we're inside of a quoted attribute value
            if (is(token, "reference.attribute-value"))
                return;
            if (is(token, "attribute-value")) {
                var firstChar = token.value.charAt(0);
                if (firstChar == '"' || firstChar == "'") {
                    var lastChar = token.value.charAt(token.value.length - 1);
                    var tokenEnd = iterator.getCurrentTokenColumn() + token.value.length;
                    if (tokenEnd > position.column || tokenEnd == position.column && firstChar != lastChar)
                        return;
                }
            }

            // find tag name
            while (!is(token, "tag-name")) {
                token = iterator.stepBackward();
            }

            var tokenRow = iterator.getCurrentTokenRow();
            var tokenColumn = iterator.getCurrentTokenColumn();

            // exit if the tag is ending
            if (is(iterator.stepBackward(), "end-tag-open"))
                return;

            var element = token.value;
            if (tokenRow == position.row)
                element = element.substring(0, position.column - tokenColumn);

            if (this.voidElements.hasOwnProperty(element.toLowerCase()))
                 return;

            return {
               text: '>' + '</' + element + '>',
               selection: [1, 1]
            };
        }
    });

    this.add('autoindent', 'insertion', function (state, action, editor, session, text) {
        if (text == "\n") {
            var cursor = editor.getCursorPosition();
            var line = session.getLine(cursor.row);
            var iterator = new TokenIterator(session, cursor.row, cursor.column);
            var token = iterator.getCurrentToken();

            if (token && token.type.indexOf('tag-close') !== -1) {
                //get tag name
                while (token && token.type.indexOf('tag-name') === -1) {
                    token = iterator.stepBackward();
                }

                if (!token) {
                    return;
                }

                var tag = token.value;

                //don't indent after closing tag
                token = iterator.stepBackward();
                if (token && token.type.indexOf('end-tag') !== -1) {
                    return;
                }

                var single_tags = ['!doctype','area','base','br','hr','input','img','link','meta'];

                if (single_tags.indexOf(tag) === -1) {
                    var nextToken = session.getTokenAt(cursor.row, cursor.column+1);
                    var next_indent = this.$getIndent(line);
                    var indent = next_indent + session.getTabString();

                    if (nextToken && nextToken.value === '</') {
                        return {
                            text: '\n' + indent + '\n' + next_indent,
                            selection: [1, indent.length, 1, indent.length]
                        };
                    } else {
                        return {
                            text: '\n' + indent
                        };
                    }
                }
            }
        }
    });

};

oop.inherits(XmlBehaviour, Behaviour);

exports.XmlBehaviour = XmlBehaviour;
});
<|endoftext|>