<commit_before>import * as types from '../mutation-types'
import _ from 'underscore'
import timeago from 'timeago.js'

const state = {
    feedPosts:   [],
    recentPosts: [],
    posts:       [],
    end:         false
}

const mutations = {
    // 获取订阅源的文章
    [types.RECEIVE_FEED_POSTS](state, { data }) {
        for (let post of data) {
            if (post.pubdate != null) {
                post.pubdate = new timeago().format(post.pubdate.split('').splice(0, 19).join('').replace('T', ' '), 'zh_CN')
            }
        }
        if (data.length === 0) {
            state.end = true
            return
        } else if (state.feedPosts.length > 0 && data[0].feed_id === state.feedPosts[0].feed_id) {
            state.feedPosts = [...state.feedPosts, ...data]
        } else {
            state.end = false
            state.feedPosts = data
        }
    },
    // 获取最近未读文章
    [types.RECEIVE_RECENT_POSTS](state, { data }) {
        state.recentPosts = data
        for (let post of state.recentPosts) {
            if (post.pubdate != null) {
                post.pubdate = new timeago().format(post.pubdate.split('').splice(0, 19).join('').replace('T', ' '), 'zh_CN')
            }
        }
    },
    // 获取指定类型文章(收藏)
    [types.RECEIVE_POSTS](state, { data }) {
        state.posts = data
    },
    // 标记已读
    [types.READ_POST](state, post) {
        for (let feedpost of state.feedPosts) {
            if (feedpost._id === post._id) {
                feedpost.read = true
            }
        }
        // 替换首页显示的该订阅源的最新未读内容
        if (post.nextunread) {
            state.recentPosts = _.map(state.recentPosts, recentpost => {
                if (recentpost.feed_id === post.nextunread.feed_id) {
                    recentpost = {
                        ...recentpost,
                        ...post.nextunread,
                        pubdate: post.nextunread.pubdate && new timeago().format(post.nextunread.pubdate.split('').splice(0, 19).join('').replace('T', ' '), 'zh_CN'),
                        unread:  recentpost.unread - 1

                    }
                }
                return recentpost
            })
        } else {
            state.recentPosts = _.filter(state.recentPosts, recentpost => recentpost.feed_id !== post.feed_id)
        }
    },
    // 全部标记已读
    [types.READ_ALL](state, feed_id) {
        for (let post of state.feedPosts) {
            post.read = true
        }
        state.recentPosts = _.filter(state.recentPosts, recentpost => recentpost.feed_id !== feed_id)
    },
    // 收藏/取消收藏书籍 ID
    [types.MARK](state, post) {
        let newItems = [], exist = false
        for (let item of state.posts) {
            if (item._id !== post._id) {
                newItems.push(item)
            } else {
                // 取消收藏
                exist = true
            }
        }
        if (!exist) {
            newItems.push(post)
        }
        state.posts = newItems
    },
    // 点赞书籍 ID
    [types.LOVE](state, id) {
        state.posts = _.map(state.posts, post => {
            if (post._id === id) { post.love = !post.love }
            return post
        })
    }
}

export default {
    state,
    mutations
}
<commit_msg>fix problem of post append of same feed<commit_after>import * as types from '../mutation-types'
import _ from 'underscore'
import timeago from 'timeago.js'

const state = {
    feedPosts:   [],
    recentPosts: [],
    posts:       [],
    end:         false
}

const mutations = {
    // 获取订阅源的文章
    [types.RECEIVE_FEED_POSTS](state, { data }) {
        for (let post of data) {
            if (post.pubdate != null) {
                post.pubdate = new timeago().format(post.pubdate.split('').splice(0, 19).join('').replace('T', ' '), 'zh_CN')
            }
        }
        if (data.length === 0) {
            state.end = true
            return
        } else if (state.feedPosts.length > 0 && data[0].feed_id === state.feedPosts[0].feed_id && !state.end) {
            state.feedPosts = [...state.feedPosts, ...data]
        } else {
            state.end = false
            state.feedPosts = data
        }
    },
    // 获取最近未读文章
    [types.RECEIVE_RECENT_POSTS](state, { data }) {
        state.recentPosts = data
        for (let post of state.recentPosts) {
            if (post.pubdate != null) {
                post.pubdate = new timeago().format(post.pubdate.split('').splice(0, 19).join('').replace('T', ' '), 'zh_CN')
            }
        }
    },
    // 获取指定类型文章(收藏)
    [types.RECEIVE_POSTS](state, { data }) {
        state.posts = data
    },
    // 标记已读
    [types.READ_POST](state, post) {
        for (let feedpost of state.feedPosts) {
            if (feedpost._id === post._id) {
                feedpost.read = true
            }
        }
        // 替换首页显示的该订阅源的最新未读内容
        if (post.nextunread) {
            state.recentPosts = _.map(state.recentPosts, recentpost => {
                if (recentpost.feed_id === post.nextunread.feed_id) {
                    recentpost = {
                        ...recentpost,
                        ...post.nextunread,
                        pubdate: post.nextunread.pubdate && new timeago().format(post.nextunread.pubdate.split('').splice(0, 19).join('').replace('T', ' '), 'zh_CN'),
                        unread:  recentpost.unread - 1

                    }
                }
                return recentpost
            })
        } else {
            state.recentPosts = _.filter(state.recentPosts, recentpost => recentpost.feed_id !== post.feed_id)
        }
    },
    // 全部标记已读
    [types.READ_ALL](state, feed_id) {
        for (let post of state.feedPosts) {
            post.read = true
        }
        state.recentPosts = _.filter(state.recentPosts, recentpost => recentpost.feed_id !== feed_id)
    },
    // 收藏/取消收藏书籍 ID
    [types.MARK](state, post) {
        let newItems = [], exist = false
        for (let item of state.posts) {
            if (item._id !== post._id) {
                newItems.push(item)
            } else {
                // 取消收藏
                exist = true
            }
        }
        if (!exist) {
            newItems.push(post)
        }
        state.posts = newItems
    },
    // 点赞书籍 ID
    [types.LOVE](state, id) {
        state.posts = _.map(state.posts, post => {
            if (post._id === id) { post.love = !post.love }
            return post
        })
    }
}

export default {
    state,
    mutations
}
<|endoftext|>


<commit_before>angular.module('sources.clans', []).
factory('bloodlineSource', [function() {
	var map = [];
	var i = 0;
	//Assassamite
	map[i] = {"name": "None", "id": i++};
	map[i] = {"name": "Vizer", "id": i++};
	map[i] = {"name": "Sorcerer", "id": i++};

	//Brujah
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "True Brujah", "id": i++};

    //Follower of Set
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "Tlaclque", "id": i++};
    map[i] = {"name": "Viper", "id": i++};

    //Gangrel
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "Coyote", "id": i++};
    map[i] = {"name": "Noiad", "id": i++};
    map[i] = {"name": "Ahrimane", "id": i++};

    //Giovanni
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "Premascine", "id": i++};

    //Lasombra
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "Kisayd", "id": i++};

    //Malkavian
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "Ananke", "id": i++};
    map[i] = {"name": "Knight of the Moon", "id": i++};

    //Nosferatu
    map[i] = {"name": "None", "id": i++};

    //Toreador
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "Ishtarri", "id": i++};
    map[i] = {"name": "Volgirre", "id": i++};

    //Tremere
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "Telyav", "id": i++};

    //Tzimisce
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "Carpathian", "id": i++};
    map[i] = {"name": "Koldun", "id": i++};

    //Ventrue
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "Crusader", "id": i++};

    //Catiff
    map[i] = {"name": "None", "id": i++};

    //Baali
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "Angellis Ater", "id": i++};

    //Cappadocian
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "Samedi", "id": i++};
    map[i] = {"name": "Lamia", "id": i++};

    //Ravnos
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "Brahman", "id": i++};

    //Salubri
    map[i] = {"name": "None", "id": i++};
    map[i] = {"name": "Healer", "id": i++};

    //Daughter of Cacophony
    map[i] = {"name": "None", "id": i++};

    //Gargoyle
    map[i] = {"name": "None", "id": i++};

	return {
		get: function() {
			return map;
		}
	}
}]).
factory('clanSource', ['bloodlineSource', function(bloodlineSource) {
	var map = [];
	var i = 0;
	var bi = 0;
	var bloodlines = bloodlineSource.get();
    map[i] = {"name": "Assamite", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name": "Brujah", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name": "Follower of Set", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name": "Gangrel", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name": "Giovanni", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name": "Lasombra", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name": "Malkavian", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name": "Nosferatu", "id": i++, "bloodlines": [bloodlines[bi++]]};
    map[i] = {"name": "Toreador", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name": "Tremere", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name":  "Tzimisce", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name":  "Ventrue", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name":  "Catiff", "id": i++, "bloodlines": [bloodlines[bi++]]};
    map[i] = {"name":  "Baali", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name":  "Cappadocian", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name":  "Ravnos", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name":  "Salubri", "id": i++, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[i] = {"name":  "Daughter of Cacophony", "id": i++, "bloodlines": [bloodlines[bi++]]};
    map[i] = {"name":  "Gargoyle", "id": i++, "bloodlines": [bloodlines[bi++]]};

	return {
		get: function() {
			return map;
		}
	}
}]);<commit_msg>Format tinkering with bloodlines.<commit_after>angular.module('sources.clans', []).
factory('bloodlineSource', [function() {
	var map = [];
	var i = -1;
	//Assassamite
	map[++i] = {"name": "None", "id": i};
	map[++i] = {"name": "Vizer", "id": i};
	map[++i] = {"name": "Sorcerer", "id": i};

	//Brujah
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "True Brujah", "id": i};

    //Follower of Set
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "Tlaclque", "id": i};
    map[++i] = {"name": "Viper", "id": i};

    //Gangrel
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "Coyote", "id": i};
    map[++i] = {"name": "Noiad", "id": i};
    map[++i] = {"name": "Ahrimane", "id": i};

    //Giovanni
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "Premascine", "id": i};

    //Lasombra
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "Kisayd", "id": i};

    //Malkavian
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "Ananke", "id": i};
    map[++i] = {"name": "Knight of the Moon", "id": i};

    //Nosferatu
    map[++i] = {"name": "None", "id": i};

    //Toreador
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "Ishtarri", "id": i};
    map[++i] = {"name": "Volgirre", "id": i};

    //Tremere
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "Telyav", "id": i};

    //Tzimisce
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "Carpathian", "id": i};
    map[++i] = {"name": "Koldun", "id": i};

    //Ventrue
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "Crusader", "id": i};

    //Catiff
    map[++i] = {"name": "None", "id": i};

    //Baali
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "Angellis Ater", "id": i};

    //Cappadocian
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "Samedi", "id": i};
    map[++i] = {"name": "Lamia", "id": i};

    //Ravnos
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "Brahman", "id": i};

    //Salubri
    map[++i] = {"name": "None", "id": i};
    map[++i] = {"name": "Healer", "id": i};

    //Daughter of Cacophony
    map[++i] = {"name": "None", "id": i};

    //Gargoyle
    map[++i] = {"name": "None", "id": i};

	return {
		get: function() {
			return map;
		}
	}
}]).
factory('clanSource', ['bloodlineSource', function(bloodlineSource) {
	var map = [];
	var i = -1;
	var bi = 0;
	var bloodlines = bloodlineSource.get();
    map[++i] = {"name": "Assamite", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name": "Brujah", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name": "Follower of Set", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name": "Gangrel", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name": "Giovanni", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name": "Lasombra", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name": "Malkavian", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name": "Nosferatu", "id": i, "bloodlines": [bloodlines[bi++]]};
    map[++i] = {"name": "Toreador", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name": "Tremere", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name":  "Tzimisce", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name":  "Ventrue", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name":  "Catiff", "id": i, "bloodlines": [bloodlines[bi++]]};
    map[++i] = {"name":  "Baali", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name":  "Cappadocian", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name":  "Ravnos", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name":  "Salubri", "id": i, "bloodlines": [bloodlines[bi++], bloodlines[bi++]]};
    map[++i] = {"name":  "Daughter of Cacophony", "id": i, "bloodlines": [bloodlines[bi++]]};
    map[++i] = {"name":  "Gargoyle", "id": i, "bloodlines": [bloodlines[bi++]]};

	return {
		get: function() {
			return map;
		}
	}
}]);<|endoftext|>


<commit_before>import React from 'react';
import { Button, Row, Col } from 'react-bootstrap';
import FontAwesome from 'react-fontawesome';

const TeamHeader = ({_id: id, teamName}) => {
    return(
        <Button className="team-header">
            <Row>
                <Col xs={2}>
                    <FontAwesome name="user-add"/>
                </Col>
                <Col xs={10} className="team-name">

{teamName}

                </Col>
            </Row>
        </Button>
    );
};

export default TeamHeader;<commit_msg>feat: added the project name field to the Team Header Component<commit_after>import React from 'react';
import { Button, Row, Col } from 'react-bootstrap';
import FontAwesome from 'react-fontawesome';

const TeamHeader = ({_id: id, teamName, projectName}) => {
    return(
        <Button className="team-header">
            <Row>
                <Col xs={2}>
                    <FontAwesome name="user-add"/>
                </Col>
                <Col xs={10} className="team-name">

{teamName} / {projectName}

                </Col>
            </Row>
        </Button>
    );
};

export default TeamHeader;<|endoftext|>


<commit_before>/*
* Copyright (c) 2013 DataTorrent, Inc. ALL Rights Reserved.
*
* 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
*
*   http://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.
*/
var _ = require('underscore');
var kt = require('knights-templar');
var Notifier = require('./Notifier');
var BaseView = require('bassview');
var SettingsView = require('./WidgetSettingsView');
var WidgetCtrl = BaseView.extend({

    initialize: function() {
        // Extend events if necessary
        if (this.events !== WidgetCtrl.prototype.events) {
            this.events = _.extend({},WidgetCtrl.prototype.events,this.events);
        }

        // Listen for changes to the id
        this.listenTo(this.model, 'change:id', this.render);
    },

    events: {
        'click .wi-delete': 'onDeleteClick',
        'click .wi-settings': 'openSettings',
        'click .wi-editName': 'editId',
        'dblclick span.wid': 'editId',
        'blur input.wid': 'saveId',
        'keydown input.wid': 'checkForEnter'
    },

    onDeleteClick: function(evt) {
        // Clear the timeout function if there
        if (this.__single_click_timeout) clearTimeout(this.__single_click_timeout);

        // check if this is a second click in a dblclick
        if (this.__delete_click_triggered) {
            this.__delete_click_triggered = false;
            this.deleteNoAlert(evt);
            return;
        }

        // not a dblclick, set the timeout
        this.__single_click_timeout = setTimeout(function(){
            this.__delete_click_triggered = false;
            this.deleteWithAlert(evt);
        }.bind(this), 200);

        // variable to keep track of dblclick/single click state
        this.__delete_click_triggered = true;
    },

    deleteWithAlert: function(evt) {
        var c = confirm('Are you sure you want to delete this widget from the dashboard? Note: double-click the trash can to suppress this warning.');
        if (c) {
            this.deleteNoAlert();
        }
    },

    deleteNoAlert: function() {
        this.collection.remove(this.model);
        this.model.trigger('remove');
    },

    editId: function(evt){

        if (this._editingId) {
            this.saveId(evt);
            return;
        }

        evt.preventDefault();
        evt.stopPropagation();

        // cache the .wid el
        var $wid = this.$('.wid');
        if (!$wid.length) return;
        // get the current id
        var curId = this.model.get('id');
        // create input
        var $input = $('<input type="text" class="wid input-small" value="'+curId+'" />');
        // replace el with the new input
        $wid.replaceWith($input);
        // focus on the input
        $input.focus();

        this._editingId = true;
    },

    checkForEnter: function(evt) {
        if (evt.which == 13) this.saveId(evt);
    },

    saveId: _.throttle(function(evt){
        // get val of input
        var newId = evt.target.value;

        // check if nothing has been changed
        if (newId == this.model.get('id')) return this.render();

        // check the collection for other widgets with this id
        if (this.model.collection) {
            var already = this.model.collection.get(newId);
            if (already) {
                this.render();
                Notifier.error({
                    'title': 'id \''+newId+'\' in use',
                    'text': 'There is already a widget with that id. Ensure that the new name is not used.'
                });
                return;
            }
        }

        // set the id to this
        this.model.set('id', newId);

        this._editingId = false;
    }, 100),

    openSettings: function(evt) {
        var settings = new SettingsView({
            model: this.model
        });
        var $settings_el = $('

').appendTo('body');

        settings.setElement($settings_el[0]);
        settings.render();
    }

});
exports = module.exports = WidgetCtrl;<commit_msg>MLHR-813 #resolve<commit_after>/*
* Copyright (c) 2013 DataTorrent, Inc. ALL Rights Reserved.
*
* 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
*
*   http://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.
*/
var _ = require('underscore');
var kt = require('knights-templar');
var Notifier = require('./Notifier');
var BaseView = require('bassview');
var SettingsView = require('./WidgetSettingsView');
var WidgetCtrl = BaseView.extend({

    initialize: function() {
        // Extend events if necessary
        if (this.events !== WidgetCtrl.prototype.events) {
            this.events = _.extend({},WidgetCtrl.prototype.events,this.events);
        }

        // Listen for changes to the id
        this.listenTo(this.model, 'change:id', this.render);
    },

    events: {
        'click .wi-delete': 'onDeleteClick',
        'click .wi-settings': 'openSettings',
        'click .wi-editName': 'editId',
        'dblclick span.wid': 'editId',
        'blur input.wid': 'saveId',
        'keydown input.wid': 'checkForEnter'
    },

    onDeleteClick: function(evt) {
        // Clear the timeout function if there
        if (this.__single_click_timeout) clearTimeout(this.__single_click_timeout);

        // check if this is a second click in a dblclick
        if (this.__delete_click_triggered) {
            this.__delete_click_triggered = false;
            this.deleteNoAlert(evt);
            return;
        }

        // not a dblclick, set the timeout
        this.__single_click_timeout = setTimeout(function(){
            this.__delete_click_triggered = false;
            this.deleteWithAlert(evt);
        }.bind(this), 200);

        // variable to keep track of dblclick/single click state
        this.__delete_click_triggered = true;
    },

    deleteWithAlert: function(evt) {
        var c = confirm('Are you sure you want to delete this widget from the dashboard? Note: double-click the "x" icon to suppress this warning.');
        if (c) {
            this.deleteNoAlert();
        }
    },

    deleteNoAlert: function() {
        this.collection.remove(this.model);
        this.model.trigger('remove');
    },

    editId: function(evt){

        if (this._editingId) {
            this.saveId(evt);
            return;
        }

        evt.preventDefault();
        evt.stopPropagation();

        // cache the .wid el
        var $wid = this.$('.wid');
        if (!$wid.length) return;
        // get the current id
        var curId = this.model.get('id');
        // create input
        var $input = $('<input type="text" class="wid input-small" value="'+curId+'" />');
        // replace el with the new input
        $wid.replaceWith($input);
        // focus on the input
        $input.focus();

        this._editingId = true;
    },

    checkForEnter: function(evt) {
        if (evt.which == 13) this.saveId(evt);
    },

    saveId: _.throttle(function(evt){
        // get val of input
        var newId = evt.target.value;

        // check if nothing has been changed
        if (newId == this.model.get('id')) return this.render();

        // check the collection for other widgets with this id
        if (this.model.collection) {
            var already = this.model.collection.get(newId);
            if (already) {
                this.render();
                Notifier.error({
                    'title': 'id \''+newId+'\' in use',
                    'text': 'There is already a widget with that id. Ensure that the new name is not used.'
                });
                return;
            }
        }

        // set the id to this
        this.model.set('id', newId);

        this._editingId = false;
    }, 100),

    openSettings: function(evt) {
        var settings = new SettingsView({
            model: this.model
        });
        var $settings_el = $('

').appendTo('body');

        settings.setElement($settings_el[0]);
        settings.render();
    }

});
exports = module.exports = WidgetCtrl;<|endoftext|>


<commit_before>// Copyright 2013 The Toolkitchen Authors. All rights reserved.
// Use of this source code is goverened by a BSD-style
// license that can be found in the LICENSE file.

(function(exports) {
  'use strict';

  var wrappedFuns = new SideTable();
  var listenersTable = new SideTable();
  var handledEventsTable = new SideTable();
  var targetTable = new SideTable();
  var currentTargetTable = new SideTable();
  var eventPhaseTable = new SideTable();
  var stopPropagationTable = new SideTable();
  var stopImmediatePropagationTable = new SideTable();

  function isShadowRoot(node) {
    return node instanceof WrapperShadowRoot;
  }

  function isInsertionPoint(node) {
    var localName = node.localName;
    return localName === 'content' || localName === 'shadow';
  }

  function isShadowHost(node) {
    return !!node.shadowRoot;
  }

  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-adjusted-parent
  function calculateParent(node, context) {
    // 1.
    if (isShadowRoot(node))
      return node.insertionPointParent || getHostForShadowRoot(node)

    // 2.
    var p = node.insertionPointParent;
    if (p)
      return p;

    // 3.
    if (context && isInsertionPoint(node)) {
      var parentNode = node.parentNode;
      if (parentNode && isShadowHost(parentNode)) {
        var trees = getShadowTrees(parentNode);
        var p = context.insertionPointParent;
        for (var i = 0; i < trees.length; i++) {
          if (trees[i].contains(p))
            return p;
        }
      }
    }

    return node.parentNode;
  }

  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#event-retargeting
  function retarget(node) {
    var stack = [];  // 1.
    var ancestor = node;  // 2.
    var targets = [];
    while (ancestor) {  // 3.
      var context = null;  // 3.2.
      if (isInsertionPoint(ancestor)) {  // 3.1.
        context = topMostNotInsertionPoint(stack);  // 3.1.1.
        var top = stack[stack.length - 1] || ancestor;  // 3.1.2.
        stack.push(top);
      }
      if (!stack.length)
        stack.push(ancestor);  // 3.3.
      var target = stack[stack.length - 1];  // 3.4.
      targets.push({target: target, ancestor: ancestor});  // 3.5.
      if (isShadowRoot(ancestor))  // 3.6.
        stack.pop();  // 3.6.1.
      ancestor = calculateParent(ancestor, context);
    }
    return targets;
  }

  function topMostNotInsertionPoint(stack) {
    for (var i = stack.length - 1; i >= 0; i--) {
      if (!isInsertionPoint(stack[i]))
        return stack[i];
    }
    return null;
  }

  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-adjusted-related-target
  function adjustRelatedTarget(target, related) {
    while (target) {  // 3.
      var stack = [];  // 3.1.
      var ancestor = related;  // 3.2.
      var last = undefined;  // 3.3. Needs to be reset every iteration.
      while (ancestor) {
        var context = null;
        if (!stack.length) {
          stack.push(ancestor);
        } else {
          if (isInsertionPoint(ancestor)) {  // 3.4.3.
            context = topMostNotInsertionPoint(stack);
            // isDistributed is more general than checking whether last is
            // assigned into ancestor.
            if (isDistributed(last)) {  // 3.4.3.2.
              var head = stack[stack.length - 1];
              stack.push(head);
            }
          }
        }

        if (inSameTree(ancestor, target))  // 3.4.4.
          return stack[stack.length - 1];

        if (isShadowRoot(ancestor))  // 3.4.5.
          stack.pop();

        last = ancestor;  // 3.4.6.
        ancestor = calculateParent(ancestor, context);  // 3.4.7.
      }
      if (isShadowRoot(target))  // 3.5.
        target = getHostForShadowRoot(target);
      else
        target = target.parentNode;  // 3.6.
    }
  }

  function isDistributed(node) {
    return node.insertionPointParent;
  }

  function inSameTree(a, b) {
    while (true) {
      if (a === b)
        return a !== null;
      if (a)
        a = a.parentNode;
      if (b)
        b = b.parentNode;
    }
  }

  function dispatchOriginalEvent(originalEvent) {
    // Make sure this event is only dispatched once.
    if (handledEventsTable.get(originalEvent))
      return;
    handledEventsTable.set(originalEvent, true);

    var target = wrap(originalEvent.target);
    var event = wrap(originalEvent);
    return dispatchEvent(event, target);
  }

  function dispatchEvent(event, originalWrapperTarget) {
    var type = event.type;
    var bubbles = event.bubbles;
    var ancestorChain = retarget(originalWrapperTarget);
    var i = ancestorChain.length - 1;

    var phase = Event.CAPTURING_PHASE;
    eventPhaseTable.set(event, phase);

    var propagationStopped = false;

    for (; !propagationStopped && i > 0; i--) {
      propagationStopped = invoke(ancestorChain[i], event, type, phase);
    }

    phase = Event.AT_TARGET;
    eventPhaseTable.set(event, phase);

    if (!propagationStopped) {
      propagationStopped = invoke(ancestorChain[0], event, type, phase);
      i++;
    }

    if (bubbles) {
      phase = Event.BUBBLING_PHASE;
      eventPhaseTable.set(event, phase);

      for (; !propagationStopped && i < ancestorChain.length; i++) {
        propagationStopped = invoke(ancestorChain[i], event, type, phase);
      }
    }

    phase = Event.NONE;
    eventPhaseTable.set(event, phase);
    currentTargetTable.set(event, null);

    return event.defaultPrevented;
  }

  function invoke(tuple, event, type, phase) {
    var target = tuple.target;
    var currentTarget = tuple.ancestor;

    var listeners = listenersTable.get(currentTarget);
    if (!listeners)
      return;

    var anyRemoved = false;
    targetTable.set(event, target);
    currentTargetTable.set(event, currentTarget);

    for (var i = 0; i < listeners.length; i++) {
      var listener = listeners[i];
      if (listener.removed) {
        anyRemoved = true;
        continue;
      }

      if (listener.type !== type ||
          !listener.capture && phase === Event.CAPTURING_PHASE ||
          listener.capture && phase === Event.BUBBLING_PHASE) {
        continue;
      }

      try {
        if (typeof listener.handler === 'function')
          listener.handler.call(currentTarget, event);
        else
          listener.handler.handleEvent(event);

        if (stopImmediatePropagationTable.get(event))
          return true;

      } catch (ex) {
        if (window.onerror)
          window.onerror(ex.message);
        else
          console.error(ex);
      }
    }

    if (anyRemoved) {
      var copy = listeners.slice();
      listeners.length = 0;
      for (var i = 0; i < copy.length; i++) {
        if (!copy[i].removed)
          listeners.push(copy[i]);
      }
    }

    return stopPropagationTable.get(event);
  }

  function Listener(type, handler, capture) {
    this.type = type;
    this.handler = handler;
    this.capture = capture;
  }
  Listener.prototype = {
    equals: function(that) {
      return this.type === that.type && this.handler === that.handler &&
          this.capture === that.capture;
    },
    get removed() {
      return this.handler === null;
    },
    remove: function() {
      this.handler = null;
    }
  };

  /**
   * This represents a logical DOM node.
   * @param {!Node} original The original DOM node, aka, the visual DOM node.
   * @constructor
   */
  function WrapperEvent(original) {
    /**
     * @type {!Event}
     */
    this.impl = original;
  }

  WrapperEvent.prototype = {
    get target() {
      return targetTable.get(this);
    },
    get currentTarget() {
      return currentTargetTable.get(this);
    },
    get eventPhase() {
      return eventPhaseTable.get(this);
    },
    stopPropagation: function() {
      stopPropagationTable.set(this, true);
    },
    stopImmediatePropagation: function() {
      stopPropagationTable.set(this, true);
      stopImmediatePropagationTable.set(this, true);
    }
  };

  wrappers.register(Event, WrapperEvent, document.createEvent('Event'));

  /**
   * This represents a logical DOM node.
   * @param {!Node} original The original DOM node, aka, the visual DOM node.
   * @constructor
   */
  function WrapperEventTarget(original) {
    /**
     * @type {!Node}
     */
    this.impl = original;
  }

  WrapperEventTarget.prototype = {
    addEventListener: function(type, fun, capture) {
      var listener = new Listener(type, fun, capture);
      var listeners = listenersTable.get(this);
      if (!listeners) {
        listeners = [];
        listenersTable.set(this, listeners);
      } else {
        // Might have a duplicate.
        for (var i = 0; i < listeners.length; i++) {
          if (listener.equals(listeners[i]))
            return;
        }
      }

      listeners.push(listener);

      unwrap(this).addEventListener(type, dispatchOriginalEvent, true);
    },
    removeEventListener: function(type, fun, capture) {
      var listeners = listenersTable.get(this);
      if (!listeners)
        return;
      var listener = new Listener(type, fun, capture);
      for (var i = 0; listeners.length; i++) {
        if (listener.equals(listeners[i])) {
          listeners[i].remove();
          return;
        }
      }
    },
    dispatchEvent: function(event) {
      return dispatchEvent(event, this);
    }
  };

  if (typeof EventTarget !== 'undefined')
    wrappers.register(EventTarget, WrapperEventTarget);

  exports.WrapperEvent = WrapperEvent;
  exports.WrapperEventTarget = WrapperEventTarget;

  exports.adjustRelatedTarget = adjustRelatedTarget;
})(this);
<commit_msg>Correctly handle missing capture parameter<commit_after>// Copyright 2013 The Toolkitchen Authors. All rights reserved.
// Use of this source code is goverened by a BSD-style
// license that can be found in the LICENSE file.

(function(exports) {
  'use strict';

  var wrappedFuns = new SideTable();
  var listenersTable = new SideTable();
  var handledEventsTable = new SideTable();
  var targetTable = new SideTable();
  var currentTargetTable = new SideTable();
  var eventPhaseTable = new SideTable();
  var stopPropagationTable = new SideTable();
  var stopImmediatePropagationTable = new SideTable();

  function isShadowRoot(node) {
    return node instanceof WrapperShadowRoot;
  }

  function isInsertionPoint(node) {
    var localName = node.localName;
    return localName === 'content' || localName === 'shadow';
  }

  function isShadowHost(node) {
    return !!node.shadowRoot;
  }

  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-adjusted-parent
  function calculateParent(node, context) {
    // 1.
    if (isShadowRoot(node))
      return node.insertionPointParent || getHostForShadowRoot(node)

    // 2.
    var p = node.insertionPointParent;
    if (p)
      return p;

    // 3.
    if (context && isInsertionPoint(node)) {
      var parentNode = node.parentNode;
      if (parentNode && isShadowHost(parentNode)) {
        var trees = getShadowTrees(parentNode);
        var p = context.insertionPointParent;
        for (var i = 0; i < trees.length; i++) {
          if (trees[i].contains(p))
            return p;
        }
      }
    }

    return node.parentNode;
  }

  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#event-retargeting
  function retarget(node) {
    var stack = [];  // 1.
    var ancestor = node;  // 2.
    var targets = [];
    while (ancestor) {  // 3.
      var context = null;  // 3.2.
      if (isInsertionPoint(ancestor)) {  // 3.1.
        context = topMostNotInsertionPoint(stack);  // 3.1.1.
        var top = stack[stack.length - 1] || ancestor;  // 3.1.2.
        stack.push(top);
      }
      if (!stack.length)
        stack.push(ancestor);  // 3.3.
      var target = stack[stack.length - 1];  // 3.4.
      targets.push({target: target, ancestor: ancestor});  // 3.5.
      if (isShadowRoot(ancestor))  // 3.6.
        stack.pop();  // 3.6.1.
      ancestor = calculateParent(ancestor, context);
    }
    return targets;
  }

  function topMostNotInsertionPoint(stack) {
    for (var i = stack.length - 1; i >= 0; i--) {
      if (!isInsertionPoint(stack[i]))
        return stack[i];
    }
    return null;
  }

  // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-adjusted-related-target
  function adjustRelatedTarget(target, related) {
    while (target) {  // 3.
      var stack = [];  // 3.1.
      var ancestor = related;  // 3.2.
      var last = undefined;  // 3.3. Needs to be reset every iteration.
      while (ancestor) {
        var context = null;
        if (!stack.length) {
          stack.push(ancestor);
        } else {
          if (isInsertionPoint(ancestor)) {  // 3.4.3.
            context = topMostNotInsertionPoint(stack);
            // isDistributed is more general than checking whether last is
            // assigned into ancestor.
            if (isDistributed(last)) {  // 3.4.3.2.
              var head = stack[stack.length - 1];
              stack.push(head);
            }
          }
        }

        if (inSameTree(ancestor, target))  // 3.4.4.
          return stack[stack.length - 1];

        if (isShadowRoot(ancestor))  // 3.4.5.
          stack.pop();

        last = ancestor;  // 3.4.6.
        ancestor = calculateParent(ancestor, context);  // 3.4.7.
      }
      if (isShadowRoot(target))  // 3.5.
        target = getHostForShadowRoot(target);
      else
        target = target.parentNode;  // 3.6.
    }
  }

  function isDistributed(node) {
    return node.insertionPointParent;
  }

  function inSameTree(a, b) {
    while (true) {
      if (a === b)
        return a !== null;
      if (a)
        a = a.parentNode;
      if (b)
        b = b.parentNode;
    }
  }

  function dispatchOriginalEvent(originalEvent) {
    // Make sure this event is only dispatched once.
    if (handledEventsTable.get(originalEvent))
      return;
    handledEventsTable.set(originalEvent, true);

    var target = wrap(originalEvent.target);
    var event = wrap(originalEvent);
    return dispatchEvent(event, target);
  }

  function dispatchEvent(event, originalWrapperTarget) {
    var type = event.type;
    var bubbles = event.bubbles;
    var ancestorChain = retarget(originalWrapperTarget);
    var i = ancestorChain.length - 1;

    var phase = Event.CAPTURING_PHASE;
    eventPhaseTable.set(event, phase);

    var propagationStopped = false;

    for (; !propagationStopped && i > 0; i--) {
      propagationStopped = invoke(ancestorChain[i], event, type, phase);
    }

    phase = Event.AT_TARGET;
    eventPhaseTable.set(event, phase);

    if (!propagationStopped) {
      propagationStopped = invoke(ancestorChain[0], event, type, phase);
      i++;
    }

    if (bubbles) {
      phase = Event.BUBBLING_PHASE;
      eventPhaseTable.set(event, phase);

      for (; !propagationStopped && i < ancestorChain.length; i++) {
        propagationStopped = invoke(ancestorChain[i], event, type, phase);
      }
    }

    phase = Event.NONE;
    eventPhaseTable.set(event, phase);
    currentTargetTable.set(event, null);

    return event.defaultPrevented;
  }

  function invoke(tuple, event, type, phase) {
    var target = tuple.target;
    var currentTarget = tuple.ancestor;

    var listeners = listenersTable.get(currentTarget);
    if (!listeners)
      return;

    var anyRemoved = false;
    targetTable.set(event, target);
    currentTargetTable.set(event, currentTarget);

    for (var i = 0; i < listeners.length; i++) {
      var listener = listeners[i];
      if (listener.removed) {
        anyRemoved = true;
        continue;
      }

      if (listener.type !== type ||
          !listener.capture && phase === Event.CAPTURING_PHASE ||
          listener.capture && phase === Event.BUBBLING_PHASE) {
        continue;
      }

      try {
        if (typeof listener.handler === 'function')
          listener.handler.call(currentTarget, event);
        else
          listener.handler.handleEvent(event);

        if (stopImmediatePropagationTable.get(event))
          return true;

      } catch (ex) {
        if (window.onerror)
          window.onerror(ex.message);
        else
          console.error(ex);
      }
    }

    if (anyRemoved) {
      var copy = listeners.slice();
      listeners.length = 0;
      for (var i = 0; i < copy.length; i++) {
        if (!copy[i].removed)
          listeners.push(copy[i]);
      }
    }

    return stopPropagationTable.get(event);
  }

  function Listener(type, handler, capture) {
    this.type = type;
    this.handler = handler;
    this.capture = Boolean(capture);
  }
  Listener.prototype = {
    equals: function(that) {
      return this.handler === that.handler && this.type === that.type &&
          this.capture === that.capture;
    },
    get removed() {
      return this.handler === null;
    },
    remove: function() {
      this.handler = null;
    }
  };

  /**
   * This represents a logical DOM node.
   * @param {!Node} original The original DOM node, aka, the visual DOM node.
   * @constructor
   */
  function WrapperEvent(original) {
    /**
     * @type {!Event}
     */
    this.impl = original;
  }

  WrapperEvent.prototype = {
    get target() {
      return targetTable.get(this);
    },
    get currentTarget() {
      return currentTargetTable.get(this);
    },
    get eventPhase() {
      return eventPhaseTable.get(this);
    },
    stopPropagation: function() {
      stopPropagationTable.set(this, true);
    },
    stopImmediatePropagation: function() {
      stopPropagationTable.set(this, true);
      stopImmediatePropagationTable.set(this, true);
    }
  };

  wrappers.register(Event, WrapperEvent, document.createEvent('Event'));

  /**
   * This represents a logical DOM node.
   * @param {!Node} original The original DOM node, aka, the visual DOM node.
   * @constructor
   */
  function WrapperEventTarget(original) {
    /**
     * @type {!Node}
     */
    this.impl = original;
  }

  WrapperEventTarget.prototype = {
    addEventListener: function(type, fun, capture) {
      var listener = new Listener(type, fun, capture);
      var listeners = listenersTable.get(this);
      if (!listeners) {
        listeners = [];
        listenersTable.set(this, listeners);
      } else {
        // Might have a duplicate.
        for (var i = 0; i < listeners.length; i++) {
          if (listener.equals(listeners[i]))
            return;
        }
      }

      listeners.push(listener);

      unwrap(this).addEventListener(type, dispatchOriginalEvent, true);
    },
    removeEventListener: function(type, fun, capture) {
      var listeners = listenersTable.get(this);
      if (!listeners)
        return;
      var listener = new Listener(type, fun, capture);
      for (var i = 0; listeners.length; i++) {
        if (listener.equals(listeners[i])) {
          listeners[i].remove();
          return;
        }
      }
    },
    dispatchEvent: function(event) {
      return dispatchEvent(event, this);
    }
  };

  if (typeof EventTarget !== 'undefined')
    wrappers.register(EventTarget, WrapperEventTarget);

  exports.WrapperEvent = WrapperEvent;
  exports.WrapperEventTarget = WrapperEventTarget;

  exports.adjustRelatedTarget = adjustRelatedTarget;
})(this);
<|endoftext|>


<commit_before>import React from 'react';
import cssModules from 'react-css-modules';
import styles from './index.module.scss';
// importing the gromment components used in this page
import Box from 'grommet-udacity/components/Box';
import Paragraph from 'grommet-udacity/components/Paragraph';
import Card from 'grommet-udacity/components/Card';
import Anchor from 'grommet-udacity/components/Anchor';
import App from 'grommet-udacity/components/App';
import Split from 'grommet-udacity/components/Split';
import Article from 'grommet-udacity/components/Article';
import Sidebar from 'grommet-udacity/components/Sidebar';
import Heading from 'grommet-udacity/components/Heading';
import Hero from 'grommet-udacity/components/Hero';
import Headline from 'grommet-udacity/components/Headline';
import { MartinRulz,
        AppFooter } from 'components';
// importing the content
import contributorVoices from './contributorVoices';
// Change as needed.  This image is optimized
const AboutPageImage = 'https://github.com/RyanCCollins/cdn/blob/master/alumni-webapp/meetups.jpeg?raw=true';

const AboutPage = () => (

    <App>
      <Split
        fixed="false"
        priority="left"
        showOnResponsive="priority"
        flex="both"
      >

            <Headline strong>
              What’s all this About?
            </Headline>
            <Heading tag="h2" strong>
              A (not so) short Why of this project.
            </Heading>
            <Paragraph>
              So you’ve graduated from one of Udacity’s Nanodegrees! Congratulations! :thumbs_up: :tada: You’re now a part of the Udacity Alumni slack channel (<- click if you’re not yet. You should be). There you’ve read some discussions, or had some discussions, and probably you’re super excited about all those other smart and handsome Alumni that are working on a million of compelling projects! (… Wait… don’t go those dark places. Fight the impostor syndrome creeping up… Grind it, gnaw it - - remember you’ve learned a lot, and most importantly you’ve learned how to learn ever more!! Your best projects lie in the future! Hm…, I can hear you think, …so what if there was a possibility to get in touch with the person who’s working on project Awwwsome…? Alright! : ) Seems we’re back on track! Great, here we go!)
            </Paragraph>
            <Paragraph>
              We’re all Udacity Alumni here. We come from a great number of diverse backgrounds. Some worked in construction before hopping onto the digital train, some in Canada, some in the Arts. Some are in school, others graduated from university with a degree in communications. Some even did a programming related education, dabbled with their mum’s tower PC after having just started to walk, or worked in these fields before - but there are also many of us who have not. Online education offers this possibility to change your path and follow interests in a new way. Some even dive into the digital world in their retirement! Yes, we’re a diverse bunch. There are those that can dedicate all their waking hours to this new path, and there are those who somehow manage to juggle all the materials while working a full-time job or raising a family (Respect!). But there is more: Coming from all corners of the world, we tie together a bouquet of timezones so that it is fair to say that this community never sleeps. And some of us stay where they are to work and study from the comfort of their homes, some others zip around and learn how to find internet on the road.
            </Paragraph>
            <Paragraph>
              Online education is a big box filled with surprises and opportunities - and interesting people.
            </Paragraph>
            <Paragraph>
              But as diverse as we might be, there’s something that ties us together: the wish to learn and the will to work for it.
            </Paragraph>
            <Paragraph>
              This webapp was born from these principles.
            </Paragraph>
            <Paragraph>
              The Alumni Webapp is a collaborative project built by and for Alumnis. It aims on creating a platform that allows us to exchange ideas, opinions, projects, jobs and whatnot. Having this webapp should strengthen the alumni community by offering chances to work together, find places to meet up and organize events.
            </Paragraph>
            <Paragraph>
              It is also a work-in-progress and as such it aims on providing another piece of the puzzle that can teach us to become better digital workers: collaboration on real-world products.
              During our Nanodegrees we spent our time learning from Udacity’s Resources and from the vast plains of the web. Then we wrapped up and applied that knowledge to fulfill tasks and complete projects. We’ve learned to research topics and errors by ourselves, and sometimes ask for support. We got to know what it’s like to build a project, receive feedback on our work, then iterate and improve.
            </Paragraph>
            <Paragraph>
              But how is it like to build something collaboratively? There’s a whole set of new skills to be tried and learned, and the Open Source Community offers great practice grounds for that. But the wide world’s web might be too intimidating to start out - so here we have our very own open source project that everyone is invited to collaborate to. A safe place to try, among people who appreciate trying. : )
            </Paragraph>
            <Paragraph>
              Collaborating is about being part of building a tool that can benefit yourself and all the other Alumnis out there. It’s about breathing life into your ideas, and it’s about working to make them happen collaboratively.
            </Paragraph>
            <Paragraph>
              Because we’re a great bunch of people who have gone through a similar path of education. We know what it’s like to be stuck, what it’s like to come from an unrelated background and doubt whether we actually know anything at all. We also know that we can learn how to do something new and exciting, and we are happy to give back to the community and help others along their personal way.
            </Paragraph>
            <Paragraph>
              So here’s something to ponder:
              When you jumble up the letters of “alumni” and add the first letters of “For You”, you get “nu FamilY”.
            </Paragraph>
            <Paragraph>
              Coincidence? Maybe.
            </Paragraph>
            <Paragraph>
              A bad wordplay? Definitely.
            </Paragraph>
            <Paragraph>
              But in a way this is what we are - and what we aim to be for each other:
            </Paragraph>
            <Paragraph>
              A community of like-minded people who want to learn more and help each other on our ways.
            </Paragraph>
            <Paragraph>
              The Udacity Alumni Webapp is the place where we can work on this together.
            </Paragraph>
            <Paragraph>
              So that’s what this is all about. : )
            </Paragraph>
            <Paragraph>
              Hopefully you like the app and the idea, and you’ll feel encouraged to post, propose, code, improve, communicate, meet, build, share and dream.
            </Paragraph>
            <Paragraph>
              And to do anything else that will help to make this place reflect the humble greatness of the people and ideas that make up this community.
            </Paragraph>

        <Sidebar>
          <Box
            pad="large"
          >
            <Heading tag="h2" strong>
              Contributor Voices
            </Heading>
            <Paragraph>
            <Card label="Anything you want" thumbnail="https://upload.wikimedia.org/wikipedia/commons/3/33/White_square_with_question_mark.png"
              heading="You!" description="There surely is something you can do to make this better! : )"
              link={<Anchor href="https://github.com/udacityalumni" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Coder" thumbnail="https://avatars0.githubusercontent.com/u/10746052?v=3&s=400"
              heading="zhangs" description="The project is about learning React and practice collaborative development with friendly fellow Udacians."
              link={<Anchor href="https://github.com/zhangtreefish" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Unknown" thumbnail="https://upload.wikimedia.org/wikipedia/commons/3/33/White_square_with_question_mark.png"
              heading="Anonymous" description="Above all else, this project has connected me with an outstanding group of people, all of whom share my passion for education."
              link={<Anchor href="https://github.com/anonymous" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Coder" thumbnail="https://avatars1.githubusercontent.com/u/2024584?v=3&s=400"
              heading="Kelli Blalock" description="Helping out with the Udacity Alumni Web App is a great way to learn new skills and how to collaborate on a coding project with a team! I didn't know how hard it would actually be to learn a professional web development stack, but with help from the team, I am contributing code, testing the app, and finding and fixing issues. It also feels pretty awesome to help with the app because Udacity has been the best learning experience I've had as far as getting job ready skills to become a web developer, and I believe this app can help alumni take their skills to the next level! Alumni can contribute to this app, find projects to collaborate on with other alumni, and perhaps find a mentor or meetup."
              link={<Anchor href="https://github.com/kellim" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Did some code" thumbnail="https://avatars3.githubusercontent.com/u/19292575?v=3&s=400"
              heading="Abishek Gosh" description="..."
              link={<Anchor href="https://github.com/ghoshabhi" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Wrote some Posts" thumbnail="https://upload.wikimedia.org/wikipedia/commons/3/33/White_square_with_question_mark.png"
              heading="SadlyFake Demo-User" description="I love blogging!"
              link={<Anchor href="https://github.com/sadly-fake" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Did some code" thumbnail="https://avatars1.githubusercontent.com/u/12371494?v=3&s=400"
              heading="Martin Breuss" description="This is me. I like the webapp project because so many nice people here, yo!"
              link={<Anchor href="https://github.com/martin-martin" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Manager" thumbnail="https://avatars2.githubusercontent.com/u/13810084?v=3&s=400"
              heading="Ryan Collins" description="Don't be lazy, write your own text!"
              link={<Anchor href="https://github.com/RyanCCollins" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Anything you want" thumbnail="https://upload.wikimedia.org/wikipedia/commons/3/33/White_square_with_question_mark.png"
              heading="You!" description="Excited to build something? Click the link!"
              link={<Anchor href="https://github.com/udacityalumni" primary={true} label="Link" />} />
            </Paragraph>
          </Box>
        </Sidebar>
      </Split>
      <AppFooter />
    </App>

);

export default cssModules(AboutPage, styles);<commit_msg>fix: mb improve styling and content of about page<commit_after>import React from 'react';
import cssModules from 'react-css-modules';
import styles from './index.module.scss';
// importing the gromment components used in this page
import Box from 'grommet-udacity/components/Box';
import Paragraph from 'grommet-udacity/components/Paragraph';
import Card from 'grommet-udacity/components/Card';
import Anchor from 'grommet-udacity/components/Anchor';
import App from 'grommet-udacity/components/App';
import Split from 'grommet-udacity/components/Split';
import Article from 'grommet-udacity/components/Article';
import Sidebar from 'grommet-udacity/components/Sidebar';
import Heading from 'grommet-udacity/components/Heading';
import Hero from 'grommet-udacity/components/Hero';
import Headline from 'grommet-udacity/components/Headline';
import { MartinRulz,
        AppFooter } from 'components';
// importing the content
import contributorVoices from './contributorVoices';
// Change as needed.  This image is optimized
const AboutPageImage = 'https://github.com/RyanCCollins/cdn/blob/master/alumni-webapp/meetups.jpeg?raw=true';

const AboutPage = () => (

    <App>
      <Split
        fixed="false"
        priority="left"
        showOnResponsive="priority"
        flex="both"
      >

            <Headline strong>
              What’s all this About?
            </Headline>
            <Heading tag="h2" strong>
              A (not so) short Why of this project.
            </Heading>
            <Paragraph>
              So you’ve graduated from one of Udacity’s Nanodegrees! Congratulations! :thumbs_up: :tada: You’re now a part of the <Anchor href="mailto:tyler@udacity.com" label="Udacity Alumni slack channel" /> (<- click if you’re not yet. You should be).

There you’ve read some discussions, or had some discussions, and probably you’re super excited about all those other smart and handsome Alumni that are working on a million of compelling projects! (… Wait… don’t go those dark places. Fight the <Anchor href="https://en.wikipedia.org/wiki/Impostor_syndrome" label="impostor syndrome" /> creeping up… Grind it, gnaw it - - remember you’ve learned a lot, and most importantly you’ve learned how to learn ever more!! Your best projects lie in the future! Hm…, I can hear you think, …so what if there was a possibility to get in touch with the person who’s working on project Awwwsome…? Alright! : ) Seems we’re back on track! Great, here we go!)
            </Paragraph>
            <Heading tag="h3">
              We’re all Udacity Alumni here. But we come from a great number of diverse backgrounds.
            </Heading>
            <Paragraph>
              Some worked in construction before hopping onto the digital train, some in Canada, some in the Arts. Some are in school, others graduated from university with a degree in communications. Some even did a programming related education, dabbled with their mum’s tower PC after having just started to walk, or earned sweet money in one of these fields before. But there are also many of us who have not, and are still pretty new to the industry.

Online education offers this possibility to change your path and follow interests in a new way. Some even dive into the digital world during their retirement! Yes yes, we’re a diverse bunch. pads any reachable back Here comes yet another example: there are those that can dedicate all their waking hours to this new path, and there are those who somehow manage to juggle all the materials while working a full-time job or raising a family (Respect!).

And there is more: Coming from all corners of the world, we tie together a bouquet of timezones so that it is fair to say that this community never sleeps. And some of us stay where they are to work and study from the comfort of their homes, some others zip around and learn how to find internet on the road.
            </Paragraph>
            <Paragraph>
              Online education is a big box filled with surprises and opportunities - and interesting people.

But as diverse as we might be, there’s something that ties us together: the wish to learn and the will to work for it.

This webapp was born from these principles.
            </Paragraph>
            <Heading tag="h3">
              The Alumni Webapp is a collaborative project built by and for Alumnis.
            </Heading>
            <Paragraph>
              It aims on creating a platform that allows us to exchange ideas, opinions, projects, jobs and whatnot. This webapp wants to strengthen the alumni community by offering chances to work together, find places to meet up, organize events, and talk about interesting topics.
            </Paragraph>
            <Paragraph>
              It is also a work-in-progress and as such it aims on providing another piece of the puzzle that can teach us to become better digital workers: collaboration on real-world products.

During our Nanodegrees we spent our time learning from Udacity’s Resources and from the vast plains of the web. Then we wrapped up and applied that knowledge to fulfill tasks and complete projects. We’ve learned to research topics and solve errors by ourselves (and also sometimes ask for support). We got to know what it’s like to build a project, receive feedback on our work, then iterate and improve.
            </Paragraph>
            <Paragraph>
              But how is it like to build something collaboratively? There’s a whole set of new skills to be tried and learned, and the Open Source Community offers great practice grounds for that. But the wide world’s web might be too intimidating to start out - so here we have our very own open source project that everyone is invited to collaborate to. A safe place to try, among a smaller web of people who appreciate trying. : )
            </Paragraph>
            <Heading tag="h3">
            Collaborating on building the webapp is about being part of building a tool that can benefit yourself and all the other Alumnis out there.
            </Heading>
            <Paragraph>
            It’s about breathing life into your ideas, and it’s about working to make them happen collaboratively.
            </Paragraph>
            <Paragraph>
              Because we’re a great bunch of people who have gone through a similar path of education. We know what it’s like to be stuck, what it’s like to come from an unrelated background and doubt whether we actually know anything at all. We also know that we can learn how to do something new and exciting, and we are happy to give back to the community and help others along their personal way.
            </Paragraph>
            <Paragraph>
              So here’s something to ponder:
              When you jumble up the letters of “alumni” and add the first letters of “For You”, you get “nu FamilY”.

Coincidence? Maybe.

A bad wordplay? Definitely.

But in a way this is what we are - and what we aim to be for each other:
            </Paragraph>
            <Heading tag="h3" strong>
              A community of like-minded people who want to learn more and help each other on our ways.
            </Heading>
            <Paragraph>
              The Udacity Alumni Webapp is a place where we can work on this together.
            </Paragraph>
            <Paragraph>
              So that’s what this is all about. : )
            </Paragraph>
            <Paragraph>
              Hopefully you like the app and the idea, and you’ll feel encouraged to post, propose, code, improve, communicate, meet, build, share and dream.

And to do anything else that will help to make this place reflect the humble greatness of the people and ideas that make up this community.
            </Paragraph>

        <Sidebar>
          <Box
            pad="large"
          >
            <Heading tag="h2" strong>
              Contributor Voices
            </Heading>
            <Paragraph>
            <Card label="Anything you want" thumbnail="https://upload.wikimedia.org/wikipedia/commons/3/33/White_square_with_question_mark.png"
              heading="Hei You!" description="There surely is something you can do to make this better! : )"
              link={<Anchor href="https://github.com/udacityalumni" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Coder" thumbnail="https://avatars0.githubusercontent.com/u/10746052?v=3&s=400"
              heading="zhangs" description="The project is about learning React and practice collaborative development with friendly fellow Udacians."
              link={<Anchor href="https://github.com/zhangtreefish" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Unknown" thumbnail="https://upload.wikimedia.org/wikipedia/commons/3/33/White_square_with_question_mark.png"
              heading="To be revealed" description="Above all else, this project has connected me with an outstanding group of people, all of whom share my passion for education."
              link={<Anchor href="https://github.com/anonymous" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Coder" thumbnail="https://avatars1.githubusercontent.com/u/2024584?v=3&s=400"
              heading="Kelli Blalock" description="Helping out with the Udacity Alumni Web App is a great way to learn new skills and how to collaborate on a coding project with a team! I didn't know how hard it would actually be to learn a professional web development stack, but with help from the team, I am contributing code, testing the app, and finding and fixing issues. It also feels pretty awesome to help with the app because Udacity has been the best learning experience I've had as far as getting job ready skills to become a web developer, and I believe this app can help alumni take their skills to the next level! Alumni can contribute to this app, find projects to collaborate on with other alumni, and perhaps find a mentor or meetup."
              link={<Anchor href="https://github.com/kellim" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Coder" thumbnail="https://avatars3.githubusercontent.com/u/19292575?v=3&s=400"
              heading="Abishek Gosh" description="..."
              link={<Anchor href="https://github.com/ghoshabhi" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Wrote some Posts" thumbnail="https://upload.wikimedia.org/wikipedia/commons/3/33/White_square_with_question_mark.png"
              heading="SadlyFake Demo-User" description="I love blogging!"
              link={<Anchor href="https://github.com/sadly-fake" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Did a bit of code" thumbnail="https://avatars1.githubusercontent.com/u/12371494?v=3&s=400"
              heading="Martin Breuss" description="This is me. I like the webapp project because so many nice people here, yo!"
              link={<Anchor href="https://github.com/martin-martin" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Manager" thumbnail="https://avatars2.githubusercontent.com/u/13810084?v=3&s=400"
              heading="Ryan Collins" description="Don't be lazy, write your own text!"
              link={<Anchor href="https://github.com/RyanCCollins" primary={true} label="Link" />} />
            </Paragraph>
            <Paragraph>
            <Card label="Anything you want" thumbnail="https://upload.wikimedia.org/wikipedia/commons/3/33/White_square_with_question_mark.png"
              heading="Hei You!" description="Excited to build something? Click the link!"
              link={<Anchor href="https://github.com/udacityalumni" primary={true} label="Link" />} />
            </Paragraph>
          </Box>
        </Sidebar>
      </Split>
      <AppFooter />
    </App>

);

export default cssModules(AboutPage, styles);<|endoftext|>


<commit_before>const electron = require('electron');
const app      = electron.app;
const dialog   = electron.dialog;
const shell    = electron.shell;
const Menu     = electron.Menu;

var fs = require('fs');
var path = require('path');

// Quit when all windows are closed and no other one is listening to this.
app.on('window-all-closed', function() {
  if (app.listeners('window-all-closed').length == 1)
    app.quit();
});

// Parse command line options.
var argv = process.argv.slice(1);
var option = { file: null, help: null, version: null, webdriver: null, modules: [] };
for (var i = 0; i < argv.length; i++) {
  if (argv[i] == '--version' || argv[i] == '-v') {
    option.version = true;
    break;
  } else if (argv[i].match(/^--app=/)) {
    option.file = argv[i].split('=')[1];
    break;
  } else if (argv[i] == '--help' || argv[i] == '-h') {
    option.help = true;
    break;
  } else if (argv[i] == '--test-type=webdriver') {
    option.webdriver = true;
  } else if (argv[i] == '--require' || argv[i] == '-r') {
    option.modules.push(argv[++i]);
    continue;
  } else if (argv[i][0] == '-') {
    continue;
  } else {
    option.file = argv[i];
    break;
  }
}

// Create default menu.
app.once('ready', function() {
  if (Menu.getApplicationMenu())
    return;

  var template = [
    {
      label: 'Edit',
      submenu: [
        {
          label: 'Undo',
          accelerator: 'CmdOrCtrl+Z',
          role: 'undo'
        },
        {
          label: 'Redo',
          accelerator: 'Shift+CmdOrCtrl+Z',
          role: 'redo'
        },
        {
          type: 'separator'
        },
        {
          label: 'Cut',
          accelerator: 'CmdOrCtrl+X',
          role: 'cut'
        },
        {
          label: 'Copy',
          accelerator: 'CmdOrCtrl+C',
          role: 'copy'
        },
        {
          label: 'Paste',
          accelerator: 'CmdOrCtrl+V',
          role: 'paste'
        },
        {
          label: 'Select All',
          accelerator: 'CmdOrCtrl+A',
          role: 'selectall'
        },
      ]
    },
    {
      label: 'View',
      submenu: [
        {
          label: 'Reload',
          accelerator: 'CmdOrCtrl+R',
          click: function(item, focusedWindow) {
            if (focusedWindow)
              focusedWindow.reload();
          }
        },
        {
          label: 'Toggle Full Screen',
          accelerator: (function() {
            if (process.platform == 'darwin')
              return 'Ctrl+Command+F';
            else
              return 'F11';
          })(),
          click: function(item, focusedWindow) {
            if (focusedWindow)
              focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
          }
        },
        {
          label: 'Toggle Developer Tools',
          accelerator: (function() {
            if (process.platform == 'darwin')
              return 'Alt+Command+I';
            else
              return 'Ctrl+Shift+I';
          })(),
          click: function(item, focusedWindow) {
            if (focusedWindow)
              focusedWindow.toggleDevTools();
          }
        },
      ]
    },
    {
      label: 'Window',
      role: 'window',
      submenu: [
        {
          label: 'Minimize',
          accelerator: 'CmdOrCtrl+M',
          role: 'minimize'
        },
        {
          label: 'Close',
          accelerator: 'CmdOrCtrl+W',
          role: 'close'
        },
      ]
    },
    {
      label: 'Help',
      role: 'help',
      submenu: [
        {
          label: 'Learn More',
          click: function() {
            shell.openExternal('http://electron.atom.io');
          }
        },
        {
          label: 'Documentation',
          click: function() {
            shell.openExternal(
              `https://github.com/atom/electron/tree/v${process.versions.electron}/docs#readme`
            );
          }
        },
        {
          label: 'Community Discussions',
          click: function() {
            shell.openExternal('https://discuss.atom.io/c/electron');
          }
        },
        {
          label: 'Search Issues',
          click: function() {
            shell.openExternal('https://github.com/atom/electron/issues');
          }
        }
      ]
    },
  ];

  if (process.platform == 'darwin') {
    template.unshift({
      label: 'Electron',
      submenu: [
        {
          label: 'About Electron',
          role: 'about'
        },
        {
          type: 'separator'
        },
        {
          label: 'Services',
          role: 'services',
          submenu: []
        },
        {
          type: 'separator'
        },
        {
          label: 'Hide Electron',
          accelerator: 'Command+H',
          role: 'hide'
        },
        {
          label: 'Hide Others',
          accelerator: 'Command+Shift+H',
          role: 'hideothers'
        },
        {
          label: 'Show All',
          role: 'unhide'
        },
        {
          type: 'separator'
        },
        {
          label: 'Quit',
          accelerator: 'Command+Q',
          click: function() { app.quit(); }
        },
      ]
    });
    template[3].submenu.push(
      {
        type: 'separator'
      },
      {
        label: 'Bring All to Front',
        role: 'front'
      }
    );
  }

  var menu = Menu.buildFromTemplate(template);
  Menu.setApplicationMenu(menu);
});

if (option.modules.length > 0) {
  require('module')._preloadModules(option.modules);
}

// Start the specified app if there is one specified in command line, otherwise
// start the default app.
if (option.file && !option.webdriver) {
  try {
    // Override app name and version.
    var packagePath = path.resolve(option.file);
    var packageJsonPath = path.join(packagePath, 'package.json');
    if (fs.existsSync(packageJsonPath)) {
      var packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
      if (packageJson.version)
        app.setVersion(packageJson.version);
      if (packageJson.productName)
        app.setName(packageJson.productName);
      else if (packageJson.name)
        app.setName(packageJson.name);
      app.setPath('userData', path.join(app.getPath('appData'), app.getName()));
      app.setPath('userCache', path.join(app.getPath('cache'), app.getName()));
      app.setAppPath(packagePath);
    }

    // Run the app.
    require('module')._load(packagePath, module, true);
  } catch(e) {
    if (e.code == 'MODULE_NOT_FOUND') {
      app.focus();
      dialog.showErrorBox(
        'Error opening app',
        'The app provided is not a valid Electron app, please read the docs on how to write one:\n' +
        `https://github.com/atom/electron/tree/v${process.versions.electron}/docs\n\n${e.toString()}`
      );
      process.exit(1);
    } else {
      console.error('App threw an error when running', e);
      throw e;
    }
  }
} else if (option.version) {
  console.log('v' + process.versions.electron);
  process.exit(0);
} else if (option.help) {
  var helpMessage = "Electron v" + process.versions.electron + " - Cross Platform Desktop Application Shell\n\n";
  helpMessage    += "Usage: electron [options] [path]\n\n";
  helpMessage    += "A path to an Electron application may be specified. The path must be to \n";
  helpMessage    += "an index.js file or to a folder containing a package.json or index.js file.\n\n";
  helpMessage    += "Options:\n";
  helpMessage    += "  -r, --require         Module to preload (option can be repeated)\n";
  helpMessage    += "  -h, --help            Print this usage message.\n";
  helpMessage    += "  -v, --version         Print the version.";
  console.log(helpMessage);
  process.exit(0);
} else {
  require('./default_app');
}
<commit_msg>Use Alt in accelerator<commit_after>const electron = require('electron');
const app      = electron.app;
const dialog   = electron.dialog;
const shell    = electron.shell;
const Menu     = electron.Menu;

var fs = require('fs');
var path = require('path');

// Quit when all windows are closed and no other one is listening to this.
app.on('window-all-closed', function() {
  if (app.listeners('window-all-closed').length == 1)
    app.quit();
});

// Parse command line options.
var argv = process.argv.slice(1);
var option = { file: null, help: null, version: null, webdriver: null, modules: [] };
for (var i = 0; i < argv.length; i++) {
  if (argv[i] == '--version' || argv[i] == '-v') {
    option.version = true;
    break;
  } else if (argv[i].match(/^--app=/)) {
    option.file = argv[i].split('=')[1];
    break;
  } else if (argv[i] == '--help' || argv[i] == '-h') {
    option.help = true;
    break;
  } else if (argv[i] == '--test-type=webdriver') {
    option.webdriver = true;
  } else if (argv[i] == '--require' || argv[i] == '-r') {
    option.modules.push(argv[++i]);
    continue;
  } else if (argv[i][0] == '-') {
    continue;
  } else {
    option.file = argv[i];
    break;
  }
}

// Create default menu.
app.once('ready', function() {
  if (Menu.getApplicationMenu())
    return;

  var template = [
    {
      label: 'Edit',
      submenu: [
        {
          label: 'Undo',
          accelerator: 'CmdOrCtrl+Z',
          role: 'undo'
        },
        {
          label: 'Redo',
          accelerator: 'Shift+CmdOrCtrl+Z',
          role: 'redo'
        },
        {
          type: 'separator'
        },
        {
          label: 'Cut',
          accelerator: 'CmdOrCtrl+X',
          role: 'cut'
        },
        {
          label: 'Copy',
          accelerator: 'CmdOrCtrl+C',
          role: 'copy'
        },
        {
          label: 'Paste',
          accelerator: 'CmdOrCtrl+V',
          role: 'paste'
        },
        {
          label: 'Select All',
          accelerator: 'CmdOrCtrl+A',
          role: 'selectall'
        },
      ]
    },
    {
      label: 'View',
      submenu: [
        {
          label: 'Reload',
          accelerator: 'CmdOrCtrl+R',
          click: function(item, focusedWindow) {
            if (focusedWindow)
              focusedWindow.reload();
          }
        },
        {
          label: 'Toggle Full Screen',
          accelerator: (function() {
            if (process.platform == 'darwin')
              return 'Ctrl+Command+F';
            else
              return 'F11';
          })(),
          click: function(item, focusedWindow) {
            if (focusedWindow)
              focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
          }
        },
        {
          label: 'Toggle Developer Tools',
          accelerator: (function() {
            if (process.platform == 'darwin')
              return 'Alt+Command+I';
            else
              return 'Ctrl+Shift+I';
          })(),
          click: function(item, focusedWindow) {
            if (focusedWindow)
              focusedWindow.toggleDevTools();
          }
        },
      ]
    },
    {
      label: 'Window',
      role: 'window',
      submenu: [
        {
          label: 'Minimize',
          accelerator: 'CmdOrCtrl+M',
          role: 'minimize'
        },
        {
          label: 'Close',
          accelerator: 'CmdOrCtrl+W',
          role: 'close'
        },
      ]
    },
    {
      label: 'Help',
      role: 'help',
      submenu: [
        {
          label: 'Learn More',
          click: function() {
            shell.openExternal('http://electron.atom.io');
          }
        },
        {
          label: 'Documentation',
          click: function() {
            shell.openExternal(
              `https://github.com/atom/electron/tree/v${process.versions.electron}/docs#readme`
            );
          }
        },
        {
          label: 'Community Discussions',
          click: function() {
            shell.openExternal('https://discuss.atom.io/c/electron');
          }
        },
        {
          label: 'Search Issues',
          click: function() {
            shell.openExternal('https://github.com/atom/electron/issues');
          }
        }
      ]
    },
  ];

  if (process.platform == 'darwin') {
    template.unshift({
      label: 'Electron',
      submenu: [
        {
          label: 'About Electron',
          role: 'about'
        },
        {
          type: 'separator'
        },
        {
          label: 'Services',
          role: 'services',
          submenu: []
        },
        {
          type: 'separator'
        },
        {
          label: 'Hide Electron',
          accelerator: 'Command+H',
          role: 'hide'
        },
        {
          label: 'Hide Others',
          accelerator: 'Command+Alt+H',
          role: 'hideothers'
        },
        {
          label: 'Show All',
          role: 'unhide'
        },
        {
          type: 'separator'
        },
        {
          label: 'Quit',
          accelerator: 'Command+Q',
          click: function() { app.quit(); }
        },
      ]
    });
    template[3].submenu.push(
      {
        type: 'separator'
      },
      {
        label: 'Bring All to Front',
        role: 'front'
      }
    );
  }

  var menu = Menu.buildFromTemplate(template);
  Menu.setApplicationMenu(menu);
});

if (option.modules.length > 0) {
  require('module')._preloadModules(option.modules);
}

// Start the specified app if there is one specified in command line, otherwise
// start the default app.
if (option.file && !option.webdriver) {
  try {
    // Override app name and version.
    var packagePath = path.resolve(option.file);
    var packageJsonPath = path.join(packagePath, 'package.json');
    if (fs.existsSync(packageJsonPath)) {
      var packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
      if (packageJson.version)
        app.setVersion(packageJson.version);
      if (packageJson.productName)
        app.setName(packageJson.productName);
      else if (packageJson.name)
        app.setName(packageJson.name);
      app.setPath('userData', path.join(app.getPath('appData'), app.getName()));
      app.setPath('userCache', path.join(app.getPath('cache'), app.getName()));
      app.setAppPath(packagePath);
    }

    // Run the app.
    require('module')._load(packagePath, module, true);
  } catch(e) {
    if (e.code == 'MODULE_NOT_FOUND') {
      app.focus();
      dialog.showErrorBox(
        'Error opening app',
        'The app provided is not a valid Electron app, please read the docs on how to write one:\n' +
        `https://github.com/atom/electron/tree/v${process.versions.electron}/docs\n\n${e.toString()}`
      );
      process.exit(1);
    } else {
      console.error('App threw an error when running', e);
      throw e;
    }
  }
} else if (option.version) {
  console.log('v' + process.versions.electron);
  process.exit(0);
} else if (option.help) {
  var helpMessage = "Electron v" + process.versions.electron + " - Cross Platform Desktop Application Shell\n\n";
  helpMessage    += "Usage: electron [options] [path]\n\n";
  helpMessage    += "A path to an Electron application may be specified. The path must be to \n";
  helpMessage    += "an index.js file or to a folder containing a package.json or index.js file.\n\n";
  helpMessage    += "Options:\n";
  helpMessage    += "  -r, --require         Module to preload (option can be repeated)\n";
  helpMessage    += "  -h, --help            Print this usage message.\n";
  helpMessage    += "  -v, --version         Print the version.";
  console.log(helpMessage);
  process.exit(0);
} else {
  require('./default_app');
}
<|endoftext|>


<commit_before>
/* global: $ */
/**
 * Plugin for managing menu in full screen
 * Enabling this plug-in removes the "menu tab" triangle
 * and uses center touch/click to show/hide the menu below
 * Behavior is predicated on custom event: `brFullScreenToggled`
 * This is fired when user clicks on the fullscreen button on the menu
 */

(function addMenuToggler () {
    jQuery.extend(BookReader.defaultOptions, {
      enableMenuToggle: true
    });

    function setupNavForToggle (br) {
      var $menuTab = br.refs.$BRnav.children('.js-tooltip');
      $menuTab.css('display', 'none');
      registerEventHandlers(br);
    }

    var removeToggleFromNav = function removeToggleFromNav (br) {
      var $menuTab = br.refs.$BRnav.children('.js-tooltip');
      $menuTab.css('display', 'block');
      removeEventHandlers(br);
    }

    var removeEventHandlers = function removeEventHandlers(br) {
      if (br.refs.$brPageViewEl) {
        br.refs.$brPageViewEl[0].removeEventListener('click', toggleMenuIfCenterClick, true);
      }
      if (br.refs.$brTwoPageView) {
        br.refs.$brTwoPageView[0].removeEventListener('click', toggleMenuIfCenterClick, true);
      }
    }

    var toggleMenuIfCenterClick = function toggleMenuIfCenterClick(br, e) {
      var menuManager = br.menuToggle;
      var bookWidth = e.currentTarget.offsetWidth;
      var leftOffset = e.currentTarget.offsetLeft
      var bookEndPageFlipArea = Math.round(bookWidth / 3);
      var leftThreshold = Math.round(bookEndPageFlipArea + leftOffset); // without it, the click area is small
      var rightThreshold = Math.round(bookWidth - bookEndPageFlipArea + leftOffset);
      var isCenterClick = (e.clientX > leftThreshold) && (e.clientX < rightThreshold);

      if (isCenterClick) {
        if (menuManager.menuIsShowing) {
          br.hideNavigation();
          menuManager.menuIsShowing = false;
        } else {
          br.showNavigation();
          menuManager.menuIsShowing = true;
        }
        event.stopPropagation();
      }
    }

    function registerEventHandlers(br) {
      var brContainer = document.querySelector('.BRcontainer') || {};
      var firstChild = brContainer.firstChild;

      if (firstChild) {
        firstChild.addEventListener('click', toggleMenuIfCenterClick.bind(this, br), true);
      }
    }

    BookReader.prototype.initMenuToggle = function brInitMenuToggle(e) {
      $(document).on('BookReader:fullscreenToggled', function (e) {
        this.menuToggle.setupNavForToggle(this);
      }.bind(this));

      var menuToggleEventRegister = function menuToggleEventRegister (e) {
        registerEventHandlers(this);
      }.bind(this);

      var eventsToHandle = [
        'BookReader:1PageViewSelected',
        'BookReader:2PageViewSelected',
        'BookReader:zoomIn',
        'BookReader:zoomOut',
        'BookReader:resize'
      ];

      $(document).on(eventsToHandle.join(' '), menuToggleEventRegister);
      $(window).on('orientationchange', menuToggleEventRegister);
      $(window).on('DOMContentLoaded', function setupNavAtFirstDraw(e) {
        setupNavForToggle(this);
      }.bind(this));
    };

    BookReader.prototype.setup = (function(super_) {
      return function(options) {
        super_.call(this, options);
        this.menuToggle = {
          menuIsShowing: true,
          setupNavForToggle: setupNavForToggle,
          removeToggleFromNav: removeToggleFromNav,
        };
      };
    })(BookReader.prototype.setup);

    BookReader.prototype.init = (function(super_) {
      return function() {
        super_.call(this);
        if (this.options.enableMenuToggle) {
          this.initMenuToggle();
        }
      };
    })(BookReader.prototype.init);
  })();
  <commit_msg>Adding DOM setup & registration handlers<commit_after>
/* global: $ */
/**
 * Plugin for managing menu in full screen
 * Enabling this plug-in removes the "menu tab" triangle
 * and uses center touch/click to show/hide the menu below
 * Behavior is predicated on custom event: `brFullScreenToggled`
 * This is fired when user clicks on the fullscreen button on the menu
 */

(function addMenuToggler () {
    jQuery.extend(BookReader.defaultOptions, {
      enableMenuToggle: true
    });

    function setupNavForToggle (br) {
      var $menuTab = br.refs.$BRnav.children('.js-tooltip');
      $menuTab.css('display', 'none');
      registerEventHandlers(br);
    }

    var removeToggleFromNav = function removeToggleFromNav (br) {
      var $menuTab = br.refs.$BRnav.children('.js-tooltip');
      $menuTab.css('display', 'block');
      removeEventHandlers(br);
    }

    var removeEventHandlers = function removeEventHandlers(br) {
      if (br.refs.$brPageViewEl) {
        br.refs.$brPageViewEl[0].removeEventListener('click', toggleMenuIfCenterClick, true);
      }
      if (br.refs.$brTwoPageView) {
        br.refs.$brTwoPageView[0].removeEventListener('click', toggleMenuIfCenterClick, true);
      }
    }

    var toggleMenuIfCenterClick = function toggleMenuIfCenterClick(br, e) {
      var menuManager = br.menuToggle;
      var bookWidth = e.currentTarget.offsetWidth;
      var leftOffset = e.currentTarget.offsetLeft
      var bookEndPageFlipArea = Math.round(bookWidth / 3);
      var leftThreshold = Math.round(bookEndPageFlipArea + leftOffset); // without it, the click area is small
      var rightThreshold = Math.round(bookWidth - bookEndPageFlipArea + leftOffset);
      var isCenterClick = (e.clientX > leftThreshold) && (e.clientX < rightThreshold);

      if (isCenterClick) {
        if (menuManager.menuIsShowing) {
          br.hideNavigation();
          menuManager.menuIsShowing = false;
        } else {
          br.showNavigation();
          menuManager.menuIsShowing = true;
        }
        event.stopPropagation();
      }
    }

    function registerEventHandlers(br) {
      var brContainer = document.querySelector('.BRcontainer') || {};
      var firstChild = brContainer.firstChild;

      if (firstChild) {
        firstChild.addEventListener('click', toggleMenuIfCenterClick.bind(this, br), true);
      }
    }

    BookReader.prototype.initMenuToggle = function brInitMenuToggle(e) {

      var menuToggleEventRegister = function menuToggleEventRegister (e) {
        registerEventHandlers(this);
      }.bind(this);

      var setupDOMandHandlers = function setupDOMandHandlers(e) {
        setupNavForToggle(this);
      }.bind(this));

      var eventsToHandle = [
        'BookReader:1PageViewSelected',
        'BookReader:2PageViewSelected',
        'BookReader:zoomIn',
        'BookReader:zoomOut',
        'BookReader:resize'
      ];

      $(document).on(eventsToHandle.join(' '), menuToggleEventRegister);
      $(window).on('orientationchange', menuToggleEventRegister);
      $(document).on('BookReader:fullscreenToggled', setupDOMandHandlers);
      $(window).on('DOMContentLoaded', setupDOMandHandlers);
    };

    BookReader.prototype.setup = (function(super_) {
      return function(options) {
        super_.call(this, options);
        this.menuToggle = {
          menuIsShowing: true,
          setupNavForToggle: setupNavForToggle,
          removeToggleFromNav: removeToggleFromNav,
        };
      };
    })(BookReader.prototype.setup);

    BookReader.prototype.init = (function(super_) {
      return function() {
        super_.call(this);
        if (this.options.enableMenuToggle) {
          this.initMenuToggle();
        }
      };
    })(BookReader.prototype.init);
  })();
  <|endoftext|>