<commit_before>// Cover up createjs with cutie. Internally. we'll use createjs so we know what's
// ours and what isn't. Externally, we don't want to confuse the user by having
// them use two different namespaces.
this.cutie = createjs;

(function(module) {
    var _scenes = {};
    var _activeScene = {};
    var _canvas = {};
    var _stage = {};

    // ======================================================
    // PUBLIC
    // ======================================================
    /**
     * Starts the game.
     * @param  {cutie.Scene} scene
     *         The scene to start the game with.
     * @param  {Object} props
     *         A series of properties that affects how the scene is set.
     *         "canvasId": The id of the canvas element you want to display
     *                     your game in.
     *         "preloadScenes": Which additional scenes to preload when you
     *                          load this scene. The progress bar for this
     *                          scene will be representative of this list's
     *                          preload progress.
     */
    module.start = function(scene, props) {
        cutie.Log.v("cutie.start()");

        props = props || {};

        // Fill in stuff using the properties the user gave
        _canvas = document.getElementById(props.canvasId || "js-canvas")
        _stage = new createjs.Stage(_canvas);
        createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED;
        createjs.Ticker.setFPS(props.fps || 60);

        // Add the listener
        createjs.Ticker.addEventListener("tick", tick);

        // Set the scene
        this.setScene(scene, props);
    }

    /**
     * Takes the specified scene and sets it as the active scene. This will
     * now be the scene that receives calls to its tick() function. If it is
     * not already preloaded, it will be preloaded
     * @param {cutie.Scene} scene
     *        The scene to be made active.
     * @param {Object} props
     *        A series of properties that affects how the scene is set.
     *        "preloadScenes": Which additional scenes to preload when you
     *                         load this scene. The progress bar for this
     *                         scene will be representative of this list's
     *                         preload progress.
     */
    module.setScene = function(sceneName, props) {
        cutie.Log.v("cutie.setScene()");

        props = props || {};

        // Set it as the active scene
        _activeScene = getScene(sceneName);

        // Build the list of scenes to preload and then preload them
        var preloadList = props.preloadScenes || [];
        preloadList.unshift(sceneName);
        preloadList = getScenes(preloadList);
        preloadScenes(preloadList);

        // Add it to the stage
        _stage.addChild(_activeScene);
    }

    /**
     * Adds the scene to the list of registered scenes.
     * @param  {cutie.Scene} scene
     *         The scene you want to register.
     * @param  {String} name
     *         The name you want to associate with the scene. This is the
     *         name you will use when setting and preloading scenes.
     */
    module.registerScene = function(scene, name) {
        if (_scenes[name]) {
            cutie.Log.w("You registered a scene called '" + name + "', but there was already a scene registered with that name. It was overwritten.");
        }
        _scenes[name] = scene;
    }

    // ======================================================
    // PRIVATE
    // ======================================================
    function tick() {
        _activeScene.tick();
        _stage.update();
    }

    /**
     * Preloads a list of scenes, and adds the preload event listeners
     * to the first scene in the list
     * @param  {cutie.Scene} scenes
     *         List of scenes to be preloaded.
     */
    function preloadScenes(scenes) {
        var loader = new createjs.LoadQueue();
        loader.installPlugin(createjs.Sound);
        loader.on("complete", scenes[0].onPreloadComplete.bind(scenes[0], scenes), scenes[0]);
        loader.on("progress", scenes[0].onPreloadProgress, scenes[0]);

        // Have all of the scene add on the the same LoadQueue
        for (var i = 0; i < scenes.length; i++) {
            if (!scenes[i].isPreloaded) {
                // Create a new LoadQueue and give it to the scene to preload
                scenes[i].preload(loader);
            }
        }

        // Kick-off the loading (just in case any files were added to the queue and set to not immmediately load)
        loader.load();
    }

    function getScenes(sceneNames) {
        var scenes = [];
        for (var i = 0; i < sceneNames.length; i++) {
            scenes.push(getScene(sceneNames[i]));
        }
        return scenes;
    }

    function getScene(sceneName) {
        var scene = _scenes[sceneName];
        if (!scene) {
            cutie.Log.e("The scene '" + sceneName + "' does not exist.");
            return null;
        }
        return scene;
    }
})(this.cutie);<commit_msg>Made it so the preload steps are skipped if all of the scenes are already loaded.<commit_after>// Cover up createjs with cutie. Internally. we'll use createjs so we know what's
// ours and what isn't. Externally, we don't want to confuse the user by having
// them use two different namespaces.
this.cutie = createjs;

(function(module) {
    var _scenes = {};
    var _activeScene = {};
    var _canvas = {};
    var _stage = {};

    // ======================================================
    // PUBLIC
    // ======================================================
    /**
     * Starts the game.
     * @param  {cutie.Scene} scene
     *         The scene to start the game with.
     * @param  {Object} props
     *         A series of properties that affects how the scene is set.
     *         "canvasId": The id of the canvas element you want to display
     *                     your game in.
     *         "preloadScenes": Which additional scenes to preload when you
     *                          load this scene. The progress bar for this
     *                          scene will be representative of this list's
     *                          preload progress.
     */
    module.start = function(scene, props) {
        cutie.Log.v("cutie.start()");

        props = props || {};

        // Fill in stuff using the properties the user gave
        _canvas = document.getElementById(props.canvasId || "js-canvas")
        _stage = new createjs.Stage(_canvas);
        createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED;
        createjs.Ticker.setFPS(props.fps || 60);

        // Add the listener
        createjs.Ticker.addEventListener("tick", tick);

        // Set the scene
        this.setScene(scene, props);
    }

    /**
     * Takes the specified scene and sets it as the active scene. This will
     * now be the scene that receives calls to its tick() function. If it is
     * not already preloaded, it will be preloaded
     * @param {cutie.Scene} scene
     *        The scene to be made active.
     * @param {Object} props
     *        A series of properties that affects how the scene is set.
     *        "preloadScenes": Which additional scenes to preload when you
     *                         load this scene. The progress bar for this
     *                         scene will be representative of this list's
     *                         preload progress.
     */
    module.setScene = function(sceneName, props) {
        cutie.Log.v("cutie.setScene()");

        props = props || {};

        // Remove the previously active scene
        _stage.removeChild(_activeScene);

        // Set it as the active scene
        _activeScene = getScene(sceneName);

        // Build the list of scenes to preload and then preload them
        var preloadList = props.preloadScenes || [];
        preloadList.unshift(sceneName);
        preloadList = getScenes(preloadList);
        preloadScenes(preloadList);

        // Add it to the stage
        _stage.addChild(_activeScene);
    }

    /**
     * Adds the scene to the list of registered scenes.
     * @param  {cutie.Scene} scene
     *         The scene you want to register.
     * @param  {String} name
     *         The name you want to associate with the scene. This is the
     *         name you will use when setting and preloading scenes.
     */
    module.registerScene = function(scene, name) {
        if (_scenes[name]) {
            cutie.Log.w("You registered a scene called '" + name + "', but there was already a scene registered with that name. It was overwritten.");
        }
        _scenes[name] = scene;
    }

    // ======================================================
    // PRIVATE
    // ======================================================
    function tick() {
        _activeScene.tick();
        _stage.update();
    }

    /**
     * Preloads a list of scenes, and adds the preload event listeners
     * to the first scene in the list
     * @param  {cutie.Scene} scenes
     *         List of scenes to be preloaded.
     */
    function preloadScenes(scenes) {
        var loader = new createjs.LoadQueue();
        loader.installPlugin(createjs.Sound);

        // Have all of the scene add onto the the same LoadQueue
        var needsPreload = false;
        for (var i = 0; i < scenes.length; i++) {
            if (!scenes[i].isPreloaded) {
                // Create a new LoadQueue and give it to the scene to preload
                scenes[i].preload(loader);
                needsPreload = true;
            }
        }

        if (needsPreload) {
            loader.on("complete", scenes[0].onPreloadComplete.bind(scenes[0], scenes), scenes[0]);
            loader.on("progress", scenes[0].onPreloadProgress, scenes[0]);

            // Kick-off the loading (just in case any files were added to the queue and set to not immmediately load)
            loader.load();
        }
        else {
            scenes[0].init();
        }
    }

    function getScenes(sceneNames) {
        var scenes = [];
        for (var i = 0; i < sceneNames.length; i++) {
            scenes.push(getScene(sceneNames[i]));
        }
        return scenes;
    }

    function getScene(sceneName) {
        var scene = _scenes[sceneName];
        if (!scene) {
            cutie.Log.e("The scene '" + sceneName + "' does not exist.");
            return null;
        }
        return scene;
    }
})(this.cutie);<|endoftext|>


<commit_before><commit_msg>Ignore non-primary touch events.<commit_after><|endoftext|>


<commit_before>/**
 * @module      app
 * @author      Reydel Leon Machado
 * @copyright   (c) 2015 Reydel Leon Machado
 * @license     Licensed under MIT license
 */

var LatestBuildsTable = React.createClass({
    render: function () {
        var rows = [];
        this.props.builds.forEach(function (build) {
            rows.push(<BuildRow build={build}/>);
        });

        return (

                        Build #
                        Project Name
                        Git Commit
                        Status
                        Duration [hh:mm:ss]

                        {rows}

        );
    }
});

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

                    {this.props.build.id}
                    {this.props.build.projectName}
                    {this.props.build.gitCommit}
                    {this.props.build.status}
                    {this.props.build.duration}

        );
    }
});

var builds = [
    { id: 1, projectName: "Project X", gitCommit: "2827771e1e12", status: "In Progress", duration: "00:00:32" },
    { id: 2, projectName: "Continuum", gitCommit: "2827771e1e12", status: "Failed", duration: "00:00:32" },
    { id: 3, projectName: "Space X", gitCommit: "2827771e1e12", status: "Completed", duration: "00:00:32" },
    { id: 4, projectName: "Craft", gitCommit: "2827771e1e12", status: "Completed", duration: "00:00:32" },
    { id: 5, projectName: "mentor", gitCommit: "2827771e1e12", status: "Failed", duration: "00:00:32" },
    { id: 6, projectName: "Xoom", gitCommit: "2827771e1e12", status: "Completed", duration: "00:00:32" },
    { id: 7, projectName: "Bridge", gitCommit: "2827771e1e12", status: "Failed", duration: "00:00:32" },
    { id: 8, projectName: "Futoba", gitCommit: "2827771e1e12", status: "Completed", duration: "00:00:32" },
    { id: 9, projectName: "Babayaga", gitCommit: "2827771e1e12", status: "Completed", duration: "00:00:32" }
];

React.render(<LatestBuildsTable builds={builds}/>, document.getElementById('latest-builds-table-container'));<commit_msg>Finished app<commit_after>/**
 * @module      app
 * @author      Reydel Leon Machado
 * @copyright   (c) 2015 Reydel Leon Machado
 * @license     Licensed under MIT license
 */

var FilterableBuildTable = React.createClass({
    getInitialState: function () {
        return {
            searchTerm: ''
        }
    },
    handleUserInput: function (searchTerm) {
        this.setState({
            searchTerm: searchTerm
        });
    },
    render: function () {
        return (

                    <SearchBox
                            searchTerm={this.state.searchTerm}
                            onUserInput={this.handleUserInput}
                            />
                    <LatestBuildsTable
                            builds={this.props.builds}
                            searchTerm={this.state.searchTerm}/>

        );
    }
});

var SearchBox = React.createClass({
    handleChange: function () {
        this.props.onUserInput(
                this.refs.searchTermInput.getDOMNode().value
        );
    },
    render: function () {
        return (
                <form>
                    <input
                            type="text"
                            placeholder="Search..."
                            value={this.props.searchTerm}
                            ref="searchTermInput"
                            onChange={this.handleChange}
                            />
                </form>
        );
    }
});

var LatestBuildsTable = React.createClass({
    render: function () {
        var rows = [];
        this.props.builds.forEach(function (build) {
            if (build.projectName.indexOf(this.props.searchTerm) === -1) {
                return;
            }

            rows.push(<BuildRow build={build}/>);
        }.bind(this));

        return (

                        Build #
                        Project Name
                        Git Commit
                        Status
                        Duration [hh:mm:ss]

                    {rows}

        );
    }
});

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

                    {this.props.build.id}
                    {this.props.build.projectName}
                    {this.props.build.gitCommit}
                    {this.props.build.status}
                    {this.props.build.duration}

        );
    }
});

var builds = [
    { id: 1, projectName: "Space X", gitCommit: "2827771e1e12", status: "In Progress", duration: "00:00:32" },
    { id: 2, projectName: "Continuum", gitCommit: "2827771e1e12", status: "Failed", duration: "00:00:32" },
    { id: 3, projectName: "Space X", gitCommit: "2827771e1e12", status: "Completed", duration: "00:00:32" },
    { id: 4, projectName: "Craft", gitCommit: "2827771e1e12", status: "Completed", duration: "00:00:32" },
    { id: 5, projectName: "mentor", gitCommit: "2827771e1e12", status: "Failed", duration: "00:00:32" },
    { id: 6, projectName: "Xoom", gitCommit: "2827771e1e12", status: "Completed", duration: "00:00:32" },
    { id: 7, projectName: "Bridge", gitCommit: "2827771e1e12", status: "Failed", duration: "00:00:32" },
    { id: 8, projectName: "Futoba", gitCommit: "2827771e1e12", status: "Completed", duration: "00:00:32" },
    { id: 9, projectName: "Babayaga", gitCommit: "2827771e1e12", status: "Completed", duration: "00:00:32" }
];

React.render(<FilterableBuildTable builds={builds}/>, document.getElementById('latest-builds-table-container'));<|endoftext|>


<commit_before>/*
 * jquery.animateNumber.js - jquery number animation plugin
 * Copyright (C) 2013, Robert Kajic (robert@kajic.com)
 * http://kajic.com
 *
 * Used on elements that have a number as content (integer or float)
 * to animate the number to a new value over a short period of time.
 *
 * Licensed under the MIT License.
 *
 * Date: 2013-01-08
 * Version: 0.1
 */

(function ($, undefined) {

	var defaults = {
		duration : 5000,
		easing: "swing",
		animateOpacity: true,
		intStepDecimals: 0,
		intEndDecimals: 0,
		floatStepDecimals: 4,
		floatEndDecimals: 1,
		format: "default",
		currencyIndicator: "$",
		currencyGroupSeparator: ",",
		currencyDecimalSeparator: ".",
		callback: function() {}
	};

	function round(number, decimals) {
		return Math.round(number*Math.pow(10,decimals))/Math.pow(10,decimals);
	}

	function formatCurrency(number, options) {
		if (!isNaN(number)) {
			var whole = Math.floor(number);
			return options.currencyIndicator + whole.toLocaleString() + options.currencyDecimalSeparator + (number - whole).toFixed(2).split('.')[1];
		}

	}

	function isInt(number) {
		return /^-?[\d]+$/.test(number);
	}

	$.fn.animateNumber = function(value, options, callback) {
		if (typeof options === "function") {
			callback = options;
			options = {};
		}
		options = $.extend({}, defaults, options);

		return this.each(function () {
			var container = $(this);
			var initialValue;
			if (options.format === "currency") {
				$(this).text( $(this).text().replace(options.currencyIndicator, "").replace(options.currencyGroupSeparator, "") );
			}
			var initialValue = parseFloat($(this).text(), 10);
			if (round(value, options.floatEndDecimals) == round(initialValue, options.floatEndDecimals)) {
				return;
			}
			var type = container.data("type") || (isInt($(this).text()) ? "int" : "float"),
				stepDecimals, endDecimals,
				defaultStepDecimals, defaultEndDecimals;
			if (type == "int") {
				defaultStepDecimals = options.intStepDecimals;
				defaultEndDecimals = options.intEndDecimals;
			} else {
				defaultStepDecimals = options.floatStepDecimals;
				defaultEndDecimals = options.floatEndDecimals;
			}
			stepDecimals = container.data("stepDecimals") || defaultStepDecimals;
			endDecimals = container.data("endDecimals") || defaultEndDecimals;

			// animate opacity
			if (options.animateOpacity) {
				container.animate({opacity: 0.2}, {
					duration: options.duration/2,
					easing: options.easing,
					complete: function() {
						container.animate({opacity: 1}, {
							duration: options.duration/2,
							easing: options.easing
						});
					}
				});
			}
			// animate number
			$({number: initialValue}).animate({number: value}, {
				duration: options.duration,
				easing: options.easing,
				step: function() {
					if (options.format === 'currency') {
						container.text(formatCurrency(this.number, options));
					} else {
						container.text(round(this.number, stepDecimals));
					}
				},
				complete: function() {
					if (options.format === 'currency') {
						container.text(formatCurrency(this.number, options));
					} else {
						container.text(round(this.number, endDecimals));
					}
					if (typeof options.callback === "function") {
						options.callback.call(container);
					}
				}
			});
		});
	};

})( jQuery );
<commit_msg>Added an option to format the animated number as currency, added handling for browser differences in 0s in decimal places<commit_after>/*
 * jquery.animateNumber.js - jquery number animation plugin
 * Copyright (C) 2013, Robert Kajic (robert@kajic.com)
 * http://kajic.com
 *
 * Used on elements that have a number as content (integer or float)
 * to animate the number to a new value over a short period of time.
 *
 * Licensed under the MIT License.
 *
 * Date: 2013-01-08
 * Version: 0.1
 */

(function ($, undefined) {

	var defaults = {
		duration : 5000,
		easing: "swing",
		animateOpacity: true,
		intStepDecimals: 0,
		intEndDecimals: 0,
		floatStepDecimals: 4,
		floatEndDecimals: 1,
		format: "default",
		currencyIndicator: "$",
		currencyGroupSeparator: ",",
		currencyDecimalSeparator: ".",
		callback: function() {}
	};

	function round(number, decimals) {
		return Math.round(number*Math.pow(10,decimals))/Math.pow(10,decimals);
	}

	function formatCurrency(number, options) {
		if (!isNaN(number)) {
			var whole = Math.floor(number);
			var formattedVal;

			// This check is necessary because some browsers preserve 0 decimals if they
			// are present in toLocaleString() and others do not.
			if (whole.toLocaleString().indexOf(options.currencyDecimalSeparator) < 0) {
				formattedVal = options.currencyIndicator + whole.toLocaleString() + options.currencyDecimalSeparator + (number - whole).toFixed(2).split('.')[1];
			} else {
				formattedVal = options.currencyIndicator + parseFloat(number.toLocaleString()).toFixed(2);
			}
			return formattedVal;
		}

	}

	function isInt(number) {
		return /^-?[\d]+$/.test(number);
	}

	$.fn.animateNumber = function(value, options, callback) {
		if (typeof options === "function") {
			callback = options;
			options = {};
		}
		options = $.extend({}, defaults, options);

		return this.each(function () {
			var container = $(this);
			var initialValue;
			if (options.format === "currency") {
				$(this).text( $(this).text().replace(options.currencyIndicator, "").replace(options.currencyGroupSeparator, "") );
			}
			var initialValue = parseFloat($(this).text(), 10);
			if (round(value, options.floatEndDecimals) == round(initialValue, options.floatEndDecimals)) {
				return;
			}
			var type = container.data("type") || (isInt($(this).text()) ? "int" : "float"),
				stepDecimals, endDecimals,
				defaultStepDecimals, defaultEndDecimals;
			if (type == "int") {
				defaultStepDecimals = options.intStepDecimals;
				defaultEndDecimals = options.intEndDecimals;
			} else {
				defaultStepDecimals = options.floatStepDecimals;
				defaultEndDecimals = options.floatEndDecimals;
			}
			stepDecimals = container.data("stepDecimals") || defaultStepDecimals;
			endDecimals = container.data("endDecimals") || defaultEndDecimals;

			// animate opacity
			if (options.animateOpacity) {
				container.animate({opacity: 0.2}, {
					duration: options.duration/2,
					easing: options.easing,
					complete: function() {
						container.animate({opacity: 1}, {
							duration: options.duration/2,
							easing: options.easing
						});
					}
				});
			}
			// animate number
			$({number: initialValue}).animate({number: value}, {
				duration: options.duration,
				easing: options.easing,
				step: function() {
					if (options.format === 'currency') {
						container.text(formatCurrency(this.number, options));
					} else {
						container.text(round(this.number, stepDecimals));
					}
				},
				complete: function() {
					if (options.format === 'currency') {
						container.text(formatCurrency(this.number, options));
					} else {
						container.text(round(this.number, endDecimals));
					}
					if (typeof options.callback === "function") {
						options.callback.call(container);
					}
				}
			});
		});
	};

})( jQuery );
<|endoftext|>


<commit_before>pc.extend(pc.fw, function () {
    /**
     * @component
     * @name pc.fw.LightComponent
     * @class The Light Component enables the Entity to light the scene. The light can be one of the
     * following types:
     *

     *
directional: A directional light. The position of the attached entity has no effect.

     *
point: A point light.

     *
spot: A spot light.

     *

     * @constructor Creates a new LightComponent. The constructor is for internal use only. To create a new Component use {@link pc.fw.LightComponentSystem#addComponent}.
     * @param {pc.fw.LightComponentSystem} system The ComponentSystem that created this Component
     * @param {pc.fw.Entity} entity The Entity that this Component is attached to.
     * @property {String} type The type of light.
     *

     *
directional: A light that is infinitely far away and lights the entire scene from one direction.

     *
point: A light that illuminates in all directions from a point.

     *
spot: A light that illuminates a cone.

     *

     * @property {pc.fw.Color} color The Color of the light
     * @property {Boolean} enabled Enable or disable the light
     * @property {Number} intensity The brightness of the light.
     * @property {Boolean} castShadows If enabled the light will cast shadows.
     * @property {Number} shadowResolution The size of the texture used for the shadow map, 128, 256, 512, 1024, 2048. (Not available for point lights)
     * @property {Number} range The range of the light. (Not available for directional lights)
     * @property {Number} innerConeAngle The angle at which the spotlight cone starts to fade off. (Only avaiable for spotlights)
     * @property {Number} outerConeAngle The angle at which the spotlight cone has faded to nothing. (Only avaiable for spotlights)
     * @property {Number} falloffMode Defines the way of distance attenuation. (Available for point and spot lights)
     *

     *
{@link pc.scene.LIGHTFALLOFF_LINEAR}: Linear.

     *
{@link pc.scene.LIGHTFALLOFF_INVERSESQUARED}: Inverse squared.

     *

     * @extends pc.fw.Component
     */
    var LightComponent = function LightComponent(system, entity) {
        this.on("set_type", this.onSetType, this);
        this.on("set_color", this.onSetColor, this);
        this.on("set_intensity", this.onSetIntensity, this);
        this.on("set_castShadows", this.onSetCastShadows, this);
        this.on("set_shadowResolution", this.onSetShadowResolution, this);
        this.on("set_range", this.onSetRange, this);
        this.on("set_innerConeAngle", this.onSetInnerConeAngle, this);
        this.on("set_outerConeAngle", this.onSetOuterConeAngle, this);
        this.on("set_falloffMode", this.onSetFalloffMode, this);
    };

    LightComponent = pc.inherits(LightComponent, pc.fw.Component);

    Object.defineProperty(LightComponent.prototype, "enable", {
        get: function() {
            console.warn("WARNING: enable: Property is deprecated. Query enabled property instead.");
            return this.enabled;
        },
        set: function(value) {
            console.warn("WARNING: enable: Property is deprecated. Set enabled property instead.");
            this.enabled = value;
        },
    });

    pc.extend(LightComponent.prototype, {
        onSetType: function (name, oldValue, newValue) {
            if (oldValue !== newValue) {
                this.system.changeType(this, oldValue, newValue);

                // refresh light properties because changing the type does not reset the
                // light properties
                this.refreshProperties();
            }
        },

        refreshProperties: function() {
            this.onSetCastShadows("castShadows", this.castShadows, this.castShadows);
            this.onSetColor("color", this.color, this.color);
            this.onSetIntensity("intensity", this.intensity, this.intensity);
            this.onSetShadowResolution("shadowResolution", this.shadowResolution, this.shadowResolution);
            this.onSetRange("range", this.range, this.range);
            this.onSetInnerConeAngle("innerConeAngle", this.innerConeAngle, this.innerConeAngle);
            this.onSetOuterConeAngle("outerConeAngle", this.outerConeAngle, this.outerConeAngle);
            this.onSetFalloffMode("falloffMode", this.falloffMode, this.falloffMode);

            if (this.enabled && this.entity.enabled) {
                this.onEnable();
            }
        },

        onSetCastShadows: function (name, oldValue, newValue) {
            var light = this.data.model.lights[0];
            light.setCastShadows(newValue);
        },

        onSetColor: function (name, oldValue, newValue) {
            var light = this.data.model.lights[0];
            light.setColor(newValue);
        },

        onSetIntensity: function (name, oldValue, newValue) {
            var light = this.data.model.lights[0];
            light.setIntensity(newValue);
        },

        onSetShadowResolution: function (name, oldValue, newValue) {
            var light = this.data.model.lights[0];
            light.setShadowResolution(newValue);
        },

        onSetRange: function (name, oldValue, newValue) {
            if (this.data.type === 'point' || this.data.type === 'spot') {
                var light = this.data.model.lights[0];
                light.setAttenuationEnd(newValue);
            }
        },

        onSetInnerConeAngle: function (name, oldValue, newValue) {
            if (this.data.type === 'spot') {
                var light = this.data.model.lights[0];
                light.setInnerConeAngle(newValue);
            }
        },

        onSetOuterConeAngle: function (name, oldValue, newValue) {
            if (this.data.type === 'spot') {
                var light = this.data.model.lights[0];
                light.setOuterConeAngle(newValue);
            }
        },

        onSetFalloffMode: function (name, oldValue, newValue) {
            if (this.data.type === 'point' || this.data.type === 'spot') {
                var light = this.data.model.lights[0];
                light.setFalloffMode(newValue);
            }
        },

        onEnable: function () {
            LightComponent._super.onEnable.call(this);

            var model = this.data.model;

            var light = model.lights[0];
            light.setEnabled(true);

            var scene = this.system.context.scene;

            if (!scene.containsModel(model)) {
                scene.addModel(model);
            }
        },

        onDisable: function () {
            LightComponent._super.onDisable.call(this);

            var model = this.data.model;

            var light = model.lights[0];
            light.setEnabled(false);

            this.system.context.scene.removeModel(model);
        }
    });

    return {
        LightComponent: LightComponent
    };
}());
<commit_msg>doc fix<commit_after>pc.extend(pc.fw, function () {
    /**
     * @component
     * @name pc.fw.LightComponent
     * @class The Light Component enables the Entity to light the scene. The light can be one of the
     * following types:
     *

     *
directional: A directional light. The position of the attached entity has no effect.

     *
point: A point light.

     *
spot: A spot light.

     *

     * @constructor Creates a new LightComponent. The constructor is for internal use only. To create a new Component use {@link pc.fw.LightComponentSystem#addComponent}.
     * @param {pc.fw.LightComponentSystem} system The ComponentSystem that created this Component
     * @param {pc.fw.Entity} entity The Entity that this Component is attached to.
     * @property {String} type The type of light.
     *

     *
directional: A light that is infinitely far away and lights the entire scene from one direction.

     *
point: A light that illuminates in all directions from a point.

     *
spot: A light that illuminates a cone.

     *

     * @property {pc.fw.Color} color The Color of the light
     * @property {Boolean} enabled Enable or disable the light
     * @property {Number} intensity The brightness of the light.
     * @property {Boolean} castShadows If enabled the light will cast shadows.
     * @property {Number} shadowResolution The size of the texture used for the shadow map, 128, 256, 512, 1024, 2048.
     * @property {Number} range The range of the light. (Not available for directional lights)
     * @property {Number} innerConeAngle The angle at which the spotlight cone starts to fade off. (Only avaiable for spotlights)
     * @property {Number} outerConeAngle The angle at which the spotlight cone has faded to nothing. (Only avaiable for spotlights)
     * @property {Number} falloffMode Defines the way of distance attenuation. (Available for point and spot lights)
     *

     *
{@link pc.scene.LIGHTFALLOFF_LINEAR}: Linear.

     *
{@link pc.scene.LIGHTFALLOFF_INVERSESQUARED}: Inverse squared.

     *

     * @extends pc.fw.Component
     */
    var LightComponent = function LightComponent(system, entity) {
        this.on("set_type", this.onSetType, this);
        this.on("set_color", this.onSetColor, this);
        this.on("set_intensity", this.onSetIntensity, this);
        this.on("set_castShadows", this.onSetCastShadows, this);
        this.on("set_shadowResolution", this.onSetShadowResolution, this);
        this.on("set_range", this.onSetRange, this);
        this.on("set_innerConeAngle", this.onSetInnerConeAngle, this);
        this.on("set_outerConeAngle", this.onSetOuterConeAngle, this);
        this.on("set_falloffMode", this.onSetFalloffMode, this);
    };

    LightComponent = pc.inherits(LightComponent, pc.fw.Component);

    Object.defineProperty(LightComponent.prototype, "enable", {
        get: function() {
            console.warn("WARNING: enable: Property is deprecated. Query enabled property instead.");
            return this.enabled;
        },
        set: function(value) {
            console.warn("WARNING: enable: Property is deprecated. Set enabled property instead.");
            this.enabled = value;
        },
    });

    pc.extend(LightComponent.prototype, {
        onSetType: function (name, oldValue, newValue) {
            if (oldValue !== newValue) {
                this.system.changeType(this, oldValue, newValue);

                // refresh light properties because changing the type does not reset the
                // light properties
                this.refreshProperties();
            }
        },

        refreshProperties: function() {
            this.onSetCastShadows("castShadows", this.castShadows, this.castShadows);
            this.onSetColor("color", this.color, this.color);
            this.onSetIntensity("intensity", this.intensity, this.intensity);
            this.onSetShadowResolution("shadowResolution", this.shadowResolution, this.shadowResolution);
            this.onSetRange("range", this.range, this.range);
            this.onSetInnerConeAngle("innerConeAngle", this.innerConeAngle, this.innerConeAngle);
            this.onSetOuterConeAngle("outerConeAngle", this.outerConeAngle, this.outerConeAngle);
            this.onSetFalloffMode("falloffMode", this.falloffMode, this.falloffMode);

            if (this.enabled && this.entity.enabled) {
                this.onEnable();
            }
        },

        onSetCastShadows: function (name, oldValue, newValue) {
            var light = this.data.model.lights[0];
            light.setCastShadows(newValue);
        },

        onSetColor: function (name, oldValue, newValue) {
            var light = this.data.model.lights[0];
            light.setColor(newValue);
        },

        onSetIntensity: function (name, oldValue, newValue) {
            var light = this.data.model.lights[0];
            light.setIntensity(newValue);
        },

        onSetShadowResolution: function (name, oldValue, newValue) {
            var light = this.data.model.lights[0];
            light.setShadowResolution(newValue);
        },

        onSetRange: function (name, oldValue, newValue) {
            if (this.data.type === 'point' || this.data.type === 'spot') {
                var light = this.data.model.lights[0];
                light.setAttenuationEnd(newValue);
            }
        },

        onSetInnerConeAngle: function (name, oldValue, newValue) {
            if (this.data.type === 'spot') {
                var light = this.data.model.lights[0];
                light.setInnerConeAngle(newValue);
            }
        },

        onSetOuterConeAngle: function (name, oldValue, newValue) {
            if (this.data.type === 'spot') {
                var light = this.data.model.lights[0];
                light.setOuterConeAngle(newValue);
            }
        },

        onSetFalloffMode: function (name, oldValue, newValue) {
            if (this.data.type === 'point' || this.data.type === 'spot') {
                var light = this.data.model.lights[0];
                light.setFalloffMode(newValue);
            }
        },

        onEnable: function () {
            LightComponent._super.onEnable.call(this);

            var model = this.data.model;

            var light = model.lights[0];
            light.setEnabled(true);

            var scene = this.system.context.scene;

            if (!scene.containsModel(model)) {
                scene.addModel(model);
            }
        },

        onDisable: function () {
            LightComponent._super.onDisable.call(this);

            var model = this.data.model;

            var light = model.lights[0];
            light.setEnabled(false);

            this.system.context.scene.removeModel(model);
        }
    });

    return {
        LightComponent: LightComponent
    };
}());
<|endoftext|>


<commit_before>/* Topbar - Search - Focus */
$(document).on('click', '#search-query', function() {
  $(this).select();
});

/* Search - Special handling of certain queries */
$(document).on('submit', '#form-search', function(e) {
  var search_query = $('#search-query').val();
  if (search_query.substring(0, 9) === 'contacts:') {
    e.preventDefault();
    $.getJSON("/contacts/" + search_query.substring(10, 999) + "/as.jhtml", function(data) {
  	  $("#content-view").html(data.result);
    });
  }
  else if (search_query.substring(0, 9) === 'tags:') {
    console.log('trying to search for tags');
  }
  else {
    console.log('inside of else, just a normal query');
  }
});

/* Activities - */
$(document).on('click', '#button-search-options', function(key) {
	$('#search-params').slideDown('fast');
});

/* Activities - */
$(document).on('blur', '#button-search-options', function(key) {
	$('#search-params').slideUp('fast');
});

/* Activities - Create New Blank Message */
$(document).on('click', '#button-compose', function(e) {
	e.preventDefault();
  Mailpile.activities.compose();
});

/* Activities - DOM */
$(document).ready(function() {
  // Command Specific Mods
  if (Mailpile.instance.state.command_url == '/contacts/') {
    $('#search-query').val('contacts: ');
  }
});<commit_msg>Added a couple special Search terms to query box 'keys:' and 'tags:'<commit_after>/* Topbar - Search - Focus */
$(document).on('click', '#search-query', function() {
  $(this).select();
});

/* Search - Special handling of certain queries */
$(document).on('submit', '#form-search', function(e) {
  var search_query = $('#search-query').val();
  if (search_query.substring(0, 9) === 'contacts:') {
    e.preventDefault();
    $.getJSON("/contacts/" + search_query.substring(10, 999) + "/as.jhtml", function(data) {
  	  $("#content-wide").html(data.result);
    });
  }
  else if (search_query.substring(0, 5) === 'tags:') {
    e.preventDefault();
    $.getJSON("/tags/" + search_query.substring(6, 999) + "/as.jhtml", function(data) {
  	  $("#content-wide").html(data.result);
    });
  }
  else if (search_query.substring(0, 5) === 'keys:') {
    e.preventDefault();
    var query = search_query.substring(6, 999);
    Mailpile.find_encryption_keys(query);
  }
  else {
    console.log('inside of else, just a normal query');
  }
});

/* Activities - */
$(document).on('click', '#button-search-options', function(key) {
	$('#search-params').slideDown('fast');
});

/* Activities - */
$(document).on('blur', '#button-search-options', function(key) {
	$('#search-params').slideUp('fast');
});

/* Activities - Create New Blank Message */
$(document).on('click', '#button-compose', function(e) {
	e.preventDefault();
  Mailpile.activities.compose();
});

/* Activities - DOM */
$(document).ready(function() {
  // Command Specific Mods
  if (Mailpile.instance.state.command_url === '/contacts/') {
    $('#search-query').val('contacts: ');
  }
  else if (Mailpile.instance.state.command_url === '/tags/') {
    $('#search-query').val('tags: ');
  }

});<|endoftext|>


<commit_before>/*
 * GeoTag-X page analytics.
 */
;(function($, undefined){
	"use strict";

	// This selector is used to determine whether or not an item is clickable.
	// Please refer to the onElementClicked method for more information.
	var isClickableSelector_ = null;

	// When the script is loaded, we have to make sure the GTM script is
	// fully loaded and to do so, we check whether the window.analyticsListener
	// variable is defined. If it isn't we keep checking at intervals of 450ms
	// until the variable gets defined, or we ultimately give up after ~10 seconds.
	// When the GTM script is ready, we trigger the 'gtmready' custom event
	// which starts page-agnostic, as well as project-specific analytics.
	$(document).ready(function(){
		var maxWaitPeriod = 10000;
		var dt = 450;
		var timer = setInterval(function(){
			if (maxWaitPeriod <= 0){
				clearInterval(timer);
				$(document).trigger("geotagx-analytics-disabled");
			}
			else {
				if (window.analyticsListener){
					clearInterval(timer);
					$(document).trigger("gtmready");
				}
				else
					maxWaitPeriod -= dt;
			}
		}, dt);
	});

	// The analytics begins only when the Google Tag Manager (GTM) script is
	// ready, i.e. when the "gtmready" custom event has been fired.
	$(document).on("gtmready", function(){
		analytics.setGlobal("userId", $("body").data("user-id"));
		analytics.setGlobal("userRemoteAddr", window.client_remote_addr);
		try {
			if(ga){
				var ga_clientIds = []
				$(ga.getAll()).each(function(){
					ga_clientIds.push($(this).get(0).get('clientId'));
				})
				analytics.setGlobal("ga_clientIds", JSON.stringify(ga_clientIds));

				// In case of anonymous users, set the userId param as `anonymous_ga_clientIds`
				if($("body").data("user-id") == 0){ //user-id = 0 for anonymous users
					analytics.setGlobal("userId", "#geotagx_anonymous_"+JSON.stringify(ga_clientIds));
				}
			}
		}
		catch(error){
			// The code above generates a ReferenceError when 'ga' is undefined
			// which can happen when the script is being run in an environment
			// where Google Analytics has been purposely disabled, e.g. on a
			// development server.
			// While the ReferenceError is expected behavior, not handling it
			// prevents the rest of the script from being executed.
		}
		// With the analytics configured, we can properly start tracking our
		// events. The "geotagx-analytics-configured" event is fired to notify
		// the project-specific analytics script that it is OK to begin tracking.
		$(document).trigger("geotagx-analytics-configured");

		// Are we viewing a category's profile page?
		var $categoryProfile = $("#category-profile[data-short-name!=][data-short-name]");
		if ($categoryProfile.length > 0)
			onVisitCategory($categoryProfile.data("short-name"));

		// Or is it a project's profile page? If it is, we are only interested
		// when the user visits the information page.
		if ($("#project-info").length > 0){
			var shortName = $.trim($("#project-profile").data("short-name"));
			if (shortName.length > 0)
				onVisitProject(shortName);
		}

		$("body").on("click.analytics", onElementClicked);
		$("#share-category > a").on("click.analytics", onShareCategory);
		$("#share-project > a").on("click.analytics", onShareProject);
		$("a[href!=][href]").on("click.analytics", onLinkClicked);
		$("#signin button").on("click.analytics", onSignInButtonClicked);

		//Add surveyModal specific events
		$("#surveyModal").on("shown.bs.modal", function(){
			var data = {};
			data.surveyType = window.geotagxSurveyType;
			data.surveyState = "OPEN";
			analytics.fireEvent("action.surveyEvent", data);
		});
		$("#surveyModal").on("hidden.bs.modal", function(){
			var data = {};
			data.surveyType = window.geotagxSurveyType;
			data.surveyState = "CLOSE";
			analytics.fireEvent("action.surveyEvent", data);
		});
	});
	/**
	 * Fires an event when a user signs in, also passes in the user email address the user tried to sign in with
	 */
	function onSignInButtonClicked(){
		var tentative_email_addr = $("#email").val();
		if(tentative_email_addr){
			var data = {
				"email" : tentative_email_addr
			};
			analytics.fireEvent("action.signInButtonClicked", data);
		}
	}
	/**
	 * Fires an event when a user clicks the browser's "Back" button.
	 */
	function onGoingBackButtonClicked(){
		var data = {
			"url":null
		};
		analytics.fireEvent("action.goingBackButtonClicked", data);
	}
	/**
	 * Determines if the element that triggered this event is clickable. If it isn't
	 * then the action.invalidClick event is fired, otherwise no operation is performed.
	 */
	function onElementClicked(e){
		var $target = $(e.target);
		var elementClass = $target.attr("class");
		if (elementClass){
			if (isClickableSelector_ == null){
				isClickableSelector_ = [
					".clickable, .clickable *", // A set of elements that aren't usually clickable but have been made so (e.g. when an event handler has been attached to them). See the project grid categories for an example of clickable divs.
					"div.modal.fade", // A modal underlay which can be used to close a modal.
					"label.illustration-label", // Illustration labels in multi-choice answers are clickable ...
					"img.illustration-img", // ... as well as the images.
					"canvas", // A canvas can be interacted with, e.g. the canvas used by the OpenLayers map.
					"input:enabled", // Enabled input fields can be selected when clicked on.
					"textarea", // Long text input fields can be selected when clicked on.
					"#questionnaire-rewind, #questionnaire-rewind *", // The "Go to previous question" button is disabled and hidden when there're no more questions. It is still considered clickable.
					"#questionnaire-no-photo, #questionnaire-no-photo *", // The "I don not see a photo" button behaves just like the "Go to previous question"" button.
					"button:enabled, button:enabled *", // Enabled buttons.
					"a[href!=], a[href!=] *", // Anchors with valid links.
					".image-caption", //Image Caption element on grid panels
					"#submit-analysis, #submit-analysis *" // Submit Task Response Button
				].join(", ");
			}

			// If the target is not clickable, i.e. does not match with the
			// clickable selector, an invalidClick action is generated.
			if (!$target.is(isClickableSelector_)){
				var data = {
					"elementClass":elementClass,
					"url":window.location.href
				};
				analytics.fireEvent("action.invalidClick", data);
			}
		}
	}
	/**
	 * Fires an event when a user visits a category's page.
	 */
	function onVisitCategory(categoryId){
		var data = {
			"categoryId":categoryId
		};
		analytics.fireEvent("action.visitCategory", data);
	}
	/**
	 * Fires an event when a user visits a project.
	 */
	function onVisitProject(projectId){
		var data = {
			"projectId":projectId
		};
		analytics.fireEvent("action.visitProject", data);
	}
	/**
	 * Fires an action.onInternalLinkClicked event when the user clicks on one of
	 * of the various internal links e.g. Find photos, my profile, etc., otherwise
	 * fires an action.onExternalLinkClicked event.
	 */
	function onLinkClicked(){
		var url = $(this).attr("href");
		if (url !== "#"){
			var isInternalLink =
				url.charAt(0) === "#" ||
				url.charAt(0) === "/" ||
				url.indexOf("http://geotagx.org") === 0 ||
				url.indexOf("https://geotagx.org") === 0;
			var data = {
				"elementUrl":url
			};

			if (isInternalLink){
				var buttonId = $(this).attr("id");
				if (buttonId !== "start-contributing" && buttonId !== "skip-tutorial")
					analytics.fireEvent("action.internalLinkClicked", data);
			}else {
				// Clicks to external pages are only interesting if we're viewing a project's profile page.
				var $projectProfile = $("#project-profile[data-short-name!=]");
				if ($projectProfile.length > 0){
					data.projectId = $projectProfile.data("short-name");
					analytics.fireEvent("action.externalLinkClicked", data);
				}
			}
		}
	}
	/**
	 * Fires an event when a user shares a category (on social media).
	 */
	function onShareCategory(){
		var data = {
			"categoryId":$("#share-category").data("name"),
			"elementUrl":$(this).attr("href")
		};
		analytics.fireEvent("action.shareCategory", data);
	}
	/**
	 * Fires an event when a user shares a project (on social media).
	 */
	function onShareProject(){
		var data = {
			"projectId":$("#share-project").data("name"),
			"elementUrl":$(this).attr("href")
		};
		analytics.fireEvent("action.shareProject", data);
	}
})(jQuery);
<commit_msg>Update analytics to match new share buttons<commit_after>/*
 * GeoTag-X page analytics.
 */
;(function($, undefined){
	"use strict";

	// This selector is used to determine whether or not an item is clickable.
	// Please refer to the onElementClicked method for more information.
	var isClickableSelector_ = null;

	// When the script is loaded, we have to make sure the GTM script is
	// fully loaded and to do so, we check whether the window.analyticsListener
	// variable is defined. If it isn't we keep checking at intervals of 450ms
	// until the variable gets defined, or we ultimately give up after ~10 seconds.
	// When the GTM script is ready, we trigger the 'gtmready' custom event
	// which starts page-agnostic, as well as project-specific analytics.
	$(document).ready(function(){
		var maxWaitPeriod = 10000;
		var dt = 450;
		var timer = setInterval(function(){
			if (maxWaitPeriod <= 0){
				clearInterval(timer);
				$(document).trigger("geotagx-analytics-disabled");
			}
			else {
				if (window.analyticsListener){
					clearInterval(timer);
					$(document).trigger("gtmready");
				}
				else
					maxWaitPeriod -= dt;
			}
		}, dt);
	});

	// The analytics begins only when the Google Tag Manager (GTM) script is
	// ready, i.e. when the "gtmready" custom event has been fired.
	$(document).on("gtmready", function(){
		analytics.setGlobal("userId", $("body").data("user-id"));
		analytics.setGlobal("userRemoteAddr", window.client_remote_addr);
		try {
			if(ga){
				var ga_clientIds = []
				$(ga.getAll()).each(function(){
					ga_clientIds.push($(this).get(0).get('clientId'));
				})
				analytics.setGlobal("ga_clientIds", JSON.stringify(ga_clientIds));

				// In case of anonymous users, set the userId param as `anonymous_ga_clientIds`
				if($("body").data("user-id") == 0){ //user-id = 0 for anonymous users
					analytics.setGlobal("userId", "#geotagx_anonymous_"+JSON.stringify(ga_clientIds));
				}
			}
		}
		catch(error){
			// The code above generates a ReferenceError when 'ga' is undefined
			// which can happen when the script is being run in an environment
			// where Google Analytics has been purposely disabled, e.g. on a
			// development server.
			// While the ReferenceError is expected behavior, not handling it
			// prevents the rest of the script from being executed.
		}
		// With the analytics configured, we can properly start tracking our
		// events. The "geotagx-analytics-configured" event is fired to notify
		// the project-specific analytics script that it is OK to begin tracking.
		$(document).trigger("geotagx-analytics-configured");

		// Are we viewing a category's profile page?
		var $categoryProfile = $("#category-profile[data-short-name!=][data-short-name]");
		if ($categoryProfile.length > 0)
			onVisitCategory($categoryProfile.data("short-name"));

		// Or is it a project's profile page? If it is, we are only interested
		// when the user visits the information page.
		if ($("#project-info").length > 0){
			var shortName = $.trim($("#project-profile").data("short-name"));
			if (shortName.length > 0)
				onVisitProject(shortName);
		}

		$("body").on("click.analytics", onElementClicked);
		$(".share-category").on("click.analytics", onShareCategory);
		$(".share-project").on("click.analytics", onShareProject);
		$("a[href!=][href]").on("click.analytics", onLinkClicked);
		$("#signin button").on("click.analytics", onSignInButtonClicked);

		//Add surveyModal specific events
		$("#surveyModal").on("shown.bs.modal", function(){
			var data = {};
			data.surveyType = window.geotagxSurveyType;
			data.surveyState = "OPEN";
			analytics.fireEvent("action.surveyEvent", data);
		});
		$("#surveyModal").on("hidden.bs.modal", function(){
			var data = {};
			data.surveyType = window.geotagxSurveyType;
			data.surveyState = "CLOSE";
			analytics.fireEvent("action.surveyEvent", data);
		});
	});
	/**
	 * Fires an event when a user signs in, also passes in the user email address the user tried to sign in with
	 */
	function onSignInButtonClicked(){
		var tentative_email_addr = $("#email").val();
		if(tentative_email_addr){
			var data = {
				"email" : tentative_email_addr
			};
			analytics.fireEvent("action.signInButtonClicked", data);
		}
	}
	/**
	 * Fires an event when a user clicks the browser's "Back" button.
	 */
	function onGoingBackButtonClicked(){
		var data = {
			"url":null
		};
		analytics.fireEvent("action.goingBackButtonClicked", data);
	}
	/**
	 * Determines if the element that triggered this event is clickable. If it isn't
	 * then the action.invalidClick event is fired, otherwise no operation is performed.
	 */
	function onElementClicked(e){
		var $target = $(e.target);
		var elementClass = $target.attr("class");
		if (elementClass){
			if (isClickableSelector_ == null){
				isClickableSelector_ = [
					".clickable, .clickable *", // A set of elements that aren't usually clickable but have been made so (e.g. when an event handler has been attached to them). See the project grid categories for an example of clickable divs.
					"div.modal.fade", // A modal underlay which can be used to close a modal.
					"label.illustration-label", // Illustration labels in multi-choice answers are clickable ...
					"img.illustration-img", // ... as well as the images.
					"canvas", // A canvas can be interacted with, e.g. the canvas used by the OpenLayers map.
					"input:enabled", // Enabled input fields can be selected when clicked on.
					"textarea", // Long text input fields can be selected when clicked on.
					"#questionnaire-rewind, #questionnaire-rewind *", // The "Go to previous question" button is disabled and hidden when there're no more questions. It is still considered clickable.
					"#questionnaire-no-photo, #questionnaire-no-photo *", // The "I don not see a photo" button behaves just like the "Go to previous question"" button.
					"button:enabled, button:enabled *", // Enabled buttons.
					"a[href!=], a[href!=] *", // Anchors with valid links.
					".image-caption", //Image Caption element on grid panels
					"#submit-analysis, #submit-analysis *" // Submit Task Response Button
				].join(", ");
			}

			// If the target is not clickable, i.e. does not match with the
			// clickable selector, an invalidClick action is generated.
			if (!$target.is(isClickableSelector_)){
				var data = {
					"elementClass":elementClass,
					"url":window.location.href
				};
				analytics.fireEvent("action.invalidClick", data);
			}
		}
	}
	/**
	 * Fires an event when a user visits a category's page.
	 */
	function onVisitCategory(categoryId){
		var data = {
			"categoryId":categoryId
		};
		analytics.fireEvent("action.visitCategory", data);
	}
	/**
	 * Fires an event when a user visits a project.
	 */
	function onVisitProject(projectId){
		var data = {
			"projectId":projectId
		};
		analytics.fireEvent("action.visitProject", data);
	}
	/**
	 * Fires an action.onInternalLinkClicked event when the user clicks on one of
	 * of the various internal links e.g. Find photos, my profile, etc., otherwise
	 * fires an action.onExternalLinkClicked event.
	 */
	function onLinkClicked(){
		var url = $(this).attr("href");
		if (url !== "#"){
			var isInternalLink =
				url.charAt(0) === "#" ||
				url.charAt(0) === "/" ||
				url.indexOf("http://geotagx.org") === 0 ||
				url.indexOf("https://geotagx.org") === 0;
			var data = {
				"elementUrl":url
			};

			if (isInternalLink){
				var buttonId = $(this).attr("id");
				if (buttonId !== "start-contributing" && buttonId !== "skip-tutorial")
					analytics.fireEvent("action.internalLinkClicked", data);
			}else {
				// Clicks to external pages are only interesting if we're viewing a project's profile page.
				var $projectProfile = $("#project-profile[data-short-name!=]");
				if ($projectProfile.length > 0){
					data.projectId = $projectProfile.data("short-name");
					analytics.fireEvent("action.externalLinkClicked", data);
				}
			}
		}
	}
	/**
	 * Fires an event when a user shares a category (on social media).
	 */
	function onShareCategory(){
		var data = {
			"categoryId":$("#share-category").data("name"),
			"elementUrl":$(this).attr("href")
		};
		analytics.fireEvent("action.shareCategory", data);
	}
	/**
	 * Fires an event when a user shares a project (on social media).
	 */
	function onShareProject(){
		var data = {
			"projectId":$("#share-project").data("name"),
			"elementUrl":$(this).attr("href")
		};
		analytics.fireEvent("action.shareProject", data);
	}
})(jQuery);
<|endoftext|>


<commit_before>export const SAUCE_LAUNCHERS = {
	// Use Chromium preinstalled with Travis VM
	// http://stackoverflow.com/questions/19255976/how-to-make-travis-execute-angular-tests-on-chrome-please-set-env-variable-chr
	'CHROME_TRAVIS_CI': {
		base: 'Chrome',
		flags: [
			'--no-sandbox'
		]
	},
	'SL_CHROME': {
		base: 'SauceLabs',
		browserName: 'chrome',
		version: '46'
	},
	'SL_CHROME_BETA': {
		base: 'SauceLabs',
		browserName: 'chrome',
		version: 'beta'
	},
	'SL_CHROME_DEV': {
		base: 'SauceLabs',
		browserName: 'chrome',
		version: 'dev'
	},
	'SL_FIREFOX': {
		base: 'SauceLabs',
		browserName: 'firefox',
		version: '42'
	},
	'SL_FIREFOX_BETA': {
		base: 'SauceLabs',
		browserName: 'firefox',
		version: 'beta'
	},
	'SL_FIREFOX_DEV': {
		base: 'SauceLabs',
		browserName: 'firefox',
		version: 'dev'
	},
	'SL_SAFARI_7': {
		base: 'SauceLabs',
		browserName: 'safari',
		platform: 'OS X 10.9',
		version: '7'
	},
	'SL_SAFARI_8': {
		base: 'SauceLabs',
		browserName: 'safari',
		platform: 'OS X 10.10',
		version: '8'
	},
	'SL_SAFARI_9': {
		base: 'SauceLabs',
		browserName: 'safari',
		platform: 'OS X 10.11',
		version: '9.0'
	},
	'SL_IOS_7': {
		base: 'SauceLabs',
		browserName: 'iphone',
		platform: 'OS X 10.10',
		version: '7.1'
	},
	'SL_IOS_8': {
		base: 'SauceLabs',
		browserName: 'iphone',
		platform: 'OS X 10.10',
		version: '8.4'
	},
	'SL_IOS_9': {
		base: 'SauceLabs',
		browserName: 'iphone',
		platform: 'OS X 10.10',
		version: '9.1'
	},
	'SL_IE_9': {
		base: 'SauceLabs',
		browserName: 'internet explorer',
		platform: 'Windows 2008',
		version: '9'
	},
	'SL_IE_10': {
		base: 'SauceLabs',
		browserName: 'internet explorer',
		platform: 'Windows 2012',
		version: '10'
	},
	'SL_IE_11': {
		base: 'SauceLabs',
		browserName: 'internet explorer',
		platform: 'Windows 8.1',
		version: '11'
	},
	'SL_EDGE': {
		base: 'SauceLabs',
		browserName: 'microsoftedge',
		platform: '20.10240'
	},
	'SL_ANDROID_4.1': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.1'
	},
	'SL_ANDROID_4.2': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.2'
	},
	'SL_ANDROID_4.3': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.3'
	},
	'SL_ANDROID_4.4': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.4'
	},
	'SL_ANDROID_5.1': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '5.1'
	}
};

export const SAUCE_ALIASES = {
	'ALL': Object.keys(SAUCE_LAUNCHERS).filter(function (item) {
		return SAUCE_LAUNCHERS[item].base == 'SauceLabs';
	}),
	'DESKTOP': ['SL_CHROME', 'SL_FIREFOX', 'SL_IE_9', 'SL_IE_10', 'SL_IE_11', 'SL_EDGE', 'SL_SAFARI_7', 'SL_SAFARI_8'],
	'MOBILE': ['SL_ANDROID_4.1', 'SL_ANDROID_4.2', 'SL_ANDROID_4.3', 'SL_ANDROID_4.4', 'SL_ANDROID_5.1', 'SL_IOS_7', 'SL_IOS_8', 'SL_IOS_9'],
	'ANDROID': ['SL_ANDROID_4.1', 'SL_ANDROID_4.2', 'SL_ANDROID_4.3', 'SL_ANDROID_4.4', 'SL_ANDROID_5.1'],
	'IE': ['SL_IE_9', 'SL_IE_10', 'SL_IE_11'],
	'IOS': ['SL_IOS_7', 'SL_IOS_8', 'SL_IOS_9'],
	'SAFARI': ['SL_SAFARI_7', 'SL_SAFARI_8', 'SL_SAFARI_9'],
	'BETA': ['SL_CHROME_BETA', 'SL_FIREFOX_BETA'],
	'DEV': ['SL_CHROME_DEV', 'SL_FIREFOX_DEV'],
	'CI': [
		'SL_CHROME',
		// 'SL_SAFARI_7',
		'SL_SAFARI_8',
		'SL_SAFARI_9',
		// 'SL_IOS_7',
		'SL_IOS_8',
		'SL_IOS_9',
		'SL_FIREFOX',
		// 'SL_IE_9',
		// 'SL_IE_10',
		// 'SL_IE_11',
		'SL_EDGE',
		// 'SL_ANDROID_4.1',
		// 'SL_ANDROID_4.2',
		// 'SL_ANDROID_4.3',
		'SL_ANDROID_4.4',
		'SL_ANDROID_5.1'
	]
};<commit_msg>chore(browser platforms): mangle with the SL browser platforms<commit_after>export const SAUCE_LAUNCHERS = {
	// Use Chromium preinstalled with Travis VM
	// http://stackoverflow.com/questions/19255976/how-to-make-travis-execute-angular-tests-on-chrome-please-set-env-variable-chr
	'CHROME_TRAVIS_CI': {
		base: 'Chrome',
		flags: [
			'--no-sandbox'
		]
	},
	'SL_CHROME': {
		base: 'SauceLabs',
		browserName: 'chrome',
		version: '46'
	},
	'SL_CHROME_BETA': {
		base: 'SauceLabs',
		browserName: 'chrome',
		version: 'beta'
	},
	'SL_CHROME_DEV': {
		base: 'SauceLabs',
		browserName: 'chrome',
		version: 'dev'
	},
	'SL_FIREFOX': {
		base: 'SauceLabs',
		browserName: 'firefox',
		// platform: 'Linux',
		version: '42.0'
	},
	'SL_FIREFOX_BETA': {
		base: 'SauceLabs',
		browserName: 'firefox',
		version: 'beta'
	},
	'SL_FIREFOX_DEV': {
		base: 'SauceLabs',
		browserName: 'firefox',
		version: 'dev'
	},
	'SL_SAFARI_7': {
		base: 'SauceLabs',
		browserName: 'safari',
		platform: 'OS X 10.9',
		version: '7'
	},
	'SL_SAFARI_8': {
		base: 'SauceLabs',
		browserName: 'safari',
		platform: 'OS X 10.10',
		version: '8'
	},
	'SL_SAFARI_9': {
		base: 'SauceLabs',
		browserName: 'safari',
		platform: 'OS X 10.11',
		version: '9.0'
	},
	'SL_IOS_7': {
		base: 'SauceLabs',
		browserName: 'iphone',
		platform: 'OS X 10.10',
		version: '7.1'
	},
	'SL_IOS_8': {
		base: 'SauceLabs',
		browserName: 'iphone',
		platform: 'OS X 10.10',
		version: '8.4'
	},
	'SL_IOS_9': {
		base: 'SauceLabs',
		browserName: 'iphone',
		platform: 'OS X 10.10',
		version: '9.1'
	},
	'SL_IE_9': {
		base: 'SauceLabs',
		browserName: 'internet explorer',
		platform: 'Windows 2008',
		version: '9'
	},
	'SL_IE_10': {
		base: 'SauceLabs',
		browserName: 'internet explorer',
		platform: 'Windows 2012',
		version: '10'
	},
	'SL_IE_11': {
		base: 'SauceLabs',
		browserName: 'internet explorer',
		platform: 'Windows 8.1',
		version: '11'
	},
	'SL_EDGE': {
		base: 'SauceLabs',
		browserName: 'MicrosoftEdge',
		platform: 'Windows 10',
		version: '20.10240'
	},
	'SL_ANDROID_4.1': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.1'
	},
	'SL_ANDROID_4.2': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.2'
	},
	'SL_ANDROID_4.3': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.3'
	},
	'SL_ANDROID_4.4': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.4'
	},
	'SL_ANDROID_5.1': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '5.1'
	}
};

export const SAUCE_ALIASES = {
	'ALL': Object.keys(SAUCE_LAUNCHERS).filter(function (item) {
		return SAUCE_LAUNCHERS[item].base == 'SauceLabs';
	}),
	'DESKTOP': ['SL_CHROME', 'SL_FIREFOX', 'SL_IE_9', 'SL_IE_10', 'SL_IE_11', 'SL_EDGE', 'SL_SAFARI_7', 'SL_SAFARI_8'],
	'MOBILE': ['SL_ANDROID_4.1', 'SL_ANDROID_4.2', 'SL_ANDROID_4.3', 'SL_ANDROID_4.4', 'SL_ANDROID_5.1', 'SL_IOS_7', 'SL_IOS_8', 'SL_IOS_9'],
	'ANDROID': ['SL_ANDROID_4.1', 'SL_ANDROID_4.2', 'SL_ANDROID_4.3', 'SL_ANDROID_4.4', 'SL_ANDROID_5.1'],
	'IE': ['SL_IE_9', 'SL_IE_10', 'SL_IE_11'],
	'IOS': ['SL_IOS_7', 'SL_IOS_8', 'SL_IOS_9'],
	'SAFARI': ['SL_SAFARI_7', 'SL_SAFARI_8', 'SL_SAFARI_9'],
	'BETA': ['SL_CHROME_BETA', 'SL_FIREFOX_BETA'],
	'DEV': ['SL_CHROME_DEV', 'SL_FIREFOX_DEV'],
	'CI': [
		'SL_CHROME',
		// 'SL_SAFARI_7',
		'SL_SAFARI_8',
		'SL_SAFARI_9',
		// 'SL_IOS_7',
		'SL_IOS_8',
		'SL_IOS_9',
		'SL_FIREFOX',
		// 'SL_IE_9',
		// 'SL_IE_10',
		// 'SL_IE_11',
		// 'SL_EDGE',
		// 'SL_ANDROID_4.1',
		// 'SL_ANDROID_4.2',
		// 'SL_ANDROID_4.3',
		// 'SL_ANDROID_4.4',
		'SL_ANDROID_5.1'
	]
};<|endoftext|>


<commit_before>function addToList(commits) {
    var list = $(".commits");
    $(commits).each(function (i, commit) {
      list.append("
"+commit["oid"]+": "+commit["message"]+"
");
    });
}

function addCommitNodes(g, commits) {
    $(commits).each(function (i, commit) {
      var oid = commit["oid"];
      if (! g.hasNode(oid)) {
        g.addNode(oid, {label: commit["message"]});
      }
    });
}

function addEdges(g, commits) {
  $(commits).each(function (i, commit) {
    var oid = commit["oid"];
    $(commit["parents"]).each(function(i, parent_oid) {
      g.addEdge(null, oid, parent_oid, {});
    });
  });
}

function draw(g) {
  var layout = dagreD3.layout().nodeSep(40).rankDir("LR");
  var renderer = new dagreD3.Renderer();
  var svg = d3.select("svg");
  var svgg = svg.select("g");

  var rendered = renderer.layout(layout).run(g, svgg);
  var zoom = d3.behavior.zoom()
    .on("zoom",function() {
      svgg.attr("transform","translate("+
        d3.event.translate.join(",")+")scale("+d3.event.scale+")");
      svgg.selectAll("path")
      .attr("d", path.projection(projection));
    });
  svg.call(zoom);
}

$(function() {
  $.get("/commits", function (commits) {
    var g = new dagreD3.Digraph();
    addCommitNodes(g, commits);
    addEdges(g, commits);
    draw(g);
  })
})
<commit_msg>Removing unnecessary code<commit_after>function addToList(commits) {
    var list = $(".commits");
    $(commits).each(function (i, commit) {
      list.append("
"+commit["oid"]+": "+commit["message"]+"
");
    });
}

function addCommitNodes(g, commits) {
    $(commits).each(function (i, commit) {
      var oid = commit["oid"];
      if (! g.hasNode(oid)) {
        g.addNode(oid, {label: commit["message"]});
      }
    });
}

function addEdges(g, commits) {
  $(commits).each(function (i, commit) {
    var oid = commit["oid"];
    $(commit["parents"]).each(function(i, parent_oid) {
      g.addEdge(null, oid, parent_oid, {});
    });
  });
}

function draw(g) {
  var layout = dagreD3.layout().nodeSep(40).rankDir("LR");
  var renderer = new dagreD3.Renderer();
  var svg = d3.select("svg");
  var svgg = svg.select("g");

  var rendered = renderer.layout(layout).run(g, svgg);
  var zoom = d3.behavior.zoom()
    .on("zoom",function() {
      svgg.attr("transform","translate("+
        d3.event.translate.join(",")+")scale("+d3.event.scale+")");
    });
  svg.call(zoom);
}

$(function() {
  $.get("/commits", function (commits) {
    var g = new dagreD3.Digraph();
    addCommitNodes(g, commits);
    addEdges(g, commits);
    draw(g);
  })
})
<|endoftext|>


<commit_before>const html = require('choo/html');
const callcount = require('./callcount.js');
const chai = require('chai');
const expect = chai.expect;

describe('callcount component', () => {
  it('should properly format call total >=1000 with commas', () => {
    let state = {totalCalls: '123456789'};
    let result = callcount(state);
    expect(result.textContent).to.contain('123,456,789');
  });

  it('should properly format call total < 1000 without commas', () => {
    const totals = '123';
    let state = {totalCalls: totals};
    let result = callcount(state);
    // console.log('Result: ', result.childNodes);
    expect(result.textContent).to.contain(totals);
    expect(result.textContent).to.not.contain(',');
  });

  it('should not format zero call total', () => {
    const totals = '0';
    let state = {totalCalls: totals};
    let result = callcount(state);
    // console.log('Result: ', result.childNodes);
    // expect(result.childNodes[1].data).to.contain('123');
    expect(result.textContent).to.contain(totals);
    expect(result.textContent).to.not.contain(',');
  });

});
<commit_msg>Skip callcount test if formatting not supported<commit_after>const html = require('choo/html');
const callcount = require('./callcount.js');
const chai = require('chai');
const expect = chai.expect;

// Skip a test if the browser does not support locale-based number formatting
function ifLocaleSupportedIt (test) {
  if (window.Intl && window.Intl.NumberFormat) {
    it(test);
  }
  else {
    it.skip(test);
  }
}

describe('callcount component', () => {
  ifLocaleSupportedIt('should properly format call total >=1000 with commas', () => {
    let state = {totalCalls: '123456789'};
    let result = callcount(state);
    expect(result.textContent).to.contain('123,456,789');
  });

  ifLocaleSupportedIt('should properly format call total < 1000 without commas', () => {
    const totals = '123';
    let state = {totalCalls: totals};
    let result = callcount(state);
    expect(result.textContent).to.contain(totals);
    expect(result.textContent).to.not.contain(',');
  });

  ifLocaleSupportedIt('should not format zero call total', () => {
    const totals = '0';
    let state = {totalCalls: totals};
    let result = callcount(state);
    expect(result.textContent).to.contain(totals);
    expect(result.textContent).to.not.contain(',');
  });

});
<|endoftext|>


<commit_before>export const SAUCE_LAUNCHERS = {
	// Use Chromium preinstalled with Travis VM
	// http://stackoverflow.com/questions/19255976/how-to-make-travis-execute-angular-tests-on-chrome-please-set-env-variable-chr
	'CHROME_TRAVIS_CI': {
		base: 'Chrome',
		flags: [
			'--no-sandbox'
		]
	},
	'SL_CHROME': {
		base: 'SauceLabs',
		browserName: 'chrome',
		version: '46'
	},
	'SL_CHROME_BETA': {
		base: 'SauceLabs',
		browserName: 'chrome',
		version: 'beta'
	},
	'SL_CHROME_DEV': {
		base: 'SauceLabs',
		browserName: 'chrome',
		version: 'dev'
	},
	'SL_FIREFOX': {
		base: 'SauceLabs',
		browserName: 'firefox',
		version: '42'
	},
	'SL_FIREFOX_BETA': {
		base: 'SauceLabs',
		browserName: 'firefox',
		version: 'beta'
	},
	'SL_FIREFOX_DEV': {
		base: 'SauceLabs',
		browserName: 'firefox',
		version: 'dev'
	},
	'SL_SAFARI_7': {
		base: 'SauceLabs',
		browserName: 'safari',
		platform: 'OS X 10.9',
		version: '7'
	},
	'SL_SAFARI_8': {
		base: 'SauceLabs',
		browserName: 'safari',
		platform: 'OS X 10.10',
		version: '8'
	},
	'SL_SAFARI_9': {
		base: 'SauceLabs',
		browserName: 'safari',
		platform: 'OS X 10.11',
		version: '9.0'
	},
	'SL_IOS_7': {
		base: 'SauceLabs',
		browserName: 'iphone',
		platform: 'OS X 10.10',
		version: '7.1'
	},
	'SL_IOS_8': {
		base: 'SauceLabs',
		browserName: 'iphone',
		platform: 'OS X 10.10',
		version: '8.4'
	},
	'SL_IOS_9': {
		base: 'SauceLabs',
		browserName: 'iphone',
		platform: 'OS X 10.10',
		version: '9.1'
	},
	'SL_IE_9': {
		base: 'SauceLabs',
		browserName: 'internet explorer',
		platform: 'Windows 2008',
		version: '9'
	},
	'SL_IE_10': {
		base: 'SauceLabs',
		browserName: 'internet explorer',
		platform: 'Windows 2012',
		version: '10'
	},
	'SL_IE_11': {
		base: 'SauceLabs',
		browserName: 'internet explorer',
		platform: 'Windows 8.1',
		version: '11'
	},
	'SL_EDGE': {
		base: 'SauceLabs',
		browserName: 'microsoftedge',
		platform: 'Windows 10',
		version: '20.10240'
	},
	'SL_ANDROID_4.1': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.1'
	},
	'SL_ANDROID_4.2': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.2'
	},
	'SL_ANDROID_4.3': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.3'
	},
	'SL_ANDROID_4.4': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.4'
	},
	'SL_ANDROID_5.1': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '5.1'
	}
};

export const SAUCE_ALIASES = {
	'ALL': Object.keys(SAUCE_LAUNCHERS).filter(function (item) {
		return SAUCE_LAUNCHERS[item].base == 'SauceLabs';
	}),
	'DESKTOP': ['SL_CHROME', 'SL_FIREFOX', 'SL_IE_9', 'SL_IE_10', 'SL_IE_11', 'SL_EDGE', 'SL_SAFARI_7', 'SL_SAFARI_8'],
	'MOBILE': ['SL_ANDROID_4.1', 'SL_ANDROID_4.2', 'SL_ANDROID_4.3', 'SL_ANDROID_4.4', 'SL_ANDROID_5.1', 'SL_IOS_7', 'SL_IOS_8', 'SL_IOS_9'],
	'ANDROID': ['SL_ANDROID_4.1', 'SL_ANDROID_4.2', 'SL_ANDROID_4.3', 'SL_ANDROID_4.4', 'SL_ANDROID_5.1'],
	'IE': ['SL_IE_9', 'SL_IE_10', 'SL_IE_11'],
	'IOS': ['SL_IOS_7', 'SL_IOS_8', 'SL_IOS_9'],
	'SAFARI': ['SL_SAFARI_7', 'SL_SAFARI_8', 'SL_SAFARI_9'],
	'BETA': ['SL_CHROME_BETA', 'SL_FIREFOX_BETA'],
	'DEV': ['SL_CHROME_DEV', 'SL_FIREFOX_DEV'],
	'CI': [
		'SL_CHROME',
		'SL_SAFARI_7',
		'SL_SAFARI_8',
		'SL_SAFARI_9',
		'SL_IOS_7',
		'SL_IOS_8',
		'SL_IOS_9',
		// 'SL_FIREFOX',
		// 'SL_IE_9',
		// 'SL_IE_10',
		// 'SL_IE_11',
		// 'SL_EDGE',
		// 'SL_ANDROID_4.1',
		// 'SL_ANDROID_4.2',
		// 'SL_ANDROID_4.3',
		// 'SL_ANDROID_4.4',
		'SL_ANDROID_5.1'
	]
};<commit_msg>chore: do not run tests on iOS 7<commit_after>export const SAUCE_LAUNCHERS = {
	// Use Chromium preinstalled with Travis VM
	// http://stackoverflow.com/questions/19255976/how-to-make-travis-execute-angular-tests-on-chrome-please-set-env-variable-chr
	'CHROME_TRAVIS_CI': {
		base: 'Chrome',
		flags: [
			'--no-sandbox'
		]
	},
	'SL_CHROME': {
		base: 'SauceLabs',
		browserName: 'chrome',
		version: '46'
	},
	'SL_CHROME_BETA': {
		base: 'SauceLabs',
		browserName: 'chrome',
		version: 'beta'
	},
	'SL_CHROME_DEV': {
		base: 'SauceLabs',
		browserName: 'chrome',
		version: 'dev'
	},
	'SL_FIREFOX': {
		base: 'SauceLabs',
		browserName: 'firefox',
		version: '42'
	},
	'SL_FIREFOX_BETA': {
		base: 'SauceLabs',
		browserName: 'firefox',
		version: 'beta'
	},
	'SL_FIREFOX_DEV': {
		base: 'SauceLabs',
		browserName: 'firefox',
		version: 'dev'
	},
	'SL_SAFARI_7': {
		base: 'SauceLabs',
		browserName: 'safari',
		platform: 'OS X 10.9',
		version: '7'
	},
	'SL_SAFARI_8': {
		base: 'SauceLabs',
		browserName: 'safari',
		platform: 'OS X 10.10',
		version: '8'
	},
	'SL_SAFARI_9': {
		base: 'SauceLabs',
		browserName: 'safari',
		platform: 'OS X 10.11',
		version: '9.0'
	},
	'SL_IOS_7': {
		base: 'SauceLabs',
		browserName: 'iphone',
		platform: 'OS X 10.10',
		version: '7.1'
	},
	'SL_IOS_8': {
		base: 'SauceLabs',
		browserName: 'iphone',
		platform: 'OS X 10.10',
		version: '8.4'
	},
	'SL_IOS_9': {
		base: 'SauceLabs',
		browserName: 'iphone',
		platform: 'OS X 10.10',
		version: '9.1'
	},
	'SL_IE_9': {
		base: 'SauceLabs',
		browserName: 'internet explorer',
		platform: 'Windows 2008',
		version: '9'
	},
	'SL_IE_10': {
		base: 'SauceLabs',
		browserName: 'internet explorer',
		platform: 'Windows 2012',
		version: '10'
	},
	'SL_IE_11': {
		base: 'SauceLabs',
		browserName: 'internet explorer',
		platform: 'Windows 8.1',
		version: '11'
	},
	'SL_EDGE': {
		base: 'SauceLabs',
		browserName: 'microsoftedge',
		platform: 'Windows 10',
		version: '20.10240'
	},
	'SL_ANDROID_4.1': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.1'
	},
	'SL_ANDROID_4.2': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.2'
	},
	'SL_ANDROID_4.3': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.3'
	},
	'SL_ANDROID_4.4': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '4.4'
	},
	'SL_ANDROID_5.1': {
		base: 'SauceLabs',
		browserName: 'android',
		platform: 'Linux',
		version: '5.1'
	}
};

export const SAUCE_ALIASES = {
	'ALL': Object.keys(SAUCE_LAUNCHERS).filter(function (item) {
		return SAUCE_LAUNCHERS[item].base == 'SauceLabs';
	}),
	'DESKTOP': ['SL_CHROME', 'SL_FIREFOX', 'SL_IE_9', 'SL_IE_10', 'SL_IE_11', 'SL_EDGE', 'SL_SAFARI_7', 'SL_SAFARI_8'],
	'MOBILE': ['SL_ANDROID_4.1', 'SL_ANDROID_4.2', 'SL_ANDROID_4.3', 'SL_ANDROID_4.4', 'SL_ANDROID_5.1', 'SL_IOS_7', 'SL_IOS_8', 'SL_IOS_9'],
	'ANDROID': ['SL_ANDROID_4.1', 'SL_ANDROID_4.2', 'SL_ANDROID_4.3', 'SL_ANDROID_4.4', 'SL_ANDROID_5.1'],
	'IE': ['SL_IE_9', 'SL_IE_10', 'SL_IE_11'],
	'IOS': ['SL_IOS_7', 'SL_IOS_8', 'SL_IOS_9'],
	'SAFARI': ['SL_SAFARI_7', 'SL_SAFARI_8', 'SL_SAFARI_9'],
	'BETA': ['SL_CHROME_BETA', 'SL_FIREFOX_BETA'],
	'DEV': ['SL_CHROME_DEV', 'SL_FIREFOX_DEV'],
	'CI': [
		'SL_CHROME',
		'SL_SAFARI_7',
		'SL_SAFARI_8',
		'SL_SAFARI_9',
		// 'SL_IOS_7',
		'SL_IOS_8',
		'SL_IOS_9',
		// 'SL_FIREFOX',
		// 'SL_IE_9',
		// 'SL_IE_10',
		// 'SL_IE_11',
		// 'SL_EDGE',
		// 'SL_ANDROID_4.1',
		// 'SL_ANDROID_4.2',
		// 'SL_ANDROID_4.3',
		// 'SL_ANDROID_4.4',
		'SL_ANDROID_5.1'
	]
};<|endoftext|>