<commit_before>'use strict';
var util = require('util'),
    fs = require('fs'),
    yeoman = require('yeoman-generator');

var ViewGenerator = yeoman.generators.NamedBase.extend({
    askForModuleName: function() {
        var modulesFolder = process.cwd() + '/app/modules/';
        var done = this.async();

        var prompts = [{
            type: 'list',
            name: 'moduleName',
            message: 'Which module does this route belongs to?',
            default: 'core',
            choices: []
        }];

        if (fs.existsSync(modulesFolder)){
            fs.readdirSync(modulesFolder).forEach(function(folder) {
                var stat = fs.statSync(modulesFolder + '/' + folder);

                if (stat.isDirectory()) {
                    prompts[0].choices.push({
                        value: folder,
                        name: folder
                    });
                }
            });
        }

        this.prompt(prompts, function(props) {
            this.moduleName = props.moduleName;
            this.controllerName = props.controllerName;

            this.slugifiedModuleName = this._.slugify(this.moduleName);
            this.humanizedModuleName = this._.humanize(this.moduleName);

            this.slugifiedName = this._.slugify(this._.humanize(this.name));
            this.classifiedName = this._.classify(this.slugifiedName);
            this.humanizedName = this._.humanize(this.slugifiedName);

            done();
        }.bind(this));
    },

    askForRouteDetails: function() {
        var done = this.async();

        var prompts = [{
            name: 'routePath',
            message: 'What do you want your route path to be?',
            default: this.slugifiedName
        }, {
            name: 'viewName',
            message: 'What do you want to call your view?',
            default: this.slugifiedName
        }, {
            name: 'controllerName',
            message: 'What do you want to call your controller?',
            default: this.classifiedName
        }];

        this.prompt(prompts, function(props) {
            this.routePath = props.routePath;
            this.viewName = props.viewName;
            this.controllerName = props.controllerName;

            this.slugifiedRoutePath = this._.slugify(this.routePath);

            this.slugifiedViewName = this._.slugify(this.viewName);
            this.humanizedViewName = this._.humanize(this.viewName);

            this.slugifiedControllerName = this._.slugify(this._.humanize(this.controllerName));
            this.classifiedControllerName = this._.classify(this.slugifiedControllerName);

            done();
        }.bind(this));
    },

    renderRoute: function() {
        var routesFilePath = process.cwd() + '/app/modules/' + this.slugifiedModuleName + '/config/routes.js';

        // If routes file exists we add a new state otherwise we render a new one
        if (fs.existsSync(routesFilePath)) {
            // Read the source routes file content
            var routesFileContent = this.readFileAsString(routesFilePath);

            // Append the new state
            routesFileContent = routesFileContent.replace('$stateProvider.', this.engine(this.read('../../templates/javascript/_route.js'), this));

            // Save route file
            this.writeFileFromString(routesFileContent, routesFilePath);
        } else {
            this.template('../../templates/javascript/_routes.js', 'app/modules/' + this.slugifiedModuleName + '/config/routes.js')
        }
    },

    renderRouteViewController: function() {
        this.template('../../templates/javascript/_controller.js', 'app/modules/' + this.slugifiedModuleName + '/controllers/' + this.slugifiedControllerName + '.js')
        this.template('../../templates/javascript/_view.html', 'app/modules/' + this.slugifiedModuleName + '/views/' + this.slugifiedViewName + '.html')
    },

    renderControllerUnitTestFile : function(){
        this.slugifiedTestFileName = this.slugifiedControllerName;
        this.template('../../templates/javascript/unit/_controller.spec.js', 'app/modules/' + this.slugifiedModuleName + '/tests/unit/' + this.slugifiedTestFileName + 'controller.spec.js');
    }
});

module.exports = ViewGenerator;
<commit_msg>Bug #16. Fix for route not being added to the list of routes<commit_after>'use strict';
var util = require('util'),
    fs = require('fs'),
    yeoman = require('yeoman-generator');

var ViewGenerator = yeoman.generators.NamedBase.extend({
    askForModuleName: function() {
        var modulesFolder = process.cwd() + '/app/modules/';
        var done = this.async();

        var prompts = [{
            type: 'list',
            name: 'moduleName',
            message: 'Which module does this route belongs to?',
            default: 'core',
            choices: []
        }];

        if (fs.existsSync(modulesFolder)){
            fs.readdirSync(modulesFolder).forEach(function(folder) {
                var stat = fs.statSync(modulesFolder + '/' + folder);

                if (stat.isDirectory()) {
                    prompts[0].choices.push({
                        value: folder,
                        name: folder
                    });
                }
            });
        }

        this.prompt(prompts, function(props) {
            this.moduleName = props.moduleName;
            this.controllerName = props.controllerName;

            this.slugifiedModuleName = this._.slugify(this.moduleName);
            this.humanizedModuleName = this._.humanize(this.moduleName);

            this.slugifiedName = this._.slugify(this._.humanize(this.name));
            this.classifiedName = this._.classify(this.slugifiedName);
            this.humanizedName = this._.humanize(this.slugifiedName);

            done();
        }.bind(this));
    },

    askForRouteDetails: function() {
        var done = this.async();

        var prompts = [{
            name: 'routePath',
            message: 'What do you want your route path to be?',
            default: this.slugifiedName
        }, {
            name: 'viewName',
            message: 'What do you want to call your view?',
            default: this.slugifiedName
        }, {
            name: 'controllerName',
            message: 'What do you want to call your controller?',
            default: this.classifiedName
        }];

        this.prompt(prompts, function(props) {
            this.routePath = props.routePath;
            this.viewName = props.viewName;
            this.controllerName = props.controllerName;

            this.slugifiedRoutePath = this._.slugify(this.routePath);

            this.slugifiedViewName = this._.slugify(this.viewName);
            this.humanizedViewName = this._.humanize(this.viewName);

            this.slugifiedControllerName = this._.slugify(this._.humanize(this.controllerName));
            this.classifiedControllerName = this._.classify(this.slugifiedControllerName);

            done();
        }.bind(this));
    },

    renderRoute: function() {
        var routesFilePath = process.cwd() + '/app/modules/' + this.slugifiedModuleName + '/config/routes.js';

        // If routes file exists we add a new state otherwise we render a new one
        if (fs.existsSync(routesFilePath)) {
            // Read the source routes file content
            var routesFileContent = this.readFileAsString(routesFilePath);

            // Append the new state
            routesFileContent = routesFileContent.replace(/\$stateProvider[\s\n]*\./, this.engine(this.read('../../templates/javascript/_route.js'), this));

            // Save route file
            this.writeFileFromString(routesFileContent, routesFilePath);
        } else {
            this.template('../../templates/javascript/_routes.js', 'app/modules/' + this.slugifiedModuleName + '/config/routes.js')
        }
    },

    renderRouteViewController: function() {
        this.template('../../templates/javascript/_controller.js', 'app/modules/' + this.slugifiedModuleName + '/controllers/' + this.slugifiedControllerName + '.js')
        this.template('../../templates/javascript/_view.html', 'app/modules/' + this.slugifiedModuleName + '/views/' + this.slugifiedViewName + '.html')
    },

    renderControllerUnitTestFile : function(){
        this.slugifiedTestFileName = this.slugifiedControllerName;
        this.template('../../templates/javascript/unit/_controller.spec.js', 'app/modules/' + this.slugifiedModuleName + '/tests/unit/' + this.slugifiedTestFileName + 'controller.spec.js');
    }
});

module.exports = ViewGenerator;
<|endoftext|>


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

var Jscs = require('jscs');

var DefaultValidator = require('./DefaultValidator');

var Validator = function() {
};

util.inherits(Validator, DefaultValidator);

Validator.prototype.validate = function(options, cb) {
	var jscs = new Jscs();
	jscs.registerDefaultRules();
	var conf = {};
	for (var key in options.config) conf[key] = options.config[key];
	jscs.configure(conf);
	try {
		var errors = jscs.checkString(options.content, options.path);
		errors = errors.getErrorList().map(function(error) {
			return {
				line: error.line,
				column: error.column,
				message: error.message,
				code: 'jscs'
			};
		});
		cb(null, errors);
	} catch (e) {
		cb([e], []);
	}
};

module.exports = Validator;
<commit_msg>[Jscs] Fix column number in report<commit_after>var util = require('util');

var Jscs = require('jscs');

var DefaultValidator = require('./DefaultValidator');

var Validator = function() {
};

util.inherits(Validator, DefaultValidator);

Validator.prototype.validate = function(options, cb) {
	var jscs = new Jscs();
	jscs.registerDefaultRules();
	var conf = {};
	for (var key in options.config) conf[key] = options.config[key];
	jscs.configure(conf);
	try {
		var errors = jscs.checkString(options.content, options.path);
		errors = errors.getErrorList().map(function(error) {
			return {
				line: error.line,
				column: error.column + 1,
				message: error.message,
				code: 'jscs'
			};
		});
		cb(null, errors);
	} catch (e) {
		cb([e], []);
	}
};

module.exports = Validator;
<|endoftext|>


<commit_before>/*
* Copyright (C) 2015-2016 by Arena of Titans Contributors.
*
* This file is part of Arena of Titans.
*
* Arena of Titans is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Arena of Titans is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Arena of Titans. If not, see <http://www.gnu.org/licenses/>.
*/

import { inject, NewInstance } from 'aurelia-framework';
import { I18N } from 'aurelia-i18n';
import { History } from './services/history';
import { Api } from './services/api';
import { EventAggregatorSubscriptions, ImageSource } from './services/utils';

const PLAYER_TRANSITION_POPUP_DISPLAY_TIME = 5000;

@inject(History, I18N, Api, NewInstance.of(EventAggregatorSubscriptions))
export class Game {
    static MAX_NUMBER_PLAYERS = 8;
    static heroes = [
        'daemon',
        'orc',
        'reaper',
        'thief',
    ];

    data = null;
    type = null;
    popupDefered = {
        promise: null,
        resolve: null,
        reject: null,
    };

    constructor(history, i18n, api, eas) {
        this._i18n = i18n;
        this._api = api;
        this._eas = eas;

        this._currentPlayerIndex = null;

        this._popupMessageId;
        this._popupMessage = {};
        this._eas.subscribe('i18n:locale:changed', () => this._translatePopupMessage());
        // Init history here: if the page is reloaded on the game page, the history may not be
        // setup until the player click on the player box. This may result in some actions not
        // being displayed. For instance, create a game, refresh, play a card. Without the line
        // below, it will not appear in the player box.
        history.init();
    }

    _translatePopupMessage() {
        if (this._popupMessageId) {
            this._popupMessage.message = this._i18n.tr(
                this._popupMessageId,
                this._popupMessageOptions
            );
        }
    }

    configureRouter(config, router) {
        router.baseUrl = 'game';
        config.options.pushState = true;
        config.map([
            {
                route: ['', 'play', ':version', ':version/play'],
                redirect: 'create',
            },
            {
                route: ['create', ':version/create', ':version/create/:id'],
                name: 'create',
                moduleId: './create/create',
                nav: false,
                title: 'Create game',
            },
            {
                route: ':version/play/:id',
                name: 'play',
                moduleId: './play/play',
                nav: false,
                title: 'Play',
            },
        ]);
        config.mapUnknownRoutes(instruction => {
            instruction.moduleId = 'not-found';

            return instruction;
        });
    }

    activate() {
        this._eas.subscribe('aot:api:error', data => {
            this._popupMessageId = data.message;
            this._translatePopupMessage();
            this.popup('error', this._popupMessage).then(() => {
                if (/\/game\/create\/.+/.test(location.pathname)) {
                    location.reload();
                }
            });
        });
        this._eas.subscribeMultiple(['aot:api:create_game', 'aot:api:play'], () => {
            if (this._api.game.next_player !== this._currentPlayerIndex) {
                this._currentPlayerIndex = this._api.game.next_player;
                if (this._currentPlayerIndex !== this._api.me.index) {
                    this._popupMessageId = 'game.play.whose_turn_message';
                    this._popupMessage.htmlMessage = true;
                } else {
                    this._popupMessageId = 'game.play.your_turn';
                }
                let hero = this._api.game.players.heroes[this._api.game.next_player];
                this._popupMessage.img = ImageSource.forChestHero(hero);
                this._popupMessageOptions = {
                    playerName: this._api.game.players.names[this._currentPlayerIndex],
                };
                this._translatePopupMessage();

                let options = {
                    timeout: PLAYER_TRANSITION_POPUP_DISPLAY_TIME,
                };
                this.popup('transition', this._popupMessage, options).then(() => {
                    this._popupMessageId = undefined;
                    this._popupMessage = {};
                    this._popupMessageOptions = {};
                });
            }
        });
    }

    deactivate() {
        this._eas.dispose();
    }

    popup(type, data, {timeout = 0} = {}) {
        this.data = data;
        this.type = type;
        this.popupDefered.promise = new Promise((resolve, reject) => {
            this.popupDefered.resolve = resolve;
            this.popupDefered.reject = reject;
        });

        this.popupDefered.promise.then(() => {
            this.data = null;
            this.type = null;
        }, () => {
            this.data = null;
            this.type = null;
        });

        if (timeout) {
            let closeTimeout = setTimeout(() => {
                this.popupDefered.resolve();
            }, timeout);
            let cancelCloseTimout = () => {
                clearTimeout(closeTimeout);
            };
            this.popupDefered.promise.then(cancelCloseTimout, cancelCloseTimout);
        }

        let startCounter = () => {
            this._eas.publish('aot:game:counter_start');
        };
        this.popupDefered.promise.then(startCounter, startCounter);

        return this.popupDefered.promise;
    }

    navigateWithRefresh(location) {
        window.location.replace(location);
    }
}
<commit_msg>feat(game): increase display time of transition popup<commit_after>/*
* Copyright (C) 2015-2016 by Arena of Titans Contributors.
*
* This file is part of Arena of Titans.
*
* Arena of Titans is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Arena of Titans is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Arena of Titans. If not, see <http://www.gnu.org/licenses/>.
*/

import { inject, NewInstance } from 'aurelia-framework';
import { I18N } from 'aurelia-i18n';
import { History } from './services/history';
import { Api } from './services/api';
import { EventAggregatorSubscriptions, ImageSource } from './services/utils';

const PLAYER_TRANSITION_POPUP_DISPLAY_TIME = 6000;

@inject(History, I18N, Api, NewInstance.of(EventAggregatorSubscriptions))
export class Game {
    static MAX_NUMBER_PLAYERS = 8;
    static heroes = [
        'daemon',
        'orc',
        'reaper',
        'thief',
    ];

    data = null;
    type = null;
    popupDefered = {
        promise: null,
        resolve: null,
        reject: null,
    };

    constructor(history, i18n, api, eas) {
        this._i18n = i18n;
        this._api = api;
        this._eas = eas;

        this._currentPlayerIndex = null;

        this._popupMessageId;
        this._popupMessage = {};
        this._eas.subscribe('i18n:locale:changed', () => this._translatePopupMessage());
        // Init history here: if the page is reloaded on the game page, the history may not be
        // setup until the player click on the player box. This may result in some actions not
        // being displayed. For instance, create a game, refresh, play a card. Without the line
        // below, it will not appear in the player box.
        history.init();
    }

    _translatePopupMessage() {
        if (this._popupMessageId) {
            this._popupMessage.message = this._i18n.tr(
                this._popupMessageId,
                this._popupMessageOptions
            );
        }
    }

    configureRouter(config, router) {
        router.baseUrl = 'game';
        config.options.pushState = true;
        config.map([
            {
                route: ['', 'play', ':version', ':version/play'],
                redirect: 'create',
            },
            {
                route: ['create', ':version/create', ':version/create/:id'],
                name: 'create',
                moduleId: './create/create',
                nav: false,
                title: 'Create game',
            },
            {
                route: ':version/play/:id',
                name: 'play',
                moduleId: './play/play',
                nav: false,
                title: 'Play',
            },
        ]);
        config.mapUnknownRoutes(instruction => {
            instruction.moduleId = 'not-found';

            return instruction;
        });
    }

    activate() {
        this._eas.subscribe('aot:api:error', data => {
            this._popupMessageId = data.message;
            this._translatePopupMessage();
            this.popup('error', this._popupMessage).then(() => {
                if (/\/game\/create\/.+/.test(location.pathname)) {
                    location.reload();
                }
            });
        });
        this._eas.subscribeMultiple(['aot:api:create_game', 'aot:api:play'], () => {
            if (this._api.game.next_player !== this._currentPlayerIndex) {
                this._currentPlayerIndex = this._api.game.next_player;
                if (this._currentPlayerIndex !== this._api.me.index) {
                    this._popupMessageId = 'game.play.whose_turn_message';
                    this._popupMessage.htmlMessage = true;
                } else {
                    this._popupMessageId = 'game.play.your_turn';
                }
                let hero = this._api.game.players.heroes[this._api.game.next_player];
                this._popupMessage.img = ImageSource.forChestHero(hero);
                this._popupMessageOptions = {
                    playerName: this._api.game.players.names[this._currentPlayerIndex],
                };
                this._translatePopupMessage();

                let options = {
                    timeout: PLAYER_TRANSITION_POPUP_DISPLAY_TIME,
                };
                this.popup('transition', this._popupMessage, options).then(() => {
                    this._popupMessageId = undefined;
                    this._popupMessage = {};
                    this._popupMessageOptions = {};
                });
            }
        });
    }

    deactivate() {
        this._eas.dispose();
    }

    popup(type, data, {timeout = 0} = {}) {
        this.data = data;
        this.type = type;
        this.popupDefered.promise = new Promise((resolve, reject) => {
            this.popupDefered.resolve = resolve;
            this.popupDefered.reject = reject;
        });

        this.popupDefered.promise.then(() => {
            this.data = null;
            this.type = null;
        }, () => {
            this.data = null;
            this.type = null;
        });

        if (timeout) {
            let closeTimeout = setTimeout(() => {
                this.popupDefered.resolve();
            }, timeout);
            let cancelCloseTimout = () => {
                clearTimeout(closeTimeout);
            };
            this.popupDefered.promise.then(cancelCloseTimout, cancelCloseTimout);
        }

        let startCounter = () => {
            this._eas.publish('aot:game:counter_start');
        };
        this.popupDefered.promise.then(startCounter, startCounter);

        return this.popupDefered.promise;
    }

    navigateWithRefresh(location) {
        window.location.replace(location);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 Titanium I.T. LLC. All rights reserved. See LICENSE.txt for details.

window.jdls = window.jdls || {};

//TODO: deleteme
jdls.debug = function(object, message) {
	"use strict";
	message = message ? " " + message : "";
	dump("Debugging" + message + ":");
	Object.getOwnPropertyNames(object).forEach(function(property) {
		if (property === "caller" || property === "callee" || property === "arguments") return;
		dump("  " + property + ": " + object[property] + " (" + typeof object[property] + ")");
	});
};

(function() {
	"use strict";

	var ObjectNode = jdls.ObjectNode = function ObjectNode(name, value) {
		this._name = objectName(name, value);
		this._value = value;
		this._prototype = Object.getPrototypeOf(value);
	};

	ObjectNode.prototype.name = function name() {
		return this._name;
	};

	ObjectNode.prototype.type = function type() {
		return objectType(this._value);
	};

	ObjectNode.prototype.title = function title() {
		return this.name() + " {" + this.type() + "}";
	};

	ObjectNode.prototype.forEachField = function forEachField(fn) {
		var self = this;
		getProperties(this._value).forEach(function(name) {
			fn(name, describeField(self._value[name]));
		});
		fn("<prototype>", describeField(this._prototype));
	};

	ObjectNode.prototype.forEachSubNode = function forEachSubNode(fn) {
		var self = this;

		getProperties(this._value).forEach(function(name) {
			subnode(name, self._value[name]);
		});
		subnode("<prototype>", this._prototype);

		function subnode(name, value) {
			if (typeof value !== "function" && typeof value !== "object") return;
			if (value === null) return;
			fn(new ObjectNode(self._name + "." + name, value));
		}
	};

	function objectName(fallbackName, object) {
		if (typeof object === "function") return functionName(object) + "()";
		if (hasOwnProperty(object, "constructor")) return functionName(object.constructor);
		return fallbackName;
	}

	function objectType(object) {
		var prototype = Object.getPrototypeOf(object);
		if (prototype === null) return "<root>";
		if (prototype.constructor === undefined || prototype.constructor === null) return "<anon>";
		return functionName(prototype.constructor);
	}

	function functionName(func) {
		var name = func.name;

		if (name === undefined) name = ieFunctionNameWorkaround(func);
		if (name === "") name = "<anon>";
		return name;
	}

	var describeField = jdls.describeField = function describeField(value) {
		if (value === null) return "null";

		switch (typeof value) {
			case "string": return '"' + value + '"';
			case "function": return functionName(value) + "()";
			case "object": return objectName("{" + objectType(value) + "}", value);
			default: return "" + value;
		}
	};

	function ieFunctionNameWorkaround(constructor) {
		// This workaround based on code by Jason Bunting et al, http://stackoverflow.com/a/332429
		var funcNameRegex = /function\s+(.{1,})\s*\(/;
		var results = (funcNameRegex).exec((constructor).toString());
		return (results && results.length > 1) ? results[1] : "";
	}

	function getProperties(object) {
		return Object.getOwnPropertyNames(object);
	}

	// can't use object.hasOwnProperty() because it doesn't work when object doesn't inherit from Object
	function hasOwnProperty(object, propertyName) {
		return Object.prototype.hasOwnProperty.call(object, propertyName);
	}

}());
<commit_msg>Factored out common forEach() code<commit_after>// Copyright (c) 2012 Titanium I.T. LLC. All rights reserved. See LICENSE.txt for details.

window.jdls = window.jdls || {};

//TODO: deleteme
jdls.debug = function(object, message) {
	"use strict";
	message = message ? " " + message : "";
	dump("Debugging" + message + ":");
	Object.getOwnPropertyNames(object).forEach(function(property) {
		if (property === "caller" || property === "callee" || property === "arguments") return;
		dump("  " + property + ": " + object[property] + " (" + typeof object[property] + ")");
	});
};

(function() {
	"use strict";

	var ObjectNode = jdls.ObjectNode = function ObjectNode(name, value) {
		this._name = objectName(name, value);
		this._value = value;
		this._prototype = Object.getPrototypeOf(value);
	};

	ObjectNode.prototype.name = function name() {
		return this._name;
	};

	ObjectNode.prototype.type = function type() {
		return objectType(this._value);
	};

	ObjectNode.prototype.title = function title() {
		return this.name() + " {" + this.type() + "}";
	};

	ObjectNode.prototype.forEachField = function forEachField(fn) {
		forEach(this._value, function(name, value) {
			fn(name, describeField(value));
		});
	};

	ObjectNode.prototype.forEachSubNode = function forEachSubNode(fn) {
		var self = this;
		forEach(this._value, function(name, value) {
			if (typeof value !== "function" && typeof value !== "object") return;
			if (value === null) return;
			fn(new ObjectNode(self._name + "." + name, value));
		});
	};

	function objectName(fallbackName, object) {
		if (typeof object === "function") return functionName(object) + "()";
		if (hasOwnProperty(object, "constructor")) return functionName(object.constructor);
		return fallbackName;
	}

	function objectType(object) {
		var prototype = Object.getPrototypeOf(object);
		if (prototype === null) return "<root>";
		if (prototype.constructor === undefined || prototype.constructor === null) return "<anon>";
		return functionName(prototype.constructor);
	}

	function functionName(func) {
		var name = func.name;

		if (name === undefined) name = ieFunctionNameWorkaround(func);
		if (name === "") name = "<anon>";
		return name;
	}

	function describeField(value) {
		if (value === null) return "null";

		switch (typeof value) {
			case "string": return '"' + value + '"';
			case "function": return functionName(value) + "()";
			case "object": return objectName("{" + objectType(value) + "}", value);
			default: return "" + value;
		}
	}

	function ieFunctionNameWorkaround(constructor) {
		// This workaround is based on code by Jason Bunting et al, http://stackoverflow.com/a/332429
		var funcNameRegex = /function\s+(.{1,})\s*\(/;
		var results = (funcNameRegex).exec((constructor).toString());
		return (results && results.length > 1) ? results[1] : "";
	}

	function forEach(object, fn) {
		getProperties(object).forEach(function(name) {
			fn(name, object[name]);
		});
		fn("<prototype>", Object.getPrototypeOf(object));
	}

	function getProperties(object) {
		return Object.getOwnPropertyNames(object);
	}

	// can't use object.hasOwnProperty() because it doesn't work when object doesn't inherit from Object
	function hasOwnProperty(object, propertyName) {
		return Object.prototype.hasOwnProperty.call(object, propertyName);
	}

}());
<|endoftext|>


<commit_before>var SpecificationBox = React.createClass({
  exportClicked: function() {
    // This is so dirty, but what else can we do?
    var contents = this.refs.editor.getValue();
    var a = document.body.appendChild(document.createElement("a"));
    a.download = "specification.clj";
    a.href = "data:text/plain;charset=utf-8," + encodeURIComponent(contents);
    a.innerHTML = "[Export content]";
    a.click();
    a.parentNode.removeChild(a);
  },
  composeClicked: function() {
    var spec = this.refs.editor.getValue();

    $.post("api/compose", {specification: spec}, function(ns) {
      this.updateState(ns);
    }.bind(this));
  },
  resetClicked: function() {
    this.refs.editor.setValue("");
    this.refs.editor.focus();
    this.replaceState({});
    this.refs.executionBox.setValue("");
  },
  exampleClicked: function(contents) {
    this.refs.editor.setValue(contents);
    this.refs.editor.clearSelection();
  },
  updateState: function(ns, latestResult) {
    $.get("api/namespace/" + ns, function(spec) {
      spec.latestResult = latestResult;
      this.setState(spec);
    }.bind(this));
  },
  getInitialState: function() {
    return {};
  },
  render: function() {
    return (

        <Toolbar
            onComposeClicked={this.composeClicked}
            onResetClicked={this.resetClicked}
            onExportClicked={this.exportClicked}
            onExampleClicked={this.exampleClicked} />
        <ExecutionBox
            spec={this.state}
            onActionExecuted={this.updateState}
            ref="executionBox" />
        <Editor ref="editor"/>

    );
  }
});

var Toolbar = React.createClass({
  composeClicked: function() {
    this.props.onComposeClicked();
  },
  exportClicked: function() {
    this.props.onExportClicked();
  },
  resetClicked: function() {
    this.props.onResetClicked();
  },
  exampleClicked: function(filename) {
    $.get("api/examples/" + filename, function(data) {
      this.props.onExampleClicked(data.contents);
    }.bind(this));
  },
  getInitialState: function() {
    return {examples: []};
  },
  componentDidMount: function() {
    $.get("api/examples", function(data) {
      this.setState({examples: data});
    }.bind(this));
  },
  render: function() {
    var exampleItems = this.state.examples.map(function(example) {
      return (
        <ToolbarItem key={example.filename} url="#"
            onItemClicked={this.exampleClicked.bind(this, example.filename)}>
          {example.title}
        </ToolbarItem>
      );
    }, this);
    return (

          <ToolbarItem key={"compose"} url={"#compose"}
              onItemClicked={this.composeClicked}>
            Compose
          </ToolbarItem>

          <ToolbarItem key={"export"} url={"#export"}
              onItemClicked={this.exportClicked}>
            Export
          </ToolbarItem>

          <ToolbarItem key={"reset"} url={"#reset"}
              onItemClicked={this.resetClicked}>
            Reset
          </ToolbarItem>

          <Dropdown title={"Examples"}>
            {exampleItems}
          </Dropdown>

    );
  }
});

var Dropdown = React.createClass({
  toggleMenu: function() {
    $(this.getDOMNode()).children("ul").slideToggle(100);
  },
  renderChildren: function() {
    return React.Children.map(this.props.children, function(child) {
      return React.addons.cloneWithProps(child, {toggleMenu: this.toggleMenu});
    }.bind(this));
  },
  render: function() {
    return (

        {this.props.title}

          {this.renderChildren()}

    );
  }
});

var ToolbarItem = React.createClass({
  itemClicked: function() {
    if(typeof(this.props.onItemClicked) === typeof(Function)) {
      this.props.onItemClicked();
    }

    if(typeof(this.props.toggleMenu) === typeof(Function)) {
      this.props.toggleMenu();
    }
  },
  render: function() {
    return (

          {this.props.children}

    );
  }
});

var Editor = React.createClass({
  getValue: function() {
    return this.editor.getValue();
  },
  setValue: function(value) {
    this.editor.setValue(value);
  },
  focus: function() {
    this.editor.focus();
  },
  clearSelection: function() {
    this.editor.clearSelection();
  },
  componentDidMount: function() {
    var editor = ace.edit("editor");
    editor.setTheme("ace/theme/monokai");
    editor.getSession().setMode("ace/mode/clojure");
    editor.focus();
    this.editor = editor;
  },
  render: function() {
    return (

    );
  }
});

var ExecutionBox = React.createClass({
  actionExecuted: function(ns, data) {
    this.props.onActionExecuted(ns, data);
  },
  setValue: function(value) {
    this.refs.executionBox.setValue(value);
  },
  render: function() {
    return (

        <ActionBox
            namespace={this.props.spec.namespace}
            onActionExecuted={this.actionExecuted}
            ref="executionBox" />
        <LatestResultBox data={this.props.spec.latestResult} />
        <DataBox data={this.props.spec.data} />

    );
  }
});

var ActionBox = React.createClass({
  actionExecuted: function(ns, data) {
    this.props.onActionExecuted(ns, data);
  },
  setValue: function(value) {
    this.editor.setValue(value);
  },
  componentDidMount: function() {
    var editor = ace.edit("executionEditor");
    editor.setTheme("ace/theme/monokai");
    editor.getSession().setMode("ace/mode/clojure");

    editor.commands.addCommand({
      name: 'executeCommand',
      bindKey: 'enter',
      exec: function(editor) {
        var requestObject = {
          ns: this.props.namespace,
          command: editor.getValue()
        };

        $.post("api/execute", requestObject, function(data) {
          this.actionExecuted(requestObject.ns, data);
        }.bind(this));
      }.bind(this),
      readOnly: false
    });

    this.editor = editor;
  },
  render: function() {
    return (

Execute actions

    );
  }
});

var LatestResultBox = React.createClass({
  render: function() {
    return (

Latest result

{this.props.data}

    );
  }
});

var DataBox = React.createClass({
  render: function() {
    var dataItems = [];

    if(typeof this.props.data !== 'undefined') {
      dataItems = this.props.data.map(function(dataItem) {
        return (
          <DataItem key={dataItem.name} data={dataItem} />
        );
      });
    }

    return (

Data

          {dataItems}

    );
  }
});

var DataItem = React.createClass({
  toggleContent: function() {
    $(this.getDOMNode()).children(".dataItemContent").slideToggle(100);
  },
  render: function() {
    return (

          {this.props.data.name}

{this.props.data.contents}

    );
  }
});

React.render(
  <SpecificationBox />,
  document.getElementById('content')
);
<commit_msg>Implemented showing of recently executed actioons.<commit_after>var SpecificationBox = React.createClass({
  exportClicked: function() {
    // This is so dirty, but what else can we do?
    var contents = this.refs.editor.getValue();
    var a = document.body.appendChild(document.createElement("a"));
    a.download = "specification.clj";
    a.href = "data:text/plain;charset=utf-8," + encodeURIComponent(contents);
    a.innerHTML = "[Export content]";
    a.click();
    a.parentNode.removeChild(a);
  },
  composeClicked: function() {
    var spec = this.refs.editor.getValue();

    $.post("api/compose", {specification: spec}, function(ns) {
      this.updateState(ns);
    }.bind(this));
  },
  resetClicked: function() {
    this.refs.editor.setValue("");
    this.refs.editor.focus();
    this.replaceState({});
    this.refs.executionBox.setValue("");
  },
  exampleClicked: function(contents) {
    this.refs.editor.setValue(contents);
    this.refs.editor.clearSelection();
  },
  updateState: function(ns, latestResult) {
    $.get("api/namespace/" + ns, function(spec) {
      spec.latestResult = latestResult;
      this.setState(spec);
    }.bind(this));
  },
  getInitialState: function() {
    return {};
  },
  render: function() {
    return (

        <Toolbar
            onComposeClicked={this.composeClicked}
            onResetClicked={this.resetClicked}
            onExportClicked={this.exportClicked}
            onExampleClicked={this.exampleClicked} />
        <ExecutionBox
            spec={this.state}
            onActionExecuted={this.updateState}
            ref="executionBox" />
        <Editor ref="editor"/>

    );
  }
});

var Toolbar = React.createClass({
  composeClicked: function() {
    this.props.onComposeClicked();
  },
  exportClicked: function() {
    this.props.onExportClicked();
  },
  resetClicked: function() {
    this.props.onResetClicked();
  },
  exampleClicked: function(filename) {
    $.get("api/examples/" + filename, function(data) {
      this.props.onExampleClicked(data.contents);
    }.bind(this));
  },
  getInitialState: function() {
    return {examples: []};
  },
  componentDidMount: function() {
    $.get("api/examples", function(data) {
      this.setState({examples: data});
    }.bind(this));
  },
  render: function() {
    var exampleItems = this.state.examples.map(function(example) {
      return (
        <ToolbarItem key={example.filename} url="#"
            onItemClicked={this.exampleClicked.bind(this, example.filename)}>
          {example.title}
        </ToolbarItem>
      );
    }, this);
    return (

          <ToolbarItem key={"compose"} url={"#compose"}
              onItemClicked={this.composeClicked}>
            Compose
          </ToolbarItem>

          <ToolbarItem key={"export"} url={"#export"}
              onItemClicked={this.exportClicked}>
            Export
          </ToolbarItem>

          <ToolbarItem key={"reset"} url={"#reset"}
              onItemClicked={this.resetClicked}>
            Reset
          </ToolbarItem>

          <Dropdown title={"Examples"}>
            {exampleItems}
          </Dropdown>

    );
  }
});

var Dropdown = React.createClass({
  toggleMenu: function() {
    $(this.getDOMNode()).children("ul").slideToggle(100);
  },
  renderChildren: function() {
    return React.Children.map(this.props.children, function(child) {
      return React.addons.cloneWithProps(child, {toggleMenu: this.toggleMenu});
    }.bind(this));
  },
  render: function() {
    return (

        {this.props.title}

          {this.renderChildren()}

    );
  }
});

var ToolbarItem = React.createClass({
  itemClicked: function() {
    if(typeof(this.props.onItemClicked) === typeof(Function)) {
      this.props.onItemClicked();
    }

    if(typeof(this.props.toggleMenu) === typeof(Function)) {
      this.props.toggleMenu();
    }
  },
  render: function() {
    return (

          {this.props.children}

    );
  }
});

var Editor = React.createClass({
  getValue: function() {
    return this.editor.getValue();
  },
  setValue: function(value) {
    this.editor.setValue(value);
  },
  focus: function() {
    this.editor.focus();
  },
  clearSelection: function() {
    this.editor.clearSelection();
  },
  componentDidMount: function() {
    var editor = ace.edit("editor");
    editor.setTheme("ace/theme/monokai");
    editor.getSession().setMode("ace/mode/clojure");
    editor.focus();
    this.editor = editor;
  },
  render: function() {
    return (

    );
  }
});

var ExecutionBox = React.createClass({
  actionExecuted: function(ns, command, data) {
    this.props.onActionExecuted(ns, data);

    var state = this.state;
    state.recentActions.unshift(command);
    state.recentActions.splice(10);
    this.setState(state);
  },
  setValue: function(value) {
    this.refs.executionBox.setValue(value);
  },
  getInitialState: function() {
    return {recentActions: []};
  },
  render: function() {
    return (

        <ActionBox
            namespace={this.props.spec.namespace}
            onActionExecuted={this.actionExecuted}
            ref="executionBox" />
        <RecentActionsBox data={this.state.recentActions} />
        <LatestResultBox data={this.props.spec.latestResult} />
        <DataBox data={this.props.spec.data} />

    );
  }
});

var ActionBox = React.createClass({
  actionExecuted: function(ns, command, data) {
    this.props.onActionExecuted(ns, command, data);
  },
  setValue: function(value) {
    this.editor.setValue(value);
  },
  componentDidMount: function() {
    var editor = ace.edit("executionEditor");
    editor.setTheme("ace/theme/monokai");
    editor.getSession().setMode("ace/mode/clojure");

    editor.commands.addCommand({
      name: 'executeCommand',
      bindKey: 'enter',
      exec: function(editor) {
        var requestObject = {
          ns: this.props.namespace,
          command: editor.getValue()
        };

        $.post("api/execute", requestObject, function(data) {
          this.actionExecuted(requestObject.ns, requestObject.command, data);
        }.bind(this));
      }.bind(this),
      readOnly: false
    });

    this.editor = editor;
  },
  render: function() {
    return (

Execute actions

    );
  }
});

var RecentActionsBox = React.createClass({
  render: function() {
    var recentActions = this.props.data.map(function(recentAction, index) {
      return (

          {recentAction}

      );
    });

    return (

Recent actions

          {recentActions}

    );
  }
});

var LatestResultBox = React.createClass({
  render: function() {
    return (

Latest result

{this.props.data}

    );
  }
});

var DataBox = React.createClass({
  render: function() {
    var dataItems = [];

    if(typeof this.props.data !== 'undefined') {
      dataItems = this.props.data.map(function(dataItem) {
        return (
          <DataItem key={dataItem.name} data={dataItem} />
        );
      });
    }

    return (

Data

          {dataItems}

    );
  }
});

var DataItem = React.createClass({
  toggleContent: function() {
    $(this.getDOMNode()).children(".dataItemContent").slideToggle(100);
  },
  render: function() {
    return (

          {this.props.data.name}

{this.props.data.contents}

    );
  }
});

React.render(
  <SpecificationBox />,
  document.getElementById('content')
);
<|endoftext|>


<commit_before>'use strict';

import * as preferences from './preferences.js';

var persistenceTimerInterval;
var persistenceTimerEnforceSaveInterval;
var persistenceEnabled = false;
var persistenceInterval = 5000;
var persistenceTarget = window.location.protocol + '//lively4/';

function hasDoNotPersistTag(node, checkForChildrenValueToo = false) {
    return node.attributes
        && node.attributes.hasOwnProperty('data-lively4-donotpersist')
        && (checkForChildrenValueToo ?
            node.dataset.lively4Donotpersist == 'children' || node.dataset.lively4Donotpersist == 'all' :
            node.dataset.lively4Donotpersist == 'all');
}

function hasParentTag(node) {
    return node.parentNode != null;
}

function hasNoDonotpersistFlagInherited(nodes, isParent = false) {
    let parents = new Set();
    for (let node of nodes) {
        if (!hasDoNotPersistTag(node, isParent) && hasParentTag(node)) {
            parents.add(node.parentNode);
        }
    }
    if (parents.size == 0) return false;
    if (parents.has(document)) return true;
    return hasNoDonotpersistFlagInherited(parents, true);
}

function checkRemovedNodes(nodes, orphans) {
    return !nodes.every(hasDoNotPersistTag) && !nodes.every(n => orphans.has(n))
}

function initialize(){
    resetPersistenceSessionStore();
    loadPreferences();

    var orphans = new Set();

    $(window).unload(saveOnLeave);

    let observer = new MutationObserver((mutations, observer) => {
        mutations.forEach(record => {
            if (record.target.id == 'console'
                || record.target.id == 'editor') return;

            let shouldSave = true;
            if (record.type == 'childList') {
                let addedNodes = [...record.addedNodes],
                    removedNodes = [...record.removedNodes],
                    nodes = addedNodes.concat(removedNodes);

                //removed nodes never have a parent, so remeber orphans when they are created
                for (let node of addedNodes) {
                    if (hasParentTag(node) == false) {
                        orphans.add(node);
                    }
                }

                shouldSave = hasNoDonotpersistFlagInherited(addedNodes) || checkRemovedNodes(removedNodes, orphans);

                //remove removed orphan nodes from orphan set
                for (let node of removedNodes) {
                    if (orphans.has(node)) {
                        orphans.delete(node);
                    }
                }
            }
            else if (record.type == 'attributes'
                || record.type == 'characterData') {
                shouldSave = hasNoDonotpersistFlagInherited([record.target]);
            }

            if (shouldSave) {
                sessionStorage["lively.scriptMutationsDetected"] = 'true';
                restartPersistenceTimerInterval();
            }
        })
    });
    observer.observe(document, {childList: true, subtree: true, characterData: true, attributes: true});
}

function loadPreferences() {
    persistenceInterval = parseInt(preferences.read('persistenceInterval'));
    persistenceTarget = preferences.read('persistenceTarget');
    persistenceEnabled = preferences.read('persistenceEnabled') == 'true';
}

function saveOnLeave() {
    stopPersistenceTimerInterval(true);
    if (isPersistenceEnabled() && sessionStorage["lively.scriptMutationsDetected"] === 'true') {
        console.log("[persistence] window-closed mutations detected, saving DOM...")
        saveDOM(false);
    }
};

function getURL(){
    var baseurl = getPersistenceTarget();
    var filename;

    var url = document.URL;
    var r = /https:\/\/([\w-]+)\.github\.io\/([\w-]+)\/(.+)/i;
    var results = url.match(r);

    if (results)
    {
        filename = results[3];
    }
    else
    {
        r = /^(?:(https?):\/\/)?(?:(\w+)(?:\:(\w+))?\@)?([\w\.\-\~]+)+(?:\:(\d+))?(?:\/([\w\.\-\~\/\%]+))?(?:\?([\w\=\&]+))?(?:\#(\w+))?$/;
        results = url.match(r);
        if (results)
        {
            filename = results[6];
        } else {
            throw "Could not parse URL to persist changes!";
        }
    }

    return new URL(baseurl + filename)
}

export function startPersistenceTimerInterval() {
    persistenceTimerInterval = setInterval(checkForMutationsToSave, persistenceInterval);
    if (persistenceTimerEnforceSaveInterval == undefined)
        persistenceTimerEnforceSaveInterval = setInterval(checkForMutationsToSave, persistenceInterval * 10);
}

export function stopPersistenceTimerInterval(stopEnforceSave = false) {
    clearInterval(persistenceTimerInterval);
    persistenceTimerInterval = undefined;
    if (stopEnforceSave) {
        stopPersistenceTimerEnforceSaveInterval()
    }
}

export function stopPersistenceTimerEnforceSaveInterval() {
    clearInterval(persistenceTimerEnforceSaveInterval);
    persistenceTimerEnforceSaveInterval = undefined;
}

export function getPersistenceInterval() {
    return persistenceInterval;
}

export function setPersistenceInterval(interval) {
    if (interval == persistenceInterval) return;

    persistenceInterval = interval;
    preferences.write('persistenceInterval', interval);

    restartPersistenceTimerInterval();
}

function restartPersistenceTimerInterval() {
    stopPersistenceTimerInterval();
    startPersistenceTimerInterval();
}

function resetPersistenceSessionStore() {
    sessionStorage["lively.scriptMutationsDetected"] = 'false';
    sessionStorage["lively.persistenceCurrentlyCloning"] = 'false';
}

function checkForMutationsToSave() {
    if (isPersistenceEnabled() && sessionStorage["lively.scriptMutationsDetected"] === 'true') {
        console.log("[persistence] timer-based mutations detected, saving DOM...")
        saveDOM();
    }
}

export function isPersistenceEnabled() {
    return persistenceEnabled;
}

export function setPersistenceEnabled(enabled) {
    if (enabled == persistenceEnabled) return;

    persistenceEnabled = enabled;
    preferences.write('persistenceEnabled', enabled);
}

export function getPersistenceTarget() {
    return persistenceTarget;
}

export function setPersistenceTarget(target) {
    if (target == persistenceTarget) return;

    persistenceTarget = target;
    preferences.write('persistenceTarget', target);
}

export function isCurrentlyCloning() {
    return sessionStorage["lively.persistenceCurrentlyCloning"] === 'true';
}

export function saveDOM(async = true) {
    var world;
    sessionStorage["lively.persistenceCurrentlyCloning"] = 'true';
    try {
        world = $("html").clone();
    }
    finally {
        sessionStorage["lively.persistenceCurrentlyCloning"] = 'false';
    }

    world.find("[data-lively4-donotpersist='children']").empty();
    world.find("[data-lively4-donotpersist='all']").remove();
    world.find("#editor").empty();
    world.find("#console").empty();
    world.find("#ace_editor\\.css").remove();
    world.find("#ace-tm").remove();
    world.find("style").filter((i,e) => /\s*\.error_widget_wrapper+/.test(e.textContent)).remove();

    var content = "<!DOCTYPE html>\n" + world[0].outerHTML;

    resetPersistenceSessionStore();

    writeFile(content, async);
    stopPersistenceTimerEnforceSaveInterval();
}

function writeFile(content, async = true) {
    var url = getURL()
    console.log("[persistence] save " + url)
    $.ajax({
        url: url,
        type: 'PUT',
        async: async,
        data: content,
        success: text => {
            console.log("[persistence] file " + url + " written.")
        },
        error: (xhr, status, error) => {
            console.log("[persistence] could not write " + url + ": " + error)
        }
    });
}

initialize();<commit_msg>Fix line endings ^M<commit_after>'use strict';

import * as preferences from './preferences.js';

var persistenceTimerInterval;
var persistenceTimerEnforceSaveInterval;
var persistenceEnabled = false;
var persistenceInterval = 5000;
var persistenceTarget = window.location.protocol + '//lively4/';

function hasDoNotPersistTag(node, checkForChildrenValueToo = false) {
    return node.attributes
        && node.attributes.hasOwnProperty('data-lively4-donotpersist')
        && (checkForChildrenValueToo ?
            node.dataset.lively4Donotpersist == 'children' || node.dataset.lively4Donotpersist == 'all' :
            node.dataset.lively4Donotpersist == 'all');
}

function hasParentTag(node) {
    return node.parentNode != null;
}

function hasNoDonotpersistFlagInherited(nodes, isParent = false) {
    let parents = new Set();
    for (let node of nodes) {
        if (!hasDoNotPersistTag(node, isParent) && hasParentTag(node)) {
            parents.add(node.parentNode);
        }
    }
    if (parents.size == 0) return false;
    if (parents.has(document)) return true;
    return hasNoDonotpersistFlagInherited(parents, true);
}

function checkRemovedNodes(nodes, orphans) {
    return !nodes.every(hasDoNotPersistTag) && !nodes.every(n => orphans.has(n))
}

function initialize(){
    resetPersistenceSessionStore();
    loadPreferences();

    var orphans = new Set();

    $(window).unload(saveOnLeave);

    let observer = new MutationObserver((mutations, observer) => {
        mutations.forEach(record => {
            if (record.target.id == 'console'
                || record.target.id == 'editor') return;

            let shouldSave = true;
            if (record.type == 'childList') {
                let addedNodes = [...record.addedNodes],
                    removedNodes = [...record.removedNodes],
                    nodes = addedNodes.concat(removedNodes);

                //removed nodes never have a parent, so remeber orphans when they are created
                for (let node of addedNodes) {
                    if (hasParentTag(node) == false) {
                        orphans.add(node);
                    }
                }

                shouldSave = hasNoDonotpersistFlagInherited(addedNodes) || checkRemovedNodes(removedNodes, orphans);

                //remove removed orphan nodes from orphan set
                for (let node of removedNodes) {
                    if (orphans.has(node)) {
                        orphans.delete(node);
                    }
                }
            }
            else if (record.type == 'attributes'
                || record.type == 'characterData') {
                shouldSave = hasNoDonotpersistFlagInherited([record.target]);
            }

            if (shouldSave) {
                sessionStorage["lively.scriptMutationsDetected"] = 'true';
                restartPersistenceTimerInterval();
            }
        })
    });
    observer.observe(document, {childList: true, subtree: true, characterData: true, attributes: true});
}

function loadPreferences() {
    persistenceInterval = parseInt(preferences.read('persistenceInterval'));
    persistenceTarget = preferences.read('persistenceTarget');
    persistenceEnabled = preferences.read('persistenceEnabled') == 'true';
}

function saveOnLeave() {
    stopPersistenceTimerInterval(true);
    if (isPersistenceEnabled() && sessionStorage["lively.scriptMutationsDetected"] === 'true') {
        console.log("[persistence] window-closed mutations detected, saving DOM...")
        saveDOM(false);
    }
};

function getURL(){
    var baseurl = getPersistenceTarget();
    var filename;

    var url = document.URL;
    var r = /https:\/\/([\w-]+)\.github\.io\/([\w-]+)\/(.+)/i;
    var results = url.match(r);

    if (results)
    {
        filename = results[3];
    }
    else
    {
        r = /^(?:(https?):\/\/)?(?:(\w+)(?:\:(\w+))?\@)?([\w\.\-\~]+)+(?:\:(\d+))?(?:\/([\w\.\-\~\/\%]+))?(?:\?([\w\=\&]+))?(?:\#(\w+))?$/;
        results = url.match(r);
        if (results)
        {
            filename = results[6];
        } else {
            throw "Could not parse URL to persist changes!";
        }
    }

    return new URL(baseurl + filename)
}

export function startPersistenceTimerInterval() {
    persistenceTimerInterval = setInterval(checkForMutationsToSave, persistenceInterval);
    if (persistenceTimerEnforceSaveInterval == undefined)
        persistenceTimerEnforceSaveInterval = setInterval(checkForMutationsToSave, persistenceInterval * 10);
}

export function stopPersistenceTimerInterval(stopEnforceSave = false) {
    clearInterval(persistenceTimerInterval);
    persistenceTimerInterval = undefined;
    if (stopEnforceSave) {
        stopPersistenceTimerEnforceSaveInterval()
    }
}

export function stopPersistenceTimerEnforceSaveInterval() {
    clearInterval(persistenceTimerEnforceSaveInterval);
    persistenceTimerEnforceSaveInterval = undefined;
}

export function getPersistenceInterval() {
    return persistenceInterval;
}

export function setPersistenceInterval(interval) {
    if (interval == persistenceInterval) return;

    persistenceInterval = interval;
    preferences.write('persistenceInterval', interval);

    restartPersistenceTimerInterval();
}

function restartPersistenceTimerInterval() {
    stopPersistenceTimerInterval();
    startPersistenceTimerInterval();
}

function resetPersistenceSessionStore() {
    sessionStorage["lively.scriptMutationsDetected"] = 'false';
    sessionStorage["lively.persistenceCurrentlyCloning"] = 'false';
}

function checkForMutationsToSave() {
    if (isPersistenceEnabled() && sessionStorage["lively.scriptMutationsDetected"] === 'true') {
        console.log("[persistence] timer-based mutations detected, saving DOM...")
        saveDOM();
    }
}

export function isPersistenceEnabled() {
    return persistenceEnabled;
}

export function setPersistenceEnabled(enabled) {
    if (enabled == persistenceEnabled) return;

    persistenceEnabled = enabled;
    preferences.write('persistenceEnabled', enabled);
}

export function getPersistenceTarget() {
    return persistenceTarget;
}

export function setPersistenceTarget(target) {
    if (target == persistenceTarget) return;

    persistenceTarget = target;
    preferences.write('persistenceTarget', target);
}

export function isCurrentlyCloning() {
    return sessionStorage["lively.persistenceCurrentlyCloning"] === 'true';
}

export function saveDOM(async = true) {
    var world;
    sessionStorage["lively.persistenceCurrentlyCloning"] = 'true';
    try {
        world = $("html").clone();
    }
    finally {
        sessionStorage["lively.persistenceCurrentlyCloning"] = 'false';
    }

    world.find("[data-lively4-donotpersist='children']").empty();
    world.find("[data-lively4-donotpersist='all']").remove();
    world.find("#editor").empty();
    world.find("#console").empty();
    world.find("#ace_editor\\.css").remove();
    world.find("#ace-tm").remove();
    world.find("style").filter((i,e) => /\s*\.error_widget_wrapper+/.test(e.textContent)).remove();

    var content = "<!DOCTYPE html>\n" + world[0].outerHTML;

    resetPersistenceSessionStore();

    writeFile(content, async);
    stopPersistenceTimerEnforceSaveInterval();
}

function writeFile(content, async = true) {
    var url = getURL()
    console.log("[persistence] save " + url)
    $.ajax({
        url: url,
        type: 'PUT',
        async: async,
        data: content,
        success: text => {
            console.log("[persistence] file " + url + " written.")
        },
        error: (xhr, status, error) => {
            console.log("[persistence] could not write " + url + ": " + error)
        }
    });
}

initialize();
<|endoftext|>


<commit_before>import * as React from 'react';
import {getFields} from './utils/getFields.js';

/**
 * Component used to render Build Information.
 *
 * @param {*} props input properties containing build information
 */
export const BuildSnapshot = (props) => {
  // State variable indicating whether the BuildSnapshot is open or closed.
  // isOpen === true indicates the tray should be visible
  // and the indicator arrow on the Header should be facing downwards.
  const [isOpen, setIsOpen] = React.useState(false);

  const headerFields = ['description', 'commitHash', 'repository', 'status'];
  const trayFields = ['builders', 'timestamp'];

  const headerData = getFields(props.buildData, headerFields, '');
  const trayData = getFields(props.buildData, trayFields, '');

  return (

      <Tray isOpen = {isOpen} data = {trayData}/>

  );
}

/**
  * Subcomponent that holds the content displayed
  * when the BuildSnapshot is collapsed.
  *
  * @param props an object containing a 'data' field
  * which encapsulates the fields from headerFields.
 */
const Header = (props) => {
  return (

 props.onClick(toggle(props.isOpen))}>
      {props.data.commitHash}
      {props.data.description}
      <FailureGroup group = {'Group'}/>
      {props.data.status}

  );
}

/**
  * Subcomponent that holds the content revealed
  * when the BuildSnapshot is open (isOpen === true).
  *
  * @param props an object containing a 'data' field
  * which encapsualtes the fields from trayFields.
 */
const Tray = (props) => {
  // State variable indicating the builder whose data
  // should be rendered to the BuilderDataTable.
  // Represents the index of the builder in props.data.builders
  const [selectedBuilder,selectBuilder] = React.useState(0);
  const builder = props.data.builders[selectedBuilder];

  if(props.isOpen !== true) return null;
  return (

      {props.data.timestamp}

{builder.name}

      <BuilderGrid onClick = {selectBuilder} data = {props.data.builders}/>
      <BuilderDataTable builder = {builder}/>

  );
}
<commit_msg>Change all instances of class to className<commit_after>import * as React from 'react';
import {getFields} from './utils/getFields.js';

/**
 * Component used to render Build Information.
 *
 * @param {*} props input properties containing build information
 */
export const BuildSnapshot = (props) => {
  // State variable indicating whether the BuildSnapshot is open or closed.
  // isOpen === true indicates the tray should be visible
  // and the indicator arrow on the Header should be facing downwards.
  const [isOpen, setIsOpen] = React.useState(false);

  const headerFields = ['description', 'commitHash', 'repository', 'status'];
  const trayFields = ['builders', 'timestamp'];

  const headerData = getFields(props.buildData, headerFields, '');
  const trayData = getFields(props.buildData, trayFields, '');

  return (

      <Tray isOpen = {isOpen} data = {trayData}/>

  );
}

/**
  * Subcomponent that holds the content displayed
  * when the BuildSnapshot is collapsed.
  *
  * @param props an object containing a 'data' field
  * which encapsulates the fields from headerFields.
 */
const Header = (props) => {
  return (

 props.onClick(toggle(props.isOpen))}>
      {props.data.commitHash}
      {props.data.description}
      <FailureGroup group = {'Group'}/>
      {props.data.status}

  );
}

/**
  * Subcomponent that holds the content revealed
  * when the BuildSnapshot is open (isOpen === true).
  *
  * @param props an object containing a 'data' field
  * which encapsualtes the fields from trayFields.
 */
const Tray = (props) => {
  // State variable indicating the builder whose data
  // should be rendered to the BuilderDataTable.
  // Represents the index of the builder in props.data.builders
  const [selectedBuilder,selectBuilder] = React.useState(0);
  const builder = props.data.builders[selectedBuilder];

  if(props.isOpen !== true) return null;
  return (

      {props.data.timestamp}

{builder.name}

      <BuilderGrid onClick = {selectBuilder} data = {props.data.builders}/>
      <BuilderDataTable builder = {builder}/>

  );
}
<|endoftext|>


<commit_before>function action(url, worker, on, action, selector, original_color, highlight_color, params, on_success) {
    if(on) {
        if(worker)
            url += worker + '/holidays/' + on + '/' + action + '/';
        else
            url += on + '/' + action;
        $(selector).attr('style', 'background: ' + highlight_color);
    } else {
        if(worker)
            url += worker + '/holidays/' + action;
        else
            url += action;
    }
    $("#holiday-dlg").load(url,
                           function() {
                               $(this).dialog({title: params.title,
                                               width: params.width,
                                               buttons: [{text: params.button_close,
                                                          click: function() {
                                                              $(this).dialog('close');
                                                              $(selector).attr('style', original_color);
                                                          }},{text: params.button_confirm,
                                                              click: function(){
                                                                  $.ajax({url: url,
                                                                          type: 'post',
                                                                          data: $('#holiday-dlg form').serialize()
                                                                         }).done(on_success)
                                                              }}]});
                           })
};

function add_holiday(worker) {
    params = {'title': 'Ajouter une absence', 'button_close': 'Fermer',
              'button_confirm': 'Ajouter', 'width': '550px'};

    on_success = function(response) {
        try {
            $.parseJSON(response);
            if(!response.err) {
                var result = response.content;
                var id = response.id;
                var li = $("

");
                var ul = $('

');
                $.each(result, function(i, e) {
                    var item = $('
' + e[1] + '
');
                    ul.append(item);
                });
                var button_edit = $('<button class="icon-edit" data-action="edit" data-id="' + id + '"></button>');
                var button_delete = $('<button class="icon-remove" data-action="delete" data-id="' + id + '"></button>');
                var actions = $('

');
                actions.append(button_edit, button_delete);
                ul.append(actions);
                li.append(ul);
                $("#holidays").append(li);
                $("#holiday-dlg").dialog("close");
            }
        } catch(e) {
            $('#holiday-dlg form').html(response);
        }

    };
    action('/cmpp/personnes/gestion/', worker, null, 'ajouter', null, null, null, params, on_success);
};

function delete_holiday(worker, holiday, url = '/cmpp/personnes/gestion/') {
    var selector = '#' + holiday + ' ul';
    var initial_color = $(selector).attr('style');
    var params = {'title': 'Supprimer une absence',
                  'button_close': 'Non', 'button_confirm': 'Oui',
                  'width': '450px'}

    on_success = function(response) {
        if(!response.err) {
            $('#' +  holiday).remove();
            $(selector).attr('style', initial_color);
            $("#holiday-dlg").dialog("close");
        }
    };
    action(url, worker, holiday, 'supprimer', selector, initial_color,
           '#f8b0b0', params, on_success);
};

function edit_holiday(worker, holiday, url = '/cmpp/personnes/gestion/') {
    var selector = '#' + holiday + ' ul';
    var initial_color = $(selector).attr('style');
    params = {'title': 'Éditer une absence',
              'button_close': 'Fermer', 'button_confirm': 'Mettre à jour',
              'width': '550px'}

    on_success = function(response) {
        try {
            $.parseJSON(response);
            if(!response.err) {
                $.each(response.content, function(i, e) {
                    $('#holidays #' + holiday + ' li.' + e[0]).html(e[1]);
                });
                $(selector).attr('style', initial_color);
                $("#holiday-dlg").dialog("close");
            }
        } catch(e) {
            console.log(e);
            $('#holiday-dlg form').html(response);
        }

    }
    action(url, worker, holiday, 'editer', selector, initial_color,  '#af7', params, on_success);
};

function edit_group_holiday(holiday) {
    var url = '/cmpp/personnes/conges/groupe/';
    edit_holiday(null, holiday, url);
}

function delete_group_holiday(holiday) {
    var url = '/cmpp/personnes/conges/groupe/';
    delete_holiday(null, holiday, url);
}<commit_msg>Handling properly functions default values(thanks webkit)<commit_after>function action(url, worker, on, action, selector, original_color, highlight_color, params, on_success) {
    if(on) {
        if(worker)
            url += worker + '/holidays/' + on + '/' + action + '/';
        else
            url += on + '/' + action;
        $(selector).attr('style', 'background: ' + highlight_color);
    } else {
        if(worker)
            url += worker + '/holidays/' + action;
        else
            url += action;
    }
    $("#holiday-dlg").load(url,
                           function() {
                               $(this).dialog({title: params.title,
                                               width: params.width,
                                               buttons: [{text: params.button_close,
                                                          click: function() {
                                                              $(this).dialog('close');
                                                              $(selector).attr('style', original_color);
                                                          }},{text: params.button_confirm,
                                                              click: function(){
                                                                  $.ajax({url: url,
                                                                          type: 'post',
                                                                          data: $('#holiday-dlg form').serialize()
                                                                         }).done(on_success)
                                                              }}]});
                           })
};

function add_holiday(worker) {
    params = {'title': 'Ajouter une absence', 'button_close': 'Fermer',
              'button_confirm': 'Ajouter', 'width': '550px'};

    on_success = function(response) {
        try {
            $.parseJSON(response);
            if(!response.err) {
                var result = response.content;
                var id = response.id;
                var li = $("

");
                var ul = $('

');
                $.each(result, function(i, e) {
                    var item = $('
' + e[1] + '
');
                    ul.append(item);
                });
                var button_edit = $('<button class="icon-edit" data-action="edit" data-id="' + id + '"></button>');
                var button_delete = $('<button class="icon-remove" data-action="delete" data-id="' + id + '"></button>');
                var actions = $('

');
                actions.append(button_edit, button_delete);
                ul.append(actions);
                li.append(ul);
                $("#holidays").append(li);
                $("#holiday-dlg").dialog("close");
            }
        } catch(e) {
            $('#holiday-dlg form').html(response);
        }

    };
    action('/cmpp/personnes/gestion/', worker, null, 'ajouter', null, null, null, params, on_success);
};

function delete_holiday(worker, holiday, url) {
    var url = url || '/cmpp/personnes/gestion/';
    var selector = '#' + holiday + ' ul';
    var initial_color = $(selector).attr('style');
    var params = {'title': 'Supprimer une absence',
                  'button_close': 'Non', 'button_confirm': 'Oui',
                  'width': '450px'}

    on_success = function(response) {
        if(!response.err) {
            $('#' +  holiday).remove();
            $(selector).attr('style', initial_color);
            $("#holiday-dlg").dialog("close");
        }
    };
    action(url, worker, holiday, 'supprimer', selector, initial_color,
           '#f8b0b0', params, on_success);
};

function edit_holiday(worker, holiday, url) {
    var url = url || '/cmpp/personnes/gestion/';
    var selector = '#' + holiday + ' ul';
    var initial_color = $(selector).attr('style');
    params = {'title': 'Éditer une absence',
              'button_close': 'Fermer', 'button_confirm': 'Mettre à jour',
              'width': '550px'}

    on_success = function(response) {
        try {
            $.parseJSON(response);
            if(!response.err) {
                $.each(response.content, function(i, e) {
                    $('#holidays #' + holiday + ' li.' + e[0]).html(e[1]);
                });
                $(selector).attr('style', initial_color);
                $("#holiday-dlg").dialog("close");
            }
        } catch(e) {
            console.log(e);
            $('#holiday-dlg form').html(response);
        }

    }
    action(url, worker, holiday, 'editer', selector, initial_color,  '#af7', params, on_success);
};

function edit_group_holiday(holiday) {
    var url = '/cmpp/personnes/conges/groupe/';
    edit_holiday(null, holiday, url);
};

function delete_group_holiday(holiday) {
    var url = '/cmpp/personnes/conges/groupe/';
    delete_holiday(null, holiday, url);
};<|endoftext|>


<commit_before>var support_email = "support@yourdomain.com";
var endpoint = "/feedback";

$(function() {

	var button = $("

feedback

").appendTo("body");

	button.click(function(e) {
		var overlay = $("

").appendTo("body");
		overlay.css("width", $(window).width() + "px").css("height", $(window).height() + "px");
		var dialog = $("

X

").appendTo("body");
		dialog.css("top", $(window).height() / 2 - 200 + "px").css("left", $(window).width() / 2 - 200 + "px");
		var content = dialog.find(".content");

		content.append("
Leave Feedback
");
		content.append("
Please leave us feedback using the form below. Your feedback will be sent directly to our development team.
");
		content.append("Type of feedback<select id='waterslide_type' name='type'><option value='bug'>Bug</option></select>");
		content.append("Please provide a title for the feedback<input type='text' id='waterslide_short' name='short' />");
		content.append("Please provide a detailed description of the idea or problem<textarea id='waterslide_long' name='long'></textarea>");
		content.append("<button id='waterslide_send'>Send Feedback</button>");

		e.stopPropagation();
	});

	$("#waterslide_dialog").live("click", function(e) {
		e.stopPropagation();
	});

	$("#waterslide_send").live("click", function(e) {
		$("#waterslide_send").addClass("disabled").text("Sending...");
		$.post(endpoint, {
			type: $("#waterslide_type").val(),
			short: $("#waterslide_short").val(),
			long: $("#waterslide_long").val()
		}, function(data) {
			if(data == "success") {
				$("#waterslide_dialog .content").html("
Leave Feedback

Thanks! Your feedback was sent successfully! We'll review it and take your suggestions into consideration.

Please note that we do not respond \
				individiually to all requests received via the feedback form. If you need immediate support, please email us at " + support_email + "
");
			}

			else {
				$("#waterslide_dialog .content").html("
Leave Feedback

Oh no! Something went wrong! Please get in touch with us at " + support_email + " instead. Sorry for the inconvenience!
");
			}
		});

		e.stopPropagation();

	});

	$("#waterslide_dialog .close").live("click", function() {
		$("#waterslide_dialog").remove();
		$("#waterslide_overlay").remove();
	});

	$("body").live("click", function() {
		$("#waterslide_dialog").remove();
		$("#waterslide_overlay").remove();
	});

});<commit_msg>Added 'idea' option<commit_after>var support_email = "support@yourdomain.com";
var endpoint = "/feedback";

$(function() {

	var button = $("

feedback

").appendTo("body");

	button.click(function(e) {
		var overlay = $("

").appendTo("body");
		overlay.css("width", $(window).width() + "px").css("height", $(window).height() + "px");
		var dialog = $("

X

").appendTo("body");
		dialog.css("top", $(window).height() / 2 - 200 + "px").css("left", $(window).width() / 2 - 200 + "px");
		var content = dialog.find(".content");

		content.append("
Leave Feedback
");
		content.append("
Please leave us feedback using the form below. Your feedback will be sent directly to our development team.
");
		content.append("Type of feedback<select id='waterslide_type' name='type'><option value='bug'>Bug</option><option value='idea'>Idea</option></select>");
		content.append("Please provide a title for the feedback<input type='text' id='waterslide_short' name='short' />");
		content.append("Please provide a detailed description of the idea or problem<textarea id='waterslide_long' name='long'></textarea>");
		content.append("<button id='waterslide_send'>Send Feedback</button>");

		e.stopPropagation();
	});

	$("#waterslide_dialog").live("click", function(e) {
		e.stopPropagation();
	});

	$("#waterslide_send").live("click", function(e) {
		$("#waterslide_send").addClass("disabled").text("Sending...");
		$.post(endpoint, {
			type: $("#waterslide_type").val(),
			short: $("#waterslide_short").val(),
			long: $("#waterslide_long").val()
		}, function(data) {
			if(data == "success") {
				$("#waterslide_dialog .content").html("
Leave Feedback

Thanks! Your feedback was sent successfully! We'll review it and take your suggestions into consideration.

Please note that we do not respond \
				individiually to all requests received via the feedback form. If you need immediate support, please email us at " + support_email + "
");
			}

			else {
				$("#waterslide_dialog .content").html("
Leave Feedback

Oh no! Something went wrong! Please get in touch with us at " + support_email + " instead. Sorry for the inconvenience!
");
			}
		});

		e.stopPropagation();

	});

	$("#waterslide_dialog .close").live("click", function() {
		$("#waterslide_dialog").remove();
		$("#waterslide_overlay").remove();
	});

	$("body").live("click", function() {
		$("#waterslide_dialog").remove();
		$("#waterslide_overlay").remove();
	});

});<|endoftext|>


<commit_before>function metaphone(word, phones){
    // +   original by: Greg Frazier
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // *     example 1: metaphone('Gnu');
    // *     returns 1: 'N'

    // As far as use of the String() constructor, author says "I vaguely remember something about Internet Explorer 6 giving me errors unless it was done that way"

	var wordlength = word.length,
        x = 0, tempchar = "",
        metaword = "";
	var removedbl = function(word){
		var wordlength = word.length,
		tempword = word.toLowerCase(),
		rebuilt,
		tempchar1, tempchar2,
		x;

		tempchar1 = tempword.charAt(0);
		rebuilt = tempchar1;
		for(x=1;x<wordlength;x++){
			tempchar2 = tempword.charAt(x);
			if(tempchar2 != tempchar1 || tempchar2 == 'c' || tempchar2 == 'g'){
				rebuilt += tempchar2;
			}
			tempchar1 = tempchar2;
		}
		return rebuilt;
	};
	var isVowel=function(a){
		switch(a.toLowerCase()) {
			case 'a': return true;
			case 'e': return true;
			case 'i': return true;
			case 'o': return true;
			case 'u': return true;
			default: return false;
		}
	};
	var tempword = removedbl(word.toLowerCase());

	//Special wh- case
	if(tempword.charAt(0) == 'w' && tempword.charAt(1) == 'h'){
		// Remove "h" and rebuild the string
		tempword = "w" + tempword.substr(2);
	}

	for(x=0; x<wordlength; x++){
		tempchar = String(tempword).charAt(x);
		if(x === 0 && x+1 <= wordlength){
			switch(tempchar){
				case 'a': if(tempword.charAt(x+1) == 'e'){ metaword += 'e'; }else{metaword += 'a';} break;
				case 'e': metaword += 'e'; break;
				case 'i': metaword += 'i'; break;
				case 'o': metaword += 'o'; break;
				case 'u': metaword += 'u'; break;
				case 'g': if(String(tempword).charAt(x+1) == 'n'){ x += 1; tempchar = String(tempword).charAt(x);} break;
				case 'k': if(String(tempword).charAt(x+1) == 'n'){ x += 1; tempchar = String(tempword).charAt(x);} break;
				case 'p': if(String(tempword).charAt(x+1) == 'n'){ x += 1; tempchar = String(tempword).charAt(x);} break;
				case 'w': if(String(tempword).charAt(x+1) == 'r'){ x += 1; tempchar = String(tempword).charAt(x); break;} break;
			}
		}
		if(isVowel(tempchar) === false){
			switch(tempchar){
				case 'b': if(String(tempword).charAt(x-1) == 'm'){ break;}else{metaword += 'b';} break;
				case 'c': if(x+1 <= wordlength){
							if(String(tempword).charAt(x+1) == 'h' && String(tempword).charAt(x-1) != 's'){
                                if (x === 0 && (x+2 <= wordlength) && isVowel(String(tempword).charAt(x+2))) {
                                    metaword += 'k';
                                } else {
                                    metaword += 'x';
                                }
                             }else if(String(tempword).charAt(x+1) == 'i' && String(tempword).charAt(x+2) == 'a'){ metaword += 'x';}
							else if(String(tempword).charAt(x+1) == 'i' || String(tempword).charAt(x+1) == 'e' || String(tempword).charAt(x+1) == 'y'){
								if(x > 0){
									if(String(tempword).charAt(x-1) == 's'){
										break;
									}else{
										metaword += 's';
									}
								}else{
									metaword += 's';
								}
							}else{
								metaword += 'k';
							}
						  }else{
							metaword += 'k';
						  }
						  break;
				case 'd': if(x+2 <= wordlength){
							if(String(tempword).charAt(x+1) == 'g'){
								if(String(tempword).charAt(x+2) == 'e' || String(tempword).charAt(x+2) == 'y' || String(tempword).charAt(x+2) == 'i'){
									metaword += 'j';
									x += 2;
								}else{
									metaword += 't';
								}
							}else{
								metaword += 't';
							}
						  }else{
								metaword += 't';
						  }
						  break;
				case 'f': metaword += 'f'; break;
				case 'g': if(x < wordlength){
							if((String(tempword).charAt(x+1) == 'n' && x+1 == wordlength - 1) || (String(tempword).charAt(x+1) == 'n' && String(tempword).charAt(x+2) == 's' && x+2 == wordlength - 1)){break;}
							if(String(tempword).charAt(x+1) == 'n' && String(tempword).charAt(x+2) == 'e' && String(tempword).charAt(x+3) == 'd' && x+3 == wordlength - 1){break;}
							if(String(tempword).charAt(x-1) == 'n' && String(tempword).charAt(x-2) == 'i' && x == wordlength - 1){break;}
							if(String(tempword).charAt(x+1) == 'h' && x+1 <= wordlength-1 && String(tempword).charAt(x-1) == 'u' && String(tempword).charAt(x-2) == 'o'){metaword += 'f';break;}
							if(String(tempword).charAt(x+1) == 'h' && x+2 <= wordlength){if(isVowel(String(tempword).charAt(x+2)) === false){break; /*silent*/ }else{metaword += 'k';}}
							else if(x+1 == wordlength){if(String(tempword).charAt(x+1) == 'n'){break;}else{metaword += 'k';}}
							else if(x+3 == wordlength){if(String(tempword).charAt(x+1) == 'n' && String(tempword).charAt(x+2) == 'e' && String(tempword).charAt(x+3) == 'd'){}else{metaword += 'k';}}
							else if(x+1 <= wordlength){if(String(tempword).charAt(x+1) == 'i' || String(tempword).charAt(x+1) == 'e' || String(tempword).charAt(x+1) == 'y'){
													if(String(tempword).charAt(x-1) != 'g'){ metaword += 'j';}
													}else if(x > 0){ if(String(tempword).charAt(x-1) == 'd'){
														switch(String(tempword).charAt(x+1)){
															case 'e':
															case 'y':
															case 'i': break;
															default: metaword += 'k';
														}
														}else{metaword += 'k';}
													}else{metaword += 'k';}
							}else{
								metaword += 'k';
							}
						  }else{
								metaword += 'k';
						  }
						  break;
				case 'm': metaword += 'm'; break;
				case 'j': metaword += 'j'; break;
				case 'n': metaword += 'n'; break;
				case 'q': metaword += 'k'; break;
				case 'r': metaword += 'r'; break;
				case 'l': metaword += 'l'; break;
				case 'v': metaword += 'f'; break;
				case 'z': metaword += 's'; break;
				case 'x': if(x === 0){metaword += 's';}else{metaword += 'ks';} break;
				case 'm': metaword += 'm'; break;
				case 'k': if(x > 0){ if(String(tempword).charAt(x-1) != 'c'){metaword += 'k';}}else{metaword += 'k';} break;
				case 'p': if(x+1 <= wordlength){if(String(tempword).charAt(x+1) == 'h'){metaword += 'f';}else{metaword +='p';}}else{metaword += 'p';} break;
				case 'y': if(x+1 <= wordlength){if(isVowel(String(tempword).charAt(x+1)) === true){metaword += 'y';}}else{metaword += 'y';} break;
				case 'h': if(x === 0 || ['c', 's', 'p', 't', 'g'].indexOf(String(tempword).charAt(x-1)) === -1) {
                            if(isVowel(String(tempword).charAt(x+1)) === true){metaword += 'h';}} break;
				case 's': if(x+1 <= wordlength){if(String(tempword).charAt(x+1) == 'h'){ metaword += 'x'; }
							else if(x+2 <= wordlength){if(String(tempword).charAt(x+1) == 'i'){if(String(tempword).charAt(x+2) == 'o' || String(tempword).charAt(x+2) == 'a'){metaword += 'x';}else{metaword += 's';}
							}else{metaword += 's';}}else{metaword += 's';}}else{metaword += 's';} break;
				case 't': if(x+1 <= wordlength){if(String(tempword).charAt(x+1) == 'h'){ metaword += '0'; }
							else if(x+2 <= wordlength){if(String(tempword).charAt(x+1) == 'i'){if(String(tempword).charAt(x+2) == 'o' || String(tempword).charAt(x+2) == 'a'){metaword += 'x';}else{metaword += 't';}
							}else{metaword += 't';}}else{metaword += 't';}}else{metaword += 't';} break;
				case 'w': if(x+1 <= wordlength){if(isVowel(String(tempword).charAt(x+1)) === true){metaword += 'w';}} break;
			}
		}
	}

    phones = parseInt(phones, 10);
    if (metaword.length > phones) {
        return metaword.substr(0, phones).toUpperCase();
    }
	return metaword.toUpperCase();
}
<commit_msg>Clean-up comment<commit_after>function metaphone(word, phones){
    // +   original by: Greg Frazier
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // *     example 1: metaphone('Gnu');
    // *     returns 1: 'N'

    // As far as use of the String() constructor, the author recalls IE 6 giving errors otherwise

	var wordlength = word.length,
        x = 0, tempchar = "",
        metaword = "";
	var removedbl = function(word){
		var wordlength = word.length,
		tempword = word.toLowerCase(),
		rebuilt,
		tempchar1, tempchar2,
		x;

		tempchar1 = tempword.charAt(0);
		rebuilt = tempchar1;
		for(x=1;x<wordlength;x++){
			tempchar2 = tempword.charAt(x);
			if(tempchar2 != tempchar1 || tempchar2 == 'c' || tempchar2 == 'g'){
				rebuilt += tempchar2;
			}
			tempchar1 = tempchar2;
		}
		return rebuilt;
	};
	var isVowel=function(a){
		switch(a.toLowerCase()) {
			case 'a': return true;
			case 'e': return true;
			case 'i': return true;
			case 'o': return true;
			case 'u': return true;
			default: return false;
		}
	};
	var tempword = removedbl(word.toLowerCase());

	//Special wh- case
	if(tempword.charAt(0) == 'w' && tempword.charAt(1) == 'h'){
		// Remove "h" and rebuild the string
		tempword = "w" + tempword.substr(2);
	}

	for(x=0; x<wordlength; x++){
		tempchar = String(tempword).charAt(x);
		if(x === 0 && x+1 <= wordlength){
			switch(tempchar){
				case 'a': if(tempword.charAt(x+1) == 'e'){ metaword += 'e'; }else{metaword += 'a';} break;
				case 'e': metaword += 'e'; break;
				case 'i': metaword += 'i'; break;
				case 'o': metaword += 'o'; break;
				case 'u': metaword += 'u'; break;
				case 'g': if(String(tempword).charAt(x+1) == 'n'){ x += 1; tempchar = String(tempword).charAt(x);} break;
				case 'k': if(String(tempword).charAt(x+1) == 'n'){ x += 1; tempchar = String(tempword).charAt(x);} break;
				case 'p': if(String(tempword).charAt(x+1) == 'n'){ x += 1; tempchar = String(tempword).charAt(x);} break;
				case 'w': if(String(tempword).charAt(x+1) == 'r'){ x += 1; tempchar = String(tempword).charAt(x); break;} break;
			}
		}
		if(isVowel(tempchar) === false){
			switch(tempchar){
				case 'b': if(String(tempword).charAt(x-1) == 'm'){ break;}else{metaword += 'b';} break;
				case 'c': if(x+1 <= wordlength){
							if(String(tempword).charAt(x+1) == 'h' && String(tempword).charAt(x-1) != 's'){
                                if (x === 0 && (x+2 <= wordlength) && isVowel(String(tempword).charAt(x+2))) {
                                    metaword += 'k';
                                } else {
                                    metaword += 'x';
                                }
                             }else if(String(tempword).charAt(x+1) == 'i' && String(tempword).charAt(x+2) == 'a'){ metaword += 'x';}
							else if(String(tempword).charAt(x+1) == 'i' || String(tempword).charAt(x+1) == 'e' || String(tempword).charAt(x+1) == 'y'){
								if(x > 0){
									if(String(tempword).charAt(x-1) == 's'){
										break;
									}else{
										metaword += 's';
									}
								}else{
									metaword += 's';
								}
							}else{
								metaword += 'k';
							}
						  }else{
							metaword += 'k';
						  }
						  break;
				case 'd': if(x+2 <= wordlength){
							if(String(tempword).charAt(x+1) == 'g'){
								if(String(tempword).charAt(x+2) == 'e' || String(tempword).charAt(x+2) == 'y' || String(tempword).charAt(x+2) == 'i'){
									metaword += 'j';
									x += 2;
								}else{
									metaword += 't';
								}
							}else{
								metaword += 't';
							}
						  }else{
								metaword += 't';
						  }
						  break;
				case 'f': metaword += 'f'; break;
				case 'g': if(x < wordlength){
							if((String(tempword).charAt(x+1) == 'n' && x+1 == wordlength - 1) || (String(tempword).charAt(x+1) == 'n' && String(tempword).charAt(x+2) == 's' && x+2 == wordlength - 1)){break;}
							if(String(tempword).charAt(x+1) == 'n' && String(tempword).charAt(x+2) == 'e' && String(tempword).charAt(x+3) == 'd' && x+3 == wordlength - 1){break;}
							if(String(tempword).charAt(x-1) == 'n' && String(tempword).charAt(x-2) == 'i' && x == wordlength - 1){break;}
							if(String(tempword).charAt(x+1) == 'h' && x+1 <= wordlength-1 && String(tempword).charAt(x-1) == 'u' && String(tempword).charAt(x-2) == 'o'){metaword += 'f';break;}
							if(String(tempword).charAt(x+1) == 'h' && x+2 <= wordlength){if(isVowel(String(tempword).charAt(x+2)) === false){break; /*silent*/ }else{metaword += 'k';}}
							else if(x+1 == wordlength){if(String(tempword).charAt(x+1) == 'n'){break;}else{metaword += 'k';}}
							else if(x+3 == wordlength){if(String(tempword).charAt(x+1) == 'n' && String(tempword).charAt(x+2) == 'e' && String(tempword).charAt(x+3) == 'd'){}else{metaword += 'k';}}
							else if(x+1 <= wordlength){if(String(tempword).charAt(x+1) == 'i' || String(tempword).charAt(x+1) == 'e' || String(tempword).charAt(x+1) == 'y'){
													if(String(tempword).charAt(x-1) != 'g'){ metaword += 'j';}
													}else if(x > 0){ if(String(tempword).charAt(x-1) == 'd'){
														switch(String(tempword).charAt(x+1)){
															case 'e':
															case 'y':
															case 'i': break;
															default: metaword += 'k';
														}
														}else{metaword += 'k';}
													}else{metaword += 'k';}
							}else{
								metaword += 'k';
							}
						  }else{
								metaword += 'k';
						  }
						  break;
				case 'm': metaword += 'm'; break;
				case 'j': metaword += 'j'; break;
				case 'n': metaword += 'n'; break;
				case 'q': metaword += 'k'; break;
				case 'r': metaword += 'r'; break;
				case 'l': metaword += 'l'; break;
				case 'v': metaword += 'f'; break;
				case 'z': metaword += 's'; break;
				case 'x': if(x === 0){metaword += 's';}else{metaword += 'ks';} break;
				case 'm': metaword += 'm'; break;
				case 'k': if(x > 0){ if(String(tempword).charAt(x-1) != 'c'){metaword += 'k';}}else{metaword += 'k';} break;
				case 'p': if(x+1 <= wordlength){if(String(tempword).charAt(x+1) == 'h'){metaword += 'f';}else{metaword +='p';}}else{metaword += 'p';} break;
				case 'y': if(x+1 <= wordlength){if(isVowel(String(tempword).charAt(x+1)) === true){metaword += 'y';}}else{metaword += 'y';} break;
				case 'h': if(x === 0 || ['c', 's', 'p', 't', 'g'].indexOf(String(tempword).charAt(x-1)) === -1) {
                            if(isVowel(String(tempword).charAt(x+1)) === true){metaword += 'h';}} break;
				case 's': if(x+1 <= wordlength){if(String(tempword).charAt(x+1) == 'h'){ metaword += 'x'; }
							else if(x+2 <= wordlength){if(String(tempword).charAt(x+1) == 'i'){if(String(tempword).charAt(x+2) == 'o' || String(tempword).charAt(x+2) == 'a'){metaword += 'x';}else{metaword += 's';}
							}else{metaword += 's';}}else{metaword += 's';}}else{metaword += 's';} break;
				case 't': if(x+1 <= wordlength){if(String(tempword).charAt(x+1) == 'h'){ metaword += '0'; }
							else if(x+2 <= wordlength){if(String(tempword).charAt(x+1) == 'i'){if(String(tempword).charAt(x+2) == 'o' || String(tempword).charAt(x+2) == 'a'){metaword += 'x';}else{metaword += 't';}
							}else{metaword += 't';}}else{metaword += 't';}}else{metaword += 't';} break;
				case 'w': if(x+1 <= wordlength){if(isVowel(String(tempword).charAt(x+1)) === true){metaword += 'w';}} break;
			}
		}
	}

    phones = parseInt(phones, 10);
    if (metaword.length > phones) {
        return metaword.substr(0, phones).toUpperCase();
    }
	return metaword.toUpperCase();
}
<|endoftext|>


<commit_before>var expect = require('chai').expect;
const assert = require('chai').assert;
var mother = require('../health_modules/mother/motherProgramEncounterDecision');
const ProgramEncounter = require("./Entities").ProgramEncounter;
const ProgramEnrolment = require("./Entities").ProgramEnrolment;
const C = require('../health_modules/common');

describe('High Risk Pregnancy Determination', function () {
    var enrolment;
    var programEncounter;
    var referenceDate;

    beforeEach(function () {
        referenceDate = new Date(2017, 6, 6);
        programEncounter = new ProgramEncounter("ANC", referenceDate);
        enrolment = new ProgramEnrolment('Mother', [programEncounter]);
        enrolment.setObservation('Last Menstrual Period', new Date(2017, 1, 10));
        programEncounter.programEnrolment = enrolment;
    });

    it('Check for mild pre-eclampsia ', function () {
        programEncounter.setObservation("Hb", 4).setObservation("Systolic", 150).setObservation("Diastolic", 90);
        programEncounter.setObservation("Urine Albumin", '+1');
        var decisions = mother.getDecisions(programEncounter, referenceDate).encounterDecisions;
        var complicationValues = C.findValue(decisions, 'High Risk Conditions');
        expect(complicationValues.indexOf("Pregnancy Induced Hypertension")).is.not.equal(-1);
        expect(complicationValues.indexOf("Mild Pre-Eclampsia")).is.not.equal(-1);
    });

    it('Check for eclampsia ', function () {
        programEncounter.setObservation("Hb", 4).setObservation("Systolic", 150).setObservation("Diastolic", 90);
        programEncounter.setObservation("Convulsions", true);
        programEncounter.setObservation("Urine Albumin", '+1');
        var decisions = mother.getDecisions(programEncounter, referenceDate).encounterDecisions;
        var complicationValues = C.findValue(decisions, 'High Risk Conditions');
        expect(complicationValues.indexOf("Pregnancy Induced Hypertension")).is.not.equal(-1);
        expect(complicationValues.indexOf("Eclampsia")).is.not.equal(-1);
    });

    it('Check for severe pre-eclampsia ', function () {
        programEncounter.setObservation("Hb", 4).setObservation("Systolic", 150).setObservation("Diastolic", 90);
        programEncounter.setObservation("Urine Albumin", '+3');
        var decisions = mother.getDecisions(programEncounter, referenceDate).encounterDecisions;
        var complicationValues = C.findValue(decisions, 'High Risk Conditions');
        expect(complicationValues.indexOf("Pregnancy Induced Hypertension")).is.not.equal(-1);
        expect(complicationValues.indexOf("Severe Pre-Eclampsia")).is.not.equal(-1);
    });

    it('Check for Anemia based on Hb result', function () {
        programEncounter.setObservation("Hb", 4).setObservation("Systolic", 150).setObservation("Diastolic", 90);
        var decisions = mother.getDecisions(programEncounter, referenceDate).encounterDecisions;
        var complicationValues = C.findValue(decisions, 'High Risk Conditions');
        expect(complicationValues.indexOf("Severe Anemia")).is.not.equal(-1);
    });

    it('no high risk condition', () => {
        var decisions = mother.getDecisions(programEncounter, new Date(2017, 2, 10)).encounterDecisions;
        var complicationValues = C.findValue(decisions, 'High Risk Conditions');
        expect(complicationValues).is.equal(null);
    });
});
<commit_msg>Minor refactoring<commit_after>var expect = require('chai').expect;
const assert = require('chai').assert;
var mother = require('../health_modules/mother/motherProgramEncounterDecision');
const ProgramEncounter = require("./Entities").ProgramEncounter;
const ProgramEnrolment = require("./Entities").ProgramEnrolment;
const C = require('../health_modules/common');

describe('High Risk Pregnancy Determination', function () {
    let enrolment, programEncounter, referenceDate;

    beforeEach(function () {
        referenceDate = new Date(2017, 6, 6);
        programEncounter = new ProgramEncounter("ANC", referenceDate);
        enrolment = new ProgramEnrolment('Mother', [programEncounter]);
        enrolment.setObservation('Last Menstrual Period', new Date(2017, 1, 10));
        programEncounter.programEnrolment = enrolment;
    });

    it('Check for mild pre-eclampsia ', function () {
        programEncounter.setObservation("Hb", 4).setObservation("Systolic", 150).setObservation("Diastolic", 90);
        programEncounter.setObservation("Urine Albumin", '+1');
        var decisions = mother.getDecisions(programEncounter, referenceDate).encounterDecisions;
        var complicationValues = C.findValue(decisions, 'High Risk Conditions');
        expect(complicationValues.indexOf("Pregnancy Induced Hypertension")).is.not.equal(-1);
        expect(complicationValues.indexOf("Mild Pre-Eclampsia")).is.not.equal(-1);
    });

    it('Check for eclampsia ', function () {
        programEncounter.setObservation("Hb", 4).setObservation("Systolic", 150).setObservation("Diastolic", 90);
        programEncounter.setObservation("Convulsions", true);
        programEncounter.setObservation("Urine Albumin", '+1');
        var decisions = mother.getDecisions(programEncounter, referenceDate).encounterDecisions;
        var complicationValues = C.findValue(decisions, 'High Risk Conditions');
        expect(complicationValues.indexOf("Pregnancy Induced Hypertension")).is.not.equal(-1);
        expect(complicationValues.indexOf("Eclampsia")).is.not.equal(-1);
    });

    it('Check for severe pre-eclampsia ', function () {
        programEncounter.setObservation("Hb", 4).setObservation("Systolic", 150).setObservation("Diastolic", 90);
        programEncounter.setObservation("Urine Albumin", '+3');
        var decisions = mother.getDecisions(programEncounter, referenceDate).encounterDecisions;
        var complicationValues = C.findValue(decisions, 'High Risk Conditions');
        expect(complicationValues.indexOf("Pregnancy Induced Hypertension")).is.not.equal(-1);
        expect(complicationValues.indexOf("Severe Pre-Eclampsia")).is.not.equal(-1);
    });

    it('Check for Anemia based on Hb result', function () {
        programEncounter.setObservation("Hb", 4).setObservation("Systolic", 150).setObservation("Diastolic", 90);
        var decisions = mother.getDecisions(programEncounter, referenceDate).encounterDecisions;
        var complicationValues = C.findValue(decisions, 'High Risk Conditions');
        expect(complicationValues.indexOf("Severe Anemia")).is.not.equal(-1);
    });

    it('no high risk condition', () => {
        var decisions = mother.getDecisions(programEncounter, new Date(2017, 2, 10)).encounterDecisions;
        var complicationValues = C.findValue(decisions, 'High Risk Conditions');
        expect(complicationValues).is.equal(null);
    });
});
<|endoftext|>