<commit_before>/**
 * Utils library v4
 */

var UTILS = (function () {

	return {
		/**
		 * Shorthand for `querySelector`
		 *
		 * @param  {string} selector CSS like selector
		 * @return {Object}          DOM Node
		 */
		qs: function (selector) {
			return document.querySelector(selector);
		},

		/**
		 * Shorthand for `querySelectorAll`
		 *
		 * @param  {string} selector CSS like selector
		 * @return {Object}          DOM NodeList
		 */
		qsa: function (selector) {
			return document.querySelectorAll(selector);
		},

		hasClass: function (elm, chkClass) {
			var className = elm.className,
				classArr = className.split(' ');

			for (var i = 0; i < classArr.length; i++ ) {
				if ( classArr[i] === chkClass ) {
					return true;
				}
			}
			return false;
		},

		/**
		 * Cross browser event handler
		 *
		 * @param {Object}   elm     Element on which the event will be bound
		 * @param {string}   type    Event type or types (e.g. 'click', 'click input')
		 * @param {Function} handler Callback function to run when event is fired
		 */
		addEvent: function (elm, type, handler) {
			var types = type.split(' '),
				ieHandler;

			// Recurse if multiple event types were given
			if (types.length > 1) {
				// On each iteration, remove the first value in the array
				while (types.length) {
					UTILS.addEvent(elm, types.shift(), handler);
				}

				return;
			}

			// Modern browsers and IE9+
			if (window.addEventListener) {
				elm.addEventListener(type, handler, false);
			// IE8
			} else if (window.attachEvent) {
				// Required for normalizing the "event" object,
				// to have the same API as addEventListener
				ieHandler = function (e) {
					e.target = e.target || e.srcElement;
					e.currentTarget = e.currentTarget || elm;

					e.stopPropagation = e.stopPropagation || function () {
						e.cancelBubble = true;
					};

					e.preventDefault = e.preventDefault || function () {
						e.returnValue = false;
					};

					return handler.call(elm, e);
				};

				// Save a reference to the handler function with a unique key
				elm[type + handler] = ieHandler;

				// Support triggering custom events
				// Save event handlers in a special property on elm
				elm._events = elm._events || {};
				// Init event handlers array for the specific type, if doesn't exist
				if (!elm._events[type]) {
					elm._events[type] = [handler];
				// Add another handler, unless it already exists
				} else if (elm._events[type].toString().indexOf(handler) < 0) {
					elm._events[type].push(handler);
				}

				// Bind the event, the IE way
				elm.attachEvent('on' + type, ieHandler);
			}
		},

		/**
		 * Check if Event constructors are supported
		 *
		 * @return {Boolean}
		 */
		isModernEvent: function () {
			try {
				if (new Event('submit', {bubbles: false}).bubbles !== false) {
					return false;
				} else if (new Event('submit', {bubbles: true}).bubbles !== true) {
					return false;
				} else {
					return true;
				}
			} catch (e) {
				return false;
			}
		},

		/**
		 * Trigger an event on a specific element
		 *
		 * Note:
		 * - bubbles/cancelable - `false` by default (not supported in IE8)
		 *
		 * @param  {Object} elm      DOM Node
		 * @param  {string} type     Event type (e.g. 'click', 'customEvent')
		 * @param  {Object} options  Options object (e.g. bubbles, cancelable)
		 */
		emitEvent: function (elm, type, options) {
			var evt,
				bubbles,
				cancelable,
				// Will be used as a fallback event object for IE8
				eFallback;

			// Support Event options
			options = options || {};
			bubbles = options.bubbles !== undefined ? options.bubbles : false;
			cancelable = options.cancelable !== undefined ? options.cancelable : false;

			// Create an event object
			// Modern browsers (except IE Any)
			if (UTILS.isModernEvent()) {
				evt = new Event(type, {
					bubbles: bubbles,
					cancelable: cancelable
				});
			// IE 9+
			} else if (document.createEvent) {
				evt = document.createEvent('Event');
				evt.initEvent(type, bubbles, cancelable);
			// IE 8
			} else {
				evt = document.createEventObject();
			}

			// Trigger the event
			// Modern browsers and IE9+
			if (elm.dispatchEvent) {
				elm.dispatchEvent(evt);
			// IE8
			} else if (elm.fireEvent) {
				// `fireEvent` will fail on non real events (i.e. custom events)
				try {
					elm.fireEvent('on' + type, evt);
				} catch (e) {
					// If we have any event handlers saved during `addEvent`
					if (elm._events && elm._events[type]) {
						// Support minimal Event properties
						eFallback = {
							target: elm,
							currentTarget: elm
						};

						// Trigger all event handlers for this event type
						for (var i = 0; i < elm._events[type].length; i++) {
							elm._events[type][i].call(elm, eFallback);
						}
					}
				}
			}
		},

		/**
		 * Cross browser event removal
		 *
		 * @param {Object}   elm     Element on which the event should be unbound
		 * @param {string}   type    Event type to unbind
		 * @param {Function} handler Reference to the original callback function
		 */
		removeEvent: function (elm, type, handler) {
			var handlerRef;

			if (window.removeEventListener) {
				// Modern browsers
				elm.removeEventListener(type, handler, false);
			} else if (window.detachEvent) {
				// IE8 and below
				handlerRef = elm[type + handler];

				// Make sure the handler key exists
				if (handlerRef) {
					elm.detachEvent('on' + type, handlerRef);
					// Remove the key from the object, prevent memory leaks
					delete elm[type + handler];
				}
			}
		},

		/**
		 * Check if a given value is a plain Object
		 *
		 * @param  {*}       o Any value to be checked
		 * @return {Boolean}   true if it's an Object
		 */
		isObject: function (o) {
			var toString = Object.prototype.toString;
			return (toString.call(o) === toString.call({}));
		},

		/**
		 * AJAX helper function (similar to jQuery, but far from it!)
		 *
		 * @param {string} url     URL for the ajax request
		 * @param {Object} options AJAX settings
		 */
		ajax: function (url, options) {
			var xhr = new XMLHttpRequest(),
				method = 'GET',
				options = UTILS.isObject(options) ? options : {};

			// Check if "method" was supplied
			if (options.method) {
				method = options.method;
			}

			// Setup the request
			xhr.open(method.toUpperCase(), url);

			xhr.onreadystatechange = function () {
				var status;

				// If request finished
				if (xhr.readyState === 4) {
					status = xhr.status;

					// If response is OK or fetched from cache
					if ((status >= 200 && status < 300) || status === 304) {
						var res = xhr.responseText,
							contentType = xhr.getResponseHeader('Content-Type');

						// If server sent a content type header, handle formats
						if (contentType) {
							// Handle JSON format
							if (contentType === 'text/json' ||
								contentType === 'application/json') {

								// JSON throws an exception on invalid JSON
								try {
									res = JSON.parse(res);
								} catch (err) {
									// Trigger "fail" callback if set
									if (options.fail) {
										options.fail.call(xhr, err);
										return;
									}
								}
							// Handle XML format
							} else if (contentType === 'text/xml' ||
								contentType === 'application/xml') {
								// responseXML returns a document object
								res = xhr.responseXML;

								// if XML was invalid, trigger fail callback
								if (res === null && options.fail) {
									options.fail.call(xhr, 'Bad XML file');
									return;
								}
							}
						}

						// Trigger done callback with the proper response
						if (options.done) {
							options.done.call(xhr, res);
						}
					}

				}
			};

			// Fire the request
			xhr.send(null);
		}
	};
}());
<commit_msg>Adding addClass, removeClass and toggle functions<commit_after>/**
 * Utils library v4
 */

var UTILS = (function () {

	return {
		/**
		 * Shorthand for `querySelector`
		 *
		 * @param  {string} selector CSS like selector
		 * @return {Object}          DOM Node
		 */
		qs: function (selector) {
			return document.querySelector(selector);
		},

		/**
		 * Shorthand for `querySelectorAll`
		 *
		 * @param  {string} selector CSS like selector
		 * @return {Object}          DOM NodeList
		 */
		qsa: function (selector) {
			return document.querySelectorAll(selector);
		},

		hasClass: function (elm, chkClass) {
			// elm.classList.contains(chkClass);
			var className = elm.className,
				classArr = className.split(' ');

			for (var i = 0; i < classArr.length; i++ ) {
				if ( classArr[i] === chkClass ) {
					return true;
				}
			}
			return false;
		},

		addClass: function (elm, newClass) {
			elm.className = elm.className + ' ' + newClass;
		},

		removeClass: function (elm, rmvClass) {
			elm.classList.remove(rmvClass);
		},

		toggle: function (elm, className) {
			elm.classList.toggle(className);
		},

		/**
		 * Cross browser event handler
		 *
		 * @param {Object}   elm     Element on which the event will be bound
		 * @param {string}   type    Event type or types (e.g. 'click', 'click input')
		 * @param {Function} handler Callback function to run when event is fired
		 */
		addEvent: function (elm, type, handler) {
			var types = type.split(' '),
				ieHandler;

			// Recurse if multiple event types were given
			if (types.length > 1) {
				// On each iteration, remove the first value in the array
				while (types.length) {
					UTILS.addEvent(elm, types.shift(), handler);
				}

				return;
			}

			// Modern browsers and IE9+
			if (window.addEventListener) {
				elm.addEventListener(type, handler, false);
			// IE8
			} else if (window.attachEvent) {
				// Required for normalizing the "event" object,
				// to have the same API as addEventListener
				ieHandler = function (e) {
					e.target = e.target || e.srcElement;
					e.currentTarget = e.currentTarget || elm;

					e.stopPropagation = e.stopPropagation || function () {
						e.cancelBubble = true;
					};

					e.preventDefault = e.preventDefault || function () {
						e.returnValue = false;
					};

					return handler.call(elm, e);
				};

				// Save a reference to the handler function with a unique key
				elm[type + handler] = ieHandler;

				// Support triggering custom events
				// Save event handlers in a special property on elm
				elm._events = elm._events || {};
				// Init event handlers array for the specific type, if doesn't exist
				if (!elm._events[type]) {
					elm._events[type] = [handler];
				// Add another handler, unless it already exists
				} else if (elm._events[type].toString().indexOf(handler) < 0) {
					elm._events[type].push(handler);
				}

				// Bind the event, the IE way
				elm.attachEvent('on' + type, ieHandler);
			}
		},

		/**
		 * Check if Event constructors are supported
		 *
		 * @return {Boolean}
		 */
		isModernEvent: function () {
			try {
				if (new Event('submit', {bubbles: false}).bubbles !== false) {
					return false;
				} else if (new Event('submit', {bubbles: true}).bubbles !== true) {
					return false;
				} else {
					return true;
				}
			} catch (e) {
				return false;
			}
		},

		/**
		 * Trigger an event on a specific element
		 *
		 * Note:
		 * - bubbles/cancelable - `false` by default (not supported in IE8)
		 *
		 * @param  {Object} elm      DOM Node
		 * @param  {string} type     Event type (e.g. 'click', 'customEvent')
		 * @param  {Object} options  Options object (e.g. bubbles, cancelable)
		 */
		emitEvent: function (elm, type, options) {
			var evt,
				bubbles,
				cancelable,
				// Will be used as a fallback event object for IE8
				eFallback;

			// Support Event options
			options = options || {};
			bubbles = options.bubbles !== undefined ? options.bubbles : false;
			cancelable = options.cancelable !== undefined ? options.cancelable : false;

			// Create an event object
			// Modern browsers (except IE Any)
			if (UTILS.isModernEvent()) {
				evt = new Event(type, {
					bubbles: bubbles,
					cancelable: cancelable
				});
			// IE 9+
			} else if (document.createEvent) {
				evt = document.createEvent('Event');
				evt.initEvent(type, bubbles, cancelable);
			// IE 8
			} else {
				evt = document.createEventObject();
			}

			// Trigger the event
			// Modern browsers and IE9+
			if (elm.dispatchEvent) {
				elm.dispatchEvent(evt);
			// IE8
			} else if (elm.fireEvent) {
				// `fireEvent` will fail on non real events (i.e. custom events)
				try {
					elm.fireEvent('on' + type, evt);
				} catch (e) {
					// If we have any event handlers saved during `addEvent`
					if (elm._events && elm._events[type]) {
						// Support minimal Event properties
						eFallback = {
							target: elm,
							currentTarget: elm
						};

						// Trigger all event handlers for this event type
						for (var i = 0; i < elm._events[type].length; i++) {
							elm._events[type][i].call(elm, eFallback);
						}
					}
				}
			}
		},

		/**
		 * Cross browser event removal
		 *
		 * @param {Object}   elm     Element on which the event should be unbound
		 * @param {string}   type    Event type to unbind
		 * @param {Function} handler Reference to the original callback function
		 */
		removeEvent: function (elm, type, handler) {
			var handlerRef;

			if (window.removeEventListener) {
				// Modern browsers
				elm.removeEventListener(type, handler, false);
			} else if (window.detachEvent) {
				// IE8 and below
				handlerRef = elm[type + handler];

				// Make sure the handler key exists
				if (handlerRef) {
					elm.detachEvent('on' + type, handlerRef);
					// Remove the key from the object, prevent memory leaks
					delete elm[type + handler];
				}
			}
		},

		/**
		 * Check if a given value is a plain Object
		 *
		 * @param  {*}       o Any value to be checked
		 * @return {Boolean}   true if it's an Object
		 */
		isObject: function (o) {
			var toString = Object.prototype.toString;
			return (toString.call(o) === toString.call({}));
		},

		/**
		 * AJAX helper function (similar to jQuery, but far from it!)
		 *
		 * @param {string} url     URL for the ajax request
		 * @param {Object} options AJAX settings
		 */
		ajax: function (url, options) {
			var xhr = new XMLHttpRequest(),
				method = 'GET',
				options = UTILS.isObject(options) ? options : {};

			// Check if "method" was supplied
			if (options.method) {
				method = options.method;
			}

			// Setup the request
			xhr.open(method.toUpperCase(), url);

			xhr.onreadystatechange = function () {
				var status;

				// If request finished
				if (xhr.readyState === 4) {
					status = xhr.status;

					// If response is OK or fetched from cache
					if ((status >= 200 && status < 300) || status === 304) {
						var res = xhr.responseText,
							contentType = xhr.getResponseHeader('Content-Type');

						// If server sent a content type header, handle formats
						if (contentType) {
							// Handle JSON format
							if (contentType === 'text/json' ||
								contentType === 'application/json') {

								// JSON throws an exception on invalid JSON
								try {
									res = JSON.parse(res);
								} catch (err) {
									// Trigger "fail" callback if set
									if (options.fail) {
										options.fail.call(xhr, err);
										return;
									}
								}
							// Handle XML format
							} else if (contentType === 'text/xml' ||
								contentType === 'application/xml') {
								// responseXML returns a document object
								res = xhr.responseXML;

								// if XML was invalid, trigger fail callback
								if (res === null && options.fail) {
									options.fail.call(xhr, 'Bad XML file');
									return;
								}
							}
						}

						// Trigger done callback with the proper response
						if (options.done) {
							options.done.call(xhr, res);
						}
					}

				}
			};

			// Fire the request
			xhr.send(null);
		}
	};
}());
<|endoftext|>


<commit_before>var preload = function(game){}

preload.prototype = {
	preload: function(){
            var load_icon = this.game.add.sprite(this.game.world.width * 0.5, this.game.world.height * 0.5, 'load_ani');
            load_icon.scale.setTo(2,2);
            load_icon.anchor.setTo(.5,.5);
            load_icon.animations.add('load');
            load_icon.animations.play('load', 10, true);
            this.load.setPreloadSprite(load_icon);

            //load other preload stuff here
	    //this.game.load.spritesheet("sprite","res/sprite.png",64,64);
	    this.game.load.image("play_btn","res/play_btn2.png");
	    this.game.load.image("game_title","res/game_title.png");
	    this.game.load.image("click_me","res/click_me.png");
	    this.game.load.image("game_over","res/game_over.png");
	    this.game.load.image("start_over","res/start_over.png");
	    this.game.load.image("simon","res/simon.png");

            //sounds
            this.game.load.audio('click', ['res/sounds/click.mp3','res/sounds/click.ogg']);
            //music: https://www.youtube.com/watch?v=qFQP_A4Vacc
            this.game.load.audio('music', ['res/music/music.mp3','res/music/music.ogg']);
	},
  	create: function(){
                click = this.game.add.audio("click");
                music = this.game.add.audio("music");
                music.play('',0,1,true);
		this.game.state.start("GameTitle");
	}
}
<commit_msg>Working on load text<commit_after>var preload = function(game){}

preload.prototype = {
	preload: function(){
            load_text = this.game.add.text(this.game.world.centerX, this.game.world.centerY + 256, 'Loading', { fill: '#ffffff' });
            load_text.anchor.setTo(.5,.5);

            this.game.load.onLoadStart.add(this.loadStart, this);
            this.game.load.onFileComplete.add(this.fileComplete, this);
            this.game.load.onLoadComplete.add(this.loadComplete, this);

            var load_icon = this.game.add.sprite(this.game.world.width * 0.5, this.game.world.height * 0.5, 'load_ani');
            load_icon.scale.setTo(2,2);
            load_icon.anchor.setTo(.5,.5);
            load_icon.animations.add('load');
            load_icon.animations.play('load', 10, true);
            this.load.setPreloadSprite(load_icon);

            //load other preload stuff here
	    //this.game.load.spritesheet("sprite","res/sprite.png",64,64);
	    this.game.load.image("play_btn","res/play_btn2.png");
	    this.game.load.image("game_title","res/game_title.png");
	    this.game.load.image("click_me","res/click_me.png");
	    this.game.load.image("game_over","res/game_over.png");
	    this.game.load.image("start_over","res/start_over.png");
	    this.game.load.image("simon","res/simon.png");

            //sounds
            this.game.load.audio('click', ['res/sounds/click.mp3','res/sounds/click.ogg']);
            //music: https://www.youtube.com/watch?v=qFQP_A4Vacc
            this.game.load.audio('music', ['res/music/music.mp3','res/music/music.ogg']);
	},
  	create: function(){
                click = this.game.add.audio("click");
                music = this.game.add.audio("music");
                music.play('',0,1,true);
	},

        loadComplete: function(){
		this.game.state.start("GameTitle");
        },

        loadStart: function(){
            //console.log("Loading...");
            load_text.setText("Loading ...");

        },

        //  This callback is sent the following parameters:
        fileComplete: function(progress, cacheKey, success, totalLoaded, totalFiles) {
            //console.log("File Complete: " + progress + "% - " + totalLoaded + " out of " + totalFiles);
            load_text.setText("File Complete: " + progress + "% - " + totalLoaded + " out of " + totalFiles);
        }

}
<|endoftext|>


<commit_before>import React, { Suspense, lazy } from 'react'
import PropTypes from 'prop-types'
import { Redirect, Route, Switch } from 'react-router-dom'
import { Helmet } from 'react-helmet'
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles'
import V0MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import defaultTheme from 'js/theme/defaultV1'
import defaultThemeLegacy from 'js/theme/default'
import withPageviewTracking from 'js/analytics/withPageviewTracking'
import ErrorBoundary from 'js/components/General/ErrorBoundary'
import FullPageLoader from 'js/components/General/FullPageLoader'
import DashboardView from 'js/components/Dashboard/DashboardView'
import tabFavicon from 'js/assets/logos/favicon.ico'
import { TAB_APP } from 'js/constants'
import { parseUrlSearchString, validateAppName } from 'js/utils/utils'
import initializeCMP from 'js/utils/initializeCMP'

// Delaying the CMP initialization avoids delaying any CMP
// responses needed for our ad partner bid requests.
// Our modified CMP API stubs are quick to respond, but the
// core CMP JS, which replaces the stubs and is out of our
// control, may be slower to respond.
// Note that because we delay CMP initialization by default,
// any pages that rely on other CMP methods, such as the
// account page, should initialize the CMP before calling
// those methods.
const initCMP = () => {
  initializeCMP()
}
setTimeout(initCMP, 2000)

const AuthenticationView = lazy(() =>
  import('js/components/Authentication/AuthenticationView')
)
const TabSettingsPageComponent = lazy(() =>
  import('js/components/Settings/TabSettingsPageComponent')
)
const FirstTabView = lazy(() => import('js/components/Dashboard/FirstTabView'))
const PostUninstallView = lazy(() =>
  import('js/components/Dashboard/PostUninstallView')
)

const muiTheme = createMuiTheme(defaultTheme)
const legacyMuiTheme = getMuiTheme(defaultThemeLegacy)

class App extends React.Component {
  render() {
    // Get the app for branding purposes (e.g. we use the auth flow for
    // multiple apps).
    const { location } = this.props
    const urlParams = parseUrlSearchString(location.search)
    const app = validateAppName(urlParams.app)

    // @material-ui-1-todo: remove legacy theme provider
    return (
      <MuiThemeProvider theme={muiTheme}>
        <V0MuiThemeProvider muiTheme={legacyMuiTheme}>
          <ErrorBoundary brand={TAB_APP}>
            <Helmet
              titleTemplate={`%s - Tab for a Cause`}
              defaultTitle={'Tab for a Cause'}
            >
              <link rel="icon" href={tabFavicon} />
            </Helmet>
            <div
              style={{
                position: 'absolute',
                top: 0,
                right: 0,
                bottom: 0,
                left: 0,
                margin: 0,
                padding: 0,
                border: 'none',
              }}
            >
              <Suspense fallback={<FullPageLoader app={app} delay={350} />}>
                <Switch>
                  <Route exact path="/newtab/" component={DashboardView} />
                  <Route
                    path="/newtab/settings/"
                    component={TabSettingsPageComponent}
                  />
                  <Route
                    path="/newtab/account/"
                    component={TabSettingsPageComponent}
                  />
                  <Route
                    path="/newtab/profile/"
                    component={TabSettingsPageComponent}
                  />
                  <Route
                    exact
                    path="/newtab/first-tab/"
                    component={FirstTabView}
                  />
                  <Route
                    exact
                    path="/newtab/uninstalled/"
                    component={PostUninstallView}
                  />
                  <Route path="/newtab/auth/" component={AuthenticationView} />
                  <Redirect from="*" to="/newtab/" />
                </Switch>
              </Suspense>
            </div>
          </ErrorBoundary>
        </V0MuiThemeProvider>
      </MuiThemeProvider>
    )
  }
}

App.propTypes = {
  location: PropTypes.shape({
    search: PropTypes.string.isRequired,
  }),
}

App.defaultProps = {}

export default withPageviewTracking(App)
<commit_msg>Reduce CMP timeout a bit<commit_after>import React, { Suspense, lazy } from 'react'
import PropTypes from 'prop-types'
import { Redirect, Route, Switch } from 'react-router-dom'
import { Helmet } from 'react-helmet'
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles'
import V0MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import defaultTheme from 'js/theme/defaultV1'
import defaultThemeLegacy from 'js/theme/default'
import withPageviewTracking from 'js/analytics/withPageviewTracking'
import ErrorBoundary from 'js/components/General/ErrorBoundary'
import FullPageLoader from 'js/components/General/FullPageLoader'
import DashboardView from 'js/components/Dashboard/DashboardView'
import tabFavicon from 'js/assets/logos/favicon.ico'
import { TAB_APP } from 'js/constants'
import { parseUrlSearchString, validateAppName } from 'js/utils/utils'
import initializeCMP from 'js/utils/initializeCMP'

// Delaying the CMP initialization avoids delaying any CMP
// responses needed for our ad partner bid requests.
// Our modified CMP API stubs are quick to respond, but the
// core CMP JS, which replaces the stubs and is out of our
// control, may be slower to respond.
// Note that because we delay CMP initialization by default,
// any pages that rely on other CMP methods, such as the
// account page, should initialize the CMP before calling
// those methods.
const initCMP = () => {
  initializeCMP()
}
setTimeout(initCMP, 1500)

const AuthenticationView = lazy(() =>
  import('js/components/Authentication/AuthenticationView')
)
const TabSettingsPageComponent = lazy(() =>
  import('js/components/Settings/TabSettingsPageComponent')
)
const FirstTabView = lazy(() => import('js/components/Dashboard/FirstTabView'))
const PostUninstallView = lazy(() =>
  import('js/components/Dashboard/PostUninstallView')
)

const muiTheme = createMuiTheme(defaultTheme)
const legacyMuiTheme = getMuiTheme(defaultThemeLegacy)

class App extends React.Component {
  render() {
    // Get the app for branding purposes (e.g. we use the auth flow for
    // multiple apps).
    const { location } = this.props
    const urlParams = parseUrlSearchString(location.search)
    const app = validateAppName(urlParams.app)

    // @material-ui-1-todo: remove legacy theme provider
    return (
      <MuiThemeProvider theme={muiTheme}>
        <V0MuiThemeProvider muiTheme={legacyMuiTheme}>
          <ErrorBoundary brand={TAB_APP}>
            <Helmet
              titleTemplate={`%s - Tab for a Cause`}
              defaultTitle={'Tab for a Cause'}
            >
              <link rel="icon" href={tabFavicon} />
            </Helmet>
            <div
              style={{
                position: 'absolute',
                top: 0,
                right: 0,
                bottom: 0,
                left: 0,
                margin: 0,
                padding: 0,
                border: 'none',
              }}
            >
              <Suspense fallback={<FullPageLoader app={app} delay={350} />}>
                <Switch>
                  <Route exact path="/newtab/" component={DashboardView} />
                  <Route
                    path="/newtab/settings/"
                    component={TabSettingsPageComponent}
                  />
                  <Route
                    path="/newtab/account/"
                    component={TabSettingsPageComponent}
                  />
                  <Route
                    path="/newtab/profile/"
                    component={TabSettingsPageComponent}
                  />
                  <Route
                    exact
                    path="/newtab/first-tab/"
                    component={FirstTabView}
                  />
                  <Route
                    exact
                    path="/newtab/uninstalled/"
                    component={PostUninstallView}
                  />
                  <Route path="/newtab/auth/" component={AuthenticationView} />
                  <Redirect from="*" to="/newtab/" />
                </Switch>
              </Suspense>
            </div>
          </ErrorBoundary>
        </V0MuiThemeProvider>
      </MuiThemeProvider>
    )
  }
}

App.propTypes = {
  location: PropTypes.shape({
    search: PropTypes.string.isRequired,
  }),
}

App.defaultProps = {}

export default withPageviewTracking(App)
<|endoftext|>


<commit_before><commit_msg>Removing extra js file.<commit_after><|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2016 Yasumichi Akahoshi
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

const {ipcRenderer} = require('electron');
const fs = require('fs');
const path = require('path');
const Md2Html = require('./md2html.js');
const FIRST_IDX = 0;

(function() {

var md2html = new Md2Html();

// request preview
ipcRenderer.on('preview', (event, data, baseURI) => {
  let base = document.getElementsByTagName("base")[FIRST_IDX];
  if (baseURI != "") {
    base.setAttribute("href", baseURI);
  }
  base.setAttribute("target", "_blank");
  document.getElementById('body').innerHTML = md2html.convert(data);
  let h1List = document.getElementsByTagName("h1");
  if (h1List.length) {
      let workTitle = h1List[FIRST_IDX].innerHTML;
      if (/^(<img [^>]*>)+$/.test(workTitle)) {
          let images = h1List[FIRST_IDX].getElementsByTagName("img");
          for (let idx=FIRST_IDX; idx < images.length; idx++) {
              if (images[idx].hasAttribute("alt")) {
                  document.title = images[idx].getAttribute("alt").trim();
                  break;
              }
          }
      } else {
          document.title = workTitle.replace(/<[^>]*>/g, "").trim();
      }
  }
});

// request export HTML
ipcRenderer.on('export-HTML', (event, filename) => {
  let base = document.getElementsByTagName("base")[FIRST_IDX];
  base.removeAttribute("href");
  base.removeAttribute("target");

  // http://blog.mudatobunka.org/entry/2015/12/23/211425#postscript
  fs.writeFile (filename, new XMLSerializer().serializeToString(document),
    (error) => {
      if (error != null) {
        alert ('error: ' + error + '\n' + filename);
        return;
    }
    let src_css = path.join(__dirname, '../templates/github.css');
    let dest_css = path.join(path.dirname(filename), "github.css");
    fs.createReadStream(src_css).pipe(fs.createWriteStream(dest_css));
  });

  base.setAttribute("target", "_blank");
});

}());
<commit_msg>refs #19, apply jsdoc comment.<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2016 Yasumichi Akahoshi
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

const {ipcRenderer} = require('electron');
const fs = require('fs');
const path = require('path');
const Md2Html = require('./md2html.js');
const FIRST_IDX = 0;

(function() {

/**
 * @module js/preview.js
 */

var md2html = new Md2Html();

/**
 * Refresh preview
 * @param {object} event
 * @param {string} data - markdown text
 * @param {string} baseURI
 * @listens preview
 */
ipcRenderer.on('preview', (event, data, baseURI) => {
  let base = document.getElementsByTagName("base")[FIRST_IDX];
  if (baseURI != "") {
    base.setAttribute("href", baseURI);
  }
  base.setAttribute("target", "_blank");
  document.getElementById('body').innerHTML = md2html.convert(data);
  let h1List = document.getElementsByTagName("h1");
  if (h1List.length) {
      let workTitle = h1List[FIRST_IDX].innerHTML;
      if (/^(<img [^>]*>)+$/.test(workTitle)) {
          let images = h1List[FIRST_IDX].getElementsByTagName("img");
          for (let idx=FIRST_IDX; idx < images.length; idx++) {
              if (images[idx].hasAttribute("alt")) {
                  document.title = images[idx].getAttribute("alt").trim();
                  break;
              }
          }
      } else {
          document.title = workTitle.replace(/<[^>]*>/g, "").trim();
      }
  }
});

/**
 * Export HTML
 * @param {object} event
 * @param {string} filename - exported HTML file name
 * @listen export-HTML
 */
ipcRenderer.on('export-HTML', (event, filename) => {
  let base = document.getElementsByTagName("base")[FIRST_IDX];
  base.removeAttribute("href");
  base.removeAttribute("target");

  // http://blog.mudatobunka.org/entry/2015/12/23/211425#postscript
  fs.writeFile (filename, new XMLSerializer().serializeToString(document),
    (error) => {
      if (error != null) {
        alert ('error: ' + error + '\n' + filename);
        return;
    }
    let src_css = path.join(__dirname, '../templates/github.css');
    let dest_css = path.join(path.dirname(filename), "github.css");
    fs.createReadStream(src_css).pipe(fs.createWriteStream(dest_css));
  });

  base.setAttribute("target", "_blank");
});

}());
<|endoftext|>


<commit_before><commit_msg>Update stations-america.js<commit_after><|endoftext|>


<commit_before>// ==== IMPORTS ====
const express 						= require('express');
const bodyParser 					= require('body-parser');
const router = require('./routes/routes');
const routes 						= require('./routes/routes').getRoutes();
const createRoute 					= require('./routes/routes').createRoute;
const config  						= require('./config');
const mongo							= require('./src/db/mongoose');

/* create express app */
const app = express();
app.use(bodyParser.json());

/* connect to the database */
// mongo.init();

router.init(config.server.enableVersus);

/* setup route handlers for all routes imported in ./routes/routes */
routes.forEach(r => {
	console.log(`[Server adding route] : ${r.method} http://localhost:${config.server.PORT}${r.path}`);
	createRoute(app, r);
});

/* start the server on the PORT specified in config */
app.listen(config.server.PORT, () => {
	console.log(`[Server is running]   : Game server is listening on http://localhost:${config.server.PORT}`);
});

module.exports = app;
<commit_msg>readded connection to database<commit_after>// ==== IMPORTS ====
const express 						= require('express');
const bodyParser 					= require('body-parser');
const router = require('./routes/routes');
const routes 						= require('./routes/routes').getRoutes();
const createRoute 					= require('./routes/routes').createRoute;
const config  						= require('./config');
const mongo							= require('./src/db/mongoose');

/* create express app */
const app = express();
app.use(bodyParser.json());

/* connect to the database */
mongo.init();

router.init(config.server.enableVersus);

/* setup route handlers for all routes imported in ./routes/routes */
routes.forEach(r => {
	console.log(`[Server adding route] : ${r.method} http://localhost:${config.server.PORT}${r.path}`);
	createRoute(app, r);
});

/* start the server on the PORT specified in config */
app.listen(config.server.PORT, () => {
	console.log(`[Server is running]   : Game server is listening on http://localhost:${config.server.PORT}`);
});

module.exports = app;
<|endoftext|>


<commit_before>(function ($) {
    "use strict";

    var portfolio = {

        logoPath: "l 0,-100, l 50,50, l 50,-50, l 0,100",
        logoFlatPath: "M50,53 l 50,0, l 50,0, l 50,0, l 50,0",
        m1Path: "M95,103 l 0,-100, l 50,50, l 50,-50, l 0,100",
        m2Path: "M105,103 l 0,-100, l 50,50, l 50,-50, l 0,100",

        init: function () {
            this.drawLogo();
            this.bindUIActions();
            portfolio.initSlider();
        },

        bindUIActions: function () {
            if (!Modernizr.touch) {
                $(".logo-wrap").on({
                    mouseenter: function () { portfolio.flattenLogo(); },
                    mouseleave: function () { portfolio.errectLogo(); }
                });
            }
        },

        windowScrolled: function () {
            if (Modernizr.touch) {
                if ($(window).scrollTop() > 10) {
                    portfolio.flattenLogo();
                } else {
                    portfolio.errectLogo();
                }
            }
        },

        windowResized: function () {
            $(".paginator").each(function () {
                var pos = $(this).parent().find(".flex-active").parent().position();
                $(this).css({ "left" : pos.left + "px", "top" : pos.top + "px" });
            });
        },

        drawLogo: function () {

            var s = new Snap("#logo");

            var logoSettings = {
                fill: "none",
                stroke: "#666",
                strokeWidth: 3,
                strokeLinejoin: "round",
                strokeLinecap: "round"
            };

            portfolio.m1 = s.path(portfolio.m1Path);
            portfolio.m1.attr(logoSettings);

            portfolio.m2 = s.path(portfolio.m2Path);
            portfolio.m2.attr(logoSettings);
        },

        flattenLogo: function () {
            portfolio.m1.animate({ d: portfolio.logoFlatPath }, 200);
            portfolio.m2.animate({ d: portfolio.logoFlatPath }, 200);
        },

        errectLogo: function () {
            portfolio.m1.animate({ d: portfolio.m1Path }, 200);
            portfolio.m2.animate({ d: portfolio.m2Path }, 200);
        },

        initSlider: function () {
            $(".flexslider").flexslider({
                animation: "slide",
                slideshow: false,
                prevText: "",
                nextText: "",
                easing: "easeInOutCubic",
                animationSpeed: Modernizr.touch ? 200 : 600,
                start: function (slider) {
                    var pos = $(slider).find(".flex-control-paging li:first-child").position();
                    if (pos) {
                        var paginator = $("

").css({ "left" : pos.left + "px", "top" : pos.top + "px" });
                        $(slider).find(".flex-control-paging").append(paginator);
                    }
                },
                before: function (slider) {
                    var target = slider.animatingTo + 1; // 1 needed to convert zero indexed array into nth-child
                    var pos = $(slider).find(".flex-control-paging li:nth-child(" + target + ")").position();
                    $(slider).find(".paginator").css({ "left" : pos.left + "px", "top" : pos.top + "px" });
                }
            });
        }
    };

    // DOM Ready
    $(function () { portfolio.init(); });
    // Window Scrolled
    $(window).on("scroll", function () { portfolio.windowScrolled(); });
    // Window Resized (smart debounced event)
    $(window).bind("debouncedresize", function () { portfolio.windowResized(); });

} (jQuery));
<commit_msg>use this for consistency<commit_after>(function ($) {
    "use strict";

    var portfolio = {

        logoPath: "l 0,-100, l 50,50, l 50,-50, l 0,100",
        logoFlatPath: "M50,53 l 50,0, l 50,0, l 50,0, l 50,0",
        m1Path: "M95,103 l 0,-100, l 50,50, l 50,-50, l 0,100",
        m2Path: "M105,103 l 0,-100, l 50,50, l 50,-50, l 0,100",

        init: function () {
            this.drawLogo();
            this.bindUIActions();
            this.initSlider();
        },

        bindUIActions: function () {
            if (!Modernizr.touch) {
                $(".logo-wrap").on({
                    mouseenter: function () { portfolio.flattenLogo(); },
                    mouseleave: function () { portfolio.errectLogo(); }
                });
            }
        },

        windowScrolled: function () {
            if (Modernizr.touch) {
                if ($(window).scrollTop() > 10) {
                    portfolio.flattenLogo();
                } else {
                    portfolio.errectLogo();
                }
            }
        },

        windowResized: function () {
            $(".paginator").each(function () {
                var pos = $(this).parent().find(".flex-active").parent().position();
                $(this).css({ "left" : pos.left + "px", "top" : pos.top + "px" });
            });
        },

        drawLogo: function () {

            var s = new Snap("#logo");

            var logoSettings = {
                fill: "none",
                stroke: "#666",
                strokeWidth: 3,
                strokeLinejoin: "round",
                strokeLinecap: "round"
            };

            portfolio.m1 = s.path(portfolio.m1Path);
            portfolio.m1.attr(logoSettings);

            portfolio.m2 = s.path(portfolio.m2Path);
            portfolio.m2.attr(logoSettings);
        },

        flattenLogo: function () {
            portfolio.m1.animate({ d: portfolio.logoFlatPath }, 200);
            portfolio.m2.animate({ d: portfolio.logoFlatPath }, 200);
        },

        errectLogo: function () {
            portfolio.m1.animate({ d: portfolio.m1Path }, 200);
            portfolio.m2.animate({ d: portfolio.m2Path }, 200);
        },

        initSlider: function () {
            $(".flexslider").flexslider({
                animation: "slide",
                slideshow: false,
                prevText: "",
                nextText: "",
                easing: "easeInOutCubic",
                animationSpeed: Modernizr.touch ? 200 : 600,
                start: function (slider) {
                    var pos = $(slider).find(".flex-control-paging li:first-child").position();
                    if (pos) {
                        var paginator = $("

").css({ "left" : pos.left + "px", "top" : pos.top + "px" });
                        $(slider).find(".flex-control-paging").append(paginator);
                    }
                },
                before: function (slider) {
                    var target = slider.animatingTo + 1; // 1 needed to convert zero indexed array into nth-child
                    var pos = $(slider).find(".flex-control-paging li:nth-child(" + target + ")").position();
                    $(slider).find(".paginator").css({ "left" : pos.left + "px", "top" : pos.top + "px" });
                }
            });
        }
    };

    // DOM Ready
    $(function () { portfolio.init(); });
    // Window Scrolled
    $(window).on("scroll", function () { portfolio.windowScrolled(); });
    // Window Resized (smart debounced event)
    $(window).bind("debouncedresize", function () { portfolio.windowResized(); });

} (jQuery));
<|endoftext|>


<commit_before>/* global module, __dirname */
/* eslint-disable camelcase */
// @flow
'use strict'

const pkg = require('./package.json')
const webpack = require('webpack')

const {
    DefinePlugin,
    HotModuleReplacementPlugin,
    LoaderOptionsPlugin,
    NormalModuleReplacementPlugin,
    NamedModulesPlugin,
    optimize: {CommonsChunkPlugin},
} = webpack

const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlPlugin = require('@gob/webpack-plugin-html')
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

const isCI = Boolean(process.env.CI)
const outputFolder = __dirname + '/build/'

function config() {
    const isProduction = process.env.NODE_ENV === 'production'
    const isDevelopment = !isProduction
    const publicPath = '/'

    const devtool = isProduction ? 'source-map' : 'eval'

    const stats = {}
    if (isProduction) {
        stats.children = false
    }

    const entry = {
        main: ['./index.js'],
    }

    if (isDevelopment) {
        // add dev server and hotloading clientside code
        entry.main.unshift(
            // 'react-hot-loader/patch',
            'webpack-dev-server/client?/',
            'webpack/hot/only-dev-server'
        )
    }

    const output = {
        path: outputFolder,
        publicPath: publicPath,

        // extract-text-plugin uses [contenthash], and webpack uses [hash].
        filename: isDevelopment ? 'app.js' : 'app.[hash].js',
        chunkFilename: 'chunk.[name].[chunkhash].js',

        // Add /*filename*/ comments to generated require()s in the output.
        pathinfo: true,
    }

    const devServer = {
        port: 3000, // for webpack-dev-server

        stats: {
            assets: false,
            version: false,
            hash: false,
            timings: false,
            chunks: false,
            chunkModules: false,
        },
        contentBase: outputFolder,

        // Makes webpack serve /index.html as the response to any request to
        // webpack-dev-server, so GET / and GET /s/1234 both get the index
        // page.
        historyApiFallback: true,

        // We also do the manual entry above and the manual adding of the hot
        // module replacment plugin below.
        hot: true,
    }

    const plugins = [
        // clean out the build folder between builds
        new CleanWebpackPlugin([outputFolder]),

        // Generates an index.html for us.
        new HtmlPlugin(context => {
            let cssPath = context.css ? `${publicPath}${context.css}` : null
            let polyfills = isProduction
                ? ''
                : ''

            return `
                <!DOCTYPE html>

                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                <title>Gobbldygook</title>

                <link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/nhhpgddphdimipafjfiggjnbbmcoklld">

                ${polyfills}
                ${cssPath ? `<link rel="stylesheet" href="${cssPath}">` : ''}

            `
        }),

        // Ignore the "full" schema in js-yaml's module, because it brings in esprima
        // to support the !!js/function type. We don't use and have no need for it, so
        // tell webpack to ignore it.
        new NormalModuleReplacementPlugin(/schema\/default_full$/, result => {
            result.request = result.request.replace(
                'default_full',
                'default_safe'
            )
        }),

        // DefinePlugin makes some variables available to the code.
        new DefinePlugin({
            VERSION: JSON.stringify(pkg.version),
            // APP_BASE is used in react-router, to set its base appropriately
            // across both local dev and gh-pages.
            APP_BASE: JSON.stringify(publicPath),
            'process.env.TRAVIS_COMMIT': JSON.stringify(
                process.env.TRAVIS_COMMIT || process.env.COMMIT_REF
            ),
            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
        }),

        // Extract the common libraries into a single file so that the chunks
        // don't need to individually bundle them.
        new CommonsChunkPlugin({
            name: 'commons',
            filename: '[name].js',
            children: true,
        }),

        // Watcher doesn't work well if you mistype casing in a path so we use
        // a plugin that prints an error when you attempt to do this.
        new CaseSensitivePathsPlugin(),

        new LoaderOptionsPlugin({
            options: {
                worker: {
                    output: {
                        filename: '[hash].worker.js',
                        chunkFilename: '[id].[hash].worker.js',
                    },
                },
            },
        }),

        new NamedModulesPlugin(),

        // copy files – into the webpack {output} directory
        new CopyWebpackPlugin([{from: './static/*', flatten: true}]),
    ]

    if (isProduction) {
        // minify in production
        plugins.push(
            new UglifyJsPlugin({
                cache: true,
                parallel: true,
                sourceMap: true,
                uglifyOptions: {
                    ecma: 8,
                    warnings: false,
                },
            })
        )
        plugins.push(
            new ExtractTextPlugin({
                filename: isDevelopment ? 'app.css' : 'app.[contenthash].css',
                allChunks: true,
            })
        )
        plugins.push(
            new LoaderOptionsPlugin({
                minimize: true,
            })
        )
        plugins.push(new DuplicatePackageCheckerPlugin())
    }

    if (isDevelopment) {
        // add dev plugins
        plugins.push(new HotModuleReplacementPlugin())
    }

    const babelLoader = {
        loader: 'babel-loader',
        options: {cacheDirectory: !isCI},
    }
    const urlLoader = {loader: 'url-loader', options: {limit: 10000}}
    const cssLoader = isProduction
        ? ExtractTextPlugin.extract({
              fallback: 'style-loader',
              use: ['css-loader', 'sass-loader'],
          })
        : ['style-loader', 'css-loader', 'sass-loader']

    const module = {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: [babelLoader],
            },
            {
                test: /\.worker\.js$/,
                exclude: /node_modules/,
                use: ['worker-loader', babelLoader],
            },
            {
                test: /\.json$/,
                use: ['json-loader'],
            },
            {
                test: /\.otf|eot|ttf|woff2?$/,
                use: [urlLoader],
            },
            {
                test: /\.jpe?g|png|gif$/,
                use: [urlLoader],
            },
            {
                test: /\.s?css$/,
                use: cssLoader,
            },
        ],
    }

    return {
        target: 'web',
        devtool,
        stats,
        entry,
        output,
        devServer,
        plugins,
        module,
    }
}

module.exports = config
<commit_msg>clean up css injection<commit_after>/* global module, __dirname */
/* eslint-disable camelcase */
// @flow
'use strict'

const pkg = require('./package.json')
const webpack = require('webpack')

const {
    DefinePlugin,
    HotModuleReplacementPlugin,
    LoaderOptionsPlugin,
    NormalModuleReplacementPlugin,
    NamedModulesPlugin,
    optimize: {CommonsChunkPlugin},
} = webpack

const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlPlugin = require('@gob/webpack-plugin-html')
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
const DuplicatePackageCheckerPlugin = require('duplicate-package-checker-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

const isCI = Boolean(process.env.CI)
const outputFolder = __dirname + '/build/'

function config() {
    const isProduction = process.env.NODE_ENV === 'production'
    const isDevelopment = !isProduction
    const publicPath = '/'

    const devtool = isProduction ? 'source-map' : 'eval'

    const stats = {}
    if (isProduction) {
        stats.children = false
    }

    const entry = {
        main: ['./index.js'],
    }

    if (isDevelopment) {
        // add dev server and hotloading clientside code
        entry.main.unshift(
            // 'react-hot-loader/patch',
            'webpack-dev-server/client?/',
            'webpack/hot/only-dev-server'
        )
    }

    const output = {
        path: outputFolder,
        publicPath: publicPath,

        // extract-text-plugin uses [contenthash], and webpack uses [hash].
        filename: isDevelopment ? 'app.js' : 'app.[hash].js',
        chunkFilename: 'chunk.[name].[chunkhash].js',

        // Add /*filename*/ comments to generated require()s in the output.
        pathinfo: true,
    }

    const devServer = {
        port: 3000, // for webpack-dev-server

        stats: {
            assets: false,
            version: false,
            hash: false,
            timings: false,
            chunks: false,
            chunkModules: false,
        },
        contentBase: outputFolder,

        // Makes webpack serve /index.html as the response to any request to
        // webpack-dev-server, so GET / and GET /s/1234 both get the index
        // page.
        historyApiFallback: true,

        // We also do the manual entry above and the manual adding of the hot
        // module replacment plugin below.
        hot: true,
    }

    const plugins = [
        // clean out the build folder between builds
        new CleanWebpackPlugin([outputFolder]),

        // Generates an index.html for us.
        new HtmlPlugin(context => {
            let cssLink = context.css ? `<link rel="stylesheet" href="${publicPath}${context.css}">` : null
            let polyfills = isProduction
                ? ''
                : ''

            return `
                <!DOCTYPE html>

                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                <title>Gobbldygook</title>

                <link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/nhhpgddphdimipafjfiggjnbbmcoklld">

                ${polyfills}
                ${cssLink ? cssLink : ''}

            `
        }),

        // Ignore the "full" schema in js-yaml's module, because it brings in esprima
        // to support the !!js/function type. We don't use and have no need for it, so
        // tell webpack to ignore it.
        new NormalModuleReplacementPlugin(/schema\/default_full$/, result => {
            result.request = result.request.replace(
                'default_full',
                'default_safe'
            )
        }),

        // DefinePlugin makes some variables available to the code.
        new DefinePlugin({
            VERSION: JSON.stringify(pkg.version),
            // APP_BASE is used in react-router, to set its base appropriately
            // across both local dev and gh-pages.
            APP_BASE: JSON.stringify(publicPath),
            'process.env.TRAVIS_COMMIT': JSON.stringify(
                process.env.TRAVIS_COMMIT || process.env.COMMIT_REF
            ),
            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
        }),

        // Extract the common libraries into a single file so that the chunks
        // don't need to individually bundle them.
        new CommonsChunkPlugin({
            name: 'commons',
            filename: '[name].js',
            children: true,
        }),

        // Watcher doesn't work well if you mistype casing in a path so we use
        // a plugin that prints an error when you attempt to do this.
        new CaseSensitivePathsPlugin(),

        new LoaderOptionsPlugin({
            options: {
                worker: {
                    output: {
                        filename: '[hash].worker.js',
                        chunkFilename: '[id].[hash].worker.js',
                    },
                },
            },
        }),

        new NamedModulesPlugin(),

        // copy files – into the webpack {output} directory
        new CopyWebpackPlugin([{from: './static/*', flatten: true}]),
    ]

    if (isProduction) {
        // minify in production
        plugins.push(
            new UglifyJsPlugin({
                cache: true,
                parallel: true,
                sourceMap: true,
                uglifyOptions: {
                    ecma: 8,
                    warnings: false,
                },
            })
        )
        plugins.push(
            new ExtractTextPlugin({
                filename: isDevelopment ? 'app.css' : 'app.[contenthash].css',
                allChunks: true,
            })
        )
        plugins.push(
            new LoaderOptionsPlugin({
                minimize: true,
            })
        )
        plugins.push(new DuplicatePackageCheckerPlugin())
    }

    if (isDevelopment) {
        // add dev plugins
        plugins.push(new HotModuleReplacementPlugin())
    }

    const babelLoader = {
        loader: 'babel-loader',
        options: {cacheDirectory: !isCI},
    }
    const urlLoader = {loader: 'url-loader', options: {limit: 10000}}
    const cssLoader = isProduction
        ? ExtractTextPlugin.extract({
              fallback: 'style-loader',
              use: ['css-loader', 'sass-loader'],
          })
        : ['style-loader', 'css-loader', 'sass-loader']

    const module = {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: [babelLoader],
            },
            {
                test: /\.worker\.js$/,
                exclude: /node_modules/,
                use: ['worker-loader', babelLoader],
            },
            {
                test: /\.json$/,
                use: ['json-loader'],
            },
            {
                test: /\.otf|eot|ttf|woff2?$/,
                use: [urlLoader],
            },
            {
                test: /\.jpe?g|png|gif$/,
                use: [urlLoader],
            },
            {
                test: /\.s?css$/,
                use: cssLoader,
            },
        ],
    }

    return {
        target: 'web',
        devtool,
        stats,
        entry,
        output,
        devServer,
        plugins,
        module,
    }
}

module.exports = config
<|endoftext|>


<commit_before>function FrameUI(elem) {
  this.elem = elem;
}

/* フレームの構造

    .
    .
    .

*/
function getFrameTemplate() {
  let frame = document.createElement("div");
  let frameDeleteBtn = document.createElement("div");
  let frameUpBtn = document.createElement("div");
  let frameDownBtn = document.createElement("div");
  frame.classList.add("thumbnail");
  frameDeleteBtn.classList.add("frame-delete");
  frameUpBtn.classList.add("frame-up");
  frameDownBtn.classList.add("frame-down");
  frameDeleteBtn.innerHTML = "";
  frameUpBtn.innerHTML = "";
  frameDownBtn.innerHTML = "";
  frame.appendChild(frameDeleteBtn);
  frame.appendChild(frameUpBtn);
  frame.appendChild(frameDownBtn);

  return frame;
}

FrameUI.prototype.append = function() {
  let newFrame = getFrameTemplate();
  this.elem.appendChild(newFrame);
  newFrame.addEventListener("click", () => {
    this.setCurrentFrame(newFrame);
  });
};

FrameUI.prototype.remove = function(frame) {
  this.elem.removeChild(frame);
};

FrameUI.prototype.moveUp = function() {
  // TODO
};

FrameUI.prototype.moveDown = function() {
  // TODO
};

FrameUI.prototype.setCurrentFrame = function(frame) {
  let selectedFrame = this.elem.querySelector(".thumbnail-selected");
  if (selectedFrame) {
    selectedFrame.classList.remove("thumbnail-selected");
  }
  frame.classList.add("thumbnail-selected");
};

module.exports = FrameUI;
<commit_msg>letをconstに変更<commit_after>function FrameUI(elem) {
  this.elem = elem;
}

/* フレームの構造

    .
    .
    .

*/
function getFrameTemplate() {
  let frame = document.createElement("div");
  let frameDeleteBtn = document.createElement("div");
  let frameUpBtn = document.createElement("div");
  let frameDownBtn = document.createElement("div");
  frame.classList.add("thumbnail");
  frameDeleteBtn.classList.add("frame-delete");
  frameUpBtn.classList.add("frame-up");
  frameDownBtn.classList.add("frame-down");
  frameDeleteBtn.innerHTML = "";
  frameUpBtn.innerHTML = "";
  frameDownBtn.innerHTML = "";
  frame.appendChild(frameDeleteBtn);
  frame.appendChild(frameUpBtn);
  frame.appendChild(frameDownBtn);

  return frame;
}

FrameUI.prototype.append = function() {
  let newFrame = getFrameTemplate();
  this.elem.appendChild(newFrame);
  newFrame.addEventListener("click", () => {
    this.setCurrentFrame(newFrame);
  });
};

FrameUI.prototype.remove = function(frame) {
  this.elem.removeChild(frame);
};

FrameUI.prototype.moveUp = function() {
  // TODO
};

FrameUI.prototype.moveDown = function() {
  // TODO
};

FrameUI.prototype.setCurrentFrame = function(frame) {
  const selectedFrame = this.elem.querySelector(".thumbnail-selected");
  if (selectedFrame) {
    selectedFrame.classList.remove("thumbnail-selected");
  }
  frame.classList.add("thumbnail-selected");
};

module.exports = FrameUI;
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';

import ChangesLinks from 'es6!display/changes/links';
import SimpleTooltip from 'es6!display/simple_tooltip';
import { ProgrammingError } from 'es6!display/errors';
import {
  get_runnable_condition,
  get_runnable_condition_color_cls,
  get_runnable_condition_short_text
} from 'es6!display/changes/build_conditions';

/*
 * Renders a small bar chart of a series of builds/tests/maybe others
 */
export var ChangesChart = React.createClass({

  MAX_CHART_HEIGHT: 40,  // pixels

  propTypes: {
    type: PropTypes.oneOf(['build', 'test']).isRequired,
    runnables: PropTypes.array.isRequired,
    // if enabled, we'll show a 'latest' label
    enableLatest: PropTypes.bool
  },

  getDefaultProps() {
    return { enableLatest: true };
  },

  render() {
    var { runnables, className, } = this.props;

    // we'll render bar heights relative to this
    // We sortBy(identity) because using sort() sorts by string representation, which is wrong.
    var longestDuration = _.chain(runnables).compact().pluck('duration').sortBy(_.identity).last().value();

    var content = _.map(this.props.runnables, (runnable, idx) => {
      var no_duration = runnable && !runnable.duration && runnable.duration === 0;
      if (_.isEmpty(runnable) || no_duration) {
        // would be nice to still show a tooltip here...
        return

;
      }

      var heightPercentage = runnable.duration / longestDuration;
      var barHeight = Math.floor(heightPercentage * this.MAX_CHART_HEIGHT) || 1;

      var columnPadding = this.MAX_CHART_HEIGHT - barHeight;

      var condition = get_runnable_condition(runnable);
      var bgColor = get_runnable_condition_color_cls(condition, true);
      var label = get_runnable_condition_short_text(condition, true);

      var tooltipText = null, href = null;
      if (this.props.type === 'build') {
        // TODO: show more details about the build
        tooltipText = runnable.name;
        href = ChangesLinks.buildHref(runnable);
      } else if (this.props.type === 'test') {
        // TODO: show more details about the test
        tooltipText = runnable.result.name;
        href = ChangesLinks.buildTestHref(runnable.job.build.id, runnable);
      } else {
        return <ProgrammingError>
          Unknown type {this.props.type}
        </ProgrammingError>;
      }

      return <SimpleTooltip label={tooltipText} placement="top" key={runnable.id}>

      </SimpleTooltip>;
    });

    if (this.props.enableLatest) {
      content.unshift(<LatestWidget key="latest" />);
    }

    var className = " changesChart " + (className || "");
    return
{content}
;
  }
});

var LatestWidget = React.createClass({
  render() {
    var divStyle = {
      position: 'absolute',
      marginLeft: -12,
      marginTop: -18,
      fontSize: 'xx-small',
    };

    var spanStyle = {
      backgroundColor: '#000000',
      color: 'white',
      padding: '1px 4px',
      borderRadius: 3
    };

    var caretStyle = {
      display: 'block',
      fontSize: 13,
      marginLeft: 13,
      marginTop: -4
    };

    return

      Latest

;
  }
});
<commit_msg>Fix ChangesChart rendering with null entries<commit_after>import React, { PropTypes } from 'react';

import ChangesLinks from 'es6!display/changes/links';
import SimpleTooltip from 'es6!display/simple_tooltip';
import { ProgrammingError } from 'es6!display/errors';
import {
  get_runnable_condition,
  get_runnable_condition_color_cls,
  get_runnable_condition_short_text
} from 'es6!display/changes/build_conditions';

/*
 * Renders a small bar chart of a series of builds/tests/maybe others
 */
export var ChangesChart = React.createClass({

  MAX_CHART_HEIGHT: 40,  // pixels

  propTypes: {
    type: PropTypes.oneOf(['build', 'test']).isRequired,
    runnables: PropTypes.array.isRequired,
    // if enabled, we'll show a 'latest' label
    enableLatest: PropTypes.bool
  },

  getDefaultProps() {
    return { enableLatest: true };
  },

  render() {
    var { runnables, className, } = this.props;

    // we'll render bar heights relative to this
    // We sortBy(identity) because using sort() sorts by string representation, which is wrong.
    var longestDuration = _.chain(runnables).compact().pluck('duration').sortBy(_.identity).last().value();

    var content = _.map(this.props.runnables, (runnable, idx) => {
      var no_duration = runnable && !runnable.duration && runnable.duration === 0;
      if (_.isEmpty(runnable) || no_duration) {
        // would be nice to still show a tooltip here...
        return

;
      }

      var heightPercentage = runnable.duration / longestDuration;
      var barHeight = Math.floor(heightPercentage * this.MAX_CHART_HEIGHT) || 1;

      var columnPadding = this.MAX_CHART_HEIGHT - barHeight;

      var condition = get_runnable_condition(runnable);
      var bgColor = get_runnable_condition_color_cls(condition, true);
      var label = get_runnable_condition_short_text(condition, true);

      var tooltipText = null, href = null;
      if (this.props.type === 'build') {
        // TODO: show more details about the build
        tooltipText = runnable.name;
        href = ChangesLinks.buildHref(runnable);
      } else if (this.props.type === 'test') {
        // TODO: show more details about the test
        tooltipText = runnable.result.name;
        href = ChangesLinks.buildTestHref(runnable.job.build.id, runnable);
      } else {
        return <ProgrammingError>
          Unknown type {this.props.type}
        </ProgrammingError>;
      }

      return <SimpleTooltip label={tooltipText} placement="top" key={runnable.id}>

      </SimpleTooltip>;
    });

    if (this.props.enableLatest) {
      content.unshift(<LatestWidget key="latest" />);
    }

    var className = " changesChart " + (className || "");
    return
{content}
;
  }
});

var LatestWidget = React.createClass({
  render() {
    var divStyle = {
      position: 'absolute',
      marginLeft: -12,
      marginTop: -18,
      fontSize: 'xx-small',
    };

    var spanStyle = {
      backgroundColor: '#000000',
      color: 'white',
      padding: '1px 4px',
      borderRadius: 3
    };

    var caretStyle = {
      display: 'block',
      fontSize: 13,
      marginLeft: 13,
      marginTop: -4
    };

    return

      Latest

;
  }
});
<|endoftext|>


<commit_before>/*
 * Kuzzle, a backend software, self-hostable and ready to use
 * to power modern apps
 *
 * Copyright 2015-2017 Kuzzle
 * mailto: support AT kuzzle.io
 * website: http://kuzzle.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const
  RoutePart = require('./routePart'),
  Request = require('kuzzle-common-objects').Request,
  {
    InternalError: KuzzleInternalError,
    BadRequestError,
    NotFoundError
  } = require('kuzzle-common-objects').errors;

const CharsetRegex = /charset=([\w-]+)/i;

/**
 * Attach handler to routes and dispatch a HTTP
 * message to the right handler
 *
 * Handlers will be called with the following arguments:
 *   - request: received HTTP request
 *   - response: HTTP response object
 *   - data: URL query arguments and/or POST data, if any
 *
 * @class Router
 */
class Router {
  constructor(kuzzle) {
    this.kuzzle = kuzzle;

    this.defaultHeaders = {
      'content-type': 'application/json',
      'Access-Control-Allow-Origin': kuzzle.config.http.accessControlAllowOrigin || '*',
      'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE,OPTIONS,HEAD',
      'Access-Control-Allow-Headers': 'Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With'
    };

    this.routes = {
      GET: new RoutePart(),
      POST: new RoutePart(),
      PUT: new RoutePart(),
      DELETE: new RoutePart(),
      HEAD: new RoutePart()
    };

    // Add an automatic HEAD route on the '/' url, answering with default headers
    attach('/', (request, cb) => {
      Object.assign(request.input.args, this.defaultHeaders);
      request.setResult({}, 200);
      cb(request);
    }, this.routes.HEAD);
  }

  /**
   * Attach a handler to a GET HTTP route
   *
   * @param {string} url
   * @param {Function} handler
   */
  get(url, handler) {
    attach(url, handler, this.routes.GET);
  }

  /**
   * Attach a handler to a POST HTTP route
   *
   * @param {string} url
   * @param {Function} handler
   */
  post(url, handler) {
    attach(url, handler, this.routes.POST);
  }

  /**
   * Attach a handler to a PUT HTTP route
   *
   * @param {string} url
   * @param {Function} handler
   */
  put(url, handler) {
    attach(url, handler, this.routes.PUT);
  }

  /**
   * Attach a handler to a DELETE HTTP route
   *
   * @param {string} url
   * @param {Function} handler
   */
  delete(url, handler) {
    attach(url, handler, this.routes.DELETE);
  }

  /**
   * Route an incoming HTTP httpRequest to the right handler
   *
   * @param {object} httpRequest - HTTP httpRequest formatted by Kuzzle Proxy
   * @param {function} cb
   */
  route(httpRequest, cb) {
    if (!this.routes[httpRequest.method]) {
      const request = new Request({requestId: httpRequest.requestId}, {}, 'rest');
      request.response.setHeaders(this.defaultHeaders);

      if (httpRequest.method.toUpperCase() === 'OPTIONS') {
        Object.assign(request.input.args, httpRequest.headers);
        request.setResult({}, 200);

        return this.kuzzle.pluginsManager.trigger('http:options', request)
          .then(result => {
            cb(result);
            return null;
          })
          .catch(error => replyWithError(cb, request, error));
      }

      return replyWithError(cb, request, new BadRequestError(`Unrecognized HTTP method ${httpRequest.method}`));
    }

    if (httpRequest.url.length > 1 && httpRequest.url.endsWith('/')) {
      httpRequest.url = httpRequest.url.slice(0, httpRequest.url.length -1);
    }

    const routeHandler = this.routes[httpRequest.method].getHandler(httpRequest);
    routeHandler.getRequest().response.setHeaders(this.defaultHeaders);

    if (routeHandler.handler !== null) {
      if (httpRequest.content.length > 0) {
        if (!httpRequest.headers['content-type'] || httpRequest.headers['content-type'].startsWith('application/json')) {
          const encoding = CharsetRegex.exec(httpRequest.headers['content-type']);

          if (encoding !== null && encoding[1].toLowerCase() !== 'utf-8') {
            return replyWithError(cb, routeHandler.getRequest(), new BadRequestError(`Invalid request charset. Expected "utf-8", got: "${encoding[1].toLowerCase()}"`));
          }

          try {
            routeHandler.addContent(httpRequest.content);
            routeHandler.invokeHandler(cb);
          }
          catch (e) {
            replyWithError(cb, routeHandler.getRequest(), new BadRequestError('Unable to convert HTTP body to JSON'));
          }
        }
        else {
          replyWithError(cb, routeHandler.getRequest(), new BadRequestError(`Invalid request content-type. Expected "application/json", got: "${httpRequest.headers['content-type']}"`));
        }
      }
      else {
        routeHandler.invokeHandler(cb);
      }
    }
    else {
      replyWithError(cb, routeHandler.getRequest(), new NotFoundError(`API URL not found: ${routeHandler.url}`));
    }
  }
}

/**
 * Attach a handler to an URL and stores it to the target object
 *
 * @param {string} url
 * @param {Function} handler
 * @param {object} target
 */
function attach(url, handler, target) {
  let cleanedUrl = url;

  if (cleanedUrl.length > 1 && cleanedUrl.endsWith('/')) {
    cleanedUrl = cleanedUrl.slice(0, cleanedUrl.length -1);
  }

  try {
    attachParts(cleanedUrl.split('/'), handler, target);
  }
  catch (e) {
    throw new KuzzleInternalError(`Unable to attach URL ${cleanedUrl}: URL path already exists`);
  }
}

function attachParts(parts, handler, target) {
  let part;

  do {
    part = parts.shift();
  } while (parts.length > 0 && part.length === 0);

  if (parts.length > 0) {
    attachParts(parts, handler, target.getNext(part));
  }
  else {
    if (target.exists(part)) {
      throw new Error('part already exists');
    }

    target.getNext(part).handler = handler;
  }
}

/**
 * Reply to a callback function with an HTTP error
 *
 * @param {function} cb
 * @param {Request} request
 * @param {Error} error
 */
function replyWithError(cb, request, error) {
  request.setError(error);

  cb(request);
}

/**
 * @type {Router}
 */
module.exports = Router;
<commit_msg>replace leading slashes with regex<commit_after>/*
 * Kuzzle, a backend software, self-hostable and ready to use
 * to power modern apps
 *
 * Copyright 2015-2017 Kuzzle
 * mailto: support AT kuzzle.io
 * website: http://kuzzle.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const
  RoutePart = require('./routePart'),
  Request = require('kuzzle-common-objects').Request,
  {
    InternalError: KuzzleInternalError,
    BadRequestError,
    NotFoundError
  } = require('kuzzle-common-objects').errors;

const
  LeadingSlashRegex = /\/+$/;
  CharsetRegex = /charset=([\w-]+)/i;

/**
 * Attach handler to routes and dispatch a HTTP
 * message to the right handler
 *
 * Handlers will be called with the following arguments:
 *   - request: received HTTP request
 *   - response: HTTP response object
 *   - data: URL query arguments and/or POST data, if any
 *
 * @class Router
 */
class Router {
  constructor(kuzzle) {
    this.kuzzle = kuzzle;

    this.defaultHeaders = {
      'content-type': 'application/json',
      'Access-Control-Allow-Origin': kuzzle.config.http.accessControlAllowOrigin || '*',
      'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE,OPTIONS,HEAD',
      'Access-Control-Allow-Headers': 'Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With'
    };

    this.routes = {
      GET: new RoutePart(),
      POST: new RoutePart(),
      PUT: new RoutePart(),
      DELETE: new RoutePart(),
      HEAD: new RoutePart()
    };

    // Add an automatic HEAD route on the '/' url, answering with default headers
    attach('/', (request, cb) => {
      Object.assign(request.input.args, this.defaultHeaders);
      request.setResult({}, 200);
      cb(request);
    }, this.routes.HEAD);
  }

  /**
   * Attach a handler to a GET HTTP route
   *
   * @param {string} url
   * @param {Function} handler
   */
  get(url, handler) {
    attach(url, handler, this.routes.GET);
  }

  /**
   * Attach a handler to a POST HTTP route
   *
   * @param {string} url
   * @param {Function} handler
   */
  post(url, handler) {
    attach(url, handler, this.routes.POST);
  }

  /**
   * Attach a handler to a PUT HTTP route
   *
   * @param {string} url
   * @param {Function} handler
   */
  put(url, handler) {
    attach(url, handler, this.routes.PUT);
  }

  /**
   * Attach a handler to a DELETE HTTP route
   *
   * @param {string} url
   * @param {Function} handler
   */
  delete(url, handler) {
    attach(url, handler, this.routes.DELETE);
  }

  /**
   * Route an incoming HTTP httpRequest to the right handler
   *
   * @param {object} httpRequest - HTTP httpRequest formatted by Kuzzle Proxy
   * @param {function} cb
   */
  route(httpRequest, cb) {
    if (!this.routes[httpRequest.method]) {
      const request = new Request({requestId: httpRequest.requestId}, {}, 'rest');
      request.response.setHeaders(this.defaultHeaders);

      if (httpRequest.method.toUpperCase() === 'OPTIONS') {
        Object.assign(request.input.args, httpRequest.headers);
        request.setResult({}, 200);

        return this.kuzzle.pluginsManager.trigger('http:options', request)
          .then(result => {
            cb(result);
            return null;
          })
          .catch(error => replyWithError(cb, request, error));
      }

      return replyWithError(cb, request, new BadRequestError(`Unrecognized HTTP method ${httpRequest.method}`));
    }

    httpRequest.url = httpRequest.url.replace(LeadingSlashRegex, '')

    const routeHandler = this.routes[httpRequest.method].getHandler(httpRequest);
    routeHandler.getRequest().response.setHeaders(this.defaultHeaders);

    if (routeHandler.handler !== null) {
      if (httpRequest.content.length > 0) {
        if (!httpRequest.headers['content-type'] || httpRequest.headers['content-type'].startsWith('application/json')) {
          const encoding = CharsetRegex.exec(httpRequest.headers['content-type']);

          if (encoding !== null && encoding[1].toLowerCase() !== 'utf-8') {
            return replyWithError(cb, routeHandler.getRequest(), new BadRequestError(`Invalid request charset. Expected "utf-8", got: "${encoding[1].toLowerCase()}"`));
          }

          try {
            routeHandler.addContent(httpRequest.content);
            routeHandler.invokeHandler(cb);
          }
          catch (e) {
            replyWithError(cb, routeHandler.getRequest(), new BadRequestError('Unable to convert HTTP body to JSON'));
          }
        }
        else {
          replyWithError(cb, routeHandler.getRequest(), new BadRequestError(`Invalid request content-type. Expected "application/json", got: "${httpRequest.headers['content-type']}"`));
        }
      }
      else {
        routeHandler.invokeHandler(cb);
      }
    }
    else {
      replyWithError(cb, routeHandler.getRequest(), new NotFoundError(`API URL not found: ${routeHandler.url}`));
    }
  }
}

/**
 * Attach a handler to an URL and stores it to the target object
 *
 * @param {string} url
 * @param {Function} handler
 * @param {object} target
 */
function attach(url, handler, target) {
  let cleanedUrl = url.replace(LeadingSlashRegex, '');

  try {
    attachParts(cleanedUrl.split('/'), handler, target);
  }
  catch (e) {
    throw new KuzzleInternalError(`Unable to attach URL ${cleanedUrl}: URL path already exists`);
  }
}

function attachParts(parts, handler, target) {
  let part;

  do {
    part = parts.shift();
  } while (parts.length > 0 && part.length === 0);

  if (parts.length > 0) {
    attachParts(parts, handler, target.getNext(part));
  }
  else {
    if (target.exists(part)) {
      throw new Error('part already exists');
    }

    target.getNext(part).handler = handler;
  }
}

/**
 * Reply to a callback function with an HTTP error
 *
 * @param {function} cb
 * @param {Request} request
 * @param {Error} error
 */
function replyWithError(cb, request, error) {
  request.setError(error);

  cb(request);
}

/**
 * @type {Router}
 */
module.exports = Router;
<|endoftext|>


<commit_before>function main() {
	// because the world main make sense in any programming language
}

/**
 * validate given email address
 * @var email: the given email address
 * @return true if valid
 * @return false if invalid
 */
function validateEmail(email) {
	var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
	return re.test(email);
}

/**
 * check if the given number is an integer or not
 * @var number: the vlaue you want to check if integer or not
 * @return true if number is an integer
 * @return false if number is anything but integer
 */
function isInt(number) {
	if(typeof number === 'number') {
		var remainder = (number % 1);
		if(remainder === 0) {
			// console.log("yes, it is an integer");
			return true;
		}
		else if(isNaN(remainder)) {
			// console.log("no, number is either: NaN, Infinity, or -Infinity");
			return false;
		}
		else {
			// console.log("no, it is a float (still a number though)");
			return false;
		}
	} else {
		// console.log("no way, it is not even a number");
		return false;
	}
}

/**
 * generate a random integer between min (inclusive) and max (inclusive)
 * @var min: the smallest number to get
 * @var max: the biggest number to get
 * @return random number between the min and max
 * @return false if min or max or both are anything but integers
 */
function getRandomInt(min, max) {
	if (isInt(min) && isInt(max)) {
		return Math.floor(Math.random() * (max - min + 1)) + min;
	} else {
		// console.log("min or max or both is or are not integers");
		return false;
	}
}

/**
 * get the current page the user is in right now
 * @return the current page name with the file extention (ex: index.html) or if it's the default page (ex: www.thecvcreator.com) return index
 * @return false if the return value was anything but sting mening an error happend
 */
function getCurrentPage() {
	var page = location.pathname.substring(location.pathname.lastIndexOf("/") + 1);
	if (typeof(page) === "string") {
		if (page.length > 0) {
			return page;
		} else if (page.length === 0) {
			return "index";
		}
	} else {
		return false;
	}
}

/**
 * so we can check if the browser is IE or not and handel events based on that
 * in order to call this function
 * addEventListener(element, event, handel);
 */
var addEventListener = (function() {
    if(document.addEventListener) {
        return function(element, event, handler) {
            element.addEventListener(event, handler, false);
        };
    }
    else {
        return function(element, event, handler) {
            element.attachEvent('on' + event, handler);
        };
    }
}());

/**
 * so we can replaceAll not just the first ocurance of the item
 * NOTE: this method add to the core javascript methods of any string
 * in other word you can use it on any string varaible
 * ex:
 * var x = "hello there I'm a test test test";
 * x.replaceAll("test", "legend");
 * x now equals: hello there I'm a legend legend legend
 */
String.prototype.replaceAll = function(search, replacement) {
	var target = this;
	return target.replace(new RegExp(search, 'g'), replacement);
};

/**
 * check a string if it is a hex color or not
 */
function isHexColor(color) {
	return color.match(/#((\w{6})|(\w{3}))/);
}

/**
 * check a string if it is a RGB color or not
 */
function isRGBColor(color) {
	return color.match(/rgb\s?\(\s?\d+\s?,\s?\d+\s?,\s?\d+\s?\)/)
}

/**
 * convert hex color to RGB color
 */
function hexToRGB(originalColor) {
	var vals = originalColor.match(/\w+/)[0];
	var retVal = {};
	if (vals.length === 3) {
		vals = vals[0] + vals[0] + vals[1] + vals[1] + vals[2] + vals[2];
	}
	retVal.red = hexToDec(vals.substr(0, 2));
	retVal.green = hexToDec(vals.substr(2, 2));
	retVal.blue = hexToDec(vals.substr(4, 2));
	return retVal;
}

/**
 * convert hex to decimal value
 */
function hexToDec(hexNum) {
	return parseInt(hexNum, 16);
}

/**
 * convert decimal to hex value
 */
function decToHex(decNum) {
	return decNum.toString(16);
}

/**
 * if color value is less then 0 set it to 0
 * if color value is bigger than 255 set it to 255
 * other then than that keep it as it is
 */
function clamp(val) {
	if (val < 0) {
		return 0;
	}
	if (val > 255) {
		return 255;
	}
	return val;
}

/**
 * check if the device is a touch device or not
 */
function is_touch_device() {
	return (('ontouchstart' in window) || (navigator.MaxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0));
}

/**
 * share on Facebook something (ex: article)
 * the clicked element must have two things
 * data-url: which contain the url that you are going to share
 * data-title: the title of your share
 */
function openFbShare(target){
	var link = jQuery(target);
	var u = encodeURIComponent(link.attr('data-url'));
	var t = encodeURIComponent(link.attr('data-title'));
	var leftPosition, topPosition;
	//Allow for borders.
	var width = 626;
	var height = 436;
	leftPosition = (window.screen.width / 2) - ((width / 2) + 10);
	//Allow for title and status bars.
	topPosition = (window.screen.height / 2) - ((height / 2) + 50);
	var windowFeatures = "status=no,height=" + height + ",width=" + width + ",resizable=yes,left=" + leftPosition + ",top=" + topPosition + ",screenX=" + leftPosition + ",screenY=" + topPosition + ",toolbar=no,menubar=no,scrollbars=no,location=no,directories=no";

	window.open('https://www.facebook.com/sharer.php?u=' + u +'&[title]=' + t,'sharer',windowFeatures);
	return false;
}
/**
 * share on Twitter something (ex: article)
 * the clicked element must have two things
 * href: which contain the url that you are going to share
 */
function openTwShare(target){
	var link = jQuery(target);
	var url = link.attr('href');
	var leftPosition, topPosition;
	var width = 626;
	var height = 436;
	leftPosition = (window.screen.width / 2) - ((width / 2) + 10);
	//Allow for title and status bars.
	topPosition = (window.screen.height / 2) - ((height / 2) + 50);
	var windowFeatures = "status=no,height=" + height + ",width=" + width + ",resizable=yes,left=" + leftPosition + ",top=" + topPosition + ",screenX=" + leftPosition + ",screenY=" + topPosition + ",toolbar=no,menubar=no,scrollbars=no,location=no,directories=no";
	//url += '?msg=' + link.attr('data-msg');
	window.open(url,'Twitter',windowFeatures);
	return false;
}

/**
 * share on Pinterest something (ex: article)
 * the clicked element must have two things
 * data-url: which contain the url that you are going to share
 * data-imt: the image of your share
 */
function openPinShare(target){
	var link = jQuery(target);
	var u = encodeURIComponent(link.attr('data-url'));
	var iu = encodeURIComponent(link.attr('data-img'));
	//var t = encodeURIComponent(link.attr('data-title'));
	var leftPosition, topPosition;
	//Allow for borders.
	var width = 750;
	var height = 550;
	leftPosition = (window.screen.width / 2) - ((width / 2) + 10);
	//Allow for title and status bars.
	topPosition = (window.screen.height / 2) - ((height / 2) + 50);
	var windowFeatures = "status=no,height=" + height + ",width=" + width + ",resizable=yes,left=" + leftPosition + ",top=" + topPosition + ",screenX=" + leftPosition + ",screenY=" + topPosition + ",toolbar=no,menubar=no,scrollbars=no,location=no,directories=no";
	window.open('https//www.pinterest.com/pin/create/button/?url='+ u +'&media=' + iu ,'sharer',windowFeatures);
	return false;
}
<commit_msg>Update functins.js<commit_after>function main() {
	// because the world main make sense in any programming language
}

/**
 * validate given email address
 * @var email: the given email address
 * @return true if valid
 * @return false if invalid
 */
function validateEmail(email) {
	var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
	return re.test(email);
}

/**
 * check if the given number is an integer or not
 * @var number: the vlaue you want to check if integer or not
 * @return true if number is an integer
 * @return false if number is anything but integer
 */
function isInt(number) {
	if(typeof number === 'number') {
		var remainder = (number % 1);
		if(remainder === 0) {
			// console.log("yes, it is an integer");
			return true;
		}
		else if(isNaN(remainder)) {
			// console.log("no, number is either: NaN, Infinity, or -Infinity");
			return false;
		}
		else {
			// console.log("no, it is a float (still a number though)");
			return false;
		}
	} else {
		// console.log("no way, it is not even a number");
		return false;
	}
}

/**
 * generate a random integer between min (inclusive) and max (inclusive)
 * @var min: the smallest number to get
 * @var max: the biggest number to get
 * @return random number between the min and max
 * @return false if min or max or both are anything but integers
 */
function getRandomInt(min, max) {
	if (isInt(min) && isInt(max)) {
		return Math.floor(Math.random() * (max - min + 1)) + min;
	} else {
		// console.log("min or max or both is or are not integers");
		return false;
	}
}

/**
 * get the current page the user is in right now
 * @return the current page name with the file extention (ex: index.html) or if it's the default page (ex: www.thecvcreator.com) return index
 * @return false if the return value was anything but sting mening an error happend
 */
function getCurrentPage() {
	var page = location.pathname.substring(location.pathname.lastIndexOf("/") + 1);
	if (typeof(page) === "string") {
		if (page.length > 0) {
			return page;
		} else if (page.length === 0) {
			return "index";
		}
	} else {
		return false;
	}
}

/**
 * so we can check if the browser is IE or not and handel events based on that
 * in order to call this function
 * addEventListener(element, event, handel);
 */
var addEventListener = (function() {
    if(document.addEventListener) {
        return function(element, event, handler) {
            element.addEventListener(event, handler, false);
        };
    }
    else {
        return function(element, event, handler) {
            element.attachEvent('on' + event, handler);
        };
    }
}());

/**
 * so we can replaceAll not just the first ocurance of the item
 * NOTE: this method add to the core javascript methods of any string
 * in other word you can use it on any string varaible
 * ex:
 * var x = "hello there I'm a test test test";
 * x.replaceAll("test", "legend");
 * x now equals: hello there I'm a legend legend legend
 */
String.prototype.replaceAll = function(search, replacement) {
	var target = this;
	return target.replace(new RegExp(search, 'g'), replacement);
};

/**
 * check a string if it is a hex color or not
 */
function isHexColor(color) {
	return color.match(/#((\w{6})|(\w{3}))/);
}

/**
 * check a string if it is a RGB color or not
 */
function isRGBColor(color) {
	return color.match(/rgb\s?\(\s?\d+\s?,\s?\d+\s?,\s?\d+\s?\)/)
}

/**
 * convert hex color to RGB color
 */
function hexToRGB(originalColor) {
	var vals = originalColor.match(/\w+/)[0];
	var retVal = {};
	if (vals.length === 3) {
		vals = vals[0] + vals[0] + vals[1] + vals[1] + vals[2] + vals[2];
	}
	retVal.red = hexToDec(vals.substr(0, 2));
	retVal.green = hexToDec(vals.substr(2, 2));
	retVal.blue = hexToDec(vals.substr(4, 2));
	return retVal;
}

/**
 * convert hex to decimal value
 */
function hexToDec(hexNum) {
	return parseInt(hexNum, 16);
}

/**
 * convert decimal to hex value
 */
function decToHex(decNum) {
	return decNum.toString(16);
}

/**
 * if color value is less then 0 set it to 0
 * if color value is bigger than 255 set it to 255
 * other then than that keep it as it is
 */
function clamp(val) {
	if (val < 0) {
		return 0;
	}
	if (val > 255) {
		return 255;
	}
	return val;
}

/**
 * check if the device is a touch device or not
 */
function is_touch_device() {
	return (('ontouchstart' in window) || (navigator.MaxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0));
}

/**
 * share on Facebook something (ex: article)
 * the clicked element must have two things
 * data-url: which contain the url that you are going to share
 * data-title: the title of your share
 */
function openFbShare(target){
	var link = jQuery(target);
	var u = encodeURIComponent(link.attr('data-url'));
	var t = encodeURIComponent(link.attr('data-title'));
	var leftPosition, topPosition;
	//Allow for borders.
	var width = 626;
	var height = 436;
	leftPosition = (window.screen.width / 2) - ((width / 2) + 10);
	//Allow for title and status bars.
	topPosition = (window.screen.height / 2) - ((height / 2) + 50);
	var windowFeatures = "status=no,height=" + height + ",width=" + width + ",resizable=yes,left=" + leftPosition + ",top=" + topPosition + ",screenX=" + leftPosition + ",screenY=" + topPosition + ",toolbar=no,menubar=no,scrollbars=no,location=no,directories=no";

	window.open('https://www.facebook.com/sharer.php?u=' + u +'&[title]=' + t,'sharer',windowFeatures);
	return false;
}
/**
 * share on Twitter something (ex: article)
 * the clicked element must have two things
 * href: which contain the url that you are going to share
 */
function openTwShare(target){
	var link = jQuery(target);
	var url = link.attr('href');
	var leftPosition, topPosition;
	var width = 626;
	var height = 436;
	leftPosition = (window.screen.width / 2) - ((width / 2) + 10);
	//Allow for title and status bars.
	topPosition = (window.screen.height / 2) - ((height / 2) + 50);
	var windowFeatures = "status=no,height=" + height + ",width=" + width + ",resizable=yes,left=" + leftPosition + ",top=" + topPosition + ",screenX=" + leftPosition + ",screenY=" + topPosition + ",toolbar=no,menubar=no,scrollbars=no,location=no,directories=no";
	//url += '?msg=' + link.attr('data-msg');
	window.open(url,'Twitter',windowFeatures);
	return false;
}

/**
 * share on Pinterest something (ex: article)
 * the clicked element must have two things
 * data-url: which contain the url that you are going to share
 * data-imt: the image of your share
 */
function openPinShare(target){
	var link = jQuery(target);
	var u = encodeURIComponent(link.attr('data-url'));
	var iu = encodeURIComponent(link.attr('data-img'));
	//var t = encodeURIComponent(link.attr('data-title'));
	var leftPosition, topPosition;
	//Allow for borders.
	var width = 750;
	var height = 550;
	leftPosition = (window.screen.width / 2) - ((width / 2) + 10);
	//Allow for title and status bars.
	topPosition = (window.screen.height / 2) - ((height / 2) + 50);
	var windowFeatures = "status=no,height=" + height + ",width=" + width + ",resizable=yes,left=" + leftPosition + ",top=" + topPosition + ",screenX=" + leftPosition + ",screenY=" + topPosition + ",toolbar=no,menubar=no,scrollbars=no,location=no,directories=no";
	window.open('https//www.pinterest.com/pin/create/button/?url='+ u +'&media=' + iu ,'sharer',windowFeatures);
	return false;
}

function isTouchScreen(){
	if ("ontouchstart" in window || navigator.msMaxTouchPoints)
        {
		return true;
        } else {
		return false;
        }
}
<|endoftext|>