<commit_before>define(function(require, exports, module) {
    main.consumes = [
        "c9", "Previewer", "fs", "dialog.error", "commands", "tabManager"
    ];
    main.provides = ["preview.markdown"];
    return main;

    // @todo possible improvements: http://benweet.github.io/stackedit/#

    function main(options, imports, register) {
        var Previewer = imports.Previewer;
        var c9 = imports.c9;
        var fs = imports.fs;
        var commands = imports.commands;
        var tabManager = imports.tabManager;
        var showError = imports["dialog.error"].show;
        var dirname = require("path").dirname;

        /***** Initialization *****/

        var plugin = new Previewer("Ajax.org", main.consumes, {
            caption: "Markdown",
            index: 200,
            selector: function(path) {
                return path && path.match(/(?:\.md|\.markdown)$/i);
            }
        });
        var emit = plugin.getEmitter();

        var counter = 0;
        var HTMLURL, previewOrigin;

        /***** Methods *****/

        function getPreviewUrl(fn) {
            if (options.local && document.baseURI.substr(0, 5) == "file:")
                return setTimeout(getPreviewUrl.bind(null, fn), 100);
            else if (HTMLURL)
                return fn(HTMLURL);

            HTMLURL = (options.staticPrefix
                ? (options.local ? dirname(document.baseURI) + "/static" : options.staticPrefix)
                    + options.htmlPath
                : "/static/plugins/c9.ide.preview/previewers/markdown.html")
                    + "?host=" + (options.local ? "local" : location.origin);

            if (HTMLURL.charAt(0) == "/")
                HTMLURL = location.protocol + "//" + location.host + HTMLURL;

            previewOrigin = HTMLURL.match(/^(?:[^\/]|\/\/)*/)[0];

            fn(HTMLURL);
        }

        // function cleanIframeSrc(src) {
        //     return src
        //         .replace(/\?host=.*?(?:\&|$)/, "")
        //         .replace(/[\?\&]$/, "");
        // }

        /***** Lifecycle *****/

        plugin.on("load", function(){

        });
        plugin.on("documentLoad", function(e) {
            var doc = e.doc;
            var session = doc.getSession();
            var tab = doc.tab;
            var editor = e.editor;

            if (session.iframe) {
                session.editor = editor;
                editor.container.appendChild(session.iframe);
                return;
            }

            var iframe = document.createElement("iframe");

            iframe.setAttribute("nwfaketop", true);
            iframe.setAttribute("nwdisable", true);

            iframe.style.width = "100%";
            iframe.style.height = "100%";
            iframe.style.border = 0;
            iframe.style.backgroundColor = "rgba(255, 255, 255, 0.88)";

            if (options.local) {
                iframe.addEventListener("load", function(){
                    // @todo to do this correctly stack needs to allow switching previewer
                    // plugin.activeSession.add(iframe.contentWindow.location.href);

                    iframe.contentWindow.opener = window;
                    if (iframe.contentWindow.start)
                        iframe.contentWindow.start(window);
                });
            }

            var onMessage = function(e) {
                if (c9.hosted && event.origin !== previewOrigin)
                    return;

                if (e.data.id != session.id)
                    return;

                if (e.data.message == "exec") {
                    commands.exec(e.data.command);
                }
                else if (e.data.message == "focus") {
                    tabManager.focusTab(tab);
                }
                else if (e.data.message == "stream.document") {
                    session.source = e.source;

                    if (session.previewTab) {
                        var doc = session.previewTab.document;

                        session.source.postMessage({
                            type: "document",
                            content: doc.value
                        }, "*");

                        if (!doc.hasValue())
                            doc.once("setValue", function(){
                                emit("update", { previewDocument: doc });
                            });
                    }
                    else {
                        fs.readFile(session.path, function(err, data) {
                            if (err)
                                return showError(err.message);

                            session.source.postMessage({
                                type: "document",
                                content: data
                            }, "*");
                        });
                    }

                    session.source.postMessage({
                        type: "keys",
                        keys: commands.getExceptionBindings()
                    }, "*");

                    tab.classList.remove("loading");
                }
            };
            window.addEventListener("message", onMessage, false);
            session.addOther(function(){
                window.removeEventListener("message", onMessage, false);
            });

            // Set iframe
            session.iframe = iframe;
            session.id = "markdown" + counter++;

            session.destroy = function(){
                delete session.editor;
                delete session.iframe;
            }

            // Load the markup renderer
            getPreviewUrl(function(url) {
                iframe.src = url + "&id=" + session.id;
            });

            session.editor = editor;
            editor.container.appendChild(session.iframe);
        });
        plugin.on("documentUnload", function(e) {
            var doc = e.doc;
            var session = doc.getSession();
            var iframe = session.iframe;

            iframe.parentNode.removeChild(iframe);

            doc.tab.classList.remove("loading");
        });
        plugin.on("documentActivate", function(e) {
            var session = e.doc.getSession();

            session.iframe.style.display = "block";
            session.editor.setLocation(session.path);
            session.editor.setButtonStyle("Markdown", "page_white.png");
        });
        plugin.on("documentDeactivate", function(e) {
            var session = e.doc.getSession();
            session.iframe.style.display = "none";
        });
        plugin.on("navigate", function(e) {
            var tab = plugin.activeDocument.tab;
            var iframe = plugin.activeSession.iframe;
            var editor = plugin.activeSession.editor;

            tab.classList.add("loading");

            tab.title =
            tab.tooltip = "[M] " + e.url;
            editor.setLocation(e.url);

            iframe.src = iframe.src;
        });
        plugin.on("update", function(e) {
            var session = plugin.activeSession;
            if (!session.source) return; // Renderer is not loaded yet

            session.source.postMessage({
                type: "document",
                content: e.previewDocument.value
            }, "*");
        });
        plugin.on("reload", function(){
            var iframe = plugin.activeSession.iframe;
            var tab = plugin.activeDocument.tab;
            tab.classList.add("loading");
            iframe.src = iframe.src;
        });
        plugin.on("popout", function(){
            var src = plugin.activeSession.iframe.src;
            window.open(src);
        });
        plugin.on("enable", function(){

        });
        plugin.on("disable", function(){

        });
        plugin.on("unload", function(){
        });

        /***** Register and define API *****/

        /**
         * Previewer for markdown content.
         **/
        plugin.freezePublicAPI({
        });

        register(null, {
            "preview.markdown": plugin
        });
    }
});<commit_msg>Fixes +3147. Properly work with built in dev tools<commit_after>define(function(require, exports, module) {
    main.consumes = [
        "c9", "Previewer", "fs", "dialog.error", "commands", "tabManager"
    ];
    main.provides = ["preview.markdown"];
    return main;

    // @todo possible improvements: http://benweet.github.io/stackedit/#

    function main(options, imports, register) {
        var Previewer = imports.Previewer;
        var c9 = imports.c9;
        var fs = imports.fs;
        var commands = imports.commands;
        var tabManager = imports.tabManager;
        var showError = imports["dialog.error"].show;
        var dirname = require("path").dirname;

        /***** Initialization *****/

        var plugin = new Previewer("Ajax.org", main.consumes, {
            caption: "Markdown",
            index: 200,
            selector: function(path) {
                return path && path.match(/(?:\.md|\.markdown)$/i);
            }
        });
        var emit = plugin.getEmitter();

        var counter = 0;
        var HTMLURL, previewOrigin;

        /***** Methods *****/

        function getPreviewUrl(fn) {
            if (options.local && document.baseURI.substr(0, 5) == "file:")
                return setTimeout(getPreviewUrl.bind(null, fn), 100);
            else if (HTMLURL)
                return fn(HTMLURL);

            HTMLURL = (options.staticPrefix
                ? (options.local ? dirname(document.baseURI) + "/static" : options.staticPrefix)
                    + options.htmlPath
                : "/static/plugins/c9.ide.preview/previewers/markdown.html")
                    + "?host=" + (options.local ? "local" : location.origin);

            if (HTMLURL.charAt(0) == "/")
                HTMLURL = location.protocol + "//" + location.host + HTMLURL;

            previewOrigin = HTMLURL.match(/^(?:[^\/]|\/\/)*/)[0];

            fn(HTMLURL);
        }

        // function cleanIframeSrc(src) {
        //     return src
        //         .replace(/\?host=.*?(?:\&|$)/, "")
        //         .replace(/[\?\&]$/, "");
        // }

        /***** Lifecycle *****/

        plugin.on("load", function(){

        });
        plugin.on("documentLoad", function(e) {
            var doc = e.doc;
            var session = doc.getSession();
            var tab = doc.tab;
            var editor = e.editor;

            if (session.iframe) {
                session.editor = editor;
                editor.container.appendChild(session.iframe);
                return;
            }

            var iframe = document.createElement("iframe");

            iframe.setAttribute("nwfaketop", true);
            iframe.setAttribute("nwdisable", true);

            iframe.style.width = "100%";
            iframe.style.height = "100%";
            iframe.style.border = 0;
            iframe.style.backgroundColor = "rgba(255, 255, 255, 0.88)";

            if (options.local) {
                iframe.addEventListener("load", function(){
                    // @todo to do this correctly stack needs to allow switching previewer
                    // plugin.activeSession.add(iframe.contentWindow.location.href);

                    iframe.contentWindow.opener = window;
                    if (iframe.contentWindow.start)
                        iframe.contentWindow.start(window);
                });
            }

            var onMessage = function(e) {
                if (c9.hosted && event.origin !== previewOrigin)
                    return;

                if (e.data.id != session.id)
                    return;

                if (e.data.message == "exec") {
                    commands.exec(e.data.command);
                }
                else if (e.data.message == "focus") {
                    tabManager.focusTab(tab);
                }
                else if (e.data.message == "stream.document") {
                    session.source = e.source;

                    if (session.previewTab) {
                        var doc = session.previewTab.document;

                        session.source.postMessage({
                            type: "document",
                            content: doc.value
                        }, "*");

                        if (!doc.hasValue())
                            doc.once("setValue", function(){
                                emit("update", { previewDocument: doc });
                            });
                    }
                    else {
                        fs.readFile(session.path, function(err, data) {
                            if (err)
                                return showError(err.message);

                            session.source.postMessage({
                                type: "document",
                                content: data
                            }, "*");
                        });
                    }

                    session.source.postMessage({
                        type: "keys",
                        keys: commands.getExceptionBindings()
                    }, "*");

                    tab.classList.remove("loading");
                }
            };
            window.addEventListener("message", onMessage, false);

            // Set iframe
            session.iframe = iframe;
            session.id = "markdown" + counter++;

            session.destroy = function(){
                delete session.editor;
                delete session.iframe;

                window.removeEventListener("message", onMessage, false);
            }

            // Load the markup renderer
            getPreviewUrl(function(url) {
                iframe.src = url + "&id=" + session.id;
            });

            session.editor = editor;
            editor.container.appendChild(session.iframe);
        });
        plugin.on("documentUnload", function(e) {
            var doc = e.doc;
            var session = doc.getSession();
            var iframe = session.iframe;

            iframe.parentNode.removeChild(iframe);

            doc.tab.classList.remove("loading");
        });
        plugin.on("documentActivate", function(e) {
            var session = e.doc.getSession();

            session.iframe.style.display = "block";
            session.editor.setLocation(session.path);
            session.editor.setButtonStyle("Markdown", "page_white.png");
        });
        plugin.on("documentDeactivate", function(e) {
            var session = e.doc.getSession();
            session.iframe.style.display = "none";
        });
        plugin.on("navigate", function(e) {
            var tab = plugin.activeDocument.tab;
            var iframe = plugin.activeSession.iframe;
            var editor = plugin.activeSession.editor;

            tab.classList.add("loading");

            tab.title =
            tab.tooltip = "[M] " + e.url;
            editor.setLocation(e.url);

            iframe.src = iframe.src;
        });
        plugin.on("update", function(e) {
            var session = plugin.activeSession;
            if (!session.source) return; // Renderer is not loaded yet

            session.source.postMessage({
                type: "document",
                content: e.previewDocument.value
            }, "*");
        });
        plugin.on("reload", function(){
            var iframe = plugin.activeSession.iframe;
            var tab = plugin.activeDocument.tab;
            tab.classList.add("loading");
            iframe.src = iframe.src;
        });
        plugin.on("popout", function(){
            var src = plugin.activeSession.iframe.src;
            window.open(src);
        });
        plugin.on("enable", function(){

        });
        plugin.on("disable", function(){

        });
        plugin.on("unload", function(){
        });

        /***** Register and define API *****/

        /**
         * Previewer for markdown content.
         **/
        plugin.freezePublicAPI({
        });

        register(null, {
            "preview.markdown": plugin
        });
    }
});<|endoftext|>


<commit_before>(function () {
	'use strict';

	///////////////////
	// SUBSCRIPTIONS //
	///////////////////

	function checked(checks, callback) {
		return function (...args) {
			for (let i = 0; i < args.length; i++)
				check(args[i], checks[i]);
			return callback(...args, this.userId);
		};
	}

	Meteor.publish('categories', () => Progressor.categories.find());
	Meteor.publish('category', checked([String], id => Progressor.categories.find(id)));
	Meteor.publish('categoriesForLanguage', checked([String], lng => Progressor.categories.find({ programmingLanguage: lng })));

	Meteor.publish('publicExercises', () => Progressor.exercises.find({ category_id: { $exists: true }, 'released.confirmed': { $exists: true } }));
	Meteor.publish('publicOrMyExercises', checked([], userId => Progressor.exercises.find({ category_id: { $exists: true }, $or: [{ 'released.confirmed': { $exists: true } }, { author_id: userId }, { lastEditor_id: userId }] })));
	Meteor.publish('publicExercisesForCategory', checked([String], cat => Progressor.exercises.find({ category_id: cat, 'released.confirmed': { $exists: true } })));
	Meteor.publish('publicExercisesForLanguage', checked([String], lng => Progressor.exercises.find({ programmingLanguage: lng, category_id: { $exists: true }, 'released.confirmed': { $exists: true } })));
	Meteor.publish('unconfirmedExercises', () => Progressor.exercises.find({ category_id: { $exists: true }, 'released.requested': { $exists: true }, 'released.confirmed': { $exists: false } }));
	Meteor.publish('exercise', checked([String], id => Progressor.exercises.find({ _id: id, category_id: { $exists: true } })));
	Meteor.publish('exerciseByResult', function (id) {
		check(id, String);
		let result = Progressor.results.findOne({ user_id: this.userId, _id: id });
		if (result)
			return Progressor.exercises.find({ _id: result.exercise_id, category_id: { $exists: true } });
	});

	Meteor.publish('myResults', userId => Progressor.results.find({ user_id: userId }));
	Meteor.publish('myResult', checked([String], (id, userId) => Progressor.results.find({ user_id: userId, _id: id })));
	Meteor.publish('myExerciseResult', checked([String], (id, userId) => Progressor.results.find({ user_id: userId, exercise_id: id })));

	//////////////////////////
	// MODIFICATION METHODS //
	//////////////////////////

	Meteor.methods(
		{
			saveCategory(category) {
				check(category, Match.ObjectIncluding(
					{
						programmingLanguage: String,
						names: [Match.ObjectIncluding({ language: String, name: String })],
						descriptions: [Match.ObjectIncluding({ language: String, description: String })]
					}));

				let user = Meteor.user();
				if (!user || !user.roles || !user.roles[Roles.GLOBAL_GROUP] || !_.contains(user.roles[Roles.GLOBAL_GROUP], Progressor.ROLE_ADMIN))
					throw new Meteor.Error('unauthorised', 'Only administrators can edit categories.');

				if (!category.author_id)
					category.author_id = this.userId;
				category.lastEditor_id = this.userId;
				category.lastEdited = new Date();

				return Progressor.categories.upsert(category._id, category).insertedId || category._id;
			},
			deleteCategory(category) {
				check(category, Match.ObjectIncluding({ _id: String }));

				let user = Meteor.user();
				if (!user || !user.roles || !user.roles[Roles.GLOBAL_GROUP] || !_.contains(user.roles[Roles.GLOBAL_GROUP], Progressor.ROLE_ADMIN))
					throw new Meteor.Error('unauthorised', 'Only administrators can edit categories.');

				return Progressor.categories.remove(category._id).rowsAffected;
			},
			saveExercise(exercise) {
				check(exercise, Match.ObjectIncluding(
					{
						programmingLanguage: String,
						category_id: String,
						difficulty: Match.Integer,
						type: Match.Integer
					}));

				let user = Meteor.user();
				if (user && user.roles && user.roles[Roles.GLOBAL_GROUP] && _.contains(user.roles[Roles.GLOBAL_GROUP], Progressor.ROLE_ADMIN)) /*OK*/;
				else if (exercise.author_id === this.userId && exercise.released && exercise.released.requested)
					throw new Meteor.Error('unauthorised', 'Only administrators can edit released exercises.');
				else
					throw new Meteor.Error('unauthorised', 'Only authors and administrators can edit exercises.');

				if (!exercise.author_id)
					exercise.author_id = this.userId;
				exercise.lastEditor_id = this.userId;
				exercise.lastEdited = new Date();

				return Progressor.exercises.upsert(exercise._id, _.omit(exercise, 'category')).insertedId || exercise._id;
			},
			toggleArchiveExercise(exercise, archive) {
				check(exercise, Match.ObjectIncluding({ _id: String }));
				check(archive, Boolean);

				return Progressor.exercises.upsert(exercise._id, { [archive === true ? '$set' : '$unset']: { archived: true } }).rowsAffected;
			},
			deleteExercise(exercise) {
				check(exercise, Match.ObjectIncluding({ _id: String }));

				let user = Meteor.user();
				if (user && user.roles && user.roles[Roles.GLOBAL_GROUP] && _.contains(user.roles[Roles.GLOBAL_GROUP], Progressor.ROLE_ADMIN)) /*OK*/;
				else if (exercise.author_id === this.userId && exercise.released && exercise.released.requested)
					throw new Meteor.Error('unauthorised', 'Only administrators can edit released exercises.');
				else
					throw new Meteor.Error('unauthorised', 'Only authors and administrators can edit exercises.');

				return Progressor.exercises.remove(exercise._id).rowsAffected;
			}
		});

	///////////////////////////
	// HOUSTON CONFIGURATION //
	///////////////////////////

	Houston.add_collection(Meteor.users);
	Houston.add_collection(Meteor.roles);

	Houston.add_collection(Houston._admins);

	function toggleFlag(collection, flag, elementName, setName, unsetName) {
		return function (document) {
			check(document, Match.ObjectIncluding({ _id: String }));

			return Progressor[collection].update(document._id, { [document[flag] !== true ? '$set' : '$unset']: { [flag]: true } }) === 1
				? `${elementName} '${document._id}' successfully ${document[flag] !== true ? setName : unsetName}.`
				: `${elementName} '${document._id}' could NOT successfully be ${document[flag] !== true ? setName : unsetName}!`;
		}
	}

	Houston.methods('exercises', {
		'Archive/Restore': toggleFlag('exercises', 'archived', 'Exercise', 'archived', 'restored'),
		'Release/Hide'(document) {
			check(document, Match.ObjectIncluding({ _id: String }));

			let release = !document.released || !document.released.confirmed;
			let result = release
				? Progressor.exercises.update(document._id, { $set: { released: { requested: document.released && document.released.requested ? document.released.requested : new Date(), confirmed: new Date(), confirmor_id: this.userId } } })
				: Progressor.exercises.update(document._id, { $unset: { 'released.confirmed': null, 'released.confirmor_id': null } });

			return result === 1
				? `Exercise '${document._id}' successfully ${release ? 'released' : 'hidden'}.`
				: `Exercise '${document._id}' could NOT successfully be ${release ? 'released' : 'hidden'}!`;
		}
	});

})();
<commit_msg>prevent publishing solution on client<commit_after>(function () {
	'use strict';

	///////////////////
	// SUBSCRIPTIONS //
	///////////////////

	function checked(checks, callback) {
		return function (...args) {
			for (let i = 0; i < args.length; i++)
				check(args[i], checks[i]);
			return callback(...args, this.userId);
		};
	}

	Meteor.publish('categories', () => Progressor.categories.find());
	Meteor.publish('category', checked([String], id => Progressor.categories.find(id)));
	Meteor.publish('categoriesForLanguage', checked([String], lng => Progressor.categories.find({ programmingLanguage: lng })));

	Meteor.publish('publicExercises', () => Progressor.exercises.find({ category_id: { $exists: true }, 'released.confirmed': { $exists: true } }));
	Meteor.publish('publicOrMyExercises', checked([], userId => Progressor.exercises.find({ category_id: { $exists: true }, $or: [{ 'released.confirmed': { $exists: true } }, { author_id: userId }, { lastEditor_id: userId }] })));
	Meteor.publish('publicExercisesForCategory', checked([String], cat => Progressor.exercises.find({ category_id: cat, 'released.confirmed': { $exists: true } })));
	Meteor.publish('publicExercisesForLanguage', checked([String], lng => Progressor.exercises.find({ programmingLanguage: lng, category_id: { $exists: true }, 'released.confirmed': { $exists: true } })));
	Meteor.publish('unconfirmedExercises', () => Progressor.exercises.find({ category_id: { $exists: true }, 'released.requested': { $exists: true }, 'released.confirmed': { $exists: false } }));
	Meteor.publish('exercise', checked([String], id => Progressor.exercises.find({ _id: id, category_id: { $exists: true } }, {fields: {solution: 0}})));
	Meteor.publish('exerciseByResult', function (id) {
		check(id, String);
		let result = Progressor.results.findOne({ user_id: this.userId, _id: id });
		if (result)
			return Progressor.exercises.find({ _id: result.exercise_id, category_id: { $exists: true } });
	});

	Meteor.publish('myResults', userId => Progressor.results.find({ user_id: userId }));
	Meteor.publish('myResult', checked([String], (id, userId) => Progressor.results.find({ user_id: userId, _id: id })));
	Meteor.publish('myExerciseResult', checked([String], (id, userId) => Progressor.results.find({ user_id: userId, exercise_id: id })));

	//////////////////////////
	// MODIFICATION METHODS //
	//////////////////////////

	Meteor.methods(
		{
			saveCategory(category) {
				check(category, Match.ObjectIncluding(
					{
						programmingLanguage: String,
						names: [Match.ObjectIncluding({ language: String, name: String })],
						descriptions: [Match.ObjectIncluding({ language: String, description: String })]
					}));

				let user = Meteor.user();
				if (!user || !user.roles || !user.roles[Roles.GLOBAL_GROUP] || !_.contains(user.roles[Roles.GLOBAL_GROUP], Progressor.ROLE_ADMIN))
					throw new Meteor.Error('unauthorised', 'Only administrators can edit categories.');

				if (!category.author_id)
					category.author_id = this.userId;
				category.lastEditor_id = this.userId;
				category.lastEdited = new Date();

				return Progressor.categories.upsert(category._id, category).insertedId || category._id;
			},
			deleteCategory(category) {
				check(category, Match.ObjectIncluding({ _id: String }));

				let user = Meteor.user();
				if (!user || !user.roles || !user.roles[Roles.GLOBAL_GROUP] || !_.contains(user.roles[Roles.GLOBAL_GROUP], Progressor.ROLE_ADMIN))
					throw new Meteor.Error('unauthorised', 'Only administrators can edit categories.');

				return Progressor.categories.remove(category._id).rowsAffected;
			},
			saveExercise(exercise) {
				check(exercise, Match.ObjectIncluding(
					{
						programmingLanguage: String,
						category_id: String,
						difficulty: Match.Integer,
						type: Match.Integer
					}));

				let user = Meteor.user();
				if (user && user.roles && user.roles[Roles.GLOBAL_GROUP] && _.contains(user.roles[Roles.GLOBAL_GROUP], Progressor.ROLE_ADMIN)) /*OK*/;
				else if (exercise.author_id === this.userId && exercise.released && exercise.released.requested)
					throw new Meteor.Error('unauthorised', 'Only administrators can edit released exercises.');
				else
					throw new Meteor.Error('unauthorised', 'Only authors and administrators can edit exercises.');

				if (!exercise.author_id)
					exercise.author_id = this.userId;
				exercise.lastEditor_id = this.userId;
				exercise.lastEdited = new Date();

				return Progressor.exercises.upsert(exercise._id, _.omit(exercise, 'category')).insertedId || exercise._id;
			},
			toggleArchiveExercise(exercise, archive) {
				check(exercise, Match.ObjectIncluding({ _id: String }));
				check(archive, Boolean);

				return Progressor.exercises.upsert(exercise._id, { [archive === true ? '$set' : '$unset']: { archived: true } }).rowsAffected;
			},
			deleteExercise(exercise) {
				check(exercise, Match.ObjectIncluding({ _id: String }));

				let user = Meteor.user();
				if (user && user.roles && user.roles[Roles.GLOBAL_GROUP] && _.contains(user.roles[Roles.GLOBAL_GROUP], Progressor.ROLE_ADMIN)) /*OK*/;
				else if (exercise.author_id === this.userId && exercise.released && exercise.released.requested)
					throw new Meteor.Error('unauthorised', 'Only administrators can edit released exercises.');
				else
					throw new Meteor.Error('unauthorised', 'Only authors and administrators can edit exercises.');

				return Progressor.exercises.remove(exercise._id).rowsAffected;
			}
		});

	///////////////////////////
	// HOUSTON CONFIGURATION //
	///////////////////////////

	Houston.add_collection(Meteor.users);
	Houston.add_collection(Meteor.roles);

	Houston.add_collection(Houston._admins);

	function toggleFlag(collection, flag, elementName, setName, unsetName) {
		return function (document) {
			check(document, Match.ObjectIncluding({ _id: String }));

			return Progressor[collection].update(document._id, { [document[flag] !== true ? '$set' : '$unset']: { [flag]: true } }) === 1
				? `${elementName} '${document._id}' successfully ${document[flag] !== true ? setName : unsetName}.`
				: `${elementName} '${document._id}' could NOT successfully be ${document[flag] !== true ? setName : unsetName}!`;
		}
	}

	Houston.methods('exercises', {
		'Archive/Restore': toggleFlag('exercises', 'archived', 'Exercise', 'archived', 'restored'),
		'Release/Hide'(document) {
			check(document, Match.ObjectIncluding({ _id: String }));

			let release = !document.released || !document.released.confirmed;
			let result = release
				? Progressor.exercises.update(document._id, { $set: { released: { requested: document.released && document.released.requested ? document.released.requested : new Date(), confirmed: new Date(), confirmor_id: this.userId } } })
				: Progressor.exercises.update(document._id, { $unset: { 'released.confirmed': null, 'released.confirmor_id': null } });

			return result === 1
				? `Exercise '${document._id}' successfully ${release ? 'released' : 'hidden'}.`
				: `Exercise '${document._id}' could NOT successfully be ${release ? 'released' : 'hidden'}!`;
		}
	});

})();
<|endoftext|>


<commit_before>module.exports = {
  'lazy loading': function (browser) {
    browser
    .url('http://localhost:8080/lazy-loading/')
      .waitForElementVisible('#app', 1000)
      .assert.count('li a', 3)
      .assert.containsText('.view', 'home')

      .click('li:nth-child(2) a')
      .assert.containsText('.view', 'This is Foo!')

      .click('li:nth-child(3) a')
      .assert.containsText('.view', 'This is Bar!')

      .click('li:nth-child(1) a')
      .assert.containsText('.view', 'home')

      // test initial visit
    .url('http://localhost:8080/lazy-loading/foo')
      .waitForElementVisible('#app', 1000)
      .assert.containsText('.view', 'This is Foo!')
      .end()
  }
}
<commit_msg>fix lazy-loading e2e-tests<commit_after>module.exports = {
  'lazy loading': function (browser) {
    browser
    .url('http://localhost:8080/lazy-loading/')
      .waitForElementVisible('#app', 1000)
      .assert.count('li a', 4)
      .assert.containsText('.view', 'home')

      .click('li:nth-child(2) a')
      .assert.containsText('.view', 'This is Foo!')

      .click('li:nth-child(3) a')
      .assert.containsText('.view', 'This is Bar!')

      .click('li:nth-child(1) a')
      .assert.containsText('.view', 'home')

      .click('li:nth-child(4) a')
      .assert.containsText('.view', 'This is Bar!')
      .assert.containsText('.view h3', 'Baz')

      // test initial visit
    .url('http://localhost:8080/lazy-loading/foo')
      .waitForElementVisible('#app', 1000)
      .assert.containsText('.view', 'This is Foo!')

    .url('http://localhost:8080/lazy-loading/bar/baz')
      .waitForElementVisible('#app', 1000)
      .assert.containsText('.view', 'This is Bar!')
      .assert.containsText('.view h3', 'Baz')
      .end()
  }
}
<|endoftext|>


<commit_before>function $(selector) {
  // Fancy library.
}

(function(/*! Stitch !*/) {
  if (!this.require) {
    var modules = {}, cache = {}, require = function(name, root) {
      var path = expand(root, name), module = cache[path], fn;
      if (module) {
        return module.exports;
      } else if (fn = modules[path] || modules[path = expand(path, './index')]) {
        module = {id: path, exports: {}};
        try {
          cache[path] = module;
          fn(module.exports, function(name) {
            return require(name, dirname(path));
          }, module);
          return module.exports;
        } catch (err) {
          delete cache[path];
          throw err;
        }
      } else {
        throw 'module \'' + name + '\' not found';
      }
    }, expand = function(root, name) {
      var results = [], parts, part;
      if (/^\.\.?(\/|$)/.test(name)) {
        parts = [root, name].join('/').split('/');
      } else {
        parts = name.split('/');
      }
      for (var i = 0, length = parts.length; i < length; i++) {
        part = parts[i];
        if (part == '..') {
          results.pop();
        } else if (part != '.' && part != '') {
          results.push(part);
        }
      }
      return results.join('/');
    }, dirname = function(path) {
      return path.split('/').slice(0, -1).join('/');
    };
    this.require = function(name) {
      return require(name, '');
    }
    this.require.define = function(bundle) {
      for (var key in bundle)
        modules[key] = bundle[key];
    };
  }
  return this.require.define;
}).call(this)({"grunt": function(exports, require, module) {/*
 * grunt
 * http://gruntjs.com/
 *
 * Copyright (c) 2013 "Cowboy" Ben Alman
 * Licensed under the MIT license.
 * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
 */

'use strict';

// This seems to be required in Windows (as of Node.js 0.8.7) to ensure that
// stdout/stderr are flushed before the process exits.

// https://gist.github.com/3427148
// https://gist.github.com/3427357

exports.exit = function exit(exitCode) {
  if (process.stdout._pendingWriteReqs || process.stderr._pendingWriteReqs) {
    process.nextTick(function() {
      exit(exitCode);
    });
  } else {
    process.exit(exitCode);
  }
};
}, "rendr/shared/module": function(exports, require, module) {module.exports = {
  method: function() {}
};
}, "test/fixtures/sample/app/app": function(exports, require, module) {var App = module.exports = function App() {};
App.prototype.name = 'sample';
}});
<commit_msg>Update fixure with Windows fix<commit_after>function $(selector) {
  // Fancy library.
}

(function(/*! Stitch !*/) {
  if (!this.require) {
    var modules = {}, cache = {}, require = function(name, root) {
      name = name.replace(/\\\\/g, '/');
      var path = expand(root, name), module = cache[path], fn;
      if (module) {
        return module.exports;
      } else if (fn = modules[path] || modules[path = expand(path, './index')]) {
        module = {id: path, exports: {}};
        try {
          cache[path] = module;
          fn(module.exports, function(name) {
            return require(name, dirname(path));
          }, module);
          return module.exports;
        } catch (err) {
          delete cache[path];
          throw err;
        }
      } else {
        throw 'module \'' + name + '\' not found';
      }
    }, expand = function(root, name) {
      var results = [], parts, part;
      if (/^\.\.?(\/|$)/.test(name)) {
        parts = [root, name].join('/').split('/');
      } else {
        parts = name.split('/');
      }
      for (var i = 0, length = parts.length; i < length; i++) {
        part = parts[i];
        if (part == '..') {
          results.pop();
        } else if (part != '.' && part != '') {
          results.push(part);
        }
      }
      return results.join('/');
    }, dirname = function(path) {
      return path.split('/').slice(0, -1).join('/');
    };
    this.require = function(name) {
      return require(name, '');
    }
    this.require.define = function(bundle) {
      for (var key in bundle)
        modules[key] = bundle[key];
    };
  }
  return this.require.define;
}).call(this)({"grunt": function(exports, require, module) {/*
 * grunt
 * http://gruntjs.com/
 *
 * Copyright (c) 2013 "Cowboy" Ben Alman
 * Licensed under the MIT license.
 * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
 */

'use strict';

// This seems to be required in Windows (as of Node.js 0.8.7) to ensure that
// stdout/stderr are flushed before the process exits.

// https://gist.github.com/3427148
// https://gist.github.com/3427357

exports.exit = function exit(exitCode) {
  if (process.stdout._pendingWriteReqs || process.stderr._pendingWriteReqs) {
    process.nextTick(function() {
      exit(exitCode);
    });
  } else {
    process.exit(exitCode);
  }
};
}, "rendr/shared/module": function(exports, require, module) {module.exports = {
  method: function() {}
};
}, "test/fixtures/sample/app/app": function(exports, require, module) {var App = module.exports = function App() {};
App.prototype.name = 'sample';
}});
<|endoftext|>


<commit_before>/*!

 * maskArea 0.1
 * http://pointslabs.co/
 * MIT licensed
 * Copyright (C) 2016 Sreejith K S, http://pointslabs.co/
 * sreeksleo@gmail.com
 * A Simple Mask Area Plugin.
 * Masking an Image with Another Image.
 *

*/
(function($) {
    var settings ;
    $.fn.maskArea = function( options ) {
        settings = $.extend({
            bgImage:null,
            maskerImage:null,
            width:500,
            height:500,
            maskerWidth:150,
            maskerHeight:150,
            complete : null
        }, options);
        return this.each( function(i) {
            arrangeDiv(this,settings.maskerImage,settings.bgImage);
        });
    };
    function arrangeDiv(_obj,_tImg,_bImg){
        var _div=null;
        var _frame=_obj.id;
        $('#'+_frame).css({
            'position':'relative'
        })
        _div=$("

");
        $('#'+_frame).append(_div);
        $(_obj).find(".img-box-archive").css(
            {
                'width': settings.width + 'px',
                'height': settings.height + 'px'
            });
        /*dimension*/
        $(_obj).find('#imageT').css(
            {
             'height': $(".img-box-archive").height() + "px",
             'width' : $(".img-box-archive").width() + "px"
            });
        $(_obj).find('#imageB').css(
            {
            'height': $(".img-box-archive").height() + "px",
             'width': $(".img-box-archive").width() + "px"
            });
        /*load img*/

        var preLoaderT = $("

");
        $(_obj).find('.imageloader').append(preLoaderT);
        var preLoaderB = $("

");
        $(_obj).find('.imageloader').append(preLoaderB);

        $(_obj).find('#imageB').on('load',function() {

           $(this).closest('div').find('.loadingbarB').remove();
               $(this).removeClass("hiddendiv").addClass("visiblediv");
             }).attr('src', _bImg);

        $(_obj).find('#imageT ').on('load',function() {
             $(this).closest('div').find('.loadingbarT').remove();
             $(this).removeClass("hiddendiv").addClass("visiblediv");
             }).attr('src', _tImg);

          drawRectangle(_obj);
    }

    function drawRectangle(_obj) {
        $(_obj).find('#imageT').addClass('has-mask');
        $(_obj).find('#masker').css({
            position:'absolute',
            width:settings.maskerWidth,
            height:settings.maskerHeight,
            left: ($(_obj).find(".img-box-archive").width() -$(_obj).find('#masker').outerWidth())/2,
            top: ($(_obj).find(".img-box-archive").height() - $(_obj).find('#masker').outerHeight())/2,
            'z-index': 1000
        });
        var imgT=$(_obj).find('#imageT');
        overlayImage(_obj, imgT);
        $(_obj).find('#masker').draggable({
            containment : $(_obj).find(".img-box-archive"),
            drag : function(event, ui) {
                overlayImage(_obj,imgT );
            },
            start : function(e, ui) {
                overlayImage(_obj, imgT);
            },
            stop : function(e, ui) {
                overlayImage(_obj, imgT);
            }
        });
        $(_obj).find('#masker').resizable({
            containment : $(_obj).find(".img-box-archive"),
            handles : 'ne, se, sw, nw',
            start : function(e, ui) {
                overlayImage(_obj, imgT);
            },
            resize : function(e, ui) {
                overlayImage(_obj, imgT);
            },
            stop : function(e, ui) {
                overlayImage(_obj, imgT);
            }
        });
    }
    var t, r, b, l, wid, leftPos, th, rightPos, w;
    function overlayImage(_obj,_imgT) {
        t, r, b, l, wid, leftPos, th, rightPos, w=null ;
        t = $(_obj).find('#masker').position().top+"px";
        l = $(_obj).find('#masker').position().left+"px";
        r = $(_obj).find('#masker').css('right');
        b = $(_obj).find('#masker').css('bottom');
        wid = $(_obj).find('#masker').width();
        leftPos = $(_obj).find('#masker').position().left;
        w = Number(wid + leftPos) + "px";
        th = $(_obj).find('#masker').height();
        rightPos = $(_obj).find('#masker').position().top;
        b =  Number(th + rightPos) + "px";
        $(_obj).find(_imgT).css({
            'clip' : 'rect(' + t + ', ' + w + ', ' + b + ', ' + l + ')',
            'position' : 'absolute',
        });
    }
}(jQuery));

<commit_msg>Delete maskArea.js<commit_after><|endoftext|>


<commit_before>define([
	"jquery"
], function($) {
	var noteToPlaybackRate = [];

	var noteRange = 48;
	var noteRangeHalved = noteRange / 2;

	for (var i = 0; i < noteRange; i++)
		noteToPlaybackRate[i] = Math.pow(2, (i - noteRangeHalved) / 12);

	var SoundOutput = function () {
		this._context = new webkitAudioContext();

		this._gainNode = this._context.createGainNode();
		this._gainNode.connect(this._context.destination);

		this._deferredURLs = {};
	};

	SoundOutput.prototype.getVolume = function () {
		return this._gainNode.gain.value;
	};

	SoundOutput.prototype.setVolume = function (volume) {
		this._gainNode.gain.value = volume;
	};

	SoundOutput.prototype.playSoundObject = function (soundObject, playbackRate, delay, callback) {
		var buffer = soundObject._buffer;
		var delay = delay || 0;
		var playbackRate = playbackRate || 1;

		var bufferSource = this._context.createBufferSource();
		bufferSource.buffer = buffer;
		bufferSource.connect(this._gainNode);
		bufferSource.playbackRate.value = playbackRate;
		bufferSource.noteOn(delay ? this._context.currentTime + delay : 0);

		if (callback) {
			// calculate total time in seconds.
			var time = delay + (buffer.duration * playbackRate);
			// convert to milliseconds for setTimeout.
			setTimeout(callback, time * 1000);
		}
	};

	SoundOutput.prototype.freeSoundAttributes = function (soundAttributes) {
		var existing = this._deferredURLs[soundAttributes.sound_url];

		if (existing) {
			if (existing.count === 1)
				delete this._deferredURLs[soundAttributes.sound_url];
			else
				existing.count--;
		}
	};

	SoundOutput.prototype.loadSoundAttributes = function (soundAttributes) {
		var existing = this._deferredURLs[soundAttributes.sound_url];

		if (existing) {
			existing.count++;

			return existing.promise;
		} else {
			var deferred = new $.Deferred();

			deferred.fail(function () {
				this.freeSound(soundAttributes);
			}.bind(this));

			var request = new XMLHttpRequest();
			request.open("GET", soundAttributes.sound_url, true);
			request.responseType = "arraybuffer";
			request.onloadend = function (event) {
				if (request.status === 200) {
					this._context.decodeAudioData(request.response,
						function (buffer) {
							deferred.resolve({
								_buffer: buffer,
								soundAttributes: soundAttributes
							});
						},
						function () {
							deferred.reject('decode');
						});
				} else {
					deferred.reject('request', request);
				}
			}.bind(this);

			request.send();

			var promise = deferred.promise();

			this._deferredURLs[soundAttributes.sound_url] = { count: 1, promise: promise };

			return promise;
		}
	};

	return SoundOutput;
});
<commit_msg>SoundOutput now extends Backbone.Event.<commit_after>define([
	"use!backbone",
	"jquery"
], function(Backbone, $) {
	var noteToPlaybackRate = [];

	var noteRange = 48;
	var noteRangeHalved = noteRange / 2;

	for (var i = 0; i < noteRange; i++)
		noteToPlaybackRate[i] = Math.pow(2, (i - noteRangeHalved) / 12);

	var SoundOutput = function () {
		this._context = new webkitAudioContext();

		this._gainNode = this._context.createGainNode();
		this._gainNode.connect(this._context.destination);

		this._deferredURLs = {};
	};

	_.extend(SoundOutput.prototype, Backbone.Events, {
		getVolume: function () {
			return this._gainNode.gain.value;
		},

		setVolume: function (volume) {
			this._gainNode.gain.value = volume;

			this.trigger("volume", volume);
		},

		playSoundObject: function (soundObject, playbackRate, delay, callback) {
			var buffer = soundObject._buffer;
			var delay = delay || 0;
			var playbackRate = playbackRate || 1;

			var bufferSource = this._context.createBufferSource();
			bufferSource.buffer = buffer;
			bufferSource.connect(this._gainNode);
			bufferSource.playbackRate.value = playbackRate;
			bufferSource.noteOn(delay ? this._context.currentTime + delay : 0);

			if (callback) {
				// calculate total time in seconds.
				var time = delay + (buffer.duration * playbackRate);
				// convert to milliseconds for setTimeout.
				setTimeout(callback, time * 1000);
			}
		},

		freeSoundAttributes: function (soundAttributes) {
			var existing = this._deferredURLs[soundAttributes.sound_url];

			if (existing) {
				if (existing.count === 1)
					delete this._deferredURLs[soundAttributes.sound_url];
				else
					existing.count--;
			}
		},

		loadSoundAttributes: function (soundAttributes) {
			var existing = this._deferredURLs[soundAttributes.sound_url];

			if (existing) {
				existing.count++;

				return existing.promise;
			} else {
				var deferred = new $.Deferred();

				deferred.fail(function () {
					this.freeSound(soundAttributes);
				}.bind(this));

				var request = new XMLHttpRequest();
				request.open("GET", soundAttributes.sound_url, true);
				request.responseType = "arraybuffer";
				request.onloadend = function (event) {
					if (request.status === 200) {
						this._context.decodeAudioData(request.response,
							function (buffer) {
								deferred.resolve({
									_buffer: buffer,
									soundAttributes: soundAttributes
								});
							},
							function () {
								deferred.reject('decode');
							});
					} else {
						deferred.reject('request', request);
					}
				}.bind(this);

				request.send();

				var promise = deferred.promise();

				this._deferredURLs[soundAttributes.sound_url] = { count: 1, promise: promise };

				return promise;
			}
		}
	});

	return SoundOutput;
});
<|endoftext|>


<commit_before>
/**
 * the user has some base layers saved
 */
cdb.admin.UserLayers = cdb.admin.Layers.extend({
  url: function() {
    return '/api/v1/users/' +  this.user.id + '/layers';
  }
});

cdb.admin.User = cdb.core.Model.extend({

  urlRoot: '/api/v1/users',

  defaults: {
    avatar_url: '',
    username:   ''
  },

  initialize: function() {
    if (this.get("get_layers")) {
      this.layers = new cdb.admin.UserLayers();
      this.layers.user = this;
      this._fetchLayers();
    }

    if (this.get('organization')) {
      this.organization = new cdb.admin.Organization(this.get('organization'));
    }

  },

  isInsideOrg: function() {
    if (this.organization) {
      return this.organization.users.length > 1;
    }
    return false;
  },

  isOrgAdmin: function() {
    if (this.organization) {
      return this.organization.owner.get('id') === this.get('id')
    }
    return false;
  },

  renderData: function() {
    return {
      username: this.get('username'),
      avatar_url: this.get('avatar_url')
    }

  },

  _fetchLayers: function() {
    this.layers.fetch({ add: true });
  }

});

<commit_msg>added render data method for user<commit_after>
/**
 * the user has some base layers saved
 */
cdb.admin.UserLayers = cdb.admin.Layers.extend({
  url: function() {
    return '/api/v1/users/' +  this.user.id + '/layers';
  }
});

cdb.admin.User = cdb.core.Model.extend({

  urlRoot: '/api/v1/users',

  defaults: {
    avatar_url: '',
    username:   ''
  },

  initialize: function() {
    if (this.get("get_layers")) {
      this.layers = new cdb.admin.UserLayers();
      this.layers.user = this;
      this._fetchLayers();
    }

    if (this.get('organization')) {
      this.organization = new cdb.admin.Organization(this.get('organization'));
    }

  },

  isInsideOrg: function() {
    if (this.organization) {
      return this.organization.users.length > 1;
    }
    return false;
  },

  isOrgAdmin: function() {
    if (this.organization) {
      return this.organization.owner.get('id') === this.get('id')
    }
    return false;
  },

  renderData: function(currentUser) {
    var name = this.get('username');
    if (currentUser && currentUser.id === this.id) {
      name = _t('You');
    }
    return {
      username: name,
      avatar_url: this.get('avatar_url')
    }

  },

  _fetchLayers: function() {
    this.layers.fetch({ add: true });
  }

});

<|endoftext|>


<commit_before>module.exports = {

  'googleAuth' : {
    'clientID' : process.env.clientID || 'nothing',
    'clientSecret' : process.env.clientSecret || 'nothing',
    'callbackURL' : process.env.callbackURL || 'http://localhost:3000/auth/google/callback'
  }

};<commit_msg>removed auth file from cache<commit_after><|endoftext|>


<commit_before>function drawNlogN(){
  var numPoints = 20,
      points = _.sortBy(uniformRandom(numPoints), f('x'))

  points.forEach(function(d, i){ d.i = i })

  var svg = d3.select('#nlogn').html('')
    .append('svg')
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
    .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")")

  var lineG = svg.append('g')

  var circles = svg.selectAll('circle')
      .data(points).enter()
    .append('circle').classed('point', true)
      .attr('r', 3)
      .attr('cx', f('x'))
      .attr('cy', f('y'))
      .each(function(d){ d.circle = d3.select(this) })
      .on('mouseover', function(d, i){
        if (i == activeI) iteratePoint()
      })

  lineG.append('path').classed('xorder', true)
      .attr('d', 'M' + points.map(f('p')).join('L'))

  var activePoints = lineG.append('path').classed('cur-hull', true)

  var topPoints = [points[0], points[1]]
  var curI = 2
  var lookingBack = false
  var activeI = curI

  function iteratePoint(){
    if (curI > points.length  - 1) return

    var curPoint = points[curI]

    if (!lookingBack){
      lookingBack = true
      activeI = _.last(topPoints).i
    } else{

      var a = topPoints[topPoints.length - 2]
      var b = topPoints[topPoints.length - 1]
      var keep = a ? !lessThan180(a, b, curPoint) : true

      if (!keep){
        topPoints.pop()
        activeI = _.last(topPoints).i
      } else{
        activeI = curI + 1
      }

      b.circle.transition()
          .style('fill', keep ? 'green' : 'steelblue')
          .style('fill-opacity', .7)
          .attr('r', 10)

      console.log(topPoints.map(f('i')))
      topPoints.push(curPoint)
      activePoints.attr('d', 'M' + topPoints.map(f('p')).join('L'))
      curI++
    }

    circles.classed('next-point', function(d, i){
      return i === activeI
    })
  }

  circles.classed('next-point', function(d, i){
    return i === curI
  })

  // svg.append('rect')
  //     .attr({width: width, height: height})
  //     .on('mousemove', function(){
  //       var p3 = d3.mouse(this)
  //       var p3 = {x: p3[0], y: p3[1]}
  //       mPath.attr('d', ['M', p2.x, ',', p2.y, 'L', p3.x, ',', p3.y].join(''))
  //       //console.log(calcAngle(p1, p2, p3))
  //       ang = isLessThan180(p1, p2, p3)
  //       aText.text(ang)
  //     })
  // var p1 = {x: 200, y: 200}
  // var p2 = {x: 300, y: 200}
  // svg.append('path').classed('mline', true)
  //     .attr('d', ['M', p1.x, ',', p1.y, 'L', p2.x, ',', p2.y].join(''))

  // var mPath = svg.append('path').classed('mline', true)
  // var aText = svg.append('text').style('fill', 'white')
  //     .attr({dy: '3em', dx: '3em'})

  svg.append('text').classed('reset-button', true)
      .attr({dy: '1em', dx: '.2em'})
      .on('click', drawNlogN)
      .text('↻')
}
drawNlogN()<commit_msg>adding logging<commit_after>function drawNlogN(){
  var numPoints = 20,
      points = _.sortBy(uniformRandom(numPoints), f('x'))

  points.forEach(function(d, i){ d.i = i })

  var svg = d3.select('#nlogn').html('')
    .append('svg')
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
    .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")")

  var lineG = svg.append('g')

  var circles = svg.selectAll('circle')
      .data(points).enter()
    .append('circle').classed('point', true)
      .attr('r', 3)
      .attr('cx', f('x'))
      .attr('cy', f('y'))
      .each(function(d){ d.circle = d3.select(this) })
      .on('mouseover', function(d, i){
        if (i == activeI) iteratePoint()
      })

  lineG.append('path').classed('xorder', true)
      .attr('d', 'M' + points.map(f('p')).join('L'))

  var activePoints = lineG.append('path').classed('cur-hull', true)

  var topPoints = [points[0], points[1]]
  var curI = 2
  var lookingBack = false
  var activeI = curI

  function iteratePoint(){
    if (curI > points.length  - 1) return

    var curPoint = points[curI]

    if (!lookingBack){
      lookingBack = true
      activeI = _.last(topPoints).i
    } else{

      var a = topPoints[topPoints.length - 2]
      var b = topPoints[topPoints.length - 1]
      var keep = a ? !lessThan180(a, b, curPoint) : true

      if (!keep){
        topPoints.pop()
        activeI = _.last(topPoints).i
      } else{
        activeI = curI + 1
      }

      b.circle.transition()
          .style('fill', keep ? 'green' : 'steelblue')
          .style('fill-opacity', .7)
          .attr('r', 10)

      console.log(topPoints.map(f('i')).join())
      topPoints.push(curPoint)
      activePoints.attr('d', 'M' + topPoints.map(f('p')).join('L'))
      curI++
    }
    console.log(activeI)

    circles.classed('next-point', function(d, i){
      return i === activeI
    })
  }

  circles.classed('next-point', function(d, i){
    return i === curI
  })

  // svg.append('rect')
  //     .attr({width: width, height: height})
  //     .on('mousemove', function(){
  //       var p3 = d3.mouse(this)
  //       var p3 = {x: p3[0], y: p3[1]}
  //       mPath.attr('d', ['M', p2.x, ',', p2.y, 'L', p3.x, ',', p3.y].join(''))
  //       //console.log(calcAngle(p1, p2, p3))
  //       ang = isLessThan180(p1, p2, p3)
  //       aText.text(ang)
  //     })
  // var p1 = {x: 200, y: 200}
  // var p2 = {x: 300, y: 200}
  // svg.append('path').classed('mline', true)
  //     .attr('d', ['M', p1.x, ',', p1.y, 'L', p2.x, ',', p2.y].join(''))

  // var mPath = svg.append('path').classed('mline', true)
  // var aText = svg.append('text').style('fill', 'white')
  //     .attr({dy: '3em', dx: '3em'})

  svg.append('text').classed('reset-button', true)
      .attr({dy: '1em', dx: '.2em'})
      .on('click', drawNlogN)
      .text('↻')
}
drawNlogN()<|endoftext|>


<commit_before>/*jslint browser: true, devel: true, nomen: true, plusplus: true, vars: true, white: true */
/*global angular*/

angular.module("OnlineStore")

.controller("HomeCtrl",
            ["$scope", "PRODUCT_CATEGORIES",
            function($scope, PRODUCT_CATEGORIES)
            {
                $scope.categories = PRODUCT_CATEGORIES;
            }
]);
<commit_msg>Code legibility improved<commit_after>/*jslint browser: true, devel: true, nomen: true, plusplus: true, vars: true, white: true */
/*global angular*/

angular.module("OnlineStore")

.controller("HomeCtrl", ["$scope", "PRODUCT_CATEGORIES", function($scope, PRODUCT_CATEGORIES)
{
    $scope.categories = PRODUCT_CATEGORIES;
}]);
<|endoftext|>


<commit_before>var chai = require('chai');
var kerouac = require('kerouac')
var factory = require('../../../app/handlers/feed/rdf');

describe('handlers/feed/rdf', function() {

  it('should export factory function', function() {
    expect(factory).to.be.a('function');
  });

  it('should be annotated', function() {
    expect(factory['@implements']).to.be.undefined;
    expect(factory['@singleton']).to.be.undefined;
  });

  describe('handler', function() {
    var site = kerouac();

    describe('with one post', function() {
      var page, err;

      before(function(done) {
        chai.kerouac.handler(factory())
          .page(function(page) {
            page.site = site;
            page.site.pages = [
              { url: '/2003/12/13/hello-world/',
                canonicalURL: 'http://www.example.com/blog/2003/12/13/hello-world/',
                meta: { post: true },
                locals: {
                  title: 'Hello, World',
                  publishedAt: new Date('2003-12-13T18:30:02Z'),
                }
              }
            ];
          })
          .end(function(p) {
            page = p;
            done();
          })
          .dispatch();
      });

      it('should write feed', function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<rdf:RDF xmlns="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">',
          '  <channel/>',
          '  <item>',
          '    <title>Hello, World</title>',
          '    <link>http://www.example.com/blog/2003/12/13/hello-world/</link>',
          '    <dc:date>2003-12-13T18:30:02Z</dc:date>',
          '  </item>',
          '</rdf:RDF>',
          ''
        ].join("\n");

        expect(page.body).to.equal(expected);
      });
    }); // with one post

  }); // handler

});
<commit_msg>Update tests.<commit_after>var chai = require('chai');
var kerouac = require('kerouac')
var factory = require('../../../app/handlers/feed/rdf');

describe('handlers/feed/rdf', function() {

  it('should export factory function', function() {
    expect(factory).to.be.a('function');
  });

  it('should be annotated', function() {
    expect(factory['@implements']).to.be.undefined;
    expect(factory['@singleton']).to.be.undefined;
  });

  describe('handler', function() {
    var site = kerouac();

    describe('with one post', function() {
      var page, err;

      before(function(done) {
        chai.kerouac.handler(factory())
          .page(function(page) {
            page.canonicalURL = 'http://www.example.com/blog/feed.rdf';

            page.site = site;
            page.site.pages = [
              { url: '/2003/12/13/hello-world/',
                canonicalURL: 'http://www.example.com/blog/2003/12/13/hello-world/',
                meta: { post: true },
                locals: {
                  title: 'Hello, World',
                  publishedAt: new Date('2003-12-13T18:30:02Z'),
                }
              }
            ];
          })
          .end(function(p) {
            page = p;
            done();
          })
          .dispatch();
      });

      it('should write feed', function() {
        var expected = [
          '<?xml version="1.0" encoding="UTF-8"?>',
          '<rdf:RDF xmlns="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">',
          '  <channel/>',
          '  <item>',
          '    <title>Hello, World</title>',
          '    <link>http://www.example.com/blog/2003/12/13/hello-world/</link>',
          '    <dc:date>2003-12-13T18:30:02Z</dc:date>',
          '  </item>',
          '</rdf:RDF>',
          ''
        ].join("\n");

        expect(page.body).to.equal(expected);
      });
    }); // with one post

  }); // handler

});
<|endoftext|>


<commit_before>'use strict';
var angular = require('angular');

angular.module('wfm-mobile.workflow', [
  'ui.router',
, 'wfm.core.mediator'
])

.run(function($state, mediator) {
  mediator.subscribe('workorder:selected', function(workorder) {
    $state.go('workflow.workorder', {
      workorderId: workorder.id
    });
  });
})

.constant('steps', [
    {code: 'begin-workflow', name: 'Begin Workflow', template: 'wfm-template/workorder-list-item.tpl.html'},
    {code: 'risk-assessment', name: 'Risk Assessment', template: 'app/workflow/risk-assessment.tpl.html'},
    {code: 'vehicle-inspection', name: 'Vehicle Inspection', template: 'app/workflow/vehicle-inspection.tpl.html'},
    {code: 'workflow-complete', name: 'Workflow Complete', template: 'wfm-template/workorder-list-item.tpl.html'}
  ]
)

.config(function($stateProvider) {
  $stateProvider
    .state('workflow', {
      url: '/workflow',
      abstract: true,
      templateUrl: 'app/workflow/workflow.tpl.html',
      controller: 'WorkflowController as workflow'
    })
    .state('workflow.workorder', {
      url: '/workorder/:workorderId',
      views: {
        'tab-workorder': {
          templateUrl: 'app/workflow/workorder.tpl.html',
          controller: 'WorkflowStepController as ctrl',
        }
      }
    })
})

.controller('WorkflowController', function($stateParams) {
  var self = this;

  self.tabGroup = 0;

  self.toggleMore = function() {
    self.tabGroup = self.tabGroup === 0 ? 1 : 0;
  }
})

.controller('WorkflowStepController', function($stateParams, $templateRequest, $scope, $compile, mediator, steps) {
  var self = this;

  mediator.publish('workorder:load', $stateParams.workorderId);
  mediator.once('workorder:loaded', function(workorder) {
    self.workorder = workorder;
  });

  self.mediator = mediator;

  self.steps = steps;

  self.stepIndex = 0;
  self.stepCurrent = steps[0];

  self.next = function() {
    if (self.stepIndex < self.steps.length -1) {
      self.stepIndex++;
    };
    self.stepCurrent = self.steps[self.stepIndex];
  }
})

.directive('workflowProgress', function($timeout) {
  var draw = function(scope, element, attrs) {
    window.requestAnimationFrame(function() {
      var div = element[0].querySelector('.progtrckr');
      if (div) {
        while (div.firstChild) {
          angular.element(div.firstChild).remove();
        }
        div = angular.element(div);
      } else {
        div = angular.element('
');
        element.append(div);
      }
      var completed = false;
      scope.steps.forEach(function(_step) {
        var cssClass;
        if (_step.code === scope.step.code) {
          cssClass = 'progtrckr-current';
          completed = true;
        } else {
          cssClass = completed ? 'progtrckr-todo' : 'progtrckr-done'
        }
        div.append('
' + _step.name + '
')
      })
    });
  };

  return {
    restrict: 'E'
  , scope: {
      step: '=',
      steps: '='
    }
  , link: function (scope, element, attrs) {
      scope.$watch('step', function(step) {
        draw(scope, element, attrs);
      });
    }
  , controller: function() {
      var self = this;
      self.selectWorkorder = function(event, workorder) {
        mediator.publish('workorder:selected', workorder);
        event.preventDefault();
      }
    }
  , controllerAs: 'ctrl'
  };
})

.directive('workflowStep', function($templateRequest, $compile, mediator) {
  return {
    restrict: 'E'
  , scope: {
      step: '=',
      workorder: '='
    }
  , link: function (scope, element, attrs) {
      scope.$watch('step', function(step) {
        console.log('requesting template', scope.step )
        if (scope.step) {
          $templateRequest(scope.step.template).then(function(template) {
            window.requestAnimationFrame(function() {
              element.html(template);
              $compile(element.contents())(scope);
            });
          });

        }
      });
    }
  , controller: function() {
      var self = this;
      self.mediator = mediator;
      self.selectWorkorder = function(event, workorder) {
        mediator.publish('workorder:selected', workorder);
        event.preventDefault();
      }
    }
  , controllerAs: 'ctrl'
  };
})
;

module.exports = 'wfm-mobile.workflow';
<commit_msg>Changed the workflow step directive to use allow using a template string directly.  This will make it easier to consume wfm templates<commit_after>'use strict';
var angular = require('angular');

angular.module('wfm-mobile.workflow', [
  'ui.router',
, 'wfm.core.mediator'
])

.run(function($state, mediator) {
  mediator.subscribe('workorder:selected', function(workorder) {
    $state.go('workflow.workorder', {
      workorderId: workorder.id
    });
  });
})

.constant('steps', [
    {code: 'begin-workflow', name: 'Begin Workflow', template: '<workorder-list-item workorder="workorder"></workorder-view-item>'},
    {code: 'risk-assessment', name: 'Risk Assessment', templatePath: 'app/workflow/risk-assessment.tpl.html'},
    {code: 'vehicle-inspection', name: 'Vehicle Inspection', templatePath: 'app/workflow/vehicle-inspection.tpl.html'},
    {code: 'workflow-complete', name: 'Workflow Complete', templatePath: 'wfm-template/workorder-list-item.tpl.html'}
  ]
)

.config(function($stateProvider) {
  $stateProvider
    .state('workflow', {
      url: '/workflow',
      abstract: true,
      templateUrl: 'app/workflow/workflow.tpl.html',
      controller: 'WorkflowController as workflow'
    })
    .state('workflow.workorder', {
      url: '/workorder/:workorderId',
      views: {
        'tab-workorder': {
          templateUrl: 'app/workflow/workorder.tpl.html',
          controller: 'WorkflowStepController as ctrl',
        }
      }
    })
})

.controller('WorkflowController', function($stateParams) {
  var self = this;

  self.tabGroup = 0;

  self.toggleMore = function() {
    self.tabGroup = self.tabGroup === 0 ? 1 : 0;
  }
})

.controller('WorkflowStepController', function($stateParams, $templateRequest, $scope, $compile, mediator, steps) {
  var self = this;

  mediator.publish('workorder:load', $stateParams.workorderId);
  mediator.once('workorder:loaded', function(workorder) {
    self.workorder = workorder;
  });

  self.mediator = mediator;

  self.steps = steps;

  self.stepIndex = 0;
  self.stepCurrent = steps[0];

  self.next = function() {
    if (self.stepIndex < self.steps.length -1) {
      self.stepIndex++;
    };
    self.stepCurrent = self.steps[self.stepIndex];
  }
})

.directive('workflowProgress', function($timeout) {
  var draw = function(scope, element, attrs) {
    window.requestAnimationFrame(function() {
      var div = element[0].querySelector('.progtrckr');
      if (div) {
        while (div.firstChild) {
          angular.element(div.firstChild).remove();
        }
        div = angular.element(div);
      } else {
        div = angular.element('
');
        element.append(div);
      }
      var completed = false;
      scope.steps.forEach(function(_step) {
        var cssClass;
        if (_step.code === scope.step.code) {
          cssClass = 'progtrckr-current';
          completed = true;
        } else {
          cssClass = completed ? 'progtrckr-todo' : 'progtrckr-done'
        }
        div.append('
' + _step.name + '
')
      })
    });
  };

  return {
    restrict: 'E'
  , scope: {
      step: '=',
      steps: '='
    }
  , link: function (scope, element, attrs) {
      scope.$watch('step', function(step) {
        draw(scope, element, attrs);
      });
    }
  , controller: function() {
      var self = this;
      self.selectWorkorder = function(event, workorder) {
        mediator.publish('workorder:selected', workorder);
        event.preventDefault();
      }
    }
  , controllerAs: 'ctrl'
  };
})

.directive('workflowStep', function($templateRequest, $compile, mediator) {
  return {
    restrict: 'E'
  , scope: {
      step: '=' // { ..., template: "an html template to use", templatePath: "a template path to load"}
    , workorder: '='
    }
  , link: function (scope, element, attrs) {
      scope.$watch('step', function(step) {
        if (scope.step) {
          if (scope.step.templatePath) {
            $templateRequest(scope.step.templatePath).then(function(template) {
              window.requestAnimationFrame(function() {
                element.html(template);
                $compile(element.contents())(scope);
              });
            });
          } else {
            window.requestAnimationFrame(function() {
              element.html(scope.step.template);
              $compile(element.contents())(scope);
            });
          };
        };
      });
    }
  , controller: function() {
      var self = this;
      self.mediator = mediator;
    }
  , controllerAs: 'ctrl'
  };
})
;

module.exports = 'wfm-mobile.workflow';
<|endoftext|>


<commit_before>//= require sweet-alert
(function( $ ) {
  var sweetAlertConfirm = function(event) {
    swalDefaultOptions = {
      title: 'Are you sure?',
      type: 'warning',
      showCancelButton: true,
      confirmButtonColor: "#DD6B55",
      confirmButtonText: "Ok"

    }

    //this.click(function(event) {
      $linkToVerify = $(this)
      var swalOptions = swalDefaultOptions;
      var optionKeys = [
                          'confirm',
                          'text',
                          'sweetAlertType',
                          'showCancelButton',
                          'confirmButtonColor',
                          'cancelButtonColor',
                          'confirmButtonText',
                          'cancelButtonText',
                          'closeOnConfirm',
                          'imageUrl',
                          'allowOutsideClick',
                          'remote',
                          'method'
                        ]

      $.each($linkToVerify.data(), function(key, val){
        if ($.inArray(key, optionKeys) >= 0) {
          swalOptions[key] = val
          if (key == 'sweetAlertType') {
            swalOptions['type'] = val;
          }

        }
      })

      message = $linkToVerify.attr('data-sweet-alert-confirm')
      swalOptions['title'] = message
      swal(swalOptions, function(r){
        if (swalOptions['remote'] === true) {
          if (r === false) {
            return false;
          } else {
            $.rails.handleRemote($linkToVerify)
          }
        }
        else if(swalOptions[ 'method' ] !== undefined) {
          if (r === false) {
            return false;
          } else {
            $.rails.handleMethod($linkToVerify);
          }
        }
        else {
          //[FIXME]Check this im not sure about this
          if (r === false) {
            return false;
          } else {
            if($linkToVerify.is('input')){
              var name = $linkToVerify.attr('name'),
              data = name ? {name: name, value:$linkToVerify.val()} : null;
              $linkToVerify.closest('form').data('ujs:submit-button', data);
              $linkToVerify.closest('form').submit();
            }
            else {
              window.location.href = $linkToVerify.attr('href');
            }

          }
        }
      });

      return false;
    //});
    //return this;
  }
  $(document).ready(function(){
    //$("a[data-sweet-alert-confirm]").sweetAlertConfirm();
    $('[data-sweet-alert-confirm]').on('click', sweetAlertConfirm)
  });

  $(document).on('page:change', function() {
    $('a[data-sweet-alert-confirm]').on('click', sweetAlertConfirm)
  });

})( jQuery );
<commit_msg>on ajaxComplete<commit_after>//= require sweet-alert
(function( $ ) {
  var sweetAlertConfirm = function(event) {
    swalDefaultOptions = {
      title: 'Are you sure?',
      type: 'warning',
      showCancelButton: true,
      confirmButtonColor: "#DD6B55",
      confirmButtonText: "Ok"

    }

    //this.click(function(event) {
      $linkToVerify = $(this)
      var swalOptions = swalDefaultOptions;
      var optionKeys = [
                          'confirm',
                          'text',
                          'sweetAlertType',
                          'showCancelButton',
                          'confirmButtonColor',
                          'cancelButtonColor',
                          'confirmButtonText',
                          'cancelButtonText',
                          'closeOnConfirm',
                          'imageUrl',
                          'allowOutsideClick',
                          'remote',
                          'method'
                        ]

      $.each($linkToVerify.data(), function(key, val){
        if ($.inArray(key, optionKeys) >= 0) {
          swalOptions[key] = val
          if (key == 'sweetAlertType') {
            swalOptions['type'] = val;
          }

        }
      })

      message = $linkToVerify.attr('data-sweet-alert-confirm')
      swalOptions['title'] = message
      swal(swalOptions, function(r){
        if (swalOptions['remote'] === true) {
          if (r === false) {
            return false;
          } else {
            $.rails.handleRemote($linkToVerify)
          }
        }
        else if(swalOptions[ 'method' ] !== undefined) {
          if (r === false) {
            return false;
          } else {
            $.rails.handleMethod($linkToVerify);
          }
        }
        else {
          //[FIXME]Check this im not sure about this
          if (r === false) {
            return false;
          } else {
            if($linkToVerify.is('input')){
              var name = $linkToVerify.attr('name'),
              data = name ? {name: name, value:$linkToVerify.val()} : null;
              $linkToVerify.closest('form').data('ujs:submit-button', data);
              $linkToVerify.closest('form').submit();
            }
            else {
              window.location.href = $linkToVerify.attr('href');
            }

          }
        }
      });

      return false;
    //});
    //return this;
  }

  $(document).on('ready page:change ajaxComplete', function() {
    $('[data-sweet-alert-confirm]').on('click', sweetAlertConfirm)
  });

})( jQuery );
<|endoftext|>


<commit_before>
DnD.Draggable2 = Ember.Mixin.create({
  classNameBindings: 'draggable dragged'.w(),

  init: function() {
    this._super();
    this.set('dragged', false);
  },

  draggable: function () {
    if (this.get('canDrag')) {
      return 'true';
    } else {
      return 'false';
    }
  }.property('canDrag'),

  mouseDown: function (event) {
    if (this.get('canDrag')) {
      var backdrop = Ember.$('

');
      backdrop.prependTo(this.$());
      backdrop.css({
        position: 'fixed',
        top: 0,
        bottom: 0,
        left: 0,
        right: 0,
        zIndex: 10000
      });

      this.setProperties({
        dragged: true
      });
      Ember.tryInvoke(this, 'click', [event]);

      var currentCoordinates = DnD.portableCoordinates(event),
          x = currentCoordinates.x,
          y = currentCoordinates.y,
          deltaX = 0,
          deltaY = 0;

      this.set('_dragMeta', Ember.Object.create({
        fromX: x,
        fromY: y,
        deltaX: deltaX,
        deltaY: deltaY,
        zIndex: this.$().css('z-index'),
        backdrop: backdrop
      }));
      this._sendDragEvent('dragBegin', x, y);

      event.preventDefault();
      event.stopPropagation();
      return false;
    }
  },
  mouseMove: function (event) {
    if (this.get('dragged')) {
      if (event.which === 0) {
        this.set('dragged', false);
      } else {
        var currentCoordinates = DnD.portableCoordinates(event),
            dragMeta = this.get('_dragMeta'),
            x = currentCoordinates.x - dragMeta.get('deltaX'),
            y = currentCoordinates.y - dragMeta.get('deltaY');

        this._sendDragEvent('dragMove', x, y);
      }

      event.preventDefault();
      event.stopPropagation();
      return false;
    }
  },
  mouseUp: function (event) {
    if (this.get('dragged')) {
      var dragMeta = this.get('_dragMeta');

      this.set('dragged', false);
      this.$().css('z-index', dragMeta.get('zIndex'));
      dragMeta.get('backdrop').remove();

      var currentCoordinates = DnD.portableCoordinates(event),
          x = currentCoordinates.x - dragMeta.get('deltaX'),
          y = currentCoordinates.y - dragMeta.get('deltaY');

      this._sendDragEvent('dragEnd', x, y);
      this.set('_dragMeta', null);

      event.preventDefault();
      event.stopPropagation();
      return false;
    }
  },

  // touchStart: function (event) {
  //   var currentCoordinates = DnD.portableCoordinates(event);
  //   if (this.get('canDrag')) {
  //     // Drag object.
  //     var object = this.dragObject(currentCoordinates.x, currentCoordinates.y);
  //     // Set last dragged from in DnD since we won't have dataTransfer for touch events.
  //     DnD.set('lastDraggedFrom', '%@:%@'.fmt(currentCoordinates.x, currentCoordinates.y));
  //     event.stopPropagation();
  //   } else {
  //     event.preventDefault();
  //     return false;
  //   }
  // },

  _sendDragEvent: function (name, x, y) {
    var dragMeta = this.get('_dragMeta'),
        fromX = dragMeta.get('fromX'),
        fromY = dragMeta.get('fromY');

    dragMeta.setProperties({
      x: x,
      y: y
    });

    Ember.tryInvoke(this, name, [{
      x: x,
      y: y,
      fromX: fromX,
      fromY: fromY,
      dx: x - fromX,
      dy: y - fromY
    }]);
  },

  _dragChanged: function () {
    this.$().css('z-index', this.get('dragged') ? 10001 : undefined);
  }.observes('dragged'),

  /** To be implemented by draggable */
  canDrag: true,

  /** To be implemented by draggable */
  dragBegin: Ember.K,
  dragMove: Ember.K,
  dragEnd: Ember.K
});
<commit_msg>Allow conditional post-drag event propagation<commit_after>
DnD.Draggable2 = Ember.Mixin.create({
  classNameBindings: 'draggable dragged'.w(),

  init: function() {
    this._super();
    this.set('dragged', false);
  },

  draggable: function () {
    if (this.get('canDrag')) {
      return 'true';
    } else {
      return 'false';
    }
  }.property('canDrag'),

  mouseDown: function (event) {
    if (this.get('canDrag')) {
      var backdrop = Ember.$('

');
      backdrop.prependTo(this.$());
      backdrop.css({
        position: 'fixed',
        top: 0,
        bottom: 0,
        left: 0,
        right: 0,
        zIndex: 10000
      });

      this.setProperties({
        dragged: true
      });
      Ember.tryInvoke(this, 'click', [event]);

      var currentCoordinates = DnD.portableCoordinates(event),
          x = currentCoordinates.x,
          y = currentCoordinates.y,
          deltaX = 0,
          deltaY = 0;

      this.set('_dragMeta', Ember.Object.create({
        fromX: x,
        fromY: y,
        deltaX: deltaX,
        deltaY: deltaY,
        zIndex: this.$().css('z-index'),
        backdrop: backdrop
      }));
      var consume = this._sendDragEvent('dragBegin', x, y);

      if (consume) {
        event.preventDefault();
        event.stopPropagation();
        return false;
      }
    }
  },
  mouseMove: function (event) {
    if (this.get('dragged')) {
      if (event.which === 0) {
        this.set('dragged', false);
      } else {
        var currentCoordinates = DnD.portableCoordinates(event),
            dragMeta = this.get('_dragMeta'),
            x = currentCoordinates.x - dragMeta.get('deltaX'),
            y = currentCoordinates.y - dragMeta.get('deltaY');

        var consume = this._sendDragEvent('dragMove', x, y);

        if (consume) {
          event.preventDefault();
          event.stopPropagation();
          return false;
        }
      }
    }
  },
  mouseUp: function (event) {
    if (this.get('dragged')) {
      var dragMeta = this.get('_dragMeta');

      this.set('dragged', false);
      this.$().css('z-index', dragMeta.get('zIndex'));
      dragMeta.get('backdrop').remove();

      var currentCoordinates = DnD.portableCoordinates(event),
          x = currentCoordinates.x - dragMeta.get('deltaX'),
          y = currentCoordinates.y - dragMeta.get('deltaY');

      var consume = this._sendDragEvent('dragEnd', x, y);
      this.set('_dragMeta', null);

      if (consume) {
        event.preventDefault();
        event.stopPropagation();
        return false;
      }
    }
  },

  // touchStart: function (event) {
  //   var currentCoordinates = DnD.portableCoordinates(event);
  //   if (this.get('canDrag')) {
  //     // Drag object.
  //     var object = this.dragObject(currentCoordinates.x, currentCoordinates.y);
  //     // Set last dragged from in DnD since we won't have dataTransfer for touch events.
  //     DnD.set('lastDraggedFrom', '%@:%@'.fmt(currentCoordinates.x, currentCoordinates.y));
  //     event.stopPropagation();
  //   } else {
  //     event.preventDefault();
  //     return false;
  //   }
  // },

  _sendDragEvent: function (name, x, y) {
    var dragMeta = this.get('_dragMeta'),
        fromX = dragMeta.get('fromX'),
        fromY = dragMeta.get('fromY');

    dragMeta.setProperties({
      x: x,
      y: y
    });

    var consume = Ember.tryInvoke(this, name, [{
      x: x,
      y: y,
      fromX: fromX,
      fromY: fromY,
      dx: x - fromX,
      dy: y - fromY
    }]);

    if (Ember.isNone(consume)) {
      return true;
    }
    return !consume;
  },

  _dragChanged: function () {
    this.$().css('z-index', this.get('dragged') ? 10001 : undefined);
  }.observes('dragged'),

  /** To be implemented by draggable */
  canDrag: true,

  /** To be implemented by draggable */
  dragBegin: Ember.K,
  dragMove: Ember.K,
  dragEnd: Ember.K
});
<|endoftext|>


<commit_before>
const { model: { User, Task } } = require('../model');
const bot = require('../lib/bot');
const moment = require('moment');

const filterUsers = async (tasks) => {
  let users = await User.findAll({
    raw: true
  });
  users = users.filter(x => tasks.findIndex(y => x.id === y.owner_id) !== -1);
  return users;
};

exports.dailyNotice = async () => {
  const tasks = await Task.findAll({
    raw: true,
    where: {
      deadline: {
        $gt: moment().startOf('day').valueOf(),
        $lt: moment().endOf('day').valueOf()
      },
      status: 1
    }
  });
  const users = await filterUsers(tasks);
  let msg;
  if (users.length === 0) {
    msg = '今日没有待办任务, 大家别偷懒哦';
  } else {
    const userTasks = users.map(x => ({
      username: x.name,
      tasks: tasks.filter(y => y.owner_id === x.id).map(z => z.content)
    }));
    msg = userTasks.map(x => `### ${x.username}\n\n${x.tasks.map(t => `- ${t}\n`).join('')}`).join('\n');
  }
  const result = await bot(msg);
  return result;
};

const buildMessage = (x) => {
  let msg = '';
  if (x.length > 0) {
    msg += `, 其中重要任务 ${x.length}个:\n`;
    x.forEach((m) => {
      msg += `- ${m.content} ${m.status === 2 ? '' : '(未完成)'}\n`;
    });
  }
  return msg;
};

const nextPeriod = async (type = 'week') => {
  const tasks = await Task.findAll({
    raw: true,
    where: {
      deadline: {
        $gt: moment().startOf(type).add(1, type === 'month' ? 'M' : 'w').valueOf(),
        $lt: moment().endOf(type).add(1, type === 'month' ? 'M' : 'w').valueOf()
      }
    }
  });
  const users = await filterUsers(tasks);
  const userTasks = users.map(x => ({
    username: x.name,
    tasks: tasks.filter(y => y.owner_id === x.id).length,
    important: tasks.filter(y => y.owner_id === x.id && y.priority >= 2)
  })).sort((x, y) => y.doneTasks - x.doneTasks);
  const msg = userTasks.map((x) => {
    let message = `### ${x.username}\n\n`;
    message += `\n\n任务: ${x.tasks}个`;
    message += buildMessage(x);
    return `${message}\n`;
  }).join('\n');
  return msg;
};

exports.notice = async (type = 'week') => {
  const tasks = await Task.findAll({
    raw: true,
    where: {
      deadline: {
        $gt: moment().startOf(type).valueOf(),
        $lt: moment().endOf(type).valueOf()
      }
    }
  });
  const users = await filterUsers(tasks);
  const userTasks = users.map(x => ({
    username: x.name,
    doneTasks: tasks.filter(y => y.owner_id === x.id && y.status === 2).length,
    undoneTasks: tasks.filter(y => y.owner_id === x.id && y.status === 1).length,
    important: tasks.filter(y => y.owner_id === x.id && y.priority >= 2)
  })).sort((x, y) => y.doneTasks - x.doneTasks);
  let msg = userTasks.map((x) => {
    let message = `### ${x.username}\n\n`;
    message += `完成任务: ${x.doneTasks}个, 未完成任务: ${x.undoneTasks}个`;
    message += buildMessage(x.important);
    return `${message}\n`;
  }).join('\n');
  msg = `## 本${type === 'month' ? '月' : '周'}任务完成情况 \n\n${msg}`;
  msg += `## 下${type === 'month' ? '月' : '周'}任务计划 \n\n${await nextPeriod(type)}`;
  const result = await bot(msg);
  return result;
};
<commit_msg>fix notice msg<commit_after>
const { model: { User, Task } } = require('../model');
const bot = require('../lib/bot');
const moment = require('moment');

const filterUsers = async (tasks) => {
  let users = await User.findAll({
    raw: true
  });
  users = users.filter(x => tasks.findIndex(y => x.id === y.owner_id) !== -1);
  return users;
};

exports.dailyNotice = async () => {
  const tasks = await Task.findAll({
    raw: true,
    where: {
      deadline: {
        $gt: moment().startOf('day').valueOf(),
        $lt: moment().endOf('day').valueOf()
      },
      status: 1
    }
  });
  const users = await filterUsers(tasks);
  let msg = '';
  if (users.length === 0) {
    msg = '今日竟然没有安排任务, 还想要年终奖么?';
  } else {
    const userTasks = users.map(x => ({
      username: x.name,
      tasks: tasks.filter(y => y.owner_id === x.id).map(z => z.content)
    }));
    if (users.length < 5) {
      msg = '怎么今天只有这么几个小伙伴有任务? 偷懒是要打pp的.\n\n';
    }
    msg += userTasks.map(x => `### ${x.username}\n\n${x.tasks.map(t => `- ${t}\n`).join('')}`).join('\n');
  }
  const result = await bot(msg);
  return result;
};

const buildMessage = (x) => {
  let msg = '';
  if (x.length > 0) {
    msg += `, 其中重要任务 ${x.length}个:\n`;
    x.forEach((m) => {
      msg += `- ${m.content} ${m.status === 2 ? '' : '(未完成)'}\n`;
    });
  }
  return msg;
};

const nextPeriod = async (type = 'week') => {
  const tasks = await Task.findAll({
    raw: true,
    where: {
      deadline: {
        $gt: moment().startOf(type).add(1, type === 'month' ? 'M' : 'w').valueOf(),
        $lt: moment().endOf(type).add(1, type === 'month' ? 'M' : 'w').valueOf()
      }
    }
  });
  const users = await filterUsers(tasks);
  const userTasks = users.map(x => ({
    username: x.name,
    tasks: tasks.filter(y => y.owner_id === x.id).length,
    important: tasks.filter(y => y.owner_id === x.id && y.priority >= 2)
  })).sort((x, y) => y.doneTasks - x.doneTasks);
  const msg = userTasks.map((x) => {
    let message = `### ${x.username}\n\n`;
    message += `\n\n任务: ${x.tasks}个`;
    message += buildMessage(x);
    return `${message}\n`;
  }).join('\n');
  return msg;
};

exports.notice = async (type = 'week') => {
  const tasks = await Task.findAll({
    raw: true,
    where: {
      deadline: {
        $gt: moment().startOf(type).valueOf(),
        $lt: moment().endOf(type).valueOf()
      }
    }
  });
  const users = await filterUsers(tasks);
  const userTasks = users.map(x => ({
    username: x.name,
    doneTasks: tasks.filter(y => y.owner_id === x.id && y.status === 2).length,
    undoneTasks: tasks.filter(y => y.owner_id === x.id && y.status === 1).length,
    important: tasks.filter(y => y.owner_id === x.id && y.priority >= 2)
  })).sort((x, y) => y.doneTasks - x.doneTasks);
  let msg = userTasks.map((x) => {
    let message = `### ${x.username}\n\n`;
    message += `完成任务: ${x.doneTasks}个, 未完成任务: ${x.undoneTasks}个`;
    message += buildMessage(x.important);
    return `${message}\n`;
  }).join('\n');
  msg = `## 本${type === 'month' ? '月' : '周'}任务完成情况 \n\n${msg}`;
  msg += `## 下${type === 'month' ? '月' : '周'}任务计划 \n\n${await nextPeriod(type)}`;
  const result = await bot(msg);
  return result;
};
<|endoftext|>


<commit_before>import { v4 } from "uuid"
import {
  forEach,
  forEachObjIndexed,
  isNil,
  map,
  reject,
  zipObj
} from "ramda"

import Redis from "./redis"

import Game from "./game"
import Revision from "./revision"

import { logger } from "~/app/index"

import { BLACK } from "~/share/constants/chess"
import { BEFORE, PRIMARY, AFTER } from "~/share/constants/role"
import { LEFT, RIGHT } from "~/share/constants/direction"
import { POSITION } from "~/share/constants/game_update_types"
import { UNIVERSE_CHANNEL } from "./universe"

export default class Client {
  constructor(universe, user, socket) {
    this.universe = universe
    this.user = user
    this.socket = socket

    this.redis = new Redis()
    this.redis.on("message", this.messageHandler.bind(this))

    this.subscribeUniverse()

    this.uuid = v4()
    this.gameUUID = null
  }

  async startGame(serializedGame) {
    this.gameUUID = serializedGame.uuid

    this.subscribeGame(this.gameUUID)
    this.socket.send({ action: "start", game: serializedGame })
  }

  // senders

  sendUniverse(universe) {
    this.socket.send({ action: "universe", universe })
  }

  sendLogin() {
    if (isNil(this.user)) {
      return
    }

    this.socket.send({ action: "login", user: this.user.serialize() })
  }

  async sendGame(game, role) {
    if (isNil(game)) {
      return
    }

    await game.serializePrepare()

    this.socket.send({ action: "game", role, game: game.serialize() })
  }

  async sendPosition({ uuid, position }) {
    this.socket.send({ action: POSITION, uuid, position })
  }

  // subscribers

  subscribeUniverse() {
    this.redis.subscribe(UNIVERSE_CHANNEL)
  }

  subscribeGame(uuid) {
    this.redis.subscribe(uuid)
  }

  // actions

  async kibitz() {
    if (await this.universe.games.length() === 0) {
      return
    }

    const first = await this.universe.games.head()
    const second = await this.universe.games.next(first)
    const third = await this.universe.games.next(second)

    const uuids = [first, second, third]
    const notNilUUIDs = reject(isNil, uuids)

    const games = await Game.where("uuid", "in", notNilUUIDs).fetchAll()

    const orderedGames = map((uuid) => {
      return games.find((game) => { return game.get("uuid") === uuid })
    }, uuids)

    forEach(this.subscribeGame.bind(this), notNilUUIDs)

    forEachObjIndexed(
      this.sendGame.bind(this),
      zipObj([BEFORE, PRIMARY, AFTER], orderedGames)
    )
  }

  async rotate({ direction, of }) {
    let uuid, role

    switch (direction) {
      case LEFT:
        uuid = await this.universe.nextGame(of)
        role = AFTER
        break

      case RIGHT:
        uuid = await this.universe.prevGame(of)
        role = BEFORE
        break

      default:
        logger.debug(`[rotate] Encountere unexpected direction: ${direction}`)
        return
    }

    this.subscribeGame(uuid)
    this.sendGame(await Game.where({ uuid: uuid }).fetch(), role)
  }

  async play() {
    this.universe.registerClient(this)
  }

  async move(move) {
    if (isNil(this.gameUUID)) {
      return
    }

    // TODO: authorize user
    const { revision, moveResult } = await Revision.move(this.gameUUID, move)

    if (revision) {
      if (moveResult && moveResult.captured) {
        // coerce into correct reserve
        if (moveResult.color === BLACK) {
          moveResult.captured = moveResult.piece.toUpperCase()
        }

        const game = await revision.game().fetch()
        this.universe.publishCapture(game, moveResult.captured)
      }

      // TODO: if revision is a result, publish result, removing from state
      const position = await revision.position().fetch()
      this.universe.publishPosition(this.gameUUID, position)
    } else {
      this.socket.send({ action: "invalid", data })
    }
  }

  // handler

  messageHandler(channel, message) {
    switch (channel) {
      case UNIVERSE_CHANNEL:
        this.sendUniverse(JSON.parse(message))
        break

      default:
        this.sendGameUpdate(channel, message)
    }
  }

  sendGameUpdate(uuid, message) {
    const { type, payload } = JSON.parse(message)

    if (type === POSITION) {
      this.sendPosition({ uuid, position: payload })
    }
  }
}
<commit_msg>factor out piece capture processing<commit_after>import { v4 } from "uuid"
import {
  forEach,
  forEachObjIndexed,
  isNil,
  map,
  reject,
  zipObj
} from "ramda"

import Redis from "./redis"

import Game from "./game"
import Revision from "./revision"

import { logger } from "~/app/index"

import { BLACK } from "~/share/constants/chess"
import { BEFORE, PRIMARY, AFTER } from "~/share/constants/role"
import { LEFT, RIGHT } from "~/share/constants/direction"
import { POSITION } from "~/share/constants/game_update_types"
import { UNIVERSE_CHANNEL } from "./universe"

export default class Client {
  constructor(universe, user, socket) {
    this.universe = universe
    this.user = user
    this.socket = socket

    this.redis = new Redis()
    this.redis.on("message", this.messageHandler.bind(this))

    this.subscribeUniverse()

    this.uuid = v4()
    this.gameUUID = null
  }

  async startGame(serializedGame) {
    this.gameUUID = serializedGame.uuid

    this.subscribeGame(this.gameUUID)
    this.socket.send({ action: "start", game: serializedGame })
  }

  // senders

  sendUniverse(universe) {
    this.socket.send({ action: "universe", universe })
  }

  sendLogin() {
    if (isNil(this.user)) {
      return
    }

    this.socket.send({ action: "login", user: this.user.serialize() })
  }

  async sendGame(game, role) {
    if (isNil(game)) {
      return
    }

    await game.serializePrepare()

    this.socket.send({ action: "game", role, game: game.serialize() })
  }

  async sendPosition({ uuid, position }) {
    this.socket.send({ action: POSITION, uuid, position })
  }

  // subscribers

  subscribeUniverse() {
    this.redis.subscribe(UNIVERSE_CHANNEL)
  }

  subscribeGame(uuid) {
    this.redis.subscribe(uuid)
  }

  // actions

  async kibitz() {
    if (await this.universe.games.length() === 0) {
      return
    }

    const first = await this.universe.games.head()
    const second = await this.universe.games.next(first)
    const third = await this.universe.games.next(second)

    const uuids = [first, second, third]
    const notNilUUIDs = reject(isNil, uuids)

    const games = await Game.where("uuid", "in", notNilUUIDs).fetchAll()

    const orderedGames = map((uuid) => {
      return games.find((game) => { return game.get("uuid") === uuid })
    }, uuids)

    forEach(this.subscribeGame.bind(this), notNilUUIDs)

    forEachObjIndexed(
      this.sendGame.bind(this),
      zipObj([BEFORE, PRIMARY, AFTER], orderedGames)
    )
  }

  async rotate({ direction, of }) {
    let uuid, role

    switch (direction) {
      case LEFT:
        uuid = await this.universe.nextGame(of)
        role = AFTER
        break

      case RIGHT:
        uuid = await this.universe.prevGame(of)
        role = BEFORE
        break

      default:
        logger.debug(`[rotate] Encountere unexpected direction: ${direction}`)
        return
    }

    this.subscribeGame(uuid)
    this.sendGame(await Game.where({ uuid: uuid }).fetch(), role)
  }

  async play() {
    this.universe.registerClient(this)
  }

  async move(move) {
    if (isNil(this.gameUUID)) {
      return
    }

    // TODO: authorize user
    const { revision, moveResult } = await Revision.move(this.gameUUID, move)

    if (revision) {
      await revision.refresh({ withRelated: ["game", "position"] })

      this.processCapture(revision, moveResult)
      // TODO: if revision is a result, publish result, removing from state

      const position = revision.related("position")
      this.universe.publishPosition(this.gameUUID, position)

    } else {
      this.socket.send({ action: "invalid", move })
    }
  }

  async processCapture(revision, moveResult) {
    if (moveResult && moveResult.captured) {
      // coerce into correct reserve
      if (moveResult.color === BLACK) {
        moveResult.captured = moveResult.piece.toUpperCase()
      }

      const game = await revision.related("game")
      this.universe.publishCapture(game, moveResult.captured)
    }
  }

  // handler

  messageHandler(channel, message) {
    switch (channel) {
      case UNIVERSE_CHANNEL:
        this.sendUniverse(JSON.parse(message))
        break

      default:
        this.sendGameUpdate(channel, message)
    }
  }

  sendGameUpdate(uuid, message) {
    const { type, payload } = JSON.parse(message)

    if (type === POSITION) {
      this.sendPosition({ uuid, position: payload })
    }
  }
}
<|endoftext|>


<commit_before>'use strict';

jasmine.getFixtures().fixturesPath = 'base/test/fixtures';

var createWidget = require('./utils/createWidget');
var mockAjax = require('./utils/mockAjax');

describe('Hour compatibility configuration', function() {

  beforeEach(function(){
    loadFixtures('hour-compatibility.html');
    jasmine.Ajax.install();
    mockAjax.all();
  });

  afterEach(function() {
    jasmine.Ajax.uninstall();
  });

  it('should be able to load with hourwidget div ID', function() {

    var config = {
      name: 'Demo Name'
    }
    createWidget(config);

    expect($('.bookingjs-displayname')).toBeInDOM();
    expect($('.bookingjs-displayname')).toBeVisible();
    expect($('.bookingjs-displayname')).toContainElement('span');
    expect($('.bookingjs-displayname span')).toContainText(config.name);

  });

});
<commit_msg>remove hour compatibility test<commit_after><|endoftext|>