<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { autobind } from 'core-decorators';
import { compose, gql, graphql } from 'react-apollo';
import { Button, Intent, Spinner, EditableText, Dialog } from '@blueprintjs/core';
import { saveState } from '../../../actions/stateActions';
import NotificationToaster from '../NotificationToaster';

import '../../scss/admin/_team-profile.scss';

const QueryTeam = gql`
query GetTeam($teamId: ID!){
	getTeam(teamId: $teamId){
		_id
		teamName
		members{
			username
			firstname
			lastname
		}
		memberCount
		points
	}
}`;

const QueryTeamOptions = {
	name: 'QueryTeam',
	options: (props) => ({
		variables: { teamId: props.team._id },
		fetchPolicy: 'cache-and-network'
	})
}

const QueryUsers = gql`
query ListAll($limit:Int, $skip:Int){
	listAll(limit:$limit, skip:$skip) {
		firstname
		lastname
		username
		teamId
	}
}`;

const QueryUsersOptions = {
	name: 'QueryUsers',
	options: {
		variables: { skip: 0, limit: 0 },
		fetchPolicy: 'network-only'
	}
}

const MutationSetTeamName = gql`
mutation SetTeamName($teamId:ID!, $name:String!) {
	setTeamName(teamId:$teamId, name:$name) {
		ok
		failureMessage
	}
}`;

const MutationSetTeamPoints = gql`
mutation SetTeamPoints($teamId:ID!, $points:Float!) {
	setTeamPoints(teamId:$teamId, points:$points) {
		ok
		failureMessage
	}
}`;

const MutationSetUserTeam = gql`
mutation SetUserTeam($username:String!,$teamId:ID!){
	setUserTeam(username:$username,teamId:$teamId){
		ok
	}
}`;

const MutationRemoveUserTeam = gql`
mutation RemoveUserTeam($username:String!){
  removeUserTeam(username:$username){
		ok
	}
}`;

const MutationRemoveTeam = gql`
mutation RemoveTeam($teamId:ID!){
	removeTeam(teamId:$teamId){
		ok
	}
}`;

@compose(
	graphql(QueryTeam, QueryTeamOptions),
	graphql(QueryUsers, QueryUsersOptions),
	graphql(MutationSetTeamName, {name: 'MutationSetTeamName'}),
	graphql(MutationSetTeamPoints, {name: 'MutationSetTeamPoints'}),
	graphql(MutationSetUserTeam, {name: 'MutationSetUserTeam'}),
	graphql(MutationRemoveUserTeam, {name: 'MutationRemoveUserTeam'}),
	graphql(MutationRemoveTeam, {name: 'MutationRemoveTeam'})
)
@connect()
@autobind
class TeamProfile extends React.Component {
	static propTypes = {
		team: PropTypes.shape({
			_id: PropTypes.string,
			teamName: PropTypes.string,
			memberCount: PropTypes.number,
			members: PropTypes.array,
			points: PropTypes.number
		}),
		closeProfile: PropTypes.func.isRequired,
		reload: PropTypes.func.isRequired
	}

	state = {
		teamName: null,
		points: null,
		saving: false,

		addUsersDialogOpen: false,
		addUserLoading: false,
		addUserError: null,
		userToAdd: null,

		removeUserDialogOpen: false,
		removeUserLoading: false,
		removeUserError: null,
		userToRemove: null,

		removeTeamDialogOpen: false,
		removeTeamLoading: false,
		removeTeamError: null
	}

	componentDidMount() {
		this._mounted = true;
	}

	componentWillUnmount() {
		this._mounted = false;
	}

	closeProfile() {
		this.props.reload();
		this.props.closeProfile();
	}

	editPoints(value) {
		this.setState({points: value});
	}

	editName(value) {
		this.setState({teamName: value});
	}

	confirmPoints(value) {
		if (value.length > 0) {
			const regex = /^[-0-9]+(\.|)[0-9]{0,2}$/;
			if (regex.exec(value)) {
				this.savePoints();
				return;
			}
		}
		this.setState({points: this.props.QueryTeam.getTeam.points});
	}

	confirmName(value) {
		if (value.length > 0) {
			this.saveName();
			return;
		}
		this.setState({points: this.props.QueryTeam.getTeam.teamName});
	}

	savePoints() {
		const variables = {
			teamId: this.props.team._id,
			points: this.state.points
		};

		// Save points
		this._save(this.props.MutationSetTeamPoints, 'setTeamPoints', variables);
	}

	saveName() {
		const variables = {
			teamId: this.props.team._id,
			name: this.state.teamName
		};

		// Save name
		this._save(this.props.MutationSetTeamName, 'setTeamName', variables);
	}

	_save(mutation, mutationName, variables) {
		this.setState({saving: true});

		// Execute mutation
		mutation({ variables })
			.then(async (result) => {
				if (result.data[mutationName].ok) {
					await this.props.QueryTeam.refetch();
					this.props.dispatch(saveState());
					if (this._mounted) this.setState({saving: false});
				}
				else {
					if (this._mounted) this.setState({saving: false});
					NotificationToaster.show({
						intent: Intent.DANGER,
						message: result.data[mutationName].failureMessage
					});
				}
			})
			.catch((err) => {
				if (this._mounted) this.setState({saving: false});
				NotificationToaster.show({
					intent: Intent.DANGER,
					message: err.toString()
				});
			});
	}

	toggleAddUsers() {
		this.setState((prevState) => {
			let state = { addUsersDialogOpen: !prevState.addUsersDialogOpen, addUserError: null };
			if (state.addUsersDialogOpen) state.userToAdd = 'NONE';
			else state.userToAdd = null;
			return state;
		});
	}

	submitAddUser() {
		this.setState({ addUserLoading: true });

		const variables = {
			teamId: this.props.team._id,
			username: this.state.userToAdd
		};

		// Save points
		this.props.MutationSetUserTeam({ variables })
			.then(async (result) => {
				await this.props.QueryUsers.refetch();
				await this.props.QueryTeam.refetch()
				this.props.dispatch(saveState());
				if (this._mounted) this.setState({addUserLoading: false, addUsersDialogOpen: false, addUserError: null});
			})
			.catch((err) => {
				if (this._mounted) this.setState({addUserLoading: false, addUserError: err.toString()});
				else console.warn(err);
			});
	}

	changeUserToAdd({ target: { value } }) {
		this.setState({ userToAdd: value });
	}

	toggleRemoveUser(userToRemove) {
		return () => {
			this.setState((prevState) => {
				return {
					removeUserDialogOpen: !prevState.removeUserDialogOpen,
					removeUserError: null,
					userToRemove: userToRemove
				};
			});
		}
	}

	submitRemoveUser() {
		this.setState({removeUserLoading: true});
		this.props.MutationRemoveUserTeam({ variables: { username: this.state.userToRemove }})
		.then(async (result) => {
			await this.props.QueryUsers.refetch()
			await this.props.QueryTeam.refetch()
			this.props.dispatch(saveState());
			if (this._mounted) this.setState({removeUserLoading: false, removeUserDialogOpen: false});
		})
		.catch((err) => {
			if (this._mounted) {
				this.setState({
					removeUserLoading: false,
					removeUserError: err.toString()
				});
			}
		});
	}

	toggleRemoveTeam() {
		this.setState((prevState) => {
			return { removeTeamDialogOpen: !prevState.removeTeamDialogOpen, removeTeamError: null };
		});
	}

	submitRemoveTeam() {
		this.setState({removeTeamLoading: true, removeTeamError: null});
		this.props.MutationRemoveTeam({ variables: { teamId: this.props.team._id }})
			.then(() => {
				this.props.closeProfile();
			})
			.catch((err) => {
				if (this._mounted) this.setState({ removeTeamLoading: false, removeTeamError: err.toString() });
			});
	}

	render() {
		let content = null;
		let showLoadingIndicator = false;

		if (this.saving || this.props.QueryTeam.loading) {
			showLoadingIndicator = true;
		}

		if (this.props.QueryTeam.getTeam) {
			let {
				teamName,
				memberCount,
				members,
				points
			} = this.props.QueryTeam.getTeam;

			if (this.state.points === null) {
				setTimeout(() => {
					this.setState({points});
				}, 0);
			}

			if (this.state.teamName === null) {
				setTimeout(() => {
					this.setState({teamName});
				}, 0);
			}

			content = (

					{members.length ?
						members.map((member) => {
							return (

										{`${member.firstname} ${member.lastname}`}

										<Button className='pt-minimal' iconName='remove'
											onClick={this.toggleRemoveUser(member.username)}/>

							);
						})
						:

							There are no users in this team.

					}

			);
		}

		return (

				<Button className='pt-minimal' intent={Intent.DANGER} text='Close' onClick={this.closeProfile} style={{float:'right'}}/>
				{showLoadingIndicator ?

						<Spinner className='pt-small'/>

				: null }

					{
						this.state.teamName ?
						<EditableText selectAllOnFocus
							value={this.state.teamName}
							onChange={this.editName}
							onConfirm={this.confirmName}/> :
						this.props.team.teamName
					}
					<Button className='pt-minimal action-button' iconName='new-person' intent={Intent.PRIMARY} onClick={this.toggleAddUsers}/>
					<Button className='pt-minimal action-button' iconName='remove' intent={Intent.DANGER} onClick={this.toggleRemoveTeam}/>

						Points:
						<EditableText selectAllOnFocus
							className='points'
							value={this.state.points}
							onChange={this.editPoints}
							onConfirm={this.confirmPoints}/>

				{content}

				{/* Add user dialog */}
				<Dialog isOpen={this.state.addUsersDialogOpen} onClose={this.toggleAddUsers} title='Add user' iconName='new-person'>

						{this.state.addUserError ?

								{this.state.addUserError}

							:null}

							Add user:

								<select onChange={this.changeUserToAdd} disabled={this.state.addUserLoading}>
									{this.props.QueryUsers.loading ?
										<option value='NONE'>Loading...</option>:
										<option value='NONE'>Select a user...</option>
									}
									{this.props.QueryUsers.loading ?
									null:
									this.props.QueryUsers.listAll.map((user) => {
										if (!user.teamId) {	// Only add users without a team
											return <option key={user.username} value={user.username}>{`${user.firstname} ${user.lastname}`}</option>
										}
									})}
								</select>

							<Button onClick={this.toggleAddUsers} text='Cancel' className='pt-minimal' disabled={this.state.addUserLoading}/>
							<Button onClick={this.submitAddUser} text='Add' intent={Intent.PRIMARY} loading={this.state.addUserLoading}/>

				</Dialog>

				{/* Remove user dialog */}
				<Dialog isOpen={this.state.removeUserDialogOpen} onClose={this.toggleRemoveUser()} title='Remove user from team' iconName='warning-sign'>

						{this.state.removeUserError ?

								{this.state.removeUserError}

							:null}

							Are you sure you want to remove {this.state.userToRemove} from this team?

							<Button onClick={this.toggleRemoveUser()} text='Cancel' className='pt-minimal' disabled={this.state.removeUserLoading}/>
							<Button onClick={this.submitRemoveUser} text='Remove team' intent={Intent.DANGER} loading={this.state.removeUserLoading}/>

				</Dialog>

				{/* Remove team dialog */}
				<Dialog isOpen={this.state.removeTeamDialogOpen} onClose={this.toggleRemoveTeam} title='Remove team' iconName='warning-sign'>

						{this.state.removeTeamError ?

								{this.state.removeTeamError}

							:null}

							Are you sure you want to remove this team?

							<Button onClick={this.toggleRemoveTeam} text='Cancel' className='pt-minimal' disabled={this.state.removeTeamLoading}/>
							<Button onClick={this.submitRemoveTeam} text='Remove team' intent={Intent.DANGER} loading={this.state.removeTeamLoading}/>

				</Dialog>

		);
	}
}

export default TeamProfile;
<commit_msg>[FIX] Remove unused variable<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { autobind } from 'core-decorators';
import { compose, gql, graphql } from 'react-apollo';
import { Button, Intent, Spinner, EditableText, Dialog } from '@blueprintjs/core';
import { saveState } from '../../../actions/stateActions';
import NotificationToaster from '../NotificationToaster';

import '../../scss/admin/_team-profile.scss';

const QueryTeam = gql`
query GetTeam($teamId: ID!){
	getTeam(teamId: $teamId){
		_id
		teamName
		members{
			username
			firstname
			lastname
		}
		memberCount
		points
	}
}`;

const QueryTeamOptions = {
	name: 'QueryTeam',
	options: (props) => ({
		variables: { teamId: props.team._id },
		fetchPolicy: 'cache-and-network'
	})
}

const QueryUsers = gql`
query ListAll($limit:Int, $skip:Int){
	listAll(limit:$limit, skip:$skip) {
		firstname
		lastname
		username
		teamId
	}
}`;

const QueryUsersOptions = {
	name: 'QueryUsers',
	options: {
		variables: { skip: 0, limit: 0 },
		fetchPolicy: 'network-only'
	}
}

const MutationSetTeamName = gql`
mutation SetTeamName($teamId:ID!, $name:String!) {
	setTeamName(teamId:$teamId, name:$name) {
		ok
		failureMessage
	}
}`;

const MutationSetTeamPoints = gql`
mutation SetTeamPoints($teamId:ID!, $points:Float!) {
	setTeamPoints(teamId:$teamId, points:$points) {
		ok
		failureMessage
	}
}`;

const MutationSetUserTeam = gql`
mutation SetUserTeam($username:String!,$teamId:ID!){
	setUserTeam(username:$username,teamId:$teamId){
		ok
	}
}`;

const MutationRemoveUserTeam = gql`
mutation RemoveUserTeam($username:String!){
  removeUserTeam(username:$username){
		ok
	}
}`;

const MutationRemoveTeam = gql`
mutation RemoveTeam($teamId:ID!){
	removeTeam(teamId:$teamId){
		ok
	}
}`;

@compose(
	graphql(QueryTeam, QueryTeamOptions),
	graphql(QueryUsers, QueryUsersOptions),
	graphql(MutationSetTeamName, {name: 'MutationSetTeamName'}),
	graphql(MutationSetTeamPoints, {name: 'MutationSetTeamPoints'}),
	graphql(MutationSetUserTeam, {name: 'MutationSetUserTeam'}),
	graphql(MutationRemoveUserTeam, {name: 'MutationRemoveUserTeam'}),
	graphql(MutationRemoveTeam, {name: 'MutationRemoveTeam'})
)
@connect()
@autobind
class TeamProfile extends React.Component {
	static propTypes = {
		team: PropTypes.shape({
			_id: PropTypes.string,
			teamName: PropTypes.string,
			memberCount: PropTypes.number,
			members: PropTypes.array,
			points: PropTypes.number
		}),
		closeProfile: PropTypes.func.isRequired,
		reload: PropTypes.func.isRequired
	}

	state = {
		teamName: null,
		points: null,
		saving: false,

		addUsersDialogOpen: false,
		addUserLoading: false,
		addUserError: null,
		userToAdd: null,

		removeUserDialogOpen: false,
		removeUserLoading: false,
		removeUserError: null,
		userToRemove: null,

		removeTeamDialogOpen: false,
		removeTeamLoading: false,
		removeTeamError: null
	}

	componentDidMount() {
		this._mounted = true;
	}

	componentWillUnmount() {
		this._mounted = false;
	}

	closeProfile() {
		this.props.reload();
		this.props.closeProfile();
	}

	editPoints(value) {
		this.setState({points: value});
	}

	editName(value) {
		this.setState({teamName: value});
	}

	confirmPoints(value) {
		if (value.length > 0) {
			const regex = /^[-0-9]+(\.|)[0-9]{0,2}$/;
			if (regex.exec(value)) {
				this.savePoints();
				return;
			}
		}
		this.setState({points: this.props.QueryTeam.getTeam.points});
	}

	confirmName(value) {
		if (value.length > 0) {
			this.saveName();
			return;
		}
		this.setState({points: this.props.QueryTeam.getTeam.teamName});
	}

	savePoints() {
		const variables = {
			teamId: this.props.team._id,
			points: this.state.points
		};

		// Save points
		this._save(this.props.MutationSetTeamPoints, 'setTeamPoints', variables);
	}

	saveName() {
		const variables = {
			teamId: this.props.team._id,
			name: this.state.teamName
		};

		// Save name
		this._save(this.props.MutationSetTeamName, 'setTeamName', variables);
	}

	_save(mutation, mutationName, variables) {
		this.setState({saving: true});

		// Execute mutation
		mutation({ variables })
			.then(async (result) => {
				if (result.data[mutationName].ok) {
					await this.props.QueryTeam.refetch();
					this.props.dispatch(saveState());
					if (this._mounted) this.setState({saving: false});
				}
				else {
					if (this._mounted) this.setState({saving: false});
					NotificationToaster.show({
						intent: Intent.DANGER,
						message: result.data[mutationName].failureMessage
					});
				}
			})
			.catch((err) => {
				if (this._mounted) this.setState({saving: false});
				NotificationToaster.show({
					intent: Intent.DANGER,
					message: err.toString()
				});
			});
	}

	toggleAddUsers() {
		this.setState((prevState) => {
			let state = { addUsersDialogOpen: !prevState.addUsersDialogOpen, addUserError: null };
			if (state.addUsersDialogOpen) state.userToAdd = 'NONE';
			else state.userToAdd = null;
			return state;
		});
	}

	submitAddUser() {
		this.setState({ addUserLoading: true });

		const variables = {
			teamId: this.props.team._id,
			username: this.state.userToAdd
		};

		// Save points
		this.props.MutationSetUserTeam({ variables })
			.then(async (result) => {
				await this.props.QueryUsers.refetch();
				await this.props.QueryTeam.refetch()
				this.props.dispatch(saveState());
				if (this._mounted) this.setState({addUserLoading: false, addUsersDialogOpen: false, addUserError: null});
			})
			.catch((err) => {
				if (this._mounted) this.setState({addUserLoading: false, addUserError: err.toString()});
				else console.warn(err);
			});
	}

	changeUserToAdd({ target: { value } }) {
		this.setState({ userToAdd: value });
	}

	toggleRemoveUser(userToRemove) {
		return () => {
			this.setState((prevState) => {
				return {
					removeUserDialogOpen: !prevState.removeUserDialogOpen,
					removeUserError: null,
					userToRemove: userToRemove
				};
			});
		}
	}

	submitRemoveUser() {
		this.setState({removeUserLoading: true});
		this.props.MutationRemoveUserTeam({ variables: { username: this.state.userToRemove }})
		.then(async (result) => {
			await this.props.QueryUsers.refetch()
			await this.props.QueryTeam.refetch()
			this.props.dispatch(saveState());
			if (this._mounted) this.setState({removeUserLoading: false, removeUserDialogOpen: false});
		})
		.catch((err) => {
			if (this._mounted) {
				this.setState({
					removeUserLoading: false,
					removeUserError: err.toString()
				});
			}
		});
	}

	toggleRemoveTeam() {
		this.setState((prevState) => {
			return { removeTeamDialogOpen: !prevState.removeTeamDialogOpen, removeTeamError: null };
		});
	}

	submitRemoveTeam() {
		this.setState({removeTeamLoading: true, removeTeamError: null});
		this.props.MutationRemoveTeam({ variables: { teamId: this.props.team._id }})
			.then(() => {
				this.props.closeProfile();
			})
			.catch((err) => {
				if (this._mounted) this.setState({ removeTeamLoading: false, removeTeamError: err.toString() });
			});
	}

	render() {
		let content = null;

		if (this.props.QueryTeam.getTeam) {
			let {
				teamName,
				memberCount,
				members,
				points
			} = this.props.QueryTeam.getTeam;

			if (this.state.points === null) {
				setTimeout(() => {
					this.setState({points});
				}, 0);
			}

			if (this.state.teamName === null) {
				setTimeout(() => {
					this.setState({teamName});
				}, 0);
			}

			content = (

					{members.length ?
						members.map((member) => {
							return (

										{`${member.firstname} ${member.lastname}`}

										<Button className='pt-minimal' iconName='remove'
											onClick={this.toggleRemoveUser(member.username)}/>

							);
						})
						:

							There are no users in this team.

					}

			);
		}

		return (

				<Button className='pt-minimal' intent={Intent.DANGER} text='Close' onClick={this.closeProfile} style={{float:'right'}}/>
				{this.props.QueryTeam.loading ?

						<Spinner className='pt-small'/>

				: null }

					{
						this.state.teamName ?
						<EditableText selectAllOnFocus
							value={this.state.teamName}
							onChange={this.editName}
							onConfirm={this.confirmName}/> :
						this.props.team.teamName
					}
					<Button className='pt-minimal action-button' iconName='new-person' intent={Intent.PRIMARY} onClick={this.toggleAddUsers}/>
					<Button className='pt-minimal action-button' iconName='remove' intent={Intent.DANGER} onClick={this.toggleRemoveTeam}/>

						Points:
						<EditableText selectAllOnFocus
							className='points'
							value={this.state.points}
							onChange={this.editPoints}
							onConfirm={this.confirmPoints}/>

				{content}

				{/* Add user dialog */}
				<Dialog isOpen={this.state.addUsersDialogOpen} onClose={this.toggleAddUsers} title='Add user' iconName='new-person'>

						{this.state.addUserError ?

								{this.state.addUserError}

							:null}

							Add user:

								<select onChange={this.changeUserToAdd} disabled={this.state.addUserLoading}>
									{this.props.QueryUsers.loading ?
										<option value='NONE'>Loading...</option>:
										<option value='NONE'>Select a user...</option>
									}
									{this.props.QueryUsers.loading ?
									null:
									this.props.QueryUsers.listAll.map((user) => {
										if (!user.teamId) {	// Only add users without a team
											return <option key={user.username} value={user.username}>{`${user.firstname} ${user.lastname}`}</option>
										}
									})}
								</select>

							<Button onClick={this.toggleAddUsers} text='Cancel' className='pt-minimal' disabled={this.state.addUserLoading}/>
							<Button onClick={this.submitAddUser} text='Add' intent={Intent.PRIMARY} loading={this.state.addUserLoading}/>

				</Dialog>

				{/* Remove user dialog */}
				<Dialog isOpen={this.state.removeUserDialogOpen} onClose={this.toggleRemoveUser()} title='Remove user from team' iconName='warning-sign'>

						{this.state.removeUserError ?

								{this.state.removeUserError}

							:null}

							Are you sure you want to remove {this.state.userToRemove} from this team?

							<Button onClick={this.toggleRemoveUser()} text='Cancel' className='pt-minimal' disabled={this.state.removeUserLoading}/>
							<Button onClick={this.submitRemoveUser} text='Remove team' intent={Intent.DANGER} loading={this.state.removeUserLoading}/>

				</Dialog>

				{/* Remove team dialog */}
				<Dialog isOpen={this.state.removeTeamDialogOpen} onClose={this.toggleRemoveTeam} title='Remove team' iconName='warning-sign'>

						{this.state.removeTeamError ?

								{this.state.removeTeamError}

							:null}

							Are you sure you want to remove this team?

							<Button onClick={this.toggleRemoveTeam} text='Cancel' className='pt-minimal' disabled={this.state.removeTeamLoading}/>
							<Button onClick={this.submitRemoveTeam} text='Remove team' intent={Intent.DANGER} loading={this.state.removeTeamLoading}/>

				</Dialog>

		);
	}
}

export default TeamProfile;
<|endoftext|>


<commit_before>// Copyright 2002-2013, University of Colorado Boulder

/**
 * JSHint options for simulations and common code, meant to be passed to grunt-contrib-jshint
 */
module.exports = {
  // options documented at http://www.jshint.com/docs/#options

  // enforcing options
  curly: true, // require braces around blocks for loops and conditionals
  eqeqeq: true, // prohibit == and !=, use === and !===
  immed: true, // prohibits the use of immediate function invocations without wrapping them in parentheses
  latedef: true, // prohibits the use of a variable before it was defined
  newcap: true, // requires you to capitalize names of constructor functions
  noarg: true, // prohibits the use of arguments.caller and arguments.callee
  nonew: true, // prohibits calling new without assigning result to a variable
  undef: true, // prohibits the use of explicitly undeclared variables
  strict: true, // requires all functions to run in ECMAScript 5's strict mode

  // relaxing options
  expr: true, // suppresses warnings about the use of expressions where normally you would expect to see assignments or function calls, so we can use assert && assert( ... )
  loopfunc: true, // suppresses warnings about defining functions inside of loops, but we know how not to shoot ourselves in the foot, and this is useful for _.each
  unused: 'vars', // prohibit unused variables, allow unused function parameters

  // tell JSHint about global variables that are defined elsewhere. If value is false (default), JSHint will consider that variable as read-only.
  globals: {

    // writable globals ---------------------------------

    assert: true,  // allow assertions
    assertSlow: true, // allow slow assertions
    sceneryLog: true, // scenery logging levels
    sceneryLayerLog: true, // scenery logging levels
    sceneryEventLog: true, // scenery logging levels
    sceneryAccessibilityLog: true, // scenery accessibility levels
    phetAllocation: true, // for tracking object allocations, see phet-core's phetAllocation
    Float32Array: true, // we actually polyfill this, so allow it to be set
    phet: true,
    together: true,

    // read-only globals ---------------------------------

    define: false, // require.js
    require: false, // require.js
    Uint16Array: false,
    Uint32Array: false,
    XMLHttpRequest: false, // allow ajax requests directly
    document: false,
    window: false,
    console: false,
    HTMLImageElement: false,
    HTMLCanvasElement: false,
    Backbone: false, // backbone is currently run outside of requirejs
    module: false, // as used in Gruntfile.js
    $: false, // jQuery
    _: false, // underscore, lodash
    clearTimeout: false,
    Image: false, // DOM.js
    Blob: false,  // DOM.js
    canvg: false,
    io: false, //socket.io,
    TWEEN: false, //sole/tween.js
    navigator: false, //For Mobile Safari detection, see http://stackoverflow.com/questions/3007480/determine-if-user-navigated-from-mobile-safari
    Howl: false, //for web audio
    ActiveXObject: false, //for full screen
    Box2D: false, //For Box2D physics engine
    Stats: false, //For @mrdoob's stats + frame rate readout component
    poly2tri: false, //For poly2tri triangulation library
    THREE: false, //For three.js 3d things
    WebSocket: false, // for WebSocket communication
    WebGLDebugUtils: false, // for khronos webgl-debug.js debugging utilities
    iframePhone: false, // for CODAP or other Concord communication
    PIXI: false,
    arch: false,
    global: false, // for linting Node.js code

    alert: false, //for debugging on ipad
    numeric: false, //Numeric library used in energy skate park
    location: false, //For setting location.href to save to local file, see http://stackoverflow.com/questions/2897619/using-html5-javascript-to-generate-and-save-a-file
    FileReader: false, //For file loading, see SaveLoadNode in Energy Skate Park: Basics
    Buffer: false
  }
};

<commit_msg>Added jsondiffpatch to globals<commit_after>// Copyright 2002-2013, University of Colorado Boulder

/**
 * JSHint options for simulations and common code, meant to be passed to grunt-contrib-jshint
 */
module.exports = {
  // options documented at http://www.jshint.com/docs/#options

  // enforcing options
  curly: true, // require braces around blocks for loops and conditionals
  eqeqeq: true, // prohibit == and !=, use === and !===
  immed: true, // prohibits the use of immediate function invocations without wrapping them in parentheses
  latedef: true, // prohibits the use of a variable before it was defined
  newcap: true, // requires you to capitalize names of constructor functions
  noarg: true, // prohibits the use of arguments.caller and arguments.callee
  nonew: true, // prohibits calling new without assigning result to a variable
  undef: true, // prohibits the use of explicitly undeclared variables
  strict: true, // requires all functions to run in ECMAScript 5's strict mode

  // relaxing options
  expr: true, // suppresses warnings about the use of expressions where normally you would expect to see assignments or function calls, so we can use assert && assert( ... )
  loopfunc: true, // suppresses warnings about defining functions inside of loops, but we know how not to shoot ourselves in the foot, and this is useful for _.each
  unused: 'vars', // prohibit unused variables, allow unused function parameters

  // tell JSHint about global variables that are defined elsewhere. If value is false (default), JSHint will consider that variable as read-only.
  globals: {

    // writable globals ---------------------------------

    assert: true,  // allow assertions
    assertSlow: true, // allow slow assertions
    sceneryLog: true, // scenery logging levels
    sceneryLayerLog: true, // scenery logging levels
    sceneryEventLog: true, // scenery logging levels
    sceneryAccessibilityLog: true, // scenery accessibility levels
    phetAllocation: true, // for tracking object allocations, see phet-core's phetAllocation
    Float32Array: true, // we actually polyfill this, so allow it to be set
    phet: true,
    together: true,

    // read-only globals ---------------------------------

    define: false, // require.js
    require: false, // require.js
    Uint16Array: false,
    Uint32Array: false,
    XMLHttpRequest: false, // allow ajax requests directly
    document: false,
    window: false,
    console: false,
    HTMLImageElement: false,
    HTMLCanvasElement: false,
    Backbone: false, // backbone is currently run outside of requirejs
    module: false, // as used in Gruntfile.js
    $: false, // jQuery
    _: false, // underscore, lodash
    clearTimeout: false,
    Image: false, // DOM.js
    Blob: false,  // DOM.js
    canvg: false,
    io: false, //socket.io,
    TWEEN: false, //sole/tween.js
    navigator: false, //For Mobile Safari detection, see http://stackoverflow.com/questions/3007480/determine-if-user-navigated-from-mobile-safari
    Howl: false, //for web audio
    ActiveXObject: false, //for full screen
    Box2D: false, //For Box2D physics engine
    Stats: false, //For @mrdoob's stats + frame rate readout component
    poly2tri: false, //For poly2tri triangulation library
    THREE: false, //For three.js 3d things
    WebSocket: false, // for WebSocket communication
    WebGLDebugUtils: false, // for khronos webgl-debug.js debugging utilities
    iframePhone: false, // for CODAP or other Concord communication
    PIXI: false,
    arch: false,
    global: false, // for linting Node.js code
    jsondiffpatch: false, // for generating diffs in together.js

    alert: false, //for debugging on ipad
    numeric: false, //Numeric library used in energy skate park
    location: false, //For setting location.href to save to local file, see http://stackoverflow.com/questions/2897619/using-html5-javascript-to-generate-and-save-a-file
    FileReader: false, //For file loading, see SaveLoadNode in Energy Skate Park: Basics
    Buffer: false
  }
};

<|endoftext|>


<commit_before>var listening = false;
var autoRestart = true;
var keepAliveTimer;
var lastKeepAliveTime = 0;
var cycle = 0;

if (!('webkitSpeechRecognition' in window)) {
    incompatible();
    recognition = {};
} else {
    var recognition = new webkitSpeechRecognition();
    recognition.continuous = true;
    recognition.interimResults = true;
    recognition.lang = "en-US";
    recognition.maxAlternatives = 1;
    keepAlive();
}

var commands = [
    {
        "when": /^(clear|clear screen)$/i,
        "do": function(e) { clearScreen(); }
    },
    {
        "when": /^stop listening$/i,
        "do": function(e) {
            $(':last', '#out').remove();
            startButton();
        }
    },
    {
        "when": /^\n\n+$/,
        "do": function(e) {
            $(':last', '#out').remove();
            $('#out').append('

');
        }
    },
    {
        "when": /^\n$/,
        "do": function(e) {
            $(':last', '#out').remove();
            $('#out').append('

');
        }
    },
    {
        "when": /^(zoom in|bigger)$/i,
        "do": function(e) {
            $(':last', '#out').remove();
            setTimeout(increaseFont, 10);
        }
    },
    {
        "when": /^(zoom out|smaller)$/i,
        "do": function(e) {
            $(':last', '#out').remove();
            setTimeout(decreaseFont, 10);
        }
    },
    {
        "when": /^(undo|delete)$/i,
        "do": function(e) {
            $(':nth-last-child(-n+2)', '#out').remove();
        }
    }
    ];

recognition.onstart = function() {
    cycle++;
    listening = true;
};

recognition.onend = function() {
    if (autoRestart) {
        recognition.start();
    } else {
        console.log("stopped listening");
        listening = false;
        $('#mic').removeClass('on');
    }
};

recognition.onresult = function(event) {
    if (typeof(event.results) === 'undefined') {
        recognition.stop();
        return;
    }
    var out = '';
    var isFinal = true;
    for (var i = event.resultIndex; i < event.results.length; i++) {
        if (!event.results[i].isFinal) isFinal = false;
        out = out + event.results[i][0].transcript + ' ';
    }
    out = out.replace(/^ +| +$/g,''); // trim, preserving newlines
    if (isFinal) {
        for (var i=0; i < commands.length; i++) {
            if (commands[i].when.test(out)) {
                commands[i].do(event);
                return;
            }
        }
    }
    var elemId = 'i' + cycle + '-' + event.resultIndex;
    var elem = $('#' + elemId);
    if (!elem.length) {
        elem = $('');
        $('#out').append(elem);
    }
    if (isFinal) {
        $(elem).addClass('final');
        prune();
    }
    $(elem).text(out);
    if (isFinal) {
        keepAliveCheck();
    }
    $('html, body').animate({
        scrollTop: $(document).height()
    }, 'fast');
};

function keepAlive() {
    recognition.stop();
    lastKeepAliveTime = new Date().getTime();
    clearInterval(keepAliveTimer);
    keepAliveTimer = setTimeout(keepAlive, 30000)
}

function keepAliveCheck() {
    if (new Date().getTime() - lastKeepAliveTime > 10000) {
        keepAlive();
    }
}

function startButton() {
    if (listening) {
        autoRestart = false;
        recognition.stop();
    } else {
        if (!recognition.start) {
            return;
        }
        recognition.start();
        autoRestart = true;
        clearScreen();
        $('#mic').addClass('on');
    }
}

function getFontSize() {
    return parseInt(/(\d+)pt/.exec(document.styleSheets[1].cssRules[0].style.fontSize)[1]);
}

function setFontSize(fontSize) {
    if (fontSize >= 8 && fontSize <= 150) {
        document.styleSheets[1].cssRules[0].style.fontSize = fontSize + 'pt';
        localStorage.setItem('visiblespeech.fontSize', fontSize);
    }
}

function increaseFont() {
    setFontSize(getFontSize() + 4);
}

function decreaseFont() {
    setFontSize(getFontSize() - 4);
}

function clearScreen() {
    $('#out').empty();
}

function prune() {
    $(':not(:nth-last-child(-n+100))', '#out').remove();
}

function incompatible() {
    setTimeout(function() {$('#incompatible').show();}, 0);
}<commit_msg>Log commands<commit_after>var listening = false;
var autoRestart = true;
var keepAliveTimer;
var lastKeepAliveTime = 0;
var cycle = 0;

if (!('webkitSpeechRecognition' in window)) {
    incompatible();
    recognition = {};
} else {
    var recognition = new webkitSpeechRecognition();
    recognition.continuous = true;
    recognition.interimResults = true;
    recognition.lang = "en-US";
    recognition.maxAlternatives = 1;
    keepAlive();
}

var commands = [
    {
        "when": /^(clear|clear screen)$/i,
        "do": function(e) {
            clearScreen();
        },
        "log": "clear"
    },
    {
        "when": /^stop listening$/i,
        "do": function(e) {
            $(':last', '#out').remove();
            startButton();
        },
        "log": "stop"
    },
    {
        "when": /^\n\n+$/,
        "do": function(e) {
            $(':last', '#out').remove();
            $('#out').append('

');
        },
        "log": "newline"
    },
    {
        "when": /^\n$/,
        "do": function(e) {
            $(':last', '#out').remove();
            $('#out').append('

');
        },
        "log": "paragraph"
    },
    {
        "when": /^(zoom in|bigger)$/i,
        "do": function(e) {
            $(':last', '#out').remove();
            setTimeout(increaseFont, 10);
        },
        "log": "bigger"
    },
    {
        "when": /^(zoom out|smaller)$/i,
        "do": function(e) {
            $(':last', '#out').remove();
            setTimeout(decreaseFont, 10);
        },
        "log": "smaller"
    },
    {
        "when": /^(undo|delete)$/i,
        "do": function(e) {
            $(':nth-last-child(-n+2)', '#out').remove();
        },
        "log": "delete"
    }
    ];

recognition.onstart = function() {
    cycle++;
    listening = true;
};

recognition.onend = function() {
    if (autoRestart) {
        recognition.start();
    } else {
        console.log("stopped listening");
        listening = false;
        $('#mic').removeClass('on');
    }
};

recognition.onresult = function(event) {
    if (typeof(event.results) === 'undefined') {
        recognition.stop();
        return;
    }
    var out = '';
    var isFinal = true;
    for (var i = event.resultIndex; i < event.results.length; i++) {
        if (!event.results[i].isFinal) isFinal = false;
        out = out + event.results[i][0].transcript + ' ';
    }
    out = out.replace(/^ +| +$/g,''); // trim, preserving newlines
    for (var i=0; i < commands.length; i++) {
        if (commands[i].when.test(out)) {
            commands[i].do(event);
            if (commands[i].log) {
                ga('send', 'event', 'command', commands[i].log);
            }
            return;
        }
    }
    var elemId = 'i' + cycle + '-' + event.resultIndex;
    var elem = $('#' + elemId);
    if (!elem.length) {
        elem = $('');
        $('#out').append(elem);
    }
    if (isFinal) {
        $(elem).addClass('final');
        prune();
    }
    $(elem).text(out);
    if (isFinal) {
        keepAliveCheck();
    }
    $('html, body').animate({
        scrollTop: $(document).height()
    }, 'fast');
};

function keepAlive() {
    recognition.stop();
    lastKeepAliveTime = new Date().getTime();
    clearInterval(keepAliveTimer);
    keepAliveTimer = setTimeout(keepAlive, 30000)
}

function keepAliveCheck() {
    if (new Date().getTime() - lastKeepAliveTime > 10000) {
        keepAlive();
    }
}

function startButton() {
    if (listening) {
        autoRestart = false;
        recognition.stop();
    } else {
        if (!recognition.start) {
            return;
        }
        recognition.start();
        autoRestart = true;
        clearScreen();
        $('#mic').addClass('on');
    }
}

function getFontSize() {
    return parseInt(/(\d+)pt/.exec(document.styleSheets[1].cssRules[0].style.fontSize)[1]);
}

function setFontSize(fontSize) {
    if (fontSize >= 8 && fontSize <= 150) {
        document.styleSheets[1].cssRules[0].style.fontSize = fontSize + 'pt';
        localStorage.setItem('visiblespeech.fontSize', fontSize);
    }
}

function increaseFont() {
    setFontSize(getFontSize() + 4);
}

function decreaseFont() {
    setFontSize(getFontSize() - 4);
}

function clearScreen() {
    $('#out').empty();
}

function prune() {
    $(':not(:nth-last-child(-n+100))', '#out').remove();
}

function incompatible() {
    setTimeout(function() {$('#incompatible').show();}, 0);
}<|endoftext|>


<commit_before>// Relative imports.
import AfghanistanPromoBanner from '../components/AfghanistanPromoBanner';
import ExploreVAModal from '../components/ExploreVAModal';
import SingleSignOnInfoModal from '../components/SingleSignOnInfoModal';
import VAMCWelcomeModal, { VAMC_PATHS } from '../components/VAMCWelcomeModal';
import VAPlusVetsModal from '../components/VAPlusVetsModal';

const config = {
  announcements: [
    {
      name: 'afghanistan-banner',
      // Only the homepage (e.g. `/`).
      paths: /^(\/)$/,
      component: AfghanistanPromoBanner,
    },
    {
      name: 'brand-consolidation-va-plus-vets',
      // All pages.
      paths: /(.)/,
      component: VAPlusVetsModal,
      disabled: !VAPlusVetsModal.isEnabled(),
      showEverytime: true,
    },
    {
      name: 'explore-va',
      // All pages.
      paths: /(.)/,
      component: ExploreVAModal,
      disabled: !ExploreVAModal.isEnabled(),
      showEverytime: true,
    },
    {
      name: 'pittsburgh-vamc',
      paths: VAMC_PATHS.PITTSBURGH,
      component: VAMCWelcomeModal,
      region: 'Pittsburgh',
    },
    {
      name: 'single-sign-on-intro',
      // All pages except the sign-in page and subroutes.
      paths: /^(?!.*\/sign-in\/).*$/,
      component: SingleSignOnInfoModal,
    },
  ],
};

export default config;
<commit_msg>Change afghanistan banner name for new version (#18756)<commit_after>// Relative imports.
import AfghanistanPromoBanner from '../components/AfghanistanPromoBanner';
import ExploreVAModal from '../components/ExploreVAModal';
import SingleSignOnInfoModal from '../components/SingleSignOnInfoModal';
import VAMCWelcomeModal, { VAMC_PATHS } from '../components/VAMCWelcomeModal';
import VAPlusVetsModal from '../components/VAPlusVetsModal';

const config = {
  announcements: [
    {
      name: 'afghanistan-banner-v2',
      // Only the homepage (e.g. `/`).
      paths: /^(\/)$/,
      component: AfghanistanPromoBanner,
    },
    {
      name: 'brand-consolidation-va-plus-vets',
      // All pages.
      paths: /(.)/,
      component: VAPlusVetsModal,
      disabled: !VAPlusVetsModal.isEnabled(),
      showEverytime: true,
    },
    {
      name: 'explore-va',
      // All pages.
      paths: /(.)/,
      component: ExploreVAModal,
      disabled: !ExploreVAModal.isEnabled(),
      showEverytime: true,
    },
    {
      name: 'pittsburgh-vamc',
      paths: VAMC_PATHS.PITTSBURGH,
      component: VAMCWelcomeModal,
      region: 'Pittsburgh',
    },
    {
      name: 'single-sign-on-intro',
      // All pages except the sign-in page and subroutes.
      paths: /^(?!.*\/sign-in\/).*$/,
      component: SingleSignOnInfoModal,
    },
  ],
};

export default config;
<|endoftext|>


<commit_before>/*
 * Dịch các văn bản mặc định cho bootstrap-select.
 * Locale: VI (Vietnamese)
 * Region: VN (Việt Nam)
 */
(function ($) {
  $.fn.selectpicker.defaults = {
    noneSelectedText: 'Chưa chọn',
    noneResultsText: 'Không có kết quả {0}',
    countSelectedText: function (numSelected, numTotal) {
      return "{0} mục đã chọn";
    },
    maxOptionsText: function (numAll, numGroup) {
      return [
        'Không thể chọn (giới hạn {n} mục)',
        'Không thể chọn (giới hạn {n} mục)'
      ];
    },
    selectAllText: 'Chọn tất cả',
    deselectAllText: 'Bỏ chọn',
    multipleSeparator: ', '
  };
})(jQuery);
<commit_msg>update Vietnamese language<commit_after>/*
 * Dịch các văn bản mặc định cho bootstrap-select.
 * Locale: VI (Vietnamese)
 * Region: VN (Việt Nam)
 */
(function ($) {
  $.fn.selectpicker.defaults = {
    noneSelectedText: 'Chưa chọn',
    noneResultsText: 'Không có kết quả cho {0}',
    countSelectedText: function (numSelected, numTotal) {
      return "{0} mục đã chọn";
    },
    maxOptionsText: function (numAll, numGroup) {
      return [
        'Không thể chọn (giới hạn {n} mục)',
        'Không thể chọn (giới hạn {n} mục)'
      ];
    },
    selectAllText: 'Chọn tất cả',
    deselectAllText: 'Bỏ chọn',
    multipleSeparator: ', '
  };
})(jQuery);
<|endoftext|>


<commit_before>// PiscoBot Script

var commandDescription = {
  name: 'Points',
  author: 'Daniel Gallegos [@that_taco_guy]',
  trigger: ':pisco:/:poop:',
  version: 1.0,
  description: 'Give or take away points from other users.',
  module: 'Core'
};

global.botHelp.push(commandDescription);

var _ = require('underscore');

function notifyRecipient(bot, message, value, user) {
  bot.startPrivateConversation({ user: user.id }, function(err, convo) {
    var notif = 'You just got ';
    if(value > 0) {
      notif += 'a shot of Pisco from <@' + message.user + '>! :tropical_drink: :sunglasses:';
    } else if(value < 0) {
      notif += 'some :shit: from <@' + message.user + '>. :joy:';
    }
    notif += '\nYou have `' + user.points + '` points now.';
    convo.say(notif);
    convo.next();
  });
}

function notifyGiver(bot, message, value, user) {
  bot.startPrivateConversation(message, function(err, convo) {
    var info = 'You just gave ';
    if(value > 0) {
      info += 'a shot of Pisco to <@' + user.id + '>. :tropical_drink: :smile:';
    } else if(value < 0) {
      info += 'some :shit: to <@' + user.id + '>. :joy:';
    }
    convo.say(info);
    convo.next();
  });
}

function modifyPoints(bot, message, value) {
  var userMatcher = /<@([A-Z0-9]*)>/g;
  var usersMatched = message.text.match(userMatcher);
  var userIDs = [];
  for(var rawUser of usersMatched) {
    var trimmedID = rawUser.replace(/(<|@|>)/g, '');
    if(trimmedID === message.user) {
      bot.reply(message, 'You can\'t give yourself points. :unamused:');
      return;
    } else {
      userIDs.push(trimmedID);
    }
  }
  if(!_.isEmpty(userIDs)) {
    for(var userID of userIDs) {
      global.piscobot.storage.users.get(userID, function(err, user) {
        if(!err) {
          if(!user) {
            user = { id: userID };
            user.points = 0;
          }
          user.points += value;
          if (user.points < 0) {
            user.points = 0;
          }
          global.piscobot.storage.users.save(user, function(err) {
            if(!err) {
              notifyRecipient(bot, message, value, user);
              notifyGiver(bot, message, value, user);
            }
          });
        }
      });
    }
    return;
  }
}

global.piscobot.hears(
  [':poop:', ':hankey:', ':shit:', ':pisco:', ':tropical_drink:'], ['ambient'],
  function(bot, message) {
    var add = [':pisco:', ':tropical_drink:'];
    var remove = [':poop:', ':hankey:', ':shit:'];
    if(_.contains(add, message.match[0])) {
      modifyPoints(bot, message, +1);
    } else if(_.contains(remove, message.match[0])) {
      modifyPoints(bot, message, -1);
    }
  }
);

global.piscobot.hears(
  ['^leaderboard'], ['direct_message', 'direct_mention'],
  function(bot, message) {
    bot.api.users.list({ token: process.env.SLACK_API_TOKEN }, function(err, team) {
      if(team.ok) {
        var users = [];
        var promises = [];
        team.members.forEach(function(member) {
          if(member.is_bot === false && member.deleted === false && member.id !== 'USLACKBOT') {
            var promise = new Promise(function(resolve, reject) {
              global.piscobot.storage.users.get(member.id, function(err, user) {
                if(err) {
                  return reject(err);
                } else {
                  if(user && user !== null) {
                    if(!user.points || user.points < 0) {
                      user.points = 0;
                    }
                    user.username = member.name;
                  } else {
                    user = { id: member.id, points: 0 };
                    global.piscobot.storage.users.save(user);
                  }
                  users.push(user);
                  return resolve();
                }
              });
            });
            promises.push(promise);
          } else {
            return;
          }
        });
        Promise.all(promises).then(function() {
          var fields = [];
          users.sort(function(a, b) {
            return b.points - a.points;
          });
          for(var user of users) {
            fields.push({
              'title': user.username,
              'value': user.points,
              'short': true
            });
          }
          var response = {
            'attachments': [{
              'fallback': 'Leaderboard for PiscoBot points system.',
              'color': '#FF7300',
              'pretext': 'Here\'s how many points everyone has, <@' + message.user +
                '>!',
              'title': 'Leaderboard',
              'fields': fields,
              'footer': 'PiscoBot',
              'footer_icon': 'https://raw.githubusercontent.com/' +
                'twitter/twemoji/gh-pages/72x72/1f379.png'
            }]
          };
          bot.reply(message, response);
        });
      } else {
        bot.reply(message,
          'There was a problem getting the points from Slack. Sorry! :disappointed:');
      }
    });
  }
);
<commit_msg>Remove notification sent to point giver<commit_after>// PiscoBot Script

var commandDescription = {
  name: 'Points',
  author: 'Daniel Gallegos [@that_taco_guy]',
  trigger: ':pisco:/:poop:',
  description: 'Give or take away points from other users.',
  module: 'Core'
};

global.botHelp.push(commandDescription);

var _ = require('underscore');

function notifyRecipient(bot, message, value, user) {
  bot.startPrivateConversation({ user: user.id }, function(err, convo) {
    var notif = 'You just got ';
    if(value > 0) {
      notif += 'a shot of Pisco from <@' + message.user + '>! :tropical_drink: :sunglasses:';
    } else if(value < 0) {
      notif += 'some :shit: from <@' + message.user + '>. :joy:';
    }
    notif += '\nYou have `' + user.points + '` points now.';
    convo.say(notif);
    convo.next();
  });
}

function modifyPoints(bot, message, value) {
  var userMatcher = /<@([A-Z0-9]*)>/g;
  var usersMatched = message.text.match(userMatcher);
  var userIDs = [];
  for(var rawUser of usersMatched) {
    var trimmedID = rawUser.replace(/(<|@|>)/g, '');
    if(trimmedID === message.user) {
      bot.reply(message, 'You can\'t give yourself points. :unamused:');
      return;
    } else {
      userIDs.push(trimmedID);
    }
  }
  if(!_.isEmpty(userIDs)) {
    for(var userID of userIDs) {
      global.piscobot.storage.users.get(userID, function(err, user) {
        if(!err) {
          if(!user) {
            user = { id: userID };
            user.points = 0;
          }
          user.points += value;
          if(user.points < 0) {
            user.points = 0;
          }
          global.piscobot.storage.users.save(user, function(err) {
            if(!err) {
              notifyRecipient(bot, message, value, user);
            }
          });
        }
      });
    }
    return;
  }
}

global.piscobot.hears(
  [':poop:', ':hankey:', ':shit:', ':pisco:', ':tropical_drink:'], ['ambient'],
  function(bot, message) {
    var add = [':pisco:', ':tropical_drink:'];
    var remove = [':poop:', ':hankey:', ':shit:'];
    if(_.contains(add, message.match[0])) {
      modifyPoints(bot, message, +1);
    } else if(_.contains(remove, message.match[0])) {
      modifyPoints(bot, message, -1);
    }
  }
);

global.piscobot.hears(
  ['^leaderboard'], ['direct_message', 'direct_mention'],
  function(bot, message) {
    bot.api.users.list({ token: process.env.SLACK_API_TOKEN }, function(err, team) {
      if(team.ok) {
        var users = [];
        var promises = [];
        team.members.forEach(function(member) {
          if(member.is_bot === false && member.deleted === false && member.id !==
            'USLACKBOT') {
            var promise = new Promise(function(resolve, reject) {
              global.piscobot.storage.users.get(member.id, function(err, user) {
                if(err) {
                  return reject(err);
                } else {
                  if(user && user !== null) {
                    if(!user.points || user.points < 0) {
                      user.points = 0;
                    }
                    user.username = member.name;
                  } else {
                    user = { id: member.id, points: 0 };
                    global.piscobot.storage.users.save(user);
                  }
                  users.push(user);
                  return resolve();
                }
              });
            });
            promises.push(promise);
          } else {
            return;
          }
        });
        Promise.all(promises).then(function() {
          var fields = [];
          users.sort(function(a, b) {
            return b.points - a.points;
          });
          for(var user of users) {
            fields.push({
              'title': user.username,
              'value': user.points,
              'short': true
            });
          }
          var response = {
            'attachments': [{
              'fallback': 'Leaderboard for PiscoBot points system.',
              'color': '#FF7300',
              'pretext': 'Here\'s how many points everyone has, <@' + message.user +
                '>!',
              'title': 'Leaderboard',
              'fields': fields,
              'footer': 'PiscoBot',
              'footer_icon': 'https://raw.githubusercontent.com/' +
                'twitter/twemoji/gh-pages/72x72/1f379.png'
            }]
          };
          bot.reply(message, response);
        });
      } else {
        bot.reply(message,
          'There was a problem getting the points from Slack. Sorry! :disappointed:');
      }
    });
  }
);
<|endoftext|>


<commit_before>function hsreact$mk_ctrl_view(name, store, renderCb) {
    return React.createClass({
        displayName: name,
        getInitialState: function() {
            return store.sdata;
        },
        _onViewChange: function(x) { // allows binding to this
            this.setState(x);
        },
        componentDidMount: function() {
            store.views.push(this._onViewChange);
        },
        componentWillUnmount: function() {
            var idx = store.views.indexOf(this._onViewChange);
            if (idx >= 0) { store.views.splice(idx, 1); }
            this._currentCallbacks.map(h$release);
            h$release(this.props.hs);
        },
        componentWillReceiveProps: function() {
            h$release(this.props.hs);
        },
        render: function() {
            var arg = {
                state: this.state,
                props: this.props.hs,
                newCallbacks: [],
                elem:null,
            };
            renderCb(arg);
            this._currentCallbacks.map(h$release);
            this._currentCallbacks = arg.newCallbacks;
            return arg.elem;
        },
        _currentCallbacks: [],
    });
}

function hsreact$mk_view(name, renderCb) {
    return React.createClass({
        displayName: name,
        componentWillUnmount: function() {
            this._currentCallbacks.map(h$release);
            h$release(this.props.hs);
        },
        componentWillReceiveProps: function() {
            h$release(this.props.hs);
        },
        render: function() {
            var arg = {
                props: this.props.hs,
                newCallbacks: [],
                elem:null,
            };
            renderCb(arg);
            this._currentCallbacks.map(h$release);
            this._currentCallbacks = arg.newCallbacks;
            return arg.elem;
        },
        _currentCallbacks: [],
    });
}

function hsreact$mk_stateful_view(name, initialState, renderCb) {
    return React.createClass({
        displayName: name,
        getInitialState: function() {
            return { hs: initialState };
        },
        componentWillUnmount: function() {
            this._currentCallbacks.map(h$release);
            h$release(this.props.hs);
            h$release(this.state.hs);
        },
        componentWillReceiveProps: function() {
            h$release(this.props.hs);
        },
        render: function() {
            var that = this;
            var arg = {
                state: this.state.hs,
                props: this.props.hs,
                newCallbacks: [],
                elem:null,
                alterState: {
                    getState: function() { return that.state.hs; },
                    setState: function(s) {
                        h$release(that.state.hs);
                        that.setState({hs: s});
                    },
                },
            };
            renderCb(arg);
            this._currentCallbacks.map(h$release);
            this._currentCallbacks = arg.newCallbacks;
            return arg.elem;
        },
        _currentCallbacks: [],
    });
}
<commit_msg>Add shouldComponentUpdate functions<commit_after>function hsreact$mk_ctrl_view(name, store, renderCb) {
    return React.createClass({
        displayName: name,
        getInitialState: function() {
            return store.sdata;
        },
        _onViewChange: function(x) { // allows binding to this
            this.setState(x);
        },
        shouldComponentUpdate: function(newProps, newState) {
            return this.props.hs.root != newProps.hs.root || this.state.root != newState.root;
        },
        componentDidMount: function() {
            store.views.push(this._onViewChange);
        },
        componentWillUnmount: function() {
            var idx = store.views.indexOf(this._onViewChange);
            if (idx >= 0) { store.views.splice(idx, 1); }
            this._currentCallbacks.map(h$release);
            h$release(this.props.hs);
        },
        componentWillReceiveProps: function() {
            h$release(this.props.hs);
        },
        render: function() {
            var arg = {
                state: this.state,
                props: this.props.hs,
                newCallbacks: [],
                elem:null,
            };
            renderCb(arg);
            this._currentCallbacks.map(h$release);
            this._currentCallbacks = arg.newCallbacks;
            return arg.elem;
        },
        _currentCallbacks: [],
    });
}

function hsreact$mk_view(name, renderCb) {
    return React.createClass({
        displayName: name,
        componentWillUnmount: function() {
            this._currentCallbacks.map(h$release);
            h$release(this.props.hs);
        },
        shouldComponentUpdate: function(newProps, newState) {
            return this.props.hs.root != newProps.hs.root;
        },
        componentWillReceiveProps: function() {
            h$release(this.props.hs);
        },
        render: function() {
            var arg = {
                props: this.props.hs,
                newCallbacks: [],
                elem:null,
            };
            renderCb(arg);
            this._currentCallbacks.map(h$release);
            this._currentCallbacks = arg.newCallbacks;
            return arg.elem;
        },
        _currentCallbacks: [],
    });
}

function hsreact$mk_stateful_view(name, initialState, renderCb) {
    return React.createClass({
        displayName: name,
        getInitialState: function() {
            return { hs: initialState };
        },
        shouldComponentUpdate: function(newProps, newState) {
            return this.props.hs.root != newProps.hs.root || this.state.hs.root != newState.hs.root;
        },
        componentWillUnmount: function() {
            this._currentCallbacks.map(h$release);
            h$release(this.props.hs);
            h$release(this.state.hs);
        },
        componentWillReceiveProps: function() {
            h$release(this.props.hs);
        },
        render: function() {
            var that = this;
            var arg = {
                state: this.state.hs,
                props: this.props.hs,
                newCallbacks: [],
                elem:null,
                alterState: {
                    getState: function() { return that.state.hs; },
                    setState: function(s) {
                        h$release(that.state.hs);
                        that.setState({hs: s});
                    },
                },
            };
            renderCb(arg);
            this._currentCallbacks.map(h$release);
            this._currentCallbacks = arg.newCallbacks;
            return arg.elem;
        },
        _currentCallbacks: [],
    });
}
<|endoftext|>


<commit_before>(function (window, document)
{

	var cookieStrKey = 'traffic_src';

	//inject global function for cookie retrieval
	window.getTrafficSrcCookie = function()
	{
		var cookies = document.cookie.split(';');
		var cookieObj = cookies.filter(function(cookie) {
			return cookie.indexOf(cookieStrKey) >= 0;
		})[0];
		if(cookieObj)
		{
			cookieObj = cookieObj.substring(cookieObj.indexOf('=') + 1, cookieObj.length);
			return JSON.parse(cookieObj);
		}
		return null;
	};

	var utils = {
		getParameterByName: function(url, name)
		{
			name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
			var regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
			var results = regex.exec(url);
			return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
		},

		getKeywords: function(url)
		{
			if(url === '' || url === 'direct') return '';

			var searchEngines = 'daum:q eniro:search_word naver:query pchome:q images.google:q google:q yahoo:p yahoo:q msn:q bing:q aol:query aol:q lycos:q lycos:query ask:q cnn:query virgilio:qs baidu:wd baidu:word alice:qs yandex:text najdi:q seznam:q rakuten:qt biglobe:q goo.ne:MT search.smt.docomo:MT onet:qt onet:q kvasir:q terra:query rambler:query conduit:q babylon:q search-results:q avg:q comcast:q incredimail:q startsiden:q go.mail.ru:q centrum.cz:q 360.cn:q sogou:query tut.by:query globo:q ukr:q so.com:q haosou.com:q auone:q'.split(' ');
			for(var i = 0; i < searchEngines.length; i++)
			{
				var val = searchEngines[i].split(':');
				var name = val[0];
				var queryParam = val[1];
				if(url.indexOf(name) >= 0 && this.getParameterByName(url, queryParam) !== '') {
					return this.getParameterByName(url, queryParam);
				}
			}

			var google = new RegExp('^https?:\/\/(www\.)?google(\.com?)?(\.[a-z]{2}t?)?\/?$', 'i');
			var yahoo = new RegExp('^https?:\/\/(r\.)?search\.yahoo\.com\/?[^?]*$', 'i');
			var bing = new RegExp('^https?:\/\/(www\.)?bing\.com\/?$', 'i');
			if(google.test(url) || yahoo.test(url) || bing.test(url)) {
				return '(not provided)';
			}

			return '';
		},

		getMedium: function(ccokieObj)
		{
			if(cookieObj.utm_medium !== '') return cookieObj.utm_medium;

			if(cookieObj.gclid !== '') return 'cpc';

			if(cookieObj.utm_source === '') return '';

			if(cookieObj.utm_source === 'direct') return '(none)';

			if(cookieObj.utm_term !== '') return 'organic';

			return 'referral';
		},

		getDateAfterYears: function(years)
		{
			return new Date(new Date().getTime() + (years * 365 * 24 * 60 * 60 * 1000));
		}
	};

	var parameters = [{
		key: 'utm_source',
		required:  true
	}, {
		key: 'utm_medium',
		required: true
	}, {
		key: 'utm_campaign',
		required: true
	}, {
		key: 'utm_content',
		required: false
	}, {
		key: 'utm_term',
		required: false
	}];

	var cookieObj = {};

	var setCookie = function()
	{
		cookieObj.gclid = utils.getParameterByName(document.location.href, 'gclid');

		var ignoreUtmParameters = false;
		for(var i = 0; i < parameters.length; i++) {
			var value = utils.getParameterByName(document.location.href, parameters[i].key);
			if(parameters[i].required && value === '') {
				ignoreUtmParameters = true;
				for(var j = 0; j < parameters.length; j++) {
					cookieObj[parameters[j]['key']] = '';
				}
				break;
			}
			cookieObj[parameters[i]['key']] = value;
		}

		if (cookieObj.gclid !== '' && cookieObj.utm_source === '')
		{
			cookieObj.utm_source = 'google';
		}
		else if(ignoreUtmParameters)
		{
			if(document.referrer.indexOf(document.location.host) >= 0) return;
			if(window.getTrafficSrcCookie() !== null && document.referrer === '') return;
			cookieObj.utm_source = document.referrer !== '' ? document.referrer : 'direct';
		}

		cookieObj.utm_term = cookieObj.utm_term === '' ? utils.getKeywords(cookieObj.utm_source) : cookieObj.utm_term;
		cookieObj.utm_medium = utils.getMedium(cookieObj);
		cookieObj.landingPage = document.location.href;

		if(cookieObj.utm_source !== '')
		{
			var cookieStr = JSON.stringify(cookieObj);
			document.cookie = cookieStrKey + '=; expires=' + new Date(-1);
			document.cookie = cookieStrKey + '=' + cookieStr + '; expires=' + utils.getDateAfterYears(1);
		}
	};

	setCookie();
})(window, document);<commit_msg>quirk<commit_after>(function (window, document)
{

	var cookieStrKey = 'traffic_src';

	//inject global function for cookie retrieval
	window.getTrafficSrcCookie = function()
	{
		var cookies = document.cookie.split(';');
		var cookieObj = cookies.filter(function(cookie) {
			return cookie.indexOf(cookieStrKey) >= 0;
		})[0];
		if(cookieObj)
		{
			cookieObj = cookieObj.substring(cookieObj.indexOf('=') + 1, cookieObj.length);
			return JSON.parse(cookieObj);
		}
		return null;
	};

	var utils = {
		getParameterByName: function(url, name)
		{
			name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
			var regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
			var results = regex.exec(url);
			return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
		},

		getKeywords: function(url)
		{
			if(url === '' || url === 'direct') return '';

			var searchEngines = 'daum:q eniro:search_word naver:query pchome:q images.google:q google:q yahoo:p yahoo:q msn:q bing:q aol:query aol:q lycos:q lycos:query ask:q cnn:query virgilio:qs baidu:wd baidu:word alice:qs yandex:text najdi:q seznam:q rakuten:qt biglobe:q goo.ne:MT search.smt.docomo:MT onet:qt onet:q kvasir:q terra:query rambler:query conduit:q babylon:q search-results:q avg:q comcast:q incredimail:q startsiden:q go.mail.ru:q centrum.cz:q 360.cn:q sogou:query tut.by:query globo:q ukr:q so.com:q haosou.com:q auone:q'.split(' ');
			for(var i = 0; i < searchEngines.length; i++)
			{
				var val = searchEngines[i].split(':');
				var name = val[0];
				var queryParam = val[1];
				if(url.indexOf(name) >= 0 && this.getParameterByName(url, queryParam) !== '') {
					return this.getParameterByName(url, queryParam);
				}
			}

			var google = new RegExp('^https?:\/\/(www\.)?google(\.com?)?(\.[a-z]{2}t?)?\/?$', 'i');
			var yahoo = new RegExp('^https?:\/\/(r\.)?search\.yahoo\.com\/?[^?]*$', 'i');
			var bing = new RegExp('^https?:\/\/(www\.)?bing\.com\/?$', 'i');
			if(google.test(url) || yahoo.test(url) || bing.test(url)) {
				return '(not provided)';
			}

			return '';
		},

		getMedium: function(ccokieObj)
		{
			if(cookieObj.utm_medium !== '') return cookieObj.utm_medium;

			if(cookieObj.gclid !== '') return 'cpc';

			if(cookieObj.utm_source === '') return '';

			if(cookieObj.utm_source === 'direct') return '(none)';

			if(cookieObj.utm_term !== '') return 'organic';

			return 'referral';
		},

		getDateAfterYears: function(years)
		{
			return new Date(new Date().getTime() + (years * 365 * 24 * 60 * 60 * 1000));
		}
	};

	var parameters = [{
		key: 'utm_source',
		required:  true
	}, {
		key: 'utm_medium',
		required: true
	}, {
		key: 'utm_campaign',
		required: true
	}, {
		key: 'utm_content',
		required: false
	}, {
		key: 'utm_term',
		required: false
	}];

	var cookieObj = {};

	var setCookie = function()
	{
		cookieObj.gclid = utils.getParameterByName(document.location.href, 'gclid');

		var ignoreUtmParameters = false;
		for(var i = 0; i < parameters.length; i++) {
			var value = utils.getParameterByName(document.location.href, parameters[i].key);
			if(parameters[i].required && value === '') {
				ignoreUtmParameters = true;
				for(var j = 0; j < parameters.length; j++) {
					cookieObj[parameters[j]['key']] = '';
				}
				break;
			}
			cookieObj[parameters[i]['key']] = value;
		}

		if (cookieObj.gclid !== '' && cookieObj.utm_source === '')
		{
			cookieObj.utm_source = 'google';
		}
		else if(ignoreUtmParameters)
		{
			if(document.referrer.indexOf(document.location.host) >= 0) return;
			if(window.getTrafficSrcCookie() !== null && document.referrer === '') return;
			cookieObj.utm_source = document.referrer !== '' ? document.referrer : 'direct';
		}

		cookieObj.utm_term = cookieObj.utm_term === '' ? utils.getKeywords(cookieObj.utm_source) : cookieObj.utm_term;
		cookieObj.utm_medium = utils.getMedium(cookieObj);
		cookieObj.landing_page = document.location.href;

		if(cookieObj.utm_source !== '')
		{
			var cookieStr = JSON.stringify(cookieObj);
			document.cookie = cookieStrKey + '=; expires=' + new Date(-1);
			document.cookie = cookieStrKey + '=' + cookieStr + '; expires=' + utils.getDateAfterYears(1);
		}
	};

	setCookie();
})(window, document);<|endoftext|>


<commit_before>include('account.js');

// FIXME: Instead of having global state, it'd be better to maintain a cache
var repositoryMenuItems = [];

const SET_TOKEN_FORMAT    = /^!set-token (.*)$/;
const ISSUE_OR_PR_FORMAT  = /^([^\/]+\/[^\/#]+)(?:\/pull\/|\/issues\/|#)(\d+)$/;
const REPOSITORY_FORMAT   = /^([^\/]+)\/([^\/#]+)$/;
const ACCOUNT_FORMAT      = /^(\w+)$/;

function run(argument) {
  runWithString(argument);
}

function runWithString(string) {
  let match;

  // Matching:
  // set-token <token>
  if (match = string.match(SET_TOKEN_FORMAT)) {
    return setToken(match[1])
  }

  // Matching:
  // rails/rails#123
  // rails/rails/issues/123
  // rails/rails/pull/123
  else if (match = string.match(ISSUE_OR_PR_FORMAT)) {
    return openIssue(match[1], match[2]);
  }

  // Matching:
  // rails/rails
  else if (match = string.match(REPOSITORY_FORMAT)) {
    return openRepository(match[2], match[1]);
  }

  // Matching:
  // rails
  else if (match = string.match(ACCOUNT_FORMAT)) {
    var account = new Account(match[1])
    return openAccount(account);
  }

  // Matching everything else:
  // rails/rails/tree/master/Gemfile
  else {
    LaunchBar.openURL('https://github.com/' + string);
  }
}

function setToken(token) {
  Action.preferences.token = token;
  LaunchBar.displayNotification({
    title: 'GitHub access token set successfully'
  });
}

function openIssue(nameWithOwner, number) {
  LaunchBar.openURL('https://github.com/' + nameWithOwner + '/issues/' + number);
}

function openRepository(name, owner) {
  var url = 'https://github.com/' + owner + '/' + name

  if (LaunchBar.options.commandKey == 1) {
    LaunchBar.openURL(url)
  } else {
    return [
      {
        title: 'View Repository',
        subtitle: '@' + owner + '/' + name,
        alwaysShowsSubtitle: true,
        icon: 'repo.png',
        url: url
      },
      {
        title: 'View Issues',
        icon: 'issue.png',
        url: url + '/issues/'
      },
      {
        title: 'View Pull Requests',
        icon: 'pull-request.png',
        url: url + '/pulls/'
      }
    ]
  }
}

function openAccount(account) {
  if (LaunchBar.options.commandKey == 1) {
    LaunchBar.openURL(account.profileURL)
  } else {
    return [
      {
        title: 'View Profile',
        subtitle: account.handle,
        alwaysShowsSubtitle: true,
        icon: 'person.png',
        url: account.profileURL,
      },
      {
        title: 'View Repositories',
        icon: 'repo.png',
        action: 'openAccountRepositories',
        actionArgument: account.login,
        actionReturnsItems: true,
      },
      {
        title: 'View Issues',
        icon: 'issue.png',
        url: account.issuesURL,
      },
      {
        title: 'View Pull Requests',
        icon: 'pull-request.png',
        url: account.pullRequestsURL,
      },
      {
        title: 'View Gists',
        icon: 'gist.png',
        url: account.gistsURL,
      }
    ]
  }
}

function openAccountRepositories(login) {
  let account = new Account(login)

  if (LaunchBar.options.commandKey == 1) {
    LaunchBar.openURL(account.repositoriesURL)
  } else {
    let menuItems = account.repositories().map(function(repository) {
      return repository.toMenuItem()
    });

    return [
      {
        title: 'View All Repositories',
        icon: 'repos.png',
        url: account.repositoriesURL
      }
    ].concat(menuItems);
  }
}

function executeQuery(query, variables) {
  if (!Action.preferences.token) {
    LaunchBar.openURL('https://github.com/prerelease/agreement');
    LaunchBar.openURL('https://github.com/settings/tokens');
    LaunchBar.alert("It looks like this is the first time you're using this " +
      "action.\n\nPlease go to https://github.com/prerelease/agreement and " +
      "accept the agreement.\n\nOnce signed, go to " +
      "https://github.com/settings/tokens and create token with 'repo' scope " +
      "and set it by invoking this action and typing !set-token <token>");
    return
  }

  result = HTTP.post('https://api.github.com/graphql', {
    headerFields: { authorization: 'token ' + Action.preferences.token },
    body: JSON.stringify({ query: query, variables: variables })
  });

  LaunchBar.debugLog(JSON.stringify(result));

  if (result.data) {
    return JSON.parse(result.data);
  }
}
<commit_msg>Use let everywhere<commit_after>include('account.js');

// FIXME: Instead of having global state, it'd be better to maintain a cache
let repositoryMenuItems = [];

const SET_TOKEN_FORMAT    = /^!set-token (.*)$/;
const ISSUE_OR_PR_FORMAT  = /^([^\/]+\/[^\/#]+)(?:\/pull\/|\/issues\/|#)(\d+)$/;
const REPOSITORY_FORMAT   = /^([^\/]+)\/([^\/#]+)$/;
const ACCOUNT_FORMAT      = /^(\w+)$/;

function run(argument) {
  runWithString(argument);
}

function runWithString(string) {
  let match;

  // Matching:
  // set-token <token>
  if (match = string.match(SET_TOKEN_FORMAT)) {
    return setToken(match[1])
  }

  // Matching:
  // rails/rails#123
  // rails/rails/issues/123
  // rails/rails/pull/123
  else if (match = string.match(ISSUE_OR_PR_FORMAT)) {
    return openIssue(match[1], match[2]);
  }

  // Matching:
  // rails/rails
  else if (match = string.match(REPOSITORY_FORMAT)) {
    return openRepository(match[2], match[1]);
  }

  // Matching:
  // rails
  else if (match = string.match(ACCOUNT_FORMAT)) {
    let account = new Account(match[1])
    return openAccount(account);
  }

  // Matching everything else:
  // rails/rails/tree/master/Gemfile
  else {
    LaunchBar.openURL('https://github.com/' + string);
  }
}

function setToken(token) {
  Action.preferences.token = token;
  LaunchBar.displayNotification({
    title: 'GitHub access token set successfully'
  });
}

function openIssue(nameWithOwner, number) {
  LaunchBar.openURL('https://github.com/' + nameWithOwner + '/issues/' + number);
}

function openRepository(name, owner) {
  let url = 'https://github.com/' + owner + '/' + name

  if (LaunchBar.options.commandKey == 1) {
    LaunchBar.openURL(url)
  } else {
    return [
      {
        title: 'View Repository',
        subtitle: '@' + owner + '/' + name,
        alwaysShowsSubtitle: true,
        icon: 'repo.png',
        url: url
      },
      {
        title: 'View Issues',
        icon: 'issue.png',
        url: url + '/issues/'
      },
      {
        title: 'View Pull Requests',
        icon: 'pull-request.png',
        url: url + '/pulls/'
      }
    ]
  }
}

function openAccount(account) {
  if (LaunchBar.options.commandKey == 1) {
    LaunchBar.openURL(account.profileURL)
  } else {
    return [
      {
        title: 'View Profile',
        subtitle: account.handle,
        alwaysShowsSubtitle: true,
        icon: 'person.png',
        url: account.profileURL,
      },
      {
        title: 'View Repositories',
        icon: 'repo.png',
        action: 'openAccountRepositories',
        actionArgument: account.login,
        actionReturnsItems: true,
      },
      {
        title: 'View Issues',
        icon: 'issue.png',
        url: account.issuesURL,
      },
      {
        title: 'View Pull Requests',
        icon: 'pull-request.png',
        url: account.pullRequestsURL,
      },
      {
        title: 'View Gists',
        icon: 'gist.png',
        url: account.gistsURL,
      }
    ]
  }
}

function openAccountRepositories(login) {
  let account = new Account(login)

  if (LaunchBar.options.commandKey == 1) {
    LaunchBar.openURL(account.repositoriesURL)
  } else {
    let menuItems = account.repositories().map(function(repository) {
      return repository.toMenuItem()
    });

    return [
      {
        title: 'View All Repositories',
        icon: 'repos.png',
        url: account.repositoriesURL
      }
    ].concat(menuItems);
  }
}

function executeQuery(query, variables) {
  if (!Action.preferences.token) {
    LaunchBar.openURL('https://github.com/prerelease/agreement');
    LaunchBar.openURL('https://github.com/settings/tokens');
    LaunchBar.alert("It looks like this is the first time you're using this " +
      "action.\n\nPlease go to https://github.com/prerelease/agreement and " +
      "accept the agreement.\n\nOnce signed, go to " +
      "https://github.com/settings/tokens and create token with 'repo' scope " +
      "and set it by invoking this action and typing !set-token <token>");
    return
  }

  result = HTTP.post('https://api.github.com/graphql', {
    headerFields: { authorization: 'token ' + Action.preferences.token },
    body: JSON.stringify({ query: query, variables: variables })
  });

  LaunchBar.debugLog(JSON.stringify(result));

  if (result.data) {
    return JSON.parse(result.data);
  }
}
<|endoftext|>


<commit_before>var AWS = require('aws-sdk');
AWS.config.region = 'eu-central-1';

var ec2 = new AWS.EC2();

var params = {
  ImageId: 'ami-60d7350f', // Ubuntu 14.04 + Docker + MYSQL
  InstanceType: 't2.micro',
  MinCount: 1, MaxCount: 1,
  SecurityGroups: ["SSH+Mysql"],
  KeyName:"EC2-Server"
};

// Create the instance
ec2.runInstances(params, function(err, data) {
  if (err) { console.log("Could not create instance", err); return; }

  var instanceId = data.Instances[0].InstanceId;
  console.log("Created instance", instanceId);

	//Detach EBS from OLD istance
	ec2.detachVolume({VolumeId: 'vol-d178e56b'}, function(err, data) {
		if (err) console.log(err, err.stack); // an error occurred
		else{ // Attach EBS to NEW istance
			var params = {
				Device: '/dev/xvdf',
				InstanceId: instanceId,
				VolumeId: 'vol-d178e56b',
			};
			ec2.attachVolume(params, function(err, data) {
				if (err) console.log(err, err.stack); // an error occurred
				else     console.log("Success attach EBS DATA");
			});
		}
	});
});
<commit_msg>Completed creation of instance<commit_after>var AWS = require('aws-sdk');
AWS.config.region = 'eu-central-1';

var ec2 = new AWS.EC2();

// 1- Read userData file
var fs = require('fs');
var bitmap = fs.readFileSync('userdata.sh');
var userData = new Buffer(bitmap).toString('base64');

var params = {
  ImageId: 'ami-60d7350f', // Docker + MYSQL
  InstanceType: 't2.micro',
  MinCount: 1, MaxCount: 1,
  SecurityGroups: ["SSH+Mysql"],
  KeyName:"EC2-Server",
	UserData:userData
};

var dataVolumeID = "vol-d178e56b"; // The ID of the DATA EBS volume

// Create the instance
ec2.runInstances(params, function(err, data) {
  if (err) { console.log("Could not create instance", err); return; }

  var instanceId = data.Instances[0].InstanceId;
  console.log("Created instance", instanceId);

	ec2.waitFor('instanceRunning', {InstanceIds:[instanceId]}, function(err, data) {
		console.log("Instance is running.");
		// get EBS state
		ec2.describeVolumes({VolumeIds:[dataVolumeID]},function(err,data){
			var volumeState = data.Volumes[0].State
			console.log("DATA volume is in " + volumeState + " state");
			if (volumeState == "in-use")
				detachVolume(instanceId);
			else
				attachVolume(instanceId);
		});
	}); // End wait for instanceRunning

	//Update ROUTE53 entry to new server

});

function detachVolume(instanceId){
	ec2.detachVolume({
			VolumeId: dataVolumeID,
			Force: true
		}, function(err, data) {
	if (err) console.log(err, err.stack); // an error occurred
	else // Attach EBS to NEW istance
		attachVolume(instanceId);
	});
}

function attachVolume(instanceId){
	ec2.waitFor("volumeAvailable", {VolumeIds:[dataVolumeID]}, function(err,data) {
			ec2.attachVolume({
					Device: '/dev/xvdf',
					InstanceId: instanceId,
					VolumeId: dataVolumeID,
				}, function(err, data) {
				if (err) console.log(err, err.stack); // an error occurred
				else     console.log("DATA volume attached succesfully");
			});
	}); //End wait for volumeAvailable
}
<|endoftext|>


<commit_before>/*
* jQuery Mobile Framework : events
* Copyright (c) jQuery Project
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
(function($, undefined ) {

// add new event shortcuts
$.each( "touchstart touchmove touchend orientationchange tap taphold swipe swipeleft swiperight scrollstart scrollstop".split( " " ), function( i, name ) {
	$.fn[ name ] = function( fn ) {
		return fn ? this.bind( name, fn ) : this.trigger( name );
	};
	$.attrFn[ name ] = true;
});

var supportTouch = $.support.touch,
	scrollEvent = "touchmove scroll",
	touchStartEvent = supportTouch ? "touchstart" : "mousedown",
	touchStopEvent = supportTouch ? "touchend" : "mouseup",
	touchMoveEvent = supportTouch ? "touchmove" : "mousemove";

function triggerCustomEvent(obj, eventType, event)
{
	var originalType = event.type;
	event.type = eventType;
	$.event.handle.call( obj, event );
	event.type = originalType;
}

// also handles scrollstop
$.event.special.scrollstart = {
	enabled: true,

	setup: function() {
		var thisObject = this,
			$this = $( thisObject ),
			scrolling,
			timer;

		function trigger( event, state ) {
			scrolling = state;
			triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event );
		}

		// iPhone triggers scroll after a small delay; use touchmove instead
		$this.bind( scrollEvent, function( event ) {
			if ( !$.event.special.scrollstart.enabled ) {
				return;
			}

			if ( !scrolling ) {
				trigger( event, true );
			}

			clearTimeout( timer );
			timer = setTimeout(function() {
				trigger( event, false );
			}, 50 );
		});
	}
};

// also handles taphold
$.event.special.tap = {
	setup: function() {
		var thisObject = this,
			$this = $( thisObject );

		$this
			.bind("vmousedown", function( event ) {
				if ( event.which && event.which !== 1 ) {
					return false;
				}

				var touching = true,
					origTarget = event.target,
					origEvent = event.originalEvent,
					timer;

				function clearTapHandlers() {
					touching = false;
					clearTimeout(timer);
					$(this).unbind("vmouseclick", clickHandler).unbind("vmousecancel", clearTapHandlers);
				}

				function clickHandler(event) {
					clearTapHandlers();

					/* ONLY trigger a 'tap' event if the start target is
					 * the same as the stop target.
					 */
					if ( !origTarget == event.target ) {
						triggerCustomEvent( thisObject, "tap", event );
					}
				}

				$this.bind("vmousecancel", clearTapHandlers).bind("vclick", clickHandler);

				timer = setTimeout(function() {
					if ( touching ) {
						triggerCustomEvent( thisObject, "taphold", event );
					}
				}, 750 );
			});
	}
};

// also handles swipeleft, swiperight
$.event.special.swipe = {
	setup: function() {
		var thisObject = this,
			$this = $( thisObject );

		$this
			.bind( touchStartEvent, function( event ) {
				var data = event.originalEvent.touches ?
						event.originalEvent.touches[ 0 ] :
						event,
					start = {
						time: (new Date).getTime(),
						coords: [ data.pageX, data.pageY ],
						origin: $( event.target )
					},
					stop;

				function moveHandler( event ) {
					if ( !start ) {
						return;
					}

					var data = event.originalEvent.touches ?
							event.originalEvent.touches[ 0 ] :
							event;
					stop = {
							time: (new Date).getTime(),
							coords: [ data.pageX, data.pageY ]
					};

					// prevent scrolling
					if ( Math.abs( start.coords[0] - stop.coords[0] ) > 10 ) {
						event.preventDefault();
					}
				}

				$this
					.bind( touchMoveEvent, moveHandler )
					.one( touchStopEvent, function( event ) {
						$this.unbind( touchMoveEvent, moveHandler );
						if ( start && stop ) {
							if ( stop.time - start.time < 1000 &&
									Math.abs( start.coords[0] - stop.coords[0]) > 30 &&
									Math.abs( start.coords[1] - stop.coords[1]) < 75 ) {
								start.origin
								.trigger( "swipe" )

								.trigger( start.coords[0] > stop.coords[0] ? "swipeleft" : "swiperight" );
							}
						}
						start = stop = undefined;
					});
			});
	}
};

(function($){
	// "Cowboy" Ben Alman

	var win = $(window),
		special_event,
		get_orientation,
		last_orientation;

	$.event.special.orientationchange = special_event = {
		setup: function(){
			// If the event is supported natively, return false so that jQuery
			// will bind to the event using DOM methods.
			if ( $.support.orientation ) { return false; }

			// Get the current orientation to avoid initial double-triggering.
			last_orientation = get_orientation();

			// Because the orientationchange event doesn't exist, simulate the
			// event by testing window dimensions on resize.
			win.bind( "resize", handler );
		},
		teardown: function(){
			// If the event is not supported natively, return false so that
			// jQuery will unbind the event using DOM methods.
			if ( $.support.orientation ) { return false; }

			// Because the orientationchange event doesn't exist, unbind the
			// resize event handler.
			win.unbind( "resize", handler );
		},
		add: function( handleObj ) {
			// Save a reference to the bound event handler.
			var old_handler = handleObj.handler;

			handleObj.handler = function( event ) {
				// Modify event object, adding the .orientation property.
				event.orientation = get_orientation();

				// Call the originally-bound event handler and return its result.
				return old_handler.apply( this, arguments );
			};
		}
	};

	// If the event is not supported natively, this handler will be bound to
	// the window resize event to simulate the orientationchange event.
	function handler() {
		// Get the current orientation.
		var orientation = get_orientation();

		if ( orientation !== last_orientation ) {
			// The orientation has changed, so trigger the orientationchange event.
			last_orientation = orientation;
			win.trigger( "orientationchange" );
		}
	};

	// Get the current page orientation. This method is exposed publicly, should it
	// be needed, as jQuery.event.special.orientationchange.orientation()
	special_event.orientation = get_orientation = function() {
		var elem = document.documentElement;
		return elem && elem.clientWidth / elem.clientHeight < 1.1 ? "portrait" : "landscape";
	};

})(jQuery);

$.each({
	scrollstop: "scrollstart",
	taphold: "tap",
	swipeleft: "swipe",
	swiperight: "swipe"
}, function( event, sourceEvent ) {
	$.event.special[ event ] = {
		setup: function() {
			$( this ).bind( sourceEvent, $.noop );
		}
	};
});

})( jQuery );
<commit_msg>Fixed typo in my last checkin for converting tap to virtual mouse events. It was preventing tap from actually firing so things like the cancel button link in a search textfield  was being followed.<commit_after>/*
* jQuery Mobile Framework : events
* Copyright (c) jQuery Project
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
(function($, undefined ) {

// add new event shortcuts
$.each( "touchstart touchmove touchend orientationchange tap taphold swipe swipeleft swiperight scrollstart scrollstop".split( " " ), function( i, name ) {
	$.fn[ name ] = function( fn ) {
		return fn ? this.bind( name, fn ) : this.trigger( name );
	};
	$.attrFn[ name ] = true;
});

var supportTouch = $.support.touch,
	scrollEvent = "touchmove scroll",
	touchStartEvent = supportTouch ? "touchstart" : "mousedown",
	touchStopEvent = supportTouch ? "touchend" : "mouseup",
	touchMoveEvent = supportTouch ? "touchmove" : "mousemove";

function triggerCustomEvent(obj, eventType, event)
{
	var originalType = event.type;
	event.type = eventType;
	$.event.handle.call( obj, event );
	event.type = originalType;
}

// also handles scrollstop
$.event.special.scrollstart = {
	enabled: true,

	setup: function() {
		var thisObject = this,
			$this = $( thisObject ),
			scrolling,
			timer;

		function trigger( event, state ) {
			scrolling = state;
			triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event );
		}

		// iPhone triggers scroll after a small delay; use touchmove instead
		$this.bind( scrollEvent, function( event ) {
			if ( !$.event.special.scrollstart.enabled ) {
				return;
			}

			if ( !scrolling ) {
				trigger( event, true );
			}

			clearTimeout( timer );
			timer = setTimeout(function() {
				trigger( event, false );
			}, 50 );
		});
	}
};

// also handles taphold
$.event.special.tap = {
	setup: function() {
		var thisObject = this,
			$this = $( thisObject );

		$this
			.bind("vmousedown", function( event ) {
				if ( event.which && event.which !== 1 ) {
					return false;
				}

				var touching = true,
					origTarget = event.target,
					origEvent = event.originalEvent,
					timer;

				function clearTapHandlers() {
					touching = false;
					clearTimeout(timer);
					$(this).unbind("vmouseclick", clickHandler).unbind("vmousecancel", clearTapHandlers);
				}

				function clickHandler(event) {
					clearTapHandlers();

					/* ONLY trigger a 'tap' event if the start target is
					 * the same as the stop target.
					 */
					if ( origTarget == event.target ) {
						triggerCustomEvent( thisObject, "tap", event );
					}
				}

				$this.bind("vmousecancel", clearTapHandlers).bind("vclick", clickHandler);

				timer = setTimeout(function() {
					if ( touching ) {
						triggerCustomEvent( thisObject, "taphold", event );
					}
				}, 750 );
			});
	}
};

// also handles swipeleft, swiperight
$.event.special.swipe = {
	setup: function() {
		var thisObject = this,
			$this = $( thisObject );

		$this
			.bind( touchStartEvent, function( event ) {
				var data = event.originalEvent.touches ?
						event.originalEvent.touches[ 0 ] :
						event,
					start = {
						time: (new Date).getTime(),
						coords: [ data.pageX, data.pageY ],
						origin: $( event.target )
					},
					stop;

				function moveHandler( event ) {
					if ( !start ) {
						return;
					}

					var data = event.originalEvent.touches ?
							event.originalEvent.touches[ 0 ] :
							event;
					stop = {
							time: (new Date).getTime(),
							coords: [ data.pageX, data.pageY ]
					};

					// prevent scrolling
					if ( Math.abs( start.coords[0] - stop.coords[0] ) > 10 ) {
						event.preventDefault();
					}
				}

				$this
					.bind( touchMoveEvent, moveHandler )
					.one( touchStopEvent, function( event ) {
						$this.unbind( touchMoveEvent, moveHandler );
						if ( start && stop ) {
							if ( stop.time - start.time < 1000 &&
									Math.abs( start.coords[0] - stop.coords[0]) > 30 &&
									Math.abs( start.coords[1] - stop.coords[1]) < 75 ) {
								start.origin
								.trigger( "swipe" )

								.trigger( start.coords[0] > stop.coords[0] ? "swipeleft" : "swiperight" );
							}
						}
						start = stop = undefined;
					});
			});
	}
};

(function($){
	// "Cowboy" Ben Alman

	var win = $(window),
		special_event,
		get_orientation,
		last_orientation;

	$.event.special.orientationchange = special_event = {
		setup: function(){
			// If the event is supported natively, return false so that jQuery
			// will bind to the event using DOM methods.
			if ( $.support.orientation ) { return false; }

			// Get the current orientation to avoid initial double-triggering.
			last_orientation = get_orientation();

			// Because the orientationchange event doesn't exist, simulate the
			// event by testing window dimensions on resize.
			win.bind( "resize", handler );
		},
		teardown: function(){
			// If the event is not supported natively, return false so that
			// jQuery will unbind the event using DOM methods.
			if ( $.support.orientation ) { return false; }

			// Because the orientationchange event doesn't exist, unbind the
			// resize event handler.
			win.unbind( "resize", handler );
		},
		add: function( handleObj ) {
			// Save a reference to the bound event handler.
			var old_handler = handleObj.handler;

			handleObj.handler = function( event ) {
				// Modify event object, adding the .orientation property.
				event.orientation = get_orientation();

				// Call the originally-bound event handler and return its result.
				return old_handler.apply( this, arguments );
			};
		}
	};

	// If the event is not supported natively, this handler will be bound to
	// the window resize event to simulate the orientationchange event.
	function handler() {
		// Get the current orientation.
		var orientation = get_orientation();

		if ( orientation !== last_orientation ) {
			// The orientation has changed, so trigger the orientationchange event.
			last_orientation = orientation;
			win.trigger( "orientationchange" );
		}
	};

	// Get the current page orientation. This method is exposed publicly, should it
	// be needed, as jQuery.event.special.orientationchange.orientation()
	special_event.orientation = get_orientation = function() {
		var elem = document.documentElement;
		return elem && elem.clientWidth / elem.clientHeight < 1.1 ? "portrait" : "landscape";
	};

})(jQuery);

$.each({
	scrollstop: "scrollstart",
	taphold: "tap",
	swipeleft: "swipe",
	swiperight: "swipe"
}, function( event, sourceEvent ) {
	$.event.special[ event ] = {
		setup: function() {
			$( this ).bind( sourceEvent, $.noop );
		}
	};
});

})( jQuery );
<|endoftext|>