<commit_before>// @flow
import * as Constants from '../../../constants/chat2'
import * as Types from '../../../constants/types/chat2'
import * as Inbox from '..'
import * as Chat2Gen from '../../../actions/chat2-gen'
import * as TeamsGen from '../../../actions/teams-gen'
import {connect, compose, lifecycle, withStateHandlers, withProps, isMobile} from '../../../util/container'
import type {TypedState, Dispatch} from '../../../util/container'
import normalRowData from './normal'
import filteredRowData from './filtered'

const mapStateToProps = (state: TypedState, {routeState}) => {
  const filter = state.chat2.inboxFilter
  const smallTeamsExpanded = routeState.get('smallTeamsExpanded')
  const rowMetadata = filter ? filteredRowData(state) : normalRowData(state, smallTeamsExpanded)
  const _selectedConversationIDKey = Constants.getSelectedConversation(state)

  return {
    ...rowMetadata,
    _selectedConversationIDKey,
    filter,
    isLoading: !state.chat2.loadingMap.isEmpty(),
    neverLoaded: state.chat2.metaMap.isEmpty(),
  }
}

const mapDispatchToProps = (dispatch: Dispatch, {routeState, setRouteState, navigateAppend}) => ({
  _onSelect: (conversationIDKey: Types.ConversationIDKey) =>
    dispatch(Chat2Gen.createSelectConversation({conversationIDKey, reason: 'inboxFilterChanged'})),
  _onSelectNext: (
    rows: Array<Inbox.RowItem>,
    selectedConversationIDKey: ?Types.ConversationIDKey,
    direction: -1 | 1
  ) => {
    const goodRows: Array<Inbox.RowItemSmall | Inbox.RowItemBig> = rows.reduce((arr, row) => {
      if (row.type === 'small' || row.type === 'big') {
        arr.push(row)
      }
      return arr
    }, [])
    const idx = goodRows.findIndex(row => row.conversationIDKey === selectedConversationIDKey)
    if (goodRows.length) {
      const {conversationIDKey} = goodRows[(idx + direction + goodRows.length) % goodRows.length]
      dispatch(Chat2Gen.createSelectConversation({conversationIDKey, reason: 'inboxFilterArrow'}))
    }
  },
  _onHotkey: (cmd: string, focusFilter: () => void) => {
    if (cmd.endsWith('+n')) {
      dispatch(Chat2Gen.createSetPendingMode({pendingMode: 'searchingForUsers'}))
    } else {
      focusFilter()
    }
  },
  getTeams: () => dispatch(TeamsGen.createGetTeams()),
  onNewChat: () => {
    dispatch(Chat2Gen.createSetPendingMode({pendingMode: 'searchingForUsers'}))
    if (isMobile) {
      dispatch(navigateAppend(['conversation']))
    }
  },
  onSetFilter: (filter: string) => dispatch(Chat2Gen.createSetInboxFilter({filter})),
  onUntrustedInboxVisible: (conversationIDKeys: Array<Types.ConversationIDKey>) =>
    dispatch(
      Chat2Gen.createMetaNeedsUpdating({
        conversationIDKeys,
        reason: 'untrusted inbox visible',
      })
    ),
  refreshInbox: (force: boolean) => dispatch(Chat2Gen.createInboxRefresh({reason: 'componentNeverLoaded'})),
  toggleSmallTeamsExpanded: () =>
    setRouteState({
      smallTeamsExpanded: !routeState.get('smallTeamsExpanded'),
    }),
})

// This merge props is not spreading on purpose so we never have any random props that might mutate and force a re-render
const mergeProps = (stateProps, dispatchProps, ownProps) => ({
  _onHotkey: dispatchProps._onHotkey,
  filter: stateProps.filter,
  getTeams: dispatchProps.getTeams,
  isLoading: stateProps.isLoading,
  neverLoaded: stateProps.neverLoaded,
  onNewChat: dispatchProps.onNewChat,
  onSelect: (conversationIDKey: Types.ConversationIDKey) => dispatchProps._onSelect(conversationIDKey),
  onSelectDown: () => dispatchProps._onSelectNext(stateProps.rows, stateProps._selectedConversationIDKey, 1),
  onSelectUp: () => dispatchProps._onSelectNext(stateProps.rows, stateProps._selectedConversationIDKey, -1),
  onSetFilter: dispatchProps.onSetFilter,
  onUntrustedInboxVisible: dispatchProps.onUntrustedInboxVisible,
  refreshInbox: dispatchProps.refreshInbox,
  rows: stateProps.rows,
  showBuildATeam: stateProps.showBuildATeam,
  showSmallTeamsExpandDivider: stateProps.showSmallTeamsExpandDivider,
  smallIDsHidden: stateProps.smallIDsHidden,
  smallTeamsExpanded: stateProps.smallTeamsExpanded,
  toggleSmallTeamsExpanded: dispatchProps.toggleSmallTeamsExpanded,
})

export default compose(
  connect(mapStateToProps, mapDispatchToProps, mergeProps),
  withStateHandlers(
    {filterFocusCount: 0},
    {focusFilter: ({filterFocusCount}) => () => ({filterFocusCount: filterFocusCount + 1})}
  ),
  withProps(props => ({
    onHotkey: (cmd: string) => props._onHotkey(cmd, props.focusFilter),
  })),
  lifecycle({
    componentDidMount() {
      if (this.props.neverLoaded) {
        this.props.refreshInbox()
        // Get team counts for team headers in the inbox
        this.props.getTeams()
      }
    },
    componentWillReceiveProps(nextProps) {
      const loadedForTheFirstTime = this.props.rows.length === 0 && nextProps.rows.length > 0
      // See if the first 6 are small, this implies its expanded
      const smallRowsPlusOne = this.props.rows.slice(0, 6).filter(r => r.type === 'small')
      const expandedForTheFirstTime = smallRowsPlusOne.length === 5 && nextProps.rows.length > 5
      if (loadedForTheFirstTime || expandedForTheFirstTime) {
        const toUnbox = nextProps.rows.slice(0, 20).reduce((arr, row) => {
          if (row.type === 'small' || row.type === 'big') {
            arr.push(row.conversationIDKey)
          }
          return arr
        }, [])
        if (toUnbox.length) {
          nextProps.onUntrustedInboxVisible(toUnbox)
        }
      }

      // keep first item selected if filter changes
      if (!isMobile) {
        if (nextProps.filter && this.props.filter !== nextProps.filter && nextProps.rows.length > 0) {
          const row = nextProps.rows[0]
          if (row.conversationIDKey) {
            this.props.onSelect(row.conversationIDKey)
          }
        }
      }
    },
  })
)(Inbox.default)
<commit_msg>add onSelectDebounced (#11277)<commit_after>// @flow
import * as Constants from '../../../constants/chat2'
import * as Types from '../../../constants/types/chat2'
import * as Inbox from '..'
import * as Chat2Gen from '../../../actions/chat2-gen'
import * as TeamsGen from '../../../actions/teams-gen'
import debounce from 'lodash/debounce'
import {connect, compose, lifecycle, withStateHandlers, withProps, isMobile} from '../../../util/container'
import type {TypedState, Dispatch} from '../../../util/container'
import normalRowData from './normal'
import filteredRowData from './filtered'

const mapStateToProps = (state: TypedState, {routeState}) => {
  const filter = state.chat2.inboxFilter
  const smallTeamsExpanded = routeState.get('smallTeamsExpanded')
  const rowMetadata = filter ? filteredRowData(state) : normalRowData(state, smallTeamsExpanded)
  const _selectedConversationIDKey = Constants.getSelectedConversation(state)

  return {
    ...rowMetadata,
    _selectedConversationIDKey,
    filter,
    isLoading: !state.chat2.loadingMap.isEmpty(),
    neverLoaded: state.chat2.metaMap.isEmpty(),
  }
}

const mapDispatchToProps = (dispatch: Dispatch, {routeState, setRouteState, navigateAppend}) => ({
  _onSelect: (conversationIDKey: Types.ConversationIDKey) =>
    dispatch(Chat2Gen.createSelectConversation({conversationIDKey, reason: 'inboxFilterChanged'})),
  _onSelectNext: (
    rows: Array<Inbox.RowItem>,
    selectedConversationIDKey: ?Types.ConversationIDKey,
    direction: -1 | 1
  ) => {
    const goodRows: Array<Inbox.RowItemSmall | Inbox.RowItemBig> = rows.reduce((arr, row) => {
      if (row.type === 'small' || row.type === 'big') {
        arr.push(row)
      }
      return arr
    }, [])
    const idx = goodRows.findIndex(row => row.conversationIDKey === selectedConversationIDKey)
    if (goodRows.length) {
      const {conversationIDKey} = goodRows[(idx + direction + goodRows.length) % goodRows.length]
      dispatch(Chat2Gen.createSelectConversation({conversationIDKey, reason: 'inboxFilterArrow'}))
    }
  },
  _onHotkey: (cmd: string, focusFilter: () => void) => {
    if (cmd.endsWith('+n')) {
      dispatch(Chat2Gen.createSetPendingMode({pendingMode: 'searchingForUsers'}))
    } else {
      focusFilter()
    }
  },
  getTeams: () => dispatch(TeamsGen.createGetTeams()),
  onNewChat: () => {
    dispatch(Chat2Gen.createSetPendingMode({pendingMode: 'searchingForUsers'}))
    if (isMobile) {
      dispatch(navigateAppend(['conversation']))
    }
  },
  onSetFilter: (filter: string) => dispatch(Chat2Gen.createSetInboxFilter({filter})),
  onUntrustedInboxVisible: (conversationIDKeys: Array<Types.ConversationIDKey>) =>
    dispatch(
      Chat2Gen.createMetaNeedsUpdating({
        conversationIDKeys,
        reason: 'untrusted inbox visible',
      })
    ),
  refreshInbox: (force: boolean) => dispatch(Chat2Gen.createInboxRefresh({reason: 'componentNeverLoaded'})),
  toggleSmallTeamsExpanded: () =>
    setRouteState({
      smallTeamsExpanded: !routeState.get('smallTeamsExpanded'),
    }),
})

// This merge props is not spreading on purpose so we never have any random props that might mutate and force a re-render
const mergeProps = (stateProps, dispatchProps, ownProps) => ({
  _onHotkey: dispatchProps._onHotkey,
  filter: stateProps.filter,
  getTeams: dispatchProps.getTeams,
  isLoading: stateProps.isLoading,
  neverLoaded: stateProps.neverLoaded,
  onNewChat: dispatchProps.onNewChat,
  onSelect: (conversationIDKey: Types.ConversationIDKey) => dispatchProps._onSelect(conversationIDKey),
  onSelectDebounced: debounce(
    (conversationIDKey: Types.ConversationIDKey) => dispatchProps._onSelect(conversationIDKey),
    400,
    {maxWait: 600}
  ),
  onSelectDown: () => dispatchProps._onSelectNext(stateProps.rows, stateProps._selectedConversationIDKey, 1),
  onSelectUp: () => dispatchProps._onSelectNext(stateProps.rows, stateProps._selectedConversationIDKey, -1),
  onSetFilter: dispatchProps.onSetFilter,
  onUntrustedInboxVisible: dispatchProps.onUntrustedInboxVisible,
  refreshInbox: dispatchProps.refreshInbox,
  rows: stateProps.rows,
  showBuildATeam: stateProps.showBuildATeam,
  showSmallTeamsExpandDivider: stateProps.showSmallTeamsExpandDivider,
  smallIDsHidden: stateProps.smallIDsHidden,
  smallTeamsExpanded: stateProps.smallTeamsExpanded,
  toggleSmallTeamsExpanded: dispatchProps.toggleSmallTeamsExpanded,
})

export default compose(
  connect(mapStateToProps, mapDispatchToProps, mergeProps),
  withStateHandlers(
    {filterFocusCount: 0},
    {focusFilter: ({filterFocusCount}) => () => ({filterFocusCount: filterFocusCount + 1})}
  ),
  withProps(props => ({
    onHotkey: (cmd: string) => props._onHotkey(cmd, props.focusFilter),
  })),
  lifecycle({
    componentDidMount() {
      if (this.props.neverLoaded) {
        this.props.refreshInbox()
        // Get team counts for team headers in the inbox
        this.props.getTeams()
      }
    },
    componentWillReceiveProps(nextProps) {
      const loadedForTheFirstTime = this.props.rows.length === 0 && nextProps.rows.length > 0
      // See if the first 6 are small, this implies its expanded
      const smallRowsPlusOne = this.props.rows.slice(0, 6).filter(r => r.type === 'small')
      const expandedForTheFirstTime = smallRowsPlusOne.length === 5 && nextProps.rows.length > 5
      if (loadedForTheFirstTime || expandedForTheFirstTime) {
        const toUnbox = nextProps.rows.slice(0, 20).reduce((arr, row) => {
          if (row.type === 'small' || row.type === 'big') {
            arr.push(row.conversationIDKey)
          }
          return arr
        }, [])
        if (toUnbox.length) {
          nextProps.onUntrustedInboxVisible(toUnbox)
        }
      }

      // keep first item selected if filter changes
      if (!isMobile) {
        if (nextProps.filter && this.props.filter !== nextProps.filter && nextProps.rows.length > 0) {
          const row = nextProps.rows[0]
          if (row.conversationIDKey) {
            this.props.onSelectDebounced(row.conversationIDKey)
          }
        }
      }
    },
  })
)(Inbox.default)
<|endoftext|>


<commit_before>var Player = require('./player.js');
var Settings = require('./settings.js');
var GameStatus = require('./gameStatus.js');

/**
 * BattleshipGame constructor
 * @param {type} id Game ID
 * @param {type} idPlayer1 Socket ID of player 1
 * @param {type} idPlayer2 Socket ID of player 2
 */
function BattleshipGame(id, idPlayer1, idPlayer2) {
  this.id = id;
  this.currentPlayer = 0;
  this.winningPlayer = null;
  this.gameStatus = GameStatus.inProgress;

  this.players = [new Player(idPlayer1), new Player(idPlayer2)];
}

/**
 * Get socket ID of player
 * @param {type} player
 * @returns {undefined}
 */
BattleshipGame.prototype.getPlayerId = function(player) {
  return this.players[player].id;
};

/**
 * Get socket ID of winning player
 * @returns {BattleshipGame.prototype@arr;players@pro;id}
 */
BattleshipGame.prototype.getWinnerId = function() {
  if(this.winningPlayer === null) {
    return null;
  }
  return this.players[this.winningPlayer].id;
};

/**
 * Get socket ID of losing player
 * @returns {BattleshipGame.prototype@arr;players@pro;id}
 */
BattleshipGame.prototype.getLoserId = function() {
  if(this.winningPlayer === null) {
    return null;
  }
  var loser = this.winningPlayer === 0 ? 1 : 0;
  return this.players[loser].id;
};

/**
 * Switch turns
 */
BattleshipGame.prototype.switchPlayer = function() {
  this.currentPlayer = this.currentPlayer === 0 ? 1 : 0;
};

/**
 * Abort game
 * @param {Number} player Player who made the request
 */
BattleshipGame.prototype.abortGame = function(player) {
  // give win to opponent
  this.gameStatus = GameStatus.gameOver;
  this.winningPlayer = player === 0 ? 1 : 0;
}

/**
 * Fire shot for current player
 * @param {Object} position with x and y
 * @returns {boolean} True if shot was valid
 */
BattleshipGame.prototype.shoot = function(position) {
  var opponent = this.currentPlayer === 0 ? 1 : 0,
      gridIndex = position.y * Settings.gridCols + position.x;

  if(this.players[opponent].shots[gridIndex] === 0 && this.gameStatus === GameStatus.inProgress) {
    // Square has not been shot at yet.
    if(!this.players[opponent].shoot(gridIndex)) {
      // Miss
      this.switchPlayer();
    }

    // Check if game over
    if(this.players[opponent].getShipsLeft() <= 0) {
      this.gameStatus = GameStatus.gameOver;
      this.winningPlayer = opponent === 0 ? 1 : 0;
    }

    return true;
  }

  return false;
};

/**
 * Get game state update (for one grid).
 * @param {Number} player Player who is getting this update
 * @param {Number} gridOwner Player whose grid state to update
 * @returns {BattleshipGame.prototype.getGameState.battleshipGameAnonym$0}
 */
BattleshipGame.prototype.getGameState = function(player, gridOwner) {
  return {
    turn: this.currentPlayer === player,                 // is it this player's turn?
    gridIndex: player === gridOwner ? 0 : 1,             // which client grid to update (0 = own, 1 = opponent)
    grid: this.getGrid(gridOwner, player !== gridOwner)  // hide unsunk ships if this is not own grid
  };
};

/**
 * Get grid with ships for a player.
 * @param {type} player Which player's grid to get
 * @param {type} hideShips Hide unsunk ships
 * @returns {BattleshipGame.prototype.getGridState.battleshipGameAnonym$0}
 */
BattleshipGame.prototype.getGrid = function(player, hideShips) {
  return {
    shots: this.players[player].shots,
    ships: hideShips ? this.players[player].getSunkShips() : this.players[player].ships
  };
};

module.exports = BattleshipGame;
<commit_msg>starting player changed to random<commit_after>var Player = require('./player.js');
var Settings = require('./settings.js');
var GameStatus = require('./gameStatus.js');

/**
 * BattleshipGame constructor
 * @param {type} id Game ID
 * @param {type} idPlayer1 Socket ID of player 1
 * @param {type} idPlayer2 Socket ID of player 2
 */
function BattleshipGame(id, idPlayer1, idPlayer2) {
  this.id = id;
  this.currentPlayer = Math.floor(Math.random() * 2);
  this.winningPlayer = null;
  this.gameStatus = GameStatus.inProgress;

  this.players = [new Player(idPlayer1), new Player(idPlayer2)];
}

/**
 * Get socket ID of player
 * @param {type} player
 * @returns {undefined}
 */
BattleshipGame.prototype.getPlayerId = function(player) {
  return this.players[player].id;
};

/**
 * Get socket ID of winning player
 * @returns {BattleshipGame.prototype@arr;players@pro;id}
 */
BattleshipGame.prototype.getWinnerId = function() {
  if(this.winningPlayer === null) {
    return null;
  }
  return this.players[this.winningPlayer].id;
};

/**
 * Get socket ID of losing player
 * @returns {BattleshipGame.prototype@arr;players@pro;id}
 */
BattleshipGame.prototype.getLoserId = function() {
  if(this.winningPlayer === null) {
    return null;
  }
  var loser = this.winningPlayer === 0 ? 1 : 0;
  return this.players[loser].id;
};

/**
 * Switch turns
 */
BattleshipGame.prototype.switchPlayer = function() {
  this.currentPlayer = this.currentPlayer === 0 ? 1 : 0;
};

/**
 * Abort game
 * @param {Number} player Player who made the request
 */
BattleshipGame.prototype.abortGame = function(player) {
  // give win to opponent
  this.gameStatus = GameStatus.gameOver;
  this.winningPlayer = player === 0 ? 1 : 0;
}

/**
 * Fire shot for current player
 * @param {Object} position with x and y
 * @returns {boolean} True if shot was valid
 */
BattleshipGame.prototype.shoot = function(position) {
  var opponent = this.currentPlayer === 0 ? 1 : 0,
      gridIndex = position.y * Settings.gridCols + position.x;

  if(this.players[opponent].shots[gridIndex] === 0 && this.gameStatus === GameStatus.inProgress) {
    // Square has not been shot at yet.
    if(!this.players[opponent].shoot(gridIndex)) {
      // Miss
      this.switchPlayer();
    }

    // Check if game over
    if(this.players[opponent].getShipsLeft() <= 0) {
      this.gameStatus = GameStatus.gameOver;
      this.winningPlayer = opponent === 0 ? 1 : 0;
    }

    return true;
  }

  return false;
};

/**
 * Get game state update (for one grid).
 * @param {Number} player Player who is getting this update
 * @param {Number} gridOwner Player whose grid state to update
 * @returns {BattleshipGame.prototype.getGameState.battleshipGameAnonym$0}
 */
BattleshipGame.prototype.getGameState = function(player, gridOwner) {
  return {
    turn: this.currentPlayer === player,                 // is it this player's turn?
    gridIndex: player === gridOwner ? 0 : 1,             // which client grid to update (0 = own, 1 = opponent)
    grid: this.getGrid(gridOwner, player !== gridOwner)  // hide unsunk ships if this is not own grid
  };
};

/**
 * Get grid with ships for a player.
 * @param {type} player Which player's grid to get
 * @param {type} hideShips Hide unsunk ships
 * @returns {BattleshipGame.prototype.getGridState.battleshipGameAnonym$0}
 */
BattleshipGame.prototype.getGrid = function(player, hideShips) {
  return {
    shots: this.players[player].shots,
    ships: hideShips ? this.players[player].getSunkShips() : this.players[player].ships
  };
};

module.exports = BattleshipGame;
<|endoftext|>


<commit_before>/* @flow */
// Styles from our designers

export const globalColors = {
  // Keybase Brand Colors
  blue: '#33a0ff',
  blue2: '#66b8ff',
  blue3: '#a8d7ff',
  blue4: '#e6f3ff',

  orange: '#ff6f21',

  yellow: '#fff75a',

  darkBlue: '#195080',
  darkBlue2: '#2470b3',
  darkBlue3: '#001b33',

  green: '#3dcc8e',
  green2: '#36b37c',

  red: '#ff4d61',

  yellowGreen: '#b3db39',
  yellowGreen2: '#89a82c',

  lightGrey: '#f6f6f6',
  lightGrey2: '#ebebeb',
  lightGrey3: '#e0e0e0',

  white: '#ffffff',
  white90: 'rgba(255, 255, 255, 0.90)',
  white75: 'rgba(255, 255, 255, 0.75)',
  white40: 'rgba(255, 255, 255, 0.40)',

  black: '#000000',
  black75: 'rgba(0, 0, 0, 0.75)',
  black60: 'rgba(0, 0, 0, 0.60)',
  black40: 'rgba(0, 0, 0, 0.40)',
  black20: 'rgba(0, 0, 0, 0.20)',
  black10: 'rgba(0, 0, 0, 0.10)',

  brown60: 'rgba(71, 31, 17, 0.6)'
}

export const globalResizing = {
  // 600px instead of 580px, since the top chrome counts too.
  login: {width: 700, height: 605},
  normal: {width: 900, height: 900}
}

const fontCommon = {
  WebkitFontSmoothing: 'antialiased',
  textRendering: 'optimizeLegibility',
  letterSpacing: '0.3px'
}

const font = {
  fontRegular: {
    ...fontCommon,
    fontFamily: 'Lato',
    fontWeight: 400
  },
  fontSemibold: {
    ...fontCommon,
    fontFamily: 'Lato',
    fontWeight: 600
  },
  fontBold: {
    ...fontCommon,
    fontFamily: 'Lato',
    fontWeight: 700
  },
  italic: {
    fontStyle: 'italic'
  },
  fontTerminal: {
    ...fontCommon,
    fontFamily: 'Source Code Pro'
  },
  fontTerminalSemibold: {
    ...fontCommon,
    fontFamily: 'Source Code Pro',
    fontWeight: 600
  }
}

const flexBoxCommon = {
  display: 'flex'
}

const util = {
  flexBoxColumn: {
    ...flexBoxCommon,
    flexDirection: 'column'
  },
  flexBoxRow: {
    ...flexBoxCommon,
    flexDirection: 'row'
  },
  flexBoxCenter: {
    ...flexBoxCommon,
    justifyContent: 'center',
    alignItems: 'center'
  },
  noSelect: {
    WebkitUserSelect: 'none'
  },
  windowDragging: { // allow frameless window dragging
    WebkitAppRegion: 'drag'
  },
  windowDraggingClickable: { // allow things in frameless regions to be clicked and not dragged
    WebkitAppRegion: 'no-drag'
  },
  rounded: {
    borderRadius: 3
  },
  windowBorder: {
    border: `solid ${globalColors.lightGrey3}`,
    borderWidth: 1
  },
  clickable: {
    cursor: 'pointer'
  },
  topMost: {
    zIndex: 9999
  }
}

export const globalStyles = {
  ...font,
  ...util
}

export function transition (...properties: Array<string>) : Object {
  return {
    transition: properties.map(p => `${p} 0.3s ease-in`).join(', ')
  }
}

export function transitionColor () : Object {
  return {
    transition: 'background 0.2s linear'
  }
}
<commit_msg>Back to 580 for Mac<commit_after>/* @flow */
// Styles from our designers

export const globalColors = {
  // Keybase Brand Colors
  blue: '#33a0ff',
  blue2: '#66b8ff',
  blue3: '#a8d7ff',
  blue4: '#e6f3ff',

  orange: '#ff6f21',

  yellow: '#fff75a',

  darkBlue: '#195080',
  darkBlue2: '#2470b3',
  darkBlue3: '#001b33',

  green: '#3dcc8e',
  green2: '#36b37c',

  red: '#ff4d61',

  yellowGreen: '#b3db39',
  yellowGreen2: '#89a82c',

  lightGrey: '#f6f6f6',
  lightGrey2: '#ebebeb',
  lightGrey3: '#e0e0e0',

  white: '#ffffff',
  white90: 'rgba(255, 255, 255, 0.90)',
  white75: 'rgba(255, 255, 255, 0.75)',
  white40: 'rgba(255, 255, 255, 0.40)',

  black: '#000000',
  black75: 'rgba(0, 0, 0, 0.75)',
  black60: 'rgba(0, 0, 0, 0.60)',
  black40: 'rgba(0, 0, 0, 0.40)',
  black20: 'rgba(0, 0, 0, 0.20)',
  black10: 'rgba(0, 0, 0, 0.10)',

  brown60: 'rgba(71, 31, 17, 0.6)'
}

export const globalResizing = {
  login: {width: 700, height: 580},
  normal: {width: 900, height: 900}
}

const fontCommon = {
  WebkitFontSmoothing: 'antialiased',
  textRendering: 'optimizeLegibility',
  letterSpacing: '0.3px'
}

const font = {
  fontRegular: {
    ...fontCommon,
    fontFamily: 'Lato',
    fontWeight: 400
  },
  fontSemibold: {
    ...fontCommon,
    fontFamily: 'Lato',
    fontWeight: 600
  },
  fontBold: {
    ...fontCommon,
    fontFamily: 'Lato',
    fontWeight: 700
  },
  italic: {
    fontStyle: 'italic'
  },
  fontTerminal: {
    ...fontCommon,
    fontFamily: 'Source Code Pro'
  },
  fontTerminalSemibold: {
    ...fontCommon,
    fontFamily: 'Source Code Pro',
    fontWeight: 600
  }
}

const flexBoxCommon = {
  display: 'flex'
}

const util = {
  flexBoxColumn: {
    ...flexBoxCommon,
    flexDirection: 'column'
  },
  flexBoxRow: {
    ...flexBoxCommon,
    flexDirection: 'row'
  },
  flexBoxCenter: {
    ...flexBoxCommon,
    justifyContent: 'center',
    alignItems: 'center'
  },
  noSelect: {
    WebkitUserSelect: 'none'
  },
  windowDragging: { // allow frameless window dragging
    WebkitAppRegion: 'drag'
  },
  windowDraggingClickable: { // allow things in frameless regions to be clicked and not dragged
    WebkitAppRegion: 'no-drag'
  },
  rounded: {
    borderRadius: 3
  },
  windowBorder: {
    border: `solid ${globalColors.lightGrey3}`,
    borderWidth: 1
  },
  clickable: {
    cursor: 'pointer'
  },
  topMost: {
    zIndex: 9999
  }
}

export const globalStyles = {
  ...font,
  ...util
}

export function transition (...properties: Array<string>) : Object {
  return {
    transition: properties.map(p => `${p} 0.3s ease-in`).join(', ')
  }
}

export function transitionColor () : Object {
  return {
    transition: 'background 0.2s linear'
  }
}
<|endoftext|>


<commit_before>// DO NOT EDIT THIS FILE
// This file is automatically generated from the webgme-setup-tool.
'use strict';

var config = require('webgme/config/config.default'),
    validateConfig = require('webgme/config/validator');

// The paths can be loaded from the webgme-setup.json

config.visualization.panelPaths.push('src/visualizers/panels');

// Visualizer descriptors
config.visualization.visualizerDescriptors.push('./src/visualizers/Visualizers.json');
// Add requirejs paths
config.requirejsPaths = {
  'panels': './src/visualizers/panels',
  'widgets': './src/visualizers/widgets'
};

config.mongo.uri = 'mongodb://127.0.0.1:27017/webgme_codeeditor';
validateConfig(config);
module.exports = config;
<commit_msg>added authentication to test server.<commit_after>// DO NOT EDIT THIS FILE
// This file is automatically generated from the webgme-setup-tool.
'use strict';

var config = require('webgme/config/config.default'),
    validateConfig = require('webgme/config/validator');

// Authentication
config.authentication.enable = true;
config.authentication.allowGuests = true;

// The paths can be loaded from the webgme-setup.json

config.visualization.panelPaths.push('src/visualizers/panels');

// Visualizer descriptors
config.visualization.visualizerDescriptors.push('./src/visualizers/Visualizers.json');
// Add requirejs paths
config.requirejsPaths = {
  'panels': './src/visualizers/panels',
  'widgets': './src/visualizers/widgets'
};

config.mongo.uri = 'mongodb://127.0.0.1:27017/webgme_codeeditor';
validateConfig(config);
module.exports = config;
<|endoftext|>


<commit_before>const {app, BrowserWindow, ipcMain} = require('electron');
const url = require('url');
const isDebug = process.env.NODE_ENV === 'development'

if (isDebug) {
  require('electron-debug')({showDevTools: true});
}

const path = require('path');
const jayson = require('jayson');
const semver = require('semver');
const https = require('https');
// tree-kill has better cross-platform handling of
// killing a process.  child-process.kill was unreliable
const kill = require('tree-kill');
const child_process = require('child_process');
const assert = require('assert');
const {version: localVersion} = require(app.getAppPath() + '/package.json');

const VERSION_CHECK_INTERVAL = 30 * 60 * 1000;
const LATEST_RELEASE_API_URL = 'https://api.github.com/repos/lbryio/lbry-app/releases/latest';

let client = jayson.client.http('http://localhost:5279/lbryapi');
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win;
// Also keep the daemon subprocess alive
let daemonSubprocess;

// This is set to true right before we try to shut the daemon subprocess --
// if it dies when we didn't ask it to shut down, we want to alert the user.
let daemonStopRequested = false;

// When a quit is attempted, we cancel the quit, do some preparations, then
// this is set to true and app.quit() is called again to quit for real.
let readyToQuit = false;

// If we receive a URI to open from an external app but there's no window to
// send it to, it's cached in this variable.
let openUri = null;

function denormalizeUri(uri) {
  // Windows normalizes URIs when they're passed in from other apps. This tries
  // to restore the original URI that was typed.
  //   - If the URI has no path, Windows adds a trailing slash. LBRY URIs
  //     can't have a slash with no path, so we just strip it off.
  //   - In a URI with a claim ID, like lbry://channel#claimid, Windows
  //     interprets the hash mark as an anchor and converts it to
  //     lbry://channel/#claimid. We remove the slash here as well.

  if (process.platform == 'win32') {
    return uri.replace(/\/$/, '').replace('/#', '#');
  } else {
    return uri;
  }
}

function checkForNewVersion(callback) {
  function formatRc(ver) {
    // Adds dash if needed to make RC suffix semver friendly
    return ver.replace(/([^-])rc/, '$1-rc');
  }

  let result = '';
  const opts = {
    headers: {
      'User-Agent': `LBRY/${localVersion}`,
    }
  };

  const req = https.get(Object.assign(opts, url.parse(LATEST_RELEASE_API_URL)), (res) => {
    res.on('data', (data) => {
      result += data;
    });
    res.on('end', () => {
      const tagName = JSON.parse(result).tag_name;
      const [_, remoteVersion] = tagName.match(/^v([\d.]+(?:-?rc\d+)?)$/);
      if (!remoteVersion) {
        if (win) {
          win.webContents.send('version-info-received', null);
        }
      } else {
        const upgradeAvailable = semver.gt(formatRc(remoteVersion), formatRc(localVersion));
        if (win) {
          win.webContents.send('version-info-received', {remoteVersion, localVersion, upgradeAvailable});
        }
      }
    })
  });

  req.on('error', (err) => {
    console.log('Failed to get current version from GitHub. Error:', err);
    if (win) {
      win.webContents.send('version-info-received', null);
    }
  });
}

ipcMain.on('version-info-requested', checkForNewVersion);

/*
 * Replacement for Electron's shell.openItem. The Electron version doesn't
 * reliably work from the main process, and we need to be able to run it
 * when no windows are open.
 */
function openItem(fullPath) {
    const subprocOptions = {
      detached: true,
      stdio: 'ignore',
    };

    let child;
    if (process.platform == 'darwin') {
      child = child_process.spawn('open', [fullPath], subprocOptions);
    } else if (process.platform == 'linux') {
      child = child_process.spawn('xdg-open', [fullPath], subprocOptions);
    } else if (process.platform == 'win32') {
      child = child_process.spawn(fullPath, [], subprocOptions);
    }

    // Causes child process reference to be garbage collected, allowing main process to exit
    child.unref();
}

function getPidsForProcessName(name) {
  if (process.platform == 'win32') {
    const tasklistOut = child_process.execSync(`tasklist /fi "Imagename eq ${name}.exe" /nh`, {encoding: 'utf8'});
    if (tasklistOut.startsWith('INFO')) {
      return [];
    } else {
      return tasklistOut.match(/[^\r\n]+/g).map((line) => line.split(/\s+/)[1]); // Second column of every non-empty line
    }
  } else {
    const pgrepOut = child_process.spawnSync('pgrep', ['-x', name], {encoding: 'utf8'}).stdout;
    return pgrepOut.match(/\d+/g);
  }
}

function createWindow () {
  win = new BrowserWindow({backgroundColor: '#155B4A', minWidth: 800, minHeight: 600 }) //$color-primary

  win.maximize()
  if (isDebug) {
    win.webContents.openDevTools();
  }
  win.loadURL(`file://${__dirname}/dist/index.html`)
  if (openUri) { // We stored and received a URI that an external app requested before we had a window object
    win.webContents.on('did-finish-load', () => {
      win.webContents.send('open-uri-requested', openUri);
    });
  }

  win.on('closed', () => {
    win = null
  })
};

function handleDaemonSubprocessExited() {
  console.log('The daemon has exited.');
  daemonSubprocess = null;
  if (!daemonStopRequested) {
    // We didn't request to stop the daemon, so display a
    // warning and schedule a quit.
    //
    // TODO: maybe it would be better to restart the daemon?
    if (win) {
      console.log('Did not request daemon stop, so quitting in 5 seconds.');
      win.loadURL(`file://${__dirname}/dist/warning.html`);
      setTimeout(quitNow, 5000);
    } else {
      console.log('Did not request daemon stop, so quitting.');
      quitNow();
    }
  }
}

function launchDaemon() {
  assert(!daemonSubprocess, 'Tried to launch daemon twice');

  if (process.env.LBRY_DAEMON) {
    executable = process.env.LBRY_DAEMON;
  } else {
    executable = path.join(__dirname, 'dist', 'lbrynet-daemon');
  }
  console.log('Launching daemon:', executable)
  daemonSubprocess = child_process.spawn(executable)
  // Need to handle the data event instead of attaching to
  // process.stdout because the latter doesn't work. I believe on
  // windows it buffers stdout and we don't get any meaningful output
  daemonSubprocess.stdout.on('data', (buf) => {console.log(String(buf).trim());});
  daemonSubprocess.stderr.on('data', (buf) => {console.log(String(buf).trim());});
  daemonSubprocess.on('exit', handleDaemonSubprocessExited);
}

/*
 * Quits without any preparation. When a quit is requested (either through the
 * interface or through app.quit()), we abort the quit, try to shut down the daemon,
 * and then call this to quit for real.
 */
function quitNow() {
  readyToQuit = true;
  app.quit();
}

if (process.platform != 'linux') {
  // On Linux, this is always returning true due to an Electron bug,
  // so for now we just don't support single-instance apps on Linux.
  const isSecondaryInstance = app.makeSingleInstance((argv) => {
    if (win) {
      if (win.isMinimized()) {
        win.restore();
      }
      win.focus();

      if (argv.length >= 2) {
        win.webContents.send('open-uri-requested', denormalizeUri(argv[1]));
      }
    } else if (argv.length >= 2) {
      openUri = denormalizeUri(argv[1]);
    }
  });

  if (isSecondaryInstance) { // We're not in the original process, so quit
    quitNow();
    return;
  }
}

app.on('ready', function(){
  launchDaemonIfNotRunning();
  createWindow();
});

function launchDaemonIfNotRunning() {
  // Check if the daemon is already running. If we get
  // an error its because its not running
  console.log('Checking for lbrynet daemon');
  client.request(
    'status', [],
    function (err, res) {
      if (err) {
        console.log('lbrynet daemon needs to be launched')
        launchDaemon();
      } else {
        console.log('lbrynet daemon is already running')
      }
    }
  );
}

/*
 * Last resort for killing unresponsive daemon instances.
 * Looks for any processes called "lbrynet-daemon" and
 * tries to force kill them.
 */
function forceKillAllDaemonsAndQuit() {
  console.log('Attempting to force kill any running lbrynet-daemon instances...');

  const daemonPids = getPidsForProcessName('lbrynet-daemon');
  if (!daemonPids) {
    console.log('No lbrynet-daemon found running.');
    quitNow();
  } else {
    console.log(`Found ${daemonPids.length} running daemon instances. Attempting to force kill...`);

    for (const pid of daemonPids) {
      let daemonKillAttemptsComplete = 0;
      kill(pid, 'SIGKILL', (err) => {
        daemonKillAttemptsComplete++;
        if (err) {
          console.log(`Failed to force kill daemon task with pid ${pid}. Error message: ${err.message}`);
        } else {
          console.log(`Force killed daemon task with pid ${pid}.`);
        }
        if (daemonKillAttemptsComplete >= daemonPids.length - 1) {
          quitNow();
        }
      });
    }
  }
}

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('before-quit', (event) => {
  if (!readyToQuit) {
    // We need to shutdown the daemon before we're ready to actually quit. This
    // event will be triggered re-entrantly once preparation is done.
    event.preventDefault();
    shutdownDaemonAndQuit();
  } else {
    console.log('Quitting.')
  }
});

app.on('activate', () => {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (win === null) {
    createWindow()
  }
});

// When a quit is attempted, this is called. It attempts to shutdown the daemon,
// then calls quitNow() to quit for real.
function shutdownDaemonAndQuit(evenIfNotStartedByApp = false) {
  function doShutdown() {
    console.log('Shutting down daemon');
    daemonStopRequested = true;
    client.request('daemon_stop', [], (err, res) => {
      if (err) {
        console.log(`received error when stopping lbrynet-daemon. Error message: ${err.message}\n`);
        console.log('You will need to manually kill the daemon.');
      } else {
        console.log('Successfully stopped daemon via RPC call.')
        quitNow();
      }
    });
  }

  if (daemonSubprocess) {
    doShutdown();
  } else if (!evenIfNotStartedByApp) {
    console.log('Not killing lbrynet-daemon because app did not start it');
    quitNow();
  } else {
    doShutdown();
  }

  // Is it safe to start the installer before the daemon finishes running?
  // If not, we should wait until the daemon is closed before we start the install.
}

function upgrade(event, installerPath) {
  app.on('quit', () => {
    console.log('Launching upgrade installer at', installerPath);
    // This gets triggered called after *all* other quit-related events, so
    // we'll only get here if we're fully prepared and quitting for real.
    openItem(installerPath);
  });

  if (win) {
    win.loadURL(`file://${__dirname}/dist/upgrade.html`);
  }

  shutdownDaemonAndQuit(true);
  // wait for daemon to shut down before upgrading
  // what to do if no shutdown in a long time?
  console.log('Update downloaded to', installerPath);
  console.log('The app will close, and you will be prompted to install the latest version of LBRY.');
  console.log('After the install is complete, please reopen the app.');
}

ipcMain.on('upgrade', upgrade);

app.setAsDefaultProtocolClient('lbry');

if (process.platform == 'darwin') {
  app.on('open-url', (event, uri) => {
    if (!win) {
      // Window not created yet, so store up requested URI for when it is
      openUri = uri;
    } else {
      win.webContents.send('open-uri-requested', uri);
    }
  });
} else if (process.argv.length >= 2) {
  if (!win) {
    openUri = denormalizeUri(process.argv[1]);
  } else {
    win.webContents.send('open-uri-requested', denormalizeUri(process.argv[1]));
  }
}
<commit_msg>On Windows, open installer using shell (allows elevation)<commit_after>const {app, BrowserWindow, ipcMain} = require('electron');
const url = require('url');
const isDebug = process.env.NODE_ENV === 'development'

if (isDebug) {
  require('electron-debug')({showDevTools: true});
}

const path = require('path');
const jayson = require('jayson');
const semver = require('semver');
const https = require('https');
// tree-kill has better cross-platform handling of
// killing a process.  child-process.kill was unreliable
const kill = require('tree-kill');
const child_process = require('child_process');
const assert = require('assert');
const {version: localVersion} = require(app.getAppPath() + '/package.json');

const VERSION_CHECK_INTERVAL = 30 * 60 * 1000;
const LATEST_RELEASE_API_URL = 'https://api.github.com/repos/lbryio/lbry-app/releases/latest';

let client = jayson.client.http('http://localhost:5279/lbryapi');
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win;
// Also keep the daemon subprocess alive
let daemonSubprocess;

// This is set to true right before we try to shut the daemon subprocess --
// if it dies when we didn't ask it to shut down, we want to alert the user.
let daemonStopRequested = false;

// When a quit is attempted, we cancel the quit, do some preparations, then
// this is set to true and app.quit() is called again to quit for real.
let readyToQuit = false;

// If we receive a URI to open from an external app but there's no window to
// send it to, it's cached in this variable.
let openUri = null;

function denormalizeUri(uri) {
  // Windows normalizes URIs when they're passed in from other apps. This tries
  // to restore the original URI that was typed.
  //   - If the URI has no path, Windows adds a trailing slash. LBRY URIs
  //     can't have a slash with no path, so we just strip it off.
  //   - In a URI with a claim ID, like lbry://channel#claimid, Windows
  //     interprets the hash mark as an anchor and converts it to
  //     lbry://channel/#claimid. We remove the slash here as well.

  if (process.platform == 'win32') {
    return uri.replace(/\/$/, '').replace('/#', '#');
  } else {
    return uri;
  }
}

function checkForNewVersion(callback) {
  function formatRc(ver) {
    // Adds dash if needed to make RC suffix semver friendly
    return ver.replace(/([^-])rc/, '$1-rc');
  }

  let result = '';
  const opts = {
    headers: {
      'User-Agent': `LBRY/${localVersion}`,
    }
  };

  const req = https.get(Object.assign(opts, url.parse(LATEST_RELEASE_API_URL)), (res) => {
    res.on('data', (data) => {
      result += data;
    });
    res.on('end', () => {
      const tagName = JSON.parse(result).tag_name;
      const [_, remoteVersion] = tagName.match(/^v([\d.]+(?:-?rc\d+)?)$/);
      if (!remoteVersion) {
        if (win) {
          win.webContents.send('version-info-received', null);
        }
      } else {
        const upgradeAvailable = semver.gt(formatRc(remoteVersion), formatRc(localVersion));
        if (win) {
          win.webContents.send('version-info-received', {remoteVersion, localVersion, upgradeAvailable});
        }
      }
    })
  });

  req.on('error', (err) => {
    console.log('Failed to get current version from GitHub. Error:', err);
    if (win) {
      win.webContents.send('version-info-received', null);
    }
  });
}

ipcMain.on('version-info-requested', checkForNewVersion);

/*
 * Replacement for Electron's shell.openItem. The Electron version doesn't
 * reliably work from the main process, and we need to be able to run it
 * when no windows are open.
 */
function openItem(fullPath) {
    const subprocOptions = {
      detached: true,
      stdio: 'ignore',
    };

    let child;
    if (process.platform == 'darwin') {
      child = child_process.spawn('open', [fullPath], subprocOptions);
    } else if (process.platform == 'linux') {
      child = child_process.spawn('xdg-open', [fullPath], subprocOptions);
    } else if (process.platform == 'win32') {
      child = child_process.spawn(fullPath, Object.assign({}, subprocOptions, {shell: true}));
    }

    // Causes child process reference to be garbage collected, allowing main process to exit
    child.unref();
}

function getPidsForProcessName(name) {
  if (process.platform == 'win32') {
    const tasklistOut = child_process.execSync(`tasklist /fi "Imagename eq ${name}.exe" /nh`, {encoding: 'utf8'});
    if (tasklistOut.startsWith('INFO')) {
      return [];
    } else {
      return tasklistOut.match(/[^\r\n]+/g).map((line) => line.split(/\s+/)[1]); // Second column of every non-empty line
    }
  } else {
    const pgrepOut = child_process.spawnSync('pgrep', ['-x', name], {encoding: 'utf8'}).stdout;
    return pgrepOut.match(/\d+/g);
  }
}

function createWindow () {
  win = new BrowserWindow({backgroundColor: '#155B4A', minWidth: 800, minHeight: 600 }) //$color-primary

  win.maximize()
  if (isDebug) {
    win.webContents.openDevTools();
  }
  win.loadURL(`file://${__dirname}/dist/index.html`)
  if (openUri) { // We stored and received a URI that an external app requested before we had a window object
    win.webContents.on('did-finish-load', () => {
      win.webContents.send('open-uri-requested', openUri);
    });
  }

  win.on('closed', () => {
    win = null
  })
};

function handleDaemonSubprocessExited() {
  console.log('The daemon has exited.');
  daemonSubprocess = null;
  if (!daemonStopRequested) {
    // We didn't request to stop the daemon, so display a
    // warning and schedule a quit.
    //
    // TODO: maybe it would be better to restart the daemon?
    if (win) {
      console.log('Did not request daemon stop, so quitting in 5 seconds.');
      win.loadURL(`file://${__dirname}/dist/warning.html`);
      setTimeout(quitNow, 5000);
    } else {
      console.log('Did not request daemon stop, so quitting.');
      quitNow();
    }
  }
}

function launchDaemon() {
  assert(!daemonSubprocess, 'Tried to launch daemon twice');

  if (process.env.LBRY_DAEMON) {
    executable = process.env.LBRY_DAEMON;
  } else {
    executable = path.join(__dirname, 'dist', 'lbrynet-daemon');
  }
  console.log('Launching daemon:', executable)
  daemonSubprocess = child_process.spawn(executable)
  // Need to handle the data event instead of attaching to
  // process.stdout because the latter doesn't work. I believe on
  // windows it buffers stdout and we don't get any meaningful output
  daemonSubprocess.stdout.on('data', (buf) => {console.log(String(buf).trim());});
  daemonSubprocess.stderr.on('data', (buf) => {console.log(String(buf).trim());});
  daemonSubprocess.on('exit', handleDaemonSubprocessExited);
}

/*
 * Quits without any preparation. When a quit is requested (either through the
 * interface or through app.quit()), we abort the quit, try to shut down the daemon,
 * and then call this to quit for real.
 */
function quitNow() {
  readyToQuit = true;
  app.quit();
}

if (process.platform != 'linux') {
  // On Linux, this is always returning true due to an Electron bug,
  // so for now we just don't support single-instance apps on Linux.
  const isSecondaryInstance = app.makeSingleInstance((argv) => {
    if (win) {
      if (win.isMinimized()) {
        win.restore();
      }
      win.focus();

      if (argv.length >= 2) {
        win.webContents.send('open-uri-requested', denormalizeUri(argv[1]));
      }
    } else if (argv.length >= 2) {
      openUri = denormalizeUri(argv[1]);
    }
  });

  if (isSecondaryInstance) { // We're not in the original process, so quit
    quitNow();
    return;
  }
}

app.on('ready', function(){
  launchDaemonIfNotRunning();
  createWindow();
});

function launchDaemonIfNotRunning() {
  // Check if the daemon is already running. If we get
  // an error its because its not running
  console.log('Checking for lbrynet daemon');
  client.request(
    'status', [],
    function (err, res) {
      if (err) {
        console.log('lbrynet daemon needs to be launched')
        launchDaemon();
      } else {
        console.log('lbrynet daemon is already running')
      }
    }
  );
}

/*
 * Last resort for killing unresponsive daemon instances.
 * Looks for any processes called "lbrynet-daemon" and
 * tries to force kill them.
 */
function forceKillAllDaemonsAndQuit() {
  console.log('Attempting to force kill any running lbrynet-daemon instances...');

  const daemonPids = getPidsForProcessName('lbrynet-daemon');
  if (!daemonPids) {
    console.log('No lbrynet-daemon found running.');
    quitNow();
  } else {
    console.log(`Found ${daemonPids.length} running daemon instances. Attempting to force kill...`);

    for (const pid of daemonPids) {
      let daemonKillAttemptsComplete = 0;
      kill(pid, 'SIGKILL', (err) => {
        daemonKillAttemptsComplete++;
        if (err) {
          console.log(`Failed to force kill daemon task with pid ${pid}. Error message: ${err.message}`);
        } else {
          console.log(`Force killed daemon task with pid ${pid}.`);
        }
        if (daemonKillAttemptsComplete >= daemonPids.length - 1) {
          quitNow();
        }
      });
    }
  }
}

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('before-quit', (event) => {
  if (!readyToQuit) {
    // We need to shutdown the daemon before we're ready to actually quit. This
    // event will be triggered re-entrantly once preparation is done.
    event.preventDefault();
    shutdownDaemonAndQuit();
  } else {
    console.log('Quitting.')
  }
});

app.on('activate', () => {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (win === null) {
    createWindow()
  }
});

// When a quit is attempted, this is called. It attempts to shutdown the daemon,
// then calls quitNow() to quit for real.
function shutdownDaemonAndQuit(evenIfNotStartedByApp = false) {
  function doShutdown() {
    console.log('Shutting down daemon');
    daemonStopRequested = true;
    client.request('daemon_stop', [], (err, res) => {
      if (err) {
        console.log(`received error when stopping lbrynet-daemon. Error message: ${err.message}\n`);
        console.log('You will need to manually kill the daemon.');
      } else {
        console.log('Successfully stopped daemon via RPC call.')
        quitNow();
      }
    });
  }

  if (daemonSubprocess) {
    doShutdown();
  } else if (!evenIfNotStartedByApp) {
    console.log('Not killing lbrynet-daemon because app did not start it');
    quitNow();
  } else {
    doShutdown();
  }

  // Is it safe to start the installer before the daemon finishes running?
  // If not, we should wait until the daemon is closed before we start the install.
}

function upgrade(event, installerPath) {
  app.on('quit', () => {
    console.log('Launching upgrade installer at', installerPath);
    // This gets triggered called after *all* other quit-related events, so
    // we'll only get here if we're fully prepared and quitting for real.
    openItem(installerPath);
  });

  if (win) {
    win.loadURL(`file://${__dirname}/dist/upgrade.html`);
  }

  shutdownDaemonAndQuit(true);
  // wait for daemon to shut down before upgrading
  // what to do if no shutdown in a long time?
  console.log('Update downloaded to', installerPath);
  console.log('The app will close, and you will be prompted to install the latest version of LBRY.');
  console.log('After the install is complete, please reopen the app.');
}

ipcMain.on('upgrade', upgrade);

app.setAsDefaultProtocolClient('lbry');

if (process.platform == 'darwin') {
  app.on('open-url', (event, uri) => {
    if (!win) {
      // Window not created yet, so store up requested URI for when it is
      openUri = uri;
    } else {
      win.webContents.send('open-uri-requested', uri);
    }
  });
} else if (process.argv.length >= 2) {
  if (!win) {
    openUri = denormalizeUri(process.argv[1]);
  } else {
    win.webContents.send('open-uri-requested', denormalizeUri(process.argv[1]));
  }
}
<|endoftext|>


<commit_before>/**
 * Created by JiaHao on 4/7/15.
 */

var fs = require('fs');
var os = require('os');
var electron = require('electron');

var wurl = require('wurl');

var app = electron.app;
var BrowserWindow = electron.BrowserWindow;
var shell = electron.shell;
var ipcMain = electron.ipcMain;

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

const APP_ARGS_FILE_PATH = __dirname + '/nativefier.json';

var mainWindow = null;

var appArgs = JSON.parse(fs.readFileSync(APP_ARGS_FILE_PATH, 'utf8'));

app.on('window-all-closed', function () {
    if (!isOSX()) {
        app.quit();
    }
});

app.on('activate', function (event, hasVisibleWindows) {
    if (isOSX()) {
        // this is called when the dock is clicked
        if (!hasVisibleWindows) {
            mainWindow.show();
        }
    }
});

app.on('before-quit', () => {
    // not fired when the close button on the window is clicked
    if (isOSX()) {
        // need to force a quit as a workaround here to simulate the osx app hiding behaviour
        // Somehow sokution at https://github.com/atom/electron/issues/444#issuecomment-76492576 does not work,
        // e.prevent default appears to persist

        // might cause issues in the future as before-quit and will-quit events are not called
        app.exit(0);
    }
});

app.on('ready', function () {
    mainWindow = new BrowserWindow(
        {
            width: appArgs.width || 1280,
            height: appArgs.height || 800,
            'web-preferences': {
                javascript: true,
                plugins: true,
                nodeIntegration: false,
                preload: __dirname + '/assets/js/index.js'
            }
        }
    );

    buildMenu(mainWindow, appArgs.nativefierVersion, app.quit);

    if (appArgs.userAgent) {
        mainWindow.webContents.setUserAgent(appArgs.userAgent);
    }

    mainWindow.webContents.on('did-finish-load', function () {
        mainWindow.webContents.send('params', JSON.stringify(appArgs));
    });

    if (appArgs.badge || appArgs.counter) {
        mainWindow.on('page-title-updated', function () {

            if (!isOSX() || mainWindow.isFocused()) {
                return;
            }

            if (appArgs.counter) {
                var itemCountRegex = /[\(](\d*?)[\)]/;
                var match = itemCountRegex.exec(mainWindow.getTitle());
                console.log(mainWindow.getTitle(), match);
                if (match) {
                    app.dock.setBadge(match[1]);
                }
                return;
            }

            app.dock.setBadge('●');
        });
    }

    mainWindow.webContents.on('new-window', function (event, urlToGo) {
        if (linkIsInternal(appArgs.targetUrl, urlToGo)) {
            return;
        }
        event.preventDefault();
        shell.openExternal(url);
    });

    mainWindow.loadURL(appArgs.targetUrl);
    // if the window is focused, clear the badge
    mainWindow.on('focus', function () {
        if (!isOSX()) {
            return;
        }
        if (appArgs.badge || appArgs.counter) {
            app.dock.setBadge('');
        }
    });

    mainWindow.on('close', (e) => {
        if (isOSX()) {
            // this is called when exiting from clicking the cross button on the window
            e.preventDefault();
            mainWindow.hide();
        }
    });
});

app.on('login', function(event, webContents, request, authInfo, callback) {
    event.preventDefault();
    var loginWindow = new BrowserWindow({
        width: 300,
        height: 400,
        frame: false,
        resizable: false
    });
    loginWindow.loadURL('file://' + __dirname + '/components/login/login.html');

    ipcMain.once('login-message', function(event, usernameAndPassword) {
        callback(usernameAndPassword[0], usernameAndPassword[1]);
        loginWindow.close();
    });
});

function isOSX() {
    return os.platform() === 'darwin';
}

function linkIsInternal(currentUrl, newUrl) {
    var currentDomain = wurl('domain', currentUrl);
    var newDomain = wurl('domain', newUrl);
    return currentDomain === newDomain;
}
<commit_msg>Fix bug in invalid parameter for link in default browser<commit_after>/**
 * Created by JiaHao on 4/7/15.
 */

var fs = require('fs');
var os = require('os');
var electron = require('electron');

var wurl = require('wurl');

var app = electron.app;
var BrowserWindow = electron.BrowserWindow;
var shell = electron.shell;
var ipcMain = electron.ipcMain;

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

const APP_ARGS_FILE_PATH = __dirname + '/nativefier.json';

var mainWindow = null;

var appArgs = JSON.parse(fs.readFileSync(APP_ARGS_FILE_PATH, 'utf8'));

app.on('window-all-closed', function () {
    if (!isOSX()) {
        app.quit();
    }
});

app.on('activate', function (event, hasVisibleWindows) {
    if (isOSX()) {
        // this is called when the dock is clicked
        if (!hasVisibleWindows) {
            mainWindow.show();
        }
    }
});

app.on('before-quit', () => {
    // not fired when the close button on the window is clicked
    if (isOSX()) {
        // need to force a quit as a workaround here to simulate the osx app hiding behaviour
        // Somehow sokution at https://github.com/atom/electron/issues/444#issuecomment-76492576 does not work,
        // e.prevent default appears to persist

        // might cause issues in the future as before-quit and will-quit events are not called
        app.exit(0);
    }
});

app.on('ready', function () {
    mainWindow = new BrowserWindow(
        {
            width: appArgs.width || 1280,
            height: appArgs.height || 800,
            'web-preferences': {
                javascript: true,
                plugins: true,
                nodeIntegration: false,
                preload: __dirname + '/assets/js/index.js'
            }
        }
    );

    buildMenu(mainWindow, appArgs.nativefierVersion, app.quit);

    if (appArgs.userAgent) {
        mainWindow.webContents.setUserAgent(appArgs.userAgent);
    }

    mainWindow.webContents.on('did-finish-load', function () {
        mainWindow.webContents.send('params', JSON.stringify(appArgs));
    });

    if (appArgs.badge || appArgs.counter) {
        mainWindow.on('page-title-updated', function () {

            if (!isOSX() || mainWindow.isFocused()) {
                return;
            }

            if (appArgs.counter) {
                var itemCountRegex = /[\(](\d*?)[\)]/;
                var match = itemCountRegex.exec(mainWindow.getTitle());
                console.log(mainWindow.getTitle(), match);
                if (match) {
                    app.dock.setBadge(match[1]);
                }
                return;
            }

            app.dock.setBadge('●');
        });
    }

    mainWindow.webContents.on('new-window', function (event, urlToGo) {
        if (linkIsInternal(appArgs.targetUrl, urlToGo)) {
            return;
        }
        event.preventDefault();
        shell.openExternal(urlToGo);
    });

    mainWindow.loadURL(appArgs.targetUrl);
    // if the window is focused, clear the badge
    mainWindow.on('focus', function () {
        if (!isOSX()) {
            return;
        }
        if (appArgs.badge || appArgs.counter) {
            app.dock.setBadge('');
        }
    });

    mainWindow.on('close', (e) => {
        if (isOSX()) {
            // this is called when exiting from clicking the cross button on the window
            e.preventDefault();
            mainWindow.hide();
        }
    });
});

app.on('login', function(event, webContents, request, authInfo, callback) {
    event.preventDefault();
    var loginWindow = new BrowserWindow({
        width: 300,
        height: 400,
        frame: false,
        resizable: false
    });
    loginWindow.loadURL('file://' + __dirname + '/components/login/login.html');

    ipcMain.once('login-message', function(event, usernameAndPassword) {
        callback(usernameAndPassword[0], usernameAndPassword[1]);
        loginWindow.close();
    });
});

function isOSX() {
    return os.platform() === 'darwin';
}

function linkIsInternal(currentUrl, newUrl) {
    var currentDomain = wurl('domain', currentUrl);
    var newDomain = wurl('domain', newUrl);
    return currentDomain === newDomain;
}
<|endoftext|>


<commit_before>var exported = {
  noflo: require('noflo'),
  underscore: require('underscore'),
  'coffee-script': require('coffee-script'),
  'child_process': null,
  'uuid': require('uuid'),
  'flowhub-registry': require('flowhub-registry'),
  'fbp-protocol-client': require('fbp-protocol-client'),
  'noflo-ui/src/JournalStore': require('../src/JournalStore'),
  'noflo-ui/runtimeinfo': require('../runtimeinfo/index.coffee')
};

window.require = function (moduleName) {
  if (typeof exported[moduleName] !== 'undefined') {
    return exported[moduleName];
  }
  throw new Error('Module ' + moduleName + ' not available');
};

window.addEventListener('WebComponentsReady', function() {
  var noflo = require('noflo');
  var runtime = require('noflo-runtime-webrtc');

  var baseDir = '/noflo-ui';
  var mainGraph = require('../graphs/main.fbp');

  var loadGraphs = function(callback) {
    noflo.graph.loadJSON(mainGraph, function (err, g) {
      if (err) {
        callback(err);
        return;
      }
      g.baseDir = baseDir;
      noflo.createNetwork(g, function (err, n) {
        if (err) {
          callback(err);
          return;
        }
        n.on('process-error', function (err) {
          console.log(err);
        });
        return callback();
      });
    });
  };
  var loadGraphsDebuggable = function(callback) {
    var secret = Math.random().toString(36).substring(7);
    noflo.graph.loadJSON(mainGraph, function (err, graph) {
      if (err) {
        callback(err);
        return;
      }
      graph.baseDir = baseDir;
      var runtimeOptions = {
        defaultGraph: graph,
        baseDir: graph.baseDir,
        permissions: {}
      };
      runtimeOptions.permissions[secret] = [
        'protocol:component',
        'protocol:runtime',
        'protocol:graph',
        'protocol:network',
        'component:getsource',
        'component:setsource'
      ];
      var rt = runtime(null, runtimeOptions, true);
      rt.start();
      var ide = 'http://app.flowhub.io';
      var debugUrl = ide+'#runtime/endpoint?'+encodeURIComponent('protocol=webrtc&address='+rt.signaller+'#'+rt.id+'&secret='+secret);
      var debugLink = document.getElementById('flowhub_debug_url');
      if (debugLink) {
        debugLink.href = debugUrl;
      } else {
        console.log(debugUrl);
      }
      rt.network.on('addnetwork', function () {
        return callback();
      });
    });
  };

  window.nofloStarted = false;
  var load = (false) ? loadGraphsDebuggable : loadGraphs;
  load(function(err) {
    if (err) {
      throw err;
    }
    document.body.classList.remove('loading');
    window.nofloStarted = true;
    setTimeout(function () {
      var loader = document.getElementById('loading');
      document.body.removeChild(loader);
    }, 400);
  });
});
<commit_msg>fbp-spec: Fix dependency missing<commit_after>var exported = {
  noflo: require('noflo'),
  underscore: require('underscore'),
  'coffee-script': require('coffee-script'),
  'child_process': null,
  'uuid': require('uuid'),
  'flowhub-registry': require('flowhub-registry'),
  'fbp-protocol-client': require('fbp-protocol-client'),
  'fbp-spec': require('fbp-spec'),
  'noflo-ui/src/JournalStore': require('../src/JournalStore'),
  'noflo-ui/runtimeinfo': require('../runtimeinfo/index.coffee')
};

window.require = function (moduleName) {
  if (typeof exported[moduleName] !== 'undefined') {
    return exported[moduleName];
  }
  throw new Error('Module ' + moduleName + ' not available');
};

window.addEventListener('WebComponentsReady', function() {
  var noflo = require('noflo');
  var runtime = require('noflo-runtime-webrtc');

  var baseDir = '/noflo-ui';
  var mainGraph = require('../graphs/main.fbp');

  var loadGraphs = function(callback) {
    noflo.graph.loadJSON(mainGraph, function (err, g) {
      if (err) {
        callback(err);
        return;
      }
      g.baseDir = baseDir;
      noflo.createNetwork(g, function (err, n) {
        if (err) {
          callback(err);
          return;
        }
        n.on('process-error', function (err) {
          console.log(err);
        });
        return callback();
      });
    });
  };
  var loadGraphsDebuggable = function(callback) {
    var secret = Math.random().toString(36).substring(7);
    noflo.graph.loadJSON(mainGraph, function (err, graph) {
      if (err) {
        callback(err);
        return;
      }
      graph.baseDir = baseDir;
      var runtimeOptions = {
        defaultGraph: graph,
        baseDir: graph.baseDir,
        permissions: {}
      };
      runtimeOptions.permissions[secret] = [
        'protocol:component',
        'protocol:runtime',
        'protocol:graph',
        'protocol:network',
        'component:getsource',
        'component:setsource'
      ];
      var rt = runtime(null, runtimeOptions, true);
      rt.start();
      var ide = 'http://app.flowhub.io';
      var debugUrl = ide+'#runtime/endpoint?'+encodeURIComponent('protocol=webrtc&address='+rt.signaller+'#'+rt.id+'&secret='+secret);
      var debugLink = document.getElementById('flowhub_debug_url');
      if (debugLink) {
        debugLink.href = debugUrl;
      } else {
        console.log(debugUrl);
      }
      rt.network.on('addnetwork', function () {
        return callback();
      });
    });
  };

  window.nofloStarted = false;
  var load = (false) ? loadGraphsDebuggable : loadGraphs;
  load(function(err) {
    if (err) {
      throw err;
    }
    document.body.classList.remove('loading');
    window.nofloStarted = true;
    setTimeout(function () {
      var loader = document.getElementById('loading');
      document.body.removeChild(loader);
    }, 400);
  });
});
<|endoftext|>


<commit_before>var counter;
var header = 130;
var effectiveWindowWidth, effectiveWindowHeight;

function setup() {
    effectiveWindowWidth = windowWidth - 16;
    effectiveWindowHeight = windowHeight - header;
    var canvas = createCanvas(effectiveWindowWidth, effectiveWindowHeight);

    canvas.parent('play');
    counter = new Counter();
    counter.new();

    var buttons = selectAll('.value-button');

    for (var i = 0; i < buttons.length; i++) {
        buttons[i].mouseClicked(function () {
            counter.guess(this.elt.innerHTML);
        });
    }

    var enterButton = select('.enter-button');
    enterButton.mouseClicked(function () {
        counter.submitGuess();
    });
}

function draw() {
    background(255, 255, 255);
    counter.draw();
}

function windowResized() {
    effectiveWindowWidth = windowWidth - 16;
    effectiveWindowHeight = windowHeight - header;
    resizeCanvas(effectiveWindowWidth, effectiveWindowHeight);
}

function keyTyped() {
    if (key === ' ' || counter.loosing) {
        counter.new();
    }
    if (keyCode == ENTER) {
        counter.submitGuess();
    }
    var numbers = ["1","2","3","4","5","6","7","8","9","0"];
    if (numbers.indexOf(key) > - 1) {
        counter.guess(key);
    }
}

function touchStarted() {
    if (touches.length > 0) {
        var touch = touches[0];
        if (
            touch.x >= 0 && touch.x < effectiveWindowWidth &&
            touch.y >= 0 && touch.y < effectiveWindowHeight
        )
        {
            counter.new();
        }
    }
}

function Counter () {
    this.objects = [];
    this.score = 0;
    this.number = 0;
    var gap = 45;
    this.new = function () {
        this.loosing = false;
        this.objects = [];
        this.number = floor(random(1, 10));
        var newPosition;
        while(this.objects.length < this.number) {
            newPosition = this.findNewPosition();
            if (!newPosition)
            {
                this.number--;
                continue;
            }
            this.objects.push({
                    position: newPosition,
                    color: color('red'),
                    type: 'ellipse'
                });
        }
        var level2 = floor(random(1, 5));
        if (this.score > 5) {
            for(var i = 0; i < level2; i++) {
                newPosition = this.findNewPosition();
                if (!newPosition)
                {
                    level2--;
                    continue;
                }
                this.objects.push({
                    position: newPosition,
                    color: color('blue'),
                    type: 'ellipse'
                });
            }
        }
        var level3 = floor(random(1, 5));
        if (this.score > 10) {
            for(var i = 0; i < level3; i++) {
                newPosition = this.findNewPosition();
                if (!newPosition)
                {
                    level3--;
                    continue;
                }
                this.objects.push({
                    position: newPosition,
                    color: color('red'),
                    type: 'rect'
                });
            }
        }
        var div = select('#solution');
        div.html("Count the RED circles and press ENTER!");
    }

    this.findNewPosition = function() {
        var counter = 0;
        while(true)
        {
            var newPosition = createVector(random(gap, effectiveWindowWidth - gap), random(gap, effectiveWindowHeight - gap));

            if (this.objects.every(function(item){
                return p5.Vector.sub(item.position, newPosition).mag() > 85;
            }))
            {
                return newPosition;
            }
            counter++;
            if (counter > 200)
                break;
        }
    }

    this.draw = function() {
        for(var i = 0; i < this.objects.length; i++) {
            var object = this.objects[i];
            fill(object.color);
            switch (object.type)
            {
                case 'ellipse':
                    ellipse(object.position.x, object.position.y, 80);
                break;
                case 'rect':
                    rect(object.position.x - 40, object.position.y - 40, 80, 80, 20);
                break;
            }
        }
        fill(0,0,0);
        textSize(30);
        text(this.score, 10, 35);
    }

    this.guess = function(guess) {
        this.lastGuess = guess;

        var div = select('#solution');
        div.html(this.lastGuess);
    }

    this.submitGuess = function(guess) {
        if (this.isValid()) {
            var div = select('#solution');
            div.html("Right");
            this.win();
            this.new();
        }
        else{
            var div = select('#solution');
            div.html("Wrong. Press any key/touch to restart.");
            this.loose();
        }
    }

    this.isValid = function() {
        return this.lastGuess == this.number;
    }

    this.win = function() {
        this.score += 1;
    }

    this.loose = function() {
        this.score = 0;
        this.objects = [];
        this.loosing = true;
    }
}<commit_msg>Adapt the object size for small displays<commit_after>var counter;
var header = 130;
var effectiveWindowWidth, effectiveWindowHeight;
var objectSize = 80;

function setup() {
    effectiveWindowWidth = windowWidth - 16;
    effectiveWindowHeight = windowHeight - header;
    var canvas = createCanvas(effectiveWindowWidth, effectiveWindowHeight);

    if (displayWidth < 700)
        objectSize = 30;

    canvas.parent('play');
    counter = new Counter();
    counter.new();

    var buttons = selectAll('.value-button');

    for (var i = 0; i < buttons.length; i++) {
        buttons[i].mouseClicked(function () {
            counter.guess(this.elt.innerHTML);
        });
    }

    var enterButton = select('.enter-button');
    enterButton.mouseClicked(function () {
        counter.submitGuess();
    });
}

function draw() {
    background(255, 255, 255);
    counter.draw();
}

function windowResized() {
    effectiveWindowWidth = windowWidth - 16;
    effectiveWindowHeight = windowHeight - header;
    resizeCanvas(effectiveWindowWidth, effectiveWindowHeight);
}

function keyTyped() {
    if (key === ' ' || counter.loosing) {
        counter.new();
    }
    if (keyCode == ENTER) {
        counter.submitGuess();
    }
    var numbers = ["1","2","3","4","5","6","7","8","9","0"];
    if (numbers.indexOf(key) > - 1) {
        counter.guess(key);
    }
}

function touchStarted() {
    if (touches.length > 0) {
        var touch = touches[0];
        if (
            touch.x >= 0 && touch.x < effectiveWindowWidth &&
            touch.y >= 0 && touch.y < effectiveWindowHeight
        )
        {
            counter.new();
        }
    }
}

function Counter () {
    this.objects = [];
    this.score = 0;
    this.number = 0;
    var gap = objectSize + 5;
    this.new = function () {
        this.loosing = false;
        this.objects = [];
        this.number = floor(random(1, 10));
        var newPosition;
        while(this.objects.length < this.number) {
            newPosition = this.findNewPosition();
            if (!newPosition)
            {
                this.number--;
                continue;
            }
            this.objects.push({
                    position: newPosition,
                    color: color('red'),
                    type: 'ellipse'
                });
        }
        var level2 = floor(random(1, 5));
        if (this.score > 5) {
            for(var i = 0; i < level2; i++) {
                newPosition = this.findNewPosition();
                if (!newPosition)
                {
                    level2--;
                    continue;
                }
                this.objects.push({
                    position: newPosition,
                    color: color('blue'),
                    type: 'ellipse'
                });
            }
        }
        var level3 = floor(random(1, 5));
        if (this.score > 10) {
            for(var i = 0; i < level3; i++) {
                newPosition = this.findNewPosition();
                if (!newPosition)
                {
                    level3--;
                    continue;
                }
                this.objects.push({
                    position: newPosition,
                    color: color('red'),
                    type: 'rect'
                });
            }
        }
        var div = select('#solution');
        div.html("Count the RED circles and press ENTER!");
    }

    this.findNewPosition = function() {
        var counter = 0;
        while(true)
        {
            var newPosition = createVector(random(gap, effectiveWindowWidth - gap), random(gap, effectiveWindowHeight - gap));

            if (this.objects.every(function(item){
                return p5.Vector.sub(item.position, newPosition).mag() > objectSize * 2 + 5;
            }))
            {
                return newPosition;
            }
            counter++;
            if (counter > 200)
                break;
        }
    }

    this.draw = function() {
        for(var i = 0; i < this.objects.length; i++) {
            var object = this.objects[i];
            fill(object.color);
            switch (object.type)
            {
                case 'ellipse':
                    ellipse(object.position.x, object.position.y, objectSize * 2);
                break;
                case 'rect':
                    rect(object.position.x - objectSize, object.position.y - objectSize, objectSize * 2, objectSize * 2, 20);
                break;
            }
        }
        fill(0,0,0);
        textSize(30);
        text(this.score, 10, 35);
    }

    this.guess = function(guess) {
        this.lastGuess = guess;

        var div = select('#solution');
        div.html(this.lastGuess);
    }

    this.submitGuess = function(guess) {
        if (this.isValid()) {
            var div = select('#solution');
            div.html("Right");
            this.win();
            this.new();
        }
        else{
            var div = select('#solution');
            div.html("Wrong. Press any key/touch to restart.");
            this.loose();
        }
    }

    this.isValid = function() {
        return this.lastGuess == this.number;
    }

    this.win = function() {
        this.score += 1;
    }

    this.loose = function() {
        this.score = 0;
        this.objects = [];
        this.loosing = true;
    }
}<|endoftext|>


<commit_before>EvemonkApp.Models.Profile = Backbone.Model.extend({
    urlRoot: '/api/profile'
});
<commit_msg>Add url to model<commit_after>EvemonkApp.Models.Profile = Backbone.Model.extend({
    url: Routes.api_profile_path()
});
<|endoftext|>


<commit_before>/**
 * Created by JiaHao on 4/7/15.
 */

var app = require('app');
var fs = require('fs');
var BrowserWindow = require('browser-window');
var ipc = require('ipc');

const APP_ARGS_FILE_PATH = __dirname + '/targetUrl.txt';
require('crash-reporter').start();

var mainWindow = null;

var appArgs = JSON.parse(fs.readFileSync(APP_ARGS_FILE_PATH, 'utf8'));

app.on('window-all-closed', function() {
    if (process.platform != 'darwin') {
        app.quit();
    }
});

app.on('ready', function() {
    mainWindow = new BrowserWindow(
        {
            width: appArgs.width || 1280,
            height: appArgs.height || 800,
            'web-preferences': {
                javascript: true,
                plugins: true,
            }
        }
    );
    mainWindow.loadUrl('file://' + __dirname + '/index.html');

    //mainWindow.openDevTools();
    mainWindow.webContents.on('did-finish-load', function() {

        mainWindow.webContents.send('params', JSON.stringify(appArgs));
    });

    // if the window is focused, clear the badge
    mainWindow.on('focus', function () {
        app.dock.setBadge('');
    });

    mainWindow.on('closed', function() {
        mainWindow = null;
    });
});

// listen for a notification message
ipc.on('notification-message', function(event, arg) {
    console.log(arg);  // prints "ping"
    if (arg === 'TITLE_CHANGED') {
        if (!mainWindow.isFocused()) {
            app.dock.setBadge('●');
        }
    }
});

app.on('window-all-closed', function() {
    app.quit();
});<commit_msg>Prevent call to setBadge when not on OSX<commit_after>/**
 * Created by JiaHao on 4/7/15.
 */

var app = require('app');
var fs = require('fs');
var BrowserWindow = require('browser-window');
var ipc = require('ipc');

const APP_ARGS_FILE_PATH = __dirname + '/targetUrl.txt';
require('crash-reporter').start();

var mainWindow = null;

var appArgs = JSON.parse(fs.readFileSync(APP_ARGS_FILE_PATH, 'utf8'));

app.on('window-all-closed', function() {
    if (process.platform != 'darwin') {
        app.quit();
    }
});

app.on('ready', function() {
    mainWindow = new BrowserWindow(
        {
            width: appArgs.width || 1280,
            height: appArgs.height || 800,
            'web-preferences': {
                javascript: true,
                plugins: true,
            }
        }
    );
    mainWindow.loadUrl('file://' + __dirname + '/index.html');

    //mainWindow.openDevTools();
    mainWindow.webContents.on('did-finish-load', function() {

        mainWindow.webContents.send('params', JSON.stringify(appArgs));
    });

    // if the window is focused, clear the badge
    mainWindow.on('focus', function () {
        if (process.platform === 'darwin') {
            app.dock.setBadge('');
        }
    });

    mainWindow.on('closed', function() {
        mainWindow = null;
    });
});

// listen for a notification message
ipc.on('notification-message', function(event, arg) {
    if (arg === 'TITLE_CHANGED') {
        if (process.platform === 'darwin' && !mainWindow.isFocused()) {
            app.dock.setBadge('●');
        }
    }
});

app.on('window-all-closed', function() {
    app.quit();
});
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.js';
import Home from './components/Home';
import Programs from './components/Programs';
import Program from './components/Program';
import Login from './components/Login';
import Register from './components/Register';
import { Router, Route, browserHistory, IndexRoute } from 'react-router';

import auth from './auth';

const requireAuth = (nextState, replaceState) => {
  if (!auth.loggedIn()) {
    replaceState({ nextPathname: nextState.location.pathname }, '/login');
  }
};

ReactDOM.render(
	<Router history={browserHistory}>
    <Route path="/" component={App}>
      <IndexRoute component={Home}/>
      <Route path="programs" component={Programs} onEnter={requireAuth} />
      <Route path="programs/:id" component={Program} />
      <Route path="login" component={Login} />
      <Route path="register" component={Register} />
    </Route>
  </Router>
  , document.getElementById('root')
);
<commit_msg>Remove _k parameter from url. This is used for old browsers.<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.js';
import Home from './components/Home';
import Programs from './components/Programs';
import Program from './components/Program';
import Login from './components/Login';
import Register from './components/Register';
import { Router, Route, IndexRoute } from 'react-router';

import auth from './auth';

import createHistory from 'history/lib/createHashHistory';

let history = createHistory({
  queryKey: false
});

const requireAuth = (nextState, replaceState) => {
  if (!auth.loggedIn()) {
    replaceState({ nextPathname: nextState.location.pathname }, '/login');
  }
};

ReactDOM.render(
	<Router history={history}>
    <Route path="/" component={App}>
      <IndexRoute component={Home}/>
      <Route path="programs" component={Programs} onEnter={requireAuth} />
      <Route path="programs/:id" component={Program} />
      <Route path="login" component={Login} />
      <Route path="register" component={Register} />
    </Route>
  </Router>
  , document.getElementById('root')
);
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

const electron = require('electron')
const app = electron.app
const Menu = require('menu')
const Shell = require('shell')

const init = () => {
  var template = [
    {
      label: 'File',
      submenu: [
        {
          label: 'New Tab',
          accelerator: 'CmdOrCtrl+T',
          click: function (item, focusedWindow) {
            if (focusedWindow) {
              focusedWindow.webContents.send('shortcut-new-frame')
            } else {
              // no active windows
              process.emit('new-window')
            }
          }
        }, {
          label: 'New Window',
          accelerator: 'CmdOrCtrl+N',
          click: () => process.emit('new-window')
        }, {
          type: 'separator'
        }, {
          // this should be disabled when
          // no windows are active
          label: 'Close Window',
          accelerator: 'CmdOrCtrl+Shift+W',
          click: function (item, focusedWindow) {
            if (focusedWindow) {
              process.emit('close-window')
            }
          }
        }, {
          // this should be disabled when
          // no windows are active
          label: 'Close Tab',
          accelerator: 'CmdOrCtrl+W',
          click: function (item, focusedWindow) {
            if (focusedWindow) {
              focusedWindow.webContents.send('shortcut-close-frame')
            }
          }
        }
      ]
    }, {
      label: 'Edit',
      submenu: [
        {
          label: 'Undo',
          accelerator: 'CmdOrCtrl+Z',
          role: 'undo'
        }, {
          label: 'Redo',
          accelerator: 'Shift+CmdOrCtrl+Z',
          role: 'redo'
        }, {
          type: 'separator'
        }, {
          label: 'Cut',
          accelerator: 'CmdOrCtrl+X',
          role: 'cut'
        }, {
          label: 'Copy',
          accelerator: 'CmdOrCtrl+C',
          role: 'copy'
        }, {
          label: 'Paste',
          accelerator: 'CmdOrCtrl+V',
          role: 'paste'
        }, {
          label: 'Select All',
          accelerator: 'CmdOrCtrl+A',
          role: 'selectall'
        }
      ]
    }, {
      label: 'View',
      submenu: [
        {
          label: 'Reload',
          accelerator: 'CmdOrCtrl+R',
          click: function (item, focusedWindow) {
            if (focusedWindow) {
              focusedWindow.reload()
            }
          }
        }, {
          label: 'Toggle Full Screen',
          accelerator: (function () {
            if (process.platform === 'darwin') {
              return 'Ctrl+Command+F'
            } else {
              return 'F11'
            }
          })(),
          click: function (item, focusedWindow) {
            if (focusedWindow) {
              focusedWindow.setFullScreen(!focusedWindow.isFullScreen())
            }
          }
        }, {
          label: 'Toggle Developer Tools',
          accelerator: (function () {
            if (process.platform === 'darwin') {
              return 'Alt+Command+I'
            } else {
              return 'Ctrl+Shift+I'
            }
          })(),
          click: function (item, focusedWindow) {
            if (focusedWindow) {
              focusedWindow.toggleDevTools()
            }
          }
        }
      ]
    }, {
      label: 'Window',
      role: 'window',
      submenu: [
        {
          label: 'Minimize',
          accelerator: 'CmdOrCtrl+M',
          role: 'minimize'
        }
      ]
    }, {
      label: 'Help',
      role: 'help',
      submenu: [
        {
          label: 'Learn More',
          click: function () { Shell.openExternal('http://brave.com') }
        }
      ]
    }
  ]

  if (process.platform === 'darwin') {
    var name = 'Brave'
    template.unshift({
      label: name, // Ignored. OSX gets this from the app Info.plist file.
      submenu: [
        {
          label: 'About ' + name,
          role: 'about'
        }, {
          type: 'separator'
        }, {
          label: 'Preferences...',
          accelerator: 'CmdOrCtrl+,'
        }, {
          type: 'separator'
        }, {
          label: 'Send us Feedback...',
          click: function (item, focusedWindow) {
            focusedWindow.webContents.send('shortcut-new-frame', 'https://brave.com')
          }
        }, {
          type: 'separator'
        }, {
          label: 'Services',
          role: 'services',
          submenu: []
        }, {
          type: 'separator'
        }, {
          label: 'Hide ' + name,
          accelerator: 'Command+H',
          role: 'hide'
        }, {
          label: 'Hide Others',
          accelerator: 'Command+Shift+H',
          role: 'hideothers'
        }, {
          label: 'Show All',
          role: 'unhide'
        }, {
          type: 'separator'
        }, {
          label: 'Quit',
          accelerator: 'Command+Q',
          click: app.quit
        }
      ]
    })
    // Window menu.
    template[3].submenu.push(
      {
        type: 'separator'
      }, {
        label: 'Bring All to Front',
        role: 'front'
      }
    )
  }

  const menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu)
}

module.exports.init = init
<commit_msg>Add level 1 submenus<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

const electron = require('electron')
const app = electron.app
const Menu = require('menu')

const init = () => {
  var template = [
    {
      label: 'File',
      submenu: [
        {
          label: 'New Tab',
          accelerator: 'CmdOrCtrl+T',
          click: function (item, focusedWindow) {
            if (focusedWindow) {
              focusedWindow.webContents.send('shortcut-new-frame')
            } else {
              // no active windows
              process.emit('new-window')
            }
          }
        }, {
          label: 'New Private Tab',
          accelerator: 'CmdOrCtrl+Alt+T',
          click: function (item, focusedWindow) {
            focusedWindow.webContents.send('shortcut-new-frame')
          }
        }, {
          label: 'New Window',
          accelerator: 'CmdOrCtrl+N',
          click: () => process.emit('new-window')
        }, {
          label: 'New Private Window',
          accelerator: 'CmdOrCtrl+Alt+N',
          click: () => process.emit('new-window')
        }, {
          type: 'separator'
        }, {
          label: 'Open File...',
          accelerator: 'CmdOrCtrl+O'
        }, {
          label: 'Open Location...',
          accelerator: 'CmdOrCtrl+L'
        }, {
          type: 'separator'
        }, {
          label: 'Import from...',
          submenu: []
        }, {
          type: 'separator'
        }, {
          // this should be disabled when
          // no windows are active
          label: 'Close Tab',
          accelerator: 'CmdOrCtrl+W',
          click: function (item, focusedWindow) {
            if (focusedWindow) {
              focusedWindow.webContents.send('shortcut-close-frame')
            }
          }
        }, {
          // this should be disabled when
          // no windows are active
          label: 'Close Window',
          accelerator: 'CmdOrCtrl+Shift+W',
          click: function (item, focusedWindow) {
            if (focusedWindow) {
              process.emit('close-window')
            }
          }
        }, {
          type: 'separator'
        }, {
          label: 'Save Page As...',
          accelerator: 'CmdOrCtrl+S'
        }, {
          label: 'Share...',
          submenu: []
        }, {
          type: 'separator'
        }, {
          label: 'Print...',
          accelerator: 'CmdOrCtrl+P',
          submenu: []
        }
      ]
    }, {
      label: 'Edit',
      submenu: [
        {
          label: 'Undo',
          accelerator: 'CmdOrCtrl+Z',
          role: 'undo'
        }, {
          label: 'Redo',
          accelerator: 'Shift+CmdOrCtrl+Z',
          role: 'redo'
        }, {
          type: 'separator'
        }, {
          label: 'Cut',
          accelerator: 'CmdOrCtrl+X',
          role: 'cut'
        }, {
          label: 'Copy',
          accelerator: 'CmdOrCtrl+C',
          role: 'copy'
        }, {
          label: 'Paste',
          accelerator: 'CmdOrCtrl+V',
          role: 'paste'
        }, {
          label: 'Paste without formatting',
          accelerator: 'Shift+CmdOrCtrl+V',
          role: 'paste'
        }, {
          type: 'separator'
        }, {
          label: 'Delete',
          accelerator: 'Delete'
        }, {
          label: 'Select All',
          accelerator: 'CmdOrCtrl+A',
          role: 'selectall'
        }, {
          type: 'separator'
        }, {
          label: 'Find on page...',
          accelerator: 'CmdOrCtrl+F'
        }, {
          label: 'Find Next',
          accelerator: 'CmdOrCtrl+G'
        }, {
          label: 'Find Previous',
          accelerator: 'Shift+CmdOrCtrl+G'
        }, {
          type: 'separator'
        }
        // OSX inserts "start dictation" and "emoji and symbols" automatically
      ]
    }, {
      label: 'View',
      submenu: [
        {
          label: 'Actual Size',
          accelerator: 'CmdOrCtrl+0'
        }, {
          label: 'Zoom In',
          accelerator: 'CmdOrCtrl+Plus' // renders as Shift+Cmd+= on OSX?
        }, {
          label: 'Zoom Out',
          accelerator: 'CmdOrCtrl+-'
        }, {
          type: 'separator'
        }, {
          label: 'Toolbars',
          submenu: []
        }, {
          type: 'separator'
        }, {
          label: 'Reload Page',
          accelerator: 'CmdOrCtrl+R',
          click: function (item, focusedWindow) {
            if (focusedWindow) {
              // TODO: reload active frame
              focusedWindow.reload()
            }
          }
        }, {
          label: 'Clean Reload',
          accelerator: 'CmdOrCtrl+Shift+R',
          click: function (item, focusedWindow) {
            if (focusedWindow) {
              // TODO: reload active frame
              focusedWindow.reloadIgnoringCache()
            }
          }
        }, {
          type: 'separator'
        }, {
          label: 'Reading View',
          accelerator: 'Alt+CmdOrCtrl+R'
        }, {
          label: 'Tab Manager',
          accelerator: 'Alt+CmdOrCtrl+M'
        }, {
          type: 'separator'
        }, {
          label: 'Text Encoding',
          submenu: []
        }, {
          type: 'separator'
        }, {
          label: 'Toggle Developer Tools',
          accelerator: 'CmdOrCtrl+Alt+I',
          click: function (item, focusedWindow) {
            if (focusedWindow) {
              focusedWindow.webContents.send('shortcut-active-frame-toggle-dev-tools')
            }
          }
        }, {
          label: 'Toggle Browser Console',
          accelerator: 'CmdOrCtrl+Shift+J',
          click: function (item, focusedWindow) {
            if (focusedWindow) {
              focusedWindow.toggleDevTools()
            }
          }
        }, {
          type: 'separator'
        }, {
          label: 'Enter Full Screen View',
          accelerator: 'Shift+CmdOrCtrl+F'
        }
        // Bring All To Front added automatically
      ]
    }, {
      label: 'History',
      submenu: [
        {
          label: 'Back',
          accelerator: 'CmdOrCtrl+['
        }, {
          label: 'Forward',
          accelerator: 'CmdOrCtrl+]'
        }, {
          type: 'separator'
        }, {
          label: 'Reopen Last Closed Tab',
          accelerator: 'Shift+CmdOrCtrl+T'
        }, {
          label: 'Reopen Last Closed Window'
        }, {
          type: 'separator'
        }, {
          label: 'My Mac',
          enabled: false
        }, {
          type: 'separator'
        }, {
          label: 'My iPhone',
          enabled: false
        }, {
          type: 'separator'
        }, {
          label: 'Show All History',
          accelerator: 'CmdOrCtrl+Y'
        }
      ]
    }, {
      label: 'Bookmarks',
      submenu: [
        {
          label: 'Add Bookmarks',
          accelerator: 'CmdOrCtrl+D'
        }, {
          label: 'Add to Favorites Bar',
          accelerator: 'Shift+CmdOrCtrl+D'
        }, {
          type: 'separator'
        }, {
          label: 'Manage Bookmarks',
          accelerator: 'Alt+CmdOrCtrl+B'
        }, {
          type: 'separator'
        }, {
          label: 'My Bookmarks',
          enabled: false
        }, {
          label: 'More',
          submenu: []
        }, {
          type: 'separator'
        }, {
          label: 'Import Bookmarks',
          submenu: []
        }
      ]
    }, {
      label: 'Bravery',
      submenu: [
        {
          label: 'Logged in as Yan (0 Points)',
          enabled: false
        }, {
          label: 'Manage...'
        }, {
          type: 'separator'
        }, {
          label: 'GiveBack to this site',
          accelerator: 'Shift+CmdOrCtrl+Y'
        }, {
          label: 'Stay ad supported on this site',
          accelerator: 'Shift+CmdOrCtrl+N'
        }, {
          type: 'separator'
        }, {
          label: 'Site Protection Settings (Changes invoke reload)',
          enabled: false // Hack to make this look like a section header.
        }, {
          type: 'checkbox',
          label: 'Block Ads',
          checked: true
        }, {
          type: 'checkbox',
          label: 'Block Cookies',
          checked: true
        }, {
          type: 'checkbox',
          label: 'Block Tracking',
          checked: true
        }, {
          type: 'checkbox',
          label: 'Block Popups',
          checked: true
        }, {
          type: 'checkbox',
          label: 'Block HTTP',
          checked: true
        }, {
          type: 'separator'
        }, {
          label: 'Disabled all protection on this site...'
        }
      ]
    }, {
      label: 'Window',
      role: 'window',
      submenu: [
        {
          label: 'Minimize',
          accelerator: 'CmdOrCtrl+M',
          role: 'minimize'
          // "Minimize all" added automatically
        }, {
          label: 'Zoom'
        }, {
          type: 'separator'
        }, {
          label: 'Select Next Tab',
          accelerator: 'Ctrl+Tab'
        }, {
          label: 'Select Previous Tab',
          accelerator: 'Ctrl+Shift+Tab'
        }, {
          label: 'Move Tab to New Window'
        }, {
          label: 'Merge All Windows'
        }, {
          type: 'separator'
        }, {
          label: 'Downloads',
          accelerator: 'Shift+CmdOrCtrl+J'
        }, {
          label: 'History',
          // On OSX, Shift+Cmd+H cannot be overridden.
          accelerator: 'CmdOrCtrl+Y'
        }, {
          label: 'Bookmarks',
          accelerator: 'Alt+CmdOrCtrl+B'
        }, {
          label: 'Tab Manager',
          accelerator: 'Alt+CmdOrCtrl+M'
        }
      ]
    }, {
      label: 'Help',
      role: 'help',
      submenu: [
        {
          label: 'Brave Help',
          click: function (item, focusedWindow) {
            focusedWindow.webContents.send('shortcut-new-frame',
                                           'https://brave.com')
          }
        }, {
          type: 'separator'
        }, {
          label: 'Submit Feedback...',
          click: function (item, focusedWindow) {
            focusedWindow.webContents.send('shortcut-new-frame',
                                           'https://brave.com')
          }
        }, {
          label: 'Spread the word about Brave...',
          click: function (item, focusedWindow) {
            focusedWindow.webContents.send('shortcut-new-frame',
                                           'https://brave.com')
          }
        }
      ]
    }
  ]

  if (process.platform === 'darwin') {
    var name = 'Brave'
    template.unshift({
      label: name, // Ignored. OSX gets this from the app Info.plist file.
      submenu: [
        {
          label: 'About ' + name,
          role: 'about'
        }, {
          type: 'separator'
        }, {
          label: 'Preferences...',
          accelerator: 'CmdOrCtrl+,'
        }, {
          type: 'separator'
        }, {
          label: 'Send us Feedback...',
          click: function (item, focusedWindow) {
            focusedWindow.webContents.send('shortcut-new-frame',
                                           'https://brave.com')
          }
        }, {
          type: 'separator'
        }, {
          label: 'Services',
          role: 'services',
          submenu: []
        }, {
          type: 'separator'
        }, {
          label: 'Hide ' + name,
          accelerator: 'Command+H',
          role: 'hide'
        }, {
          label: 'Hide Others',
          accelerator: 'Command+Shift+H',
          role: 'hideothers'
        }, {
          label: 'Show All',
          role: 'unhide'
        }, {
          type: 'separator'
        }, {
          label: 'Quit ' + name,
          accelerator: 'Command+Q',
          click: app.quit
        }
      ]
    })
    // Window menu.
    template[3].submenu.push(
      {
        type: 'separator'
      }, {
        label: 'Bring All to Front',
        role: 'front'
      }
    )
  }

  const menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu)
}

module.exports.init = init
<|endoftext|>